From 133755c7cfbf45f925df8508449867ddbabb2068 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Tue, 1 May 2012 03:01:28 -0700 Subject: [PATCH] --- yaml --- r: 306658 b: refs/heads/master c: 2a4ffa4c8934bd9a36c8354a4b87a529114baf62 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/Documentation/RCU/torture.txt | 15 +- .../devicetree/bindings/arm/arch_timer.txt | 27 - .../bindings/pinctrl/fsl,imx-pinctrl.txt | 95 - .../bindings/pinctrl/fsl,imx51-pinctrl.txt | 787 --- .../bindings/pinctrl/fsl,imx53-pinctrl.txt | 1202 ---- .../bindings/pinctrl/fsl,imx6q-pinctrl.txt | 1628 ----- .../bindings/pinctrl/fsl,mxs-pinctrl.txt | 918 --- .../pinctrl/nvidia,tegra20-pinmux.txt | 132 - .../pinctrl/nvidia,tegra30-pinmux.txt | 132 - .../bindings/pinctrl/pinctrl-bindings.txt | 128 - .../bindings/pinmux/pinmux_nvidia.txt | 5 + .../bindings/regulator/fixed-regulator.txt | 5 +- .../bindings/regulator/tps62360-regulator.txt | 44 - .../bindings/regulator/tps6586x.txt | 97 - .../devicetree/bindings/sound/sgtl5000.txt | 2 - trunk/Documentation/driver-model/devres.txt | 8 - .../feature-removal-schedule.txt | 10 - .../Documentation/filesystems/gfs2-glocks.txt | 119 +- trunk/Documentation/filesystems/gfs2.txt | 9 +- trunk/Documentation/filesystems/proc.txt | 1 + trunk/Documentation/kernel-parameters.txt | 108 +- trunk/Documentation/networking/00-INDEX | 8 + trunk/Documentation/networking/3c359.txt | 58 + trunk/Documentation/networking/3c509.txt | 1 + trunk/Documentation/networking/batman-adv.txt | 11 +- trunk/Documentation/networking/fore200e.txt | 6 +- trunk/Documentation/networking/ieee802154.txt | 75 +- trunk/Documentation/networking/olympic.txt | 79 + trunk/Documentation/networking/smctr.txt | 66 + trunk/Documentation/networking/tms380tr.txt | 147 + trunk/Documentation/pinctrl.txt | 94 +- .../power/regulator/regulator.txt | 3 +- trunk/Documentation/prctl/seccomp_filter.txt | 163 - .../Documentation/scsi/ChangeLog.megaraid_sas | 8 - trunk/Documentation/security/Smack.txt | 204 +- trunk/Documentation/security/Yama.txt | 10 +- trunk/Documentation/security/keys.txt | 17 - trunk/Documentation/sparc/README-2.5 | 46 + trunk/Documentation/virtual/virtio-spec.txt | 1164 +--- trunk/MAINTAINERS | 46 +- trunk/Makefile | 11 +- trunk/arch/Kconfig | 38 - trunk/arch/alpha/Kconfig | 3 +- trunk/arch/alpha/include/asm/rtc.h | 8 +- trunk/arch/alpha/kernel/Makefile | 2 +- trunk/arch/alpha/kernel/core_tsunami.c | 1 - trunk/{init => arch/alpha/kernel}/init_task.c | 17 +- trunk/arch/alpha/kernel/smp.c | 20 +- trunk/arch/alpha/kernel/sys_marvel.c | 2 +- trunk/arch/arm/Kconfig | 30 +- trunk/arch/arm/Makefile | 4 +- trunk/arch/arm/boot/compressed/head.S | 71 +- trunk/arch/arm/common/it8152.c | 7 +- trunk/arch/arm/common/via82c505.c | 11 +- trunk/arch/arm/common/vic.c | 56 +- trunk/arch/arm/configs/rpc_defconfig | 2 + trunk/arch/arm/include/asm/arch_timer.h | 19 - trunk/arch/arm/include/asm/cacheflush.h | 6 +- trunk/arch/arm/include/asm/cmpxchg.h | 73 +- trunk/arch/arm/include/asm/cpu.h | 1 + trunk/arch/arm/include/asm/glue-df.h | 8 + trunk/arch/arm/include/asm/glue-proc.h | 18 + trunk/arch/arm/include/asm/hardware/it8152.h | 2 +- trunk/arch/arm/include/asm/mach/pci.h | 17 +- trunk/arch/arm/include/asm/mach/time.h | 5 - trunk/arch/arm/include/asm/mmu.h | 7 + trunk/arch/arm/include/asm/mmu_context.h | 104 +- trunk/arch/arm/include/asm/page.h | 9 + trunk/arch/arm/include/asm/pgtable-3level.h | 2 + trunk/arch/arm/include/asm/processor.h | 2 + trunk/arch/arm/include/asm/ptrace.h | 5 - trunk/arch/arm/include/asm/syscall.h | 93 - trunk/arch/arm/include/asm/thread_info.h | 1 - trunk/arch/arm/include/asm/tlbflush.h | 21 +- trunk/arch/arm/kernel/Makefile | 3 +- trunk/arch/arm/kernel/arch_timer.c | 350 - trunk/arch/arm/kernel/bios32.c | 37 +- trunk/arch/arm/kernel/entry-armv.S | 4 + trunk/arch/arm/kernel/entry-common.S | 28 + trunk/arch/arm/kernel/head.S | 9 +- trunk/arch/arm/kernel/init_task.c | 37 + trunk/arch/arm/kernel/process.c | 20 + trunk/arch/arm/kernel/ptrace.c | 41 +- trunk/arch/arm/kernel/signal.c | 2 - trunk/arch/arm/kernel/smp.c | 33 +- trunk/arch/arm/kernel/smp_scu.c | 3 +- trunk/arch/arm/kernel/sys_arm.c | 2 +- trunk/arch/arm/kernel/thumbee.c | 4 +- trunk/arch/arm/kernel/time.c | 36 - trunk/arch/arm/kernel/traps.c | 11 +- trunk/arch/arm/lib/Makefile | 23 +- trunk/arch/arm/lib/io-readsw-armv3.S | 106 + trunk/arch/arm/lib/io-writesw-armv3.S | 126 + trunk/arch/arm/lib/uaccess.S | 564 ++ trunk/arch/arm/mach-cns3xxx/pcie.c | 12 +- trunk/arch/arm/mach-dove/pcie.c | 24 +- trunk/arch/arm/mach-exynos/Kconfig | 3 - trunk/arch/arm/mach-exynos/clock-exynos5.c | 2 +- .../arm/mach-exynos/mach-universal_c210.c | 4 +- trunk/arch/arm/mach-footbridge/cats-pci.c | 9 +- trunk/arch/arm/mach-footbridge/dc21285.c | 7 +- trunk/arch/arm/mach-footbridge/ebsa285-pci.c | 3 +- .../arch/arm/mach-footbridge/netwinder-pci.c | 3 +- trunk/arch/arm/mach-footbridge/personal-pci.c | 2 +- trunk/arch/arm/mach-integrator/impd1.c | 22 +- .../include/mach/entry-macro.S | 39 + .../arm/mach-integrator/include/mach/irqs.h | 63 +- .../arch/arm/mach-integrator/integrator_ap.c | 10 +- .../arch/arm/mach-integrator/integrator_cp.c | 33 +- trunk/arch/arm/mach-integrator/pci.c | 19 +- trunk/arch/arm/mach-integrator/pci_v3.c | 8 +- trunk/arch/arm/mach-iop13xx/iq81340mc.c | 1 + trunk/arch/arm/mach-iop13xx/iq81340sc.c | 1 + trunk/arch/arm/mach-iop32x/em7210.c | 3 +- trunk/arch/arm/mach-iop32x/glantank.c | 3 +- trunk/arch/arm/mach-iop32x/iq31244.c | 6 +- trunk/arch/arm/mach-iop32x/iq80321.c | 3 +- trunk/arch/arm/mach-iop32x/n2100.c | 3 +- trunk/arch/arm/mach-iop33x/iq80331.c | 3 +- trunk/arch/arm/mach-iop33x/iq80332.c | 3 +- trunk/arch/arm/mach-ixp2000/enp2611.c | 9 +- .../arm/mach-ixp2000/include/mach/platform.h | 2 +- trunk/arch/arm/mach-ixp2000/ixdp2400.c | 2 +- trunk/arch/arm/mach-ixp2000/ixdp2800.c | 2 +- trunk/arch/arm/mach-ixp2000/ixdp2x01.c | 2 +- trunk/arch/arm/mach-ixp2000/pci.c | 8 +- .../arm/mach-ixp23xx/include/mach/platform.h | 2 +- trunk/arch/arm/mach-ixp23xx/ixdp2351.c | 2 +- trunk/arch/arm/mach-ixp23xx/pci.c | 6 + trunk/arch/arm/mach-ixp23xx/roadrunner.c | 2 +- trunk/arch/arm/mach-ixp4xx/avila-pci.c | 3 +- trunk/arch/arm/mach-ixp4xx/common-pci.c | 6 + trunk/arch/arm/mach-ixp4xx/coyote-pci.c | 3 +- trunk/arch/arm/mach-ixp4xx/dsmg600-pci.c | 3 +- trunk/arch/arm/mach-ixp4xx/fsg-pci.c | 3 +- trunk/arch/arm/mach-ixp4xx/gateway7001-pci.c | 3 +- trunk/arch/arm/mach-ixp4xx/goramo_mlr.c | 3 +- trunk/arch/arm/mach-ixp4xx/gtwx5715-pci.c | 3 +- .../arm/mach-ixp4xx/include/mach/platform.h | 2 +- trunk/arch/arm/mach-ixp4xx/ixdp425-pci.c | 3 +- trunk/arch/arm/mach-ixp4xx/ixdpg425-pci.c | 3 +- trunk/arch/arm/mach-ixp4xx/miccpt-pci.c | 3 +- trunk/arch/arm/mach-ixp4xx/nas100d-pci.c | 3 +- trunk/arch/arm/mach-ixp4xx/nslu2-pci.c | 3 +- trunk/arch/arm/mach-ixp4xx/vulcan-pci.c | 3 +- trunk/arch/arm/mach-ixp4xx/wg302v2-pci.c | 3 +- trunk/arch/arm/mach-kirkwood/board-dt.c | 1 - trunk/arch/arm/mach-kirkwood/pcie.c | 16 +- trunk/arch/arm/mach-ks8695/pci.c | 9 +- trunk/arch/arm/mach-mv78xx0/pcie.c | 24 +- trunk/arch/arm/mach-mxs/devices-mx23.h | 12 +- trunk/arch/arm/mach-mxs/devices-mx28.h | 12 +- trunk/arch/arm/mach-mxs/devices.c | 16 + trunk/arch/arm/mach-mxs/devices/Makefile | 1 + trunk/arch/arm/mach-mxs/devices/amba-duart.c | 40 + .../mach-mxs/include/mach/devices-common.h | 5 + trunk/arch/arm/mach-omap1/ams-delta-fiq.c | 2 +- trunk/arch/arm/mach-omap2/board-igep0020.c | 2 +- .../include/mach/ctrl_module_pad_core_44xx.h | 8 +- trunk/arch/arm/mach-orion5x/db88f5281-setup.c | 1 + trunk/arch/arm/mach-orion5x/dns323-setup.c | 1 + .../arch/arm/mach-orion5x/kurobox_pro-setup.c | 1 + trunk/arch/arm/mach-orion5x/mpp.h | 4 +- trunk/arch/arm/mach-orion5x/mss2-setup.c | 1 + .../arm/mach-orion5x/rd88f5181l-fxo-setup.c | 1 + .../arm/mach-orion5x/rd88f5181l-ge-setup.c | 1 + trunk/arch/arm/mach-orion5x/rd88f5182-setup.c | 1 + .../arm/mach-orion5x/rd88f6183ap-ge-setup.c | 1 + .../arm/mach-orion5x/terastation_pro2-setup.c | 1 + trunk/arch/arm/mach-orion5x/ts209-setup.c | 1 + trunk/arch/arm/mach-orion5x/ts409-setup.c | 1 + trunk/arch/arm/mach-orion5x/wnr854t-setup.c | 1 + .../arch/arm/mach-orion5x/wrt350n-v2-setup.c | 1 + trunk/arch/arm/mach-prima2/irq.c | 6 +- trunk/arch/arm/mach-pxa/cm-x2xx-pci.c | 3 +- trunk/arch/arm/mach-sa1100/pci-nanoengine.c | 8 +- trunk/arch/arm/mach-shark/pci.c | 3 +- trunk/arch/arm/mach-shmobile/board-ag5evm.c | 22 +- trunk/arch/arm/mach-shmobile/board-mackerel.c | 22 +- trunk/arch/arm/mach-shmobile/headsmp.S | 56 +- .../arm/mach-shmobile/include/mach/common.h | 2 +- trunk/arch/arm/mach-shmobile/setup-r8a7779.c | 4 - trunk/arch/arm/mach-shmobile/setup-sh73a0.c | 4 - trunk/arch/arm/mach-shmobile/smp-r8a7779.c | 8 +- trunk/arch/arm/mach-shmobile/smp-sh73a0.c | 7 +- trunk/arch/arm/mach-shmobile/timer.c | 9 + trunk/arch/arm/mach-tegra/flowctrl.c | 4 +- trunk/arch/arm/mach-tegra/pcie.c | 1 + trunk/arch/arm/mach-tegra/timer.c | 5 +- trunk/arch/arm/mach-ux500/devices-common.c | 33 + trunk/arch/arm/mach-ux500/devices-common.h | 23 +- trunk/arch/arm/mach-ux500/devices-db8500.h | 2 +- trunk/arch/arm/mach-versatile/core.c | 18 +- trunk/arch/arm/mach-versatile/pci.c | 13 +- trunk/arch/arm/mach-vexpress/v2m.c | 8 +- trunk/arch/arm/mm/Kconfig | 46 +- trunk/arch/arm/mm/Makefile | 4 + trunk/arch/arm/mm/cache-v3.S | 1 - trunk/arch/arm/mm/cache-v4.S | 1 - trunk/arch/arm/mm/cache-v4wb.S | 6 +- trunk/arch/arm/mm/cache-v4wt.S | 1 - trunk/arch/arm/mm/cache-v6.S | 10 +- trunk/arch/arm/mm/cache-v7.S | 10 +- trunk/arch/arm/mm/context.c | 57 +- trunk/arch/arm/mm/copypage-v3.c | 81 + trunk/arch/arm/mm/fault.c | 7 +- trunk/arch/arm/mm/mmu.c | 3 +- trunk/arch/arm/mm/proc-arm1020.S | 1 - trunk/arch/arm/mm/proc-arm1020e.S | 1 - trunk/arch/arm/mm/proc-arm1022.S | 1 - trunk/arch/arm/mm/proc-arm1026.S | 1 - trunk/arch/arm/mm/proc-arm6_7.S | 327 + trunk/arch/arm/mm/proc-arm920.S | 1 - trunk/arch/arm/mm/proc-arm922.S | 1 - trunk/arch/arm/mm/proc-arm925.S | 1 - trunk/arch/arm/mm/proc-arm926.S | 1 - trunk/arch/arm/mm/proc-arm940.S | 6 +- trunk/arch/arm/mm/proc-arm946.S | 1 - trunk/arch/arm/mm/proc-feroceon.S | 1 - trunk/arch/arm/mm/proc-mohawk.S | 1 - trunk/arch/arm/mm/proc-v7-2level.S | 9 +- trunk/arch/arm/mm/tlb-v3.S | 48 + trunk/arch/arm/plat-iop/pci.c | 8 +- trunk/arch/arm/plat-omap/counter_32k.c | 6 +- trunk/arch/arm/plat-versatile/Kconfig | 6 - trunk/arch/arm/plat-versatile/fpga-irq.c | 116 +- .../plat-versatile/include/plat/fpga-irq.h | 11 +- trunk/arch/arm/tools/mach-types | 505 +- trunk/arch/arm/vfp/vfpmodule.c | 40 +- trunk/arch/avr32/kernel/Makefile | 2 +- trunk/arch/avr32/kernel/init_task.c | 31 + trunk/arch/blackfin/ADI_BSD.txt | 41 + trunk/arch/blackfin/Clear_BSD.txt | 33 - trunk/arch/blackfin/Kconfig | 185 +- trunk/arch/blackfin/Kconfig.debug | 7 - trunk/arch/blackfin/Makefile | 4 +- .../configs/BF561-EZKIT-SMP_defconfig | 4 +- .../blackfin/configs/BF609-EZKIT_defconfig | 155 - trunk/arch/blackfin/include/asm/bfin-global.h | 5 - trunk/arch/blackfin/include/asm/bfin6xx_spi.h | 258 - trunk/arch/blackfin/include/asm/bfin_crc.h | 139 - trunk/arch/blackfin/include/asm/bfin_dma.h | 84 +- trunk/arch/blackfin/include/asm/bfin_pfmon.h | 2 +- trunk/arch/blackfin/include/asm/bfin_ppi.h | 128 - trunk/arch/blackfin/include/asm/bfin_rotary.h | 1 - trunk/arch/blackfin/include/asm/bfin_serial.h | 182 +- trunk/arch/blackfin/include/asm/bfin_sport.h | 1 - trunk/arch/blackfin/include/asm/bfin_sport3.h | 107 - trunk/arch/blackfin/include/asm/bfin_twi.h | 142 - trunk/arch/blackfin/include/asm/blackfin.h | 8 +- trunk/arch/blackfin/include/asm/clkdev.h | 14 - trunk/arch/blackfin/include/asm/clocks.h | 23 - trunk/arch/blackfin/include/asm/cplb.h | 4 - .../blackfin/include/asm/def_LPBlackfin.h | 6 +- trunk/arch/blackfin/include/asm/dma.h | 137 +- trunk/arch/blackfin/include/asm/dpmc.h | 656 -- trunk/arch/blackfin/include/asm/fixed_code.h | 30 +- trunk/arch/blackfin/include/asm/gpio.h | 44 - trunk/arch/blackfin/include/asm/gptimers.h | 104 - trunk/arch/blackfin/include/asm/irqflags.h | 6 +- trunk/arch/blackfin/include/asm/page.h | 5 +- trunk/arch/blackfin/include/asm/pda.h | 2 - trunk/arch/blackfin/include/asm/pm.h | 31 - trunk/arch/blackfin/include/asm/unistd.h | 2 +- trunk/arch/blackfin/kernel/Makefile | 2 +- trunk/arch/blackfin/kernel/bfin_dma.c | 146 +- trunk/arch/blackfin/kernel/bfin_gpio.c | 28 +- .../blackfin/kernel/cplb-nompu/cplbinit.c | 4 +- .../arch/blackfin/kernel/cplb-nompu/cplbmgr.c | 6 - trunk/arch/blackfin/kernel/debug-mmrs.c | 9 +- trunk/arch/blackfin/kernel/entry.S | 10 + trunk/arch/blackfin/kernel/gptimers.c | 85 +- trunk/arch/blackfin/kernel/init_task.c | 32 + trunk/arch/blackfin/kernel/process.c | 8 +- trunk/arch/blackfin/kernel/reboot.c | 6 +- trunk/arch/blackfin/kernel/setup.c | 132 +- trunk/arch/blackfin/kernel/shadow_console.c | 6 +- trunk/arch/blackfin/kernel/time-ts.c | 27 +- trunk/arch/blackfin/lib/divsi3.S | 2 +- trunk/arch/blackfin/lib/memchr.S | 2 +- trunk/arch/blackfin/lib/memcmp.S | 2 +- trunk/arch/blackfin/lib/memcpy.S | 2 +- trunk/arch/blackfin/lib/memmove.S | 2 +- trunk/arch/blackfin/lib/memset.S | 2 +- trunk/arch/blackfin/lib/modsi3.S | 2 +- trunk/arch/blackfin/lib/muldi3.S | 2 +- trunk/arch/blackfin/lib/smulsi3_highpart.S | 2 +- trunk/arch/blackfin/lib/strcmp.S | 2 +- trunk/arch/blackfin/lib/strcpy.S | 2 +- trunk/arch/blackfin/lib/strncmp.S | 2 +- trunk/arch/blackfin/lib/strncpy.S | 2 +- trunk/arch/blackfin/lib/udivsi3.S | 2 +- trunk/arch/blackfin/lib/umodsi3.S | 2 +- trunk/arch/blackfin/lib/umulsi3_highpart.S | 2 +- trunk/arch/blackfin/mach-bf518/boards/ezbrd.c | 5 - .../blackfin/mach-bf518/boards/tcm-bf518.c | 5 - .../mach-bf518/include/mach/anomaly.h | 3 +- .../mach-bf518/include/mach/cdefBF512.h | 2 +- .../mach-bf518/include/mach/cdefBF514.h | 2 +- .../mach-bf518/include/mach/cdefBF516.h | 2 +- .../mach-bf518/include/mach/cdefBF518.h | 2 +- .../mach-bf518/include/mach/defBF512.h | 73 +- .../mach-bf518/include/mach/defBF514.h | 2 +- .../mach-bf518/include/mach/defBF516.h | 2 +- .../mach-bf518/include/mach/defBF518.h | 2 +- .../blackfin/mach-bf527/boards/ad7160eval.c | 6 - .../blackfin/mach-bf527/boards/cm_bf527.c | 5 - trunk/arch/blackfin/mach-bf527/boards/ezbrd.c | 5 - trunk/arch/blackfin/mach-bf527/boards/ezkit.c | 6 - .../blackfin/mach-bf527/boards/tll6527m.c | 5 - .../mach-bf527/include/mach/anomaly.h | 3 +- .../mach-bf527/include/mach/defBF522.h | 73 +- .../mach-bf527/include/mach/defBF525.h | 2 +- .../mach-bf527/include/mach/defBF527.h | 2 +- .../mach-bf533/include/mach/anomaly.h | 3 +- .../mach-bf533/include/mach/defBF532.h | 2 +- .../blackfin/mach-bf537/boards/cm_bf537e.c | 5 - .../blackfin/mach-bf537/boards/cm_bf537u.c | 5 - .../arch/blackfin/mach-bf537/boards/dnp5370.c | 5 - .../blackfin/mach-bf537/boards/minotaur.c | 5 - trunk/arch/blackfin/mach-bf537/boards/stamp.c | 66 +- .../blackfin/mach-bf537/boards/tcm_bf537.c | 5 - .../mach-bf537/include/mach/anomaly.h | 3 +- .../mach-bf537/include/mach/defBF534.h | 71 +- .../mach-bf537/include/mach/defBF537.h | 2 +- trunk/arch/blackfin/mach-bf538/boards/ezkit.c | 8 +- .../mach-bf538/include/mach/anomaly.h | 3 +- .../mach-bf538/include/mach/defBF538.h | 78 +- .../mach-bf538/include/mach/defBF539.h | 2 +- .../blackfin/mach-bf548/boards/cm_bf548.c | 10 - trunk/arch/blackfin/mach-bf548/boards/ezkit.c | 11 - .../mach-bf548/include/mach/anomaly.h | 3 +- .../mach-bf548/include/mach/defBF542.h | 2 +- .../mach-bf548/include/mach/defBF544.h | 2 +- .../mach-bf548/include/mach/defBF547.h | 2 +- .../mach-bf548/include/mach/defBF548.h | 2 +- .../mach-bf548/include/mach/defBF549.h | 2 +- .../mach-bf548/include/mach/defBF54x_base.h | 111 +- .../mach-bf561/include/mach/anomaly.h | 3 +- .../mach-bf561/include/mach/defBF561.h | 2 +- trunk/arch/blackfin/mach-bf609/Kconfig | 56 - trunk/arch/blackfin/mach-bf609/Makefile | 6 - trunk/arch/blackfin/mach-bf609/boards/Kconfig | 12 - .../arch/blackfin/mach-bf609/boards/Makefile | 5 - trunk/arch/blackfin/mach-bf609/boards/ezkit.c | 1340 ---- trunk/arch/blackfin/mach-bf609/clock.c | 390 -- trunk/arch/blackfin/mach-bf609/dma.c | 202 - trunk/arch/blackfin/mach-bf609/hibernate.S | 65 - .../mach-bf609/include/mach/anomaly.h | 130 - .../blackfin/mach-bf609/include/mach/bf609.h | 93 - .../mach-bf609/include/mach/bfin_serial.h | 17 - .../mach-bf609/include/mach/blackfin.h | 25 - .../mach-bf609/include/mach/cdefBF609.h | 15 - .../mach-bf609/include/mach/cdefBF60x_base.h | 3252 ---------- .../mach-bf609/include/mach/defBF609.h | 15 - .../mach-bf609/include/mach/defBF60x_base.h | 3587 ----------- .../blackfin/mach-bf609/include/mach/dma.h | 116 - .../blackfin/mach-bf609/include/mach/gpio.h | 171 - .../blackfin/mach-bf609/include/mach/irq.h | 318 - .../mach-bf609/include/mach/mem_map.h | 86 - .../blackfin/mach-bf609/include/mach/pll.h | 1 - .../blackfin/mach-bf609/include/mach/pm.h | 21 - .../mach-bf609/include/mach/portmux.h | 347 - trunk/arch/blackfin/mach-bf609/pm.c | 362 -- trunk/arch/blackfin/mach-common/Makefile | 5 +- trunk/arch/blackfin/mach-common/clock.h | 27 - trunk/arch/blackfin/mach-common/clocks-init.c | 153 +- trunk/arch/blackfin/mach-common/cpufreq.c | 46 +- trunk/arch/blackfin/mach-common/dpmc_modes.S | 606 +- trunk/arch/blackfin/mach-common/entry.S | 5 +- trunk/arch/blackfin/mach-common/head.S | 2 + .../arch/blackfin/mach-common/ints-priority.c | 423 +- trunk/arch/blackfin/mach-common/pm.c | 62 +- trunk/arch/blackfin/mach-common/smp.c | 19 +- trunk/arch/blackfin/mm/init.c | 14 +- trunk/arch/blackfin/mm/sram-alloc.c | 36 - trunk/arch/c6x/Kconfig | 14 +- trunk/arch/c6x/include/asm/elf.h | 14 +- trunk/arch/c6x/include/asm/mmu.h | 4 - trunk/arch/c6x/include/asm/ptrace.h | 5 - trunk/arch/c6x/include/asm/thread_info.h | 17 +- trunk/arch/c6x/kernel/process.c | 16 + trunk/arch/cris/Kconfig | 1 - trunk/arch/cris/arch-v32/kernel/smp.c | 14 +- trunk/arch/cris/include/asm/processor.h | 5 +- trunk/arch/cris/include/asm/thread_info.h | 6 + trunk/arch/cris/kernel/process.c | 28 + trunk/arch/frv/Makefile | 2 +- trunk/arch/frv/include/asm/processor.h | 4 + trunk/arch/frv/include/asm/thread_info.h | 15 + trunk/arch/frv/kernel/Makefile | 2 +- trunk/arch/frv/kernel/init_task.c | 32 + trunk/arch/frv/kernel/process.c | 15 + trunk/arch/h8300/kernel/Makefile | 2 +- trunk/arch/h8300/kernel/init_task.c | 36 + trunk/arch/hexagon/Kconfig | 3 +- trunk/arch/hexagon/Makefile | 3 +- trunk/arch/hexagon/include/asm/thread_info.h | 8 + trunk/arch/hexagon/kernel/Makefile | 2 +- trunk/arch/hexagon/kernel/init_task.c | 54 + trunk/arch/hexagon/kernel/process.c | 37 + trunk/arch/hexagon/kernel/smp.c | 11 +- trunk/arch/ia64/Kconfig | 4 - trunk/arch/ia64/include/asm/irq_remapping.h | 4 - trunk/arch/ia64/include/asm/processor.h | 1 + trunk/arch/ia64/include/asm/thread_info.h | 3 + trunk/arch/ia64/kernel/process.c | 20 + trunk/arch/ia64/kernel/smpboot.c | 63 +- trunk/arch/ia64/kvm/kvm-ia64.c | 2 +- trunk/arch/m32r/Makefile | 2 +- trunk/arch/m32r/include/asm/thread_info.h | 17 +- trunk/arch/m32r/kernel/Makefile | 2 +- trunk/arch/m32r/kernel/init_task.c | 34 + trunk/arch/m32r/kernel/smpboot.c | 6 +- trunk/arch/m68k/Makefile | 25 +- trunk/arch/m68k/amiga/platform.c | 126 +- trunk/arch/m68k/atari/ataints.c | 4 +- trunk/arch/m68k/configs/m5475evb_defconfig | 62 - trunk/arch/m68k/include/asm/atariints.h | 4 +- trunk/arch/m68k/include/asm/cacheflush_no.h | 32 +- trunk/arch/m68k/include/asm/entry.h | 6 +- trunk/arch/m68k/include/asm/flat.h | 7 +- trunk/arch/m68k/include/asm/io_mm.h | 7 - trunk/arch/m68k/include/asm/m528xsim.h | 179 +- trunk/arch/m68k/include/asm/mcfgpio.h | 57 - trunk/arch/m68k/include/asm/unaligned.h | 2 +- trunk/arch/m68k/include/asm/vga.h | 27 - trunk/arch/m68k/kernel/Makefile | 2 +- trunk/arch/m68k/kernel/dma.c | 165 +- trunk/arch/m68k/kernel/dma_mm.c | 131 + trunk/arch/m68k/kernel/dma_no.c | 75 + trunk/arch/m68k/kernel/init_task.c | 35 + trunk/arch/m68k/kernel/signal.c | 1201 +--- trunk/arch/m68k/kernel/signal_mm.c | 1115 ++++ trunk/arch/m68k/kernel/signal_no.c | 765 +++ trunk/arch/m68k/mm/fault.c | 42 +- trunk/arch/m68k/platform/5206/Makefile | 18 + .../{coldfire/m5206.c => 5206/config.c} | 9 - trunk/arch/m68k/platform/5206/gpio.c | 49 + trunk/arch/m68k/platform/520x/Makefile | 17 + .../{coldfire/m520x.c => 520x/config.c} | 22 +- trunk/arch/m68k/platform/520x/gpio.c | 175 + trunk/arch/m68k/platform/523x/Makefile | 17 + .../{coldfire/m523x.c => 523x/config.c} | 28 +- trunk/arch/m68k/platform/523x/gpio.c | 284 + trunk/arch/m68k/platform/5249/Makefile | 18 + .../{coldfire/m5249.c => 5249/config.c} | 16 +- trunk/arch/m68k/platform/5249/gpio.c | 65 + .../{coldfire/intc-5249.c => 5249/intc2.c} | 0 trunk/arch/m68k/platform/5272/Makefile | 18 + .../{coldfire/m5272.c => 5272/config.c} | 11 - trunk/arch/m68k/platform/5272/gpio.c | 81 + .../{coldfire/intc-5272.c => 5272/intc.c} | 0 trunk/arch/m68k/platform/527x/Makefile | 18 + .../{coldfire/m527x.c => 527x/config.c} | 49 +- trunk/arch/m68k/platform/527x/gpio.c | 609 ++ trunk/arch/m68k/platform/528x/Makefile | 18 + .../{coldfire/m528x.c => 528x/config.c} | 37 +- trunk/arch/m68k/platform/528x/gpio.c | 438 ++ trunk/arch/m68k/platform/5307/Makefile | 20 + .../{coldfire/m5307.c => 5307/config.c} | 9 - trunk/arch/m68k/platform/5307/gpio.c | 49 + .../m68k/platform/{coldfire => 5307}/nettel.c | 0 trunk/arch/m68k/platform/532x/Makefile | 18 + .../{coldfire/m532x.c => 532x/config.c} | 31 +- trunk/arch/m68k/platform/532x/gpio.c | 337 + trunk/arch/m68k/platform/5407/Makefile | 18 + .../{coldfire/m5407.c => 5407/config.c} | 9 - trunk/arch/m68k/platform/5407/gpio.c | 49 + trunk/arch/m68k/platform/54xx/Makefile | 19 + .../{coldfire/m54xx.c => 54xx/config.c} | 7 - .../platform/{coldfire => 54xx}/firebee.c | 0 trunk/arch/m68k/platform/coldfire/Makefile | 28 +- trunk/arch/m68k/platform/coldfire/device.c | 6 +- trunk/arch/m68k/platform/coldfire/gpio.c | 4 - trunk/arch/microblaze/kernel/Makefile | 2 +- trunk/arch/microblaze/kernel/init_task.c | 26 + trunk/arch/microblaze/kernel/ptrace.c | 2 +- trunk/arch/microblaze/pci/pci-common.c | 1 - trunk/arch/mips/Kconfig | 1 - trunk/arch/mips/Makefile | 2 +- trunk/arch/mips/configs/mtx1_defconfig | 4 + trunk/arch/mips/include/asm/thread_info.h | 12 + trunk/arch/mips/kernel/Makefile | 2 +- trunk/arch/mips/kernel/init_task.c | 35 + trunk/arch/mips/kernel/ptrace.c | 2 +- trunk/arch/mips/kernel/smp.c | 56 +- trunk/arch/mn10300/Makefile | 2 +- trunk/arch/mn10300/include/asm/thread_info.h | 17 +- trunk/arch/mn10300/kernel/Makefile | 2 +- trunk/arch/mn10300/kernel/init_task.c | 39 + trunk/arch/mn10300/kernel/kgdb.c | 3 +- trunk/arch/mn10300/kernel/smp.c | 11 +- trunk/arch/openrisc/Kconfig | 1 - trunk/arch/openrisc/Makefile | 2 +- trunk/arch/openrisc/include/asm/Kbuild | 3 +- trunk/arch/openrisc/include/asm/dma-mapping.h | 147 +- trunk/arch/openrisc/include/asm/elf.h | 12 +- trunk/arch/openrisc/include/asm/ptrace.h | 6 +- trunk/arch/openrisc/kernel/Makefile | 2 +- trunk/arch/openrisc/kernel/dma.c | 109 +- trunk/arch/openrisc/kernel/entry.S | 8 +- trunk/arch/openrisc/kernel/init_task.c | 42 + trunk/arch/openrisc/kernel/irq.c | 83 +- trunk/arch/openrisc/mm/fault.c | 32 +- trunk/arch/parisc/Kconfig | 1 - trunk/arch/parisc/Makefile | 2 +- trunk/arch/parisc/include/asm/hardware.h | 3 +- trunk/arch/parisc/include/asm/page.h | 6 - trunk/arch/parisc/include/asm/pdc.h | 7 + trunk/arch/parisc/include/asm/pgtable.h | 2 - trunk/arch/parisc/include/asm/prefetch.h | 7 +- trunk/arch/parisc/include/asm/spinlock.h | 2 - trunk/arch/parisc/kernel/Makefile | 2 +- trunk/arch/parisc/kernel/entry.S | 4 - trunk/arch/parisc/kernel/init_task.c | 70 + trunk/arch/parisc/kernel/pacache.S | 38 +- trunk/arch/parisc/kernel/pdc_cons.c | 3 +- trunk/arch/parisc/kernel/smp.c | 33 +- trunk/arch/parisc/kernel/time.c | 1 - trunk/arch/parisc/mm/init.c | 12 - trunk/arch/powerpc/Kconfig | 7 +- .../arch/powerpc/include/asm/exception-64s.h | 7 + trunk/arch/powerpc/include/asm/kvm_book3s.h | 7 +- trunk/arch/powerpc/include/asm/processor.h | 1 + trunk/arch/powerpc/include/asm/thread_info.h | 13 + trunk/arch/powerpc/kernel/Makefile | 2 +- trunk/arch/powerpc/kernel/entry_64.S | 62 +- trunk/arch/powerpc/kernel/exceptions-64s.S | 2 +- trunk/arch/powerpc/kernel/idle.c | 23 + trunk/arch/powerpc/kernel/init_task.c | 29 + trunk/arch/powerpc/kernel/irq.c | 21 +- trunk/arch/powerpc/kernel/process.c | 31 + trunk/arch/powerpc/kernel/ptrace.c | 2 +- trunk/arch/powerpc/kernel/smp.c | 76 +- trunk/arch/powerpc/kernel/traps.c | 10 +- trunk/arch/powerpc/kvm/book3s_64_mmu_host.c | 13 +- trunk/arch/powerpc/kvm/book3s_64_mmu_hv.c | 22 +- trunk/arch/powerpc/kvm/book3s_hv.c | 2 + trunk/arch/powerpc/kvm/book3s_hv_rm_mmu.c | 1 - trunk/arch/powerpc/kvm/book3s_segment.S | 42 +- trunk/arch/s390/Kconfig | 56 +- trunk/arch/s390/Makefile | 1 + trunk/arch/s390/boot/.gitignore | 2 - trunk/arch/s390/boot/compressed/.gitignore | 3 - trunk/arch/s390/defconfig | 1 + trunk/arch/s390/include/asm/barrier.h | 37 +- trunk/arch/s390/include/asm/ccwgroup.h | 14 +- trunk/arch/s390/include/asm/io.h | 7 +- trunk/arch/s390/include/asm/qdio.h | 19 +- trunk/arch/s390/include/asm/setup.h | 3 + trunk/arch/s390/include/asm/smp.h | 2 +- trunk/arch/s390/include/asm/thread_info.h | 2 + trunk/arch/s390/include/asm/timex.h | 17 +- trunk/arch/s390/kernel/.gitignore | 1 - trunk/arch/s390/kernel/Makefile | 2 +- trunk/arch/s390/kernel/compat_signal.c | 7 + trunk/arch/s390/kernel/early.c | 2 + trunk/arch/s390/kernel/entry.S | 21 +- trunk/arch/s390/kernel/entry64.S | 51 +- trunk/arch/s390/kernel/head.S | 123 + trunk/arch/s390/kernel/init_task.c | 38 + trunk/arch/s390/kernel/ptrace.c | 2 +- trunk/arch/s390/kernel/signal.c | 16 + trunk/arch/s390/kernel/smp.c | 39 +- trunk/arch/s390/kernel/vdso32/.gitignore | 1 - trunk/arch/s390/kernel/vdso64/.gitignore | 1 - trunk/arch/s390/mm/fault.c | 45 +- trunk/arch/s390/mm/hugetlbpage.c | 2 - trunk/arch/s390/mm/maccess.c | 67 - trunk/arch/s390/mm/pgtable.c | 2 - trunk/arch/score/include/asm/thread_info.h | 10 +- trunk/arch/score/kernel/Makefile | 2 +- trunk/arch/score/kernel/init_task.c | 46 + trunk/arch/sh/Kconfig | 4 +- trunk/arch/sh/Makefile | 2 +- trunk/arch/sh/include/asm/processor.h | 5 + trunk/arch/sh/include/asm/thread_info.h | 11 +- trunk/arch/sh/kernel/Makefile | 2 +- trunk/arch/sh/kernel/idle.c | 20 + trunk/arch/sh/kernel/init_task.c | 30 + trunk/arch/sh/kernel/process.c | 46 +- trunk/arch/sh/kernel/ptrace_32.c | 2 +- trunk/arch/sh/kernel/ptrace_64.c | 2 +- trunk/arch/sh/kernel/smp.c | 14 +- trunk/arch/sparc/Kbuild | 8 - trunk/arch/sparc/Kconfig | 15 +- trunk/arch/sparc/Makefile | 49 +- trunk/arch/sparc/boot/Makefile | 61 +- trunk/arch/sparc/boot/btfixupprep.c | 386 ++ trunk/arch/sparc/include/asm/asi.h | 14 - trunk/arch/sparc/include/asm/asmmacro.h | 17 + trunk/arch/sparc/include/asm/btfixup.h | 208 + trunk/arch/sparc/include/asm/cache.h | 114 + trunk/arch/sparc/include/asm/cacheflush.h | 4 - trunk/arch/sparc/include/asm/cacheflush_32.h | 73 +- trunk/arch/sparc/include/asm/cacheflush_64.h | 3 + trunk/arch/sparc/include/asm/cachetlb_32.h | 29 - trunk/arch/sparc/include/asm/cmpxchg_32.h | 27 + trunk/arch/sparc/include/asm/contregs.h | 22 + trunk/arch/sparc/include/asm/cpu_type.h | 20 +- trunk/arch/sparc/include/asm/cpudata_32.h | 1 + trunk/arch/sparc/include/asm/cypress.h | 79 + trunk/arch/sparc/include/asm/dma.h | 52 +- trunk/arch/sparc/include/asm/elf_32.h | 13 +- trunk/arch/sparc/include/asm/floppy_32.h | 45 +- trunk/arch/sparc/include/asm/floppy_64.h | 6 +- trunk/arch/sparc/include/asm/head_32.h | 21 +- trunk/arch/sparc/include/asm/leon.h | 66 +- trunk/arch/sparc/include/asm/machines.h | 23 +- trunk/arch/sparc/include/asm/mbus.h | 4 + trunk/arch/sparc/include/asm/memreg.h | 51 + trunk/arch/sparc/include/asm/mmu_context_32.h | 11 +- trunk/arch/sparc/include/asm/obio.h | 13 + trunk/arch/sparc/include/asm/oplib_32.h | 8 + trunk/arch/sparc/include/asm/page_32.h | 13 +- trunk/arch/sparc/include/asm/pgalloc_32.h | 76 +- trunk/arch/sparc/include/asm/pgtable_32.h | 387 +- trunk/arch/sparc/include/asm/pgtable_64.h | 4 + trunk/arch/sparc/include/asm/pgtsrmmu.h | 50 + trunk/arch/sparc/include/asm/pgtsun4c.h | 172 + trunk/arch/sparc/include/asm/processor_32.h | 1 + trunk/arch/sparc/include/asm/setup.h | 3 + trunk/arch/sparc/include/asm/shmparam_32.h | 4 +- trunk/arch/sparc/include/asm/smp_32.h | 114 +- trunk/arch/sparc/include/asm/smpprim.h | 54 + trunk/arch/sparc/include/asm/string_32.h | 63 +- trunk/arch/sparc/include/asm/sysen.h | 15 + trunk/arch/sparc/include/asm/thread_info_32.h | 10 +- trunk/arch/sparc/include/asm/thread_info_64.h | 25 +- trunk/arch/sparc/include/asm/timer_32.h | 33 +- trunk/arch/sparc/include/asm/timex_32.h | 1 + trunk/arch/sparc/include/asm/tlbflush_32.h | 56 +- trunk/arch/sparc/include/asm/uaccess_32.h | 1 + trunk/arch/sparc/include/asm/vac-ops.h | 127 + trunk/arch/sparc/include/asm/vaddrs.h | 16 + trunk/arch/sparc/include/asm/winmacro.h | 49 +- trunk/arch/sparc/kernel/Makefile | 4 +- trunk/arch/sparc/kernel/auxio_32.c | 13 +- trunk/arch/sparc/kernel/central.c | 2 +- trunk/arch/sparc/kernel/devices.c | 4 + trunk/arch/sparc/kernel/ds.c | 2 +- trunk/arch/sparc/kernel/entry.S | 432 +- trunk/arch/sparc/kernel/etrap_32.S | 50 +- trunk/arch/sparc/kernel/head_32.S | 639 +- trunk/arch/sparc/kernel/head_64.S | 2 +- trunk/arch/sparc/kernel/idprom.c | 19 +- trunk/arch/sparc/kernel/init_task.c | 22 + trunk/arch/sparc/kernel/ioport.c | 23 +- trunk/arch/sparc/kernel/irq.h | 60 +- trunk/arch/sparc/kernel/irq_32.c | 19 +- trunk/arch/sparc/kernel/irq_64.c | 2 +- trunk/arch/sparc/kernel/kernel.h | 10 + trunk/arch/sparc/kernel/leon_kernel.c | 98 +- trunk/arch/sparc/kernel/leon_smp.c | 122 +- trunk/arch/sparc/kernel/module.c | 21 +- trunk/arch/sparc/kernel/muldiv.c | 238 + trunk/arch/sparc/kernel/of_device_32.c | 4 +- trunk/arch/sparc/kernel/pcic.c | 55 +- trunk/arch/sparc/kernel/process_32.c | 116 + trunk/arch/sparc/kernel/ptrace_64.c | 2 +- trunk/arch/sparc/kernel/rtrap_32.S | 76 +- trunk/arch/sparc/kernel/rtrap_64.S | 12 +- trunk/arch/sparc/kernel/setup_32.c | 70 +- trunk/arch/sparc/kernel/signal_32.c | 7 +- trunk/arch/sparc/kernel/smp_32.c | 187 +- trunk/arch/sparc/kernel/smp_64.c | 12 +- trunk/arch/sparc/kernel/sparc_ksyms_32.c | 14 + trunk/arch/sparc/kernel/sun4c_irq.c | 264 + trunk/arch/sparc/kernel/sun4d_irq.c | 48 +- trunk/arch/sparc/kernel/sun4d_smp.c | 127 +- trunk/arch/sparc/kernel/sun4m_irq.c | 58 +- trunk/arch/sparc/kernel/sun4m_smp.c | 124 +- trunk/arch/sparc/kernel/sys_sparc_32.c | 11 + trunk/arch/sparc/kernel/systbls_64.S | 2 +- trunk/arch/sparc/kernel/time_32.c | 220 +- trunk/arch/sparc/kernel/trampoline_32.S | 22 +- trunk/arch/sparc/kernel/traps_32.c | 2 + .../sparc/kernel/{ttable_64.S => ttable.S} | 0 trunk/arch/sparc/kernel/ttable_32.S | 417 -- trunk/arch/sparc/kernel/unaligned_64.c | 1 + trunk/arch/sparc/kernel/wof.S | 72 +- trunk/arch/sparc/kernel/wuf.S | 60 +- trunk/arch/sparc/lib/Makefile | 6 +- trunk/arch/sparc/lib/ashldi3.S | 7 +- trunk/arch/sparc/lib/ashrdi3.S | 7 +- trunk/arch/sparc/lib/atomic_32.S | 44 + trunk/arch/sparc/lib/atomic_64.S | 49 +- trunk/arch/sparc/lib/bitops.S | 37 +- trunk/arch/sparc/lib/blockops.S | 10 +- trunk/arch/sparc/lib/bzero.S | 20 +- trunk/arch/sparc/lib/divdi3.S | 4 +- trunk/arch/sparc/lib/ipcsum.S | 9 +- trunk/arch/sparc/lib/ksyms.c | 22 + trunk/arch/sparc/lib/lshrdi3.S | 5 +- trunk/arch/sparc/lib/memmove.S | 9 +- trunk/arch/sparc/lib/mul.S | 137 + trunk/arch/sparc/lib/muldi3.S | 4 +- trunk/arch/sparc/lib/rem.S | 384 ++ trunk/arch/sparc/lib/sdiv.S | 381 ++ trunk/arch/sparc/lib/strlen_user_64.S | 8 +- trunk/arch/sparc/lib/strncmp_32.S | 8 +- trunk/arch/sparc/lib/strncmp_64.S | 8 +- trunk/arch/sparc/lib/strncpy_from_user_32.S | 6 +- trunk/arch/sparc/lib/strncpy_from_user_64.S | 8 +- trunk/arch/sparc/lib/ucmpdi2.c | 19 - trunk/arch/sparc/lib/udiv.S | 357 + trunk/arch/sparc/lib/udivdi3.S | 3 +- trunk/arch/sparc/lib/umul.S | 171 + trunk/arch/sparc/lib/urem.S | 357 + trunk/arch/sparc/lib/xor.S | 50 +- trunk/arch/sparc/mm/Makefile | 9 +- trunk/arch/sparc/mm/btfixup.c | 328 + trunk/arch/sparc/mm/fault_32.c | 207 +- trunk/arch/sparc/mm/init_32.c | 51 + trunk/arch/sparc/mm/init_64.c | 121 +- trunk/arch/sparc/mm/io-unit.c | 35 +- trunk/arch/sparc/mm/iommu.c | 71 +- trunk/arch/sparc/mm/leon_mm.c | 95 +- trunk/arch/sparc/mm/loadmmu.c | 43 + trunk/arch/sparc/mm/nosun4c.c | 77 + trunk/arch/sparc/mm/srmmu.c | 1232 +++- trunk/arch/sparc/mm/srmmu.h | 4 - trunk/arch/sparc/mm/sun4c.c | 2166 +++++++ trunk/arch/sparc/mm/ultra.S | 6 +- trunk/arch/sparc/mm/viking.S | 1 + trunk/arch/sparc/prom/Makefile | 1 + trunk/arch/sparc/prom/segment.c | 28 + trunk/arch/tile/Kconfig | 1 - trunk/arch/tile/include/asm/thread_info.h | 15 +- trunk/arch/tile/kernel/Makefile | 2 +- trunk/arch/tile/kernel/compat_signal.c | 12 +- trunk/arch/tile/kernel/init_task.c | 59 + trunk/arch/tile/kernel/intvec_32.S | 41 +- trunk/arch/tile/kernel/intvec_64.S | 38 +- trunk/arch/tile/kernel/process.c | 30 +- trunk/arch/tile/kernel/setup.c | 16 - trunk/arch/tile/kernel/smpboot.c | 2 +- trunk/arch/um/drivers/mconsole_kern.c | 1 - trunk/arch/um/include/asm/processor-generic.h | 2 + trunk/arch/um/kernel/Makefile | 2 +- trunk/arch/um/kernel/init_task.c | 38 + trunk/arch/um/kernel/smp.c | 2 +- trunk/arch/um/kernel/um_arch.c | 5 - trunk/arch/unicore32/Makefile | 1 + trunk/arch/unicore32/kernel/Makefile | 2 +- trunk/arch/unicore32/kernel/init_task.c | 44 + trunk/arch/x86/Kconfig | 9 +- trunk/arch/x86/Makefile | 4 +- trunk/arch/x86/boot/compressed/Makefile | 9 +- .../x86/{tools => boot/compressed}/relocs.c | 244 +- trunk/arch/x86/ia32/ia32_aout.c | 3 +- trunk/arch/x86/ia32/ia32_signal.c | 4 - trunk/arch/x86/include/asm/boot.h | 2 +- trunk/arch/x86/include/asm/ia32.h | 6 - trunk/arch/x86/include/asm/irq_remapping.h | 118 +- trunk/arch/x86/include/asm/kvm_para.h | 3 - trunk/arch/x86/include/asm/nmi.h | 22 +- trunk/arch/x86/include/asm/page_32_types.h | 4 +- trunk/arch/x86/include/asm/page_64_types.h | 4 +- trunk/arch/x86/include/asm/processor.h | 2 + trunk/arch/x86/include/asm/smp.h | 11 +- trunk/arch/x86/include/asm/stat.h | 21 - trunk/arch/x86/include/asm/syscall.h | 27 - trunk/arch/x86/include/asm/thread_info.h | 21 +- trunk/arch/x86/include/asm/word-at-a-time.h | 33 - trunk/arch/x86/kernel/Makefile | 2 +- trunk/arch/x86/kernel/acpi/boot.c | 2 +- trunk/arch/x86/kernel/apic/apic.c | 30 +- trunk/arch/x86/kernel/apic/io_apic.c | 297 +- trunk/arch/x86/kernel/apm_32.c | 2 +- trunk/arch/x86/kernel/cpu/amd.c | 18 - trunk/arch/x86/kernel/cpu/mcheck/mce.c | 14 +- trunk/arch/x86/kernel/init_task.c | 42 + trunk/arch/x86/kernel/irq_32.c | 8 +- trunk/arch/x86/kernel/kvm.c | 9 +- trunk/arch/x86/kernel/microcode_intel.c | 14 +- trunk/arch/x86/kernel/nmi.c | 83 +- trunk/arch/x86/kernel/process.c | 34 +- trunk/arch/x86/kernel/process_64.c | 1 - trunk/arch/x86/kernel/ptrace.c | 7 +- trunk/arch/x86/kernel/setup_percpu.c | 14 +- trunk/arch/x86/kernel/smpboot.c | 83 +- trunk/arch/x86/kvm/x86.c | 1 - trunk/arch/x86/lib/usercopy.c | 20 +- trunk/arch/x86/pci/acpi.c | 128 +- trunk/arch/x86/pci/amd_bus.c | 91 +- trunk/arch/x86/pci/broadcom_bus.c | 12 +- trunk/arch/x86/pci/bus_numa.c | 69 +- trunk/arch/x86/pci/bus_numa.h | 18 +- trunk/arch/x86/pci/common.c | 43 +- trunk/arch/x86/pci/i386.c | 2 +- trunk/arch/x86/platform/geode/net5501.c | 2 +- trunk/arch/x86/tools/.gitignore | 1 - trunk/arch/x86/tools/Makefile | 4 - trunk/arch/x86/xen/enlighten.c | 42 +- trunk/arch/x86/xen/mmu.c | 7 +- trunk/arch/x86/xen/smp.c | 19 +- trunk/arch/xtensa/configs/common_defconfig | 5 + trunk/arch/xtensa/kernel/Makefile | 2 +- trunk/arch/xtensa/kernel/init_task.c | 31 + trunk/block/genhd.c | 10 +- trunk/block/partitions/ibm.c | 2 +- trunk/drivers/acpi/bus.c | 4 - trunk/drivers/acpi/power.c | 11 +- trunk/drivers/acpi/scan.c | 21 +- trunk/drivers/amba/bus.c | 53 +- trunk/drivers/base/regmap/Kconfig | 3 - trunk/drivers/base/regmap/Makefile | 1 - trunk/drivers/base/regmap/internal.h | 26 +- trunk/drivers/base/regmap/regcache-lzo.c | 11 +- trunk/drivers/base/regmap/regcache-rbtree.c | 44 +- trunk/drivers/base/regmap/regcache.c | 34 +- trunk/drivers/base/regmap/regmap-debugfs.c | 18 +- trunk/drivers/base/regmap/regmap-i2c.c | 13 +- trunk/drivers/base/regmap/regmap-irq.c | 184 +- trunk/drivers/base/regmap/regmap-mmio.c | 224 - trunk/drivers/base/regmap/regmap-spi.c | 13 +- trunk/drivers/base/regmap/regmap.c | 278 +- trunk/drivers/block/DAC960.c | 23 +- trunk/drivers/block/drbd/drbd_nl.c | 2 +- trunk/drivers/block/mtip32xx/mtip32xx.c | 4 +- trunk/drivers/block/virtio_blk.c | 21 +- trunk/drivers/char/virtio_console.c | 7 - trunk/drivers/clk/clkdev.c | 142 +- trunk/drivers/cpuidle/cpuidle.c | 13 +- trunk/drivers/crypto/Kconfig | 2 - trunk/drivers/dma/at_hdmac.c | 4 +- trunk/drivers/dma/ep93xx_dma.c | 4 +- trunk/drivers/dma/pl330.c | 3 +- trunk/drivers/gpio/gpio-omap.c | 9 +- trunk/drivers/gpio/gpio-pch.c | 57 +- trunk/drivers/gpio/gpio-samsung.c | 18 +- trunk/drivers/gpu/drm/i915/i915_debugfs.c | 3 - trunk/drivers/gpu/drm/i915/i915_dma.c | 15 +- trunk/drivers/gpu/drm/i915/intel_display.c | 9 +- trunk/drivers/gpu/drm/i915/intel_hdmi.c | 2 +- trunk/drivers/gpu/drm/i915/intel_lvds.c | 4 +- trunk/drivers/gpu/drm/i915/intel_ringbuffer.c | 9 +- trunk/drivers/gpu/drm/i915/intel_sdvo.c | 6 - trunk/drivers/gpu/drm/nouveau/nouveau_i2c.c | 199 +- trunk/drivers/gpu/drm/nouveau/nouveau_i2c.h | 1 - trunk/drivers/gpu/drm/radeon/radeon_device.c | 4 +- trunk/drivers/ieee802154/Kconfig | 8 - trunk/drivers/ieee802154/Makefile | 1 - trunk/drivers/ieee802154/fakelb.c | 294 - trunk/drivers/infiniband/Kconfig | 1 - trunk/drivers/infiniband/Makefile | 1 - trunk/drivers/infiniband/core/cma.c | 42 +- trunk/drivers/infiniband/core/umem.c | 2 +- trunk/drivers/infiniband/core/uverbs_cmd.c | 108 +- trunk/drivers/infiniband/core/verbs.c | 15 +- trunk/drivers/infiniband/hw/cxgb4/Makefile | 2 +- trunk/drivers/infiniband/hw/cxgb4/cm.c | 36 +- trunk/drivers/infiniband/hw/cxgb4/device.c | 340 +- trunk/drivers/infiniband/hw/cxgb4/ev.c | 8 +- trunk/drivers/infiniband/hw/cxgb4/id_table.c | 112 - trunk/drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 134 +- trunk/drivers/infiniband/hw/cxgb4/mem.c | 21 +- trunk/drivers/infiniband/hw/cxgb4/provider.c | 19 +- trunk/drivers/infiniband/hw/cxgb4/qp.c | 105 +- trunk/drivers/infiniband/hw/cxgb4/resource.c | 180 +- trunk/drivers/infiniband/hw/cxgb4/t4.h | 24 - trunk/drivers/infiniband/hw/cxgb4/user.h | 2 +- .../infiniband/hw/ipath/ipath_iba6110.c | 3 +- .../drivers/infiniband/hw/ipath/ipath_intr.c | 3 +- trunk/drivers/infiniband/hw/mlx4/cq.c | 13 +- trunk/drivers/infiniband/hw/mlx4/main.c | 104 +- trunk/drivers/infiniband/hw/mlx4/mlx4_ib.h | 2 - trunk/drivers/infiniband/hw/mlx4/mr.c | 2 +- trunk/drivers/infiniband/hw/mlx4/qp.c | 54 +- trunk/drivers/infiniband/hw/mlx4/srq.c | 2 +- trunk/drivers/infiniband/hw/nes/nes_cm.c | 7 +- trunk/drivers/infiniband/hw/ocrdma/Kconfig | 8 - trunk/drivers/infiniband/hw/ocrdma/Makefile | 5 - trunk/drivers/infiniband/hw/ocrdma/ocrdma.h | 393 -- .../drivers/infiniband/hw/ocrdma/ocrdma_abi.h | 134 - .../drivers/infiniband/hw/ocrdma/ocrdma_ah.c | 172 - .../drivers/infiniband/hw/ocrdma/ocrdma_ah.h | 42 - .../drivers/infiniband/hw/ocrdma/ocrdma_hw.c | 2640 -------- .../drivers/infiniband/hw/ocrdma/ocrdma_hw.h | 132 - .../infiniband/hw/ocrdma/ocrdma_main.c | 577 -- .../drivers/infiniband/hw/ocrdma/ocrdma_sli.h | 1672 ----- .../infiniband/hw/ocrdma/ocrdma_verbs.c | 2537 -------- .../infiniband/hw/ocrdma/ocrdma_verbs.h | 94 - trunk/drivers/infiniband/hw/qib/qib.h | 35 +- trunk/drivers/infiniband/hw/qib/qib_driver.c | 5 +- trunk/drivers/infiniband/hw/qib/qib_iba6120.c | 1 - trunk/drivers/infiniband/hw/qib/qib_iba7220.c | 1 - trunk/drivers/infiniband/hw/qib/qib_iba7322.c | 3 +- trunk/drivers/infiniband/hw/qib/qib_init.c | 3 +- trunk/drivers/infiniband/hw/qib/qib_mad.c | 63 +- trunk/drivers/infiniband/hw/qib/qib_qp.c | 7 - trunk/drivers/infiniband/hw/qib/qib_rc.c | 4 +- trunk/drivers/infiniband/hw/qib/qib_ruc.c | 12 +- trunk/drivers/infiniband/hw/qib/qib_sysfs.c | 7 +- trunk/drivers/infiniband/hw/qib/qib_tx.c | 25 +- trunk/drivers/infiniband/hw/qib/qib_uc.c | 4 +- trunk/drivers/infiniband/hw/qib/qib_ud.c | 16 +- trunk/drivers/infiniband/hw/qib/qib_verbs.h | 145 +- .../drivers/infiniband/ulp/iser/iscsi_iser.c | 5 +- .../drivers/infiniband/ulp/iser/iser_verbs.c | 3 +- trunk/drivers/infiniband/ulp/srpt/ib_srpt.c | 10 +- trunk/drivers/iommu/Makefile | 2 +- trunk/drivers/iommu/dmar.c | 11 +- trunk/drivers/iommu/intel-iommu.c | 3 +- ...intel_irq_remapping.c => intr_remapping.c} | 359 +- trunk/drivers/iommu/intr_remapping.h | 17 + trunk/drivers/iommu/irq_remapping.c | 166 - trunk/drivers/iommu/irq_remapping.h | 90 - trunk/drivers/isdn/hardware/mISDN/avmfritz.c | 223 +- trunk/drivers/isdn/hardware/mISDN/hfcmulti.c | 121 +- trunk/drivers/isdn/hardware/mISDN/hfcpci.c | 98 +- trunk/drivers/isdn/hardware/mISDN/hfcsusb.c | 137 +- trunk/drivers/isdn/hardware/mISDN/hfcsusb.h | 6 - trunk/drivers/isdn/hardware/mISDN/mISDNipac.c | 128 +- trunk/drivers/isdn/hardware/mISDN/mISDNisar.c | 131 +- trunk/drivers/isdn/hardware/mISDN/netjet.c | 213 +- trunk/drivers/isdn/hardware/mISDN/w6692.c | 135 +- trunk/drivers/isdn/i4l/isdn_bsdcomp.c | 2 +- trunk/drivers/isdn/mISDN/dsp_core.c | 1 - trunk/drivers/isdn/mISDN/hwchannel.c | 162 +- trunk/drivers/isdn/mISDN/l1oip_core.c | 2 +- trunk/drivers/leds/leds-netxbig.c | 4 +- trunk/drivers/leds/leds-ns2.c | 2 +- trunk/drivers/md/bitmap.c | 3 +- trunk/drivers/md/bitmap.h | 3 + trunk/drivers/md/dm-log-userspace-transfer.c | 2 +- trunk/drivers/md/dm-mpath.c | 4 +- trunk/drivers/md/dm-thin.c | 48 +- trunk/drivers/md/md.c | 2 - trunk/drivers/md/raid10.c | 56 +- .../drivers/media/dvb/dvb-core/dvb_frontend.c | 4 - trunk/drivers/media/rc/ene_ir.c | 32 +- trunk/drivers/media/rc/fintek-cir.c | 22 +- trunk/drivers/media/rc/ite-cir.c | 20 +- trunk/drivers/media/rc/nuvoton-cir.c | 36 +- trunk/drivers/media/rc/winbond-cir.c | 78 +- trunk/drivers/media/video/gspca/sonixj.c | 8 +- .../media/video/marvell-ccic/mmp-driver.c | 1 + .../media/video/s5p-fimc/fimc-capture.c | 33 +- .../drivers/media/video/s5p-fimc/fimc-core.c | 4 +- .../drivers/media/video/s5p-fimc/fimc-core.h | 2 +- trunk/drivers/media/video/soc_camera.c | 8 +- .../media/video/videobuf2-dma-contig.c | 3 +- trunk/drivers/media/video/videobuf2-memops.c | 1 - trunk/drivers/message/fusion/mptlan.h | 1 + trunk/drivers/mfd/Kconfig | 14 - trunk/drivers/mfd/Makefile | 2 - trunk/drivers/mfd/da9052-core.c | 8 +- trunk/drivers/mfd/palmas.c | 509 -- trunk/drivers/mfd/tps65090.c | 11 + trunk/drivers/mfd/tps6586x.c | 86 - trunk/drivers/mfd/twl-core.c | 7 + trunk/drivers/mfd/wm8994-irq.c | 6 + trunk/drivers/mmc/host/mmci.c | 18 +- trunk/drivers/mtd/mtdchar.c | 2 +- trunk/drivers/mtd/nand/ams-delta.c | 17 +- trunk/drivers/net/Kconfig | 7 +- trunk/drivers/net/Makefile | 1 + trunk/drivers/net/Space.c | 62 +- trunk/drivers/net/bonding/bond_3ad.c | 18 +- trunk/drivers/net/bonding/bond_3ad.h | 2 +- trunk/drivers/net/bonding/bond_alb.c | 70 +- trunk/drivers/net/bonding/bond_main.c | 18 +- trunk/drivers/net/bonding/bonding.h | 2 +- trunk/drivers/net/ethernet/3com/3c509.c | 123 +- trunk/drivers/net/ethernet/8390/Kconfig | 24 + trunk/drivers/net/ethernet/8390/Makefile | 1 + trunk/drivers/net/ethernet/8390/ne2.c | 798 +++ trunk/drivers/net/ethernet/8390/smc-mca.c | 575 ++ trunk/drivers/net/ethernet/amd/ariadne.c | 8 +- trunk/drivers/net/ethernet/amd/atarilance.c | 11 +- trunk/drivers/net/ethernet/amd/depca.c | 213 +- trunk/drivers/net/ethernet/broadcom/tg3.c | 38 +- trunk/drivers/net/ethernet/broadcom/tg3.h | 2 + .../net/ethernet/chelsio/cxgb4/cxgb4.h | 23 - .../net/ethernet/chelsio/cxgb4/cxgb4_main.c | 235 +- .../net/ethernet/chelsio/cxgb4/cxgb4_uld.h | 11 - .../drivers/net/ethernet/chelsio/cxgb4/sge.c | 22 +- .../net/ethernet/chelsio/cxgb4/t4_hw.c | 62 +- .../net/ethernet/chelsio/cxgb4/t4_regs.h | 53 - .../net/ethernet/chelsio/cxgb4/t4fw_api.h | 15 - trunk/drivers/net/ethernet/cirrus/cs89x0.c | 2393 +++---- .../net/ethernet/cisco/enic/enic_main.c | 12 +- trunk/drivers/net/ethernet/davicom/Kconfig | 2 +- trunk/drivers/net/ethernet/dec/ewrk3.c | 3 +- trunk/drivers/net/ethernet/dec/tulip/de4x5.c | 2 +- .../net/ethernet/emulex/benet/Makefile | 2 +- trunk/drivers/net/ethernet/emulex/benet/be.h | 62 +- .../net/ethernet/emulex/benet/be_cmds.c | 95 - .../net/ethernet/emulex/benet/be_cmds.h | 58 - .../net/ethernet/emulex/benet/be_ethtool.c | 77 - .../drivers/net/ethernet/emulex/benet/be_hw.h | 6 +- .../net/ethernet/emulex/benet/be_main.c | 324 +- .../net/ethernet/emulex/benet/be_roce.c | 182 - .../net/ethernet/emulex/benet/be_roce.h | 75 - .../drivers/net/ethernet/freescale/gianfar.c | 2 +- trunk/drivers/net/ethernet/fujitsu/at1700.c | 120 +- trunk/drivers/net/ethernet/i825xx/3c523.c | 1312 ++++ trunk/drivers/net/ethernet/i825xx/3c523.h | 355 + trunk/drivers/net/ethernet/i825xx/3c527.c | 1660 +++++ trunk/drivers/net/ethernet/i825xx/3c527.h | 81 + trunk/drivers/net/ethernet/i825xx/Kconfig | 22 + trunk/drivers/net/ethernet/i825xx/Makefile | 2 + trunk/drivers/net/ethernet/i825xx/eexpress.c | 60 +- .../drivers/net/ethernet/ibm/ehea/ehea_main.c | 2 - trunk/drivers/net/ethernet/intel/Kconfig | 11 - .../net/ethernet/intel/e1000/e1000_main.c | 36 +- .../net/ethernet/intel/e1000e/defines.h | 2 +- .../drivers/net/ethernet/intel/e1000e/param.c | 56 +- trunk/drivers/net/ethernet/intel/igb/Makefile | 3 +- .../net/ethernet/intel/igb/e1000_82575.c | 276 +- .../net/ethernet/intel/igb/e1000_82575.h | 3 +- .../net/ethernet/intel/igb/e1000_defines.h | 35 - .../drivers/net/ethernet/intel/igb/e1000_hw.h | 14 - .../net/ethernet/intel/igb/e1000_i210.c | 603 -- .../net/ethernet/intel/igb/e1000_i210.h | 76 - .../net/ethernet/intel/igb/e1000_mac.c | 1 - .../net/ethernet/intel/igb/e1000_nvm.c | 1 + .../net/ethernet/intel/igb/e1000_phy.c | 147 +- .../net/ethernet/intel/igb/e1000_phy.h | 22 - .../net/ethernet/intel/igb/e1000_regs.h | 14 - trunk/drivers/net/ethernet/intel/igb/igb.h | 9 +- .../net/ethernet/intel/igb/igb_ethtool.c | 141 +- .../drivers/net/ethernet/intel/igb/igb_main.c | 130 +- .../drivers/net/ethernet/intel/igb/igb_ptp.c | 4 - .../drivers/net/ethernet/intel/ixgbe/Makefile | 2 - .../drivers/net/ethernet/intel/ixgbe/ixgbe.h | 37 - .../net/ethernet/intel/ixgbe/ixgbe_common.c | 2 +- .../ethernet/intel/ixgbe/ixgbe_dcb_82598.c | 69 +- .../ethernet/intel/ixgbe/ixgbe_dcb_82599.c | 93 +- .../net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c | 98 +- .../net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 71 +- .../net/ethernet/intel/ixgbe/ixgbe_main.c | 198 +- .../net/ethernet/intel/ixgbe/ixgbe_ptp.c | 900 --- .../net/ethernet/intel/ixgbe/ixgbe_sriov.c | 13 +- .../net/ethernet/intel/ixgbe/ixgbe_sysfs.c | 36 +- .../net/ethernet/intel/ixgbe/ixgbe_type.h | 47 +- .../net/ethernet/mellanox/mlx4/alloc.c | 3 + .../drivers/net/ethernet/mellanox/mlx4/cmd.c | 7 +- .../net/ethernet/mellanox/mlx4/en_main.c | 6 +- .../net/ethernet/mellanox/mlx4/en_netdev.c | 41 +- .../net/ethernet/mellanox/mlx4/en_tx.c | 15 +- trunk/drivers/net/ethernet/mellanox/mlx4/fw.c | 32 +- trunk/drivers/net/ethernet/mellanox/mlx4/fw.h | 2 - .../drivers/net/ethernet/mellanox/mlx4/main.c | 49 +- .../drivers/net/ethernet/mellanox/mlx4/mcg.c | 2 + .../drivers/net/ethernet/mellanox/mlx4/mlx4.h | 12 +- .../net/ethernet/mellanox/mlx4/mlx4_en.h | 9 +- trunk/drivers/net/ethernet/mellanox/mlx4/mr.c | 5 +- trunk/drivers/net/ethernet/mellanox/mlx4/pd.c | 39 +- .../drivers/net/ethernet/mellanox/mlx4/port.c | 7 +- .../ethernet/mellanox/mlx4/resource_tracker.c | 271 +- trunk/drivers/net/ethernet/micrel/ks8851.c | 7 +- trunk/drivers/net/ethernet/natsemi/Kconfig | 20 +- trunk/drivers/net/ethernet/natsemi/Makefile | 1 + .../net/ethernet/oki-semi/pch_gbe/pch_gbe.h | 2 + .../ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 25 +- .../net/ethernet/qlogic/netxen/netxen_nic.h | 20 +- .../ethernet/qlogic/netxen/netxen_nic_ctx.c | 5 +- .../qlogic/netxen/netxen_nic_ethtool.c | 18 +- .../ethernet/qlogic/netxen/netxen_nic_hdr.h | 26 - .../ethernet/qlogic/netxen/netxen_nic_init.c | 4 +- .../ethernet/qlogic/netxen/netxen_nic_main.c | 140 +- .../ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 7 +- .../net/ethernet/qlogic/qlcnic/qlcnic_main.c | 5 +- trunk/drivers/net/ethernet/realtek/r8169.c | 16 +- trunk/drivers/net/ethernet/sfc/efx.c | 38 +- trunk/drivers/net/ethernet/sfc/ethtool.c | 37 +- trunk/drivers/net/ethernet/sfc/mcdi_phy.c | 76 - trunk/drivers/net/ethernet/sfc/net_driver.h | 8 +- trunk/drivers/net/ethernet/sfc/qt202x_phy.c | 33 - trunk/drivers/net/ethernet/sfc/rx.c | 31 +- .../net/ethernet/stmicro/stmmac/common.h | 6 +- .../net/ethernet/stmicro/stmmac/dwmac1000.h | 12 +- .../ethernet/stmicro/stmmac/dwmac1000_core.c | 11 +- .../ethernet/stmicro/stmmac/dwmac1000_dma.c | 6 +- .../ethernet/stmicro/stmmac/dwmac100_core.c | 2 +- .../ethernet/stmicro/stmmac/dwmac100_dma.c | 2 +- .../net/ethernet/stmicro/stmmac/dwmac_lib.c | 8 +- .../net/ethernet/stmicro/stmmac/stmmac.h | 1 - .../net/ethernet/stmicro/stmmac/stmmac_main.c | 22 +- trunk/drivers/net/ethernet/sun/sunvnet.c | 2 +- trunk/drivers/net/ethernet/tile/tilepro.c | 2 +- .../net/ethernet/toshiba/ps3_gelic_wireless.c | 8 +- trunk/drivers/net/hyperv/hyperv_net.h | 290 +- trunk/drivers/net/hyperv/rndis_filter.c | 46 +- trunk/drivers/net/macvlan.c | 9 +- trunk/drivers/net/macvtap.c | 43 +- trunk/drivers/net/phy/mdio_bus.c | 2 +- trunk/drivers/net/phy/phy_device.c | 3 +- trunk/drivers/net/ppp/ppp_async.c | 2 +- trunk/drivers/net/ppp/ppp_generic.c | 14 +- trunk/drivers/net/ppp/ppp_synctty.c | 4 +- trunk/drivers/net/ppp/pppoe.c | 18 +- trunk/drivers/net/ppp/pptp.c | 2 +- trunk/drivers/net/tokenring/3c359.c | 1831 ++++++ trunk/drivers/net/tokenring/3c359.h | 291 + trunk/drivers/net/tokenring/Kconfig | 199 + trunk/drivers/net/tokenring/Makefile | 16 + trunk/drivers/net/tokenring/abyss.c | 468 ++ trunk/drivers/net/tokenring/abyss.h | 58 + trunk/drivers/net/tokenring/ibmtr.c | 1964 ++++++ trunk/drivers/net/tokenring/ibmtr_cs.c | 370 ++ trunk/drivers/net/tokenring/lanstreamer.c | 1909 ++++++ trunk/drivers/net/tokenring/lanstreamer.h | 343 + trunk/drivers/net/tokenring/madgemc.c | 761 +++ trunk/drivers/net/tokenring/madgemc.h | 70 + trunk/drivers/net/tokenring/olympic.c | 1737 +++++ trunk/drivers/net/tokenring/olympic.h | 321 + trunk/drivers/net/tokenring/proteon.c | 422 ++ trunk/drivers/net/tokenring/skisa.c | 432 ++ trunk/drivers/net/tokenring/smctr.c | 5717 +++++++++++++++++ trunk/drivers/net/tokenring/smctr.h | 1585 +++++ trunk/drivers/net/tokenring/tms380tr.c | 2306 +++++++ trunk/drivers/net/tokenring/tms380tr.h | 1141 ++++ trunk/drivers/net/tokenring/tmspci.c | 236 + trunk/drivers/net/tun.c | 2 +- trunk/drivers/net/usb/cdc_ether.c | 72 - trunk/drivers/net/usb/qmi_wwan.c | 39 +- trunk/drivers/net/usb/rndis_host.c | 83 +- trunk/drivers/net/usb/usbnet.c | 54 +- trunk/drivers/net/virtio_net.c | 2 - trunk/drivers/net/wireless/at76c50x-usb.c | 2 +- trunk/drivers/net/wireless/ath/ath5k/base.c | 6 +- trunk/drivers/net/wireless/ath/ath9k/recv.c | 2 +- trunk/drivers/net/wireless/ath/carl9170/rx.c | 2 +- .../drivers/net/wireless/ipw2x00/libipw_rx.c | 16 +- trunk/drivers/net/wireless/iwlegacy/3945.c | 4 +- .../drivers/net/wireless/iwlegacy/4965-mac.c | 2 +- trunk/drivers/net/wireless/iwlegacy/common.c | 14 +- .../drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 11 +- .../net/wireless/iwlwifi/iwl-agn-rxon.c | 8 +- .../net/wireless/iwlwifi/iwl-agn-sta.c | 6 +- trunk/drivers/net/wireless/mac80211_hwsim.c | 5 + trunk/drivers/net/wireless/mwl8k.c | 2 +- trunk/drivers/net/wireless/p54/txrx.c | 2 +- trunk/drivers/net/wireless/rndis_wlan.c | 373 +- trunk/drivers/net/wireless/rtlwifi/base.c | 2 +- trunk/drivers/net/wireless/rtlwifi/pci.c | 16 +- trunk/drivers/net/wireless/rtlwifi/ps.c | 2 +- .../net/wireless/rtlwifi/rtl8192ce/trx.c | 10 +- .../net/wireless/rtlwifi/rtl8192cu/mac.c | 10 +- .../net/wireless/rtlwifi/rtl8192de/trx.c | 11 +- .../net/wireless/rtlwifi/rtl8192se/trx.c | 11 +- trunk/drivers/net/wireless/rtlwifi/usb.c | 10 +- trunk/drivers/of/base.c | 41 - trunk/drivers/parisc/sba_iommu.c | 1 - trunk/drivers/pci/Makefile | 2 +- trunk/drivers/pci/host-bridge.c | 96 - trunk/drivers/pci/pci-acpi.c | 2 +- trunk/drivers/pci/pci-driver.c | 6 - trunk/drivers/pci/pci.c | 30 +- trunk/drivers/pci/pcie/portdrv_core.c | 2 +- trunk/drivers/pci/probe.c | 154 +- trunk/drivers/pci/quirks.c | 58 - trunk/drivers/pinctrl/Kconfig | 45 +- trunk/drivers/pinctrl/Makefile | 10 - trunk/drivers/pinctrl/core.c | 244 +- trunk/drivers/pinctrl/core.h | 12 +- trunk/drivers/pinctrl/devicetree.c | 249 - trunk/drivers/pinctrl/devicetree.h | 35 - trunk/drivers/pinctrl/pinconf.c | 56 +- trunk/drivers/pinctrl/pinconf.h | 17 +- trunk/drivers/pinctrl/pinctrl-coh901.c | 4 +- trunk/drivers/pinctrl/pinctrl-imx.c | 620 -- trunk/drivers/pinctrl/pinctrl-imx.h | 106 - trunk/drivers/pinctrl/pinctrl-imx23.c | 305 - trunk/drivers/pinctrl/pinctrl-imx28.c | 421 -- trunk/drivers/pinctrl/pinctrl-imx51.c | 1322 ---- trunk/drivers/pinctrl/pinctrl-imx53.c | 1649 ----- trunk/drivers/pinctrl/pinctrl-imx6q.c | 2331 ------- trunk/drivers/pinctrl/pinctrl-mxs.c | 528 -- trunk/drivers/pinctrl/pinctrl-mxs.h | 91 - trunk/drivers/pinctrl/pinctrl-pxa3xx.c | 30 +- trunk/drivers/pinctrl/pinctrl-sirf.c | 20 +- trunk/drivers/pinctrl/pinctrl-tegra.c | 245 +- trunk/drivers/pinctrl/pinctrl-u300.c | 20 +- trunk/drivers/pinctrl/pinmux.c | 97 +- trunk/drivers/pinctrl/pinmux.h | 18 +- .../drivers/platform/x86/intel_mid_powerbtn.c | 2 +- trunk/drivers/ptp/ptp_pch.c | 1 - trunk/drivers/regulator/88pm8607.c | 179 +- trunk/drivers/regulator/Kconfig | 33 +- trunk/drivers/regulator/Makefile | 5 +- trunk/drivers/regulator/aat2870-regulator.c | 10 +- trunk/drivers/regulator/ab3100.c | 65 +- trunk/drivers/regulator/ab8500.c | 235 +- trunk/drivers/regulator/ad5398.c | 19 +- trunk/drivers/regulator/anatop-regulator.c | 9 +- trunk/drivers/regulator/core.c | 461 +- trunk/drivers/regulator/da903x.c | 209 +- trunk/drivers/regulator/da9052-regulator.c | 441 +- trunk/drivers/regulator/db8500-prcmu.c | 133 +- trunk/drivers/regulator/dummy.c | 7 +- trunk/drivers/regulator/fixed.c | 69 +- trunk/drivers/regulator/gpio-regulator.c | 22 +- trunk/drivers/regulator/isl6271a-regulator.c | 73 +- trunk/drivers/regulator/lp3971.c | 87 +- trunk/drivers/regulator/lp3972.c | 74 +- trunk/drivers/regulator/max1586.c | 28 +- trunk/drivers/regulator/max8649.c | 110 +- trunk/drivers/regulator/max8660.c | 165 +- trunk/drivers/regulator/max8925-regulator.c | 83 +- trunk/drivers/regulator/max8952.c | 70 +- trunk/drivers/regulator/max8997.c | 344 +- trunk/drivers/regulator/max8998.c | 122 +- trunk/drivers/regulator/mc13783-regulator.c | 12 +- trunk/drivers/regulator/mc13892-regulator.c | 25 +- .../regulator/mc13xxx-regulator-core.c | 54 +- trunk/drivers/regulator/mc13xxx.h | 2 + trunk/drivers/regulator/of_regulator.c | 47 - trunk/drivers/regulator/palmas-regulator.c | 822 --- trunk/drivers/regulator/pcap-regulator.c | 54 +- trunk/drivers/regulator/pcf50633-regulator.c | 199 +- trunk/drivers/regulator/rc5t583-regulator.c | 255 - trunk/drivers/regulator/s5m8767.c | 327 +- trunk/drivers/regulator/tps6105x-regulator.c | 11 +- trunk/drivers/regulator/tps62360-regulator.c | 380 +- trunk/drivers/regulator/tps65023-regulator.c | 244 +- trunk/drivers/regulator/tps6507x-regulator.c | 22 +- trunk/drivers/regulator/tps65090-regulator.c | 150 - trunk/drivers/regulator/tps65217-regulator.c | 78 +- trunk/drivers/regulator/tps6524x-regulator.c | 47 +- trunk/drivers/regulator/tps6586x-regulator.c | 108 +- trunk/drivers/regulator/tps65910-regulator.c | 323 +- trunk/drivers/regulator/tps65912-regulator.c | 60 +- trunk/drivers/regulator/twl-regulator.c | 127 +- trunk/drivers/regulator/userspace-consumer.c | 20 +- trunk/drivers/regulator/virtual.c | 26 +- trunk/drivers/regulator/wm831x-dcdc.c | 174 +- trunk/drivers/regulator/wm831x-isink.c | 8 +- trunk/drivers/regulator/wm831x-ldo.c | 201 +- trunk/drivers/regulator/wm8350-regulator.c | 11 +- trunk/drivers/regulator/wm8400-regulator.c | 176 +- trunk/drivers/regulator/wm8994-regulator.c | 111 +- trunk/drivers/remoteproc/remoteproc_core.c | 2 +- trunk/drivers/rtc/rtc-mpc5121.c | 3 +- trunk/drivers/rtc/rtc-pl031.c | 18 - trunk/drivers/s390/char/sclp_cmd.c | 12 +- trunk/drivers/s390/char/tape.h | 43 + trunk/drivers/s390/char/tape_34xx.c | 136 + trunk/drivers/s390/char/tape_3590.c | 105 + trunk/drivers/s390/char/tape_char.c | 13 + trunk/drivers/s390/char/tape_core.c | 16 +- trunk/drivers/s390/cio/ccwgroup.c | 112 +- trunk/drivers/s390/cio/cio.c | 73 +- trunk/drivers/s390/cio/device.c | 13 +- trunk/drivers/s390/cio/device.h | 1 - trunk/drivers/s390/cio/qdio_main.c | 47 +- trunk/drivers/s390/crypto/ap_bus.c | 24 +- trunk/drivers/s390/crypto/ap_bus.h | 7 +- trunk/drivers/s390/crypto/zcrypt_cex2a.c | 3 +- trunk/drivers/s390/crypto/zcrypt_pcica.c | 3 +- trunk/drivers/s390/crypto/zcrypt_pcicc.c | 3 +- trunk/drivers/s390/crypto/zcrypt_pcixcc.c | 5 +- trunk/drivers/s390/net/Kconfig | 5 +- trunk/drivers/s390/net/claw.c | 165 +- trunk/drivers/s390/net/ctcm_main.c | 52 +- trunk/drivers/s390/net/ctcm_main.h | 8 +- trunk/drivers/s390/net/ctcm_sysfs.c | 37 +- trunk/drivers/s390/net/lcs.c | 73 +- trunk/drivers/s390/net/qeth_core.h | 28 +- trunk/drivers/s390/net/qeth_core_main.c | 186 +- trunk/drivers/s390/net/qeth_core_mpc.h | 10 + trunk/drivers/s390/net/qeth_core_sys.c | 49 +- trunk/drivers/s390/net/qeth_l2_main.c | 16 +- trunk/drivers/s390/net/qeth_l3_main.c | 110 +- trunk/drivers/s390/net/qeth_l3_sys.c | 112 + trunk/drivers/scsi/Kconfig | 1 - trunk/drivers/scsi/aacraid/src.c | 2 - trunk/drivers/scsi/atari_scsi.c | 26 +- trunk/drivers/scsi/atari_scsi.h | 5 + trunk/drivers/scsi/be2iscsi/be.h | 4 + trunk/drivers/scsi/be2iscsi/be_cmds.c | 2 - trunk/drivers/scsi/be2iscsi/be_cmds.h | 154 +- trunk/drivers/scsi/be2iscsi/be_iscsi.c | 493 +- trunk/drivers/scsi/be2iscsi/be_iscsi.h | 15 - trunk/drivers/scsi/be2iscsi/be_main.c | 447 +- trunk/drivers/scsi/be2iscsi/be_main.h | 17 +- trunk/drivers/scsi/be2iscsi/be_mgmt.c | 522 +- trunk/drivers/scsi/be2iscsi/be_mgmt.h | 50 +- trunk/drivers/scsi/bfa/bfa_fcs.h | 3 + trunk/drivers/scsi/bfa/bfa_fcs_lport.c | 32 +- trunk/drivers/scsi/bfa/bfad.c | 17 + trunk/drivers/scsi/bfa/bfad_attr.c | 20 +- .../drivers/scsi/bnx2i/57xx_iscsi_constants.h | 2 +- trunk/drivers/scsi/bnx2i/57xx_iscsi_hsi.h | 2 +- trunk/drivers/scsi/bnx2i/bnx2i.h | 2 +- trunk/drivers/scsi/bnx2i/bnx2i_hwi.c | 2 +- trunk/drivers/scsi/bnx2i/bnx2i_init.c | 6 +- trunk/drivers/scsi/bnx2i/bnx2i_iscsi.c | 3 +- trunk/drivers/scsi/bnx2i/bnx2i_sysfs.c | 2 +- .../scsi/device_handler/scsi_dh_alua.c | 70 +- trunk/drivers/scsi/fcoe/fcoe.c | 41 +- trunk/drivers/scsi/fcoe/fcoe.h | 4 +- trunk/drivers/scsi/fcoe/fcoe_ctlr.c | 8 +- trunk/drivers/scsi/hosts.c | 3 - trunk/drivers/scsi/hpsa.c | 683 +- trunk/drivers/scsi/hpsa.h | 85 +- trunk/drivers/scsi/hpsa_cmd.h | 37 +- trunk/drivers/scsi/isci/host.c | 703 +- trunk/drivers/scsi/isci/host.h | 124 +- trunk/drivers/scsi/isci/init.c | 212 +- trunk/drivers/scsi/isci/phy.c | 76 +- trunk/drivers/scsi/isci/phy.h | 9 +- trunk/drivers/scsi/isci/port.c | 68 +- trunk/drivers/scsi/isci/port.h | 11 +- trunk/drivers/scsi/isci/port_config.c | 18 +- trunk/drivers/scsi/isci/probe_roms.c | 12 + trunk/drivers/scsi/isci/probe_roms.h | 2 + trunk/drivers/scsi/isci/registers.h | 8 - trunk/drivers/scsi/isci/remote_device.c | 576 +- trunk/drivers/scsi/isci/remote_device.h | 63 +- trunk/drivers/scsi/isci/remote_node_context.c | 393 +- trunk/drivers/scsi/isci/remote_node_context.h | 43 +- trunk/drivers/scsi/isci/request.c | 715 ++- trunk/drivers/scsi/isci/request.h | 125 +- .../drivers/scsi/isci/scu_completion_codes.h | 2 - trunk/drivers/scsi/isci/task.c | 800 ++- trunk/drivers/scsi/isci/task.h | 132 +- .../scsi/isci/unsolicited_frame_control.c | 30 +- .../scsi/isci/unsolicited_frame_control.h | 6 +- trunk/drivers/scsi/libfc/fc_lport.c | 2 +- trunk/drivers/scsi/lpfc/lpfc.h | 4 - trunk/drivers/scsi/lpfc/lpfc_bsg.c | 4 +- trunk/drivers/scsi/lpfc/lpfc_bsg.h | 3 +- trunk/drivers/scsi/lpfc/lpfc_crtn.h | 8 +- trunk/drivers/scsi/lpfc/lpfc_debugfs.c | 46 - trunk/drivers/scsi/lpfc/lpfc_debugfs.h | 418 -- trunk/drivers/scsi/lpfc/lpfc_els.c | 141 +- trunk/drivers/scsi/lpfc/lpfc_hbadisc.c | 18 +- trunk/drivers/scsi/lpfc/lpfc_hw.h | 3 - trunk/drivers/scsi/lpfc/lpfc_hw4.h | 18 +- trunk/drivers/scsi/lpfc/lpfc_init.c | 377 +- trunk/drivers/scsi/lpfc/lpfc_nportdisc.c | 9 - trunk/drivers/scsi/lpfc/lpfc_scsi.c | 414 +- trunk/drivers/scsi/lpfc/lpfc_sli.c | 785 ++- trunk/drivers/scsi/lpfc/lpfc_sli.h | 2 +- trunk/drivers/scsi/lpfc/lpfc_sli4.h | 17 +- trunk/drivers/scsi/lpfc/lpfc_version.h | 2 +- trunk/drivers/scsi/megaraid/megaraid_sas.h | 6 +- .../drivers/scsi/megaraid/megaraid_sas_base.c | 2 +- trunk/drivers/scsi/megaraid/megaraid_sas_fp.c | 21 +- .../scsi/megaraid/megaraid_sas_fusion.c | 4 +- trunk/drivers/scsi/mpt2sas/mpi/mpi2.h | 7 +- trunk/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h | 68 +- trunk/drivers/scsi/mpt2sas/mpt2sas_base.c | 38 +- trunk/drivers/scsi/mpt2sas/mpt2sas_base.h | 10 +- trunk/drivers/scsi/mpt2sas/mpt2sas_ctl.c | 312 +- trunk/drivers/scsi/mpt2sas/mpt2sas_scsih.c | 597 +- .../drivers/scsi/mpt2sas/mpt2sas_transport.c | 243 +- trunk/drivers/scsi/pm8001/pm8001_defs.h | 3 +- trunk/drivers/scsi/pm8001/pm8001_hwi.c | 23 +- trunk/drivers/scsi/pm8001/pm8001_hwi.h | 2 +- trunk/drivers/scsi/pm8001/pm8001_init.c | 10 +- trunk/drivers/scsi/qla2xxx/qla_bsg.c | 3 - trunk/drivers/scsi/qla2xxx/qla_dbg.c | 2 +- trunk/drivers/scsi/qla2xxx/qla_isr.c | 15 +- trunk/drivers/scsi/qla2xxx/qla_nx.c | 1 - trunk/drivers/scsi/qla2xxx/qla_os.c | 18 +- trunk/drivers/scsi/qla2xxx/qla_sup.c | 3 - trunk/drivers/scsi/qla2xxx/qla_version.h | 6 +- trunk/drivers/scsi/scsi.c | 6 - trunk/drivers/scsi/scsi_lib.c | 10 +- trunk/drivers/scsi/scsi_pm.c | 2 +- trunk/drivers/scsi/scsi_priv.h | 2 - trunk/drivers/scsi/scsi_transport_fc.c | 24 +- trunk/drivers/scsi/scsi_transport_spi.c | 4 +- trunk/drivers/scsi/sd.c | 5 +- trunk/drivers/scsi/sg.c | 183 +- trunk/drivers/scsi/st.h | 2 +- trunk/drivers/scsi/storvsc_drv.c | 20 +- trunk/drivers/scsi/ufs/ufshcd.c | 8 +- trunk/drivers/scsi/virtio_scsi.c | 24 +- trunk/drivers/target/iscsi/iscsi_target.c | 821 +-- trunk/drivers/target/iscsi/iscsi_target.h | 3 +- .../target/iscsi/iscsi_target_configfs.c | 2 +- .../drivers/target/iscsi/iscsi_target_core.h | 12 +- .../target/iscsi/iscsi_target_datain_values.c | 35 +- .../drivers/target/iscsi/iscsi_target_erl0.c | 31 +- .../drivers/target/iscsi/iscsi_target_erl1.c | 23 +- .../drivers/target/iscsi/iscsi_target_erl2.c | 28 +- .../target/iscsi/iscsi_target_parameters.c | 17 + .../target/iscsi/iscsi_target_seq_pdu_list.c | 145 +- .../target/iscsi/iscsi_target_seq_pdu_list.h | 2 +- trunk/drivers/target/iscsi/iscsi_target_tmr.c | 15 +- .../drivers/target/iscsi/iscsi_target_util.c | 192 +- .../drivers/target/iscsi/iscsi_target_util.h | 3 + trunk/drivers/target/loopback/tcm_loop.c | 4 +- trunk/drivers/target/target_core_alua.c | 100 +- trunk/drivers/target/target_core_alua.h | 14 +- trunk/drivers/target/target_core_cdb.c | 118 +- trunk/drivers/target/target_core_configfs.c | 25 +- trunk/drivers/target/target_core_device.c | 84 +- trunk/drivers/target/target_core_file.c | 153 +- trunk/drivers/target/target_core_file.h | 4 + trunk/drivers/target/target_core_iblock.c | 152 +- trunk/drivers/target/target_core_iblock.h | 1 + trunk/drivers/target/target_core_internal.h | 25 +- trunk/drivers/target/target_core_pr.c | 70 +- trunk/drivers/target/target_core_pr.h | 8 +- trunk/drivers/target/target_core_pscsi.c | 179 +- trunk/drivers/target/target_core_pscsi.h | 1 + trunk/drivers/target/target_core_rd.c | 168 +- trunk/drivers/target/target_core_rd.h | 20 + trunk/drivers/target/target_core_tmr.c | 71 +- trunk/drivers/target/target_core_tpg.c | 27 +- trunk/drivers/target/target_core_transport.c | 994 ++- trunk/drivers/target/tcm_fc/tfc_cmd.c | 18 +- trunk/drivers/target/tcm_fc/tfc_conf.c | 3 + trunk/drivers/target/tcm_fc/tfc_io.c | 2 +- trunk/drivers/tty/vt/keyboard.c | 2 +- trunk/drivers/usb/gadget/Kconfig | 10 - trunk/drivers/usb/gadget/Makefile | 2 - trunk/drivers/usb/gadget/f_rndis.c | 6 +- trunk/drivers/usb/gadget/ndis.h | 164 + trunk/drivers/usb/gadget/rndis.c | 271 +- trunk/drivers/usb/gadget/rndis.h | 48 +- trunk/drivers/usb/gadget/tcm_usb_gadget.c | 2480 ------- trunk/drivers/usb/gadget/tcm_usb_gadget.h | 146 - trunk/drivers/usb/musb/musb_io.h | 2 +- trunk/drivers/vhost/net.c | 7 +- trunk/drivers/video/console/sticore.c | 2 - trunk/drivers/video/sh_mobile_lcdcfb.c | 5 +- trunk/drivers/video/sh_mobile_lcdcfb.h | 1 - trunk/drivers/video/uvesafb.c | 2 +- trunk/drivers/video/xen-fbfront.c | 27 +- trunk/drivers/virtio/Kconfig | 11 - trunk/drivers/virtio/virtio.c | 11 +- trunk/drivers/virtio/virtio_balloon.c | 34 +- trunk/drivers/virtio/virtio_mmio.c | 163 - trunk/drivers/watchdog/hpwdt.c | 46 +- trunk/drivers/xen/Kconfig | 22 +- trunk/firmware/3com/3C359.bin.ihex | 1573 +++++ trunk/firmware/Makefile | 2 + trunk/firmware/WHENCE | 38 + trunk/firmware/tr_smctr.bin.ihex | 477 ++ trunk/fs/Kconfig.binfmt | 2 +- trunk/fs/aio.c | 30 +- trunk/fs/bio.c | 7 +- trunk/fs/block_dev.c | 6 +- trunk/fs/btrfs/ctree.c | 28 +- trunk/fs/btrfs/disk-io.c | 18 +- trunk/fs/btrfs/disk-io.h | 3 +- trunk/fs/btrfs/extent-tree.c | 2 +- trunk/fs/btrfs/extent_io.c | 4 +- trunk/fs/btrfs/ioctl.h | 4 +- trunk/fs/btrfs/scrub.c | 7 - trunk/fs/btrfs/tree-log.c | 2 +- trunk/fs/buffer.c | 4 +- trunk/fs/cifs/cifsfs.c | 4 +- trunk/fs/cifs/cifsfs.h | 2 +- trunk/fs/cifs/cifssmb.c | 6 +- trunk/fs/cifs/connect.c | 24 +- trunk/fs/cifs/dir.c | 17 +- trunk/fs/dcache.c | 200 +- trunk/fs/exec.c | 10 +- trunk/fs/ext2/namei.c | 2 +- trunk/fs/ext3/namei.c | 2 +- trunk/fs/ext4/namei.c | 5 +- trunk/fs/gfs2/acl.c | 12 +- trunk/fs/gfs2/aops.c | 18 +- trunk/fs/gfs2/bmap.c | 10 +- trunk/fs/gfs2/dir.c | 2 +- trunk/fs/gfs2/file.c | 12 +- trunk/fs/gfs2/glops.c | 6 + trunk/fs/gfs2/incore.h | 26 +- trunk/fs/gfs2/inode.h | 3 + trunk/fs/gfs2/log.c | 103 +- trunk/fs/gfs2/log.h | 2 + trunk/fs/gfs2/lops.c | 520 +- trunk/fs/gfs2/lops.h | 14 +- trunk/fs/gfs2/main.c | 26 +- trunk/fs/gfs2/meta_io.c | 28 +- trunk/fs/gfs2/meta_io.h | 4 +- trunk/fs/gfs2/ops_fstype.c | 1 + trunk/fs/gfs2/quota.c | 6 +- trunk/fs/gfs2/rgrp.c | 102 +- trunk/fs/gfs2/trace_gfs2.h | 16 +- trunk/fs/gfs2/trans.c | 44 +- trunk/fs/gfs2/util.c | 3 +- trunk/fs/gfs2/util.h | 3 +- trunk/fs/hfsplus/catalog.c | 4 - trunk/fs/hfsplus/dir.c | 11 - trunk/fs/jffs2/gc.c | 2 +- trunk/fs/libfs.c | 4 +- trunk/fs/namei.c | 81 +- trunk/fs/nfs/dir.c | 5 +- trunk/fs/nfs/nfs3proc.c | 3 +- trunk/fs/nfs/nfs4proc.c | 3 +- trunk/fs/nfs/proc.c | 3 +- trunk/fs/nilfs2/namei.c | 2 +- trunk/fs/open.c | 2 +- trunk/fs/proc/base.c | 63 +- trunk/fs/proc/task_mmu.c | 12 +- trunk/fs/stat.c | 49 +- trunk/fs/ubifs/tnc.c | 2 +- trunk/fs/ubifs/xattr.c | 6 +- trunk/fs/udf/namei.c | 2 +- trunk/fs/ufs/super.c | 5 +- trunk/include/acpi/actypes.h | 7 +- trunk/include/asm-generic/pci-bridge.h | 6 - trunk/include/asm-generic/siginfo.h | 22 - trunk/include/asm-generic/statfs.h | 2 +- trunk/include/asm-generic/syscall.h | 14 - trunk/include/keys/keyring-type.h | 2 +- trunk/include/linux/Kbuild | 3 +- trunk/include/linux/amba/bus.h | 8 - trunk/include/linux/atmlec.h | 7 + trunk/include/linux/audit.h | 8 +- trunk/include/linux/blkdev.h | 3 +- trunk/include/linux/clk.h | 32 - trunk/include/linux/clkdev.h | 3 - trunk/include/linux/dcache.h | 21 +- trunk/include/linux/dmar.h | 85 + trunk/include/linux/etherdevice.h | 48 +- trunk/include/linux/ethtool.h | 40 +- trunk/include/linux/filter.h | 12 - trunk/include/linux/fs.h | 1 - trunk/include/linux/ftrace_event.h | 2 - trunk/include/linux/genhd.h | 6 + trunk/include/linux/i2c/twl.h | 13 +- trunk/include/linux/ibmtr.h | 373 ++ trunk/include/linux/if_arp.h | 3 +- trunk/include/linux/if_ec.h | 68 + trunk/include/linux/if_tr.h | 103 + trunk/include/linux/in6.h | 2 +- trunk/include/linux/interrupt.h | 8 +- trunk/include/linux/ioport.h | 7 - trunk/include/linux/ipx.h | 2 +- trunk/include/linux/key.h | 11 +- trunk/include/linux/keyctl.h | 1 - trunk/include/linux/lsm_audit.h | 6 + trunk/include/linux/mISDNhw.h | 22 +- trunk/include/linux/mISDNif.h | 9 +- trunk/include/linux/mfd/da9052/da9052.h | 1 - trunk/include/linux/mfd/palmas.h | 2620 -------- trunk/include/linux/mfd/rc5t583.h | 29 - trunk/include/linux/mfd/s5m87xx/s5m-core.h | 1 - trunk/include/linux/mfd/s5m87xx/s5m-pmic.h | 29 - trunk/include/linux/mfd/tps65090.h | 13 - trunk/include/linux/mfd/tps6586x.h | 1 - trunk/include/linux/mfd/wm8994/core.h | 12 +- trunk/include/linux/micrel_phy.h | 2 +- trunk/include/linux/mlx4/device.h | 8 - trunk/include/linux/mlx4/qp.h | 3 +- trunk/include/linux/mm.h | 6 +- trunk/include/linux/net.h | 23 - trunk/include/linux/netdevice.h | 11 + .../linux/netfilter/ipset/ip_set_ahash.h | 16 - .../linux/netfilter/ipset/ip_set_timeout.h | 4 - trunk/include/linux/netfilter/xt_HMARK.h | 45 - trunk/include/linux/netfilter/xt_hashlimit.h | 12 +- .../include/linux/netfilter_ipv6/ip6_tables.h | 7 +- trunk/include/linux/nl802154.h | 20 - trunk/include/linux/of.h | 51 - trunk/include/linux/pci.h | 9 +- trunk/include/linux/phy.h | 1 + trunk/include/linux/pinctrl/consumer.h | 44 - trunk/include/linux/pinctrl/machine.h | 7 +- trunk/include/linux/pinctrl/pinconf.h | 6 +- trunk/include/linux/pinctrl/pinctrl.h | 22 +- trunk/include/linux/pinctrl/pinmux.h | 9 +- trunk/include/linux/pkt_sched.h | 80 - trunk/include/linux/prctl.h | 15 - trunk/include/linux/ptrace.h | 5 +- trunk/include/linux/rculist.h | 40 +- trunk/include/linux/rcupdate.h | 20 - trunk/include/linux/rcutiny.h | 11 + trunk/include/linux/rcutree.h | 19 + trunk/include/linux/regmap.h | 44 +- trunk/include/linux/regulator/driver.h | 73 +- trunk/include/linux/regulator/fixed.h | 7 - trunk/include/linux/regulator/of_regulator.h | 18 - trunk/include/linux/regulator/tps62360.h | 6 +- .../linux/regulator/tps65090-regulator.h | 50 - trunk/include/linux/rndis.h | 390 -- trunk/include/linux/sched.h | 14 +- trunk/include/linux/seccomp.h | 107 +- trunk/include/linux/security.h | 14 +- trunk/include/linux/seqlock.h | 23 +- trunk/include/linux/skbuff.h | 47 +- trunk/include/linux/smp.h | 6 +- trunk/include/linux/srcu.h | 48 +- trunk/include/linux/stmmac.h | 1 - trunk/include/linux/thread_info.h | 6 - trunk/include/linux/trdevice.h | 37 + trunk/include/linux/usb/rndis_host.h | 66 +- trunk/include/linux/usb/usbnet.h | 3 +- trunk/include/linux/virtio_config.h | 11 +- trunk/include/media/soc_camera.h | 3 +- trunk/include/net/addrconf.h | 18 +- trunk/include/net/bluetooth/bluetooth.h | 1 - trunk/include/net/codel.h | 342 - trunk/include/net/ieee802154_netdev.h | 27 +- trunk/include/net/if_inet6.h | 54 + trunk/include/net/inet_frag.h | 3 +- trunk/include/net/ip.h | 17 + trunk/include/net/ip6_route.h | 2 +- trunk/include/net/ipv6.h | 34 +- trunk/include/net/lapb.h | 6 - trunk/include/net/llc_pdu.h | 7 + trunk/include/net/mac802154.h | 136 - trunk/include/net/rawv6.h | 2 +- trunk/include/net/sctp/sctp.h | 13 - trunk/include/net/sock.h | 153 +- trunk/include/net/tcp.h | 59 +- trunk/include/net/wpan-phy.h | 10 +- trunk/include/net/xfrm.h | 12 +- trunk/include/rdma/ib_mad.h | 2 +- trunk/include/rdma/ib_verbs.h | 4 +- trunk/include/scsi/iscsi_proto.h | 2 - trunk/include/scsi/sas.h | 1 - trunk/include/target/target_core_backend.h | 16 +- trunk/include/target/target_core_base.h | 59 +- trunk/include/target/target_core_fabric.h | 11 +- trunk/include/trace/events/rcu.h | 2 - trunk/include/video/vga.h | 22 + trunk/init/Kconfig | 50 +- trunk/init/Makefile | 4 - trunk/init/do_mounts.c | 2 +- trunk/init/main.c | 7 +- trunk/kernel/Makefile | 1 - trunk/kernel/auditsc.c | 8 +- trunk/kernel/compat.c | 63 +- trunk/kernel/cpu.c | 13 +- trunk/kernel/fork.c | 75 +- trunk/kernel/hung_task.c | 4 +- trunk/kernel/irq/chip.c | 5 +- trunk/kernel/irq/irqdesc.c | 1 - trunk/kernel/irq/manage.c | 46 +- trunk/kernel/irq/pm.c | 7 +- trunk/kernel/irq/resend.c | 7 +- trunk/kernel/rcupdate.c | 28 - trunk/kernel/rcutiny_plugin.h | 16 + trunk/kernel/rcutorture.c | 257 +- trunk/kernel/rcutree.c | 332 +- trunk/kernel/rcutree.h | 23 +- trunk/kernel/rcutree_plugin.h | 154 +- trunk/kernel/rcutree_trace.c | 4 +- trunk/kernel/sched/Makefile | 2 + trunk/kernel/sched/core.c | 5 - trunk/kernel/seccomp.c | 458 +- trunk/kernel/signal.c | 9 +- trunk/kernel/smp.c | 27 - trunk/kernel/smpboot.c | 62 - trunk/kernel/smpboot.h | 18 - trunk/kernel/srcu.c | 548 +- trunk/kernel/sys.c | 12 +- trunk/kernel/timer.c | 8 +- trunk/kernel/trace/trace_events.c | 5 +- trunk/kernel/trace/trace_export.c | 1 - trunk/lib/debugobjects.c | 11 +- trunk/lib/list_debug.c | 22 - trunk/mm/hugetlb.c | 1 + trunk/mm/memcontrol.c | 8 +- trunk/mm/memory.c | 28 +- trunk/mm/mmap.c | 18 +- trunk/mm/nobootmem.c | 3 +- trunk/mm/page_alloc.c | 2 +- trunk/mm/percpu.c | 22 +- trunk/mm/slub.c | 2 +- trunk/net/802/Makefile | 1 + trunk/net/802/p8022.c | 3 +- trunk/net/802/stp.c | 2 +- trunk/net/802/tr.c | 670 ++ trunk/net/8021q/vlan.c | 10 +- trunk/net/8021q/vlan_core.c | 3 +- trunk/net/8021q/vlan_dev.c | 12 +- trunk/net/9p/trans_virtio.c | 3 +- trunk/net/Kconfig | 11 +- trunk/net/Makefile | 2 +- trunk/net/atm/ioctl.c | 8 +- trunk/net/atm/lec.c | 144 +- trunk/net/atm/lec.h | 1 + trunk/net/atm/mpc.c | 3 +- trunk/net/batman-adv/bat_debugfs.c | 4 +- trunk/net/batman-adv/bat_iv_ogm.c | 183 +- trunk/net/batman-adv/bat_sysfs.c | 100 +- trunk/net/batman-adv/bridge_loop_avoidance.c | 2 +- trunk/net/batman-adv/bridge_loop_avoidance.h | 2 +- trunk/net/batman-adv/gateway_client.c | 6 +- trunk/net/batman-adv/hard-interface.c | 123 +- trunk/net/batman-adv/main.c | 124 +- trunk/net/batman-adv/main.h | 8 +- trunk/net/batman-adv/originator.c | 52 +- trunk/net/batman-adv/originator.h | 7 +- trunk/net/batman-adv/packet.h | 1 - trunk/net/batman-adv/routing.c | 49 +- trunk/net/batman-adv/routing.h | 4 +- trunk/net/batman-adv/send.c | 6 +- trunk/net/batman-adv/translation-table.c | 23 +- trunk/net/batman-adv/translation-table.h | 4 +- trunk/net/batman-adv/types.h | 19 +- trunk/net/batman-adv/unicast.c | 8 - trunk/net/bluetooth/af_bluetooth.c | 2 +- trunk/net/bluetooth/bnep/core.c | 6 +- trunk/net/bluetooth/hci_core.c | 8 - trunk/net/bluetooth/hci_event.c | 11 +- trunk/net/bluetooth/l2cap_core.c | 5 - trunk/net/bluetooth/l2cap_sock.c | 12 +- trunk/net/bridge/br_device.c | 2 +- trunk/net/bridge/br_fdb.c | 14 +- trunk/net/bridge/br_input.c | 2 +- trunk/net/bridge/br_multicast.c | 4 +- trunk/net/bridge/br_netfilter.c | 2 +- trunk/net/bridge/br_stp_bpdu.c | 2 +- trunk/net/bridge/br_stp_if.c | 11 +- trunk/net/bridge/netfilter/ebt_stp.c | 4 +- trunk/net/caif/caif_socket.c | 10 +- trunk/net/compat.c | 8 + trunk/net/core/dev.c | 83 +- trunk/net/core/drop_monitor.c | 56 +- trunk/net/core/ethtool.c | 71 +- trunk/net/core/filter.c | 6 - trunk/net/core/neighbour.c | 13 +- trunk/net/core/net_namespace.c | 6 +- trunk/net/core/netprio_cgroup.c | 6 +- trunk/net/core/pktgen.c | 58 +- trunk/net/core/rtnetlink.c | 8 +- trunk/net/core/skbuff.c | 197 +- trunk/net/core/sock.c | 39 +- trunk/net/dccp/proto.c | 4 +- trunk/net/decnet/dn_fib.c | 5 +- trunk/net/decnet/dn_neigh.c | 22 +- trunk/net/decnet/dn_nsp_in.c | 11 +- trunk/net/decnet/dn_nsp_out.c | 5 +- trunk/net/decnet/dn_route.c | 15 +- trunk/net/decnet/dn_table.c | 4 +- trunk/net/decnet/netfilter/dn_rtmsg.c | 3 +- trunk/net/dns_resolver/dns_key.c | 5 + trunk/net/dsa/slave.c | 10 +- trunk/net/econet/Kconfig | 36 + trunk/net/econet/Makefile | 7 + trunk/net/econet/af_econet.c | 1172 ++++ trunk/net/ethernet/eth.c | 5 +- trunk/net/ieee802154/nl-phy.c | 9 +- trunk/net/ipv4/Kconfig | 8 +- trunk/net/ipv4/ah4.c | 4 +- trunk/net/ipv4/arp.c | 22 +- trunk/net/ipv4/devinet.c | 5 +- trunk/net/ipv4/fib_trie.c | 2 - trunk/net/ipv4/icmp.c | 20 +- trunk/net/ipv4/inet_timewait_sock.c | 4 +- trunk/net/ipv4/ip_fragment.c | 39 +- trunk/net/ipv4/ip_input.c | 13 +- trunk/net/ipv4/ip_options.c | 6 +- trunk/net/ipv4/ip_output.c | 4 +- trunk/net/ipv4/ipconfig.c | 18 +- trunk/net/ipv4/ipmr.c | 3 +- trunk/net/ipv4/netfilter/arp_tables.c | 5 +- trunk/net/ipv4/netfilter/ip_tables.c | 3 +- trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c | 3 +- trunk/net/ipv4/netfilter/nf_nat_h323.c | 26 +- trunk/net/ipv4/netfilter/nf_nat_snmp_basic.c | 8 +- trunk/net/ipv4/route.c | 57 +- trunk/net/ipv4/tcp.c | 90 +- trunk/net/ipv4/tcp_cong.c | 6 +- trunk/net/ipv4/tcp_hybla.c | 10 +- trunk/net/ipv4/tcp_input.c | 376 +- trunk/net/ipv4/tcp_ipv4.c | 37 +- trunk/net/ipv4/tcp_minisocks.c | 24 +- trunk/net/ipv4/tcp_output.c | 82 +- trunk/net/ipv4/udp.c | 8 +- trunk/net/ipv6/Kconfig | 4 +- trunk/net/ipv6/addrconf.c | 101 +- trunk/net/ipv6/addrlabel.c | 26 +- trunk/net/ipv6/af_inet6.c | 53 +- trunk/net/ipv6/ah6.c | 30 +- trunk/net/ipv6/anycast.c | 12 +- trunk/net/ipv6/datagram.c | 4 +- trunk/net/ipv6/esp6.c | 14 +- trunk/net/ipv6/exthdrs.c | 73 +- trunk/net/ipv6/exthdrs_core.c | 2 +- trunk/net/ipv6/icmp.c | 22 +- trunk/net/ipv6/ip6_fib.c | 25 +- trunk/net/ipv6/ip6_flowlabel.c | 24 +- trunk/net/ipv6/ip6_input.c | 9 +- trunk/net/ipv6/ip6_output.c | 16 +- trunk/net/ipv6/ip6_tunnel.c | 58 +- trunk/net/ipv6/ip6mr.c | 5 +- trunk/net/ipv6/ipcomp6.c | 15 +- trunk/net/ipv6/mcast.c | 69 +- trunk/net/ipv6/mip6.c | 32 +- trunk/net/ipv6/ndisc.c | 243 +- trunk/net/ipv6/netfilter/ip6_tables.c | 39 +- trunk/net/ipv6/netfilter/ip6t_REJECT.c | 6 +- trunk/net/ipv6/netfilter/ip6t_ah.c | 4 +- trunk/net/ipv6/netfilter/ip6t_frag.c | 4 +- trunk/net/ipv6/netfilter/ip6t_hbh.c | 4 +- trunk/net/ipv6/netfilter/ip6t_rt.c | 4 +- trunk/net/ipv6/netfilter/ip6table_mangle.c | 3 +- .../netfilter/nf_conntrack_l3proto_ipv6.c | 3 +- trunk/net/ipv6/netfilter/nf_conntrack_reasm.c | 7 +- trunk/net/ipv6/raw.c | 10 +- trunk/net/ipv6/reassembly.c | 41 +- trunk/net/ipv6/route.c | 24 +- trunk/net/ipv6/sit.c | 12 +- trunk/net/ipv6/tcp_ipv6.c | 14 +- trunk/net/ipv6/tunnel6.c | 10 +- trunk/net/ipv6/udp.c | 6 +- trunk/net/ipx/af_ipx.c | 14 +- trunk/net/l2tp/l2tp_core.c | 219 +- trunk/net/l2tp/l2tp_core.h | 36 +- trunk/net/l2tp/l2tp_debugfs.c | 6 +- trunk/net/l2tp/l2tp_eth.c | 15 +- trunk/net/l2tp/l2tp_ip.c | 15 +- trunk/net/l2tp/l2tp_ip6.c | 15 +- trunk/net/l2tp/l2tp_netlink.c | 4 +- trunk/net/l2tp/l2tp_ppp.c | 128 +- trunk/net/lapb/lapb_iface.c | 22 +- trunk/net/lapb/lapb_in.c | 320 +- trunk/net/lapb/lapb_out.c | 38 +- trunk/net/lapb/lapb_subr.c | 28 +- trunk/net/lapb/lapb_timer.c | 32 +- trunk/net/llc/af_llc.c | 14 +- trunk/net/llc/llc_output.c | 3 + trunk/net/llc/llc_sap.c | 4 + trunk/net/mac80211/agg-rx.c | 13 +- trunk/net/mac80211/cfg.c | 2 +- trunk/net/mac80211/ht.c | 8 +- trunk/net/mac80211/ibss.c | 22 +- trunk/net/mac80211/ieee80211_i.h | 2 +- trunk/net/mac80211/iface.c | 2 +- trunk/net/mac80211/mesh.c | 4 +- trunk/net/mac80211/mesh_hwmp.c | 14 +- trunk/net/mac80211/mesh_pathtbl.c | 12 +- trunk/net/mac80211/mlme.c | 41 +- trunk/net/mac80211/rx.c | 50 +- trunk/net/mac80211/scan.c | 2 +- trunk/net/mac80211/sta_info.c | 8 +- trunk/net/mac80211/sta_info.h | 2 +- trunk/net/mac80211/status.c | 2 +- trunk/net/mac80211/tx.c | 28 +- trunk/net/mac802154/Kconfig | 16 - trunk/net/mac802154/Makefile | 2 - trunk/net/mac802154/ieee802154_dev.c | 294 - trunk/net/mac802154/mac802154.h | 109 - trunk/net/mac802154/mac_cmd.c | 45 - trunk/net/mac802154/mib.c | 93 - trunk/net/mac802154/monitor.c | 116 - trunk/net/mac802154/rx.c | 114 - trunk/net/mac802154/tx.c | 116 - trunk/net/netfilter/Kconfig | 15 - trunk/net/netfilter/Makefile | 1 - .../net/netfilter/ipset/ip_set_bitmap_ipmac.c | 4 +- trunk/net/netfilter/ipset/ip_set_hash_ip.c | 10 +- .../net/netfilter/ipset/ip_set_hash_ipport.c | 10 +- .../netfilter/ipset/ip_set_hash_ipportip.c | 10 +- .../netfilter/ipset/ip_set_hash_ipportnet.c | 10 +- trunk/net/netfilter/ipset/ip_set_hash_net.c | 10 +- .../netfilter/ipset/ip_set_hash_netiface.c | 10 +- .../net/netfilter/ipset/ip_set_hash_netport.c | 10 +- trunk/net/netfilter/nf_conntrack_amanda.c | 3 +- trunk/net/netfilter/nf_conntrack_core.c | 5 +- trunk/net/netfilter/nf_conntrack_expect.c | 4 +- trunk/net/netfilter/nf_conntrack_h323_main.c | 13 +- trunk/net/netfilter/nf_conntrack_irc.c | 8 +- trunk/net/netfilter/nf_conntrack_proto_tcp.c | 3 +- trunk/net/netfilter/nfnetlink_queue.c | 9 +- trunk/net/netfilter/xt_CT.c | 1 + trunk/net/netfilter/xt_HMARK.c | 362 -- trunk/net/netfilter/xt_TCPMSS.c | 10 +- trunk/net/netfilter/xt_TPROXY.c | 4 +- trunk/net/netfilter/xt_hashlimit.c | 132 +- trunk/net/netfilter/xt_limit.c | 5 +- trunk/net/netfilter/xt_mac.c | 2 +- trunk/net/netfilter/xt_set.c | 15 +- trunk/net/netfilter/xt_socket.c | 4 +- trunk/net/openvswitch/datapath.c | 29 +- trunk/net/openvswitch/flow.c | 3 +- trunk/net/openvswitch/vport-netdev.c | 6 +- trunk/net/sched/Kconfig | 22 - trunk/net/sched/Makefile | 2 - trunk/net/sched/act_csum.c | 2 +- trunk/net/sched/act_ipt.c | 7 +- trunk/net/sched/act_mirred.c | 5 +- trunk/net/sched/cls_u32.c | 3 +- trunk/net/sched/ematch.c | 4 +- trunk/net/sched/sch_api.c | 10 +- trunk/net/sched/sch_atm.c | 4 +- trunk/net/sched/sch_codel.c | 276 - trunk/net/sched/sch_drr.c | 4 +- trunk/net/sched/sch_fq_codel.c | 626 -- trunk/net/sched/sch_generic.c | 11 +- trunk/net/sched/sch_gred.c | 12 +- trunk/net/sched/sch_hfsc.c | 2 +- trunk/net/sched/sch_htb.c | 2 +- trunk/net/sctp/output.c | 4 +- trunk/net/sctp/sm_sideeffect.c | 5 +- trunk/net/sctp/sm_statefuns.c | 18 +- trunk/net/sctp/socket.c | 6 +- trunk/net/sctp/transport.c | 17 + trunk/net/socket.c | 3 +- trunk/net/sunrpc/auth_gss/gss_mech_switch.c | 7 +- trunk/net/sunrpc/clnt.c | 4 +- trunk/net/sunrpc/rpc_pipe.c | 7 +- trunk/net/sunrpc/svc.c | 18 +- trunk/net/sunrpc/svc_xprt.c | 13 +- trunk/net/sunrpc/svcsock.c | 28 +- trunk/net/sysctl_net.c | 4 + trunk/net/wireless/ibss.c | 2 +- trunk/net/wireless/lib80211_crypt_ccmp.c | 33 +- trunk/net/wireless/lib80211_crypt_tkip.c | 50 +- trunk/net/wireless/mlme.c | 31 +- trunk/net/wireless/scan.c | 2 +- trunk/net/wireless/util.c | 11 +- trunk/net/wireless/wext-sme.c | 2 +- trunk/net/wireless/wext-spy.c | 2 +- trunk/net/xfrm/Kconfig | 13 +- trunk/net/xfrm/Makefile | 3 +- trunk/net/xfrm/xfrm_algo.c | 5 +- trunk/net/xfrm/xfrm_policy.c | 28 +- trunk/samples/Makefile | 2 +- trunk/samples/seccomp/Makefile | 32 - trunk/samples/seccomp/bpf-direct.c | 190 - trunk/samples/seccomp/bpf-fancy.c | 102 - trunk/samples/seccomp/bpf-helper.c | 89 - trunk/samples/seccomp/bpf-helper.h | 238 - trunk/samples/seccomp/dropper.c | 68 - trunk/scripts/Makefile | 2 - trunk/security/Kconfig | 68 +- trunk/security/apparmor/audit.c | 11 +- trunk/security/apparmor/capability.c | 4 +- trunk/security/apparmor/domain.c | 35 - trunk/security/apparmor/file.c | 2 +- trunk/security/apparmor/include/audit.h | 1 - trunk/security/apparmor/ipc.c | 2 +- trunk/security/apparmor/lib.c | 2 +- trunk/security/apparmor/lsm.c | 6 +- trunk/security/apparmor/path.c | 2 - trunk/security/apparmor/policy.c | 6 +- trunk/security/apparmor/policy_unpack.c | 2 +- trunk/security/apparmor/resource.c | 2 +- trunk/security/capability.c | 4 +- trunk/security/commoncap.c | 7 +- trunk/security/integrity/ima/ima_main.c | 4 +- trunk/security/keys/Kconfig | 71 - trunk/security/keys/Makefile | 12 +- trunk/security/keys/compat.c | 3 - trunk/security/keys/gc.c | 94 +- trunk/security/keys/internal.h | 15 +- trunk/security/keys/key.c | 25 - trunk/security/keys/keyctl.c | 34 - trunk/security/keys/keyring.c | 167 +- trunk/security/keys/permission.c | 43 +- trunk/security/keys/proc.c | 3 +- trunk/security/keys/process_keys.c | 2 - trunk/security/lsm_audit.c | 15 +- trunk/security/security.c | 4 +- trunk/security/selinux/avc.c | 130 +- trunk/security/selinux/hooks.c | 268 +- trunk/security/selinux/include/avc.h | 100 +- trunk/security/selinux/include/security.h | 4 +- trunk/security/selinux/netif.c | 6 +- trunk/security/selinux/netnode.c | 6 +- trunk/security/selinux/netport.c | 6 +- trunk/security/selinux/selinuxfs.c | 11 +- trunk/security/selinux/ss/context.h | 20 - trunk/security/selinux/ss/mls.c | 24 - trunk/security/selinux/ss/policydb.c | 44 - trunk/security/selinux/ss/policydb.h | 14 - trunk/security/selinux/ss/services.c | 56 +- trunk/security/smack/smack.h | 59 +- trunk/security/smack/smack_access.c | 233 +- trunk/security/smack/smack_lsm.c | 243 +- trunk/security/smack/smackfs.c | 993 +-- trunk/security/tomoyo/common.c | 26 +- trunk/security/tomoyo/common.h | 1 + trunk/security/tomoyo/tomoyo.c | 6 +- trunk/security/yama/yama_lsm.c | 63 +- trunk/sound/pci/echoaudio/echoaudio_dsp.c | 2 +- trunk/sound/pci/hda/hda_codec.c | 4 + trunk/sound/pci/hda/hda_intel.c | 20 +- trunk/sound/pci/hda/patch_realtek.c | 16 +- trunk/sound/pci/hda/patch_sigmatel.c | 6 +- trunk/sound/pci/rme9652/hdsp.c | 1 - trunk/sound/soc/blackfin/bf5xx-ssm2602.c | 2 - trunk/sound/soc/codecs/cs42l73.c | 16 +- trunk/sound/soc/codecs/sgtl5000.c | 8 +- trunk/sound/soc/codecs/tlv320aic23.c | 4 +- trunk/sound/soc/codecs/wm8350.c | 11 +- trunk/sound/soc/codecs/wm8994.c | 2 +- trunk/sound/soc/codecs/wm_hubs.c | 15 +- trunk/sound/soc/omap/omap-pcm.c | 4 - trunk/sound/soc/samsung/s3c2412-i2s.c | 2 +- trunk/sound/soc/sh/migor.c | 2 +- trunk/sound/soc/soc-core.c | 6 +- trunk/tools/perf/Makefile | 4 +- trunk/tools/perf/builtin-stat.c | 40 +- trunk/tools/perf/util/header.c | 2 +- 1994 files changed, 77199 insertions(+), 87650 deletions(-) delete mode 100644 trunk/Documentation/devicetree/bindings/arm/arch_timer.txt delete mode 100644 trunk/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt delete mode 100644 trunk/Documentation/devicetree/bindings/pinctrl/fsl,imx51-pinctrl.txt delete mode 100644 trunk/Documentation/devicetree/bindings/pinctrl/fsl,imx53-pinctrl.txt delete mode 100644 trunk/Documentation/devicetree/bindings/pinctrl/fsl,imx6q-pinctrl.txt delete mode 100644 trunk/Documentation/devicetree/bindings/pinctrl/fsl,mxs-pinctrl.txt delete mode 100644 trunk/Documentation/devicetree/bindings/pinctrl/nvidia,tegra20-pinmux.txt delete mode 100644 trunk/Documentation/devicetree/bindings/pinctrl/nvidia,tegra30-pinmux.txt delete mode 100644 trunk/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt create mode 100644 trunk/Documentation/devicetree/bindings/pinmux/pinmux_nvidia.txt delete mode 100644 trunk/Documentation/devicetree/bindings/regulator/tps62360-regulator.txt delete mode 100644 trunk/Documentation/devicetree/bindings/regulator/tps6586x.txt create mode 100644 trunk/Documentation/networking/3c359.txt create mode 100644 trunk/Documentation/networking/olympic.txt create mode 100644 trunk/Documentation/networking/smctr.txt create mode 100644 trunk/Documentation/networking/tms380tr.txt delete mode 100644 trunk/Documentation/prctl/seccomp_filter.txt create mode 100644 trunk/Documentation/sparc/README-2.5 rename trunk/{init => arch/alpha/kernel}/init_task.c (73%) delete mode 100644 trunk/arch/arm/include/asm/arch_timer.h delete mode 100644 trunk/arch/arm/include/asm/syscall.h delete mode 100644 trunk/arch/arm/kernel/arch_timer.c create mode 100644 trunk/arch/arm/kernel/init_task.c create mode 100644 trunk/arch/arm/lib/io-readsw-armv3.S create mode 100644 trunk/arch/arm/lib/io-writesw-armv3.S create mode 100644 trunk/arch/arm/lib/uaccess.S create mode 100644 trunk/arch/arm/mach-integrator/include/mach/entry-macro.S create mode 100644 trunk/arch/arm/mach-mxs/devices/amba-duart.c create mode 100644 trunk/arch/arm/mm/copypage-v3.c create mode 100644 trunk/arch/arm/mm/proc-arm6_7.S create mode 100644 trunk/arch/arm/mm/tlb-v3.S create mode 100644 trunk/arch/avr32/kernel/init_task.c create mode 100644 trunk/arch/blackfin/ADI_BSD.txt delete mode 100644 trunk/arch/blackfin/Clear_BSD.txt delete mode 100644 trunk/arch/blackfin/configs/BF609-EZKIT_defconfig delete mode 100644 trunk/arch/blackfin/include/asm/bfin6xx_spi.h delete mode 100644 trunk/arch/blackfin/include/asm/bfin_crc.h delete mode 100644 trunk/arch/blackfin/include/asm/bfin_sport3.h delete mode 100644 trunk/arch/blackfin/include/asm/clkdev.h delete mode 100644 trunk/arch/blackfin/include/asm/pm.h create mode 100644 trunk/arch/blackfin/kernel/init_task.c delete mode 100644 trunk/arch/blackfin/mach-bf609/Kconfig delete mode 100644 trunk/arch/blackfin/mach-bf609/Makefile delete mode 100644 trunk/arch/blackfin/mach-bf609/boards/Kconfig delete mode 100644 trunk/arch/blackfin/mach-bf609/boards/Makefile delete mode 100644 trunk/arch/blackfin/mach-bf609/boards/ezkit.c delete mode 100644 trunk/arch/blackfin/mach-bf609/clock.c delete mode 100644 trunk/arch/blackfin/mach-bf609/dma.c delete mode 100644 trunk/arch/blackfin/mach-bf609/hibernate.S delete mode 100644 trunk/arch/blackfin/mach-bf609/include/mach/anomaly.h delete mode 100644 trunk/arch/blackfin/mach-bf609/include/mach/bf609.h delete mode 100644 trunk/arch/blackfin/mach-bf609/include/mach/bfin_serial.h delete mode 100644 trunk/arch/blackfin/mach-bf609/include/mach/blackfin.h delete mode 100644 trunk/arch/blackfin/mach-bf609/include/mach/cdefBF609.h delete mode 100644 trunk/arch/blackfin/mach-bf609/include/mach/cdefBF60x_base.h delete mode 100644 trunk/arch/blackfin/mach-bf609/include/mach/defBF609.h delete mode 100644 trunk/arch/blackfin/mach-bf609/include/mach/defBF60x_base.h delete mode 100644 trunk/arch/blackfin/mach-bf609/include/mach/dma.h delete mode 100644 trunk/arch/blackfin/mach-bf609/include/mach/gpio.h delete mode 100644 trunk/arch/blackfin/mach-bf609/include/mach/irq.h delete mode 100644 trunk/arch/blackfin/mach-bf609/include/mach/mem_map.h delete mode 100644 trunk/arch/blackfin/mach-bf609/include/mach/pll.h delete mode 100644 trunk/arch/blackfin/mach-bf609/include/mach/pm.h delete mode 100644 trunk/arch/blackfin/mach-bf609/include/mach/portmux.h delete mode 100644 trunk/arch/blackfin/mach-bf609/pm.c delete mode 100644 trunk/arch/blackfin/mach-common/clock.h create mode 100644 trunk/arch/frv/kernel/init_task.c create mode 100644 trunk/arch/h8300/kernel/init_task.c create mode 100644 trunk/arch/hexagon/kernel/init_task.c delete mode 100644 trunk/arch/ia64/include/asm/irq_remapping.h create mode 100644 trunk/arch/m32r/kernel/init_task.c delete mode 100644 trunk/arch/m68k/configs/m5475evb_defconfig delete mode 100644 trunk/arch/m68k/include/asm/vga.h create mode 100644 trunk/arch/m68k/kernel/dma_mm.c create mode 100644 trunk/arch/m68k/kernel/dma_no.c create mode 100644 trunk/arch/m68k/kernel/init_task.c create mode 100644 trunk/arch/m68k/kernel/signal_mm.c create mode 100644 trunk/arch/m68k/kernel/signal_no.c create mode 100644 trunk/arch/m68k/platform/5206/Makefile rename trunk/arch/m68k/platform/{coldfire/m5206.c => 5206/config.c} (80%) create mode 100644 trunk/arch/m68k/platform/5206/gpio.c create mode 100644 trunk/arch/m68k/platform/520x/Makefile rename trunk/arch/m68k/platform/{coldfire/m520x.c => 520x/config.c} (79%) create mode 100644 trunk/arch/m68k/platform/520x/gpio.c create mode 100644 trunk/arch/m68k/platform/523x/Makefile rename trunk/arch/m68k/platform/{coldfire/m523x.c => 523x/config.c} (68%) create mode 100644 trunk/arch/m68k/platform/523x/gpio.c create mode 100644 trunk/arch/m68k/platform/5249/Makefile rename trunk/arch/m68k/platform/{coldfire/m5249.c => 5249/config.c} (82%) create mode 100644 trunk/arch/m68k/platform/5249/gpio.c rename trunk/arch/m68k/platform/{coldfire/intc-5249.c => 5249/intc2.c} (100%) create mode 100644 trunk/arch/m68k/platform/5272/Makefile rename trunk/arch/m68k/platform/{coldfire/m5272.c => 5272/config.c} (88%) create mode 100644 trunk/arch/m68k/platform/5272/gpio.c rename trunk/arch/m68k/platform/{coldfire/intc-5272.c => 5272/intc.c} (100%) create mode 100644 trunk/arch/m68k/platform/527x/Makefile rename trunk/arch/m68k/platform/{coldfire/m527x.c => 527x/config.c} (67%) create mode 100644 trunk/arch/m68k/platform/527x/gpio.c create mode 100644 trunk/arch/m68k/platform/528x/Makefile rename trunk/arch/m68k/platform/{coldfire/m528x.c => 528x/config.c} (70%) create mode 100644 trunk/arch/m68k/platform/528x/gpio.c create mode 100644 trunk/arch/m68k/platform/5307/Makefile rename trunk/arch/m68k/platform/{coldfire/m5307.c => 5307/config.c} (85%) create mode 100644 trunk/arch/m68k/platform/5307/gpio.c rename trunk/arch/m68k/platform/{coldfire => 5307}/nettel.c (100%) create mode 100644 trunk/arch/m68k/platform/532x/Makefile rename trunk/arch/m68k/platform/{coldfire/m532x.c => 532x/config.c} (93%) create mode 100644 trunk/arch/m68k/platform/532x/gpio.c create mode 100644 trunk/arch/m68k/platform/5407/Makefile rename trunk/arch/m68k/platform/{coldfire/m5407.c => 5407/config.c} (77%) create mode 100644 trunk/arch/m68k/platform/5407/gpio.c create mode 100644 trunk/arch/m68k/platform/54xx/Makefile rename trunk/arch/m68k/platform/{coldfire/m54xx.c => 54xx/config.c} (93%) rename trunk/arch/m68k/platform/{coldfire => 54xx}/firebee.c (100%) create mode 100644 trunk/arch/microblaze/kernel/init_task.c create mode 100644 trunk/arch/mips/kernel/init_task.c create mode 100644 trunk/arch/mn10300/kernel/init_task.c create mode 100644 trunk/arch/openrisc/kernel/init_task.c create mode 100644 trunk/arch/parisc/kernel/init_task.c create mode 100644 trunk/arch/powerpc/kernel/init_task.c delete mode 100644 trunk/arch/s390/boot/.gitignore delete mode 100644 trunk/arch/s390/boot/compressed/.gitignore delete mode 100644 trunk/arch/s390/kernel/.gitignore create mode 100644 trunk/arch/s390/kernel/init_task.c delete mode 100644 trunk/arch/s390/kernel/vdso32/.gitignore delete mode 100644 trunk/arch/s390/kernel/vdso64/.gitignore create mode 100644 trunk/arch/score/kernel/init_task.c create mode 100644 trunk/arch/sh/kernel/init_task.c delete mode 100644 trunk/arch/sparc/Kbuild create mode 100644 trunk/arch/sparc/boot/btfixupprep.c create mode 100644 trunk/arch/sparc/include/asm/btfixup.h delete mode 100644 trunk/arch/sparc/include/asm/cachetlb_32.h create mode 100644 trunk/arch/sparc/include/asm/cypress.h create mode 100644 trunk/arch/sparc/include/asm/memreg.h create mode 100644 trunk/arch/sparc/include/asm/pgtsun4c.h create mode 100644 trunk/arch/sparc/include/asm/smpprim.h create mode 100644 trunk/arch/sparc/include/asm/sysen.h create mode 100644 trunk/arch/sparc/include/asm/vac-ops.h create mode 100644 trunk/arch/sparc/kernel/init_task.c create mode 100644 trunk/arch/sparc/kernel/muldiv.c create mode 100644 trunk/arch/sparc/kernel/sun4c_irq.c rename trunk/arch/sparc/kernel/{ttable_64.S => ttable.S} (100%) delete mode 100644 trunk/arch/sparc/kernel/ttable_32.S create mode 100644 trunk/arch/sparc/lib/atomic_32.S create mode 100644 trunk/arch/sparc/lib/mul.S create mode 100644 trunk/arch/sparc/lib/rem.S create mode 100644 trunk/arch/sparc/lib/sdiv.S delete mode 100644 trunk/arch/sparc/lib/ucmpdi2.c create mode 100644 trunk/arch/sparc/lib/udiv.S create mode 100644 trunk/arch/sparc/lib/umul.S create mode 100644 trunk/arch/sparc/lib/urem.S create mode 100644 trunk/arch/sparc/mm/btfixup.c create mode 100644 trunk/arch/sparc/mm/loadmmu.c create mode 100644 trunk/arch/sparc/mm/nosun4c.c delete mode 100644 trunk/arch/sparc/mm/srmmu.h create mode 100644 trunk/arch/sparc/mm/sun4c.c create mode 100644 trunk/arch/sparc/prom/segment.c create mode 100644 trunk/arch/tile/kernel/init_task.c create mode 100644 trunk/arch/um/kernel/init_task.c create mode 100644 trunk/arch/unicore32/kernel/init_task.c rename trunk/arch/x86/{tools => boot/compressed}/relocs.c (76%) create mode 100644 trunk/arch/x86/kernel/init_task.c delete mode 100644 trunk/arch/x86/tools/.gitignore create mode 100644 trunk/arch/xtensa/kernel/init_task.c delete mode 100644 trunk/drivers/base/regmap/regmap-mmio.c delete mode 100644 trunk/drivers/ieee802154/fakelb.c delete mode 100644 trunk/drivers/infiniband/hw/cxgb4/id_table.c delete mode 100644 trunk/drivers/infiniband/hw/ocrdma/Kconfig delete mode 100644 trunk/drivers/infiniband/hw/ocrdma/Makefile delete mode 100644 trunk/drivers/infiniband/hw/ocrdma/ocrdma.h delete mode 100644 trunk/drivers/infiniband/hw/ocrdma/ocrdma_abi.h delete mode 100644 trunk/drivers/infiniband/hw/ocrdma/ocrdma_ah.c delete mode 100644 trunk/drivers/infiniband/hw/ocrdma/ocrdma_ah.h delete mode 100644 trunk/drivers/infiniband/hw/ocrdma/ocrdma_hw.c delete mode 100644 trunk/drivers/infiniband/hw/ocrdma/ocrdma_hw.h delete mode 100644 trunk/drivers/infiniband/hw/ocrdma/ocrdma_main.c delete mode 100644 trunk/drivers/infiniband/hw/ocrdma/ocrdma_sli.h delete mode 100644 trunk/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c delete mode 100644 trunk/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h rename trunk/drivers/iommu/{intel_irq_remapping.c => intr_remapping.c} (66%) create mode 100644 trunk/drivers/iommu/intr_remapping.h delete mode 100644 trunk/drivers/iommu/irq_remapping.c delete mode 100644 trunk/drivers/iommu/irq_remapping.h delete mode 100644 trunk/drivers/mfd/palmas.c create mode 100644 trunk/drivers/net/ethernet/8390/ne2.c create mode 100644 trunk/drivers/net/ethernet/8390/smc-mca.c delete mode 100644 trunk/drivers/net/ethernet/emulex/benet/be_roce.c delete mode 100644 trunk/drivers/net/ethernet/emulex/benet/be_roce.h create mode 100644 trunk/drivers/net/ethernet/i825xx/3c523.c create mode 100644 trunk/drivers/net/ethernet/i825xx/3c523.h create mode 100644 trunk/drivers/net/ethernet/i825xx/3c527.c create mode 100644 trunk/drivers/net/ethernet/i825xx/3c527.h delete mode 100644 trunk/drivers/net/ethernet/intel/igb/e1000_i210.c delete mode 100644 trunk/drivers/net/ethernet/intel/igb/e1000_i210.h delete mode 100644 trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c create mode 100644 trunk/drivers/net/tokenring/3c359.c create mode 100644 trunk/drivers/net/tokenring/3c359.h create mode 100644 trunk/drivers/net/tokenring/Kconfig create mode 100644 trunk/drivers/net/tokenring/Makefile create mode 100644 trunk/drivers/net/tokenring/abyss.c create mode 100644 trunk/drivers/net/tokenring/abyss.h create mode 100644 trunk/drivers/net/tokenring/ibmtr.c create mode 100644 trunk/drivers/net/tokenring/ibmtr_cs.c create mode 100644 trunk/drivers/net/tokenring/lanstreamer.c create mode 100644 trunk/drivers/net/tokenring/lanstreamer.h create mode 100644 trunk/drivers/net/tokenring/madgemc.c create mode 100644 trunk/drivers/net/tokenring/madgemc.h create mode 100644 trunk/drivers/net/tokenring/olympic.c create mode 100644 trunk/drivers/net/tokenring/olympic.h create mode 100644 trunk/drivers/net/tokenring/proteon.c create mode 100644 trunk/drivers/net/tokenring/skisa.c create mode 100644 trunk/drivers/net/tokenring/smctr.c create mode 100644 trunk/drivers/net/tokenring/smctr.h create mode 100644 trunk/drivers/net/tokenring/tms380tr.c create mode 100644 trunk/drivers/net/tokenring/tms380tr.h create mode 100644 trunk/drivers/net/tokenring/tmspci.c delete mode 100644 trunk/drivers/pci/host-bridge.c delete mode 100644 trunk/drivers/pinctrl/devicetree.c delete mode 100644 trunk/drivers/pinctrl/devicetree.h delete mode 100644 trunk/drivers/pinctrl/pinctrl-imx.c delete mode 100644 trunk/drivers/pinctrl/pinctrl-imx.h delete mode 100644 trunk/drivers/pinctrl/pinctrl-imx23.c delete mode 100644 trunk/drivers/pinctrl/pinctrl-imx28.c delete mode 100644 trunk/drivers/pinctrl/pinctrl-imx51.c delete mode 100644 trunk/drivers/pinctrl/pinctrl-imx53.c delete mode 100644 trunk/drivers/pinctrl/pinctrl-imx6q.c delete mode 100644 trunk/drivers/pinctrl/pinctrl-mxs.c delete mode 100644 trunk/drivers/pinctrl/pinctrl-mxs.h delete mode 100644 trunk/drivers/regulator/palmas-regulator.c delete mode 100644 trunk/drivers/regulator/rc5t583-regulator.c delete mode 100644 trunk/drivers/regulator/tps65090-regulator.c delete mode 100644 trunk/drivers/usb/gadget/tcm_usb_gadget.c delete mode 100644 trunk/drivers/usb/gadget/tcm_usb_gadget.h create mode 100644 trunk/firmware/3com/3C359.bin.ihex create mode 100644 trunk/firmware/tr_smctr.bin.ihex create mode 100644 trunk/include/linux/ibmtr.h create mode 100644 trunk/include/linux/if_ec.h create mode 100644 trunk/include/linux/if_tr.h delete mode 100644 trunk/include/linux/mfd/palmas.h delete mode 100644 trunk/include/linux/netfilter/xt_HMARK.h delete mode 100644 trunk/include/linux/regulator/tps65090-regulator.h delete mode 100644 trunk/include/linux/rndis.h create mode 100644 trunk/include/linux/trdevice.h delete mode 100644 trunk/include/net/codel.h delete mode 100644 trunk/include/net/mac802154.h delete mode 100644 trunk/kernel/smpboot.c delete mode 100644 trunk/kernel/smpboot.h create mode 100644 trunk/net/802/tr.c create mode 100644 trunk/net/econet/Kconfig create mode 100644 trunk/net/econet/Makefile create mode 100644 trunk/net/econet/af_econet.c delete mode 100644 trunk/net/mac802154/Kconfig delete mode 100644 trunk/net/mac802154/Makefile delete mode 100644 trunk/net/mac802154/ieee802154_dev.c delete mode 100644 trunk/net/mac802154/mac802154.h delete mode 100644 trunk/net/mac802154/mac_cmd.c delete mode 100644 trunk/net/mac802154/mib.c delete mode 100644 trunk/net/mac802154/monitor.c delete mode 100644 trunk/net/mac802154/rx.c delete mode 100644 trunk/net/mac802154/tx.c delete mode 100644 trunk/net/netfilter/xt_HMARK.c delete mode 100644 trunk/net/sched/sch_codel.c delete mode 100644 trunk/net/sched/sch_fq_codel.c delete mode 100644 trunk/samples/seccomp/Makefile delete mode 100644 trunk/samples/seccomp/bpf-direct.c delete mode 100644 trunk/samples/seccomp/bpf-fancy.c delete mode 100644 trunk/samples/seccomp/bpf-helper.c delete mode 100644 trunk/samples/seccomp/bpf-helper.h delete mode 100644 trunk/samples/seccomp/dropper.c delete mode 100644 trunk/security/keys/Kconfig diff --git a/[refs] b/[refs] index 4cecbab19691..299eb277bdd6 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 35c579070a349cfe54f9e09a47df2c5b68d58469 +refs/heads/master: 2a4ffa4c8934bd9a36c8354a4b87a529114baf62 diff --git a/trunk/Documentation/RCU/torture.txt b/trunk/Documentation/RCU/torture.txt index 4ddf3913fd8c..375d3fb71437 100644 --- a/trunk/Documentation/RCU/torture.txt +++ b/trunk/Documentation/RCU/torture.txt @@ -47,16 +47,6 @@ irqreader Says to invoke RCU readers from irq level. This is currently permit this. (Or, more accurately, variants of RCU that do -not- permit this know to ignore this variable.) -n_barrier_cbs If this is nonzero, RCU barrier testing will be conducted, - in which case n_barrier_cbs specifies the number of - RCU callbacks (and corresponding kthreads) to use for - this testing. The value cannot be negative. If you - specify this to be non-zero when torture_type indicates a - synchronous RCU implementation (one for which a member of - the synchronize_rcu() rather than the call_rcu() family is - used -- see the documentation for torture_type below), an - error will be reported and no testing will be carried out. - nfakewriters This is the number of RCU fake writer threads to run. Fake writer threads repeatedly use the synchronous "wait for current readers" function of the interface selected by @@ -198,7 +188,7 @@ OUTPUT The statistics output is as follows: rcu-torture:--- Start of test: nreaders=16 nfakewriters=4 stat_interval=30 verbose=0 test_no_idle_hz=1 shuffle_interval=3 stutter=5 irqreader=1 fqs_duration=0 fqs_holdoff=0 fqs_stutter=3 test_boost=1/0 test_boost_interval=7 test_boost_duration=4 - rcu-torture: rtc: (null) ver: 155441 tfle: 0 rta: 155441 rtaf: 8884 rtf: 155440 rtmbe: 0 rtbe: 0 rtbke: 0 rtbre: 0 rtbf: 0 rtb: 0 nt: 3055767 + rcu-torture: rtc: (null) ver: 155441 tfle: 0 rta: 155441 rtaf: 8884 rtf: 155440 rtmbe: 0 rtbke: 0 rtbre: 0 rtbf: 0 rtb: 0 nt: 3055767 rcu-torture: Reader Pipe: 727860534 34213 0 0 0 0 0 0 0 0 0 rcu-torture: Reader Batch: 727877838 17003 0 0 0 0 0 0 0 0 0 rcu-torture: Free-Block Circulation: 155440 155440 155440 155440 155440 155440 155440 155440 155440 155440 0 @@ -240,9 +230,6 @@ o "rtmbe": A non-zero value indicates that rcutorture believes that rcu_assign_pointer() and rcu_dereference() are not working correctly. This value should be zero. -o "rtbe": A non-zero value indicates that one of the rcu_barrier() - family of functions is not working correctly. - o "rtbke": rcutorture was unable to create the real-time kthreads used to force RCU priority inversion. This value should be zero. diff --git a/trunk/Documentation/devicetree/bindings/arm/arch_timer.txt b/trunk/Documentation/devicetree/bindings/arm/arch_timer.txt deleted file mode 100644 index 52478c83d0cc..000000000000 --- a/trunk/Documentation/devicetree/bindings/arm/arch_timer.txt +++ /dev/null @@ -1,27 +0,0 @@ -* ARM architected timer - -ARM Cortex-A7 and Cortex-A15 have a per-core architected timer, which -provides per-cpu timers. - -The timer is attached to a GIC to deliver its per-processor interrupts. - -** Timer node properties: - -- compatible : Should at least contain "arm,armv7-timer". - -- interrupts : Interrupt list for secure, non-secure, virtual and - hypervisor timers, in that order. - -- clock-frequency : The frequency of the main counter, in Hz. Optional. - -Example: - - timer { - compatible = "arm,cortex-a15-timer", - "arm,armv7-timer"; - interrupts = <1 13 0xf08>, - <1 14 0xf08>, - <1 11 0xf08>, - <1 10 0xf08>; - clock-frequency = <100000000>; - }; diff --git a/trunk/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt b/trunk/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt deleted file mode 100644 index ab19e6bc7d3b..000000000000 --- a/trunk/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt +++ /dev/null @@ -1,95 +0,0 @@ -* Freescale IOMUX Controller (IOMUXC) for i.MX - -The IOMUX Controller (IOMUXC), together with the IOMUX, enables the IC -to share one PAD to several functional blocks. The sharing is done by -multiplexing the PAD input/output signals. For each PAD there are up to -8 muxing options (called ALT modes). Since different modules require -different PAD settings (like pull up, keeper, etc) the IOMUXC controls -also the PAD settings parameters. - -Please refer to pinctrl-bindings.txt in this directory for details of the -common pinctrl bindings used by client devices, including the meaning of the -phrase "pin configuration node". - -Freescale IMX pin configuration node is a node of a group of pins which can be -used for a specific device or function. This node represents both mux and config -of the pins in that group. The 'mux' selects the function mode(also named mux -mode) this pin can work on and the 'config' configures various pad settings -such as pull-up, open drain, drive strength, etc. - -Required properties for iomux controller: -- compatible: "fsl,-iomuxc" - Please refer to each fsl,-pinctrl.txt binding doc for supported SoCs. - -Required properties for pin configuration node: -- fsl,pins: two integers array, represents a group of pins mux and config - setting. The format is fsl,pins = , PIN_FUNC_ID is a - pin working on a specific function, CONFIG is the pad setting value like - pull-up on this pin. Please refer to fsl,-pinctrl.txt for the valid - pins and functions of each SoC. - -Bits used for CONFIG: -NO_PAD_CTL(1 << 31): indicate this pin does not need config. - -SION(1 << 30): Software Input On Field. -Force the selected mux mode input path no matter of MUX_MODE functionality. -By default the input path is determined by functionality of the selected -mux mode (regular). - -Other bits are used for PAD setting. -Please refer to each fsl,-pinctrl,txt binding doc for SoC specific part -of bits definitions. - -NOTE: -Some requirements for using fsl,imx-pinctrl binding: -1. We have pin function node defined under iomux controller node to represent - what pinmux functions this SoC supports. -2. The pin configuration node intends to work on a specific function should - to be defined under that specific function node. - The function node's name should represent well about what function - this group of pins in this pin configuration node are working on. -3. The driver can use the function node's name and pin configuration node's - name describe the pin function and group hierarchy. - For example, Linux IMX pinctrl driver takes the function node's name - as the function name and pin configuration node's name as group name to - create the map table. -4. Each pin configuration node should have a phandle, devices can set pins - configurations by referring to the phandle of that pin configuration node. - -Examples: -usdhc@0219c000 { /* uSDHC4 */ - fsl,card-wired; - vmmc-supply = <®_3p3v>; - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usdhc4_1>; -}; - -iomuxc@020e0000 { - compatible = "fsl,imx6q-iomuxc"; - reg = <0x020e0000 0x4000>; - - /* shared pinctrl settings */ - usdhc4 { - pinctrl_usdhc4_1: usdhc4grp-1 { - fsl,pins = <1386 0x17059 /* MX6Q_PAD_SD4_CMD__USDHC4_CMD */ - 1392 0x10059 /* MX6Q_PAD_SD4_CLK__USDHC4_CLK */ - 1462 0x17059 /* MX6Q_PAD_SD4_DAT0__USDHC4_DAT0 */ - 1470 0x17059 /* MX6Q_PAD_SD4_DAT1__USDHC4_DAT1 */ - 1478 0x17059 /* MX6Q_PAD_SD4_DAT2__USDHC4_DAT2 */ - 1486 0x17059 /* MX6Q_PAD_SD4_DAT3__USDHC4_DAT3 */ - 1493 0x17059 /* MX6Q_PAD_SD4_DAT4__USDHC4_DAT4 */ - 1501 0x17059 /* MX6Q_PAD_SD4_DAT5__USDHC4_DAT5 */ - 1509 0x17059 /* MX6Q_PAD_SD4_DAT6__USDHC4_DAT6 */ - 1517 0x17059>; /* MX6Q_PAD_SD4_DAT7__USDHC4_DAT7 */ - }; - }; - .... -}; -Refer to the IOMUXC controller chapter in imx6q datasheet, -0x17059 means enable hysteresis, 47KOhm Pull Up, 50Mhz speed, -80Ohm driver strength and Fast Slew Rate. -User should refer to each SoC spec to set the correct value. - -TODO: when dtc macro support is available, we can change above raw data -to dt macro which can get better readability in dts file. diff --git a/trunk/Documentation/devicetree/bindings/pinctrl/fsl,imx51-pinctrl.txt b/trunk/Documentation/devicetree/bindings/pinctrl/fsl,imx51-pinctrl.txt deleted file mode 100644 index b96fa4c31745..000000000000 --- a/trunk/Documentation/devicetree/bindings/pinctrl/fsl,imx51-pinctrl.txt +++ /dev/null @@ -1,787 +0,0 @@ -* Freescale IMX51 IOMUX Controller - -Please refer to fsl,imx-pinctrl.txt in this directory for common binding part -and usage. - -Required properties: -- compatible: "fsl,imx51-iomuxc" -- fsl,pins: two integers array, represents a group of pins mux and config - setting. The format is fsl,pins = , PIN_FUNC_ID is a - pin working on a specific function, CONFIG is the pad setting value like - pull-up for this pin. Please refer to imx51 datasheet for the valid pad - config settings. - -CONFIG bits definition: -PAD_CTL_HVE (1 << 13) -PAD_CTL_HYS (1 << 8) -PAD_CTL_PKE (1 << 7) -PAD_CTL_PUE (1 << 6) -PAD_CTL_PUS_100K_DOWN (0 << 4) -PAD_CTL_PUS_47K_UP (1 << 4) -PAD_CTL_PUS_100K_UP (2 << 4) -PAD_CTL_PUS_22K_UP (3 << 4) -PAD_CTL_ODE (1 << 3) -PAD_CTL_DSE_LOW (0 << 1) -PAD_CTL_DSE_MED (1 << 1) -PAD_CTL_DSE_HIGH (2 << 1) -PAD_CTL_DSE_MAX (3 << 1) -PAD_CTL_SRE_FAST (1 << 0) -PAD_CTL_SRE_SLOW (0 << 0) - -See below for available PIN_FUNC_ID for imx51: -MX51_PAD_EIM_D16__AUD4_RXFS 0 -MX51_PAD_EIM_D16__AUD5_TXD 1 -MX51_PAD_EIM_D16__EIM_D16 2 -MX51_PAD_EIM_D16__GPIO2_0 3 -MX51_PAD_EIM_D16__I2C1_SDA 4 -MX51_PAD_EIM_D16__UART2_CTS 5 -MX51_PAD_EIM_D16__USBH2_DATA0 6 -MX51_PAD_EIM_D17__AUD5_RXD 7 -MX51_PAD_EIM_D17__EIM_D17 8 -MX51_PAD_EIM_D17__GPIO2_1 9 -MX51_PAD_EIM_D17__UART2_RXD 10 -MX51_PAD_EIM_D17__UART3_CTS 11 -MX51_PAD_EIM_D17__USBH2_DATA1 12 -MX51_PAD_EIM_D18__AUD5_TXC 13 -MX51_PAD_EIM_D18__EIM_D18 14 -MX51_PAD_EIM_D18__GPIO2_2 15 -MX51_PAD_EIM_D18__UART2_TXD 16 -MX51_PAD_EIM_D18__UART3_RTS 17 -MX51_PAD_EIM_D18__USBH2_DATA2 18 -MX51_PAD_EIM_D19__AUD4_RXC 19 -MX51_PAD_EIM_D19__AUD5_TXFS 20 -MX51_PAD_EIM_D19__EIM_D19 21 -MX51_PAD_EIM_D19__GPIO2_3 22 -MX51_PAD_EIM_D19__I2C1_SCL 23 -MX51_PAD_EIM_D19__UART2_RTS 24 -MX51_PAD_EIM_D19__USBH2_DATA3 25 -MX51_PAD_EIM_D20__AUD4_TXD 26 -MX51_PAD_EIM_D20__EIM_D20 27 -MX51_PAD_EIM_D20__GPIO2_4 28 -MX51_PAD_EIM_D20__SRTC_ALARM_DEB 29 -MX51_PAD_EIM_D20__USBH2_DATA4 30 -MX51_PAD_EIM_D21__AUD4_RXD 31 -MX51_PAD_EIM_D21__EIM_D21 32 -MX51_PAD_EIM_D21__GPIO2_5 33 -MX51_PAD_EIM_D21__SRTC_ALARM_DEB 34 -MX51_PAD_EIM_D21__USBH2_DATA5 35 -MX51_PAD_EIM_D22__AUD4_TXC 36 -MX51_PAD_EIM_D22__EIM_D22 37 -MX51_PAD_EIM_D22__GPIO2_6 38 -MX51_PAD_EIM_D22__USBH2_DATA6 39 -MX51_PAD_EIM_D23__AUD4_TXFS 40 -MX51_PAD_EIM_D23__EIM_D23 41 -MX51_PAD_EIM_D23__GPIO2_7 42 -MX51_PAD_EIM_D23__SPDIF_OUT1 43 -MX51_PAD_EIM_D23__USBH2_DATA7 44 -MX51_PAD_EIM_D24__AUD6_RXFS 45 -MX51_PAD_EIM_D24__EIM_D24 46 -MX51_PAD_EIM_D24__GPIO2_8 47 -MX51_PAD_EIM_D24__I2C2_SDA 48 -MX51_PAD_EIM_D24__UART3_CTS 49 -MX51_PAD_EIM_D24__USBOTG_DATA0 50 -MX51_PAD_EIM_D25__EIM_D25 51 -MX51_PAD_EIM_D25__KEY_COL6 52 -MX51_PAD_EIM_D25__UART2_CTS 53 -MX51_PAD_EIM_D25__UART3_RXD 54 -MX51_PAD_EIM_D25__USBOTG_DATA1 55 -MX51_PAD_EIM_D26__EIM_D26 56 -MX51_PAD_EIM_D26__KEY_COL7 57 -MX51_PAD_EIM_D26__UART2_RTS 58 -MX51_PAD_EIM_D26__UART3_TXD 59 -MX51_PAD_EIM_D26__USBOTG_DATA2 60 -MX51_PAD_EIM_D27__AUD6_RXC 61 -MX51_PAD_EIM_D27__EIM_D27 62 -MX51_PAD_EIM_D27__GPIO2_9 63 -MX51_PAD_EIM_D27__I2C2_SCL 64 -MX51_PAD_EIM_D27__UART3_RTS 65 -MX51_PAD_EIM_D27__USBOTG_DATA3 66 -MX51_PAD_EIM_D28__AUD6_TXD 67 -MX51_PAD_EIM_D28__EIM_D28 68 -MX51_PAD_EIM_D28__KEY_ROW4 69 -MX51_PAD_EIM_D28__USBOTG_DATA4 70 -MX51_PAD_EIM_D29__AUD6_RXD 71 -MX51_PAD_EIM_D29__EIM_D29 72 -MX51_PAD_EIM_D29__KEY_ROW5 73 -MX51_PAD_EIM_D29__USBOTG_DATA5 74 -MX51_PAD_EIM_D30__AUD6_TXC 75 -MX51_PAD_EIM_D30__EIM_D30 76 -MX51_PAD_EIM_D30__KEY_ROW6 77 -MX51_PAD_EIM_D30__USBOTG_DATA6 78 -MX51_PAD_EIM_D31__AUD6_TXFS 79 -MX51_PAD_EIM_D31__EIM_D31 80 -MX51_PAD_EIM_D31__KEY_ROW7 81 -MX51_PAD_EIM_D31__USBOTG_DATA7 82 -MX51_PAD_EIM_A16__EIM_A16 83 -MX51_PAD_EIM_A16__GPIO2_10 84 -MX51_PAD_EIM_A16__OSC_FREQ_SEL0 85 -MX51_PAD_EIM_A17__EIM_A17 86 -MX51_PAD_EIM_A17__GPIO2_11 87 -MX51_PAD_EIM_A17__OSC_FREQ_SEL1 88 -MX51_PAD_EIM_A18__BOOT_LPB0 89 -MX51_PAD_EIM_A18__EIM_A18 90 -MX51_PAD_EIM_A18__GPIO2_12 91 -MX51_PAD_EIM_A19__BOOT_LPB1 92 -MX51_PAD_EIM_A19__EIM_A19 93 -MX51_PAD_EIM_A19__GPIO2_13 94 -MX51_PAD_EIM_A20__BOOT_UART_SRC0 95 -MX51_PAD_EIM_A20__EIM_A20 96 -MX51_PAD_EIM_A20__GPIO2_14 97 -MX51_PAD_EIM_A21__BOOT_UART_SRC1 98 -MX51_PAD_EIM_A21__EIM_A21 99 -MX51_PAD_EIM_A21__GPIO2_15 100 -MX51_PAD_EIM_A22__EIM_A22 101 -MX51_PAD_EIM_A22__GPIO2_16 102 -MX51_PAD_EIM_A23__BOOT_HPN_EN 103 -MX51_PAD_EIM_A23__EIM_A23 104 -MX51_PAD_EIM_A23__GPIO2_17 105 -MX51_PAD_EIM_A24__EIM_A24 106 -MX51_PAD_EIM_A24__GPIO2_18 107 -MX51_PAD_EIM_A24__USBH2_CLK 108 -MX51_PAD_EIM_A25__DISP1_PIN4 109 -MX51_PAD_EIM_A25__EIM_A25 110 -MX51_PAD_EIM_A25__GPIO2_19 111 -MX51_PAD_EIM_A25__USBH2_DIR 112 -MX51_PAD_EIM_A26__CSI1_DATA_EN 113 -MX51_PAD_EIM_A26__DISP2_EXT_CLK 114 -MX51_PAD_EIM_A26__EIM_A26 115 -MX51_PAD_EIM_A26__GPIO2_20 116 -MX51_PAD_EIM_A26__USBH2_STP 117 -MX51_PAD_EIM_A27__CSI2_DATA_EN 118 -MX51_PAD_EIM_A27__DISP1_PIN1 119 -MX51_PAD_EIM_A27__EIM_A27 120 -MX51_PAD_EIM_A27__GPIO2_21 121 -MX51_PAD_EIM_A27__USBH2_NXT 122 -MX51_PAD_EIM_EB0__EIM_EB0 123 -MX51_PAD_EIM_EB1__EIM_EB1 124 -MX51_PAD_EIM_EB2__AUD5_RXFS 125 -MX51_PAD_EIM_EB2__CSI1_D2 126 -MX51_PAD_EIM_EB2__EIM_EB2 127 -MX51_PAD_EIM_EB2__FEC_MDIO 128 -MX51_PAD_EIM_EB2__GPIO2_22 129 -MX51_PAD_EIM_EB2__GPT_CMPOUT1 130 -MX51_PAD_EIM_EB3__AUD5_RXC 131 -MX51_PAD_EIM_EB3__CSI1_D3 132 -MX51_PAD_EIM_EB3__EIM_EB3 133 -MX51_PAD_EIM_EB3__FEC_RDATA1 134 -MX51_PAD_EIM_EB3__GPIO2_23 135 -MX51_PAD_EIM_EB3__GPT_CMPOUT2 136 -MX51_PAD_EIM_OE__EIM_OE 137 -MX51_PAD_EIM_OE__GPIO2_24 138 -MX51_PAD_EIM_CS0__EIM_CS0 139 -MX51_PAD_EIM_CS0__GPIO2_25 140 -MX51_PAD_EIM_CS1__EIM_CS1 141 -MX51_PAD_EIM_CS1__GPIO2_26 142 -MX51_PAD_EIM_CS2__AUD5_TXD 143 -MX51_PAD_EIM_CS2__CSI1_D4 144 -MX51_PAD_EIM_CS2__EIM_CS2 145 -MX51_PAD_EIM_CS2__FEC_RDATA2 146 -MX51_PAD_EIM_CS2__GPIO2_27 147 -MX51_PAD_EIM_CS2__USBOTG_STP 148 -MX51_PAD_EIM_CS3__AUD5_RXD 149 -MX51_PAD_EIM_CS3__CSI1_D5 150 -MX51_PAD_EIM_CS3__EIM_CS3 151 -MX51_PAD_EIM_CS3__FEC_RDATA3 152 -MX51_PAD_EIM_CS3__GPIO2_28 153 -MX51_PAD_EIM_CS3__USBOTG_NXT 154 -MX51_PAD_EIM_CS4__AUD5_TXC 155 -MX51_PAD_EIM_CS4__CSI1_D6 156 -MX51_PAD_EIM_CS4__EIM_CS4 157 -MX51_PAD_EIM_CS4__FEC_RX_ER 158 -MX51_PAD_EIM_CS4__GPIO2_29 159 -MX51_PAD_EIM_CS4__USBOTG_CLK 160 -MX51_PAD_EIM_CS5__AUD5_TXFS 161 -MX51_PAD_EIM_CS5__CSI1_D7 162 -MX51_PAD_EIM_CS5__DISP1_EXT_CLK 163 -MX51_PAD_EIM_CS5__EIM_CS5 164 -MX51_PAD_EIM_CS5__FEC_CRS 165 -MX51_PAD_EIM_CS5__GPIO2_30 166 -MX51_PAD_EIM_CS5__USBOTG_DIR 167 -MX51_PAD_EIM_DTACK__EIM_DTACK 168 -MX51_PAD_EIM_DTACK__GPIO2_31 169 -MX51_PAD_EIM_LBA__EIM_LBA 170 -MX51_PAD_EIM_LBA__GPIO3_1 171 -MX51_PAD_EIM_CRE__EIM_CRE 172 -MX51_PAD_EIM_CRE__GPIO3_2 173 -MX51_PAD_DRAM_CS1__DRAM_CS1 174 -MX51_PAD_NANDF_WE_B__GPIO3_3 175 -MX51_PAD_NANDF_WE_B__NANDF_WE_B 176 -MX51_PAD_NANDF_WE_B__PATA_DIOW 177 -MX51_PAD_NANDF_WE_B__SD3_DATA0 178 -MX51_PAD_NANDF_RE_B__GPIO3_4 179 -MX51_PAD_NANDF_RE_B__NANDF_RE_B 180 -MX51_PAD_NANDF_RE_B__PATA_DIOR 181 -MX51_PAD_NANDF_RE_B__SD3_DATA1 182 -MX51_PAD_NANDF_ALE__GPIO3_5 183 -MX51_PAD_NANDF_ALE__NANDF_ALE 184 -MX51_PAD_NANDF_ALE__PATA_BUFFER_EN 185 -MX51_PAD_NANDF_CLE__GPIO3_6 186 -MX51_PAD_NANDF_CLE__NANDF_CLE 187 -MX51_PAD_NANDF_CLE__PATA_RESET_B 188 -MX51_PAD_NANDF_WP_B__GPIO3_7 189 -MX51_PAD_NANDF_WP_B__NANDF_WP_B 190 -MX51_PAD_NANDF_WP_B__PATA_DMACK 191 -MX51_PAD_NANDF_WP_B__SD3_DATA2 192 -MX51_PAD_NANDF_RB0__ECSPI2_SS1 193 -MX51_PAD_NANDF_RB0__GPIO3_8 194 -MX51_PAD_NANDF_RB0__NANDF_RB0 195 -MX51_PAD_NANDF_RB0__PATA_DMARQ 196 -MX51_PAD_NANDF_RB0__SD3_DATA3 197 -MX51_PAD_NANDF_RB1__CSPI_MOSI 198 -MX51_PAD_NANDF_RB1__ECSPI2_RDY 199 -MX51_PAD_NANDF_RB1__GPIO3_9 200 -MX51_PAD_NANDF_RB1__NANDF_RB1 201 -MX51_PAD_NANDF_RB1__PATA_IORDY 202 -MX51_PAD_NANDF_RB1__SD4_CMD 203 -MX51_PAD_NANDF_RB2__DISP2_WAIT 204 -MX51_PAD_NANDF_RB2__ECSPI2_SCLK 205 -MX51_PAD_NANDF_RB2__FEC_COL 206 -MX51_PAD_NANDF_RB2__GPIO3_10 207 -MX51_PAD_NANDF_RB2__NANDF_RB2 208 -MX51_PAD_NANDF_RB2__USBH3_H3_DP 209 -MX51_PAD_NANDF_RB2__USBH3_NXT 210 -MX51_PAD_NANDF_RB3__DISP1_WAIT 211 -MX51_PAD_NANDF_RB3__ECSPI2_MISO 212 -MX51_PAD_NANDF_RB3__FEC_RX_CLK 213 -MX51_PAD_NANDF_RB3__GPIO3_11 214 -MX51_PAD_NANDF_RB3__NANDF_RB3 215 -MX51_PAD_NANDF_RB3__USBH3_CLK 216 -MX51_PAD_NANDF_RB3__USBH3_H3_DM 217 -MX51_PAD_GPIO_NAND__GPIO_NAND 218 -MX51_PAD_GPIO_NAND__PATA_INTRQ 219 -MX51_PAD_NANDF_CS0__GPIO3_16 220 -MX51_PAD_NANDF_CS0__NANDF_CS0 221 -MX51_PAD_NANDF_CS1__GPIO3_17 222 -MX51_PAD_NANDF_CS1__NANDF_CS1 223 -MX51_PAD_NANDF_CS2__CSPI_SCLK 224 -MX51_PAD_NANDF_CS2__FEC_TX_ER 225 -MX51_PAD_NANDF_CS2__GPIO3_18 226 -MX51_PAD_NANDF_CS2__NANDF_CS2 227 -MX51_PAD_NANDF_CS2__PATA_CS_0 228 -MX51_PAD_NANDF_CS2__SD4_CLK 229 -MX51_PAD_NANDF_CS2__USBH3_H1_DP 230 -MX51_PAD_NANDF_CS3__FEC_MDC 231 -MX51_PAD_NANDF_CS3__GPIO3_19 232 -MX51_PAD_NANDF_CS3__NANDF_CS3 233 -MX51_PAD_NANDF_CS3__PATA_CS_1 234 -MX51_PAD_NANDF_CS3__SD4_DAT0 235 -MX51_PAD_NANDF_CS3__USBH3_H1_DM 236 -MX51_PAD_NANDF_CS4__FEC_TDATA1 237 -MX51_PAD_NANDF_CS4__GPIO3_20 238 -MX51_PAD_NANDF_CS4__NANDF_CS4 239 -MX51_PAD_NANDF_CS4__PATA_DA_0 240 -MX51_PAD_NANDF_CS4__SD4_DAT1 241 -MX51_PAD_NANDF_CS4__USBH3_STP 242 -MX51_PAD_NANDF_CS5__FEC_TDATA2 243 -MX51_PAD_NANDF_CS5__GPIO3_21 244 -MX51_PAD_NANDF_CS5__NANDF_CS5 245 -MX51_PAD_NANDF_CS5__PATA_DA_1 246 -MX51_PAD_NANDF_CS5__SD4_DAT2 247 -MX51_PAD_NANDF_CS5__USBH3_DIR 248 -MX51_PAD_NANDF_CS6__CSPI_SS3 249 -MX51_PAD_NANDF_CS6__FEC_TDATA3 250 -MX51_PAD_NANDF_CS6__GPIO3_22 251 -MX51_PAD_NANDF_CS6__NANDF_CS6 252 -MX51_PAD_NANDF_CS6__PATA_DA_2 253 -MX51_PAD_NANDF_CS6__SD4_DAT3 254 -MX51_PAD_NANDF_CS7__FEC_TX_EN 255 -MX51_PAD_NANDF_CS7__GPIO3_23 256 -MX51_PAD_NANDF_CS7__NANDF_CS7 257 -MX51_PAD_NANDF_CS7__SD3_CLK 258 -MX51_PAD_NANDF_RDY_INT__ECSPI2_SS0 259 -MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK 260 -MX51_PAD_NANDF_RDY_INT__GPIO3_24 261 -MX51_PAD_NANDF_RDY_INT__NANDF_RDY_INT 262 -MX51_PAD_NANDF_RDY_INT__SD3_CMD 263 -MX51_PAD_NANDF_D15__ECSPI2_MOSI 264 -MX51_PAD_NANDF_D15__GPIO3_25 265 -MX51_PAD_NANDF_D15__NANDF_D15 266 -MX51_PAD_NANDF_D15__PATA_DATA15 267 -MX51_PAD_NANDF_D15__SD3_DAT7 268 -MX51_PAD_NANDF_D14__ECSPI2_SS3 269 -MX51_PAD_NANDF_D14__GPIO3_26 270 -MX51_PAD_NANDF_D14__NANDF_D14 271 -MX51_PAD_NANDF_D14__PATA_DATA14 272 -MX51_PAD_NANDF_D14__SD3_DAT6 273 -MX51_PAD_NANDF_D13__ECSPI2_SS2 274 -MX51_PAD_NANDF_D13__GPIO3_27 275 -MX51_PAD_NANDF_D13__NANDF_D13 276 -MX51_PAD_NANDF_D13__PATA_DATA13 277 -MX51_PAD_NANDF_D13__SD3_DAT5 278 -MX51_PAD_NANDF_D12__ECSPI2_SS1 279 -MX51_PAD_NANDF_D12__GPIO3_28 280 -MX51_PAD_NANDF_D12__NANDF_D12 281 -MX51_PAD_NANDF_D12__PATA_DATA12 282 -MX51_PAD_NANDF_D12__SD3_DAT4 283 -MX51_PAD_NANDF_D11__FEC_RX_DV 284 -MX51_PAD_NANDF_D11__GPIO3_29 285 -MX51_PAD_NANDF_D11__NANDF_D11 286 -MX51_PAD_NANDF_D11__PATA_DATA11 287 -MX51_PAD_NANDF_D11__SD3_DATA3 288 -MX51_PAD_NANDF_D10__GPIO3_30 289 -MX51_PAD_NANDF_D10__NANDF_D10 290 -MX51_PAD_NANDF_D10__PATA_DATA10 291 -MX51_PAD_NANDF_D10__SD3_DATA2 292 -MX51_PAD_NANDF_D9__FEC_RDATA0 293 -MX51_PAD_NANDF_D9__GPIO3_31 294 -MX51_PAD_NANDF_D9__NANDF_D9 295 -MX51_PAD_NANDF_D9__PATA_DATA9 296 -MX51_PAD_NANDF_D9__SD3_DATA1 297 -MX51_PAD_NANDF_D8__FEC_TDATA0 298 -MX51_PAD_NANDF_D8__GPIO4_0 299 -MX51_PAD_NANDF_D8__NANDF_D8 300 -MX51_PAD_NANDF_D8__PATA_DATA8 301 -MX51_PAD_NANDF_D8__SD3_DATA0 302 -MX51_PAD_NANDF_D7__GPIO4_1 303 -MX51_PAD_NANDF_D7__NANDF_D7 304 -MX51_PAD_NANDF_D7__PATA_DATA7 305 -MX51_PAD_NANDF_D7__USBH3_DATA0 306 -MX51_PAD_NANDF_D6__GPIO4_2 307 -MX51_PAD_NANDF_D6__NANDF_D6 308 -MX51_PAD_NANDF_D6__PATA_DATA6 309 -MX51_PAD_NANDF_D6__SD4_LCTL 310 -MX51_PAD_NANDF_D6__USBH3_DATA1 311 -MX51_PAD_NANDF_D5__GPIO4_3 312 -MX51_PAD_NANDF_D5__NANDF_D5 313 -MX51_PAD_NANDF_D5__PATA_DATA5 314 -MX51_PAD_NANDF_D5__SD4_WP 315 -MX51_PAD_NANDF_D5__USBH3_DATA2 316 -MX51_PAD_NANDF_D4__GPIO4_4 317 -MX51_PAD_NANDF_D4__NANDF_D4 318 -MX51_PAD_NANDF_D4__PATA_DATA4 319 -MX51_PAD_NANDF_D4__SD4_CD 320 -MX51_PAD_NANDF_D4__USBH3_DATA3 321 -MX51_PAD_NANDF_D3__GPIO4_5 322 -MX51_PAD_NANDF_D3__NANDF_D3 323 -MX51_PAD_NANDF_D3__PATA_DATA3 324 -MX51_PAD_NANDF_D3__SD4_DAT4 325 -MX51_PAD_NANDF_D3__USBH3_DATA4 326 -MX51_PAD_NANDF_D2__GPIO4_6 327 -MX51_PAD_NANDF_D2__NANDF_D2 328 -MX51_PAD_NANDF_D2__PATA_DATA2 329 -MX51_PAD_NANDF_D2__SD4_DAT5 330 -MX51_PAD_NANDF_D2__USBH3_DATA5 331 -MX51_PAD_NANDF_D1__GPIO4_7 332 -MX51_PAD_NANDF_D1__NANDF_D1 333 -MX51_PAD_NANDF_D1__PATA_DATA1 334 -MX51_PAD_NANDF_D1__SD4_DAT6 335 -MX51_PAD_NANDF_D1__USBH3_DATA6 336 -MX51_PAD_NANDF_D0__GPIO4_8 337 -MX51_PAD_NANDF_D0__NANDF_D0 338 -MX51_PAD_NANDF_D0__PATA_DATA0 339 -MX51_PAD_NANDF_D0__SD4_DAT7 340 -MX51_PAD_NANDF_D0__USBH3_DATA7 341 -MX51_PAD_CSI1_D8__CSI1_D8 342 -MX51_PAD_CSI1_D8__GPIO3_12 343 -MX51_PAD_CSI1_D9__CSI1_D9 344 -MX51_PAD_CSI1_D9__GPIO3_13 345 -MX51_PAD_CSI1_D10__CSI1_D10 346 -MX51_PAD_CSI1_D11__CSI1_D11 347 -MX51_PAD_CSI1_D12__CSI1_D12 348 -MX51_PAD_CSI1_D13__CSI1_D13 349 -MX51_PAD_CSI1_D14__CSI1_D14 350 -MX51_PAD_CSI1_D15__CSI1_D15 351 -MX51_PAD_CSI1_D16__CSI1_D16 352 -MX51_PAD_CSI1_D17__CSI1_D17 353 -MX51_PAD_CSI1_D18__CSI1_D18 354 -MX51_PAD_CSI1_D19__CSI1_D19 355 -MX51_PAD_CSI1_VSYNC__CSI1_VSYNC 356 -MX51_PAD_CSI1_VSYNC__GPIO3_14 357 -MX51_PAD_CSI1_HSYNC__CSI1_HSYNC 358 -MX51_PAD_CSI1_HSYNC__GPIO3_15 359 -MX51_PAD_CSI1_PIXCLK__CSI1_PIXCLK 360 -MX51_PAD_CSI1_MCLK__CSI1_MCLK 361 -MX51_PAD_CSI2_D12__CSI2_D12 362 -MX51_PAD_CSI2_D12__GPIO4_9 363 -MX51_PAD_CSI2_D13__CSI2_D13 364 -MX51_PAD_CSI2_D13__GPIO4_10 365 -MX51_PAD_CSI2_D14__CSI2_D14 366 -MX51_PAD_CSI2_D15__CSI2_D15 367 -MX51_PAD_CSI2_D16__CSI2_D16 368 -MX51_PAD_CSI2_D17__CSI2_D17 369 -MX51_PAD_CSI2_D18__CSI2_D18 370 -MX51_PAD_CSI2_D18__GPIO4_11 371 -MX51_PAD_CSI2_D19__CSI2_D19 372 -MX51_PAD_CSI2_D19__GPIO4_12 373 -MX51_PAD_CSI2_VSYNC__CSI2_VSYNC 374 -MX51_PAD_CSI2_VSYNC__GPIO4_13 375 -MX51_PAD_CSI2_HSYNC__CSI2_HSYNC 376 -MX51_PAD_CSI2_HSYNC__GPIO4_14 377 -MX51_PAD_CSI2_PIXCLK__CSI2_PIXCLK 378 -MX51_PAD_CSI2_PIXCLK__GPIO4_15 379 -MX51_PAD_I2C1_CLK__GPIO4_16 380 -MX51_PAD_I2C1_CLK__I2C1_CLK 381 -MX51_PAD_I2C1_DAT__GPIO4_17 382 -MX51_PAD_I2C1_DAT__I2C1_DAT 383 -MX51_PAD_AUD3_BB_TXD__AUD3_TXD 384 -MX51_PAD_AUD3_BB_TXD__GPIO4_18 385 -MX51_PAD_AUD3_BB_RXD__AUD3_RXD 386 -MX51_PAD_AUD3_BB_RXD__GPIO4_19 387 -MX51_PAD_AUD3_BB_RXD__UART3_RXD 388 -MX51_PAD_AUD3_BB_CK__AUD3_TXC 389 -MX51_PAD_AUD3_BB_CK__GPIO4_20 390 -MX51_PAD_AUD3_BB_FS__AUD3_TXFS 391 -MX51_PAD_AUD3_BB_FS__GPIO4_21 392 -MX51_PAD_AUD3_BB_FS__UART3_TXD 393 -MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI 394 -MX51_PAD_CSPI1_MOSI__GPIO4_22 395 -MX51_PAD_CSPI1_MOSI__I2C1_SDA 396 -MX51_PAD_CSPI1_MISO__AUD4_RXD 397 -MX51_PAD_CSPI1_MISO__ECSPI1_MISO 398 -MX51_PAD_CSPI1_MISO__GPIO4_23 399 -MX51_PAD_CSPI1_SS0__AUD4_TXC 400 -MX51_PAD_CSPI1_SS0__ECSPI1_SS0 401 -MX51_PAD_CSPI1_SS0__GPIO4_24 402 -MX51_PAD_CSPI1_SS1__AUD4_TXD 403 -MX51_PAD_CSPI1_SS1__ECSPI1_SS1 404 -MX51_PAD_CSPI1_SS1__GPIO4_25 405 -MX51_PAD_CSPI1_RDY__AUD4_TXFS 406 -MX51_PAD_CSPI1_RDY__ECSPI1_RDY 407 -MX51_PAD_CSPI1_RDY__GPIO4_26 408 -MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK 409 -MX51_PAD_CSPI1_SCLK__GPIO4_27 410 -MX51_PAD_CSPI1_SCLK__I2C1_SCL 411 -MX51_PAD_UART1_RXD__GPIO4_28 412 -MX51_PAD_UART1_RXD__UART1_RXD 413 -MX51_PAD_UART1_TXD__GPIO4_29 414 -MX51_PAD_UART1_TXD__PWM2_PWMO 415 -MX51_PAD_UART1_TXD__UART1_TXD 416 -MX51_PAD_UART1_RTS__GPIO4_30 417 -MX51_PAD_UART1_RTS__UART1_RTS 418 -MX51_PAD_UART1_CTS__GPIO4_31 419 -MX51_PAD_UART1_CTS__UART1_CTS 420 -MX51_PAD_UART2_RXD__FIRI_TXD 421 -MX51_PAD_UART2_RXD__GPIO1_20 422 -MX51_PAD_UART2_RXD__UART2_RXD 423 -MX51_PAD_UART2_TXD__FIRI_RXD 424 -MX51_PAD_UART2_TXD__GPIO1_21 425 -MX51_PAD_UART2_TXD__UART2_TXD 426 -MX51_PAD_UART3_RXD__CSI1_D0 427 -MX51_PAD_UART3_RXD__GPIO1_22 428 -MX51_PAD_UART3_RXD__UART1_DTR 429 -MX51_PAD_UART3_RXD__UART3_RXD 430 -MX51_PAD_UART3_TXD__CSI1_D1 431 -MX51_PAD_UART3_TXD__GPIO1_23 432 -MX51_PAD_UART3_TXD__UART1_DSR 433 -MX51_PAD_UART3_TXD__UART3_TXD 434 -MX51_PAD_OWIRE_LINE__GPIO1_24 435 -MX51_PAD_OWIRE_LINE__OWIRE_LINE 436 -MX51_PAD_OWIRE_LINE__SPDIF_OUT 437 -MX51_PAD_KEY_ROW0__KEY_ROW0 438 -MX51_PAD_KEY_ROW1__KEY_ROW1 439 -MX51_PAD_KEY_ROW2__KEY_ROW2 440 -MX51_PAD_KEY_ROW3__KEY_ROW3 441 -MX51_PAD_KEY_COL0__KEY_COL0 442 -MX51_PAD_KEY_COL0__PLL1_BYP 443 -MX51_PAD_KEY_COL1__KEY_COL1 444 -MX51_PAD_KEY_COL1__PLL2_BYP 445 -MX51_PAD_KEY_COL2__KEY_COL2 446 -MX51_PAD_KEY_COL2__PLL3_BYP 447 -MX51_PAD_KEY_COL3__KEY_COL3 448 -MX51_PAD_KEY_COL4__I2C2_SCL 449 -MX51_PAD_KEY_COL4__KEY_COL4 450 -MX51_PAD_KEY_COL4__SPDIF_OUT1 451 -MX51_PAD_KEY_COL4__UART1_RI 452 -MX51_PAD_KEY_COL4__UART3_RTS 453 -MX51_PAD_KEY_COL5__I2C2_SDA 454 -MX51_PAD_KEY_COL5__KEY_COL5 455 -MX51_PAD_KEY_COL5__UART1_DCD 456 -MX51_PAD_KEY_COL5__UART3_CTS 457 -MX51_PAD_USBH1_CLK__CSPI_SCLK 458 -MX51_PAD_USBH1_CLK__GPIO1_25 459 -MX51_PAD_USBH1_CLK__I2C2_SCL 460 -MX51_PAD_USBH1_CLK__USBH1_CLK 461 -MX51_PAD_USBH1_DIR__CSPI_MOSI 462 -MX51_PAD_USBH1_DIR__GPIO1_26 463 -MX51_PAD_USBH1_DIR__I2C2_SDA 464 -MX51_PAD_USBH1_DIR__USBH1_DIR 465 -MX51_PAD_USBH1_STP__CSPI_RDY 466 -MX51_PAD_USBH1_STP__GPIO1_27 467 -MX51_PAD_USBH1_STP__UART3_RXD 468 -MX51_PAD_USBH1_STP__USBH1_STP 469 -MX51_PAD_USBH1_NXT__CSPI_MISO 470 -MX51_PAD_USBH1_NXT__GPIO1_28 471 -MX51_PAD_USBH1_NXT__UART3_TXD 472 -MX51_PAD_USBH1_NXT__USBH1_NXT 473 -MX51_PAD_USBH1_DATA0__GPIO1_11 474 -MX51_PAD_USBH1_DATA0__UART2_CTS 475 -MX51_PAD_USBH1_DATA0__USBH1_DATA0 476 -MX51_PAD_USBH1_DATA1__GPIO1_12 477 -MX51_PAD_USBH1_DATA1__UART2_RXD 478 -MX51_PAD_USBH1_DATA1__USBH1_DATA1 479 -MX51_PAD_USBH1_DATA2__GPIO1_13 480 -MX51_PAD_USBH1_DATA2__UART2_TXD 481 -MX51_PAD_USBH1_DATA2__USBH1_DATA2 482 -MX51_PAD_USBH1_DATA3__GPIO1_14 483 -MX51_PAD_USBH1_DATA3__UART2_RTS 484 -MX51_PAD_USBH1_DATA3__USBH1_DATA3 485 -MX51_PAD_USBH1_DATA4__CSPI_SS0 486 -MX51_PAD_USBH1_DATA4__GPIO1_15 487 -MX51_PAD_USBH1_DATA4__USBH1_DATA4 488 -MX51_PAD_USBH1_DATA5__CSPI_SS1 489 -MX51_PAD_USBH1_DATA5__GPIO1_16 490 -MX51_PAD_USBH1_DATA5__USBH1_DATA5 491 -MX51_PAD_USBH1_DATA6__CSPI_SS3 492 -MX51_PAD_USBH1_DATA6__GPIO1_17 493 -MX51_PAD_USBH1_DATA6__USBH1_DATA6 494 -MX51_PAD_USBH1_DATA7__ECSPI1_SS3 495 -MX51_PAD_USBH1_DATA7__ECSPI2_SS3 496 -MX51_PAD_USBH1_DATA7__GPIO1_18 497 -MX51_PAD_USBH1_DATA7__USBH1_DATA7 498 -MX51_PAD_DI1_PIN11__DI1_PIN11 499 -MX51_PAD_DI1_PIN11__ECSPI1_SS2 500 -MX51_PAD_DI1_PIN11__GPIO3_0 501 -MX51_PAD_DI1_PIN12__DI1_PIN12 502 -MX51_PAD_DI1_PIN12__GPIO3_1 503 -MX51_PAD_DI1_PIN13__DI1_PIN13 504 -MX51_PAD_DI1_PIN13__GPIO3_2 505 -MX51_PAD_DI1_D0_CS__DI1_D0_CS 506 -MX51_PAD_DI1_D0_CS__GPIO3_3 507 -MX51_PAD_DI1_D1_CS__DI1_D1_CS 508 -MX51_PAD_DI1_D1_CS__DISP1_PIN14 509 -MX51_PAD_DI1_D1_CS__DISP1_PIN5 510 -MX51_PAD_DI1_D1_CS__GPIO3_4 511 -MX51_PAD_DISPB2_SER_DIN__DISP1_PIN1 512 -MX51_PAD_DISPB2_SER_DIN__DISPB2_SER_DIN 513 -MX51_PAD_DISPB2_SER_DIN__GPIO3_5 514 -MX51_PAD_DISPB2_SER_DIO__DISP1_PIN6 515 -MX51_PAD_DISPB2_SER_DIO__DISPB2_SER_DIO 516 -MX51_PAD_DISPB2_SER_DIO__GPIO3_6 517 -MX51_PAD_DISPB2_SER_CLK__DISP1_PIN17 518 -MX51_PAD_DISPB2_SER_CLK__DISP1_PIN7 519 -MX51_PAD_DISPB2_SER_CLK__DISPB2_SER_CLK 520 -MX51_PAD_DISPB2_SER_CLK__GPIO3_7 521 -MX51_PAD_DISPB2_SER_RS__DISP1_EXT_CLK 522 -MX51_PAD_DISPB2_SER_RS__DISP1_PIN16 523 -MX51_PAD_DISPB2_SER_RS__DISP1_PIN8 524 -MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS 525 -MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS 526 -MX51_PAD_DISPB2_SER_RS__GPIO3_8 527 -MX51_PAD_DISP1_DAT0__DISP1_DAT0 528 -MX51_PAD_DISP1_DAT1__DISP1_DAT1 529 -MX51_PAD_DISP1_DAT2__DISP1_DAT2 530 -MX51_PAD_DISP1_DAT3__DISP1_DAT3 531 -MX51_PAD_DISP1_DAT4__DISP1_DAT4 532 -MX51_PAD_DISP1_DAT5__DISP1_DAT5 533 -MX51_PAD_DISP1_DAT6__BOOT_USB_SRC 534 -MX51_PAD_DISP1_DAT6__DISP1_DAT6 535 -MX51_PAD_DISP1_DAT7__BOOT_EEPROM_CFG 536 -MX51_PAD_DISP1_DAT7__DISP1_DAT7 537 -MX51_PAD_DISP1_DAT8__BOOT_SRC0 538 -MX51_PAD_DISP1_DAT8__DISP1_DAT8 539 -MX51_PAD_DISP1_DAT9__BOOT_SRC1 540 -MX51_PAD_DISP1_DAT9__DISP1_DAT9 541 -MX51_PAD_DISP1_DAT10__BOOT_SPARE_SIZE 542 -MX51_PAD_DISP1_DAT10__DISP1_DAT10 543 -MX51_PAD_DISP1_DAT11__BOOT_LPB_FREQ2 544 -MX51_PAD_DISP1_DAT11__DISP1_DAT11 545 -MX51_PAD_DISP1_DAT12__BOOT_MLC_SEL 546 -MX51_PAD_DISP1_DAT12__DISP1_DAT12 547 -MX51_PAD_DISP1_DAT13__BOOT_MEM_CTL0 548 -MX51_PAD_DISP1_DAT13__DISP1_DAT13 549 -MX51_PAD_DISP1_DAT14__BOOT_MEM_CTL1 550 -MX51_PAD_DISP1_DAT14__DISP1_DAT14 551 -MX51_PAD_DISP1_DAT15__BOOT_BUS_WIDTH 552 -MX51_PAD_DISP1_DAT15__DISP1_DAT15 553 -MX51_PAD_DISP1_DAT16__BOOT_PAGE_SIZE0 554 -MX51_PAD_DISP1_DAT16__DISP1_DAT16 555 -MX51_PAD_DISP1_DAT17__BOOT_PAGE_SIZE1 556 -MX51_PAD_DISP1_DAT17__DISP1_DAT17 557 -MX51_PAD_DISP1_DAT18__BOOT_WEIM_MUXED0 558 -MX51_PAD_DISP1_DAT18__DISP1_DAT18 559 -MX51_PAD_DISP1_DAT18__DISP2_PIN11 560 -MX51_PAD_DISP1_DAT18__DISP2_PIN5 561 -MX51_PAD_DISP1_DAT19__BOOT_WEIM_MUXED1 562 -MX51_PAD_DISP1_DAT19__DISP1_DAT19 563 -MX51_PAD_DISP1_DAT19__DISP2_PIN12 564 -MX51_PAD_DISP1_DAT19__DISP2_PIN6 565 -MX51_PAD_DISP1_DAT20__BOOT_MEM_TYPE0 566 -MX51_PAD_DISP1_DAT20__DISP1_DAT20 567 -MX51_PAD_DISP1_DAT20__DISP2_PIN13 568 -MX51_PAD_DISP1_DAT20__DISP2_PIN7 569 -MX51_PAD_DISP1_DAT21__BOOT_MEM_TYPE1 570 -MX51_PAD_DISP1_DAT21__DISP1_DAT21 571 -MX51_PAD_DISP1_DAT21__DISP2_PIN14 572 -MX51_PAD_DISP1_DAT21__DISP2_PIN8 573 -MX51_PAD_DISP1_DAT22__BOOT_LPB_FREQ0 574 -MX51_PAD_DISP1_DAT22__DISP1_DAT22 575 -MX51_PAD_DISP1_DAT22__DISP2_D0_CS 576 -MX51_PAD_DISP1_DAT22__DISP2_DAT16 577 -MX51_PAD_DISP1_DAT23__BOOT_LPB_FREQ1 578 -MX51_PAD_DISP1_DAT23__DISP1_DAT23 579 -MX51_PAD_DISP1_DAT23__DISP2_D1_CS 580 -MX51_PAD_DISP1_DAT23__DISP2_DAT17 581 -MX51_PAD_DISP1_DAT23__DISP2_SER_CS 582 -MX51_PAD_DI1_PIN3__DI1_PIN3 583 -MX51_PAD_DI1_PIN2__DI1_PIN2 584 -MX51_PAD_DI_GP2__DISP1_SER_CLK 585 -MX51_PAD_DI_GP2__DISP2_WAIT 586 -MX51_PAD_DI_GP3__CSI1_DATA_EN 587 -MX51_PAD_DI_GP3__DISP1_SER_DIO 588 -MX51_PAD_DI_GP3__FEC_TX_ER 589 -MX51_PAD_DI2_PIN4__CSI2_DATA_EN 590 -MX51_PAD_DI2_PIN4__DI2_PIN4 591 -MX51_PAD_DI2_PIN4__FEC_CRS 592 -MX51_PAD_DI2_PIN2__DI2_PIN2 593 -MX51_PAD_DI2_PIN2__FEC_MDC 594 -MX51_PAD_DI2_PIN3__DI2_PIN3 595 -MX51_PAD_DI2_PIN3__FEC_MDIO 596 -MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK 597 -MX51_PAD_DI2_DISP_CLK__FEC_RDATA1 598 -MX51_PAD_DI_GP4__DI2_PIN15 599 -MX51_PAD_DI_GP4__DISP1_SER_DIN 600 -MX51_PAD_DI_GP4__DISP2_PIN1 601 -MX51_PAD_DI_GP4__FEC_RDATA2 602 -MX51_PAD_DISP2_DAT0__DISP2_DAT0 603 -MX51_PAD_DISP2_DAT0__FEC_RDATA3 604 -MX51_PAD_DISP2_DAT0__KEY_COL6 605 -MX51_PAD_DISP2_DAT0__UART3_RXD 606 -MX51_PAD_DISP2_DAT0__USBH3_CLK 607 -MX51_PAD_DISP2_DAT1__DISP2_DAT1 608 -MX51_PAD_DISP2_DAT1__FEC_RX_ER 609 -MX51_PAD_DISP2_DAT1__KEY_COL7 610 -MX51_PAD_DISP2_DAT1__UART3_TXD 611 -MX51_PAD_DISP2_DAT1__USBH3_DIR 612 -MX51_PAD_DISP2_DAT2__DISP2_DAT2 613 -MX51_PAD_DISP2_DAT3__DISP2_DAT3 614 -MX51_PAD_DISP2_DAT4__DISP2_DAT4 615 -MX51_PAD_DISP2_DAT5__DISP2_DAT5 616 -MX51_PAD_DISP2_DAT6__DISP2_DAT6 617 -MX51_PAD_DISP2_DAT6__FEC_TDATA1 618 -MX51_PAD_DISP2_DAT6__GPIO1_19 619 -MX51_PAD_DISP2_DAT6__KEY_ROW4 620 -MX51_PAD_DISP2_DAT6__USBH3_STP 621 -MX51_PAD_DISP2_DAT7__DISP2_DAT7 622 -MX51_PAD_DISP2_DAT7__FEC_TDATA2 623 -MX51_PAD_DISP2_DAT7__GPIO1_29 624 -MX51_PAD_DISP2_DAT7__KEY_ROW5 625 -MX51_PAD_DISP2_DAT7__USBH3_NXT 626 -MX51_PAD_DISP2_DAT8__DISP2_DAT8 627 -MX51_PAD_DISP2_DAT8__FEC_TDATA3 628 -MX51_PAD_DISP2_DAT8__GPIO1_30 629 -MX51_PAD_DISP2_DAT8__KEY_ROW6 630 -MX51_PAD_DISP2_DAT8__USBH3_DATA0 631 -MX51_PAD_DISP2_DAT9__AUD6_RXC 632 -MX51_PAD_DISP2_DAT9__DISP2_DAT9 633 -MX51_PAD_DISP2_DAT9__FEC_TX_EN 634 -MX51_PAD_DISP2_DAT9__GPIO1_31 635 -MX51_PAD_DISP2_DAT9__USBH3_DATA1 636 -MX51_PAD_DISP2_DAT10__DISP2_DAT10 637 -MX51_PAD_DISP2_DAT10__DISP2_SER_CS 638 -MX51_PAD_DISP2_DAT10__FEC_COL 639 -MX51_PAD_DISP2_DAT10__KEY_ROW7 640 -MX51_PAD_DISP2_DAT10__USBH3_DATA2 641 -MX51_PAD_DISP2_DAT11__AUD6_TXD 642 -MX51_PAD_DISP2_DAT11__DISP2_DAT11 643 -MX51_PAD_DISP2_DAT11__FEC_RX_CLK 644 -MX51_PAD_DISP2_DAT11__GPIO1_10 645 -MX51_PAD_DISP2_DAT11__USBH3_DATA3 646 -MX51_PAD_DISP2_DAT12__AUD6_RXD 647 -MX51_PAD_DISP2_DAT12__DISP2_DAT12 648 -MX51_PAD_DISP2_DAT12__FEC_RX_DV 649 -MX51_PAD_DISP2_DAT12__USBH3_DATA4 650 -MX51_PAD_DISP2_DAT13__AUD6_TXC 651 -MX51_PAD_DISP2_DAT13__DISP2_DAT13 652 -MX51_PAD_DISP2_DAT13__FEC_TX_CLK 653 -MX51_PAD_DISP2_DAT13__USBH3_DATA5 654 -MX51_PAD_DISP2_DAT14__AUD6_TXFS 655 -MX51_PAD_DISP2_DAT14__DISP2_DAT14 656 -MX51_PAD_DISP2_DAT14__FEC_RDATA0 657 -MX51_PAD_DISP2_DAT14__USBH3_DATA6 658 -MX51_PAD_DISP2_DAT15__AUD6_RXFS 659 -MX51_PAD_DISP2_DAT15__DISP1_SER_CS 660 -MX51_PAD_DISP2_DAT15__DISP2_DAT15 661 -MX51_PAD_DISP2_DAT15__FEC_TDATA0 662 -MX51_PAD_DISP2_DAT15__USBH3_DATA7 663 -MX51_PAD_SD1_CMD__AUD5_RXFS 664 -MX51_PAD_SD1_CMD__CSPI_MOSI 665 -MX51_PAD_SD1_CMD__SD1_CMD 666 -MX51_PAD_SD1_CLK__AUD5_RXC 667 -MX51_PAD_SD1_CLK__CSPI_SCLK 668 -MX51_PAD_SD1_CLK__SD1_CLK 669 -MX51_PAD_SD1_DATA0__AUD5_TXD 670 -MX51_PAD_SD1_DATA0__CSPI_MISO 671 -MX51_PAD_SD1_DATA0__SD1_DATA0 672 -MX51_PAD_EIM_DA0__EIM_DA0 673 -MX51_PAD_EIM_DA1__EIM_DA1 674 -MX51_PAD_EIM_DA2__EIM_DA2 675 -MX51_PAD_EIM_DA3__EIM_DA3 676 -MX51_PAD_SD1_DATA1__AUD5_RXD 677 -MX51_PAD_SD1_DATA1__SD1_DATA1 678 -MX51_PAD_EIM_DA4__EIM_DA4 679 -MX51_PAD_EIM_DA5__EIM_DA5 680 -MX51_PAD_EIM_DA6__EIM_DA6 681 -MX51_PAD_EIM_DA7__EIM_DA7 682 -MX51_PAD_SD1_DATA2__AUD5_TXC 683 -MX51_PAD_SD1_DATA2__SD1_DATA2 684 -MX51_PAD_EIM_DA10__EIM_DA10 685 -MX51_PAD_EIM_DA11__EIM_DA11 686 -MX51_PAD_EIM_DA8__EIM_DA8 687 -MX51_PAD_EIM_DA9__EIM_DA9 688 -MX51_PAD_SD1_DATA3__AUD5_TXFS 689 -MX51_PAD_SD1_DATA3__CSPI_SS1 690 -MX51_PAD_SD1_DATA3__SD1_DATA3 691 -MX51_PAD_GPIO1_0__CSPI_SS2 692 -MX51_PAD_GPIO1_0__GPIO1_0 693 -MX51_PAD_GPIO1_0__SD1_CD 694 -MX51_PAD_GPIO1_1__CSPI_MISO 695 -MX51_PAD_GPIO1_1__GPIO1_1 696 -MX51_PAD_GPIO1_1__SD1_WP 697 -MX51_PAD_EIM_DA12__EIM_DA12 698 -MX51_PAD_EIM_DA13__EIM_DA13 699 -MX51_PAD_EIM_DA14__EIM_DA14 700 -MX51_PAD_EIM_DA15__EIM_DA15 701 -MX51_PAD_SD2_CMD__CSPI_MOSI 702 -MX51_PAD_SD2_CMD__I2C1_SCL 703 -MX51_PAD_SD2_CMD__SD2_CMD 704 -MX51_PAD_SD2_CLK__CSPI_SCLK 705 -MX51_PAD_SD2_CLK__I2C1_SDA 706 -MX51_PAD_SD2_CLK__SD2_CLK 707 -MX51_PAD_SD2_DATA0__CSPI_MISO 708 -MX51_PAD_SD2_DATA0__SD1_DAT4 709 -MX51_PAD_SD2_DATA0__SD2_DATA0 710 -MX51_PAD_SD2_DATA1__SD1_DAT5 711 -MX51_PAD_SD2_DATA1__SD2_DATA1 712 -MX51_PAD_SD2_DATA1__USBH3_H2_DP 713 -MX51_PAD_SD2_DATA2__SD1_DAT6 714 -MX51_PAD_SD2_DATA2__SD2_DATA2 715 -MX51_PAD_SD2_DATA2__USBH3_H2_DM 716 -MX51_PAD_SD2_DATA3__CSPI_SS2 717 -MX51_PAD_SD2_DATA3__SD1_DAT7 718 -MX51_PAD_SD2_DATA3__SD2_DATA3 719 -MX51_PAD_GPIO1_2__CCM_OUT_2 720 -MX51_PAD_GPIO1_2__GPIO1_2 721 -MX51_PAD_GPIO1_2__I2C2_SCL 722 -MX51_PAD_GPIO1_2__PLL1_BYP 723 -MX51_PAD_GPIO1_2__PWM1_PWMO 724 -MX51_PAD_GPIO1_3__GPIO1_3 725 -MX51_PAD_GPIO1_3__I2C2_SDA 726 -MX51_PAD_GPIO1_3__PLL2_BYP 727 -MX51_PAD_GPIO1_3__PWM2_PWMO 728 -MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ 729 -MX51_PAD_PMIC_INT_REQ__PMIC_PMU_IRQ_B 730 -MX51_PAD_GPIO1_4__DISP2_EXT_CLK 731 -MX51_PAD_GPIO1_4__EIM_RDY 732 -MX51_PAD_GPIO1_4__GPIO1_4 733 -MX51_PAD_GPIO1_4__WDOG1_WDOG_B 734 -MX51_PAD_GPIO1_5__CSI2_MCLK 735 -MX51_PAD_GPIO1_5__DISP2_PIN16 736 -MX51_PAD_GPIO1_5__GPIO1_5 737 -MX51_PAD_GPIO1_5__WDOG2_WDOG_B 738 -MX51_PAD_GPIO1_6__DISP2_PIN17 739 -MX51_PAD_GPIO1_6__GPIO1_6 740 -MX51_PAD_GPIO1_6__REF_EN_B 741 -MX51_PAD_GPIO1_7__CCM_OUT_0 742 -MX51_PAD_GPIO1_7__GPIO1_7 743 -MX51_PAD_GPIO1_7__SD2_WP 744 -MX51_PAD_GPIO1_7__SPDIF_OUT1 745 -MX51_PAD_GPIO1_8__CSI2_DATA_EN 746 -MX51_PAD_GPIO1_8__GPIO1_8 747 -MX51_PAD_GPIO1_8__SD2_CD 748 -MX51_PAD_GPIO1_8__USBH3_PWR 749 -MX51_PAD_GPIO1_9__CCM_OUT_1 750 -MX51_PAD_GPIO1_9__DISP2_D1_CS 751 -MX51_PAD_GPIO1_9__DISP2_SER_CS 752 -MX51_PAD_GPIO1_9__GPIO1_9 753 -MX51_PAD_GPIO1_9__SD2_LCTL 754 -MX51_PAD_GPIO1_9__USBH3_OC 755 diff --git a/trunk/Documentation/devicetree/bindings/pinctrl/fsl,imx53-pinctrl.txt b/trunk/Documentation/devicetree/bindings/pinctrl/fsl,imx53-pinctrl.txt deleted file mode 100644 index ca85ca432ef0..000000000000 --- a/trunk/Documentation/devicetree/bindings/pinctrl/fsl,imx53-pinctrl.txt +++ /dev/null @@ -1,1202 +0,0 @@ -* Freescale IMX53 IOMUX Controller - -Please refer to fsl,imx-pinctrl.txt in this directory for common binding part -and usage. - -Required properties: -- compatible: "fsl,imx53-iomuxc" -- fsl,pins: two integers array, represents a group of pins mux and config - setting. The format is fsl,pins = , PIN_FUNC_ID is a - pin working on a specific function, CONFIG is the pad setting value like - pull-up for this pin. Please refer to imx53 datasheet for the valid pad - config settings. - -CONFIG bits definition: -PAD_CTL_HVE (1 << 13) -PAD_CTL_HYS (1 << 8) -PAD_CTL_PKE (1 << 7) -PAD_CTL_PUE (1 << 6) -PAD_CTL_PUS_100K_DOWN (0 << 4) -PAD_CTL_PUS_47K_UP (1 << 4) -PAD_CTL_PUS_100K_UP (2 << 4) -PAD_CTL_PUS_22K_UP (3 << 4) -PAD_CTL_ODE (1 << 3) -PAD_CTL_DSE_LOW (0 << 1) -PAD_CTL_DSE_MED (1 << 1) -PAD_CTL_DSE_HIGH (2 << 1) -PAD_CTL_DSE_MAX (3 << 1) -PAD_CTL_SRE_FAST (1 << 0) -PAD_CTL_SRE_SLOW (0 << 0) - -See below for available PIN_FUNC_ID for imx53: -MX53_PAD_GPIO_19__KPP_COL_5 0 -MX53_PAD_GPIO_19__GPIO4_5 1 -MX53_PAD_GPIO_19__CCM_CLKO 2 -MX53_PAD_GPIO_19__SPDIF_OUT1 3 -MX53_PAD_GPIO_19__RTC_CE_RTC_EXT_TRIG2 4 -MX53_PAD_GPIO_19__ECSPI1_RDY 5 -MX53_PAD_GPIO_19__FEC_TDATA_3 6 -MX53_PAD_GPIO_19__SRC_INT_BOOT 7 -MX53_PAD_KEY_COL0__KPP_COL_0 8 -MX53_PAD_KEY_COL0__GPIO4_6 9 -MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC 10 -MX53_PAD_KEY_COL0__UART4_TXD_MUX 11 -MX53_PAD_KEY_COL0__ECSPI1_SCLK 12 -MX53_PAD_KEY_COL0__FEC_RDATA_3 13 -MX53_PAD_KEY_COL0__SRC_ANY_PU_RST 14 -MX53_PAD_KEY_ROW0__KPP_ROW_0 15 -MX53_PAD_KEY_ROW0__GPIO4_7 16 -MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD 17 -MX53_PAD_KEY_ROW0__UART4_RXD_MUX 18 -MX53_PAD_KEY_ROW0__ECSPI1_MOSI 19 -MX53_PAD_KEY_ROW0__FEC_TX_ER 20 -MX53_PAD_KEY_COL1__KPP_COL_1 21 -MX53_PAD_KEY_COL1__GPIO4_8 22 -MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS 23 -MX53_PAD_KEY_COL1__UART5_TXD_MUX 24 -MX53_PAD_KEY_COL1__ECSPI1_MISO 25 -MX53_PAD_KEY_COL1__FEC_RX_CLK 26 -MX53_PAD_KEY_COL1__USBPHY1_TXREADY 27 -MX53_PAD_KEY_ROW1__KPP_ROW_1 28 -MX53_PAD_KEY_ROW1__GPIO4_9 29 -MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD 30 -MX53_PAD_KEY_ROW1__UART5_RXD_MUX 31 -MX53_PAD_KEY_ROW1__ECSPI1_SS0 32 -MX53_PAD_KEY_ROW1__FEC_COL 33 -MX53_PAD_KEY_ROW1__USBPHY1_RXVALID 34 -MX53_PAD_KEY_COL2__KPP_COL_2 35 -MX53_PAD_KEY_COL2__GPIO4_10 36 -MX53_PAD_KEY_COL2__CAN1_TXCAN 37 -MX53_PAD_KEY_COL2__FEC_MDIO 38 -MX53_PAD_KEY_COL2__ECSPI1_SS1 39 -MX53_PAD_KEY_COL2__FEC_RDATA_2 40 -MX53_PAD_KEY_COL2__USBPHY1_RXACTIVE 41 -MX53_PAD_KEY_ROW2__KPP_ROW_2 42 -MX53_PAD_KEY_ROW2__GPIO4_11 43 -MX53_PAD_KEY_ROW2__CAN1_RXCAN 44 -MX53_PAD_KEY_ROW2__FEC_MDC 45 -MX53_PAD_KEY_ROW2__ECSPI1_SS2 46 -MX53_PAD_KEY_ROW2__FEC_TDATA_2 47 -MX53_PAD_KEY_ROW2__USBPHY1_RXERROR 48 -MX53_PAD_KEY_COL3__KPP_COL_3 49 -MX53_PAD_KEY_COL3__GPIO4_12 50 -MX53_PAD_KEY_COL3__USBOH3_H2_DP 51 -MX53_PAD_KEY_COL3__SPDIF_IN1 52 -MX53_PAD_KEY_COL3__I2C2_SCL 53 -MX53_PAD_KEY_COL3__ECSPI1_SS3 54 -MX53_PAD_KEY_COL3__FEC_CRS 55 -MX53_PAD_KEY_COL3__USBPHY1_SIECLOCK 56 -MX53_PAD_KEY_ROW3__KPP_ROW_3 57 -MX53_PAD_KEY_ROW3__GPIO4_13 58 -MX53_PAD_KEY_ROW3__USBOH3_H2_DM 59 -MX53_PAD_KEY_ROW3__CCM_ASRC_EXT_CLK 60 -MX53_PAD_KEY_ROW3__I2C2_SDA 61 -MX53_PAD_KEY_ROW3__OSC32K_32K_OUT 62 -MX53_PAD_KEY_ROW3__CCM_PLL4_BYP 63 -MX53_PAD_KEY_ROW3__USBPHY1_LINESTATE_0 64 -MX53_PAD_KEY_COL4__KPP_COL_4 65 -MX53_PAD_KEY_COL4__GPIO4_14 66 -MX53_PAD_KEY_COL4__CAN2_TXCAN 67 -MX53_PAD_KEY_COL4__IPU_SISG_4 68 -MX53_PAD_KEY_COL4__UART5_RTS 69 -MX53_PAD_KEY_COL4__USBOH3_USBOTG_OC 70 -MX53_PAD_KEY_COL4__USBPHY1_LINESTATE_1 71 -MX53_PAD_KEY_ROW4__KPP_ROW_4 72 -MX53_PAD_KEY_ROW4__GPIO4_15 73 -MX53_PAD_KEY_ROW4__CAN2_RXCAN 74 -MX53_PAD_KEY_ROW4__IPU_SISG_5 75 -MX53_PAD_KEY_ROW4__UART5_CTS 76 -MX53_PAD_KEY_ROW4__USBOH3_USBOTG_PWR 77 -MX53_PAD_KEY_ROW4__USBPHY1_VBUSVALID 78 -MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK 79 -MX53_PAD_DI0_DISP_CLK__GPIO4_16 80 -MX53_PAD_DI0_DISP_CLK__USBOH3_USBH2_DIR 81 -MX53_PAD_DI0_DISP_CLK__SDMA_DEBUG_CORE_STATE_0 82 -MX53_PAD_DI0_DISP_CLK__EMI_EMI_DEBUG_0 83 -MX53_PAD_DI0_DISP_CLK__USBPHY1_AVALID 84 -MX53_PAD_DI0_PIN15__IPU_DI0_PIN15 85 -MX53_PAD_DI0_PIN15__GPIO4_17 86 -MX53_PAD_DI0_PIN15__AUDMUX_AUD6_TXC 87 -MX53_PAD_DI0_PIN15__SDMA_DEBUG_CORE_STATE_1 88 -MX53_PAD_DI0_PIN15__EMI_EMI_DEBUG_1 89 -MX53_PAD_DI0_PIN15__USBPHY1_BVALID 90 -MX53_PAD_DI0_PIN2__IPU_DI0_PIN2 91 -MX53_PAD_DI0_PIN2__GPIO4_18 92 -MX53_PAD_DI0_PIN2__AUDMUX_AUD6_TXD 93 -MX53_PAD_DI0_PIN2__SDMA_DEBUG_CORE_STATE_2 94 -MX53_PAD_DI0_PIN2__EMI_EMI_DEBUG_2 95 -MX53_PAD_DI0_PIN2__USBPHY1_ENDSESSION 96 -MX53_PAD_DI0_PIN3__IPU_DI0_PIN3 97 -MX53_PAD_DI0_PIN3__GPIO4_19 98 -MX53_PAD_DI0_PIN3__AUDMUX_AUD6_TXFS 99 -MX53_PAD_DI0_PIN3__SDMA_DEBUG_CORE_STATE_3 100 -MX53_PAD_DI0_PIN3__EMI_EMI_DEBUG_3 101 -MX53_PAD_DI0_PIN3__USBPHY1_IDDIG 102 -MX53_PAD_DI0_PIN4__IPU_DI0_PIN4 103 -MX53_PAD_DI0_PIN4__GPIO4_20 104 -MX53_PAD_DI0_PIN4__AUDMUX_AUD6_RXD 105 -MX53_PAD_DI0_PIN4__ESDHC1_WP 106 -MX53_PAD_DI0_PIN4__SDMA_DEBUG_YIELD 107 -MX53_PAD_DI0_PIN4__EMI_EMI_DEBUG_4 108 -MX53_PAD_DI0_PIN4__USBPHY1_HOSTDISCONNECT 109 -MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0 110 -MX53_PAD_DISP0_DAT0__GPIO4_21 111 -MX53_PAD_DISP0_DAT0__CSPI_SCLK 112 -MX53_PAD_DISP0_DAT0__USBOH3_USBH2_DATA_0 113 -MX53_PAD_DISP0_DAT0__SDMA_DEBUG_CORE_RUN 114 -MX53_PAD_DISP0_DAT0__EMI_EMI_DEBUG_5 115 -MX53_PAD_DISP0_DAT0__USBPHY2_TXREADY 116 -MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1 117 -MX53_PAD_DISP0_DAT1__GPIO4_22 118 -MX53_PAD_DISP0_DAT1__CSPI_MOSI 119 -MX53_PAD_DISP0_DAT1__USBOH3_USBH2_DATA_1 120 -MX53_PAD_DISP0_DAT1__SDMA_DEBUG_EVENT_CHANNEL_SEL 121 -MX53_PAD_DISP0_DAT1__EMI_EMI_DEBUG_6 122 -MX53_PAD_DISP0_DAT1__USBPHY2_RXVALID 123 -MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2 124 -MX53_PAD_DISP0_DAT2__GPIO4_23 125 -MX53_PAD_DISP0_DAT2__CSPI_MISO 126 -MX53_PAD_DISP0_DAT2__USBOH3_USBH2_DATA_2 127 -MX53_PAD_DISP0_DAT2__SDMA_DEBUG_MODE 128 -MX53_PAD_DISP0_DAT2__EMI_EMI_DEBUG_7 129 -MX53_PAD_DISP0_DAT2__USBPHY2_RXACTIVE 130 -MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3 131 -MX53_PAD_DISP0_DAT3__GPIO4_24 132 -MX53_PAD_DISP0_DAT3__CSPI_SS0 133 -MX53_PAD_DISP0_DAT3__USBOH3_USBH2_DATA_3 134 -MX53_PAD_DISP0_DAT3__SDMA_DEBUG_BUS_ERROR 135 -MX53_PAD_DISP0_DAT3__EMI_EMI_DEBUG_8 136 -MX53_PAD_DISP0_DAT3__USBPHY2_RXERROR 137 -MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4 138 -MX53_PAD_DISP0_DAT4__GPIO4_25 139 -MX53_PAD_DISP0_DAT4__CSPI_SS1 140 -MX53_PAD_DISP0_DAT4__USBOH3_USBH2_DATA_4 141 -MX53_PAD_DISP0_DAT4__SDMA_DEBUG_BUS_RWB 142 -MX53_PAD_DISP0_DAT4__EMI_EMI_DEBUG_9 143 -MX53_PAD_DISP0_DAT4__USBPHY2_SIECLOCK 144 -MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5 145 -MX53_PAD_DISP0_DAT5__GPIO4_26 146 -MX53_PAD_DISP0_DAT5__CSPI_SS2 147 -MX53_PAD_DISP0_DAT5__USBOH3_USBH2_DATA_5 148 -MX53_PAD_DISP0_DAT5__SDMA_DEBUG_MATCHED_DMBUS 149 -MX53_PAD_DISP0_DAT5__EMI_EMI_DEBUG_10 150 -MX53_PAD_DISP0_DAT5__USBPHY2_LINESTATE_0 151 -MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6 152 -MX53_PAD_DISP0_DAT6__GPIO4_27 153 -MX53_PAD_DISP0_DAT6__CSPI_SS3 154 -MX53_PAD_DISP0_DAT6__USBOH3_USBH2_DATA_6 155 -MX53_PAD_DISP0_DAT6__SDMA_DEBUG_RTBUFFER_WRITE 156 -MX53_PAD_DISP0_DAT6__EMI_EMI_DEBUG_11 157 -MX53_PAD_DISP0_DAT6__USBPHY2_LINESTATE_1 158 -MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7 159 -MX53_PAD_DISP0_DAT7__GPIO4_28 160 -MX53_PAD_DISP0_DAT7__CSPI_RDY 161 -MX53_PAD_DISP0_DAT7__USBOH3_USBH2_DATA_7 162 -MX53_PAD_DISP0_DAT7__SDMA_DEBUG_EVENT_CHANNEL_0 163 -MX53_PAD_DISP0_DAT7__EMI_EMI_DEBUG_12 164 -MX53_PAD_DISP0_DAT7__USBPHY2_VBUSVALID 165 -MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8 166 -MX53_PAD_DISP0_DAT8__GPIO4_29 167 -MX53_PAD_DISP0_DAT8__PWM1_PWMO 168 -MX53_PAD_DISP0_DAT8__WDOG1_WDOG_B 169 -MX53_PAD_DISP0_DAT8__SDMA_DEBUG_EVENT_CHANNEL_1 170 -MX53_PAD_DISP0_DAT8__EMI_EMI_DEBUG_13 171 -MX53_PAD_DISP0_DAT8__USBPHY2_AVALID 172 -MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9 173 -MX53_PAD_DISP0_DAT9__GPIO4_30 174 -MX53_PAD_DISP0_DAT9__PWM2_PWMO 175 -MX53_PAD_DISP0_DAT9__WDOG2_WDOG_B 176 -MX53_PAD_DISP0_DAT9__SDMA_DEBUG_EVENT_CHANNEL_2 177 -MX53_PAD_DISP0_DAT9__EMI_EMI_DEBUG_14 178 -MX53_PAD_DISP0_DAT9__USBPHY2_VSTATUS_0 179 -MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10 180 -MX53_PAD_DISP0_DAT10__GPIO4_31 181 -MX53_PAD_DISP0_DAT10__USBOH3_USBH2_STP 182 -MX53_PAD_DISP0_DAT10__SDMA_DEBUG_EVENT_CHANNEL_3 183 -MX53_PAD_DISP0_DAT10__EMI_EMI_DEBUG_15 184 -MX53_PAD_DISP0_DAT10__USBPHY2_VSTATUS_1 185 -MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11 186 -MX53_PAD_DISP0_DAT11__GPIO5_5 187 -MX53_PAD_DISP0_DAT11__USBOH3_USBH2_NXT 188 -MX53_PAD_DISP0_DAT11__SDMA_DEBUG_EVENT_CHANNEL_4 189 -MX53_PAD_DISP0_DAT11__EMI_EMI_DEBUG_16 190 -MX53_PAD_DISP0_DAT11__USBPHY2_VSTATUS_2 191 -MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12 192 -MX53_PAD_DISP0_DAT12__GPIO5_6 193 -MX53_PAD_DISP0_DAT12__USBOH3_USBH2_CLK 194 -MX53_PAD_DISP0_DAT12__SDMA_DEBUG_EVENT_CHANNEL_5 195 -MX53_PAD_DISP0_DAT12__EMI_EMI_DEBUG_17 196 -MX53_PAD_DISP0_DAT12__USBPHY2_VSTATUS_3 197 -MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13 198 -MX53_PAD_DISP0_DAT13__GPIO5_7 199 -MX53_PAD_DISP0_DAT13__AUDMUX_AUD5_RXFS 200 -MX53_PAD_DISP0_DAT13__SDMA_DEBUG_EVT_CHN_LINES_0 201 -MX53_PAD_DISP0_DAT13__EMI_EMI_DEBUG_18 202 -MX53_PAD_DISP0_DAT13__USBPHY2_VSTATUS_4 203 -MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14 204 -MX53_PAD_DISP0_DAT14__GPIO5_8 205 -MX53_PAD_DISP0_DAT14__AUDMUX_AUD5_RXC 206 -MX53_PAD_DISP0_DAT14__SDMA_DEBUG_EVT_CHN_LINES_1 207 -MX53_PAD_DISP0_DAT14__EMI_EMI_DEBUG_19 208 -MX53_PAD_DISP0_DAT14__USBPHY2_VSTATUS_5 209 -MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15 210 -MX53_PAD_DISP0_DAT15__GPIO5_9 211 -MX53_PAD_DISP0_DAT15__ECSPI1_SS1 212 -MX53_PAD_DISP0_DAT15__ECSPI2_SS1 213 -MX53_PAD_DISP0_DAT15__SDMA_DEBUG_EVT_CHN_LINES_2 214 -MX53_PAD_DISP0_DAT15__EMI_EMI_DEBUG_20 215 -MX53_PAD_DISP0_DAT15__USBPHY2_VSTATUS_6 216 -MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16 217 -MX53_PAD_DISP0_DAT16__GPIO5_10 218 -MX53_PAD_DISP0_DAT16__ECSPI2_MOSI 219 -MX53_PAD_DISP0_DAT16__AUDMUX_AUD5_TXC 220 -MX53_PAD_DISP0_DAT16__SDMA_EXT_EVENT_0 221 -MX53_PAD_DISP0_DAT16__SDMA_DEBUG_EVT_CHN_LINES_3 222 -MX53_PAD_DISP0_DAT16__EMI_EMI_DEBUG_21 223 -MX53_PAD_DISP0_DAT16__USBPHY2_VSTATUS_7 224 -MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17 225 -MX53_PAD_DISP0_DAT17__GPIO5_11 226 -MX53_PAD_DISP0_DAT17__ECSPI2_MISO 227 -MX53_PAD_DISP0_DAT17__AUDMUX_AUD5_TXD 228 -MX53_PAD_DISP0_DAT17__SDMA_EXT_EVENT_1 229 -MX53_PAD_DISP0_DAT17__SDMA_DEBUG_EVT_CHN_LINES_4 230 -MX53_PAD_DISP0_DAT17__EMI_EMI_DEBUG_22 231 -MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18 232 -MX53_PAD_DISP0_DAT18__GPIO5_12 233 -MX53_PAD_DISP0_DAT18__ECSPI2_SS0 234 -MX53_PAD_DISP0_DAT18__AUDMUX_AUD5_TXFS 235 -MX53_PAD_DISP0_DAT18__AUDMUX_AUD4_RXFS 236 -MX53_PAD_DISP0_DAT18__SDMA_DEBUG_EVT_CHN_LINES_5 237 -MX53_PAD_DISP0_DAT18__EMI_EMI_DEBUG_23 238 -MX53_PAD_DISP0_DAT18__EMI_WEIM_CS_2 239 -MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19 240 -MX53_PAD_DISP0_DAT19__GPIO5_13 241 -MX53_PAD_DISP0_DAT19__ECSPI2_SCLK 242 -MX53_PAD_DISP0_DAT19__AUDMUX_AUD5_RXD 243 -MX53_PAD_DISP0_DAT19__AUDMUX_AUD4_RXC 244 -MX53_PAD_DISP0_DAT19__SDMA_DEBUG_EVT_CHN_LINES_6 245 -MX53_PAD_DISP0_DAT19__EMI_EMI_DEBUG_24 246 -MX53_PAD_DISP0_DAT19__EMI_WEIM_CS_3 247 -MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20 248 -MX53_PAD_DISP0_DAT20__GPIO5_14 249 -MX53_PAD_DISP0_DAT20__ECSPI1_SCLK 250 -MX53_PAD_DISP0_DAT20__AUDMUX_AUD4_TXC 251 -MX53_PAD_DISP0_DAT20__SDMA_DEBUG_EVT_CHN_LINES_7 252 -MX53_PAD_DISP0_DAT20__EMI_EMI_DEBUG_25 253 -MX53_PAD_DISP0_DAT20__SATA_PHY_TDI 254 -MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21 255 -MX53_PAD_DISP0_DAT21__GPIO5_15 256 -MX53_PAD_DISP0_DAT21__ECSPI1_MOSI 257 -MX53_PAD_DISP0_DAT21__AUDMUX_AUD4_TXD 258 -MX53_PAD_DISP0_DAT21__SDMA_DEBUG_BUS_DEVICE_0 259 -MX53_PAD_DISP0_DAT21__EMI_EMI_DEBUG_26 260 -MX53_PAD_DISP0_DAT21__SATA_PHY_TDO 261 -MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22 262 -MX53_PAD_DISP0_DAT22__GPIO5_16 263 -MX53_PAD_DISP0_DAT22__ECSPI1_MISO 264 -MX53_PAD_DISP0_DAT22__AUDMUX_AUD4_TXFS 265 -MX53_PAD_DISP0_DAT22__SDMA_DEBUG_BUS_DEVICE_1 266 -MX53_PAD_DISP0_DAT22__EMI_EMI_DEBUG_27 267 -MX53_PAD_DISP0_DAT22__SATA_PHY_TCK 268 -MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23 269 -MX53_PAD_DISP0_DAT23__GPIO5_17 270 -MX53_PAD_DISP0_DAT23__ECSPI1_SS0 271 -MX53_PAD_DISP0_DAT23__AUDMUX_AUD4_RXD 272 -MX53_PAD_DISP0_DAT23__SDMA_DEBUG_BUS_DEVICE_2 273 -MX53_PAD_DISP0_DAT23__EMI_EMI_DEBUG_28 274 -MX53_PAD_DISP0_DAT23__SATA_PHY_TMS 275 -MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK 276 -MX53_PAD_CSI0_PIXCLK__GPIO5_18 277 -MX53_PAD_CSI0_PIXCLK__SDMA_DEBUG_PC_0 278 -MX53_PAD_CSI0_PIXCLK__EMI_EMI_DEBUG_29 279 -MX53_PAD_CSI0_MCLK__IPU_CSI0_HSYNC 280 -MX53_PAD_CSI0_MCLK__GPIO5_19 281 -MX53_PAD_CSI0_MCLK__CCM_CSI0_MCLK 282 -MX53_PAD_CSI0_MCLK__SDMA_DEBUG_PC_1 283 -MX53_PAD_CSI0_MCLK__EMI_EMI_DEBUG_30 284 -MX53_PAD_CSI0_MCLK__TPIU_TRCTL 285 -MX53_PAD_CSI0_DATA_EN__IPU_CSI0_DATA_EN 286 -MX53_PAD_CSI0_DATA_EN__GPIO5_20 287 -MX53_PAD_CSI0_DATA_EN__SDMA_DEBUG_PC_2 288 -MX53_PAD_CSI0_DATA_EN__EMI_EMI_DEBUG_31 289 -MX53_PAD_CSI0_DATA_EN__TPIU_TRCLK 290 -MX53_PAD_CSI0_VSYNC__IPU_CSI0_VSYNC 291 -MX53_PAD_CSI0_VSYNC__GPIO5_21 292 -MX53_PAD_CSI0_VSYNC__SDMA_DEBUG_PC_3 293 -MX53_PAD_CSI0_VSYNC__EMI_EMI_DEBUG_32 294 -MX53_PAD_CSI0_VSYNC__TPIU_TRACE_0 295 -MX53_PAD_CSI0_DAT4__IPU_CSI0_D_4 296 -MX53_PAD_CSI0_DAT4__GPIO5_22 297 -MX53_PAD_CSI0_DAT4__KPP_COL_5 298 -MX53_PAD_CSI0_DAT4__ECSPI1_SCLK 299 -MX53_PAD_CSI0_DAT4__USBOH3_USBH3_STP 300 -MX53_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC 301 -MX53_PAD_CSI0_DAT4__EMI_EMI_DEBUG_33 302 -MX53_PAD_CSI0_DAT4__TPIU_TRACE_1 303 -MX53_PAD_CSI0_DAT5__IPU_CSI0_D_5 304 -MX53_PAD_CSI0_DAT5__GPIO5_23 305 -MX53_PAD_CSI0_DAT5__KPP_ROW_5 306 -MX53_PAD_CSI0_DAT5__ECSPI1_MOSI 307 -MX53_PAD_CSI0_DAT5__USBOH3_USBH3_NXT 308 -MX53_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD 309 -MX53_PAD_CSI0_DAT5__EMI_EMI_DEBUG_34 310 -MX53_PAD_CSI0_DAT5__TPIU_TRACE_2 311 -MX53_PAD_CSI0_DAT6__IPU_CSI0_D_6 312 -MX53_PAD_CSI0_DAT6__GPIO5_24 313 -MX53_PAD_CSI0_DAT6__KPP_COL_6 314 -MX53_PAD_CSI0_DAT6__ECSPI1_MISO 315 -MX53_PAD_CSI0_DAT6__USBOH3_USBH3_CLK 316 -MX53_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS 317 -MX53_PAD_CSI0_DAT6__EMI_EMI_DEBUG_35 318 -MX53_PAD_CSI0_DAT6__TPIU_TRACE_3 319 -MX53_PAD_CSI0_DAT7__IPU_CSI0_D_7 320 -MX53_PAD_CSI0_DAT7__GPIO5_25 321 -MX53_PAD_CSI0_DAT7__KPP_ROW_6 322 -MX53_PAD_CSI0_DAT7__ECSPI1_SS0 323 -MX53_PAD_CSI0_DAT7__USBOH3_USBH3_DIR 324 -MX53_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD 325 -MX53_PAD_CSI0_DAT7__EMI_EMI_DEBUG_36 326 -MX53_PAD_CSI0_DAT7__TPIU_TRACE_4 327 -MX53_PAD_CSI0_DAT8__IPU_CSI0_D_8 328 -MX53_PAD_CSI0_DAT8__GPIO5_26 329 -MX53_PAD_CSI0_DAT8__KPP_COL_7 330 -MX53_PAD_CSI0_DAT8__ECSPI2_SCLK 331 -MX53_PAD_CSI0_DAT8__USBOH3_USBH3_OC 332 -MX53_PAD_CSI0_DAT8__I2C1_SDA 333 -MX53_PAD_CSI0_DAT8__EMI_EMI_DEBUG_37 334 -MX53_PAD_CSI0_DAT8__TPIU_TRACE_5 335 -MX53_PAD_CSI0_DAT9__IPU_CSI0_D_9 336 -MX53_PAD_CSI0_DAT9__GPIO5_27 337 -MX53_PAD_CSI0_DAT9__KPP_ROW_7 338 -MX53_PAD_CSI0_DAT9__ECSPI2_MOSI 339 -MX53_PAD_CSI0_DAT9__USBOH3_USBH3_PWR 340 -MX53_PAD_CSI0_DAT9__I2C1_SCL 341 -MX53_PAD_CSI0_DAT9__EMI_EMI_DEBUG_38 342 -MX53_PAD_CSI0_DAT9__TPIU_TRACE_6 343 -MX53_PAD_CSI0_DAT10__IPU_CSI0_D_10 344 -MX53_PAD_CSI0_DAT10__GPIO5_28 345 -MX53_PAD_CSI0_DAT10__UART1_TXD_MUX 346 -MX53_PAD_CSI0_DAT10__ECSPI2_MISO 347 -MX53_PAD_CSI0_DAT10__AUDMUX_AUD3_RXC 348 -MX53_PAD_CSI0_DAT10__SDMA_DEBUG_PC_4 349 -MX53_PAD_CSI0_DAT10__EMI_EMI_DEBUG_39 350 -MX53_PAD_CSI0_DAT10__TPIU_TRACE_7 351 -MX53_PAD_CSI0_DAT11__IPU_CSI0_D_11 352 -MX53_PAD_CSI0_DAT11__GPIO5_29 353 -MX53_PAD_CSI0_DAT11__UART1_RXD_MUX 354 -MX53_PAD_CSI0_DAT11__ECSPI2_SS0 355 -MX53_PAD_CSI0_DAT11__AUDMUX_AUD3_RXFS 356 -MX53_PAD_CSI0_DAT11__SDMA_DEBUG_PC_5 357 -MX53_PAD_CSI0_DAT11__EMI_EMI_DEBUG_40 358 -MX53_PAD_CSI0_DAT11__TPIU_TRACE_8 359 -MX53_PAD_CSI0_DAT12__IPU_CSI0_D_12 360 -MX53_PAD_CSI0_DAT12__GPIO5_30 361 -MX53_PAD_CSI0_DAT12__UART4_TXD_MUX 362 -MX53_PAD_CSI0_DAT12__USBOH3_USBH3_DATA_0 363 -MX53_PAD_CSI0_DAT12__SDMA_DEBUG_PC_6 364 -MX53_PAD_CSI0_DAT12__EMI_EMI_DEBUG_41 365 -MX53_PAD_CSI0_DAT12__TPIU_TRACE_9 366 -MX53_PAD_CSI0_DAT13__IPU_CSI0_D_13 367 -MX53_PAD_CSI0_DAT13__GPIO5_31 368 -MX53_PAD_CSI0_DAT13__UART4_RXD_MUX 369 -MX53_PAD_CSI0_DAT13__USBOH3_USBH3_DATA_1 370 -MX53_PAD_CSI0_DAT13__SDMA_DEBUG_PC_7 371 -MX53_PAD_CSI0_DAT13__EMI_EMI_DEBUG_42 372 -MX53_PAD_CSI0_DAT13__TPIU_TRACE_10 373 -MX53_PAD_CSI0_DAT14__IPU_CSI0_D_14 374 -MX53_PAD_CSI0_DAT14__GPIO6_0 375 -MX53_PAD_CSI0_DAT14__UART5_TXD_MUX 376 -MX53_PAD_CSI0_DAT14__USBOH3_USBH3_DATA_2 377 -MX53_PAD_CSI0_DAT14__SDMA_DEBUG_PC_8 378 -MX53_PAD_CSI0_DAT14__EMI_EMI_DEBUG_43 379 -MX53_PAD_CSI0_DAT14__TPIU_TRACE_11 380 -MX53_PAD_CSI0_DAT15__IPU_CSI0_D_15 381 -MX53_PAD_CSI0_DAT15__GPIO6_1 382 -MX53_PAD_CSI0_DAT15__UART5_RXD_MUX 383 -MX53_PAD_CSI0_DAT15__USBOH3_USBH3_DATA_3 384 -MX53_PAD_CSI0_DAT15__SDMA_DEBUG_PC_9 385 -MX53_PAD_CSI0_DAT15__EMI_EMI_DEBUG_44 386 -MX53_PAD_CSI0_DAT15__TPIU_TRACE_12 387 -MX53_PAD_CSI0_DAT16__IPU_CSI0_D_16 388 -MX53_PAD_CSI0_DAT16__GPIO6_2 389 -MX53_PAD_CSI0_DAT16__UART4_RTS 390 -MX53_PAD_CSI0_DAT16__USBOH3_USBH3_DATA_4 391 -MX53_PAD_CSI0_DAT16__SDMA_DEBUG_PC_10 392 -MX53_PAD_CSI0_DAT16__EMI_EMI_DEBUG_45 393 -MX53_PAD_CSI0_DAT16__TPIU_TRACE_13 394 -MX53_PAD_CSI0_DAT17__IPU_CSI0_D_17 395 -MX53_PAD_CSI0_DAT17__GPIO6_3 396 -MX53_PAD_CSI0_DAT17__UART4_CTS 397 -MX53_PAD_CSI0_DAT17__USBOH3_USBH3_DATA_5 398 -MX53_PAD_CSI0_DAT17__SDMA_DEBUG_PC_11 399 -MX53_PAD_CSI0_DAT17__EMI_EMI_DEBUG_46 400 -MX53_PAD_CSI0_DAT17__TPIU_TRACE_14 401 -MX53_PAD_CSI0_DAT18__IPU_CSI0_D_18 402 -MX53_PAD_CSI0_DAT18__GPIO6_4 403 -MX53_PAD_CSI0_DAT18__UART5_RTS 404 -MX53_PAD_CSI0_DAT18__USBOH3_USBH3_DATA_6 405 -MX53_PAD_CSI0_DAT18__SDMA_DEBUG_PC_12 406 -MX53_PAD_CSI0_DAT18__EMI_EMI_DEBUG_47 407 -MX53_PAD_CSI0_DAT18__TPIU_TRACE_15 408 -MX53_PAD_CSI0_DAT19__IPU_CSI0_D_19 409 -MX53_PAD_CSI0_DAT19__GPIO6_5 410 -MX53_PAD_CSI0_DAT19__UART5_CTS 411 -MX53_PAD_CSI0_DAT19__USBOH3_USBH3_DATA_7 412 -MX53_PAD_CSI0_DAT19__SDMA_DEBUG_PC_13 413 -MX53_PAD_CSI0_DAT19__EMI_EMI_DEBUG_48 414 -MX53_PAD_CSI0_DAT19__USBPHY2_BISTOK 415 -MX53_PAD_EIM_A25__EMI_WEIM_A_25 416 -MX53_PAD_EIM_A25__GPIO5_2 417 -MX53_PAD_EIM_A25__ECSPI2_RDY 418 -MX53_PAD_EIM_A25__IPU_DI1_PIN12 419 -MX53_PAD_EIM_A25__CSPI_SS1 420 -MX53_PAD_EIM_A25__IPU_DI0_D1_CS 421 -MX53_PAD_EIM_A25__USBPHY1_BISTOK 422 -MX53_PAD_EIM_EB2__EMI_WEIM_EB_2 423 -MX53_PAD_EIM_EB2__GPIO2_30 424 -MX53_PAD_EIM_EB2__CCM_DI1_EXT_CLK 425 -MX53_PAD_EIM_EB2__IPU_SER_DISP1_CS 426 -MX53_PAD_EIM_EB2__ECSPI1_SS0 427 -MX53_PAD_EIM_EB2__I2C2_SCL 428 -MX53_PAD_EIM_D16__EMI_WEIM_D_16 429 -MX53_PAD_EIM_D16__GPIO3_16 430 -MX53_PAD_EIM_D16__IPU_DI0_PIN5 431 -MX53_PAD_EIM_D16__IPU_DISPB1_SER_CLK 432 -MX53_PAD_EIM_D16__ECSPI1_SCLK 433 -MX53_PAD_EIM_D16__I2C2_SDA 434 -MX53_PAD_EIM_D17__EMI_WEIM_D_17 435 -MX53_PAD_EIM_D17__GPIO3_17 436 -MX53_PAD_EIM_D17__IPU_DI0_PIN6 437 -MX53_PAD_EIM_D17__IPU_DISPB1_SER_DIN 438 -MX53_PAD_EIM_D17__ECSPI1_MISO 439 -MX53_PAD_EIM_D17__I2C3_SCL 440 -MX53_PAD_EIM_D18__EMI_WEIM_D_18 441 -MX53_PAD_EIM_D18__GPIO3_18 442 -MX53_PAD_EIM_D18__IPU_DI0_PIN7 443 -MX53_PAD_EIM_D18__IPU_DISPB1_SER_DIO 444 -MX53_PAD_EIM_D18__ECSPI1_MOSI 445 -MX53_PAD_EIM_D18__I2C3_SDA 446 -MX53_PAD_EIM_D18__IPU_DI1_D0_CS 447 -MX53_PAD_EIM_D19__EMI_WEIM_D_19 448 -MX53_PAD_EIM_D19__GPIO3_19 449 -MX53_PAD_EIM_D19__IPU_DI0_PIN8 450 -MX53_PAD_EIM_D19__IPU_DISPB1_SER_RS 451 -MX53_PAD_EIM_D19__ECSPI1_SS1 452 -MX53_PAD_EIM_D19__EPIT1_EPITO 453 -MX53_PAD_EIM_D19__UART1_CTS 454 -MX53_PAD_EIM_D19__USBOH3_USBH2_OC 455 -MX53_PAD_EIM_D20__EMI_WEIM_D_20 456 -MX53_PAD_EIM_D20__GPIO3_20 457 -MX53_PAD_EIM_D20__IPU_DI0_PIN16 458 -MX53_PAD_EIM_D20__IPU_SER_DISP0_CS 459 -MX53_PAD_EIM_D20__CSPI_SS0 460 -MX53_PAD_EIM_D20__EPIT2_EPITO 461 -MX53_PAD_EIM_D20__UART1_RTS 462 -MX53_PAD_EIM_D20__USBOH3_USBH2_PWR 463 -MX53_PAD_EIM_D21__EMI_WEIM_D_21 464 -MX53_PAD_EIM_D21__GPIO3_21 465 -MX53_PAD_EIM_D21__IPU_DI0_PIN17 466 -MX53_PAD_EIM_D21__IPU_DISPB0_SER_CLK 467 -MX53_PAD_EIM_D21__CSPI_SCLK 468 -MX53_PAD_EIM_D21__I2C1_SCL 469 -MX53_PAD_EIM_D21__USBOH3_USBOTG_OC 470 -MX53_PAD_EIM_D22__EMI_WEIM_D_22 471 -MX53_PAD_EIM_D22__GPIO3_22 472 -MX53_PAD_EIM_D22__IPU_DI0_PIN1 473 -MX53_PAD_EIM_D22__IPU_DISPB0_SER_DIN 474 -MX53_PAD_EIM_D22__CSPI_MISO 475 -MX53_PAD_EIM_D22__USBOH3_USBOTG_PWR 476 -MX53_PAD_EIM_D23__EMI_WEIM_D_23 477 -MX53_PAD_EIM_D23__GPIO3_23 478 -MX53_PAD_EIM_D23__UART3_CTS 479 -MX53_PAD_EIM_D23__UART1_DCD 480 -MX53_PAD_EIM_D23__IPU_DI0_D0_CS 481 -MX53_PAD_EIM_D23__IPU_DI1_PIN2 482 -MX53_PAD_EIM_D23__IPU_CSI1_DATA_EN 483 -MX53_PAD_EIM_D23__IPU_DI1_PIN14 484 -MX53_PAD_EIM_EB3__EMI_WEIM_EB_3 485 -MX53_PAD_EIM_EB3__GPIO2_31 486 -MX53_PAD_EIM_EB3__UART3_RTS 487 -MX53_PAD_EIM_EB3__UART1_RI 488 -MX53_PAD_EIM_EB3__IPU_DI1_PIN3 489 -MX53_PAD_EIM_EB3__IPU_CSI1_HSYNC 490 -MX53_PAD_EIM_EB3__IPU_DI1_PIN16 491 -MX53_PAD_EIM_D24__EMI_WEIM_D_24 492 -MX53_PAD_EIM_D24__GPIO3_24 493 -MX53_PAD_EIM_D24__UART3_TXD_MUX 494 -MX53_PAD_EIM_D24__ECSPI1_SS2 495 -MX53_PAD_EIM_D24__CSPI_SS2 496 -MX53_PAD_EIM_D24__AUDMUX_AUD5_RXFS 497 -MX53_PAD_EIM_D24__ECSPI2_SS2 498 -MX53_PAD_EIM_D24__UART1_DTR 499 -MX53_PAD_EIM_D25__EMI_WEIM_D_25 500 -MX53_PAD_EIM_D25__GPIO3_25 501 -MX53_PAD_EIM_D25__UART3_RXD_MUX 502 -MX53_PAD_EIM_D25__ECSPI1_SS3 503 -MX53_PAD_EIM_D25__CSPI_SS3 504 -MX53_PAD_EIM_D25__AUDMUX_AUD5_RXC 505 -MX53_PAD_EIM_D25__ECSPI2_SS3 506 -MX53_PAD_EIM_D25__UART1_DSR 507 -MX53_PAD_EIM_D26__EMI_WEIM_D_26 508 -MX53_PAD_EIM_D26__GPIO3_26 509 -MX53_PAD_EIM_D26__UART2_TXD_MUX 510 -MX53_PAD_EIM_D26__FIRI_RXD 511 -MX53_PAD_EIM_D26__IPU_CSI0_D_1 512 -MX53_PAD_EIM_D26__IPU_DI1_PIN11 513 -MX53_PAD_EIM_D26__IPU_SISG_2 514 -MX53_PAD_EIM_D26__IPU_DISP1_DAT_22 515 -MX53_PAD_EIM_D27__EMI_WEIM_D_27 516 -MX53_PAD_EIM_D27__GPIO3_27 517 -MX53_PAD_EIM_D27__UART2_RXD_MUX 518 -MX53_PAD_EIM_D27__FIRI_TXD 519 -MX53_PAD_EIM_D27__IPU_CSI0_D_0 520 -MX53_PAD_EIM_D27__IPU_DI1_PIN13 521 -MX53_PAD_EIM_D27__IPU_SISG_3 522 -MX53_PAD_EIM_D27__IPU_DISP1_DAT_23 523 -MX53_PAD_EIM_D28__EMI_WEIM_D_28 524 -MX53_PAD_EIM_D28__GPIO3_28 525 -MX53_PAD_EIM_D28__UART2_CTS 526 -MX53_PAD_EIM_D28__IPU_DISPB0_SER_DIO 527 -MX53_PAD_EIM_D28__CSPI_MOSI 528 -MX53_PAD_EIM_D28__I2C1_SDA 529 -MX53_PAD_EIM_D28__IPU_EXT_TRIG 530 -MX53_PAD_EIM_D28__IPU_DI0_PIN13 531 -MX53_PAD_EIM_D29__EMI_WEIM_D_29 532 -MX53_PAD_EIM_D29__GPIO3_29 533 -MX53_PAD_EIM_D29__UART2_RTS 534 -MX53_PAD_EIM_D29__IPU_DISPB0_SER_RS 535 -MX53_PAD_EIM_D29__CSPI_SS0 536 -MX53_PAD_EIM_D29__IPU_DI1_PIN15 537 -MX53_PAD_EIM_D29__IPU_CSI1_VSYNC 538 -MX53_PAD_EIM_D29__IPU_DI0_PIN14 539 -MX53_PAD_EIM_D30__EMI_WEIM_D_30 540 -MX53_PAD_EIM_D30__GPIO3_30 541 -MX53_PAD_EIM_D30__UART3_CTS 542 -MX53_PAD_EIM_D30__IPU_CSI0_D_3 543 -MX53_PAD_EIM_D30__IPU_DI0_PIN11 544 -MX53_PAD_EIM_D30__IPU_DISP1_DAT_21 545 -MX53_PAD_EIM_D30__USBOH3_USBH1_OC 546 -MX53_PAD_EIM_D30__USBOH3_USBH2_OC 547 -MX53_PAD_EIM_D31__EMI_WEIM_D_31 548 -MX53_PAD_EIM_D31__GPIO3_31 549 -MX53_PAD_EIM_D31__UART3_RTS 550 -MX53_PAD_EIM_D31__IPU_CSI0_D_2 551 -MX53_PAD_EIM_D31__IPU_DI0_PIN12 552 -MX53_PAD_EIM_D31__IPU_DISP1_DAT_20 553 -MX53_PAD_EIM_D31__USBOH3_USBH1_PWR 554 -MX53_PAD_EIM_D31__USBOH3_USBH2_PWR 555 -MX53_PAD_EIM_A24__EMI_WEIM_A_24 556 -MX53_PAD_EIM_A24__GPIO5_4 557 -MX53_PAD_EIM_A24__IPU_DISP1_DAT_19 558 -MX53_PAD_EIM_A24__IPU_CSI1_D_19 559 -MX53_PAD_EIM_A24__IPU_SISG_2 560 -MX53_PAD_EIM_A24__USBPHY2_BVALID 561 -MX53_PAD_EIM_A23__EMI_WEIM_A_23 562 -MX53_PAD_EIM_A23__GPIO6_6 563 -MX53_PAD_EIM_A23__IPU_DISP1_DAT_18 564 -MX53_PAD_EIM_A23__IPU_CSI1_D_18 565 -MX53_PAD_EIM_A23__IPU_SISG_3 566 -MX53_PAD_EIM_A23__USBPHY2_ENDSESSION 567 -MX53_PAD_EIM_A22__EMI_WEIM_A_22 568 -MX53_PAD_EIM_A22__GPIO2_16 569 -MX53_PAD_EIM_A22__IPU_DISP1_DAT_17 570 -MX53_PAD_EIM_A22__IPU_CSI1_D_17 571 -MX53_PAD_EIM_A22__SRC_BT_CFG1_7 572 -MX53_PAD_EIM_A21__EMI_WEIM_A_21 573 -MX53_PAD_EIM_A21__GPIO2_17 574 -MX53_PAD_EIM_A21__IPU_DISP1_DAT_16 575 -MX53_PAD_EIM_A21__IPU_CSI1_D_16 576 -MX53_PAD_EIM_A21__SRC_BT_CFG1_6 577 -MX53_PAD_EIM_A20__EMI_WEIM_A_20 578 -MX53_PAD_EIM_A20__GPIO2_18 579 -MX53_PAD_EIM_A20__IPU_DISP1_DAT_15 580 -MX53_PAD_EIM_A20__IPU_CSI1_D_15 581 -MX53_PAD_EIM_A20__SRC_BT_CFG1_5 582 -MX53_PAD_EIM_A19__EMI_WEIM_A_19 583 -MX53_PAD_EIM_A19__GPIO2_19 584 -MX53_PAD_EIM_A19__IPU_DISP1_DAT_14 585 -MX53_PAD_EIM_A19__IPU_CSI1_D_14 586 -MX53_PAD_EIM_A19__SRC_BT_CFG1_4 587 -MX53_PAD_EIM_A18__EMI_WEIM_A_18 588 -MX53_PAD_EIM_A18__GPIO2_20 589 -MX53_PAD_EIM_A18__IPU_DISP1_DAT_13 590 -MX53_PAD_EIM_A18__IPU_CSI1_D_13 591 -MX53_PAD_EIM_A18__SRC_BT_CFG1_3 592 -MX53_PAD_EIM_A17__EMI_WEIM_A_17 593 -MX53_PAD_EIM_A17__GPIO2_21 594 -MX53_PAD_EIM_A17__IPU_DISP1_DAT_12 595 -MX53_PAD_EIM_A17__IPU_CSI1_D_12 596 -MX53_PAD_EIM_A17__SRC_BT_CFG1_2 597 -MX53_PAD_EIM_A16__EMI_WEIM_A_16 598 -MX53_PAD_EIM_A16__GPIO2_22 599 -MX53_PAD_EIM_A16__IPU_DI1_DISP_CLK 600 -MX53_PAD_EIM_A16__IPU_CSI1_PIXCLK 601 -MX53_PAD_EIM_A16__SRC_BT_CFG1_1 602 -MX53_PAD_EIM_CS0__EMI_WEIM_CS_0 603 -MX53_PAD_EIM_CS0__GPIO2_23 604 -MX53_PAD_EIM_CS0__ECSPI2_SCLK 605 -MX53_PAD_EIM_CS0__IPU_DI1_PIN5 606 -MX53_PAD_EIM_CS1__EMI_WEIM_CS_1 607 -MX53_PAD_EIM_CS1__GPIO2_24 608 -MX53_PAD_EIM_CS1__ECSPI2_MOSI 609 -MX53_PAD_EIM_CS1__IPU_DI1_PIN6 610 -MX53_PAD_EIM_OE__EMI_WEIM_OE 611 -MX53_PAD_EIM_OE__GPIO2_25 612 -MX53_PAD_EIM_OE__ECSPI2_MISO 613 -MX53_PAD_EIM_OE__IPU_DI1_PIN7 614 -MX53_PAD_EIM_OE__USBPHY2_IDDIG 615 -MX53_PAD_EIM_RW__EMI_WEIM_RW 616 -MX53_PAD_EIM_RW__GPIO2_26 617 -MX53_PAD_EIM_RW__ECSPI2_SS0 618 -MX53_PAD_EIM_RW__IPU_DI1_PIN8 619 -MX53_PAD_EIM_RW__USBPHY2_HOSTDISCONNECT 620 -MX53_PAD_EIM_LBA__EMI_WEIM_LBA 621 -MX53_PAD_EIM_LBA__GPIO2_27 622 -MX53_PAD_EIM_LBA__ECSPI2_SS1 623 -MX53_PAD_EIM_LBA__IPU_DI1_PIN17 624 -MX53_PAD_EIM_LBA__SRC_BT_CFG1_0 625 -MX53_PAD_EIM_EB0__EMI_WEIM_EB_0 626 -MX53_PAD_EIM_EB0__GPIO2_28 627 -MX53_PAD_EIM_EB0__IPU_DISP1_DAT_11 628 -MX53_PAD_EIM_EB0__IPU_CSI1_D_11 629 -MX53_PAD_EIM_EB0__GPC_PMIC_RDY 630 -MX53_PAD_EIM_EB0__SRC_BT_CFG2_7 631 -MX53_PAD_EIM_EB1__EMI_WEIM_EB_1 632 -MX53_PAD_EIM_EB1__GPIO2_29 633 -MX53_PAD_EIM_EB1__IPU_DISP1_DAT_10 634 -MX53_PAD_EIM_EB1__IPU_CSI1_D_10 635 -MX53_PAD_EIM_EB1__SRC_BT_CFG2_6 636 -MX53_PAD_EIM_DA0__EMI_NAND_WEIM_DA_0 637 -MX53_PAD_EIM_DA0__GPIO3_0 638 -MX53_PAD_EIM_DA0__IPU_DISP1_DAT_9 639 -MX53_PAD_EIM_DA0__IPU_CSI1_D_9 640 -MX53_PAD_EIM_DA0__SRC_BT_CFG2_5 641 -MX53_PAD_EIM_DA1__EMI_NAND_WEIM_DA_1 642 -MX53_PAD_EIM_DA1__GPIO3_1 643 -MX53_PAD_EIM_DA1__IPU_DISP1_DAT_8 644 -MX53_PAD_EIM_DA1__IPU_CSI1_D_8 645 -MX53_PAD_EIM_DA1__SRC_BT_CFG2_4 646 -MX53_PAD_EIM_DA2__EMI_NAND_WEIM_DA_2 647 -MX53_PAD_EIM_DA2__GPIO3_2 648 -MX53_PAD_EIM_DA2__IPU_DISP1_DAT_7 649 -MX53_PAD_EIM_DA2__IPU_CSI1_D_7 650 -MX53_PAD_EIM_DA2__SRC_BT_CFG2_3 651 -MX53_PAD_EIM_DA3__EMI_NAND_WEIM_DA_3 652 -MX53_PAD_EIM_DA3__GPIO3_3 653 -MX53_PAD_EIM_DA3__IPU_DISP1_DAT_6 654 -MX53_PAD_EIM_DA3__IPU_CSI1_D_6 655 -MX53_PAD_EIM_DA3__SRC_BT_CFG2_2 656 -MX53_PAD_EIM_DA4__EMI_NAND_WEIM_DA_4 657 -MX53_PAD_EIM_DA4__GPIO3_4 658 -MX53_PAD_EIM_DA4__IPU_DISP1_DAT_5 659 -MX53_PAD_EIM_DA4__IPU_CSI1_D_5 660 -MX53_PAD_EIM_DA4__SRC_BT_CFG3_7 661 -MX53_PAD_EIM_DA5__EMI_NAND_WEIM_DA_5 662 -MX53_PAD_EIM_DA5__GPIO3_5 663 -MX53_PAD_EIM_DA5__IPU_DISP1_DAT_4 664 -MX53_PAD_EIM_DA5__IPU_CSI1_D_4 665 -MX53_PAD_EIM_DA5__SRC_BT_CFG3_6 666 -MX53_PAD_EIM_DA6__EMI_NAND_WEIM_DA_6 667 -MX53_PAD_EIM_DA6__GPIO3_6 668 -MX53_PAD_EIM_DA6__IPU_DISP1_DAT_3 669 -MX53_PAD_EIM_DA6__IPU_CSI1_D_3 670 -MX53_PAD_EIM_DA6__SRC_BT_CFG3_5 671 -MX53_PAD_EIM_DA7__EMI_NAND_WEIM_DA_7 672 -MX53_PAD_EIM_DA7__GPIO3_7 673 -MX53_PAD_EIM_DA7__IPU_DISP1_DAT_2 674 -MX53_PAD_EIM_DA7__IPU_CSI1_D_2 675 -MX53_PAD_EIM_DA7__SRC_BT_CFG3_4 676 -MX53_PAD_EIM_DA8__EMI_NAND_WEIM_DA_8 677 -MX53_PAD_EIM_DA8__GPIO3_8 678 -MX53_PAD_EIM_DA8__IPU_DISP1_DAT_1 679 -MX53_PAD_EIM_DA8__IPU_CSI1_D_1 680 -MX53_PAD_EIM_DA8__SRC_BT_CFG3_3 681 -MX53_PAD_EIM_DA9__EMI_NAND_WEIM_DA_9 682 -MX53_PAD_EIM_DA9__GPIO3_9 683 -MX53_PAD_EIM_DA9__IPU_DISP1_DAT_0 684 -MX53_PAD_EIM_DA9__IPU_CSI1_D_0 685 -MX53_PAD_EIM_DA9__SRC_BT_CFG3_2 686 -MX53_PAD_EIM_DA10__EMI_NAND_WEIM_DA_10 687 -MX53_PAD_EIM_DA10__GPIO3_10 688 -MX53_PAD_EIM_DA10__IPU_DI1_PIN15 689 -MX53_PAD_EIM_DA10__IPU_CSI1_DATA_EN 690 -MX53_PAD_EIM_DA10__SRC_BT_CFG3_1 691 -MX53_PAD_EIM_DA11__EMI_NAND_WEIM_DA_11 692 -MX53_PAD_EIM_DA11__GPIO3_11 693 -MX53_PAD_EIM_DA11__IPU_DI1_PIN2 694 -MX53_PAD_EIM_DA11__IPU_CSI1_HSYNC 695 -MX53_PAD_EIM_DA12__EMI_NAND_WEIM_DA_12 696 -MX53_PAD_EIM_DA12__GPIO3_12 697 -MX53_PAD_EIM_DA12__IPU_DI1_PIN3 698 -MX53_PAD_EIM_DA12__IPU_CSI1_VSYNC 699 -MX53_PAD_EIM_DA13__EMI_NAND_WEIM_DA_13 700 -MX53_PAD_EIM_DA13__GPIO3_13 701 -MX53_PAD_EIM_DA13__IPU_DI1_D0_CS 702 -MX53_PAD_EIM_DA13__CCM_DI1_EXT_CLK 703 -MX53_PAD_EIM_DA14__EMI_NAND_WEIM_DA_14 704 -MX53_PAD_EIM_DA14__GPIO3_14 705 -MX53_PAD_EIM_DA14__IPU_DI1_D1_CS 706 -MX53_PAD_EIM_DA14__CCM_DI0_EXT_CLK 707 -MX53_PAD_EIM_DA15__EMI_NAND_WEIM_DA_15 708 -MX53_PAD_EIM_DA15__GPIO3_15 709 -MX53_PAD_EIM_DA15__IPU_DI1_PIN1 710 -MX53_PAD_EIM_DA15__IPU_DI1_PIN4 711 -MX53_PAD_NANDF_WE_B__EMI_NANDF_WE_B 712 -MX53_PAD_NANDF_WE_B__GPIO6_12 713 -MX53_PAD_NANDF_RE_B__EMI_NANDF_RE_B 714 -MX53_PAD_NANDF_RE_B__GPIO6_13 715 -MX53_PAD_EIM_WAIT__EMI_WEIM_WAIT 716 -MX53_PAD_EIM_WAIT__GPIO5_0 717 -MX53_PAD_EIM_WAIT__EMI_WEIM_DTACK_B 718 -MX53_PAD_LVDS1_TX3_P__GPIO6_22 719 -MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3 720 -MX53_PAD_LVDS1_TX2_P__GPIO6_24 721 -MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2 722 -MX53_PAD_LVDS1_CLK_P__GPIO6_26 723 -MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK 724 -MX53_PAD_LVDS1_TX1_P__GPIO6_28 725 -MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1 726 -MX53_PAD_LVDS1_TX0_P__GPIO6_30 727 -MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0 728 -MX53_PAD_LVDS0_TX3_P__GPIO7_22 729 -MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3 730 -MX53_PAD_LVDS0_CLK_P__GPIO7_24 731 -MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK 732 -MX53_PAD_LVDS0_TX2_P__GPIO7_26 733 -MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2 734 -MX53_PAD_LVDS0_TX1_P__GPIO7_28 735 -MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1 736 -MX53_PAD_LVDS0_TX0_P__GPIO7_30 737 -MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0 738 -MX53_PAD_GPIO_10__GPIO4_0 739 -MX53_PAD_GPIO_10__OSC32k_32K_OUT 740 -MX53_PAD_GPIO_11__GPIO4_1 741 -MX53_PAD_GPIO_12__GPIO4_2 742 -MX53_PAD_GPIO_13__GPIO4_3 743 -MX53_PAD_GPIO_14__GPIO4_4 744 -MX53_PAD_NANDF_CLE__EMI_NANDF_CLE 745 -MX53_PAD_NANDF_CLE__GPIO6_7 746 -MX53_PAD_NANDF_CLE__USBPHY1_VSTATUS_0 747 -MX53_PAD_NANDF_ALE__EMI_NANDF_ALE 748 -MX53_PAD_NANDF_ALE__GPIO6_8 749 -MX53_PAD_NANDF_ALE__USBPHY1_VSTATUS_1 750 -MX53_PAD_NANDF_WP_B__EMI_NANDF_WP_B 751 -MX53_PAD_NANDF_WP_B__GPIO6_9 752 -MX53_PAD_NANDF_WP_B__USBPHY1_VSTATUS_2 753 -MX53_PAD_NANDF_RB0__EMI_NANDF_RB_0 754 -MX53_PAD_NANDF_RB0__GPIO6_10 755 -MX53_PAD_NANDF_RB0__USBPHY1_VSTATUS_3 756 -MX53_PAD_NANDF_CS0__EMI_NANDF_CS_0 757 -MX53_PAD_NANDF_CS0__GPIO6_11 758 -MX53_PAD_NANDF_CS0__USBPHY1_VSTATUS_4 759 -MX53_PAD_NANDF_CS1__EMI_NANDF_CS_1 760 -MX53_PAD_NANDF_CS1__GPIO6_14 761 -MX53_PAD_NANDF_CS1__MLB_MLBCLK 762 -MX53_PAD_NANDF_CS1__USBPHY1_VSTATUS_5 763 -MX53_PAD_NANDF_CS2__EMI_NANDF_CS_2 764 -MX53_PAD_NANDF_CS2__GPIO6_15 765 -MX53_PAD_NANDF_CS2__IPU_SISG_0 766 -MX53_PAD_NANDF_CS2__ESAI1_TX0 767 -MX53_PAD_NANDF_CS2__EMI_WEIM_CRE 768 -MX53_PAD_NANDF_CS2__CCM_CSI0_MCLK 769 -MX53_PAD_NANDF_CS2__MLB_MLBSIG 770 -MX53_PAD_NANDF_CS2__USBPHY1_VSTATUS_6 771 -MX53_PAD_NANDF_CS3__EMI_NANDF_CS_3 772 -MX53_PAD_NANDF_CS3__GPIO6_16 773 -MX53_PAD_NANDF_CS3__IPU_SISG_1 774 -MX53_PAD_NANDF_CS3__ESAI1_TX1 775 -MX53_PAD_NANDF_CS3__EMI_WEIM_A_26 776 -MX53_PAD_NANDF_CS3__MLB_MLBDAT 777 -MX53_PAD_NANDF_CS3__USBPHY1_VSTATUS_7 778 -MX53_PAD_FEC_MDIO__FEC_MDIO 779 -MX53_PAD_FEC_MDIO__GPIO1_22 780 -MX53_PAD_FEC_MDIO__ESAI1_SCKR 781 -MX53_PAD_FEC_MDIO__FEC_COL 782 -MX53_PAD_FEC_MDIO__RTC_CE_RTC_PS2 783 -MX53_PAD_FEC_MDIO__SDMA_DEBUG_BUS_DEVICE_3 784 -MX53_PAD_FEC_MDIO__EMI_EMI_DEBUG_49 785 -MX53_PAD_FEC_REF_CLK__FEC_TX_CLK 786 -MX53_PAD_FEC_REF_CLK__GPIO1_23 787 -MX53_PAD_FEC_REF_CLK__ESAI1_FSR 788 -MX53_PAD_FEC_REF_CLK__SDMA_DEBUG_BUS_DEVICE_4 789 -MX53_PAD_FEC_REF_CLK__EMI_EMI_DEBUG_50 790 -MX53_PAD_FEC_RX_ER__FEC_RX_ER 791 -MX53_PAD_FEC_RX_ER__GPIO1_24 792 -MX53_PAD_FEC_RX_ER__ESAI1_HCKR 793 -MX53_PAD_FEC_RX_ER__FEC_RX_CLK 794 -MX53_PAD_FEC_RX_ER__RTC_CE_RTC_PS3 795 -MX53_PAD_FEC_CRS_DV__FEC_RX_DV 796 -MX53_PAD_FEC_CRS_DV__GPIO1_25 797 -MX53_PAD_FEC_CRS_DV__ESAI1_SCKT 798 -MX53_PAD_FEC_RXD1__FEC_RDATA_1 799 -MX53_PAD_FEC_RXD1__GPIO1_26 800 -MX53_PAD_FEC_RXD1__ESAI1_FST 801 -MX53_PAD_FEC_RXD1__MLB_MLBSIG 802 -MX53_PAD_FEC_RXD1__RTC_CE_RTC_PS1 803 -MX53_PAD_FEC_RXD0__FEC_RDATA_0 804 -MX53_PAD_FEC_RXD0__GPIO1_27 805 -MX53_PAD_FEC_RXD0__ESAI1_HCKT 806 -MX53_PAD_FEC_RXD0__OSC32k_32K_OUT 807 -MX53_PAD_FEC_TX_EN__FEC_TX_EN 808 -MX53_PAD_FEC_TX_EN__GPIO1_28 809 -MX53_PAD_FEC_TX_EN__ESAI1_TX3_RX2 810 -MX53_PAD_FEC_TXD1__FEC_TDATA_1 811 -MX53_PAD_FEC_TXD1__GPIO1_29 812 -MX53_PAD_FEC_TXD1__ESAI1_TX2_RX3 813 -MX53_PAD_FEC_TXD1__MLB_MLBCLK 814 -MX53_PAD_FEC_TXD1__RTC_CE_RTC_PRSC_CLK 815 -MX53_PAD_FEC_TXD0__FEC_TDATA_0 816 -MX53_PAD_FEC_TXD0__GPIO1_30 817 -MX53_PAD_FEC_TXD0__ESAI1_TX4_RX1 818 -MX53_PAD_FEC_TXD0__USBPHY2_DATAOUT_0 819 -MX53_PAD_FEC_MDC__FEC_MDC 820 -MX53_PAD_FEC_MDC__GPIO1_31 821 -MX53_PAD_FEC_MDC__ESAI1_TX5_RX0 822 -MX53_PAD_FEC_MDC__MLB_MLBDAT 823 -MX53_PAD_FEC_MDC__RTC_CE_RTC_ALARM1_TRIG 824 -MX53_PAD_FEC_MDC__USBPHY2_DATAOUT_1 825 -MX53_PAD_PATA_DIOW__PATA_DIOW 826 -MX53_PAD_PATA_DIOW__GPIO6_17 827 -MX53_PAD_PATA_DIOW__UART1_TXD_MUX 828 -MX53_PAD_PATA_DIOW__USBPHY2_DATAOUT_2 829 -MX53_PAD_PATA_DMACK__PATA_DMACK 830 -MX53_PAD_PATA_DMACK__GPIO6_18 831 -MX53_PAD_PATA_DMACK__UART1_RXD_MUX 832 -MX53_PAD_PATA_DMACK__USBPHY2_DATAOUT_3 833 -MX53_PAD_PATA_DMARQ__PATA_DMARQ 834 -MX53_PAD_PATA_DMARQ__GPIO7_0 835 -MX53_PAD_PATA_DMARQ__UART2_TXD_MUX 836 -MX53_PAD_PATA_DMARQ__CCM_CCM_OUT_0 837 -MX53_PAD_PATA_DMARQ__USBPHY2_DATAOUT_4 838 -MX53_PAD_PATA_BUFFER_EN__PATA_BUFFER_EN 839 -MX53_PAD_PATA_BUFFER_EN__GPIO7_1 840 -MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX 841 -MX53_PAD_PATA_BUFFER_EN__CCM_CCM_OUT_1 842 -MX53_PAD_PATA_BUFFER_EN__USBPHY2_DATAOUT_5 843 -MX53_PAD_PATA_INTRQ__PATA_INTRQ 844 -MX53_PAD_PATA_INTRQ__GPIO7_2 845 -MX53_PAD_PATA_INTRQ__UART2_CTS 846 -MX53_PAD_PATA_INTRQ__CAN1_TXCAN 847 -MX53_PAD_PATA_INTRQ__CCM_CCM_OUT_2 848 -MX53_PAD_PATA_INTRQ__USBPHY2_DATAOUT_6 849 -MX53_PAD_PATA_DIOR__PATA_DIOR 850 -MX53_PAD_PATA_DIOR__GPIO7_3 851 -MX53_PAD_PATA_DIOR__UART2_RTS 852 -MX53_PAD_PATA_DIOR__CAN1_RXCAN 853 -MX53_PAD_PATA_DIOR__USBPHY2_DATAOUT_7 854 -MX53_PAD_PATA_RESET_B__PATA_PATA_RESET_B 855 -MX53_PAD_PATA_RESET_B__GPIO7_4 856 -MX53_PAD_PATA_RESET_B__ESDHC3_CMD 857 -MX53_PAD_PATA_RESET_B__UART1_CTS 858 -MX53_PAD_PATA_RESET_B__CAN2_TXCAN 859 -MX53_PAD_PATA_RESET_B__USBPHY1_DATAOUT_0 860 -MX53_PAD_PATA_IORDY__PATA_IORDY 861 -MX53_PAD_PATA_IORDY__GPIO7_5 862 -MX53_PAD_PATA_IORDY__ESDHC3_CLK 863 -MX53_PAD_PATA_IORDY__UART1_RTS 864 -MX53_PAD_PATA_IORDY__CAN2_RXCAN 865 -MX53_PAD_PATA_IORDY__USBPHY1_DATAOUT_1 866 -MX53_PAD_PATA_DA_0__PATA_DA_0 867 -MX53_PAD_PATA_DA_0__GPIO7_6 868 -MX53_PAD_PATA_DA_0__ESDHC3_RST 869 -MX53_PAD_PATA_DA_0__OWIRE_LINE 870 -MX53_PAD_PATA_DA_0__USBPHY1_DATAOUT_2 871 -MX53_PAD_PATA_DA_1__PATA_DA_1 872 -MX53_PAD_PATA_DA_1__GPIO7_7 873 -MX53_PAD_PATA_DA_1__ESDHC4_CMD 874 -MX53_PAD_PATA_DA_1__UART3_CTS 875 -MX53_PAD_PATA_DA_1__USBPHY1_DATAOUT_3 876 -MX53_PAD_PATA_DA_2__PATA_DA_2 877 -MX53_PAD_PATA_DA_2__GPIO7_8 878 -MX53_PAD_PATA_DA_2__ESDHC4_CLK 879 -MX53_PAD_PATA_DA_2__UART3_RTS 880 -MX53_PAD_PATA_DA_2__USBPHY1_DATAOUT_4 881 -MX53_PAD_PATA_CS_0__PATA_CS_0 882 -MX53_PAD_PATA_CS_0__GPIO7_9 883 -MX53_PAD_PATA_CS_0__UART3_TXD_MUX 884 -MX53_PAD_PATA_CS_0__USBPHY1_DATAOUT_5 885 -MX53_PAD_PATA_CS_1__PATA_CS_1 886 -MX53_PAD_PATA_CS_1__GPIO7_10 887 -MX53_PAD_PATA_CS_1__UART3_RXD_MUX 888 -MX53_PAD_PATA_CS_1__USBPHY1_DATAOUT_6 889 -MX53_PAD_PATA_DATA0__PATA_DATA_0 890 -MX53_PAD_PATA_DATA0__GPIO2_0 891 -MX53_PAD_PATA_DATA0__EMI_NANDF_D_0 892 -MX53_PAD_PATA_DATA0__ESDHC3_DAT4 893 -MX53_PAD_PATA_DATA0__GPU3d_GPU_DEBUG_OUT_0 894 -MX53_PAD_PATA_DATA0__IPU_DIAG_BUS_0 895 -MX53_PAD_PATA_DATA0__USBPHY1_DATAOUT_7 896 -MX53_PAD_PATA_DATA1__PATA_DATA_1 897 -MX53_PAD_PATA_DATA1__GPIO2_1 898 -MX53_PAD_PATA_DATA1__EMI_NANDF_D_1 899 -MX53_PAD_PATA_DATA1__ESDHC3_DAT5 900 -MX53_PAD_PATA_DATA1__GPU3d_GPU_DEBUG_OUT_1 901 -MX53_PAD_PATA_DATA1__IPU_DIAG_BUS_1 902 -MX53_PAD_PATA_DATA2__PATA_DATA_2 903 -MX53_PAD_PATA_DATA2__GPIO2_2 904 -MX53_PAD_PATA_DATA2__EMI_NANDF_D_2 905 -MX53_PAD_PATA_DATA2__ESDHC3_DAT6 906 -MX53_PAD_PATA_DATA2__GPU3d_GPU_DEBUG_OUT_2 907 -MX53_PAD_PATA_DATA2__IPU_DIAG_BUS_2 908 -MX53_PAD_PATA_DATA3__PATA_DATA_3 909 -MX53_PAD_PATA_DATA3__GPIO2_3 910 -MX53_PAD_PATA_DATA3__EMI_NANDF_D_3 911 -MX53_PAD_PATA_DATA3__ESDHC3_DAT7 912 -MX53_PAD_PATA_DATA3__GPU3d_GPU_DEBUG_OUT_3 913 -MX53_PAD_PATA_DATA3__IPU_DIAG_BUS_3 914 -MX53_PAD_PATA_DATA4__PATA_DATA_4 915 -MX53_PAD_PATA_DATA4__GPIO2_4 916 -MX53_PAD_PATA_DATA4__EMI_NANDF_D_4 917 -MX53_PAD_PATA_DATA4__ESDHC4_DAT4 918 -MX53_PAD_PATA_DATA4__GPU3d_GPU_DEBUG_OUT_4 919 -MX53_PAD_PATA_DATA4__IPU_DIAG_BUS_4 920 -MX53_PAD_PATA_DATA5__PATA_DATA_5 921 -MX53_PAD_PATA_DATA5__GPIO2_5 922 -MX53_PAD_PATA_DATA5__EMI_NANDF_D_5 923 -MX53_PAD_PATA_DATA5__ESDHC4_DAT5 924 -MX53_PAD_PATA_DATA5__GPU3d_GPU_DEBUG_OUT_5 925 -MX53_PAD_PATA_DATA5__IPU_DIAG_BUS_5 926 -MX53_PAD_PATA_DATA6__PATA_DATA_6 927 -MX53_PAD_PATA_DATA6__GPIO2_6 928 -MX53_PAD_PATA_DATA6__EMI_NANDF_D_6 929 -MX53_PAD_PATA_DATA6__ESDHC4_DAT6 930 -MX53_PAD_PATA_DATA6__GPU3d_GPU_DEBUG_OUT_6 931 -MX53_PAD_PATA_DATA6__IPU_DIAG_BUS_6 932 -MX53_PAD_PATA_DATA7__PATA_DATA_7 933 -MX53_PAD_PATA_DATA7__GPIO2_7 934 -MX53_PAD_PATA_DATA7__EMI_NANDF_D_7 935 -MX53_PAD_PATA_DATA7__ESDHC4_DAT7 936 -MX53_PAD_PATA_DATA7__GPU3d_GPU_DEBUG_OUT_7 937 -MX53_PAD_PATA_DATA7__IPU_DIAG_BUS_7 938 -MX53_PAD_PATA_DATA8__PATA_DATA_8 939 -MX53_PAD_PATA_DATA8__GPIO2_8 940 -MX53_PAD_PATA_DATA8__ESDHC1_DAT4 941 -MX53_PAD_PATA_DATA8__EMI_NANDF_D_8 942 -MX53_PAD_PATA_DATA8__ESDHC3_DAT0 943 -MX53_PAD_PATA_DATA8__GPU3d_GPU_DEBUG_OUT_8 944 -MX53_PAD_PATA_DATA8__IPU_DIAG_BUS_8 945 -MX53_PAD_PATA_DATA9__PATA_DATA_9 946 -MX53_PAD_PATA_DATA9__GPIO2_9 947 -MX53_PAD_PATA_DATA9__ESDHC1_DAT5 948 -MX53_PAD_PATA_DATA9__EMI_NANDF_D_9 949 -MX53_PAD_PATA_DATA9__ESDHC3_DAT1 950 -MX53_PAD_PATA_DATA9__GPU3d_GPU_DEBUG_OUT_9 951 -MX53_PAD_PATA_DATA9__IPU_DIAG_BUS_9 952 -MX53_PAD_PATA_DATA10__PATA_DATA_10 953 -MX53_PAD_PATA_DATA10__GPIO2_10 954 -MX53_PAD_PATA_DATA10__ESDHC1_DAT6 955 -MX53_PAD_PATA_DATA10__EMI_NANDF_D_10 956 -MX53_PAD_PATA_DATA10__ESDHC3_DAT2 957 -MX53_PAD_PATA_DATA10__GPU3d_GPU_DEBUG_OUT_10 958 -MX53_PAD_PATA_DATA10__IPU_DIAG_BUS_10 959 -MX53_PAD_PATA_DATA11__PATA_DATA_11 960 -MX53_PAD_PATA_DATA11__GPIO2_11 961 -MX53_PAD_PATA_DATA11__ESDHC1_DAT7 962 -MX53_PAD_PATA_DATA11__EMI_NANDF_D_11 963 -MX53_PAD_PATA_DATA11__ESDHC3_DAT3 964 -MX53_PAD_PATA_DATA11__GPU3d_GPU_DEBUG_OUT_11 965 -MX53_PAD_PATA_DATA11__IPU_DIAG_BUS_11 966 -MX53_PAD_PATA_DATA12__PATA_DATA_12 967 -MX53_PAD_PATA_DATA12__GPIO2_12 968 -MX53_PAD_PATA_DATA12__ESDHC2_DAT4 969 -MX53_PAD_PATA_DATA12__EMI_NANDF_D_12 970 -MX53_PAD_PATA_DATA12__ESDHC4_DAT0 971 -MX53_PAD_PATA_DATA12__GPU3d_GPU_DEBUG_OUT_12 972 -MX53_PAD_PATA_DATA12__IPU_DIAG_BUS_12 973 -MX53_PAD_PATA_DATA13__PATA_DATA_13 974 -MX53_PAD_PATA_DATA13__GPIO2_13 975 -MX53_PAD_PATA_DATA13__ESDHC2_DAT5 976 -MX53_PAD_PATA_DATA13__EMI_NANDF_D_13 977 -MX53_PAD_PATA_DATA13__ESDHC4_DAT1 978 -MX53_PAD_PATA_DATA13__GPU3d_GPU_DEBUG_OUT_13 979 -MX53_PAD_PATA_DATA13__IPU_DIAG_BUS_13 980 -MX53_PAD_PATA_DATA14__PATA_DATA_14 981 -MX53_PAD_PATA_DATA14__GPIO2_14 982 -MX53_PAD_PATA_DATA14__ESDHC2_DAT6 983 -MX53_PAD_PATA_DATA14__EMI_NANDF_D_14 984 -MX53_PAD_PATA_DATA14__ESDHC4_DAT2 985 -MX53_PAD_PATA_DATA14__GPU3d_GPU_DEBUG_OUT_14 986 -MX53_PAD_PATA_DATA14__IPU_DIAG_BUS_14 987 -MX53_PAD_PATA_DATA15__PATA_DATA_15 988 -MX53_PAD_PATA_DATA15__GPIO2_15 989 -MX53_PAD_PATA_DATA15__ESDHC2_DAT7 990 -MX53_PAD_PATA_DATA15__EMI_NANDF_D_15 991 -MX53_PAD_PATA_DATA15__ESDHC4_DAT3 992 -MX53_PAD_PATA_DATA15__GPU3d_GPU_DEBUG_OUT_15 993 -MX53_PAD_PATA_DATA15__IPU_DIAG_BUS_15 994 -MX53_PAD_SD1_DATA0__ESDHC1_DAT0 995 -MX53_PAD_SD1_DATA0__GPIO1_16 996 -MX53_PAD_SD1_DATA0__GPT_CAPIN1 997 -MX53_PAD_SD1_DATA0__CSPI_MISO 998 -MX53_PAD_SD1_DATA0__CCM_PLL3_BYP 999 -MX53_PAD_SD1_DATA1__ESDHC1_DAT1 1000 -MX53_PAD_SD1_DATA1__GPIO1_17 1001 -MX53_PAD_SD1_DATA1__GPT_CAPIN2 1002 -MX53_PAD_SD1_DATA1__CSPI_SS0 1003 -MX53_PAD_SD1_DATA1__CCM_PLL4_BYP 1004 -MX53_PAD_SD1_CMD__ESDHC1_CMD 1005 -MX53_PAD_SD1_CMD__GPIO1_18 1006 -MX53_PAD_SD1_CMD__GPT_CMPOUT1 1007 -MX53_PAD_SD1_CMD__CSPI_MOSI 1008 -MX53_PAD_SD1_CMD__CCM_PLL1_BYP 1009 -MX53_PAD_SD1_DATA2__ESDHC1_DAT2 1010 -MX53_PAD_SD1_DATA2__GPIO1_19 1011 -MX53_PAD_SD1_DATA2__GPT_CMPOUT2 1012 -MX53_PAD_SD1_DATA2__PWM2_PWMO 1013 -MX53_PAD_SD1_DATA2__WDOG1_WDOG_B 1014 -MX53_PAD_SD1_DATA2__CSPI_SS1 1015 -MX53_PAD_SD1_DATA2__WDOG1_WDOG_RST_B_DEB 1016 -MX53_PAD_SD1_DATA2__CCM_PLL2_BYP 1017 -MX53_PAD_SD1_CLK__ESDHC1_CLK 1018 -MX53_PAD_SD1_CLK__GPIO1_20 1019 -MX53_PAD_SD1_CLK__OSC32k_32K_OUT 1020 -MX53_PAD_SD1_CLK__GPT_CLKIN 1021 -MX53_PAD_SD1_CLK__CSPI_SCLK 1022 -MX53_PAD_SD1_CLK__SATA_PHY_DTB_0 1023 -MX53_PAD_SD1_DATA3__ESDHC1_DAT3 1024 -MX53_PAD_SD1_DATA3__GPIO1_21 1025 -MX53_PAD_SD1_DATA3__GPT_CMPOUT3 1026 -MX53_PAD_SD1_DATA3__PWM1_PWMO 1027 -MX53_PAD_SD1_DATA3__WDOG2_WDOG_B 1028 -MX53_PAD_SD1_DATA3__CSPI_SS2 1029 -MX53_PAD_SD1_DATA3__WDOG2_WDOG_RST_B_DEB 1030 -MX53_PAD_SD1_DATA3__SATA_PHY_DTB_1 1031 -MX53_PAD_SD2_CLK__ESDHC2_CLK 1032 -MX53_PAD_SD2_CLK__GPIO1_10 1033 -MX53_PAD_SD2_CLK__KPP_COL_5 1034 -MX53_PAD_SD2_CLK__AUDMUX_AUD4_RXFS 1035 -MX53_PAD_SD2_CLK__CSPI_SCLK 1036 -MX53_PAD_SD2_CLK__SCC_RANDOM_V 1037 -MX53_PAD_SD2_CMD__ESDHC2_CMD 1038 -MX53_PAD_SD2_CMD__GPIO1_11 1039 -MX53_PAD_SD2_CMD__KPP_ROW_5 1040 -MX53_PAD_SD2_CMD__AUDMUX_AUD4_RXC 1041 -MX53_PAD_SD2_CMD__CSPI_MOSI 1042 -MX53_PAD_SD2_CMD__SCC_RANDOM 1043 -MX53_PAD_SD2_DATA3__ESDHC2_DAT3 1044 -MX53_PAD_SD2_DATA3__GPIO1_12 1045 -MX53_PAD_SD2_DATA3__KPP_COL_6 1046 -MX53_PAD_SD2_DATA3__AUDMUX_AUD4_TXC 1047 -MX53_PAD_SD2_DATA3__CSPI_SS2 1048 -MX53_PAD_SD2_DATA3__SJC_DONE 1049 -MX53_PAD_SD2_DATA2__ESDHC2_DAT2 1050 -MX53_PAD_SD2_DATA2__GPIO1_13 1051 -MX53_PAD_SD2_DATA2__KPP_ROW_6 1052 -MX53_PAD_SD2_DATA2__AUDMUX_AUD4_TXD 1053 -MX53_PAD_SD2_DATA2__CSPI_SS1 1054 -MX53_PAD_SD2_DATA2__SJC_FAIL 1055 -MX53_PAD_SD2_DATA1__ESDHC2_DAT1 1056 -MX53_PAD_SD2_DATA1__GPIO1_14 1057 -MX53_PAD_SD2_DATA1__KPP_COL_7 1058 -MX53_PAD_SD2_DATA1__AUDMUX_AUD4_TXFS 1059 -MX53_PAD_SD2_DATA1__CSPI_SS0 1060 -MX53_PAD_SD2_DATA1__RTIC_SEC_VIO 1061 -MX53_PAD_SD2_DATA0__ESDHC2_DAT0 1062 -MX53_PAD_SD2_DATA0__GPIO1_15 1063 -MX53_PAD_SD2_DATA0__KPP_ROW_7 1064 -MX53_PAD_SD2_DATA0__AUDMUX_AUD4_RXD 1065 -MX53_PAD_SD2_DATA0__CSPI_MISO 1066 -MX53_PAD_SD2_DATA0__RTIC_DONE_INT 1067 -MX53_PAD_GPIO_0__CCM_CLKO 1068 -MX53_PAD_GPIO_0__GPIO1_0 1069 -MX53_PAD_GPIO_0__KPP_COL_5 1070 -MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK 1071 -MX53_PAD_GPIO_0__EPIT1_EPITO 1072 -MX53_PAD_GPIO_0__SRTC_ALARM_DEB 1073 -MX53_PAD_GPIO_0__USBOH3_USBH1_PWR 1074 -MX53_PAD_GPIO_0__CSU_TD 1075 -MX53_PAD_GPIO_1__ESAI1_SCKR 1076 -MX53_PAD_GPIO_1__GPIO1_1 1077 -MX53_PAD_GPIO_1__KPP_ROW_5 1078 -MX53_PAD_GPIO_1__CCM_SSI_EXT2_CLK 1079 -MX53_PAD_GPIO_1__PWM2_PWMO 1080 -MX53_PAD_GPIO_1__WDOG2_WDOG_B 1081 -MX53_PAD_GPIO_1__ESDHC1_CD 1082 -MX53_PAD_GPIO_1__SRC_TESTER_ACK 1083 -MX53_PAD_GPIO_9__ESAI1_FSR 1084 -MX53_PAD_GPIO_9__GPIO1_9 1085 -MX53_PAD_GPIO_9__KPP_COL_6 1086 -MX53_PAD_GPIO_9__CCM_REF_EN_B 1087 -MX53_PAD_GPIO_9__PWM1_PWMO 1088 -MX53_PAD_GPIO_9__WDOG1_WDOG_B 1089 -MX53_PAD_GPIO_9__ESDHC1_WP 1090 -MX53_PAD_GPIO_9__SCC_FAIL_STATE 1091 -MX53_PAD_GPIO_3__ESAI1_HCKR 1092 -MX53_PAD_GPIO_3__GPIO1_3 1093 -MX53_PAD_GPIO_3__I2C3_SCL 1094 -MX53_PAD_GPIO_3__DPLLIP1_TOG_EN 1095 -MX53_PAD_GPIO_3__CCM_CLKO2 1096 -MX53_PAD_GPIO_3__OBSERVE_MUX_OBSRV_INT_OUT0 1097 -MX53_PAD_GPIO_3__USBOH3_USBH1_OC 1098 -MX53_PAD_GPIO_3__MLB_MLBCLK 1099 -MX53_PAD_GPIO_6__ESAI1_SCKT 1100 -MX53_PAD_GPIO_6__GPIO1_6 1101 -MX53_PAD_GPIO_6__I2C3_SDA 1102 -MX53_PAD_GPIO_6__CCM_CCM_OUT_0 1103 -MX53_PAD_GPIO_6__CSU_CSU_INT_DEB 1104 -MX53_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 1105 -MX53_PAD_GPIO_6__ESDHC2_LCTL 1106 -MX53_PAD_GPIO_6__MLB_MLBSIG 1107 -MX53_PAD_GPIO_2__ESAI1_FST 1108 -MX53_PAD_GPIO_2__GPIO1_2 1109 -MX53_PAD_GPIO_2__KPP_ROW_6 1110 -MX53_PAD_GPIO_2__CCM_CCM_OUT_1 1111 -MX53_PAD_GPIO_2__CSU_CSU_ALARM_AUT_0 1112 -MX53_PAD_GPIO_2__OBSERVE_MUX_OBSRV_INT_OUT2 1113 -MX53_PAD_GPIO_2__ESDHC2_WP 1114 -MX53_PAD_GPIO_2__MLB_MLBDAT 1115 -MX53_PAD_GPIO_4__ESAI1_HCKT 1116 -MX53_PAD_GPIO_4__GPIO1_4 1117 -MX53_PAD_GPIO_4__KPP_COL_7 1118 -MX53_PAD_GPIO_4__CCM_CCM_OUT_2 1119 -MX53_PAD_GPIO_4__CSU_CSU_ALARM_AUT_1 1120 -MX53_PAD_GPIO_4__OBSERVE_MUX_OBSRV_INT_OUT3 1121 -MX53_PAD_GPIO_4__ESDHC2_CD 1122 -MX53_PAD_GPIO_4__SCC_SEC_STATE 1123 -MX53_PAD_GPIO_5__ESAI1_TX2_RX3 1124 -MX53_PAD_GPIO_5__GPIO1_5 1125 -MX53_PAD_GPIO_5__KPP_ROW_7 1126 -MX53_PAD_GPIO_5__CCM_CLKO 1127 -MX53_PAD_GPIO_5__CSU_CSU_ALARM_AUT_2 1128 -MX53_PAD_GPIO_5__OBSERVE_MUX_OBSRV_INT_OUT4 1129 -MX53_PAD_GPIO_5__I2C3_SCL 1130 -MX53_PAD_GPIO_5__CCM_PLL1_BYP 1131 -MX53_PAD_GPIO_7__ESAI1_TX4_RX1 1132 -MX53_PAD_GPIO_7__GPIO1_7 1133 -MX53_PAD_GPIO_7__EPIT1_EPITO 1134 -MX53_PAD_GPIO_7__CAN1_TXCAN 1135 -MX53_PAD_GPIO_7__UART2_TXD_MUX 1136 -MX53_PAD_GPIO_7__FIRI_RXD 1137 -MX53_PAD_GPIO_7__SPDIF_PLOCK 1138 -MX53_PAD_GPIO_7__CCM_PLL2_BYP 1139 -MX53_PAD_GPIO_8__ESAI1_TX5_RX0 1140 -MX53_PAD_GPIO_8__GPIO1_8 1141 -MX53_PAD_GPIO_8__EPIT2_EPITO 1142 -MX53_PAD_GPIO_8__CAN1_RXCAN 1143 -MX53_PAD_GPIO_8__UART2_RXD_MUX 1144 -MX53_PAD_GPIO_8__FIRI_TXD 1145 -MX53_PAD_GPIO_8__SPDIF_SRCLK 1146 -MX53_PAD_GPIO_8__CCM_PLL3_BYP 1147 -MX53_PAD_GPIO_16__ESAI1_TX3_RX2 1148 -MX53_PAD_GPIO_16__GPIO7_11 1149 -MX53_PAD_GPIO_16__TZIC_PWRFAIL_INT 1150 -MX53_PAD_GPIO_16__RTC_CE_RTC_EXT_TRIG1 1151 -MX53_PAD_GPIO_16__SPDIF_IN1 1152 -MX53_PAD_GPIO_16__I2C3_SDA 1153 -MX53_PAD_GPIO_16__SJC_DE_B 1154 -MX53_PAD_GPIO_17__ESAI1_TX0 1155 -MX53_PAD_GPIO_17__GPIO7_12 1156 -MX53_PAD_GPIO_17__SDMA_EXT_EVENT_0 1157 -MX53_PAD_GPIO_17__GPC_PMIC_RDY 1158 -MX53_PAD_GPIO_17__RTC_CE_RTC_FSV_TRIG 1159 -MX53_PAD_GPIO_17__SPDIF_OUT1 1160 -MX53_PAD_GPIO_17__IPU_SNOOP2 1161 -MX53_PAD_GPIO_17__SJC_JTAG_ACT 1162 -MX53_PAD_GPIO_18__ESAI1_TX1 1163 -MX53_PAD_GPIO_18__GPIO7_13 1164 -MX53_PAD_GPIO_18__SDMA_EXT_EVENT_1 1165 -MX53_PAD_GPIO_18__OWIRE_LINE 1166 -MX53_PAD_GPIO_18__RTC_CE_RTC_ALARM2_TRIG 1167 -MX53_PAD_GPIO_18__CCM_ASRC_EXT_CLK 1168 -MX53_PAD_GPIO_18__ESDHC1_LCTL 1169 -MX53_PAD_GPIO_18__SRC_SYSTEM_RST 1170 diff --git a/trunk/Documentation/devicetree/bindings/pinctrl/fsl,imx6q-pinctrl.txt b/trunk/Documentation/devicetree/bindings/pinctrl/fsl,imx6q-pinctrl.txt deleted file mode 100644 index 82b43f915857..000000000000 --- a/trunk/Documentation/devicetree/bindings/pinctrl/fsl,imx6q-pinctrl.txt +++ /dev/null @@ -1,1628 +0,0 @@ -* Freescale IMX6Q IOMUX Controller - -Please refer to fsl,imx-pinctrl.txt in this directory for common binding part -and usage. - -Required properties: -- compatible: "fsl,imx6q-iomuxc" -- fsl,pins: two integers array, represents a group of pins mux and config - setting. The format is fsl,pins = , PIN_FUNC_ID is a - pin working on a specific function, CONFIG is the pad setting value like - pull-up for this pin. Please refer to imx6q datasheet for the valid pad - config settings. - -CONFIG bits definition: -PAD_CTL_HYS (1 << 16) -PAD_CTL_PUS_100K_DOWN (0 << 14) -PAD_CTL_PUS_47K_UP (1 << 14) -PAD_CTL_PUS_100K_UP (2 << 14) -PAD_CTL_PUS_22K_UP (3 << 14) -PAD_CTL_PUE (1 << 13) -PAD_CTL_PKE (1 << 12) -PAD_CTL_ODE (1 << 11) -PAD_CTL_SPEED_LOW (1 << 6) -PAD_CTL_SPEED_MED (2 << 6) -PAD_CTL_SPEED_HIGH (3 << 6) -PAD_CTL_DSE_DISABLE (0 << 3) -PAD_CTL_DSE_240ohm (1 << 3) -PAD_CTL_DSE_120ohm (2 << 3) -PAD_CTL_DSE_80ohm (3 << 3) -PAD_CTL_DSE_60ohm (4 << 3) -PAD_CTL_DSE_48ohm (5 << 3) -PAD_CTL_DSE_40ohm (6 << 3) -PAD_CTL_DSE_34ohm (7 << 3) -PAD_CTL_SRE_FAST (1 << 0) -PAD_CTL_SRE_SLOW (0 << 0) - -See below for available PIN_FUNC_ID for imx6q: -MX6Q_PAD_SD2_DAT1__USDHC2_DAT1 0 -MX6Q_PAD_SD2_DAT1__ECSPI5_SS0 1 -MX6Q_PAD_SD2_DAT1__WEIM_WEIM_CS_2 2 -MX6Q_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS 3 -MX6Q_PAD_SD2_DAT1__KPP_COL_7 4 -MX6Q_PAD_SD2_DAT1__GPIO_1_14 5 -MX6Q_PAD_SD2_DAT1__CCM_WAIT 6 -MX6Q_PAD_SD2_DAT1__ANATOP_TESTO_0 7 -MX6Q_PAD_SD2_DAT2__USDHC2_DAT2 8 -MX6Q_PAD_SD2_DAT2__ECSPI5_SS1 9 -MX6Q_PAD_SD2_DAT2__WEIM_WEIM_CS_3 10 -MX6Q_PAD_SD2_DAT2__AUDMUX_AUD4_TXD 11 -MX6Q_PAD_SD2_DAT2__KPP_ROW_6 12 -MX6Q_PAD_SD2_DAT2__GPIO_1_13 13 -MX6Q_PAD_SD2_DAT2__CCM_STOP 14 -MX6Q_PAD_SD2_DAT2__ANATOP_TESTO_1 15 -MX6Q_PAD_SD2_DAT0__USDHC2_DAT0 16 -MX6Q_PAD_SD2_DAT0__ECSPI5_MISO 17 -MX6Q_PAD_SD2_DAT0__AUDMUX_AUD4_RXD 18 -MX6Q_PAD_SD2_DAT0__KPP_ROW_7 19 -MX6Q_PAD_SD2_DAT0__GPIO_1_15 20 -MX6Q_PAD_SD2_DAT0__DCIC2_DCIC_OUT 21 -MX6Q_PAD_SD2_DAT0__TESTO_2 22 -MX6Q_PAD_RGMII_TXC__USBOH3_H2_DATA 23 -MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC 24 -MX6Q_PAD_RGMII_TXC__SPDIF_SPDIF_EXTCLK 25 -MX6Q_PAD_RGMII_TXC__GPIO_6_19 26 -MX6Q_PAD_RGMII_TXC__MIPI_CORE_DPHY_IN_0 27 -MX6Q_PAD_RGMII_TXC__ANATOP_24M_OUT 28 -MX6Q_PAD_RGMII_TD0__MIPI_HSI_CRL_TX_RDY 29 -MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0 30 -MX6Q_PAD_RGMII_TD0__GPIO_6_20 31 -MX6Q_PAD_RGMII_TD0__MIPI_CORE_DPHY_IN_1 32 -MX6Q_PAD_RGMII_TD1__MIPI_HSI_CRL_RX_FLG 33 -MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1 34 -MX6Q_PAD_RGMII_TD1__GPIO_6_21 35 -MX6Q_PAD_RGMII_TD1__MIPI_CORE_DPHY_IN_2 36 -MX6Q_PAD_RGMII_TD1__CCM_PLL3_BYP 37 -MX6Q_PAD_RGMII_TD2__MIPI_HSI_CRL_RX_DTA 38 -MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2 39 -MX6Q_PAD_RGMII_TD2__GPIO_6_22 40 -MX6Q_PAD_RGMII_TD2__MIPI_CORE_DPHY_IN_3 41 -MX6Q_PAD_RGMII_TD2__CCM_PLL2_BYP 42 -MX6Q_PAD_RGMII_TD3__MIPI_HSI_CRL_RX_WAK 43 -MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3 44 -MX6Q_PAD_RGMII_TD3__GPIO_6_23 45 -MX6Q_PAD_RGMII_TD3__MIPI_CORE_DPHY_IN_4 46 -MX6Q_PAD_RGMII_RX_CTL__USBOH3_H3_DATA 47 -MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL 48 -MX6Q_PAD_RGMII_RX_CTL__GPIO_6_24 49 -MX6Q_PAD_RGMII_RX_CTL__MIPI_DPHY_IN_5 50 -MX6Q_PAD_RGMII_RD0__MIPI_HSI_CRL_RX_RDY 51 -MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0 52 -MX6Q_PAD_RGMII_RD0__GPIO_6_25 53 -MX6Q_PAD_RGMII_RD0__MIPI_CORE_DPHY_IN_6 54 -MX6Q_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE 55 -MX6Q_PAD_RGMII_TX_CTL__RGMII_TX_CTL 56 -MX6Q_PAD_RGMII_TX_CTL__GPIO_6_26 57 -MX6Q_PAD_RGMII_TX_CTL__CORE_DPHY_IN_7 58 -MX6Q_PAD_RGMII_TX_CTL__ANATOP_REF_OUT 59 -MX6Q_PAD_RGMII_RD1__MIPI_HSI_CTRL_TX_FL 60 -MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1 61 -MX6Q_PAD_RGMII_RD1__GPIO_6_27 62 -MX6Q_PAD_RGMII_RD1__CORE_DPHY_TEST_IN_8 63 -MX6Q_PAD_RGMII_RD1__SJC_FAIL 64 -MX6Q_PAD_RGMII_RD2__MIPI_HSI_CRL_TX_DTA 65 -MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2 66 -MX6Q_PAD_RGMII_RD2__GPIO_6_28 67 -MX6Q_PAD_RGMII_RD2__MIPI_CORE_DPHY_IN_9 68 -MX6Q_PAD_RGMII_RD3__MIPI_HSI_CRL_TX_WAK 69 -MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3 70 -MX6Q_PAD_RGMII_RD3__GPIO_6_29 71 -MX6Q_PAD_RGMII_RD3__MIPI_CORE_DPHY_IN10 72 -MX6Q_PAD_RGMII_RXC__USBOH3_H3_STROBE 73 -MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC 74 -MX6Q_PAD_RGMII_RXC__GPIO_6_30 75 -MX6Q_PAD_RGMII_RXC__MIPI_CORE_DPHY_IN11 76 -MX6Q_PAD_EIM_A25__WEIM_WEIM_A_25 77 -MX6Q_PAD_EIM_A25__ECSPI4_SS1 78 -MX6Q_PAD_EIM_A25__ECSPI2_RDY 79 -MX6Q_PAD_EIM_A25__IPU1_DI1_PIN12 80 -MX6Q_PAD_EIM_A25__IPU1_DI0_D1_CS 81 -MX6Q_PAD_EIM_A25__GPIO_5_2 82 -MX6Q_PAD_EIM_A25__HDMI_TX_CEC_LINE 83 -MX6Q_PAD_EIM_A25__PL301_PER1_HBURST_0 84 -MX6Q_PAD_EIM_EB2__WEIM_WEIM_EB_2 85 -MX6Q_PAD_EIM_EB2__ECSPI1_SS0 86 -MX6Q_PAD_EIM_EB2__CCM_DI1_EXT_CLK 87 -MX6Q_PAD_EIM_EB2__IPU2_CSI1_D_19 88 -MX6Q_PAD_EIM_EB2__HDMI_TX_DDC_SCL 89 -MX6Q_PAD_EIM_EB2__GPIO_2_30 90 -MX6Q_PAD_EIM_EB2__I2C2_SCL 91 -MX6Q_PAD_EIM_EB2__SRC_BT_CFG_30 92 -MX6Q_PAD_EIM_D16__WEIM_WEIM_D_16 93 -MX6Q_PAD_EIM_D16__ECSPI1_SCLK 94 -MX6Q_PAD_EIM_D16__IPU1_DI0_PIN5 95 -MX6Q_PAD_EIM_D16__IPU2_CSI1_D_18 96 -MX6Q_PAD_EIM_D16__HDMI_TX_DDC_SDA 97 -MX6Q_PAD_EIM_D16__GPIO_3_16 98 -MX6Q_PAD_EIM_D16__I2C2_SDA 99 -MX6Q_PAD_EIM_D17__WEIM_WEIM_D_17 100 -MX6Q_PAD_EIM_D17__ECSPI1_MISO 101 -MX6Q_PAD_EIM_D17__IPU1_DI0_PIN6 102 -MX6Q_PAD_EIM_D17__IPU2_CSI1_PIXCLK 103 -MX6Q_PAD_EIM_D17__DCIC1_DCIC_OUT 104 -MX6Q_PAD_EIM_D17__GPIO_3_17 105 -MX6Q_PAD_EIM_D17__I2C3_SCL 106 -MX6Q_PAD_EIM_D17__PL301_PER1_HBURST_1 107 -MX6Q_PAD_EIM_D18__WEIM_WEIM_D_18 108 -MX6Q_PAD_EIM_D18__ECSPI1_MOSI 109 -MX6Q_PAD_EIM_D18__IPU1_DI0_PIN7 110 -MX6Q_PAD_EIM_D18__IPU2_CSI1_D_17 111 -MX6Q_PAD_EIM_D18__IPU1_DI1_D0_CS 112 -MX6Q_PAD_EIM_D18__GPIO_3_18 113 -MX6Q_PAD_EIM_D18__I2C3_SDA 114 -MX6Q_PAD_EIM_D18__PL301_PER1_HBURST_2 115 -MX6Q_PAD_EIM_D19__WEIM_WEIM_D_19 116 -MX6Q_PAD_EIM_D19__ECSPI1_SS1 117 -MX6Q_PAD_EIM_D19__IPU1_DI0_PIN8 118 -MX6Q_PAD_EIM_D19__IPU2_CSI1_D_16 119 -MX6Q_PAD_EIM_D19__UART1_CTS 120 -MX6Q_PAD_EIM_D19__GPIO_3_19 121 -MX6Q_PAD_EIM_D19__EPIT1_EPITO 122 -MX6Q_PAD_EIM_D19__PL301_PER1_HRESP 123 -MX6Q_PAD_EIM_D20__WEIM_WEIM_D_20 124 -MX6Q_PAD_EIM_D20__ECSPI4_SS0 125 -MX6Q_PAD_EIM_D20__IPU1_DI0_PIN16 126 -MX6Q_PAD_EIM_D20__IPU2_CSI1_D_15 127 -MX6Q_PAD_EIM_D20__UART1_RTS 128 -MX6Q_PAD_EIM_D20__GPIO_3_20 129 -MX6Q_PAD_EIM_D20__EPIT2_EPITO 130 -MX6Q_PAD_EIM_D21__WEIM_WEIM_D_21 131 -MX6Q_PAD_EIM_D21__ECSPI4_SCLK 132 -MX6Q_PAD_EIM_D21__IPU1_DI0_PIN17 133 -MX6Q_PAD_EIM_D21__IPU2_CSI1_D_11 134 -MX6Q_PAD_EIM_D21__USBOH3_USBOTG_OC 135 -MX6Q_PAD_EIM_D21__GPIO_3_21 136 -MX6Q_PAD_EIM_D21__I2C1_SCL 137 -MX6Q_PAD_EIM_D21__SPDIF_IN1 138 -MX6Q_PAD_EIM_D22__WEIM_WEIM_D_22 139 -MX6Q_PAD_EIM_D22__ECSPI4_MISO 140 -MX6Q_PAD_EIM_D22__IPU1_DI0_PIN1 141 -MX6Q_PAD_EIM_D22__IPU2_CSI1_D_10 142 -MX6Q_PAD_EIM_D22__USBOH3_USBOTG_PWR 143 -MX6Q_PAD_EIM_D22__GPIO_3_22 144 -MX6Q_PAD_EIM_D22__SPDIF_OUT1 145 -MX6Q_PAD_EIM_D22__PL301_PER1_HWRITE 146 -MX6Q_PAD_EIM_D23__WEIM_WEIM_D_23 147 -MX6Q_PAD_EIM_D23__IPU1_DI0_D0_CS 148 -MX6Q_PAD_EIM_D23__UART3_CTS 149 -MX6Q_PAD_EIM_D23__UART1_DCD 150 -MX6Q_PAD_EIM_D23__IPU2_CSI1_DATA_EN 151 -MX6Q_PAD_EIM_D23__GPIO_3_23 152 -MX6Q_PAD_EIM_D23__IPU1_DI1_PIN2 153 -MX6Q_PAD_EIM_D23__IPU1_DI1_PIN14 154 -MX6Q_PAD_EIM_EB3__WEIM_WEIM_EB_3 155 -MX6Q_PAD_EIM_EB3__ECSPI4_RDY 156 -MX6Q_PAD_EIM_EB3__UART3_RTS 157 -MX6Q_PAD_EIM_EB3__UART1_RI 158 -MX6Q_PAD_EIM_EB3__IPU2_CSI1_HSYNC 159 -MX6Q_PAD_EIM_EB3__GPIO_2_31 160 -MX6Q_PAD_EIM_EB3__IPU1_DI1_PIN3 161 -MX6Q_PAD_EIM_EB3__SRC_BT_CFG_31 162 -MX6Q_PAD_EIM_D24__WEIM_WEIM_D_24 163 -MX6Q_PAD_EIM_D24__ECSPI4_SS2 164 -MX6Q_PAD_EIM_D24__UART3_TXD 165 -MX6Q_PAD_EIM_D24__ECSPI1_SS2 166 -MX6Q_PAD_EIM_D24__ECSPI2_SS2 167 -MX6Q_PAD_EIM_D24__GPIO_3_24 168 -MX6Q_PAD_EIM_D24__AUDMUX_AUD5_RXFS 169 -MX6Q_PAD_EIM_D24__UART1_DTR 170 -MX6Q_PAD_EIM_D25__WEIM_WEIM_D_25 171 -MX6Q_PAD_EIM_D25__ECSPI4_SS3 172 -MX6Q_PAD_EIM_D25__UART3_RXD 173 -MX6Q_PAD_EIM_D25__ECSPI1_SS3 174 -MX6Q_PAD_EIM_D25__ECSPI2_SS3 175 -MX6Q_PAD_EIM_D25__GPIO_3_25 176 -MX6Q_PAD_EIM_D25__AUDMUX_AUD5_RXC 177 -MX6Q_PAD_EIM_D25__UART1_DSR 178 -MX6Q_PAD_EIM_D26__WEIM_WEIM_D_26 179 -MX6Q_PAD_EIM_D26__IPU1_DI1_PIN11 180 -MX6Q_PAD_EIM_D26__IPU1_CSI0_D_1 181 -MX6Q_PAD_EIM_D26__IPU2_CSI1_D_14 182 -MX6Q_PAD_EIM_D26__UART2_TXD 183 -MX6Q_PAD_EIM_D26__GPIO_3_26 184 -MX6Q_PAD_EIM_D26__IPU1_SISG_2 185 -MX6Q_PAD_EIM_D26__IPU1_DISP1_DAT_22 186 -MX6Q_PAD_EIM_D27__WEIM_WEIM_D_27 187 -MX6Q_PAD_EIM_D27__IPU1_DI1_PIN13 188 -MX6Q_PAD_EIM_D27__IPU1_CSI0_D_0 189 -MX6Q_PAD_EIM_D27__IPU2_CSI1_D_13 190 -MX6Q_PAD_EIM_D27__UART2_RXD 191 -MX6Q_PAD_EIM_D27__GPIO_3_27 192 -MX6Q_PAD_EIM_D27__IPU1_SISG_3 193 -MX6Q_PAD_EIM_D27__IPU1_DISP1_DAT_23 194 -MX6Q_PAD_EIM_D28__WEIM_WEIM_D_28 195 -MX6Q_PAD_EIM_D28__I2C1_SDA 196 -MX6Q_PAD_EIM_D28__ECSPI4_MOSI 197 -MX6Q_PAD_EIM_D28__IPU2_CSI1_D_12 198 -MX6Q_PAD_EIM_D28__UART2_CTS 199 -MX6Q_PAD_EIM_D28__GPIO_3_28 200 -MX6Q_PAD_EIM_D28__IPU1_EXT_TRIG 201 -MX6Q_PAD_EIM_D28__IPU1_DI0_PIN13 202 -MX6Q_PAD_EIM_D29__WEIM_WEIM_D_29 203 -MX6Q_PAD_EIM_D29__IPU1_DI1_PIN15 204 -MX6Q_PAD_EIM_D29__ECSPI4_SS0 205 -MX6Q_PAD_EIM_D29__UART2_RTS 206 -MX6Q_PAD_EIM_D29__GPIO_3_29 207 -MX6Q_PAD_EIM_D29__IPU2_CSI1_VSYNC 208 -MX6Q_PAD_EIM_D29__IPU1_DI0_PIN14 209 -MX6Q_PAD_EIM_D30__WEIM_WEIM_D_30 210 -MX6Q_PAD_EIM_D30__IPU1_DISP1_DAT_21 211 -MX6Q_PAD_EIM_D30__IPU1_DI0_PIN11 212 -MX6Q_PAD_EIM_D30__IPU1_CSI0_D_3 213 -MX6Q_PAD_EIM_D30__UART3_CTS 214 -MX6Q_PAD_EIM_D30__GPIO_3_30 215 -MX6Q_PAD_EIM_D30__USBOH3_USBH1_OC 216 -MX6Q_PAD_EIM_D30__PL301_PER1_HPROT_0 217 -MX6Q_PAD_EIM_D31__WEIM_WEIM_D_31 218 -MX6Q_PAD_EIM_D31__IPU1_DISP1_DAT_20 219 -MX6Q_PAD_EIM_D31__IPU1_DI0_PIN12 220 -MX6Q_PAD_EIM_D31__IPU1_CSI0_D_2 221 -MX6Q_PAD_EIM_D31__UART3_RTS 222 -MX6Q_PAD_EIM_D31__GPIO_3_31 223 -MX6Q_PAD_EIM_D31__USBOH3_USBH1_PWR 224 -MX6Q_PAD_EIM_D31__PL301_PER1_HPROT_1 225 -MX6Q_PAD_EIM_A24__WEIM_WEIM_A_24 226 -MX6Q_PAD_EIM_A24__IPU1_DISP1_DAT_19 227 -MX6Q_PAD_EIM_A24__IPU2_CSI1_D_19 228 -MX6Q_PAD_EIM_A24__IPU2_SISG_2 229 -MX6Q_PAD_EIM_A24__IPU1_SISG_2 230 -MX6Q_PAD_EIM_A24__GPIO_5_4 231 -MX6Q_PAD_EIM_A24__PL301_PER1_HPROT_2 232 -MX6Q_PAD_EIM_A24__SRC_BT_CFG_24 233 -MX6Q_PAD_EIM_A23__WEIM_WEIM_A_23 234 -MX6Q_PAD_EIM_A23__IPU1_DISP1_DAT_18 235 -MX6Q_PAD_EIM_A23__IPU2_CSI1_D_18 236 -MX6Q_PAD_EIM_A23__IPU2_SISG_3 237 -MX6Q_PAD_EIM_A23__IPU1_SISG_3 238 -MX6Q_PAD_EIM_A23__GPIO_6_6 239 -MX6Q_PAD_EIM_A23__PL301_PER1_HPROT_3 240 -MX6Q_PAD_EIM_A23__SRC_BT_CFG_23 241 -MX6Q_PAD_EIM_A22__WEIM_WEIM_A_22 242 -MX6Q_PAD_EIM_A22__IPU1_DISP1_DAT_17 243 -MX6Q_PAD_EIM_A22__IPU2_CSI1_D_17 244 -MX6Q_PAD_EIM_A22__GPIO_2_16 245 -MX6Q_PAD_EIM_A22__TPSMP_HDATA_0 246 -MX6Q_PAD_EIM_A22__SRC_BT_CFG_22 247 -MX6Q_PAD_EIM_A21__WEIM_WEIM_A_21 248 -MX6Q_PAD_EIM_A21__IPU1_DISP1_DAT_16 249 -MX6Q_PAD_EIM_A21__IPU2_CSI1_D_16 250 -MX6Q_PAD_EIM_A21__RESERVED_RESERVED 251 -MX6Q_PAD_EIM_A21__MIPI_CORE_DPHY_OUT_18 252 -MX6Q_PAD_EIM_A21__GPIO_2_17 253 -MX6Q_PAD_EIM_A21__TPSMP_HDATA_1 254 -MX6Q_PAD_EIM_A21__SRC_BT_CFG_21 255 -MX6Q_PAD_EIM_A20__WEIM_WEIM_A_20 256 -MX6Q_PAD_EIM_A20__IPU1_DISP1_DAT_15 257 -MX6Q_PAD_EIM_A20__IPU2_CSI1_D_15 258 -MX6Q_PAD_EIM_A20__RESERVED_RESERVED 259 -MX6Q_PAD_EIM_A20__MIPI_CORE_DPHY_OUT_19 260 -MX6Q_PAD_EIM_A20__GPIO_2_18 261 -MX6Q_PAD_EIM_A20__TPSMP_HDATA_2 262 -MX6Q_PAD_EIM_A20__SRC_BT_CFG_20 263 -MX6Q_PAD_EIM_A19__WEIM_WEIM_A_19 264 -MX6Q_PAD_EIM_A19__IPU1_DISP1_DAT_14 265 -MX6Q_PAD_EIM_A19__IPU2_CSI1_D_14 266 -MX6Q_PAD_EIM_A19__RESERVED_RESERVED 267 -MX6Q_PAD_EIM_A19__MIPI_CORE_DPHY_OUT_20 268 -MX6Q_PAD_EIM_A19__GPIO_2_19 269 -MX6Q_PAD_EIM_A19__TPSMP_HDATA_3 270 -MX6Q_PAD_EIM_A19__SRC_BT_CFG_19 271 -MX6Q_PAD_EIM_A18__WEIM_WEIM_A_18 272 -MX6Q_PAD_EIM_A18__IPU1_DISP1_DAT_13 273 -MX6Q_PAD_EIM_A18__IPU2_CSI1_D_13 274 -MX6Q_PAD_EIM_A18__RESERVED_RESERVED 275 -MX6Q_PAD_EIM_A18__MIPI_CORE_DPHY_OUT_21 276 -MX6Q_PAD_EIM_A18__GPIO_2_20 277 -MX6Q_PAD_EIM_A18__TPSMP_HDATA_4 278 -MX6Q_PAD_EIM_A18__SRC_BT_CFG_18 279 -MX6Q_PAD_EIM_A17__WEIM_WEIM_A_17 280 -MX6Q_PAD_EIM_A17__IPU1_DISP1_DAT_12 281 -MX6Q_PAD_EIM_A17__IPU2_CSI1_D_12 282 -MX6Q_PAD_EIM_A17__RESERVED_RESERVED 283 -MX6Q_PAD_EIM_A17__MIPI_CORE_DPHY_OUT_22 284 -MX6Q_PAD_EIM_A17__GPIO_2_21 285 -MX6Q_PAD_EIM_A17__TPSMP_HDATA_5 286 -MX6Q_PAD_EIM_A17__SRC_BT_CFG_17 287 -MX6Q_PAD_EIM_A16__WEIM_WEIM_A_16 288 -MX6Q_PAD_EIM_A16__IPU1_DI1_DISP_CLK 289 -MX6Q_PAD_EIM_A16__IPU2_CSI1_PIXCLK 290 -MX6Q_PAD_EIM_A16__MIPI_CORE_DPHY_OUT_23 291 -MX6Q_PAD_EIM_A16__GPIO_2_22 292 -MX6Q_PAD_EIM_A16__TPSMP_HDATA_6 293 -MX6Q_PAD_EIM_A16__SRC_BT_CFG_16 294 -MX6Q_PAD_EIM_CS0__WEIM_WEIM_CS_0 295 -MX6Q_PAD_EIM_CS0__IPU1_DI1_PIN5 296 -MX6Q_PAD_EIM_CS0__ECSPI2_SCLK 297 -MX6Q_PAD_EIM_CS0__MIPI_CORE_DPHY_OUT_24 298 -MX6Q_PAD_EIM_CS0__GPIO_2_23 299 -MX6Q_PAD_EIM_CS0__TPSMP_HDATA_7 300 -MX6Q_PAD_EIM_CS1__WEIM_WEIM_CS_1 301 -MX6Q_PAD_EIM_CS1__IPU1_DI1_PIN6 302 -MX6Q_PAD_EIM_CS1__ECSPI2_MOSI 303 -MX6Q_PAD_EIM_CS1__MIPI_CORE_DPHY_OUT_25 304 -MX6Q_PAD_EIM_CS1__GPIO_2_24 305 -MX6Q_PAD_EIM_CS1__TPSMP_HDATA_8 306 -MX6Q_PAD_EIM_OE__WEIM_WEIM_OE 307 -MX6Q_PAD_EIM_OE__IPU1_DI1_PIN7 308 -MX6Q_PAD_EIM_OE__ECSPI2_MISO 309 -MX6Q_PAD_EIM_OE__MIPI_CORE_DPHY_OUT_26 310 -MX6Q_PAD_EIM_OE__GPIO_2_25 311 -MX6Q_PAD_EIM_OE__TPSMP_HDATA_9 312 -MX6Q_PAD_EIM_RW__WEIM_WEIM_RW 313 -MX6Q_PAD_EIM_RW__IPU1_DI1_PIN8 314 -MX6Q_PAD_EIM_RW__ECSPI2_SS0 315 -MX6Q_PAD_EIM_RW__MIPI_CORE_DPHY_OUT_27 316 -MX6Q_PAD_EIM_RW__GPIO_2_26 317 -MX6Q_PAD_EIM_RW__TPSMP_HDATA_10 318 -MX6Q_PAD_EIM_RW__SRC_BT_CFG_29 319 -MX6Q_PAD_EIM_LBA__WEIM_WEIM_LBA 320 -MX6Q_PAD_EIM_LBA__IPU1_DI1_PIN17 321 -MX6Q_PAD_EIM_LBA__ECSPI2_SS1 322 -MX6Q_PAD_EIM_LBA__GPIO_2_27 323 -MX6Q_PAD_EIM_LBA__TPSMP_HDATA_11 324 -MX6Q_PAD_EIM_LBA__SRC_BT_CFG_26 325 -MX6Q_PAD_EIM_EB0__WEIM_WEIM_EB_0 326 -MX6Q_PAD_EIM_EB0__IPU1_DISP1_DAT_11 327 -MX6Q_PAD_EIM_EB0__IPU2_CSI1_D_11 328 -MX6Q_PAD_EIM_EB0__MIPI_CORE_DPHY_OUT_0 329 -MX6Q_PAD_EIM_EB0__CCM_PMIC_RDY 330 -MX6Q_PAD_EIM_EB0__GPIO_2_28 331 -MX6Q_PAD_EIM_EB0__TPSMP_HDATA_12 332 -MX6Q_PAD_EIM_EB0__SRC_BT_CFG_27 333 -MX6Q_PAD_EIM_EB1__WEIM_WEIM_EB_1 334 -MX6Q_PAD_EIM_EB1__IPU1_DISP1_DAT_10 335 -MX6Q_PAD_EIM_EB1__IPU2_CSI1_D_10 336 -MX6Q_PAD_EIM_EB1__MIPI_CORE_DPHY__OUT_1 337 -MX6Q_PAD_EIM_EB1__GPIO_2_29 338 -MX6Q_PAD_EIM_EB1__TPSMP_HDATA_13 339 -MX6Q_PAD_EIM_EB1__SRC_BT_CFG_28 340 -MX6Q_PAD_EIM_DA0__WEIM_WEIM_DA_A_0 341 -MX6Q_PAD_EIM_DA0__IPU1_DISP1_DAT_9 342 -MX6Q_PAD_EIM_DA0__IPU2_CSI1_D_9 343 -MX6Q_PAD_EIM_DA0__MIPI_CORE_DPHY__OUT_2 344 -MX6Q_PAD_EIM_DA0__GPIO_3_0 345 -MX6Q_PAD_EIM_DA0__TPSMP_HDATA_14 346 -MX6Q_PAD_EIM_DA0__SRC_BT_CFG_0 347 -MX6Q_PAD_EIM_DA1__WEIM_WEIM_DA_A_1 348 -MX6Q_PAD_EIM_DA1__IPU1_DISP1_DAT_8 349 -MX6Q_PAD_EIM_DA1__IPU2_CSI1_D_8 350 -MX6Q_PAD_EIM_DA1__MIPI_CORE_DPHY_OUT_3 351 -MX6Q_PAD_EIM_DA1__USBPHY1_TX_LS_MODE 352 -MX6Q_PAD_EIM_DA1__GPIO_3_1 353 -MX6Q_PAD_EIM_DA1__TPSMP_HDATA_15 354 -MX6Q_PAD_EIM_DA1__SRC_BT_CFG_1 355 -MX6Q_PAD_EIM_DA2__WEIM_WEIM_DA_A_2 356 -MX6Q_PAD_EIM_DA2__IPU1_DISP1_DAT_7 357 -MX6Q_PAD_EIM_DA2__IPU2_CSI1_D_7 358 -MX6Q_PAD_EIM_DA2__MIPI_CORE_DPHY_OUT_4 359 -MX6Q_PAD_EIM_DA2__USBPHY1_TX_HS_MODE 360 -MX6Q_PAD_EIM_DA2__GPIO_3_2 361 -MX6Q_PAD_EIM_DA2__TPSMP_HDATA_16 362 -MX6Q_PAD_EIM_DA2__SRC_BT_CFG_2 363 -MX6Q_PAD_EIM_DA3__WEIM_WEIM_DA_A_3 364 -MX6Q_PAD_EIM_DA3__IPU1_DISP1_DAT_6 365 -MX6Q_PAD_EIM_DA3__IPU2_CSI1_D_6 366 -MX6Q_PAD_EIM_DA3__MIPI_CORE_DPHY_OUT_5 367 -MX6Q_PAD_EIM_DA3__USBPHY1_TX_HIZ 368 -MX6Q_PAD_EIM_DA3__GPIO_3_3 369 -MX6Q_PAD_EIM_DA3__TPSMP_HDATA_17 370 -MX6Q_PAD_EIM_DA3__SRC_BT_CFG_3 371 -MX6Q_PAD_EIM_DA4__WEIM_WEIM_DA_A_4 372 -MX6Q_PAD_EIM_DA4__IPU1_DISP1_DAT_5 373 -MX6Q_PAD_EIM_DA4__IPU2_CSI1_D_5 374 -MX6Q_PAD_EIM_DA4__MIPI_CORE_DPHY_OUT_6 375 -MX6Q_PAD_EIM_DA4__ANATOP_USBPHY1_TX_EN 376 -MX6Q_PAD_EIM_DA4__GPIO_3_4 377 -MX6Q_PAD_EIM_DA4__TPSMP_HDATA_18 378 -MX6Q_PAD_EIM_DA4__SRC_BT_CFG_4 379 -MX6Q_PAD_EIM_DA5__WEIM_WEIM_DA_A_5 380 -MX6Q_PAD_EIM_DA5__IPU1_DISP1_DAT_4 381 -MX6Q_PAD_EIM_DA5__IPU2_CSI1_D_4 382 -MX6Q_PAD_EIM_DA5__MIPI_CORE_DPHY_OUT_7 383 -MX6Q_PAD_EIM_DA5__ANATOP_USBPHY1_TX_DP 384 -MX6Q_PAD_EIM_DA5__GPIO_3_5 385 -MX6Q_PAD_EIM_DA5__TPSMP_HDATA_19 386 -MX6Q_PAD_EIM_DA5__SRC_BT_CFG_5 387 -MX6Q_PAD_EIM_DA6__WEIM_WEIM_DA_A_6 388 -MX6Q_PAD_EIM_DA6__IPU1_DISP1_DAT_3 389 -MX6Q_PAD_EIM_DA6__IPU2_CSI1_D_3 390 -MX6Q_PAD_EIM_DA6__MIPI_CORE_DPHY_OUT_8 391 -MX6Q_PAD_EIM_DA6__ANATOP_USBPHY1_TX_DN 392 -MX6Q_PAD_EIM_DA6__GPIO_3_6 393 -MX6Q_PAD_EIM_DA6__TPSMP_HDATA_20 394 -MX6Q_PAD_EIM_DA6__SRC_BT_CFG_6 395 -MX6Q_PAD_EIM_DA7__WEIM_WEIM_DA_A_7 396 -MX6Q_PAD_EIM_DA7__IPU1_DISP1_DAT_2 397 -MX6Q_PAD_EIM_DA7__IPU2_CSI1_D_2 398 -MX6Q_PAD_EIM_DA7__MIPI_CORE_DPHY_OUT_9 399 -MX6Q_PAD_EIM_DA7__GPIO_3_7 400 -MX6Q_PAD_EIM_DA7__TPSMP_HDATA_21 401 -MX6Q_PAD_EIM_DA7__SRC_BT_CFG_7 402 -MX6Q_PAD_EIM_DA8__WEIM_WEIM_DA_A_8 403 -MX6Q_PAD_EIM_DA8__IPU1_DISP1_DAT_1 404 -MX6Q_PAD_EIM_DA8__IPU2_CSI1_D_1 405 -MX6Q_PAD_EIM_DA8__MIPI_CORE_DPHY_OUT_10 406 -MX6Q_PAD_EIM_DA8__GPIO_3_8 407 -MX6Q_PAD_EIM_DA8__TPSMP_HDATA_22 408 -MX6Q_PAD_EIM_DA8__SRC_BT_CFG_8 409 -MX6Q_PAD_EIM_DA9__WEIM_WEIM_DA_A_9 410 -MX6Q_PAD_EIM_DA9__IPU1_DISP1_DAT_0 411 -MX6Q_PAD_EIM_DA9__IPU2_CSI1_D_0 412 -MX6Q_PAD_EIM_DA9__MIPI_CORE_DPHY_OUT_11 413 -MX6Q_PAD_EIM_DA9__GPIO_3_9 414 -MX6Q_PAD_EIM_DA9__TPSMP_HDATA_23 415 -MX6Q_PAD_EIM_DA9__SRC_BT_CFG_9 416 -MX6Q_PAD_EIM_DA10__WEIM_WEIM_DA_A_10 417 -MX6Q_PAD_EIM_DA10__IPU1_DI1_PIN15 418 -MX6Q_PAD_EIM_DA10__IPU2_CSI1_DATA_EN 419 -MX6Q_PAD_EIM_DA10__MIPI_CORE_DPHY_OUT12 420 -MX6Q_PAD_EIM_DA10__GPIO_3_10 421 -MX6Q_PAD_EIM_DA10__TPSMP_HDATA_24 422 -MX6Q_PAD_EIM_DA10__SRC_BT_CFG_10 423 -MX6Q_PAD_EIM_DA11__WEIM_WEIM_DA_A_11 424 -MX6Q_PAD_EIM_DA11__IPU1_DI1_PIN2 425 -MX6Q_PAD_EIM_DA11__IPU2_CSI1_HSYNC 426 -MX6Q_PAD_EIM_DA11__MIPI_CORE_DPHY_OUT13 427 -MX6Q_PAD_EIM_DA11__SDMA_DBG_EVT_CHN_6 428 -MX6Q_PAD_EIM_DA11__GPIO_3_11 429 -MX6Q_PAD_EIM_DA11__TPSMP_HDATA_25 430 -MX6Q_PAD_EIM_DA11__SRC_BT_CFG_11 431 -MX6Q_PAD_EIM_DA12__WEIM_WEIM_DA_A_12 432 -MX6Q_PAD_EIM_DA12__IPU1_DI1_PIN3 433 -MX6Q_PAD_EIM_DA12__IPU2_CSI1_VSYNC 434 -MX6Q_PAD_EIM_DA12__MIPI_CORE_DPHY_OUT14 435 -MX6Q_PAD_EIM_DA12__SDMA_DEBUG_EVT_CHN_3 436 -MX6Q_PAD_EIM_DA12__GPIO_3_12 437 -MX6Q_PAD_EIM_DA12__TPSMP_HDATA_26 438 -MX6Q_PAD_EIM_DA12__SRC_BT_CFG_12 439 -MX6Q_PAD_EIM_DA13__WEIM_WEIM_DA_A_13 440 -MX6Q_PAD_EIM_DA13__IPU1_DI1_D0_CS 441 -MX6Q_PAD_EIM_DA13__CCM_DI1_EXT_CLK 442 -MX6Q_PAD_EIM_DA13__MIPI_CORE_DPHY_OUT15 443 -MX6Q_PAD_EIM_DA13__SDMA_DEBUG_EVT_CHN_4 444 -MX6Q_PAD_EIM_DA13__GPIO_3_13 445 -MX6Q_PAD_EIM_DA13__TPSMP_HDATA_27 446 -MX6Q_PAD_EIM_DA13__SRC_BT_CFG_13 447 -MX6Q_PAD_EIM_DA14__WEIM_WEIM_DA_A_14 448 -MX6Q_PAD_EIM_DA14__IPU1_DI1_D1_CS 449 -MX6Q_PAD_EIM_DA14__CCM_DI0_EXT_CLK 450 -MX6Q_PAD_EIM_DA14__MIPI_CORE_DPHY_OUT16 451 -MX6Q_PAD_EIM_DA14__SDMA_DEBUG_EVT_CHN_5 452 -MX6Q_PAD_EIM_DA14__GPIO_3_14 453 -MX6Q_PAD_EIM_DA14__TPSMP_HDATA_28 454 -MX6Q_PAD_EIM_DA14__SRC_BT_CFG_14 455 -MX6Q_PAD_EIM_DA15__WEIM_WEIM_DA_A_15 456 -MX6Q_PAD_EIM_DA15__IPU1_DI1_PIN1 457 -MX6Q_PAD_EIM_DA15__IPU1_DI1_PIN4 458 -MX6Q_PAD_EIM_DA15__MIPI_CORE_DPHY_OUT17 459 -MX6Q_PAD_EIM_DA15__GPIO_3_15 460 -MX6Q_PAD_EIM_DA15__TPSMP_HDATA_29 461 -MX6Q_PAD_EIM_DA15__SRC_BT_CFG_15 462 -MX6Q_PAD_EIM_WAIT__WEIM_WEIM_WAIT 463 -MX6Q_PAD_EIM_WAIT__WEIM_WEIM_DTACK_B 464 -MX6Q_PAD_EIM_WAIT__GPIO_5_0 465 -MX6Q_PAD_EIM_WAIT__TPSMP_HDATA_30 466 -MX6Q_PAD_EIM_WAIT__SRC_BT_CFG_25 467 -MX6Q_PAD_EIM_BCLK__WEIM_WEIM_BCLK 468 -MX6Q_PAD_EIM_BCLK__IPU1_DI1_PIN16 469 -MX6Q_PAD_EIM_BCLK__GPIO_6_31 470 -MX6Q_PAD_EIM_BCLK__TPSMP_HDATA_31 471 -MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DSP_CLK 472 -MX6Q_PAD_DI0_DISP_CLK__IPU2_DI0_DSP_CLK 473 -MX6Q_PAD_DI0_DISP_CLK__MIPI_CR_DPY_OT28 474 -MX6Q_PAD_DI0_DISP_CLK__SDMA_DBG_CR_STA0 475 -MX6Q_PAD_DI0_DISP_CLK__GPIO_4_16 476 -MX6Q_PAD_DI0_DISP_CLK__MMDC_DEBUG_0 477 -MX6Q_PAD_DI0_PIN15__IPU1_DI0_PIN15 478 -MX6Q_PAD_DI0_PIN15__IPU2_DI0_PIN15 479 -MX6Q_PAD_DI0_PIN15__AUDMUX_AUD6_TXC 480 -MX6Q_PAD_DI0_PIN15__MIPI_CR_DPHY_OUT_29 481 -MX6Q_PAD_DI0_PIN15__SDMA_DBG_CORE_STA_1 482 -MX6Q_PAD_DI0_PIN15__GPIO_4_17 483 -MX6Q_PAD_DI0_PIN15__MMDC_MMDC_DEBUG_1 484 -MX6Q_PAD_DI0_PIN2__IPU1_DI0_PIN2 485 -MX6Q_PAD_DI0_PIN2__IPU2_DI0_PIN2 486 -MX6Q_PAD_DI0_PIN2__AUDMUX_AUD6_TXD 487 -MX6Q_PAD_DI0_PIN2__MIPI_CR_DPHY_OUT_30 488 -MX6Q_PAD_DI0_PIN2__SDMA_DBG_CORE_STA_2 489 -MX6Q_PAD_DI0_PIN2__GPIO_4_18 490 -MX6Q_PAD_DI0_PIN2__MMDC_DEBUG_2 491 -MX6Q_PAD_DI0_PIN2__PL301_PER1_HADDR_9 492 -MX6Q_PAD_DI0_PIN3__IPU1_DI0_PIN3 493 -MX6Q_PAD_DI0_PIN3__IPU2_DI0_PIN3 494 -MX6Q_PAD_DI0_PIN3__AUDMUX_AUD6_TXFS 495 -MX6Q_PAD_DI0_PIN3__MIPI_CORE_DPHY_OUT31 496 -MX6Q_PAD_DI0_PIN3__SDMA_DBG_CORE_STA_3 497 -MX6Q_PAD_DI0_PIN3__GPIO_4_19 498 -MX6Q_PAD_DI0_PIN3__MMDC_MMDC_DEBUG_3 499 -MX6Q_PAD_DI0_PIN3__PL301_PER1_HADDR_10 500 -MX6Q_PAD_DI0_PIN4__IPU1_DI0_PIN4 501 -MX6Q_PAD_DI0_PIN4__IPU2_DI0_PIN4 502 -MX6Q_PAD_DI0_PIN4__AUDMUX_AUD6_RXD 503 -MX6Q_PAD_DI0_PIN4__USDHC1_WP 504 -MX6Q_PAD_DI0_PIN4__SDMA_DEBUG_YIELD 505 -MX6Q_PAD_DI0_PIN4__GPIO_4_20 506 -MX6Q_PAD_DI0_PIN4__MMDC_MMDC_DEBUG_4 507 -MX6Q_PAD_DI0_PIN4__PL301_PER1_HADDR_11 508 -MX6Q_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0 509 -MX6Q_PAD_DISP0_DAT0__IPU2_DISP0_DAT_0 510 -MX6Q_PAD_DISP0_DAT0__ECSPI3_SCLK 511 -MX6Q_PAD_DISP0_DAT0__USDHC1_USDHC_DBG_0 512 -MX6Q_PAD_DISP0_DAT0__SDMA_DBG_CORE_RUN 513 -MX6Q_PAD_DISP0_DAT0__GPIO_4_21 514 -MX6Q_PAD_DISP0_DAT0__MMDC_MMDC_DEBUG_5 515 -MX6Q_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1 516 -MX6Q_PAD_DISP0_DAT1__IPU2_DISP0_DAT_1 517 -MX6Q_PAD_DISP0_DAT1__ECSPI3_MOSI 518 -MX6Q_PAD_DISP0_DAT1__USDHC1_USDHC_DBG_1 519 -MX6Q_PAD_DISP0_DAT1__SDMA_DBG_EVT_CHNSL 520 -MX6Q_PAD_DISP0_DAT1__GPIO_4_22 521 -MX6Q_PAD_DISP0_DAT1__MMDC_DEBUG_6 522 -MX6Q_PAD_DISP0_DAT1__PL301_PER1_HADR_12 523 -MX6Q_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2 524 -MX6Q_PAD_DISP0_DAT2__IPU2_DISP0_DAT_2 525 -MX6Q_PAD_DISP0_DAT2__ECSPI3_MISO 526 -MX6Q_PAD_DISP0_DAT2__USDHC1_USDHC_DBG_2 527 -MX6Q_PAD_DISP0_DAT2__SDMA_DEBUG_MODE 528 -MX6Q_PAD_DISP0_DAT2__GPIO_4_23 529 -MX6Q_PAD_DISP0_DAT2__MMDC_DEBUG_7 530 -MX6Q_PAD_DISP0_DAT2__PL301_PER1_HADR_13 531 -MX6Q_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3 532 -MX6Q_PAD_DISP0_DAT3__IPU2_DISP0_DAT_3 533 -MX6Q_PAD_DISP0_DAT3__ECSPI3_SS0 534 -MX6Q_PAD_DISP0_DAT3__USDHC1_USDHC_DBG_3 535 -MX6Q_PAD_DISP0_DAT3__SDMA_DBG_BUS_ERROR 536 -MX6Q_PAD_DISP0_DAT3__GPIO_4_24 537 -MX6Q_PAD_DISP0_DAT3__MMDC_MMDC_DBG_8 538 -MX6Q_PAD_DISP0_DAT3__PL301_PER1_HADR_14 539 -MX6Q_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4 540 -MX6Q_PAD_DISP0_DAT4__IPU2_DISP0_DAT_4 541 -MX6Q_PAD_DISP0_DAT4__ECSPI3_SS1 542 -MX6Q_PAD_DISP0_DAT4__USDHC1_USDHC_DBG_4 543 -MX6Q_PAD_DISP0_DAT4__SDMA_DEBUG_BUS_RWB 544 -MX6Q_PAD_DISP0_DAT4__GPIO_4_25 545 -MX6Q_PAD_DISP0_DAT4__MMDC_MMDC_DEBUG_9 546 -MX6Q_PAD_DISP0_DAT4__PL301_PER1_HADR_15 547 -MX6Q_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5 548 -MX6Q_PAD_DISP0_DAT5__IPU2_DISP0_DAT_5 549 -MX6Q_PAD_DISP0_DAT5__ECSPI3_SS2 550 -MX6Q_PAD_DISP0_DAT5__AUDMUX_AUD6_RXFS 551 -MX6Q_PAD_DISP0_DAT5__SDMA_DBG_MCH_DMBUS 552 -MX6Q_PAD_DISP0_DAT5__GPIO_4_26 553 -MX6Q_PAD_DISP0_DAT5__MMDC_DEBUG_10 554 -MX6Q_PAD_DISP0_DAT5__PL301_PER1_HADR_16 555 -MX6Q_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6 556 -MX6Q_PAD_DISP0_DAT6__IPU2_DISP0_DAT_6 557 -MX6Q_PAD_DISP0_DAT6__ECSPI3_SS3 558 -MX6Q_PAD_DISP0_DAT6__AUDMUX_AUD6_RXC 559 -MX6Q_PAD_DISP0_DAT6__SDMA_DBG_RTBUF_WRT 560 -MX6Q_PAD_DISP0_DAT6__GPIO_4_27 561 -MX6Q_PAD_DISP0_DAT6__MMDC_DEBUG_11 562 -MX6Q_PAD_DISP0_DAT6__PL301_PER1_HADR_17 563 -MX6Q_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7 564 -MX6Q_PAD_DISP0_DAT7__IPU2_DISP0_DAT_7 565 -MX6Q_PAD_DISP0_DAT7__ECSPI3_RDY 566 -MX6Q_PAD_DISP0_DAT7__USDHC1_USDHC_DBG_5 567 -MX6Q_PAD_DISP0_DAT7__SDMA_DBG_EVT_CHN_0 568 -MX6Q_PAD_DISP0_DAT7__GPIO_4_28 569 -MX6Q_PAD_DISP0_DAT7__MMDC_DEBUG_12 570 -MX6Q_PAD_DISP0_DAT7__PL301_PER1_HADR_18 571 -MX6Q_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8 572 -MX6Q_PAD_DISP0_DAT8__IPU2_DISP0_DAT_8 573 -MX6Q_PAD_DISP0_DAT8__PWM1_PWMO 574 -MX6Q_PAD_DISP0_DAT8__WDOG1_WDOG_B 575 -MX6Q_PAD_DISP0_DAT8__SDMA_DBG_EVT_CHN_1 576 -MX6Q_PAD_DISP0_DAT8__GPIO_4_29 577 -MX6Q_PAD_DISP0_DAT8__MMDC_DEBUG_13 578 -MX6Q_PAD_DISP0_DAT8__PL301_PER1_HADR_19 579 -MX6Q_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9 580 -MX6Q_PAD_DISP0_DAT9__IPU2_DISP0_DAT_9 581 -MX6Q_PAD_DISP0_DAT9__PWM2_PWMO 582 -MX6Q_PAD_DISP0_DAT9__WDOG2_WDOG_B 583 -MX6Q_PAD_DISP0_DAT9__SDMA_DBG_EVT_CHN_2 584 -MX6Q_PAD_DISP0_DAT9__GPIO_4_30 585 -MX6Q_PAD_DISP0_DAT9__MMDC_DEBUG_14 586 -MX6Q_PAD_DISP0_DAT9__PL301_PER1_HADR_20 587 -MX6Q_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10 588 -MX6Q_PAD_DISP0_DAT10__IPU2_DISP0_DAT_10 589 -MX6Q_PAD_DISP0_DAT10__USDHC1_DBG_6 590 -MX6Q_PAD_DISP0_DAT10__SDMA_DBG_EVT_CHN3 591 -MX6Q_PAD_DISP0_DAT10__GPIO_4_31 592 -MX6Q_PAD_DISP0_DAT10__MMDC_DEBUG_15 593 -MX6Q_PAD_DISP0_DAT10__PL301_PER1_HADR21 594 -MX6Q_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11 595 -MX6Q_PAD_DISP0_DAT11__IPU2_DISP0_DAT_11 596 -MX6Q_PAD_DISP0_DAT11__USDHC1_USDHC_DBG7 597 -MX6Q_PAD_DISP0_DAT11__SDMA_DBG_EVT_CHN4 598 -MX6Q_PAD_DISP0_DAT11__GPIO_5_5 599 -MX6Q_PAD_DISP0_DAT11__MMDC_DEBUG_16 600 -MX6Q_PAD_DISP0_DAT11__PL301_PER1_HADR22 601 -MX6Q_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12 602 -MX6Q_PAD_DISP0_DAT12__IPU2_DISP0_DAT_12 603 -MX6Q_PAD_DISP0_DAT12__RESERVED_RESERVED 604 -MX6Q_PAD_DISP0_DAT12__SDMA_DBG_EVT_CHN5 605 -MX6Q_PAD_DISP0_DAT12__GPIO_5_6 606 -MX6Q_PAD_DISP0_DAT12__MMDC_DEBUG_17 607 -MX6Q_PAD_DISP0_DAT12__PL301_PER1_HADR23 608 -MX6Q_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13 609 -MX6Q_PAD_DISP0_DAT13__IPU2_DISP0_DAT_13 610 -MX6Q_PAD_DISP0_DAT13__AUDMUX_AUD5_RXFS 611 -MX6Q_PAD_DISP0_DAT13__SDMA_DBG_EVT_CHN0 612 -MX6Q_PAD_DISP0_DAT13__GPIO_5_7 613 -MX6Q_PAD_DISP0_DAT13__MMDC_DEBUG_18 614 -MX6Q_PAD_DISP0_DAT13__PL301_PER1_HADR24 615 -MX6Q_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14 616 -MX6Q_PAD_DISP0_DAT14__IPU2_DISP0_DAT_14 617 -MX6Q_PAD_DISP0_DAT14__AUDMUX_AUD5_RXC 618 -MX6Q_PAD_DISP0_DAT14__SDMA_DBG_EVT_CHN1 619 -MX6Q_PAD_DISP0_DAT14__GPIO_5_8 620 -MX6Q_PAD_DISP0_DAT14__MMDC_DEBUG_19 621 -MX6Q_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15 622 -MX6Q_PAD_DISP0_DAT15__IPU2_DISP0_DAT_15 623 -MX6Q_PAD_DISP0_DAT15__ECSPI1_SS1 624 -MX6Q_PAD_DISP0_DAT15__ECSPI2_SS1 625 -MX6Q_PAD_DISP0_DAT15__SDMA_DBG_EVT_CHN2 626 -MX6Q_PAD_DISP0_DAT15__GPIO_5_9 627 -MX6Q_PAD_DISP0_DAT15__MMDC_DEBUG_20 628 -MX6Q_PAD_DISP0_DAT15__PL301_PER1_HADR25 629 -MX6Q_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16 630 -MX6Q_PAD_DISP0_DAT16__IPU2_DISP0_DAT_16 631 -MX6Q_PAD_DISP0_DAT16__ECSPI2_MOSI 632 -MX6Q_PAD_DISP0_DAT16__AUDMUX_AUD5_TXC 633 -MX6Q_PAD_DISP0_DAT16__SDMA_EXT_EVENT_0 634 -MX6Q_PAD_DISP0_DAT16__GPIO_5_10 635 -MX6Q_PAD_DISP0_DAT16__MMDC_DEBUG_21 636 -MX6Q_PAD_DISP0_DAT16__PL301_PER1_HADR26 637 -MX6Q_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17 638 -MX6Q_PAD_DISP0_DAT17__IPU2_DISP0_DAT_17 639 -MX6Q_PAD_DISP0_DAT17__ECSPI2_MISO 640 -MX6Q_PAD_DISP0_DAT17__AUDMUX_AUD5_TXD 641 -MX6Q_PAD_DISP0_DAT17__SDMA_EXT_EVENT_1 642 -MX6Q_PAD_DISP0_DAT17__GPIO_5_11 643 -MX6Q_PAD_DISP0_DAT17__MMDC_DEBUG_22 644 -MX6Q_PAD_DISP0_DAT17__PL301_PER1_HADR27 645 -MX6Q_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18 646 -MX6Q_PAD_DISP0_DAT18__IPU2_DISP0_DAT_18 647 -MX6Q_PAD_DISP0_DAT18__ECSPI2_SS0 648 -MX6Q_PAD_DISP0_DAT18__AUDMUX_AUD5_TXFS 649 -MX6Q_PAD_DISP0_DAT18__AUDMUX_AUD4_RXFS 650 -MX6Q_PAD_DISP0_DAT18__GPIO_5_12 651 -MX6Q_PAD_DISP0_DAT18__MMDC_DEBUG_23 652 -MX6Q_PAD_DISP0_DAT18__WEIM_WEIM_CS_2 653 -MX6Q_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19 654 -MX6Q_PAD_DISP0_DAT19__IPU2_DISP0_DAT_19 655 -MX6Q_PAD_DISP0_DAT19__ECSPI2_SCLK 656 -MX6Q_PAD_DISP0_DAT19__AUDMUX_AUD5_RXD 657 -MX6Q_PAD_DISP0_DAT19__AUDMUX_AUD4_RXC 658 -MX6Q_PAD_DISP0_DAT19__GPIO_5_13 659 -MX6Q_PAD_DISP0_DAT19__MMDC_DEBUG_24 660 -MX6Q_PAD_DISP0_DAT19__WEIM_WEIM_CS_3 661 -MX6Q_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20 662 -MX6Q_PAD_DISP0_DAT20__IPU2_DISP0_DAT_20 663 -MX6Q_PAD_DISP0_DAT20__ECSPI1_SCLK 664 -MX6Q_PAD_DISP0_DAT20__AUDMUX_AUD4_TXC 665 -MX6Q_PAD_DISP0_DAT20__SDMA_DBG_EVT_CHN7 666 -MX6Q_PAD_DISP0_DAT20__GPIO_5_14 667 -MX6Q_PAD_DISP0_DAT20__MMDC_DEBUG_25 668 -MX6Q_PAD_DISP0_DAT20__PL301_PER1_HADR28 669 -MX6Q_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21 670 -MX6Q_PAD_DISP0_DAT21__IPU2_DISP0_DAT_21 671 -MX6Q_PAD_DISP0_DAT21__ECSPI1_MOSI 672 -MX6Q_PAD_DISP0_DAT21__AUDMUX_AUD4_TXD 673 -MX6Q_PAD_DISP0_DAT21__SDMA_DBG_BUS_DEV0 674 -MX6Q_PAD_DISP0_DAT21__GPIO_5_15 675 -MX6Q_PAD_DISP0_DAT21__MMDC_DEBUG_26 676 -MX6Q_PAD_DISP0_DAT21__PL301_PER1_HADR29 677 -MX6Q_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22 678 -MX6Q_PAD_DISP0_DAT22__IPU2_DISP0_DAT_22 679 -MX6Q_PAD_DISP0_DAT22__ECSPI1_MISO 680 -MX6Q_PAD_DISP0_DAT22__AUDMUX_AUD4_TXFS 681 -MX6Q_PAD_DISP0_DAT22__SDMA_DBG_BUS_DEV1 682 -MX6Q_PAD_DISP0_DAT22__GPIO_5_16 683 -MX6Q_PAD_DISP0_DAT22__MMDC_DEBUG_27 684 -MX6Q_PAD_DISP0_DAT22__PL301_PER1_HADR30 685 -MX6Q_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23 686 -MX6Q_PAD_DISP0_DAT23__IPU2_DISP0_DAT_23 687 -MX6Q_PAD_DISP0_DAT23__ECSPI1_SS0 688 -MX6Q_PAD_DISP0_DAT23__AUDMUX_AUD4_RXD 689 -MX6Q_PAD_DISP0_DAT23__SDMA_DBG_BUS_DEV2 690 -MX6Q_PAD_DISP0_DAT23__GPIO_5_17 691 -MX6Q_PAD_DISP0_DAT23__MMDC_DEBUG_28 692 -MX6Q_PAD_DISP0_DAT23__PL301_PER1_HADR31 693 -MX6Q_PAD_ENET_MDIO__RESERVED_RESERVED 694 -MX6Q_PAD_ENET_MDIO__ENET_MDIO 695 -MX6Q_PAD_ENET_MDIO__ESAI1_SCKR 696 -MX6Q_PAD_ENET_MDIO__SDMA_DEBUG_BUS_DEV3 697 -MX6Q_PAD_ENET_MDIO__ENET_1588_EVT1_OUT 698 -MX6Q_PAD_ENET_MDIO__GPIO_1_22 699 -MX6Q_PAD_ENET_MDIO__SPDIF_PLOCK 700 -MX6Q_PAD_ENET_REF_CLK__RESERVED_RSRVED 701 -MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK 702 -MX6Q_PAD_ENET_REF_CLK__ESAI1_FSR 703 -MX6Q_PAD_ENET_REF_CLK__SDMA_DBGBUS_DEV4 704 -MX6Q_PAD_ENET_REF_CLK__GPIO_1_23 705 -MX6Q_PAD_ENET_REF_CLK__SPDIF_SRCLK 706 -MX6Q_PAD_ENET_REF_CLK__USBPHY1_RX_SQH 707 -MX6Q_PAD_ENET_RX_ER__ENET_RX_ER 708 -MX6Q_PAD_ENET_RX_ER__ESAI1_HCKR 709 -MX6Q_PAD_ENET_RX_ER__SPDIF_IN1 710 -MX6Q_PAD_ENET_RX_ER__ENET_1588_EVT2_OUT 711 -MX6Q_PAD_ENET_RX_ER__GPIO_1_24 712 -MX6Q_PAD_ENET_RX_ER__PHY_TDI 713 -MX6Q_PAD_ENET_RX_ER__USBPHY1_RX_HS_RXD 714 -MX6Q_PAD_ENET_CRS_DV__RESERVED_RSRVED 715 -MX6Q_PAD_ENET_CRS_DV__ENET_RX_EN 716 -MX6Q_PAD_ENET_CRS_DV__ESAI1_SCKT 717 -MX6Q_PAD_ENET_CRS_DV__SPDIF_EXTCLK 718 -MX6Q_PAD_ENET_CRS_DV__GPIO_1_25 719 -MX6Q_PAD_ENET_CRS_DV__PHY_TDO 720 -MX6Q_PAD_ENET_CRS_DV__USBPHY1_RX_FS_RXD 721 -MX6Q_PAD_ENET_RXD1__MLB_MLBSIG 722 -MX6Q_PAD_ENET_RXD1__ENET_RDATA_1 723 -MX6Q_PAD_ENET_RXD1__ESAI1_FST 724 -MX6Q_PAD_ENET_RXD1__ENET_1588_EVT3_OUT 725 -MX6Q_PAD_ENET_RXD1__GPIO_1_26 726 -MX6Q_PAD_ENET_RXD1__PHY_TCK 727 -MX6Q_PAD_ENET_RXD1__USBPHY1_RX_DISCON 728 -MX6Q_PAD_ENET_RXD0__OSC32K_32K_OUT 729 -MX6Q_PAD_ENET_RXD0__ENET_RDATA_0 730 -MX6Q_PAD_ENET_RXD0__ESAI1_HCKT 731 -MX6Q_PAD_ENET_RXD0__SPDIF_OUT1 732 -MX6Q_PAD_ENET_RXD0__GPIO_1_27 733 -MX6Q_PAD_ENET_RXD0__PHY_TMS 734 -MX6Q_PAD_ENET_RXD0__USBPHY1_PLL_CK20DIV 735 -MX6Q_PAD_ENET_TX_EN__RESERVED_RSRVED 736 -MX6Q_PAD_ENET_TX_EN__ENET_TX_EN 737 -MX6Q_PAD_ENET_TX_EN__ESAI1_TX3_RX2 738 -MX6Q_PAD_ENET_TX_EN__GPIO_1_28 739 -MX6Q_PAD_ENET_TX_EN__SATA_PHY_TDI 740 -MX6Q_PAD_ENET_TX_EN__USBPHY2_RX_SQH 741 -MX6Q_PAD_ENET_TXD1__MLB_MLBCLK 742 -MX6Q_PAD_ENET_TXD1__ENET_TDATA_1 743 -MX6Q_PAD_ENET_TXD1__ESAI1_TX2_RX3 744 -MX6Q_PAD_ENET_TXD1__ENET_1588_EVENT0_IN 745 -MX6Q_PAD_ENET_TXD1__GPIO_1_29 746 -MX6Q_PAD_ENET_TXD1__SATA_PHY_TDO 747 -MX6Q_PAD_ENET_TXD1__USBPHY2_RX_HS_RXD 748 -MX6Q_PAD_ENET_TXD0__RESERVED_RSRVED 749 -MX6Q_PAD_ENET_TXD0__ENET_TDATA_0 750 -MX6Q_PAD_ENET_TXD0__ESAI1_TX4_RX1 751 -MX6Q_PAD_ENET_TXD0__GPIO_1_30 752 -MX6Q_PAD_ENET_TXD0__SATA_PHY_TCK 753 -MX6Q_PAD_ENET_TXD0__USBPHY2_RX_FS_RXD 754 -MX6Q_PAD_ENET_MDC__MLB_MLBDAT 755 -MX6Q_PAD_ENET_MDC__ENET_MDC 756 -MX6Q_PAD_ENET_MDC__ESAI1_TX5_RX0 757 -MX6Q_PAD_ENET_MDC__ENET_1588_EVENT1_IN 758 -MX6Q_PAD_ENET_MDC__GPIO_1_31 759 -MX6Q_PAD_ENET_MDC__SATA_PHY_TMS 760 -MX6Q_PAD_ENET_MDC__USBPHY2_RX_DISCON 761 -MX6Q_PAD_DRAM_D40__MMDC_DRAM_D_40 762 -MX6Q_PAD_DRAM_D41__MMDC_DRAM_D_41 763 -MX6Q_PAD_DRAM_D42__MMDC_DRAM_D_42 764 -MX6Q_PAD_DRAM_D43__MMDC_DRAM_D_43 765 -MX6Q_PAD_DRAM_D44__MMDC_DRAM_D_44 766 -MX6Q_PAD_DRAM_D45__MMDC_DRAM_D_45 767 -MX6Q_PAD_DRAM_D46__MMDC_DRAM_D_46 768 -MX6Q_PAD_DRAM_D47__MMDC_DRAM_D_47 769 -MX6Q_PAD_DRAM_SDQS5__MMDC_DRAM_SDQS_5 770 -MX6Q_PAD_DRAM_DQM5__MMDC_DRAM_DQM_5 771 -MX6Q_PAD_DRAM_D32__MMDC_DRAM_D_32 772 -MX6Q_PAD_DRAM_D33__MMDC_DRAM_D_33 773 -MX6Q_PAD_DRAM_D34__MMDC_DRAM_D_34 774 -MX6Q_PAD_DRAM_D35__MMDC_DRAM_D_35 775 -MX6Q_PAD_DRAM_D36__MMDC_DRAM_D_36 776 -MX6Q_PAD_DRAM_D37__MMDC_DRAM_D_37 777 -MX6Q_PAD_DRAM_D38__MMDC_DRAM_D_38 778 -MX6Q_PAD_DRAM_D39__MMDC_DRAM_D_39 779 -MX6Q_PAD_DRAM_DQM4__MMDC_DRAM_DQM_4 780 -MX6Q_PAD_DRAM_SDQS4__MMDC_DRAM_SDQS_4 781 -MX6Q_PAD_DRAM_D24__MMDC_DRAM_D_24 782 -MX6Q_PAD_DRAM_D25__MMDC_DRAM_D_25 783 -MX6Q_PAD_DRAM_D26__MMDC_DRAM_D_26 784 -MX6Q_PAD_DRAM_D27__MMDC_DRAM_D_27 785 -MX6Q_PAD_DRAM_D28__MMDC_DRAM_D_28 786 -MX6Q_PAD_DRAM_D29__MMDC_DRAM_D_29 787 -MX6Q_PAD_DRAM_SDQS3__MMDC_DRAM_SDQS_3 788 -MX6Q_PAD_DRAM_D30__MMDC_DRAM_D_30 789 -MX6Q_PAD_DRAM_D31__MMDC_DRAM_D_31 790 -MX6Q_PAD_DRAM_DQM3__MMDC_DRAM_DQM_3 791 -MX6Q_PAD_DRAM_D16__MMDC_DRAM_D_16 792 -MX6Q_PAD_DRAM_D17__MMDC_DRAM_D_17 793 -MX6Q_PAD_DRAM_D18__MMDC_DRAM_D_18 794 -MX6Q_PAD_DRAM_D19__MMDC_DRAM_D_19 795 -MX6Q_PAD_DRAM_D20__MMDC_DRAM_D_20 796 -MX6Q_PAD_DRAM_D21__MMDC_DRAM_D_21 797 -MX6Q_PAD_DRAM_D22__MMDC_DRAM_D_22 798 -MX6Q_PAD_DRAM_SDQS2__MMDC_DRAM_SDQS_2 799 -MX6Q_PAD_DRAM_D23__MMDC_DRAM_D_23 800 -MX6Q_PAD_DRAM_DQM2__MMDC_DRAM_DQM_2 801 -MX6Q_PAD_DRAM_A0__MMDC_DRAM_A_0 802 -MX6Q_PAD_DRAM_A1__MMDC_DRAM_A_1 803 -MX6Q_PAD_DRAM_A2__MMDC_DRAM_A_2 804 -MX6Q_PAD_DRAM_A3__MMDC_DRAM_A_3 805 -MX6Q_PAD_DRAM_A4__MMDC_DRAM_A_4 806 -MX6Q_PAD_DRAM_A5__MMDC_DRAM_A_5 807 -MX6Q_PAD_DRAM_A6__MMDC_DRAM_A_6 808 -MX6Q_PAD_DRAM_A7__MMDC_DRAM_A_7 809 -MX6Q_PAD_DRAM_A8__MMDC_DRAM_A_8 810 -MX6Q_PAD_DRAM_A9__MMDC_DRAM_A_9 811 -MX6Q_PAD_DRAM_A10__MMDC_DRAM_A_10 812 -MX6Q_PAD_DRAM_A11__MMDC_DRAM_A_11 813 -MX6Q_PAD_DRAM_A12__MMDC_DRAM_A_12 814 -MX6Q_PAD_DRAM_A13__MMDC_DRAM_A_13 815 -MX6Q_PAD_DRAM_A14__MMDC_DRAM_A_14 816 -MX6Q_PAD_DRAM_A15__MMDC_DRAM_A_15 817 -MX6Q_PAD_DRAM_CAS__MMDC_DRAM_CAS 818 -MX6Q_PAD_DRAM_CS0__MMDC_DRAM_CS_0 819 -MX6Q_PAD_DRAM_CS1__MMDC_DRAM_CS_1 820 -MX6Q_PAD_DRAM_RAS__MMDC_DRAM_RAS 821 -MX6Q_PAD_DRAM_RESET__MMDC_DRAM_RESET 822 -MX6Q_PAD_DRAM_SDBA0__MMDC_DRAM_SDBA_0 823 -MX6Q_PAD_DRAM_SDBA1__MMDC_DRAM_SDBA_1 824 -MX6Q_PAD_DRAM_SDCLK_0__MMDC_DRAM_SDCLK0 825 -MX6Q_PAD_DRAM_SDBA2__MMDC_DRAM_SDBA_2 826 -MX6Q_PAD_DRAM_SDCKE0__MMDC_DRAM_SDCKE_0 827 -MX6Q_PAD_DRAM_SDCLK_1__MMDC_DRAM_SDCLK1 828 -MX6Q_PAD_DRAM_SDCKE1__MMDC_DRAM_SDCKE_1 829 -MX6Q_PAD_DRAM_SDODT0__MMDC_DRAM_ODT_0 830 -MX6Q_PAD_DRAM_SDODT1__MMDC_DRAM_ODT_1 831 -MX6Q_PAD_DRAM_SDWE__MMDC_DRAM_SDWE 832 -MX6Q_PAD_DRAM_D0__MMDC_DRAM_D_0 833 -MX6Q_PAD_DRAM_D1__MMDC_DRAM_D_1 834 -MX6Q_PAD_DRAM_D2__MMDC_DRAM_D_2 835 -MX6Q_PAD_DRAM_D3__MMDC_DRAM_D_3 836 -MX6Q_PAD_DRAM_D4__MMDC_DRAM_D_4 837 -MX6Q_PAD_DRAM_D5__MMDC_DRAM_D_5 838 -MX6Q_PAD_DRAM_SDQS0__MMDC_DRAM_SDQS_0 839 -MX6Q_PAD_DRAM_D6__MMDC_DRAM_D_6 840 -MX6Q_PAD_DRAM_D7__MMDC_DRAM_D_7 841 -MX6Q_PAD_DRAM_DQM0__MMDC_DRAM_DQM_0 842 -MX6Q_PAD_DRAM_D8__MMDC_DRAM_D_8 843 -MX6Q_PAD_DRAM_D9__MMDC_DRAM_D_9 844 -MX6Q_PAD_DRAM_D10__MMDC_DRAM_D_10 845 -MX6Q_PAD_DRAM_D11__MMDC_DRAM_D_11 846 -MX6Q_PAD_DRAM_D12__MMDC_DRAM_D_12 847 -MX6Q_PAD_DRAM_D13__MMDC_DRAM_D_13 848 -MX6Q_PAD_DRAM_D14__MMDC_DRAM_D_14 849 -MX6Q_PAD_DRAM_SDQS1__MMDC_DRAM_SDQS_1 850 -MX6Q_PAD_DRAM_D15__MMDC_DRAM_D_15 851 -MX6Q_PAD_DRAM_DQM1__MMDC_DRAM_DQM_1 852 -MX6Q_PAD_DRAM_D48__MMDC_DRAM_D_48 853 -MX6Q_PAD_DRAM_D49__MMDC_DRAM_D_49 854 -MX6Q_PAD_DRAM_D50__MMDC_DRAM_D_50 855 -MX6Q_PAD_DRAM_D51__MMDC_DRAM_D_51 856 -MX6Q_PAD_DRAM_D52__MMDC_DRAM_D_52 857 -MX6Q_PAD_DRAM_D53__MMDC_DRAM_D_53 858 -MX6Q_PAD_DRAM_D54__MMDC_DRAM_D_54 859 -MX6Q_PAD_DRAM_D55__MMDC_DRAM_D_55 860 -MX6Q_PAD_DRAM_SDQS6__MMDC_DRAM_SDQS_6 861 -MX6Q_PAD_DRAM_DQM6__MMDC_DRAM_DQM_6 862 -MX6Q_PAD_DRAM_D56__MMDC_DRAM_D_56 863 -MX6Q_PAD_DRAM_SDQS7__MMDC_DRAM_SDQS_7 864 -MX6Q_PAD_DRAM_D57__MMDC_DRAM_D_57 865 -MX6Q_PAD_DRAM_D58__MMDC_DRAM_D_58 866 -MX6Q_PAD_DRAM_D59__MMDC_DRAM_D_59 867 -MX6Q_PAD_DRAM_D60__MMDC_DRAM_D_60 868 -MX6Q_PAD_DRAM_DQM7__MMDC_DRAM_DQM_7 869 -MX6Q_PAD_DRAM_D61__MMDC_DRAM_D_61 870 -MX6Q_PAD_DRAM_D62__MMDC_DRAM_D_62 871 -MX6Q_PAD_DRAM_D63__MMDC_DRAM_D_63 872 -MX6Q_PAD_KEY_COL0__ECSPI1_SCLK 873 -MX6Q_PAD_KEY_COL0__ENET_RDATA_3 874 -MX6Q_PAD_KEY_COL0__AUDMUX_AUD5_TXC 875 -MX6Q_PAD_KEY_COL0__KPP_COL_0 876 -MX6Q_PAD_KEY_COL0__UART4_TXD 877 -MX6Q_PAD_KEY_COL0__GPIO_4_6 878 -MX6Q_PAD_KEY_COL0__DCIC1_DCIC_OUT 879 -MX6Q_PAD_KEY_COL0__SRC_ANY_PU_RST 880 -MX6Q_PAD_KEY_ROW0__ECSPI1_MOSI 881 -MX6Q_PAD_KEY_ROW0__ENET_TDATA_3 882 -MX6Q_PAD_KEY_ROW0__AUDMUX_AUD5_TXD 883 -MX6Q_PAD_KEY_ROW0__KPP_ROW_0 884 -MX6Q_PAD_KEY_ROW0__UART4_RXD 885 -MX6Q_PAD_KEY_ROW0__GPIO_4_7 886 -MX6Q_PAD_KEY_ROW0__DCIC2_DCIC_OUT 887 -MX6Q_PAD_KEY_ROW0__PL301_PER1_HADR_0 888 -MX6Q_PAD_KEY_COL1__ECSPI1_MISO 889 -MX6Q_PAD_KEY_COL1__ENET_MDIO 890 -MX6Q_PAD_KEY_COL1__AUDMUX_AUD5_TXFS 891 -MX6Q_PAD_KEY_COL1__KPP_COL_1 892 -MX6Q_PAD_KEY_COL1__UART5_TXD 893 -MX6Q_PAD_KEY_COL1__GPIO_4_8 894 -MX6Q_PAD_KEY_COL1__USDHC1_VSELECT 895 -MX6Q_PAD_KEY_COL1__PL301MX_PER1_HADR_1 896 -MX6Q_PAD_KEY_ROW1__ECSPI1_SS0 897 -MX6Q_PAD_KEY_ROW1__ENET_COL 898 -MX6Q_PAD_KEY_ROW1__AUDMUX_AUD5_RXD 899 -MX6Q_PAD_KEY_ROW1__KPP_ROW_1 900 -MX6Q_PAD_KEY_ROW1__UART5_RXD 901 -MX6Q_PAD_KEY_ROW1__GPIO_4_9 902 -MX6Q_PAD_KEY_ROW1__USDHC2_VSELECT 903 -MX6Q_PAD_KEY_ROW1__PL301_PER1_HADDR_2 904 -MX6Q_PAD_KEY_COL2__ECSPI1_SS1 905 -MX6Q_PAD_KEY_COL2__ENET_RDATA_2 906 -MX6Q_PAD_KEY_COL2__CAN1_TXCAN 907 -MX6Q_PAD_KEY_COL2__KPP_COL_2 908 -MX6Q_PAD_KEY_COL2__ENET_MDC 909 -MX6Q_PAD_KEY_COL2__GPIO_4_10 910 -MX6Q_PAD_KEY_COL2__USBOH3_H1_PWRCTL_WKP 911 -MX6Q_PAD_KEY_COL2__PL301_PER1_HADDR_3 912 -MX6Q_PAD_KEY_ROW2__ECSPI1_SS2 913 -MX6Q_PAD_KEY_ROW2__ENET_TDATA_2 914 -MX6Q_PAD_KEY_ROW2__CAN1_RXCAN 915 -MX6Q_PAD_KEY_ROW2__KPP_ROW_2 916 -MX6Q_PAD_KEY_ROW2__USDHC2_VSELECT 917 -MX6Q_PAD_KEY_ROW2__GPIO_4_11 918 -MX6Q_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 919 -MX6Q_PAD_KEY_ROW2__PL301_PER1_HADR_4 920 -MX6Q_PAD_KEY_COL3__ECSPI1_SS3 921 -MX6Q_PAD_KEY_COL3__ENET_CRS 922 -MX6Q_PAD_KEY_COL3__HDMI_TX_DDC_SCL 923 -MX6Q_PAD_KEY_COL3__KPP_COL_3 924 -MX6Q_PAD_KEY_COL3__I2C2_SCL 925 -MX6Q_PAD_KEY_COL3__GPIO_4_12 926 -MX6Q_PAD_KEY_COL3__SPDIF_IN1 927 -MX6Q_PAD_KEY_COL3__PL301_PER1_HADR_5 928 -MX6Q_PAD_KEY_ROW3__OSC32K_32K_OUT 929 -MX6Q_PAD_KEY_ROW3__ASRC_ASRC_EXT_CLK 930 -MX6Q_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 931 -MX6Q_PAD_KEY_ROW3__KPP_ROW_3 932 -MX6Q_PAD_KEY_ROW3__I2C2_SDA 933 -MX6Q_PAD_KEY_ROW3__GPIO_4_13 934 -MX6Q_PAD_KEY_ROW3__USDHC1_VSELECT 935 -MX6Q_PAD_KEY_ROW3__PL301_PER1_HADR_6 936 -MX6Q_PAD_KEY_COL4__CAN2_TXCAN 937 -MX6Q_PAD_KEY_COL4__IPU1_SISG_4 938 -MX6Q_PAD_KEY_COL4__USBOH3_USBOTG_OC 939 -MX6Q_PAD_KEY_COL4__KPP_COL_4 940 -MX6Q_PAD_KEY_COL4__UART5_RTS 941 -MX6Q_PAD_KEY_COL4__GPIO_4_14 942 -MX6Q_PAD_KEY_COL4__MMDC_DEBUG_49 943 -MX6Q_PAD_KEY_COL4__PL301_PER1_HADDR_7 944 -MX6Q_PAD_KEY_ROW4__CAN2_RXCAN 945 -MX6Q_PAD_KEY_ROW4__IPU1_SISG_5 946 -MX6Q_PAD_KEY_ROW4__USBOH3_USBOTG_PWR 947 -MX6Q_PAD_KEY_ROW4__KPP_ROW_4 948 -MX6Q_PAD_KEY_ROW4__UART5_CTS 949 -MX6Q_PAD_KEY_ROW4__GPIO_4_15 950 -MX6Q_PAD_KEY_ROW4__MMDC_DEBUG_50 951 -MX6Q_PAD_KEY_ROW4__PL301_PER1_HADR_8 952 -MX6Q_PAD_GPIO_0__CCM_CLKO 953 -MX6Q_PAD_GPIO_0__KPP_COL_5 954 -MX6Q_PAD_GPIO_0__ASRC_ASRC_EXT_CLK 955 -MX6Q_PAD_GPIO_0__EPIT1_EPITO 956 -MX6Q_PAD_GPIO_0__GPIO_1_0 957 -MX6Q_PAD_GPIO_0__USBOH3_USBH1_PWR 958 -MX6Q_PAD_GPIO_0__SNVS_HP_WRAP_SNVS_VIO5 959 -MX6Q_PAD_GPIO_1__ESAI1_SCKR 960 -MX6Q_PAD_GPIO_1__WDOG2_WDOG_B 961 -MX6Q_PAD_GPIO_1__KPP_ROW_5 962 -MX6Q_PAD_GPIO_1__PWM2_PWMO 963 -MX6Q_PAD_GPIO_1__GPIO_1_1 964 -MX6Q_PAD_GPIO_1__USDHC1_CD 965 -MX6Q_PAD_GPIO_1__SRC_TESTER_ACK 966 -MX6Q_PAD_GPIO_9__ESAI1_FSR 967 -MX6Q_PAD_GPIO_9__WDOG1_WDOG_B 968 -MX6Q_PAD_GPIO_9__KPP_COL_6 969 -MX6Q_PAD_GPIO_9__CCM_REF_EN_B 970 -MX6Q_PAD_GPIO_9__PWM1_PWMO 971 -MX6Q_PAD_GPIO_9__GPIO_1_9 972 -MX6Q_PAD_GPIO_9__USDHC1_WP 973 -MX6Q_PAD_GPIO_9__SRC_EARLY_RST 974 -MX6Q_PAD_GPIO_3__ESAI1_HCKR 975 -MX6Q_PAD_GPIO_3__OBSERVE_MUX_INT_OUT0 976 -MX6Q_PAD_GPIO_3__I2C3_SCL 977 -MX6Q_PAD_GPIO_3__ANATOP_24M_OUT 978 -MX6Q_PAD_GPIO_3__CCM_CLKO2 979 -MX6Q_PAD_GPIO_3__GPIO_1_3 980 -MX6Q_PAD_GPIO_3__USBOH3_USBH1_OC 981 -MX6Q_PAD_GPIO_3__MLB_MLBCLK 982 -MX6Q_PAD_GPIO_6__ESAI1_SCKT 983 -MX6Q_PAD_GPIO_6__OBSERVE_MUX_INT_OUT1 984 -MX6Q_PAD_GPIO_6__I2C3_SDA 985 -MX6Q_PAD_GPIO_6__CCM_CCM_OUT_0 986 -MX6Q_PAD_GPIO_6__CSU_CSU_INT_DEB 987 -MX6Q_PAD_GPIO_6__GPIO_1_6 988 -MX6Q_PAD_GPIO_6__USDHC2_LCTL 989 -MX6Q_PAD_GPIO_6__MLB_MLBSIG 990 -MX6Q_PAD_GPIO_2__ESAI1_FST 991 -MX6Q_PAD_GPIO_2__OBSERVE_MUX_INT_OUT2 992 -MX6Q_PAD_GPIO_2__KPP_ROW_6 993 -MX6Q_PAD_GPIO_2__CCM_CCM_OUT_1 994 -MX6Q_PAD_GPIO_2__CSU_CSU_ALARM_AUT_0 995 -MX6Q_PAD_GPIO_2__GPIO_1_2 996 -MX6Q_PAD_GPIO_2__USDHC2_WP 997 -MX6Q_PAD_GPIO_2__MLB_MLBDAT 998 -MX6Q_PAD_GPIO_4__ESAI1_HCKT 999 -MX6Q_PAD_GPIO_4__OBSERVE_MUX_INT_OUT3 1000 -MX6Q_PAD_GPIO_4__KPP_COL_7 1001 -MX6Q_PAD_GPIO_4__CCM_CCM_OUT_2 1002 -MX6Q_PAD_GPIO_4__CSU_CSU_ALARM_AUT_1 1003 -MX6Q_PAD_GPIO_4__GPIO_1_4 1004 -MX6Q_PAD_GPIO_4__USDHC2_CD 1005 -MX6Q_PAD_GPIO_4__OCOTP_CRL_WRAR_FUSE_LA 1006 -MX6Q_PAD_GPIO_5__ESAI1_TX2_RX3 1007 -MX6Q_PAD_GPIO_5__OBSERVE_MUX_INT_OUT4 1008 -MX6Q_PAD_GPIO_5__KPP_ROW_7 1009 -MX6Q_PAD_GPIO_5__CCM_CLKO 1010 -MX6Q_PAD_GPIO_5__CSU_CSU_ALARM_AUT_2 1011 -MX6Q_PAD_GPIO_5__GPIO_1_5 1012 -MX6Q_PAD_GPIO_5__I2C3_SCL 1013 -MX6Q_PAD_GPIO_5__CHEETAH_EVENTI 1014 -MX6Q_PAD_GPIO_7__ESAI1_TX4_RX1 1015 -MX6Q_PAD_GPIO_7__ECSPI5_RDY 1016 -MX6Q_PAD_GPIO_7__EPIT1_EPITO 1017 -MX6Q_PAD_GPIO_7__CAN1_TXCAN 1018 -MX6Q_PAD_GPIO_7__UART2_TXD 1019 -MX6Q_PAD_GPIO_7__GPIO_1_7 1020 -MX6Q_PAD_GPIO_7__SPDIF_PLOCK 1021 -MX6Q_PAD_GPIO_7__USBOH3_OTGUSB_HST_MODE 1022 -MX6Q_PAD_GPIO_8__ESAI1_TX5_RX0 1023 -MX6Q_PAD_GPIO_8__ANATOP_ANATOP_32K_OUT 1024 -MX6Q_PAD_GPIO_8__EPIT2_EPITO 1025 -MX6Q_PAD_GPIO_8__CAN1_RXCAN 1026 -MX6Q_PAD_GPIO_8__UART2_RXD 1027 -MX6Q_PAD_GPIO_8__GPIO_1_8 1028 -MX6Q_PAD_GPIO_8__SPDIF_SRCLK 1029 -MX6Q_PAD_GPIO_8__USBOH3_OTG_PWRCTL_WAK 1030 -MX6Q_PAD_GPIO_16__ESAI1_TX3_RX2 1031 -MX6Q_PAD_GPIO_16__ENET_1588_EVENT2_IN 1032 -MX6Q_PAD_GPIO_16__ENET_ETHERNET_REF_OUT 1033 -MX6Q_PAD_GPIO_16__USDHC1_LCTL 1034 -MX6Q_PAD_GPIO_16__SPDIF_IN1 1035 -MX6Q_PAD_GPIO_16__GPIO_7_11 1036 -MX6Q_PAD_GPIO_16__I2C3_SDA 1037 -MX6Q_PAD_GPIO_16__SJC_DE_B 1038 -MX6Q_PAD_GPIO_17__ESAI1_TX0 1039 -MX6Q_PAD_GPIO_17__ENET_1588_EVENT3_IN 1040 -MX6Q_PAD_GPIO_17__CCM_PMIC_RDY 1041 -MX6Q_PAD_GPIO_17__SDMA_SDMA_EXT_EVENT_0 1042 -MX6Q_PAD_GPIO_17__SPDIF_OUT1 1043 -MX6Q_PAD_GPIO_17__GPIO_7_12 1044 -MX6Q_PAD_GPIO_17__SJC_JTAG_ACT 1045 -MX6Q_PAD_GPIO_18__ESAI1_TX1 1046 -MX6Q_PAD_GPIO_18__ENET_RX_CLK 1047 -MX6Q_PAD_GPIO_18__USDHC3_VSELECT 1048 -MX6Q_PAD_GPIO_18__SDMA_SDMA_EXT_EVENT_1 1049 -MX6Q_PAD_GPIO_18__ASRC_ASRC_EXT_CLK 1050 -MX6Q_PAD_GPIO_18__GPIO_7_13 1051 -MX6Q_PAD_GPIO_18__SNVS_HP_WRA_SNVS_VIO5 1052 -MX6Q_PAD_GPIO_18__SRC_SYSTEM_RST 1053 -MX6Q_PAD_GPIO_19__KPP_COL_5 1054 -MX6Q_PAD_GPIO_19__ENET_1588_EVENT0_OUT 1055 -MX6Q_PAD_GPIO_19__SPDIF_OUT1 1056 -MX6Q_PAD_GPIO_19__CCM_CLKO 1057 -MX6Q_PAD_GPIO_19__ECSPI1_RDY 1058 -MX6Q_PAD_GPIO_19__GPIO_4_5 1059 -MX6Q_PAD_GPIO_19__ENET_TX_ER 1060 -MX6Q_PAD_GPIO_19__SRC_INT_BOOT 1061 -MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 1062 -MX6Q_PAD_CSI0_PIXCLK__PCIE_CTRL_MUX_12 1063 -MX6Q_PAD_CSI0_PIXCLK__SDMA_DEBUG_PC_0 1064 -MX6Q_PAD_CSI0_PIXCLK__GPIO_5_18 1065 -MX6Q_PAD_CSI0_PIXCLK___MMDC_DEBUG_29 1066 -MX6Q_PAD_CSI0_PIXCLK__CHEETAH_EVENTO 1067 -MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 1068 -MX6Q_PAD_CSI0_MCLK__PCIE_CTRL_MUX_13 1069 -MX6Q_PAD_CSI0_MCLK__CCM_CLKO 1070 -MX6Q_PAD_CSI0_MCLK__SDMA_DEBUG_PC_1 1071 -MX6Q_PAD_CSI0_MCLK__GPIO_5_19 1072 -MX6Q_PAD_CSI0_MCLK__MMDC_MMDC_DEBUG_30 1073 -MX6Q_PAD_CSI0_MCLK__CHEETAH_TRCTL 1074 -MX6Q_PAD_CSI0_DATA_EN__IPU1_CSI0_DA_EN 1075 -MX6Q_PAD_CSI0_DATA_EN__WEIM_WEIM_D_0 1076 -MX6Q_PAD_CSI0_DATA_EN__PCIE_CTRL_MUX_14 1077 -MX6Q_PAD_CSI0_DATA_EN__SDMA_DEBUG_PC_2 1078 -MX6Q_PAD_CSI0_DATA_EN__GPIO_5_20 1079 -MX6Q_PAD_CSI0_DATA_EN__MMDC_DEBUG_31 1080 -MX6Q_PAD_CSI0_DATA_EN__CHEETAH_TRCLK 1081 -MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 1082 -MX6Q_PAD_CSI0_VSYNC__WEIM_WEIM_D_1 1083 -MX6Q_PAD_CSI0_VSYNC__PCIE_CTRL_MUX_15 1084 -MX6Q_PAD_CSI0_VSYNC__SDMA_DEBUG_PC_3 1085 -MX6Q_PAD_CSI0_VSYNC__GPIO_5_21 1086 -MX6Q_PAD_CSI0_VSYNC__MMDC_DEBUG_32 1087 -MX6Q_PAD_CSI0_VSYNC__CHEETAH_TRACE_0 1088 -MX6Q_PAD_CSI0_DAT4__IPU1_CSI0_D_4 1089 -MX6Q_PAD_CSI0_DAT4__WEIM_WEIM_D_2 1090 -MX6Q_PAD_CSI0_DAT4__ECSPI1_SCLK 1091 -MX6Q_PAD_CSI0_DAT4__KPP_COL_5 1092 -MX6Q_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC 1093 -MX6Q_PAD_CSI0_DAT4__GPIO_5_22 1094 -MX6Q_PAD_CSI0_DAT4__MMDC_DEBUG_43 1095 -MX6Q_PAD_CSI0_DAT4__CHEETAH_TRACE_1 1096 -MX6Q_PAD_CSI0_DAT5__IPU1_CSI0_D_5 1097 -MX6Q_PAD_CSI0_DAT5__WEIM_WEIM_D_3 1098 -MX6Q_PAD_CSI0_DAT5__ECSPI1_MOSI 1099 -MX6Q_PAD_CSI0_DAT5__KPP_ROW_5 1100 -MX6Q_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD 1101 -MX6Q_PAD_CSI0_DAT5__GPIO_5_23 1102 -MX6Q_PAD_CSI0_DAT5__MMDC_MMDC_DEBUG_44 1103 -MX6Q_PAD_CSI0_DAT5__CHEETAH_TRACE_2 1104 -MX6Q_PAD_CSI0_DAT6__IPU1_CSI0_D_6 1105 -MX6Q_PAD_CSI0_DAT6__WEIM_WEIM_D_4 1106 -MX6Q_PAD_CSI0_DAT6__ECSPI1_MISO 1107 -MX6Q_PAD_CSI0_DAT6__KPP_COL_6 1108 -MX6Q_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS 1109 -MX6Q_PAD_CSI0_DAT6__GPIO_5_24 1110 -MX6Q_PAD_CSI0_DAT6__MMDC_MMDC_DEBUG_45 1111 -MX6Q_PAD_CSI0_DAT6__CHEETAH_TRACE_3 1112 -MX6Q_PAD_CSI0_DAT7__IPU1_CSI0_D_7 1113 -MX6Q_PAD_CSI0_DAT7__WEIM_WEIM_D_5 1114 -MX6Q_PAD_CSI0_DAT7__ECSPI1_SS0 1115 -MX6Q_PAD_CSI0_DAT7__KPP_ROW_6 1116 -MX6Q_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD 1117 -MX6Q_PAD_CSI0_DAT7__GPIO_5_25 1118 -MX6Q_PAD_CSI0_DAT7__MMDC_MMDC_DEBUG_46 1119 -MX6Q_PAD_CSI0_DAT7__CHEETAH_TRACE_4 1120 -MX6Q_PAD_CSI0_DAT8__IPU1_CSI0_D_8 1121 -MX6Q_PAD_CSI0_DAT8__WEIM_WEIM_D_6 1122 -MX6Q_PAD_CSI0_DAT8__ECSPI2_SCLK 1123 -MX6Q_PAD_CSI0_DAT8__KPP_COL_7 1124 -MX6Q_PAD_CSI0_DAT8__I2C1_SDA 1125 -MX6Q_PAD_CSI0_DAT8__GPIO_5_26 1126 -MX6Q_PAD_CSI0_DAT8__MMDC_MMDC_DEBUG_47 1127 -MX6Q_PAD_CSI0_DAT8__CHEETAH_TRACE_5 1128 -MX6Q_PAD_CSI0_DAT9__IPU1_CSI0_D_9 1129 -MX6Q_PAD_CSI0_DAT9__WEIM_WEIM_D_7 1130 -MX6Q_PAD_CSI0_DAT9__ECSPI2_MOSI 1131 -MX6Q_PAD_CSI0_DAT9__KPP_ROW_7 1132 -MX6Q_PAD_CSI0_DAT9__I2C1_SCL 1133 -MX6Q_PAD_CSI0_DAT9__GPIO_5_27 1134 -MX6Q_PAD_CSI0_DAT9__MMDC_MMDC_DEBUG_48 1135 -MX6Q_PAD_CSI0_DAT9__CHEETAH_TRACE_6 1136 -MX6Q_PAD_CSI0_DAT10__IPU1_CSI0_D_10 1137 -MX6Q_PAD_CSI0_DAT10__AUDMUX_AUD3_RXC 1138 -MX6Q_PAD_CSI0_DAT10__ECSPI2_MISO 1139 -MX6Q_PAD_CSI0_DAT10__UART1_TXD 1140 -MX6Q_PAD_CSI0_DAT10__SDMA_DEBUG_PC_4 1141 -MX6Q_PAD_CSI0_DAT10__GPIO_5_28 1142 -MX6Q_PAD_CSI0_DAT10__MMDC_MMDC_DEBUG_33 1143 -MX6Q_PAD_CSI0_DAT10__CHEETAH_TRACE_7 1144 -MX6Q_PAD_CSI0_DAT11__IPU1_CSI0_D_11 1145 -MX6Q_PAD_CSI0_DAT11__AUDMUX_AUD3_RXFS 1146 -MX6Q_PAD_CSI0_DAT11__ECSPI2_SS0 1147 -MX6Q_PAD_CSI0_DAT11__UART1_RXD 1148 -MX6Q_PAD_CSI0_DAT11__SDMA_DEBUG_PC_5 1149 -MX6Q_PAD_CSI0_DAT11__GPIO_5_29 1150 -MX6Q_PAD_CSI0_DAT11__MMDC_MMDC_DEBUG_34 1151 -MX6Q_PAD_CSI0_DAT11__CHEETAH_TRACE_8 1152 -MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12 1153 -MX6Q_PAD_CSI0_DAT12__WEIM_WEIM_D_8 1154 -MX6Q_PAD_CSI0_DAT12__PCIE_CTRL_MUX_16 1155 -MX6Q_PAD_CSI0_DAT12__UART4_TXD 1156 -MX6Q_PAD_CSI0_DAT12__SDMA_DEBUG_PC_6 1157 -MX6Q_PAD_CSI0_DAT12__GPIO_5_30 1158 -MX6Q_PAD_CSI0_DAT12__MMDC_MMDC_DEBUG_35 1159 -MX6Q_PAD_CSI0_DAT12__CHEETAH_TRACE_9 1160 -MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13 1161 -MX6Q_PAD_CSI0_DAT13__WEIM_WEIM_D_9 1162 -MX6Q_PAD_CSI0_DAT13__PCIE_CTRL_MUX_17 1163 -MX6Q_PAD_CSI0_DAT13__UART4_RXD 1164 -MX6Q_PAD_CSI0_DAT13__SDMA_DEBUG_PC_7 1165 -MX6Q_PAD_CSI0_DAT13__GPIO_5_31 1166 -MX6Q_PAD_CSI0_DAT13__MMDC_MMDC_DEBUG_36 1167 -MX6Q_PAD_CSI0_DAT13__CHEETAH_TRACE_10 1168 -MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14 1169 -MX6Q_PAD_CSI0_DAT14__WEIM_WEIM_D_10 1170 -MX6Q_PAD_CSI0_DAT14__PCIE_CTRL_MUX_18 1171 -MX6Q_PAD_CSI0_DAT14__UART5_TXD 1172 -MX6Q_PAD_CSI0_DAT14__SDMA_DEBUG_PC_8 1173 -MX6Q_PAD_CSI0_DAT14__GPIO_6_0 1174 -MX6Q_PAD_CSI0_DAT14__MMDC_MMDC_DEBUG_37 1175 -MX6Q_PAD_CSI0_DAT14__CHEETAH_TRACE_11 1176 -MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15 1177 -MX6Q_PAD_CSI0_DAT15__WEIM_WEIM_D_11 1178 -MX6Q_PAD_CSI0_DAT15__PCIE_CTRL_MUX_19 1179 -MX6Q_PAD_CSI0_DAT15__UART5_RXD 1180 -MX6Q_PAD_CSI0_DAT15__SDMA_DEBUG_PC_9 1181 -MX6Q_PAD_CSI0_DAT15__GPIO_6_1 1182 -MX6Q_PAD_CSI0_DAT15__MMDC_MMDC_DEBUG_38 1183 -MX6Q_PAD_CSI0_DAT15__CHEETAH_TRACE_12 1184 -MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16 1185 -MX6Q_PAD_CSI0_DAT16__WEIM_WEIM_D_12 1186 -MX6Q_PAD_CSI0_DAT16__PCIE_CTRL_MUX_20 1187 -MX6Q_PAD_CSI0_DAT16__UART4_RTS 1188 -MX6Q_PAD_CSI0_DAT16__SDMA_DEBUG_PC_10 1189 -MX6Q_PAD_CSI0_DAT16__GPIO_6_2 1190 -MX6Q_PAD_CSI0_DAT16__MMDC_MMDC_DEBUG_39 1191 -MX6Q_PAD_CSI0_DAT16__CHEETAH_TRACE_13 1192 -MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17 1193 -MX6Q_PAD_CSI0_DAT17__WEIM_WEIM_D_13 1194 -MX6Q_PAD_CSI0_DAT17__PCIE_CTRL_MUX_21 1195 -MX6Q_PAD_CSI0_DAT17__UART4_CTS 1196 -MX6Q_PAD_CSI0_DAT17__SDMA_DEBUG_PC_11 1197 -MX6Q_PAD_CSI0_DAT17__GPIO_6_3 1198 -MX6Q_PAD_CSI0_DAT17__MMDC_MMDC_DEBUG_40 1199 -MX6Q_PAD_CSI0_DAT17__CHEETAH_TRACE_14 1200 -MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18 1201 -MX6Q_PAD_CSI0_DAT18__WEIM_WEIM_D_14 1202 -MX6Q_PAD_CSI0_DAT18__PCIE_CTRL_MUX_22 1203 -MX6Q_PAD_CSI0_DAT18__UART5_RTS 1204 -MX6Q_PAD_CSI0_DAT18__SDMA_DEBUG_PC_12 1205 -MX6Q_PAD_CSI0_DAT18__GPIO_6_4 1206 -MX6Q_PAD_CSI0_DAT18__MMDC_MMDC_DEBUG_41 1207 -MX6Q_PAD_CSI0_DAT18__CHEETAH_TRACE_15 1208 -MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19 1209 -MX6Q_PAD_CSI0_DAT19__WEIM_WEIM_D_15 1210 -MX6Q_PAD_CSI0_DAT19__PCIE_CTRL_MUX_23 1211 -MX6Q_PAD_CSI0_DAT19__UART5_CTS 1212 -MX6Q_PAD_CSI0_DAT19__SDMA_DEBUG_PC_13 1213 -MX6Q_PAD_CSI0_DAT19__GPIO_6_5 1214 -MX6Q_PAD_CSI0_DAT19__MMDC_MMDC_DEBUG_42 1215 -MX6Q_PAD_CSI0_DAT19__ANATOP_TESTO_9 1216 -MX6Q_PAD_JTAG_TMS__SJC_TMS 1217 -MX6Q_PAD_JTAG_MOD__SJC_MOD 1218 -MX6Q_PAD_JTAG_TRSTB__SJC_TRSTB 1219 -MX6Q_PAD_JTAG_TDI__SJC_TDI 1220 -MX6Q_PAD_JTAG_TCK__SJC_TCK 1221 -MX6Q_PAD_JTAG_TDO__SJC_TDO 1222 -MX6Q_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3 1223 -MX6Q_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2 1224 -MX6Q_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK 1225 -MX6Q_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1 1226 -MX6Q_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0 1227 -MX6Q_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3 1228 -MX6Q_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK 1229 -MX6Q_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2 1230 -MX6Q_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1 1231 -MX6Q_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0 1232 -MX6Q_PAD_TAMPER__SNVS_LP_WRAP_SNVS_TD1 1233 -MX6Q_PAD_PMIC_ON_REQ__SNVS_LPWRAP_WKALM 1234 -MX6Q_PAD_PMIC_STBY_REQ__CCM_PMIC_STBYRQ 1235 -MX6Q_PAD_POR_B__SRC_POR_B 1236 -MX6Q_PAD_BOOT_MODE1__SRC_BOOT_MODE_1 1237 -MX6Q_PAD_RESET_IN_B__SRC_RESET_B 1238 -MX6Q_PAD_BOOT_MODE0__SRC_BOOT_MODE_0 1239 -MX6Q_PAD_TEST_MODE__TCU_TEST_MODE 1240 -MX6Q_PAD_SD3_DAT7__USDHC3_DAT7 1241 -MX6Q_PAD_SD3_DAT7__UART1_TXD 1242 -MX6Q_PAD_SD3_DAT7__PCIE_CTRL_MUX_24 1243 -MX6Q_PAD_SD3_DAT7__USBOH3_UH3_DFD_OUT_0 1244 -MX6Q_PAD_SD3_DAT7__USBOH3_UH2_DFD_OUT_0 1245 -MX6Q_PAD_SD3_DAT7__GPIO_6_17 1246 -MX6Q_PAD_SD3_DAT7__MIPI_CORE_DPHY_IN_12 1247 -MX6Q_PAD_SD3_DAT7__USBPHY2_CLK20DIV 1248 -MX6Q_PAD_SD3_DAT6__USDHC3_DAT6 1249 -MX6Q_PAD_SD3_DAT6__UART1_RXD 1250 -MX6Q_PAD_SD3_DAT6__PCIE_CTRL_MUX_25 1251 -MX6Q_PAD_SD3_DAT6__USBOH3_UH3_DFD_OUT_1 1252 -MX6Q_PAD_SD3_DAT6__USBOH3_UH2_DFD_OUT_1 1253 -MX6Q_PAD_SD3_DAT6__GPIO_6_18 1254 -MX6Q_PAD_SD3_DAT6__MIPI_CORE_DPHY_IN_13 1255 -MX6Q_PAD_SD3_DAT6__ANATOP_TESTO_10 1256 -MX6Q_PAD_SD3_DAT5__USDHC3_DAT5 1257 -MX6Q_PAD_SD3_DAT5__UART2_TXD 1258 -MX6Q_PAD_SD3_DAT5__PCIE_CTRL_MUX_26 1259 -MX6Q_PAD_SD3_DAT5__USBOH3_UH3_DFD_OUT_2 1260 -MX6Q_PAD_SD3_DAT5__USBOH3_UH2_DFD_OUT_2 1261 -MX6Q_PAD_SD3_DAT5__GPIO_7_0 1262 -MX6Q_PAD_SD3_DAT5__MIPI_CORE_DPHY_IN_14 1263 -MX6Q_PAD_SD3_DAT5__ANATOP_TESTO_11 1264 -MX6Q_PAD_SD3_DAT4__USDHC3_DAT4 1265 -MX6Q_PAD_SD3_DAT4__UART2_RXD 1266 -MX6Q_PAD_SD3_DAT4__PCIE_CTRL_MUX_27 1267 -MX6Q_PAD_SD3_DAT4__USBOH3_UH3_DFD_OUT_3 1268 -MX6Q_PAD_SD3_DAT4__USBOH3_UH2_DFD_OUT_3 1269 -MX6Q_PAD_SD3_DAT4__GPIO_7_1 1270 -MX6Q_PAD_SD3_DAT4__MIPI_CORE_DPHY_IN_15 1271 -MX6Q_PAD_SD3_DAT4__ANATOP_TESTO_12 1272 -MX6Q_PAD_SD3_CMD__USDHC3_CMD 1273 -MX6Q_PAD_SD3_CMD__UART2_CTS 1274 -MX6Q_PAD_SD3_CMD__CAN1_TXCAN 1275 -MX6Q_PAD_SD3_CMD__USBOH3_UH3_DFD_OUT_4 1276 -MX6Q_PAD_SD3_CMD__USBOH3_UH2_DFD_OUT_4 1277 -MX6Q_PAD_SD3_CMD__GPIO_7_2 1278 -MX6Q_PAD_SD3_CMD__MIPI_CORE_DPHY_IN_16 1279 -MX6Q_PAD_SD3_CMD__ANATOP_TESTO_13 1280 -MX6Q_PAD_SD3_CLK__USDHC3_CLK 1281 -MX6Q_PAD_SD3_CLK__UART2_RTS 1282 -MX6Q_PAD_SD3_CLK__CAN1_RXCAN 1283 -MX6Q_PAD_SD3_CLK__USBOH3_UH3_DFD_OUT_5 1284 -MX6Q_PAD_SD3_CLK__USBOH3_UH2_DFD_OUT_5 1285 -MX6Q_PAD_SD3_CLK__GPIO_7_3 1286 -MX6Q_PAD_SD3_CLK__MIPI_CORE_DPHY_IN_17 1287 -MX6Q_PAD_SD3_CLK__ANATOP_TESTO_14 1288 -MX6Q_PAD_SD3_DAT0__USDHC3_DAT0 1289 -MX6Q_PAD_SD3_DAT0__UART1_CTS 1290 -MX6Q_PAD_SD3_DAT0__CAN2_TXCAN 1291 -MX6Q_PAD_SD3_DAT0__USBOH3_UH3_DFD_OUT_6 1292 -MX6Q_PAD_SD3_DAT0__USBOH3_UH2_DFD_OUT_6 1293 -MX6Q_PAD_SD3_DAT0__GPIO_7_4 1294 -MX6Q_PAD_SD3_DAT0__MIPI_CORE_DPHY_IN_18 1295 -MX6Q_PAD_SD3_DAT0__ANATOP_TESTO_15 1296 -MX6Q_PAD_SD3_DAT1__USDHC3_DAT1 1297 -MX6Q_PAD_SD3_DAT1__UART1_RTS 1298 -MX6Q_PAD_SD3_DAT1__CAN2_RXCAN 1299 -MX6Q_PAD_SD3_DAT1__USBOH3_UH3_DFD_OUT_7 1300 -MX6Q_PAD_SD3_DAT1__USBOH3_UH2_DFD_OUT_7 1301 -MX6Q_PAD_SD3_DAT1__GPIO_7_5 1302 -MX6Q_PAD_SD3_DAT1__MIPI_CORE_DPHY_IN_19 1303 -MX6Q_PAD_SD3_DAT1__ANATOP_TESTI_0 1304 -MX6Q_PAD_SD3_DAT2__USDHC3_DAT2 1305 -MX6Q_PAD_SD3_DAT2__PCIE_CTRL_MUX_28 1306 -MX6Q_PAD_SD3_DAT2__USBOH3_UH3_DFD_OUT_8 1307 -MX6Q_PAD_SD3_DAT2__USBOH3_UH2_DFD_OUT_8 1308 -MX6Q_PAD_SD3_DAT2__GPIO_7_6 1309 -MX6Q_PAD_SD3_DAT2__MIPI_CORE_DPHY_IN_20 1310 -MX6Q_PAD_SD3_DAT2__ANATOP_TESTI_1 1311 -MX6Q_PAD_SD3_DAT3__USDHC3_DAT3 1312 -MX6Q_PAD_SD3_DAT3__UART3_CTS 1313 -MX6Q_PAD_SD3_DAT3__PCIE_CTRL_MUX_29 1314 -MX6Q_PAD_SD3_DAT3__USBOH3_UH3_DFD_OUT_9 1315 -MX6Q_PAD_SD3_DAT3__USBOH3_UH2_DFD_OUT_9 1316 -MX6Q_PAD_SD3_DAT3__GPIO_7_7 1317 -MX6Q_PAD_SD3_DAT3__MIPI_CORE_DPHY_IN_21 1318 -MX6Q_PAD_SD3_DAT3__ANATOP_TESTI_2 1319 -MX6Q_PAD_SD3_RST__USDHC3_RST 1320 -MX6Q_PAD_SD3_RST__UART3_RTS 1321 -MX6Q_PAD_SD3_RST__PCIE_CTRL_MUX_30 1322 -MX6Q_PAD_SD3_RST__USBOH3_UH3_DFD_OUT_10 1323 -MX6Q_PAD_SD3_RST__USBOH3_UH2_DFD_OUT_10 1324 -MX6Q_PAD_SD3_RST__GPIO_7_8 1325 -MX6Q_PAD_SD3_RST__MIPI_CORE_DPHY_IN_22 1326 -MX6Q_PAD_SD3_RST__ANATOP_ANATOP_TESTI_3 1327 -MX6Q_PAD_NANDF_CLE__RAWNAND_CLE 1328 -MX6Q_PAD_NANDF_CLE__IPU2_SISG_4 1329 -MX6Q_PAD_NANDF_CLE__PCIE_CTRL_MUX_31 1330 -MX6Q_PAD_NANDF_CLE__USBOH3_UH3_DFD_OT11 1331 -MX6Q_PAD_NANDF_CLE__USBOH3_UH2_DFD_OT11 1332 -MX6Q_PAD_NANDF_CLE__GPIO_6_7 1333 -MX6Q_PAD_NANDF_CLE__MIPI_CORE_DPHY_IN23 1334 -MX6Q_PAD_NANDF_CLE__TPSMP_HTRANS_0 1335 -MX6Q_PAD_NANDF_ALE__RAWNAND_ALE 1336 -MX6Q_PAD_NANDF_ALE__USDHC4_RST 1337 -MX6Q_PAD_NANDF_ALE__PCIE_CTRL_MUX_0 1338 -MX6Q_PAD_NANDF_ALE__USBOH3_UH3_DFD_OT12 1339 -MX6Q_PAD_NANDF_ALE__USBOH3_UH2_DFD_OT12 1340 -MX6Q_PAD_NANDF_ALE__GPIO_6_8 1341 -MX6Q_PAD_NANDF_ALE__MIPI_CR_DPHY_IN_24 1342 -MX6Q_PAD_NANDF_ALE__TPSMP_HTRANS_1 1343 -MX6Q_PAD_NANDF_WP_B__RAWNAND_RESETN 1344 -MX6Q_PAD_NANDF_WP_B__IPU2_SISG_5 1345 -MX6Q_PAD_NANDF_WP_B__PCIE_CTRL__MUX_1 1346 -MX6Q_PAD_NANDF_WP_B__USBOH3_UH3_DFDOT13 1347 -MX6Q_PAD_NANDF_WP_B__USBOH3_UH2_DFDOT13 1348 -MX6Q_PAD_NANDF_WP_B__GPIO_6_9 1349 -MX6Q_PAD_NANDF_WP_B__MIPI_CR_DPHY_OUT32 1350 -MX6Q_PAD_NANDF_WP_B__PL301_PER1_HSIZE_0 1351 -MX6Q_PAD_NANDF_RB0__RAWNAND_READY0 1352 -MX6Q_PAD_NANDF_RB0__IPU2_DI0_PIN1 1353 -MX6Q_PAD_NANDF_RB0__PCIE_CTRL_MUX_2 1354 -MX6Q_PAD_NANDF_RB0__USBOH3_UH3_DFD_OT14 1355 -MX6Q_PAD_NANDF_RB0__USBOH3_UH2_DFD_OT14 1356 -MX6Q_PAD_NANDF_RB0__GPIO_6_10 1357 -MX6Q_PAD_NANDF_RB0__MIPI_CR_DPHY_OUT_33 1358 -MX6Q_PAD_NANDF_RB0__PL301_PER1_HSIZE_1 1359 -MX6Q_PAD_NANDF_CS0__RAWNAND_CE0N 1360 -MX6Q_PAD_NANDF_CS0__USBOH3_UH3_DFD_OT15 1361 -MX6Q_PAD_NANDF_CS0__USBOH3_UH2_DFD_OT15 1362 -MX6Q_PAD_NANDF_CS0__GPIO_6_11 1363 -MX6Q_PAD_NANDF_CS0__PL301_PER1_HSIZE_2 1364 -MX6Q_PAD_NANDF_CS1__RAWNAND_CE1N 1365 -MX6Q_PAD_NANDF_CS1__USDHC4_VSELECT 1366 -MX6Q_PAD_NANDF_CS1__USDHC3_VSELECT 1367 -MX6Q_PAD_NANDF_CS1__PCIE_CTRL_MUX_3 1368 -MX6Q_PAD_NANDF_CS1__GPIO_6_14 1369 -MX6Q_PAD_NANDF_CS1__PL301_PER1_HRDYOUT 1370 -MX6Q_PAD_NANDF_CS2__RAWNAND_CE2N 1371 -MX6Q_PAD_NANDF_CS2__IPU1_SISG_0 1372 -MX6Q_PAD_NANDF_CS2__ESAI1_TX0 1373 -MX6Q_PAD_NANDF_CS2__WEIM_WEIM_CRE 1374 -MX6Q_PAD_NANDF_CS2__CCM_CLKO2 1375 -MX6Q_PAD_NANDF_CS2__GPIO_6_15 1376 -MX6Q_PAD_NANDF_CS2__IPU2_SISG_0 1377 -MX6Q_PAD_NANDF_CS3__RAWNAND_CE3N 1378 -MX6Q_PAD_NANDF_CS3__IPU1_SISG_1 1379 -MX6Q_PAD_NANDF_CS3__ESAI1_TX1 1380 -MX6Q_PAD_NANDF_CS3__WEIM_WEIM_A_26 1381 -MX6Q_PAD_NANDF_CS3__PCIE_CTRL_MUX_4 1382 -MX6Q_PAD_NANDF_CS3__GPIO_6_16 1383 -MX6Q_PAD_NANDF_CS3__IPU2_SISG_1 1384 -MX6Q_PAD_NANDF_CS3__TPSMP_CLK 1385 -MX6Q_PAD_SD4_CMD__USDHC4_CMD 1386 -MX6Q_PAD_SD4_CMD__RAWNAND_RDN 1387 -MX6Q_PAD_SD4_CMD__UART3_TXD 1388 -MX6Q_PAD_SD4_CMD__PCIE_CTRL_MUX_5 1389 -MX6Q_PAD_SD4_CMD__GPIO_7_9 1390 -MX6Q_PAD_SD4_CMD__TPSMP_HDATA_DIR 1391 -MX6Q_PAD_SD4_CLK__USDHC4_CLK 1392 -MX6Q_PAD_SD4_CLK__RAWNAND_WRN 1393 -MX6Q_PAD_SD4_CLK__UART3_RXD 1394 -MX6Q_PAD_SD4_CLK__PCIE_CTRL_MUX_6 1395 -MX6Q_PAD_SD4_CLK__GPIO_7_10 1396 -MX6Q_PAD_NANDF_D0__RAWNAND_D0 1397 -MX6Q_PAD_NANDF_D0__USDHC1_DAT4 1398 -MX6Q_PAD_NANDF_D0__GPU3D_GPU_DBG_OUT_0 1399 -MX6Q_PAD_NANDF_D0__USBOH3_UH2_DFD_OUT16 1400 -MX6Q_PAD_NANDF_D0__USBOH3_UH3_DFD_OUT16 1401 -MX6Q_PAD_NANDF_D0__GPIO_2_0 1402 -MX6Q_PAD_NANDF_D0__IPU1_IPU_DIAG_BUS_0 1403 -MX6Q_PAD_NANDF_D0__IPU2_IPU_DIAG_BUS_0 1404 -MX6Q_PAD_NANDF_D1__RAWNAND_D1 1405 -MX6Q_PAD_NANDF_D1__USDHC1_DAT5 1406 -MX6Q_PAD_NANDF_D1__GPU3D_GPU_DEBUG_OUT1 1407 -MX6Q_PAD_NANDF_D1__USBOH3_UH2_DFD_OUT17 1408 -MX6Q_PAD_NANDF_D1__USBOH3_UH3_DFD_OUT17 1409 -MX6Q_PAD_NANDF_D1__GPIO_2_1 1410 -MX6Q_PAD_NANDF_D1__IPU1_IPU_DIAG_BUS_1 1411 -MX6Q_PAD_NANDF_D1__IPU2_IPU_DIAG_BUS_1 1412 -MX6Q_PAD_NANDF_D2__RAWNAND_D2 1413 -MX6Q_PAD_NANDF_D2__USDHC1_DAT6 1414 -MX6Q_PAD_NANDF_D2__GPU3D_GPU_DBG_OUT_2 1415 -MX6Q_PAD_NANDF_D2__USBOH3_UH2_DFD_OUT18 1416 -MX6Q_PAD_NANDF_D2__USBOH3_UH3_DFD_OUT18 1417 -MX6Q_PAD_NANDF_D2__GPIO_2_2 1418 -MX6Q_PAD_NANDF_D2__IPU1_IPU_DIAG_BUS_2 1419 -MX6Q_PAD_NANDF_D2__IPU2_IPU_DIAG_BUS_2 1420 -MX6Q_PAD_NANDF_D3__RAWNAND_D3 1421 -MX6Q_PAD_NANDF_D3__USDHC1_DAT7 1422 -MX6Q_PAD_NANDF_D3__GPU3D_GPU_DBG_OUT_3 1423 -MX6Q_PAD_NANDF_D3__USBOH3_UH2_DFD_OUT19 1424 -MX6Q_PAD_NANDF_D3__USBOH3_UH3_DFD_OUT19 1425 -MX6Q_PAD_NANDF_D3__GPIO_2_3 1426 -MX6Q_PAD_NANDF_D3__IPU1_IPU_DIAG_BUS_3 1427 -MX6Q_PAD_NANDF_D3__IPU2_IPU_DIAG_BUS_3 1428 -MX6Q_PAD_NANDF_D4__RAWNAND_D4 1429 -MX6Q_PAD_NANDF_D4__USDHC2_DAT4 1430 -MX6Q_PAD_NANDF_D4__GPU3D_GPU_DBG_OUT_4 1431 -MX6Q_PAD_NANDF_D4__USBOH3_UH2_DFD_OUT20 1432 -MX6Q_PAD_NANDF_D4__USBOH3_UH3_DFD_OUT20 1433 -MX6Q_PAD_NANDF_D4__GPIO_2_4 1434 -MX6Q_PAD_NANDF_D4__IPU1_IPU_DIAG_BUS_4 1435 -MX6Q_PAD_NANDF_D4__IPU2_IPU_DIAG_BUS_4 1436 -MX6Q_PAD_NANDF_D5__RAWNAND_D5 1437 -MX6Q_PAD_NANDF_D5__USDHC2_DAT5 1438 -MX6Q_PAD_NANDF_D5__GPU3D_GPU_DBG_OUT_5 1439 -MX6Q_PAD_NANDF_D5__USBOH3_UH2_DFD_OUT21 1440 -MX6Q_PAD_NANDF_D5__USBOH3_UH3_DFD_OUT21 1441 -MX6Q_PAD_NANDF_D5__GPIO_2_5 1442 -MX6Q_PAD_NANDF_D5__IPU1_IPU_DIAG_BUS_5 1443 -MX6Q_PAD_NANDF_D5__IPU2_IPU_DIAG_BUS_5 1444 -MX6Q_PAD_NANDF_D6__RAWNAND_D6 1445 -MX6Q_PAD_NANDF_D6__USDHC2_DAT6 1446 -MX6Q_PAD_NANDF_D6__GPU3D_GPU_DBG_OUT_6 1447 -MX6Q_PAD_NANDF_D6__USBOH3_UH2_DFD_OUT22 1448 -MX6Q_PAD_NANDF_D6__USBOH3_UH3_DFD_OUT22 1449 -MX6Q_PAD_NANDF_D6__GPIO_2_6 1450 -MX6Q_PAD_NANDF_D6__IPU1_IPU_DIAG_BUS_6 1451 -MX6Q_PAD_NANDF_D6__IPU2_IPU_DIAG_BUS_6 1452 -MX6Q_PAD_NANDF_D7__RAWNAND_D7 1453 -MX6Q_PAD_NANDF_D7__USDHC2_DAT7 1454 -MX6Q_PAD_NANDF_D7__GPU3D_GPU_DBG_OUT_7 1455 -MX6Q_PAD_NANDF_D7__USBOH3_UH2_DFD_OUT23 1456 -MX6Q_PAD_NANDF_D7__USBOH3_UH3_DFD_OUT23 1457 -MX6Q_PAD_NANDF_D7__GPIO_2_7 1458 -MX6Q_PAD_NANDF_D7__IPU1_IPU_DIAG_BUS_7 1459 -MX6Q_PAD_NANDF_D7__IPU2_IPU_DIAG_BUS_7 1460 -MX6Q_PAD_SD4_DAT0__RAWNAND_D8 1461 -MX6Q_PAD_SD4_DAT0__USDHC4_DAT0 1462 -MX6Q_PAD_SD4_DAT0__RAWNAND_DQS 1463 -MX6Q_PAD_SD4_DAT0__USBOH3_UH2_DFD_OUT24 1464 -MX6Q_PAD_SD4_DAT0__USBOH3_UH3_DFD_OUT24 1465 -MX6Q_PAD_SD4_DAT0__GPIO_2_8 1466 -MX6Q_PAD_SD4_DAT0__IPU1_IPU_DIAG_BUS_8 1467 -MX6Q_PAD_SD4_DAT0__IPU2_IPU_DIAG_BUS_8 1468 -MX6Q_PAD_SD4_DAT1__RAWNAND_D9 1469 -MX6Q_PAD_SD4_DAT1__USDHC4_DAT1 1470 -MX6Q_PAD_SD4_DAT1__PWM3_PWMO 1471 -MX6Q_PAD_SD4_DAT1__USBOH3_UH2_DFD_OUT25 1472 -MX6Q_PAD_SD4_DAT1__USBOH3_UH3_DFD_OUT25 1473 -MX6Q_PAD_SD4_DAT1__GPIO_2_9 1474 -MX6Q_PAD_SD4_DAT1__IPU1_IPU_DIAG_BUS_9 1475 -MX6Q_PAD_SD4_DAT1__IPU2_IPU_DIAG_BUS_9 1476 -MX6Q_PAD_SD4_DAT2__RAWNAND_D10 1477 -MX6Q_PAD_SD4_DAT2__USDHC4_DAT2 1478 -MX6Q_PAD_SD4_DAT2__PWM4_PWMO 1479 -MX6Q_PAD_SD4_DAT2__USBOH3_UH2_DFD_OUT26 1480 -MX6Q_PAD_SD4_DAT2__USBOH3_UH3_DFD_OUT26 1481 -MX6Q_PAD_SD4_DAT2__GPIO_2_10 1482 -MX6Q_PAD_SD4_DAT2__IPU1_IPU_DIAG_BUS_10 1483 -MX6Q_PAD_SD4_DAT2__IPU2_IPU_DIAG_BUS_10 1484 -MX6Q_PAD_SD4_DAT3__RAWNAND_D11 1485 -MX6Q_PAD_SD4_DAT3__USDHC4_DAT3 1486 -MX6Q_PAD_SD4_DAT3__USBOH3_UH2_DFD_OUT27 1487 -MX6Q_PAD_SD4_DAT3__USBOH3_UH3_DFD_OUT27 1488 -MX6Q_PAD_SD4_DAT3__GPIO_2_11 1489 -MX6Q_PAD_SD4_DAT3__IPU1_IPU_DIAG_BUS_11 1490 -MX6Q_PAD_SD4_DAT3__IPU2_IPU_DIAG_BUS_11 1491 -MX6Q_PAD_SD4_DAT4__RAWNAND_D12 1492 -MX6Q_PAD_SD4_DAT4__USDHC4_DAT4 1493 -MX6Q_PAD_SD4_DAT4__UART2_RXD 1494 -MX6Q_PAD_SD4_DAT4__USBOH3_UH2_DFD_OUT28 1495 -MX6Q_PAD_SD4_DAT4__USBOH3_UH3_DFD_OUT28 1496 -MX6Q_PAD_SD4_DAT4__GPIO_2_12 1497 -MX6Q_PAD_SD4_DAT4__IPU1_IPU_DIAG_BUS_12 1498 -MX6Q_PAD_SD4_DAT4__IPU2_IPU_DIAG_BUS_12 1499 -MX6Q_PAD_SD4_DAT5__RAWNAND_D13 1500 -MX6Q_PAD_SD4_DAT5__USDHC4_DAT5 1501 -MX6Q_PAD_SD4_DAT5__UART2_RTS 1502 -MX6Q_PAD_SD4_DAT5__USBOH3_UH2_DFD_OUT29 1503 -MX6Q_PAD_SD4_DAT5__USBOH3_UH3_DFD_OUT29 1504 -MX6Q_PAD_SD4_DAT5__GPIO_2_13 1505 -MX6Q_PAD_SD4_DAT5__IPU1_IPU_DIAG_BUS_13 1506 -MX6Q_PAD_SD4_DAT5__IPU2_IPU_DIAG_BUS_13 1507 -MX6Q_PAD_SD4_DAT6__RAWNAND_D14 1508 -MX6Q_PAD_SD4_DAT6__USDHC4_DAT6 1509 -MX6Q_PAD_SD4_DAT6__UART2_CTS 1510 -MX6Q_PAD_SD4_DAT6__USBOH3_UH2_DFD_OUT30 1511 -MX6Q_PAD_SD4_DAT6__USBOH3_UH3_DFD_OUT30 1512 -MX6Q_PAD_SD4_DAT6__GPIO_2_14 1513 -MX6Q_PAD_SD4_DAT6__IPU1_IPU_DIAG_BUS_14 1514 -MX6Q_PAD_SD4_DAT6__IPU2_IPU_DIAG_BUS_14 1515 -MX6Q_PAD_SD4_DAT7__RAWNAND_D15 1516 -MX6Q_PAD_SD4_DAT7__USDHC4_DAT7 1517 -MX6Q_PAD_SD4_DAT7__UART2_TXD 1518 -MX6Q_PAD_SD4_DAT7__USBOH3_UH2_DFD_OUT31 1519 -MX6Q_PAD_SD4_DAT7__USBOH3_UH3_DFD_OUT31 1520 -MX6Q_PAD_SD4_DAT7__GPIO_2_15 1521 -MX6Q_PAD_SD4_DAT7__IPU1_IPU_DIAG_BUS_15 1522 -MX6Q_PAD_SD4_DAT7__IPU2_IPU_DIAG_BUS_15 1523 -MX6Q_PAD_SD1_DAT1__USDHC1_DAT1 1524 -MX6Q_PAD_SD1_DAT1__ECSPI5_SS0 1525 -MX6Q_PAD_SD1_DAT1__PWM3_PWMO 1526 -MX6Q_PAD_SD1_DAT1__GPT_CAPIN2 1527 -MX6Q_PAD_SD1_DAT1__PCIE_CTRL_MUX_7 1528 -MX6Q_PAD_SD1_DAT1__GPIO_1_17 1529 -MX6Q_PAD_SD1_DAT1__HDMI_TX_OPHYDTB_0 1530 -MX6Q_PAD_SD1_DAT1__ANATOP_TESTO_8 1531 -MX6Q_PAD_SD1_DAT0__USDHC1_DAT0 1532 -MX6Q_PAD_SD1_DAT0__ECSPI5_MISO 1533 -MX6Q_PAD_SD1_DAT0__CAAM_WRAP_RNG_OSCOBS 1534 -MX6Q_PAD_SD1_DAT0__GPT_CAPIN1 1535 -MX6Q_PAD_SD1_DAT0__PCIE_CTRL_MUX_8 1536 -MX6Q_PAD_SD1_DAT0__GPIO_1_16 1537 -MX6Q_PAD_SD1_DAT0__HDMI_TX_OPHYDTB_1 1538 -MX6Q_PAD_SD1_DAT0__ANATOP_TESTO_7 1539 -MX6Q_PAD_SD1_DAT3__USDHC1_DAT3 1540 -MX6Q_PAD_SD1_DAT3__ECSPI5_SS2 1541 -MX6Q_PAD_SD1_DAT3__GPT_CMPOUT3 1542 -MX6Q_PAD_SD1_DAT3__PWM1_PWMO 1543 -MX6Q_PAD_SD1_DAT3__WDOG2_WDOG_B 1544 -MX6Q_PAD_SD1_DAT3__GPIO_1_21 1545 -MX6Q_PAD_SD1_DAT3__WDOG2_WDOG_RST_B_DEB 1546 -MX6Q_PAD_SD1_DAT3__ANATOP_TESTO_6 1547 -MX6Q_PAD_SD1_CMD__USDHC1_CMD 1548 -MX6Q_PAD_SD1_CMD__ECSPI5_MOSI 1549 -MX6Q_PAD_SD1_CMD__PWM4_PWMO 1550 -MX6Q_PAD_SD1_CMD__GPT_CMPOUT1 1551 -MX6Q_PAD_SD1_CMD__GPIO_1_18 1552 -MX6Q_PAD_SD1_CMD__ANATOP_TESTO_5 1553 -MX6Q_PAD_SD1_DAT2__USDHC1_DAT2 1554 -MX6Q_PAD_SD1_DAT2__ECSPI5_SS1 1555 -MX6Q_PAD_SD1_DAT2__GPT_CMPOUT2 1556 -MX6Q_PAD_SD1_DAT2__PWM2_PWMO 1557 -MX6Q_PAD_SD1_DAT2__WDOG1_WDOG_B 1558 -MX6Q_PAD_SD1_DAT2__GPIO_1_19 1559 -MX6Q_PAD_SD1_DAT2__WDOG1_WDOG_RST_B_DEB 1560 -MX6Q_PAD_SD1_DAT2__ANATOP_TESTO_4 1561 -MX6Q_PAD_SD1_CLK__USDHC1_CLK 1562 -MX6Q_PAD_SD1_CLK__ECSPI5_SCLK 1563 -MX6Q_PAD_SD1_CLK__OSC32K_32K_OUT 1564 -MX6Q_PAD_SD1_CLK__GPT_CLKIN 1565 -MX6Q_PAD_SD1_CLK__GPIO_1_20 1566 -MX6Q_PAD_SD1_CLK__PHY_DTB_0 1567 -MX6Q_PAD_SD1_CLK__SATA_PHY_DTB_0 1568 -MX6Q_PAD_SD2_CLK__USDHC2_CLK 1569 -MX6Q_PAD_SD2_CLK__ECSPI5_SCLK 1570 -MX6Q_PAD_SD2_CLK__KPP_COL_5 1571 -MX6Q_PAD_SD2_CLK__AUDMUX_AUD4_RXFS 1572 -MX6Q_PAD_SD2_CLK__PCIE_CTRL_MUX_9 1573 -MX6Q_PAD_SD2_CLK__GPIO_1_10 1574 -MX6Q_PAD_SD2_CLK__PHY_DTB_1 1575 -MX6Q_PAD_SD2_CLK__SATA_PHY_DTB_1 1576 -MX6Q_PAD_SD2_CMD__USDHC2_CMD 1577 -MX6Q_PAD_SD2_CMD__ECSPI5_MOSI 1578 -MX6Q_PAD_SD2_CMD__KPP_ROW_5 1579 -MX6Q_PAD_SD2_CMD__AUDMUX_AUD4_RXC 1580 -MX6Q_PAD_SD2_CMD__PCIE_CTRL_MUX_10 1581 -MX6Q_PAD_SD2_CMD__GPIO_1_11 1582 -MX6Q_PAD_SD2_DAT3__USDHC2_DAT3 1583 -MX6Q_PAD_SD2_DAT3__ECSPI5_SS3 1584 -MX6Q_PAD_SD2_DAT3__KPP_COL_6 1585 -MX6Q_PAD_SD2_DAT3__AUDMUX_AUD4_TXC 1586 -MX6Q_PAD_SD2_DAT3__PCIE_CTRL_MUX_11 1587 -MX6Q_PAD_SD2_DAT3__GPIO_1_12 1588 -MX6Q_PAD_SD2_DAT3__SJC_DONE 1589 -MX6Q_PAD_SD2_DAT3__ANATOP_TESTO_3 1590 diff --git a/trunk/Documentation/devicetree/bindings/pinctrl/fsl,mxs-pinctrl.txt b/trunk/Documentation/devicetree/bindings/pinctrl/fsl,mxs-pinctrl.txt deleted file mode 100644 index f7e8e8f4d9a3..000000000000 --- a/trunk/Documentation/devicetree/bindings/pinctrl/fsl,mxs-pinctrl.txt +++ /dev/null @@ -1,918 +0,0 @@ -* Freescale MXS Pin Controller - -The pins controlled by mxs pin controller are organized in banks, each bank -has 32 pins. Each pin has 4 multiplexing functions, and generally, the 4th -function is GPIO. The configuration on the pins includes drive strength, -voltage and pull-up. - -Required properties: -- compatible: "fsl,imx23-pinctrl" or "fsl,imx28-pinctrl" -- reg: Should contain the register physical address and length for the - pin controller. - -Please refer to pinctrl-bindings.txt in this directory for details of the -common pinctrl bindings used by client devices. - -The node of mxs pin controller acts as a container for an arbitrary number of -subnodes. Each of these subnodes represents some desired configuration for -a group of pins, and only affects those parameters that are explicitly listed. -In other words, a subnode that describes a drive strength parameter implies no -information about pull-up. For this reason, even seemingly boolean values are -actually tristates in this binding: unspecified, off, or on. Unspecified is -represented as an absent property, and off/on are represented as integer -values 0 and 1. - -Those subnodes under mxs pin controller node will fall into two categories. -One is to set up a group of pins for a function, both mux selection and pin -configurations, and it's called group node in the binding document. The other -one is to adjust the pin configuration for some particular pins that need a -different configuration than what is defined in group node. The binding -document calls this type of node config node. - -On mxs, there is no hardware pin group. The pin group in this binding only -means a group of pins put together for particular peripheral to work in -particular function, like SSP0 functioning as mmc0-8bit. That said, the -group node should include all the pins needed for one function rather than -having these pins defined in several group nodes. It also means each of -"pinctrl-*" phandle in client device node should only have one group node -pointed in there, while the phandle can have multiple config node referenced -there to adjust configurations for some pins in the group. - -Required subnode-properties: -- fsl,pinmux-ids: An integer array. Each integer in the array specify a pin - with given mux function, with bank, pin and mux packed as below. - - [15..12] : bank number - [11..4] : pin number - [3..0] : mux selection - - This integer with mux selection packed is used as an entity by both group - and config nodes to identify a pin. The mux selection in the integer takes - effects only on group node, and will get ignored by driver with config node, - since config node is only meant to set up pin configurations. - - Valid values for these integers are listed below. - -- reg: Should be the index of the group nodes for same function. This property - is required only for group nodes, and should not be present in any config - nodes. - -Optional subnode-properties: -- fsl,drive-strength: Integer. - 0: 4 mA - 1: 8 mA - 2: 12 mA - 3: 16 mA -- fsl,voltage: Integer. - 0: 1.8 V - 1: 3.3 V -- fsl,pull-up: Integer. - 0: Disable the internal pull-up - 1: Enable the internal pull-up - -Examples: - -pinctrl@80018000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,imx28-pinctrl"; - reg = <0x80018000 2000>; - - mmc0_8bit_pins_a: mmc0-8bit@0 { - reg = <0>; - fsl,pinmux-ids = < - 0x2000 0x2010 0x2020 0x2030 - 0x2040 0x2050 0x2060 0x2070 - 0x2080 0x2090 0x20a0>; - fsl,drive-strength = <1>; - fsl,voltage = <1>; - fsl,pull-up = <1>; - }; - - mmc_cd_cfg: mmc-cd-cfg { - fsl,pinmux-ids = <0x2090>; - fsl,pull-up = <0>; - }; - - mmc_sck_cfg: mmc-sck-cfg { - fsl,pinmux-ids = <0x20a0>; - fsl,drive-strength = <2>; - fsl,pull-up = <0>; - }; -}; - -In this example, group node mmc0-8bit defines a group of pins for mxs SSP0 -to function as a 8-bit mmc device, with 8mA, 3.3V and pull-up configurations -applied on all these pins. And config nodes mmc-cd-cfg and mmc-sck-cfg are -adjusting the configuration for pins card-detection and clock from what group -node mmc0-8bit defines. Only the configuration properties to be adjusted need -to be listed in the config nodes. - -Valid values for i.MX28 pinmux-id: - -pinmux id ------- -- -MX28_PAD_GPMI_D00__GPMI_D0 0x0000 -MX28_PAD_GPMI_D01__GPMI_D1 0x0010 -MX28_PAD_GPMI_D02__GPMI_D2 0x0020 -MX28_PAD_GPMI_D03__GPMI_D3 0x0030 -MX28_PAD_GPMI_D04__GPMI_D4 0x0040 -MX28_PAD_GPMI_D05__GPMI_D5 0x0050 -MX28_PAD_GPMI_D06__GPMI_D6 0x0060 -MX28_PAD_GPMI_D07__GPMI_D7 0x0070 -MX28_PAD_GPMI_CE0N__GPMI_CE0N 0x0100 -MX28_PAD_GPMI_CE1N__GPMI_CE1N 0x0110 -MX28_PAD_GPMI_CE2N__GPMI_CE2N 0x0120 -MX28_PAD_GPMI_CE3N__GPMI_CE3N 0x0130 -MX28_PAD_GPMI_RDY0__GPMI_READY0 0x0140 -MX28_PAD_GPMI_RDY1__GPMI_READY1 0x0150 -MX28_PAD_GPMI_RDY2__GPMI_READY2 0x0160 -MX28_PAD_GPMI_RDY3__GPMI_READY3 0x0170 -MX28_PAD_GPMI_RDN__GPMI_RDN 0x0180 -MX28_PAD_GPMI_WRN__GPMI_WRN 0x0190 -MX28_PAD_GPMI_ALE__GPMI_ALE 0x01a0 -MX28_PAD_GPMI_CLE__GPMI_CLE 0x01b0 -MX28_PAD_GPMI_RESETN__GPMI_RESETN 0x01c0 -MX28_PAD_LCD_D00__LCD_D0 0x1000 -MX28_PAD_LCD_D01__LCD_D1 0x1010 -MX28_PAD_LCD_D02__LCD_D2 0x1020 -MX28_PAD_LCD_D03__LCD_D3 0x1030 -MX28_PAD_LCD_D04__LCD_D4 0x1040 -MX28_PAD_LCD_D05__LCD_D5 0x1050 -MX28_PAD_LCD_D06__LCD_D6 0x1060 -MX28_PAD_LCD_D07__LCD_D7 0x1070 -MX28_PAD_LCD_D08__LCD_D8 0x1080 -MX28_PAD_LCD_D09__LCD_D9 0x1090 -MX28_PAD_LCD_D10__LCD_D10 0x10a0 -MX28_PAD_LCD_D11__LCD_D11 0x10b0 -MX28_PAD_LCD_D12__LCD_D12 0x10c0 -MX28_PAD_LCD_D13__LCD_D13 0x10d0 -MX28_PAD_LCD_D14__LCD_D14 0x10e0 -MX28_PAD_LCD_D15__LCD_D15 0x10f0 -MX28_PAD_LCD_D16__LCD_D16 0x1100 -MX28_PAD_LCD_D17__LCD_D17 0x1110 -MX28_PAD_LCD_D18__LCD_D18 0x1120 -MX28_PAD_LCD_D19__LCD_D19 0x1130 -MX28_PAD_LCD_D20__LCD_D20 0x1140 -MX28_PAD_LCD_D21__LCD_D21 0x1150 -MX28_PAD_LCD_D22__LCD_D22 0x1160 -MX28_PAD_LCD_D23__LCD_D23 0x1170 -MX28_PAD_LCD_RD_E__LCD_RD_E 0x1180 -MX28_PAD_LCD_WR_RWN__LCD_WR_RWN 0x1190 -MX28_PAD_LCD_RS__LCD_RS 0x11a0 -MX28_PAD_LCD_CS__LCD_CS 0x11b0 -MX28_PAD_LCD_VSYNC__LCD_VSYNC 0x11c0 -MX28_PAD_LCD_HSYNC__LCD_HSYNC 0x11d0 -MX28_PAD_LCD_DOTCLK__LCD_DOTCLK 0x11e0 -MX28_PAD_LCD_ENABLE__LCD_ENABLE 0x11f0 -MX28_PAD_SSP0_DATA0__SSP0_D0 0x2000 -MX28_PAD_SSP0_DATA1__SSP0_D1 0x2010 -MX28_PAD_SSP0_DATA2__SSP0_D2 0x2020 -MX28_PAD_SSP0_DATA3__SSP0_D3 0x2030 -MX28_PAD_SSP0_DATA4__SSP0_D4 0x2040 -MX28_PAD_SSP0_DATA5__SSP0_D5 0x2050 -MX28_PAD_SSP0_DATA6__SSP0_D6 0x2060 -MX28_PAD_SSP0_DATA7__SSP0_D7 0x2070 -MX28_PAD_SSP0_CMD__SSP0_CMD 0x2080 -MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT 0x2090 -MX28_PAD_SSP0_SCK__SSP0_SCK 0x20a0 -MX28_PAD_SSP1_SCK__SSP1_SCK 0x20c0 -MX28_PAD_SSP1_CMD__SSP1_CMD 0x20d0 -MX28_PAD_SSP1_DATA0__SSP1_D0 0x20e0 -MX28_PAD_SSP1_DATA3__SSP1_D3 0x20f0 -MX28_PAD_SSP2_SCK__SSP2_SCK 0x2100 -MX28_PAD_SSP2_MOSI__SSP2_CMD 0x2110 -MX28_PAD_SSP2_MISO__SSP2_D0 0x2120 -MX28_PAD_SSP2_SS0__SSP2_D3 0x2130 -MX28_PAD_SSP2_SS1__SSP2_D4 0x2140 -MX28_PAD_SSP2_SS2__SSP2_D5 0x2150 -MX28_PAD_SSP3_SCK__SSP3_SCK 0x2180 -MX28_PAD_SSP3_MOSI__SSP3_CMD 0x2190 -MX28_PAD_SSP3_MISO__SSP3_D0 0x21a0 -MX28_PAD_SSP3_SS0__SSP3_D3 0x21b0 -MX28_PAD_AUART0_RX__AUART0_RX 0x3000 -MX28_PAD_AUART0_TX__AUART0_TX 0x3010 -MX28_PAD_AUART0_CTS__AUART0_CTS 0x3020 -MX28_PAD_AUART0_RTS__AUART0_RTS 0x3030 -MX28_PAD_AUART1_RX__AUART1_RX 0x3040 -MX28_PAD_AUART1_TX__AUART1_TX 0x3050 -MX28_PAD_AUART1_CTS__AUART1_CTS 0x3060 -MX28_PAD_AUART1_RTS__AUART1_RTS 0x3070 -MX28_PAD_AUART2_RX__AUART2_RX 0x3080 -MX28_PAD_AUART2_TX__AUART2_TX 0x3090 -MX28_PAD_AUART2_CTS__AUART2_CTS 0x30a0 -MX28_PAD_AUART2_RTS__AUART2_RTS 0x30b0 -MX28_PAD_AUART3_RX__AUART3_RX 0x30c0 -MX28_PAD_AUART3_TX__AUART3_TX 0x30d0 -MX28_PAD_AUART3_CTS__AUART3_CTS 0x30e0 -MX28_PAD_AUART3_RTS__AUART3_RTS 0x30f0 -MX28_PAD_PWM0__PWM_0 0x3100 -MX28_PAD_PWM1__PWM_1 0x3110 -MX28_PAD_PWM2__PWM_2 0x3120 -MX28_PAD_SAIF0_MCLK__SAIF0_MCLK 0x3140 -MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK 0x3150 -MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK 0x3160 -MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0 0x3170 -MX28_PAD_I2C0_SCL__I2C0_SCL 0x3180 -MX28_PAD_I2C0_SDA__I2C0_SDA 0x3190 -MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0 0x31a0 -MX28_PAD_SPDIF__SPDIF_TX 0x31b0 -MX28_PAD_PWM3__PWM_3 0x31c0 -MX28_PAD_PWM4__PWM_4 0x31d0 -MX28_PAD_LCD_RESET__LCD_RESET 0x31e0 -MX28_PAD_ENET0_MDC__ENET0_MDC 0x4000 -MX28_PAD_ENET0_MDIO__ENET0_MDIO 0x4010 -MX28_PAD_ENET0_RX_EN__ENET0_RX_EN 0x4020 -MX28_PAD_ENET0_RXD0__ENET0_RXD0 0x4030 -MX28_PAD_ENET0_RXD1__ENET0_RXD1 0x4040 -MX28_PAD_ENET0_TX_CLK__ENET0_TX_CLK 0x4050 -MX28_PAD_ENET0_TX_EN__ENET0_TX_EN 0x4060 -MX28_PAD_ENET0_TXD0__ENET0_TXD0 0x4070 -MX28_PAD_ENET0_TXD1__ENET0_TXD1 0x4080 -MX28_PAD_ENET0_RXD2__ENET0_RXD2 0x4090 -MX28_PAD_ENET0_RXD3__ENET0_RXD3 0x40a0 -MX28_PAD_ENET0_TXD2__ENET0_TXD2 0x40b0 -MX28_PAD_ENET0_TXD3__ENET0_TXD3 0x40c0 -MX28_PAD_ENET0_RX_CLK__ENET0_RX_CLK 0x40d0 -MX28_PAD_ENET0_COL__ENET0_COL 0x40e0 -MX28_PAD_ENET0_CRS__ENET0_CRS 0x40f0 -MX28_PAD_ENET_CLK__CLKCTRL_ENET 0x4100 -MX28_PAD_JTAG_RTCK__JTAG_RTCK 0x4140 -MX28_PAD_EMI_D00__EMI_DATA0 0x5000 -MX28_PAD_EMI_D01__EMI_DATA1 0x5010 -MX28_PAD_EMI_D02__EMI_DATA2 0x5020 -MX28_PAD_EMI_D03__EMI_DATA3 0x5030 -MX28_PAD_EMI_D04__EMI_DATA4 0x5040 -MX28_PAD_EMI_D05__EMI_DATA5 0x5050 -MX28_PAD_EMI_D06__EMI_DATA6 0x5060 -MX28_PAD_EMI_D07__EMI_DATA7 0x5070 -MX28_PAD_EMI_D08__EMI_DATA8 0x5080 -MX28_PAD_EMI_D09__EMI_DATA9 0x5090 -MX28_PAD_EMI_D10__EMI_DATA10 0x50a0 -MX28_PAD_EMI_D11__EMI_DATA11 0x50b0 -MX28_PAD_EMI_D12__EMI_DATA12 0x50c0 -MX28_PAD_EMI_D13__EMI_DATA13 0x50d0 -MX28_PAD_EMI_D14__EMI_DATA14 0x50e0 -MX28_PAD_EMI_D15__EMI_DATA15 0x50f0 -MX28_PAD_EMI_ODT0__EMI_ODT0 0x5100 -MX28_PAD_EMI_DQM0__EMI_DQM0 0x5110 -MX28_PAD_EMI_ODT1__EMI_ODT1 0x5120 -MX28_PAD_EMI_DQM1__EMI_DQM1 0x5130 -MX28_PAD_EMI_DDR_OPEN_FB__EMI_DDR_OPEN_FEEDBACK 0x5140 -MX28_PAD_EMI_CLK__EMI_CLK 0x5150 -MX28_PAD_EMI_DQS0__EMI_DQS0 0x5160 -MX28_PAD_EMI_DQS1__EMI_DQS1 0x5170 -MX28_PAD_EMI_DDR_OPEN__EMI_DDR_OPEN 0x51a0 -MX28_PAD_EMI_A00__EMI_ADDR0 0x6000 -MX28_PAD_EMI_A01__EMI_ADDR1 0x6010 -MX28_PAD_EMI_A02__EMI_ADDR2 0x6020 -MX28_PAD_EMI_A03__EMI_ADDR3 0x6030 -MX28_PAD_EMI_A04__EMI_ADDR4 0x6040 -MX28_PAD_EMI_A05__EMI_ADDR5 0x6050 -MX28_PAD_EMI_A06__EMI_ADDR6 0x6060 -MX28_PAD_EMI_A07__EMI_ADDR7 0x6070 -MX28_PAD_EMI_A08__EMI_ADDR8 0x6080 -MX28_PAD_EMI_A09__EMI_ADDR9 0x6090 -MX28_PAD_EMI_A10__EMI_ADDR10 0x60a0 -MX28_PAD_EMI_A11__EMI_ADDR11 0x60b0 -MX28_PAD_EMI_A12__EMI_ADDR12 0x60c0 -MX28_PAD_EMI_A13__EMI_ADDR13 0x60d0 -MX28_PAD_EMI_A14__EMI_ADDR14 0x60e0 -MX28_PAD_EMI_BA0__EMI_BA0 0x6100 -MX28_PAD_EMI_BA1__EMI_BA1 0x6110 -MX28_PAD_EMI_BA2__EMI_BA2 0x6120 -MX28_PAD_EMI_CASN__EMI_CASN 0x6130 -MX28_PAD_EMI_RASN__EMI_RASN 0x6140 -MX28_PAD_EMI_WEN__EMI_WEN 0x6150 -MX28_PAD_EMI_CE0N__EMI_CE0N 0x6160 -MX28_PAD_EMI_CE1N__EMI_CE1N 0x6170 -MX28_PAD_EMI_CKE__EMI_CKE 0x6180 -MX28_PAD_GPMI_D00__SSP1_D0 0x0001 -MX28_PAD_GPMI_D01__SSP1_D1 0x0011 -MX28_PAD_GPMI_D02__SSP1_D2 0x0021 -MX28_PAD_GPMI_D03__SSP1_D3 0x0031 -MX28_PAD_GPMI_D04__SSP1_D4 0x0041 -MX28_PAD_GPMI_D05__SSP1_D5 0x0051 -MX28_PAD_GPMI_D06__SSP1_D6 0x0061 -MX28_PAD_GPMI_D07__SSP1_D7 0x0071 -MX28_PAD_GPMI_CE0N__SSP3_D0 0x0101 -MX28_PAD_GPMI_CE1N__SSP3_D3 0x0111 -MX28_PAD_GPMI_CE2N__CAN1_TX 0x0121 -MX28_PAD_GPMI_CE3N__CAN1_RX 0x0131 -MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT 0x0141 -MX28_PAD_GPMI_RDY1__SSP1_CMD 0x0151 -MX28_PAD_GPMI_RDY2__CAN0_TX 0x0161 -MX28_PAD_GPMI_RDY3__CAN0_RX 0x0171 -MX28_PAD_GPMI_RDN__SSP3_SCK 0x0181 -MX28_PAD_GPMI_WRN__SSP1_SCK 0x0191 -MX28_PAD_GPMI_ALE__SSP3_D1 0x01a1 -MX28_PAD_GPMI_CLE__SSP3_D2 0x01b1 -MX28_PAD_GPMI_RESETN__SSP3_CMD 0x01c1 -MX28_PAD_LCD_D03__ETM_DA8 0x1031 -MX28_PAD_LCD_D04__ETM_DA9 0x1041 -MX28_PAD_LCD_D08__ETM_DA3 0x1081 -MX28_PAD_LCD_D09__ETM_DA4 0x1091 -MX28_PAD_LCD_D20__ENET1_1588_EVENT2_OUT 0x1141 -MX28_PAD_LCD_D21__ENET1_1588_EVENT2_IN 0x1151 -MX28_PAD_LCD_D22__ENET1_1588_EVENT3_OUT 0x1161 -MX28_PAD_LCD_D23__ENET1_1588_EVENT3_IN 0x1171 -MX28_PAD_LCD_RD_E__LCD_VSYNC 0x1181 -MX28_PAD_LCD_WR_RWN__LCD_HSYNC 0x1191 -MX28_PAD_LCD_RS__LCD_DOTCLK 0x11a1 -MX28_PAD_LCD_CS__LCD_ENABLE 0x11b1 -MX28_PAD_LCD_VSYNC__SAIF1_SDATA0 0x11c1 -MX28_PAD_LCD_HSYNC__SAIF1_SDATA1 0x11d1 -MX28_PAD_LCD_DOTCLK__SAIF1_MCLK 0x11e1 -MX28_PAD_SSP0_DATA4__SSP2_D0 0x2041 -MX28_PAD_SSP0_DATA5__SSP2_D3 0x2051 -MX28_PAD_SSP0_DATA6__SSP2_CMD 0x2061 -MX28_PAD_SSP0_DATA7__SSP2_SCK 0x2071 -MX28_PAD_SSP1_SCK__SSP2_D1 0x20c1 -MX28_PAD_SSP1_CMD__SSP2_D2 0x20d1 -MX28_PAD_SSP1_DATA0__SSP2_D6 0x20e1 -MX28_PAD_SSP1_DATA3__SSP2_D7 0x20f1 -MX28_PAD_SSP2_SCK__AUART2_RX 0x2101 -MX28_PAD_SSP2_MOSI__AUART2_TX 0x2111 -MX28_PAD_SSP2_MISO__AUART3_RX 0x2121 -MX28_PAD_SSP2_SS0__AUART3_TX 0x2131 -MX28_PAD_SSP2_SS1__SSP2_D1 0x2141 -MX28_PAD_SSP2_SS2__SSP2_D2 0x2151 -MX28_PAD_SSP3_SCK__AUART4_TX 0x2181 -MX28_PAD_SSP3_MOSI__AUART4_RX 0x2191 -MX28_PAD_SSP3_MISO__AUART4_RTS 0x21a1 -MX28_PAD_SSP3_SS0__AUART4_CTS 0x21b1 -MX28_PAD_AUART0_RX__I2C0_SCL 0x3001 -MX28_PAD_AUART0_TX__I2C0_SDA 0x3011 -MX28_PAD_AUART0_CTS__AUART4_RX 0x3021 -MX28_PAD_AUART0_RTS__AUART4_TX 0x3031 -MX28_PAD_AUART1_RX__SSP2_CARD_DETECT 0x3041 -MX28_PAD_AUART1_TX__SSP3_CARD_DETECT 0x3051 -MX28_PAD_AUART1_CTS__USB0_OVERCURRENT 0x3061 -MX28_PAD_AUART1_RTS__USB0_ID 0x3071 -MX28_PAD_AUART2_RX__SSP3_D1 0x3081 -MX28_PAD_AUART2_TX__SSP3_D2 0x3091 -MX28_PAD_AUART2_CTS__I2C1_SCL 0x30a1 -MX28_PAD_AUART2_RTS__I2C1_SDA 0x30b1 -MX28_PAD_AUART3_RX__CAN0_TX 0x30c1 -MX28_PAD_AUART3_TX__CAN0_RX 0x30d1 -MX28_PAD_AUART3_CTS__CAN1_TX 0x30e1 -MX28_PAD_AUART3_RTS__CAN1_RX 0x30f1 -MX28_PAD_PWM0__I2C1_SCL 0x3101 -MX28_PAD_PWM1__I2C1_SDA 0x3111 -MX28_PAD_PWM2__USB0_ID 0x3121 -MX28_PAD_SAIF0_MCLK__PWM_3 0x3141 -MX28_PAD_SAIF0_LRCLK__PWM_4 0x3151 -MX28_PAD_SAIF0_BITCLK__PWM_5 0x3161 -MX28_PAD_SAIF0_SDATA0__PWM_6 0x3171 -MX28_PAD_I2C0_SCL__TIMROT_ROTARYA 0x3181 -MX28_PAD_I2C0_SDA__TIMROT_ROTARYB 0x3191 -MX28_PAD_SAIF1_SDATA0__PWM_7 0x31a1 -MX28_PAD_LCD_RESET__LCD_VSYNC 0x31e1 -MX28_PAD_ENET0_MDC__GPMI_CE4N 0x4001 -MX28_PAD_ENET0_MDIO__GPMI_CE5N 0x4011 -MX28_PAD_ENET0_RX_EN__GPMI_CE6N 0x4021 -MX28_PAD_ENET0_RXD0__GPMI_CE7N 0x4031 -MX28_PAD_ENET0_RXD1__GPMI_READY4 0x4041 -MX28_PAD_ENET0_TX_CLK__HSADC_TRIGGER 0x4051 -MX28_PAD_ENET0_TX_EN__GPMI_READY5 0x4061 -MX28_PAD_ENET0_TXD0__GPMI_READY6 0x4071 -MX28_PAD_ENET0_TXD1__GPMI_READY7 0x4081 -MX28_PAD_ENET0_RXD2__ENET1_RXD0 0x4091 -MX28_PAD_ENET0_RXD3__ENET1_RXD1 0x40a1 -MX28_PAD_ENET0_TXD2__ENET1_TXD0 0x40b1 -MX28_PAD_ENET0_TXD3__ENET1_TXD1 0x40c1 -MX28_PAD_ENET0_RX_CLK__ENET0_RX_ER 0x40d1 -MX28_PAD_ENET0_COL__ENET1_TX_EN 0x40e1 -MX28_PAD_ENET0_CRS__ENET1_RX_EN 0x40f1 -MX28_PAD_GPMI_CE2N__ENET0_RX_ER 0x0122 -MX28_PAD_GPMI_CE3N__SAIF1_MCLK 0x0132 -MX28_PAD_GPMI_RDY0__USB0_ID 0x0142 -MX28_PAD_GPMI_RDY2__ENET0_TX_ER 0x0162 -MX28_PAD_GPMI_RDY3__HSADC_TRIGGER 0x0172 -MX28_PAD_GPMI_ALE__SSP3_D4 0x01a2 -MX28_PAD_GPMI_CLE__SSP3_D5 0x01b2 -MX28_PAD_LCD_D00__ETM_DA0 0x1002 -MX28_PAD_LCD_D01__ETM_DA1 0x1012 -MX28_PAD_LCD_D02__ETM_DA2 0x1022 -MX28_PAD_LCD_D03__ETM_DA3 0x1032 -MX28_PAD_LCD_D04__ETM_DA4 0x1042 -MX28_PAD_LCD_D05__ETM_DA5 0x1052 -MX28_PAD_LCD_D06__ETM_DA6 0x1062 -MX28_PAD_LCD_D07__ETM_DA7 0x1072 -MX28_PAD_LCD_D08__ETM_DA8 0x1082 -MX28_PAD_LCD_D09__ETM_DA9 0x1092 -MX28_PAD_LCD_D10__ETM_DA10 0x10a2 -MX28_PAD_LCD_D11__ETM_DA11 0x10b2 -MX28_PAD_LCD_D12__ETM_DA12 0x10c2 -MX28_PAD_LCD_D13__ETM_DA13 0x10d2 -MX28_PAD_LCD_D14__ETM_DA14 0x10e2 -MX28_PAD_LCD_D15__ETM_DA15 0x10f2 -MX28_PAD_LCD_D16__ETM_DA7 0x1102 -MX28_PAD_LCD_D17__ETM_DA6 0x1112 -MX28_PAD_LCD_D18__ETM_DA5 0x1122 -MX28_PAD_LCD_D19__ETM_DA4 0x1132 -MX28_PAD_LCD_D20__ETM_DA3 0x1142 -MX28_PAD_LCD_D21__ETM_DA2 0x1152 -MX28_PAD_LCD_D22__ETM_DA1 0x1162 -MX28_PAD_LCD_D23__ETM_DA0 0x1172 -MX28_PAD_LCD_RD_E__ETM_TCTL 0x1182 -MX28_PAD_LCD_WR_RWN__ETM_TCLK 0x1192 -MX28_PAD_LCD_HSYNC__ETM_TCTL 0x11d2 -MX28_PAD_LCD_DOTCLK__ETM_TCLK 0x11e2 -MX28_PAD_SSP1_SCK__ENET0_1588_EVENT2_OUT 0x20c2 -MX28_PAD_SSP1_CMD__ENET0_1588_EVENT2_IN 0x20d2 -MX28_PAD_SSP1_DATA0__ENET0_1588_EVENT3_OUT 0x20e2 -MX28_PAD_SSP1_DATA3__ENET0_1588_EVENT3_IN 0x20f2 -MX28_PAD_SSP2_SCK__SAIF0_SDATA1 0x2102 -MX28_PAD_SSP2_MOSI__SAIF0_SDATA2 0x2112 -MX28_PAD_SSP2_MISO__SAIF1_SDATA1 0x2122 -MX28_PAD_SSP2_SS0__SAIF1_SDATA2 0x2132 -MX28_PAD_SSP2_SS1__USB1_OVERCURRENT 0x2142 -MX28_PAD_SSP2_SS2__USB0_OVERCURRENT 0x2152 -MX28_PAD_SSP3_SCK__ENET1_1588_EVENT0_OUT 0x2182 -MX28_PAD_SSP3_MOSI__ENET1_1588_EVENT0_IN 0x2192 -MX28_PAD_SSP3_MISO__ENET1_1588_EVENT1_OUT 0x21a2 -MX28_PAD_SSP3_SS0__ENET1_1588_EVENT1_IN 0x21b2 -MX28_PAD_AUART0_RX__DUART_CTS 0x3002 -MX28_PAD_AUART0_TX__DUART_RTS 0x3012 -MX28_PAD_AUART0_CTS__DUART_RX 0x3022 -MX28_PAD_AUART0_RTS__DUART_TX 0x3032 -MX28_PAD_AUART1_RX__PWM_0 0x3042 -MX28_PAD_AUART1_TX__PWM_1 0x3052 -MX28_PAD_AUART1_CTS__TIMROT_ROTARYA 0x3062 -MX28_PAD_AUART1_RTS__TIMROT_ROTARYB 0x3072 -MX28_PAD_AUART2_RX__SSP3_D4 0x3082 -MX28_PAD_AUART2_TX__SSP3_D5 0x3092 -MX28_PAD_AUART2_CTS__SAIF1_BITCLK 0x30a2 -MX28_PAD_AUART2_RTS__SAIF1_LRCLK 0x30b2 -MX28_PAD_AUART3_RX__ENET0_1588_EVENT0_OUT 0x30c2 -MX28_PAD_AUART3_TX__ENET0_1588_EVENT0_IN 0x30d2 -MX28_PAD_AUART3_CTS__ENET0_1588_EVENT1_OUT 0x30e2 -MX28_PAD_AUART3_RTS__ENET0_1588_EVENT1_IN 0x30f2 -MX28_PAD_PWM0__DUART_RX 0x3102 -MX28_PAD_PWM1__DUART_TX 0x3112 -MX28_PAD_PWM2__USB1_OVERCURRENT 0x3122 -MX28_PAD_SAIF0_MCLK__AUART4_CTS 0x3142 -MX28_PAD_SAIF0_LRCLK__AUART4_RTS 0x3152 -MX28_PAD_SAIF0_BITCLK__AUART4_RX 0x3162 -MX28_PAD_SAIF0_SDATA0__AUART4_TX 0x3172 -MX28_PAD_I2C0_SCL__DUART_RX 0x3182 -MX28_PAD_I2C0_SDA__DUART_TX 0x3192 -MX28_PAD_SAIF1_SDATA0__SAIF0_SDATA1 0x31a2 -MX28_PAD_SPDIF__ENET1_RX_ER 0x31b2 -MX28_PAD_ENET0_MDC__SAIF0_SDATA1 0x4002 -MX28_PAD_ENET0_MDIO__SAIF0_SDATA2 0x4012 -MX28_PAD_ENET0_RX_EN__SAIF1_SDATA1 0x4022 -MX28_PAD_ENET0_RXD0__SAIF1_SDATA2 0x4032 -MX28_PAD_ENET0_TX_CLK__ENET0_1588_EVENT2_OUT 0x4052 -MX28_PAD_ENET0_RXD2__ENET0_1588_EVENT0_OUT 0x4092 -MX28_PAD_ENET0_RXD3__ENET0_1588_EVENT0_IN 0x40a2 -MX28_PAD_ENET0_TXD2__ENET0_1588_EVENT1_OUT 0x40b2 -MX28_PAD_ENET0_TXD3__ENET0_1588_EVENT1_IN 0x40c2 -MX28_PAD_ENET0_RX_CLK__ENET0_1588_EVENT2_IN 0x40d2 -MX28_PAD_ENET0_COL__ENET0_1588_EVENT3_OUT 0x40e2 -MX28_PAD_ENET0_CRS__ENET0_1588_EVENT3_IN 0x40f2 -MX28_PAD_GPMI_D00__GPIO_0_0 0x0003 -MX28_PAD_GPMI_D01__GPIO_0_1 0x0013 -MX28_PAD_GPMI_D02__GPIO_0_2 0x0023 -MX28_PAD_GPMI_D03__GPIO_0_3 0x0033 -MX28_PAD_GPMI_D04__GPIO_0_4 0x0043 -MX28_PAD_GPMI_D05__GPIO_0_5 0x0053 -MX28_PAD_GPMI_D06__GPIO_0_6 0x0063 -MX28_PAD_GPMI_D07__GPIO_0_7 0x0073 -MX28_PAD_GPMI_CE0N__GPIO_0_16 0x0103 -MX28_PAD_GPMI_CE1N__GPIO_0_17 0x0113 -MX28_PAD_GPMI_CE2N__GPIO_0_18 0x0123 -MX28_PAD_GPMI_CE3N__GPIO_0_19 0x0133 -MX28_PAD_GPMI_RDY0__GPIO_0_20 0x0143 -MX28_PAD_GPMI_RDY1__GPIO_0_21 0x0153 -MX28_PAD_GPMI_RDY2__GPIO_0_22 0x0163 -MX28_PAD_GPMI_RDY3__GPIO_0_23 0x0173 -MX28_PAD_GPMI_RDN__GPIO_0_24 0x0183 -MX28_PAD_GPMI_WRN__GPIO_0_25 0x0193 -MX28_PAD_GPMI_ALE__GPIO_0_26 0x01a3 -MX28_PAD_GPMI_CLE__GPIO_0_27 0x01b3 -MX28_PAD_GPMI_RESETN__GPIO_0_28 0x01c3 -MX28_PAD_LCD_D00__GPIO_1_0 0x1003 -MX28_PAD_LCD_D01__GPIO_1_1 0x1013 -MX28_PAD_LCD_D02__GPIO_1_2 0x1023 -MX28_PAD_LCD_D03__GPIO_1_3 0x1033 -MX28_PAD_LCD_D04__GPIO_1_4 0x1043 -MX28_PAD_LCD_D05__GPIO_1_5 0x1053 -MX28_PAD_LCD_D06__GPIO_1_6 0x1063 -MX28_PAD_LCD_D07__GPIO_1_7 0x1073 -MX28_PAD_LCD_D08__GPIO_1_8 0x1083 -MX28_PAD_LCD_D09__GPIO_1_9 0x1093 -MX28_PAD_LCD_D10__GPIO_1_10 0x10a3 -MX28_PAD_LCD_D11__GPIO_1_11 0x10b3 -MX28_PAD_LCD_D12__GPIO_1_12 0x10c3 -MX28_PAD_LCD_D13__GPIO_1_13 0x10d3 -MX28_PAD_LCD_D14__GPIO_1_14 0x10e3 -MX28_PAD_LCD_D15__GPIO_1_15 0x10f3 -MX28_PAD_LCD_D16__GPIO_1_16 0x1103 -MX28_PAD_LCD_D17__GPIO_1_17 0x1113 -MX28_PAD_LCD_D18__GPIO_1_18 0x1123 -MX28_PAD_LCD_D19__GPIO_1_19 0x1133 -MX28_PAD_LCD_D20__GPIO_1_20 0x1143 -MX28_PAD_LCD_D21__GPIO_1_21 0x1153 -MX28_PAD_LCD_D22__GPIO_1_22 0x1163 -MX28_PAD_LCD_D23__GPIO_1_23 0x1173 -MX28_PAD_LCD_RD_E__GPIO_1_24 0x1183 -MX28_PAD_LCD_WR_RWN__GPIO_1_25 0x1193 -MX28_PAD_LCD_RS__GPIO_1_26 0x11a3 -MX28_PAD_LCD_CS__GPIO_1_27 0x11b3 -MX28_PAD_LCD_VSYNC__GPIO_1_28 0x11c3 -MX28_PAD_LCD_HSYNC__GPIO_1_29 0x11d3 -MX28_PAD_LCD_DOTCLK__GPIO_1_30 0x11e3 -MX28_PAD_LCD_ENABLE__GPIO_1_31 0x11f3 -MX28_PAD_SSP0_DATA0__GPIO_2_0 0x2003 -MX28_PAD_SSP0_DATA1__GPIO_2_1 0x2013 -MX28_PAD_SSP0_DATA2__GPIO_2_2 0x2023 -MX28_PAD_SSP0_DATA3__GPIO_2_3 0x2033 -MX28_PAD_SSP0_DATA4__GPIO_2_4 0x2043 -MX28_PAD_SSP0_DATA5__GPIO_2_5 0x2053 -MX28_PAD_SSP0_DATA6__GPIO_2_6 0x2063 -MX28_PAD_SSP0_DATA7__GPIO_2_7 0x2073 -MX28_PAD_SSP0_CMD__GPIO_2_8 0x2083 -MX28_PAD_SSP0_DETECT__GPIO_2_9 0x2093 -MX28_PAD_SSP0_SCK__GPIO_2_10 0x20a3 -MX28_PAD_SSP1_SCK__GPIO_2_12 0x20c3 -MX28_PAD_SSP1_CMD__GPIO_2_13 0x20d3 -MX28_PAD_SSP1_DATA0__GPIO_2_14 0x20e3 -MX28_PAD_SSP1_DATA3__GPIO_2_15 0x20f3 -MX28_PAD_SSP2_SCK__GPIO_2_16 0x2103 -MX28_PAD_SSP2_MOSI__GPIO_2_17 0x2113 -MX28_PAD_SSP2_MISO__GPIO_2_18 0x2123 -MX28_PAD_SSP2_SS0__GPIO_2_19 0x2133 -MX28_PAD_SSP2_SS1__GPIO_2_20 0x2143 -MX28_PAD_SSP2_SS2__GPIO_2_21 0x2153 -MX28_PAD_SSP3_SCK__GPIO_2_24 0x2183 -MX28_PAD_SSP3_MOSI__GPIO_2_25 0x2193 -MX28_PAD_SSP3_MISO__GPIO_2_26 0x21a3 -MX28_PAD_SSP3_SS0__GPIO_2_27 0x21b3 -MX28_PAD_AUART0_RX__GPIO_3_0 0x3003 -MX28_PAD_AUART0_TX__GPIO_3_1 0x3013 -MX28_PAD_AUART0_CTS__GPIO_3_2 0x3023 -MX28_PAD_AUART0_RTS__GPIO_3_3 0x3033 -MX28_PAD_AUART1_RX__GPIO_3_4 0x3043 -MX28_PAD_AUART1_TX__GPIO_3_5 0x3053 -MX28_PAD_AUART1_CTS__GPIO_3_6 0x3063 -MX28_PAD_AUART1_RTS__GPIO_3_7 0x3073 -MX28_PAD_AUART2_RX__GPIO_3_8 0x3083 -MX28_PAD_AUART2_TX__GPIO_3_9 0x3093 -MX28_PAD_AUART2_CTS__GPIO_3_10 0x30a3 -MX28_PAD_AUART2_RTS__GPIO_3_11 0x30b3 -MX28_PAD_AUART3_RX__GPIO_3_12 0x30c3 -MX28_PAD_AUART3_TX__GPIO_3_13 0x30d3 -MX28_PAD_AUART3_CTS__GPIO_3_14 0x30e3 -MX28_PAD_AUART3_RTS__GPIO_3_15 0x30f3 -MX28_PAD_PWM0__GPIO_3_16 0x3103 -MX28_PAD_PWM1__GPIO_3_17 0x3113 -MX28_PAD_PWM2__GPIO_3_18 0x3123 -MX28_PAD_SAIF0_MCLK__GPIO_3_20 0x3143 -MX28_PAD_SAIF0_LRCLK__GPIO_3_21 0x3153 -MX28_PAD_SAIF0_BITCLK__GPIO_3_22 0x3163 -MX28_PAD_SAIF0_SDATA0__GPIO_3_23 0x3173 -MX28_PAD_I2C0_SCL__GPIO_3_24 0x3183 -MX28_PAD_I2C0_SDA__GPIO_3_25 0x3193 -MX28_PAD_SAIF1_SDATA0__GPIO_3_26 0x31a3 -MX28_PAD_SPDIF__GPIO_3_27 0x31b3 -MX28_PAD_PWM3__GPIO_3_28 0x31c3 -MX28_PAD_PWM4__GPIO_3_29 0x31d3 -MX28_PAD_LCD_RESET__GPIO_3_30 0x31e3 -MX28_PAD_ENET0_MDC__GPIO_4_0 0x4003 -MX28_PAD_ENET0_MDIO__GPIO_4_1 0x4013 -MX28_PAD_ENET0_RX_EN__GPIO_4_2 0x4023 -MX28_PAD_ENET0_RXD0__GPIO_4_3 0x4033 -MX28_PAD_ENET0_RXD1__GPIO_4_4 0x4043 -MX28_PAD_ENET0_TX_CLK__GPIO_4_5 0x4053 -MX28_PAD_ENET0_TX_EN__GPIO_4_6 0x4063 -MX28_PAD_ENET0_TXD0__GPIO_4_7 0x4073 -MX28_PAD_ENET0_TXD1__GPIO_4_8 0x4083 -MX28_PAD_ENET0_RXD2__GPIO_4_9 0x4093 -MX28_PAD_ENET0_RXD3__GPIO_4_10 0x40a3 -MX28_PAD_ENET0_TXD2__GPIO_4_11 0x40b3 -MX28_PAD_ENET0_TXD3__GPIO_4_12 0x40c3 -MX28_PAD_ENET0_RX_CLK__GPIO_4_13 0x40d3 -MX28_PAD_ENET0_COL__GPIO_4_14 0x40e3 -MX28_PAD_ENET0_CRS__GPIO_4_15 0x40f3 -MX28_PAD_ENET_CLK__GPIO_4_16 0x4103 -MX28_PAD_JTAG_RTCK__GPIO_4_20 0x4143 - -Valid values for i.MX23 pinmux-id: - -pinmux id ------- -- -MX23_PAD_GPMI_D00__GPMI_D00 0x0000 -MX23_PAD_GPMI_D01__GPMI_D01 0x0010 -MX23_PAD_GPMI_D02__GPMI_D02 0x0020 -MX23_PAD_GPMI_D03__GPMI_D03 0x0030 -MX23_PAD_GPMI_D04__GPMI_D04 0x0040 -MX23_PAD_GPMI_D05__GPMI_D05 0x0050 -MX23_PAD_GPMI_D06__GPMI_D06 0x0060 -MX23_PAD_GPMI_D07__GPMI_D07 0x0070 -MX23_PAD_GPMI_D08__GPMI_D08 0x0080 -MX23_PAD_GPMI_D09__GPMI_D09 0x0090 -MX23_PAD_GPMI_D10__GPMI_D10 0x00a0 -MX23_PAD_GPMI_D11__GPMI_D11 0x00b0 -MX23_PAD_GPMI_D12__GPMI_D12 0x00c0 -MX23_PAD_GPMI_D13__GPMI_D13 0x00d0 -MX23_PAD_GPMI_D14__GPMI_D14 0x00e0 -MX23_PAD_GPMI_D15__GPMI_D15 0x00f0 -MX23_PAD_GPMI_CLE__GPMI_CLE 0x0100 -MX23_PAD_GPMI_ALE__GPMI_ALE 0x0110 -MX23_PAD_GPMI_CE2N__GPMI_CE2N 0x0120 -MX23_PAD_GPMI_RDY0__GPMI_RDY0 0x0130 -MX23_PAD_GPMI_RDY1__GPMI_RDY1 0x0140 -MX23_PAD_GPMI_RDY2__GPMI_RDY2 0x0150 -MX23_PAD_GPMI_RDY3__GPMI_RDY3 0x0160 -MX23_PAD_GPMI_WPN__GPMI_WPN 0x0170 -MX23_PAD_GPMI_WRN__GPMI_WRN 0x0180 -MX23_PAD_GPMI_RDN__GPMI_RDN 0x0190 -MX23_PAD_AUART1_CTS__AUART1_CTS 0x01a0 -MX23_PAD_AUART1_RTS__AUART1_RTS 0x01b0 -MX23_PAD_AUART1_RX__AUART1_RX 0x01c0 -MX23_PAD_AUART1_TX__AUART1_TX 0x01d0 -MX23_PAD_I2C_SCL__I2C_SCL 0x01e0 -MX23_PAD_I2C_SDA__I2C_SDA 0x01f0 -MX23_PAD_LCD_D00__LCD_D00 0x1000 -MX23_PAD_LCD_D01__LCD_D01 0x1010 -MX23_PAD_LCD_D02__LCD_D02 0x1020 -MX23_PAD_LCD_D03__LCD_D03 0x1030 -MX23_PAD_LCD_D04__LCD_D04 0x1040 -MX23_PAD_LCD_D05__LCD_D05 0x1050 -MX23_PAD_LCD_D06__LCD_D06 0x1060 -MX23_PAD_LCD_D07__LCD_D07 0x1070 -MX23_PAD_LCD_D08__LCD_D08 0x1080 -MX23_PAD_LCD_D09__LCD_D09 0x1090 -MX23_PAD_LCD_D10__LCD_D10 0x10a0 -MX23_PAD_LCD_D11__LCD_D11 0x10b0 -MX23_PAD_LCD_D12__LCD_D12 0x10c0 -MX23_PAD_LCD_D13__LCD_D13 0x10d0 -MX23_PAD_LCD_D14__LCD_D14 0x10e0 -MX23_PAD_LCD_D15__LCD_D15 0x10f0 -MX23_PAD_LCD_D16__LCD_D16 0x1100 -MX23_PAD_LCD_D17__LCD_D17 0x1110 -MX23_PAD_LCD_RESET__LCD_RESET 0x1120 -MX23_PAD_LCD_RS__LCD_RS 0x1130 -MX23_PAD_LCD_WR__LCD_WR 0x1140 -MX23_PAD_LCD_CS__LCD_CS 0x1150 -MX23_PAD_LCD_DOTCK__LCD_DOTCK 0x1160 -MX23_PAD_LCD_ENABLE__LCD_ENABLE 0x1170 -MX23_PAD_LCD_HSYNC__LCD_HSYNC 0x1180 -MX23_PAD_LCD_VSYNC__LCD_VSYNC 0x1190 -MX23_PAD_PWM0__PWM0 0x11a0 -MX23_PAD_PWM1__PWM1 0x11b0 -MX23_PAD_PWM2__PWM2 0x11c0 -MX23_PAD_PWM3__PWM3 0x11d0 -MX23_PAD_PWM4__PWM4 0x11e0 -MX23_PAD_SSP1_CMD__SSP1_CMD 0x2000 -MX23_PAD_SSP1_DETECT__SSP1_DETECT 0x2010 -MX23_PAD_SSP1_DATA0__SSP1_DATA0 0x2020 -MX23_PAD_SSP1_DATA1__SSP1_DATA1 0x2030 -MX23_PAD_SSP1_DATA2__SSP1_DATA2 0x2040 -MX23_PAD_SSP1_DATA3__SSP1_DATA3 0x2050 -MX23_PAD_SSP1_SCK__SSP1_SCK 0x2060 -MX23_PAD_ROTARYA__ROTARYA 0x2070 -MX23_PAD_ROTARYB__ROTARYB 0x2080 -MX23_PAD_EMI_A00__EMI_A00 0x2090 -MX23_PAD_EMI_A01__EMI_A01 0x20a0 -MX23_PAD_EMI_A02__EMI_A02 0x20b0 -MX23_PAD_EMI_A03__EMI_A03 0x20c0 -MX23_PAD_EMI_A04__EMI_A04 0x20d0 -MX23_PAD_EMI_A05__EMI_A05 0x20e0 -MX23_PAD_EMI_A06__EMI_A06 0x20f0 -MX23_PAD_EMI_A07__EMI_A07 0x2100 -MX23_PAD_EMI_A08__EMI_A08 0x2110 -MX23_PAD_EMI_A09__EMI_A09 0x2120 -MX23_PAD_EMI_A10__EMI_A10 0x2130 -MX23_PAD_EMI_A11__EMI_A11 0x2140 -MX23_PAD_EMI_A12__EMI_A12 0x2150 -MX23_PAD_EMI_BA0__EMI_BA0 0x2160 -MX23_PAD_EMI_BA1__EMI_BA1 0x2170 -MX23_PAD_EMI_CASN__EMI_CASN 0x2180 -MX23_PAD_EMI_CE0N__EMI_CE0N 0x2190 -MX23_PAD_EMI_CE1N__EMI_CE1N 0x21a0 -MX23_PAD_GPMI_CE1N__GPMI_CE1N 0x21b0 -MX23_PAD_GPMI_CE0N__GPMI_CE0N 0x21c0 -MX23_PAD_EMI_CKE__EMI_CKE 0x21d0 -MX23_PAD_EMI_RASN__EMI_RASN 0x21e0 -MX23_PAD_EMI_WEN__EMI_WEN 0x21f0 -MX23_PAD_EMI_D00__EMI_D00 0x3000 -MX23_PAD_EMI_D01__EMI_D01 0x3010 -MX23_PAD_EMI_D02__EMI_D02 0x3020 -MX23_PAD_EMI_D03__EMI_D03 0x3030 -MX23_PAD_EMI_D04__EMI_D04 0x3040 -MX23_PAD_EMI_D05__EMI_D05 0x3050 -MX23_PAD_EMI_D06__EMI_D06 0x3060 -MX23_PAD_EMI_D07__EMI_D07 0x3070 -MX23_PAD_EMI_D08__EMI_D08 0x3080 -MX23_PAD_EMI_D09__EMI_D09 0x3090 -MX23_PAD_EMI_D10__EMI_D10 0x30a0 -MX23_PAD_EMI_D11__EMI_D11 0x30b0 -MX23_PAD_EMI_D12__EMI_D12 0x30c0 -MX23_PAD_EMI_D13__EMI_D13 0x30d0 -MX23_PAD_EMI_D14__EMI_D14 0x30e0 -MX23_PAD_EMI_D15__EMI_D15 0x30f0 -MX23_PAD_EMI_DQM0__EMI_DQM0 0x3100 -MX23_PAD_EMI_DQM1__EMI_DQM1 0x3110 -MX23_PAD_EMI_DQS0__EMI_DQS0 0x3120 -MX23_PAD_EMI_DQS1__EMI_DQS1 0x3130 -MX23_PAD_EMI_CLK__EMI_CLK 0x3140 -MX23_PAD_EMI_CLKN__EMI_CLKN 0x3150 -MX23_PAD_GPMI_D00__LCD_D8 0x0001 -MX23_PAD_GPMI_D01__LCD_D9 0x0011 -MX23_PAD_GPMI_D02__LCD_D10 0x0021 -MX23_PAD_GPMI_D03__LCD_D11 0x0031 -MX23_PAD_GPMI_D04__LCD_D12 0x0041 -MX23_PAD_GPMI_D05__LCD_D13 0x0051 -MX23_PAD_GPMI_D06__LCD_D14 0x0061 -MX23_PAD_GPMI_D07__LCD_D15 0x0071 -MX23_PAD_GPMI_D08__LCD_D18 0x0081 -MX23_PAD_GPMI_D09__LCD_D19 0x0091 -MX23_PAD_GPMI_D10__LCD_D20 0x00a1 -MX23_PAD_GPMI_D11__LCD_D21 0x00b1 -MX23_PAD_GPMI_D12__LCD_D22 0x00c1 -MX23_PAD_GPMI_D13__LCD_D23 0x00d1 -MX23_PAD_GPMI_D14__AUART2_RX 0x00e1 -MX23_PAD_GPMI_D15__AUART2_TX 0x00f1 -MX23_PAD_GPMI_CLE__LCD_D16 0x0101 -MX23_PAD_GPMI_ALE__LCD_D17 0x0111 -MX23_PAD_GPMI_CE2N__ATA_A2 0x0121 -MX23_PAD_AUART1_RTS__IR_CLK 0x01b1 -MX23_PAD_AUART1_RX__IR_RX 0x01c1 -MX23_PAD_AUART1_TX__IR_TX 0x01d1 -MX23_PAD_I2C_SCL__GPMI_RDY2 0x01e1 -MX23_PAD_I2C_SDA__GPMI_CE2N 0x01f1 -MX23_PAD_LCD_D00__ETM_DA8 0x1001 -MX23_PAD_LCD_D01__ETM_DA9 0x1011 -MX23_PAD_LCD_D02__ETM_DA10 0x1021 -MX23_PAD_LCD_D03__ETM_DA11 0x1031 -MX23_PAD_LCD_D04__ETM_DA12 0x1041 -MX23_PAD_LCD_D05__ETM_DA13 0x1051 -MX23_PAD_LCD_D06__ETM_DA14 0x1061 -MX23_PAD_LCD_D07__ETM_DA15 0x1071 -MX23_PAD_LCD_D08__ETM_DA0 0x1081 -MX23_PAD_LCD_D09__ETM_DA1 0x1091 -MX23_PAD_LCD_D10__ETM_DA2 0x10a1 -MX23_PAD_LCD_D11__ETM_DA3 0x10b1 -MX23_PAD_LCD_D12__ETM_DA4 0x10c1 -MX23_PAD_LCD_D13__ETM_DA5 0x10d1 -MX23_PAD_LCD_D14__ETM_DA6 0x10e1 -MX23_PAD_LCD_D15__ETM_DA7 0x10f1 -MX23_PAD_LCD_RESET__ETM_TCTL 0x1121 -MX23_PAD_LCD_RS__ETM_TCLK 0x1131 -MX23_PAD_LCD_DOTCK__GPMI_RDY3 0x1161 -MX23_PAD_LCD_ENABLE__I2C_SCL 0x1171 -MX23_PAD_LCD_HSYNC__I2C_SDA 0x1181 -MX23_PAD_LCD_VSYNC__LCD_BUSY 0x1191 -MX23_PAD_PWM0__ROTARYA 0x11a1 -MX23_PAD_PWM1__ROTARYB 0x11b1 -MX23_PAD_PWM2__GPMI_RDY3 0x11c1 -MX23_PAD_PWM3__ETM_TCTL 0x11d1 -MX23_PAD_PWM4__ETM_TCLK 0x11e1 -MX23_PAD_SSP1_DETECT__GPMI_CE3N 0x2011 -MX23_PAD_SSP1_DATA1__I2C_SCL 0x2031 -MX23_PAD_SSP1_DATA2__I2C_SDA 0x2041 -MX23_PAD_ROTARYA__AUART2_RTS 0x2071 -MX23_PAD_ROTARYB__AUART2_CTS 0x2081 -MX23_PAD_GPMI_D00__SSP2_DATA0 0x0002 -MX23_PAD_GPMI_D01__SSP2_DATA1 0x0012 -MX23_PAD_GPMI_D02__SSP2_DATA2 0x0022 -MX23_PAD_GPMI_D03__SSP2_DATA3 0x0032 -MX23_PAD_GPMI_D04__SSP2_DATA4 0x0042 -MX23_PAD_GPMI_D05__SSP2_DATA5 0x0052 -MX23_PAD_GPMI_D06__SSP2_DATA6 0x0062 -MX23_PAD_GPMI_D07__SSP2_DATA7 0x0072 -MX23_PAD_GPMI_D08__SSP1_DATA4 0x0082 -MX23_PAD_GPMI_D09__SSP1_DATA5 0x0092 -MX23_PAD_GPMI_D10__SSP1_DATA6 0x00a2 -MX23_PAD_GPMI_D11__SSP1_DATA7 0x00b2 -MX23_PAD_GPMI_D15__GPMI_CE3N 0x00f2 -MX23_PAD_GPMI_RDY0__SSP2_DETECT 0x0132 -MX23_PAD_GPMI_RDY1__SSP2_CMD 0x0142 -MX23_PAD_GPMI_WRN__SSP2_SCK 0x0182 -MX23_PAD_AUART1_CTS__SSP1_DATA4 0x01a2 -MX23_PAD_AUART1_RTS__SSP1_DATA5 0x01b2 -MX23_PAD_AUART1_RX__SSP1_DATA6 0x01c2 -MX23_PAD_AUART1_TX__SSP1_DATA7 0x01d2 -MX23_PAD_I2C_SCL__AUART1_TX 0x01e2 -MX23_PAD_I2C_SDA__AUART1_RX 0x01f2 -MX23_PAD_LCD_D08__SAIF2_SDATA0 0x1082 -MX23_PAD_LCD_D09__SAIF1_SDATA0 0x1092 -MX23_PAD_LCD_D10__SAIF_MCLK_BITCLK 0x10a2 -MX23_PAD_LCD_D11__SAIF_LRCLK 0x10b2 -MX23_PAD_LCD_D12__SAIF2_SDATA1 0x10c2 -MX23_PAD_LCD_D13__SAIF2_SDATA2 0x10d2 -MX23_PAD_LCD_D14__SAIF1_SDATA2 0x10e2 -MX23_PAD_LCD_D15__SAIF1_SDATA1 0x10f2 -MX23_PAD_LCD_D16__SAIF_ALT_BITCLK 0x1102 -MX23_PAD_LCD_RESET__GPMI_CE3N 0x1122 -MX23_PAD_PWM0__DUART_RX 0x11a2 -MX23_PAD_PWM1__DUART_TX 0x11b2 -MX23_PAD_PWM3__AUART1_CTS 0x11d2 -MX23_PAD_PWM4__AUART1_RTS 0x11e2 -MX23_PAD_SSP1_CMD__JTAG_TDO 0x2002 -MX23_PAD_SSP1_DETECT__USB_OTG_ID 0x2012 -MX23_PAD_SSP1_DATA0__JTAG_TDI 0x2022 -MX23_PAD_SSP1_DATA1__JTAG_TCLK 0x2032 -MX23_PAD_SSP1_DATA2__JTAG_RTCK 0x2042 -MX23_PAD_SSP1_DATA3__JTAG_TMS 0x2052 -MX23_PAD_SSP1_SCK__JTAG_TRST 0x2062 -MX23_PAD_ROTARYA__SPDIF 0x2072 -MX23_PAD_ROTARYB__GPMI_CE3N 0x2082 -MX23_PAD_GPMI_D00__GPIO_0_0 0x0003 -MX23_PAD_GPMI_D01__GPIO_0_1 0x0013 -MX23_PAD_GPMI_D02__GPIO_0_2 0x0023 -MX23_PAD_GPMI_D03__GPIO_0_3 0x0033 -MX23_PAD_GPMI_D04__GPIO_0_4 0x0043 -MX23_PAD_GPMI_D05__GPIO_0_5 0x0053 -MX23_PAD_GPMI_D06__GPIO_0_6 0x0063 -MX23_PAD_GPMI_D07__GPIO_0_7 0x0073 -MX23_PAD_GPMI_D08__GPIO_0_8 0x0083 -MX23_PAD_GPMI_D09__GPIO_0_9 0x0093 -MX23_PAD_GPMI_D10__GPIO_0_10 0x00a3 -MX23_PAD_GPMI_D11__GPIO_0_11 0x00b3 -MX23_PAD_GPMI_D12__GPIO_0_12 0x00c3 -MX23_PAD_GPMI_D13__GPIO_0_13 0x00d3 -MX23_PAD_GPMI_D14__GPIO_0_14 0x00e3 -MX23_PAD_GPMI_D15__GPIO_0_15 0x00f3 -MX23_PAD_GPMI_CLE__GPIO_0_16 0x0103 -MX23_PAD_GPMI_ALE__GPIO_0_17 0x0113 -MX23_PAD_GPMI_CE2N__GPIO_0_18 0x0123 -MX23_PAD_GPMI_RDY0__GPIO_0_19 0x0133 -MX23_PAD_GPMI_RDY1__GPIO_0_20 0x0143 -MX23_PAD_GPMI_RDY2__GPIO_0_21 0x0153 -MX23_PAD_GPMI_RDY3__GPIO_0_22 0x0163 -MX23_PAD_GPMI_WPN__GPIO_0_23 0x0173 -MX23_PAD_GPMI_WRN__GPIO_0_24 0x0183 -MX23_PAD_GPMI_RDN__GPIO_0_25 0x0193 -MX23_PAD_AUART1_CTS__GPIO_0_26 0x01a3 -MX23_PAD_AUART1_RTS__GPIO_0_27 0x01b3 -MX23_PAD_AUART1_RX__GPIO_0_28 0x01c3 -MX23_PAD_AUART1_TX__GPIO_0_29 0x01d3 -MX23_PAD_I2C_SCL__GPIO_0_30 0x01e3 -MX23_PAD_I2C_SDA__GPIO_0_31 0x01f3 -MX23_PAD_LCD_D00__GPIO_1_0 0x1003 -MX23_PAD_LCD_D01__GPIO_1_1 0x1013 -MX23_PAD_LCD_D02__GPIO_1_2 0x1023 -MX23_PAD_LCD_D03__GPIO_1_3 0x1033 -MX23_PAD_LCD_D04__GPIO_1_4 0x1043 -MX23_PAD_LCD_D05__GPIO_1_5 0x1053 -MX23_PAD_LCD_D06__GPIO_1_6 0x1063 -MX23_PAD_LCD_D07__GPIO_1_7 0x1073 -MX23_PAD_LCD_D08__GPIO_1_8 0x1083 -MX23_PAD_LCD_D09__GPIO_1_9 0x1093 -MX23_PAD_LCD_D10__GPIO_1_10 0x10a3 -MX23_PAD_LCD_D11__GPIO_1_11 0x10b3 -MX23_PAD_LCD_D12__GPIO_1_12 0x10c3 -MX23_PAD_LCD_D13__GPIO_1_13 0x10d3 -MX23_PAD_LCD_D14__GPIO_1_14 0x10e3 -MX23_PAD_LCD_D15__GPIO_1_15 0x10f3 -MX23_PAD_LCD_D16__GPIO_1_16 0x1103 -MX23_PAD_LCD_D17__GPIO_1_17 0x1113 -MX23_PAD_LCD_RESET__GPIO_1_18 0x1123 -MX23_PAD_LCD_RS__GPIO_1_19 0x1133 -MX23_PAD_LCD_WR__GPIO_1_20 0x1143 -MX23_PAD_LCD_CS__GPIO_1_21 0x1153 -MX23_PAD_LCD_DOTCK__GPIO_1_22 0x1163 -MX23_PAD_LCD_ENABLE__GPIO_1_23 0x1173 -MX23_PAD_LCD_HSYNC__GPIO_1_24 0x1183 -MX23_PAD_LCD_VSYNC__GPIO_1_25 0x1193 -MX23_PAD_PWM0__GPIO_1_26 0x11a3 -MX23_PAD_PWM1__GPIO_1_27 0x11b3 -MX23_PAD_PWM2__GPIO_1_28 0x11c3 -MX23_PAD_PWM3__GPIO_1_29 0x11d3 -MX23_PAD_PWM4__GPIO_1_30 0x11e3 -MX23_PAD_SSP1_CMD__GPIO_2_0 0x2003 -MX23_PAD_SSP1_DETECT__GPIO_2_1 0x2013 -MX23_PAD_SSP1_DATA0__GPIO_2_2 0x2023 -MX23_PAD_SSP1_DATA1__GPIO_2_3 0x2033 -MX23_PAD_SSP1_DATA2__GPIO_2_4 0x2043 -MX23_PAD_SSP1_DATA3__GPIO_2_5 0x2053 -MX23_PAD_SSP1_SCK__GPIO_2_6 0x2063 -MX23_PAD_ROTARYA__GPIO_2_7 0x2073 -MX23_PAD_ROTARYB__GPIO_2_8 0x2083 -MX23_PAD_EMI_A00__GPIO_2_9 0x2093 -MX23_PAD_EMI_A01__GPIO_2_10 0x20a3 -MX23_PAD_EMI_A02__GPIO_2_11 0x20b3 -MX23_PAD_EMI_A03__GPIO_2_12 0x20c3 -MX23_PAD_EMI_A04__GPIO_2_13 0x20d3 -MX23_PAD_EMI_A05__GPIO_2_14 0x20e3 -MX23_PAD_EMI_A06__GPIO_2_15 0x20f3 -MX23_PAD_EMI_A07__GPIO_2_16 0x2103 -MX23_PAD_EMI_A08__GPIO_2_17 0x2113 -MX23_PAD_EMI_A09__GPIO_2_18 0x2123 -MX23_PAD_EMI_A10__GPIO_2_19 0x2133 -MX23_PAD_EMI_A11__GPIO_2_20 0x2143 -MX23_PAD_EMI_A12__GPIO_2_21 0x2153 -MX23_PAD_EMI_BA0__GPIO_2_22 0x2163 -MX23_PAD_EMI_BA1__GPIO_2_23 0x2173 -MX23_PAD_EMI_CASN__GPIO_2_24 0x2183 -MX23_PAD_EMI_CE0N__GPIO_2_25 0x2193 -MX23_PAD_EMI_CE1N__GPIO_2_26 0x21a3 -MX23_PAD_GPMI_CE1N__GPIO_2_27 0x21b3 -MX23_PAD_GPMI_CE0N__GPIO_2_28 0x21c3 -MX23_PAD_EMI_CKE__GPIO_2_29 0x21d3 -MX23_PAD_EMI_RASN__GPIO_2_30 0x21e3 -MX23_PAD_EMI_WEN__GPIO_2_31 0x21f3 diff --git a/trunk/Documentation/devicetree/bindings/pinctrl/nvidia,tegra20-pinmux.txt b/trunk/Documentation/devicetree/bindings/pinctrl/nvidia,tegra20-pinmux.txt deleted file mode 100644 index c8e578263ce2..000000000000 --- a/trunk/Documentation/devicetree/bindings/pinctrl/nvidia,tegra20-pinmux.txt +++ /dev/null @@ -1,132 +0,0 @@ -NVIDIA Tegra20 pinmux controller - -Required properties: -- compatible: "nvidia,tegra20-pinmux" -- reg: Should contain the register physical address and length for each of - the tri-state, mux, pull-up/down, and pad control register sets. - -Please refer to pinctrl-bindings.txt in this directory for details of the -common pinctrl bindings used by client devices, including the meaning of the -phrase "pin configuration node". - -Tegra's pin configuration nodes act as a container for an abitrary number of -subnodes. Each of these subnodes represents some desired configuration for a -pin, a group, or a list of pins or groups. This configuration can include the -mux function to select on those pin(s)/group(s), and various pin configuration -parameters, such as pull-up, tristate, drive strength, etc. - -The name of each subnode is not important; all subnodes should be enumerated -and processed purely based on their content. - -Each subnode only affects those parameters that are explicitly listed. In -other words, a subnode that lists a mux function but no pin configuration -parameters implies no information about any pin configuration parameters. -Similarly, a pin subnode that describes a pullup parameter implies no -information about e.g. the mux function or tristate parameter. For this -reason, even seemingly boolean values are actually tristates in this binding: -unspecified, off, or on. Unspecified is represented as an absent property, -and off/on are represented as integer values 0 and 1. - -Required subnode-properties: -- nvidia,pins : An array of strings. Each string contains the name of a pin or - group. Valid values for these names are listed below. - -Optional subnode-properties: -- nvidia,function: A string containing the name of the function to mux to the - pin or group. Valid values for function names are listed below. See the Tegra - TRM to determine which are valid for each pin or group. -- nvidia,pull: Integer, representing the pull-down/up to apply to the pin. - 0: none, 1: down, 2: up. -- nvidia,tristate: Integer. - 0: drive, 1: tristate. -- nvidia,high-speed-mode: Integer. Enable high speed mode the pins. - 0: no, 1: yes. -- nvidia,schmitt: Integer. Enables Schmitt Trigger on the input. - 0: no, 1: yes. -- nvidia,low-power-mode: Integer. Valid values 0-3. 0 is least power, 3 is - most power. Controls the drive power or current. See "Low Power Mode" - or "LPMD1" and "LPMD0" in the Tegra TRM. -- nvidia,pull-down-strength: Integer. Controls drive strength. 0 is weakest. - The range of valid values depends on the pingroup. See "CAL_DRVDN" in the - Tegra TRM. -- nvidia,pull-up-strength: Integer. Controls drive strength. 0 is weakest. - The range of valid values depends on the pingroup. See "CAL_DRVUP" in the - Tegra TRM. -- nvidia,slew-rate-rising: Integer. Controls rising signal slew rate. 0 is - fastest. The range of valid values depends on the pingroup. See - "DRVDN_SLWR" in the Tegra TRM. -- nvidia,slew-rate-falling: Integer. Controls falling signal slew rate. 0 is - fastest. The range of valid values depends on the pingroup. See - "DRVUP_SLWF" in the Tegra TRM. - -Note that many of these properties are only valid for certain specific pins -or groups. See the Tegra TRM and various pinmux spreadsheets for complete -details regarding which groups support which functionality. The Linux pinctrl -driver may also be a useful reference, since it consolidates, disambiguates, -and corrects data from all those sources. - -Valid values for pin and group names are: - - mux groups: - - These all support nvidia,function, nvidia,tristate, and many support - nvidia,pull. - - ata, atb, atc, atd, ate, cdev1, cdev2, crtp, csus, dap1, dap2, dap3, dap4, - ddc, dta, dtb, dtc, dtd, dte, dtf, gma, gmb, gmc, gmd, gme, gpu, gpu7, - gpv, hdint, i2cp, irrx, irtx, kbca, kbcb, kbcc, kbcd, kbce, kbcf, lcsn, - ld0, ld1, ld2, ld3, ld4, ld5, ld6, ld7, ld8, ld9, ld10, ld11, ld12, ld13, - ld14, ld15, ld16, ld17, ldc, ldi, lhp0, lhp1, lhp2, lhs, lm0, lm1, lpp, - lpw0, lpw1, lpw2, lsc0, lsc1, lsck, lsda, lsdi, lspi, lvp0, lvp1, lvs, - owc, pmc, pta, rm, sdb, sdc, sdd, sdio1, slxa, slxc, slxd, slxk, spdi, - spdo, spia, spib, spic, spid, spie, spif, spig, spih, uaa, uab, uac, uad, - uca, ucb, uda. - - tristate groups: - - These only support nvidia,pull. - - ck32, ddrc, pmca, pmcb, pmcc, pmcd, pmce, xm2c, xm2d, ls, lc, ld17_0, - ld19_18, ld21_20, ld23_22. - - drive groups: - - With some exceptions, these support nvidia,high-speed-mode, - nvidia,schmitt, nvidia,low-power-mode, nvidia,pull-down-strength, - nvidia,pull-up-strength, nvidia,slew_rate-rising, nvidia,slew_rate-falling. - - drive_ao1, drive_ao2, drive_at1, drive_at2, drive_cdev1, drive_cdev2, - drive_csus, drive_dap1, drive_dap2, drive_dap3, drive_dap4, drive_dbg, - drive_lcd1, drive_lcd2, drive_sdmmc2, drive_sdmmc3, drive_spi, drive_uaa, - drive_uab, drive_uart2, drive_uart3, drive_vi1, drive_vi2, drive_xm2a, - drive_xm2c, drive_xm2d, drive_xm2clk, drive_sdio1, drive_crt, drive_ddc, - drive_gma, drive_gmb, drive_gmc, drive_gmd, drive_gme, drive_owr, - drive_uda. - -Example: - - pinctrl@70000000 { - compatible = "nvidia,tegra20-pinmux"; - reg = < 0x70000014 0x10 /* Tri-state registers */ - 0x70000080 0x20 /* Mux registers */ - 0x700000a0 0x14 /* Pull-up/down registers */ - 0x70000868 0xa8 >; /* Pad control registers */ - }; - -Example board file extract: - - pinctrl@70000000 { - sdio4_default: sdio4_default { - atb { - nvidia,pins = "atb", "gma", "gme"; - nvidia,function = "sdio4"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - }; - }; - }; - - sdhci@c8000600 { - pinctrl-names = "default"; - pinctrl-0 = <&sdio4_default>; - }; diff --git a/trunk/Documentation/devicetree/bindings/pinctrl/nvidia,tegra30-pinmux.txt b/trunk/Documentation/devicetree/bindings/pinctrl/nvidia,tegra30-pinmux.txt deleted file mode 100644 index c275b70349c1..000000000000 --- a/trunk/Documentation/devicetree/bindings/pinctrl/nvidia,tegra30-pinmux.txt +++ /dev/null @@ -1,132 +0,0 @@ -NVIDIA Tegra30 pinmux controller - -The Tegra30 pinctrl binding is very similar to the Tegra20 pinctrl binding, -as described in nvidia,tegra20-pinmux.txt. In fact, this document assumes -that binding as a baseline, and only documents the differences between the -two bindings. - -Required properties: -- compatible: "nvidia,tegra30-pinmux" -- reg: Should contain the register physical address and length for each of - the pad control and mux registers. - -Tegra30 adds the following optional properties for pin configuration subnodes: -- nvidia,enable-input: Integer. Enable the pin's input path. 0: no, 1: yes. -- nvidia,open-drain: Integer. Enable open drain mode. 0: no, 1: yes. -- nvidia,lock: Integer. Lock the pin configuration against further changes - until reset. 0: no, 1: yes. -- nvidia,io-reset: Integer. Reset the IO path. 0: no, 1: yes. - -As with Tegra20, see the Tegra TRM for complete details regarding which groups -support which functionality. - -Valid values for pin and group names are: - - per-pin mux groups: - - These all support nvidia,function, nvidia,tristate, nvidia,pull, - nvidia,enable-input, nvidia,lock. Some support nvidia,open-drain, - nvidia,io-reset. - - clk_32k_out_pa0, uart3_cts_n_pa1, dap2_fs_pa2, dap2_sclk_pa3, - dap2_din_pa4, dap2_dout_pa5, sdmmc3_clk_pa6, sdmmc3_cmd_pa7, gmi_a17_pb0, - gmi_a18_pb1, lcd_pwr0_pb2, lcd_pclk_pb3, sdmmc3_dat3_pb4, sdmmc3_dat2_pb5, - sdmmc3_dat1_pb6, sdmmc3_dat0_pb7, uart3_rts_n_pc0, lcd_pwr1_pc1, - uart2_txd_pc2, uart2_rxd_pc3, gen1_i2c_scl_pc4, gen1_i2c_sda_pc5, - lcd_pwr2_pc6, gmi_wp_n_pc7, sdmmc3_dat5_pd0, sdmmc3_dat4_pd1, lcd_dc1_pd2, - sdmmc3_dat6_pd3, sdmmc3_dat7_pd4, vi_d1_pd5, vi_vsync_pd6, vi_hsync_pd7, - lcd_d0_pe0, lcd_d1_pe1, lcd_d2_pe2, lcd_d3_pe3, lcd_d4_pe4, lcd_d5_pe5, - lcd_d6_pe6, lcd_d7_pe7, lcd_d8_pf0, lcd_d9_pf1, lcd_d10_pf2, lcd_d11_pf3, - lcd_d12_pf4, lcd_d13_pf5, lcd_d14_pf6, lcd_d15_pf7, gmi_ad0_pg0, - gmi_ad1_pg1, gmi_ad2_pg2, gmi_ad3_pg3, gmi_ad4_pg4, gmi_ad5_pg5, - gmi_ad6_pg6, gmi_ad7_pg7, gmi_ad8_ph0, gmi_ad9_ph1, gmi_ad10_ph2, - gmi_ad11_ph3, gmi_ad12_ph4, gmi_ad13_ph5, gmi_ad14_ph6, gmi_ad15_ph7, - gmi_wr_n_pi0, gmi_oe_n_pi1, gmi_dqs_pi2, gmi_cs6_n_pi3, gmi_rst_n_pi4, - gmi_iordy_pi5, gmi_cs7_n_pi6, gmi_wait_pi7, gmi_cs0_n_pj0, lcd_de_pj1, - gmi_cs1_n_pj2, lcd_hsync_pj3, lcd_vsync_pj4, uart2_cts_n_pj5, - uart2_rts_n_pj6, gmi_a16_pj7, gmi_adv_n_pk0, gmi_clk_pk1, gmi_cs4_n_pk2, - gmi_cs2_n_pk3, gmi_cs3_n_pk4, spdif_out_pk5, spdif_in_pk6, gmi_a19_pk7, - vi_d2_pl0, vi_d3_pl1, vi_d4_pl2, vi_d5_pl3, vi_d6_pl4, vi_d7_pl5, - vi_d8_pl6, vi_d9_pl7, lcd_d16_pm0, lcd_d17_pm1, lcd_d18_pm2, lcd_d19_pm3, - lcd_d20_pm4, lcd_d21_pm5, lcd_d22_pm6, lcd_d23_pm7, dap1_fs_pn0, - dap1_din_pn1, dap1_dout_pn2, dap1_sclk_pn3, lcd_cs0_n_pn4, lcd_sdout_pn5, - lcd_dc0_pn6, hdmi_int_pn7, ulpi_data7_po0, ulpi_data0_po1, ulpi_data1_po2, - ulpi_data2_po3, ulpi_data3_po4, ulpi_data4_po5, ulpi_data5_po6, - ulpi_data6_po7, dap3_fs_pp0, dap3_din_pp1, dap3_dout_pp2, dap3_sclk_pp3, - dap4_fs_pp4, dap4_din_pp5, dap4_dout_pp6, dap4_sclk_pp7, kb_col0_pq0, - kb_col1_pq1, kb_col2_pq2, kb_col3_pq3, kb_col4_pq4, kb_col5_pq5, - kb_col6_pq6, kb_col7_pq7, kb_row0_pr0, kb_row1_pr1, kb_row2_pr2, - kb_row3_pr3, kb_row4_pr4, kb_row5_pr5, kb_row6_pr6, kb_row7_pr7, - kb_row8_ps0, kb_row9_ps1, kb_row10_ps2, kb_row11_ps3, kb_row12_ps4, - kb_row13_ps5, kb_row14_ps6, kb_row15_ps7, vi_pclk_pt0, vi_mclk_pt1, - vi_d10_pt2, vi_d11_pt3, vi_d0_pt4, gen2_i2c_scl_pt5, gen2_i2c_sda_pt6, - sdmmc4_cmd_pt7, pu0, pu1, pu2, pu3, pu4, pu5, pu6, jtag_rtck_pu7, pv0, - pv1, pv2, pv3, ddc_scl_pv4, ddc_sda_pv5, crt_hsync_pv6, crt_vsync_pv7, - lcd_cs1_n_pw0, lcd_m1_pw1, spi2_cs1_n_pw2, spi2_cs2_n_pw3, clk1_out_pw4, - clk2_out_pw5, uart3_txd_pw6, uart3_rxd_pw7, spi2_mosi_px0, spi2_miso_px1, - spi2_sck_px2, spi2_cs0_n_px3, spi1_mosi_px4, spi1_sck_px5, spi1_cs0_n_px6, - spi1_miso_px7, ulpi_clk_py0, ulpi_dir_py1, ulpi_nxt_py2, ulpi_stp_py3, - sdmmc1_dat3_py4, sdmmc1_dat2_py5, sdmmc1_dat1_py6, sdmmc1_dat0_py7, - sdmmc1_clk_pz0, sdmmc1_cmd_pz1, lcd_sdin_pz2, lcd_wr_n_pz3, lcd_sck_pz4, - sys_clk_req_pz5, pwr_i2c_scl_pz6, pwr_i2c_sda_pz7, sdmmc4_dat0_paa0, - sdmmc4_dat1_paa1, sdmmc4_dat2_paa2, sdmmc4_dat3_paa3, sdmmc4_dat4_paa4, - sdmmc4_dat5_paa5, sdmmc4_dat6_paa6, sdmmc4_dat7_paa7, pbb0, - cam_i2c_scl_pbb1, cam_i2c_sda_pbb2, pbb3, pbb4, pbb5, pbb6, pbb7, - cam_mclk_pcc0, pcc1, pcc2, sdmmc4_rst_n_pcc3, sdmmc4_clk_pcc4, - clk2_req_pcc5, pex_l2_rst_n_pcc6, pex_l2_clkreq_n_pcc7, - pex_l0_prsnt_n_pdd0, pex_l0_rst_n_pdd1, pex_l0_clkreq_n_pdd2, - pex_wake_n_pdd3, pex_l1_prsnt_n_pdd4, pex_l1_rst_n_pdd5, - pex_l1_clkreq_n_pdd6, pex_l2_prsnt_n_pdd7, clk3_out_pee0, clk3_req_pee1, - clk1_req_pee2, hdmi_cec_pee3, clk_32k_in, core_pwr_req, cpu_pwr_req, owr, - pwr_int_n. - - drive groups: - - These all support nvidia,pull-down-strength, nvidia,pull-up-strength, - nvidia,slew_rate-rising, nvidia,slew_rate-falling. Most but not all - support nvidia,high-speed-mode, nvidia,schmitt, nvidia,low-power-mode. - - ao1, ao2, at1, at2, at3, at4, at5, cdev1, cdev2, cec, crt, csus, dap1, - dap2, dap3, dap4, dbg, ddc, dev3, gma, gmb, gmc, gmd, gme, gmf, gmg, - gmh, gpv, lcd1, lcd2, owr, sdio1, sdio2, sdio3, spi, uaa, uab, uart2, - uart3, uda, vi1. - -Example: - - pinctrl@70000000 { - compatible = "nvidia,tegra30-pinmux"; - reg = < 0x70000868 0xd0 /* Pad control registers */ - 0x70003000 0x3e0 >; /* Mux registers */ - }; - -Example board file extract: - - pinctrl@70000000 { - sdmmc4_default: pinmux { - sdmmc4_clk_pcc4 { - nvidia,pins = "sdmmc4_clk_pcc4", - "sdmmc4_rst_n_pcc3"; - nvidia,function = "sdmmc4"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - }; - sdmmc4_dat0_paa0 { - nvidia,pins = "sdmmc4_dat0_paa0", - "sdmmc4_dat1_paa1", - "sdmmc4_dat2_paa2", - "sdmmc4_dat3_paa3", - "sdmmc4_dat4_paa4", - "sdmmc4_dat5_paa5", - "sdmmc4_dat6_paa6", - "sdmmc4_dat7_paa7"; - nvidia,function = "sdmmc4"; - nvidia,pull = <2>; - nvidia,tristate = <0>; - }; - }; - }; - - sdhci@78000400 { - pinctrl-names = "default"; - pinctrl-0 = <&sdmmc4_default>; - }; diff --git a/trunk/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt b/trunk/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt deleted file mode 100644 index c95ea8278f87..000000000000 --- a/trunk/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt +++ /dev/null @@ -1,128 +0,0 @@ -== Introduction == - -Hardware modules that control pin multiplexing or configuration parameters -such as pull-up/down, tri-state, drive-strength etc are designated as pin -controllers. Each pin controller must be represented as a node in device tree, -just like any other hardware module. - -Hardware modules whose signals are affected by pin configuration are -designated client devices. Again, each client device must be represented as a -node in device tree, just like any other hardware module. - -For a client device to operate correctly, certain pin controllers must -set up certain specific pin configurations. Some client devices need a -single static pin configuration, e.g. set up during initialization. Others -need to reconfigure pins at run-time, for example to tri-state pins when the -device is inactive. Hence, each client device can define a set of named -states. The number and names of those states is defined by the client device's -own binding. - -The common pinctrl bindings defined in this file provide an infrastructure -for client device device tree nodes to map those state names to the pin -configuration used by those states. - -Note that pin controllers themselves may also be client devices of themselves. -For example, a pin controller may set up its own "active" state when the -driver loads. This would allow representing a board's static pin configuration -in a single place, rather than splitting it across multiple client device -nodes. The decision to do this or not somewhat rests with the author of -individual board device tree files, and any requirements imposed by the -bindings for the individual client devices in use by that board, i.e. whether -they require certain specific named states for dynamic pin configuration. - -== Pinctrl client devices == - -For each client device individually, every pin state is assigned an integer -ID. These numbers start at 0, and are contiguous. For each state ID, a unique -property exists to define the pin configuration. Each state may also be -assigned a name. When names are used, another property exists to map from -those names to the integer IDs. - -Each client device's own binding determines the set of states the must be -defined in its device tree node, and whether to define the set of state -IDs that must be provided, or whether to define the set of state names that -must be provided. - -Required properties: -pinctrl-0: List of phandles, each pointing at a pin configuration - node. These referenced pin configuration nodes must be child - nodes of the pin controller that they configure. Multiple - entries may exist in this list so that multiple pin - controllers may be configured, or so that a state may be built - from multiple nodes for a single pin controller, each - contributing part of the overall configuration. See the next - section of this document for details of the format of these - pin configuration nodes. - - In some cases, it may be useful to define a state, but for it - to be empty. This may be required when a common IP block is - used in an SoC either without a pin controller, or where the - pin controller does not affect the HW module in question. If - the binding for that IP block requires certain pin states to - exist, they must still be defined, but may be left empty. - -Optional properties: -pinctrl-1: List of phandles, each pointing at a pin configuration - node within a pin controller. -... -pinctrl-n: List of phandles, each pointing at a pin configuration - node within a pin controller. -pinctrl-names: The list of names to assign states. List entry 0 defines the - name for integer state ID 0, list entry 1 for state ID 1, and - so on. - -For example: - - /* For a client device requiring named states */ - device { - pinctrl-names = "active", "idle"; - pinctrl-0 = <&state_0_node_a>; - pinctrl-1 = <&state_1_node_a &state_1_node_b>; - }; - - /* For the same device if using state IDs */ - device { - pinctrl-0 = <&state_0_node_a>; - pinctrl-1 = <&state_1_node_a &state_1_node_b>; - }; - - /* - * For an IP block whose binding supports pin configuration, - * but in use on an SoC that doesn't have any pin control hardware - */ - device { - pinctrl-names = "active", "idle"; - pinctrl-0 = <>; - pinctrl-1 = <>; - }; - -== Pin controller devices == - -Pin controller devices should contain the pin configuration nodes that client -devices reference. - -For example: - - pincontroller { - ... /* Standard DT properties for the device itself elided */ - - state_0_node_a { - ... - }; - state_1_node_a { - ... - }; - state_1_node_b { - ... - }; - } - -The contents of each of those pin configuration child nodes is defined -entirely by the binding for the individual pin controller device. There -exists no common standard for this content. - -The pin configuration nodes need not be direct children of the pin controller -device; they may be grandchildren, for example. Whether this is legal, and -whether there is any interaction between the child and intermediate parent -nodes, is again defined entirely by the binding for the individual pin -controller device. diff --git a/trunk/Documentation/devicetree/bindings/pinmux/pinmux_nvidia.txt b/trunk/Documentation/devicetree/bindings/pinmux/pinmux_nvidia.txt new file mode 100644 index 000000000000..36f82dbdd14d --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/pinmux/pinmux_nvidia.txt @@ -0,0 +1,5 @@ +NVIDIA Tegra 2 pinmux controller + +Required properties: +- compatible : "nvidia,tegra20-pinmux" + diff --git a/trunk/Documentation/devicetree/bindings/regulator/fixed-regulator.txt b/trunk/Documentation/devicetree/bindings/regulator/fixed-regulator.txt index 2f5b6b1ba15f..9cf57fd042d2 100644 --- a/trunk/Documentation/devicetree/bindings/regulator/fixed-regulator.txt +++ b/trunk/Documentation/devicetree/bindings/regulator/fixed-regulator.txt @@ -8,8 +8,6 @@ Optional properties: - startup-delay-us: startup time in microseconds - enable-active-high: Polarity of GPIO is Active high If this property is missing, the default assumed is Active low. -- gpio-open-drain: GPIO is open drain type. - If this property is missing then default assumption is false. Any property defined as part of the core regulator binding, defined in regulator.txt, can also be used. @@ -27,6 +25,5 @@ Example: gpio = <&gpio1 16 0>; startup-delay-us = <70000>; enable-active-high; - regulator-boot-on; - gpio-open-drain; + regulator-boot-on }; diff --git a/trunk/Documentation/devicetree/bindings/regulator/tps62360-regulator.txt b/trunk/Documentation/devicetree/bindings/regulator/tps62360-regulator.txt deleted file mode 100644 index c8ca6b8f6582..000000000000 --- a/trunk/Documentation/devicetree/bindings/regulator/tps62360-regulator.txt +++ /dev/null @@ -1,44 +0,0 @@ -TPS62360 Voltage regulators - -Required properties: -- compatible: Must be one of the following. - "ti,tps62360" - "ti,tps62361", - "ti,tps62362", - "ti,tps62363", -- reg: I2C slave address - -Optional properties: -- ti,enable-vout-discharge: Enable output discharge. This is boolean value. -- ti,enable-pull-down: Enable pull down. This is boolean value. -- ti,vsel0-gpio: GPIO for controlling VSEL0 line. - If this property is missing, then assume that there is no GPIO - for vsel0 control. -- ti,vsel1-gpio: Gpio for controlling VSEL1 line. - If this property is missing, then assume that there is no GPIO - for vsel1 control. -- ti,vsel0-state-high: Inital state of vsel0 input is high. - If this property is missing, then assume the state as low (0). -- ti,vsel1-state-high: Inital state of vsel1 input is high. - If this property is missing, then assume the state as low (0). - -Any property defined as part of the core regulator binding, defined in -regulator.txt, can also be used. - -Example: - - abc: tps62360 { - compatible = "ti,tps62361"; - reg = <0x60>; - regulator-name = "tps62361-vout"; - regulator-min-microvolt = <500000>; - regulator-max-microvolt = <1500000>; - regulator-boot-on - ti,vsel0-gpio = <&gpio1 16 0>; - ti,vsel1-gpio = <&gpio1 17 0>; - ti,vsel0-state-high; - ti,vsel1-state-high; - ti,enable-pull-down; - ti,enable-force-pwm; - ti,enable-vout-discharge; - }; diff --git a/trunk/Documentation/devicetree/bindings/regulator/tps6586x.txt b/trunk/Documentation/devicetree/bindings/regulator/tps6586x.txt deleted file mode 100644 index 0fcabaa3baa3..000000000000 --- a/trunk/Documentation/devicetree/bindings/regulator/tps6586x.txt +++ /dev/null @@ -1,97 +0,0 @@ -TPS6586x family of regulators - -Required properties: -- compatible: "ti,tps6586x" -- reg: I2C slave address -- interrupts: the interrupt outputs of the controller -- #gpio-cells: number of cells to describe a GPIO -- gpio-controller: mark the device as a GPIO controller -- regulators: list of regulators provided by this controller, must be named - after their hardware counterparts: sm[0-2], ldo[0-9] and ldo_rtc - -Each regulator is defined using the standard binding for regulators. - -Example: - - pmu: tps6586x@34 { - compatible = "ti,tps6586x"; - reg = <0x34>; - interrupts = <0 88 0x4>; - - #gpio-cells = <2>; - gpio-controller; - - regulators { - sm0_reg: sm0 { - regulator-min-microvolt = < 725000>; - regulator-max-microvolt = <1500000>; - regulator-boot-on; - regulator-always-on; - }; - - sm1_reg: sm1 { - regulator-min-microvolt = < 725000>; - regulator-max-microvolt = <1500000>; - regulator-boot-on; - regulator-always-on; - }; - - sm2_reg: sm2 { - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <4550000>; - regulator-boot-on; - regulator-always-on; - }; - - ldo0_reg: ldo0 { - regulator-name = "PCIE CLK"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - }; - - ldo1_reg: ldo1 { - regulator-min-microvolt = < 725000>; - regulator-max-microvolt = <1500000>; - }; - - ldo2_reg: ldo2 { - regulator-min-microvolt = < 725000>; - regulator-max-microvolt = <1500000>; - }; - - ldo3_reg: ldo3 { - regulator-min-microvolt = <1250000>; - regulator-max-microvolt = <3300000>; - }; - - ldo4_reg: ldo4 { - regulator-min-microvolt = <1700000>; - regulator-max-microvolt = <2475000>; - }; - - ldo5_reg: ldo5 { - regulator-min-microvolt = <1250000>; - regulator-max-microvolt = <3300000>; - }; - - ldo6_reg: ldo6 { - regulator-min-microvolt = <1250000>; - regulator-max-microvolt = <3300000>; - }; - - ldo7_reg: ldo7 { - regulator-min-microvolt = <1250000>; - regulator-max-microvolt = <3300000>; - }; - - ldo8_reg: ldo8 { - regulator-min-microvolt = <1250000>; - regulator-max-microvolt = <3300000>; - }; - - ldo9_reg: ldo9 { - regulator-min-microvolt = <1250000>; - regulator-max-microvolt = <3300000>; - }; - }; - }; diff --git a/trunk/Documentation/devicetree/bindings/sound/sgtl5000.txt b/trunk/Documentation/devicetree/bindings/sound/sgtl5000.txt index 9cc44449508d..2c3cd413f042 100644 --- a/trunk/Documentation/devicetree/bindings/sound/sgtl5000.txt +++ b/trunk/Documentation/devicetree/bindings/sound/sgtl5000.txt @@ -3,8 +3,6 @@ Required properties: - compatible : "fsl,sgtl5000". -- reg : the I2C address of the device - Example: codec: sgtl5000@0a { diff --git a/trunk/Documentation/driver-model/devres.txt b/trunk/Documentation/driver-model/devres.txt index 950856bd2e39..2a596a4fc23e 100644 --- a/trunk/Documentation/driver-model/devres.txt +++ b/trunk/Documentation/driver-model/devres.txt @@ -276,11 +276,3 @@ REGULATOR devm_regulator_get() devm_regulator_put() devm_regulator_bulk_get() - -CLOCK - devm_clk_get() - devm_clk_put() - -PINCTRL - devm_pinctrl_get() - devm_pinctrl_put() diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index e4b57756b9f5..03ca210406ed 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -539,13 +539,3 @@ When: 3.6 Why: setitimer is not returning -EFAULT if user pointer is NULL. This violates the spec. Who: Sasikantha Babu - ----------------------------- - -What: V4L2_CID_HCENTER, V4L2_CID_VCENTER V4L2 controls -When: 3.7 -Why: The V4L2_CID_VCENTER, V4L2_CID_HCENTER controls have been deprecated - for about 4 years and they are not used by any mainline driver. - There are newer controls (V4L2_CID_PAN*, V4L2_CID_TILT*) that provide - similar functionality. -Who: Sylwester Nawrocki diff --git a/trunk/Documentation/filesystems/gfs2-glocks.txt b/trunk/Documentation/filesystems/gfs2-glocks.txt index fcc79957be63..0494f78d87e4 100644 --- a/trunk/Documentation/filesystems/gfs2-glocks.txt +++ b/trunk/Documentation/filesystems/gfs2-glocks.txt @@ -61,9 +61,7 @@ go_unlock | Called on the final local unlock of a lock go_dump | Called to print content of object for debugfs file, or on | error to dump glock to the log. go_type | The type of the glock, LM_TYPE_..... -go_callback | Called if the DLM sends a callback to drop this lock -go_flags | GLOF_ASPACE is set, if the glock has an address space - | associated with it +go_min_hold_time | The minimum hold time The minimum hold time for each lock is the time after a remote lock grant for which we ignore remote demote requests. This is in order to @@ -91,7 +89,6 @@ go_demote_ok | Sometimes | Yes go_lock | Yes | No go_unlock | Yes | No go_dump | Sometimes | Yes -go_callback | Sometimes (N/A) | Yes N.B. Operations must not drop either the bit lock or the spinlock if its held on entry. go_dump and do_demote_ok must never block. @@ -114,118 +111,4 @@ itself (locking order as above), and the other, known as the iopen glock is used in conjunction with the i_nlink field in the inode to determine the lifetime of the inode in question. Locking of inodes is on a per-inode basis. Locking of rgrps is on a per rgrp basis. -In general we prefer to lock local locks prior to cluster locks. - - Glock Statistics - ------------------ - -The stats are divided into two sets: those relating to the -super block and those relating to an individual glock. The -super block stats are done on a per cpu basis in order to -try and reduce the overhead of gathering them. They are also -further divided by glock type. All timings are in nanoseconds. - -In the case of both the super block and glock statistics, -the same information is gathered in each case. The super -block timing statistics are used to provide default values for -the glock timing statistics, so that newly created glocks -should have, as far as possible, a sensible starting point. -The per-glock counters are initialised to zero when the -glock is created. The per-glock statistics are lost when -the glock is ejected from memory. - -The statistics are divided into three pairs of mean and -variance, plus two counters. The mean/variance pairs are -smoothed exponential estimates and the algorithm used is -one which will be very familiar to those used to calculation -of round trip times in network code. See "TCP/IP Illustrated, -Volume 1", W. Richard Stevens, sect 21.3, "Round-Trip Time Measurement", -p. 299 and onwards. Also, Volume 2, Sect. 25.10, p. 838 and onwards. -Unlike the TCP/IP Illustrated case, the mean and variance are -not scaled, but are in units of integer nanoseconds. - -The three pairs of mean/variance measure the following -things: - - 1. DLM lock time (non-blocking requests) - 2. DLM lock time (blocking requests) - 3. Inter-request time (again to the DLM) - -A non-blocking request is one which will complete right -away, whatever the state of the DLM lock in question. That -currently means any requests when (a) the current state of -the lock is exclusive, i.e. a lock demotion (b) the requested -state is either null or unlocked (again, a demotion) or (c) the -"try lock" flag is set. A blocking request covers all the other -lock requests. - -There are two counters. The first is there primarily to show -how many lock requests have been made, and thus how much data -has gone into the mean/variance calculations. The other counter -is counting queuing of holders at the top layer of the glock -code. Hopefully that number will be a lot larger than the number -of dlm lock requests issued. - -So why gather these statistics? There are several reasons -we'd like to get a better idea of these timings: - -1. To be able to better set the glock "min hold time" -2. To spot performance issues more easily -3. To improve the algorithm for selecting resource groups for -allocation (to base it on lock wait time, rather than blindly -using a "try lock") - -Due to the smoothing action of the updates, a step change in -some input quantity being sampled will only fully be taken -into account after 8 samples (or 4 for the variance) and this -needs to be carefully considered when interpreting the -results. - -Knowing both the time it takes a lock request to complete and -the average time between lock requests for a glock means we -can compute the total percentage of the time for which the -node is able to use a glock vs. time that the rest of the -cluster has its share. That will be very useful when setting -the lock min hold time. - -Great care has been taken to ensure that we -measure exactly the quantities that we want, as accurately -as possible. There are always inaccuracies in any -measuring system, but I hope this is as accurate as we -can reasonably make it. - -Per sb stats can be found here: -/sys/kernel/debug/gfs2//sbstats -Per glock stats can be found here: -/sys/kernel/debug/gfs2//glstats - -Assuming that debugfs is mounted on /sys/kernel/debug and also -that is replaced with the name of the gfs2 filesystem -in question. - -The abbreviations used in the output as are follows: - -srtt - Smoothed round trip time for non-blocking dlm requests -srttvar - Variance estimate for srtt -srttb - Smoothed round trip time for (potentially) blocking dlm requests -srttvarb - Variance estimate for srttb -sirt - Smoothed inter-request time (for dlm requests) -sirtvar - Variance estimate for sirt -dlm - Number of dlm requests made (dcnt in glstats file) -queue - Number of glock requests queued (qcnt in glstats file) - -The sbstats file contains a set of these stats for each glock type (so 8 lines -for each type) and for each cpu (one column per cpu). The glstats file contains -a set of these stats for each glock in a similar format to the glocks file, but -using the format mean/variance for each of the timing stats. - -The gfs2_glock_lock_time tracepoint prints out the current values of the stats -for the glock in question, along with some addition information on each dlm -reply that is received: - -status - The status of the dlm request -flags - The dlm request flags -tdiff - The time taken by this specific request -(remaining fields as per above list) - diff --git a/trunk/Documentation/filesystems/gfs2.txt b/trunk/Documentation/filesystems/gfs2.txt index cc4f2306609e..4cda926628aa 100644 --- a/trunk/Documentation/filesystems/gfs2.txt +++ b/trunk/Documentation/filesystems/gfs2.txt @@ -1,7 +1,7 @@ Global File System ------------------ -https://fedorahosted.org/cluster/wiki/HomePage +http://sources.redhat.com/cluster/wiki/ GFS is a cluster file system. It allows a cluster of computers to simultaneously use a block device that is shared between them (with FC, @@ -30,8 +30,7 @@ needed, simply: If you are using Fedora, you need to install the gfs2-utils package and, for lock_dlm, you will also need to install the cman package -and write a cluster.conf as per the documentation. For F17 and above -cman has been replaced by the dlm package. +and write a cluster.conf as per the documentation. GFS2 is not on-disk compatible with previous versions of GFS, but it is pretty close. @@ -40,6 +39,8 @@ The following man pages can be found at the URL above: fsck.gfs2 to repair a filesystem gfs2_grow to expand a filesystem online gfs2_jadd to add journals to a filesystem online - tunegfs2 to manipulate, examine and tune a filesystem + gfs2_tool to manipulate, examine and tune a filesystem + gfs2_quota to examine and change quota values in a filesystem gfs2_convert to convert a gfs filesystem to gfs2 in-place + mount.gfs2 to help mount(8) mount a filesystem mkfs.gfs2 to make a filesystem diff --git a/trunk/Documentation/filesystems/proc.txt b/trunk/Documentation/filesystems/proc.txt index ef088e55ab2e..b7413cb46dcb 100644 --- a/trunk/Documentation/filesystems/proc.txt +++ b/trunk/Documentation/filesystems/proc.txt @@ -996,6 +996,7 @@ Table 1-9: Network info in /proc/net snmp SNMP data sockstat Socket statistics tcp TCP sockets + tr_rif Token ring RIF routing table udp UDP sockets unix UNIX domain sockets wireless Wireless interface data (Wavelan etc) diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index e275432ef2c7..c1601e5a8b71 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -110,7 +110,6 @@ parameter is applicable: USB USB support is enabled. USBHID USB Human Interface Device support is enabled. V4L Video For Linux support is enabled. - VMMIO Driver for memory mapped virtio devices is enabled. VGA The VGA console has been enabled. VT Virtual terminal support is enabled. WDT Watchdog support is enabled. @@ -2162,9 +2161,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. on: Turn realloc on realloc same as realloc=on noari do not use PCIe ARI. - pcie_scan_all Scan all possible PCIe devices. Otherwise we - only look for one device below a PCIe downstream - port. pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power Management. @@ -2334,100 +2330,18 @@ bytes respectively. Such letter suffixes can also be entirely omitted. ramdisk_size= [RAM] Sizes of RAM disks in kilobytes See Documentation/blockdev/ramdisk.txt. - rcutree.blimit= [KNL,BOOT] + rcupdate.blimit= [KNL,BOOT] Set maximum number of finished RCU callbacks to process in one batch. - rcutree.qhimark= [KNL,BOOT] + rcupdate.qhimark= [KNL,BOOT] Set threshold of queued RCU callbacks over which batch limiting is disabled. - rcutree.qlowmark= [KNL,BOOT] + rcupdate.qlowmark= [KNL,BOOT] Set threshold of queued RCU callbacks below which batch limiting is re-enabled. - rcutree.rcu_cpu_stall_suppress= [KNL,BOOT] - Suppress RCU CPU stall warning messages. - - rcutree.rcu_cpu_stall_timeout= [KNL,BOOT] - Set timeout for RCU CPU stall warning messages. - - rcutorture.fqs_duration= [KNL,BOOT] - Set duration of force_quiescent_state bursts. - - rcutorture.fqs_holdoff= [KNL,BOOT] - Set holdoff time within force_quiescent_state bursts. - - rcutorture.fqs_stutter= [KNL,BOOT] - Set wait time between force_quiescent_state bursts. - - rcutorture.irqreader= [KNL,BOOT] - Test RCU readers from irq handlers. - - rcutorture.n_barrier_cbs= [KNL,BOOT] - Set callbacks/threads for rcu_barrier() testing. - - rcutorture.nfakewriters= [KNL,BOOT] - Set number of concurrent RCU writers. These just - stress RCU, they don't participate in the actual - test, hence the "fake". - - rcutorture.nreaders= [KNL,BOOT] - Set number of RCU readers. - - rcutorture.onoff_holdoff= [KNL,BOOT] - Set time (s) after boot for CPU-hotplug testing. - - rcutorture.onoff_interval= [KNL,BOOT] - Set time (s) between CPU-hotplug operations, or - zero to disable CPU-hotplug testing. - - rcutorture.shuffle_interval= [KNL,BOOT] - Set task-shuffle interval (s). Shuffling tasks - allows some CPUs to go into dyntick-idle mode - during the rcutorture test. - - rcutorture.shutdown_secs= [KNL,BOOT] - Set time (s) after boot system shutdown. This - is useful for hands-off automated testing. - - rcutorture.stall_cpu= [KNL,BOOT] - Duration of CPU stall (s) to test RCU CPU stall - warnings, zero to disable. - - rcutorture.stall_cpu_holdoff= [KNL,BOOT] - Time to wait (s) after boot before inducing stall. - - rcutorture.stat_interval= [KNL,BOOT] - Time (s) between statistics printk()s. - - rcutorture.stutter= [KNL,BOOT] - Time (s) to stutter testing, for example, specifying - five seconds causes the test to run for five seconds, - wait for five seconds, and so on. This tests RCU's - ability to transition abruptly to and from idle. - - rcutorture.test_boost= [KNL,BOOT] - Test RCU priority boosting? 0=no, 1=maybe, 2=yes. - "Maybe" means test if the RCU implementation - under test support RCU priority boosting. - - rcutorture.test_boost_duration= [KNL,BOOT] - Duration (s) of each individual boost test. - - rcutorture.test_boost_interval= [KNL,BOOT] - Interval (s) between each boost test. - - rcutorture.test_no_idle_hz= [KNL,BOOT] - Test RCU's dyntick-idle handling. See also the - rcutorture.shuffle_interval parameter. - - rcutorture.torture_type= [KNL,BOOT] - Specify the RCU implementation to test. - - rcutorture.verbose= [KNL,BOOT] - Enable additional printk() statements. - rdinit= [KNL] Format: Run specified binary instead of /init from the ramdisk, @@ -2933,22 +2847,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. video= [FB] Frame buffer configuration See Documentation/fb/modedb.txt. - virtio_mmio.device= - [VMMIO] Memory mapped virtio (platform) device. - - @:[:] - where: - := size (can use standard suffixes - like K, M and G) - := physical base address - := interrupt number (as passed to - request_irq()) - := (optional) platform device id - example: - virtio_mmio.device=1K@0x100b0000:48:7 - - Can be used multiple times for multiple devices. - vga= [BOOT,X86-32] Select a particular video mode See Documentation/x86/boot.txt and Documentation/svga.txt. diff --git a/trunk/Documentation/networking/00-INDEX b/trunk/Documentation/networking/00-INDEX index 2cc3c7733a2f..9ad9ddeb384c 100644 --- a/trunk/Documentation/networking/00-INDEX +++ b/trunk/Documentation/networking/00-INDEX @@ -1,5 +1,7 @@ 00-INDEX - this file +3c359.txt + - information on the 3Com TokenLink Velocity XL (3c5359) driver. 3c505.txt - information on the 3Com EtherLink Plus (3c505) driver. 3c509.txt @@ -140,6 +142,8 @@ netif-msg.txt - Design of the network interface message level setting (NETIF_MSG_*). nfc.txt - The Linux Near Field Communication (NFS) subsystem. +olympic.txt + - IBM PCI Pit/Pit-Phy/Olympic Token Ring driver info. openvswitch.txt - Open vSwitch developer documentation. operstates.txt @@ -180,6 +184,8 @@ skfp.txt - SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info. smc9.txt - the driver for SMC's 9000 series of Ethernet cards +smctr.txt + - SMC TokenCard TokenRing Linux driver info. spider-net.txt - README for the Spidernet Driver (as found in PS3 / Cell BE). stmmac.txt @@ -194,6 +200,8 @@ tcp-thin.txt - kernel tuning options for low rate 'thin' TCP streams. tlan.txt - ThunderLAN (Compaq Netelligent 10/100, Olicom OC-2xxx) driver info. +tms380tr.txt + - SysKonnect Token Ring ISA/PCI adapter driver info. tproxy.txt - Transparent proxy support user guide. tuntap.txt diff --git a/trunk/Documentation/networking/3c359.txt b/trunk/Documentation/networking/3c359.txt new file mode 100644 index 000000000000..dadfe8147ab8 --- /dev/null +++ b/trunk/Documentation/networking/3c359.txt @@ -0,0 +1,58 @@ + +3COM PCI TOKEN LINK VELOCITY XL TOKEN RING CARDS README + +Release 0.9.0 - Release + Jul 17th 2000 Mike Phillips + + 1.2.0 - Final + Feb 17th 2002 Mike Phillips + Updated for submission to the 2.4.x kernel. + +Thanks: + Terry Murphy from 3Com for tech docs and support, + Adam D. Ligas for testing the driver. + +Note: + This driver will NOT work with the 3C339 Token Ring cards, you need +to use the tms380 driver instead. + +Options: + +The driver accepts three options: ringspeed, pkt_buf_sz and message_level. + +These options can be specified differently for each card found. + +ringspeed: Has one of three settings 0 (default), 4 or 16. 0 will +make the card autosense the ringspeed and join at the appropriate speed, +this will be the default option for most people. 4 or 16 allow you to +explicitly force the card to operate at a certain speed. The card will fail +if you try to insert it at the wrong speed. (Although some hubs will allow +this so be *very* careful). The main purpose for explicitly setting the ring +speed is for when the card is first on the ring. In autosense mode, if the card +cannot detect any active monitors on the ring it will open at the same speed as +its last opening. This can be hazardous if this speed does not match the speed +you want the ring to operate at. + +pkt_buf_sz: This is this initial receive buffer allocation size. This will +default to 4096 if no value is entered. You may increase performance of the +driver by setting this to a value larger than the network packet size, although +the driver now re-sizes buffers based on MTU settings as well. + +message_level: Controls level of messages created by the driver. Defaults to 0: +which only displays start-up and critical messages. Presently any non-zero +value will display all soft messages as well. NB This does not turn +debugging messages on, that must be done by modified the source code. + +Variable MTU size: + +The driver can handle a MTU size up to either 4500 or 18000 depending upon +ring speed. The driver also changes the size of the receive buffers as part +of the mtu re-sizing, so if you set mtu = 18000, you will need to be able +to allocate 16 * (sk_buff with 18000 buffer size) call it 18500 bytes per ring +position = 296,000 bytes of memory space, plus of course anything +necessary for the tx sk_buff's. Remember this is per card, so if you are +building routers, gateway's etc, you could start to use a lot of memory +real fast. + +2/17/02 Mike Phillips + diff --git a/trunk/Documentation/networking/3c509.txt b/trunk/Documentation/networking/3c509.txt index fbf722e15ac3..dcc9eaf59395 100644 --- a/trunk/Documentation/networking/3c509.txt +++ b/trunk/Documentation/networking/3c509.txt @@ -25,6 +25,7 @@ models: 3c509B (later revision of the ISA card; supports full-duplex) 3c589 (PCMCIA) 3c589B (later revision of the 3c589; supports full-duplex) + 3c529 (MCA) 3c579 (EISA) Large portions of this documentation were heavily borrowed from the guide diff --git a/trunk/Documentation/networking/batman-adv.txt b/trunk/Documentation/networking/batman-adv.txt index 75a592365af9..220a58c2fb11 100644 --- a/trunk/Documentation/networking/batman-adv.txt +++ b/trunk/Documentation/networking/batman-adv.txt @@ -1,3 +1,5 @@ +[state: 21-08-2011] + BATMAN-ADV ---------- @@ -66,11 +68,10 @@ All mesh wide settings can be found in batman's own interface folder: # ls /sys/class/net/bat0/mesh/ -# aggregated_ogms gw_bandwidth log_level -# ap_isolation gw_mode orig_interval -# bonding gw_sel_class routing_algo -# bridge_loop_avoidance hop_penalty vis_mode -# fragmentation +# aggregated_ogms fragmentation hop_penalty +# ap_isolation gw_bandwidth log_level +# bonding gw_mode orig_interval +# bridge_loop_avoidance gw_sel_class vis_mode There is a special folder for debugging information: diff --git a/trunk/Documentation/networking/fore200e.txt b/trunk/Documentation/networking/fore200e.txt index d52af53efdc5..f648eb265188 100644 --- a/trunk/Documentation/networking/fore200e.txt +++ b/trunk/Documentation/networking/fore200e.txt @@ -11,10 +11,12 @@ i386, alpha (untested), powerpc, sparc and sparc64 archs. The intent is to enable the use of different models of FORE adapters at the same time, by hosts that have several bus interfaces (such as PCI+SBUS, -or PCI+EISA). +PCI+MCA or PCI+EISA). Only PCI and SBUS devices are currently supported by the driver, but support -for other bus interfaces such as EISA should not be too hard to add. +for other bus interfaces such as EISA should not be too hard to add (this may +be more tricky for the MCA bus, though, as FORE made some MCA-specific +modifications to the adapter's AALI interface). Firmware Copyright Notice diff --git a/trunk/Documentation/networking/ieee802154.txt b/trunk/Documentation/networking/ieee802154.txt index 703cf4370c79..1dc1c24a7547 100644 --- a/trunk/Documentation/networking/ieee802154.txt +++ b/trunk/Documentation/networking/ieee802154.txt @@ -4,22 +4,15 @@ Introduction ============ -The IEEE 802.15.4 working group focuses on standartization of bottom -two layers: Medium Accsess Control (MAC) and Physical (PHY). And there -are mainly two options available for upper layers: - - ZigBee - proprietary protocol from ZigBee Alliance - - 6LowPAN - IPv6 networking over low rate personal area networks The Linux-ZigBee project goal is to provide complete implementation -of IEEE 802.15.4 and 6LoWPAN protocols. IEEE 802.15.4 is a stack +of IEEE 802.15.4 / ZigBee / 6LoWPAN protocols. IEEE 802.15.4 is a stack of protocols for organizing Low-Rate Wireless Personal Area Networks. -The stack is composed of three main parts: - - IEEE 802.15.4 layer; We have chosen to use plain Berkeley socket API, - the generic Linux networking stack to transfer IEEE 802.15.4 messages - and a special protocol over genetlink for configuration/management - - MAC - provides access to shared channel and reliable data delivery - - PHY - represents device drivers +Currently only IEEE 802.15.4 layer is implemented. We have chosen +to use plain Berkeley socket API, the generic Linux networking stack +to transfer IEEE 802.15.4 messages and a special protocol over genetlink +for configuration/management Socket API @@ -36,6 +29,15 @@ or git tree at git://linux-zigbee.git.sourceforge.net/gitroot/linux-zigbee). One can use SOCK_RAW for passing raw data towards device xmit function. YMMV. +MLME - MAC Level Management +============================ + +Most of IEEE 802.15.4 MLME interfaces are directly mapped on netlink commands. +See the include/net/nl802154.h header. Our userspace tools package +(see above) provides CLI configuration utility for radio interfaces and simple +coordinator for IEEE 802.15.4 networks as an example users of MLME protocol. + + Kernel side ============= @@ -49,15 +51,6 @@ Like with WiFi, there are several types of devices implementing IEEE 802.15.4. Those types of devices require different approach to be hooked into Linux kernel. -MLME - MAC Level Management -============================ - -Most of IEEE 802.15.4 MLME interfaces are directly mapped on netlink commands. -See the include/net/nl802154.h header. Our userspace tools package -(see above) provides CLI configuration utility for radio interfaces and simple -coordinator for IEEE 802.15.4 networks as an example users of MLME protocol. - - HardMAC ======= @@ -80,47 +73,11 @@ We provide an example of simple HardMAC driver at drivers/ieee802154/fakehard.c SoftMAC ======= -The MAC is the middle layer in the IEEE 802.15.4 Linux stack. This moment it -provides interface for drivers registration and management of slave interfaces. - -NOTE: Currently the only monitor device type is supported - it's IEEE 802.15.4 -stack interface for network sniffers (e.g. WireShark). - -This layer is going to be extended soon. +We are going to provide intermediate layer implementing IEEE 802.15.4 MAC +in software. This is currently WIP. See header include/net/mac802154.h and several drivers in drivers/ieee802154/. - -Device drivers API -================== - -The include/net/mac802154.h defines following functions: - - struct ieee802154_dev *ieee802154_alloc_device - (size_t priv_size, struct ieee802154_ops *ops): - allocation of IEEE 802.15.4 compatible device - - - void ieee802154_free_device(struct ieee802154_dev *dev): - freeing allocated device - - - int ieee802154_register_device(struct ieee802154_dev *dev): - register PHY in the system - - - void ieee802154_unregister_device(struct ieee802154_dev *dev): - freeing registered PHY - -Moreover IEEE 802.15.4 device operations structure should be filled. - -Fake drivers -============ - -In addition there are two drivers available which simulate real devices with -HardMAC (fakehard) and SoftMAC (fakelb - IEEE 802.15.4 loopback driver) -interfaces. This option provides possibility to test and debug stack without -usage of real hardware. - -See sources in drivers/ieee802154 folder for more details. - - 6LoWPAN Linux implementation ============================ diff --git a/trunk/Documentation/networking/olympic.txt b/trunk/Documentation/networking/olympic.txt new file mode 100644 index 000000000000..b95b5bf96751 --- /dev/null +++ b/trunk/Documentation/networking/olympic.txt @@ -0,0 +1,79 @@ + +IBM PCI Pit/Pit-Phy/Olympic CHIPSET BASED TOKEN RING CARDS README + +Release 0.2.0 - Release + June 8th 1999 Peter De Schrijver & Mike Phillips +Release 0.9.C - Release + April 18th 2001 Mike Phillips + +Thanks: +Erik De Cock, Adrian Bridgett and Frank Fiene for their +patience and testing. +Donald Champion for the cardbus support +Kyle Lucke for the dma api changes. +Jonathon Bitner for hardware support. +Everybody on linux-tr for their continued support. + +Options: + +The driver accepts four options: ringspeed, pkt_buf_sz, +message_level and network_monitor. + +These options can be specified differently for each card found. + +ringspeed: Has one of three settings 0 (default), 4 or 16. 0 will +make the card autosense the ringspeed and join at the appropriate speed, +this will be the default option for most people. 4 or 16 allow you to +explicitly force the card to operate at a certain speed. The card will fail +if you try to insert it at the wrong speed. (Although some hubs will allow +this so be *very* careful). The main purpose for explicitly setting the ring +speed is for when the card is first on the ring. In autosense mode, if the card +cannot detect any active monitors on the ring it will not open, so you must +re-init the card at the appropriate speed. Unfortunately at present the only +way of doing this is rmmod and insmod which is a bit tough if it is compiled +in the kernel. + +pkt_buf_sz: This is this initial receive buffer allocation size. This will +default to 4096 if no value is entered. You may increase performance of the +driver by setting this to a value larger than the network packet size, although +the driver now re-sizes buffers based on MTU settings as well. + +message_level: Controls level of messages created by the driver. Defaults to 0: +which only displays start-up and critical messages. Presently any non-zero +value will display all soft messages as well. NB This does not turn +debugging messages on, that must be done by modified the source code. + +network_monitor: Any non-zero value will provide a quasi network monitoring +mode. All unexpected MAC frames (beaconing etc.) will be received +by the driver and the source and destination addresses printed. +Also an entry will be added in /proc/net called olympic_tr%d, where tr%d +is the registered device name, i.e tr0, tr1, etc. This displays low +level information about the configuration of the ring and the adapter. +This feature has been designed for network administrators to assist in +the diagnosis of network / ring problems. (This used to OLYMPIC_NETWORK_MONITOR, +but has now changed to allow each adapter to be configured differently and +to alleviate the necessity to re-compile olympic to turn the option on). + +Multi-card: + +The driver will detect multiple cards and will work with shared interrupts, +each card is assigned the next token ring device, i.e. tr0 , tr1, tr2. The +driver should also happily reside in the system with other drivers. It has +been tested with ibmtr.c running, and I personally have had one Olicom PCI +card and two IBM olympic cards (all on the same interrupt), all running +together. + +Variable MTU size: + +The driver can handle a MTU size up to either 4500 or 18000 depending upon +ring speed. The driver also changes the size of the receive buffers as part +of the mtu re-sizing, so if you set mtu = 18000, you will need to be able +to allocate 16 * (sk_buff with 18000 buffer size) call it 18500 bytes per ring +position = 296,000 bytes of memory space, plus of course anything +necessary for the tx sk_buff's. Remember this is per card, so if you are +building routers, gateway's etc, you could start to use a lot of memory +real fast. + + +6/8/99 Peter De Schrijver and Mike Phillips + diff --git a/trunk/Documentation/networking/smctr.txt b/trunk/Documentation/networking/smctr.txt new file mode 100644 index 000000000000..9af25b810c1f --- /dev/null +++ b/trunk/Documentation/networking/smctr.txt @@ -0,0 +1,66 @@ +Text File for the SMC TokenCard TokenRing Linux driver (smctr.c). + By Jay Schulist + +The Linux SMC Token Ring driver works with the SMC TokenCard Elite (8115T) +ISA and SMC TokenCard Elite/A (8115T/A) MCA adapters. + +Latest information on this driver can be obtained on the Linux-SNA WWW site. +Please point your browser to: http://www.linux-sna.org + +This driver is rather simple to use. Select Y to Token Ring adapter support +in the kernel configuration. A choice for SMC Token Ring adapters will +appear. This drives supports all SMC ISA/MCA adapters. Choose this +option. I personally recommend compiling the driver as a module (M), but if you +you would like to compile it statically answer Y instead. + +This driver supports multiple adapters without the need to load multiple copies +of the driver. You should be able to load up to 7 adapters without any kernel +modifications, if you are in need of more please contact the maintainer of this +driver. + +Load the driver either by lilo/loadlin or as a module. When a module using the +following command will suffice for most: + +# modprobe smctr +smctr.c: v1.00 12/6/99 by jschlst@samba.org +tr0: SMC TokenCard 8115T at Io 0x300, Irq 10, Rom 0xd8000, Ram 0xcc000. + +Now just setup the device via ifconfig and set and routes you may have. After +this you are ready to start sending some tokens. + +Errata: +1). For anyone wondering where to pick up the SMC adapters please browse + to http://www.smc.com + +2). If you are the first/only Token Ring Client on a Token Ring LAN, please + specify the ringspeed with the ringspeed=[4/16] module option. If no + ringspeed is specified the driver will attempt to autodetect the ring + speed and/or if the adapter is the first/only station on the ring take + the appropriate actions. + + NOTE: Default ring speed is 16MB UTP. + +3). PnP support for this adapter sucks. I recommend hard setting the + IO/MEM/IRQ by the jumpers on the adapter. If this is not possible + load the module with the following io=[ioaddr] mem=[mem_addr] + irq=[irq_num]. + + The following IRQ, IO, and MEM settings are supported. + + IO ports: + 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0, 0x300, + 0x320, 0x340, 0x360, 0x380. + + IRQs: + 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15 + + Memory addresses: + 0xA0000, 0xA4000, 0xA8000, 0xAC000, 0xB0000, 0xB4000, + 0xB8000, 0xBC000, 0xC0000, 0xC4000, 0xC8000, 0xCC000, + 0xD0000, 0xD4000, 0xD8000, 0xDC000, 0xE0000, 0xE4000, + 0xE8000, 0xEC000, 0xF0000, 0xF4000, 0xF8000, 0xFC000 + +This driver is under the GNU General Public License. Its Firmware image is +included as an initialized C-array and is licensed by SMC to the Linux +users of this driver. However no warranty about its fitness is expressed or +implied by SMC. diff --git a/trunk/Documentation/networking/tms380tr.txt b/trunk/Documentation/networking/tms380tr.txt new file mode 100644 index 000000000000..1f73e13058df --- /dev/null +++ b/trunk/Documentation/networking/tms380tr.txt @@ -0,0 +1,147 @@ +Text file for the Linux SysKonnect Token Ring ISA/PCI Adapter Driver. + Text file by: Jay Schulist + +The Linux SysKonnect Token Ring driver works with the SysKonnect TR4/16(+) ISA, +SysKonnect TR4/16(+) PCI, SysKonnect TR4/16 PCI, and older revisions of the +SK NET TR4/16 ISA card. + +Latest information on this driver can be obtained on the Linux-SNA WWW site. +Please point your browser to: +http://www.linux-sna.org + +Many thanks to Christoph Goos for his excellent work on this driver and +SysKonnect for donating the adapters to Linux-SNA for the testing and +maintenance of this device driver. + +Important information to be noted: +1. Adapters can be slow to open (~20 secs) and close (~5 secs), please be + patient. +2. This driver works very well when autoprobing for adapters. Why even + think about those nasty io/int/dma settings of modprobe when the driver + will do it all for you! + +This driver is rather simple to use. Select Y to Token Ring adapter support +in the kernel configuration. A choice for SysKonnect Token Ring adapters will +appear. This drives supports all SysKonnect ISA and PCI adapters. Choose this +option. I personally recommend compiling the driver as a module (M), but if you +you would like to compile it statically answer Y instead. + +This driver supports multiple adapters without the need to load multiple copies +of the driver. You should be able to load up to 7 adapters without any kernel +modifications, if you are in need of more please contact the maintainer of this +driver. + +Load the driver either by lilo/loadlin or as a module. When a module using the +following command will suffice for most: + +# modprobe sktr + +This will produce output similar to the following: (Output is user specific) + +sktr.c: v1.01 08/29/97 by Christoph Goos +tr0: SK NET TR 4/16 PCI found at 0x6100, using IRQ 17. +tr1: SK NET TR 4/16 PCI found at 0x6200, using IRQ 16. +tr2: SK NET TR 4/16 ISA found at 0xa20, using IRQ 10 and DMA 5. + +Now just setup the device via ifconfig and set and routes you may have. After +this you are ready to start sending some tokens. + +Errata: +For anyone wondering where to pick up the SysKonnect adapters please browse +to http://www.syskonnect.com + +This driver is under the GNU General Public License. Its Firmware image is +included as an initialized C-array and is licensed by SysKonnect to the Linux +users of this driver. However no warranty about its fitness is expressed or +implied by SysKonnect. + +Below find attached the setting for the SK NET TR 4/16 ISA adapters +------------------------------------------------------------------- + + *************************** + *** C O N T E N T S *** + *************************** + + 1) Location of DIP-Switch W1 + 2) Default settings + 3) DIP-Switch W1 description + + + ============================================================== + CHAPTER 1 LOCATION OF DIP-SWITCH + ============================================================== + +UÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +þUÄÄÄÄÄÄ¿ UÄÄÄÄÄ¿ UÄÄÄ¿ þ +þAÄÄÄÄÄÄU W1 AÄÄÄÄÄU UÄÄÄÄ¿ þ þ þ +þUÄÄÄÄÄÄ¿ þ þ þ þ UÄÄÅ¿ +þAÄÄÄÄÄÄU UÄÄÄÄÄÄÄÄÄÄÄ¿ AÄÄÄÄU þ þ þ þþ +þUÄÄÄÄÄÄ¿ þ þ UÄÄÄ¿ AÄÄÄU AÄÄÅU +þAÄÄÄÄÄÄU þ TMS380C26 þ þ þ þ +þUÄÄÄÄÄÄ¿ þ þ AÄÄÄU AÄ¿ +þAÄÄÄÄÄÄU þ þ þ þ +þ AÄÄÄÄÄÄÄÄÄÄÄU þ þ +þ þ þ +þ AÄU +þ þ +þ þ +þ þ +þ þ +AÄÄÄÄÄÄÄÄÄÄÄÄAÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄAÄÄAÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄAÄÄÄÄÄÄÄÄÄU + AÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄU AÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄU + + ============================================================== + CHAPTER 2 DEFAULT SETTINGS + ============================================================== + + W1 1 2 3 4 5 6 7 8 + +------------------------------+ + | ON X | + | OFF X X X X X X X | + +------------------------------+ + + W1.1 = ON Adapter drives address lines SA17..19 + W1.2 - 1.5 = OFF BootROM disabled + W1.6 - 1.8 = OFF I/O address 0A20h + + ============================================================== + CHAPTER 3 DIP SWITCH W1 DESCRIPTION + ============================================================== + + UÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄ¿ ON + þ 1 þ 2 þ 3 þ 4 þ 5 þ 6 þ 7 þ 8 þ + AÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄU OFF + |AD | BootROM Addr. | I/O | + +-+-+-------+-------+-----+-----+ + | | | + | | +------ 6 7 8 + | | ON ON ON 1900h + | | ON ON OFF 0900h + | | ON OFF ON 1980h + | | ON OFF OFF 0980h + | | OFF ON ON 1b20h + | | OFF ON OFF 0b20h + | | OFF OFF ON 1a20h + | | OFF OFF OFF 0a20h (+) + | | + | | + | +-------- 2 3 4 5 + | OFF x x x disabled (+) + | ON ON ON ON C0000 + | ON ON ON OFF C4000 + | ON ON OFF ON C8000 + | ON ON OFF OFF CC000 + | ON OFF ON ON D0000 + | ON OFF ON OFF D4000 + | ON OFF OFF ON D8000 + | ON OFF OFF OFF DC000 + | + | + +----- 1 + OFF adapter does NOT drive SA<17..19> + ON adapter drives SA<17..19> (+) + + + (+) means default setting + + ******************************** diff --git a/trunk/Documentation/pinctrl.txt b/trunk/Documentation/pinctrl.txt index e40f4b4e1977..d97bccf46147 100644 --- a/trunk/Documentation/pinctrl.txt +++ b/trunk/Documentation/pinctrl.txt @@ -152,9 +152,11 @@ static const struct foo_group foo_groups[] = { }; -static int foo_get_groups_count(struct pinctrl_dev *pctldev) +static int foo_list_groups(struct pinctrl_dev *pctldev, unsigned selector) { - return ARRAY_SIZE(foo_groups); + if (selector >= ARRAY_SIZE(foo_groups)) + return -EINVAL; + return 0; } static const char *foo_get_group_name(struct pinctrl_dev *pctldev, @@ -173,7 +175,7 @@ static int foo_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, } static struct pinctrl_ops foo_pctrl_ops = { - .get_groups_count = foo_get_groups_count, + .list_groups = foo_list_groups, .get_group_name = foo_get_group_name, .get_group_pins = foo_get_group_pins, }; @@ -184,12 +186,13 @@ static struct pinctrl_desc foo_desc = { .pctlops = &foo_pctrl_ops, }; -The pin control subsystem will call the .get_groups_count() function to -determine total number of legal selectors, then it will call the other functions -to retrieve the name and pins of the group. Maintaining the data structure of -the groups is up to the driver, this is just a simple example - in practice you -may need more entries in your group structure, for example specific register -ranges associated with each group and so on. +The pin control subsystem will call the .list_groups() function repeatedly +beginning on 0 until it returns non-zero to determine legal selectors, then +it will call the other functions to retrieve the name and pins of the group. +Maintaining the data structure of the groups is up to the driver, this is +just a simple example - in practice you may need more entries in your group +structure, for example specific register ranges associated with each group +and so on. Pin configuration @@ -603,9 +606,11 @@ static const struct foo_group foo_groups[] = { }; -static int foo_get_groups_count(struct pinctrl_dev *pctldev) +static int foo_list_groups(struct pinctrl_dev *pctldev, unsigned selector) { - return ARRAY_SIZE(foo_groups); + if (selector >= ARRAY_SIZE(foo_groups)) + return -EINVAL; + return 0; } static const char *foo_get_group_name(struct pinctrl_dev *pctldev, @@ -624,7 +629,7 @@ static int foo_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, } static struct pinctrl_ops foo_pctrl_ops = { - .get_groups_count = foo_get_groups_count, + .list_groups = foo_list_groups, .get_group_name = foo_get_group_name, .get_group_pins = foo_get_group_pins, }; @@ -635,7 +640,7 @@ struct foo_pmx_func { const unsigned num_groups; }; -static const char * const spi0_groups[] = { "spi0_0_grp", "spi0_1_grp" }; +static const char * const spi0_groups[] = { "spi0_1_grp" }; static const char * const i2c0_groups[] = { "i2c0_grp" }; static const char * const mmc0_groups[] = { "mmc0_1_grp", "mmc0_2_grp", "mmc0_3_grp" }; @@ -658,9 +663,11 @@ static const struct foo_pmx_func foo_functions[] = { }, }; -int foo_get_functions_count(struct pinctrl_dev *pctldev) +int foo_list_funcs(struct pinctrl_dev *pctldev, unsigned selector) { - return ARRAY_SIZE(foo_functions); + if (selector >= ARRAY_SIZE(foo_functions)) + return -EINVAL; + return 0; } const char *foo_get_fname(struct pinctrl_dev *pctldev, unsigned selector) @@ -696,7 +703,7 @@ void foo_disable(struct pinctrl_dev *pctldev, unsigned selector, } struct pinmux_ops foo_pmxops = { - .get_functions_count = foo_get_functions_count, + .list_functions = foo_list_funcs, .get_function_name = foo_get_fname, .get_function_groups = foo_get_groups, .enable = foo_enable, @@ -779,7 +786,7 @@ and spi on the second function mapping: #include -static const struct pinctrl_map mapping[] __initconst = { +static const struct pinctrl_map __initdata mapping[] = { { .dev_name = "foo-spi.0", .name = PINCTRL_STATE_DEFAULT, @@ -945,13 +952,13 @@ case), we define a mapping like this: The result of grabbing this mapping from the device with something like this (see next paragraph): - p = devm_pinctrl_get(dev); + p = pinctrl_get(dev); s = pinctrl_lookup_state(p, "8bit"); ret = pinctrl_select_state(p, s); or more simply: - p = devm_pinctrl_get_select(dev, "8bit"); + p = pinctrl_get_select(dev, "8bit"); Will be that you activate all the three bottom records in the mapping at once. Since they share the same name, pin controller device, function and @@ -985,7 +992,7 @@ foo_probe() /* Allocate a state holder named "foo" etc */ struct foo_state *foo = ...; - foo->p = devm_pinctrl_get(&device); + foo->p = pinctrl_get(&device); if (IS_ERR(foo->p)) { /* FIXME: clean up "foo" here */ return PTR_ERR(foo->p); @@ -993,17 +1000,24 @@ foo_probe() foo->s = pinctrl_lookup_state(foo->p, PINCTRL_STATE_DEFAULT); if (IS_ERR(foo->s)) { + pinctrl_put(foo->p); /* FIXME: clean up "foo" here */ return PTR_ERR(s); } ret = pinctrl_select_state(foo->s); if (ret < 0) { + pinctrl_put(foo->p); /* FIXME: clean up "foo" here */ return ret; } } +foo_remove() +{ + pinctrl_put(state->p); +} + This get/lookup/select/put sequence can just as well be handled by bus drivers if you don't want each and every driver to handle it and you know the arrangement on your bus. @@ -1015,11 +1029,6 @@ The semantics of the pinctrl APIs are: kernel memory to hold the pinmux state. All mapping table parsing or similar slow operations take place within this API. -- devm_pinctrl_get() is a variant of pinctrl_get() that causes pinctrl_put() - to be called automatically on the retrieved pointer when the associated - device is removed. It is recommended to use this function over plain - pinctrl_get(). - - pinctrl_lookup_state() is called in process context to obtain a handle to a specific state for a the client device. This operation may be slow too. @@ -1032,30 +1041,14 @@ The semantics of the pinctrl APIs are: - pinctrl_put() frees all information associated with a pinctrl handle. -- devm_pinctrl_put() is a variant of pinctrl_put() that may be used to - explicitly destroy a pinctrl object returned by devm_pinctrl_get(). - However, use of this function will be rare, due to the automatic cleanup - that will occur even without calling it. - - pinctrl_get() must be paired with a plain pinctrl_put(). - pinctrl_get() may not be paired with devm_pinctrl_put(). - devm_pinctrl_get() can optionally be paired with devm_pinctrl_put(). - devm_pinctrl_get() may not be paired with plain pinctrl_put(). - Usually the pin control core handled the get/put pair and call out to the device drivers bookkeeping operations, like checking available functions and the associated pins, whereas the enable/disable pass on to the pin controller driver which takes care of activating and/or deactivating the mux setting by quickly poking some registers. -The pins are allocated for your device when you issue the devm_pinctrl_get() -call, after this you should be able to see this in the debugfs listing of all -pins. - -NOTE: the pinctrl system will return -EPROBE_DEFER if it cannot find the -requested pinctrl handles, for example if the pinctrl driver has not yet -registered. Thus make sure that the error path in your driver gracefully -cleans up and is ready to retry the probing later in the startup process. +The pins are allocated for your device when you issue the pinctrl_get() call, +after this you should be able to see this in the debugfs listing of all pins. System pin control hogging @@ -1101,13 +1094,13 @@ it, disables and releases it, and muxes it in on the pins defined by group B: #include -struct pinctrl *p; -struct pinctrl_state *s1, *s2; - -foo_probe() +foo_switch() { + struct pinctrl *p; + struct pinctrl_state *s1, *s2; + /* Setup */ - p = devm_pinctrl_get(&device); + p = pinctrl_get(&device); if (IS_ERR(p)) ... @@ -1118,10 +1111,7 @@ foo_probe() s2 = pinctrl_lookup_state(foo->p, "pos-B"); if (IS_ERR(s2)) ... -} -foo_switch() -{ /* Enable on position A */ ret = pinctrl_select_state(s1); if (ret < 0) @@ -1135,6 +1125,8 @@ foo_switch() ... ... + + pinctrl_put(p); } The above has to be done from process context. diff --git a/trunk/Documentation/power/regulator/regulator.txt b/trunk/Documentation/power/regulator/regulator.txt index 13902778ae44..e272d9909e39 100644 --- a/trunk/Documentation/power/regulator/regulator.txt +++ b/trunk/Documentation/power/regulator/regulator.txt @@ -11,7 +11,8 @@ Registration Drivers can register a regulator by calling :- struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, - const struct regulator_config *config); + struct device *dev, struct regulator_init_data *init_data, + void *driver_data, struct device_node *of_node); This will register the regulators capabilities and operations to the regulator core. diff --git a/trunk/Documentation/prctl/seccomp_filter.txt b/trunk/Documentation/prctl/seccomp_filter.txt deleted file mode 100644 index 597c3c581375..000000000000 --- a/trunk/Documentation/prctl/seccomp_filter.txt +++ /dev/null @@ -1,163 +0,0 @@ - SECure COMPuting with filters - ============================= - -Introduction ------------- - -A large number of system calls are exposed to every userland process -with many of them going unused for the entire lifetime of the process. -As system calls change and mature, bugs are found and eradicated. A -certain subset of userland applications benefit by having a reduced set -of available system calls. The resulting set reduces the total kernel -surface exposed to the application. System call filtering is meant for -use with those applications. - -Seccomp filtering provides a means for a process to specify a filter for -incoming system calls. The filter is expressed as a Berkeley Packet -Filter (BPF) program, as with socket filters, except that the data -operated on is related to the system call being made: system call -number and the system call arguments. This allows for expressive -filtering of system calls using a filter program language with a long -history of being exposed to userland and a straightforward data set. - -Additionally, BPF makes it impossible for users of seccomp to fall prey -to time-of-check-time-of-use (TOCTOU) attacks that are common in system -call interposition frameworks. BPF programs may not dereference -pointers which constrains all filters to solely evaluating the system -call arguments directly. - -What it isn't -------------- - -System call filtering isn't a sandbox. It provides a clearly defined -mechanism for minimizing the exposed kernel surface. It is meant to be -a tool for sandbox developers to use. Beyond that, policy for logical -behavior and information flow should be managed with a combination of -other system hardening techniques and, potentially, an LSM of your -choosing. Expressive, dynamic filters provide further options down this -path (avoiding pathological sizes or selecting which of the multiplexed -system calls in socketcall() is allowed, for instance) which could be -construed, incorrectly, as a more complete sandboxing solution. - -Usage ------ - -An additional seccomp mode is added and is enabled using the same -prctl(2) call as the strict seccomp. If the architecture has -CONFIG_HAVE_ARCH_SECCOMP_FILTER, then filters may be added as below: - -PR_SET_SECCOMP: - Now takes an additional argument which specifies a new filter - using a BPF program. - The BPF program will be executed over struct seccomp_data - reflecting the system call number, arguments, and other - metadata. The BPF program must then return one of the - acceptable values to inform the kernel which action should be - taken. - - Usage: - prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, prog); - - The 'prog' argument is a pointer to a struct sock_fprog which - will contain the filter program. If the program is invalid, the - call will return -1 and set errno to EINVAL. - - If fork/clone and execve are allowed by @prog, any child - processes will be constrained to the same filters and system - call ABI as the parent. - - Prior to use, the task must call prctl(PR_SET_NO_NEW_PRIVS, 1) or - run with CAP_SYS_ADMIN privileges in its namespace. If these are not - true, -EACCES will be returned. This requirement ensures that filter - programs cannot be applied to child processes with greater privileges - than the task that installed them. - - Additionally, if prctl(2) is allowed by the attached filter, - additional filters may be layered on which will increase evaluation - time, but allow for further decreasing the attack surface during - execution of a process. - -The above call returns 0 on success and non-zero on error. - -Return values -------------- -A seccomp filter may return any of the following values. If multiple -filters exist, the return value for the evaluation of a given system -call will always use the highest precedent value. (For example, -SECCOMP_RET_KILL will always take precedence.) - -In precedence order, they are: - -SECCOMP_RET_KILL: - Results in the task exiting immediately without executing the - system call. The exit status of the task (status & 0x7f) will - be SIGSYS, not SIGKILL. - -SECCOMP_RET_TRAP: - Results in the kernel sending a SIGSYS signal to the triggering - task without executing the system call. The kernel will - rollback the register state to just before the system call - entry such that a signal handler in the task will be able to - inspect the ucontext_t->uc_mcontext registers and emulate - system call success or failure upon return from the signal - handler. - - The SECCOMP_RET_DATA portion of the return value will be passed - as si_errno. - - SIGSYS triggered by seccomp will have a si_code of SYS_SECCOMP. - -SECCOMP_RET_ERRNO: - Results in the lower 16-bits of the return value being passed - to userland as the errno without executing the system call. - -SECCOMP_RET_TRACE: - When returned, this value will cause the kernel to attempt to - notify a ptrace()-based tracer prior to executing the system - call. If there is no tracer present, -ENOSYS is returned to - userland and the system call is not executed. - - A tracer will be notified if it requests PTRACE_O_TRACESECCOMP - using ptrace(PTRACE_SETOPTIONS). The tracer will be notified - of a PTRACE_EVENT_SECCOMP and the SECCOMP_RET_DATA portion of - the BPF program return value will be available to the tracer - via PTRACE_GETEVENTMSG. - -SECCOMP_RET_ALLOW: - Results in the system call being executed. - -If multiple filters exist, the return value for the evaluation of a -given system call will always use the highest precedent value. - -Precedence is only determined using the SECCOMP_RET_ACTION mask. When -multiple filters return values of the same precedence, only the -SECCOMP_RET_DATA from the most recently installed filter will be -returned. - -Pitfalls --------- - -The biggest pitfall to avoid during use is filtering on system call -number without checking the architecture value. Why? On any -architecture that supports multiple system call invocation conventions, -the system call numbers may vary based on the specific invocation. If -the numbers in the different calling conventions overlap, then checks in -the filters may be abused. Always check the arch value! - -Example -------- - -The samples/seccomp/ directory contains both an x86-specific example -and a more generic example of a higher level macro interface for BPF -program generation. - - - -Adding architecture support ------------------------ - -See arch/Kconfig for the authoritative requirements. In general, if an -architecture supports both ptrace_event and seccomp, it will be able to -support seccomp filter with minor fixup: SIGSYS support and seccomp return -value checking. Then it must just add CONFIG_HAVE_ARCH_SECCOMP_FILTER -to its arch-specific Kconfig. diff --git a/trunk/Documentation/scsi/ChangeLog.megaraid_sas b/trunk/Documentation/scsi/ChangeLog.megaraid_sas index 80441ab608e4..83f8ea8b79eb 100644 --- a/trunk/Documentation/scsi/ChangeLog.megaraid_sas +++ b/trunk/Documentation/scsi/ChangeLog.megaraid_sas @@ -1,11 +1,3 @@ -Release Date : Mon. Mar 19, 2012 17:00:00 PST 2012 - - (emaild-id:megaraidlinux@lsi.com) - Adam Radford -Current Version : 00.00.06.15-rc1 -Old Version : 00.00.06.14-rc1 - 1. Optimize HostMSIxVectors setting. - 2. Add fpRead/WriteCapable, fpRead/WriteAcrossStripe checks. -------------------------------------------------------------------------------- Release Date : Fri. Jan 6, 2012 17:00:00 PST 2010 - (emaild-id:megaraidlinux@lsi.com) Adam Radford diff --git a/trunk/Documentation/security/Smack.txt b/trunk/Documentation/security/Smack.txt index a416479b8a1c..d2f72ae66432 100644 --- a/trunk/Documentation/security/Smack.txt +++ b/trunk/Documentation/security/Smack.txt @@ -15,7 +15,7 @@ at hand. Smack consists of three major components: - The kernel - - Basic utilities, which are helpful but not required + - A start-up script and a few modified applications - Configuration data The kernel component of Smack is implemented as a Linux @@ -23,28 +23,37 @@ Security Modules (LSM) module. It requires netlabel and works best with file systems that support extended attributes, although xattr support is not strictly required. It is safe to run a Smack kernel under a "vanilla" distribution. - Smack kernels use the CIPSO IP option. Some network configurations are intolerant of IP options and can impede access to systems that use them as Smack does. -The current git repositories for Smack user space are: +The startup script etc-init.d-smack should be installed +in /etc/init.d/smack and should be invoked early in the +start-up process. On Fedora rc5.d/S02smack is recommended. +This script ensures that certain devices have the correct +Smack attributes and loads the Smack configuration if +any is defined. This script invokes two programs that +ensure configuration data is properly formatted. These +programs are /usr/sbin/smackload and /usr/sin/smackcipso. +The system will run just fine without these programs, +but it will be difficult to set access rules properly. + +A version of "ls" that provides a "-M" option to display +Smack labels on long listing is available. - git@gitorious.org:meego-platform-security/smackutil.git - git@gitorious.org:meego-platform-security/libsmack.git +A hacked version of sshd that allows network logins by users +with specific Smack labels is available. This version does +not work for scp. You must set the /etc/ssh/sshd_config +line: + UsePrivilegeSeparation no -These should make and install on most modern distributions. -There are three commands included in smackutil: +The format of /etc/smack/usr is: -smackload - properly formats data for writing to /smack/load -smackcipso - properly formats data for writing to /smack/cipso -chsmack - display or set Smack extended attribute values + username smack In keeping with the intent of Smack, configuration data is minimal and not strictly required. The most important configuration step is mounting the smackfs pseudo filesystem. -If smackutil is installed the startup script will take care -of this, but it can be manually as well. Add this line to /etc/fstab: @@ -52,148 +61,19 @@ Add this line to /etc/fstab: and create the /smack directory for mounting. -Smack uses extended attributes (xattrs) to store labels on filesystem -objects. The attributes are stored in the extended attribute security -name space. A process must have CAP_MAC_ADMIN to change any of these -attributes. - -The extended attributes that Smack uses are: - -SMACK64 - Used to make access control decisions. In almost all cases - the label given to a new filesystem object will be the label - of the process that created it. -SMACK64EXEC - The Smack label of a process that execs a program file with - this attribute set will run with this attribute's value. -SMACK64MMAP - Don't allow the file to be mmapped by a process whose Smack - label does not allow all of the access permitted to a process - with the label contained in this attribute. This is a very - specific use case for shared libraries. -SMACK64TRANSMUTE - Can only have the value "TRUE". If this attribute is present - on a directory when an object is created in the directory and - the Smack rule (more below) that permitted the write access - to the directory includes the transmute ("t") mode the object - gets the label of the directory instead of the label of the - creating process. If the object being created is a directory - the SMACK64TRANSMUTE attribute is set as well. -SMACK64IPIN - This attribute is only available on file descriptors for sockets. - Use the Smack label in this attribute for access control - decisions on packets being delivered to this socket. -SMACK64IPOUT - This attribute is only available on file descriptors for sockets. - Use the Smack label in this attribute for access control - decisions on packets coming from this socket. - -There are multiple ways to set a Smack label on a file: +Smack uses extended attributes (xattrs) to store file labels. +The command to set a Smack label on a file is: # attr -S -s SMACK64 -V "value" path - # chsmack -a value path -A process can see the smack label it is running with by -reading /proc/self/attr/current. A process with CAP_MAC_ADMIN -can set the process smack by writing there. - -Most Smack configuration is accomplished by writing to files -in the smackfs filesystem. This pseudo-filesystem is usually -mounted on /smack. - -access - This interface reports whether a subject with the specified - Smack label has a particular access to an object with a - specified Smack label. Write a fixed format access rule to - this file. The next read will indicate whether the access - would be permitted. The text will be either "1" indicating - access, or "0" indicating denial. -access2 - This interface reports whether a subject with the specified - Smack label has a particular access to an object with a - specified Smack label. Write a long format access rule to - this file. The next read will indicate whether the access - would be permitted. The text will be either "1" indicating - access, or "0" indicating denial. -ambient - This contains the Smack label applied to unlabeled network - packets. -cipso - This interface allows a specific CIPSO header to be assigned - to a Smack label. The format accepted on write is: - "%24s%4d%4d"["%4d"]... - The first string is a fixed Smack label. The first number is - the level to use. The second number is the number of categories. - The following numbers are the categories. - "level-3-cats-5-19 3 2 5 19" -cipso2 - This interface allows a specific CIPSO header to be assigned - to a Smack label. The format accepted on write is: - "%s%4d%4d"["%4d"]... - The first string is a long Smack label. The first number is - the level to use. The second number is the number of categories. - The following numbers are the categories. - "level-3-cats-5-19 3 2 5 19" -direct - This contains the CIPSO level used for Smack direct label - representation in network packets. -doi - This contains the CIPSO domain of interpretation used in - network packets. -load - This interface allows access control rules in addition to - the system defined rules to be specified. The format accepted - on write is: - "%24s%24s%5s" - where the first string is the subject label, the second the - object label, and the third the requested access. The access - string may contain only the characters "rwxat-", and specifies - which sort of access is allowed. The "-" is a placeholder for - permissions that are not allowed. The string "r-x--" would - specify read and execute access. Labels are limited to 23 - characters in length. -load2 - This interface allows access control rules in addition to - the system defined rules to be specified. The format accepted - on write is: - "%s %s %s" - where the first string is the subject label, the second the - object label, and the third the requested access. The access - string may contain only the characters "rwxat-", and specifies - which sort of access is allowed. The "-" is a placeholder for - permissions that are not allowed. The string "r-x--" would - specify read and execute access. -load-self - This interface allows process specific access rules to be - defined. These rules are only consulted if access would - otherwise be permitted, and are intended to provide additional - restrictions on the process. The format is the same as for - the load interface. -load-self2 - This interface allows process specific access rules to be - defined. These rules are only consulted if access would - otherwise be permitted, and are intended to provide additional - restrictions on the process. The format is the same as for - the load2 interface. -logging - This contains the Smack logging state. -mapped - This contains the CIPSO level used for Smack mapped label - representation in network packets. -netlabel - This interface allows specific internet addresses to be - treated as single label hosts. Packets are sent to single - label hosts without CIPSO headers, but only from processes - that have Smack write access to the host label. All packets - received from single label hosts are given the specified - label. The format accepted on write is: - "%d.%d.%d.%d label" or "%d.%d.%d.%d/%d label". -onlycap - This contains the label processes must have for CAP_MAC_ADMIN - and CAP_MAC_OVERRIDE to be effective. If this file is empty - these capabilities are effective at for processes with any - label. The value is set by writing the desired label to the - file or cleared by writing "-" to the file. +NOTE: Smack labels are limited to 23 characters. The attr command + does not enforce this restriction and can be used to set + invalid Smack labels on files. + +If you don't do anything special all users will get the floor ("_") +label when they log in. If you do want to log in via the hacked ssh +at other labels use the attr command to set the smack value on the +home directory and its contents. You can add access rules in /etc/smack/accesses. They take the form: @@ -203,6 +83,10 @@ access is a combination of the letters rwxa which specify the kind of access permitted a subject with subjectlabel on an object with objectlabel. If there is no rule no access is allowed. +A process can see the smack label it is running with by +reading /proc/self/attr/current. A privileged process can +set the process smack by writing there. + Look for additional programs on http://schaufler-ca.com From the Smack Whitepaper: @@ -302,7 +186,7 @@ team. Smack labels are unstructured, case sensitive, and the only operation ever performed on them is comparison for equality. Smack labels cannot contain unprintable characters, the "/" (slash), the "\" (backslash), the "'" (quote) and '"' (double-quote) characters. -Smack labels cannot begin with a '-'. This is reserved for special options. +Smack labels cannot begin with a '-', which is reserved for special options. There are some predefined labels: @@ -310,7 +194,7 @@ There are some predefined labels: ^ Pronounced "hat", a single circumflex character. * Pronounced "star", a single asterisk character. ? Pronounced "huh", a single question mark character. - @ Pronounced "web", a single at sign character. + @ Pronounced "Internet", a single at sign character. Every task on a Smack system is assigned a label. System tasks, such as init(8) and systems daemons, are run with the floor ("_") label. User tasks @@ -362,14 +246,13 @@ The format of an access rule is: Where subject-label is the Smack label of the task, object-label is the Smack label of the thing being accessed, and access is a string specifying the sort -of access allowed. The access specification is searched for letters that -describe access modes: +of access allowed. The Smack labels are limited to 23 characters. The access +specification is searched for letters that describe access modes: a: indicates that append access should be granted. r: indicates that read access should be granted. w: indicates that write access should be granted. x: indicates that execute access should be granted. - t: indicates that the rule requests transmutation. Uppercase values for the specification letters are allowed as well. Access mode specifications can be in any order. Examples of acceptable rules @@ -390,7 +273,7 @@ Examples of unacceptable rules are: Spaces are not allowed in labels. Since a subject always has access to files with the same label specifying a rule for that case is pointless. Only -valid letters (rwxatRWXAT) and the dash ('-') character are allowed in +valid letters (rwxaRWXA) and the dash ('-') character are allowed in access specifications. The dash is a placeholder, so "a-r" is the same as "ar". A lone dash is used to specify that no access should be allowed. @@ -414,13 +297,6 @@ but not any of its attributes by the circumstance of having read access to the containing directory but not to the differently labeled file. This is an artifact of the file name being data in the directory, not a part of the file. -If a directory is marked as transmuting (SMACK64TRANSMUTE=TRUE) and the -access rule that allows a process to create an object in that directory -includes 't' access the label assigned to the new object will be that -of the directory, not the creating process. This makes it much easier -for two processes with different labels to share data without granting -access to all of their files. - IPC objects, message queues, semaphore sets, and memory segments exist in flat namespaces and access requests are only required to match the object in question. diff --git a/trunk/Documentation/security/Yama.txt b/trunk/Documentation/security/Yama.txt index e369de2d48cd..a9511f179069 100644 --- a/trunk/Documentation/security/Yama.txt +++ b/trunk/Documentation/security/Yama.txt @@ -34,7 +34,7 @@ parent to a child process (i.e. direct "gdb EXE" and "strace EXE" still work), or with CAP_SYS_PTRACE (i.e. "gdb --pid=PID", and "strace -p PID" still work as root). -In mode 1, software that has defined application-specific relationships +For software that has defined application-specific relationships between a debugging process and its inferior (crash handlers, etc), prctl(PR_SET_PTRACER, pid, ...) can be used. An inferior can declare which other process (and its descendents) are allowed to call PTRACE_ATTACH @@ -46,8 +46,6 @@ restrictions, it can call prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, ...) so that any otherwise allowed process (even those in external pid namespaces) may attach. -These restrictions do not change how ptrace via PTRACE_TRACEME operates. - The sysctl settings are: 0 - classic ptrace permissions: a process can PTRACE_ATTACH to any other @@ -62,12 +60,6 @@ The sysctl settings are: inferior can call prctl(PR_SET_PTRACER, debugger, ...) to declare an allowed debugger PID to call PTRACE_ATTACH on the inferior. -2 - admin-only attach: only processes with CAP_SYS_PTRACE may use ptrace - with PTRACE_ATTACH. - -3 - no attach: no processes may use ptrace with PTRACE_ATTACH. Once set, - this sysctl cannot be changed to a lower value. - The original children-only logic was based on the restrictions in grsecurity. ============================================================== diff --git a/trunk/Documentation/security/keys.txt b/trunk/Documentation/security/keys.txt index aa0dbd74b71b..d389acd31e19 100644 --- a/trunk/Documentation/security/keys.txt +++ b/trunk/Documentation/security/keys.txt @@ -805,23 +805,6 @@ The keyctl syscall functions are: kernel and resumes executing userspace. - (*) Invalidate a key. - - long keyctl(KEYCTL_INVALIDATE, key_serial_t key); - - This function marks a key as being invalidated and then wakes up the - garbage collector. The garbage collector immediately removes invalidated - keys from all keyrings and deletes the key when its reference count - reaches zero. - - Keys that are marked invalidated become invisible to normal key operations - immediately, though they are still visible in /proc/keys until deleted - (they're marked with an 'i' flag). - - A process must have search permission on the key for this function to be - successful. - - =============== KERNEL SERVICES =============== diff --git a/trunk/Documentation/sparc/README-2.5 b/trunk/Documentation/sparc/README-2.5 new file mode 100644 index 000000000000..806fe490a56d --- /dev/null +++ b/trunk/Documentation/sparc/README-2.5 @@ -0,0 +1,46 @@ +BTFIXUP +------- + +To build new kernels you have to issue "make image". The ready kernel +in ELF format is placed in arch/sparc/boot/image. Explanation is below. + +BTFIXUP is a unique feature of Linux/sparc among other architectures, +developed by Jakub Jelinek (I think... Obviously David S. Miller took +part, too). It allows to boot the same kernel at different +sub-architectures, such as sun4c, sun4m, sun4d, where SunOS uses +different kernels. This feature is convinient for people who you move +disks between boxes and for distrution builders. + +To function, BTFIXUP must link the kernel "in the draft" first, +analyze the result, write a special stub code based on that, and +build the final kernel with the stub (btfix.o). + +Kai Germaschewski improved the build system of the kernel in the 2.5 series +significantly. Unfortunately, the traditional way of running the draft +linking from architecture specific Makefile before the actual linking +by generic Makefile is nearly impossible to support properly in the +new build system. Therefore, the way we integrate BTFIXUP with the +build system was changed in 2.5.40. Now, generic Makefile performs +the draft linking and stores the result in file vmlinux. Architecture +specific post-processing invokes BTFIXUP machinery and final linking +in the same way as other architectures do bootstraps. + +Implications of that change are as follows. + +1. Hackers must type "make image" now, instead of just "make", in the same + way as s390 people do now. It is analogous to "make bzImage" on i386. + This does NOT affect sparc64, you continue to use "make" to build sparc64 + kernels. + +2. vmlinux is not the final kernel, so RPM builders have to adjust + their spec files (if they delivered vmlinux for debugging). + System.map generated for vmlinux is still valid. + +3. Scripts that produce a.out images have to be changed. First, if they + invoke make, they have to use "make image". Second, they have to pick up + the new kernel in arch/sparc/boot/image instead of vmlinux. + +4. Since we are compliant with Kai's build system now, make -j is permitted. + +-- Pete Zaitcev +zaitcev@yahoo.com diff --git a/trunk/Documentation/virtual/virtio-spec.txt b/trunk/Documentation/virtual/virtio-spec.txt index 0d6ec85481cb..da094737e2f8 100644 --- a/trunk/Documentation/virtual/virtio-spec.txt +++ b/trunk/Documentation/virtual/virtio-spec.txt @@ -1,11 +1,11 @@ [Generated file: see http://ozlabs.org/~rusty/virtio-spec/] Virtio PCI Card Specification -v0.9.5 DRAFT +v0.9.1 DRAFT - -Rusty Russell IBM Corporation (Editor) +Rusty Russell IBM Corporation (Editor) -2012 May 7. +2011 August 1. Purpose and Description @@ -68,11 +68,11 @@ and consists of three parts: +-------------------+-----------------------------------+-----------+ -When the driver wants to send a buffer to the device, it fills in -a slot in the descriptor table (or chains several together), and -writes the descriptor index into the available ring. It then -notifies the device. When the device has finished a buffer, it -writes the descriptor into the used ring, and sends an interrupt. +When the driver wants to send buffers to the device, it puts them +in one or more slots in the descriptor table, and writes the +descriptor indices into the available ring. It then notifies the +device. When the device has finished with the buffers, it writes +the descriptors into the used ring, and sends an interrupt. Specification @@ -106,13 +106,7 @@ for informational purposes by the guest). +----------------------+--------------------+---------------+ | 6 | ioMemory | - | +----------------------+--------------------+---------------+ -| 7 | rpmsg | Appendix H | -+----------------------+--------------------+---------------+ -| 8 | SCSI host | Appendix I | -+----------------------+--------------------+---------------+ | 9 | 9P transport | - | -+----------------------+--------------------+---------------+ -| 10 | mac80211 wlan | - | +----------------------+--------------------+---------------+ @@ -133,7 +127,7 @@ Note that this is possible because while the virtio header is PCI the native endian of the guest (where such distinction is applicable). - Device Initialization Sequence + Device Initialization Sequence We start with an overview of device initialization, then expand on the details of the device and how each step is preformed. @@ -183,10 +177,7 @@ The virtio header looks as follows: If MSI-X is enabled for the device, two additional fields -immediately follow this header:[footnote: -ie. once you enable MSI-X on the device, the other fields move. -If you turn it off again, they move back! -] +immediately follow this header: +------------++----------------+--------+ @@ -200,6 +191,20 @@ If you turn it off again, they move back! +------------++----------------+--------+ +Finally, if feature bits (VIRTIO_F_FEATURES_HI) this is +immediately followed by two additional fields: + + ++------------++----------------------+---------------------- +| Bits || 32 | 32 ++------------++----------------------+---------------------- +| Read/Write || R | R+W ++------------++----------------------+---------------------- +| Purpose || Device | Guest +| || Features bits 32:63 | Features bits 32:63 ++------------++----------------------+---------------------- + + Immediately following these general headers, there may be device-specific headers: @@ -233,25 +238,31 @@ at least one bit should be set: may be a significant (or infinite) delay before setting this bit. - DRIVER_OK (4) Indicates that the driver is set up and ready to + DRIVER_OK (3) Indicates that the driver is set up and ready to drive the device. - FAILED (128) Indicates that something went wrong in the guest, + FAILED (8) Indicates that something went wrong in the guest, and it has given up on the device. This could be an internal error, or the driver didn't like the device for some reason, or even a fatal error during device operation. The device must be reset before attempting to re-initialize. - Feature Bits + Feature Bits -Thefirst configuration field indicates the features that the -device supports. The bits are allocated as follows: +The least significant 31 bits of the first configuration field +indicates the features that the device supports (the high bit is +reserved, and will be used to indicate the presence of future +feature bits elsewhere). If more than 31 feature bits are +supported, the device indicates so by setting feature bit 31 (see +[cha:Reserved-Feature-Bits]). The bits are allocated as follows: 0 to 23 Feature bits for the specific device type - 24 to 32 Feature bits reserved for extensions to the queue and + 24 to 40 Feature bits reserved for extensions to the queue and feature negotiation mechanisms + 41 to 63 Feature bits reserved for future extensions + For example, feature bit 0 for a network device (i.e. Subsystem Device ID 1) indicates that the device supports checksumming of packets. @@ -275,6 +286,10 @@ will not see that feature bit in the Device Features field and can go into backwards compatibility mode (or, for poor implementations, set the FAILED Device Status bit). +Access to feature bits 32 to 63 is enabled by Guest by setting +feature bit 31. If this bit is unset, Device must assume that all +feature bits > 31 are unset. + Configuration/Queue Vectors When MSI-X capability is present and enabled in the device @@ -309,7 +324,7 @@ success, the previously written value is returned, and on failure, NO_VECTOR is returned. If a mapping failure is detected, the driver can retry mapping with fewervectors, or disable MSI-X. - Virtqueue Configuration + Virtqueue Configuration As a device can have zero or more virtqueues for bulk data transport (for example, the network driver has two), the driver @@ -572,7 +587,7 @@ and Red Hat under the (3-clause) BSD license so that it can be freely used by all other projects, and is reproduced (with slight variation to remove Linux assumptions) in Appendix A. - Device Operation + Device Operation There are two parts to device operation: supplying new buffers to the device, and processing used buffers from the device. As an @@ -798,7 +813,7 @@ vring.used->ring[vq->last_seen_used%vsz]; } - Dealing With Configuration Changes + Dealing With Configuration Changes Some virtio PCI devices can change the device configuration state, as reflected in the virtio header in the PCI configuration @@ -1245,6 +1260,18 @@ Currently there are five device-independent feature bits defined: driver should ignore the used_event field; the device should ignore the avail_event field; the flags field is used + VIRTIO_F_BAD_FEATURE(30) This feature should never be + negotiated by the guest; doing so is an indication that the + guest is faulty[footnote: +An experimental virtio PCI driver contained in Linux version +2.6.25 had this problem, and this feature bit can be used to +detect it. +] + + VIRTIO_F_FEATURES_HIGH(31) This feature indicates that the + device supports feature bits 32:63. If unset, feature bits + 32:63 are unset. + Appendix C: Network Device The virtio network device is a virtual ethernet card, and is the @@ -1308,17 +1335,11 @@ were required. VIRTIO_NET_F_CTRL_VLAN (19) Control channel VLAN filtering. - VIRTIO_NET_F_GUEST_ANNOUNCE(21) Guest can send gratuitous - packets. - Device configuration layout Two configuration fields are currently defined. The mac address field always exists (though is only valid if VIRTIO_NET_F_MAC is set), and the status field - only exists if VIRTIO_NET_F_STATUS is set. Two read-only bits - are currently defined for the status field: - VIRTIO_NET_S_LINK_UP and VIRTIO_NET_S_ANNOUNCE. #define VIRTIO_NET_S_LINK_UP 1 - -#define VIRTIO_NET_S_ANNOUNCE 2 + only exists if VIRTIO_NET_F_STATUS is set. Only one bit is + currently defined for the status field: VIRTIO_NET_S_LINK_UP. #define VIRTIO_NET_S_LINK_UP 1 @@ -1356,19 +1377,12 @@ struct virtio_net_config { packets by negotating the VIRTIO_NET_F_CSUM feature. This “ checksum offload” is a common feature on modern network cards. - If that feature is negotiated[footnote: -ie. VIRTIO_NET_F_HOST_TSO* and VIRTIO_NET_F_HOST_UFO are -dependent on VIRTIO_NET_F_CSUM; a dvice which offers the offload -features must offer the checksum feature, and a driver which -accepts the offload features must accept the checksum feature. -Similar logic applies to the VIRTIO_NET_F_GUEST_TSO4 features -depending on VIRTIO_NET_F_GUEST_CSUM. -], a driver can use TCP or UDP segmentation offload by - negotiating the VIRTIO_NET_F_HOST_TSO4 (IPv4 TCP), - VIRTIO_NET_F_HOST_TSO6 (IPv6 TCP) and VIRTIO_NET_F_HOST_UFO - (UDP fragmentation) features. It should not send TCP packets - requiring segmentation offload which have the Explicit - Congestion Notification bit set, unless the + If that feature is negotiated, a driver can use TCP or UDP + segmentation offload by negotiating the VIRTIO_NET_F_HOST_TSO4 + (IPv4 TCP), VIRTIO_NET_F_HOST_TSO6 (IPv6 TCP) and + VIRTIO_NET_F_HOST_UFO (UDP fragmentation) features. It should + not send TCP packets requiring segmentation offload which have + the Explicit Congestion Notification bit set, unless the VIRTIO_NET_F_HOST_ECN feature is negotiated.[footnote: This is a common restriction in real, older network cards. ] @@ -1389,7 +1403,7 @@ segmentation, if both guests are amenable. Packets are transmitted by placing them in the transmitq, and buffers for incoming packets are placed in the receiveq. In each -case, the packet itself is preceeded by a header: +case, the packet itself is preceded by a header: struct virtio_net_hdr { @@ -1448,10 +1462,9 @@ It will have a 14 byte ethernet header and 20 byte IP header followed by the TCP header (with the TCP checksum field 16 bytes into that header). csum_start will be 14+20 = 34 (the TCP checksum includes the header), and csum_offset will be 16. The -value in the TCP checksum field should be initialized to the sum -of the TCP pseudo header, so that replacing it by the ones' -complement checksum of the TCP header and body will give the -correct result. +value in the TCP checksum field will be the sum of the TCP pseudo +header, so that replacing it by the ones' complement checksum of +the TCP header and body will give the correct result. ] If the driver negotiated @@ -1470,8 +1483,8 @@ Due to various bugs in implementations, this field is not useful as a guarantee of the transport header size. ] - gso_size is the maximum size of each packet beyond that header - (ie. MSS). + gso_size is the size of the packet beyond that header (ie. + MSS). If the driver negotiated the VIRTIO_NET_F_HOST_ECN feature, the VIRTIO_NET_HDR_GSO_ECN bit may be set in “gso_type” as well, @@ -1554,9 +1567,7 @@ Processing packet involves: If the VIRTIO_NET_F_GUEST_TSO4, TSO6 or UFO options were negotiated, then the “gso_type” may be something other than VIRTIO_NET_HDR_GSO_NONE, and the “gso_size” field indicates the - desired MSS (see [enu:If-the-driver]). - - Control Virtqueue + desired MSS (see [enu:If-the-driver]).Control Virtqueue The driver uses the control virtqueue (if VIRTIO_NET_F_VTRL_VQ is negotiated) to send commands to manipulate various features of @@ -1631,7 +1642,7 @@ struct virtio_net_ctrl_mac { The device can filter incoming packets by any number of destination MAC addresses.[footnote: -Since there are no guarentees, it can use a hash filter +Since there are no guarantees, it can use a hash filter orsilently switch to allmulti or promiscuous mode if it is given too many addresses. ] This table is set using the class VIRTIO_NET_CTRL_MAC and the @@ -1654,38 +1665,6 @@ can control a VLAN filter table in the device. Both the VIRTIO_NET_CTRL_VLAN_ADD and VIRTIO_NET_CTRL_VLAN_DEL command take a 16-bit VLAN id as the command-specific-data. - Gratuitous Packet Sending - -If the driver negotiates the VIRTIO_NET_F_GUEST_ANNOUNCE (depends -on VIRTIO_NET_F_CTRL_VQ), it can ask the guest to send gratuitous -packets; this is usually done after the guest has been physically -migrated, and needs to announce its presence on the new network -links. (As hypervisor does not have the knowledge of guest -network configuration (eg. tagged vlan) it is simplest to prod -the guest in this way). - -#define VIRTIO_NET_CTRL_ANNOUNCE 3 - - #define VIRTIO_NET_CTRL_ANNOUNCE_ACK 0 - -The Guest needs to check VIRTIO_NET_S_ANNOUNCE bit in status -field when it notices the changes of device configuration. The -command VIRTIO_NET_CTRL_ANNOUNCE_ACK is used to indicate that -driver has recevied the notification and device would clear the -VIRTIO_NET_S_ANNOUNCE bit in the status filed after it received -this command. - -Processing this notification involves: - - Sending the gratuitous packets or marking there are pending - gratuitous packets to be sent and letting deferred routine to - send them. - - Sending VIRTIO_NET_CTRL_ANNOUNCE_ACK command through control - vq. - - . - Appendix D: Block Device The virtio block device is a simple virtual block device (ie. @@ -1720,6 +1699,8 @@ device except where noted. VIRTIO_BLK_F_FLUSH (9) Cache flush command support. + + Device configuration layout The capacity of the device (expressed in 512-byte sectors) is always present. The availability of the others all depend on various feature bits @@ -1762,6 +1743,8 @@ device except where noted. If the VIRTIO_BLK_F_RO feature is set by the device, any write requests will fail. + + Device Operation The driver queues requests to the virtqueue, and they are used by @@ -1822,7 +1805,7 @@ the FLUSH and FLUSH_OUT types are equivalent, the device does not distinguish between them ]). If the device has VIRTIO_BLK_F_BARRIER feature the high bit (VIRTIO_BLK_T_BARRIER) indicates that this request acts as a -barrier and that all preceeding requests must be complete before +barrier and that all preceding requests must be complete before this one, and all following requests must not be started until this is complete. Note that a barrier does not flush caches in the underlying backend device in host, and thus does not serve as @@ -2135,7 +2118,7 @@ This is historical, and independent of the guest page size Otherwise, the guest may begin to re-use pages previously given to the balloon before the device has acknowledged their - withdrawl. [footnote: + withdrawal. [footnote: In this case, deflation advice is merely a courtesy ] @@ -2215,996 +2198,3 @@ as follows: VIRTIO_BALLOON_S_MEMTOT The total amount of memory available (in bytes). -Appendix H: Rpmsg: Remote Processor Messaging - -Virtio rpmsg devices represent remote processors on the system -which run in asymmetric multi-processing (AMP) configuration, and -which are usually used to offload cpu-intensive tasks from the -main application processor (a typical SoC methodology). - -Virtio is being used to communicate with those remote processors; -empty buffers are placed in one virtqueue for receiving messages, -and non-empty buffers, containing outbound messages, are enqueued -in a second virtqueue for transmission. - -Numerous communication channels can be multiplexed over those two -virtqueues, so different entities, running on the application and -remote processor, can directly communicate in a point-to-point -fashion. - - Configuration - - Subsystem Device ID 7 - - Virtqueues 0:receiveq. 1:transmitq. - - Feature bits - - VIRTIO_RPMSG_F_NS (0) Device sends (and capable of receiving) - name service messages announcing the creation (or - destruction) of a channel:/** - - * struct rpmsg_ns_msg - dynamic name service announcement -message - - * @name: name of remote service that is published - - * @addr: address of remote service that is published - - * @flags: indicates whether service is created or destroyed - - * - - * This message is sent across to publish a new service (or -announce - - * about its removal). When we receives these messages, an -appropriate - - * rpmsg channel (i.e device) is created/destroyed. - - */ - -struct rpmsg_ns_msgoon_config { - - char name[RPMSG_NAME_SIZE]; - - u32 addr; - - u32 flags; - -} __packed; - - - -/** - - * enum rpmsg_ns_flags - dynamic name service announcement flags - - * - - * @RPMSG_NS_CREATE: a new remote service was just created - - * @RPMSG_NS_DESTROY: a remote service was just destroyed - - */ - -enum rpmsg_ns_flags { - - RPMSG_NS_CREATE = 0, - - RPMSG_NS_DESTROY = 1, - -}; - - Device configuration layout - -At his point none currently defined. - - Device Initialization - - The initialization routine should identify the receive and - transmission virtqueues. - - The receive virtqueue should be filled with receive buffers. - - Device Operation - -Messages are transmitted by placing them in the transmitq, and -buffers for inbound messages are placed in the receiveq. In any -case, messages are always preceded by the following header: /** - - * struct rpmsg_hdr - common header for all rpmsg messages - - * @src: source address - - * @dst: destination address - - * @reserved: reserved for future use - - * @len: length of payload (in bytes) - - * @flags: message flags - - * @data: @len bytes of message payload data - - * - - * Every message sent(/received) on the rpmsg bus begins with -this header. - - */ - -struct rpmsg_hdr { - - u32 src; - - u32 dst; - - u32 reserved; - - u16 len; - - u16 flags; - - u8 data[0]; - -} __packed; - -Appendix I: SCSI Host Device - -The virtio SCSI host device groups together one or more virtual -logical units (such as disks), and allows communicating to them -using the SCSI protocol. An instance of the device represents a -SCSI host to which many targets and LUNs are attached. - -The virtio SCSI device services two kinds of requests: - - command requests for a logical unit; - - task management functions related to a logical unit, target or - command. - -The device is also able to send out notifications about added and -removed logical units. Together, these capabilities provide a -SCSI transport protocol that uses virtqueues as the transfer -medium. In the transport protocol, the virtio driver acts as the -initiator, while the virtio SCSI host provides one or more -targets that receive and process the requests. - - Configuration - - Subsystem Device ID 8 - - Virtqueues 0:controlq; 1:eventq; 2..n:request queues. - - Feature bits - - VIRTIO_SCSI_F_INOUT (0) A single request can include both - read-only and write-only data buffers. - - VIRTIO_SCSI_F_HOTPLUG (1) The host should enable - hot-plug/hot-unplug of new LUNs and targets on the SCSI bus. - - Device configuration layout All fields of this configuration - are always available. sense_size and cdb_size are writable by - the guest.struct virtio_scsi_config { - - u32 num_queues; - - u32 seg_max; - - u32 max_sectors; - - u32 cmd_per_lun; - - u32 event_info_size; - - u32 sense_size; - - u32 cdb_size; - - u16 max_channel; - - u16 max_target; - - u32 max_lun; - -}; - - num_queues is the total number of request virtqueues exposed by - the device. The driver is free to use only one request queue, - or it can use more to achieve better performance. - - seg_max is the maximum number of segments that can be in a - command. A bidirectional command can include seg_max input - segments and seg_max output segments. - - max_sectors is a hint to the guest about the maximum transfer - size it should use. - - cmd_per_lun is a hint to the guest about the maximum number of - linked commands it should send to one LUN. The actual value - to be used is the minimum of cmd_per_lun and the virtqueue - size. - - event_info_size is the maximum size that the device will fill - for buffers that the driver places in the eventq. The driver - should always put buffers at least of this size. It is - written by the device depending on the set of negotated - features. - - sense_size is the maximum size of the sense data that the - device will write. The default value is written by the device - and will always be 96, but the driver can modify it. It is - restored to the default when the device is reset. - - cdb_size is the maximum size of the CDB that the driver will - write. The default value is written by the device and will - always be 32, but the driver can likewise modify it. It is - restored to the default when the device is reset. - - max_channel, max_target and max_lun can be used by the driver - as hints to constrain scanning the logical units on the - host.h - - Device Initialization - -The initialization routine should first of all discover the -device's virtqueues. - -If the driver uses the eventq, it should then place at least a -buffer in the eventq. - -The driver can immediately issue requests (for example, INQUIRY -or REPORT LUNS) or task management functions (for example, I_T -RESET). - - Device Operation: request queues - -The driver queues requests to an arbitrary request queue, and -they are used by the device on that same queue. It is the -responsibility of the driver to ensure strict request ordering -for commands placed on different queues, because they will be -consumed with no order constraints. - -Requests have the following format: - -struct virtio_scsi_req_cmd { - - // Read-only - - u8 lun[8]; - - u64 id; - - u8 task_attr; - - u8 prio; - - u8 crn; - - char cdb[cdb_size]; - - char dataout[]; - - // Write-only part - - u32 sense_len; - - u32 residual; - - u16 status_qualifier; - - u8 status; - - u8 response; - - u8 sense[sense_size]; - - char datain[]; - -}; - - - -/* command-specific response values */ - -#define VIRTIO_SCSI_S_OK 0 - -#define VIRTIO_SCSI_S_OVERRUN 1 - -#define VIRTIO_SCSI_S_ABORTED 2 - -#define VIRTIO_SCSI_S_BAD_TARGET 3 - -#define VIRTIO_SCSI_S_RESET 4 - -#define VIRTIO_SCSI_S_BUSY 5 - -#define VIRTIO_SCSI_S_TRANSPORT_FAILURE 6 - -#define VIRTIO_SCSI_S_TARGET_FAILURE 7 - -#define VIRTIO_SCSI_S_NEXUS_FAILURE 8 - -#define VIRTIO_SCSI_S_FAILURE 9 - - - -/* task_attr */ - -#define VIRTIO_SCSI_S_SIMPLE 0 - -#define VIRTIO_SCSI_S_ORDERED 1 - -#define VIRTIO_SCSI_S_HEAD 2 - -#define VIRTIO_SCSI_S_ACA 3 - -The lun field addresses a target and logical unit in the -virtio-scsi device's SCSI domain. The only supported format for -the LUN field is: first byte set to 1, second byte set to target, -third and fourth byte representing a single level LUN structure, -followed by four zero bytes. With this representation, a -virtio-scsi device can serve up to 256 targets and 16384 LUNs per -target. - -The id field is the command identifier (“tag”). - -task_attr, prio and crn should be left to zero. task_attr defines -the task attribute as in the table above, but all task attributes -may be mapped to SIMPLE by the device; crn may also be provided -by clients, but is generally expected to be 0. The maximum CRN -value defined by the protocol is 255, since CRN is stored in an -8-bit integer. - -All of these fields are defined in SAM. They are always -read-only, as are the cdb and dataout field. The cdb_size is -taken from the configuration space. - -sense and subsequent fields are always write-only. The sense_len -field indicates the number of bytes actually written to the sense -buffer. The residual field indicates the residual size, -calculated as “data_length - number_of_transferred_bytes”, for -read or write operations. For bidirectional commands, the -number_of_transferred_bytes includes both read and written bytes. -A residual field that is less than the size of datain means that -the dataout field was processed entirely. A residual field that -exceeds the size of datain means that the dataout field was -processed partially and the datain field was not processed at -all. - -The status byte is written by the device to be the status code as -defined in SAM. - -The response byte is written by the device to be one of the -following: - - VIRTIO_SCSI_S_OK when the request was completed and the status - byte is filled with a SCSI status code (not necessarily - "GOOD"). - - VIRTIO_SCSI_S_OVERRUN if the content of the CDB requires - transferring more data than is available in the data buffers. - - VIRTIO_SCSI_S_ABORTED if the request was cancelled due to an - ABORT TASK or ABORT TASK SET task management function. - - VIRTIO_SCSI_S_BAD_TARGET if the request was never processed - because the target indicated by the lun field does not exist. - - VIRTIO_SCSI_S_RESET if the request was cancelled due to a bus - or device reset (including a task management function). - - VIRTIO_SCSI_S_TRANSPORT_FAILURE if the request failed due to a - problem in the connection between the host and the target - (severed link). - - VIRTIO_SCSI_S_TARGET_FAILURE if the target is suffering a - failure and the guest should not retry on other paths. - - VIRTIO_SCSI_S_NEXUS_FAILURE if the nexus is suffering a failure - but retrying on other paths might yield a different result. - - VIRTIO_SCSI_S_BUSY if the request failed but retrying on the - same path should work. - - VIRTIO_SCSI_S_FAILURE for other host or guest error. In - particular, if neither dataout nor datain is empty, and the - VIRTIO_SCSI_F_INOUT feature has not been negotiated, the - request will be immediately returned with a response equal to - VIRTIO_SCSI_S_FAILURE. - - Device Operation: controlq - -The controlq is used for other SCSI transport operations. -Requests have the following format: - -struct virtio_scsi_ctrl { - - u32 type; - - ... - - u8 response; - -}; - - - -/* response values valid for all commands */ - -#define VIRTIO_SCSI_S_OK 0 - -#define VIRTIO_SCSI_S_BAD_TARGET 3 - -#define VIRTIO_SCSI_S_BUSY 5 - -#define VIRTIO_SCSI_S_TRANSPORT_FAILURE 6 - -#define VIRTIO_SCSI_S_TARGET_FAILURE 7 - -#define VIRTIO_SCSI_S_NEXUS_FAILURE 8 - -#define VIRTIO_SCSI_S_FAILURE 9 - -#define VIRTIO_SCSI_S_INCORRECT_LUN 12 - -The type identifies the remaining fields. - -The following commands are defined: - - Task management function -#define VIRTIO_SCSI_T_TMF 0 - - - -#define VIRTIO_SCSI_T_TMF_ABORT_TASK 0 - -#define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET 1 - -#define VIRTIO_SCSI_T_TMF_CLEAR_ACA 2 - -#define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET 3 - -#define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET 4 - -#define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET 5 - -#define VIRTIO_SCSI_T_TMF_QUERY_TASK 6 - -#define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET 7 - - - -struct virtio_scsi_ctrl_tmf - -{ - - // Read-only part - - u32 type; - - u32 subtype; - - u8 lun[8]; - - u64 id; - - // Write-only part - - u8 response; - -} - - - -/* command-specific response values */ - -#define VIRTIO_SCSI_S_FUNCTION_COMPLETE 0 - -#define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED 10 - -#define VIRTIO_SCSI_S_FUNCTION_REJECTED 11 - - The type is VIRTIO_SCSI_T_TMF; the subtype field defines. All - fields except response are filled by the driver. The subtype - field must always be specified and identifies the requested - task management function. - - Other fields may be irrelevant for the requested TMF; if so, - they are ignored but they should still be present. The lun - field is in the same format specified for request queues; the - single level LUN is ignored when the task management function - addresses a whole I_T nexus. When relevant, the value of the id - field is matched against the id values passed on the requestq. - - The outcome of the task management function is written by the - device in the response field. The command-specific response - values map 1-to-1 with those defined in SAM. - - Asynchronous notification query -#define VIRTIO_SCSI_T_AN_QUERY 1 - - - -struct virtio_scsi_ctrl_an { - - // Read-only part - - u32 type; - - u8 lun[8]; - - u32 event_requested; - - // Write-only part - - u32 event_actual; - - u8 response; - -} - - - -#define VIRTIO_SCSI_EVT_ASYNC_OPERATIONAL_CHANGE 2 - -#define VIRTIO_SCSI_EVT_ASYNC_POWER_MGMT 4 - -#define VIRTIO_SCSI_EVT_ASYNC_EXTERNAL_REQUEST 8 - -#define VIRTIO_SCSI_EVT_ASYNC_MEDIA_CHANGE 16 - -#define VIRTIO_SCSI_EVT_ASYNC_MULTI_HOST 32 - -#define VIRTIO_SCSI_EVT_ASYNC_DEVICE_BUSY 64 - - By sending this command, the driver asks the device which - events the given LUN can report, as described in paragraphs 6.6 - and A.6 of the SCSI MMC specification. The driver writes the - events it is interested in into the event_requested; the device - responds by writing the events that it supports into - event_actual. - - The type is VIRTIO_SCSI_T_AN_QUERY. The lun and event_requested - fields are written by the driver. The event_actual and response - fields are written by the device. - - No command-specific values are defined for the response byte. - - Asynchronous notification subscription -#define VIRTIO_SCSI_T_AN_SUBSCRIBE 2 - - - -struct virtio_scsi_ctrl_an { - - // Read-only part - - u32 type; - - u8 lun[8]; - - u32 event_requested; - - // Write-only part - - u32 event_actual; - - u8 response; - -} - - By sending this command, the driver asks the specified LUN to - report events for its physical interface, again as described in - the SCSI MMC specification. The driver writes the events it is - interested in into the event_requested; the device responds by - writing the events that it supports into event_actual. - - Event types are the same as for the asynchronous notification - query message. - - The type is VIRTIO_SCSI_T_AN_SUBSCRIBE. The lun and - event_requested fields are written by the driver. The - event_actual and response fields are written by the device. - - No command-specific values are defined for the response byte. - - Device Operation: eventq - -The eventq is used by the device to report information on logical -units that are attached to it. The driver should always leave a -few buffers ready in the eventq. In general, the device will not -queue events to cope with an empty eventq, and will end up -dropping events if it finds no buffer ready. However, when -reporting events for many LUNs (e.g. when a whole target -disappears), the device can throttle events to avoid dropping -them. For this reason, placing 10-15 buffers on the event queue -should be enough. - -Buffers are placed in the eventq and filled by the device when -interesting events occur. The buffers should be strictly -write-only (device-filled) and the size of the buffers should be -at least the value given in the device's configuration -information. - -Buffers returned by the device on the eventq will be referred to -as "events" in the rest of this section. Events have the -following format: - -#define VIRTIO_SCSI_T_EVENTS_MISSED 0x80000000 - - - -struct virtio_scsi_event { - - // Write-only part - - u32 event; - - ... - -} - -If bit 31 is set in the event field, the device failed to report -an event due to missing buffers. In this case, the driver should -poll the logical units for unit attention conditions, and/or do -whatever form of bus scan is appropriate for the guest operating -system. - -Other data that the device writes to the buffer depends on the -contents of the event field. The following events are defined: - - No event -#define VIRTIO_SCSI_T_NO_EVENT 0 - - This event is fired in the following cases: - - When the device detects in the eventq a buffer that is shorter - than what is indicated in the configuration field, it might - use it immediately and put this dummy value in the event - field. A well-written driver will never observe this - situation. - - When events are dropped, the device may signal this event as - soon as the drivers makes a buffer available, in order to - request action from the driver. In this case, of course, this - event will be reported with the VIRTIO_SCSI_T_EVENTS_MISSED - flag. - - Transport reset -#define VIRTIO_SCSI_T_TRANSPORT_RESET 1 - - - -struct virtio_scsi_event_reset { - - // Write-only part - - u32 event; - - u8 lun[8]; - - u32 reason; - -} - - - -#define VIRTIO_SCSI_EVT_RESET_HARD 0 - -#define VIRTIO_SCSI_EVT_RESET_RESCAN 1 - -#define VIRTIO_SCSI_EVT_RESET_REMOVED 2 - - By sending this event, the device signals that a logical unit - on a target has been reset, including the case of a new device - appearing or disappearing on the bus.The device fills in all - fields. The event field is set to - VIRTIO_SCSI_T_TRANSPORT_RESET. The lun field addresses a - logical unit in the SCSI host. - - The reason value is one of the three #define values appearing - above: - - VIRTIO_SCSI_EVT_RESET_REMOVED (“LUN/target removed”) is used if - the target or logical unit is no longer able to receive - commands. - - VIRTIO_SCSI_EVT_RESET_HARD (“LUN hard reset”) is used if the - logical unit has been reset, but is still present. - - VIRTIO_SCSI_EVT_RESET_RESCAN (“rescan LUN/target”) is used if a - target or logical unit has just appeared on the device. - - The “removed” and “rescan” events, when sent for LUN 0, may - apply to the entire target. After receiving them the driver - should ask the initiator to rescan the target, in order to - detect the case when an entire target has appeared or - disappeared. These two events will never be reported unless the - VIRTIO_SCSI_F_HOTPLUG feature was negotiated between the host - and the guest. - - Events will also be reported via sense codes (this obviously - does not apply to newly appeared buses or targets, since the - application has never discovered them): - - “LUN/target removed” maps to sense key ILLEGAL REQUEST, asc - 0x25, ascq 0x00 (LOGICAL UNIT NOT SUPPORTED) - - “LUN hard reset” maps to sense key UNIT ATTENTION, asc 0x29 - (POWER ON, RESET OR BUS DEVICE RESET OCCURRED) - - “rescan LUN/target” maps to sense key UNIT ATTENTION, asc 0x3f, - ascq 0x0e (REPORTED LUNS DATA HAS CHANGED) - - The preferred way to detect transport reset is always to use - events, because sense codes are only seen by the driver when it - sends a SCSI command to the logical unit or target. However, in - case events are dropped, the initiator will still be able to - synchronize with the actual state of the controller if the - driver asks the initiator to rescan of the SCSI bus. During the - rescan, the initiator will be able to observe the above sense - codes, and it will process them as if it the driver had - received the equivalent event. - - Asynchronous notification -#define VIRTIO_SCSI_T_ASYNC_NOTIFY 2 - - - -struct virtio_scsi_event_an { - - // Write-only part - - u32 event; - - u8 lun[8]; - - u32 reason; - -} - - By sending this event, the device signals that an asynchronous - event was fired from a physical interface. - - All fields are written by the device. The event field is set to - VIRTIO_SCSI_T_ASYNC_NOTIFY. The lun field addresses a logical - unit in the SCSI host. The reason field is a subset of the - events that the driver has subscribed to via the "Asynchronous - notification subscription" command. - - When dropped events are reported, the driver should poll for - asynchronous events manually using SCSI commands. - -Appendix X: virtio-mmio - -Virtual environments without PCI support (a common situation in -embedded devices models) might use simple memory mapped device (“ -virtio-mmio”) instead of the PCI device. - -The memory mapped virtio device behaviour is based on the PCI -device specification. Therefore most of operations like device -initialization, queues configuration and buffer transfers are -nearly identical. Existing differences are described in the -following sections. - - Device Initialization - -Instead of using the PCI IO space for virtio header, the “ -virtio-mmio” device provides a set of memory mapped control -registers, all 32 bits wide, followed by device-specific -configuration space. The following list presents their layout: - - Offset from the device base address | Direction | Name - Description - - 0x000 | R | MagicValue - “virt” string. - - 0x004 | R | Version - Device version number. Currently must be 1. - - 0x008 | R | DeviceID - Virtio Subsystem Device ID (ie. 1 for network card). - - 0x00c | R | VendorID - Virtio Subsystem Vendor ID. - - 0x010 | R | HostFeatures - Flags representing features the device supports. - Reading from this register returns 32 consecutive flag bits, - first bit depending on the last value written to - HostFeaturesSel register. Access to this register returns bits HostFeaturesSel*32 - - to (HostFeaturesSel*32)+31 -, eg. feature bits 0 to 31 if - HostFeaturesSel is set to 0 and features bits 32 to 63 if - HostFeaturesSel is set to 1. Also see [sub:Feature-Bits] - - 0x014 | W | HostFeaturesSel - Device (Host) features word selection. - Writing to this register selects a set of 32 device feature bits - accessible by reading from HostFeatures register. Device driver - must write a value to the HostFeaturesSel register before - reading from the HostFeatures register. - - 0x020 | W | GuestFeatures - Flags representing device features understood and activated by - the driver. - Writing to this register sets 32 consecutive flag bits, first - bit depending on the last value written to GuestFeaturesSel - register. Access to this register sets bits GuestFeaturesSel*32 - - to (GuestFeaturesSel*32)+31 -, eg. feature bits 0 to 31 if - GuestFeaturesSel is set to 0 and features bits 32 to 63 if - GuestFeaturesSel is set to 1. Also see [sub:Feature-Bits] - - 0x024 | W | GuestFeaturesSel - Activated (Guest) features word selection. - Writing to this register selects a set of 32 activated feature - bits accessible by writing to the GuestFeatures register. - Device driver must write a value to the GuestFeaturesSel - register before writing to the GuestFeatures register. - - 0x028 | W | GuestPageSize - Guest page size. - Device driver must write the guest page size in bytes to the - register during initialization, before any queues are used. - This value must be a power of 2 and is used by the Host to - calculate Guest address of the first queue page (see QueuePFN). - - 0x030 | W | QueueSel - Virtual queue index (first queue is 0). - Writing to this register selects the virtual queue that the - following operations on QueueNum, QueueAlign and QueuePFN apply - to. - - 0x034 | R | QueueNumMax - Maximum virtual queue size. - Reading from the register returns the maximum size of the queue - the Host is ready to process or zero (0x0) if the queue is not - available. This applies to the queue selected by writing to - QueueSel and is allowed only when QueuePFN is set to zero - (0x0), so when the queue is not actively used. - - 0x038 | W | QueueNum - Virtual queue size. - Queue size is a number of elements in the queue, therefore size - of the descriptor table and both available and used rings. - Writing to this register notifies the Host what size of the - queue the Guest will use. This applies to the queue selected by - writing to QueueSel. - - 0x03c | W | QueueAlign - Used Ring alignment in the virtual queue. - Writing to this register notifies the Host about alignment - boundary of the Used Ring in bytes. This value must be a power - of 2 and applies to the queue selected by writing to QueueSel. - - 0x040 | RW | QueuePFN - Guest physical page number of the virtual queue. - Writing to this register notifies the host about location of the - virtual queue in the Guest's physical address space. This value - is the index number of a page starting with the queue - Descriptor Table. Value zero (0x0) means physical address zero - (0x00000000) and is illegal. When the Guest stops using the - queue it must write zero (0x0) to this register. - Reading from this register returns the currently used page - number of the queue, therefore a value other than zero (0x0) - means that the queue is in use. - Both read and write accesses apply to the queue selected by - writing to QueueSel. - - 0x050 | W | QueueNotify - Queue notifier. - Writing a queue index to this register notifies the Host that - there are new buffers to process in the queue. - - 0x60 | R | InterruptStatus -Interrupt status. -Reading from this register returns a bit mask of interrupts - asserted by the device. An interrupt is asserted if the - corresponding bit is set, ie. equals one (1). - - Bit 0 | Used Ring Update -This interrupt is asserted when the Host has updated the Used - Ring in at least one of the active virtual queues. - - Bit 1 | Configuration change -This interrupt is asserted when configuration of the device has - changed. - - 0x064 | W | InterruptACK - Interrupt acknowledge. - Writing to this register notifies the Host that the Guest - finished handling interrupts. Set bits in the value clear the - corresponding bits of the InterruptStatus register. - - 0x070 | RW | Status - Device status. - Reading from this register returns the current device status - flags. - Writing non-zero values to this register sets the status flags, - indicating the Guest progress. Writing zero (0x0) to this - register triggers a device reset. - Also see [sub:Device-Initialization-Sequence] - - 0x100+ | RW | Config - Device-specific configuration space starts at an offset 0x100 - and is accessed with byte alignment. Its meaning and size - depends on the device and the driver. - -Virtual queue size is a number of elements in the queue, -therefore size of the descriptor table and both available and -used rings. - -The endianness of the registers follows the native endianness of -the Guest. Writing to registers described as “R” and reading from -registers described as “W” is not permitted and can cause -undefined behavior. - -The device initialization is performed as described in [sub:Device-Initialization-Sequence] - with one exception: the Guest must notify the Host about its -page size, writing the size in bytes to GuestPageSize register -before the initialization is finished. - -The memory mapped virtio devices generate single interrupt only, -therefore no special configuration is required. - - Virtqueue Configuration - -The virtual queue configuration is performed in a similar way to -the one described in [sec:Virtqueue-Configuration] with a few -additional operations: - - Select the queue writing its index (first queue is 0) to the - QueueSel register. - - Check if the queue is not already in use: read QueuePFN - register, returned value should be zero (0x0). - - Read maximum queue size (number of elements) from the - QueueNumMax register. If the returned value is zero (0x0) the - queue is not available. - - Allocate and zero the queue pages in contiguous virtual memory, - aligning the Used Ring to an optimal boundary (usually page - size). Size of the allocated queue may be smaller than or equal - to the maximum size returned by the Host. - - Notify the Host about the queue size by writing the size to - QueueNum register. - - Notify the Host about the used alignment by writing its value - in bytes to QueueAlign register. - - Write the physical number of the first page of the queue to the - QueuePFN register. - -The queue and the device are ready to begin normal operations -now. - - Device Operation - -The memory mapped virtio device behaves in the same way as -described in [sec:Device-Operation], with the following -exceptions: - - The device is notified about new buffers available in a queue - by writing the queue index to register QueueNum instead of the - virtio header in PCI I/O space ([sub:Notifying-The-Device]). - - The memory mapped virtio device is using single, dedicated - interrupt signal, which is raised when at least one of the - interrupts described in the InterruptStatus register - description is asserted. After receiving an interrupt, the - driver must read the InterruptStatus register to check what - caused the interrupt (see the register description). After the - interrupt is handled, the driver must acknowledge it by writing - a bit mask corresponding to the serviced interrupt to the - InterruptACK register. - diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index d4abe7572ead..887c965c2711 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1599,7 +1599,6 @@ F: include/linux/bcma/ BROCADE BFA FC SCSI DRIVER M: Jing Huang -M: Krishna C Gudipati L: linux-scsi@vger.kernel.org S: Supported F: drivers/scsi/bfa/ @@ -1733,7 +1732,6 @@ S: Supported F: include/linux/capability.h F: security/capability.c F: security/commoncap.c -F: kernel/capability.c CELL BROADBAND ENGINE ARCHITECTURE M: Arnd Bergmann @@ -1971,9 +1969,10 @@ S: Maintained F: drivers/net/ethernet/ti/cpmac.c CPU FREQUENCY DRIVERS -M: Rafael J. Wysocki +M: Dave Jones L: cpufreq@vger.kernel.org -L: linux-pm@vger.kernel.org +W: http://www.codemonkey.org.uk/projects/cpufreq/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq.git S: Maintained F: drivers/cpufreq/ F: include/linux/cpufreq.h @@ -3630,7 +3629,7 @@ S: Maintained F: drivers/net/ethernet/icplus/ipg.* IPATH DRIVER -M: Mike Marciniszyn +M: Mike Marciniszyn L: linux-rdma@vger.kernel.org S: Maintained F: drivers/infiniband/hw/ipath/ @@ -4033,7 +4032,6 @@ F: Documentation/scsi/53c700.txt F: drivers/scsi/53c700* LED SUBSYSTEM -M: Bryan Wu M: Richard Purdie S: Maintained F: drivers/leds/ @@ -5130,13 +5128,19 @@ F: Documentation/powerpc/eeh-pci-error-recovery.txt PCI SUBSYSTEM M: Bjorn Helgaas L: linux-pci@vger.kernel.org -Q: http://patchwork.ozlabs.org/project/linux-pci/list/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/linux.git +Q: http://patchwork.kernel.org/project/linux-pci/list/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci.git S: Supported F: Documentation/PCI/ F: drivers/pci/ F: include/linux/pci* +PCI HOTPLUG +M: Bjorn Helgaas +L: linux-pci@vger.kernel.org +S: Supported +F: drivers/pci/hotplug + PCMCIA SUBSYSTEM P: Linux PCMCIA Team L: linux-pcmcia@lists.infradead.org @@ -5449,7 +5453,7 @@ L: rtc-linux@googlegroups.com S: Maintained QIB DRIVER -M: Mike Marciniszyn +M: Mike Marciniszyn L: linux-rdma@vger.kernel.org S: Supported F: drivers/infiniband/hw/qib/ @@ -5599,13 +5603,14 @@ F: net/rds/ READ-COPY UPDATE (RCU) M: Dipankar Sarma M: "Paul E. McKenney" -W: http://www.rdrop.com/users/paulmck/RCU/ +W: http://www.rdrop.com/users/paulmck/rclock/ S: Supported T: git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git F: Documentation/RCU/ -X: Documentation/RCU/torture.txt F: include/linux/rcu* +F: include/linux/srcu* F: kernel/rcu* +F: kernel/srcu* X: kernel/rcutorture.c REAL TIME CLOCK (RTC) SUBSYSTEM @@ -5951,7 +5956,7 @@ SECURITY SUBSYSTEM M: James Morris L: linux-security-module@vger.kernel.org (suggested Cc:) T: git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git -W: http://kernsec.org/ +W: http://security.wiki.kernel.org/ S: Supported F: security/ @@ -6122,15 +6127,6 @@ S: Maintained F: include/linux/sl?b*.h F: mm/sl?b.c -SLEEPABLE READ-COPY UPDATE (SRCU) -M: Lai Jiangshan -M: "Paul E. McKenney" -W: http://www.rdrop.com/users/paulmck/RCU/ -S: Supported -T: git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git -F: include/linux/srcu* -F: kernel/srcu* - SMC91x ETHERNET DRIVER M: Nicolas Pitre S: Odd Fixes @@ -6892,14 +6888,6 @@ F: Documentation/cdrom/ F: drivers/cdrom/cdrom.c F: include/linux/cdrom.h -UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER -M: Vinayak Holikatti -M: Santosh Y -L: linux-scsi@vger.kernel.org -S: Supported -F: Documentation/scsi/ufs.txt -F: drivers/scsi/ufs/ - UNSORTED BLOCK IMAGES (UBI) M: Artem Bityutskiy W: http://www.linux-mtd.infradead.org/ diff --git a/trunk/Makefile b/trunk/Makefile index a6879630a3ea..a06ee9fa8022 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 4 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = -rc5 NAME = Saber-toothed Squirrel # *DOCUMENTATION* @@ -442,7 +442,7 @@ asm-generic: no-dot-config-targets := clean mrproper distclean \ cscope gtags TAGS tags help %docs check% coccicheck \ - include/linux/version.h headers_% archheaders archscripts \ + include/linux/version.h headers_% archheaders \ kernelversion %src-pkg config-targets := 0 @@ -979,7 +979,7 @@ prepare1: prepare2 include/linux/version.h include/generated/utsrelease.h \ include/config/auto.conf $(cmd_crmodverdir) -archprepare: archheaders archscripts prepare1 scripts_basic +archprepare: archheaders prepare1 scripts_basic prepare0: archprepare FORCE $(Q)$(MAKE) $(build)=. @@ -1049,11 +1049,8 @@ hdr-dst = $(if $(KBUILD_HEADERS), dst=include/asm-$(hdr-arch), dst=include/asm) PHONY += archheaders archheaders: -PHONY += archscripts -archscripts: - PHONY += __headers -__headers: include/linux/version.h scripts_basic asm-generic archheaders archscripts FORCE +__headers: include/linux/version.h scripts_basic asm-generic archheaders FORCE $(Q)$(MAKE) $(build)=scripts build_unifdef PHONY += headers_install_all diff --git a/trunk/arch/Kconfig b/trunk/arch/Kconfig index 1f9461b9cc89..684eb5af439d 100644 --- a/trunk/arch/Kconfig +++ b/trunk/arch/Kconfig @@ -145,21 +145,6 @@ config HAVE_DMA_ATTRS config USE_GENERIC_SMP_HELPERS bool -config GENERIC_SMP_IDLE_THREAD - bool - -# Select if arch init_task initializer is different to init/init_task.c -config ARCH_INIT_TASK - bool - -# Select if arch has its private alloc_task_struct() function -config ARCH_TASK_STRUCT_ALLOCATOR - bool - -# Select if arch has its private alloc_thread_info() function -config ARCH_THREAD_INFO_ALLOCATOR - bool - config HAVE_REGS_AND_STACK_ACCESS_API bool help @@ -231,27 +216,4 @@ config HAVE_CMPXCHG_DOUBLE config ARCH_WANT_OLD_COMPAT_IPC bool -config HAVE_ARCH_SECCOMP_FILTER - bool - help - An arch should select this symbol if it provides all of these things: - - syscall_get_arch() - - syscall_get_arguments() - - syscall_rollback() - - syscall_set_return_value() - - SIGSYS siginfo_t support - - secure_computing is called from a ptrace_event()-safe context - - secure_computing return value is checked and a return value of -1 - results in the system call being skipped immediately. - -config SECCOMP_FILTER - def_bool y - depends on HAVE_ARCH_SECCOMP_FILTER && SECCOMP && NET - help - Enable tasks to build secure computing environments defined - in terms of Berkeley Packet Filter programs which implement - task-defined system call filtering polices. - - See Documentation/prctl/seccomp_filter.txt for details. - source "kernel/gcov/Kconfig" diff --git a/trunk/arch/alpha/Kconfig b/trunk/arch/alpha/Kconfig index 0893f023efb8..56a4df952fb0 100644 --- a/trunk/arch/alpha/Kconfig +++ b/trunk/arch/alpha/Kconfig @@ -15,7 +15,6 @@ config ALPHA select GENERIC_IRQ_SHOW select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_HAVE_NMI_SAFE_CMPXCHG - select GENERIC_SMP_IDLE_THREAD help The Alpha is a 64-bit general-purpose processor designed and marketed by the Digital Equipment Corporation of blessed memory, @@ -478,7 +477,7 @@ config ALPHA_BROKEN_IRQ_MASK config VGA_HOSE bool - depends on VGA_CONSOLE && (ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL || ALPHA_TSUNAMI) + depends on ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL || ALPHA_TSUNAMI default y help Support VGA on an arbitrary hose; needed for several platforms diff --git a/trunk/arch/alpha/include/asm/rtc.h b/trunk/arch/alpha/include/asm/rtc.h index d70408d36677..1f7fba671ae6 100644 --- a/trunk/arch/alpha/include/asm/rtc.h +++ b/trunk/arch/alpha/include/asm/rtc.h @@ -1,10 +1,14 @@ #ifndef _ALPHA_RTC_H #define _ALPHA_RTC_H -#if defined(CONFIG_ALPHA_MARVEL) && defined(CONFIG_SMP) \ - || defined(CONFIG_ALPHA_GENERIC) +#if defined(CONFIG_ALPHA_GENERIC) # define get_rtc_time alpha_mv.rtc_get_time # define set_rtc_time alpha_mv.rtc_set_time +#else +# if defined(CONFIG_ALPHA_MARVEL) && defined(CONFIG_SMP) +# define get_rtc_time marvel_get_rtc_time +# define set_rtc_time marvel_set_rtc_time +# endif #endif #include diff --git a/trunk/arch/alpha/kernel/Makefile b/trunk/arch/alpha/kernel/Makefile index 84ec46b38f7d..7a6d908bb865 100644 --- a/trunk/arch/alpha/kernel/Makefile +++ b/trunk/arch/alpha/kernel/Makefile @@ -6,7 +6,7 @@ extra-y := head.o vmlinux.lds asflags-y := $(KBUILD_CFLAGS) ccflags-y := -Wno-sign-compare -obj-y := entry.o traps.o process.o osf_sys.o irq.o \ +obj-y := entry.o traps.o process.o init_task.o osf_sys.o irq.o \ irq_alpha.o signal.o setup.o ptrace.o time.o \ alpha_ksyms.o systbls.o err_common.o io.o diff --git a/trunk/arch/alpha/kernel/core_tsunami.c b/trunk/arch/alpha/kernel/core_tsunami.c index 61893d7bdda5..5e7c28f92f19 100644 --- a/trunk/arch/alpha/kernel/core_tsunami.c +++ b/trunk/arch/alpha/kernel/core_tsunami.c @@ -11,7 +11,6 @@ #include #undef __EXTERN_INLINE -#include #include #include #include diff --git a/trunk/init/init_task.c b/trunk/arch/alpha/kernel/init_task.c similarity index 73% rename from trunk/init/init_task.c rename to trunk/arch/alpha/kernel/init_task.c index 8b2f3996b035..6f80ca4f9766 100644 --- a/trunk/init/init_task.c +++ b/trunk/arch/alpha/kernel/init_task.c @@ -1,24 +1,17 @@ -#include -#include -#include +#include +#include #include #include +#include #include -#include - -#include +#include #include + static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); - -/* Initial task structure */ struct task_struct init_task = INIT_TASK(init_task); EXPORT_SYMBOL(init_task); -/* - * Initial thread structure. Alignment of this is handled by a special - * linker map entry. - */ union thread_union init_thread_union __init_task_data = { INIT_THREAD_INFO(init_task) }; diff --git a/trunk/arch/alpha/kernel/smp.c b/trunk/arch/alpha/kernel/smp.c index 35ddc02bfa4a..50d438db1f6b 100644 --- a/trunk/arch/alpha/kernel/smp.c +++ b/trunk/arch/alpha/kernel/smp.c @@ -357,10 +357,24 @@ secondary_cpu_start(int cpuid, struct task_struct *idle) * Bring one cpu online. */ static int __cpuinit -smp_boot_one_cpu(int cpuid, struct task_struct *idle) +smp_boot_one_cpu(int cpuid) { + struct task_struct *idle; unsigned long timeout; + /* Cook up an idler for this guy. Note that the address we + give to kernel_thread is irrelevant -- it's going to start + where HWRPB.CPU_restart says to start. But this gets all + the other task-y sort of data structures set up like we + wish. We can't use kernel_thread since we must avoid + rescheduling the child. */ + idle = fork_idle(cpuid); + if (IS_ERR(idle)) + panic("failed fork for CPU %d", cpuid); + + DBGS(("smp_boot_one_cpu: CPU %d state 0x%lx flags 0x%lx\n", + cpuid, idle->state, idle->flags)); + /* Signal the secondary to wait a moment. */ smp_secondary_alive = -1; @@ -473,9 +487,9 @@ smp_prepare_boot_cpu(void) } int __cpuinit -__cpu_up(unsigned int cpu, struct task_struct *tidle) +__cpu_up(unsigned int cpu) { - smp_boot_one_cpu(cpu, tidle); + smp_boot_one_cpu(cpu); return cpu_online(cpu) ? 0 : -ENOSYS; } diff --git a/trunk/arch/alpha/kernel/sys_marvel.c b/trunk/arch/alpha/kernel/sys_marvel.c index 407accc80877..14a4b6a7cf59 100644 --- a/trunk/arch/alpha/kernel/sys_marvel.c +++ b/trunk/arch/alpha/kernel/sys_marvel.c @@ -317,7 +317,7 @@ marvel_init_irq(void) } static int -marvel_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +marvel_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct pci_controller *hose = dev->sysdata; struct io7_port *io7_port = hose->sysdata; diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 002b1c8da225..36586dba6fa6 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -11,7 +11,6 @@ config ARM select HAVE_OPROFILE if (HAVE_PERF_EVENTS) select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL select HAVE_ARCH_KGDB - select HAVE_ARCH_TRACEHOOK select HAVE_KPROBES if !XIP_KERNEL select HAVE_KRETPROBES if (HAVE_KPROBES) select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) @@ -31,15 +30,10 @@ config ARM select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7)) select HAVE_C_RECORDMCOUNT select HAVE_GENERIC_HARDIRQS - select HARDIRQS_SW_RESEND - select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW - select GENERIC_IRQ_PROBE - select HARDIRQS_SW_RESEND select CPU_PM if (SUSPEND || CPU_IDLE) select GENERIC_PCI_IOMAP - select HAVE_BPF_JIT - select GENERIC_SMP_IDLE_THREAD + select HAVE_BPF_JIT if NET help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and @@ -132,6 +126,14 @@ config TRACE_IRQFLAGS_SUPPORT bool default y +config HARDIRQS_SW_RESEND + bool + default y + +config GENERIC_IRQ_PROBE + bool + default y + config GENERIC_LOCKBREAK bool default y @@ -157,6 +159,9 @@ config ARCH_HAS_CPUFREQ and that the relevant menu configurations are displayed for it. +config ARCH_HAS_CPU_IDLE_WAIT + def_bool y + config GENERIC_HWEIGHT bool default y @@ -275,7 +280,6 @@ config ARCH_INTEGRATOR select NEED_MACH_IO_H select NEED_MACH_MEMORY_H select SPARSE_IRQ - select MULTI_IRQ_HANDLER help Support for ARM's Integrator platform. @@ -628,6 +632,7 @@ config ARCH_MMP select CLKDEV_LOOKUP select GENERIC_CLOCKEVENTS select GPIO_PXA + select TICK_ONESHOT select PLAT_PXA select SPARSE_IRQ select GENERIC_ALLOCATOR @@ -711,6 +716,7 @@ config ARCH_PXA select ARCH_REQUIRE_GPIOLIB select GENERIC_CLOCKEVENTS select GPIO_PXA + select TICK_ONESHOT select PLAT_PXA select SPARSE_IRQ select AUTO_ZRELADDR @@ -777,6 +783,7 @@ config ARCH_SA1100 select CPU_FREQ select GENERIC_CLOCKEVENTS select CLKDEV_LOOKUP + select TICK_ONESHOT select ARCH_REQUIRE_GPIOLIB select HAVE_IDE select NEED_MACH_MEMORY_H @@ -1545,15 +1552,10 @@ config HAVE_ARM_SCU help This option enables support for the ARM system coherency unit -config ARM_ARCH_TIMER - bool "Architected timer support" - depends on CPU_V7 - help - This option enables support for the ARM architected timer - config HAVE_ARM_TWD bool depends on SMP + select TICK_ONESHOT help This options enables support for the ARM timer and watchdog unit diff --git a/trunk/arch/arm/Makefile b/trunk/arch/arm/Makefile index 3b18ef7ad278..047a20780fc1 100644 --- a/trunk/arch/arm/Makefile +++ b/trunk/arch/arm/Makefile @@ -70,6 +70,8 @@ arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4 arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3 # This selects how we optimise for the processor. +tune-$(CONFIG_CPU_ARM610) :=-mtune=arm610 +tune-$(CONFIG_CPU_ARM710) :=-mtune=arm710 tune-$(CONFIG_CPU_ARM7TDMI) :=-mtune=arm7tdmi tune-$(CONFIG_CPU_ARM720T) :=-mtune=arm7tdmi tune-$(CONFIG_CPU_ARM740T) :=-mtune=arm7tdmi @@ -117,7 +119,7 @@ KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_THUMB2) $(arch-y) $(tune-y) -include asm/ CHECKFLAGS += -D__arm__ #Default value -head-y := arch/arm/kernel/head$(MMUEXT).o +head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o textofs-y := 0x00008000 textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000 # We don't want the htc bootloader to corrupt kernel during resume diff --git a/trunk/arch/arm/boot/compressed/head.S b/trunk/arch/arm/boot/compressed/head.S index b8c64b80bafc..dc7e8ce8e6be 100644 --- a/trunk/arch/arm/boot/compressed/head.S +++ b/trunk/arch/arm/boot/compressed/head.S @@ -567,12 +567,6 @@ __armv3_mpu_cache_on: mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 mov pc, lr -#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH -#define CB_BITS 0x08 -#else -#define CB_BITS 0x0c -#endif - __setup_mmu: sub r3, r4, #16384 @ Page directory size bic r3, r3, #0xff @ Align the pointer bic r3, r3, #0x3f00 @@ -584,14 +578,17 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size mov r9, r0, lsr #18 mov r9, r9, lsl #18 @ start of RAM add r10, r9, #0x10000000 @ a reasonable RAM size - mov r1, #0x12 @ XN|U + section mapping - orr r1, r1, #3 << 10 @ AP=11 + mov r1, #0x12 + orr r1, r1, #3 << 10 add r2, r3, #16384 1: cmp r1, r9 @ if virt > start of RAM - cmphs r10, r1 @ && end of RAM > virt - bic r1, r1, #0x1c @ clear XN|U + C + B - orrlo r1, r1, #0x10 @ Set XN|U for non-RAM - orrhs r1, r1, r6 @ set RAM section settings +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + orrhs r1, r1, #0x08 @ set cacheable +#else + orrhs r1, r1, #0x0c @ set cacheable, bufferable +#endif + cmp r1, r10 @ if virt > end of RAM + bichs r1, r1, #0x0c @ clear cacheable, bufferable str r1, [r0], #4 @ 1:1 mapping add r1, r1, #1048576 teq r0, r2 @@ -602,7 +599,7 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size * so there is no map overlap problem for up to 1 MB compressed kernel. * If the execution is in RAM then we would only be duplicating the above. */ - orr r1, r6, #0x04 @ ensure B is set for this + mov r1, #0x1e orr r1, r1, #3 << 10 mov r2, pc mov r2, r2, lsr #20 @@ -623,7 +620,6 @@ __arm926ejs_mmu_cache_on: __armv4_mmu_cache_on: mov r12, lr #ifdef CONFIG_MMU - mov r6, #CB_BITS | 0x12 @ U bl __setup_mmu mov r0, #0 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer @@ -645,7 +641,6 @@ __armv7_mmu_cache_on: #ifdef CONFIG_MMU mrc p15, 0, r11, c0, c1, 4 @ read ID_MMFR0 tst r11, #0xf @ VMSA - movne r6, #CB_BITS | 0x02 @ !XN blne __setup_mmu mov r0, #0 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer @@ -660,7 +655,7 @@ __armv7_mmu_cache_on: orr r0, r0, #1 << 25 @ big-endian page tables #endif orrne r0, r0, #1 @ MMU enabled - movne r1, #0xfffffffd @ domain 0 = client + movne r1, #-1 mcrne p15, 0, r3, c2, c0, 0 @ load page table pointer mcrne p15, 0, r1, c3, c0, 0 @ load domain access control #endif @@ -673,7 +668,6 @@ __armv7_mmu_cache_on: __fa526_cache_on: mov r12, lr - mov r6, #CB_BITS | 0x12 @ U bl __setup_mmu mov r0, #0 mcr p15, 0, r0, c7, c7, 0 @ Invalidate whole cache @@ -686,6 +680,18 @@ __fa526_cache_on: mcr p15, 0, r0, c8, c7, 0 @ flush UTLB mov pc, r12 +__arm6_mmu_cache_on: + mov r12, lr + bl __setup_mmu + mov r0, #0 + mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 + mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3 + mov r0, #0x30 + bl __common_mmu_cache_on + mov r0, #0 + mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3 + mov pc, r12 + __common_mmu_cache_on: #ifndef CONFIG_THUMB2_KERNEL #ifndef DEBUG @@ -750,6 +756,16 @@ call_cache_fn: adr r12, proc_types .align 2 .type proc_types,#object proc_types: + .word 0x41560600 @ ARM6/610 + .word 0xffffffe0 + W(b) __arm6_mmu_cache_off @ works, but slow + W(b) __arm6_mmu_cache_off + mov pc, lr + THUMB( nop ) +@ b __arm6_mmu_cache_on @ untested +@ b __arm6_mmu_cache_off +@ b __armv3_mmu_cache_flush + .word 0x00000000 @ old ARM ID .word 0x0000f000 mov pc, lr @@ -761,10 +777,8 @@ proc_types: .word 0x41007000 @ ARM7/710 .word 0xfff8fe00 - mov pc, lr - THUMB( nop ) - mov pc, lr - THUMB( nop ) + W(b) __arm7_mmu_cache_off + W(b) __arm7_mmu_cache_off mov pc, lr THUMB( nop ) @@ -963,6 +977,21 @@ __armv7_mmu_cache_off: mcr p15, 0, r0, c7, c5, 4 @ ISB mov pc, r12 +__arm6_mmu_cache_off: + mov r0, #0x00000030 @ ARM6 control reg. + b __armv3_mmu_cache_off + +__arm7_mmu_cache_off: + mov r0, #0x00000070 @ ARM7 control reg. + b __armv3_mmu_cache_off + +__armv3_mmu_cache_off: + mcr p15, 0, r0, c1, c0, 0 @ turn MMU and cache off + mov r0, #0 + mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 + mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3 + mov pc, lr + /* * Clean and flush the cache to maintain consistency. * diff --git a/trunk/arch/arm/common/it8152.c b/trunk/arch/arm/common/it8152.c index c4110d1b1f2d..dcb13494ca0d 100644 --- a/trunk/arch/arm/common/it8152.c +++ b/trunk/arch/arm/common/it8152.c @@ -222,7 +222,7 @@ static int it8152_pci_write_config(struct pci_bus *bus, return PCIBIOS_SUCCESSFUL; } -struct pci_ops it8152_ops = { +static struct pci_ops it8152_ops = { .read = it8152_pci_read_config, .write = it8152_pci_write_config, }; @@ -346,4 +346,9 @@ void pcibios_set_master(struct pci_dev *dev) } +struct pci_bus * __init it8152_pci_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_root_bus(NULL, nr, &it8152_ops, sys, &sys->resources); +} + EXPORT_SYMBOL(dma_set_coherent_mask); diff --git a/trunk/arch/arm/common/via82c505.c b/trunk/arch/arm/common/via82c505.c index 6cb362e56d29..1171a5010aea 100644 --- a/trunk/arch/arm/common/via82c505.c +++ b/trunk/arch/arm/common/via82c505.c @@ -51,7 +51,7 @@ via82c505_write_config(struct pci_bus *bus, unsigned int devfn, int where, return PCIBIOS_SUCCESSFUL; } -struct pci_ops via82c505_ops = { +static struct pci_ops via82c505_ops = { .read = via82c505_read_config, .write = via82c505_write_config, }; @@ -81,3 +81,12 @@ int __init via82c505_setup(int nr, struct pci_sys_data *sys) { return (nr == 0); } + +struct pci_bus * __init via82c505_scan_bus(int nr, struct pci_sys_data *sysdata) +{ + if (nr == 0) + return pci_scan_root_bus(NULL, 0, &via82c505_ops, sysdata, + &sysdata->resources); + + return NULL; +} diff --git a/trunk/arch/arm/common/vic.c b/trunk/arch/arm/common/vic.c index e0d538803cc3..7e288f96cedf 100644 --- a/trunk/arch/arm/common/vic.c +++ b/trunk/arch/arm/common/vic.c @@ -39,7 +39,6 @@ * struct vic_device - VIC PM device * @irq: The IRQ number for the base of the VIC. * @base: The register base for the VIC. - * @valid_sources: A bitmask of valid interrupts * @resume_sources: A bitmask of interrupts for resume. * @resume_irqs: The IRQs enabled for resume. * @int_select: Save for VIC_INT_SELECT. @@ -51,7 +50,6 @@ struct vic_device { void __iomem *base; int irq; - u32 valid_sources; u32 resume_sources; u32 resume_irqs; u32 int_select; @@ -166,32 +164,10 @@ static int __init vic_pm_init(void) late_initcall(vic_pm_init); #endif /* CONFIG_PM */ -static struct irq_chip vic_chip; - -static int vic_irqdomain_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hwirq) -{ - struct vic_device *v = d->host_data; - - /* Skip invalid IRQs, only register handlers for the real ones */ - if (!(v->valid_sources & (1 << hwirq))) - return -ENOTSUPP; - irq_set_chip_and_handler(irq, &vic_chip, handle_level_irq); - irq_set_chip_data(irq, v->base); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - return 0; -} - -static struct irq_domain_ops vic_irqdomain_ops = { - .map = vic_irqdomain_map, - .xlate = irq_domain_xlate_onetwocell, -}; - /** * vic_register() - Register a VIC. * @base: The base address of the VIC. * @irq: The base IRQ for the VIC. - * @valid_sources: bitmask of valid interrupts * @resume_sources: bitmask of interrupts allowed for resume sources. * @node: The device tree node associated with the VIC. * @@ -202,8 +178,7 @@ static struct irq_domain_ops vic_irqdomain_ops = { * This also configures the IRQ domain for the VIC. */ static void __init vic_register(void __iomem *base, unsigned int irq, - u32 valid_sources, u32 resume_sources, - struct device_node *node) + u32 resume_sources, struct device_node *node) { struct vic_device *v; @@ -214,12 +189,11 @@ static void __init vic_register(void __iomem *base, unsigned int irq, v = &vic_devices[vic_id]; v->base = base; - v->valid_sources = valid_sources; v->resume_sources = resume_sources; v->irq = irq; vic_id++; - v->domain = irq_domain_add_legacy(node, fls(valid_sources), irq, 0, - &vic_irqdomain_ops, v); + v->domain = irq_domain_add_legacy(node, 32, irq, 0, + &irq_domain_simple_ops, v); } static void vic_ack_irq(struct irq_data *d) @@ -313,6 +287,23 @@ static void __init vic_clear_interrupts(void __iomem *base) } } +static void __init vic_set_irq_sources(void __iomem *base, + unsigned int irq_start, u32 vic_sources) +{ + unsigned int i; + + for (i = 0; i < 32; i++) { + if (vic_sources & (1 << i)) { + unsigned int irq = irq_start + i; + + irq_set_chip_and_handler(irq, &vic_chip, + handle_level_irq); + irq_set_chip_data(irq, base); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + } +} + /* * The PL190 cell from ARM has been modified by ST to handle 64 interrupts. * The original cell has 32 interrupts, while the modified one has 64, @@ -347,7 +338,8 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start, writel(32, base + VIC_PL190_DEF_VECT_ADDR); } - vic_register(base, irq_start, vic_sources, 0, node); + vic_set_irq_sources(base, irq_start, vic_sources); + vic_register(base, irq_start, 0, node); } void __init __vic_init(void __iomem *base, unsigned int irq_start, @@ -387,7 +379,9 @@ void __init __vic_init(void __iomem *base, unsigned int irq_start, vic_init2(base); - vic_register(base, irq_start, vic_sources, resume_sources, node); + vic_set_irq_sources(base, irq_start, vic_sources); + + vic_register(base, irq_start, resume_sources, node); } /** diff --git a/trunk/arch/arm/configs/rpc_defconfig b/trunk/arch/arm/configs/rpc_defconfig index 00515ef9782d..af278f7a2246 100644 --- a/trunk/arch/arm/configs/rpc_defconfig +++ b/trunk/arch/arm/configs/rpc_defconfig @@ -8,6 +8,8 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set CONFIG_ARCH_RPC=y +CONFIG_CPU_ARM610=y +CONFIG_CPU_ARM710=y CONFIG_CPU_SA110=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 diff --git a/trunk/arch/arm/include/asm/arch_timer.h b/trunk/arch/arm/include/asm/arch_timer.h deleted file mode 100644 index ed2e95d46e29..000000000000 --- a/trunk/arch/arm/include/asm/arch_timer.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __ASMARM_ARCH_TIMER_H -#define __ASMARM_ARCH_TIMER_H - -#ifdef CONFIG_ARM_ARCH_TIMER -int arch_timer_of_register(void); -int arch_timer_sched_clock_init(void); -#else -static inline int arch_timer_of_register(void) -{ - return -ENXIO; -} - -static inline int arch_timer_sched_clock_init(void) -{ - return -ENXIO; -} -#endif - -#endif diff --git a/trunk/arch/arm/include/asm/cacheflush.h b/trunk/arch/arm/include/asm/cacheflush.h index 004c1bc95d2b..d5d8d5c72682 100644 --- a/trunk/arch/arm/include/asm/cacheflush.h +++ b/trunk/arch/arm/include/asm/cacheflush.h @@ -101,7 +101,7 @@ struct cpu_cache_fns { void (*flush_user_range)(unsigned long, unsigned long, unsigned int); void (*coherent_kern_range)(unsigned long, unsigned long); - int (*coherent_user_range)(unsigned long, unsigned long); + void (*coherent_user_range)(unsigned long, unsigned long); void (*flush_kern_dcache_area)(void *, size_t); void (*dma_map_area)(const void *, size_t, int); @@ -142,7 +142,7 @@ extern void __cpuc_flush_kern_all(void); extern void __cpuc_flush_user_all(void); extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int); extern void __cpuc_coherent_kern_range(unsigned long, unsigned long); -extern int __cpuc_coherent_user_range(unsigned long, unsigned long); +extern void __cpuc_coherent_user_range(unsigned long, unsigned long); extern void __cpuc_flush_dcache_area(void *, size_t); /* @@ -249,7 +249,7 @@ extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr * Harvard caches are synchronised for the user space address range. * This is used for the ARM private sys_cacheflush system call. */ -#define flush_cache_user_range(start,end) \ +#define flush_cache_user_range(vma,start,end) \ __cpuc_coherent_user_range((start) & PAGE_MASK, PAGE_ALIGN(end)) /* diff --git a/trunk/arch/arm/include/asm/cmpxchg.h b/trunk/arch/arm/include/asm/cmpxchg.h index 7eb18c1d8d6c..d41d7cbf0ada 100644 --- a/trunk/arch/arm/include/asm/cmpxchg.h +++ b/trunk/arch/arm/include/asm/cmpxchg.h @@ -229,19 +229,66 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr, (unsigned long)(n), \ sizeof(*(ptr)))) -#define cmpxchg64(ptr, o, n) \ - ((__typeof__(*(ptr)))atomic64_cmpxchg(container_of((ptr), \ - atomic64_t, \ - counter), \ - (unsigned long)(o), \ - (unsigned long)(n))) - -#define cmpxchg64_local(ptr, o, n) \ - ((__typeof__(*(ptr)))local64_cmpxchg(container_of((ptr), \ - local64_t, \ - a), \ - (unsigned long)(o), \ - (unsigned long)(n))) +#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */ + +/* + * Note : ARMv7-M (currently unsupported by Linux) does not support + * ldrexd/strexd. If ARMv7-M is ever supported by the Linux kernel, it should + * not be allowed to use __cmpxchg64. + */ +static inline unsigned long long __cmpxchg64(volatile void *ptr, + unsigned long long old, + unsigned long long new) +{ + register unsigned long long oldval asm("r0"); + register unsigned long long __old asm("r2") = old; + register unsigned long long __new asm("r4") = new; + unsigned long res; + + do { + asm volatile( + " @ __cmpxchg8\n" + " ldrexd %1, %H1, [%2]\n" + " mov %0, #0\n" + " teq %1, %3\n" + " teqeq %H1, %H3\n" + " strexdeq %0, %4, %H4, [%2]\n" + : "=&r" (res), "=&r" (oldval) + : "r" (ptr), "Ir" (__old), "r" (__new) + : "memory", "cc"); + } while (res); + + return oldval; +} + +static inline unsigned long long __cmpxchg64_mb(volatile void *ptr, + unsigned long long old, + unsigned long long new) +{ + unsigned long long ret; + + smp_mb(); + ret = __cmpxchg64(ptr, old, new); + smp_mb(); + + return ret; +} + +#define cmpxchg64(ptr,o,n) \ + ((__typeof__(*(ptr)))__cmpxchg64_mb((ptr), \ + (unsigned long long)(o), \ + (unsigned long long)(n))) + +#define cmpxchg64_local(ptr,o,n) \ + ((__typeof__(*(ptr)))__cmpxchg64((ptr), \ + (unsigned long long)(o), \ + (unsigned long long)(n))) + +#else /* min ARCH = ARMv6 */ + +#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) + +#endif #endif /* __LINUX_ARM_ARCH__ >= 6 */ diff --git a/trunk/arch/arm/include/asm/cpu.h b/trunk/arch/arm/include/asm/cpu.h index d797223b39d5..793968173bef 100644 --- a/trunk/arch/arm/include/asm/cpu.h +++ b/trunk/arch/arm/include/asm/cpu.h @@ -16,6 +16,7 @@ struct cpuinfo_arm { struct cpu cpu; #ifdef CONFIG_SMP + struct task_struct *idle; unsigned int loops_per_jiffy; #endif }; diff --git a/trunk/arch/arm/include/asm/glue-df.h b/trunk/arch/arm/include/asm/glue-df.h index 8cacbcda76da..354d571e8bcc 100644 --- a/trunk/arch/arm/include/asm/glue-df.h +++ b/trunk/arch/arm/include/asm/glue-df.h @@ -31,6 +31,14 @@ #undef CPU_DABORT_HANDLER #undef MULTI_DABORT +#if defined(CONFIG_CPU_ARM610) +# ifdef CPU_DABORT_HANDLER +# define MULTI_DABORT 1 +# else +# define CPU_DABORT_HANDLER cpu_arm6_data_abort +# endif +#endif + #if defined(CONFIG_CPU_ARM710) # ifdef CPU_DABORT_HANDLER # define MULTI_DABORT 1 diff --git a/trunk/arch/arm/include/asm/glue-proc.h b/trunk/arch/arm/include/asm/glue-proc.h index ac1dd54724b6..e2be7f142668 100644 --- a/trunk/arch/arm/include/asm/glue-proc.h +++ b/trunk/arch/arm/include/asm/glue-proc.h @@ -23,6 +23,15 @@ * CPU_NAME - the prefix for CPU related functions */ +#ifdef CONFIG_CPU_ARM610 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm6 +# endif +#endif + #ifdef CONFIG_CPU_ARM7TDMI # ifdef CPU_NAME # undef MULTI_CPU @@ -32,6 +41,15 @@ # endif #endif +#ifdef CONFIG_CPU_ARM710 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm7 +# endif +#endif + #ifdef CONFIG_CPU_ARM720T # ifdef CPU_NAME # undef MULTI_CPU diff --git a/trunk/arch/arm/include/asm/hardware/it8152.h b/trunk/arch/arm/include/asm/hardware/it8152.h index d36a73d7c0e8..73f84fa4f366 100644 --- a/trunk/arch/arm/include/asm/hardware/it8152.h +++ b/trunk/arch/arm/include/asm/hardware/it8152.h @@ -110,6 +110,6 @@ extern void it8152_irq_demux(unsigned int irq, struct irq_desc *desc); extern void it8152_init_irq(void); extern int it8152_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); extern int it8152_pci_setup(int nr, struct pci_sys_data *sys); -extern struct pci_ops it8152_ops; +extern struct pci_bus *it8152_pci_scan_bus(int nr, struct pci_sys_data *sys); #endif /* __ASM_HARDWARE_IT8152_H */ diff --git a/trunk/arch/arm/include/asm/mach/pci.h b/trunk/arch/arm/include/asm/mach/pci.h index 26c511fddf8f..d943b7d20f11 100644 --- a/trunk/arch/arm/include/asm/mach/pci.h +++ b/trunk/arch/arm/include/asm/mach/pci.h @@ -12,14 +12,13 @@ #define __ASM_MACH_PCI_H struct pci_sys_data; -struct pci_ops; struct pci_bus; struct hw_pci { #ifdef CONFIG_PCI_DOMAINS int domain; #endif - struct pci_ops *ops; + struct list_head buses; int nr_controllers; int (*setup)(int nr, struct pci_sys_data *); struct pci_bus *(*scan)(int nr, struct pci_sys_data *); @@ -46,9 +45,15 @@ struct pci_sys_data { u8 (*swizzle)(struct pci_dev *, u8 *); /* IRQ mapping */ int (*map_irq)(const struct pci_dev *, u8, u8); + struct hw_pci *hw; void *private_data; /* platform controller private data */ }; +/* + * This is the standard PCI-PCI bridge swizzling algorithm. + */ +#define pci_std_swizzle pci_common_swizzle + /* * Call this with your hw_pci struct to initialise the PCI system. */ @@ -57,22 +62,22 @@ void pci_common_init(struct hw_pci *); /* * PCI controllers */ -extern struct pci_ops iop3xx_ops; extern int iop3xx_pci_setup(int nr, struct pci_sys_data *); +extern struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *); extern void iop3xx_pci_preinit(void); extern void iop3xx_pci_preinit_cond(void); -extern struct pci_ops dc21285_ops; extern int dc21285_setup(int nr, struct pci_sys_data *); +extern struct pci_bus *dc21285_scan_bus(int nr, struct pci_sys_data *); extern void dc21285_preinit(void); extern void dc21285_postinit(void); -extern struct pci_ops via82c505_ops; extern int via82c505_setup(int nr, struct pci_sys_data *); +extern struct pci_bus *via82c505_scan_bus(int nr, struct pci_sys_data *); extern void via82c505_init(void *sysdata); -extern struct pci_ops pci_v3_ops; extern int pci_v3_setup(int nr, struct pci_sys_data *); +extern struct pci_bus *pci_v3_scan_bus(int nr, struct pci_sys_data *); extern void pci_v3_preinit(void); extern void pci_v3_postinit(void); diff --git a/trunk/arch/arm/include/asm/mach/time.h b/trunk/arch/arm/include/asm/mach/time.h index 6ca945f534ab..f73c908b7fa0 100644 --- a/trunk/arch/arm/include/asm/mach/time.h +++ b/trunk/arch/arm/include/asm/mach/time.h @@ -42,9 +42,4 @@ struct sys_timer { extern void timer_tick(void); -struct timespec; -typedef void (*clock_access_fn)(struct timespec *); -extern int register_persistent_clock(clock_access_fn read_boot, - clock_access_fn read_persistent); - #endif diff --git a/trunk/arch/arm/include/asm/mmu.h b/trunk/arch/arm/include/asm/mmu.h index 14965658a923..b8e580a297e4 100644 --- a/trunk/arch/arm/include/asm/mmu.h +++ b/trunk/arch/arm/include/asm/mmu.h @@ -34,4 +34,11 @@ typedef struct { #endif +/* + * switch_mm() may do a full cache flush over the context switch, + * so enable interrupts over the context switch to avoid high + * latency. + */ +#define __ARCH_WANT_INTERRUPTS_ON_CTXSW + #endif diff --git a/trunk/arch/arm/include/asm/mmu_context.h b/trunk/arch/arm/include/asm/mmu_context.h index 0306bc642c0d..a0b3cac0547c 100644 --- a/trunk/arch/arm/include/asm/mmu_context.h +++ b/trunk/arch/arm/include/asm/mmu_context.h @@ -43,104 +43,45 @@ void __check_kvm_seq(struct mm_struct *mm); #define ASID_FIRST_VERSION (1 << ASID_BITS) extern unsigned int cpu_last_asid; +#ifdef CONFIG_SMP +DECLARE_PER_CPU(struct mm_struct *, current_mm); +#endif void __init_new_context(struct task_struct *tsk, struct mm_struct *mm); void __new_context(struct mm_struct *mm); -void cpu_set_reserved_ttbr0(void); -static inline void switch_new_context(struct mm_struct *mm) +static inline void check_context(struct mm_struct *mm) { - unsigned long flags; - - __new_context(mm); - - local_irq_save(flags); - cpu_switch_mm(mm->pgd, mm); - local_irq_restore(flags); -} + /* + * This code is executed with interrupts enabled. Therefore, + * mm->context.id cannot be updated to the latest ASID version + * on a different CPU (and condition below not triggered) + * without first getting an IPI to reset the context. The + * alternative is to take a read_lock on mm->context.id_lock + * (after changing its type to rwlock_t). + */ + if (unlikely((mm->context.id ^ cpu_last_asid) >> ASID_BITS)) + __new_context(mm); -static inline void check_and_switch_context(struct mm_struct *mm, - struct task_struct *tsk) -{ if (unlikely(mm->context.kvm_seq != init_mm.context.kvm_seq)) __check_kvm_seq(mm); - - /* - * Required during context switch to avoid speculative page table - * walking with the wrong TTBR. - */ - cpu_set_reserved_ttbr0(); - - if (!((mm->context.id ^ cpu_last_asid) >> ASID_BITS)) - /* - * The ASID is from the current generation, just switch to the - * new pgd. This condition is only true for calls from - * context_switch() and interrupts are already disabled. - */ - cpu_switch_mm(mm->pgd, mm); - else if (irqs_disabled()) - /* - * Defer the new ASID allocation until after the context - * switch critical region since __new_context() cannot be - * called with interrupts disabled (it sends IPIs). - */ - set_ti_thread_flag(task_thread_info(tsk), TIF_SWITCH_MM); - else - /* - * That is a direct call to switch_mm() or activate_mm() with - * interrupts enabled and a new context. - */ - switch_new_context(mm); } #define init_new_context(tsk,mm) (__init_new_context(tsk,mm),0) -#define finish_arch_post_lock_switch \ - finish_arch_post_lock_switch -static inline void finish_arch_post_lock_switch(void) -{ - if (test_and_clear_thread_flag(TIF_SWITCH_MM)) - switch_new_context(current->mm); -} - -#else /* !CONFIG_CPU_HAS_ASID */ +#else -#ifdef CONFIG_MMU - -static inline void check_and_switch_context(struct mm_struct *mm, - struct task_struct *tsk) +static inline void check_context(struct mm_struct *mm) { +#ifdef CONFIG_MMU if (unlikely(mm->context.kvm_seq != init_mm.context.kvm_seq)) __check_kvm_seq(mm); - - if (irqs_disabled()) - /* - * cpu_switch_mm() needs to flush the VIVT caches. To avoid - * high interrupt latencies, defer the call and continue - * running with the old mm. Since we only support UP systems - * on non-ASID CPUs, the old mm will remain valid until the - * finish_arch_post_lock_switch() call. - */ - set_ti_thread_flag(task_thread_info(tsk), TIF_SWITCH_MM); - else - cpu_switch_mm(mm->pgd, mm); -} - -#define finish_arch_post_lock_switch \ - finish_arch_post_lock_switch -static inline void finish_arch_post_lock_switch(void) -{ - if (test_and_clear_thread_flag(TIF_SWITCH_MM)) { - struct mm_struct *mm = current->mm; - cpu_switch_mm(mm->pgd, mm); - } +#endif } -#endif /* CONFIG_MMU */ - #define init_new_context(tsk,mm) 0 -#endif /* CONFIG_CPU_HAS_ASID */ +#endif #define destroy_context(mm) do { } while(0) @@ -178,7 +119,12 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next, __flush_icache_all(); #endif if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) { - check_and_switch_context(next, tsk); +#ifdef CONFIG_SMP + struct mm_struct **crt_mm = &per_cpu(current_mm, cpu); + *crt_mm = next; +#endif + check_context(next); + cpu_switch_mm(next->pgd, next); if (cache_is_vivt()) cpumask_clear_cpu(cpu, mm_cpumask(prev)); } diff --git a/trunk/arch/arm/include/asm/page.h b/trunk/arch/arm/include/asm/page.h index ecf901902e44..5838361c48b3 100644 --- a/trunk/arch/arm/include/asm/page.h +++ b/trunk/arch/arm/include/asm/page.h @@ -34,6 +34,7 @@ * processor(s) we're building for. * * We have the following to choose from: + * v3 - ARMv3 * v4wt - ARMv4 with writethrough cache, without minicache * v4wb - ARMv4 with writeback cache, without minicache * v4_mc - ARMv4 with minicache @@ -43,6 +44,14 @@ #undef _USER #undef MULTI_USER +#ifdef CONFIG_CPU_COPY_V3 +# ifdef _USER +# define MULTI_USER 1 +# else +# define _USER v3 +# endif +#endif + #ifdef CONFIG_CPU_COPY_V4WT # ifdef _USER # define MULTI_USER 1 diff --git a/trunk/arch/arm/include/asm/pgtable-3level.h b/trunk/arch/arm/include/asm/pgtable-3level.h index b24903549d1c..759af70f9a0a 100644 --- a/trunk/arch/arm/include/asm/pgtable-3level.h +++ b/trunk/arch/arm/include/asm/pgtable-3level.h @@ -69,6 +69,8 @@ */ #define L_PTE_PRESENT (_AT(pteval_t, 3) << 0) /* Valid */ #define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */ +#define L_PTE_BUFFERABLE (_AT(pteval_t, 1) << 2) /* AttrIndx[0] */ +#define L_PTE_CACHEABLE (_AT(pteval_t, 1) << 3) /* AttrIndx[1] */ #define L_PTE_USER (_AT(pteval_t, 1) << 6) /* AP[1] */ #define L_PTE_RDONLY (_AT(pteval_t, 1) << 7) /* AP[2] */ #define L_PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ diff --git a/trunk/arch/arm/include/asm/processor.h b/trunk/arch/arm/include/asm/processor.h index d7038fa22343..5ac8d3d3e025 100644 --- a/trunk/arch/arm/include/asm/processor.h +++ b/trunk/arch/arm/include/asm/processor.h @@ -88,6 +88,8 @@ unsigned long get_wchan(struct task_struct *p); #define cpu_relax() barrier() #endif +void cpu_idle_wait(void); + /* * Create a new kernel thread */ diff --git a/trunk/arch/arm/include/asm/ptrace.h b/trunk/arch/arm/include/asm/ptrace.h index 355ece523f41..451808ba1211 100644 --- a/trunk/arch/arm/include/asm/ptrace.h +++ b/trunk/arch/arm/include/asm/ptrace.h @@ -249,11 +249,6 @@ static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) return regs->ARM_sp; } -static inline unsigned long user_stack_pointer(struct pt_regs *regs) -{ - return regs->ARM_sp; -} - #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ diff --git a/trunk/arch/arm/include/asm/syscall.h b/trunk/arch/arm/include/asm/syscall.h deleted file mode 100644 index c334a23ddf75..000000000000 --- a/trunk/arch/arm/include/asm/syscall.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Access to user system call parameters and results - * - * See asm-generic/syscall.h for descriptions of what we must do here. - */ - -#ifndef _ASM_ARM_SYSCALL_H -#define _ASM_ARM_SYSCALL_H - -#include - -extern const unsigned long sys_call_table[]; - -static inline int syscall_get_nr(struct task_struct *task, - struct pt_regs *regs) -{ - return task_thread_info(task)->syscall; -} - -static inline void syscall_rollback(struct task_struct *task, - struct pt_regs *regs) -{ - regs->ARM_r0 = regs->ARM_ORIG_r0; -} - -static inline long syscall_get_error(struct task_struct *task, - struct pt_regs *regs) -{ - unsigned long error = regs->ARM_r0; - return IS_ERR_VALUE(error) ? error : 0; -} - -static inline long syscall_get_return_value(struct task_struct *task, - struct pt_regs *regs) -{ - return regs->ARM_r0; -} - -static inline void syscall_set_return_value(struct task_struct *task, - struct pt_regs *regs, - int error, long val) -{ - regs->ARM_r0 = (long) error ? error : val; -} - -#define SYSCALL_MAX_ARGS 7 - -static inline void syscall_get_arguments(struct task_struct *task, - struct pt_regs *regs, - unsigned int i, unsigned int n, - unsigned long *args) -{ - if (i + n > SYSCALL_MAX_ARGS) { - unsigned long *args_bad = args + SYSCALL_MAX_ARGS - i; - unsigned int n_bad = n + i - SYSCALL_MAX_ARGS; - pr_warning("%s called with max args %d, handling only %d\n", - __func__, i + n, SYSCALL_MAX_ARGS); - memset(args_bad, 0, n_bad * sizeof(args[0])); - n = SYSCALL_MAX_ARGS - i; - } - - if (i == 0) { - args[0] = regs->ARM_ORIG_r0; - args++; - i++; - n--; - } - - memcpy(args, ®s->ARM_r0 + i, n * sizeof(args[0])); -} - -static inline void syscall_set_arguments(struct task_struct *task, - struct pt_regs *regs, - unsigned int i, unsigned int n, - const unsigned long *args) -{ - if (i + n > SYSCALL_MAX_ARGS) { - pr_warning("%s called with max args %d, handling only %d\n", - __func__, i + n, SYSCALL_MAX_ARGS); - n = SYSCALL_MAX_ARGS - i; - } - - if (i == 0) { - regs->ARM_ORIG_r0 = args[0]; - args++; - i++; - n--; - } - - memcpy(®s->ARM_r0 + i, args, n * sizeof(args[0])); -} - -#endif /* _ASM_ARM_SYSCALL_H */ diff --git a/trunk/arch/arm/include/asm/thread_info.h b/trunk/arch/arm/include/asm/thread_info.h index 68388eb4946b..0f04d84582e1 100644 --- a/trunk/arch/arm/include/asm/thread_info.h +++ b/trunk/arch/arm/include/asm/thread_info.h @@ -153,7 +153,6 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_RESTORE_SIGMASK 20 #define TIF_SECCOMP 21 -#define TIF_SWITCH_MM 22 /* deferred switch_mm */ #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) diff --git a/trunk/arch/arm/include/asm/tlbflush.h b/trunk/arch/arm/include/asm/tlbflush.h index 6e924d3a77eb..85fe61e73202 100644 --- a/trunk/arch/arm/include/asm/tlbflush.h +++ b/trunk/arch/arm/include/asm/tlbflush.h @@ -65,6 +65,21 @@ #define MULTI_TLB 1 #endif +#define v3_tlb_flags (TLB_V3_FULL | TLB_V3_PAGE) + +#ifdef CONFIG_CPU_TLB_V3 +# define v3_possible_flags v3_tlb_flags +# define v3_always_flags v3_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v3 +# endif +#else +# define v3_possible_flags 0 +# define v3_always_flags (-1UL) +#endif + #define v4_tlb_flags (TLB_V4_U_FULL | TLB_V4_U_PAGE) #ifdef CONFIG_CPU_TLB_V4WT @@ -283,7 +298,8 @@ extern struct cpu_tlb_fns cpu_tlb; * implemented the "%?" method, but this has been discontinued due to too * many people getting it wrong. */ -#define possible_tlb_flags (v4_possible_flags | \ +#define possible_tlb_flags (v3_possible_flags | \ + v4_possible_flags | \ v4wbi_possible_flags | \ fr_possible_flags | \ v4wb_possible_flags | \ @@ -291,7 +307,8 @@ extern struct cpu_tlb_fns cpu_tlb; v6wbi_possible_flags | \ v7wbi_possible_flags) -#define always_tlb_flags (v4_always_flags & \ +#define always_tlb_flags (v3_always_flags & \ + v4_always_flags & \ v4wbi_always_flags & \ fr_always_flags & \ v4wb_always_flags & \ diff --git a/trunk/arch/arm/kernel/Makefile b/trunk/arch/arm/kernel/Makefile index 7ad2d5cf7008..7b787d642af4 100644 --- a/trunk/arch/arm/kernel/Makefile +++ b/trunk/arch/arm/kernel/Makefile @@ -34,7 +34,6 @@ obj-$(CONFIG_ARM_CPU_SUSPEND) += sleep.o suspend.o obj-$(CONFIG_SMP) += smp.o smp_tlb.o obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o -obj-$(CONFIG_ARM_ARCH_TIMER) += arch_timer.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o @@ -82,4 +81,4 @@ head-y := head$(MMUEXT).o obj-$(CONFIG_DEBUG_LL) += debug.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o -extra-y := $(head-y) vmlinux.lds +extra-y := $(head-y) init_task.o vmlinux.lds diff --git a/trunk/arch/arm/kernel/arch_timer.c b/trunk/arch/arm/kernel/arch_timer.c deleted file mode 100644 index dd58035621f7..000000000000 --- a/trunk/arch/arm/kernel/arch_timer.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * linux/arch/arm/kernel/arch_timer.c - * - * Copyright (C) 2011 ARM Ltd. - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -static unsigned long arch_timer_rate; -static int arch_timer_ppi; -static int arch_timer_ppi2; - -static struct clock_event_device __percpu **arch_timer_evt; - -/* - * Architected system timer support. - */ - -#define ARCH_TIMER_CTRL_ENABLE (1 << 0) -#define ARCH_TIMER_CTRL_IT_MASK (1 << 1) -#define ARCH_TIMER_CTRL_IT_STAT (1 << 2) - -#define ARCH_TIMER_REG_CTRL 0 -#define ARCH_TIMER_REG_FREQ 1 -#define ARCH_TIMER_REG_TVAL 2 - -static void arch_timer_reg_write(int reg, u32 val) -{ - switch (reg) { - case ARCH_TIMER_REG_CTRL: - asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val)); - break; - case ARCH_TIMER_REG_TVAL: - asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val)); - break; - } - - isb(); -} - -static u32 arch_timer_reg_read(int reg) -{ - u32 val; - - switch (reg) { - case ARCH_TIMER_REG_CTRL: - asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val)); - break; - case ARCH_TIMER_REG_FREQ: - asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val)); - break; - case ARCH_TIMER_REG_TVAL: - asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val)); - break; - default: - BUG(); - } - - return val; -} - -static irqreturn_t arch_timer_handler(int irq, void *dev_id) -{ - struct clock_event_device *evt = *(struct clock_event_device **)dev_id; - unsigned long ctrl; - - ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL); - if (ctrl & ARCH_TIMER_CTRL_IT_STAT) { - ctrl |= ARCH_TIMER_CTRL_IT_MASK; - arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl); - evt->event_handler(evt); - return IRQ_HANDLED; - } - - return IRQ_NONE; -} - -static void arch_timer_disable(void) -{ - unsigned long ctrl; - - ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL); - ctrl &= ~ARCH_TIMER_CTRL_ENABLE; - arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl); -} - -static void arch_timer_set_mode(enum clock_event_mode mode, - struct clock_event_device *clk) -{ - switch (mode) { - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - arch_timer_disable(); - break; - default: - break; - } -} - -static int arch_timer_set_next_event(unsigned long evt, - struct clock_event_device *unused) -{ - unsigned long ctrl; - - ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL); - ctrl |= ARCH_TIMER_CTRL_ENABLE; - ctrl &= ~ARCH_TIMER_CTRL_IT_MASK; - - arch_timer_reg_write(ARCH_TIMER_REG_TVAL, evt); - arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl); - - return 0; -} - -static int __cpuinit arch_timer_setup(struct clock_event_device *clk) -{ - /* Be safe... */ - arch_timer_disable(); - - clk->features = CLOCK_EVT_FEAT_ONESHOT; - clk->name = "arch_sys_timer"; - clk->rating = 450; - clk->set_mode = arch_timer_set_mode; - clk->set_next_event = arch_timer_set_next_event; - clk->irq = arch_timer_ppi; - - clockevents_config_and_register(clk, arch_timer_rate, - 0xf, 0x7fffffff); - - *__this_cpu_ptr(arch_timer_evt) = clk; - - enable_percpu_irq(clk->irq, 0); - if (arch_timer_ppi2) - enable_percpu_irq(arch_timer_ppi2, 0); - - return 0; -} - -/* Is the optional system timer available? */ -static int local_timer_is_architected(void) -{ - return (cpu_architecture() >= CPU_ARCH_ARMv7) && - ((read_cpuid_ext(CPUID_EXT_PFR1) >> 16) & 0xf) == 1; -} - -static int arch_timer_available(void) -{ - unsigned long freq; - - if (!local_timer_is_architected()) - return -ENXIO; - - if (arch_timer_rate == 0) { - arch_timer_reg_write(ARCH_TIMER_REG_CTRL, 0); - freq = arch_timer_reg_read(ARCH_TIMER_REG_FREQ); - - /* Check the timer frequency. */ - if (freq == 0) { - pr_warn("Architected timer frequency not available\n"); - return -EINVAL; - } - - arch_timer_rate = freq; - } - - pr_info_once("Architected local timer running at %lu.%02luMHz.\n", - arch_timer_rate / 1000000, (arch_timer_rate / 10000) % 100); - return 0; -} - -static inline cycle_t arch_counter_get_cntpct(void) -{ - u32 cvall, cvalh; - - asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (cvall), "=r" (cvalh)); - - return ((cycle_t) cvalh << 32) | cvall; -} - -static inline cycle_t arch_counter_get_cntvct(void) -{ - u32 cvall, cvalh; - - asm volatile("mrrc p15, 1, %0, %1, c14" : "=r" (cvall), "=r" (cvalh)); - - return ((cycle_t) cvalh << 32) | cvall; -} - -static u32 notrace arch_counter_get_cntvct32(void) -{ - cycle_t cntvct = arch_counter_get_cntvct(); - - /* - * The sched_clock infrastructure only knows about counters - * with at most 32bits. Forget about the upper 24 bits for the - * time being... - */ - return (u32)(cntvct & (u32)~0); -} - -static cycle_t arch_counter_read(struct clocksource *cs) -{ - return arch_counter_get_cntpct(); -} - -static struct clocksource clocksource_counter = { - .name = "arch_sys_counter", - .rating = 400, - .read = arch_counter_read, - .mask = CLOCKSOURCE_MASK(56), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static void __cpuinit arch_timer_stop(struct clock_event_device *clk) -{ - pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n", - clk->irq, smp_processor_id()); - disable_percpu_irq(clk->irq); - if (arch_timer_ppi2) - disable_percpu_irq(arch_timer_ppi2); - arch_timer_set_mode(CLOCK_EVT_MODE_UNUSED, clk); -} - -static struct local_timer_ops arch_timer_ops __cpuinitdata = { - .setup = arch_timer_setup, - .stop = arch_timer_stop, -}; - -static struct clock_event_device arch_timer_global_evt; - -static int __init arch_timer_register(void) -{ - int err; - - err = arch_timer_available(); - if (err) - return err; - - arch_timer_evt = alloc_percpu(struct clock_event_device *); - if (!arch_timer_evt) - return -ENOMEM; - - clocksource_register_hz(&clocksource_counter, arch_timer_rate); - - err = request_percpu_irq(arch_timer_ppi, arch_timer_handler, - "arch_timer", arch_timer_evt); - if (err) { - pr_err("arch_timer: can't register interrupt %d (%d)\n", - arch_timer_ppi, err); - goto out_free; - } - - if (arch_timer_ppi2) { - err = request_percpu_irq(arch_timer_ppi2, arch_timer_handler, - "arch_timer", arch_timer_evt); - if (err) { - pr_err("arch_timer: can't register interrupt %d (%d)\n", - arch_timer_ppi2, err); - arch_timer_ppi2 = 0; - goto out_free_irq; - } - } - - err = local_timer_register(&arch_timer_ops); - if (err) { - /* - * We couldn't register as a local timer (could be - * because we're on a UP platform, or because some - * other local timer is already present...). Try as a - * global timer instead. - */ - arch_timer_global_evt.cpumask = cpumask_of(0); - err = arch_timer_setup(&arch_timer_global_evt); - } - - if (err) - goto out_free_irq; - - return 0; - -out_free_irq: - free_percpu_irq(arch_timer_ppi, arch_timer_evt); - if (arch_timer_ppi2) - free_percpu_irq(arch_timer_ppi2, arch_timer_evt); - -out_free: - free_percpu(arch_timer_evt); - - return err; -} - -static const struct of_device_id arch_timer_of_match[] __initconst = { - { .compatible = "arm,armv7-timer", }, - {}, -}; - -int __init arch_timer_of_register(void) -{ - struct device_node *np; - u32 freq; - - np = of_find_matching_node(NULL, arch_timer_of_match); - if (!np) { - pr_err("arch_timer: can't find DT node\n"); - return -ENODEV; - } - - /* Try to determine the frequency from the device tree or CNTFRQ */ - if (!of_property_read_u32(np, "clock-frequency", &freq)) - arch_timer_rate = freq; - - arch_timer_ppi = irq_of_parse_and_map(np, 0); - arch_timer_ppi2 = irq_of_parse_and_map(np, 1); - pr_info("arch_timer: found %s irqs %d %d\n", - np->name, arch_timer_ppi, arch_timer_ppi2); - - return arch_timer_register(); -} - -int __init arch_timer_sched_clock_init(void) -{ - int err; - - err = arch_timer_available(); - if (err) - return err; - - setup_sched_clock(arch_counter_get_cntvct32, 32, arch_timer_rate); - return 0; -} diff --git a/trunk/arch/arm/kernel/bios32.c b/trunk/arch/arm/kernel/bios32.c index 25552508c3fd..ede5f7741c42 100644 --- a/trunk/arch/arm/kernel/bios32.c +++ b/trunk/arch/arm/kernel/bios32.c @@ -374,29 +374,16 @@ EXPORT_SYMBOL(pcibios_fixup_bus); #endif /* - * Swizzle the device pin each time we cross a bridge. If a platform does - * not provide a swizzle function, we perform the standard PCI swizzling. - * - * The default swizzling walks up the bus tree one level at a time, applying - * the standard swizzle function at each step, stopping when it finds the PCI - * root bus. This will return the slot number of the bridge device on the - * root bus and the interrupt pin on that device which should correspond - * with the downstream device interrupt. - * - * Platforms may override this, in which case the slot and pin returned - * depend entirely on the platform code. However, please note that the - * PCI standard swizzle is implemented on plug-in cards and Cardbus based - * PCI extenders, so it can not be ignored. + * Swizzle the device pin each time we cross a bridge. + * This might update pin and returns the slot number. */ static u8 __devinit pcibios_swizzle(struct pci_dev *dev, u8 *pin) { struct pci_sys_data *sys = dev->sysdata; - int slot, oldpin = *pin; + int slot = 0, oldpin = *pin; if (sys->swizzle) slot = sys->swizzle(dev, pin); - else - slot = pci_common_swizzle(dev, pin); if (debug_pci) printk("PCI: %s swizzling pin %d => pin %d slot %d\n", @@ -423,7 +410,7 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) return irq; } -static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head) +static void __init pcibios_init_hw(struct hw_pci *hw) { struct pci_sys_data *sys = NULL; int ret; @@ -437,6 +424,7 @@ static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head) #ifdef CONFIG_PCI_DOMAINS sys->domain = hw->domain; #endif + sys->hw = hw; sys->busnr = busnr; sys->swizzle = hw->swizzle; sys->map_irq = hw->map_irq; @@ -452,18 +440,14 @@ static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head) &iomem_resource, sys->mem_offset); } - if (hw->scan) - sys->bus = hw->scan(nr, sys); - else - sys->bus = pci_scan_root_bus(NULL, sys->busnr, - hw->ops, sys, &sys->resources); + sys->bus = hw->scan(nr, sys); if (!sys->bus) panic("PCI: unable to scan bus!"); busnr = sys->bus->subordinate + 1; - list_add(&sys->node, head); + list_add(&sys->node, &hw->buses); } else { kfree(sys); if (ret < 0) @@ -475,18 +459,19 @@ static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head) void __init pci_common_init(struct hw_pci *hw) { struct pci_sys_data *sys; - LIST_HEAD(head); + + INIT_LIST_HEAD(&hw->buses); pci_add_flags(PCI_REASSIGN_ALL_RSRC); if (hw->preinit) hw->preinit(); - pcibios_init_hw(hw, &head); + pcibios_init_hw(hw); if (hw->postinit) hw->postinit(); pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq); - list_for_each_entry(sys, &head, node) { + list_for_each_entry(sys, &hw->buses, node) { struct pci_bus *bus = sys->bus; if (!pci_has_flag(PCI_PROBE_ONLY)) { diff --git a/trunk/arch/arm/kernel/entry-armv.S b/trunk/arch/arm/kernel/entry-armv.S index 437f0c426517..7fd3ad048da9 100644 --- a/trunk/arch/arm/kernel/entry-armv.S +++ b/trunk/arch/arm/kernel/entry-armv.S @@ -556,6 +556,10 @@ call_fpe: #endif tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 tstne r0, #0x04000000 @ bit 26 set on both ARM and Thumb-2 +#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710) + and r8, r0, #0x0f000000 @ mask out op-code bits + teqne r8, #0x0f000000 @ SWI (ARM6/7 bug)? +#endif moveq pc, lr get_thread_info r10 @ get current thread and r8, r0, #0x00000f00 @ mask out CP number diff --git a/trunk/arch/arm/kernel/entry-common.S b/trunk/arch/arm/kernel/entry-common.S index 7bd2d3cb8957..54ee265dd819 100644 --- a/trunk/arch/arm/kernel/entry-common.S +++ b/trunk/arch/arm/kernel/entry-common.S @@ -335,6 +335,20 @@ ENDPROC(ftrace_stub) *----------------------------------------------------------------------------- */ + /* If we're optimising for StrongARM the resulting code won't + run on an ARM7 and we can save a couple of instructions. + --pb */ +#ifdef CONFIG_CPU_ARM710 +#define A710(code...) code +.Larm710bug: + ldmia sp, {r0 - lr}^ @ Get calling r0 - lr + mov r0, r0 + add sp, sp, #S_FRAME_SIZE + subs pc, lr, #4 +#else +#define A710(code...) +#endif + .align 5 ENTRY(vector_swi) sub sp, sp, #S_FRAME_SIZE @@ -365,6 +379,9 @@ ENTRY(vector_swi) ldreq r10, [lr, #-4] @ get SWI instruction #else ldr r10, [lr, #-4] @ get SWI instruction + A710( and ip, r10, #0x0f000000 @ check for SWI ) + A710( teq ip, #0x0f000000 ) + A710( bne .Larm710bug ) #endif #ifdef CONFIG_CPU_ENDIAN_BE8 rev r10, r10 @ little endian instruction @@ -375,15 +392,26 @@ ENTRY(vector_swi) /* * Pure EABI user space always put syscall number into scno (r7). */ + A710( ldr ip, [lr, #-4] @ get SWI instruction ) + A710( and ip, ip, #0x0f000000 @ check for SWI ) + A710( teq ip, #0x0f000000 ) + A710( bne .Larm710bug ) + #elif defined(CONFIG_ARM_THUMB) + /* Legacy ABI only, possibly thumb mode. */ tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in ldreq scno, [lr, #-4] #else + /* Legacy ABI only. */ ldr scno, [lr, #-4] @ get SWI instruction + A710( and ip, scno, #0x0f000000 @ check for SWI ) + A710( teq ip, #0x0f000000 ) + A710( bne .Larm710bug ) + #endif #ifdef CONFIG_ALIGNMENT_TRAP diff --git a/trunk/arch/arm/kernel/head.S b/trunk/arch/arm/kernel/head.S index 835898e7d704..3bf0c7f8b043 100644 --- a/trunk/arch/arm/kernel/head.S +++ b/trunk/arch/arm/kernel/head.S @@ -277,6 +277,10 @@ __create_page_tables: mov r3, r3, lsl #PMD_ORDER add r0, r4, r3 + rsb r3, r3, #0x4000 @ PTRS_PER_PGD*sizeof(long) + cmp r3, #0x0800 @ limit to 512MB + movhi r3, #0x0800 + add r6, r0, r3 mov r3, r7, lsr #SECTION_SHIFT ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags orr r3, r7, r3, lsl #SECTION_SHIFT @@ -285,10 +289,13 @@ __create_page_tables: #else orr r3, r3, #PMD_SECT_XN #endif - str r3, [r0], #4 +1: str r3, [r0], #4 #ifdef CONFIG_ARM_LPAE str r7, [r0], #4 #endif + add r3, r3, #1 << SECTION_SHIFT + cmp r0, r6 + blo 1b #else /* CONFIG_DEBUG_ICEDCC || CONFIG_DEBUG_SEMIHOSTING */ /* we don't need any serial debugging mappings */ diff --git a/trunk/arch/arm/kernel/init_task.c b/trunk/arch/arm/kernel/init_task.c new file mode 100644 index 000000000000..e7cbb50dc356 --- /dev/null +++ b/trunk/arch/arm/kernel/init_task.c @@ -0,0 +1,37 @@ +/* + * linux/arch/arm/kernel/init_task.c + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +/* + * Initial thread structure. + * + * We need to make sure that this is 8192-byte aligned due to the + * way process stacks are handled. This is done by making sure + * the linker maps this in the .text segment right after head.S, + * and making head.S ensure the proper alignment. + * + * The things we do for performance.. + */ +union thread_union init_thread_union __init_task_data = + { INIT_THREAD_INFO(init_task) }; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); + +EXPORT_SYMBOL(init_task); diff --git a/trunk/arch/arm/kernel/process.c b/trunk/arch/arm/kernel/process.c index 19c95ea65b2f..2b7b017a20cd 100644 --- a/trunk/arch/arm/kernel/process.c +++ b/trunk/arch/arm/kernel/process.c @@ -157,6 +157,26 @@ EXPORT_SYMBOL(pm_power_off); void (*arm_pm_restart)(char str, const char *cmd) = null_restart; EXPORT_SYMBOL_GPL(arm_pm_restart); +static void do_nothing(void *unused) +{ +} + +/* + * cpu_idle_wait - Used to ensure that all the CPUs discard old value of + * pm_idle and update to new pm_idle value. Required while changing pm_idle + * handler on SMP systems. + * + * Caller must have changed pm_idle to the new value before the call. Old + * pm_idle value will not be used by any CPU after the return of this function. + */ +void cpu_idle_wait(void) +{ + smp_mb(); + /* kick all the CPUs so that they exit out of pm_idle */ + smp_call_function(do_nothing, NULL, 1); +} +EXPORT_SYMBOL_GPL(cpu_idle_wait); + /* * This is our default idle handler. */ diff --git a/trunk/arch/arm/kernel/ptrace.c b/trunk/arch/arm/kernel/ptrace.c index 14e38261cd31..80abafb9bf33 100644 --- a/trunk/arch/arm/kernel/ptrace.c +++ b/trunk/arch/arm/kernel/ptrace.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -907,33 +906,49 @@ long arch_ptrace(struct task_struct *child, long request, return ret; } +#ifdef __ARMEB__ +#define AUDIT_ARCH_NR AUDIT_ARCH_ARMEB +#else +#define AUDIT_ARCH_NR AUDIT_ARCH_ARM +#endif + asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) { unsigned long ip; - if (why) + /* + * Save IP. IP is used to denote syscall entry/exit: + * IP = 0 -> entry, = 1 -> exit + */ + ip = regs->ARM_ip; + regs->ARM_ip = why; + + if (!ip) audit_syscall_exit(regs); else - audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, + audit_syscall_entry(AUDIT_ARCH_NR, scno, regs->ARM_r0, regs->ARM_r1, regs->ARM_r2, regs->ARM_r3); if (!test_thread_flag(TIF_SYSCALL_TRACE)) return scno; + if (!(current->ptrace & PT_PTRACED)) + return scno; current_thread_info()->syscall = scno; + /* the 0x80 provides a way for the tracing parent to distinguish + between a syscall stop and SIGTRAP delivery */ + ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) + ? 0x80 : 0)); /* - * IP is used to denote syscall entry/exit: - * IP = 0 -> entry, =1 -> exit + * this isn't the same as continuing with a signal, but it will do + * for normal use. strace only continues with a signal if the + * stopping signal is not SIGTRAP. -brl */ - ip = regs->ARM_ip; - regs->ARM_ip = why; - - if (why) - tracehook_report_syscall_exit(regs, 0); - else if (tracehook_report_syscall_entry(regs)) - current_thread_info()->syscall = -1; - + if (current->exit_code) { + send_sig(current->exit_code, current, 1); + current->exit_code = 0; + } regs->ARM_ip = ip; return current_thread_info()->syscall; diff --git a/trunk/arch/arm/kernel/signal.c b/trunk/arch/arm/kernel/signal.c index 73d9a420850d..d68d1b694680 100644 --- a/trunk/arch/arm/kernel/signal.c +++ b/trunk/arch/arm/kernel/signal.c @@ -589,8 +589,6 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, */ block_sigmask(ka, sig); - tracehook_signal_handler(sig, info, ka, regs, 0); - return 0; } diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c index b735521a4a54..f6a4d32b0421 100644 --- a/trunk/arch/arm/kernel/smp.c +++ b/trunk/arch/arm/kernel/smp.c @@ -60,10 +60,31 @@ enum ipi_msg_type { static DECLARE_COMPLETION(cpu_running); -int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle) +int __cpuinit __cpu_up(unsigned int cpu) { + struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu); + struct task_struct *idle = ci->idle; int ret; + /* + * Spawn a new process manually, if not already done. + * Grab a pointer to its task struct so we can mess with it + */ + if (!idle) { + idle = fork_idle(cpu); + if (IS_ERR(idle)) { + printk(KERN_ERR "CPU%u: fork() failed\n", cpu); + return PTR_ERR(idle); + } + ci->idle = idle; + } else { + /* + * Since this idle thread is being re-used, call + * init_idle() to reinitialize the thread structure. + */ + init_idle(idle, cpu); + } + /* * We need to tell the secondary core where to find * its stack and the page tables. @@ -230,6 +251,8 @@ asmlinkage void __cpuinit secondary_start_kernel(void) struct mm_struct *mm = &init_mm; unsigned int cpu = smp_processor_id(); + printk("CPU%u: Booted secondary processor\n", cpu); + /* * All kernel threads share the same mm context; grab a * reference and switch to it. @@ -241,8 +264,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void) enter_lazy_tlb(mm, current); local_flush_tlb_all(); - printk("CPU%u: Booted secondary processor\n", cpu); - cpu_init(); preempt_disable(); trace_hardirqs_off(); @@ -297,6 +318,9 @@ void __init smp_cpus_done(unsigned int max_cpus) void __init smp_prepare_boot_cpu(void) { + unsigned int cpu = smp_processor_id(); + + per_cpu(cpu_data, cpu).idle = current; } void __init smp_prepare_cpus(unsigned int max_cpus) @@ -430,9 +454,6 @@ static struct local_timer_ops *lt_ops; #ifdef CONFIG_LOCAL_TIMERS int local_timer_register(struct local_timer_ops *ops) { - if (!is_smp() || !setup_max_cpus) - return -ENXIO; - if (lt_ops) return -EBUSY; diff --git a/trunk/arch/arm/kernel/smp_scu.c b/trunk/arch/arm/kernel/smp_scu.c index b9f015e843d8..8f5dd7963356 100644 --- a/trunk/arch/arm/kernel/smp_scu.c +++ b/trunk/arch/arm/kernel/smp_scu.c @@ -11,7 +11,6 @@ #include #include -#include #include #include #include @@ -75,7 +74,7 @@ void scu_enable(void __iomem *scu_base) int scu_power_mode(void __iomem *scu_base, unsigned int mode) { unsigned int val; - int cpu = cpu_logical_map(smp_processor_id()); + int cpu = smp_processor_id(); if (mode > 3 || mode == 1 || cpu > 3) return -EINVAL; diff --git a/trunk/arch/arm/kernel/sys_arm.c b/trunk/arch/arm/kernel/sys_arm.c index 76cbb055dd05..d2b177905cdb 100644 --- a/trunk/arch/arm/kernel/sys_arm.c +++ b/trunk/arch/arm/kernel/sys_arm.c @@ -115,7 +115,7 @@ int kernel_execve(const char *filename, "Ir" (THREAD_START_SP - sizeof(regs)), "r" (®s), "Ir" (sizeof(regs)) - : "r0", "r1", "r2", "r3", "r8", "r9", "ip", "lr", "memory"); + : "r0", "r1", "r2", "r3", "ip", "lr", "memory"); out: return ret; diff --git a/trunk/arch/arm/kernel/thumbee.c b/trunk/arch/arm/kernel/thumbee.c index 7b8403b76666..aab899764053 100644 --- a/trunk/arch/arm/kernel/thumbee.c +++ b/trunk/arch/arm/kernel/thumbee.c @@ -20,7 +20,6 @@ #include #include -#include #include #include @@ -68,7 +67,8 @@ static int __init thumbee_init(void) if (cpu_arch < CPU_ARCH_ARMv7) return 0; - pfr0 = read_cpuid_ext(CPUID_EXT_PFR0); + /* processor feature register 0 */ + asm("mrc p15, 0, %0, c0, c1, 0\n" : "=r" (pfr0)); if ((pfr0 & 0x0000f000) != 0x00001000) return 0; diff --git a/trunk/arch/arm/kernel/time.c b/trunk/arch/arm/kernel/time.c index af2afb019672..fe31b22f18fd 100644 --- a/trunk/arch/arm/kernel/time.c +++ b/trunk/arch/arm/kernel/time.c @@ -110,42 +110,6 @@ void timer_tick(void) } #endif -static void dummy_clock_access(struct timespec *ts) -{ - ts->tv_sec = 0; - ts->tv_nsec = 0; -} - -static clock_access_fn __read_persistent_clock = dummy_clock_access; -static clock_access_fn __read_boot_clock = dummy_clock_access;; - -void read_persistent_clock(struct timespec *ts) -{ - __read_persistent_clock(ts); -} - -void read_boot_clock(struct timespec *ts) -{ - __read_boot_clock(ts); -} - -int __init register_persistent_clock(clock_access_fn read_boot, - clock_access_fn read_persistent) -{ - /* Only allow the clockaccess functions to be registered once */ - if (__read_persistent_clock == dummy_clock_access && - __read_boot_clock == dummy_clock_access) { - if (read_boot) - __read_boot_clock = read_boot; - if (read_persistent) - __read_persistent_clock = read_persistent; - - return 0; - } - - return -EINVAL; -} - #if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS) static int timer_suspend(void) { diff --git a/trunk/arch/arm/kernel/traps.c b/trunk/arch/arm/kernel/traps.c index 3647170e9a16..778454750a6c 100644 --- a/trunk/arch/arm/kernel/traps.c +++ b/trunk/arch/arm/kernel/traps.c @@ -479,14 +479,14 @@ static int bad_syscall(int n, struct pt_regs *regs) return regs->ARM_r0; } -static inline int +static inline void do_cache_op(unsigned long start, unsigned long end, int flags) { struct mm_struct *mm = current->active_mm; struct vm_area_struct *vma; if (end < start || flags) - return -EINVAL; + return; down_read(&mm->mmap_sem); vma = find_vma(mm, start); @@ -496,11 +496,9 @@ do_cache_op(unsigned long start, unsigned long end, int flags) if (end > vma->vm_end) end = vma->vm_end; - up_read(&mm->mmap_sem); - return flush_cache_user_range(start, end); + flush_cache_user_range(vma, start, end); } up_read(&mm->mmap_sem); - return -EINVAL; } /* @@ -546,7 +544,8 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) * the specified region). */ case NR(cacheflush): - return do_cache_op(regs->ARM_r0, regs->ARM_r1, regs->ARM_r2); + do_cache_op(regs->ARM_r0, regs->ARM_r1, regs->ARM_r2); + return 0; case NR(usr26): if (!(elf_hwcap & HWCAP_26BIT)) diff --git a/trunk/arch/arm/lib/Makefile b/trunk/arch/arm/lib/Makefile index 992769ae2599..0ade0acc1ed9 100644 --- a/trunk/arch/arm/lib/Makefile +++ b/trunk/arch/arm/lib/Makefile @@ -17,13 +17,30 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ call_with_stack.o mmu-y := clear_user.o copy_page.o getuser.o putuser.o -mmu-y += copy_from_user.o copy_to_user.o + +# the code in uaccess.S is not preemption safe and +# probably faster on ARMv3 only +ifeq ($(CONFIG_PREEMPT),y) + mmu-y += copy_from_user.o copy_to_user.o +else +ifneq ($(CONFIG_CPU_32v3),y) + mmu-y += copy_from_user.o copy_to_user.o +else + mmu-y += uaccess.o +endif +endif # using lib_ here won't override already available weak symbols obj-$(CONFIG_UACCESS_WITH_MEMCPY) += uaccess_with_memcpy.o -lib-$(CONFIG_MMU) += $(mmu-y) -lib-y += io-readsw-armv4.o io-writesw-armv4.o +lib-$(CONFIG_MMU) += $(mmu-y) + +ifeq ($(CONFIG_CPU_32v3),y) + lib-y += io-readsw-armv3.o io-writesw-armv3.o +else + lib-y += io-readsw-armv4.o io-writesw-armv4.o +endif + lib-$(CONFIG_ARCH_RPC) += ecard.o io-acorn.o floppydma.o lib-$(CONFIG_ARCH_SHARK) += io-shark.o diff --git a/trunk/arch/arm/lib/io-readsw-armv3.S b/trunk/arch/arm/lib/io-readsw-armv3.S new file mode 100644 index 000000000000..88487c8c4f23 --- /dev/null +++ b/trunk/arch/arm/lib/io-readsw-armv3.S @@ -0,0 +1,106 @@ +/* + * linux/arch/arm/lib/io-readsw-armv3.S + * + * Copyright (C) 1995-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include + +.Linsw_bad_alignment: + adr r0, .Linsw_bad_align_msg + mov r2, lr + b panic +.Linsw_bad_align_msg: + .asciz "insw: bad buffer alignment (0x%p, lr=0x%08lX)\n" + .align + +.Linsw_align: tst r1, #1 + bne .Linsw_bad_alignment + + ldr r3, [r0] + strb r3, [r1], #1 + mov r3, r3, lsr #8 + strb r3, [r1], #1 + + subs r2, r2, #1 + moveq pc, lr + +ENTRY(__raw_readsw) + teq r2, #0 @ do we have to check for the zero len? + moveq pc, lr + tst r1, #3 + bne .Linsw_align + +.Linsw_aligned: mov ip, #0xff + orr ip, ip, ip, lsl #8 + stmfd sp!, {r4, r5, r6, lr} + + subs r2, r2, #8 + bmi .Lno_insw_8 + +.Linsw_8_lp: ldr r3, [r0] + and r3, r3, ip + ldr r4, [r0] + orr r3, r3, r4, lsl #16 + + ldr r4, [r0] + and r4, r4, ip + ldr r5, [r0] + orr r4, r4, r5, lsl #16 + + ldr r5, [r0] + and r5, r5, ip + ldr r6, [r0] + orr r5, r5, r6, lsl #16 + + ldr r6, [r0] + and r6, r6, ip + ldr lr, [r0] + orr r6, r6, lr, lsl #16 + + stmia r1!, {r3 - r6} + + subs r2, r2, #8 + bpl .Linsw_8_lp + + tst r2, #7 + ldmeqfd sp!, {r4, r5, r6, pc} + +.Lno_insw_8: tst r2, #4 + beq .Lno_insw_4 + + ldr r3, [r0] + and r3, r3, ip + ldr r4, [r0] + orr r3, r3, r4, lsl #16 + + ldr r4, [r0] + and r4, r4, ip + ldr r5, [r0] + orr r4, r4, r5, lsl #16 + + stmia r1!, {r3, r4} + +.Lno_insw_4: tst r2, #2 + beq .Lno_insw_2 + + ldr r3, [r0] + and r3, r3, ip + ldr r4, [r0] + orr r3, r3, r4, lsl #16 + + str r3, [r1], #4 + +.Lno_insw_2: tst r2, #1 + ldrne r3, [r0] + strneb r3, [r1], #1 + movne r3, r3, lsr #8 + strneb r3, [r1] + + ldmfd sp!, {r4, r5, r6, pc} + + diff --git a/trunk/arch/arm/lib/io-writesw-armv3.S b/trunk/arch/arm/lib/io-writesw-armv3.S new file mode 100644 index 000000000000..49b800419e32 --- /dev/null +++ b/trunk/arch/arm/lib/io-writesw-armv3.S @@ -0,0 +1,126 @@ +/* + * linux/arch/arm/lib/io-writesw-armv3.S + * + * Copyright (C) 1995-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include + +.Loutsw_bad_alignment: + adr r0, .Loutsw_bad_align_msg + mov r2, lr + b panic +.Loutsw_bad_align_msg: + .asciz "outsw: bad buffer alignment (0x%p, lr=0x%08lX)\n" + .align + +.Loutsw_align: tst r1, #1 + bne .Loutsw_bad_alignment + + add r1, r1, #2 + + ldr r3, [r1, #-4] + mov r3, r3, lsr #16 + orr r3, r3, r3, lsl #16 + str r3, [r0] + subs r2, r2, #1 + moveq pc, lr + +ENTRY(__raw_writesw) + teq r2, #0 @ do we have to check for the zero len? + moveq pc, lr + tst r1, #3 + bne .Loutsw_align + + stmfd sp!, {r4, r5, r6, lr} + + subs r2, r2, #8 + bmi .Lno_outsw_8 + +.Loutsw_8_lp: ldmia r1!, {r3, r4, r5, r6} + + mov ip, r3, lsl #16 + orr ip, ip, ip, lsr #16 + str ip, [r0] + + mov ip, r3, lsr #16 + orr ip, ip, ip, lsl #16 + str ip, [r0] + + mov ip, r4, lsl #16 + orr ip, ip, ip, lsr #16 + str ip, [r0] + + mov ip, r4, lsr #16 + orr ip, ip, ip, lsl #16 + str ip, [r0] + + mov ip, r5, lsl #16 + orr ip, ip, ip, lsr #16 + str ip, [r0] + + mov ip, r5, lsr #16 + orr ip, ip, ip, lsl #16 + str ip, [r0] + + mov ip, r6, lsl #16 + orr ip, ip, ip, lsr #16 + str ip, [r0] + + mov ip, r6, lsr #16 + orr ip, ip, ip, lsl #16 + str ip, [r0] + + subs r2, r2, #8 + bpl .Loutsw_8_lp + + tst r2, #7 + ldmeqfd sp!, {r4, r5, r6, pc} + +.Lno_outsw_8: tst r2, #4 + beq .Lno_outsw_4 + + ldmia r1!, {r3, r4} + + mov ip, r3, lsl #16 + orr ip, ip, ip, lsr #16 + str ip, [r0] + + mov ip, r3, lsr #16 + orr ip, ip, ip, lsl #16 + str ip, [r0] + + mov ip, r4, lsl #16 + orr ip, ip, ip, lsr #16 + str ip, [r0] + + mov ip, r4, lsr #16 + orr ip, ip, ip, lsl #16 + str ip, [r0] + +.Lno_outsw_4: tst r2, #2 + beq .Lno_outsw_2 + + ldr r3, [r1], #4 + + mov ip, r3, lsl #16 + orr ip, ip, ip, lsr #16 + str ip, [r0] + + mov ip, r3, lsr #16 + orr ip, ip, ip, lsl #16 + str ip, [r0] + +.Lno_outsw_2: tst r2, #1 + + ldrne r3, [r1] + + movne ip, r3, lsl #16 + orrne ip, ip, ip, lsr #16 + strne ip, [r0] + + ldmfd sp!, {r4, r5, r6, pc} diff --git a/trunk/arch/arm/lib/uaccess.S b/trunk/arch/arm/lib/uaccess.S new file mode 100644 index 000000000000..5c908b1cb8ed --- /dev/null +++ b/trunk/arch/arm/lib/uaccess.S @@ -0,0 +1,564 @@ +/* + * linux/arch/arm/lib/uaccess.S + * + * Copyright (C) 1995, 1996,1997,1998 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Routines to block copy data to/from user memory + * These are highly optimised both for the 4k page size + * and for various alignments. + */ +#include +#include +#include +#include + + .text + +#define PAGE_SHIFT 12 + +/* Prototype: int __copy_to_user(void *to, const char *from, size_t n) + * Purpose : copy a block to user memory from kernel memory + * Params : to - user memory + * : from - kernel memory + * : n - number of bytes to copy + * Returns : Number of bytes NOT copied. + */ + +.Lc2u_dest_not_aligned: + rsb ip, ip, #4 + cmp ip, #2 + ldrb r3, [r1], #1 +USER( TUSER( strb) r3, [r0], #1) @ May fault + ldrgeb r3, [r1], #1 +USER( TUSER( strgeb) r3, [r0], #1) @ May fault + ldrgtb r3, [r1], #1 +USER( TUSER( strgtb) r3, [r0], #1) @ May fault + sub r2, r2, ip + b .Lc2u_dest_aligned + +ENTRY(__copy_to_user) + stmfd sp!, {r2, r4 - r7, lr} + cmp r2, #4 + blt .Lc2u_not_enough + ands ip, r0, #3 + bne .Lc2u_dest_not_aligned +.Lc2u_dest_aligned: + + ands ip, r1, #3 + bne .Lc2u_src_not_aligned +/* + * Seeing as there has to be at least 8 bytes to copy, we can + * copy one word, and force a user-mode page fault... + */ + +.Lc2u_0fupi: subs r2, r2, #4 + addmi ip, r2, #4 + bmi .Lc2u_0nowords + ldr r3, [r1], #4 +USER( TUSER( str) r3, [r0], #4) @ May fault + mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction + rsb ip, ip, #0 + movs ip, ip, lsr #32 - PAGE_SHIFT + beq .Lc2u_0fupi +/* + * ip = max no. of bytes to copy before needing another "strt" insn + */ + cmp r2, ip + movlt ip, r2 + sub r2, r2, ip + subs ip, ip, #32 + blt .Lc2u_0rem8lp + +.Lc2u_0cpy8lp: ldmia r1!, {r3 - r6} + stmia r0!, {r3 - r6} @ Shouldnt fault + ldmia r1!, {r3 - r6} + subs ip, ip, #32 + stmia r0!, {r3 - r6} @ Shouldnt fault + bpl .Lc2u_0cpy8lp + +.Lc2u_0rem8lp: cmn ip, #16 + ldmgeia r1!, {r3 - r6} + stmgeia r0!, {r3 - r6} @ Shouldnt fault + tst ip, #8 + ldmneia r1!, {r3 - r4} + stmneia r0!, {r3 - r4} @ Shouldnt fault + tst ip, #4 + ldrne r3, [r1], #4 + TUSER( strne) r3, [r0], #4 @ Shouldnt fault + ands ip, ip, #3 + beq .Lc2u_0fupi +.Lc2u_0nowords: teq ip, #0 + beq .Lc2u_finished +.Lc2u_nowords: cmp ip, #2 + ldrb r3, [r1], #1 +USER( TUSER( strb) r3, [r0], #1) @ May fault + ldrgeb r3, [r1], #1 +USER( TUSER( strgeb) r3, [r0], #1) @ May fault + ldrgtb r3, [r1], #1 +USER( TUSER( strgtb) r3, [r0], #1) @ May fault + b .Lc2u_finished + +.Lc2u_not_enough: + movs ip, r2 + bne .Lc2u_nowords +.Lc2u_finished: mov r0, #0 + ldmfd sp!, {r2, r4 - r7, pc} + +.Lc2u_src_not_aligned: + bic r1, r1, #3 + ldr r7, [r1], #4 + cmp ip, #2 + bgt .Lc2u_3fupi + beq .Lc2u_2fupi +.Lc2u_1fupi: subs r2, r2, #4 + addmi ip, r2, #4 + bmi .Lc2u_1nowords + mov r3, r7, pull #8 + ldr r7, [r1], #4 + orr r3, r3, r7, push #24 +USER( TUSER( str) r3, [r0], #4) @ May fault + mov ip, r0, lsl #32 - PAGE_SHIFT + rsb ip, ip, #0 + movs ip, ip, lsr #32 - PAGE_SHIFT + beq .Lc2u_1fupi + cmp r2, ip + movlt ip, r2 + sub r2, r2, ip + subs ip, ip, #16 + blt .Lc2u_1rem8lp + +.Lc2u_1cpy8lp: mov r3, r7, pull #8 + ldmia r1!, {r4 - r7} + subs ip, ip, #16 + orr r3, r3, r4, push #24 + mov r4, r4, pull #8 + orr r4, r4, r5, push #24 + mov r5, r5, pull #8 + orr r5, r5, r6, push #24 + mov r6, r6, pull #8 + orr r6, r6, r7, push #24 + stmia r0!, {r3 - r6} @ Shouldnt fault + bpl .Lc2u_1cpy8lp + +.Lc2u_1rem8lp: tst ip, #8 + movne r3, r7, pull #8 + ldmneia r1!, {r4, r7} + orrne r3, r3, r4, push #24 + movne r4, r4, pull #8 + orrne r4, r4, r7, push #24 + stmneia r0!, {r3 - r4} @ Shouldnt fault + tst ip, #4 + movne r3, r7, pull #8 + ldrne r7, [r1], #4 + orrne r3, r3, r7, push #24 + TUSER( strne) r3, [r0], #4 @ Shouldnt fault + ands ip, ip, #3 + beq .Lc2u_1fupi +.Lc2u_1nowords: mov r3, r7, get_byte_1 + teq ip, #0 + beq .Lc2u_finished + cmp ip, #2 +USER( TUSER( strb) r3, [r0], #1) @ May fault + movge r3, r7, get_byte_2 +USER( TUSER( strgeb) r3, [r0], #1) @ May fault + movgt r3, r7, get_byte_3 +USER( TUSER( strgtb) r3, [r0], #1) @ May fault + b .Lc2u_finished + +.Lc2u_2fupi: subs r2, r2, #4 + addmi ip, r2, #4 + bmi .Lc2u_2nowords + mov r3, r7, pull #16 + ldr r7, [r1], #4 + orr r3, r3, r7, push #16 +USER( TUSER( str) r3, [r0], #4) @ May fault + mov ip, r0, lsl #32 - PAGE_SHIFT + rsb ip, ip, #0 + movs ip, ip, lsr #32 - PAGE_SHIFT + beq .Lc2u_2fupi + cmp r2, ip + movlt ip, r2 + sub r2, r2, ip + subs ip, ip, #16 + blt .Lc2u_2rem8lp + +.Lc2u_2cpy8lp: mov r3, r7, pull #16 + ldmia r1!, {r4 - r7} + subs ip, ip, #16 + orr r3, r3, r4, push #16 + mov r4, r4, pull #16 + orr r4, r4, r5, push #16 + mov r5, r5, pull #16 + orr r5, r5, r6, push #16 + mov r6, r6, pull #16 + orr r6, r6, r7, push #16 + stmia r0!, {r3 - r6} @ Shouldnt fault + bpl .Lc2u_2cpy8lp + +.Lc2u_2rem8lp: tst ip, #8 + movne r3, r7, pull #16 + ldmneia r1!, {r4, r7} + orrne r3, r3, r4, push #16 + movne r4, r4, pull #16 + orrne r4, r4, r7, push #16 + stmneia r0!, {r3 - r4} @ Shouldnt fault + tst ip, #4 + movne r3, r7, pull #16 + ldrne r7, [r1], #4 + orrne r3, r3, r7, push #16 + TUSER( strne) r3, [r0], #4 @ Shouldnt fault + ands ip, ip, #3 + beq .Lc2u_2fupi +.Lc2u_2nowords: mov r3, r7, get_byte_2 + teq ip, #0 + beq .Lc2u_finished + cmp ip, #2 +USER( TUSER( strb) r3, [r0], #1) @ May fault + movge r3, r7, get_byte_3 +USER( TUSER( strgeb) r3, [r0], #1) @ May fault + ldrgtb r3, [r1], #0 +USER( TUSER( strgtb) r3, [r0], #1) @ May fault + b .Lc2u_finished + +.Lc2u_3fupi: subs r2, r2, #4 + addmi ip, r2, #4 + bmi .Lc2u_3nowords + mov r3, r7, pull #24 + ldr r7, [r1], #4 + orr r3, r3, r7, push #8 +USER( TUSER( str) r3, [r0], #4) @ May fault + mov ip, r0, lsl #32 - PAGE_SHIFT + rsb ip, ip, #0 + movs ip, ip, lsr #32 - PAGE_SHIFT + beq .Lc2u_3fupi + cmp r2, ip + movlt ip, r2 + sub r2, r2, ip + subs ip, ip, #16 + blt .Lc2u_3rem8lp + +.Lc2u_3cpy8lp: mov r3, r7, pull #24 + ldmia r1!, {r4 - r7} + subs ip, ip, #16 + orr r3, r3, r4, push #8 + mov r4, r4, pull #24 + orr r4, r4, r5, push #8 + mov r5, r5, pull #24 + orr r5, r5, r6, push #8 + mov r6, r6, pull #24 + orr r6, r6, r7, push #8 + stmia r0!, {r3 - r6} @ Shouldnt fault + bpl .Lc2u_3cpy8lp + +.Lc2u_3rem8lp: tst ip, #8 + movne r3, r7, pull #24 + ldmneia r1!, {r4, r7} + orrne r3, r3, r4, push #8 + movne r4, r4, pull #24 + orrne r4, r4, r7, push #8 + stmneia r0!, {r3 - r4} @ Shouldnt fault + tst ip, #4 + movne r3, r7, pull #24 + ldrne r7, [r1], #4 + orrne r3, r3, r7, push #8 + TUSER( strne) r3, [r0], #4 @ Shouldnt fault + ands ip, ip, #3 + beq .Lc2u_3fupi +.Lc2u_3nowords: mov r3, r7, get_byte_3 + teq ip, #0 + beq .Lc2u_finished + cmp ip, #2 +USER( TUSER( strb) r3, [r0], #1) @ May fault + ldrgeb r3, [r1], #1 +USER( TUSER( strgeb) r3, [r0], #1) @ May fault + ldrgtb r3, [r1], #0 +USER( TUSER( strgtb) r3, [r0], #1) @ May fault + b .Lc2u_finished +ENDPROC(__copy_to_user) + + .pushsection .fixup,"ax" + .align 0 +9001: ldmfd sp!, {r0, r4 - r7, pc} + .popsection + +/* Prototype: unsigned long __copy_from_user(void *to,const void *from,unsigned long n); + * Purpose : copy a block from user memory to kernel memory + * Params : to - kernel memory + * : from - user memory + * : n - number of bytes to copy + * Returns : Number of bytes NOT copied. + */ +.Lcfu_dest_not_aligned: + rsb ip, ip, #4 + cmp ip, #2 +USER( TUSER( ldrb) r3, [r1], #1) @ May fault + strb r3, [r0], #1 +USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault + strgeb r3, [r0], #1 +USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault + strgtb r3, [r0], #1 + sub r2, r2, ip + b .Lcfu_dest_aligned + +ENTRY(__copy_from_user) + stmfd sp!, {r0, r2, r4 - r7, lr} + cmp r2, #4 + blt .Lcfu_not_enough + ands ip, r0, #3 + bne .Lcfu_dest_not_aligned +.Lcfu_dest_aligned: + ands ip, r1, #3 + bne .Lcfu_src_not_aligned + +/* + * Seeing as there has to be at least 8 bytes to copy, we can + * copy one word, and force a user-mode page fault... + */ + +.Lcfu_0fupi: subs r2, r2, #4 + addmi ip, r2, #4 + bmi .Lcfu_0nowords +USER( TUSER( ldr) r3, [r1], #4) + str r3, [r0], #4 + mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction + rsb ip, ip, #0 + movs ip, ip, lsr #32 - PAGE_SHIFT + beq .Lcfu_0fupi +/* + * ip = max no. of bytes to copy before needing another "strt" insn + */ + cmp r2, ip + movlt ip, r2 + sub r2, r2, ip + subs ip, ip, #32 + blt .Lcfu_0rem8lp + +.Lcfu_0cpy8lp: ldmia r1!, {r3 - r6} @ Shouldnt fault + stmia r0!, {r3 - r6} + ldmia r1!, {r3 - r6} @ Shouldnt fault + subs ip, ip, #32 + stmia r0!, {r3 - r6} + bpl .Lcfu_0cpy8lp + +.Lcfu_0rem8lp: cmn ip, #16 + ldmgeia r1!, {r3 - r6} @ Shouldnt fault + stmgeia r0!, {r3 - r6} + tst ip, #8 + ldmneia r1!, {r3 - r4} @ Shouldnt fault + stmneia r0!, {r3 - r4} + tst ip, #4 + TUSER( ldrne) r3, [r1], #4 @ Shouldnt fault + strne r3, [r0], #4 + ands ip, ip, #3 + beq .Lcfu_0fupi +.Lcfu_0nowords: teq ip, #0 + beq .Lcfu_finished +.Lcfu_nowords: cmp ip, #2 +USER( TUSER( ldrb) r3, [r1], #1) @ May fault + strb r3, [r0], #1 +USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault + strgeb r3, [r0], #1 +USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault + strgtb r3, [r0], #1 + b .Lcfu_finished + +.Lcfu_not_enough: + movs ip, r2 + bne .Lcfu_nowords +.Lcfu_finished: mov r0, #0 + add sp, sp, #8 + ldmfd sp!, {r4 - r7, pc} + +.Lcfu_src_not_aligned: + bic r1, r1, #3 +USER( TUSER( ldr) r7, [r1], #4) @ May fault + cmp ip, #2 + bgt .Lcfu_3fupi + beq .Lcfu_2fupi +.Lcfu_1fupi: subs r2, r2, #4 + addmi ip, r2, #4 + bmi .Lcfu_1nowords + mov r3, r7, pull #8 +USER( TUSER( ldr) r7, [r1], #4) @ May fault + orr r3, r3, r7, push #24 + str r3, [r0], #4 + mov ip, r1, lsl #32 - PAGE_SHIFT + rsb ip, ip, #0 + movs ip, ip, lsr #32 - PAGE_SHIFT + beq .Lcfu_1fupi + cmp r2, ip + movlt ip, r2 + sub r2, r2, ip + subs ip, ip, #16 + blt .Lcfu_1rem8lp + +.Lcfu_1cpy8lp: mov r3, r7, pull #8 + ldmia r1!, {r4 - r7} @ Shouldnt fault + subs ip, ip, #16 + orr r3, r3, r4, push #24 + mov r4, r4, pull #8 + orr r4, r4, r5, push #24 + mov r5, r5, pull #8 + orr r5, r5, r6, push #24 + mov r6, r6, pull #8 + orr r6, r6, r7, push #24 + stmia r0!, {r3 - r6} + bpl .Lcfu_1cpy8lp + +.Lcfu_1rem8lp: tst ip, #8 + movne r3, r7, pull #8 + ldmneia r1!, {r4, r7} @ Shouldnt fault + orrne r3, r3, r4, push #24 + movne r4, r4, pull #8 + orrne r4, r4, r7, push #24 + stmneia r0!, {r3 - r4} + tst ip, #4 + movne r3, r7, pull #8 +USER( TUSER( ldrne) r7, [r1], #4) @ May fault + orrne r3, r3, r7, push #24 + strne r3, [r0], #4 + ands ip, ip, #3 + beq .Lcfu_1fupi +.Lcfu_1nowords: mov r3, r7, get_byte_1 + teq ip, #0 + beq .Lcfu_finished + cmp ip, #2 + strb r3, [r0], #1 + movge r3, r7, get_byte_2 + strgeb r3, [r0], #1 + movgt r3, r7, get_byte_3 + strgtb r3, [r0], #1 + b .Lcfu_finished + +.Lcfu_2fupi: subs r2, r2, #4 + addmi ip, r2, #4 + bmi .Lcfu_2nowords + mov r3, r7, pull #16 +USER( TUSER( ldr) r7, [r1], #4) @ May fault + orr r3, r3, r7, push #16 + str r3, [r0], #4 + mov ip, r1, lsl #32 - PAGE_SHIFT + rsb ip, ip, #0 + movs ip, ip, lsr #32 - PAGE_SHIFT + beq .Lcfu_2fupi + cmp r2, ip + movlt ip, r2 + sub r2, r2, ip + subs ip, ip, #16 + blt .Lcfu_2rem8lp + + +.Lcfu_2cpy8lp: mov r3, r7, pull #16 + ldmia r1!, {r4 - r7} @ Shouldnt fault + subs ip, ip, #16 + orr r3, r3, r4, push #16 + mov r4, r4, pull #16 + orr r4, r4, r5, push #16 + mov r5, r5, pull #16 + orr r5, r5, r6, push #16 + mov r6, r6, pull #16 + orr r6, r6, r7, push #16 + stmia r0!, {r3 - r6} + bpl .Lcfu_2cpy8lp + +.Lcfu_2rem8lp: tst ip, #8 + movne r3, r7, pull #16 + ldmneia r1!, {r4, r7} @ Shouldnt fault + orrne r3, r3, r4, push #16 + movne r4, r4, pull #16 + orrne r4, r4, r7, push #16 + stmneia r0!, {r3 - r4} + tst ip, #4 + movne r3, r7, pull #16 +USER( TUSER( ldrne) r7, [r1], #4) @ May fault + orrne r3, r3, r7, push #16 + strne r3, [r0], #4 + ands ip, ip, #3 + beq .Lcfu_2fupi +.Lcfu_2nowords: mov r3, r7, get_byte_2 + teq ip, #0 + beq .Lcfu_finished + cmp ip, #2 + strb r3, [r0], #1 + movge r3, r7, get_byte_3 + strgeb r3, [r0], #1 +USER( TUSER( ldrgtb) r3, [r1], #0) @ May fault + strgtb r3, [r0], #1 + b .Lcfu_finished + +.Lcfu_3fupi: subs r2, r2, #4 + addmi ip, r2, #4 + bmi .Lcfu_3nowords + mov r3, r7, pull #24 +USER( TUSER( ldr) r7, [r1], #4) @ May fault + orr r3, r3, r7, push #8 + str r3, [r0], #4 + mov ip, r1, lsl #32 - PAGE_SHIFT + rsb ip, ip, #0 + movs ip, ip, lsr #32 - PAGE_SHIFT + beq .Lcfu_3fupi + cmp r2, ip + movlt ip, r2 + sub r2, r2, ip + subs ip, ip, #16 + blt .Lcfu_3rem8lp + +.Lcfu_3cpy8lp: mov r3, r7, pull #24 + ldmia r1!, {r4 - r7} @ Shouldnt fault + orr r3, r3, r4, push #8 + mov r4, r4, pull #24 + orr r4, r4, r5, push #8 + mov r5, r5, pull #24 + orr r5, r5, r6, push #8 + mov r6, r6, pull #24 + orr r6, r6, r7, push #8 + stmia r0!, {r3 - r6} + subs ip, ip, #16 + bpl .Lcfu_3cpy8lp + +.Lcfu_3rem8lp: tst ip, #8 + movne r3, r7, pull #24 + ldmneia r1!, {r4, r7} @ Shouldnt fault + orrne r3, r3, r4, push #8 + movne r4, r4, pull #24 + orrne r4, r4, r7, push #8 + stmneia r0!, {r3 - r4} + tst ip, #4 + movne r3, r7, pull #24 +USER( TUSER( ldrne) r7, [r1], #4) @ May fault + orrne r3, r3, r7, push #8 + strne r3, [r0], #4 + ands ip, ip, #3 + beq .Lcfu_3fupi +.Lcfu_3nowords: mov r3, r7, get_byte_3 + teq ip, #0 + beq .Lcfu_finished + cmp ip, #2 + strb r3, [r0], #1 +USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault + strgeb r3, [r0], #1 +USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault + strgtb r3, [r0], #1 + b .Lcfu_finished +ENDPROC(__copy_from_user) + + .pushsection .fixup,"ax" + .align 0 + /* + * We took an exception. r0 contains a pointer to + * the byte not copied. + */ +9001: ldr r2, [sp], #4 @ void *to + sub r2, r0, r2 @ bytes copied + ldr r1, [sp], #4 @ unsigned long count + subs r4, r1, r2 @ bytes left to copy + movne r1, r4 + blne __memzero + mov r0, r4 + ldmfd sp!, {r4 - r7, pc} + .popsection + diff --git a/trunk/arch/arm/mach-cns3xxx/pcie.c b/trunk/arch/arm/mach-cns3xxx/pcie.c index 311328314163..79d001f831e0 100644 --- a/trunk/arch/arm/mach-cns3xxx/pcie.c +++ b/trunk/arch/arm/mach-cns3xxx/pcie.c @@ -166,6 +166,12 @@ static struct pci_ops cns3xxx_pcie_ops = { .write = cns3xxx_pci_write_config, }; +static struct pci_bus *cns3xxx_pci_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_root_bus(NULL, sys->busnr, &cns3xxx_pcie_ops, sys, + &sys->resources); +} + static int cns3xxx_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct cns3xxx_pcie *cnspci = pdev_to_cnspci(dev); @@ -215,9 +221,10 @@ static struct cns3xxx_pcie cns3xxx_pcie[] = { .irqs = { IRQ_CNS3XXX_PCIE0_RC, IRQ_CNS3XXX_PCIE0_DEVICE, }, .hw_pci = { .domain = 0, + .swizzle = pci_std_swizzle, .nr_controllers = 1, - .ops = &cns3xxx_pcie_ops, .setup = cns3xxx_pci_setup, + .scan = cns3xxx_pci_scan_bus, .map_irq = cns3xxx_pcie_map_irq, }, }, @@ -257,9 +264,10 @@ static struct cns3xxx_pcie cns3xxx_pcie[] = { .irqs = { IRQ_CNS3XXX_PCIE1_RC, IRQ_CNS3XXX_PCIE1_DEVICE, }, .hw_pci = { .domain = 1, + .swizzle = pci_std_swizzle, .nr_controllers = 1, - .ops = &cns3xxx_pcie_ops, .setup = cns3xxx_pci_setup, + .scan = cns3xxx_pci_scan_bus, .map_irq = cns3xxx_pcie_map_irq, }, }, diff --git a/trunk/arch/arm/mach-dove/pcie.c b/trunk/arch/arm/mach-dove/pcie.c index 47921b0cdc65..48a032005ea3 100644 --- a/trunk/arch/arm/mach-dove/pcie.c +++ b/trunk/arch/arm/mach-dove/pcie.c @@ -43,7 +43,6 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys) return 0; pp = &pcie_port[nr]; - sys->private_data = pp; pp->root_bus_nr = sys->busnr; /* @@ -94,6 +93,19 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys) return 1; } +static struct pcie_port *bus_to_port(int bus) +{ + int i; + + for (i = num_pcie_ports - 1; i >= 0; i--) { + int rbus = pcie_port[i].root_bus_nr; + if (rbus != -1 && rbus <= bus) + break; + } + + return i >= 0 ? pcie_port + i : NULL; +} + static int pcie_valid_config(struct pcie_port *pp, int bus, int dev) { /* @@ -109,8 +121,7 @@ static int pcie_valid_config(struct pcie_port *pp, int bus, int dev) static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 *val) { - struct pci_sys_data *sys = bus->sysdata; - struct pcie_port *pp = sys->private_data; + struct pcie_port *pp = bus_to_port(bus->number); unsigned long flags; int ret; @@ -129,8 +140,7 @@ static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, static int pcie_wr_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 val) { - struct pci_sys_data *sys = bus->sysdata; - struct pcie_port *pp = sys->private_data; + struct pcie_port *pp = bus_to_port(bus->number); unsigned long flags; int ret; @@ -184,14 +194,14 @@ dove_pcie_scan_bus(int nr, struct pci_sys_data *sys) static int __init dove_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - struct pci_sys_data *sys = dev->sysdata; - struct pcie_port *pp = sys->private_data; + struct pcie_port *pp = bus_to_port(dev->bus->number); return pp->index ? IRQ_DOVE_PCIE1 : IRQ_DOVE_PCIE0; } static struct hw_pci dove_pci __initdata = { .nr_controllers = 2, + .swizzle = pci_std_swizzle, .setup = dove_pcie_setup, .scan = dove_pcie_scan_bus, .map_irq = dove_pcie_map_irq, diff --git a/trunk/arch/arm/mach-exynos/Kconfig b/trunk/arch/arm/mach-exynos/Kconfig index b8df521fb68e..e81c35f936b5 100644 --- a/trunk/arch/arm/mach-exynos/Kconfig +++ b/trunk/arch/arm/mach-exynos/Kconfig @@ -232,9 +232,6 @@ config MACH_ARMLEX4210 config MACH_UNIVERSAL_C210 bool "Mobile UNIVERSAL_C210 Board" select CPU_EXYNOS4210 - select S5P_HRT - select CLKSRC_MMIO - select HAVE_SCHED_CLOCK select S5P_GPIO_INT select S5P_DEV_FIMC0 select S5P_DEV_FIMC1 diff --git a/trunk/arch/arm/mach-exynos/clock-exynos5.c b/trunk/arch/arm/mach-exynos/clock-exynos5.c index 7ac6ff4c46bd..5cd7a8b8868c 100644 --- a/trunk/arch/arm/mach-exynos/clock-exynos5.c +++ b/trunk/arch/arm/mach-exynos/clock-exynos5.c @@ -678,7 +678,7 @@ static struct clk exynos5_clk_pdma1 = { .name = "dma", .devname = "dma-pl330.1", .enable = exynos5_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 2), + .ctrlbit = (1 << 1), }; static struct clk exynos5_clk_mdma1 = { diff --git a/trunk/arch/arm/mach-exynos/mach-universal_c210.c b/trunk/arch/arm/mach-exynos/mach-universal_c210.c index a34036eb8ba2..cb2b027f09a6 100644 --- a/trunk/arch/arm/mach-exynos/mach-universal_c210.c +++ b/trunk/arch/arm/mach-exynos/mach-universal_c210.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include @@ -1064,7 +1063,6 @@ static void __init universal_map_io(void) exynos_init_io(NULL, 0); s3c24xx_init_clocks(24000000); s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs)); - s5p_set_timer_source(S5P_PWM2, S5P_PWM4); } static void s5p_tv_setup(void) @@ -1115,7 +1113,7 @@ MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210") .map_io = universal_map_io, .handle_irq = gic_handle_irq, .init_machine = universal_machine_init, - .timer = &s5p_timer, + .timer = &exynos4_timer, .reserve = &universal_reserve, .restart = exynos4_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-footbridge/cats-pci.c b/trunk/arch/arm/mach-footbridge/cats-pci.c index 5cec2567c9c5..32321f66dec4 100644 --- a/trunk/arch/arm/mach-footbridge/cats-pci.c +++ b/trunk/arch/arm/mach-footbridge/cats-pci.c @@ -16,11 +16,6 @@ /* cats host-specific stuff */ static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 }; -static u8 cats_no_swizzle(struct pci_dev *dev, u8 *pin) -{ - return 0; -} - static int __init cats_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (dev->irq >= 255) @@ -44,11 +39,11 @@ static int __init cats_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) * cards being used (ie, pci-pci bridge based cards)? */ static struct hw_pci cats_pci __initdata = { - .swizzle = cats_no_swizzle, + .swizzle = NULL, .map_irq = cats_map_irq, .nr_controllers = 1, - .ops = &dc21285_ops, .setup = dc21285_setup, + .scan = dc21285_scan_bus, .preinit = dc21285_preinit, .postinit = dc21285_postinit, }; diff --git a/trunk/arch/arm/mach-footbridge/dc21285.c b/trunk/arch/arm/mach-footbridge/dc21285.c index 9d62e3381024..e17e11de4f5e 100644 --- a/trunk/arch/arm/mach-footbridge/dc21285.c +++ b/trunk/arch/arm/mach-footbridge/dc21285.c @@ -129,7 +129,7 @@ dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where, return PCIBIOS_SUCCESSFUL; } -struct pci_ops dc21285_ops = { +static struct pci_ops dc21285_ops = { .read = dc21285_read_config, .write = dc21285_write_config, }; @@ -284,6 +284,11 @@ int __init dc21285_setup(int nr, struct pci_sys_data *sys) return 1; } +struct pci_bus * __init dc21285_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_root_bus(NULL, 0, &dc21285_ops, sys, &sys->resources); +} + #define dc21285_request_irq(_a, _b, _c, _d, _e) \ WARN_ON(request_irq(_a, _b, _c, _d, _e) < 0) diff --git a/trunk/arch/arm/mach-footbridge/ebsa285-pci.c b/trunk/arch/arm/mach-footbridge/ebsa285-pci.c index fd12d8a36dc5..511c673ffa9d 100644 --- a/trunk/arch/arm/mach-footbridge/ebsa285-pci.c +++ b/trunk/arch/arm/mach-footbridge/ebsa285-pci.c @@ -29,10 +29,11 @@ static int __init ebsa285_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci ebsa285_pci __initdata = { + .swizzle = pci_std_swizzle, .map_irq = ebsa285_map_irq, .nr_controllers = 1, - .ops = &dc21285_ops, .setup = dc21285_setup, + .scan = dc21285_scan_bus, .preinit = dc21285_preinit, .postinit = dc21285_postinit, }; diff --git a/trunk/arch/arm/mach-footbridge/netwinder-pci.c b/trunk/arch/arm/mach-footbridge/netwinder-pci.c index 0fba5134e4fe..62187610e17e 100644 --- a/trunk/arch/arm/mach-footbridge/netwinder-pci.c +++ b/trunk/arch/arm/mach-footbridge/netwinder-pci.c @@ -43,10 +43,11 @@ static int __init netwinder_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci netwinder_pci __initdata = { + .swizzle = pci_std_swizzle, .map_irq = netwinder_map_irq, .nr_controllers = 1, - .ops = &dc21285_ops, .setup = dc21285_setup, + .scan = dc21285_scan_bus, .preinit = dc21285_preinit, .postinit = dc21285_postinit, }; diff --git a/trunk/arch/arm/mach-footbridge/personal-pci.c b/trunk/arch/arm/mach-footbridge/personal-pci.c index 5c9ee54613b2..aeb651d914a6 100644 --- a/trunk/arch/arm/mach-footbridge/personal-pci.c +++ b/trunk/arch/arm/mach-footbridge/personal-pci.c @@ -41,8 +41,8 @@ static int __init personal_server_map_irq(const struct pci_dev *dev, u8 slot, static struct hw_pci personal_server_pci __initdata = { .map_irq = personal_server_map_irq, .nr_controllers = 1, - .ops = &dc21285_ops, .setup = dc21285_setup, + .scan = dc21285_scan_bus, .preinit = dc21285_preinit, .postinit = dc21285_postinit, }; diff --git a/trunk/arch/arm/mach-integrator/impd1.c b/trunk/arch/arm/mach-integrator/impd1.c index e428f3ab15c7..3e538da6cb1f 100644 --- a/trunk/arch/arm/mach-integrator/impd1.c +++ b/trunk/arch/arm/mach-integrator/impd1.c @@ -398,16 +398,24 @@ static int impd1_probe(struct lm_device *dev) struct impd1_device *idev = impd1_devs + i; struct amba_device *d; unsigned long pc_base; - char devname[32]; pc_base = dev->resource.start + idev->offset; - snprintf(devname, 32, "lm%x:%5.5lx", dev->id, idev->offset >> 12); - d = amba_ahb_device_add(&dev->dev, devname, pc_base, SZ_4K, - dev->irq, dev->irq, - idev->platform_data, idev->id); - if (IS_ERR(d)) { - dev_err(&dev->dev, "unable to register device: %ld\n", PTR_ERR(d)); + + d = amba_device_alloc(NULL, pc_base, SZ_4K); + if (!d) continue; + + dev_set_name(&d->dev, "lm%x:%5.5lx", dev->id, idev->offset >> 12); + d->dev.parent = &dev->dev; + d->irq[0] = dev->irq; + d->irq[1] = dev->irq; + d->periphid = idev->id; + d->dev.platform_data = idev->platform_data; + + ret = amba_device_add(d, &dev->resource); + if (ret) { + dev_err(&d->dev, "unable to register device: %d\n", ret); + amba_device_put(d); } } diff --git a/trunk/arch/arm/mach-integrator/include/mach/entry-macro.S b/trunk/arch/arm/mach-integrator/include/mach/entry-macro.S new file mode 100644 index 000000000000..5cc7b85ad9df --- /dev/null +++ b/trunk/arch/arm/mach-integrator/include/mach/entry-macro.S @@ -0,0 +1,39 @@ +/* + * arch/arm/mach-integrator/include/mach/entry-macro.S + * + * Low-level IRQ helper macros for Integrator platforms + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include +#include +#include + + .macro get_irqnr_preamble, base, tmp + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp +/* FIXME: should not be using soo many LDRs here */ + ldr \base, =IO_ADDRESS(INTEGRATOR_IC_BASE) + mov \irqnr, #IRQ_PIC_START + ldr \irqstat, [\base, #IRQ_STATUS] @ get masked status + ldr \base, =IO_ADDRESS(INTEGRATOR_HDR_BASE) + teq \irqstat, #0 + ldreq \irqstat, [\base, #(INTEGRATOR_HDR_IC_OFFSET+IRQ_STATUS)] + moveq \irqnr, #IRQ_CIC_START + +1001: tst \irqstat, #15 + bne 1002f + add \irqnr, \irqnr, #4 + movs \irqstat, \irqstat, lsr #4 + bne 1001b +1002: tst \irqstat, #1 + bne 1003f + add \irqnr, \irqnr, #1 + movs \irqstat, \irqstat, lsr #1 + bne 1002b +1003: /* EQ will be set if no irqs pending */ + .endm + diff --git a/trunk/arch/arm/mach-integrator/include/mach/irqs.h b/trunk/arch/arm/mach-integrator/include/mach/irqs.h index 7371018455d2..a19a1a2fcf6b 100644 --- a/trunk/arch/arm/mach-integrator/include/mach/irqs.h +++ b/trunk/arch/arm/mach-integrator/include/mach/irqs.h @@ -22,37 +22,37 @@ /* * Interrupt numbers */ -#define IRQ_PIC_START 1 -#define IRQ_SOFTINT 1 -#define IRQ_UARTINT0 2 -#define IRQ_UARTINT1 3 -#define IRQ_KMIINT0 4 -#define IRQ_KMIINT1 5 -#define IRQ_TIMERINT0 6 -#define IRQ_TIMERINT1 7 -#define IRQ_TIMERINT2 8 -#define IRQ_RTCINT 9 -#define IRQ_AP_EXPINT0 10 -#define IRQ_AP_EXPINT1 11 -#define IRQ_AP_EXPINT2 12 -#define IRQ_AP_EXPINT3 13 -#define IRQ_AP_PCIINT0 14 -#define IRQ_AP_PCIINT1 15 -#define IRQ_AP_PCIINT2 16 -#define IRQ_AP_PCIINT3 17 -#define IRQ_AP_V3INT 18 -#define IRQ_AP_CPINT0 19 -#define IRQ_AP_CPINT1 20 -#define IRQ_AP_LBUSTIMEOUT 21 -#define IRQ_AP_APCINT 22 -#define IRQ_CP_CLCDCINT 23 -#define IRQ_CP_MMCIINT0 24 -#define IRQ_CP_MMCIINT1 25 -#define IRQ_CP_AACIINT 26 -#define IRQ_CP_CPPLDINT 27 -#define IRQ_CP_ETHINT 28 -#define IRQ_CP_TSPENINT 29 -#define IRQ_PIC_END 29 +#define IRQ_PIC_START 0 +#define IRQ_SOFTINT 0 +#define IRQ_UARTINT0 1 +#define IRQ_UARTINT1 2 +#define IRQ_KMIINT0 3 +#define IRQ_KMIINT1 4 +#define IRQ_TIMERINT0 5 +#define IRQ_TIMERINT1 6 +#define IRQ_TIMERINT2 7 +#define IRQ_RTCINT 8 +#define IRQ_AP_EXPINT0 9 +#define IRQ_AP_EXPINT1 10 +#define IRQ_AP_EXPINT2 11 +#define IRQ_AP_EXPINT3 12 +#define IRQ_AP_PCIINT0 13 +#define IRQ_AP_PCIINT1 14 +#define IRQ_AP_PCIINT2 15 +#define IRQ_AP_PCIINT3 16 +#define IRQ_AP_V3INT 17 +#define IRQ_AP_CPINT0 18 +#define IRQ_AP_CPINT1 19 +#define IRQ_AP_LBUSTIMEOUT 20 +#define IRQ_AP_APCINT 21 +#define IRQ_CP_CLCDCINT 22 +#define IRQ_CP_MMCIINT0 23 +#define IRQ_CP_MMCIINT1 24 +#define IRQ_CP_AACIINT 25 +#define IRQ_CP_CPPLDINT 26 +#define IRQ_CP_ETHINT 27 +#define IRQ_CP_TSPENINT 28 +#define IRQ_PIC_END 31 #define IRQ_CIC_START 32 #define IRQ_CM_SOFTINT 32 @@ -80,3 +80,4 @@ #define NR_IRQS_INTEGRATOR_AP 34 #define NR_IRQS_INTEGRATOR_CP 47 + diff --git a/trunk/arch/arm/mach-integrator/integrator_ap.c b/trunk/arch/arm/mach-integrator/integrator_ap.c index c857501c5783..871f148ffd72 100644 --- a/trunk/arch/arm/mach-integrator/integrator_ap.c +++ b/trunk/arch/arm/mach-integrator/integrator_ap.c @@ -162,6 +162,12 @@ static void __init ap_map_io(void) #define INTEGRATOR_SC_VALID_INT 0x003fffff +static struct fpga_irq_data sc_irq_data = { + .base = VA_IC_BASE, + .irq_start = 0, + .chip.name = "SC", +}; + static void __init ap_init_irq(void) { /* Disable all interrupts initially. */ @@ -172,8 +178,7 @@ static void __init ap_init_irq(void) writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); - fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START, - -1, INTEGRATOR_SC_VALID_INT, NULL); + fpga_irq_init(-1, INTEGRATOR_SC_VALID_INT, &sc_irq_data); } #ifdef CONFIG_PM @@ -473,7 +478,6 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator") .nr_irqs = NR_IRQS_INTEGRATOR_AP, .init_early = integrator_init_early, .init_irq = ap_init_irq, - .handle_irq = fpga_handle_irq, .timer = &ap_timer, .init_machine = ap_init, .restart = integrator_restart, diff --git a/trunk/arch/arm/mach-integrator/integrator_cp.c b/trunk/arch/arm/mach-integrator/integrator_cp.c index a56c53608939..48a115a91d9d 100644 --- a/trunk/arch/arm/mach-integrator/integrator_cp.c +++ b/trunk/arch/arm/mach-integrator/integrator_cp.c @@ -143,14 +143,30 @@ static void __init intcp_map_io(void) iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc)); } +static struct fpga_irq_data cic_irq_data = { + .base = INTCP_VA_CIC_BASE, + .irq_start = IRQ_CIC_START, + .chip.name = "CIC", +}; + +static struct fpga_irq_data pic_irq_data = { + .base = INTCP_VA_PIC_BASE, + .irq_start = IRQ_PIC_START, + .chip.name = "PIC", +}; + +static struct fpga_irq_data sic_irq_data = { + .base = INTCP_VA_SIC_BASE, + .irq_start = IRQ_SIC_START, + .chip.name = "SIC", +}; + static void __init intcp_init_irq(void) { - u32 pic_mask, cic_mask, sic_mask; + u32 pic_mask, sic_mask; - /* These masks are for the HW IRQ registers */ pic_mask = ~((~0u) << (11 - IRQ_PIC_START)); pic_mask |= (~((~0u) << (29 - 22))) << 22; - cic_mask = ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)); sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START)); /* @@ -163,14 +179,12 @@ static void __init intcp_init_irq(void) writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR); writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR); - fpga_irq_init(INTCP_VA_PIC_BASE, "PIC", IRQ_PIC_START, - -1, pic_mask, NULL); + fpga_irq_init(-1, pic_mask, &pic_irq_data); - fpga_irq_init(INTCP_VA_CIC_BASE, "CIC", IRQ_CIC_START, - -1, cic_mask, NULL); + fpga_irq_init(-1, ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)), + &cic_irq_data); - fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START, - IRQ_CP_CPPLDINT, sic_mask, NULL); + fpga_irq_init(IRQ_CP_CPPLDINT, sic_mask, &sic_irq_data); } /* @@ -453,7 +467,6 @@ MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") .nr_irqs = NR_IRQS_INTEGRATOR_CP, .init_early = intcp_init_early, .init_irq = intcp_init_irq, - .handle_irq = fpga_handle_irq, .timer = &cp_timer, .init_machine = intcp_init, .restart = integrator_restart, diff --git a/trunk/arch/arm/mach-integrator/pci.c b/trunk/arch/arm/mach-integrator/pci.c index 6c1667e728f5..f1ca9c122861 100644 --- a/trunk/arch/arm/mach-integrator/pci.c +++ b/trunk/arch/arm/mach-integrator/pci.c @@ -70,10 +70,21 @@ */ static u8 __init integrator_swizzle(struct pci_dev *dev, u8 *pinp) { - if (*pinp == 0) - *pinp = 1; + int pin = *pinp; - return pci_common_swizzle(dev, pinp); + if (pin == 0) + pin = 1; + + while (dev->bus->self) { + pin = pci_swizzle_interrupt_pin(dev, pin); + /* + * move up the chain of bridges, swizzling as we go. + */ + dev = dev->bus->self; + } + *pinp = pin; + + return PCI_SLOT(dev->devfn); } static int irq_tab[4] __initdata = { @@ -98,7 +109,7 @@ static struct hw_pci integrator_pci __initdata = { .map_irq = integrator_map_irq, .setup = pci_v3_setup, .nr_controllers = 1, - .ops = &pci_v3_ops, + .scan = pci_v3_scan_bus, .preinit = pci_v3_preinit, .postinit = pci_v3_postinit, }; diff --git a/trunk/arch/arm/mach-integrator/pci_v3.c b/trunk/arch/arm/mach-integrator/pci_v3.c index b866880e82ac..67e6f9a9d1a0 100644 --- a/trunk/arch/arm/mach-integrator/pci_v3.c +++ b/trunk/arch/arm/mach-integrator/pci_v3.c @@ -340,7 +340,7 @@ static int v3_write_config(struct pci_bus *bus, unsigned int devfn, int where, return PCIBIOS_SUCCESSFUL; } -struct pci_ops pci_v3_ops = { +static struct pci_ops pci_v3_ops = { .read = v3_read_config, .write = v3_write_config, }; @@ -488,6 +488,12 @@ int __init pci_v3_setup(int nr, struct pci_sys_data *sys) return ret; } +struct pci_bus * __init pci_v3_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_root_bus(NULL, sys->busnr, &pci_v3_ops, sys, + &sys->resources); +} + /* * V3_LB_BASE? - local bus address * V3_LB_MAP? - pci bus address diff --git a/trunk/arch/arm/mach-iop13xx/iq81340mc.c b/trunk/arch/arm/mach-iop13xx/iq81340mc.c index e3f3e7daa79e..5c96b73e6964 100644 --- a/trunk/arch/arm/mach-iop13xx/iq81340mc.c +++ b/trunk/arch/arm/mach-iop13xx/iq81340mc.c @@ -54,6 +54,7 @@ iq81340mc_pcix_map_irq(const struct pci_dev *dev, u8 idsel, u8 pin) } static struct hw_pci iq81340mc_pci __initdata = { + .swizzle = pci_std_swizzle, .nr_controllers = 0, .setup = iop13xx_pci_setup, .map_irq = iq81340mc_pcix_map_irq, diff --git a/trunk/arch/arm/mach-iop13xx/iq81340sc.c b/trunk/arch/arm/mach-iop13xx/iq81340sc.c index 060cddde2fd4..aa4dd750135a 100644 --- a/trunk/arch/arm/mach-iop13xx/iq81340sc.c +++ b/trunk/arch/arm/mach-iop13xx/iq81340sc.c @@ -56,6 +56,7 @@ iq81340sc_atux_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) } static struct hw_pci iq81340sc_pci __initdata = { + .swizzle = pci_std_swizzle, .nr_controllers = 0, .setup = iop13xx_pci_setup, .scan = iop13xx_scan_bus, diff --git a/trunk/arch/arm/mach-iop32x/em7210.c b/trunk/arch/arm/mach-iop32x/em7210.c index 9f369f09c29d..24069e03fdc1 100644 --- a/trunk/arch/arm/mach-iop32x/em7210.c +++ b/trunk/arch/arm/mach-iop32x/em7210.c @@ -103,10 +103,11 @@ em7210_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci em7210_pci __initdata = { + .swizzle = pci_std_swizzle, .nr_controllers = 1, - .ops = &iop3xx_ops, .setup = iop3xx_pci_setup, .preinit = iop3xx_pci_preinit, + .scan = iop3xx_pci_scan_bus, .map_irq = em7210_pci_map_irq, }; diff --git a/trunk/arch/arm/mach-iop32x/glantank.c b/trunk/arch/arm/mach-iop32x/glantank.c index c15a100ba779..204e1d1cd766 100644 --- a/trunk/arch/arm/mach-iop32x/glantank.c +++ b/trunk/arch/arm/mach-iop32x/glantank.c @@ -96,10 +96,11 @@ glantank_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci glantank_pci __initdata = { + .swizzle = pci_std_swizzle, .nr_controllers = 1, - .ops = &iop3xx_ops, .setup = iop3xx_pci_setup, .preinit = iop3xx_pci_preinit, + .scan = iop3xx_pci_scan_bus, .map_irq = glantank_pci_map_irq, }; diff --git a/trunk/arch/arm/mach-iop32x/iq31244.c b/trunk/arch/arm/mach-iop32x/iq31244.c index ddd1c7ecfe57..3eb642af1cdc 100644 --- a/trunk/arch/arm/mach-iop32x/iq31244.c +++ b/trunk/arch/arm/mach-iop32x/iq31244.c @@ -130,10 +130,11 @@ ep80219_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci ep80219_pci __initdata = { + .swizzle = pci_std_swizzle, .nr_controllers = 1, - .ops = &iop3xx_ops, .setup = iop3xx_pci_setup, .preinit = iop3xx_pci_preinit, + .scan = iop3xx_pci_scan_bus, .map_irq = ep80219_pci_map_irq, }; @@ -165,10 +166,11 @@ iq31244_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci iq31244_pci __initdata = { + .swizzle = pci_std_swizzle, .nr_controllers = 1, - .ops = &iop3xx_ops, .setup = iop3xx_pci_setup, .preinit = iop3xx_pci_preinit, + .scan = iop3xx_pci_scan_bus, .map_irq = iq31244_pci_map_irq, }; diff --git a/trunk/arch/arm/mach-iop32x/iq80321.c b/trunk/arch/arm/mach-iop32x/iq80321.c index bf155e6a3b45..2ec724b58a2c 100644 --- a/trunk/arch/arm/mach-iop32x/iq80321.c +++ b/trunk/arch/arm/mach-iop32x/iq80321.c @@ -101,10 +101,11 @@ iq80321_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci iq80321_pci __initdata = { + .swizzle = pci_std_swizzle, .nr_controllers = 1, - .ops = &iop3xx_ops, .setup = iop3xx_pci_setup, .preinit = iop3xx_pci_preinit_cond, + .scan = iop3xx_pci_scan_bus, .map_irq = iq80321_pci_map_irq, }; diff --git a/trunk/arch/arm/mach-iop32x/n2100.c b/trunk/arch/arm/mach-iop32x/n2100.c index 5a7ae91e8849..6b6d55912444 100644 --- a/trunk/arch/arm/mach-iop32x/n2100.c +++ b/trunk/arch/arm/mach-iop32x/n2100.c @@ -114,10 +114,11 @@ n2100_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci n2100_pci __initdata = { + .swizzle = pci_std_swizzle, .nr_controllers = 1, - .ops = &iop3xx_ops, .setup = iop3xx_pci_setup, .preinit = iop3xx_pci_preinit, + .scan = iop3xx_pci_scan_bus, .map_irq = n2100_pci_map_irq, }; diff --git a/trunk/arch/arm/mach-iop33x/iq80331.c b/trunk/arch/arm/mach-iop33x/iq80331.c index e74a7debe793..abce934f3816 100644 --- a/trunk/arch/arm/mach-iop33x/iq80331.c +++ b/trunk/arch/arm/mach-iop33x/iq80331.c @@ -84,10 +84,11 @@ iq80331_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci iq80331_pci __initdata = { + .swizzle = pci_std_swizzle, .nr_controllers = 1, - .ops = &iop3xx_ops, .setup = iop3xx_pci_setup, .preinit = iop3xx_pci_preinit_cond, + .scan = iop3xx_pci_scan_bus, .map_irq = iq80331_pci_map_irq, }; diff --git a/trunk/arch/arm/mach-iop33x/iq80332.c b/trunk/arch/arm/mach-iop33x/iq80332.c index e2f5beece6e8..7513559e25bb 100644 --- a/trunk/arch/arm/mach-iop33x/iq80332.c +++ b/trunk/arch/arm/mach-iop33x/iq80332.c @@ -84,10 +84,11 @@ iq80332_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci iq80332_pci __initdata = { + .swizzle = pci_std_swizzle, .nr_controllers = 1, - .ops = &iop3xx_ops, .setup = iop3xx_pci_setup, .preinit = iop3xx_pci_preinit_cond, + .scan = iop3xx_pci_scan_bus, .map_irq = iq80332_pci_map_irq, }; diff --git a/trunk/arch/arm/mach-ixp2000/enp2611.c b/trunk/arch/arm/mach-ixp2000/enp2611.c index 73df2f688813..4867f408617c 100644 --- a/trunk/arch/arm/mach-ixp2000/enp2611.c +++ b/trunk/arch/arm/mach-ixp2000/enp2611.c @@ -141,6 +141,13 @@ static struct pci_ops enp2611_pci_ops = { .write = enp2611_pci_write_config }; +static struct pci_bus * __init enp2611_pci_scan_bus(int nr, + struct pci_sys_data *sys) +{ + return pci_scan_root_bus(NULL, sys->busnr, &enp2611_pci_ops, sys, + &sys->resources); +} + static int __init enp2611_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { @@ -173,9 +180,9 @@ static int __init enp2611_pci_map_irq(const struct pci_dev *dev, u8 slot, struct hw_pci enp2611_pci __initdata = { .nr_controllers = 1, - .ops = &enp2611_pci_ops, .setup = enp2611_pci_setup, .preinit = enp2611_pci_preinit, + .scan = enp2611_pci_scan_bus, .map_irq = enp2611_pci_map_irq, }; diff --git a/trunk/arch/arm/mach-ixp2000/include/mach/platform.h b/trunk/arch/arm/mach-ixp2000/include/mach/platform.h index 6b500c0858be..bb0f8dcf9ee1 100644 --- a/trunk/arch/arm/mach-ixp2000/include/mach/platform.h +++ b/trunk/arch/arm/mach-ixp2000/include/mach/platform.h @@ -127,10 +127,10 @@ unsigned long ixp2000_gettimeoffset(void); struct pci_sys_data; -extern struct pci_ops ixp2000_pci_ops; u32 *ixp2000_pci_config_addr(unsigned int bus, unsigned int devfn, int where); void ixp2000_pci_preinit(void); int ixp2000_pci_setup(int, struct pci_sys_data*); +struct pci_bus* ixp2000_pci_scan_bus(int, struct pci_sys_data*); int ixp2000_pci_read_config(struct pci_bus*, unsigned int, int, int, u32 *); int ixp2000_pci_write_config(struct pci_bus*, unsigned int, int, int, u32); diff --git a/trunk/arch/arm/mach-ixp2000/ixdp2400.c b/trunk/arch/arm/mach-ixp2000/ixdp2400.c index 4ec44801d303..915ad49e3b8f 100644 --- a/trunk/arch/arm/mach-ixp2000/ixdp2400.c +++ b/trunk/arch/arm/mach-ixp2000/ixdp2400.c @@ -146,10 +146,10 @@ static void ixdp2400_pci_postinit(void) static struct hw_pci ixdp2400_pci __initdata = { .nr_controllers = 1, - .ops = &ixp2000_pci_ops, .setup = ixdp2400_pci_setup, .preinit = ixdp2400_pci_preinit, .postinit = ixdp2400_pci_postinit, + .scan = ixp2000_pci_scan_bus, .map_irq = ixdp2400_pci_map_irq, }; diff --git a/trunk/arch/arm/mach-ixp2000/ixdp2800.c b/trunk/arch/arm/mach-ixp2000/ixdp2800.c index 44378c31d177..a9f1819ea049 100644 --- a/trunk/arch/arm/mach-ixp2000/ixdp2800.c +++ b/trunk/arch/arm/mach-ixp2000/ixdp2800.c @@ -246,10 +246,10 @@ static void __init ixdp2800_pci_postinit(void) struct __initdata hw_pci ixdp2800_pci __initdata = { .nr_controllers = 1, - .ops = &ixp2000_pci_ops, .setup = ixdp2800_pci_setup, .preinit = ixdp2800_pci_preinit, .postinit = ixdp2800_pci_postinit, + .scan = ixp2000_pci_scan_bus, .map_irq = ixdp2800_pci_map_irq, }; diff --git a/trunk/arch/arm/mach-ixp2000/ixdp2x01.c b/trunk/arch/arm/mach-ixp2000/ixdp2x01.c index af8b801d7d59..5196c39cdba4 100644 --- a/trunk/arch/arm/mach-ixp2000/ixdp2x01.c +++ b/trunk/arch/arm/mach-ixp2000/ixdp2x01.c @@ -327,9 +327,9 @@ static int ixdp2x01_pci_setup(int nr, struct pci_sys_data *sys) struct hw_pci ixdp2x01_pci __initdata = { .nr_controllers = 1, - .ops = &ixp2000_pci_ops, .setup = ixdp2x01_pci_setup, .preinit = ixdp2x01_pci_preinit, + .scan = ixp2000_pci_scan_bus, .map_irq = ixdp2x01_pci_map_irq, }; diff --git a/trunk/arch/arm/mach-ixp2000/pci.c b/trunk/arch/arm/mach-ixp2000/pci.c index d706838db023..9c02de932fac 100644 --- a/trunk/arch/arm/mach-ixp2000/pci.c +++ b/trunk/arch/arm/mach-ixp2000/pci.c @@ -124,11 +124,17 @@ int ixp2000_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where, } -struct pci_ops ixp2000_pci_ops = { +static struct pci_ops ixp2000_pci_ops = { .read = ixp2000_pci_read_config, .write = ixp2000_pci_write_config }; +struct pci_bus *ixp2000_pci_scan_bus(int nr, struct pci_sys_data *sysdata) +{ + return pci_scan_root_bus(NULL, sysdata->busnr, &ixp2000_pci_ops, + sysdata, &sysdata->resources); +} + int ixp2000_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { diff --git a/trunk/arch/arm/mach-ixp23xx/include/mach/platform.h b/trunk/arch/arm/mach-ixp23xx/include/mach/platform.h index 798d8b42ab4a..50de558e722e 100644 --- a/trunk/arch/arm/mach-ixp23xx/include/mach/platform.h +++ b/trunk/arch/arm/mach-ixp23xx/include/mach/platform.h @@ -37,7 +37,7 @@ void ixp23xx_sys_init(void); void ixp23xx_restart(char, const char *); int ixp23xx_pci_setup(int, struct pci_sys_data *); void ixp23xx_pci_preinit(void); -extern struct pci_ops ixp23xx_pci_ops; +struct pci_bus *ixp23xx_pci_scan_bus(int, struct pci_sys_data*); void ixp23xx_pci_slave_init(void); extern struct sys_timer ixp23xx_timer; diff --git a/trunk/arch/arm/mach-ixp23xx/ixdp2351.c b/trunk/arch/arm/mach-ixp23xx/ixdp2351.c index 8b48e32a8a62..b0e07db5ceaf 100644 --- a/trunk/arch/arm/mach-ixp23xx/ixdp2351.c +++ b/trunk/arch/arm/mach-ixp23xx/ixdp2351.c @@ -251,9 +251,9 @@ static int __init ixdp2351_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci ixdp2351_pci __initdata = { .nr_controllers = 1, - .ops = &ixp23xx_pci_ops, .preinit = ixp23xx_pci_preinit, .setup = ixp23xx_pci_setup, + .scan = ixp23xx_pci_scan_bus, .map_irq = ixdp2351_map_irq, }; diff --git a/trunk/arch/arm/mach-ixp23xx/pci.c b/trunk/arch/arm/mach-ixp23xx/pci.c index 9211506ef556..911f5a58e006 100644 --- a/trunk/arch/arm/mach-ixp23xx/pci.c +++ b/trunk/arch/arm/mach-ixp23xx/pci.c @@ -140,6 +140,12 @@ struct pci_ops ixp23xx_pci_ops = { .write = ixp23xx_pci_write_config, }; +struct pci_bus *ixp23xx_pci_scan_bus(int nr, struct pci_sys_data *sysdata) +{ + return pci_scan_root_bus(NULL, sysdata->busnr, &ixp23xx_pci_ops, + sysdata, &sysdata->resources); +} + int ixp23xx_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { volatile unsigned long temp; diff --git a/trunk/arch/arm/mach-ixp23xx/roadrunner.c b/trunk/arch/arm/mach-ixp23xx/roadrunner.c index 8c0e5de3c609..eaaa3fa9fd05 100644 --- a/trunk/arch/arm/mach-ixp23xx/roadrunner.c +++ b/trunk/arch/arm/mach-ixp23xx/roadrunner.c @@ -118,9 +118,9 @@ static void __init roadrunner_pci_preinit(void) static struct hw_pci roadrunner_pci __initdata = { .nr_controllers = 1, - .ops = &ixp23xx_pci_ops, .preinit = roadrunner_pci_preinit, .setup = ixp23xx_pci_setup, + .scan = ixp23xx_pci_scan_bus, .map_irq = roadrunner_map_irq, }; diff --git a/trunk/arch/arm/mach-ixp4xx/avila-pci.c b/trunk/arch/arm/mach-ixp4xx/avila-pci.c index 548c7d43ade6..8fea0a3c5246 100644 --- a/trunk/arch/arm/mach-ixp4xx/avila-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/avila-pci.c @@ -65,9 +65,10 @@ static int __init avila_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci avila_pci __initdata = { .nr_controllers = 1, - .ops = &ixp4xx_ops, .preinit = avila_pci_preinit, + .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, .map_irq = avila_map_irq, }; diff --git a/trunk/arch/arm/mach-ixp4xx/common-pci.c b/trunk/arch/arm/mach-ixp4xx/common-pci.c index 1694f01ce2b6..d5719eb42591 100644 --- a/trunk/arch/arm/mach-ixp4xx/common-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/common-pci.c @@ -480,6 +480,12 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys) return 1; } +struct pci_bus * __devinit ixp4xx_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_root_bus(NULL, sys->busnr, &ixp4xx_ops, sys, + &sys->resources); +} + int dma_set_coherent_mask(struct device *dev, u64 mask) { if (mask >= SZ_64M - 1) diff --git a/trunk/arch/arm/mach-ixp4xx/coyote-pci.c b/trunk/arch/arm/mach-ixp4xx/coyote-pci.c index 5d14ce2aee6d..71f5c9c60fc3 100644 --- a/trunk/arch/arm/mach-ixp4xx/coyote-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/coyote-pci.c @@ -48,9 +48,10 @@ static int __init coyote_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci coyote_pci __initdata = { .nr_controllers = 1, - .ops = &ixp4xx_ops, .preinit = coyote_pci_preinit, + .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, .map_irq = coyote_map_irq, }; diff --git a/trunk/arch/arm/mach-ixp4xx/dsmg600-pci.c b/trunk/arch/arm/mach-ixp4xx/dsmg600-pci.c index 8dca76937723..0532510b5e8c 100644 --- a/trunk/arch/arm/mach-ixp4xx/dsmg600-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/dsmg600-pci.c @@ -62,9 +62,10 @@ static int __init dsmg600_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci __initdata dsmg600_pci = { .nr_controllers = 1, - .ops = &ixp4xx_ops, .preinit = dsmg600_pci_preinit, + .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, .map_irq = dsmg600_map_irq, }; diff --git a/trunk/arch/arm/mach-ixp4xx/fsg-pci.c b/trunk/arch/arm/mach-ixp4xx/fsg-pci.c index fd4a8625b4ae..d2ac803328f7 100644 --- a/trunk/arch/arm/mach-ixp4xx/fsg-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/fsg-pci.c @@ -59,9 +59,10 @@ static int __init fsg_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci fsg_pci __initdata = { .nr_controllers = 1, - .ops = &ixp4xx_ops, .preinit = fsg_pci_preinit, + .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, .map_irq = fsg_map_irq, }; diff --git a/trunk/arch/arm/mach-ixp4xx/gateway7001-pci.c b/trunk/arch/arm/mach-ixp4xx/gateway7001-pci.c index d9d6cc089707..76581fb467c4 100644 --- a/trunk/arch/arm/mach-ixp4xx/gateway7001-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/gateway7001-pci.c @@ -47,9 +47,10 @@ static int __init gateway7001_map_irq(const struct pci_dev *dev, u8 slot, struct hw_pci gateway7001_pci __initdata = { .nr_controllers = 1, - .ops = &ixp4xx_ops, .preinit = gateway7001_pci_preinit, + .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, .map_irq = gateway7001_map_irq, }; diff --git a/trunk/arch/arm/mach-ixp4xx/goramo_mlr.c b/trunk/arch/arm/mach-ixp4xx/goramo_mlr.c index b800a031207c..46bb924962ee 100644 --- a/trunk/arch/arm/mach-ixp4xx/goramo_mlr.c +++ b/trunk/arch/arm/mach-ixp4xx/goramo_mlr.c @@ -473,10 +473,11 @@ static int __init gmlr_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) static struct hw_pci gmlr_hw_pci __initdata = { .nr_controllers = 1, - .ops = &ixp4xx_ops, .preinit = gmlr_pci_preinit, .postinit = gmlr_pci_postinit, + .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, .map_irq = gmlr_map_irq, }; diff --git a/trunk/arch/arm/mach-ixp4xx/gtwx5715-pci.c b/trunk/arch/arm/mach-ixp4xx/gtwx5715-pci.c index 551d114c9e14..d68fc068c38d 100644 --- a/trunk/arch/arm/mach-ixp4xx/gtwx5715-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/gtwx5715-pci.c @@ -67,9 +67,10 @@ static int __init gtwx5715_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci gtwx5715_pci __initdata = { .nr_controllers = 1, - .ops = &ixp4xx_ops, .preinit = gtwx5715_pci_preinit, + .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, .map_irq = gtwx5715_map_irq, }; diff --git a/trunk/arch/arm/mach-ixp4xx/include/mach/platform.h b/trunk/arch/arm/mach-ixp4xx/include/mach/platform.h index 5bce94aacca9..b66bedc64de1 100644 --- a/trunk/arch/arm/mach-ixp4xx/include/mach/platform.h +++ b/trunk/arch/arm/mach-ixp4xx/include/mach/platform.h @@ -130,7 +130,7 @@ extern void ixp4xx_restart(char, const char *); extern void ixp4xx_pci_preinit(void); struct pci_sys_data; extern int ixp4xx_setup(int nr, struct pci_sys_data *sys); -extern struct pci_ops ixp4xx_ops; +extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys); /* * GPIO-functions diff --git a/trunk/arch/arm/mach-ixp4xx/ixdp425-pci.c b/trunk/arch/arm/mach-ixp4xx/ixdp425-pci.c index 318424dd3c50..fffd8c5e40bf 100644 --- a/trunk/arch/arm/mach-ixp4xx/ixdp425-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/ixdp425-pci.c @@ -60,9 +60,10 @@ static int __init ixdp425_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci ixdp425_pci __initdata = { .nr_controllers = 1, - .ops = &ixp4xx_ops, .preinit = ixdp425_pci_preinit, + .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, .map_irq = ixdp425_map_irq, }; diff --git a/trunk/arch/arm/mach-ixp4xx/ixdpg425-pci.c b/trunk/arch/arm/mach-ixp4xx/ixdpg425-pci.c index 1f8717ba13dc..34efe75015ec 100644 --- a/trunk/arch/arm/mach-ixp4xx/ixdpg425-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/ixdpg425-pci.c @@ -42,9 +42,10 @@ static int __init ixdpg425_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci ixdpg425_pci __initdata = { .nr_controllers = 1, - .ops = &ixp4xx_ops, .preinit = ixdpg425_pci_preinit, + .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, .map_irq = ixdpg425_map_irq, }; diff --git a/trunk/arch/arm/mach-ixp4xx/miccpt-pci.c b/trunk/arch/arm/mach-ixp4xx/miccpt-pci.c index d114ccd2017c..ca0bae7fca90 100644 --- a/trunk/arch/arm/mach-ixp4xx/miccpt-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/miccpt-pci.c @@ -61,9 +61,10 @@ static int __init miccpt_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci miccpt_pci __initdata = { .nr_controllers = 1, - .ops = &ixp4xx_ops, .preinit = miccpt_pci_preinit, + .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, .map_irq = miccpt_map_irq, }; diff --git a/trunk/arch/arm/mach-ixp4xx/nas100d-pci.c b/trunk/arch/arm/mach-ixp4xx/nas100d-pci.c index 8f0eba0a6800..5434ccf553eb 100644 --- a/trunk/arch/arm/mach-ixp4xx/nas100d-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/nas100d-pci.c @@ -58,9 +58,10 @@ static int __init nas100d_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci __initdata nas100d_pci = { .nr_controllers = 1, - .ops = &ixp4xx_ops, .preinit = nas100d_pci_preinit, + .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, .map_irq = nas100d_map_irq, }; diff --git a/trunk/arch/arm/mach-ixp4xx/nslu2-pci.c b/trunk/arch/arm/mach-ixp4xx/nslu2-pci.c index 032defe111aa..b57160535e47 100644 --- a/trunk/arch/arm/mach-ixp4xx/nslu2-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/nslu2-pci.c @@ -54,9 +54,10 @@ static int __init nslu2_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci __initdata nslu2_pci = { .nr_controllers = 1, - .ops = &ixp4xx_ops, .preinit = nslu2_pci_preinit, + .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, .map_irq = nslu2_map_irq, }; diff --git a/trunk/arch/arm/mach-ixp4xx/vulcan-pci.c b/trunk/arch/arm/mach-ixp4xx/vulcan-pci.c index a4220fa5e0c3..0bc3f34c282f 100644 --- a/trunk/arch/arm/mach-ixp4xx/vulcan-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/vulcan-pci.c @@ -56,9 +56,10 @@ static int __init vulcan_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci vulcan_pci __initdata = { .nr_controllers = 1, - .ops = &ixp4xx_ops, .preinit = vulcan_pci_preinit, + .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, .map_irq = vulcan_map_irq, }; diff --git a/trunk/arch/arm/mach-ixp4xx/wg302v2-pci.c b/trunk/arch/arm/mach-ixp4xx/wg302v2-pci.c index c92e5b82af36..f27dfcfe811b 100644 --- a/trunk/arch/arm/mach-ixp4xx/wg302v2-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/wg302v2-pci.c @@ -46,9 +46,10 @@ static int __init wg302v2_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci wg302v2_pci __initdata = { .nr_controllers = 1, - .ops = &ixp4xx_ops, .preinit = wg302v2_pci_preinit, + .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, .map_irq = wg302v2_map_irq, }; diff --git a/trunk/arch/arm/mach-kirkwood/board-dt.c b/trunk/arch/arm/mach-kirkwood/board-dt.c index f7fe1b9f3170..1c672d9e6656 100644 --- a/trunk/arch/arm/mach-kirkwood/board-dt.c +++ b/trunk/arch/arm/mach-kirkwood/board-dt.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mach-kirkwood/pcie.c b/trunk/arch/arm/mach-kirkwood/pcie.c index de373176ee67..f56a0118c1bb 100644 --- a/trunk/arch/arm/mach-kirkwood/pcie.c +++ b/trunk/arch/arm/mach-kirkwood/pcie.c @@ -44,6 +44,12 @@ struct pcie_port { static int pcie_port_map[2]; static int num_pcie_ports; +static inline struct pcie_port *bus_to_port(struct pci_bus *bus) +{ + struct pci_sys_data *sys = bus->sysdata; + return sys->private_data; +} + static int pcie_valid_config(struct pcie_port *pp, int bus, int dev) { /* @@ -73,8 +79,7 @@ static int pcie_valid_config(struct pcie_port *pp, int bus, int dev) static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 *val) { - struct pci_sys_data *sys = bus->sysdata; - struct pcie_port *pp = sys->private_data; + struct pcie_port *pp = bus_to_port(bus); unsigned long flags; int ret; @@ -93,8 +98,7 @@ static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, static int pcie_wr_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 val) { - struct pci_sys_data *sys = bus->sysdata; - struct pcie_port *pp = sys->private_data; + struct pcie_port *pp = bus_to_port(bus); unsigned long flags; int ret; @@ -244,13 +248,13 @@ kirkwood_pcie_scan_bus(int nr, struct pci_sys_data *sys) static int __init kirkwood_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - struct pci_sys_data *sys = dev->sysdata; - struct pcie_port *pp = sys->private_data; + struct pcie_port *pp = bus_to_port(dev->bus); return pp->irq; } static struct hw_pci kirkwood_pci __initdata = { + .swizzle = pci_std_swizzle, .setup = kirkwood_pcie_setup, .scan = kirkwood_pcie_scan_bus, .map_irq = kirkwood_pcie_map_irq, diff --git a/trunk/arch/arm/mach-ks8695/pci.c b/trunk/arch/arm/mach-ks8695/pci.c index bb18193b4bac..acc701435817 100644 --- a/trunk/arch/arm/mach-ks8695/pci.c +++ b/trunk/arch/arm/mach-ks8695/pci.c @@ -141,6 +141,12 @@ static struct pci_ops ks8695_pci_ops = { .write = ks8695_pci_writeconfig, }; +static struct pci_bus* __init ks8695_pci_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_root_bus(NULL, sys->busnr, &ks8695_pci_ops, sys, + &sys->resources); +} + static struct resource pci_mem = { .name = "PCI Memory space", .start = KS8695_PCIMEM_PA, @@ -296,10 +302,11 @@ static void ks8695_show_pciregs(void) static struct hw_pci ks8695_pci __initdata = { .nr_controllers = 1, - .ops = &ks8695_pci_ops, .preinit = ks8695_pci_preinit, .setup = ks8695_pci_setup, + .scan = ks8695_pci_scan_bus, .postinit = NULL, + .swizzle = pci_std_swizzle, .map_irq = NULL, }; diff --git a/trunk/arch/arm/mach-mv78xx0/pcie.c b/trunk/arch/arm/mach-mv78xx0/pcie.c index 2e56e86b6d68..df3e38055a24 100644 --- a/trunk/arch/arm/mach-mv78xx0/pcie.c +++ b/trunk/arch/arm/mach-mv78xx0/pcie.c @@ -147,7 +147,6 @@ static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys) return 0; pp = &pcie_port[nr]; - sys->private_data = pp; pp->root_bus_nr = sys->busnr; /* @@ -162,6 +161,19 @@ static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys) return 1; } +static struct pcie_port *bus_to_port(int bus) +{ + int i; + + for (i = num_pcie_ports - 1; i >= 0; i--) { + int rbus = pcie_port[i].root_bus_nr; + if (rbus != -1 && rbus <= bus) + break; + } + + return i >= 0 ? pcie_port + i : NULL; +} + static int pcie_valid_config(struct pcie_port *pp, int bus, int dev) { /* @@ -177,8 +189,7 @@ static int pcie_valid_config(struct pcie_port *pp, int bus, int dev) static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 *val) { - struct pci_sys_data *sys = bus->sysdata; - struct pcie_port *pp = sys->private_data; + struct pcie_port *pp = bus_to_port(bus->number); unsigned long flags; int ret; @@ -197,8 +208,7 @@ static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, static int pcie_wr_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 val) { - struct pci_sys_data *sys = bus->sysdata; - struct pcie_port *pp = sys->private_data; + struct pcie_port *pp = bus_to_port(bus->number); unsigned long flags; int ret; @@ -253,8 +263,7 @@ mv78xx0_pcie_scan_bus(int nr, struct pci_sys_data *sys) static int __init mv78xx0_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - struct pci_sys_data *sys = dev->bus->sysdata; - struct pcie_port *pp = sys->private_data; + struct pcie_port *pp = bus_to_port(dev->bus->number); return IRQ_MV78XX0_PCIE_00 + (pp->maj << 2) + pp->min; } @@ -262,6 +271,7 @@ static int __init mv78xx0_pcie_map_irq(const struct pci_dev *dev, u8 slot, static struct hw_pci mv78xx0_pci __initdata = { .nr_controllers = 8, .preinit = mv78xx0_pcie_preinit, + .swizzle = pci_std_swizzle, .setup = mv78xx0_pcie_setup, .scan = mv78xx0_pcie_scan_bus, .map_irq = mv78xx0_pcie_map_irq, diff --git a/trunk/arch/arm/mach-mxs/devices-mx23.h b/trunk/arch/arm/mach-mxs/devices-mx23.h index 9acdd6387047..4d1329d59287 100644 --- a/trunk/arch/arm/mach-mxs/devices-mx23.h +++ b/trunk/arch/arm/mach-mxs/devices-mx23.h @@ -11,16 +11,10 @@ #include #include #include -#include -static inline int mx23_add_duart(void) -{ - struct amba_device *d; - - d = amba_ahb_device_add(NULL, "duart", MX23_DUART_BASE_ADDR, SZ_8K, - MX23_INT_DUART, 0, 0, 0); - return IS_ERR(d) ? PTR_ERR(d) : 0; -} +extern const struct amba_device mx23_duart_device __initconst; +#define mx23_add_duart() \ + mxs_add_duart(&mx23_duart_device) extern const struct mxs_auart_data mx23_auart_data[] __initconst; #define mx23_add_auart(id) mxs_add_auart(&mx23_auart_data[id]) diff --git a/trunk/arch/arm/mach-mxs/devices-mx28.h b/trunk/arch/arm/mach-mxs/devices-mx28.h index 84b2960df117..9dbeae130842 100644 --- a/trunk/arch/arm/mach-mxs/devices-mx28.h +++ b/trunk/arch/arm/mach-mxs/devices-mx28.h @@ -11,16 +11,10 @@ #include #include #include -#include -static inline int mx28_add_duart(void) -{ - struct amba_device *d; - - d = amba_ahb_device_add(NULL, "duart", MX28_DUART_BASE_ADDR, SZ_8K, - MX28_INT_DUART, 0, 0, 0); - return IS_ERR(d) ? PTR_ERR(d) : 0; -} +extern const struct amba_device mx28_duart_device __initconst; +#define mx28_add_duart() \ + mxs_add_duart(&mx28_duart_device) extern const struct mxs_auart_data mx28_auart_data[] __initconst; #define mx28_add_auart(id) mxs_add_auart(&mx28_auart_data[id]) diff --git a/trunk/arch/arm/mach-mxs/devices.c b/trunk/arch/arm/mach-mxs/devices.c index cf50b5a66dda..01faffec3064 100644 --- a/trunk/arch/arm/mach-mxs/devices.c +++ b/trunk/arch/arm/mach-mxs/devices.c @@ -75,6 +75,22 @@ struct platform_device *__init mxs_add_platform_device_dmamask( return pdev; } +int __init mxs_add_amba_device(const struct amba_device *dev) +{ + struct amba_device *adev = amba_device_alloc(dev->dev.init_name, + dev->res.start, resource_size(&dev->res)); + + if (!adev) { + pr_err("%s: failed to allocate memory", __func__); + return -ENOMEM; + } + + adev->irq[0] = dev->irq[0]; + adev->irq[1] = dev->irq[1]; + + return amba_device_add(adev, &iomem_resource); +} + struct device mxs_apbh_bus = { .init_name = "mxs_apbh", .parent = &platform_bus, diff --git a/trunk/arch/arm/mach-mxs/devices/Makefile b/trunk/arch/arm/mach-mxs/devices/Makefile index 5f72d9787444..c8f5c9541a30 100644 --- a/trunk/arch/arm/mach-mxs/devices/Makefile +++ b/trunk/arch/arm/mach-mxs/devices/Makefile @@ -1,3 +1,4 @@ +obj-$(CONFIG_MXS_HAVE_AMBA_DUART) += amba-duart.o obj-$(CONFIG_MXS_HAVE_PLATFORM_AUART) += platform-auart.o obj-y += platform-dma.o obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o diff --git a/trunk/arch/arm/mach-mxs/devices/amba-duart.c b/trunk/arch/arm/mach-mxs/devices/amba-duart.c new file mode 100644 index 000000000000..a5479f766046 --- /dev/null +++ b/trunk/arch/arm/mach-mxs/devices/amba-duart.c @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2009-2010 Pengutronix + * Uwe Kleine-Koenig + * + * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + */ +#include +#include +#include +#include + +#define MXS_AMBA_DUART_DEVICE(name, soc) \ +const struct amba_device name##_device __initconst = { \ + .dev = { \ + .init_name = "duart", \ + }, \ + .res = { \ + .start = soc ## _DUART_BASE_ADDR, \ + .end = (soc ## _DUART_BASE_ADDR) + SZ_8K - 1, \ + .flags = IORESOURCE_MEM, \ + }, \ + .irq = {soc ## _INT_DUART}, \ +} + +#ifdef CONFIG_SOC_IMX23 +MXS_AMBA_DUART_DEVICE(mx23_duart, MX23); +#endif + +#ifdef CONFIG_SOC_IMX28 +MXS_AMBA_DUART_DEVICE(mx28_duart, MX28); +#endif + +int __init mxs_add_duart(const struct amba_device *dev) +{ + return mxs_add_amba_device(dev); +} diff --git a/trunk/arch/arm/mach-mxs/include/mach/devices-common.h b/trunk/arch/arm/mach-mxs/include/mach/devices-common.h index 21e45a70d344..f2e383955d88 100644 --- a/trunk/arch/arm/mach-mxs/include/mach/devices-common.h +++ b/trunk/arch/arm/mach-mxs/include/mach/devices-common.h @@ -27,6 +27,11 @@ static inline struct platform_device *mxs_add_platform_device( name, id, res, num_resources, data, size_data, 0); } +int __init mxs_add_amba_device(const struct amba_device *dev); + +/* duart */ +int __init mxs_add_duart(const struct amba_device *dev); + /* auart */ struct mxs_auart_data { int id; diff --git a/trunk/arch/arm/mach-omap1/ams-delta-fiq.c b/trunk/arch/arm/mach-omap1/ams-delta-fiq.c index cfd98b186fcc..fcce7ff37630 100644 --- a/trunk/arch/arm/mach-omap1/ams-delta-fiq.c +++ b/trunk/arch/arm/mach-omap1/ams-delta-fiq.c @@ -48,7 +48,7 @@ static irqreturn_t deferred_fiq(int irq, void *dev_id) struct irq_chip *irq_chip = NULL; int gpio, irq_num, fiq_count; - irq_desc = irq_to_desc(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK)); + irq_desc = irq_to_desc(IH_GPIO_BASE); if (irq_desc) irq_chip = irq_desc->irq_data.chip; diff --git a/trunk/arch/arm/mach-omap2/board-igep0020.c b/trunk/arch/arm/mach-omap2/board-igep0020.c index 740cee9369ba..930c0d380435 100644 --- a/trunk/arch/arm/mach-omap2/board-igep0020.c +++ b/trunk/arch/arm/mach-omap2/board-igep0020.c @@ -641,7 +641,7 @@ static struct regulator_consumer_supply dummy_supplies[] = { static void __init igep_init(void) { - regulator_register_fixed(1, dummy_supplies, ARRAY_SIZE(dummy_supplies)); + regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); /* Get IGEP2 hardware revision */ diff --git a/trunk/arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h b/trunk/arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h index c88420de1151..1e2d3322f33e 100644 --- a/trunk/arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h +++ b/trunk/arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h @@ -941,10 +941,10 @@ #define OMAP4_DSI2_LANEENABLE_MASK (0x7 << 29) #define OMAP4_DSI1_LANEENABLE_SHIFT 24 #define OMAP4_DSI1_LANEENABLE_MASK (0x1f << 24) -#define OMAP4_DSI1_PIPD_SHIFT 19 -#define OMAP4_DSI1_PIPD_MASK (0x1f << 19) -#define OMAP4_DSI2_PIPD_SHIFT 14 -#define OMAP4_DSI2_PIPD_MASK (0x1f << 14) +#define OMAP4_DSI2_PIPD_SHIFT 19 +#define OMAP4_DSI2_PIPD_MASK (0x1f << 19) +#define OMAP4_DSI1_PIPD_SHIFT 14 +#define OMAP4_DSI1_PIPD_MASK (0x1f << 14) /* CONTROL_MCBSPLP */ #define OMAP4_ALBCTRLRX_FSX_SHIFT 31 diff --git a/trunk/arch/arm/mach-orion5x/db88f5281-setup.c b/trunk/arch/arm/mach-orion5x/db88f5281-setup.c index 49a3fd630313..e52108c9aaea 100644 --- a/trunk/arch/arm/mach-orion5x/db88f5281-setup.c +++ b/trunk/arch/arm/mach-orion5x/db88f5281-setup.c @@ -265,6 +265,7 @@ static int __init db88f5281_pci_map_irq(const struct pci_dev *dev, u8 slot, static struct hw_pci db88f5281_pci __initdata = { .nr_controllers = 2, .preinit = db88f5281_pci_preinit, + .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = db88f5281_pci_map_irq, diff --git a/trunk/arch/arm/mach-orion5x/dns323-setup.c b/trunk/arch/arm/mach-orion5x/dns323-setup.c index 8c06ccac44c2..c3ed15b8ea25 100644 --- a/trunk/arch/arm/mach-orion5x/dns323-setup.c +++ b/trunk/arch/arm/mach-orion5x/dns323-setup.c @@ -86,6 +86,7 @@ static int __init dns323_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) static struct hw_pci dns323_pci __initdata = { .nr_controllers = 2, + .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = dns323_pci_map_irq, diff --git a/trunk/arch/arm/mach-orion5x/kurobox_pro-setup.c b/trunk/arch/arm/mach-orion5x/kurobox_pro-setup.c index 1e458efafb9a..47587b832842 100644 --- a/trunk/arch/arm/mach-orion5x/kurobox_pro-setup.c +++ b/trunk/arch/arm/mach-orion5x/kurobox_pro-setup.c @@ -138,6 +138,7 @@ static int __init kurobox_pro_pci_map_irq(const struct pci_dev *dev, u8 slot, static struct hw_pci kurobox_pro_pci __initdata = { .nr_controllers = 2, + .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = kurobox_pro_pci_map_irq, diff --git a/trunk/arch/arm/mach-orion5x/mpp.h b/trunk/arch/arm/mach-orion5x/mpp.h index db70e79a1198..eac68978a2c2 100644 --- a/trunk/arch/arm/mach-orion5x/mpp.h +++ b/trunk/arch/arm/mach-orion5x/mpp.h @@ -65,8 +65,8 @@ #define MPP8_GIGE MPP(8, 0x1, 0, 0, 1, 1, 1) #define MPP9_UNUSED MPP(9, 0x0, 0, 0, 1, 1, 1) -#define MPP9_GPIO MPP(9, 0x0, 1, 1, 1, 1, 1) -#define MPP9_GIGE MPP(9, 0x1, 0, 0, 1, 1, 1) +#define MPP9_GPIO MPP(9, 0x0, 0, 0, 1, 1, 1) +#define MPP9_GIGE MPP(9, 0x1, 1, 1, 1, 1, 1) #define MPP10_UNUSED MPP(10, 0x0, 0, 0, 1, 1, 1) #define MPP10_GPIO MPP(10, 0x0, 1, 1, 1, 1, 1) diff --git a/trunk/arch/arm/mach-orion5x/mss2-setup.c b/trunk/arch/arm/mach-orion5x/mss2-setup.c index 1c16d045333e..65faaa34de61 100644 --- a/trunk/arch/arm/mach-orion5x/mss2-setup.c +++ b/trunk/arch/arm/mach-orion5x/mss2-setup.c @@ -89,6 +89,7 @@ static int __init mss2_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) static struct hw_pci mss2_pci __initdata = { .nr_controllers = 2, + .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = mss2_pci_map_irq, diff --git a/trunk/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c b/trunk/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c index 78a6a11d8216..292038fc59fd 100644 --- a/trunk/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c +++ b/trunk/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c @@ -149,6 +149,7 @@ rd88f5181l_fxo_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) static struct hw_pci rd88f5181l_fxo_pci __initdata = { .nr_controllers = 2, + .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = rd88f5181l_fxo_pci_map_irq, diff --git a/trunk/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c b/trunk/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c index 2f5dc54cd4cd..c44eabaabc16 100644 --- a/trunk/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c +++ b/trunk/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c @@ -161,6 +161,7 @@ rd88f5181l_ge_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) static struct hw_pci rd88f5181l_ge_pci __initdata = { .nr_controllers = 2, + .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = rd88f5181l_ge_pci_map_irq, diff --git a/trunk/arch/arm/mach-orion5x/rd88f5182-setup.c b/trunk/arch/arm/mach-orion5x/rd88f5182-setup.c index 399130fac0b6..e3ce61711478 100644 --- a/trunk/arch/arm/mach-orion5x/rd88f5182-setup.c +++ b/trunk/arch/arm/mach-orion5x/rd88f5182-setup.c @@ -200,6 +200,7 @@ static int __init rd88f5182_pci_map_irq(const struct pci_dev *dev, u8 slot, static struct hw_pci rd88f5182_pci __initdata = { .nr_controllers = 2, .preinit = rd88f5182_pci_preinit, + .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = rd88f5182_pci_map_irq, diff --git a/trunk/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c b/trunk/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c index e91bf0ba4e8e..2c5fab00d205 100644 --- a/trunk/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c +++ b/trunk/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c @@ -102,6 +102,7 @@ static void __init rd88f6183ap_ge_init(void) static struct hw_pci rd88f6183ap_ge_pci __initdata = { .nr_controllers = 2, + .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = orion5x_pci_map_irq, diff --git a/trunk/arch/arm/mach-orion5x/terastation_pro2-setup.c b/trunk/arch/arm/mach-orion5x/terastation_pro2-setup.c index 90e571dc4deb..632a861ef82b 100644 --- a/trunk/arch/arm/mach-orion5x/terastation_pro2-setup.c +++ b/trunk/arch/arm/mach-orion5x/terastation_pro2-setup.c @@ -122,6 +122,7 @@ static int __init tsp2_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) static struct hw_pci tsp2_pci __initdata = { .nr_controllers = 2, .preinit = tsp2_pci_preinit, + .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = tsp2_pci_map_irq, diff --git a/trunk/arch/arm/mach-orion5x/ts209-setup.c b/trunk/arch/arm/mach-orion5x/ts209-setup.c index b184f680e0db..5d6408745582 100644 --- a/trunk/arch/arm/mach-orion5x/ts209-setup.c +++ b/trunk/arch/arm/mach-orion5x/ts209-setup.c @@ -170,6 +170,7 @@ static int __init qnap_ts209_pci_map_irq(const struct pci_dev *dev, u8 slot, static struct hw_pci qnap_ts209_pci __initdata = { .nr_controllers = 2, .preinit = qnap_ts209_pci_preinit, + .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = qnap_ts209_pci_map_irq, diff --git a/trunk/arch/arm/mach-orion5x/ts409-setup.c b/trunk/arch/arm/mach-orion5x/ts409-setup.c index a5c2e64c4ece..4e6ff759cd32 100644 --- a/trunk/arch/arm/mach-orion5x/ts409-setup.c +++ b/trunk/arch/arm/mach-orion5x/ts409-setup.c @@ -140,6 +140,7 @@ static int __init qnap_ts409_pci_map_irq(const struct pci_dev *dev, u8 slot, static struct hw_pci qnap_ts409_pci __initdata = { .nr_controllers = 2, + .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = qnap_ts409_pci_map_irq, diff --git a/trunk/arch/arm/mach-orion5x/wnr854t-setup.c b/trunk/arch/arm/mach-orion5x/wnr854t-setup.c index 754c12b6abf0..078c03f7cd52 100644 --- a/trunk/arch/arm/mach-orion5x/wnr854t-setup.c +++ b/trunk/arch/arm/mach-orion5x/wnr854t-setup.c @@ -155,6 +155,7 @@ static int __init wnr854t_pci_map_irq(const struct pci_dev *dev, u8 slot, static struct hw_pci wnr854t_pci __initdata = { .nr_controllers = 2, + .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = wnr854t_pci_map_irq, diff --git a/trunk/arch/arm/mach-orion5x/wrt350n-v2-setup.c b/trunk/arch/arm/mach-orion5x/wrt350n-v2-setup.c index 45c21251eb1e..46a9778171ce 100644 --- a/trunk/arch/arm/mach-orion5x/wrt350n-v2-setup.c +++ b/trunk/arch/arm/mach-orion5x/wrt350n-v2-setup.c @@ -243,6 +243,7 @@ static int __init wrt350n_v2_pci_map_irq(const struct pci_dev *dev, u8 slot, static struct hw_pci wrt350n_v2_pci __initdata = { .nr_controllers = 2, + .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = wrt350n_v2_pci_map_irq, diff --git a/trunk/arch/arm/mach-prima2/irq.c b/trunk/arch/arm/mach-prima2/irq.c index a7b9415d30f8..37c2de9b6f26 100644 --- a/trunk/arch/arm/mach-prima2/irq.c +++ b/trunk/arch/arm/mach-prima2/irq.c @@ -42,8 +42,7 @@ sirfsoc_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) static __init void sirfsoc_irq_init(void) { sirfsoc_alloc_gc(sirfsoc_intc_base, 0, 32); - sirfsoc_alloc_gc(sirfsoc_intc_base + 4, 32, - SIRFSOC_INTENAL_IRQ_END + 1 - 32); + sirfsoc_alloc_gc(sirfsoc_intc_base + 4, 32, SIRFSOC_INTENAL_IRQ_END - 32); writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL0); writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL1); @@ -69,8 +68,7 @@ void __init sirfsoc_of_irq_init(void) if (!sirfsoc_intc_base) panic("unable to map intc cpu registers\n"); - irq_domain_add_legacy(np, SIRFSOC_INTENAL_IRQ_END + 1, 0, 0, - &irq_domain_simple_ops, NULL); + irq_domain_add_legacy(np, 32, 0, 0, &irq_domain_simple_ops, NULL); of_node_put(np); diff --git a/trunk/arch/arm/mach-pxa/cm-x2xx-pci.c b/trunk/arch/arm/mach-pxa/cm-x2xx-pci.c index d8f816c24a2f..ebd9259f5ac9 100644 --- a/trunk/arch/arm/mach-pxa/cm-x2xx-pci.c +++ b/trunk/arch/arm/mach-pxa/cm-x2xx-pci.c @@ -181,10 +181,11 @@ static void cmx2xx_pci_preinit(void) } static struct hw_pci cmx2xx_pci __initdata = { + .swizzle = pci_std_swizzle, .map_irq = cmx2xx_pci_map_irq, .nr_controllers = 1, - .ops = &it8152_ops, .setup = it8152_pci_setup, + .scan = it8152_pci_scan_bus, .preinit = cmx2xx_pci_preinit, }; diff --git a/trunk/arch/arm/mach-sa1100/pci-nanoengine.c b/trunk/arch/arm/mach-sa1100/pci-nanoengine.c index ff02e2da99f2..b49108b890a8 100644 --- a/trunk/arch/arm/mach-sa1100/pci-nanoengine.c +++ b/trunk/arch/arm/mach-sa1100/pci-nanoengine.c @@ -129,6 +129,12 @@ static int __init pci_nanoengine_map_irq(const struct pci_dev *dev, u8 slot, return NANOENGINE_IRQ_GPIO_PCI; } +struct pci_bus * __init pci_nanoengine_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_root_bus(NULL, sys->busnr, &pci_nano_ops, sys, + &sys->resources); +} + static struct resource pci_io_ports = DEFINE_RES_IO_NAMED(0x400, 0x400, "PCI IO"); @@ -268,7 +274,7 @@ int __init pci_nanoengine_setup(int nr, struct pci_sys_data *sys) static struct hw_pci nanoengine_pci __initdata = { .map_irq = pci_nanoengine_map_irq, .nr_controllers = 1, - .ops = &pci_nano_ops, + .scan = pci_nanoengine_scan_bus, .setup = pci_nanoengine_setup, }; diff --git a/trunk/arch/arm/mach-shark/pci.c b/trunk/arch/arm/mach-shark/pci.c index 9089407d5326..7cb79a092f31 100644 --- a/trunk/arch/arm/mach-shark/pci.c +++ b/trunk/arch/arm/mach-shark/pci.c @@ -29,9 +29,10 @@ extern void __init via82c505_preinit(void); static struct hw_pci shark_pci __initdata = { .setup = via82c505_setup, + .swizzle = pci_std_swizzle, .map_irq = shark_map_irq, .nr_controllers = 1, - .ops = &via82c505_ops, + .scan = via82c505_scan_bus, .preinit = via82c505_preinit, }; diff --git a/trunk/arch/arm/mach-shmobile/board-ag5evm.c b/trunk/arch/arm/mach-shmobile/board-ag5evm.c index 0891ec6e27f5..cb224a344af0 100644 --- a/trunk/arch/arm/mach-shmobile/board-ag5evm.c +++ b/trunk/arch/arm/mach-shmobile/board-ag5evm.c @@ -365,13 +365,23 @@ static struct platform_device mipidsi0_device = { }; /* SDHI0 */ +static irqreturn_t ag5evm_sdhi0_gpio_cd(int irq, void *arg) +{ + struct device *dev = arg; + struct sh_mobile_sdhi_info *info = dev->platform_data; + struct tmio_mmc_data *pdata = info->pdata; + + tmio_mmc_cd_wakeup(pdata); + + return IRQ_HANDLED; +} + static struct sh_mobile_sdhi_info sdhi0_info = { .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, - .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_USE_GPIO_CD, + .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT, .tmio_caps = MMC_CAP_SD_HIGHSPEED, .tmio_ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29, - .cd_gpio = GPIO_PORT251, }; static struct resource sdhi0_resources[] = { @@ -547,6 +557,7 @@ static void __init ag5evm_init(void) lcd_backlight_reset(); /* enable SDHI0 on CN15 [SD I/F] */ + gpio_request(GPIO_FN_SDHICD0, NULL); gpio_request(GPIO_FN_SDHIWP0, NULL); gpio_request(GPIO_FN_SDHICMD0, NULL); gpio_request(GPIO_FN_SDHICLK0, NULL); @@ -555,6 +566,13 @@ static void __init ag5evm_init(void) gpio_request(GPIO_FN_SDHID0_1, NULL); gpio_request(GPIO_FN_SDHID0_0, NULL); + if (!request_irq(intcs_evt2irq(0x3c0), ag5evm_sdhi0_gpio_cd, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + "sdhi0 cd", &sdhi0_device.dev)) + sdhi0_info.tmio_flags |= TMIO_MMC_HAS_COLD_CD; + else + pr_warn("Unable to setup SDHI0 GPIO IRQ\n"); + /* enable SDHI1 on CN4 [WLAN I/F] */ gpio_request(GPIO_FN_SDHICLK1, NULL); gpio_request(GPIO_FN_SDHICMD1_PU, NULL); diff --git a/trunk/arch/arm/mach-shmobile/board-mackerel.c b/trunk/arch/arm/mach-shmobile/board-mackerel.c index 8c6202bb6aeb..f49e28abe0ab 100644 --- a/trunk/arch/arm/mach-shmobile/board-mackerel.c +++ b/trunk/arch/arm/mach-shmobile/board-mackerel.c @@ -1011,12 +1011,21 @@ static int slot_cn7_get_cd(struct platform_device *pdev) } /* SDHI0 */ +static irqreturn_t mackerel_sdhi0_gpio_cd(int irq, void *arg) +{ + struct device *dev = arg; + struct sh_mobile_sdhi_info *info = dev->platform_data; + struct tmio_mmc_data *pdata = info->pdata; + + tmio_mmc_cd_wakeup(pdata); + + return IRQ_HANDLED; +} + static struct sh_mobile_sdhi_info sdhi0_info = { .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, - .tmio_flags = TMIO_MMC_USE_GPIO_CD, .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ, - .cd_gpio = GPIO_PORT172, }; static struct resource sdhi0_resources[] = { @@ -1375,6 +1384,7 @@ static void __init mackerel_init(void) { u32 srcr4; struct clk *clk; + int ret; /* External clock source */ clk_set_rate(&sh7372_dv_clki_clk, 27000000); @@ -1471,6 +1481,7 @@ static void __init mackerel_init(void) irq_set_irq_type(IRQ21, IRQ_TYPE_LEVEL_HIGH); /* enable SDHI0 */ + gpio_request(GPIO_FN_SDHICD0, NULL); gpio_request(GPIO_FN_SDHIWP0, NULL); gpio_request(GPIO_FN_SDHICMD0, NULL); gpio_request(GPIO_FN_SDHICLK0, NULL); @@ -1479,6 +1490,13 @@ static void __init mackerel_init(void) gpio_request(GPIO_FN_SDHID0_1, NULL); gpio_request(GPIO_FN_SDHID0_0, NULL); + ret = request_irq(evt2irq(0x3340), mackerel_sdhi0_gpio_cd, + IRQF_TRIGGER_FALLING, "sdhi0 cd", &sdhi0_device.dev); + if (!ret) + sdhi0_info.tmio_flags |= TMIO_MMC_HAS_COLD_CD; + else + pr_err("Cannot get IRQ #%d: %d\n", evt2irq(0x3340), ret); + #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) /* enable SDHI1 */ gpio_request(GPIO_FN_SDHICMD1, NULL); diff --git a/trunk/arch/arm/mach-shmobile/headsmp.S b/trunk/arch/arm/mach-shmobile/headsmp.S index b202c1272526..6ac015c89206 100644 --- a/trunk/arch/arm/mach-shmobile/headsmp.S +++ b/trunk/arch/arm/mach-shmobile/headsmp.S @@ -16,59 +16,6 @@ __CPUINIT -/* Cache invalidation nicked from arch/arm/mach-imx/head-v7.S, thanks! - * - * The secondary kernel init calls v7_flush_dcache_all before it enables - * the L1; however, the L1 comes out of reset in an undefined state, so - * the clean + invalidate performed by v7_flush_dcache_all causes a bunch - * of cache lines with uninitialized data and uninitialized tags to get - * written out to memory, which does really unpleasant things to the main - * processor. We fix this by performing an invalidate, rather than a - * clean + invalidate, before jumping into the kernel. - * - * This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and needs - * to be called for both secondary cores startup and primary core resume - * procedures. Ideally, it should be moved into arch/arm/mm/cache-v7.S. - */ -ENTRY(v7_invalidate_l1) - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache - mcr p15, 2, r0, c0, c0, 0 - mrc p15, 1, r0, c0, c0, 0 - - ldr r1, =0x7fff - and r2, r1, r0, lsr #13 - - ldr r1, =0x3ff - - and r3, r1, r0, lsr #3 @ NumWays - 1 - add r2, r2, #1 @ NumSets - - and r0, r0, #0x7 - add r0, r0, #4 @ SetShift - - clz r1, r3 @ WayShift - add r4, r3, #1 @ NumWays -1: sub r2, r2, #1 @ NumSets-- - mov r3, r4 @ Temp = NumWays -2: subs r3, r3, #1 @ Temp-- - mov r5, r3, lsl r1 - mov r6, r2, lsl r0 - orr r5, r5, r6 @ Reg = (Temp< #include #include +#include #include @@ -18,6 +19,38 @@ #include "devices-common.h" +struct amba_device * +dbx500_add_amba_device(struct device *parent, const char *name, + resource_size_t base, int irq, void *pdata, + unsigned int periphid) +{ + struct amba_device *dev; + int ret; + + dev = amba_device_alloc(name, base, SZ_4K); + if (!dev) + return ERR_PTR(-ENOMEM); + + dev->dma_mask = DMA_BIT_MASK(32); + dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); + + dev->irq[0] = irq; + + dev->periphid = periphid; + + dev->dev.platform_data = pdata; + + dev->dev.parent = parent; + + ret = amba_device_add(dev, &iomem_resource); + if (ret) { + amba_device_put(dev); + return ERR_PTR(ret); + } + + return dev; +} + static struct platform_device * dbx500_add_gpio(struct device *parent, int id, resource_size_t addr, int irq, struct nmk_gpio_platform_data *pdata) diff --git a/trunk/arch/arm/mach-ux500/devices-common.h b/trunk/arch/arm/mach-ux500/devices-common.h index f75bcb2ab13b..39c74ec82add 100644 --- a/trunk/arch/arm/mach-ux500/devices-common.h +++ b/trunk/arch/arm/mach-ux500/devices-common.h @@ -11,9 +11,13 @@ #include #include #include -#include #include +extern struct amba_device * +dbx500_add_amba_device(struct device *parent, const char *name, + resource_size_t base, int irq, void *pdata, + unsigned int periphid); + struct spi_master_cntlr; static inline struct amba_device * @@ -21,8 +25,8 @@ dbx500_add_msp_spi(struct device *parent, const char *name, resource_size_t base, int irq, struct spi_master_cntlr *pdata) { - return amba_ahb_device_add(parent, name, base, SZ_4K, irq, 0, - pdata, 0); + return dbx500_add_amba_device(parent, name, base, irq, + pdata, 0); } static inline struct amba_device * @@ -30,8 +34,8 @@ dbx500_add_spi(struct device *parent, const char *name, resource_size_t base, int irq, struct spi_master_cntlr *pdata, u32 periphid) { - return amba_ahb_device_add(parent, name, base, SZ_4K, irq, 0, - pdata, periphid); + return dbx500_add_amba_device(parent, name, base, irq, + pdata, periphid); } struct mmci_platform_data; @@ -40,8 +44,8 @@ static inline struct amba_device * dbx500_add_sdi(struct device *parent, const char *name, resource_size_t base, int irq, struct mmci_platform_data *pdata, u32 periphid) { - return amba_ahb_device_add(parent, name, base, SZ_4K, irq, 0, - pdata, periphid); + return dbx500_add_amba_device(parent, name, base, irq, + pdata, periphid); } struct amba_pl011_data; @@ -50,7 +54,7 @@ static inline struct amba_device * dbx500_add_uart(struct device *parent, const char *name, resource_size_t base, int irq, struct amba_pl011_data *pdata) { - return amba_ahb_device_add(parent, name, base, SZ_4K, irq, 0, pdata, 0); + return dbx500_add_amba_device(parent, name, base, irq, pdata, 0); } struct nmk_i2c_controller; @@ -81,8 +85,7 @@ dbx500_add_i2c(struct device *parent, int id, resource_size_t base, int irq, static inline struct amba_device * dbx500_add_rtc(struct device *parent, resource_size_t base, int irq) { - return amba_apb_device_add(parent, "rtc-pl031", base, SZ_4K, irq, - 0, NULL, 0); + return dbx500_add_amba_device(parent, "rtc-pl031", base, irq, NULL, 0); } struct nmk_gpio_platform_data; diff --git a/trunk/arch/arm/mach-ux500/devices-db8500.h b/trunk/arch/arm/mach-ux500/devices-db8500.h index 6fc7eb24d9a0..9fd93e9da529 100644 --- a/trunk/arch/arm/mach-ux500/devices-db8500.h +++ b/trunk/arch/arm/mach-ux500/devices-db8500.h @@ -31,7 +31,7 @@ static inline struct amba_device * db8500_add_ssp(struct device *parent, const char *name, resource_size_t base, int irq, struct pl022_ssp_controller *pdata) { - return amba_ahb_device_add(parent, name, base, SZ_4K, irq, 0, pdata, 0); + return dbx500_add_amba_device(parent, name, base, irq, pdata, 0); } diff --git a/trunk/arch/arm/mach-versatile/core.c b/trunk/arch/arm/mach-versatile/core.c index cf4687ee2a7b..6bbd74e950ab 100644 --- a/trunk/arch/arm/mach-versatile/core.c +++ b/trunk/arch/arm/mach-versatile/core.c @@ -66,6 +66,12 @@ #define VA_VIC_BASE __io_address(VERSATILE_VIC_BASE) #define VA_SIC_BASE __io_address(VERSATILE_SIC_BASE) +static struct fpga_irq_data sic_irq = { + .base = VA_SIC_BASE, + .irq_start = IRQ_SIC_START, + .chip.name = "SIC", +}; + #if 1 #define IRQ_MMCI0A IRQ_VICSOURCE22 #define IRQ_AACI IRQ_VICSOURCE24 @@ -99,11 +105,8 @@ void __init versatile_init_irq(void) writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); - np = of_find_matching_node_by_address(NULL, sic_of_match, - VERSATILE_SIC_BASE); - - fpga_irq_init(VA_SIC_BASE, "SIC", IRQ_SIC_START, - IRQ_VICSOURCE31, ~PIC_MASK, np); + fpga_irq_init(IRQ_VICSOURCE31, ~PIC_MASK, &sic_irq); + irq_domain_generate_simple(sic_of_match, VERSATILE_SIC_BASE, IRQ_SIC_START); /* * Interrupts on secondary controller from 0 to 8 are routed to @@ -663,18 +666,17 @@ static struct amba_device *amba_devs[] __initdata = { * having a specific name. */ struct of_dev_auxdata versatile_auxdata_lookup[] __initdata = { - OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI0_BASE, "fpga:05", &mmc0_plat_data), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI0_BASE, "fpga:05", NULL), OF_DEV_AUXDATA("arm,primecell", VERSATILE_KMI0_BASE, "fpga:06", NULL), OF_DEV_AUXDATA("arm,primecell", VERSATILE_KMI1_BASE, "fpga:07", NULL), OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART3_BASE, "fpga:09", NULL), - /* FIXME: this is buggy, the platform data is needed for this MMC instance too */ OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI1_BASE, "fpga:0b", NULL), OF_DEV_AUXDATA("arm,primecell", VERSATILE_CLCD_BASE, "dev:20", &clcd_plat_data), OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART0_BASE, "dev:f1", NULL), OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART1_BASE, "dev:f2", NULL), OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART2_BASE, "dev:f3", NULL), - OF_DEV_AUXDATA("arm,primecell", VERSATILE_SSP_BASE, "dev:f4", &ssp0_plat_data), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_SSP_BASE, "dev:f4", NULL), #if 0 /* diff --git a/trunk/arch/arm/mach-versatile/pci.c b/trunk/arch/arm/mach-versatile/pci.c index 15c6a00000ec..d2268be8c34c 100644 --- a/trunk/arch/arm/mach-versatile/pci.c +++ b/trunk/arch/arm/mach-versatile/pci.c @@ -303,6 +303,12 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys) } +struct pci_bus * __init pci_versatile_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_root_bus(NULL, sys->busnr, &pci_versatile_ops, sys, + &sys->resources); +} + void __init pci_versatile_preinit(void) { pcibios_min_io = 0x44000000; @@ -333,16 +339,19 @@ static int __init versatile_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) * 26 1 29 * 27 1 30 */ - irq = 27 + ((slot - 24 + pin - 1) & 3); + irq = 27 + ((slot + pin - 1) & 3); + + printk("PCI map irq: slot %d, pin %d, devslot %d, irq: %d\n",slot,pin,devslot,irq); return irq; } static struct hw_pci versatile_pci __initdata = { + .swizzle = NULL, .map_irq = versatile_map_irq, .nr_controllers = 1, - .ops = &pci_versatile_ops, .setup = pci_versatile_setup, + .scan = pci_versatile_scan_bus, .preinit = pci_versatile_preinit, }; diff --git a/trunk/arch/arm/mach-vexpress/v2m.c b/trunk/arch/arm/mach-vexpress/v2m.c index 04dd092211b8..47cdcca5a7e7 100644 --- a/trunk/arch/arm/mach-vexpress/v2m.c +++ b/trunk/arch/arm/mach-vexpress/v2m.c @@ -19,10 +19,8 @@ #include #include -#include #include #include -#include #include #include #include @@ -618,6 +616,7 @@ void __init v2m_dt_init_early(void) } clkdev_add_table(v2m_dt_lookups, ARRAY_SIZE(v2m_dt_lookups)); + versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000); } static struct of_device_id vexpress_irq_match[] __initdata = { @@ -644,11 +643,6 @@ static void __init v2m_dt_timer_init(void) return; node = of_find_node_by_path(path); v2m_sp804_init(of_iomap(node, 0), irq_of_parse_and_map(node, 0)); - if (arch_timer_of_register() != 0) - twd_local_timer_of_register(); - - if (arch_timer_sched_clock_init() != 0) - versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000); } static struct sys_timer v2m_dt_timer = { diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig index 101b9681c08c..7c8a7d8467bf 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -4,6 +4,23 @@ comment "Processor Type" # which CPUs we support in the kernel image, and the compiler instruction # optimiser behaviour. +# ARM610 +config CPU_ARM610 + bool "Support ARM610 processor" if ARCH_RPC + select CPU_32v3 + select CPU_CACHE_V3 + select CPU_CACHE_VIVT + select CPU_CP15_MMU + select CPU_COPY_V3 if MMU + select CPU_TLB_V3 if MMU + select CPU_PABRT_LEGACY + help + The ARM610 is the successor to the ARM3 processor + and was produced by VLSI Technology Inc. + + Say Y if you want support for the ARM610 processor. + Otherwise, say N. + # ARM7TDMI config CPU_ARM7TDMI bool "Support ARM7TDMI processor" @@ -19,6 +36,25 @@ config CPU_ARM7TDMI Say Y if you want support for the ARM7TDMI processor. Otherwise, say N. +# ARM710 +config CPU_ARM710 + bool "Support ARM710 processor" if ARCH_RPC + select CPU_32v3 + select CPU_CACHE_V3 + select CPU_CACHE_VIVT + select CPU_CP15_MMU + select CPU_COPY_V3 if MMU + select CPU_TLB_V3 if MMU + select CPU_PABRT_LEGACY + help + A 32-bit RISC microprocessor based on the ARM7 processor core + designed by Advanced RISC Machines Ltd. The ARM710 is the + successor to the ARM610 processor. It was released in + July 1994 by VLSI Technology Inc. + + Say Y if you want support for the ARM710 processor. + Otherwise, say N. + # ARM720T config CPU_ARM720T bool "Support ARM720T processor" if ARCH_INTEGRATOR @@ -494,6 +530,9 @@ config CPU_CACHE_FA if MMU # The copy-page model +config CPU_COPY_V3 + bool + config CPU_COPY_V4WT bool @@ -510,6 +549,11 @@ config CPU_COPY_V6 bool # This selects the TLB model +config CPU_TLB_V3 + bool + help + ARM Architecture Version 3 TLB. + config CPU_TLB_V4WT bool help @@ -687,7 +731,7 @@ config CPU_HIGH_VECTOR config CPU_ICACHE_DISABLE bool "Disable I-Cache (I-bit)" - depends on CPU_CP15 && !(CPU_ARM720T || CPU_ARM740T || CPU_XSCALE || CPU_XSC3) + depends on CPU_CP15 && !(CPU_ARM610 || CPU_ARM710 || CPU_ARM720T || CPU_ARM740T || CPU_XSCALE || CPU_XSC3) help Say Y here to disable the processor instruction cache. Unless you have a reason not to or are unsure, say N. diff --git a/trunk/arch/arm/mm/Makefile b/trunk/arch/arm/mm/Makefile index 8a9c4cb50a93..bca7e61928c7 100644 --- a/trunk/arch/arm/mm/Makefile +++ b/trunk/arch/arm/mm/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_CPU_CACHE_FA) += cache-fa.o AFLAGS_cache-v6.o :=-Wa,-march=armv6 AFLAGS_cache-v7.o :=-Wa,-march=armv7-a +obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o obj-$(CONFIG_CPU_COPY_V4WB) += copypage-v4wb.o obj-$(CONFIG_CPU_COPY_FEROCEON) += copypage-feroceon.o @@ -53,6 +54,7 @@ obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o obj-$(CONFIG_CPU_XSC3) += copypage-xsc3.o obj-$(CONFIG_CPU_COPY_FA) += copypage-fa.o +obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o obj-$(CONFIG_CPU_TLB_V4WB) += tlb-v4wb.o obj-$(CONFIG_CPU_TLB_V4WBI) += tlb-v4wbi.o @@ -64,6 +66,8 @@ obj-$(CONFIG_CPU_TLB_FA) += tlb-fa.o AFLAGS_tlb-v6.o :=-Wa,-march=armv6 AFLAGS_tlb-v7.o :=-Wa,-march=armv7-a +obj-$(CONFIG_CPU_ARM610) += proc-arm6_7.o +obj-$(CONFIG_CPU_ARM710) += proc-arm6_7.o obj-$(CONFIG_CPU_ARM7TDMI) += proc-arm7tdmi.o obj-$(CONFIG_CPU_ARM720T) += proc-arm720.o obj-$(CONFIG_CPU_ARM740T) += proc-arm740.o diff --git a/trunk/arch/arm/mm/cache-v3.S b/trunk/arch/arm/mm/cache-v3.S index 52e35f32eefb..c2301f226100 100644 --- a/trunk/arch/arm/mm/cache-v3.S +++ b/trunk/arch/arm/mm/cache-v3.S @@ -78,7 +78,6 @@ ENTRY(v3_coherent_kern_range) * - end - virtual end address */ ENTRY(v3_coherent_user_range) - mov r0, #0 mov pc, lr /* diff --git a/trunk/arch/arm/mm/cache-v4.S b/trunk/arch/arm/mm/cache-v4.S index 022135d2b7e4..fd9bb7addc8d 100644 --- a/trunk/arch/arm/mm/cache-v4.S +++ b/trunk/arch/arm/mm/cache-v4.S @@ -88,7 +88,6 @@ ENTRY(v4_coherent_kern_range) * - end - virtual end address */ ENTRY(v4_coherent_user_range) - mov r0, #0 mov pc, lr /* diff --git a/trunk/arch/arm/mm/cache-v4wb.S b/trunk/arch/arm/mm/cache-v4wb.S index 8f1eeae340c8..4f2c14151ccb 100644 --- a/trunk/arch/arm/mm/cache-v4wb.S +++ b/trunk/arch/arm/mm/cache-v4wb.S @@ -167,9 +167,9 @@ ENTRY(v4wb_coherent_user_range) add r0, r0, #CACHE_DLINESIZE cmp r0, r1 blo 1b - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache - mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov ip, #0 + mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB mov pc, lr diff --git a/trunk/arch/arm/mm/cache-v4wt.S b/trunk/arch/arm/mm/cache-v4wt.S index b34a5f908a82..4d7b467631ce 100644 --- a/trunk/arch/arm/mm/cache-v4wt.S +++ b/trunk/arch/arm/mm/cache-v4wt.S @@ -125,7 +125,6 @@ ENTRY(v4wt_coherent_user_range) add r0, r0, #CACHE_DLINESIZE cmp r0, r1 blo 1b - mov r0, #0 mov pc, lr /* diff --git a/trunk/arch/arm/mm/cache-v6.S b/trunk/arch/arm/mm/cache-v6.S index 4b10760c56d6..74c2e5a33a4d 100644 --- a/trunk/arch/arm/mm/cache-v6.S +++ b/trunk/arch/arm/mm/cache-v6.S @@ -12,7 +12,6 @@ #include #include #include -#include #include #include "proc-macros.S" @@ -136,6 +135,7 @@ ENTRY(v6_coherent_user_range) 1: USER( mcr p15, 0, r0, c7, c10, 1 ) @ clean D line add r0, r0, #CACHE_LINE_SIZE +2: cmp r0, r1 blo 1b #endif @@ -154,11 +154,13 @@ ENTRY(v6_coherent_user_range) /* * Fault handling for the cache operation above. If the virtual address in r0 - * isn't mapped, fail with -EFAULT. + * isn't mapped, just try the next page. */ 9001: - mov r0, #-EFAULT - mov pc, lr + mov r0, r0, lsr #12 + mov r0, r0, lsl #12 + add r0, r0, #4096 + b 2b UNWIND(.fnend ) ENDPROC(v6_coherent_user_range) ENDPROC(v6_coherent_kern_range) diff --git a/trunk/arch/arm/mm/cache-v7.S b/trunk/arch/arm/mm/cache-v7.S index 39e3fb3db801..a655d3da386d 100644 --- a/trunk/arch/arm/mm/cache-v7.S +++ b/trunk/arch/arm/mm/cache-v7.S @@ -13,7 +13,6 @@ #include #include #include -#include #include #include "proc-macros.S" @@ -199,6 +198,7 @@ ENTRY(v7_coherent_user_range) add r12, r12, r2 cmp r12, r1 blo 2b +3: mov r0, #0 ALT_SMP(mcr p15, 0, r0, c7, c1, 6) @ invalidate BTB Inner Shareable ALT_UP(mcr p15, 0, r0, c7, c5, 6) @ invalidate BTB @@ -208,11 +208,13 @@ ENTRY(v7_coherent_user_range) /* * Fault handling for the cache operation above. If the virtual address in r0 - * isn't mapped, fail with -EFAULT. + * isn't mapped, just try the next page. */ 9001: - mov r0, #-EFAULT - mov pc, lr + mov r12, r12, lsr #12 + mov r12, r12, lsl #12 + add r12, r12, #4096 + b 3b UNWIND(.fnend ) ENDPROC(v7_coherent_kern_range) ENDPROC(v7_coherent_user_range) diff --git a/trunk/arch/arm/mm/context.c b/trunk/arch/arm/mm/context.c index 806cc4f63516..ee9bb363d606 100644 --- a/trunk/arch/arm/mm/context.c +++ b/trunk/arch/arm/mm/context.c @@ -18,39 +18,30 @@ static DEFINE_RAW_SPINLOCK(cpu_asid_lock); unsigned int cpu_last_asid = ASID_FIRST_VERSION; +#ifdef CONFIG_SMP +DEFINE_PER_CPU(struct mm_struct *, current_mm); +#endif #ifdef CONFIG_ARM_LPAE -void cpu_set_reserved_ttbr0(void) -{ - unsigned long ttbl = __pa(swapper_pg_dir); - unsigned long ttbh = 0; - - /* - * Set TTBR0 to swapper_pg_dir which contains only global entries. The - * ASID is set to 0. - */ - asm volatile( - " mcrr p15, 0, %0, %1, c2 @ set TTBR0\n" - : - : "r" (ttbl), "r" (ttbh)); - isb(); +#define cpu_set_asid(asid) { \ + unsigned long ttbl, ttbh; \ + asm volatile( \ + " mrrc p15, 0, %0, %1, c2 @ read TTBR0\n" \ + " mov %1, %2, lsl #(48 - 32) @ set ASID\n" \ + " mcrr p15, 0, %0, %1, c2 @ set TTBR0\n" \ + : "=&r" (ttbl), "=&r" (ttbh) \ + : "r" (asid & ~ASID_MASK)); \ } #else -void cpu_set_reserved_ttbr0(void) -{ - u32 ttb; - /* Copy TTBR1 into TTBR0 */ - asm volatile( - " mrc p15, 0, %0, c2, c0, 1 @ read TTBR1\n" - " mcr p15, 0, %0, c2, c0, 0 @ set TTBR0\n" - : "=r" (ttb)); - isb(); -} +#define cpu_set_asid(asid) \ + asm(" mcr p15, 0, %0, c13, c0, 1\n" : : "r" (asid)) #endif /* * We fork()ed a process, and we need a new context for the child - * to run in. + * to run in. We reserve version 0 for initial tasks so we will + * always allocate an ASID. The ASID 0 is reserved for the TTBR + * register changing sequence. */ void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) { @@ -60,7 +51,9 @@ void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) static void flush_context(void) { - cpu_set_reserved_ttbr0(); + /* set the reserved ASID before flushing the TLB */ + cpu_set_asid(0); + isb(); local_flush_tlb_all(); if (icache_is_vivt_asid_tagged()) { __flush_icache_all(); @@ -105,7 +98,14 @@ static void reset_context(void *info) { unsigned int asid; unsigned int cpu = smp_processor_id(); - struct mm_struct *mm = current->active_mm; + struct mm_struct *mm = per_cpu(current_mm, cpu); + + /* + * Check if a current_mm was set on this CPU as it might still + * be in the early booting stages and using the reserved ASID. + */ + if (!mm) + return; smp_rmb(); asid = cpu_last_asid + cpu + 1; @@ -114,7 +114,8 @@ static void reset_context(void *info) set_mm_context(mm, asid); /* set the new ASID */ - cpu_switch_mm(mm->pgd, mm); + cpu_set_asid(mm->context.id); + isb(); } #else diff --git a/trunk/arch/arm/mm/copypage-v3.c b/trunk/arch/arm/mm/copypage-v3.c new file mode 100644 index 000000000000..3935bddd4769 --- /dev/null +++ b/trunk/arch/arm/mm/copypage-v3.c @@ -0,0 +1,81 @@ +/* + * linux/arch/arm/mm/copypage-v3.c + * + * Copyright (C) 1995-1999 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include + +/* + * ARMv3 optimised copy_user_highpage + * + * FIXME: do we need to handle cache stuff... + */ +static void __naked +v3_copy_user_page(void *kto, const void *kfrom) +{ + asm("\n\ + stmfd sp!, {r4, lr} @ 2\n\ + mov r2, %2 @ 1\n\ + ldmia %0!, {r3, r4, ip, lr} @ 4+1\n\ +1: stmia %1!, {r3, r4, ip, lr} @ 4\n\ + ldmia %0!, {r3, r4, ip, lr} @ 4+1\n\ + stmia %1!, {r3, r4, ip, lr} @ 4\n\ + ldmia %0!, {r3, r4, ip, lr} @ 4+1\n\ + stmia %1!, {r3, r4, ip, lr} @ 4\n\ + ldmia %0!, {r3, r4, ip, lr} @ 4\n\ + subs r2, r2, #1 @ 1\n\ + stmia %1!, {r3, r4, ip, lr} @ 4\n\ + ldmneia %0!, {r3, r4, ip, lr} @ 4\n\ + bne 1b @ 1\n\ + ldmfd sp!, {r4, pc} @ 3" + : + : "r" (kfrom), "r" (kto), "I" (PAGE_SIZE / 64)); +} + +void v3_copy_user_highpage(struct page *to, struct page *from, + unsigned long vaddr, struct vm_area_struct *vma) +{ + void *kto, *kfrom; + + kto = kmap_atomic(to); + kfrom = kmap_atomic(from); + v3_copy_user_page(kto, kfrom); + kunmap_atomic(kfrom); + kunmap_atomic(kto); +} + +/* + * ARMv3 optimised clear_user_page + * + * FIXME: do we need to handle cache stuff... + */ +void v3_clear_user_highpage(struct page *page, unsigned long vaddr) +{ + void *ptr, *kaddr = kmap_atomic(page); + asm volatile("\n\ + mov r1, %2 @ 1\n\ + mov r2, #0 @ 1\n\ + mov r3, #0 @ 1\n\ + mov ip, #0 @ 1\n\ + mov lr, #0 @ 1\n\ +1: stmia %0!, {r2, r3, ip, lr} @ 4\n\ + stmia %0!, {r2, r3, ip, lr} @ 4\n\ + stmia %0!, {r2, r3, ip, lr} @ 4\n\ + stmia %0!, {r2, r3, ip, lr} @ 4\n\ + subs r1, r1, #1 @ 1\n\ + bne 1b @ 1" + : "=r" (ptr) + : "0" (kaddr), "I" (PAGE_SIZE / 64) + : "r1", "r2", "r3", "ip", "lr"); + kunmap_atomic(kaddr); +} + +struct cpu_user_fns v3_user_fns __initdata = { + .cpu_clear_user_highpage = v3_clear_user_highpage, + .cpu_copy_user_highpage = v3_copy_user_highpage, +}; diff --git a/trunk/arch/arm/mm/fault.c b/trunk/arch/arm/mm/fault.c index c3bd83450227..f07467533365 100644 --- a/trunk/arch/arm/mm/fault.c +++ b/trunk/arch/arm/mm/fault.c @@ -247,9 +247,7 @@ __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, return handle_mm_fault(mm, vma, addr & PAGE_MASK, flags); check_stack: - /* Don't allow expansion below FIRST_USER_ADDRESS */ - if (vma->vm_flags & VM_GROWSDOWN && - addr >= FIRST_USER_ADDRESS && !expand_stack(vma, addr)) + if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr)) goto good_area; out: return fault; @@ -432,6 +430,9 @@ do_translation_fault(unsigned long addr, unsigned int fsr, index = pgd_index(addr); + /* + * FIXME: CP15 C1 is write only on ARMv3 architectures. + */ pgd = cpu_get_pgd() + index; pgd_k = init_mm.pgd + index; diff --git a/trunk/arch/arm/mm/mmu.c b/trunk/arch/arm/mm/mmu.c index aa78de8bfdd3..2c7cf2f9c837 100644 --- a/trunk/arch/arm/mm/mmu.c +++ b/trunk/arch/arm/mm/mmu.c @@ -489,8 +489,7 @@ static void __init build_mem_type_table(void) */ for (i = 0; i < ARRAY_SIZE(mem_types); i++) { mem_types[i].prot_pte |= PTE_EXT_AF; - if (mem_types[i].prot_sect) - mem_types[i].prot_sect |= PMD_SECT_AF; + mem_types[i].prot_sect |= PMD_SECT_AF; } kern_pgprot |= PTE_EXT_AF; vecs_pgprot |= PTE_EXT_AF; diff --git a/trunk/arch/arm/mm/proc-arm1020.S b/trunk/arch/arm/mm/proc-arm1020.S index 0650bb87c1e3..234951345eb3 100644 --- a/trunk/arch/arm/mm/proc-arm1020.S +++ b/trunk/arch/arm/mm/proc-arm1020.S @@ -241,7 +241,6 @@ ENTRY(arm1020_coherent_user_range) cmp r0, r1 blo 1b mcr p15, 0, ip, c7, c10, 4 @ drain WB - mov r0, #0 mov pc, lr /* diff --git a/trunk/arch/arm/mm/proc-arm1020e.S b/trunk/arch/arm/mm/proc-arm1020e.S index 4188478325a6..c244b06caac9 100644 --- a/trunk/arch/arm/mm/proc-arm1020e.S +++ b/trunk/arch/arm/mm/proc-arm1020e.S @@ -235,7 +235,6 @@ ENTRY(arm1020e_coherent_user_range) cmp r0, r1 blo 1b mcr p15, 0, ip, c7, c10, 4 @ drain WB - mov r0, #0 mov pc, lr /* diff --git a/trunk/arch/arm/mm/proc-arm1022.S b/trunk/arch/arm/mm/proc-arm1022.S index 33c68824bff0..38fe22efd18f 100644 --- a/trunk/arch/arm/mm/proc-arm1022.S +++ b/trunk/arch/arm/mm/proc-arm1022.S @@ -224,7 +224,6 @@ ENTRY(arm1022_coherent_user_range) cmp r0, r1 blo 1b mcr p15, 0, ip, c7, c10, 4 @ drain WB - mov r0, #0 mov pc, lr /* diff --git a/trunk/arch/arm/mm/proc-arm1026.S b/trunk/arch/arm/mm/proc-arm1026.S index fbc1d5fc24dc..3eb9c3c26c75 100644 --- a/trunk/arch/arm/mm/proc-arm1026.S +++ b/trunk/arch/arm/mm/proc-arm1026.S @@ -218,7 +218,6 @@ ENTRY(arm1026_coherent_user_range) cmp r0, r1 blo 1b mcr p15, 0, ip, c7, c10, 4 @ drain WB - mov r0, #0 mov pc, lr /* diff --git a/trunk/arch/arm/mm/proc-arm6_7.S b/trunk/arch/arm/mm/proc-arm6_7.S new file mode 100644 index 000000000000..4fbeb5b8e6c2 --- /dev/null +++ b/trunk/arch/arm/mm/proc-arm6_7.S @@ -0,0 +1,327 @@ +/* + * linux/arch/arm/mm/proc-arm6,7.S + * + * Copyright (C) 1997-2000 Russell King + * hacked for non-paged-MM by Hyok S. Choi, 2003. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * These are the low level assembler for performing cache and TLB + * functions on the ARM610 & ARM710. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "proc-macros.S" + +ENTRY(cpu_arm6_dcache_clean_area) +ENTRY(cpu_arm7_dcache_clean_area) + mov pc, lr + +/* + * Function: arm6_7_data_abort () + * + * Params : r2 = pt_regs + * : r4 = aborted context pc + * : r5 = aborted context psr + * + * Purpose : obtain information about current aborted instruction + * + * Returns : r4-r5, r10-r11, r13 preserved + */ + +ENTRY(cpu_arm7_data_abort) + mrc p15, 0, r1, c5, c0, 0 @ get FSR + mrc p15, 0, r0, c6, c0, 0 @ get FAR + ldr r8, [r4] @ read arm instruction + tst r8, #1 << 20 @ L = 0 -> write? + orreq r1, r1, #1 << 11 @ yes. + and r7, r8, #15 << 24 + add pc, pc, r7, lsr #22 @ Now branch to the relevant processing routine + nop + +/* 0 */ b .data_unknown +/* 1 */ b do_DataAbort @ swp +/* 2 */ b .data_unknown +/* 3 */ b .data_unknown +/* 4 */ b .data_arm_lateldrpostconst @ ldr rd, [rn], #m +/* 5 */ b .data_arm_lateldrpreconst @ ldr rd, [rn, #m] +/* 6 */ b .data_arm_lateldrpostreg @ ldr rd, [rn], rm +/* 7 */ b .data_arm_lateldrprereg @ ldr rd, [rn, rm] +/* 8 */ b .data_arm_ldmstm @ ldm*a rn, +/* 9 */ b .data_arm_ldmstm @ ldm*b rn, +/* a */ b .data_unknown +/* b */ b .data_unknown +/* c */ b do_DataAbort @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m +/* d */ b do_DataAbort @ ldc rd, [rn, #m] +/* e */ b .data_unknown +/* f */ +.data_unknown: @ Part of jumptable + mov r0, r4 + mov r1, r8 + b baddataabort + +ENTRY(cpu_arm6_data_abort) + mrc p15, 0, r1, c5, c0, 0 @ get FSR + mrc p15, 0, r0, c6, c0, 0 @ get FAR + ldr r8, [r4] @ read arm instruction + tst r8, #1 << 20 @ L = 0 -> write? + orreq r1, r1, #1 << 11 @ yes. + and r7, r8, #14 << 24 + teq r7, #8 << 24 @ was it ldm/stm + bne do_DataAbort + +.data_arm_ldmstm: + tst r8, #1 << 21 @ check writeback bit + beq do_DataAbort @ no writeback -> no fixup + mov r7, #0x11 + orr r7, r7, #0x1100 + and r6, r8, r7 + and r9, r8, r7, lsl #1 + add r6, r6, r9, lsr #1 + and r9, r8, r7, lsl #2 + add r6, r6, r9, lsr #2 + and r9, r8, r7, lsl #3 + add r6, r6, r9, lsr #3 + add r6, r6, r6, lsr #8 + add r6, r6, r6, lsr #4 + and r6, r6, #15 @ r6 = no. of registers to transfer. + and r9, r8, #15 << 16 @ Extract 'n' from instruction + ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' + tst r8, #1 << 23 @ Check U bit + subne r7, r7, r6, lsl #2 @ Undo increment + addeq r7, r7, r6, lsl #2 @ Undo decrement + str r7, [r2, r9, lsr #14] @ Put register 'Rn' + b do_DataAbort + +.data_arm_apply_r6_and_rn: + and r9, r8, #15 << 16 @ Extract 'n' from instruction + ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' + tst r8, #1 << 23 @ Check U bit + subne r7, r7, r6 @ Undo incrmenet + addeq r7, r7, r6 @ Undo decrement + str r7, [r2, r9, lsr #14] @ Put register 'Rn' + b do_DataAbort + +.data_arm_lateldrpreconst: + tst r8, #1 << 21 @ check writeback bit + beq do_DataAbort @ no writeback -> no fixup +.data_arm_lateldrpostconst: + movs r6, r8, lsl #20 @ Get offset + beq do_DataAbort @ zero -> no fixup + and r9, r8, #15 << 16 @ Extract 'n' from instruction + ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' + tst r8, #1 << 23 @ Check U bit + subne r7, r7, r6, lsr #20 @ Undo increment + addeq r7, r7, r6, lsr #20 @ Undo decrement + str r7, [r2, r9, lsr #14] @ Put register 'Rn' + b do_DataAbort + +.data_arm_lateldrprereg: + tst r8, #1 << 21 @ check writeback bit + beq do_DataAbort @ no writeback -> no fixup +.data_arm_lateldrpostreg: + and r7, r8, #15 @ Extract 'm' from instruction + ldr r6, [r2, r7, lsl #2] @ Get register 'Rm' + mov r9, r8, lsr #7 @ get shift count + ands r9, r9, #31 + and r7, r8, #0x70 @ get shift type + orreq r7, r7, #8 @ shift count = 0 + add pc, pc, r7 + nop + + mov r6, r6, lsl r9 @ 0: LSL #!0 + b .data_arm_apply_r6_and_rn + b .data_arm_apply_r6_and_rn @ 1: LSL #0 + nop + b .data_unknown @ 2: MUL? + nop + b .data_unknown @ 3: MUL? + nop + mov r6, r6, lsr r9 @ 4: LSR #!0 + b .data_arm_apply_r6_and_rn + mov r6, r6, lsr #32 @ 5: LSR #32 + b .data_arm_apply_r6_and_rn + b .data_unknown @ 6: MUL? + nop + b .data_unknown @ 7: MUL? + nop + mov r6, r6, asr r9 @ 8: ASR #!0 + b .data_arm_apply_r6_and_rn + mov r6, r6, asr #32 @ 9: ASR #32 + b .data_arm_apply_r6_and_rn + b .data_unknown @ A: MUL? + nop + b .data_unknown @ B: MUL? + nop + mov r6, r6, ror r9 @ C: ROR #!0 + b .data_arm_apply_r6_and_rn + mov r6, r6, rrx @ D: RRX + b .data_arm_apply_r6_and_rn + b .data_unknown @ E: MUL? + nop + b .data_unknown @ F: MUL? + +/* + * Function: arm6_7_proc_init (void) + * : arm6_7_proc_fin (void) + * + * Notes : This processor does not require these + */ +ENTRY(cpu_arm6_proc_init) +ENTRY(cpu_arm7_proc_init) + mov pc, lr + +ENTRY(cpu_arm6_proc_fin) +ENTRY(cpu_arm7_proc_fin) + mov r0, #0x31 @ ....S..DP...M + mcr p15, 0, r0, c1, c0, 0 @ disable caches + mov pc, lr + +ENTRY(cpu_arm6_do_idle) +ENTRY(cpu_arm7_do_idle) + mov pc, lr + +/* + * Function: arm6_7_switch_mm(unsigned long pgd_phys) + * Params : pgd_phys Physical address of page table + * Purpose : Perform a task switch, saving the old processes state, and restoring + * the new. + */ +ENTRY(cpu_arm6_switch_mm) +ENTRY(cpu_arm7_switch_mm) +#ifdef CONFIG_MMU + mov r1, #0 + mcr p15, 0, r1, c7, c0, 0 @ flush cache + mcr p15, 0, r0, c2, c0, 0 @ update page table ptr + mcr p15, 0, r1, c5, c0, 0 @ flush TLBs +#endif + mov pc, lr + +/* + * Function: arm6_7_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext) + * Params : r0 = Address to set + * : r1 = value to set + * Purpose : Set a PTE and flush it out of any WB cache + */ + .align 5 +ENTRY(cpu_arm6_set_pte_ext) +ENTRY(cpu_arm7_set_pte_ext) +#ifdef CONFIG_MMU + armv3_set_pte_ext wc_disable=0 +#endif /* CONFIG_MMU */ + mov pc, lr + +/* + * Function: _arm6_7_reset + * Params : r0 = address to jump to + * Notes : This sets up everything for a reset + */ + .pushsection .idmap.text, "ax" +ENTRY(cpu_arm6_reset) +ENTRY(cpu_arm7_reset) + mov r1, #0 + mcr p15, 0, r1, c7, c0, 0 @ flush cache +#ifdef CONFIG_MMU + mcr p15, 0, r1, c5, c0, 0 @ flush TLB +#endif + mov r1, #0x30 + mcr p15, 0, r1, c1, c0, 0 @ turn off MMU etc + mov pc, r0 +ENDPROC(cpu_arm6_reset) +ENDPROC(cpu_arm7_reset) + .popsection + + __CPUINIT + + .type __arm6_setup, #function +__arm6_setup: mov r0, #0 + mcr p15, 0, r0, c7, c0 @ flush caches on v3 +#ifdef CONFIG_MMU + mcr p15, 0, r0, c5, c0 @ flush TLBs on v3 + mov r0, #0x3d @ . ..RS BLDP WCAM + orr r0, r0, #0x100 @ . ..01 0011 1101 +#else + mov r0, #0x3c @ . ..RS BLDP WCA. +#endif + mov pc, lr + .size __arm6_setup, . - __arm6_setup + + .type __arm7_setup, #function +__arm7_setup: mov r0, #0 + mcr p15, 0, r0, c7, c0 @ flush caches on v3 +#ifdef CONFIG_MMU + mcr p15, 0, r0, c5, c0 @ flush TLBs on v3 + mcr p15, 0, r0, c3, c0 @ load domain access register + mov r0, #0x7d @ . ..RS BLDP WCAM + orr r0, r0, #0x100 @ . ..01 0111 1101 +#else + mov r0, #0x7c @ . ..RS BLDP WCA. +#endif + mov pc, lr + .size __arm7_setup, . - __arm7_setup + + __INITDATA + + @ define struct processor (see and proc-macros.S) + define_processor_functions arm6, dabort=cpu_arm6_data_abort, pabort=legacy_pabort + define_processor_functions arm7, dabort=cpu_arm7_data_abort, pabort=legacy_pabort + + .section ".rodata" + + string cpu_arch_name, "armv3" + string cpu_elf_name, "v3" + string cpu_arm6_name, "ARM6" + string cpu_arm610_name, "ARM610" + string cpu_arm7_name, "ARM7" + string cpu_arm710_name, "ARM710" + + .align + + .section ".proc.info.init", #alloc, #execinstr + +.macro arm67_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, \ + cpu_mm_mmu_flags:req, cpu_flush:req, cpu_proc_funcs:req + .type __\name\()_proc_info, #object +__\name\()_proc_info: + .long \cpu_val + .long \cpu_mask + .long \cpu_mm_mmu_flags + .long PMD_TYPE_SECT | \ + PMD_BIT4 | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b \cpu_flush + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_26BIT + .long \cpu_name + .long \cpu_proc_funcs + .long v3_tlb_fns + .long v3_user_fns + .long v3_cache_fns + .size __\name\()_proc_info, . - __\name\()_proc_info +.endm + + arm67_proc_info arm6, 0x41560600, 0xfffffff0, cpu_arm6_name, \ + 0x00000c1e, __arm6_setup, arm6_processor_functions + arm67_proc_info arm610, 0x41560610, 0xfffffff0, cpu_arm610_name, \ + 0x00000c1e, __arm6_setup, arm6_processor_functions + arm67_proc_info arm7, 0x41007000, 0xffffff00, cpu_arm7_name, \ + 0x00000c1e, __arm7_setup, arm7_processor_functions + arm67_proc_info arm710, 0x41007100, 0xfff8ff00, cpu_arm710_name, \ + PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_BIT4 | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ, \ + __arm7_setup, arm7_processor_functions diff --git a/trunk/arch/arm/mm/proc-arm920.S b/trunk/arch/arm/mm/proc-arm920.S index 1a8c138eb897..cb941ae95f66 100644 --- a/trunk/arch/arm/mm/proc-arm920.S +++ b/trunk/arch/arm/mm/proc-arm920.S @@ -210,7 +210,6 @@ ENTRY(arm920_coherent_user_range) cmp r0, r1 blo 1b mcr p15, 0, r0, c7, c10, 4 @ drain WB - mov r0, #0 mov pc, lr /* diff --git a/trunk/arch/arm/mm/proc-arm922.S b/trunk/arch/arm/mm/proc-arm922.S index 4c44d7e1c3ca..4ec0e074dd55 100644 --- a/trunk/arch/arm/mm/proc-arm922.S +++ b/trunk/arch/arm/mm/proc-arm922.S @@ -212,7 +212,6 @@ ENTRY(arm922_coherent_user_range) cmp r0, r1 blo 1b mcr p15, 0, r0, c7, c10, 4 @ drain WB - mov r0, #0 mov pc, lr /* diff --git a/trunk/arch/arm/mm/proc-arm925.S b/trunk/arch/arm/mm/proc-arm925.S index ec5b1180994f..9dccd9a365b3 100644 --- a/trunk/arch/arm/mm/proc-arm925.S +++ b/trunk/arch/arm/mm/proc-arm925.S @@ -258,7 +258,6 @@ ENTRY(arm925_coherent_user_range) cmp r0, r1 blo 1b mcr p15, 0, r0, c7, c10, 4 @ drain WB - mov r0, #0 mov pc, lr /* diff --git a/trunk/arch/arm/mm/proc-arm926.S b/trunk/arch/arm/mm/proc-arm926.S index c31e62c606c0..820259b81a1f 100644 --- a/trunk/arch/arm/mm/proc-arm926.S +++ b/trunk/arch/arm/mm/proc-arm926.S @@ -221,7 +221,6 @@ ENTRY(arm926_coherent_user_range) cmp r0, r1 blo 1b mcr p15, 0, r0, c7, c10, 4 @ drain WB - mov r0, #0 mov pc, lr /* diff --git a/trunk/arch/arm/mm/proc-arm940.S b/trunk/arch/arm/mm/proc-arm940.S index a613a7dd7146..9fdc0a170974 100644 --- a/trunk/arch/arm/mm/proc-arm940.S +++ b/trunk/arch/arm/mm/proc-arm940.S @@ -160,7 +160,7 @@ ENTRY(arm940_coherent_user_range) * - size - region size */ ENTRY(arm940_flush_kern_dcache_area) - mov r0, #0 + mov ip, #0 mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments 1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries 2: mcr p15, 0, r3, c7, c14, 2 @ clean/flush D index @@ -168,8 +168,8 @@ ENTRY(arm940_flush_kern_dcache_area) bcs 2b @ entries 63 to 0 subs r1, r1, #1 << 4 bcs 1b @ segments 7 to 0 - mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache - mcr p15, 0, r0, c7, c10, 4 @ drain WB + mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB mov pc, lr /* diff --git a/trunk/arch/arm/mm/proc-arm946.S b/trunk/arch/arm/mm/proc-arm946.S index 9f4f2999fdd0..f684cfedcca9 100644 --- a/trunk/arch/arm/mm/proc-arm946.S +++ b/trunk/arch/arm/mm/proc-arm946.S @@ -190,7 +190,6 @@ ENTRY(arm946_coherent_user_range) cmp r0, r1 blo 1b mcr p15, 0, r0, c7, c10, 4 @ drain WB - mov r0, #0 mov pc, lr /* diff --git a/trunk/arch/arm/mm/proc-feroceon.S b/trunk/arch/arm/mm/proc-feroceon.S index 23a8e4c7f2bd..ba3c500584ac 100644 --- a/trunk/arch/arm/mm/proc-feroceon.S +++ b/trunk/arch/arm/mm/proc-feroceon.S @@ -232,7 +232,6 @@ ENTRY(feroceon_coherent_user_range) cmp r0, r1 blo 1b mcr p15, 0, r0, c7, c10, 4 @ drain WB - mov r0, #0 mov pc, lr /* diff --git a/trunk/arch/arm/mm/proc-mohawk.S b/trunk/arch/arm/mm/proc-mohawk.S index b0475468c711..cdfedc5b8ad8 100644 --- a/trunk/arch/arm/mm/proc-mohawk.S +++ b/trunk/arch/arm/mm/proc-mohawk.S @@ -193,7 +193,6 @@ ENTRY(mohawk_coherent_user_range) cmp r0, r1 blo 1b mcr p15, 0, r0, c7, c10, 4 @ drain WB - mov r0, #0 mov pc, lr /* diff --git a/trunk/arch/arm/mm/proc-v7-2level.S b/trunk/arch/arm/mm/proc-v7-2level.S index 42ac069c8012..3a4b3e7b888c 100644 --- a/trunk/arch/arm/mm/proc-v7-2level.S +++ b/trunk/arch/arm/mm/proc-v7-2level.S @@ -49,9 +49,14 @@ ENTRY(cpu_v7_switch_mm) #ifdef CONFIG_ARM_ERRATA_754322 dsb #endif - mcr p15, 0, r1, c13, c0, 1 @ set context ID + mcr p15, 0, r2, c13, c0, 1 @ set reserved context ID + isb +1: mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 isb - mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 +#ifdef CONFIG_ARM_ERRATA_754322 + dsb +#endif + mcr p15, 0, r1, c13, c0, 1 @ set context ID isb #endif mov pc, lr diff --git a/trunk/arch/arm/mm/tlb-v3.S b/trunk/arch/arm/mm/tlb-v3.S new file mode 100644 index 000000000000..d253995ec4ca --- /dev/null +++ b/trunk/arch/arm/mm/tlb-v3.S @@ -0,0 +1,48 @@ +/* + * linux/arch/arm/mm/tlbv3.S + * + * Copyright (C) 1997-2002 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * ARM architecture version 3 TLB handling functions. + * + * Processors: ARM610, ARM710. + */ +#include +#include +#include +#include +#include "proc-macros.S" + + .align 5 +/* + * v3_flush_user_tlb_range(start, end, mm) + * + * Invalidate a range of TLB entries in the specified address space. + * + * - start - range start address + * - end - range end address + * - mm - mm_struct describing address space + */ + .align 5 +ENTRY(v3_flush_user_tlb_range) + vma_vm_mm r2, r2 + act_mm r3 @ get current->active_mm + teq r2, r3 @ == mm ? + movne pc, lr @ no, we dont do anything +ENTRY(v3_flush_kern_tlb_range) + bic r0, r0, #0x0ff + bic r0, r0, #0xf00 +1: mcr p15, 0, r0, c6, c0, 0 @ invalidate TLB entry + add r0, r0, #PAGE_SZ + cmp r0, r1 + blo 1b + mov pc, lr + + __INITDATA + + /* define struct cpu_tlb_fns (see and proc-macros.S) */ + define_tlb_functions v3, v3_tlb_flags diff --git a/trunk/arch/arm/plat-iop/pci.c b/trunk/arch/arm/plat-iop/pci.c index 8daae9b230ea..0da42058a20f 100644 --- a/trunk/arch/arm/plat-iop/pci.c +++ b/trunk/arch/arm/plat-iop/pci.c @@ -160,7 +160,7 @@ iop3xx_write_config(struct pci_bus *bus, unsigned int devfn, int where, return PCIBIOS_SUCCESSFUL; } -struct pci_ops iop3xx_ops = { +static struct pci_ops iop3xx_ops = { .read = iop3xx_read_config, .write = iop3xx_write_config, }; @@ -220,6 +220,12 @@ int iop3xx_pci_setup(int nr, struct pci_sys_data *sys) return 1; } +struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_root_bus(NULL, sys->busnr, &iop3xx_ops, sys, + &sys->resources); +} + void __init iop3xx_atu_setup(void) { /* BAR 0 ( Disabled ) */ diff --git a/trunk/arch/arm/plat-omap/counter_32k.c b/trunk/arch/arm/plat-omap/counter_32k.c index 44ae077dbc28..5068fe5a6910 100644 --- a/trunk/arch/arm/plat-omap/counter_32k.c +++ b/trunk/arch/arm/plat-omap/counter_32k.c @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -44,7 +43,7 @@ static u32 notrace omap_32k_read_sched_clock(void) } /** - * omap_read_persistent_clock - Return time from a persistent clock. + * read_persistent_clock - Return time from a persistent clock. * * Reads the time from a source which isn't disabled during PM, the * 32k sync timer. Convert the cycles elapsed since last read into @@ -53,7 +52,7 @@ static u32 notrace omap_32k_read_sched_clock(void) static struct timespec persistent_ts; static cycles_t cycles, last_cycles; static unsigned int persistent_mult, persistent_shift; -static void omap_read_persistent_clock(struct timespec *ts) +void read_persistent_clock(struct timespec *ts) { unsigned long long nsecs; cycles_t delta; @@ -117,7 +116,6 @@ int __init omap_init_clocksource_32k(void) printk(err, "32k_counter"); setup_sched_clock(omap_32k_read_sched_clock, 32, 32768); - register_persistent_clock(NULL, omap_read_persistent_clock); } return 0; } diff --git a/trunk/arch/arm/plat-versatile/Kconfig b/trunk/arch/arm/plat-versatile/Kconfig index 81ee7cc34457..043f7b02a9e7 100644 --- a/trunk/arch/arm/plat-versatile/Kconfig +++ b/trunk/arch/arm/plat-versatile/Kconfig @@ -5,12 +5,6 @@ config PLAT_VERSATILE_CLCD config PLAT_VERSATILE_FPGA_IRQ bool - select IRQ_DOMAIN - -config PLAT_VERSATILE_FPGA_IRQ_NR - int - default 4 - depends on PLAT_VERSATILE_FPGA_IRQ config PLAT_VERSATILE_LEDS def_bool y if LEDS_CLASS diff --git a/trunk/arch/arm/plat-versatile/fpga-irq.c b/trunk/arch/arm/plat-versatile/fpga-irq.c index 6e70d03824a1..f0cc8e19b094 100644 --- a/trunk/arch/arm/plat-versatile/fpga-irq.c +++ b/trunk/arch/arm/plat-versatile/fpga-irq.c @@ -3,10 +3,7 @@ */ #include #include -#include -#include -#include #include #include @@ -15,32 +12,10 @@ #define IRQ_ENABLE_SET 0x08 #define IRQ_ENABLE_CLEAR 0x0c -/** - * struct fpga_irq_data - irq data container for the FPGA IRQ controller - * @base: memory offset in virtual memory - * @irq_start: first IRQ number handled by this instance - * @chip: chip container for this instance - * @domain: IRQ domain for this instance - * @valid: mask for valid IRQs on this controller - * @used_irqs: number of active IRQs on this controller - */ -struct fpga_irq_data { - void __iomem *base; - unsigned int irq_start; - struct irq_chip chip; - u32 valid; - struct irq_domain *domain; - u8 used_irqs; -}; - -/* we cannot allocate memory when the controllers are initially registered */ -static struct fpga_irq_data fpga_irq_devices[CONFIG_PLAT_VERSATILE_FPGA_IRQ_NR]; -static int fpga_irq_id; - static void fpga_irq_mask(struct irq_data *d) { struct fpga_irq_data *f = irq_data_get_irq_chip_data(d); - u32 mask = 1 << d->hwirq; + u32 mask = 1 << (d->irq - f->irq_start); writel(mask, f->base + IRQ_ENABLE_CLEAR); } @@ -48,7 +23,7 @@ static void fpga_irq_mask(struct irq_data *d) static void fpga_irq_unmask(struct irq_data *d) { struct fpga_irq_data *f = irq_data_get_irq_chip_data(d); - u32 mask = 1 << d->hwirq; + u32 mask = 1 << (d->irq - f->irq_start); writel(mask, f->base + IRQ_ENABLE_SET); } @@ -66,93 +41,32 @@ static void fpga_irq_handle(unsigned int irq, struct irq_desc *desc) do { irq = ffs(status) - 1; status &= ~(1 << irq); - generic_handle_irq(irq_find_mapping(f->domain, irq)); - } while (status); -} -/* - * Handle each interrupt in a single FPGA IRQ controller. Returns non-zero - * if we've handled at least one interrupt. This does a single read of the - * status register and handles all interrupts in order from LSB first. - */ -static int handle_one_fpga(struct fpga_irq_data *f, struct pt_regs *regs) -{ - int handled = 0; - int irq; - u32 status; - - while ((status = readl(f->base + IRQ_STATUS))) { - irq = ffs(status) - 1; - handle_IRQ(irq_find_mapping(f->domain, irq), regs); - handled = 1; - } - - return handled; -} - -/* - * Keep iterating over all registered FPGA IRQ controllers until there are - * no pending interrupts. - */ -asmlinkage void __exception_irq_entry fpga_handle_irq(struct pt_regs *regs) -{ - int i, handled; - - do { - for (i = 0, handled = 0; i < fpga_irq_id; ++i) - handled |= handle_one_fpga(&fpga_irq_devices[i], regs); - } while (handled); -} - -static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hwirq) -{ - struct fpga_irq_data *f = d->host_data; - - /* Skip invalid IRQs, only register handlers for the real ones */ - if (!(f->valid & (1 << hwirq))) - return -ENOTSUPP; - irq_set_chip_data(irq, f); - irq_set_chip_and_handler(irq, &f->chip, - handle_level_irq); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - f->used_irqs++; - return 0; + generic_handle_irq(irq + f->irq_start); + } while (status); } -static struct irq_domain_ops fpga_irqdomain_ops = { - .map = fpga_irqdomain_map, - .xlate = irq_domain_xlate_onetwocell, -}; - -void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start, - int parent_irq, u32 valid, struct device_node *node) +void __init fpga_irq_init(int parent_irq, u32 valid, struct fpga_irq_data *f) { - struct fpga_irq_data *f; + unsigned int i; - if (fpga_irq_id >= ARRAY_SIZE(fpga_irq_devices)) { - printk(KERN_ERR "%s: too few FPGA IRQ controllers, increase CONFIG_PLAT_VERSATILE_FPGA_IRQ_NR\n", __func__); - return; - } - - f = &fpga_irq_devices[fpga_irq_id]; - f->base = base; - f->irq_start = irq_start; - f->chip.name = name; f->chip.irq_ack = fpga_irq_mask; f->chip.irq_mask = fpga_irq_mask; f->chip.irq_unmask = fpga_irq_unmask; - f->valid = valid; if (parent_irq != -1) { irq_set_handler_data(parent_irq, f); irq_set_chained_handler(parent_irq, fpga_irq_handle); } - f->domain = irq_domain_add_legacy(node, fls(valid), f->irq_start, 0, - &fpga_irqdomain_ops, f); - pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n", - fpga_irq_id, name, base, f->used_irqs); + for (i = 0; i < 32; i++) { + if (valid & (1 << i)) { + unsigned int irq = f->irq_start + i; - fpga_irq_id++; + irq_set_chip_data(irq, f); + irq_set_chip_and_handler(irq, &f->chip, + handle_level_irq); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + } } diff --git a/trunk/arch/arm/plat-versatile/include/plat/fpga-irq.h b/trunk/arch/arm/plat-versatile/include/plat/fpga-irq.h index 91bcfb67551d..627fafd1e595 100644 --- a/trunk/arch/arm/plat-versatile/include/plat/fpga-irq.h +++ b/trunk/arch/arm/plat-versatile/include/plat/fpga-irq.h @@ -1,11 +1,12 @@ #ifndef PLAT_FPGA_IRQ_H #define PLAT_FPGA_IRQ_H -struct device_node; -struct pt_regs; +struct fpga_irq_data { + void __iomem *base; + unsigned int irq_start; + struct irq_chip chip; +}; -void fpga_handle_irq(struct pt_regs *regs); -void fpga_irq_init(void __iomem *, const char *, int, int, u32, - struct device_node *node); +void fpga_irq_init(int, u32, struct fpga_irq_data *); #endif diff --git a/trunk/arch/arm/tools/mach-types b/trunk/arch/arm/tools/mach-types index 2997e56ce0dd..f9c9f33f8cbe 100644 --- a/trunk/arch/arm/tools/mach-types +++ b/trunk/arch/arm/tools/mach-types @@ -16,7 +16,7 @@ # are merged into mainline or have been edited in the machine database # within the last 12 months. References to machine_is_NAME() do not count! # -# Last update: Thu Apr 26 08:44:23 2012 +# Last update: Tue Dec 6 11:07:38 2011 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -205,7 +205,6 @@ omap_fsample MACH_OMAP_FSAMPLE OMAP_FSAMPLE 970 snapper_cl15 MACH_SNAPPER_CL15 SNAPPER_CL15 986 omap_palmz71 MACH_OMAP_PALMZ71 OMAP_PALMZ71 993 smdk2412 MACH_SMDK2412 SMDK2412 1009 -bkde303 MACH_BKDE303 BKDE303 1021 smdk2413 MACH_SMDK2413 SMDK2413 1022 aml_m5900 MACH_AML_M5900 AML_M5900 1024 balloon3 MACH_BALLOON3 BALLOON3 1029 @@ -382,6 +381,8 @@ davinci_da850_evm MACH_DAVINCI_DA850_EVM DAVINCI_DA850_EVM 2157 at91sam9g10ek MACH_AT91SAM9G10EK AT91SAM9G10EK 2159 omap_4430sdp MACH_OMAP_4430SDP OMAP_4430SDP 2160 magx_zn5 MACH_MAGX_ZN5 MAGX_ZN5 2162 +btmavb101 MACH_BTMAVB101 BTMAVB101 2172 +btmawb101 MACH_BTMAWB101 BTMAWB101 2173 tx25 MACH_TX25 TX25 2177 omap3_torpedo MACH_OMAP3_TORPEDO OMAP3_TORPEDO 2178 anw6410 MACH_ANW6410 ANW6410 2183 @@ -396,6 +397,7 @@ net2big_v2 MACH_NET2BIG_V2 NET2BIG_V2 2204 net5big_v2 MACH_NET5BIG_V2 NET5BIG_V2 2206 inetspace_v2 MACH_INETSPACE_V2 INETSPACE_V2 2208 at91sam9g45ekes MACH_AT91SAM9G45EKES AT91SAM9G45EKES 2212 +pc7302 MACH_PC7302 PC7302 2220 spear600 MACH_SPEAR600 SPEAR600 2236 spear300 MACH_SPEAR300 SPEAR300 2237 lilly1131 MACH_LILLY1131 LILLY1131 2239 @@ -405,6 +407,7 @@ d2net MACH_D2NET D2NET 2282 bigdisk MACH_BIGDISK BIGDISK 2283 at91sam9g20ek_2mmc MACH_AT91SAM9G20EK_2MMC AT91SAM9G20EK_2MMC 2288 bcmring MACH_BCMRING BCMRING 2289 +dp6xx MACH_DP6XX DP6XX 2302 mahimahi MACH_MAHIMAHI MAHIMAHI 2304 smdk6442 MACH_SMDK6442 SMDK6442 2324 openrd_base MACH_OPENRD_BASE OPENRD_BASE 2325 @@ -441,6 +444,8 @@ mx28evk MACH_MX28EVK MX28EVK 2531 smartq5 MACH_SMARTQ5 SMARTQ5 2534 davinci_dm6467tevm MACH_DAVINCI_DM6467TEVM DAVINCI_DM6467TEVM 2548 mxt_td60 MACH_MXT_TD60 MXT_TD60 2550 +riot_bei2 MACH_RIOT_BEI2 RIOT_BEI2 2576 +riot_x37 MACH_RIOT_X37 RIOT_X37 2578 pca101 MACH_PCA101 PCA101 2595 capc7117 MACH_CAPC7117 CAPC7117 2612 icontrol MACH_ICONTROL ICONTROL 2624 @@ -455,6 +460,7 @@ spear320 MACH_SPEAR320 SPEAR320 2661 aquila MACH_AQUILA AQUILA 2676 esata_sheevaplug MACH_ESATA_SHEEVAPLUG ESATA_SHEEVAPLUG 2678 msm7x30_surf MACH_MSM7X30_SURF MSM7X30_SURF 2679 +ea2478devkit MACH_EA2478DEVKIT EA2478DEVKIT 2683 terastation_wxl MACH_TERASTATION_WXL TERASTATION_WXL 2697 msm7x25_surf MACH_MSM7X25_SURF MSM7X25_SURF 2703 msm7x25_ffa MACH_MSM7X25_FFA MSM7X25_FFA 2704 @@ -473,6 +479,8 @@ wbd222 MACH_WBD222 WBD222 2753 msm8x60_surf MACH_MSM8X60_SURF MSM8X60_SURF 2755 msm8x60_sim MACH_MSM8X60_SIM MSM8X60_SIM 2756 tcc8000_sdk MACH_TCC8000_SDK TCC8000_SDK 2758 +nanos MACH_NANOS NANOS 2759 +stamp9g45 MACH_STAMP9G45 STAMP9G45 2761 cns3420vb MACH_CNS3420VB CNS3420VB 2776 omap4_panda MACH_OMAP4_PANDA OMAP4_PANDA 2791 ti8168evm MACH_TI8168EVM TI8168EVM 2800 @@ -482,9 +490,12 @@ eukrea_cpuimx35sd MACH_EUKREA_CPUIMX35SD EUKREA_CPUIMX35SD 2821 eukrea_cpuimx51sd MACH_EUKREA_CPUIMX51SD EUKREA_CPUIMX51SD 2822 eukrea_cpuimx51 MACH_EUKREA_CPUIMX51 EUKREA_CPUIMX51 2823 smdkc210 MACH_SMDKC210 SMDKC210 2838 -pcaal1 MACH_PCAAL1 PCAAL1 2843 +pca102 MACH_PCA102 PCA102 2843 t5325 MACH_T5325 T5325 2846 income MACH_INCOME INCOME 2849 +vvbox_sdorig2 MACH_VVBOX_SDORIG2 VVBOX_SDORIG2 2857 +vvbox_sdlite2 MACH_VVBOX_SDLITE2 VVBOX_SDLITE2 2858 +vvbox_sdpro4 MACH_VVBOX_SDPRO4 VVBOX_SDPRO4 2859 mx257sx MACH_MX257SX MX257SX 2861 goni MACH_GONI GONI 2862 bv07 MACH_BV07 BV07 2882 @@ -493,7 +504,6 @@ devixp MACH_DEVIXP DEVIXP 2885 miccpt MACH_MICCPT MICCPT 2886 mic256 MACH_MIC256 MIC256 2887 u5500 MACH_U5500 U5500 2890 -pov15hd MACH_POV15HD POV15HD 2910 linkstation_lschl MACH_LINKSTATION_LSCHL LINKSTATION_LSCHL 2913 smdkv310 MACH_SMDKV310 SMDKV310 2925 wm8505_7in_netbook MACH_WM8505_7IN_NETBOOK WM8505_7IN_NETBOOK 2928 @@ -527,24 +537,243 @@ trimslice MACH_TRIMSLICE TRIMSLICE 3209 mackerel MACH_MACKEREL MACKEREL 3211 kaen MACH_KAEN KAEN 3217 nokia_rm680 MACH_NOKIA_RM680 NOKIA_RM680 3220 +dm6446_adbox MACH_DM6446_ADBOX DM6446_ADBOX 3226 +quad_salsa MACH_QUAD_SALSA QUAD_SALSA 3227 +abb_gma_1_1 MACH_ABB_GMA_1_1 ABB_GMA_1_1 3228 +svcid MACH_SVCID SVCID 3229 msm8960_sim MACH_MSM8960_SIM MSM8960_SIM 3230 msm8960_rumi3 MACH_MSM8960_RUMI3 MSM8960_RUMI3 3231 +icon_g MACH_ICON_G ICON_G 3232 +mb3 MACH_MB3 MB3 3233 gsia18s MACH_GSIA18S GSIA18S 3234 +pivicc MACH_PIVICC PIVICC 3235 +pcm048 MACH_PCM048 PCM048 3236 +dds MACH_DDS DDS 3237 +chalten_xa1 MACH_CHALTEN_XA1 CHALTEN_XA1 3238 +ts48xx MACH_TS48XX TS48XX 3239 +tonga2_tfttimer MACH_TONGA2_TFTTIMER TONGA2_TFTTIMER 3240 +whistler MACH_WHISTLER WHISTLER 3241 +asl_phoenix MACH_ASL_PHOENIX ASL_PHOENIX 3242 +at91sam9263otlite MACH_AT91SAM9263OTLITE AT91SAM9263OTLITE 3243 +ddplug MACH_DDPLUG DDPLUG 3244 +d2plug MACH_D2PLUG D2PLUG 3245 +kzm9d MACH_KZM9D KZM9D 3246 +verdi_lte MACH_VERDI_LTE VERDI_LTE 3247 +nanozoom MACH_NANOZOOM NANOZOOM 3248 +dm3730_som_lv MACH_DM3730_SOM_LV DM3730_SOM_LV 3249 +dm3730_torpedo MACH_DM3730_TORPEDO DM3730_TORPEDO 3250 +anchovy MACH_ANCHOVY ANCHOVY 3251 +re2rev20 MACH_RE2REV20 RE2REV20 3253 +re2rev21 MACH_RE2REV21 RE2REV21 3254 +cns21xx MACH_CNS21XX CNS21XX 3255 +rider MACH_RIDER RIDER 3257 +nsk330 MACH_NSK330 NSK330 3258 +cns2133evb MACH_CNS2133EVB CNS2133EVB 3259 +z3_816x_mod MACH_Z3_816X_MOD Z3_816X_MOD 3260 +z3_814x_mod MACH_Z3_814X_MOD Z3_814X_MOD 3261 +beect MACH_BEECT BEECT 3262 +dma_thunderbug MACH_DMA_THUNDERBUG DMA_THUNDERBUG 3263 +omn_at91sam9g20 MACH_OMN_AT91SAM9G20 OMN_AT91SAM9G20 3264 +mx25_e2s_uc MACH_MX25_E2S_UC MX25_E2S_UC 3265 +mione MACH_MIONE MIONE 3266 +top9000_tcu MACH_TOP9000_TCU TOP9000_TCU 3267 +top9000_bsl MACH_TOP9000_BSL TOP9000_BSL 3268 +kingdom MACH_KINGDOM KINGDOM 3269 +armadillo460 MACH_ARMADILLO460 ARMADILLO460 3270 +lq2 MACH_LQ2 LQ2 3271 +sweda_tms2 MACH_SWEDA_TMS2 SWEDA_TMS2 3272 mx53_loco MACH_MX53_LOCO MX53_LOCO 3273 +acer_a8 MACH_ACER_A8 ACER_A8 3275 +acer_gauguin MACH_ACER_GAUGUIN ACER_GAUGUIN 3276 +guppy MACH_GUPPY GUPPY 3277 +mx61_ard MACH_MX61_ARD MX61_ARD 3278 tx53 MACH_TX53 TX53 3279 +omapl138_case_a3 MACH_OMAPL138_CASE_A3 OMAPL138_CASE_A3 3280 +uemd MACH_UEMD UEMD 3281 +ccwmx51mut MACH_CCWMX51MUT CCWMX51MUT 3282 +rockhopper MACH_ROCKHOPPER ROCKHOPPER 3283 encore MACH_ENCORE ENCORE 3284 +hkdkc100 MACH_HKDKC100 HKDKC100 3285 +ts42xx MACH_TS42XX TS42XX 3286 +aebl MACH_AEBL AEBL 3287 wario MACH_WARIO WARIO 3288 +gfs_spm MACH_GFS_SPM GFS_SPM 3289 cm_t3730 MACH_CM_T3730 CM_T3730 3290 +isc3 MACH_ISC3 ISC3 3291 +rascal MACH_RASCAL RASCAL 3292 hrefv60 MACH_HREFV60 HREFV60 3293 +tpt_2_0 MACH_TPT_2_0 TPT_2_0 3294 +splendor MACH_SPLENDOR SPLENDOR 3296 +msm8x60_qt MACH_MSM8X60_QT MSM8X60_QT 3298 +htc_hd_mini MACH_HTC_HD_MINI HTC_HD_MINI 3299 +athene MACH_ATHENE ATHENE 3300 +deep_r_ek_1 MACH_DEEP_R_EK_1 DEEP_R_EK_1 3301 +vivow_ct MACH_VIVOW_CT VIVOW_CT 3302 +nery_1000 MACH_NERY_1000 NERY_1000 3303 +rfl109145_ssrv MACH_RFL109145_SSRV RFL109145_SSRV 3304 +nmh MACH_NMH NMH 3305 +wn802t MACH_WN802T WN802T 3306 +dragonet MACH_DRAGONET DRAGONET 3307 +at91sam9263desk16l MACH_AT91SAM9263DESK16L AT91SAM9263DESK16L 3309 +bcmhana_sv MACH_BCMHANA_SV BCMHANA_SV 3310 +bcmhana_tablet MACH_BCMHANA_TABLET BCMHANA_TABLET 3311 +koi MACH_KOI KOI 3312 +ts4800 MACH_TS4800 TS4800 3313 +tqma9263 MACH_TQMA9263 TQMA9263 3314 +holiday MACH_HOLIDAY HOLIDAY 3315 +pcats_overlay MACH_PCATS_OVERLAY PCATS_OVERLAY 3317 +hwgw6410 MACH_HWGW6410 HWGW6410 3318 +shenzhou MACH_SHENZHOU SHENZHOU 3319 +cwme9210 MACH_CWME9210 CWME9210 3320 +cwme9210js MACH_CWME9210JS CWME9210JS 3321 +colibri_tegra2 MACH_COLIBRI_TEGRA2 COLIBRI_TEGRA2 3323 +w21 MACH_W21 W21 3324 +polysat1 MACH_POLYSAT1 POLYSAT1 3325 +dataway MACH_DATAWAY DATAWAY 3326 +cobral138 MACH_COBRAL138 COBRAL138 3327 +roverpcs8 MACH_ROVERPCS8 ROVERPCS8 3328 +marvelc MACH_MARVELC MARVELC 3329 +navefihid MACH_NAVEFIHID NAVEFIHID 3330 +dm365_cv100 MACH_DM365_CV100 DM365_CV100 3331 +able MACH_ABLE ABLE 3332 +legacy MACH_LEGACY LEGACY 3333 +icong MACH_ICONG ICONG 3334 +rover_g8 MACH_ROVER_G8 ROVER_G8 3335 +t5388p MACH_T5388P T5388P 3336 +dingo MACH_DINGO DINGO 3337 +goflexhome MACH_GOFLEXHOME GOFLEXHOME 3338 +lanreadyfn511 MACH_LANREADYFN511 LANREADYFN511 3340 +omap3_baia MACH_OMAP3_BAIA OMAP3_BAIA 3341 +omap3smartdisplay MACH_OMAP3SMARTDISPLAY OMAP3SMARTDISPLAY 3342 +xilinx MACH_XILINX XILINX 3343 +a2f MACH_A2F A2F 3344 +sky25 MACH_SKY25 SKY25 3345 +ccmx53 MACH_CCMX53 CCMX53 3346 +ccmx53js MACH_CCMX53JS CCMX53JS 3347 +ccwmx53 MACH_CCWMX53 CCWMX53 3348 +ccwmx53js MACH_CCWMX53JS CCWMX53JS 3349 +frisms MACH_FRISMS FRISMS 3350 +msm7x27a_ffa MACH_MSM7X27A_FFA MSM7X27A_FFA 3351 +msm7x27a_surf MACH_MSM7X27A_SURF MSM7X27A_SURF 3352 +msm7x27a_rumi3 MACH_MSM7X27A_RUMI3 MSM7X27A_RUMI3 3353 +dimmsam9g20 MACH_DIMMSAM9G20 DIMMSAM9G20 3354 +dimm_imx28 MACH_DIMM_IMX28 DIMM_IMX28 3355 +amk_a4 MACH_AMK_A4 AMK_A4 3356 +gnet_sgme MACH_GNET_SGME GNET_SGME 3357 +shooter_u MACH_SHOOTER_U SHOOTER_U 3358 +vmx53 MACH_VMX53 VMX53 3359 +rhino MACH_RHINO RHINO 3360 armlex4210 MACH_ARMLEX4210 ARMLEX4210 3361 +swarcoextmodem MACH_SWARCOEXTMODEM SWARCOEXTMODEM 3362 snowball MACH_SNOWBALL SNOWBALL 3363 +pcm049 MACH_PCM049 PCM049 3364 +vigor MACH_VIGOR VIGOR 3365 +oslo_amundsen MACH_OSLO_AMUNDSEN OSLO_AMUNDSEN 3366 +gsl_diamond MACH_GSL_DIAMOND GSL_DIAMOND 3367 +cv2201 MACH_CV2201 CV2201 3368 +cv2202 MACH_CV2202 CV2202 3369 +cv2203 MACH_CV2203 CV2203 3370 +vit_ibox MACH_VIT_IBOX VIT_IBOX 3371 +dm6441_esp MACH_DM6441_ESP DM6441_ESP 3372 +at91sam9x5ek MACH_AT91SAM9X5EK AT91SAM9X5EK 3373 +libra MACH_LIBRA LIBRA 3374 +easycrrh MACH_EASYCRRH EASYCRRH 3375 +tripel MACH_TRIPEL TRIPEL 3376 +endian_mini MACH_ENDIAN_MINI ENDIAN_MINI 3377 xilinx_ep107 MACH_XILINX_EP107 XILINX_EP107 3378 nuri MACH_NURI NURI 3379 +janus MACH_JANUS JANUS 3380 +ddnas MACH_DDNAS DDNAS 3381 +tag MACH_TAG TAG 3382 +tagw MACH_TAGW TAGW 3383 +nitrogen_vm_imx51 MACH_NITROGEN_VM_IMX51 NITROGEN_VM_IMX51 3384 +viprinet MACH_VIPRINET VIPRINET 3385 +bockw MACH_BOCKW BOCKW 3386 +eva2000 MACH_EVA2000 EVA2000 3387 +steelyard MACH_STEELYARD STEELYARD 3388 +nsslsboard MACH_NSSLSBOARD NSSLSBOARD 3392 +geneva_b5 MACH_GENEVA_B5 GENEVA_B5 3393 +spear1340 MACH_SPEAR1340 SPEAR1340 3394 +rexmas MACH_REXMAS REXMAS 3395 +msm8960_cdp MACH_MSM8960_CDP MSM8960_CDP 3396 +msm8960_fluid MACH_MSM8960_FLUID MSM8960_FLUID 3398 +msm8960_apq MACH_MSM8960_APQ MSM8960_APQ 3399 +helios_v2 MACH_HELIOS_V2 HELIOS_V2 3400 +mif10p MACH_MIF10P MIF10P 3401 +iam28 MACH_IAM28 IAM28 3402 +picasso MACH_PICASSO PICASSO 3403 +mr301a MACH_MR301A MR301A 3404 +notle MACH_NOTLE NOTLE 3405 +eelx2 MACH_EELX2 EELX2 3406 +moon MACH_MOON MOON 3407 +ruby MACH_RUBY RUBY 3408 +goldengate MACH_GOLDENGATE GOLDENGATE 3409 +ctbu_gen2 MACH_CTBU_GEN2 CTBU_GEN2 3410 +kmp_am17_01 MACH_KMP_AM17_01 KMP_AM17_01 3411 wtplug MACH_WTPLUG WTPLUG 3412 +mx27su2 MACH_MX27SU2 MX27SU2 3413 +nb31 MACH_NB31 NB31 3414 +hjsdu MACH_HJSDU HJSDU 3415 +td3_rev1 MACH_TD3_REV1 TD3_REV1 3416 +eag_ci4000 MACH_EAG_CI4000 EAG_CI4000 3417 +net5big_nand_v2 MACH_NET5BIG_NAND_V2 NET5BIG_NAND_V2 3418 +cpx2 MACH_CPX2 CPX2 3419 +net2big_nand_v2 MACH_NET2BIG_NAND_V2 NET2BIG_NAND_V2 3420 +ecuv5 MACH_ECUV5 ECUV5 3421 +hsgx6d MACH_HSGX6D HSGX6D 3422 +dawad7 MACH_DAWAD7 DAWAD7 3423 +sam9repeater MACH_SAM9REPEATER SAM9REPEATER 3424 +gt_i5700 MACH_GT_I5700 GT_I5700 3425 +ctera_plug_c2 MACH_CTERA_PLUG_C2 CTERA_PLUG_C2 3426 +marvelct MACH_MARVELCT MARVELCT 3427 +ag11005 MACH_AG11005 AG11005 3428 +vangogh MACH_VANGOGH VANGOGH 3430 +matrix505 MACH_MATRIX505 MATRIX505 3431 +oce_nigma MACH_OCE_NIGMA OCE_NIGMA 3432 +t55 MACH_T55 T55 3433 +bio3k MACH_BIO3K BIO3K 3434 +expressct MACH_EXPRESSCT EXPRESSCT 3435 +cardhu MACH_CARDHU CARDHU 3436 +aruba MACH_ARUBA ARUBA 3437 +bonaire MACH_BONAIRE BONAIRE 3438 +nuc700evb MACH_NUC700EVB NUC700EVB 3439 +nuc710evb MACH_NUC710EVB NUC710EVB 3440 +nuc740evb MACH_NUC740EVB NUC740EVB 3441 +nuc745evb MACH_NUC745EVB NUC745EVB 3442 +transcede MACH_TRANSCEDE TRANSCEDE 3443 +mora MACH_MORA MORA 3444 +nda_evm MACH_NDA_EVM NDA_EVM 3445 +timu MACH_TIMU TIMU 3446 +expressh MACH_EXPRESSH EXPRESSH 3447 veridis_a300 MACH_VERIDIS_A300 VERIDIS_A300 3448 +dm368_leopard MACH_DM368_LEOPARD DM368_LEOPARD 3449 +omap_mcop MACH_OMAP_MCOP OMAP_MCOP 3450 +tritip MACH_TRITIP TRITIP 3451 +sm1k MACH_SM1K SM1K 3452 +monch MACH_MONCH MONCH 3453 +curacao MACH_CURACAO CURACAO 3454 origen MACH_ORIGEN ORIGEN 3455 +epc10 MACH_EPC10 EPC10 3456 +sgh_i740 MACH_SGH_I740 SGH_I740 3457 +tuna MACH_TUNA TUNA 3458 +mx51_tulip MACH_MX51_TULIP MX51_TULIP 3459 +mx51_aster7 MACH_MX51_ASTER7 MX51_ASTER7 3460 +acro37xbrd MACH_ACRO37XBRD ACRO37XBRD 3461 +elke MACH_ELKE ELKE 3462 +sbc6000x MACH_SBC6000X SBC6000X 3463 +r1801e MACH_R1801E R1801E 3464 +h1600 MACH_H1600 H1600 3465 +mini210 MACH_MINI210 MINI210 3466 +mini8168 MACH_MINI8168 MINI8168 3467 +pc7308 MACH_PC7308 PC7308 3468 +kmm2m01 MACH_KMM2M01 KMM2M01 3470 +mx51erebus MACH_MX51EREBUS MX51EREBUS 3471 wm8650refboard MACH_WM8650REFBOARD WM8650REFBOARD 3472 +tuxrail MACH_TUXRAIL TUXRAIL 3473 +arthur MACH_ARTHUR ARTHUR 3474 +doorboy MACH_DOORBOY DOORBOY 3475 xarina MACH_XARINA XARINA 3476 +roverx7 MACH_ROVERX7 ROVERX7 3477 sdvr MACH_SDVR SDVR 3478 acer_maya MACH_ACER_MAYA ACER_MAYA 3479 pico MACH_PICO PICO 3480 @@ -770,7 +999,6 @@ promwad_jade MACH_PROMWAD_JADE PROMWAD_JADE 3708 amp MACH_AMP AMP 3709 gnet_amp MACH_GNET_AMP GNET_AMP 3710 toques MACH_TOQUES TOQUES 3711 -apx4devkit MACH_APX4DEVKIT APX4DEVKIT 3712 dct_storm MACH_DCT_STORM DCT_STORM 3713 owl MACH_OWL OWL 3715 cogent_csb1741 MACH_COGENT_CSB1741 COGENT_CSB1741 3716 @@ -835,6 +1063,7 @@ shelter MACH_SHELTER SHELTER 3778 omap3_devkit8500 MACH_OMAP3_DEVKIT8500 OMAP3_DEVKIT8500 3779 edgetd MACH_EDGETD EDGETD 3780 copperyard MACH_COPPERYARD COPPERYARD 3781 +edge MACH_EDGE EDGE 3782 edge_u MACH_EDGE_U EDGE_U 3783 edge_td MACH_EDGE_TD EDGE_TD 3784 wdss MACH_WDSS WDSS 3785 @@ -940,269 +1169,3 @@ elite_ulk MACH_ELITE_ULK ELITE_ULK 3888 pov2 MACH_POV2 POV2 3889 ipod_touch_2g MACH_IPOD_TOUCH_2G IPOD_TOUCH_2G 3890 da850_pqab MACH_DA850_PQAB DA850_PQAB 3891 -fermi MACH_FERMI FERMI 3892 -ccardwmx28 MACH_CCARDWMX28 CCARDWMX28 3893 -ccardmx28 MACH_CCARDMX28 CCARDMX28 3894 -fs20_fcm2050 MACH_FS20_FCM2050 FS20_FCM2050 3895 -kinetis MACH_KINETIS KINETIS 3896 -kai MACH_KAI KAI 3897 -bcthb2 MACH_BCTHB2 BCTHB2 3898 -inels3_cu MACH_INELS3_CU INELS3_CU 3899 -da850_apollo MACH_DA850_APOLLO DA850_APOLLO 3901 -tracnas MACH_TRACNAS TRACNAS 3902 -mityarm335x MACH_MITYARM335X MITYARM335X 3903 -xcgz7x MACH_XCGZ7X XCGZ7X 3904 -cubox MACH_CUBOX CUBOX 3905 -terminator MACH_TERMINATOR TERMINATOR 3906 -eye03 MACH_EYE03 EYE03 3907 -kota3 MACH_KOTA3 KOTA3 3908 -pscpe MACH_PSCPE PSCPE 3910 -akt1100 MACH_AKT1100 AKT1100 3911 -pcaaxl2 MACH_PCAAXL2 PCAAXL2 3912 -primodd_ct MACH_PRIMODD_CT PRIMODD_CT 3913 -nsbc MACH_NSBC NSBC 3914 -meson2_skt MACH_MESON2_SKT MESON2_SKT 3915 -meson2_ref MACH_MESON2_REF MESON2_REF 3916 -ccardwmx28js MACH_CCARDWMX28JS CCARDWMX28JS 3917 -ccardmx28js MACH_CCARDMX28JS CCARDMX28JS 3918 -indico MACH_INDICO INDICO 3919 -msm8960dt MACH_MSM8960DT MSM8960DT 3920 -primods MACH_PRIMODS PRIMODS 3921 -beluga_m1388 MACH_BELUGA_M1388 BELUGA_M1388 3922 -primotd MACH_PRIMOTD PRIMOTD 3923 -varan_master MACH_VARAN_MASTER VARAN_MASTER 3924 -primodd MACH_PRIMODD PRIMODD 3925 -jetduo MACH_JETDUO JETDUO 3926 -mx53_umobo MACH_MX53_UMOBO MX53_UMOBO 3927 -trats MACH_TRATS TRATS 3928 -starcraft MACH_STARCRAFT STARCRAFT 3929 -qseven_tegra2 MACH_QSEVEN_TEGRA2 QSEVEN_TEGRA2 3930 -lichee_sun4i_devbd MACH_LICHEE_SUN4I_DEVBD LICHEE_SUN4I_DEVBD 3931 -movenow MACH_MOVENOW MOVENOW 3932 -golf_u MACH_GOLF_U GOLF_U 3933 -msm7627a_evb MACH_MSM7627A_EVB MSM7627A_EVB 3934 -rambo MACH_RAMBO RAMBO 3935 -golfu MACH_GOLFU GOLFU 3936 -mango310 MACH_MANGO310 MANGO310 3937 -dns343 MACH_DNS343 DNS343 3938 -var_som_om44 MACH_VAR_SOM_OM44 VAR_SOM_OM44 3939 -naon MACH_NAON NAON 3940 -vp4000 MACH_VP4000 VP4000 3941 -impcard MACH_IMPCARD IMPCARD 3942 -smoovcam MACH_SMOOVCAM SMOOVCAM 3943 -cobham3725 MACH_COBHAM3725 COBHAM3725 3944 -cobham3730 MACH_COBHAM3730 COBHAM3730 3945 -cobham3703 MACH_COBHAM3703 COBHAM3703 3946 -quetzal MACH_QUETZAL QUETZAL 3947 -apq8064_cdp MACH_APQ8064_CDP APQ8064_CDP 3948 -apq8064_mtp MACH_APQ8064_MTP APQ8064_MTP 3949 -apq8064_fluid MACH_APQ8064_FLUID APQ8064_FLUID 3950 -apq8064_liquid MACH_APQ8064_LIQUID APQ8064_LIQUID 3951 -mango210 MACH_MANGO210 MANGO210 3952 -mango100 MACH_MANGO100 MANGO100 3953 -mango24 MACH_MANGO24 MANGO24 3954 -mango64 MACH_MANGO64 MANGO64 3955 -nsa320 MACH_NSA320 NSA320 3956 -elv_ccu2 MACH_ELV_CCU2 ELV_CCU2 3957 -triton_x00 MACH_TRITON_X00 TRITON_X00 3958 -triton_1500_2000 MACH_TRITON_1500_2000 TRITON_1500_2000 3959 -pogoplugv4 MACH_POGOPLUGV4 POGOPLUGV4 3960 -venus_cl MACH_VENUS_CL VENUS_CL 3961 -vulcano_g20 MACH_VULCANO_G20 VULCANO_G20 3962 -sgs_i9100 MACH_SGS_I9100 SGS_I9100 3963 -stsv2 MACH_STSV2 STSV2 3964 -csb1724 MACH_CSB1724 CSB1724 3965 -omapl138_lcdk MACH_OMAPL138_LCDK OMAPL138_LCDK 3966 -pvd_mx25 MACH_PVD_MX25 PVD_MX25 3968 -meson6_skt MACH_MESON6_SKT MESON6_SKT 3969 -meson6_ref MACH_MESON6_REF MESON6_REF 3970 -pxm MACH_PXM PXM 3971 -pogoplugv3 MACH_POGOPLUGV3 POGOPLUGV3 3973 -mlp89626 MACH_MLP89626 MLP89626 3974 -iomegahmndce MACH_IOMEGAHMNDCE IOMEGAHMNDCE 3975 -pogoplugv3pci MACH_POGOPLUGV3PCI POGOPLUGV3PCI 3976 -bntv250 MACH_BNTV250 BNTV250 3977 -mx53_qseven MACH_MX53_QSEVEN MX53_QSEVEN 3978 -gtl_it1100 MACH_GTL_IT1100 GTL_IT1100 3979 -mx6q_sabresd MACH_MX6Q_SABRESD MX6Q_SABRESD 3980 -mt4 MACH_MT4 MT4 3981 -jumbo_d MACH_JUMBO_D JUMBO_D 3982 -jumbo_i MACH_JUMBO_I JUMBO_I 3983 -fs20_dmp MACH_FS20_DMP FS20_DMP 3984 -dns320 MACH_DNS320 DNS320 3985 -mx28bacos MACH_MX28BACOS MX28BACOS 3986 -tl80 MACH_TL80 TL80 3987 -polatis_nic_1001 MACH_POLATIS_NIC_1001 POLATIS_NIC_1001 3988 -tely MACH_TELY TELY 3989 -u8520 MACH_U8520 U8520 3990 -manta MACH_MANTA MANTA 3991 -mpq8064_cdp MACH_MPQ8064_CDP MPQ8064_CDP 3993 -mpq8064_dtv MACH_MPQ8064_DTV MPQ8064_DTV 3995 -dm368som MACH_DM368SOM DM368SOM 3996 -gprisb2 MACH_GPRISB2 GPRISB2 3997 -chammid MACH_CHAMMID CHAMMID 3998 -seoul2 MACH_SEOUL2 SEOUL2 3999 -omap4_nooktablet MACH_OMAP4_NOOKTABLET OMAP4_NOOKTABLET 4000 -aalto MACH_AALTO AALTO 4001 -metro MACH_METRO METRO 4002 -cydm3730 MACH_CYDM3730 CYDM3730 4003 -tqma53 MACH_TQMA53 TQMA53 4004 -msm7627a_qrd3 MACH_MSM7627A_QRD3 MSM7627A_QRD3 4005 -mx28_canby MACH_MX28_CANBY MX28_CANBY 4006 -tiger MACH_TIGER TIGER 4007 -pcats_9307_type_a MACH_PCATS_9307_TYPE_A PCATS_9307_TYPE_A 4008 -pcats_9307_type_o MACH_PCATS_9307_TYPE_O PCATS_9307_TYPE_O 4009 -pcats_9307_type_r MACH_PCATS_9307_TYPE_R PCATS_9307_TYPE_R 4010 -streamplug MACH_STREAMPLUG STREAMPLUG 4011 -icechicken_dev MACH_ICECHICKEN_DEV ICECHICKEN_DEV 4012 -hedgehog MACH_HEDGEHOG HEDGEHOG 4013 -yusend_obc MACH_YUSEND_OBC YUSEND_OBC 4014 -imxninja MACH_IMXNINJA IMXNINJA 4015 -omap4_jarod MACH_OMAP4_JAROD OMAP4_JAROD 4016 -eco5_pk MACH_ECO5_PK ECO5_PK 4017 -qj2440 MACH_QJ2440 QJ2440 4018 -mx6q_mercury MACH_MX6Q_MERCURY MX6Q_MERCURY 4019 -cm6810 MACH_CM6810 CM6810 4020 -omap4_torpedo MACH_OMAP4_TORPEDO OMAP4_TORPEDO 4021 -nsa310 MACH_NSA310 NSA310 4022 -tmx536 MACH_TMX536 TMX536 4023 -ktt20 MACH_KTT20 KTT20 4024 -dragonix MACH_DRAGONIX DRAGONIX 4025 -lungching MACH_LUNGCHING LUNGCHING 4026 -bulogics MACH_BULOGICS BULOGICS 4027 -mx535_sx MACH_MX535_SX MX535_SX 4028 -ngui3250 MACH_NGUI3250 NGUI3250 4029 -salutec_dac MACH_SALUTEC_DAC SALUTEC_DAC 4030 -loco MACH_LOCO LOCO 4031 -ctera_plug_usi MACH_CTERA_PLUG_USI CTERA_PLUG_USI 4032 -scepter MACH_SCEPTER SCEPTER 4033 -sga MACH_SGA SGA 4034 -p_81_j5 MACH_P_81_J5 P_81_J5 4035 -p_81_o4 MACH_P_81_O4 P_81_O4 4036 -msm8625_surf MACH_MSM8625_SURF MSM8625_SURF 4037 -carallon_shark MACH_CARALLON_SHARK CARALLON_SHARK 4038 -ordog MACH_ORDOG ORDOG 4040 -puente_io MACH_PUENTE_IO PUENTE_IO 4041 -msm8625_evb MACH_MSM8625_EVB MSM8625_EVB 4042 -ev_am1707 MACH_EV_AM1707 EV_AM1707 4043 -ev_am1707e2 MACH_EV_AM1707E2 EV_AM1707E2 4044 -ev_am3517e2 MACH_EV_AM3517E2 EV_AM3517E2 4045 -calabria MACH_CALABRIA CALABRIA 4046 -ev_imx287 MACH_EV_IMX287 EV_IMX287 4047 -erau MACH_ERAU ERAU 4048 -sichuan MACH_SICHUAN SICHUAN 4049 -davinci_da850 MACH_DAVINCI_DA850 DAVINCI_DA850 4051 -omap138_trunarc MACH_OMAP138_TRUNARC OMAP138_TRUNARC 4052 -bcm4761 MACH_BCM4761 BCM4761 4053 -picasso_e2 MACH_PICASSO_E2 PICASSO_E2 4054 -picasso_mf MACH_PICASSO_MF PICASSO_MF 4055 -miro MACH_MIRO MIRO 4056 -at91sam9g20ewon3 MACH_AT91SAM9G20EWON3 AT91SAM9G20EWON3 4057 -yoyo MACH_YOYO YOYO 4058 -windjkl MACH_WINDJKL WINDJKL 4059 -monarudo MACH_MONARUDO MONARUDO 4060 -batan MACH_BATAN BATAN 4061 -tadao MACH_TADAO TADAO 4062 -baso MACH_BASO BASO 4063 -mahon MACH_MAHON MAHON 4064 -villec2 MACH_VILLEC2 VILLEC2 4065 -asi1230 MACH_ASI1230 ASI1230 4066 -alaska MACH_ALASKA ALASKA 4067 -swarco_shdsl2 MACH_SWARCO_SHDSL2 SWARCO_SHDSL2 4068 -oxrtu MACH_OXRTU OXRTU 4069 -omap5_panda MACH_OMAP5_PANDA OMAP5_PANDA 4070 -c8000 MACH_C8000 C8000 4072 -bje_display3_5 MACH_BJE_DISPLAY3_5 BJE_DISPLAY3_5 4073 -picomod7 MACH_PICOMOD7 PICOMOD7 4074 -picocom5 MACH_PICOCOM5 PICOCOM5 4075 -qblissa8 MACH_QBLISSA8 QBLISSA8 4076 -armstonea8 MACH_ARMSTONEA8 ARMSTONEA8 4077 -netdcu14 MACH_NETDCU14 NETDCU14 4078 -at91sam9x5_epiphan MACH_AT91SAM9X5_EPIPHAN AT91SAM9X5_EPIPHAN 4079 -p2u MACH_P2U P2U 4080 -doris MACH_DORIS DORIS 4081 -j49 MACH_J49 J49 4082 -vdss2e MACH_VDSS2E VDSS2E 4083 -vc300 MACH_VC300 VC300 4084 -ns115_pad_test MACH_NS115_PAD_TEST NS115_PAD_TEST 4085 -ns115_pad_ref MACH_NS115_PAD_REF NS115_PAD_REF 4086 -ns115_phone_test MACH_NS115_PHONE_TEST NS115_PHONE_TEST 4087 -ns115_phone_ref MACH_NS115_PHONE_REF NS115_PHONE_REF 4088 -golfc MACH_GOLFC GOLFC 4089 -xerox_olympus MACH_XEROX_OLYMPUS XEROX_OLYMPUS 4090 -mx6sl_arm2 MACH_MX6SL_ARM2 MX6SL_ARM2 4091 -csb1701_csb1726 MACH_CSB1701_CSB1726 CSB1701_CSB1726 4092 -at91sam9xeek MACH_AT91SAM9XEEK AT91SAM9XEEK 4093 -ebv210 MACH_EBV210 EBV210 4094 -msm7627a_qrd7 MACH_MSM7627A_QRD7 MSM7627A_QRD7 4095 -svthin MACH_SVTHIN SVTHIN 4096 -duovero MACH_DUOVERO DUOVERO 4097 -chupacabra MACH_CHUPACABRA CHUPACABRA 4098 -scorpion MACH_SCORPION SCORPION 4099 -davinci_he_hmi10 MACH_DAVINCI_HE_HMI10 DAVINCI_HE_HMI10 4100 -topkick MACH_TOPKICK TOPKICK 4101 -m3_auguestrush MACH_M3_AUGUESTRUSH M3_AUGUESTRUSH 4102 -ipc335x MACH_IPC335X IPC335X 4103 -sun4i MACH_SUN4I SUN4I 4104 -imx233_olinuxino MACH_IMX233_OLINUXINO IMX233_OLINUXINO 4105 -k2_wl MACH_K2_WL K2_WL 4106 -k2_ul MACH_K2_UL K2_UL 4107 -k2_cl MACH_K2_CL K2_CL 4108 -minbari_w MACH_MINBARI_W MINBARI_W 4109 -minbari_m MACH_MINBARI_M MINBARI_M 4110 -k035 MACH_K035 K035 4111 -ariel MACH_ARIEL ARIEL 4112 -arielsaarc MACH_ARIELSAARC ARIELSAARC 4113 -arieldkb MACH_ARIELDKB ARIELDKB 4114 -armadillo810 MACH_ARMADILLO810 ARMADILLO810 4115 -tam335x MACH_TAM335X TAM335X 4116 -grouper MACH_GROUPER GROUPER 4117 -mpcsa21_9g20 MACH_MPCSA21_9G20 MPCSA21_9G20 4118 -m6u_cpu MACH_M6U_CPU M6U_CPU 4119 -davinci_dp10 MACH_DAVINCI_DP10 DAVINCI_DP10 4120 -ginkgo MACH_GINKGO GINKGO 4121 -cgt_qmx6 MACH_CGT_QMX6 CGT_QMX6 4122 -profpga MACH_PROFPGA PROFPGA 4123 -acfx100oc MACH_ACFX100OC ACFX100OC 4124 -acfx100nb MACH_ACFX100NB ACFX100NB 4125 -capricorn MACH_CAPRICORN CAPRICORN 4126 -pisces MACH_PISCES PISCES 4127 -aries MACH_ARIES ARIES 4128 -cancer MACH_CANCER CANCER 4129 -leo MACH_LEO LEO 4130 -virgo MACH_VIRGO VIRGO 4131 -sagittarius MACH_SAGITTARIUS SAGITTARIUS 4132 -devil MACH_DEVIL DEVIL 4133 -ballantines MACH_BALLANTINES BALLANTINES 4134 -omap3_procerusvpu MACH_OMAP3_PROCERUSVPU OMAP3_PROCERUSVPU 4135 -my27 MACH_MY27 MY27 4136 -sun6i MACH_SUN6I SUN6I 4137 -sun5i MACH_SUN5I SUN5I 4138 -mx512_mx MACH_MX512_MX MX512_MX 4139 -kzm9g MACH_KZM9G KZM9G 4140 -vdstbn MACH_VDSTBN VDSTBN 4141 -cfa10036 MACH_CFA10036 CFA10036 4142 -cfa10049 MACH_CFA10049 CFA10049 4143 -pcm051 MACH_PCM051 PCM051 4144 -vybrid_vf7xx MACH_VYBRID_VF7XX VYBRID_VF7XX 4145 -vybrid_vf6xx MACH_VYBRID_VF6XX VYBRID_VF6XX 4146 -vybrid_vf5xx MACH_VYBRID_VF5XX VYBRID_VF5XX 4147 -vybrid_vf4xx MACH_VYBRID_VF4XX VYBRID_VF4XX 4148 -aria_g25 MACH_ARIA_G25 ARIA_G25 4149 -bcm21553 MACH_BCM21553 BCM21553 4150 -smdk5410 MACH_SMDK5410 SMDK5410 4151 -lpc18xx MACH_LPC18XX LPC18XX 4152 -oratisparty MACH_ORATISPARTY ORATISPARTY 4153 -qseven MACH_QSEVEN QSEVEN 4154 -gmv_generic MACH_GMV_GENERIC GMV_GENERIC 4155 -th_link_eth MACH_TH_LINK_ETH TH_LINK_ETH 4156 -tn_muninn MACH_TN_MUNINN TN_MUNINN 4157 -rampage MACH_RAMPAGE RAMPAGE 4158 -visstrim_mv10 MACH_VISSTRIM_MV10 VISSTRIM_MV10 4159 -mx28_wilma MACH_MX28_WILMA MX28_WILMA 4164 -msm8625_ffa MACH_MSM8625_FFA MSM8625_FFA 4166 -vpu101 MACH_VPU101 VPU101 4167 -baileys MACH_BAILEYS BAILEYS 4169 -familybox MACH_FAMILYBOX FAMILYBOX 4170 -ensemble_mx35 MACH_ENSEMBLE_MX35 ENSEMBLE_MX35 4171 -sc_sps_1 MACH_SC_SPS_1 SC_SPS_1 4172 diff --git a/trunk/arch/arm/vfp/vfpmodule.c b/trunk/arch/arm/vfp/vfpmodule.c index 586961929e96..bc683b8219b5 100644 --- a/trunk/arch/arm/vfp/vfpmodule.c +++ b/trunk/arch/arm/vfp/vfpmodule.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -241,11 +240,11 @@ static void vfp_panic(char *reason, u32 inst) { int i; - pr_err("VFP: Error: %s\n", reason); - pr_err("VFP: EXC 0x%08x SCR 0x%08x INST 0x%08x\n", + printk(KERN_ERR "VFP: Error: %s\n", reason); + printk(KERN_ERR "VFP: EXC 0x%08x SCR 0x%08x INST 0x%08x\n", fmrx(FPEXC), fmrx(FPSCR), inst); for (i = 0; i < 32; i += 2) - pr_err("VFP: s%2u: 0x%08x s%2u: 0x%08x\n", + printk(KERN_ERR "VFP: s%2u: 0x%08x s%2u: 0x%08x\n", i, vfp_get_float(i), i+1, vfp_get_float(i+1)); } @@ -433,10 +432,7 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) static void vfp_enable(void *unused) { - u32 access; - - BUG_ON(preemptible()); - access = get_copro_access(); + u32 access = get_copro_access(); /* * Enable full access to VFP (cp10 and cp11) @@ -452,7 +448,7 @@ static int vfp_pm_suspend(void) /* if vfp is on, then save state for resumption */ if (fpexc & FPEXC_EN) { - pr_debug("%s: saving vfp state\n", __func__); + printk(KERN_DEBUG "%s: saving vfp state\n", __func__); vfp_save_state(&ti->vfpstate, fpexc); /* disable, just in case */ @@ -577,6 +573,12 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp, * entry. */ hwstate->fpscr &= ~(FPSCR_LENGTH_MASK | FPSCR_STRIDE_MASK); + + /* + * Disable VFP in the hwstate so that we can detect if it gets + * used. + */ + hwstate->fpexc &= ~FPEXC_EN; return 0; } @@ -589,8 +591,12 @@ int vfp_restore_user_hwstate(struct user_vfp __user *ufp, unsigned long fpexc; int err = 0; - /* Disable VFP to avoid corrupting the new thread state. */ - vfp_flush_hwstate(thread); + /* + * If VFP has been used, then disable it to avoid corrupting + * the new thread state. + */ + if (hwstate->fpexc & FPEXC_EN) + vfp_flush_hwstate(thread); /* * Copy the floating point registers. There can be unused @@ -651,7 +657,7 @@ static int __init vfp_init(void) unsigned int cpu_arch = cpu_architecture(); if (cpu_arch >= CPU_ARCH_ARMv6) - on_each_cpu(vfp_enable, NULL, 1); + vfp_enable(NULL); /* * First check that there is a VFP that we can use. @@ -664,16 +670,18 @@ static int __init vfp_init(void) barrier(); vfp_vector = vfp_null_entry; - pr_info("VFP support v0.3: "); + printk(KERN_INFO "VFP support v0.3: "); if (VFP_arch) - pr_cont("not present\n"); + printk("not present\n"); else if (vfpsid & FPSID_NODOUBLE) { - pr_cont("no double precision support\n"); + printk("no double precision support\n"); } else { hotcpu_notifier(vfp_hotplug, 0); + smp_call_function(vfp_enable, NULL, 1); + VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */ - pr_cont("implementor %02x architecture %d part %02x variant %x rev %x\n", + printk("implementor %02x architecture %d part %02x variant %x rev %x\n", (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT, (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT, (vfpsid & FPSID_PART_MASK) >> FPSID_PART_BIT, diff --git a/trunk/arch/avr32/kernel/Makefile b/trunk/arch/avr32/kernel/Makefile index 9e2c465ef3a6..18229d0d1861 100644 --- a/trunk/arch/avr32/kernel/Makefile +++ b/trunk/arch/avr32/kernel/Makefile @@ -8,7 +8,7 @@ obj-$(CONFIG_SUBARCH_AVR32B) += entry-avr32b.o obj-y += syscall_table.o syscall-stubs.o irq.o obj-y += setup.o traps.o ocd.o ptrace.o obj-y += signal.o sys_avr32.o process.o time.o -obj-y += switch_to.o cpu.o +obj-y += init_task.o switch_to.o cpu.o obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_STACKTRACE) += stacktrace.o diff --git a/trunk/arch/avr32/kernel/init_task.c b/trunk/arch/avr32/kernel/init_task.c new file mode 100644 index 000000000000..6b2343e6fe33 --- /dev/null +++ b/trunk/arch/avr32/kernel/init_task.c @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2004-2006 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include + +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +/* + * Initial thread structure. Must be aligned on an 8192-byte boundary. + */ +union thread_union init_thread_union __init_task_data = + { INIT_THREAD_INFO(init_task) }; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); + +EXPORT_SYMBOL(init_task); diff --git a/trunk/arch/blackfin/ADI_BSD.txt b/trunk/arch/blackfin/ADI_BSD.txt new file mode 100644 index 000000000000..501d0b645943 --- /dev/null +++ b/trunk/arch/blackfin/ADI_BSD.txt @@ -0,0 +1,41 @@ +This BSD-Style License applies to a few files in ./arch/blackfin directory, +and is included here, so people understand which code they can use outside +the Linux kernel, in non-GPL based projects. + +Using the files released under the "ADI BSD" license, must comply with +these license terms. + +-------------------------------------------------------------------------- + +Copyright Analog Devices, Inc. + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + - Neither the name of Analog Devices, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + - The use of this software may or may not infringe the patent rights + of one or more patent holders. This license does not release you + from the requirement that you obtain separate licenses from these + patent holders to use this software. + +THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE diff --git a/trunk/arch/blackfin/Clear_BSD.txt b/trunk/arch/blackfin/Clear_BSD.txt deleted file mode 100644 index bfa4b378a368..000000000000 --- a/trunk/arch/blackfin/Clear_BSD.txt +++ /dev/null @@ -1,33 +0,0 @@ -The Clear BSD license: - -Copyright (c) 2012, Analog Devices, Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted (subject to the limitations in the -disclaimer below) provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the - distribution. - -* Neither the name of Analog Devices, Inc. nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE -GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT -HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/trunk/arch/blackfin/Kconfig b/trunk/arch/blackfin/Kconfig index 7f3c589cc024..373a6902d8fa 100644 --- a/trunk/arch/blackfin/Kconfig +++ b/trunk/arch/blackfin/Kconfig @@ -37,7 +37,6 @@ config BLACKFIN select GENERIC_IRQ_PROBE select IRQ_PER_CPU if SMP select HAVE_NMI_WATCHDOG if NMI_WATCHDOG - select GENERIC_SMP_IDLE_THREAD config GENERIC_CSUM def_bool y @@ -227,12 +226,6 @@ config BF561 help BF561 Processor Support. -config BF609 - bool "BF609" - select CLKDEV_LOOKUP - help - BF609 Processor Support. - endchoice config SMP @@ -258,27 +251,27 @@ config HOTPLUG_CPU config BF_REV_MIN int - default 0 if (BF51x || BF52x || (BF54x && !BF54xM)) || BF60x + default 0 if (BF51x || BF52x || (BF54x && !BF54xM)) default 2 if (BF537 || BF536 || BF534) default 3 if (BF561 || BF533 || BF532 || BF531 || BF54xM) default 4 if (BF538 || BF539) config BF_REV_MAX int - default 2 if (BF51x || BF52x || (BF54x && !BF54xM)) || BF60x + default 2 if (BF51x || BF52x || (BF54x && !BF54xM)) default 3 if (BF537 || BF536 || BF534 || BF54xM) default 5 if (BF561 || BF538 || BF539) default 6 if (BF533 || BF532 || BF531) choice prompt "Silicon Rev" - default BF_REV_0_0 if (BF51x || BF52x || BF60x) + default BF_REV_0_0 if (BF51x || BF52x) default BF_REV_0_2 if (BF534 || BF536 || BF537 || (BF54x && !BF54xM)) default BF_REV_0_3 if (BF531 || BF532 || BF533 || BF54xM || BF561) config BF_REV_0_0 bool "0.0" - depends on (BF51x || BF52x || (BF54x && !BF54xM) || BF60x) + depends on (BF51x || BF52x || (BF54x && !BF54xM)) config BF_REV_0_1 bool "0.1" @@ -357,7 +350,6 @@ source "arch/blackfin/mach-bf561/Kconfig" source "arch/blackfin/mach-bf537/Kconfig" source "arch/blackfin/mach-bf538/Kconfig" source "arch/blackfin/mach-bf548/Kconfig" -source "arch/blackfin/mach-bf609/Kconfig" menu "Board customizations" @@ -387,12 +379,6 @@ config BOOT_LOAD memory region is used to capture NULL pointer references as well as some core kernel functions. -config PHY_RAM_BASE_ADDRESS - hex "Physical RAM Base" - default 0x0 - help - set BF609 FPGA physical SRAM base address - config ROM_BASE hex "Kernel ROM Base" depends on ROMKERNEL @@ -436,7 +422,7 @@ config BFIN_KERNEL_CLOCK config PLL_BYPASS bool "Bypass PLL" - depends on BFIN_KERNEL_CLOCK && (!BF60x) + depends on BFIN_KERNEL_CLOCK default n config CLKIN_HALF @@ -455,7 +441,7 @@ config VCO_MULT default "20" if (BFIN537_STAMP || BFIN527_EZKIT || BFIN527_EZKIT_V2 || BFIN548_EZKIT || BFIN548_BLUETECHNIX_CM || BFIN538_EZKIT) default "22" if BFIN533_BLUETECHNIX_CM default "20" if (BFIN537_BLUETECHNIX_CM_E || BFIN537_BLUETECHNIX_CM_U || BFIN527_BLUETECHNIX_CM || BFIN561_BLUETECHNIX_CM) - default "20" if (BFIN561_EZKIT || BF609) + default "20" if BFIN561_EZKIT default "16" if (H8606_HVSISTEMAS || BLACKSTAMP || BFIN526_EZBRD || BFIN518F_EZBRD) default "25" if BFIN527_AD7160EVAL help @@ -487,45 +473,12 @@ config SCLK_DIV int "System Clock Divider" depends on BFIN_KERNEL_CLOCK range 1 15 - default 4 + default 5 help - This sets the frequency of the system clock (including SDRAM or DDR) on - !BF60x else it set the clock for system buses and provides the - source from which SCLK0 and SCLK1 are derived. + This sets the frequency of the system clock (including SDRAM or DDR). This can be between 1 and 15 System Clock = (PLL frequency) / (this setting) -config SCLK0_DIV - int "System Clock0 Divider" - depends on BFIN_KERNEL_CLOCK && BF60x - range 1 15 - default 1 - help - This sets the frequency of the system clock0 for PVP and all other - peripherals not clocked by SCLK1. - This can be between 1 and 15 - System Clock0 = (System Clock) / (this setting) - -config SCLK1_DIV - int "System Clock1 Divider" - depends on BFIN_KERNEL_CLOCK && BF60x - range 1 15 - default 1 - help - This sets the frequency of the system clock1 (including SPORT, SPI and ACM). - This can be between 1 and 15 - System Clock1 = (System Clock) / (this setting) - -config DCLK_DIV - int "DDR Clock Divider" - depends on BFIN_KERNEL_CLOCK && BF60x - range 1 15 - default 2 - help - This sets the frequency of the DDR memory. - This can be between 1 and 15 - DDR Clock = (PLL frequency) / (this setting) - choice prompt "DDR SDRAM Chip Type" depends on BFIN_KERNEL_CLOCK @@ -541,7 +494,7 @@ endchoice choice prompt "DDR/SDRAM Timing" - depends on BFIN_KERNEL_CLOCK && !BF60x + depends on BFIN_KERNEL_CLOCK default BFIN_KERNEL_CLOCK_MEMINIT_CALC help This option allows you to specify Blackfin SDRAM/DDR Timing parameters @@ -623,7 +576,6 @@ config MAX_VCO_HZ default 600000000 if BF548 default 533333333 if BF549 default 600000000 if BF561 - default 800000000 if BF609 config MIN_VCO_HZ int @@ -631,7 +583,6 @@ config MIN_VCO_HZ config MAX_SCLK_HZ int - default 200000000 if BF609 default 133333333 config MIN_SCLK_HZ @@ -1100,7 +1051,7 @@ endchoice config BFIN_L2_DCACHEABLE bool "Enable DCACHE for L2 SRAM" depends on BFIN_DCACHE - depends on (BF54x || BF561 || BF60x) && !SMP + depends on (BF54x || BF561) && !SMP default n choice prompt "L2 SRAM DCACHE policy" @@ -1126,7 +1077,6 @@ config MPU comment "Asynchronous Memory Configuration" menu "EBIU_AMGCTL Global Control" - depends on !BF60x config C_AMCKEN bool "Enable CLKOUT" default y @@ -1177,7 +1127,6 @@ endchoice endmenu menu "EBIU_AMBCTL Control" - depends on !BF60x config BANK_0 hex "Bank 0 (AMBCTL0.L)" default 0x7BB0 @@ -1257,7 +1206,7 @@ config ARCH_SUSPEND_POSSIBLE choice prompt "Standby Power Saving Mode" - depends on PM && !BF60x + depends on PM default PM_BFIN_SLEEP_DEEPER config PM_BFIN_SLEEP_DEEPER bool "Sleep Deeper" @@ -1312,118 +1261,6 @@ config PM_BFIN_WAKE_GP On ADSP-BF549 this option enables the the same functionality on the /MRXON pin also PH7. -config PM_BFIN_WAKE_PA15 - bool "Allow Wake-Up from PA15" - depends on PM && BF60x - default n - help - Enable PA15 Wake-Up - -config PM_BFIN_WAKE_PA15_POL - int "Wake-up priority" - depends on PM_BFIN_WAKE_PA15 - default 0 - help - Wake-Up priority 0(low) 1(high) - -config PM_BFIN_WAKE_PB15 - bool "Allow Wake-Up from PB15" - depends on PM && BF60x - default n - help - Enable PB15 Wake-Up - -config PM_BFIN_WAKE_PB15_POL - int "Wake-up priority" - depends on PM_BFIN_WAKE_PB15 - default 0 - help - Wake-Up priority 0(low) 1(high) - -config PM_BFIN_WAKE_PC15 - bool "Allow Wake-Up from PC15" - depends on PM && BF60x - default n - help - Enable PC15 Wake-Up - -config PM_BFIN_WAKE_PC15_POL - int "Wake-up priority" - depends on PM_BFIN_WAKE_PC15 - default 0 - help - Wake-Up priority 0(low) 1(high) - -config PM_BFIN_WAKE_PD06 - bool "Allow Wake-Up from PD06(ETH0_PHYINT)" - depends on PM && BF60x - default n - help - Enable PD06(ETH0_PHYINT) Wake-up - -config PM_BFIN_WAKE_PD06_POL - int "Wake-up priority" - depends on PM_BFIN_WAKE_PD06 - default 0 - help - Wake-Up priority 0(low) 1(high) - -config PM_BFIN_WAKE_PE12 - bool "Allow Wake-Up from PE12(ETH1_PHYINT, PUSH BUTTON)" - depends on PM && BF60x - default n - help - Enable PE12(ETH1_PHYINT, PUSH BUTTON) Wake-up - -config PM_BFIN_WAKE_PE12_POL - int "Wake-up priority" - depends on PM_BFIN_WAKE_PE12 - default 0 - help - Wake-Up priority 0(low) 1(high) - -config PM_BFIN_WAKE_PG04 - bool "Allow Wake-Up from PG04(CAN0_RX)" - depends on PM && BF60x - default n - help - Enable PG04(CAN0_RX) Wake-up - -config PM_BFIN_WAKE_PG04_POL - int "Wake-up priority" - depends on PM_BFIN_WAKE_PG04 - default 0 - help - Wake-Up priority 0(low) 1(high) - -config PM_BFIN_WAKE_PG13 - bool "Allow Wake-Up from PG13" - depends on PM && BF60x - default n - help - Enable PG13 Wake-Up - -config PM_BFIN_WAKE_PG13_POL - int "Wake-up priority" - depends on PM_BFIN_WAKE_PG13 - default 0 - help - Wake-Up priority 0(low) 1(high) - -config PM_BFIN_WAKE_USB - bool "Allow Wake-Up from (USB)" - depends on PM && BF60x - default n - help - Enable (USB) Wake-up - -config PM_BFIN_WAKE_USB_POL - int "Wake-up priority" - depends on PM_BFIN_WAKE_USB - default 0 - help - Wake-Up priority 0(low) 1(high) - endmenu menu "CPU Frequency scaling" diff --git a/trunk/arch/blackfin/Kconfig.debug b/trunk/arch/blackfin/Kconfig.debug index 79594694ee90..e2a3d4c8ab9a 100644 --- a/trunk/arch/blackfin/Kconfig.debug +++ b/trunk/arch/blackfin/Kconfig.debug @@ -253,11 +253,4 @@ config BFIN_PSEUDODBG_INSNS Most people should say N here. -config BFIN_PM_WAKEUP_TIME_BENCH - bool "Display the total time for kernel to resume from power saving mode" - default n - help - Display the total time when kernel resumes normal from standby or - suspend to mem mode. - endmenu diff --git a/trunk/arch/blackfin/Makefile b/trunk/arch/blackfin/Makefile index d3d7e64ca96d..46f42b2066e5 100644 --- a/trunk/arch/blackfin/Makefile +++ b/trunk/arch/blackfin/Makefile @@ -54,7 +54,6 @@ machine-$(CONFIG_BF548M) := bf548 machine-$(CONFIG_BF549) := bf548 machine-$(CONFIG_BF549M) := bf548 machine-$(CONFIG_BF561) := bf561 -machine-$(CONFIG_BF609) := bf609 MACHINE := $(machine-y) export MACHINE @@ -87,7 +86,6 @@ cpu-$(CONFIG_BF548M) := bf548m cpu-$(CONFIG_BF549) := bf549 cpu-$(CONFIG_BF549M) := bf549m cpu-$(CONFIG_BF561) := bf561 -cpu-$(CONFIG_BF609) := bf609 rev-$(CONFIG_BF_REV_0_0) := 0.0 rev-$(CONFIG_BF_REV_0_1) := 0.1 @@ -109,6 +107,8 @@ KBUILD_AFLAGS += -mcpu=$(CPU_REV) CHECKFLAGS_SILICON = $(shell echo "" | $(CPP) $(KBUILD_CFLAGS) -dD - 2>/dev/null | awk '$$2 == "__SILICON_REVISION__" { print $$3 }') CHECKFLAGS += -D__SILICON_REVISION__=$(CHECKFLAGS_SILICON) -D__bfin__ +head-y := arch/$(ARCH)/kernel/init_task.o + core-y += arch/$(ARCH)/kernel/ arch/$(ARCH)/mm/ arch/$(ARCH)/mach-common/ # If we have a machine-specific directory, then include it in the build. diff --git a/trunk/arch/blackfin/configs/BF561-EZKIT-SMP_defconfig b/trunk/arch/blackfin/configs/BF561-EZKIT-SMP_defconfig index e2a2fa5935ce..680730eeaf23 100644 --- a/trunk/arch/blackfin/configs/BF561-EZKIT-SMP_defconfig +++ b/trunk/arch/blackfin/configs/BF561-EZKIT-SMP_defconfig @@ -21,12 +21,14 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_IOSCHED_CFQ is not set CONFIG_PREEMPT_VOLUNTARY=y CONFIG_BF561=y -CONFIG_SMP=y CONFIG_IRQ_TIMER0=10 CONFIG_CLKIN_HZ=30000000 CONFIG_HIGH_RES_TIMERS=y CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 CONFIG_BFIN_GPTIMERS=m +CONFIG_BFIN_EXTMEM_WRITETHROUGH=y +CONFIG_BFIN_L2_DCACHEABLE=y +CONFIG_BFIN_L2_WRITETHROUGH=y CONFIG_C_CDPRIO=y CONFIG_BANK_3=0xAAC2 CONFIG_BINFMT_FLAT=y diff --git a/trunk/arch/blackfin/configs/BF609-EZKIT_defconfig b/trunk/arch/blackfin/configs/BF609-EZKIT_defconfig deleted file mode 100644 index be9526bee4fb..000000000000 --- a/trunk/arch/blackfin/configs/BF609-EZKIT_defconfig +++ /dev/null @@ -1,155 +0,0 @@ -CONFIG_EXPERIMENTAL=y -CONFIG_SYSVIPC=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_BLK_DEV_INITRD=y -CONFIG_EXPERT=y -# CONFIG_ELF_CORE is not set -# CONFIG_FUTEX is not set -# CONFIG_SIGNALFD is not set -# CONFIG_TIMERFD is not set -# CONFIG_EVENTFD is not set -# CONFIG_AIO is not set -CONFIG_SLAB=y -CONFIG_MMAP_ALLOW_UNINITIALIZED=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_LBDAF is not set -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_PREEMPT_VOLUNTARY=y -CONFIG_BF609=y -CONFIG_PINT1_ASSIGN=0x01010000 -CONFIG_PINT2_ASSIGN=0x07000101 -CONFIG_PINT3_ASSIGN=0x02020303 -CONFIG_HIGH_RES_TIMERS=y -CONFIG_IP_CHECKSUM_L1=y -CONFIG_SYSCALL_TAB_L1=y -CONFIG_CPLB_SWITCH_TAB_L1=y -# CONFIG_APP_STACK_L1 is not set -# CONFIG_BFIN_INS_LOWOVERHEAD is not set -CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 -CONFIG_BINFMT_FLAT=y -CONFIG_BINFMT_ZFLAT=y -CONFIG_PM_BFIN_WAKE_PE12=y -CONFIG_PM_BFIN_WAKE_PE12_POL=1 -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -# CONFIG_IPV6 is not set -CONFIG_NETFILTER=y -CONFIG_CAN=y -CONFIG_CAN_BFIN=y -CONFIG_IRDA=y -CONFIG_IRTTY_SIR=y -# CONFIG_WIRELESS is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_FW_LOADER=m -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_STAA=y -CONFIG_MTD_COMPLEX_MAPPINGS=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_M25P80=y -CONFIG_MTD_UBI=m -CONFIG_SCSI=y -CONFIG_BLK_DEV_SD=y -CONFIG_NETDEVICES=y -# CONFIG_NET_VENDOR_BROADCOM is not set -# CONFIG_NET_VENDOR_CHELSIO is not set -# CONFIG_NET_VENDOR_INTEL is not set -# CONFIG_NET_VENDOR_MARVELL is not set -# CONFIG_NET_VENDOR_MICREL is not set -# CONFIG_NET_VENDOR_MICROCHIP is not set -# CONFIG_NET_VENDOR_NATSEMI is not set -# CONFIG_NET_VENDOR_SEEQ is not set -# CONFIG_NET_VENDOR_SMSC is not set -CONFIG_STMMAC_ETH=y -CONFIG_STMMAC_IEEE1588=y -# CONFIG_WLAN is not set -# CONFIG_INPUT_MOUSEDEV is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_MISC=y -CONFIG_INPUT_BFIN_ROTARY=y -# CONFIG_SERIO is not set -# CONFIG_LEGACY_PTYS is not set -CONFIG_BFIN_SIMPLE_TIMER=m -CONFIG_BFIN_LINKPORT=y -# CONFIG_DEVKMEM is not set -CONFIG_SERIAL_BFIN=y -CONFIG_SERIAL_BFIN_CONSOLE=y -CONFIG_SERIAL_BFIN_UART0=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_BLACKFIN_TWI=y -CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 -CONFIG_SPI=y -CONFIG_SPI_BFIN6XX=y -CONFIG_GPIOLIB=y -CONFIG_GPIO_SYSFS=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_BFIN_WDT=y -CONFIG_SOUND=m -CONFIG_SND=m -CONFIG_SND_MIXER_OSS=m -CONFIG_SND_PCM_OSS=m -# CONFIG_SND_DRIVERS is not set -# CONFIG_SND_SPI is not set -# CONFIG_SND_USB is not set -CONFIG_SND_SOC=m -CONFIG_SND_BF6XX_I2S=m -CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61=m -CONFIG_SND_SOC_ALL_CODECS=m -CONFIG_USB=y -CONFIG_USB_MUSB_HDRC=y -CONFIG_USB_MUSB_BLACKFIN=m -CONFIG_USB_STORAGE=y -CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_MUSB_HDRC=y -CONFIG_USB_ZERO=y -CONFIG_MMC=y -CONFIG_SDH_BFIN=y -# CONFIG_IOMMU_SUPPORT is not set -CONFIG_EXT2_FS=y -# CONFIG_DNOTIFY is not set -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_JFFS2_FS=m -CONFIG_UBIFS_FS=m -CONFIG_NFS_FS=m -CONFIG_NFS_V3=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_ISO8859_1=y -CONFIG_DEBUG_FS=y -CONFIG_DEBUG_SHIRQ=y -CONFIG_DETECT_HUNG_TASK=y -CONFIG_DEBUG_INFO=y -CONFIG_FRAME_POINTER=y -# CONFIG_FTRACE is not set -CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE=y -CONFIG_EARLY_PRINTK=y -CONFIG_CPLB_INFO=y -CONFIG_BFIN_PSEUDODBG_INSNS=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_MD4=y -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_ARC4=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/trunk/arch/blackfin/include/asm/bfin-global.h b/trunk/arch/blackfin/include/asm/bfin-global.h index 608be5e6d25c..17bcbf60bcae 100644 --- a/trunk/arch/blackfin/include/asm/bfin-global.h +++ b/trunk/arch/blackfin/include/asm/bfin-global.h @@ -35,11 +35,6 @@ extern void bfin_setup_cpudata(unsigned int cpu); extern unsigned long get_cclk(void); extern unsigned long get_sclk(void); -#ifdef CONFIG_BF60x -extern unsigned long get_sclk0(void); -extern unsigned long get_sclk1(void); -extern unsigned long get_dclk(void); -#endif extern unsigned long sclk_to_usecs(unsigned long sclk); extern unsigned long usecs_to_sclk(unsigned long usecs); diff --git a/trunk/arch/blackfin/include/asm/bfin6xx_spi.h b/trunk/arch/blackfin/include/asm/bfin6xx_spi.h deleted file mode 100644 index 89370b653dcd..000000000000 --- a/trunk/arch/blackfin/include/asm/bfin6xx_spi.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Analog Devices SPI3 controller driver - * - * Copyright (c) 2011 Analog Devices Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _SPI_CHANNEL_H_ -#define _SPI_CHANNEL_H_ - -#include - -/* SPI_CONTROL */ -#define SPI_CTL_EN 0x00000001 /* Enable */ -#define SPI_CTL_MSTR 0x00000002 /* Master/Slave */ -#define SPI_CTL_PSSE 0x00000004 /* controls modf error in master mode */ -#define SPI_CTL_ODM 0x00000008 /* Open Drain Mode */ -#define SPI_CTL_CPHA 0x00000010 /* Clock Phase */ -#define SPI_CTL_CPOL 0x00000020 /* Clock Polarity */ -#define SPI_CTL_ASSEL 0x00000040 /* Slave Select Pin Control */ -#define SPI_CTL_SELST 0x00000080 /* Slave Select Polarity in-between transfers */ -#define SPI_CTL_EMISO 0x00000100 /* Enable MISO */ -#define SPI_CTL_SIZE 0x00000600 /* Word Transfer Size */ -#define SPI_CTL_SIZE08 0x00000000 /* SIZE: 8 bits */ -#define SPI_CTL_SIZE16 0x00000200 /* SIZE: 16 bits */ -#define SPI_CTL_SIZE32 0x00000400 /* SIZE: 32 bits */ -#define SPI_CTL_LSBF 0x00001000 /* LSB First */ -#define SPI_CTL_FCEN 0x00002000 /* Flow-Control Enable */ -#define SPI_CTL_FCCH 0x00004000 /* Flow-Control Channel Selection */ -#define SPI_CTL_FCPL 0x00008000 /* Flow-Control Polarity */ -#define SPI_CTL_FCWM 0x00030000 /* Flow-Control Water-Mark */ -#define SPI_CTL_FIFO0 0x00000000 /* FCWM: TFIFO empty or RFIFO Full */ -#define SPI_CTL_FIFO1 0x00010000 /* FCWM: TFIFO 75% or more empty or RFIFO 75% or more full */ -#define SPI_CTL_FIFO2 0x00020000 /* FCWM: TFIFO 50% or more empty or RFIFO 50% or more full */ -#define SPI_CTL_FMODE 0x00040000 /* Fast-mode Enable */ -#define SPI_CTL_MIOM 0x00300000 /* Multiple I/O Mode */ -#define SPI_CTL_MIO_DIS 0x00000000 /* MIOM: Disable */ -#define SPI_CTL_MIO_DUAL 0x00100000 /* MIOM: Enable DIOM (Dual I/O Mode) */ -#define SPI_CTL_MIO_QUAD 0x00200000 /* MIOM: Enable QUAD (Quad SPI Mode) */ -#define SPI_CTL_SOSI 0x00400000 /* Start on MOSI */ -/* SPI_RX_CONTROL */ -#define SPI_RXCTL_REN 0x00000001 /* Receive Channel Enable */ -#define SPI_RXCTL_RTI 0x00000004 /* Receive Transfer Initiate */ -#define SPI_RXCTL_RWCEN 0x00000008 /* Receive Word Counter Enable */ -#define SPI_RXCTL_RDR 0x00000070 /* Receive Data Request */ -#define SPI_RXCTL_RDR_DIS 0x00000000 /* RDR: Disabled */ -#define SPI_RXCTL_RDR_NE 0x00000010 /* RDR: RFIFO not empty */ -#define SPI_RXCTL_RDR_25 0x00000020 /* RDR: RFIFO 25% full */ -#define SPI_RXCTL_RDR_50 0x00000030 /* RDR: RFIFO 50% full */ -#define SPI_RXCTL_RDR_75 0x00000040 /* RDR: RFIFO 75% full */ -#define SPI_RXCTL_RDR_FULL 0x00000050 /* RDR: RFIFO full */ -#define SPI_RXCTL_RDO 0x00000100 /* Receive Data Over-Run */ -#define SPI_RXCTL_RRWM 0x00003000 /* FIFO Regular Water-Mark */ -#define SPI_RXCTL_RWM_0 0x00000000 /* RRWM: RFIFO Empty */ -#define SPI_RXCTL_RWM_25 0x00001000 /* RRWM: RFIFO 25% full */ -#define SPI_RXCTL_RWM_50 0x00002000 /* RRWM: RFIFO 50% full */ -#define SPI_RXCTL_RWM_75 0x00003000 /* RRWM: RFIFO 75% full */ -#define SPI_RXCTL_RUWM 0x00070000 /* FIFO Urgent Water-Mark */ -#define SPI_RXCTL_UWM_DIS 0x00000000 /* RUWM: Disabled */ -#define SPI_RXCTL_UWM_25 0x00010000 /* RUWM: RFIFO 25% full */ -#define SPI_RXCTL_UWM_50 0x00020000 /* RUWM: RFIFO 50% full */ -#define SPI_RXCTL_UWM_75 0x00030000 /* RUWM: RFIFO 75% full */ -#define SPI_RXCTL_UWM_FULL 0x00040000 /* RUWM: RFIFO full */ -/* SPI_TX_CONTROL */ -#define SPI_TXCTL_TEN 0x00000001 /* Transmit Channel Enable */ -#define SPI_TXCTL_TTI 0x00000004 /* Transmit Transfer Initiate */ -#define SPI_TXCTL_TWCEN 0x00000008 /* Transmit Word Counter Enable */ -#define SPI_TXCTL_TDR 0x00000070 /* Transmit Data Request */ -#define SPI_TXCTL_TDR_DIS 0x00000000 /* TDR: Disabled */ -#define SPI_TXCTL_TDR_NF 0x00000010 /* TDR: TFIFO not full */ -#define SPI_TXCTL_TDR_25 0x00000020 /* TDR: TFIFO 25% empty */ -#define SPI_TXCTL_TDR_50 0x00000030 /* TDR: TFIFO 50% empty */ -#define SPI_TXCTL_TDR_75 0x00000040 /* TDR: TFIFO 75% empty */ -#define SPI_TXCTL_TDR_EMPTY 0x00000050 /* TDR: TFIFO empty */ -#define SPI_TXCTL_TDU 0x00000100 /* Transmit Data Under-Run */ -#define SPI_TXCTL_TRWM 0x00003000 /* FIFO Regular Water-Mark */ -#define SPI_TXCTL_RWM_FULL 0x00000000 /* TRWM: TFIFO full */ -#define SPI_TXCTL_RWM_25 0x00001000 /* TRWM: TFIFO 25% empty */ -#define SPI_TXCTL_RWM_50 0x00002000 /* TRWM: TFIFO 50% empty */ -#define SPI_TXCTL_RWM_75 0x00003000 /* TRWM: TFIFO 75% empty */ -#define SPI_TXCTL_TUWM 0x00070000 /* FIFO Urgent Water-Mark */ -#define SPI_TXCTL_UWM_DIS 0x00000000 /* TUWM: Disabled */ -#define SPI_TXCTL_UWM_25 0x00010000 /* TUWM: TFIFO 25% empty */ -#define SPI_TXCTL_UWM_50 0x00020000 /* TUWM: TFIFO 50% empty */ -#define SPI_TXCTL_UWM_75 0x00030000 /* TUWM: TFIFO 75% empty */ -#define SPI_TXCTL_UWM_EMPTY 0x00040000 /* TUWM: TFIFO empty */ -/* SPI_CLOCK */ -#define SPI_CLK_BAUD 0x0000FFFF /* Baud Rate */ -/* SPI_DELAY */ -#define SPI_DLY_STOP 0x000000FF /* Transfer delay time in multiples of SCK period */ -#define SPI_DLY_LEADX 0x00000100 /* Extended (1 SCK) LEAD Control */ -#define SPI_DLY_LAGX 0x00000200 /* Extended (1 SCK) LAG control */ -/* SPI_SSEL */ -#define SPI_SLVSEL_SSE1 0x00000002 /* SPISSEL1 Enable */ -#define SPI_SLVSEL_SSE2 0x00000004 /* SPISSEL2 Enable */ -#define SPI_SLVSEL_SSE3 0x00000008 /* SPISSEL3 Enable */ -#define SPI_SLVSEL_SSE4 0x00000010 /* SPISSEL4 Enable */ -#define SPI_SLVSEL_SSE5 0x00000020 /* SPISSEL5 Enable */ -#define SPI_SLVSEL_SSE6 0x00000040 /* SPISSEL6 Enable */ -#define SPI_SLVSEL_SSE7 0x00000080 /* SPISSEL7 Enable */ -#define SPI_SLVSEL_SSEL1 0x00000200 /* SPISSEL1 Value */ -#define SPI_SLVSEL_SSEL2 0x00000400 /* SPISSEL2 Value */ -#define SPI_SLVSEL_SSEL3 0x00000800 /* SPISSEL3 Value */ -#define SPI_SLVSEL_SSEL4 0x00001000 /* SPISSEL4 Value */ -#define SPI_SLVSEL_SSEL5 0x00002000 /* SPISSEL5 Value */ -#define SPI_SLVSEL_SSEL6 0x00004000 /* SPISSEL6 Value */ -#define SPI_SLVSEL_SSEL7 0x00008000 /* SPISSEL7 Value */ -/* SPI_RWC */ -#define SPI_RWC_VALUE 0x0000FFFF /* Received Word-Count */ -/* SPI_RWCR */ -#define SPI_RWCR_VALUE 0x0000FFFF /* Received Word-Count Reload */ -/* SPI_TWC */ -#define SPI_TWC_VALUE 0x0000FFFF /* Transmitted Word-Count */ -/* SPI_TWCR */ -#define SPI_TWCR_VALUE 0x0000FFFF /* Transmitted Word-Count Reload */ -/* SPI_IMASK */ -#define SPI_IMSK_RUWM 0x00000002 /* Receive Urgent Water-Mark Interrupt Mask */ -#define SPI_IMSK_TUWM 0x00000004 /* Transmit Urgent Water-Mark Interrupt Mask */ -#define SPI_IMSK_ROM 0x00000010 /* Receive Over-Run Error Interrupt Mask */ -#define SPI_IMSK_TUM 0x00000020 /* Transmit Under-Run Error Interrupt Mask */ -#define SPI_IMSK_TCM 0x00000040 /* Transmit Collision Error Interrupt Mask */ -#define SPI_IMSK_MFM 0x00000080 /* Mode Fault Error Interrupt Mask */ -#define SPI_IMSK_RSM 0x00000100 /* Receive Start Interrupt Mask */ -#define SPI_IMSK_TSM 0x00000200 /* Transmit Start Interrupt Mask */ -#define SPI_IMSK_RFM 0x00000400 /* Receive Finish Interrupt Mask */ -#define SPI_IMSK_TFM 0x00000800 /* Transmit Finish Interrupt Mask */ -/* SPI_IMASKCL */ -#define SPI_IMSK_CLR_RUW 0x00000002 /* Receive Urgent Water-Mark Interrupt Mask */ -#define SPI_IMSK_CLR_TUWM 0x00000004 /* Transmit Urgent Water-Mark Interrupt Mask */ -#define SPI_IMSK_CLR_ROM 0x00000010 /* Receive Over-Run Error Interrupt Mask */ -#define SPI_IMSK_CLR_TUM 0x00000020 /* Transmit Under-Run Error Interrupt Mask */ -#define SPI_IMSK_CLR_TCM 0x00000040 /* Transmit Collision Error Interrupt Mask */ -#define SPI_IMSK_CLR_MFM 0x00000080 /* Mode Fault Error Interrupt Mask */ -#define SPI_IMSK_CLR_RSM 0x00000100 /* Receive Start Interrupt Mask */ -#define SPI_IMSK_CLR_TSM 0x00000200 /* Transmit Start Interrupt Mask */ -#define SPI_IMSK_CLR_RFM 0x00000400 /* Receive Finish Interrupt Mask */ -#define SPI_IMSK_CLR_TFM 0x00000800 /* Transmit Finish Interrupt Mask */ -/* SPI_IMASKST */ -#define SPI_IMSK_SET_RUWM 0x00000002 /* Receive Urgent Water-Mark Interrupt Mask */ -#define SPI_IMSK_SET_TUWM 0x00000004 /* Transmit Urgent Water-Mark Interrupt Mask */ -#define SPI_IMSK_SET_ROM 0x00000010 /* Receive Over-Run Error Interrupt Mask */ -#define SPI_IMSK_SET_TUM 0x00000020 /* Transmit Under-Run Error Interrupt Mask */ -#define SPI_IMSK_SET_TCM 0x00000040 /* Transmit Collision Error Interrupt Mask */ -#define SPI_IMSK_SET_MFM 0x00000080 /* Mode Fault Error Interrupt Mask */ -#define SPI_IMSK_SET_RSM 0x00000100 /* Receive Start Interrupt Mask */ -#define SPI_IMSK_SET_TSM 0x00000200 /* Transmit Start Interrupt Mask */ -#define SPI_IMSK_SET_RFM 0x00000400 /* Receive Finish Interrupt Mask */ -#define SPI_IMSK_SET_TFM 0x00000800 /* Transmit Finish Interrupt Mask */ -/* SPI_STATUS */ -#define SPI_STAT_SPIF 0x00000001 /* SPI Finished */ -#define SPI_STAT_RUWM 0x00000002 /* Receive Urgent Water-Mark Breached */ -#define SPI_STAT_TUWM 0x00000004 /* Transmit Urgent Water-Mark Breached */ -#define SPI_STAT_ROE 0x00000010 /* Receive Over-Run Error Indication */ -#define SPI_STAT_TUE 0x00000020 /* Transmit Under-Run Error Indication */ -#define SPI_STAT_TCE 0x00000040 /* Transmit Collision Error Indication */ -#define SPI_STAT_MODF 0x00000080 /* Mode Fault Error Indication */ -#define SPI_STAT_RS 0x00000100 /* Receive Start Indication */ -#define SPI_STAT_TS 0x00000200 /* Transmit Start Indication */ -#define SPI_STAT_RF 0x00000400 /* Receive Finish Indication */ -#define SPI_STAT_TF 0x00000800 /* Transmit Finish Indication */ -#define SPI_STAT_RFS 0x00007000 /* SPI_RFIFO status */ -#define SPI_STAT_RFIFO_EMPTY 0x00000000 /* RFS: RFIFO Empty */ -#define SPI_STAT_RFIFO_25 0x00001000 /* RFS: RFIFO 25% Full */ -#define SPI_STAT_RFIFO_50 0x00002000 /* RFS: RFIFO 50% Full */ -#define SPI_STAT_RFIFO_75 0x00003000 /* RFS: RFIFO 75% Full */ -#define SPI_STAT_RFIFO_FULL 0x00004000 /* RFS: RFIFO Full */ -#define SPI_STAT_TFS 0x00070000 /* SPI_TFIFO status */ -#define SPI_STAT_TFIFO_FULL 0x00000000 /* TFS: TFIFO full */ -#define SPI_STAT_TFIFO_25 0x00010000 /* TFS: TFIFO 25% empty */ -#define SPI_STAT_TFIFO_50 0x00020000 /* TFS: TFIFO 50% empty */ -#define SPI_STAT_TFIFO_75 0x00030000 /* TFS: TFIFO 75% empty */ -#define SPI_STAT_TFIFO_EMPTY 0x00040000 /* TFS: TFIFO empty */ -#define SPI_STAT_FCS 0x00100000 /* Flow-Control Stall Indication */ -#define SPI_STAT_RFE 0x00400000 /* SPI_RFIFO Empty */ -#define SPI_STAT_TFF 0x00800000 /* SPI_TFIFO Full */ -/* SPI_ILAT */ -#define SPI_ILAT_RUWMI 0x00000002 /* Receive Urgent Water Mark Interrupt */ -#define SPI_ILAT_TUWMI 0x00000004 /* Transmit Urgent Water Mark Interrupt */ -#define SPI_ILAT_ROI 0x00000010 /* Receive Over-Run Error Indication */ -#define SPI_ILAT_TUI 0x00000020 /* Transmit Under-Run Error Indication */ -#define SPI_ILAT_TCI 0x00000040 /* Transmit Collision Error Indication */ -#define SPI_ILAT_MFI 0x00000080 /* Mode Fault Error Indication */ -#define SPI_ILAT_RSI 0x00000100 /* Receive Start Indication */ -#define SPI_ILAT_TSI 0x00000200 /* Transmit Start Indication */ -#define SPI_ILAT_RFI 0x00000400 /* Receive Finish Indication */ -#define SPI_ILAT_TFI 0x00000800 /* Transmit Finish Indication */ -/* SPI_ILATCL */ -#define SPI_ILAT_CLR_RUWMI 0x00000002 /* Receive Urgent Water Mark Interrupt */ -#define SPI_ILAT_CLR_TUWMI 0x00000004 /* Transmit Urgent Water Mark Interrupt */ -#define SPI_ILAT_CLR_ROI 0x00000010 /* Receive Over-Run Error Indication */ -#define SPI_ILAT_CLR_TUI 0x00000020 /* Transmit Under-Run Error Indication */ -#define SPI_ILAT_CLR_TCI 0x00000040 /* Transmit Collision Error Indication */ -#define SPI_ILAT_CLR_MFI 0x00000080 /* Mode Fault Error Indication */ -#define SPI_ILAT_CLR_RSI 0x00000100 /* Receive Start Indication */ -#define SPI_ILAT_CLR_TSI 0x00000200 /* Transmit Start Indication */ -#define SPI_ILAT_CLR_RFI 0x00000400 /* Receive Finish Indication */ -#define SPI_ILAT_CLR_TFI 0x00000800 /* Transmit Finish Indication */ - -/* - * bfin spi3 registers layout - */ -struct bfin_spi_regs { - u32 revid; - u32 control; - u32 rx_control; - u32 tx_control; - u32 clock; - u32 delay; - u32 ssel; - u32 rwc; - u32 rwcr; - u32 twc; - u32 twcr; - u32 reserved0; - u32 emask; - u32 emaskcl; - u32 emaskst; - u32 reserved1; - u32 status; - u32 elat; - u32 elatcl; - u32 reserved2; - u32 rfifo; - u32 reserved3; - u32 tfifo; -}; - -#define MAX_CTRL_CS 8 /* cs in spi controller */ - -/* device.platform_data for SSP controller devices */ -struct bfin6xx_spi_master { - u16 num_chipselect; - u16 pin_req[7]; -}; - -/* spi_board_info.controller_data for SPI slave devices, - * copied to spi_device.platform_data ... mostly for dma tuning - */ -struct bfin6xx_spi_chip { - u32 control; - u16 cs_chg_udelay; /* Some devices require 16-bit delays */ - u32 tx_dummy_val; /* tx value for rx only transfer */ - bool enable_dma; -}; - -#endif /* _SPI_CHANNEL_H_ */ diff --git a/trunk/arch/blackfin/include/asm/bfin_crc.h b/trunk/arch/blackfin/include/asm/bfin_crc.h deleted file mode 100644 index 3deb4452ceed..000000000000 --- a/trunk/arch/blackfin/include/asm/bfin_crc.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * bfin_crc.h - interface to Blackfin CRC controllers - * - * Copyright 2012 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#ifndef __BFIN_CRC_H__ -#define __BFIN_CRC_H__ - -/* Function driver which use hardware crc must initialize the structure */ -struct crc_info { - /* Input data address */ - unsigned char *in_addr; - /* Output data address */ - unsigned char *out_addr; - /* Input or output bytes */ - unsigned long datasize; - union { - /* CRC to compare with that of input buffer */ - unsigned long crc_compare; - /* Value to compare with input data */ - unsigned long val_verify; - /* Value to fill */ - unsigned long val_fill; - }; - /* Value to program the 32b CRC Polynomial */ - unsigned long crc_poly; - union { - /* CRC calculated from the input data */ - unsigned long crc_result; - /* First failed position to verify input data */ - unsigned long pos_verify; - }; - /* CRC mirror flags */ - unsigned int bitmirr:1; - unsigned int bytmirr:1; - unsigned int w16swp:1; - unsigned int fdsel:1; - unsigned int rsltmirr:1; - unsigned int polymirr:1; - unsigned int cmpmirr:1; -}; - -/* Userspace interface */ -#define CRC_IOC_MAGIC 'C' -#define CRC_IOC_CALC_CRC _IOWR('C', 0x01, unsigned int) -#define CRC_IOC_MEMCPY_CRC _IOWR('C', 0x02, unsigned int) -#define CRC_IOC_VERIFY_VAL _IOWR('C', 0x03, unsigned int) -#define CRC_IOC_FILL_VAL _IOWR('C', 0x04, unsigned int) - - -#ifdef __KERNEL__ - -#include -#include -#include - -struct crc_register { - u32 control; - u32 datacnt; - u32 datacntrld; - u32 __pad_1[2]; - u32 compare; - u32 fillval; - u32 datafifo; - u32 intren; - u32 intrenset; - u32 intrenclr; - u32 poly; - u32 __pad_2[4]; - u32 status; - u32 datacntcap; - u32 __pad_3; - u32 result; - u32 curresult; - u32 __pad_4[3]; - u32 revid; -}; - -struct bfin_crc { - struct miscdevice mdev; - struct list_head list; - int irq; - int dma_ch_src; - int dma_ch_dest; - volatile struct crc_register *regs; - struct crc_info *info; - struct mutex mutex; - struct completion c; - unsigned short opmode; - char name[20]; -}; - -/* CRC_STATUS Masks */ -#define CMPERR 0x00000002 /* Compare error */ -#define DCNTEXP 0x00000010 /* datacnt register expired */ -#define IBR 0x00010000 /* Input buffer ready */ -#define OBR 0x00020000 /* Output buffer ready */ -#define IRR 0x00040000 /* Immediate result readt */ -#define LUTDONE 0x00080000 /* Look-up table generation done */ -#define FSTAT 0x00700000 /* FIFO status */ -#define MAX_FIFO 4 /* Max fifo size */ - -/* CRC_CONTROL Masks */ -#define BLKEN 0x00000001 /* Block enable */ -#define OPMODE 0x000000F0 /* Operation mode */ -#define OPMODE_OFFSET 4 /* Operation mode mask offset*/ -#define MODE_DMACPY_CRC 1 /* MTM CRC compute and compare */ -#define MODE_DATA_FILL 2 /* MTM data fill */ -#define MODE_CALC_CRC 3 /* MSM CRC compute and compare */ -#define MODE_DATA_VERIFY 4 /* MSM data verify */ -#define AUTOCLRZ 0x00000100 /* Auto clear to zero */ -#define AUTOCLRF 0x00000200 /* Auto clear to one */ -#define OBRSTALL 0x00001000 /* Stall on output buffer ready */ -#define IRRSTALL 0x00002000 /* Stall on immediate result ready */ -#define BITMIRR 0x00010000 /* Mirror bits within each byte of 32-bit input data */ -#define BITMIRR_OFFSET 16 /* Mirror bits offset */ -#define BYTMIRR 0x00020000 /* Mirror bytes of 32-bit input data */ -#define BYTMIRR_OFFSET 17 /* Mirror bytes offset */ -#define W16SWP 0x00040000 /* Mirror uppper and lower 16-bit word of 32-bit input data */ -#define W16SWP_OFFSET 18 /* Mirror 16-bit word offset */ -#define FDSEL 0x00080000 /* FIFO is written after input data is mirrored */ -#define FDSEL_OFFSET 19 /* Mirror FIFO offset */ -#define RSLTMIRR 0x00100000 /* CRC result registers are mirrored. */ -#define RSLTMIRR_OFFSET 20 /* Mirror CRC result offset. */ -#define POLYMIRR 0x00200000 /* CRC poly register is mirrored. */ -#define POLYMIRR_OFFSET 21 /* Mirror CRC poly offset. */ -#define CMPMIRR 0x00400000 /* CRC compare register is mirrored. */ -#define CMPMIRR_OFFSET 22 /* Mirror CRC compare offset. */ - -/* CRC_INTREN Masks */ -#define CMPERRI 0x02 /* CRC_ERROR_INTR */ -#define DCNTEXPI 0x10 /* CRC_STATUS_INTR */ - -#endif - -#endif diff --git a/trunk/arch/blackfin/include/asm/bfin_dma.h b/trunk/arch/blackfin/include/asm/bfin_dma.h index 6319f4e49083..d51120744148 100644 --- a/trunk/arch/blackfin/include/asm/bfin_dma.h +++ b/trunk/arch/blackfin/include/asm/bfin_dma.h @@ -15,55 +15,12 @@ #define DMAEN 0x0001 /* DMA Channel Enable */ #define WNR 0x0002 /* Channel Direction (W/R*) */ #define WDSIZE_8 0x0000 /* Transfer Word Size = 8 */ -#define PSIZE_8 0x00000000 /* Transfer Word Size = 16 */ - -#ifdef CONFIG_BF60x - -#define PSIZE_16 0x00000010 /* Transfer Word Size = 16 */ -#define PSIZE_32 0x00000020 /* Transfer Word Size = 32 */ -#define PSIZE_64 0x00000030 /* Transfer Word Size = 32 */ -#define WDSIZE_16 0x00000100 /* Transfer Word Size = 16 */ -#define WDSIZE_32 0x00000200 /* Transfer Word Size = 32 */ -#define WDSIZE_64 0x00000300 /* Transfer Word Size = 32 */ -#define WDSIZE_128 0x00000400 /* Transfer Word Size = 32 */ -#define WDSIZE_256 0x00000500 /* Transfer Word Size = 32 */ -#define DMA2D 0x04000000 /* DMA Mode (2D/1D*) */ -#define RESTART 0x00000004 /* DMA Buffer Clear SYNC */ -#define DI_EN_X 0x00100000 /* Data Interrupt Enable in X count */ -#define DI_EN_Y 0x00200000 /* Data Interrupt Enable in Y count */ -#define DI_EN_P 0x00300000 /* Data Interrupt Enable in Peripheral */ -#define DI_EN DI_EN_X /* Data Interrupt Enable */ -#define NDSIZE_0 0x00000000 /* Next Descriptor Size = 1 */ -#define NDSIZE_1 0x00010000 /* Next Descriptor Size = 2 */ -#define NDSIZE_2 0x00020000 /* Next Descriptor Size = 3 */ -#define NDSIZE_3 0x00030000 /* Next Descriptor Size = 4 */ -#define NDSIZE_4 0x00040000 /* Next Descriptor Size = 5 */ -#define NDSIZE_5 0x00050000 /* Next Descriptor Size = 6 */ -#define NDSIZE_6 0x00060000 /* Next Descriptor Size = 7 */ -#define NDSIZE 0x00070000 /* Next Descriptor Size */ -#define NDSIZE_OFFSET 16 /* Next Descriptor Size Offset */ -#define DMAFLOW_LIST 0x00004000 /* Descriptor List Mode */ -#define DMAFLOW_LARGE DMAFLOW_LIST -#define DMAFLOW_ARRAY 0x00005000 /* Descriptor Array Mode */ -#define DMAFLOW_LIST_DEMAND 0x00006000 /* Descriptor Demand List Mode */ -#define DMAFLOW_ARRAY_DEMAND 0x00007000 /* Descriptor Demand Array Mode */ -#define DMA_RUN_DFETCH 0x00000100 /* DMA Channel Running Indicator (DFETCH) */ -#define DMA_RUN 0x00000200 /* DMA Channel Running Indicator */ -#define DMA_RUN_WAIT_TRIG 0x00000300 /* DMA Channel Running Indicator (WAIT TRIG) */ -#define DMA_RUN_WAIT_ACK 0x00000400 /* DMA Channel Running Indicator (WAIT ACK) */ - -#else - -#define PSIZE_16 0x0000 /* Transfer Word Size = 16 */ -#define PSIZE_32 0x0000 /* Transfer Word Size = 32 */ #define WDSIZE_16 0x0004 /* Transfer Word Size = 16 */ #define WDSIZE_32 0x0008 /* Transfer Word Size = 32 */ #define DMA2D 0x0010 /* DMA Mode (2D/1D*) */ #define RESTART 0x0020 /* DMA Buffer Clear */ #define DI_SEL 0x0040 /* Data Interrupt Timing Select */ #define DI_EN 0x0080 /* Data Interrupt Enable */ -#define DI_EN_X 0x00C0 /* Data Interrupt Enable in X count*/ -#define DI_EN_Y 0x0080 /* Data Interrupt Enable in Y count*/ #define NDSIZE_0 0x0000 /* Next Descriptor Size = 0 (Stop/Autobuffer) */ #define NDSIZE_1 0x0100 /* Next Descriptor Size = 1 */ #define NDSIZE_2 0x0200 /* Next Descriptor Size = 2 */ @@ -75,26 +32,18 @@ #define NDSIZE_8 0x0800 /* Next Descriptor Size = 8 */ #define NDSIZE_9 0x0900 /* Next Descriptor Size = 9 */ #define NDSIZE 0x0f00 /* Next Descriptor Size */ -#define NDSIZE_OFFSET 8 /* Next Descriptor Size Offset */ -#define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */ -#define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */ -#define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */ -#define DFETCH 0x0004 /* DMA Descriptor Fetch Indicator */ -#define DMA_RUN 0x0008 /* DMA Channel Running Indicator */ - -#endif #define DMAFLOW 0x7000 /* Flow Control */ #define DMAFLOW_STOP 0x0000 /* Stop Mode */ #define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */ +#define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */ +#define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */ +#define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */ /* DMA_IRQ_STATUS Masks */ #define DMA_DONE 0x0001 /* DMA Completion Interrupt Status */ #define DMA_ERR 0x0002 /* DMA Error Interrupt Status */ -#ifdef CONFIG_BF60x -#define DMA_PIRQ 0x0004 /* DMA Peripheral Error Interrupt Status */ -#else -#define DMA_PIRQ 0 -#endif +#define DFETCH 0x0004 /* DMA Descriptor Fetch Indicator */ +#define DMA_RUN 0x0008 /* DMA Channel Running Indicator */ /* * All Blackfin system MMRs are padded to 32bits even if the register @@ -108,26 +57,6 @@ struct bfin_dma_regs { u32 next_desc_ptr; u32 start_addr; -#ifdef CONFIG_BF60x - u32 cfg; - u32 x_count; - u32 x_modify; - u32 y_count; - u32 y_modify; - u32 pad1; - u32 pad2; - u32 curr_desc_ptr; - u32 prev_desc_ptr; - u32 curr_addr; - u32 irq_status; - u32 curr_x_count; - u32 curr_y_count; - u32 pad3; - u32 bw_limit_count; - u32 curr_bw_limit_count; - u32 bw_monitor_count; - u32 curr_bw_monitor_count; -#else __BFP(config); u32 __pad0; __BFP(x_count); @@ -142,10 +71,8 @@ struct bfin_dma_regs { u32 __pad1; __BFP(curr_y_count); u32 __pad2; -#endif }; -#ifndef CONFIG_BF60x /* * bfin handshake mdma registers layout */ @@ -158,7 +85,6 @@ struct bfin_hmdma_regs { __BFP(ecount); __BFP(bcount); }; -#endif #undef __BFP diff --git a/trunk/arch/blackfin/include/asm/bfin_pfmon.h b/trunk/arch/blackfin/include/asm/bfin_pfmon.h index bf52e1f32257..accd47e2db40 100644 --- a/trunk/arch/blackfin/include/asm/bfin_pfmon.h +++ b/trunk/arch/blackfin/include/asm/bfin_pfmon.h @@ -3,7 +3,7 @@ * * Copyright 2005-2011 Analog Devices Inc. * - * Licensed under the Clear BSD license or GPL-2 (or later). + * Licensed under the ADI BSD license or GPL-2 (or later). */ #ifndef __ASM_BFIN_PFMON_H__ diff --git a/trunk/arch/blackfin/include/asm/bfin_ppi.h b/trunk/arch/blackfin/include/asm/bfin_ppi.h index a4e872e16e75..3be05faa2c65 100644 --- a/trunk/arch/blackfin/include/asm/bfin_ppi.h +++ b/trunk/arch/blackfin/include/asm/bfin_ppi.h @@ -10,7 +10,6 @@ #define __ASM_BFIN_PPI_H__ #include -#include /* * All Blackfin system MMRs are padded to 32bits even if the register @@ -49,133 +48,6 @@ struct bfin_eppi_regs { u32 clip; }; -/* - * bfin eppi3 registers layout - */ -struct bfin_eppi3_regs { - u32 stat; - u32 hcnt; - u32 hdly; - u32 vcnt; - u32 vdly; - u32 frame; - u32 line; - u32 clkdiv; - u32 ctl; - u32 fs1_wlhb; - u32 fs1_paspl; - u32 fs2_wlvb; - u32 fs2_palpf; - u32 imsk; - u32 oddclip; - u32 evenclip; - u32 fs1_dly; - u32 fs2_dly; - u32 ctl2; -}; - #undef __BFP -#ifdef EPPI0_CTL2 -#define EPPI_STAT_CFIFOERR 0x00000001 /* Chroma FIFO Error */ -#define EPPI_STAT_YFIFOERR 0x00000002 /* Luma FIFO Error */ -#define EPPI_STAT_LTERROVR 0x00000004 /* Line Track Overflow */ -#define EPPI_STAT_LTERRUNDR 0x00000008 /* Line Track Underflow */ -#define EPPI_STAT_FTERROVR 0x00000010 /* Frame Track Overflow */ -#define EPPI_STAT_FTERRUNDR 0x00000020 /* Frame Track Underflow */ -#define EPPI_STAT_ERRNCOR 0x00000040 /* Preamble Error Not Corrected */ -#define EPPI_STAT_PXPERR 0x00000080 /* PxP Ready Error */ -#define EPPI_STAT_ERRDET 0x00004000 /* Preamble Error Detected */ -#define EPPI_STAT_FLD 0x00008000 /* Current Field Received by EPPI */ - -#define EPPI_HCNT_VALUE 0x0000FFFF /* Holds the number of samples to read in or write out per line, after PPIx_HDLY number of cycles have expired since the last assertion of PPIx_FS1 */ - -#define EPPI_HDLY_VALUE 0x0000FFFF /* Number of PPIx_CLK cycles to delay after assertion of PPIx_FS1 before starting to read or write data */ - -#define EPPI_VCNT_VALUE 0x0000FFFF /* Holds the number of lines to read in or write out, after PPIx_VDLY number of lines from the start of frame */ - -#define EPPI_VDLY_VALUE 0x0000FFFF /* Number of lines to wait after the start of a new frame before starting to read/transmit data */ - -#define EPPI_FRAME_VALUE 0x0000FFFF /* Holds the number of lines expected per frame of data */ - -#define EPPI_LINE_VALUE 0x0000FFFF /* Holds the number of samples expected per line */ - -#define EPPI_CLKDIV_VALUE 0x0000FFFF /* Internal clock divider */ - -#define EPPI_CTL_EN 0x00000001 /* PPI Enable */ -#define EPPI_CTL_DIR 0x00000002 /* PPI Direction */ -#define EPPI_CTL_XFRTYPE 0x0000000C /* PPI Operating Mode */ -#define EPPI_CTL_ACTIVE656 0x00000000 /* XFRTYPE: ITU656 Active Video Only Mode */ -#define EPPI_CTL_ENTIRE656 0x00000004 /* XFRTYPE: ITU656 Entire Field Mode */ -#define EPPI_CTL_VERT656 0x00000008 /* XFRTYPE: ITU656 Vertical Blanking Only Mode */ -#define EPPI_CTL_NON656 0x0000000C /* XFRTYPE: Non-ITU656 Mode (GP Mode) */ -#define EPPI_CTL_FSCFG 0x00000030 /* Frame Sync Configuration */ -#define EPPI_CTL_SYNC0 0x00000000 /* FSCFG: Sync Mode 0 */ -#define EPPI_CTL_SYNC1 0x00000010 /* FSCFG: Sync Mode 1 */ -#define EPPI_CTL_SYNC2 0x00000020 /* FSCFG: Sync Mode 2 */ -#define EPPI_CTL_SYNC3 0x00000030 /* FSCFG: Sync Mode 3 */ -#define EPPI_CTL_FLDSEL 0x00000040 /* Field Select/Trigger */ -#define EPPI_CTL_ITUTYPE 0x00000080 /* ITU Interlace or Progressive */ -#define EPPI_CTL_BLANKGEN 0x00000100 /* ITU Output Mode with Internal Blanking Generation */ -#define EPPI_CTL_ICLKGEN 0x00000200 /* Internal Clock Generation */ -#define EPPI_CTL_IFSGEN 0x00000400 /* Internal Frame Sync Generation */ -#define EPPI_CTL_SIGNEXT 0x00000800 /* Sign Extension */ -#define EPPI_CTL_POLC 0x00003000 /* Frame Sync and Data Driving and Sampling Edges */ -#define EPPI_CTL_POLC0 0x00000000 /* POLC: Clock/Sync polarity mode 0 */ -#define EPPI_CTL_POLC1 0x00001000 /* POLC: Clock/Sync polarity mode 1 */ -#define EPPI_CTL_POLC2 0x00002000 /* POLC: Clock/Sync polarity mode 2 */ -#define EPPI_CTL_POLC3 0x00003000 /* POLC: Clock/Sync polarity mode 3 */ -#define EPPI_CTL_POLS 0x0000C000 /* Frame Sync Polarity */ -#define EPPI_CTL_FS1HI_FS2HI 0x00000000 /* POLS: FS1 and FS2 are active high */ -#define EPPI_CTL_FS1LO_FS2HI 0x00004000 /* POLS: FS1 is active low. FS2 is active high */ -#define EPPI_CTL_FS1HI_FS2LO 0x00008000 /* POLS: FS1 is active high. FS2 is active low */ -#define EPPI_CTL_FS1LO_FS2LO 0x0000C000 /* POLS: FS1 and FS2 are active low */ -#define EPPI_CTL_DLEN 0x00070000 /* Data Length */ -#define EPPI_CTL_DLEN08 0x00000000 /* DLEN: 8 bits */ -#define EPPI_CTL_DLEN10 0x00010000 /* DLEN: 10 bits */ -#define EPPI_CTL_DLEN12 0x00020000 /* DLEN: 12 bits */ -#define EPPI_CTL_DLEN14 0x00030000 /* DLEN: 14 bits */ -#define EPPI_CTL_DLEN16 0x00040000 /* DLEN: 16 bits */ -#define EPPI_CTL_DLEN18 0x00050000 /* DLEN: 18 bits */ -#define EPPI_CTL_DLEN20 0x00060000 /* DLEN: 20 bits */ -#define EPPI_CTL_DLEN24 0x00070000 /* DLEN: 24 bits */ -#define EPPI_CTL_DMIRR 0x00080000 /* Data Mirroring */ -#define EPPI_CTL_SKIPEN 0x00100000 /* Skip Enable */ -#define EPPI_CTL_SKIPEO 0x00200000 /* Skip Even or Odd */ -#define EPPI_CTL_PACKEN 0x00400000 /* Pack/Unpack Enable */ -#define EPPI_CTL_SWAPEN 0x00800000 /* Swap Enable */ -#define EPPI_CTL_SPLTEO 0x01000000 /* Split Even and Odd Data Samples */ -#define EPPI_CTL_SUBSPLTODD 0x02000000 /* Sub-Split Odd Samples */ -#define EPPI_CTL_SPLTWRD 0x04000000 /* Split Word */ -#define EPPI_CTL_RGBFMTEN 0x08000000 /* RGB Formatting Enable */ -#define EPPI_CTL_DMACFG 0x10000000 /* One or Two DMA Channels Mode */ -#define EPPI_CTL_DMAFINEN 0x20000000 /* DMA Finish Enable */ -#define EPPI_CTL_MUXSEL 0x40000000 /* MUX Select */ -#define EPPI_CTL_CLKGATEN 0x80000000 /* Clock Gating Enable */ - -#define EPPI_FS2_WLVB_F2VBAD 0xFF000000 /* In GP transmit mode with BLANKGEN = 1, contains number of lines of vertical blanking after field 2 */ -#define EPPI_FS2_WLVB_F2VBBD 0x00FF0000 /* In GP transmit mode with BLANKGEN = 1, contains number of lines of vertical blanking before field 2 */ -#define EPPI_FS2_WLVB_F1VBAD 0x0000FF00 /* In GP transmit mode with, BLANKGEN = 1, contains number of lines of vertical blanking after field 1 */ -#define EPPI_FS2_WLVB_F1VBBD 0x000000FF /* In GP 2, or 3 FS modes used to generate PPIx_FS2 width (32-bit). In GP Transmit mode, with BLANKGEN=1, contains the number of lines of Vertical blanking before field 1. */ - -#define EPPI_FS2_PALPF_F2ACT 0xFFFF0000 /* Number of lines of Active Data in Field 2 */ -#define EPPI_FS2_PALPF_F1ACT 0x0000FFFF /* Number of lines of Active Data in Field 1 */ - -#define EPPI_IMSK_CFIFOERR 0x00000001 /* Mask CFIFO Underflow or Overflow Error Interrupt */ -#define EPPI_IMSK_YFIFOERR 0x00000002 /* Mask YFIFO Underflow or Overflow Error Interrupt */ -#define EPPI_IMSK_LTERROVR 0x00000004 /* Mask Line Track Overflow Error Interrupt */ -#define EPPI_IMSK_LTERRUNDR 0x00000008 /* Mask Line Track Underflow Error Interrupt */ -#define EPPI_IMSK_FTERROVR 0x00000010 /* Mask Frame Track Overflow Error Interrupt */ -#define EPPI_IMSK_FTERRUNDR 0x00000020 /* Mask Frame Track Underflow Error Interrupt */ -#define EPPI_IMSK_ERRNCOR 0x00000040 /* Mask ITU Preamble Error Not Corrected Interrupt */ -#define EPPI_IMSK_PXPERR 0x00000080 /* Mask PxP Ready Error Interrupt */ - -#define EPPI_ODDCLIP_HIGHODD 0xFFFF0000 -#define EPPI_ODDCLIP_LOWODD 0x0000FFFF - -#define EPPI_EVENCLIP_HIGHEVEN 0xFFFF0000 -#define EPPI_EVENCLIP_LOWEVEN 0x0000FFFF - -#define EPPI_CTL2_FS1FINEN 0x00000002 /* HSYNC Finish Enable */ -#endif #endif diff --git a/trunk/arch/blackfin/include/asm/bfin_rotary.h b/trunk/arch/blackfin/include/asm/bfin_rotary.h index 8895a750c70c..0b6910bdc57f 100644 --- a/trunk/arch/blackfin/include/asm/bfin_rotary.h +++ b/trunk/arch/blackfin/include/asm/bfin_rotary.h @@ -39,7 +39,6 @@ struct bfin_rotary_platform_data { unsigned int rotary_rel_code; unsigned short debounce; /* 0..17 */ unsigned short mode; - unsigned short pm_wakeup; }; /* CNT_CONFIG bitmasks */ diff --git a/trunk/arch/blackfin/include/asm/bfin_serial.h b/trunk/arch/blackfin/include/asm/bfin_serial.h index 8597158010b5..68bcc3d119b6 100644 --- a/trunk/arch/blackfin/include/asm/bfin_serial.h +++ b/trunk/arch/blackfin/include/asm/bfin_serial.h @@ -18,7 +18,7 @@ defined(CONFIG_BFIN_UART1_CTSRTS) || \ defined(CONFIG_BFIN_UART2_CTSRTS) || \ defined(CONFIG_BFIN_UART3_CTSRTS) -# if defined(BFIN_UART_BF54X_STYLE) || defined(BFIN_UART_BF60X_STYLE) +# ifdef BFIN_UART_BF54X_STYLE # define CONFIG_SERIAL_BFIN_HARD_CTSRTS # else # define CONFIG_SERIAL_BFIN_CTSRTS @@ -58,69 +58,14 @@ struct bfin_serial_port { #endif }; -#ifdef BFIN_UART_BF60X_STYLE - -/* UART_CTL Masks */ -#define UCEN 0x1 /* Enable UARTx Clocks */ -#define LOOP_ENA 0x2 /* Loopback Mode Enable */ -#define UMOD_MDB 0x10 /* Enable MDB Mode */ -#define UMOD_IRDA 0x20 /* Enable IrDA Mode */ -#define UMOD_MASK 0x30 /* Uart Mode Mask */ -#define WLS(x) (((x-5) & 0x03) << 8) /* Word Length Select */ -#define WLS_MASK 0x300 /* Word length Select Mask */ -#define WLS_OFFSET 8 /* Word length Select Offset */ -#define STB 0x1000 /* Stop Bits */ -#define STBH 0x2000 /* Half Stop Bits */ -#define PEN 0x4000 /* Parity Enable */ -#define EPS 0x8000 /* Even Parity Select */ -#define STP 0x10000 /* Stick Parity */ -#define FPE 0x20000 /* Force Parity Error On Transmit */ -#define FFE 0x40000 /* Force Framing Error On Transmit */ -#define SB 0x80000 /* Set Break */ -#define LCR_MASK (SB | STP | EPS | PEN | STB | WLS_MASK) -#define FCPOL 0x400000 /* Flow Control Pin Polarity */ -#define RPOLC 0x800000 /* IrDA RX Polarity Change */ -#define TPOLC 0x1000000 /* IrDA TX Polarity Change */ -#define MRTS 0x2000000 /* Manual Request To Send */ -#define XOFF 0x4000000 /* Transmitter Off */ -#define ARTS 0x8000000 /* Automatic Request To Send */ -#define ACTS 0x10000000 /* Automatic Clear To Send */ -#define RFIT 0x20000000 /* Receive FIFO IRQ Threshold */ -#define RFRT 0x40000000 /* Receive FIFO RTS Threshold */ - -/* UART_STAT Masks */ -#define DR 0x01 /* Data Ready */ -#define OE 0x02 /* Overrun Error */ -#define PE 0x04 /* Parity Error */ -#define FE 0x08 /* Framing Error */ -#define BI 0x10 /* Break Interrupt */ -#define THRE 0x20 /* THR Empty */ -#define TEMT 0x80 /* TSR and UART_THR Empty */ -#define TFI 0x100 /* Transmission Finished Indicator */ - -#define ASTKY 0x200 /* Address Sticky */ -#define ADDR 0x400 /* Address bit status */ -#define RO 0x800 /* Reception Ongoing */ -#define SCTS 0x1000 /* Sticky CTS */ -#define CTS 0x10000 /* Clear To Send */ -#define RFCS 0x20000 /* Receive FIFO Count Status */ - -/* UART_CLOCK Masks */ -#define EDBO 0x80000000 /* Enable Devide by One */ - -#else /* BFIN_UART_BF60X_STYLE */ - /* UART_LCR Masks */ #define WLS(x) (((x)-5) & 0x03) /* Word Length Select */ -#define WLS_MASK 0x03 /* Word length Select Mask */ -#define WLS_OFFSET 0 /* Word length Select Offset */ #define STB 0x04 /* Stop Bits */ #define PEN 0x08 /* Parity Enable */ #define EPS 0x10 /* Even Parity Select */ #define STP 0x20 /* Stick Parity */ #define SB 0x40 /* Set Break */ #define DLAB 0x80 /* Divisor Latch Access */ -#define LCR_MASK (SB | STP | EPS | PEN | STB | WLS_MASK) /* UART_LSR Masks */ #define DR 0x01 /* Data Ready */ @@ -132,6 +77,15 @@ struct bfin_serial_port { #define TEMT 0x40 /* TSR and UART_THR Empty */ #define TFI 0x80 /* Transmission Finished Indicator */ +/* UART_IER Masks */ +#define ERBFI 0x01 /* Enable Receive Buffer Full Interrupt */ +#define ETBEI 0x02 /* Enable Transmit Buffer Empty Interrupt */ +#define ELSI 0x04 /* Enable RX Status Interrupt */ +#define EDSSI 0x08 /* Enable Modem Status Interrupt */ +#define EDTPTI 0x10 /* Enable DMA Transmit PIRQ Interrupt */ +#define ETFI 0x20 /* Enable Transmission Finished Interrupt */ +#define ERFCI 0x40 /* Enable Receive FIFO Count Interrupt */ + /* UART_MCR Masks */ #define XOFF 0x01 /* Transmitter Off */ #define MRTS 0x02 /* Manual Request To Send */ @@ -149,36 +103,13 @@ struct bfin_serial_port { /* UART_GCTL Masks */ #define UCEN 0x01 /* Enable UARTx Clocks */ -#define UMOD_IRDA 0x02 /* Enable IrDA Mode */ -#define UMOD_MASK 0x02 /* Uart Mode Mask */ +#define IREN 0x02 /* Enable IrDA Mode */ #define TPOLC 0x04 /* IrDA TX Polarity Change */ #define RPOLC 0x08 /* IrDA RX Polarity Change */ #define FPE 0x10 /* Force Parity Error On Transmit */ #define FFE 0x20 /* Force Framing Error On Transmit */ -#endif /* BFIN_UART_BF60X_STYLE */ - -/* UART_IER Masks */ -#define ERBFI 0x01 /* Enable Receive Buffer Full Interrupt */ -#define ETBEI 0x02 /* Enable Transmit Buffer Empty Interrupt */ -#define ELSI 0x04 /* Enable RX Status Interrupt */ -#define EDSSI 0x08 /* Enable Modem Status Interrupt */ -#define EDTPTI 0x10 /* Enable DMA Transmit PIRQ Interrupt */ -#define ETFI 0x20 /* Enable Transmission Finished Interrupt */ -#define ERFCI 0x40 /* Enable Receive FIFO Count Interrupt */ - -#if defined(BFIN_UART_BF60X_STYLE) -# define OFFSET_REDIV 0x00 /* Version ID Register */ -# define OFFSET_CTL 0x04 /* Control Register */ -# define OFFSET_STAT 0x08 /* Status Register */ -# define OFFSET_SCR 0x0C /* SCR Scratch Register */ -# define OFFSET_CLK 0x10 /* Clock Rate Register */ -# define OFFSET_IER 0x14 /* Interrupt Enable Register */ -# define OFFSET_IER_SET 0x18 /* Set Interrupt Enable Register */ -# define OFFSET_IER_CLEAR 0x1C /* Clear Interrupt Enable Register */ -# define OFFSET_RBR 0x20 /* Receive Buffer register */ -# define OFFSET_THR 0x24 /* Transmit Holding register */ -#elif defined(BFIN_UART_BF54X_STYLE) +#ifdef BFIN_UART_BF54X_STYLE # define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */ # define OFFSET_DLH 0x04 /* Divisor Latch (High-Byte) */ # define OFFSET_GCTL 0x08 /* Global Control Register */ @@ -214,23 +145,7 @@ struct bfin_serial_port { */ #define __BFP(m) u16 m; u16 __pad_##m struct bfin_uart_regs { -#if defined(BFIN_UART_BF60X_STYLE) - u32 revid; - u32 ctl; - u32 stat; - u32 scr; - u32 clk; - u32 ier; - u32 ier_set; - u32 ier_clear; - u32 rbr; - u32 thr; - u32 taip; - u32 tsr; - u32 rsr; - u32 txdiv; - u32 rxdiv; -#elif defined(BFIN_UART_BF54X_STYLE) +#ifdef BFIN_UART_BF54X_STYLE __BFP(dll); __BFP(dlh); __BFP(gctl); @@ -267,70 +182,13 @@ struct bfin_uart_regs { }; #undef __BFP -#define port_membase(uart) (((struct bfin_serial_port *)(uart))->port.membase) - -/* #ifndef port_membase # define port_membase(p) 0 #endif -*/ -#ifdef BFIN_UART_BF60X_STYLE - -#define UART_GET_CHAR(p) bfin_read32(port_membase(p) + OFFSET_RBR) -#define UART_GET_CLK(p) bfin_read32(port_membase(p) + OFFSET_CLK) -#define UART_GET_CTL(p) bfin_read32(port_membase(p) + OFFSET_CTL) -#define UART_GET_GCTL(p) UART_GET_CTL(p) -#define UART_GET_LCR(p) UART_GET_CTL(p) -#define UART_GET_MCR(p) UART_GET_CTL(p) -#if ANOMALY_05001001 -#define UART_GET_STAT(p) \ -({ \ - u32 __ret; \ - unsigned long flags; \ - flags = hard_local_irq_save(); \ - __ret = bfin_read32(port_membase(p) + OFFSET_STAT); \ - hard_local_irq_restore(flags); \ - __ret; \ -}) -#else -#define UART_GET_STAT(p) bfin_read32(port_membase(p) + OFFSET_STAT) -#endif -#define UART_GET_MSR(p) UART_GET_STAT(p) - -#define UART_PUT_CHAR(p, v) bfin_write32(port_membase(p) + OFFSET_THR, v) -#define UART_PUT_CLK(p, v) bfin_write32(port_membase(p) + OFFSET_CLK, v) -#define UART_PUT_CTL(p, v) bfin_write32(port_membase(p) + OFFSET_CTL, v) -#define UART_PUT_GCTL(p, v) UART_PUT_CTL(p, v) -#define UART_PUT_LCR(p, v) UART_PUT_CTL(p, v) -#define UART_PUT_MCR(p, v) UART_PUT_CTL(p, v) -#define UART_PUT_STAT(p, v) bfin_write32(port_membase(p) + OFFSET_STAT, v) - -#define UART_CLEAR_IER(p, v) bfin_write32(port_membase(p) + OFFSET_IER_CLEAR, v) -#define UART_GET_IER(p) bfin_read32(port_membase(p) + OFFSET_IER) -#define UART_SET_IER(p, v) bfin_write32(port_membase(p) + OFFSET_IER_SET, v) - -#define UART_CLEAR_DLAB(p) /* MMRs not muxed on BF60x */ -#define UART_SET_DLAB(p) /* MMRs not muxed on BF60x */ - -#define UART_CLEAR_LSR(p) UART_PUT_STAT(p, -1) -#define UART_GET_LSR(p) UART_GET_STAT(p) -#define UART_PUT_LSR(p, v) UART_PUT_STAT(p, v) - -/* This handles hard CTS/RTS */ -#define BFIN_UART_CTSRTS_HARD -#define UART_CLEAR_SCTS(p) UART_PUT_STAT(p, SCTS) -#define UART_GET_CTS(x) (UART_GET_MSR(x) & CTS) -#define UART_DISABLE_RTS(x) UART_PUT_MCR(x, UART_GET_MCR(x) & ~(ARTS | MRTS)) -#define UART_ENABLE_RTS(x) UART_PUT_MCR(x, UART_GET_MCR(x) | MRTS | ARTS) -#define UART_ENABLE_INTS(x, v) UART_SET_IER(x, v) -#define UART_DISABLE_INTS(x) UART_CLEAR_IER(x, 0xF) - -#else /* BFIN_UART_BF60X_STYLE */ #define UART_GET_CHAR(p) bfin_read16(port_membase(p) + OFFSET_RBR) #define UART_GET_DLL(p) bfin_read16(port_membase(p) + OFFSET_DLL) #define UART_GET_DLH(p) bfin_read16(port_membase(p) + OFFSET_DLH) -#define UART_GET_CLK(p) ((UART_GET_DLH(p) << 8) | UART_GET_DLL(p)) #define UART_GET_GCTL(p) bfin_read16(port_membase(p) + OFFSET_GCTL) #define UART_GET_LCR(p) bfin_read16(port_membase(p) + OFFSET_LCR) #define UART_GET_MCR(p) bfin_read16(port_membase(p) + OFFSET_MCR) @@ -339,11 +197,6 @@ struct bfin_uart_regs { #define UART_PUT_CHAR(p, v) bfin_write16(port_membase(p) + OFFSET_THR, v) #define UART_PUT_DLL(p, v) bfin_write16(port_membase(p) + OFFSET_DLL, v) #define UART_PUT_DLH(p, v) bfin_write16(port_membase(p) + OFFSET_DLH, v) -#define UART_PUT_CLK(p, v) do \ -{\ -UART_PUT_DLL(p, v & 0xFF); \ -UART_PUT_DLH(p, (v >> 8) & 0xFF); } while (0); - #define UART_PUT_GCTL(p, v) bfin_write16(port_membase(p) + OFFSET_GCTL, v) #define UART_PUT_LCR(p, v) bfin_write16(port_membase(p) + OFFSET_LCR, v) #define UART_PUT_MCR(p, v) bfin_write16(port_membase(p) + OFFSET_MCR, v) @@ -380,17 +233,12 @@ UART_PUT_DLH(p, (v >> 8) & 0xFF); } while (0); #define UART_CLEAR_DLAB(p) do { UART_PUT_LCR(p, UART_GET_LCR(p) & ~DLAB); SSYNC(); } while (0) #define UART_SET_DLAB(p) do { UART_PUT_LCR(p, UART_GET_LCR(p) | DLAB); SSYNC(); } while (0) -#define get_lsr_cache(uart) (((struct bfin_serial_port *)(uart))->lsr) -#define put_lsr_cache(uart, v) (((struct bfin_serial_port *)(uart))->lsr = (v)) - -/* #ifndef put_lsr_cache # define put_lsr_cache(p, v) #endif #ifndef get_lsr_cache # define get_lsr_cache(p) 0 #endif -*/ /* The hardware clears the LSR bits upon read, so we need to cache * some of the more fun bits in software so they don't get lost @@ -419,9 +267,7 @@ static inline void UART_PUT_LSR(void *p, uint16_t val) #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) #define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0) -#endif /* BFIN_UART_BF54X_STYLE */ - -#endif /* BFIN_UART_BF60X_STYLE */ +#endif #ifndef BFIN_UART_TX_FIFO_SIZE # define BFIN_UART_TX_FIFO_SIZE 2 diff --git a/trunk/arch/blackfin/include/asm/bfin_sport.h b/trunk/arch/blackfin/include/asm/bfin_sport.h index f8907ea6b5b6..0afcfbd54a82 100644 --- a/trunk/arch/blackfin/include/asm/bfin_sport.h +++ b/trunk/arch/blackfin/include/asm/bfin_sport.h @@ -24,7 +24,6 @@ struct sport_config { /* TDM (multichannels), I2S or other mode */ unsigned int mode:3; - unsigned int polled; /* use poll instead of irq when set */ /* if TDM mode is selected, channels must be set */ int channels; /* Must be in 8 units */ diff --git a/trunk/arch/blackfin/include/asm/bfin_sport3.h b/trunk/arch/blackfin/include/asm/bfin_sport3.h deleted file mode 100644 index 03c00220d69b..000000000000 --- a/trunk/arch/blackfin/include/asm/bfin_sport3.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * bfin_sport - Analog Devices BF6XX SPORT registers - * - * Copyright (c) 2012 Analog Devices Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _BFIN_SPORT3_H_ -#define _BFIN_SPORT3_H_ - -#include - -#define SPORT_CTL_SPENPRI 0x00000001 /* Enable Primary Channel */ -#define SPORT_CTL_DTYPE 0x00000006 /* Data type select */ -#define SPORT_CTL_RJUSTIFY_ZFILL 0x00000000 /* DTYPE: MCM mode: Right-justify, zero-fill unused MSBs */ -#define SPORT_CTL_RJUSTIFY_SFILL 0x00000002 /* DTYPE: MCM mode: Right-justify, sign-extend unused MSBs */ -#define SPORT_CTL_USE_U_LAW 0x00000004 /* DTYPE: MCM mode: Compand using u-law */ -#define SPORT_CTL_USE_A_LAW 0x00000006 /* DTYPE: MCM mode: Compand using A-law */ -#define SPORT_CTL_LSBF 0x00000008 /* Serial bit endian select */ -#define SPORT_CTL_SLEN 0x000001F0 /* Serial Word length select */ -#define SPORT_CTL_PACK 0x00000200 /* 16-bit to 32-bit packing enable */ -#define SPORT_CTL_ICLK 0x00000400 /* Internal Clock Select */ -#define SPORT_CTL_OPMODE 0x00000800 /* Operation mode */ -#define SPORT_CTL_CKRE 0x00001000 /* Clock rising edge select */ -#define SPORT_CTL_FSR 0x00002000 /* Frame Sync required */ -#define SPORT_CTL_IFS 0x00004000 /* Internal Frame Sync select */ -#define SPORT_CTL_DIFS 0x00008000 /* Data-independent frame sync select */ -#define SPORT_CTL_LFS 0x00010000 /* Active low frame sync select */ -#define SPORT_CTL_LAFS 0x00020000 /* Late Transmit frame select */ -#define SPORT_CTL_RJUST 0x00040000 /* Right Justified mode select */ -#define SPORT_CTL_FSED 0x00080000 /* External frame sync edge select */ -#define SPORT_CTL_TFIEN 0x00100000 /* Transmit finish interrrupt enable select */ -#define SPORT_CTL_GCLKEN 0x00200000 /* Gated clock mode select */ -#define SPORT_CTL_SPENSEC 0x01000000 /* Enable secondary channel */ -#define SPORT_CTL_SPTRAN 0x02000000 /* Data direction control */ -#define SPORT_CTL_DERRSEC 0x04000000 /* Secondary channel error status */ -#define SPORT_CTL_DXSSEC 0x18000000 /* Secondary channel data buffer status */ -#define SPORT_CTL_SEC_EMPTY 0x00000000 /* DXSSEC: Empty */ -#define SPORT_CTL_SEC_PART_FULL 0x10000000 /* DXSSEC: Partially full */ -#define SPORT_CTL_SEC_FULL 0x18000000 /* DXSSEC: Full */ -#define SPORT_CTL_DERRPRI 0x20000000 /* Primary channel error status */ -#define SPORT_CTL_DXSPRI 0xC0000000 /* Primary channel data buffer status */ -#define SPORT_CTL_PRM_EMPTY 0x00000000 /* DXSPRI: Empty */ -#define SPORT_CTL_PRM_PART_FULL 0x80000000 /* DXSPRI: Partially full */ -#define SPORT_CTL_PRM_FULL 0xC0000000 /* DXSPRI: Full */ - -#define SPORT_DIV_CLKDIV 0x0000FFFF /* Clock divisor */ -#define SPORT_DIV_FSDIV 0xFFFF0000 /* Frame sync divisor */ - -#define SPORT_MCTL_MCE 0x00000001 /* Multichannel enable */ -#define SPORT_MCTL_MCPDE 0x00000004 /* Multichannel data packing select */ -#define SPORT_MCTL_MFD 0x000000F0 /* Multichannel frame delay */ -#define SPORT_MCTL_WSIZE 0x00007F00 /* Number of multichannel slots */ -#define SPORT_MCTL_WOFFSET 0x03FF0000 /* Window offset size */ - -#define SPORT_CNT_CLKCNT 0x0000FFFF /* Current state of clk div counter */ -#define SPORT_CNT_FSDIVCNT 0xFFFF0000 /* Current state of frame div counter */ - -#define SPORT_ERR_DERRPMSK 0x00000001 /* Primary channel data error interrupt enable */ -#define SPORT_ERR_DERRSMSK 0x00000002 /* Secondary channel data error interrupt enable */ -#define SPORT_ERR_FSERRMSK 0x00000004 /* Frame sync error interrupt enable */ -#define SPORT_ERR_DERRPSTAT 0x00000010 /* Primary channel data error status */ -#define SPORT_ERR_DERRSSTAT 0x00000020 /* Secondary channel data error status */ -#define SPORT_ERR_FSERRSTAT 0x00000040 /* Frame sync error status */ - -#define SPORT_MSTAT_CURCHAN 0x000003FF /* Channel which is being serviced in the multichannel operation */ - -#define SPORT_CTL2_FSMUXSEL 0x00000001 /* Frame Sync MUX Select */ -#define SPORT_CTL2_CKMUXSEL 0x00000002 /* Clock MUX Select */ -#define SPORT_CTL2_LBSEL 0x00000004 /* Loopback Select */ - -struct sport_register { - u32 spctl; - u32 div; - u32 spmctl; - u32 spcs0; - u32 spcs1; - u32 spcs2; - u32 spcs3; - u32 spcnt; - u32 sperrctl; - u32 spmstat; - u32 spctl2; - u32 txa; - u32 rxa; - u32 txb; - u32 rxb; - u32 revid; -}; - -struct bfin_snd_platform_data { - const unsigned short *pin_req; -}; - -#endif diff --git a/trunk/arch/blackfin/include/asm/bfin_twi.h b/trunk/arch/blackfin/include/asm/bfin_twi.h index 2f3339a47626..e767d649dfc4 100644 --- a/trunk/arch/blackfin/include/asm/bfin_twi.h +++ b/trunk/arch/blackfin/include/asm/bfin_twi.h @@ -10,7 +10,6 @@ #define __ASM_BFIN_TWI_H__ #include -#include /* * All Blackfin system MMRs are padded to 32bits even if the register @@ -43,145 +42,4 @@ struct bfin_twi_regs { #undef __BFP -struct bfin_twi_iface { - int irq; - spinlock_t lock; - char read_write; - u8 command; - u8 *transPtr; - int readNum; - int writeNum; - int cur_mode; - int manual_stop; - int result; - struct i2c_adapter adap; - struct completion complete; - struct i2c_msg *pmsg; - int msg_num; - int cur_msg; - u16 saved_clkdiv; - u16 saved_control; - struct bfin_twi_regs *regs_base; -}; - -#define DEFINE_TWI_REG(reg_name, reg) \ -static inline u16 read_##reg_name(struct bfin_twi_iface *iface) \ - { return iface->regs_base->reg; } \ -static inline void write_##reg_name(struct bfin_twi_iface *iface, u16 v) \ - { iface->regs_base->reg = v; } - -DEFINE_TWI_REG(CLKDIV, clkdiv) -DEFINE_TWI_REG(CONTROL, control) -DEFINE_TWI_REG(SLAVE_CTL, slave_ctl) -DEFINE_TWI_REG(SLAVE_STAT, slave_stat) -DEFINE_TWI_REG(SLAVE_ADDR, slave_addr) -DEFINE_TWI_REG(MASTER_CTL, master_ctl) -DEFINE_TWI_REG(MASTER_STAT, master_stat) -DEFINE_TWI_REG(MASTER_ADDR, master_addr) -DEFINE_TWI_REG(INT_STAT, int_stat) -DEFINE_TWI_REG(INT_MASK, int_mask) -DEFINE_TWI_REG(FIFO_CTL, fifo_ctl) -DEFINE_TWI_REG(FIFO_STAT, fifo_stat) -DEFINE_TWI_REG(XMT_DATA8, xmt_data8) -DEFINE_TWI_REG(XMT_DATA16, xmt_data16) -#if !ANOMALY_05001001 -DEFINE_TWI_REG(RCV_DATA8, rcv_data8) -DEFINE_TWI_REG(RCV_DATA16, rcv_data16) -#else -static inline u16 read_RCV_DATA8(struct bfin_twi_iface *iface) -{ - u16 ret; - unsigned long flags; - - flags = hard_local_irq_save(); - ret = iface->regs_base->rcv_data8; - hard_local_irq_restore(flags); - - return ret; -} - -static inline u16 read_RCV_DATA16(struct bfin_twi_iface *iface) -{ - u16 ret; - unsigned long flags; - - flags = hard_local_irq_save(); - ret = iface->regs_base->rcv_data16; - hard_local_irq_restore(flags); - - return ret; -} -#endif - - -/* ******************** TWO-WIRE INTERFACE (TWI) MASKS ***********************/ -/* TWI_CLKDIV Macros (Use: *pTWI_CLKDIV = CLKLOW(x)|CLKHI(y); ) */ -#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */ -#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */ - -/* TWI_PRESCALE Masks */ -#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */ -#define TWI_ENA 0x0080 /* TWI Enable */ -#define SCCB 0x0200 /* SCCB Compatibility Enable */ - -/* TWI_SLAVE_CTL Masks */ -#define SEN 0x0001 /* Slave Enable */ -#define SADD_LEN 0x0002 /* Slave Address Length */ -#define STDVAL 0x0004 /* Slave Transmit Data Valid */ -#define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */ -#define GEN 0x0010 /* General Call Address Matching Enabled */ - -/* TWI_SLAVE_STAT Masks */ -#define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */ -#define GCALL 0x0002 /* General Call Indicator */ - -/* TWI_MASTER_CTL Masks */ -#define MEN 0x0001 /* Master Mode Enable */ -#define MADD_LEN 0x0002 /* Master Address Length */ -#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */ -#define FAST 0x0008 /* Use Fast Mode Timing Specs */ -#define STOP 0x0010 /* Issue Stop Condition */ -#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */ -#define DCNT 0x3FC0 /* Data Bytes To Transfer */ -#define SDAOVR 0x4000 /* Serial Data Override */ -#define SCLOVR 0x8000 /* Serial Clock Override */ - -/* TWI_MASTER_STAT Masks */ -#define MPROG 0x0001 /* Master Transfer In Progress */ -#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */ -#define ANAK 0x0004 /* Address Not Acknowledged */ -#define DNAK 0x0008 /* Data Not Acknowledged */ -#define BUFRDERR 0x0010 /* Buffer Read Error */ -#define BUFWRERR 0x0020 /* Buffer Write Error */ -#define SDASEN 0x0040 /* Serial Data Sense */ -#define SCLSEN 0x0080 /* Serial Clock Sense */ -#define BUSBUSY 0x0100 /* Bus Busy Indicator */ - -/* TWI_INT_SRC and TWI_INT_ENABLE Masks */ -#define SINIT 0x0001 /* Slave Transfer Initiated */ -#define SCOMP 0x0002 /* Slave Transfer Complete */ -#define SERR 0x0004 /* Slave Transfer Error */ -#define SOVF 0x0008 /* Slave Overflow */ -#define MCOMP 0x0010 /* Master Transfer Complete */ -#define MERR 0x0020 /* Master Transfer Error */ -#define XMTSERV 0x0040 /* Transmit FIFO Service */ -#define RCVSERV 0x0080 /* Receive FIFO Service */ - -/* TWI_FIFO_CTRL Masks */ -#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */ -#define RCVFLUSH 0x0002 /* Receive Buffer Flush */ -#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */ -#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */ - -/* TWI_FIFO_STAT Masks */ -#define XMTSTAT 0x0003 /* Transmit FIFO Status */ -#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */ -#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */ -#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */ - -#define RCVSTAT 0x000C /* Receive FIFO Status */ -#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */ -#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */ -#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */ - #endif diff --git a/trunk/arch/blackfin/include/asm/blackfin.h b/trunk/arch/blackfin/include/asm/blackfin.h index f111f366d758..7be5368c0512 100644 --- a/trunk/arch/blackfin/include/asm/blackfin.h +++ b/trunk/arch/blackfin/include/asm/blackfin.h @@ -63,16 +63,20 @@ static inline void CSYNC(void) #if ANOMALY_05000312 || ANOMALY_05000244 #define SSYNC(scratch) \ +do { \ cli scratch; \ nop; nop; nop; \ SSYNC; \ - sti scratch; + sti scratch; \ +} while (0) #define CSYNC(scratch) \ +do { \ cli scratch; \ nop; nop; nop; \ CSYNC; \ - sti scratch; + sti scratch; \ +} while (0) #else #define SSYNC(scratch) SSYNC; diff --git a/trunk/arch/blackfin/include/asm/clkdev.h b/trunk/arch/blackfin/include/asm/clkdev.h deleted file mode 100644 index 9053beda8c50..000000000000 --- a/trunk/arch/blackfin/include/asm/clkdev.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __ASM_CLKDEV__H_ -#define __ASM_CLKDEV__H_ - -#include - -static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size) -{ - return kzalloc(size, GFP_KERNEL); -} - -#define __clk_put(clk) -#define __clk_get(clk) ({ 1; }) - -#endif diff --git a/trunk/arch/blackfin/include/asm/clocks.h b/trunk/arch/blackfin/include/asm/clocks.h index 9b3c85b3c288..6f0b61852f58 100644 --- a/trunk/arch/blackfin/include/asm/clocks.h +++ b/trunk/arch/blackfin/include/asm/clocks.h @@ -48,27 +48,4 @@ # define CONFIG_VCO_MULT 0 #endif -#include - -struct clk_ops { - unsigned long (*get_rate)(struct clk *clk); - unsigned long (*round_rate)(struct clk *clk, unsigned long rate); - int (*set_rate)(struct clk *clk, unsigned long rate); - int (*enable)(struct clk *clk); - int (*disable)(struct clk *clk); -}; - -struct clk { - struct clk *parent; - const char *name; - unsigned long rate; - spinlock_t lock; - u32 flags; - const struct clk_ops *ops; - void __iomem *reg; - u32 mask; - u32 shift; -}; - -int clk_init(void); #endif diff --git a/trunk/arch/blackfin/include/asm/cplb.h b/trunk/arch/blackfin/include/asm/cplb.h index 5c37f620c4b3..fda96261ed62 100644 --- a/trunk/arch/blackfin/include/asm/cplb.h +++ b/trunk/arch/blackfin/include/asm/cplb.h @@ -62,10 +62,6 @@ #define SIZE_4K 0x00001000 /* 4K */ #define SIZE_1M 0x00100000 /* 1M */ #define SIZE_4M 0x00400000 /* 4M */ -#define SIZE_16K 0x00004000 /* 16K */ -#define SIZE_64K 0x00010000 /* 64K */ -#define SIZE_16M 0x01000000 /* 16M */ -#define SIZE_64M 0x04000000 /* 64M */ #define MAX_CPLBS 16 diff --git a/trunk/arch/blackfin/include/asm/def_LPBlackfin.h b/trunk/arch/blackfin/include/asm/def_LPBlackfin.h index fe0ca03a1cb2..823679011457 100644 --- a/trunk/arch/blackfin/include/asm/def_LPBlackfin.h +++ b/trunk/arch/blackfin/include/asm/def_LPBlackfin.h @@ -3,7 +3,7 @@ * * Copyright 2005-2008 Analog Devices Inc. * - * Licensed under the Clear BSD license or GPL-2 (or later). + * Licensed under the ADI BSD license or GPL-2 (or later). */ #ifndef _DEF_LPBLACKFIN_H @@ -622,10 +622,6 @@ do { \ #define PAGE_SIZE_4KB 0x00010000 /* 4 KB page size */ #define PAGE_SIZE_1MB 0x00020000 /* 1 MB page size */ #define PAGE_SIZE_4MB 0x00030000 /* 4 MB page size */ -#define PAGE_SIZE_16KB 0x00040000 /* 16 KB page size */ -#define PAGE_SIZE_64KB 0x00050000 /* 64 KB page size */ -#define PAGE_SIZE_16MB 0x00060000 /* 16 MB page size */ -#define PAGE_SIZE_64MB 0x00070000 /* 64 MB page size */ #define CPLB_L1SRAM 0x00000020 /* 0=SRAM mapped in L1, 0=SRAM not * mapped to L1 */ diff --git a/trunk/arch/blackfin/include/asm/dma.h b/trunk/arch/blackfin/include/asm/dma.h index 40e9c2bbc6e3..dac0c97242bb 100644 --- a/trunk/arch/blackfin/include/asm/dma.h +++ b/trunk/arch/blackfin/include/asm/dma.h @@ -22,22 +22,12 @@ #define DATA_SIZE_8 0 #define DATA_SIZE_16 1 #define DATA_SIZE_32 2 -#ifdef CONFIG_BF60x -#define DATA_SIZE_64 3 -#endif #define DMA_FLOW_STOP 0 #define DMA_FLOW_AUTO 1 -#ifdef CONFIG_BF60x -#define DMA_FLOW_LIST 4 -#define DMA_FLOW_ARRAY 5 -#define DMA_FLOW_LIST_DEMAND 6 -#define DMA_FLOW_ARRAY_DEMAND 7 -#else #define DMA_FLOW_ARRAY 4 #define DMA_FLOW_SMALL 6 #define DMA_FLOW_LARGE 7 -#endif #define DIMENSION_LINEAR 0 #define DIMENSION_2D 1 @@ -46,80 +36,26 @@ #define DIR_WRITE 1 #define INTR_DISABLE 0 -#ifdef CONFIG_BF60x -#define INTR_ON_PERI 1 -#endif #define INTR_ON_BUF 2 #define INTR_ON_ROW 3 #define DMA_NOSYNC_KEEP_DMA_BUF 0 #define DMA_SYNC_RESTART 1 -#ifdef DMA_MMR_SIZE_32 -#define DMA_MMR_SIZE_TYPE long -#define DMA_MMR_READ bfin_read32 -#define DMA_MMR_WRITE bfin_write32 -#else -#define DMA_MMR_SIZE_TYPE short -#define DMA_MMR_READ bfin_read16 -#define DMA_MMR_WRITE bfin_write16 -#endif - -struct dma_desc_array { - unsigned long start_addr; - unsigned DMA_MMR_SIZE_TYPE cfg; - unsigned DMA_MMR_SIZE_TYPE x_count; - DMA_MMR_SIZE_TYPE x_modify; -} __attribute__((packed)); - struct dmasg { void *next_desc_addr; unsigned long start_addr; - unsigned DMA_MMR_SIZE_TYPE cfg; - unsigned DMA_MMR_SIZE_TYPE x_count; - DMA_MMR_SIZE_TYPE x_modify; - unsigned DMA_MMR_SIZE_TYPE y_count; - DMA_MMR_SIZE_TYPE y_modify; + unsigned short cfg; + unsigned short x_count; + short x_modify; + unsigned short y_count; + short y_modify; } __attribute__((packed)); struct dma_register { void *next_desc_ptr; /* DMA Next Descriptor Pointer register */ unsigned long start_addr; /* DMA Start address register */ -#ifdef CONFIG_BF60x - unsigned long cfg; /* DMA Configuration register */ - unsigned long x_count; /* DMA x_count register */ - - long x_modify; /* DMA x_modify register */ - - unsigned long y_count; /* DMA y_count register */ - - long y_modify; /* DMA y_modify register */ - - unsigned long reserved; - unsigned long reserved2; - - void *curr_desc_ptr; /* DMA Current Descriptor Pointer - register */ - void *prev_desc_ptr; /* DMA previous initial Descriptor Pointer - register */ - unsigned long curr_addr_ptr; /* DMA Current Address Pointer - register */ - unsigned long irq_status; /* DMA irq status register */ - - unsigned long curr_x_count; /* DMA Current x-count register */ - - unsigned long curr_y_count; /* DMA Current y-count register */ - - unsigned long reserved3; - - unsigned long bw_limit_count; /* DMA band width limit count register */ - unsigned long curr_bw_limit_count; /* DMA Current band width limit - count register */ - unsigned long bw_monitor_count; /* DMA band width limit count register */ - unsigned long curr_bw_monitor_count; /* DMA Current band width limit - count register */ -#else unsigned short cfg; /* DMA Configuration register */ unsigned short dummy1; /* DMA Configuration register */ @@ -156,7 +92,6 @@ struct dma_register { unsigned short dummy9; unsigned long reserved3; -#endif }; @@ -196,23 +131,23 @@ static inline void set_dma_curr_desc_addr(unsigned int channel, void *addr) { dma_ch[channel].regs->curr_desc_ptr = addr; } -static inline void set_dma_x_count(unsigned int channel, unsigned DMA_MMR_SIZE_TYPE x_count) +static inline void set_dma_x_count(unsigned int channel, unsigned short x_count) { dma_ch[channel].regs->x_count = x_count; } -static inline void set_dma_y_count(unsigned int channel, unsigned DMA_MMR_SIZE_TYPE y_count) +static inline void set_dma_y_count(unsigned int channel, unsigned short y_count) { dma_ch[channel].regs->y_count = y_count; } -static inline void set_dma_x_modify(unsigned int channel, DMA_MMR_SIZE_TYPE x_modify) +static inline void set_dma_x_modify(unsigned int channel, short x_modify) { dma_ch[channel].regs->x_modify = x_modify; } -static inline void set_dma_y_modify(unsigned int channel, DMA_MMR_SIZE_TYPE y_modify) +static inline void set_dma_y_modify(unsigned int channel, short y_modify) { dma_ch[channel].regs->y_modify = y_modify; } -static inline void set_dma_config(unsigned int channel, unsigned DMA_MMR_SIZE_TYPE config) +static inline void set_dma_config(unsigned int channel, unsigned short config) { dma_ch[channel].regs->cfg = config; } @@ -221,55 +156,23 @@ static inline void set_dma_curr_addr(unsigned int channel, unsigned long addr) dma_ch[channel].regs->curr_addr_ptr = addr; } -#ifdef CONFIG_BF60x -static inline unsigned long -set_bfin_dma_config2(char direction, char flow_mode, char intr_mode, - char dma_mode, char mem_width, char syncmode, char peri_width) -{ - unsigned long config = 0; - - switch (intr_mode) { - case INTR_ON_BUF: - if (dma_mode == DIMENSION_2D) - config = DI_EN_Y; - else - config = DI_EN_X; - break; - case INTR_ON_ROW: - config = DI_EN_X; - break; - case INTR_ON_PERI: - config = DI_EN_P; - break; - }; - - return config | (direction << 1) | (mem_width << 8) | (dma_mode << 26) | - (flow_mode << 12) | (syncmode << 2) | (peri_width << 4); -} -#endif - -static inline unsigned DMA_MMR_SIZE_TYPE +static inline unsigned short set_bfin_dma_config(char direction, char flow_mode, - char intr_mode, char dma_mode, char mem_width, char syncmode) + char intr_mode, char dma_mode, char width, char syncmode) { -#ifdef CONFIG_BF60x - return set_bfin_dma_config2(direction, flow_mode, intr_mode, dma_mode, - mem_width, syncmode, mem_width); -#else - return (direction << 1) | (mem_width << 2) | (dma_mode << 4) | + return (direction << 1) | (width << 2) | (dma_mode << 4) | (intr_mode << 6) | (flow_mode << 12) | (syncmode << 5); -#endif } -static inline unsigned DMA_MMR_SIZE_TYPE get_dma_curr_irqstat(unsigned int channel) +static inline unsigned short get_dma_curr_irqstat(unsigned int channel) { return dma_ch[channel].regs->irq_status; } -static inline unsigned DMA_MMR_SIZE_TYPE get_dma_curr_xcount(unsigned int channel) +static inline unsigned short get_dma_curr_xcount(unsigned int channel) { return dma_ch[channel].regs->curr_x_count; } -static inline unsigned DMA_MMR_SIZE_TYPE get_dma_curr_ycount(unsigned int channel) +static inline unsigned short get_dma_curr_ycount(unsigned int channel) { return dma_ch[channel].regs->curr_y_count; } @@ -281,7 +184,7 @@ static inline void *get_dma_curr_desc_ptr(unsigned int channel) { return dma_ch[channel].regs->curr_desc_ptr; } -static inline unsigned DMA_MMR_SIZE_TYPE get_dma_config(unsigned int channel) +static inline unsigned short get_dma_config(unsigned int channel) { return dma_ch[channel].regs->cfg; } @@ -300,8 +203,8 @@ static inline void set_dma_sg(unsigned int channel, struct dmasg *sg, int ndsize dma_ch[channel].regs->next_desc_ptr = sg; dma_ch[channel].regs->cfg = - (dma_ch[channel].regs->cfg & ~NDSIZE) | - ((ndsize << NDSIZE_OFFSET) & NDSIZE); + (dma_ch[channel].regs->cfg & ~(0xf << 8)) | + ((ndsize & 0xf) << 8); } static inline int dma_channel_active(unsigned int channel) @@ -336,7 +239,7 @@ static inline void dma_enable_irq(unsigned int channel) } static inline void clear_dma_irqstat(unsigned int channel) { - dma_ch[channel].regs->irq_status = DMA_DONE | DMA_ERR | DMA_PIRQ; + dma_ch[channel].regs->irq_status = DMA_DONE | DMA_ERR; } void *dma_memcpy(void *dest, const void *src, size_t count); diff --git a/trunk/arch/blackfin/include/asm/dpmc.h b/trunk/arch/blackfin/include/asm/dpmc.h index e91eae8330a6..c4ec959dad78 100644 --- a/trunk/arch/blackfin/include/asm/dpmc.h +++ b/trunk/arch/blackfin/include/asm/dpmc.h @@ -9,651 +9,6 @@ #ifndef _BLACKFIN_DPMC_H_ #define _BLACKFIN_DPMC_H_ -#ifdef __ASSEMBLY__ -#define PM_REG0 R7 -#define PM_REG1 R6 -#define PM_REG2 R5 -#define PM_REG3 R4 -#define PM_REG4 R3 -#define PM_REG5 R2 -#define PM_REG6 R1 -#define PM_REG7 R0 -#define PM_REG8 P5 -#define PM_REG9 P4 -#define PM_REG10 P3 -#define PM_REG11 P2 -#define PM_REG12 P1 -#define PM_REG13 P0 - -#define PM_REGSET0 R7:7 -#define PM_REGSET1 R7:6 -#define PM_REGSET2 R7:5 -#define PM_REGSET3 R7:4 -#define PM_REGSET4 R7:3 -#define PM_REGSET5 R7:2 -#define PM_REGSET6 R7:1 -#define PM_REGSET7 R7:0 -#define PM_REGSET8 R7:0, P5:5 -#define PM_REGSET9 R7:0, P5:4 -#define PM_REGSET10 R7:0, P5:3 -#define PM_REGSET11 R7:0, P5:2 -#define PM_REGSET12 R7:0, P5:1 -#define PM_REGSET13 R7:0, P5:0 - -#define _PM_PUSH(n, x, w, base) PM_REG##n = w[FP + ((x) - (base))]; -#define _PM_POP(n, x, w, base) w[FP + ((x) - (base))] = PM_REG##n; -#define PM_PUSH_SYNC(n) [--sp] = (PM_REGSET##n); -#define PM_POP_SYNC(n) (PM_REGSET##n) = [sp++]; -#define PM_PUSH(n, x) PM_REG##n = [FP++]; -#define PM_POP(n, x) [FP--] = PM_REG##n; -#define PM_CORE_PUSH(n, x) _PM_PUSH(n, x, , COREMMR_BASE) -#define PM_CORE_POP(n, x) _PM_POP(n, x, , COREMMR_BASE) -#define PM_SYS_PUSH(n, x) _PM_PUSH(n, x, , SYSMMR_BASE) -#define PM_SYS_POP(n, x) _PM_POP(n, x, , SYSMMR_BASE) -#define PM_SYS_PUSH16(n, x) _PM_PUSH(n, x, w, SYSMMR_BASE) -#define PM_SYS_POP16(n, x) _PM_POP(n, x, w, SYSMMR_BASE) - - .macro bfin_init_pm_bench_cycles -#ifdef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH - R4 = 0; - CYCLES = R4; - CYCLES2 = R4; - R4 = SYSCFG; - BITSET(R4, 1); - SYSCFG = R4; -#endif - .endm - - .macro bfin_cpu_reg_save - /* - * Save the core regs early so we can blow them away when - * saving/restoring MMR states - */ - [--sp] = (R7:0, P5:0); - [--sp] = fp; - [--sp] = usp; - - [--sp] = i0; - [--sp] = i1; - [--sp] = i2; - [--sp] = i3; - - [--sp] = m0; - [--sp] = m1; - [--sp] = m2; - [--sp] = m3; - - [--sp] = l0; - [--sp] = l1; - [--sp] = l2; - [--sp] = l3; - - [--sp] = b0; - [--sp] = b1; - [--sp] = b2; - [--sp] = b3; - [--sp] = a0.x; - [--sp] = a0.w; - [--sp] = a1.x; - [--sp] = a1.w; - - [--sp] = LC0; - [--sp] = LC1; - [--sp] = LT0; - [--sp] = LT1; - [--sp] = LB0; - [--sp] = LB1; - - /* We can't push RETI directly as that'll change IPEND[4] */ - r7 = RETI; - [--sp] = RETS; - [--sp] = ASTAT; -#ifndef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH - [--sp] = CYCLES; - [--sp] = CYCLES2; -#endif - [--sp] = SYSCFG; - [--sp] = RETX; - [--sp] = SEQSTAT; - [--sp] = r7; - - /* Save first func arg in M3 */ - M3 = R0; - .endm - - .macro bfin_cpu_reg_restore - /* Restore Core Registers */ - RETI = [sp++]; - SEQSTAT = [sp++]; - RETX = [sp++]; - SYSCFG = [sp++]; -#ifndef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH - CYCLES2 = [sp++]; - CYCLES = [sp++]; -#endif - ASTAT = [sp++]; - RETS = [sp++]; - - LB1 = [sp++]; - LB0 = [sp++]; - LT1 = [sp++]; - LT0 = [sp++]; - LC1 = [sp++]; - LC0 = [sp++]; - - a1.w = [sp++]; - a1.x = [sp++]; - a0.w = [sp++]; - a0.x = [sp++]; - b3 = [sp++]; - b2 = [sp++]; - b1 = [sp++]; - b0 = [sp++]; - - l3 = [sp++]; - l2 = [sp++]; - l1 = [sp++]; - l0 = [sp++]; - - m3 = [sp++]; - m2 = [sp++]; - m1 = [sp++]; - m0 = [sp++]; - - i3 = [sp++]; - i2 = [sp++]; - i1 = [sp++]; - i0 = [sp++]; - - usp = [sp++]; - fp = [sp++]; - (R7:0, P5:0) = [sp++]; - - .endm - - .macro bfin_sys_mmr_save - /* Save system MMRs */ - FP.H = hi(SYSMMR_BASE); - FP.L = lo(SYSMMR_BASE); -#ifdef SIC_IMASK0 - PM_SYS_PUSH(0, SIC_IMASK0) - PM_SYS_PUSH(1, SIC_IMASK1) -# ifdef SIC_IMASK2 - PM_SYS_PUSH(2, SIC_IMASK2) -# endif -#else -# ifdef SIC_IMASK - PM_SYS_PUSH(0, SIC_IMASK) -# endif -#endif - -#ifdef SIC_IAR0 - PM_SYS_PUSH(3, SIC_IAR0) - PM_SYS_PUSH(4, SIC_IAR1) - PM_SYS_PUSH(5, SIC_IAR2) -#endif -#ifdef SIC_IAR3 - PM_SYS_PUSH(6, SIC_IAR3) -#endif -#ifdef SIC_IAR4 - PM_SYS_PUSH(7, SIC_IAR4) - PM_SYS_PUSH(8, SIC_IAR5) - PM_SYS_PUSH(9, SIC_IAR6) -#endif -#ifdef SIC_IAR7 - PM_SYS_PUSH(10, SIC_IAR7) -#endif -#ifdef SIC_IAR8 - PM_SYS_PUSH(11, SIC_IAR8) - PM_SYS_PUSH(12, SIC_IAR9) - PM_SYS_PUSH(13, SIC_IAR10) -#endif - PM_PUSH_SYNC(13) -#ifdef SIC_IAR11 - PM_SYS_PUSH(0, SIC_IAR11) -#endif - -#ifdef SIC_IWR - PM_SYS_PUSH(1, SIC_IWR) -#endif -#ifdef SIC_IWR0 - PM_SYS_PUSH(1, SIC_IWR0) -#endif -#ifdef SIC_IWR1 - PM_SYS_PUSH(2, SIC_IWR1) -#endif -#ifdef SIC_IWR2 - PM_SYS_PUSH(3, SIC_IWR2) -#endif - -#ifdef PINT0_ASSIGN - PM_SYS_PUSH(4, PINT0_MASK_SET) - PM_SYS_PUSH(5, PINT1_MASK_SET) - PM_SYS_PUSH(6, PINT2_MASK_SET) - PM_SYS_PUSH(7, PINT3_MASK_SET) - PM_SYS_PUSH(8, PINT0_ASSIGN) - PM_SYS_PUSH(9, PINT1_ASSIGN) - PM_SYS_PUSH(10, PINT2_ASSIGN) - PM_SYS_PUSH(11, PINT3_ASSIGN) - PM_SYS_PUSH(12, PINT0_INVERT_SET) - PM_SYS_PUSH(13, PINT1_INVERT_SET) - PM_PUSH_SYNC(13) - PM_SYS_PUSH(0, PINT2_INVERT_SET) - PM_SYS_PUSH(1, PINT3_INVERT_SET) - PM_SYS_PUSH(2, PINT0_EDGE_SET) - PM_SYS_PUSH(3, PINT1_EDGE_SET) - PM_SYS_PUSH(4, PINT2_EDGE_SET) - PM_SYS_PUSH(5, PINT3_EDGE_SET) -#endif - -#ifdef SYSCR - PM_SYS_PUSH16(6, SYSCR) -#endif - -#ifdef EBIU_AMGCTL - PM_SYS_PUSH16(7, EBIU_AMGCTL) - PM_SYS_PUSH(8, EBIU_AMBCTL0) - PM_SYS_PUSH(9, EBIU_AMBCTL1) -#endif -#ifdef EBIU_FCTL - PM_SYS_PUSH(10, EBIU_MBSCTL) - PM_SYS_PUSH(11, EBIU_MODE) - PM_SYS_PUSH(12, EBIU_FCTL) - PM_PUSH_SYNC(12) -#else - PM_PUSH_SYNC(9) -#endif - .endm - - - .macro bfin_sys_mmr_restore -/* Restore System MMRs */ - FP.H = hi(SYSMMR_BASE); - FP.L = lo(SYSMMR_BASE); - -#ifdef EBIU_FCTL - PM_POP_SYNC(12) - PM_SYS_POP(12, EBIU_FCTL) - PM_SYS_POP(11, EBIU_MODE) - PM_SYS_POP(10, EBIU_MBSCTL) -#else - PM_POP_SYNC(9) -#endif - -#ifdef EBIU_AMBCTL - PM_SYS_POP(9, EBIU_AMBCTL1) - PM_SYS_POP(8, EBIU_AMBCTL0) - PM_SYS_POP16(7, EBIU_AMGCTL) -#endif - -#ifdef SYSCR - PM_SYS_POP16(6, SYSCR) -#endif - -#ifdef PINT0_ASSIGN - PM_SYS_POP(5, PINT3_EDGE_SET) - PM_SYS_POP(4, PINT2_EDGE_SET) - PM_SYS_POP(3, PINT1_EDGE_SET) - PM_SYS_POP(2, PINT0_EDGE_SET) - PM_SYS_POP(1, PINT3_INVERT_SET) - PM_SYS_POP(0, PINT2_INVERT_SET) - PM_POP_SYNC(13) - PM_SYS_POP(13, PINT1_INVERT_SET) - PM_SYS_POP(12, PINT0_INVERT_SET) - PM_SYS_POP(11, PINT3_ASSIGN) - PM_SYS_POP(10, PINT2_ASSIGN) - PM_SYS_POP(9, PINT1_ASSIGN) - PM_SYS_POP(8, PINT0_ASSIGN) - PM_SYS_POP(7, PINT3_MASK_SET) - PM_SYS_POP(6, PINT2_MASK_SET) - PM_SYS_POP(5, PINT1_MASK_SET) - PM_SYS_POP(4, PINT0_MASK_SET) -#endif - -#ifdef SIC_IWR2 - PM_SYS_POP(3, SIC_IWR2) -#endif -#ifdef SIC_IWR1 - PM_SYS_POP(2, SIC_IWR1) -#endif -#ifdef SIC_IWR0 - PM_SYS_POP(1, SIC_IWR0) -#endif -#ifdef SIC_IWR - PM_SYS_POP(1, SIC_IWR) -#endif - -#ifdef SIC_IAR11 - PM_SYS_POP(0, SIC_IAR11) -#endif - PM_POP_SYNC(13) -#ifdef SIC_IAR8 - PM_SYS_POP(13, SIC_IAR10) - PM_SYS_POP(12, SIC_IAR9) - PM_SYS_POP(11, SIC_IAR8) -#endif -#ifdef SIC_IAR7 - PM_SYS_POP(10, SIC_IAR7) -#endif -#ifdef SIC_IAR6 - PM_SYS_POP(9, SIC_IAR6) - PM_SYS_POP(8, SIC_IAR5) - PM_SYS_POP(7, SIC_IAR4) -#endif -#ifdef SIC_IAR3 - PM_SYS_POP(6, SIC_IAR3) -#endif -#ifdef SIC_IAR0 - PM_SYS_POP(5, SIC_IAR2) - PM_SYS_POP(4, SIC_IAR1) - PM_SYS_POP(3, SIC_IAR0) -#endif -#ifdef SIC_IMASK0 -# ifdef SIC_IMASK2 - PM_SYS_POP(2, SIC_IMASK2) -# endif - PM_SYS_POP(1, SIC_IMASK1) - PM_SYS_POP(0, SIC_IMASK0) -#else -# ifdef SIC_IMASK - PM_SYS_POP(0, SIC_IMASK) -# endif -#endif - .endm - - .macro bfin_core_mmr_save - /* Save Core MMRs */ - I0.H = hi(COREMMR_BASE); - I0.L = lo(COREMMR_BASE); - I1 = I0; - I2 = I0; - I3 = I0; - B0 = I0; - B1 = I0; - B2 = I0; - B3 = I0; - I1.L = lo(DCPLB_ADDR0); - I2.L = lo(DCPLB_DATA0); - I3.L = lo(ICPLB_ADDR0); - B0.L = lo(ICPLB_DATA0); - B1.L = lo(EVT2); - B2.L = lo(IMASK); - B3.L = lo(TCNTL); - - /* Event Vectors */ - FP = B1; - PM_PUSH(0, EVT2) - PM_PUSH(1, EVT3) - FP += 4; /* EVT4 */ - PM_PUSH(2, EVT5) - PM_PUSH(3, EVT6) - PM_PUSH(4, EVT7) - PM_PUSH(5, EVT8) - PM_PUSH_SYNC(5) - - PM_PUSH(0, EVT9) - PM_PUSH(1, EVT10) - PM_PUSH(2, EVT11) - PM_PUSH(3, EVT12) - PM_PUSH(4, EVT13) - PM_PUSH(5, EVT14) - PM_PUSH(6, EVT15) - - /* CEC */ - FP = B2; - PM_PUSH(7, IMASK) - FP += 4; /* IPEND */ - PM_PUSH(8, ILAT) - PM_PUSH(9, IPRIO) - - /* Core Timer */ - FP = B3; - PM_PUSH(10, TCNTL) - PM_PUSH(11, TPERIOD) - PM_PUSH(12, TSCALE) - PM_PUSH(13, TCOUNT) - PM_PUSH_SYNC(13) - - /* Misc non-contiguous registers */ - FP = I0; - PM_CORE_PUSH(0, DMEM_CONTROL); - PM_CORE_PUSH(1, IMEM_CONTROL); - PM_CORE_PUSH(2, TBUFCTL); - PM_PUSH_SYNC(2) - - /* DCPLB Addr */ - FP = I1; - PM_PUSH(0, DCPLB_ADDR0) - PM_PUSH(1, DCPLB_ADDR1) - PM_PUSH(2, DCPLB_ADDR2) - PM_PUSH(3, DCPLB_ADDR3) - PM_PUSH(4, DCPLB_ADDR4) - PM_PUSH(5, DCPLB_ADDR5) - PM_PUSH(6, DCPLB_ADDR6) - PM_PUSH(7, DCPLB_ADDR7) - PM_PUSH(8, DCPLB_ADDR8) - PM_PUSH(9, DCPLB_ADDR9) - PM_PUSH(10, DCPLB_ADDR10) - PM_PUSH(11, DCPLB_ADDR11) - PM_PUSH(12, DCPLB_ADDR12) - PM_PUSH(13, DCPLB_ADDR13) - PM_PUSH_SYNC(13) - PM_PUSH(0, DCPLB_ADDR14) - PM_PUSH(1, DCPLB_ADDR15) - - /* DCPLB Data */ - FP = I2; - PM_PUSH(2, DCPLB_DATA0) - PM_PUSH(3, DCPLB_DATA1) - PM_PUSH(4, DCPLB_DATA2) - PM_PUSH(5, DCPLB_DATA3) - PM_PUSH(6, DCPLB_DATA4) - PM_PUSH(7, DCPLB_DATA5) - PM_PUSH(8, DCPLB_DATA6) - PM_PUSH(9, DCPLB_DATA7) - PM_PUSH(10, DCPLB_DATA8) - PM_PUSH(11, DCPLB_DATA9) - PM_PUSH(12, DCPLB_DATA10) - PM_PUSH(13, DCPLB_DATA11) - PM_PUSH_SYNC(13) - PM_PUSH(0, DCPLB_DATA12) - PM_PUSH(1, DCPLB_DATA13) - PM_PUSH(2, DCPLB_DATA14) - PM_PUSH(3, DCPLB_DATA15) - - /* ICPLB Addr */ - FP = I3; - PM_PUSH(4, ICPLB_ADDR0) - PM_PUSH(5, ICPLB_ADDR1) - PM_PUSH(6, ICPLB_ADDR2) - PM_PUSH(7, ICPLB_ADDR3) - PM_PUSH(8, ICPLB_ADDR4) - PM_PUSH(9, ICPLB_ADDR5) - PM_PUSH(10, ICPLB_ADDR6) - PM_PUSH(11, ICPLB_ADDR7) - PM_PUSH(12, ICPLB_ADDR8) - PM_PUSH(13, ICPLB_ADDR9) - PM_PUSH_SYNC(13) - PM_PUSH(0, ICPLB_ADDR10) - PM_PUSH(1, ICPLB_ADDR11) - PM_PUSH(2, ICPLB_ADDR12) - PM_PUSH(3, ICPLB_ADDR13) - PM_PUSH(4, ICPLB_ADDR14) - PM_PUSH(5, ICPLB_ADDR15) - - /* ICPLB Data */ - FP = B0; - PM_PUSH(6, ICPLB_DATA0) - PM_PUSH(7, ICPLB_DATA1) - PM_PUSH(8, ICPLB_DATA2) - PM_PUSH(9, ICPLB_DATA3) - PM_PUSH(10, ICPLB_DATA4) - PM_PUSH(11, ICPLB_DATA5) - PM_PUSH(12, ICPLB_DATA6) - PM_PUSH(13, ICPLB_DATA7) - PM_PUSH_SYNC(13) - PM_PUSH(0, ICPLB_DATA8) - PM_PUSH(1, ICPLB_DATA9) - PM_PUSH(2, ICPLB_DATA10) - PM_PUSH(3, ICPLB_DATA11) - PM_PUSH(4, ICPLB_DATA12) - PM_PUSH(5, ICPLB_DATA13) - PM_PUSH(6, ICPLB_DATA14) - PM_PUSH(7, ICPLB_DATA15) - PM_PUSH_SYNC(7) - .endm - - .macro bfin_core_mmr_restore - /* Restore Core MMRs */ - I0.H = hi(COREMMR_BASE); - I0.L = lo(COREMMR_BASE); - I1 = I0; - I2 = I0; - I3 = I0; - B0 = I0; - B1 = I0; - B2 = I0; - B3 = I0; - I1.L = lo(DCPLB_ADDR15); - I2.L = lo(DCPLB_DATA15); - I3.L = lo(ICPLB_ADDR15); - B0.L = lo(ICPLB_DATA15); - B1.L = lo(EVT15); - B2.L = lo(IPRIO); - B3.L = lo(TCOUNT); - - /* ICPLB Data */ - FP = B0; - PM_POP_SYNC(7) - PM_POP(7, ICPLB_DATA15) - PM_POP(6, ICPLB_DATA14) - PM_POP(5, ICPLB_DATA13) - PM_POP(4, ICPLB_DATA12) - PM_POP(3, ICPLB_DATA11) - PM_POP(2, ICPLB_DATA10) - PM_POP(1, ICPLB_DATA9) - PM_POP(0, ICPLB_DATA8) - PM_POP_SYNC(13) - PM_POP(13, ICPLB_DATA7) - PM_POP(12, ICPLB_DATA6) - PM_POP(11, ICPLB_DATA5) - PM_POP(10, ICPLB_DATA4) - PM_POP(9, ICPLB_DATA3) - PM_POP(8, ICPLB_DATA2) - PM_POP(7, ICPLB_DATA1) - PM_POP(6, ICPLB_DATA0) - - /* ICPLB Addr */ - FP = I3; - PM_POP(5, ICPLB_ADDR15) - PM_POP(4, ICPLB_ADDR14) - PM_POP(3, ICPLB_ADDR13) - PM_POP(2, ICPLB_ADDR12) - PM_POP(1, ICPLB_ADDR11) - PM_POP(0, ICPLB_ADDR10) - PM_POP_SYNC(13) - PM_POP(13, ICPLB_ADDR9) - PM_POP(12, ICPLB_ADDR8) - PM_POP(11, ICPLB_ADDR7) - PM_POP(10, ICPLB_ADDR6) - PM_POP(9, ICPLB_ADDR5) - PM_POP(8, ICPLB_ADDR4) - PM_POP(7, ICPLB_ADDR3) - PM_POP(6, ICPLB_ADDR2) - PM_POP(5, ICPLB_ADDR1) - PM_POP(4, ICPLB_ADDR0) - - /* DCPLB Data */ - FP = I2; - PM_POP(3, DCPLB_DATA15) - PM_POP(2, DCPLB_DATA14) - PM_POP(1, DCPLB_DATA13) - PM_POP(0, DCPLB_DATA12) - PM_POP_SYNC(13) - PM_POP(13, DCPLB_DATA11) - PM_POP(12, DCPLB_DATA10) - PM_POP(11, DCPLB_DATA9) - PM_POP(10, DCPLB_DATA8) - PM_POP(9, DCPLB_DATA7) - PM_POP(8, DCPLB_DATA6) - PM_POP(7, DCPLB_DATA5) - PM_POP(6, DCPLB_DATA4) - PM_POP(5, DCPLB_DATA3) - PM_POP(4, DCPLB_DATA2) - PM_POP(3, DCPLB_DATA1) - PM_POP(2, DCPLB_DATA0) - - /* DCPLB Addr */ - FP = I1; - PM_POP(1, DCPLB_ADDR15) - PM_POP(0, DCPLB_ADDR14) - PM_POP_SYNC(13) - PM_POP(13, DCPLB_ADDR13) - PM_POP(12, DCPLB_ADDR12) - PM_POP(11, DCPLB_ADDR11) - PM_POP(10, DCPLB_ADDR10) - PM_POP(9, DCPLB_ADDR9) - PM_POP(8, DCPLB_ADDR8) - PM_POP(7, DCPLB_ADDR7) - PM_POP(6, DCPLB_ADDR6) - PM_POP(5, DCPLB_ADDR5) - PM_POP(4, DCPLB_ADDR4) - PM_POP(3, DCPLB_ADDR3) - PM_POP(2, DCPLB_ADDR2) - PM_POP(1, DCPLB_ADDR1) - PM_POP(0, DCPLB_ADDR0) - - - /* Misc non-contiguous registers */ - - /* icache & dcache will enable later - drop IMEM_CONTROL, DMEM_CONTROL pop - */ - FP = I0; - PM_POP_SYNC(2) - PM_CORE_POP(2, TBUFCTL) - PM_CORE_POP(1, IMEM_CONTROL) - PM_CORE_POP(0, DMEM_CONTROL) - - /* Core Timer */ - FP = B3; - R0 = 0x1; - [FP - 0xC] = R0; - - PM_POP_SYNC(13) - FP = B3; - PM_POP(13, TCOUNT) - PM_POP(12, TSCALE) - PM_POP(11, TPERIOD) - PM_POP(10, TCNTL) - - /* CEC */ - FP = B2; - PM_POP(9, IPRIO) - PM_POP(8, ILAT) - FP += -4; /* IPEND */ - PM_POP(7, IMASK) - - /* Event Vectors */ - FP = B1; - PM_POP(6, EVT15) - PM_POP(5, EVT14) - PM_POP(4, EVT13) - PM_POP(3, EVT12) - PM_POP(2, EVT11) - PM_POP(1, EVT10) - PM_POP(0, EVT9) - PM_POP_SYNC(5) - PM_POP(5, EVT8) - PM_POP(4, EVT7) - PM_POP(3, EVT6) - PM_POP(2, EVT5) - FP += -4; /* EVT4 */ - PM_POP(1, EVT3) - PM_POP(0, EVT2) - .endm -#endif - #include /* PLL_CTL Masks */ @@ -743,16 +98,6 @@ #define VLEV_130 0x00F0 /* VLEV = 1.30 V (-5% - +10% Accuracy) */ #endif -#ifdef CONFIG_BF60x -#define PA15WE 0x00000001 /* Allow Wake-Up from PA15 */ -#define PB15WE 0x00000002 /* Allow Wake-Up from PB15 */ -#define PC15WE 0x00000004 /* Allow Wake-Up from PC15 */ -#define PD06WE 0x00000008 /* Allow Wake-Up from PD06(ETH0_PHYINT) */ -#define PE12WE 0x00000010 /* Allow Wake-Up from PE12(ETH1_PHYINT, PUSH BUTTON) */ -#define PG04WE 0x00000020 /* Allow Wake-Up from PG04(CAN0_RX) */ -#define PG13WE 0x00000040 /* Allow Wake-Up from PG13 */ -#define USBWE 0x00000080 /* Allow Wake-Up from (USB) */ -#else #define WAKE 0x0100 /* Enable RTC/Reset Wakeup From Hibernate */ #define CANWE 0x0200 /* Enable CAN Wakeup From Hibernate */ #define PHYWE 0x0400 /* Enable PHY Wakeup From Hibernate */ @@ -768,7 +113,6 @@ #else #define USBWE 0x0800 /* Enable USB Wakeup From Hibernate */ #endif -#endif #ifndef __ASSEMBLY__ diff --git a/trunk/arch/blackfin/include/asm/fixed_code.h b/trunk/arch/blackfin/include/asm/fixed_code.h index 5395088b2d0e..73fe53e7fd24 100644 --- a/trunk/arch/blackfin/include/asm/fixed_code.h +++ b/trunk/arch/blackfin/include/asm/fixed_code.h @@ -29,28 +29,24 @@ extern void sigreturn_stub(void); #endif #endif -#ifndef CONFIG_PHY_RAM_BASE_ADDRESS -#define CONFIG_PHY_RAM_BASE_ADDRESS 0x0 -#endif - -#define FIXED_CODE_START (CONFIG_PHY_RAM_BASE_ADDRESS + 0x400) +#define FIXED_CODE_START 0x400 -#define SIGRETURN_STUB (CONFIG_PHY_RAM_BASE_ADDRESS + 0x400) +#define SIGRETURN_STUB 0x400 -#define ATOMIC_SEQS_START (CONFIG_PHY_RAM_BASE_ADDRESS + 0x410) +#define ATOMIC_SEQS_START 0x410 -#define ATOMIC_XCHG32 (CONFIG_PHY_RAM_BASE_ADDRESS + 0x410) -#define ATOMIC_CAS32 (CONFIG_PHY_RAM_BASE_ADDRESS + 0x420) -#define ATOMIC_ADD32 (CONFIG_PHY_RAM_BASE_ADDRESS + 0x430) -#define ATOMIC_SUB32 (CONFIG_PHY_RAM_BASE_ADDRESS + 0x440) -#define ATOMIC_IOR32 (CONFIG_PHY_RAM_BASE_ADDRESS + 0x450) -#define ATOMIC_AND32 (CONFIG_PHY_RAM_BASE_ADDRESS + 0x460) -#define ATOMIC_XOR32 (CONFIG_PHY_RAM_BASE_ADDRESS + 0x470) +#define ATOMIC_XCHG32 0x410 +#define ATOMIC_CAS32 0x420 +#define ATOMIC_ADD32 0x430 +#define ATOMIC_SUB32 0x440 +#define ATOMIC_IOR32 0x450 +#define ATOMIC_AND32 0x460 +#define ATOMIC_XOR32 0x470 -#define ATOMIC_SEQS_END (CONFIG_PHY_RAM_BASE_ADDRESS + 0x480) +#define ATOMIC_SEQS_END 0x480 -#define SAFE_USER_INSTRUCTION (CONFIG_PHY_RAM_BASE_ADDRESS + 0x480) +#define SAFE_USER_INSTRUCTION 0x480 -#define FIXED_CODE_END (CONFIG_PHY_RAM_BASE_ADDRESS + 0x490) +#define FIXED_CODE_END 0x490 #endif diff --git a/trunk/arch/blackfin/include/asm/gpio.h b/trunk/arch/blackfin/include/asm/gpio.h index 3d84d96f7c2c..12d3571b5232 100644 --- a/trunk/arch/blackfin/include/asm/gpio.h +++ b/trunk/arch/blackfin/include/asm/gpio.h @@ -26,7 +26,6 @@ #ifndef __ASSEMBLY__ #include -#include /*********************************************************** * @@ -245,49 +244,6 @@ static inline int gpio_set_debounce(unsigned gpio, unsigned debounce) return -EINVAL; } -static inline int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) -{ - int err; - - err = bfin_gpio_request(gpio, label); - if (err) - return err; - - if (flags & GPIOF_DIR_IN) - err = bfin_gpio_direction_input(gpio); - else - err = bfin_gpio_direction_output(gpio, - (flags & GPIOF_INIT_HIGH) ? 1 : 0); - - if (err) - bfin_gpio_free(gpio); - - return err; -} - -static inline int gpio_request_array(const struct gpio *array, size_t num) -{ - int i, err; - - for (i = 0; i < num; i++, array++) { - err = gpio_request_one(array->gpio, array->flags, array->label); - if (err) - goto err_free; - } - return 0; - -err_free: - while (i--) - bfin_gpio_free((--array)->gpio); - return err; -} - -static inline void gpio_free_array(const struct gpio *array, size_t num) -{ - while (num--) - bfin_gpio_free((array++)->gpio); -} - static inline int __gpio_get_value(unsigned gpio) { return bfin_gpio_get_value(gpio); diff --git a/trunk/arch/blackfin/include/asm/gptimers.h b/trunk/arch/blackfin/include/asm/gptimers.h index 381e3d621a4c..38bddcb190c8 100644 --- a/trunk/arch/blackfin/include/asm/gptimers.h +++ b/trunk/arch/blackfin/include/asm/gptimers.h @@ -43,13 +43,6 @@ # define TIMER8_GROUP_REG TMRS4_ENABLE # define TIMER_GROUP2 1 #endif -/* - * BF609: 8 timers: - */ -#if defined(CONFIG_BF60x) -# define MAX_BLACKFIN_GPTIMERS 8 -# define TIMER0_GROUP_REG TIMER_RUN -#endif /* * All others: 3 timers: */ @@ -111,72 +104,6 @@ # define FS2_TIMER_BIT TIMER1bit #endif -#ifdef CONFIG_BF60x -/* - * Timer Configuration Register Bits - */ -#define TIMER_EMU_RUN 0x8000 -#define TIMER_BPER_EN 0x4000 -#define TIMER_BWID_EN 0x2000 -#define TIMER_BDLY_EN 0x1000 -#define TIMER_OUT_DIS 0x0800 -#define TIMER_TIN_SEL 0x0400 -#define TIMER_CLK_SEL 0x0300 -#define TIMER_CLK_SCLK 0x0000 -#define TIMER_CLK_ALT_CLK0 0x0100 -#define TIMER_CLK_ALT_CLK1 0x0300 -#define TIMER_PULSE_HI 0x0080 -#define TIMER_SLAVE_TRIG 0x0040 -#define TIMER_IRQ_MODE 0x0030 -#define TIMER_IRQ_ACT_EDGE 0x0000 -#define TIMER_IRQ_DLY 0x0010 -#define TIMER_IRQ_WID_DLY 0x0020 -#define TIMER_IRQ_PER 0x0030 -#define TIMER_MODE 0x000f -#define TIMER_MODE_WDOG_P 0x0008 -#define TIMER_MODE_WDOG_W 0x0009 -#define TIMER_MODE_PWM_CONT 0x000c -#define TIMER_MODE_PWM 0x000d -#define TIMER_MODE_WDTH 0x000a -#define TIMER_MODE_WDTH_D 0x000b -#define TIMER_MODE_EXT_CLK 0x000e -#define TIMER_MODE_PININT 0x000f - -/* - * Timer Status Register Bits - */ -#define TIMER_STATUS_TIMIL0 0x0001 -#define TIMER_STATUS_TIMIL1 0x0002 -#define TIMER_STATUS_TIMIL2 0x0004 -#define TIMER_STATUS_TIMIL3 0x0008 -#define TIMER_STATUS_TIMIL4 0x0010 -#define TIMER_STATUS_TIMIL5 0x0020 -#define TIMER_STATUS_TIMIL6 0x0040 -#define TIMER_STATUS_TIMIL7 0x0080 - -#define TIMER_STATUS_TOVF0 0x0001 /* timer 0 overflow error */ -#define TIMER_STATUS_TOVF1 0x0002 -#define TIMER_STATUS_TOVF2 0x0004 -#define TIMER_STATUS_TOVF3 0x0008 -#define TIMER_STATUS_TOVF4 0x0010 -#define TIMER_STATUS_TOVF5 0x0020 -#define TIMER_STATUS_TOVF6 0x0040 -#define TIMER_STATUS_TOVF7 0x0080 - -/* - * Timer Slave Enable Status : write 1 to clear - */ -#define TIMER_STATUS_TRUN0 0x0001 -#define TIMER_STATUS_TRUN1 0x0002 -#define TIMER_STATUS_TRUN2 0x0004 -#define TIMER_STATUS_TRUN3 0x0008 -#define TIMER_STATUS_TRUN4 0x0010 -#define TIMER_STATUS_TRUN5 0x0020 -#define TIMER_STATUS_TRUN6 0x0040 -#define TIMER_STATUS_TRUN7 0x0080 - -#else - /* * Timer Configuration Register Bits */ @@ -243,18 +170,12 @@ #define TIMER_STATUS_TRUN10 0x4000 #define TIMER_STATUS_TRUN11 0x8000 -#endif - /* The actual gptimer API */ void set_gptimer_pwidth(unsigned int timer_id, uint32_t width); uint32_t get_gptimer_pwidth(unsigned int timer_id); void set_gptimer_period(unsigned int timer_id, uint32_t period); uint32_t get_gptimer_period(unsigned int timer_id); -#ifdef CONFIG_BF60x -void set_gptimer_delay(unsigned int timer_id, uint32_t delay); -uint32_t get_gptimer_delay(unsigned int timer_id); -#endif uint32_t get_gptimer_count(unsigned int timer_id); int get_gptimer_intr(unsigned int timer_id); void clear_gptimer_intr(unsigned int timer_id); @@ -296,41 +217,16 @@ struct bfin_gptimer_regs { u32 counter; u32 period; u32 width; -#ifdef CONFIG_BF60x - u32 delay; -#endif }; /* * bfin group timer registers layout */ -#ifndef CONFIG_BF60x struct bfin_gptimer_group_regs { __BFP(enable); __BFP(disable); u32 status; }; -#else -struct bfin_gptimer_group_regs { - __BFP(run); - __BFP(enable); - __BFP(disable); - __BFP(stop_cfg); - __BFP(stop_cfg_set); - __BFP(stop_cfg_clr); - __BFP(data_imsk); - __BFP(stat_imsk); - __BFP(tr_msk); - __BFP(tr_ie); - __BFP(data_ilat); - __BFP(stat_ilat); - __BFP(err_status); - __BFP(bcast_per); - __BFP(bcast_wid); - __BFP(bcast_dly); - -}; -#endif #undef __BFP diff --git a/trunk/arch/blackfin/include/asm/irqflags.h b/trunk/arch/blackfin/include/asm/irqflags.h index 07aff230a812..43eb4749de3d 100644 --- a/trunk/arch/blackfin/include/asm/irqflags.h +++ b/trunk/arch/blackfin/include/asm/irqflags.h @@ -67,11 +67,7 @@ static inline notrace unsigned long __hard_local_irq_save(void) static inline notrace int hard_irqs_disabled_flags(unsigned long flags) { -#ifdef CONFIG_BF60x - return (flags & IMASK_IVG11) == 0; -#else return (flags & ~0x3f) == 0; -#endif } static inline notrace int hard_irqs_disabled(void) @@ -228,7 +224,7 @@ static inline notrace void hard_local_irq_restore(unsigned long flags) * Direct interface to linux/irqflags.h. */ #define arch_local_save_flags() hard_local_save_flags() -#define arch_local_irq_save() __hard_local_irq_save() +#define arch_local_irq_save(flags) __hard_local_irq_save() #define arch_local_irq_restore(flags) __hard_local_irq_restore(flags) #define arch_local_irq_enable() __hard_local_irq_enable() #define arch_local_irq_disable() __hard_local_irq_disable() diff --git a/trunk/arch/blackfin/include/asm/page.h b/trunk/arch/blackfin/include/asm/page.h index b93474d5be75..7202404966f6 100644 --- a/trunk/arch/blackfin/include/asm/page.h +++ b/trunk/arch/blackfin/include/asm/page.h @@ -7,15 +7,14 @@ #ifndef _BLACKFIN_PAGE_H #define _BLACKFIN_PAGE_H -#define ARCH_PFN_OFFSET (CONFIG_PHY_RAM_BASE_ADDRESS >> PAGE_SHIFT) -#define MAP_NR(addr) ((unsigned long)(addr) >> PAGE_SHIFT) +#include +#define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT) #define VM_DATA_DEFAULT_FLAGS \ (VM_READ | VM_WRITE | \ ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) -#include #include #include diff --git a/trunk/arch/blackfin/include/asm/pda.h b/trunk/arch/blackfin/include/asm/pda.h index 68d6f6618f2a..28c2498c9c98 100644 --- a/trunk/arch/blackfin/include/asm/pda.h +++ b/trunk/arch/blackfin/include/asm/pda.h @@ -13,9 +13,7 @@ #ifndef __ASSEMBLY__ struct blackfin_pda { /* Per-processor Data Area */ -#ifdef CONFIG_SMP struct blackfin_pda *next; -#endif unsigned long syscfg; #ifdef CONFIG_SMP diff --git a/trunk/arch/blackfin/include/asm/pm.h b/trunk/arch/blackfin/include/asm/pm.h deleted file mode 100644 index f72239bf3638..000000000000 --- a/trunk/arch/blackfin/include/asm/pm.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Blackfin bf609 power management - * - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2 - */ - -#ifndef __PM_H__ -#define __PM_H__ - -#include - -struct bfin_cpu_pm_fns { - void (*save)(unsigned long *); - void (*restore)(unsigned long *); - int (*valid)(suspend_state_t state); - void (*enter)(suspend_state_t state); - int (*prepare)(void); - void (*finish)(void); -}; - -extern struct bfin_cpu_pm_fns *bfin_cpu_pm; - -# ifdef CONFIG_BFIN_COREB -void bfin_coreb_start(void); -void bfin_coreb_stop(void); -void bfin_coreb_reset(void); -# endif - -#endif diff --git a/trunk/arch/blackfin/include/asm/unistd.h b/trunk/arch/blackfin/include/asm/unistd.h index 3287222cba34..75ec9df5318b 100644 --- a/trunk/arch/blackfin/include/asm/unistd.h +++ b/trunk/arch/blackfin/include/asm/unistd.h @@ -11,7 +11,7 @@ */ #define __NR_restart_syscall 0 #define __NR_exit 1 - /* 2 __NR_fork not supported on nommu */ +#define __NR_fork 2 #define __NR_read 3 #define __NR_write 4 #define __NR_open 5 diff --git a/trunk/arch/blackfin/kernel/Makefile b/trunk/arch/blackfin/kernel/Makefile index 08e6625106be..9a0d6d706443 100644 --- a/trunk/arch/blackfin/kernel/Makefile +++ b/trunk/arch/blackfin/kernel/Makefile @@ -2,7 +2,7 @@ # arch/blackfin/kernel/Makefile # -extra-y := vmlinux.lds +extra-y := init_task.o vmlinux.lds obj-y := \ entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \ diff --git a/trunk/arch/blackfin/kernel/bfin_dma.c b/trunk/arch/blackfin/kernel/bfin_dma.c index c166939ffb2b..40c2ed61258e 100644 --- a/trunk/arch/blackfin/kernel/bfin_dma.c +++ b/trunk/arch/blackfin/kernel/bfin_dma.c @@ -45,15 +45,9 @@ static int __init blackfin_dma_init(void) atomic_set(&dma_ch[i].chan_status, 0); dma_ch[i].regs = dma_io_base_addr[i]; } -#ifdef CH_MEM_STREAM3_SRC - /* Mark MEMDMA Channel 3 as requested since we're using it internally */ - request_dma(CH_MEM_STREAM3_DEST, "Blackfin dma_memcpy"); - request_dma(CH_MEM_STREAM3_SRC, "Blackfin dma_memcpy"); -#else /* Mark MEMDMA Channel 0 as requested since we're using it internally */ request_dma(CH_MEM_STREAM0_DEST, "Blackfin dma_memcpy"); request_dma(CH_MEM_STREAM0_SRC, "Blackfin dma_memcpy"); -#endif #if defined(CONFIG_DEB_DMA_URGENT) bfin_write_EBIU_DDRQUE(bfin_read_EBIU_DDRQUE() @@ -90,8 +84,7 @@ static const struct file_operations proc_dma_operations = { static int __init proc_dma_init(void) { - proc_create("dma", 0, NULL, &proc_dma_operations); - return 0; + return proc_create("dma", 0, NULL, &proc_dma_operations) != NULL; } late_initcall(proc_dma_init); #endif @@ -211,7 +204,6 @@ EXPORT_SYMBOL(free_dma); # ifndef MAX_DMA_SUSPEND_CHANNELS # define MAX_DMA_SUSPEND_CHANNELS MAX_DMA_CHANNELS # endif -# ifndef CONFIG_BF60x int blackfin_dma_suspend(void) { int i; @@ -221,6 +213,7 @@ int blackfin_dma_suspend(void) printk(KERN_ERR "DMA Channel %d failed to suspend\n", i); return -EBUSY; } + if (i < MAX_DMA_SUSPEND_CHANNELS) dma_ch[i].saved_peripheral_map = dma_ch[i].regs->peripheral_map; } @@ -237,6 +230,7 @@ void blackfin_dma_resume(void) for (i = 0; i < MAX_DMA_CHANNELS; ++i) { dma_ch[i].regs->cfg = 0; + if (i < MAX_DMA_SUSPEND_CHANNELS) dma_ch[i].regs->peripheral_map = dma_ch[i].saved_peripheral_map; } @@ -244,16 +238,6 @@ void blackfin_dma_resume(void) bfin_write_DMAC_TC_PER(0x0111); #endif } -# else -int blackfin_dma_suspend(void) -{ - return 0; -} - -void blackfin_dma_resume(void) -{ -} -#endif #endif /** @@ -295,10 +279,10 @@ void __init early_dma_memcpy(void *pdst, const void *psrc, size_t size) src_ch = (struct dma_register *)MDMA_S0_NEXT_DESC_PTR; } - if (!DMA_MMR_READ(&src_ch->cfg)) + if (!bfin_read16(&src_ch->cfg)) break; - else if (DMA_MMR_READ(&dst_ch->irq_status) & DMA_DONE) { - DMA_MMR_WRITE(&src_ch->cfg, 0); + else if (bfin_read16(&dst_ch->irq_status) & DMA_DONE) { + bfin_write16(&src_ch->cfg, 0); break; } } @@ -311,31 +295,22 @@ void __init early_dma_memcpy(void *pdst, const void *psrc, size_t size) /* Destination */ bfin_write32(&dst_ch->start_addr, dst); - DMA_MMR_WRITE(&dst_ch->x_count, size >> 2); - DMA_MMR_WRITE(&dst_ch->x_modify, 1 << 2); - DMA_MMR_WRITE(&dst_ch->irq_status, DMA_DONE | DMA_ERR); + bfin_write16(&dst_ch->x_count, size >> 2); + bfin_write16(&dst_ch->x_modify, 1 << 2); + bfin_write16(&dst_ch->irq_status, DMA_DONE | DMA_ERR); /* Source */ bfin_write32(&src_ch->start_addr, src); - DMA_MMR_WRITE(&src_ch->x_count, size >> 2); - DMA_MMR_WRITE(&src_ch->x_modify, 1 << 2); - DMA_MMR_WRITE(&src_ch->irq_status, DMA_DONE | DMA_ERR); + bfin_write16(&src_ch->x_count, size >> 2); + bfin_write16(&src_ch->x_modify, 1 << 2); + bfin_write16(&src_ch->irq_status, DMA_DONE | DMA_ERR); /* Enable */ - DMA_MMR_WRITE(&src_ch->cfg, DMAEN | WDSIZE_32); - DMA_MMR_WRITE(&dst_ch->cfg, WNR | DI_EN_X | DMAEN | WDSIZE_32); + bfin_write16(&src_ch->cfg, DMAEN | WDSIZE_32); + bfin_write16(&dst_ch->cfg, WNR | DI_EN | DMAEN | WDSIZE_32); /* Since we are atomic now, don't use the workaround ssync */ __builtin_bfin_ssync(); - -#ifdef CONFIG_BF60x - /* Work around a possible MDMA anomaly. Running 2 MDMA channels to - * transfer DDR data to L1 SRAM may corrupt data. - * Should be reverted after this issue is root caused. - */ - while (!(DMA_MMR_READ(&dst_ch->irq_status) & DMA_DONE)) - continue; -#endif } void __init early_dma_memcpy_done(void) @@ -361,42 +336,6 @@ void __init early_dma_memcpy_done(void) __builtin_bfin_ssync(); } -#ifdef CH_MEM_STREAM3_SRC -#define bfin_read_MDMA_S_CONFIG bfin_read_MDMA_S3_CONFIG -#define bfin_write_MDMA_S_CONFIG bfin_write_MDMA_S3_CONFIG -#define bfin_write_MDMA_S_START_ADDR bfin_write_MDMA_S3_START_ADDR -#define bfin_write_MDMA_S_IRQ_STATUS bfin_write_MDMA_S3_IRQ_STATUS -#define bfin_write_MDMA_S_X_COUNT bfin_write_MDMA_S3_X_COUNT -#define bfin_write_MDMA_S_X_MODIFY bfin_write_MDMA_S3_X_MODIFY -#define bfin_write_MDMA_S_Y_COUNT bfin_write_MDMA_S3_Y_COUNT -#define bfin_write_MDMA_S_Y_MODIFY bfin_write_MDMA_S3_Y_MODIFY -#define bfin_write_MDMA_D_CONFIG bfin_write_MDMA_D3_CONFIG -#define bfin_write_MDMA_D_START_ADDR bfin_write_MDMA_D3_START_ADDR -#define bfin_read_MDMA_D_IRQ_STATUS bfin_read_MDMA_D3_IRQ_STATUS -#define bfin_write_MDMA_D_IRQ_STATUS bfin_write_MDMA_D3_IRQ_STATUS -#define bfin_write_MDMA_D_X_COUNT bfin_write_MDMA_D3_X_COUNT -#define bfin_write_MDMA_D_X_MODIFY bfin_write_MDMA_D3_X_MODIFY -#define bfin_write_MDMA_D_Y_COUNT bfin_write_MDMA_D3_Y_COUNT -#define bfin_write_MDMA_D_Y_MODIFY bfin_write_MDMA_D3_Y_MODIFY -#else -#define bfin_read_MDMA_S_CONFIG bfin_read_MDMA_S0_CONFIG -#define bfin_write_MDMA_S_CONFIG bfin_write_MDMA_S0_CONFIG -#define bfin_write_MDMA_S_START_ADDR bfin_write_MDMA_S0_START_ADDR -#define bfin_write_MDMA_S_IRQ_STATUS bfin_write_MDMA_S0_IRQ_STATUS -#define bfin_write_MDMA_S_X_COUNT bfin_write_MDMA_S0_X_COUNT -#define bfin_write_MDMA_S_X_MODIFY bfin_write_MDMA_S0_X_MODIFY -#define bfin_write_MDMA_S_Y_COUNT bfin_write_MDMA_S0_Y_COUNT -#define bfin_write_MDMA_S_Y_MODIFY bfin_write_MDMA_S0_Y_MODIFY -#define bfin_write_MDMA_D_CONFIG bfin_write_MDMA_D0_CONFIG -#define bfin_write_MDMA_D_START_ADDR bfin_write_MDMA_D0_START_ADDR -#define bfin_read_MDMA_D_IRQ_STATUS bfin_read_MDMA_D0_IRQ_STATUS -#define bfin_write_MDMA_D_IRQ_STATUS bfin_write_MDMA_D0_IRQ_STATUS -#define bfin_write_MDMA_D_X_COUNT bfin_write_MDMA_D0_X_COUNT -#define bfin_write_MDMA_D_X_MODIFY bfin_write_MDMA_D0_X_MODIFY -#define bfin_write_MDMA_D_Y_COUNT bfin_write_MDMA_D0_Y_COUNT -#define bfin_write_MDMA_D_Y_MODIFY bfin_write_MDMA_D0_Y_MODIFY -#endif - /** * __dma_memcpy - program the MDMA registers * @@ -419,8 +358,8 @@ static void __dma_memcpy(u32 daddr, s16 dmod, u32 saddr, s16 smod, size_t cnt, u */ __builtin_bfin_ssync(); - if (bfin_read_MDMA_S_CONFIG()) - while (!(bfin_read_MDMA_D_IRQ_STATUS() & DMA_DONE)) + if (bfin_read_MDMA_S0_CONFIG()) + while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) continue; if (conf & DMA2D) { @@ -435,42 +374,39 @@ static void __dma_memcpy(u32 daddr, s16 dmod, u32 saddr, s16 smod, size_t cnt, u u32 shift = abs(dmod) >> 1; size_t ycnt = cnt >> (16 - shift); cnt = 1 << (16 - shift); - bfin_write_MDMA_D_Y_COUNT(ycnt); - bfin_write_MDMA_S_Y_COUNT(ycnt); - bfin_write_MDMA_D_Y_MODIFY(dmod); - bfin_write_MDMA_S_Y_MODIFY(smod); + bfin_write_MDMA_D0_Y_COUNT(ycnt); + bfin_write_MDMA_S0_Y_COUNT(ycnt); + bfin_write_MDMA_D0_Y_MODIFY(dmod); + bfin_write_MDMA_S0_Y_MODIFY(smod); } - bfin_write_MDMA_D_START_ADDR(daddr); - bfin_write_MDMA_D_X_COUNT(cnt); - bfin_write_MDMA_D_X_MODIFY(dmod); - bfin_write_MDMA_D_IRQ_STATUS(DMA_DONE | DMA_ERR); + bfin_write_MDMA_D0_START_ADDR(daddr); + bfin_write_MDMA_D0_X_COUNT(cnt); + bfin_write_MDMA_D0_X_MODIFY(dmod); + bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); - bfin_write_MDMA_S_START_ADDR(saddr); - bfin_write_MDMA_S_X_COUNT(cnt); - bfin_write_MDMA_S_X_MODIFY(smod); - bfin_write_MDMA_S_IRQ_STATUS(DMA_DONE | DMA_ERR); + bfin_write_MDMA_S0_START_ADDR(saddr); + bfin_write_MDMA_S0_X_COUNT(cnt); + bfin_write_MDMA_S0_X_MODIFY(smod); + bfin_write_MDMA_S0_IRQ_STATUS(DMA_DONE | DMA_ERR); - bfin_write_MDMA_S_CONFIG(DMAEN | conf); - if (conf & DMA2D) - bfin_write_MDMA_D_CONFIG(WNR | DI_EN_Y | DMAEN | conf); - else - bfin_write_MDMA_D_CONFIG(WNR | DI_EN_X | DMAEN | conf); + bfin_write_MDMA_S0_CONFIG(DMAEN | conf); + bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | conf); spin_unlock_irqrestore(&mdma_lock, flags); SSYNC(); - while (!(bfin_read_MDMA_D_IRQ_STATUS() & DMA_DONE)) - if (bfin_read_MDMA_S_CONFIG()) + while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) + if (bfin_read_MDMA_S0_CONFIG()) continue; else return; - bfin_write_MDMA_D_IRQ_STATUS(DMA_DONE | DMA_ERR); + bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); - bfin_write_MDMA_S_CONFIG(0); - bfin_write_MDMA_D_CONFIG(0); + bfin_write_MDMA_S0_CONFIG(0); + bfin_write_MDMA_D0_CONFIG(0); } /** @@ -512,10 +448,8 @@ static void *_dma_memcpy(void *pdst, const void *psrc, size_t size) } size >>= shift; -#ifndef DMA_MMR_SIZE_32 if (size > 0x10000) conf |= DMA2D; -#endif __dma_memcpy(dst, mod, src, mod, size, conf); @@ -554,9 +488,6 @@ EXPORT_SYMBOL(dma_memcpy); */ void *dma_memcpy_nocache(void *pdst, const void *psrc, size_t size) { -#ifdef DMA_MMR_SIZE_32 - _dma_memcpy(pdst, psrc, size); -#else size_t bulk, rest; bulk = size & ~0xffff; @@ -564,7 +495,6 @@ void *dma_memcpy_nocache(void *pdst, const void *psrc, size_t size) if (bulk) _dma_memcpy(pdst, psrc, bulk); _dma_memcpy(pdst + bulk, psrc + bulk, rest); -#endif return pdst; } EXPORT_SYMBOL(dma_memcpy_nocache); @@ -584,14 +514,14 @@ void *safe_dma_memcpy(void *dst, const void *src, size_t size) } EXPORT_SYMBOL(safe_dma_memcpy); -static void _dma_out(unsigned long addr, unsigned long buf, unsigned DMA_MMR_SIZE_TYPE len, +static void _dma_out(unsigned long addr, unsigned long buf, unsigned short len, u16 size, u16 dma_size) { blackfin_dcache_flush_range(buf, buf + len * size); __dma_memcpy(addr, 0, buf, size, len, dma_size); } -static void _dma_in(unsigned long addr, unsigned long buf, unsigned DMA_MMR_SIZE_TYPE len, +static void _dma_in(unsigned long addr, unsigned long buf, unsigned short len, u16 size, u16 dma_size) { blackfin_dcache_invalidate_range(buf, buf + len * size); @@ -599,7 +529,7 @@ static void _dma_in(unsigned long addr, unsigned long buf, unsigned DMA_MMR_SIZE } #define MAKE_DMA_IO(io, bwl, isize, dmasize, cnst) \ -void dma_##io##s##bwl(unsigned long addr, cnst void *buf, unsigned DMA_MMR_SIZE_TYPE len) \ +void dma_##io##s##bwl(unsigned long addr, cnst void *buf, unsigned short len) \ { \ _dma_##io(addr, (unsigned long)buf, len, isize, WDSIZE_##dmasize); \ } \ diff --git a/trunk/arch/blackfin/kernel/bfin_gpio.c b/trunk/arch/blackfin/kernel/bfin_gpio.c index 83139aaf3072..02796b88443d 100644 --- a/trunk/arch/blackfin/kernel/bfin_gpio.c +++ b/trunk/arch/blackfin/kernel/bfin_gpio.c @@ -58,7 +58,7 @@ static struct gpio_port_t * const gpio_array[] = { (struct gpio_port_t *) FIO0_FLAG_D, (struct gpio_port_t *) FIO1_FLAG_D, (struct gpio_port_t *) FIO2_FLAG_D, -#elif defined(CONFIG_BF54x) || defined(CONFIG_BF60x) +#elif defined(CONFIG_BF54x) (struct gpio_port_t *)PORTA_FER, (struct gpio_port_t *)PORTB_FER, (struct gpio_port_t *)PORTC_FER, @@ -66,11 +66,9 @@ static struct gpio_port_t * const gpio_array[] = { (struct gpio_port_t *)PORTE_FER, (struct gpio_port_t *)PORTF_FER, (struct gpio_port_t *)PORTG_FER, -# if defined(CONFIG_BF54x) (struct gpio_port_t *)PORTH_FER, (struct gpio_port_t *)PORTI_FER, (struct gpio_port_t *)PORTJ_FER, -# endif #else # error no gpio arrays defined #endif @@ -212,7 +210,7 @@ static void port_setup(unsigned gpio, unsigned short usage) else *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio); SSYNC(); -#elif defined(CONFIG_BF54x) || defined(CONFIG_BF60x) +#elif defined(CONFIG_BF54x) if (usage == GPIO_USAGE) gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio); else @@ -301,7 +299,7 @@ static void portmux_setup(unsigned short per) pmux |= (function << offset); bfin_write_PORT_MUX(pmux); } -#elif defined(CONFIG_BF54x) || defined(CONFIG_BF60x) +#elif defined(CONFIG_BF54x) inline void portmux_setup(unsigned short per) { u16 ident = P_IDENT(per); @@ -379,7 +377,7 @@ static int portmux_group_check(unsigned short per) } #endif -#if !(defined(CONFIG_BF54x) || defined(CONFIG_BF60x)) +#ifndef CONFIG_BF54x /*********************************************************** * * FUNCTIONS: Blackfin General Purpose Ports Access Functions @@ -682,7 +680,7 @@ void bfin_gpio_pm_hibernate_restore(void) #endif -#else /* CONFIG_BF54x || CONFIG_BF60x */ +#else /* CONFIG_BF54x */ #ifdef CONFIG_PM int bfin_pm_standby_ctrl(unsigned ctrl) @@ -728,7 +726,7 @@ unsigned short get_gpio_dir(unsigned gpio) } EXPORT_SYMBOL(get_gpio_dir); -#endif /* CONFIG_BF54x || CONFIG_BF60x */ +#endif /* CONFIG_BF54x */ /*********************************************************** * @@ -785,7 +783,7 @@ int peripheral_request(unsigned short per, const char *label) * be requested and used by several drivers */ -#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) +#ifdef CONFIG_BF54x if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) { #else if (!(per & P_MAYSHARE)) { @@ -939,7 +937,7 @@ int bfin_gpio_request(unsigned gpio, const char *label) printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!" " (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio); } -#if !(defined(CONFIG_BF54x) || defined(CONFIG_BF60x)) +#ifndef CONFIG_BF54x else { /* Reset POLAR setting when acquiring a gpio for the first time */ set_gpio_polar(gpio, 0); } @@ -1112,7 +1110,7 @@ void bfin_gpio_irq_free(unsigned gpio) static inline void __bfin_gpio_direction_input(unsigned gpio) { -#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) +#ifdef CONFIG_BF54x gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio); #else gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); @@ -1140,13 +1138,13 @@ EXPORT_SYMBOL(bfin_gpio_direction_input); void bfin_gpio_irq_prepare(unsigned gpio) { -#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) +#ifdef CONFIG_BF54x unsigned long flags; #endif port_setup(gpio, GPIO_USAGE); -#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) +#ifdef CONFIG_BF54x flags = hard_local_irq_save(); __bfin_gpio_direction_input(gpio); hard_local_irq_restore(flags); @@ -1175,7 +1173,7 @@ int bfin_gpio_direction_output(unsigned gpio, int value) gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); gpio_set_value(gpio, value); -#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) +#ifdef CONFIG_BF54x gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio); #else gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio); @@ -1190,7 +1188,7 @@ EXPORT_SYMBOL(bfin_gpio_direction_output); int bfin_gpio_get_value(unsigned gpio) { -#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) +#ifdef CONFIG_BF54x return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio))); #else unsigned long flags; diff --git a/trunk/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/trunk/arch/blackfin/kernel/cplb-nompu/cplbinit.c index 3e366dc2d6e1..886e00014d75 100644 --- a/trunk/arch/blackfin/kernel/cplb-nompu/cplbinit.c +++ b/trunk/arch/blackfin/kernel/cplb-nompu/cplbinit.c @@ -139,7 +139,7 @@ void __init generate_cplb_tables_all(void) dcplb_bounds[i_d].eaddr = BOOT_ROM_START; dcplb_bounds[i_d++].data = 0; /* BootROM -- largest one should be less than 1 meg. */ - dcplb_bounds[i_d].eaddr = BOOT_ROM_START + BOOT_ROM_LENGTH; + dcplb_bounds[i_d].eaddr = BOOT_ROM_START + (1 * 1024 * 1024); dcplb_bounds[i_d++].data = SDRAM_DGENERIC; if (L2_LENGTH) { /* Addressing hole up to L2 SRAM. */ @@ -178,7 +178,7 @@ void __init generate_cplb_tables_all(void) icplb_bounds[i_i].eaddr = BOOT_ROM_START; icplb_bounds[i_i++].data = 0; /* BootROM -- largest one should be less than 1 meg. */ - icplb_bounds[i_i].eaddr = BOOT_ROM_START + BOOT_ROM_LENGTH; + icplb_bounds[i_i].eaddr = BOOT_ROM_START + (1 * 1024 * 1024); icplb_bounds[i_i++].data = SDRAM_IGENERIC; if (L2_LENGTH) { diff --git a/trunk/arch/blackfin/kernel/cplb-nompu/cplbmgr.c b/trunk/arch/blackfin/kernel/cplb-nompu/cplbmgr.c index e854f9066cbd..5b88861d6183 100644 --- a/trunk/arch/blackfin/kernel/cplb-nompu/cplbmgr.c +++ b/trunk/arch/blackfin/kernel/cplb-nompu/cplbmgr.c @@ -179,12 +179,6 @@ MGR_ATTR static int dcplb_miss(int cpu) addr = addr1; } -#ifdef CONFIG_BF60x - if ((addr >= ASYNC_BANK0_BASE) - && (addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE)) - d_data |= PAGE_SIZE_64MB; -#endif - /* Pick entry to evict */ idx = evict_one_dcplb(cpu); diff --git a/trunk/arch/blackfin/kernel/debug-mmrs.c b/trunk/arch/blackfin/kernel/debug-mmrs.c index 01232a13470d..92f664826281 100644 --- a/trunk/arch/blackfin/kernel/debug-mmrs.c +++ b/trunk/arch/blackfin/kernel/debug-mmrs.c @@ -105,7 +105,6 @@ DEFINE_SYSREG(seqstat, , ); DEFINE_SYSREG(syscfg, , CSYNC()); #define D_SYSREG(sr) debugfs_create_file(#sr, S_IRUSR|S_IWUSR, parent, NULL, &fops_sysreg_##sr) -#ifndef CONFIG_BF60x /* * CAN */ @@ -224,10 +223,8 @@ bfin_debug_mmrs_dma(struct dentry *parent, unsigned long base, int num, char mdm __DMA(CURR_DESC_PTR, curr_desc_ptr); __DMA(CURR_ADDR, curr_addr); __DMA(IRQ_STATUS, irq_status); -#ifndef CONFIG_BF60x if (strcmp(pfx, "IMDMA") != 0) __DMA(PERIPHERAL_MAP, peripheral_map); -#endif __DMA(CURR_X_COUNT, curr_x_count); __DMA(CURR_Y_COUNT, curr_y_count); } @@ -571,7 +568,7 @@ bfin_debug_mmrs_uart(struct dentry *parent, unsigned long base, int num) #endif } #define UART(num) bfin_debug_mmrs_uart(parent, UART##num##_DLL, num) -#endif /* CONFIG_BF60x */ + /* * The actual debugfs generation */ @@ -743,7 +740,7 @@ static int __init bfin_debug_mmrs_init(void) D32(WPDACNT0); D32(WPDACNT1); D32(WPSTAT); -#ifndef CONFIG_BF60x + /* System MMRs */ #ifdef ATAPI_CONTROL parent = debugfs_create_dir("atapi", top); @@ -1876,7 +1873,7 @@ static int __init bfin_debug_mmrs_init(void) } #endif /* BF54x */ -#endif /* CONFIG_BF60x */ + debug_mmrs_dentry = top; return 0; diff --git a/trunk/arch/blackfin/kernel/entry.S b/trunk/arch/blackfin/kernel/entry.S index f33792cc1a0d..686478f5f66b 100644 --- a/trunk/arch/blackfin/kernel/entry.S +++ b/trunk/arch/blackfin/kernel/entry.S @@ -64,6 +64,16 @@ ENTRY(_ret_from_fork) jump (p0); ENDPROC(_ret_from_fork) +ENTRY(_sys_fork) + r0 = -EINVAL; +#if (ANOMALY_05000371) + nop; + nop; + nop; +#endif + rts; +ENDPROC(_sys_fork) + ENTRY(_sys_vfork) r0 = sp; r0 += 24; diff --git a/trunk/arch/blackfin/kernel/gptimers.c b/trunk/arch/blackfin/kernel/gptimers.c index d776773d3869..06459f4bf43a 100644 --- a/trunk/arch/blackfin/kernel/gptimers.c +++ b/trunk/arch/blackfin/kernel/gptimers.c @@ -23,11 +23,7 @@ printk(KERN_DEBUG "%s:%s:%i: Assertion failed: " #expr "\n", __FILE__, __func__, __LINE__); #endif -#ifndef CONFIG_BF60x -# define BFIN_TIMER_NUM_GROUP (BFIN_TIMER_OCTET(MAX_BLACKFIN_GPTIMERS - 1) + 1) -#else -# define BFIN_TIMER_NUM_GROUP 1 -#endif +#define BFIN_TIMER_NUM_GROUP (BFIN_TIMER_OCTET(MAX_BLACKFIN_GPTIMERS - 1) + 1) static struct bfin_gptimer_regs * const timer_regs[MAX_BLACKFIN_GPTIMERS] = { @@ -162,74 +158,6 @@ uint32_t get_gptimer_count(unsigned int timer_id) } EXPORT_SYMBOL(get_gptimer_count); -#ifdef CONFIG_BF60x -void set_gptimer_delay(unsigned int timer_id, uint32_t delay) -{ - tassert(timer_id < MAX_BLACKFIN_GPTIMERS); - bfin_write(&timer_regs[timer_id]->delay, delay); - SSYNC(); -} -EXPORT_SYMBOL(set_gptimer_delay); - -uint32_t get_gptimer_delay(unsigned int timer_id) -{ - tassert(timer_id < MAX_BLACKFIN_GPTIMERS); - return bfin_read(&timer_regs[timer_id]->delay); -} -EXPORT_SYMBOL(get_gptimer_delay); -#endif - -#ifdef CONFIG_BF60x -int get_gptimer_intr(unsigned int timer_id) -{ - tassert(timer_id < MAX_BLACKFIN_GPTIMERS); - return !!(bfin_read(&group_regs[BFIN_TIMER_OCTET(timer_id)]->data_ilat) & timil_mask[timer_id]); -} -EXPORT_SYMBOL(get_gptimer_intr); - -void clear_gptimer_intr(unsigned int timer_id) -{ - tassert(timer_id < MAX_BLACKFIN_GPTIMERS); - bfin_write(&group_regs[BFIN_TIMER_OCTET(timer_id)]->data_ilat, timil_mask[timer_id]); -} -EXPORT_SYMBOL(clear_gptimer_intr); - -int get_gptimer_over(unsigned int timer_id) -{ - tassert(timer_id < MAX_BLACKFIN_GPTIMERS); - return !!(bfin_read(&group_regs[BFIN_TIMER_OCTET(timer_id)]->stat_ilat) & tovf_mask[timer_id]); -} -EXPORT_SYMBOL(get_gptimer_over); - -void clear_gptimer_over(unsigned int timer_id) -{ - tassert(timer_id < MAX_BLACKFIN_GPTIMERS); - bfin_write(&group_regs[BFIN_TIMER_OCTET(timer_id)]->stat_ilat, tovf_mask[timer_id]); -} -EXPORT_SYMBOL(clear_gptimer_over); - -int get_gptimer_run(unsigned int timer_id) -{ - tassert(timer_id < MAX_BLACKFIN_GPTIMERS); - return !!(bfin_read(&group_regs[BFIN_TIMER_OCTET(timer_id)]->run) & trun_mask[timer_id]); -} -EXPORT_SYMBOL(get_gptimer_run); - -uint32_t get_gptimer_status(unsigned int group) -{ - tassert(group < BFIN_TIMER_NUM_GROUP); - return bfin_read(&group_regs[group]->data_ilat); -} -EXPORT_SYMBOL(get_gptimer_status); - -void set_gptimer_status(unsigned int group, uint32_t value) -{ - tassert(group < BFIN_TIMER_NUM_GROUP); - bfin_write(&group_regs[group]->data_ilat, value); - SSYNC(); -} -EXPORT_SYMBOL(set_gptimer_status); -#else uint32_t get_gptimer_status(unsigned int group) { tassert(group < BFIN_TIMER_NUM_GROUP); @@ -284,7 +212,6 @@ int get_gptimer_run(unsigned int timer_id) return !!(read_gptimer_status(timer_id) & trun_mask[timer_id]); } EXPORT_SYMBOL(get_gptimer_run); -#endif void set_gptimer_config(unsigned int timer_id, uint16_t config) { @@ -304,12 +231,6 @@ EXPORT_SYMBOL(get_gptimer_config); void enable_gptimers(uint16_t mask) { int i; -#ifdef CONFIG_BF60x - uint16_t imask; - imask = bfin_read16(TIMER_DATA_IMSK); - imask &= ~mask; - bfin_write16(TIMER_DATA_IMSK, imask); -#endif tassert((mask & ~BLACKFIN_GPTIMER_IDMASK) == 0); for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i) { bfin_write(&group_regs[i]->enable, mask & 0xFF); @@ -332,16 +253,12 @@ static void _disable_gptimers(uint16_t mask) void disable_gptimers(uint16_t mask) { -#ifndef CONFIG_BF60x int i; _disable_gptimers(mask); for (i = 0; i < MAX_BLACKFIN_GPTIMERS; ++i) if (mask & (1 << i)) bfin_write(&group_regs[BFIN_TIMER_OCTET(i)]->status, trun_mask[i]); SSYNC(); -#else - _disable_gptimers(mask); -#endif } EXPORT_SYMBOL(disable_gptimers); diff --git a/trunk/arch/blackfin/kernel/init_task.c b/trunk/arch/blackfin/kernel/init_task.c new file mode 100644 index 000000000000..d3970e8acd1a --- /dev/null +++ b/trunk/arch/blackfin/kernel/init_task.c @@ -0,0 +1,32 @@ +/* + * Copyright 2004-2009 Analog Devices Inc. + * + * Licensed under the GPL-2 or later + */ + +#include +#include +#include +#include +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); +EXPORT_SYMBOL(init_task); + +/* + * Initial thread structure. + * + * We need to make sure that this is 8192-byte aligned due to the + * way process stacks are handled. This is done by having a special + * "init_task" linker map entry. + */ +union thread_union init_thread_union + __init_task_data = { +INIT_THREAD_INFO(init_task)}; diff --git a/trunk/arch/blackfin/kernel/process.c b/trunk/arch/blackfin/kernel/process.c index 2e3994b20169..c0f4fe287eb6 100644 --- a/trunk/arch/blackfin/kernel/process.c +++ b/trunk/arch/blackfin/kernel/process.c @@ -95,9 +95,7 @@ void cpu_idle(void) idle(); rcu_idle_exit(); tick_nohz_idle_exit(); - preempt_enable_no_resched(); - schedule(); - preempt_disable(); + schedule_preempt_disabled(); } } @@ -331,16 +329,12 @@ int in_mem_const(unsigned long addr, unsigned long size, { return in_mem_const_off(addr, size, 0, const_addr, const_size); } -#ifdef CONFIG_BF60x -#define ASYNC_ENABLED(bnum, bctlnum) 1 -#else #define ASYNC_ENABLED(bnum, bctlnum) \ ({ \ (bfin_read_EBIU_AMGCTL() & 0xe) < ((bnum + 1) << 1) ? 0 : \ bfin_read_EBIU_AMBCTL##bctlnum() & B##bnum##RDYEN ? 0 : \ 1; \ }) -#endif /* * We can't read EBIU banks that aren't enabled or we end up hanging * on the access to the async space. Make sure we validate accesses diff --git a/trunk/arch/blackfin/kernel/reboot.c b/trunk/arch/blackfin/kernel/reboot.c index 5272e6eefd92..b0434f89e8de 100644 --- a/trunk/arch/blackfin/kernel/reboot.c +++ b/trunk/arch/blackfin/kernel/reboot.c @@ -22,7 +22,6 @@ __attribute__ ((__l1_text__, __noreturn__)) static void bfin_reset(void) { -#ifndef CONFIG_BF60x if (!ANOMALY_05000353 && !ANOMALY_05000386) bfrom_SoftReset((void *)(L1_SCRATCH_START + L1_SCRATCH_LENGTH - 20)); @@ -58,6 +57,7 @@ static void bfin_reset(void) if (__SILICON_REVISION__ < 1 && bfin_revid() < 1) bfin_read_SWRST(); #endif + /* Wait for the SWRST write to complete. Cannot rely on SSYNC * though as the System state is all reset now. */ @@ -72,10 +72,6 @@ static void bfin_reset(void) while (1) /* Issue core reset */ asm("raise 1"); -#else - while (1) - bfin_write_RCU0_CTL(0x1); -#endif } __attribute__((weak)) diff --git a/trunk/arch/blackfin/kernel/setup.c b/trunk/arch/blackfin/kernel/setup.c index ada8f0fc71e4..2ad747e909fb 100644 --- a/trunk/arch/blackfin/kernel/setup.c +++ b/trunk/arch/blackfin/kernel/setup.c @@ -25,16 +25,12 @@ #include #include #include -#include #include #include #include #include #include #include -#ifdef CONFIG_BF60x -#include -#endif u16 _bfin_swrst; EXPORT_SYMBOL(_bfin_swrst); @@ -554,6 +550,7 @@ static __init void memory_setup(void) { #ifdef CONFIG_MTD_UCLINUX unsigned long mtd_phys = 0; + unsigned long n; #endif unsigned long max_mem; @@ -597,9 +594,9 @@ static __init void memory_setup(void) mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 8))); # if defined(CONFIG_EXT2_FS) || defined(CONFIG_EXT3_FS) - if (*((unsigned short *)(mtd_phys + 0x438)) == EXT2_SUPER_MAGIC) - mtd_size = - PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x404)) << 10); + n = ext2_image_size((void *)(mtd_phys + 0x400)); + if (n) + mtd_size = PAGE_ALIGN(n * 1024); # endif # if defined(CONFIG_CRAMFS) @@ -615,8 +612,7 @@ static __init void memory_setup(void) /* ROM_FS is XIP, so if we found it, we need to limit memory */ if (memory_end > max_mem) { - pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", - (max_mem - CONFIG_PHY_RAM_BASE_ADDRESS) >> 20); + pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", max_mem >> 20); memory_end = max_mem; } } @@ -646,8 +642,7 @@ static __init void memory_setup(void) * doesn't exist, or we don't need to - then dont. */ if (memory_end > max_mem) { - pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", - (max_mem - CONFIG_PHY_RAM_BASE_ADDRESS) >> 20); + pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", max_mem >> 20); memory_end = max_mem; } @@ -666,8 +661,8 @@ static __init void memory_setup(void) init_mm.end_data = (unsigned long)_edata; init_mm.brk = (unsigned long)0; - printk(KERN_INFO "Board Memory: %ldMB\n", (physical_mem_end - CONFIG_PHY_RAM_BASE_ADDRESS) >> 20); - printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", (_ramend - CONFIG_PHY_RAM_BASE_ADDRESS) >> 20); + printk(KERN_INFO "Board Memory: %ldMB\n", physical_mem_end >> 20); + printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20); printk(KERN_INFO "Memory map:\n" " fixedcode = 0x%p-0x%p\n" @@ -710,7 +705,7 @@ void __init find_min_max_pfn(void) int i; max_pfn = 0; - min_low_pfn = PFN_DOWN(memory_end); + min_low_pfn = memory_end; for (i = 0; i < bfin_memmap.nr_map; i++) { unsigned long start, end; @@ -753,7 +748,8 @@ static __init void setup_bootmem_allocator(void) /* pfn of the first usable page frame after kernel image*/ if (min_low_pfn < memory_start >> PAGE_SHIFT) min_low_pfn = memory_start >> PAGE_SHIFT; - start_pfn = CONFIG_PHY_RAM_BASE_ADDRESS >> PAGE_SHIFT; + + start_pfn = PAGE_OFFSET >> PAGE_SHIFT; end_pfn = memory_end >> PAGE_SHIFT; /* @@ -798,8 +794,8 @@ static __init void setup_bootmem_allocator(void) } /* reserve memory before memory_start, including bootmap */ - reserve_bootmem(CONFIG_PHY_RAM_BASE_ADDRESS, - memory_start + bootmap_size + PAGE_SIZE - 1 - CONFIG_PHY_RAM_BASE_ADDRESS, + reserve_bootmem(PAGE_OFFSET, + memory_start + bootmap_size + PAGE_SIZE - 1 - PAGE_OFFSET, BOOTMEM_DEFAULT); } @@ -848,40 +844,13 @@ static inline int __init get_mem_size(void) break; } switch (ddrctl & 0x30000) { - case DEVWD_4: - ret *= 2; - case DEVWD_8: - ret *= 2; - case DEVWD_16: - break; + case DEVWD_4: ret *= 2; + case DEVWD_8: ret *= 2; + case DEVWD_16: break; } if ((ddrctl & 0xc000) == 0x4000) ret *= 2; return ret; -#elif defined(CONFIG_BF60x) - u32 ddrctl = bfin_read_DMC0_CFG(); - int ret; - switch (ddrctl & 0xf00) { - case DEVSZ_64: - ret = 64 / 8; - break; - case DEVSZ_128: - ret = 128 / 8; - break; - case DEVSZ_256: - ret = 256 / 8; - break; - case DEVSZ_512: - ret = 512 / 8; - break; - case DEVSZ_1G: - ret = 1024 / 8; - break; - case DEVSZ_2G: - ret = 2048 / 8; - break; - } - return ret; #endif BUG(); } @@ -891,22 +860,6 @@ void __init native_machine_early_platform_add_devices(void) { } -#ifdef CONFIG_BF60x -static inline u_long bfin_get_clk(char *name) -{ - struct clk *clk; - u_long clk_rate; - - clk = clk_get(NULL, name); - if (IS_ERR(clk)) - return 0; - - clk_rate = clk_get_rate(clk); - clk_put(clk); - return clk_rate; -} -#endif - void __init setup_arch(char **cmdline_p) { u32 mmr; @@ -917,7 +870,6 @@ void __init setup_arch(char **cmdline_p) enable_shadow_console(); /* Check to make sure we are running on the right processor */ - mmr = bfin_cpuid(); if (unlikely(CPUID != bfin_cpuid())) printk(KERN_ERR "ERROR: Not running on ADSP-%s: unknown CPUID 0x%04x Rev 0.%d\n", CPU, bfin_cpuid(), bfin_revid()); @@ -938,10 +890,6 @@ void __init setup_arch(char **cmdline_p) memset(&bfin_memmap, 0, sizeof(bfin_memmap)); -#ifdef CONFIG_BF60x - /* Should init clock device before parse command early */ - clk_init(); -#endif /* If the user does not specify things on the command line, use * what the bootloader set things up as */ @@ -956,7 +904,6 @@ void __init setup_arch(char **cmdline_p) memory_setup(); -#ifndef CONFIG_BF60x /* Initialize Async memory banks */ bfin_write_EBIU_AMBCTL0(AMBCTL0VAL); bfin_write_EBIU_AMBCTL1(AMBCTL1VAL); @@ -966,7 +913,6 @@ void __init setup_arch(char **cmdline_p) bfin_write_EBIU_MODE(CONFIG_EBIU_MODEVAL); bfin_write_EBIU_FCTL(CONFIG_EBIU_FCTLVAL); #endif -#endif #ifdef CONFIG_BFIN_HYSTERESIS_CONTROL bfin_write_PORTF_HYSTERESIS(HYST_PORTF_0_15); bfin_write_PORTG_HYSTERESIS(HYST_PORTG_0_15); @@ -992,7 +938,7 @@ void __init setup_arch(char **cmdline_p) printk(KERN_INFO "Hardware Trace %s and %sabled\n", (mmr & 0x1) ? "active" : "off", (mmr & 0x2) ? "en" : "dis"); -#ifndef CONFIG_BF60x + mmr = bfin_read_SYSCR(); printk(KERN_INFO "Boot Mode: %i\n", mmr & 0xF); @@ -1034,7 +980,7 @@ void __init setup_arch(char **cmdline_p) printk(KERN_INFO "Recovering from Watchdog event\n"); else if (_bfin_swrst & RESET_SOFTWARE) printk(KERN_NOTICE "Reset caused by Software reset\n"); -#endif + printk(KERN_INFO "Blackfin support (C) 2004-2010 Analog Devices, Inc.\n"); if (bfin_compiled_revid() == 0xffff) printk(KERN_INFO "Compiled for ADSP-%s Rev any, running on 0.%d\n", CPU, bfin_revid()); @@ -1062,13 +1008,8 @@ void __init setup_arch(char **cmdline_p) printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n"); -#ifdef CONFIG_BF60x - printk(KERN_INFO "Processor Speed: %lu MHz core clock, %lu MHz SCLk, %lu MHz SCLK0, %lu MHz SCLK1 and %lu MHz DCLK\n", - cclk / 1000000, bfin_get_clk("SYSCLK") / 1000000, get_sclk0() / 1000000, get_sclk1() / 1000000, get_dclk() / 1000000); -#else printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu MHz System Clock\n", cclk / 1000000, sclk / 1000000); -#endif setup_bootmem_allocator(); @@ -1119,12 +1060,10 @@ subsys_initcall(topology_init); /* Get the input clock frequency */ static u_long cached_clkin_hz = CONFIG_CLKIN_HZ; -#ifndef CONFIG_BF60x static u_long get_clkin_hz(void) { return cached_clkin_hz; } -#endif static int __init early_init_clkin_hz(char *buf) { cached_clkin_hz = simple_strtoul(buf, NULL, 0); @@ -1136,7 +1075,6 @@ static int __init early_init_clkin_hz(char *buf) } early_param("clkin_hz=", early_init_clkin_hz); -#ifndef CONFIG_BF60x /* Get the voltage input multiplier */ static u_long get_vco(void) { @@ -1159,14 +1097,10 @@ static u_long get_vco(void) cached_vco *= msel; return cached_vco; } -#endif /* Get the Core clock */ u_long get_cclk(void) { -#ifdef CONFIG_BF60x - return bfin_get_clk("CCLK"); -#else static u_long cached_cclk_pll_div, cached_cclk; u_long csel, ssel; @@ -1186,39 +1120,12 @@ u_long get_cclk(void) else cached_cclk = get_vco() >> csel; return cached_cclk; -#endif } EXPORT_SYMBOL(get_cclk); -#ifdef CONFIG_BF60x -/* Get the bf60x clock of SCLK0 domain */ -u_long get_sclk0(void) -{ - return bfin_get_clk("SCLK0"); -} -EXPORT_SYMBOL(get_sclk0); - -/* Get the bf60x clock of SCLK1 domain */ -u_long get_sclk1(void) -{ - return bfin_get_clk("SCLK1"); -} -EXPORT_SYMBOL(get_sclk1); - -/* Get the bf60x DRAM clock */ -u_long get_dclk(void) -{ - return bfin_get_clk("DCLK"); -} -EXPORT_SYMBOL(get_dclk); -#endif - -/* Get the default system clock */ +/* Get the System clock */ u_long get_sclk(void) { -#ifdef CONFIG_BF60x - return get_sclk0(); -#else static u_long cached_sclk; u_long ssel; @@ -1239,7 +1146,6 @@ u_long get_sclk(void) cached_sclk = get_vco() / ssel; return cached_sclk; -#endif } EXPORT_SYMBOL(get_sclk); diff --git a/trunk/arch/blackfin/kernel/shadow_console.c b/trunk/arch/blackfin/kernel/shadow_console.c index aeb8343eeb03..557e9fef406a 100644 --- a/trunk/arch/blackfin/kernel/shadow_console.c +++ b/trunk/arch/blackfin/kernel/shadow_console.c @@ -15,9 +15,9 @@ #include #include -#define SHADOW_CONSOLE_START (CONFIG_PHY_RAM_BASE_ADDRESS + 0x500) -#define SHADOW_CONSOLE_END (CONFIG_PHY_RAM_BASE_ADDRESS + 0x1000) -#define SHADOW_CONSOLE_MAGIC_LOC (CONFIG_PHY_RAM_BASE_ADDRESS + 0x4F0) +#define SHADOW_CONSOLE_START (0x500) +#define SHADOW_CONSOLE_END (0x1000) +#define SHADOW_CONSOLE_MAGIC_LOC (0x4F0) #define SHADOW_CONSOLE_MAGIC (0xDEADBEEF) static __initdata char *shadow_console_buffer = (char *)SHADOW_CONSOLE_START; diff --git a/trunk/arch/blackfin/kernel/time-ts.c b/trunk/arch/blackfin/kernel/time-ts.c index f608f02f29a3..d98f2d69b0c4 100644 --- a/trunk/arch/blackfin/kernel/time-ts.c +++ b/trunk/arch/blackfin/kernel/time-ts.c @@ -66,14 +66,8 @@ void __init setup_gptimer0(void) { disable_gptimers(TIMER0bit); -#ifdef CONFIG_BF60x - bfin_write16(TIMER_DATA_IMSK, 0); - set_gptimer_config(TIMER0_id, TIMER_OUT_DIS - | TIMER_MODE_PWM_CONT | TIMER_PULSE_HI | TIMER_IRQ_PER); -#else set_gptimer_config(TIMER0_id, \ TIMER_OUT_DIS | TIMER_PERIOD_CNT | TIMER_MODE_PWM); -#endif set_gptimer_period(TIMER0_id, -1); set_gptimer_pwidth(TIMER0_id, -2); SSYNC(); @@ -141,15 +135,9 @@ static void bfin_gptmr0_set_mode(enum clock_event_mode mode, { switch (mode) { case CLOCK_EVT_MODE_PERIODIC: { -#ifndef CONFIG_BF60x set_gptimer_config(TIMER0_id, \ TIMER_OUT_DIS | TIMER_IRQ_ENA | \ TIMER_PERIOD_CNT | TIMER_MODE_PWM); -#else - set_gptimer_config(TIMER0_id, TIMER_OUT_DIS - | TIMER_MODE_PWM_CONT | TIMER_PULSE_HI | TIMER_IRQ_PER); -#endif - set_gptimer_period(TIMER0_id, get_sclk() / HZ); set_gptimer_pwidth(TIMER0_id, get_sclk() / HZ - 1); enable_gptimers(TIMER0bit); @@ -157,14 +145,8 @@ static void bfin_gptmr0_set_mode(enum clock_event_mode mode, } case CLOCK_EVT_MODE_ONESHOT: disable_gptimers(TIMER0bit); -#ifndef CONFIG_BF60x set_gptimer_config(TIMER0_id, \ TIMER_OUT_DIS | TIMER_IRQ_ENA | TIMER_MODE_PWM); -#else - set_gptimer_config(TIMER0_id, TIMER_OUT_DIS | TIMER_MODE_PWM - | TIMER_PULSE_HI | TIMER_IRQ_WID_DLY); -#endif - set_gptimer_period(TIMER0_id, 0); break; case CLOCK_EVT_MODE_UNUSED: @@ -178,7 +160,7 @@ static void bfin_gptmr0_set_mode(enum clock_event_mode mode, static void bfin_gptmr0_ack(void) { - clear_gptimer_intr(TIMER0_id); + set_gptimer_status(TIMER_GROUP1, TIMER_STATUS_TIMIL0); } static void __init bfin_gptmr0_init(void) @@ -215,7 +197,7 @@ static struct clock_event_device clockevent_gptmr0 = { .rating = 300, .irq = IRQ_TIMER0, .shift = 32, - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, .set_next_event = bfin_gptmr0_set_next_event, .set_mode = bfin_gptmr0_set_mode, }; @@ -325,11 +307,6 @@ void bfin_coretmr_clockevent_init(void) unsigned int cpu = smp_processor_id(); struct clock_event_device *evt = &per_cpu(coretmr_events, cpu); -#ifdef CONFIG_SMP - evt->broadcast = smp_timer_broadcast; -#endif - - #ifdef CONFIG_SMP evt->broadcast = smp_timer_broadcast; #endif diff --git a/trunk/arch/blackfin/lib/divsi3.S b/trunk/arch/blackfin/lib/divsi3.S index ef2cd99efb89..f89c5a49c47b 100644 --- a/trunk/arch/blackfin/lib/divsi3.S +++ b/trunk/arch/blackfin/lib/divsi3.S @@ -1,7 +1,7 @@ /* * Copyright 2004-2009 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) * * 16 / 32 bit signed division. * Special cases : diff --git a/trunk/arch/blackfin/lib/memchr.S b/trunk/arch/blackfin/lib/memchr.S index bcfc8a14c3f2..542e40f8775f 100644 --- a/trunk/arch/blackfin/lib/memchr.S +++ b/trunk/arch/blackfin/lib/memchr.S @@ -1,7 +1,7 @@ /* * Copyright 2005-2009 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #include diff --git a/trunk/arch/blackfin/lib/memcmp.S b/trunk/arch/blackfin/lib/memcmp.S index 2e1c9477f2f7..ce5b9f1a8267 100644 --- a/trunk/arch/blackfin/lib/memcmp.S +++ b/trunk/arch/blackfin/lib/memcmp.S @@ -1,7 +1,7 @@ /* * Copyright 2004-2009 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #include diff --git a/trunk/arch/blackfin/lib/memcpy.S b/trunk/arch/blackfin/lib/memcpy.S index 53cb3698ab33..c31bf22aab19 100644 --- a/trunk/arch/blackfin/lib/memcpy.S +++ b/trunk/arch/blackfin/lib/memcpy.S @@ -7,7 +7,7 @@ * * Copyright 2004-2009 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #include diff --git a/trunk/arch/blackfin/lib/memmove.S b/trunk/arch/blackfin/lib/memmove.S index e0b78208f1d6..4eca566237a4 100644 --- a/trunk/arch/blackfin/lib/memmove.S +++ b/trunk/arch/blackfin/lib/memmove.S @@ -1,7 +1,7 @@ /* * Copyright 2005-2009 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #include diff --git a/trunk/arch/blackfin/lib/memset.S b/trunk/arch/blackfin/lib/memset.S index cdcf9148ea20..eab1bef3f5bf 100644 --- a/trunk/arch/blackfin/lib/memset.S +++ b/trunk/arch/blackfin/lib/memset.S @@ -1,7 +1,7 @@ /* * Copyright 2004-2009 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #include diff --git a/trunk/arch/blackfin/lib/modsi3.S b/trunk/arch/blackfin/lib/modsi3.S index f7026ce1fa0e..8b0c7d4052af 100644 --- a/trunk/arch/blackfin/lib/modsi3.S +++ b/trunk/arch/blackfin/lib/modsi3.S @@ -6,7 +6,7 @@ * * Copyright 2004-2009 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ .global ___modsi3; diff --git a/trunk/arch/blackfin/lib/muldi3.S b/trunk/arch/blackfin/lib/muldi3.S index abf9b2a515b2..953a38a1d1d1 100644 --- a/trunk/arch/blackfin/lib/muldi3.S +++ b/trunk/arch/blackfin/lib/muldi3.S @@ -1,7 +1,7 @@ /* * Copyright 2008 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ .align 2 diff --git a/trunk/arch/blackfin/lib/smulsi3_highpart.S b/trunk/arch/blackfin/lib/smulsi3_highpart.S index e50d6c4ac2a5..99ee8c5de38b 100644 --- a/trunk/arch/blackfin/lib/smulsi3_highpart.S +++ b/trunk/arch/blackfin/lib/smulsi3_highpart.S @@ -1,7 +1,7 @@ /* * Copyright 2007 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ .align 2 diff --git a/trunk/arch/blackfin/lib/strcmp.S b/trunk/arch/blackfin/lib/strcmp.S index 9c8b9863713e..d7c1d158973b 100644 --- a/trunk/arch/blackfin/lib/strcmp.S +++ b/trunk/arch/blackfin/lib/strcmp.S @@ -1,7 +1,7 @@ /* * Copyright 2005-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #include diff --git a/trunk/arch/blackfin/lib/strcpy.S b/trunk/arch/blackfin/lib/strcpy.S index 9495aa77cc40..a6a0c6363806 100644 --- a/trunk/arch/blackfin/lib/strcpy.S +++ b/trunk/arch/blackfin/lib/strcpy.S @@ -1,7 +1,7 @@ /* * Copyright 2005-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #include diff --git a/trunk/arch/blackfin/lib/strncmp.S b/trunk/arch/blackfin/lib/strncmp.S index 3bfaedce893e..6da37c34a847 100644 --- a/trunk/arch/blackfin/lib/strncmp.S +++ b/trunk/arch/blackfin/lib/strncmp.S @@ -1,7 +1,7 @@ /* * Copyright 2005-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #include diff --git a/trunk/arch/blackfin/lib/strncpy.S b/trunk/arch/blackfin/lib/strncpy.S index 92fd1823bbee..2c07dddac995 100644 --- a/trunk/arch/blackfin/lib/strncpy.S +++ b/trunk/arch/blackfin/lib/strncpy.S @@ -1,7 +1,7 @@ /* * Copyright 2005-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #include diff --git a/trunk/arch/blackfin/lib/udivsi3.S b/trunk/arch/blackfin/lib/udivsi3.S index 748a6a2e8c17..97e904315ec6 100644 --- a/trunk/arch/blackfin/lib/udivsi3.S +++ b/trunk/arch/blackfin/lib/udivsi3.S @@ -1,7 +1,7 @@ /* * Copyright 2004-2009 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #include diff --git a/trunk/arch/blackfin/lib/umodsi3.S b/trunk/arch/blackfin/lib/umodsi3.S index 3794c00d859d..168eba7c64c8 100644 --- a/trunk/arch/blackfin/lib/umodsi3.S +++ b/trunk/arch/blackfin/lib/umodsi3.S @@ -3,7 +3,7 @@ * * Copyright 2004-2009 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifdef CONFIG_ARITHMETIC_OPS_L1 diff --git a/trunk/arch/blackfin/lib/umulsi3_highpart.S b/trunk/arch/blackfin/lib/umulsi3_highpart.S index 0dcace96e4e7..051824a6ed00 100644 --- a/trunk/arch/blackfin/lib/umulsi3_highpart.S +++ b/trunk/arch/blackfin/lib/umulsi3_highpart.S @@ -1,7 +1,7 @@ /* * Copyright 2007 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ .align 2 diff --git a/trunk/arch/blackfin/mach-bf518/boards/ezbrd.c b/trunk/arch/blackfin/mach-bf518/boards/ezbrd.c index f8047ca3b339..a17395727efa 100644 --- a/trunk/arch/blackfin/mach-bf518/boards/ezbrd.c +++ b/trunk/arch/blackfin/mach-bf518/boards/ezbrd.c @@ -529,8 +529,6 @@ static struct platform_device bfin_i2s = { #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) -static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; - static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -549,9 +547,6 @@ static struct platform_device i2c_bfin_twi_device = { .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, - .dev = { - .platform_data = &bfin_twi0_pins, - }, }; #endif diff --git a/trunk/arch/blackfin/mach-bf518/boards/tcm-bf518.c b/trunk/arch/blackfin/mach-bf518/boards/tcm-bf518.c index 0bedc737566b..6eebee4e4217 100644 --- a/trunk/arch/blackfin/mach-bf518/boards/tcm-bf518.c +++ b/trunk/arch/blackfin/mach-bf518/boards/tcm-bf518.c @@ -455,8 +455,6 @@ static struct platform_device bfin_sir1_device = { #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) -static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; - static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -475,9 +473,6 @@ static struct platform_device i2c_bfin_twi_device = { .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, - .dev = { - .platform_data = &bfin_twi0_pins, - }, }; #endif diff --git a/trunk/arch/blackfin/mach-bf518/include/mach/anomaly.h b/trunk/arch/blackfin/mach-bf518/include/mach/anomaly.h index 845e6bc8d633..56383f7cbc07 100644 --- a/trunk/arch/blackfin/mach-bf518/include/mach/anomaly.h +++ b/trunk/arch/blackfin/mach-bf518/include/mach/anomaly.h @@ -6,7 +6,8 @@ * DO NOT EDIT THIS FILE * * Copyright 2004-2011 Analog Devices Inc. - * Licensed under the Clear BSD license. + * Licensed under the ADI BSD license. + * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd */ /* This file should be up to date with: diff --git a/trunk/arch/blackfin/mach-bf518/include/mach/cdefBF512.h b/trunk/arch/blackfin/mach-bf518/include/mach/cdefBF512.h index 1c03ad4bcb72..bb79627f0929 100644 --- a/trunk/arch/blackfin/mach-bf518/include/mach/cdefBF512.h +++ b/trunk/arch/blackfin/mach-bf518/include/mach/cdefBF512.h @@ -1,7 +1,7 @@ /* * Copyright 2008-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _CDEF_BF512_H diff --git a/trunk/arch/blackfin/mach-bf518/include/mach/cdefBF514.h b/trunk/arch/blackfin/mach-bf518/include/mach/cdefBF514.h index 861221d1dcc9..dc988668203e 100644 --- a/trunk/arch/blackfin/mach-bf518/include/mach/cdefBF514.h +++ b/trunk/arch/blackfin/mach-bf518/include/mach/cdefBF514.h @@ -1,7 +1,7 @@ /* * Copyright 2008-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _CDEF_BF514_H diff --git a/trunk/arch/blackfin/mach-bf518/include/mach/cdefBF516.h b/trunk/arch/blackfin/mach-bf518/include/mach/cdefBF516.h index cc9bf0d378c3..142e45cbc253 100644 --- a/trunk/arch/blackfin/mach-bf518/include/mach/cdefBF516.h +++ b/trunk/arch/blackfin/mach-bf518/include/mach/cdefBF516.h @@ -1,7 +1,7 @@ /* * Copyright 2008-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _CDEF_BF516_H diff --git a/trunk/arch/blackfin/mach-bf518/include/mach/cdefBF518.h b/trunk/arch/blackfin/mach-bf518/include/mach/cdefBF518.h index 96a82fd62ef1..e638197bf8b1 100644 --- a/trunk/arch/blackfin/mach-bf518/include/mach/cdefBF518.h +++ b/trunk/arch/blackfin/mach-bf518/include/mach/cdefBF518.h @@ -1,7 +1,7 @@ /* * Copyright 2008-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _CDEF_BF518_H diff --git a/trunk/arch/blackfin/mach-bf518/include/mach/defBF512.h b/trunk/arch/blackfin/mach-bf518/include/mach/defBF512.h index e6a017faad01..729704078cd7 100644 --- a/trunk/arch/blackfin/mach-bf518/include/mach/defBF512.h +++ b/trunk/arch/blackfin/mach-bf518/include/mach/defBF512.h @@ -1,7 +1,7 @@ /* * Copyright 2008-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF512_H @@ -1083,6 +1083,77 @@ #define ERR_NCOR 0x8000 /* Error Not Corrected Indicator */ +/* ******************** TWO-WIRE INTERFACE (TWI) MASKS ***********************/ +/* TWI_CLKDIV Macros (Use: *pTWI_CLKDIV = CLKLOW(x)|CLKHI(y); ) */ +#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */ +#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */ + +/* TWI_PRESCALE Masks */ +#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */ +#define TWI_ENA 0x0080 /* TWI Enable */ +#define SCCB 0x0200 /* SCCB Compatibility Enable */ + +/* TWI_SLAVE_CTL Masks */ +#define SEN 0x0001 /* Slave Enable */ +#define SADD_LEN 0x0002 /* Slave Address Length */ +#define STDVAL 0x0004 /* Slave Transmit Data Valid */ +#define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */ +#define GEN 0x0010 /* General Call Adrress Matching Enabled */ + +/* TWI_SLAVE_STAT Masks */ +#define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */ +#define GCALL 0x0002 /* General Call Indicator */ + +/* TWI_MASTER_CTL Masks */ +#define MEN 0x0001 /* Master Mode Enable */ +#define MADD_LEN 0x0002 /* Master Address Length */ +#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */ +#define FAST 0x0008 /* Use Fast Mode Timing Specs */ +#define STOP 0x0010 /* Issue Stop Condition */ +#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */ +#define DCNT 0x3FC0 /* Data Bytes To Transfer */ +#define SDAOVR 0x4000 /* Serial Data Override */ +#define SCLOVR 0x8000 /* Serial Clock Override */ + +/* TWI_MASTER_STAT Masks */ +#define MPROG 0x0001 /* Master Transfer In Progress */ +#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */ +#define ANAK 0x0004 /* Address Not Acknowledged */ +#define DNAK 0x0008 /* Data Not Acknowledged */ +#define BUFRDERR 0x0010 /* Buffer Read Error */ +#define BUFWRERR 0x0020 /* Buffer Write Error */ +#define SDASEN 0x0040 /* Serial Data Sense */ +#define SCLSEN 0x0080 /* Serial Clock Sense */ +#define BUSBUSY 0x0100 /* Bus Busy Indicator */ + +/* TWI_INT_SRC and TWI_INT_ENABLE Masks */ +#define SINIT 0x0001 /* Slave Transfer Initiated */ +#define SCOMP 0x0002 /* Slave Transfer Complete */ +#define SERR 0x0004 /* Slave Transfer Error */ +#define SOVF 0x0008 /* Slave Overflow */ +#define MCOMP 0x0010 /* Master Transfer Complete */ +#define MERR 0x0020 /* Master Transfer Error */ +#define XMTSERV 0x0040 /* Transmit FIFO Service */ +#define RCVSERV 0x0080 /* Receive FIFO Service */ + +/* TWI_FIFO_CTRL Masks */ +#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */ +#define RCVFLUSH 0x0002 /* Receive Buffer Flush */ +#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */ +#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */ + +/* TWI_FIFO_STAT Masks */ +#define XMTSTAT 0x0003 /* Transmit FIFO Status */ +#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */ +#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */ +#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */ + +#define RCVSTAT 0x000C /* Receive FIFO Status */ +#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */ +#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */ +#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */ + + /* ******************* PIN CONTROL REGISTER MASKS ************************/ /* PORT_MUX Masks */ #define PJSE 0x0001 /* Port J SPI/SPORT Enable */ diff --git a/trunk/arch/blackfin/mach-bf518/include/mach/defBF514.h b/trunk/arch/blackfin/mach-bf518/include/mach/defBF514.h index 97feaa629ed7..cfab428e577c 100644 --- a/trunk/arch/blackfin/mach-bf518/include/mach/defBF514.h +++ b/trunk/arch/blackfin/mach-bf518/include/mach/defBF514.h @@ -1,7 +1,7 @@ /* * Copyright 2008-2009 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF514_H diff --git a/trunk/arch/blackfin/mach-bf518/include/mach/defBF516.h b/trunk/arch/blackfin/mach-bf518/include/mach/defBF516.h index 7c79cb6a03b1..22a3aa0d2629 100644 --- a/trunk/arch/blackfin/mach-bf518/include/mach/defBF516.h +++ b/trunk/arch/blackfin/mach-bf518/include/mach/defBF516.h @@ -1,7 +1,7 @@ /* * Copyright 2008-2009 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF516_H diff --git a/trunk/arch/blackfin/mach-bf518/include/mach/defBF518.h b/trunk/arch/blackfin/mach-bf518/include/mach/defBF518.h index 12042ff13601..cb18270e55c2 100644 --- a/trunk/arch/blackfin/mach-bf518/include/mach/defBF518.h +++ b/trunk/arch/blackfin/mach-bf518/include/mach/defBF518.h @@ -1,7 +1,7 @@ /* * Copyright 2008-2009 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF518_H diff --git a/trunk/arch/blackfin/mach-bf527/boards/ad7160eval.c b/trunk/arch/blackfin/mach-bf527/boards/ad7160eval.c index d58f50e5aa4b..fad7fea1b0bf 100644 --- a/trunk/arch/blackfin/mach-bf527/boards/ad7160eval.c +++ b/trunk/arch/blackfin/mach-bf527/boards/ad7160eval.c @@ -569,8 +569,6 @@ static const struct ad7160_platform_data bfin_ad7160_ts_info = { #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) -static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; - static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -589,9 +587,6 @@ static struct platform_device i2c_bfin_twi_device = { .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, - .dev = { - .platform_data = &bfin_twi0_pins, - }, }; #endif @@ -686,7 +681,6 @@ static struct bfin_rotary_platform_data bfin_rotary_data = { .rotary_button_key = KEY_ENTER, .debounce = 10, /* 0..17 */ .mode = ROT_QUAD_ENC | ROT_DEBE, - .pm_wakeup = 1, }; static struct resource bfin_rotary_resources[] = { diff --git a/trunk/arch/blackfin/mach-bf527/boards/cm_bf527.c b/trunk/arch/blackfin/mach-bf527/boards/cm_bf527.c index 413d0132b66f..65b7fbd30e16 100644 --- a/trunk/arch/blackfin/mach-bf527/boards/cm_bf527.c +++ b/trunk/arch/blackfin/mach-bf527/boards/cm_bf527.c @@ -698,8 +698,6 @@ static struct platform_device bfin_sir1_device = { #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) -static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; - static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -718,9 +716,6 @@ static struct platform_device i2c_bfin_twi_device = { .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, - .dev = { - .platform_data = &bfin_twi0_pins, - }, }; #endif diff --git a/trunk/arch/blackfin/mach-bf527/boards/ezbrd.c b/trunk/arch/blackfin/mach-bf527/boards/ezbrd.c index 50bda79194e5..17c6a24cc076 100644 --- a/trunk/arch/blackfin/mach-bf527/boards/ezbrd.c +++ b/trunk/arch/blackfin/mach-bf527/boards/ezbrd.c @@ -576,8 +576,6 @@ static struct platform_device bfin_sir1_device = { #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) -static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; - static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -596,9 +594,6 @@ static struct platform_device i2c_bfin_twi_device = { .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, - .dev = { - .platform_data = &bfin_twi0_pins, - }, }; #endif diff --git a/trunk/arch/blackfin/mach-bf527/boards/ezkit.c b/trunk/arch/blackfin/mach-bf527/boards/ezkit.c index af732eb3a687..2f9a2bd83ce4 100644 --- a/trunk/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/trunk/arch/blackfin/mach-bf527/boards/ezkit.c @@ -869,8 +869,6 @@ static struct platform_device bfin_sir1_device = { #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) -static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; - static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -889,9 +887,6 @@ static struct platform_device i2c_bfin_twi_device = { .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, - .dev = { - .platform_data = &bfin_twi0_pins, - }, }; #endif @@ -1110,7 +1105,6 @@ static struct bfin_rotary_platform_data bfin_rotary_data = { .rotary_button_key = KEY_ENTER, .debounce = 10, /* 0..17 */ .mode = ROT_QUAD_ENC | ROT_DEBE, - .pm_wakeup = 1, }; static struct resource bfin_rotary_resources[] = { diff --git a/trunk/arch/blackfin/mach-bf527/boards/tll6527m.c b/trunk/arch/blackfin/mach-bf527/boards/tll6527m.c index 1509c5a8a3ff..d192c0ac941c 100644 --- a/trunk/arch/blackfin/mach-bf527/boards/tll6527m.c +++ b/trunk/arch/blackfin/mach-bf527/boards/tll6527m.c @@ -656,8 +656,6 @@ static struct platform_device bfin_sir1_device = { #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) -static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; - static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -676,9 +674,6 @@ static struct platform_device i2c_bfin_twi_device = { .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, - .dev = { - .platform_data = &bfin_twi0_pins, - }, }; #endif diff --git a/trunk/arch/blackfin/mach-bf527/include/mach/anomaly.h b/trunk/arch/blackfin/mach-bf527/include/mach/anomaly.h index aa14110be4c4..688470611e15 100644 --- a/trunk/arch/blackfin/mach-bf527/include/mach/anomaly.h +++ b/trunk/arch/blackfin/mach-bf527/include/mach/anomaly.h @@ -6,7 +6,8 @@ * DO NOT EDIT THIS FILE * * Copyright 2004-2011 Analog Devices Inc. - * Licensed under the Clear BSD license. + * Licensed under the ADI BSD license. + * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd */ /* This file should be up to date with: diff --git a/trunk/arch/blackfin/mach-bf527/include/mach/defBF522.h b/trunk/arch/blackfin/mach-bf527/include/mach/defBF522.h index e007017cf958..37d353a19722 100644 --- a/trunk/arch/blackfin/mach-bf527/include/mach/defBF522.h +++ b/trunk/arch/blackfin/mach-bf527/include/mach/defBF522.h @@ -1,7 +1,7 @@ /* * Copyright 2007-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF522_H @@ -1084,6 +1084,77 @@ #define ERR_NCOR 0x8000 /* Error Not Corrected Indicator */ +/* ******************** TWO-WIRE INTERFACE (TWI) MASKS ***********************/ +/* TWI_CLKDIV Macros (Use: *pTWI_CLKDIV = CLKLOW(x)|CLKHI(y); ) */ +#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */ +#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */ + +/* TWI_PRESCALE Masks */ +#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */ +#define TWI_ENA 0x0080 /* TWI Enable */ +#define SCCB 0x0200 /* SCCB Compatibility Enable */ + +/* TWI_SLAVE_CTL Masks */ +#define SEN 0x0001 /* Slave Enable */ +#define SADD_LEN 0x0002 /* Slave Address Length */ +#define STDVAL 0x0004 /* Slave Transmit Data Valid */ +#define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */ +#define GEN 0x0010 /* General Call Adrress Matching Enabled */ + +/* TWI_SLAVE_STAT Masks */ +#define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */ +#define GCALL 0x0002 /* General Call Indicator */ + +/* TWI_MASTER_CTL Masks */ +#define MEN 0x0001 /* Master Mode Enable */ +#define MADD_LEN 0x0002 /* Master Address Length */ +#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */ +#define FAST 0x0008 /* Use Fast Mode Timing Specs */ +#define STOP 0x0010 /* Issue Stop Condition */ +#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */ +#define DCNT 0x3FC0 /* Data Bytes To Transfer */ +#define SDAOVR 0x4000 /* Serial Data Override */ +#define SCLOVR 0x8000 /* Serial Clock Override */ + +/* TWI_MASTER_STAT Masks */ +#define MPROG 0x0001 /* Master Transfer In Progress */ +#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */ +#define ANAK 0x0004 /* Address Not Acknowledged */ +#define DNAK 0x0008 /* Data Not Acknowledged */ +#define BUFRDERR 0x0010 /* Buffer Read Error */ +#define BUFWRERR 0x0020 /* Buffer Write Error */ +#define SDASEN 0x0040 /* Serial Data Sense */ +#define SCLSEN 0x0080 /* Serial Clock Sense */ +#define BUSBUSY 0x0100 /* Bus Busy Indicator */ + +/* TWI_INT_SRC and TWI_INT_ENABLE Masks */ +#define SINIT 0x0001 /* Slave Transfer Initiated */ +#define SCOMP 0x0002 /* Slave Transfer Complete */ +#define SERR 0x0004 /* Slave Transfer Error */ +#define SOVF 0x0008 /* Slave Overflow */ +#define MCOMP 0x0010 /* Master Transfer Complete */ +#define MERR 0x0020 /* Master Transfer Error */ +#define XMTSERV 0x0040 /* Transmit FIFO Service */ +#define RCVSERV 0x0080 /* Receive FIFO Service */ + +/* TWI_FIFO_CTRL Masks */ +#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */ +#define RCVFLUSH 0x0002 /* Receive Buffer Flush */ +#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */ +#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */ + +/* TWI_FIFO_STAT Masks */ +#define XMTSTAT 0x0003 /* Transmit FIFO Status */ +#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */ +#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */ +#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */ + +#define RCVSTAT 0x000C /* Receive FIFO Status */ +#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */ +#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */ +#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */ + + /* Omit CAN masks from defBF534.h */ /* ******************* PIN CONTROL REGISTER MASKS ************************/ diff --git a/trunk/arch/blackfin/mach-bf527/include/mach/defBF525.h b/trunk/arch/blackfin/mach-bf527/include/mach/defBF525.h index 71578d964d00..aab80bb1a683 100644 --- a/trunk/arch/blackfin/mach-bf527/include/mach/defBF525.h +++ b/trunk/arch/blackfin/mach-bf527/include/mach/defBF525.h @@ -1,7 +1,7 @@ /* * Copyright 2007-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF525_H diff --git a/trunk/arch/blackfin/mach-bf527/include/mach/defBF527.h b/trunk/arch/blackfin/mach-bf527/include/mach/defBF527.h index aeb84795b35e..05369a92fbc8 100644 --- a/trunk/arch/blackfin/mach-bf527/include/mach/defBF527.h +++ b/trunk/arch/blackfin/mach-bf527/include/mach/defBF527.h @@ -1,7 +1,7 @@ /* * Copyright 2007-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF527_H diff --git a/trunk/arch/blackfin/mach-bf533/include/mach/anomaly.h b/trunk/arch/blackfin/mach-bf533/include/mach/anomaly.h index 3a8f73a669f0..03f2b40912a3 100644 --- a/trunk/arch/blackfin/mach-bf533/include/mach/anomaly.h +++ b/trunk/arch/blackfin/mach-bf533/include/mach/anomaly.h @@ -6,7 +6,8 @@ * DO NOT EDIT THIS FILE * * Copyright 2004-2011 Analog Devices Inc. - * Licensed under the Clear BSD license. + * Licensed under the ADI BSD license. + * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd */ /* This file should be up to date with: diff --git a/trunk/arch/blackfin/mach-bf533/include/mach/defBF532.h b/trunk/arch/blackfin/mach-bf533/include/mach/defBF532.h index d438150b1025..2376d5393511 100644 --- a/trunk/arch/blackfin/mach-bf533/include/mach/defBF532.h +++ b/trunk/arch/blackfin/mach-bf533/include/mach/defBF532.h @@ -3,7 +3,7 @@ * * Copyright 2005-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF532_H diff --git a/trunk/arch/blackfin/mach-bf537/boards/cm_bf537e.c b/trunk/arch/blackfin/mach-bf537/boards/cm_bf537e.c index 9408ab56d87f..27fd2c32ae9a 100644 --- a/trunk/arch/blackfin/mach-bf537/boards/cm_bf537e.c +++ b/trunk/arch/blackfin/mach-bf537/boards/cm_bf537e.c @@ -486,8 +486,6 @@ static struct platform_device bfin_sir1_device = { #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) -static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; - static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -506,9 +504,6 @@ static struct platform_device i2c_bfin_twi_device = { .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, - .dev = { - .platform_data = &bfin_twi0_pins, - }, }; #endif diff --git a/trunk/arch/blackfin/mach-bf537/boards/cm_bf537u.c b/trunk/arch/blackfin/mach-bf537/boards/cm_bf537u.c index 0143d8bef909..3f3abad86ec3 100644 --- a/trunk/arch/blackfin/mach-bf537/boards/cm_bf537u.c +++ b/trunk/arch/blackfin/mach-bf537/boards/cm_bf537u.c @@ -451,8 +451,6 @@ static struct platform_device bfin_sir1_device = { #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) -static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; - static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -471,9 +469,6 @@ static struct platform_device i2c_bfin_twi_device = { .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, - .dev = { - .platform_data = &bfin_twi0_pins, - }, }; #endif diff --git a/trunk/arch/blackfin/mach-bf537/boards/dnp5370.c b/trunk/arch/blackfin/mach-bf537/boards/dnp5370.c index 8bbf0a23fd49..6f77bf708ec0 100644 --- a/trunk/arch/blackfin/mach-bf537/boards/dnp5370.c +++ b/trunk/arch/blackfin/mach-bf537/boards/dnp5370.c @@ -329,8 +329,6 @@ static struct platform_device bfin_uart1_device = { #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) -static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; - static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -349,9 +347,6 @@ static struct platform_device i2c_bfin_twi_device = { .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, - .dev = { - .platform_data = &bfin_twi0_pins, - }, }; #endif diff --git a/trunk/arch/blackfin/mach-bf537/boards/minotaur.c b/trunk/arch/blackfin/mach-bf537/boards/minotaur.c index a10f90e444bc..d2d71282618f 100644 --- a/trunk/arch/blackfin/mach-bf537/boards/minotaur.c +++ b/trunk/arch/blackfin/mach-bf537/boards/minotaur.c @@ -386,8 +386,6 @@ static struct platform_device bfin_sir1_device = { #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) -static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; - static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -406,9 +404,6 @@ static struct platform_device i2c_bfin_twi_device = { .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, - .dev = { - .platform_data = &bfin_twi0_pins, - }, }; #endif diff --git a/trunk/arch/blackfin/mach-bf537/boards/stamp.c b/trunk/arch/blackfin/mach-bf537/boards/stamp.c index c9d9473a5ab2..f3562b0922af 100644 --- a/trunk/arch/blackfin/mach-bf537/boards/stamp.c +++ b/trunk/arch/blackfin/mach-bf537/boards/stamp.c @@ -1790,8 +1790,6 @@ static struct platform_device bfin_sir1_device = { #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) -static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; - static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -1810,9 +1808,6 @@ static struct platform_device i2c_bfin_twi_device = { .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, - .dev = { - .platform_data = &bfin_twi0_pins, - }, }; #endif @@ -2366,13 +2361,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { }, #endif }; -#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) \ -|| defined(CONFIG_BFIN_SPORT) || defined(CONFIG_BFIN_SPORT_MODULE) -unsigned short bfin_sport0_peripherals[] = { - P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, - P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0 -}; -#endif + #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) #ifdef CONFIG_SERIAL_BFIN_SPORT0_UART static struct resource bfin_sport0_uart_resources[] = { @@ -2393,6 +2382,11 @@ static struct resource bfin_sport0_uart_resources[] = { }, }; +static unsigned short bfin_sport0_peripherals[] = { + P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0 +}; + static struct platform_device bfin_sport0_uart_device = { .name = "bfin-sport-uart", .id = 0, @@ -2438,49 +2432,7 @@ static struct platform_device bfin_sport1_uart_device = { }; #endif #endif -#if defined(CONFIG_BFIN_SPORT) || defined(CONFIG_BFIN_SPORT_MODULE) -static struct resource bfin_sport0_resources[] = { - { - .start = SPORT0_TCR1, - .end = SPORT0_MRCS3+4, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_SPORT0_RX, - .end = IRQ_SPORT0_RX+1, - .flags = IORESOURCE_IRQ, - }, - { - .start = IRQ_SPORT0_TX, - .end = IRQ_SPORT0_TX+1, - .flags = IORESOURCE_IRQ, - }, - { - .start = IRQ_SPORT0_ERROR, - .end = IRQ_SPORT0_ERROR, - .flags = IORESOURCE_IRQ, - }, - { - .start = CH_SPORT0_TX, - .end = CH_SPORT0_TX, - .flags = IORESOURCE_DMA, - }, - { - .start = CH_SPORT0_RX, - .end = CH_SPORT0_RX, - .flags = IORESOURCE_DMA, - }, -}; -static struct platform_device bfin_sport0_device = { - .name = "bfin_sport_raw", - .id = 0, - .num_resources = ARRAY_SIZE(bfin_sport0_resources), - .resource = bfin_sport0_resources, - .dev = { - .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ - }, -}; -#endif + #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) #define CF_IDE_NAND_CARD_USE_HDD_INTERFACE /* #define CF_IDE_NAND_CARD_USE_CF_IN_COMMON_MEMORY_MODE */ @@ -2802,9 +2754,7 @@ static struct platform_device bf5xx_adau1701_device = { static struct platform_device *stamp_devices[] __initdata = { &bfin_dpmc, -#if defined(CONFIG_BFIN_SPORT) || defined(CONFIG_BFIN_SPORT_MODULE) - &bfin_sport0_device, -#endif + #if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) &bfin_pcmcia_cf_device, #endif diff --git a/trunk/arch/blackfin/mach-bf537/boards/tcm_bf537.c b/trunk/arch/blackfin/mach-bf537/boards/tcm_bf537.c index e285c3675286..3fb421823857 100644 --- a/trunk/arch/blackfin/mach-bf537/boards/tcm_bf537.c +++ b/trunk/arch/blackfin/mach-bf537/boards/tcm_bf537.c @@ -453,8 +453,6 @@ static struct platform_device bfin_sir1_device = { #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) -static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; - static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -473,9 +471,6 @@ static struct platform_device i2c_bfin_twi_device = { .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, - .dev = { - .platform_data = &bfin_twi0_pins, - }, }; #endif diff --git a/trunk/arch/blackfin/mach-bf537/include/mach/anomaly.h b/trunk/arch/blackfin/mach-bf537/include/mach/anomaly.h index df9212696397..543cd3fb305e 100644 --- a/trunk/arch/blackfin/mach-bf537/include/mach/anomaly.h +++ b/trunk/arch/blackfin/mach-bf537/include/mach/anomaly.h @@ -6,7 +6,8 @@ * DO NOT EDIT THIS FILE * * Copyright 2004-2011 Analog Devices Inc. - * Licensed under the Clear BSD license. + * Licensed under the ADI BSD license. + * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd */ /* This file should be up to date with: diff --git a/trunk/arch/blackfin/mach-bf537/include/mach/defBF534.h b/trunk/arch/blackfin/mach-bf537/include/mach/defBF534.h index ef6a98cdfd44..4a031dde173f 100644 --- a/trunk/arch/blackfin/mach-bf537/include/mach/defBF534.h +++ b/trunk/arch/blackfin/mach-bf537/include/mach/defBF534.h @@ -1,7 +1,7 @@ /* * Copyright 2005-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF534_H @@ -1403,6 +1403,75 @@ #define ERR_DET 0x4000 /* Error Detected Indicator */ #define ERR_NCOR 0x8000 /* Error Not Corrected Indicator */ +/* ******************** TWO-WIRE INTERFACE (TWI) MASKS ***********************/ +/* TWI_CLKDIV Macros (Use: *pTWI_CLKDIV = CLKLOW(x)|CLKHI(y); ) */ +#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */ +#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */ + +/* TWI_PRESCALE Masks */ +#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */ +#define TWI_ENA 0x0080 /* TWI Enable */ +#define SCCB 0x0200 /* SCCB Compatibility Enable */ + +/* TWI_SLAVE_CTL Masks */ +#define SEN 0x0001 /* Slave Enable */ +#define SADD_LEN 0x0002 /* Slave Address Length */ +#define STDVAL 0x0004 /* Slave Transmit Data Valid */ +#define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */ +#define GEN 0x0010 /* General Call Address Matching Enabled */ + +/* TWI_SLAVE_STAT Masks */ +#define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */ +#define GCALL 0x0002 /* General Call Indicator */ + +/* TWI_MASTER_CTL Masks */ +#define MEN 0x0001 /* Master Mode Enable */ +#define MADD_LEN 0x0002 /* Master Address Length */ +#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */ +#define FAST 0x0008 /* Use Fast Mode Timing Specs */ +#define STOP 0x0010 /* Issue Stop Condition */ +#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */ +#define DCNT 0x3FC0 /* Data Bytes To Transfer */ +#define SDAOVR 0x4000 /* Serial Data Override */ +#define SCLOVR 0x8000 /* Serial Clock Override */ + +/* TWI_MASTER_STAT Masks */ +#define MPROG 0x0001 /* Master Transfer In Progress */ +#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */ +#define ANAK 0x0004 /* Address Not Acknowledged */ +#define DNAK 0x0008 /* Data Not Acknowledged */ +#define BUFRDERR 0x0010 /* Buffer Read Error */ +#define BUFWRERR 0x0020 /* Buffer Write Error */ +#define SDASEN 0x0040 /* Serial Data Sense */ +#define SCLSEN 0x0080 /* Serial Clock Sense */ +#define BUSBUSY 0x0100 /* Bus Busy Indicator */ + +/* TWI_INT_SRC and TWI_INT_ENABLE Masks */ +#define SINIT 0x0001 /* Slave Transfer Initiated */ +#define SCOMP 0x0002 /* Slave Transfer Complete */ +#define SERR 0x0004 /* Slave Transfer Error */ +#define SOVF 0x0008 /* Slave Overflow */ +#define MCOMP 0x0010 /* Master Transfer Complete */ +#define MERR 0x0020 /* Master Transfer Error */ +#define XMTSERV 0x0040 /* Transmit FIFO Service */ +#define RCVSERV 0x0080 /* Receive FIFO Service */ + +/* TWI_FIFO_CTRL Masks */ +#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */ +#define RCVFLUSH 0x0002 /* Receive Buffer Flush */ +#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */ +#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */ + +/* TWI_FIFO_STAT Masks */ +#define XMTSTAT 0x0003 /* Transmit FIFO Status */ +#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */ +#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */ +#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */ + +#define RCVSTAT 0x000C /* Receive FIFO Status */ +#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */ +#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */ +#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */ /* ******************* PIN CONTROL REGISTER MASKS ************************/ /* PORT_MUX Masks */ diff --git a/trunk/arch/blackfin/mach-bf537/include/mach/defBF537.h b/trunk/arch/blackfin/mach-bf537/include/mach/defBF537.h index e10332c9f660..3d471d752684 100644 --- a/trunk/arch/blackfin/mach-bf537/include/mach/defBF537.h +++ b/trunk/arch/blackfin/mach-bf537/include/mach/defBF537.h @@ -1,7 +1,7 @@ /* * Copyright 2005-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF537_H diff --git a/trunk/arch/blackfin/mach-bf538/boards/ezkit.c b/trunk/arch/blackfin/mach-bf538/boards/ezkit.c index a4fce0370c1d..85038f54354d 100644 --- a/trunk/arch/blackfin/mach-bf538/boards/ezkit.c +++ b/trunk/arch/blackfin/mach-bf538/boards/ezkit.c @@ -718,8 +718,6 @@ static struct platform_device bf538_spi_master2 = { }; #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) -static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; - static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -738,13 +736,9 @@ static struct platform_device i2c_bfin_twi0_device = { .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, - .dev = { - .platform_data = &bfin_twi0_pins, - }, }; -static const u16 bfin_twi1_pins[] = {P_TWI1_SCL, P_TWI1_SDA, 0}; - +#if !defined(CONFIG_BF542) /* The BF542 only has 1 TWI */ static struct resource bfin_twi1_resource[] = { [0] = { .start = TWI1_REGBASE, diff --git a/trunk/arch/blackfin/mach-bf538/include/mach/anomaly.h b/trunk/arch/blackfin/mach-bf538/include/mach/anomaly.h index 318d922d11d4..b6ca99788710 100644 --- a/trunk/arch/blackfin/mach-bf538/include/mach/anomaly.h +++ b/trunk/arch/blackfin/mach-bf538/include/mach/anomaly.h @@ -6,7 +6,8 @@ * DO NOT EDIT THIS FILE * * Copyright 2004-2011 Analog Devices Inc. - * Licensed under the Clear BSD license. + * Licensed under the ADI BSD license. + * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd */ /* This file should be up to date with: diff --git a/trunk/arch/blackfin/mach-bf538/include/mach/defBF538.h b/trunk/arch/blackfin/mach-bf538/include/mach/defBF538.h index 876a77028001..d27f81d6c4b1 100644 --- a/trunk/arch/blackfin/mach-bf538/include/mach/defBF538.h +++ b/trunk/arch/blackfin/mach-bf538/include/mach/defBF538.h @@ -1,7 +1,7 @@ /* * Copyright 2008-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF538_H @@ -1746,4 +1746,80 @@ #define SDEASE 0x00000010 /* SDRAM EAB sticky error status - W1C */ #define BGSTAT 0x00000020 /* Bus granted */ + +/* ******************** TWO-WIRE INTERFACE (TWIx) MASKS ***********************/ +/* TWIx_CLKDIV Macros (Use: *pTWIx_CLKDIV = CLKLOW(x)|CLKHI(y); ) */ +#ifdef _MISRA_RULES +#define CLKLOW(x) ((x) & 0xFFu) /* Periods Clock Is Held Low */ +#define CLKHI(y) (((y)&0xFFu)<<0x8) /* Periods Before New Clock Low */ +#else +#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */ +#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */ +#endif /* _MISRA_RULES */ + +/* TWIx_PRESCALE Masks */ +#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */ +#define TWI_ENA 0x0080 /* TWI Enable */ +#define SCCB 0x0200 /* SCCB Compatibility Enable */ + +/* TWIx_SLAVE_CTRL Masks */ +#define SEN 0x0001 /* Slave Enable */ +#define SADD_LEN 0x0002 /* Slave Address Length */ +#define STDVAL 0x0004 /* Slave Transmit Data Valid */ +#define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */ +#define GEN 0x0010 /* General Call Adrress Matching Enabled */ + +/* TWIx_SLAVE_STAT Masks */ +#define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */ +#define GCALL 0x0002 /* General Call Indicator */ + +/* TWIx_MASTER_CTRL Masks */ +#define MEN 0x0001 /* Master Mode Enable */ +#define MADD_LEN 0x0002 /* Master Address Length */ +#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */ +#define FAST 0x0008 /* Use Fast Mode Timing Specs */ +#define STOP 0x0010 /* Issue Stop Condition */ +#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */ +#define DCNT 0x3FC0 /* Data Bytes To Transfer */ +#define SDAOVR 0x4000 /* Serial Data Override */ +#define SCLOVR 0x8000 /* Serial Clock Override */ + +/* TWIx_MASTER_STAT Masks */ +#define MPROG 0x0001 /* Master Transfer In Progress */ +#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */ +#define ANAK 0x0004 /* Address Not Acknowledged */ +#define DNAK 0x0008 /* Data Not Acknowledged */ +#define BUFRDERR 0x0010 /* Buffer Read Error */ +#define BUFWRERR 0x0020 /* Buffer Write Error */ +#define SDASEN 0x0040 /* Serial Data Sense */ +#define SCLSEN 0x0080 /* Serial Clock Sense */ +#define BUSBUSY 0x0100 /* Bus Busy Indicator */ + +/* TWIx_INT_SRC and TWIx_INT_ENABLE Masks */ +#define SINIT 0x0001 /* Slave Transfer Initiated */ +#define SCOMP 0x0002 /* Slave Transfer Complete */ +#define SERR 0x0004 /* Slave Transfer Error */ +#define SOVF 0x0008 /* Slave Overflow */ +#define MCOMP 0x0010 /* Master Transfer Complete */ +#define MERR 0x0020 /* Master Transfer Error */ +#define XMTSERV 0x0040 /* Transmit FIFO Service */ +#define RCVSERV 0x0080 /* Receive FIFO Service */ + +/* TWIx_FIFO_CTL Masks */ +#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */ +#define RCVFLUSH 0x0002 /* Receive Buffer Flush */ +#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */ +#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */ + +/* TWIx_FIFO_STAT Masks */ +#define XMTSTAT 0x0003 /* Transmit FIFO Status */ +#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */ +#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */ +#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */ + +#define RCVSTAT 0x000C /* Receive FIFO Status */ +#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */ +#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */ +#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */ + #endif diff --git a/trunk/arch/blackfin/mach-bf538/include/mach/defBF539.h b/trunk/arch/blackfin/mach-bf538/include/mach/defBF539.h index 199e871634b4..8100bcd01a0d 100644 --- a/trunk/arch/blackfin/mach-bf538/include/mach/defBF539.h +++ b/trunk/arch/blackfin/mach-bf538/include/mach/defBF539.h @@ -1,7 +1,7 @@ /* * Copyright 2008-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF539_H diff --git a/trunk/arch/blackfin/mach-bf548/boards/cm_bf548.c b/trunk/arch/blackfin/mach-bf548/boards/cm_bf548.c index e92543362f35..68af594db48e 100644 --- a/trunk/arch/blackfin/mach-bf548/boards/cm_bf548.c +++ b/trunk/arch/blackfin/mach-bf548/boards/cm_bf548.c @@ -1007,8 +1007,6 @@ static struct platform_device bf54x_spi_master1 = { #endif /* spi master and devices */ #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) -static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; - static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -1027,14 +1025,9 @@ static struct platform_device i2c_bfin_twi0_device = { .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, - .dev = { - .platform_data = &bfin_twi0_pins, - }, }; #if !defined(CONFIG_BF542) /* The BF542 only has 1 TWI */ -static const u16 bfin_twi1_pins[] = {P_TWI1_SCL, P_TWI1_SDA, 0}; - static struct resource bfin_twi1_resource[] = { [0] = { .start = TWI1_REGBASE, @@ -1053,9 +1046,6 @@ static struct platform_device i2c_bfin_twi1_device = { .id = 1, .num_resources = ARRAY_SIZE(bfin_twi1_resource), .resource = bfin_twi1_resource, - .dev = { - .platform_data = &bfin_twi1_pins, - }, }; #endif #endif diff --git a/trunk/arch/blackfin/mach-bf548/boards/ezkit.c b/trunk/arch/blackfin/mach-bf548/boards/ezkit.c index 3bd75bae750d..4cadaf8d0b56 100644 --- a/trunk/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/trunk/arch/blackfin/mach-bf548/boards/ezkit.c @@ -165,7 +165,6 @@ static struct bfin_rotary_platform_data bfin_rotary_data = { .rotary_button_key = KEY_ENTER, .debounce = 10, /* 0..17 */ .mode = ROT_QUAD_ENC | ROT_DEBE, - .pm_wakeup = 1, }; static struct resource bfin_rotary_resources[] = { @@ -1252,8 +1251,6 @@ static struct platform_device bfin_capture_device = { #endif #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) -static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; - static struct resource bfin_twi0_resource[] = { [0] = { .start = TWI0_REGBASE, @@ -1272,14 +1269,9 @@ static struct platform_device i2c_bfin_twi0_device = { .id = 0, .num_resources = ARRAY_SIZE(bfin_twi0_resource), .resource = bfin_twi0_resource, - .dev = { - .platform_data = &bfin_twi0_pins, - }, }; #if !defined(CONFIG_BF542) /* The BF542 only has 1 TWI */ -static const u16 bfin_twi1_pins[] = {P_TWI1_SCL, P_TWI1_SDA, 0}; - static struct resource bfin_twi1_resource[] = { [0] = { .start = TWI1_REGBASE, @@ -1298,9 +1290,6 @@ static struct platform_device i2c_bfin_twi1_device = { .id = 1, .num_resources = ARRAY_SIZE(bfin_twi1_resource), .resource = bfin_twi1_resource, - .dev = { - .platform_data = &bfin_twi1_pins, - }, }; #endif #endif diff --git a/trunk/arch/blackfin/mach-bf548/include/mach/anomaly.h b/trunk/arch/blackfin/mach-bf548/include/mach/anomaly.h index 5b711d85b90b..ac96ee83b00e 100644 --- a/trunk/arch/blackfin/mach-bf548/include/mach/anomaly.h +++ b/trunk/arch/blackfin/mach-bf548/include/mach/anomaly.h @@ -6,7 +6,8 @@ * DO NOT EDIT THIS FILE * * Copyright 2004-2011 Analog Devices Inc. - * Licensed under the Clear BSD license. + * Licensed under the ADI BSD license. + * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd */ /* This file should be up to date with: diff --git a/trunk/arch/blackfin/mach-bf548/include/mach/defBF542.h b/trunk/arch/blackfin/mach-bf548/include/mach/defBF542.h index 51161575a163..629bf216e2b5 100644 --- a/trunk/arch/blackfin/mach-bf548/include/mach/defBF542.h +++ b/trunk/arch/blackfin/mach-bf548/include/mach/defBF542.h @@ -1,7 +1,7 @@ /* * Copyright 2007-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF542_H diff --git a/trunk/arch/blackfin/mach-bf548/include/mach/defBF544.h b/trunk/arch/blackfin/mach-bf548/include/mach/defBF544.h index 329b2c58228b..bcccab36629c 100644 --- a/trunk/arch/blackfin/mach-bf548/include/mach/defBF544.h +++ b/trunk/arch/blackfin/mach-bf548/include/mach/defBF544.h @@ -1,7 +1,7 @@ /* * Copyright 2007-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF544_H diff --git a/trunk/arch/blackfin/mach-bf548/include/mach/defBF547.h b/trunk/arch/blackfin/mach-bf548/include/mach/defBF547.h index e18de212ba1a..1fa41ec03f31 100644 --- a/trunk/arch/blackfin/mach-bf548/include/mach/defBF547.h +++ b/trunk/arch/blackfin/mach-bf548/include/mach/defBF547.h @@ -1,7 +1,7 @@ /* * Copyright 2008-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF547_H diff --git a/trunk/arch/blackfin/mach-bf548/include/mach/defBF548.h b/trunk/arch/blackfin/mach-bf548/include/mach/defBF548.h index 27f29481e283..3c7f1b69349e 100644 --- a/trunk/arch/blackfin/mach-bf548/include/mach/defBF548.h +++ b/trunk/arch/blackfin/mach-bf548/include/mach/defBF548.h @@ -1,7 +1,7 @@ /* * Copyright 2007-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF548_H diff --git a/trunk/arch/blackfin/mach-bf548/include/mach/defBF549.h b/trunk/arch/blackfin/mach-bf548/include/mach/defBF549.h index ac569fc12972..9a45cb6b30da 100644 --- a/trunk/arch/blackfin/mach-bf548/include/mach/defBF549.h +++ b/trunk/arch/blackfin/mach-bf548/include/mach/defBF549.h @@ -1,7 +1,7 @@ /* * Copyright 2007-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF549_H diff --git a/trunk/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h b/trunk/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h index 8f6e1925779d..0867c2bedb43 100644 --- a/trunk/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h +++ b/trunk/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h @@ -1,7 +1,7 @@ /* * Copyright 2007-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF54X_H @@ -2062,6 +2062,115 @@ #define LOW_EVEN 0xff0000 /* Lower Limit for Even Bytes (Luma) */ #define HIGH_EVEN 0xff000000 /* Upper Limit for Even Bytes (Luma) */ +/* ************************************************ */ +/* The TWI bit masks fields are from the ADSP-BF538 */ +/* and they have not been verified as the final */ +/* ones for the Moab processors ... bz 1/19/2007 */ +/* ************************************************ */ + +/* Bit masks for TWIx_CONTROL */ + +#define PRESCALE 0x7f /* Prescale Value */ +#define TWI_ENA 0x80 /* TWI Enable */ +#define SCCB 0x200 /* Serial Camera Control Bus */ + +/* Bit maskes for TWIx_CLKDIV */ + +#define CLKLOW 0xff /* Clock Low */ +#define CLKHI 0xff00 /* Clock High */ + +/* Bit maskes for TWIx_SLAVE_CTL */ + +#define SEN 0x1 /* Slave Enable */ +#define STDVAL 0x4 /* Slave Transmit Data Valid */ +#define NAK 0x8 /* Not Acknowledge */ +#define GEN 0x10 /* General Call Enable */ + +/* Bit maskes for TWIx_SLAVE_ADDR */ + +#define SADDR 0x7f /* Slave Mode Address */ + +/* Bit maskes for TWIx_SLAVE_STAT */ + +#define SDIR 0x1 /* Slave Transfer Direction */ +#define GCALL 0x2 /* General Call */ + +/* Bit maskes for TWIx_MASTER_CTL */ + +#define MEN 0x1 /* Master Mode Enable */ +#define MDIR 0x4 /* Master Transfer Direction */ +#define FAST 0x8 /* Fast Mode */ +#define STOP 0x10 /* Issue Stop Condition */ +#define RSTART 0x20 /* Repeat Start */ +#define DCNT 0x3fc0 /* Data Transfer Count */ +#define SDAOVR 0x4000 /* Serial Data Override */ +#define SCLOVR 0x8000 /* Serial Clock Override */ + +/* Bit maskes for TWIx_MASTER_ADDR */ + +#define MADDR 0x7f /* Master Mode Address */ + +/* Bit maskes for TWIx_MASTER_STAT */ + +#define MPROG 0x1 /* Master Transfer in Progress */ +#define LOSTARB 0x2 /* Lost Arbitration */ +#define ANAK 0x4 /* Address Not Acknowledged */ +#define DNAK 0x8 /* Data Not Acknowledged */ +#define BUFRDERR 0x10 /* Buffer Read Error */ +#define BUFWRERR 0x20 /* Buffer Write Error */ +#define SDASEN 0x40 /* Serial Data Sense */ +#define SCLSEN 0x80 /* Serial Clock Sense */ +#define BUSBUSY 0x100 /* Bus Busy */ + +/* Bit maskes for TWIx_FIFO_CTL */ + +#define XMTFLUSH 0x1 /* Transmit Buffer Flush */ +#define RCVFLUSH 0x2 /* Receive Buffer Flush */ +#define XMTINTLEN 0x4 /* Transmit Buffer Interrupt Length */ +#define RCVINTLEN 0x8 /* Receive Buffer Interrupt Length */ + +/* Bit maskes for TWIx_FIFO_STAT */ + +#define XMTSTAT 0x3 /* Transmit FIFO Status */ +#define RCVSTAT 0xc /* Receive FIFO Status */ + +/* Bit maskes for TWIx_INT_MASK */ + +#define SINITM 0x1 /* Slave Transfer Initiated Interrupt Mask */ +#define SCOMPM 0x2 /* Slave Transfer Complete Interrupt Mask */ +#define SERRM 0x4 /* Slave Transfer Error Interrupt Mask */ +#define SOVFM 0x8 /* Slave Overflow Interrupt Mask */ +#define MCOMPM 0x10 /* Master Transfer Complete Interrupt Mask */ +#define MERRM 0x20 /* Master Transfer Error Interrupt Mask */ +#define XMTSERVM 0x40 /* Transmit FIFO Service Interrupt Mask */ +#define RCVSERVM 0x80 /* Receive FIFO Service Interrupt Mask */ + +/* Bit maskes for TWIx_INT_STAT */ + +#define SINIT 0x1 /* Slave Transfer Initiated */ +#define SCOMP 0x2 /* Slave Transfer Complete */ +#define SERR 0x4 /* Slave Transfer Error */ +#define SOVF 0x8 /* Slave Overflow */ +#define MCOMP 0x10 /* Master Transfer Complete */ +#define MERR 0x20 /* Master Transfer Error */ +#define XMTSERV 0x40 /* Transmit FIFO Service */ +#define RCVSERV 0x80 /* Receive FIFO Service */ + +/* Bit maskes for TWIx_XMT_DATA8 */ + +#define XMTDATA8 0xff /* Transmit FIFO 8-Bit Data */ + +/* Bit maskes for TWIx_XMT_DATA16 */ + +#define XMTDATA16 0xffff /* Transmit FIFO 16-Bit Data */ + +/* Bit maskes for TWIx_RCV_DATA8 */ + +#define RCVDATA8 0xff /* Receive FIFO 8-Bit Data */ + +/* Bit maskes for TWIx_RCV_DATA16 */ + +#define RCVDATA16 0xffff /* Receive FIFO 16-Bit Data */ /* ******************************************* */ /* MULTI BIT MACRO ENUMERATIONS */ diff --git a/trunk/arch/blackfin/mach-bf561/include/mach/anomaly.h b/trunk/arch/blackfin/mach-bf561/include/mach/anomaly.h index 72476ff50335..836baeed303a 100644 --- a/trunk/arch/blackfin/mach-bf561/include/mach/anomaly.h +++ b/trunk/arch/blackfin/mach-bf561/include/mach/anomaly.h @@ -6,7 +6,8 @@ * DO NOT EDIT THIS FILE * * Copyright 2004-2011 Analog Devices Inc. - * Licensed under the Clear BSD license. + * Licensed under the ADI BSD license. + * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd */ /* This file should be up to date with: diff --git a/trunk/arch/blackfin/mach-bf561/include/mach/defBF561.h b/trunk/arch/blackfin/mach-bf561/include/mach/defBF561.h index 9f21f768c63a..5f0ac5a77a37 100644 --- a/trunk/arch/blackfin/mach-bf561/include/mach/defBF561.h +++ b/trunk/arch/blackfin/mach-bf561/include/mach/defBF561.h @@ -1,7 +1,7 @@ /* * Copyright 2005-2010 Analog Devices Inc. * - * Licensed under the Clear BSD license or the GPL-2 (or later) + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _DEF_BF561_H diff --git a/trunk/arch/blackfin/mach-bf609/Kconfig b/trunk/arch/blackfin/mach-bf609/Kconfig deleted file mode 100644 index 2cb727243778..000000000000 --- a/trunk/arch/blackfin/mach-bf609/Kconfig +++ /dev/null @@ -1,56 +0,0 @@ -config BF60x - def_bool y - depends on (BF609) - select IRQ_PREFLOW_FASTEOI - -if (BF60x) - -source "arch/blackfin/mach-bf609/boards/Kconfig" - -menu "BF609 Specific Configuration" - -comment "Pin Interrupt to Port Assignment" -menu "Assignment" - -config PINTx_REASSIGN - bool "Reprogram PINT Assignment" - default y - help - The interrupt assignment registers controls the pin-to-interrupt - assignment in a byte-wide manner. Each option allows you to select - a set of pins (High/Low Byte) of an specific Port being mapped - to one of the four PIN Interrupts IRQ_PINTx. - - You shouldn't change any of these unless you know exactly what you're doing. - Please consult the Blackfin BF60x Processor Hardware Reference Manual. - -config PINT0_ASSIGN - hex "PINT0_ASSIGN" - depends on PINTx_REASSIGN - default 0x00000101 -config PINT1_ASSIGN - hex "PINT1_ASSIGN" - depends on PINTx_REASSIGN - default 0x00000101 -config PINT2_ASSIGN - hex "PINT2_ASSIGN" - depends on PINTx_REASSIGN - default 0x00000101 -config PINT3_ASSIGN - hex "PINT3_ASSIGN" - depends on PINTx_REASSIGN - default 0x00000101 -config PINT4_ASSIGN - hex "PINT3_ASSIGN" - depends on PINTx_REASSIGN - default 0x00000101 -config PINT5_ASSIGN - hex "PINT3_ASSIGN" - depends on PINTx_REASSIGN - default 0x00000101 - -endmenu - -endmenu - -endif diff --git a/trunk/arch/blackfin/mach-bf609/Makefile b/trunk/arch/blackfin/mach-bf609/Makefile deleted file mode 100644 index 2a27f8174543..000000000000 --- a/trunk/arch/blackfin/mach-bf609/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# -# arch/blackfin/mach-bf609/Makefile -# - -obj-y := dma.o clock.o -obj-$(CONFIG_PM) += pm.o hibernate.o diff --git a/trunk/arch/blackfin/mach-bf609/boards/Kconfig b/trunk/arch/blackfin/mach-bf609/boards/Kconfig deleted file mode 100644 index 30e8b6b0d2ed..000000000000 --- a/trunk/arch/blackfin/mach-bf609/boards/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -choice - prompt "System type" - default BFIN609_EZKIT - help - Select your board! - -config BFIN609_EZKIT - bool "BF609-EZKIT" - help - BFIN609-EZKIT board support. - -endchoice diff --git a/trunk/arch/blackfin/mach-bf609/boards/Makefile b/trunk/arch/blackfin/mach-bf609/boards/Makefile deleted file mode 100644 index 11f98b0882ea..000000000000 --- a/trunk/arch/blackfin/mach-bf609/boards/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# arch/blackfin/mach-bf609/boards/Makefile -# - -obj-$(CONFIG_BFIN609_EZKIT) += ezkit.o diff --git a/trunk/arch/blackfin/mach-bf609/boards/ezkit.c b/trunk/arch/blackfin/mach-bf609/boards/ezkit.c deleted file mode 100644 index ac64f47217c1..000000000000 --- a/trunk/arch/blackfin/mach-bf609/boards/ezkit.c +++ /dev/null @@ -1,1340 +0,0 @@ -/* - * Copyright 2004-2009 Analog Devices Inc. - * 2005 National ICT Australia (NICTA) - * Aidan Williams - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Name the Board for the /proc/cpuinfo - */ -const char bfin_board_name[] = "ADI BF609-EZKIT"; - -/* - * Driver needs to know address, irq and flag pin. - */ - -#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE) -#include -static struct resource bfin_isp1760_resources[] = { - [0] = { - .start = 0x2C0C0000, - .end = 0x2C0C0000 + 0xfffff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_PG7, - .end = IRQ_PG7, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct isp1760_platform_data isp1760_priv = { - .is_isp1761 = 0, - .bus_width_16 = 1, - .port1_otg = 0, - .analog_oc = 0, - .dack_polarity_high = 0, - .dreq_polarity_high = 0, -}; - -static struct platform_device bfin_isp1760_device = { - .name = "isp1760", - .id = 0, - .dev = { - .platform_data = &isp1760_priv, - }, - .num_resources = ARRAY_SIZE(bfin_isp1760_resources), - .resource = bfin_isp1760_resources, -}; -#endif - -#if defined(CONFIG_INPUT_BFIN_ROTARY) || defined(CONFIG_INPUT_BFIN_ROTARY_MODULE) -#include - -static struct bfin_rotary_platform_data bfin_rotary_data = { - /*.rotary_up_key = KEY_UP,*/ - /*.rotary_down_key = KEY_DOWN,*/ - .rotary_rel_code = REL_WHEEL, - .rotary_button_key = KEY_ENTER, - .debounce = 10, /* 0..17 */ - .mode = ROT_QUAD_ENC | ROT_DEBE, -}; - -static struct resource bfin_rotary_resources[] = { - { - .start = IRQ_CNT, - .end = IRQ_CNT, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device bfin_rotary_device = { - .name = "bfin-rotary", - .id = -1, - .num_resources = ARRAY_SIZE(bfin_rotary_resources), - .resource = bfin_rotary_resources, - .dev = { - .platform_data = &bfin_rotary_data, - }, -}; -#endif - -#if defined(CONFIG_STMMAC_ETH) || defined(CONFIG_STMMAC_ETH_MODULE) -#include - -static unsigned short pins[] = P_RMII0; - -static struct stmmac_mdio_bus_data phy_private_data = { - .bus_id = 0, - .phy_mask = 1, -}; - -static struct plat_stmmacenet_data eth_private_data = { - .bus_id = 0, - .enh_desc = 1, - .phy_addr = 1, - .mdio_bus_data = &phy_private_data, -}; - -static struct platform_device bfin_eth_device = { - .name = "stmmaceth", - .id = 0, - .num_resources = 2, - .resource = (struct resource[]) { - { - .start = EMAC0_MACCFG, - .end = EMAC0_MACCFG + 0x1274, - .flags = IORESOURCE_MEM, - }, - { - .name = "macirq", - .start = IRQ_EMAC0_STAT, - .end = IRQ_EMAC0_STAT, - .flags = IORESOURCE_IRQ, - }, - }, - .dev = { - .power.can_wakeup = 1, - .platform_data = ð_private_data, - } -}; -#endif - -#if defined(CONFIG_INPUT_ADXL34X) || defined(CONFIG_INPUT_ADXL34X_MODULE) -#include -static const struct adxl34x_platform_data adxl34x_info = { - .x_axis_offset = 0, - .y_axis_offset = 0, - .z_axis_offset = 0, - .tap_threshold = 0x31, - .tap_duration = 0x10, - .tap_latency = 0x60, - .tap_window = 0xF0, - .tap_axis_control = ADXL_TAP_X_EN | ADXL_TAP_Y_EN | ADXL_TAP_Z_EN, - .act_axis_control = 0xFF, - .activity_threshold = 5, - .inactivity_threshold = 3, - .inactivity_time = 4, - .free_fall_threshold = 0x7, - .free_fall_time = 0x20, - .data_rate = 0x8, - .data_range = ADXL_FULL_RES, - - .ev_type = EV_ABS, - .ev_code_x = ABS_X, /* EV_REL */ - .ev_code_y = ABS_Y, /* EV_REL */ - .ev_code_z = ABS_Z, /* EV_REL */ - - .ev_code_tap = {BTN_TOUCH, BTN_TOUCH, BTN_TOUCH}, /* EV_KEY x,y,z */ - -/* .ev_code_ff = KEY_F,*/ /* EV_KEY */ -/* .ev_code_act_inactivity = KEY_A,*/ /* EV_KEY */ - .power_mode = ADXL_AUTO_SLEEP | ADXL_LINK, - .fifo_mode = ADXL_FIFO_STREAM, - .orientation_enable = ADXL_EN_ORIENTATION_3D, - .deadzone_angle = ADXL_DEADZONE_ANGLE_10p8, - .divisor_length = ADXL_LP_FILTER_DIVISOR_16, - /* EV_KEY {+Z, +Y, +X, -X, -Y, -Z} */ - .ev_codes_orient_3d = {BTN_Z, BTN_Y, BTN_X, BTN_A, BTN_B, BTN_C}, -}; -#endif - -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) -static struct platform_device rtc_device = { - .name = "rtc-bfin", - .id = -1, -}; -#endif - -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -#ifdef CONFIG_SERIAL_BFIN_UART0 -static struct resource bfin_uart0_resources[] = { - { - .start = UART0_REVID, - .end = UART0_RXDIV+4, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_UART0_TX, - .end = IRQ_UART0_TX, - .flags = IORESOURCE_IRQ, - }, - { - .start = IRQ_UART0_RX, - .end = IRQ_UART0_RX, - .flags = IORESOURCE_IRQ, - }, - { - .start = IRQ_UART0_STAT, - .end = IRQ_UART0_STAT, - .flags = IORESOURCE_IRQ, - }, - { - .start = CH_UART0_TX, - .end = CH_UART0_TX, - .flags = IORESOURCE_DMA, - }, - { - .start = CH_UART0_RX, - .end = CH_UART0_RX, - .flags = IORESOURCE_DMA, - }, -#ifdef CONFIG_BFIN_UART0_CTSRTS - { /* CTS pin -- 0 means not supported */ - .start = GPIO_PD10, - .end = GPIO_PD10, - .flags = IORESOURCE_IO, - }, - { /* RTS pin -- 0 means not supported */ - .start = GPIO_PD9, - .end = GPIO_PD9, - .flags = IORESOURCE_IO, - }, -#endif -}; - -static unsigned short bfin_uart0_peripherals[] = { - P_UART0_TX, P_UART0_RX, -#ifdef CONFIG_BFIN_UART0_CTSRTS - P_UART0_RTS, P_UART0_CTS, -#endif - 0 -}; - -static struct platform_device bfin_uart0_device = { - .name = "bfin-uart", - .id = 0, - .num_resources = ARRAY_SIZE(bfin_uart0_resources), - .resource = bfin_uart0_resources, - .dev = { - .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ - }, -}; -#endif -#ifdef CONFIG_SERIAL_BFIN_UART1 -static struct resource bfin_uart1_resources[] = { - { - .start = UART1_REVID, - .end = UART1_RXDIV+4, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_UART1_TX, - .end = IRQ_UART1_TX, - .flags = IORESOURCE_IRQ, - }, - { - .start = IRQ_UART1_RX, - .end = IRQ_UART1_RX, - .flags = IORESOURCE_IRQ, - }, - { - .start = IRQ_UART1_STAT, - .end = IRQ_UART1_STAT, - .flags = IORESOURCE_IRQ, - }, - { - .start = CH_UART1_TX, - .end = CH_UART1_TX, - .flags = IORESOURCE_DMA, - }, - { - .start = CH_UART1_RX, - .end = CH_UART1_RX, - .flags = IORESOURCE_DMA, - }, -#ifdef CONFIG_BFIN_UART1_CTSRTS - { /* CTS pin -- 0 means not supported */ - .start = GPIO_PG13, - .end = GPIO_PG13, - .flags = IORESOURCE_IO, - }, - { /* RTS pin -- 0 means not supported */ - .start = GPIO_PG10, - .end = GPIO_PG10, - .flags = IORESOURCE_IO, - }, -#endif -}; - -static unsigned short bfin_uart1_peripherals[] = { - P_UART1_TX, P_UART1_RX, -#ifdef CONFIG_BFIN_UART1_CTSRTS - P_UART1_RTS, P_UART1_CTS, -#endif - 0 -}; - -static struct platform_device bfin_uart1_device = { - .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart1_resources), - .resource = bfin_uart1_resources, - .dev = { - .platform_data = &bfin_uart1_peripherals, /* Passed to driver */ - }, -}; -#endif -#endif - -#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) -#ifdef CONFIG_BFIN_SIR0 -static struct resource bfin_sir0_resources[] = { - { - .start = 0xFFC00400, - .end = 0xFFC004FF, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_UART0_TX, - .end = IRQ_UART0_TX+1, - .flags = IORESOURCE_IRQ, - }, - { - .start = CH_UART0_TX, - .end = CH_UART0_TX+1, - .flags = IORESOURCE_DMA, - }, -}; -static struct platform_device bfin_sir0_device = { - .name = "bfin_sir", - .id = 0, - .num_resources = ARRAY_SIZE(bfin_sir0_resources), - .resource = bfin_sir0_resources, -}; -#endif -#ifdef CONFIG_BFIN_SIR1 -static struct resource bfin_sir1_resources[] = { - { - .start = 0xFFC02000, - .end = 0xFFC020FF, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_UART1_TX, - .end = IRQ_UART1_TX+1, - .flags = IORESOURCE_IRQ, - }, - { - .start = CH_UART1_TX, - .end = CH_UART1_TX+1, - .flags = IORESOURCE_DMA, - }, -}; -static struct platform_device bfin_sir1_device = { - .name = "bfin_sir", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_sir1_resources), - .resource = bfin_sir1_resources, -}; -#endif -#endif - -#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) -static struct resource musb_resources[] = { - [0] = { - .start = 0xFFCC1000, - .end = 0xFFCC1398, - .flags = IORESOURCE_MEM, - }, - [1] = { /* general IRQ */ - .start = IRQ_USB_STAT, - .end = IRQ_USB_STAT, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - .name = "mc" - }, - [2] = { /* DMA IRQ */ - .start = IRQ_USB_DMA, - .end = IRQ_USB_DMA, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - .name = "dma" - }, -}; - -static struct musb_hdrc_config musb_config = { - .multipoint = 1, - .dyn_fifo = 0, - .dma = 1, - .num_eps = 16, - .dma_channels = 8, - .clkin = 48, /* musb CLKIN in MHZ */ -}; - -static struct musb_hdrc_platform_data musb_plat = { -#if defined(CONFIG_USB_MUSB_HDRC) && defined(CONFIG_USB_GADGET_MUSB_HDRC) - .mode = MUSB_OTG, -#elif defined(CONFIG_USB_MUSB_HDRC) - .mode = MUSB_HOST, -#elif defined(CONFIG_USB_GADGET_MUSB_HDRC) - .mode = MUSB_PERIPHERAL, -#endif - .config = &musb_config, -}; - -static u64 musb_dmamask = ~(u32)0; - -static struct platform_device musb_device = { - .name = "musb-blackfin", - .id = 0, - .dev = { - .dma_mask = &musb_dmamask, - .coherent_dma_mask = 0xffffffff, - .platform_data = &musb_plat, - }, - .num_resources = ARRAY_SIZE(musb_resources), - .resource = musb_resources, -}; -#endif - -#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) -#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART -static struct resource bfin_sport0_uart_resources[] = { - { - .start = SPORT0_TCR1, - .end = SPORT0_MRCS3+4, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_SPORT0_RX, - .end = IRQ_SPORT0_RX+1, - .flags = IORESOURCE_IRQ, - }, - { - .start = IRQ_SPORT0_ERROR, - .end = IRQ_SPORT0_ERROR, - .flags = IORESOURCE_IRQ, - }, -}; - -static unsigned short bfin_sport0_peripherals[] = { - P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, - P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0 -}; - -static struct platform_device bfin_sport0_uart_device = { - .name = "bfin-sport-uart", - .id = 0, - .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources), - .resource = bfin_sport0_uart_resources, - .dev = { - .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ - }, -}; -#endif -#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART -static struct resource bfin_sport1_uart_resources[] = { - { - .start = SPORT1_TCR1, - .end = SPORT1_MRCS3+4, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_SPORT1_RX, - .end = IRQ_SPORT1_RX+1, - .flags = IORESOURCE_IRQ, - }, - { - .start = IRQ_SPORT1_ERROR, - .end = IRQ_SPORT1_ERROR, - .flags = IORESOURCE_IRQ, - }, -}; - -static unsigned short bfin_sport1_peripherals[] = { - P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, - P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0 -}; - -static struct platform_device bfin_sport1_uart_device = { - .name = "bfin-sport-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources), - .resource = bfin_sport1_uart_resources, - .dev = { - .platform_data = &bfin_sport1_peripherals, /* Passed to driver */ - }, -}; -#endif -#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART -static struct resource bfin_sport2_uart_resources[] = { - { - .start = SPORT2_TCR1, - .end = SPORT2_MRCS3+4, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_SPORT2_RX, - .end = IRQ_SPORT2_RX+1, - .flags = IORESOURCE_IRQ, - }, - { - .start = IRQ_SPORT2_ERROR, - .end = IRQ_SPORT2_ERROR, - .flags = IORESOURCE_IRQ, - }, -}; - -static unsigned short bfin_sport2_peripherals[] = { - P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS, - P_SPORT2_DRPRI, P_SPORT2_RSCLK, P_SPORT2_DRSEC, P_SPORT2_DTSEC, 0 -}; - -static struct platform_device bfin_sport2_uart_device = { - .name = "bfin-sport-uart", - .id = 2, - .num_resources = ARRAY_SIZE(bfin_sport2_uart_resources), - .resource = bfin_sport2_uart_resources, - .dev = { - .platform_data = &bfin_sport2_peripherals, /* Passed to driver */ - }, -}; -#endif -#endif - -#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE) - -static unsigned short bfin_can0_peripherals[] = { - P_CAN0_RX, P_CAN0_TX, 0 -}; - -static struct resource bfin_can0_resources[] = { - { - .start = 0xFFC00A00, - .end = 0xFFC00FFF, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_CAN0_RX, - .end = IRQ_CAN0_RX, - .flags = IORESOURCE_IRQ, - }, - { - .start = IRQ_CAN0_TX, - .end = IRQ_CAN0_TX, - .flags = IORESOURCE_IRQ, - }, - { - .start = IRQ_CAN0_STAT, - .end = IRQ_CAN0_STAT, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device bfin_can0_device = { - .name = "bfin_can", - .id = 0, - .num_resources = ARRAY_SIZE(bfin_can0_resources), - .resource = bfin_can0_resources, - .dev = { - .platform_data = &bfin_can0_peripherals, /* Passed to driver */ - }, -}; - -#endif - -#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) -static struct mtd_partition partition_info[] = { - { - .name = "bootloader(nand)", - .offset = 0, - .size = 0x80000, - }, { - .name = "linux kernel(nand)", - .offset = MTDPART_OFS_APPEND, - .size = 4 * 1024 * 1024, - }, - { - .name = "file system(nand)", - .offset = MTDPART_OFS_APPEND, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct bf5xx_nand_platform bfin_nand_platform = { - .data_width = NFC_NWIDTH_8, - .partitions = partition_info, - .nr_partitions = ARRAY_SIZE(partition_info), - .rd_dly = 3, - .wr_dly = 3, -}; - -static struct resource bfin_nand_resources[] = { - { - .start = 0xFFC03B00, - .end = 0xFFC03B4F, - .flags = IORESOURCE_MEM, - }, - { - .start = CH_NFC, - .end = CH_NFC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device bfin_nand_device = { - .name = "bfin-nand", - .id = 0, - .num_resources = ARRAY_SIZE(bfin_nand_resources), - .resource = bfin_nand_resources, - .dev = { - .platform_data = &bfin_nand_platform, - }, -}; -#endif - -#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN_MODULE) - -static struct bfin_sd_host bfin_sdh_data = { - .dma_chan = CH_RSI, - .irq_int0 = IRQ_RSI_INT0, - .pin_req = {P_RSI_DATA0, P_RSI_DATA1, P_RSI_DATA2, P_RSI_DATA3, P_RSI_CMD, P_RSI_CLK, 0}, -}; - -static struct platform_device bfin_sdh_device = { - .name = "bfin-sdh", - .id = 0, - .dev = { - .platform_data = &bfin_sdh_data, - }, -}; -#endif - -#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) -static struct mtd_partition ezkit_partitions[] = { - { - .name = "bootloader(nor)", - .size = 0x80000, - .offset = 0, - }, { - .name = "linux kernel(nor)", - .size = 0x400000, - .offset = MTDPART_OFS_APPEND, - }, { - .name = "file system(nor)", - .size = 0x1000000 - 0x80000 - 0x400000, - .offset = MTDPART_OFS_APPEND, - }, -}; - -int bf609_nor_flash_init(struct platform_device *dev) -{ -#define CONFIG_SMC_GCTL_VAL 0x00000010 - const unsigned short pins[] = { - P_A3, P_A4, P_A5, P_A6, P_A7, P_A8, P_A9, P_A10, P_A11, P_A12, - P_A13, P_A14, P_A15, P_A16, P_A17, P_A18, P_A19, P_A20, P_A21, - P_A22, P_A23, P_A24, P_A25, P_NORCK, 0, - }; - - peripheral_request_list(pins, "smc0"); - - bfin_write32(SMC_GCTL, CONFIG_SMC_GCTL_VAL); - bfin_write32(SMC_B0CTL, 0x01002011); - bfin_write32(SMC_B0TIM, 0x08170977); - bfin_write32(SMC_B0ETIM, 0x00092231); - return 0; -} - -static struct physmap_flash_data ezkit_flash_data = { - .width = 2, - .parts = ezkit_partitions, - .init = bf609_nor_flash_init, - .nr_parts = ARRAY_SIZE(ezkit_partitions), -}; - -static struct resource ezkit_flash_resource = { - .start = 0xb0000000, - .end = 0xb0ffffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device ezkit_flash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &ezkit_flash_data, - }, - .num_resources = 1, - .resource = &ezkit_flash_resource, -}; -#endif - -#if defined(CONFIG_MTD_M25P80) \ - || defined(CONFIG_MTD_M25P80_MODULE) -/* SPI flash chip (w25q32) */ -static struct mtd_partition bfin_spi_flash_partitions[] = { - { - .name = "bootloader(spi)", - .size = 0x00080000, - .offset = 0, - .mask_flags = MTD_CAP_ROM - }, { - .name = "linux kernel(spi)", - .size = 0x00180000, - .offset = MTDPART_OFS_APPEND, - }, { - .name = "file system(spi)", - .size = MTDPART_SIZ_FULL, - .offset = MTDPART_OFS_APPEND, - } -}; - -static struct flash_platform_data bfin_spi_flash_data = { - .name = "m25p80", - .parts = bfin_spi_flash_partitions, - .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), - .type = "w25q32", -}; - -static struct bfin6xx_spi_chip spi_flash_chip_info = { - .enable_dma = true, /* use dma transfer with this chip*/ -}; -#endif - -#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) -static struct bfin6xx_spi_chip spidev_chip_info = { - .enable_dma = true, -}; -#endif - -#if defined(CONFIG_SND_BF6XX_I2S) || defined(CONFIG_SND_BF6XX_I2S_MODULE) -static struct platform_device bfin_i2s_pcm = { - .name = "bfin-i2s-pcm-audio", - .id = -1, -}; -#endif - -#if defined(CONFIG_SND_BF6XX_SOC_I2S) || \ - defined(CONFIG_SND_BF6XX_SOC_I2S_MODULE) -#include -static struct resource bfin_snd_resources[] = { - { - .start = SPORT0_CTL_A, - .end = SPORT0_CTL_A, - .flags = IORESOURCE_MEM, - }, - { - .start = SPORT0_CTL_B, - .end = SPORT0_CTL_B, - .flags = IORESOURCE_MEM, - }, - { - .start = CH_SPORT0_TX, - .end = CH_SPORT0_TX, - .flags = IORESOURCE_DMA, - }, - { - .start = CH_SPORT0_RX, - .end = CH_SPORT0_RX, - .flags = IORESOURCE_DMA, - }, - { - .start = IRQ_SPORT0_TX_STAT, - .end = IRQ_SPORT0_TX_STAT, - .flags = IORESOURCE_IRQ, - }, - { - .start = IRQ_SPORT0_RX_STAT, - .end = IRQ_SPORT0_RX_STAT, - .flags = IORESOURCE_IRQ, - }, -}; - -static const unsigned short bfin_snd_pin[] = { - P_SPORT0_ACLK, P_SPORT0_AFS, P_SPORT0_AD0, P_SPORT0_BCLK, - P_SPORT0_BFS, P_SPORT0_BD0, 0, -}; - -static struct bfin_snd_platform_data bfin_snd_data = { - .pin_req = bfin_snd_pin, -}; - -static struct platform_device bfin_i2s = { - .name = "bfin-i2s", - .num_resources = ARRAY_SIZE(bfin_snd_resources), - .resource = bfin_snd_resources, - .dev = { - .platform_data = &bfin_snd_data, - }, -}; -#endif - -#if defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61) || \ - defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61_MODULE) -static struct platform_device adau1761_device = { - .name = "bfin-eval-adau1x61", -}; -#endif - -#if defined(CONFIG_SND_SOC_ADAU1761) || defined(CONFIG_SND_SOC_ADAU1761_MODULE) -#include -static struct adau1761_platform_data adau1761_info = { - .lineout_mode = ADAU1761_OUTPUT_MODE_LINE, - .headphone_mode = ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS, -}; -#endif - -#if defined(CONFIG_VIDEO_BLACKFIN_CAPTURE) \ - || defined(CONFIG_VIDEO_BLACKFIN_CAPTURE_MODULE) -#include -#include -#include - -static const unsigned short ppi_req[] = { - P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3, - P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7, - P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, - 0, -}; - -static const struct ppi_info ppi_info = { - .type = PPI_TYPE_EPPI3, - .dma_ch = CH_EPPI0_CH0, - .irq_err = IRQ_EPPI0_STAT, - .base = (void __iomem *)EPPI0_STAT, - .pin_req = ppi_req, -}; - -#if defined(CONFIG_VIDEO_VS6624) \ - || defined(CONFIG_VIDEO_VS6624_MODULE) -static struct v4l2_input vs6624_inputs[] = { - { - .index = 0, - .name = "Camera", - .type = V4L2_INPUT_TYPE_CAMERA, - .std = V4L2_STD_UNKNOWN, - }, -}; - -static struct bcap_route vs6624_routes[] = { - { - .input = 0, - .output = 0, - }, -}; - -static const unsigned vs6624_ce_pin = GPIO_PD1; - -static struct bfin_capture_config bfin_capture_data = { - .card_name = "BF609", - .inputs = vs6624_inputs, - .num_inputs = ARRAY_SIZE(vs6624_inputs), - .routes = vs6624_routes, - .i2c_adapter_id = 0, - .board_info = { - .type = "vs6624", - .addr = 0x10, - .platform_data = (void *)&vs6624_ce_pin, - }, - .ppi_info = &ppi_info, - .ppi_control = (PACK_EN | DLEN_8 | EPPI_CTL_FS1HI_FS2HI - | EPPI_CTL_POLC3 | EPPI_CTL_SYNC2 | EPPI_CTL_NON656), - .blank_clocks = 8, -}; -#endif - -static struct platform_device bfin_capture_device = { - .name = "bfin_capture", - .dev = { - .platform_data = &bfin_capture_data, - }, -}; -#endif - -#if defined(CONFIG_BFIN_CRC) -#define BFIN_CRC_NAME "bfin-crc" - -static struct resource bfin_crc0_resources[] = { - { - .start = REG_CRC0_CTL, - .end = REG_CRC0_REVID+4, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_CRC0_DCNTEXP, - .end = IRQ_CRC0_DCNTEXP, - .flags = IORESOURCE_IRQ, - }, - { - .start = CH_MEM_STREAM0_SRC_CRC0, - .end = CH_MEM_STREAM0_SRC_CRC0, - .flags = IORESOURCE_DMA, - }, - { - .start = CH_MEM_STREAM0_DEST_CRC0, - .end = CH_MEM_STREAM0_DEST_CRC0, - .flags = IORESOURCE_DMA, - }, -}; - -static struct platform_device bfin_crc0_device = { - .name = BFIN_CRC_NAME, - .id = 0, - .num_resources = ARRAY_SIZE(bfin_crc0_resources), - .resource = bfin_crc0_resources, -}; - -static struct resource bfin_crc1_resources[] = { - { - .start = REG_CRC1_CTL, - .end = REG_CRC1_REVID+4, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_CRC1_DCNTEXP, - .end = IRQ_CRC1_DCNTEXP, - .flags = IORESOURCE_IRQ, - }, - { - .start = CH_MEM_STREAM1_SRC_CRC1, - .end = CH_MEM_STREAM1_SRC_CRC1, - .flags = IORESOURCE_DMA, - }, - { - .start = CH_MEM_STREAM1_DEST_CRC1, - .end = CH_MEM_STREAM1_DEST_CRC1, - .flags = IORESOURCE_DMA, - }, -}; - -static struct platform_device bfin_crc1_device = { - .name = BFIN_CRC_NAME, - .id = 1, - .num_resources = ARRAY_SIZE(bfin_crc1_resources), - .resource = bfin_crc1_resources, -}; -#endif - -#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) -static const struct ad7877_platform_data bfin_ad7877_ts_info = { - .model = 7877, - .vref_delay_usecs = 50, /* internal, no capacitor */ - .x_plate_ohms = 419, - .y_plate_ohms = 486, - .pressure_max = 1000, - .pressure_min = 0, - .stopacq_polarity = 1, - .first_conversion_delay = 3, - .acquisition_time = 1, - .averaging = 1, - .pen_down_acc_interval = 1, -}; -#endif - -static struct spi_board_info bfin_spi_board_info[] __initdata = { -#if defined(CONFIG_MTD_M25P80) \ - || defined(CONFIG_MTD_M25P80_MODULE) - { - /* the modalias must be the same as spi device driver name */ - .modalias = "m25p80", /* Name of spi_driver for this device */ - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, /* Framework bus number */ - .chip_select = 1, /* SPI_SSEL1*/ - .platform_data = &bfin_spi_flash_data, - .controller_data = &spi_flash_chip_info, - .mode = SPI_MODE_3, - }, -#endif -#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) - { - .modalias = "ad7877", - .platform_data = &bfin_ad7877_ts_info, - .irq = IRQ_PB4, /* old boards (<=Rev 1.3) use IRQ_PJ11 */ - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 2, - }, -#endif -#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) - { - .modalias = "spidev", - .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 1, - .controller_data = &spidev_chip_info, - }, -#endif -#if defined(CONFIG_INPUT_ADXL34X_SPI) || defined(CONFIG_INPUT_ADXL34X_SPI_MODULE) - { - .modalias = "adxl34x", - .platform_data = &adxl34x_info, - .irq = IRQ_PC5, - .max_speed_hz = 5000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = 2, - .mode = SPI_MODE_3, - }, -#endif -}; -#if defined(CONFIG_SPI_BFIN6XX) || defined(CONFIG_SPI_BFIN6XX_MODULE) -/* SPI (0) */ -static struct resource bfin_spi0_resource[] = { - { - .start = SPI0_REGBASE, - .end = SPI0_REGBASE + 0xFF, - .flags = IORESOURCE_MEM, - }, - { - .start = CH_SPI0_TX, - .end = CH_SPI0_TX, - .flags = IORESOURCE_DMA, - }, - { - .start = CH_SPI0_RX, - .end = CH_SPI0_RX, - .flags = IORESOURCE_DMA, - }, -}; - -/* SPI (1) */ -static struct resource bfin_spi1_resource[] = { - { - .start = SPI1_REGBASE, - .end = SPI1_REGBASE + 0xFF, - .flags = IORESOURCE_MEM, - }, - { - .start = CH_SPI1_TX, - .end = CH_SPI1_TX, - .flags = IORESOURCE_DMA, - }, - { - .start = CH_SPI1_RX, - .end = CH_SPI1_RX, - .flags = IORESOURCE_DMA, - }, - -}; - -/* SPI controller data */ -static struct bfin6xx_spi_master bf60x_spi_master_info0 = { - .num_chipselect = 4, - .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0}, -}; - -static struct platform_device bf60x_spi_master0 = { - .name = "bfin-spi", - .id = 0, /* Bus number */ - .num_resources = ARRAY_SIZE(bfin_spi0_resource), - .resource = bfin_spi0_resource, - .dev = { - .platform_data = &bf60x_spi_master_info0, /* Passed to driver */ - }, -}; - -static struct bfin6xx_spi_master bf60x_spi_master_info1 = { - .num_chipselect = 4, - .pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0}, -}; - -static struct platform_device bf60x_spi_master1 = { - .name = "bfin-spi", - .id = 1, /* Bus number */ - .num_resources = ARRAY_SIZE(bfin_spi1_resource), - .resource = bfin_spi1_resource, - .dev = { - .platform_data = &bf60x_spi_master_info1, /* Passed to driver */ - }, -}; -#endif /* spi master and devices */ - -#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) -static const u16 bfin_twi0_pins[] = {P_TWI0_SCL, P_TWI0_SDA, 0}; - -static struct resource bfin_twi0_resource[] = { - [0] = { - .start = TWI0_CLKDIV, - .end = TWI0_CLKDIV + 0xFF, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_TWI0, - .end = IRQ_TWI0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device i2c_bfin_twi0_device = { - .name = "i2c-bfin-twi", - .id = 0, - .num_resources = ARRAY_SIZE(bfin_twi0_resource), - .resource = bfin_twi0_resource, - .dev = { - .platform_data = &bfin_twi0_pins, - }, -}; - -static const u16 bfin_twi1_pins[] = {P_TWI1_SCL, P_TWI1_SDA, 0}; - -static struct resource bfin_twi1_resource[] = { - [0] = { - .start = TWI1_CLKDIV, - .end = TWI1_CLKDIV + 0xFF, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_TWI1, - .end = IRQ_TWI1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device i2c_bfin_twi1_device = { - .name = "i2c-bfin-twi", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_twi1_resource), - .resource = bfin_twi1_resource, - .dev = { - .platform_data = &bfin_twi1_pins, - }, -}; -#endif - -static struct i2c_board_info __initdata bfin_i2c_board_info0[] = { -#if defined(CONFIG_INPUT_ADXL34X_I2C) || defined(CONFIG_INPUT_ADXL34X_I2C_MODULE) - { - I2C_BOARD_INFO("adxl34x", 0x53), - .irq = IRQ_PC5, - .platform_data = (void *)&adxl34x_info, - }, -#endif -#if defined(CONFIG_SND_SOC_ADAU1761) || defined(CONFIG_SND_SOC_ADAU1761_MODULE) - { - I2C_BOARD_INFO("adau1761", 0x38), - .platform_data = (void *)&adau1761_info - }, -#endif -}; - -static struct i2c_board_info __initdata bfin_i2c_board_info1[] = { -}; - -static const unsigned int cclk_vlev_datasheet[] = -{ -/* - * Internal VLEV BF54XSBBC1533 - ****temporarily using these values until data sheet is updated - */ - VRPAIR(VLEV_085, 150000000), - VRPAIR(VLEV_090, 250000000), - VRPAIR(VLEV_110, 276000000), - VRPAIR(VLEV_115, 301000000), - VRPAIR(VLEV_120, 525000000), - VRPAIR(VLEV_125, 550000000), - VRPAIR(VLEV_130, 600000000), -}; - -static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = { - .tuple_tab = cclk_vlev_datasheet, - .tabsize = ARRAY_SIZE(cclk_vlev_datasheet), - .vr_settling_time = 25 /* us */, -}; - -static struct platform_device bfin_dpmc = { - .name = "bfin dpmc", - .dev = { - .platform_data = &bfin_dmpc_vreg_data, - }, -}; - -static struct platform_device *ezkit_devices[] __initdata = { - - &bfin_dpmc, - -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) - &rtc_device, -#endif - -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -#ifdef CONFIG_SERIAL_BFIN_UART0 - &bfin_uart0_device, -#endif -#ifdef CONFIG_SERIAL_BFIN_UART1 - &bfin_uart1_device, -#endif -#endif - -#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) -#ifdef CONFIG_BFIN_SIR0 - &bfin_sir0_device, -#endif -#ifdef CONFIG_BFIN_SIR1 - &bfin_sir1_device, -#endif -#endif - -#if defined(CONFIG_STMMAC_ETH) || defined(CONFIG_STMMAC_ETH_MODULE) - &bfin_eth_device, -#endif - -#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) - &musb_device, -#endif - -#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE) - &bfin_isp1760_device, -#endif - -#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) -#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART - &bfin_sport0_uart_device, -#endif -#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART - &bfin_sport1_uart_device, -#endif -#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART - &bfin_sport2_uart_device, -#endif -#endif - -#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE) - &bfin_can0_device, -#endif - -#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) - &bfin_nand_device, -#endif - -#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN_MODULE) - &bfin_sdh_device, -#endif - -#if defined(CONFIG_SPI_BFIN6XX) || defined(CONFIG_SPI_BFIN6XX_MODULE) - &bf60x_spi_master0, - &bf60x_spi_master1, -#endif - -#if defined(CONFIG_INPUT_BFIN_ROTARY) || defined(CONFIG_INPUT_BFIN_ROTARY_MODULE) - &bfin_rotary_device, -#endif - -#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) - &i2c_bfin_twi0_device, -#if !defined(CONFIG_BF542) - &i2c_bfin_twi1_device, -#endif -#endif - -#if defined(CONFIG_BFIN_CRC) - &bfin_crc0_device, - &bfin_crc1_device, -#endif - -#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) - &bfin_device_gpiokeys, -#endif - -#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) - &ezkit_flash_device, -#endif -#if defined(CONFIG_SND_BF6XX_I2S) || defined(CONFIG_SND_BF6XX_I2S_MODULE) - &bfin_i2s_pcm, -#endif -#if defined(CONFIG_SND_BF6XX_SOC_I2S) || \ - defined(CONFIG_SND_BF6XX_SOC_I2S_MODULE) - &bfin_i2s, -#endif -#if defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61) || \ - defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61_MODULE) - &adau1761_device, -#endif -#if defined(CONFIG_VIDEO_BLACKFIN_CAPTURE) \ - || defined(CONFIG_VIDEO_BLACKFIN_CAPTURE_MODULE) - &bfin_capture_device, -#endif -}; - -static int __init ezkit_init(void) -{ - printk(KERN_INFO "%s(): registering device resources\n", __func__); - - i2c_register_board_info(0, bfin_i2c_board_info0, - ARRAY_SIZE(bfin_i2c_board_info0)); - i2c_register_board_info(1, bfin_i2c_board_info1, - ARRAY_SIZE(bfin_i2c_board_info1)); - -#if defined(CONFIG_STMMAC_ETH) || defined(CONFIG_STMMAC_ETH_MODULE) - if (!peripheral_request_list(pins, "emac0")) - printk(KERN_ERR "%s(): request emac pins failed\n", __func__); -#endif - - platform_add_devices(ezkit_devices, ARRAY_SIZE(ezkit_devices)); - - spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); - - return 0; -} - -arch_initcall(ezkit_init); - -static struct platform_device *ezkit_early_devices[] __initdata = { -#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) -#ifdef CONFIG_SERIAL_BFIN_UART0 - &bfin_uart0_device, -#endif -#ifdef CONFIG_SERIAL_BFIN_UART1 - &bfin_uart1_device, -#endif -#endif - -#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE) -#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART - &bfin_sport0_uart_device, -#endif -#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART - &bfin_sport1_uart_device, -#endif -#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART - &bfin_sport2_uart_device, -#endif -#endif -}; - -void __init native_machine_early_platform_add_devices(void) -{ - printk(KERN_INFO "register early platform devices\n"); - early_platform_add_devices(ezkit_early_devices, - ARRAY_SIZE(ezkit_early_devices)); -} diff --git a/trunk/arch/blackfin/mach-bf609/clock.c b/trunk/arch/blackfin/mach-bf609/clock.c deleted file mode 100644 index 7f8f529693ae..000000000000 --- a/trunk/arch/blackfin/mach-bf609/clock.c +++ /dev/null @@ -1,390 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define CGU0_CTL_DF (1 << 0) - -#define CGU0_CTL_MSEL_SHIFT 8 -#define CGU0_CTL_MSEL_MASK (0x7f << 8) - -#define CGU0_STAT_PLLEN (1 << 0) -#define CGU0_STAT_PLLBP (1 << 1) -#define CGU0_STAT_PLLLK (1 << 2) -#define CGU0_STAT_CLKSALGN (1 << 3) -#define CGU0_STAT_CCBF0 (1 << 4) -#define CGU0_STAT_CCBF1 (1 << 5) -#define CGU0_STAT_SCBF0 (1 << 6) -#define CGU0_STAT_SCBF1 (1 << 7) -#define CGU0_STAT_DCBF (1 << 8) -#define CGU0_STAT_OCBF (1 << 9) -#define CGU0_STAT_ADDRERR (1 << 16) -#define CGU0_STAT_LWERR (1 << 17) -#define CGU0_STAT_DIVERR (1 << 18) -#define CGU0_STAT_WDFMSERR (1 << 19) -#define CGU0_STAT_WDIVERR (1 << 20) -#define CGU0_STAT_PLOCKERR (1 << 21) - -#define CGU0_DIV_CSEL_SHIFT 0 -#define CGU0_DIV_CSEL_MASK 0x0000001F -#define CGU0_DIV_S0SEL_SHIFT 5 -#define CGU0_DIV_S0SEL_MASK (0x3 << CGU0_DIV_S0SEL_SHIFT) -#define CGU0_DIV_SYSSEL_SHIFT 8 -#define CGU0_DIV_SYSSEL_MASK (0x1f << CGU0_DIV_SYSSEL_SHIFT) -#define CGU0_DIV_S1SEL_SHIFT 13 -#define CGU0_DIV_S1SEL_MASK (0x3 << CGU0_DIV_S1SEL_SHIFT) -#define CGU0_DIV_DSEL_SHIFT 16 -#define CGU0_DIV_DSEL_MASK (0x1f << CGU0_DIV_DSEL_SHIFT) -#define CGU0_DIV_OSEL_SHIFT 22 -#define CGU0_DIV_OSEL_MASK (0x7f << CGU0_DIV_OSEL_SHIFT) - -#define CLK(_clk, _devname, _conname) \ - { \ - .clk = &_clk, \ - .dev_id = _devname, \ - .con_id = _conname, \ - } - -#define NEEDS_INITIALIZATION 0x11 - -static LIST_HEAD(clk_list); - -static void clk_reg_write_mask(u32 reg, uint32_t val, uint32_t mask) -{ - u32 val2; - - val2 = bfin_read32(reg); - val2 &= ~mask; - val2 |= val; - bfin_write32(reg, val2); -} - -static void clk_reg_set_bits(u32 reg, uint32_t mask) -{ - u32 val; - - val = bfin_read32(reg); - val |= mask; - bfin_write32(reg, val); -} - -static void clk_reg_clear_bits(u32 reg, uint32_t mask) -{ - u32 val; - - val = bfin_read32(reg); - val &= ~mask; - bfin_write32(reg, val); -} - -int wait_for_pll_align(void) -{ - int i = 10000; - while (i-- && (bfin_read32(CGU0_STAT) & CGU0_STAT_CLKSALGN)); - - if (bfin_read32(CGU0_STAT) & CGU0_STAT_CLKSALGN) { - printk(KERN_DEBUG "fail to align clk\n"); - return -1; - } - return 0; -} - -int clk_enable(struct clk *clk) -{ - int ret = -EIO; - if (clk->ops && clk->ops->enable) - ret = clk->ops->enable(clk); - return ret; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ - if (clk->ops && clk->ops->disable) - clk->ops->disable(clk); -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - unsigned long ret = 0; - if (clk->ops && clk->ops->get_rate) - ret = clk->ops->get_rate(clk); - return ret; -} -EXPORT_SYMBOL(clk_get_rate); - -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - long ret = -EIO; - if (clk->ops && clk->ops->round_rate) - ret = clk->ops->round_rate(clk, rate); - return ret; -} -EXPORT_SYMBOL(clk_round_rate); - -int clk_set_rate(struct clk *clk, unsigned long rate) -{ - int ret = -EIO; - if (clk->ops && clk->ops->set_rate) - ret = clk->ops->set_rate(clk, rate); - return ret; -} -EXPORT_SYMBOL(clk_set_rate); - -unsigned long vco_get_rate(struct clk *clk) -{ - return clk->rate; -} - -unsigned long pll_get_rate(struct clk *clk) -{ - u32 df; - u32 msel; - u32 ctl = bfin_read32(CGU0_CTL); - u32 stat = bfin_read32(CGU0_STAT); - if (stat & CGU0_STAT_PLLBP) - return 0; - msel = (ctl & CGU0_CTL_MSEL_MASK) >> CGU0_CTL_MSEL_SHIFT; - df = (ctl & CGU0_CTL_DF); - clk->parent->rate = clk_get_rate(clk->parent); - return clk->parent->rate / (df + 1) * msel * 2; -} - -unsigned long pll_round_rate(struct clk *clk, unsigned long rate) -{ - u32 div; - div = rate / clk->parent->rate; - return clk->parent->rate * div; -} - -int pll_set_rate(struct clk *clk, unsigned long rate) -{ - u32 msel; - u32 stat = bfin_read32(CGU0_STAT); - if (!(stat & CGU0_STAT_PLLEN)) - return -EBUSY; - if (!(stat & CGU0_STAT_PLLLK)) - return -EBUSY; - if (wait_for_pll_align()) - return -EBUSY; - msel = rate / clk->parent->rate / 2; - clk_reg_write_mask(CGU0_CTL, msel << CGU0_CTL_MSEL_SHIFT, - CGU0_CTL_MSEL_MASK); - clk->rate = rate; - return 0; -} - -unsigned long cclk_get_rate(struct clk *clk) -{ - if (clk->parent) - return clk->parent->rate; - else - return 0; -} - -unsigned long sys_clk_get_rate(struct clk *clk) -{ - unsigned long drate; - u32 msel; - u32 df; - u32 ctl = bfin_read32(CGU0_CTL); - u32 div = bfin_read32(CGU0_DIV); - div = (div & clk->mask) >> clk->shift; - msel = (ctl & CGU0_CTL_MSEL_MASK) >> CGU0_CTL_MSEL_SHIFT; - df = (ctl & CGU0_CTL_DF); - - if (!strcmp(clk->parent->name, "SYS_CLKIN")) { - drate = clk->parent->rate / (df + 1); - drate *= msel; - drate /= div; - return drate; - } else { - clk->parent->rate = clk_get_rate(clk->parent); - return clk->parent->rate / div; - } -} - -unsigned long sys_clk_round_rate(struct clk *clk, unsigned long rate) -{ - unsigned long max_rate; - unsigned long drate; - int i; - u32 msel; - u32 df; - u32 ctl = bfin_read32(CGU0_CTL); - - msel = (ctl & CGU0_CTL_MSEL_MASK) >> CGU0_CTL_MSEL_SHIFT; - df = (ctl & CGU0_CTL_DF); - max_rate = clk->parent->rate / (df + 1) * msel; - - if (rate > max_rate) - return 0; - - for (i = 1; i < clk->mask; i++) { - drate = max_rate / i; - if (rate >= drate) - return drate; - } - return 0; -} - -int sys_clk_set_rate(struct clk *clk, unsigned long rate) -{ - u32 div = bfin_read32(CGU0_DIV); - div = (div & clk->mask) >> clk->shift; - - rate = clk_round_rate(clk, rate); - - if (!rate) - return -EINVAL; - - div = (clk_get_rate(clk) * div) / rate; - - if (wait_for_pll_align()) - return -EBUSY; - clk_reg_write_mask(CGU0_DIV, div << clk->shift, - clk->mask); - clk->rate = rate; - return 0; -} - -static struct clk_ops vco_ops = { - .get_rate = vco_get_rate, -}; - -static struct clk_ops pll_ops = { - .get_rate = pll_get_rate, - .set_rate = pll_set_rate, -}; - -static struct clk_ops cclk_ops = { - .get_rate = cclk_get_rate, -}; - -static struct clk_ops sys_clk_ops = { - .get_rate = sys_clk_get_rate, - .set_rate = sys_clk_set_rate, - .round_rate = sys_clk_round_rate, -}; - -static struct clk sys_clkin = { - .name = "SYS_CLKIN", - .rate = CONFIG_CLKIN_HZ, - .ops = &vco_ops, -}; - -static struct clk pll_clk = { - .name = "PLLCLK", - .rate = 500000000, - .parent = &sys_clkin, - .ops = &pll_ops, - .flags = NEEDS_INITIALIZATION, -}; - -static struct clk cclk = { - .name = "CCLK", - .rate = 500000000, - .mask = CGU0_DIV_CSEL_MASK, - .shift = CGU0_DIV_CSEL_SHIFT, - .parent = &sys_clkin, - .ops = &sys_clk_ops, - .flags = NEEDS_INITIALIZATION, -}; - -static struct clk cclk0 = { - .name = "CCLK0", - .parent = &cclk, - .ops = &cclk_ops, -}; - -static struct clk cclk1 = { - .name = "CCLK1", - .parent = &cclk, - .ops = &cclk_ops, -}; - -static struct clk sysclk = { - .name = "SYSCLK", - .rate = 500000000, - .mask = CGU0_DIV_SYSSEL_MASK, - .shift = CGU0_DIV_SYSSEL_SHIFT, - .parent = &sys_clkin, - .ops = &sys_clk_ops, - .flags = NEEDS_INITIALIZATION, -}; - -static struct clk sclk0 = { - .name = "SCLK0", - .rate = 500000000, - .mask = CGU0_DIV_S0SEL_MASK, - .shift = CGU0_DIV_S0SEL_SHIFT, - .parent = &sysclk, - .ops = &sys_clk_ops, -}; - -static struct clk sclk1 = { - .name = "SCLK1", - .rate = 500000000, - .mask = CGU0_DIV_S1SEL_MASK, - .shift = CGU0_DIV_S1SEL_SHIFT, - .parent = &sysclk, - .ops = &sys_clk_ops, -}; - -static struct clk dclk = { - .name = "DCLK", - .rate = 500000000, - .mask = CGU0_DIV_DSEL_MASK, - .shift = CGU0_DIV_DSEL_SHIFT, - .parent = &sys_clkin, - .ops = &sys_clk_ops, -}; - -static struct clk oclk = { - .name = "OCLK", - .rate = 500000000, - .mask = CGU0_DIV_OSEL_MASK, - .shift = CGU0_DIV_OSEL_SHIFT, - .parent = &pll_clk, -}; - -static struct clk_lookup bf609_clks[] = { - CLK(sys_clkin, NULL, "SYS_CLKIN"), - CLK(pll_clk, NULL, "PLLCLK"), - CLK(cclk, NULL, "CCLK"), - CLK(cclk0, NULL, "CCLK0"), - CLK(cclk1, NULL, "CCLK1"), - CLK(sysclk, NULL, "SYSCLK"), - CLK(sclk0, NULL, "SCLK0"), - CLK(sclk1, NULL, "SCLK1"), - CLK(dclk, NULL, "DCLK"), - CLK(oclk, NULL, "OCLK"), -}; - -int __init clk_init(void) -{ - int i; - struct clk *clkp; - for (i = 0; i < ARRAY_SIZE(bf609_clks); i++) { - clkp = bf609_clks[i].clk; - if (clkp->flags & NEEDS_INITIALIZATION) - clk_get_rate(clkp); - } - clkdev_add_table(bf609_clks, ARRAY_SIZE(bf609_clks)); - return 0; -} diff --git a/trunk/arch/blackfin/mach-bf609/dma.c b/trunk/arch/blackfin/mach-bf609/dma.c deleted file mode 100644 index 1da4b38ac22c..000000000000 --- a/trunk/arch/blackfin/mach-bf609/dma.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * the simple DMA Implementation for Blackfin - * - * Copyright 2007-2009 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include - -#include -#include - -struct dma_register * const dma_io_base_addr[MAX_DMA_CHANNELS] = { - (struct dma_register *) DMA0_NEXT_DESC_PTR, - (struct dma_register *) DMA1_NEXT_DESC_PTR, - (struct dma_register *) DMA2_NEXT_DESC_PTR, - (struct dma_register *) DMA3_NEXT_DESC_PTR, - (struct dma_register *) DMA4_NEXT_DESC_PTR, - (struct dma_register *) DMA5_NEXT_DESC_PTR, - (struct dma_register *) DMA6_NEXT_DESC_PTR, - (struct dma_register *) DMA7_NEXT_DESC_PTR, - (struct dma_register *) DMA8_NEXT_DESC_PTR, - (struct dma_register *) DMA9_NEXT_DESC_PTR, - (struct dma_register *) DMA10_NEXT_DESC_PTR, - (struct dma_register *) DMA11_NEXT_DESC_PTR, - (struct dma_register *) DMA12_NEXT_DESC_PTR, - (struct dma_register *) DMA13_NEXT_DESC_PTR, - (struct dma_register *) DMA14_NEXT_DESC_PTR, - (struct dma_register *) DMA15_NEXT_DESC_PTR, - (struct dma_register *) DMA16_NEXT_DESC_PTR, - (struct dma_register *) DMA17_NEXT_DESC_PTR, - (struct dma_register *) DMA18_NEXT_DESC_PTR, - (struct dma_register *) DMA19_NEXT_DESC_PTR, - (struct dma_register *) DMA20_NEXT_DESC_PTR, - (struct dma_register *) MDMA0_SRC_CRC0_NEXT_DESC_PTR, - (struct dma_register *) MDMA0_DEST_CRC0_NEXT_DESC_PTR, - (struct dma_register *) MDMA1_SRC_CRC1_NEXT_DESC_PTR, - (struct dma_register *) MDMA1_DEST_CRC1_NEXT_DESC_PTR, - (struct dma_register *) MDMA2_SRC_NEXT_DESC_PTR, - (struct dma_register *) MDMA2_DEST_NEXT_DESC_PTR, - (struct dma_register *) MDMA3_SRC_NEXT_DESC_PTR, - (struct dma_register *) MDMA3_DEST_NEXT_DESC_PTR, - (struct dma_register *) DMA29_NEXT_DESC_PTR, - (struct dma_register *) DMA30_NEXT_DESC_PTR, - (struct dma_register *) DMA31_NEXT_DESC_PTR, - (struct dma_register *) DMA32_NEXT_DESC_PTR, - (struct dma_register *) DMA33_NEXT_DESC_PTR, - (struct dma_register *) DMA34_NEXT_DESC_PTR, - (struct dma_register *) DMA35_NEXT_DESC_PTR, - (struct dma_register *) DMA36_NEXT_DESC_PTR, - (struct dma_register *) DMA37_NEXT_DESC_PTR, - (struct dma_register *) DMA38_NEXT_DESC_PTR, - (struct dma_register *) DMA39_NEXT_DESC_PTR, - (struct dma_register *) DMA40_NEXT_DESC_PTR, - (struct dma_register *) DMA41_NEXT_DESC_PTR, - (struct dma_register *) DMA42_NEXT_DESC_PTR, - (struct dma_register *) DMA43_NEXT_DESC_PTR, - (struct dma_register *) DMA44_NEXT_DESC_PTR, - (struct dma_register *) DMA45_NEXT_DESC_PTR, - (struct dma_register *) DMA46_NEXT_DESC_PTR, -}; -EXPORT_SYMBOL(dma_io_base_addr); - -int channel2irq(unsigned int channel) -{ - int ret_irq = -1; - - switch (channel) { - case CH_SPORT0_RX: - ret_irq = IRQ_SPORT0_RX; - break; - case CH_SPORT0_TX: - ret_irq = IRQ_SPORT0_TX; - break; - case CH_SPORT1_RX: - ret_irq = IRQ_SPORT1_RX; - break; - case CH_SPORT1_TX: - ret_irq = IRQ_SPORT1_TX; - break; - case CH_SPORT2_RX: - ret_irq = IRQ_SPORT2_RX; - break; - case CH_SPORT2_TX: - ret_irq = IRQ_SPORT2_TX; - break; - case CH_SPI0_TX: - ret_irq = IRQ_SPI0_TX; - break; - case CH_SPI0_RX: - ret_irq = IRQ_SPI0_RX; - break; - case CH_SPI1_TX: - ret_irq = IRQ_SPI1_TX; - break; - case CH_SPI1_RX: - ret_irq = IRQ_SPI1_RX; - break; - case CH_RSI: - ret_irq = IRQ_RSI; - break; - case CH_SDU: - ret_irq = IRQ_SDU; - break; - case CH_LP0: - ret_irq = IRQ_LP0; - break; - case CH_LP1: - ret_irq = IRQ_LP1; - break; - case CH_LP2: - ret_irq = IRQ_LP2; - break; - case CH_LP3: - ret_irq = IRQ_LP3; - break; - case CH_UART0_RX: - ret_irq = IRQ_UART0_RX; - break; - case CH_UART0_TX: - ret_irq = IRQ_UART0_TX; - break; - case CH_UART1_RX: - ret_irq = IRQ_UART1_RX; - break; - case CH_UART1_TX: - ret_irq = IRQ_UART1_TX; - break; - case CH_EPPI0_CH0: - ret_irq = IRQ_EPPI0_CH0; - break; - case CH_EPPI0_CH1: - ret_irq = IRQ_EPPI0_CH1; - break; - case CH_EPPI1_CH0: - ret_irq = IRQ_EPPI1_CH0; - break; - case CH_EPPI1_CH1: - ret_irq = IRQ_EPPI1_CH1; - break; - case CH_EPPI2_CH0: - ret_irq = IRQ_EPPI2_CH0; - break; - case CH_EPPI2_CH1: - ret_irq = IRQ_EPPI2_CH1; - break; - case CH_PIXC_CH0: - ret_irq = IRQ_PIXC_CH0; - break; - case CH_PIXC_CH1: - ret_irq = IRQ_PIXC_CH1; - break; - case CH_PIXC_CH2: - ret_irq = IRQ_PIXC_CH2; - break; - case CH_PVP_CPDOB: - ret_irq = IRQ_PVP_CPDOB; - break; - case CH_PVP_CPDOC: - ret_irq = IRQ_PVP_CPDOC; - break; - case CH_PVP_CPSTAT: - ret_irq = IRQ_PVP_CPSTAT; - break; - case CH_PVP_CPCI: - ret_irq = IRQ_PVP_CPCI; - break; - case CH_PVP_MPDO: - ret_irq = IRQ_PVP_MPDO; - break; - case CH_PVP_MPDI: - ret_irq = IRQ_PVP_MPDI; - break; - case CH_PVP_MPSTAT: - ret_irq = IRQ_PVP_MPSTAT; - break; - case CH_PVP_MPCI: - ret_irq = IRQ_PVP_MPCI; - break; - case CH_PVP_CPDOA: - ret_irq = IRQ_PVP_CPDOA; - break; - case CH_MEM_STREAM0_SRC: - case CH_MEM_STREAM0_DEST: - ret_irq = IRQ_MDMAS0; - break; - case CH_MEM_STREAM1_SRC: - case CH_MEM_STREAM1_DEST: - ret_irq = IRQ_MDMAS1; - break; - case CH_MEM_STREAM2_SRC: - case CH_MEM_STREAM2_DEST: - ret_irq = IRQ_MDMAS2; - break; - case CH_MEM_STREAM3_SRC: - case CH_MEM_STREAM3_DEST: - ret_irq = IRQ_MDMAS3; - break; - } - return ret_irq; -} diff --git a/trunk/arch/blackfin/mach-bf609/hibernate.S b/trunk/arch/blackfin/mach-bf609/hibernate.S deleted file mode 100644 index d37a532519c8..000000000000 --- a/trunk/arch/blackfin/mach-bf609/hibernate.S +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include -#include - -#define PM_STACK (COREA_L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12) - -.section .l1.text -ENTRY(_enter_hibernate) - /* switch stack to L1 scratch, prepare for ddr srfr */ - P0.H = HI(PM_STACK); - P0.L = LO(PM_STACK); - SP = P0; - - call _bf609_ddr_sr; - call _bfin_hibernate_syscontrol; - - P0.H = HI(DPM0_RESTORE4); - P0.L = LO(DPM0_RESTORE4); - P1.H = _bf609_pm_data; - P1.L = _bf609_pm_data; - [P0] = P1; - - P0.H = HI(DPM0_CTL); - P0.L = LO(DPM0_CTL); - R3.H = HI(0x00000010); - R3.L = LO(0x00000010); - - bfin_init_pm_bench_cycles; - - [P0] = R3; - - SSYNC; -ENDPROC(_enter_hibernate_mode) - -.section .text -ENTRY(_bf609_hibernate) - bfin_cpu_reg_save; - bfin_core_mmr_save; - - P0.H = _bf609_pm_data; - P0.L = _bf609_pm_data; - R1.H = 0xDEAD; - R1.L = 0xBEEF; - R2.H = .Lpm_resume_here; - R2.L = .Lpm_resume_here; - [P0++] = R1; - [P0++] = R2; - [P0++] = SP; - - P1.H = _enter_hibernate; - P1.L = _enter_hibernate; - - call (P1); -.Lpm_resume_here: - - bfin_core_mmr_restore; - bfin_cpu_reg_restore; - - [--sp] = RETI; /* Clear Global Interrupt Disable */ - SP += 4; - - RTS; - -ENDPROC(_bf609_hibernate) - diff --git a/trunk/arch/blackfin/mach-bf609/include/mach/anomaly.h b/trunk/arch/blackfin/mach-bf609/include/mach/anomaly.h deleted file mode 100644 index bdd39aefb565..000000000000 --- a/trunk/arch/blackfin/mach-bf609/include/mach/anomaly.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * DO NOT EDIT THIS FILE - * This file is under version control at - * svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/ - * and can be replaced with that version at any time - * DO NOT EDIT THIS FILE - * - * Copyright 2004-2011 Analog Devices Inc. - * Licensed under the Clear BSD license. - */ - -/* This file should be up to date with: - */ - -#if __SILICON_REVISION__ < 0 -# error will not work on BF506 silicon version -#endif - -#ifndef _MACH_ANOMALY_H_ -#define _MACH_ANOMALY_H_ - -/* Multi-Issue Instruction with dsp32shiftimm in slot1 and P-reg Store in slot2 Not Supported */ -#define ANOMALY_05000074 (1) -/* DMA_RUN Bit Is Not Valid after a Peripheral Receive Channel DMA Stops */ -#define ANOMALY_05000119 (1) -/* Rx.H Cannot Be Used to Access 16-bit System MMR Registers */ -#define ANOMALY_05000122 (1) -/* False Hardware Error from an Access in the Shadow of a Conditional Branch */ -#define ANOMALY_05000245 (1) -/* Incorrect Timer Pulse Width in Single-Shot PWM_OUT Mode with External Clock */ -#define ANOMALY_05000254 (1) -/* Sensitivity To Noise with Slow Input Edge Rates on External SPORT TX and RX Clocks */ -#define ANOMALY_05000265 (1) -/* False Hardware Errors Caused by Fetches at the Boundary of Reserved Memory */ -#define ANOMALY_05000310 (1) -/* PPI Underflow Error Goes Undetected in ITU-R 656 Mode */ -#define ANOMALY_05000366 (1) -/* Speculative Fetches Can Cause Undesired External FIFO Operations */ -#define ANOMALY_05000416 (1) -/* Speculative Fetches of Indirect-Pointer Instructions Can Cause False Hardware Errors */ -#define ANOMALY_05000426 (1) -/* IFLUSH Instruction at End of Hardware Loop Causes Infinite Stall */ -#define ANOMALY_05000443 (1) -/* UART IrDA Receiver Fails on Extended Bit Pulses */ -#define ANOMALY_05000447 (1) -/* False Hardware Error when RETI Points to Invalid Memory */ -#define ANOMALY_05000461 (1) -/* PLL Latches Incorrect Settings During Reset */ -#define ANOMALY_05000469 (1) -/* Incorrect Default MSEL Value in PLL_CTL */ -#define ANOMALY_05000472 (1) -/* Interrupted SPORT Receive Data Register Read Results In Underflow when SLEN > 15 */ -#define ANOMALY_05000473 (1) -/* TESTSET Instruction Cannot Be Interrupted */ -#define ANOMALY_05000477 (1) -/* Reads of ITEST_COMMAND and ITEST_DATA Registers Cause Cache Corruption */ -#define ANOMALY_05000481 (1) -/* IFLUSH sucks at life */ -#define ANOMALY_05000491 (1) -/* Tempopary anomaly ID for data loss in MMR read operation if interrupted */ -#define ANOMALY_05001001 (__SILICON_REVISION__ < 1) - -/* Anomalies that don't exist on this proc */ -#define ANOMALY_05000099 (0) -#define ANOMALY_05000120 (0) -#define ANOMALY_05000125 (0) -#define ANOMALY_05000149 (0) -#define ANOMALY_05000158 (0) -#define ANOMALY_05000171 (0) -#define ANOMALY_05000179 (0) -#define ANOMALY_05000182 (0) -#define ANOMALY_05000183 (0) -#define ANOMALY_05000189 (0) -#define ANOMALY_05000198 (0) -#define ANOMALY_05000202 (0) -#define ANOMALY_05000215 (0) -#define ANOMALY_05000219 (0) -#define ANOMALY_05000220 (0) -#define ANOMALY_05000227 (0) -#define ANOMALY_05000230 (0) -#define ANOMALY_05000231 (0) -#define ANOMALY_05000233 (0) -#define ANOMALY_05000234 (0) -#define ANOMALY_05000242 (0) -#define ANOMALY_05000244 (0) -#define ANOMALY_05000248 (0) -#define ANOMALY_05000250 (0) -#define ANOMALY_05000257 (0) -#define ANOMALY_05000261 (0) -#define ANOMALY_05000263 (0) -#define ANOMALY_05000266 (0) -#define ANOMALY_05000273 (0) -#define ANOMALY_05000274 (0) -#define ANOMALY_05000278 (0) -#define ANOMALY_05000281 (0) -#define ANOMALY_05000283 (0) -#define ANOMALY_05000285 (0) -#define ANOMALY_05000287 (0) -#define ANOMALY_05000301 (0) -#define ANOMALY_05000305 (0) -#define ANOMALY_05000307 (0) -#define ANOMALY_05000311 (0) -#define ANOMALY_05000312 (0) -#define ANOMALY_05000315 (0) -#define ANOMALY_05000323 (0) -#define ANOMALY_05000353 (1) -#define ANOMALY_05000357 (0) -#define ANOMALY_05000362 (1) -#define ANOMALY_05000363 (0) -#define ANOMALY_05000364 (0) -#define ANOMALY_05000371 (0) -#define ANOMALY_05000380 (0) -#define ANOMALY_05000386 (0) -#define ANOMALY_05000389 (0) -#define ANOMALY_05000400 (0) -#define ANOMALY_05000402 (0) -#define ANOMALY_05000412 (0) -#define ANOMALY_05000432 (0) -#define ANOMALY_05000440 (0) -#define ANOMALY_05000448 (0) -#define ANOMALY_05000456 (0) -#define ANOMALY_05000450 (0) -#define ANOMALY_05000465 (0) -#define ANOMALY_05000467 (0) -#define ANOMALY_05000474 (0) -#define ANOMALY_05000475 (0) -#define ANOMALY_05000480 (0) -#define ANOMALY_05000485 (0) - -#endif diff --git a/trunk/arch/blackfin/mach-bf609/include/mach/bf609.h b/trunk/arch/blackfin/mach-bf609/include/mach/bf609.h deleted file mode 100644 index c897c2a2fbfa..000000000000 --- a/trunk/arch/blackfin/mach-bf609/include/mach/bf609.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#ifndef __MACH_BF609_H__ -#define __MACH_BF609_H__ - -#define OFFSET_(x) ((x) & 0x0000FFFF) - -/*some misc defines*/ -#define IMASK_IVG15 0x8000 -#define IMASK_IVG14 0x4000 -#define IMASK_IVG13 0x2000 -#define IMASK_IVG12 0x1000 - -#define IMASK_IVG11 0x0800 -#define IMASK_IVG10 0x0400 -#define IMASK_IVG9 0x0200 -#define IMASK_IVG8 0x0100 - -#define IMASK_IVG7 0x0080 -#define IMASK_IVGTMR 0x0040 -#define IMASK_IVGHW 0x0020 - -/***************************/ - - -#define BFIN_DSUBBANKS 4 -#define BFIN_DWAYS 2 -#define BFIN_DLINES 64 -#define BFIN_ISUBBANKS 4 -#define BFIN_IWAYS 4 -#define BFIN_ILINES 32 - -#define WAY0_L 0x1 -#define WAY1_L 0x2 -#define WAY01_L 0x3 -#define WAY2_L 0x4 -#define WAY02_L 0x5 -#define WAY12_L 0x6 -#define WAY012_L 0x7 - -#define WAY3_L 0x8 -#define WAY03_L 0x9 -#define WAY13_L 0xA -#define WAY013_L 0xB - -#define WAY32_L 0xC -#define WAY320_L 0xD -#define WAY321_L 0xE -#define WAYALL_L 0xF - -#define DMC_ENABLE (2<<2) /*yes, 2, not 1 */ - -/********************************* EBIU Settings ************************************/ -#define AMBCTL0VAL ((CONFIG_BANK_1 << 16) | CONFIG_BANK_0) -#define AMBCTL1VAL ((CONFIG_BANK_3 << 16) | CONFIG_BANK_2) - -#ifdef CONFIG_C_AMBEN_ALL -#define V_AMBEN AMBEN_ALL -#endif -#ifdef CONFIG_C_AMBEN -#define V_AMBEN 0x0 -#endif -#ifdef CONFIG_C_AMBEN_B0 -#define V_AMBEN AMBEN_B0 -#endif -#ifdef CONFIG_C_AMBEN_B0_B1 -#define V_AMBEN AMBEN_B0_B1 -#endif -#ifdef CONFIG_C_AMBEN_B0_B1_B2 -#define V_AMBEN AMBEN_B0_B1_B2 -#endif -#ifdef CONFIG_C_AMCKEN -#define V_AMCKEN AMCKEN -#else -#define V_AMCKEN 0x0 -#endif - -#define AMGCTLVAL (V_AMBEN | V_AMCKEN) - -#if defined(CONFIG_BF609) -# define CPU "BF609" -# define CPUID 0x27fe /* temperary fake value */ -#endif - -#ifndef CPU -#error "Unknown CPU type - This kernel doesn't seem to be configured properly" -#endif - -#endif /* __MACH_BF609_H__ */ diff --git a/trunk/arch/blackfin/mach-bf609/include/mach/bfin_serial.h b/trunk/arch/blackfin/mach-bf609/include/mach/bfin_serial.h deleted file mode 100644 index 1fd398147fd9..000000000000 --- a/trunk/arch/blackfin/mach-bf609/include/mach/bfin_serial.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * mach/bfin_serial.h - Blackfin UART/Serial definitions - * - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#ifndef __BFIN_MACH_SERIAL_H__ -#define __BFIN_MACH_SERIAL_H__ - -#define BFIN_UART_NR_PORTS 2 -#define BFIN_UART_TX_FIFO_SIZE 8 - -#define BFIN_UART_BF60X_STYLE - -#endif diff --git a/trunk/arch/blackfin/mach-bf609/include/mach/blackfin.h b/trunk/arch/blackfin/mach-bf609/include/mach/blackfin.h deleted file mode 100644 index b1a48c410711..000000000000 --- a/trunk/arch/blackfin/mach-bf609/include/mach/blackfin.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#ifndef _MACH_BLACKFIN_H_ -#define _MACH_BLACKFIN_H_ - -#include "bf609.h" -#include "anomaly.h" - -#include -#ifdef CONFIG_BF609 -# include "defBF609.h" -#endif - -#ifndef __ASSEMBLY__ -# include -# ifdef CONFIG_BF609 -# include "cdefBF609.h" -# endif -#endif - -#endif diff --git a/trunk/arch/blackfin/mach-bf609/include/mach/cdefBF609.h b/trunk/arch/blackfin/mach-bf609/include/mach/cdefBF609.h deleted file mode 100644 index c4f3fe19acda..000000000000 --- a/trunk/arch/blackfin/mach-bf609/include/mach/cdefBF609.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#ifndef _CDEF_BF609_H -#define _CDEF_BF609_H - -/* include cdefBF60x_base.h for the set of #defines that are common to all ADSP-BF60x bfin_read_()rocessors */ -#include "cdefBF60x_base.h" - -/* The following are the #defines needed by ADSP-BF609 that are not in the common header */ - -#endif /* _CDEF_BF609_H */ diff --git a/trunk/arch/blackfin/mach-bf609/include/mach/cdefBF60x_base.h b/trunk/arch/blackfin/mach-bf609/include/mach/cdefBF60x_base.h deleted file mode 100644 index 4954cf3f7e16..000000000000 --- a/trunk/arch/blackfin/mach-bf609/include/mach/cdefBF60x_base.h +++ /dev/null @@ -1,3252 +0,0 @@ -/* - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#ifndef _CDEF_BF60X_H -#define _CDEF_BF60X_H - -/* ************************************************************** */ -/* SYSTEM & MMR ADDRESS DEFINITIONS COMMON TO ALL ADSP-BF60x */ -/* ************************************************************** */ - -/* Debug/MP/Emulation Registers (0xFFC00014 - 0xFFC00014) */ - -#define bfin_read_CHIPID() bfin_read32(CHIPID) -#define bfin_write_CHIPID(val) bfin_write32(CHIPID, val) - -/* System Reset and Interrubfin_read_()t Controller (0xFFC00100 - 0xFFC00104) */ - -/* SEC0 Registers */ -#define bfin_read_SEC0_CCTL() bfin_read32(SEC0_CCTL) -#define bfin_write_SEC0_CCTL(val) bfin_write32(SEC0_CCTL, val) -#define bfin_read_SEC0_CSID() bfin_read32(SEC0_CSID) -#define bfin_write_SEC0_CSID(val) bfin_write32(SEC0_CSID, val) -#define bfin_read_SEC_GCTL() bfin_read32(SEC_GCTL) -#define bfin_write_SEC_GCTL(val) bfin_write32(SEC_GCTL, val) - -#define bfin_read_SEC_FCTL() bfin_read32(SEC_FCTL) -#define bfin_write_SEC_FCTL(val) bfin_write32(SEC_FCTL, val) - -#define bfin_read_SEC_SCTL(sid) bfin_read32((SEC_SCTL0 + (sid) * 8)) -#define bfin_write_SEC_SCTL(sid, val) bfin_write32((SEC_SCTL0 + (sid) * 8), val) - -#define bfin_read_SEC_SSTAT(sid) bfin_read32((SEC_SSTAT0 + (sid) * 8)) -#define bfin_write_SEC_SSTAT(sid, val) bfin_write32((SEC_SSTAT0 + (sid) * 8), val) - -/* RCU0 Registers */ -#define bfin_read_RCU0_CTL() bfin_read32(RCU0_CTL) -#define bfin_write_RCU0_CTL(val) bfin_write32(RCU0_CTL, val) - -/* Watchdog Timer Registers */ -#define bfin_read_WDOG_CTL() bfin_read16(WDOG_CTL) -#define bfin_write_WDOG_CTL(val) bfin_write16(WDOG_CTL, val) -#define bfin_read_WDOG_CNT() bfin_read32(WDOG_CNT) -#define bfin_write_WDOG_CNT(val) bfin_write32(WDOG_CNT, val) -#define bfin_read_WDOG_STAT() bfin_read32(WDOG_STAT) -#define bfin_write_WDOG_STAT(val) bfin_write32(WDOG_STAT, val) - -/* RTC Registers */ - -/* UART0 Registers */ - -#define bfin_read_UART0_REVID() bfin_read32(UART0_REVID) -#define bfin_write_UART0_REVID(val) bfin_write32(UART0_REVID, val) -#define bfin_read_UART0_GCTL() bfin_read32(UART0_GCTL) -#define bfin_write_UART0_GCTL(val) bfin_write32(UART0_GCTL, val) -#define bfin_read_UART0_STAT() bfin_read32(UART0_STAT) -#define bfin_write_UART0_STAT(val) bfin_write32(UART0_STAT, val) -#define bfin_read_UART0_SCR() bfin_read32(UART0_SCR) -#define bfin_write_UART0_SCR(val) bfin_write32(UART0_SCR, val) -#define bfin_read_UART0_CLK() bfin_read32(UART0_CLK) -#define bfin_write_UART0_CLK(val) bfin_write32(UART0_CLK, val) -#define bfin_read_UART0_IER() bfin_read32(UART0_IER) -#define bfin_write_UART0_IER(val) bfin_write32(UART0_IER, val) -#define bfin_read_UART0_IER_SET() bfin_read32(UART0_IER_SET) -#define bfin_write_UART0_IER_SET(val) bfin_write32(UART0_IER_SET, val) -#define bfin_read_UART0_IER_CLEAR() bfin_read32(UART0_IER_CLEAR) -#define bfin_write_UART0_IER_CLEAR(val) bfin_write32(UART0_IER_CLEAR, val) -#define bfin_read_UART0_RBR() bfin_read32(UART0_RBR) -#define bfin_write_UART0_RBR(val) bfin_write32(UART0_RBR, val) -#define bfin_read_UART0_THR() bfin_read32(UART0_THR) -#define bfin_write_UART0_THR(val) bfin_write32(UART0_THR, val) -#define bfin_read_UART0_TAIP() bfin_read32(UART0_TAIP) -#define bfin_write_UART0_TAIP(val) bfin_write32(UART0_TAIP, val) -#define bfin_read_UART0_TSR() bfin_read32(UART0_TSR) -#define bfin_write_UART0_TSR(val) bfin_write32(UART0_TSR, val) -#define bfin_read_UART0_RSR() bfin_read32(UART0_RSR) -#define bfin_write_UART0_RSR(val) bfin_write32(UART0_RSR, val) -#define bfin_read_UART0_TXCNT() bfin_read32(UART0_TXCNT) -#define bfin_write_UART0_TXCNT(val) bfin_write32(UART0_TXCNT, val) -#define bfin_read_UART0_RXCNT() bfin_read32(UART0_RXCNT) -#define bfin_write_UART0_RXCNT(val) bfin_write32(UART0_RXCNT, val) - -/* UART1 Registers */ - -#define bfin_read_UART1_REVID() bfin_read32(UART1_REVID) -#define bfin_write_UART1_REVID(val) bfin_write32(UART1_REVID, val) -#define bfin_read_UART1_GCTL() bfin_read32(UART1_GCTL) -#define bfin_write_UART1_GCTL(val) bfin_write32(UART1_GCTL, val) -#define bfin_read_UART1_STAT() bfin_read32(UART1_STAT) -#define bfin_write_UART1_STAT(val) bfin_write32(UART1_STAT, val) -#define bfin_read_UART1_SCR() bfin_read32(UART1_SCR) -#define bfin_write_UART1_SCR(val) bfin_write32(UART1_SCR, val) -#define bfin_read_UART1_CLK() bfin_read32(UART1_CLK) -#define bfin_write_UART1_CLK(val) bfin_write32(UART1_CLK, val) -#define bfin_read_UART1_IER() bfin_read32(UART1_IER) -#define bfin_write_UART1_IER(val) bfin_write32(UART1_IER, val) -#define bfin_read_UART1_IER_SET() bfin_read32(UART1_IER_SET) -#define bfin_write_UART1_IER_SET(val) bfin_write32(UART1_IER_SET, val) -#define bfin_read_UART1_IER_CLEAR() bfin_read32(UART1_IER_CLEAR) -#define bfin_write_UART1_IER_CLEAR(val) bfin_write32(UART1_IER_CLEAR, val) -#define bfin_read_UART1_RBR() bfin_read32(UART1_RBR) -#define bfin_write_UART1_RBR(val) bfin_write32(UART1_RBR, val) -#define bfin_read_UART1_THR() bfin_read32(UART1_THR) -#define bfin_write_UART1_THR(val) bfin_write32(UART1_THR, val) -#define bfin_read_UART1_TAIP() bfin_read32(UART1_TAIP) -#define bfin_write_UART1_TAIP(val) bfin_write32(UART1_TAIP, val) -#define bfin_read_UART1_TSR() bfin_read32(UART1_TSR) -#define bfin_write_UART1_TSR(val) bfin_write32(UART1_TSR, val) -#define bfin_read_UART1_RSR() bfin_read32(UART1_RSR) -#define bfin_write_UART1_RSR(val) bfin_write32(UART1_RSR, val) -#define bfin_read_UART1_TXCNT() bfin_read32(UART1_TXCNT) -#define bfin_write_UART1_TXCNT(val) bfin_write32(UART1_TXCNT, val) -#define bfin_read_UART1_RXCNT() bfin_read32(UART1_RXCNT) -#define bfin_write_UART1_RXCNT(val) bfin_write32(UART1_RXCNT, val) - - -/* SPI0 Registers */ - -#define bfin_read_SPI0_CTL() bfin_read32(SPI0_CTL) -#define bfin_write_SPI0_CTL(val) bfin_write32(SPI0_CTL, val) -#define bfin_read_SPI0_RXCTL() bfin_read32(SPI0_RXCTL) -#define bfin_write_SPI0_RXCTL(val) bfin_write32(SPI0_RXCTL, val) -#define bfin_read_SPI0_TXCTL() bfin_read32(SPI0_TXCTL) -#define bfin_write_SPI0_TXCTL(val) bfin_write32(SPI0_TXCTL, val) -#define bfin_read_SPI0_CLK() bfin_read32(SPI0_CLK) -#define bfin_write_SPI0_CLK(val) bfin_write32(SPI0_CLK, val) -#define bfin_read_SPI0_DLY() bfin_read32(SPI0_DLY) -#define bfin_write_SPI0_DLY(val) bfin_write32(SPI0_DLY, val) -#define bfin_read_SPI0_SLVSEL() bfin_read32(SPI0_SLVSEL) -#define bfin_write_SPI0_SLVSEL(val) bfin_write32(SPI0_SLVSEL, val) -#define bfin_read_SPI0_RWC() bfin_read32(SPI0_RWC) -#define bfin_write_SPI0_RWC(val) bfin_write32(SPI0_RWC, val) -#define bfin_read_SPI0_RWCR() bfin_read32(SPI0_RWCR) -#define bfin_write_SPI0_RWCR(val) bfin_write32(SPI0_RWCR, val) -#define bfin_read_SPI0_TWC() bfin_read32(SPI0_TWC) -#define bfin_write_SPI0_TWC(val) bfin_write32(SPI0_TWC, val) -#define bfin_read_SPI0_TWCR() bfin_read32(SPI0_TWCR) -#define bfin_write_SPI0_TWCR(val) bfin_write32(SPI0_TWCR, val) -#define bfin_read_SPI0_IMSK() bfin_read32(SPI0_IMSK) -#define bfin_write_SPI0_IMSK(val) bfin_write32(SPI0_IMSK, val) -#define bfin_read_SPI0_IMSK_CLR() bfin_read32(SPI0_IMSK_CLR) -#define bfin_write_SPI0_IMSK_CLR(val) bfin_write32(SPI0_IMSK_CLR, val) -#define bfin_read_SPI0_IMSK_SET() bfin_read32(SPI0_IMSK_SET) -#define bfin_write_SPI0_IMSK_SET(val) bfin_write32(SPI0_IMSK_SET, val) -#define bfin_read_SPI0_STAT() bfin_read32(SPI0_STAT) -#define bfin_write_SPI0_STAT(val) bfin_write32(SPI0_STAT, val) -#define bfin_read_SPI0_ILAT() bfin_read32(SPI0_ILAT) -#define bfin_write_SPI0_ILAT(val) bfin_write32(SPI0_ILAT, val) -#define bfin_read_SPI0_ILAT_CLR() bfin_read32(SPI0_ILAT_CLR) -#define bfin_write_SPI0_ILAT_CLR(val) bfin_write32(SPI0_ILAT_CLR, val) -#define bfin_read_SPI0_RFIFO() bfin_read32(SPI0_RFIFO) -#define bfin_write_SPI0_RFIFO(val) bfin_write32(SPI0_RFIFO, val) -#define bfin_read_SPI0_TFIFO() bfin_read32(SPI0_TFIFO) -#define bfin_write_SPI0_TFIFO(val) bfin_write32(SPI0_TFIFO, val) - -/* SPI1 Registers */ - -#define bfin_read_SPI1_CTL() bfin_read32(SPI1_CTL) -#define bfin_write_SPI1_CTL(val) bfin_write32(SPI1_CTL, val) -#define bfin_read_SPI1_RXCTL() bfin_read32(SPI1_RXCTL) -#define bfin_write_SPI1_RXCTL(val) bfin_write32(SPI1_RXCTL, val) -#define bfin_read_SPI1_TXCTL() bfin_read32(SPI1_TXCTL) -#define bfin_write_SPI1_TXCTL(val) bfin_write32(SPI1_TXCTL, val) -#define bfin_read_SPI1_CLK() bfin_read32(SPI1_CLK) -#define bfin_write_SPI1_CLK(val) bfin_write32(SPI1_CLK, val) -#define bfin_read_SPI1_DLY() bfin_read32(SPI1_DLY) -#define bfin_write_SPI1_DLY(val) bfin_write32(SPI1_DLY, val) -#define bfin_read_SPI1_SLVSEL() bfin_read32(SPI1_SLVSEL) -#define bfin_write_SPI1_SLVSEL(val) bfin_write32(SPI1_SLVSEL, val) -#define bfin_read_SPI1_RWC() bfin_read32(SPI1_RWC) -#define bfin_write_SPI1_RWC(val) bfin_write32(SPI1_RWC, val) -#define bfin_read_SPI1_RWCR() bfin_read32(SPI1_RWCR) -#define bfin_write_SPI1_RWCR(val) bfin_write32(SPI1_RWCR, val) -#define bfin_read_SPI1_TWC() bfin_read32(SPI1_TWC) -#define bfin_write_SPI1_TWC(val) bfin_write32(SPI1_TWC, val) -#define bfin_read_SPI1_TWCR() bfin_read32(SPI1_TWCR) -#define bfin_write_SPI1_TWCR(val) bfin_write32(SPI1_TWCR, val) -#define bfin_read_SPI1_IMSK() bfin_read32(SPI1_IMSK) -#define bfin_write_SPI1_IMSK(val) bfin_write32(SPI1_IMSK, val) -#define bfin_read_SPI1_IMSK_CLR() bfin_read32(SPI1_IMSK_CLR) -#define bfin_write_SPI1_IMSK_CLR(val) bfin_write32(SPI1_IMSK_CLR, val) -#define bfin_read_SPI1_IMSK_SET() bfin_read32(SPI1_IMSK_SET) -#define bfin_write_SPI1_IMSK_SET(val) bfin_write32(SPI1_IMSK_SET, val) -#define bfin_read_SPI1_STAT() bfin_read32(SPI1_STAT) -#define bfin_write_SPI1_STAT(val) bfin_write32(SPI1_STAT, val) -#define bfin_read_SPI1_ILAT() bfin_read32(SPI1_ILAT) -#define bfin_write_SPI1_ILAT(val) bfin_write32(SPI1_ILAT, val) -#define bfin_read_SPI1_ILAT_CLR() bfin_read32(SPI1_ILAT_CLR) -#define bfin_write_SPI1_ILAT_CLR(val) bfin_write32(SPI1_ILAT_CLR, val) -#define bfin_read_SPI1_RFIFO() bfin_read32(SPI1_RFIFO) -#define bfin_write_SPI1_RFIFO(val) bfin_write32(SPI1_RFIFO, val) -#define bfin_read_SPI1_TFIFO() bfin_read32(SPI1_TFIFO) -#define bfin_write_SPI1_TFIFO(val) bfin_write32(SPI1_TFIFO, val) - -/* Timer 0-7 registers */ -#define bfin_read_TIMER0_CONFIG() bfin_read16(TIMER0_CONFIG) -#define bfin_write_TIMER0_CONFIG(val) bfin_write16(TIMER0_CONFIG, val) -#define bfin_read_TIMER0_COUNTER() bfin_read32(TIMER0_COUNTER) -#define bfin_write_TIMER0_COUNTER(val) bfin_write32(TIMER0_COUNTER, val) -#define bfin_read_TIMER0_PERIOD() bfin_read32(TIMER0_PERIOD) -#define bfin_write_TIMER0_PERIOD(val) bfin_write32(TIMER0_PERIOD, val) -#define bfin_read_TIMER0_WIDTH() bfin_read32(TIMER0_WIDTH) -#define bfin_write_TIMER0_WIDTH(val) bfin_write32(TIMER0_WIDTH, val) -#define bfin_read_TIMER1_CONFIG() bfin_read16(TIMER1_CONFIG) -#define bfin_write_TIMER1_CONFIG(val) bfin_write16(TIMER1_CONFIG, val) -#define bfin_read_TIMER1_COUNTER() bfin_read32(TIMER1_COUNTER) -#define bfin_write_TIMER1_COUNTER(val) bfin_write32(TIMER1_COUNTER, val) -#define bfin_read_TIMER1_PERIOD() bfin_read32(TIMER1_PERIOD) -#define bfin_write_TIMER1_PERIOD(val) bfin_write32(TIMER1_PERIOD, val) -#define bfin_read_TIMER1_WIDTH() bfin_read32(TIMER1_WIDTH) -#define bfin_write_TIMER1_WIDTH(val) bfin_write32(TIMER1_WIDTH, val) -#define bfin_read_TIMER2_CONFIG() bfin_read16(TIMER2_CONFIG) -#define bfin_write_TIMER2_CONFIG(val) bfin_write16(TIMER2_CONFIG, val) -#define bfin_read_TIMER2_COUNTER() bfin_read32(TIMER2_COUNTER) -#define bfin_write_TIMER2_COUNTER(val) bfin_write32(TIMER2_COUNTER, val) -#define bfin_read_TIMER2_PERIOD() bfin_read32(TIMER2_PERIOD) -#define bfin_write_TIMER2_PERIOD(val) bfin_write32(TIMER2_PERIOD, val) -#define bfin_read_TIMER2_WIDTH() bfin_read32(TIMER2_WIDTH) -#define bfin_write_TIMER2_WIDTH(val) bfin_write32(TIMER2_WIDTH, val) -#define bfin_read_TIMER3_CONFIG() bfin_read16(TIMER3_CONFIG) -#define bfin_write_TIMER3_CONFIG(val) bfin_write16(TIMER3_CONFIG, val) -#define bfin_read_TIMER3_COUNTER() bfin_read32(TIMER3_COUNTER) -#define bfin_write_TIMER3_COUNTER(val) bfin_write32(TIMER3_COUNTER, val) -#define bfin_read_TIMER3_PERIOD() bfin_read32(TIMER3_PERIOD) -#define bfin_write_TIMER3_PERIOD(val) bfin_write32(TIMER3_PERIOD, val) -#define bfin_read_TIMER3_WIDTH() bfin_read32(TIMER3_WIDTH) -#define bfin_write_TIMER3_WIDTH(val) bfin_write32(TIMER3_WIDTH, val) -#define bfin_read_TIMER4_CONFIG() bfin_read16(TIMER4_CONFIG) -#define bfin_write_TIMER4_CONFIG(val) bfin_write16(TIMER4_CONFIG, val) -#define bfin_read_TIMER4_COUNTER() bfin_read32(TIMER4_COUNTER) -#define bfin_write_TIMER4_COUNTER(val) bfin_write32(TIMER4_COUNTER, val) -#define bfin_read_TIMER4_PERIOD() bfin_read32(TIMER4_PERIOD) -#define bfin_write_TIMER4_PERIOD(val) bfin_write32(TIMER4_PERIOD, val) -#define bfin_read_TIMER4_WIDTH() bfin_read32(TIMER4_WIDTH) -#define bfin_write_TIMER4_WIDTH(val) bfin_write32(TIMER4_WIDTH, val) -#define bfin_read_TIMER5_CONFIG() bfin_read16(TIMER5_CONFIG) -#define bfin_write_TIMER5_CONFIG(val) bfin_write16(TIMER5_CONFIG, val) -#define bfin_read_TIMER5_COUNTER() bfin_read32(TIMER5_COUNTER) -#define bfin_write_TIMER5_COUNTER(val) bfin_write32(TIMER5_COUNTER, val) -#define bfin_read_TIMER5_PERIOD() bfin_read32(TIMER5_PERIOD) -#define bfin_write_TIMER5_PERIOD(val) bfin_write32(TIMER5_PERIOD, val) -#define bfin_read_TIMER5_WIDTH() bfin_read32(TIMER5_WIDTH) -#define bfin_write_TIMER5_WIDTH(val) bfin_write32(TIMER5_WIDTH, val) -#define bfin_read_TIMER6_CONFIG() bfin_read16(TIMER6_CONFIG) -#define bfin_write_TIMER6_CONFIG(val) bfin_write16(TIMER6_CONFIG, val) -#define bfin_read_TIMER6_COUNTER() bfin_read32(TIMER6_COUNTER) -#define bfin_write_TIMER6_COUNTER(val) bfin_write32(TIMER6_COUNTER, val) -#define bfin_read_TIMER6_PERIOD() bfin_read32(TIMER6_PERIOD) -#define bfin_write_TIMER6_PERIOD(val) bfin_write32(TIMER6_PERIOD, val) -#define bfin_read_TIMER6_WIDTH() bfin_read32(TIMER6_WIDTH) -#define bfin_write_TIMER6_WIDTH(val) bfin_write32(TIMER6_WIDTH, val) -#define bfin_read_TIMER7_CONFIG() bfin_read16(TIMER7_CONFIG) -#define bfin_write_TIMER7_CONFIG(val) bfin_write16(TIMER7_CONFIG, val) -#define bfin_read_TIMER7_COUNTER() bfin_read32(TIMER7_COUNTER) -#define bfin_write_TIMER7_COUNTER(val) bfin_write32(TIMER7_COUNTER, val) -#define bfin_read_TIMER7_PERIOD() bfin_read32(TIMER7_PERIOD) -#define bfin_write_TIMER7_PERIOD(val) bfin_write32(TIMER7_PERIOD, val) -#define bfin_read_TIMER7_WIDTH() bfin_read32(TIMER7_WIDTH) -#define bfin_write_TIMER7_WIDTH(val) bfin_write32(TIMER7_WIDTH, val) - - - - -/* Two Wire Interface Registers (TWI0) */ - -/* SPORT1 Registers */ - - -/* SMC Registers */ -#define bfin_read_SMC_GCTL() bfin_read32(SMC_GCTL) -#define bfin_write_SMC_GCTL(val) bfin_write32(SMC_GCTL, val) -#define bfin_read_SMC_GSTAT() bfin_read32(SMC_GSTAT) -#define bfin_read_SMC_B0CTL() bfin_read32(SMC_B0CTL) -#define bfin_write_SMC_B0CTL(val) bfin_write32(SMC_B0CTL, val) -#define bfin_read_SMC_B0TIM() bfin_read32(SMC_B0TIM) -#define bfin_write_SMC_B0TIM(val) bfin_write32(SMC_B0TIM, val) -#define bfin_read_SMC_B0ETIM() bfin_read32(SMC_B0ETIM) -#define bfin_write_SMC_B0ETIM(val) bfin_write32(SMC_B0ETIM, val) -#define bfin_read_SMC_B1CTL() bfin_read32(SMC_B1CTL) -#define bfin_write_SMC_B1CTL(val) bfin_write32(SMC_B1CTL, val) -#define bfin_read_SMC_B1TIM() bfin_read32(SMC_B1TIM) -#define bfin_write_SMC_B1TIM(val) bfin_write32(SMC_B1TIM, val) -#define bfin_read_SMC_B1ETIM() bfin_read32(SMC_B1ETIM) -#define bfin_write_SMC_B1ETIM(val) bfin_write32(SMC_B1ETIM, val) -#define bfin_read_SMC_B2CTL() bfin_read32(SMC_B2CTL) -#define bfin_write_SMC_B2CTL(val) bfin_write32(SMC_B2CTL, val) -#define bfin_read_SMC_B2TIM() bfin_read32(SMC_B2TIM) -#define bfin_write_SMC_B2TIM(val) bfin_write32(SMC_B2TIM, val) -#define bfin_read_SMC_B2ETIM() bfin_read32(SMC_B2ETIM) -#define bfin_write_SMC_B2ETIM(val) bfin_write32(SMC_B2ETIM, val) -#define bfin_read_SMC_B3CTL() bfin_read32(SMC_B3CTL) -#define bfin_write_SMC_B3CTL(val) bfin_write32(SMC_B3CTL, val) -#define bfin_read_SMC_B3TIM() bfin_read32(SMC_B3TIM) -#define bfin_write_SMC_B3TIM(val) bfin_write32(SMC_B3TIM, val) -#define bfin_read_SMC_B3ETIM() bfin_read32(SMC_B3ETIM) -#define bfin_write_SMC_B3ETIM(val) bfin_write32(SMC_B3ETIM, val) - -/* DDR2 Memory Control Registers */ -#define bfin_read_DMC0_CFG() bfin_read32(DMC0_CFG) -#define bfin_write_DMC0_CFG(val) bfin_write32(DMC0_CFG, val) -#define bfin_read_DMC0_TR0() bfin_read32(DMC0_TR0) -#define bfin_write_DMC0_TR0(val) bfin_write32(DMC0_TR0, val) -#define bfin_read_DMC0_TR1() bfin_read32(DMC0_TR1) -#define bfin_write_DMC0_TR1(val) bfin_write32(DMC0_TR1, val) -#define bfin_read_DMC0_TR2() bfin_read32(DMC0_TR2) -#define bfin_write_DMC0_TR2(val) bfin_write32(DMC0_TR2, val) -#define bfin_read_DMC0_MR() bfin_read32(DMC0_MR) -#define bfin_write_DMC0_MR(val) bfin_write32(DMC0_MR, val) -#define bfin_read_DMC0_EMR1() bfin_read32(DMC0_EMR1) -#define bfin_write_DMC0_EMR1(val) bfin_write32(DMC0_EMR1, val) -#define bfin_read_DMC0_CTL() bfin_read32(DMC0_CTL) -#define bfin_write_DMC0_CTL(val) bfin_write32(DMC0_CTL, val) -#define bfin_read_DMC0_STAT() bfin_read32(DMC0_STAT) -#define bfin_write_DMC0_STAT(val) bfin_write32(DMC0_STAT, val) -#define bfin_read_DMC0_DLLCTL() bfin_read32(DMC0_DLLCTL) -#define bfin_write_DMC0_DLLCTL(val) bfin_write32(DMC0_DLLCTL, val) - -/* DDR BankRead and Write Count Registers */ - - -/* DMA Channel 0 Registers */ - -#define bfin_read_DMA0_NEXT_DESC_PTR() bfin_read32(DMA0_NEXT_DESC_PTR) -#define bfin_write_DMA0_NEXT_DESC_PTR(val) bfin_write32(DMA0_NEXT_DESC_PTR, val) -#define bfin_read_DMA0_START_ADDR() bfin_read32(DMA0_START_ADDR) -#define bfin_write_DMA0_START_ADDR(val) bfin_write32(DMA0_START_ADDR, val) -#define bfin_read_DMA0_CONFIG() bfin_read32(DMA0_CONFIG) -#define bfin_write_DMA0_CONFIG(val) bfin_write32(DMA0_CONFIG, val) -#define bfin_read_DMA0_X_COUNT() bfin_read32(DMA0_X_COUNT) -#define bfin_write_DMA0_X_COUNT(val) bfin_write32(DMA0_X_COUNT, val) -#define bfin_read_DMA0_X_MODIFY() bfin_read32(DMA0_X_MODIFY) -#define bfin_write_DMA0_X_MODIFY(val) bfin_write32(DMA0_X_MODIFY, val) -#define bfin_read_DMA0_Y_COUNT() bfin_read32(DMA0_Y_COUNT) -#define bfin_write_DMA0_Y_COUNT(val) bfin_write32(DMA0_Y_COUNT, val) -#define bfin_read_DMA0_Y_MODIFY() bfin_read32(DMA0_Y_MODIFY) -#define bfin_write_DMA0_Y_MODIFY(val) bfin_write32(DMA0_Y_MODIFY, val) -#define bfin_read_DMA0_CURR_DESC_PTR() bfin_read32(DMA0_CURR_DESC_PTR) -#define bfin_write_DMA0_CURR_DESC_PTR(val) bfin_write32(DMA0_CURR_DESC_PTR, val) -#define bfin_read_DMA0_PREV_DESC_PTR() bfin_read32(DMA0_PREV_DESC_PTR) -#define bfin_write_DMA0_PREV_DESC_PTR(val) bfin_write32(DMA0_PREV_DESC_PTR, val) -#define bfin_read_DMA0_CURR_ADDR() bfin_read32(DMA0_CURR_ADDR) -#define bfin_write_DMA0_CURR_ADDR(val) bfin_write32(DMA0_CURR_ADDR, val) -#define bfin_read_DMA0_IRQ_STATUS() bfin_read32(DMA0_IRQ_STATUS) -#define bfin_write_DMA0_IRQ_STATUS(val) bfin_write32(DMA0_IRQ_STATUS, val) -#define bfin_read_DMA0_CURR_X_COUNT() bfin_read32(DMA0_CURR_X_COUNT) -#define bfin_write_DMA0_CURR_X_COUNT(val) bfin_write32(DMA0_CURR_X_COUNT, val) -#define bfin_read_DMA0_CURR_Y_COUNT() bfin_read32(DMA0_CURR_Y_COUNT) -#define bfin_write_DMA0_CURR_Y_COUNT(val) bfin_write32(DMA0_CURR_Y_COUNT, val) -#define bfin_read_DMA0_BWL_COUNT() bfin_read32(DMA0_BWL_COUNT) -#define bfin_write_DMA0_BWL_COUNT(val) bfin_write32(DMA0_BWL_COUNT, val) -#define bfin_read_DMA0_CURR_BWL_COUNT() bfin_read32(DMA0_CURR_BWL_COUNT) -#define bfin_write_DMA0_CURR_BWL_COUNT(val) bfin_write32(DMA0_CURR_BWL_COUNT, val) -#define bfin_read_DMA0_BWM_COUNT() bfin_read32(DMA0_BWM_COUNT) -#define bfin_write_DMA0_BWM_COUNT(val) bfin_write32(DMA0_BWM_COUNT, val) -#define bfin_read_DMA0_CURR_BWM_COUNT() bfin_read32(DMA0_CURR_BWM_COUNT) -#define bfin_write_DMA0_CURR_BWM_COUNT(val) bfin_write32(DMA0_CURR_BWM_COUNT, val) - -/* DMA Channel 1 Registers */ - -#define bfin_read_DMA1_NEXT_DESC_PTR() bfin_read32(DMA1_NEXT_DESC_PTR) -#define bfin_write_DMA1_NEXT_DESC_PTR(val) bfin_write32(DMA1_NEXT_DESC_PTR, val) -#define bfin_read_DMA1_START_ADDR() bfin_read32(DMA1_START_ADDR) -#define bfin_write_DMA1_START_ADDR(val) bfin_write32(DMA1_START_ADDR, val) -#define bfin_read_DMA1_CONFIG() bfin_read32(DMA1_CONFIG) -#define bfin_write_DMA1_CONFIG(val) bfin_write32(DMA1_CONFIG, val) -#define bfin_read_DMA1_X_COUNT() bfin_read32(DMA1_X_COUNT) -#define bfin_write_DMA1_X_COUNT(val) bfin_write32(DMA1_X_COUNT, val) -#define bfin_read_DMA1_X_MODIFY() bfin_read32(DMA1_X_MODIFY) -#define bfin_write_DMA1_X_MODIFY(val) bfin_write32(DMA1_X_MODIFY, val) -#define bfin_read_DMA1_Y_COUNT() bfin_read32(DMA1_Y_COUNT) -#define bfin_write_DMA1_Y_COUNT(val) bfin_write32(DMA1_Y_COUNT, val) -#define bfin_read_DMA1_Y_MODIFY() bfin_read32(DMA1_Y_MODIFY) -#define bfin_write_DMA1_Y_MODIFY(val) bfin_write32(DMA1_Y_MODIFY, val) -#define bfin_read_DMA1_CURR_DESC_PTR() bfin_read32(DMA1_CURR_DESC_PTR) -#define bfin_write_DMA1_CURR_DESC_PTR(val) bfin_write32(DMA1_CURR_DESC_PTR, val) -#define bfin_read_DMA1_PREV_DESC_PTR() bfin_read32(DMA1_PREV_DESC_PTR) -#define bfin_write_DMA1_PREV_DESC_PTR(val) bfin_write32(DMA1_PREV_DESC_PTR, val) -#define bfin_read_DMA1_CURR_ADDR() bfin_read32(DMA1_CURR_ADDR) -#define bfin_write_DMA1_CURR_ADDR(val) bfin_write32(DMA1_CURR_ADDR, val) -#define bfin_read_DMA1_IRQ_STATUS() bfin_read32(DMA1_IRQ_STATUS) -#define bfin_write_DMA1_IRQ_STATUS(val) bfin_write32(DMA1_IRQ_STATUS, val) -#define bfin_read_DMA1_CURR_X_COUNT() bfin_read32(DMA1_CURR_X_COUNT) -#define bfin_write_DMA1_CURR_X_COUNT(val) bfin_write32(DMA1_CURR_X_COUNT, val) -#define bfin_read_DMA1_CURR_Y_COUNT() bfin_read32(DMA1_CURR_Y_COUNT) -#define bfin_write_DMA1_CURR_Y_COUNT(val) bfin_write32(DMA1_CURR_Y_COUNT, val) -#define bfin_read_DMA1_BWL_COUNT() bfin_read32(DMA1_BWL_COUNT) -#define bfin_write_DMA1_BWL_COUNT(val) bfin_write32(DMA1_BWL_COUNT, val) -#define bfin_read_DMA1_CURR_BWL_COUNT() bfin_read32(DMA1_CURR_BWL_COUNT) -#define bfin_write_DMA1_CURR_BWL_COUNT(val) bfin_write32(DMA1_CURR_BWL_COUNT, val) -#define bfin_read_DMA1_BWM_COUNT() bfin_read32(DMA1_BWM_COUNT) -#define bfin_write_DMA1_BWM_COUNT(val) bfin_write32(DMA1_BWM_COUNT, val) -#define bfin_read_DMA1_CURR_BWM_COUNT() bfin_read32(DMA1_CURR_BWM_COUNT) -#define bfin_write_DMA1_CURR_BWM_COUNT(val) bfin_write32(DMA1_CURR_BWM_COUNT, val) - -/* DMA Channel 2 Registers */ - -#define bfin_read_DMA2_NEXT_DESC_PTR() bfin_read32(DMA2_NEXT_DESC_PTR) -#define bfin_write_DMA2_NEXT_DESC_PTR(val) bfin_write32(DMA2_NEXT_DESC_PTR, val) -#define bfin_read_DMA2_START_ADDR() bfin_read32(DMA2_START_ADDR) -#define bfin_write_DMA2_START_ADDR(val) bfin_write32(DMA2_START_ADDR, val) -#define bfin_read_DMA2_CONFIG() bfin_read32(DMA2_CONFIG) -#define bfin_write_DMA2_CONFIG(val) bfin_write32(DMA2_CONFIG, val) -#define bfin_read_DMA2_X_COUNT() bfin_read32(DMA2_X_COUNT) -#define bfin_write_DMA2_X_COUNT(val) bfin_write32(DMA2_X_COUNT, val) -#define bfin_read_DMA2_X_MODIFY() bfin_read32(DMA2_X_MODIFY) -#define bfin_write_DMA2_X_MODIFY(val) bfin_write32(DMA2_X_MODIFY, val) -#define bfin_read_DMA2_Y_COUNT() bfin_read32(DMA2_Y_COUNT) -#define bfin_write_DMA2_Y_COUNT(val) bfin_write32(DMA2_Y_COUNT, val) -#define bfin_read_DMA2_Y_MODIFY() bfin_read32(DMA2_Y_MODIFY) -#define bfin_write_DMA2_Y_MODIFY(val) bfin_write32(DMA2_Y_MODIFY, val) -#define bfin_read_DMA2_CURR_DESC_PTR() bfin_read32(DMA2_CURR_DESC_PTR) -#define bfin_write_DMA2_CURR_DESC_PTR(val) bfin_write32(DMA2_CURR_DESC_PTR, val) -#define bfin_read_DMA2_PREV_DESC_PTR() bfin_read32(DMA2_PREV_DESC_PTR) -#define bfin_write_DMA2_PREV_DESC_PTR(val) bfin_write32(DMA2_PREV_DESC_PTR, val) -#define bfin_read_DMA2_CURR_ADDR() bfin_read32(DMA2_CURR_ADDR) -#define bfin_write_DMA2_CURR_ADDR(val) bfin_write32(DMA2_CURR_ADDR, val) -#define bfin_read_DMA2_IRQ_STATUS() bfin_read32(DMA2_IRQ_STATUS) -#define bfin_write_DMA2_IRQ_STATUS(val) bfin_write32(DMA2_IRQ_STATUS, val) -#define bfin_read_DMA2_CURR_X_COUNT() bfin_read32(DMA2_CURR_X_COUNT) -#define bfin_write_DMA2_CURR_X_COUNT(val) bfin_write32(DMA2_CURR_X_COUNT, val) -#define bfin_read_DMA2_CURR_Y_COUNT() bfin_read32(DMA2_CURR_Y_COUNT) -#define bfin_write_DMA2_CURR_Y_COUNT(val) bfin_write32(DMA2_CURR_Y_COUNT, val) -#define bfin_read_DMA2_BWL_COUNT() bfin_read32(DMA2_BWL_COUNT) -#define bfin_write_DMA2_BWL_COUNT(val) bfin_write32(DMA2_BWL_COUNT, val) -#define bfin_read_DMA2_CURR_BWL_COUNT() bfin_read32(DMA2_CURR_BWL_COUNT) -#define bfin_write_DMA2_CURR_BWL_COUNT(val) bfin_write32(DMA2_CURR_BWL_COUNT, val) -#define bfin_read_DMA2_BWM_COUNT() bfin_read32(DMA2_BWM_COUNT) -#define bfin_write_DMA2_BWM_COUNT(val) bfin_write32(DMA2_BWM_COUNT, val) -#define bfin_read_DMA2_CURR_BWM_COUNT() bfin_read32(DMA2_CURR_BWM_COUNT) -#define bfin_write_DMA2_CURR_BWM_COUNT(val) bfin_write32(DMA2_CURR_BWM_COUNT, val) - -/* DMA Channel 3 Registers */ - -#define bfin_read_DMA3_NEXT_DESC_PTR() bfin_read32(DMA3_NEXT_DESC_PTR) -#define bfin_write_DMA3_NEXT_DESC_PTR(val) bfin_write32(DMA3_NEXT_DESC_PTR, val) -#define bfin_read_DMA3_START_ADDR() bfin_read32(DMA3_START_ADDR) -#define bfin_write_DMA3_START_ADDR(val) bfin_write32(DMA3_START_ADDR, val) -#define bfin_read_DMA3_CONFIG() bfin_read32(DMA3_CONFIG) -#define bfin_write_DMA3_CONFIG(val) bfin_write32(DMA3_CONFIG, val) -#define bfin_read_DMA3_X_COUNT() bfin_read32(DMA3_X_COUNT) -#define bfin_write_DMA3_X_COUNT(val) bfin_write32(DMA3_X_COUNT, val) -#define bfin_read_DMA3_X_MODIFY() bfin_read32(DMA3_X_MODIFY) -#define bfin_write_DMA3_X_MODIFY(val) bfin_write32(DMA3_X_MODIFY, val) -#define bfin_read_DMA3_Y_COUNT() bfin_read32(DMA3_Y_COUNT) -#define bfin_write_DMA3_Y_COUNT(val) bfin_write32(DMA3_Y_COUNT, val) -#define bfin_read_DMA3_Y_MODIFY() bfin_read32(DMA3_Y_MODIFY) -#define bfin_write_DMA3_Y_MODIFY(val) bfin_write32(DMA3_Y_MODIFY, val) -#define bfin_read_DMA3_CURR_DESC_PTR() bfin_read32(DMA3_CURR_DESC_PTR) -#define bfin_write_DMA3_CURR_DESC_PTR(val) bfin_write32(DMA3_CURR_DESC_PTR, val) -#define bfin_read_DMA3_PREV_DESC_PTR() bfin_read32(DMA3_PREV_DESC_PTR) -#define bfin_write_DMA3_PREV_DESC_PTR(val) bfin_write32(DMA3_PREV_DESC_PTR, val) -#define bfin_read_DMA3_CURR_ADDR() bfin_read32(DMA3_CURR_ADDR) -#define bfin_write_DMA3_CURR_ADDR(val) bfin_write32(DMA3_CURR_ADDR, val) -#define bfin_read_DMA3_IRQ_STATUS() bfin_read32(DMA3_IRQ_STATUS) -#define bfin_write_DMA3_IRQ_STATUS(val) bfin_write32(DMA3_IRQ_STATUS, val) -#define bfin_read_DMA3_CURR_X_COUNT() bfin_read32(DMA3_CURR_X_COUNT) -#define bfin_write_DMA3_CURR_X_COUNT(val) bfin_write32(DMA3_CURR_X_COUNT, val) -#define bfin_read_DMA3_CURR_Y_COUNT() bfin_read32(DMA3_CURR_Y_COUNT) -#define bfin_write_DMA3_CURR_Y_COUNT(val) bfin_write32(DMA3_CURR_Y_COUNT, val) -#define bfin_read_DMA3_BWL_COUNT() bfin_read32(DMA3_BWL_COUNT) -#define bfin_write_DMA3_BWL_COUNT(val) bfin_write32(DMA3_BWL_COUNT, val) -#define bfin_read_DMA3_CURR_BWL_COUNT() bfin_read32(DMA3_CURR_BWL_COUNT) -#define bfin_write_DMA3_CURR_BWL_COUNT(val) bfin_write32(DMA3_CURR_BWL_COUNT, val) -#define bfin_read_DMA3_BWM_COUNT() bfin_read32(DMA3_BWM_COUNT) -#define bfin_write_DMA3_BWM_COUNT(val) bfin_write32(DMA3_BWM_COUNT, val) -#define bfin_read_DMA3_CURR_BWM_COUNT() bfin_read32(DMA3_CURR_BWM_COUNT) -#define bfin_write_DMA3_CURR_BWM_COUNT(val) bfin_write32(DMA3_CURR_BWM_COUNT, val) - -/* DMA Channel 4 Registers */ - -#define bfin_read_DMA4_NEXT_DESC_PTR() bfin_read32(DMA4_NEXT_DESC_PTR) -#define bfin_write_DMA4_NEXT_DESC_PTR(val) bfin_write32(DMA4_NEXT_DESC_PTR, val) -#define bfin_read_DMA4_START_ADDR() bfin_read32(DMA4_START_ADDR) -#define bfin_write_DMA4_START_ADDR(val) bfin_write32(DMA4_START_ADDR, val) -#define bfin_read_DMA4_CONFIG() bfin_read32(DMA4_CONFIG) -#define bfin_write_DMA4_CONFIG(val) bfin_write32(DMA4_CONFIG, val) -#define bfin_read_DMA4_X_COUNT() bfin_read32(DMA4_X_COUNT) -#define bfin_write_DMA4_X_COUNT(val) bfin_write32(DMA4_X_COUNT, val) -#define bfin_read_DMA4_X_MODIFY() bfin_read32(DMA4_X_MODIFY) -#define bfin_write_DMA4_X_MODIFY(val) bfin_write32(DMA4_X_MODIFY, val) -#define bfin_read_DMA4_Y_COUNT() bfin_read32(DMA4_Y_COUNT) -#define bfin_write_DMA4_Y_COUNT(val) bfin_write32(DMA4_Y_COUNT, val) -#define bfin_read_DMA4_Y_MODIFY() bfin_read32(DMA4_Y_MODIFY) -#define bfin_write_DMA4_Y_MODIFY(val) bfin_write32(DMA4_Y_MODIFY, val) -#define bfin_read_DMA4_CURR_DESC_PTR() bfin_read32(DMA4_CURR_DESC_PTR) -#define bfin_write_DMA4_CURR_DESC_PTR(val) bfin_write32(DMA4_CURR_DESC_PTR, val) -#define bfin_read_DMA4_PREV_DESC_PTR() bfin_read32(DMA4_PREV_DESC_PTR) -#define bfin_write_DMA4_PREV_DESC_PTR(val) bfin_write32(DMA4_PREV_DESC_PTR, val) -#define bfin_read_DMA4_CURR_ADDR() bfin_read32(DMA4_CURR_ADDR) -#define bfin_write_DMA4_CURR_ADDR(val) bfin_write32(DMA4_CURR_ADDR, val) -#define bfin_read_DMA4_IRQ_STATUS() bfin_read32(DMA4_IRQ_STATUS) -#define bfin_write_DMA4_IRQ_STATUS(val) bfin_write32(DMA4_IRQ_STATUS, val) -#define bfin_read_DMA4_CURR_X_COUNT() bfin_read32(DMA4_CURR_X_COUNT) -#define bfin_write_DMA4_CURR_X_COUNT(val) bfin_write32(DMA4_CURR_X_COUNT, val) -#define bfin_read_DMA4_CURR_Y_COUNT() bfin_read32(DMA4_CURR_Y_COUNT) -#define bfin_write_DMA4_CURR_Y_COUNT(val) bfin_write32(DMA4_CURR_Y_COUNT, val) -#define bfin_read_DMA4_BWL_COUNT() bfin_read32(DMA4_BWL_COUNT) -#define bfin_write_DMA4_BWL_COUNT(val) bfin_write32(DMA4_BWL_COUNT, val) -#define bfin_read_DMA4_CURR_BWL_COUNT() bfin_read32(DMA4_CURR_BWL_COUNT) -#define bfin_write_DMA4_CURR_BWL_COUNT(val) bfin_write32(DMA4_CURR_BWL_COUNT, val) -#define bfin_read_DMA4_BWM_COUNT() bfin_read32(DMA4_BWM_COUNT) -#define bfin_write_DMA4_BWM_COUNT(val) bfin_write32(DMA4_BWM_COUNT, val) -#define bfin_read_DMA4_CURR_BWM_COUNT() bfin_read32(DMA4_CURR_BWM_COUNT) -#define bfin_write_DMA4_CURR_BWM_COUNT(val) bfin_write32(DMA4_CURR_BWM_COUNT, val) - -/* DMA Channel 5 Registers */ - -#define bfin_read_DMA5_NEXT_DESC_PTR() bfin_read32(DMA5_NEXT_DESC_PTR) -#define bfin_write_DMA5_NEXT_DESC_PTR(val) bfin_write32(DMA5_NEXT_DESC_PTR, val) -#define bfin_read_DMA5_START_ADDR() bfin_read32(DMA5_START_ADDR) -#define bfin_write_DMA5_START_ADDR(val) bfin_write32(DMA5_START_ADDR, val) -#define bfin_read_DMA5_CONFIG() bfin_read32(DMA5_CONFIG) -#define bfin_write_DMA5_CONFIG(val) bfin_write32(DMA5_CONFIG, val) -#define bfin_read_DMA5_X_COUNT() bfin_read32(DMA5_X_COUNT) -#define bfin_write_DMA5_X_COUNT(val) bfin_write32(DMA5_X_COUNT, val) -#define bfin_read_DMA5_X_MODIFY() bfin_read32(DMA5_X_MODIFY) -#define bfin_write_DMA5_X_MODIFY(val) bfin_write32(DMA5_X_MODIFY, val) -#define bfin_read_DMA5_Y_COUNT() bfin_read32(DMA5_Y_COUNT) -#define bfin_write_DMA5_Y_COUNT(val) bfin_write32(DMA5_Y_COUNT, val) -#define bfin_read_DMA5_Y_MODIFY() bfin_read32(DMA5_Y_MODIFY) -#define bfin_write_DMA5_Y_MODIFY(val) bfin_write32(DMA5_Y_MODIFY, val) -#define bfin_read_DMA5_CURR_DESC_PTR() bfin_read32(DMA5_CURR_DESC_PTR) -#define bfin_write_DMA5_CURR_DESC_PTR(val) bfin_write32(DMA5_CURR_DESC_PTR, val) -#define bfin_read_DMA5_PREV_DESC_PTR() bfin_read32(DMA5_PREV_DESC_PTR) -#define bfin_write_DMA5_PREV_DESC_PTR(val) bfin_write32(DMA5_PREV_DESC_PTR, val) -#define bfin_read_DMA5_CURR_ADDR() bfin_read32(DMA5_CURR_ADDR) -#define bfin_write_DMA5_CURR_ADDR(val) bfin_write32(DMA5_CURR_ADDR, val) -#define bfin_read_DMA5_IRQ_STATUS() bfin_read32(DMA5_IRQ_STATUS) -#define bfin_write_DMA5_IRQ_STATUS(val) bfin_write32(DMA5_IRQ_STATUS, val) -#define bfin_read_DMA5_CURR_X_COUNT() bfin_read32(DMA5_CURR_X_COUNT) -#define bfin_write_DMA5_CURR_X_COUNT(val) bfin_write32(DMA5_CURR_X_COUNT, val) -#define bfin_read_DMA5_CURR_Y_COUNT() bfin_read32(DMA5_CURR_Y_COUNT) -#define bfin_write_DMA5_CURR_Y_COUNT(val) bfin_write32(DMA5_CURR_Y_COUNT, val) -#define bfin_read_DMA5_BWL_COUNT() bfin_read32(DMA5_BWL_COUNT) -#define bfin_write_DMA5_BWL_COUNT(val) bfin_write32(DMA5_BWL_COUNT, val) -#define bfin_read_DMA5_CURR_BWL_COUNT() bfin_read32(DMA5_CURR_BWL_COUNT) -#define bfin_write_DMA5_CURR_BWL_COUNT(val) bfin_write32(DMA5_CURR_BWL_COUNT, val) -#define bfin_read_DMA5_BWM_COUNT() bfin_read32(DMA5_BWM_COUNT) -#define bfin_write_DMA5_BWM_COUNT(val) bfin_write32(DMA5_BWM_COUNT, val) -#define bfin_read_DMA5_CURR_BWM_COUNT() bfin_read32(DMA5_CURR_BWM_COUNT) -#define bfin_write_DMA5_CURR_BWM_COUNT(val) bfin_write32(DMA5_CURR_BWM_COUNT, val) - -/* DMA Channel 6 Registers */ - -#define bfin_read_DMA6_NEXT_DESC_PTR() bfin_read32(DMA6_NEXT_DESC_PTR) -#define bfin_write_DMA6_NEXT_DESC_PTR(val) bfin_write32(DMA6_NEXT_DESC_PTR, val) -#define bfin_read_DMA6_START_ADDR() bfin_read32(DMA6_START_ADDR) -#define bfin_write_DMA6_START_ADDR(val) bfin_write32(DMA6_START_ADDR, val) -#define bfin_read_DMA6_CONFIG() bfin_read32(DMA6_CONFIG) -#define bfin_write_DMA6_CONFIG(val) bfin_write32(DMA6_CONFIG, val) -#define bfin_read_DMA6_X_COUNT() bfin_read32(DMA6_X_COUNT) -#define bfin_write_DMA6_X_COUNT(val) bfin_write32(DMA6_X_COUNT, val) -#define bfin_read_DMA6_X_MODIFY() bfin_read32(DMA6_X_MODIFY) -#define bfin_write_DMA6_X_MODIFY(val) bfin_write32(DMA6_X_MODIFY, val) -#define bfin_read_DMA6_Y_COUNT() bfin_read32(DMA6_Y_COUNT) -#define bfin_write_DMA6_Y_COUNT(val) bfin_write32(DMA6_Y_COUNT, val) -#define bfin_read_DMA6_Y_MODIFY() bfin_read32(DMA6_Y_MODIFY) -#define bfin_write_DMA6_Y_MODIFY(val) bfin_write32(DMA6_Y_MODIFY, val) -#define bfin_read_DMA6_CURR_DESC_PTR() bfin_read32(DMA6_CURR_DESC_PTR) -#define bfin_write_DMA6_CURR_DESC_PTR(val) bfin_write32(DMA6_CURR_DESC_PTR, val) -#define bfin_read_DMA6_PREV_DESC_PTR() bfin_read32(DMA6_PREV_DESC_PTR) -#define bfin_write_DMA6_PREV_DESC_PTR(val) bfin_write32(DMA6_PREV_DESC_PTR, val) -#define bfin_read_DMA6_CURR_ADDR() bfin_read32(DMA6_CURR_ADDR) -#define bfin_write_DMA6_CURR_ADDR(val) bfin_write32(DMA6_CURR_ADDR, val) -#define bfin_read_DMA6_IRQ_STATUS() bfin_read32(DMA6_IRQ_STATUS) -#define bfin_write_DMA6_IRQ_STATUS(val) bfin_write32(DMA6_IRQ_STATUS, val) -#define bfin_read_DMA6_CURR_X_COUNT() bfin_read32(DMA6_CURR_X_COUNT) -#define bfin_write_DMA6_CURR_X_COUNT(val) bfin_write32(DMA6_CURR_X_COUNT, val) -#define bfin_read_DMA6_CURR_Y_COUNT() bfin_read32(DMA6_CURR_Y_COUNT) -#define bfin_write_DMA6_CURR_Y_COUNT(val) bfin_write32(DMA6_CURR_Y_COUNT, val) -#define bfin_read_DMA6_BWL_COUNT() bfin_read32(DMA6_BWL_COUNT) -#define bfin_write_DMA6_BWL_COUNT(val) bfin_write32(DMA6_BWL_COUNT, val) -#define bfin_read_DMA6_CURR_BWL_COUNT() bfin_read32(DMA6_CURR_BWL_COUNT) -#define bfin_write_DMA6_CURR_BWL_COUNT(val) bfin_write32(DMA6_CURR_BWL_COUNT, val) -#define bfin_read_DMA6_BWM_COUNT() bfin_read32(DMA6_BWM_COUNT) -#define bfin_write_DMA6_BWM_COUNT(val) bfin_write32(DMA6_BWM_COUNT, val) -#define bfin_read_DMA6_CURR_BWM_COUNT() bfin_read32(DMA6_CURR_BWM_COUNT) -#define bfin_write_DMA6_CURR_BWM_COUNT(val) bfin_write32(DMA6_CURR_BWM_COUNT, val) - -/* DMA Channel 7 Registers */ - -#define bfin_read_DMA7_NEXT_DESC_PTR() bfin_read32(DMA7_NEXT_DESC_PTR) -#define bfin_write_DMA7_NEXT_DESC_PTR(val) bfin_write32(DMA7_NEXT_DESC_PTR, val) -#define bfin_read_DMA7_START_ADDR() bfin_read32(DMA7_START_ADDR) -#define bfin_write_DMA7_START_ADDR(val) bfin_write32(DMA7_START_ADDR, val) -#define bfin_read_DMA7_CONFIG() bfin_read32(DMA7_CONFIG) -#define bfin_write_DMA7_CONFIG(val) bfin_write32(DMA7_CONFIG, val) -#define bfin_read_DMA7_X_COUNT() bfin_read32(DMA7_X_COUNT) -#define bfin_write_DMA7_X_COUNT(val) bfin_write32(DMA7_X_COUNT, val) -#define bfin_read_DMA7_X_MODIFY() bfin_read32(DMA7_X_MODIFY) -#define bfin_write_DMA7_X_MODIFY(val) bfin_write32(DMA7_X_MODIFY, val) -#define bfin_read_DMA7_Y_COUNT() bfin_read32(DMA7_Y_COUNT) -#define bfin_write_DMA7_Y_COUNT(val) bfin_write32(DMA7_Y_COUNT, val) -#define bfin_read_DMA7_Y_MODIFY() bfin_read32(DMA7_Y_MODIFY) -#define bfin_write_DMA7_Y_MODIFY(val) bfin_write32(DMA7_Y_MODIFY, val) -#define bfin_read_DMA7_CURR_DESC_PTR() bfin_read32(DMA7_CURR_DESC_PTR) -#define bfin_write_DMA7_CURR_DESC_PTR(val) bfin_write32(DMA7_CURR_DESC_PTR, val) -#define bfin_read_DMA7_PREV_DESC_PTR() bfin_read32(DMA7_PREV_DESC_PTR) -#define bfin_write_DMA7_PREV_DESC_PTR(val) bfin_write32(DMA7_PREV_DESC_PTR, val) -#define bfin_read_DMA7_CURR_ADDR() bfin_read32(DMA7_CURR_ADDR) -#define bfin_write_DMA7_CURR_ADDR(val) bfin_write32(DMA7_CURR_ADDR, val) -#define bfin_read_DMA7_IRQ_STATUS() bfin_read32(DMA7_IRQ_STATUS) -#define bfin_write_DMA7_IRQ_STATUS(val) bfin_write32(DMA7_IRQ_STATUS, val) -#define bfin_read_DMA7_CURR_X_COUNT() bfin_read32(DMA7_CURR_X_COUNT) -#define bfin_write_DMA7_CURR_X_COUNT(val) bfin_write32(DMA7_CURR_X_COUNT, val) -#define bfin_read_DMA7_CURR_Y_COUNT() bfin_read32(DMA7_CURR_Y_COUNT) -#define bfin_write_DMA7_CURR_Y_COUNT(val) bfin_write32(DMA7_CURR_Y_COUNT, val) -#define bfin_read_DMA7_BWL_COUNT() bfin_read32(DMA7_BWL_COUNT) -#define bfin_write_DMA7_BWL_COUNT(val) bfin_write32(DMA7_BWL_COUNT, val) -#define bfin_read_DMA7_CURR_BWL_COUNT() bfin_read32(DMA7_CURR_BWL_COUNT) -#define bfin_write_DMA7_CURR_BWL_COUNT(val) bfin_write32(DMA7_CURR_BWL_COUNT, val) -#define bfin_read_DMA7_BWM_COUNT() bfin_read32(DMA7_BWM_COUNT) -#define bfin_write_DMA7_BWM_COUNT(val) bfin_write32(DMA7_BWM_COUNT, val) -#define bfin_read_DMA7_CURR_BWM_COUNT() bfin_read32(DMA7_CURR_BWM_COUNT) -#define bfin_write_DMA7_CURR_BWM_COUNT(val) bfin_write32(DMA7_CURR_BWM_COUNT, val) - -/* DMA Channel 8 Registers */ - -#define bfin_read_DMA8_NEXT_DESC_PTR() bfin_read32(DMA8_NEXT_DESC_PTR) -#define bfin_write_DMA8_NEXT_DESC_PTR(val) bfin_write32(DMA8_NEXT_DESC_PTR, val) -#define bfin_read_DMA8_START_ADDR() bfin_read32(DMA8_START_ADDR) -#define bfin_write_DMA8_START_ADDR(val) bfin_write32(DMA8_START_ADDR, val) -#define bfin_read_DMA8_CONFIG() bfin_read32(DMA8_CONFIG) -#define bfin_write_DMA8_CONFIG(val) bfin_write32(DMA8_CONFIG, val) -#define bfin_read_DMA8_X_COUNT() bfin_read32(DMA8_X_COUNT) -#define bfin_write_DMA8_X_COUNT(val) bfin_write32(DMA8_X_COUNT, val) -#define bfin_read_DMA8_X_MODIFY() bfin_read32(DMA8_X_MODIFY) -#define bfin_write_DMA8_X_MODIFY(val) bfin_write32(DMA8_X_MODIFY, val) -#define bfin_read_DMA8_Y_COUNT() bfin_read32(DMA8_Y_COUNT) -#define bfin_write_DMA8_Y_COUNT(val) bfin_write32(DMA8_Y_COUNT, val) -#define bfin_read_DMA8_Y_MODIFY() bfin_read32(DMA8_Y_MODIFY) -#define bfin_write_DMA8_Y_MODIFY(val) bfin_write32(DMA8_Y_MODIFY, val) -#define bfin_read_DMA8_CURR_DESC_PTR() bfin_read32(DMA8_CURR_DESC_PTR) -#define bfin_write_DMA8_CURR_DESC_PTR(val) bfin_write32(DMA8_CURR_DESC_PTR, val) -#define bfin_read_DMA8_PREV_DESC_PTR() bfin_read32(DMA8_PREV_DESC_PTR) -#define bfin_write_DMA8_PREV_DESC_PTR(val) bfin_write32(DMA8_PREV_DESC_PTR, val) -#define bfin_read_DMA8_CURR_ADDR() bfin_read32(DMA8_CURR_ADDR) -#define bfin_write_DMA8_CURR_ADDR(val) bfin_write32(DMA8_CURR_ADDR, val) -#define bfin_read_DMA8_IRQ_STATUS() bfin_read32(DMA8_IRQ_STATUS) -#define bfin_write_DMA8_IRQ_STATUS(val) bfin_write32(DMA8_IRQ_STATUS, val) -#define bfin_read_DMA8_CURR_X_COUNT() bfin_read32(DMA8_CURR_X_COUNT) -#define bfin_write_DMA8_CURR_X_COUNT(val) bfin_write32(DMA8_CURR_X_COUNT, val) -#define bfin_read_DMA8_CURR_Y_COUNT() bfin_read32(DMA8_CURR_Y_COUNT) -#define bfin_write_DMA8_CURR_Y_COUNT(val) bfin_write32(DMA8_CURR_Y_COUNT, val) -#define bfin_read_DMA8_BWL_COUNT() bfin_read32(DMA8_BWL_COUNT) -#define bfin_write_DMA8_BWL_COUNT(val) bfin_write32(DMA8_BWL_COUNT, val) -#define bfin_read_DMA8_CURR_BWL_COUNT() bfin_read32(DMA8_CURR_BWL_COUNT) -#define bfin_write_DMA8_CURR_BWL_COUNT(val) bfin_write32(DMA8_CURR_BWL_COUNT, val) -#define bfin_read_DMA8_BWM_COUNT() bfin_read32(DMA8_BWM_COUNT) -#define bfin_write_DMA8_BWM_COUNT(val) bfin_write32(DMA8_BWM_COUNT, val) -#define bfin_read_DMA8_CURR_BWM_COUNT() bfin_read32(DMA8_CURR_BWM_COUNT) -#define bfin_write_DMA8_CURR_BWM_COUNT(val) bfin_write32(DMA8_CURR_BWM_COUNT, val) - -/* DMA Channel 9 Registers */ - -#define bfin_read_DMA9_NEXT_DESC_PTR() bfin_read32(DMA9_NEXT_DESC_PTR) -#define bfin_write_DMA9_NEXT_DESC_PTR(val) bfin_write32(DMA9_NEXT_DESC_PTR, val) -#define bfin_read_DMA9_START_ADDR() bfin_read32(DMA9_START_ADDR) -#define bfin_write_DMA9_START_ADDR(val) bfin_write32(DMA9_START_ADDR, val) -#define bfin_read_DMA9_CONFIG() bfin_read32(DMA9_CONFIG) -#define bfin_write_DMA9_CONFIG(val) bfin_write32(DMA9_CONFIG, val) -#define bfin_read_DMA9_X_COUNT() bfin_read32(DMA9_X_COUNT) -#define bfin_write_DMA9_X_COUNT(val) bfin_write32(DMA9_X_COUNT, val) -#define bfin_read_DMA9_X_MODIFY() bfin_read32(DMA9_X_MODIFY) -#define bfin_write_DMA9_X_MODIFY(val) bfin_write32(DMA9_X_MODIFY, val) -#define bfin_read_DMA9_Y_COUNT() bfin_read32(DMA9_Y_COUNT) -#define bfin_write_DMA9_Y_COUNT(val) bfin_write32(DMA9_Y_COUNT, val) -#define bfin_read_DMA9_Y_MODIFY() bfin_read32(DMA9_Y_MODIFY) -#define bfin_write_DMA9_Y_MODIFY(val) bfin_write32(DMA9_Y_MODIFY, val) -#define bfin_read_DMA9_CURR_DESC_PTR() bfin_read32(DMA9_CURR_DESC_PTR) -#define bfin_write_DMA9_CURR_DESC_PTR(val) bfin_write32(DMA9_CURR_DESC_PTR, val) -#define bfin_read_DMA9_PREV_DESC_PTR() bfin_read32(DMA9_PREV_DESC_PTR) -#define bfin_write_DMA9_PREV_DESC_PTR(val) bfin_write32(DMA9_PREV_DESC_PTR, val) -#define bfin_read_DMA9_CURR_ADDR() bfin_read32(DMA9_CURR_ADDR) -#define bfin_write_DMA9_CURR_ADDR(val) bfin_write32(DMA9_CURR_ADDR, val) -#define bfin_read_DMA9_IRQ_STATUS() bfin_read32(DMA9_IRQ_STATUS) -#define bfin_write_DMA9_IRQ_STATUS(val) bfin_write32(DMA9_IRQ_STATUS, val) -#define bfin_read_DMA9_CURR_X_COUNT() bfin_read32(DMA9_CURR_X_COUNT) -#define bfin_write_DMA9_CURR_X_COUNT(val) bfin_write32(DMA9_CURR_X_COUNT, val) -#define bfin_read_DMA9_CURR_Y_COUNT() bfin_read32(DMA9_CURR_Y_COUNT) -#define bfin_write_DMA9_CURR_Y_COUNT(val) bfin_write32(DMA9_CURR_Y_COUNT, val) -#define bfin_read_DMA9_BWL_COUNT() bfin_read32(DMA9_BWL_COUNT) -#define bfin_write_DMA9_BWL_COUNT(val) bfin_write32(DMA9_BWL_COUNT, val) -#define bfin_read_DMA9_CURR_BWL_COUNT() bfin_read32(DMA9_CURR_BWL_COUNT) -#define bfin_write_DMA9_CURR_BWL_COUNT(val) bfin_write32(DMA9_CURR_BWL_COUNT, val) -#define bfin_read_DMA9_BWM_COUNT() bfin_read32(DMA9_BWM_COUNT) -#define bfin_write_DMA9_BWM_COUNT(val) bfin_write32(DMA9_BWM_COUNT, val) -#define bfin_read_DMA9_CURR_BWM_COUNT() bfin_read32(DMA9_CURR_BWM_COUNT) -#define bfin_write_DMA9_CURR_BWM_COUNT(val) bfin_write32(DMA9_CURR_BWM_COUNT, val) - -/* DMA Channel 10 Registers */ - -#define bfin_read_DMA10_NEXT_DESC_PTR() bfin_read32(DMA10_NEXT_DESC_PTR) -#define bfin_write_DMA10_NEXT_DESC_PTR(val) bfin_write32(DMA10_NEXT_DESC_PTR, val) -#define bfin_read_DMA10_START_ADDR() bfin_read32(DMA10_START_ADDR) -#define bfin_write_DMA10_START_ADDR(val) bfin_write32(DMA10_START_ADDR, val) -#define bfin_read_DMA10_CONFIG() bfin_read32(DMA10_CONFIG) -#define bfin_write_DMA10_CONFIG(val) bfin_write32(DMA10_CONFIG, val) -#define bfin_read_DMA10_X_COUNT() bfin_read32(DMA10_X_COUNT) -#define bfin_write_DMA10_X_COUNT(val) bfin_write32(DMA10_X_COUNT, val) -#define bfin_read_DMA10_X_MODIFY() bfin_read32(DMA10_X_MODIFY) -#define bfin_write_DMA10_X_MODIFY(val) bfin_write32(DMA10_X_MODIFY, val) -#define bfin_read_DMA10_Y_COUNT() bfin_read32(DMA10_Y_COUNT) -#define bfin_write_DMA10_Y_COUNT(val) bfin_write32(DMA10_Y_COUNT, val) -#define bfin_read_DMA10_Y_MODIFY() bfin_read32(DMA10_Y_MODIFY) -#define bfin_write_DMA10_Y_MODIFY(val) bfin_write32(DMA10_Y_MODIFY, val) -#define bfin_read_DMA10_CURR_DESC_PTR() bfin_read32(DMA10_CURR_DESC_PTR) -#define bfin_write_DMA10_CURR_DESC_PTR(val) bfin_write32(DMA10_CURR_DESC_PTR, val) -#define bfin_read_DMA10_PREV_DESC_PTR() bfin_read32(DMA10_PREV_DESC_PTR) -#define bfin_write_DMA10_PREV_DESC_PTR(val) bfin_write32(DMA10_PREV_DESC_PTR, val) -#define bfin_read_DMA10_CURR_ADDR() bfin_read32(DMA10_CURR_ADDR) -#define bfin_write_DMA10_CURR_ADDR(val) bfin_write32(DMA10_CURR_ADDR, val) -#define bfin_read_DMA10_IRQ_STATUS() bfin_read32(DMA10_IRQ_STATUS) -#define bfin_write_DMA10_IRQ_STATUS(val) bfin_write32(DMA10_IRQ_STATUS, val) -#define bfin_read_DMA10_CURR_X_COUNT() bfin_read32(DMA10_CURR_X_COUNT) -#define bfin_write_DMA10_CURR_X_COUNT(val) bfin_write32(DMA10_CURR_X_COUNT, val) -#define bfin_read_DMA10_CURR_Y_COUNT() bfin_read32(DMA10_CURR_Y_COUNT) -#define bfin_write_DMA10_CURR_Y_COUNT(val) bfin_write32(DMA10_CURR_Y_COUNT, val) -#define bfin_read_DMA10_BWL_COUNT() bfin_read32(DMA10_BWL_COUNT) -#define bfin_write_DMA10_BWL_COUNT(val) bfin_write32(DMA10_BWL_COUNT, val) -#define bfin_read_DMA10_CURR_BWL_COUNT() bfin_read32(DMA10_CURR_BWL_COUNT) -#define bfin_write_DMA10_CURR_BWL_COUNT(val) bfin_write32(DMA10_CURR_BWL_COUNT, val) -#define bfin_read_DMA10_BWM_COUNT() bfin_read32(DMA10_BWM_COUNT) -#define bfin_write_DMA10_BWM_COUNT(val) bfin_write32(DMA10_BWM_COUNT, val) -#define bfin_read_DMA10_CURR_BWM_COUNT() bfin_read32(DMA10_CURR_BWM_COUNT) -#define bfin_write_DMA10_CURR_BWM_COUNT(val) bfin_write32(DMA10_CURR_BWM_COUNT, val) - -/* DMA Channel 11 Registers */ - -#define bfin_read_DMA11_NEXT_DESC_PTR() bfin_read32(DMA11_NEXT_DESC_PTR) -#define bfin_write_DMA11_NEXT_DESC_PTR(val) bfin_write32(DMA11_NEXT_DESC_PTR, val) -#define bfin_read_DMA11_START_ADDR() bfin_read32(DMA11_START_ADDR) -#define bfin_write_DMA11_START_ADDR(val) bfin_write32(DMA11_START_ADDR, val) -#define bfin_read_DMA11_CONFIG() bfin_read32(DMA11_CONFIG) -#define bfin_write_DMA11_CONFIG(val) bfin_write32(DMA11_CONFIG, val) -#define bfin_read_DMA11_X_COUNT() bfin_read32(DMA11_X_COUNT) -#define bfin_write_DMA11_X_COUNT(val) bfin_write32(DMA11_X_COUNT, val) -#define bfin_read_DMA11_X_MODIFY() bfin_read32(DMA11_X_MODIFY) -#define bfin_write_DMA11_X_MODIFY(val) bfin_write32(DMA11_X_MODIFY, val) -#define bfin_read_DMA11_Y_COUNT() bfin_read32(DMA11_Y_COUNT) -#define bfin_write_DMA11_Y_COUNT(val) bfin_write32(DMA11_Y_COUNT, val) -#define bfin_read_DMA11_Y_MODIFY() bfin_read32(DMA11_Y_MODIFY) -#define bfin_write_DMA11_Y_MODIFY(val) bfin_write32(DMA11_Y_MODIFY, val) -#define bfin_read_DMA11_CURR_DESC_PTR() bfin_read32(DMA11_CURR_DESC_PTR) -#define bfin_write_DMA11_CURR_DESC_PTR(val) bfin_write32(DMA11_CURR_DESC_PTR, val) -#define bfin_read_DMA11_PREV_DESC_PTR() bfin_read32(DMA11_PREV_DESC_PTR) -#define bfin_write_DMA11_PREV_DESC_PTR(val) bfin_write32(DMA11_PREV_DESC_PTR, val) -#define bfin_read_DMA11_CURR_ADDR() bfin_read32(DMA11_CURR_ADDR) -#define bfin_write_DMA11_CURR_ADDR(val) bfin_write32(DMA11_CURR_ADDR, val) -#define bfin_read_DMA11_IRQ_STATUS() bfin_read32(DMA11_IRQ_STATUS) -#define bfin_write_DMA11_IRQ_STATUS(val) bfin_write32(DMA11_IRQ_STATUS, val) -#define bfin_read_DMA11_CURR_X_COUNT() bfin_read32(DMA11_CURR_X_COUNT) -#define bfin_write_DMA11_CURR_X_COUNT(val) bfin_write32(DMA11_CURR_X_COUNT, val) -#define bfin_read_DMA11_CURR_Y_COUNT() bfin_read32(DMA11_CURR_Y_COUNT) -#define bfin_write_DMA11_CURR_Y_COUNT(val) bfin_write32(DMA11_CURR_Y_COUNT, val) -#define bfin_read_DMA11_BWL_COUNT() bfin_read32(DMA11_BWL_COUNT) -#define bfin_write_DMA11_BWL_COUNT(val) bfin_write32(DMA11_BWL_COUNT, val) -#define bfin_read_DMA11_CURR_BWL_COUNT() bfin_read32(DMA11_CURR_BWL_COUNT) -#define bfin_write_DMA11_CURR_BWL_COUNT(val) bfin_write32(DMA11_CURR_BWL_COUNT, val) -#define bfin_read_DMA11_BWM_COUNT() bfin_read32(DMA11_BWM_COUNT) -#define bfin_write_DMA11_BWM_COUNT(val) bfin_write32(DMA11_BWM_COUNT, val) -#define bfin_read_DMA11_CURR_BWM_COUNT() bfin_read32(DMA11_CURR_BWM_COUNT) -#define bfin_write_DMA11_CURR_BWM_COUNT(val) bfin_write32(DMA11_CURR_BWM_COUNT, val) - -/* DMA Channel 12 Registers */ - -#define bfin_read_DMA12_NEXT_DESC_PTR() bfin_read32(DMA12_NEXT_DESC_PTR) -#define bfin_write_DMA12_NEXT_DESC_PTR(val) bfin_write32(DMA12_NEXT_DESC_PTR, val) -#define bfin_read_DMA12_START_ADDR() bfin_read32(DMA12_START_ADDR) -#define bfin_write_DMA12_START_ADDR(val) bfin_write32(DMA12_START_ADDR, val) -#define bfin_read_DMA12_CONFIG() bfin_read32(DMA12_CONFIG) -#define bfin_write_DMA12_CONFIG(val) bfin_write32(DMA12_CONFIG, val) -#define bfin_read_DMA12_X_COUNT() bfin_read32(DMA12_X_COUNT) -#define bfin_write_DMA12_X_COUNT(val) bfin_write32(DMA12_X_COUNT, val) -#define bfin_read_DMA12_X_MODIFY() bfin_read32(DMA12_X_MODIFY) -#define bfin_write_DMA12_X_MODIFY(val) bfin_write32(DMA12_X_MODIFY, val) -#define bfin_read_DMA12_Y_COUNT() bfin_read32(DMA12_Y_COUNT) -#define bfin_write_DMA12_Y_COUNT(val) bfin_write32(DMA12_Y_COUNT, val) -#define bfin_read_DMA12_Y_MODIFY() bfin_read32(DMA12_Y_MODIFY) -#define bfin_write_DMA12_Y_MODIFY(val) bfin_write32(DMA12_Y_MODIFY, val) -#define bfin_read_DMA12_CURR_DESC_PTR() bfin_read32(DMA12_CURR_DESC_PTR) -#define bfin_write_DMA12_CURR_DESC_PTR(val) bfin_write32(DMA12_CURR_DESC_PTR, val) -#define bfin_read_DMA12_PREV_DESC_PTR() bfin_read32(DMA12_PREV_DESC_PTR) -#define bfin_write_DMA12_PREV_DESC_PTR(val) bfin_write32(DMA12_PREV_DESC_PTR, val) -#define bfin_read_DMA12_CURR_ADDR() bfin_read32(DMA12_CURR_ADDR) -#define bfin_write_DMA12_CURR_ADDR(val) bfin_write32(DMA12_CURR_ADDR, val) -#define bfin_read_DMA12_IRQ_STATUS() bfin_read32(DMA12_IRQ_STATUS) -#define bfin_write_DMA12_IRQ_STATUS(val) bfin_write32(DMA12_IRQ_STATUS, val) -#define bfin_read_DMA12_CURR_X_COUNT() bfin_read32(DMA12_CURR_X_COUNT) -#define bfin_write_DMA12_CURR_X_COUNT(val) bfin_write32(DMA12_CURR_X_COUNT, val) -#define bfin_read_DMA12_CURR_Y_COUNT() bfin_read32(DMA12_CURR_Y_COUNT) -#define bfin_write_DMA12_CURR_Y_COUNT(val) bfin_write32(DMA12_CURR_Y_COUNT, val) -#define bfin_read_DMA12_BWL_COUNT() bfin_read32(DMA12_BWL_COUNT) -#define bfin_write_DMA12_BWL_COUNT(val) bfin_write32(DMA12_BWL_COUNT, val) -#define bfin_read_DMA12_CURR_BWL_COUNT() bfin_read32(DMA12_CURR_BWL_COUNT) -#define bfin_write_DMA12_CURR_BWL_COUNT(val) bfin_write32(DMA12_CURR_BWL_COUNT, val) -#define bfin_read_DMA12_BWM_COUNT() bfin_read32(DMA12_BWM_COUNT) -#define bfin_write_DMA12_BWM_COUNT(val) bfin_write32(DMA12_BWM_COUNT, val) -#define bfin_read_DMA12_CURR_BWM_COUNT() bfin_read32(DMA12_CURR_BWM_COUNT) -#define bfin_write_DMA12_CURR_BWM_COUNT(val) bfin_write32(DMA12_CURR_BWM_COUNT, val) - -/* DMA Channel 13 Registers */ - -#define bfin_read_DMA13_NEXT_DESC_PTR() bfin_read32(DMA13_NEXT_DESC_PTR) -#define bfin_write_DMA13_NEXT_DESC_PTR(val) bfin_write32(DMA13_NEXT_DESC_PTR, val) -#define bfin_read_DMA13_START_ADDR() bfin_read32(DMA13_START_ADDR) -#define bfin_write_DMA13_START_ADDR(val) bfin_write32(DMA13_START_ADDR, val) -#define bfin_read_DMA13_CONFIG() bfin_read32(DMA13_CONFIG) -#define bfin_write_DMA13_CONFIG(val) bfin_write32(DMA13_CONFIG, val) -#define bfin_read_DMA13_X_COUNT() bfin_read32(DMA13_X_COUNT) -#define bfin_write_DMA13_X_COUNT(val) bfin_write32(DMA13_X_COUNT, val) -#define bfin_read_DMA13_X_MODIFY() bfin_read32(DMA13_X_MODIFY) -#define bfin_write_DMA13_X_MODIFY(val) bfin_write32(DMA13_X_MODIFY, val) -#define bfin_read_DMA13_Y_COUNT() bfin_read32(DMA13_Y_COUNT) -#define bfin_write_DMA13_Y_COUNT(val) bfin_write32(DMA13_Y_COUNT, val) -#define bfin_read_DMA13_Y_MODIFY() bfin_read32(DMA13_Y_MODIFY) -#define bfin_write_DMA13_Y_MODIFY(val) bfin_write32(DMA13_Y_MODIFY, val) -#define bfin_read_DMA13_CURR_DESC_PTR() bfin_read32(DMA13_CURR_DESC_PTR) -#define bfin_write_DMA13_CURR_DESC_PTR(val) bfin_write32(DMA13_CURR_DESC_PTR, val) -#define bfin_read_DMA13_PREV_DESC_PTR() bfin_read32(DMA13_PREV_DESC_PTR) -#define bfin_write_DMA13_PREV_DESC_PTR(val) bfin_write32(DMA13_PREV_DESC_PTR, val) -#define bfin_read_DMA13_CURR_ADDR() bfin_read32(DMA13_CURR_ADDR) -#define bfin_write_DMA13_CURR_ADDR(val) bfin_write32(DMA13_CURR_ADDR, val) -#define bfin_read_DMA13_IRQ_STATUS() bfin_read32(DMA13_IRQ_STATUS) -#define bfin_write_DMA13_IRQ_STATUS(val) bfin_write32(DMA13_IRQ_STATUS, val) -#define bfin_read_DMA13_CURR_X_COUNT() bfin_read32(DMA13_CURR_X_COUNT) -#define bfin_write_DMA13_CURR_X_COUNT(val) bfin_write32(DMA13_CURR_X_COUNT, val) -#define bfin_read_DMA13_CURR_Y_COUNT() bfin_read32(DMA13_CURR_Y_COUNT) -#define bfin_write_DMA13_CURR_Y_COUNT(val) bfin_write32(DMA13_CURR_Y_COUNT, val) -#define bfin_read_DMA13_BWL_COUNT() bfin_read32(DMA13_BWL_COUNT) -#define bfin_write_DMA13_BWL_COUNT(val) bfin_write32(DMA13_BWL_COUNT, val) -#define bfin_read_DMA13_CURR_BWL_COUNT() bfin_read32(DMA13_CURR_BWL_COUNT) -#define bfin_write_DMA13_CURR_BWL_COUNT(val) bfin_write32(DMA13_CURR_BWL_COUNT, val) -#define bfin_read_DMA13_BWM_COUNT() bfin_read32(DMA13_BWM_COUNT) -#define bfin_write_DMA13_BWM_COUNT(val) bfin_write32(DMA13_BWM_COUNT, val) -#define bfin_read_DMA13_CURR_BWM_COUNT() bfin_read32(DMA13_CURR_BWM_COUNT) -#define bfin_write_DMA13_CURR_BWM_COUNT(val) bfin_write32(DMA13_CURR_BWM_COUNT, val) - -/* DMA Channel 14 Registers */ - -#define bfin_read_DMA14_NEXT_DESC_PTR() bfin_read32(DMA14_NEXT_DESC_PTR) -#define bfin_write_DMA14_NEXT_DESC_PTR(val) bfin_write32(DMA14_NEXT_DESC_PTR, val) -#define bfin_read_DMA14_START_ADDR() bfin_read32(DMA14_START_ADDR) -#define bfin_write_DMA14_START_ADDR(val) bfin_write32(DMA14_START_ADDR, val) -#define bfin_read_DMA14_CONFIG() bfin_read32(DMA14_CONFIG) -#define bfin_write_DMA14_CONFIG(val) bfin_write32(DMA14_CONFIG, val) -#define bfin_read_DMA14_X_COUNT() bfin_read32(DMA14_X_COUNT) -#define bfin_write_DMA14_X_COUNT(val) bfin_write32(DMA14_X_COUNT, val) -#define bfin_read_DMA14_X_MODIFY() bfin_read32(DMA14_X_MODIFY) -#define bfin_write_DMA14_X_MODIFY(val) bfin_write32(DMA14_X_MODIFY, val) -#define bfin_read_DMA14_Y_COUNT() bfin_read32(DMA14_Y_COUNT) -#define bfin_write_DMA14_Y_COUNT(val) bfin_write32(DMA14_Y_COUNT, val) -#define bfin_read_DMA14_Y_MODIFY() bfin_read32(DMA14_Y_MODIFY) -#define bfin_write_DMA14_Y_MODIFY(val) bfin_write32(DMA14_Y_MODIFY, val) -#define bfin_read_DMA14_CURR_DESC_PTR() bfin_read32(DMA14_CURR_DESC_PTR) -#define bfin_write_DMA14_CURR_DESC_PTR(val) bfin_write32(DMA14_CURR_DESC_PTR, val) -#define bfin_read_DMA14_PREV_DESC_PTR() bfin_read32(DMA14_PREV_DESC_PTR) -#define bfin_write_DMA14_PREV_DESC_PTR(val) bfin_write32(DMA14_PREV_DESC_PTR, val) -#define bfin_read_DMA14_CURR_ADDR() bfin_read32(DMA14_CURR_ADDR) -#define bfin_write_DMA14_CURR_ADDR(val) bfin_write32(DMA14_CURR_ADDR, val) -#define bfin_read_DMA14_IRQ_STATUS() bfin_read32(DMA14_IRQ_STATUS) -#define bfin_write_DMA14_IRQ_STATUS(val) bfin_write32(DMA14_IRQ_STATUS, val) -#define bfin_read_DMA14_CURR_X_COUNT() bfin_read32(DMA14_CURR_X_COUNT) -#define bfin_write_DMA14_CURR_X_COUNT(val) bfin_write32(DMA14_CURR_X_COUNT, val) -#define bfin_read_DMA14_CURR_Y_COUNT() bfin_read32(DMA14_CURR_Y_COUNT) -#define bfin_write_DMA14_CURR_Y_COUNT(val) bfin_write32(DMA14_CURR_Y_COUNT, val) -#define bfin_read_DMA14_BWL_COUNT() bfin_read32(DMA14_BWL_COUNT) -#define bfin_write_DMA14_BWL_COUNT(val) bfin_write32(DMA14_BWL_COUNT, val) -#define bfin_read_DMA14_CURR_BWL_COUNT() bfin_read32(DMA14_CURR_BWL_COUNT) -#define bfin_write_DMA14_CURR_BWL_COUNT(val) bfin_write32(DMA14_CURR_BWL_COUNT, val) -#define bfin_read_DMA14_BWM_COUNT() bfin_read32(DMA14_BWM_COUNT) -#define bfin_write_DMA14_BWM_COUNT(val) bfin_write32(DMA14_BWM_COUNT, val) -#define bfin_read_DMA14_CURR_BWM_COUNT() bfin_read32(DMA14_CURR_BWM_COUNT) -#define bfin_write_DMA14_CURR_BWM_COUNT(val) bfin_write32(DMA14_CURR_BWM_COUNT, val) - -/* DMA Channel 15 Registers */ - -#define bfin_read_DMA15_NEXT_DESC_PTR() bfin_read32(DMA15_NEXT_DESC_PTR) -#define bfin_write_DMA15_NEXT_DESC_PTR(val) bfin_write32(DMA15_NEXT_DESC_PTR, val) -#define bfin_read_DMA15_START_ADDR() bfin_read32(DMA15_START_ADDR) -#define bfin_write_DMA15_START_ADDR(val) bfin_write32(DMA15_START_ADDR, val) -#define bfin_read_DMA15_CONFIG() bfin_read32(DMA15_CONFIG) -#define bfin_write_DMA15_CONFIG(val) bfin_write32(DMA15_CONFIG, val) -#define bfin_read_DMA15_X_COUNT() bfin_read32(DMA15_X_COUNT) -#define bfin_write_DMA15_X_COUNT(val) bfin_write32(DMA15_X_COUNT, val) -#define bfin_read_DMA15_X_MODIFY() bfin_read32(DMA15_X_MODIFY) -#define bfin_write_DMA15_X_MODIFY(val) bfin_write32(DMA15_X_MODIFY, val) -#define bfin_read_DMA15_Y_COUNT() bfin_read32(DMA15_Y_COUNT) -#define bfin_write_DMA15_Y_COUNT(val) bfin_write32(DMA15_Y_COUNT, val) -#define bfin_read_DMA15_Y_MODIFY() bfin_read32(DMA15_Y_MODIFY) -#define bfin_write_DMA15_Y_MODIFY(val) bfin_write32(DMA15_Y_MODIFY, val) -#define bfin_read_DMA15_CURR_DESC_PTR() bfin_read32(DMA15_CURR_DESC_PTR) -#define bfin_write_DMA15_CURR_DESC_PTR(val) bfin_write32(DMA15_CURR_DESC_PTR, val) -#define bfin_read_DMA15_PREV_DESC_PTR() bfin_read32(DMA15_PREV_DESC_PTR) -#define bfin_write_DMA15_PREV_DESC_PTR(val) bfin_write32(DMA15_PREV_DESC_PTR, val) -#define bfin_read_DMA15_CURR_ADDR() bfin_read32(DMA15_CURR_ADDR) -#define bfin_write_DMA15_CURR_ADDR(val) bfin_write32(DMA15_CURR_ADDR, val) -#define bfin_read_DMA15_IRQ_STATUS() bfin_read32(DMA15_IRQ_STATUS) -#define bfin_write_DMA15_IRQ_STATUS(val) bfin_write32(DMA15_IRQ_STATUS, val) -#define bfin_read_DMA15_CURR_X_COUNT() bfin_read32(DMA15_CURR_X_COUNT) -#define bfin_write_DMA15_CURR_X_COUNT(val) bfin_write32(DMA15_CURR_X_COUNT, val) -#define bfin_read_DMA15_CURR_Y_COUNT() bfin_read32(DMA15_CURR_Y_COUNT) -#define bfin_write_DMA15_CURR_Y_COUNT(val) bfin_write32(DMA15_CURR_Y_COUNT, val) -#define bfin_read_DMA15_BWL_COUNT() bfin_read32(DMA15_BWL_COUNT) -#define bfin_write_DMA15_BWL_COUNT(val) bfin_write32(DMA15_BWL_COUNT, val) -#define bfin_read_DMA15_CURR_BWL_COUNT() bfin_read32(DMA15_CURR_BWL_COUNT) -#define bfin_write_DMA15_CURR_BWL_COUNT(val) bfin_write32(DMA15_CURR_BWL_COUNT, val) -#define bfin_read_DMA15_BWM_COUNT() bfin_read32(DMA15_BWM_COUNT) -#define bfin_write_DMA15_BWM_COUNT(val) bfin_write32(DMA15_BWM_COUNT, val) -#define bfin_read_DMA15_CURR_BWM_COUNT() bfin_read32(DMA15_CURR_BWM_COUNT) -#define bfin_write_DMA15_CURR_BWM_COUNT(val) bfin_write32(DMA15_CURR_BWM_COUNT, val) - -/* DMA Channel 16 Registers */ - -#define bfin_read_DMA16_NEXT_DESC_PTR() bfin_read32(DMA16_NEXT_DESC_PTR) -#define bfin_write_DMA16_NEXT_DESC_PTR(val) bfin_write32(DMA16_NEXT_DESC_PTR, val) -#define bfin_read_DMA16_START_ADDR() bfin_read32(DMA16_START_ADDR) -#define bfin_write_DMA16_START_ADDR(val) bfin_write32(DMA16_START_ADDR, val) -#define bfin_read_DMA16_CONFIG() bfin_read32(DMA16_CONFIG) -#define bfin_write_DMA16_CONFIG(val) bfin_write32(DMA16_CONFIG, val) -#define bfin_read_DMA16_X_COUNT() bfin_read32(DMA16_X_COUNT) -#define bfin_write_DMA16_X_COUNT(val) bfin_write32(DMA16_X_COUNT, val) -#define bfin_read_DMA16_X_MODIFY() bfin_read32(DMA16_X_MODIFY) -#define bfin_write_DMA16_X_MODIFY(val) bfin_write32(DMA16_X_MODIFY, val) -#define bfin_read_DMA16_Y_COUNT() bfin_read32(DMA16_Y_COUNT) -#define bfin_write_DMA16_Y_COUNT(val) bfin_write32(DMA16_Y_COUNT, val) -#define bfin_read_DMA16_Y_MODIFY() bfin_read32(DMA16_Y_MODIFY) -#define bfin_write_DMA16_Y_MODIFY(val) bfin_write32(DMA16_Y_MODIFY, val) -#define bfin_read_DMA16_CURR_DESC_PTR() bfin_read32(DMA16_CURR_DESC_PTR) -#define bfin_write_DMA16_CURR_DESC_PTR(val) bfin_write32(DMA16_CURR_DESC_PTR, val) -#define bfin_read_DMA16_PREV_DESC_PTR() bfin_read32(DMA16_PREV_DESC_PTR) -#define bfin_write_DMA16_PREV_DESC_PTR(val) bfin_write32(DMA16_PREV_DESC_PTR, val) -#define bfin_read_DMA16_CURR_ADDR() bfin_read32(DMA16_CURR_ADDR) -#define bfin_write_DMA16_CURR_ADDR(val) bfin_write32(DMA16_CURR_ADDR, val) -#define bfin_read_DMA16_IRQ_STATUS() bfin_read32(DMA16_IRQ_STATUS) -#define bfin_write_DMA16_IRQ_STATUS(val) bfin_write32(DMA16_IRQ_STATUS, val) -#define bfin_read_DMA16_CURR_X_COUNT() bfin_read32(DMA16_CURR_X_COUNT) -#define bfin_write_DMA16_CURR_X_COUNT(val) bfin_write32(DMA16_CURR_X_COUNT, val) -#define bfin_read_DMA16_CURR_Y_COUNT() bfin_read32(DMA16_CURR_Y_COUNT) -#define bfin_write_DMA16_CURR_Y_COUNT(val) bfin_write32(DMA16_CURR_Y_COUNT, val) -#define bfin_read_DMA16_BWL_COUNT() bfin_read32(DMA16_BWL_COUNT) -#define bfin_write_DMA16_BWL_COUNT(val) bfin_write32(DMA16_BWL_COUNT, val) -#define bfin_read_DMA16_CURR_BWL_COUNT() bfin_read32(DMA16_CURR_BWL_COUNT) -#define bfin_write_DMA16_CURR_BWL_COUNT(val) bfin_write32(DMA16_CURR_BWL_COUNT, val) -#define bfin_read_DMA16_BWM_COUNT() bfin_read32(DMA16_BWM_COUNT) -#define bfin_write_DMA16_BWM_COUNT(val) bfin_write32(DMA16_BWM_COUNT, val) -#define bfin_read_DMA16_CURR_BWM_COUNT() bfin_read32(DMA16_CURR_BWM_COUNT) -#define bfin_write_DMA16_CURR_BWM_COUNT(val) bfin_write32(DMA16_CURR_BWM_COUNT, val) - -/* DMA Channel 17 Registers */ - -#define bfin_read_DMA17_NEXT_DESC_PTR() bfin_read32(DMA17_NEXT_DESC_PTR) -#define bfin_write_DMA17_NEXT_DESC_PTR(val) bfin_write32(DMA17_NEXT_DESC_PTR, val) -#define bfin_read_DMA17_START_ADDR() bfin_read32(DMA17_START_ADDR) -#define bfin_write_DMA17_START_ADDR(val) bfin_write32(DMA17_START_ADDR, val) -#define bfin_read_DMA17_CONFIG() bfin_read32(DMA17_CONFIG) -#define bfin_write_DMA17_CONFIG(val) bfin_write32(DMA17_CONFIG, val) -#define bfin_read_DMA17_X_COUNT() bfin_read32(DMA17_X_COUNT) -#define bfin_write_DMA17_X_COUNT(val) bfin_write32(DMA17_X_COUNT, val) -#define bfin_read_DMA17_X_MODIFY() bfin_read32(DMA17_X_MODIFY) -#define bfin_write_DMA17_X_MODIFY(val) bfin_write32(DMA17_X_MODIFY, val) -#define bfin_read_DMA17_Y_COUNT() bfin_read32(DMA17_Y_COUNT) -#define bfin_write_DMA17_Y_COUNT(val) bfin_write32(DMA17_Y_COUNT, val) -#define bfin_read_DMA17_Y_MODIFY() bfin_read32(DMA17_Y_MODIFY) -#define bfin_write_DMA17_Y_MODIFY(val) bfin_write32(DMA17_Y_MODIFY, val) -#define bfin_read_DMA17_CURR_DESC_PTR() bfin_read32(DMA17_CURR_DESC_PTR) -#define bfin_write_DMA17_CURR_DESC_PTR(val) bfin_write32(DMA17_CURR_DESC_PTR, val) -#define bfin_read_DMA17_PREV_DESC_PTR() bfin_read32(DMA17_PREV_DESC_PTR) -#define bfin_write_DMA17_PREV_DESC_PTR(val) bfin_write32(DMA17_PREV_DESC_PTR, val) -#define bfin_read_DMA17_CURR_ADDR() bfin_read32(DMA17_CURR_ADDR) -#define bfin_write_DMA17_CURR_ADDR(val) bfin_write32(DMA17_CURR_ADDR, val) -#define bfin_read_DMA17_IRQ_STATUS() bfin_read32(DMA17_IRQ_STATUS) -#define bfin_write_DMA17_IRQ_STATUS(val) bfin_write32(DMA17_IRQ_STATUS, val) -#define bfin_read_DMA17_CURR_X_COUNT() bfin_read32(DMA17_CURR_X_COUNT) -#define bfin_write_DMA17_CURR_X_COUNT(val) bfin_write32(DMA17_CURR_X_COUNT, val) -#define bfin_read_DMA17_CURR_Y_COUNT() bfin_read32(DMA17_CURR_Y_COUNT) -#define bfin_write_DMA17_CURR_Y_COUNT(val) bfin_write32(DMA17_CURR_Y_COUNT, val) -#define bfin_read_DMA17_BWL_COUNT() bfin_read32(DMA17_BWL_COUNT) -#define bfin_write_DMA17_BWL_COUNT(val) bfin_write32(DMA17_BWL_COUNT, val) -#define bfin_read_DMA17_CURR_BWL_COUNT() bfin_read32(DMA17_CURR_BWL_COUNT) -#define bfin_write_DMA17_CURR_BWL_COUNT(val) bfin_write32(DMA17_CURR_BWL_COUNT, val) -#define bfin_read_DMA17_BWM_COUNT() bfin_read32(DMA17_BWM_COUNT) -#define bfin_write_DMA17_BWM_COUNT(val) bfin_write32(DMA17_BWM_COUNT, val) -#define bfin_read_DMA17_CURR_BWM_COUNT() bfin_read32(DMA17_CURR_BWM_COUNT) -#define bfin_write_DMA17_CURR_BWM_COUNT(val) bfin_write32(DMA17_CURR_BWM_COUNT, val) - -/* DMA Channel 18 Registers */ - -#define bfin_read_DMA18_NEXT_DESC_PTR() bfin_read32(DMA18_NEXT_DESC_PTR) -#define bfin_write_DMA18_NEXT_DESC_PTR(val) bfin_write32(DMA18_NEXT_DESC_PTR, val) -#define bfin_read_DMA18_START_ADDR() bfin_read32(DMA18_START_ADDR) -#define bfin_write_DMA18_START_ADDR(val) bfin_write32(DMA18_START_ADDR, val) -#define bfin_read_DMA18_CONFIG() bfin_read32(DMA18_CONFIG) -#define bfin_write_DMA18_CONFIG(val) bfin_write32(DMA18_CONFIG, val) -#define bfin_read_DMA18_X_COUNT() bfin_read32(DMA18_X_COUNT) -#define bfin_write_DMA18_X_COUNT(val) bfin_write32(DMA18_X_COUNT, val) -#define bfin_read_DMA18_X_MODIFY() bfin_read32(DMA18_X_MODIFY) -#define bfin_write_DMA18_X_MODIFY(val) bfin_write32(DMA18_X_MODIFY, val) -#define bfin_read_DMA18_Y_COUNT() bfin_read32(DMA18_Y_COUNT) -#define bfin_write_DMA18_Y_COUNT(val) bfin_write32(DMA18_Y_COUNT, val) -#define bfin_read_DMA18_Y_MODIFY() bfin_read32(DMA18_Y_MODIFY) -#define bfin_write_DMA18_Y_MODIFY(val) bfin_write32(DMA18_Y_MODIFY, val) -#define bfin_read_DMA18_CURR_DESC_PTR() bfin_read32(DMA18_CURR_DESC_PTR) -#define bfin_write_DMA18_CURR_DESC_PTR(val) bfin_write32(DMA18_CURR_DESC_PTR, val) -#define bfin_read_DMA18_PREV_DESC_PTR() bfin_read32(DMA18_PREV_DESC_PTR) -#define bfin_write_DMA18_PREV_DESC_PTR(val) bfin_write32(DMA18_PREV_DESC_PTR, val) -#define bfin_read_DMA18_CURR_ADDR() bfin_read32(DMA18_CURR_ADDR) -#define bfin_write_DMA18_CURR_ADDR(val) bfin_write32(DMA18_CURR_ADDR, val) -#define bfin_read_DMA18_IRQ_STATUS() bfin_read32(DMA18_IRQ_STATUS) -#define bfin_write_DMA18_IRQ_STATUS(val) bfin_write32(DMA18_IRQ_STATUS, val) -#define bfin_read_DMA18_CURR_X_COUNT() bfin_read32(DMA18_CURR_X_COUNT) -#define bfin_write_DMA18_CURR_X_COUNT(val) bfin_write32(DMA18_CURR_X_COUNT, val) -#define bfin_read_DMA18_CURR_Y_COUNT() bfin_read32(DMA18_CURR_Y_COUNT) -#define bfin_write_DMA18_CURR_Y_COUNT(val) bfin_write32(DMA18_CURR_Y_COUNT, val) -#define bfin_read_DMA18_BWL_COUNT() bfin_read32(DMA18_BWL_COUNT) -#define bfin_write_DMA18_BWL_COUNT(val) bfin_write32(DMA18_BWL_COUNT, val) -#define bfin_read_DMA18_CURR_BWL_COUNT() bfin_read32(DMA18_CURR_BWL_COUNT) -#define bfin_write_DMA18_CURR_BWL_COUNT(val) bfin_write32(DMA18_CURR_BWL_COUNT, val) -#define bfin_read_DMA18_BWM_COUNT() bfin_read32(DMA18_BWM_COUNT) -#define bfin_write_DMA18_BWM_COUNT(val) bfin_write32(DMA18_BWM_COUNT, val) -#define bfin_read_DMA18_CURR_BWM_COUNT() bfin_read32(DMA18_CURR_BWM_COUNT) -#define bfin_write_DMA18_CURR_BWM_COUNT(val) bfin_write32(DMA18_CURR_BWM_COUNT, val) - -/* DMA Channel 19 Registers */ - -#define bfin_read_DMA19_NEXT_DESC_PTR() bfin_read32(DMA19_NEXT_DESC_PTR) -#define bfin_write_DMA19_NEXT_DESC_PTR(val) bfin_write32(DMA19_NEXT_DESC_PTR, val) -#define bfin_read_DMA19_START_ADDR() bfin_read32(DMA19_START_ADDR) -#define bfin_write_DMA19_START_ADDR(val) bfin_write32(DMA19_START_ADDR, val) -#define bfin_read_DMA19_CONFIG() bfin_read32(DMA19_CONFIG) -#define bfin_write_DMA19_CONFIG(val) bfin_write32(DMA19_CONFIG, val) -#define bfin_read_DMA19_X_COUNT() bfin_read32(DMA19_X_COUNT) -#define bfin_write_DMA19_X_COUNT(val) bfin_write32(DMA19_X_COUNT, val) -#define bfin_read_DMA19_X_MODIFY() bfin_read32(DMA19_X_MODIFY) -#define bfin_write_DMA19_X_MODIFY(val) bfin_write32(DMA19_X_MODIFY, val) -#define bfin_read_DMA19_Y_COUNT() bfin_read32(DMA19_Y_COUNT) -#define bfin_write_DMA19_Y_COUNT(val) bfin_write32(DMA19_Y_COUNT, val) -#define bfin_read_DMA19_Y_MODIFY() bfin_read32(DMA19_Y_MODIFY) -#define bfin_write_DMA19_Y_MODIFY(val) bfin_write32(DMA19_Y_MODIFY, val) -#define bfin_read_DMA19_CURR_DESC_PTR() bfin_read32(DMA19_CURR_DESC_PTR) -#define bfin_write_DMA19_CURR_DESC_PTR(val) bfin_write32(DMA19_CURR_DESC_PTR, val) -#define bfin_read_DMA19_PREV_DESC_PTR() bfin_read32(DMA19_PREV_DESC_PTR) -#define bfin_write_DMA19_PREV_DESC_PTR(val) bfin_write32(DMA19_PREV_DESC_PTR, val) -#define bfin_read_DMA19_CURR_ADDR() bfin_read32(DMA19_CURR_ADDR) -#define bfin_write_DMA19_CURR_ADDR(val) bfin_write32(DMA19_CURR_ADDR, val) -#define bfin_read_DMA19_IRQ_STATUS() bfin_read32(DMA19_IRQ_STATUS) -#define bfin_write_DMA19_IRQ_STATUS(val) bfin_write32(DMA19_IRQ_STATUS, val) -#define bfin_read_DMA19_CURR_X_COUNT() bfin_read32(DMA19_CURR_X_COUNT) -#define bfin_write_DMA19_CURR_X_COUNT(val) bfin_write32(DMA19_CURR_X_COUNT, val) -#define bfin_read_DMA19_CURR_Y_COUNT() bfin_read32(DMA19_CURR_Y_COUNT) -#define bfin_write_DMA19_CURR_Y_COUNT(val) bfin_write32(DMA19_CURR_Y_COUNT, val) -#define bfin_read_DMA19_BWL_COUNT() bfin_read32(DMA19_BWL_COUNT) -#define bfin_write_DMA19_BWL_COUNT(val) bfin_write32(DMA19_BWL_COUNT, val) -#define bfin_read_DMA19_CURR_BWL_COUNT() bfin_read32(DMA19_CURR_BWL_COUNT) -#define bfin_write_DMA19_CURR_BWL_COUNT(val) bfin_write32(DMA19_CURR_BWL_COUNT, val) -#define bfin_read_DMA19_BWM_COUNT() bfin_read32(DMA19_BWM_COUNT) -#define bfin_write_DMA19_BWM_COUNT(val) bfin_write32(DMA19_BWM_COUNT, val) -#define bfin_read_DMA19_CURR_BWM_COUNT() bfin_read32(DMA19_CURR_BWM_COUNT) -#define bfin_write_DMA19_CURR_BWM_COUNT(val) bfin_write32(DMA19_CURR_BWM_COUNT, val) - -/* DMA Channel 20 Registers */ - -#define bfin_read_DMA20_NEXT_DESC_PTR() bfin_read32(DMA20_NEXT_DESC_PTR) -#define bfin_write_DMA20_NEXT_DESC_PTR(val) bfin_write32(DMA20_NEXT_DESC_PTR, val) -#define bfin_read_DMA20_START_ADDR() bfin_read32(DMA20_START_ADDR) -#define bfin_write_DMA20_START_ADDR(val) bfin_write32(DMA20_START_ADDR, val) -#define bfin_read_DMA20_CONFIG() bfin_read32(DMA20_CONFIG) -#define bfin_write_DMA20_CONFIG(val) bfin_write32(DMA20_CONFIG, val) -#define bfin_read_DMA20_X_COUNT() bfin_read32(DMA20_X_COUNT) -#define bfin_write_DMA20_X_COUNT(val) bfin_write32(DMA20_X_COUNT, val) -#define bfin_read_DMA20_X_MODIFY() bfin_read32(DMA20_X_MODIFY) -#define bfin_write_DMA20_X_MODIFY(val) bfin_write32(DMA20_X_MODIFY, val) -#define bfin_read_DMA20_Y_COUNT() bfin_read32(DMA20_Y_COUNT) -#define bfin_write_DMA20_Y_COUNT(val) bfin_write32(DMA20_Y_COUNT, val) -#define bfin_read_DMA20_Y_MODIFY() bfin_read32(DMA20_Y_MODIFY) -#define bfin_write_DMA20_Y_MODIFY(val) bfin_write32(DMA20_Y_MODIFY, val) -#define bfin_read_DMA20_CURR_DESC_PTR() bfin_read32(DMA20_CURR_DESC_PTR) -#define bfin_write_DMA20_CURR_DESC_PTR(val) bfin_write32(DMA20_CURR_DESC_PTR, val) -#define bfin_read_DMA20_PREV_DESC_PTR() bfin_read32(DMA20_PREV_DESC_PTR) -#define bfin_write_DMA20_PREV_DESC_PTR(val) bfin_write32(DMA20_PREV_DESC_PTR, val) -#define bfin_read_DMA20_CURR_ADDR() bfin_read32(DMA20_CURR_ADDR) -#define bfin_write_DMA20_CURR_ADDR(val) bfin_write32(DMA20_CURR_ADDR, val) -#define bfin_read_DMA20_IRQ_STATUS() bfin_read32(DMA20_IRQ_STATUS) -#define bfin_write_DMA20_IRQ_STATUS(val) bfin_write32(DMA20_IRQ_STATUS, val) -#define bfin_read_DMA20_CURR_X_COUNT() bfin_read32(DMA20_CURR_X_COUNT) -#define bfin_write_DMA20_CURR_X_COUNT(val) bfin_write32(DMA20_CURR_X_COUNT, val) -#define bfin_read_DMA20_CURR_Y_COUNT() bfin_read32(DMA20_CURR_Y_COUNT) -#define bfin_write_DMA20_CURR_Y_COUNT(val) bfin_write32(DMA20_CURR_Y_COUNT, val) -#define bfin_read_DMA20_BWL_COUNT() bfin_read32(DMA20_BWL_COUNT) -#define bfin_write_DMA20_BWL_COUNT(val) bfin_write32(DMA20_BWL_COUNT, val) -#define bfin_read_DMA20_CURR_BWL_COUNT() bfin_read32(DMA20_CURR_BWL_COUNT) -#define bfin_write_DMA20_CURR_BWL_COUNT(val) bfin_write32(DMA20_CURR_BWL_COUNT, val) -#define bfin_read_DMA20_BWM_COUNT() bfin_read32(DMA20_BWM_COUNT) -#define bfin_write_DMA20_BWM_COUNT(val) bfin_write32(DMA20_BWM_COUNT, val) -#define bfin_read_DMA20_CURR_BWM_COUNT() bfin_read32(DMA20_CURR_BWM_COUNT) -#define bfin_write_DMA20_CURR_BWM_COUNT(val) bfin_write32(DMA20_CURR_BWM_COUNT, val) - - -/* MDMA Stream 0 Registers (DMA Channel 21 and 22) */ - -#define bfin_read_MDMA0_DEST_CRC0_NEXT_DESC_PTR() bfin_read32(MDMA0_DEST_CRC0_NEXT_DESC_PTR) -#define bfin_write_MDMA0_DEST_CRC0_NEXT_DESC_PTR(val) bfin_write32(MDMA0_DEST_CRC0_NEXT_DESC_PTR, val) -#define bfin_read_MDMA0_DEST_CRC0_START_ADDR() bfin_read32(MDMA0_DEST_CRC0_START_ADDR) -#define bfin_write_MDMA0_DEST_CRC0_START_ADDR(val) bfin_write32(MDMA0_DEST_CRC0_START_ADDR, val) -#define bfin_read_MDMA0_DEST_CRC0_CONFIG() bfin_read32(MDMA0_DEST_CRC0_CONFIG) -#define bfin_write_MDMA0_DEST_CRC0_CONFIG(val) bfin_write32(MDMA0_DEST_CRC0_CONFIG, val) -#define bfin_read_MDMA0_DEST_CRC0_X_COUNT() bfin_read32(MDMA0_DEST_CRC0_X_COUNT) -#define bfin_write_MDMA0_DEST_CRC0_X_COUNT(val) bfin_write32(MDMA0_DEST_CRC0_X_COUNT, val) -#define bfin_read_MDMA0_DEST_CRC0_X_MODIFY() bfin_read32(MDMA0_DEST_CRC0_X_MODIFY) -#define bfin_write_MDMA0_DEST_CRC0_X_MODIFY(val) bfin_write32(MDMA0_DEST_CRC0_X_MODIFY, val) -#define bfin_read_MDMA0_DEST_CRC0_Y_COUNT() bfin_read32(MDMA0_DEST_CRC0_Y_COUNT) -#define bfin_write_MDMA0_DEST_CRC0_Y_COUNT(val) bfin_write32(MDMA0_DEST_CRC0_Y_COUNT, val) -#define bfin_read_MDMA0_DEST_CRC0_Y_MODIFY() bfin_read32(MDMA0_DEST_CRC0_Y_MODIFY) -#define bfin_write_MDMA0_DEST_CRC0_Y_MODIFY(val) bfin_write32(MDMA0_DEST_CRC0_Y_MODIFY, val) -#define bfin_read_MDMA0_DEST_CRC0_CURR_DESC_PTR() bfin_read32(MDMA0_DEST_CRC0_CURR_DESC_PTR) -#define bfin_write_MDMA0_DEST_CRC0_CURR_DESC_PTR(val) bfin_write32(MDMA0_DEST_CRC0_CURR_DESC_PTR, val) -#define bfin_read_MDMA0_DEST_CRC0_PREV_DESC_PTR() bfin_read32(MDMA0_DEST_CRC0_PREV_DESC_PTR) -#define bfin_write_MDMA0_DEST_CRC0_PREV_DESC_PTR(val) bfin_write32(MDMA0_DEST_CRC0_PREV_DESC_PTR, val) -#define bfin_read_MDMA0_DEST_CRC0_CURR_ADDR() bfin_read32(MDMA0_DEST_CRC0_CURR_ADDR) -#define bfin_write_MDMA0_DEST_CRC0_CURR_ADDR(val) bfin_write32(MDMA0_DEST_CRC0_CURR_ADDR, val) -#define bfin_read_MDMA0_DEST_CRC0_IRQ_STATUS() bfin_read32(MDMA0_DEST_CRC0_IRQ_STATUS) -#define bfin_write_MDMA0_DEST_CRC0_IRQ_STATUS(val) bfin_write32(MDMA0_DEST_CRC0_IRQ_STATUS, val) -#define bfin_read_MDMA0_DEST_CRC0_CURR_X_COUNT() bfin_read32(MDMA0_DEST_CRC0_CURR_X_COUNT) -#define bfin_write_MDMA0_DEST_CRC0_CURR_X_COUNT(val) bfin_write32(MDMA0_DEST_CRC0_CURR_X_COUNT, val) -#define bfin_read_MDMA0_DEST_CRC0_CURR_Y_COUNT() bfin_read32(MDMA0_DEST_CRC0_CURR_Y_COUNT) -#define bfin_write_MDMA0_DEST_CRC0_CURR_Y_COUNT(val) bfin_write32(MDMA0_DEST_CRC0_CURR_Y_COUNT, val) -#define bfin_read_MDMA0_SRC_CRC0_NEXT_DESC_PTR() bfin_read32(MDMA0_SRC_CRC0_NEXT_DESC_PTR) -#define bfin_write_MDMA0_SRC_CRC0_NEXT_DESC_PTR(val) bfin_write32(MDMA0_SRC_CRC0_NEXT_DESC_PTR, val) -#define bfin_read_MDMA0_SRC_CRC0_START_ADDR() bfin_read32(MDMA0_SRC_CRC0_START_ADDR) -#define bfin_write_MDMA0_SRC_CRC0_START_ADDR(val) bfin_write32(MDMA0_SRC_CRC0_START_ADDR, val) -#define bfin_read_MDMA0_SRC_CRC0_CONFIG() bfin_read32(MDMA0_SRC_CRC0_CONFIG) -#define bfin_write_MDMA0_SRC_CRC0_CONFIG(val) bfin_write32(MDMA0_SRC_CRC0_CONFIG, val) -#define bfin_read_MDMA0_SRC_CRC0_X_COUNT() bfin_read32(MDMA0_SRC_CRC0_X_COUNT) -#define bfin_write_MDMA0_SRC_CRC0_X_COUNT(val) bfin_write32(MDMA0_SRC_CRC0_X_COUNT, val) -#define bfin_read_MDMA0_SRC_CRC0_X_MODIFY() bfin_read32(MDMA0_SRC_CRC0_X_MODIFY) -#define bfin_write_MDMA0_SRC_CRC0_X_MODIFY(val) bfin_write32(MDMA0_SRC_CRC0_X_MODIFY, val) -#define bfin_read_MDMA0_SRC_CRC0_Y_COUNT() bfin_read32(MDMA0_SRC_CRC0_Y_COUNT) -#define bfin_write_MDMA0_SRC_CRC0_Y_COUNT(val) bfin_write32(MDMA0_SRC_CRC0_Y_COUNT, val) -#define bfin_read_MDMA0_SRC_CRC0_Y_MODIFY() bfin_read32(MDMA0_SRC_CRC0_Y_MODIFY) -#define bfin_write_MDMA0_SRC_CRC0_Y_MODIFY(val) bfin_write32(MDMA0_SRC_CRC0_Y_MODIFY, val) -#define bfin_read_MDMA0_SRC_CRC0_CURR_DESC_PTR() bfin_read32(MDMA0_SRC_CRC0_CURR_DESC_PTR) -#define bfin_write_MDMA0_SRC_CRC0_CURR_DESC_PTR(val) bfin_write32(MDMA0_SRC_CRC0_CURR_DESC_PTR, val) -#define bfin_read_MDMA0_SRC_CRC0_PREV_DESC_PTR() bfin_read32(MDMA0_SRC_CRC0_PREV_DESC_PTR) -#define bfin_write_MDMA0_SRC_CRC0_PREV_DESC_PTR(val) bfin_write32(MDMA0_SRC_CRC0_PREV_DESC_PTR, val) -#define bfin_read_MDMA0_SRC_CRC0_CURR_ADDR() bfin_read32(MDMA0_SRC_CRC0_CURR_ADDR) -#define bfin_write_MDMA0_SRC_CRC0_CURR_ADDR(val) bfin_write32(MDMA0_SRC_CRC0_CURR_ADDR, val) -#define bfin_read_MDMA0_SRC_CRC0_IRQ_STATUS() bfin_read32(MDMA0_SRC_CRC0_IRQ_STATUS) -#define bfin_write_MDMA0_SRC_CRC0_IRQ_STATUS(val) bfin_write32(MDMA0_SRC_CRC0_IRQ_STATUS, val) -#define bfin_read_MDMA0_SRC_CRC0_CURR_X_COUNT() bfin_read32(MDMA0_SRC_CRC0_CURR_X_COUNT) -#define bfin_write_MDMA0_SRC_CRC0_CURR_X_COUNT(val) bfin_write32(MDMA0_SRC_CRC0_CURR_X_COUNT, val) -#define bfin_read_MDMA0_SRC_CRC0_CURR_Y_COUNT() bfin_read32(MDMA0_SRC_CRC0_CURR_Y_COUNT) -#define bfin_write_MDMA0_SRC_CRC0_CURR_Y_COUNT(val) bfin_write32(MDMA0_SRC_CRC0_CURR_Y_COUNT, val) - -/* MDMA Stream 1 Registers (DMA Channel 23 and 24) */ - -#define bfin_read_MDMA1_DEST_CRC1_NEXT_DESC_PTR() bfin_read32(MDMA1_DEST_CRC1_NEXT_DESC_PTR) -#define bfin_write_MDMA1_DEST_CRC1_NEXT_DESC_PTR(val) bfin_write32(MDMA1_DEST_CRC1_NEXT_DESC_PTR, val) -#define bfin_read_MDMA1_DEST_CRC1_START_ADDR() bfin_read32(MDMA1_DEST_CRC1_START_ADDR) -#define bfin_write_MDMA1_DEST_CRC1_START_ADDR(val) bfin_write32(MDMA1_DEST_CRC1_START_ADDR, val) -#define bfin_read_MDMA1_DEST_CRC1_CONFIG() bfin_read32(MDMA1_DEST_CRC1_CONFIG) -#define bfin_write_MDMA1_DEST_CRC1_CONFIG(val) bfin_write32(MDMA1_DEST_CRC1_CONFIG, val) -#define bfin_read_MDMA1_DEST_CRC1_X_COUNT() bfin_read32(MDMA1_DEST_CRC1_X_COUNT) -#define bfin_write_MDMA1_DEST_CRC1_X_COUNT(val) bfin_write32(MDMA1_DEST_CRC1_X_COUNT, val) -#define bfin_read_MDMA1_DEST_CRC1_X_MODIFY() bfin_read32(MDMA1_DEST_CRC1_X_MODIFY) -#define bfin_write_MDMA1_DEST_CRC1_X_MODIFY(val) bfin_write32(MDMA1_DEST_CRC1_X_MODIFY, val) -#define bfin_read_MDMA1_DEST_CRC1_Y_COUNT() bfin_read32(MDMA1_DEST_CRC1_Y_COUNT) -#define bfin_write_MDMA1_DEST_CRC1_Y_COUNT(val) bfin_write32(MDMA1_DEST_CRC1_Y_COUNT, val) -#define bfin_read_MDMA1_DEST_CRC1_Y_MODIFY() bfin_read32(MDMA1_DEST_CRC1_Y_MODIFY) -#define bfin_write_MDMA1_DEST_CRC1_Y_MODIFY(val) bfin_write32(MDMA1_DEST_CRC1_Y_MODIFY, val) -#define bfin_read_MDMA1_DEST_CRC1_CURR_DESC_PTR() bfin_read32(MDMA1_DEST_CRC1_CURR_DESC_PTR) -#define bfin_write_MDMA1_DEST_CRC1_CURR_DESC_PTR(val) bfin_write32(MDMA1_DEST_CRC1_CURR_DESC_PTR, val) -#define bfin_read_MDMA1_DEST_CRC1_PREV_DESC_PTR() bfin_read32(MDMA1_DEST_CRC1_PREV_DESC_PTR) -#define bfin_write_MDMA1_DEST_CRC1_PREV_DESC_PTR(val) bfin_write32(MDMA1_DEST_CRC1_PREV_DESC_PTR, val) -#define bfin_read_MDMA1_DEST_CRC1_CURR_ADDR() bfin_read32(MDMA1_DEST_CRC1_CURR_ADDR) -#define bfin_write_MDMA1_DEST_CRC1_CURR_ADDR(val) bfin_write32(MDMA1_DEST_CRC1_CURR_ADDR, val) -#define bfin_read_MDMA1_DEST_CRC1_IRQ_STATUS() bfin_read32(MDMA1_DEST_CRC1_IRQ_STATUS) -#define bfin_write_MDMA1_DEST_CRC1_IRQ_STATUS(val) bfin_write32(MDMA1_DEST_CRC1_IRQ_STATUS, val) -#define bfin_read_MDMA1_DEST_CRC1_CURR_X_COUNT() bfin_read32(MDMA1_DEST_CRC1_CURR_X_COUNT) -#define bfin_write_MDMA1_DEST_CRC1_CURR_X_COUNT(val) bfin_write32(MDMA1_DEST_CRC1_CURR_X_COUNT, val) -#define bfin_read_MDMA1_DEST_CRC1_CURR_Y_COUNT() bfin_read32(MDMA1_DEST_CRC1_CURR_Y_COUNT) -#define bfin_write_MDMA1_DEST_CRC1_CURR_Y_COUNT(val) bfin_write32(MDMA1_DEST_CRC1_CURR_Y_COUNT, val) -#define bfin_read_MDMA1_SRC_CRC1_NEXT_DESC_PTR() bfin_read32(MDMA1_SRC_CRC1_NEXT_DESC_PTR) -#define bfin_write_MDMA1_SRC_CRC1_NEXT_DESC_PTR(val) bfin_write32(MDMA1_SRC_CRC1_NEXT_DESC_PTR, val) -#define bfin_read_MDMA1_SRC_CRC1_START_ADDR() bfin_read32(MDMA1_SRC_CRC1_START_ADDR) -#define bfin_write_MDMA1_SRC_CRC1_START_ADDR(val) bfin_write32(MDMA1_SRC_CRC1_START_ADDR, val) -#define bfin_read_MDMA1_SRC_CRC1_CONFIG() bfin_read32(MDMA1_SRC_CRC1_CONFIG) -#define bfin_write_MDMA1_SRC_CRC1_CONFIG(val) bfin_write32(MDMA1_SRC_CRC1_CONFIG, val) -#define bfin_read_MDMA1_SRC_CRC1_X_COUNT() bfin_read32(MDMA1_SRC_CRC1_X_COUNT) -#define bfin_write_MDMA1_SRC_CRC1_X_COUNT(val) bfin_write32(MDMA1_SRC_CRC1_X_COUNT, val) -#define bfin_read_MDMA1_SRC_CRC1_X_MODIFY() bfin_read32(MDMA1_SRC_CRC1_X_MODIFY) -#define bfin_write_MDMA1_SRC_CRC1_X_MODIFY(val) bfin_write32(MDMA1_SRC_CRC1_X_MODIFY, val) -#define bfin_read_MDMA1_SRC_CRC1_Y_COUNT() bfin_read32(MDMA1_SRC_CRC1_Y_COUNT) -#define bfin_write_MDMA1_SRC_CRC1_Y_COUNT(val) bfin_write32(MDMA1_SRC_CRC1_Y_COUNT, val) -#define bfin_read_MDMA1_SRC_CRC1_Y_MODIFY() bfin_read32(MDMA1_SRC_CRC1_Y_MODIFY) -#define bfin_write_MDMA1_SRC_CRC1_Y_MODIFY(val) bfin_write32(MDMA1_SRC_CRC1_Y_MODIFY, val) -#define bfin_read_MDMA1_SRC_CRC1_CURR_DESC_PTR() bfin_read32(MDMA1_SRC_CRC1_CURR_DESC_PTR) -#define bfin_write_MDMA1_SRC_CRC1_CURR_DESC_PTR(val) bfin_write32(MDMA1_SRC_CRC1_CURR_DESC_PTR, val) -#define bfin_read_MDMA1_SRC_CRC1_PREV_DESC_PTR() bfin_read32(MDMA1_SRC_CRC1_PREV_DESC_PTR) -#define bfin_write_MDMA1_SRC_CRC1_PREV_DESC_PTR(val) bfin_write32(MDMA1_SRC_CRC1_PREV_DESC_PTR, val) -#define bfin_read_MDMA1_SRC_CRC1_CURR_ADDR() bfin_read32(MDMA1_SRC_CRC1_CURR_ADDR) -#define bfin_write_MDMA1_SRC_CRC1_CURR_ADDR(val) bfin_write32(MDMA1_SRC_CRC1_CURR_ADDR, val) -#define bfin_read_MDMA1_SRC_CRC1_IRQ_STATUS() bfin_read32(MDMA1_SRC_CRC1_IRQ_STATUS) -#define bfin_write_MDMA1_SRC_CRC1_IRQ_STATUS(val) bfin_write32(MDMA1_SRC_CRC1_IRQ_STATUS, val) -#define bfin_read_MDMA1_SRC_CRC1_CURR_X_COUNT() bfin_read32(MDMA1_SRC_CRC1_CURR_X_COUNT) -#define bfin_write_MDMA1_SRC_CRC1_CURR_X_COUNT(val) bfin_write32(MDMA1_SRC_CRC1_CURR_X_COUNT, val) -#define bfin_read_MDMA1_SRC_CRC1_CURR_Y_COUNT() bfin_read32(MDMA1_SRC_CRC1_CURR_Y_COUNT) -#define bfin_write_MDMA1_SRC_CRC1_CURR_Y_COUNT(val) bfin_write32(MDMA1_SRC_CRC1_CURR_Y_COUNT, val) - - -/* MDMA Stream 2 Registers (DMA Channel 25 and 26) */ - -#define bfin_read_MDMA2_DEST_NEXT_DESC_PTR() bfin_read32(MDMA2_DEST_NEXT_DESC_PTR) -#define bfin_write_MDMA2_DEST_NEXT_DESC_PTR(val) bfin_write32(MDMA2_DEST_NEXT_DESC_PTR, val) -#define bfin_read_MDMA2_DEST_START_ADDR() bfin_read32(MDMA2_DEST_START_ADDR) -#define bfin_write_MDMA2_DEST_START_ADDR(val) bfin_write32(MDMA2_DEST_START_ADDR, val) -#define bfin_read_MDMA2_DEST_CONFIG() bfin_read32(MDMA2_DEST_CONFIG) -#define bfin_write_MDMA2_DEST_CONFIG(val) bfin_write32(MDMA2_DEST_CONFIG, val) -#define bfin_read_MDMA2_DEST_X_COUNT() bfin_read32(MDMA2_DEST_X_COUNT) -#define bfin_write_MDMA2_DEST_X_COUNT(val) bfin_write32(MDMA2_DEST_X_COUNT, val) -#define bfin_read_MDMA2_DEST_X_MODIFY() bfin_read32(MDMA2_DEST_X_MODIFY) -#define bfin_write_MDMA2_DEST_X_MODIFY(val) bfin_write32(MDMA2_DEST_X_MODIFY, val) -#define bfin_read_MDMA2_DEST_Y_COUNT() bfin_read32(MDMA2_DEST_Y_COUNT) -#define bfin_write_MDMA2_DEST_Y_COUNT(val) bfin_write32(MDMA2_DEST_Y_COUNT, val) -#define bfin_read_MDMA2_DEST_Y_MODIFY() bfin_read32(MDMA2_DEST_Y_MODIFY) -#define bfin_write_MDMA2_DEST_Y_MODIFY(val) bfin_write32(MDMA2_DEST_Y_MODIFY, val) -#define bfin_read_MDMA2_DEST_CURR_DESC_PTR() bfin_read32(MDMA2_DEST_CURR_DESC_PTR) -#define bfin_write_MDMA2_DEST_CURR_DESC_PTR(val) bfin_write32(MDMA2_DEST_CURR_DESC_PTR, val) -#define bfin_read_MDMA2_DEST_PREV_DESC_PTR() bfin_read32(MDMA2_DEST_PREV_DESC_PTR) -#define bfin_write_MDMA2_DEST_PREV_DESC_PTR(val) bfin_write32(MDMA2_DEST_PREV_DESC_PTR, val) -#define bfin_read_MDMA2_DEST_CURR_ADDR() bfin_read32(MDMA2_DEST_CURR_ADDR) -#define bfin_write_MDMA2_DEST_CURR_ADDR(val) bfin_write32(MDMA2_DEST_CURR_ADDR, val) -#define bfin_read_MDMA2_DEST_IRQ_STATUS() bfin_read32(MDMA2_DEST_IRQ_STATUS) -#define bfin_write_MDMA2_DEST_IRQ_STATUS(val) bfin_write32(MDMA2_DEST_IRQ_STATUS, val) -#define bfin_read_MDMA2_DEST_CURR_X_COUNT() bfin_read32(MDMA2_DEST_CURR_X_COUNT) -#define bfin_write_MDMA2_DEST_CURR_X_COUNT(val) bfin_write32(MDMA2_DEST_CURR_X_COUNT, val) -#define bfin_read_MDMA2_DEST_CURR_Y_COUNT() bfin_read32(MDMA2_DEST_CURR_Y_COUNT) -#define bfin_write_MDMA2_DEST_CURR_Y_COUNT(val) bfin_write32(MDMA2_DEST_CURR_Y_COUNT, val) -#define bfin_read_MDMA2_SRC_NEXT_DESC_PTR() bfin_read32(MDMA2_SRC_NEXT_DESC_PTR) -#define bfin_write_MDMA2_SRC_NEXT_DESC_PTR(val) bfin_write32(MDMA2_SRC_NEXT_DESC_PTR, val) -#define bfin_read_MDMA2_SRC_START_ADDR() bfin_read32(MDMA2_SRC_START_ADDR) -#define bfin_write_MDMA2_SRC_START_ADDR(val) bfin_write32(MDMA2_SRC_START_ADDR, val) -#define bfin_read_MDMA2_SRC_CONFIG() bfin_read32(MDMA2_SRC_CONFIG) -#define bfin_write_MDMA2_SRC_CONFIG(val) bfin_write32(MDMA2_SRC_CONFIG, val) -#define bfin_read_MDMA2_SRC_X_COUNT() bfin_read32(MDMA2_SRC_X_COUNT) -#define bfin_write_MDMA2_SRC_X_COUNT(val) bfin_write32(MDMA2_SRC_X_COUNT, val) -#define bfin_read_MDMA2_SRC_X_MODIFY() bfin_read32(MDMA2_SRC_X_MODIFY) -#define bfin_write_MDMA2_SRC_X_MODIFY(val) bfin_write32(MDMA2_SRC_X_MODIFY, val) -#define bfin_read_MDMA2_SRC_Y_COUNT() bfin_read32(MDMA2_SRC_Y_COUNT) -#define bfin_write_MDMA2_SRC_Y_COUNT(val) bfin_write32(MDMA2_SRC_Y_COUNT, val) -#define bfin_read_MDMA2_SRC_Y_MODIFY() bfin_read32(MDMA2_SRC_Y_MODIFY) -#define bfin_write_MDMA2_SRC_Y_MODIFY(val) bfin_write32(MDMA2_SRC_Y_MODIFY, val) -#define bfin_read_MDMA2_SRC_CURR_DESC_PTR() bfin_read32(MDMA2_SRC_CURR_DESC_PTR) -#define bfin_write_MDMA2_SRC_CURR_DESC_PTR(val) bfin_write32(MDMA2_SRC_CURR_DESC_PTR, val) -#define bfin_read_MDMA2_SRC_PREV_DESC_PTR() bfin_read32(MDMA2_SRC_PREV_DESC_PTR) -#define bfin_write_MDMA2_SRC_PREV_DESC_PTR(val) bfin_write32(MDMA2_SRC_PREV_DESC_PTR, val) -#define bfin_read_MDMA2_SRC_CURR_ADDR() bfin_read32(MDMA2_SRC_CURR_ADDR) -#define bfin_write_MDMA2_SRC_CURR_ADDR(val) bfin_write32(MDMA2_SRC_CURR_ADDR, val) -#define bfin_read_MDMA2_SRC_IRQ_STATUS() bfin_read32(MDMA2_SRC_IRQ_STATUS) -#define bfin_write_MDMA2_SRC_IRQ_STATUS(val) bfin_write32(MDMA2_SRC_IRQ_STATUS, val) -#define bfin_read_MDMA2_SRC_CURR_X_COUNT() bfin_read32(MDMA2_SRC_CURR_X_COUNT) -#define bfin_write_MDMA2_SRC_CURR_X_COUNT(val) bfin_write32(MDMA2_SRC_CURR_X_COUNT, val) -#define bfin_read_MDMA2_SRC_CURR_Y_COUNT() bfin_read32(MDMA2_SRC_CURR_Y_COUNT) -#define bfin_write_MDMA2_SRC_CURR_Y_COUNT(val) bfin_write32(MDMA2_SRC_CURR_Y_COUNT, val) - -/* MDMA Stream 3 Registers (DMA Channel 27 and 28) */ - -#define bfin_read_MDMA3_DEST_NEXT_DESC_PTR() bfin_read32(MDMA3_DEST_NEXT_DESC_PTR) -#define bfin_write_MDMA3_DEST_NEXT_DESC_PTR(val) bfin_write32(MDMA3_DEST_NEXT_DESC_PTR, val) -#define bfin_read_MDMA3_DEST_START_ADDR() bfin_read32(MDMA3_DEST_START_ADDR) -#define bfin_write_MDMA3_DEST_START_ADDR(val) bfin_write32(MDMA3_DEST_START_ADDR, val) -#define bfin_read_MDMA3_DEST_CONFIG() bfin_read32(MDMA3_DEST_CONFIG) -#define bfin_write_MDMA3_DEST_CONFIG(val) bfin_write32(MDMA3_DEST_CONFIG, val) -#define bfin_read_MDMA3_DEST_X_COUNT() bfin_read32(MDMA3_DEST_X_COUNT) -#define bfin_write_MDMA3_DEST_X_COUNT(val) bfin_write32(MDMA3_DEST_X_COUNT, val) -#define bfin_read_MDMA3_DEST_X_MODIFY() bfin_read32(MDMA3_DEST_X_MODIFY) -#define bfin_write_MDMA3_DEST_X_MODIFY(val) bfin_write32(MDMA3_DEST_X_MODIFY, val) -#define bfin_read_MDMA3_DEST_Y_COUNT() bfin_read32(MDMA3_DEST_Y_COUNT) -#define bfin_write_MDMA3_DEST_Y_COUNT(val) bfin_write32(MDMA3_DEST_Y_COUNT, val) -#define bfin_read_MDMA3_DEST_Y_MODIFY() bfin_read32(MDMA3_DEST_Y_MODIFY) -#define bfin_write_MDMA3_DEST_Y_MODIFY(val) bfin_write32(MDMA3_DEST_Y_MODIFY, val) -#define bfin_read_MDMA3_DEST_CURR_DESC_PTR() bfin_read32(MDMA3_DEST_CURR_DESC_PTR) -#define bfin_write_MDMA3_DEST_CURR_DESC_PTR(val) bfin_write32(MDMA3_DEST_CURR_DESC_PTR, val) -#define bfin_read_MDMA3_DEST_PREV_DESC_PTR() bfin_read32(MDMA3_DEST_PREV_DESC_PTR) -#define bfin_write_MDMA3_DEST_PREV_DESC_PTR(val) bfin_write32(MDMA3_DEST_PREV_DESC_PTR, val) -#define bfin_read_MDMA3_DEST_CURR_ADDR() bfin_read32(MDMA3_DEST_CURR_ADDR) -#define bfin_write_MDMA3_DEST_CURR_ADDR(val) bfin_write32(MDMA3_DEST_CURR_ADDR, val) -#define bfin_read_MDMA3_DEST_IRQ_STATUS() bfin_read32(MDMA3_DEST_IRQ_STATUS) -#define bfin_write_MDMA3_DEST_IRQ_STATUS(val) bfin_write32(MDMA3_DEST_IRQ_STATUS, val) -#define bfin_read_MDMA3_DEST_CURR_X_COUNT() bfin_read32(MDMA3_DEST_CURR_X_COUNT) -#define bfin_write_MDMA3_DEST_CURR_X_COUNT(val) bfin_write32(MDMA3_DEST_CURR_X_COUNT, val) -#define bfin_read_MDMA3_DEST_CURR_Y_COUNT() bfin_read32(MDMA3_DEST_CURR_Y_COUNT) -#define bfin_write_MDMA3_DEST_CURR_Y_COUNT(val) bfin_write32(MDMA3_DEST_CURR_Y_COUNT, val) -#define bfin_read_MDMA3_SRC_NEXT_DESC_PTR() bfin_read32(MDMA3_SRC_NEXT_DESC_PTR) -#define bfin_write_MDMA3_SRC_NEXT_DESC_PTR(val) bfin_write32(MDMA3_SRC_NEXT_DESC_PTR, val) -#define bfin_read_MDMA3_SRC_START_ADDR() bfin_read32(MDMA3_SRC_START_ADDR) -#define bfin_write_MDMA3_SRC_START_ADDR(val) bfin_write32(MDMA3_SRC_START_ADDR, val) -#define bfin_read_MDMA3_SRC_CONFIG() bfin_read32(MDMA3_SRC_CONFIG) -#define bfin_write_MDMA3_SRC_CONFIG(val) bfin_write32(MDMA3_SRC_CONFIG, val) -#define bfin_read_MDMA3_SRC_X_COUNT() bfin_read32(MDMA3_SRC_X_COUNT) -#define bfin_write_MDMA3_SRC_X_COUNT(val) bfin_write32(MDMA3_SRC_X_COUNT, val) -#define bfin_read_MDMA3_SRC_X_MODIFY() bfin_read32(MDMA3_SRC_X_MODIFY) -#define bfin_write_MDMA3_SRC_X_MODIFY(val) bfin_write32(MDMA3_SRC_X_MODIFY, val) -#define bfin_read_MDMA3_SRC_Y_COUNT() bfin_read32(MDMA3_SRC_Y_COUNT) -#define bfin_write_MDMA3_SRC_Y_COUNT(val) bfin_write32(MDMA3_SRC_Y_COUNT, val) -#define bfin_read_MDMA3_SRC_Y_MODIFY() bfin_read32(MDMA3_SRC_Y_MODIFY) -#define bfin_write_MDMA3_SRC_Y_MODIFY(val) bfin_write32(MDMA3_SRC_Y_MODIFY, val) -#define bfin_read_MDMA3_SRC_CURR_DESC_PTR() bfin_read32(MDMA3_SRC_CURR_DESC_PTR) -#define bfin_write_MDMA3_SRC_CURR_DESC_PTR(val) bfin_write32(MDMA3_SRC_CURR_DESC_PTR, val) -#define bfin_read_MDMA3_SRC_PREV_DESC_PTR() bfin_read32(MDMA3_SRC_PREV_DESC_PTR) -#define bfin_write_MDMA3_SRC_PREV_DESC_PTR(val) bfin_write32(MDMA3_SRC_PREV_DESC_PTR, val) -#define bfin_read_MDMA3_SRC_CURR_ADDR() bfin_read32(MDMA3_SRC_CURR_ADDR) -#define bfin_write_MDMA3_SRC_CURR_ADDR(val) bfin_write32(MDMA3_SRC_CURR_ADDR, val) -#define bfin_read_MDMA3_SRC_IRQ_STATUS() bfin_read32(MDMA3_SRC_IRQ_STATUS) -#define bfin_write_MDMA3_SRC_IRQ_STATUS(val) bfin_write32(MDMA3_SRC_IRQ_STATUS, val) -#define bfin_read_MDMA3_SRC_CURR_X_COUNT() bfin_read32(MDMA3_SRC_CURR_X_COUNT) -#define bfin_write_MDMA3_SRC_CURR_X_COUNT(val) bfin_write32(MDMA3_SRC_CURR_X_COUNT, val) -#define bfin_read_MDMA3_SRC_CURR_Y_COUNT() bfin_read32(MDMA3_SRC_CURR_Y_COUNT) -#define bfin_write_MDMA3_SRC_CURR_Y_COUNT(val) bfin_write32(MDMA3_SRC_CURR_Y_COUNT, val) - - -/* DMA Channel 29 Registers */ - -#define bfin_read_DMA29_NEXT_DESC_PTR() bfin_read32(DMA29_NEXT_DESC_PTR) -#define bfin_write_DMA29_NEXT_DESC_PTR(val) bfin_write32(DMA29_NEXT_DESC_PTR, val) -#define bfin_read_DMA29_START_ADDR() bfin_read32(DMA29_START_ADDR) -#define bfin_write_DMA29_START_ADDR(val) bfin_write32(DMA29_START_ADDR, val) -#define bfin_read_DMA29_CONFIG() bfin_read32(DMA29_CONFIG) -#define bfin_write_DMA29_CONFIG(val) bfin_write32(DMA29_CONFIG, val) -#define bfin_read_DMA29_X_COUNT() bfin_read32(DMA29_X_COUNT) -#define bfin_write_DMA29_X_COUNT(val) bfin_write32(DMA29_X_COUNT, val) -#define bfin_read_DMA29_X_MODIFY() bfin_read32(DMA29_X_MODIFY) -#define bfin_write_DMA29_X_MODIFY(val) bfin_write32(DMA29_X_MODIFY, val) -#define bfin_read_DMA29_Y_COUNT() bfin_read32(DMA29_Y_COUNT) -#define bfin_write_DMA29_Y_COUNT(val) bfin_write32(DMA29_Y_COUNT, val) -#define bfin_read_DMA29_Y_MODIFY() bfin_read32(DMA29_Y_MODIFY) -#define bfin_write_DMA29_Y_MODIFY(val) bfin_write32(DMA29_Y_MODIFY, val) -#define bfin_read_DMA29_CURR_DESC_PTR() bfin_read32(DMA29_CURR_DESC_PTR) -#define bfin_write_DMA29_CURR_DESC_PTR(val) bfin_write32(DMA29_CURR_DESC_PTR, val) -#define bfin_read_DMA29_PREV_DESC_PTR() bfin_read32(DMA29_PREV_DESC_PTR) -#define bfin_write_DMA29_PREV_DESC_PTR(val) bfin_write32(DMA29_PREV_DESC_PTR, val) -#define bfin_read_DMA29_CURR_ADDR() bfin_read32(DMA29_CURR_ADDR) -#define bfin_write_DMA29_CURR_ADDR(val) bfin_write32(DMA29_CURR_ADDR, val) -#define bfin_read_DMA29_IRQ_STATUS() bfin_read32(DMA29_IRQ_STATUS) -#define bfin_write_DMA29_IRQ_STATUS(val) bfin_write32(DMA29_IRQ_STATUS, val) -#define bfin_read_DMA29_CURR_X_COUNT() bfin_read32(DMA29_CURR_X_COUNT) -#define bfin_write_DMA29_CURR_X_COUNT(val) bfin_write32(DMA29_CURR_X_COUNT, val) -#define bfin_read_DMA29_CURR_Y_COUNT() bfin_read32(DMA29_CURR_Y_COUNT) -#define bfin_write_DMA29_CURR_Y_COUNT(val) bfin_write32(DMA29_CURR_Y_COUNT, val) -#define bfin_read_DMA29_BWL_COUNT() bfin_read32(DMA29_BWL_COUNT) -#define bfin_write_DMA29_BWL_COUNT(val) bfin_write32(DMA29_BWL_COUNT, val) -#define bfin_read_DMA29_CURR_BWL_COUNT() bfin_read32(DMA29_CURR_BWL_COUNT) -#define bfin_write_DMA29_CURR_BWL_COUNT(val) bfin_write32(DMA29_CURR_BWL_COUNT, val) -#define bfin_read_DMA29_BWM_COUNT() bfin_read32(DMA29_BWM_COUNT) -#define bfin_write_DMA29_BWM_COUNT(val) bfin_write32(DMA29_BWM_COUNT, val) -#define bfin_read_DMA29_CURR_BWM_COUNT() bfin_read32(DMA29_CURR_BWM_COUNT) -#define bfin_write_DMA29_CURR_BWM_COUNT(val) bfin_write32(DMA29_CURR_BWM_COUNT, val) - -/* DMA Channel 30 Registers */ - -#define bfin_read_DMA30_NEXT_DESC_PTR() bfin_read32(DMA30_NEXT_DESC_PTR) -#define bfin_write_DMA30_NEXT_DESC_PTR(val) bfin_write32(DMA30_NEXT_DESC_PTR, val) -#define bfin_read_DMA30_START_ADDR() bfin_read32(DMA30_START_ADDR) -#define bfin_write_DMA30_START_ADDR(val) bfin_write32(DMA30_START_ADDR, val) -#define bfin_read_DMA30_CONFIG() bfin_read32(DMA30_CONFIG) -#define bfin_write_DMA30_CONFIG(val) bfin_write32(DMA30_CONFIG, val) -#define bfin_read_DMA30_X_COUNT() bfin_read32(DMA30_X_COUNT) -#define bfin_write_DMA30_X_COUNT(val) bfin_write32(DMA30_X_COUNT, val) -#define bfin_read_DMA30_X_MODIFY() bfin_read32(DMA30_X_MODIFY) -#define bfin_write_DMA30_X_MODIFY(val) bfin_write32(DMA30_X_MODIFY, val) -#define bfin_read_DMA30_Y_COUNT() bfin_read32(DMA30_Y_COUNT) -#define bfin_write_DMA30_Y_COUNT(val) bfin_write32(DMA30_Y_COUNT, val) -#define bfin_read_DMA30_Y_MODIFY() bfin_read32(DMA30_Y_MODIFY) -#define bfin_write_DMA30_Y_MODIFY(val) bfin_write32(DMA30_Y_MODIFY, val) -#define bfin_read_DMA30_CURR_DESC_PTR() bfin_read32(DMA30_CURR_DESC_PTR) -#define bfin_write_DMA30_CURR_DESC_PTR(val) bfin_write32(DMA30_CURR_DESC_PTR, val) -#define bfin_read_DMA30_PREV_DESC_PTR() bfin_read32(DMA30_PREV_DESC_PTR) -#define bfin_write_DMA30_PREV_DESC_PTR(val) bfin_write32(DMA30_PREV_DESC_PTR, val) -#define bfin_read_DMA30_CURR_ADDR() bfin_read32(DMA30_CURR_ADDR) -#define bfin_write_DMA30_CURR_ADDR(val) bfin_write32(DMA30_CURR_ADDR, val) -#define bfin_read_DMA30_IRQ_STATUS() bfin_read32(DMA30_IRQ_STATUS) -#define bfin_write_DMA30_IRQ_STATUS(val) bfin_write32(DMA30_IRQ_STATUS, val) -#define bfin_read_DMA30_CURR_X_COUNT() bfin_read32(DMA30_CURR_X_COUNT) -#define bfin_write_DMA30_CURR_X_COUNT(val) bfin_write32(DMA30_CURR_X_COUNT, val) -#define bfin_read_DMA30_CURR_Y_COUNT() bfin_read32(DMA30_CURR_Y_COUNT) -#define bfin_write_DMA30_CURR_Y_COUNT(val) bfin_write32(DMA30_CURR_Y_COUNT, val) -#define bfin_read_DMA30_BWL_COUNT() bfin_read32(DMA30_BWL_COUNT) -#define bfin_write_DMA30_BWL_COUNT(val) bfin_write32(DMA30_BWL_COUNT, val) -#define bfin_read_DMA30_CURR_BWL_COUNT() bfin_read32(DMA30_CURR_BWL_COUNT) -#define bfin_write_DMA30_CURR_BWL_COUNT(val) bfin_write32(DMA30_CURR_BWL_COUNT, val) -#define bfin_read_DMA30_BWM_COUNT() bfin_read32(DMA30_BWM_COUNT) -#define bfin_write_DMA30_BWM_COUNT(val) bfin_write32(DMA30_BWM_COUNT, val) -#define bfin_read_DMA30_CURR_BWM_COUNT() bfin_read32(DMA30_CURR_BWM_COUNT) -#define bfin_write_DMA30_CURR_BWM_COUNT(val) bfin_write32(DMA30_CURR_BWM_COUNT, val) - -/* DMA Channel 31 Registers */ - -#define bfin_read_DMA31_NEXT_DESC_PTR() bfin_read32(DMA31_NEXT_DESC_PTR) -#define bfin_write_DMA31_NEXT_DESC_PTR(val) bfin_write32(DMA31_NEXT_DESC_PTR, val) -#define bfin_read_DMA31_START_ADDR() bfin_read32(DMA31_START_ADDR) -#define bfin_write_DMA31_START_ADDR(val) bfin_write32(DMA31_START_ADDR, val) -#define bfin_read_DMA31_CONFIG() bfin_read32(DMA31_CONFIG) -#define bfin_write_DMA31_CONFIG(val) bfin_write32(DMA31_CONFIG, val) -#define bfin_read_DMA31_X_COUNT() bfin_read32(DMA31_X_COUNT) -#define bfin_write_DMA31_X_COUNT(val) bfin_write32(DMA31_X_COUNT, val) -#define bfin_read_DMA31_X_MODIFY() bfin_read32(DMA31_X_MODIFY) -#define bfin_write_DMA31_X_MODIFY(val) bfin_write32(DMA31_X_MODIFY, val) -#define bfin_read_DMA31_Y_COUNT() bfin_read32(DMA31_Y_COUNT) -#define bfin_write_DMA31_Y_COUNT(val) bfin_write32(DMA31_Y_COUNT, val) -#define bfin_read_DMA31_Y_MODIFY() bfin_read32(DMA31_Y_MODIFY) -#define bfin_write_DMA31_Y_MODIFY(val) bfin_write32(DMA31_Y_MODIFY, val) -#define bfin_read_DMA31_CURR_DESC_PTR() bfin_read32(DMA31_CURR_DESC_PTR) -#define bfin_write_DMA31_CURR_DESC_PTR(val) bfin_write32(DMA31_CURR_DESC_PTR, val) -#define bfin_read_DMA31_PREV_DESC_PTR() bfin_read32(DMA31_PREV_DESC_PTR) -#define bfin_write_DMA31_PREV_DESC_PTR(val) bfin_write32(DMA31_PREV_DESC_PTR, val) -#define bfin_read_DMA31_CURR_ADDR() bfin_read32(DMA31_CURR_ADDR) -#define bfin_write_DMA31_CURR_ADDR(val) bfin_write32(DMA31_CURR_ADDR, val) -#define bfin_read_DMA31_IRQ_STATUS() bfin_read32(DMA31_IRQ_STATUS) -#define bfin_write_DMA31_IRQ_STATUS(val) bfin_write32(DMA31_IRQ_STATUS, val) -#define bfin_read_DMA31_CURR_X_COUNT() bfin_read32(DMA31_CURR_X_COUNT) -#define bfin_write_DMA31_CURR_X_COUNT(val) bfin_write32(DMA31_CURR_X_COUNT, val) -#define bfin_read_DMA31_CURR_Y_COUNT() bfin_read32(DMA31_CURR_Y_COUNT) -#define bfin_write_DMA31_CURR_Y_COUNT(val) bfin_write32(DMA31_CURR_Y_COUNT, val) -#define bfin_read_DMA31_BWL_COUNT() bfin_read32(DMA31_BWL_COUNT) -#define bfin_write_DMA31_BWL_COUNT(val) bfin_write32(DMA31_BWL_COUNT, val) -#define bfin_read_DMA31_CURR_BWL_COUNT() bfin_read32(DMA31_CURR_BWL_COUNT) -#define bfin_write_DMA31_CURR_BWL_COUNT(val) bfin_write32(DMA31_CURR_BWL_COUNT, val) -#define bfin_read_DMA31_BWM_COUNT() bfin_read32(DMA31_BWM_COUNT) -#define bfin_write_DMA31_BWM_COUNT(val) bfin_write32(DMA31_BWM_COUNT, val) -#define bfin_read_DMA31_CURR_BWM_COUNT() bfin_read32(DMA31_CURR_BWM_COUNT) -#define bfin_write_DMA31_CURR_BWM_COUNT(val) bfin_write32(DMA31_CURR_BWM_COUNT, val) - -/* DMA Channel 32 Registers */ - -#define bfin_read_DMA32_NEXT_DESC_PTR() bfin_read32(DMA32_NEXT_DESC_PTR) -#define bfin_write_DMA32_NEXT_DESC_PTR(val) bfin_write32(DMA32_NEXT_DESC_PTR, val) -#define bfin_read_DMA32_START_ADDR() bfin_read32(DMA32_START_ADDR) -#define bfin_write_DMA32_START_ADDR(val) bfin_write32(DMA32_START_ADDR, val) -#define bfin_read_DMA32_CONFIG() bfin_read32(DMA32_CONFIG) -#define bfin_write_DMA32_CONFIG(val) bfin_write32(DMA32_CONFIG, val) -#define bfin_read_DMA32_X_COUNT() bfin_read32(DMA32_X_COUNT) -#define bfin_write_DMA32_X_COUNT(val) bfin_write32(DMA32_X_COUNT, val) -#define bfin_read_DMA32_X_MODIFY() bfin_read32(DMA32_X_MODIFY) -#define bfin_write_DMA32_X_MODIFY(val) bfin_write32(DMA32_X_MODIFY, val) -#define bfin_read_DMA32_Y_COUNT() bfin_read32(DMA32_Y_COUNT) -#define bfin_write_DMA32_Y_COUNT(val) bfin_write32(DMA32_Y_COUNT, val) -#define bfin_read_DMA32_Y_MODIFY() bfin_read32(DMA32_Y_MODIFY) -#define bfin_write_DMA32_Y_MODIFY(val) bfin_write32(DMA32_Y_MODIFY, val) -#define bfin_read_DMA32_CURR_DESC_PTR() bfin_read32(DMA32_CURR_DESC_PTR) -#define bfin_write_DMA32_CURR_DESC_PTR(val) bfin_write32(DMA32_CURR_DESC_PTR, val) -#define bfin_read_DMA32_PREV_DESC_PTR() bfin_read32(DMA32_PREV_DESC_PTR) -#define bfin_write_DMA32_PREV_DESC_PTR(val) bfin_write32(DMA32_PREV_DESC_PTR, val) -#define bfin_read_DMA32_CURR_ADDR() bfin_read32(DMA32_CURR_ADDR) -#define bfin_write_DMA32_CURR_ADDR(val) bfin_write32(DMA32_CURR_ADDR, val) -#define bfin_read_DMA32_IRQ_STATUS() bfin_read32(DMA32_IRQ_STATUS) -#define bfin_write_DMA32_IRQ_STATUS(val) bfin_write32(DMA32_IRQ_STATUS, val) -#define bfin_read_DMA32_CURR_X_COUNT() bfin_read32(DMA32_CURR_X_COUNT) -#define bfin_write_DMA32_CURR_X_COUNT(val) bfin_write32(DMA32_CURR_X_COUNT, val) -#define bfin_read_DMA32_CURR_Y_COUNT() bfin_read32(DMA32_CURR_Y_COUNT) -#define bfin_write_DMA32_CURR_Y_COUNT(val) bfin_write32(DMA32_CURR_Y_COUNT, val) -#define bfin_read_DMA32_BWL_COUNT() bfin_read32(DMA32_BWL_COUNT) -#define bfin_write_DMA32_BWL_COUNT(val) bfin_write32(DMA32_BWL_COUNT, val) -#define bfin_read_DMA32_CURR_BWL_COUNT() bfin_read32(DMA32_CURR_BWL_COUNT) -#define bfin_write_DMA32_CURR_BWL_COUNT(val) bfin_write32(DMA32_CURR_BWL_COUNT, val) -#define bfin_read_DMA32_BWM_COUNT() bfin_read32(DMA32_BWM_COUNT) -#define bfin_write_DMA32_BWM_COUNT(val) bfin_write32(DMA32_BWM_COUNT, val) -#define bfin_read_DMA32_CURR_BWM_COUNT() bfin_read32(DMA32_CURR_BWM_COUNT) -#define bfin_write_DMA32_CURR_BWM_COUNT(val) bfin_write32(DMA32_CURR_BWM_COUNT, val) - -/* DMA Channel 33 Registers */ - -#define bfin_read_DMA33_NEXT_DESC_PTR() bfin_read32(DMA33_NEXT_DESC_PTR) -#define bfin_write_DMA33_NEXT_DESC_PTR(val) bfin_write32(DMA33_NEXT_DESC_PTR, val) -#define bfin_read_DMA33_START_ADDR() bfin_read32(DMA33_START_ADDR) -#define bfin_write_DMA33_START_ADDR(val) bfin_write32(DMA33_START_ADDR, val) -#define bfin_read_DMA33_CONFIG() bfin_read32(DMA33_CONFIG) -#define bfin_write_DMA33_CONFIG(val) bfin_write32(DMA33_CONFIG, val) -#define bfin_read_DMA33_X_COUNT() bfin_read32(DMA33_X_COUNT) -#define bfin_write_DMA33_X_COUNT(val) bfin_write32(DMA33_X_COUNT, val) -#define bfin_read_DMA33_X_MODIFY() bfin_read32(DMA33_X_MODIFY) -#define bfin_write_DMA33_X_MODIFY(val) bfin_write32(DMA33_X_MODIFY, val) -#define bfin_read_DMA33_Y_COUNT() bfin_read32(DMA33_Y_COUNT) -#define bfin_write_DMA33_Y_COUNT(val) bfin_write32(DMA33_Y_COUNT, val) -#define bfin_read_DMA33_Y_MODIFY() bfin_read32(DMA33_Y_MODIFY) -#define bfin_write_DMA33_Y_MODIFY(val) bfin_write32(DMA33_Y_MODIFY, val) -#define bfin_read_DMA33_CURR_DESC_PTR() bfin_read32(DMA33_CURR_DESC_PTR) -#define bfin_write_DMA33_CURR_DESC_PTR(val) bfin_write32(DMA33_CURR_DESC_PTR, val) -#define bfin_read_DMA33_PREV_DESC_PTR() bfin_read32(DMA33_PREV_DESC_PTR) -#define bfin_write_DMA33_PREV_DESC_PTR(val) bfin_write32(DMA33_PREV_DESC_PTR, val) -#define bfin_read_DMA33_CURR_ADDR() bfin_read32(DMA33_CURR_ADDR) -#define bfin_write_DMA33_CURR_ADDR(val) bfin_write32(DMA33_CURR_ADDR, val) -#define bfin_read_DMA33_IRQ_STATUS() bfin_read32(DMA33_IRQ_STATUS) -#define bfin_write_DMA33_IRQ_STATUS(val) bfin_write32(DMA33_IRQ_STATUS, val) -#define bfin_read_DMA33_CURR_X_COUNT() bfin_read32(DMA33_CURR_X_COUNT) -#define bfin_write_DMA33_CURR_X_COUNT(val) bfin_write32(DMA33_CURR_X_COUNT, val) -#define bfin_read_DMA33_CURR_Y_COUNT() bfin_read32(DMA33_CURR_Y_COUNT) -#define bfin_write_DMA33_CURR_Y_COUNT(val) bfin_write32(DMA33_CURR_Y_COUNT, val) -#define bfin_read_DMA33_BWL_COUNT() bfin_read32(DMA33_BWL_COUNT) -#define bfin_write_DMA33_BWL_COUNT(val) bfin_write32(DMA33_BWL_COUNT, val) -#define bfin_read_DMA33_CURR_BWL_COUNT() bfin_read32(DMA33_CURR_BWL_COUNT) -#define bfin_write_DMA33_CURR_BWL_COUNT(val) bfin_write32(DMA33_CURR_BWL_COUNT, val) -#define bfin_read_DMA33_BWM_COUNT() bfin_read32(DMA33_BWM_COUNT) -#define bfin_write_DMA33_BWM_COUNT(val) bfin_write32(DMA33_BWM_COUNT, val) -#define bfin_read_DMA33_CURR_BWM_COUNT() bfin_read32(DMA33_CURR_BWM_COUNT) -#define bfin_write_DMA33_CURR_BWM_COUNT(val) bfin_write32(DMA33_CURR_BWM_COUNT, val) - -/* DMA Channel 34 Registers */ - -#define bfin_read_DMA34_NEXT_DESC_PTR() bfin_read32(DMA34_NEXT_DESC_PTR) -#define bfin_write_DMA34_NEXT_DESC_PTR(val) bfin_write32(DMA34_NEXT_DESC_PTR, val) -#define bfin_read_DMA34_START_ADDR() bfin_read32(DMA34_START_ADDR) -#define bfin_write_DMA34_START_ADDR(val) bfin_write32(DMA34_START_ADDR, val) -#define bfin_read_DMA34_CONFIG() bfin_read32(DMA34_CONFIG) -#define bfin_write_DMA34_CONFIG(val) bfin_write32(DMA34_CONFIG, val) -#define bfin_read_DMA34_X_COUNT() bfin_read32(DMA34_X_COUNT) -#define bfin_write_DMA34_X_COUNT(val) bfin_write32(DMA34_X_COUNT, val) -#define bfin_read_DMA34_X_MODIFY() bfin_read32(DMA34_X_MODIFY) -#define bfin_write_DMA34_X_MODIFY(val) bfin_write32(DMA34_X_MODIFY, val) -#define bfin_read_DMA34_Y_COUNT() bfin_read32(DMA34_Y_COUNT) -#define bfin_write_DMA34_Y_COUNT(val) bfin_write32(DMA34_Y_COUNT, val) -#define bfin_read_DMA34_Y_MODIFY() bfin_read32(DMA34_Y_MODIFY) -#define bfin_write_DMA34_Y_MODIFY(val) bfin_write32(DMA34_Y_MODIFY, val) -#define bfin_read_DMA34_CURR_DESC_PTR() bfin_read32(DMA34_CURR_DESC_PTR) -#define bfin_write_DMA34_CURR_DESC_PTR(val) bfin_write32(DMA34_CURR_DESC_PTR, val) -#define bfin_read_DMA34_PREV_DESC_PTR() bfin_read32(DMA34_PREV_DESC_PTR) -#define bfin_write_DMA34_PREV_DESC_PTR(val) bfin_write32(DMA34_PREV_DESC_PTR, val) -#define bfin_read_DMA34_CURR_ADDR() bfin_read32(DMA34_CURR_ADDR) -#define bfin_write_DMA34_CURR_ADDR(val) bfin_write32(DMA34_CURR_ADDR, val) -#define bfin_read_DMA34_IRQ_STATUS() bfin_read32(DMA34_IRQ_STATUS) -#define bfin_write_DMA34_IRQ_STATUS(val) bfin_write32(DMA34_IRQ_STATUS, val) -#define bfin_read_DMA34_CURR_X_COUNT() bfin_read32(DMA34_CURR_X_COUNT) -#define bfin_write_DMA34_CURR_X_COUNT(val) bfin_write32(DMA34_CURR_X_COUNT, val) -#define bfin_read_DMA34_CURR_Y_COUNT() bfin_read32(DMA34_CURR_Y_COUNT) -#define bfin_write_DMA34_CURR_Y_COUNT(val) bfin_write32(DMA34_CURR_Y_COUNT, val) -#define bfin_read_DMA34_BWL_COUNT() bfin_read32(DMA34_BWL_COUNT) -#define bfin_write_DMA34_BWL_COUNT(val) bfin_write32(DMA34_BWL_COUNT, val) -#define bfin_read_DMA34_CURR_BWL_COUNT() bfin_read32(DMA34_CURR_BWL_COUNT) -#define bfin_write_DMA34_CURR_BWL_COUNT(val) bfin_write32(DMA34_CURR_BWL_COUNT, val) -#define bfin_read_DMA34_BWM_COUNT() bfin_read32(DMA34_BWM_COUNT) -#define bfin_write_DMA34_BWM_COUNT(val) bfin_write32(DMA34_BWM_COUNT, val) -#define bfin_read_DMA34_CURR_BWM_COUNT() bfin_read32(DMA34_CURR_BWM_COUNT) -#define bfin_write_DMA34_CURR_BWM_COUNT(val) bfin_write32(DMA34_CURR_BWM_COUNT, val) - -/* DMA Channel 35 Registers */ - -#define bfin_read_DMA35_NEXT_DESC_PTR() bfin_read32(DMA35_NEXT_DESC_PTR) -#define bfin_write_DMA35_NEXT_DESC_PTR(val) bfin_write32(DMA35_NEXT_DESC_PTR, val) -#define bfin_read_DMA35_START_ADDR() bfin_read32(DMA35_START_ADDR) -#define bfin_write_DMA35_START_ADDR(val) bfin_write32(DMA35_START_ADDR, val) -#define bfin_read_DMA35_CONFIG() bfin_read32(DMA35_CONFIG) -#define bfin_write_DMA35_CONFIG(val) bfin_write32(DMA35_CONFIG, val) -#define bfin_read_DMA35_X_COUNT() bfin_read32(DMA35_X_COUNT) -#define bfin_write_DMA35_X_COUNT(val) bfin_write32(DMA35_X_COUNT, val) -#define bfin_read_DMA35_X_MODIFY() bfin_read32(DMA35_X_MODIFY) -#define bfin_write_DMA35_X_MODIFY(val) bfin_write32(DMA35_X_MODIFY, val) -#define bfin_read_DMA35_Y_COUNT() bfin_read32(DMA35_Y_COUNT) -#define bfin_write_DMA35_Y_COUNT(val) bfin_write32(DMA35_Y_COUNT, val) -#define bfin_read_DMA35_Y_MODIFY() bfin_read32(DMA35_Y_MODIFY) -#define bfin_write_DMA35_Y_MODIFY(val) bfin_write32(DMA35_Y_MODIFY, val) -#define bfin_read_DMA35_CURR_DESC_PTR() bfin_read32(DMA35_CURR_DESC_PTR) -#define bfin_write_DMA35_CURR_DESC_PTR(val) bfin_write32(DMA35_CURR_DESC_PTR, val) -#define bfin_read_DMA35_PREV_DESC_PTR() bfin_read32(DMA35_PREV_DESC_PTR) -#define bfin_write_DMA35_PREV_DESC_PTR(val) bfin_write32(DMA35_PREV_DESC_PTR, val) -#define bfin_read_DMA35_CURR_ADDR() bfin_read32(DMA35_CURR_ADDR) -#define bfin_write_DMA35_CURR_ADDR(val) bfin_write32(DMA35_CURR_ADDR, val) -#define bfin_read_DMA35_IRQ_STATUS() bfin_read32(DMA35_IRQ_STATUS) -#define bfin_write_DMA35_IRQ_STATUS(val) bfin_write32(DMA35_IRQ_STATUS, val) -#define bfin_read_DMA35_CURR_X_COUNT() bfin_read32(DMA35_CURR_X_COUNT) -#define bfin_write_DMA35_CURR_X_COUNT(val) bfin_write32(DMA35_CURR_X_COUNT, val) -#define bfin_read_DMA35_CURR_Y_COUNT() bfin_read32(DMA35_CURR_Y_COUNT) -#define bfin_write_DMA35_CURR_Y_COUNT(val) bfin_write32(DMA35_CURR_Y_COUNT, val) -#define bfin_read_DMA35_BWL_COUNT() bfin_read32(DMA35_BWL_COUNT) -#define bfin_write_DMA35_BWL_COUNT(val) bfin_write32(DMA35_BWL_COUNT, val) -#define bfin_read_DMA35_CURR_BWL_COUNT() bfin_read32(DMA35_CURR_BWL_COUNT) -#define bfin_write_DMA35_CURR_BWL_COUNT(val) bfin_write32(DMA35_CURR_BWL_COUNT, val) -#define bfin_read_DMA35_BWM_COUNT() bfin_read32(DMA35_BWM_COUNT) -#define bfin_write_DMA35_BWM_COUNT(val) bfin_write32(DMA35_BWM_COUNT, val) -#define bfin_read_DMA35_CURR_BWM_COUNT() bfin_read32(DMA35_CURR_BWM_COUNT) -#define bfin_write_DMA35_CURR_BWM_COUNT(val) bfin_write32(DMA35_CURR_BWM_COUNT, val) - -/* DMA Channel 36 Registers */ - -#define bfin_read_DMA36_NEXT_DESC_PTR() bfin_read32(DMA36_NEXT_DESC_PTR) -#define bfin_write_DMA36_NEXT_DESC_PTR(val) bfin_write32(DMA36_NEXT_DESC_PTR, val) -#define bfin_read_DMA36_START_ADDR() bfin_read32(DMA36_START_ADDR) -#define bfin_write_DMA36_START_ADDR(val) bfin_write32(DMA36_START_ADDR, val) -#define bfin_read_DMA36_CONFIG() bfin_read32(DMA36_CONFIG) -#define bfin_write_DMA36_CONFIG(val) bfin_write32(DMA36_CONFIG, val) -#define bfin_read_DMA36_X_COUNT() bfin_read32(DMA36_X_COUNT) -#define bfin_write_DMA36_X_COUNT(val) bfin_write32(DMA36_X_COUNT, val) -#define bfin_read_DMA36_X_MODIFY() bfin_read32(DMA36_X_MODIFY) -#define bfin_write_DMA36_X_MODIFY(val) bfin_write32(DMA36_X_MODIFY, val) -#define bfin_read_DMA36_Y_COUNT() bfin_read32(DMA36_Y_COUNT) -#define bfin_write_DMA36_Y_COUNT(val) bfin_write32(DMA36_Y_COUNT, val) -#define bfin_read_DMA36_Y_MODIFY() bfin_read32(DMA36_Y_MODIFY) -#define bfin_write_DMA36_Y_MODIFY(val) bfin_write32(DMA36_Y_MODIFY, val) -#define bfin_read_DMA36_CURR_DESC_PTR() bfin_read32(DMA36_CURR_DESC_PTR) -#define bfin_write_DMA36_CURR_DESC_PTR(val) bfin_write32(DMA36_CURR_DESC_PTR, val) -#define bfin_read_DMA36_PREV_DESC_PTR() bfin_read32(DMA36_PREV_DESC_PTR) -#define bfin_write_DMA36_PREV_DESC_PTR(val) bfin_write32(DMA36_PREV_DESC_PTR, val) -#define bfin_read_DMA36_CURR_ADDR() bfin_read32(DMA36_CURR_ADDR) -#define bfin_write_DMA36_CURR_ADDR(val) bfin_write32(DMA36_CURR_ADDR, val) -#define bfin_read_DMA36_IRQ_STATUS() bfin_read32(DMA36_IRQ_STATUS) -#define bfin_write_DMA36_IRQ_STATUS(val) bfin_write32(DMA36_IRQ_STATUS, val) -#define bfin_read_DMA36_CURR_X_COUNT() bfin_read32(DMA36_CURR_X_COUNT) -#define bfin_write_DMA36_CURR_X_COUNT(val) bfin_write32(DMA36_CURR_X_COUNT, val) -#define bfin_read_DMA36_CURR_Y_COUNT() bfin_read32(DMA36_CURR_Y_COUNT) -#define bfin_write_DMA36_CURR_Y_COUNT(val) bfin_write32(DMA36_CURR_Y_COUNT, val) -#define bfin_read_DMA36_BWL_COUNT() bfin_read32(DMA36_BWL_COUNT) -#define bfin_write_DMA36_BWL_COUNT(val) bfin_write32(DMA36_BWL_COUNT, val) -#define bfin_read_DMA36_CURR_BWL_COUNT() bfin_read32(DMA36_CURR_BWL_COUNT) -#define bfin_write_DMA36_CURR_BWL_COUNT(val) bfin_write32(DMA36_CURR_BWL_COUNT, val) -#define bfin_read_DMA36_BWM_COUNT() bfin_read32(DMA36_BWM_COUNT) -#define bfin_write_DMA36_BWM_COUNT(val) bfin_write32(DMA36_BWM_COUNT, val) -#define bfin_read_DMA36_CURR_BWM_COUNT() bfin_read32(DMA36_CURR_BWM_COUNT) -#define bfin_write_DMA36_CURR_BWM_COUNT(val) bfin_write32(DMA36_CURR_BWM_COUNT, val) - -/* DMA Channel 37 Registers */ - -#define bfin_read_DMA37_NEXT_DESC_PTR() bfin_read32(DMA37_NEXT_DESC_PTR) -#define bfin_write_DMA37_NEXT_DESC_PTR(val) bfin_write32(DMA37_NEXT_DESC_PTR, val) -#define bfin_read_DMA37_START_ADDR() bfin_read32(DMA37_START_ADDR) -#define bfin_write_DMA37_START_ADDR(val) bfin_write32(DMA37_START_ADDR, val) -#define bfin_read_DMA37_CONFIG() bfin_read32(DMA37_CONFIG) -#define bfin_write_DMA37_CONFIG(val) bfin_write32(DMA37_CONFIG, val) -#define bfin_read_DMA37_X_COUNT() bfin_read32(DMA37_X_COUNT) -#define bfin_write_DMA37_X_COUNT(val) bfin_write32(DMA37_X_COUNT, val) -#define bfin_read_DMA37_X_MODIFY() bfin_read32(DMA37_X_MODIFY) -#define bfin_write_DMA37_X_MODIFY(val) bfin_write32(DMA37_X_MODIFY, val) -#define bfin_read_DMA37_Y_COUNT() bfin_read32(DMA37_Y_COUNT) -#define bfin_write_DMA37_Y_COUNT(val) bfin_write32(DMA37_Y_COUNT, val) -#define bfin_read_DMA37_Y_MODIFY() bfin_read32(DMA37_Y_MODIFY) -#define bfin_write_DMA37_Y_MODIFY(val) bfin_write32(DMA37_Y_MODIFY, val) -#define bfin_read_DMA37_CURR_DESC_PTR() bfin_read32(DMA37_CURR_DESC_PTR) -#define bfin_write_DMA37_CURR_DESC_PTR(val) bfin_write32(DMA37_CURR_DESC_PTR, val) -#define bfin_read_DMA37_PREV_DESC_PTR() bfin_read32(DMA37_PREV_DESC_PTR) -#define bfin_write_DMA37_PREV_DESC_PTR(val) bfin_write32(DMA37_PREV_DESC_PTR, val) -#define bfin_read_DMA37_CURR_ADDR() bfin_read32(DMA37_CURR_ADDR) -#define bfin_write_DMA37_CURR_ADDR(val) bfin_write32(DMA37_CURR_ADDR, val) -#define bfin_read_DMA37_IRQ_STATUS() bfin_read32(DMA37_IRQ_STATUS) -#define bfin_write_DMA37_IRQ_STATUS(val) bfin_write32(DMA37_IRQ_STATUS, val) -#define bfin_read_DMA37_CURR_X_COUNT() bfin_read32(DMA37_CURR_X_COUNT) -#define bfin_write_DMA37_CURR_X_COUNT(val) bfin_write32(DMA37_CURR_X_COUNT, val) -#define bfin_read_DMA37_CURR_Y_COUNT() bfin_read32(DMA37_CURR_Y_COUNT) -#define bfin_write_DMA37_CURR_Y_COUNT(val) bfin_write32(DMA37_CURR_Y_COUNT, val) -#define bfin_read_DMA37_BWL_COUNT() bfin_read32(DMA37_BWL_COUNT) -#define bfin_write_DMA37_BWL_COUNT(val) bfin_write32(DMA37_BWL_COUNT, val) -#define bfin_read_DMA37_CURR_BWL_COUNT() bfin_read32(DMA37_CURR_BWL_COUNT) -#define bfin_write_DMA37_CURR_BWL_COUNT(val) bfin_write32(DMA37_CURR_BWL_COUNT, val) -#define bfin_read_DMA37_BWM_COUNT() bfin_read32(DMA37_BWM_COUNT) -#define bfin_write_DMA37_BWM_COUNT(val) bfin_write32(DMA37_BWM_COUNT, val) -#define bfin_read_DMA37_CURR_BWM_COUNT() bfin_read32(DMA37_CURR_BWM_COUNT) -#define bfin_write_DMA37_CURR_BWM_COUNT(val) bfin_write32(DMA37_CURR_BWM_COUNT, val) - -/* DMA Channel 38 Registers */ - -#define bfin_read_DMA38_NEXT_DESC_PTR() bfin_read32(DMA38_NEXT_DESC_PTR) -#define bfin_write_DMA38_NEXT_DESC_PTR(val) bfin_write32(DMA38_NEXT_DESC_PTR, val) -#define bfin_read_DMA38_START_ADDR() bfin_read32(DMA38_START_ADDR) -#define bfin_write_DMA38_START_ADDR(val) bfin_write32(DMA38_START_ADDR, val) -#define bfin_read_DMA38_CONFIG() bfin_read32(DMA38_CONFIG) -#define bfin_write_DMA38_CONFIG(val) bfin_write32(DMA38_CONFIG, val) -#define bfin_read_DMA38_X_COUNT() bfin_read32(DMA38_X_COUNT) -#define bfin_write_DMA38_X_COUNT(val) bfin_write32(DMA38_X_COUNT, val) -#define bfin_read_DMA38_X_MODIFY() bfin_read32(DMA38_X_MODIFY) -#define bfin_write_DMA38_X_MODIFY(val) bfin_write32(DMA38_X_MODIFY, val) -#define bfin_read_DMA38_Y_COUNT() bfin_read32(DMA38_Y_COUNT) -#define bfin_write_DMA38_Y_COUNT(val) bfin_write32(DMA38_Y_COUNT, val) -#define bfin_read_DMA38_Y_MODIFY() bfin_read32(DMA38_Y_MODIFY) -#define bfin_write_DMA38_Y_MODIFY(val) bfin_write32(DMA38_Y_MODIFY, val) -#define bfin_read_DMA38_CURR_DESC_PTR() bfin_read32(DMA38_CURR_DESC_PTR) -#define bfin_write_DMA38_CURR_DESC_PTR(val) bfin_write32(DMA38_CURR_DESC_PTR, val) -#define bfin_read_DMA38_PREV_DESC_PTR() bfin_read32(DMA38_PREV_DESC_PTR) -#define bfin_write_DMA38_PREV_DESC_PTR(val) bfin_write32(DMA38_PREV_DESC_PTR, val) -#define bfin_read_DMA38_CURR_ADDR() bfin_read32(DMA38_CURR_ADDR) -#define bfin_write_DMA38_CURR_ADDR(val) bfin_write32(DMA38_CURR_ADDR, val) -#define bfin_read_DMA38_IRQ_STATUS() bfin_read32(DMA38_IRQ_STATUS) -#define bfin_write_DMA38_IRQ_STATUS(val) bfin_write32(DMA38_IRQ_STATUS, val) -#define bfin_read_DMA38_CURR_X_COUNT() bfin_read32(DMA38_CURR_X_COUNT) -#define bfin_write_DMA38_CURR_X_COUNT(val) bfin_write32(DMA38_CURR_X_COUNT, val) -#define bfin_read_DMA38_CURR_Y_COUNT() bfin_read32(DMA38_CURR_Y_COUNT) -#define bfin_write_DMA38_CURR_Y_COUNT(val) bfin_write32(DMA38_CURR_Y_COUNT, val) -#define bfin_read_DMA38_BWL_COUNT() bfin_read32(DMA38_BWL_COUNT) -#define bfin_write_DMA38_BWL_COUNT(val) bfin_write32(DMA38_BWL_COUNT, val) -#define bfin_read_DMA38_CURR_BWL_COUNT() bfin_read32(DMA38_CURR_BWL_COUNT) -#define bfin_write_DMA38_CURR_BWL_COUNT(val) bfin_write32(DMA38_CURR_BWL_COUNT, val) -#define bfin_read_DMA38_BWM_COUNT() bfin_read32(DMA38_BWM_COUNT) -#define bfin_write_DMA38_BWM_COUNT(val) bfin_write32(DMA38_BWM_COUNT, val) -#define bfin_read_DMA38_CURR_BWM_COUNT() bfin_read32(DMA38_CURR_BWM_COUNT) -#define bfin_write_DMA38_CURR_BWM_COUNT(val) bfin_write32(DMA38_CURR_BWM_COUNT, val) - -/* DMA Channel 39 Registers */ - -#define bfin_read_DMA39_NEXT_DESC_PTR() bfin_read32(DMA39_NEXT_DESC_PTR) -#define bfin_write_DMA39_NEXT_DESC_PTR(val) bfin_write32(DMA39_NEXT_DESC_PTR, val) -#define bfin_read_DMA39_START_ADDR() bfin_read32(DMA39_START_ADDR) -#define bfin_write_DMA39_START_ADDR(val) bfin_write32(DMA39_START_ADDR, val) -#define bfin_read_DMA39_CONFIG() bfin_read32(DMA39_CONFIG) -#define bfin_write_DMA39_CONFIG(val) bfin_write32(DMA39_CONFIG, val) -#define bfin_read_DMA39_X_COUNT() bfin_read32(DMA39_X_COUNT) -#define bfin_write_DMA39_X_COUNT(val) bfin_write32(DMA39_X_COUNT, val) -#define bfin_read_DMA39_X_MODIFY() bfin_read32(DMA39_X_MODIFY) -#define bfin_write_DMA39_X_MODIFY(val) bfin_write32(DMA39_X_MODIFY, val) -#define bfin_read_DMA39_Y_COUNT() bfin_read32(DMA39_Y_COUNT) -#define bfin_write_DMA39_Y_COUNT(val) bfin_write32(DMA39_Y_COUNT, val) -#define bfin_read_DMA39_Y_MODIFY() bfin_read32(DMA39_Y_MODIFY) -#define bfin_write_DMA39_Y_MODIFY(val) bfin_write32(DMA39_Y_MODIFY, val) -#define bfin_read_DMA39_CURR_DESC_PTR() bfin_read32(DMA39_CURR_DESC_PTR) -#define bfin_write_DMA39_CURR_DESC_PTR(val) bfin_write32(DMA39_CURR_DESC_PTR, val) -#define bfin_read_DMA39_PREV_DESC_PTR() bfin_read32(DMA39_PREV_DESC_PTR) -#define bfin_write_DMA39_PREV_DESC_PTR(val) bfin_write32(DMA39_PREV_DESC_PTR, val) -#define bfin_read_DMA39_CURR_ADDR() bfin_read32(DMA39_CURR_ADDR) -#define bfin_write_DMA39_CURR_ADDR(val) bfin_write32(DMA39_CURR_ADDR, val) -#define bfin_read_DMA39_IRQ_STATUS() bfin_read32(DMA39_IRQ_STATUS) -#define bfin_write_DMA39_IRQ_STATUS(val) bfin_write32(DMA39_IRQ_STATUS, val) -#define bfin_read_DMA39_CURR_X_COUNT() bfin_read32(DMA39_CURR_X_COUNT) -#define bfin_write_DMA39_CURR_X_COUNT(val) bfin_write32(DMA39_CURR_X_COUNT, val) -#define bfin_read_DMA39_CURR_Y_COUNT() bfin_read32(DMA39_CURR_Y_COUNT) -#define bfin_write_DMA39_CURR_Y_COUNT(val) bfin_write32(DMA39_CURR_Y_COUNT, val) -#define bfin_read_DMA39_BWL_COUNT() bfin_read32(DMA39_BWL_COUNT) -#define bfin_write_DMA39_BWL_COUNT(val) bfin_write32(DMA39_BWL_COUNT, val) -#define bfin_read_DMA39_CURR_BWL_COUNT() bfin_read32(DMA39_CURR_BWL_COUNT) -#define bfin_write_DMA39_CURR_BWL_COUNT(val) bfin_write32(DMA39_CURR_BWL_COUNT, val) -#define bfin_read_DMA39_BWM_COUNT() bfin_read32(DMA39_BWM_COUNT) -#define bfin_write_DMA39_BWM_COUNT(val) bfin_write32(DMA39_BWM_COUNT, val) -#define bfin_read_DMA39_CURR_BWM_COUNT() bfin_read32(DMA39_CURR_BWM_COUNT) -#define bfin_write_DMA39_CURR_BWM_COUNT(val) bfin_write32(DMA39_CURR_BWM_COUNT, val) - -/* DMA Channel 40 Registers */ - -#define bfin_read_DMA40_NEXT_DESC_PTR() bfin_read32(DMA40_NEXT_DESC_PTR) -#define bfin_write_DMA40_NEXT_DESC_PTR(val) bfin_write32(DMA40_NEXT_DESC_PTR, val) -#define bfin_read_DMA40_START_ADDR() bfin_read32(DMA40_START_ADDR) -#define bfin_write_DMA40_START_ADDR(val) bfin_write32(DMA40_START_ADDR, val) -#define bfin_read_DMA40_CONFIG() bfin_read32(DMA40_CONFIG) -#define bfin_write_DMA40_CONFIG(val) bfin_write32(DMA40_CONFIG, val) -#define bfin_read_DMA40_X_COUNT() bfin_read32(DMA40_X_COUNT) -#define bfin_write_DMA40_X_COUNT(val) bfin_write32(DMA40_X_COUNT, val) -#define bfin_read_DMA40_X_MODIFY() bfin_read32(DMA40_X_MODIFY) -#define bfin_write_DMA40_X_MODIFY(val) bfin_write32(DMA40_X_MODIFY, val) -#define bfin_read_DMA40_Y_COUNT() bfin_read32(DMA40_Y_COUNT) -#define bfin_write_DMA40_Y_COUNT(val) bfin_write32(DMA40_Y_COUNT, val) -#define bfin_read_DMA40_Y_MODIFY() bfin_read32(DMA40_Y_MODIFY) -#define bfin_write_DMA40_Y_MODIFY(val) bfin_write32(DMA40_Y_MODIFY, val) -#define bfin_read_DMA40_CURR_DESC_PTR() bfin_read32(DMA40_CURR_DESC_PTR) -#define bfin_write_DMA40_CURR_DESC_PTR(val) bfin_write32(DMA40_CURR_DESC_PTR, val) -#define bfin_read_DMA40_PREV_DESC_PTR() bfin_read32(DMA40_PREV_DESC_PTR) -#define bfin_write_DMA40_PREV_DESC_PTR(val) bfin_write32(DMA40_PREV_DESC_PTR, val) -#define bfin_read_DMA40_CURR_ADDR() bfin_read32(DMA40_CURR_ADDR) -#define bfin_write_DMA40_CURR_ADDR(val) bfin_write32(DMA40_CURR_ADDR, val) -#define bfin_read_DMA40_IRQ_STATUS() bfin_read32(DMA40_IRQ_STATUS) -#define bfin_write_DMA40_IRQ_STATUS(val) bfin_write32(DMA40_IRQ_STATUS, val) -#define bfin_read_DMA40_CURR_X_COUNT() bfin_read32(DMA40_CURR_X_COUNT) -#define bfin_write_DMA40_CURR_X_COUNT(val) bfin_write32(DMA40_CURR_X_COUNT, val) -#define bfin_read_DMA40_CURR_Y_COUNT() bfin_read32(DMA40_CURR_Y_COUNT) -#define bfin_write_DMA40_CURR_Y_COUNT(val) bfin_write32(DMA40_CURR_Y_COUNT, val) -#define bfin_read_DMA40_BWL_COUNT() bfin_read32(DMA40_BWL_COUNT) -#define bfin_write_DMA40_BWL_COUNT(val) bfin_write32(DMA40_BWL_COUNT, val) -#define bfin_read_DMA40_CURR_BWL_COUNT() bfin_read32(DMA40_CURR_BWL_COUNT) -#define bfin_write_DMA40_CURR_BWL_COUNT(val) bfin_write32(DMA40_CURR_BWL_COUNT, val) -#define bfin_read_DMA40_BWM_COUNT() bfin_read32(DMA40_BWM_COUNT) -#define bfin_write_DMA40_BWM_COUNT(val) bfin_write32(DMA40_BWM_COUNT, val) -#define bfin_read_DMA40_CURR_BWM_COUNT() bfin_read32(DMA40_CURR_BWM_COUNT) -#define bfin_write_DMA40_CURR_BWM_COUNT(val) bfin_write32(DMA40_CURR_BWM_COUNT, val) - -/* DMA Channel 41 Registers */ - -#define bfin_read_DMA41_NEXT_DESC_PTR() bfin_read32(DMA41_NEXT_DESC_PTR) -#define bfin_write_DMA41_NEXT_DESC_PTR(val) bfin_write32(DMA41_NEXT_DESC_PTR, val) -#define bfin_read_DMA41_START_ADDR() bfin_read32(DMA41_START_ADDR) -#define bfin_write_DMA41_START_ADDR(val) bfin_write32(DMA41_START_ADDR, val) -#define bfin_read_DMA41_CONFIG() bfin_read32(DMA41_CONFIG) -#define bfin_write_DMA41_CONFIG(val) bfin_write32(DMA41_CONFIG, val) -#define bfin_read_DMA41_X_COUNT() bfin_read32(DMA41_X_COUNT) -#define bfin_write_DMA41_X_COUNT(val) bfin_write32(DMA41_X_COUNT, val) -#define bfin_read_DMA41_X_MODIFY() bfin_read32(DMA41_X_MODIFY) -#define bfin_write_DMA41_X_MODIFY(val) bfin_write32(DMA41_X_MODIFY, val) -#define bfin_read_DMA41_Y_COUNT() bfin_read32(DMA41_Y_COUNT) -#define bfin_write_DMA41_Y_COUNT(val) bfin_write32(DMA41_Y_COUNT, val) -#define bfin_read_DMA41_Y_MODIFY() bfin_read32(DMA41_Y_MODIFY) -#define bfin_write_DMA41_Y_MODIFY(val) bfin_write32(DMA41_Y_MODIFY, val) -#define bfin_read_DMA41_CURR_DESC_PTR() bfin_read32(DMA41_CURR_DESC_PTR) -#define bfin_write_DMA41_CURR_DESC_PTR(val) bfin_write32(DMA41_CURR_DESC_PTR, val) -#define bfin_read_DMA41_PREV_DESC_PTR() bfin_read32(DMA41_PREV_DESC_PTR) -#define bfin_write_DMA41_PREV_DESC_PTR(val) bfin_write32(DMA41_PREV_DESC_PTR, val) -#define bfin_read_DMA41_CURR_ADDR() bfin_read32(DMA41_CURR_ADDR) -#define bfin_write_DMA41_CURR_ADDR(val) bfin_write32(DMA41_CURR_ADDR, val) -#define bfin_read_DMA41_IRQ_STATUS() bfin_read32(DMA41_IRQ_STATUS) -#define bfin_write_DMA41_IRQ_STATUS(val) bfin_write32(DMA41_IRQ_STATUS, val) -#define bfin_read_DMA41_CURR_X_COUNT() bfin_read32(DMA41_CURR_X_COUNT) -#define bfin_write_DMA41_CURR_X_COUNT(val) bfin_write32(DMA41_CURR_X_COUNT, val) -#define bfin_read_DMA41_CURR_Y_COUNT() bfin_read32(DMA41_CURR_Y_COUNT) -#define bfin_write_DMA41_CURR_Y_COUNT(val) bfin_write32(DMA41_CURR_Y_COUNT, val) -#define bfin_read_DMA41_BWL_COUNT() bfin_read32(DMA41_BWL_COUNT) -#define bfin_write_DMA41_BWL_COUNT(val) bfin_write32(DMA41_BWL_COUNT, val) -#define bfin_read_DMA41_CURR_BWL_COUNT() bfin_read32(DMA41_CURR_BWL_COUNT) -#define bfin_write_DMA41_CURR_BWL_COUNT(val) bfin_write32(DMA41_CURR_BWL_COUNT, val) -#define bfin_read_DMA41_BWM_COUNT() bfin_read32(DMA41_BWM_COUNT) -#define bfin_write_DMA41_BWM_COUNT(val) bfin_write32(DMA41_BWM_COUNT, val) -#define bfin_read_DMA41_CURR_BWM_COUNT() bfin_read32(DMA41_CURR_BWM_COUNT) -#define bfin_write_DMA41_CURR_BWM_COUNT(val) bfin_write32(DMA41_CURR_BWM_COUNT, val) - -/* DMA Channel 42 Registers */ - -#define bfin_read_DMA42_NEXT_DESC_PTR() bfin_read32(DMA42_NEXT_DESC_PTR) -#define bfin_write_DMA42_NEXT_DESC_PTR(val) bfin_write32(DMA42_NEXT_DESC_PTR, val) -#define bfin_read_DMA42_START_ADDR() bfin_read32(DMA42_START_ADDR) -#define bfin_write_DMA42_START_ADDR(val) bfin_write32(DMA42_START_ADDR, val) -#define bfin_read_DMA42_CONFIG() bfin_read32(DMA42_CONFIG) -#define bfin_write_DMA42_CONFIG(val) bfin_write32(DMA42_CONFIG, val) -#define bfin_read_DMA42_X_COUNT() bfin_read32(DMA42_X_COUNT) -#define bfin_write_DMA42_X_COUNT(val) bfin_write32(DMA42_X_COUNT, val) -#define bfin_read_DMA42_X_MODIFY() bfin_read32(DMA42_X_MODIFY) -#define bfin_write_DMA42_X_MODIFY(val) bfin_write32(DMA42_X_MODIFY, val) -#define bfin_read_DMA42_Y_COUNT() bfin_read32(DMA42_Y_COUNT) -#define bfin_write_DMA42_Y_COUNT(val) bfin_write32(DMA42_Y_COUNT, val) -#define bfin_read_DMA42_Y_MODIFY() bfin_read32(DMA42_Y_MODIFY) -#define bfin_write_DMA42_Y_MODIFY(val) bfin_write32(DMA42_Y_MODIFY, val) -#define bfin_read_DMA42_CURR_DESC_PTR() bfin_read32(DMA42_CURR_DESC_PTR) -#define bfin_write_DMA42_CURR_DESC_PTR(val) bfin_write32(DMA42_CURR_DESC_PTR, val) -#define bfin_read_DMA42_PREV_DESC_PTR() bfin_read32(DMA42_PREV_DESC_PTR) -#define bfin_write_DMA42_PREV_DESC_PTR(val) bfin_write32(DMA42_PREV_DESC_PTR, val) -#define bfin_read_DMA42_CURR_ADDR() bfin_read32(DMA42_CURR_ADDR) -#define bfin_write_DMA42_CURR_ADDR(val) bfin_write32(DMA42_CURR_ADDR, val) -#define bfin_read_DMA42_IRQ_STATUS() bfin_read32(DMA42_IRQ_STATUS) -#define bfin_write_DMA42_IRQ_STATUS(val) bfin_write32(DMA42_IRQ_STATUS, val) -#define bfin_read_DMA42_CURR_X_COUNT() bfin_read32(DMA42_CURR_X_COUNT) -#define bfin_write_DMA42_CURR_X_COUNT(val) bfin_write32(DMA42_CURR_X_COUNT, val) -#define bfin_read_DMA42_CURR_Y_COUNT() bfin_read32(DMA42_CURR_Y_COUNT) -#define bfin_write_DMA42_CURR_Y_COUNT(val) bfin_write32(DMA42_CURR_Y_COUNT, val) -#define bfin_read_DMA42_BWL_COUNT() bfin_read32(DMA42_BWL_COUNT) -#define bfin_write_DMA42_BWL_COUNT(val) bfin_write32(DMA42_BWL_COUNT, val) -#define bfin_read_DMA42_CURR_BWL_COUNT() bfin_read32(DMA42_CURR_BWL_COUNT) -#define bfin_write_DMA42_CURR_BWL_COUNT(val) bfin_write32(DMA42_CURR_BWL_COUNT, val) -#define bfin_read_DMA42_BWM_COUNT() bfin_read32(DMA42_BWM_COUNT) -#define bfin_write_DMA42_BWM_COUNT(val) bfin_write32(DMA42_BWM_COUNT, val) -#define bfin_read_DMA42_CURR_BWM_COUNT() bfin_read32(DMA42_CURR_BWM_COUNT) -#define bfin_write_DMA42_CURR_BWM_COUNT(val) bfin_write32(DMA42_CURR_BWM_COUNT, val) - -/* DMA Channel 43 Registers */ - -#define bfin_read_DMA43_NEXT_DESC_PTR() bfin_read32(DMA43_NEXT_DESC_PTR) -#define bfin_write_DMA43_NEXT_DESC_PTR(val) bfin_write32(DMA43_NEXT_DESC_PTR, val) -#define bfin_read_DMA43_START_ADDR() bfin_read32(DMA43_START_ADDR) -#define bfin_write_DMA43_START_ADDR(val) bfin_write32(DMA43_START_ADDR, val) -#define bfin_read_DMA43_CONFIG() bfin_read32(DMA43_CONFIG) -#define bfin_write_DMA43_CONFIG(val) bfin_write32(DMA43_CONFIG, val) -#define bfin_read_DMA43_X_COUNT() bfin_read32(DMA43_X_COUNT) -#define bfin_write_DMA43_X_COUNT(val) bfin_write32(DMA43_X_COUNT, val) -#define bfin_read_DMA43_X_MODIFY() bfin_read32(DMA43_X_MODIFY) -#define bfin_write_DMA43_X_MODIFY(val) bfin_write32(DMA43_X_MODIFY, val) -#define bfin_read_DMA43_Y_COUNT() bfin_read32(DMA43_Y_COUNT) -#define bfin_write_DMA43_Y_COUNT(val) bfin_write32(DMA43_Y_COUNT, val) -#define bfin_read_DMA43_Y_MODIFY() bfin_read32(DMA43_Y_MODIFY) -#define bfin_write_DMA43_Y_MODIFY(val) bfin_write32(DMA43_Y_MODIFY, val) -#define bfin_read_DMA43_CURR_DESC_PTR() bfin_read32(DMA43_CURR_DESC_PTR) -#define bfin_write_DMA43_CURR_DESC_PTR(val) bfin_write32(DMA43_CURR_DESC_PTR, val) -#define bfin_read_DMA43_PREV_DESC_PTR() bfin_read32(DMA43_PREV_DESC_PTR) -#define bfin_write_DMA43_PREV_DESC_PTR(val) bfin_write32(DMA43_PREV_DESC_PTR, val) -#define bfin_read_DMA43_CURR_ADDR() bfin_read32(DMA43_CURR_ADDR) -#define bfin_write_DMA43_CURR_ADDR(val) bfin_write32(DMA43_CURR_ADDR, val) -#define bfin_read_DMA43_IRQ_STATUS() bfin_read32(DMA43_IRQ_STATUS) -#define bfin_write_DMA43_IRQ_STATUS(val) bfin_write32(DMA43_IRQ_STATUS, val) -#define bfin_read_DMA43_CURR_X_COUNT() bfin_read32(DMA43_CURR_X_COUNT) -#define bfin_write_DMA43_CURR_X_COUNT(val) bfin_write32(DMA43_CURR_X_COUNT, val) -#define bfin_read_DMA43_CURR_Y_COUNT() bfin_read32(DMA43_CURR_Y_COUNT) -#define bfin_write_DMA43_CURR_Y_COUNT(val) bfin_write32(DMA43_CURR_Y_COUNT, val) -#define bfin_read_DMA43_BWL_COUNT() bfin_read32(DMA43_BWL_COUNT) -#define bfin_write_DMA43_BWL_COUNT(val) bfin_write32(DMA43_BWL_COUNT, val) -#define bfin_read_DMA43_CURR_BWL_COUNT() bfin_read32(DMA43_CURR_BWL_COUNT) -#define bfin_write_DMA43_CURR_BWL_COUNT(val) bfin_write32(DMA43_CURR_BWL_COUNT, val) -#define bfin_read_DMA43_BWM_COUNT() bfin_read32(DMA43_BWM_COUNT) -#define bfin_write_DMA43_BWM_COUNT(val) bfin_write32(DMA43_BWM_COUNT, val) -#define bfin_read_DMA43_CURR_BWM_COUNT() bfin_read32(DMA43_CURR_BWM_COUNT) -#define bfin_write_DMA43_CURR_BWM_COUNT(val) bfin_write32(DMA43_CURR_BWM_COUNT, val) - -/* DMA Channel 44 Registers */ - -#define bfin_read_DMA44_NEXT_DESC_PTR() bfin_read32(DMA44_NEXT_DESC_PTR) -#define bfin_write_DMA44_NEXT_DESC_PTR(val) bfin_write32(DMA44_NEXT_DESC_PTR, val) -#define bfin_read_DMA44_START_ADDR() bfin_read32(DMA44_START_ADDR) -#define bfin_write_DMA44_START_ADDR(val) bfin_write32(DMA44_START_ADDR, val) -#define bfin_read_DMA44_CONFIG() bfin_read32(DMA44_CONFIG) -#define bfin_write_DMA44_CONFIG(val) bfin_write32(DMA44_CONFIG, val) -#define bfin_read_DMA44_X_COUNT() bfin_read32(DMA44_X_COUNT) -#define bfin_write_DMA44_X_COUNT(val) bfin_write32(DMA44_X_COUNT, val) -#define bfin_read_DMA44_X_MODIFY() bfin_read32(DMA44_X_MODIFY) -#define bfin_write_DMA44_X_MODIFY(val) bfin_write32(DMA44_X_MODIFY, val) -#define bfin_read_DMA44_Y_COUNT() bfin_read32(DMA44_Y_COUNT) -#define bfin_write_DMA44_Y_COUNT(val) bfin_write32(DMA44_Y_COUNT, val) -#define bfin_read_DMA44_Y_MODIFY() bfin_read32(DMA44_Y_MODIFY) -#define bfin_write_DMA44_Y_MODIFY(val) bfin_write32(DMA44_Y_MODIFY, val) -#define bfin_read_DMA44_CURR_DESC_PTR() bfin_read32(DMA44_CURR_DESC_PTR) -#define bfin_write_DMA44_CURR_DESC_PTR(val) bfin_write32(DMA44_CURR_DESC_PTR, val) -#define bfin_read_DMA44_PREV_DESC_PTR() bfin_read32(DMA44_PREV_DESC_PTR) -#define bfin_write_DMA44_PREV_DESC_PTR(val) bfin_write32(DMA44_PREV_DESC_PTR, val) -#define bfin_read_DMA44_CURR_ADDR() bfin_read32(DMA44_CURR_ADDR) -#define bfin_write_DMA44_CURR_ADDR(val) bfin_write32(DMA44_CURR_ADDR, val) -#define bfin_read_DMA44_IRQ_STATUS() bfin_read32(DMA44_IRQ_STATUS) -#define bfin_write_DMA44_IRQ_STATUS(val) bfin_write32(DMA44_IRQ_STATUS, val) -#define bfin_read_DMA44_CURR_X_COUNT() bfin_read32(DMA44_CURR_X_COUNT) -#define bfin_write_DMA44_CURR_X_COUNT(val) bfin_write32(DMA44_CURR_X_COUNT, val) -#define bfin_read_DMA44_CURR_Y_COUNT() bfin_read32(DMA44_CURR_Y_COUNT) -#define bfin_write_DMA44_CURR_Y_COUNT(val) bfin_write32(DMA44_CURR_Y_COUNT, val) -#define bfin_read_DMA44_BWL_COUNT() bfin_read32(DMA44_BWL_COUNT) -#define bfin_write_DMA44_BWL_COUNT(val) bfin_write32(DMA44_BWL_COUNT, val) -#define bfin_read_DMA44_CURR_BWL_COUNT() bfin_read32(DMA44_CURR_BWL_COUNT) -#define bfin_write_DMA44_CURR_BWL_COUNT(val) bfin_write32(DMA44_CURR_BWL_COUNT, val) -#define bfin_read_DMA44_BWM_COUNT() bfin_read32(DMA44_BWM_COUNT) -#define bfin_write_DMA44_BWM_COUNT(val) bfin_write32(DMA44_BWM_COUNT, val) -#define bfin_read_DMA44_CURR_BWM_COUNT() bfin_read32(DMA44_CURR_BWM_COUNT) -#define bfin_write_DMA44_CURR_BWM_COUNT(val) bfin_write32(DMA44_CURR_BWM_COUNT, val) - -/* DMA Channel 45 Registers */ - -#define bfin_read_DMA45_NEXT_DESC_PTR() bfin_read32(DMA45_NEXT_DESC_PTR) -#define bfin_write_DMA45_NEXT_DESC_PTR(val) bfin_write32(DMA45_NEXT_DESC_PTR, val) -#define bfin_read_DMA45_START_ADDR() bfin_read32(DMA45_START_ADDR) -#define bfin_write_DMA45_START_ADDR(val) bfin_write32(DMA45_START_ADDR, val) -#define bfin_read_DMA45_CONFIG() bfin_read32(DMA45_CONFIG) -#define bfin_write_DMA45_CONFIG(val) bfin_write32(DMA45_CONFIG, val) -#define bfin_read_DMA45_X_COUNT() bfin_read32(DMA45_X_COUNT) -#define bfin_write_DMA45_X_COUNT(val) bfin_write32(DMA45_X_COUNT, val) -#define bfin_read_DMA45_X_MODIFY() bfin_read32(DMA45_X_MODIFY) -#define bfin_write_DMA45_X_MODIFY(val) bfin_write32(DMA45_X_MODIFY, val) -#define bfin_read_DMA45_Y_COUNT() bfin_read32(DMA45_Y_COUNT) -#define bfin_write_DMA45_Y_COUNT(val) bfin_write32(DMA45_Y_COUNT, val) -#define bfin_read_DMA45_Y_MODIFY() bfin_read32(DMA45_Y_MODIFY) -#define bfin_write_DMA45_Y_MODIFY(val) bfin_write32(DMA45_Y_MODIFY, val) -#define bfin_read_DMA45_CURR_DESC_PTR() bfin_read32(DMA45_CURR_DESC_PTR) -#define bfin_write_DMA45_CURR_DESC_PTR(val) bfin_write32(DMA45_CURR_DESC_PTR, val) -#define bfin_read_DMA45_PREV_DESC_PTR() bfin_read32(DMA45_PREV_DESC_PTR) -#define bfin_write_DMA45_PREV_DESC_PTR(val) bfin_write32(DMA45_PREV_DESC_PTR, val) -#define bfin_read_DMA45_CURR_ADDR() bfin_read32(DMA45_CURR_ADDR) -#define bfin_write_DMA45_CURR_ADDR(val) bfin_write32(DMA45_CURR_ADDR, val) -#define bfin_read_DMA45_IRQ_STATUS() bfin_read32(DMA45_IRQ_STATUS) -#define bfin_write_DMA45_IRQ_STATUS(val) bfin_write32(DMA45_IRQ_STATUS, val) -#define bfin_read_DMA45_CURR_X_COUNT() bfin_read32(DMA45_CURR_X_COUNT) -#define bfin_write_DMA45_CURR_X_COUNT(val) bfin_write32(DMA45_CURR_X_COUNT, val) -#define bfin_read_DMA45_CURR_Y_COUNT() bfin_read32(DMA45_CURR_Y_COUNT) -#define bfin_write_DMA45_CURR_Y_COUNT(val) bfin_write32(DMA45_CURR_Y_COUNT, val) -#define bfin_read_DMA45_BWL_COUNT() bfin_read32(DMA45_BWL_COUNT) -#define bfin_write_DMA45_BWL_COUNT(val) bfin_write32(DMA45_BWL_COUNT, val) -#define bfin_read_DMA45_CURR_BWL_COUNT() bfin_read32(DMA45_CURR_BWL_COUNT) -#define bfin_write_DMA45_CURR_BWL_COUNT(val) bfin_write32(DMA45_CURR_BWL_COUNT, val) -#define bfin_read_DMA45_BWM_COUNT() bfin_read32(DMA45_BWM_COUNT) -#define bfin_write_DMA45_BWM_COUNT(val) bfin_write32(DMA45_BWM_COUNT, val) -#define bfin_read_DMA45_CURR_BWM_COUNT() bfin_read32(DMA45_CURR_BWM_COUNT) -#define bfin_write_DMA45_CURR_BWM_COUNT(val) bfin_write32(DMA45_CURR_BWM_COUNT, val) - -/* DMA Channel 46 Registers */ - -#define bfin_read_DMA46_NEXT_DESC_PTR() bfin_read32(DMA46_NEXT_DESC_PTR) -#define bfin_write_DMA46_NEXT_DESC_PTR(val) bfin_write32(DMA46_NEXT_DESC_PTR, val) -#define bfin_read_DMA46_START_ADDR() bfin_read32(DMA46_START_ADDR) -#define bfin_write_DMA46_START_ADDR(val) bfin_write32(DMA46_START_ADDR, val) -#define bfin_read_DMA46_CONFIG() bfin_read32(DMA46_CONFIG) -#define bfin_write_DMA46_CONFIG(val) bfin_write32(DMA46_CONFIG, val) -#define bfin_read_DMA46_X_COUNT() bfin_read32(DMA46_X_COUNT) -#define bfin_write_DMA46_X_COUNT(val) bfin_write32(DMA46_X_COUNT, val) -#define bfin_read_DMA46_X_MODIFY() bfin_read32(DMA46_X_MODIFY) -#define bfin_write_DMA46_X_MODIFY(val) bfin_write32(DMA46_X_MODIFY, val) -#define bfin_read_DMA46_Y_COUNT() bfin_read32(DMA46_Y_COUNT) -#define bfin_write_DMA46_Y_COUNT(val) bfin_write32(DMA46_Y_COUNT, val) -#define bfin_read_DMA46_Y_MODIFY() bfin_read32(DMA46_Y_MODIFY) -#define bfin_write_DMA46_Y_MODIFY(val) bfin_write32(DMA46_Y_MODIFY, val) -#define bfin_read_DMA46_CURR_DESC_PTR() bfin_read32(DMA46_CURR_DESC_PTR) -#define bfin_write_DMA46_CURR_DESC_PTR(val) bfin_write32(DMA46_CURR_DESC_PTR, val) -#define bfin_read_DMA46_PREV_DESC_PTR() bfin_read32(DMA46_PREV_DESC_PTR) -#define bfin_write_DMA46_PREV_DESC_PTR(val) bfin_write32(DMA46_PREV_DESC_PTR, val) -#define bfin_read_DMA46_CURR_ADDR() bfin_read32(DMA46_CURR_ADDR) -#define bfin_write_DMA46_CURR_ADDR(val) bfin_write32(DMA46_CURR_ADDR, val) -#define bfin_read_DMA46_IRQ_STATUS() bfin_read32(DMA46_IRQ_STATUS) -#define bfin_write_DMA46_IRQ_STATUS(val) bfin_write32(DMA46_IRQ_STATUS, val) -#define bfin_read_DMA46_CURR_X_COUNT() bfin_read32(DMA46_CURR_X_COUNT) -#define bfin_write_DMA46_CURR_X_COUNT(val) bfin_write32(DMA46_CURR_X_COUNT, val) -#define bfin_read_DMA46_CURR_Y_COUNT() bfin_read32(DMA46_CURR_Y_COUNT) -#define bfin_write_DMA46_CURR_Y_COUNT(val) bfin_write32(DMA46_CURR_Y_COUNT, val) -#define bfin_read_DMA46_BWL_COUNT() bfin_read32(DMA46_BWL_COUNT) -#define bfin_write_DMA46_BWL_COUNT(val) bfin_write32(DMA46_BWL_COUNT, val) -#define bfin_read_DMA46_CURR_BWL_COUNT() bfin_read32(DMA46_CURR_BWL_COUNT) -#define bfin_write_DMA46_CURR_BWL_COUNT(val) bfin_write32(DMA46_CURR_BWL_COUNT, val) -#define bfin_read_DMA46_BWM_COUNT() bfin_read32(DMA46_BWM_COUNT) -#define bfin_write_DMA46_BWM_COUNT(val) bfin_write32(DMA46_BWM_COUNT, val) -#define bfin_read_DMA46_CURR_BWM_COUNT() bfin_read32(DMA46_CURR_BWM_COUNT) -#define bfin_write_DMA46_CURR_BWM_COUNT(val) bfin_write32(DMA46_CURR_BWM_COUNT, val) - - -/* EPPI1 Registers */ - - -/* Port Interrubfin_read_()t 0 Registers (32-bit) */ - -#define bfin_read_PINT0_MASK_SET() bfin_read32(PINT0_MASK_SET) -#define bfin_write_PINT0_MASK_SET(val) bfin_write32(PINT0_MASK_SET, val) -#define bfin_read_PINT0_MASK_CLEAR() bfin_read32(PINT0_MASK_CLEAR) -#define bfin_write_PINT0_MASK_CLEAR(val) bfin_write32(PINT0_MASK_CLEAR, val) -#define bfin_read_PINT0_REQUEST() bfin_read32(PINT0_REQUEST) -#define bfin_write_PINT0_REQUEST(val) bfin_write32(PINT0_REQUEST, val) -#define bfin_read_PINT0_ASSIGN() bfin_read32(PINT0_ASSIGN) -#define bfin_write_PINT0_ASSIGN(val) bfin_write32(PINT0_ASSIGN, val) -#define bfin_read_PINT0_EDGE_SET() bfin_read32(PINT0_EDGE_SET) -#define bfin_write_PINT0_EDGE_SET(val) bfin_write32(PINT0_EDGE_SET, val) -#define bfin_read_PINT0_EDGE_CLEAR() bfin_read32(PINT0_EDGE_CLEAR) -#define bfin_write_PINT0_EDGE_CLEAR(val) bfin_write32(PINT0_EDGE_CLEAR, val) -#define bfin_read_PINT0_INVERT_SET() bfin_read32(PINT0_INVERT_SET) -#define bfin_write_PINT0_INVERT_SET(val) bfin_write32(PINT0_INVERT_SET, val) -#define bfin_read_PINT0_INVERT_CLEAR() bfin_read32(PINT0_INVERT_CLEAR) -#define bfin_write_PINT0_INVERT_CLEAR(val) bfin_write32(PINT0_INVERT_CLEAR, val) -#define bfin_read_PINT0_PINSTATE() bfin_read32(PINT0_PINSTATE) -#define bfin_write_PINT0_PINSTATE(val) bfin_write32(PINT0_PINSTATE, val) -#define bfin_read_PINT0_LATCH() bfin_read32(PINT0_LATCH) -#define bfin_write_PINT0_LATCH(val) bfin_write32(PINT0_LATCH, val) - -/* Port Interrubfin_read_()t 1 Registers (32-bit) */ - -#define bfin_read_PINT1_MASK_SET() bfin_read32(PINT1_MASK_SET) -#define bfin_write_PINT1_MASK_SET(val) bfin_write32(PINT1_MASK_SET, val) -#define bfin_read_PINT1_MASK_CLEAR() bfin_read32(PINT1_MASK_CLEAR) -#define bfin_write_PINT1_MASK_CLEAR(val) bfin_write32(PINT1_MASK_CLEAR, val) -#define bfin_read_PINT1_REQUEST() bfin_read32(PINT1_REQUEST) -#define bfin_write_PINT1_REQUEST(val) bfin_write32(PINT1_REQUEST, val) -#define bfin_read_PINT1_ASSIGN() bfin_read32(PINT1_ASSIGN) -#define bfin_write_PINT1_ASSIGN(val) bfin_write32(PINT1_ASSIGN, val) -#define bfin_read_PINT1_EDGE_SET() bfin_read32(PINT1_EDGE_SET) -#define bfin_write_PINT1_EDGE_SET(val) bfin_write32(PINT1_EDGE_SET, val) -#define bfin_read_PINT1_EDGE_CLEAR() bfin_read32(PINT1_EDGE_CLEAR) -#define bfin_write_PINT1_EDGE_CLEAR(val) bfin_write32(PINT1_EDGE_CLEAR, val) -#define bfin_read_PINT1_INVERT_SET() bfin_read32(PINT1_INVERT_SET) -#define bfin_write_PINT1_INVERT_SET(val) bfin_write32(PINT1_INVERT_SET, val) -#define bfin_read_PINT1_INVERT_CLEAR() bfin_read32(PINT1_INVERT_CLEAR) -#define bfin_write_PINT1_INVERT_CLEAR(val) bfin_write32(PINT1_INVERT_CLEAR, val) -#define bfin_read_PINT1_PINSTATE() bfin_read32(PINT1_PINSTATE) -#define bfin_write_PINT1_PINSTATE(val) bfin_write32(PINT1_PINSTATE, val) -#define bfin_read_PINT1_LATCH() bfin_read32(PINT1_LATCH) -#define bfin_write_PINT1_LATCH(val) bfin_write32(PINT1_LATCH, val) - -/* Port Interrubfin_read_()t 2 Registers (32-bit) */ - -#define bfin_read_PINT2_MASK_SET() bfin_read32(PINT2_MASK_SET) -#define bfin_write_PINT2_MASK_SET(val) bfin_write32(PINT2_MASK_SET, val) -#define bfin_read_PINT2_MASK_CLEAR() bfin_read32(PINT2_MASK_CLEAR) -#define bfin_write_PINT2_MASK_CLEAR(val) bfin_write32(PINT2_MASK_CLEAR, val) -#define bfin_read_PINT2_REQUEST() bfin_read32(PINT2_REQUEST) -#define bfin_write_PINT2_REQUEST(val) bfin_write32(PINT2_REQUEST, val) -#define bfin_read_PINT2_ASSIGN() bfin_read32(PINT2_ASSIGN) -#define bfin_write_PINT2_ASSIGN(val) bfin_write32(PINT2_ASSIGN, val) -#define bfin_read_PINT2_EDGE_SET() bfin_read32(PINT2_EDGE_SET) -#define bfin_write_PINT2_EDGE_SET(val) bfin_write32(PINT2_EDGE_SET, val) -#define bfin_read_PINT2_EDGE_CLEAR() bfin_read32(PINT2_EDGE_CLEAR) -#define bfin_write_PINT2_EDGE_CLEAR(val) bfin_write32(PINT2_EDGE_CLEAR, val) -#define bfin_read_PINT2_INVERT_SET() bfin_read32(PINT2_INVERT_SET) -#define bfin_write_PINT2_INVERT_SET(val) bfin_write32(PINT2_INVERT_SET, val) -#define bfin_read_PINT2_INVERT_CLEAR() bfin_read32(PINT2_INVERT_CLEAR) -#define bfin_write_PINT2_INVERT_CLEAR(val) bfin_write32(PINT2_INVERT_CLEAR, val) -#define bfin_read_PINT2_PINSTATE() bfin_read32(PINT2_PINSTATE) -#define bfin_write_PINT2_PINSTATE(val) bfin_write32(PINT2_PINSTATE, val) -#define bfin_read_PINT2_LATCH() bfin_read32(PINT2_LATCH) -#define bfin_write_PINT2_LATCH(val) bfin_write32(PINT2_LATCH, val) - -/* Port Interrubfin_read_()t 3 Registers (32-bit) */ - -#define bfin_read_PINT3_MASK_SET() bfin_read32(PINT3_MASK_SET) -#define bfin_write_PINT3_MASK_SET(val) bfin_write32(PINT3_MASK_SET, val) -#define bfin_read_PINT3_MASK_CLEAR() bfin_read32(PINT3_MASK_CLEAR) -#define bfin_write_PINT3_MASK_CLEAR(val) bfin_write32(PINT3_MASK_CLEAR, val) -#define bfin_read_PINT3_REQUEST() bfin_read32(PINT3_REQUEST) -#define bfin_write_PINT3_REQUEST(val) bfin_write32(PINT3_REQUEST, val) -#define bfin_read_PINT3_ASSIGN() bfin_read32(PINT3_ASSIGN) -#define bfin_write_PINT3_ASSIGN(val) bfin_write32(PINT3_ASSIGN, val) -#define bfin_read_PINT3_EDGE_SET() bfin_read32(PINT3_EDGE_SET) -#define bfin_write_PINT3_EDGE_SET(val) bfin_write32(PINT3_EDGE_SET, val) -#define bfin_read_PINT3_EDGE_CLEAR() bfin_read32(PINT3_EDGE_CLEAR) -#define bfin_write_PINT3_EDGE_CLEAR(val) bfin_write32(PINT3_EDGE_CLEAR, val) -#define bfin_read_PINT3_INVERT_SET() bfin_read32(PINT3_INVERT_SET) -#define bfin_write_PINT3_INVERT_SET(val) bfin_write32(PINT3_INVERT_SET, val) -#define bfin_read_PINT3_INVERT_CLEAR() bfin_read32(PINT3_INVERT_CLEAR) -#define bfin_write_PINT3_INVERT_CLEAR(val) bfin_write32(PINT3_INVERT_CLEAR, val) -#define bfin_read_PINT3_PINSTATE() bfin_read32(PINT3_PINSTATE) -#define bfin_write_PINT3_PINSTATE(val) bfin_write32(PINT3_PINSTATE, val) -#define bfin_read_PINT3_LATCH() bfin_read32(PINT3_LATCH) -#define bfin_write_PINT3_LATCH(val) bfin_write32(PINT3_LATCH, val) - -/* Port Interrubfin_read_()t 4 Registers (32-bit) */ - -#define bfin_read_PINT4_MASK_SET() bfin_read32(PINT4_MASK_SET) -#define bfin_write_PINT4_MASK_SET(val) bfin_write32(PINT4_MASK_SET, val) -#define bfin_read_PINT4_MASK_CLEAR() bfin_read32(PINT4_MASK_CLEAR) -#define bfin_write_PINT4_MASK_CLEAR(val) bfin_write32(PINT4_MASK_CLEAR, val) -#define bfin_read_PINT4_REQUEST() bfin_read32(PINT4_REQUEST) -#define bfin_write_PINT4_REQUEST(val) bfin_write32(PINT4_REQUEST, val) -#define bfin_read_PINT4_ASSIGN() bfin_read32(PINT4_ASSIGN) -#define bfin_write_PINT4_ASSIGN(val) bfin_write32(PINT4_ASSIGN, val) -#define bfin_read_PINT4_EDGE_SET() bfin_read32(PINT4_EDGE_SET) -#define bfin_write_PINT4_EDGE_SET(val) bfin_write32(PINT4_EDGE_SET, val) -#define bfin_read_PINT4_EDGE_CLEAR() bfin_read32(PINT4_EDGE_CLEAR) -#define bfin_write_PINT4_EDGE_CLEAR(val) bfin_write32(PINT4_EDGE_CLEAR, val) -#define bfin_read_PINT4_INVERT_SET() bfin_read32(PINT4_INVERT_SET) -#define bfin_write_PINT4_INVERT_SET(val) bfin_write32(PINT4_INVERT_SET, val) -#define bfin_read_PINT4_INVERT_CLEAR() bfin_read32(PINT4_INVERT_CLEAR) -#define bfin_write_PINT4_INVERT_CLEAR(val) bfin_write32(PINT4_INVERT_CLEAR, val) -#define bfin_read_PINT4_PINSTATE() bfin_read32(PINT4_PINSTATE) -#define bfin_write_PINT4_PINSTATE(val) bfin_write32(PINT4_PINSTATE, val) -#define bfin_read_PINT4_LATCH() bfin_read32(PINT4_LATCH) -#define bfin_write_PINT4_LATCH(val) bfin_write32(PINT4_LATCH, val) - -/* Port Interrubfin_read_()t 5 Registers (32-bit) */ - -#define bfin_read_PINT5_MASK_SET() bfin_read32(PINT5_MASK_SET) -#define bfin_write_PINT5_MASK_SET(val) bfin_write32(PINT5_MASK_SET, val) -#define bfin_read_PINT5_MASK_CLEAR() bfin_read32(PINT5_MASK_CLEAR) -#define bfin_write_PINT5_MASK_CLEAR(val) bfin_write32(PINT5_MASK_CLEAR, val) -#define bfin_read_PINT5_REQUEST() bfin_read32(PINT5_REQUEST) -#define bfin_write_PINT5_REQUEST(val) bfin_write32(PINT5_REQUEST, val) -#define bfin_read_PINT5_ASSIGN() bfin_read32(PINT5_ASSIGN) -#define bfin_write_PINT5_ASSIGN(val) bfin_write32(PINT5_ASSIGN, val) -#define bfin_read_PINT5_EDGE_SET() bfin_read32(PINT5_EDGE_SET) -#define bfin_write_PINT5_EDGE_SET(val) bfin_write32(PINT5_EDGE_SET, val) -#define bfin_read_PINT5_EDGE_CLEAR() bfin_read32(PINT5_EDGE_CLEAR) -#define bfin_write_PINT5_EDGE_CLEAR(val) bfin_write32(PINT5_EDGE_CLEAR, val) -#define bfin_read_PINT5_INVERT_SET() bfin_read32(PINT5_INVERT_SET) -#define bfin_write_PINT5_INVERT_SET(val) bfin_write32(PINT5_INVERT_SET, val) -#define bfin_read_PINT5_INVERT_CLEAR() bfin_read32(PINT5_INVERT_CLEAR) -#define bfin_write_PINT5_INVERT_CLEAR(val) bfin_write32(PINT5_INVERT_CLEAR, val) -#define bfin_read_PINT5_PINSTATE() bfin_read32(PINT5_PINSTATE) -#define bfin_write_PINT5_PINSTATE(val) bfin_write32(PINT5_PINSTATE, val) -#define bfin_read_PINT5_LATCH() bfin_read32(PINT5_LATCH) -#define bfin_write_PINT5_LATCH(val) bfin_write32(PINT5_LATCH, val) - -/* Port A Registers */ - -#define bfin_read_PORTA_FER() bfin_read32(PORTA_FER) -#define bfin_write_PORTA_FER(val) bfin_write32(PORTA_FER, val) -#define bfin_read_PORTA_FER_SET() bfin_read32(PORTA_FER_SET) -#define bfin_write_PORTA_FER_SET(val) bfin_write32(PORTA_FER_SET, val) -#define bfin_read_PORTA_FER_CLEAR() bfin_read32(PORTA_FER_CLEAR) -#define bfin_write_PORTA_FER_CLEAR(val) bfin_write32(PORTA_FER_CLEAR, val) -#define bfin_read_PORTA() bfin_read32(PORTA) -#define bfin_write_PORTA(val) bfin_write32(PORTA, val) -#define bfin_read_PORTA_SET() bfin_read32(PORTA_SET) -#define bfin_write_PORTA_SET(val) bfin_write32(PORTA_SET, val) -#define bfin_read_PORTA_CLEAR() bfin_read32(PORTA_CLEAR) -#define bfin_write_PORTA_CLEAR(val) bfin_write32(PORTA_CLEAR, val) -#define bfin_read_PORTA_DIR() bfin_read32(PORTA_DIR) -#define bfin_write_PORTA_DIR(val) bfin_write32(PORTA_DIR, val) -#define bfin_read_PORTA_DIR_SET() bfin_read32(PORTA_DIR_SET) -#define bfin_write_PORTA_DIR_SET(val) bfin_write32(PORTA_DIR_SET, val) -#define bfin_read_PORTA_DIR_CLEAR() bfin_read32(PORTA_DIR_CLEAR) -#define bfin_write_PORTA_DIR_CLEAR(val) bfin_write32(PORTA_DIR_CLEAR, val) -#define bfin_read_PORTA_INEN() bfin_read32(PORTA_INEN) -#define bfin_write_PORTA_INEN(val) bfin_write32(PORTA_INEN, val) -#define bfin_read_PORTA_INEN_SET() bfin_read32(PORTA_INEN_SET) -#define bfin_write_PORTA_INEN_SET(val) bfin_write32(PORTA_INEN_SET, val) -#define bfin_read_PORTA_INEN_CLEAR() bfin_read32(PORTA_INEN_CLEAR) -#define bfin_write_PORTA_INEN_CLEAR(val) bfin_write32(PORTA_INEN_CLEAR, val) -#define bfin_read_PORTA_MUX() bfin_read32(PORTA_MUX) -#define bfin_write_PORTA_MUX(val) bfin_write32(PORTA_MUX, val) -#define bfin_read_PORTA_DATA_TGL() bfin_read32(PORTA_DATA_TGL) -#define bfin_write_PORTA_DATA_TGL(val) bfin_write32(PORTA_DATA_TGL, val) -#define bfin_read_PORTA_POL() bfin_read32(PORTA_POL) -#define bfin_write_PORTA_POL(val) bfin_write32(PORTA_POL, val) -#define bfin_read_PORTA_POL_SET() bfin_read32(PORTA_POL_SET) -#define bfin_write_PORTA_POL_SET(val) bfin_write32(PORTA_POL_SET, val) -#define bfin_read_PORTA_POL_CLEAR() bfin_read32(PORTA_POL_CLEAR) -#define bfin_write_PORTA_POL_CLEAR(val) bfin_write32(PORTA_POL_CLEAR, val) -#define bfin_read_PORTA_LOCK() bfin_read32(PORTA_LOCK) -#define bfin_write_PORTA_LOCK(val) bfin_write32(PORTA_LOCK, val) -#define bfin_read_PORTA_REVID() bfin_read32(PORTA_REVID) -#define bfin_write_PORTA_REVID(val) bfin_write32(PORTA_REVID, val) - - - -/* Port B Registers */ -#define bfin_read_PORTB_FER() bfin_read32(PORTB_FER) -#define bfin_write_PORTB_FER(val) bfin_write32(PORTB_FER, val) -#define bfin_read_PORTB_FER_SET() bfin_read32(PORTB_FER_SET) -#define bfin_write_PORTB_FER_SET(val) bfin_write32(PORTB_FER_SET, val) -#define bfin_read_PORTB_FER_CLEAR() bfin_read32(PORTB_FER_CLEAR) -#define bfin_write_PORTB_FER_CLEAR(val) bfin_write32(PORTB_FER_CLEAR, val) -#define bfin_read_PORTB() bfin_read32(PORTB) -#define bfin_write_PORTB(val) bfin_write32(PORTB, val) -#define bfin_read_PORTB_SET() bfin_read32(PORTB_SET) -#define bfin_write_PORTB_SET(val) bfin_write32(PORTB_SET, val) -#define bfin_read_PORTB_CLEAR() bfin_read32(PORTB_CLEAR) -#define bfin_write_PORTB_CLEAR(val) bfin_write32(PORTB_CLEAR, val) -#define bfin_read_PORTB_DIR() bfin_read32(PORTB_DIR) -#define bfin_write_PORTB_DIR(val) bfin_write32(PORTB_DIR, val) -#define bfin_read_PORTB_DIR_SET() bfin_read32(PORTB_DIR_SET) -#define bfin_write_PORTB_DIR_SET(val) bfin_write32(PORTB_DIR_SET, val) -#define bfin_read_PORTB_DIR_CLEAR() bfin_read32(PORTB_DIR_CLEAR) -#define bfin_write_PORTB_DIR_CLEAR(val) bfin_write32(PORTB_DIR_CLEAR, val) -#define bfin_read_PORTB_INEN() bfin_read32(PORTB_INEN) -#define bfin_write_PORTB_INEN(val) bfin_write32(PORTB_INEN, val) -#define bfin_read_PORTB_INEN_SET() bfin_read32(PORTB_INEN_SET) -#define bfin_write_PORTB_INEN_SET(val) bfin_write32(PORTB_INEN_SET, val) -#define bfin_read_PORTB_INEN_CLEAR() bfin_read32(PORTB_INEN_CLEAR) -#define bfin_write_PORTB_INEN_CLEAR(val) bfin_write32(PORTB_INEN_CLEAR, val) -#define bfin_read_PORTB_MUX() bfin_read32(PORTB_MUX) -#define bfin_write_PORTB_MUX(val) bfin_write32(PORTB_MUX, val) -#define bfin_read_PORTB_DATA_TGL() bfin_read32(PORTB_DATA_TGL) -#define bfin_write_PORTB_DATA_TGL(val) bfin_write32(PORTB_DATA_TGL, val) -#define bfin_read_PORTB_POL() bfin_read32(PORTB_POL) -#define bfin_write_PORTB_POL(val) bfin_write32(PORTB_POL, val) -#define bfin_read_PORTB_POL_SET() bfin_read32(PORTB_POL_SET) -#define bfin_write_PORTB_POL_SET(val) bfin_write32(PORTB_POL_SET, val) -#define bfin_read_PORTB_POL_CLEAR() bfin_read32(PORTB_POL_CLEAR) -#define bfin_write_PORTB_POL_CLEAR(val) bfin_write32(PORTB_POL_CLEAR, val) -#define bfin_read_PORTB_LOCK() bfin_read32(PORTB_LOCK) -#define bfin_write_PORTB_LOCK(val) bfin_write32(PORTB_LOCK, val) -#define bfin_read_PORTB_REVID() bfin_read32(PORTB_REVID) -#define bfin_write_PORTB_REVID(val) bfin_write32(PORTB_REVID, val) - - -/* Port C Registers */ -#define bfin_read_PORTC_FER() bfin_read32(PORTC_FER) -#define bfin_write_PORTC_FER(val) bfin_write32(PORTC_FER, val) -#define bfin_read_PORTC_FER_SET() bfin_read32(PORTC_FER_SET) -#define bfin_write_PORTC_FER_SET(val) bfin_write32(PORTC_FER_SET, val) -#define bfin_read_PORTC_FER_CLEAR() bfin_read32(PORTC_FER_CLEAR) -#define bfin_write_PORTC_FER_CLEAR(val) bfin_write32(PORTC_FER_CLEAR, val) -#define bfin_read_PORTC() bfin_read32(PORTC) -#define bfin_write_PORTC(val) bfin_write32(PORTC, val) -#define bfin_read_PORTC_SET() bfin_read32(PORTC_SET) -#define bfin_write_PORTC_SET(val) bfin_write32(PORTC_SET, val) -#define bfin_read_PORTC_CLEAR() bfin_read32(PORTC_CLEAR) -#define bfin_write_PORTC_CLEAR(val) bfin_write32(PORTC_CLEAR, val) -#define bfin_read_PORTC_DIR() bfin_read32(PORTC_DIR) -#define bfin_write_PORTC_DIR(val) bfin_write32(PORTC_DIR, val) -#define bfin_read_PORTC_DIR_SET() bfin_read32(PORTC_DIR_SET) -#define bfin_write_PORTC_DIR_SET(val) bfin_write32(PORTC_DIR_SET, val) -#define bfin_read_PORTC_DIR_CLEAR() bfin_read32(PORTC_DIR_CLEAR) -#define bfin_write_PORTC_DIR_CLEAR(val) bfin_write32(PORTC_DIR_CLEAR, val) -#define bfin_read_PORTC_INEN() bfin_read32(PORTC_INEN) -#define bfin_write_PORTC_INEN(val) bfin_write32(PORTC_INEN, val) -#define bfin_read_PORTC_INEN_SET() bfin_read32(PORTC_INEN_SET) -#define bfin_write_PORTC_INEN_SET(val) bfin_write32(PORTC_INEN_SET, val) -#define bfin_read_PORTC_INEN_CLEAR() bfin_read32(PORTC_INEN_CLEAR) -#define bfin_write_PORTC_INEN_CLEAR(val) bfin_write32(PORTC_INEN_CLEAR, val) -#define bfin_read_PORTC_MUX() bfin_read32(PORTC_MUX) -#define bfin_write_PORTC_MUX(val) bfin_write32(PORTC_MUX, val) -#define bfin_read_PORTC_DATA_TGL() bfin_read32(PORTC_DATA_TGL) -#define bfin_write_PORTC_DATA_TGL(val) bfin_write32(PORTC_DATA_TGL, val) -#define bfin_read_PORTC_POL() bfin_read32(PORTC_POL) -#define bfin_write_PORTC_POL(val) bfin_write32(PORTC_POL, val) -#define bfin_read_PORTC_POL_SET() bfin_read32(PORTC_POL_SET) -#define bfin_write_PORTC_POL_SET(val) bfin_write32(PORTC_POL_SET, val) -#define bfin_read_PORTC_POL_CLEAR() bfin_read32(PORTC_POL_CLEAR) -#define bfin_write_PORTC_POL_CLEAR(val) bfin_write32(PORTC_POL_CLEAR, val) -#define bfin_read_PORTC_LOCK() bfin_read32(PORTC_LOCK) -#define bfin_write_PORTC_LOCK(val) bfin_write32(PORTC_LOCK, val) -#define bfin_read_PORTC_REVID() bfin_read32(PORTC_REVID) -#define bfin_write_PORTC_REVID(val) bfin_write32(PORTC_REVID, val) - - -/* Port D Registers */ -#define bfin_read_PORTD_FER() bfin_read32(PORTD_FER) -#define bfin_write_PORTD_FER(val) bfin_write32(PORTD_FER, val) -#define bfin_read_PORTD_FER_SET() bfin_read32(PORTD_FER_SET) -#define bfin_write_PORTD_FER_SET(val) bfin_write32(PORTD_FER_SET, val) -#define bfin_read_PORTD_FER_CLEAR() bfin_read32(PORTD_FER_CLEAR) -#define bfin_write_PORTD_FER_CLEAR(val) bfin_write32(PORTD_FER_CLEAR, val) -#define bfin_read_PORTD() bfin_read32(PORTD) -#define bfin_write_PORTD(val) bfin_write32(PORTD, val) -#define bfin_read_PORTD_SET() bfin_read32(PORTD_SET) -#define bfin_write_PORTD_SET(val) bfin_write32(PORTD_SET, val) -#define bfin_read_PORTD_CLEAR() bfin_read32(PORTD_CLEAR) -#define bfin_write_PORTD_CLEAR(val) bfin_write32(PORTD_CLEAR, val) -#define bfin_read_PORTD_DIR() bfin_read32(PORTD_DIR) -#define bfin_write_PORTD_DIR(val) bfin_write32(PORTD_DIR, val) -#define bfin_read_PORTD_DIR_SET() bfin_read32(PORTD_DIR_SET) -#define bfin_write_PORTD_DIR_SET(val) bfin_write32(PORTD_DIR_SET, val) -#define bfin_read_PORTD_DIR_CLEAR() bfin_read32(PORTD_DIR_CLEAR) -#define bfin_write_PORTD_DIR_CLEAR(val) bfin_write32(PORTD_DIR_CLEAR, val) -#define bfin_read_PORTD_INEN() bfin_read32(PORTD_INEN) -#define bfin_write_PORTD_INEN(val) bfin_write32(PORTD_INEN, val) -#define bfin_read_PORTD_INEN_SET() bfin_read32(PORTD_INEN_SET) -#define bfin_write_PORTD_INEN_SET(val) bfin_write32(PORTD_INEN_SET, val) -#define bfin_read_PORTD_INEN_CLEAR() bfin_read32(PORTD_INEN_CLEAR) -#define bfin_write_PORTD_INEN_CLEAR(val) bfin_write32(PORTD_INEN_CLEAR, val) -#define bfin_read_PORTD_MUX() bfin_read32(PORTD_MUX) -#define bfin_write_PORTD_MUX(val) bfin_write32(PORTD_MUX, val) -#define bfin_read_PORTD_DATA_TGL() bfin_read32(PORTD_DATA_TGL) -#define bfin_write_PORTD_DATA_TGL(val) bfin_write32(PORTD_DATA_TGL, val) -#define bfin_read_PORTD_POL() bfin_read32(PORTD_POL) -#define bfin_write_PORTD_POL(val) bfin_write32(PORTD_POL, val) -#define bfin_read_PORTD_POL_SET() bfin_read32(PORTD_POL_SET) -#define bfin_write_PORTD_POL_SET(val) bfin_write32(PORTD_POL_SET, val) -#define bfin_read_PORTD_POL_CLEAR() bfin_read32(PORTD_POL_CLEAR) -#define bfin_write_PORTD_POL_CLEAR(val) bfin_write32(PORTD_POL_CLEAR, val) -#define bfin_read_PORTD_LOCK() bfin_read32(PORTD_LOCK) -#define bfin_write_PORTD_LOCK(val) bfin_write32(PORTD_LOCK, val) -#define bfin_read_PORTD_REVID() bfin_read32(PORTD_REVID) -#define bfin_write_PORTD_REVID(val) bfin_write32(PORTD_REVID, val) - - -/* Port E Registers */ -#define bfin_read_PORTE_FER() bfin_read32(PORTE_FER) -#define bfin_write_PORTE_FER(val) bfin_write32(PORTE_FER, val) -#define bfin_read_PORTE_FER_SET() bfin_read32(PORTE_FER_SET) -#define bfin_write_PORTE_FER_SET(val) bfin_write32(PORTE_FER_SET, val) -#define bfin_read_PORTE_FER_CLEAR() bfin_read32(PORTE_FER_CLEAR) -#define bfin_write_PORTE_FER_CLEAR(val) bfin_write32(PORTE_FER_CLEAR, val) -#define bfin_read_PORTE() bfin_read32(PORTE) -#define bfin_write_PORTE(val) bfin_write32(PORTE, val) -#define bfin_read_PORTE_SET() bfin_read32(PORTE_SET) -#define bfin_write_PORTE_SET(val) bfin_write32(PORTE_SET, val) -#define bfin_read_PORTE_CLEAR() bfin_read32(PORTE_CLEAR) -#define bfin_write_PORTE_CLEAR(val) bfin_write32(PORTE_CLEAR, val) -#define bfin_read_PORTE_DIR() bfin_read32(PORTE_DIR) -#define bfin_write_PORTE_DIR(val) bfin_write32(PORTE_DIR, val) -#define bfin_read_PORTE_DIR_SET() bfin_read32(PORTE_DIR_SET) -#define bfin_write_PORTE_DIR_SET(val) bfin_write32(PORTE_DIR_SET, val) -#define bfin_read_PORTE_DIR_CLEAR() bfin_read32(PORTE_DIR_CLEAR) -#define bfin_write_PORTE_DIR_CLEAR(val) bfin_write32(PORTE_DIR_CLEAR, val) -#define bfin_read_PORTE_INEN() bfin_read32(PORTE_INEN) -#define bfin_write_PORTE_INEN(val) bfin_write32(PORTE_INEN, val) -#define bfin_read_PORTE_INEN_SET() bfin_read32(PORTE_INEN_SET) -#define bfin_write_PORTE_INEN_SET(val) bfin_write32(PORTE_INEN_SET, val) -#define bfin_read_PORTE_INEN_CLEAR() bfin_read32(PORTE_INEN_CLEAR) -#define bfin_write_PORTE_INEN_CLEAR(val) bfin_write32(PORTE_INEN_CLEAR, val) -#define bfin_read_PORTE_MUX() bfin_read32(PORTE_MUX) -#define bfin_write_PORTE_MUX(val) bfin_write32(PORTE_MUX, val) -#define bfin_read_PORTE_DATA_TGL() bfin_read32(PORTE_DATA_TGL) -#define bfin_write_PORTE_DATA_TGL(val) bfin_write32(PORTE_DATA_TGL, val) -#define bfin_read_PORTE_POL() bfin_read32(PORTE_POL) -#define bfin_write_PORTE_POL(val) bfin_write32(PORTE_POL, val) -#define bfin_read_PORTE_POL_SET() bfin_read32(PORTE_POL_SET) -#define bfin_write_PORTE_POL_SET(val) bfin_write32(PORTE_POL_SET, val) -#define bfin_read_PORTE_POL_CLEAR() bfin_read32(PORTE_POL_CLEAR) -#define bfin_write_PORTE_POL_CLEAR(val) bfin_write32(PORTE_POL_CLEAR, val) -#define bfin_read_PORTE_LOCK() bfin_read32(PORTE_LOCK) -#define bfin_write_PORTE_LOCK(val) bfin_write32(PORTE_LOCK, val) -#define bfin_read_PORTE_REVID() bfin_read32(PORTE_REVID) -#define bfin_write_PORTE_REVID(val) bfin_write32(PORTE_REVID, val) - - -/* Port F Registers */ -#define bfin_read_PORTF_FER() bfin_read32(PORTF_FER) -#define bfin_write_PORTF_FER(val) bfin_write32(PORTF_FER, val) -#define bfin_read_PORTF_FER_SET() bfin_read32(PORTF_FER_SET) -#define bfin_write_PORTF_FER_SET(val) bfin_write32(PORTF_FER_SET, val) -#define bfin_read_PORTF_FER_CLEAR() bfin_read32(PORTF_FER_CLEAR) -#define bfin_write_PORTF_FER_CLEAR(val) bfin_write32(PORTF_FER_CLEAR, val) -#define bfin_read_PORTF() bfin_read32(PORTF) -#define bfin_write_PORTF(val) bfin_write32(PORTF, val) -#define bfin_read_PORTF_SET() bfin_read32(PORTF_SET) -#define bfin_write_PORTF_SET(val) bfin_write32(PORTF_SET, val) -#define bfin_read_PORTF_CLEAR() bfin_read32(PORTF_CLEAR) -#define bfin_write_PORTF_CLEAR(val) bfin_write32(PORTF_CLEAR, val) -#define bfin_read_PORTF_DIR() bfin_read32(PORTF_DIR) -#define bfin_write_PORTF_DIR(val) bfin_write32(PORTF_DIR, val) -#define bfin_read_PORTF_DIR_SET() bfin_read32(PORTF_DIR_SET) -#define bfin_write_PORTF_DIR_SET(val) bfin_write32(PORTF_DIR_SET, val) -#define bfin_read_PORTF_DIR_CLEAR() bfin_read32(PORTF_DIR_CLEAR) -#define bfin_write_PORTF_DIR_CLEAR(val) bfin_write32(PORTF_DIR_CLEAR, val) -#define bfin_read_PORTF_INEN() bfin_read32(PORTF_INEN) -#define bfin_write_PORTF_INEN(val) bfin_write32(PORTF_INEN, val) -#define bfin_read_PORTF_INEN_SET() bfin_read32(PORTF_INEN_SET) -#define bfin_write_PORTF_INEN_SET(val) bfin_write32(PORTF_INEN_SET, val) -#define bfin_read_PORTF_INEN_CLEAR() bfin_read32(PORTF_INEN_CLEAR) -#define bfin_write_PORTF_INEN_CLEAR(val) bfin_write32(PORTF_INEN_CLEAR, val) -#define bfin_read_PORTF_MUX() bfin_read32(PORTF_MUX) -#define bfin_write_PORTF_MUX(val) bfin_write32(PORTF_MUX, val) -#define bfin_read_PORTF_DATA_TGL() bfin_read32(PORTF_DATA_TGL) -#define bfin_write_PORTF_DATA_TGL(val) bfin_write32(PORTF_DATA_TGL, val) -#define bfin_read_PORTF_POL() bfin_read32(PORTF_POL) -#define bfin_write_PORTF_POL(val) bfin_write32(PORTF_POL, val) -#define bfin_read_PORTF_POL_SET() bfin_read32(PORTF_POL_SET) -#define bfin_write_PORTF_POL_SET(val) bfin_write32(PORTF_POL_SET, val) -#define bfin_read_PORTF_POL_CLEAR() bfin_read32(PORTF_POL_CLEAR) -#define bfin_write_PORTF_POL_CLEAR(val) bfin_write32(PORTF_POL_CLEAR, val) -#define bfin_read_PORTF_LOCK() bfin_read32(PORTF_LOCK) -#define bfin_write_PORTF_LOCK(val) bfin_write32(PORTF_LOCK, val) -#define bfin_read_PORTF_REVID() bfin_read32(PORTF_REVID) -#define bfin_write_PORTF_REVID(val) bfin_write32(PORTF_REVID, val) - - -/* Port G Registers */ -#define bfin_read_PORTG_FER() bfin_read32(PORTG_FER) -#define bfin_write_PORTG_FER(val) bfin_write32(PORTG_FER, val) -#define bfin_read_PORTG_FER_SET() bfin_read32(PORTG_FER_SET) -#define bfin_write_PORTG_FER_SET(val) bfin_write32(PORTG_FER_SET, val) -#define bfin_read_PORTG_FER_CLEAR() bfin_read32(PORTG_FER_CLEAR) -#define bfin_write_PORTG_FER_CLEAR(val) bfin_write32(PORTG_FER_CLEAR, val) -#define bfin_read_PORTG() bfin_read32(PORTG) -#define bfin_write_PORTG(val) bfin_write32(PORTG, val) -#define bfin_read_PORTG_SET() bfin_read32(PORTG_SET) -#define bfin_write_PORTG_SET(val) bfin_write32(PORTG_SET, val) -#define bfin_read_PORTG_CLEAR() bfin_read32(PORTG_CLEAR) -#define bfin_write_PORTG_CLEAR(val) bfin_write32(PORTG_CLEAR, val) -#define bfin_read_PORTG_DIR() bfin_read32(PORTG_DIR) -#define bfin_write_PORTG_DIR(val) bfin_write32(PORTG_DIR, val) -#define bfin_read_PORTG_DIR_SET() bfin_read32(PORTG_DIR_SET) -#define bfin_write_PORTG_DIR_SET(val) bfin_write32(PORTG_DIR_SET, val) -#define bfin_read_PORTG_DIR_CLEAR() bfin_read32(PORTG_DIR_CLEAR) -#define bfin_write_PORTG_DIR_CLEAR(val) bfin_write32(PORTG_DIR_CLEAR, val) -#define bfin_read_PORTG_INEN() bfin_read32(PORTG_INEN) -#define bfin_write_PORTG_INEN(val) bfin_write32(PORTG_INEN, val) -#define bfin_read_PORTG_INEN_SET() bfin_read32(PORTG_INEN_SET) -#define bfin_write_PORTG_INEN_SET(val) bfin_write32(PORTG_INEN_SET, val) -#define bfin_read_PORTG_INEN_CLEAR() bfin_read32(PORTG_INEN_CLEAR) -#define bfin_write_PORTG_INEN_CLEAR(val) bfin_write32(PORTG_INEN_CLEAR, val) -#define bfin_read_PORTG_MUX() bfin_read32(PORTG_MUX) -#define bfin_write_PORTG_MUX(val) bfin_write32(PORTG_MUX, val) -#define bfin_read_PORTG_DATA_TGL() bfin_read32(PORTG_DATA_TGL) -#define bfin_write_PORTG_DATA_TGL(val) bfin_write32(PORTG_DATA_TGL, val) -#define bfin_read_PORTG_POL() bfin_read32(PORTG_POL) -#define bfin_write_PORTG_POL(val) bfin_write32(PORTG_POL, val) -#define bfin_read_PORTG_POL_SET() bfin_read32(PORTG_POL_SET) -#define bfin_write_PORTG_POL_SET(val) bfin_write32(PORTG_POL_SET, val) -#define bfin_read_PORTG_POL_CLEAR() bfin_read32(PORTG_POL_CLEAR) -#define bfin_write_PORTG_POL_CLEAR(val) bfin_write32(PORTG_POL_CLEAR, val) -#define bfin_read_PORTG_LOCK() bfin_read32(PORTG_LOCK) -#define bfin_write_PORTG_LOCK(val) bfin_write32(PORTG_LOCK, val) -#define bfin_read_PORTG_REVID() bfin_read32(PORTG_REVID) -#define bfin_write_PORTG_REVID(val) bfin_write32(PORTG_REVID, val) - - - - -/* CAN Controller 0 Config 1 Registers */ - -#define bfin_read_CAN0_MC1() bfin_read16(CAN0_MC1) -#define bfin_write_CAN0_MC1(val) bfin_write16(CAN0_MC1, val) -#define bfin_read_CAN0_MD1() bfin_read16(CAN0_MD1) -#define bfin_write_CAN0_MD1(val) bfin_write16(CAN0_MD1, val) -#define bfin_read_CAN0_TRS1() bfin_read16(CAN0_TRS1) -#define bfin_write_CAN0_TRS1(val) bfin_write16(CAN0_TRS1, val) -#define bfin_read_CAN0_TRR1() bfin_read16(CAN0_TRR1) -#define bfin_write_CAN0_TRR1(val) bfin_write16(CAN0_TRR1, val) -#define bfin_read_CAN0_TA1() bfin_read16(CAN0_TA1) -#define bfin_write_CAN0_TA1(val) bfin_write16(CAN0_TA1, val) -#define bfin_read_CAN0_AA1() bfin_read16(CAN0_AA1) -#define bfin_write_CAN0_AA1(val) bfin_write16(CAN0_AA1, val) -#define bfin_read_CAN0_RMP1() bfin_read16(CAN0_RMP1) -#define bfin_write_CAN0_RMP1(val) bfin_write16(CAN0_RMP1, val) -#define bfin_read_CAN0_RML1() bfin_read16(CAN0_RML1) -#define bfin_write_CAN0_RML1(val) bfin_write16(CAN0_RML1, val) -#define bfin_read_CAN0_MBTIF1() bfin_read16(CAN0_MBTIF1) -#define bfin_write_CAN0_MBTIF1(val) bfin_write16(CAN0_MBTIF1, val) -#define bfin_read_CAN0_MBRIF1() bfin_read16(CAN0_MBRIF1) -#define bfin_write_CAN0_MBRIF1(val) bfin_write16(CAN0_MBRIF1, val) -#define bfin_read_CAN0_MBIM1() bfin_read16(CAN0_MBIM1) -#define bfin_write_CAN0_MBIM1(val) bfin_write16(CAN0_MBIM1, val) -#define bfin_read_CAN0_RFH1() bfin_read16(CAN0_RFH1) -#define bfin_write_CAN0_RFH1(val) bfin_write16(CAN0_RFH1, val) -#define bfin_read_CAN0_OPSS1() bfin_read16(CAN0_OPSS1) -#define bfin_write_CAN0_OPSS1(val) bfin_write16(CAN0_OPSS1, val) - -/* CAN Controller 0 Config 2 Registers */ - -#define bfin_read_CAN0_MC2() bfin_read16(CAN0_MC2) -#define bfin_write_CAN0_MC2(val) bfin_write16(CAN0_MC2, val) -#define bfin_read_CAN0_MD2() bfin_read16(CAN0_MD2) -#define bfin_write_CAN0_MD2(val) bfin_write16(CAN0_MD2, val) -#define bfin_read_CAN0_TRS2() bfin_read16(CAN0_TRS2) -#define bfin_write_CAN0_TRS2(val) bfin_write16(CAN0_TRS2, val) -#define bfin_read_CAN0_TRR2() bfin_read16(CAN0_TRR2) -#define bfin_write_CAN0_TRR2(val) bfin_write16(CAN0_TRR2, val) -#define bfin_read_CAN0_TA2() bfin_read16(CAN0_TA2) -#define bfin_write_CAN0_TA2(val) bfin_write16(CAN0_TA2, val) -#define bfin_read_CAN0_AA2() bfin_read16(CAN0_AA2) -#define bfin_write_CAN0_AA2(val) bfin_write16(CAN0_AA2, val) -#define bfin_read_CAN0_RMP2() bfin_read16(CAN0_RMP2) -#define bfin_write_CAN0_RMP2(val) bfin_write16(CAN0_RMP2, val) -#define bfin_read_CAN0_RML2() bfin_read16(CAN0_RML2) -#define bfin_write_CAN0_RML2(val) bfin_write16(CAN0_RML2, val) -#define bfin_read_CAN0_MBTIF2() bfin_read16(CAN0_MBTIF2) -#define bfin_write_CAN0_MBTIF2(val) bfin_write16(CAN0_MBTIF2, val) -#define bfin_read_CAN0_MBRIF2() bfin_read16(CAN0_MBRIF2) -#define bfin_write_CAN0_MBRIF2(val) bfin_write16(CAN0_MBRIF2, val) -#define bfin_read_CAN0_MBIM2() bfin_read16(CAN0_MBIM2) -#define bfin_write_CAN0_MBIM2(val) bfin_write16(CAN0_MBIM2, val) -#define bfin_read_CAN0_RFH2() bfin_read16(CAN0_RFH2) -#define bfin_write_CAN0_RFH2(val) bfin_write16(CAN0_RFH2, val) -#define bfin_read_CAN0_OPSS2() bfin_read16(CAN0_OPSS2) -#define bfin_write_CAN0_OPSS2(val) bfin_write16(CAN0_OPSS2, val) - -/* CAN Controller 0 Clock/Interrubfin_read_()t/Counter Registers */ - -#define bfin_read_CAN0_CLOCK() bfin_read16(CAN0_CLOCK) -#define bfin_write_CAN0_CLOCK(val) bfin_write16(CAN0_CLOCK, val) -#define bfin_read_CAN0_TIMING() bfin_read16(CAN0_TIMING) -#define bfin_write_CAN0_TIMING(val) bfin_write16(CAN0_TIMING, val) -#define bfin_read_CAN0_DEBUG() bfin_read16(CAN0_DEBUG) -#define bfin_write_CAN0_DEBUG(val) bfin_write16(CAN0_DEBUG, val) -#define bfin_read_CAN0_STATUS() bfin_read16(CAN0_STATUS) -#define bfin_write_CAN0_STATUS(val) bfin_write16(CAN0_STATUS, val) -#define bfin_read_CAN0_CEC() bfin_read16(CAN0_CEC) -#define bfin_write_CAN0_CEC(val) bfin_write16(CAN0_CEC, val) -#define bfin_read_CAN0_GIS() bfin_read16(CAN0_GIS) -#define bfin_write_CAN0_GIS(val) bfin_write16(CAN0_GIS, val) -#define bfin_read_CAN0_GIM() bfin_read16(CAN0_GIM) -#define bfin_write_CAN0_GIM(val) bfin_write16(CAN0_GIM, val) -#define bfin_read_CAN0_GIF() bfin_read16(CAN0_GIF) -#define bfin_write_CAN0_GIF(val) bfin_write16(CAN0_GIF, val) -#define bfin_read_CAN0_CONTROL() bfin_read16(CAN0_CONTROL) -#define bfin_write_CAN0_CONTROL(val) bfin_write16(CAN0_CONTROL, val) -#define bfin_read_CAN0_INTR() bfin_read16(CAN0_INTR) -#define bfin_write_CAN0_INTR(val) bfin_write16(CAN0_INTR, val) -#define bfin_read_CAN0_MBTD() bfin_read16(CAN0_MBTD) -#define bfin_write_CAN0_MBTD(val) bfin_write16(CAN0_MBTD, val) -#define bfin_read_CAN0_EWR() bfin_read16(CAN0_EWR) -#define bfin_write_CAN0_EWR(val) bfin_write16(CAN0_EWR, val) -#define bfin_read_CAN0_ESR() bfin_read16(CAN0_ESR) -#define bfin_write_CAN0_ESR(val) bfin_write16(CAN0_ESR, val) -#define bfin_read_CAN0_UCCNT() bfin_read16(CAN0_UCCNT) -#define bfin_write_CAN0_UCCNT(val) bfin_write16(CAN0_UCCNT, val) -#define bfin_read_CAN0_UCRC() bfin_read16(CAN0_UCRC) -#define bfin_write_CAN0_UCRC(val) bfin_write16(CAN0_UCRC, val) -#define bfin_read_CAN0_UCCNF() bfin_read16(CAN0_UCCNF) -#define bfin_write_CAN0_UCCNF(val) bfin_write16(CAN0_UCCNF, val) - -/* CAN Controller 0 Accebfin_read_()tance Registers */ - -#define bfin_read_CAN0_AM00L() bfin_read16(CAN0_AM00L) -#define bfin_write_CAN0_AM00L(val) bfin_write16(CAN0_AM00L, val) -#define bfin_read_CAN0_AM00H() bfin_read16(CAN0_AM00H) -#define bfin_write_CAN0_AM00H(val) bfin_write16(CAN0_AM00H, val) -#define bfin_read_CAN0_AM01L() bfin_read16(CAN0_AM01L) -#define bfin_write_CAN0_AM01L(val) bfin_write16(CAN0_AM01L, val) -#define bfin_read_CAN0_AM01H() bfin_read16(CAN0_AM01H) -#define bfin_write_CAN0_AM01H(val) bfin_write16(CAN0_AM01H, val) -#define bfin_read_CAN0_AM02L() bfin_read16(CAN0_AM02L) -#define bfin_write_CAN0_AM02L(val) bfin_write16(CAN0_AM02L, val) -#define bfin_read_CAN0_AM02H() bfin_read16(CAN0_AM02H) -#define bfin_write_CAN0_AM02H(val) bfin_write16(CAN0_AM02H, val) -#define bfin_read_CAN0_AM03L() bfin_read16(CAN0_AM03L) -#define bfin_write_CAN0_AM03L(val) bfin_write16(CAN0_AM03L, val) -#define bfin_read_CAN0_AM03H() bfin_read16(CAN0_AM03H) -#define bfin_write_CAN0_AM03H(val) bfin_write16(CAN0_AM03H, val) -#define bfin_read_CAN0_AM04L() bfin_read16(CAN0_AM04L) -#define bfin_write_CAN0_AM04L(val) bfin_write16(CAN0_AM04L, val) -#define bfin_read_CAN0_AM04H() bfin_read16(CAN0_AM04H) -#define bfin_write_CAN0_AM04H(val) bfin_write16(CAN0_AM04H, val) -#define bfin_read_CAN0_AM05L() bfin_read16(CAN0_AM05L) -#define bfin_write_CAN0_AM05L(val) bfin_write16(CAN0_AM05L, val) -#define bfin_read_CAN0_AM05H() bfin_read16(CAN0_AM05H) -#define bfin_write_CAN0_AM05H(val) bfin_write16(CAN0_AM05H, val) -#define bfin_read_CAN0_AM06L() bfin_read16(CAN0_AM06L) -#define bfin_write_CAN0_AM06L(val) bfin_write16(CAN0_AM06L, val) -#define bfin_read_CAN0_AM06H() bfin_read16(CAN0_AM06H) -#define bfin_write_CAN0_AM06H(val) bfin_write16(CAN0_AM06H, val) -#define bfin_read_CAN0_AM07L() bfin_read16(CAN0_AM07L) -#define bfin_write_CAN0_AM07L(val) bfin_write16(CAN0_AM07L, val) -#define bfin_read_CAN0_AM07H() bfin_read16(CAN0_AM07H) -#define bfin_write_CAN0_AM07H(val) bfin_write16(CAN0_AM07H, val) -#define bfin_read_CAN0_AM08L() bfin_read16(CAN0_AM08L) -#define bfin_write_CAN0_AM08L(val) bfin_write16(CAN0_AM08L, val) -#define bfin_read_CAN0_AM08H() bfin_read16(CAN0_AM08H) -#define bfin_write_CAN0_AM08H(val) bfin_write16(CAN0_AM08H, val) -#define bfin_read_CAN0_AM09L() bfin_read16(CAN0_AM09L) -#define bfin_write_CAN0_AM09L(val) bfin_write16(CAN0_AM09L, val) -#define bfin_read_CAN0_AM09H() bfin_read16(CAN0_AM09H) -#define bfin_write_CAN0_AM09H(val) bfin_write16(CAN0_AM09H, val) -#define bfin_read_CAN0_AM10L() bfin_read16(CAN0_AM10L) -#define bfin_write_CAN0_AM10L(val) bfin_write16(CAN0_AM10L, val) -#define bfin_read_CAN0_AM10H() bfin_read16(CAN0_AM10H) -#define bfin_write_CAN0_AM10H(val) bfin_write16(CAN0_AM10H, val) -#define bfin_read_CAN0_AM11L() bfin_read16(CAN0_AM11L) -#define bfin_write_CAN0_AM11L(val) bfin_write16(CAN0_AM11L, val) -#define bfin_read_CAN0_AM11H() bfin_read16(CAN0_AM11H) -#define bfin_write_CAN0_AM11H(val) bfin_write16(CAN0_AM11H, val) -#define bfin_read_CAN0_AM12L() bfin_read16(CAN0_AM12L) -#define bfin_write_CAN0_AM12L(val) bfin_write16(CAN0_AM12L, val) -#define bfin_read_CAN0_AM12H() bfin_read16(CAN0_AM12H) -#define bfin_write_CAN0_AM12H(val) bfin_write16(CAN0_AM12H, val) -#define bfin_read_CAN0_AM13L() bfin_read16(CAN0_AM13L) -#define bfin_write_CAN0_AM13L(val) bfin_write16(CAN0_AM13L, val) -#define bfin_read_CAN0_AM13H() bfin_read16(CAN0_AM13H) -#define bfin_write_CAN0_AM13H(val) bfin_write16(CAN0_AM13H, val) -#define bfin_read_CAN0_AM14L() bfin_read16(CAN0_AM14L) -#define bfin_write_CAN0_AM14L(val) bfin_write16(CAN0_AM14L, val) -#define bfin_read_CAN0_AM14H() bfin_read16(CAN0_AM14H) -#define bfin_write_CAN0_AM14H(val) bfin_write16(CAN0_AM14H, val) -#define bfin_read_CAN0_AM15L() bfin_read16(CAN0_AM15L) -#define bfin_write_CAN0_AM15L(val) bfin_write16(CAN0_AM15L, val) -#define bfin_read_CAN0_AM15H() bfin_read16(CAN0_AM15H) -#define bfin_write_CAN0_AM15H(val) bfin_write16(CAN0_AM15H, val) - -/* CAN Controller 0 Accebfin_read_()tance Registers */ - -#define bfin_read_CAN0_AM16L() bfin_read16(CAN0_AM16L) -#define bfin_write_CAN0_AM16L(val) bfin_write16(CAN0_AM16L, val) -#define bfin_read_CAN0_AM16H() bfin_read16(CAN0_AM16H) -#define bfin_write_CAN0_AM16H(val) bfin_write16(CAN0_AM16H, val) -#define bfin_read_CAN0_AM17L() bfin_read16(CAN0_AM17L) -#define bfin_write_CAN0_AM17L(val) bfin_write16(CAN0_AM17L, val) -#define bfin_read_CAN0_AM17H() bfin_read16(CAN0_AM17H) -#define bfin_write_CAN0_AM17H(val) bfin_write16(CAN0_AM17H, val) -#define bfin_read_CAN0_AM18L() bfin_read16(CAN0_AM18L) -#define bfin_write_CAN0_AM18L(val) bfin_write16(CAN0_AM18L, val) -#define bfin_read_CAN0_AM18H() bfin_read16(CAN0_AM18H) -#define bfin_write_CAN0_AM18H(val) bfin_write16(CAN0_AM18H, val) -#define bfin_read_CAN0_AM19L() bfin_read16(CAN0_AM19L) -#define bfin_write_CAN0_AM19L(val) bfin_write16(CAN0_AM19L, val) -#define bfin_read_CAN0_AM19H() bfin_read16(CAN0_AM19H) -#define bfin_write_CAN0_AM19H(val) bfin_write16(CAN0_AM19H, val) -#define bfin_read_CAN0_AM20L() bfin_read16(CAN0_AM20L) -#define bfin_write_CAN0_AM20L(val) bfin_write16(CAN0_AM20L, val) -#define bfin_read_CAN0_AM20H() bfin_read16(CAN0_AM20H) -#define bfin_write_CAN0_AM20H(val) bfin_write16(CAN0_AM20H, val) -#define bfin_read_CAN0_AM21L() bfin_read16(CAN0_AM21L) -#define bfin_write_CAN0_AM21L(val) bfin_write16(CAN0_AM21L, val) -#define bfin_read_CAN0_AM21H() bfin_read16(CAN0_AM21H) -#define bfin_write_CAN0_AM21H(val) bfin_write16(CAN0_AM21H, val) -#define bfin_read_CAN0_AM22L() bfin_read16(CAN0_AM22L) -#define bfin_write_CAN0_AM22L(val) bfin_write16(CAN0_AM22L, val) -#define bfin_read_CAN0_AM22H() bfin_read16(CAN0_AM22H) -#define bfin_write_CAN0_AM22H(val) bfin_write16(CAN0_AM22H, val) -#define bfin_read_CAN0_AM23L() bfin_read16(CAN0_AM23L) -#define bfin_write_CAN0_AM23L(val) bfin_write16(CAN0_AM23L, val) -#define bfin_read_CAN0_AM23H() bfin_read16(CAN0_AM23H) -#define bfin_write_CAN0_AM23H(val) bfin_write16(CAN0_AM23H, val) -#define bfin_read_CAN0_AM24L() bfin_read16(CAN0_AM24L) -#define bfin_write_CAN0_AM24L(val) bfin_write16(CAN0_AM24L, val) -#define bfin_read_CAN0_AM24H() bfin_read16(CAN0_AM24H) -#define bfin_write_CAN0_AM24H(val) bfin_write16(CAN0_AM24H, val) -#define bfin_read_CAN0_AM25L() bfin_read16(CAN0_AM25L) -#define bfin_write_CAN0_AM25L(val) bfin_write16(CAN0_AM25L, val) -#define bfin_read_CAN0_AM25H() bfin_read16(CAN0_AM25H) -#define bfin_write_CAN0_AM25H(val) bfin_write16(CAN0_AM25H, val) -#define bfin_read_CAN0_AM26L() bfin_read16(CAN0_AM26L) -#define bfin_write_CAN0_AM26L(val) bfin_write16(CAN0_AM26L, val) -#define bfin_read_CAN0_AM26H() bfin_read16(CAN0_AM26H) -#define bfin_write_CAN0_AM26H(val) bfin_write16(CAN0_AM26H, val) -#define bfin_read_CAN0_AM27L() bfin_read16(CAN0_AM27L) -#define bfin_write_CAN0_AM27L(val) bfin_write16(CAN0_AM27L, val) -#define bfin_read_CAN0_AM27H() bfin_read16(CAN0_AM27H) -#define bfin_write_CAN0_AM27H(val) bfin_write16(CAN0_AM27H, val) -#define bfin_read_CAN0_AM28L() bfin_read16(CAN0_AM28L) -#define bfin_write_CAN0_AM28L(val) bfin_write16(CAN0_AM28L, val) -#define bfin_read_CAN0_AM28H() bfin_read16(CAN0_AM28H) -#define bfin_write_CAN0_AM28H(val) bfin_write16(CAN0_AM28H, val) -#define bfin_read_CAN0_AM29L() bfin_read16(CAN0_AM29L) -#define bfin_write_CAN0_AM29L(val) bfin_write16(CAN0_AM29L, val) -#define bfin_read_CAN0_AM29H() bfin_read16(CAN0_AM29H) -#define bfin_write_CAN0_AM29H(val) bfin_write16(CAN0_AM29H, val) -#define bfin_read_CAN0_AM30L() bfin_read16(CAN0_AM30L) -#define bfin_write_CAN0_AM30L(val) bfin_write16(CAN0_AM30L, val) -#define bfin_read_CAN0_AM30H() bfin_read16(CAN0_AM30H) -#define bfin_write_CAN0_AM30H(val) bfin_write16(CAN0_AM30H, val) -#define bfin_read_CAN0_AM31L() bfin_read16(CAN0_AM31L) -#define bfin_write_CAN0_AM31L(val) bfin_write16(CAN0_AM31L, val) -#define bfin_read_CAN0_AM31H() bfin_read16(CAN0_AM31H) -#define bfin_write_CAN0_AM31H(val) bfin_write16(CAN0_AM31H, val) - -/* CAN Controller 0 Mailbox Data Registers */ - -#define bfin_read_CAN0_MB00_DATA0() bfin_read16(CAN0_MB00_DATA0) -#define bfin_write_CAN0_MB00_DATA0(val) bfin_write16(CAN0_MB00_DATA0, val) -#define bfin_read_CAN0_MB00_DATA1() bfin_read16(CAN0_MB00_DATA1) -#define bfin_write_CAN0_MB00_DATA1(val) bfin_write16(CAN0_MB00_DATA1, val) -#define bfin_read_CAN0_MB00_DATA2() bfin_read16(CAN0_MB00_DATA2) -#define bfin_write_CAN0_MB00_DATA2(val) bfin_write16(CAN0_MB00_DATA2, val) -#define bfin_read_CAN0_MB00_DATA3() bfin_read16(CAN0_MB00_DATA3) -#define bfin_write_CAN0_MB00_DATA3(val) bfin_write16(CAN0_MB00_DATA3, val) -#define bfin_read_CAN0_MB00_LENGTH() bfin_read16(CAN0_MB00_LENGTH) -#define bfin_write_CAN0_MB00_LENGTH(val) bfin_write16(CAN0_MB00_LENGTH, val) -#define bfin_read_CAN0_MB00_TIMESTAMP() bfin_read16(CAN0_MB00_TIMESTAMP) -#define bfin_write_CAN0_MB00_TIMESTAMP(val) bfin_write16(CAN0_MB00_TIMESTAMP, val) -#define bfin_read_CAN0_MB00_ID0() bfin_read16(CAN0_MB00_ID0) -#define bfin_write_CAN0_MB00_ID0(val) bfin_write16(CAN0_MB00_ID0, val) -#define bfin_read_CAN0_MB00_ID1() bfin_read16(CAN0_MB00_ID1) -#define bfin_write_CAN0_MB00_ID1(val) bfin_write16(CAN0_MB00_ID1, val) -#define bfin_read_CAN0_MB01_DATA0() bfin_read16(CAN0_MB01_DATA0) -#define bfin_write_CAN0_MB01_DATA0(val) bfin_write16(CAN0_MB01_DATA0, val) -#define bfin_read_CAN0_MB01_DATA1() bfin_read16(CAN0_MB01_DATA1) -#define bfin_write_CAN0_MB01_DATA1(val) bfin_write16(CAN0_MB01_DATA1, val) -#define bfin_read_CAN0_MB01_DATA2() bfin_read16(CAN0_MB01_DATA2) -#define bfin_write_CAN0_MB01_DATA2(val) bfin_write16(CAN0_MB01_DATA2, val) -#define bfin_read_CAN0_MB01_DATA3() bfin_read16(CAN0_MB01_DATA3) -#define bfin_write_CAN0_MB01_DATA3(val) bfin_write16(CAN0_MB01_DATA3, val) -#define bfin_read_CAN0_MB01_LENGTH() bfin_read16(CAN0_MB01_LENGTH) -#define bfin_write_CAN0_MB01_LENGTH(val) bfin_write16(CAN0_MB01_LENGTH, val) -#define bfin_read_CAN0_MB01_TIMESTAMP() bfin_read16(CAN0_MB01_TIMESTAMP) -#define bfin_write_CAN0_MB01_TIMESTAMP(val) bfin_write16(CAN0_MB01_TIMESTAMP, val) -#define bfin_read_CAN0_MB01_ID0() bfin_read16(CAN0_MB01_ID0) -#define bfin_write_CAN0_MB01_ID0(val) bfin_write16(CAN0_MB01_ID0, val) -#define bfin_read_CAN0_MB01_ID1() bfin_read16(CAN0_MB01_ID1) -#define bfin_write_CAN0_MB01_ID1(val) bfin_write16(CAN0_MB01_ID1, val) -#define bfin_read_CAN0_MB02_DATA0() bfin_read16(CAN0_MB02_DATA0) -#define bfin_write_CAN0_MB02_DATA0(val) bfin_write16(CAN0_MB02_DATA0, val) -#define bfin_read_CAN0_MB02_DATA1() bfin_read16(CAN0_MB02_DATA1) -#define bfin_write_CAN0_MB02_DATA1(val) bfin_write16(CAN0_MB02_DATA1, val) -#define bfin_read_CAN0_MB02_DATA2() bfin_read16(CAN0_MB02_DATA2) -#define bfin_write_CAN0_MB02_DATA2(val) bfin_write16(CAN0_MB02_DATA2, val) -#define bfin_read_CAN0_MB02_DATA3() bfin_read16(CAN0_MB02_DATA3) -#define bfin_write_CAN0_MB02_DATA3(val) bfin_write16(CAN0_MB02_DATA3, val) -#define bfin_read_CAN0_MB02_LENGTH() bfin_read16(CAN0_MB02_LENGTH) -#define bfin_write_CAN0_MB02_LENGTH(val) bfin_write16(CAN0_MB02_LENGTH, val) -#define bfin_read_CAN0_MB02_TIMESTAMP() bfin_read16(CAN0_MB02_TIMESTAMP) -#define bfin_write_CAN0_MB02_TIMESTAMP(val) bfin_write16(CAN0_MB02_TIMESTAMP, val) -#define bfin_read_CAN0_MB02_ID0() bfin_read16(CAN0_MB02_ID0) -#define bfin_write_CAN0_MB02_ID0(val) bfin_write16(CAN0_MB02_ID0, val) -#define bfin_read_CAN0_MB02_ID1() bfin_read16(CAN0_MB02_ID1) -#define bfin_write_CAN0_MB02_ID1(val) bfin_write16(CAN0_MB02_ID1, val) -#define bfin_read_CAN0_MB03_DATA0() bfin_read16(CAN0_MB03_DATA0) -#define bfin_write_CAN0_MB03_DATA0(val) bfin_write16(CAN0_MB03_DATA0, val) -#define bfin_read_CAN0_MB03_DATA1() bfin_read16(CAN0_MB03_DATA1) -#define bfin_write_CAN0_MB03_DATA1(val) bfin_write16(CAN0_MB03_DATA1, val) -#define bfin_read_CAN0_MB03_DATA2() bfin_read16(CAN0_MB03_DATA2) -#define bfin_write_CAN0_MB03_DATA2(val) bfin_write16(CAN0_MB03_DATA2, val) -#define bfin_read_CAN0_MB03_DATA3() bfin_read16(CAN0_MB03_DATA3) -#define bfin_write_CAN0_MB03_DATA3(val) bfin_write16(CAN0_MB03_DATA3, val) -#define bfin_read_CAN0_MB03_LENGTH() bfin_read16(CAN0_MB03_LENGTH) -#define bfin_write_CAN0_MB03_LENGTH(val) bfin_write16(CAN0_MB03_LENGTH, val) -#define bfin_read_CAN0_MB03_TIMESTAMP() bfin_read16(CAN0_MB03_TIMESTAMP) -#define bfin_write_CAN0_MB03_TIMESTAMP(val) bfin_write16(CAN0_MB03_TIMESTAMP, val) -#define bfin_read_CAN0_MB03_ID0() bfin_read16(CAN0_MB03_ID0) -#define bfin_write_CAN0_MB03_ID0(val) bfin_write16(CAN0_MB03_ID0, val) -#define bfin_read_CAN0_MB03_ID1() bfin_read16(CAN0_MB03_ID1) -#define bfin_write_CAN0_MB03_ID1(val) bfin_write16(CAN0_MB03_ID1, val) -#define bfin_read_CAN0_MB04_DATA0() bfin_read16(CAN0_MB04_DATA0) -#define bfin_write_CAN0_MB04_DATA0(val) bfin_write16(CAN0_MB04_DATA0, val) -#define bfin_read_CAN0_MB04_DATA1() bfin_read16(CAN0_MB04_DATA1) -#define bfin_write_CAN0_MB04_DATA1(val) bfin_write16(CAN0_MB04_DATA1, val) -#define bfin_read_CAN0_MB04_DATA2() bfin_read16(CAN0_MB04_DATA2) -#define bfin_write_CAN0_MB04_DATA2(val) bfin_write16(CAN0_MB04_DATA2, val) -#define bfin_read_CAN0_MB04_DATA3() bfin_read16(CAN0_MB04_DATA3) -#define bfin_write_CAN0_MB04_DATA3(val) bfin_write16(CAN0_MB04_DATA3, val) -#define bfin_read_CAN0_MB04_LENGTH() bfin_read16(CAN0_MB04_LENGTH) -#define bfin_write_CAN0_MB04_LENGTH(val) bfin_write16(CAN0_MB04_LENGTH, val) -#define bfin_read_CAN0_MB04_TIMESTAMP() bfin_read16(CAN0_MB04_TIMESTAMP) -#define bfin_write_CAN0_MB04_TIMESTAMP(val) bfin_write16(CAN0_MB04_TIMESTAMP, val) -#define bfin_read_CAN0_MB04_ID0() bfin_read16(CAN0_MB04_ID0) -#define bfin_write_CAN0_MB04_ID0(val) bfin_write16(CAN0_MB04_ID0, val) -#define bfin_read_CAN0_MB04_ID1() bfin_read16(CAN0_MB04_ID1) -#define bfin_write_CAN0_MB04_ID1(val) bfin_write16(CAN0_MB04_ID1, val) -#define bfin_read_CAN0_MB05_DATA0() bfin_read16(CAN0_MB05_DATA0) -#define bfin_write_CAN0_MB05_DATA0(val) bfin_write16(CAN0_MB05_DATA0, val) -#define bfin_read_CAN0_MB05_DATA1() bfin_read16(CAN0_MB05_DATA1) -#define bfin_write_CAN0_MB05_DATA1(val) bfin_write16(CAN0_MB05_DATA1, val) -#define bfin_read_CAN0_MB05_DATA2() bfin_read16(CAN0_MB05_DATA2) -#define bfin_write_CAN0_MB05_DATA2(val) bfin_write16(CAN0_MB05_DATA2, val) -#define bfin_read_CAN0_MB05_DATA3() bfin_read16(CAN0_MB05_DATA3) -#define bfin_write_CAN0_MB05_DATA3(val) bfin_write16(CAN0_MB05_DATA3, val) -#define bfin_read_CAN0_MB05_LENGTH() bfin_read16(CAN0_MB05_LENGTH) -#define bfin_write_CAN0_MB05_LENGTH(val) bfin_write16(CAN0_MB05_LENGTH, val) -#define bfin_read_CAN0_MB05_TIMESTAMP() bfin_read16(CAN0_MB05_TIMESTAMP) -#define bfin_write_CAN0_MB05_TIMESTAMP(val) bfin_write16(CAN0_MB05_TIMESTAMP, val) -#define bfin_read_CAN0_MB05_ID0() bfin_read16(CAN0_MB05_ID0) -#define bfin_write_CAN0_MB05_ID0(val) bfin_write16(CAN0_MB05_ID0, val) -#define bfin_read_CAN0_MB05_ID1() bfin_read16(CAN0_MB05_ID1) -#define bfin_write_CAN0_MB05_ID1(val) bfin_write16(CAN0_MB05_ID1, val) -#define bfin_read_CAN0_MB06_DATA0() bfin_read16(CAN0_MB06_DATA0) -#define bfin_write_CAN0_MB06_DATA0(val) bfin_write16(CAN0_MB06_DATA0, val) -#define bfin_read_CAN0_MB06_DATA1() bfin_read16(CAN0_MB06_DATA1) -#define bfin_write_CAN0_MB06_DATA1(val) bfin_write16(CAN0_MB06_DATA1, val) -#define bfin_read_CAN0_MB06_DATA2() bfin_read16(CAN0_MB06_DATA2) -#define bfin_write_CAN0_MB06_DATA2(val) bfin_write16(CAN0_MB06_DATA2, val) -#define bfin_read_CAN0_MB06_DATA3() bfin_read16(CAN0_MB06_DATA3) -#define bfin_write_CAN0_MB06_DATA3(val) bfin_write16(CAN0_MB06_DATA3, val) -#define bfin_read_CAN0_MB06_LENGTH() bfin_read16(CAN0_MB06_LENGTH) -#define bfin_write_CAN0_MB06_LENGTH(val) bfin_write16(CAN0_MB06_LENGTH, val) -#define bfin_read_CAN0_MB06_TIMESTAMP() bfin_read16(CAN0_MB06_TIMESTAMP) -#define bfin_write_CAN0_MB06_TIMESTAMP(val) bfin_write16(CAN0_MB06_TIMESTAMP, val) -#define bfin_read_CAN0_MB06_ID0() bfin_read16(CAN0_MB06_ID0) -#define bfin_write_CAN0_MB06_ID0(val) bfin_write16(CAN0_MB06_ID0, val) -#define bfin_read_CAN0_MB06_ID1() bfin_read16(CAN0_MB06_ID1) -#define bfin_write_CAN0_MB06_ID1(val) bfin_write16(CAN0_MB06_ID1, val) -#define bfin_read_CAN0_MB07_DATA0() bfin_read16(CAN0_MB07_DATA0) -#define bfin_write_CAN0_MB07_DATA0(val) bfin_write16(CAN0_MB07_DATA0, val) -#define bfin_read_CAN0_MB07_DATA1() bfin_read16(CAN0_MB07_DATA1) -#define bfin_write_CAN0_MB07_DATA1(val) bfin_write16(CAN0_MB07_DATA1, val) -#define bfin_read_CAN0_MB07_DATA2() bfin_read16(CAN0_MB07_DATA2) -#define bfin_write_CAN0_MB07_DATA2(val) bfin_write16(CAN0_MB07_DATA2, val) -#define bfin_read_CAN0_MB07_DATA3() bfin_read16(CAN0_MB07_DATA3) -#define bfin_write_CAN0_MB07_DATA3(val) bfin_write16(CAN0_MB07_DATA3, val) -#define bfin_read_CAN0_MB07_LENGTH() bfin_read16(CAN0_MB07_LENGTH) -#define bfin_write_CAN0_MB07_LENGTH(val) bfin_write16(CAN0_MB07_LENGTH, val) -#define bfin_read_CAN0_MB07_TIMESTAMP() bfin_read16(CAN0_MB07_TIMESTAMP) -#define bfin_write_CAN0_MB07_TIMESTAMP(val) bfin_write16(CAN0_MB07_TIMESTAMP, val) -#define bfin_read_CAN0_MB07_ID0() bfin_read16(CAN0_MB07_ID0) -#define bfin_write_CAN0_MB07_ID0(val) bfin_write16(CAN0_MB07_ID0, val) -#define bfin_read_CAN0_MB07_ID1() bfin_read16(CAN0_MB07_ID1) -#define bfin_write_CAN0_MB07_ID1(val) bfin_write16(CAN0_MB07_ID1, val) -#define bfin_read_CAN0_MB08_DATA0() bfin_read16(CAN0_MB08_DATA0) -#define bfin_write_CAN0_MB08_DATA0(val) bfin_write16(CAN0_MB08_DATA0, val) -#define bfin_read_CAN0_MB08_DATA1() bfin_read16(CAN0_MB08_DATA1) -#define bfin_write_CAN0_MB08_DATA1(val) bfin_write16(CAN0_MB08_DATA1, val) -#define bfin_read_CAN0_MB08_DATA2() bfin_read16(CAN0_MB08_DATA2) -#define bfin_write_CAN0_MB08_DATA2(val) bfin_write16(CAN0_MB08_DATA2, val) -#define bfin_read_CAN0_MB08_DATA3() bfin_read16(CAN0_MB08_DATA3) -#define bfin_write_CAN0_MB08_DATA3(val) bfin_write16(CAN0_MB08_DATA3, val) -#define bfin_read_CAN0_MB08_LENGTH() bfin_read16(CAN0_MB08_LENGTH) -#define bfin_write_CAN0_MB08_LENGTH(val) bfin_write16(CAN0_MB08_LENGTH, val) -#define bfin_read_CAN0_MB08_TIMESTAMP() bfin_read16(CAN0_MB08_TIMESTAMP) -#define bfin_write_CAN0_MB08_TIMESTAMP(val) bfin_write16(CAN0_MB08_TIMESTAMP, val) -#define bfin_read_CAN0_MB08_ID0() bfin_read16(CAN0_MB08_ID0) -#define bfin_write_CAN0_MB08_ID0(val) bfin_write16(CAN0_MB08_ID0, val) -#define bfin_read_CAN0_MB08_ID1() bfin_read16(CAN0_MB08_ID1) -#define bfin_write_CAN0_MB08_ID1(val) bfin_write16(CAN0_MB08_ID1, val) -#define bfin_read_CAN0_MB09_DATA0() bfin_read16(CAN0_MB09_DATA0) -#define bfin_write_CAN0_MB09_DATA0(val) bfin_write16(CAN0_MB09_DATA0, val) -#define bfin_read_CAN0_MB09_DATA1() bfin_read16(CAN0_MB09_DATA1) -#define bfin_write_CAN0_MB09_DATA1(val) bfin_write16(CAN0_MB09_DATA1, val) -#define bfin_read_CAN0_MB09_DATA2() bfin_read16(CAN0_MB09_DATA2) -#define bfin_write_CAN0_MB09_DATA2(val) bfin_write16(CAN0_MB09_DATA2, val) -#define bfin_read_CAN0_MB09_DATA3() bfin_read16(CAN0_MB09_DATA3) -#define bfin_write_CAN0_MB09_DATA3(val) bfin_write16(CAN0_MB09_DATA3, val) -#define bfin_read_CAN0_MB09_LENGTH() bfin_read16(CAN0_MB09_LENGTH) -#define bfin_write_CAN0_MB09_LENGTH(val) bfin_write16(CAN0_MB09_LENGTH, val) -#define bfin_read_CAN0_MB09_TIMESTAMP() bfin_read16(CAN0_MB09_TIMESTAMP) -#define bfin_write_CAN0_MB09_TIMESTAMP(val) bfin_write16(CAN0_MB09_TIMESTAMP, val) -#define bfin_read_CAN0_MB09_ID0() bfin_read16(CAN0_MB09_ID0) -#define bfin_write_CAN0_MB09_ID0(val) bfin_write16(CAN0_MB09_ID0, val) -#define bfin_read_CAN0_MB09_ID1() bfin_read16(CAN0_MB09_ID1) -#define bfin_write_CAN0_MB09_ID1(val) bfin_write16(CAN0_MB09_ID1, val) -#define bfin_read_CAN0_MB10_DATA0() bfin_read16(CAN0_MB10_DATA0) -#define bfin_write_CAN0_MB10_DATA0(val) bfin_write16(CAN0_MB10_DATA0, val) -#define bfin_read_CAN0_MB10_DATA1() bfin_read16(CAN0_MB10_DATA1) -#define bfin_write_CAN0_MB10_DATA1(val) bfin_write16(CAN0_MB10_DATA1, val) -#define bfin_read_CAN0_MB10_DATA2() bfin_read16(CAN0_MB10_DATA2) -#define bfin_write_CAN0_MB10_DATA2(val) bfin_write16(CAN0_MB10_DATA2, val) -#define bfin_read_CAN0_MB10_DATA3() bfin_read16(CAN0_MB10_DATA3) -#define bfin_write_CAN0_MB10_DATA3(val) bfin_write16(CAN0_MB10_DATA3, val) -#define bfin_read_CAN0_MB10_LENGTH() bfin_read16(CAN0_MB10_LENGTH) -#define bfin_write_CAN0_MB10_LENGTH(val) bfin_write16(CAN0_MB10_LENGTH, val) -#define bfin_read_CAN0_MB10_TIMESTAMP() bfin_read16(CAN0_MB10_TIMESTAMP) -#define bfin_write_CAN0_MB10_TIMESTAMP(val) bfin_write16(CAN0_MB10_TIMESTAMP, val) -#define bfin_read_CAN0_MB10_ID0() bfin_read16(CAN0_MB10_ID0) -#define bfin_write_CAN0_MB10_ID0(val) bfin_write16(CAN0_MB10_ID0, val) -#define bfin_read_CAN0_MB10_ID1() bfin_read16(CAN0_MB10_ID1) -#define bfin_write_CAN0_MB10_ID1(val) bfin_write16(CAN0_MB10_ID1, val) -#define bfin_read_CAN0_MB11_DATA0() bfin_read16(CAN0_MB11_DATA0) -#define bfin_write_CAN0_MB11_DATA0(val) bfin_write16(CAN0_MB11_DATA0, val) -#define bfin_read_CAN0_MB11_DATA1() bfin_read16(CAN0_MB11_DATA1) -#define bfin_write_CAN0_MB11_DATA1(val) bfin_write16(CAN0_MB11_DATA1, val) -#define bfin_read_CAN0_MB11_DATA2() bfin_read16(CAN0_MB11_DATA2) -#define bfin_write_CAN0_MB11_DATA2(val) bfin_write16(CAN0_MB11_DATA2, val) -#define bfin_read_CAN0_MB11_DATA3() bfin_read16(CAN0_MB11_DATA3) -#define bfin_write_CAN0_MB11_DATA3(val) bfin_write16(CAN0_MB11_DATA3, val) -#define bfin_read_CAN0_MB11_LENGTH() bfin_read16(CAN0_MB11_LENGTH) -#define bfin_write_CAN0_MB11_LENGTH(val) bfin_write16(CAN0_MB11_LENGTH, val) -#define bfin_read_CAN0_MB11_TIMESTAMP() bfin_read16(CAN0_MB11_TIMESTAMP) -#define bfin_write_CAN0_MB11_TIMESTAMP(val) bfin_write16(CAN0_MB11_TIMESTAMP, val) -#define bfin_read_CAN0_MB11_ID0() bfin_read16(CAN0_MB11_ID0) -#define bfin_write_CAN0_MB11_ID0(val) bfin_write16(CAN0_MB11_ID0, val) -#define bfin_read_CAN0_MB11_ID1() bfin_read16(CAN0_MB11_ID1) -#define bfin_write_CAN0_MB11_ID1(val) bfin_write16(CAN0_MB11_ID1, val) -#define bfin_read_CAN0_MB12_DATA0() bfin_read16(CAN0_MB12_DATA0) -#define bfin_write_CAN0_MB12_DATA0(val) bfin_write16(CAN0_MB12_DATA0, val) -#define bfin_read_CAN0_MB12_DATA1() bfin_read16(CAN0_MB12_DATA1) -#define bfin_write_CAN0_MB12_DATA1(val) bfin_write16(CAN0_MB12_DATA1, val) -#define bfin_read_CAN0_MB12_DATA2() bfin_read16(CAN0_MB12_DATA2) -#define bfin_write_CAN0_MB12_DATA2(val) bfin_write16(CAN0_MB12_DATA2, val) -#define bfin_read_CAN0_MB12_DATA3() bfin_read16(CAN0_MB12_DATA3) -#define bfin_write_CAN0_MB12_DATA3(val) bfin_write16(CAN0_MB12_DATA3, val) -#define bfin_read_CAN0_MB12_LENGTH() bfin_read16(CAN0_MB12_LENGTH) -#define bfin_write_CAN0_MB12_LENGTH(val) bfin_write16(CAN0_MB12_LENGTH, val) -#define bfin_read_CAN0_MB12_TIMESTAMP() bfin_read16(CAN0_MB12_TIMESTAMP) -#define bfin_write_CAN0_MB12_TIMESTAMP(val) bfin_write16(CAN0_MB12_TIMESTAMP, val) -#define bfin_read_CAN0_MB12_ID0() bfin_read16(CAN0_MB12_ID0) -#define bfin_write_CAN0_MB12_ID0(val) bfin_write16(CAN0_MB12_ID0, val) -#define bfin_read_CAN0_MB12_ID1() bfin_read16(CAN0_MB12_ID1) -#define bfin_write_CAN0_MB12_ID1(val) bfin_write16(CAN0_MB12_ID1, val) -#define bfin_read_CAN0_MB13_DATA0() bfin_read16(CAN0_MB13_DATA0) -#define bfin_write_CAN0_MB13_DATA0(val) bfin_write16(CAN0_MB13_DATA0, val) -#define bfin_read_CAN0_MB13_DATA1() bfin_read16(CAN0_MB13_DATA1) -#define bfin_write_CAN0_MB13_DATA1(val) bfin_write16(CAN0_MB13_DATA1, val) -#define bfin_read_CAN0_MB13_DATA2() bfin_read16(CAN0_MB13_DATA2) -#define bfin_write_CAN0_MB13_DATA2(val) bfin_write16(CAN0_MB13_DATA2, val) -#define bfin_read_CAN0_MB13_DATA3() bfin_read16(CAN0_MB13_DATA3) -#define bfin_write_CAN0_MB13_DATA3(val) bfin_write16(CAN0_MB13_DATA3, val) -#define bfin_read_CAN0_MB13_LENGTH() bfin_read16(CAN0_MB13_LENGTH) -#define bfin_write_CAN0_MB13_LENGTH(val) bfin_write16(CAN0_MB13_LENGTH, val) -#define bfin_read_CAN0_MB13_TIMESTAMP() bfin_read16(CAN0_MB13_TIMESTAMP) -#define bfin_write_CAN0_MB13_TIMESTAMP(val) bfin_write16(CAN0_MB13_TIMESTAMP, val) -#define bfin_read_CAN0_MB13_ID0() bfin_read16(CAN0_MB13_ID0) -#define bfin_write_CAN0_MB13_ID0(val) bfin_write16(CAN0_MB13_ID0, val) -#define bfin_read_CAN0_MB13_ID1() bfin_read16(CAN0_MB13_ID1) -#define bfin_write_CAN0_MB13_ID1(val) bfin_write16(CAN0_MB13_ID1, val) -#define bfin_read_CAN0_MB14_DATA0() bfin_read16(CAN0_MB14_DATA0) -#define bfin_write_CAN0_MB14_DATA0(val) bfin_write16(CAN0_MB14_DATA0, val) -#define bfin_read_CAN0_MB14_DATA1() bfin_read16(CAN0_MB14_DATA1) -#define bfin_write_CAN0_MB14_DATA1(val) bfin_write16(CAN0_MB14_DATA1, val) -#define bfin_read_CAN0_MB14_DATA2() bfin_read16(CAN0_MB14_DATA2) -#define bfin_write_CAN0_MB14_DATA2(val) bfin_write16(CAN0_MB14_DATA2, val) -#define bfin_read_CAN0_MB14_DATA3() bfin_read16(CAN0_MB14_DATA3) -#define bfin_write_CAN0_MB14_DATA3(val) bfin_write16(CAN0_MB14_DATA3, val) -#define bfin_read_CAN0_MB14_LENGTH() bfin_read16(CAN0_MB14_LENGTH) -#define bfin_write_CAN0_MB14_LENGTH(val) bfin_write16(CAN0_MB14_LENGTH, val) -#define bfin_read_CAN0_MB14_TIMESTAMP() bfin_read16(CAN0_MB14_TIMESTAMP) -#define bfin_write_CAN0_MB14_TIMESTAMP(val) bfin_write16(CAN0_MB14_TIMESTAMP, val) -#define bfin_read_CAN0_MB14_ID0() bfin_read16(CAN0_MB14_ID0) -#define bfin_write_CAN0_MB14_ID0(val) bfin_write16(CAN0_MB14_ID0, val) -#define bfin_read_CAN0_MB14_ID1() bfin_read16(CAN0_MB14_ID1) -#define bfin_write_CAN0_MB14_ID1(val) bfin_write16(CAN0_MB14_ID1, val) -#define bfin_read_CAN0_MB15_DATA0() bfin_read16(CAN0_MB15_DATA0) -#define bfin_write_CAN0_MB15_DATA0(val) bfin_write16(CAN0_MB15_DATA0, val) -#define bfin_read_CAN0_MB15_DATA1() bfin_read16(CAN0_MB15_DATA1) -#define bfin_write_CAN0_MB15_DATA1(val) bfin_write16(CAN0_MB15_DATA1, val) -#define bfin_read_CAN0_MB15_DATA2() bfin_read16(CAN0_MB15_DATA2) -#define bfin_write_CAN0_MB15_DATA2(val) bfin_write16(CAN0_MB15_DATA2, val) -#define bfin_read_CAN0_MB15_DATA3() bfin_read16(CAN0_MB15_DATA3) -#define bfin_write_CAN0_MB15_DATA3(val) bfin_write16(CAN0_MB15_DATA3, val) -#define bfin_read_CAN0_MB15_LENGTH() bfin_read16(CAN0_MB15_LENGTH) -#define bfin_write_CAN0_MB15_LENGTH(val) bfin_write16(CAN0_MB15_LENGTH, val) -#define bfin_read_CAN0_MB15_TIMESTAMP() bfin_read16(CAN0_MB15_TIMESTAMP) -#define bfin_write_CAN0_MB15_TIMESTAMP(val) bfin_write16(CAN0_MB15_TIMESTAMP, val) -#define bfin_read_CAN0_MB15_ID0() bfin_read16(CAN0_MB15_ID0) -#define bfin_write_CAN0_MB15_ID0(val) bfin_write16(CAN0_MB15_ID0, val) -#define bfin_read_CAN0_MB15_ID1() bfin_read16(CAN0_MB15_ID1) -#define bfin_write_CAN0_MB15_ID1(val) bfin_write16(CAN0_MB15_ID1, val) - -/* CAN Controller 0 Mailbox Data Registers */ - -#define bfin_read_CAN0_MB16_DATA0() bfin_read16(CAN0_MB16_DATA0) -#define bfin_write_CAN0_MB16_DATA0(val) bfin_write16(CAN0_MB16_DATA0, val) -#define bfin_read_CAN0_MB16_DATA1() bfin_read16(CAN0_MB16_DATA1) -#define bfin_write_CAN0_MB16_DATA1(val) bfin_write16(CAN0_MB16_DATA1, val) -#define bfin_read_CAN0_MB16_DATA2() bfin_read16(CAN0_MB16_DATA2) -#define bfin_write_CAN0_MB16_DATA2(val) bfin_write16(CAN0_MB16_DATA2, val) -#define bfin_read_CAN0_MB16_DATA3() bfin_read16(CAN0_MB16_DATA3) -#define bfin_write_CAN0_MB16_DATA3(val) bfin_write16(CAN0_MB16_DATA3, val) -#define bfin_read_CAN0_MB16_LENGTH() bfin_read16(CAN0_MB16_LENGTH) -#define bfin_write_CAN0_MB16_LENGTH(val) bfin_write16(CAN0_MB16_LENGTH, val) -#define bfin_read_CAN0_MB16_TIMESTAMP() bfin_read16(CAN0_MB16_TIMESTAMP) -#define bfin_write_CAN0_MB16_TIMESTAMP(val) bfin_write16(CAN0_MB16_TIMESTAMP, val) -#define bfin_read_CAN0_MB16_ID0() bfin_read16(CAN0_MB16_ID0) -#define bfin_write_CAN0_MB16_ID0(val) bfin_write16(CAN0_MB16_ID0, val) -#define bfin_read_CAN0_MB16_ID1() bfin_read16(CAN0_MB16_ID1) -#define bfin_write_CAN0_MB16_ID1(val) bfin_write16(CAN0_MB16_ID1, val) -#define bfin_read_CAN0_MB17_DATA0() bfin_read16(CAN0_MB17_DATA0) -#define bfin_write_CAN0_MB17_DATA0(val) bfin_write16(CAN0_MB17_DATA0, val) -#define bfin_read_CAN0_MB17_DATA1() bfin_read16(CAN0_MB17_DATA1) -#define bfin_write_CAN0_MB17_DATA1(val) bfin_write16(CAN0_MB17_DATA1, val) -#define bfin_read_CAN0_MB17_DATA2() bfin_read16(CAN0_MB17_DATA2) -#define bfin_write_CAN0_MB17_DATA2(val) bfin_write16(CAN0_MB17_DATA2, val) -#define bfin_read_CAN0_MB17_DATA3() bfin_read16(CAN0_MB17_DATA3) -#define bfin_write_CAN0_MB17_DATA3(val) bfin_write16(CAN0_MB17_DATA3, val) -#define bfin_read_CAN0_MB17_LENGTH() bfin_read16(CAN0_MB17_LENGTH) -#define bfin_write_CAN0_MB17_LENGTH(val) bfin_write16(CAN0_MB17_LENGTH, val) -#define bfin_read_CAN0_MB17_TIMESTAMP() bfin_read16(CAN0_MB17_TIMESTAMP) -#define bfin_write_CAN0_MB17_TIMESTAMP(val) bfin_write16(CAN0_MB17_TIMESTAMP, val) -#define bfin_read_CAN0_MB17_ID0() bfin_read16(CAN0_MB17_ID0) -#define bfin_write_CAN0_MB17_ID0(val) bfin_write16(CAN0_MB17_ID0, val) -#define bfin_read_CAN0_MB17_ID1() bfin_read16(CAN0_MB17_ID1) -#define bfin_write_CAN0_MB17_ID1(val) bfin_write16(CAN0_MB17_ID1, val) -#define bfin_read_CAN0_MB18_DATA0() bfin_read16(CAN0_MB18_DATA0) -#define bfin_write_CAN0_MB18_DATA0(val) bfin_write16(CAN0_MB18_DATA0, val) -#define bfin_read_CAN0_MB18_DATA1() bfin_read16(CAN0_MB18_DATA1) -#define bfin_write_CAN0_MB18_DATA1(val) bfin_write16(CAN0_MB18_DATA1, val) -#define bfin_read_CAN0_MB18_DATA2() bfin_read16(CAN0_MB18_DATA2) -#define bfin_write_CAN0_MB18_DATA2(val) bfin_write16(CAN0_MB18_DATA2, val) -#define bfin_read_CAN0_MB18_DATA3() bfin_read16(CAN0_MB18_DATA3) -#define bfin_write_CAN0_MB18_DATA3(val) bfin_write16(CAN0_MB18_DATA3, val) -#define bfin_read_CAN0_MB18_LENGTH() bfin_read16(CAN0_MB18_LENGTH) -#define bfin_write_CAN0_MB18_LENGTH(val) bfin_write16(CAN0_MB18_LENGTH, val) -#define bfin_read_CAN0_MB18_TIMESTAMP() bfin_read16(CAN0_MB18_TIMESTAMP) -#define bfin_write_CAN0_MB18_TIMESTAMP(val) bfin_write16(CAN0_MB18_TIMESTAMP, val) -#define bfin_read_CAN0_MB18_ID0() bfin_read16(CAN0_MB18_ID0) -#define bfin_write_CAN0_MB18_ID0(val) bfin_write16(CAN0_MB18_ID0, val) -#define bfin_read_CAN0_MB18_ID1() bfin_read16(CAN0_MB18_ID1) -#define bfin_write_CAN0_MB18_ID1(val) bfin_write16(CAN0_MB18_ID1, val) -#define bfin_read_CAN0_MB19_DATA0() bfin_read16(CAN0_MB19_DATA0) -#define bfin_write_CAN0_MB19_DATA0(val) bfin_write16(CAN0_MB19_DATA0, val) -#define bfin_read_CAN0_MB19_DATA1() bfin_read16(CAN0_MB19_DATA1) -#define bfin_write_CAN0_MB19_DATA1(val) bfin_write16(CAN0_MB19_DATA1, val) -#define bfin_read_CAN0_MB19_DATA2() bfin_read16(CAN0_MB19_DATA2) -#define bfin_write_CAN0_MB19_DATA2(val) bfin_write16(CAN0_MB19_DATA2, val) -#define bfin_read_CAN0_MB19_DATA3() bfin_read16(CAN0_MB19_DATA3) -#define bfin_write_CAN0_MB19_DATA3(val) bfin_write16(CAN0_MB19_DATA3, val) -#define bfin_read_CAN0_MB19_LENGTH() bfin_read16(CAN0_MB19_LENGTH) -#define bfin_write_CAN0_MB19_LENGTH(val) bfin_write16(CAN0_MB19_LENGTH, val) -#define bfin_read_CAN0_MB19_TIMESTAMP() bfin_read16(CAN0_MB19_TIMESTAMP) -#define bfin_write_CAN0_MB19_TIMESTAMP(val) bfin_write16(CAN0_MB19_TIMESTAMP, val) -#define bfin_read_CAN0_MB19_ID0() bfin_read16(CAN0_MB19_ID0) -#define bfin_write_CAN0_MB19_ID0(val) bfin_write16(CAN0_MB19_ID0, val) -#define bfin_read_CAN0_MB19_ID1() bfin_read16(CAN0_MB19_ID1) -#define bfin_write_CAN0_MB19_ID1(val) bfin_write16(CAN0_MB19_ID1, val) -#define bfin_read_CAN0_MB20_DATA0() bfin_read16(CAN0_MB20_DATA0) -#define bfin_write_CAN0_MB20_DATA0(val) bfin_write16(CAN0_MB20_DATA0, val) -#define bfin_read_CAN0_MB20_DATA1() bfin_read16(CAN0_MB20_DATA1) -#define bfin_write_CAN0_MB20_DATA1(val) bfin_write16(CAN0_MB20_DATA1, val) -#define bfin_read_CAN0_MB20_DATA2() bfin_read16(CAN0_MB20_DATA2) -#define bfin_write_CAN0_MB20_DATA2(val) bfin_write16(CAN0_MB20_DATA2, val) -#define bfin_read_CAN0_MB20_DATA3() bfin_read16(CAN0_MB20_DATA3) -#define bfin_write_CAN0_MB20_DATA3(val) bfin_write16(CAN0_MB20_DATA3, val) -#define bfin_read_CAN0_MB20_LENGTH() bfin_read16(CAN0_MB20_LENGTH) -#define bfin_write_CAN0_MB20_LENGTH(val) bfin_write16(CAN0_MB20_LENGTH, val) -#define bfin_read_CAN0_MB20_TIMESTAMP() bfin_read16(CAN0_MB20_TIMESTAMP) -#define bfin_write_CAN0_MB20_TIMESTAMP(val) bfin_write16(CAN0_MB20_TIMESTAMP, val) -#define bfin_read_CAN0_MB20_ID0() bfin_read16(CAN0_MB20_ID0) -#define bfin_write_CAN0_MB20_ID0(val) bfin_write16(CAN0_MB20_ID0, val) -#define bfin_read_CAN0_MB20_ID1() bfin_read16(CAN0_MB20_ID1) -#define bfin_write_CAN0_MB20_ID1(val) bfin_write16(CAN0_MB20_ID1, val) -#define bfin_read_CAN0_MB21_DATA0() bfin_read16(CAN0_MB21_DATA0) -#define bfin_write_CAN0_MB21_DATA0(val) bfin_write16(CAN0_MB21_DATA0, val) -#define bfin_read_CAN0_MB21_DATA1() bfin_read16(CAN0_MB21_DATA1) -#define bfin_write_CAN0_MB21_DATA1(val) bfin_write16(CAN0_MB21_DATA1, val) -#define bfin_read_CAN0_MB21_DATA2() bfin_read16(CAN0_MB21_DATA2) -#define bfin_write_CAN0_MB21_DATA2(val) bfin_write16(CAN0_MB21_DATA2, val) -#define bfin_read_CAN0_MB21_DATA3() bfin_read16(CAN0_MB21_DATA3) -#define bfin_write_CAN0_MB21_DATA3(val) bfin_write16(CAN0_MB21_DATA3, val) -#define bfin_read_CAN0_MB21_LENGTH() bfin_read16(CAN0_MB21_LENGTH) -#define bfin_write_CAN0_MB21_LENGTH(val) bfin_write16(CAN0_MB21_LENGTH, val) -#define bfin_read_CAN0_MB21_TIMESTAMP() bfin_read16(CAN0_MB21_TIMESTAMP) -#define bfin_write_CAN0_MB21_TIMESTAMP(val) bfin_write16(CAN0_MB21_TIMESTAMP, val) -#define bfin_read_CAN0_MB21_ID0() bfin_read16(CAN0_MB21_ID0) -#define bfin_write_CAN0_MB21_ID0(val) bfin_write16(CAN0_MB21_ID0, val) -#define bfin_read_CAN0_MB21_ID1() bfin_read16(CAN0_MB21_ID1) -#define bfin_write_CAN0_MB21_ID1(val) bfin_write16(CAN0_MB21_ID1, val) -#define bfin_read_CAN0_MB22_DATA0() bfin_read16(CAN0_MB22_DATA0) -#define bfin_write_CAN0_MB22_DATA0(val) bfin_write16(CAN0_MB22_DATA0, val) -#define bfin_read_CAN0_MB22_DATA1() bfin_read16(CAN0_MB22_DATA1) -#define bfin_write_CAN0_MB22_DATA1(val) bfin_write16(CAN0_MB22_DATA1, val) -#define bfin_read_CAN0_MB22_DATA2() bfin_read16(CAN0_MB22_DATA2) -#define bfin_write_CAN0_MB22_DATA2(val) bfin_write16(CAN0_MB22_DATA2, val) -#define bfin_read_CAN0_MB22_DATA3() bfin_read16(CAN0_MB22_DATA3) -#define bfin_write_CAN0_MB22_DATA3(val) bfin_write16(CAN0_MB22_DATA3, val) -#define bfin_read_CAN0_MB22_LENGTH() bfin_read16(CAN0_MB22_LENGTH) -#define bfin_write_CAN0_MB22_LENGTH(val) bfin_write16(CAN0_MB22_LENGTH, val) -#define bfin_read_CAN0_MB22_TIMESTAMP() bfin_read16(CAN0_MB22_TIMESTAMP) -#define bfin_write_CAN0_MB22_TIMESTAMP(val) bfin_write16(CAN0_MB22_TIMESTAMP, val) -#define bfin_read_CAN0_MB22_ID0() bfin_read16(CAN0_MB22_ID0) -#define bfin_write_CAN0_MB22_ID0(val) bfin_write16(CAN0_MB22_ID0, val) -#define bfin_read_CAN0_MB22_ID1() bfin_read16(CAN0_MB22_ID1) -#define bfin_write_CAN0_MB22_ID1(val) bfin_write16(CAN0_MB22_ID1, val) -#define bfin_read_CAN0_MB23_DATA0() bfin_read16(CAN0_MB23_DATA0) -#define bfin_write_CAN0_MB23_DATA0(val) bfin_write16(CAN0_MB23_DATA0, val) -#define bfin_read_CAN0_MB23_DATA1() bfin_read16(CAN0_MB23_DATA1) -#define bfin_write_CAN0_MB23_DATA1(val) bfin_write16(CAN0_MB23_DATA1, val) -#define bfin_read_CAN0_MB23_DATA2() bfin_read16(CAN0_MB23_DATA2) -#define bfin_write_CAN0_MB23_DATA2(val) bfin_write16(CAN0_MB23_DATA2, val) -#define bfin_read_CAN0_MB23_DATA3() bfin_read16(CAN0_MB23_DATA3) -#define bfin_write_CAN0_MB23_DATA3(val) bfin_write16(CAN0_MB23_DATA3, val) -#define bfin_read_CAN0_MB23_LENGTH() bfin_read16(CAN0_MB23_LENGTH) -#define bfin_write_CAN0_MB23_LENGTH(val) bfin_write16(CAN0_MB23_LENGTH, val) -#define bfin_read_CAN0_MB23_TIMESTAMP() bfin_read16(CAN0_MB23_TIMESTAMP) -#define bfin_write_CAN0_MB23_TIMESTAMP(val) bfin_write16(CAN0_MB23_TIMESTAMP, val) -#define bfin_read_CAN0_MB23_ID0() bfin_read16(CAN0_MB23_ID0) -#define bfin_write_CAN0_MB23_ID0(val) bfin_write16(CAN0_MB23_ID0, val) -#define bfin_read_CAN0_MB23_ID1() bfin_read16(CAN0_MB23_ID1) -#define bfin_write_CAN0_MB23_ID1(val) bfin_write16(CAN0_MB23_ID1, val) -#define bfin_read_CAN0_MB24_DATA0() bfin_read16(CAN0_MB24_DATA0) -#define bfin_write_CAN0_MB24_DATA0(val) bfin_write16(CAN0_MB24_DATA0, val) -#define bfin_read_CAN0_MB24_DATA1() bfin_read16(CAN0_MB24_DATA1) -#define bfin_write_CAN0_MB24_DATA1(val) bfin_write16(CAN0_MB24_DATA1, val) -#define bfin_read_CAN0_MB24_DATA2() bfin_read16(CAN0_MB24_DATA2) -#define bfin_write_CAN0_MB24_DATA2(val) bfin_write16(CAN0_MB24_DATA2, val) -#define bfin_read_CAN0_MB24_DATA3() bfin_read16(CAN0_MB24_DATA3) -#define bfin_write_CAN0_MB24_DATA3(val) bfin_write16(CAN0_MB24_DATA3, val) -#define bfin_read_CAN0_MB24_LENGTH() bfin_read16(CAN0_MB24_LENGTH) -#define bfin_write_CAN0_MB24_LENGTH(val) bfin_write16(CAN0_MB24_LENGTH, val) -#define bfin_read_CAN0_MB24_TIMESTAMP() bfin_read16(CAN0_MB24_TIMESTAMP) -#define bfin_write_CAN0_MB24_TIMESTAMP(val) bfin_write16(CAN0_MB24_TIMESTAMP, val) -#define bfin_read_CAN0_MB24_ID0() bfin_read16(CAN0_MB24_ID0) -#define bfin_write_CAN0_MB24_ID0(val) bfin_write16(CAN0_MB24_ID0, val) -#define bfin_read_CAN0_MB24_ID1() bfin_read16(CAN0_MB24_ID1) -#define bfin_write_CAN0_MB24_ID1(val) bfin_write16(CAN0_MB24_ID1, val) -#define bfin_read_CAN0_MB25_DATA0() bfin_read16(CAN0_MB25_DATA0) -#define bfin_write_CAN0_MB25_DATA0(val) bfin_write16(CAN0_MB25_DATA0, val) -#define bfin_read_CAN0_MB25_DATA1() bfin_read16(CAN0_MB25_DATA1) -#define bfin_write_CAN0_MB25_DATA1(val) bfin_write16(CAN0_MB25_DATA1, val) -#define bfin_read_CAN0_MB25_DATA2() bfin_read16(CAN0_MB25_DATA2) -#define bfin_write_CAN0_MB25_DATA2(val) bfin_write16(CAN0_MB25_DATA2, val) -#define bfin_read_CAN0_MB25_DATA3() bfin_read16(CAN0_MB25_DATA3) -#define bfin_write_CAN0_MB25_DATA3(val) bfin_write16(CAN0_MB25_DATA3, val) -#define bfin_read_CAN0_MB25_LENGTH() bfin_read16(CAN0_MB25_LENGTH) -#define bfin_write_CAN0_MB25_LENGTH(val) bfin_write16(CAN0_MB25_LENGTH, val) -#define bfin_read_CAN0_MB25_TIMESTAMP() bfin_read16(CAN0_MB25_TIMESTAMP) -#define bfin_write_CAN0_MB25_TIMESTAMP(val) bfin_write16(CAN0_MB25_TIMESTAMP, val) -#define bfin_read_CAN0_MB25_ID0() bfin_read16(CAN0_MB25_ID0) -#define bfin_write_CAN0_MB25_ID0(val) bfin_write16(CAN0_MB25_ID0, val) -#define bfin_read_CAN0_MB25_ID1() bfin_read16(CAN0_MB25_ID1) -#define bfin_write_CAN0_MB25_ID1(val) bfin_write16(CAN0_MB25_ID1, val) -#define bfin_read_CAN0_MB26_DATA0() bfin_read16(CAN0_MB26_DATA0) -#define bfin_write_CAN0_MB26_DATA0(val) bfin_write16(CAN0_MB26_DATA0, val) -#define bfin_read_CAN0_MB26_DATA1() bfin_read16(CAN0_MB26_DATA1) -#define bfin_write_CAN0_MB26_DATA1(val) bfin_write16(CAN0_MB26_DATA1, val) -#define bfin_read_CAN0_MB26_DATA2() bfin_read16(CAN0_MB26_DATA2) -#define bfin_write_CAN0_MB26_DATA2(val) bfin_write16(CAN0_MB26_DATA2, val) -#define bfin_read_CAN0_MB26_DATA3() bfin_read16(CAN0_MB26_DATA3) -#define bfin_write_CAN0_MB26_DATA3(val) bfin_write16(CAN0_MB26_DATA3, val) -#define bfin_read_CAN0_MB26_LENGTH() bfin_read16(CAN0_MB26_LENGTH) -#define bfin_write_CAN0_MB26_LENGTH(val) bfin_write16(CAN0_MB26_LENGTH, val) -#define bfin_read_CAN0_MB26_TIMESTAMP() bfin_read16(CAN0_MB26_TIMESTAMP) -#define bfin_write_CAN0_MB26_TIMESTAMP(val) bfin_write16(CAN0_MB26_TIMESTAMP, val) -#define bfin_read_CAN0_MB26_ID0() bfin_read16(CAN0_MB26_ID0) -#define bfin_write_CAN0_MB26_ID0(val) bfin_write16(CAN0_MB26_ID0, val) -#define bfin_read_CAN0_MB26_ID1() bfin_read16(CAN0_MB26_ID1) -#define bfin_write_CAN0_MB26_ID1(val) bfin_write16(CAN0_MB26_ID1, val) -#define bfin_read_CAN0_MB27_DATA0() bfin_read16(CAN0_MB27_DATA0) -#define bfin_write_CAN0_MB27_DATA0(val) bfin_write16(CAN0_MB27_DATA0, val) -#define bfin_read_CAN0_MB27_DATA1() bfin_read16(CAN0_MB27_DATA1) -#define bfin_write_CAN0_MB27_DATA1(val) bfin_write16(CAN0_MB27_DATA1, val) -#define bfin_read_CAN0_MB27_DATA2() bfin_read16(CAN0_MB27_DATA2) -#define bfin_write_CAN0_MB27_DATA2(val) bfin_write16(CAN0_MB27_DATA2, val) -#define bfin_read_CAN0_MB27_DATA3() bfin_read16(CAN0_MB27_DATA3) -#define bfin_write_CAN0_MB27_DATA3(val) bfin_write16(CAN0_MB27_DATA3, val) -#define bfin_read_CAN0_MB27_LENGTH() bfin_read16(CAN0_MB27_LENGTH) -#define bfin_write_CAN0_MB27_LENGTH(val) bfin_write16(CAN0_MB27_LENGTH, val) -#define bfin_read_CAN0_MB27_TIMESTAMP() bfin_read16(CAN0_MB27_TIMESTAMP) -#define bfin_write_CAN0_MB27_TIMESTAMP(val) bfin_write16(CAN0_MB27_TIMESTAMP, val) -#define bfin_read_CAN0_MB27_ID0() bfin_read16(CAN0_MB27_ID0) -#define bfin_write_CAN0_MB27_ID0(val) bfin_write16(CAN0_MB27_ID0, val) -#define bfin_read_CAN0_MB27_ID1() bfin_read16(CAN0_MB27_ID1) -#define bfin_write_CAN0_MB27_ID1(val) bfin_write16(CAN0_MB27_ID1, val) -#define bfin_read_CAN0_MB28_DATA0() bfin_read16(CAN0_MB28_DATA0) -#define bfin_write_CAN0_MB28_DATA0(val) bfin_write16(CAN0_MB28_DATA0, val) -#define bfin_read_CAN0_MB28_DATA1() bfin_read16(CAN0_MB28_DATA1) -#define bfin_write_CAN0_MB28_DATA1(val) bfin_write16(CAN0_MB28_DATA1, val) -#define bfin_read_CAN0_MB28_DATA2() bfin_read16(CAN0_MB28_DATA2) -#define bfin_write_CAN0_MB28_DATA2(val) bfin_write16(CAN0_MB28_DATA2, val) -#define bfin_read_CAN0_MB28_DATA3() bfin_read16(CAN0_MB28_DATA3) -#define bfin_write_CAN0_MB28_DATA3(val) bfin_write16(CAN0_MB28_DATA3, val) -#define bfin_read_CAN0_MB28_LENGTH() bfin_read16(CAN0_MB28_LENGTH) -#define bfin_write_CAN0_MB28_LENGTH(val) bfin_write16(CAN0_MB28_LENGTH, val) -#define bfin_read_CAN0_MB28_TIMESTAMP() bfin_read16(CAN0_MB28_TIMESTAMP) -#define bfin_write_CAN0_MB28_TIMESTAMP(val) bfin_write16(CAN0_MB28_TIMESTAMP, val) -#define bfin_read_CAN0_MB28_ID0() bfin_read16(CAN0_MB28_ID0) -#define bfin_write_CAN0_MB28_ID0(val) bfin_write16(CAN0_MB28_ID0, val) -#define bfin_read_CAN0_MB28_ID1() bfin_read16(CAN0_MB28_ID1) -#define bfin_write_CAN0_MB28_ID1(val) bfin_write16(CAN0_MB28_ID1, val) -#define bfin_read_CAN0_MB29_DATA0() bfin_read16(CAN0_MB29_DATA0) -#define bfin_write_CAN0_MB29_DATA0(val) bfin_write16(CAN0_MB29_DATA0, val) -#define bfin_read_CAN0_MB29_DATA1() bfin_read16(CAN0_MB29_DATA1) -#define bfin_write_CAN0_MB29_DATA1(val) bfin_write16(CAN0_MB29_DATA1, val) -#define bfin_read_CAN0_MB29_DATA2() bfin_read16(CAN0_MB29_DATA2) -#define bfin_write_CAN0_MB29_DATA2(val) bfin_write16(CAN0_MB29_DATA2, val) -#define bfin_read_CAN0_MB29_DATA3() bfin_read16(CAN0_MB29_DATA3) -#define bfin_write_CAN0_MB29_DATA3(val) bfin_write16(CAN0_MB29_DATA3, val) -#define bfin_read_CAN0_MB29_LENGTH() bfin_read16(CAN0_MB29_LENGTH) -#define bfin_write_CAN0_MB29_LENGTH(val) bfin_write16(CAN0_MB29_LENGTH, val) -#define bfin_read_CAN0_MB29_TIMESTAMP() bfin_read16(CAN0_MB29_TIMESTAMP) -#define bfin_write_CAN0_MB29_TIMESTAMP(val) bfin_write16(CAN0_MB29_TIMESTAMP, val) -#define bfin_read_CAN0_MB29_ID0() bfin_read16(CAN0_MB29_ID0) -#define bfin_write_CAN0_MB29_ID0(val) bfin_write16(CAN0_MB29_ID0, val) -#define bfin_read_CAN0_MB29_ID1() bfin_read16(CAN0_MB29_ID1) -#define bfin_write_CAN0_MB29_ID1(val) bfin_write16(CAN0_MB29_ID1, val) -#define bfin_read_CAN0_MB30_DATA0() bfin_read16(CAN0_MB30_DATA0) -#define bfin_write_CAN0_MB30_DATA0(val) bfin_write16(CAN0_MB30_DATA0, val) -#define bfin_read_CAN0_MB30_DATA1() bfin_read16(CAN0_MB30_DATA1) -#define bfin_write_CAN0_MB30_DATA1(val) bfin_write16(CAN0_MB30_DATA1, val) -#define bfin_read_CAN0_MB30_DATA2() bfin_read16(CAN0_MB30_DATA2) -#define bfin_write_CAN0_MB30_DATA2(val) bfin_write16(CAN0_MB30_DATA2, val) -#define bfin_read_CAN0_MB30_DATA3() bfin_read16(CAN0_MB30_DATA3) -#define bfin_write_CAN0_MB30_DATA3(val) bfin_write16(CAN0_MB30_DATA3, val) -#define bfin_read_CAN0_MB30_LENGTH() bfin_read16(CAN0_MB30_LENGTH) -#define bfin_write_CAN0_MB30_LENGTH(val) bfin_write16(CAN0_MB30_LENGTH, val) -#define bfin_read_CAN0_MB30_TIMESTAMP() bfin_read16(CAN0_MB30_TIMESTAMP) -#define bfin_write_CAN0_MB30_TIMESTAMP(val) bfin_write16(CAN0_MB30_TIMESTAMP, val) -#define bfin_read_CAN0_MB30_ID0() bfin_read16(CAN0_MB30_ID0) -#define bfin_write_CAN0_MB30_ID0(val) bfin_write16(CAN0_MB30_ID0, val) -#define bfin_read_CAN0_MB30_ID1() bfin_read16(CAN0_MB30_ID1) -#define bfin_write_CAN0_MB30_ID1(val) bfin_write16(CAN0_MB30_ID1, val) -#define bfin_read_CAN0_MB31_DATA0() bfin_read16(CAN0_MB31_DATA0) -#define bfin_write_CAN0_MB31_DATA0(val) bfin_write16(CAN0_MB31_DATA0, val) -#define bfin_read_CAN0_MB31_DATA1() bfin_read16(CAN0_MB31_DATA1) -#define bfin_write_CAN0_MB31_DATA1(val) bfin_write16(CAN0_MB31_DATA1, val) -#define bfin_read_CAN0_MB31_DATA2() bfin_read16(CAN0_MB31_DATA2) -#define bfin_write_CAN0_MB31_DATA2(val) bfin_write16(CAN0_MB31_DATA2, val) -#define bfin_read_CAN0_MB31_DATA3() bfin_read16(CAN0_MB31_DATA3) -#define bfin_write_CAN0_MB31_DATA3(val) bfin_write16(CAN0_MB31_DATA3, val) -#define bfin_read_CAN0_MB31_LENGTH() bfin_read16(CAN0_MB31_LENGTH) -#define bfin_write_CAN0_MB31_LENGTH(val) bfin_write16(CAN0_MB31_LENGTH, val) -#define bfin_read_CAN0_MB31_TIMESTAMP() bfin_read16(CAN0_MB31_TIMESTAMP) -#define bfin_write_CAN0_MB31_TIMESTAMP(val) bfin_write16(CAN0_MB31_TIMESTAMP, val) -#define bfin_read_CAN0_MB31_ID0() bfin_read16(CAN0_MB31_ID0) -#define bfin_write_CAN0_MB31_ID0(val) bfin_write16(CAN0_MB31_ID0, val) -#define bfin_read_CAN0_MB31_ID1() bfin_read16(CAN0_MB31_ID1) -#define bfin_write_CAN0_MB31_ID1(val) bfin_write16(CAN0_MB31_ID1, val) - -/* Counter Registers */ - -#define bfin_read_CNT_CONFIG() bfin_read16(CNT_CONFIG) -#define bfin_write_CNT_CONFIG(val) bfin_write16(CNT_CONFIG, val) -#define bfin_read_CNT_IMASK() bfin_read16(CNT_IMASK) -#define bfin_write_CNT_IMASK(val) bfin_write16(CNT_IMASK, val) -#define bfin_read_CNT_STATUS() bfin_read16(CNT_STATUS) -#define bfin_write_CNT_STATUS(val) bfin_write16(CNT_STATUS, val) -#define bfin_read_CNT_COMMAND() bfin_read16(CNT_COMMAND) -#define bfin_write_CNT_COMMAND(val) bfin_write16(CNT_COMMAND, val) -#define bfin_read_CNT_DEBOUNCE() bfin_read16(CNT_DEBOUNCE) -#define bfin_write_CNT_DEBOUNCE(val) bfin_write16(CNT_DEBOUNCE, val) -#define bfin_read_CNT_COUNTER() bfin_read32(CNT_COUNTER) -#define bfin_write_CNT_COUNTER(val) bfin_write32(CNT_COUNTER, val) -#define bfin_read_CNT_MAX() bfin_read32(CNT_MAX) -#define bfin_write_CNT_MAX(val) bfin_write32(CNT_MAX, val) -#define bfin_read_CNT_MIN() bfin_read32(CNT_MIN) -#define bfin_write_CNT_MIN(val) bfin_write32(CNT_MIN, val) - -/* RSI Register */ -#define bfin_read_RSI_CLK_CTL() bfin_read16(RSI_CLK_CONTROL) -#define bfin_write_RSI_CLK_CTL(val) bfin_write16(RSI_CLK_CONTROL, val) -#define bfin_read_RSI_ARGUMENT() bfin_read32(RSI_ARGUMENT) -#define bfin_write_RSI_ARGUMENT(val) bfin_write32(RSI_ARGUMENT, val) -#define bfin_read_RSI_COMMAND() bfin_read16(RSI_COMMAND) -#define bfin_write_RSI_COMMAND(val) bfin_write16(RSI_COMMAND, val) -#define bfin_read_RSI_RESP_CMD() bfin_read16(RSI_RESP_CMD) -#define bfin_write_RSI_RESP_CMD(val) bfin_write16(RSI_RESP_CMD, val) -#define bfin_read_RSI_RESPONSE0() bfin_read32(RSI_RESPONSE0) -#define bfin_write_RSI_RESPONSE0(val) bfin_write32(RSI_RESPONSE0, val) -#define bfin_read_RSI_RESPONSE1() bfin_read32(RSI_RESPONSE1) -#define bfin_write_RSI_RESPONSE1(val) bfin_write32(RSI_RESPONSE1, val) -#define bfin_read_RSI_RESPONSE2() bfin_read32(RSI_RESPONSE2) -#define bfin_write_RSI_RESPONSE2(val) bfin_write32(RSI_RESPONSE2, val) -#define bfin_read_RSI_RESPONSE3() bfin_read32(RSI_RESPONSE3) -#define bfin_write_RSI_RESPONSE3(val) bfin_write32(RSI_RESPONSE3, val) -#define bfin_read_RSI_DATA_TIMER() bfin_read32(RSI_DATA_TIMER) -#define bfin_write_RSI_DATA_TIMER(val) bfin_write32(RSI_DATA_TIMER, val) -#define bfin_read_RSI_DATA_LGTH() bfin_read16(RSI_DATA_LGTH) -#define bfin_write_RSI_DATA_LGTH(val) bfin_write16(RSI_DATA_LGTH, val) -#define bfin_read_RSI_DATA_CTL() bfin_read16(RSI_DATA_CONTROL) -#define bfin_write_RSI_DATA_CTL(val) bfin_write16(RSI_DATA_CONTROL, val) -#define bfin_read_RSI_DATA_CNT() bfin_read16(RSI_DATA_CNT) -#define bfin_write_RSI_DATA_CNT(val) bfin_write16(RSI_DATA_CNT, val) -#define bfin_read_RSI_STATUS() bfin_read32(RSI_STATUS) -#define bfin_write_RSI_STATUS(val) bfin_write32(RSI_STATUS, val) -#define bfin_read_RSI_STATUS_CLR() bfin_read16(RSI_STATUSCL) -#define bfin_write_RSI_STATUS_CLR(val) bfin_write16(RSI_STATUSCL, val) -#define bfin_read_RSI_MASK0() bfin_read32(RSI_MASK0) -#define bfin_write_RSI_MASK0(val) bfin_write32(RSI_MASK0, val) -#define bfin_read_RSI_MASK1() bfin_read32(RSI_MASK1) -#define bfin_write_RSI_MASK1(val) bfin_write32(RSI_MASK1, val) -#define bfin_read_RSI_FIFO_CNT() bfin_read16(RSI_FIFO_CNT) -#define bfin_write_RSI_FIFO_CNT(val) bfin_write16(RSI_FIFO_CNT, val) -#define bfin_read_RSI_CEATA_CONTROL() bfin_read16(RSI_CEATA_CONTROL) -#define bfin_write_RSI_CEATA_CONTROL(val) bfin_write16(RSI_CEATA_CONTROL, val) -#define bfin_read_RSI_BLKSZ() bfin_read16(RSI_BLKSZ) -#define bfin_write_RSI_BLKSZ(val) bfin_write16(RSI_BLKSZ, val) -#define bfin_read_RSI_FIFO() bfin_read32(RSI_FIFO) -#define bfin_write_RSI_FIFO(val) bfin_write32(RSI_FIFO, val) -#define bfin_read_RSI_E_STATUS() bfin_read32(RSI_ESTAT) -#define bfin_write_RSI_E_STATUS(val) bfin_write32(RSI_ESTAT, val) -#define bfin_read_RSI_E_MASK() bfin_read32(RSI_EMASK) -#define bfin_write_RSI_E_MASK(val) bfin_write32(RSI_EMASK, val) -#define bfin_read_RSI_CFG() bfin_read16(RSI_CONFIG) -#define bfin_write_RSI_CFG(val) bfin_write16(RSI_CONFIG, val) -#define bfin_read_RSI_RD_WAIT_EN() bfin_read16(RSI_RD_WAIT_EN) -#define bfin_write_RSI_RD_WAIT_EN(val) bfin_write16(RSI_RD_WAIT_EN, val) -#define bfin_read_RSI_PID0() bfin_read16(RSI_PID0) -#define bfin_write_RSI_PID0(val) bfin_write16(RSI_PID0, val) -#define bfin_read_RSI_PID1() bfin_read16(RSI_PID1) -#define bfin_write_RSI_PID1(val) bfin_write16(RSI_PID1, val) -#define bfin_read_RSI_PID2() bfin_read16(RSI_PID2) -#define bfin_write_RSI_PID2(val) bfin_write16(RSI_PID2, val) -#define bfin_read_RSI_PID3() bfin_read16(RSI_PID3) -#define bfin_write_RSI_PID3(val) bfin_write16(RSI_PID3, val) - -/* usb register */ -#define bfin_read_USB_PLLOSC_CTRL() bfin_read16(USB_PLL_OSC) -#define bfin_write_USB_PLLOSC_CTRL(val) bfin_write16(USB_PLL_OSC, val) -#define bfin_write_USB_VBUS_CTL(val) bfin_write8(USB_VBUS_CTL, val) -#define bfin_write_USB_APHY_CNTRL(val) bfin_write8(USB_PHY_CTL, val) -#define bfin_read_USB_APHY_CNTRL() bfin_read8(USB_PHY_CTL) - -#endif /* _CDEF_BF60X_H */ - diff --git a/trunk/arch/blackfin/mach-bf609/include/mach/defBF609.h b/trunk/arch/blackfin/mach-bf609/include/mach/defBF609.h deleted file mode 100644 index 19690cc42113..000000000000 --- a/trunk/arch/blackfin/mach-bf609/include/mach/defBF609.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the Clear BSD license or the GPL-2 (or later) - */ - -#ifndef _DEF_BF609_H -#define _DEF_BF609_H - -/* Include defBF60x_base.h for the set of #defines that are common to all ADSP-BF60x processors */ -#include "defBF60x_base.h" - -/* The following are the #defines needed by ADSP-BF609 that are not in the common header */ - -#endif /* _DEF_BF609_H */ diff --git a/trunk/arch/blackfin/mach-bf609/include/mach/defBF60x_base.h b/trunk/arch/blackfin/mach-bf609/include/mach/defBF60x_base.h deleted file mode 100644 index 6aac38544cc9..000000000000 --- a/trunk/arch/blackfin/mach-bf609/include/mach/defBF60x_base.h +++ /dev/null @@ -1,3587 +0,0 @@ -/* - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the Clear BSD license or the GPL-2 (or later) - */ - -#ifndef _DEF_BF60X_H -#define _DEF_BF60X_H - - -/* ************************************************************** */ -/* SYSTEM & MMR ADDRESS DEFINITIONS COMMON TO ALL ADSP-BF60x */ -/* ************************************************************** */ - - -/* ========================= - CNT Registers - ========================= */ - -/* ========================= - CNT0 - ========================= */ -#define CNT_CONFIG 0xFFC00400 /* CNT0 Configuration Register */ -#define CNT_IMASK 0xFFC00404 /* CNT0 Interrupt Mask Register */ -#define CNT_STATUS 0xFFC00408 /* CNT0 Status Register */ -#define CNT_COMMAND 0xFFC0040C /* CNT0 Command Register */ -#define CNT_DEBOUNCE 0xFFC00410 /* CNT0 Debounce Register */ -#define CNT_COUNTER 0xFFC00414 /* CNT0 Counter Register */ -#define CNT_MAX 0xFFC00418 /* CNT0 Maximum Count Register */ -#define CNT_MIN 0xFFC0041C /* CNT0 Minimum Count Register */ - - -/* ========================= - RSI Registers - ========================= */ - -#define RSI_CLK_CONTROL 0xFFC00604 /* RSI0 Clock Control Register */ -#define RSI_ARGUMENT 0xFFC00608 /* RSI0 Argument Register */ -#define RSI_COMMAND 0xFFC0060C /* RSI0 Command Register */ -#define RSI_RESP_CMD 0xFFC00610 /* RSI0 Response Command Register */ -#define RSI_RESPONSE0 0xFFC00614 /* RSI0 Response 0 Register */ -#define RSI_RESPONSE1 0xFFC00618 /* RSI0 Response 1 Register */ -#define RSI_RESPONSE2 0xFFC0061C /* RSI0 Response 2 Register */ -#define RSI_RESPONSE3 0xFFC00620 /* RSI0 Response 3 Register */ -#define RSI_DATA_TIMER 0xFFC00624 /* RSI0 Data Timer Register */ -#define RSI_DATA_LGTH 0xFFC00628 /* RSI0 Data Length Register */ -#define RSI_DATA_CONTROL 0xFFC0062C /* RSI0 Data Control Register */ -#define RSI_DATA_CNT 0xFFC00630 /* RSI0 Data Count Register */ -#define RSI_STATUS 0xFFC00634 /* RSI0 Status Register */ -#define RSI_STATUSCL 0xFFC00638 /* RSI0 Status Clear Register */ -#define RSI_MASK0 0xFFC0063C /* RSI0 Interrupt 0 Mask Register */ -#define RSI_MASK1 0xFFC00640 /* RSI0 Interrupt 1 Mask Register */ -#define RSI_FIFO_CNT 0xFFC00648 /* RSI0 FIFO Counter Register */ -#define RSI_CEATA_CONTROL 0xFFC0064C /* RSI0 This register contains bit to dis CCS gen */ -#define RSI_BOOT_TCNTR 0xFFC00650 /* RSI0 Boot Timing Counter Register */ -#define RSI_BACK_TOUT 0xFFC00654 /* RSI0 Boot Acknowledge Timeout Register */ -#define RSI_SLP_WKUP_TOUT 0xFFC00658 /* RSI0 Sleep Wakeup Timeout Register */ -#define RSI_BLKSZ 0xFFC0065C /* RSI0 Block Size Register */ -#define RSI_FIFO 0xFFC00680 /* RSI0 Data FIFO Register */ -#define RSI_ESTAT 0xFFC006C0 /* RSI0 Exception Status Register */ -#define RSI_EMASK 0xFFC006C4 /* RSI0 Exception Mask Register */ -#define RSI_CONFIG 0xFFC006C8 /* RSI0 Configuration Register */ -#define RSI_RD_WAIT_EN 0xFFC006CC /* RSI0 Read Wait Enable Register */ -#define RSI_PID0 0xFFC006D0 /* RSI0 Peripheral Identification Register */ -#define RSI_PID1 0xFFC006D4 /* RSI0 Peripheral Identification Register */ -#define RSI_PID2 0xFFC006D8 /* RSI0 Peripheral Identification Register */ -#define RSI_PID3 0xFFC006DC /* RSI0 Peripheral Identification Register */ - -/* ========================= - CAN Registers - ========================= */ - -/* ========================= - CAN0 - ========================= */ -#define CAN0_MC1 0xFFC00A00 /* CAN0 Mailbox Configuration Register 1 */ -#define CAN0_MD1 0xFFC00A04 /* CAN0 Mailbox Direction Register 1 */ -#define CAN0_TRS1 0xFFC00A08 /* CAN0 Transmission Request Set Register 1 */ -#define CAN0_TRR1 0xFFC00A0C /* CAN0 Transmission Request Reset Register 1 */ -#define CAN0_TA1 0xFFC00A10 /* CAN0 Transmission Acknowledge Register 1 */ -#define CAN0_AA1 0xFFC00A14 /* CAN0 Abort Acknowledge Register 1 */ -#define CAN0_RMP1 0xFFC00A18 /* CAN0 Receive Message Pending Register 1 */ -#define CAN0_RML1 0xFFC00A1C /* CAN0 Receive Message Lost Register 1 */ -#define CAN0_MBTIF1 0xFFC00A20 /* CAN0 Mailbox Transmit Interrupt Flag Register 1 */ -#define CAN0_MBRIF1 0xFFC00A24 /* CAN0 Mailbox Receive Interrupt Flag Register 1 */ -#define CAN0_MBIM1 0xFFC00A28 /* CAN0 Mailbox Interrupt Mask Register 1 */ -#define CAN0_RFH1 0xFFC00A2C /* CAN0 Remote Frame Handling Register 1 */ -#define CAN0_OPSS1 0xFFC00A30 /* CAN0 Overwrite Protection/Single Shot Transmission Register 1 */ -#define CAN0_MC2 0xFFC00A40 /* CAN0 Mailbox Configuration Register 2 */ -#define CAN0_MD2 0xFFC00A44 /* CAN0 Mailbox Direction Register 2 */ -#define CAN0_TRS2 0xFFC00A48 /* CAN0 Transmission Request Set Register 2 */ -#define CAN0_TRR2 0xFFC00A4C /* CAN0 Transmission Request Reset Register 2 */ -#define CAN0_TA2 0xFFC00A50 /* CAN0 Transmission Acknowledge Register 2 */ -#define CAN0_AA2 0xFFC00A54 /* CAN0 Abort Acknowledge Register 2 */ -#define CAN0_RMP2 0xFFC00A58 /* CAN0 Receive Message Pending Register 2 */ -#define CAN0_RML2 0xFFC00A5C /* CAN0 Receive Message Lost Register 2 */ -#define CAN0_MBTIF2 0xFFC00A60 /* CAN0 Mailbox Transmit Interrupt Flag Register 2 */ -#define CAN0_MBRIF2 0xFFC00A64 /* CAN0 Mailbox Receive Interrupt Flag Register 2 */ -#define CAN0_MBIM2 0xFFC00A68 /* CAN0 Mailbox Interrupt Mask Register 2 */ -#define CAN0_RFH2 0xFFC00A6C /* CAN0 Remote Frame Handling Register 2 */ -#define CAN0_OPSS2 0xFFC00A70 /* CAN0 Overwrite Protection/Single Shot Transmission Register 2 */ -#define CAN0_CLOCK 0xFFC00A80 /* CAN0 Clock Register */ -#define CAN0_TIMING 0xFFC00A84 /* CAN0 Timing Register */ -#define CAN0_DEBUG 0xFFC00A88 /* CAN0 Debug Register */ -#define CAN0_STATUS 0xFFC00A8C /* CAN0 Status Register */ -#define CAN0_CEC 0xFFC00A90 /* CAN0 Error Counter Register */ -#define CAN0_GIS 0xFFC00A94 /* CAN0 Global CAN Interrupt Status */ -#define CAN0_GIM 0xFFC00A98 /* CAN0 Global CAN Interrupt Mask */ -#define CAN0_GIF 0xFFC00A9C /* CAN0 Global CAN Interrupt Flag */ -#define CAN0_CONTROL 0xFFC00AA0 /* CAN0 CAN Master Control Register */ -#define CAN0_INTR 0xFFC00AA4 /* CAN0 Interrupt Pending Register */ -#define CAN0_MBTD 0xFFC00AAC /* CAN0 Temporary Mailbox Disable Register */ -#define CAN0_EWR 0xFFC00AB0 /* CAN0 Error Counter Warning Level Register */ -#define CAN0_ESR 0xFFC00AB4 /* CAN0 Error Status Register */ -#define CAN0_UCCNT 0xFFC00AC4 /* CAN0 Universal Counter Register */ -#define CAN0_UCRC 0xFFC00AC8 /* CAN0 Universal Counter Reload/Capture Register */ -#define CAN0_UCCNF 0xFFC00ACC /* CAN0 Universal Counter Configuration Mode Register */ -#define CAN0_AM00L 0xFFC00B00 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM01L 0xFFC00B08 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM02L 0xFFC00B10 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM03L 0xFFC00B18 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM04L 0xFFC00B20 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM05L 0xFFC00B28 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM06L 0xFFC00B30 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM07L 0xFFC00B38 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM08L 0xFFC00B40 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM09L 0xFFC00B48 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM10L 0xFFC00B50 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM11L 0xFFC00B58 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM12L 0xFFC00B60 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM13L 0xFFC00B68 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM14L 0xFFC00B70 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM15L 0xFFC00B78 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM16L 0xFFC00B80 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM17L 0xFFC00B88 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM18L 0xFFC00B90 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM19L 0xFFC00B98 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM20L 0xFFC00BA0 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM21L 0xFFC00BA8 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM22L 0xFFC00BB0 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM23L 0xFFC00BB8 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM24L 0xFFC00BC0 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM25L 0xFFC00BC8 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM26L 0xFFC00BD0 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM27L 0xFFC00BD8 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM28L 0xFFC00BE0 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM29L 0xFFC00BE8 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM30L 0xFFC00BF0 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM31L 0xFFC00BF8 /* CAN0 Acceptance Mask Register (L) */ -#define CAN0_AM00H 0xFFC00B04 /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM01H 0xFFC00B0C /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM02H 0xFFC00B14 /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM03H 0xFFC00B1C /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM04H 0xFFC00B24 /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM05H 0xFFC00B2C /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM06H 0xFFC00B34 /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM07H 0xFFC00B3C /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM08H 0xFFC00B44 /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM09H 0xFFC00B4C /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM10H 0xFFC00B54 /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM11H 0xFFC00B5C /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM12H 0xFFC00B64 /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM13H 0xFFC00B6C /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM14H 0xFFC00B74 /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM15H 0xFFC00B7C /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM16H 0xFFC00B84 /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM17H 0xFFC00B8C /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM18H 0xFFC00B94 /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM19H 0xFFC00B9C /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM20H 0xFFC00BA4 /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM21H 0xFFC00BAC /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM22H 0xFFC00BB4 /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM23H 0xFFC00BBC /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM24H 0xFFC00BC4 /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM25H 0xFFC00BCC /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM26H 0xFFC00BD4 /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM27H 0xFFC00BDC /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM28H 0xFFC00BE4 /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM29H 0xFFC00BEC /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM30H 0xFFC00BF4 /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_AM31H 0xFFC00BFC /* CAN0 Acceptance Mask Register (H) */ -#define CAN0_MB00_DATA0 0xFFC00C00 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB01_DATA0 0xFFC00C20 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB02_DATA0 0xFFC00C40 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB03_DATA0 0xFFC00C60 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB04_DATA0 0xFFC00C80 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB05_DATA0 0xFFC00CA0 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB06_DATA0 0xFFC00CC0 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB07_DATA0 0xFFC00CE0 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB08_DATA0 0xFFC00D00 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB09_DATA0 0xFFC00D20 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB10_DATA0 0xFFC00D40 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB11_DATA0 0xFFC00D60 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB12_DATA0 0xFFC00D80 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB13_DATA0 0xFFC00DA0 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB14_DATA0 0xFFC00DC0 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB15_DATA0 0xFFC00DE0 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB16_DATA0 0xFFC00E00 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB17_DATA0 0xFFC00E20 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB18_DATA0 0xFFC00E40 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB19_DATA0 0xFFC00E60 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB20_DATA0 0xFFC00E80 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB21_DATA0 0xFFC00EA0 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB22_DATA0 0xFFC00EC0 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB23_DATA0 0xFFC00EE0 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB24_DATA0 0xFFC00F00 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB25_DATA0 0xFFC00F20 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB26_DATA0 0xFFC00F40 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB27_DATA0 0xFFC00F60 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB28_DATA0 0xFFC00F80 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB29_DATA0 0xFFC00FA0 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB30_DATA0 0xFFC00FC0 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB31_DATA0 0xFFC00FE0 /* CAN0 Mailbox Word 0 Register */ -#define CAN0_MB00_DATA1 0xFFC00C04 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB01_DATA1 0xFFC00C24 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB02_DATA1 0xFFC00C44 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB03_DATA1 0xFFC00C64 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB04_DATA1 0xFFC00C84 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB05_DATA1 0xFFC00CA4 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB06_DATA1 0xFFC00CC4 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB07_DATA1 0xFFC00CE4 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB08_DATA1 0xFFC00D04 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB09_DATA1 0xFFC00D24 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB10_DATA1 0xFFC00D44 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB11_DATA1 0xFFC00D64 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB12_DATA1 0xFFC00D84 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB13_DATA1 0xFFC00DA4 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB14_DATA1 0xFFC00DC4 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB15_DATA1 0xFFC00DE4 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB16_DATA1 0xFFC00E04 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB17_DATA1 0xFFC00E24 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB18_DATA1 0xFFC00E44 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB19_DATA1 0xFFC00E64 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB20_DATA1 0xFFC00E84 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB21_DATA1 0xFFC00EA4 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB22_DATA1 0xFFC00EC4 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB23_DATA1 0xFFC00EE4 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB24_DATA1 0xFFC00F04 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB25_DATA1 0xFFC00F24 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB26_DATA1 0xFFC00F44 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB27_DATA1 0xFFC00F64 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB28_DATA1 0xFFC00F84 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB29_DATA1 0xFFC00FA4 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB30_DATA1 0xFFC00FC4 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB31_DATA1 0xFFC00FE4 /* CAN0 Mailbox Word 1 Register */ -#define CAN0_MB00_DATA2 0xFFC00C08 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB01_DATA2 0xFFC00C28 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB02_DATA2 0xFFC00C48 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB03_DATA2 0xFFC00C68 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB04_DATA2 0xFFC00C88 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB05_DATA2 0xFFC00CA8 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB06_DATA2 0xFFC00CC8 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB07_DATA2 0xFFC00CE8 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB08_DATA2 0xFFC00D08 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB09_DATA2 0xFFC00D28 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB10_DATA2 0xFFC00D48 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB11_DATA2 0xFFC00D68 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB12_DATA2 0xFFC00D88 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB13_DATA2 0xFFC00DA8 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB14_DATA2 0xFFC00DC8 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB15_DATA2 0xFFC00DE8 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB16_DATA2 0xFFC00E08 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB17_DATA2 0xFFC00E28 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB18_DATA2 0xFFC00E48 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB19_DATA2 0xFFC00E68 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB20_DATA2 0xFFC00E88 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB21_DATA2 0xFFC00EA8 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB22_DATA2 0xFFC00EC8 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB23_DATA2 0xFFC00EE8 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB24_DATA2 0xFFC00F08 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB25_DATA2 0xFFC00F28 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB26_DATA2 0xFFC00F48 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB27_DATA2 0xFFC00F68 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB28_DATA2 0xFFC00F88 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB29_DATA2 0xFFC00FA8 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB30_DATA2 0xFFC00FC8 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB31_DATA2 0xFFC00FE8 /* CAN0 Mailbox Word 2 Register */ -#define CAN0_MB00_DATA3 0xFFC00C0C /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB01_DATA3 0xFFC00C2C /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB02_DATA3 0xFFC00C4C /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB03_DATA3 0xFFC00C6C /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB04_DATA3 0xFFC00C8C /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB05_DATA3 0xFFC00CAC /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB06_DATA3 0xFFC00CCC /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB07_DATA3 0xFFC00CEC /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB08_DATA3 0xFFC00D0C /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB09_DATA3 0xFFC00D2C /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB10_DATA3 0xFFC00D4C /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB11_DATA3 0xFFC00D6C /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB12_DATA3 0xFFC00D8C /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB13_DATA3 0xFFC00DAC /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB14_DATA3 0xFFC00DCC /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB15_DATA3 0xFFC00DEC /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB16_DATA3 0xFFC00E0C /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB17_DATA3 0xFFC00E2C /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB18_DATA3 0xFFC00E4C /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB19_DATA3 0xFFC00E6C /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB20_DATA3 0xFFC00E8C /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB21_DATA3 0xFFC00EAC /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB22_DATA3 0xFFC00ECC /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB23_DATA3 0xFFC00EEC /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB24_DATA3 0xFFC00F0C /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB25_DATA3 0xFFC00F2C /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB26_DATA3 0xFFC00F4C /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB27_DATA3 0xFFC00F6C /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB28_DATA3 0xFFC00F8C /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB29_DATA3 0xFFC00FAC /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB30_DATA3 0xFFC00FCC /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB31_DATA3 0xFFC00FEC /* CAN0 Mailbox Word 3 Register */ -#define CAN0_MB00_LENGTH 0xFFC00C10 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB01_LENGTH 0xFFC00C30 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB02_LENGTH 0xFFC00C50 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB03_LENGTH 0xFFC00C70 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB04_LENGTH 0xFFC00C90 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB05_LENGTH 0xFFC00CB0 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB06_LENGTH 0xFFC00CD0 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB07_LENGTH 0xFFC00CF0 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB08_LENGTH 0xFFC00D10 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB09_LENGTH 0xFFC00D30 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB10_LENGTH 0xFFC00D50 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB11_LENGTH 0xFFC00D70 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB12_LENGTH 0xFFC00D90 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB13_LENGTH 0xFFC00DB0 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB14_LENGTH 0xFFC00DD0 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB15_LENGTH 0xFFC00DF0 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB16_LENGTH 0xFFC00E10 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB17_LENGTH 0xFFC00E30 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB18_LENGTH 0xFFC00E50 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB19_LENGTH 0xFFC00E70 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB20_LENGTH 0xFFC00E90 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB21_LENGTH 0xFFC00EB0 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB22_LENGTH 0xFFC00ED0 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB23_LENGTH 0xFFC00EF0 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB24_LENGTH 0xFFC00F10 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB25_LENGTH 0xFFC00F30 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB26_LENGTH 0xFFC00F50 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB27_LENGTH 0xFFC00F70 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB28_LENGTH 0xFFC00F90 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB29_LENGTH 0xFFC00FB0 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB30_LENGTH 0xFFC00FD0 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB31_LENGTH 0xFFC00FF0 /* CAN0 Mailbox Word 4 Register */ -#define CAN0_MB00_TIMESTAMP 0xFFC00C14 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB01_TIMESTAMP 0xFFC00C34 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB02_TIMESTAMP 0xFFC00C54 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB03_TIMESTAMP 0xFFC00C74 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB04_TIMESTAMP 0xFFC00C94 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB05_TIMESTAMP 0xFFC00CB4 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB06_TIMESTAMP 0xFFC00CD4 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB07_TIMESTAMP 0xFFC00CF4 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB08_TIMESTAMP 0xFFC00D14 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB09_TIMESTAMP 0xFFC00D34 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB10_TIMESTAMP 0xFFC00D54 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB11_TIMESTAMP 0xFFC00D74 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB12_TIMESTAMP 0xFFC00D94 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB13_TIMESTAMP 0xFFC00DB4 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB14_TIMESTAMP 0xFFC00DD4 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB15_TIMESTAMP 0xFFC00DF4 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB16_TIMESTAMP 0xFFC00E14 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB17_TIMESTAMP 0xFFC00E34 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB18_TIMESTAMP 0xFFC00E54 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB19_TIMESTAMP 0xFFC00E74 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB20_TIMESTAMP 0xFFC00E94 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB21_TIMESTAMP 0xFFC00EB4 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB22_TIMESTAMP 0xFFC00ED4 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB23_TIMESTAMP 0xFFC00EF4 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB24_TIMESTAMP 0xFFC00F14 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB25_TIMESTAMP 0xFFC00F34 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB26_TIMESTAMP 0xFFC00F54 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB27_TIMESTAMP 0xFFC00F74 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB28_TIMESTAMP 0xFFC00F94 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB29_TIMESTAMP 0xFFC00FB4 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB30_TIMESTAMP 0xFFC00FD4 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB31_TIMESTAMP 0xFFC00FF4 /* CAN0 Mailbox Word 5 Register */ -#define CAN0_MB00_ID0 0xFFC00C18 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB01_ID0 0xFFC00C38 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB02_ID0 0xFFC00C58 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB03_ID0 0xFFC00C78 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB04_ID0 0xFFC00C98 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB05_ID0 0xFFC00CB8 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB06_ID0 0xFFC00CD8 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB07_ID0 0xFFC00CF8 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB08_ID0 0xFFC00D18 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB09_ID0 0xFFC00D38 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB10_ID0 0xFFC00D58 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB11_ID0 0xFFC00D78 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB12_ID0 0xFFC00D98 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB13_ID0 0xFFC00DB8 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB14_ID0 0xFFC00DD8 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB15_ID0 0xFFC00DF8 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB16_ID0 0xFFC00E18 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB17_ID0 0xFFC00E38 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB18_ID0 0xFFC00E58 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB19_ID0 0xFFC00E78 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB20_ID0 0xFFC00E98 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB21_ID0 0xFFC00EB8 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB22_ID0 0xFFC00ED8 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB23_ID0 0xFFC00EF8 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB24_ID0 0xFFC00F18 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB25_ID0 0xFFC00F38 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB26_ID0 0xFFC00F58 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB27_ID0 0xFFC00F78 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB28_ID0 0xFFC00F98 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB29_ID0 0xFFC00FB8 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB30_ID0 0xFFC00FD8 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB31_ID0 0xFFC00FF8 /* CAN0 Mailbox Word 6 Register */ -#define CAN0_MB00_ID1 0xFFC00C1C /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB01_ID1 0xFFC00C3C /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB02_ID1 0xFFC00C5C /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB03_ID1 0xFFC00C7C /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB04_ID1 0xFFC00C9C /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB05_ID1 0xFFC00CBC /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB06_ID1 0xFFC00CDC /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB07_ID1 0xFFC00CFC /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB08_ID1 0xFFC00D1C /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB09_ID1 0xFFC00D3C /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB10_ID1 0xFFC00D5C /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB11_ID1 0xFFC00D7C /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB12_ID1 0xFFC00D9C /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB13_ID1 0xFFC00DBC /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB14_ID1 0xFFC00DDC /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB15_ID1 0xFFC00DFC /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB16_ID1 0xFFC00E1C /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB17_ID1 0xFFC00E3C /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB18_ID1 0xFFC00E5C /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB19_ID1 0xFFC00E7C /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB20_ID1 0xFFC00E9C /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB21_ID1 0xFFC00EBC /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB22_ID1 0xFFC00EDC /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB23_ID1 0xFFC00EFC /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB24_ID1 0xFFC00F1C /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB25_ID1 0xFFC00F3C /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB26_ID1 0xFFC00F5C /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB27_ID1 0xFFC00F7C /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB28_ID1 0xFFC00F9C /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB29_ID1 0xFFC00FBC /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB30_ID1 0xFFC00FDC /* CAN0 Mailbox Word 7 Register */ -#define CAN0_MB31_ID1 0xFFC00FFC /* CAN0 Mailbox Word 7 Register */ - -/* ========================= - LINK PORT Registers - ========================= */ -#define LP0_CTL 0xFFC01000 /* LP0 Control Register */ -#define LP0_STAT 0xFFC01004 /* LP0 Status Register */ -#define LP0_DIV 0xFFC01008 /* LP0 Clock Divider Value */ -#define LP0_CNT 0xFFC0100C /* LP0 Current Count Value of Clock Divider */ -#define LP0_TX 0xFFC01010 /* LP0 Transmit Buffer */ -#define LP0_RX 0xFFC01014 /* LP0 Receive Buffer */ -#define LP0_TXIN_SHDW 0xFFC01018 /* LP0 Shadow Input Transmit Buffer */ -#define LP0_TXOUT_SHDW 0xFFC0101C /* LP0 Shadow Output Transmit Buffer */ -#define LP1_CTL 0xFFC01100 /* LP1 Control Register */ -#define LP1_STAT 0xFFC01104 /* LP1 Status Register */ -#define LP1_DIV 0xFFC01108 /* LP1 Clock Divider Value */ -#define LP1_CNT 0xFFC0110C /* LP1 Current Count Value of Clock Divider */ -#define LP1_TX 0xFFC01110 /* LP1 Transmit Buffer */ -#define LP1_RX 0xFFC01114 /* LP1 Receive Buffer */ -#define LP1_TXIN_SHDW 0xFFC01118 /* LP1 Shadow Input Transmit Buffer */ -#define LP1_TXOUT_SHDW 0xFFC0111C /* LP1 Shadow Output Transmit Buffer */ -#define LP2_CTL 0xFFC01200 /* LP2 Control Register */ -#define LP2_STAT 0xFFC01204 /* LP2 Status Register */ -#define LP2_DIV 0xFFC01208 /* LP2 Clock Divider Value */ -#define LP2_CNT 0xFFC0120C /* LP2 Current Count Value of Clock Divider */ -#define LP2_TX 0xFFC01210 /* LP2 Transmit Buffer */ -#define LP2_RX 0xFFC01214 /* LP2 Receive Buffer */ -#define LP2_TXIN_SHDW 0xFFC01218 /* LP2 Shadow Input Transmit Buffer */ -#define LP2_TXOUT_SHDW 0xFFC0121C /* LP2 Shadow Output Transmit Buffer */ -#define LP3_CTL 0xFFC01300 /* LP3 Control Register */ -#define LP3_STAT 0xFFC01304 /* LP3 Status Register */ -#define LP3_DIV 0xFFC01308 /* LP3 Clock Divider Value */ -#define LP3_CNT 0xFFC0130C /* LP3 Current Count Value of Clock Divider */ -#define LP3_TX 0xFFC01310 /* LP3 Transmit Buffer */ -#define LP3_RX 0xFFC01314 /* LP3 Receive Buffer */ -#define LP3_TXIN_SHDW 0xFFC01318 /* LP3 Shadow Input Transmit Buffer */ -#define LP3_TXOUT_SHDW 0xFFC0131C /* LP3 Shadow Output Transmit Buffer */ - -/* ========================= - TIMER Registers - ========================= */ -#define TIMER_REVID 0xFFC01400 /* GPTIMER Timer IP Version ID */ -#define TIMER_RUN 0xFFC01404 /* GPTIMER Timer Run Register */ -#define TIMER_RUN_SET 0xFFC01408 /* GPTIMER Run Register Alias to Set */ -#define TIMER_RUN_CLR 0xFFC0140C /* GPTIMER Run Register Alias to Clear */ -#define TIMER_STOP_CFG 0xFFC01410 /* GPTIMER Stop Config Register */ -#define TIMER_STOP_CFG_SET 0xFFC01414 /* GPTIMER Stop Config Alias to Set */ -#define TIMER_STOP_CFG_CLR 0xFFC01418 /* GPTIMER Stop Config Alias to Clear */ -#define TIMER_DATA_IMSK 0xFFC0141C /* GPTIMER Data Interrupt Mask register */ -#define TIMER_STAT_IMSK 0xFFC01420 /* GPTIMER Status Interrupt Mask register */ -#define TIMER_TRG_MSK 0xFFC01424 /* GPTIMER Output Trigger Mask register */ -#define TIMER_TRG_IE 0xFFC01428 /* GPTIMER Slave Trigger Enable register */ -#define TIMER_DATA_ILAT 0xFFC0142C /* GPTIMER Data Interrupt Register */ -#define TIMER_STAT_ILAT 0xFFC01430 /* GPTIMER Status (Error) Interrupt Register */ -#define TIMER_ERR_TYPE 0xFFC01434 /* GPTIMER Register Indicating Type of Error */ -#define TIMER_BCAST_PER 0xFFC01438 /* GPTIMER Broadcast Period */ -#define TIMER_BCAST_WID 0xFFC0143C /* GPTIMER Broadcast Width */ -#define TIMER_BCAST_DLY 0xFFC01440 /* GPTIMER Broadcast Delay */ - -/* ========================= - TIMER0~7 - ========================= */ -#define TIMER0_CONFIG 0xFFC01460 /* TIMER0 Per Timer Config Register */ -#define TIMER0_COUNTER 0xFFC01464 /* TIMER0 Per Timer Counter Register */ -#define TIMER0_PERIOD 0xFFC01468 /* TIMER0 Per Timer Period Register */ -#define TIMER0_WIDTH 0xFFC0146C /* TIMER0 Per Timer Width Register */ -#define TIMER0_DELAY 0xFFC01470 /* TIMER0 Per Timer Delay Register */ - -#define TIMER1_CONFIG 0xFFC01480 /* TIMER1 Per Timer Config Register */ -#define TIMER1_COUNTER 0xFFC01484 /* TIMER1 Per Timer Counter Register */ -#define TIMER1_PERIOD 0xFFC01488 /* TIMER1 Per Timer Period Register */ -#define TIMER1_WIDTH 0xFFC0148C /* TIMER1 Per Timer Width Register */ -#define TIMER1_DELAY 0xFFC01490 /* TIMER1 Per Timer Delay Register */ - -#define TIMER2_CONFIG 0xFFC014A0 /* TIMER2 Per Timer Config Register */ -#define TIMER2_COUNTER 0xFFC014A4 /* TIMER2 Per Timer Counter Register */ -#define TIMER2_PERIOD 0xFFC014A8 /* TIMER2 Per Timer Period Register */ -#define TIMER2_WIDTH 0xFFC014AC /* TIMER2 Per Timer Width Register */ -#define TIMER2_DELAY 0xFFC014B0 /* TIMER2 Per Timer Delay Register */ - -#define TIMER3_CONFIG 0xFFC014C0 /* TIMER3 Per Timer Config Register */ -#define TIMER3_COUNTER 0xFFC014C4 /* TIMER3 Per Timer Counter Register */ -#define TIMER3_PERIOD 0xFFC014C8 /* TIMER3 Per Timer Period Register */ -#define TIMER3_WIDTH 0xFFC014CC /* TIMER3 Per Timer Width Register */ -#define TIMER3_DELAY 0xFFC014D0 /* TIMER3 Per Timer Delay Register */ - -#define TIMER4_CONFIG 0xFFC014E0 /* TIMER4 Per Timer Config Register */ -#define TIMER4_COUNTER 0xFFC014E4 /* TIMER4 Per Timer Counter Register */ -#define TIMER4_PERIOD 0xFFC014E8 /* TIMER4 Per Timer Period Register */ -#define TIMER4_WIDTH 0xFFC014EC /* TIMER4 Per Timer Width Register */ -#define TIMER4_DELAY 0xFFC014F0 /* TIMER4 Per Timer Delay Register */ - -#define TIMER5_CONFIG 0xFFC01500 /* TIMER5 Per Timer Config Register */ -#define TIMER5_COUNTER 0xFFC01504 /* TIMER5 Per Timer Counter Register */ -#define TIMER5_PERIOD 0xFFC01508 /* TIMER5 Per Timer Period Register */ -#define TIMER5_WIDTH 0xFFC0150C /* TIMER5 Per Timer Width Register */ -#define TIMER5_DELAY 0xFFC01510 /* TIMER5 Per Timer Delay Register */ - -#define TIMER6_CONFIG 0xFFC01520 /* TIMER6 Per Timer Config Register */ -#define TIMER6_COUNTER 0xFFC01524 /* TIMER6 Per Timer Counter Register */ -#define TIMER6_PERIOD 0xFFC01528 /* TIMER6 Per Timer Period Register */ -#define TIMER6_WIDTH 0xFFC0152C /* TIMER6 Per Timer Width Register */ -#define TIMER6_DELAY 0xFFC01530 /* TIMER6 Per Timer Delay Register */ - -#define TIMER7_CONFIG 0xFFC01540 /* TIMER7 Per Timer Config Register */ -#define TIMER7_COUNTER 0xFFC01544 /* TIMER7 Per Timer Counter Register */ -#define TIMER7_PERIOD 0xFFC01548 /* TIMER7 Per Timer Period Register */ -#define TIMER7_WIDTH 0xFFC0154C /* TIMER7 Per Timer Width Register */ -#define TIMER7_DELAY 0xFFC01550 /* TIMER7 Per Timer Delay Register */ - -/* ========================= - CRC Registers - ========================= */ - -/* ========================= - CRC0 - ========================= */ -#define REG_CRC0_CTL 0xFFC01C00 /* CRC0 Control Register */ -#define REG_CRC0_DCNT 0xFFC01C04 /* CRC0 Data Word Count Register */ -#define REG_CRC0_DCNTRLD 0xFFC01C08 /* CRC0 Data Word Count Reload Register */ -#define REG_CRC0_COMP 0xFFC01C14 /* CRC0 DATA Compare Register */ -#define REG_CRC0_FILLVAL 0xFFC01C18 /* CRC0 Fill Value Register */ -#define REG_CRC0_DFIFO 0xFFC01C1C /* CRC0 DATA FIFO Register */ -#define REG_CRC0_INEN 0xFFC01C20 /* CRC0 Interrupt Enable Register */ -#define REG_CRC0_INEN_SET 0xFFC01C24 /* CRC0 Interrupt Enable Set Register */ -#define REG_CRC0_INEN_CLR 0xFFC01C28 /* CRC0 Interrupt Enable Clear Register */ -#define REG_CRC0_POLY 0xFFC01C2C /* CRC0 Polynomial Register */ -#define REG_CRC0_STAT 0xFFC01C40 /* CRC0 Status Register */ -#define REG_CRC0_DCNTCAP 0xFFC01C44 /* CRC0 DATA Count Capture Register */ -#define REG_CRC0_RESULT_FIN 0xFFC01C4C /* CRC0 Final CRC Result Register */ -#define REG_CRC0_RESULT_CUR 0xFFC01C50 /* CRC0 Current CRC Result Register */ -#define REG_CRC0_REVID 0xFFC01C60 /* CRC0 Revision ID Register */ - -/* ========================= - CRC1 - ========================= */ -#define REG_CRC1_CTL 0xFFC01D00 /* CRC1 Control Register */ -#define REG_CRC1_DCNT 0xFFC01D04 /* CRC1 Data Word Count Register */ -#define REG_CRC1_DCNTRLD 0xFFC01D08 /* CRC1 Data Word Count Reload Register */ -#define REG_CRC1_COMP 0xFFC01D14 /* CRC1 DATA Compare Register */ -#define REG_CRC1_FILLVAL 0xFFC01D18 /* CRC1 Fill Value Register */ -#define REG_CRC1_DFIFO 0xFFC01D1C /* CRC1 DATA FIFO Register */ -#define REG_CRC1_INEN 0xFFC01D20 /* CRC1 Interrupt Enable Register */ -#define REG_CRC1_INEN_SET 0xFFC01D24 /* CRC1 Interrupt Enable Set Register */ -#define REG_CRC1_INEN_CLR 0xFFC01D28 /* CRC1 Interrupt Enable Clear Register */ -#define REG_CRC1_POLY 0xFFC01D2C /* CRC1 Polynomial Register */ -#define REG_CRC1_STAT 0xFFC01D40 /* CRC1 Status Register */ -#define REG_CRC1_DCNTCAP 0xFFC01D44 /* CRC1 DATA Count Capture Register */ -#define REG_CRC1_RESULT_FIN 0xFFC01D4C /* CRC1 Final CRC Result Register */ -#define REG_CRC1_RESULT_CUR 0xFFC01D50 /* CRC1 Current CRC Result Register */ -#define REG_CRC1_REVID 0xFFC01D60 /* CRC1 Revision ID Register */ - -/* ========================= - TWI Registers - ========================= */ - -/* ========================= - TWI0 - ========================= */ -#define TWI0_CLKDIV 0xFFC01E00 /* TWI0 SCL Clock Divider */ -#define TWI0_CONTROL 0xFFC01E04 /* TWI0 Control Register */ -#define TWI0_SLAVE_CTL 0xFFC01E08 /* TWI0 Slave Mode Control Register */ -#define TWI0_SLAVE_STAT 0xFFC01E0C /* TWI0 Slave Mode Status Register */ -#define TWI0_SLAVE_ADDR 0xFFC01E10 /* TWI0 Slave Mode Address Register */ -#define TWI0_MASTER_CTL 0xFFC01E14 /* TWI0 Master Mode Control Registers */ -#define TWI0_MASTER_STAT 0xFFC01E18 /* TWI0 Master Mode Status Register */ -#define TWI0_MASTER_ADDR 0xFFC01E1C /* TWI0 Master Mode Address Register */ -#define TWI0_INT_STAT 0xFFC01E20 /* TWI0 Interrupt Status Register */ -#define TWI0_INT_MASK 0xFFC01E24 /* TWI0 Interrupt Mask Register */ -#define TWI0_FIFO_CTL 0xFFC01E28 /* TWI0 FIFO Control Register */ -#define TWI0_FIFO_STAT 0xFFC01E2C /* TWI0 FIFO Status Register */ -#define TWI0_XMT_DATA8 0xFFC01E80 /* TWI0 FIFO Transmit Data Single-Byte Register */ -#define TWI0_XMT_DATA16 0xFFC01E84 /* TWI0 FIFO Transmit Data Double-Byte Register */ -#define TWI0_RCV_DATA8 0xFFC01E88 /* TWI0 FIFO Transmit Data Single-Byte Register */ -#define TWI0_RCV_DATA16 0xFFC01E8C /* TWI0 FIFO Transmit Data Double-Byte Register */ - -/* ========================= - TWI1 - ========================= */ -#define TWI1_CLKDIV 0xFFC01F00 /* TWI1 SCL Clock Divider */ -#define TWI1_CONTROL 0xFFC01F04 /* TWI1 Control Register */ -#define TWI1_SLAVE_CTL 0xFFC01F08 /* TWI1 Slave Mode Control Register */ -#define TWI1_SLAVE_STAT 0xFFC01F0C /* TWI1 Slave Mode Status Register */ -#define TWI1_SLAVE_ADDR 0xFFC01F10 /* TWI1 Slave Mode Address Register */ -#define TWI1_MASTER_CTL 0xFFC01F14 /* TWI1 Master Mode Control Registers */ -#define TWI1_MASTER_STAT 0xFFC01F18 /* TWI1 Master Mode Status Register */ -#define TWI1_MASTER_ADDR 0xFFC01F1C /* TWI1 Master Mode Address Register */ -#define TWI1_INT_STAT 0xFFC01F20 /* TWI1 Interrupt Status Register */ -#define TWI1_INT_MASK 0xFFC01F24 /* TWI1 Interrupt Mask Register */ -#define TWI1_FIFO_CTL 0xFFC01F28 /* TWI1 FIFO Control Register */ -#define TWI1_FIFO_STAT 0xFFC01F2C /* TWI1 FIFO Status Register */ -#define TWI1_XMT_DATA8 0xFFC01F80 /* TWI1 FIFO Transmit Data Single-Byte Register */ -#define TWI1_XMT_DATA16 0xFFC01F84 /* TWI1 FIFO Transmit Data Double-Byte Register */ -#define TWI1_RCV_DATA8 0xFFC01F88 /* TWI1 FIFO Transmit Data Single-Byte Register */ -#define TWI1_RCV_DATA16 0xFFC01F8C /* TWI1 FIFO Transmit Data Double-Byte Register */ - - -/* ========================= - UART Registers - ========================= */ - -/* ========================= - UART0 - ========================= */ -#define UART0_REVID 0xFFC02000 /* UART0 Revision ID Register */ -#define UART0_CTL 0xFFC02004 /* UART0 Control Register */ -#define UART0_STAT 0xFFC02008 /* UART0 Status Register */ -#define UART0_SCR 0xFFC0200C /* UART0 Scratch Register */ -#define UART0_CLK 0xFFC02010 /* UART0 Clock Rate Register */ -#define UART0_IER 0xFFC02014 /* UART0 Interrupt Mask Register */ -#define UART0_IER_SET 0xFFC02018 /* UART0 Interrupt Mask Set Register */ -#define UART0_IER_CLR 0xFFC0201C /* UART0 Interrupt Mask Clear Register */ -#define UART0_RBR 0xFFC02020 /* UART0 Receive Buffer Register */ -#define UART0_THR 0xFFC02024 /* UART0 Transmit Hold Register */ -#define UART0_TAIP 0xFFC02028 /* UART0 Transmit Address/Insert Pulse Register */ -#define UART0_TSR 0xFFC0202C /* UART0 Transmit Shift Register */ -#define UART0_RSR 0xFFC02030 /* UART0 Receive Shift Register */ -#define UART0_TXDIV 0xFFC02034 /* UART0 Transmit Clock Devider Register */ -#define UART0_RXDIV 0xFFC02038 /* UART0 Receive Clock Devider Register */ - -/* ========================= - UART1 - ========================= */ -#define UART1_REVID 0xFFC02400 /* UART1 Revision ID Register */ -#define UART1_CTL 0xFFC02404 /* UART1 Control Register */ -#define UART1_STAT 0xFFC02408 /* UART1 Status Register */ -#define UART1_SCR 0xFFC0240C /* UART1 Scratch Register */ -#define UART1_CLK 0xFFC02410 /* UART1 Clock Rate Register */ -#define UART1_IER 0xFFC02414 /* UART1 Interrupt Mask Register */ -#define UART1_IER_SET 0xFFC02418 /* UART1 Interrupt Mask Set Register */ -#define UART1_IER_CLR 0xFFC0241C /* UART1 Interrupt Mask Clear Register */ -#define UART1_RBR 0xFFC02420 /* UART1 Receive Buffer Register */ -#define UART1_THR 0xFFC02424 /* UART1 Transmit Hold Register */ -#define UART1_TAIP 0xFFC02428 /* UART1 Transmit Address/Insert Pulse Register */ -#define UART1_TSR 0xFFC0242C /* UART1 Transmit Shift Register */ -#define UART1_RSR 0xFFC02430 /* UART1 Receive Shift Register */ -#define UART1_TXDIV 0xFFC02434 /* UART1 Transmit Clock Devider Register */ -#define UART1_RXDIV 0xFFC02438 /* UART1 Receive Clock Devider Register */ - - -/* ========================= - PORT Registers - ========================= */ - -/* ========================= - PORTA - ========================= */ -#define PORTA_FER 0xFFC03000 /* PORTA Port x Function Enable Register */ -#define PORTA_FER_SET 0xFFC03004 /* PORTA Port x Function Enable Set Register */ -#define PORTA_FER_CLEAR 0xFFC03008 /* PORTA Port x Function Enable Clear Register */ -#define PORTA_DATA 0xFFC0300C /* PORTA Port x GPIO Data Register */ -#define PORTA_DATA_SET 0xFFC03010 /* PORTA Port x GPIO Data Set Register */ -#define PORTA_DATA_CLEAR 0xFFC03014 /* PORTA Port x GPIO Data Clear Register */ -#define PORTA_DIR 0xFFC03018 /* PORTA Port x GPIO Direction Register */ -#define PORTA_DIR_SET 0xFFC0301C /* PORTA Port x GPIO Direction Set Register */ -#define PORTA_DIR_CLEAR 0xFFC03020 /* PORTA Port x GPIO Direction Clear Register */ -#define PORTA_INEN 0xFFC03024 /* PORTA Port x GPIO Input Enable Register */ -#define PORTA_INEN_SET 0xFFC03028 /* PORTA Port x GPIO Input Enable Set Register */ -#define PORTA_INEN_CLEAR 0xFFC0302C /* PORTA Port x GPIO Input Enable Clear Register */ -#define PORTA_MUX 0xFFC03030 /* PORTA Port x Multiplexer Control Register */ -#define PORTA_DATA_TGL 0xFFC03034 /* PORTA Port x GPIO Input Enable Toggle Register */ -#define PORTA_POL 0xFFC03038 /* PORTA Port x GPIO Programming Inversion Register */ -#define PORTA_POL_SET 0xFFC0303C /* PORTA Port x GPIO Programming Inversion Set Register */ -#define PORTA_POL_CLEAR 0xFFC03040 /* PORTA Port x GPIO Programming Inversion Clear Register */ -#define PORTA_LOCK 0xFFC03044 /* PORTA Port x GPIO Lock Register */ -#define PORTA_REVID 0xFFC0307C /* PORTA Port x GPIO Revision ID */ - -/* ========================= - PORTB - ========================= */ -#define PORTB_FER 0xFFC03080 /* PORTB Port x Function Enable Register */ -#define PORTB_FER_SET 0xFFC03084 /* PORTB Port x Function Enable Set Register */ -#define PORTB_FER_CLEAR 0xFFC03088 /* PORTB Port x Function Enable Clear Register */ -#define PORTB_DATA 0xFFC0308C /* PORTB Port x GPIO Data Register */ -#define PORTB_DATA_SET 0xFFC03090 /* PORTB Port x GPIO Data Set Register */ -#define PORTB_DATA_CLEAR 0xFFC03094 /* PORTB Port x GPIO Data Clear Register */ -#define PORTB_DIR 0xFFC03098 /* PORTB Port x GPIO Direction Register */ -#define PORTB_DIR_SET 0xFFC0309C /* PORTB Port x GPIO Direction Set Register */ -#define PORTB_DIR_CLEAR 0xFFC030A0 /* PORTB Port x GPIO Direction Clear Register */ -#define PORTB_INEN 0xFFC030A4 /* PORTB Port x GPIO Input Enable Register */ -#define PORTB_INEN_SET 0xFFC030A8 /* PORTB Port x GPIO Input Enable Set Register */ -#define PORTB_INEN_CLEAR 0xFFC030AC /* PORTB Port x GPIO Input Enable Clear Register */ -#define PORTB_MUX 0xFFC030B0 /* PORTB Port x Multiplexer Control Register */ -#define PORTB_DATA_TGL 0xFFC030B4 /* PORTB Port x GPIO Input Enable Toggle Register */ -#define PORTB_POL 0xFFC030B8 /* PORTB Port x GPIO Programming Inversion Register */ -#define PORTB_POL_SET 0xFFC030BC /* PORTB Port x GPIO Programming Inversion Set Register */ -#define PORTB_POL_CLEAR 0xFFC030C0 /* PORTB Port x GPIO Programming Inversion Clear Register */ -#define PORTB_LOCK 0xFFC030C4 /* PORTB Port x GPIO Lock Register */ -#define PORTB_REVID 0xFFC030FC /* PORTB Port x GPIO Revision ID */ - -/* ========================= - PORTC - ========================= */ -#define PORTC_FER 0xFFC03100 /* PORTC Port x Function Enable Register */ -#define PORTC_FER_SET 0xFFC03104 /* PORTC Port x Function Enable Set Register */ -#define PORTC_FER_CLEAR 0xFFC03108 /* PORTC Port x Function Enable Clear Register */ -#define PORTC_DATA 0xFFC0310C /* PORTC Port x GPIO Data Register */ -#define PORTC_DATA_SET 0xFFC03110 /* PORTC Port x GPIO Data Set Register */ -#define PORTC_DATA_CLEAR 0xFFC03114 /* PORTC Port x GPIO Data Clear Register */ -#define PORTC_DIR 0xFFC03118 /* PORTC Port x GPIO Direction Register */ -#define PORTC_DIR_SET 0xFFC0311C /* PORTC Port x GPIO Direction Set Register */ -#define PORTC_DIR_CLEAR 0xFFC03120 /* PORTC Port x GPIO Direction Clear Register */ -#define PORTC_INEN 0xFFC03124 /* PORTC Port x GPIO Input Enable Register */ -#define PORTC_INEN_SET 0xFFC03128 /* PORTC Port x GPIO Input Enable Set Register */ -#define PORTC_INEN_CLEAR 0xFFC0312C /* PORTC Port x GPIO Input Enable Clear Register */ -#define PORTC_MUX 0xFFC03130 /* PORTC Port x Multiplexer Control Register */ -#define PORTC_DATA_TGL 0xFFC03134 /* PORTC Port x GPIO Input Enable Toggle Register */ -#define PORTC_POL 0xFFC03138 /* PORTC Port x GPIO Programming Inversion Register */ -#define PORTC_POL_SET 0xFFC0313C /* PORTC Port x GPIO Programming Inversion Set Register */ -#define PORTC_POL_CLEAR 0xFFC03140 /* PORTC Port x GPIO Programming Inversion Clear Register */ -#define PORTC_LOCK 0xFFC03144 /* PORTC Port x GPIO Lock Register */ -#define PORTC_REVID 0xFFC0317C /* PORTC Port x GPIO Revision ID */ - -/* ========================= - PORTD - ========================= */ -#define PORTD_FER 0xFFC03180 /* PORTD Port x Function Enable Register */ -#define PORTD_FER_SET 0xFFC03184 /* PORTD Port x Function Enable Set Register */ -#define PORTD_FER_CLEAR 0xFFC03188 /* PORTD Port x Function Enable Clear Register */ -#define PORTD_DATA 0xFFC0318C /* PORTD Port x GPIO Data Register */ -#define PORTD_DATA_SET 0xFFC03190 /* PORTD Port x GPIO Data Set Register */ -#define PORTD_DATA_CLEAR 0xFFC03194 /* PORTD Port x GPIO Data Clear Register */ -#define PORTD_DIR 0xFFC03198 /* PORTD Port x GPIO Direction Register */ -#define PORTD_DIR_SET 0xFFC0319C /* PORTD Port x GPIO Direction Set Register */ -#define PORTD_DIR_CLEAR 0xFFC031A0 /* PORTD Port x GPIO Direction Clear Register */ -#define PORTD_INEN 0xFFC031A4 /* PORTD Port x GPIO Input Enable Register */ -#define PORTD_INEN_SET 0xFFC031A8 /* PORTD Port x GPIO Input Enable Set Register */ -#define PORTD_INEN_CLEAR 0xFFC031AC /* PORTD Port x GPIO Input Enable Clear Register */ -#define PORTD_MUX 0xFFC031B0 /* PORTD Port x Multiplexer Control Register */ -#define PORTD_DATA_TGL 0xFFC031B4 /* PORTD Port x GPIO Input Enable Toggle Register */ -#define PORTD_POL 0xFFC031B8 /* PORTD Port x GPIO Programming Inversion Register */ -#define PORTD_POL_SET 0xFFC031BC /* PORTD Port x GPIO Programming Inversion Set Register */ -#define PORTD_POL_CLEAR 0xFFC031C0 /* PORTD Port x GPIO Programming Inversion Clear Register */ -#define PORTD_LOCK 0xFFC031C4 /* PORTD Port x GPIO Lock Register */ -#define PORTD_REVID 0xFFC031FC /* PORTD Port x GPIO Revision ID */ - -/* ========================= - PORTE - ========================= */ -#define PORTE_FER 0xFFC03200 /* PORTE Port x Function Enable Register */ -#define PORTE_FER_SET 0xFFC03204 /* PORTE Port x Function Enable Set Register */ -#define PORTE_FER_CLEAR 0xFFC03208 /* PORTE Port x Function Enable Clear Register */ -#define PORTE_DATA 0xFFC0320C /* PORTE Port x GPIO Data Register */ -#define PORTE_DATA_SET 0xFFC03210 /* PORTE Port x GPIO Data Set Register */ -#define PORTE_DATA_CLEAR 0xFFC03214 /* PORTE Port x GPIO Data Clear Register */ -#define PORTE_DIR 0xFFC03218 /* PORTE Port x GPIO Direction Register */ -#define PORTE_DIR_SET 0xFFC0321C /* PORTE Port x GPIO Direction Set Register */ -#define PORTE_DIR_CLEAR 0xFFC03220 /* PORTE Port x GPIO Direction Clear Register */ -#define PORTE_INEN 0xFFC03224 /* PORTE Port x GPIO Input Enable Register */ -#define PORTE_INEN_SET 0xFFC03228 /* PORTE Port x GPIO Input Enable Set Register */ -#define PORTE_INEN_CLEAR 0xFFC0322C /* PORTE Port x GPIO Input Enable Clear Register */ -#define PORTE_MUX 0xFFC03230 /* PORTE Port x Multiplexer Control Register */ -#define PORTE_DATA_TGL 0xFFC03234 /* PORTE Port x GPIO Input Enable Toggle Register */ -#define PORTE_POL 0xFFC03238 /* PORTE Port x GPIO Programming Inversion Register */ -#define PORTE_POL_SET 0xFFC0323C /* PORTE Port x GPIO Programming Inversion Set Register */ -#define PORTE_POL_CLEAR 0xFFC03240 /* PORTE Port x GPIO Programming Inversion Clear Register */ -#define PORTE_LOCK 0xFFC03244 /* PORTE Port x GPIO Lock Register */ -#define PORTE_REVID 0xFFC0327C /* PORTE Port x GPIO Revision ID */ - -/* ========================= - PORTF - ========================= */ -#define PORTF_FER 0xFFC03280 /* PORTF Port x Function Enable Register */ -#define PORTF_FER_SET 0xFFC03284 /* PORTF Port x Function Enable Set Register */ -#define PORTF_FER_CLEAR 0xFFC03288 /* PORTF Port x Function Enable Clear Register */ -#define PORTF_DATA 0xFFC0328C /* PORTF Port x GPIO Data Register */ -#define PORTF_DATA_SET 0xFFC03290 /* PORTF Port x GPIO Data Set Register */ -#define PORTF_DATA_CLEAR 0xFFC03294 /* PORTF Port x GPIO Data Clear Register */ -#define PORTF_DIR 0xFFC03298 /* PORTF Port x GPIO Direction Register */ -#define PORTF_DIR_SET 0xFFC0329C /* PORTF Port x GPIO Direction Set Register */ -#define PORTF_DIR_CLEAR 0xFFC032A0 /* PORTF Port x GPIO Direction Clear Register */ -#define PORTF_INEN 0xFFC032A4 /* PORTF Port x GPIO Input Enable Register */ -#define PORTF_INEN_SET 0xFFC032A8 /* PORTF Port x GPIO Input Enable Set Register */ -#define PORTF_INEN_CLEAR 0xFFC032AC /* PORTF Port x GPIO Input Enable Clear Register */ -#define PORTF_MUX 0xFFC032B0 /* PORTF Port x Multiplexer Control Register */ -#define PORTF_DATA_TGL 0xFFC032B4 /* PORTF Port x GPIO Input Enable Toggle Register */ -#define PORTF_POL 0xFFC032B8 /* PORTF Port x GPIO Programming Inversion Register */ -#define PORTF_POL_SET 0xFFC032BC /* PORTF Port x GPIO Programming Inversion Set Register */ -#define PORTF_POL_CLEAR 0xFFC032C0 /* PORTF Port x GPIO Programming Inversion Clear Register */ -#define PORTF_LOCK 0xFFC032C4 /* PORTF Port x GPIO Lock Register */ -#define PORTF_REVID 0xFFC032FC /* PORTF Port x GPIO Revision ID */ - -/* ========================= - PORTG - ========================= */ -#define PORTG_FER 0xFFC03300 /* PORTG Port x Function Enable Register */ -#define PORTG_FER_SET 0xFFC03304 /* PORTG Port x Function Enable Set Register */ -#define PORTG_FER_CLEAR 0xFFC03308 /* PORTG Port x Function Enable Clear Register */ -#define PORTG_DATA 0xFFC0330C /* PORTG Port x GPIO Data Register */ -#define PORTG_DATA_SET 0xFFC03310 /* PORTG Port x GPIO Data Set Register */ -#define PORTG_DATA_CLEAR 0xFFC03314 /* PORTG Port x GPIO Data Clear Register */ -#define PORTG_DIR 0xFFC03318 /* PORTG Port x GPIO Direction Register */ -#define PORTG_DIR_SET 0xFFC0331C /* PORTG Port x GPIO Direction Set Register */ -#define PORTG_DIR_CLEAR 0xFFC03320 /* PORTG Port x GPIO Direction Clear Register */ -#define PORTG_INEN 0xFFC03324 /* PORTG Port x GPIO Input Enable Register */ -#define PORTG_INEN_SET 0xFFC03328 /* PORTG Port x GPIO Input Enable Set Register */ -#define PORTG_INEN_CLEAR 0xFFC0332C /* PORTG Port x GPIO Input Enable Clear Register */ -#define PORTG_MUX 0xFFC03330 /* PORTG Port x Multiplexer Control Register */ -#define PORTG_DATA_TGL 0xFFC03334 /* PORTG Port x GPIO Input Enable Toggle Register */ -#define PORTG_POL 0xFFC03338 /* PORTG Port x GPIO Programming Inversion Register */ -#define PORTG_POL_SET 0xFFC0333C /* PORTG Port x GPIO Programming Inversion Set Register */ -#define PORTG_POL_CLEAR 0xFFC03340 /* PORTG Port x GPIO Programming Inversion Clear Register */ -#define PORTG_LOCK 0xFFC03344 /* PORTG Port x GPIO Lock Register */ -#define PORTG_REVID 0xFFC0337C /* PORTG Port x GPIO Revision ID */ - - -/* ========================= - PINT Registers - ========================= */ - -/* ========================= - PINT0 - ========================= */ -#define PINT0_MASK_SET 0xFFC04000 /* PINT0 Pint Mask Set Register */ -#define PINT0_MASK_CLEAR 0xFFC04004 /* PINT0 Pint Mask Clear Register */ -#define PINT0_REQUEST 0xFFC04008 /* PINT0 Pint Request Register */ -#define PINT0_ASSIGN 0xFFC0400C /* PINT0 Pint Assign Register */ -#define PINT0_EDGE_SET 0xFFC04010 /* PINT0 Pint Edge Set Register */ -#define PINT0_EDGE_CLEAR 0xFFC04014 /* PINT0 Pint Edge Clear Register */ -#define PINT0_INVERT_SET 0xFFC04018 /* PINT0 Pint Invert Set Register */ -#define PINT0_INVERT_CLEAR 0xFFC0401C /* PINT0 Pint Invert Clear Register */ -#define PINT0_PINSTATE 0xFFC04020 /* PINT0 Pint Pinstate Register */ -#define PINT0_LATCH 0xFFC04024 /* PINT0 Pint Latch Register */ - -/* ========================= - PINT1 - ========================= */ -#define PINT1_MASK_SET 0xFFC04100 /* PINT1 Pint Mask Set Register */ -#define PINT1_MASK_CLEAR 0xFFC04104 /* PINT1 Pint Mask Clear Register */ -#define PINT1_REQUEST 0xFFC04108 /* PINT1 Pint Request Register */ -#define PINT1_ASSIGN 0xFFC0410C /* PINT1 Pint Assign Register */ -#define PINT1_EDGE_SET 0xFFC04110 /* PINT1 Pint Edge Set Register */ -#define PINT1_EDGE_CLEAR 0xFFC04114 /* PINT1 Pint Edge Clear Register */ -#define PINT1_INVERT_SET 0xFFC04118 /* PINT1 Pint Invert Set Register */ -#define PINT1_INVERT_CLEAR 0xFFC0411C /* PINT1 Pint Invert Clear Register */ -#define PINT1_PINSTATE 0xFFC04120 /* PINT1 Pint Pinstate Register */ -#define PINT1_LATCH 0xFFC04124 /* PINT1 Pint Latch Register */ - -/* ========================= - PINT2 - ========================= */ -#define PINT2_MASK_SET 0xFFC04200 /* PINT2 Pint Mask Set Register */ -#define PINT2_MASK_CLEAR 0xFFC04204 /* PINT2 Pint Mask Clear Register */ -#define PINT2_REQUEST 0xFFC04208 /* PINT2 Pint Request Register */ -#define PINT2_ASSIGN 0xFFC0420C /* PINT2 Pint Assign Register */ -#define PINT2_EDGE_SET 0xFFC04210 /* PINT2 Pint Edge Set Register */ -#define PINT2_EDGE_CLEAR 0xFFC04214 /* PINT2 Pint Edge Clear Register */ -#define PINT2_INVERT_SET 0xFFC04218 /* PINT2 Pint Invert Set Register */ -#define PINT2_INVERT_CLEAR 0xFFC0421C /* PINT2 Pint Invert Clear Register */ -#define PINT2_PINSTATE 0xFFC04220 /* PINT2 Pint Pinstate Register */ -#define PINT2_LATCH 0xFFC04224 /* PINT2 Pint Latch Register */ - -/* ========================= - PINT3 - ========================= */ -#define PINT3_MASK_SET 0xFFC04300 /* PINT3 Pint Mask Set Register */ -#define PINT3_MASK_CLEAR 0xFFC04304 /* PINT3 Pint Mask Clear Register */ -#define PINT3_REQUEST 0xFFC04308 /* PINT3 Pint Request Register */ -#define PINT3_ASSIGN 0xFFC0430C /* PINT3 Pint Assign Register */ -#define PINT3_EDGE_SET 0xFFC04310 /* PINT3 Pint Edge Set Register */ -#define PINT3_EDGE_CLEAR 0xFFC04314 /* PINT3 Pint Edge Clear Register */ -#define PINT3_INVERT_SET 0xFFC04318 /* PINT3 Pint Invert Set Register */ -#define PINT3_INVERT_CLEAR 0xFFC0431C /* PINT3 Pint Invert Clear Register */ -#define PINT3_PINSTATE 0xFFC04320 /* PINT3 Pint Pinstate Register */ -#define PINT3_LATCH 0xFFC04324 /* PINT3 Pint Latch Register */ - -/* ========================= - PINT4 - ========================= */ -#define PINT4_MASK_SET 0xFFC04400 /* PINT4 Pint Mask Set Register */ -#define PINT4_MASK_CLEAR 0xFFC04404 /* PINT4 Pint Mask Clear Register */ -#define PINT4_REQUEST 0xFFC04408 /* PINT4 Pint Request Register */ -#define PINT4_ASSIGN 0xFFC0440C /* PINT4 Pint Assign Register */ -#define PINT4_EDGE_SET 0xFFC04410 /* PINT4 Pint Edge Set Register */ -#define PINT4_EDGE_CLEAR 0xFFC04414 /* PINT4 Pint Edge Clear Register */ -#define PINT4_INVERT_SET 0xFFC04418 /* PINT4 Pint Invert Set Register */ -#define PINT4_INVERT_CLEAR 0xFFC0441C /* PINT4 Pint Invert Clear Register */ -#define PINT4_PINSTATE 0xFFC04420 /* PINT4 Pint Pinstate Register */ -#define PINT4_LATCH 0xFFC04424 /* PINT4 Pint Latch Register */ - -/* ========================= - PINT5 - ========================= */ -#define PINT5_MASK_SET 0xFFC04500 /* PINT5 Pint Mask Set Register */ -#define PINT5_MASK_CLEAR 0xFFC04504 /* PINT5 Pint Mask Clear Register */ -#define PINT5_REQUEST 0xFFC04508 /* PINT5 Pint Request Register */ -#define PINT5_ASSIGN 0xFFC0450C /* PINT5 Pint Assign Register */ -#define PINT5_EDGE_SET 0xFFC04510 /* PINT5 Pint Edge Set Register */ -#define PINT5_EDGE_CLEAR 0xFFC04514 /* PINT5 Pint Edge Clear Register */ -#define PINT5_INVERT_SET 0xFFC04518 /* PINT5 Pint Invert Set Register */ -#define PINT5_INVERT_CLEAR 0xFFC0451C /* PINT5 Pint Invert Clear Register */ -#define PINT5_PINSTATE 0xFFC04520 /* PINT5 Pint Pinstate Register */ -#define PINT5_LATCH 0xFFC04524 /* PINT5 Pint Latch Register */ - - -/* ========================= - SMC Registers - ========================= */ - -/* ========================= - SMC0 - ========================= */ -#define SMC_GCTL 0xFFC16004 /* SMC0 SMC Control Register */ -#define SMC_GSTAT 0xFFC16008 /* SMC0 SMC Status Register */ -#define SMC_B0CTL 0xFFC1600C /* SMC0 SMC Bank0 Control Register */ -#define SMC_B0TIM 0xFFC16010 /* SMC0 SMC Bank0 Timing Register */ -#define SMC_B0ETIM 0xFFC16014 /* SMC0 SMC Bank0 Extended Timing Register */ -#define SMC_B1CTL 0xFFC1601C /* SMC0 SMC BANK1 Control Register */ -#define SMC_B1TIM 0xFFC16020 /* SMC0 SMC BANK1 Timing Register */ -#define SMC_B1ETIM 0xFFC16024 /* SMC0 SMC BANK1 Extended Timing Register */ -#define SMC_B2CTL 0xFFC1602C /* SMC0 SMC BANK2 Control Register */ -#define SMC_B2TIM 0xFFC16030 /* SMC0 SMC BANK2 Timing Register */ -#define SMC_B2ETIM 0xFFC16034 /* SMC0 SMC BANK2 Extended Timing Register */ -#define SMC_B3CTL 0xFFC1603C /* SMC0 SMC BANK3 Control Register */ -#define SMC_B3TIM 0xFFC16040 /* SMC0 SMC BANK3 Timing Register */ -#define SMC_B3ETIM 0xFFC16044 /* SMC0 SMC BANK3 Extended Timing Register */ - - -/* ========================= - WDOG Registers - ========================= */ - -/* ========================= - WDOG0 - ========================= */ -#define WDOG0_CTL 0xFFC17000 /* WDOG0 Control Register */ -#define WDOG0_CNT 0xFFC17004 /* WDOG0 Count Register */ -#define WDOG0_STAT 0xFFC17008 /* WDOG0 Watchdog Timer Status Register */ -#define WDOG_CTL WDOG0_CTL -#define WDOG_CNT WDOG0_CNT -#define WDOG_STAT WDOG0_STAT - -/* ========================= - WDOG1 - ========================= */ -#define WDOG1_CTL 0xFFC17800 /* WDOG1 Control Register */ -#define WDOG1_CNT 0xFFC17804 /* WDOG1 Count Register */ -#define WDOG1_STAT 0xFFC17808 /* WDOG1 Watchdog Timer Status Register */ - - -/* ========================= - SDU Registers - ========================= */ - -/* ========================= - SDU0 - ========================= */ -#define SDU0_IDCODE 0xFFC1F020 /* SDU0 ID Code Register */ -#define SDU0_CTL 0xFFC1F050 /* SDU0 Control Register */ -#define SDU0_STAT 0xFFC1F054 /* SDU0 Status Register */ -#define SDU0_MACCTL 0xFFC1F058 /* SDU0 Memory Access Control Register */ -#define SDU0_MACADDR 0xFFC1F05C /* SDU0 Memory Access Address Register */ -#define SDU0_MACDATA 0xFFC1F060 /* SDU0 Memory Access Data Register */ -#define SDU0_DMARD 0xFFC1F064 /* SDU0 DMA Read Data Register */ -#define SDU0_DMAWD 0xFFC1F068 /* SDU0 DMA Write Data Register */ -#define SDU0_MSG 0xFFC1F080 /* SDU0 Message Register */ -#define SDU0_MSG_SET 0xFFC1F084 /* SDU0 Message Set Register */ -#define SDU0_MSG_CLR 0xFFC1F088 /* SDU0 Message Clear Register */ -#define SDU0_GHLT 0xFFC1F08C /* SDU0 Group Halt Register */ - - -/* ========================= - EMAC Registers - ========================= */ -/* ========================= - EMAC0 - ========================= */ -#define EMAC0_MACCFG 0xFFC20000 /* EMAC0 MAC Configuration Register */ -#define EMAC0_MACFRMFILT 0xFFC20004 /* EMAC0 Filter Register for filtering Received Frames */ -#define EMAC0_HASHTBL_HI 0xFFC20008 /* EMAC0 Contains the Upper 32 bits of the hash table */ -#define EMAC0_HASHTBL_LO 0xFFC2000C /* EMAC0 Contains the lower 32 bits of the hash table */ -#define EMAC0_GMII_ADDR 0xFFC20010 /* EMAC0 Management Address Register */ -#define EMAC0_GMII_DATA 0xFFC20014 /* EMAC0 Management Data Register */ -#define EMAC0_FLOWCTL 0xFFC20018 /* EMAC0 MAC FLow Control Register */ -#define EMAC0_VLANTAG 0xFFC2001C /* EMAC0 VLAN Tag Register */ -#define EMAC0_VER 0xFFC20020 /* EMAC0 EMAC Version Register */ -#define EMAC0_DBG 0xFFC20024 /* EMAC0 EMAC Debug Register */ -#define EMAC0_RMTWKUP 0xFFC20028 /* EMAC0 Remote wake up frame register */ -#define EMAC0_PMT_CTLSTAT 0xFFC2002C /* EMAC0 PMT Control and Status Register */ -#define EMAC0_ISTAT 0xFFC20038 /* EMAC0 EMAC Interrupt Status Register */ -#define EMAC0_IMSK 0xFFC2003C /* EMAC0 EMAC Interrupt Mask Register */ -#define EMAC0_ADDR0_HI 0xFFC20040 /* EMAC0 EMAC Address0 High Register */ -#define EMAC0_ADDR0_LO 0xFFC20044 /* EMAC0 EMAC Address0 Low Register */ -#define EMAC0_MMC_CTL 0xFFC20100 /* EMAC0 MMC Control Register */ -#define EMAC0_MMC_RXINT 0xFFC20104 /* EMAC0 MMC RX Interrupt Register */ -#define EMAC0_MMC_TXINT 0xFFC20108 /* EMAC0 MMC TX Interrupt Register */ -#define EMAC0_MMC_RXIMSK 0xFFC2010C /* EMAC0 MMC RX Interrupt Mask Register */ -#define EMAC0_MMC_TXIMSK 0xFFC20110 /* EMAC0 MMC TX Interrupt Mask Register */ -#define EMAC0_TXOCTCNT_GB 0xFFC20114 /* EMAC0 Num bytes transmitted exclusive of preamble */ -#define EMAC0_TXFRMCNT_GB 0xFFC20118 /* EMAC0 Num frames transmitted exclusive of retired */ -#define EMAC0_TXBCASTFRM_G 0xFFC2011C /* EMAC0 Number of good broadcast frames transmitted. */ -#define EMAC0_TXMCASTFRM_G 0xFFC20120 /* EMAC0 Number of good multicast frames transmitted. */ -#define EMAC0_TX64_GB 0xFFC20124 /* EMAC0 Number of 64 byte length frames */ -#define EMAC0_TX65TO127_GB 0xFFC20128 /* EMAC0 Number of frames of length b/w 65-127 (inclusive) bytes */ -#define EMAC0_TX128TO255_GB 0xFFC2012C /* EMAC0 Number of frames of length b/w 128-255 (inclusive) bytes */ -#define EMAC0_TX256TO511_GB 0xFFC20130 /* EMAC0 Number of frames of length b/w 256-511 (inclusive) bytes */ -#define EMAC0_TX512TO1023_GB 0xFFC20134 /* EMAC0 Number of frames of length b/w 512-1023 (inclusive) bytes */ -#define EMAC0_TX1024TOMAX_GB 0xFFC20138 /* EMAC0 Number of frames of length b/w 1024-max (inclusive) bytes */ -#define EMAC0_TXUCASTFRM_GB 0xFFC2013C /* EMAC0 Number of good and bad unicast frames transmitted */ -#define EMAC0_TXMCASTFRM_GB 0xFFC20140 /* EMAC0 Number of good and bad multicast frames transmitted */ -#define EMAC0_TXBCASTFRM_GB 0xFFC20144 /* EMAC0 Number of good and bad broadcast frames transmitted */ -#define EMAC0_TXUNDR_ERR 0xFFC20148 /* EMAC0 Number of frames aborted due to frame underflow error */ -#define EMAC0_TXSNGCOL_G 0xFFC2014C /* EMAC0 Number of transmitted frames after single collision */ -#define EMAC0_TXMULTCOL_G 0xFFC20150 /* EMAC0 Number of transmitted frames with more than one collision */ -#define EMAC0_TXDEFERRED 0xFFC20154 /* EMAC0 Number of transmitted frames after deferral */ -#define EMAC0_TXLATECOL 0xFFC20158 /* EMAC0 Number of frames aborted due to late collision error */ -#define EMAC0_TXEXCESSCOL 0xFFC2015C /* EMAC0 Number of aborted frames due to excessive collisions */ -#define EMAC0_TXCARR_ERR 0xFFC20160 /* EMAC0 Number of aborted frames due to carrier sense error */ -#define EMAC0_TXOCTCNT_G 0xFFC20164 /* EMAC0 Number of bytes transmitted in good frames only */ -#define EMAC0_TXFRMCNT_G 0xFFC20168 /* EMAC0 Number of good frames transmitted. */ -#define EMAC0_TXEXCESSDEF 0xFFC2016C /* EMAC0 Number of frames aborted due to excessive deferral */ -#define EMAC0_TXPAUSEFRM 0xFFC20170 /* EMAC0 Number of good PAUSE frames transmitted. */ -#define EMAC0_TXVLANFRM_G 0xFFC20174 /* EMAC0 Number of VLAN frames transmitted */ -#define EMAC0_RXFRMCNT_GB 0xFFC20180 /* EMAC0 Number of good and bad frames received. */ -#define EMAC0_RXOCTCNT_GB 0xFFC20184 /* EMAC0 Number of bytes received in good and bad frames */ -#define EMAC0_RXOCTCNT_G 0xFFC20188 /* EMAC0 Number of bytes received only in good frames */ -#define EMAC0_RXBCASTFRM_G 0xFFC2018C /* EMAC0 Number of good broadcast frames received. */ -#define EMAC0_RXMCASTFRM_G 0xFFC20190 /* EMAC0 Number of good multicast frames received */ -#define EMAC0_RXCRC_ERR 0xFFC20194 /* EMAC0 Number of frames received with CRC error */ -#define EMAC0_RXALIGN_ERR 0xFFC20198 /* EMAC0 Number of frames with alignment error */ -#define EMAC0_RXRUNT_ERR 0xFFC2019C /* EMAC0 Number of frames received with runt error. */ -#define EMAC0_RXJAB_ERR 0xFFC201A0 /* EMAC0 Number of frames received with length greater than 1518 */ -#define EMAC0_RXUSIZE_G 0xFFC201A4 /* EMAC0 Number of frames received with length 64 */ -#define EMAC0_RXOSIZE_G 0xFFC201A8 /* EMAC0 Number of frames received with length greater than maxium */ -#define EMAC0_RX64_GB 0xFFC201AC /* EMAC0 Number of good and bad frames of lengh 64 bytes */ -#define EMAC0_RX65TO127_GB 0xFFC201B0 /* EMAC0 Number of good and bad frame between 64-127(inclusive) */ -#define EMAC0_RX128TO255_GB 0xFFC201B4 /* EMAC0 Number of good and bad frames received with length between 128 and 255 (inclusive) bytes, exclusive of preamble. */ -#define EMAC0_RX256TO511_GB 0xFFC201B8 /* EMAC0 Number of good and bad frames between 256-511(inclusive) */ -#define EMAC0_RX512TO1023_GB 0xFFC201BC /* EMAC0 Number of good and bad frames received between 512-1023 */ -#define EMAC0_RX1024TOMAX_GB 0xFFC201C0 /* EMAC0 Number of frames received between 1024 and maxsize */ -#define EMAC0_RXUCASTFRM_G 0xFFC201C4 /* EMAC0 Number of good unicast frames received. */ -#define EMAC0_RXLEN_ERR 0xFFC201C8 /* EMAC0 Number of frames received with length error */ -#define EMAC0_RXOORTYPE 0xFFC201CC /* EMAC0 Number of frames with length not equal to valid frame size */ -#define EMAC0_RXPAUSEFRM 0xFFC201D0 /* EMAC0 Number of good and valid PAUSE frames received. */ -#define EMAC0_RXFIFO_OVF 0xFFC201D4 /* EMAC0 Number of missed received frames due to FIFO overflow. This counter is not present in the GMAC-CORE configuration. */ -#define EMAC0_RXVLANFRM_GB 0xFFC201D8 /* EMAC0 Number of good and bad VLAN frames received. */ -#define EMAC0_RXWDOG_ERR 0xFFC201DC /* EMAC0 Frames received with error due to watchdog timeout */ -#define EMAC0_IPC_RXIMSK 0xFFC20200 /* EMAC0 MMC IPC RX Interrupt Mask Register */ -#define EMAC0_IPC_RXINT 0xFFC20208 /* EMAC0 MMC IPC RX Interrupt Register */ -#define EMAC0_RXIPV4_GD_FRM 0xFFC20210 /* EMAC0 Number of good IPv4 datagrams */ -#define EMAC0_RXIPV4_HDR_ERR_FRM 0xFFC20214 /* EMAC0 Number of IPv4 datagrams with header errors */ -#define EMAC0_RXIPV4_NOPAY_FRM 0xFFC20218 /* EMAC0 Number of IPv4 datagrams without checksum */ -#define EMAC0_RXIPV4_FRAG_FRM 0xFFC2021C /* EMAC0 Number of good IPv4 datagrams with fragmentation */ -#define EMAC0_RXIPV4_UDSBL_FRM 0xFFC20220 /* EMAC0 Number of IPv4 UDP datagrams with disabled checksum */ -#define EMAC0_RXIPV6_GD_FRM 0xFFC20224 /* EMAC0 Number of IPv4 datagrams with TCP/UDP/ICMP payloads */ -#define EMAC0_RXIPV6_HDR_ERR_FRM 0xFFC20228 /* EMAC0 Number of IPv6 datagrams with header errors */ -#define EMAC0_RXIPV6_NOPAY_FRM 0xFFC2022C /* EMAC0 Number of IPv6 datagrams with no TCP/UDP/ICMP payload */ -#define EMAC0_RXUDP_GD_FRM 0xFFC20230 /* EMAC0 Number of good IP datagrames with good UDP payload */ -#define EMAC0_RXUDP_ERR_FRM 0xFFC20234 /* EMAC0 Number of good IP datagrams with UDP checksum errors */ -#define EMAC0_RXTCP_GD_FRM 0xFFC20238 /* EMAC0 Number of good IP datagrams with a good TCP payload */ -#define EMAC0_RXTCP_ERR_FRM 0xFFC2023C /* EMAC0 Number of good IP datagrams with TCP checksum errors */ -#define EMAC0_RXICMP_GD_FRM 0xFFC20240 /* EMAC0 Number of good IP datagrams with a good ICMP payload */ -#define EMAC0_RXICMP_ERR_FRM 0xFFC20244 /* EMAC0 Number of good IP datagrams with ICMP checksum errors */ -#define EMAC0_RXIPV4_GD_OCT 0xFFC20250 /* EMAC0 Bytes received in IPv4 datagrams including tcp,udp or icmp */ -#define EMAC0_RXIPV4_HDR_ERR_OCT 0xFFC20254 /* EMAC0 Bytes received in IPv4 datagrams with header errors */ -#define EMAC0_RXIPV4_NOPAY_OCT 0xFFC20258 /* EMAC0 Bytes received in IPv4 datagrams without tcp,udp,icmp load */ -#define EMAC0_RXIPV4_FRAG_OCT 0xFFC2025C /* EMAC0 Bytes received in fragmented IPv4 datagrams */ -#define EMAC0_RXIPV4_UDSBL_OCT 0xFFC20260 /* EMAC0 Bytes received in UDP segment with checksum disabled */ -#define EMAC0_RXIPV6_GD_OCT 0xFFC20264 /* EMAC0 Bytes received in good IPv6 including tcp,udp or icmp load */ -#define EMAC0_RXIPV6_HDR_ERR_OCT 0xFFC20268 /* EMAC0 Number of bytes received in IPv6 with header errors */ -#define EMAC0_RXIPV6_NOPAY_OCT 0xFFC2026C /* EMAC0 Bytes received in IPv6 without tcp,udp or icmp load */ -#define EMAC0_RXUDP_GD_OCT 0xFFC20270 /* EMAC0 Number of bytes received in good UDP segments */ -#define EMAC0_RXUDP_ERR_OCT 0xFFC20274 /* EMAC0 Number of bytes received in UDP segment with checksum err */ -#define EMAC0_RXTCP_GD_OCT 0xFFC20278 /* EMAC0 Number of bytes received in a good TCP segment */ -#define EMAC0_RXTCP_ERR_OCT 0xFFC2027C /* EMAC0 Number of bytes received in TCP segment with checksum err */ -#define EMAC0_RXICMP_GD_OCT 0xFFC20280 /* EMAC0 Number of bytes received in a good ICMP segment */ -#define EMAC0_RXICMP_ERR_OCT 0xFFC20284 /* EMAC0 Bytes received in an ICMP segment with checksum errors */ -#define EMAC0_TM_CTL 0xFFC20700 /* EMAC0 EMAC Time Stamp Control Register */ -#define EMAC0_TM_SUBSEC 0xFFC20704 /* EMAC0 EMAC Time Stamp Sub Second Increment */ -#define EMAC0_TM_SEC 0xFFC20708 /* EMAC0 EMAC Time Stamp Second Register */ -#define EMAC0_TM_NSEC 0xFFC2070C /* EMAC0 EMAC Time Stamp Nano Second Register */ -#define EMAC0_TM_SECUPDT 0xFFC20710 /* EMAC0 EMAC Time Stamp Seconds Update */ -#define EMAC0_TM_NSECUPDT 0xFFC20714 /* EMAC0 EMAC Time Stamp Nano Seconds Update */ -#define EMAC0_TM_ADDEND 0xFFC20718 /* EMAC0 EMAC Time Stamp Addend Register */ -#define EMAC0_TM_TGTM 0xFFC2071C /* EMAC0 EMAC Time Stamp Target Time Sec. */ -#define EMAC0_TM_NTGTM 0xFFC20720 /* EMAC0 EMAC Time Stamp Target Time Nanosec. */ -#define EMAC0_TM_HISEC 0xFFC20724 /* EMAC0 EMAC Time Stamp High Second Register */ -#define EMAC0_TM_STMPSTAT 0xFFC20728 /* EMAC0 EMAC Time Stamp Status Register */ -#define EMAC0_TM_PPSCTL 0xFFC2072C /* EMAC0 EMAC PPS Control Register */ -#define EMAC0_TM_AUXSTMP_NSEC 0xFFC20730 /* EMAC0 EMAC Auxillary Time Stamp Nano Register */ -#define EMAC0_TM_AUXSTMP_SEC 0xFFC20734 /* EMAC0 EMAC Auxillary Time Stamp Sec Register */ -#define EMAC0_DMA_BUSMODE 0xFFC21000 /* EMAC0 Bus Operating Modes for EMAC DMA */ -#define EMAC0_DMA_TXPOLL 0xFFC21004 /* EMAC0 TX DMA Poll demand register */ -#define EMAC0_DMA_RXPOLL 0xFFC21008 /* EMAC0 RX DMA Poll demand register */ -#define EMAC0_DMA_RXDSC_ADDR 0xFFC2100C /* EMAC0 RX Descriptor List Address */ -#define EMAC0_DMA_TXDSC_ADDR 0xFFC21010 /* EMAC0 TX Descriptor List Address */ -#define EMAC0_DMA_STAT 0xFFC21014 /* EMAC0 DMA Status Register */ -#define EMAC0_DMA_OPMODE 0xFFC21018 /* EMAC0 DMA Operation Mode Register */ -#define EMAC0_DMA_IEN 0xFFC2101C /* EMAC0 DMA Interrupt Enable Register */ -#define EMAC0_DMA_MISS_FRM 0xFFC21020 /* EMAC0 DMA missed frame and buffer overflow counter */ -#define EMAC0_DMA_RXIWDOG 0xFFC21024 /* EMAC0 DMA RX Interrupt Watch Dog timer */ -#define EMAC0_DMA_BMMODE 0xFFC21028 /* EMAC0 AXI Bus Mode Register */ -#define EMAC0_DMA_BMSTAT 0xFFC2102C /* EMAC0 AXI Status Register */ -#define EMAC0_DMA_TXDSC_CUR 0xFFC21048 /* EMAC0 TX current descriptor register */ -#define EMAC0_DMA_RXDSC_CUR 0xFFC2104C /* EMAC0 RX current descriptor register */ -#define EMAC0_DMA_TXBUF_CUR 0xFFC21050 /* EMAC0 TX current buffer pointer register */ -#define EMAC0_DMA_RXBUF_CUR 0xFFC21054 /* EMAC0 RX current buffer pointer register */ -#define EMAC0_HWFEAT 0xFFC21058 /* EMAC0 Hardware Feature Register */ - -/* ========================= - EMAC1 - ========================= */ -#define EMAC1_MACCFG 0xFFC22000 /* EMAC1 MAC Configuration Register */ -#define EMAC1_MACFRMFILT 0xFFC22004 /* EMAC1 Filter Register for filtering Received Frames */ -#define EMAC1_HASHTBL_HI 0xFFC22008 /* EMAC1 Contains the Upper 32 bits of the hash table */ -#define EMAC1_HASHTBL_LO 0xFFC2200C /* EMAC1 Contains the lower 32 bits of the hash table */ -#define EMAC1_GMII_ADDR 0xFFC22010 /* EMAC1 Management Address Register */ -#define EMAC1_GMII_DATA 0xFFC22014 /* EMAC1 Management Data Register */ -#define EMAC1_FLOWCTL 0xFFC22018 /* EMAC1 MAC FLow Control Register */ -#define EMAC1_VLANTAG 0xFFC2201C /* EMAC1 VLAN Tag Register */ -#define EMAC1_VER 0xFFC22020 /* EMAC1 EMAC Version Register */ -#define EMAC1_DBG 0xFFC22024 /* EMAC1 EMAC Debug Register */ -#define EMAC1_RMTWKUP 0xFFC22028 /* EMAC1 Remote wake up frame register */ -#define EMAC1_PMT_CTLSTAT 0xFFC2202C /* EMAC1 PMT Control and Status Register */ -#define EMAC1_ISTAT 0xFFC22038 /* EMAC1 EMAC Interrupt Status Register */ -#define EMAC1_IMSK 0xFFC2203C /* EMAC1 EMAC Interrupt Mask Register */ -#define EMAC1_ADDR0_HI 0xFFC22040 /* EMAC1 EMAC Address0 High Register */ -#define EMAC1_ADDR0_LO 0xFFC22044 /* EMAC1 EMAC Address0 Low Register */ -#define EMAC1_MMC_CTL 0xFFC22100 /* EMAC1 MMC Control Register */ -#define EMAC1_MMC_RXINT 0xFFC22104 /* EMAC1 MMC RX Interrupt Register */ -#define EMAC1_MMC_TXINT 0xFFC22108 /* EMAC1 MMC TX Interrupt Register */ -#define EMAC1_MMC_RXIMSK 0xFFC2210C /* EMAC1 MMC RX Interrupt Mask Register */ -#define EMAC1_MMC_TXIMSK 0xFFC22110 /* EMAC1 MMC TX Interrupt Mask Register */ -#define EMAC1_TXOCTCNT_GB 0xFFC22114 /* EMAC1 Num bytes transmitted exclusive of preamble */ -#define EMAC1_TXFRMCNT_GB 0xFFC22118 /* EMAC1 Num frames transmitted exclusive of retired */ -#define EMAC1_TXBCASTFRM_G 0xFFC2211C /* EMAC1 Number of good broadcast frames transmitted. */ -#define EMAC1_TXMCASTFRM_G 0xFFC22120 /* EMAC1 Number of good multicast frames transmitted. */ -#define EMAC1_TX64_GB 0xFFC22124 /* EMAC1 Number of 64 byte length frames */ -#define EMAC1_TX65TO127_GB 0xFFC22128 /* EMAC1 Number of frames of length b/w 65-127 (inclusive) bytes */ -#define EMAC1_TX128TO255_GB 0xFFC2212C /* EMAC1 Number of frames of length b/w 128-255 (inclusive) bytes */ -#define EMAC1_TX256TO511_GB 0xFFC22130 /* EMAC1 Number of frames of length b/w 256-511 (inclusive) bytes */ -#define EMAC1_TX512TO1023_GB 0xFFC22134 /* EMAC1 Number of frames of length b/w 512-1023 (inclusive) bytes */ -#define EMAC1_TX1024TOMAX_GB 0xFFC22138 /* EMAC1 Number of frames of length b/w 1024-max (inclusive) bytes */ -#define EMAC1_TXUCASTFRM_GB 0xFFC2213C /* EMAC1 Number of good and bad unicast frames transmitted */ -#define EMAC1_TXMCASTFRM_GB 0xFFC22140 /* EMAC1 Number of good and bad multicast frames transmitted */ -#define EMAC1_TXBCASTFRM_GB 0xFFC22144 /* EMAC1 Number of good and bad broadcast frames transmitted */ -#define EMAC1_TXUNDR_ERR 0xFFC22148 /* EMAC1 Number of frames aborted due to frame underflow error */ -#define EMAC1_TXSNGCOL_G 0xFFC2214C /* EMAC1 Number of transmitted frames after single collision */ -#define EMAC1_TXMULTCOL_G 0xFFC22150 /* EMAC1 Number of transmitted frames with more than one collision */ -#define EMAC1_TXDEFERRED 0xFFC22154 /* EMAC1 Number of transmitted frames after deferral */ -#define EMAC1_TXLATECOL 0xFFC22158 /* EMAC1 Number of frames aborted due to late collision error */ -#define EMAC1_TXEXCESSCOL 0xFFC2215C /* EMAC1 Number of aborted frames due to excessive collisions */ -#define EMAC1_TXCARR_ERR 0xFFC22160 /* EMAC1 Number of aborted frames due to carrier sense error */ -#define EMAC1_TXOCTCNT_G 0xFFC22164 /* EMAC1 Number of bytes transmitted in good frames only */ -#define EMAC1_TXFRMCNT_G 0xFFC22168 /* EMAC1 Number of good frames transmitted. */ -#define EMAC1_TXEXCESSDEF 0xFFC2216C /* EMAC1 Number of frames aborted due to excessive deferral */ -#define EMAC1_TXPAUSEFRM 0xFFC22170 /* EMAC1 Number of good PAUSE frames transmitted. */ -#define EMAC1_TXVLANFRM_G 0xFFC22174 /* EMAC1 Number of VLAN frames transmitted */ -#define EMAC1_RXFRMCNT_GB 0xFFC22180 /* EMAC1 Number of good and bad frames received. */ -#define EMAC1_RXOCTCNT_GB 0xFFC22184 /* EMAC1 Number of bytes received in good and bad frames */ -#define EMAC1_RXOCTCNT_G 0xFFC22188 /* EMAC1 Number of bytes received only in good frames */ -#define EMAC1_RXBCASTFRM_G 0xFFC2218C /* EMAC1 Number of good broadcast frames received. */ -#define EMAC1_RXMCASTFRM_G 0xFFC22190 /* EMAC1 Number of good multicast frames received */ -#define EMAC1_RXCRC_ERR 0xFFC22194 /* EMAC1 Number of frames received with CRC error */ -#define EMAC1_RXALIGN_ERR 0xFFC22198 /* EMAC1 Number of frames with alignment error */ -#define EMAC1_RXRUNT_ERR 0xFFC2219C /* EMAC1 Number of frames received with runt error. */ -#define EMAC1_RXJAB_ERR 0xFFC221A0 /* EMAC1 Number of frames received with length greater than 1518 */ -#define EMAC1_RXUSIZE_G 0xFFC221A4 /* EMAC1 Number of frames received with length 64 */ -#define EMAC1_RXOSIZE_G 0xFFC221A8 /* EMAC1 Number of frames received with length greater than maxium */ -#define EMAC1_RX64_GB 0xFFC221AC /* EMAC1 Number of good and bad frames of lengh 64 bytes */ -#define EMAC1_RX65TO127_GB 0xFFC221B0 /* EMAC1 Number of good and bad frame between 64-127(inclusive) */ -#define EMAC1_RX128TO255_GB 0xFFC221B4 /* EMAC1 Number of good and bad frames received with length between 128 and 255 (inclusive) bytes, exclusive of preamble. */ -#define EMAC1_RX256TO511_GB 0xFFC221B8 /* EMAC1 Number of good and bad frames between 256-511(inclusive) */ -#define EMAC1_RX512TO1023_GB 0xFFC221BC /* EMAC1 Number of good and bad frames received between 512-1023 */ -#define EMAC1_RX1024TOMAX_GB 0xFFC221C0 /* EMAC1 Number of frames received between 1024 and maxsize */ -#define EMAC1_RXUCASTFRM_G 0xFFC221C4 /* EMAC1 Number of good unicast frames received. */ -#define EMAC1_RXLEN_ERR 0xFFC221C8 /* EMAC1 Number of frames received with length error */ -#define EMAC1_RXOORTYPE 0xFFC221CC /* EMAC1 Number of frames with length not equal to valid frame size */ -#define EMAC1_RXPAUSEFRM 0xFFC221D0 /* EMAC1 Number of good and valid PAUSE frames received. */ -#define EMAC1_RXFIFO_OVF 0xFFC221D4 /* EMAC1 Number of missed received frames due to FIFO overflow. This counter is not present in the GMAC-CORE configuration. */ -#define EMAC1_RXVLANFRM_GB 0xFFC221D8 /* EMAC1 Number of good and bad VLAN frames received. */ -#define EMAC1_RXWDOG_ERR 0xFFC221DC /* EMAC1 Frames received with error due to watchdog timeout */ -#define EMAC1_IPC_RXIMSK 0xFFC22200 /* EMAC1 MMC IPC RX Interrupt Mask Register */ -#define EMAC1_IPC_RXINT 0xFFC22208 /* EMAC1 MMC IPC RX Interrupt Register */ -#define EMAC1_RXIPV4_GD_FRM 0xFFC22210 /* EMAC1 Number of good IPv4 datagrams */ -#define EMAC1_RXIPV4_HDR_ERR_FRM 0xFFC22214 /* EMAC1 Number of IPv4 datagrams with header errors */ -#define EMAC1_RXIPV4_NOPAY_FRM 0xFFC22218 /* EMAC1 Number of IPv4 datagrams without checksum */ -#define EMAC1_RXIPV4_FRAG_FRM 0xFFC2221C /* EMAC1 Number of good IPv4 datagrams with fragmentation */ -#define EMAC1_RXIPV4_UDSBL_FRM 0xFFC22220 /* EMAC1 Number of IPv4 UDP datagrams with disabled checksum */ -#define EMAC1_RXIPV6_GD_FRM 0xFFC22224 /* EMAC1 Number of IPv4 datagrams with TCP/UDP/ICMP payloads */ -#define EMAC1_RXIPV6_HDR_ERR_FRM 0xFFC22228 /* EMAC1 Number of IPv6 datagrams with header errors */ -#define EMAC1_RXIPV6_NOPAY_FRM 0xFFC2222C /* EMAC1 Number of IPv6 datagrams with no TCP/UDP/ICMP payload */ -#define EMAC1_RXUDP_GD_FRM 0xFFC22230 /* EMAC1 Number of good IP datagrames with good UDP payload */ -#define EMAC1_RXUDP_ERR_FRM 0xFFC22234 /* EMAC1 Number of good IP datagrams with UDP checksum errors */ -#define EMAC1_RXTCP_GD_FRM 0xFFC22238 /* EMAC1 Number of good IP datagrams with a good TCP payload */ -#define EMAC1_RXTCP_ERR_FRM 0xFFC2223C /* EMAC1 Number of good IP datagrams with TCP checksum errors */ -#define EMAC1_RXICMP_GD_FRM 0xFFC22240 /* EMAC1 Number of good IP datagrams with a good ICMP payload */ -#define EMAC1_RXICMP_ERR_FRM 0xFFC22244 /* EMAC1 Number of good IP datagrams with ICMP checksum errors */ -#define EMAC1_RXIPV4_GD_OCT 0xFFC22250 /* EMAC1 Bytes received in IPv4 datagrams including tcp,udp or icmp */ -#define EMAC1_RXIPV4_HDR_ERR_OCT 0xFFC22254 /* EMAC1 Bytes received in IPv4 datagrams with header errors */ -#define EMAC1_RXIPV4_NOPAY_OCT 0xFFC22258 /* EMAC1 Bytes received in IPv4 datagrams without tcp,udp,icmp load */ -#define EMAC1_RXIPV4_FRAG_OCT 0xFFC2225C /* EMAC1 Bytes received in fragmented IPv4 datagrams */ -#define EMAC1_RXIPV4_UDSBL_OCT 0xFFC22260 /* EMAC1 Bytes received in UDP segment with checksum disabled */ -#define EMAC1_RXIPV6_GD_OCT 0xFFC22264 /* EMAC1 Bytes received in good IPv6 including tcp,udp or icmp load */ -#define EMAC1_RXIPV6_HDR_ERR_OCT 0xFFC22268 /* EMAC1 Number of bytes received in IPv6 with header errors */ -#define EMAC1_RXIPV6_NOPAY_OCT 0xFFC2226C /* EMAC1 Bytes received in IPv6 without tcp,udp or icmp load */ -#define EMAC1_RXUDP_GD_OCT 0xFFC22270 /* EMAC1 Number of bytes received in good UDP segments */ -#define EMAC1_RXUDP_ERR_OCT 0xFFC22274 /* EMAC1 Number of bytes received in UDP segment with checksum err */ -#define EMAC1_RXTCP_GD_OCT 0xFFC22278 /* EMAC1 Number of bytes received in a good TCP segment */ -#define EMAC1_RXTCP_ERR_OCT 0xFFC2227C /* EMAC1 Number of bytes received in TCP segment with checksum err */ -#define EMAC1_RXICMP_GD_OCT 0xFFC22280 /* EMAC1 Number of bytes received in a good ICMP segment */ -#define EMAC1_RXICMP_ERR_OCT 0xFFC22284 /* EMAC1 Bytes received in an ICMP segment with checksum errors */ -#define EMAC1_TM_CTL 0xFFC22700 /* EMAC1 EMAC Time Stamp Control Register */ -#define EMAC1_TM_SUBSEC 0xFFC22704 /* EMAC1 EMAC Time Stamp Sub Second Increment */ -#define EMAC1_TM_SEC 0xFFC22708 /* EMAC1 EMAC Time Stamp Second Register */ -#define EMAC1_TM_NSEC 0xFFC2270C /* EMAC1 EMAC Time Stamp Nano Second Register */ -#define EMAC1_TM_SECUPDT 0xFFC22710 /* EMAC1 EMAC Time Stamp Seconds Update */ -#define EMAC1_TM_NSECUPDT 0xFFC22714 /* EMAC1 EMAC Time Stamp Nano Seconds Update */ -#define EMAC1_TM_ADDEND 0xFFC22718 /* EMAC1 EMAC Time Stamp Addend Register */ -#define EMAC1_TM_TGTM 0xFFC2271C /* EMAC1 EMAC Time Stamp Target Time Sec. */ -#define EMAC1_TM_NTGTM 0xFFC22720 /* EMAC1 EMAC Time Stamp Target Time Nanosec. */ -#define EMAC1_TM_HISEC 0xFFC22724 /* EMAC1 EMAC Time Stamp High Second Register */ -#define EMAC1_TM_STMPSTAT 0xFFC22728 /* EMAC1 EMAC Time Stamp Status Register */ -#define EMAC1_TM_PPSCTL 0xFFC2272C /* EMAC1 EMAC PPS Control Register */ -#define EMAC1_TM_AUXSTMP_NSEC 0xFFC22730 /* EMAC1 EMAC Auxillary Time Stamp Nano Register */ -#define EMAC1_TM_AUXSTMP_SEC 0xFFC22734 /* EMAC1 EMAC Auxillary Time Stamp Sec Register */ -#define EMAC1_DMA_BUSMODE 0xFFC23000 /* EMAC1 Bus Operating Modes for EMAC DMA */ -#define EMAC1_DMA_TXPOLL 0xFFC23004 /* EMAC1 TX DMA Poll demand register */ -#define EMAC1_DMA_RXPOLL 0xFFC23008 /* EMAC1 RX DMA Poll demand register */ -#define EMAC1_DMA_RXDSC_ADDR 0xFFC2300C /* EMAC1 RX Descriptor List Address */ -#define EMAC1_DMA_TXDSC_ADDR 0xFFC23010 /* EMAC1 TX Descriptor List Address */ -#define EMAC1_DMA_STAT 0xFFC23014 /* EMAC1 DMA Status Register */ -#define EMAC1_DMA_OPMODE 0xFFC23018 /* EMAC1 DMA Operation Mode Register */ -#define EMAC1_DMA_IEN 0xFFC2301C /* EMAC1 DMA Interrupt Enable Register */ -#define EMAC1_DMA_MISS_FRM 0xFFC23020 /* EMAC1 DMA missed frame and buffer overflow counter */ -#define EMAC1_DMA_RXIWDOG 0xFFC23024 /* EMAC1 DMA RX Interrupt Watch Dog timer */ -#define EMAC1_DMA_BMMODE 0xFFC23028 /* EMAC1 AXI Bus Mode Register */ -#define EMAC1_DMA_BMSTAT 0xFFC2302C /* EMAC1 AXI Status Register */ -#define EMAC1_DMA_TXDSC_CUR 0xFFC23048 /* EMAC1 TX current descriptor register */ -#define EMAC1_DMA_RXDSC_CUR 0xFFC2304C /* EMAC1 RX current descriptor register */ -#define EMAC1_DMA_TXBUF_CUR 0xFFC23050 /* EMAC1 TX current buffer pointer register */ -#define EMAC1_DMA_RXBUF_CUR 0xFFC23054 /* EMAC1 RX current buffer pointer register */ -#define EMAC1_HWFEAT 0xFFC23058 /* EMAC1 Hardware Feature Register */ - - -/* ========================= - SPI Registers - ========================= */ - -/* ========================= - SPI0 - ========================= */ -#define SPI0_REGBASE 0xFFC40400 -#define SPI0_CTL 0xFFC40404 /* SPI0 Control Register */ -#define SPI0_RXCTL 0xFFC40408 /* SPI0 RX Control Register */ -#define SPI0_TXCTL 0xFFC4040C /* SPI0 TX Control Register */ -#define SPI0_CLK 0xFFC40410 /* SPI0 Clock Rate Register */ -#define SPI0_DLY 0xFFC40414 /* SPI0 Delay Register */ -#define SPI0_SLVSEL 0xFFC40418 /* SPI0 Slave Select Register */ -#define SPI0_RWC 0xFFC4041C /* SPI0 Received Word-Count Register */ -#define SPI0_RWCR 0xFFC40420 /* SPI0 Received Word-Count Reload Register */ -#define SPI0_TWC 0xFFC40424 /* SPI0 Transmitted Word-Count Register */ -#define SPI0_TWCR 0xFFC40428 /* SPI0 Transmitted Word-Count Reload Register */ -#define SPI0_IMSK 0xFFC40430 /* SPI0 Interrupt Mask Register */ -#define SPI0_IMSK_CLR 0xFFC40434 /* SPI0 Interrupt Mask Clear Register */ -#define SPI0_IMSK_SET 0xFFC40438 /* SPI0 Interrupt Mask Set Register */ -#define SPI0_STAT 0xFFC40440 /* SPI0 Status Register */ -#define SPI0_ILAT 0xFFC40444 /* SPI0 Masked Interrupt Condition Register */ -#define SPI0_ILAT_CLR 0xFFC40448 /* SPI0 Masked Interrupt Clear Register */ -#define SPI0_RFIFO 0xFFC40450 /* SPI0 Receive FIFO Data Register */ -#define SPI0_TFIFO 0xFFC40458 /* SPI0 Transmit FIFO Data Register */ - -/* ========================= - SPI1 - ========================= */ -#define SPI1_REGBASE 0xFFC40500 -#define SPI1_CTL 0xFFC40504 /* SPI1 Control Register */ -#define SPI1_RXCTL 0xFFC40508 /* SPI1 RX Control Register */ -#define SPI1_TXCTL 0xFFC4050C /* SPI1 TX Control Register */ -#define SPI1_CLK 0xFFC40510 /* SPI1 Clock Rate Register */ -#define SPI1_DLY 0xFFC40514 /* SPI1 Delay Register */ -#define SPI1_SLVSEL 0xFFC40518 /* SPI1 Slave Select Register */ -#define SPI1_RWC 0xFFC4051C /* SPI1 Received Word-Count Register */ -#define SPI1_RWCR 0xFFC40520 /* SPI1 Received Word-Count Reload Register */ -#define SPI1_TWC 0xFFC40524 /* SPI1 Transmitted Word-Count Register */ -#define SPI1_TWCR 0xFFC40528 /* SPI1 Transmitted Word-Count Reload Register */ -#define SPI1_IMSK 0xFFC40530 /* SPI1 Interrupt Mask Register */ -#define SPI1_IMSK_CLR 0xFFC40534 /* SPI1 Interrupt Mask Clear Register */ -#define SPI1_IMSK_SET 0xFFC40538 /* SPI1 Interrupt Mask Set Register */ -#define SPI1_STAT 0xFFC40540 /* SPI1 Status Register */ -#define SPI1_ILAT 0xFFC40544 /* SPI1 Masked Interrupt Condition Register */ -#define SPI1_ILAT_CLR 0xFFC40548 /* SPI1 Masked Interrupt Clear Register */ -#define SPI1_RFIFO 0xFFC40550 /* SPI1 Receive FIFO Data Register */ -#define SPI1_TFIFO 0xFFC40558 /* SPI1 Transmit FIFO Data Register */ - -/* ========================= - SPORT Registers - ========================= */ - -/* ========================= - SPORT0 - ========================= */ -#define SPORT0_CTL_A 0xFFC40000 /* SPORT0 'A' Control Register */ -#define SPORT0_DIV_A 0xFFC40004 /* SPORT0 'A' Clock and FS Divide Register */ -#define SPORT0_MCTL_A 0xFFC40008 /* SPORT0 'A' Multichannel Control Register */ -#define SPORT0_CS0_A 0xFFC4000C /* SPORT0 'A' Multichannel Select Register (Channels 0-31) */ -#define SPORT0_CS1_A 0xFFC40010 /* SPORT0 'A' Multichannel Select Register (Channels 32-63) */ -#define SPORT0_CS2_A 0xFFC40014 /* SPORT0 'A' Multichannel Select Register (Channels 64-95) */ -#define SPORT0_CS3_A 0xFFC40018 /* SPORT0 'A' Multichannel Select Register (Channels 96-127) */ -#define SPORT0_CNT_A 0xFFC4001C /* SPORT0 'A' Frame Sync And Clock Divisor Current Count */ -#define SPORT0_ERR_A 0xFFC40020 /* SPORT0 'A' Error Register */ -#define SPORT0_MSTAT_A 0xFFC40024 /* SPORT0 'A' Multichannel Mode Status Register */ -#define SPORT0_CTL2_A 0xFFC40028 /* SPORT0 'A' Control Register 2 */ -#define SPORT0_TXPRI_A 0xFFC40040 /* SPORT0 'A' Primary Channel Transmit Buffer Register */ -#define SPORT0_RXPRI_A 0xFFC40044 /* SPORT0 'A' Primary Channel Receive Buffer Register */ -#define SPORT0_TXSEC_A 0xFFC40048 /* SPORT0 'A' Secondary Channel Transmit Buffer Register */ -#define SPORT0_RXSEC_A 0xFFC4004C /* SPORT0 'A' Secondary Channel Receive Buffer Register */ -#define SPORT0_CTL_B 0xFFC40080 /* SPORT0 'B' Control Register */ -#define SPORT0_DIV_B 0xFFC40084 /* SPORT0 'B' Clock and FS Divide Register */ -#define SPORT0_MCTL_B 0xFFC40088 /* SPORT0 'B' Multichannel Control Register */ -#define SPORT0_CS0_B 0xFFC4008C /* SPORT0 'B' Multichannel Select Register (Channels 0-31) */ -#define SPORT0_CS1_B 0xFFC40090 /* SPORT0 'B' Multichannel Select Register (Channels 32-63) */ -#define SPORT0_CS2_B 0xFFC40094 /* SPORT0 'B' Multichannel Select Register (Channels 64-95) */ -#define SPORT0_CS3_B 0xFFC40098 /* SPORT0 'B' Multichannel Select Register (Channels 96-127) */ -#define SPORT0_CNT_B 0xFFC4009C /* SPORT0 'B' Frame Sync And Clock Divisor Current Count */ -#define SPORT0_ERR_B 0xFFC400A0 /* SPORT0 'B' Error Register */ -#define SPORT0_MSTAT_B 0xFFC400A4 /* SPORT0 'B' Multichannel Mode Status Register */ -#define SPORT0_CTL2_B 0xFFC400A8 /* SPORT0 'B' Control Register 2 */ -#define SPORT0_TXPRI_B 0xFFC400C0 /* SPORT0 'B' Primary Channel Transmit Buffer Register */ -#define SPORT0_RXPRI_B 0xFFC400C4 /* SPORT0 'B' Primary Channel Receive Buffer Register */ -#define SPORT0_TXSEC_B 0xFFC400C8 /* SPORT0 'B' Secondary Channel Transmit Buffer Register */ -#define SPORT0_RXSEC_B 0xFFC400CC /* SPORT0 'B' Secondary Channel Receive Buffer Register */ - -/* ========================= - SPORT1 - ========================= */ -#define SPORT1_CTL_A 0xFFC40100 /* SPORT1 'A' Control Register */ -#define SPORT1_DIV_A 0xFFC40104 /* SPORT1 'A' Clock and FS Divide Register */ -#define SPORT1_MCTL_A 0xFFC40108 /* SPORT1 'A' Multichannel Control Register */ -#define SPORT1_CS0_A 0xFFC4010C /* SPORT1 'A' Multichannel Select Register (Channels 0-31) */ -#define SPORT1_CS1_A 0xFFC40110 /* SPORT1 'A' Multichannel Select Register (Channels 32-63) */ -#define SPORT1_CS2_A 0xFFC40114 /* SPORT1 'A' Multichannel Select Register (Channels 64-95) */ -#define SPORT1_CS3_A 0xFFC40118 /* SPORT1 'A' Multichannel Select Register (Channels 96-127) */ -#define SPORT1_CNT_A 0xFFC4011C /* SPORT1 'A' Frame Sync And Clock Divisor Current Count */ -#define SPORT1_ERR_A 0xFFC40120 /* SPORT1 'A' Error Register */ -#define SPORT1_MSTAT_A 0xFFC40124 /* SPORT1 'A' Multichannel Mode Status Register */ -#define SPORT1_CTL2_A 0xFFC40128 /* SPORT1 'A' Control Register 2 */ -#define SPORT1_TXPRI_A 0xFFC40140 /* SPORT1 'A' Primary Channel Transmit Buffer Register */ -#define SPORT1_RXPRI_A 0xFFC40144 /* SPORT1 'A' Primary Channel Receive Buffer Register */ -#define SPORT1_TXSEC_A 0xFFC40148 /* SPORT1 'A' Secondary Channel Transmit Buffer Register */ -#define SPORT1_RXSEC_A 0xFFC4014C /* SPORT1 'A' Secondary Channel Receive Buffer Register */ -#define SPORT1_CTL_B 0xFFC40180 /* SPORT1 'B' Control Register */ -#define SPORT1_DIV_B 0xFFC40184 /* SPORT1 'B' Clock and FS Divide Register */ -#define SPORT1_MCTL_B 0xFFC40188 /* SPORT1 'B' Multichannel Control Register */ -#define SPORT1_CS0_B 0xFFC4018C /* SPORT1 'B' Multichannel Select Register (Channels 0-31) */ -#define SPORT1_CS1_B 0xFFC40190 /* SPORT1 'B' Multichannel Select Register (Channels 32-63) */ -#define SPORT1_CS2_B 0xFFC40194 /* SPORT1 'B' Multichannel Select Register (Channels 64-95) */ -#define SPORT1_CS3_B 0xFFC40198 /* SPORT1 'B' Multichannel Select Register (Channels 96-127) */ -#define SPORT1_CNT_B 0xFFC4019C /* SPORT1 'B' Frame Sync And Clock Divisor Current Count */ -#define SPORT1_ERR_B 0xFFC401A0 /* SPORT1 'B' Error Register */ -#define SPORT1_MSTAT_B 0xFFC401A4 /* SPORT1 'B' Multichannel Mode Status Register */ -#define SPORT1_CTL2_B 0xFFC401A8 /* SPORT1 'B' Control Register 2 */ -#define SPORT1_TXPRI_B 0xFFC401C0 /* SPORT1 'B' Primary Channel Transmit Buffer Register */ -#define SPORT1_RXPRI_B 0xFFC401C4 /* SPORT1 'B' Primary Channel Receive Buffer Register */ -#define SPORT1_TXSEC_B 0xFFC401C8 /* SPORT1 'B' Secondary Channel Transmit Buffer Register */ -#define SPORT1_RXSEC_B 0xFFC401CC /* SPORT1 'B' Secondary Channel Receive Buffer Register */ - -/* ========================= - SPORT2 - ========================= */ -#define SPORT2_CTL_A 0xFFC40200 /* SPORT2 'A' Control Register */ -#define SPORT2_DIV_A 0xFFC40204 /* SPORT2 'A' Clock and FS Divide Register */ -#define SPORT2_MCTL_A 0xFFC40208 /* SPORT2 'A' Multichannel Control Register */ -#define SPORT2_CS0_A 0xFFC4020C /* SPORT2 'A' Multichannel Select Register (Channels 0-31) */ -#define SPORT2_CS1_A 0xFFC40210 /* SPORT2 'A' Multichannel Select Register (Channels 32-63) */ -#define SPORT2_CS2_A 0xFFC40214 /* SPORT2 'A' Multichannel Select Register (Channels 64-95) */ -#define SPORT2_CS3_A 0xFFC40218 /* SPORT2 'A' Multichannel Select Register (Channels 96-127) */ -#define SPORT2_CNT_A 0xFFC4021C /* SPORT2 'A' Frame Sync And Clock Divisor Current Count */ -#define SPORT2_ERR_A 0xFFC40220 /* SPORT2 'A' Error Register */ -#define SPORT2_MSTAT_A 0xFFC40224 /* SPORT2 'A' Multichannel Mode Status Register */ -#define SPORT2_CTL2_A 0xFFC40228 /* SPORT2 'A' Control Register 2 */ -#define SPORT2_TXPRI_A 0xFFC40240 /* SPORT2 'A' Primary Channel Transmit Buffer Register */ -#define SPORT2_RXPRI_A 0xFFC40244 /* SPORT2 'A' Primary Channel Receive Buffer Register */ -#define SPORT2_TXSEC_A 0xFFC40248 /* SPORT2 'A' Secondary Channel Transmit Buffer Register */ -#define SPORT2_RXSEC_A 0xFFC4024C /* SPORT2 'A' Secondary Channel Receive Buffer Register */ -#define SPORT2_CTL_B 0xFFC40280 /* SPORT2 'B' Control Register */ -#define SPORT2_DIV_B 0xFFC40284 /* SPORT2 'B' Clock and FS Divide Register */ -#define SPORT2_MCTL_B 0xFFC40288 /* SPORT2 'B' Multichannel Control Register */ -#define SPORT2_CS0_B 0xFFC4028C /* SPORT2 'B' Multichannel Select Register (Channels 0-31) */ -#define SPORT2_CS1_B 0xFFC40290 /* SPORT2 'B' Multichannel Select Register (Channels 32-63) */ -#define SPORT2_CS2_B 0xFFC40294 /* SPORT2 'B' Multichannel Select Register (Channels 64-95) */ -#define SPORT2_CS3_B 0xFFC40298 /* SPORT2 'B' Multichannel Select Register (Channels 96-127) */ -#define SPORT2_CNT_B 0xFFC4029C /* SPORT2 'B' Frame Sync And Clock Divisor Current Count */ -#define SPORT2_ERR_B 0xFFC402A0 /* SPORT2 'B' Error Register */ -#define SPORT2_MSTAT_B 0xFFC402A4 /* SPORT2 'B' Multichannel Mode Status Register */ -#define SPORT2_CTL2_B 0xFFC402A8 /* SPORT2 'B' Control Register 2 */ -#define SPORT2_TXPRI_B 0xFFC402C0 /* SPORT2 'B' Primary Channel Transmit Buffer Register */ -#define SPORT2_RXPRI_B 0xFFC402C4 /* SPORT2 'B' Primary Channel Receive Buffer Register */ -#define SPORT2_TXSEC_B 0xFFC402C8 /* SPORT2 'B' Secondary Channel Transmit Buffer Register */ -#define SPORT2_RXSEC_B 0xFFC402CC /* SPORT2 'B' Secondary Channel Receive Buffer Register */ - -/* ========================= - EPPI Registers - ========================= */ - -/* ========================= - EPPI0 - ========================= */ -#define EPPI0_STAT 0xFFC18000 /* EPPI0 Status Register */ -#define EPPI0_HCNT 0xFFC18004 /* EPPI0 Horizontal Transfer Count Register */ -#define EPPI0_HDLY 0xFFC18008 /* EPPI0 Horizontal Delay Count Register */ -#define EPPI0_VCNT 0xFFC1800C /* EPPI0 Vertical Transfer Count Register */ -#define EPPI0_VDLY 0xFFC18010 /* EPPI0 Vertical Delay Count Register */ -#define EPPI0_FRAME 0xFFC18014 /* EPPI0 Lines Per Frame Register */ -#define EPPI0_LINE 0xFFC18018 /* EPPI0 Samples Per Line Register */ -#define EPPI0_CLKDIV 0xFFC1801C /* EPPI0 Clock Divide Register */ -#define EPPI0_CTL 0xFFC18020 /* EPPI0 Control Register */ -#define EPPI0_FS1_WLHB 0xFFC18024 /* EPPI0 FS1 Width Register / EPPI Horizontal Blanking Samples Per Line Register */ -#define EPPI0_FS1_PASPL 0xFFC18028 /* EPPI0 FS1 Period Register / EPPI Active Samples Per Line Register */ -#define EPPI0_FS2_WLVB 0xFFC1802C /* EPPI0 FS2 Width Register / EPPI Lines Of Vertical Blanking Register */ -#define EPPI0_FS2_PALPF 0xFFC18030 /* EPPI0 FS2 Period Register / EPPI Active Lines Per Field Register */ -#define EPPI0_IMSK 0xFFC18034 /* EPPI0 Interrupt Mask Register */ -#define EPPI0_ODDCLIP 0xFFC1803C /* EPPI0 Clipping Register for ODD (Chroma) Data */ -#define EPPI0_EVENCLIP 0xFFC18040 /* EPPI0 Clipping Register for EVEN (Luma) Data */ -#define EPPI0_FS1_DLY 0xFFC18044 /* EPPI0 Frame Sync 1 Delay Value */ -#define EPPI0_FS2_DLY 0xFFC18048 /* EPPI0 Frame Sync 2 Delay Value */ -#define EPPI0_CTL2 0xFFC1804C /* EPPI0 Control Register 2 */ - -/* ========================= - EPPI1 - ========================= */ -#define EPPI1_STAT 0xFFC18400 /* EPPI1 Status Register */ -#define EPPI1_HCNT 0xFFC18404 /* EPPI1 Horizontal Transfer Count Register */ -#define EPPI1_HDLY 0xFFC18408 /* EPPI1 Horizontal Delay Count Register */ -#define EPPI1_VCNT 0xFFC1840C /* EPPI1 Vertical Transfer Count Register */ -#define EPPI1_VDLY 0xFFC18410 /* EPPI1 Vertical Delay Count Register */ -#define EPPI1_FRAME 0xFFC18414 /* EPPI1 Lines Per Frame Register */ -#define EPPI1_LINE 0xFFC18418 /* EPPI1 Samples Per Line Register */ -#define EPPI1_CLKDIV 0xFFC1841C /* EPPI1 Clock Divide Register */ -#define EPPI1_CTL 0xFFC18420 /* EPPI1 Control Register */ -#define EPPI1_FS1_WLHB 0xFFC18424 /* EPPI1 FS1 Width Register / EPPI Horizontal Blanking Samples Per Line Register */ -#define EPPI1_FS1_PASPL 0xFFC18428 /* EPPI1 FS1 Period Register / EPPI Active Samples Per Line Register */ -#define EPPI1_FS2_WLVB 0xFFC1842C /* EPPI1 FS2 Width Register / EPPI Lines Of Vertical Blanking Register */ -#define EPPI1_FS2_PALPF 0xFFC18430 /* EPPI1 FS2 Period Register / EPPI Active Lines Per Field Register */ -#define EPPI1_IMSK 0xFFC18434 /* EPPI1 Interrupt Mask Register */ -#define EPPI1_ODDCLIP 0xFFC1843C /* EPPI1 Clipping Register for ODD (Chroma) Data */ -#define EPPI1_EVENCLIP 0xFFC18440 /* EPPI1 Clipping Register for EVEN (Luma) Data */ -#define EPPI1_FS1_DLY 0xFFC18444 /* EPPI1 Frame Sync 1 Delay Value */ -#define EPPI1_FS2_DLY 0xFFC18448 /* EPPI1 Frame Sync 2 Delay Value */ -#define EPPI1_CTL2 0xFFC1844C /* EPPI1 Control Register 2 */ - -/* ========================= - EPPI2 - ========================= */ -#define EPPI2_STAT 0xFFC18800 /* EPPI2 Status Register */ -#define EPPI2_HCNT 0xFFC18804 /* EPPI2 Horizontal Transfer Count Register */ -#define EPPI2_HDLY 0xFFC18808 /* EPPI2 Horizontal Delay Count Register */ -#define EPPI2_VCNT 0xFFC1880C /* EPPI2 Vertical Transfer Count Register */ -#define EPPI2_VDLY 0xFFC18810 /* EPPI2 Vertical Delay Count Register */ -#define EPPI2_FRAME 0xFFC18814 /* EPPI2 Lines Per Frame Register */ -#define EPPI2_LINE 0xFFC18818 /* EPPI2 Samples Per Line Register */ -#define EPPI2_CLKDIV 0xFFC1881C /* EPPI2 Clock Divide Register */ -#define EPPI2_CTL 0xFFC18820 /* EPPI2 Control Register */ -#define EPPI2_FS1_WLHB 0xFFC18824 /* EPPI2 FS1 Width Register / EPPI Horizontal Blanking Samples Per Line Register */ -#define EPPI2_FS1_PASPL 0xFFC18828 /* EPPI2 FS1 Period Register / EPPI Active Samples Per Line Register */ -#define EPPI2_FS2_WLVB 0xFFC1882C /* EPPI2 FS2 Width Register / EPPI Lines Of Vertical Blanking Register */ -#define EPPI2_FS2_PALPF 0xFFC18830 /* EPPI2 FS2 Period Register / EPPI Active Lines Per Field Register */ -#define EPPI2_IMSK 0xFFC18834 /* EPPI2 Interrupt Mask Register */ -#define EPPI2_ODDCLIP 0xFFC1883C /* EPPI2 Clipping Register for ODD (Chroma) Data */ -#define EPPI2_EVENCLIP 0xFFC18840 /* EPPI2 Clipping Register for EVEN (Luma) Data */ -#define EPPI2_FS1_DLY 0xFFC18844 /* EPPI2 Frame Sync 1 Delay Value */ -#define EPPI2_FS2_DLY 0xFFC18848 /* EPPI2 Frame Sync 2 Delay Value */ -#define EPPI2_CTL2 0xFFC1884C /* EPPI2 Control Register 2 */ - - - -/* ========================= - DDE Registers - ========================= */ - -/* ========================= - DMA0 - ========================= */ -#define DMA0_NEXT_DESC_PTR 0xFFC41000 /* DMA0 Pointer to Next Initial Descriptor */ -#define DMA0_START_ADDR 0xFFC41004 /* DMA0 Start Address of Current Buffer */ -#define DMA0_CONFIG 0xFFC41008 /* DMA0 Configuration Register */ -#define DMA0_X_COUNT 0xFFC4100C /* DMA0 Inner Loop Count Start Value */ -#define DMA0_X_MODIFY 0xFFC41010 /* DMA0 Inner Loop Address Increment */ -#define DMA0_Y_COUNT 0xFFC41014 /* DMA0 Outer Loop Count Start Value (2D only) */ -#define DMA0_Y_MODIFY 0xFFC41018 /* DMA0 Outer Loop Address Increment (2D only) */ -#define DMA0_CURR_DESC_PTR 0xFFC41024 /* DMA0 Current Descriptor Pointer */ -#define DMA0_PREV_DESC_PTR 0xFFC41028 /* DMA0 Previous Initial Descriptor Pointer */ -#define DMA0_CURR_ADDR 0xFFC4102C /* DMA0 Current Address */ -#define DMA0_IRQ_STATUS 0xFFC41030 /* DMA0 Status Register */ -#define DMA0_CURR_X_COUNT 0xFFC41034 /* DMA0 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA0_CURR_Y_COUNT 0xFFC41038 /* DMA0 Current Row Count (2D only) */ -#define DMA0_BWL_COUNT 0xFFC41040 /* DMA0 Bandwidth Limit Count */ -#define DMA0_CURR_BWL_COUNT 0xFFC41044 /* DMA0 Bandwidth Limit Count Current */ -#define DMA0_BWM_COUNT 0xFFC41048 /* DMA0 Bandwidth Monitor Count */ -#define DMA0_CURR_BWM_COUNT 0xFFC4104C /* DMA0 Bandwidth Monitor Count Current */ - -/* ========================= - DMA1 - ========================= */ -#define DMA1_NEXT_DESC_PTR 0xFFC41080 /* DMA1 Pointer to Next Initial Descriptor */ -#define DMA1_START_ADDR 0xFFC41084 /* DMA1 Start Address of Current Buffer */ -#define DMA1_CONFIG 0xFFC41088 /* DMA1 Configuration Register */ -#define DMA1_X_COUNT 0xFFC4108C /* DMA1 Inner Loop Count Start Value */ -#define DMA1_X_MODIFY 0xFFC41090 /* DMA1 Inner Loop Address Increment */ -#define DMA1_Y_COUNT 0xFFC41094 /* DMA1 Outer Loop Count Start Value (2D only) */ -#define DMA1_Y_MODIFY 0xFFC41098 /* DMA1 Outer Loop Address Increment (2D only) */ -#define DMA1_CURR_DESC_PTR 0xFFC410A4 /* DMA1 Current Descriptor Pointer */ -#define DMA1_PREV_DESC_PTR 0xFFC410A8 /* DMA1 Previous Initial Descriptor Pointer */ -#define DMA1_CURR_ADDR 0xFFC410AC /* DMA1 Current Address */ -#define DMA1_IRQ_STATUS 0xFFC410B0 /* DMA1 Status Register */ -#define DMA1_CURR_X_COUNT 0xFFC410B4 /* DMA1 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA1_CURR_Y_COUNT 0xFFC410B8 /* DMA1 Current Row Count (2D only) */ -#define DMA1_BWL_COUNT 0xFFC410C0 /* DMA1 Bandwidth Limit Count */ -#define DMA1_CURR_BWL_COUNT 0xFFC410C4 /* DMA1 Bandwidth Limit Count Current */ -#define DMA1_BWM_COUNT 0xFFC410C8 /* DMA1 Bandwidth Monitor Count */ -#define DMA1_CURR_BWM_COUNT 0xFFC410CC /* DMA1 Bandwidth Monitor Count Current */ - -/* ========================= - DMA2 - ========================= */ -#define DMA2_NEXT_DESC_PTR 0xFFC41100 /* DMA2 Pointer to Next Initial Descriptor */ -#define DMA2_START_ADDR 0xFFC41104 /* DMA2 Start Address of Current Buffer */ -#define DMA2_CONFIG 0xFFC41108 /* DMA2 Configuration Register */ -#define DMA2_X_COUNT 0xFFC4110C /* DMA2 Inner Loop Count Start Value */ -#define DMA2_X_MODIFY 0xFFC41110 /* DMA2 Inner Loop Address Increment */ -#define DMA2_Y_COUNT 0xFFC41114 /* DMA2 Outer Loop Count Start Value (2D only) */ -#define DMA2_Y_MODIFY 0xFFC41118 /* DMA2 Outer Loop Address Increment (2D only) */ -#define DMA2_CURR_DESC_PTR 0xFFC41124 /* DMA2 Current Descriptor Pointer */ -#define DMA2_PREV_DESC_PTR 0xFFC41128 /* DMA2 Previous Initial Descriptor Pointer */ -#define DMA2_CURR_ADDR 0xFFC4112C /* DMA2 Current Address */ -#define DMA2_IRQ_STATUS 0xFFC41130 /* DMA2 Status Register */ -#define DMA2_CURR_X_COUNT 0xFFC41134 /* DMA2 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA2_CURR_Y_COUNT 0xFFC41138 /* DMA2 Current Row Count (2D only) */ -#define DMA2_BWL_COUNT 0xFFC41140 /* DMA2 Bandwidth Limit Count */ -#define DMA2_CURR_BWL_COUNT 0xFFC41144 /* DMA2 Bandwidth Limit Count Current */ -#define DMA2_BWM_COUNT 0xFFC41148 /* DMA2 Bandwidth Monitor Count */ -#define DMA2_CURR_BWM_COUNT 0xFFC4114C /* DMA2 Bandwidth Monitor Count Current */ - -/* ========================= - DMA3 - ========================= */ -#define DMA3_NEXT_DESC_PTR 0xFFC41180 /* DMA3 Pointer to Next Initial Descriptor */ -#define DMA3_START_ADDR 0xFFC41184 /* DMA3 Start Address of Current Buffer */ -#define DMA3_CONFIG 0xFFC41188 /* DMA3 Configuration Register */ -#define DMA3_X_COUNT 0xFFC4118C /* DMA3 Inner Loop Count Start Value */ -#define DMA3_X_MODIFY 0xFFC41190 /* DMA3 Inner Loop Address Increment */ -#define DMA3_Y_COUNT 0xFFC41194 /* DMA3 Outer Loop Count Start Value (2D only) */ -#define DMA3_Y_MODIFY 0xFFC41198 /* DMA3 Outer Loop Address Increment (2D only) */ -#define DMA3_CURR_DESC_PTR 0xFFC411A4 /* DMA3 Current Descriptor Pointer */ -#define DMA3_PREV_DESC_PTR 0xFFC411A8 /* DMA3 Previous Initial Descriptor Pointer */ -#define DMA3_CURR_ADDR 0xFFC411AC /* DMA3 Current Address */ -#define DMA3_IRQ_STATUS 0xFFC411B0 /* DMA3 Status Register */ -#define DMA3_CURR_X_COUNT 0xFFC411B4 /* DMA3 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA3_CURR_Y_COUNT 0xFFC411B8 /* DMA3 Current Row Count (2D only) */ -#define DMA3_BWL_COUNT 0xFFC411C0 /* DMA3 Bandwidth Limit Count */ -#define DMA3_CURR_BWL_COUNT 0xFFC411C4 /* DMA3 Bandwidth Limit Count Current */ -#define DMA3_BWM_COUNT 0xFFC411C8 /* DMA3 Bandwidth Monitor Count */ -#define DMA3_CURR_BWM_COUNT 0xFFC411CC /* DMA3 Bandwidth Monitor Count Current */ - -/* ========================= - DMA4 - ========================= */ -#define DMA4_NEXT_DESC_PTR 0xFFC41200 /* DMA4 Pointer to Next Initial Descriptor */ -#define DMA4_START_ADDR 0xFFC41204 /* DMA4 Start Address of Current Buffer */ -#define DMA4_CONFIG 0xFFC41208 /* DMA4 Configuration Register */ -#define DMA4_X_COUNT 0xFFC4120C /* DMA4 Inner Loop Count Start Value */ -#define DMA4_X_MODIFY 0xFFC41210 /* DMA4 Inner Loop Address Increment */ -#define DMA4_Y_COUNT 0xFFC41214 /* DMA4 Outer Loop Count Start Value (2D only) */ -#define DMA4_Y_MODIFY 0xFFC41218 /* DMA4 Outer Loop Address Increment (2D only) */ -#define DMA4_CURR_DESC_PTR 0xFFC41224 /* DMA4 Current Descriptor Pointer */ -#define DMA4_PREV_DESC_PTR 0xFFC41228 /* DMA4 Previous Initial Descriptor Pointer */ -#define DMA4_CURR_ADDR 0xFFC4122C /* DMA4 Current Address */ -#define DMA4_IRQ_STATUS 0xFFC41230 /* DMA4 Status Register */ -#define DMA4_CURR_X_COUNT 0xFFC41234 /* DMA4 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA4_CURR_Y_COUNT 0xFFC41238 /* DMA4 Current Row Count (2D only) */ -#define DMA4_BWL_COUNT 0xFFC41240 /* DMA4 Bandwidth Limit Count */ -#define DMA4_CURR_BWL_COUNT 0xFFC41244 /* DMA4 Bandwidth Limit Count Current */ -#define DMA4_BWM_COUNT 0xFFC41248 /* DMA4 Bandwidth Monitor Count */ -#define DMA4_CURR_BWM_COUNT 0xFFC4124C /* DMA4 Bandwidth Monitor Count Current */ - -/* ========================= - DMA5 - ========================= */ -#define DMA5_NEXT_DESC_PTR 0xFFC41280 /* DMA5 Pointer to Next Initial Descriptor */ -#define DMA5_START_ADDR 0xFFC41284 /* DMA5 Start Address of Current Buffer */ -#define DMA5_CONFIG 0xFFC41288 /* DMA5 Configuration Register */ -#define DMA5_X_COUNT 0xFFC4128C /* DMA5 Inner Loop Count Start Value */ -#define DMA5_X_MODIFY 0xFFC41290 /* DMA5 Inner Loop Address Increment */ -#define DMA5_Y_COUNT 0xFFC41294 /* DMA5 Outer Loop Count Start Value (2D only) */ -#define DMA5_Y_MODIFY 0xFFC41298 /* DMA5 Outer Loop Address Increment (2D only) */ -#define DMA5_CURR_DESC_PTR 0xFFC412A4 /* DMA5 Current Descriptor Pointer */ -#define DMA5_PREV_DESC_PTR 0xFFC412A8 /* DMA5 Previous Initial Descriptor Pointer */ -#define DMA5_CURR_ADDR 0xFFC412AC /* DMA5 Current Address */ -#define DMA5_IRQ_STATUS 0xFFC412B0 /* DMA5 Status Register */ -#define DMA5_CURR_X_COUNT 0xFFC412B4 /* DMA5 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA5_CURR_Y_COUNT 0xFFC412B8 /* DMA5 Current Row Count (2D only) */ -#define DMA5_BWL_COUNT 0xFFC412C0 /* DMA5 Bandwidth Limit Count */ -#define DMA5_CURR_BWL_COUNT 0xFFC412C4 /* DMA5 Bandwidth Limit Count Current */ -#define DMA5_BWM_COUNT 0xFFC412C8 /* DMA5 Bandwidth Monitor Count */ -#define DMA5_CURR_BWM_COUNT 0xFFC412CC /* DMA5 Bandwidth Monitor Count Current */ - -/* ========================= - DMA6 - ========================= */ -#define DMA6_NEXT_DESC_PTR 0xFFC41300 /* DMA6 Pointer to Next Initial Descriptor */ -#define DMA6_START_ADDR 0xFFC41304 /* DMA6 Start Address of Current Buffer */ -#define DMA6_CONFIG 0xFFC41308 /* DMA6 Configuration Register */ -#define DMA6_X_COUNT 0xFFC4130C /* DMA6 Inner Loop Count Start Value */ -#define DMA6_X_MODIFY 0xFFC41310 /* DMA6 Inner Loop Address Increment */ -#define DMA6_Y_COUNT 0xFFC41314 /* DMA6 Outer Loop Count Start Value (2D only) */ -#define DMA6_Y_MODIFY 0xFFC41318 /* DMA6 Outer Loop Address Increment (2D only) */ -#define DMA6_CURR_DESC_PTR 0xFFC41324 /* DMA6 Current Descriptor Pointer */ -#define DMA6_PREV_DESC_PTR 0xFFC41328 /* DMA6 Previous Initial Descriptor Pointer */ -#define DMA6_CURR_ADDR 0xFFC4132C /* DMA6 Current Address */ -#define DMA6_IRQ_STATUS 0xFFC41330 /* DMA6 Status Register */ -#define DMA6_CURR_X_COUNT 0xFFC41334 /* DMA6 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA6_CURR_Y_COUNT 0xFFC41338 /* DMA6 Current Row Count (2D only) */ -#define DMA6_BWL_COUNT 0xFFC41340 /* DMA6 Bandwidth Limit Count */ -#define DMA6_CURR_BWL_COUNT 0xFFC41344 /* DMA6 Bandwidth Limit Count Current */ -#define DMA6_BWM_COUNT 0xFFC41348 /* DMA6 Bandwidth Monitor Count */ -#define DMA6_CURR_BWM_COUNT 0xFFC4134C /* DMA6 Bandwidth Monitor Count Current */ - -/* ========================= - DMA7 - ========================= */ -#define DMA7_NEXT_DESC_PTR 0xFFC41380 /* DMA7 Pointer to Next Initial Descriptor */ -#define DMA7_START_ADDR 0xFFC41384 /* DMA7 Start Address of Current Buffer */ -#define DMA7_CONFIG 0xFFC41388 /* DMA7 Configuration Register */ -#define DMA7_X_COUNT 0xFFC4138C /* DMA7 Inner Loop Count Start Value */ -#define DMA7_X_MODIFY 0xFFC41390 /* DMA7 Inner Loop Address Increment */ -#define DMA7_Y_COUNT 0xFFC41394 /* DMA7 Outer Loop Count Start Value (2D only) */ -#define DMA7_Y_MODIFY 0xFFC41398 /* DMA7 Outer Loop Address Increment (2D only) */ -#define DMA7_CURR_DESC_PTR 0xFFC413A4 /* DMA7 Current Descriptor Pointer */ -#define DMA7_PREV_DESC_PTR 0xFFC413A8 /* DMA7 Previous Initial Descriptor Pointer */ -#define DMA7_CURR_ADDR 0xFFC413AC /* DMA7 Current Address */ -#define DMA7_IRQ_STATUS 0xFFC413B0 /* DMA7 Status Register */ -#define DMA7_CURR_X_COUNT 0xFFC413B4 /* DMA7 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA7_CURR_Y_COUNT 0xFFC413B8 /* DMA7 Current Row Count (2D only) */ -#define DMA7_BWL_COUNT 0xFFC413C0 /* DMA7 Bandwidth Limit Count */ -#define DMA7_CURR_BWL_COUNT 0xFFC413C4 /* DMA7 Bandwidth Limit Count Current */ -#define DMA7_BWM_COUNT 0xFFC413C8 /* DMA7 Bandwidth Monitor Count */ -#define DMA7_CURR_BWM_COUNT 0xFFC413CC /* DMA7 Bandwidth Monitor Count Current */ - -/* ========================= - DMA8 - ========================= */ -#define DMA8_NEXT_DESC_PTR 0xFFC41400 /* DMA8 Pointer to Next Initial Descriptor */ -#define DMA8_START_ADDR 0xFFC41404 /* DMA8 Start Address of Current Buffer */ -#define DMA8_CONFIG 0xFFC41408 /* DMA8 Configuration Register */ -#define DMA8_X_COUNT 0xFFC4140C /* DMA8 Inner Loop Count Start Value */ -#define DMA8_X_MODIFY 0xFFC41410 /* DMA8 Inner Loop Address Increment */ -#define DMA8_Y_COUNT 0xFFC41414 /* DMA8 Outer Loop Count Start Value (2D only) */ -#define DMA8_Y_MODIFY 0xFFC41418 /* DMA8 Outer Loop Address Increment (2D only) */ -#define DMA8_CURR_DESC_PTR 0xFFC41424 /* DMA8 Current Descriptor Pointer */ -#define DMA8_PREV_DESC_PTR 0xFFC41428 /* DMA8 Previous Initial Descriptor Pointer */ -#define DMA8_CURR_ADDR 0xFFC4142C /* DMA8 Current Address */ -#define DMA8_IRQ_STATUS 0xFFC41430 /* DMA8 Status Register */ -#define DMA8_CURR_X_COUNT 0xFFC41434 /* DMA8 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA8_CURR_Y_COUNT 0xFFC41438 /* DMA8 Current Row Count (2D only) */ -#define DMA8_BWL_COUNT 0xFFC41440 /* DMA8 Bandwidth Limit Count */ -#define DMA8_CURR_BWL_COUNT 0xFFC41444 /* DMA8 Bandwidth Limit Count Current */ -#define DMA8_BWM_COUNT 0xFFC41448 /* DMA8 Bandwidth Monitor Count */ -#define DMA8_CURR_BWM_COUNT 0xFFC4144C /* DMA8 Bandwidth Monitor Count Current */ - -/* ========================= - DMA9 - ========================= */ -#define DMA9_NEXT_DESC_PTR 0xFFC41480 /* DMA9 Pointer to Next Initial Descriptor */ -#define DMA9_START_ADDR 0xFFC41484 /* DMA9 Start Address of Current Buffer */ -#define DMA9_CONFIG 0xFFC41488 /* DMA9 Configuration Register */ -#define DMA9_X_COUNT 0xFFC4148C /* DMA9 Inner Loop Count Start Value */ -#define DMA9_X_MODIFY 0xFFC41490 /* DMA9 Inner Loop Address Increment */ -#define DMA9_Y_COUNT 0xFFC41494 /* DMA9 Outer Loop Count Start Value (2D only) */ -#define DMA9_Y_MODIFY 0xFFC41498 /* DMA9 Outer Loop Address Increment (2D only) */ -#define DMA9_CURR_DESC_PTR 0xFFC414A4 /* DMA9 Current Descriptor Pointer */ -#define DMA9_PREV_DESC_PTR 0xFFC414A8 /* DMA9 Previous Initial Descriptor Pointer */ -#define DMA9_CURR_ADDR 0xFFC414AC /* DMA9 Current Address */ -#define DMA9_IRQ_STATUS 0xFFC414B0 /* DMA9 Status Register */ -#define DMA9_CURR_X_COUNT 0xFFC414B4 /* DMA9 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA9_CURR_Y_COUNT 0xFFC414B8 /* DMA9 Current Row Count (2D only) */ -#define DMA9_BWL_COUNT 0xFFC414C0 /* DMA9 Bandwidth Limit Count */ -#define DMA9_CURR_BWL_COUNT 0xFFC414C4 /* DMA9 Bandwidth Limit Count Current */ -#define DMA9_BWM_COUNT 0xFFC414C8 /* DMA9 Bandwidth Monitor Count */ -#define DMA9_CURR_BWM_COUNT 0xFFC414CC /* DMA9 Bandwidth Monitor Count Current */ - -/* ========================= - DMA10 - ========================= */ -#define DMA10_NEXT_DESC_PTR 0xFFC05000 /* DMA10 Pointer to Next Initial Descriptor */ -#define DMA10_START_ADDR 0xFFC05004 /* DMA10 Start Address of Current Buffer */ -#define DMA10_CONFIG 0xFFC05008 /* DMA10 Configuration Register */ -#define DMA10_X_COUNT 0xFFC0500C /* DMA10 Inner Loop Count Start Value */ -#define DMA10_X_MODIFY 0xFFC05010 /* DMA10 Inner Loop Address Increment */ -#define DMA10_Y_COUNT 0xFFC05014 /* DMA10 Outer Loop Count Start Value (2D only) */ -#define DMA10_Y_MODIFY 0xFFC05018 /* DMA10 Outer Loop Address Increment (2D only) */ -#define DMA10_CURR_DESC_PTR 0xFFC05024 /* DMA10 Current Descriptor Pointer */ -#define DMA10_PREV_DESC_PTR 0xFFC05028 /* DMA10 Previous Initial Descriptor Pointer */ -#define DMA10_CURR_ADDR 0xFFC0502C /* DMA10 Current Address */ -#define DMA10_IRQ_STATUS 0xFFC05030 /* DMA10 Status Register */ -#define DMA10_CURR_X_COUNT 0xFFC05034 /* DMA10 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA10_CURR_Y_COUNT 0xFFC05038 /* DMA10 Current Row Count (2D only) */ -#define DMA10_BWL_COUNT 0xFFC05040 /* DMA10 Bandwidth Limit Count */ -#define DMA10_CURR_BWL_COUNT 0xFFC05044 /* DMA10 Bandwidth Limit Count Current */ -#define DMA10_BWM_COUNT 0xFFC05048 /* DMA10 Bandwidth Monitor Count */ -#define DMA10_CURR_BWM_COUNT 0xFFC0504C /* DMA10 Bandwidth Monitor Count Current */ - -/* ========================= - DMA11 - ========================= */ -#define DMA11_NEXT_DESC_PTR 0xFFC05080 /* DMA11 Pointer to Next Initial Descriptor */ -#define DMA11_START_ADDR 0xFFC05084 /* DMA11 Start Address of Current Buffer */ -#define DMA11_CONFIG 0xFFC05088 /* DMA11 Configuration Register */ -#define DMA11_X_COUNT 0xFFC0508C /* DMA11 Inner Loop Count Start Value */ -#define DMA11_X_MODIFY 0xFFC05090 /* DMA11 Inner Loop Address Increment */ -#define DMA11_Y_COUNT 0xFFC05094 /* DMA11 Outer Loop Count Start Value (2D only) */ -#define DMA11_Y_MODIFY 0xFFC05098 /* DMA11 Outer Loop Address Increment (2D only) */ -#define DMA11_CURR_DESC_PTR 0xFFC050A4 /* DMA11 Current Descriptor Pointer */ -#define DMA11_PREV_DESC_PTR 0xFFC050A8 /* DMA11 Previous Initial Descriptor Pointer */ -#define DMA11_CURR_ADDR 0xFFC050AC /* DMA11 Current Address */ -#define DMA11_IRQ_STATUS 0xFFC050B0 /* DMA11 Status Register */ -#define DMA11_CURR_X_COUNT 0xFFC050B4 /* DMA11 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA11_CURR_Y_COUNT 0xFFC050B8 /* DMA11 Current Row Count (2D only) */ -#define DMA11_BWL_COUNT 0xFFC050C0 /* DMA11 Bandwidth Limit Count */ -#define DMA11_CURR_BWL_COUNT 0xFFC050C4 /* DMA11 Bandwidth Limit Count Current */ -#define DMA11_BWM_COUNT 0xFFC050C8 /* DMA11 Bandwidth Monitor Count */ -#define DMA11_CURR_BWM_COUNT 0xFFC050CC /* DMA11 Bandwidth Monitor Count Current */ - -/* ========================= - DMA12 - ========================= */ -#define DMA12_NEXT_DESC_PTR 0xFFC05100 /* DMA12 Pointer to Next Initial Descriptor */ -#define DMA12_START_ADDR 0xFFC05104 /* DMA12 Start Address of Current Buffer */ -#define DMA12_CONFIG 0xFFC05108 /* DMA12 Configuration Register */ -#define DMA12_X_COUNT 0xFFC0510C /* DMA12 Inner Loop Count Start Value */ -#define DMA12_X_MODIFY 0xFFC05110 /* DMA12 Inner Loop Address Increment */ -#define DMA12_Y_COUNT 0xFFC05114 /* DMA12 Outer Loop Count Start Value (2D only) */ -#define DMA12_Y_MODIFY 0xFFC05118 /* DMA12 Outer Loop Address Increment (2D only) */ -#define DMA12_CURR_DESC_PTR 0xFFC05124 /* DMA12 Current Descriptor Pointer */ -#define DMA12_PREV_DESC_PTR 0xFFC05128 /* DMA12 Previous Initial Descriptor Pointer */ -#define DMA12_CURR_ADDR 0xFFC0512C /* DMA12 Current Address */ -#define DMA12_IRQ_STATUS 0xFFC05130 /* DMA12 Status Register */ -#define DMA12_CURR_X_COUNT 0xFFC05134 /* DMA12 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA12_CURR_Y_COUNT 0xFFC05138 /* DMA12 Current Row Count (2D only) */ -#define DMA12_BWL_COUNT 0xFFC05140 /* DMA12 Bandwidth Limit Count */ -#define DMA12_CURR_BWL_COUNT 0xFFC05144 /* DMA12 Bandwidth Limit Count Current */ -#define DMA12_BWM_COUNT 0xFFC05148 /* DMA12 Bandwidth Monitor Count */ -#define DMA12_CURR_BWM_COUNT 0xFFC0514C /* DMA12 Bandwidth Monitor Count Current */ - -/* ========================= - DMA13 - ========================= */ -#define DMA13_NEXT_DESC_PTR 0xFFC07000 /* DMA13 Pointer to Next Initial Descriptor */ -#define DMA13_START_ADDR 0xFFC07004 /* DMA13 Start Address of Current Buffer */ -#define DMA13_CONFIG 0xFFC07008 /* DMA13 Configuration Register */ -#define DMA13_X_COUNT 0xFFC0700C /* DMA13 Inner Loop Count Start Value */ -#define DMA13_X_MODIFY 0xFFC07010 /* DMA13 Inner Loop Address Increment */ -#define DMA13_Y_COUNT 0xFFC07014 /* DMA13 Outer Loop Count Start Value (2D only) */ -#define DMA13_Y_MODIFY 0xFFC07018 /* DMA13 Outer Loop Address Increment (2D only) */ -#define DMA13_CURR_DESC_PTR 0xFFC07024 /* DMA13 Current Descriptor Pointer */ -#define DMA13_PREV_DESC_PTR 0xFFC07028 /* DMA13 Previous Initial Descriptor Pointer */ -#define DMA13_CURR_ADDR 0xFFC0702C /* DMA13 Current Address */ -#define DMA13_IRQ_STATUS 0xFFC07030 /* DMA13 Status Register */ -#define DMA13_CURR_X_COUNT 0xFFC07034 /* DMA13 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA13_CURR_Y_COUNT 0xFFC07038 /* DMA13 Current Row Count (2D only) */ -#define DMA13_BWL_COUNT 0xFFC07040 /* DMA13 Bandwidth Limit Count */ -#define DMA13_CURR_BWL_COUNT 0xFFC07044 /* DMA13 Bandwidth Limit Count Current */ -#define DMA13_BWM_COUNT 0xFFC07048 /* DMA13 Bandwidth Monitor Count */ -#define DMA13_CURR_BWM_COUNT 0xFFC0704C /* DMA13 Bandwidth Monitor Count Current */ - -/* ========================= - DMA14 - ========================= */ -#define DMA14_NEXT_DESC_PTR 0xFFC07080 /* DMA14 Pointer to Next Initial Descriptor */ -#define DMA14_START_ADDR 0xFFC07084 /* DMA14 Start Address of Current Buffer */ -#define DMA14_CONFIG 0xFFC07088 /* DMA14 Configuration Register */ -#define DMA14_X_COUNT 0xFFC0708C /* DMA14 Inner Loop Count Start Value */ -#define DMA14_X_MODIFY 0xFFC07090 /* DMA14 Inner Loop Address Increment */ -#define DMA14_Y_COUNT 0xFFC07094 /* DMA14 Outer Loop Count Start Value (2D only) */ -#define DMA14_Y_MODIFY 0xFFC07098 /* DMA14 Outer Loop Address Increment (2D only) */ -#define DMA14_CURR_DESC_PTR 0xFFC070A4 /* DMA14 Current Descriptor Pointer */ -#define DMA14_PREV_DESC_PTR 0xFFC070A8 /* DMA14 Previous Initial Descriptor Pointer */ -#define DMA14_CURR_ADDR 0xFFC070AC /* DMA14 Current Address */ -#define DMA14_IRQ_STATUS 0xFFC070B0 /* DMA14 Status Register */ -#define DMA14_CURR_X_COUNT 0xFFC070B4 /* DMA14 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA14_CURR_Y_COUNT 0xFFC070B8 /* DMA14 Current Row Count (2D only) */ -#define DMA14_BWL_COUNT 0xFFC070C0 /* DMA14 Bandwidth Limit Count */ -#define DMA14_CURR_BWL_COUNT 0xFFC070C4 /* DMA14 Bandwidth Limit Count Current */ -#define DMA14_BWM_COUNT 0xFFC070C8 /* DMA14 Bandwidth Monitor Count */ -#define DMA14_CURR_BWM_COUNT 0xFFC070CC /* DMA14 Bandwidth Monitor Count Current */ - -/* ========================= - DMA15 - ========================= */ -#define DMA15_NEXT_DESC_PTR 0xFFC07100 /* DMA15 Pointer to Next Initial Descriptor */ -#define DMA15_START_ADDR 0xFFC07104 /* DMA15 Start Address of Current Buffer */ -#define DMA15_CONFIG 0xFFC07108 /* DMA15 Configuration Register */ -#define DMA15_X_COUNT 0xFFC0710C /* DMA15 Inner Loop Count Start Value */ -#define DMA15_X_MODIFY 0xFFC07110 /* DMA15 Inner Loop Address Increment */ -#define DMA15_Y_COUNT 0xFFC07114 /* DMA15 Outer Loop Count Start Value (2D only) */ -#define DMA15_Y_MODIFY 0xFFC07118 /* DMA15 Outer Loop Address Increment (2D only) */ -#define DMA15_CURR_DESC_PTR 0xFFC07124 /* DMA15 Current Descriptor Pointer */ -#define DMA15_PREV_DESC_PTR 0xFFC07128 /* DMA15 Previous Initial Descriptor Pointer */ -#define DMA15_CURR_ADDR 0xFFC0712C /* DMA15 Current Address */ -#define DMA15_IRQ_STATUS 0xFFC07130 /* DMA15 Status Register */ -#define DMA15_CURR_X_COUNT 0xFFC07134 /* DMA15 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA15_CURR_Y_COUNT 0xFFC07138 /* DMA15 Current Row Count (2D only) */ -#define DMA15_BWL_COUNT 0xFFC07140 /* DMA15 Bandwidth Limit Count */ -#define DMA15_CURR_BWL_COUNT 0xFFC07144 /* DMA15 Bandwidth Limit Count Current */ -#define DMA15_BWM_COUNT 0xFFC07148 /* DMA15 Bandwidth Monitor Count */ -#define DMA15_CURR_BWM_COUNT 0xFFC0714C /* DMA15 Bandwidth Monitor Count Current */ - -/* ========================= - DMA16 - ========================= */ -#define DMA16_NEXT_DESC_PTR 0xFFC07180 /* DMA16 Pointer to Next Initial Descriptor */ -#define DMA16_START_ADDR 0xFFC07184 /* DMA16 Start Address of Current Buffer */ -#define DMA16_CONFIG 0xFFC07188 /* DMA16 Configuration Register */ -#define DMA16_X_COUNT 0xFFC0718C /* DMA16 Inner Loop Count Start Value */ -#define DMA16_X_MODIFY 0xFFC07190 /* DMA16 Inner Loop Address Increment */ -#define DMA16_Y_COUNT 0xFFC07194 /* DMA16 Outer Loop Count Start Value (2D only) */ -#define DMA16_Y_MODIFY 0xFFC07198 /* DMA16 Outer Loop Address Increment (2D only) */ -#define DMA16_CURR_DESC_PTR 0xFFC071A4 /* DMA16 Current Descriptor Pointer */ -#define DMA16_PREV_DESC_PTR 0xFFC071A8 /* DMA16 Previous Initial Descriptor Pointer */ -#define DMA16_CURR_ADDR 0xFFC071AC /* DMA16 Current Address */ -#define DMA16_IRQ_STATUS 0xFFC071B0 /* DMA16 Status Register */ -#define DMA16_CURR_X_COUNT 0xFFC071B4 /* DMA16 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA16_CURR_Y_COUNT 0xFFC071B8 /* DMA16 Current Row Count (2D only) */ -#define DMA16_BWL_COUNT 0xFFC071C0 /* DMA16 Bandwidth Limit Count */ -#define DMA16_CURR_BWL_COUNT 0xFFC071C4 /* DMA16 Bandwidth Limit Count Current */ -#define DMA16_BWM_COUNT 0xFFC071C8 /* DMA16 Bandwidth Monitor Count */ -#define DMA16_CURR_BWM_COUNT 0xFFC071CC /* DMA16 Bandwidth Monitor Count Current */ - -/* ========================= - DMA17 - ========================= */ -#define DMA17_NEXT_DESC_PTR 0xFFC07200 /* DMA17 Pointer to Next Initial Descriptor */ -#define DMA17_START_ADDR 0xFFC07204 /* DMA17 Start Address of Current Buffer */ -#define DMA17_CONFIG 0xFFC07208 /* DMA17 Configuration Register */ -#define DMA17_X_COUNT 0xFFC0720C /* DMA17 Inner Loop Count Start Value */ -#define DMA17_X_MODIFY 0xFFC07210 /* DMA17 Inner Loop Address Increment */ -#define DMA17_Y_COUNT 0xFFC07214 /* DMA17 Outer Loop Count Start Value (2D only) */ -#define DMA17_Y_MODIFY 0xFFC07218 /* DMA17 Outer Loop Address Increment (2D only) */ -#define DMA17_CURR_DESC_PTR 0xFFC07224 /* DMA17 Current Descriptor Pointer */ -#define DMA17_PREV_DESC_PTR 0xFFC07228 /* DMA17 Previous Initial Descriptor Pointer */ -#define DMA17_CURR_ADDR 0xFFC0722C /* DMA17 Current Address */ -#define DMA17_IRQ_STATUS 0xFFC07230 /* DMA17 Status Register */ -#define DMA17_CURR_X_COUNT 0xFFC07234 /* DMA17 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA17_CURR_Y_COUNT 0xFFC07238 /* DMA17 Current Row Count (2D only) */ -#define DMA17_BWL_COUNT 0xFFC07240 /* DMA17 Bandwidth Limit Count */ -#define DMA17_CURR_BWL_COUNT 0xFFC07244 /* DMA17 Bandwidth Limit Count Current */ -#define DMA17_BWM_COUNT 0xFFC07248 /* DMA17 Bandwidth Monitor Count */ -#define DMA17_CURR_BWM_COUNT 0xFFC0724C /* DMA17 Bandwidth Monitor Count Current */ - -/* ========================= - DMA18 - ========================= */ -#define DMA18_NEXT_DESC_PTR 0xFFC07280 /* DMA18 Pointer to Next Initial Descriptor */ -#define DMA18_START_ADDR 0xFFC07284 /* DMA18 Start Address of Current Buffer */ -#define DMA18_CONFIG 0xFFC07288 /* DMA18 Configuration Register */ -#define DMA18_X_COUNT 0xFFC0728C /* DMA18 Inner Loop Count Start Value */ -#define DMA18_X_MODIFY 0xFFC07290 /* DMA18 Inner Loop Address Increment */ -#define DMA18_Y_COUNT 0xFFC07294 /* DMA18 Outer Loop Count Start Value (2D only) */ -#define DMA18_Y_MODIFY 0xFFC07298 /* DMA18 Outer Loop Address Increment (2D only) */ -#define DMA18_CURR_DESC_PTR 0xFFC072A4 /* DMA18 Current Descriptor Pointer */ -#define DMA18_PREV_DESC_PTR 0xFFC072A8 /* DMA18 Previous Initial Descriptor Pointer */ -#define DMA18_CURR_ADDR 0xFFC072AC /* DMA18 Current Address */ -#define DMA18_IRQ_STATUS 0xFFC072B0 /* DMA18 Status Register */ -#define DMA18_CURR_X_COUNT 0xFFC072B4 /* DMA18 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA18_CURR_Y_COUNT 0xFFC072B8 /* DMA18 Current Row Count (2D only) */ -#define DMA18_BWL_COUNT 0xFFC072C0 /* DMA18 Bandwidth Limit Count */ -#define DMA18_CURR_BWL_COUNT 0xFFC072C4 /* DMA18 Bandwidth Limit Count Current */ -#define DMA18_BWM_COUNT 0xFFC072C8 /* DMA18 Bandwidth Monitor Count */ -#define DMA18_CURR_BWM_COUNT 0xFFC072CC /* DMA18 Bandwidth Monitor Count Current */ - -/* ========================= - DMA19 - ========================= */ -#define DMA19_NEXT_DESC_PTR 0xFFC07300 /* DMA19 Pointer to Next Initial Descriptor */ -#define DMA19_START_ADDR 0xFFC07304 /* DMA19 Start Address of Current Buffer */ -#define DMA19_CONFIG 0xFFC07308 /* DMA19 Configuration Register */ -#define DMA19_X_COUNT 0xFFC0730C /* DMA19 Inner Loop Count Start Value */ -#define DMA19_X_MODIFY 0xFFC07310 /* DMA19 Inner Loop Address Increment */ -#define DMA19_Y_COUNT 0xFFC07314 /* DMA19 Outer Loop Count Start Value (2D only) */ -#define DMA19_Y_MODIFY 0xFFC07318 /* DMA19 Outer Loop Address Increment (2D only) */ -#define DMA19_CURR_DESC_PTR 0xFFC07324 /* DMA19 Current Descriptor Pointer */ -#define DMA19_PREV_DESC_PTR 0xFFC07328 /* DMA19 Previous Initial Descriptor Pointer */ -#define DMA19_CURR_ADDR 0xFFC0732C /* DMA19 Current Address */ -#define DMA19_IRQ_STATUS 0xFFC07330 /* DMA19 Status Register */ -#define DMA19_CURR_X_COUNT 0xFFC07334 /* DMA19 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA19_CURR_Y_COUNT 0xFFC07338 /* DMA19 Current Row Count (2D only) */ -#define DMA19_BWL_COUNT 0xFFC07340 /* DMA19 Bandwidth Limit Count */ -#define DMA19_CURR_BWL_COUNT 0xFFC07344 /* DMA19 Bandwidth Limit Count Current */ -#define DMA19_BWM_COUNT 0xFFC07348 /* DMA19 Bandwidth Monitor Count */ -#define DMA19_CURR_BWM_COUNT 0xFFC0734C /* DMA19 Bandwidth Monitor Count Current */ - -/* ========================= - DMA20 - ========================= */ -#define DMA20_NEXT_DESC_PTR 0xFFC07380 /* DMA20 Pointer to Next Initial Descriptor */ -#define DMA20_START_ADDR 0xFFC07384 /* DMA20 Start Address of Current Buffer */ -#define DMA20_CONFIG 0xFFC07388 /* DMA20 Configuration Register */ -#define DMA20_X_COUNT 0xFFC0738C /* DMA20 Inner Loop Count Start Value */ -#define DMA20_X_MODIFY 0xFFC07390 /* DMA20 Inner Loop Address Increment */ -#define DMA20_Y_COUNT 0xFFC07394 /* DMA20 Outer Loop Count Start Value (2D only) */ -#define DMA20_Y_MODIFY 0xFFC07398 /* DMA20 Outer Loop Address Increment (2D only) */ -#define DMA20_CURR_DESC_PTR 0xFFC073A4 /* DMA20 Current Descriptor Pointer */ -#define DMA20_PREV_DESC_PTR 0xFFC073A8 /* DMA20 Previous Initial Descriptor Pointer */ -#define DMA20_CURR_ADDR 0xFFC073AC /* DMA20 Current Address */ -#define DMA20_IRQ_STATUS 0xFFC073B0 /* DMA20 Status Register */ -#define DMA20_CURR_X_COUNT 0xFFC073B4 /* DMA20 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA20_CURR_Y_COUNT 0xFFC073B8 /* DMA20 Current Row Count (2D only) */ -#define DMA20_BWL_COUNT 0xFFC073C0 /* DMA20 Bandwidth Limit Count */ -#define DMA20_CURR_BWL_COUNT 0xFFC073C4 /* DMA20 Bandwidth Limit Count Current */ -#define DMA20_BWM_COUNT 0xFFC073C8 /* DMA20 Bandwidth Monitor Count */ -#define DMA20_CURR_BWM_COUNT 0xFFC073CC /* DMA20 Bandwidth Monitor Count Current */ - -/* ========================= - DMA21 - ========================= */ -#define DMA21_NEXT_DESC_PTR 0xFFC09000 /* DMA21 Pointer to Next Initial Descriptor */ -#define DMA21_START_ADDR 0xFFC09004 /* DMA21 Start Address of Current Buffer */ -#define DMA21_CONFIG 0xFFC09008 /* DMA21 Configuration Register */ -#define DMA21_X_COUNT 0xFFC0900C /* DMA21 Inner Loop Count Start Value */ -#define DMA21_X_MODIFY 0xFFC09010 /* DMA21 Inner Loop Address Increment */ -#define DMA21_Y_COUNT 0xFFC09014 /* DMA21 Outer Loop Count Start Value (2D only) */ -#define DMA21_Y_MODIFY 0xFFC09018 /* DMA21 Outer Loop Address Increment (2D only) */ -#define DMA21_CURR_DESC_PTR 0xFFC09024 /* DMA21 Current Descriptor Pointer */ -#define DMA21_PREV_DESC_PTR 0xFFC09028 /* DMA21 Previous Initial Descriptor Pointer */ -#define DMA21_CURR_ADDR 0xFFC0902C /* DMA21 Current Address */ -#define DMA21_IRQ_STATUS 0xFFC09030 /* DMA21 Status Register */ -#define DMA21_CURR_X_COUNT 0xFFC09034 /* DMA21 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA21_CURR_Y_COUNT 0xFFC09038 /* DMA21 Current Row Count (2D only) */ -#define DMA21_BWL_COUNT 0xFFC09040 /* DMA21 Bandwidth Limit Count */ -#define DMA21_CURR_BWL_COUNT 0xFFC09044 /* DMA21 Bandwidth Limit Count Current */ -#define DMA21_BWM_COUNT 0xFFC09048 /* DMA21 Bandwidth Monitor Count */ -#define DMA21_CURR_BWM_COUNT 0xFFC0904C /* DMA21 Bandwidth Monitor Count Current */ - -/* ========================= - DMA22 - ========================= */ -#define DMA22_NEXT_DESC_PTR 0xFFC09080 /* DMA22 Pointer to Next Initial Descriptor */ -#define DMA22_START_ADDR 0xFFC09084 /* DMA22 Start Address of Current Buffer */ -#define DMA22_CONFIG 0xFFC09088 /* DMA22 Configuration Register */ -#define DMA22_X_COUNT 0xFFC0908C /* DMA22 Inner Loop Count Start Value */ -#define DMA22_X_MODIFY 0xFFC09090 /* DMA22 Inner Loop Address Increment */ -#define DMA22_Y_COUNT 0xFFC09094 /* DMA22 Outer Loop Count Start Value (2D only) */ -#define DMA22_Y_MODIFY 0xFFC09098 /* DMA22 Outer Loop Address Increment (2D only) */ -#define DMA22_CURR_DESC_PTR 0xFFC090A4 /* DMA22 Current Descriptor Pointer */ -#define DMA22_PREV_DESC_PTR 0xFFC090A8 /* DMA22 Previous Initial Descriptor Pointer */ -#define DMA22_CURR_ADDR 0xFFC090AC /* DMA22 Current Address */ -#define DMA22_IRQ_STATUS 0xFFC090B0 /* DMA22 Status Register */ -#define DMA22_CURR_X_COUNT 0xFFC090B4 /* DMA22 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA22_CURR_Y_COUNT 0xFFC090B8 /* DMA22 Current Row Count (2D only) */ -#define DMA22_BWL_COUNT 0xFFC090C0 /* DMA22 Bandwidth Limit Count */ -#define DMA22_CURR_BWL_COUNT 0xFFC090C4 /* DMA22 Bandwidth Limit Count Current */ -#define DMA22_BWM_COUNT 0xFFC090C8 /* DMA22 Bandwidth Monitor Count */ -#define DMA22_CURR_BWM_COUNT 0xFFC090CC /* DMA22 Bandwidth Monitor Count Current */ - -/* ========================= - DMA23 - ========================= */ -#define DMA23_NEXT_DESC_PTR 0xFFC09100 /* DMA23 Pointer to Next Initial Descriptor */ -#define DMA23_START_ADDR 0xFFC09104 /* DMA23 Start Address of Current Buffer */ -#define DMA23_CONFIG 0xFFC09108 /* DMA23 Configuration Register */ -#define DMA23_X_COUNT 0xFFC0910C /* DMA23 Inner Loop Count Start Value */ -#define DMA23_X_MODIFY 0xFFC09110 /* DMA23 Inner Loop Address Increment */ -#define DMA23_Y_COUNT 0xFFC09114 /* DMA23 Outer Loop Count Start Value (2D only) */ -#define DMA23_Y_MODIFY 0xFFC09118 /* DMA23 Outer Loop Address Increment (2D only) */ -#define DMA23_CURR_DESC_PTR 0xFFC09124 /* DMA23 Current Descriptor Pointer */ -#define DMA23_PREV_DESC_PTR 0xFFC09128 /* DMA23 Previous Initial Descriptor Pointer */ -#define DMA23_CURR_ADDR 0xFFC0912C /* DMA23 Current Address */ -#define DMA23_IRQ_STATUS 0xFFC09130 /* DMA23 Status Register */ -#define DMA23_CURR_X_COUNT 0xFFC09134 /* DMA23 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA23_CURR_Y_COUNT 0xFFC09138 /* DMA23 Current Row Count (2D only) */ -#define DMA23_BWL_COUNT 0xFFC09140 /* DMA23 Bandwidth Limit Count */ -#define DMA23_CURR_BWL_COUNT 0xFFC09144 /* DMA23 Bandwidth Limit Count Current */ -#define DMA23_BWM_COUNT 0xFFC09148 /* DMA23 Bandwidth Monitor Count */ -#define DMA23_CURR_BWM_COUNT 0xFFC0914C /* DMA23 Bandwidth Monitor Count Current */ - -/* ========================= - DMA24 - ========================= */ -#define DMA24_NEXT_DESC_PTR 0xFFC09180 /* DMA24 Pointer to Next Initial Descriptor */ -#define DMA24_START_ADDR 0xFFC09184 /* DMA24 Start Address of Current Buffer */ -#define DMA24_CONFIG 0xFFC09188 /* DMA24 Configuration Register */ -#define DMA24_X_COUNT 0xFFC0918C /* DMA24 Inner Loop Count Start Value */ -#define DMA24_X_MODIFY 0xFFC09190 /* DMA24 Inner Loop Address Increment */ -#define DMA24_Y_COUNT 0xFFC09194 /* DMA24 Outer Loop Count Start Value (2D only) */ -#define DMA24_Y_MODIFY 0xFFC09198 /* DMA24 Outer Loop Address Increment (2D only) */ -#define DMA24_CURR_DESC_PTR 0xFFC091A4 /* DMA24 Current Descriptor Pointer */ -#define DMA24_PREV_DESC_PTR 0xFFC091A8 /* DMA24 Previous Initial Descriptor Pointer */ -#define DMA24_CURR_ADDR 0xFFC091AC /* DMA24 Current Address */ -#define DMA24_IRQ_STATUS 0xFFC091B0 /* DMA24 Status Register */ -#define DMA24_CURR_X_COUNT 0xFFC091B4 /* DMA24 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA24_CURR_Y_COUNT 0xFFC091B8 /* DMA24 Current Row Count (2D only) */ -#define DMA24_BWL_COUNT 0xFFC091C0 /* DMA24 Bandwidth Limit Count */ -#define DMA24_CURR_BWL_COUNT 0xFFC091C4 /* DMA24 Bandwidth Limit Count Current */ -#define DMA24_BWM_COUNT 0xFFC091C8 /* DMA24 Bandwidth Monitor Count */ -#define DMA24_CURR_BWM_COUNT 0xFFC091CC /* DMA24 Bandwidth Monitor Count Current */ - -/* ========================= - DMA25 - ========================= */ -#define DMA25_NEXT_DESC_PTR 0xFFC09200 /* DMA25 Pointer to Next Initial Descriptor */ -#define DMA25_START_ADDR 0xFFC09204 /* DMA25 Start Address of Current Buffer */ -#define DMA25_CONFIG 0xFFC09208 /* DMA25 Configuration Register */ -#define DMA25_X_COUNT 0xFFC0920C /* DMA25 Inner Loop Count Start Value */ -#define DMA25_X_MODIFY 0xFFC09210 /* DMA25 Inner Loop Address Increment */ -#define DMA25_Y_COUNT 0xFFC09214 /* DMA25 Outer Loop Count Start Value (2D only) */ -#define DMA25_Y_MODIFY 0xFFC09218 /* DMA25 Outer Loop Address Increment (2D only) */ -#define DMA25_CURR_DESC_PTR 0xFFC09224 /* DMA25 Current Descriptor Pointer */ -#define DMA25_PREV_DESC_PTR 0xFFC09228 /* DMA25 Previous Initial Descriptor Pointer */ -#define DMA25_CURR_ADDR 0xFFC0922C /* DMA25 Current Address */ -#define DMA25_IRQ_STATUS 0xFFC09230 /* DMA25 Status Register */ -#define DMA25_CURR_X_COUNT 0xFFC09234 /* DMA25 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA25_CURR_Y_COUNT 0xFFC09238 /* DMA25 Current Row Count (2D only) */ -#define DMA25_BWL_COUNT 0xFFC09240 /* DMA25 Bandwidth Limit Count */ -#define DMA25_CURR_BWL_COUNT 0xFFC09244 /* DMA25 Bandwidth Limit Count Current */ -#define DMA25_BWM_COUNT 0xFFC09248 /* DMA25 Bandwidth Monitor Count */ -#define DMA25_CURR_BWM_COUNT 0xFFC0924C /* DMA25 Bandwidth Monitor Count Current */ - -/* ========================= - DMA26 - ========================= */ -#define DMA26_NEXT_DESC_PTR 0xFFC09280 /* DMA26 Pointer to Next Initial Descriptor */ -#define DMA26_START_ADDR 0xFFC09284 /* DMA26 Start Address of Current Buffer */ -#define DMA26_CONFIG 0xFFC09288 /* DMA26 Configuration Register */ -#define DMA26_X_COUNT 0xFFC0928C /* DMA26 Inner Loop Count Start Value */ -#define DMA26_X_MODIFY 0xFFC09290 /* DMA26 Inner Loop Address Increment */ -#define DMA26_Y_COUNT 0xFFC09294 /* DMA26 Outer Loop Count Start Value (2D only) */ -#define DMA26_Y_MODIFY 0xFFC09298 /* DMA26 Outer Loop Address Increment (2D only) */ -#define DMA26_CURR_DESC_PTR 0xFFC092A4 /* DMA26 Current Descriptor Pointer */ -#define DMA26_PREV_DESC_PTR 0xFFC092A8 /* DMA26 Previous Initial Descriptor Pointer */ -#define DMA26_CURR_ADDR 0xFFC092AC /* DMA26 Current Address */ -#define DMA26_IRQ_STATUS 0xFFC092B0 /* DMA26 Status Register */ -#define DMA26_CURR_X_COUNT 0xFFC092B4 /* DMA26 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA26_CURR_Y_COUNT 0xFFC092B8 /* DMA26 Current Row Count (2D only) */ -#define DMA26_BWL_COUNT 0xFFC092C0 /* DMA26 Bandwidth Limit Count */ -#define DMA26_CURR_BWL_COUNT 0xFFC092C4 /* DMA26 Bandwidth Limit Count Current */ -#define DMA26_BWM_COUNT 0xFFC092C8 /* DMA26 Bandwidth Monitor Count */ -#define DMA26_CURR_BWM_COUNT 0xFFC092CC /* DMA26 Bandwidth Monitor Count Current */ - -/* ========================= - DMA27 - ========================= */ -#define DMA27_NEXT_DESC_PTR 0xFFC09300 /* DMA27 Pointer to Next Initial Descriptor */ -#define DMA27_START_ADDR 0xFFC09304 /* DMA27 Start Address of Current Buffer */ -#define DMA27_CONFIG 0xFFC09308 /* DMA27 Configuration Register */ -#define DMA27_X_COUNT 0xFFC0930C /* DMA27 Inner Loop Count Start Value */ -#define DMA27_X_MODIFY 0xFFC09310 /* DMA27 Inner Loop Address Increment */ -#define DMA27_Y_COUNT 0xFFC09314 /* DMA27 Outer Loop Count Start Value (2D only) */ -#define DMA27_Y_MODIFY 0xFFC09318 /* DMA27 Outer Loop Address Increment (2D only) */ -#define DMA27_CURR_DESC_PTR 0xFFC09324 /* DMA27 Current Descriptor Pointer */ -#define DMA27_PREV_DESC_PTR 0xFFC09328 /* DMA27 Previous Initial Descriptor Pointer */ -#define DMA27_CURR_ADDR 0xFFC0932C /* DMA27 Current Address */ -#define DMA27_IRQ_STATUS 0xFFC09330 /* DMA27 Status Register */ -#define DMA27_CURR_X_COUNT 0xFFC09334 /* DMA27 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA27_CURR_Y_COUNT 0xFFC09338 /* DMA27 Current Row Count (2D only) */ -#define DMA27_BWL_COUNT 0xFFC09340 /* DMA27 Bandwidth Limit Count */ -#define DMA27_CURR_BWL_COUNT 0xFFC09344 /* DMA27 Bandwidth Limit Count Current */ -#define DMA27_BWM_COUNT 0xFFC09348 /* DMA27 Bandwidth Monitor Count */ -#define DMA27_CURR_BWM_COUNT 0xFFC0934C /* DMA27 Bandwidth Monitor Count Current */ - -/* ========================= - DMA28 - ========================= */ -#define DMA28_NEXT_DESC_PTR 0xFFC09380 /* DMA28 Pointer to Next Initial Descriptor */ -#define DMA28_START_ADDR 0xFFC09384 /* DMA28 Start Address of Current Buffer */ -#define DMA28_CONFIG 0xFFC09388 /* DMA28 Configuration Register */ -#define DMA28_X_COUNT 0xFFC0938C /* DMA28 Inner Loop Count Start Value */ -#define DMA28_X_MODIFY 0xFFC09390 /* DMA28 Inner Loop Address Increment */ -#define DMA28_Y_COUNT 0xFFC09394 /* DMA28 Outer Loop Count Start Value (2D only) */ -#define DMA28_Y_MODIFY 0xFFC09398 /* DMA28 Outer Loop Address Increment (2D only) */ -#define DMA28_CURR_DESC_PTR 0xFFC093A4 /* DMA28 Current Descriptor Pointer */ -#define DMA28_PREV_DESC_PTR 0xFFC093A8 /* DMA28 Previous Initial Descriptor Pointer */ -#define DMA28_CURR_ADDR 0xFFC093AC /* DMA28 Current Address */ -#define DMA28_IRQ_STATUS 0xFFC093B0 /* DMA28 Status Register */ -#define DMA28_CURR_X_COUNT 0xFFC093B4 /* DMA28 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA28_CURR_Y_COUNT 0xFFC093B8 /* DMA28 Current Row Count (2D only) */ -#define DMA28_BWL_COUNT 0xFFC093C0 /* DMA28 Bandwidth Limit Count */ -#define DMA28_CURR_BWL_COUNT 0xFFC093C4 /* DMA28 Bandwidth Limit Count Current */ -#define DMA28_BWM_COUNT 0xFFC093C8 /* DMA28 Bandwidth Monitor Count */ -#define DMA28_CURR_BWM_COUNT 0xFFC093CC /* DMA28 Bandwidth Monitor Count Current */ - -/* ========================= - DMA29 - ========================= */ -#define DMA29_NEXT_DESC_PTR 0xFFC0B000 /* DMA29 Pointer to Next Initial Descriptor */ -#define DMA29_START_ADDR 0xFFC0B004 /* DMA29 Start Address of Current Buffer */ -#define DMA29_CONFIG 0xFFC0B008 /* DMA29 Configuration Register */ -#define DMA29_X_COUNT 0xFFC0B00C /* DMA29 Inner Loop Count Start Value */ -#define DMA29_X_MODIFY 0xFFC0B010 /* DMA29 Inner Loop Address Increment */ -#define DMA29_Y_COUNT 0xFFC0B014 /* DMA29 Outer Loop Count Start Value (2D only) */ -#define DMA29_Y_MODIFY 0xFFC0B018 /* DMA29 Outer Loop Address Increment (2D only) */ -#define DMA29_CURR_DESC_PTR 0xFFC0B024 /* DMA29 Current Descriptor Pointer */ -#define DMA29_PREV_DESC_PTR 0xFFC0B028 /* DMA29 Previous Initial Descriptor Pointer */ -#define DMA29_CURR_ADDR 0xFFC0B02C /* DMA29 Current Address */ -#define DMA29_IRQ_STATUS 0xFFC0B030 /* DMA29 Status Register */ -#define DMA29_CURR_X_COUNT 0xFFC0B034 /* DMA29 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA29_CURR_Y_COUNT 0xFFC0B038 /* DMA29 Current Row Count (2D only) */ -#define DMA29_BWL_COUNT 0xFFC0B040 /* DMA29 Bandwidth Limit Count */ -#define DMA29_CURR_BWL_COUNT 0xFFC0B044 /* DMA29 Bandwidth Limit Count Current */ -#define DMA29_BWM_COUNT 0xFFC0B048 /* DMA29 Bandwidth Monitor Count */ -#define DMA29_CURR_BWM_COUNT 0xFFC0B04C /* DMA29 Bandwidth Monitor Count Current */ - -/* ========================= - DMA30 - ========================= */ -#define DMA30_NEXT_DESC_PTR 0xFFC0B080 /* DMA30 Pointer to Next Initial Descriptor */ -#define DMA30_START_ADDR 0xFFC0B084 /* DMA30 Start Address of Current Buffer */ -#define DMA30_CONFIG 0xFFC0B088 /* DMA30 Configuration Register */ -#define DMA30_X_COUNT 0xFFC0B08C /* DMA30 Inner Loop Count Start Value */ -#define DMA30_X_MODIFY 0xFFC0B090 /* DMA30 Inner Loop Address Increment */ -#define DMA30_Y_COUNT 0xFFC0B094 /* DMA30 Outer Loop Count Start Value (2D only) */ -#define DMA30_Y_MODIFY 0xFFC0B098 /* DMA30 Outer Loop Address Increment (2D only) */ -#define DMA30_CURR_DESC_PTR 0xFFC0B0A4 /* DMA30 Current Descriptor Pointer */ -#define DMA30_PREV_DESC_PTR 0xFFC0B0A8 /* DMA30 Previous Initial Descriptor Pointer */ -#define DMA30_CURR_ADDR 0xFFC0B0AC /* DMA30 Current Address */ -#define DMA30_IRQ_STATUS 0xFFC0B0B0 /* DMA30 Status Register */ -#define DMA30_CURR_X_COUNT 0xFFC0B0B4 /* DMA30 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA30_CURR_Y_COUNT 0xFFC0B0B8 /* DMA30 Current Row Count (2D only) */ -#define DMA30_BWL_COUNT 0xFFC0B0C0 /* DMA30 Bandwidth Limit Count */ -#define DMA30_CURR_BWL_COUNT 0xFFC0B0C4 /* DMA30 Bandwidth Limit Count Current */ -#define DMA30_BWM_COUNT 0xFFC0B0C8 /* DMA30 Bandwidth Monitor Count */ -#define DMA30_CURR_BWM_COUNT 0xFFC0B0CC /* DMA30 Bandwidth Monitor Count Current */ - -/* ========================= - DMA31 - ========================= */ -#define DMA31_NEXT_DESC_PTR 0xFFC0B100 /* DMA31 Pointer to Next Initial Descriptor */ -#define DMA31_START_ADDR 0xFFC0B104 /* DMA31 Start Address of Current Buffer */ -#define DMA31_CONFIG 0xFFC0B108 /* DMA31 Configuration Register */ -#define DMA31_X_COUNT 0xFFC0B10C /* DMA31 Inner Loop Count Start Value */ -#define DMA31_X_MODIFY 0xFFC0B110 /* DMA31 Inner Loop Address Increment */ -#define DMA31_Y_COUNT 0xFFC0B114 /* DMA31 Outer Loop Count Start Value (2D only) */ -#define DMA31_Y_MODIFY 0xFFC0B118 /* DMA31 Outer Loop Address Increment (2D only) */ -#define DMA31_CURR_DESC_PTR 0xFFC0B124 /* DMA31 Current Descriptor Pointer */ -#define DMA31_PREV_DESC_PTR 0xFFC0B128 /* DMA31 Previous Initial Descriptor Pointer */ -#define DMA31_CURR_ADDR 0xFFC0B12C /* DMA31 Current Address */ -#define DMA31_IRQ_STATUS 0xFFC0B130 /* DMA31 Status Register */ -#define DMA31_CURR_X_COUNT 0xFFC0B134 /* DMA31 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA31_CURR_Y_COUNT 0xFFC0B138 /* DMA31 Current Row Count (2D only) */ -#define DMA31_BWL_COUNT 0xFFC0B140 /* DMA31 Bandwidth Limit Count */ -#define DMA31_CURR_BWL_COUNT 0xFFC0B144 /* DMA31 Bandwidth Limit Count Current */ -#define DMA31_BWM_COUNT 0xFFC0B148 /* DMA31 Bandwidth Monitor Count */ -#define DMA31_CURR_BWM_COUNT 0xFFC0B14C /* DMA31 Bandwidth Monitor Count Current */ - -/* ========================= - DMA32 - ========================= */ -#define DMA32_NEXT_DESC_PTR 0xFFC0B180 /* DMA32 Pointer to Next Initial Descriptor */ -#define DMA32_START_ADDR 0xFFC0B184 /* DMA32 Start Address of Current Buffer */ -#define DMA32_CONFIG 0xFFC0B188 /* DMA32 Configuration Register */ -#define DMA32_X_COUNT 0xFFC0B18C /* DMA32 Inner Loop Count Start Value */ -#define DMA32_X_MODIFY 0xFFC0B190 /* DMA32 Inner Loop Address Increment */ -#define DMA32_Y_COUNT 0xFFC0B194 /* DMA32 Outer Loop Count Start Value (2D only) */ -#define DMA32_Y_MODIFY 0xFFC0B198 /* DMA32 Outer Loop Address Increment (2D only) */ -#define DMA32_CURR_DESC_PTR 0xFFC0B1A4 /* DMA32 Current Descriptor Pointer */ -#define DMA32_PREV_DESC_PTR 0xFFC0B1A8 /* DMA32 Previous Initial Descriptor Pointer */ -#define DMA32_CURR_ADDR 0xFFC0B1AC /* DMA32 Current Address */ -#define DMA32_IRQ_STATUS 0xFFC0B1B0 /* DMA32 Status Register */ -#define DMA32_CURR_X_COUNT 0xFFC0B1B4 /* DMA32 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA32_CURR_Y_COUNT 0xFFC0B1B8 /* DMA32 Current Row Count (2D only) */ -#define DMA32_BWL_COUNT 0xFFC0B1C0 /* DMA32 Bandwidth Limit Count */ -#define DMA32_CURR_BWL_COUNT 0xFFC0B1C4 /* DMA32 Bandwidth Limit Count Current */ -#define DMA32_BWM_COUNT 0xFFC0B1C8 /* DMA32 Bandwidth Monitor Count */ -#define DMA32_CURR_BWM_COUNT 0xFFC0B1CC /* DMA32 Bandwidth Monitor Count Current */ - -/* ========================= - DMA33 - ========================= */ -#define DMA33_NEXT_DESC_PTR 0xFFC0D000 /* DMA33 Pointer to Next Initial Descriptor */ -#define DMA33_START_ADDR 0xFFC0D004 /* DMA33 Start Address of Current Buffer */ -#define DMA33_CONFIG 0xFFC0D008 /* DMA33 Configuration Register */ -#define DMA33_X_COUNT 0xFFC0D00C /* DMA33 Inner Loop Count Start Value */ -#define DMA33_X_MODIFY 0xFFC0D010 /* DMA33 Inner Loop Address Increment */ -#define DMA33_Y_COUNT 0xFFC0D014 /* DMA33 Outer Loop Count Start Value (2D only) */ -#define DMA33_Y_MODIFY 0xFFC0D018 /* DMA33 Outer Loop Address Increment (2D only) */ -#define DMA33_CURR_DESC_PTR 0xFFC0D024 /* DMA33 Current Descriptor Pointer */ -#define DMA33_PREV_DESC_PTR 0xFFC0D028 /* DMA33 Previous Initial Descriptor Pointer */ -#define DMA33_CURR_ADDR 0xFFC0D02C /* DMA33 Current Address */ -#define DMA33_IRQ_STATUS 0xFFC0D030 /* DMA33 Status Register */ -#define DMA33_CURR_X_COUNT 0xFFC0D034 /* DMA33 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA33_CURR_Y_COUNT 0xFFC0D038 /* DMA33 Current Row Count (2D only) */ -#define DMA33_BWL_COUNT 0xFFC0D040 /* DMA33 Bandwidth Limit Count */ -#define DMA33_CURR_BWL_COUNT 0xFFC0D044 /* DMA33 Bandwidth Limit Count Current */ -#define DMA33_BWM_COUNT 0xFFC0D048 /* DMA33 Bandwidth Monitor Count */ -#define DMA33_CURR_BWM_COUNT 0xFFC0D04C /* DMA33 Bandwidth Monitor Count Current */ - -/* ========================= - DMA34 - ========================= */ -#define DMA34_NEXT_DESC_PTR 0xFFC0D080 /* DMA34 Pointer to Next Initial Descriptor */ -#define DMA34_START_ADDR 0xFFC0D084 /* DMA34 Start Address of Current Buffer */ -#define DMA34_CONFIG 0xFFC0D088 /* DMA34 Configuration Register */ -#define DMA34_X_COUNT 0xFFC0D08C /* DMA34 Inner Loop Count Start Value */ -#define DMA34_X_MODIFY 0xFFC0D090 /* DMA34 Inner Loop Address Increment */ -#define DMA34_Y_COUNT 0xFFC0D094 /* DMA34 Outer Loop Count Start Value (2D only) */ -#define DMA34_Y_MODIFY 0xFFC0D098 /* DMA34 Outer Loop Address Increment (2D only) */ -#define DMA34_CURR_DESC_PTR 0xFFC0D0A4 /* DMA34 Current Descriptor Pointer */ -#define DMA34_PREV_DESC_PTR 0xFFC0D0A8 /* DMA34 Previous Initial Descriptor Pointer */ -#define DMA34_CURR_ADDR 0xFFC0D0AC /* DMA34 Current Address */ -#define DMA34_IRQ_STATUS 0xFFC0D0B0 /* DMA34 Status Register */ -#define DMA34_CURR_X_COUNT 0xFFC0D0B4 /* DMA34 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA34_CURR_Y_COUNT 0xFFC0D0B8 /* DMA34 Current Row Count (2D only) */ -#define DMA34_BWL_COUNT 0xFFC0D0C0 /* DMA34 Bandwidth Limit Count */ -#define DMA34_CURR_BWL_COUNT 0xFFC0D0C4 /* DMA34 Bandwidth Limit Count Current */ -#define DMA34_BWM_COUNT 0xFFC0D0C8 /* DMA34 Bandwidth Monitor Count */ -#define DMA34_CURR_BWM_COUNT 0xFFC0D0CC /* DMA34 Bandwidth Monitor Count Current */ - -/* ========================= - DMA35 - ========================= */ -#define DMA35_NEXT_DESC_PTR 0xFFC10000 /* DMA35 Pointer to Next Initial Descriptor */ -#define DMA35_START_ADDR 0xFFC10004 /* DMA35 Start Address of Current Buffer */ -#define DMA35_CONFIG 0xFFC10008 /* DMA35 Configuration Register */ -#define DMA35_X_COUNT 0xFFC1000C /* DMA35 Inner Loop Count Start Value */ -#define DMA35_X_MODIFY 0xFFC10010 /* DMA35 Inner Loop Address Increment */ -#define DMA35_Y_COUNT 0xFFC10014 /* DMA35 Outer Loop Count Start Value (2D only) */ -#define DMA35_Y_MODIFY 0xFFC10018 /* DMA35 Outer Loop Address Increment (2D only) */ -#define DMA35_CURR_DESC_PTR 0xFFC10024 /* DMA35 Current Descriptor Pointer */ -#define DMA35_PREV_DESC_PTR 0xFFC10028 /* DMA35 Previous Initial Descriptor Pointer */ -#define DMA35_CURR_ADDR 0xFFC1002C /* DMA35 Current Address */ -#define DMA35_IRQ_STATUS 0xFFC10030 /* DMA35 Status Register */ -#define DMA35_CURR_X_COUNT 0xFFC10034 /* DMA35 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA35_CURR_Y_COUNT 0xFFC10038 /* DMA35 Current Row Count (2D only) */ -#define DMA35_BWL_COUNT 0xFFC10040 /* DMA35 Bandwidth Limit Count */ -#define DMA35_CURR_BWL_COUNT 0xFFC10044 /* DMA35 Bandwidth Limit Count Current */ -#define DMA35_BWM_COUNT 0xFFC10048 /* DMA35 Bandwidth Monitor Count */ -#define DMA35_CURR_BWM_COUNT 0xFFC1004C /* DMA35 Bandwidth Monitor Count Current */ - -/* ========================= - DMA36 - ========================= */ -#define DMA36_NEXT_DESC_PTR 0xFFC10080 /* DMA36 Pointer to Next Initial Descriptor */ -#define DMA36_START_ADDR 0xFFC10084 /* DMA36 Start Address of Current Buffer */ -#define DMA36_CONFIG 0xFFC10088 /* DMA36 Configuration Register */ -#define DMA36_X_COUNT 0xFFC1008C /* DMA36 Inner Loop Count Start Value */ -#define DMA36_X_MODIFY 0xFFC10090 /* DMA36 Inner Loop Address Increment */ -#define DMA36_Y_COUNT 0xFFC10094 /* DMA36 Outer Loop Count Start Value (2D only) */ -#define DMA36_Y_MODIFY 0xFFC10098 /* DMA36 Outer Loop Address Increment (2D only) */ -#define DMA36_CURR_DESC_PTR 0xFFC100A4 /* DMA36 Current Descriptor Pointer */ -#define DMA36_PREV_DESC_PTR 0xFFC100A8 /* DMA36 Previous Initial Descriptor Pointer */ -#define DMA36_CURR_ADDR 0xFFC100AC /* DMA36 Current Address */ -#define DMA36_IRQ_STATUS 0xFFC100B0 /* DMA36 Status Register */ -#define DMA36_CURR_X_COUNT 0xFFC100B4 /* DMA36 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA36_CURR_Y_COUNT 0xFFC100B8 /* DMA36 Current Row Count (2D only) */ -#define DMA36_BWL_COUNT 0xFFC100C0 /* DMA36 Bandwidth Limit Count */ -#define DMA36_CURR_BWL_COUNT 0xFFC100C4 /* DMA36 Bandwidth Limit Count Current */ -#define DMA36_BWM_COUNT 0xFFC100C8 /* DMA36 Bandwidth Monitor Count */ -#define DMA36_CURR_BWM_COUNT 0xFFC100CC /* DMA36 Bandwidth Monitor Count Current */ - -/* ========================= - DMA37 - ========================= */ -#define DMA37_NEXT_DESC_PTR 0xFFC10100 /* DMA37 Pointer to Next Initial Descriptor */ -#define DMA37_START_ADDR 0xFFC10104 /* DMA37 Start Address of Current Buffer */ -#define DMA37_CONFIG 0xFFC10108 /* DMA37 Configuration Register */ -#define DMA37_X_COUNT 0xFFC1010C /* DMA37 Inner Loop Count Start Value */ -#define DMA37_X_MODIFY 0xFFC10110 /* DMA37 Inner Loop Address Increment */ -#define DMA37_Y_COUNT 0xFFC10114 /* DMA37 Outer Loop Count Start Value (2D only) */ -#define DMA37_Y_MODIFY 0xFFC10118 /* DMA37 Outer Loop Address Increment (2D only) */ -#define DMA37_CURR_DESC_PTR 0xFFC10124 /* DMA37 Current Descriptor Pointer */ -#define DMA37_PREV_DESC_PTR 0xFFC10128 /* DMA37 Previous Initial Descriptor Pointer */ -#define DMA37_CURR_ADDR 0xFFC1012C /* DMA37 Current Address */ -#define DMA37_IRQ_STATUS 0xFFC10130 /* DMA37 Status Register */ -#define DMA37_CURR_X_COUNT 0xFFC10134 /* DMA37 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA37_CURR_Y_COUNT 0xFFC10138 /* DMA37 Current Row Count (2D only) */ -#define DMA37_BWL_COUNT 0xFFC10140 /* DMA37 Bandwidth Limit Count */ -#define DMA37_CURR_BWL_COUNT 0xFFC10144 /* DMA37 Bandwidth Limit Count Current */ -#define DMA37_BWM_COUNT 0xFFC10148 /* DMA37 Bandwidth Monitor Count */ -#define DMA37_CURR_BWM_COUNT 0xFFC1014C /* DMA37 Bandwidth Monitor Count Current */ - -/* ========================= - DMA38 - ========================= */ -#define DMA38_NEXT_DESC_PTR 0xFFC12000 /* DMA38 Pointer to Next Initial Descriptor */ -#define DMA38_START_ADDR 0xFFC12004 /* DMA38 Start Address of Current Buffer */ -#define DMA38_CONFIG 0xFFC12008 /* DMA38 Configuration Register */ -#define DMA38_X_COUNT 0xFFC1200C /* DMA38 Inner Loop Count Start Value */ -#define DMA38_X_MODIFY 0xFFC12010 /* DMA38 Inner Loop Address Increment */ -#define DMA38_Y_COUNT 0xFFC12014 /* DMA38 Outer Loop Count Start Value (2D only) */ -#define DMA38_Y_MODIFY 0xFFC12018 /* DMA38 Outer Loop Address Increment (2D only) */ -#define DMA38_CURR_DESC_PTR 0xFFC12024 /* DMA38 Current Descriptor Pointer */ -#define DMA38_PREV_DESC_PTR 0xFFC12028 /* DMA38 Previous Initial Descriptor Pointer */ -#define DMA38_CURR_ADDR 0xFFC1202C /* DMA38 Current Address */ -#define DMA38_IRQ_STATUS 0xFFC12030 /* DMA38 Status Register */ -#define DMA38_CURR_X_COUNT 0xFFC12034 /* DMA38 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA38_CURR_Y_COUNT 0xFFC12038 /* DMA38 Current Row Count (2D only) */ -#define DMA38_BWL_COUNT 0xFFC12040 /* DMA38 Bandwidth Limit Count */ -#define DMA38_CURR_BWL_COUNT 0xFFC12044 /* DMA38 Bandwidth Limit Count Current */ -#define DMA38_BWM_COUNT 0xFFC12048 /* DMA38 Bandwidth Monitor Count */ -#define DMA38_CURR_BWM_COUNT 0xFFC1204C /* DMA38 Bandwidth Monitor Count Current */ - -/* ========================= - DMA39 - ========================= */ -#define DMA39_NEXT_DESC_PTR 0xFFC12080 /* DMA39 Pointer to Next Initial Descriptor */ -#define DMA39_START_ADDR 0xFFC12084 /* DMA39 Start Address of Current Buffer */ -#define DMA39_CONFIG 0xFFC12088 /* DMA39 Configuration Register */ -#define DMA39_X_COUNT 0xFFC1208C /* DMA39 Inner Loop Count Start Value */ -#define DMA39_X_MODIFY 0xFFC12090 /* DMA39 Inner Loop Address Increment */ -#define DMA39_Y_COUNT 0xFFC12094 /* DMA39 Outer Loop Count Start Value (2D only) */ -#define DMA39_Y_MODIFY 0xFFC12098 /* DMA39 Outer Loop Address Increment (2D only) */ -#define DMA39_CURR_DESC_PTR 0xFFC120A4 /* DMA39 Current Descriptor Pointer */ -#define DMA39_PREV_DESC_PTR 0xFFC120A8 /* DMA39 Previous Initial Descriptor Pointer */ -#define DMA39_CURR_ADDR 0xFFC120AC /* DMA39 Current Address */ -#define DMA39_IRQ_STATUS 0xFFC120B0 /* DMA39 Status Register */ -#define DMA39_CURR_X_COUNT 0xFFC120B4 /* DMA39 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA39_CURR_Y_COUNT 0xFFC120B8 /* DMA39 Current Row Count (2D only) */ -#define DMA39_BWL_COUNT 0xFFC120C0 /* DMA39 Bandwidth Limit Count */ -#define DMA39_CURR_BWL_COUNT 0xFFC120C4 /* DMA39 Bandwidth Limit Count Current */ -#define DMA39_BWM_COUNT 0xFFC120C8 /* DMA39 Bandwidth Monitor Count */ -#define DMA39_CURR_BWM_COUNT 0xFFC120CC /* DMA39 Bandwidth Monitor Count Current */ - -/* ========================= - DMA40 - ========================= */ -#define DMA40_NEXT_DESC_PTR 0xFFC12100 /* DMA40 Pointer to Next Initial Descriptor */ -#define DMA40_START_ADDR 0xFFC12104 /* DMA40 Start Address of Current Buffer */ -#define DMA40_CONFIG 0xFFC12108 /* DMA40 Configuration Register */ -#define DMA40_X_COUNT 0xFFC1210C /* DMA40 Inner Loop Count Start Value */ -#define DMA40_X_MODIFY 0xFFC12110 /* DMA40 Inner Loop Address Increment */ -#define DMA40_Y_COUNT 0xFFC12114 /* DMA40 Outer Loop Count Start Value (2D only) */ -#define DMA40_Y_MODIFY 0xFFC12118 /* DMA40 Outer Loop Address Increment (2D only) */ -#define DMA40_CURR_DESC_PTR 0xFFC12124 /* DMA40 Current Descriptor Pointer */ -#define DMA40_PREV_DESC_PTR 0xFFC12128 /* DMA40 Previous Initial Descriptor Pointer */ -#define DMA40_CURR_ADDR 0xFFC1212C /* DMA40 Current Address */ -#define DMA40_IRQ_STATUS 0xFFC12130 /* DMA40 Status Register */ -#define DMA40_CURR_X_COUNT 0xFFC12134 /* DMA40 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA40_CURR_Y_COUNT 0xFFC12138 /* DMA40 Current Row Count (2D only) */ -#define DMA40_BWL_COUNT 0xFFC12140 /* DMA40 Bandwidth Limit Count */ -#define DMA40_CURR_BWL_COUNT 0xFFC12144 /* DMA40 Bandwidth Limit Count Current */ -#define DMA40_BWM_COUNT 0xFFC12148 /* DMA40 Bandwidth Monitor Count */ -#define DMA40_CURR_BWM_COUNT 0xFFC1214C /* DMA40 Bandwidth Monitor Count Current */ - -/* ========================= - DMA41 - ========================= */ -#define DMA41_NEXT_DESC_PTR 0xFFC12180 /* DMA41 Pointer to Next Initial Descriptor */ -#define DMA41_START_ADDR 0xFFC12184 /* DMA41 Start Address of Current Buffer */ -#define DMA41_CONFIG 0xFFC12188 /* DMA41 Configuration Register */ -#define DMA41_X_COUNT 0xFFC1218C /* DMA41 Inner Loop Count Start Value */ -#define DMA41_X_MODIFY 0xFFC12190 /* DMA41 Inner Loop Address Increment */ -#define DMA41_Y_COUNT 0xFFC12194 /* DMA41 Outer Loop Count Start Value (2D only) */ -#define DMA41_Y_MODIFY 0xFFC12198 /* DMA41 Outer Loop Address Increment (2D only) */ -#define DMA41_CURR_DESC_PTR 0xFFC121A4 /* DMA41 Current Descriptor Pointer */ -#define DMA41_PREV_DESC_PTR 0xFFC121A8 /* DMA41 Previous Initial Descriptor Pointer */ -#define DMA41_CURR_ADDR 0xFFC121AC /* DMA41 Current Address */ -#define DMA41_IRQ_STATUS 0xFFC121B0 /* DMA41 Status Register */ -#define DMA41_CURR_X_COUNT 0xFFC121B4 /* DMA41 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA41_CURR_Y_COUNT 0xFFC121B8 /* DMA41 Current Row Count (2D only) */ -#define DMA41_BWL_COUNT 0xFFC121C0 /* DMA41 Bandwidth Limit Count */ -#define DMA41_CURR_BWL_COUNT 0xFFC121C4 /* DMA41 Bandwidth Limit Count Current */ -#define DMA41_BWM_COUNT 0xFFC121C8 /* DMA41 Bandwidth Monitor Count */ -#define DMA41_CURR_BWM_COUNT 0xFFC121CC /* DMA41 Bandwidth Monitor Count Current */ - -/* ========================= - DMA42 - ========================= */ -#define DMA42_NEXT_DESC_PTR 0xFFC14000 /* DMA42 Pointer to Next Initial Descriptor */ -#define DMA42_START_ADDR 0xFFC14004 /* DMA42 Start Address of Current Buffer */ -#define DMA42_CONFIG 0xFFC14008 /* DMA42 Configuration Register */ -#define DMA42_X_COUNT 0xFFC1400C /* DMA42 Inner Loop Count Start Value */ -#define DMA42_X_MODIFY 0xFFC14010 /* DMA42 Inner Loop Address Increment */ -#define DMA42_Y_COUNT 0xFFC14014 /* DMA42 Outer Loop Count Start Value (2D only) */ -#define DMA42_Y_MODIFY 0xFFC14018 /* DMA42 Outer Loop Address Increment (2D only) */ -#define DMA42_CURR_DESC_PTR 0xFFC14024 /* DMA42 Current Descriptor Pointer */ -#define DMA42_PREV_DESC_PTR 0xFFC14028 /* DMA42 Previous Initial Descriptor Pointer */ -#define DMA42_CURR_ADDR 0xFFC1402C /* DMA42 Current Address */ -#define DMA42_IRQ_STATUS 0xFFC14030 /* DMA42 Status Register */ -#define DMA42_CURR_X_COUNT 0xFFC14034 /* DMA42 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA42_CURR_Y_COUNT 0xFFC14038 /* DMA42 Current Row Count (2D only) */ -#define DMA42_BWL_COUNT 0xFFC14040 /* DMA42 Bandwidth Limit Count */ -#define DMA42_CURR_BWL_COUNT 0xFFC14044 /* DMA42 Bandwidth Limit Count Current */ -#define DMA42_BWM_COUNT 0xFFC14048 /* DMA42 Bandwidth Monitor Count */ -#define DMA42_CURR_BWM_COUNT 0xFFC1404C /* DMA42 Bandwidth Monitor Count Current */ - -/* ========================= - DMA43 - ========================= */ -#define DMA43_NEXT_DESC_PTR 0xFFC14080 /* DMA43 Pointer to Next Initial Descriptor */ -#define DMA43_START_ADDR 0xFFC14084 /* DMA43 Start Address of Current Buffer */ -#define DMA43_CONFIG 0xFFC14088 /* DMA43 Configuration Register */ -#define DMA43_X_COUNT 0xFFC1408C /* DMA43 Inner Loop Count Start Value */ -#define DMA43_X_MODIFY 0xFFC14090 /* DMA43 Inner Loop Address Increment */ -#define DMA43_Y_COUNT 0xFFC14094 /* DMA43 Outer Loop Count Start Value (2D only) */ -#define DMA43_Y_MODIFY 0xFFC14098 /* DMA43 Outer Loop Address Increment (2D only) */ -#define DMA43_CURR_DESC_PTR 0xFFC140A4 /* DMA43 Current Descriptor Pointer */ -#define DMA43_PREV_DESC_PTR 0xFFC140A8 /* DMA43 Previous Initial Descriptor Pointer */ -#define DMA43_CURR_ADDR 0xFFC140AC /* DMA43 Current Address */ -#define DMA43_IRQ_STATUS 0xFFC140B0 /* DMA43 Status Register */ -#define DMA43_CURR_X_COUNT 0xFFC140B4 /* DMA43 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA43_CURR_Y_COUNT 0xFFC140B8 /* DMA43 Current Row Count (2D only) */ -#define DMA43_BWL_COUNT 0xFFC140C0 /* DMA43 Bandwidth Limit Count */ -#define DMA43_CURR_BWL_COUNT 0xFFC140C4 /* DMA43 Bandwidth Limit Count Current */ -#define DMA43_BWM_COUNT 0xFFC140C8 /* DMA43 Bandwidth Monitor Count */ -#define DMA43_CURR_BWM_COUNT 0xFFC140CC /* DMA43 Bandwidth Monitor Count Current */ - -/* ========================= - DMA44 - ========================= */ -#define DMA44_NEXT_DESC_PTR 0xFFC14100 /* DMA44 Pointer to Next Initial Descriptor */ -#define DMA44_START_ADDR 0xFFC14104 /* DMA44 Start Address of Current Buffer */ -#define DMA44_CONFIG 0xFFC14108 /* DMA44 Configuration Register */ -#define DMA44_X_COUNT 0xFFC1410C /* DMA44 Inner Loop Count Start Value */ -#define DMA44_X_MODIFY 0xFFC14110 /* DMA44 Inner Loop Address Increment */ -#define DMA44_Y_COUNT 0xFFC14114 /* DMA44 Outer Loop Count Start Value (2D only) */ -#define DMA44_Y_MODIFY 0xFFC14118 /* DMA44 Outer Loop Address Increment (2D only) */ -#define DMA44_CURR_DESC_PTR 0xFFC14124 /* DMA44 Current Descriptor Pointer */ -#define DMA44_PREV_DESC_PTR 0xFFC14128 /* DMA44 Previous Initial Descriptor Pointer */ -#define DMA44_CURR_ADDR 0xFFC1412C /* DMA44 Current Address */ -#define DMA44_IRQ_STATUS 0xFFC14130 /* DMA44 Status Register */ -#define DMA44_CURR_X_COUNT 0xFFC14134 /* DMA44 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA44_CURR_Y_COUNT 0xFFC14138 /* DMA44 Current Row Count (2D only) */ -#define DMA44_BWL_COUNT 0xFFC14140 /* DMA44 Bandwidth Limit Count */ -#define DMA44_CURR_BWL_COUNT 0xFFC14144 /* DMA44 Bandwidth Limit Count Current */ -#define DMA44_BWM_COUNT 0xFFC14148 /* DMA44 Bandwidth Monitor Count */ -#define DMA44_CURR_BWM_COUNT 0xFFC1414C /* DMA44 Bandwidth Monitor Count Current */ - -/* ========================= - DMA45 - ========================= */ -#define DMA45_NEXT_DESC_PTR 0xFFC14180 /* DMA45 Pointer to Next Initial Descriptor */ -#define DMA45_START_ADDR 0xFFC14184 /* DMA45 Start Address of Current Buffer */ -#define DMA45_CONFIG 0xFFC14188 /* DMA45 Configuration Register */ -#define DMA45_X_COUNT 0xFFC1418C /* DMA45 Inner Loop Count Start Value */ -#define DMA45_X_MODIFY 0xFFC14190 /* DMA45 Inner Loop Address Increment */ -#define DMA45_Y_COUNT 0xFFC14194 /* DMA45 Outer Loop Count Start Value (2D only) */ -#define DMA45_Y_MODIFY 0xFFC14198 /* DMA45 Outer Loop Address Increment (2D only) */ -#define DMA45_CURR_DESC_PTR 0xFFC141A4 /* DMA45 Current Descriptor Pointer */ -#define DMA45_PREV_DESC_PTR 0xFFC141A8 /* DMA45 Previous Initial Descriptor Pointer */ -#define DMA45_CURR_ADDR 0xFFC141AC /* DMA45 Current Address */ -#define DMA45_IRQ_STATUS 0xFFC141B0 /* DMA45 Status Register */ -#define DMA45_CURR_X_COUNT 0xFFC141B4 /* DMA45 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA45_CURR_Y_COUNT 0xFFC141B8 /* DMA45 Current Row Count (2D only) */ -#define DMA45_BWL_COUNT 0xFFC141C0 /* DMA45 Bandwidth Limit Count */ -#define DMA45_CURR_BWL_COUNT 0xFFC141C4 /* DMA45 Bandwidth Limit Count Current */ -#define DMA45_BWM_COUNT 0xFFC141C8 /* DMA45 Bandwidth Monitor Count */ -#define DMA45_CURR_BWM_COUNT 0xFFC141CC /* DMA45 Bandwidth Monitor Count Current */ - -/* ========================= - DMA46 - ========================= */ -#define DMA46_NEXT_DESC_PTR 0xFFC14200 /* DMA46 Pointer to Next Initial Descriptor */ -#define DMA46_START_ADDR 0xFFC14204 /* DMA46 Start Address of Current Buffer */ -#define DMA46_CONFIG 0xFFC14208 /* DMA46 Configuration Register */ -#define DMA46_X_COUNT 0xFFC1420C /* DMA46 Inner Loop Count Start Value */ -#define DMA46_X_MODIFY 0xFFC14210 /* DMA46 Inner Loop Address Increment */ -#define DMA46_Y_COUNT 0xFFC14214 /* DMA46 Outer Loop Count Start Value (2D only) */ -#define DMA46_Y_MODIFY 0xFFC14218 /* DMA46 Outer Loop Address Increment (2D only) */ -#define DMA46_CURR_DESC_PTR 0xFFC14224 /* DMA46 Current Descriptor Pointer */ -#define DMA46_PREV_DESC_PTR 0xFFC14228 /* DMA46 Previous Initial Descriptor Pointer */ -#define DMA46_CURR_ADDR 0xFFC1422C /* DMA46 Current Address */ -#define DMA46_IRQ_STATUS 0xFFC14230 /* DMA46 Status Register */ -#define DMA46_CURR_X_COUNT 0xFFC14234 /* DMA46 Current Count(1D) or intra-row XCNT (2D) */ -#define DMA46_CURR_Y_COUNT 0xFFC14238 /* DMA46 Current Row Count (2D only) */ -#define DMA46_BWL_COUNT 0xFFC14240 /* DMA46 Bandwidth Limit Count */ -#define DMA46_CURR_BWL_COUNT 0xFFC14244 /* DMA46 Bandwidth Limit Count Current */ -#define DMA46_BWM_COUNT 0xFFC14248 /* DMA46 Bandwidth Monitor Count */ -#define DMA46_CURR_BWM_COUNT 0xFFC1424C /* DMA46 Bandwidth Monitor Count Current */ - - -/******************************************************************************** - DMA Alias Definitions - ********************************************************************************/ -#define MDMA0_DEST_CRC0_NEXT_DESC_PTR (DMA22_NEXT_DESC_PTR) -#define MDMA0_DEST_CRC0_START_ADDR (DMA22_START_ADDR) -#define MDMA0_DEST_CRC0_CONFIG (DMA22_CONFIG) -#define MDMA0_DEST_CRC0_X_COUNT (DMA22_X_COUNT) -#define MDMA0_DEST_CRC0_X_MODIFY (DMA22_X_MODIFY) -#define MDMA0_DEST_CRC0_Y_COUNT (DMA22_Y_COUNT) -#define MDMA0_DEST_CRC0_Y_MODIFY (DMA22_Y_MODIFY) -#define MDMA0_DEST_CRC0_CURR_DESC_PTR (DMA22_CURR_DESC_PTR) -#define MDMA0_DEST_CRC0_PREV_DESC_PTR (DMA22_PREV_DESC_PTR) -#define MDMA0_DEST_CRC0_CURR_ADDR (DMA22_CURR_ADDR) -#define MDMA0_DEST_CRC0_IRQ_STATUS (DMA22_IRQ_STATUS) -#define MDMA0_DEST_CRC0_CURR_X_COUNT (DMA22_CURR_X_COUNT) -#define MDMA0_DEST_CRC0_CURR_Y_COUNT (DMA22_CURR_Y_COUNT) -#define MDMA0_DEST_CRC0_BWL_COUNT (DMA22_BWL_COUNT) -#define MDMA0_DEST_CRC0_CURR_BWL_COUNT (DMA22_CURR_BWL_COUNT) -#define MDMA0_DEST_CRC0_BWM_COUNT (DMA22_BWM_COUNT) -#define MDMA0_DEST_CRC0_CURR_BWM_COUNT (DMA22_CURR_BWM_COUNT) -#define MDMA0_SRC_CRC0_NEXT_DESC_PTR (DMA21_NEXT_DESC_PTR) -#define MDMA0_SRC_CRC0_START_ADDR (DMA21_START_ADDR) -#define MDMA0_SRC_CRC0_CONFIG (DMA21_CONFIG) -#define MDMA0_SRC_CRC0_X_COUNT (DMA21_X_COUNT) -#define MDMA0_SRC_CRC0_X_MODIFY (DMA21_X_MODIFY) -#define MDMA0_SRC_CRC0_Y_COUNT (DMA21_Y_COUNT) -#define MDMA0_SRC_CRC0_Y_MODIFY (DMA21_Y_MODIFY) -#define MDMA0_SRC_CRC0_CURR_DESC_PTR (DMA21_CURR_DESC_PTR) -#define MDMA0_SRC_CRC0_PREV_DESC_PTR (DMA21_PREV_DESC_PTR) -#define MDMA0_SRC_CRC0_CURR_ADDR (DMA21_CURR_ADDR) -#define MDMA0_SRC_CRC0_IRQ_STATUS (DMA21_IRQ_STATUS) -#define MDMA0_SRC_CRC0_CURR_X_COUNT (DMA21_CURR_X_COUNT) -#define MDMA0_SRC_CRC0_CURR_Y_COUNT (DMA21_CURR_Y_COUNT) -#define MDMA0_SRC_CRC0_BWL_COUNT (DMA21_BWL_COUNT) -#define MDMA0_SRC_CRC0_CURR_BWL_COUNT (DMA21_CURR_BWL_COUNT) -#define MDMA0_SRC_CRC0_BWM_COUNT (DMA21_BWM_COUNT) -#define MDMA0_SRC_CRC0_CURR_BWM_COUNT (DMA21_CURR_BWM_COUNT) -#define MDMA1_DEST_CRC1_NEXT_DESC_PTR (DMA24_NEXT_DESC_PTR) -#define MDMA1_DEST_CRC1_START_ADDR (DMA24_START_ADDR) -#define MDMA1_DEST_CRC1_CONFIG (DMA24_CONFIG) -#define MDMA1_DEST_CRC1_X_COUNT (DMA24_X_COUNT) -#define MDMA1_DEST_CRC1_X_MODIFY (DMA24_X_MODIFY) -#define MDMA1_DEST_CRC1_Y_COUNT (DMA24_Y_COUNT) -#define MDMA1_DEST_CRC1_Y_MODIFY (DMA24_Y_MODIFY) -#define MDMA1_DEST_CRC1_CURR_DESC_PTR (DMA24_CURR_DESC_PTR) -#define MDMA1_DEST_CRC1_PREV_DESC_PTR (DMA24_PREV_DESC_PTR) -#define MDMA1_DEST_CRC1_CURR_ADDR (DMA24_CURR_ADDR) -#define MDMA1_DEST_CRC1_IRQ_STATUS (DMA24_IRQ_STATUS) -#define MDMA1_DEST_CRC1_CURR_X_COUNT (DMA24_CURR_X_COUNT) -#define MDMA1_DEST_CRC1_CURR_Y_COUNT (DMA24_CURR_Y_COUNT) -#define MDMA1_DEST_CRC1_BWL_COUNT (DMA24_BWL_COUNT) -#define MDMA1_DEST_CRC1_CURR_BWL_COUNT (DMA24_CURR_BWL_COUNT) -#define MDMA1_DEST_CRC1_BWM_COUNT (DMA24_BWM_COUNT) -#define MDMA1_DEST_CRC1_CURR_BWM_COUNT (DMA24_CURR_BWM_COUNT) -#define MDMA1_SRC_CRC1_NEXT_DESC_PTR (DMA23_NEXT_DESC_PTR) -#define MDMA1_SRC_CRC1_START_ADDR (DMA23_START_ADDR) -#define MDMA1_SRC_CRC1_CONFIG (DMA23_CONFIG) -#define MDMA1_SRC_CRC1_X_COUNT (DMA23_X_COUNT) -#define MDMA1_SRC_CRC1_X_MODIFY (DMA23_X_MODIFY) -#define MDMA1_SRC_CRC1_Y_COUNT (DMA23_Y_COUNT) -#define MDMA1_SRC_CRC1_Y_MODIFY (DMA23_Y_MODIFY) -#define MDMA1_SRC_CRC1_CURR_DESC_PTR (DMA23_CURR_DESC_PTR) -#define MDMA1_SRC_CRC1_PREV_DESC_PTR (DMA23_PREV_DESC_PTR) -#define MDMA1_SRC_CRC1_CURR_ADDR (DMA23_CURR_ADDR) -#define MDMA1_SRC_CRC1_IRQ_STATUS (DMA23_IRQ_STATUS) -#define MDMA1_SRC_CRC1_CURR_X_COUNT (DMA23_CURR_X_COUNT) -#define MDMA1_SRC_CRC1_CURR_Y_COUNT (DMA23_CURR_Y_COUNT) -#define MDMA1_SRC_CRC1_BWL_COUNT (DMA23_BWL_COUNT) -#define MDMA1_SRC_CRC1_CURR_BWL_COUNT (DMA23_CURR_BWL_COUNT) -#define MDMA1_SRC_CRC1_BWM_COUNT (DMA23_BWM_COUNT) -#define MDMA1_SRC_CRC1_CURR_BWM_COUNT (DMA23_CURR_BWM_COUNT) -#define MDMA2_DEST_NEXT_DESC_PTR (DMA26_NEXT_DESC_PTR) -#define MDMA2_DEST_START_ADDR (DMA26_START_ADDR) -#define MDMA2_DEST_CONFIG (DMA26_CONFIG) -#define MDMA2_DEST_X_COUNT (DMA26_X_COUNT) -#define MDMA2_DEST_X_MODIFY (DMA26_X_MODIFY) -#define MDMA2_DEST_Y_COUNT (DMA26_Y_COUNT) -#define MDMA2_DEST_Y_MODIFY (DMA26_Y_MODIFY) -#define MDMA2_DEST_CURR_DESC_PTR (DMA26_CURR_DESC_PTR) -#define MDMA2_DEST_PREV_DESC_PTR (DMA26_PREV_DESC_PTR) -#define MDMA2_DEST_CURR_ADDR (DMA26_CURR_ADDR) -#define MDMA2_DEST_IRQ_STATUS (DMA26_IRQ_STATUS) -#define MDMA2_DEST_CURR_X_COUNT (DMA26_CURR_X_COUNT) -#define MDMA2_DEST_CURR_Y_COUNT (DMA26_CURR_Y_COUNT) -#define MDMA2_DEST_BWL_COUNT (DMA26_BWL_COUNT) -#define MDMA2_DEST_CURR_BWL_COUNT (DMA26_CURR_BWL_COUNT) -#define MDMA2_DEST_BWM_COUNT (DMA26_BWM_COUNT) -#define MDMA2_DEST_CURR_BWM_COUNT (DMA26_CURR_BWM_COUNT) -#define MDMA2_SRC_NEXT_DESC_PTR (DMA25_NEXT_DESC_PTR) -#define MDMA2_SRC_START_ADDR (DMA25_START_ADDR) -#define MDMA2_SRC_CONFIG (DMA25_CONFIG) -#define MDMA2_SRC_X_COUNT (DMA25_X_COUNT) -#define MDMA2_SRC_X_MODIFY (DMA25_X_MODIFY) -#define MDMA2_SRC_Y_COUNT (DMA25_Y_COUNT) -#define MDMA2_SRC_Y_MODIFY (DMA25_Y_MODIFY) -#define MDMA2_SRC_CURR_DESC_PTR (DMA25_CURR_DESC_PTR) -#define MDMA2_SRC_PREV_DESC_PTR (DMA25_PREV_DESC_PTR) -#define MDMA2_SRC_CURR_ADDR (DMA25_CURR_ADDR) -#define MDMA2_SRC_IRQ_STATUS (DMA25_IRQ_STATUS) -#define MDMA2_SRC_CURR_X_COUNT (DMA25_CURR_X_COUNT) -#define MDMA2_SRC_CURR_Y_COUNT (DMA25_CURR_Y_COUNT) -#define MDMA2_SRC_BWL_COUNT (DMA25_BWL_COUNT) -#define MDMA2_SRC_CURR_BWL_COUNT (DMA25_CURR_BWL_COUNT) -#define MDMA2_SRC_BWM_COUNT (DMA25_BWM_COUNT) -#define MDMA2_SRC_CURR_BWM_COUNT (DMA25_CURR_BWM_COUNT) -#define MDMA3_DEST_NEXT_DESC_PTR (DMA28_NEXT_DESC_PTR) -#define MDMA3_DEST_START_ADDR (DMA28_START_ADDR) -#define MDMA3_DEST_CONFIG (DMA28_CONFIG) -#define MDMA3_DEST_X_COUNT (DMA28_X_COUNT) -#define MDMA3_DEST_X_MODIFY (DMA28_X_MODIFY) -#define MDMA3_DEST_Y_COUNT (DMA28_Y_COUNT) -#define MDMA3_DEST_Y_MODIFY (DMA28_Y_MODIFY) -#define MDMA3_DEST_CURR_DESC_PTR (DMA28_CURR_DESC_PTR) -#define MDMA3_DEST_PREV_DESC_PTR (DMA28_PREV_DESC_PTR) -#define MDMA3_DEST_CURR_ADDR (DMA28_CURR_ADDR) -#define MDMA3_DEST_IRQ_STATUS (DMA28_IRQ_STATUS) -#define MDMA3_DEST_CURR_X_COUNT (DMA28_CURR_X_COUNT) -#define MDMA3_DEST_CURR_Y_COUNT (DMA28_CURR_Y_COUNT) -#define MDMA3_DEST_BWL_COUNT (DMA28_BWL_COUNT) -#define MDMA3_DEST_CURR_BWL_COUNT (DMA28_CURR_BWL_COUNT) -#define MDMA3_DEST_BWM_COUNT (DMA28_BWM_COUNT) -#define MDMA3_DEST_CURR_BWM_COUNT (DMA28_CURR_BWM_COUNT) -#define MDMA3_SRC_NEXT_DESC_PTR (DMA27_NEXT_DESC_PTR) -#define MDMA3_SRC_START_ADDR (DMA27_START_ADDR) -#define MDMA3_SRC_CONFIG (DMA27_CONFIG) -#define MDMA3_SRC_X_COUNT (DMA27_X_COUNT) -#define MDMA3_SRC_X_MODIFY (DMA27_X_MODIFY) -#define MDMA3_SRC_Y_COUNT (DMA27_Y_COUNT) -#define MDMA3_SRC_Y_MODIFY (DMA27_Y_MODIFY) -#define MDMA3_SRC_CURR_DESC_PTR (DMA27_CURR_DESC_PTR) -#define MDMA3_SRC_PREV_DESC_PTR (DMA27_PREV_DESC_PTR) -#define MDMA3_SRC_CURR_ADDR (DMA27_CURR_ADDR) -#define MDMA3_SRC_IRQ_STATUS (DMA27_IRQ_STATUS) -#define MDMA3_SRC_CURR_X_COUNT (DMA27_CURR_X_COUNT) -#define MDMA3_SRC_CURR_Y_COUNT (DMA27_CURR_Y_COUNT) -#define MDMA3_SRC_BWL_COUNT (DMA27_BWL_COUNT) -#define MDMA3_SRC_CURR_BWL_COUNT (DMA27_CURR_BWL_COUNT) -#define MDMA3_SRC_BWM_COUNT (DMA27_BWM_COUNT) -#define MDMA3_SRC_CURR_BWM_COUNT (DMA27_CURR_BWM_COUNT) - - -/* ========================= - DMC Registers - ========================= */ - -/* ========================= - DMC0 - ========================= */ -#define DMC0_ID 0xFFC80000 /* DMC0 Identification Register */ -#define DMC0_CTL 0xFFC80004 /* DMC0 Control Register */ -#define DMC0_STAT 0xFFC80008 /* DMC0 Status Register */ -#define DMC0_EFFCTL 0xFFC8000C /* DMC0 Efficiency Controller */ -#define DMC0_PRIO 0xFFC80010 /* DMC0 Priority ID Register */ -#define DMC0_PRIOMSK 0xFFC80014 /* DMC0 Priority ID Mask */ -#define DMC0_CFG 0xFFC80040 /* DMC0 SDRAM Configuration */ -#define DMC0_TR0 0xFFC80044 /* DMC0 Timing Register 0 */ -#define DMC0_TR1 0xFFC80048 /* DMC0 Timing Register 1 */ -#define DMC0_TR2 0xFFC8004C /* DMC0 Timing Register 2 */ -#define DMC0_MSK 0xFFC8005C /* DMC0 Mode Register Mask */ -#define DMC0_MR 0xFFC80060 /* DMC0 Mode Shadow register */ -#define DMC0_EMR1 0xFFC80064 /* DMC0 EMR1 Shadow Register */ -#define DMC0_EMR2 0xFFC80068 /* DMC0 EMR2 Shadow Register */ -#define DMC0_EMR3 0xFFC8006C /* DMC0 EMR3 Shadow Register */ -#define DMC0_DLLCTL 0xFFC80080 /* DMC0 DLL Control Register */ -#define DMC0_PADCTL 0xFFC800C0 /* DMC0 PAD Control Register 0 */ - -#define DEVSZ_64 0x000 /* DMC External Bank Size = 64Mbit */ -#define DEVSZ_128 0x100 /* DMC External Bank Size = 128Mbit */ -#define DEVSZ_256 0x200 /* DMC External Bank Size = 256Mbit */ -#define DEVSZ_512 0x300 /* DMC External Bank Size = 512Mbit */ -#define DEVSZ_1G 0x400 /* DMC External Bank Size = 1Gbit */ -#define DEVSZ_2G 0x500 /* DMC External Bank Size = 2Gbit */ - - -/* ========================= - L2CTL Registers - ========================= */ - -/* ========================= - L2CTL0 - ========================= */ -#define L2CTL0_CTL 0xFFCA3000 /* L2CTL0 L2 Control Register */ -#define L2CTL0_ACTL_C0 0xFFCA3004 /* L2CTL0 L2 Core 0 Access Control Register */ -#define L2CTL0_ACTL_C1 0xFFCA3008 /* L2CTL0 L2 Core 1 Access Control Register */ -#define L2CTL0_ACTL_SYS 0xFFCA300C /* L2CTL0 L2 System Access Control Register */ -#define L2CTL0_STAT 0xFFCA3010 /* L2CTL0 L2 Status Register */ -#define L2CTL0_RPCR 0xFFCA3014 /* L2CTL0 L2 Read Priority Count Register */ -#define L2CTL0_WPCR 0xFFCA3018 /* L2CTL0 L2 Write Priority Count Register */ -#define L2CTL0_RFA 0xFFCA3024 /* L2CTL0 L2 Refresh Address Regsiter */ -#define L2CTL0_ERRADDR0 0xFFCA3040 /* L2CTL0 L2 Bank 0 ECC Error Address Register */ -#define L2CTL0_ERRADDR1 0xFFCA3044 /* L2CTL0 L2 Bank 1 ECC Error Address Register */ -#define L2CTL0_ERRADDR2 0xFFCA3048 /* L2CTL0 L2 Bank 2 ECC Error Address Register */ -#define L2CTL0_ERRADDR3 0xFFCA304C /* L2CTL0 L2 Bank 3 ECC Error Address Register */ -#define L2CTL0_ERRADDR4 0xFFCA3050 /* L2CTL0 L2 Bank 4 ECC Error Address Register */ -#define L2CTL0_ERRADDR5 0xFFCA3054 /* L2CTL0 L2 Bank 5 ECC Error Address Register */ -#define L2CTL0_ERRADDR6 0xFFCA3058 /* L2CTL0 L2 Bank 6 ECC Error Address Register */ -#define L2CTL0_ERRADDR7 0xFFCA305C /* L2CTL0 L2 Bank 7 ECC Error Address Register */ -#define L2CTL0_ET0 0xFFCA3080 /* L2CTL0 L2 AXI Error 0 Type Register */ -#define L2CTL0_EADDR0 0xFFCA3084 /* L2CTL0 L2 AXI Error 0 Address Register */ -#define L2CTL0_ET1 0xFFCA3088 /* L2CTL0 L2 AXI Error 1 Type Register */ -#define L2CTL0_EADDR1 0xFFCA308C /* L2CTL0 L2 AXI Error 1 Address Register */ - - -/* ========================= - SEC Registers - ========================= */ -/* ------------------------------------------------------------------------------------------------------------------------ - SEC Core Interface (SCI) Register Definitions - ------------------------------------------------------------------------------------------------------------------------ */ - -#define SEC_SCI_BASE 0xFFCA4400 -#define SEC_SCI_OFF 0x40 -#define SEC_CCTL 0x0 /* SEC Core Control Register n */ -#define SEC_CSTAT 0x4 /* SEC Core Status Register n */ -#define SEC_CPND 0x8 /* SEC Core Pending IRQ Register n */ -#define SEC_CACT 0xC /* SEC Core Active IRQ Register n */ -#define SEC_CPMSK 0x10 /* SEC Core IRQ Priority Mask Register n */ -#define SEC_CGMSK 0x14 /* SEC Core IRQ Group Mask Register n */ -#define SEC_CPLVL 0x18 /* SEC Core IRQ Priority Level Register n */ -#define SEC_CSID 0x1C /* SEC Core IRQ Source ID Register n */ - -#define bfin_read_SEC_SCI(n, reg) bfin_read32(SEC_SCI_BASE + (n) * SEC_SCI_OFF + reg) -#define bfin_write_SEC_SCI(n, reg, val) \ - bfin_write32(SEC_SCI_BASE + (n) * SEC_SCI_OFF + reg, val) - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC Fault Management Interface (SFI) Register Definitions - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_FCTL 0xFFCA4010 /* SEC Fault Control Register */ -#define SEC_FSTAT 0xFFCA4014 /* SEC Fault Status Register */ -#define SEC_FSID 0xFFCA4018 /* SEC Fault Source ID Register */ -#define SEC_FEND 0xFFCA401C /* SEC Fault End Register */ -#define SEC_FDLY 0xFFCA4020 /* SEC Fault Delay Register */ -#define SEC_FDLY_CUR 0xFFCA4024 /* SEC Fault Delay Current Register */ -#define SEC_FSRDLY 0xFFCA4028 /* SEC Fault System Reset Delay Register */ -#define SEC_FSRDLY_CUR 0xFFCA402C /* SEC Fault System Reset Delay Current Register */ -#define SEC_FCOPP 0xFFCA4030 /* SEC Fault COP Period Register */ -#define SEC_FCOPP_CUR 0xFFCA4034 /* SEC Fault COP Period Current Register */ - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC Global Register Definitions - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_GCTL 0xFFCA4000 /* SEC Global Control Register */ -#define SEC_GSTAT 0xFFCA4004 /* SEC Global Status Register */ -#define SEC_RAISE 0xFFCA4008 /* SEC Global Raise Register */ -#define SEC_END 0xFFCA400C /* SEC Global End Register */ - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC Source Interface (SSI) Register Definitions - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_SCTL0 0xFFCA4800 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL1 0xFFCA4808 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL2 0xFFCA4810 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL3 0xFFCA4818 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL4 0xFFCA4820 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL5 0xFFCA4828 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL6 0xFFCA4830 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL7 0xFFCA4838 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL8 0xFFCA4840 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL9 0xFFCA4848 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL10 0xFFCA4850 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL11 0xFFCA4858 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL12 0xFFCA4860 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL13 0xFFCA4868 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL14 0xFFCA4870 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL15 0xFFCA4878 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL16 0xFFCA4880 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL17 0xFFCA4888 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL18 0xFFCA4890 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL19 0xFFCA4898 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL20 0xFFCA48A0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL21 0xFFCA48A8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL22 0xFFCA48B0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL23 0xFFCA48B8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL24 0xFFCA48C0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL25 0xFFCA48C8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL26 0xFFCA48D0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL27 0xFFCA48D8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL28 0xFFCA48E0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL29 0xFFCA48E8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL30 0xFFCA48F0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL31 0xFFCA48F8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL32 0xFFCA4900 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL33 0xFFCA4908 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL34 0xFFCA4910 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL35 0xFFCA4918 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL36 0xFFCA4920 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL37 0xFFCA4928 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL38 0xFFCA4930 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL39 0xFFCA4938 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL40 0xFFCA4940 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL41 0xFFCA4948 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL42 0xFFCA4950 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL43 0xFFCA4958 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL44 0xFFCA4960 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL45 0xFFCA4968 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL46 0xFFCA4970 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL47 0xFFCA4978 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL48 0xFFCA4980 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL49 0xFFCA4988 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL50 0xFFCA4990 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL51 0xFFCA4998 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL52 0xFFCA49A0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL53 0xFFCA49A8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL54 0xFFCA49B0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL55 0xFFCA49B8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL56 0xFFCA49C0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL57 0xFFCA49C8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL58 0xFFCA49D0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL59 0xFFCA49D8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL60 0xFFCA49E0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL61 0xFFCA49E8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL62 0xFFCA49F0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL63 0xFFCA49F8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL64 0xFFCA4A00 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL65 0xFFCA4A08 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL66 0xFFCA4A10 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL67 0xFFCA4A18 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL68 0xFFCA4A20 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL69 0xFFCA4A28 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL70 0xFFCA4A30 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL71 0xFFCA4A38 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL72 0xFFCA4A40 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL73 0xFFCA4A48 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL74 0xFFCA4A50 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL75 0xFFCA4A58 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL76 0xFFCA4A60 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL77 0xFFCA4A68 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL78 0xFFCA4A70 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL79 0xFFCA4A78 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL80 0xFFCA4A80 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL81 0xFFCA4A88 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL82 0xFFCA4A90 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL83 0xFFCA4A98 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL84 0xFFCA4AA0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL85 0xFFCA4AA8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL86 0xFFCA4AB0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL87 0xFFCA4AB8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL88 0xFFCA4AC0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL89 0xFFCA4AC8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL90 0xFFCA4AD0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL91 0xFFCA4AD8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL92 0xFFCA4AE0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL93 0xFFCA4AE8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL94 0xFFCA4AF0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL95 0xFFCA4AF8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL96 0xFFCA4B00 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL97 0xFFCA4B08 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL98 0xFFCA4B10 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL99 0xFFCA4B18 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL100 0xFFCA4B20 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL101 0xFFCA4B28 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL102 0xFFCA4B30 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL103 0xFFCA4B38 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL104 0xFFCA4B40 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL105 0xFFCA4B48 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL106 0xFFCA4B50 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL107 0xFFCA4B58 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL108 0xFFCA4B60 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL109 0xFFCA4B68 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL110 0xFFCA4B70 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL111 0xFFCA4B78 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL112 0xFFCA4B80 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL113 0xFFCA4B88 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL114 0xFFCA4B90 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL115 0xFFCA4B98 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL116 0xFFCA4BA0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL117 0xFFCA4BA8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL118 0xFFCA4BB0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL119 0xFFCA4BB8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL120 0xFFCA4BC0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL121 0xFFCA4BC8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL122 0xFFCA4BD0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL123 0xFFCA4BD8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL124 0xFFCA4BE0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL125 0xFFCA4BE8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL126 0xFFCA4BF0 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL127 0xFFCA4BF8 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL128 0xFFCA4C00 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL129 0xFFCA4C08 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL130 0xFFCA4C10 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL131 0xFFCA4C18 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL132 0xFFCA4C20 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL133 0xFFCA4C28 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL134 0xFFCA4C30 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL135 0xFFCA4C38 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL136 0xFFCA4C40 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL137 0xFFCA4C48 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL138 0xFFCA4C50 /* SEC IRQ Source Control Register n */ -#define SEC_SCTL139 0xFFCA4C58 /* SEC IRQ Source Control Register n */ -#define SEC_SSTAT0 0xFFCA4804 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT1 0xFFCA480C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT2 0xFFCA4814 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT3 0xFFCA481C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT4 0xFFCA4824 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT5 0xFFCA482C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT6 0xFFCA4834 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT7 0xFFCA483C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT8 0xFFCA4844 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT9 0xFFCA484C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT10 0xFFCA4854 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT11 0xFFCA485C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT12 0xFFCA4864 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT13 0xFFCA486C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT14 0xFFCA4874 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT15 0xFFCA487C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT16 0xFFCA4884 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT17 0xFFCA488C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT18 0xFFCA4894 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT19 0xFFCA489C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT20 0xFFCA48A4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT21 0xFFCA48AC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT22 0xFFCA48B4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT23 0xFFCA48BC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT24 0xFFCA48C4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT25 0xFFCA48CC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT26 0xFFCA48D4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT27 0xFFCA48DC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT28 0xFFCA48E4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT29 0xFFCA48EC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT30 0xFFCA48F4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT31 0xFFCA48FC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT32 0xFFCA4904 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT33 0xFFCA490C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT34 0xFFCA4914 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT35 0xFFCA491C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT36 0xFFCA4924 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT37 0xFFCA492C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT38 0xFFCA4934 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT39 0xFFCA493C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT40 0xFFCA4944 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT41 0xFFCA494C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT42 0xFFCA4954 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT43 0xFFCA495C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT44 0xFFCA4964 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT45 0xFFCA496C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT46 0xFFCA4974 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT47 0xFFCA497C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT48 0xFFCA4984 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT49 0xFFCA498C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT50 0xFFCA4994 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT51 0xFFCA499C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT52 0xFFCA49A4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT53 0xFFCA49AC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT54 0xFFCA49B4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT55 0xFFCA49BC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT56 0xFFCA49C4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT57 0xFFCA49CC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT58 0xFFCA49D4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT59 0xFFCA49DC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT60 0xFFCA49E4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT61 0xFFCA49EC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT62 0xFFCA49F4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT63 0xFFCA49FC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT64 0xFFCA4A04 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT65 0xFFCA4A0C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT66 0xFFCA4A14 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT67 0xFFCA4A1C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT68 0xFFCA4A24 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT69 0xFFCA4A2C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT70 0xFFCA4A34 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT71 0xFFCA4A3C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT72 0xFFCA4A44 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT73 0xFFCA4A4C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT74 0xFFCA4A54 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT75 0xFFCA4A5C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT76 0xFFCA4A64 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT77 0xFFCA4A6C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT78 0xFFCA4A74 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT79 0xFFCA4A7C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT80 0xFFCA4A84 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT81 0xFFCA4A8C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT82 0xFFCA4A94 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT83 0xFFCA4A9C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT84 0xFFCA4AA4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT85 0xFFCA4AAC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT86 0xFFCA4AB4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT87 0xFFCA4ABC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT88 0xFFCA4AC4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT89 0xFFCA4ACC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT90 0xFFCA4AD4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT91 0xFFCA4ADC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT92 0xFFCA4AE4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT93 0xFFCA4AEC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT94 0xFFCA4AF4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT95 0xFFCA4AFC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT96 0xFFCA4B04 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT97 0xFFCA4B0C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT98 0xFFCA4B14 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT99 0xFFCA4B1C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT100 0xFFCA4B24 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT101 0xFFCA4B2C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT102 0xFFCA4B34 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT103 0xFFCA4B3C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT104 0xFFCA4B44 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT105 0xFFCA4B4C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT106 0xFFCA4B54 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT107 0xFFCA4B5C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT108 0xFFCA4B64 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT109 0xFFCA4B6C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT110 0xFFCA4B74 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT111 0xFFCA4B7C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT112 0xFFCA4B84 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT113 0xFFCA4B8C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT114 0xFFCA4B94 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT115 0xFFCA4B9C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT116 0xFFCA4BA4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT117 0xFFCA4BAC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT118 0xFFCA4BB4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT119 0xFFCA4BBC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT120 0xFFCA4BC4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT121 0xFFCA4BCC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT122 0xFFCA4BD4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT123 0xFFCA4BDC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT124 0xFFCA4BE4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT125 0xFFCA4BEC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT126 0xFFCA4BF4 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT127 0xFFCA4BFC /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT128 0xFFCA4C04 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT129 0xFFCA4C0C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT130 0xFFCA4C14 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT131 0xFFCA4C1C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT132 0xFFCA4C24 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT133 0xFFCA4C2C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT134 0xFFCA4C34 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT135 0xFFCA4C3C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT136 0xFFCA4C44 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT137 0xFFCA4C4C /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT138 0xFFCA4C54 /* SEC IRQ Source Status Register n */ -#define SEC_SSTAT139 0xFFCA4C5C /* SEC IRQ Source Status Register n */ - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC_CCTL Pos/Masks Description - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_CCTL_LOCK 0x80000000 /* LOCK: Lock */ -#define SEC_CCTL_NMI_EN 0x00010000 /* NMIEN: Enable */ -#define SEC_CCTL_WAITIDLE 0x00001000 /* WFI: Wait for Idle */ -#define SEC_CCTL_RESET 0x00000002 /* RESET: Reset */ -#define SEC_CCTL_EN 0x00000001 /* EN: Enable */ - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC_CSTAT Pos/Masks Description - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_CSTAT_NMI 0x00010000 /* NMI Status */ -#define SEC_CSTAT_WAITING 0x00001000 /* WFI: Waiting */ -#define SEC_CSTAT_VALID_SID 0x00000400 /* SIDV: Valid */ -#define SEC_CSTAT_VALID_ACT 0x00000200 /* ACTV: Valid */ -#define SEC_CSTAT_VALID_PND 0x00000100 /* PNDV: Valid */ -#define SEC_CSTAT_ERRC 0x00000030 /* Error Cause */ -#define SEC_CSTAT_ACKERR 0x00000010 /* ERRC: Acknowledge Error */ -#define SEC_CSTAT_ERR 0x00000002 /* ERR: Error Occurred */ - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC_CPND Pos/Masks Description - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_CPND_PRIO 0x0000FF00 /* Highest Pending IRQ Priority */ -#define SEC_CPND_SID 0x000000FF /* Highest Pending IRQ Source ID */ - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC_CACT Pos/Masks Description - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_CACT_PRIO 0x0000FF00 /* Highest Active IRQ Priority */ -#define SEC_CACT_SID 0x000000FF /* Highest Active IRQ Source ID */ - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC_CPMSK Pos/Masks Description - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_CPMSK_LOCK 0x80000000 /* LOCK: Lock */ -#define SEC_CPMSK_PRIO 0x000000FF /* IRQ Priority Mask */ - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC_CGMSK Pos/Masks Description - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_CGMSK_LOCK 0x80000000 /* LOCK: Lock */ -#define SEC_CGMSK_MASK 0x00000100 /* UGRP: Mask Ungrouped Sources */ -#define SEC_CGMSK_GRP 0x0000000F /* Grouped Mask */ - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC_CPLVL Pos/Masks Description - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_CPLVL_LOCK 0x80000000 /* LOCK: Lock */ -#define SEC_CPLVL_PLVL 0x00000007 /* Priority Levels */ - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC_CSID Pos/Masks Description - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_CSID_SID 0x000000FF /* Source ID */ - - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC_FCTL Pos/Masks Description - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_FCTL_LOCK 0x80000000 /* LOCK: Lock */ -#define SEC_FCTL_FLTPND_MODE 0x00002000 /* TES: Fault Pending Mode */ -#define SEC_FCTL_COP_MODE 0x00001000 /* CMS: COP Mode */ -#define SEC_FCTL_FLTIN_EN 0x00000080 /* FIEN: Enable */ -#define SEC_FCTL_SYSRST_EN 0x00000040 /* SREN: Enable */ -#define SEC_FCTL_TRGOUT_EN 0x00000020 /* TOEN: Enable */ -#define SEC_FCTL_FLTOUT_EN 0x00000010 /* FOEN: Enable */ -#define SEC_FCTL_RESET 0x00000002 /* RESET: Reset */ -#define SEC_FCTL_EN 0x00000001 /* EN: Enable */ - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC_FSTAT Pos/Masks Description - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_FSTAT_NXTFLT 0x00000400 /* NPND: Pending */ -#define SEC_FSTAT_FLTACT 0x00000200 /* ACT: Active Fault */ -#define SEC_FSTAT_FLTPND 0x00000100 /* PND: Pending */ -#define SEC_FSTAT_ERRC 0x00000030 /* Error Cause */ -#define SEC_FSTAT_ENDERR 0x00000020 /* ERRC: End Error */ -#define SEC_FSTAT_ERR 0x00000002 /* ERR: Error Occurred */ - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC_FSID Pos/Masks Description - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_FSID_SRC_EXTFLT 0x00010000 /* FEXT: Fault External */ -#define SEC_FSID_SID 0x000000FF /* Source ID */ - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC_FEND Pos/Masks Description - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_FEND_END_EXTFLT 0x00010000 /* FEXT: Fault External */ -#define SEC_FEND_SID 0x000000FF /* Source ID */ - - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC_GCTL Pos/Masks Description - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_GCTL_LOCK 0x80000000 /* Lock */ -#define SEC_GCTL_RESET 0x00000002 /* Reset */ -#define SEC_GCTL_EN 0x00000001 /* Enable */ - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC_GSTAT Pos/Masks Description - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_GSTAT_LWERR 0x80000000 /* LWERR: Error Occurred */ -#define SEC_GSTAT_ADRERR 0x40000000 /* ADRERR: Error Occurred */ -#define SEC_GSTAT_SID 0x00FF0000 /* Source ID for SSI Error */ -#define SEC_GSTAT_SCI 0x00000F00 /* SCI ID for SCI Error */ -#define SEC_GSTAT_ERRC 0x00000030 /* Error Cause */ -#define SEC_GSTAT_SCIERR 0x00000010 /* ERRC: SCI Error */ -#define SEC_GSTAT_SSIERR 0x00000020 /* ERRC: SSI Error */ -#define SEC_GSTAT_ERR 0x00000002 /* ERR: Error Occurred */ - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC_RAISE Pos/Masks Description - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_RAISE_SID 0x000000FF /* Source ID IRQ Set to Pending */ - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC_END Pos/Masks Description - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_END_SID 0x000000FF /* Source ID IRQ to End */ - - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC_SCTL Pos/Masks Description - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_SCTL_LOCK 0x80000000 /* Lock */ -#define SEC_SCTL_CTG 0x0F000000 /* Core Target Select */ -#define SEC_SCTL_GRP 0x000F0000 /* Group Select */ -#define SEC_SCTL_PRIO 0x0000FF00 /* Priority Level Select */ -#define SEC_SCTL_ERR_EN 0x00000010 /* ERREN: Enable */ -#define SEC_SCTL_EDGE 0x00000008 /* ES: Edge Sensitive */ -#define SEC_SCTL_SRC_EN 0x00000004 /* SEN: Enable */ -#define SEC_SCTL_FAULT_EN 0x00000002 /* FEN: Enable */ -#define SEC_SCTL_INT_EN 0x00000001 /* IEN: Enable */ - -/* ------------------------------------------------------------------------------------------------------------------------ - SEC_SSTAT Pos/Masks Description - ------------------------------------------------------------------------------------------------------------------------ */ -#define SEC_SSTAT_CHID 0x00FF0000 /* Channel ID */ -#define SEC_SSTAT_ACTIVE_SRC 0x00000200 /* ACT: Active Source */ -#define SEC_SSTAT_PENDING 0x00000100 /* PND: Pending */ -#define SEC_SSTAT_ERRC 0x00000030 /* Error Cause */ -#define SEC_SSTAT_ENDERR 0x00000020 /* ERRC: End Error */ -#define SEC_SSTAT_ERR 0x00000002 /* Error */ - - -/* ========================= - RCU Registers - ========================= */ - -/* ========================= - RCU0 - ========================= */ -#define RCU0_CTL 0xFFCA6000 /* RCU0 Control Register */ -#define RCU0_STAT 0xFFCA6004 /* RCU0 Status Register */ -#define RCU0_CRCTL 0xFFCA6008 /* RCU0 Core Reset Control Register */ -#define RCU0_CRSTAT 0xFFCA600C /* RCU0 Core Reset Status Register */ -#define RCU0_SIDIS 0xFFCA6010 /* RCU0 System Interface Disable Register */ -#define RCU0_SISTAT 0xFFCA6014 /* RCU0 System Interface Status Register */ -#define RCU0_SVECT_LCK 0xFFCA6018 /* RCU0 SVECT Lock Register */ -#define RCU0_BCODE 0xFFCA601C /* RCU0 Boot Code Register */ -#define RCU0_SVECT0 0xFFCA6020 /* RCU0 Software Vector Register n */ -#define RCU0_SVECT1 0xFFCA6024 /* RCU0 Software Vector Register n */ - - -/* ========================= - CGU0 - ========================= */ -#define CGU0_CTL 0xFFCA8000 /* CGU0 Control Register */ -#define CGU0_STAT 0xFFCA8004 /* CGU0 Status Register */ -#define CGU0_DIV 0xFFCA8008 /* CGU0 Divisor Register */ -#define CGU0_CLKOUTSEL 0xFFCA800C /* CGU0 CLKOUT Select Register */ - - -/* ========================= - DPM Registers - ========================= */ - -/* ========================= - DPM0 - ========================= */ -#define DPM0_CTL 0xFFCA9000 /* DPM0 Control Register */ -#define DPM0_STAT 0xFFCA9004 /* DPM0 Status Register */ -#define DPM0_CCBF_DIS 0xFFCA9008 /* DPM0 Core Clock Buffer Disable Register */ -#define DPM0_CCBF_EN 0xFFCA900C /* DPM0 Core Clock Buffer Enable Register */ -#define DPM0_CCBF_STAT 0xFFCA9010 /* DPM0 Core Clock Buffer Status Register */ -#define DPM0_CCBF_STAT_STKY 0xFFCA9014 /* DPM0 Core Clock Buffer Status Sticky Register */ -#define DPM0_SCBF_DIS 0xFFCA9018 /* DPM0 System Clock Buffer Disable Register */ -#define DPM0_WAKE_EN 0xFFCA901C /* DPM0 Wakeup Enable Register */ -#define DPM0_WAKE_POL 0xFFCA9020 /* DPM0 Wakeup Polarity Register */ -#define DPM0_WAKE_STAT 0xFFCA9024 /* DPM0 Wakeup Status Register */ -#define DPM0_HIB_DIS 0xFFCA9028 /* DPM0 Hibernate Disable Register */ -#define DPM0_PGCNTR 0xFFCA902C /* DPM0 Power Good Counter Register */ -#define DPM0_RESTORE0 0xFFCA9030 /* DPM0 Restore Register */ -#define DPM0_RESTORE1 0xFFCA9034 /* DPM0 Restore Register */ -#define DPM0_RESTORE2 0xFFCA9038 /* DPM0 Restore Register */ -#define DPM0_RESTORE3 0xFFCA903C /* DPM0 Restore Register */ -#define DPM0_RESTORE4 0xFFCA9040 /* DPM0 Restore Register */ -#define DPM0_RESTORE5 0xFFCA9044 /* DPM0 Restore Register */ -#define DPM0_RESTORE6 0xFFCA9048 /* DPM0 Restore Register */ -#define DPM0_RESTORE7 0xFFCA904C /* DPM0 Restore Register */ -#define DPM0_RESTORE8 0xFFCA9050 /* DPM0 Restore Register */ -#define DPM0_RESTORE9 0xFFCA9054 /* DPM0 Restore Register */ -#define DPM0_RESTORE10 0xFFCA9058 /* DPM0 Restore Register */ -#define DPM0_RESTORE11 0xFFCA905C /* DPM0 Restore Register */ -#define DPM0_RESTORE12 0xFFCA9060 /* DPM0 Restore Register */ -#define DPM0_RESTORE13 0xFFCA9064 /* DPM0 Restore Register */ -#define DPM0_RESTORE14 0xFFCA9068 /* DPM0 Restore Register */ -#define DPM0_RESTORE15 0xFFCA906C /* DPM0 Restore Register */ - - -/* ========================= - DBG Registers - ========================= */ - -/* USB register */ -#define USB_FADDR 0xFFCC1000 /* USB Device Address in Peripheral Mode */ -#define USB_POWER 0xFFCC1001 /* USB Power and Device Control */ -#define USB_INTRTX 0xFFCC1002 /* USB Transmit Interrupt */ -#define USB_INTRRX 0xFFCC1004 /* USB Receive Interrupts */ -#define USB_INTRTXE 0xFFCC1006 /* USB Transmit Interrupt Enable */ -#define USB_INTRRXE 0xFFCC1008 /* USB Receive Interrupt Enable */ -#define USB_INTRUSB 0xFFCC100A /* USB USB Interrupts */ -#define USB_INTRUSBE 0xFFCC100B /* USB USB Interrupt Enable */ -#define USB_FRAME 0xFFCC100C /* USB Frame Number */ -#define USB_INDEX 0xFFCC100E /* USB Index */ -#define USB_TESTMODE 0xFFCC100F /* USB Testmodes */ -#define USB_EPI_TXMAXP0 0xFFCC1010 /* USB Transmit Maximum Packet Length */ -#define USB_EP_NI0_TXMAXP 0xFFCC1010 -#define USB_EP0I_CSR0_H 0xFFCC1012 /* USB Config and Status EP0 */ -#define USB_EPI_TXCSR0_H 0xFFCC1012 /* USB Transmit Configuration and Status */ -#define USB_EP0I_CSR0_P 0xFFCC1012 /* USB Config and Status EP0 */ -#define USB_EPI_TXCSR0_P 0xFFCC1012 /* USB Transmit Configuration and Status */ -#define USB_EPI_RXMAXP0 0xFFCC1014 /* USB Receive Maximum Packet Length */ -#define USB_EPI_RXCSR0_H 0xFFCC1016 /* USB Receive Configuration and Status Register */ -#define USB_EPI_RXCSR0_P 0xFFCC1016 /* USB Receive Configuration and Status Register */ -#define USB_EP0I_CNT0 0xFFCC1018 /* USB Number of Received Bytes for Endpoint 0 */ -#define USB_EPI_RXCNT0 0xFFCC1018 /* USB Number of Byte Received */ -#define USB_EP0I_TYPE0 0xFFCC101A /* USB Speed for Endpoint 0 */ -#define USB_EPI_TXTYPE0 0xFFCC101A /* USB Transmit Type */ -#define USB_EP0I_NAKLIMIT0 0xFFCC101B /* USB NAK Response Timeout for Endpoint 0 */ -#define USB_EPI_TXINTERVAL0 0xFFCC101B /* USB Transmit Polling Interval */ -#define USB_EPI_RXTYPE0 0xFFCC101C /* USB Receive Type */ -#define USB_EPI_RXINTERVAL0 0xFFCC101D /* USB Receive Polling Interval */ -#define USB_EP0I_CFGDATA0 0xFFCC101F /* USB Configuration Information */ -#define USB_FIFOB0 0xFFCC1020 /* USB FIFO Data */ -#define USB_FIFOB1 0xFFCC1024 /* USB FIFO Data */ -#define USB_FIFOB2 0xFFCC1028 /* USB FIFO Data */ -#define USB_FIFOB3 0xFFCC102C /* USB FIFO Data */ -#define USB_FIFOB4 0xFFCC1030 /* USB FIFO Data */ -#define USB_FIFOB5 0xFFCC1034 /* USB FIFO Data */ -#define USB_FIFOB6 0xFFCC1038 /* USB FIFO Data */ -#define USB_FIFOB7 0xFFCC103C /* USB FIFO Data */ -#define USB_FIFOB8 0xFFCC1040 /* USB FIFO Data */ -#define USB_FIFOB9 0xFFCC1044 /* USB FIFO Data */ -#define USB_FIFOB10 0xFFCC1048 /* USB FIFO Data */ -#define USB_FIFOB11 0xFFCC104C /* USB FIFO Data */ -#define USB_FIFOH0 0xFFCC1020 /* USB FIFO Data */ -#define USB_FIFOH1 0xFFCC1024 /* USB FIFO Data */ -#define USB_FIFOH2 0xFFCC1028 /* USB FIFO Data */ -#define USB_FIFOH3 0xFFCC102C /* USB FIFO Data */ -#define USB_FIFOH4 0xFFCC1030 /* USB FIFO Data */ -#define USB_FIFOH5 0xFFCC1034 /* USB FIFO Data */ -#define USB_FIFOH6 0xFFCC1038 /* USB FIFO Data */ -#define USB_FIFOH7 0xFFCC103C /* USB FIFO Data */ -#define USB_FIFOH8 0xFFCC1040 /* USB FIFO Data */ -#define USB_FIFOH9 0xFFCC1044 /* USB FIFO Data */ -#define USB_FIFOH10 0xFFCC1048 /* USB FIFO Data */ -#define USB_FIFOH11 0xFFCC104C /* USB FIFO Data */ -#define USB_FIFO0 0xFFCC1020 /* USB FIFO Data */ -#define USB_EP0_FIFO 0xFFCC1020 -#define USB_FIFO1 0xFFCC1024 /* USB FIFO Data */ -#define USB_FIFO2 0xFFCC1028 /* USB FIFO Data */ -#define USB_FIFO3 0xFFCC102C /* USB FIFO Data */ -#define USB_FIFO4 0xFFCC1030 /* USB FIFO Data */ -#define USB_FIFO5 0xFFCC1034 /* USB FIFO Data */ -#define USB_FIFO6 0xFFCC1038 /* USB FIFO Data */ -#define USB_FIFO7 0xFFCC103C /* USB FIFO Data */ -#define USB_FIFO8 0xFFCC1040 /* USB FIFO Data */ -#define USB_FIFO9 0xFFCC1044 /* USB FIFO Data */ -#define USB_FIFO10 0xFFCC1048 /* USB FIFO Data */ -#define USB_FIFO11 0xFFCC104C /* USB FIFO Data */ -#define USB_OTG_DEV_CTL 0xFFCC1060 /* USB Device Control */ -#define USB_TXFIFOSZ 0xFFCC1062 /* USB Transmit FIFO Size */ -#define USB_RXFIFOSZ 0xFFCC1063 /* USB Receive FIFO Size */ -#define USB_TXFIFOADDR 0xFFCC1064 /* USB Transmit FIFO Address */ -#define USB_RXFIFOADDR 0xFFCC1066 /* USB Receive FIFO Address */ -#define USB_VENDSTAT 0xFFCC1068 /* USB Vendor Status */ -#define USB_HWVERS 0xFFCC106C /* USB Hardware Version */ -#define USB_EPINFO 0xFFCC1078 /* USB Endpoint Info */ -#define USB_RAMINFO 0xFFCC1079 /* USB Ram Information */ -#define USB_LINKINFO 0xFFCC107A /* USB Programmable Delay Values */ -#define USB_VPLEN 0xFFCC107B /* USB VBus Pulse Duration */ -#define USB_HS_EOF1 0xFFCC107C /* USB High Speed End of Frame Remaining */ -#define USB_FS_EOF1 0xFFCC107D /* USB Full Speed End of Frame Remaining */ -#define USB_LS_EOF1 0xFFCC107E /* USB Low Speed End of Frame Remaining */ -#define USB_SOFT_RST 0xFFCC107F /* USB Software Reset */ -#define USB_TXFUNCADDR0 0xFFCC1080 /* USB Transmit Function Address */ -#define USB_TXFUNCADDR1 0xFFCC1088 /* USB Transmit Function Address */ -#define USB_TXFUNCADDR2 0xFFCC1090 /* USB Transmit Function Address */ -#define USB_TXFUNCADDR3 0xFFCC1098 /* USB Transmit Function Address */ -#define USB_TXFUNCADDR4 0xFFCC10A0 /* USB Transmit Function Address */ -#define USB_TXFUNCADDR5 0xFFCC10A8 /* USB Transmit Function Address */ -#define USB_TXFUNCADDR6 0xFFCC10B0 /* USB Transmit Function Address */ -#define USB_TXFUNCADDR7 0xFFCC10B8 /* USB Transmit Function Address */ -#define USB_TXFUNCADDR8 0xFFCC10C0 /* USB Transmit Function Address */ -#define USB_TXFUNCADDR9 0xFFCC10C8 /* USB Transmit Function Address */ -#define USB_TXFUNCADDR10 0xFFCC10D0 /* USB Transmit Function Address */ -#define USB_TXFUNCADDR11 0xFFCC10D8 /* USB Transmit Function Address */ -#define USB_TXHUBADDR0 0xFFCC1082 /* USB Transmit Hub Address */ -#define USB_TXHUBADDR1 0xFFCC108A /* USB Transmit Hub Address */ -#define USB_TXHUBADDR2 0xFFCC1092 /* USB Transmit Hub Address */ -#define USB_TXHUBADDR3 0xFFCC109A /* USB Transmit Hub Address */ -#define USB_TXHUBADDR4 0xFFCC10A2 /* USB Transmit Hub Address */ -#define USB_TXHUBADDR5 0xFFCC10AA /* USB Transmit Hub Address */ -#define USB_TXHUBADDR6 0xFFCC10B2 /* USB Transmit Hub Address */ -#define USB_TXHUBADDR7 0xFFCC10BA /* USB Transmit Hub Address */ -#define USB_TXHUBADDR8 0xFFCC10C2 /* USB Transmit Hub Address */ -#define USB_TXHUBADDR9 0xFFCC10CA /* USB Transmit Hub Address */ -#define USB_TXHUBADDR10 0xFFCC10D2 /* USB Transmit Hub Address */ -#define USB_TXHUBADDR11 0xFFCC10DA /* USB Transmit Hub Address */ -#define USB_TXHUBPORT0 0xFFCC1083 /* USB Transmit Hub Port */ -#define USB_TXHUBPORT1 0xFFCC108B /* USB Transmit Hub Port */ -#define USB_TXHUBPORT2 0xFFCC1093 /* USB Transmit Hub Port */ -#define USB_TXHUBPORT3 0xFFCC109B /* USB Transmit Hub Port */ -#define USB_TXHUBPORT4 0xFFCC10A3 /* USB Transmit Hub Port */ -#define USB_TXHUBPORT5 0xFFCC10AB /* USB Transmit Hub Port */ -#define USB_TXHUBPORT6 0xFFCC10B3 /* USB Transmit Hub Port */ -#define USB_TXHUBPORT7 0xFFCC10BB /* USB Transmit Hub Port */ -#define USB_TXHUBPORT8 0xFFCC10C3 /* USB Transmit Hub Port */ -#define USB_TXHUBPORT9 0xFFCC10CB /* USB Transmit Hub Port */ -#define USB_TXHUBPORT10 0xFFCC10D3 /* USB Transmit Hub Port */ -#define USB_TXHUBPORT11 0xFFCC10DB /* USB Transmit Hub Port */ -#define USB_RXFUNCADDR0 0xFFCC1084 /* USB Receive Function Address */ -#define USB_RXFUNCADDR1 0xFFCC108C /* USB Receive Function Address */ -#define USB_RXFUNCADDR2 0xFFCC1094 /* USB Receive Function Address */ -#define USB_RXFUNCADDR3 0xFFCC109C /* USB Receive Function Address */ -#define USB_RXFUNCADDR4 0xFFCC10A4 /* USB Receive Function Address */ -#define USB_RXFUNCADDR5 0xFFCC10AC /* USB Receive Function Address */ -#define USB_RXFUNCADDR6 0xFFCC10B4 /* USB Receive Function Address */ -#define USB_RXFUNCADDR7 0xFFCC10BC /* USB Receive Function Address */ -#define USB_RXFUNCADDR8 0xFFCC10C4 /* USB Receive Function Address */ -#define USB_RXFUNCADDR9 0xFFCC10CC /* USB Receive Function Address */ -#define USB_RXFUNCADDR10 0xFFCC10D4 /* USB Receive Function Address */ -#define USB_RXFUNCADDR11 0xFFCC10DC /* USB Receive Function Address */ -#define USB_RXHUBADDR0 0xFFCC1086 /* USB Receive Hub Address */ -#define USB_RXHUBADDR1 0xFFCC108E /* USB Receive Hub Address */ -#define USB_RXHUBADDR2 0xFFCC1096 /* USB Receive Hub Address */ -#define USB_RXHUBADDR3 0xFFCC109E /* USB Receive Hub Address */ -#define USB_RXHUBADDR4 0xFFCC10A6 /* USB Receive Hub Address */ -#define USB_RXHUBADDR5 0xFFCC10AE /* USB Receive Hub Address */ -#define USB_RXHUBADDR6 0xFFCC10B6 /* USB Receive Hub Address */ -#define USB_RXHUBADDR7 0xFFCC10BE /* USB Receive Hub Address */ -#define USB_RXHUBADDR8 0xFFCC10C6 /* USB Receive Hub Address */ -#define USB_RXHUBADDR9 0xFFCC10CE /* USB Receive Hub Address */ -#define USB_RXHUBADDR10 0xFFCC10D6 /* USB Receive Hub Address */ -#define USB_RXHUBADDR11 0xFFCC10DE /* USB Receive Hub Address */ -#define USB_RXHUBPORT0 0xFFCC1087 /* USB Receive Hub Port */ -#define USB_RXHUBPORT1 0xFFCC108F /* USB Receive Hub Port */ -#define USB_RXHUBPORT2 0xFFCC1097 /* USB Receive Hub Port */ -#define USB_RXHUBPORT3 0xFFCC109F /* USB Receive Hub Port */ -#define USB_RXHUBPORT4 0xFFCC10A7 /* USB Receive Hub Port */ -#define USB_RXHUBPORT5 0xFFCC10AF /* USB Receive Hub Port */ -#define USB_RXHUBPORT6 0xFFCC10B7 /* USB Receive Hub Port */ -#define USB_RXHUBPORT7 0xFFCC10BF /* USB Receive Hub Port */ -#define USB_RXHUBPORT8 0xFFCC10C7 /* USB Receive Hub Port */ -#define USB_RXHUBPORT9 0xFFCC10CF /* USB Receive Hub Port */ -#define USB_RXHUBPORT10 0xFFCC10D7 /* USB Receive Hub Port */ -#define USB_RXHUBPORT11 0xFFCC10DF /* USB Receive Hub Port */ -#define USB_EP0_CSR0_H 0xFFCC1102 /* USB Config and Status EP0 */ -#define USB_EP0_CSR0_P 0xFFCC1102 /* USB Config and Status EP0 */ -#define USB_EP0_CNT0 0xFFCC1108 /* USB Number of Received Bytes for Endpoint 0 */ -#define USB_EP0_TYPE0 0xFFCC110A /* USB Speed for Endpoint 0 */ -#define USB_EP0_NAKLIMIT0 0xFFCC110B /* USB NAK Response Timeout for Endpoint 0 */ -#define USB_EP0_CFGDATA0 0xFFCC110F /* USB Configuration Information */ -#define USB_EP_TXMAXP0 0xFFCC1110 /* USB Transmit Maximum Packet Length */ -#define USB_EP_TXMAXP1 0xFFCC1120 /* USB Transmit Maximum Packet Length */ -#define USB_EP_TXMAXP2 0xFFCC1130 /* USB Transmit Maximum Packet Length */ -#define USB_EP_TXMAXP3 0xFFCC1140 /* USB Transmit Maximum Packet Length */ -#define USB_EP_TXMAXP4 0xFFCC1150 /* USB Transmit Maximum Packet Length */ -#define USB_EP_TXMAXP5 0xFFCC1160 /* USB Transmit Maximum Packet Length */ -#define USB_EP_TXMAXP6 0xFFCC1170 /* USB Transmit Maximum Packet Length */ -#define USB_EP_TXMAXP7 0xFFCC1180 /* USB Transmit Maximum Packet Length */ -#define USB_EP_TXMAXP8 0xFFCC1190 /* USB Transmit Maximum Packet Length */ -#define USB_EP_TXMAXP9 0xFFCC11A0 /* USB Transmit Maximum Packet Length */ -#define USB_EP_TXMAXP10 0xFFCC11B0 /* USB Transmit Maximum Packet Length */ -#define USB_EP_TXCSR0_H 0xFFCC1112 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR1_H 0xFFCC1122 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR2_H 0xFFCC1132 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR3_H 0xFFCC1142 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR4_H 0xFFCC1152 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR5_H 0xFFCC1162 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR6_H 0xFFCC1172 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR7_H 0xFFCC1182 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR8_H 0xFFCC1192 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR9_H 0xFFCC11A2 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR10_H 0xFFCC11B2 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR0_P 0xFFCC1112 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR1_P 0xFFCC1122 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR2_P 0xFFCC1132 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR3_P 0xFFCC1142 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR4_P 0xFFCC1152 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR5_P 0xFFCC1162 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR6_P 0xFFCC1172 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR7_P 0xFFCC1182 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR8_P 0xFFCC1192 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR9_P 0xFFCC11A2 /* USB Transmit Configuration and Status */ -#define USB_EP_TXCSR10_P 0xFFCC11B2 /* USB Transmit Configuration and Status */ -#define USB_EP_RXMAXP0 0xFFCC1114 /* USB Receive Maximum Packet Length */ -#define USB_EP_RXMAXP1 0xFFCC1124 /* USB Receive Maximum Packet Length */ -#define USB_EP_RXMAXP2 0xFFCC1134 /* USB Receive Maximum Packet Length */ -#define USB_EP_RXMAXP3 0xFFCC1144 /* USB Receive Maximum Packet Length */ -#define USB_EP_RXMAXP4 0xFFCC1154 /* USB Receive Maximum Packet Length */ -#define USB_EP_RXMAXP5 0xFFCC1164 /* USB Receive Maximum Packet Length */ -#define USB_EP_RXMAXP6 0xFFCC1174 /* USB Receive Maximum Packet Length */ -#define USB_EP_RXMAXP7 0xFFCC1184 /* USB Receive Maximum Packet Length */ -#define USB_EP_RXMAXP8 0xFFCC1194 /* USB Receive Maximum Packet Length */ -#define USB_EP_RXMAXP9 0xFFCC11A4 /* USB Receive Maximum Packet Length */ -#define USB_EP_RXMAXP10 0xFFCC11B4 /* USB Receive Maximum Packet Length */ -#define USB_EP_RXCSR0_H 0xFFCC1116 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR1_H 0xFFCC1126 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR2_H 0xFFCC1136 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR3_H 0xFFCC1146 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR4_H 0xFFCC1156 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR5_H 0xFFCC1166 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR6_H 0xFFCC1176 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR7_H 0xFFCC1186 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR8_H 0xFFCC1196 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR9_H 0xFFCC11A6 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR10_H 0xFFCC11B6 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR0_P 0xFFCC1116 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR1_P 0xFFCC1126 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR2_P 0xFFCC1136 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR3_P 0xFFCC1146 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR4_P 0xFFCC1156 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR5_P 0xFFCC1166 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR6_P 0xFFCC1176 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR7_P 0xFFCC1186 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR8_P 0xFFCC1196 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR9_P 0xFFCC11A6 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCSR10_P 0xFFCC11B6 /* USB Receive Configuration and Status Register */ -#define USB_EP_RXCNT0 0xFFCC1118 /* USB Number of Byte Received */ -#define USB_EP_RXCNT1 0xFFCC1128 /* USB Number of Byte Received */ -#define USB_EP_RXCNT2 0xFFCC1138 /* USB Number of Byte Received */ -#define USB_EP_RXCNT3 0xFFCC1148 /* USB Number of Byte Received */ -#define USB_EP_RXCNT4 0xFFCC1158 /* USB Number of Byte Received */ -#define USB_EP_RXCNT5 0xFFCC1168 /* USB Number of Byte Received */ -#define USB_EP_RXCNT6 0xFFCC1178 /* USB Number of Byte Received */ -#define USB_EP_RXCNT7 0xFFCC1188 /* USB Number of Byte Received */ -#define USB_EP_RXCNT8 0xFFCC1198 /* USB Number of Byte Received */ -#define USB_EP_RXCNT9 0xFFCC11A8 /* USB Number of Byte Received */ -#define USB_EP_RXCNT10 0xFFCC11B8 /* USB Number of Byte Received */ -#define USB_EP_TXTYPE0 0xFFCC111A /* USB Transmit Type */ -#define USB_EP_TXTYPE1 0xFFCC112A /* USB Transmit Type */ -#define USB_EP_TXTYPE2 0xFFCC113A /* USB Transmit Type */ -#define USB_EP_TXTYPE3 0xFFCC114A /* USB Transmit Type */ -#define USB_EP_TXTYPE4 0xFFCC115A /* USB Transmit Type */ -#define USB_EP_TXTYPE5 0xFFCC116A /* USB Transmit Type */ -#define USB_EP_TXTYPE6 0xFFCC117A /* USB Transmit Type */ -#define USB_EP_TXTYPE7 0xFFCC118A /* USB Transmit Type */ -#define USB_EP_TXTYPE8 0xFFCC119A /* USB Transmit Type */ -#define USB_EP_TXTYPE9 0xFFCC11AA /* USB Transmit Type */ -#define USB_EP_TXTYPE10 0xFFCC11BA /* USB Transmit Type */ -#define USB_EP_TXINTERVAL0 0xFFCC111B /* USB Transmit Polling Interval */ -#define USB_EP_TXINTERVAL1 0xFFCC112B /* USB Transmit Polling Interval */ -#define USB_EP_TXINTERVAL2 0xFFCC113B /* USB Transmit Polling Interval */ -#define USB_EP_TXINTERVAL3 0xFFCC114B /* USB Transmit Polling Interval */ -#define USB_EP_TXINTERVAL4 0xFFCC115B /* USB Transmit Polling Interval */ -#define USB_EP_TXINTERVAL5 0xFFCC116B /* USB Transmit Polling Interval */ -#define USB_EP_TXINTERVAL6 0xFFCC117B /* USB Transmit Polling Interval */ -#define USB_EP_TXINTERVAL7 0xFFCC118B /* USB Transmit Polling Interval */ -#define USB_EP_TXINTERVAL8 0xFFCC119B /* USB Transmit Polling Interval */ -#define USB_EP_TXINTERVAL9 0xFFCC11AB /* USB Transmit Polling Interval */ -#define USB_EP_TXINTERVAL10 0xFFCC11BB /* USB Transmit Polling Interval */ -#define USB_EP_RXTYPE0 0xFFCC111C /* USB Receive Type */ -#define USB_EP_RXTYPE1 0xFFCC112C /* USB Receive Type */ -#define USB_EP_RXTYPE2 0xFFCC113C /* USB Receive Type */ -#define USB_EP_RXTYPE3 0xFFCC114C /* USB Receive Type */ -#define USB_EP_RXTYPE4 0xFFCC115C /* USB Receive Type */ -#define USB_EP_RXTYPE5 0xFFCC116C /* USB Receive Type */ -#define USB_EP_RXTYPE6 0xFFCC117C /* USB Receive Type */ -#define USB_EP_RXTYPE7 0xFFCC118C /* USB Receive Type */ -#define USB_EP_RXTYPE8 0xFFCC119C /* USB Receive Type */ -#define USB_EP_RXTYPE9 0xFFCC11AC /* USB Receive Type */ -#define USB_EP_RXTYPE10 0xFFCC11BC /* USB Receive Type */ -#define USB_EP_RXINTERVAL0 0xFFCC111D /* USB Receive Polling Interval */ -#define USB_EP_RXINTERVAL1 0xFFCC112D /* USB Receive Polling Interval */ -#define USB_EP_RXINTERVAL2 0xFFCC113D /* USB Receive Polling Interval */ -#define USB_EP_RXINTERVAL3 0xFFCC114D /* USB Receive Polling Interval */ -#define USB_EP_RXINTERVAL4 0xFFCC115D /* USB Receive Polling Interval */ -#define USB_EP_RXINTERVAL5 0xFFCC116D /* USB Receive Polling Interval */ -#define USB_EP_RXINTERVAL6 0xFFCC117D /* USB Receive Polling Interval */ -#define USB_EP_RXINTERVAL7 0xFFCC118D /* USB Receive Polling Interval */ -#define USB_EP_RXINTERVAL8 0xFFCC119D /* USB Receive Polling Interval */ -#define USB_EP_RXINTERVAL9 0xFFCC11AD /* USB Receive Polling Interval */ -#define USB_EP_RXINTERVAL10 0xFFCC11BD /* USB Receive Polling Interval */ -#define USB_DMA_IRQ 0xFFCC1200 /* USB Interrupt Register */ -#define USB_DMA_CTL0 0xFFCC1204 /* USB DMA Control */ -#define USB_DMA_CTL1 0xFFCC1214 /* USB DMA Control */ -#define USB_DMA_CTL2 0xFFCC1224 /* USB DMA Control */ -#define USB_DMA_CTL3 0xFFCC1234 /* USB DMA Control */ -#define USB_DMA_CTL4 0xFFCC1244 /* USB DMA Control */ -#define USB_DMA_CTL5 0xFFCC1254 /* USB DMA Control */ -#define USB_DMA_CTL6 0xFFCC1264 /* USB DMA Control */ -#define USB_DMA_CTL7 0xFFCC1274 /* USB DMA Control */ -#define USB_DMA_ADDR0 0xFFCC1208 /* USB DMA Address */ -#define USB_DMA_ADDR1 0xFFCC1218 /* USB DMA Address */ -#define USB_DMA_ADDR2 0xFFCC1228 /* USB DMA Address */ -#define USB_DMA_ADDR3 0xFFCC1238 /* USB DMA Address */ -#define USB_DMA_ADDR4 0xFFCC1248 /* USB DMA Address */ -#define USB_DMA_ADDR5 0xFFCC1258 /* USB DMA Address */ -#define USB_DMA_ADDR6 0xFFCC1268 /* USB DMA Address */ -#define USB_DMA_ADDR7 0xFFCC1278 /* USB DMA Address */ -#define USB_DMA_CNT0 0xFFCC120C /* USB DMA Count */ -#define USB_DMA_CNT1 0xFFCC121C /* USB DMA Count */ -#define USB_DMA_CNT2 0xFFCC122C /* USB DMA Count */ -#define USB_DMA_CNT3 0xFFCC123C /* USB DMA Count */ -#define USB_DMA_CNT4 0xFFCC124C /* USB DMA Count */ -#define USB_DMA_CNT5 0xFFCC125C /* USB DMA Count */ -#define USB_DMA_CNT6 0xFFCC126C /* USB DMA Count */ -#define USB_DMA_CNT7 0xFFCC127C /* USB DMA Count */ -#define USB_RQPKTCNT0 0xFFCC1300 /* USB Request Packet Count */ -#define USB_RQPKTCNT1 0xFFCC1304 /* USB Request Packet Count */ -#define USB_RQPKTCNT2 0xFFCC1308 /* USB Request Packet Count */ -#define USB_RQPKTCNT3 0xFFCC130C /* USB Request Packet Count */ -#define USB_RQPKTCNT4 0xFFCC1310 /* USB Request Packet Count */ -#define USB_RQPKTCNT5 0xFFCC1314 /* USB Request Packet Count */ -#define USB_RQPKTCNT6 0xFFCC1318 /* USB Request Packet Count */ -#define USB_RQPKTCNT7 0xFFCC131C /* USB Request Packet Count */ -#define USB_RQPKTCNT8 0xFFCC1320 /* USB Request Packet Count */ -#define USB_RQPKTCNT9 0xFFCC1324 /* USB Request Packet Count */ -#define USB_RQPKTCNT10 0xFFCC1328 /* USB Request Packet Count */ -#define USB_CT_UCH 0xFFCC1344 /* USB Chirp Timeout */ -#define USB_CT_HHSRTN 0xFFCC1346 /* USB High Speed Resume Return to Normal */ -#define USB_CT_HSBT 0xFFCC1348 /* USB High Speed Timeout */ -#define USB_LPM_ATTR 0xFFCC1360 /* USB LPM Attribute */ -#define USB_LPM_CTL 0xFFCC1362 /* USB LPM Control */ -#define USB_LPM_IEN 0xFFCC1363 /* USB LPM Interrupt Enable */ -#define USB_LPM_IRQ 0xFFCC1364 /* USB LPM Interrupt */ -#define USB_LPM_FADDR 0xFFCC1365 /* USB LPM Function Address */ -#define USB_VBUS_CTL 0xFFCC1380 /* USB VBus Control */ -#define USB_BAT_CHG 0xFFCC1381 /* USB Battery Charging */ -#define USB_PHY_CTL 0xFFCC1394 /* USB PHY Control */ -#define USB_TESTCTL 0xFFCC1397 /* USB Test Control */ -#define USB_PLL_OSC 0xFFCC1398 /* USB PLL and Oscillator Control */ - - - -/* ========================= - CHIPID - ========================= */ - -#define CHIPID 0xffc00014 -/* CHIPID Masks */ -#define CHIPID_VERSION 0xF0000000 -#define CHIPID_FAMILY 0x0FFFF000 -#define CHIPID_MANUFACTURE 0x00000FFE - - -#endif /* _DEF_BF60X_H */ diff --git a/trunk/arch/blackfin/mach-bf609/include/mach/dma.h b/trunk/arch/blackfin/mach-bf609/include/mach/dma.h deleted file mode 100644 index 872d141ca119..000000000000 --- a/trunk/arch/blackfin/mach-bf609/include/mach/dma.h +++ /dev/null @@ -1,116 +0,0 @@ -/* mach/dma.h - arch-specific DMA defines - * - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#ifndef _MACH_DMA_H_ -#define _MACH_DMA_H_ - -#define CH_SPORT0_TX 0 -#define CH_SPORT0_RX 1 -#define CH_SPORT1_TX 2 -#define CH_SPORT1_RX 3 -#define CH_SPORT2_TX 4 -#define CH_SPORT2_RX 5 -#define CH_SPI0_TX 6 -#define CH_SPI0_RX 7 -#define CH_SPI1_TX 8 -#define CH_SPI1_RX 9 -#define CH_RSI 10 -#define CH_SDU 11 -#define CH_LP0 13 -#define CH_LP1 14 -#define CH_LP2 15 -#define CH_LP3 16 -#define CH_UART0_TX 17 -#define CH_UART0_RX 18 -#define CH_UART1_TX 19 -#define CH_UART1_RX 20 -#define CH_MEM_STREAM0_SRC_CRC0 21 -#define CH_MEM_STREAM0_SRC CH_MEM_STREAM0_SRC_CRC0 -#define CH_MEM_STREAM0_DEST_CRC0 22 -#define CH_MEM_STREAM0_DEST CH_MEM_STREAM0_DEST_CRC0 -#define CH_MEM_STREAM1_SRC_CRC1 23 -#define CH_MEM_STREAM1_SRC CH_MEM_STREAM1_SRC_CRC1 -#define CH_MEM_STREAM1_DEST_CRC1 24 -#define CH_MEM_STREAM1_DEST CH_MEM_STREAM1_DEST_CRC1 -#define CH_MEM_STREAM2_SRC 25 -#define CH_MEM_STREAM2_DEST 26 -#define CH_MEM_STREAM3_SRC 27 -#define CH_MEM_STREAM3_DEST 28 -#define CH_EPPI0_CH0 29 -#define CH_EPPI0_CH1 30 -#define CH_EPPI1_CH0 31 -#define CH_EPPI1_CH1 32 -#define CH_EPPI2_CH0 33 -#define CH_EPPI2_CH1 34 -#define CH_PIXC_CH0 35 -#define CH_PIXC_CH1 36 -#define CH_PIXC_CH2 37 -#define CH_PVP_CPDOB 38 -#define CH_PVP_CPDOC 39 -#define CH_PVP_CPSTAT 40 -#define CH_PVP_CPCI 41 -#define CH_PVP_MPDO 42 -#define CH_PVP_MPDI 43 -#define CH_PVP_MPSTAT 44 -#define CH_PVP_MPCI 45 -#define CH_PVP_CPDOA 46 - -#define MAX_DMA_CHANNELS 47 -#define MAX_DMA_SUSPEND_CHANNELS 0 -#define DMA_MMR_SIZE_32 - -#define bfin_read_MDMA_S0_CONFIG bfin_read_MDMA0_SRC_CRC0_CONFIG -#define bfin_write_MDMA_S0_CONFIG bfin_write_MDMA0_SRC_CRC0_CONFIG -#define bfin_read_MDMA_S0_IRQ_STATUS bfin_read_MDMA0_SRC_CRC0_IRQ_STATUS -#define bfin_write_MDMA_S0_IRQ_STATUS bfin_write_MDMA0_SRC_CRC0_IRQ_STATUS -#define bfin_write_MDMA_S0_START_ADDR bfin_write_MDMA0_SRC_CRC0_START_ADDR -#define bfin_write_MDMA_S0_X_COUNT bfin_write_MDMA0_SRC_CRC0_X_COUNT -#define bfin_write_MDMA_S0_X_MODIFY bfin_write_MDMA0_SRC_CRC0_X_MODIFY -#define bfin_write_MDMA_S0_Y_COUNT bfin_write_MDMA0_SRC_CRC0_Y_COUNT -#define bfin_write_MDMA_S0_Y_MODIFY bfin_write_MDMA0_SRC_CRC0_Y_MODIFY -#define bfin_read_MDMA_D0_CONFIG bfin_read_MDMA0_DEST_CRC0_CONFIG -#define bfin_write_MDMA_D0_CONFIG bfin_write_MDMA0_DEST_CRC0_CONFIG -#define bfin_read_MDMA_D0_IRQ_STATUS bfin_read_MDMA0_DEST_CRC0_IRQ_STATUS -#define bfin_write_MDMA_D0_IRQ_STATUS bfin_write_MDMA0_DEST_CRC0_IRQ_STATUS -#define bfin_write_MDMA_D0_START_ADDR bfin_write_MDMA0_DEST_CRC0_START_ADDR -#define bfin_write_MDMA_D0_X_COUNT bfin_write_MDMA0_DEST_CRC0_X_COUNT -#define bfin_write_MDMA_D0_X_MODIFY bfin_write_MDMA0_DEST_CRC0_X_MODIFY -#define bfin_write_MDMA_D0_Y_COUNT bfin_write_MDMA0_DEST_CRC0_Y_COUNT -#define bfin_write_MDMA_D0_Y_MODIFY bfin_write_MDMA0_DEST_CRC0_Y_MODIFY - -#define bfin_read_MDMA_S1_CONFIG bfin_read_MDMA1_SRC_CRC1_CONFIG -#define bfin_write_MDMA_S1_CONFIG bfin_write_MDMA1_SRC_CRC1_CONFIG -#define bfin_read_MDMA_D1_CONFIG bfin_read_MDMA1_DEST_CRC1_CONFIG -#define bfin_write_MDMA_D1_CONFIG bfin_write_MDMA1_DEST_CRC1_CONFIG -#define bfin_read_MDMA_D1_IRQ_STATUS bfin_read_MDMA1_DEST_CRC1_IRQ_STATUS -#define bfin_write_MDMA_D1_IRQ_STATUS bfin_write_MDMA1_DEST_CRC1_IRQ_STATUS - -#define bfin_read_MDMA_S3_CONFIG bfin_read_MDMA3_SRC_CONFIG -#define bfin_write_MDMA_S3_CONFIG bfin_write_MDMA3_SRC_CONFIG -#define bfin_read_MDMA_S3_IRQ_STATUS bfin_read_MDMA3_SRC_IRQ_STATUS -#define bfin_write_MDMA_S3_IRQ_STATUS bfin_write_MDMA3_SRC_IRQ_STATUS -#define bfin_write_MDMA_S3_START_ADDR bfin_write_MDMA3_SRC_START_ADDR -#define bfin_write_MDMA_S3_X_COUNT bfin_write_MDMA3_SRC_X_COUNT -#define bfin_write_MDMA_S3_X_MODIFY bfin_write_MDMA3_SRC_X_MODIFY -#define bfin_write_MDMA_S3_Y_COUNT bfin_write_MDMA3_SRC_Y_COUNT -#define bfin_write_MDMA_S3_Y_MODIFY bfin_write_MDMA3_SRC_Y_MODIFY -#define bfin_read_MDMA_D3_CONFIG bfin_read_MDMA3_DEST_CONFIG -#define bfin_write_MDMA_D3_CONFIG bfin_write_MDMA3_DEST_CONFIG -#define bfin_read_MDMA_D3_IRQ_STATUS bfin_read_MDMA3_DEST_IRQ_STATUS -#define bfin_write_MDMA_D3_IRQ_STATUS bfin_write_MDMA3_DEST_IRQ_STATUS -#define bfin_write_MDMA_D3_START_ADDR bfin_write_MDMA3_DEST_START_ADDR -#define bfin_write_MDMA_D3_X_COUNT bfin_write_MDMA3_DEST_X_COUNT -#define bfin_write_MDMA_D3_X_MODIFY bfin_write_MDMA3_DEST_X_MODIFY -#define bfin_write_MDMA_D3_Y_COUNT bfin_write_MDMA3_DEST_Y_COUNT -#define bfin_write_MDMA_D3_Y_MODIFY bfin_write_MDMA3_DEST_Y_MODIFY - -#define MDMA_S0_NEXT_DESC_PTR MDMA0_SRC_CRC0_NEXT_DESC_PTR -#define MDMA_D0_NEXT_DESC_PTR MDMA0_DEST_CRC0_NEXT_DESC_PTR -#define MDMA_S1_NEXT_DESC_PTR MDMA1_SRC_CRC1_NEXT_DESC_PTR -#define MDMA_D1_NEXT_DESC_PTR MDMA1_DEST_CRC1_NEXT_DESC_PTR - -#endif diff --git a/trunk/arch/blackfin/mach-bf609/include/mach/gpio.h b/trunk/arch/blackfin/mach-bf609/include/mach/gpio.h deleted file mode 100644 index 127586b1e04a..000000000000 --- a/trunk/arch/blackfin/mach-bf609/include/mach/gpio.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2007-2009 Analog Devices Inc. - * Licensed under the GPL-2 or later. - */ - -#ifndef _MACH_GPIO_H_ -#define _MACH_GPIO_H_ - -#define MAX_BLACKFIN_GPIOS 112 - -#define GPIO_PA0 0 -#define GPIO_PA1 1 -#define GPIO_PA2 2 -#define GPIO_PA3 3 -#define GPIO_PA4 4 -#define GPIO_PA5 5 -#define GPIO_PA6 6 -#define GPIO_PA7 7 -#define GPIO_PA8 8 -#define GPIO_PA9 9 -#define GPIO_PA10 10 -#define GPIO_PA11 11 -#define GPIO_PA12 12 -#define GPIO_PA13 13 -#define GPIO_PA14 14 -#define GPIO_PA15 15 -#define GPIO_PB0 16 -#define GPIO_PB1 17 -#define GPIO_PB2 18 -#define GPIO_PB3 19 -#define GPIO_PB4 20 -#define GPIO_PB5 21 -#define GPIO_PB6 22 -#define GPIO_PB7 23 -#define GPIO_PB8 24 -#define GPIO_PB9 25 -#define GPIO_PB10 26 -#define GPIO_PB11 27 -#define GPIO_PB12 28 -#define GPIO_PB13 29 -#define GPIO_PB14 30 -#define GPIO_PB15 31 -#define GPIO_PC0 32 -#define GPIO_PC1 33 -#define GPIO_PC2 34 -#define GPIO_PC3 35 -#define GPIO_PC4 36 -#define GPIO_PC5 37 -#define GPIO_PC6 38 -#define GPIO_PC7 39 -#define GPIO_PC8 40 -#define GPIO_PC9 41 -#define GPIO_PC10 42 -#define GPIO_PC11 43 -#define GPIO_PC12 44 -#define GPIO_PC13 45 -#define GPIO_PC14 46 -#define GPIO_PC15 47 -#define GPIO_PD0 48 -#define GPIO_PD1 49 -#define GPIO_PD2 50 -#define GPIO_PD3 51 -#define GPIO_PD4 52 -#define GPIO_PD5 53 -#define GPIO_PD6 54 -#define GPIO_PD7 55 -#define GPIO_PD8 56 -#define GPIO_PD9 57 -#define GPIO_PD10 58 -#define GPIO_PD11 59 -#define GPIO_PD12 60 -#define GPIO_PD13 61 -#define GPIO_PD14 62 -#define GPIO_PD15 63 -#define GPIO_PE0 64 -#define GPIO_PE1 65 -#define GPIO_PE2 66 -#define GPIO_PE3 67 -#define GPIO_PE4 68 -#define GPIO_PE5 69 -#define GPIO_PE6 70 -#define GPIO_PE7 71 -#define GPIO_PE8 72 -#define GPIO_PE9 73 -#define GPIO_PE10 74 -#define GPIO_PE11 75 -#define GPIO_PE12 76 -#define GPIO_PE13 77 -#define GPIO_PE14 78 -#define GPIO_PE15 79 -#define GPIO_PF0 80 -#define GPIO_PF1 81 -#define GPIO_PF2 82 -#define GPIO_PF3 83 -#define GPIO_PF4 84 -#define GPIO_PF5 85 -#define GPIO_PF6 86 -#define GPIO_PF7 87 -#define GPIO_PF8 88 -#define GPIO_PF9 89 -#define GPIO_PF10 90 -#define GPIO_PF11 91 -#define GPIO_PF12 92 -#define GPIO_PF13 93 -#define GPIO_PF14 94 -#define GPIO_PF15 95 -#define GPIO_PG0 96 -#define GPIO_PG1 97 -#define GPIO_PG2 98 -#define GPIO_PG3 99 -#define GPIO_PG4 100 -#define GPIO_PG5 101 -#define GPIO_PG6 102 -#define GPIO_PG7 103 -#define GPIO_PG8 104 -#define GPIO_PG9 105 -#define GPIO_PG10 106 -#define GPIO_PG11 107 -#define GPIO_PG12 108 -#define GPIO_PG13 109 -#define GPIO_PG14 110 -#define GPIO_PG15 111 - - -#define BFIN_GPIO_PINT 1 - - -#ifndef __ASSEMBLY__ - -struct gpio_port_t { - unsigned long port_fer; - unsigned long port_fer_set; - unsigned long port_fer_clear; - unsigned long data; - unsigned long data_set; - unsigned long data_clear; - unsigned long dir; - unsigned long dir_set; - unsigned long dir_clear; - unsigned long inen; - unsigned long inen_set; - unsigned long inen_clear; - unsigned long port_mux; - unsigned long toggle; - unsigned long polar; - unsigned long polar_set; - unsigned long polar_clear; - unsigned long lock; - unsigned long spare; - unsigned long revid; -}; - -struct gpio_port_s { - unsigned short fer; - unsigned short data; - unsigned short dir; - unsigned short inen; - unsigned int mux; -}; - -#endif - -#include -#include -#include -#include -#include -#include -#include - -#endif /* _MACH_GPIO_H_ */ diff --git a/trunk/arch/blackfin/mach-bf609/include/mach/irq.h b/trunk/arch/blackfin/mach-bf609/include/mach/irq.h deleted file mode 100644 index 0004552433b2..000000000000 --- a/trunk/arch/blackfin/mach-bf609/include/mach/irq.h +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#ifndef _BF60x_IRQ_H_ -#define _BF60x_IRQ_H_ - -#include - -#undef BFIN_IRQ -#define BFIN_IRQ(x) ((x) + IVG15) - -#define NR_PERI_INTS (5 * 32) - -#define IRQ_SEC_ERR BFIN_IRQ(0) /* SEC Error */ -#define IRQ_CGU_EVT BFIN_IRQ(1) /* CGU Event */ -#define IRQ_WATCH0 BFIN_IRQ(2) /* Watchdog0 Interrupt */ -#define IRQ_WATCH1 BFIN_IRQ(3) /* Watchdog1 Interrupt */ -#define IRQ_L2CTL0_ECC_ERR BFIN_IRQ(4) /* L2 ECC Error */ -#define IRQ_L2CTL0_ECC_WARN BFIN_IRQ(5) /* L2 ECC Waring */ -#define IRQ_C0_DBL_FAULT BFIN_IRQ(6) /* Core 0 Double Fault */ -#define IRQ_C1_DBL_FAULT BFIN_IRQ(7) /* Core 1 Double Fault */ -#define IRQ_C0_HW_ERR BFIN_IRQ(8) /* Core 0 Hardware Error */ -#define IRQ_C1_HW_ERR BFIN_IRQ(9) /* Core 1 Hardware Error */ -#define IRQ_C0_NMI_L1_PARITY_ERR BFIN_IRQ(10) /* Core 0 Unhandled NMI or L1 Memory Parity Error */ -#define IRQ_C1_NMI_L1_PARITY_ERR BFIN_IRQ(11) /* Core 1 Unhandled NMI or L1 Memory Parity Error */ -#define CORE_IRQS (IRQ_C1_NMI_L1_PARITY_ERR + 1) - -#define IRQ_TIMER0 BFIN_IRQ(12) /* Timer 0 Interrupt */ -#define IRQ_TIMER1 BFIN_IRQ(13) /* Timer 1 Interrupt */ -#define IRQ_TIMER2 BFIN_IRQ(14) /* Timer 2 Interrupt */ -#define IRQ_TIMER3 BFIN_IRQ(15) /* Timer 3 Interrupt */ -#define IRQ_TIMER4 BFIN_IRQ(16) /* Timer 4 Interrupt */ -#define IRQ_TIMER5 BFIN_IRQ(17) /* Timer 5 Interrupt */ -#define IRQ_TIMER6 BFIN_IRQ(18) /* Timer 6 Interrupt */ -#define IRQ_TIMER7 BFIN_IRQ(19) /* Timer 7 Interrupt */ -#define IRQ_TIMER_STAT BFIN_IRQ(20) /* Timer Block Status */ -#define IRQ_PINT0 BFIN_IRQ(21) /* PINT0 Interrupt */ -#define IRQ_PINT1 BFIN_IRQ(22) /* PINT1 Interrupt */ -#define IRQ_PINT2 BFIN_IRQ(23) /* PINT2 Interrupt */ -#define IRQ_PINT3 BFIN_IRQ(24) /* PINT3 Interrupt */ -#define IRQ_PINT4 BFIN_IRQ(25) /* PINT4 Interrupt */ -#define IRQ_PINT5 BFIN_IRQ(26) /* PINT5 Interrupt */ -#define IRQ_CNT BFIN_IRQ(27) /* CNT Interrupt */ -#define IRQ_PWM0_TRIP BFIN_IRQ(28) /* PWM0 Trip Interrupt */ -#define IRQ_PWM0_SYNC BFIN_IRQ(29) /* PWM0 Sync Interrupt */ -#define IRQ_PWM1_TRIP BFIN_IRQ(30) /* PWM1 Trip Interrupt */ -#define IRQ_PWM1_SYNC BFIN_IRQ(31) /* PWM1 Sync Interrupt */ -#define IRQ_TWI0 BFIN_IRQ(32) /* TWI0 Interrupt */ -#define IRQ_TWI1 BFIN_IRQ(33) /* TWI1 Interrupt */ -#define IRQ_SOFT0 BFIN_IRQ(34) /* Software-Driven Interrupt 0 */ -#define IRQ_SOFT1 BFIN_IRQ(35) /* Software-Driven Interrupt 1 */ -#define IRQ_SOFT2 BFIN_IRQ(36) /* Software-Driven Interrupt 2 */ -#define IRQ_SOFT3 BFIN_IRQ(37) /* Software-Driven Interrupt 3 */ -#define IRQ_ACM_EVT_MISS BFIN_IRQ(38) /* ACM Event Miss */ -#define IRQ_ACM_EVT_COMPLETE BFIN_IRQ(39) /* ACM Event Complete */ -#define IRQ_CAN0_RX BFIN_IRQ(40) /* CAN0 Receive Interrupt */ -#define IRQ_CAN0_TX BFIN_IRQ(41) /* CAN0 Transmit Interrupt */ -#define IRQ_CAN0_STAT BFIN_IRQ(42) /* CAN0 Status */ -#define IRQ_SPORT0_TX BFIN_IRQ(43) /* SPORT0 TX Interrupt (DMA0) */ -#define IRQ_SPORT0_TX_STAT BFIN_IRQ(44) /* SPORT0 TX Status Interrupt */ -#define IRQ_SPORT0_RX BFIN_IRQ(45) /* SPORT0 RX Interrupt (DMA1) */ -#define IRQ_SPORT0_RX_STAT BFIN_IRQ(46) /* SPORT0 RX Status Interrupt */ -#define IRQ_SPORT1_TX BFIN_IRQ(47) /* SPORT1 TX Interrupt (DMA2) */ -#define IRQ_SPORT1_TX_STAT BFIN_IRQ(48) /* SPORT1 TX Status Interrupt */ -#define IRQ_SPORT1_RX BFIN_IRQ(49) /* SPORT1 RX Interrupt (DMA3) */ -#define IRQ_SPORT1_RX_STAT BFIN_IRQ(50) /* SPORT1 RX Status Interrupt */ -#define IRQ_SPORT2_TX BFIN_IRQ(51) /* SPORT2 TX Interrupt (DMA4) */ -#define IRQ_SPORT2_TX_STAT BFIN_IRQ(52) /* SPORT2 TX Status Interrupt */ -#define IRQ_SPORT2_RX BFIN_IRQ(53) /* SPORT2 RX Interrupt (DMA5) */ -#define IRQ_SPORT2_RX_STAT BFIN_IRQ(54) /* SPORT2 RX Status Interrupt */ -#define IRQ_SPI0_TX BFIN_IRQ(55) /* SPI0 TX Interrupt (DMA6) */ -#define IRQ_SPI0_RX BFIN_IRQ(56) /* SPI0 RX Interrupt (DMA7) */ -#define IRQ_SPI0_STAT BFIN_IRQ(57) /* SPI0 Status Interrupt */ -#define IRQ_SPI1_TX BFIN_IRQ(58) /* SPI1 TX Interrupt (DMA8) */ -#define IRQ_SPI1_RX BFIN_IRQ(59) /* SPI1 RX Interrupt (DMA9) */ -#define IRQ_SPI1_STAT BFIN_IRQ(60) /* SPI1 Status Interrupt */ -#define IRQ_RSI BFIN_IRQ(61) /* RSI (DMA10) Interrupt */ -#define IRQ_RSI_INT0 BFIN_IRQ(62) /* RSI Interrupt0 */ -#define IRQ_RSI_INT1 BFIN_IRQ(63) /* RSI Interrupt1 */ -#define IRQ_SDU BFIN_IRQ(64) /* DMA11 Data (SDU) */ -/* -- RESERVED -- 65 DMA12 Data (Reserved) */ -/* -- RESERVED -- 66 Reserved */ -/* -- RESERVED -- 67 Reserved */ -#define IRQ_EMAC0_STAT BFIN_IRQ(68) /* EMAC0 Status */ -/* -- RESERVED -- 69 EMAC0 Power (Reserved) */ -#define IRQ_EMAC1_STAT BFIN_IRQ(70) /* EMAC1 Status */ -/* -- RESERVED -- 71 EMAC1 Power (Reserved) */ -#define IRQ_LP0 BFIN_IRQ(72) /* DMA13 Data (Link Port 0) */ -#define IRQ_LP0_STAT BFIN_IRQ(73) /* Link Port 0 Status */ -#define IRQ_LP1 BFIN_IRQ(74) /* DMA14 Data (Link Port 1) */ -#define IRQ_LP1_STAT BFIN_IRQ(75) /* Link Port 1 Status */ -#define IRQ_LP2 BFIN_IRQ(76) /* DMA15 Data (Link Port 2) */ -#define IRQ_LP2_STAT BFIN_IRQ(77) /* Link Port 2 Status */ -#define IRQ_LP3 BFIN_IRQ(78) /* DMA16 Data(Link Port 3) */ -#define IRQ_LP3_STAT BFIN_IRQ(79) /* Link Port 3 Status */ -#define IRQ_UART0_TX BFIN_IRQ(80) /* UART0 TX Interrupt (DMA17) */ -#define IRQ_UART0_RX BFIN_IRQ(81) /* UART0 RX Interrupt (DMA18) */ -#define IRQ_UART0_STAT BFIN_IRQ(82) /* UART0 Status(Error) Interrupt */ -#define IRQ_UART1_TX BFIN_IRQ(83) /* UART1 TX Interrupt (DMA19) */ -#define IRQ_UART1_RX BFIN_IRQ(84) /* UART1 RX Interrupt (DMA20) */ -#define IRQ_UART1_STAT BFIN_IRQ(85) /* UART1 Status(Error) Interrupt */ -#define IRQ_MDMA0_SRC_CRC0 BFIN_IRQ(86) /* DMA21 Data (MDMA Stream 0 Source/CRC0 Input Channel) */ -#define IRQ_MDMA0_DEST_CRC0 BFIN_IRQ(87) /* DMA22 Data (MDMA Stream 0 Destination/CRC0 Output Channel) */ -#define IRQ_MDMAS0 IRQ_MDMA0_DEST_CRC0 -#define IRQ_CRC0_DCNTEXP BFIN_IRQ(88) /* CRC0 DATACOUNT Expiration */ -#define IRQ_CRC0_ERR BFIN_IRQ(89) /* CRC0 Error */ -#define IRQ_MDMA1_SRC_CRC1 BFIN_IRQ(90) /* DMA23 Data (MDMA Stream 1 Source/CRC1 Input Channel) */ -#define IRQ_MDMA1_DEST_CRC1 BFIN_IRQ(91) /* DMA24 Data (MDMA Stream 1 Destination/CRC1 Output Channel) */ -#define IRQ_MDMAS1 IRQ_MDMA1_DEST_CRC1 -#define IRQ_CRC1_DCNTEXP BFIN_IRQ(92) /* CRC1 DATACOUNT Expiration */ -#define IRQ_CRC1_ERR BFIN_IRQ(93) /* CRC1 Error */ -#define IRQ_MDMA2_SRC BFIN_IRQ(94) /* DMA25 Data (MDMA Stream 2 Source Channel) */ -#define IRQ_MDMA2_DEST BFIN_IRQ(95) /* DMA26 Data (MDMA Stream 2 Destination Channel) */ -#define IRQ_MDMAS2 IRQ_MDMA2_DEST -#define IRQ_MDMA3_SRC BFIN_IRQ(96) /* DMA27 Data (MDMA Stream 3 Source Channel) */ -#define IRQ_MDMA3_DEST BFIN_IRQ(97) /* DMA28 Data (MDMA Stream 3 Destination Channel) */ -#define IRQ_MDMAS3 IRQ_MDMA3_DEST -#define IRQ_EPPI0_CH0 BFIN_IRQ(98) /* DMA29 Data (EPPI0 Channel 0) */ -#define IRQ_EPPI0_CH1 BFIN_IRQ(99) /* DMA30 Data (EPPI0 Channel 1) */ -#define IRQ_EPPI0_STAT BFIN_IRQ(100) /* EPPI0 Status */ -#define IRQ_EPPI2_CH0 BFIN_IRQ(101) /* DMA31 Data (EPPI2 Channel 0) */ -#define IRQ_EPPI2_CH1 BFIN_IRQ(102) /* DMA32 Data (EPPI2 Channel 1) */ -#define IRQ_EPPI2_STAT BFIN_IRQ(103) /* EPPI2 Status */ -#define IRQ_EPPI1_CH0 BFIN_IRQ(104) /* DMA33 Data (EPPI1 Channel 0) */ -#define IRQ_EPPI1_CH1 BFIN_IRQ(105) /* DMA34 Data (EPPI1 Channel 1) */ -#define IRQ_EPPI1_STAT BFIN_IRQ(106) /* EPPI1 Status */ -#define IRQ_PIXC_CH0 BFIN_IRQ(107) /* DMA35 Data (PIXC Channel 0) */ -#define IRQ_PIXC_CH1 BFIN_IRQ(108) /* DMA36 Data (PIXC Channel 1) */ -#define IRQ_PIXC_CH2 BFIN_IRQ(109) /* DMA37 Data (PIXC Channel 2) */ -#define IRQ_PIXC_STAT BFIN_IRQ(110) /* PIXC Status */ -#define IRQ_PVP_CPDOB BFIN_IRQ(111) /* DMA38 Data (PVP0 Camera Pipe Data Out B) */ -#define IRQ_PVP_CPDOC BFIN_IRQ(112) /* DMA39 Data (PVP0 Camera Pipe Data Out C) */ -#define IRQ_PVP_CPSTAT BFIN_IRQ(113) /* DMA40 Data (PVP0 Camera Pipe Status Out) */ -#define IRQ_PVP_CPCI BFIN_IRQ(114) /* DMA41 Data (PVP0 Camera Pipe Control In) */ -#define IRQ_PVP_STAT0 BFIN_IRQ(115) /* PVP0 Status 0 */ -#define IRQ_PVP_MPDO BFIN_IRQ(116) /* DMA42 Data (PVP0 Memory Pipe Data Out) */ -#define IRQ_PVP_MPDI BFIN_IRQ(117) /* DMA43 Data (PVP0 Memory Pipe Data In) */ -#define IRQ_PVP_MPSTAT BFIN_IRQ(118) /* DMA44 Data (PVP0 Memory Pipe Status Out) */ -#define IRQ_PVP_MPCI BFIN_IRQ(119) /* DMA45 Data (PVP0 Memory Pipe Control In) */ -#define IRQ_PVP_CPDOA BFIN_IRQ(120) /* DMA46 Data (PVP0 Camera Pipe Data Out A) */ -#define IRQ_PVP_STAT1 BFIN_IRQ(121) /* PVP0 Status 1 */ -#define IRQ_USB_STAT BFIN_IRQ(122) /* USB Status Interrupt */ -#define IRQ_USB_DMA BFIN_IRQ(123) /* USB DMA Interrupt */ -#define IRQ_TRU_INT0 BFIN_IRQ(124) /* TRU0 Interrupt 0 */ -#define IRQ_TRU_INT1 BFIN_IRQ(125) /* TRU0 Interrupt 1 */ -#define IRQ_TRU_INT2 BFIN_IRQ(126) /* TRU0 Interrupt 2 */ -#define IRQ_TRU_INT3 BFIN_IRQ(127) /* TRU0 Interrupt 3 */ -#define IRQ_DMAC0_ERROR BFIN_IRQ(128) /* DMAC0 Status Interrupt */ -#define IRQ_CGU0_ERROR BFIN_IRQ(129) /* CGU0 Error */ -/* -- RESERVED -- 130 Reserved */ -#define IRQ_DPM BFIN_IRQ(131) /* DPM0 Event */ -/* -- RESERVED -- 132 Reserved */ -#define IRQ_SWU0 BFIN_IRQ(133) /* SWU0 */ -#define IRQ_SWU1 BFIN_IRQ(134) /* SWU1 */ -#define IRQ_SWU2 BFIN_IRQ(135) /* SWU2 */ -#define IRQ_SWU3 BFIN_IRQ(136) /* SWU3 */ -#define IRQ_SWU4 BFIN_IRQ(137) /* SWU4 */ -#define IRQ_SWU5 BFIN_IRQ(138) /* SWU5 */ -#define IRQ_SWU6 BFIN_IRQ(139) /* SWU6 */ - -#define SYS_IRQS IRQ_SWU6 - -#define BFIN_PA_IRQ(x) ((x) + SYS_IRQS + 1) -#define IRQ_PA0 BFIN_PA_IRQ(0) -#define IRQ_PA1 BFIN_PA_IRQ(1) -#define IRQ_PA2 BFIN_PA_IRQ(2) -#define IRQ_PA3 BFIN_PA_IRQ(3) -#define IRQ_PA4 BFIN_PA_IRQ(4) -#define IRQ_PA5 BFIN_PA_IRQ(5) -#define IRQ_PA6 BFIN_PA_IRQ(6) -#define IRQ_PA7 BFIN_PA_IRQ(7) -#define IRQ_PA8 BFIN_PA_IRQ(8) -#define IRQ_PA9 BFIN_PA_IRQ(9) -#define IRQ_PA10 BFIN_PA_IRQ(10) -#define IRQ_PA11 BFIN_PA_IRQ(11) -#define IRQ_PA12 BFIN_PA_IRQ(12) -#define IRQ_PA13 BFIN_PA_IRQ(13) -#define IRQ_PA14 BFIN_PA_IRQ(14) -#define IRQ_PA15 BFIN_PA_IRQ(15) - -#define BFIN_PB_IRQ(x) ((x) + IRQ_PA15 + 1) -#define IRQ_PB0 BFIN_PB_IRQ(0) -#define IRQ_PB1 BFIN_PB_IRQ(1) -#define IRQ_PB2 BFIN_PB_IRQ(2) -#define IRQ_PB3 BFIN_PB_IRQ(3) -#define IRQ_PB4 BFIN_PB_IRQ(4) -#define IRQ_PB5 BFIN_PB_IRQ(5) -#define IRQ_PB6 BFIN_PB_IRQ(6) -#define IRQ_PB7 BFIN_PB_IRQ(7) -#define IRQ_PB8 BFIN_PB_IRQ(8) -#define IRQ_PB9 BFIN_PB_IRQ(9) -#define IRQ_PB10 BFIN_PB_IRQ(10) -#define IRQ_PB11 BFIN_PB_IRQ(11) -#define IRQ_PB12 BFIN_PB_IRQ(12) -#define IRQ_PB13 BFIN_PB_IRQ(13) -#define IRQ_PB14 BFIN_PB_IRQ(14) -#define IRQ_PB15 BFIN_PB_IRQ(15) /* N/A */ - -#define BFIN_PC_IRQ(x) ((x) + IRQ_PB15 + 1) -#define IRQ_PC0 BFIN_PC_IRQ(0) -#define IRQ_PC1 BFIN_PC_IRQ(1) -#define IRQ_PC2 BFIN_PC_IRQ(2) -#define IRQ_PC3 BFIN_PC_IRQ(3) -#define IRQ_PC4 BFIN_PC_IRQ(4) -#define IRQ_PC5 BFIN_PC_IRQ(5) -#define IRQ_PC6 BFIN_PC_IRQ(6) -#define IRQ_PC7 BFIN_PC_IRQ(7) -#define IRQ_PC8 BFIN_PC_IRQ(8) -#define IRQ_PC9 BFIN_PC_IRQ(9) -#define IRQ_PC10 BFIN_PC_IRQ(10) -#define IRQ_PC11 BFIN_PC_IRQ(11) -#define IRQ_PC12 BFIN_PC_IRQ(12) -#define IRQ_PC13 BFIN_PC_IRQ(13) -#define IRQ_PC14 BFIN_PC_IRQ(14) /* N/A */ -#define IRQ_PC15 BFIN_PC_IRQ(15) /* N/A */ - -#define BFIN_PD_IRQ(x) ((x) + IRQ_PC15 + 1) -#define IRQ_PD0 BFIN_PD_IRQ(0) -#define IRQ_PD1 BFIN_PD_IRQ(1) -#define IRQ_PD2 BFIN_PD_IRQ(2) -#define IRQ_PD3 BFIN_PD_IRQ(3) -#define IRQ_PD4 BFIN_PD_IRQ(4) -#define IRQ_PD5 BFIN_PD_IRQ(5) -#define IRQ_PD6 BFIN_PD_IRQ(6) -#define IRQ_PD7 BFIN_PD_IRQ(7) -#define IRQ_PD8 BFIN_PD_IRQ(8) -#define IRQ_PD9 BFIN_PD_IRQ(9) -#define IRQ_PD10 BFIN_PD_IRQ(10) -#define IRQ_PD11 BFIN_PD_IRQ(11) -#define IRQ_PD12 BFIN_PD_IRQ(12) -#define IRQ_PD13 BFIN_PD_IRQ(13) -#define IRQ_PD14 BFIN_PD_IRQ(14) -#define IRQ_PD15 BFIN_PD_IRQ(15) - -#define BFIN_PE_IRQ(x) ((x) + IRQ_PD15 + 1) -#define IRQ_PE0 BFIN_PE_IRQ(0) -#define IRQ_PE1 BFIN_PE_IRQ(1) -#define IRQ_PE2 BFIN_PE_IRQ(2) -#define IRQ_PE3 BFIN_PE_IRQ(3) -#define IRQ_PE4 BFIN_PE_IRQ(4) -#define IRQ_PE5 BFIN_PE_IRQ(5) -#define IRQ_PE6 BFIN_PE_IRQ(6) -#define IRQ_PE7 BFIN_PE_IRQ(7) -#define IRQ_PE8 BFIN_PE_IRQ(8) -#define IRQ_PE9 BFIN_PE_IRQ(9) -#define IRQ_PE10 BFIN_PE_IRQ(10) -#define IRQ_PE11 BFIN_PE_IRQ(11) -#define IRQ_PE12 BFIN_PE_IRQ(12) -#define IRQ_PE13 BFIN_PE_IRQ(13) -#define IRQ_PE14 BFIN_PE_IRQ(14) -#define IRQ_PE15 BFIN_PE_IRQ(15) - -#define BFIN_PF_IRQ(x) ((x) + IRQ_PE15 + 1) -#define IRQ_PF0 BFIN_PF_IRQ(0) -#define IRQ_PF1 BFIN_PF_IRQ(1) -#define IRQ_PF2 BFIN_PF_IRQ(2) -#define IRQ_PF3 BFIN_PF_IRQ(3) -#define IRQ_PF4 BFIN_PF_IRQ(4) -#define IRQ_PF5 BFIN_PF_IRQ(5) -#define IRQ_PF6 BFIN_PF_IRQ(6) -#define IRQ_PF7 BFIN_PF_IRQ(7) -#define IRQ_PF8 BFIN_PF_IRQ(8) -#define IRQ_PF9 BFIN_PF_IRQ(9) -#define IRQ_PF10 BFIN_PF_IRQ(10) -#define IRQ_PF11 BFIN_PF_IRQ(11) -#define IRQ_PF12 BFIN_PF_IRQ(12) -#define IRQ_PF13 BFIN_PF_IRQ(13) -#define IRQ_PF14 BFIN_PF_IRQ(14) -#define IRQ_PF15 BFIN_PF_IRQ(15) - -#define BFIN_PG_IRQ(x) ((x) + IRQ_PF15 + 1) -#define IRQ_PG0 BFIN_PG_IRQ(0) -#define IRQ_PG1 BFIN_PG_IRQ(1) -#define IRQ_PG2 BFIN_PG_IRQ(2) -#define IRQ_PG3 BFIN_PG_IRQ(3) -#define IRQ_PG4 BFIN_PG_IRQ(4) -#define IRQ_PG5 BFIN_PG_IRQ(5) -#define IRQ_PG6 BFIN_PG_IRQ(6) -#define IRQ_PG7 BFIN_PG_IRQ(7) -#define IRQ_PG8 BFIN_PG_IRQ(8) -#define IRQ_PG9 BFIN_PG_IRQ(9) -#define IRQ_PG10 BFIN_PG_IRQ(10) -#define IRQ_PG11 BFIN_PG_IRQ(11) -#define IRQ_PG12 BFIN_PG_IRQ(12) -#define IRQ_PG13 BFIN_PG_IRQ(13) -#define IRQ_PG14 BFIN_PG_IRQ(14) -#define IRQ_PG15 BFIN_PG_IRQ(15) - -#define GPIO_IRQ_BASE IRQ_PA0 - -#define NR_MACH_IRQS (IRQ_PG15 + 1) - -#ifndef __ASSEMBLY__ -#include - -/* - * bfin pint registers layout - */ -struct bfin_pint_regs { - u32 mask_set; - u32 mask_clear; - u32 request; - u32 assign; - u32 edge_set; - u32 edge_clear; - u32 invert_set; - u32 invert_clear; - u32 pinstate; - u32 latch; - u32 __pad0[2]; -}; - -#endif - -#endif diff --git a/trunk/arch/blackfin/mach-bf609/include/mach/mem_map.h b/trunk/arch/blackfin/mach-bf609/include/mach/mem_map.h deleted file mode 100644 index 20b65bfc5311..000000000000 --- a/trunk/arch/blackfin/mach-bf609/include/mach/mem_map.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * BF60x memory map - * - * Copyright 2011 Analog Devices Inc. - * Licensed under the GPL-2 or later. - */ - -#ifndef __BFIN_MACH_MEM_MAP_H__ -#define __BFIN_MACH_MEM_MAP_H__ - -#ifndef __BFIN_MEM_MAP_H__ -# error "do not include mach/mem_map.h directly -- use asm/mem_map.h" -#endif - -/* Async Memory Banks */ -#define ASYNC_BANK3_BASE 0xBC000000 /* Async Bank 3 */ -#define ASYNC_BANK3_SIZE 0x04000000 /* 64M */ -#define ASYNC_BANK2_BASE 0xB8000000 /* Async Bank 2 */ -#define ASYNC_BANK2_SIZE 0x04000000 /* 64M */ -#define ASYNC_BANK1_BASE 0xB4000000 /* Async Bank 1 */ -#define ASYNC_BANK1_SIZE 0x04000000 /* 64M */ -#define ASYNC_BANK0_BASE 0xB0000000 /* Async Bank 0 */ -#define ASYNC_BANK0_SIZE 0x04000000 /* 64M */ - -/* Boot ROM Memory */ - -#define BOOT_ROM_START 0xC8000000 -#define BOOT_ROM_LENGTH 0x8000 - -/* Level 1 Memory */ - -/* Memory Map for ADSP-BF60x processors */ -#ifdef CONFIG_BFIN_ICACHE -#define BFIN_ICACHESIZE (16*1024) -#define L1_CODE_LENGTH 0x10000 -#else -#define BFIN_ICACHESIZE (0*1024) -#define L1_CODE_LENGTH 0x14000 -#endif - -#define L1_CODE_START 0xFFA00000 -#define L1_DATA_A_START 0xFF800000 -#define L1_DATA_B_START 0xFF900000 - - -#define COREA_L1_SCRATCH_START 0xFFB00000 -#define COREB_L1_SCRATCH_START 0xFF700000 - -#define COREB_L1_CODE_START 0xFF600000 -#define COREB_L1_DATA_A_START 0xFF400000 -#define COREB_L1_DATA_B_START 0xFF500000 - -#define COREB_L1_CODE_LENGTH 0x14000 -#define COREB_L1_DATA_A_LENGTH 0x8000 -#define COREB_L1_DATA_B_LENGTH 0x8000 - - -#ifdef CONFIG_BFIN_DCACHE - -#ifdef CONFIG_BFIN_DCACHE_BANKA -#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0) -#define L1_DATA_A_LENGTH (0x8000 - 0x4000) -#define L1_DATA_B_LENGTH 0x8000 -#define BFIN_DCACHESIZE (16*1024) -#define BFIN_DSUPBANKS 1 -#else -#define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0) -#define L1_DATA_A_LENGTH (0x8000 - 0x4000) -#define L1_DATA_B_LENGTH (0x8000 - 0x4000) -#define BFIN_DCACHESIZE (32*1024) -#define BFIN_DSUPBANKS 2 -#endif - -#else -#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0) -#define L1_DATA_A_LENGTH 0x8000 -#define L1_DATA_B_LENGTH 0x8000 -#define BFIN_DCACHESIZE (0*1024) -#define BFIN_DSUPBANKS 0 -#endif /*CONFIG_BFIN_DCACHE*/ - -/* Level 2 Memory */ -#define L2_START 0xC8080000 -#define L2_LENGTH 0x40000 - -#endif diff --git a/trunk/arch/blackfin/mach-bf609/include/mach/pll.h b/trunk/arch/blackfin/mach-bf609/include/mach/pll.h deleted file mode 100644 index 1857a4a0f262..000000000000 --- a/trunk/arch/blackfin/mach-bf609/include/mach/pll.h +++ /dev/null @@ -1 +0,0 @@ -/* #include */ diff --git a/trunk/arch/blackfin/mach-bf609/include/mach/pm.h b/trunk/arch/blackfin/mach-bf609/include/mach/pm.h deleted file mode 100644 index 036d9bdc889e..000000000000 --- a/trunk/arch/blackfin/mach-bf609/include/mach/pm.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Blackfin bf609 power management - * - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2 - */ - -#ifndef __MACH_BF609_PM_H__ -#define __MACH_BF609_PM_H__ - -#include - -int bfin609_pm_enter(suspend_state_t state); -int bf609_pm_prepare(void); -void bf609_pm_finish(void); - -void bf609_hibernate(void); -void bfin_sec_raise_irq(unsigned int sid); -void coreb_enable(void); -#endif diff --git a/trunk/arch/blackfin/mach-bf609/include/mach/portmux.h b/trunk/arch/blackfin/mach-bf609/include/mach/portmux.h deleted file mode 100644 index 2e1a51c25098..000000000000 --- a/trunk/arch/blackfin/mach-bf609/include/mach/portmux.h +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2 or later - */ - -#ifndef _MACH_PORTMUX_H_ -#define _MACH_PORTMUX_H_ - -#define MAX_RESOURCES MAX_BLACKFIN_GPIOS - -/* EMAC RMII Port Mux */ -#define P_MII0_MDC (P_DEFINED | P_IDENT(GPIO_PC6) | P_FUNCT(0)) -#define P_MII0_MDIO (P_DEFINED | P_IDENT(GPIO_PC7) | P_FUNCT(0)) -#define P_MII0_ETxD0 (P_DEFINED | P_IDENT(GPIO_PC2) | P_FUNCT(0)) -#define P_MII0_ERxD0 (P_DEFINED | P_IDENT(GPIO_PC0) | P_FUNCT(0)) -#define P_MII0_ETxD1 (P_DEFINED | P_IDENT(GPIO_PC3) | P_FUNCT(0)) -#define P_MII0_ERxD1 (P_DEFINED | P_IDENT(GPIO_PC1) | P_FUNCT(0)) -#define P_MII0_ETxEN (P_DEFINED | P_IDENT(GPIO_PB13) | P_FUNCT(0)) -#define P_MII0_PHYINT (P_DEFINED | P_IDENT(GPIO_PD6) | P_FUNCT(0)) -#define P_MII0_CRS (P_DEFINED | P_IDENT(GPIO_PC5) | P_FUNCT(0)) -#define P_MII0_ERxER (P_DEFINED | P_IDENT(GPIO_PC4) | P_FUNCT(0)) -#define P_MII0_TxCLK (P_DEFINED | P_IDENT(GPIO_PB14) | P_FUNCT(0)) - -#define P_RMII0 {\ - P_MII0_ETxD0, \ - P_MII0_ETxD1, \ - P_MII0_ETxEN, \ - P_MII0_ERxD0, \ - P_MII0_ERxD1, \ - P_MII0_ERxER, \ - P_MII0_TxCLK, \ - P_MII0_PHYINT, \ - P_MII0_CRS, \ - P_MII0_MDC, \ - P_MII0_MDIO, 0} - -#define P_MII1_MDC (P_DEFINED | P_IDENT(GPIO_PE10) | P_FUNCT(0)) -#define P_MII1_MDIO (P_DEFINED | P_IDENT(GPIO_PE11) | P_FUNCT(0)) -#define P_MII1_ETxD0 (P_DEFINED | P_IDENT(GPIO_PG3) | P_FUNCT(0)) -#define P_MII1_ERxD0 (P_DEFINED | P_IDENT(GPIO_PG0) | P_FUNCT(0)) -#define P_MII1_ETxD1 (P_DEFINED | P_IDENT(GPIO_PG2) | P_FUNCT(0)) -#define P_MII1_ERxD1 (P_DEFINED | P_IDENT(GPIO_PE15) | P_FUNCT(0)) -#define P_MII1_ETxEN (P_DEFINED | P_IDENT(GPIO_PG5) | P_FUNCT(0)) -#define P_MII1_PHYINT (P_DEFINED | P_IDENT(GPIO_PE12) | P_FUNCT(0)) -#define P_MII1_CRS (P_DEFINED | P_IDENT(GPIO_PE13) | P_FUNCT(0)) -#define P_MII1_ERxER (P_DEFINED | P_IDENT(GPIO_PE14) | P_FUNCT(0)) -#define P_MII1_TxCLK (P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(0)) - -#define P_RMII1 {\ - P_MII1_ETxD0, \ - P_MII1_ETxD1, \ - P_MII1_ETxEN, \ - P_MII1_ERxD0, \ - P_MII1_ERxD1, \ - P_MII1_ERxER, \ - P_MII1_TxCLK, \ - P_MII1_PHYINT, \ - P_MII1_CRS, \ - P_MII1_MDC, \ - P_MII1_MDIO, 0} - -/* PPI Port Mux */ -#define P_PPI0_D0 (P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(1)) -#define P_PPI0_D1 (P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(1)) -#define P_PPI0_D2 (P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(1)) -#define P_PPI0_D3 (P_DEFINED | P_IDENT(GPIO_PF3) | P_FUNCT(1)) -#define P_PPI0_D4 (P_DEFINED | P_IDENT(GPIO_PF4) | P_FUNCT(1)) -#define P_PPI0_D5 (P_DEFINED | P_IDENT(GPIO_PF5) | P_FUNCT(1)) -#define P_PPI0_D6 (P_DEFINED | P_IDENT(GPIO_PF6) | P_FUNCT(1)) -#define P_PPI0_D7 (P_DEFINED | P_IDENT(GPIO_PF7) | P_FUNCT(1)) -#define P_PPI0_D8 (P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(1)) -#define P_PPI0_D9 (P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(1)) -#define P_PPI0_D10 (P_DEFINED | P_IDENT(GPIO_PF10) | P_FUNCT(1)) -#define P_PPI0_D11 (P_DEFINED | P_IDENT(GPIO_PF11) | P_FUNCT(1)) -#define P_PPI0_D12 (P_DEFINED | P_IDENT(GPIO_PF12) | P_FUNCT(1)) -#define P_PPI0_D13 (P_DEFINED | P_IDENT(GPIO_PF13) | P_FUNCT(1)) -#define P_PPI0_D14 (P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(1)) -#define P_PPI0_D15 (P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(1)) -#define P_PPI0_D16 (P_DEFINED | P_IDENT(GPIO_PE3) | P_FUNCT(1)) -#define P_PPI0_D17 (P_DEFINED | P_IDENT(GPIO_PE4) | P_FUNCT(1)) -#define P_PPI0_D18 (P_DEFINED | P_IDENT(GPIO_PE0) | P_FUNCT(1)) -#define P_PPI0_D19 (P_DEFINED | P_IDENT(GPIO_PE1) | P_FUNCT(1)) -#define P_PPI0_D20 (P_DEFINED | P_IDENT(GPIO_PD12) | P_FUNCT(1)) -#define P_PPI0_D21 (P_DEFINED | P_IDENT(GPIO_PD15) | P_FUNCT(1)) -#define P_PPI0_D22 (P_DEFINED | P_IDENT(GPIO_PE2) | P_FUNCT(1)) -#define P_PPI0_D23 (P_DEFINED | P_IDENT(GPIO_PE5) | P_FUNCT(1)) -#define P_PPI0_CLK (P_DEFINED | P_IDENT(GPIO_PE9) | P_FUNCT(1)) -#define P_PPI0_FS1 (P_DEFINED | P_IDENT(GPIO_PE8) | P_FUNCT(1)) -#define P_PPI0_FS2 (P_DEFINED | P_IDENT(GPIO_PE7) | P_FUNCT(1)) -#define P_PPI0_FS3 (P_DEFINED | P_IDENT(GPIO_PE6) | P_FUNCT(1)) - -#define P_PPI1_D0 (P_DEFINED | P_IDENT(GPIO_PC0) | P_FUNCT(1)) -#define P_PPI1_D1 (P_DEFINED | P_IDENT(GPIO_PC1) | P_FUNCT(1)) -#define P_PPI1_D2 (P_DEFINED | P_IDENT(GPIO_PC2) | P_FUNCT(1)) -#define P_PPI1_D3 (P_DEFINED | P_IDENT(GPIO_PC3) | P_FUNCT(1)) -#define P_PPI1_D4 (P_DEFINED | P_IDENT(GPIO_PC4) | P_FUNCT(1)) -#define P_PPI1_D5 (P_DEFINED | P_IDENT(GPIO_PC5) | P_FUNCT(1)) -#define P_PPI1_D6 (P_DEFINED | P_IDENT(GPIO_PC6) | P_FUNCT(1)) -#define P_PPI1_D7 (P_DEFINED | P_IDENT(GPIO_PC7) | P_FUNCT(1)) -#define P_PPI1_D8 (P_DEFINED | P_IDENT(GPIO_PC8) | P_FUNCT(1)) -#define P_PPI1_D9 (P_DEFINED | P_IDENT(GPIO_PC9) | P_FUNCT(1)) -#define P_PPI1_D10 (P_DEFINED | P_IDENT(GPIO_PC10) | P_FUNCT(1)) -#define P_PPI1_D11 (P_DEFINED | P_IDENT(GPIO_PC11) | P_FUNCT(1)) -#define P_PPI1_D12 (P_DEFINED | P_IDENT(GPIO_PC12) | P_FUNCT(1)) -#define P_PPI1_D13 (P_DEFINED | P_IDENT(GPIO_PC13) | P_FUNCT(1)) -#define P_PPI1_D14 (P_DEFINED | P_IDENT(GPIO_PC14) | P_FUNCT(1)) -#define P_PPI1_D15 (P_DEFINED | P_IDENT(GPIO_PC15) | P_FUNCT(1)) -#define P_PPI1_D16 (P_DEFINED | P_IDENT(GPIO_PD0) | P_FUNCT(1)) -#define P_PPI1_D17 (P_DEFINED | P_IDENT(GPIO_PD1) | P_FUNCT(1)) -#define P_PPI1_CLK (P_DEFINED | P_IDENT(GPIO_PB14) | P_FUNCT(1)) -#define P_PPI1_FS1 (P_DEFINED | P_IDENT(GPIO_PB13) | P_FUNCT(1)) -#define P_PPI1_FS2 (P_DEFINED | P_IDENT(GPIO_PD6) | P_FUNCT(1)) -#define P_PPI1_FS3 (P_DEFINED | P_IDENT(GPIO_PB15) | P_FUNCT(1)) - -#define P_PPI2_D0 (P_DEFINED | P_IDENT(GPIO_PA0) | P_FUNCT(1)) -#define P_PPI2_D1 (P_DEFINED | P_IDENT(GPIO_PA1) | P_FUNCT(1)) -#define P_PPI2_D2 (P_DEFINED | P_IDENT(GPIO_PA2) | P_FUNCT(1)) -#define P_PPI2_D3 (P_DEFINED | P_IDENT(GPIO_PA3) | P_FUNCT(1)) -#define P_PPI2_D4 (P_DEFINED | P_IDENT(GPIO_PA4) | P_FUNCT(1)) -#define P_PPI2_D5 (P_DEFINED | P_IDENT(GPIO_PA5) | P_FUNCT(1)) -#define P_PPI2_D6 (P_DEFINED | P_IDENT(GPIO_PA6) | P_FUNCT(1)) -#define P_PPI2_D7 (P_DEFINED | P_IDENT(GPIO_PA7) | P_FUNCT(1)) -#define P_PPI2_D8 (P_DEFINED | P_IDENT(GPIO_PA8) | P_FUNCT(1)) -#define P_PPI2_D9 (P_DEFINED | P_IDENT(GPIO_PA9) | P_FUNCT(1)) -#define P_PPI2_D10 (P_DEFINED | P_IDENT(GPIO_PA10) | P_FUNCT(1)) -#define P_PPI2_D11 (P_DEFINED | P_IDENT(GPIO_PA11) | P_FUNCT(1)) -#define P_PPI2_D12 (P_DEFINED | P_IDENT(GPIO_PA12) | P_FUNCT(1)) -#define P_PPI2_D13 (P_DEFINED | P_IDENT(GPIO_PA13) | P_FUNCT(1)) -#define P_PPI2_D14 (P_DEFINED | P_IDENT(GPIO_PA14) | P_FUNCT(1)) -#define P_PPI2_D15 (P_DEFINED | P_IDENT(GPIO_PA15) | P_FUNCT(1)) -#define P_PPI2_D16 (P_DEFINED | P_IDENT(GPIO_PB7) | P_FUNCT(1)) -#define P_PPI2_D17 (P_DEFINED | P_IDENT(GPIO_PB8) | P_FUNCT(1)) -#define P_PPI2_CLK (P_DEFINED | P_IDENT(GPIO_PB0) | P_FUNCT(1)) -#define P_PPI2_FS1 (P_DEFINED | P_IDENT(GPIO_PB1) | P_FUNCT(1)) -#define P_PPI2_FS2 (P_DEFINED | P_IDENT(GPIO_PB2) | P_FUNCT(1)) -#define P_PPI2_FS3 (P_DEFINED | P_IDENT(GPIO_PB3) | P_FUNCT(1)) - -/* SPI Port Mux */ -#define P_SPI0_SS (P_DEFINED | P_IDENT(GPIO_PD11) | P_FUNCT(3)) -#define P_SPI0_SCK (P_DEFINED | P_IDENT(GPIO_PD4) | P_FUNCT(0)) -#define P_SPI0_MISO (P_DEFINED | P_IDENT(GPIO_PD2) | P_FUNCT(0)) -#define P_SPI0_MOSI (P_DEFINED | P_IDENT(GPIO_PD3) | P_FUNCT(0)) -#define P_SPI0_RDY (P_DEFINED | P_IDENT(GPIO_PD10) | P_FUNCT(0)) -#define P_SPI0_D2 (P_DEFINED | P_IDENT(GPIO_PD0) | P_FUNCT(0)) -#define P_SPI0_D3 (P_DEFINED | P_IDENT(GPIO_PD1) | P_FUNCT(0)) - -#define P_SPI0_SSEL1 (P_DEFINED | P_IDENT(GPIO_PD11) | P_FUNCT(0)) -#define P_SPI0_SSEL2 (P_DEFINED | P_IDENT(GPIO_PD1) | P_FUNCT(2)) -#define P_SPI0_SSEL3 (P_DEFINED | P_IDENT(GPIO_PD0) | P_FUNCT(2)) -#define P_SPI0_SSEL4 (P_DEFINED | P_IDENT(GPIO_PC15) | P_FUNCT(0)) -#define P_SPI0_SSEL5 (P_DEFINED | P_IDENT(GPIO_PD9) | P_FUNCT(0)) -#define P_SPI0_SSEL6 (P_DEFINED | P_IDENT(GPIO_PC13) | P_FUNCT(0)) -#define P_SPI0_SSEL7 (P_DEFINED | P_IDENT(GPIO_PC12) | P_FUNCT(0)) - -#define P_SPI1_SS (P_DEFINED | P_IDENT(GPIO_PD12) | P_FUNCT(3)) -#define P_SPI1_SCK (P_DEFINED | P_IDENT(GPIO_PD5) | P_FUNCT(0)) -#define P_SPI1_MISO (P_DEFINED | P_IDENT(GPIO_PD14) | P_FUNCT(0)) -#define P_SPI1_MOSI (P_DEFINED | P_IDENT(GPIO_PD13) | P_FUNCT(0)) -#define P_SPI1_RDY (P_DEFINED | P_IDENT(GPIO_PE2) | P_FUNCT(0)) -#define P_SPI1_D2 (P_DEFINED | P_IDENT(GPIO_PE1) | P_FUNCT(0)) -#define P_SPI1_D3 (P_DEFINED | P_IDENT(GPIO_PE0) | P_FUNCT(0)) - -#define P_SPI1_SSEL1 (P_DEFINED | P_IDENT(GPIO_PD12) | P_FUNCT(0)) -#define P_SPI1_SSEL2 (P_DEFINED | P_IDENT(GPIO_PD15) | P_FUNCT(2)) -#define P_SPI1_SSEL3 (P_DEFINED | P_IDENT(GPIO_PD10) | P_FUNCT(2)) -#define P_SPI1_SSEL4 (P_DEFINED | P_IDENT(GPIO_PD9) | P_FUNCT(2)) -#define P_SPI1_SSEL5 (P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(0)) -#define P_SPI1_SSEL6 (P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(0)) -#define P_SPI1_SSEL7 (P_DEFINED | P_IDENT(GPIO_PC14) | P_FUNCT(0)) - -#define GPIO_DEFAULT_BOOT_SPI_CS -#define P_DEFAULT_BOOT_SPI_CS - -/* CORE IDLE */ -#define P_IDLEA (P_DEFINED | P_IDENT(GPIO_PG14) | P_FUNCT(1)) -#define P_IDLEB (P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(1)) -#define P_SLEEP (P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(2)) - -/* UART Port Mux */ -#define P_UART0_TX (P_DEFINED | P_IDENT(GPIO_PD7) | P_FUNCT(1)) -#define P_UART0_RX (P_DEFINED | P_IDENT(GPIO_PD8) | P_FUNCT(1)) -#define P_UART0_RTS (P_DEFINED | P_IDENT(GPIO_PD9) | P_FUNCT(1)) -#define P_UART0_CTS (P_DEFINED | P_IDENT(GPIO_PD10) | P_FUNCT(1)) - -#define P_UART1_TX (P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(0)) -#define P_UART1_RX (P_DEFINED | P_IDENT(GPIO_PG14) | P_FUNCT(0)) -#define P_UART1_RTS (P_DEFINED | P_IDENT(GPIO_PG10) | P_FUNCT(0)) -#define P_UART1_CTS (P_DEFINED | P_IDENT(GPIO_PG13) | P_FUNCT(0)) - -/* Timer */ -#define P_TMRCLK (P_DEFINED | P_IDENT(GPIO_PG13) | P_FUNCT(3)) -#define P_TMR0 (P_DEFINED | P_IDENT(GPIO_PE14) | P_FUNCT(2)) -#define P_TMR1 (P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(1)) -#define P_TMR2 (P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(1)) -#define P_TMR3 (P_DEFINED | P_IDENT(GPIO_PG8) | P_FUNCT(1)) -#define P_TMR4 (P_DEFINED | P_IDENT(GPIO_PG9) | P_FUNCT(1)) -#define P_TMR5 (P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(1)) -#define P_TMR6 (P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(1)) -#define P_TMR7 (P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(1)) - -/* RSI */ -#define P_RSI_DATA0 (P_DEFINED | P_IDENT(GPIO_PG3) | P_FUNCT(2)) -#define P_RSI_DATA1 (P_DEFINED | P_IDENT(GPIO_PG2) | P_FUNCT(2)) -#define P_RSI_DATA2 (P_DEFINED | P_IDENT(GPIO_PG0) | P_FUNCT(2)) -#define P_RSI_DATA3 (P_DEFINED | P_IDENT(GPIO_PE15) | P_FUNCT(2)) -#define P_RSI_DATA4 (P_DEFINED | P_IDENT(GPIO_PE13) | P_FUNCT(2)) -#define P_RSI_DATA5 (P_DEFINED | P_IDENT(GPIO_PE12) | P_FUNCT(2)) -#define P_RSI_DATA6 (P_DEFINED | P_IDENT(GPIO_PE10) | P_FUNCT(2)) -#define P_RSI_DATA7 (P_DEFINED | P_IDENT(GPIO_PE11) | P_FUNCT(2)) -#define P_RSI_CMD (P_DEFINED | P_IDENT(GPIO_PG5) | P_FUNCT(1)) -#define P_RSI_CLK (P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(1)) - -/* PTP */ -#define P_PTP0_PPS (P_DEFINED | P_IDENT(GPIO_PB15) | P_FUNCT(0)) -#define P_PTP0_CLKIN (P_DEFINED | P_IDENT(GPIO_PC13) | P_FUNCT(2)) -#define P_PTP0_AUXIN (P_DEFINED | P_IDENT(GPIO_PC11) | P_FUNCT(2)) - -#define P_PTP1_PPS (P_DEFINED | P_IDENT(GPIO_PC9) | P_FUNCT(0)) -#define P_PTP1_CLKIN (P_DEFINED | P_IDENT(GPIO_PC13) | P_FUNCT(2)) -#define P_PTP1_AUXIN (P_DEFINED | P_IDENT(GPIO_PC11) | P_FUNCT(2)) - -/* SMC Port Mux */ -#define P_A3 (P_DEFINED | P_IDENT(GPIO_PA0) | P_FUNCT(0)) -#define P_A4 (P_DEFINED | P_IDENT(GPIO_PA1) | P_FUNCT(0)) -#define P_A5 (P_DEFINED | P_IDENT(GPIO_PA2) | P_FUNCT(0)) -#define P_A6 (P_DEFINED | P_IDENT(GPIO_PA3) | P_FUNCT(0)) -#define P_A7 (P_DEFINED | P_IDENT(GPIO_PA4) | P_FUNCT(0)) -#define P_A8 (P_DEFINED | P_IDENT(GPIO_PA5) | P_FUNCT(0)) -#define P_A9 (P_DEFINED | P_IDENT(GPIO_PA6) | P_FUNCT(0)) -#define P_A10 (P_DEFINED | P_IDENT(GPIO_PA7) | P_FUNCT(0)) -#define P_A11 (P_DEFINED | P_IDENT(GPIO_PA8) | P_FUNCT(0)) -#define P_A12 (P_DEFINED | P_IDENT(GPIO_PA9) | P_FUNCT(0)) -#define P_A13 (P_DEFINED | P_IDENT(GPIO_PB2) | P_FUNCT(0)) -#define P_A14 (P_DEFINED | P_IDENT(GPIO_PA10) | P_FUNCT(0)) -#define P_A15 (P_DEFINED | P_IDENT(GPIO_PA11) | P_FUNCT(0)) -#define P_A16 (P_DEFINED | P_IDENT(GPIO_PB3) | P_FUNCT(0)) -#define P_A17 (P_DEFINED | P_IDENT(GPIO_PA12) | P_FUNCT(0)) -#define P_A18 (P_DEFINED | P_IDENT(GPIO_PA13) | P_FUNCT(0)) -#define P_A19 (P_DEFINED | P_IDENT(GPIO_PA14) | P_FUNCT(0)) -#define P_A20 (P_DEFINED | P_IDENT(GPIO_PA15) | P_FUNCT(0)) -#define P_A21 (P_DEFINED | P_IDENT(GPIO_PB6) | P_FUNCT(0)) -#define P_A22 (P_DEFINED | P_IDENT(GPIO_PB7) | P_FUNCT(0)) -#define P_A23 (P_DEFINED | P_IDENT(GPIO_PB8) | P_FUNCT(0)) -#define P_A24 (P_DEFINED | P_IDENT(GPIO_PB10) | P_FUNCT(0)) -#define P_A25 (P_DEFINED | P_IDENT(GPIO_PB11) | P_FUNCT(0)) -#define P_NORCK (P_DEFINED | P_IDENT(GPIO_PB0) | P_FUNCT(0)) - -#define P_AMS1 (P_DEFINED | P_IDENT(GPIO_PB1) | P_FUNCT(0)) -#define P_AMS2 (P_DEFINED | P_IDENT(GPIO_PB4) | P_FUNCT(0)) -#define P_AMS3 (P_DEFINED | P_IDENT(GPIO_PB5) | P_FUNCT(0)) - -/* CAN */ -#define P_CAN0_TX (P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(2)) -#define P_CAN0_RX (P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(2)) - -/* SPORT */ -#define P_SPORT0_ACLK (P_DEFINED | P_IDENT(GPIO_PB5) | P_FUNCT(2)) -#define P_SPORT0_AFS (P_DEFINED | P_IDENT(GPIO_PB4) | P_FUNCT(2)) -#define P_SPORT0_AD0 (P_DEFINED | P_IDENT(GPIO_PB9) | P_FUNCT(2)) -#define P_SPORT0_AD1 (P_DEFINED | P_IDENT(GPIO_PB12) | P_FUNCT(2)) -#define P_SPORT0_ATDV (P_DEFINED | P_IDENT(GPIO_PB6) | P_FUNCT(1)) -#define P_SPORT0_BCLK (P_DEFINED | P_IDENT(GPIO_PB8) | P_FUNCT(2)) -#define P_SPORT0_BFS (P_DEFINED | P_IDENT(GPIO_PB7) | P_FUNCT(2)) -#define P_SPORT0_BD0 (P_DEFINED | P_IDENT(GPIO_PB11) | P_FUNCT(2)) -#define P_SPORT0_BD1 (P_DEFINED | P_IDENT(GPIO_PB10) | P_FUNCT(2)) -#define P_SPORT0_BTDV (P_DEFINED | P_IDENT(GPIO_PB12) | P_FUNCT(1)) - -#define P_SPORT1_ACLK (P_DEFINED | P_IDENT(GPIO_PE2) | P_FUNCT(2)) -#define P_SPORT1_AFS (P_DEFINED | P_IDENT(GPIO_PE5) | P_FUNCT(2)) -#define P_SPORT1_AD0 (P_DEFINED | P_IDENT(GPIO_PD15) | P_FUNCT(2)) -#define P_SPORT1_AD1 (P_DEFINED | P_IDENT(GPIO_PD12) | P_FUNCT(2)) -#define P_SPORT1_ATDV (P_DEFINED | P_IDENT(GPIO_PE6) | P_FUNCT(0)) -#define P_SPORT1_BCLK (P_DEFINED | P_IDENT(GPIO_PE4) | P_FUNCT(2)) -#define P_SPORT1_BFS (P_DEFINED | P_IDENT(GPIO_PE3) | P_FUNCT(2)) -#define P_SPORT1_BD0 (P_DEFINED | P_IDENT(GPIO_PE1) | P_FUNCT(2)) -#define P_SPORT1_BD1 (P_DEFINED | P_IDENT(GPIO_PE0) | P_FUNCT(2)) -#define P_SPORT1_BTDV (P_DEFINED | P_IDENT(GPIO_PE7) | P_FUNCT(0)) - -#define P_SPORT2_ACLK (P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(0)) -#define P_SPORT2_AFS (P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(0)) -#define P_SPORT2_AD0 (P_DEFINED | P_IDENT(GPIO_PG9) | P_FUNCT(0)) -#define P_SPORT2_AD1 (P_DEFINED | P_IDENT(GPIO_PG8) | P_FUNCT(0)) -#define P_SPORT2_ATDV (P_DEFINED | P_IDENT(GPIO_PE14) | P_FUNCT(1)) -#define P_SPORT2_BCLK (P_DEFINED | P_IDENT(GPIO_PG10) | P_FUNCT(1)) -#define P_SPORT2_BFS (P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(0)) -#define P_SPORT2_BD0 (P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(0)) -#define P_SPORT2_BD1 (P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(0)) -#define P_SPORT2_BTDV (P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(2)) - -/* LINK PORT */ -#define P_LP0_CLK (P_DEFINED | P_IDENT(GPIO_PB0) | P_FUNCT(2)) -#define P_LP0_ACK (P_DEFINED | P_IDENT(GPIO_PB1) | P_FUNCT(2)) -#define P_LP0_D0 (P_DEFINED | P_IDENT(GPIO_PA0) | P_FUNCT(2)) -#define P_LP0_D1 (P_DEFINED | P_IDENT(GPIO_PA1) | P_FUNCT(2)) -#define P_LP0_D2 (P_DEFINED | P_IDENT(GPIO_PA2) | P_FUNCT(2)) -#define P_LP0_D3 (P_DEFINED | P_IDENT(GPIO_PA3) | P_FUNCT(2)) -#define P_LP0_D4 (P_DEFINED | P_IDENT(GPIO_PA4) | P_FUNCT(2)) -#define P_LP0_D5 (P_DEFINED | P_IDENT(GPIO_PA5) | P_FUNCT(2)) -#define P_LP0_D6 (P_DEFINED | P_IDENT(GPIO_PA6) | P_FUNCT(2)) -#define P_LP0_D7 (P_DEFINED | P_IDENT(GPIO_PA7) | P_FUNCT(2)) - -#define P_LP1_CLK (P_DEFINED | P_IDENT(GPIO_PB3) | P_FUNCT(2)) -#define P_LP1_ACK (P_DEFINED | P_IDENT(GPIO_PB2) | P_FUNCT(2)) -#define P_LP1_D0 (P_DEFINED | P_IDENT(GPIO_PA8) | P_FUNCT(2)) -#define P_LP1_D1 (P_DEFINED | P_IDENT(GPIO_PA9) | P_FUNCT(2)) -#define P_LP1_D2 (P_DEFINED | P_IDENT(GPIO_PA10) | P_FUNCT(2)) -#define P_LP1_D3 (P_DEFINED | P_IDENT(GPIO_PA11) | P_FUNCT(2)) -#define P_LP1_D4 (P_DEFINED | P_IDENT(GPIO_PA12) | P_FUNCT(2)) -#define P_LP1_D5 (P_DEFINED | P_IDENT(GPIO_PA13) | P_FUNCT(2)) -#define P_LP1_D6 (P_DEFINED | P_IDENT(GPIO_PA14) | P_FUNCT(2)) -#define P_LP1_D7 (P_DEFINED | P_IDENT(GPIO_PA15) | P_FUNCT(2)) - -#define P_LP2_CLK (P_DEFINED | P_IDENT(GPIO_PE6) | P_FUNCT(2)) -#define P_LP2_ACK (P_DEFINED | P_IDENT(GPIO_PE7) | P_FUNCT(2)) -#define P_LP2_D0 (P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(2)) -#define P_LP2_D1 (P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(2)) -#define P_LP2_D2 (P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(2)) -#define P_LP2_D3 (P_DEFINED | P_IDENT(GPIO_PF3) | P_FUNCT(2)) -#define P_LP2_D4 (P_DEFINED | P_IDENT(GPIO_PF4) | P_FUNCT(2)) -#define P_LP2_D5 (P_DEFINED | P_IDENT(GPIO_PF5) | P_FUNCT(2)) -#define P_LP2_D6 (P_DEFINED | P_IDENT(GPIO_PF6) | P_FUNCT(2)) -#define P_LP2_D7 (P_DEFINED | P_IDENT(GPIO_PF7) | P_FUNCT(2)) - -#define P_LP3_CLK (P_DEFINED | P_IDENT(GPIO_PE9) | P_FUNCT(2)) -#define P_LP3_ACK (P_DEFINED | P_IDENT(GPIO_PE8) | P_FUNCT(2)) -#define P_LP3_D0 (P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(2)) -#define P_LP3_D1 (P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(2)) -#define P_LP3_D2 (P_DEFINED | P_IDENT(GPIO_PF10) | P_FUNCT(2)) -#define P_LP3_D3 (P_DEFINED | P_IDENT(GPIO_PF11) | P_FUNCT(2)) -#define P_LP3_D4 (P_DEFINED | P_IDENT(GPIO_PF12) | P_FUNCT(2)) -#define P_LP3_D5 (P_DEFINED | P_IDENT(GPIO_PF13) | P_FUNCT(2)) -#define P_LP3_D6 (P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(2)) -#define P_LP3_D7 (P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(2)) - -/* TWI */ -#define P_TWI0_SCL (P_DONTCARE) -#define P_TWI0_SDA (P_DONTCARE) -#define P_TWI1_SCL (P_DONTCARE) -#define P_TWI1_SDA (P_DONTCARE) - -/* Rotary Encoder */ -#define P_CNT_CZM (P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(3)) -#define P_CNT_CUD (P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(3)) -#define P_CNT_CDG (P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(3)) - -#endif /* _MACH_PORTMUX_H_ */ diff --git a/trunk/arch/blackfin/mach-bf609/pm.c b/trunk/arch/blackfin/mach-bf609/pm.c deleted file mode 100644 index b76966eb16ad..000000000000 --- a/trunk/arch/blackfin/mach-bf609/pm.c +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Blackfin bf609 power management - * - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2 - */ - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -/***********************************************************/ -/* */ -/* Wakeup Actions for DPM_RESTORE */ -/* */ -/***********************************************************/ -#define BITP_ROM_WUA_CHKHDR 24 -#define BITP_ROM_WUA_DDRLOCK 7 -#define BITP_ROM_WUA_DDRDLLEN 6 -#define BITP_ROM_WUA_DDR 5 -#define BITP_ROM_WUA_CGU 4 -#define BITP_ROM_WUA_MEMBOOT 2 -#define BITP_ROM_WUA_EN 1 - -#define BITM_ROM_WUA_CHKHDR (0xFF000000) -#define ENUM_ROM_WUA_CHKHDR_AD 0xAD000000 - -#define BITM_ROM_WUA_DDRLOCK (0x00000080) -#define BITM_ROM_WUA_DDRDLLEN (0x00000040) -#define BITM_ROM_WUA_DDR (0x00000020) -#define BITM_ROM_WUA_CGU (0x00000010) -#define BITM_ROM_WUA_MEMBOOT (0x00000002) -#define BITM_ROM_WUA_EN (0x00000001) - -/***********************************************************/ -/* */ -/* Syscontrol */ -/* */ -/***********************************************************/ -#define BITP_ROM_SYSCTRL_CGU_LOCKINGEN 28 /* unlocks CGU_CTL register */ -#define BITP_ROM_SYSCTRL_WUA_OVERRIDE 24 -#define BITP_ROM_SYSCTRL_WUA_DDRDLLEN 20 /* Saves the DDR DLL and PADS registers to the DPM registers */ -#define BITP_ROM_SYSCTRL_WUA_DDR 19 /* Saves the DDR registers to the DPM registers */ -#define BITP_ROM_SYSCTRL_WUA_CGU 18 /* Saves the CGU registers into DPM registers */ -#define BITP_ROM_SYSCTRL_WUA_DPMWRITE 17 /* Saves the Syscontrol structure structure contents into DPM registers */ -#define BITP_ROM_SYSCTRL_WUA_EN 16 /* reads current PLL and DDR configuration into structure */ -#define BITP_ROM_SYSCTRL_DDR_WRITE 13 /* writes the DDR registers from Syscontrol structure for wakeup initialization of DDR */ -#define BITP_ROM_SYSCTRL_DDR_READ 12 /* Read the DDR registers into the Syscontrol structure for storing prior to hibernate */ -#define BITP_ROM_SYSCTRL_CGU_AUTODIS 11 /* Disables auto handling of UPDT and ALGN fields */ -#define BITP_ROM_SYSCTRL_CGU_CLKOUTSEL 7 /* access CGU_CLKOUTSEL register */ -#define BITP_ROM_SYSCTRL_CGU_DIV 6 /* access CGU_DIV register */ -#define BITP_ROM_SYSCTRL_CGU_STAT 5 /* access CGU_STAT register */ -#define BITP_ROM_SYSCTRL_CGU_CTL 4 /* access CGU_CTL register */ -#define BITP_ROM_SYSCTRL_CGU_RTNSTAT 2 /* Update structure STAT field upon error */ -#define BITP_ROM_SYSCTRL_WRITE 1 /* write registers */ -#define BITP_ROM_SYSCTRL_READ 0 /* read registers */ - -#define BITM_ROM_SYSCTRL_CGU_READ (0x00000001) /* Read CGU registers */ -#define BITM_ROM_SYSCTRL_CGU_WRITE (0x00000002) /* Write registers */ -#define BITM_ROM_SYSCTRL_CGU_RTNSTAT (0x00000004) /* Update structure STAT field upon error or after a write operation */ -#define BITM_ROM_SYSCTRL_CGU_CTL (0x00000010) /* Access CGU_CTL register */ -#define BITM_ROM_SYSCTRL_CGU_STAT (0x00000020) /* Access CGU_STAT register */ -#define BITM_ROM_SYSCTRL_CGU_DIV (0x00000040) /* Access CGU_DIV register */ -#define BITM_ROM_SYSCTRL_CGU_CLKOUTSEL (0x00000080) /* Access CGU_CLKOUTSEL register */ -#define BITM_ROM_SYSCTRL_CGU_AUTODIS (0x00000800) /* Disables auto handling of UPDT and ALGN fields */ -#define BITM_ROM_SYSCTRL_DDR_READ (0x00001000) /* Reads the contents of the DDR registers and stores them into the structure */ -#define BITM_ROM_SYSCTRL_DDR_WRITE (0x00002000) /* Writes the DDR registers from the structure, only really intented for wakeup functionality and not for full DDR configuration */ -#define BITM_ROM_SYSCTRL_WUA_EN (0x00010000) /* Wakeup entry or exit opertation enable */ -#define BITM_ROM_SYSCTRL_WUA_DPMWRITE (0x00020000) /* When set indicates a restore of the PLL and DDR is to be performed otherwise a save is required */ -#define BITM_ROM_SYSCTRL_WUA_CGU (0x00040000) /* Only applicable for a PLL and DDR save operation to the DPM, saves the current settings if cleared or the contents of the structure if set */ -#define BITM_ROM_SYSCTRL_WUA_DDR (0x00080000) /* Only applicable for a PLL and DDR save operation to the DPM, saves the current settings if cleared or the contents of the structure if set */ -#define BITM_ROM_SYSCTRL_WUA_DDRDLLEN (0x00100000) /* Enables saving/restoring of the DDR DLLCTL register */ -#define BITM_ROM_SYSCTRL_WUA_OVERRIDE (0x01000000) -#define BITM_ROM_SYSCTRL_CGU_LOCKINGEN (0x10000000) /* Unlocks the CGU_CTL register */ - - -/* Structures for the syscontrol() function */ -struct STRUCT_ROM_SYSCTRL { - uint32_t ulCGU_CTL; - uint32_t ulCGU_STAT; - uint32_t ulCGU_DIV; - uint32_t ulCGU_CLKOUTSEL; - uint32_t ulWUA_Flags; - uint32_t ulWUA_BootAddr; - uint32_t ulWUA_User; - uint32_t ulDDR_CTL; - uint32_t ulDDR_CFG; - uint32_t ulDDR_TR0; - uint32_t ulDDR_TR1; - uint32_t ulDDR_TR2; - uint32_t ulDDR_MR; - uint32_t ulDDR_EMR1; - uint32_t ulDDR_EMR2; - uint32_t ulDDR_PADCTL; - uint32_t ulDDR_DLLCTL; - uint32_t ulReserved; -}; - -struct bfin_pm_data { - uint32_t magic; - uint32_t resume_addr; - uint32_t sp; -}; - -struct bfin_pm_data bf609_pm_data; - -struct STRUCT_ROM_SYSCTRL configvalues; -uint32_t dactionflags; - -#define FUNC_ROM_SYSCONTROL 0xC8000080 -__attribute__((l1_data)) -static uint32_t (* const bfrom_SysControl)(uint32_t action_flags, struct STRUCT_ROM_SYSCTRL *settings, void *reserved) = (void *)FUNC_ROM_SYSCONTROL; - -__attribute__((l1_text)) -void bfin_cpu_suspend(void) -{ - __asm__ __volatile__( \ - ".align 8;" \ - "idle;" \ - : : \ - ); -} - -__attribute__((l1_text)) -void bfin_deepsleep(unsigned long mask) -{ - uint32_t dpm0_ctl; - - bfin_write32(DPM0_WAKE_EN, 0x10); - bfin_write32(DPM0_WAKE_POL, 0x10); - dpm0_ctl = 0x00000008; - bfin_write32(DPM0_CTL, dpm0_ctl); - SSYNC(); - __asm__ __volatile__( \ - ".align 8;" \ - "idle;" \ - : : \ - ); -#ifdef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH - __asm__ __volatile__( - "R0 = 0;" - "CYCLES = R0;" - "CYCLES2 = R0;" - "R0 = SYSCFG;" - "BITSET(R0, 1);" - "SYSCFG = R0;" - : : : "R0" - ); -#endif - -} - -__attribute__((l1_text)) -void bf609_ddr_sr(void) -{ - uint32_t reg; - - reg = bfin_read_DMC0_CTL(); - reg |= 0x8; - bfin_write_DMC0_CTL(reg); - - while (!(bfin_read_DMC0_STAT() & 0x8)) - continue; -} - -__attribute__((l1_text)) -void bf609_ddr_sr_exit(void) -{ - uint32_t reg; - while (!(bfin_read_DMC0_STAT() & 0x1)) - continue; - - reg = bfin_read_DMC0_CTL(); - reg &= ~0x8; - bfin_write_DMC0_CTL(reg); - - while ((bfin_read_DMC0_STAT() & 0x8)) - continue; -} - -__attribute__((l1_text)) -void bfin_hibernate_syscontrol(void) -{ - configvalues.ulWUA_Flags = (0xAD000000 | BITM_ROM_WUA_EN - | BITM_ROM_WUA_CGU | BITM_ROM_WUA_DDR | BITM_ROM_WUA_DDRDLLEN); - - dactionflags = (BITM_ROM_SYSCTRL_WUA_EN - | BITM_ROM_SYSCTRL_WUA_DPMWRITE | BITM_ROM_SYSCTRL_WUA_CGU - | BITM_ROM_SYSCTRL_WUA_DDR | BITM_ROM_SYSCTRL_WUA_DDRDLLEN); - - bfrom_SysControl(dactionflags, &configvalues, NULL); - - bfin_write32(DPM0_RESTORE5, bfin_read32(DPM0_RESTORE5) | 4); -} - -#ifndef CONFIG_BF60x -# define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) -#else -# define SIC_SYSIRQ(irq) ((irq) - IVG15) -#endif -void bfin_hibernate(unsigned long mask) -{ - bfin_write32(DPM0_WAKE_EN, 0x10); - bfin_write32(DPM0_WAKE_POL, 0x10); - bfin_write32(DPM0_PGCNTR, 0x0000FFFF); - bfin_write32(DPM0_HIB_DIS, 0xFFFF); - - printk(KERN_DEBUG "hibernate: restore %x pgcnt %x\n", bfin_read32(DPM0_RESTORE0), bfin_read32(DPM0_PGCNTR)); - - bf609_hibernate(); -} - -void bf609_cpu_pm_enter(suspend_state_t state) -{ - int error; - unsigned long wakeup = 0; - unsigned long wakeup_pol = 0; - -#ifdef CONFIG_PM_BFIN_WAKE_PA15 - wakeup |= PA15WE; -# if CONFIG_PM_BFIN_WAKE_PA15_POL - wakeup_pol |= PA15WE; -# endif -#endif - -#ifdef CONFIG_PM_BFIN_WAKE_PB15 - wakeup |= PB15WE; -# if CONFIG_PM_BFIN_WAKE_PA15_POL - wakeup_pol |= PB15WE; -# endif -#endif - -#ifdef CONFIG_PM_BFIN_WAKE_PC15 - wakeup |= PC15WE; -# if CONFIG_PM_BFIN_WAKE_PC15_POL - wakeup_pol |= PC15WE; -# endif -#endif - -#ifdef CONFIG_PM_BFIN_WAKE_PD06 - wakeup |= PD06WE; -# if CONFIG_PM_BFIN_WAKE_PD06_POL - wakeup_pol |= PD06WE; -# endif -#endif - -#ifdef CONFIG_PM_BFIN_WAKE_PE12 - wakeup |= PE12WE; -# if CONFIG_PM_BFIN_WAKE_PE12_POL - wakeup_pol |= PE12WE; -# endif -#endif - -#ifdef CONFIG_PM_BFIN_WAKE_PG04 - wakeup |= PG04WE; -# if CONFIG_PM_BFIN_WAKE_PG04_POL - wakeup_pol |= PG04WE; -# endif -#endif - -#ifdef CONFIG_PM_BFIN_WAKE_PG13 - wakeup |= PG13WE; -# if CONFIG_PM_BFIN_WAKE_PG13_POL - wakeup_pol |= PG13WE; -# endif -#endif - -#ifdef CONFIG_PM_BFIN_WAKE_USB - wakeup |= USBWE; -# if CONFIG_PM_BFIN_WAKE_USB_POL - wakeup_pol |= USBWE; -# endif -#endif - - error = irq_set_irq_wake(255, 1); - if(error < 0) - printk(KERN_DEBUG "Unable to get irq wake\n"); - error = irq_set_irq_wake(231, 1); - if (error < 0) - printk(KERN_DEBUG "Unable to get irq wake\n"); - - if (state == PM_SUSPEND_STANDBY) - bfin_deepsleep(wakeup); - else { - bfin_hibernate(wakeup); - } -} - -int bf609_cpu_pm_prepare(void) -{ - return 0; -} - -void bf609_cpu_pm_finish(void) -{ - -} - -static struct bfin_cpu_pm_fns bf609_cpu_pm = { - .enter = bf609_cpu_pm_enter, - .prepare = bf609_cpu_pm_prepare, - .finish = bf609_cpu_pm_finish, -}; - -static irqreturn_t test_isr(int irq, void *dev_id) -{ - printk(KERN_DEBUG "gpio irq %d\n", irq); - return IRQ_HANDLED; -} - -static irqreturn_t dpm0_isr(int irq, void *dev_id) -{ - uint32_t wake_stat; - - wake_stat = bfin_read32(DPM0_WAKE_STAT); - printk(KERN_DEBUG "enter %s wake stat %08x\n", __func__, wake_stat); - - bfin_write32(DPM0_WAKE_STAT, wake_stat); - return IRQ_HANDLED; -} - -static int __init bf609_init_pm(void) -{ - int irq; - int error; - -#if CONFIG_PM_BFIN_WAKE_PE12 - irq = gpio_to_irq(GPIO_PE12); - if (irq < 0) { - error = irq; - printk(KERN_DEBUG "Unable to get irq number for GPIO %d, error %d\n", - GPIO_PE12, error); - } - - error = request_irq(irq, test_isr, IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND, "gpiope12", NULL); - if(error < 0) - printk(KERN_DEBUG "Unable to get irq\n"); -#endif - - error = request_irq(IRQ_CGU_EVT, dpm0_isr, IRQF_NO_SUSPEND, "cgu0 event", NULL); - if(error < 0) - printk(KERN_DEBUG "Unable to get irq\n"); - - error = request_irq(IRQ_DPM, dpm0_isr, IRQF_NO_SUSPEND, "dpm0 event", NULL); - if (error < 0) - printk(KERN_DEBUG "Unable to get irq\n"); - - bfin_cpu_pm = &bf609_cpu_pm; - return 0; -} - -late_initcall(bf609_init_pm); diff --git a/trunk/arch/blackfin/mach-common/Makefile b/trunk/arch/blackfin/mach-common/Makefile index 75f0ba29ebb9..ff299f24aba0 100644 --- a/trunk/arch/blackfin/mach-common/Makefile +++ b/trunk/arch/blackfin/mach-common/Makefile @@ -6,10 +6,7 @@ obj-y := \ cache.o cache-c.o entry.o head.o \ interrupt.o arch_checks.o ints-priority.o -obj-$(CONFIG_PM) += pm.o -ifneq ($(CONFIG_BF60x),y) -obj-$(CONFIG_PM) += dpmc_modes.o -endif +obj-$(CONFIG_PM) += pm.o dpmc_modes.o obj-$(CONFIG_CPU_FREQ) += cpufreq.o obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o obj-$(CONFIG_SMP) += smp.o diff --git a/trunk/arch/blackfin/mach-common/clock.h b/trunk/arch/blackfin/mach-common/clock.h deleted file mode 100644 index 645ff460a1f2..000000000000 --- a/trunk/arch/blackfin/mach-common/clock.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __MACH_COMMON_CLKDEV_H -#define __MACH_COMMON_CLKDEV_H - -#include - -struct clk_ops { - unsigned long (*get_rate)(struct clk *clk); - unsigned long (*round_rate)(struct clk *clk, unsigned long rate); - int (*set_rate)(struct clk *clk, unsigned long rate); - int (*enable)(struct clk *clk); - int (*disable)(struct clk *clk); -}; - -struct clk { - const char *name; - unsigned long rate; - spinlock_t lock; - u32 flags; - const struct clk_ops *ops; - const struct params *params; - void __iomem *reg; - u32 mask; - u32 shift; -}; - -#endif - diff --git a/trunk/arch/blackfin/mach-common/clocks-init.c b/trunk/arch/blackfin/mach-common/clocks-init.c index 7ad2407d1571..d5cfe611b778 100644 --- a/trunk/arch/blackfin/mach-common/clocks-init.c +++ b/trunk/arch/blackfin/mach-common/clocks-init.c @@ -15,121 +15,10 @@ #include #include -#ifdef CONFIG_BF60x -#define CSEL_P 0 -#define S0SEL_P 5 -#define SYSSEL_P 8 -#define S1SEL_P 13 -#define DSEL_P 16 -#define OSEL_P 22 -#define ALGN_P 29 -#define UPDT_P 30 -#define LOCK_P 31 - -#define CGU_CTL_VAL ((CONFIG_VCO_MULT << 8) | CLKIN_HALF) -#define CGU_DIV_VAL \ - ((CONFIG_CCLK_DIV << CSEL_P) | \ - (CONFIG_SCLK_DIV << SYSSEL_P) | \ - (CONFIG_SCLK0_DIV << S0SEL_P) | \ - (CONFIG_SCLK1_DIV << S1SEL_P) | \ - (CONFIG_DCLK_DIV << DSEL_P)) - -#define CONFIG_BFIN_DCLK (((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_DCLK_DIV) / 1000000) -#if ((CONFIG_BFIN_DCLK != 125) && \ - (CONFIG_BFIN_DCLK != 133) && (CONFIG_BFIN_DCLK != 150) && \ - (CONFIG_BFIN_DCLK != 166) && (CONFIG_BFIN_DCLK != 200) && \ - (CONFIG_BFIN_DCLK != 225) && (CONFIG_BFIN_DCLK != 250)) -#error "DCLK must be in (125, 133, 150, 166, 200, 225, 250)MHz" -#endif -struct ddr_config { - u32 ddr_clk; - u32 dmc_ddrctl; - u32 dmc_ddrcfg; - u32 dmc_ddrtr0; - u32 dmc_ddrtr1; - u32 dmc_ddrtr2; - u32 dmc_ddrmr; - u32 dmc_ddrmr1; -}; - -struct ddr_config ddr_config_table[] __attribute__((section(".data_l1"))) = { - [0] = { - .ddr_clk = 125, - .dmc_ddrctl = 0x00000904, - .dmc_ddrcfg = 0x00000422, - .dmc_ddrtr0 = 0x20705212, - .dmc_ddrtr1 = 0x201003CF, - .dmc_ddrtr2 = 0x00320107, - .dmc_ddrmr = 0x00000422, - .dmc_ddrmr1 = 0x4, - }, - [1] = { - .ddr_clk = 133, - .dmc_ddrctl = 0x00000904, - .dmc_ddrcfg = 0x00000422, - .dmc_ddrtr0 = 0x20806313, - .dmc_ddrtr1 = 0x2013040D, - .dmc_ddrtr2 = 0x00320108, - .dmc_ddrmr = 0x00000632, - .dmc_ddrmr1 = 0x4, - }, - [2] = { - .ddr_clk = 150, - .dmc_ddrctl = 0x00000904, - .dmc_ddrcfg = 0x00000422, - .dmc_ddrtr0 = 0x20A07323, - .dmc_ddrtr1 = 0x20160492, - .dmc_ddrtr2 = 0x00320209, - .dmc_ddrmr = 0x00000632, - .dmc_ddrmr1 = 0x4, - }, - [3] = { - .ddr_clk = 166, - .dmc_ddrctl = 0x00000904, - .dmc_ddrcfg = 0x00000422, - .dmc_ddrtr0 = 0x20A07323, - .dmc_ddrtr1 = 0x2016050E, - .dmc_ddrtr2 = 0x00320209, - .dmc_ddrmr = 0x00000632, - .dmc_ddrmr1 = 0x4, - }, - [4] = { - .ddr_clk = 200, - .dmc_ddrctl = 0x00000904, - .dmc_ddrcfg = 0x00000422, - .dmc_ddrtr0 = 0x20a07323, - .dmc_ddrtr1 = 0x2016050f, - .dmc_ddrtr2 = 0x00320509, - .dmc_ddrmr = 0x00000632, - .dmc_ddrmr1 = 0x4, - }, - [5] = { - .ddr_clk = 225, - .dmc_ddrctl = 0x00000904, - .dmc_ddrcfg = 0x00000422, - .dmc_ddrtr0 = 0x20E0A424, - .dmc_ddrtr1 = 0x302006DB, - .dmc_ddrtr2 = 0x0032020D, - .dmc_ddrmr = 0x00000842, - .dmc_ddrmr1 = 0x4, - }, - [6] = { - .ddr_clk = 250, - .dmc_ddrctl = 0x00000904, - .dmc_ddrcfg = 0x00000422, - .dmc_ddrtr0 = 0x20E0A424, - .dmc_ddrtr1 = 0x3020079E, - .dmc_ddrtr2 = 0x0032020D, - .dmc_ddrmr = 0x00000842, - .dmc_ddrmr1 = 0x4, - }, -}; -#else #define SDGCTL_WIDTH (1 << 31) /* SDRAM external data path width */ #define PLL_CTL_VAL \ (((CONFIG_VCO_MULT & 63) << 9) | CLKIN_HALF | \ - (PLL_BYPASS << 8) | (ANOMALY_05000305 ? 0 : 0x8000)) -#endif + (PLL_BYPASS << 8) | (ANOMALY_05000305 ? 0 : 0x8000)) __attribute__((l1_text)) static void do_sync(void) @@ -144,44 +33,6 @@ void init_clocks(void) * in the middle of reprogramming things, and that'll screw us up. * For example, any automatic DMAs left by U-Boot for splash screens. */ - -#ifdef CONFIG_BF60x - int i, dlldatacycle, dll_ctl; - bfin_write32(CGU0_DIV, CGU_DIV_VAL); - bfin_write32(CGU0_CTL, CGU_CTL_VAL); - while ((bfin_read32(CGU0_STAT) & 0x8) || !(bfin_read32(CGU0_STAT) & 0x4)) - continue; - - bfin_write32(CGU0_DIV, CGU_DIV_VAL | (1 << UPDT_P)); - while (bfin_read32(CGU0_STAT) & (1 << 3)) - continue; - - for (i = 0; i < 7; i++) { - if (ddr_config_table[i].ddr_clk == CONFIG_BFIN_DCLK) { - bfin_write_DDR0_CFG(ddr_config_table[i].dmc_ddrcfg); - bfin_write_DDR0_TR0(ddr_config_table[i].dmc_ddrtr0); - bfin_write_DDR0_TR1(ddr_config_table[i].dmc_ddrtr1); - bfin_write_DDR0_TR2(ddr_config_table[i].dmc_ddrtr2); - bfin_write_DDR0_MR(ddr_config_table[i].dmc_ddrmr); - bfin_write_DDR0_EMR1(ddr_config_table[i].dmc_ddrmr1); - bfin_write_DDR0_CTL(ddr_config_table[i].dmc_ddrctl); - break; - } - } - - do_sync(); - while (!(bfin_read_DDR0_STAT() & 0x4)) - continue; - - dlldatacycle = (bfin_read_DDR0_STAT() & 0x00f00000) >> 20; - dll_ctl = bfin_read_DDR0_DLLCTL(); - dll_ctl &= 0x0ff; - bfin_write_DDR0_DLLCTL(dll_ctl | (dlldatacycle << 8)); - - do_sync(); - while (!(bfin_read_DDR0_STAT() & 0x2000)) - continue; -#else size_t i; for (i = 0; i < MAX_DMA_CHANNELS; ++i) { struct dma_register *dma = dma_io_base_addr[i]; @@ -239,9 +90,7 @@ void init_clocks(void) #ifdef CONFIG_MEM_EBIU_DDRQUE bfin_write_EBIU_DDRQUE(CONFIG_MEM_EBIU_DDRQUE); #endif -#endif #endif do_sync(); bfin_read16(0); - } diff --git a/trunk/arch/blackfin/mach-common/cpufreq.c b/trunk/arch/blackfin/mach-common/cpufreq.c index 6e87dc13f6bf..2e6eefd812f4 100644 --- a/trunk/arch/blackfin/mach-common/cpufreq.c +++ b/trunk/arch/blackfin/mach-common/cpufreq.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -18,7 +17,6 @@ #include #include - /* this is the table of CCLK frequencies, in Hz */ /* .index is the entry in the auxiliary dpm_state_table[] */ static struct cpufreq_frequency_table bfin_freq_table[] = { @@ -69,22 +67,12 @@ static void __init bfin_init_tables(unsigned long cclk, unsigned long sclk) #else min_cclk = sclk; #endif - -#ifndef CONFIG_BF60x csel = ((bfin_read_PLL_DIV() & CSEL) >> 4); -#else - csel = bfin_read32(CGU0_DIV) & 0x1F; -#endif for (index = 0; (cclk >> index) >= min_cclk && csel <= 3; index++, csel++) { bfin_freq_table[index].frequency = cclk >> index; -#ifndef CONFIG_BF60x dpm_state_table[index].csel = csel << 4; /* Shift now into PLL_DIV bitpos */ dpm_state_table[index].tscale = (TIME_SCALE / (1 << csel)) - 1; -#else - dpm_state_table[index].csel = csel; - dpm_state_table[index].tscale = TIME_SCALE >> index; -#endif pr_debug("cpufreq: freq:%d csel:0x%x tscale:%d\n", bfin_freq_table[index].frequency, @@ -111,34 +99,14 @@ static unsigned int bfin_getfreq_khz(unsigned int cpu) return get_cclk() / 1000; } -#ifdef CONFIG_BF60x -unsigned long cpu_set_cclk(int cpu, unsigned long new) -{ - struct clk *clk; - int ret; - - clk = clk_get(NULL, "CCLK"); - if (IS_ERR(clk)) - return -ENODEV; - - ret = clk_set_rate(clk, new); - clk_put(clk); - return ret; -} -#endif - static int bfin_target(struct cpufreq_policy *poli, unsigned int target_freq, unsigned int relation) { -#ifndef CONFIG_BF60x - unsigned int plldiv; -#endif - unsigned int index, cpu; + unsigned int index, plldiv, cpu; unsigned long flags, cclk_hz; struct cpufreq_freqs freqs; static unsigned long lpj_ref; static unsigned int lpj_ref_freq; - int ret = 0; #if defined(CONFIG_CYCLES_CLOCKSOURCE) cycles_t cycles; @@ -166,17 +134,9 @@ static int bfin_target(struct cpufreq_policy *poli, cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); if (cpu == CPUFREQ_CPU) { flags = hard_local_irq_save(); -#ifndef CONFIG_BF60x plldiv = (bfin_read_PLL_DIV() & SSEL) | dpm_state_table[index].csel; bfin_write_PLL_DIV(plldiv); -#else - ret = cpu_set_cclk(cpu, freqs.new * 1000); - if (ret != 0) { - pr_debug("cpufreq set freq failed %d\n", ret); - break; - } -#endif on_each_cpu(bfin_adjust_core_timer, &index, 1); #if defined(CONFIG_CYCLES_CLOCKSOURCE) cycles = get_cycles(); @@ -201,7 +161,7 @@ static int bfin_target(struct cpufreq_policy *poli, } pr_debug("cpufreq: done\n"); - return ret; + return 0; } static int bfin_verify_speed(struct cpufreq_policy *policy) @@ -209,7 +169,7 @@ static int bfin_verify_speed(struct cpufreq_policy *policy) return cpufreq_frequency_table_verify(policy, bfin_freq_table); } -static int __bfin_cpu_init(struct cpufreq_policy *policy) +static int __init __bfin_cpu_init(struct cpufreq_policy *policy) { unsigned long cclk, sclk; diff --git a/trunk/arch/blackfin/mach-common/dpmc_modes.S b/trunk/arch/blackfin/mach-common/dpmc_modes.S index de99f3aac2c5..1c534d298de4 100644 --- a/trunk/arch/blackfin/mach-common/dpmc_modes.S +++ b/trunk/arch/blackfin/mach-common/dpmc_modes.S @@ -10,6 +10,7 @@ #include .section .l1.text + ENTRY(_sleep_mode) [--SP] = (R7:4, P5:3); [--SP] = RETS; @@ -42,9 +43,6 @@ ENTRY(_sleep_mode) BITCLR (R7, 5); w[p0] = R7.L; IDLE; - - bfin_init_pm_bench_cycles; - call _test_pll_locked; RETS = [SP++]; @@ -60,13 +58,12 @@ ENDPROC(_sleep_mode) * * We accept just one argument -- the value to write to VR_CTL. */ - ENTRY(_hibernate_mode) /* Save/setup the regs we need early for minor pipeline optimization */ R4 = R0; - P3.H = hi(VR_CTL); P3.L = lo(VR_CTL); + /* Disable all wakeup sources */ R0 = IWR_DISABLE_ALL; R1 = IWR_DISABLE_ALL; @@ -77,9 +74,6 @@ ENTRY(_hibernate_mode) /* Finally, we climb into our cave to hibernate */ W[P3] = R4.L; - - bfin_init_pm_bench_cycles; - CLI R2; IDLE; .Lforever: @@ -164,8 +158,6 @@ ENTRY(_sleep_deeper) SSYNC; IDLE; - bfin_init_pm_bench_cycles; - call _test_pll_locked; P0.H = hi(PLL_DIV); @@ -284,10 +276,327 @@ ENTRY(_test_pll_locked) ENDPROC(_test_pll_locked) .section .text + +#define PM_REG0 R7 +#define PM_REG1 R6 +#define PM_REG2 R5 +#define PM_REG3 R4 +#define PM_REG4 R3 +#define PM_REG5 R2 +#define PM_REG6 R1 +#define PM_REG7 R0 +#define PM_REG8 P5 +#define PM_REG9 P4 +#define PM_REG10 P3 +#define PM_REG11 P2 +#define PM_REG12 P1 +#define PM_REG13 P0 + +#define PM_REGSET0 R7:7 +#define PM_REGSET1 R7:6 +#define PM_REGSET2 R7:5 +#define PM_REGSET3 R7:4 +#define PM_REGSET4 R7:3 +#define PM_REGSET5 R7:2 +#define PM_REGSET6 R7:1 +#define PM_REGSET7 R7:0 +#define PM_REGSET8 R7:0, P5:5 +#define PM_REGSET9 R7:0, P5:4 +#define PM_REGSET10 R7:0, P5:3 +#define PM_REGSET11 R7:0, P5:2 +#define PM_REGSET12 R7:0, P5:1 +#define PM_REGSET13 R7:0, P5:0 + +#define _PM_PUSH(n, x, w, base) PM_REG##n = w[FP + ((x) - (base))]; +#define _PM_POP(n, x, w, base) w[FP + ((x) - (base))] = PM_REG##n; +#define PM_PUSH_SYNC(n) [--sp] = (PM_REGSET##n); +#define PM_POP_SYNC(n) (PM_REGSET##n) = [sp++]; +#define PM_PUSH(n, x) PM_REG##n = [FP++]; +#define PM_POP(n, x) [FP--] = PM_REG##n; +#define PM_CORE_PUSH(n, x) _PM_PUSH(n, x, , COREMMR_BASE) +#define PM_CORE_POP(n, x) _PM_POP(n, x, , COREMMR_BASE) +#define PM_SYS_PUSH(n, x) _PM_PUSH(n, x, , SYSMMR_BASE) +#define PM_SYS_POP(n, x) _PM_POP(n, x, , SYSMMR_BASE) +#define PM_SYS_PUSH16(n, x) _PM_PUSH(n, x, w, SYSMMR_BASE) +#define PM_SYS_POP16(n, x) _PM_POP(n, x, w, SYSMMR_BASE) + ENTRY(_do_hibernate) - bfin_cpu_reg_save; - bfin_sys_mmr_save; - bfin_core_mmr_save; + /* + * Save the core regs early so we can blow them away when + * saving/restoring MMR states + */ + [--sp] = (R7:0, P5:0); + [--sp] = fp; + [--sp] = usp; + + [--sp] = i0; + [--sp] = i1; + [--sp] = i2; + [--sp] = i3; + + [--sp] = m0; + [--sp] = m1; + [--sp] = m2; + [--sp] = m3; + + [--sp] = l0; + [--sp] = l1; + [--sp] = l2; + [--sp] = l3; + + [--sp] = b0; + [--sp] = b1; + [--sp] = b2; + [--sp] = b3; + [--sp] = a0.x; + [--sp] = a0.w; + [--sp] = a1.x; + [--sp] = a1.w; + + [--sp] = LC0; + [--sp] = LC1; + [--sp] = LT0; + [--sp] = LT1; + [--sp] = LB0; + [--sp] = LB1; + + /* We can't push RETI directly as that'll change IPEND[4] */ + r7 = RETI; + [--sp] = RETS; + [--sp] = ASTAT; + [--sp] = CYCLES; + [--sp] = CYCLES2; + [--sp] = SYSCFG; + [--sp] = RETX; + [--sp] = SEQSTAT; + [--sp] = r7; + + /* Save first func arg in M3 */ + M3 = R0; + + /* Save system MMRs */ + FP.H = hi(SYSMMR_BASE); + FP.L = lo(SYSMMR_BASE); + +#ifdef SIC_IMASK0 + PM_SYS_PUSH(0, SIC_IMASK0) + PM_SYS_PUSH(1, SIC_IMASK1) +# ifdef SIC_IMASK2 + PM_SYS_PUSH(2, SIC_IMASK2) +# endif +#else + PM_SYS_PUSH(0, SIC_IMASK) +#endif +#ifdef SIC_IAR0 + PM_SYS_PUSH(3, SIC_IAR0) + PM_SYS_PUSH(4, SIC_IAR1) + PM_SYS_PUSH(5, SIC_IAR2) +#endif +#ifdef SIC_IAR3 + PM_SYS_PUSH(6, SIC_IAR3) +#endif +#ifdef SIC_IAR4 + PM_SYS_PUSH(7, SIC_IAR4) + PM_SYS_PUSH(8, SIC_IAR5) + PM_SYS_PUSH(9, SIC_IAR6) +#endif +#ifdef SIC_IAR7 + PM_SYS_PUSH(10, SIC_IAR7) +#endif +#ifdef SIC_IAR8 + PM_SYS_PUSH(11, SIC_IAR8) + PM_SYS_PUSH(12, SIC_IAR9) + PM_SYS_PUSH(13, SIC_IAR10) +#endif + PM_PUSH_SYNC(13) +#ifdef SIC_IAR11 + PM_SYS_PUSH(0, SIC_IAR11) +#endif + +#ifdef SIC_IWR + PM_SYS_PUSH(1, SIC_IWR) +#endif +#ifdef SIC_IWR0 + PM_SYS_PUSH(1, SIC_IWR0) +#endif +#ifdef SIC_IWR1 + PM_SYS_PUSH(2, SIC_IWR1) +#endif +#ifdef SIC_IWR2 + PM_SYS_PUSH(3, SIC_IWR2) +#endif + +#ifdef PINT0_ASSIGN + PM_SYS_PUSH(4, PINT0_MASK_SET) + PM_SYS_PUSH(5, PINT1_MASK_SET) + PM_SYS_PUSH(6, PINT2_MASK_SET) + PM_SYS_PUSH(7, PINT3_MASK_SET) + PM_SYS_PUSH(8, PINT0_ASSIGN) + PM_SYS_PUSH(9, PINT1_ASSIGN) + PM_SYS_PUSH(10, PINT2_ASSIGN) + PM_SYS_PUSH(11, PINT3_ASSIGN) + PM_SYS_PUSH(12, PINT0_INVERT_SET) + PM_SYS_PUSH(13, PINT1_INVERT_SET) + PM_PUSH_SYNC(13) + PM_SYS_PUSH(0, PINT2_INVERT_SET) + PM_SYS_PUSH(1, PINT3_INVERT_SET) + PM_SYS_PUSH(2, PINT0_EDGE_SET) + PM_SYS_PUSH(3, PINT1_EDGE_SET) + PM_SYS_PUSH(4, PINT2_EDGE_SET) + PM_SYS_PUSH(5, PINT3_EDGE_SET) +#endif + + PM_SYS_PUSH16(6, SYSCR) + + PM_SYS_PUSH16(7, EBIU_AMGCTL) + PM_SYS_PUSH(8, EBIU_AMBCTL0) + PM_SYS_PUSH(9, EBIU_AMBCTL1) +#ifdef EBIU_FCTL + PM_SYS_PUSH(10, EBIU_MBSCTL) + PM_SYS_PUSH(11, EBIU_MODE) + PM_SYS_PUSH(12, EBIU_FCTL) + PM_PUSH_SYNC(12) +#else + PM_PUSH_SYNC(9) +#endif + + /* Save Core MMRs */ + I0.H = hi(COREMMR_BASE); + I0.L = lo(COREMMR_BASE); + I1 = I0; + I2 = I0; + I3 = I0; + B0 = I0; + B1 = I0; + B2 = I0; + B3 = I0; + I1.L = lo(DCPLB_ADDR0); + I2.L = lo(DCPLB_DATA0); + I3.L = lo(ICPLB_ADDR0); + B0.L = lo(ICPLB_DATA0); + B1.L = lo(EVT2); + B2.L = lo(IMASK); + B3.L = lo(TCNTL); + + /* DCPLB Addr */ + FP = I1; + PM_PUSH(0, DCPLB_ADDR0) + PM_PUSH(1, DCPLB_ADDR1) + PM_PUSH(2, DCPLB_ADDR2) + PM_PUSH(3, DCPLB_ADDR3) + PM_PUSH(4, DCPLB_ADDR4) + PM_PUSH(5, DCPLB_ADDR5) + PM_PUSH(6, DCPLB_ADDR6) + PM_PUSH(7, DCPLB_ADDR7) + PM_PUSH(8, DCPLB_ADDR8) + PM_PUSH(9, DCPLB_ADDR9) + PM_PUSH(10, DCPLB_ADDR10) + PM_PUSH(11, DCPLB_ADDR11) + PM_PUSH(12, DCPLB_ADDR12) + PM_PUSH(13, DCPLB_ADDR13) + PM_PUSH_SYNC(13) + PM_PUSH(0, DCPLB_ADDR14) + PM_PUSH(1, DCPLB_ADDR15) + + /* DCPLB Data */ + FP = I2; + PM_PUSH(2, DCPLB_DATA0) + PM_PUSH(3, DCPLB_DATA1) + PM_PUSH(4, DCPLB_DATA2) + PM_PUSH(5, DCPLB_DATA3) + PM_PUSH(6, DCPLB_DATA4) + PM_PUSH(7, DCPLB_DATA5) + PM_PUSH(8, DCPLB_DATA6) + PM_PUSH(9, DCPLB_DATA7) + PM_PUSH(10, DCPLB_DATA8) + PM_PUSH(11, DCPLB_DATA9) + PM_PUSH(12, DCPLB_DATA10) + PM_PUSH(13, DCPLB_DATA11) + PM_PUSH_SYNC(13) + PM_PUSH(0, DCPLB_DATA12) + PM_PUSH(1, DCPLB_DATA13) + PM_PUSH(2, DCPLB_DATA14) + PM_PUSH(3, DCPLB_DATA15) + + /* ICPLB Addr */ + FP = I3; + PM_PUSH(4, ICPLB_ADDR0) + PM_PUSH(5, ICPLB_ADDR1) + PM_PUSH(6, ICPLB_ADDR2) + PM_PUSH(7, ICPLB_ADDR3) + PM_PUSH(8, ICPLB_ADDR4) + PM_PUSH(9, ICPLB_ADDR5) + PM_PUSH(10, ICPLB_ADDR6) + PM_PUSH(11, ICPLB_ADDR7) + PM_PUSH(12, ICPLB_ADDR8) + PM_PUSH(13, ICPLB_ADDR9) + PM_PUSH_SYNC(13) + PM_PUSH(0, ICPLB_ADDR10) + PM_PUSH(1, ICPLB_ADDR11) + PM_PUSH(2, ICPLB_ADDR12) + PM_PUSH(3, ICPLB_ADDR13) + PM_PUSH(4, ICPLB_ADDR14) + PM_PUSH(5, ICPLB_ADDR15) + + /* ICPLB Data */ + FP = B0; + PM_PUSH(6, ICPLB_DATA0) + PM_PUSH(7, ICPLB_DATA1) + PM_PUSH(8, ICPLB_DATA2) + PM_PUSH(9, ICPLB_DATA3) + PM_PUSH(10, ICPLB_DATA4) + PM_PUSH(11, ICPLB_DATA5) + PM_PUSH(12, ICPLB_DATA6) + PM_PUSH(13, ICPLB_DATA7) + PM_PUSH_SYNC(13) + PM_PUSH(0, ICPLB_DATA8) + PM_PUSH(1, ICPLB_DATA9) + PM_PUSH(2, ICPLB_DATA10) + PM_PUSH(3, ICPLB_DATA11) + PM_PUSH(4, ICPLB_DATA12) + PM_PUSH(5, ICPLB_DATA13) + PM_PUSH(6, ICPLB_DATA14) + PM_PUSH(7, ICPLB_DATA15) + + /* Event Vectors */ + FP = B1; + PM_PUSH(8, EVT2) + PM_PUSH(9, EVT3) + FP += 4; /* EVT4 */ + PM_PUSH(10, EVT5) + PM_PUSH(11, EVT6) + PM_PUSH(12, EVT7) + PM_PUSH(13, EVT8) + PM_PUSH_SYNC(13) + PM_PUSH(0, EVT9) + PM_PUSH(1, EVT10) + PM_PUSH(2, EVT11) + PM_PUSH(3, EVT12) + PM_PUSH(4, EVT13) + PM_PUSH(5, EVT14) + PM_PUSH(6, EVT15) + + /* CEC */ + FP = B2; + PM_PUSH(7, IMASK) + FP += 4; /* IPEND */ + PM_PUSH(8, ILAT) + PM_PUSH(9, IPRIO) + + /* Core Timer */ + FP = B3; + PM_PUSH(10, TCNTL) + PM_PUSH(11, TPERIOD) + PM_PUSH(12, TSCALE) + PM_PUSH(13, TCOUNT) + PM_PUSH_SYNC(13) + + /* Misc non-contiguous registers */ + FP = I0; + PM_CORE_PUSH(0, DMEM_CONTROL); + PM_CORE_PUSH(1, IMEM_CONTROL); + PM_CORE_PUSH(2, TBUFCTL); + PM_PUSH_SYNC(2) /* Setup args to hibernate mode early for pipeline optimization */ R0 = M3; @@ -309,9 +618,274 @@ ENTRY(_do_hibernate) .Lpm_resume_here: - bfin_core_mmr_restore; - bfin_sys_mmr_restore; - bfin_cpu_reg_restore; + /* Restore Core MMRs */ + I0.H = hi(COREMMR_BASE); + I0.L = lo(COREMMR_BASE); + I1 = I0; + I2 = I0; + I3 = I0; + B0 = I0; + B1 = I0; + B2 = I0; + B3 = I0; + I1.L = lo(DCPLB_ADDR15); + I2.L = lo(DCPLB_DATA15); + I3.L = lo(ICPLB_ADDR15); + B0.L = lo(ICPLB_DATA15); + B1.L = lo(EVT15); + B2.L = lo(IPRIO); + B3.L = lo(TCOUNT); + + /* Misc non-contiguous registers */ + FP = I0; + PM_POP_SYNC(2) + PM_CORE_POP(2, TBUFCTL) + PM_CORE_POP(1, IMEM_CONTROL) + PM_CORE_POP(0, DMEM_CONTROL) + + /* Core Timer */ + PM_POP_SYNC(13) + FP = B3; + PM_POP(13, TCOUNT) + PM_POP(12, TSCALE) + PM_POP(11, TPERIOD) + PM_POP(10, TCNTL) + + /* CEC */ + FP = B2; + PM_POP(9, IPRIO) + PM_POP(8, ILAT) + FP += -4; /* IPEND */ + PM_POP(7, IMASK) + + /* Event Vectors */ + FP = B1; + PM_POP(6, EVT15) + PM_POP(5, EVT14) + PM_POP(4, EVT13) + PM_POP(3, EVT12) + PM_POP(2, EVT11) + PM_POP(1, EVT10) + PM_POP(0, EVT9) + PM_POP_SYNC(13) + PM_POP(13, EVT8) + PM_POP(12, EVT7) + PM_POP(11, EVT6) + PM_POP(10, EVT5) + FP += -4; /* EVT4 */ + PM_POP(9, EVT3) + PM_POP(8, EVT2) + + /* ICPLB Data */ + FP = B0; + PM_POP(7, ICPLB_DATA15) + PM_POP(6, ICPLB_DATA14) + PM_POP(5, ICPLB_DATA13) + PM_POP(4, ICPLB_DATA12) + PM_POP(3, ICPLB_DATA11) + PM_POP(2, ICPLB_DATA10) + PM_POP(1, ICPLB_DATA9) + PM_POP(0, ICPLB_DATA8) + PM_POP_SYNC(13) + PM_POP(13, ICPLB_DATA7) + PM_POP(12, ICPLB_DATA6) + PM_POP(11, ICPLB_DATA5) + PM_POP(10, ICPLB_DATA4) + PM_POP(9, ICPLB_DATA3) + PM_POP(8, ICPLB_DATA2) + PM_POP(7, ICPLB_DATA1) + PM_POP(6, ICPLB_DATA0) + + /* ICPLB Addr */ + FP = I3; + PM_POP(5, ICPLB_ADDR15) + PM_POP(4, ICPLB_ADDR14) + PM_POP(3, ICPLB_ADDR13) + PM_POP(2, ICPLB_ADDR12) + PM_POP(1, ICPLB_ADDR11) + PM_POP(0, ICPLB_ADDR10) + PM_POP_SYNC(13) + PM_POP(13, ICPLB_ADDR9) + PM_POP(12, ICPLB_ADDR8) + PM_POP(11, ICPLB_ADDR7) + PM_POP(10, ICPLB_ADDR6) + PM_POP(9, ICPLB_ADDR5) + PM_POP(8, ICPLB_ADDR4) + PM_POP(7, ICPLB_ADDR3) + PM_POP(6, ICPLB_ADDR2) + PM_POP(5, ICPLB_ADDR1) + PM_POP(4, ICPLB_ADDR0) + + /* DCPLB Data */ + FP = I2; + PM_POP(3, DCPLB_DATA15) + PM_POP(2, DCPLB_DATA14) + PM_POP(1, DCPLB_DATA13) + PM_POP(0, DCPLB_DATA12) + PM_POP_SYNC(13) + PM_POP(13, DCPLB_DATA11) + PM_POP(12, DCPLB_DATA10) + PM_POP(11, DCPLB_DATA9) + PM_POP(10, DCPLB_DATA8) + PM_POP(9, DCPLB_DATA7) + PM_POP(8, DCPLB_DATA6) + PM_POP(7, DCPLB_DATA5) + PM_POP(6, DCPLB_DATA4) + PM_POP(5, DCPLB_DATA3) + PM_POP(4, DCPLB_DATA2) + PM_POP(3, DCPLB_DATA1) + PM_POP(2, DCPLB_DATA0) + + /* DCPLB Addr */ + FP = I1; + PM_POP(1, DCPLB_ADDR15) + PM_POP(0, DCPLB_ADDR14) + PM_POP_SYNC(13) + PM_POP(13, DCPLB_ADDR13) + PM_POP(12, DCPLB_ADDR12) + PM_POP(11, DCPLB_ADDR11) + PM_POP(10, DCPLB_ADDR10) + PM_POP(9, DCPLB_ADDR9) + PM_POP(8, DCPLB_ADDR8) + PM_POP(7, DCPLB_ADDR7) + PM_POP(6, DCPLB_ADDR6) + PM_POP(5, DCPLB_ADDR5) + PM_POP(4, DCPLB_ADDR4) + PM_POP(3, DCPLB_ADDR3) + PM_POP(2, DCPLB_ADDR2) + PM_POP(1, DCPLB_ADDR1) + PM_POP(0, DCPLB_ADDR0) + + /* Restore System MMRs */ + FP.H = hi(SYSMMR_BASE); + FP.L = lo(SYSMMR_BASE); + +#ifdef EBIU_FCTL + PM_POP_SYNC(12) + PM_SYS_POP(12, EBIU_FCTL) + PM_SYS_POP(11, EBIU_MODE) + PM_SYS_POP(10, EBIU_MBSCTL) +#else + PM_POP_SYNC(9) +#endif + PM_SYS_POP(9, EBIU_AMBCTL1) + PM_SYS_POP(8, EBIU_AMBCTL0) + PM_SYS_POP16(7, EBIU_AMGCTL) + + PM_SYS_POP16(6, SYSCR) + +#ifdef PINT0_ASSIGN + PM_SYS_POP(5, PINT3_EDGE_SET) + PM_SYS_POP(4, PINT2_EDGE_SET) + PM_SYS_POP(3, PINT1_EDGE_SET) + PM_SYS_POP(2, PINT0_EDGE_SET) + PM_SYS_POP(1, PINT3_INVERT_SET) + PM_SYS_POP(0, PINT2_INVERT_SET) + PM_POP_SYNC(13) + PM_SYS_POP(13, PINT1_INVERT_SET) + PM_SYS_POP(12, PINT0_INVERT_SET) + PM_SYS_POP(11, PINT3_ASSIGN) + PM_SYS_POP(10, PINT2_ASSIGN) + PM_SYS_POP(9, PINT1_ASSIGN) + PM_SYS_POP(8, PINT0_ASSIGN) + PM_SYS_POP(7, PINT3_MASK_SET) + PM_SYS_POP(6, PINT2_MASK_SET) + PM_SYS_POP(5, PINT1_MASK_SET) + PM_SYS_POP(4, PINT0_MASK_SET) +#endif + +#ifdef SIC_IWR2 + PM_SYS_POP(3, SIC_IWR2) +#endif +#ifdef SIC_IWR1 + PM_SYS_POP(2, SIC_IWR1) +#endif +#ifdef SIC_IWR0 + PM_SYS_POP(1, SIC_IWR0) +#endif +#ifdef SIC_IWR + PM_SYS_POP(1, SIC_IWR) +#endif + +#ifdef SIC_IAR11 + PM_SYS_POP(0, SIC_IAR11) +#endif + PM_POP_SYNC(13) +#ifdef SIC_IAR8 + PM_SYS_POP(13, SIC_IAR10) + PM_SYS_POP(12, SIC_IAR9) + PM_SYS_POP(11, SIC_IAR8) +#endif +#ifdef SIC_IAR7 + PM_SYS_POP(10, SIC_IAR7) +#endif +#ifdef SIC_IAR6 + PM_SYS_POP(9, SIC_IAR6) + PM_SYS_POP(8, SIC_IAR5) + PM_SYS_POP(7, SIC_IAR4) +#endif +#ifdef SIC_IAR3 + PM_SYS_POP(6, SIC_IAR3) +#endif +#ifdef SIC_IAR0 + PM_SYS_POP(5, SIC_IAR2) + PM_SYS_POP(4, SIC_IAR1) + PM_SYS_POP(3, SIC_IAR0) +#endif +#ifdef SIC_IMASK0 +# ifdef SIC_IMASK2 + PM_SYS_POP(2, SIC_IMASK2) +# endif + PM_SYS_POP(1, SIC_IMASK1) + PM_SYS_POP(0, SIC_IMASK0) +#else + PM_SYS_POP(0, SIC_IMASK) +#endif + + /* Restore Core Registers */ + RETI = [sp++]; + SEQSTAT = [sp++]; + RETX = [sp++]; + SYSCFG = [sp++]; + CYCLES2 = [sp++]; + CYCLES = [sp++]; + ASTAT = [sp++]; + RETS = [sp++]; + + LB1 = [sp++]; + LB0 = [sp++]; + LT1 = [sp++]; + LT0 = [sp++]; + LC1 = [sp++]; + LC0 = [sp++]; + + a1.w = [sp++]; + a1.x = [sp++]; + a0.w = [sp++]; + a0.x = [sp++]; + b3 = [sp++]; + b2 = [sp++]; + b1 = [sp++]; + b0 = [sp++]; + + l3 = [sp++]; + l2 = [sp++]; + l1 = [sp++]; + l0 = [sp++]; + + m3 = [sp++]; + m2 = [sp++]; + m1 = [sp++]; + m0 = [sp++]; + + i3 = [sp++]; + i2 = [sp++]; + i1 = [sp++]; + i0 = [sp++]; + + usp = [sp++]; + fp = [sp++]; + (R7:0, P5:0) = [sp++]; [--sp] = RETI; /* Clear Global Interrupt Disable */ SP += 4; diff --git a/trunk/arch/blackfin/mach-common/entry.S b/trunk/arch/blackfin/mach-common/entry.S index 80aa2535e2c9..4698a9800522 100644 --- a/trunk/arch/blackfin/mach-common/entry.S +++ b/trunk/arch/blackfin/mach-common/entry.S @@ -1141,8 +1141,7 @@ ENTRY(_schedule_and_signal_from_int) sti r0; /* finish the userspace "atomic" functions for it */ - r1.l = lo(FIXED_CODE_END); - r1.h = hi(FIXED_CODE_END); + r1 = FIXED_CODE_END; r2 = [sp + PT_PC]; cc = r1 <= r2; if cc jump .Lresume_userspace (bp); @@ -1377,7 +1376,7 @@ END(_ex_table) ENTRY(_sys_call_table) .long _sys_restart_syscall /* 0 */ .long _sys_exit - .long _sys_ni_syscall /* fork */ + .long _sys_fork .long _sys_read .long _sys_write .long _sys_open /* 5 */ diff --git a/trunk/arch/blackfin/mach-common/head.S b/trunk/arch/blackfin/mach-common/head.S index 31515f0146f9..8b4d98854403 100644 --- a/trunk/arch/blackfin/mach-common/head.S +++ b/trunk/arch/blackfin/mach-common/head.S @@ -210,12 +210,14 @@ ENDPROC(__start) ENTRY(_real_start) /* Enable nested interrupts */ [--sp] = reti; + /* watchdog off for now */ p0.l = lo(WDOG_CTL); p0.h = hi(WDOG_CTL); r0 = 0xAD6(z); w[p0] = r0; ssync; + /* Pass the u-boot arguments to the global value command line */ R0 = R7; call _cmdline_init; diff --git a/trunk/arch/blackfin/mach-common/ints-priority.c b/trunk/arch/blackfin/mach-common/ints-priority.c index 2729cba715b0..332dace6af34 100644 --- a/trunk/arch/blackfin/mach-common/ints-priority.c +++ b/trunk/arch/blackfin/mach-common/ints-priority.c @@ -16,8 +16,6 @@ #include #include #include -#include -#include #ifdef CONFIG_IPIPE #include #endif @@ -27,11 +25,7 @@ #include #include -#ifndef CONFIG_BF60x -# define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) -#else -# define SIC_SYSIRQ(irq) ((irq) - IVG15) -#endif +#define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) /* * NOTES: @@ -56,7 +50,6 @@ unsigned long bfin_sic_iwr[3]; /* Up to 3 SIC_IWRx registers */ unsigned vr_wakeup; #endif -#ifndef CONFIG_BF60x static struct ivgx { /* irq number for request_irq, available in mach-bf5xx/irq.h */ unsigned int irqno; @@ -85,8 +78,7 @@ static void __init search_IAR(void) for (irqN = 0; irqN < NR_PERI_INTS; irqN += 4) { int irqn; - u32 iar = - bfin_read32((unsigned long *)SIC_IAR0 + + u32 iar = bfin_read32((unsigned long *)SIC_IAR0 + #if defined(CONFIG_BF51x) || defined(CONFIG_BF52x) || \ defined(CONFIG_BF538) || defined(CONFIG_BF539) ((irqN % 32) >> 3) + ((irqN / 32) * ((SIC_IAR4 - SIC_IAR0) / 4)) @@ -94,6 +86,7 @@ static void __init search_IAR(void) (irqN >> 3) #endif ); + for (irqn = irqN; irqn < irqN + 4; ++irqn) { int iar_shift = (irqn & 7) * 4; if (ivg == (0xf & (iar >> iar_shift))) { @@ -106,11 +99,11 @@ static void __init search_IAR(void) } } } -#endif /* * This is for core internal IRQs */ + void bfin_ack_noop(struct irq_data *d) { /* Dummy function. */ @@ -143,21 +136,21 @@ static void bfin_core_unmask_irq(struct irq_data *d) void bfin_internal_mask_irq(unsigned int irq) { unsigned long flags = hard_local_irq_save(); -#ifndef CONFIG_BF60x + #ifdef SIC_IMASK0 unsigned mask_bank = SIC_SYSIRQ(irq) / 32; unsigned mask_bit = SIC_SYSIRQ(irq) % 32; bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) & - ~(1 << mask_bit)); -# if defined(CONFIG_SMP) || defined(CONFIG_ICC) + ~(1 << mask_bit)); +# ifdef CONFIG_SMP bfin_write_SICB_IMASK(mask_bank, bfin_read_SICB_IMASK(mask_bank) & - ~(1 << mask_bit)); + ~(1 << mask_bit)); # endif #else bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & - ~(1 << SIC_SYSIRQ(irq))); -#endif /* end of SIC_IMASK0 */ + ~(1 << SIC_SYSIRQ(irq))); #endif + hard_local_irq_restore(flags); } @@ -167,7 +160,7 @@ static void bfin_internal_mask_irq_chip(struct irq_data *d) } #ifdef CONFIG_SMP -void bfin_internal_unmask_irq_affinity(unsigned int irq, +static void bfin_internal_unmask_irq_affinity(unsigned int irq, const struct cpumask *affinity) #else void bfin_internal_unmask_irq(unsigned int irq) @@ -175,7 +168,6 @@ void bfin_internal_unmask_irq(unsigned int irq) { unsigned long flags = hard_local_irq_save(); -#ifndef CONFIG_BF60x #ifdef SIC_IMASK0 unsigned mask_bank = SIC_SYSIRQ(irq) / 32; unsigned mask_bit = SIC_SYSIRQ(irq) % 32; @@ -183,239 +175,22 @@ void bfin_internal_unmask_irq(unsigned int irq) if (cpumask_test_cpu(0, affinity)) # endif bfin_write_SIC_IMASK(mask_bank, - bfin_read_SIC_IMASK(mask_bank) | - (1 << mask_bit)); + bfin_read_SIC_IMASK(mask_bank) | + (1 << mask_bit)); # ifdef CONFIG_SMP if (cpumask_test_cpu(1, affinity)) bfin_write_SICB_IMASK(mask_bank, - bfin_read_SICB_IMASK(mask_bank) | - (1 << mask_bit)); + bfin_read_SICB_IMASK(mask_bank) | + (1 << mask_bit)); # endif #else bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | - (1 << SIC_SYSIRQ(irq))); -#endif + (1 << SIC_SYSIRQ(irq))); #endif - hard_local_irq_restore(flags); -} - -#ifdef CONFIG_BF60x -static void bfin_sec_preflow_handler(struct irq_data *d) -{ - unsigned long flags = hard_local_irq_save(); - unsigned int sid = SIC_SYSIRQ(d->irq); - - bfin_write_SEC_SCI(0, SEC_CSID, sid); - - hard_local_irq_restore(flags); -} - -static void bfin_sec_mask_ack_irq(struct irq_data *d) -{ - unsigned long flags = hard_local_irq_save(); - unsigned int sid = SIC_SYSIRQ(d->irq); - - bfin_write_SEC_SCI(0, SEC_CSID, sid); hard_local_irq_restore(flags); } -static void bfin_sec_unmask_irq(struct irq_data *d) -{ - unsigned long flags = hard_local_irq_save(); - unsigned int sid = SIC_SYSIRQ(d->irq); - - bfin_write32(SEC_END, sid); - - hard_local_irq_restore(flags); -} - -static void bfin_sec_enable_ssi(unsigned int sid) -{ - unsigned long flags = hard_local_irq_save(); - uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); - - reg_sctl |= SEC_SCTL_SRC_EN; - bfin_write_SEC_SCTL(sid, reg_sctl); - - hard_local_irq_restore(flags); -} - -static void bfin_sec_disable_ssi(unsigned int sid) -{ - unsigned long flags = hard_local_irq_save(); - uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); - - reg_sctl &= ((uint32_t)~SEC_SCTL_SRC_EN); - bfin_write_SEC_SCTL(sid, reg_sctl); - - hard_local_irq_restore(flags); -} - -static void bfin_sec_set_ssi_coreid(unsigned int sid, unsigned int coreid) -{ - unsigned long flags = hard_local_irq_save(); - uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); - - reg_sctl &= ((uint32_t)~SEC_SCTL_CTG); - bfin_write_SEC_SCTL(sid, reg_sctl | ((coreid << 20) & SEC_SCTL_CTG)); - - hard_local_irq_restore(flags); -} - -static void bfin_sec_enable_sci(unsigned int sid) -{ - unsigned long flags = hard_local_irq_save(); - uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); - - if (sid == SIC_SYSIRQ(IRQ_WATCH0)) - reg_sctl |= SEC_SCTL_FAULT_EN; - else - reg_sctl |= SEC_SCTL_INT_EN; - bfin_write_SEC_SCTL(sid, reg_sctl); - - hard_local_irq_restore(flags); -} - -static void bfin_sec_disable_sci(unsigned int sid) -{ - unsigned long flags = hard_local_irq_save(); - uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); - - reg_sctl &= ((uint32_t)~SEC_SCTL_INT_EN); - bfin_write_SEC_SCTL(sid, reg_sctl); - - hard_local_irq_restore(flags); -} - -static void bfin_sec_enable(struct irq_data *d) -{ - unsigned long flags = hard_local_irq_save(); - unsigned int sid = SIC_SYSIRQ(d->irq); - - bfin_sec_enable_sci(sid); - bfin_sec_enable_ssi(sid); - - hard_local_irq_restore(flags); -} - -static void bfin_sec_disable(struct irq_data *d) -{ - unsigned long flags = hard_local_irq_save(); - unsigned int sid = SIC_SYSIRQ(d->irq); - - bfin_sec_disable_sci(sid); - bfin_sec_disable_ssi(sid); - - hard_local_irq_restore(flags); -} - -static void bfin_sec_raise_irq(unsigned int sid) -{ - unsigned long flags = hard_local_irq_save(); - - bfin_write32(SEC_RAISE, sid); - - hard_local_irq_restore(flags); -} - -static void init_software_driven_irq(void) -{ - bfin_sec_set_ssi_coreid(34, 0); - bfin_sec_set_ssi_coreid(35, 1); - bfin_sec_set_ssi_coreid(36, 0); - bfin_sec_set_ssi_coreid(37, 1); -} - -void bfin_sec_resume(void) -{ - bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET); - udelay(100); - bfin_write_SEC_GCTL(SEC_GCTL_EN); - bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); -} - -void handle_sec_sfi_fault(uint32_t gstat) -{ - -} - -void handle_sec_sci_fault(uint32_t gstat) -{ - uint32_t core_id; - uint32_t cstat; - - core_id = gstat & SEC_GSTAT_SCI; - cstat = bfin_read_SEC_SCI(core_id, SEC_CSTAT); - if (cstat & SEC_CSTAT_ERR) { - switch (cstat & SEC_CSTAT_ERRC) { - case SEC_CSTAT_ACKERR: - printk(KERN_DEBUG "sec ack err\n"); - break; - default: - printk(KERN_DEBUG "sec sci unknow err\n"); - } - } - -} - -void handle_sec_ssi_fault(uint32_t gstat) -{ - uint32_t sid; - uint32_t sstat; - - sid = gstat & SEC_GSTAT_SID; - sstat = bfin_read_SEC_SSTAT(sid); - -} - -void handle_sec_fault(unsigned int irq, struct irq_desc *desc) -{ - uint32_t sec_gstat; - - raw_spin_lock(&desc->lock); - - sec_gstat = bfin_read32(SEC_GSTAT); - if (sec_gstat & SEC_GSTAT_ERR) { - - switch (sec_gstat & SEC_GSTAT_ERRC) { - case 0: - handle_sec_sfi_fault(sec_gstat); - break; - case SEC_GSTAT_SCIERR: - handle_sec_sci_fault(sec_gstat); - break; - case SEC_GSTAT_SSIERR: - handle_sec_ssi_fault(sec_gstat); - break; - } - - - } - - raw_spin_unlock(&desc->lock); -} - -static int sec_suspend(void) -{ - return 0; -} - -static void sec_resume(void) -{ - bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET); - udelay(100); - bfin_write_SEC_GCTL(SEC_GCTL_EN); - bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); -} - -static struct syscore_ops sec_pm_syscore_ops = { - .suspend = sec_suspend, - .resume = sec_resume, -}; - -#endif - #ifdef CONFIG_SMP static void bfin_internal_unmask_irq_chip(struct irq_data *d) { @@ -437,7 +212,7 @@ static void bfin_internal_unmask_irq_chip(struct irq_data *d) } #endif -#if defined(CONFIG_PM) && !defined(CONFIG_BF60x) +#ifdef CONFIG_PM int bfin_internal_set_wake(unsigned int irq, unsigned int state) { u32 bank, bit, wakeup = 0; @@ -496,20 +271,22 @@ static int bfin_internal_set_wake_chip(struct irq_data *d, unsigned int state) return bfin_internal_set_wake(d->irq, state); } #else -# define bfin_internal_set_wake(irq, state) # define bfin_internal_set_wake_chip NULL #endif static struct irq_chip bfin_core_irqchip = { .name = "CORE", + .irq_ack = bfin_ack_noop, .irq_mask = bfin_core_mask_irq, .irq_unmask = bfin_core_unmask_irq, }; static struct irq_chip bfin_internal_irqchip = { .name = "INTN", + .irq_ack = bfin_ack_noop, .irq_mask = bfin_internal_mask_irq_chip, .irq_unmask = bfin_internal_unmask_irq_chip, + .irq_mask_ack = bfin_internal_mask_irq_chip, .irq_disable = bfin_internal_mask_irq_chip, .irq_enable = bfin_internal_unmask_irq_chip, #ifdef CONFIG_SMP @@ -518,18 +295,6 @@ static struct irq_chip bfin_internal_irqchip = { .irq_set_wake = bfin_internal_set_wake_chip, }; -#ifdef CONFIG_BF60x -static struct irq_chip bfin_sec_irqchip = { - .name = "SEC", - .irq_mask_ack = bfin_sec_mask_ack_irq, - .irq_mask = bfin_sec_mask_ack_irq, - .irq_unmask = bfin_sec_unmask_irq, - .irq_eoi = bfin_sec_unmask_irq, - .irq_disable = bfin_sec_disable, - .irq_enable = bfin_sec_enable, -}; -#endif - void bfin_handle_irq(unsigned irq) { #ifdef CONFIG_IPIPE @@ -631,6 +396,8 @@ int bfin_mac_status_set_wake(struct irq_data *d, unsigned int state) static struct irq_chip bfin_mac_status_irqchip = { .name = "MACST", + .irq_ack = bfin_ack_noop, + .irq_mask_ack = bfin_mac_status_mask_irq, .irq_mask = bfin_mac_status_mask_irq, .irq_unmask = bfin_mac_status_unmask_irq, .irq_set_wake = bfin_mac_status_set_wake, @@ -654,15 +421,15 @@ void bfin_demux_mac_status_irq(unsigned int int_err_irq, } else { bfin_mac_status_ack_irq(irq); pr_debug("IRQ %d:" - " MASKED MAC ERROR INTERRUPT ASSERTED\n", - irq); + " MASKED MAC ERROR INTERRUPT ASSERTED\n", + irq); } } else printk(KERN_ERR - "%s : %s : LINE %d :\nIRQ ?: MAC ERROR" - " INTERRUPT ASSERTED BUT NO SOURCE FOUND" - "(EMAC_SYSTAT=0x%X)\n", - __func__, __FILE__, __LINE__, status); + "%s : %s : LINE %d :\nIRQ ?: MAC ERROR" + " INTERRUPT ASSERTED BUT NO SOURCE FOUND" + "(EMAC_SYSTAT=0x%X)\n", + __func__, __FILE__, __LINE__, status); } #endif @@ -816,7 +583,7 @@ static void bfin_demux_gpio_block(unsigned int irq) } void bfin_demux_gpio_irq(unsigned int inta_irq, - struct irq_desc *desc) + struct irq_desc *desc) { unsigned int irq; @@ -868,15 +635,9 @@ void bfin_demux_gpio_irq(unsigned int inta_irq, #else -# ifndef CONFIG_BF60x #define NR_PINT_SYS_IRQS 4 -#define NR_PINTS 160 -# else -#define NR_PINT_SYS_IRQS 6 -#define NR_PINTS 112 -#endif - #define NR_PINT_BITS 32 +#define NR_PINTS 160 #define IRQ_NOT_AVAIL 0xFF #define PINT_2_BANK(x) ((x) >> 5) @@ -891,13 +652,8 @@ static struct bfin_pint_regs * const pint[NR_PINT_SYS_IRQS] = { (struct bfin_pint_regs *)PINT1_MASK_SET, (struct bfin_pint_regs *)PINT2_MASK_SET, (struct bfin_pint_regs *)PINT3_MASK_SET, -#ifdef CONFIG_BF60x - (struct bfin_pint_regs *)PINT4_MASK_SET, - (struct bfin_pint_regs *)PINT5_MASK_SET, -#endif }; -#ifndef CONFIG_BF60x inline unsigned int get_irq_base(u32 bank, u8 bmap) { unsigned int irq_base; @@ -910,16 +666,6 @@ inline unsigned int get_irq_base(u32 bank, u8 bmap) return irq_base; } -#else -inline unsigned int get_irq_base(u32 bank, u8 bmap) -{ - unsigned int irq_base; - - irq_base = IRQ_PA0 + bank * 16 + bmap * 16; - - return irq_base; -} -#endif /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ void init_pint_lut(void) @@ -1108,14 +854,6 @@ static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state) case 1: pint_irq = IRQ_PINT1; break; -#ifdef CONFIG_BF60x - case 4: - pint_irq = IRQ_PINT4; - break; - case 5: - pint_irq = IRQ_PINT5; - break; -#endif default: return -EINVAL; } @@ -1129,21 +867,10 @@ static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state) #endif void bfin_demux_gpio_irq(unsigned int inta_irq, - struct irq_desc *desc) + struct irq_desc *desc) { u32 bank, pint_val; u32 request, irq; - u32 level_mask; - int umask = 0; - struct irq_chip *chip = irq_desc_get_chip(desc); - - if (chip->irq_mask_ack) { - chip->irq_mask_ack(&desc->irq_data); - } else { - chip->irq_mask(&desc->irq_data); - if (chip->irq_ack) - chip->irq_ack(&desc->irq_data); - } switch (inta_irq) { case IRQ_PINT0: @@ -1158,14 +885,6 @@ void bfin_demux_gpio_irq(unsigned int inta_irq, case IRQ_PINT1: bank = 1; break; -#ifdef CONFIG_BF60x - case IRQ_PINT4: - bank = 4; - break; - case IRQ_PINT5: - bank = 5; - break; -#endif default: return; } @@ -1174,23 +893,15 @@ void bfin_demux_gpio_irq(unsigned int inta_irq, request = pint[bank]->request; - level_mask = pint[bank]->edge_set & request; - while (request) { if (request & 1) { irq = pint2irq_lut[pint_val] + SYS_IRQS; - if (level_mask & PINT_BIT(pint_val)) { - umask = 1; - chip->irq_unmask(&desc->irq_data); - } bfin_handle_irq(irq); } pint_val++; request >>= 1; } - if (!umask) - chip->irq_unmask(&desc->irq_data); } #endif @@ -1240,7 +951,6 @@ int __init init_arch_irq(void) int irq; unsigned long ilat = 0; -#ifndef CONFIG_BF60x /* Disable all the peripheral intrs - page 4-29 HW Ref manual */ #ifdef SIC_IMASK0 bfin_write_SIC_IMASK0(SIC_UNMASK_ALL); @@ -1248,16 +958,13 @@ int __init init_arch_irq(void) # ifdef SIC_IMASK2 bfin_write_SIC_IMASK2(SIC_UNMASK_ALL); # endif -# if defined(CONFIG_SMP) || defined(CONFIG_ICC) +# ifdef CONFIG_SMP bfin_write_SICB_IMASK0(SIC_UNMASK_ALL); bfin_write_SICB_IMASK1(SIC_UNMASK_ALL); # endif #else bfin_write_SIC_IMASK(SIC_UNMASK_ALL); #endif -#else /* CONFIG_BF60x */ - bfin_write_SEC_GCTL(SEC_GCTL_RESET); -#endif local_irq_disable(); @@ -1267,10 +974,6 @@ int __init init_arch_irq(void) pint[1]->assign = CONFIG_PINT1_ASSIGN; pint[2]->assign = CONFIG_PINT2_ASSIGN; pint[3]->assign = CONFIG_PINT3_ASSIGN; -# ifdef CONFIG_BF60x - pint[4]->assign = CONFIG_PINT4_ASSIGN; - pint[5]->assign = CONFIG_PINT5_ASSIGN; -# endif # endif /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ init_pint_lut(); @@ -1283,7 +986,6 @@ int __init init_arch_irq(void) irq_set_chip(irq, &bfin_internal_irqchip); switch (irq) { -#ifndef CONFIG_BF60x #if BFIN_GPIO_PINT case IRQ_PINT0: case IRQ_PINT1: @@ -1313,13 +1015,12 @@ int __init init_arch_irq(void) bfin_demux_mac_status_irq); break; #endif -#if defined(CONFIG_SMP) || defined(CONFIG_ICC) +#ifdef CONFIG_SMP case IRQ_SUPPLE_0: case IRQ_SUPPLE_1: irq_set_handler(irq, handle_percpu_irq); break; #endif -#endif #ifdef CONFIG_TICKSOURCE_CORETMR case IRQ_CORETMR: @@ -1349,8 +1050,7 @@ int __init init_arch_irq(void) init_mach_irq(); -#ifndef CONFIG_BF60x -#if (defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) && !defined(CONFIG_BF60x) +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++) irq_set_chip_and_handler(irq, &bfin_mac_status_irqchip, handle_level_irq); @@ -1360,28 +1060,7 @@ int __init init_arch_irq(void) irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++) irq_set_chip_and_handler(irq, &bfin_gpio_irqchip, handle_level_irq); -#else - for (irq = BFIN_IRQ(0); irq <= SYS_IRQS; irq++) { - if (irq < CORE_IRQS) { - irq_set_chip(irq, &bfin_sec_irqchip); - __irq_set_handler(irq, handle_sec_fault, 0, NULL); - } else if (irq >= BFIN_IRQ(21) && irq <= BFIN_IRQ(26)) { - irq_set_chip(irq, &bfin_sec_irqchip); - irq_set_chained_handler(irq, bfin_demux_gpio_irq); - } else if (irq >= BFIN_IRQ(34) && irq <= BFIN_IRQ(37)) { - irq_set_chip(irq, &bfin_sec_irqchip); - irq_set_handler(irq, handle_percpu_irq); - } else { - irq_set_chip_and_handler(irq, &bfin_sec_irqchip, - handle_fasteoi_irq); - __irq_set_preflow_handler(irq, bfin_sec_preflow_handler); - } - } - for (irq = GPIO_IRQ_BASE; - irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++) - irq_set_chip_and_handler(irq, &bfin_gpio_irqchip, - handle_level_irq); -#endif + bfin_write_IMASK(0); CSYNC(); ilat = bfin_read_ILAT(); @@ -1393,17 +1072,14 @@ int __init init_arch_irq(void) /* IMASK=xxx is equivalent to STI xx or bfin_irq_flags=xx, * local_irq_enable() */ -#ifndef CONFIG_BF60x program_IAR(); /* Therefore it's better to setup IARs before interrupts enabled */ search_IAR(); /* Enable interrupts IVG7-15 */ bfin_irq_flags |= IMASK_IVG15 | - IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | - IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; - - bfin_sti(bfin_irq_flags); + IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | + IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; /* This implicitly covers ANOMALY_05000171 * Boot-ROM code modifies SICA_IWRx wakeup registers @@ -1427,23 +1103,7 @@ int __init init_arch_irq(void) #else bfin_write_SIC_IWR(IWR_DISABLE_ALL); #endif -#else /* CONFIG_BF60x */ - /* Enable interrupts IVG7-15 */ - bfin_irq_flags |= IMASK_IVG15 | - IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | - IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; - - bfin_write_SEC_FCTL(SEC_FCTL_EN | SEC_FCTL_SYSRST_EN | SEC_FCTL_FLTIN_EN); - bfin_sec_enable_sci(SIC_SYSIRQ(IRQ_WATCH0)); - bfin_sec_enable_ssi(SIC_SYSIRQ(IRQ_WATCH0)); - bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET); - udelay(100); - bfin_write_SEC_GCTL(SEC_GCTL_EN); - bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); - init_software_driven_irq(); - register_syscore_ops(&sec_pm_syscore_ops); -#endif return 0; } @@ -1452,14 +1112,13 @@ __attribute__((l1_text)) #endif static int vec_to_irq(int vec) { -#ifndef CONFIG_BF60x struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst; struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop; unsigned long sic_status[3]; -#endif + if (likely(vec == EVT_IVTMR_P)) return IRQ_CORETMR; -#ifndef CONFIG_BF60x + #ifdef SIC_ISR sic_status[0] = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR(); #else @@ -1488,10 +1147,6 @@ static int vec_to_irq(int vec) #endif return ivg->irqno; } -#else - /* for bf60x read */ - return BFIN_IRQ(bfin_read_SEC_SCI(0, SEC_CSID)); -#endif /* end of CONFIG_BF60x */ } #ifdef CONFIG_DO_IRQ_L1 diff --git a/trunk/arch/blackfin/mach-common/pm.c b/trunk/arch/blackfin/mach-common/pm.c index ca6655e0d653..3c648a077e75 100644 --- a/trunk/arch/blackfin/mach-common/pm.c +++ b/trunk/arch/blackfin/mach-common/pm.c @@ -19,33 +19,20 @@ #include #include #include -#include -#ifdef CONFIG_BF60x -struct bfin_cpu_pm_fns *bfin_cpu_pm; -#endif void bfin_pm_suspend_standby_enter(void) { -#ifndef CONFIG_BF60x bfin_pm_standby_setup(); -#endif -#ifdef CONFIG_BF60x - bfin_cpu_pm->enter(PM_SUSPEND_STANDBY); -#else -# ifdef CONFIG_PM_BFIN_SLEEP_DEEPER +#ifdef CONFIG_PM_BFIN_SLEEP_DEEPER sleep_deeper(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); -# else +#else sleep_mode(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); -# endif #endif -#ifndef CONFIG_BF60x bfin_pm_standby_restore(); -#endif -#ifndef CONFIG_BF60x #ifdef SIC_IWR0 bfin_write_SIC_IWR0(IWR_DISABLE_ALL); # ifdef SIC_IWR1 @@ -65,8 +52,6 @@ void bfin_pm_suspend_standby_enter(void) #else bfin_write_SIC_IWR(IWR_DISABLE_ALL); #endif - -#endif } int bf53x_suspend_l1_mem(unsigned char *memptr) @@ -98,13 +83,10 @@ int bf53x_resume_l1_mem(unsigned char *memptr) } #if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK) -# ifdef CONFIG_BF60x -__attribute__((l1_text)) -# endif static void flushinv_all_dcache(void) { - register u32 way, bank, subbank, set; - register u32 status, addr; + u32 way, bank, subbank, set; + u32 status, addr; u32 dmem_ctl = bfin_read_DMEM_CONTROL(); for (bank = 0; bank < 2; ++bank) { @@ -151,7 +133,6 @@ int bfin_pm_suspend_mem_enter(void) return -ENOMEM; } -#ifndef CONFIG_BF60x wakeup = bfin_read_VR_CTL() & ~FREQ; wakeup |= SCKELOW; @@ -160,7 +141,6 @@ int bfin_pm_suspend_mem_enter(void) #endif #ifdef CONFIG_PM_BFIN_WAKE_GP wakeup |= GPWE; -#endif #endif ret = blackfin_dma_suspend(); @@ -179,11 +159,7 @@ int bfin_pm_suspend_mem_enter(void) _disable_icplb(); bf53x_suspend_l1_mem(memptr); -#ifndef CONFIG_BF60x do_hibernate(wakeup | vr_wakeup); /* See you later! */ -#else - bfin_cpu_pm->enter(PM_SUSPEND_MEM); -#endif bf53x_resume_l1_mem(memptr); @@ -247,39 +223,9 @@ static int bfin_pm_enter(suspend_state_t state) return 0; } -#ifdef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH -void bfin_pm_end(void) -{ - u32 cycle, cycle2; - u64 usec64; - u32 usec; - - __asm__ __volatile__ ( - "1: %0 = CYCLES2\n" - "%1 = CYCLES\n" - "%2 = CYCLES2\n" - "CC = %2 == %0\n" - "if ! CC jump 1b\n" - : "=d,a" (cycle2), "=d,a" (cycle), "=d,a" (usec) : : "CC" - ); - - usec64 = ((u64)cycle2 << 32) + cycle; - do_div(usec64, get_cclk() / USEC_PER_SEC); - usec = usec64; - if (usec == 0) - usec = 1; - - pr_info("PM: resume of kernel completes after %ld msec %03ld usec\n", - usec / USEC_PER_MSEC, usec % USEC_PER_MSEC); -} -#endif - static const struct platform_suspend_ops bfin_pm_ops = { .enter = bfin_pm_enter, .valid = bfin_pm_valid, -#ifdef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH - .end = bfin_pm_end, -#endif }; static int __init bfin_pm_init(void) diff --git a/trunk/arch/blackfin/mach-common/smp.c b/trunk/arch/blackfin/mach-common/smp.c index 00bbe672b3b3..ac8f8a43158c 100644 --- a/trunk/arch/blackfin/mach-common/smp.c +++ b/trunk/arch/blackfin/mach-common/smp.c @@ -340,10 +340,27 @@ void smp_send_stop(void) return; } -int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle) +int __cpuinit __cpu_up(unsigned int cpu) { int ret; + struct blackfin_cpudata *ci = &per_cpu(cpu_data, cpu); + struct task_struct *idle = ci->idle; + if (idle) { + free_task(idle); + idle = NULL; + } + + if (!idle) { + idle = fork_idle(cpu); + if (IS_ERR(idle)) { + printk(KERN_ERR "CPU%u: fork() failed\n", cpu); + return PTR_ERR(idle); + } + ci->idle = idle; + } else { + init_idle(idle, cpu); + } secondary_stack = task_stack_page(idle) + THREAD_SIZE; ret = platform_boot_secondary(cpu, idle); diff --git a/trunk/arch/blackfin/mm/init.c b/trunk/arch/blackfin/mm/init.c index 9cb85537bd2b..78daae084915 100644 --- a/trunk/arch/blackfin/mm/init.c +++ b/trunk/arch/blackfin/mm/init.c @@ -48,7 +48,7 @@ void __init paging_init(void) unsigned long zones_size[MAX_NR_ZONES] = { [0] = 0, - [ZONE_DMA] = (end_mem - CONFIG_PHY_RAM_BASE_ADDRESS) >> PAGE_SHIFT, + [ZONE_DMA] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT, [ZONE_NORMAL] = 0, #ifdef CONFIG_HIGHMEM [ZONE_HIGHMEM] = 0, @@ -60,8 +60,7 @@ void __init paging_init(void) pr_debug("free_area_init -> start_mem is %#lx virtual_end is %#lx\n", PAGE_ALIGN(memory_start), end_mem); - free_area_init_node(0, zones_size, - CONFIG_PHY_RAM_BASE_ADDRESS >> PAGE_SHIFT, NULL); + free_area_init(zones_size); } asmlinkage void __init init_pda(void) @@ -76,6 +75,9 @@ asmlinkage void __init init_pda(void) valid pointers to it. */ memset(&cpu_pda[cpu], 0, sizeof(cpu_pda[cpu])); + cpu_pda[0].next = &cpu_pda[1]; + cpu_pda[1].next = &cpu_pda[0]; + #ifdef CONFIG_EXCEPTION_L1_SCRATCH cpu_pda[cpu].ex_stack = (unsigned long *)(L1_SCRATCH_START + \ L1_SCRATCH_LENGTH); @@ -107,10 +109,10 @@ void __init mem_init(void) totalram_pages = free_all_bootmem(); reservedpages = 0; - for (tmp = ARCH_PFN_OFFSET; tmp < max_mapnr; tmp++) + for (tmp = 0; tmp < max_mapnr; tmp++) if (PageReserved(pfn_to_page(tmp))) reservedpages++; - freepages = max_mapnr - ARCH_PFN_OFFSET - reservedpages; + freepages = max_mapnr - reservedpages; /* do not count in kernel image between _rambase and _ramstart */ reservedpages -= (_ramstart - _rambase) >> PAGE_SHIFT; @@ -125,7 +127,7 @@ void __init mem_init(void) printk(KERN_INFO "Memory available: %luk/%luk RAM, " "(%uk init code, %uk kernel code, %uk data, %uk dma, %uk reserved)\n", - (unsigned long) freepages << (PAGE_SHIFT-10), (_ramend - CONFIG_PHY_RAM_BASE_ADDRESS) >> 10, + (unsigned long) freepages << (PAGE_SHIFT-10), _ramend >> 10, initk, codek, datak, DMA_UNCACHED_REGION >> 10, (reservedpages << (PAGE_SHIFT-10))); } diff --git a/trunk/arch/blackfin/mm/sram-alloc.c b/trunk/arch/blackfin/mm/sram-alloc.c index 342e378da1ec..29d98faa1efd 100644 --- a/trunk/arch/blackfin/mm/sram-alloc.c +++ b/trunk/arch/blackfin/mm/sram-alloc.c @@ -186,45 +186,9 @@ static void __init l1_inst_sram_init(void) #endif } -#ifdef __ADSPBF60x__ -static irqreturn_t l2_ecc_err(int irq, void *dev_id) -{ - int status; - - printk(KERN_ERR "L2 ecc error happend\n"); - status = bfin_read32(L2CTL0_STAT); - if (status & 0x1) - printk(KERN_ERR "Core channel error type:0x%x, addr:0x%x\n", - bfin_read32(L2CTL0_ET0), bfin_read32(L2CTL0_EADDR0)); - if (status & 0x2) - printk(KERN_ERR "System channel error type:0x%x, addr:0x%x\n", - bfin_read32(L2CTL0_ET1), bfin_read32(L2CTL0_EADDR1)); - - status = status >> 8; - if (status) - printk(KERN_ERR "L2 Bank%d error, addr:0x%x\n", - status, bfin_read32(L2CTL0_ERRADDR0 + status)); - - panic("L2 Ecc error"); - return IRQ_HANDLED; -} -#endif - static void __init l2_sram_init(void) { #if L2_LENGTH != 0 - -#ifdef __ADSPBF60x__ - int ret; - - ret = request_irq(IRQ_L2CTL0_ECC_ERR, l2_ecc_err, 0, "l2-ecc-err", - NULL); - if (unlikely(ret < 0)) { - printk(KERN_INFO "Fail to request l2 ecc error interrupt"); - return; - } -#endif - free_l2_sram_head.next = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); if (!free_l2_sram_head.next) { diff --git a/trunk/arch/c6x/Kconfig b/trunk/arch/c6x/Kconfig index 1f15b88b537f..1c3ccd416d50 100644 --- a/trunk/arch/c6x/Kconfig +++ b/trunk/arch/c6x/Kconfig @@ -3,7 +3,7 @@ # see Documentation/kbuild/kconfig-language.txt. # -config C6X +config TMS320C6X def_bool y select CLKDEV_LOOKUP select GENERIC_IRQ_SHOW @@ -19,12 +19,24 @@ config C6X config MMU def_bool n +config ZONE_DMA + def_bool y + config FPU def_bool n +config HIGHMEM + def_bool n + +config NUMA + def_bool n + config RWSEM_GENERIC_SPINLOCK def_bool y +config RWSEM_XCHGADD_ALGORITHM + def_bool n + config GENERIC_CALIBRATE_DELAY def_bool y diff --git a/trunk/arch/c6x/include/asm/elf.h b/trunk/arch/c6x/include/asm/elf.h index f4552db20b4a..d57865ba2c44 100644 --- a/trunk/arch/c6x/include/asm/elf.h +++ b/trunk/arch/c6x/include/asm/elf.h @@ -30,19 +30,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; */ #define elf_check_arch(x) ((x)->e_machine == EM_TI_C6000) -#define elf_check_fdpic(x) (1) -#define elf_check_const_displacement(x) (0) - -#define ELF_FDPIC_PLAT_INIT(_regs, _exec_map, _interp_map, _dynamic_addr) \ -do { \ - _regs->b4 = (_exec_map); \ - _regs->a6 = (_interp_map); \ - _regs->b6 = (_dynamic_addr); \ -} while (0) - -#define ELF_FDPIC_CORE_EFLAGS 0 - -#define ELF_CORE_COPY_FPREGS(...) 0 /* No FPU regs to copy */ +#define elf_check_const_displacement(x) (1) /* * These are used to set parameters in the core dumps. diff --git a/trunk/arch/c6x/include/asm/mmu.h b/trunk/arch/c6x/include/asm/mmu.h index 4467e770a1ce..41592bf16067 100644 --- a/trunk/arch/c6x/include/asm/mmu.h +++ b/trunk/arch/c6x/include/asm/mmu.h @@ -13,10 +13,6 @@ typedef struct { unsigned long end_brk; -#ifdef CONFIG_BINFMT_ELF_FDPIC - unsigned long exec_fdpic_loadmap; - unsigned long interp_fdpic_loadmap; -#endif } mm_context_t; #endif /* _ASM_C6X_MMU_H */ diff --git a/trunk/arch/c6x/include/asm/ptrace.h b/trunk/arch/c6x/include/asm/ptrace.h index b04ff5964258..21e8d7931fe7 100644 --- a/trunk/arch/c6x/include/asm/ptrace.h +++ b/trunk/arch/c6x/include/asm/ptrace.h @@ -97,11 +97,6 @@ #define PT_DP PT_B14 /* Data Segment Pointer (B14) */ #define PT_SP PT_B15 /* Stack Pointer (B15) */ -#define PTRACE_GETFDPIC 31 /* get the ELF fdpic loadmap address */ - -#define PTRACE_GETFDPIC_EXEC 0 /* [addr] request the executable loadmap */ -#define PTRACE_GETFDPIC_INTERP 1 /* [addr] request the interpreter loadmap */ - #ifndef __ASSEMBLY__ #ifdef _BIG_ENDIAN diff --git a/trunk/arch/c6x/include/asm/thread_info.h b/trunk/arch/c6x/include/asm/thread_info.h index 1710bcbb8d09..fd99148cda9d 100644 --- a/trunk/arch/c6x/include/asm/thread_info.h +++ b/trunk/arch/c6x/include/asm/thread_info.h @@ -20,11 +20,11 @@ #ifdef CONFIG_4KSTACKS #define THREAD_SIZE 4096 #define THREAD_SHIFT 12 -#define THREAD_SIZE_ORDER 0 +#define THREAD_ORDER 0 #else #define THREAD_SIZE 8192 #define THREAD_SHIFT 13 -#define THREAD_SIZE_ORDER 1 +#define THREAD_ORDER 1 #endif #define THREAD_START_SP (THREAD_SIZE - 8) @@ -80,6 +80,19 @@ struct thread_info *current_thread_info(void) return ti; } +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + +/* thread information allocation */ +#ifdef CONFIG_DEBUG_STACK_USAGE +#define THREAD_FLAGS (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO) +#else +#define THREAD_FLAGS (GFP_KERNEL | __GFP_NOTRACK) +#endif + +#define alloc_thread_info_node(tsk, node) \ + ((struct thread_info *)__get_free_pages(THREAD_FLAGS, THREAD_ORDER)) + +#define free_thread_info(ti) free_pages((unsigned long) (ti), THREAD_ORDER) #define get_thread_info(ti) get_task_struct((ti)->task) #define put_thread_info(ti) put_task_struct((ti)->task) #endif /* __ASSEMBLY__ */ diff --git a/trunk/arch/c6x/kernel/process.c b/trunk/arch/c6x/kernel/process.c index 45e924a636a0..7ca8c41b03cd 100644 --- a/trunk/arch/c6x/kernel/process.c +++ b/trunk/arch/c6x/kernel/process.c @@ -26,6 +26,22 @@ void (*c6x_halt)(void); extern asmlinkage void ret_from_fork(void); +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); + +/* + * Initial thread structure. + */ +union thread_union init_thread_union __init_task_data = { + INIT_THREAD_INFO(init_task) +}; + +/* + * Initial task structure. + */ +struct task_struct init_task = INIT_TASK(init_task); +EXPORT_SYMBOL(init_task); + /* * power off function, if any */ diff --git a/trunk/arch/cris/Kconfig b/trunk/arch/cris/Kconfig index 2995035812ec..b3abfb08aa5c 100644 --- a/trunk/arch/cris/Kconfig +++ b/trunk/arch/cris/Kconfig @@ -49,7 +49,6 @@ config CRIS select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_SHOW select GENERIC_IOMAP - select GENERIC_SMP_IDLE_THREAD if ETRAX_ARCH_V32 config HZ int diff --git a/trunk/arch/cris/arch-v32/kernel/smp.c b/trunk/arch/cris/arch-v32/kernel/smp.c index ebe2cb30bd11..0b99df72d2a4 100644 --- a/trunk/arch/cris/arch-v32/kernel/smp.c +++ b/trunk/arch/cris/arch-v32/kernel/smp.c @@ -108,12 +108,17 @@ void __init smp_cpus_done(unsigned int max_cpus) /* Bring one cpu online.*/ static int __init -smp_boot_one_cpu(int cpuid, struct task_struct idle) +smp_boot_one_cpu(int cpuid) { unsigned timeout; + struct task_struct *idle; cpumask_t cpu_mask; cpumask_clear(&cpu_mask); + idle = fork_idle(cpuid); + if (IS_ERR(idle)) + panic("SMP: fork failed for CPU:%d", cpuid); + task_thread_info(idle)->cpu = cpuid; /* Information to the CPU that is about to boot */ @@ -137,6 +142,9 @@ smp_boot_one_cpu(int cpuid, struct task_struct idle) barrier(); } + put_task_struct(idle); + idle = NULL; + printk(KERN_CRIT "SMP: CPU:%d is stuck.\n", cpuid); return -1; } @@ -199,9 +207,9 @@ int setup_profiling_timer(unsigned int multiplier) */ unsigned long cache_decay_ticks = 1; -int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) +int __cpuinit __cpu_up(unsigned int cpu) { - smp_boot_one_cpu(cpu, tidle); + smp_boot_one_cpu(cpu); return cpu_online(cpu) ? 0 : -ENOSYS; } diff --git a/trunk/arch/cris/include/asm/processor.h b/trunk/arch/cris/include/asm/processor.h index 8dc56ef08712..4210d72a6667 100644 --- a/trunk/arch/cris/include/asm/processor.h +++ b/trunk/arch/cris/include/asm/processor.h @@ -25,12 +25,13 @@ struct task_struct; */ #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3)) -/* THREAD_SIZE is the size of the thread_info/kernel_stack combo. +/* THREAD_SIZE is the size of the task_struct/kernel_stack combo. * normally, the stack is found by doing something like p + THREAD_SIZE * in CRIS, a page is 8192 bytes, which seems like a sane size */ + #define THREAD_SIZE PAGE_SIZE -#define THREAD_SIZE_ORDER (0) +#define KERNEL_STACK_SIZE PAGE_SIZE /* * At user->kernel entry, the pt_regs struct is stacked on the top of the kernel-stack. diff --git a/trunk/arch/cris/include/asm/thread_info.h b/trunk/arch/cris/include/asm/thread_info.h index 5b1c448df5c0..29b92884d793 100644 --- a/trunk/arch/cris/include/asm/thread_info.h +++ b/trunk/arch/cris/include/asm/thread_info.h @@ -65,6 +65,12 @@ struct thread_info { #define init_thread_info (init_thread_union.thread_info) +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR +/* thread information allocation */ +#define alloc_thread_info_node(tsk, node) \ + ((struct thread_info *) __get_free_pages(GFP_KERNEL, 1)) +#define free_thread_info(ti) free_pages((unsigned long) (ti), 1) + #endif /* !__ASSEMBLY__ */ /* diff --git a/trunk/arch/cris/kernel/process.c b/trunk/arch/cris/kernel/process.c index 66fd01728790..891dad85e8bd 100644 --- a/trunk/arch/cris/kernel/process.c +++ b/trunk/arch/cris/kernel/process.c @@ -28,6 +28,34 @@ //#define DEBUG +/* + * Initial task structure. Make this a per-architecture thing, + * because different architectures tend to have different + * alignment requirements and potentially different initial + * setup. + */ + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +/* + * Initial thread structure. + * + * We need to make sure that this is 8192-byte aligned due to the + * way process stacks are handled. This is done by having a special + * "init_task" linker map entry.. + */ +union thread_union init_thread_union __init_task_data = + { INIT_THREAD_INFO(init_task) }; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); + +EXPORT_SYMBOL(init_task); + /* * The hlt_counter, disable_hlt and enable_hlt is just here as a hook if * there would ever be a halt sequence (for power save when idle) with diff --git a/trunk/arch/frv/Makefile b/trunk/arch/frv/Makefile index 4d1b1e9baef1..7ff84575b186 100644 --- a/trunk/arch/frv/Makefile +++ b/trunk/arch/frv/Makefile @@ -81,7 +81,7 @@ ifdef CONFIG_DEBUG_INFO KBUILD_AFLAGS += -Wa,--gdwarf2 endif -head-y := arch/frv/kernel/head.o +head-y := arch/frv/kernel/head.o arch/frv/kernel/init_task.o core-y += arch/frv/kernel/ arch/frv/mm/ libs-y += arch/frv/lib/ diff --git a/trunk/arch/frv/include/asm/processor.h b/trunk/arch/frv/include/asm/processor.h index 9b1a92b73f60..81c2e271d620 100644 --- a/trunk/arch/frv/include/asm/processor.h +++ b/trunk/arch/frv/include/asm/processor.h @@ -135,6 +135,10 @@ unsigned long get_wchan(struct task_struct *p); #define KSTK_EIP(tsk) ((tsk)->thread.frame0->pc) #define KSTK_ESP(tsk) ((tsk)->thread.frame0->sp) +/* Allocation and freeing of basic task resources. */ +extern struct task_struct *alloc_task_struct_node(int node); +extern void free_task_struct(struct task_struct *p); + #define cpu_relax() barrier() /* data cache prefetch */ diff --git a/trunk/arch/frv/include/asm/thread_info.h b/trunk/arch/frv/include/asm/thread_info.h index 54ab13a0de41..92d83ea99ae5 100644 --- a/trunk/arch/frv/include/asm/thread_info.h +++ b/trunk/arch/frv/include/asm/thread_info.h @@ -21,6 +21,8 @@ #define THREAD_SIZE 8192 +#define __HAVE_ARCH_TASK_STRUCT_ALLOCATOR + /* * low level task data that entry.S needs immediate access to * - this struct should fit entirely inside of one cache line @@ -80,6 +82,19 @@ register struct thread_info *__current_thread_info asm("gr15"); #define current_thread_info() ({ __current_thread_info; }) +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + +/* thread information allocation */ +#ifdef CONFIG_DEBUG_STACK_USAGE +#define alloc_thread_info_node(tsk, node) \ + kzalloc_node(THREAD_SIZE, GFP_KERNEL, node) +#else +#define alloc_thread_info_node(tsk, node) \ + kmalloc_node(THREAD_SIZE, GFP_KERNEL, node) +#endif + +#define free_thread_info(info) kfree(info) + #endif /* __ASSEMBLY__ */ /* diff --git a/trunk/arch/frv/kernel/Makefile b/trunk/arch/frv/kernel/Makefile index ad4087b69968..c36f70b6699a 100644 --- a/trunk/arch/frv/kernel/Makefile +++ b/trunk/arch/frv/kernel/Makefile @@ -5,7 +5,7 @@ heads-y := head-uc-fr401.o head-uc-fr451.o head-uc-fr555.o heads-$(CONFIG_MMU) := head-mmu-fr451.o -extra-y:= head.o vmlinux.lds +extra-y:= head.o init_task.o vmlinux.lds obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \ kernel_execve.o process.o traps.o ptrace.o signal.o dma.o \ diff --git a/trunk/arch/frv/kernel/init_task.c b/trunk/arch/frv/kernel/init_task.c new file mode 100644 index 000000000000..3c3e0b336a9d --- /dev/null +++ b/trunk/arch/frv/kernel/init_task.c @@ -0,0 +1,32 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +/* + * Initial thread structure. + * + * We need to make sure that this is THREAD_SIZE aligned due to the + * way process stacks are handled. This is done by having a special + * "init_task" linker map entry.. + */ +union thread_union init_thread_union __init_task_data = + { INIT_THREAD_INFO(init_task) }; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); + +EXPORT_SYMBOL(init_task); diff --git a/trunk/arch/frv/kernel/process.c b/trunk/arch/frv/kernel/process.c index ed09e9e2c653..d4de48bd5efe 100644 --- a/trunk/arch/frv/kernel/process.c +++ b/trunk/arch/frv/kernel/process.c @@ -43,6 +43,21 @@ asmlinkage void ret_from_fork(void); void (*pm_power_off)(void); EXPORT_SYMBOL(pm_power_off); +struct task_struct *alloc_task_struct_node(int node) +{ + struct task_struct *p = kmalloc_node(THREAD_SIZE, GFP_KERNEL, node); + + if (p) + atomic_set((atomic_t *)(p+1), 1); + return p; +} + +void free_task_struct(struct task_struct *p) +{ + if (atomic_dec_and_test((atomic_t *)(p+1))) + kfree(p); +} + static void core_sleep_idle(void) { #ifdef LED_DEBUG_SLEEP diff --git a/trunk/arch/h8300/kernel/Makefile b/trunk/arch/h8300/kernel/Makefile index 1cc57f872d34..8d4d2a54be9e 100644 --- a/trunk/arch/h8300/kernel/Makefile +++ b/trunk/arch/h8300/kernel/Makefile @@ -6,7 +6,7 @@ extra-y := vmlinux.lds obj-y := process.o traps.o ptrace.o irq.o \ sys_h8300.o time.o signal.o \ - setup.o gpio.o syscalls.o \ + setup.o gpio.o init_task.o syscalls.o \ entry.o timer/ obj-$(CONFIG_MODULES) += module.o h8300_ksyms.o diff --git a/trunk/arch/h8300/kernel/init_task.c b/trunk/arch/h8300/kernel/init_task.c new file mode 100644 index 000000000000..54c1062ee80e --- /dev/null +++ b/trunk/arch/h8300/kernel/init_task.c @@ -0,0 +1,36 @@ +/* + * linux/arch/h8300/kernel/init_task.c + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +__asm__(".align 4"); +struct task_struct init_task = INIT_TASK(init_task); + +EXPORT_SYMBOL(init_task); + +/* + * Initial thread structure. + * + * We need to make sure that this is 8192-byte aligned due to the + * way process stacks are handled. This is done by having a special + * "init_task" linker map entry.. + */ +union thread_union init_thread_union __init_task_data = + { INIT_THREAD_INFO(init_task) }; + diff --git a/trunk/arch/hexagon/Kconfig b/trunk/arch/hexagon/Kconfig index 22615dd02219..9059e3905887 100644 --- a/trunk/arch/hexagon/Kconfig +++ b/trunk/arch/hexagon/Kconfig @@ -18,6 +18,8 @@ config HEXAGON select GENERIC_ATOMIC64 select HAVE_PERF_EVENTS select HAVE_GENERIC_HARDIRQS + select GENERIC_HARDIRQS_NO__DO_IRQ + select GENERIC_HARDIRQS_NO_DEPRECATED # GENERIC_ALLOCATOR is used by dma_alloc_coherent() select GENERIC_ALLOCATOR select GENERIC_IRQ_SHOW @@ -25,7 +27,6 @@ config HEXAGON select HAVE_ARCH_TRACEHOOK select NO_IOPORT select GENERIC_IOMAP - select GENERIC_SMP_IDLE_THREAD # mostly generic routines, with some accelerated ones ---help--- Qualcomm Hexagon is a processor architecture designed for high diff --git a/trunk/arch/hexagon/Makefile b/trunk/arch/hexagon/Makefile index e27d030846ae..0c4de8790fd5 100644 --- a/trunk/arch/hexagon/Makefile +++ b/trunk/arch/hexagon/Makefile @@ -45,7 +45,8 @@ KBUILD_AFLAGS += -DTHREADINFO_REG=$(TIR_NAME) LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) libs-y += $(LIBGCC) -head-y := arch/hexagon/kernel/head.o +head-y := arch/hexagon/kernel/head.o \ + arch/hexagon/kernel/init_task.o core-y += arch/hexagon/kernel/ \ arch/hexagon/mm/ \ diff --git a/trunk/arch/hexagon/include/asm/thread_info.h b/trunk/arch/hexagon/include/asm/thread_info.h index 4f936a7ee847..9c2934ff5756 100644 --- a/trunk/arch/hexagon/include/asm/thread_info.h +++ b/trunk/arch/hexagon/include/asm/thread_info.h @@ -31,7 +31,15 @@ #define THREAD_SHIFT 12 #define THREAD_SIZE (1<= PAGE_SHIFT #define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT) +#else /* don't use standard allocator */ +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR +extern struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node); +extern void free_thread_info(struct thread_info *ti); +#endif + #ifndef __ASSEMBLY__ diff --git a/trunk/arch/hexagon/kernel/Makefile b/trunk/arch/hexagon/kernel/Makefile index 536aec093e62..3689f3754d09 100644 --- a/trunk/arch/hexagon/kernel/Makefile +++ b/trunk/arch/hexagon/kernel/Makefile @@ -1,4 +1,4 @@ -extra-y := head.o vmlinux.lds +extra-y := head.o vmlinux.lds init_task.o obj-$(CONFIG_SMP) += smp.o topology.o diff --git a/trunk/arch/hexagon/kernel/init_task.c b/trunk/arch/hexagon/kernel/init_task.c new file mode 100644 index 000000000000..73283d3edf09 --- /dev/null +++ b/trunk/arch/hexagon/kernel/init_task.c @@ -0,0 +1,54 @@ +/* + * Init task definition + * + * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); + +/* + * Initial thread structure. + * + * We need to make sure that this is 8192-byte aligned due to the + * way process stacks are handled. This is done by making sure + * the linker maps this in the .text segment right after head.S, + * and making head.S ensure the proper alignment. + */ +union thread_union init_thread_union + __attribute__((__section__(".data.init_task"), + __aligned__(THREAD_SIZE))) = { + INIT_THREAD_INFO(init_task) + }; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); +EXPORT_SYMBOL(init_task); diff --git a/trunk/arch/hexagon/kernel/process.c b/trunk/arch/hexagon/kernel/process.c index af51de63b835..ff02821bfb7e 100644 --- a/trunk/arch/hexagon/kernel/process.c +++ b/trunk/arch/hexagon/kernel/process.c @@ -233,6 +233,43 @@ unsigned long get_wchan(struct task_struct *p) return 0; } +/* + * Borrowed from PowerPC -- basically allow smaller kernel stacks if we + * go crazy with the page sizes. + */ +#if THREAD_SHIFT < PAGE_SHIFT + +static struct kmem_cache *thread_info_cache; + +struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node) +{ + struct thread_info *ti; + + ti = kmem_cache_alloc_node(thread_info_cache, GFP_KERNEL, node); + if (unlikely(ti == NULL)) + return NULL; +#ifdef CONFIG_DEBUG_STACK_USAGE + memset(ti, 0, THREAD_SIZE); +#endif + return ti; +} + +void free_thread_info(struct thread_info *ti) +{ + kmem_cache_free(thread_info_cache, ti); +} + +/* Weak symbol; called by init/main.c */ + +void thread_info_cache_init(void) +{ + thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE, + THREAD_SIZE, 0, NULL); + BUG_ON(thread_info_cache == NULL); +} + +#endif /* THREAD_SHIFT < PAGE_SHIFT */ + /* * Required placeholder. */ diff --git a/trunk/arch/hexagon/kernel/smp.c b/trunk/arch/hexagon/kernel/smp.c index f7264621e58d..1298141874a3 100644 --- a/trunk/arch/hexagon/kernel/smp.c +++ b/trunk/arch/hexagon/kernel/smp.c @@ -196,11 +196,18 @@ void __cpuinit start_secondary(void) * maintains control until "cpu_online(cpu)" is set. */ -int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle) +int __cpuinit __cpu_up(unsigned int cpu) { - struct thread_info *thread = (struct thread_info *)idle->stack; + struct task_struct *idle; + struct thread_info *thread; void *stack_start; + /* Create new init task for the CPU */ + idle = fork_idle(cpu); + if (IS_ERR(idle)) + panic(KERN_ERR "fork_idle failed\n"); + + thread = (struct thread_info *)idle->stack; thread->cpu = cpu; /* Boot to the head. */ diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index ba667b60f32d..bd7266903bf8 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -33,10 +33,6 @@ config IA64 select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_IOMAP - select GENERIC_SMP_IDLE_THREAD - select ARCH_INIT_TASK - select ARCH_TASK_STRUCT_ALLOCATOR - select ARCH_THREAD_INFO_ALLOCATOR default y help The Itanium Processor Family is Intel's 64-bit successor to diff --git a/trunk/arch/ia64/include/asm/irq_remapping.h b/trunk/arch/ia64/include/asm/irq_remapping.h deleted file mode 100644 index a8687b1d8906..000000000000 --- a/trunk/arch/ia64/include/asm/irq_remapping.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef __IA64_INTR_REMAPPING_H -#define __IA64_INTR_REMAPPING_H -#define irq_remapping_enabled 0 -#endif diff --git a/trunk/arch/ia64/include/asm/processor.h b/trunk/arch/ia64/include/asm/processor.h index f92f67aba618..483f6c6a4238 100644 --- a/trunk/arch/ia64/include/asm/processor.h +++ b/trunk/arch/ia64/include/asm/processor.h @@ -723,6 +723,7 @@ extern unsigned long boot_option_idle_override; enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_FORCE_MWAIT, IDLE_NOMWAIT, IDLE_POLL}; +void cpu_idle_wait(void); void default_idle(void); #define ia64_platform_is(x) (strcmp(x, platform_name) == 0) diff --git a/trunk/arch/ia64/include/asm/thread_info.h b/trunk/arch/ia64/include/asm/thread_info.h index 310d9734f02d..e054bcc4273c 100644 --- a/trunk/arch/ia64/include/asm/thread_info.h +++ b/trunk/arch/ia64/include/asm/thread_info.h @@ -54,6 +54,8 @@ struct thread_info { }, \ } +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + #ifndef ASM_OFFSETS_C /* how to get the thread information struct from C */ #define current_thread_info() ((struct thread_info *) ((char *) current + IA64_TASK_SIZE)) @@ -82,6 +84,7 @@ struct thread_info { #endif #define end_of_stack(p) (unsigned long *)((void *)(p) + IA64_RBS_OFFSET) +#define __HAVE_ARCH_TASK_STRUCT_ALLOCATOR #define alloc_task_struct_node(node) \ ({ \ struct page *page = alloc_pages_node(node, GFP_KERNEL | __GFP_COMP, \ diff --git a/trunk/arch/ia64/kernel/process.c b/trunk/arch/ia64/kernel/process.c index 5e0e86ddb12f..ce74e143aea3 100644 --- a/trunk/arch/ia64/kernel/process.c +++ b/trunk/arch/ia64/kernel/process.c @@ -273,6 +273,26 @@ static inline void play_dead(void) } #endif /* CONFIG_HOTPLUG_CPU */ +static void do_nothing(void *unused) +{ +} + +/* + * cpu_idle_wait - Used to ensure that all the CPUs discard old value of + * pm_idle and update to new pm_idle value. Required while changing pm_idle + * handler on SMP systems. + * + * Caller must have changed pm_idle to the new value before the call. Old + * pm_idle value will not be used by any CPU after the return of this function. + */ +void cpu_idle_wait(void) +{ + smp_mb(); + /* kick all the CPUs so that they exit out of pm_idle */ + smp_call_function(do_nothing, NULL, 1); +} +EXPORT_SYMBOL_GPL(cpu_idle_wait); + void __attribute__((noreturn)) cpu_idle (void) { diff --git a/trunk/arch/ia64/kernel/smpboot.c b/trunk/arch/ia64/kernel/smpboot.c index 1113b8aba07f..796f6a5b966a 100644 --- a/trunk/arch/ia64/kernel/smpboot.c +++ b/trunk/arch/ia64/kernel/smpboot.c @@ -74,6 +74,13 @@ #define bsp_remove_ok 0 #endif +/* + * Store all idle threads, this can be reused instead of creating + * a new thread. Also avoids complicated thread destroy functionality + * for idle threads. + */ +struct task_struct *idle_thread_array[NR_CPUS]; + /* * Global array allocated for NR_CPUS at boot time */ @@ -87,7 +94,13 @@ struct sal_to_os_boot *sal_state_for_booting_cpu = &sal_boot_rendez_state[0]; #define set_brendez_area(x) (sal_state_for_booting_cpu = &sal_boot_rendez_state[(x)]); +#define get_idle_for_cpu(x) (idle_thread_array[(x)]) +#define set_idle_for_cpu(x,p) (idle_thread_array[(x)] = (p)) + #else + +#define get_idle_for_cpu(x) (NULL) +#define set_idle_for_cpu(x,p) #define set_brendez_area(x) #endif @@ -467,12 +480,54 @@ struct pt_regs * __cpuinit idle_regs(struct pt_regs *regs) return NULL; } +struct create_idle { + struct work_struct work; + struct task_struct *idle; + struct completion done; + int cpu; +}; + +void __cpuinit +do_fork_idle(struct work_struct *work) +{ + struct create_idle *c_idle = + container_of(work, struct create_idle, work); + + c_idle->idle = fork_idle(c_idle->cpu); + complete(&c_idle->done); +} + static int __cpuinit -do_boot_cpu (int sapicid, int cpu, struct task_struct *idle) +do_boot_cpu (int sapicid, int cpu) { int timeout; + struct create_idle c_idle = { + .work = __WORK_INITIALIZER(c_idle.work, do_fork_idle), + .cpu = cpu, + .done = COMPLETION_INITIALIZER(c_idle.done), + }; + + /* + * We can't use kernel_thread since we must avoid to + * reschedule the child. + */ + c_idle.idle = get_idle_for_cpu(cpu); + if (c_idle.idle) { + init_idle(c_idle.idle, cpu); + goto do_rest; + } + + schedule_work(&c_idle.work); + wait_for_completion(&c_idle.done); + + if (IS_ERR(c_idle.idle)) + panic("failed fork for CPU %d", cpu); + + set_idle_for_cpu(cpu, c_idle.idle); + +do_rest: + task_for_booting_cpu = c_idle.idle; - task_for_booting_cpu = idle; Dprintk("Sending wakeup vector %lu to AP 0x%x/0x%x.\n", ap_wakeup_vector, cpu, sapicid); set_brendez_area(cpu); @@ -738,7 +793,7 @@ set_cpu_sibling_map(int cpu) } int __cpuinit -__cpu_up(unsigned int cpu, struct task_struct *tidle) +__cpu_up (unsigned int cpu) { int ret; int sapicid; @@ -756,7 +811,7 @@ __cpu_up(unsigned int cpu, struct task_struct *tidle) per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; /* Processor goes to start_secondary(), sets online flag */ - ret = do_boot_cpu(sapicid, cpu, tidle); + ret = do_boot_cpu(sapicid, cpu); if (ret < 0) return ret; diff --git a/trunk/arch/ia64/kvm/kvm-ia64.c b/trunk/arch/ia64/kvm/kvm-ia64.c index 463fb3bbe11e..f5104b7c52cd 100644 --- a/trunk/arch/ia64/kvm/kvm-ia64.c +++ b/trunk/arch/ia64/kvm/kvm-ia64.c @@ -1174,7 +1174,7 @@ static enum hrtimer_restart hlt_timer_fn(struct hrtimer *data) bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu) { - return irqchip_in_kernel(vcpu->kvm) == (vcpu->arch.apic != NULL); + return irqchip_in_kernel(vcpu->kcm) == (vcpu->arch.apic != NULL); } int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) diff --git a/trunk/arch/m32r/Makefile b/trunk/arch/m32r/Makefile index def8dd0b6bc5..8ff5ba0ea26c 100644 --- a/trunk/arch/m32r/Makefile +++ b/trunk/arch/m32r/Makefile @@ -31,7 +31,7 @@ KBUILD_AFLAGS += $(aflags-y) CHECKFLAGS += -D__m32r__ -D__BIG_ENDIAN__=1 -head-y := arch/m32r/kernel/head.o +head-y := arch/m32r/kernel/head.o arch/m32r/kernel/init_task.o LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) diff --git a/trunk/arch/m32r/include/asm/thread_info.h b/trunk/arch/m32r/include/asm/thread_info.h index c083f6073ef4..bf8fa3c06f4e 100644 --- a/trunk/arch/m32r/include/asm/thread_info.h +++ b/trunk/arch/m32r/include/asm/thread_info.h @@ -55,8 +55,8 @@ struct thread_info { #define PREEMPT_ACTIVE 0x10000000 -#define THREAD_SIZE (PAGE_SIZE << 1) -#define THREAD_SIZE_ORDER 1 +#define THREAD_SIZE (PAGE_SIZE << 1) + /* * macros/functions for gaining access to the thread information structure */ @@ -92,6 +92,19 @@ static inline struct thread_info *current_thread_info(void) return ti; } +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + +/* thread information allocation */ +#ifdef CONFIG_DEBUG_STACK_USAGE +#define alloc_thread_info_node(tsk, node) \ + kzalloc_node(THREAD_SIZE, GFP_KERNEL, node) +#else +#define alloc_thread_info_node(tsk, node) \ + kmalloc_node(THREAD_SIZE, GFP_KERNEL, node) +#endif + +#define free_thread_info(info) kfree(info) + #define TI_FLAG_FAULT_CODE_SHIFT 28 static inline void set_thread_fault_code(unsigned int val) diff --git a/trunk/arch/m32r/kernel/Makefile b/trunk/arch/m32r/kernel/Makefile index 0c09dad8b1f8..b1a4b6036591 100644 --- a/trunk/arch/m32r/kernel/Makefile +++ b/trunk/arch/m32r/kernel/Makefile @@ -2,7 +2,7 @@ # Makefile for the Linux/M32R kernel. # -extra-y := head.o vmlinux.lds +extra-y := head.o init_task.o vmlinux.lds obj-y := process.o entry.o traps.o align.o irq.o setup.o time.o \ m32r_ksyms.o sys_m32r.o signal.o ptrace.o diff --git a/trunk/arch/m32r/kernel/init_task.c b/trunk/arch/m32r/kernel/init_task.c new file mode 100644 index 000000000000..6c42d5f8df50 --- /dev/null +++ b/trunk/arch/m32r/kernel/init_task.c @@ -0,0 +1,34 @@ +/* orig : i386 init_task.c */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +/* + * Initial thread structure. + * + * We need to make sure that this is 8192-byte aligned due to the + * way process stacks are handled. This is done by having a special + * "init_task" linker map entry.. + */ +union thread_union init_thread_union __init_task_data = + { INIT_THREAD_INFO(init_task) }; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); + +EXPORT_SYMBOL(init_task); + diff --git a/trunk/arch/m32r/kernel/smpboot.c b/trunk/arch/m32r/kernel/smpboot.c index a2cfc0abb05c..cfdbe5d15002 100644 --- a/trunk/arch/m32r/kernel/smpboot.c +++ b/trunk/arch/m32r/kernel/smpboot.c @@ -109,8 +109,12 @@ static unsigned int calibration_result; /* Function Prototypes */ /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ +void smp_prepare_boot_cpu(void); +void smp_prepare_cpus(unsigned int); static void init_ipi_lock(void); static void do_boot_cpu(int); +int __cpu_up(unsigned int); +void smp_cpus_done(unsigned int); int start_secondary(void *); static void smp_callin(void); @@ -343,7 +347,7 @@ static void __init do_boot_cpu(int phys_id) } } -int __cpuinit __cpu_up(unsigned int cpu_id, struct task_struct *tidle) +int __cpuinit __cpu_up(unsigned int cpu_id) { int timeout; diff --git a/trunk/arch/m68k/Makefile b/trunk/arch/m68k/Makefile index b7f2e2d5cd2e..cf318f20c64d 100644 --- a/trunk/arch/m68k/Makefile +++ b/trunk/arch/m68k/Makefile @@ -16,13 +16,6 @@ KBUILD_DEFCONFIG := multi_defconfig -ifneq ($(SUBARCH),$(ARCH)) - ifeq ($(CROSS_COMPILE),) - CROSS_COMPILE := $(call cc-cross-prefix, \ - m68k-linux-gnu- m68k-linux- m68k-unknown-linux-gnu-) - endif -endif - # # Enable processor type. Ordering of these is important - we want to # use the minimum processor type of the range we support. The logic @@ -69,6 +62,12 @@ endif LDFLAGS := -m m68kelf KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds +ifneq ($(SUBARCH),$(ARCH)) + ifeq ($(CROSS_COMPILE),) + CROSS_COMPILE := $(call cc-cross-prefix, \ + m68k-linux-gnu- m68k-linux- m68k-unknown-linux-gnu-) + endif +endif ifdef CONFIG_SUN3 LDFLAGS_vmlinux = -N @@ -116,6 +115,18 @@ core-$(CONFIG_M68000) += arch/m68k/platform/68328/ core-$(CONFIG_M68EZ328) += arch/m68k/platform/68EZ328/ core-$(CONFIG_M68VZ328) += arch/m68k/platform/68VZ328/ core-$(CONFIG_COLDFIRE) += arch/m68k/platform/coldfire/ +core-$(CONFIG_M5206) += arch/m68k/platform/5206/ +core-$(CONFIG_M5206e) += arch/m68k/platform/5206/ +core-$(CONFIG_M520x) += arch/m68k/platform/520x/ +core-$(CONFIG_M523x) += arch/m68k/platform/523x/ +core-$(CONFIG_M5249) += arch/m68k/platform/5249/ +core-$(CONFIG_M527x) += arch/m68k/platform/527x/ +core-$(CONFIG_M5272) += arch/m68k/platform/5272/ +core-$(CONFIG_M528x) += arch/m68k/platform/528x/ +core-$(CONFIG_M5307) += arch/m68k/platform/5307/ +core-$(CONFIG_M532x) += arch/m68k/platform/532x/ +core-$(CONFIG_M5407) += arch/m68k/platform/5407/ +core-$(CONFIG_M54xx) += arch/m68k/platform/54xx/ all: zImage diff --git a/trunk/arch/m68k/amiga/platform.c b/trunk/arch/m68k/amiga/platform.c index 80076d368b7e..7fd8b41723ea 100644 --- a/trunk/arch/m68k/amiga/platform.c +++ b/trunk/arch/m68k/amiga/platform.c @@ -6,7 +6,6 @@ * for more details. */ -#include #include #include #include @@ -47,25 +46,18 @@ static const struct resource zorro_resources[] __initconst = { static int __init amiga_init_bus(void) { - struct platform_device *pdev; - unsigned int n; - if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO)) return -ENODEV; - n = AMIGAHW_PRESENT(ZORRO3) ? 4 : 2; - pdev = platform_device_register_simple("amiga-zorro", -1, - zorro_resources, n); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - + platform_device_register_simple("amiga-zorro", -1, zorro_resources, + AMIGAHW_PRESENT(ZORRO3) ? 4 : 2); return 0; } subsys_initcall(amiga_init_bus); -static int __init z_dev_present(zorro_id id) +static int z_dev_present(zorro_id id) { unsigned int i; @@ -134,122 +126,72 @@ static const struct resource amiga_rtc_resource __initconst = { static int __init amiga_init_devices(void) { struct platform_device *pdev; - int error; if (!MACH_IS_AMIGA) return -ENODEV; /* video hardware */ - if (AMIGAHW_PRESENT(AMI_VIDEO)) { - pdev = platform_device_register_simple("amiga-video", -1, NULL, - 0); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - } + if (AMIGAHW_PRESENT(AMI_VIDEO)) + platform_device_register_simple("amiga-video", -1, NULL, 0); /* sound hardware */ - if (AMIGAHW_PRESENT(AMI_AUDIO)) { - pdev = platform_device_register_simple("amiga-audio", -1, NULL, - 0); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - } + if (AMIGAHW_PRESENT(AMI_AUDIO)) + platform_device_register_simple("amiga-audio", -1, NULL, 0); /* storage interfaces */ - if (AMIGAHW_PRESENT(AMI_FLOPPY)) { - pdev = platform_device_register_simple("amiga-floppy", -1, - NULL, 0); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - } + if (AMIGAHW_PRESENT(AMI_FLOPPY)) + platform_device_register_simple("amiga-floppy", -1, NULL, 0); - if (AMIGAHW_PRESENT(A3000_SCSI)) { - pdev = platform_device_register_simple("amiga-a3000-scsi", -1, - &a3000_scsi_resource, 1); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - } + if (AMIGAHW_PRESENT(A3000_SCSI)) + platform_device_register_simple("amiga-a3000-scsi", -1, + &a3000_scsi_resource, 1); - if (AMIGAHW_PRESENT(A4000_SCSI)) { - pdev = platform_device_register_simple("amiga-a4000t-scsi", -1, - &a4000t_scsi_resource, - 1); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - } + if (AMIGAHW_PRESENT(A4000_SCSI)) + platform_device_register_simple("amiga-a4000t-scsi", -1, + &a4000t_scsi_resource, 1); if (AMIGAHW_PRESENT(A1200_IDE) || z_dev_present(ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530_SCSI_IDE)) { pdev = platform_device_register_simple("amiga-gayle-ide", -1, &a1200_ide_resource, 1); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - error = platform_device_add_data(pdev, &a1200_ide_pdata, - sizeof(a1200_ide_pdata)); - if (error) - return error; + platform_device_add_data(pdev, &a1200_ide_pdata, + sizeof(a1200_ide_pdata)); } if (AMIGAHW_PRESENT(A4000_IDE)) { pdev = platform_device_register_simple("amiga-gayle-ide", -1, &a4000_ide_resource, 1); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - error = platform_device_add_data(pdev, &a4000_ide_pdata, - sizeof(a4000_ide_pdata)); - if (error) - return error; + platform_device_add_data(pdev, &a4000_ide_pdata, + sizeof(a4000_ide_pdata)); } /* other I/O hardware */ - if (AMIGAHW_PRESENT(AMI_KEYBOARD)) { - pdev = platform_device_register_simple("amiga-keyboard", -1, - NULL, 0); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - } + if (AMIGAHW_PRESENT(AMI_KEYBOARD)) + platform_device_register_simple("amiga-keyboard", -1, NULL, 0); - if (AMIGAHW_PRESENT(AMI_MOUSE)) { - pdev = platform_device_register_simple("amiga-mouse", -1, NULL, - 0); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - } + if (AMIGAHW_PRESENT(AMI_MOUSE)) + platform_device_register_simple("amiga-mouse", -1, NULL, 0); - if (AMIGAHW_PRESENT(AMI_SERIAL)) { - pdev = platform_device_register_simple("amiga-serial", -1, - NULL, 0); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - } + if (AMIGAHW_PRESENT(AMI_SERIAL)) + platform_device_register_simple("amiga-serial", -1, NULL, 0); - if (AMIGAHW_PRESENT(AMI_PARALLEL)) { - pdev = platform_device_register_simple("amiga-parallel", -1, - NULL, 0); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - } + if (AMIGAHW_PRESENT(AMI_PARALLEL)) + platform_device_register_simple("amiga-parallel", -1, NULL, 0); /* real time clocks */ - if (AMIGAHW_PRESENT(A2000_CLK)) { - pdev = platform_device_register_simple("rtc-msm6242", -1, - &amiga_rtc_resource, 1); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - } + if (AMIGAHW_PRESENT(A2000_CLK)) + platform_device_register_simple("rtc-msm6242", -1, + &amiga_rtc_resource, 1); - if (AMIGAHW_PRESENT(A3000_CLK)) { - pdev = platform_device_register_simple("rtc-rp5c01", -1, - &amiga_rtc_resource, 1); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - } + if (AMIGAHW_PRESENT(A3000_CLK)) + platform_device_register_simple("rtc-rp5c01", -1, + &amiga_rtc_resource, 1); return 0; } -arch_initcall(amiga_init_devices); +device_initcall(amiga_init_devices); diff --git a/trunk/arch/m68k/atari/ataints.c b/trunk/arch/m68k/atari/ataints.c index 3f41092d1b70..783d8f02360d 100644 --- a/trunk/arch/m68k/atari/ataints.c +++ b/trunk/arch/m68k/atari/ataints.c @@ -206,7 +206,7 @@ void __init atari_init_IRQ(void) * hardware with a programmable int vector (probably a VME board). */ -unsigned int atari_register_vme_int(void) +unsigned long atari_register_vme_int(void) { int i; @@ -223,7 +223,7 @@ unsigned int atari_register_vme_int(void) EXPORT_SYMBOL(atari_register_vme_int); -void atari_unregister_vme_int(unsigned int irq) +void atari_unregister_vme_int(unsigned long irq) { if (irq >= VME_SOURCE_BASE && irq < VME_SOURCE_BASE + VME_MAX_SOURCES) { irq -= VME_SOURCE_BASE; diff --git a/trunk/arch/m68k/configs/m5475evb_defconfig b/trunk/arch/m68k/configs/m5475evb_defconfig deleted file mode 100644 index c5018a68819b..000000000000 --- a/trunk/arch/m68k/configs/m5475evb_defconfig +++ /dev/null @@ -1,62 +0,0 @@ -CONFIG_EXPERIMENTAL=y -# CONFIG_SWAP is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y -CONFIG_SYSCTL_SYSCALL=y -# CONFIG_KALLSYMS is not set -# CONFIG_HOTPLUG is not set -# CONFIG_FUTEX is not set -# CONFIG_EPOLL is not set -# CONFIG_SIGNALFD is not set -# CONFIG_TIMERFD is not set -# CONFIG_EVENTFD is not set -# CONFIG_SHMEM is not set -# CONFIG_AIO is not set -CONFIG_EMBEDDED=y -CONFIG_MODULES=y -# CONFIG_LBDAF is not set -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_COLDFIRE=y -CONFIG_M547x=y -CONFIG_CLOCK_SET=y -CONFIG_CLOCK_FREQ=266000000 -# CONFIG_4KSTACKS is not set -CONFIG_RAMBASE=0x0 -CONFIG_RAMSIZE=0x2000000 -CONFIG_VECTORBASE=0x0 -CONFIG_MBAR=0xff000000 -CONFIG_KERNELBASE=0x20000 -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -# CONFIG_FW_LOADER is not set -CONFIG_MTD=y -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_RAM=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_UCLINUX=y -CONFIG_BLK_DEV_RAM=y -# CONFIG_INPUT is not set -# CONFIG_VT is not set -# CONFIG_UNIX98_PTYS is not set -CONFIG_SERIAL_MCF=y -CONFIG_SERIAL_MCF_CONSOLE=y -# CONFIG_HW_RANDOM is not set -# CONFIG_HWMON is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_IOMMU_SUPPORT is not set -CONFIG_EXT2_FS=y -# CONFIG_FILE_LOCKING is not set -# CONFIG_DNOTIFY is not set -# CONFIG_INOTIFY_USER is not set -# CONFIG_PROC_PAGE_MONITOR is not set -CONFIG_ROMFS_FS=y -CONFIG_ROMFS_BACKED_BY_MTD=y -# CONFIG_SCHED_DEBUG is not set -CONFIG_BOOTPARAM=y -CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0" diff --git a/trunk/arch/m68k/include/asm/atariints.h b/trunk/arch/m68k/include/asm/atariints.h index 5fc13bdf9044..656bbbf5a6ff 100644 --- a/trunk/arch/m68k/include/asm/atariints.h +++ b/trunk/arch/m68k/include/asm/atariints.h @@ -198,7 +198,7 @@ static inline int atari_irq_pending( unsigned irq ) return( get_mfp_bit( irq, MFP_PENDING ) ); } -unsigned int atari_register_vme_int(void); -void atari_unregister_vme_int(unsigned int); +unsigned long atari_register_vme_int( void ); +void atari_unregister_vme_int( unsigned long ); #endif /* linux/atariints.h */ diff --git a/trunk/arch/m68k/include/asm/cacheflush_no.h b/trunk/arch/m68k/include/asm/cacheflush_no.h index 7cafb537d03c..cb88aa96c4f1 100644 --- a/trunk/arch/m68k/include/asm/cacheflush_no.h +++ b/trunk/arch/m68k/include/asm/cacheflush_no.h @@ -30,8 +30,11 @@ void mcf_cache_push(void); -static inline void __clear_cache_all(void) +static inline void __flush_cache_all(void) { +#ifdef CACHE_PUSH + mcf_cache_push(); +#endif #ifdef CACHE_INVALIDATE __asm__ __volatile__ ( "movel %0, %%d0\n\t" @@ -41,14 +44,6 @@ static inline void __clear_cache_all(void) #endif } -static inline void __flush_cache_all(void) -{ -#ifdef CACHE_PUSH - mcf_cache_push(); -#endif - __clear_cache_all(); -} - /* * Some ColdFire parts implement separate instruction and data caches, * on those we should just flush the appropriate cache. If we don't need @@ -81,23 +76,4 @@ static inline void __flush_dcache_all(void) __asm__ __volatile__ ( "nop" ); #endif } - -/* - * Push cache entries at supplied address. We want to write back any dirty - * data and the invalidate the cache lines associated with this address. - */ -static inline void cache_push(unsigned long paddr, int len) -{ - __flush_cache_all(); -} - -/* - * Clear cache entries at supplied address (that is don't write back any - * dirty data). - */ -static inline void cache_clear(unsigned long paddr, int len) -{ - __clear_cache_all(); -} - #endif /* _M68KNOMMU_CACHEFLUSH_H */ diff --git a/trunk/arch/m68k/include/asm/entry.h b/trunk/arch/m68k/include/asm/entry.h index d7de0f1a8957..622138dc7288 100644 --- a/trunk/arch/m68k/include/asm/entry.h +++ b/trunk/arch/m68k/include/asm/entry.h @@ -33,11 +33,13 @@ /* the following macro is used when enabling interrupts */ #if defined(MACH_ATARI_ONLY) - /* block out HSYNC = ipl 2 on the atari */ -#define ALLOWINT (~0x500) + /* block out HSYNC on the atari */ +#define ALLOWINT (~0x400) +#define MAX_NOINT_IPL 3 #else /* portable version */ #define ALLOWINT (~0x700) +#define MAX_NOINT_IPL 0 #endif /* machine compilation types */ #ifdef __ASSEMBLY__ diff --git a/trunk/arch/m68k/include/asm/flat.h b/trunk/arch/m68k/include/asm/flat.h index f9454b89a51b..a0e290793978 100644 --- a/trunk/arch/m68k/include/asm/flat.h +++ b/trunk/arch/m68k/include/asm/flat.h @@ -11,11 +11,6 @@ #define flat_get_addr_from_rp(rp, relval, flags, p) get_unaligned(rp) #define flat_put_addr_at_rp(rp, val, relval) put_unaligned(val,rp) #define flat_get_relocate_addr(rel) (rel) - -static inline int flat_set_persistent(unsigned long relval, - unsigned long *persistent) -{ - return 0; -} +#define flat_set_persistent(relval, p) 0 #endif /* __M68KNOMMU_FLAT_H__ */ diff --git a/trunk/arch/m68k/include/asm/io_mm.h b/trunk/arch/m68k/include/asm/io_mm.h index fa4324bcf566..0fb3468000e7 100644 --- a/trunk/arch/m68k/include/asm/io_mm.h +++ b/trunk/arch/m68k/include/asm/io_mm.h @@ -278,13 +278,6 @@ static inline void isa_delay(void) #define readl(addr) in_le32(addr) #define writel(val,addr) out_le32((addr),(val)) -#define readsb(port, buf, nr) raw_insb((port), (u8 *)(buf), (nr)) -#define readsw(port, buf, nr) raw_insw((port), (u16 *)(buf), (nr)) -#define readsl(port, buf, nr) raw_insl((port), (u32 *)(buf), (nr)) -#define writesb(port, buf, nr) raw_outsb((port), (u8 *)(buf), (nr)) -#define writesw(port, buf, nr) raw_outsw((port), (u16 *)(buf), (nr)) -#define writesl(port, buf, nr) raw_outsl((port), (u32 *)(buf), (nr)) - #define mmiowb() static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size) diff --git a/trunk/arch/m68k/include/asm/m528xsim.h b/trunk/arch/m68k/include/asm/m528xsim.h index d63b99ff7ff7..569476fba18c 100644 --- a/trunk/arch/m68k/include/asm/m528xsim.h +++ b/trunk/arch/m68k/include/asm/m528xsim.h @@ -97,81 +97,100 @@ /* * GPIO registers */ -#define MCFGPIO_PODR_A (MCF_IPSBAR + 0x00100000) -#define MCFGPIO_PODR_B (MCF_IPSBAR + 0x00100001) -#define MCFGPIO_PODR_C (MCF_IPSBAR + 0x00100002) -#define MCFGPIO_PODR_D (MCF_IPSBAR + 0x00100003) -#define MCFGPIO_PODR_E (MCF_IPSBAR + 0x00100004) -#define MCFGPIO_PODR_F (MCF_IPSBAR + 0x00100005) -#define MCFGPIO_PODR_G (MCF_IPSBAR + 0x00100006) -#define MCFGPIO_PODR_H (MCF_IPSBAR + 0x00100007) -#define MCFGPIO_PODR_J (MCF_IPSBAR + 0x00100008) -#define MCFGPIO_PODR_DD (MCF_IPSBAR + 0x00100009) -#define MCFGPIO_PODR_EH (MCF_IPSBAR + 0x0010000A) -#define MCFGPIO_PODR_EL (MCF_IPSBAR + 0x0010000B) -#define MCFGPIO_PODR_AS (MCF_IPSBAR + 0x0010000C) -#define MCFGPIO_PODR_QS (MCF_IPSBAR + 0x0010000D) -#define MCFGPIO_PODR_SD (MCF_IPSBAR + 0x0010000E) -#define MCFGPIO_PODR_TC (MCF_IPSBAR + 0x0010000F) -#define MCFGPIO_PODR_TD (MCF_IPSBAR + 0x00100010) -#define MCFGPIO_PODR_UA (MCF_IPSBAR + 0x00100011) - -#define MCFGPIO_PDDR_A (MCF_IPSBAR + 0x00100014) -#define MCFGPIO_PDDR_B (MCF_IPSBAR + 0x00100015) -#define MCFGPIO_PDDR_C (MCF_IPSBAR + 0x00100016) -#define MCFGPIO_PDDR_D (MCF_IPSBAR + 0x00100017) -#define MCFGPIO_PDDR_E (MCF_IPSBAR + 0x00100018) -#define MCFGPIO_PDDR_F (MCF_IPSBAR + 0x00100019) -#define MCFGPIO_PDDR_G (MCF_IPSBAR + 0x0010001A) -#define MCFGPIO_PDDR_H (MCF_IPSBAR + 0x0010001B) -#define MCFGPIO_PDDR_J (MCF_IPSBAR + 0x0010001C) -#define MCFGPIO_PDDR_DD (MCF_IPSBAR + 0x0010001D) -#define MCFGPIO_PDDR_EH (MCF_IPSBAR + 0x0010001E) -#define MCFGPIO_PDDR_EL (MCF_IPSBAR + 0x0010001F) -#define MCFGPIO_PDDR_AS (MCF_IPSBAR + 0x00100020) -#define MCFGPIO_PDDR_QS (MCF_IPSBAR + 0x00100021) -#define MCFGPIO_PDDR_SD (MCF_IPSBAR + 0x00100022) -#define MCFGPIO_PDDR_TC (MCF_IPSBAR + 0x00100023) -#define MCFGPIO_PDDR_TD (MCF_IPSBAR + 0x00100024) -#define MCFGPIO_PDDR_UA (MCF_IPSBAR + 0x00100025) - -#define MCFGPIO_PPDSDR_A (MCF_IPSBAR + 0x00100028) -#define MCFGPIO_PPDSDR_B (MCF_IPSBAR + 0x00100029) -#define MCFGPIO_PPDSDR_C (MCF_IPSBAR + 0x0010002A) -#define MCFGPIO_PPDSDR_D (MCF_IPSBAR + 0x0010002B) -#define MCFGPIO_PPDSDR_E (MCF_IPSBAR + 0x0010002C) -#define MCFGPIO_PPDSDR_F (MCF_IPSBAR + 0x0010002D) -#define MCFGPIO_PPDSDR_G (MCF_IPSBAR + 0x0010002E) -#define MCFGPIO_PPDSDR_H (MCF_IPSBAR + 0x0010002F) -#define MCFGPIO_PPDSDR_J (MCF_IPSBAR + 0x00100030) -#define MCFGPIO_PPDSDR_DD (MCF_IPSBAR + 0x00100031) -#define MCFGPIO_PPDSDR_EH (MCF_IPSBAR + 0x00100032) -#define MCFGPIO_PPDSDR_EL (MCF_IPSBAR + 0x00100033) -#define MCFGPIO_PPDSDR_AS (MCF_IPSBAR + 0x00100034) -#define MCFGPIO_PPDSDR_QS (MCF_IPSBAR + 0x00100035) -#define MCFGPIO_PPDSDR_SD (MCF_IPSBAR + 0x00100036) -#define MCFGPIO_PPDSDR_TC (MCF_IPSBAR + 0x00100037) -#define MCFGPIO_PPDSDR_TD (MCF_IPSBAR + 0x00100038) -#define MCFGPIO_PPDSDR_UA (MCF_IPSBAR + 0x00100039) - -#define MCFGPIO_PCLRR_A (MCF_IPSBAR + 0x0010003C) -#define MCFGPIO_PCLRR_B (MCF_IPSBAR + 0x0010003D) -#define MCFGPIO_PCLRR_C (MCF_IPSBAR + 0x0010003E) -#define MCFGPIO_PCLRR_D (MCF_IPSBAR + 0x0010003F) -#define MCFGPIO_PCLRR_E (MCF_IPSBAR + 0x00100040) -#define MCFGPIO_PCLRR_F (MCF_IPSBAR + 0x00100041) -#define MCFGPIO_PCLRR_G (MCF_IPSBAR + 0x00100042) -#define MCFGPIO_PCLRR_H (MCF_IPSBAR + 0x00100043) -#define MCFGPIO_PCLRR_J (MCF_IPSBAR + 0x00100044) -#define MCFGPIO_PCLRR_DD (MCF_IPSBAR + 0x00100045) -#define MCFGPIO_PCLRR_EH (MCF_IPSBAR + 0x00100046) -#define MCFGPIO_PCLRR_EL (MCF_IPSBAR + 0x00100047) -#define MCFGPIO_PCLRR_AS (MCF_IPSBAR + 0x00100048) -#define MCFGPIO_PCLRR_QS (MCF_IPSBAR + 0x00100049) -#define MCFGPIO_PCLRR_SD (MCF_IPSBAR + 0x0010004A) -#define MCFGPIO_PCLRR_TC (MCF_IPSBAR + 0x0010004B) -#define MCFGPIO_PCLRR_TD (MCF_IPSBAR + 0x0010004C) -#define MCFGPIO_PCLRR_UA (MCF_IPSBAR + 0x0010004D) +#define MCFGPIO_PORTA (MCF_IPSBAR + 0x00100000) +#define MCFGPIO_PORTB (MCF_IPSBAR + 0x00100001) +#define MCFGPIO_PORTC (MCF_IPSBAR + 0x00100002) +#define MCFGPIO_PORTD (MCF_IPSBAR + 0x00100003) +#define MCFGPIO_PORTE (MCF_IPSBAR + 0x00100004) +#define MCFGPIO_PORTF (MCF_IPSBAR + 0x00100005) +#define MCFGPIO_PORTG (MCF_IPSBAR + 0x00100006) +#define MCFGPIO_PORTH (MCF_IPSBAR + 0x00100007) +#define MCFGPIO_PORTJ (MCF_IPSBAR + 0x00100008) +#define MCFGPIO_PORTDD (MCF_IPSBAR + 0x00100009) +#define MCFGPIO_PORTEH (MCF_IPSBAR + 0x0010000A) +#define MCFGPIO_PORTEL (MCF_IPSBAR + 0x0010000B) +#define MCFGPIO_PORTAS (MCF_IPSBAR + 0x0010000C) +#define MCFGPIO_PORTQS (MCF_IPSBAR + 0x0010000D) +#define MCFGPIO_PORTSD (MCF_IPSBAR + 0x0010000E) +#define MCFGPIO_PORTTC (MCF_IPSBAR + 0x0010000F) +#define MCFGPIO_PORTTD (MCF_IPSBAR + 0x00100010) +#define MCFGPIO_PORTUA (MCF_IPSBAR + 0x00100011) + +#define MCFGPIO_DDRA (MCF_IPSBAR + 0x00100014) +#define MCFGPIO_DDRB (MCF_IPSBAR + 0x00100015) +#define MCFGPIO_DDRC (MCF_IPSBAR + 0x00100016) +#define MCFGPIO_DDRD (MCF_IPSBAR + 0x00100017) +#define MCFGPIO_DDRE (MCF_IPSBAR + 0x00100018) +#define MCFGPIO_DDRF (MCF_IPSBAR + 0x00100019) +#define MCFGPIO_DDRG (MCF_IPSBAR + 0x0010001A) +#define MCFGPIO_DDRH (MCF_IPSBAR + 0x0010001B) +#define MCFGPIO_DDRJ (MCF_IPSBAR + 0x0010001C) +#define MCFGPIO_DDRDD (MCF_IPSBAR + 0x0010001D) +#define MCFGPIO_DDREH (MCF_IPSBAR + 0x0010001E) +#define MCFGPIO_DDREL (MCF_IPSBAR + 0x0010001F) +#define MCFGPIO_DDRAS (MCF_IPSBAR + 0x00100020) +#define MCFGPIO_DDRQS (MCF_IPSBAR + 0x00100021) +#define MCFGPIO_DDRSD (MCF_IPSBAR + 0x00100022) +#define MCFGPIO_DDRTC (MCF_IPSBAR + 0x00100023) +#define MCFGPIO_DDRTD (MCF_IPSBAR + 0x00100024) +#define MCFGPIO_DDRUA (MCF_IPSBAR + 0x00100025) + +#define MCFGPIO_PORTAP (MCF_IPSBAR + 0x00100028) +#define MCFGPIO_PORTBP (MCF_IPSBAR + 0x00100029) +#define MCFGPIO_PORTCP (MCF_IPSBAR + 0x0010002A) +#define MCFGPIO_PORTDP (MCF_IPSBAR + 0x0010002B) +#define MCFGPIO_PORTEP (MCF_IPSBAR + 0x0010002C) +#define MCFGPIO_PORTFP (MCF_IPSBAR + 0x0010002D) +#define MCFGPIO_PORTGP (MCF_IPSBAR + 0x0010002E) +#define MCFGPIO_PORTHP (MCF_IPSBAR + 0x0010002F) +#define MCFGPIO_PORTJP (MCF_IPSBAR + 0x00100030) +#define MCFGPIO_PORTDDP (MCF_IPSBAR + 0x00100031) +#define MCFGPIO_PORTEHP (MCF_IPSBAR + 0x00100032) +#define MCFGPIO_PORTELP (MCF_IPSBAR + 0x00100033) +#define MCFGPIO_PORTASP (MCF_IPSBAR + 0x00100034) +#define MCFGPIO_PORTQSP (MCF_IPSBAR + 0x00100035) +#define MCFGPIO_PORTSDP (MCF_IPSBAR + 0x00100036) +#define MCFGPIO_PORTTCP (MCF_IPSBAR + 0x00100037) +#define MCFGPIO_PORTTDP (MCF_IPSBAR + 0x00100038) +#define MCFGPIO_PORTUAP (MCF_IPSBAR + 0x00100039) + +#define MCFGPIO_SETA (MCF_IPSBAR + 0x00100028) +#define MCFGPIO_SETB (MCF_IPSBAR + 0x00100029) +#define MCFGPIO_SETC (MCF_IPSBAR + 0x0010002A) +#define MCFGPIO_SETD (MCF_IPSBAR + 0x0010002B) +#define MCFGPIO_SETE (MCF_IPSBAR + 0x0010002C) +#define MCFGPIO_SETF (MCF_IPSBAR + 0x0010002D) +#define MCFGPIO_SETG (MCF_IPSBAR + 0x0010002E) +#define MCFGPIO_SETH (MCF_IPSBAR + 0x0010002F) +#define MCFGPIO_SETJ (MCF_IPSBAR + 0x00100030) +#define MCFGPIO_SETDD (MCF_IPSBAR + 0x00100031) +#define MCFGPIO_SETEH (MCF_IPSBAR + 0x00100032) +#define MCFGPIO_SETEL (MCF_IPSBAR + 0x00100033) +#define MCFGPIO_SETAS (MCF_IPSBAR + 0x00100034) +#define MCFGPIO_SETQS (MCF_IPSBAR + 0x00100035) +#define MCFGPIO_SETSD (MCF_IPSBAR + 0x00100036) +#define MCFGPIO_SETTC (MCF_IPSBAR + 0x00100037) +#define MCFGPIO_SETTD (MCF_IPSBAR + 0x00100038) +#define MCFGPIO_SETUA (MCF_IPSBAR + 0x00100039) + +#define MCFGPIO_CLRA (MCF_IPSBAR + 0x0010003C) +#define MCFGPIO_CLRB (MCF_IPSBAR + 0x0010003D) +#define MCFGPIO_CLRC (MCF_IPSBAR + 0x0010003E) +#define MCFGPIO_CLRD (MCF_IPSBAR + 0x0010003F) +#define MCFGPIO_CLRE (MCF_IPSBAR + 0x00100040) +#define MCFGPIO_CLRF (MCF_IPSBAR + 0x00100041) +#define MCFGPIO_CLRG (MCF_IPSBAR + 0x00100042) +#define MCFGPIO_CLRH (MCF_IPSBAR + 0x00100043) +#define MCFGPIO_CLRJ (MCF_IPSBAR + 0x00100044) +#define MCFGPIO_CLRDD (MCF_IPSBAR + 0x00100045) +#define MCFGPIO_CLREH (MCF_IPSBAR + 0x00100046) +#define MCFGPIO_CLREL (MCF_IPSBAR + 0x00100047) +#define MCFGPIO_CLRAS (MCF_IPSBAR + 0x00100048) +#define MCFGPIO_CLRQS (MCF_IPSBAR + 0x00100049) +#define MCFGPIO_CLRSD (MCF_IPSBAR + 0x0010004A) +#define MCFGPIO_CLRTC (MCF_IPSBAR + 0x0010004B) +#define MCFGPIO_CLRTD (MCF_IPSBAR + 0x0010004C) +#define MCFGPIO_CLRUA (MCF_IPSBAR + 0x0010004D) #define MCFGPIO_PBCDPAR (MCF_IPSBAR + 0x00100050) #define MCFGPIO_PFPAR (MCF_IPSBAR + 0x00100051) @@ -223,11 +242,11 @@ * definitions for generic gpio support * */ -#define MCFGPIO_PODR MCFGPIO_PODR_A /* port output data */ -#define MCFGPIO_PDDR MCFGPIO_PDDR_A /* port data direction */ -#define MCFGPIO_PPDR MCFGPIO_PPDSDR_A/* port pin data */ -#define MCFGPIO_SETR MCFGPIO_PPDSDR_A/* set output */ -#define MCFGPIO_CLRR MCFGPIO_PCLRR_A /* clr output */ +#define MCFGPIO_PODR MCFGPIO_PORTA /* port output data */ +#define MCFGPIO_PDDR MCFGPIO_DDRA /* port data direction */ +#define MCFGPIO_PPDR MCFGPIO_PORTAP /* port pin data */ +#define MCFGPIO_SETR MCFGPIO_SETA /* set output */ +#define MCFGPIO_CLRR MCFGPIO_CLRA /* clr output */ #define MCFGPIO_IRQ_MAX 8 #define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE diff --git a/trunk/arch/m68k/include/asm/mcfgpio.h b/trunk/arch/m68k/include/asm/mcfgpio.h index fe468eaa51e0..ee5e4ccce89e 100644 --- a/trunk/arch/m68k/include/asm/mcfgpio.h +++ b/trunk/arch/m68k/include/asm/mcfgpio.h @@ -29,9 +29,6 @@ struct mcf_gpio_chip { const u8 *gpio_to_pinmux; }; -extern struct mcf_gpio_chip mcf_gpio_chips[]; -extern unsigned int mcf_gpio_chips_size; - int mcf_gpio_direction_input(struct gpio_chip *, unsigned); int mcf_gpio_get_value(struct gpio_chip *, unsigned); int mcf_gpio_direction_output(struct gpio_chip *, unsigned, int); @@ -40,58 +37,4 @@ void mcf_gpio_set_value_fast(struct gpio_chip *, unsigned, int); int mcf_gpio_request(struct gpio_chip *, unsigned); void mcf_gpio_free(struct gpio_chip *, unsigned); -/* - * Define macros to ease the pain of setting up the GPIO tables. There - * are two cases we need to deal with here, they cover all currently - * available ColdFire GPIO hardware. There are of course minor differences - * in the layout and number of bits in each ColdFire part, but the macros - * take all that in. - * - * Firstly is the conventional GPIO registers where we toggle individual - * bits in a register, preserving the other bits in the register. For - * lack of a better term I have called this the slow method. - */ -#define MCFGPS(mlabel, mbase, mngpio, mpddr, mpodr, mppdr) \ - { \ - .gpio_chip = { \ - .label = #mlabel, \ - .request = mcf_gpio_request, \ - .free = mcf_gpio_free, \ - .direction_input = mcf_gpio_direction_input, \ - .direction_output = mcf_gpio_direction_output,\ - .get = mcf_gpio_get_value, \ - .set = mcf_gpio_set_value, \ - .base = mbase, \ - .ngpio = mngpio, \ - }, \ - .pddr = (void __iomem *) mpddr, \ - .podr = (void __iomem *) mpodr, \ - .ppdr = (void __iomem *) mppdr, \ - } - -/* - * Secondly is the faster case, where we have set and clear registers - * that allow us to set or clear a bit with a single write, not having - * to worry about preserving other bits. - */ -#define MCFGPF(mlabel, mbase, mngpio) \ - { \ - .gpio_chip = { \ - .label = #mlabel, \ - .request = mcf_gpio_request, \ - .free = mcf_gpio_free, \ - .direction_input = mcf_gpio_direction_input, \ - .direction_output = mcf_gpio_direction_output,\ - .get = mcf_gpio_get_value, \ - .set = mcf_gpio_set_value_fast, \ - .base = mbase, \ - .ngpio = mngpio, \ - }, \ - .pddr = (void __iomem *) MCFGPIO_PDDR_##mlabel, \ - .podr = (void __iomem *) MCFGPIO_PODR_##mlabel, \ - .ppdr = (void __iomem *) MCFGPIO_PPDSDR_##mlabel, \ - .setr = (void __iomem *) MCFGPIO_PPDSDR_##mlabel, \ - .clrr = (void __iomem *) MCFGPIO_PCLRR_##mlabel, \ - } - #endif diff --git a/trunk/arch/m68k/include/asm/unaligned.h b/trunk/arch/m68k/include/asm/unaligned.h index f4043ae63db1..019caa740c21 100644 --- a/trunk/arch/m68k/include/asm/unaligned.h +++ b/trunk/arch/m68k/include/asm/unaligned.h @@ -2,7 +2,7 @@ #define _ASM_M68K_UNALIGNED_H -#if defined(CONFIG_COLDFIRE) || defined(CONFIG_M68000) +#ifdef CONFIG_COLDFIRE #include #include #include diff --git a/trunk/arch/m68k/include/asm/vga.h b/trunk/arch/m68k/include/asm/vga.h deleted file mode 100644 index d3aa1401e7aa..000000000000 --- a/trunk/arch/m68k/include/asm/vga.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _ASM_M68K_VGA_H -#define _ASM_M68K_VGA_H - -#include - -/* - * FIXME - * Ugh, we don't have PCI space, so map readb() and friends to use raw I/O - * accessors, which are identical to the z_*() Zorro bus accessors. - * This should make cirrusfb work again on Amiga - */ -#undef inb_p -#undef inw_p -#undef outb_p -#undef outw -#undef readb -#undef writeb -#undef writew -#define inb_p(port) 0 -#define inw_p(port) 0 -#define outb_p(port, val) do { } while (0) -#define outw(port, val) do { } while (0) -#define readb raw_inb -#define writeb raw_outb -#define writew raw_outw - -#endif /* _ASM_M68K_VGA_H */ diff --git a/trunk/arch/m68k/kernel/Makefile b/trunk/arch/m68k/kernel/Makefile index 5c7070e21eb7..40d29a788b05 100644 --- a/trunk/arch/m68k/kernel/Makefile +++ b/trunk/arch/m68k/kernel/Makefile @@ -13,7 +13,7 @@ extra-$(CONFIG_SUN3X) := head.o extra-$(CONFIG_SUN3) := sun3-head.o extra-y += vmlinux.lds -obj-y := entry.o irq.o m68k_ksyms.o module.o process.o ptrace.o +obj-y := entry.o init_task.o irq.o m68k_ksyms.o module.o process.o ptrace.o obj-y += setup.o signal.o sys_m68k.o syscalltable.o time.o traps.o obj-$(CONFIG_MMU_MOTOROLA) += ints.o vectors.o diff --git a/trunk/arch/m68k/kernel/dma.c b/trunk/arch/m68k/kernel/dma.c index f6daf6e15d2e..90e8cb726c8c 100644 --- a/trunk/arch/m68k/kernel/dma.c +++ b/trunk/arch/m68k/kernel/dma.c @@ -1,164 +1,5 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include - -#include - #ifdef CONFIG_MMU - -void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *handle, gfp_t flag) -{ - struct page *page, **map; - pgprot_t pgprot; - void *addr; - int i, order; - - pr_debug("dma_alloc_coherent: %d,%x\n", size, flag); - - size = PAGE_ALIGN(size); - order = get_order(size); - - page = alloc_pages(flag, order); - if (!page) - return NULL; - - *handle = page_to_phys(page); - map = kmalloc(sizeof(struct page *) << order, flag & ~__GFP_DMA); - if (!map) { - __free_pages(page, order); - return NULL; - } - split_page(page, order); - - order = 1 << order; - size >>= PAGE_SHIFT; - map[0] = page; - for (i = 1; i < size; i++) - map[i] = page + i; - for (; i < order; i++) - __free_page(page + i); - pgprot = __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY); - if (CPU_IS_040_OR_060) - pgprot_val(pgprot) |= _PAGE_GLOBAL040 | _PAGE_NOCACHE_S; - else - pgprot_val(pgprot) |= _PAGE_NOCACHE030; - addr = vmap(map, size, VM_MAP, pgprot); - kfree(map); - - return addr; -} - -void dma_free_coherent(struct device *dev, size_t size, - void *addr, dma_addr_t handle) -{ - pr_debug("dma_free_coherent: %p, %x\n", addr, handle); - vfree(addr); -} - +#include "dma_mm.c" #else - -#include - -void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp) -{ - void *ret; - /* ignore region specifiers */ - gfp &= ~(__GFP_DMA | __GFP_HIGHMEM); - - if (dev == NULL || (*dev->dma_mask < 0xffffffff)) - gfp |= GFP_DMA; - ret = (void *)__get_free_pages(gfp, get_order(size)); - - if (ret != NULL) { - memset(ret, 0, size); - *dma_handle = virt_to_phys(ret); - } - return ret; -} - -void dma_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - free_pages((unsigned long)vaddr, get_order(size)); -} - -#endif /* CONFIG_MMU */ - -EXPORT_SYMBOL(dma_alloc_coherent); -EXPORT_SYMBOL(dma_free_coherent); - -void dma_sync_single_for_device(struct device *dev, dma_addr_t handle, - size_t size, enum dma_data_direction dir) -{ - switch (dir) { - case DMA_TO_DEVICE: - cache_push(handle, size); - break; - case DMA_FROM_DEVICE: - cache_clear(handle, size); - break; - default: - if (printk_ratelimit()) - printk("dma_sync_single_for_device: unsupported dir %u\n", dir); - break; - } -} -EXPORT_SYMBOL(dma_sync_single_for_device); - -void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents, - enum dma_data_direction dir) -{ - int i; - - for (i = 0; i < nents; sg++, i++) - dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir); -} -EXPORT_SYMBOL(dma_sync_sg_for_device); - -dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size, - enum dma_data_direction dir) -{ - dma_addr_t handle = virt_to_bus(addr); - - dma_sync_single_for_device(dev, handle, size, dir); - return handle; -} -EXPORT_SYMBOL(dma_map_single); - -dma_addr_t dma_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction dir) -{ - dma_addr_t handle = page_to_phys(page) + offset; - - dma_sync_single_for_device(dev, handle, size, dir); - return handle; -} -EXPORT_SYMBOL(dma_map_page); - -int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, - enum dma_data_direction dir) -{ - int i; - - for (i = 0; i < nents; sg++, i++) { - sg->dma_address = sg_phys(sg); - dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir); - } - return nents; -} -EXPORT_SYMBOL(dma_map_sg); +#include "dma_no.c" +#endif diff --git a/trunk/arch/m68k/kernel/dma_mm.c b/trunk/arch/m68k/kernel/dma_mm.c new file mode 100644 index 000000000000..a3c471b523f2 --- /dev/null +++ b/trunk/arch/m68k/kernel/dma_mm.c @@ -0,0 +1,131 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#undef DEBUG + +#include +#include +#include +#include +#include +#include +#include + +#include + +void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *handle, gfp_t flag) +{ + struct page *page, **map; + pgprot_t pgprot; + void *addr; + int i, order; + + pr_debug("dma_alloc_coherent: %d,%x\n", size, flag); + + size = PAGE_ALIGN(size); + order = get_order(size); + + page = alloc_pages(flag, order); + if (!page) + return NULL; + + *handle = page_to_phys(page); + map = kmalloc(sizeof(struct page *) << order, flag & ~__GFP_DMA); + if (!map) { + __free_pages(page, order); + return NULL; + } + split_page(page, order); + + order = 1 << order; + size >>= PAGE_SHIFT; + map[0] = page; + for (i = 1; i < size; i++) + map[i] = page + i; + for (; i < order; i++) + __free_page(page + i); + pgprot = __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY); + if (CPU_IS_040_OR_060) + pgprot_val(pgprot) |= _PAGE_GLOBAL040 | _PAGE_NOCACHE_S; + else + pgprot_val(pgprot) |= _PAGE_NOCACHE030; + addr = vmap(map, size, VM_MAP, pgprot); + kfree(map); + + return addr; +} +EXPORT_SYMBOL(dma_alloc_coherent); + +void dma_free_coherent(struct device *dev, size_t size, + void *addr, dma_addr_t handle) +{ + pr_debug("dma_free_coherent: %p, %x\n", addr, handle); + vfree(addr); +} +EXPORT_SYMBOL(dma_free_coherent); + +void dma_sync_single_for_device(struct device *dev, dma_addr_t handle, + size_t size, enum dma_data_direction dir) +{ + switch (dir) { + case DMA_TO_DEVICE: + cache_push(handle, size); + break; + case DMA_FROM_DEVICE: + cache_clear(handle, size); + break; + default: + if (printk_ratelimit()) + printk("dma_sync_single_for_device: unsupported dir %u\n", dir); + break; + } +} +EXPORT_SYMBOL(dma_sync_single_for_device); + +void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction dir) +{ + int i; + + for (i = 0; i < nents; sg++, i++) + dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir); +} +EXPORT_SYMBOL(dma_sync_sg_for_device); + +dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size, + enum dma_data_direction dir) +{ + dma_addr_t handle = virt_to_bus(addr); + + dma_sync_single_for_device(dev, handle, size, dir); + return handle; +} +EXPORT_SYMBOL(dma_map_single); + +dma_addr_t dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction dir) +{ + dma_addr_t handle = page_to_phys(page) + offset; + + dma_sync_single_for_device(dev, handle, size, dir); + return handle; +} +EXPORT_SYMBOL(dma_map_page); + +int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction dir) +{ + int i; + + for (i = 0; i < nents; sg++, i++) { + sg->dma_address = sg_phys(sg); + dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir); + } + return nents; +} +EXPORT_SYMBOL(dma_map_sg); diff --git a/trunk/arch/m68k/kernel/dma_no.c b/trunk/arch/m68k/kernel/dma_no.c new file mode 100644 index 000000000000..f1dc3fc71bc2 --- /dev/null +++ b/trunk/arch/m68k/kernel/dma_no.c @@ -0,0 +1,75 @@ +/* + * Dynamic DMA mapping support. + * + * We never have any address translations to worry about, so this + * is just alloc/free. + */ + +#include +#include +#include +#include +#include +#include +#include + +void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp) +{ + void *ret; + /* ignore region specifiers */ + gfp &= ~(__GFP_DMA | __GFP_HIGHMEM); + + if (dev == NULL || (*dev->dma_mask < 0xffffffff)) + gfp |= GFP_DMA; + ret = (void *)__get_free_pages(gfp, get_order(size)); + + if (ret != NULL) { + memset(ret, 0, size); + *dma_handle = virt_to_phys(ret); + } + return ret; +} + +void dma_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + free_pages((unsigned long)vaddr, get_order(size)); +} + +void dma_sync_single_for_device(struct device *dev, dma_addr_t handle, + size_t size, enum dma_data_direction dir) +{ + switch (dir) { + case DMA_TO_DEVICE: + flush_dcache_range(handle, size); + break; + case DMA_FROM_DEVICE: + /* Should be clear already */ + break; + default: + if (printk_ratelimit()) + printk("dma_sync_single_for_device: unsupported dir %u\n", dir); + break; + } +} + +EXPORT_SYMBOL(dma_sync_single_for_device); +dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size, + enum dma_data_direction dir) +{ + dma_addr_t handle = virt_to_phys(addr); + flush_dcache_range(handle, size); + return handle; +} +EXPORT_SYMBOL(dma_map_single); + +dma_addr_t dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction dir) +{ + dma_addr_t handle = page_to_phys(page) + offset; + dma_sync_single_for_device(dev, handle, size, dir); + return handle; +} +EXPORT_SYMBOL(dma_map_page); diff --git a/trunk/arch/m68k/kernel/init_task.c b/trunk/arch/m68k/kernel/init_task.c new file mode 100644 index 000000000000..c744cfc6bfa1 --- /dev/null +++ b/trunk/arch/m68k/kernel/init_task.c @@ -0,0 +1,35 @@ +/* + * linux/arch/m68knommu/kernel/init_task.c + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); + +EXPORT_SYMBOL(init_task); + +/* + * Initial thread structure. + * + * We need to make sure that this is THREAD size aligned due to the + * way process stacks are handled. This is done by having a special + * "init_task" linker map entry.. + */ +union thread_union init_thread_union __init_task_data = + { INIT_THREAD_INFO(init_task) }; + diff --git a/trunk/arch/m68k/kernel/signal.c b/trunk/arch/m68k/kernel/signal.c index 1747c7030a33..2e25713e2ead 100644 --- a/trunk/arch/m68k/kernel/signal.c +++ b/trunk/arch/m68k/kernel/signal.c @@ -1,1202 +1,5 @@ -/* - * linux/arch/m68k/kernel/signal.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -/* - * Linux/m68k support by Hamish Macdonald - * - * 68060 fixes by Jesper Skov - * - * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab - * - * mathemu support by Roman Zippel - * (Note: fpstate in the signal context is completely ignored for the emulator - * and the internal floating point format is put on stack) - */ - -/* - * ++roman (07/09/96): implemented signal stacks (specially for tosemu on - * Atari :-) Current limitation: Only one sigstack can be active at one time. - * If a second signal with SA_ONSTACK set arrives while working on a sigstack, - * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested - * signal handlers! - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - #ifdef CONFIG_MMU - -/* - * Handle the slight differences in classic 68k and ColdFire trap frames. - */ -#ifdef CONFIG_COLDFIRE -#define FORMAT 4 -#define FMT4SIZE 0 +#include "signal_mm.c" #else -#define FORMAT 0 -#define FMT4SIZE sizeof(((struct frame *)0)->un.fmt4) +#include "signal_no.c" #endif - -static const int frame_size_change[16] = { - [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */ - [2] = sizeof(((struct frame *)0)->un.fmt2), - [3] = sizeof(((struct frame *)0)->un.fmt3), - [4] = FMT4SIZE, - [5] = -1, /* sizeof(((struct frame *)0)->un.fmt5), */ - [6] = -1, /* sizeof(((struct frame *)0)->un.fmt6), */ - [7] = sizeof(((struct frame *)0)->un.fmt7), - [8] = -1, /* sizeof(((struct frame *)0)->un.fmt8), */ - [9] = sizeof(((struct frame *)0)->un.fmt9), - [10] = sizeof(((struct frame *)0)->un.fmta), - [11] = sizeof(((struct frame *)0)->un.fmtb), - [12] = -1, /* sizeof(((struct frame *)0)->un.fmtc), */ - [13] = -1, /* sizeof(((struct frame *)0)->un.fmtd), */ - [14] = -1, /* sizeof(((struct frame *)0)->un.fmte), */ - [15] = -1, /* sizeof(((struct frame *)0)->un.fmtf), */ -}; - -static inline int frame_extra_sizes(int f) -{ - return frame_size_change[f]; -} - -int handle_kernel_fault(struct pt_regs *regs) -{ - const struct exception_table_entry *fixup; - struct pt_regs *tregs; - - /* Are we prepared to handle this kernel fault? */ - fixup = search_exception_tables(regs->pc); - if (!fixup) - return 0; - - /* Create a new four word stack frame, discarding the old one. */ - regs->stkadj = frame_extra_sizes(regs->format); - tregs = (struct pt_regs *)((long)regs + regs->stkadj); - tregs->vector = regs->vector; - tregs->format = FORMAT; - tregs->pc = fixup->fixup; - tregs->sr = regs->sr; - - return 1; -} - -void ptrace_signal_deliver(struct pt_regs *regs, void *cookie) -{ - if (regs->orig_d0 < 0) - return; - switch (regs->d0) { - case -ERESTARTNOHAND: - case -ERESTARTSYS: - case -ERESTARTNOINTR: - regs->d0 = regs->orig_d0; - regs->orig_d0 = -1; - regs->pc -= 2; - break; - } -} - -static inline void push_cache (unsigned long vaddr) -{ - /* - * Using the old cache_push_v() was really a big waste. - * - * What we are trying to do is to flush 8 bytes to ram. - * Flushing 2 cache lines of 16 bytes is much cheaper than - * flushing 1 or 2 pages, as previously done in - * cache_push_v(). - * Jes - */ - if (CPU_IS_040) { - unsigned long temp; - - __asm__ __volatile__ (".chip 68040\n\t" - "nop\n\t" - "ptestr (%1)\n\t" - "movec %%mmusr,%0\n\t" - ".chip 68k" - : "=r" (temp) - : "a" (vaddr)); - - temp &= PAGE_MASK; - temp |= vaddr & ~PAGE_MASK; - - __asm__ __volatile__ (".chip 68040\n\t" - "nop\n\t" - "cpushl %%bc,(%0)\n\t" - ".chip 68k" - : : "a" (temp)); - } - else if (CPU_IS_060) { - unsigned long temp; - __asm__ __volatile__ (".chip 68060\n\t" - "plpar (%0)\n\t" - ".chip 68k" - : "=a" (temp) - : "0" (vaddr)); - __asm__ __volatile__ (".chip 68060\n\t" - "cpushl %%bc,(%0)\n\t" - ".chip 68k" - : : "a" (temp)); - } else if (!CPU_IS_COLDFIRE) { - /* - * 68030/68020 have no writeback cache; - * still need to clear icache. - * Note that vaddr is guaranteed to be long word aligned. - */ - unsigned long temp; - asm volatile ("movec %%cacr,%0" : "=r" (temp)); - temp += 4; - asm volatile ("movec %0,%%caar\n\t" - "movec %1,%%cacr" - : : "r" (vaddr), "r" (temp)); - asm volatile ("movec %0,%%caar\n\t" - "movec %1,%%cacr" - : : "r" (vaddr + 4), "r" (temp)); - } -} - -static inline void adjustformat(struct pt_regs *regs) -{ -} - -static inline void save_a5_state(struct sigcontext *sc, struct pt_regs *regs) -{ -} - -#else /* CONFIG_MMU */ - -void ret_from_user_signal(void); -void ret_from_user_rt_signal(void); - -static inline int frame_extra_sizes(int f) -{ - /* No frame size adjustments required on non-MMU CPUs */ - return 0; -} - -static inline void adjustformat(struct pt_regs *regs) -{ - ((struct switch_stack *)regs - 1)->a5 = current->mm->start_data; - /* - * set format byte to make stack appear modulo 4, which it will - * be when doing the rte - */ - regs->format = 0x4; -} - -static inline void save_a5_state(struct sigcontext *sc, struct pt_regs *regs) -{ - sc->sc_a5 = ((struct switch_stack *)regs - 1)->a5; -} - -static inline void push_cache(unsigned long vaddr) -{ -} - -#endif /* CONFIG_MMU */ - -/* - * Atomically swap in the new signal mask, and wait for a signal. - */ -asmlinkage int -sys_sigsuspend(int unused0, int unused1, old_sigset_t mask) -{ - mask &= _BLOCKABLE; - spin_lock_irq(¤t->sighand->siglock); - current->saved_sigmask = current->blocked; - siginitset(¤t->blocked, mask); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - current->state = TASK_INTERRUPTIBLE; - schedule(); - set_restore_sigmask(); - - return -ERESTARTNOHAND; -} - -asmlinkage int -sys_sigaction(int sig, const struct old_sigaction __user *act, - struct old_sigaction __user *oact) -{ - struct k_sigaction new_ka, old_ka; - int ret; - - if (act) { - old_sigset_t mask; - if (!access_ok(VERIFY_READ, act, sizeof(*act)) || - __get_user(new_ka.sa.sa_handler, &act->sa_handler) || - __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || - __get_user(new_ka.sa.sa_flags, &act->sa_flags) || - __get_user(mask, &act->sa_mask)) - return -EFAULT; - siginitset(&new_ka.sa.sa_mask, mask); - } - - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); - - if (!ret && oact) { - if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || - __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || - __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || - __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || - __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) - return -EFAULT; - } - - return ret; -} - -asmlinkage int -sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) -{ - return do_sigaltstack(uss, uoss, rdusp()); -} - - -/* - * Do a signal return; undo the signal stack. - * - * Keep the return code on the stack quadword aligned! - * That makes the cache flush below easier. - */ - -struct sigframe -{ - char __user *pretcode; - int sig; - int code; - struct sigcontext __user *psc; - char retcode[8]; - unsigned long extramask[_NSIG_WORDS-1]; - struct sigcontext sc; -}; - -struct rt_sigframe -{ - char __user *pretcode; - int sig; - struct siginfo __user *pinfo; - void __user *puc; - char retcode[8]; - struct siginfo info; - struct ucontext uc; -}; - -#define FPCONTEXT_SIZE 216 -#define uc_fpstate uc_filler[0] -#define uc_formatvec uc_filler[FPCONTEXT_SIZE/4] -#define uc_extra uc_filler[FPCONTEXT_SIZE/4+1] - -#ifdef CONFIG_FPU - -static unsigned char fpu_version; /* version number of fpu, set by setup_frame */ - -static inline int restore_fpu_state(struct sigcontext *sc) -{ - int err = 1; - - if (FPU_IS_EMU) { - /* restore registers */ - memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12); - memcpy(current->thread.fp, sc->sc_fpregs, 24); - return 0; - } - - if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) { - /* Verify the frame format. */ - if (!(CPU_IS_060 || CPU_IS_COLDFIRE) && - (sc->sc_fpstate[0] != fpu_version)) - goto out; - if (CPU_IS_020_OR_030) { - if (m68k_fputype & FPU_68881 && - !(sc->sc_fpstate[1] == 0x18 || sc->sc_fpstate[1] == 0xb4)) - goto out; - if (m68k_fputype & FPU_68882 && - !(sc->sc_fpstate[1] == 0x38 || sc->sc_fpstate[1] == 0xd4)) - goto out; - } else if (CPU_IS_040) { - if (!(sc->sc_fpstate[1] == 0x00 || - sc->sc_fpstate[1] == 0x28 || - sc->sc_fpstate[1] == 0x60)) - goto out; - } else if (CPU_IS_060) { - if (!(sc->sc_fpstate[3] == 0x00 || - sc->sc_fpstate[3] == 0x60 || - sc->sc_fpstate[3] == 0xe0)) - goto out; - } else if (CPU_IS_COLDFIRE) { - if (!(sc->sc_fpstate[0] == 0x00 || - sc->sc_fpstate[0] == 0x05 || - sc->sc_fpstate[0] == 0xe5)) - goto out; - } else - goto out; - - if (CPU_IS_COLDFIRE) { - __asm__ volatile ("fmovemd %0,%%fp0-%%fp1\n\t" - "fmovel %1,%%fpcr\n\t" - "fmovel %2,%%fpsr\n\t" - "fmovel %3,%%fpiar" - : /* no outputs */ - : "m" (sc->sc_fpregs[0]), - "m" (sc->sc_fpcntl[0]), - "m" (sc->sc_fpcntl[1]), - "m" (sc->sc_fpcntl[2])); - } else { - __asm__ volatile (".chip 68k/68881\n\t" - "fmovemx %0,%%fp0-%%fp1\n\t" - "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" - ".chip 68k" - : /* no outputs */ - : "m" (*sc->sc_fpregs), - "m" (*sc->sc_fpcntl)); - } - } - - if (CPU_IS_COLDFIRE) { - __asm__ volatile ("frestore %0" : : "m" (*sc->sc_fpstate)); - } else { - __asm__ volatile (".chip 68k/68881\n\t" - "frestore %0\n\t" - ".chip 68k" - : : "m" (*sc->sc_fpstate)); - } - err = 0; - -out: - return err; -} - -static inline int rt_restore_fpu_state(struct ucontext __user *uc) -{ - unsigned char fpstate[FPCONTEXT_SIZE]; - int context_size = CPU_IS_060 ? 8 : (CPU_IS_COLDFIRE ? 12 : 0); - fpregset_t fpregs; - int err = 1; - - if (FPU_IS_EMU) { - /* restore fpu control register */ - if (__copy_from_user(current->thread.fpcntl, - uc->uc_mcontext.fpregs.f_fpcntl, 12)) - goto out; - /* restore all other fpu register */ - if (__copy_from_user(current->thread.fp, - uc->uc_mcontext.fpregs.f_fpregs, 96)) - goto out; - return 0; - } - - if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate)) - goto out; - if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { - if (!(CPU_IS_060 || CPU_IS_COLDFIRE)) - context_size = fpstate[1]; - /* Verify the frame format. */ - if (!(CPU_IS_060 || CPU_IS_COLDFIRE) && - (fpstate[0] != fpu_version)) - goto out; - if (CPU_IS_020_OR_030) { - if (m68k_fputype & FPU_68881 && - !(context_size == 0x18 || context_size == 0xb4)) - goto out; - if (m68k_fputype & FPU_68882 && - !(context_size == 0x38 || context_size == 0xd4)) - goto out; - } else if (CPU_IS_040) { - if (!(context_size == 0x00 || - context_size == 0x28 || - context_size == 0x60)) - goto out; - } else if (CPU_IS_060) { - if (!(fpstate[3] == 0x00 || - fpstate[3] == 0x60 || - fpstate[3] == 0xe0)) - goto out; - } else if (CPU_IS_COLDFIRE) { - if (!(fpstate[3] == 0x00 || - fpstate[3] == 0x05 || - fpstate[3] == 0xe5)) - goto out; - } else - goto out; - if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs, - sizeof(fpregs))) - goto out; - - if (CPU_IS_COLDFIRE) { - __asm__ volatile ("fmovemd %0,%%fp0-%%fp7\n\t" - "fmovel %1,%%fpcr\n\t" - "fmovel %2,%%fpsr\n\t" - "fmovel %3,%%fpiar" - : /* no outputs */ - : "m" (fpregs.f_fpregs[0]), - "m" (fpregs.f_fpcntl[0]), - "m" (fpregs.f_fpcntl[1]), - "m" (fpregs.f_fpcntl[2])); - } else { - __asm__ volatile (".chip 68k/68881\n\t" - "fmovemx %0,%%fp0-%%fp7\n\t" - "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" - ".chip 68k" - : /* no outputs */ - : "m" (*fpregs.f_fpregs), - "m" (*fpregs.f_fpcntl)); - } - } - if (context_size && - __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1, - context_size)) - goto out; - - if (CPU_IS_COLDFIRE) { - __asm__ volatile ("frestore %0" : : "m" (*fpstate)); - } else { - __asm__ volatile (".chip 68k/68881\n\t" - "frestore %0\n\t" - ".chip 68k" - : : "m" (*fpstate)); - } - err = 0; - -out: - return err; -} - -/* - * Set up a signal frame. - */ -static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs) -{ - if (FPU_IS_EMU) { - /* save registers */ - memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12); - memcpy(sc->sc_fpregs, current->thread.fp, 24); - return; - } - - if (CPU_IS_COLDFIRE) { - __asm__ volatile ("fsave %0" - : : "m" (*sc->sc_fpstate) : "memory"); - } else { - __asm__ volatile (".chip 68k/68881\n\t" - "fsave %0\n\t" - ".chip 68k" - : : "m" (*sc->sc_fpstate) : "memory"); - } - - if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) { - fpu_version = sc->sc_fpstate[0]; - if (CPU_IS_020_OR_030 && - regs->vector >= (VEC_FPBRUC * 4) && - regs->vector <= (VEC_FPNAN * 4)) { - /* Clear pending exception in 68882 idle frame */ - if (*(unsigned short *) sc->sc_fpstate == 0x1f38) - sc->sc_fpstate[0x38] |= 1 << 3; - } - - if (CPU_IS_COLDFIRE) { - __asm__ volatile ("fmovemd %%fp0-%%fp1,%0\n\t" - "fmovel %%fpcr,%1\n\t" - "fmovel %%fpsr,%2\n\t" - "fmovel %%fpiar,%3" - : "=m" (sc->sc_fpregs[0]), - "=m" (sc->sc_fpcntl[0]), - "=m" (sc->sc_fpcntl[1]), - "=m" (sc->sc_fpcntl[2]) - : /* no inputs */ - : "memory"); - } else { - __asm__ volatile (".chip 68k/68881\n\t" - "fmovemx %%fp0-%%fp1,%0\n\t" - "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" - ".chip 68k" - : "=m" (*sc->sc_fpregs), - "=m" (*sc->sc_fpcntl) - : /* no inputs */ - : "memory"); - } - } -} - -static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs) -{ - unsigned char fpstate[FPCONTEXT_SIZE]; - int context_size = CPU_IS_060 ? 8 : (CPU_IS_COLDFIRE ? 12 : 0); - int err = 0; - - if (FPU_IS_EMU) { - /* save fpu control register */ - err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpcntl, - current->thread.fpcntl, 12); - /* save all other fpu register */ - err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs, - current->thread.fp, 96); - return err; - } - - if (CPU_IS_COLDFIRE) { - __asm__ volatile ("fsave %0" : : "m" (*fpstate) : "memory"); - } else { - __asm__ volatile (".chip 68k/68881\n\t" - "fsave %0\n\t" - ".chip 68k" - : : "m" (*fpstate) : "memory"); - } - - err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate); - if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { - fpregset_t fpregs; - if (!(CPU_IS_060 || CPU_IS_COLDFIRE)) - context_size = fpstate[1]; - fpu_version = fpstate[0]; - if (CPU_IS_020_OR_030 && - regs->vector >= (VEC_FPBRUC * 4) && - regs->vector <= (VEC_FPNAN * 4)) { - /* Clear pending exception in 68882 idle frame */ - if (*(unsigned short *) fpstate == 0x1f38) - fpstate[0x38] |= 1 << 3; - } - if (CPU_IS_COLDFIRE) { - __asm__ volatile ("fmovemd %%fp0-%%fp7,%0\n\t" - "fmovel %%fpcr,%1\n\t" - "fmovel %%fpsr,%2\n\t" - "fmovel %%fpiar,%3" - : "=m" (fpregs.f_fpregs[0]), - "=m" (fpregs.f_fpcntl[0]), - "=m" (fpregs.f_fpcntl[1]), - "=m" (fpregs.f_fpcntl[2]) - : /* no inputs */ - : "memory"); - } else { - __asm__ volatile (".chip 68k/68881\n\t" - "fmovemx %%fp0-%%fp7,%0\n\t" - "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" - ".chip 68k" - : "=m" (*fpregs.f_fpregs), - "=m" (*fpregs.f_fpcntl) - : /* no inputs */ - : "memory"); - } - err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs, - sizeof(fpregs)); - } - if (context_size) - err |= copy_to_user((long __user *)&uc->uc_fpstate + 1, fpstate + 4, - context_size); - return err; -} - -#else /* CONFIG_FPU */ - -/* - * For the case with no FPU configured these all do nothing. - */ -static inline int restore_fpu_state(struct sigcontext *sc) -{ - return 0; -} - -static inline int rt_restore_fpu_state(struct ucontext __user *uc) -{ - return 0; -} - -static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs) -{ -} - -static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs) -{ - return 0; -} - -#endif /* CONFIG_FPU */ - -static int mangle_kernel_stack(struct pt_regs *regs, int formatvec, - void __user *fp) -{ - int fsize = frame_extra_sizes(formatvec >> 12); - if (fsize < 0) { - /* - * user process trying to return with weird frame format - */ -#ifdef DEBUG - printk("user process returning with weird frame format\n"); -#endif - return 1; - } - if (!fsize) { - regs->format = formatvec >> 12; - regs->vector = formatvec & 0xfff; - } else { - struct switch_stack *sw = (struct switch_stack *)regs - 1; - unsigned long buf[fsize / 2]; /* yes, twice as much */ - - /* that'll make sure that expansion won't crap over data */ - if (copy_from_user(buf + fsize / 4, fp, fsize)) - return 1; - - /* point of no return */ - regs->format = formatvec >> 12; - regs->vector = formatvec & 0xfff; -#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack)) - __asm__ __volatile__ ( -#ifdef CONFIG_COLDFIRE - " movel %0,%/sp\n\t" - " bra ret_from_signal\n" -#else - " movel %0,%/a0\n\t" - " subl %1,%/a0\n\t" /* make room on stack */ - " movel %/a0,%/sp\n\t" /* set stack pointer */ - /* move switch_stack and pt_regs */ - "1: movel %0@+,%/a0@+\n\t" - " dbra %2,1b\n\t" - " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */ - " lsrl #2,%1\n\t" - " subql #1,%1\n\t" - /* copy to the gap we'd made */ - "2: movel %4@+,%/a0@+\n\t" - " dbra %1,2b\n\t" - " bral ret_from_signal\n" -#endif - : /* no outputs, it doesn't ever return */ - : "a" (sw), "d" (fsize), "d" (frame_offset/4-1), - "n" (frame_offset), "a" (buf + fsize/4) - : "a0"); -#undef frame_offset - } - return 0; -} - -static inline int -restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp) -{ - int formatvec; - struct sigcontext context; - int err = 0; - - /* Always make any pending restarted system calls return -EINTR */ - current_thread_info()->restart_block.fn = do_no_restart_syscall; - - /* get previous context */ - if (copy_from_user(&context, usc, sizeof(context))) - goto badframe; - - /* restore passed registers */ - regs->d0 = context.sc_d0; - regs->d1 = context.sc_d1; - regs->a0 = context.sc_a0; - regs->a1 = context.sc_a1; - regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff); - regs->pc = context.sc_pc; - regs->orig_d0 = -1; /* disable syscall checks */ - wrusp(context.sc_usp); - formatvec = context.sc_formatvec; - - err = restore_fpu_state(&context); - - if (err || mangle_kernel_stack(regs, formatvec, fp)) - goto badframe; - - return 0; - -badframe: - return 1; -} - -static inline int -rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw, - struct ucontext __user *uc) -{ - int temp; - greg_t __user *gregs = uc->uc_mcontext.gregs; - unsigned long usp; - int err; - - /* Always make any pending restarted system calls return -EINTR */ - current_thread_info()->restart_block.fn = do_no_restart_syscall; - - err = __get_user(temp, &uc->uc_mcontext.version); - if (temp != MCONTEXT_VERSION) - goto badframe; - /* restore passed registers */ - err |= __get_user(regs->d0, &gregs[0]); - err |= __get_user(regs->d1, &gregs[1]); - err |= __get_user(regs->d2, &gregs[2]); - err |= __get_user(regs->d3, &gregs[3]); - err |= __get_user(regs->d4, &gregs[4]); - err |= __get_user(regs->d5, &gregs[5]); - err |= __get_user(sw->d6, &gregs[6]); - err |= __get_user(sw->d7, &gregs[7]); - err |= __get_user(regs->a0, &gregs[8]); - err |= __get_user(regs->a1, &gregs[9]); - err |= __get_user(regs->a2, &gregs[10]); - err |= __get_user(sw->a3, &gregs[11]); - err |= __get_user(sw->a4, &gregs[12]); - err |= __get_user(sw->a5, &gregs[13]); - err |= __get_user(sw->a6, &gregs[14]); - err |= __get_user(usp, &gregs[15]); - wrusp(usp); - err |= __get_user(regs->pc, &gregs[16]); - err |= __get_user(temp, &gregs[17]); - regs->sr = (regs->sr & 0xff00) | (temp & 0xff); - regs->orig_d0 = -1; /* disable syscall checks */ - err |= __get_user(temp, &uc->uc_formatvec); - - err |= rt_restore_fpu_state(uc); - - if (err || do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT) - goto badframe; - - if (mangle_kernel_stack(regs, temp, &uc->uc_extra)) - goto badframe; - - return 0; - -badframe: - return 1; -} - -asmlinkage int do_sigreturn(unsigned long __unused) -{ - struct switch_stack *sw = (struct switch_stack *) &__unused; - struct pt_regs *regs = (struct pt_regs *) (sw + 1); - unsigned long usp = rdusp(); - struct sigframe __user *frame = (struct sigframe __user *)(usp - 4); - sigset_t set; - - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) - goto badframe; - if (__get_user(set.sig[0], &frame->sc.sc_mask) || - (_NSIG_WORDS > 1 && - __copy_from_user(&set.sig[1], &frame->extramask, - sizeof(frame->extramask)))) - goto badframe; - - sigdelsetmask(&set, ~_BLOCKABLE); - current->blocked = set; - recalc_sigpending(); - - if (restore_sigcontext(regs, &frame->sc, frame + 1)) - goto badframe; - return regs->d0; - -badframe: - force_sig(SIGSEGV, current); - return 0; -} - -asmlinkage int do_rt_sigreturn(unsigned long __unused) -{ - struct switch_stack *sw = (struct switch_stack *) &__unused; - struct pt_regs *regs = (struct pt_regs *) (sw + 1); - unsigned long usp = rdusp(); - struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4); - sigset_t set; - - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) - goto badframe; - if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) - goto badframe; - - sigdelsetmask(&set, ~_BLOCKABLE); - current->blocked = set; - recalc_sigpending(); - - if (rt_restore_ucontext(regs, sw, &frame->uc)) - goto badframe; - return regs->d0; - -badframe: - force_sig(SIGSEGV, current); - return 0; -} - -static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, - unsigned long mask) -{ - sc->sc_mask = mask; - sc->sc_usp = rdusp(); - sc->sc_d0 = regs->d0; - sc->sc_d1 = regs->d1; - sc->sc_a0 = regs->a0; - sc->sc_a1 = regs->a1; - sc->sc_sr = regs->sr; - sc->sc_pc = regs->pc; - sc->sc_formatvec = regs->format << 12 | regs->vector; - save_a5_state(sc, regs); - save_fpu_state(sc, regs); -} - -static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs) -{ - struct switch_stack *sw = (struct switch_stack *)regs - 1; - greg_t __user *gregs = uc->uc_mcontext.gregs; - int err = 0; - - err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version); - err |= __put_user(regs->d0, &gregs[0]); - err |= __put_user(regs->d1, &gregs[1]); - err |= __put_user(regs->d2, &gregs[2]); - err |= __put_user(regs->d3, &gregs[3]); - err |= __put_user(regs->d4, &gregs[4]); - err |= __put_user(regs->d5, &gregs[5]); - err |= __put_user(sw->d6, &gregs[6]); - err |= __put_user(sw->d7, &gregs[7]); - err |= __put_user(regs->a0, &gregs[8]); - err |= __put_user(regs->a1, &gregs[9]); - err |= __put_user(regs->a2, &gregs[10]); - err |= __put_user(sw->a3, &gregs[11]); - err |= __put_user(sw->a4, &gregs[12]); - err |= __put_user(sw->a5, &gregs[13]); - err |= __put_user(sw->a6, &gregs[14]); - err |= __put_user(rdusp(), &gregs[15]); - err |= __put_user(regs->pc, &gregs[16]); - err |= __put_user(regs->sr, &gregs[17]); - err |= __put_user((regs->format << 12) | regs->vector, &uc->uc_formatvec); - err |= rt_save_fpu_state(uc, regs); - return err; -} - -static inline void __user * -get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) -{ - unsigned long usp; - - /* Default to using normal stack. */ - usp = rdusp(); - - /* This is the X/Open sanctioned signal stack switching. */ - if (ka->sa.sa_flags & SA_ONSTACK) { - if (!sas_ss_flags(usp)) - usp = current->sas_ss_sp + current->sas_ss_size; - } - return (void __user *)((usp - frame_size) & -8UL); -} - -static int setup_frame (int sig, struct k_sigaction *ka, - sigset_t *set, struct pt_regs *regs) -{ - struct sigframe __user *frame; - int fsize = frame_extra_sizes(regs->format); - struct sigcontext context; - int err = 0; - - if (fsize < 0) { -#ifdef DEBUG - printk ("setup_frame: Unknown frame format %#x\n", - regs->format); -#endif - goto give_sigsegv; - } - - frame = get_sigframe(ka, regs, sizeof(*frame) + fsize); - - if (fsize) - err |= copy_to_user (frame + 1, regs + 1, fsize); - - err |= __put_user((current_thread_info()->exec_domain - && current_thread_info()->exec_domain->signal_invmap - && sig < 32 - ? current_thread_info()->exec_domain->signal_invmap[sig] - : sig), - &frame->sig); - - err |= __put_user(regs->vector, &frame->code); - err |= __put_user(&frame->sc, &frame->psc); - - if (_NSIG_WORDS > 1) - err |= copy_to_user(frame->extramask, &set->sig[1], - sizeof(frame->extramask)); - - setup_sigcontext(&context, regs, set->sig[0]); - err |= copy_to_user (&frame->sc, &context, sizeof(context)); - - /* Set up to return from userspace. */ -#ifdef CONFIG_MMU - err |= __put_user(frame->retcode, &frame->pretcode); - /* moveq #,d0; trap #0 */ - err |= __put_user(0x70004e40 + (__NR_sigreturn << 16), - (long __user *)(frame->retcode)); -#else - err |= __put_user((void *) ret_from_user_signal, &frame->pretcode); -#endif - - if (err) - goto give_sigsegv; - - push_cache ((unsigned long) &frame->retcode); - - /* - * Set up registers for signal handler. All the state we are about - * to destroy is successfully copied to sigframe. - */ - wrusp ((unsigned long) frame); - regs->pc = (unsigned long) ka->sa.sa_handler; - adjustformat(regs); - - /* - * This is subtle; if we build more than one sigframe, all but the - * first one will see frame format 0 and have fsize == 0, so we won't - * screw stkadj. - */ - if (fsize) - regs->stkadj = fsize; - - /* Prepare to skip over the extra stuff in the exception frame. */ - if (regs->stkadj) { - struct pt_regs *tregs = - (struct pt_regs *)((ulong)regs + regs->stkadj); -#ifdef DEBUG - printk("Performing stackadjust=%04x\n", regs->stkadj); -#endif - /* This must be copied with decreasing addresses to - handle overlaps. */ - tregs->vector = 0; - tregs->format = 0; - tregs->pc = regs->pc; - tregs->sr = regs->sr; - } - return 0; - -give_sigsegv: - force_sigsegv(sig, current); - return err; -} - -static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, - sigset_t *set, struct pt_regs *regs) -{ - struct rt_sigframe __user *frame; - int fsize = frame_extra_sizes(regs->format); - int err = 0; - - if (fsize < 0) { -#ifdef DEBUG - printk ("setup_frame: Unknown frame format %#x\n", - regs->format); -#endif - goto give_sigsegv; - } - - frame = get_sigframe(ka, regs, sizeof(*frame)); - - if (fsize) - err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize); - - err |= __put_user((current_thread_info()->exec_domain - && current_thread_info()->exec_domain->signal_invmap - && sig < 32 - ? current_thread_info()->exec_domain->signal_invmap[sig] - : sig), - &frame->sig); - err |= __put_user(&frame->info, &frame->pinfo); - err |= __put_user(&frame->uc, &frame->puc); - err |= copy_siginfo_to_user(&frame->info, info); - - /* Create the ucontext. */ - err |= __put_user(0, &frame->uc.uc_flags); - err |= __put_user(NULL, &frame->uc.uc_link); - err |= __put_user((void __user *)current->sas_ss_sp, - &frame->uc.uc_stack.ss_sp); - err |= __put_user(sas_ss_flags(rdusp()), - &frame->uc.uc_stack.ss_flags); - err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); - err |= rt_setup_ucontext(&frame->uc, regs); - err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set)); - - /* Set up to return from userspace. */ -#ifdef CONFIG_MMU - err |= __put_user(frame->retcode, &frame->pretcode); -#ifdef __mcoldfire__ - /* movel #__NR_rt_sigreturn,d0; trap #0 */ - err |= __put_user(0x203c0000, (long __user *)(frame->retcode + 0)); - err |= __put_user(0x00004e40 + (__NR_rt_sigreturn << 16), - (long __user *)(frame->retcode + 4)); -#else - /* moveq #,d0; notb d0; trap #0 */ - err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16), - (long __user *)(frame->retcode + 0)); - err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4)); -#endif -#else - err |= __put_user((void *) ret_from_user_rt_signal, &frame->pretcode); -#endif /* CONFIG_MMU */ - - if (err) - goto give_sigsegv; - - push_cache ((unsigned long) &frame->retcode); - - /* - * Set up registers for signal handler. All the state we are about - * to destroy is successfully copied to sigframe. - */ - wrusp ((unsigned long) frame); - regs->pc = (unsigned long) ka->sa.sa_handler; - adjustformat(regs); - - /* - * This is subtle; if we build more than one sigframe, all but the - * first one will see frame format 0 and have fsize == 0, so we won't - * screw stkadj. - */ - if (fsize) - regs->stkadj = fsize; - - /* Prepare to skip over the extra stuff in the exception frame. */ - if (regs->stkadj) { - struct pt_regs *tregs = - (struct pt_regs *)((ulong)regs + regs->stkadj); -#ifdef DEBUG - printk("Performing stackadjust=%04x\n", regs->stkadj); -#endif - /* This must be copied with decreasing addresses to - handle overlaps. */ - tregs->vector = 0; - tregs->format = 0; - tregs->pc = regs->pc; - tregs->sr = regs->sr; - } - return 0; - -give_sigsegv: - force_sigsegv(sig, current); - return err; -} - -static inline void -handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) -{ - switch (regs->d0) { - case -ERESTARTNOHAND: - if (!has_handler) - goto do_restart; - regs->d0 = -EINTR; - break; - - case -ERESTART_RESTARTBLOCK: - if (!has_handler) { - regs->d0 = __NR_restart_syscall; - regs->pc -= 2; - break; - } - regs->d0 = -EINTR; - break; - - case -ERESTARTSYS: - if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) { - regs->d0 = -EINTR; - break; - } - /* fallthrough */ - case -ERESTARTNOINTR: - do_restart: - regs->d0 = regs->orig_d0; - regs->pc -= 2; - break; - } -} - -/* - * OK, we're invoking a handler - */ -static void -handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, - sigset_t *oldset, struct pt_regs *regs) -{ - int err; - /* are we from a system call? */ - if (regs->orig_d0 >= 0) - /* If so, check system call restarting.. */ - handle_restart(regs, ka, 1); - - /* set up the stack frame */ - if (ka->sa.sa_flags & SA_SIGINFO) - err = setup_rt_frame(sig, ka, info, oldset, regs); - else - err = setup_frame(sig, ka, oldset, regs); - - if (err) - return; - - sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(¤t->blocked,sig); - recalc_sigpending(); - - if (test_thread_flag(TIF_DELAYED_TRACE)) { - regs->sr &= ~0x8000; - send_sig(SIGTRAP, current, 1); - } - - clear_thread_flag(TIF_RESTORE_SIGMASK); -} - -/* - * Note that 'init' is a special process: it doesn't get signals it doesn't - * want to handle. Thus you cannot kill init even with a SIGKILL even by - * mistake. - */ -asmlinkage void do_signal(struct pt_regs *regs) -{ - siginfo_t info; - struct k_sigaction ka; - int signr; - sigset_t *oldset; - - current->thread.esp0 = (unsigned long) regs; - - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - oldset = ¤t->saved_sigmask; - else - oldset = ¤t->blocked; - - signr = get_signal_to_deliver(&info, &ka, regs, NULL); - if (signr > 0) { - /* Whee! Actually deliver the signal. */ - handle_signal(signr, &ka, &info, oldset, regs); - return; - } - - /* Did we come from a system call? */ - if (regs->orig_d0 >= 0) - /* Restart the system call - no handlers present */ - handle_restart(regs, NULL, 0); - - /* If there's no signal to deliver, we just restore the saved mask. */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); - } -} diff --git a/trunk/arch/m68k/kernel/signal_mm.c b/trunk/arch/m68k/kernel/signal_mm.c new file mode 100644 index 000000000000..cb856f9da655 --- /dev/null +++ b/trunk/arch/m68k/kernel/signal_mm.c @@ -0,0 +1,1115 @@ +/* + * linux/arch/m68k/kernel/signal.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +/* + * Linux/m68k support by Hamish Macdonald + * + * 68060 fixes by Jesper Skov + * + * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab + * + * mathemu support by Roman Zippel + * (Note: fpstate in the signal context is completely ignored for the emulator + * and the internal floating point format is put on stack) + */ + +/* + * ++roman (07/09/96): implemented signal stacks (specially for tosemu on + * Atari :-) Current limitation: Only one sigstack can be active at one time. + * If a second signal with SA_ONSTACK set arrives while working on a sigstack, + * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested + * signal handlers! + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) + +static const int frame_extra_sizes[16] = { + [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */ + [2] = sizeof(((struct frame *)0)->un.fmt2), + [3] = sizeof(((struct frame *)0)->un.fmt3), +#ifdef CONFIG_COLDFIRE + [4] = 0, +#else + [4] = sizeof(((struct frame *)0)->un.fmt4), +#endif + [5] = -1, /* sizeof(((struct frame *)0)->un.fmt5), */ + [6] = -1, /* sizeof(((struct frame *)0)->un.fmt6), */ + [7] = sizeof(((struct frame *)0)->un.fmt7), + [8] = -1, /* sizeof(((struct frame *)0)->un.fmt8), */ + [9] = sizeof(((struct frame *)0)->un.fmt9), + [10] = sizeof(((struct frame *)0)->un.fmta), + [11] = sizeof(((struct frame *)0)->un.fmtb), + [12] = -1, /* sizeof(((struct frame *)0)->un.fmtc), */ + [13] = -1, /* sizeof(((struct frame *)0)->un.fmtd), */ + [14] = -1, /* sizeof(((struct frame *)0)->un.fmte), */ + [15] = -1, /* sizeof(((struct frame *)0)->un.fmtf), */ +}; + +int handle_kernel_fault(struct pt_regs *regs) +{ + const struct exception_table_entry *fixup; + struct pt_regs *tregs; + + /* Are we prepared to handle this kernel fault? */ + fixup = search_exception_tables(regs->pc); + if (!fixup) + return 0; + + /* Create a new four word stack frame, discarding the old one. */ + regs->stkadj = frame_extra_sizes[regs->format]; + tregs = (struct pt_regs *)((long)regs + regs->stkadj); + tregs->vector = regs->vector; +#ifdef CONFIG_COLDFIRE + tregs->format = 4; +#else + tregs->format = 0; +#endif + tregs->pc = fixup->fixup; + tregs->sr = regs->sr; + + return 1; +} + +/* + * Atomically swap in the new signal mask, and wait for a signal. + */ +asmlinkage int +sys_sigsuspend(int unused0, int unused1, old_sigset_t mask) +{ + mask &= _BLOCKABLE; + spin_lock_irq(¤t->sighand->siglock); + current->saved_sigmask = current->blocked; + siginitset(¤t->blocked, mask); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + current->state = TASK_INTERRUPTIBLE; + schedule(); + set_restore_sigmask(); + + return -ERESTARTNOHAND; +} + +asmlinkage int +sys_sigaction(int sig, const struct old_sigaction __user *act, + struct old_sigaction __user *oact) +{ + struct k_sigaction new_ka, old_ka; + int ret; + + if (act) { + old_sigset_t mask; + if (!access_ok(VERIFY_READ, act, sizeof(*act)) || + __get_user(new_ka.sa.sa_handler, &act->sa_handler) || + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || + __get_user(new_ka.sa.sa_flags, &act->sa_flags) || + __get_user(mask, &act->sa_mask)) + return -EFAULT; + siginitset(&new_ka.sa.sa_mask, mask); + } + + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); + + if (!ret && oact) { + if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || + __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || + __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) + return -EFAULT; + } + + return ret; +} + +asmlinkage int +sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) +{ + return do_sigaltstack(uss, uoss, rdusp()); +} + + +/* + * Do a signal return; undo the signal stack. + * + * Keep the return code on the stack quadword aligned! + * That makes the cache flush below easier. + */ + +struct sigframe +{ + char __user *pretcode; + int sig; + int code; + struct sigcontext __user *psc; + char retcode[8]; + unsigned long extramask[_NSIG_WORDS-1]; + struct sigcontext sc; +}; + +struct rt_sigframe +{ + char __user *pretcode; + int sig; + struct siginfo __user *pinfo; + void __user *puc; + char retcode[8]; + struct siginfo info; + struct ucontext uc; +}; + + +static unsigned char fpu_version; /* version number of fpu, set by setup_frame */ + +static inline int restore_fpu_state(struct sigcontext *sc) +{ + int err = 1; + + if (FPU_IS_EMU) { + /* restore registers */ + memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12); + memcpy(current->thread.fp, sc->sc_fpregs, 24); + return 0; + } + + if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) { + /* Verify the frame format. */ + if (!(CPU_IS_060 || CPU_IS_COLDFIRE) && + (sc->sc_fpstate[0] != fpu_version)) + goto out; + if (CPU_IS_020_OR_030) { + if (m68k_fputype & FPU_68881 && + !(sc->sc_fpstate[1] == 0x18 || sc->sc_fpstate[1] == 0xb4)) + goto out; + if (m68k_fputype & FPU_68882 && + !(sc->sc_fpstate[1] == 0x38 || sc->sc_fpstate[1] == 0xd4)) + goto out; + } else if (CPU_IS_040) { + if (!(sc->sc_fpstate[1] == 0x00 || + sc->sc_fpstate[1] == 0x28 || + sc->sc_fpstate[1] == 0x60)) + goto out; + } else if (CPU_IS_060) { + if (!(sc->sc_fpstate[3] == 0x00 || + sc->sc_fpstate[3] == 0x60 || + sc->sc_fpstate[3] == 0xe0)) + goto out; + } else if (CPU_IS_COLDFIRE) { + if (!(sc->sc_fpstate[0] == 0x00 || + sc->sc_fpstate[0] == 0x05 || + sc->sc_fpstate[0] == 0xe5)) + goto out; + } else + goto out; + + if (CPU_IS_COLDFIRE) { + __asm__ volatile ("fmovemd %0,%%fp0-%%fp1\n\t" + "fmovel %1,%%fpcr\n\t" + "fmovel %2,%%fpsr\n\t" + "fmovel %3,%%fpiar" + : /* no outputs */ + : "m" (sc->sc_fpregs[0]), + "m" (sc->sc_fpcntl[0]), + "m" (sc->sc_fpcntl[1]), + "m" (sc->sc_fpcntl[2])); + } else { + __asm__ volatile (".chip 68k/68881\n\t" + "fmovemx %0,%%fp0-%%fp1\n\t" + "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" + ".chip 68k" + : /* no outputs */ + : "m" (*sc->sc_fpregs), + "m" (*sc->sc_fpcntl)); + } + } + + if (CPU_IS_COLDFIRE) { + __asm__ volatile ("frestore %0" : : "m" (*sc->sc_fpstate)); + } else { + __asm__ volatile (".chip 68k/68881\n\t" + "frestore %0\n\t" + ".chip 68k" + : : "m" (*sc->sc_fpstate)); + } + err = 0; + +out: + return err; +} + +#define FPCONTEXT_SIZE 216 +#define uc_fpstate uc_filler[0] +#define uc_formatvec uc_filler[FPCONTEXT_SIZE/4] +#define uc_extra uc_filler[FPCONTEXT_SIZE/4+1] + +static inline int rt_restore_fpu_state(struct ucontext __user *uc) +{ + unsigned char fpstate[FPCONTEXT_SIZE]; + int context_size = CPU_IS_060 ? 8 : (CPU_IS_COLDFIRE ? 12 : 0); + fpregset_t fpregs; + int err = 1; + + if (FPU_IS_EMU) { + /* restore fpu control register */ + if (__copy_from_user(current->thread.fpcntl, + uc->uc_mcontext.fpregs.f_fpcntl, 12)) + goto out; + /* restore all other fpu register */ + if (__copy_from_user(current->thread.fp, + uc->uc_mcontext.fpregs.f_fpregs, 96)) + goto out; + return 0; + } + + if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate)) + goto out; + if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { + if (!(CPU_IS_060 || CPU_IS_COLDFIRE)) + context_size = fpstate[1]; + /* Verify the frame format. */ + if (!(CPU_IS_060 || CPU_IS_COLDFIRE) && + (fpstate[0] != fpu_version)) + goto out; + if (CPU_IS_020_OR_030) { + if (m68k_fputype & FPU_68881 && + !(context_size == 0x18 || context_size == 0xb4)) + goto out; + if (m68k_fputype & FPU_68882 && + !(context_size == 0x38 || context_size == 0xd4)) + goto out; + } else if (CPU_IS_040) { + if (!(context_size == 0x00 || + context_size == 0x28 || + context_size == 0x60)) + goto out; + } else if (CPU_IS_060) { + if (!(fpstate[3] == 0x00 || + fpstate[3] == 0x60 || + fpstate[3] == 0xe0)) + goto out; + } else if (CPU_IS_COLDFIRE) { + if (!(fpstate[3] == 0x00 || + fpstate[3] == 0x05 || + fpstate[3] == 0xe5)) + goto out; + } else + goto out; + if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs, + sizeof(fpregs))) + goto out; + + if (CPU_IS_COLDFIRE) { + __asm__ volatile ("fmovemd %0,%%fp0-%%fp7\n\t" + "fmovel %1,%%fpcr\n\t" + "fmovel %2,%%fpsr\n\t" + "fmovel %3,%%fpiar" + : /* no outputs */ + : "m" (fpregs.f_fpregs[0]), + "m" (fpregs.f_fpcntl[0]), + "m" (fpregs.f_fpcntl[1]), + "m" (fpregs.f_fpcntl[2])); + } else { + __asm__ volatile (".chip 68k/68881\n\t" + "fmovemx %0,%%fp0-%%fp7\n\t" + "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" + ".chip 68k" + : /* no outputs */ + : "m" (*fpregs.f_fpregs), + "m" (*fpregs.f_fpcntl)); + } + } + if (context_size && + __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1, + context_size)) + goto out; + + if (CPU_IS_COLDFIRE) { + __asm__ volatile ("frestore %0" : : "m" (*fpstate)); + } else { + __asm__ volatile (".chip 68k/68881\n\t" + "frestore %0\n\t" + ".chip 68k" + : : "m" (*fpstate)); + } + err = 0; + +out: + return err; +} + +static int mangle_kernel_stack(struct pt_regs *regs, int formatvec, + void __user *fp) +{ + int fsize = frame_extra_sizes[formatvec >> 12]; + if (fsize < 0) { + /* + * user process trying to return with weird frame format + */ +#ifdef DEBUG + printk("user process returning with weird frame format\n"); +#endif + return 1; + } + if (!fsize) { + regs->format = formatvec >> 12; + regs->vector = formatvec & 0xfff; + } else { + struct switch_stack *sw = (struct switch_stack *)regs - 1; + unsigned long buf[fsize / 2]; /* yes, twice as much */ + + /* that'll make sure that expansion won't crap over data */ + if (copy_from_user(buf + fsize / 4, fp, fsize)) + return 1; + + /* point of no return */ + regs->format = formatvec >> 12; + regs->vector = formatvec & 0xfff; +#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack)) + __asm__ __volatile__ ( +#ifdef CONFIG_COLDFIRE + " movel %0,%/sp\n\t" + " bra ret_from_signal\n" +#else + " movel %0,%/a0\n\t" + " subl %1,%/a0\n\t" /* make room on stack */ + " movel %/a0,%/sp\n\t" /* set stack pointer */ + /* move switch_stack and pt_regs */ + "1: movel %0@+,%/a0@+\n\t" + " dbra %2,1b\n\t" + " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */ + " lsrl #2,%1\n\t" + " subql #1,%1\n\t" + /* copy to the gap we'd made */ + "2: movel %4@+,%/a0@+\n\t" + " dbra %1,2b\n\t" + " bral ret_from_signal\n" +#endif + : /* no outputs, it doesn't ever return */ + : "a" (sw), "d" (fsize), "d" (frame_offset/4-1), + "n" (frame_offset), "a" (buf + fsize/4) + : "a0"); +#undef frame_offset + } + return 0; +} + +static inline int +restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp) +{ + int formatvec; + struct sigcontext context; + int err; + + /* Always make any pending restarted system calls return -EINTR */ + current_thread_info()->restart_block.fn = do_no_restart_syscall; + + /* get previous context */ + if (copy_from_user(&context, usc, sizeof(context))) + goto badframe; + + /* restore passed registers */ + regs->d0 = context.sc_d0; + regs->d1 = context.sc_d1; + regs->a0 = context.sc_a0; + regs->a1 = context.sc_a1; + regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff); + regs->pc = context.sc_pc; + regs->orig_d0 = -1; /* disable syscall checks */ + wrusp(context.sc_usp); + formatvec = context.sc_formatvec; + + err = restore_fpu_state(&context); + + if (err || mangle_kernel_stack(regs, formatvec, fp)) + goto badframe; + + return 0; + +badframe: + return 1; +} + +static inline int +rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw, + struct ucontext __user *uc) +{ + int temp; + greg_t __user *gregs = uc->uc_mcontext.gregs; + unsigned long usp; + int err; + + /* Always make any pending restarted system calls return -EINTR */ + current_thread_info()->restart_block.fn = do_no_restart_syscall; + + err = __get_user(temp, &uc->uc_mcontext.version); + if (temp != MCONTEXT_VERSION) + goto badframe; + /* restore passed registers */ + err |= __get_user(regs->d0, &gregs[0]); + err |= __get_user(regs->d1, &gregs[1]); + err |= __get_user(regs->d2, &gregs[2]); + err |= __get_user(regs->d3, &gregs[3]); + err |= __get_user(regs->d4, &gregs[4]); + err |= __get_user(regs->d5, &gregs[5]); + err |= __get_user(sw->d6, &gregs[6]); + err |= __get_user(sw->d7, &gregs[7]); + err |= __get_user(regs->a0, &gregs[8]); + err |= __get_user(regs->a1, &gregs[9]); + err |= __get_user(regs->a2, &gregs[10]); + err |= __get_user(sw->a3, &gregs[11]); + err |= __get_user(sw->a4, &gregs[12]); + err |= __get_user(sw->a5, &gregs[13]); + err |= __get_user(sw->a6, &gregs[14]); + err |= __get_user(usp, &gregs[15]); + wrusp(usp); + err |= __get_user(regs->pc, &gregs[16]); + err |= __get_user(temp, &gregs[17]); + regs->sr = (regs->sr & 0xff00) | (temp & 0xff); + regs->orig_d0 = -1; /* disable syscall checks */ + err |= __get_user(temp, &uc->uc_formatvec); + + err |= rt_restore_fpu_state(uc); + + if (err || do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT) + goto badframe; + + if (mangle_kernel_stack(regs, temp, &uc->uc_extra)) + goto badframe; + + return 0; + +badframe: + return 1; +} + +asmlinkage int do_sigreturn(unsigned long __unused) +{ + struct switch_stack *sw = (struct switch_stack *) &__unused; + struct pt_regs *regs = (struct pt_regs *) (sw + 1); + unsigned long usp = rdusp(); + struct sigframe __user *frame = (struct sigframe __user *)(usp - 4); + sigset_t set; + + if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + if (__get_user(set.sig[0], &frame->sc.sc_mask) || + (_NSIG_WORDS > 1 && + __copy_from_user(&set.sig[1], &frame->extramask, + sizeof(frame->extramask)))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + current->blocked = set; + recalc_sigpending(); + + if (restore_sigcontext(regs, &frame->sc, frame + 1)) + goto badframe; + return regs->d0; + +badframe: + force_sig(SIGSEGV, current); + return 0; +} + +asmlinkage int do_rt_sigreturn(unsigned long __unused) +{ + struct switch_stack *sw = (struct switch_stack *) &__unused; + struct pt_regs *regs = (struct pt_regs *) (sw + 1); + unsigned long usp = rdusp(); + struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4); + sigset_t set; + + if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + current->blocked = set; + recalc_sigpending(); + + if (rt_restore_ucontext(regs, sw, &frame->uc)) + goto badframe; + return regs->d0; + +badframe: + force_sig(SIGSEGV, current); + return 0; +} + +/* + * Set up a signal frame. + */ + +static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs) +{ + if (FPU_IS_EMU) { + /* save registers */ + memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12); + memcpy(sc->sc_fpregs, current->thread.fp, 24); + return; + } + + if (CPU_IS_COLDFIRE) { + __asm__ volatile ("fsave %0" + : : "m" (*sc->sc_fpstate) : "memory"); + } else { + __asm__ volatile (".chip 68k/68881\n\t" + "fsave %0\n\t" + ".chip 68k" + : : "m" (*sc->sc_fpstate) : "memory"); + } + + if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) { + fpu_version = sc->sc_fpstate[0]; + if (CPU_IS_020_OR_030 && + regs->vector >= (VEC_FPBRUC * 4) && + regs->vector <= (VEC_FPNAN * 4)) { + /* Clear pending exception in 68882 idle frame */ + if (*(unsigned short *) sc->sc_fpstate == 0x1f38) + sc->sc_fpstate[0x38] |= 1 << 3; + } + + if (CPU_IS_COLDFIRE) { + __asm__ volatile ("fmovemd %%fp0-%%fp1,%0\n\t" + "fmovel %%fpcr,%1\n\t" + "fmovel %%fpsr,%2\n\t" + "fmovel %%fpiar,%3" + : "=m" (sc->sc_fpregs[0]), + "=m" (sc->sc_fpcntl[0]), + "=m" (sc->sc_fpcntl[1]), + "=m" (sc->sc_fpcntl[2]) + : /* no inputs */ + : "memory"); + } else { + __asm__ volatile (".chip 68k/68881\n\t" + "fmovemx %%fp0-%%fp1,%0\n\t" + "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" + ".chip 68k" + : "=m" (*sc->sc_fpregs), + "=m" (*sc->sc_fpcntl) + : /* no inputs */ + : "memory"); + } + } +} + +static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs) +{ + unsigned char fpstate[FPCONTEXT_SIZE]; + int context_size = CPU_IS_060 ? 8 : (CPU_IS_COLDFIRE ? 12 : 0); + int err = 0; + + if (FPU_IS_EMU) { + /* save fpu control register */ + err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpcntl, + current->thread.fpcntl, 12); + /* save all other fpu register */ + err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs, + current->thread.fp, 96); + return err; + } + + if (CPU_IS_COLDFIRE) { + __asm__ volatile ("fsave %0" : : "m" (*fpstate) : "memory"); + } else { + __asm__ volatile (".chip 68k/68881\n\t" + "fsave %0\n\t" + ".chip 68k" + : : "m" (*fpstate) : "memory"); + } + + err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate); + if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { + fpregset_t fpregs; + if (!(CPU_IS_060 || CPU_IS_COLDFIRE)) + context_size = fpstate[1]; + fpu_version = fpstate[0]; + if (CPU_IS_020_OR_030 && + regs->vector >= (VEC_FPBRUC * 4) && + regs->vector <= (VEC_FPNAN * 4)) { + /* Clear pending exception in 68882 idle frame */ + if (*(unsigned short *) fpstate == 0x1f38) + fpstate[0x38] |= 1 << 3; + } + if (CPU_IS_COLDFIRE) { + __asm__ volatile ("fmovemd %%fp0-%%fp7,%0\n\t" + "fmovel %%fpcr,%1\n\t" + "fmovel %%fpsr,%2\n\t" + "fmovel %%fpiar,%3" + : "=m" (fpregs.f_fpregs[0]), + "=m" (fpregs.f_fpcntl[0]), + "=m" (fpregs.f_fpcntl[1]), + "=m" (fpregs.f_fpcntl[2]) + : /* no inputs */ + : "memory"); + } else { + __asm__ volatile (".chip 68k/68881\n\t" + "fmovemx %%fp0-%%fp7,%0\n\t" + "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" + ".chip 68k" + : "=m" (*fpregs.f_fpregs), + "=m" (*fpregs.f_fpcntl) + : /* no inputs */ + : "memory"); + } + err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs, + sizeof(fpregs)); + } + if (context_size) + err |= copy_to_user((long __user *)&uc->uc_fpstate + 1, fpstate + 4, + context_size); + return err; +} + +static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, + unsigned long mask) +{ + sc->sc_mask = mask; + sc->sc_usp = rdusp(); + sc->sc_d0 = regs->d0; + sc->sc_d1 = regs->d1; + sc->sc_a0 = regs->a0; + sc->sc_a1 = regs->a1; + sc->sc_sr = regs->sr; + sc->sc_pc = regs->pc; + sc->sc_formatvec = regs->format << 12 | regs->vector; + save_fpu_state(sc, regs); +} + +static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs) +{ + struct switch_stack *sw = (struct switch_stack *)regs - 1; + greg_t __user *gregs = uc->uc_mcontext.gregs; + int err = 0; + + err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version); + err |= __put_user(regs->d0, &gregs[0]); + err |= __put_user(regs->d1, &gregs[1]); + err |= __put_user(regs->d2, &gregs[2]); + err |= __put_user(regs->d3, &gregs[3]); + err |= __put_user(regs->d4, &gregs[4]); + err |= __put_user(regs->d5, &gregs[5]); + err |= __put_user(sw->d6, &gregs[6]); + err |= __put_user(sw->d7, &gregs[7]); + err |= __put_user(regs->a0, &gregs[8]); + err |= __put_user(regs->a1, &gregs[9]); + err |= __put_user(regs->a2, &gregs[10]); + err |= __put_user(sw->a3, &gregs[11]); + err |= __put_user(sw->a4, &gregs[12]); + err |= __put_user(sw->a5, &gregs[13]); + err |= __put_user(sw->a6, &gregs[14]); + err |= __put_user(rdusp(), &gregs[15]); + err |= __put_user(regs->pc, &gregs[16]); + err |= __put_user(regs->sr, &gregs[17]); + err |= __put_user((regs->format << 12) | regs->vector, &uc->uc_formatvec); + err |= rt_save_fpu_state(uc, regs); + return err; +} + +static inline void push_cache (unsigned long vaddr) +{ + /* + * Using the old cache_push_v() was really a big waste. + * + * What we are trying to do is to flush 8 bytes to ram. + * Flushing 2 cache lines of 16 bytes is much cheaper than + * flushing 1 or 2 pages, as previously done in + * cache_push_v(). + * Jes + */ + if (CPU_IS_040) { + unsigned long temp; + + __asm__ __volatile__ (".chip 68040\n\t" + "nop\n\t" + "ptestr (%1)\n\t" + "movec %%mmusr,%0\n\t" + ".chip 68k" + : "=r" (temp) + : "a" (vaddr)); + + temp &= PAGE_MASK; + temp |= vaddr & ~PAGE_MASK; + + __asm__ __volatile__ (".chip 68040\n\t" + "nop\n\t" + "cpushl %%bc,(%0)\n\t" + ".chip 68k" + : : "a" (temp)); + } + else if (CPU_IS_060) { + unsigned long temp; + __asm__ __volatile__ (".chip 68060\n\t" + "plpar (%0)\n\t" + ".chip 68k" + : "=a" (temp) + : "0" (vaddr)); + __asm__ __volatile__ (".chip 68060\n\t" + "cpushl %%bc,(%0)\n\t" + ".chip 68k" + : : "a" (temp)); + } else if (!CPU_IS_COLDFIRE) { + /* + * 68030/68020 have no writeback cache; + * still need to clear icache. + * Note that vaddr is guaranteed to be long word aligned. + */ + unsigned long temp; + asm volatile ("movec %%cacr,%0" : "=r" (temp)); + temp += 4; + asm volatile ("movec %0,%%caar\n\t" + "movec %1,%%cacr" + : : "r" (vaddr), "r" (temp)); + asm volatile ("movec %0,%%caar\n\t" + "movec %1,%%cacr" + : : "r" (vaddr + 4), "r" (temp)); + } +} + +static inline void __user * +get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) +{ + unsigned long usp; + + /* Default to using normal stack. */ + usp = rdusp(); + + /* This is the X/Open sanctioned signal stack switching. */ + if (ka->sa.sa_flags & SA_ONSTACK) { + if (!sas_ss_flags(usp)) + usp = current->sas_ss_sp + current->sas_ss_size; + } + return (void __user *)((usp - frame_size) & -8UL); +} + +static int setup_frame (int sig, struct k_sigaction *ka, + sigset_t *set, struct pt_regs *regs) +{ + struct sigframe __user *frame; + int fsize = frame_extra_sizes[regs->format]; + struct sigcontext context; + int err = 0; + + if (fsize < 0) { +#ifdef DEBUG + printk ("setup_frame: Unknown frame format %#x\n", + regs->format); +#endif + goto give_sigsegv; + } + + frame = get_sigframe(ka, regs, sizeof(*frame) + fsize); + + if (fsize) + err |= copy_to_user (frame + 1, regs + 1, fsize); + + err |= __put_user((current_thread_info()->exec_domain + && current_thread_info()->exec_domain->signal_invmap + && sig < 32 + ? current_thread_info()->exec_domain->signal_invmap[sig] + : sig), + &frame->sig); + + err |= __put_user(regs->vector, &frame->code); + err |= __put_user(&frame->sc, &frame->psc); + + if (_NSIG_WORDS > 1) + err |= copy_to_user(frame->extramask, &set->sig[1], + sizeof(frame->extramask)); + + setup_sigcontext(&context, regs, set->sig[0]); + err |= copy_to_user (&frame->sc, &context, sizeof(context)); + + /* Set up to return from userspace. */ + err |= __put_user(frame->retcode, &frame->pretcode); + /* moveq #,d0; trap #0 */ + err |= __put_user(0x70004e40 + (__NR_sigreturn << 16), + (long __user *)(frame->retcode)); + + if (err) + goto give_sigsegv; + + push_cache ((unsigned long) &frame->retcode); + + /* + * Set up registers for signal handler. All the state we are about + * to destroy is successfully copied to sigframe. + */ + wrusp ((unsigned long) frame); + regs->pc = (unsigned long) ka->sa.sa_handler; + + /* + * This is subtle; if we build more than one sigframe, all but the + * first one will see frame format 0 and have fsize == 0, so we won't + * screw stkadj. + */ + if (fsize) + regs->stkadj = fsize; + + /* Prepare to skip over the extra stuff in the exception frame. */ + if (regs->stkadj) { + struct pt_regs *tregs = + (struct pt_regs *)((ulong)regs + regs->stkadj); +#ifdef DEBUG + printk("Performing stackadjust=%04x\n", regs->stkadj); +#endif + /* This must be copied with decreasing addresses to + handle overlaps. */ + tregs->vector = 0; + tregs->format = 0; + tregs->pc = regs->pc; + tregs->sr = regs->sr; + } + return 0; + +give_sigsegv: + force_sigsegv(sig, current); + return err; +} + +static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, + sigset_t *set, struct pt_regs *regs) +{ + struct rt_sigframe __user *frame; + int fsize = frame_extra_sizes[regs->format]; + int err = 0; + + if (fsize < 0) { +#ifdef DEBUG + printk ("setup_frame: Unknown frame format %#x\n", + regs->format); +#endif + goto give_sigsegv; + } + + frame = get_sigframe(ka, regs, sizeof(*frame)); + + if (fsize) + err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize); + + err |= __put_user((current_thread_info()->exec_domain + && current_thread_info()->exec_domain->signal_invmap + && sig < 32 + ? current_thread_info()->exec_domain->signal_invmap[sig] + : sig), + &frame->sig); + err |= __put_user(&frame->info, &frame->pinfo); + err |= __put_user(&frame->uc, &frame->puc); + err |= copy_siginfo_to_user(&frame->info, info); + + /* Create the ucontext. */ + err |= __put_user(0, &frame->uc.uc_flags); + err |= __put_user(NULL, &frame->uc.uc_link); + err |= __put_user((void __user *)current->sas_ss_sp, + &frame->uc.uc_stack.ss_sp); + err |= __put_user(sas_ss_flags(rdusp()), + &frame->uc.uc_stack.ss_flags); + err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); + err |= rt_setup_ucontext(&frame->uc, regs); + err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set)); + + /* Set up to return from userspace. */ + err |= __put_user(frame->retcode, &frame->pretcode); +#ifdef __mcoldfire__ + /* movel #__NR_rt_sigreturn,d0; trap #0 */ + err |= __put_user(0x203c0000, (long __user *)(frame->retcode + 0)); + err |= __put_user(0x00004e40 + (__NR_rt_sigreturn << 16), + (long __user *)(frame->retcode + 4)); +#else + /* moveq #,d0; notb d0; trap #0 */ + err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16), + (long __user *)(frame->retcode + 0)); + err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4)); +#endif + + if (err) + goto give_sigsegv; + + push_cache ((unsigned long) &frame->retcode); + + /* + * Set up registers for signal handler. All the state we are about + * to destroy is successfully copied to sigframe. + */ + wrusp ((unsigned long) frame); + regs->pc = (unsigned long) ka->sa.sa_handler; + + /* + * This is subtle; if we build more than one sigframe, all but the + * first one will see frame format 0 and have fsize == 0, so we won't + * screw stkadj. + */ + if (fsize) + regs->stkadj = fsize; + + /* Prepare to skip over the extra stuff in the exception frame. */ + if (regs->stkadj) { + struct pt_regs *tregs = + (struct pt_regs *)((ulong)regs + regs->stkadj); +#ifdef DEBUG + printk("Performing stackadjust=%04x\n", regs->stkadj); +#endif + /* This must be copied with decreasing addresses to + handle overlaps. */ + tregs->vector = 0; + tregs->format = 0; + tregs->pc = regs->pc; + tregs->sr = regs->sr; + } + return 0; + +give_sigsegv: + force_sigsegv(sig, current); + return err; +} + +static inline void +handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) +{ + switch (regs->d0) { + case -ERESTARTNOHAND: + if (!has_handler) + goto do_restart; + regs->d0 = -EINTR; + break; + + case -ERESTART_RESTARTBLOCK: + if (!has_handler) { + regs->d0 = __NR_restart_syscall; + regs->pc -= 2; + break; + } + regs->d0 = -EINTR; + break; + + case -ERESTARTSYS: + if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) { + regs->d0 = -EINTR; + break; + } + /* fallthrough */ + case -ERESTARTNOINTR: + do_restart: + regs->d0 = regs->orig_d0; + regs->pc -= 2; + break; + } +} + +void ptrace_signal_deliver(struct pt_regs *regs, void *cookie) +{ + if (regs->orig_d0 < 0) + return; + switch (regs->d0) { + case -ERESTARTNOHAND: + case -ERESTARTSYS: + case -ERESTARTNOINTR: + regs->d0 = regs->orig_d0; + regs->orig_d0 = -1; + regs->pc -= 2; + break; + } +} + +/* + * OK, we're invoking a handler + */ +static void +handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, + sigset_t *oldset, struct pt_regs *regs) +{ + int err; + /* are we from a system call? */ + if (regs->orig_d0 >= 0) + /* If so, check system call restarting.. */ + handle_restart(regs, ka, 1); + + /* set up the stack frame */ + if (ka->sa.sa_flags & SA_SIGINFO) + err = setup_rt_frame(sig, ka, info, oldset, regs); + else + err = setup_frame(sig, ka, oldset, regs); + + if (err) + return; + + sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + if (!(ka->sa.sa_flags & SA_NODEFER)) + sigaddset(¤t->blocked,sig); + recalc_sigpending(); + + if (test_thread_flag(TIF_DELAYED_TRACE)) { + regs->sr &= ~0x8000; + send_sig(SIGTRAP, current, 1); + } + + clear_thread_flag(TIF_RESTORE_SIGMASK); +} + +/* + * Note that 'init' is a special process: it doesn't get signals it doesn't + * want to handle. Thus you cannot kill init even with a SIGKILL even by + * mistake. + */ +asmlinkage void do_signal(struct pt_regs *regs) +{ + siginfo_t info; + struct k_sigaction ka; + int signr; + sigset_t *oldset; + + current->thread.esp0 = (unsigned long) regs; + + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + oldset = ¤t->saved_sigmask; + else + oldset = ¤t->blocked; + + signr = get_signal_to_deliver(&info, &ka, regs, NULL); + if (signr > 0) { + /* Whee! Actually deliver the signal. */ + handle_signal(signr, &ka, &info, oldset, regs); + return; + } + + /* Did we come from a system call? */ + if (regs->orig_d0 >= 0) + /* Restart the system call - no handlers present */ + handle_restart(regs, NULL, 0); + + /* If there's no signal to deliver, we just restore the saved mask. */ + if (test_thread_flag(TIF_RESTORE_SIGMASK)) { + clear_thread_flag(TIF_RESTORE_SIGMASK); + sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); + } +} diff --git a/trunk/arch/m68k/kernel/signal_no.c b/trunk/arch/m68k/kernel/signal_no.c new file mode 100644 index 000000000000..36a81bb6835a --- /dev/null +++ b/trunk/arch/m68k/kernel/signal_no.c @@ -0,0 +1,765 @@ +/* + * linux/arch/m68knommu/kernel/signal.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +/* + * Linux/m68k support by Hamish Macdonald + * + * 68060 fixes by Jesper Skov + * + * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab + * + * mathemu support by Roman Zippel + * (Note: fpstate in the signal context is completely ignored for the emulator + * and the internal floating point format is put on stack) + */ + +/* + * ++roman (07/09/96): implemented signal stacks (specially for tosemu on + * Atari :-) Current limitation: Only one sigstack can be active at one time. + * If a second signal with SA_ONSTACK set arrives while working on a sigstack, + * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested + * signal handlers! + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) + +void ret_from_user_signal(void); +void ret_from_user_rt_signal(void); + +/* + * Atomically swap in the new signal mask, and wait for a signal. + */ +asmlinkage int +sys_sigsuspend(int unused0, int unused1, old_sigset_t mask) +{ + mask &= _BLOCKABLE; + spin_lock_irq(¤t->sighand->siglock); + current->saved_sigmask = current->blocked; + siginitset(¤t->blocked, mask); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + current->state = TASK_INTERRUPTIBLE; + schedule(); + set_restore_sigmask(); + + return -ERESTARTNOHAND; +} + +asmlinkage int +sys_sigaction(int sig, const struct old_sigaction __user *act, + struct old_sigaction __user *oact) +{ + struct k_sigaction new_ka, old_ka; + int ret; + + if (act) { + old_sigset_t mask; + if (!access_ok(VERIFY_READ, act, sizeof(*act)) || + __get_user(new_ka.sa.sa_handler, &act->sa_handler) || + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || + __get_user(new_ka.sa.sa_flags, &act->sa_flags) || + __get_user(mask, &act->sa_mask)) + return -EFAULT; + siginitset(&new_ka.sa.sa_mask, mask); + } + + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); + + if (!ret && oact) { + if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || + __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || + __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) + return -EFAULT; + } + + return ret; +} + +asmlinkage int +sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) +{ + return do_sigaltstack(uss, uoss, rdusp()); +} + + +/* + * Do a signal return; undo the signal stack. + * + * Keep the return code on the stack quadword aligned! + * That makes the cache flush below easier. + */ + +struct sigframe +{ + char __user *pretcode; + int sig; + int code; + struct sigcontext __user *psc; + char retcode[8]; + unsigned long extramask[_NSIG_WORDS-1]; + struct sigcontext sc; +}; + +struct rt_sigframe +{ + char __user *pretcode; + int sig; + struct siginfo __user *pinfo; + void __user *puc; + char retcode[8]; + struct siginfo info; + struct ucontext uc; +}; + +#ifdef CONFIG_FPU + +static unsigned char fpu_version = 0; /* version number of fpu, set by setup_frame */ + +static inline int restore_fpu_state(struct sigcontext *sc) +{ + int err = 1; + + if (FPU_IS_EMU) { + /* restore registers */ + memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12); + memcpy(current->thread.fp, sc->sc_fpregs, 24); + return 0; + } + + if (sc->sc_fpstate[0]) { + /* Verify the frame format. */ + if (sc->sc_fpstate[0] != fpu_version) + goto out; + + __asm__ volatile (".chip 68k/68881\n\t" + "fmovemx %0,%%fp0-%%fp1\n\t" + "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" + ".chip 68k" + : /* no outputs */ + : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl)); + } + __asm__ volatile (".chip 68k/68881\n\t" + "frestore %0\n\t" + ".chip 68k" : : "m" (*sc->sc_fpstate)); + err = 0; + +out: + return err; +} + +#define FPCONTEXT_SIZE 216 +#define uc_fpstate uc_filler[0] +#define uc_formatvec uc_filler[FPCONTEXT_SIZE/4] +#define uc_extra uc_filler[FPCONTEXT_SIZE/4+1] + +static inline int rt_restore_fpu_state(struct ucontext __user *uc) +{ + unsigned char fpstate[FPCONTEXT_SIZE]; + int context_size = 0; + fpregset_t fpregs; + int err = 1; + + if (FPU_IS_EMU) { + /* restore fpu control register */ + if (__copy_from_user(current->thread.fpcntl, + uc->uc_mcontext.fpregs.f_fpcntl, 12)) + goto out; + /* restore all other fpu register */ + if (__copy_from_user(current->thread.fp, + uc->uc_mcontext.fpregs.f_fpregs, 96)) + goto out; + return 0; + } + + if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate)) + goto out; + if (fpstate[0]) { + context_size = fpstate[1]; + + /* Verify the frame format. */ + if (fpstate[0] != fpu_version) + goto out; + if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs, + sizeof(fpregs))) + goto out; + __asm__ volatile (".chip 68k/68881\n\t" + "fmovemx %0,%%fp0-%%fp7\n\t" + "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" + ".chip 68k" + : /* no outputs */ + : "m" (*fpregs.f_fpregs), + "m" (*fpregs.f_fpcntl)); + } + if (context_size && + __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1, + context_size)) + goto out; + __asm__ volatile (".chip 68k/68881\n\t" + "frestore %0\n\t" + ".chip 68k" : : "m" (*fpstate)); + err = 0; + +out: + return err; +} + +#endif + +static inline int +restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp, + int *pd0) +{ + int formatvec; + struct sigcontext context; + int err = 0; + + /* Always make any pending restarted system calls return -EINTR */ + current_thread_info()->restart_block.fn = do_no_restart_syscall; + + /* get previous context */ + if (copy_from_user(&context, usc, sizeof(context))) + goto badframe; + + /* restore passed registers */ + regs->d1 = context.sc_d1; + regs->a0 = context.sc_a0; + regs->a1 = context.sc_a1; + ((struct switch_stack *)regs - 1)->a5 = context.sc_a5; + regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff); + regs->pc = context.sc_pc; + regs->orig_d0 = -1; /* disable syscall checks */ + wrusp(context.sc_usp); + formatvec = context.sc_formatvec; + regs->format = formatvec >> 12; + regs->vector = formatvec & 0xfff; + +#ifdef CONFIG_FPU + err = restore_fpu_state(&context); +#endif + + *pd0 = context.sc_d0; + return err; + +badframe: + return 1; +} + +static inline int +rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw, + struct ucontext __user *uc, int *pd0) +{ + int temp; + greg_t __user *gregs = uc->uc_mcontext.gregs; + unsigned long usp; + int err; + + /* Always make any pending restarted system calls return -EINTR */ + current_thread_info()->restart_block.fn = do_no_restart_syscall; + + err = __get_user(temp, &uc->uc_mcontext.version); + if (temp != MCONTEXT_VERSION) + goto badframe; + /* restore passed registers */ + err |= __get_user(regs->d0, &gregs[0]); + err |= __get_user(regs->d1, &gregs[1]); + err |= __get_user(regs->d2, &gregs[2]); + err |= __get_user(regs->d3, &gregs[3]); + err |= __get_user(regs->d4, &gregs[4]); + err |= __get_user(regs->d5, &gregs[5]); + err |= __get_user(sw->d6, &gregs[6]); + err |= __get_user(sw->d7, &gregs[7]); + err |= __get_user(regs->a0, &gregs[8]); + err |= __get_user(regs->a1, &gregs[9]); + err |= __get_user(regs->a2, &gregs[10]); + err |= __get_user(sw->a3, &gregs[11]); + err |= __get_user(sw->a4, &gregs[12]); + err |= __get_user(sw->a5, &gregs[13]); + err |= __get_user(sw->a6, &gregs[14]); + err |= __get_user(usp, &gregs[15]); + wrusp(usp); + err |= __get_user(regs->pc, &gregs[16]); + err |= __get_user(temp, &gregs[17]); + regs->sr = (regs->sr & 0xff00) | (temp & 0xff); + regs->orig_d0 = -1; /* disable syscall checks */ + regs->format = temp >> 12; + regs->vector = temp & 0xfff; + + if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT) + goto badframe; + + *pd0 = regs->d0; + return err; + +badframe: + return 1; +} + +asmlinkage int do_sigreturn(unsigned long __unused) +{ + struct switch_stack *sw = (struct switch_stack *) &__unused; + struct pt_regs *regs = (struct pt_regs *) (sw + 1); + unsigned long usp = rdusp(); + struct sigframe __user *frame = (struct sigframe __user *)(usp - 4); + sigset_t set; + int d0; + + if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + if (__get_user(set.sig[0], &frame->sc.sc_mask) || + (_NSIG_WORDS > 1 && + __copy_from_user(&set.sig[1], &frame->extramask, + sizeof(frame->extramask)))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0)) + goto badframe; + return d0; + +badframe: + force_sig(SIGSEGV, current); + return 0; +} + +asmlinkage int do_rt_sigreturn(unsigned long __unused) +{ + struct switch_stack *sw = (struct switch_stack *) &__unused; + struct pt_regs *regs = (struct pt_regs *) (sw + 1); + unsigned long usp = rdusp(); + struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4); + sigset_t set; + int d0; + + if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + if (rt_restore_ucontext(regs, sw, &frame->uc, &d0)) + goto badframe; + return d0; + +badframe: + force_sig(SIGSEGV, current); + return 0; +} + +#ifdef CONFIG_FPU +/* + * Set up a signal frame. + */ + +static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs) +{ + if (FPU_IS_EMU) { + /* save registers */ + memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12); + memcpy(sc->sc_fpregs, current->thread.fp, 24); + return; + } + + __asm__ volatile (".chip 68k/68881\n\t" + "fsave %0\n\t" + ".chip 68k" + : : "m" (*sc->sc_fpstate) : "memory"); + + if (sc->sc_fpstate[0]) { + fpu_version = sc->sc_fpstate[0]; + __asm__ volatile (".chip 68k/68881\n\t" + "fmovemx %%fp0-%%fp1,%0\n\t" + "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" + ".chip 68k" + : "=m" (*sc->sc_fpregs), + "=m" (*sc->sc_fpcntl) + : /* no inputs */ + : "memory"); + } +} + +static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs) +{ + unsigned char fpstate[FPCONTEXT_SIZE]; + int context_size = 0; + int err = 0; + + if (FPU_IS_EMU) { + /* save fpu control register */ + err |= copy_to_user(uc->uc_mcontext.fpregs.f_pcntl, + current->thread.fpcntl, 12); + /* save all other fpu register */ + err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs, + current->thread.fp, 96); + return err; + } + + __asm__ volatile (".chip 68k/68881\n\t" + "fsave %0\n\t" + ".chip 68k" + : : "m" (*fpstate) : "memory"); + + err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate); + if (fpstate[0]) { + fpregset_t fpregs; + context_size = fpstate[1]; + fpu_version = fpstate[0]; + __asm__ volatile (".chip 68k/68881\n\t" + "fmovemx %%fp0-%%fp7,%0\n\t" + "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" + ".chip 68k" + : "=m" (*fpregs.f_fpregs), + "=m" (*fpregs.f_fpcntl) + : /* no inputs */ + : "memory"); + err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs, + sizeof(fpregs)); + } + if (context_size) + err |= copy_to_user((long __user *)&uc->uc_fpstate + 1, fpstate + 4, + context_size); + return err; +} + +#endif + +static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, + unsigned long mask) +{ + sc->sc_mask = mask; + sc->sc_usp = rdusp(); + sc->sc_d0 = regs->d0; + sc->sc_d1 = regs->d1; + sc->sc_a0 = regs->a0; + sc->sc_a1 = regs->a1; + sc->sc_a5 = ((struct switch_stack *)regs - 1)->a5; + sc->sc_sr = regs->sr; + sc->sc_pc = regs->pc; + sc->sc_formatvec = regs->format << 12 | regs->vector; +#ifdef CONFIG_FPU + save_fpu_state(sc, regs); +#endif +} + +static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs) +{ + struct switch_stack *sw = (struct switch_stack *)regs - 1; + greg_t __user *gregs = uc->uc_mcontext.gregs; + int err = 0; + + err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version); + err |= __put_user(regs->d0, &gregs[0]); + err |= __put_user(regs->d1, &gregs[1]); + err |= __put_user(regs->d2, &gregs[2]); + err |= __put_user(regs->d3, &gregs[3]); + err |= __put_user(regs->d4, &gregs[4]); + err |= __put_user(regs->d5, &gregs[5]); + err |= __put_user(sw->d6, &gregs[6]); + err |= __put_user(sw->d7, &gregs[7]); + err |= __put_user(regs->a0, &gregs[8]); + err |= __put_user(regs->a1, &gregs[9]); + err |= __put_user(regs->a2, &gregs[10]); + err |= __put_user(sw->a3, &gregs[11]); + err |= __put_user(sw->a4, &gregs[12]); + err |= __put_user(sw->a5, &gregs[13]); + err |= __put_user(sw->a6, &gregs[14]); + err |= __put_user(rdusp(), &gregs[15]); + err |= __put_user(regs->pc, &gregs[16]); + err |= __put_user(regs->sr, &gregs[17]); +#ifdef CONFIG_FPU + err |= rt_save_fpu_state(uc, regs); +#endif + return err; +} + +static inline void __user * +get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) +{ + unsigned long usp; + + /* Default to using normal stack. */ + usp = rdusp(); + + /* This is the X/Open sanctioned signal stack switching. */ + if (ka->sa.sa_flags & SA_ONSTACK) { + if (!sas_ss_flags(usp)) + usp = current->sas_ss_sp + current->sas_ss_size; + } + return (void __user *)((usp - frame_size) & -8UL); +} + +static int setup_frame (int sig, struct k_sigaction *ka, + sigset_t *set, struct pt_regs *regs) +{ + struct sigframe __user *frame; + struct sigcontext context; + int err = 0; + + frame = get_sigframe(ka, regs, sizeof(*frame)); + + err |= __put_user((current_thread_info()->exec_domain + && current_thread_info()->exec_domain->signal_invmap + && sig < 32 + ? current_thread_info()->exec_domain->signal_invmap[sig] + : sig), + &frame->sig); + + err |= __put_user(regs->vector, &frame->code); + err |= __put_user(&frame->sc, &frame->psc); + + if (_NSIG_WORDS > 1) + err |= copy_to_user(frame->extramask, &set->sig[1], + sizeof(frame->extramask)); + + setup_sigcontext(&context, regs, set->sig[0]); + err |= copy_to_user (&frame->sc, &context, sizeof(context)); + + /* Set up to return from userspace. */ + err |= __put_user((void *) ret_from_user_signal, &frame->pretcode); + + if (err) + goto give_sigsegv; + + /* Set up registers for signal handler */ + wrusp ((unsigned long) frame); + regs->pc = (unsigned long) ka->sa.sa_handler; + ((struct switch_stack *)regs - 1)->a5 = current->mm->start_data; + regs->format = 0x4; /*set format byte to make stack appear modulo 4 + which it will be when doing the rte */ + +adjust_stack: + /* Prepare to skip over the extra stuff in the exception frame. */ + if (regs->stkadj) { + struct pt_regs *tregs = + (struct pt_regs *)((ulong)regs + regs->stkadj); +#if defined(DEBUG) + printk(KERN_DEBUG "Performing stackadjust=%04x\n", regs->stkadj); +#endif + /* This must be copied with decreasing addresses to + handle overlaps. */ + tregs->vector = 0; + tregs->format = 0; + tregs->pc = regs->pc; + tregs->sr = regs->sr; + } + return err; + +give_sigsegv: + force_sigsegv(sig, current); + goto adjust_stack; +} + +static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, + sigset_t *set, struct pt_regs *regs) +{ + struct rt_sigframe __user *frame; + int err = 0; + + frame = get_sigframe(ka, regs, sizeof(*frame)); + + err |= __put_user((current_thread_info()->exec_domain + && current_thread_info()->exec_domain->signal_invmap + && sig < 32 + ? current_thread_info()->exec_domain->signal_invmap[sig] + : sig), + &frame->sig); + err |= __put_user(&frame->info, &frame->pinfo); + err |= __put_user(&frame->uc, &frame->puc); + err |= copy_siginfo_to_user(&frame->info, info); + + /* Create the ucontext. */ + err |= __put_user(0, &frame->uc.uc_flags); + err |= __put_user(NULL, &frame->uc.uc_link); + err |= __put_user((void __user *)current->sas_ss_sp, + &frame->uc.uc_stack.ss_sp); + err |= __put_user(sas_ss_flags(rdusp()), + &frame->uc.uc_stack.ss_flags); + err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); + err |= rt_setup_ucontext(&frame->uc, regs); + err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set)); + + /* Set up to return from userspace. */ + err |= __put_user((void *) ret_from_user_rt_signal, &frame->pretcode); + + if (err) + goto give_sigsegv; + + /* Set up registers for signal handler */ + wrusp ((unsigned long) frame); + regs->pc = (unsigned long) ka->sa.sa_handler; + ((struct switch_stack *)regs - 1)->a5 = current->mm->start_data; + regs->format = 0x4; /*set format byte to make stack appear modulo 4 + which it will be when doing the rte */ + +adjust_stack: + /* Prepare to skip over the extra stuff in the exception frame. */ + if (regs->stkadj) { + struct pt_regs *tregs = + (struct pt_regs *)((ulong)regs + regs->stkadj); +#if defined(DEBUG) + printk(KERN_DEBUG "Performing stackadjust=%04x\n", regs->stkadj); +#endif + /* This must be copied with decreasing addresses to + handle overlaps. */ + tregs->vector = 0; + tregs->format = 0; + tregs->pc = regs->pc; + tregs->sr = regs->sr; + } + return err; + +give_sigsegv: + force_sigsegv(sig, current); + goto adjust_stack; +} + +static inline void +handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) +{ + switch (regs->d0) { + case -ERESTARTNOHAND: + if (!has_handler) + goto do_restart; + regs->d0 = -EINTR; + break; + + case -ERESTART_RESTARTBLOCK: + if (!has_handler) { + regs->d0 = __NR_restart_syscall; + regs->pc -= 2; + break; + } + regs->d0 = -EINTR; + break; + + case -ERESTARTSYS: + if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) { + regs->d0 = -EINTR; + break; + } + /* fallthrough */ + case -ERESTARTNOINTR: + do_restart: + regs->d0 = regs->orig_d0; + regs->pc -= 2; + break; + } +} + +/* + * OK, we're invoking a handler + */ +static void +handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, + sigset_t *oldset, struct pt_regs *regs) +{ + int err; + /* are we from a system call? */ + if (regs->orig_d0 >= 0) + /* If so, check system call restarting.. */ + handle_restart(regs, ka, 1); + + /* set up the stack frame */ + if (ka->sa.sa_flags & SA_SIGINFO) + err = setup_rt_frame(sig, ka, info, oldset, regs); + else + err = setup_frame(sig, ka, oldset, regs); + + if (err) + return; + + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + if (!(ka->sa.sa_flags & SA_NODEFER)) + sigaddset(¤t->blocked,sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + clear_thread_flag(TIF_RESTORE_SIGMASK); +} + +/* + * Note that 'init' is a special process: it doesn't get signals it doesn't + * want to handle. Thus you cannot kill init even with a SIGKILL even by + * mistake. + */ +asmlinkage void do_signal(struct pt_regs *regs) +{ + struct k_sigaction ka; + siginfo_t info; + int signr; + sigset_t *oldset; + + /* + * We want the common case to go fast, which + * is why we may in certain cases get here from + * kernel mode. Just return without doing anything + * if so. + */ + if (!user_mode(regs)) + return; + + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + oldset = ¤t->saved_sigmask; + else + oldset = ¤t->blocked; + + signr = get_signal_to_deliver(&info, &ka, regs, NULL); + if (signr > 0) { + /* Whee! Actually deliver the signal. */ + handle_signal(signr, &ka, &info, oldset, regs); + return; + } + + /* Did we come from a system call? */ + if (regs->orig_d0 >= 0) { + /* Restart the system call - no handlers present */ + handle_restart(regs, NULL, 0); + } + + /* If there's no signal to deliver, we just restore the saved mask. */ + if (test_thread_flag(TIF_RESTORE_SIGMASK)) { + clear_thread_flag(TIF_RESTORE_SIGMASK); + sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); + } +} diff --git a/trunk/arch/m68k/mm/fault.c b/trunk/arch/m68k/mm/fault.c index aeebbb7b30f0..6b020a8461e7 100644 --- a/trunk/arch/m68k/mm/fault.c +++ b/trunk/arch/m68k/mm/fault.c @@ -72,8 +72,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, { struct mm_struct *mm = current->mm; struct vm_area_struct * vma; - int fault; - unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; + int write, fault; #ifdef DEBUG printk ("do page fault:\nregs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld, %p\n", @@ -88,7 +87,6 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, if (in_atomic() || !mm) goto no_context; -retry: down_read(&mm->mmap_sem); vma = find_vma(mm, address); @@ -119,13 +117,14 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, #ifdef DEBUG printk("do_page_fault: good_area\n"); #endif + write = 0; switch (error_code & 3) { default: /* 3: write, present */ /* fall through */ case 2: /* write, not present */ if (!(vma->vm_flags & VM_WRITE)) goto acc_err; - flags |= FAULT_FLAG_WRITE; + write++; break; case 1: /* read, present */ goto acc_err; @@ -140,14 +139,10 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, * the fault. */ - fault = handle_mm_fault(mm, vma, address, flags); + fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0); #ifdef DEBUG printk("handle_mm_fault returns %d\n",fault); #endif - - if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) - return 0; - if (unlikely(fault & VM_FAULT_ERROR)) { if (fault & VM_FAULT_OOM) goto out_of_memory; @@ -155,31 +150,10 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, goto bus_err; BUG(); } - - /* - * Major/minor page fault accounting is only done on the - * initial attempt. If we go through a retry, it is extremely - * likely that the page will be found in page cache at that point. - */ - if (flags & FAULT_FLAG_ALLOW_RETRY) { - if (fault & VM_FAULT_MAJOR) - current->maj_flt++; - else - current->min_flt++; - if (fault & VM_FAULT_RETRY) { - /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk - * of starvation. */ - flags &= ~FAULT_FLAG_ALLOW_RETRY; - - /* - * No need to up_read(&mm->mmap_sem) as we would - * have already released it in __lock_page_or_retry - * in mm/filemap.c. - */ - - goto retry; - } - } + if (fault & VM_FAULT_MAJOR) + current->maj_flt++; + else + current->min_flt++; up_read(&mm->mmap_sem); return 0; diff --git a/trunk/arch/m68k/platform/5206/Makefile b/trunk/arch/m68k/platform/5206/Makefile new file mode 100644 index 000000000000..b5db05625cfa --- /dev/null +++ b/trunk/arch/m68k/platform/5206/Makefile @@ -0,0 +1,18 @@ +# +# Makefile for the m68knommu linux kernel. +# + +# +# If you want to play with the HW breakpoints then you will +# need to add define this, which will give you a stack backtrace +# on the console port whenever a DBG interrupt occurs. You have to +# set up you HW breakpoints to trigger a DBG interrupt: +# +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT +# + +asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 + +obj-y := config.o gpio.o + diff --git a/trunk/arch/m68k/platform/coldfire/m5206.c b/trunk/arch/m68k/platform/5206/config.c similarity index 80% rename from trunk/arch/m68k/platform/coldfire/m5206.c rename to trunk/arch/m68k/platform/5206/config.c index a8b81df653f0..6bfbeebd231b 100644 --- a/trunk/arch/m68k/platform/coldfire/m5206.c +++ b/trunk/arch/m68k/platform/5206/config.c @@ -16,15 +16,6 @@ #include #include #include -#include - -/***************************************************************************/ - -struct mcf_gpio_chip mcf_gpio_chips[] = { - MCFGPS(PP, 0, 8, MCFSIM_PADDR, MCFSIM_PADAT, MCFSIM_PADAT), -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); /***************************************************************************/ diff --git a/trunk/arch/m68k/platform/5206/gpio.c b/trunk/arch/m68k/platform/5206/gpio.c new file mode 100644 index 000000000000..b9ab4a120f28 --- /dev/null +++ b/trunk/arch/m68k/platform/5206/gpio.c @@ -0,0 +1,49 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +*/ + +#include +#include + +#include +#include +#include + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "PP", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFSIM_PADDR, + .podr = (void __iomem *) MCFSIM_PADAT, + .ppdr = (void __iomem *) MCFSIM_PADAT, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/trunk/arch/m68k/platform/520x/Makefile b/trunk/arch/m68k/platform/520x/Makefile new file mode 100644 index 000000000000..ad3f4e5a57ce --- /dev/null +++ b/trunk/arch/m68k/platform/520x/Makefile @@ -0,0 +1,17 @@ +# +# Makefile for the M5208 specific file. +# + +# +# If you want to play with the HW breakpoints then you will +# need to add define this, which will give you a stack backtrace +# on the console port whenever a DBG interrupt occurs. You have to +# set up you HW breakpoints to trigger a DBG interrupt: +# +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT +# + +asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 + +obj-y := config.o gpio.o diff --git a/trunk/arch/m68k/platform/coldfire/m520x.c b/trunk/arch/m68k/platform/520x/config.c similarity index 79% rename from trunk/arch/m68k/platform/coldfire/m520x.c rename to trunk/arch/m68k/platform/520x/config.c index 3264b8883d5f..235947844f27 100644 --- a/trunk/arch/m68k/platform/coldfire/m520x.c +++ b/trunk/arch/m68k/platform/520x/config.c @@ -19,26 +19,10 @@ #include #include #include -#include /***************************************************************************/ -struct mcf_gpio_chip mcf_gpio_chips[] = { - MCFGPS(PIRQ, 0, 8, MCFEPORT_EPDDR, MCFEPORT_EPDR, MCFEPORT_EPPDR), - MCFGPF(CS, 9, 3), - MCFGPF(FECI2C, 16, 4), - MCFGPF(QSPI, 24, 4), - MCFGPF(TIMER, 32, 4), - MCFGPF(UART, 40, 8), - MCFGPF(FECH, 48, 8), - MCFGPF(FECL, 56, 8), -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); - -/***************************************************************************/ - -#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) +#ifdef CONFIG_SPI_COLDFIRE_QSPI static void __init m520x_qspi_init(void) { @@ -51,7 +35,7 @@ static void __init m520x_qspi_init(void) writew(par, MCF_GPIO_PAR_UART); } -#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */ +#endif /* CONFIG_SPI_COLDFIRE_QSPI */ /***************************************************************************/ @@ -95,7 +79,7 @@ void __init config_BSP(char *commandp, int size) mach_sched_init = hw_timer_init; m520x_uarts_init(); m520x_fec_init(); -#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) +#ifdef CONFIG_SPI_COLDFIRE_QSPI m520x_qspi_init(); #endif } diff --git a/trunk/arch/m68k/platform/520x/gpio.c b/trunk/arch/m68k/platform/520x/gpio.c new file mode 100644 index 000000000000..9bcc3e4b60c5 --- /dev/null +++ b/trunk/arch/m68k/platform/520x/gpio.c @@ -0,0 +1,175 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +*/ + +#include +#include + +#include +#include +#include + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "PIRQ", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFEPORT_EPDDR, + .podr = (void __iomem *) MCFEPORT_EPDR, + .ppdr = (void __iomem *) MCFEPORT_EPPDR, + }, + { + .gpio_chip = { + .label = "CS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 9, + .ngpio = 3, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_CS, + .podr = (void __iomem *) MCFGPIO_PODR_CS, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_CS, + .setr = (void __iomem *) MCFGPIO_PPDSDR_CS, + .clrr = (void __iomem *) MCFGPIO_PCLRR_CS, + }, + { + .gpio_chip = { + .label = "FECI2C", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 16, + .ngpio = 4, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_FECI2C, + .podr = (void __iomem *) MCFGPIO_PODR_FECI2C, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_FECI2C, + .setr = (void __iomem *) MCFGPIO_PPDSDR_FECI2C, + .clrr = (void __iomem *) MCFGPIO_PCLRR_FECI2C, + }, + { + .gpio_chip = { + .label = "QSPI", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 24, + .ngpio = 4, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_QSPI, + .podr = (void __iomem *) MCFGPIO_PODR_QSPI, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_QSPI, + .setr = (void __iomem *) MCFGPIO_PPDSDR_QSPI, + .clrr = (void __iomem *) MCFGPIO_PCLRR_QSPI, + }, + { + .gpio_chip = { + .label = "TIMER", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 32, + .ngpio = 4, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_TIMER, + .podr = (void __iomem *) MCFGPIO_PODR_TIMER, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_TIMER, + .setr = (void __iomem *) MCFGPIO_PPDSDR_TIMER, + .clrr = (void __iomem *) MCFGPIO_PCLRR_TIMER, + }, + { + .gpio_chip = { + .label = "UART", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 40, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_UART, + .podr = (void __iomem *) MCFGPIO_PODR_UART, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_UART, + .setr = (void __iomem *) MCFGPIO_PPDSDR_UART, + .clrr = (void __iomem *) MCFGPIO_PCLRR_UART, + }, + { + .gpio_chip = { + .label = "FECH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 48, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_FECH, + .podr = (void __iomem *) MCFGPIO_PODR_FECH, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_FECH, + .setr = (void __iomem *) MCFGPIO_PPDSDR_FECH, + .clrr = (void __iomem *) MCFGPIO_PCLRR_FECH, + }, + { + .gpio_chip = { + .label = "FECL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 56, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_FECL, + .podr = (void __iomem *) MCFGPIO_PODR_FECL, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_FECL, + .setr = (void __iomem *) MCFGPIO_PPDSDR_FECL, + .clrr = (void __iomem *) MCFGPIO_PCLRR_FECL, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/trunk/arch/m68k/platform/523x/Makefile b/trunk/arch/m68k/platform/523x/Makefile new file mode 100644 index 000000000000..c04b8f71c88c --- /dev/null +++ b/trunk/arch/m68k/platform/523x/Makefile @@ -0,0 +1,17 @@ +# +# Makefile for the m68knommu linux kernel. +# + +# +# If you want to play with the HW breakpoints then you will +# need to add define this, which will give you a stack backtrace +# on the console port whenever a DBG interrupt occurs. You have to +# set up you HW breakpoints to trigger a DBG interrupt: +# +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT +# + +asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 + +obj-y := config.o gpio.o diff --git a/trunk/arch/m68k/platform/coldfire/m523x.c b/trunk/arch/m68k/platform/523x/config.c similarity index 68% rename from trunk/arch/m68k/platform/coldfire/m523x.c rename to trunk/arch/m68k/platform/523x/config.c index 5d57a4249412..c8b405d5a961 100644 --- a/trunk/arch/m68k/platform/coldfire/m523x.c +++ b/trunk/arch/m68k/platform/523x/config.c @@ -19,32 +19,10 @@ #include #include #include -#include /***************************************************************************/ -struct mcf_gpio_chip mcf_gpio_chips[] = { - MCFGPS(PIRQ, 1, 7, MCFEPORT_EPDDR, MCFEPORT_EPDR, MCFEPORT_EPPDR), - MCFGPF(ADDR, 13, 3), - MCFGPF(DATAH, 16, 8), - MCFGPF(DATAL, 24, 8), - MCFGPF(BUSCTL, 32, 8), - MCFGPF(BS, 40, 4), - MCFGPF(CS, 49, 7), - MCFGPF(SDRAM, 56, 6), - MCFGPF(FECI2C, 64, 4), - MCFGPF(UARTH, 72, 2), - MCFGPF(UARTL, 80, 8), - MCFGPF(QSPI, 88, 5), - MCFGPF(TIMER, 96, 8), - MCFGPF(ETPU, 104, 3), -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); - -/***************************************************************************/ - -#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) +#ifdef CONFIG_SPI_COLDFIRE_QSPI static void __init m523x_qspi_init(void) { @@ -58,7 +36,7 @@ static void __init m523x_qspi_init(void) writew(par, MCFGPIO_PAR_TIMER); } -#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */ +#endif /* CONFIG_SPI_COLDFIRE_QSPI */ /***************************************************************************/ @@ -80,7 +58,7 @@ void __init config_BSP(char *commandp, int size) { mach_sched_init = hw_timer_init; m523x_fec_init(); -#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) +#ifdef CONFIG_SPI_COLDFIRE_QSPI m523x_qspi_init(); #endif } diff --git a/trunk/arch/m68k/platform/523x/gpio.c b/trunk/arch/m68k/platform/523x/gpio.c new file mode 100644 index 000000000000..327ebf142c8e --- /dev/null +++ b/trunk/arch/m68k/platform/523x/gpio.c @@ -0,0 +1,284 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +*/ + +#include +#include + +#include +#include +#include + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "PIRQ", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .base = 1, + .ngpio = 7, + }, + .pddr = (void __iomem *) MCFEPORT_EPDDR, + .podr = (void __iomem *) MCFEPORT_EPDR, + .ppdr = (void __iomem *) MCFEPORT_EPPDR, + }, + { + .gpio_chip = { + .label = "ADDR", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 13, + .ngpio = 3, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_ADDR, + .podr = (void __iomem *) MCFGPIO_PODR_ADDR, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_ADDR, + .setr = (void __iomem *) MCFGPIO_PPDSDR_ADDR, + .clrr = (void __iomem *) MCFGPIO_PCLRR_ADDR, + }, + { + .gpio_chip = { + .label = "DATAH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 16, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_DATAH, + .podr = (void __iomem *) MCFGPIO_PODR_DATAH, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_DATAH, + .setr = (void __iomem *) MCFGPIO_PPDSDR_DATAH, + .clrr = (void __iomem *) MCFGPIO_PCLRR_DATAH, + }, + { + .gpio_chip = { + .label = "DATAL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 24, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_DATAL, + .podr = (void __iomem *) MCFGPIO_PODR_DATAL, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_DATAL, + .setr = (void __iomem *) MCFGPIO_PPDSDR_DATAL, + .clrr = (void __iomem *) MCFGPIO_PCLRR_DATAL, + }, + { + .gpio_chip = { + .label = "BUSCTL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 32, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_BUSCTL, + .podr = (void __iomem *) MCFGPIO_PODR_BUSCTL, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_BUSCTL, + .setr = (void __iomem *) MCFGPIO_PPDSDR_BUSCTL, + .clrr = (void __iomem *) MCFGPIO_PCLRR_BUSCTL, + }, + { + .gpio_chip = { + .label = "BS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 40, + .ngpio = 4, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_BS, + .podr = (void __iomem *) MCFGPIO_PODR_BS, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_BS, + .setr = (void __iomem *) MCFGPIO_PPDSDR_BS, + .clrr = (void __iomem *) MCFGPIO_PCLRR_BS, + }, + { + .gpio_chip = { + .label = "CS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 49, + .ngpio = 7, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_CS, + .podr = (void __iomem *) MCFGPIO_PODR_CS, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_CS, + .setr = (void __iomem *) MCFGPIO_PPDSDR_CS, + .clrr = (void __iomem *) MCFGPIO_PCLRR_CS, + }, + { + .gpio_chip = { + .label = "SDRAM", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 56, + .ngpio = 6, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_SDRAM, + .podr = (void __iomem *) MCFGPIO_PODR_SDRAM, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_SDRAM, + .setr = (void __iomem *) MCFGPIO_PPDSDR_SDRAM, + .clrr = (void __iomem *) MCFGPIO_PCLRR_SDRAM, + }, + { + .gpio_chip = { + .label = "FECI2C", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 64, + .ngpio = 4, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_FECI2C, + .podr = (void __iomem *) MCFGPIO_PODR_FECI2C, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_FECI2C, + .setr = (void __iomem *) MCFGPIO_PPDSDR_FECI2C, + .clrr = (void __iomem *) MCFGPIO_PCLRR_FECI2C, + }, + { + .gpio_chip = { + .label = "UARTH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 72, + .ngpio = 2, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_UARTH, + .podr = (void __iomem *) MCFGPIO_PODR_UARTH, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_UARTH, + .setr = (void __iomem *) MCFGPIO_PPDSDR_UARTH, + .clrr = (void __iomem *) MCFGPIO_PCLRR_UARTH, + }, + { + .gpio_chip = { + .label = "UARTL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 80, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_UARTL, + .podr = (void __iomem *) MCFGPIO_PODR_UARTL, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_UARTL, + .setr = (void __iomem *) MCFGPIO_PPDSDR_UARTL, + .clrr = (void __iomem *) MCFGPIO_PCLRR_UARTL, + }, + { + .gpio_chip = { + .label = "QSPI", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 88, + .ngpio = 5, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_QSPI, + .podr = (void __iomem *) MCFGPIO_PODR_QSPI, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_QSPI, + .setr = (void __iomem *) MCFGPIO_PPDSDR_QSPI, + .clrr = (void __iomem *) MCFGPIO_PCLRR_QSPI, + }, + { + .gpio_chip = { + .label = "TIMER", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 96, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_TIMER, + .podr = (void __iomem *) MCFGPIO_PODR_TIMER, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_TIMER, + .setr = (void __iomem *) MCFGPIO_PPDSDR_TIMER, + .clrr = (void __iomem *) MCFGPIO_PCLRR_TIMER, + }, + { + .gpio_chip = { + .label = "ETPU", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 104, + .ngpio = 3, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_ETPU, + .podr = (void __iomem *) MCFGPIO_PODR_ETPU, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_ETPU, + .setr = (void __iomem *) MCFGPIO_PPDSDR_ETPU, + .clrr = (void __iomem *) MCFGPIO_PCLRR_ETPU, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/trunk/arch/m68k/platform/5249/Makefile b/trunk/arch/m68k/platform/5249/Makefile new file mode 100644 index 000000000000..4bed30fd0073 --- /dev/null +++ b/trunk/arch/m68k/platform/5249/Makefile @@ -0,0 +1,18 @@ +# +# Makefile for the m68knommu linux kernel. +# + +# +# If you want to play with the HW breakpoints then you will +# need to add define this, which will give you a stack backtrace +# on the console port whenever a DBG interrupt occurs. You have to +# set up you HW breakpoints to trigger a DBG interrupt: +# +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT +# + +asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 + +obj-y := config.o gpio.o intc2.o + diff --git a/trunk/arch/m68k/platform/coldfire/m5249.c b/trunk/arch/m68k/platform/5249/config.c similarity index 82% rename from trunk/arch/m68k/platform/coldfire/m5249.c rename to trunk/arch/m68k/platform/5249/config.c index fdfa1edfd1ac..bbf05135bb98 100644 --- a/trunk/arch/m68k/platform/coldfire/m5249.c +++ b/trunk/arch/m68k/platform/5249/config.c @@ -16,16 +16,6 @@ #include #include #include -#include - -/***************************************************************************/ - -struct mcf_gpio_chip mcf_gpio_chips[] = { - MCFGPS(GPIO0, 0, 32, MCFSIM2_GPIOENABLE, MCFSIM2_GPIOWRITE, MCFSIM2_GPIOREAD), - MCFGPS(GPIO1, 32, 32, MCFSIM2_GPIO1ENABLE, MCFSIM2_GPIO1WRITE, MCFSIM2_GPIO1READ), -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); /***************************************************************************/ @@ -61,7 +51,7 @@ static struct platform_device *m5249_devices[] __initdata = { /***************************************************************************/ -#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) +#ifdef CONFIG_SPI_COLDFIRE_QSPI static void __init m5249_qspi_init(void) { @@ -71,7 +61,7 @@ static void __init m5249_qspi_init(void) mcf_mapirq2imr(MCF_IRQ_QSPI, MCFINTC_QSPI); } -#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */ +#endif /* CONFIG_SPI_COLDFIRE_QSPI */ /***************************************************************************/ @@ -100,7 +90,7 @@ void __init config_BSP(char *commandp, int size) #ifdef CONFIG_M5249C3 m5249_smc91x_init(); #endif -#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) +#ifdef CONFIG_SPI_COLDFIRE_QSPI m5249_qspi_init(); #endif } diff --git a/trunk/arch/m68k/platform/5249/gpio.c b/trunk/arch/m68k/platform/5249/gpio.c new file mode 100644 index 000000000000..2b56c6ef65bf --- /dev/null +++ b/trunk/arch/m68k/platform/5249/gpio.c @@ -0,0 +1,65 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +*/ + +#include +#include + +#include +#include +#include + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "GPIO0", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .ngpio = 32, + }, + .pddr = (void __iomem *) MCFSIM2_GPIOENABLE, + .podr = (void __iomem *) MCFSIM2_GPIOWRITE, + .ppdr = (void __iomem *) MCFSIM2_GPIOREAD, + }, + { + .gpio_chip = { + .label = "GPIO1", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .base = 32, + .ngpio = 32, + }, + .pddr = (void __iomem *) MCFSIM2_GPIO1ENABLE, + .podr = (void __iomem *) MCFSIM2_GPIO1WRITE, + .ppdr = (void __iomem *) MCFSIM2_GPIO1READ, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/trunk/arch/m68k/platform/coldfire/intc-5249.c b/trunk/arch/m68k/platform/5249/intc2.c similarity index 100% rename from trunk/arch/m68k/platform/coldfire/intc-5249.c rename to trunk/arch/m68k/platform/5249/intc2.c diff --git a/trunk/arch/m68k/platform/5272/Makefile b/trunk/arch/m68k/platform/5272/Makefile new file mode 100644 index 000000000000..34110fc14301 --- /dev/null +++ b/trunk/arch/m68k/platform/5272/Makefile @@ -0,0 +1,18 @@ +# +# Makefile for the linux kernel. +# + +# +# If you want to play with the HW breakpoints then you will +# need to add define this, which will give you a stack backtrace +# on the console port whenever a DBG interrupt occurs. You have to +# set up you HW breakpoints to trigger a DBG interrupt: +# +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT +# + +asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 + +obj-y := config.o gpio.o intc.o + diff --git a/trunk/arch/m68k/platform/coldfire/m5272.c b/trunk/arch/m68k/platform/5272/config.c similarity index 88% rename from trunk/arch/m68k/platform/coldfire/m5272.c rename to trunk/arch/m68k/platform/5272/config.c index 43e36060da18..e68bc7a148eb 100644 --- a/trunk/arch/m68k/platform/coldfire/m5272.c +++ b/trunk/arch/m68k/platform/5272/config.c @@ -19,7 +19,6 @@ #include #include #include -#include /***************************************************************************/ @@ -31,16 +30,6 @@ unsigned char ledbank = 0xff; /***************************************************************************/ -struct mcf_gpio_chip mcf_gpio_chips[] = { - MCFGPS(PA, 0, 16, MCFSIM_PADDR, MCFSIM_PADAT, MCFSIM_PADAT), - MCFGPS(PB, 16, 16, MCFSIM_PBDDR, MCFSIM_PBDAT, MCFSIM_PBDAT), - MCFGPS(Pc, 32, 16, MCFSIM_PCDDR, MCFSIM_PCDAT, MCFSIM_PCDAT), -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); - -/***************************************************************************/ - static void __init m5272_uarts_init(void) { u32 v; diff --git a/trunk/arch/m68k/platform/5272/gpio.c b/trunk/arch/m68k/platform/5272/gpio.c new file mode 100644 index 000000000000..57ac10a5d7f7 --- /dev/null +++ b/trunk/arch/m68k/platform/5272/gpio.c @@ -0,0 +1,81 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +*/ + +#include +#include + +#include +#include +#include + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "PA", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .ngpio = 16, + }, + .pddr = (void __iomem *) MCFSIM_PADDR, + .podr = (void __iomem *) MCFSIM_PADAT, + .ppdr = (void __iomem *) MCFSIM_PADAT, + }, + { + .gpio_chip = { + .label = "PB", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .base = 16, + .ngpio = 16, + }, + .pddr = (void __iomem *) MCFSIM_PBDDR, + .podr = (void __iomem *) MCFSIM_PBDAT, + .ppdr = (void __iomem *) MCFSIM_PBDAT, + }, + { + .gpio_chip = { + .label = "PC", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .base = 32, + .ngpio = 16, + }, + .pddr = (void __iomem *) MCFSIM_PCDDR, + .podr = (void __iomem *) MCFSIM_PCDAT, + .ppdr = (void __iomem *) MCFSIM_PCDAT, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/trunk/arch/m68k/platform/coldfire/intc-5272.c b/trunk/arch/m68k/platform/5272/intc.c similarity index 100% rename from trunk/arch/m68k/platform/coldfire/intc-5272.c rename to trunk/arch/m68k/platform/5272/intc.c diff --git a/trunk/arch/m68k/platform/527x/Makefile b/trunk/arch/m68k/platform/527x/Makefile new file mode 100644 index 000000000000..6ac4b57370ea --- /dev/null +++ b/trunk/arch/m68k/platform/527x/Makefile @@ -0,0 +1,18 @@ +# +# Makefile for the linux kernel. +# + +# +# If you want to play with the HW breakpoints then you will +# need to add define this, which will give you a stack backtrace +# on the console port whenever a DBG interrupt occurs. You have to +# set up you HW breakpoints to trigger a DBG interrupt: +# +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT +# + +asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 + +obj-y := config.o gpio.o + diff --git a/trunk/arch/m68k/platform/coldfire/m527x.c b/trunk/arch/m68k/platform/527x/config.c similarity index 67% rename from trunk/arch/m68k/platform/coldfire/m527x.c rename to trunk/arch/m68k/platform/527x/config.c index 9b0b66aabd1b..f91a53294c35 100644 --- a/trunk/arch/m68k/platform/coldfire/m527x.c +++ b/trunk/arch/m68k/platform/527x/config.c @@ -20,53 +20,10 @@ #include #include #include -#include /***************************************************************************/ -struct mcf_gpio_chip mcf_gpio_chips[] = { -#if defined(CONFIG_M5271) - MCFGPS(PIRQ, 1, 7, MCFEPORT_EPDDR, MCFEPORT_EPDR, MCFEPORT_EPPDR), - MCFGPF(ADDR, 13, 3), - MCFGPF(DATAH, 16, 8), - MCFGPF(DATAL, 24, 8), - MCFGPF(BUSCTL, 32, 8), - MCFGPF(BS, 40, 4), - MCFGPF(CS, 49, 7), - MCFGPF(SDRAM, 56, 6), - MCFGPF(FECI2C, 64, 4), - MCFGPF(UARTH, 72, 2), - MCFGPF(UARTL, 80, 8), - MCFGPF(QSPI, 88, 5), - MCFGPF(TIMER, 96, 8), -#elif defined(CONFIG_M5275) - MCFGPS(PIRQ, 1, 7, MCFEPORT_EPDDR, MCFEPORT_EPDR, MCFEPORT_EPPDR), - MCFGPF(BUSCTL, 8, 8), - MCFGPF(ADDR, 21, 3), - MCFGPF(CS, 25, 7), - MCFGPF(FEC0H, 32, 8), - MCFGPF(FEC0L, 40, 8), - MCFGPF(FECI2C, 48, 6), - MCFGPF(QSPI, 56, 7), - MCFGPF(SDRAM, 64, 8), - MCFGPF(TIMERH, 72, 4), - MCFGPF(TIMERL, 80, 4), - MCFGPF(UARTL, 88, 8), - MCFGPF(FEC1H, 96, 8), - MCFGPF(FEC1L, 104, 8), - MCFGPF(BS, 114, 2), - MCFGPF(IRQ, 121, 7), - MCFGPF(USBH, 128, 1), - MCFGPF(USBL, 136, 8), - MCFGPF(UARTH, 144, 4), -#endif -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); - -/***************************************************************************/ - -#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) +#ifdef CONFIG_SPI_COLDFIRE_QSPI static void __init m527x_qspi_init(void) { @@ -85,7 +42,7 @@ static void __init m527x_qspi_init(void) #endif } -#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */ +#endif /* CONFIG_SPI_COLDFIRE_QSPI */ /***************************************************************************/ @@ -133,7 +90,7 @@ void __init config_BSP(char *commandp, int size) mach_sched_init = hw_timer_init; m527x_uarts_init(); m527x_fec_init(); -#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) +#ifdef CONFIG_SPI_COLDFIRE_QSPI m527x_qspi_init(); #endif } diff --git a/trunk/arch/m68k/platform/527x/gpio.c b/trunk/arch/m68k/platform/527x/gpio.c new file mode 100644 index 000000000000..205da0aa0f2d --- /dev/null +++ b/trunk/arch/m68k/platform/527x/gpio.c @@ -0,0 +1,609 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +*/ + +#include +#include + +#include +#include +#include + +static struct mcf_gpio_chip mcf_gpio_chips[] = { +#if defined(CONFIG_M5271) + { + .gpio_chip = { + .label = "PIRQ", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .base = 1, + .ngpio = 7, + }, + .pddr = (void __iomem *) MCFEPORT_EPDDR, + .podr = (void __iomem *) MCFEPORT_EPDR, + .ppdr = (void __iomem *) MCFEPORT_EPPDR, + }, + { + .gpio_chip = { + .label = "ADDR", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 13, + .ngpio = 3, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_ADDR, + .podr = (void __iomem *) MCFGPIO_PODR_ADDR, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_ADDR, + .setr = (void __iomem *) MCFGPIO_PPDSDR_ADDR, + .clrr = (void __iomem *) MCFGPIO_PCLRR_ADDR, + }, + { + .gpio_chip = { + .label = "DATAH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 16, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_DATAH, + .podr = (void __iomem *) MCFGPIO_PODR_DATAH, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_DATAH, + .setr = (void __iomem *) MCFGPIO_PPDSDR_DATAH, + .clrr = (void __iomem *) MCFGPIO_PCLRR_DATAH, + }, + { + .gpio_chip = { + .label = "DATAL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 24, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_DATAL, + .podr = (void __iomem *) MCFGPIO_PODR_DATAL, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_DATAL, + .setr = (void __iomem *) MCFGPIO_PPDSDR_DATAL, + .clrr = (void __iomem *) MCFGPIO_PCLRR_DATAL, + }, + { + .gpio_chip = { + .label = "BUSCTL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 32, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_BUSCTL, + .podr = (void __iomem *) MCFGPIO_PODR_BUSCTL, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_BUSCTL, + .setr = (void __iomem *) MCFGPIO_PPDSDR_BUSCTL, + .clrr = (void __iomem *) MCFGPIO_PCLRR_BUSCTL, + }, + { + .gpio_chip = { + .label = "BS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 40, + .ngpio = 4, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_BS, + .podr = (void __iomem *) MCFGPIO_PODR_BS, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_BS, + .setr = (void __iomem *) MCFGPIO_PPDSDR_BS, + .clrr = (void __iomem *) MCFGPIO_PCLRR_BS, + }, + { + .gpio_chip = { + .label = "CS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 49, + .ngpio = 7, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_CS, + .podr = (void __iomem *) MCFGPIO_PODR_CS, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_CS, + .setr = (void __iomem *) MCFGPIO_PPDSDR_CS, + .clrr = (void __iomem *) MCFGPIO_PCLRR_CS, + }, + { + .gpio_chip = { + .label = "SDRAM", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 56, + .ngpio = 6, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_SDRAM, + .podr = (void __iomem *) MCFGPIO_PODR_SDRAM, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_SDRAM, + .setr = (void __iomem *) MCFGPIO_PPDSDR_SDRAM, + .clrr = (void __iomem *) MCFGPIO_PCLRR_SDRAM, + }, + { + .gpio_chip = { + .label = "FECI2C", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 64, + .ngpio = 4, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_FECI2C, + .podr = (void __iomem *) MCFGPIO_PODR_FECI2C, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_FECI2C, + .setr = (void __iomem *) MCFGPIO_PPDSDR_FECI2C, + .clrr = (void __iomem *) MCFGPIO_PCLRR_FECI2C, + }, + { + .gpio_chip = { + .label = "UARTH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 72, + .ngpio = 2, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_UARTH, + .podr = (void __iomem *) MCFGPIO_PODR_UARTH, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_UARTH, + .setr = (void __iomem *) MCFGPIO_PPDSDR_UARTH, + .clrr = (void __iomem *) MCFGPIO_PCLRR_UARTH, + }, + { + .gpio_chip = { + .label = "UARTL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 80, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_UARTL, + .podr = (void __iomem *) MCFGPIO_PODR_UARTL, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_UARTL, + .setr = (void __iomem *) MCFGPIO_PPDSDR_UARTL, + .clrr = (void __iomem *) MCFGPIO_PCLRR_UARTL, + }, + { + .gpio_chip = { + .label = "QSPI", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 88, + .ngpio = 5, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_QSPI, + .podr = (void __iomem *) MCFGPIO_PODR_QSPI, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_QSPI, + .setr = (void __iomem *) MCFGPIO_PPDSDR_QSPI, + .clrr = (void __iomem *) MCFGPIO_PCLRR_QSPI, + }, + { + .gpio_chip = { + .label = "TIMER", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 96, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_TIMER, + .podr = (void __iomem *) MCFGPIO_PODR_TIMER, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_TIMER, + .setr = (void __iomem *) MCFGPIO_PPDSDR_TIMER, + .clrr = (void __iomem *) MCFGPIO_PCLRR_TIMER, + }, +#elif defined(CONFIG_M5275) + { + .gpio_chip = { + .label = "PIRQ", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .base = 1, + .ngpio = 7, + }, + .pddr = (void __iomem *) MCFEPORT_EPDDR, + .podr = (void __iomem *) MCFEPORT_EPDR, + .ppdr = (void __iomem *) MCFEPORT_EPPDR, + }, + { + .gpio_chip = { + .label = "BUSCTL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 8, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_BUSCTL, + .podr = (void __iomem *) MCFGPIO_PODR_BUSCTL, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_BUSCTL, + .setr = (void __iomem *) MCFGPIO_PPDSDR_BUSCTL, + .clrr = (void __iomem *) MCFGPIO_PCLRR_BUSCTL, + }, + { + .gpio_chip = { + .label = "ADDR", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 21, + .ngpio = 3, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_ADDR, + .podr = (void __iomem *) MCFGPIO_PODR_ADDR, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_ADDR, + .setr = (void __iomem *) MCFGPIO_PPDSDR_ADDR, + .clrr = (void __iomem *) MCFGPIO_PCLRR_ADDR, + }, + { + .gpio_chip = { + .label = "CS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 25, + .ngpio = 7, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_CS, + .podr = (void __iomem *) MCFGPIO_PODR_CS, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_CS, + .setr = (void __iomem *) MCFGPIO_PPDSDR_CS, + .clrr = (void __iomem *) MCFGPIO_PCLRR_CS, + }, + { + .gpio_chip = { + .label = "FEC0H", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 32, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_FEC0H, + .podr = (void __iomem *) MCFGPIO_PODR_FEC0H, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_FEC0H, + .setr = (void __iomem *) MCFGPIO_PPDSDR_FEC0H, + .clrr = (void __iomem *) MCFGPIO_PCLRR_FEC0H, + }, + { + .gpio_chip = { + .label = "FEC0L", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 40, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_FEC0L, + .podr = (void __iomem *) MCFGPIO_PODR_FEC0L, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_FEC0L, + .setr = (void __iomem *) MCFGPIO_PPDSDR_FEC0L, + .clrr = (void __iomem *) MCFGPIO_PCLRR_FEC0L, + }, + { + .gpio_chip = { + .label = "FECI2C", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 48, + .ngpio = 6, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_FECI2C, + .podr = (void __iomem *) MCFGPIO_PODR_FECI2C, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_FECI2C, + .setr = (void __iomem *) MCFGPIO_PPDSDR_FECI2C, + .clrr = (void __iomem *) MCFGPIO_PCLRR_FECI2C, + }, + { + .gpio_chip = { + .label = "QSPI", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 56, + .ngpio = 7, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_QSPI, + .podr = (void __iomem *) MCFGPIO_PODR_QSPI, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_QSPI, + .setr = (void __iomem *) MCFGPIO_PPDSDR_QSPI, + .clrr = (void __iomem *) MCFGPIO_PCLRR_QSPI, + }, + { + .gpio_chip = { + .label = "SDRAM", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 64, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_SDRAM, + .podr = (void __iomem *) MCFGPIO_PODR_SDRAM, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_SDRAM, + .setr = (void __iomem *) MCFGPIO_PPDSDR_SDRAM, + .clrr = (void __iomem *) MCFGPIO_PCLRR_SDRAM, + }, + { + .gpio_chip = { + .label = "TIMERH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 72, + .ngpio = 4, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_TIMERH, + .podr = (void __iomem *) MCFGPIO_PODR_TIMERH, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_TIMERH, + .setr = (void __iomem *) MCFGPIO_PPDSDR_TIMERH, + .clrr = (void __iomem *) MCFGPIO_PCLRR_TIMERH, + }, + { + .gpio_chip = { + .label = "TIMERL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 80, + .ngpio = 4, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_TIMERL, + .podr = (void __iomem *) MCFGPIO_PODR_TIMERL, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_TIMERL, + .setr = (void __iomem *) MCFGPIO_PPDSDR_TIMERL, + .clrr = (void __iomem *) MCFGPIO_PCLRR_TIMERL, + }, + { + .gpio_chip = { + .label = "UARTL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 88, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_UARTL, + .podr = (void __iomem *) MCFGPIO_PODR_UARTL, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_UARTL, + .setr = (void __iomem *) MCFGPIO_PPDSDR_UARTL, + .clrr = (void __iomem *) MCFGPIO_PCLRR_UARTL, + }, + { + .gpio_chip = { + .label = "FEC1H", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 96, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_FEC1H, + .podr = (void __iomem *) MCFGPIO_PODR_FEC1H, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_FEC1H, + .setr = (void __iomem *) MCFGPIO_PPDSDR_FEC1H, + .clrr = (void __iomem *) MCFGPIO_PCLRR_FEC1H, + }, + { + .gpio_chip = { + .label = "FEC1L", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 104, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_FEC1L, + .podr = (void __iomem *) MCFGPIO_PODR_FEC1L, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_FEC1L, + .setr = (void __iomem *) MCFGPIO_PPDSDR_FEC1L, + .clrr = (void __iomem *) MCFGPIO_PCLRR_FEC1L, + }, + { + .gpio_chip = { + .label = "BS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 114, + .ngpio = 2, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_BS, + .podr = (void __iomem *) MCFGPIO_PODR_BS, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_BS, + .setr = (void __iomem *) MCFGPIO_PPDSDR_BS, + .clrr = (void __iomem *) MCFGPIO_PCLRR_BS, + }, + { + .gpio_chip = { + .label = "IRQ", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 121, + .ngpio = 7, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_IRQ, + .podr = (void __iomem *) MCFGPIO_PODR_IRQ, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_IRQ, + .setr = (void __iomem *) MCFGPIO_PPDSDR_IRQ, + .clrr = (void __iomem *) MCFGPIO_PCLRR_IRQ, + }, + { + .gpio_chip = { + .label = "USBH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 128, + .ngpio = 1, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_USBH, + .podr = (void __iomem *) MCFGPIO_PODR_USBH, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_USBH, + .setr = (void __iomem *) MCFGPIO_PPDSDR_USBH, + .clrr = (void __iomem *) MCFGPIO_PCLRR_USBH, + }, + { + .gpio_chip = { + .label = "USBL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 136, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_USBL, + .podr = (void __iomem *) MCFGPIO_PODR_USBL, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_USBL, + .setr = (void __iomem *) MCFGPIO_PPDSDR_USBL, + .clrr = (void __iomem *) MCFGPIO_PCLRR_USBL, + }, + { + .gpio_chip = { + .label = "UARTH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 144, + .ngpio = 4, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_UARTH, + .podr = (void __iomem *) MCFGPIO_PODR_UARTH, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_UARTH, + .setr = (void __iomem *) MCFGPIO_PPDSDR_UARTH, + .clrr = (void __iomem *) MCFGPIO_PCLRR_UARTH, + }, +#endif +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/trunk/arch/m68k/platform/528x/Makefile b/trunk/arch/m68k/platform/528x/Makefile new file mode 100644 index 000000000000..6ac4b57370ea --- /dev/null +++ b/trunk/arch/m68k/platform/528x/Makefile @@ -0,0 +1,18 @@ +# +# Makefile for the linux kernel. +# + +# +# If you want to play with the HW breakpoints then you will +# need to add define this, which will give you a stack backtrace +# on the console port whenever a DBG interrupt occurs. You have to +# set up you HW breakpoints to trigger a DBG interrupt: +# +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT +# + +asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 + +obj-y := config.o gpio.o + diff --git a/trunk/arch/m68k/platform/coldfire/m528x.c b/trunk/arch/m68k/platform/528x/config.c similarity index 70% rename from trunk/arch/m68k/platform/coldfire/m528x.c rename to trunk/arch/m68k/platform/528x/config.c index 7ed1276b29dc..d4492926614c 100644 --- a/trunk/arch/m68k/platform/coldfire/m528x.c +++ b/trunk/arch/m68k/platform/528x/config.c @@ -21,41 +21,10 @@ #include #include #include -#include /***************************************************************************/ -struct mcf_gpio_chip mcf_gpio_chips[] = { - MCFGPS(NQ, 1, 7, MCFEPORT_EPDDR, MCFEPORT_EPDR, MCFEPORT_EPPDR), - MCFGPS(TA, 8, 4, MCFGPTA_GPTDDR, MCFGPTA_GPTPORT, MCFGPTB_GPTPORT), - MCFGPS(TB, 16, 4, MCFGPTB_GPTDDR, MCFGPTB_GPTPORT, MCFGPTB_GPTPORT), - MCFGPS(QA, 24, 4, MCFQADC_DDRQA, MCFQADC_PORTQA, MCFQADC_PORTQA), - MCFGPS(QB, 32, 4, MCFQADC_DDRQB, MCFQADC_PORTQB, MCFQADC_PORTQB), - MCFGPF(A, 40, 8), - MCFGPF(B, 48, 8), - MCFGPF(C, 56, 8), - MCFGPF(D, 64, 8), - MCFGPF(E, 72, 8), - MCFGPF(F, 80, 8), - MCFGPF(G, 88, 8), - MCFGPF(H, 96, 8), - MCFGPF(J, 104, 8), - MCFGPF(DD, 112, 8), - MCFGPF(EH, 120, 8), - MCFGPF(EL, 128, 8), - MCFGPF(AS, 136, 6), - MCFGPF(QS, 144, 7), - MCFGPF(SD, 152, 6), - MCFGPF(TC, 160, 4), - MCFGPF(TD, 168, 4), - MCFGPF(UA, 176, 4), -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); - -/***************************************************************************/ - -#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) +#ifdef CONFIG_SPI_COLDFIRE_QSPI static void __init m528x_qspi_init(void) { @@ -63,7 +32,7 @@ static void __init m528x_qspi_init(void) __raw_writeb(0x07, MCFGPIO_PQSPAR); } -#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */ +#endif /* CONFIG_SPI_COLDFIRE_QSPI */ /***************************************************************************/ @@ -129,7 +98,7 @@ void __init config_BSP(char *commandp, int size) mach_sched_init = hw_timer_init; m528x_uarts_init(); m528x_fec_init(); -#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) +#ifdef CONFIG_SPI_COLDFIRE_QSPI m528x_qspi_init(); #endif } diff --git a/trunk/arch/m68k/platform/528x/gpio.c b/trunk/arch/m68k/platform/528x/gpio.c new file mode 100644 index 000000000000..526db665d87e --- /dev/null +++ b/trunk/arch/m68k/platform/528x/gpio.c @@ -0,0 +1,438 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +*/ + +#include +#include + +#include +#include +#include + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "NQ", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .base = 1, + .ngpio = 7, + }, + .pddr = (void __iomem *)MCFEPORT_EPDDR, + .podr = (void __iomem *)MCFEPORT_EPDR, + .ppdr = (void __iomem *)MCFEPORT_EPPDR, + }, + { + .gpio_chip = { + .label = "TA", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 8, + .ngpio = 4, + }, + .pddr = (void __iomem *)MCFGPTA_GPTDDR, + .podr = (void __iomem *)MCFGPTA_GPTPORT, + .ppdr = (void __iomem *)MCFGPTB_GPTPORT, + }, + { + .gpio_chip = { + .label = "TB", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 16, + .ngpio = 4, + }, + .pddr = (void __iomem *)MCFGPTB_GPTDDR, + .podr = (void __iomem *)MCFGPTB_GPTPORT, + .ppdr = (void __iomem *)MCFGPTB_GPTPORT, + }, + { + .gpio_chip = { + .label = "QA", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 24, + .ngpio = 4, + }, + .pddr = (void __iomem *)MCFQADC_DDRQA, + .podr = (void __iomem *)MCFQADC_PORTQA, + .ppdr = (void __iomem *)MCFQADC_PORTQA, + }, + { + .gpio_chip = { + .label = "QB", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 32, + .ngpio = 4, + }, + .pddr = (void __iomem *)MCFQADC_DDRQB, + .podr = (void __iomem *)MCFQADC_PORTQB, + .ppdr = (void __iomem *)MCFQADC_PORTQB, + }, + { + .gpio_chip = { + .label = "A", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 40, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDRA, + .podr = (void __iomem *)MCFGPIO_PORTA, + .ppdr = (void __iomem *)MCFGPIO_PORTAP, + .setr = (void __iomem *)MCFGPIO_SETA, + .clrr = (void __iomem *)MCFGPIO_CLRA, + }, + { + .gpio_chip = { + .label = "B", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 48, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDRB, + .podr = (void __iomem *)MCFGPIO_PORTB, + .ppdr = (void __iomem *)MCFGPIO_PORTBP, + .setr = (void __iomem *)MCFGPIO_SETB, + .clrr = (void __iomem *)MCFGPIO_CLRB, + }, + { + .gpio_chip = { + .label = "C", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 56, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDRC, + .podr = (void __iomem *)MCFGPIO_PORTC, + .ppdr = (void __iomem *)MCFGPIO_PORTCP, + .setr = (void __iomem *)MCFGPIO_SETC, + .clrr = (void __iomem *)MCFGPIO_CLRC, + }, + { + .gpio_chip = { + .label = "D", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 64, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDRD, + .podr = (void __iomem *)MCFGPIO_PORTD, + .ppdr = (void __iomem *)MCFGPIO_PORTDP, + .setr = (void __iomem *)MCFGPIO_SETD, + .clrr = (void __iomem *)MCFGPIO_CLRD, + }, + { + .gpio_chip = { + .label = "E", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 72, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDRE, + .podr = (void __iomem *)MCFGPIO_PORTE, + .ppdr = (void __iomem *)MCFGPIO_PORTEP, + .setr = (void __iomem *)MCFGPIO_SETE, + .clrr = (void __iomem *)MCFGPIO_CLRE, + }, + { + .gpio_chip = { + .label = "F", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 80, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDRF, + .podr = (void __iomem *)MCFGPIO_PORTF, + .ppdr = (void __iomem *)MCFGPIO_PORTFP, + .setr = (void __iomem *)MCFGPIO_SETF, + .clrr = (void __iomem *)MCFGPIO_CLRF, + }, + { + .gpio_chip = { + .label = "G", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 88, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDRG, + .podr = (void __iomem *)MCFGPIO_PORTG, + .ppdr = (void __iomem *)MCFGPIO_PORTGP, + .setr = (void __iomem *)MCFGPIO_SETG, + .clrr = (void __iomem *)MCFGPIO_CLRG, + }, + { + .gpio_chip = { + .label = "H", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 96, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDRH, + .podr = (void __iomem *)MCFGPIO_PORTH, + .ppdr = (void __iomem *)MCFGPIO_PORTHP, + .setr = (void __iomem *)MCFGPIO_SETH, + .clrr = (void __iomem *)MCFGPIO_CLRH, + }, + { + .gpio_chip = { + .label = "J", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 104, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDRJ, + .podr = (void __iomem *)MCFGPIO_PORTJ, + .ppdr = (void __iomem *)MCFGPIO_PORTJP, + .setr = (void __iomem *)MCFGPIO_SETJ, + .clrr = (void __iomem *)MCFGPIO_CLRJ, + }, + { + .gpio_chip = { + .label = "DD", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 112, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDRDD, + .podr = (void __iomem *)MCFGPIO_PORTDD, + .ppdr = (void __iomem *)MCFGPIO_PORTDDP, + .setr = (void __iomem *)MCFGPIO_SETDD, + .clrr = (void __iomem *)MCFGPIO_CLRDD, + }, + { + .gpio_chip = { + .label = "EH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 120, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDREH, + .podr = (void __iomem *)MCFGPIO_PORTEH, + .ppdr = (void __iomem *)MCFGPIO_PORTEHP, + .setr = (void __iomem *)MCFGPIO_SETEH, + .clrr = (void __iomem *)MCFGPIO_CLREH, + }, + { + .gpio_chip = { + .label = "EL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 128, + .ngpio = 8, + }, + .pddr = (void __iomem *)MCFGPIO_DDREL, + .podr = (void __iomem *)MCFGPIO_PORTEL, + .ppdr = (void __iomem *)MCFGPIO_PORTELP, + .setr = (void __iomem *)MCFGPIO_SETEL, + .clrr = (void __iomem *)MCFGPIO_CLREL, + }, + { + .gpio_chip = { + .label = "AS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 136, + .ngpio = 6, + }, + .pddr = (void __iomem *)MCFGPIO_DDRAS, + .podr = (void __iomem *)MCFGPIO_PORTAS, + .ppdr = (void __iomem *)MCFGPIO_PORTASP, + .setr = (void __iomem *)MCFGPIO_SETAS, + .clrr = (void __iomem *)MCFGPIO_CLRAS, + }, + { + .gpio_chip = { + .label = "QS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 144, + .ngpio = 7, + }, + .pddr = (void __iomem *)MCFGPIO_DDRQS, + .podr = (void __iomem *)MCFGPIO_PORTQS, + .ppdr = (void __iomem *)MCFGPIO_PORTQSP, + .setr = (void __iomem *)MCFGPIO_SETQS, + .clrr = (void __iomem *)MCFGPIO_CLRQS, + }, + { + .gpio_chip = { + .label = "SD", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 152, + .ngpio = 6, + }, + .pddr = (void __iomem *)MCFGPIO_DDRSD, + .podr = (void __iomem *)MCFGPIO_PORTSD, + .ppdr = (void __iomem *)MCFGPIO_PORTSDP, + .setr = (void __iomem *)MCFGPIO_SETSD, + .clrr = (void __iomem *)MCFGPIO_CLRSD, + }, + { + .gpio_chip = { + .label = "TC", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 160, + .ngpio = 4, + }, + .pddr = (void __iomem *)MCFGPIO_DDRTC, + .podr = (void __iomem *)MCFGPIO_PORTTC, + .ppdr = (void __iomem *)MCFGPIO_PORTTCP, + .setr = (void __iomem *)MCFGPIO_SETTC, + .clrr = (void __iomem *)MCFGPIO_CLRTC, + }, + { + .gpio_chip = { + .label = "TD", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 168, + .ngpio = 4, + }, + .pddr = (void __iomem *)MCFGPIO_DDRTD, + .podr = (void __iomem *)MCFGPIO_PORTTD, + .ppdr = (void __iomem *)MCFGPIO_PORTTDP, + .setr = (void __iomem *)MCFGPIO_SETTD, + .clrr = (void __iomem *)MCFGPIO_CLRTD, + }, + { + .gpio_chip = { + .label = "UA", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 176, + .ngpio = 4, + }, + .pddr = (void __iomem *)MCFGPIO_DDRUA, + .podr = (void __iomem *)MCFGPIO_PORTUA, + .ppdr = (void __iomem *)MCFGPIO_PORTUAP, + .setr = (void __iomem *)MCFGPIO_SETUA, + .clrr = (void __iomem *)MCFGPIO_CLRUA, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/trunk/arch/m68k/platform/5307/Makefile b/trunk/arch/m68k/platform/5307/Makefile new file mode 100644 index 000000000000..d4293b791f2e --- /dev/null +++ b/trunk/arch/m68k/platform/5307/Makefile @@ -0,0 +1,20 @@ +# +# Makefile for the m68knommu kernel. +# + +# +# If you want to play with the HW breakpoints then you will +# need to add define this, which will give you a stack backtrace +# on the console port whenever a DBG interrupt occurs. You have to +# set up you HW breakpoints to trigger a DBG interrupt: +# +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT +# + +asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 + +obj-y += config.o gpio.o +obj-$(CONFIG_NETtel) += nettel.o +obj-$(CONFIG_CLEOPATRA) += nettel.o + diff --git a/trunk/arch/m68k/platform/coldfire/m5307.c b/trunk/arch/m68k/platform/5307/config.c similarity index 85% rename from trunk/arch/m68k/platform/coldfire/m5307.c rename to trunk/arch/m68k/platform/5307/config.c index 93b484976ab3..a568d2870d15 100644 --- a/trunk/arch/m68k/platform/coldfire/m5307.c +++ b/trunk/arch/m68k/platform/5307/config.c @@ -16,7 +16,6 @@ #include #include #include -#include #include /***************************************************************************/ @@ -29,14 +28,6 @@ unsigned char ledbank = 0xff; /***************************************************************************/ -struct mcf_gpio_chip mcf_gpio_chips[] = { - MCFGPS(PP, 0, 16, MCFSIM_PADDR, MCFSIM_PADAT, MCFSIM_PADAT), -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); - -/***************************************************************************/ - void __init config_BSP(char *commandp, int size) { #if defined(CONFIG_NETtel) || \ diff --git a/trunk/arch/m68k/platform/5307/gpio.c b/trunk/arch/m68k/platform/5307/gpio.c new file mode 100644 index 000000000000..5850612b4a38 --- /dev/null +++ b/trunk/arch/m68k/platform/5307/gpio.c @@ -0,0 +1,49 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +*/ + +#include +#include + +#include +#include +#include + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "PP", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .ngpio = 16, + }, + .pddr = (void __iomem *) MCFSIM_PADDR, + .podr = (void __iomem *) MCFSIM_PADAT, + .ppdr = (void __iomem *) MCFSIM_PADAT, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/trunk/arch/m68k/platform/coldfire/nettel.c b/trunk/arch/m68k/platform/5307/nettel.c similarity index 100% rename from trunk/arch/m68k/platform/coldfire/nettel.c rename to trunk/arch/m68k/platform/5307/nettel.c diff --git a/trunk/arch/m68k/platform/532x/Makefile b/trunk/arch/m68k/platform/532x/Makefile new file mode 100644 index 000000000000..ce01669399c6 --- /dev/null +++ b/trunk/arch/m68k/platform/532x/Makefile @@ -0,0 +1,18 @@ +# +# Makefile for the m68knommu linux kernel. +# + +# +# If you want to play with the HW breakpoints then you will +# need to add define this, which will give you a stack backtrace +# on the console port whenever a DBG interrupt occurs. You have to +# set up you HW breakpoints to trigger a DBG interrupt: +# +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT +# + +asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 + +#obj-y := config.o usb-mcf532x.o spi-mcf532x.o +obj-y := config.o gpio.o diff --git a/trunk/arch/m68k/platform/coldfire/m532x.c b/trunk/arch/m68k/platform/532x/config.c similarity index 93% rename from trunk/arch/m68k/platform/coldfire/m532x.c rename to trunk/arch/m68k/platform/532x/config.c index 8e9476d59a65..2bec3477b739 100644 --- a/trunk/arch/m68k/platform/coldfire/m532x.c +++ b/trunk/arch/m68k/platform/532x/config.c @@ -26,36 +26,11 @@ #include #include #include -#include #include /***************************************************************************/ -struct mcf_gpio_chip mcf_gpio_chips[] = { - MCFGPS(PIRQ, 0, 8, MCFEPORT_EPDDR, MCFEPORT_EPDR, MCFEPORT_EPPDR), - MCFGPF(FECH, 8, 8), - MCFGPF(FECL, 16, 8), - MCFGPF(SSI, 24, 5), - MCFGPF(BUSCTL, 32, 4), - MCFGPF(BE, 40, 4), - MCFGPF(CS, 49, 5), - MCFGPF(PWM, 58, 4), - MCFGPF(FECI2C, 64, 4), - MCFGPF(UART, 72, 8), - MCFGPF(QSPI, 80, 6), - MCFGPF(TIMER, 88, 4), - MCFGPF(LCDDATAH, 96, 2), - MCFGPF(LCDDATAM, 104, 8), - MCFGPF(LCDDATAL, 112, 8), - MCFGPF(LCDCTLH, 120, 1), - MCFGPF(LCDCTLL, 128, 8), -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); - -/***************************************************************************/ - -#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) +#ifdef CONFIG_SPI_COLDFIRE_QSPI static void __init m532x_qspi_init(void) { @@ -63,7 +38,7 @@ static void __init m532x_qspi_init(void) writew(0x01f0, MCF_GPIO_PAR_QSPI); } -#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */ +#endif /* CONFIG_SPI_COLDFIRE_QSPI */ /***************************************************************************/ @@ -102,7 +77,7 @@ void __init config_BSP(char *commandp, int size) mach_sched_init = hw_timer_init; m532x_uarts_init(); m532x_fec_init(); -#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) +#ifdef CONFIG_SPI_COLDFIRE_QSPI m532x_qspi_init(); #endif diff --git a/trunk/arch/m68k/platform/532x/gpio.c b/trunk/arch/m68k/platform/532x/gpio.c new file mode 100644 index 000000000000..212a85deac90 --- /dev/null +++ b/trunk/arch/m68k/platform/532x/gpio.c @@ -0,0 +1,337 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +*/ + +#include +#include + +#include +#include +#include + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "PIRQ", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFEPORT_EPDDR, + .podr = (void __iomem *) MCFEPORT_EPDR, + .ppdr = (void __iomem *) MCFEPORT_EPPDR, + }, + { + .gpio_chip = { + .label = "FECH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 8, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_FECH, + .podr = (void __iomem *) MCFGPIO_PODR_FECH, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_FECH, + .setr = (void __iomem *) MCFGPIO_PPDSDR_FECH, + .clrr = (void __iomem *) MCFGPIO_PCLRR_FECH, + }, + { + .gpio_chip = { + .label = "FECL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 16, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_FECL, + .podr = (void __iomem *) MCFGPIO_PODR_FECL, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_FECL, + .setr = (void __iomem *) MCFGPIO_PPDSDR_FECL, + .clrr = (void __iomem *) MCFGPIO_PCLRR_FECL, + }, + { + .gpio_chip = { + .label = "SSI", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 24, + .ngpio = 5, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_SSI, + .podr = (void __iomem *) MCFGPIO_PODR_SSI, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_SSI, + .setr = (void __iomem *) MCFGPIO_PPDSDR_SSI, + .clrr = (void __iomem *) MCFGPIO_PCLRR_SSI, + }, + { + .gpio_chip = { + .label = "BUSCTL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 32, + .ngpio = 4, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_BUSCTL, + .podr = (void __iomem *) MCFGPIO_PODR_BUSCTL, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_BUSCTL, + .setr = (void __iomem *) MCFGPIO_PPDSDR_BUSCTL, + .clrr = (void __iomem *) MCFGPIO_PCLRR_BUSCTL, + }, + { + .gpio_chip = { + .label = "BE", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 40, + .ngpio = 4, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_BE, + .podr = (void __iomem *) MCFGPIO_PODR_BE, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_BE, + .setr = (void __iomem *) MCFGPIO_PPDSDR_BE, + .clrr = (void __iomem *) MCFGPIO_PCLRR_BE, + }, + { + .gpio_chip = { + .label = "CS", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 49, + .ngpio = 5, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_CS, + .podr = (void __iomem *) MCFGPIO_PODR_CS, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_CS, + .setr = (void __iomem *) MCFGPIO_PPDSDR_CS, + .clrr = (void __iomem *) MCFGPIO_PCLRR_CS, + }, + { + .gpio_chip = { + .label = "PWM", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 58, + .ngpio = 4, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_PWM, + .podr = (void __iomem *) MCFGPIO_PODR_PWM, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_PWM, + .setr = (void __iomem *) MCFGPIO_PPDSDR_PWM, + .clrr = (void __iomem *) MCFGPIO_PCLRR_PWM, + }, + { + .gpio_chip = { + .label = "FECI2C", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 64, + .ngpio = 4, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_FECI2C, + .podr = (void __iomem *) MCFGPIO_PODR_FECI2C, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_FECI2C, + .setr = (void __iomem *) MCFGPIO_PPDSDR_FECI2C, + .clrr = (void __iomem *) MCFGPIO_PCLRR_FECI2C, + }, + { + .gpio_chip = { + .label = "UART", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 72, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_UART, + .podr = (void __iomem *) MCFGPIO_PODR_UART, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_UART, + .setr = (void __iomem *) MCFGPIO_PPDSDR_UART, + .clrr = (void __iomem *) MCFGPIO_PCLRR_UART, + }, + { + .gpio_chip = { + .label = "QSPI", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 80, + .ngpio = 6, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_QSPI, + .podr = (void __iomem *) MCFGPIO_PODR_QSPI, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_QSPI, + .setr = (void __iomem *) MCFGPIO_PPDSDR_QSPI, + .clrr = (void __iomem *) MCFGPIO_PCLRR_QSPI, + }, + { + .gpio_chip = { + .label = "TIMER", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 88, + .ngpio = 4, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_TIMER, + .podr = (void __iomem *) MCFGPIO_PODR_TIMER, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_TIMER, + .setr = (void __iomem *) MCFGPIO_PPDSDR_TIMER, + .clrr = (void __iomem *) MCFGPIO_PCLRR_TIMER, + }, + { + .gpio_chip = { + .label = "LCDDATAH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 96, + .ngpio = 2, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_LCDDATAH, + .podr = (void __iomem *) MCFGPIO_PODR_LCDDATAH, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_LCDDATAH, + .setr = (void __iomem *) MCFGPIO_PPDSDR_LCDDATAH, + .clrr = (void __iomem *) MCFGPIO_PCLRR_LCDDATAH, + }, + { + .gpio_chip = { + .label = "LCDDATAM", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 104, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_LCDDATAM, + .podr = (void __iomem *) MCFGPIO_PODR_LCDDATAM, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_LCDDATAM, + .setr = (void __iomem *) MCFGPIO_PPDSDR_LCDDATAM, + .clrr = (void __iomem *) MCFGPIO_PCLRR_LCDDATAM, + }, + { + .gpio_chip = { + .label = "LCDDATAL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 112, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_LCDDATAL, + .podr = (void __iomem *) MCFGPIO_PODR_LCDDATAL, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_LCDDATAL, + .setr = (void __iomem *) MCFGPIO_PPDSDR_LCDDATAL, + .clrr = (void __iomem *) MCFGPIO_PCLRR_LCDDATAL, + }, + { + .gpio_chip = { + .label = "LCDCTLH", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 120, + .ngpio = 1, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_LCDCTLH, + .podr = (void __iomem *) MCFGPIO_PODR_LCDCTLH, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_LCDCTLH, + .setr = (void __iomem *) MCFGPIO_PPDSDR_LCDCTLH, + .clrr = (void __iomem *) MCFGPIO_PCLRR_LCDCTLH, + }, + { + .gpio_chip = { + .label = "LCDCTLL", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value_fast, + .base = 128, + .ngpio = 8, + }, + .pddr = (void __iomem *) MCFGPIO_PDDR_LCDCTLL, + .podr = (void __iomem *) MCFGPIO_PODR_LCDCTLL, + .ppdr = (void __iomem *) MCFGPIO_PPDSDR_LCDCTLL, + .setr = (void __iomem *) MCFGPIO_PPDSDR_LCDCTLL, + .clrr = (void __iomem *) MCFGPIO_PCLRR_LCDCTLL, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/trunk/arch/m68k/platform/5407/Makefile b/trunk/arch/m68k/platform/5407/Makefile new file mode 100644 index 000000000000..e83fe148eddc --- /dev/null +++ b/trunk/arch/m68k/platform/5407/Makefile @@ -0,0 +1,18 @@ +# +# Makefile for the m68knommu linux kernel. +# + +# +# If you want to play with the HW breakpoints then you will +# need to add define this, which will give you a stack backtrace +# on the console port whenever a DBG interrupt occurs. You have to +# set up you HW breakpoints to trigger a DBG interrupt: +# +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT +# + +asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 + +obj-y := config.o gpio.o + diff --git a/trunk/arch/m68k/platform/coldfire/m5407.c b/trunk/arch/m68k/platform/5407/config.c similarity index 77% rename from trunk/arch/m68k/platform/coldfire/m5407.c rename to trunk/arch/m68k/platform/5407/config.c index faa6680b3404..bb6c746ae819 100644 --- a/trunk/arch/m68k/platform/coldfire/m5407.c +++ b/trunk/arch/m68k/platform/5407/config.c @@ -16,15 +16,6 @@ #include #include #include -#include - -/***************************************************************************/ - -struct mcf_gpio_chip mcf_gpio_chips[] = { - MCFGPS(PP, 0, 16, MCFSIM_PADDR, MCFSIM_PADAT, MCFSIM_PADAT), -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); /***************************************************************************/ diff --git a/trunk/arch/m68k/platform/5407/gpio.c b/trunk/arch/m68k/platform/5407/gpio.c new file mode 100644 index 000000000000..5850612b4a38 --- /dev/null +++ b/trunk/arch/m68k/platform/5407/gpio.c @@ -0,0 +1,49 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +*/ + +#include +#include + +#include +#include +#include + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "PP", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .ngpio = 16, + }, + .pddr = (void __iomem *) MCFSIM_PADDR, + .podr = (void __iomem *) MCFSIM_PADAT, + .ppdr = (void __iomem *) MCFSIM_PADAT, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/trunk/arch/m68k/platform/54xx/Makefile b/trunk/arch/m68k/platform/54xx/Makefile new file mode 100644 index 000000000000..6cfd090ec3cd --- /dev/null +++ b/trunk/arch/m68k/platform/54xx/Makefile @@ -0,0 +1,19 @@ +# +# Makefile for the m68knommu linux kernel. +# + +# +# If you want to play with the HW breakpoints then you will +# need to add define this, which will give you a stack backtrace +# on the console port whenever a DBG interrupt occurs. You have to +# set up you HW breakpoints to trigger a DBG interrupt: +# +# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT +# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT +# + +asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 + +obj-y := config.o +obj-$(CONFIG_FIREBEE) += firebee.o + diff --git a/trunk/arch/m68k/platform/coldfire/m54xx.c b/trunk/arch/m68k/platform/54xx/config.c similarity index 93% rename from trunk/arch/m68k/platform/coldfire/m54xx.c rename to trunk/arch/m68k/platform/54xx/config.c index 20672dadb252..2081c6cbb3de 100644 --- a/trunk/arch/m68k/platform/coldfire/m54xx.c +++ b/trunk/arch/m68k/platform/54xx/config.c @@ -21,19 +21,12 @@ #include #include #include -#include #ifdef CONFIG_MMU #include #endif /***************************************************************************/ -struct mcf_gpio_chip mcf_gpio_chips[] = { }; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); - -/***************************************************************************/ - static void __init m54xx_uarts_init(void) { /* enable io pins */ diff --git a/trunk/arch/m68k/platform/coldfire/firebee.c b/trunk/arch/m68k/platform/54xx/firebee.c similarity index 100% rename from trunk/arch/m68k/platform/coldfire/firebee.c rename to trunk/arch/m68k/platform/54xx/firebee.c diff --git a/trunk/arch/m68k/platform/coldfire/Makefile b/trunk/arch/m68k/platform/coldfire/Makefile index 76d389d9a84e..a0815c61dec1 100644 --- a/trunk/arch/m68k/platform/coldfire/Makefile +++ b/trunk/arch/m68k/platform/coldfire/Makefile @@ -15,22 +15,18 @@ asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 obj-$(CONFIG_COLDFIRE) += cache.o clk.o device.o dma.o entry.o vectors.o -obj-$(CONFIG_M5206) += m5206.o timers.o intc.o reset.o -obj-$(CONFIG_M5206e) += m5206.o timers.o intc.o reset.o -obj-$(CONFIG_M520x) += m520x.o pit.o intc-simr.o reset.o -obj-$(CONFIG_M523x) += m523x.o pit.o dma_timer.o intc-2.o reset.o -obj-$(CONFIG_M5249) += m5249.o timers.o intc.o intc-5249.o reset.o -obj-$(CONFIG_M527x) += m527x.o pit.o intc-2.o reset.o -obj-$(CONFIG_M5272) += m5272.o intc-5272.o timers.o -obj-$(CONFIG_M528x) += m528x.o pit.o intc-2.o reset.o -obj-$(CONFIG_M5307) += m5307.o timers.o intc.o reset.o -obj-$(CONFIG_M532x) += m532x.o timers.o intc-simr.o reset.o -obj-$(CONFIG_M5407) += m5407.o timers.o intc.o reset.o -obj-$(CONFIG_M54xx) += m54xx.o sltimers.o intc-2.o - -obj-$(CONFIG_NETtel) += nettel.o -obj-$(CONFIG_CLEOPATRA) += nettel.o -obj-$(CONFIG_FIREBEE) += firebee.o +obj-$(CONFIG_M5206) += timers.o intc.o reset.o +obj-$(CONFIG_M5206e) += timers.o intc.o reset.o +obj-$(CONFIG_M520x) += pit.o intc-simr.o reset.o +obj-$(CONFIG_M523x) += pit.o dma_timer.o intc-2.o reset.o +obj-$(CONFIG_M5249) += timers.o intc.o reset.o +obj-$(CONFIG_M527x) += pit.o intc-2.o reset.o +obj-$(CONFIG_M5272) += timers.o +obj-$(CONFIG_M528x) += pit.o intc-2.o reset.o +obj-$(CONFIG_M5307) += timers.o intc.o reset.o +obj-$(CONFIG_M532x) += timers.o intc-simr.o reset.o +obj-$(CONFIG_M5407) += timers.o intc.o reset.o +obj-$(CONFIG_M54xx) += sltimers.o intc-2.o obj-y += pinmux.o gpio.o extra-y := head.o diff --git a/trunk/arch/m68k/platform/coldfire/device.c b/trunk/arch/m68k/platform/coldfire/device.c index 3aa77ddea89d..7af97362b95c 100644 --- a/trunk/arch/m68k/platform/coldfire/device.c +++ b/trunk/arch/m68k/platform/coldfire/device.c @@ -121,7 +121,7 @@ static struct platform_device mcf_fec1 = { #endif /* MCFFEC_BASE1 */ #endif /* CONFIG_FEC */ -#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) +#ifdef CONFIG_SPI_COLDFIRE_QSPI /* * The ColdFire QSPI module is an SPI protocol hardware block used * on a number of different ColdFire CPUs. @@ -274,7 +274,7 @@ static struct platform_device mcf_qspi = { .resource = mcf_qspi_resources, .dev.platform_data = &mcf_qspi_data, }; -#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */ +#endif /* CONFIG_SPI_COLDFIRE_QSPI */ static struct platform_device *mcf_devices[] __initdata = { &mcf_uart, @@ -284,7 +284,7 @@ static struct platform_device *mcf_devices[] __initdata = { &mcf_fec1, #endif #endif -#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) +#ifdef CONFIG_SPI_COLDFIRE_QSPI &mcf_qspi, #endif }; diff --git a/trunk/arch/m68k/platform/coldfire/gpio.c b/trunk/arch/m68k/platform/coldfire/gpio.c index 4c8c42450a4e..292a1a5a2d7c 100644 --- a/trunk/arch/m68k/platform/coldfire/gpio.c +++ b/trunk/arch/m68k/platform/coldfire/gpio.c @@ -122,10 +122,6 @@ struct bus_type mcf_gpio_subsys = { static int __init mcf_gpio_sysinit(void) { - unsigned int i = 0; - - while (i < mcf_gpio_chips_size) - gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); return subsys_system_register(&mcf_gpio_subsys, NULL); } diff --git a/trunk/arch/microblaze/kernel/Makefile b/trunk/arch/microblaze/kernel/Makefile index 928c950fc14c..494b63b72dd7 100644 --- a/trunk/arch/microblaze/kernel/Makefile +++ b/trunk/arch/microblaze/kernel/Makefile @@ -16,7 +16,7 @@ endif extra-y := head.o vmlinux.lds obj-y += dma.o exceptions.o \ - hw_exception_handler.o intc.o irq.o \ + hw_exception_handler.o init_task.o intc.o irq.o \ process.o prom.o prom_parse.o ptrace.o \ reset.o setup.o signal.o sys_microblaze.o timer.o traps.o unwind.o diff --git a/trunk/arch/microblaze/kernel/init_task.c b/trunk/arch/microblaze/kernel/init_task.c new file mode 100644 index 000000000000..b5d711f94ff8 --- /dev/null +++ b/trunk/arch/microblaze/kernel/init_task.c @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2009 Michal Simek + * Copyright (C) 2009 PetaLogix + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include + +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); + +union thread_union init_thread_union __init_task_data = + { INIT_THREAD_INFO(init_task) }; + +struct task_struct init_task = INIT_TASK(init_task); +EXPORT_SYMBOL(init_task); diff --git a/trunk/arch/microblaze/kernel/ptrace.c b/trunk/arch/microblaze/kernel/ptrace.c index ab1b9db661f3..6eb2aa927d89 100644 --- a/trunk/arch/microblaze/kernel/ptrace.c +++ b/trunk/arch/microblaze/kernel/ptrace.c @@ -136,7 +136,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) { long ret = 0; - secure_computing_strict(regs->r12); + secure_computing(regs->r12); if (test_thread_flag(TIF_SYSCALL_TRACE) && tracehook_report_syscall_entry(regs)) diff --git a/trunk/arch/microblaze/pci/pci-common.c b/trunk/arch/microblaze/pci/pci-common.c index ed22bfc5db14..d10403dadd2b 100644 --- a/trunk/arch/microblaze/pci/pci-common.c +++ b/trunk/arch/microblaze/pci/pci-common.c @@ -1422,7 +1422,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, struct list_head *resources) { - unsigned long io_offset; struct resource *res; int i; diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 186fc8cf9ee0..ce30e2f91d77 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -29,7 +29,6 @@ config MIPS select HAVE_MEMBLOCK select HAVE_MEMBLOCK_NODE_MAP select ARCH_DISCARD_MEMBLOCK - select GENERIC_SMP_IDLE_THREAD menu "Machine selection" diff --git a/trunk/arch/mips/Makefile b/trunk/arch/mips/Makefile index 76017c25a9e6..4fedf5a51d96 100644 --- a/trunk/arch/mips/Makefile +++ b/trunk/arch/mips/Makefile @@ -235,7 +235,7 @@ endif OBJCOPYFLAGS += --remove-section=.reginfo -head-y := arch/mips/kernel/head.o +head-y := arch/mips/kernel/head.o arch/mips/kernel/init_task.o libs-y += arch/mips/lib/ diff --git a/trunk/arch/mips/configs/mtx1_defconfig b/trunk/arch/mips/configs/mtx1_defconfig index 46c61edcdf7b..807c97eed8a8 100644 --- a/trunk/arch/mips/configs/mtx1_defconfig +++ b/trunk/arch/mips/configs/mtx1_defconfig @@ -346,8 +346,11 @@ CONFIG_CHELSIO_T1=m CONFIG_IXGB=m CONFIG_S2IO=m CONFIG_MYRI10GE=m +CONFIG_TR=y CONFIG_IBMOL=m CONFIG_IBMLS=m +CONFIG_3C359=m +CONFIG_TMS380TR=m CONFIG_TMSPCI=m CONFIG_ABYSS=m CONFIG_USB_CATC=m @@ -373,6 +376,7 @@ CONFIG_PCMCIA_SMC91C92=m CONFIG_PCMCIA_XIRC2PS=m CONFIG_PCMCIA_AXNET=m CONFIG_ARCNET_COM20020_CS=m +CONFIG_PCMCIA_IBMTR=m CONFIG_WAN=y CONFIG_LANMEDIA=m CONFIG_HDLC=m diff --git a/trunk/arch/mips/include/asm/thread_info.h b/trunk/arch/mips/include/asm/thread_info.h index e2eca7d10598..0d85d8e440c5 100644 --- a/trunk/arch/mips/include/asm/thread_info.h +++ b/trunk/arch/mips/include/asm/thread_info.h @@ -85,6 +85,18 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define STACK_WARN (THREAD_SIZE / 8) +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + +#ifdef CONFIG_DEBUG_STACK_USAGE +#define alloc_thread_info_node(tsk, node) \ + kzalloc_node(THREAD_SIZE, GFP_KERNEL, node) +#else +#define alloc_thread_info_node(tsk, node) \ + kmalloc_node(THREAD_SIZE, GFP_KERNEL, node) +#endif + +#define free_thread_info(info) kfree(info) + #endif /* !__ASSEMBLY__ */ #define PREEMPT_ACTIVE 0x10000000 diff --git a/trunk/arch/mips/kernel/Makefile b/trunk/arch/mips/kernel/Makefile index fdaf65e1a99d..0c6877ea9004 100644 --- a/trunk/arch/mips/kernel/Makefile +++ b/trunk/arch/mips/kernel/Makefile @@ -2,7 +2,7 @@ # Makefile for the Linux/MIPS kernel. # -extra-y := head.o vmlinux.lds +extra-y := head.o init_task.o vmlinux.lds obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ ptrace.o reset.o setup.o signal.o syscall.o \ diff --git a/trunk/arch/mips/kernel/init_task.c b/trunk/arch/mips/kernel/init_task.c new file mode 100644 index 000000000000..5f9a76263c9a --- /dev/null +++ b/trunk/arch/mips/kernel/init_task.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +/* + * Initial thread structure. + * + * We need to make sure that this is 8192-byte aligned due to the + * way process stacks are handled. This is done by making sure + * the linker maps this in the .text segment right after head.S, + * and making head.S ensure the proper alignment. + * + * The things we do for performance.. + */ +union thread_union init_thread_union __init_task_data + __attribute__((__aligned__(THREAD_SIZE))) = + { INIT_THREAD_INFO(init_task) }; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); + +EXPORT_SYMBOL(init_task); diff --git a/trunk/arch/mips/kernel/ptrace.c b/trunk/arch/mips/kernel/ptrace.c index 4812c6d916e4..7c24c2973c6d 100644 --- a/trunk/arch/mips/kernel/ptrace.c +++ b/trunk/arch/mips/kernel/ptrace.c @@ -535,7 +535,7 @@ static inline int audit_arch(void) asmlinkage void syscall_trace_enter(struct pt_regs *regs) { /* do the secure computing check first */ - secure_computing_strict(regs->regs[2]); + secure_computing(regs->regs[2]); if (!(current->ptrace & PT_PTRACED)) goto out; diff --git a/trunk/arch/mips/kernel/smp.c b/trunk/arch/mips/kernel/smp.c index 71a95f55a649..ba9376bf52a1 100644 --- a/trunk/arch/mips/kernel/smp.c +++ b/trunk/arch/mips/kernel/smp.c @@ -186,9 +186,61 @@ void __devinit smp_prepare_boot_cpu(void) cpu_set(0, cpu_callin_map); } -int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) +/* + * Called once for each "cpu_possible(cpu)". Needs to spin up the cpu + * and keep control until "cpu_online(cpu)" is set. Note: cpu is + * physical, not logical. + */ +static struct task_struct *cpu_idle_thread[NR_CPUS]; + +struct create_idle { + struct work_struct work; + struct task_struct *idle; + struct completion done; + int cpu; +}; + +static void __cpuinit do_fork_idle(struct work_struct *work) +{ + struct create_idle *c_idle = + container_of(work, struct create_idle, work); + + c_idle->idle = fork_idle(c_idle->cpu); + complete(&c_idle->done); +} + +int __cpuinit __cpu_up(unsigned int cpu) { - mp_ops->boot_secondary(cpu, tidle); + struct task_struct *idle; + + /* + * Processor goes to start_secondary(), sets online flag + * The following code is purely to make sure + * Linux can schedule processes on this slave. + */ + if (!cpu_idle_thread[cpu]) { + /* + * Schedule work item to avoid forking user task + * Ported from arch/x86/kernel/smpboot.c + */ + struct create_idle c_idle = { + .cpu = cpu, + .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done), + }; + + INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle); + schedule_work(&c_idle.work); + wait_for_completion(&c_idle.done); + idle = cpu_idle_thread[cpu] = c_idle.idle; + + if (IS_ERR(idle)) + panic(KERN_ERR "Fork failed for CPU %d", cpu); + } else { + idle = cpu_idle_thread[cpu]; + init_idle(idle, cpu); + } + + mp_ops->boot_secondary(cpu, idle); /* * Trust is futile. We should really have timeouts ... diff --git a/trunk/arch/mn10300/Makefile b/trunk/arch/mn10300/Makefile index 33188b6e81e4..7120282bf0d8 100644 --- a/trunk/arch/mn10300/Makefile +++ b/trunk/arch/mn10300/Makefile @@ -51,7 +51,7 @@ UNIT := asb2364 endif -head-y := arch/mn10300/kernel/head.o +head-y := arch/mn10300/kernel/head.o arch/mn10300/kernel/init_task.o core-y += arch/mn10300/kernel/ arch/mn10300/mm/ diff --git a/trunk/arch/mn10300/include/asm/thread_info.h b/trunk/arch/mn10300/include/asm/thread_info.h index 08251d6f6b11..28cf52100baa 100644 --- a/trunk/arch/mn10300/include/asm/thread_info.h +++ b/trunk/arch/mn10300/include/asm/thread_info.h @@ -20,10 +20,8 @@ #ifdef CONFIG_4KSTACKS #define THREAD_SIZE (4096) -#define THREAD_SIZE_ORDER (0) #else #define THREAD_SIZE (8192) -#define THREAD_SIZE_ORDER (1) #endif #define STACK_WARN (THREAD_SIZE / 8) @@ -122,8 +120,21 @@ static inline unsigned long current_stack_pointer(void) return sp; } +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + +/* thread information allocation */ +#ifdef CONFIG_DEBUG_STACK_USAGE +#define alloc_thread_info_node(tsk, node) \ + kzalloc_node(THREAD_SIZE, GFP_KERNEL, node) +#else +#define alloc_thread_info_node(tsk, node) \ + kmalloc_node(THREAD_SIZE, GFP_KERNEL, node) +#endif + #ifndef CONFIG_KGDB -void arch_release_thread_info(struct thread_info *ti) +#define free_thread_info(ti) kfree((ti)) +#else +extern void free_thread_info(struct thread_info *); #endif #define get_thread_info(ti) get_task_struct((ti)->task) #define put_thread_info(ti) put_task_struct((ti)->task) diff --git a/trunk/arch/mn10300/kernel/Makefile b/trunk/arch/mn10300/kernel/Makefile index d06749173d63..47ed30fe8178 100644 --- a/trunk/arch/mn10300/kernel/Makefile +++ b/trunk/arch/mn10300/kernel/Makefile @@ -1,7 +1,7 @@ # # Makefile for the MN10300-specific core kernel code # -extra-y := head.o vmlinux.lds +extra-y := head.o init_task.o vmlinux.lds fpu-obj-y := fpu-nofpu.o fpu-nofpu-low.o fpu-obj-$(CONFIG_FPU) := fpu.o fpu-low.o diff --git a/trunk/arch/mn10300/kernel/init_task.c b/trunk/arch/mn10300/kernel/init_task.c new file mode 100644 index 000000000000..a481b043bea7 --- /dev/null +++ b/trunk/arch/mn10300/kernel/init_task.c @@ -0,0 +1,39 @@ +/* MN10300 Initial task definitions + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +/* + * Initial thread structure. + * + * We need to make sure that this is THREAD_SIZE aligned due to the + * way process stacks are handled. This is done by having a special + * "init_task" linker map entry.. + */ +union thread_union init_thread_union __init_task_data = + { INIT_THREAD_INFO(init_task) }; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); +EXPORT_SYMBOL(init_task); diff --git a/trunk/arch/mn10300/kernel/kgdb.c b/trunk/arch/mn10300/kernel/kgdb.c index 99770823451a..f6c981db2a36 100644 --- a/trunk/arch/mn10300/kernel/kgdb.c +++ b/trunk/arch/mn10300/kernel/kgdb.c @@ -397,7 +397,7 @@ static bool kgdb_arch_undo_singlestep(struct pt_regs *regs) * single-step state is cleared. At this point the breakpoints should have * been removed by __switch_to(). */ -void arch_release_thread_info(struct thread_info *ti) +void free_thread_info(struct thread_info *ti) { if (kgdb_sstep_thread == ti) { kgdb_sstep_thread = NULL; @@ -407,6 +407,7 @@ void arch_release_thread_info(struct thread_info *ti) * so force immediate reentry */ kgdb_breakpoint(); } + kfree(ti); } /* diff --git a/trunk/arch/mn10300/kernel/smp.c b/trunk/arch/mn10300/kernel/smp.c index 090d35d36973..910dddf65e44 100644 --- a/trunk/arch/mn10300/kernel/smp.c +++ b/trunk/arch/mn10300/kernel/smp.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -39,6 +38,7 @@ #include "internal.h" #ifdef CONFIG_HOTPLUG_CPU +#include #include static unsigned long sleep_mode[NR_CPUS]; @@ -874,13 +874,10 @@ static void __init smp_online(void) cpu = smp_processor_id(); - notify_cpu_starting(cpu); + local_irq_enable(); - ipi_call_lock(); set_cpu_online(cpu, true); - ipi_call_unlock(); - - local_irq_enable(); + smp_wmb(); } /** @@ -924,7 +921,7 @@ void initialize_secondary(void) * __cpu_up - Set smp_commenced_mask for the nominated CPU * @cpu: The target CPU. */ -int __devinit __cpu_up(unsigned int cpu, struct task_struct *tidle) +int __devinit __cpu_up(unsigned int cpu) { int timeout; diff --git a/trunk/arch/openrisc/Kconfig b/trunk/arch/openrisc/Kconfig index 7589051e79e0..a4787197d8fe 100644 --- a/trunk/arch/openrisc/Kconfig +++ b/trunk/arch/openrisc/Kconfig @@ -7,7 +7,6 @@ config OPENRISC def_bool y select OF select OF_EARLY_FLATTREE - select IRQ_DOMAIN select HAVE_MEMBLOCK select ARCH_WANT_OPTIONAL_GPIOLIB select HAVE_ARCH_TRACEHOOK diff --git a/trunk/arch/openrisc/Makefile b/trunk/arch/openrisc/Makefile index 966886c8daf5..158ae4c0dc6c 100644 --- a/trunk/arch/openrisc/Makefile +++ b/trunk/arch/openrisc/Makefile @@ -38,7 +38,7 @@ else KBUILD_CFLAGS += $(call cc-option,-msoft-div) endif -head-y := arch/openrisc/kernel/head.o +head-y := arch/openrisc/kernel/head.o arch/openrisc/kernel/init_task.o core-y += arch/openrisc/lib/ \ arch/openrisc/kernel/ \ diff --git a/trunk/arch/openrisc/include/asm/Kbuild b/trunk/arch/openrisc/include/asm/Kbuild index c936483bc8e2..dcea5a0308ae 100644 --- a/trunk/arch/openrisc/include/asm/Kbuild +++ b/trunk/arch/openrisc/include/asm/Kbuild @@ -1,7 +1,6 @@ include include/asm-generic/Kbuild.asm -header-y += elf.h -header-y += ucontext.h +header-y += spr_defs.h generic-y += atomic.h generic-y += auxvec.h diff --git a/trunk/arch/openrisc/include/asm/dma-mapping.h b/trunk/arch/openrisc/include/asm/dma-mapping.h index fab8628e1b6e..b206ba4608b2 100644 --- a/trunk/arch/openrisc/include/asm/dma-mapping.h +++ b/trunk/arch/openrisc/include/asm/dma-mapping.h @@ -20,71 +20,150 @@ /* * See Documentation/DMA-API-HOWTO.txt and * Documentation/DMA-API.txt for documentation. + * + * This file is written with the intention of eventually moving over + * to largely using asm-generic/dma-mapping-common.h in its place. */ #include #include #include -#include #define DMA_ERROR_CODE (~(dma_addr_t)0x0) -extern struct dma_map_ops or1k_dma_map_ops; - -static inline struct dma_map_ops *get_dma_ops(struct device *dev) -{ - return &or1k_dma_map_ops; -} - -#include - -#define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL) -static inline void *dma_alloc_attrs(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp, - struct dma_attrs *attrs) +#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) +#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) + +void *or1k_dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag); +void or1k_dma_free_coherent(struct device *dev, size_t size, void *vaddr, + dma_addr_t dma_handle); +dma_addr_t or1k_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction dir, + struct dma_attrs *attrs); +void or1k_unmap_page(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs); +int or1k_map_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs); +void or1k_unmap_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs); +void or1k_sync_single_for_cpu(struct device *dev, + dma_addr_t dma_handle, size_t size, + enum dma_data_direction dir); +void or1k_sync_single_for_device(struct device *dev, + dma_addr_t dma_handle, size_t size, + enum dma_data_direction dir); + +static inline void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag) { - struct dma_map_ops *ops = get_dma_ops(dev); void *memory; - memory = ops->alloc(dev, size, dma_handle, gfp, attrs); + memory = or1k_dma_alloc_coherent(dev, size, dma_handle, flag); debug_dma_alloc_coherent(dev, size, *dma_handle, memory); - return memory; } -#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) +static inline void dma_free_coherent(struct device *dev, size_t size, + void *cpu_addr, dma_addr_t dma_handle) +{ + debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); + or1k_dma_free_coherent(dev, size, cpu_addr, dma_handle); +} -static inline void dma_free_attrs(struct device *dev, size_t size, - void *cpu_addr, dma_addr_t dma_handle, - struct dma_attrs *attrs) +static inline dma_addr_t dma_map_single(struct device *dev, void *ptr, + size_t size, + enum dma_data_direction dir) { - struct dma_map_ops *ops = get_dma_ops(dev); + dma_addr_t addr; + + kmemcheck_mark_initialized(ptr, size); + BUG_ON(!valid_dma_direction(dir)); + addr = or1k_map_page(dev, virt_to_page(ptr), + (unsigned long)ptr & ~PAGE_MASK, size, + dir, NULL); + debug_dma_map_page(dev, virt_to_page(ptr), + (unsigned long)ptr & ~PAGE_MASK, size, + dir, addr, true); + return addr; +} - debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); +static inline void dma_unmap_single(struct device *dev, dma_addr_t addr, + size_t size, + enum dma_data_direction dir) +{ + BUG_ON(!valid_dma_direction(dir)); + or1k_unmap_page(dev, addr, size, dir, NULL); + debug_dma_unmap_page(dev, addr, size, dir, true); +} + +static inline int dma_map_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir) +{ + int i, ents; + struct scatterlist *s; + + for_each_sg(sg, s, nents, i) + kmemcheck_mark_initialized(sg_virt(s), s->length); + BUG_ON(!valid_dma_direction(dir)); + ents = or1k_map_sg(dev, sg, nents, dir, NULL); + debug_dma_map_sg(dev, sg, nents, ents, dir); + + return ents; +} - ops->free(dev, size, cpu_addr, dma_handle, attrs); +static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir) +{ + BUG_ON(!valid_dma_direction(dir)); + debug_dma_unmap_sg(dev, sg, nents, dir); + or1k_unmap_sg(dev, sg, nents, dir, NULL); } -static inline void *dma_alloc_noncoherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp) +static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, + size_t offset, size_t size, + enum dma_data_direction dir) { - struct dma_attrs attrs; + dma_addr_t addr; - dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs); + kmemcheck_mark_initialized(page_address(page) + offset, size); + BUG_ON(!valid_dma_direction(dir)); + addr = or1k_map_page(dev, page, offset, size, dir, NULL); + debug_dma_map_page(dev, page, offset, size, dir, addr, false); - return dma_alloc_attrs(dev, size, dma_handle, gfp, &attrs); + return addr; } -static inline void dma_free_noncoherent(struct device *dev, size_t size, - void *cpu_addr, dma_addr_t dma_handle) +static inline void dma_unmap_page(struct device *dev, dma_addr_t addr, + size_t size, enum dma_data_direction dir) { - struct dma_attrs attrs; + BUG_ON(!valid_dma_direction(dir)); + or1k_unmap_page(dev, addr, size, dir, NULL); + debug_dma_unmap_page(dev, addr, size, dir, true); +} - dma_set_attr(DMA_ATTR_NON_CONSISTENT, &attrs); +static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr, + size_t size, + enum dma_data_direction dir) +{ + BUG_ON(!valid_dma_direction(dir)); + or1k_sync_single_for_cpu(dev, addr, size, dir); + debug_dma_sync_single_for_cpu(dev, addr, size, dir); +} - dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs); +static inline void dma_sync_single_for_device(struct device *dev, + dma_addr_t addr, size_t size, + enum dma_data_direction dir) +{ + BUG_ON(!valid_dma_direction(dir)); + or1k_sync_single_for_device(dev, addr, size, dir); + debug_dma_sync_single_for_device(dev, addr, size, dir); } static inline int dma_supported(struct device *dev, u64 dma_mask) diff --git a/trunk/arch/openrisc/include/asm/elf.h b/trunk/arch/openrisc/include/asm/elf.h index a8fe2c513070..2ce603bbfdd3 100644 --- a/trunk/arch/openrisc/include/asm/elf.h +++ b/trunk/arch/openrisc/include/asm/elf.h @@ -19,18 +19,12 @@ #ifndef __ASM_OPENRISC_ELF_H #define __ASM_OPENRISC_ELF_H -/* - * This files is partially exported to userspace. This allows us to keep - * the ELF bits in one place which should assist in keeping the kernel and - * userspace in sync. - */ - /* * ELF register definitions.. */ +#include +#include -/* for struct user_regs_struct definition */ -#include /* The OR1K relocation types... not all relevant for module loader */ #define R_OR32_NONE 0 @@ -68,8 +62,6 @@ typedef unsigned long elf_fpregset_t; #ifdef __KERNEL__ -#include - /* * This is used to ensure we don't load something for the wrong architecture. */ diff --git a/trunk/arch/openrisc/include/asm/ptrace.h b/trunk/arch/openrisc/include/asm/ptrace.h index 8555c0c3d4d7..4651a737591d 100644 --- a/trunk/arch/openrisc/include/asm/ptrace.h +++ b/trunk/arch/openrisc/include/asm/ptrace.h @@ -19,6 +19,8 @@ #ifndef __ASM_OPENRISC_PTRACE_H #define __ASM_OPENRISC_PTRACE_H +#include + #ifndef __ASSEMBLY__ /* * This is the layout of the regset returned by the GETREGSET ptrace call @@ -28,13 +30,13 @@ struct user_regs_struct { unsigned long gpr[32]; unsigned long pc; unsigned long sr; + unsigned long pad1; + unsigned long pad2; }; #endif #ifdef __KERNEL__ -#include - /* * Make kernel PTrace/register structures opaque to userspace... userspace can * access thread state via the regset mechanism. This allows us a bit of diff --git a/trunk/arch/openrisc/kernel/Makefile b/trunk/arch/openrisc/kernel/Makefile index e1ee0fa2bbda..9a4c2706d795 100644 --- a/trunk/arch/openrisc/kernel/Makefile +++ b/trunk/arch/openrisc/kernel/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -extra-y := head.o vmlinux.lds +extra-y := head.o vmlinux.lds init_task.o obj-y := setup.o idle.o or32_ksyms.o process.o dma.o \ traps.o time.o irq.o entry.o ptrace.o signal.o sys_or32.o \ diff --git a/trunk/arch/openrisc/kernel/dma.c b/trunk/arch/openrisc/kernel/dma.c index 0b77ddb1ee07..f1c8ee2895d0 100644 --- a/trunk/arch/openrisc/kernel/dma.c +++ b/trunk/arch/openrisc/kernel/dma.c @@ -21,16 +21,13 @@ #include #include -#include -#include #include #include #include -static int -page_set_nocache(pte_t *pte, unsigned long addr, - unsigned long next, struct mm_walk *walk) +static int page_set_nocache(pte_t *pte, unsigned long addr, + unsigned long next, struct mm_walk *walk) { unsigned long cl; @@ -49,9 +46,8 @@ page_set_nocache(pte_t *pte, unsigned long addr, return 0; } -static int -page_clear_nocache(pte_t *pte, unsigned long addr, - unsigned long next, struct mm_walk *walk) +static int page_clear_nocache(pte_t *pte, unsigned long addr, + unsigned long next, struct mm_walk *walk) { pte_val(*pte) &= ~_PAGE_CI; @@ -71,19 +67,9 @@ page_clear_nocache(pte_t *pte, unsigned long addr, * cache-inhibit bit on those pages, and makes sure that the pages are * flushed out of the cache before they are used. * - * If the NON_CONSISTENT attribute is set, then this function just - * returns "normal", cachable memory. - * - * There are additional flags WEAK_ORDERING and WRITE_COMBINE to take - * into consideration here, too. All current known implementations of - * the OR1K support only strongly ordered memory accesses, so that flag - * is being ignored for now; uncached but write-combined memory is a - * missing feature of the OR1K. */ -static void * -or1k_dma_alloc(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp, - struct dma_attrs *attrs) +void *or1k_dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp) { unsigned long va; void *page; @@ -101,23 +87,20 @@ or1k_dma_alloc(struct device *dev, size_t size, va = (unsigned long)page; - if (!dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs)) { - /* - * We need to iterate through the pages, clearing the dcache for - * them and setting the cache-inhibit bit. - */ - if (walk_page_range(va, va + size, &walk)) { - free_pages_exact(page, size); - return NULL; - } + /* + * We need to iterate through the pages, clearing the dcache for + * them and setting the cache-inhibit bit. + */ + if (walk_page_range(va, va + size, &walk)) { + free_pages_exact(page, size); + return NULL; } return (void *)va; } -static void -or1k_dma_free(struct device *dev, size_t size, void *vaddr, - dma_addr_t dma_handle, struct dma_attrs *attrs) +void or1k_dma_free_coherent(struct device *dev, size_t size, void *vaddr, + dma_addr_t dma_handle) { unsigned long va = (unsigned long)vaddr; struct mm_walk walk = { @@ -125,19 +108,16 @@ or1k_dma_free(struct device *dev, size_t size, void *vaddr, .mm = &init_mm }; - if (!dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs)) { - /* walk_page_range shouldn't be able to fail here */ - WARN_ON(walk_page_range(va, va + size, &walk)); - } + /* walk_page_range shouldn't be able to fail here */ + WARN_ON(walk_page_range(va, va + size, &walk)); free_pages_exact(vaddr, size); } -static dma_addr_t -or1k_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction dir, - struct dma_attrs *attrs) +dma_addr_t or1k_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction dir, + struct dma_attrs *attrs) { unsigned long cl; dma_addr_t addr = page_to_phys(page) + offset; @@ -167,18 +147,16 @@ or1k_map_page(struct device *dev, struct page *page, return addr; } -static void -or1k_unmap_page(struct device *dev, dma_addr_t dma_handle, - size_t size, enum dma_data_direction dir, - struct dma_attrs *attrs) +void or1k_unmap_page(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs) { /* Nothing special to do here... */ } -static int -or1k_map_sg(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction dir, - struct dma_attrs *attrs) +int or1k_map_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs) { struct scatterlist *s; int i; @@ -191,10 +169,9 @@ or1k_map_sg(struct device *dev, struct scatterlist *sg, return nents; } -static void -or1k_unmap_sg(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction dir, - struct dma_attrs *attrs) +void or1k_unmap_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs) { struct scatterlist *s; int i; @@ -204,10 +181,9 @@ or1k_unmap_sg(struct device *dev, struct scatterlist *sg, } } -static void -or1k_sync_single_for_cpu(struct device *dev, - dma_addr_t dma_handle, size_t size, - enum dma_data_direction dir) +void or1k_sync_single_for_cpu(struct device *dev, + dma_addr_t dma_handle, size_t size, + enum dma_data_direction dir) { unsigned long cl; dma_addr_t addr = dma_handle; @@ -217,10 +193,9 @@ or1k_sync_single_for_cpu(struct device *dev, mtspr(SPR_DCBIR, cl); } -static void -or1k_sync_single_for_device(struct device *dev, - dma_addr_t dma_handle, size_t size, - enum dma_data_direction dir) +void or1k_sync_single_for_device(struct device *dev, + dma_addr_t dma_handle, size_t size, + enum dma_data_direction dir) { unsigned long cl; dma_addr_t addr = dma_handle; @@ -230,18 +205,6 @@ or1k_sync_single_for_device(struct device *dev, mtspr(SPR_DCBFR, cl); } -struct dma_map_ops or1k_dma_map_ops = { - .alloc = or1k_dma_alloc, - .free = or1k_dma_free, - .map_page = or1k_map_page, - .unmap_page = or1k_unmap_page, - .map_sg = or1k_map_sg, - .unmap_sg = or1k_unmap_sg, - .sync_single_for_cpu = or1k_sync_single_for_cpu, - .sync_single_for_device = or1k_sync_single_for_device, -}; -EXPORT_SYMBOL(or1k_dma_map_ops); - /* Number of entries preallocated for DMA-API debugging */ #define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16) diff --git a/trunk/arch/openrisc/kernel/entry.S b/trunk/arch/openrisc/kernel/entry.S index ddfcaa828b0e..6e61af8682b8 100644 --- a/trunk/arch/openrisc/kernel/entry.S +++ b/trunk/arch/openrisc/kernel/entry.S @@ -1117,10 +1117,10 @@ ENTRY(sys_rt_sigreturn) ENTRY(sys_or1k_atomic) /* FIXME: This ignores r3 and always does an XCHG */ DISABLE_INTERRUPTS(r17,r19) - l.lwz r29,0(r4) - l.lwz r27,0(r5) - l.sw 0(r4),r27 - l.sw 0(r5),r29 + l.lwz r30,0(r4) + l.lwz r28,0(r5) + l.sw 0(r4),r28 + l.sw 0(r5),r30 ENABLE_INTERRUPTS(r17) l.jr r9 l.or r11,r0,r0 diff --git a/trunk/arch/openrisc/kernel/init_task.c b/trunk/arch/openrisc/kernel/init_task.c new file mode 100644 index 000000000000..ca534082d5f3 --- /dev/null +++ b/trunk/arch/openrisc/kernel/init_task.c @@ -0,0 +1,42 @@ +/* + * OpenRISC init_task.c + * + * Linux architectural port borrowing liberally from similar works of + * others. All original copyrights apply as per the original source + * declaration. + * + * Modifications for the OpenRISC architecture: + * Copyright (C) 2003 Matjaz Breskvar + * Copyright (C) 2010-2011 Jonas Bonn + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); + +/* + * Initial thread structure. + * + * We need to make sure that this is THREAD_SIZE aligned due to the + * way process stacks are handled. This is done by having a special + * "init_task" linker map entry.. + */ +union thread_union init_thread_union __init_task_data = { + INIT_THREAD_INFO(init_task) +}; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); +EXPORT_SYMBOL(init_task); diff --git a/trunk/arch/openrisc/kernel/irq.c b/trunk/arch/openrisc/kernel/irq.c index e935b9d8eee1..4bfead220956 100644 --- a/trunk/arch/openrisc/kernel/irq.c +++ b/trunk/arch/openrisc/kernel/irq.c @@ -14,13 +14,17 @@ * 2 of the License, or (at your option) any later version. */ +#include +#include #include #include #include #include #include +#include +#include #include -#include + #include /* read interrupt enabled status */ @@ -94,7 +98,6 @@ static void or1k_pic_mask_ack(struct irq_data *data) #endif } -#if 0 static int or1k_pic_set_type(struct irq_data *data, unsigned int flow_type) { /* There's nothing to do in the PIC configuration when changing @@ -104,64 +107,43 @@ static int or1k_pic_set_type(struct irq_data *data, unsigned int flow_type) return irq_setup_alt_chip(data, flow_type); } -#endif - -static struct irq_chip or1k_dev = { - .name = "or1k-PIC", - .irq_unmask = or1k_pic_unmask, - .irq_mask = or1k_pic_mask, - .irq_ack = or1k_pic_ack, - .irq_mask_ack = or1k_pic_mask_ack, -}; - -static struct irq_domain *root_domain; static inline int pic_get_irq(int first) { - int hwirq; - - hwirq = ffs(mfspr(SPR_PICSR) >> first); - if (!hwirq) - return NO_IRQ; - else - hwirq = hwirq + first -1; + int irq; - return irq_find_mapping(root_domain, hwirq); -} - - -static int or1k_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) -{ - irq_set_chip_and_handler_name(irq, &or1k_dev, - handle_level_irq, "level"); - irq_set_status_flags(irq, IRQ_LEVEL | IRQ_NOPROBE); + irq = ffs(mfspr(SPR_PICSR) >> first); - return 0; + return irq ? irq + first - 1 : NO_IRQ; } -static const struct irq_domain_ops or1k_irq_domain_ops = { - .xlate = irq_domain_xlate_onecell, - .map = or1k_map, -}; - -/* - * This sets up the IRQ domain for the PIC built in to the OpenRISC - * 1000 CPU. This is the "root" domain as these are the interrupts - * that directly trigger an exception in the CPU. - */ static void __init or1k_irq_init(void) { - struct device_node *intc = NULL; - - /* The interrupt controller device node is mandatory */ - intc = of_find_compatible_node(NULL, NULL, "opencores,or1k-pic"); - BUG_ON(!intc); + struct irq_chip_generic *gc; + struct irq_chip_type *ct; /* Disable all interrupts until explicitly requested */ mtspr(SPR_PICMR, (0UL)); - root_domain = irq_domain_add_linear(intc, 32, - &or1k_irq_domain_ops, NULL); + gc = irq_alloc_generic_chip("or1k-PIC", 1, 0, 0, handle_level_irq); + ct = gc->chip_types; + + ct->chip.irq_unmask = or1k_pic_unmask; + ct->chip.irq_mask = or1k_pic_mask; + ct->chip.irq_ack = or1k_pic_ack; + ct->chip.irq_mask_ack = or1k_pic_mask_ack; + ct->chip.irq_set_type = or1k_pic_set_type; + + /* The OR1K PIC can handle both level and edge trigged + * interrupts in roughly the same manner + */ +#if 0 + /* FIXME: chip.type??? */ + ct->chip.type = IRQ_TYPE_EDGE_BOTH | IRQ_TYPE_LEVEL_MASK; +#endif + + irq_setup_generic_chip(gc, IRQ_MSK(NR_IRQS), 0, + IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); } void __init init_IRQ(void) @@ -182,3 +164,10 @@ void __irq_entry do_IRQ(struct pt_regs *regs) irq_exit(); set_irq_regs(old_regs); } + +unsigned int irq_create_of_mapping(struct device_node *controller, + const u32 *intspec, unsigned int intsize) +{ + return intspec[0]; +} +EXPORT_SYMBOL_GPL(irq_create_of_mapping); diff --git a/trunk/arch/openrisc/mm/fault.c b/trunk/arch/openrisc/mm/fault.c index 40f850e9766c..a5dce82f864b 100644 --- a/trunk/arch/openrisc/mm/fault.c +++ b/trunk/arch/openrisc/mm/fault.c @@ -54,7 +54,6 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long address, struct vm_area_struct *vma; siginfo_t info; int fault; - unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; tsk = current; @@ -106,7 +105,6 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long address, if (in_interrupt() || !mm) goto no_context; -retry: down_read(&mm->mmap_sem); vma = find_vma(mm, address); @@ -145,7 +143,6 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long address, if (write_acc) { if (!(vma->vm_flags & VM_WRITE)) goto bad_area; - flags |= FAULT_FLAG_WRITE; } else { /* not present */ if (!(vma->vm_flags & (VM_READ | VM_EXEC))) @@ -162,11 +159,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long address, * the fault. */ - fault = handle_mm_fault(mm, vma, address, flags); - - if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) - return; - + fault = handle_mm_fault(mm, vma, address, write_acc); if (unlikely(fault & VM_FAULT_ERROR)) { if (fault & VM_FAULT_OOM) goto out_of_memory; @@ -174,24 +167,11 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long address, goto do_sigbus; BUG(); } - - if (flags & FAULT_FLAG_ALLOW_RETRY) { - /*RGD modeled on Cris */ - if (fault & VM_FAULT_MAJOR) - tsk->maj_flt++; - else - tsk->min_flt++; - if (fault & VM_FAULT_RETRY) { - flags &= ~FAULT_FLAG_ALLOW_RETRY; - - /* No need to up_read(&mm->mmap_sem) as we would - * have already released it in __lock_page_or_retry - * in mm/filemap.c. - */ - - goto retry; - } - } + /*RGD modeled on Cris */ + if (fault & VM_FAULT_MAJOR) + tsk->maj_flt++; + else + tsk->min_flt++; up_read(&mm->mmap_sem); return; diff --git a/trunk/arch/parisc/Kconfig b/trunk/arch/parisc/Kconfig index ddb8b24b823d..242a1b7ac759 100644 --- a/trunk/arch/parisc/Kconfig +++ b/trunk/arch/parisc/Kconfig @@ -17,7 +17,6 @@ config PARISC select GENERIC_PCI_IOMAP select IRQ_PER_CPU select ARCH_HAVE_NMI_SAFE_CMPXCHG - select GENERIC_SMP_IDLE_THREAD help The PA-RISC microprocessor is designed by Hewlett-Packard and used diff --git a/trunk/arch/parisc/Makefile b/trunk/arch/parisc/Makefile index dbc3850b1d0d..19ab7b2ea1cd 100644 --- a/trunk/arch/parisc/Makefile +++ b/trunk/arch/parisc/Makefile @@ -75,7 +75,7 @@ head-y := arch/parisc/kernel/head.o KBUILD_CFLAGS += $(cflags-y) -kernel-y := mm/ kernel/ math-emu/ +kernel-y := mm/ kernel/ math-emu/ kernel/init_task.o kernel-$(CONFIG_HPUX) += hpux/ core-y += $(addprefix arch/parisc/, $(kernel-y)) diff --git a/trunk/arch/parisc/include/asm/hardware.h b/trunk/arch/parisc/include/asm/hardware.h index d1d864b81bae..4e9626836bab 100644 --- a/trunk/arch/parisc/include/asm/hardware.h +++ b/trunk/arch/parisc/include/asm/hardware.h @@ -2,6 +2,7 @@ #define _PARISC_HARDWARE_H #include +#include #define HWTYPE_ANY_ID PA_HWTYPE_ANY_ID #define HVERSION_ANY_ID PA_HVERSION_ANY_ID @@ -94,14 +95,12 @@ struct bc_module { #define HPHW_MC 15 #define HPHW_FAULTY 31 -struct parisc_device_id; /* hardware.c: */ extern const char *parisc_hardware_description(struct parisc_device_id *id); extern enum cpu_type parisc_get_cpu_type(unsigned long hversion); struct pci_dev; -struct hardware_path; /* drivers.c: */ extern struct parisc_device *alloc_pa_dev(unsigned long hpa, diff --git a/trunk/arch/parisc/include/asm/page.h b/trunk/arch/parisc/include/asm/page.h index 4e0e7dbf0f3f..a84cc1f925f6 100644 --- a/trunk/arch/parisc/include/asm/page.h +++ b/trunk/arch/parisc/include/asm/page.h @@ -160,11 +160,5 @@ extern int npmem_ranges; #include #include -#include - -#define PAGE0 ((struct zeropage *)__PAGE_OFFSET) - -/* DEFINITION OF THE ZERO-PAGE (PAG0) */ -/* based on work by Jason Eckhardt (jason@equator.com) */ #endif /* _PARISC_PAGE_H */ diff --git a/trunk/arch/parisc/include/asm/pdc.h b/trunk/arch/parisc/include/asm/pdc.h index 7f0f2d23059d..4ca510b3c6f8 100644 --- a/trunk/arch/parisc/include/asm/pdc.h +++ b/trunk/arch/parisc/include/asm/pdc.h @@ -343,6 +343,8 @@ #ifdef __KERNEL__ +#include /* for __PAGE_OFFSET */ + extern int pdc_type; /* Values for pdc_type */ @@ -675,6 +677,11 @@ static inline char * os_id_to_string(u16 os_id) { #endif /* __KERNEL__ */ +#define PAGE0 ((struct zeropage *)__PAGE_OFFSET) + +/* DEFINITION OF THE ZERO-PAGE (PAG0) */ +/* based on work by Jason Eckhardt (jason@equator.com) */ + /* flags of the device_path */ #define PF_AUTOBOOT 0x80 #define PF_AUTOSEARCH 0x40 diff --git a/trunk/arch/parisc/include/asm/pgtable.h b/trunk/arch/parisc/include/asm/pgtable.h index ee99f2339356..22dadeb58695 100644 --- a/trunk/arch/parisc/include/asm/pgtable.h +++ b/trunk/arch/parisc/include/asm/pgtable.h @@ -44,8 +44,6 @@ struct vm_area_struct; #endif /* !__ASSEMBLY__ */ -#include - #define pte_ERROR(e) \ printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) #define pmd_ERROR(e) \ diff --git a/trunk/arch/parisc/include/asm/prefetch.h b/trunk/arch/parisc/include/asm/prefetch.h index 1ee7c82672c1..c5edc60c059f 100644 --- a/trunk/arch/parisc/include/asm/prefetch.h +++ b/trunk/arch/parisc/include/asm/prefetch.h @@ -21,12 +21,7 @@ #define ARCH_HAS_PREFETCH static inline void prefetch(const void *addr) { - __asm__( -#ifndef CONFIG_PA20 - /* Need to avoid prefetch of NULL on PA7300LC */ - " extrw,u,= %0,31,32,%%r0\n" -#endif - " ldw 0(%0), %%r0" : : "r" (addr)); + __asm__("ldw 0(%0), %%r0" : : "r" (addr)); } /* LDD is a PA2.0 addition. */ diff --git a/trunk/arch/parisc/include/asm/spinlock.h b/trunk/arch/parisc/include/asm/spinlock.h index 3516e0b27044..804aa28ab1d6 100644 --- a/trunk/arch/parisc/include/asm/spinlock.h +++ b/trunk/arch/parisc/include/asm/spinlock.h @@ -1,8 +1,6 @@ #ifndef __ASM_SPINLOCK_H #define __ASM_SPINLOCK_H -#include -#include #include #include diff --git a/trunk/arch/parisc/kernel/Makefile b/trunk/arch/parisc/kernel/Makefile index 66ee3f12df58..67db0722e6ca 100644 --- a/trunk/arch/parisc/kernel/Makefile +++ b/trunk/arch/parisc/kernel/Makefile @@ -2,7 +2,7 @@ # Makefile for arch/parisc/kernel # -extra-y := head.o vmlinux.lds +extra-y := init_task.o head.o vmlinux.lds obj-y := cache.o pacache.o setup.o traps.o time.o irq.o \ pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \ diff --git a/trunk/arch/parisc/kernel/entry.S b/trunk/arch/parisc/kernel/entry.S index 535034217021..6f0594439143 100644 --- a/trunk/arch/parisc/kernel/entry.S +++ b/trunk/arch/parisc/kernel/entry.S @@ -581,11 +581,7 @@ */ cmpiclr,= 0x01,\tmp,%r0 ldi (_PAGE_DIRTY|_PAGE_READ|_PAGE_WRITE),\prot -#ifdef CONFIG_64BIT depd,z \prot,8,7,\prot -#else - depw,z \prot,8,7,\prot -#endif /* * OK, it is in the temp alias region, check whether "from" or "to". * Check "subtle" note in pacache.S re: r23/r26. diff --git a/trunk/arch/parisc/kernel/init_task.c b/trunk/arch/parisc/kernel/init_task.c new file mode 100644 index 000000000000..4a91e433416f --- /dev/null +++ b/trunk/arch/parisc/kernel/init_task.c @@ -0,0 +1,70 @@ +/* + * Static declaration of "init" task data structure. + * + * Copyright (C) 2000 Paul Bame + * Copyright (C) 2000-2001 John Marvin + * Copyright (C) 2001 Helge Deller + * Copyright (C) 2002 Matthew Wilcox + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +/* + * Initial task structure. + * + * We need to make sure that this is 16384-byte aligned due to the + * way process stacks are handled. This is done by having a special + * "init_task" linker map entry.. + */ +union thread_union init_thread_union __init_task_data + __attribute__((aligned(128))) = + { INIT_THREAD_INFO(init_task) }; + +#if PT_NLEVELS == 3 +/* NOTE: This layout exactly conforms to the hybrid L2/L3 page table layout + * with the first pmd adjacent to the pgd and below it. gcc doesn't actually + * guarantee that global objects will be laid out in memory in the same order + * as the order of declaration, so put these in different sections and use + * the linker script to order them. */ +pmd_t pmd0[PTRS_PER_PMD] __attribute__ ((__section__ (".data..vm0.pmd"), aligned(PAGE_SIZE))); +#endif + +pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((__section__ (".data..vm0.pgd"), aligned(PAGE_SIZE))); +pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((__section__ (".data..vm0.pte"), aligned(PAGE_SIZE))); + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +EXPORT_SYMBOL(init_task); + +__asm__(".data"); +struct task_struct init_task = INIT_TASK(init_task); diff --git a/trunk/arch/parisc/kernel/pacache.S b/trunk/arch/parisc/kernel/pacache.S index 5d7218ad885c..93ff3d90edd1 100644 --- a/trunk/arch/parisc/kernel/pacache.S +++ b/trunk/arch/parisc/kernel/pacache.S @@ -692,7 +692,7 @@ ENTRY(flush_icache_page_asm) /* Purge any old translation */ - pitlb (%sr4,%r28) + pitlb (%sr0,%r28) ldil L%icache_stride, %r1 ldw R%icache_stride(%r1), %r1 @@ -706,29 +706,27 @@ ENTRY(flush_icache_page_asm) sub %r25, %r1, %r25 - /* fic only has the type 26 form on PA1.1, requiring an - * explicit space specification, so use %sr4 */ -1: fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) - fic,m %r1(%sr4,%r28) +1: fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) + fic,m %r1(%r28) cmpb,COND(<<) %r28, %r25,1b - fic,m %r1(%sr4,%r28) + fic,m %r1(%r28) sync bv %r0(%r2) - pitlb (%sr4,%r25) + pitlb (%sr0,%r25) .exit .procend diff --git a/trunk/arch/parisc/kernel/pdc_cons.c b/trunk/arch/parisc/kernel/pdc_cons.c index 47341aa208f2..4f004596a6e7 100644 --- a/trunk/arch/parisc/kernel/pdc_cons.c +++ b/trunk/arch/parisc/kernel/pdc_cons.c @@ -50,7 +50,6 @@ #include #include #include -#include /* for PAGE0 */ #include /* for iodc_call() proto and friends */ static DEFINE_SPINLOCK(pdc_console_lock); @@ -105,7 +104,7 @@ static int pdc_console_tty_open(struct tty_struct *tty, struct file *filp) static void pdc_console_tty_close(struct tty_struct *tty, struct file *filp) { - if (tty->count == 1) { + if (!tty->count) { del_timer_sync(&pdc_console_timer); tty_port_tty_set(&tty_port, NULL); } diff --git a/trunk/arch/parisc/kernel/smp.c b/trunk/arch/parisc/kernel/smp.c index a47828d31fe6..0bb1d63907f8 100644 --- a/trunk/arch/parisc/kernel/smp.c +++ b/trunk/arch/parisc/kernel/smp.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -296,13 +295,8 @@ smp_cpu_init(int cpunum) printk(KERN_CRIT "CPU#%d already initialized!\n", cpunum); machine_halt(); - } - - notify_cpu_starting(cpunum); - - ipi_call_lock(); + } set_cpu_online(cpunum, true); - ipi_call_unlock(); /* Initialise the idle task for this CPU */ atomic_inc(&init_mm.mm_count); @@ -340,11 +334,26 @@ void __init smp_callin(void) /* * Bring one cpu online. */ -int __cpuinit smp_boot_one_cpu(int cpuid, struct task_struct *idle) +int __cpuinit smp_boot_one_cpu(int cpuid) { const struct cpuinfo_parisc *p = &per_cpu(cpu_data, cpuid); + struct task_struct *idle; long timeout; + /* + * Create an idle task for this CPU. Note the address wed* give + * to kernel_thread is irrelevant -- it's going to start + * where OS_BOOT_RENDEVZ vector in SAL says to start. But + * this gets all the other task-y sort of data structures set + * up like we wish. We need to pull the just created idle task + * off the run queue and stuff it into the init_tasks[] array. + * Sheesh . . . + */ + + idle = fork_idle(cpuid); + if (IS_ERR(idle)) + panic("SMP: fork failed for CPU:%d", cpuid); + task_thread_info(idle)->cpu = cpuid; /* Let _start know what logical CPU we're booting @@ -388,6 +397,10 @@ int __cpuinit smp_boot_one_cpu(int cpuid, struct task_struct *idle) udelay(100); barrier(); } + + put_task_struct(idle); + idle = NULL; + printk(KERN_CRIT "SMP: CPU:%d is stuck.\n", cpuid); return -1; @@ -436,10 +449,10 @@ void smp_cpus_done(unsigned int cpu_max) } -int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) +int __cpuinit __cpu_up(unsigned int cpu) { if (cpu != 0 && cpu < parisc_max_cpus) - smp_boot_one_cpu(cpu, tidle); + smp_boot_one_cpu(cpu); return cpu_online(cpu) ? 0 : -ENOSYS; } diff --git a/trunk/arch/parisc/kernel/time.c b/trunk/arch/parisc/kernel/time.c index 70e105d62423..7c0774397b89 100644 --- a/trunk/arch/parisc/kernel/time.c +++ b/trunk/arch/parisc/kernel/time.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/parisc/mm/init.c b/trunk/arch/parisc/mm/init.c index 3ac462de53a4..82f364e209fc 100644 --- a/trunk/arch/parisc/mm/init.c +++ b/trunk/arch/parisc/mm/init.c @@ -33,18 +33,6 @@ extern int data_start; -#if PT_NLEVELS == 3 -/* NOTE: This layout exactly conforms to the hybrid L2/L3 page table layout - * with the first pmd adjacent to the pgd and below it. gcc doesn't actually - * guarantee that global objects will be laid out in memory in the same order - * as the order of declaration, so put these in different sections and use - * the linker script to order them. */ -pmd_t pmd0[PTRS_PER_PMD] __attribute__ ((__section__ (".data..vm0.pmd"), aligned(PAGE_SIZE))); -#endif - -pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((__section__ (".data..vm0.pgd"), aligned(PAGE_SIZE))); -pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((__section__ (".data..vm0.pte"), aligned(PAGE_SIZE))); - #ifdef CONFIG_DISCONTIGMEM struct node_map_data node_data[MAX_NUMNODES] __read_mostly; unsigned char pfnnid_map[PFNNID_MAP_MAX] __read_mostly; diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 8a01098eaaca..feab3bad6d0f 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -87,6 +87,10 @@ config ARCH_HAS_ILOG2_U64 bool default y if 64BIT +config ARCH_HAS_CPU_IDLE_WAIT + bool + default y + config GENERIC_HWEIGHT bool default y @@ -137,10 +141,9 @@ config PPC select IRQ_FORCED_THREADING select HAVE_RCU_TABLE_FREE if SMP select HAVE_SYSCALL_TRACEPOINTS - select HAVE_BPF_JIT if PPC64 + select HAVE_BPF_JIT if (PPC64 && NET) select HAVE_ARCH_JUMP_LABEL select ARCH_HAVE_NMI_SAFE_CMPXCHG - select GENERIC_SMP_IDLE_THREAD config EARLY_PRINTK bool diff --git a/trunk/arch/powerpc/include/asm/exception-64s.h b/trunk/arch/powerpc/include/asm/exception-64s.h index d58fc4e4149c..548da3aa0a30 100644 --- a/trunk/arch/powerpc/include/asm/exception-64s.h +++ b/trunk/arch/powerpc/include/asm/exception-64s.h @@ -288,6 +288,13 @@ label##_hv: \ /* Exception addition: Hard disable interrupts */ #define DISABLE_INTS SOFT_DISABLE_INTS(r10,r11) +/* Exception addition: Keep interrupt state */ +#define ENABLE_INTS \ + ld r11,PACAKMSR(r13); \ + ld r12,_MSR(r1); \ + rlwimi r11,r12,0,MSR_EE; \ + mtmsrd r11,1 + #define ADD_NVGPRS \ bl .save_nvgprs diff --git a/trunk/arch/powerpc/include/asm/kvm_book3s.h b/trunk/arch/powerpc/include/asm/kvm_book3s.h index fd07f43d6622..aa795ccef294 100644 --- a/trunk/arch/powerpc/include/asm/kvm_book3s.h +++ b/trunk/arch/powerpc/include/asm/kvm_book3s.h @@ -81,13 +81,12 @@ struct kvmppc_vcpu_book3s { u64 sdr1; u64 hior; u64 msr_mask; + u64 vsid_next; #ifdef CONFIG_PPC_BOOK3S_32 u32 vsid_pool[VSID_POOL_SIZE]; - u32 vsid_next; #else - u64 proto_vsid_first; - u64 proto_vsid_max; - u64 proto_vsid_next; + u64 vsid_first; + u64 vsid_max; #endif int context_id[SID_CONTEXTS]; diff --git a/trunk/arch/powerpc/include/asm/processor.h b/trunk/arch/powerpc/include/asm/processor.h index 48a26d379222..8e2d0371fe1e 100644 --- a/trunk/arch/powerpc/include/asm/processor.h +++ b/trunk/arch/powerpc/include/asm/processor.h @@ -386,6 +386,7 @@ extern unsigned long cpuidle_disable; enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF}; extern int powersave_nap; /* set if nap mode can be used in idle loop */ +void cpu_idle_wait(void); #ifdef CONFIG_PSERIES_IDLE extern void update_smt_snooze_delay(int snooze); diff --git a/trunk/arch/powerpc/include/asm/thread_info.h b/trunk/arch/powerpc/include/asm/thread_info.h index 1a1bb00f061a..4a741c7efd02 100644 --- a/trunk/arch/powerpc/include/asm/thread_info.h +++ b/trunk/arch/powerpc/include/asm/thread_info.h @@ -62,8 +62,21 @@ struct thread_info { #define init_thread_info (init_thread_union.thread_info) #define init_stack (init_thread_union.stack) +/* thread information allocation */ + +#if THREAD_SHIFT >= PAGE_SHIFT + #define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT) +#else /* THREAD_SHIFT < PAGE_SHIFT */ + +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + +extern struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node); +extern void free_thread_info(struct thread_info *ti); + +#endif /* THREAD_SHIFT < PAGE_SHIFT */ + /* how to get the thread information struct from C */ static inline struct thread_info *current_thread_info(void) { diff --git a/trunk/arch/powerpc/kernel/Makefile b/trunk/arch/powerpc/kernel/Makefile index 83afacd3ba7b..f5808a35688c 100644 --- a/trunk/arch/powerpc/kernel/Makefile +++ b/trunk/arch/powerpc/kernel/Makefile @@ -28,7 +28,7 @@ endif obj-y := cputable.o ptrace.o syscalls.o \ irq.o align.o signal_32.o pmc.o vdso.o \ - process.o systbl.o idle.o \ + init_task.o process.o systbl.o idle.o \ signal.o sysfs.o cacheinfo.o time.o \ prom.o traps.o setup-common.o \ udbg.o misc.o io.o dma.o \ diff --git a/trunk/arch/powerpc/kernel/entry_64.S b/trunk/arch/powerpc/kernel/entry_64.S index ef2074c3e906..f8a7a1a1a9f4 100644 --- a/trunk/arch/powerpc/kernel/entry_64.S +++ b/trunk/arch/powerpc/kernel/entry_64.S @@ -588,19 +588,23 @@ _GLOBAL(ret_from_except_lite) fast_exc_return_irq: restore: /* - * This is the main kernel exit path. First we check if we - * are about to re-enable interrupts + * This is the main kernel exit path, we first check if we + * have to change our interrupt state. */ ld r5,SOFTE(r1) lbz r6,PACASOFTIRQEN(r13) - cmpwi cr0,r5,0 - beq restore_irq_off + cmpwi cr1,r5,0 + cmpw cr0,r5,r6 + beq cr0,4f - /* We are enabling, were we already enabled ? Yes, just return */ - cmpwi cr0,r6,1 - beq cr0,do_restore + /* We do, handle disable first, which is easy */ + bne cr1,3f; + li r0,0 + stb r0,PACASOFTIRQEN(r13); + TRACE_DISABLE_INTS + b 4f - /* +3: /* * We are about to soft-enable interrupts (we are hard disabled * at this point). We check if there's anything that needs to * be replayed first. @@ -622,7 +626,7 @@ restore_no_replay: /* * Final return path. BookE is handled in a different file */ -do_restore: +4: #ifdef CONFIG_PPC_BOOK3E b .exception_return_book3e #else @@ -695,25 +699,6 @@ fast_exception_return: #endif /* CONFIG_PPC_BOOK3E */ - /* - * We are returning to a context with interrupts soft disabled. - * - * However, we may also about to hard enable, so we need to - * make sure that in this case, we also clear PACA_IRQ_HARD_DIS - * or that bit can get out of sync and bad things will happen - */ -restore_irq_off: - ld r3,_MSR(r1) - lbz r7,PACAIRQHAPPENED(r13) - andi. r0,r3,MSR_EE - beq 1f - rlwinm r7,r7,0,~PACA_IRQ_HARD_DIS - stb r7,PACAIRQHAPPENED(r13) -1: li r0,0 - stb r0,PACASOFTIRQEN(r13); - TRACE_DISABLE_INTS - b do_restore - /* * Something did happen, check if a re-emit is needed * (this also clears paca->irq_happened) @@ -763,9 +748,6 @@ restore_check_irq_replay: #endif /* CONFIG_PPC_BOOK3E */ 1: b .ret_from_except /* What else to do here ? */ - - -3: do_work: #ifdef CONFIG_PREEMPT andi. r0,r3,MSR_PR /* Returning to user mode? */ @@ -785,6 +767,16 @@ do_work: SOFT_DISABLE_INTS(r3,r4) 1: bl .preempt_schedule_irq + /* Hard-disable interrupts again (and update PACA) */ +#ifdef CONFIG_PPC_BOOK3E + wrteei 0 +#else + ld r10,PACAKMSR(r13) /* Get kernel MSR without EE */ + mtmsrd r10,1 +#endif /* CONFIG_PPC_BOOK3E */ + li r0,PACA_IRQ_HARD_DIS + stb r0,PACAIRQHAPPENED(r13) + /* Re-test flags and eventually loop */ clrrdi r9,r1,THREAD_SHIFT ld r4,TI_FLAGS(r9) @@ -795,6 +787,14 @@ do_work: user_work: #endif /* CONFIG_PREEMPT */ + /* Enable interrupts */ +#ifdef CONFIG_PPC_BOOK3E + wrteei 1 +#else + ori r10,r10,MSR_EE + mtmsrd r10,1 +#endif /* CONFIG_PPC_BOOK3E */ + andi. r0,r4,_TIF_NEED_RESCHED beq 1f bl .restore_interrupts diff --git a/trunk/arch/powerpc/kernel/exceptions-64s.S b/trunk/arch/powerpc/kernel/exceptions-64s.S index 8f880bc77c56..cb705fdbb458 100644 --- a/trunk/arch/powerpc/kernel/exceptions-64s.S +++ b/trunk/arch/powerpc/kernel/exceptions-64s.S @@ -768,8 +768,8 @@ alignment_common: std r3,_DAR(r1) std r4,_DSISR(r1) bl .save_nvgprs - DISABLE_INTS addi r3,r1,STACK_FRAME_OVERHEAD + ENABLE_INTS bl .alignment_exception b .ret_from_except diff --git a/trunk/arch/powerpc/kernel/idle.c b/trunk/arch/powerpc/kernel/idle.c index 2099d9a879e8..6d2209ac0c44 100644 --- a/trunk/arch/powerpc/kernel/idle.c +++ b/trunk/arch/powerpc/kernel/idle.c @@ -113,6 +113,29 @@ void cpu_idle(void) } } + +/* + * cpu_idle_wait - Used to ensure that all the CPUs come out of the old + * idle loop and start using the new idle loop. + * Required while changing idle handler on SMP systems. + * Caller must have changed idle handler to the new value before the call. + * This window may be larger on shared systems. + */ +void cpu_idle_wait(void) +{ + int cpu; + smp_mb(); + + /* kick all the CPUs so that they exit out of old idle routine */ + get_online_cpus(); + for_each_online_cpu(cpu) { + if (cpu != smp_processor_id()) + smp_send_reschedule(cpu); + } + put_online_cpus(); +} +EXPORT_SYMBOL_GPL(cpu_idle_wait); + int powersave_nap; #ifdef CONFIG_SYSCTL diff --git a/trunk/arch/powerpc/kernel/init_task.c b/trunk/arch/powerpc/kernel/init_task.c new file mode 100644 index 000000000000..d076d465dbd1 --- /dev/null +++ b/trunk/arch/powerpc/kernel/init_task.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +/* + * Initial thread structure. + * + * We need to make sure that this is 16384-byte aligned due to the + * way process stacks are handled. This is done by having a special + * "init_task" linker map entry.. + */ +union thread_union init_thread_union __init_task_data = + { INIT_THREAD_INFO(init_task) }; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); + +EXPORT_SYMBOL(init_task); diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c index 641da9e868ce..43eb74fcedde 100644 --- a/trunk/arch/powerpc/kernel/irq.c +++ b/trunk/arch/powerpc/kernel/irq.c @@ -229,19 +229,6 @@ notrace void arch_local_irq_restore(unsigned long en) */ if (unlikely(irq_happened != PACA_IRQ_HARD_DIS)) __hard_irq_disable(); -#ifdef CONFIG_TRACE_IRQFLAG - else { - /* - * We should already be hard disabled here. We had bugs - * where that wasn't the case so let's dbl check it and - * warn if we are wrong. Only do that when IRQ tracing - * is enabled as mfmsr() can be costly. - */ - if (WARN_ON(mfmsr() & MSR_EE)) - __hard_irq_disable(); - } -#endif /* CONFIG_TRACE_IRQFLAG */ - set_soft_enabled(0); /* @@ -273,17 +260,11 @@ EXPORT_SYMBOL(arch_local_irq_restore); * if they are currently disabled. This is typically called before * schedule() or do_signal() when returning to userspace. We do it * in C to avoid the burden of dealing with lockdep etc... - * - * NOTE: This is called with interrupts hard disabled but not marked - * as such in paca->irq_happened, so we need to resync this. */ void restore_interrupts(void) { - if (irqs_disabled()) { - local_paca->irq_happened |= PACA_IRQ_HARD_DIS; + if (irqs_disabled()) local_irq_enable(); - } else - __hard_irq_enable(); } #endif /* CONFIG_PPC64 */ diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index aa05935b6947..4937c9690090 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -1252,6 +1252,37 @@ void __ppc64_runlatch_off(void) } #endif /* CONFIG_PPC64 */ +#if THREAD_SHIFT < PAGE_SHIFT + +static struct kmem_cache *thread_info_cache; + +struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node) +{ + struct thread_info *ti; + + ti = kmem_cache_alloc_node(thread_info_cache, GFP_KERNEL, node); + if (unlikely(ti == NULL)) + return NULL; +#ifdef CONFIG_DEBUG_STACK_USAGE + memset(ti, 0, THREAD_SIZE); +#endif + return ti; +} + +void free_thread_info(struct thread_info *ti) +{ + kmem_cache_free(thread_info_cache, ti); +} + +void thread_info_cache_init(void) +{ + thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE, + THREAD_SIZE, 0, NULL); + BUG_ON(thread_info_cache == NULL); +} + +#endif /* THREAD_SHIFT < PAGE_SHIFT */ + unsigned long arch_align_stack(unsigned long sp) { if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) diff --git a/trunk/arch/powerpc/kernel/ptrace.c b/trunk/arch/powerpc/kernel/ptrace.c index dd5e214cdf21..8d8e028893be 100644 --- a/trunk/arch/powerpc/kernel/ptrace.c +++ b/trunk/arch/powerpc/kernel/ptrace.c @@ -1710,7 +1710,7 @@ long do_syscall_trace_enter(struct pt_regs *regs) { long ret = 0; - secure_computing_strict(regs->gpr[0]); + secure_computing(regs->gpr[0]); if (test_thread_flag(TIF_SYSCALL_TRACE) && tracehook_report_syscall_entry(regs)) diff --git a/trunk/arch/powerpc/kernel/smp.c b/trunk/arch/powerpc/kernel/smp.c index e4cb34322de4..d9f94410fd7f 100644 --- a/trunk/arch/powerpc/kernel/smp.c +++ b/trunk/arch/powerpc/kernel/smp.c @@ -57,9 +57,27 @@ #define DBG(fmt...) #endif + +/* Store all idle threads, this can be reused instead of creating +* a new thread. Also avoids complicated thread destroy functionality +* for idle threads. +*/ #ifdef CONFIG_HOTPLUG_CPU +/* + * Needed only for CONFIG_HOTPLUG_CPU because __cpuinitdata is + * removed after init for !CONFIG_HOTPLUG_CPU. + */ +static DEFINE_PER_CPU(struct task_struct *, idle_thread_array); +#define get_idle_for_cpu(x) (per_cpu(idle_thread_array, x)) +#define set_idle_for_cpu(x, p) (per_cpu(idle_thread_array, x) = (p)) + /* State of each CPU during hotplug phases */ static DEFINE_PER_CPU(int, cpu_state) = { 0 }; + +#else +static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ; +#define get_idle_for_cpu(x) (idle_thread_array[(x)]) +#define set_idle_for_cpu(x, p) (idle_thread_array[(x)] = (p)) #endif struct thread_info *secondary_ti; @@ -411,19 +429,60 @@ int generic_check_cpu_restart(unsigned int cpu) } #endif -static void cpu_idle_thread_init(unsigned int cpu, struct task_struct *idle) +struct create_idle { + struct work_struct work; + struct task_struct *idle; + struct completion done; + int cpu; +}; + +static void __cpuinit do_fork_idle(struct work_struct *work) { - struct thread_info *ti = task_thread_info(idle); + struct create_idle *c_idle = + container_of(work, struct create_idle, work); + + c_idle->idle = fork_idle(c_idle->cpu); + complete(&c_idle->done); +} + +static int __cpuinit create_idle(unsigned int cpu) +{ + struct thread_info *ti; + struct create_idle c_idle = { + .cpu = cpu, + .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done), + }; + INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle); + + c_idle.idle = get_idle_for_cpu(cpu); + + /* We can't use kernel_thread since we must avoid to + * reschedule the child. We use a workqueue because + * we want to fork from a kernel thread, not whatever + * userspace process happens to be trying to online us. + */ + if (!c_idle.idle) { + schedule_work(&c_idle.work); + wait_for_completion(&c_idle.done); + } else + init_idle(c_idle.idle, cpu); + if (IS_ERR(c_idle.idle)) { + pr_err("Failed fork for CPU %u: %li", cpu, PTR_ERR(c_idle.idle)); + return PTR_ERR(c_idle.idle); + } + ti = task_thread_info(c_idle.idle); #ifdef CONFIG_PPC64 - paca[cpu].__current = idle; + paca[cpu].__current = c_idle.idle; paca[cpu].kstack = (unsigned long)ti + THREAD_SIZE - STACK_FRAME_OVERHEAD; #endif ti->cpu = cpu; - secondary_ti = current_set[cpu] = ti; + current_set[cpu] = ti; + + return 0; } -int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) +int __cpuinit __cpu_up(unsigned int cpu) { int rc, c; @@ -431,7 +490,12 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu))) return -EINVAL; - cpu_idle_thread_init(cpu, tidle); + /* Make sure we have an idle thread */ + rc = create_idle(cpu); + if (rc) + return rc; + + secondary_ti = current_set[cpu]; /* Make sure callin-map entry is 0 (can be leftover a CPU * hotplug diff --git a/trunk/arch/powerpc/kernel/traps.c b/trunk/arch/powerpc/kernel/traps.c index 158972341a2d..6aa0c663e247 100644 --- a/trunk/arch/powerpc/kernel/traps.c +++ b/trunk/arch/powerpc/kernel/traps.c @@ -248,7 +248,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) addr, regs->nip, regs->link, code); } - if (arch_irqs_disabled() && !arch_irq_disabled_regs(regs)) + if (!arch_irq_disabled_regs(regs)) local_irq_enable(); memset(&info, 0, sizeof(info)); @@ -1019,9 +1019,7 @@ void __kprobes program_check_exception(struct pt_regs *regs) return; } - /* We restore the interrupt state now */ - if (!arch_irq_disabled_regs(regs)) - local_irq_enable(); + local_irq_enable(); #ifdef CONFIG_MATH_EMULATION /* (reason & REASON_ILLEGAL) would be the obvious thing here, @@ -1071,10 +1069,6 @@ void alignment_exception(struct pt_regs *regs) { int sig, code, fixed = 0; - /* We restore the interrupt state now */ - if (!arch_irq_disabled_regs(regs)) - local_irq_enable(); - /* we don't implement logging of alignment exceptions */ if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) fixed = fix_alignment(regs); diff --git a/trunk/arch/powerpc/kvm/book3s_64_mmu_host.c b/trunk/arch/powerpc/kvm/book3s_64_mmu_host.c index 10fc8ec9d2a8..6f87f39a1ac2 100644 --- a/trunk/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/trunk/arch/powerpc/kvm/book3s_64_mmu_host.c @@ -194,14 +194,14 @@ static struct kvmppc_sid_map *create_sid_map(struct kvm_vcpu *vcpu, u64 gvsid) backwards_map = !backwards_map; /* Uh-oh ... out of mappings. Let's flush! */ - if (vcpu_book3s->proto_vsid_next == vcpu_book3s->proto_vsid_max) { - vcpu_book3s->proto_vsid_next = vcpu_book3s->proto_vsid_first; + if (vcpu_book3s->vsid_next == vcpu_book3s->vsid_max) { + vcpu_book3s->vsid_next = vcpu_book3s->vsid_first; memset(vcpu_book3s->sid_map, 0, sizeof(struct kvmppc_sid_map) * SID_MAP_NUM); kvmppc_mmu_pte_flush(vcpu, 0, 0); kvmppc_mmu_flush_segments(vcpu); } - map->host_vsid = vsid_scramble(vcpu_book3s->proto_vsid_next++, 256M); + map->host_vsid = vcpu_book3s->vsid_next++; map->guest_vsid = gvsid; map->valid = true; @@ -319,10 +319,9 @@ int kvmppc_mmu_init(struct kvm_vcpu *vcpu) return -1; vcpu3s->context_id[0] = err; - vcpu3s->proto_vsid_max = ((vcpu3s->context_id[0] + 1) - << USER_ESID_BITS) - 1; - vcpu3s->proto_vsid_first = vcpu3s->context_id[0] << USER_ESID_BITS; - vcpu3s->proto_vsid_next = vcpu3s->proto_vsid_first; + vcpu3s->vsid_max = ((vcpu3s->context_id[0] + 1) << USER_ESID_BITS) - 1; + vcpu3s->vsid_first = vcpu3s->context_id[0] << USER_ESID_BITS; + vcpu3s->vsid_next = vcpu3s->vsid_first; kvmppc_mmu_hpte_init(vcpu); diff --git a/trunk/arch/powerpc/kvm/book3s_64_mmu_hv.c b/trunk/arch/powerpc/kvm/book3s_64_mmu_hv.c index c3beaeef3f60..ddc485a529f2 100644 --- a/trunk/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/trunk/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -258,8 +258,6 @@ static long kvmppc_get_guest_page(struct kvm *kvm, unsigned long gfn, !(memslot->userspace_addr & (s - 1))) { start &= ~(s - 1); pgsize = s; - get_page(hpage); - put_page(page); page = hpage; } } @@ -283,8 +281,11 @@ static long kvmppc_get_guest_page(struct kvm *kvm, unsigned long gfn, err = 0; out: - if (got) + if (got) { + if (PageHuge(page)) + page = compound_head(page); put_page(page); + } return err; up_err: @@ -677,15 +678,8 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, SetPageDirty(page); out_put: - if (page) { - /* - * We drop pages[0] here, not page because page might - * have been set to the head page of a compound, but - * we have to drop the reference on the correct tail - * page to match the get inside gup() - */ - put_page(pages[0]); - } + if (page) + put_page(page); return ret; out_unlock: @@ -985,7 +979,6 @@ void *kvmppc_pin_guest_page(struct kvm *kvm, unsigned long gpa, pa = *physp; } page = pfn_to_page(pa >> PAGE_SHIFT); - get_page(page); } else { hva = gfn_to_hva_memslot(memslot, gfn); npages = get_user_pages_fast(hva, 1, 1, pages); @@ -998,6 +991,8 @@ void *kvmppc_pin_guest_page(struct kvm *kvm, unsigned long gpa, page = compound_head(page); psize <<= compound_order(page); } + if (!kvm->arch.using_mmu_notifiers) + get_page(page); offset = gpa & (psize - 1); if (nb_ret) *nb_ret = psize - offset; @@ -1008,6 +1003,7 @@ void kvmppc_unpin_guest_page(struct kvm *kvm, void *va) { struct page *page = virt_to_page(va); + page = compound_head(page); put_page(page); } diff --git a/trunk/arch/powerpc/kvm/book3s_hv.c b/trunk/arch/powerpc/kvm/book3s_hv.c index 108d1f580177..01294a5099dd 100644 --- a/trunk/arch/powerpc/kvm/book3s_hv.c +++ b/trunk/arch/powerpc/kvm/book3s_hv.c @@ -1192,6 +1192,8 @@ static void unpin_slot(struct kvm *kvm, int slot_id) continue; pfn = physp[j] >> PAGE_SHIFT; page = pfn_to_page(pfn); + if (PageHuge(page)) + page = compound_head(page); SetPageDirty(page); put_page(page); } diff --git a/trunk/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/trunk/arch/powerpc/kvm/book3s_hv_rm_mmu.c index cec4daddbf31..def880aea63a 100644 --- a/trunk/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/trunk/arch/powerpc/kvm/book3s_hv_rm_mmu.c @@ -463,7 +463,6 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) /* insert R and C bits from PTE */ rcbits = rev->guest_rpte & (HPTE_R_R|HPTE_R_C); args[j] |= rcbits << (56 - 5); - hp[0] = 0; continue; } diff --git a/trunk/arch/powerpc/kvm/book3s_segment.S b/trunk/arch/powerpc/kvm/book3s_segment.S index 6e6e9cef34a8..0676ae249b9f 100644 --- a/trunk/arch/powerpc/kvm/book3s_segment.S +++ b/trunk/arch/powerpc/kvm/book3s_segment.S @@ -197,8 +197,7 @@ kvmppc_interrupt: /* Save guest PC and MSR */ #ifdef CONFIG_PPC64 BEGIN_FTR_SECTION - andi. r0, r12, 0x2 - cmpwi cr1, r0, 0 + andi. r0,r12,0x2 beq 1f mfspr r3,SPRN_HSRR0 mfspr r4,SPRN_HSRR1 @@ -251,12 +250,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) beq ld_last_prev_inst cmpwi r12, BOOK3S_INTERRUPT_ALIGNMENT beq- ld_last_inst -#ifdef CONFIG_PPC64 -BEGIN_FTR_SECTION - cmpwi r12, BOOK3S_INTERRUPT_H_EMUL_ASSIST - beq- ld_last_inst -END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) -#endif b no_ld_last_inst @@ -323,17 +316,23 @@ no_dcbz32_off: * Having set up SRR0/1 with the address where we want * to continue with relocation on (potentially in module * space), we either just go straight there with rfi[d], - * or we jump to an interrupt handler if there is an - * interrupt to be handled first. In the latter case, - * the rfi[d] at the end of the interrupt handler will - * get us back to where we want to continue. + * or we jump to an interrupt handler with bctr if there + * is an interrupt to be handled first. In the latter + * case, the rfi[d] at the end of the interrupt handler + * will get us back to where we want to continue. */ + cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL + beq 1f + cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER + beq 1f + cmpwi r12, BOOK3S_INTERRUPT_PERFMON +1: mtctr r12 + /* Register usage at this point: * * R1 = host R1 * R2 = host R2 - * R10 = raw exit handler id * R12 = exit handler id * R13 = shadow vcpu (32-bit) or PACA (64-bit) * SVCPU.* = guest * @@ -343,25 +342,12 @@ no_dcbz32_off: PPC_LL r6, HSTATE_HOST_MSR(r13) PPC_LL r8, HSTATE_VMHANDLER(r13) -#ifdef CONFIG_PPC64 -BEGIN_FTR_SECTION - beq cr1, 1f - mtspr SPRN_HSRR1, r6 - mtspr SPRN_HSRR0, r8 -END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) -#endif -1: /* Restore host msr -> SRR1 */ + /* Restore host msr -> SRR1 */ mtsrr1 r6 /* Load highmem handler address */ mtsrr0 r8 /* RFI into the highmem handler, or jump to interrupt handler */ - cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL - beqa BOOK3S_INTERRUPT_EXTERNAL - cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER - beqa BOOK3S_INTERRUPT_DECREMENTER - cmpwi r12, BOOK3S_INTERRUPT_PERFMON - beqa BOOK3S_INTERRUPT_PERFMON - + beqctr RFI kvmppc_handler_trampoline_exit_end: diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index e16390c0bca8..9015060919a0 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -122,7 +122,6 @@ config S390 select ARCH_INLINE_WRITE_UNLOCK_BH select ARCH_INLINE_WRITE_UNLOCK_IRQ select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE - select GENERIC_SMP_IDLE_THREAD config SCHED_OMIT_FRAME_POINTER def_bool y @@ -218,7 +217,7 @@ config COMPAT def_bool y prompt "Kernel support for 31 bit emulation" depends on 64BIT - select COMPAT_BINFMT_ELF if BINFMT_ELF + select COMPAT_BINFMT_ELF select ARCH_WANT_OLD_COMPAT_IPC help Select this option if you want to enable your system kernel to @@ -235,25 +234,6 @@ config KEYS_COMPAT config AUDIT_ARCH def_bool y -config HAVE_MARCH_Z900_FEATURES - def_bool n - -config HAVE_MARCH_Z990_FEATURES - def_bool n - select HAVE_MARCH_Z900_FEATURES - -config HAVE_MARCH_Z9_109_FEATURES - def_bool n - select HAVE_MARCH_Z990_FEATURES - -config HAVE_MARCH_Z10_FEATURES - def_bool n - select HAVE_MARCH_Z9_109_FEATURES - -config HAVE_MARCH_Z196_FEATURES - def_bool n - select HAVE_MARCH_Z10_FEATURES - comment "Code generation options" choice @@ -269,7 +249,6 @@ config MARCH_G5 config MARCH_Z900 bool "IBM zSeries model z800 and z900" - select HAVE_MARCH_Z900_FEATURES if 64BIT help Select this to enable optimizations for model z800/z900 (2064 and 2066 series). This will enable some optimizations that are not @@ -277,7 +256,6 @@ config MARCH_Z900 config MARCH_Z990 bool "IBM zSeries model z890 and z990" - select HAVE_MARCH_Z990_FEATURES if 64BIT help Select this to enable optimizations for model z890/z990 (2084 and 2086 series). The kernel will be slightly faster but will not work @@ -285,7 +263,6 @@ config MARCH_Z990 config MARCH_Z9_109 bool "IBM System z9" - select HAVE_MARCH_Z9_109_FEATURES if 64BIT help Select this to enable optimizations for IBM System z9 (2094 and 2096 series). The kernel will be slightly faster but will not work @@ -293,7 +270,6 @@ config MARCH_Z9_109 config MARCH_Z10 bool "IBM System z10" - select HAVE_MARCH_Z10_FEATURES if 64BIT help Select this to enable optimizations for IBM System z10 (2097 and 2098 series). The kernel will be slightly faster but will not work @@ -301,7 +277,6 @@ config MARCH_Z10 config MARCH_Z196 bool "IBM zEnterprise 114 and 196" - select HAVE_MARCH_Z196_FEATURES if 64BIT help Select this to enable optimizations for IBM zEnterprise 114 and 196 (2818 and 2817 series). The kernel will be slightly faster but will @@ -431,6 +406,33 @@ config CHSC_SCH comment "Misc" +config IPL + def_bool y + prompt "Builtin IPL record support" + help + If you want to use the produced kernel to IPL directly from a + device, you have to merge a bootsector specific to the device + into the first bytes of the kernel. You will have to select the + IPL device. + +choice + prompt "IPL method generated into head.S" + depends on IPL + default IPL_VM + help + Select "tape" if you want to IPL the image from a Tape. + + Select "vm_reader" if you are running under VM/ESA and want + to IPL the image from the emulated card reader. + +config IPL_TAPE + bool "tape" + +config IPL_VM + bool "vm_reader" + +endchoice + source "fs/Kconfig.binfmt" config FORCE_MAX_ZONEORDER @@ -567,7 +569,7 @@ config KEXEC config CRASH_DUMP bool "kernel crash dumps" - depends on 64BIT && SMP + depends on 64BIT select KEXEC help Generate crash dump after being started by kexec. diff --git a/trunk/arch/s390/Makefile b/trunk/arch/s390/Makefile index 49e76e8b477d..0ad2f1e1ce9e 100644 --- a/trunk/arch/s390/Makefile +++ b/trunk/arch/s390/Makefile @@ -91,6 +91,7 @@ OBJCOPYFLAGS := -O binary head-y := arch/s390/kernel/head.o head-y += arch/s390/kernel/$(if $(CONFIG_64BIT),head64.o,head31.o) +head-y += arch/s390/kernel/init_task.o # See arch/s390/Kbuild for content of core part of the kernel core-y += arch/s390/ diff --git a/trunk/arch/s390/boot/.gitignore b/trunk/arch/s390/boot/.gitignore deleted file mode 100644 index 017d5912ad2d..000000000000 --- a/trunk/arch/s390/boot/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -image -bzImage diff --git a/trunk/arch/s390/boot/compressed/.gitignore b/trunk/arch/s390/boot/compressed/.gitignore deleted file mode 100644 index ae06b9b4c02f..000000000000 --- a/trunk/arch/s390/boot/compressed/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -sizes.h -vmlinux -vmlinux.lds diff --git a/trunk/arch/s390/defconfig b/trunk/arch/s390/defconfig index 37d2bf267964..1957a9dd256d 100644 --- a/trunk/arch/s390/defconfig +++ b/trunk/arch/s390/defconfig @@ -155,6 +155,7 @@ CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=m CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m CONFIG_CRYPTO_SALSA20=m diff --git a/trunk/arch/s390/include/asm/barrier.h b/trunk/arch/s390/include/asm/barrier.h index 10a508802940..451273ad4d34 100644 --- a/trunk/arch/s390/include/asm/barrier.h +++ b/trunk/arch/s390/include/asm/barrier.h @@ -11,28 +11,25 @@ * Force strict CPU ordering. * And yes, this is required on UP too when we're talking * to devices. + * + * This is very similar to the ppc eieio/sync instruction in that is + * does a checkpoint syncronisation & makes sure that + * all memory ops have completed wrt other CPU's ( see 7-15 POP DJB ). */ -static inline void mb(void) -{ -#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES - /* Fast-BCR without checkpoint synchronization */ - asm volatile("bcr 14,0" : : : "memory"); -#else - asm volatile("bcr 15,0" : : : "memory"); -#endif -} - -#define rmb() mb() -#define wmb() mb() -#define read_barrier_depends() do { } while(0) -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() -#define smp_read_barrier_depends() read_barrier_depends() -#define smp_mb__before_clear_bit() smp_mb() -#define smp_mb__after_clear_bit() smp_mb() +#define eieio() asm volatile("bcr 15,0" : : : "memory") +#define SYNC_OTHER_CORES(x) eieio() +#define mb() eieio() +#define rmb() eieio() +#define wmb() eieio() +#define read_barrier_depends() do { } while(0) +#define smp_mb() mb() +#define smp_rmb() rmb() +#define smp_wmb() wmb() +#define smp_read_barrier_depends() read_barrier_depends() +#define smp_mb__before_clear_bit() smp_mb() +#define smp_mb__after_clear_bit() smp_mb() -#define set_mb(var, value) do { var = value; mb(); } while (0) +#define set_mb(var, value) do { var = value; mb(); } while (0) #endif /* __ASM_BARRIER_H */ diff --git a/trunk/arch/s390/include/asm/ccwgroup.h b/trunk/arch/s390/include/asm/ccwgroup.h index f2ef34f6d6e5..f2ea2c56a7e1 100644 --- a/trunk/arch/s390/include/asm/ccwgroup.h +++ b/trunk/arch/s390/include/asm/ccwgroup.h @@ -29,7 +29,9 @@ struct ccwgroup_device { /** * struct ccwgroup_driver - driver for ccw group devices - * @setup: function called during device creation to setup the device + * @max_slaves: maximum number of slave devices + * @driver_id: unique id + * @probe: function called on probe * @remove: function called on remove * @set_online: function called when device is set online * @set_offline: function called when device is set offline @@ -42,7 +44,10 @@ struct ccwgroup_device { * @driver: embedded driver structure */ struct ccwgroup_driver { - int (*setup) (struct ccwgroup_device *); + int max_slaves; + unsigned long driver_id; + + int (*probe) (struct ccwgroup_device *); void (*remove) (struct ccwgroup_device *); int (*set_online) (struct ccwgroup_device *); int (*set_offline) (struct ccwgroup_device *); @@ -58,8 +63,9 @@ struct ccwgroup_driver { extern int ccwgroup_driver_register (struct ccwgroup_driver *cdriver); extern void ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver); -int ccwgroup_create_dev(struct device *root, struct ccwgroup_driver *gdrv, - int num_devices, const char *buf); +int ccwgroup_create_from_string(struct device *root, unsigned int creator_id, + struct ccw_driver *cdrv, int num_devices, + const char *buf); extern int ccwgroup_probe_ccwdev(struct ccw_device *cdev); extern void ccwgroup_remove_ccwdev(struct ccw_device *cdev); diff --git a/trunk/arch/s390/include/asm/io.h b/trunk/arch/s390/include/asm/io.h index 27216d317991..b7ff6afc3caa 100644 --- a/trunk/arch/s390/include/asm/io.h +++ b/trunk/arch/s390/include/asm/io.h @@ -38,8 +38,11 @@ static inline void * phys_to_virt(unsigned long address) return (void *) address; } -void *xlate_dev_mem_ptr(unsigned long phys); -void unxlate_dev_mem_ptr(unsigned long phys, void *addr); +/* + * Convert a physical pointer to a virtual kernel pointer for /dev/mem + * access + */ +#define xlate_dev_mem_ptr(p) __va(p) /* * Convert a virtual cached pointer to an uncached pointer diff --git a/trunk/arch/s390/include/asm/qdio.h b/trunk/arch/s390/include/asm/qdio.h index f039d86adf67..d75c8e78f7e3 100644 --- a/trunk/arch/s390/include/asm/qdio.h +++ b/trunk/arch/s390/include/asm/qdio.h @@ -258,6 +258,11 @@ struct slsb { u8 val[QDIO_MAX_BUFFERS_PER_Q]; } __attribute__ ((packed, aligned(256))); +#define CHSC_AC2_MULTI_BUFFER_AVAILABLE 0x0080 +#define CHSC_AC2_MULTI_BUFFER_ENABLED 0x0040 +#define CHSC_AC2_DATA_DIV_AVAILABLE 0x0010 +#define CHSC_AC2_DATA_DIV_ENABLED 0x0002 + /** * struct qdio_outbuf_state - SBAL related asynchronous operation information * (for communication with upper layer programs) @@ -288,8 +293,6 @@ struct qdio_outbuf_state { #define AC1_SC_QEBSM_AVAILABLE 0x02 /* available for subchannel */ #define AC1_SC_QEBSM_ENABLED 0x01 /* enabled for subchannel */ -#define CHSC_AC2_MULTI_BUFFER_AVAILABLE 0x0080 -#define CHSC_AC2_MULTI_BUFFER_ENABLED 0x0040 #define CHSC_AC2_DATA_DIV_AVAILABLE 0x0010 #define CHSC_AC2_DATA_DIV_ENABLED 0x0002 @@ -325,13 +328,11 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int, int, int, unsigned long); /* qdio errors reported to the upper-layer program */ -#define QDIO_ERROR_ACTIVATE 0x0001 -#define QDIO_ERROR_GET_BUF_STATE 0x0002 -#define QDIO_ERROR_SET_BUF_STATE 0x0004 -#define QDIO_ERROR_SLSB_STATE 0x0100 - -#define QDIO_ERROR_FATAL 0x00ff -#define QDIO_ERROR_TEMPORARY 0xff00 +#define QDIO_ERROR_SIGA_TARGET 0x02 +#define QDIO_ERROR_SIGA_ACCESS_EXCEPTION 0x10 +#define QDIO_ERROR_SIGA_BUSY 0x20 +#define QDIO_ERROR_ACTIVATE_CHECK_CONDITION 0x40 +#define QDIO_ERROR_SLSB_STATE 0x80 /* for qdio_cleanup */ #define QDIO_FLAG_CLEANUP_USING_CLEAR 0x01 diff --git a/trunk/arch/s390/include/asm/setup.h b/trunk/arch/s390/include/asm/setup.h index 7244e1f64126..b21e46e5d4b8 100644 --- a/trunk/arch/s390/include/asm/setup.h +++ b/trunk/arch/s390/include/asm/setup.h @@ -82,6 +82,7 @@ extern unsigned int user_mode; #define MACHINE_FLAG_LPAR (1UL << 12) #define MACHINE_FLAG_SPP (1UL << 13) #define MACHINE_FLAG_TOPOLOGY (1UL << 14) +#define MACHINE_FLAG_STCKF (1UL << 15) #define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM) #define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM) @@ -100,6 +101,7 @@ extern unsigned int user_mode; #define MACHINE_HAS_PFMF (0) #define MACHINE_HAS_SPP (0) #define MACHINE_HAS_TOPOLOGY (0) +#define MACHINE_HAS_STCKF (0) #else /* __s390x__ */ #define MACHINE_HAS_IEEE (1) #define MACHINE_HAS_CSP (1) @@ -111,6 +113,7 @@ extern unsigned int user_mode; #define MACHINE_HAS_PFMF (S390_lowcore.machine_flags & MACHINE_FLAG_PFMF) #define MACHINE_HAS_SPP (S390_lowcore.machine_flags & MACHINE_FLAG_SPP) #define MACHINE_HAS_TOPOLOGY (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY) +#define MACHINE_HAS_STCKF (S390_lowcore.machine_flags & MACHINE_FLAG_STCKF) #endif /* __s390x__ */ #define ZFCPDUMP_HSA_SIZE (32UL<<20) diff --git a/trunk/arch/s390/include/asm/smp.h b/trunk/arch/s390/include/asm/smp.h index 0b6f586c1383..c77c6de6f6c0 100644 --- a/trunk/arch/s390/include/asm/smp.h +++ b/trunk/arch/s390/include/asm/smp.h @@ -16,7 +16,7 @@ extern struct mutex smp_cpu_state_mutex; extern struct save_area *zfcpdump_save_areas[NR_CPUS + 1]; -extern int __cpu_up(unsigned int cpu, struct task_struct *tidle); +extern int __cpu_up(unsigned int cpu); extern void arch_send_call_function_single_ipi(int cpu); extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); diff --git a/trunk/arch/s390/include/asm/thread_info.h b/trunk/arch/s390/include/asm/thread_info.h index 003b04edcff6..a73038155e0d 100644 --- a/trunk/arch/s390/include/asm/thread_info.h +++ b/trunk/arch/s390/include/asm/thread_info.h @@ -95,6 +95,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */ #define TIF_SECCOMP 10 /* secure computing */ #define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */ +#define TIF_SIE 12 /* guest execution active */ #define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_31BIT 17 /* 32bit process */ @@ -113,6 +114,7 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_SYSCALL_AUDIT (1<sas_ss_sp + current->sas_ss_size; } + /* This is the legacy signal stack switching. */ + else if (!user_mode(regs) && + !(ka->sa.sa_flags & SA_RESTORER) && + ka->sa.sa_restorer) { + sp = (unsigned long) ka->sa.sa_restorer; + } + return (void __user *)((sp - frame_size) & -8ul); } diff --git a/trunk/arch/s390/kernel/early.c b/trunk/arch/s390/kernel/early.c index d84181f1f5e8..9475e682727f 100644 --- a/trunk/arch/s390/kernel/early.c +++ b/trunk/arch/s390/kernel/early.c @@ -374,6 +374,8 @@ static __init void detect_machine_facilities(void) S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS; if (test_facility(40)) S390_lowcore.machine_flags |= MACHINE_FLAG_SPP; + if (test_facility(25)) + S390_lowcore.machine_flags |= MACHINE_FLAG_STCKF; #endif } diff --git a/trunk/arch/s390/kernel/entry.S b/trunk/arch/s390/kernel/entry.S index 1ae93b573d7d..74ee563fe62b 100644 --- a/trunk/arch/s390/kernel/entry.S +++ b/trunk/arch/s390/kernel/entry.S @@ -145,23 +145,22 @@ STACK_SIZE = 1 << STACK_SHIFT * gpr2 = prev */ ENTRY(__switch_to) - stm %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task - st %r15,__THREAD_ksp(%r2) # store kernel stack of prev l %r4,__THREAD_info(%r2) # get thread_info of prev l %r5,__THREAD_info(%r3) # get thread_info of next - lr %r15,%r5 - ahi %r15,STACK_SIZE # end of kernel stack of next - st %r3,__LC_CURRENT # store task struct of next - st %r5,__LC_THREAD_INFO # store thread info of next - st %r15,__LC_KERNEL_STACK # store end of kernel stack - lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 - mvc __LC_CURRENT_PID(4,%r0),__TASK_pid(%r3) # store pid of next - l %r15,__THREAD_ksp(%r3) # load kernel stack of next tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending? jz 0f ni __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev oi __TI_flags+3(%r5),_TIF_MCCK_PENDING # set it in next -0: lm %r6,%r15,__SF_GPRS(%r15) # load gprs of next task +0: stm %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task + st %r15,__THREAD_ksp(%r2) # store kernel stack of prev + l %r15,__THREAD_ksp(%r3) # load kernel stack of next + lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 + lm %r6,%r15,__SF_GPRS(%r15) # load gprs of next task + st %r3,__LC_CURRENT # store task struct of next + mvc __LC_CURRENT_PID(4,%r0),__TASK_pid(%r3) # store pid of next + st %r5,__LC_THREAD_INFO # store thread info of next + ahi %r5,STACK_SIZE # end of kernel stack of next + st %r5,__LC_KERNEL_STACK # store end of kernel stack br %r14 __critical_start: diff --git a/trunk/arch/s390/kernel/entry64.S b/trunk/arch/s390/kernel/entry64.S index 229fe1d07749..4e1c292fa7e3 100644 --- a/trunk/arch/s390/kernel/entry64.S +++ b/trunk/arch/s390/kernel/entry64.S @@ -81,14 +81,16 @@ _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) .macro HANDLE_SIE_INTERCEPT scratch #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) - tmhh %r8,0x0001 # interrupting from user ? - jnz .+42 + tm __TI_flags+6(%r12),_TIF_SIE>>8 + jz .+42 + tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP + jz .+8 + .insn s,0xb2800000,BASED(.Lhost_id) # set host id lgr \scratch,%r9 slg \scratch,BASED(.Lsie_loop) clg \scratch,BASED(.Lsie_length) - jhe .+22 + jhe .+10 lg %r9,BASED(.Lsie_loop) - SPP BASED(.Lhost_id) # set host id #endif .endm @@ -146,14 +148,6 @@ _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) ssm __LC_RETURN_PSW .endm - .macro STCK savearea -#ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES - .insn s,0xb27c0000,\savearea # store clock fast -#else - .insn s,0xb2050000,\savearea # store clock -#endif - .endm - .section .kprobes.text, "ax" /* @@ -164,23 +158,22 @@ _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) * gpr2 = prev */ ENTRY(__switch_to) - stmg %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task - stg %r15,__THREAD_ksp(%r2) # store kernel stack of prev lg %r4,__THREAD_info(%r2) # get thread_info of prev lg %r5,__THREAD_info(%r3) # get thread_info of next - lgr %r15,%r5 - aghi %r15,STACK_SIZE # end of kernel stack of next - stg %r3,__LC_CURRENT # store task struct of next - stg %r5,__LC_THREAD_INFO # store thread info of next - stg %r15,__LC_KERNEL_STACK # store end of kernel stack - lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 - mvc __LC_CURRENT_PID+4(4,%r0),__TASK_pid(%r3) # store pid of next - lg %r15,__THREAD_ksp(%r3) # load kernel stack of next tm __TI_flags+7(%r4),_TIF_MCCK_PENDING # machine check pending? jz 0f ni __TI_flags+7(%r4),255-_TIF_MCCK_PENDING # clear flag in prev oi __TI_flags+7(%r5),_TIF_MCCK_PENDING # set it in next -0: lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task +0: stmg %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task + stg %r15,__THREAD_ksp(%r2) # store kernel stack of prev + lg %r15,__THREAD_ksp(%r3) # load kernel stack of next + lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 + lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task + stg %r3,__LC_CURRENT # store task struct of next + mvc __LC_CURRENT_PID+4(4,%r0),__TASK_pid(%r3) # store pid of next + stg %r5,__LC_THREAD_INFO # store thread info of next + aghi %r5,STACK_SIZE # end of kernel stack of next + stg %r5,__LC_KERNEL_STACK # store end of kernel stack br %r14 __critical_start: @@ -465,7 +458,7 @@ pgm_svcper: * IO interrupt handler routine */ ENTRY(io_int_handler) - STCK __LC_INT_CLOCK + stck __LC_INT_CLOCK stpt __LC_ASYNC_ENTER_TIMER stmg %r8,%r15,__LC_SAVE_AREA_ASYNC lg %r10,__LC_LAST_BREAK @@ -611,7 +604,7 @@ io_notify_resume: * External interrupt handler routine */ ENTRY(ext_int_handler) - STCK __LC_INT_CLOCK + stck __LC_INT_CLOCK stpt __LC_ASYNC_ENTER_TIMER stmg %r8,%r15,__LC_SAVE_AREA_ASYNC lg %r10,__LC_LAST_BREAK @@ -629,7 +622,6 @@ ext_skip: mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC stmg %r8,%r9,__PT_PSW(%r11) TRACE_IRQS_OFF - xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) lghi %r1,4096 lgr %r2,%r11 # pass pointer to pt_regs llgf %r3,__LC_EXT_CPU_ADDR # get cpu address + interruption code @@ -646,7 +638,7 @@ ENTRY(psw_idle) larl %r1,psw_idle_lpsw+4 stg %r1,__SF_EMPTY+8(%r15) larl %r1,.Lvtimer_max - STCK __IDLE_ENTER(%r2) + stck __IDLE_ENTER(%r2) ltr %r5,%r5 stpt __VQ_IDLE_ENTER(%r3) jz psw_idle_lpsw @@ -662,7 +654,7 @@ __critical_end: * Machine check handler routines */ ENTRY(mcck_int_handler) - STCK __LC_MCCK_CLOCK + stck __LC_MCCK_CLOCK la %r1,4095 # revalidate r1 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs @@ -975,6 +967,7 @@ ENTRY(sie64a) xc __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # host id == 0 lmg %r0,%r13,0(%r3) # load guest gprs 0-13 lg %r14,__LC_THREAD_INFO # pointer thread_info struct + oi __TI_flags+6(%r14),_TIF_SIE>>8 sie_loop: lg %r14,__LC_THREAD_INFO # pointer thread_info struct tm __TI_flags+7(%r14),_TIF_EXIT_SIE @@ -992,6 +985,7 @@ sie_done: lg %r14,__LC_THREAD_INFO # pointer thread_info struct sie_exit: lctlg %c1,%c1,__LC_USER_ASCE # load primary asce + ni __TI_flags+6(%r14),255-(_TIF_SIE>>8) lg %r14,__SF_EMPTY+8(%r15) # load guest register save area stmg %r0,%r13,0(%r14) # save guest gprs 0-13 lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers @@ -1000,6 +994,7 @@ sie_exit: sie_fault: lctlg %c1,%c1,__LC_USER_ASCE # load primary asce lg %r14,__LC_THREAD_INFO # pointer thread_info struct + ni __TI_flags+6(%r14),255-(_TIF_SIE>>8) lg %r14,__SF_EMPTY+8(%r15) # load guest register save area stmg %r0,%r13,0(%r14) # save guest gprs 0-13 lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers diff --git a/trunk/arch/s390/kernel/head.S b/trunk/arch/s390/kernel/head.S index 4939d15375aa..adccd908ebc7 100644 --- a/trunk/arch/s390/kernel/head.S +++ b/trunk/arch/s390/kernel/head.S @@ -34,7 +34,125 @@ #endif __HEAD +#ifndef CONFIG_IPL + .org 0 + .long 0x00080000,0x80000000+startup # Just a restart PSW +#else +#ifdef CONFIG_IPL_TAPE +#define IPL_BS 1024 + .org 0 + .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded + .long 0x27000000,0x60000001 # by ipl to addresses 0-23. + .long 0x02000000,0x20000000+IPL_BS # (a PSW and two CCWs). + .long 0x00000000,0x00000000 # external old psw + .long 0x00000000,0x00000000 # svc old psw + .long 0x00000000,0x00000000 # program check old psw + .long 0x00000000,0x00000000 # machine check old psw + .long 0x00000000,0x00000000 # io old psw + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x000a0000,0x00000058 # external new psw + .long 0x000a0000,0x00000060 # svc new psw + .long 0x000a0000,0x00000068 # program check new psw + .long 0x000a0000,0x00000070 # machine check new psw + .long 0x00080000,0x80000000+.Lioint # io new psw + .org 0x100 +# +# subroutine for loading from tape +# Parameters: +# R1 = device number +# R2 = load address +.Lloader: + st %r14,.Lldret + la %r3,.Lorbread # r3 = address of orb + la %r5,.Lirb # r5 = address of irb + st %r2,.Lccwread+4 # initialize CCW data addresses + lctl %c6,%c6,.Lcr6 + slr %r2,%r2 +.Lldlp: + la %r6,3 # 3 retries +.Lssch: + ssch 0(%r3) # load chunk of IPL_BS bytes + bnz .Llderr +.Lw4end: + bas %r14,.Lwait4io + tm 8(%r5),0x82 # do we have a problem ? + bnz .Lrecov + slr %r7,%r7 + icm %r7,3,10(%r5) # get residual count + lcr %r7,%r7 + la %r7,IPL_BS(%r7) # IPL_BS-residual=#bytes read + ar %r2,%r7 # add to total size + tm 8(%r5),0x01 # found a tape mark ? + bnz .Ldone + l %r0,.Lccwread+4 # update CCW data addresses + ar %r0,%r7 + st %r0,.Lccwread+4 + b .Lldlp +.Ldone: + l %r14,.Lldret + br %r14 # r2 contains the total size +.Lrecov: + bas %r14,.Lsense # do the sensing + bct %r6,.Lssch # dec. retry count & branch + b .Llderr +# +# Sense subroutine +# +.Lsense: + st %r14,.Lsnsret + la %r7,.Lorbsense + ssch 0(%r7) # start sense command + bnz .Llderr + bas %r14,.Lwait4io + l %r14,.Lsnsret + tm 8(%r5),0x82 # do we have a problem ? + bnz .Llderr + br %r14 +# +# Wait for interrupt subroutine +# +.Lwait4io: + lpsw .Lwaitpsw +.Lioint: + c %r1,0xb8 # compare subchannel number + bne .Lwait4io + tsch 0(%r5) + slr %r0,%r0 + tm 8(%r5),0x82 # do we have a problem ? + bnz .Lwtexit + tm 8(%r5),0x04 # got device end ? + bz .Lwait4io +.Lwtexit: + br %r14 +.Llderr: + lpsw .Lcrash + + .align 8 +.Lorbread: + .long 0x00000000,0x0080ff00,.Lccwread + .align 8 +.Lorbsense: + .long 0x00000000,0x0080ff00,.Lccwsense + .align 8 +.Lccwread: + .long 0x02200000+IPL_BS,0x00000000 +.Lccwsense: + .long 0x04200001,0x00000000 +.Lwaitpsw: + .long 0x020a0000,0x80000000+.Lioint + +.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +.Lcr6: .long 0xff000000 + .align 8 +.Lcrash:.long 0x000a0000,0x00000000 +.Lldret:.long 0 +.Lsnsret: .long 0 +#endif /* CONFIG_IPL_TAPE */ + +#ifdef CONFIG_IPL_VM #define IPL_BS 0x730 .org 0 .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded @@ -138,6 +256,7 @@ __HEAD .long 0x02600050,0x00000000 .endr .long 0x02200050,0x00000000 +#endif /* CONFIG_IPL_VM */ iplstart: lh %r1,0xb8 # test if subchannel number @@ -206,6 +325,7 @@ iplstart: clc 0(3,%r2),.L_eof bz .Lagain2 +#ifdef CONFIG_IPL_VM # # reset files in VM reader # @@ -238,6 +358,7 @@ iplstart: .long 0x00080000,0x80000000+.Lrdrint .Lrdrwaitpsw: .long 0x020a0000,0x80000000+.Lrdrint +#endif # # everything loaded, go for it @@ -255,6 +376,8 @@ iplstart: .L_eof: .long 0xc5d6c600 /* C'EOF' */ .L_hdr: .long 0xc8c4d900 /* C'HDR' */ +#endif /* CONFIG_IPL */ + # # SALIPL loader support. Based on a patch by Rob van der Heij. # This entry point is called directly from the SALIPL loader and diff --git a/trunk/arch/s390/kernel/init_task.c b/trunk/arch/s390/kernel/init_task.c new file mode 100644 index 000000000000..4d1c9fb0b540 --- /dev/null +++ b/trunk/arch/s390/kernel/init_task.c @@ -0,0 +1,38 @@ +/* + * arch/s390/kernel/init_task.c + * + * S390 version + * + * Derived from "arch/i386/kernel/init_task.c" + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +/* + * Initial thread structure. + * + * We need to make sure that this is THREAD_SIZE aligned due to the + * way process stacks are handled. This is done by having a special + * "init_task" linker map entry.. + */ +union thread_union init_thread_union __init_task_data = + { INIT_THREAD_INFO(init_task) }; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); + +EXPORT_SYMBOL(init_task); diff --git a/trunk/arch/s390/kernel/ptrace.c b/trunk/arch/s390/kernel/ptrace.c index 4993e689b2c2..02f300fbf070 100644 --- a/trunk/arch/s390/kernel/ptrace.c +++ b/trunk/arch/s390/kernel/ptrace.c @@ -719,7 +719,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) long ret = 0; /* Do the secure computing check first. */ - secure_computing_strict(regs->gprs[2]); + secure_computing(regs->gprs[2]); /* * The sysc_tracesys code in entry.S stored the system diff --git a/trunk/arch/s390/kernel/signal.c b/trunk/arch/s390/kernel/signal.c index 8a4e2b760d56..f7582b27f600 100644 --- a/trunk/arch/s390/kernel/signal.c +++ b/trunk/arch/s390/kernel/signal.c @@ -235,6 +235,13 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) sp = current->sas_ss_sp + current->sas_ss_size; } + /* This is the legacy signal stack switching. */ + else if (!user_mode(regs) && + !(ka->sa.sa_flags & SA_RESTORER) && + ka->sa.sa_restorer) { + sp = (unsigned long) ka->sa.sa_restorer; + } + return (void __user *)((sp - frame_size) & -8ul); } @@ -407,6 +414,15 @@ void do_signal(struct pt_regs *regs) struct k_sigaction ka; sigset_t *oldset; + /* + * We want the common case to go fast, which + * is why we may in certain cases get here from + * kernel mode. Just return without doing anything + * if so. + */ + if (!user_mode(regs)) + return; + if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index 647ba9425893..1f77227669e8 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -85,6 +85,7 @@ enum { struct pcpu { struct cpu cpu; + struct task_struct *idle; /* idle process for the cpu */ struct _lowcore *lowcore; /* lowcore page(s) for the cpu */ unsigned long async_stack; /* async stack for the cpu */ unsigned long panic_stack; /* panic stack for the cpu */ @@ -225,8 +226,6 @@ static int __cpuinit pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu) return -ENOMEM; } -#ifdef CONFIG_HOTPLUG_CPU - static void pcpu_free_lowcore(struct pcpu *pcpu) { pcpu_sigp_retry(pcpu, sigp_set_prefix, 0); @@ -248,8 +247,6 @@ static void pcpu_free_lowcore(struct pcpu *pcpu) } } -#endif /* CONFIG_HOTPLUG_CPU */ - static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu) { struct _lowcore *lc = pcpu->lowcore; @@ -724,9 +721,26 @@ static void __cpuinit smp_start_secondary(void *cpuvoid) cpu_idle(); } +struct create_idle { + struct work_struct work; + struct task_struct *idle; + struct completion done; + int cpu; +}; + +static void __cpuinit smp_fork_idle(struct work_struct *work) +{ + struct create_idle *c_idle; + + c_idle = container_of(work, struct create_idle, work); + c_idle->idle = fork_idle(c_idle->cpu); + complete(&c_idle->done); +} + /* Upping and downing of CPUs */ -int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) +int __cpuinit __cpu_up(unsigned int cpu) { + struct create_idle c_idle; struct pcpu *pcpu; int rc; @@ -736,12 +750,22 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) if (pcpu_sigp_retry(pcpu, sigp_initial_cpu_reset, 0) != sigp_order_code_accepted) return -EIO; - + if (!pcpu->idle) { + c_idle.done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done); + INIT_WORK_ONSTACK(&c_idle.work, smp_fork_idle); + c_idle.cpu = cpu; + schedule_work(&c_idle.work); + wait_for_completion(&c_idle.done); + if (IS_ERR(c_idle.idle)) + return PTR_ERR(c_idle.idle); + pcpu->idle = c_idle.idle; + } + init_idle(pcpu->idle, cpu); rc = pcpu_alloc_lowcore(pcpu, cpu); if (rc) return rc; pcpu_prepare_secondary(pcpu, cpu); - pcpu_attach_task(pcpu, tidle); + pcpu_attach_task(pcpu, pcpu->idle); pcpu_start_fn(pcpu, smp_start_secondary, NULL); while (!cpu_online(cpu)) cpu_relax(); @@ -828,6 +852,7 @@ void __init smp_prepare_boot_cpu(void) struct pcpu *pcpu = pcpu_devices; boot_cpu_address = stap(); + pcpu->idle = current; pcpu->state = CPU_STATE_CONFIGURED; pcpu->address = boot_cpu_address; pcpu->lowcore = (struct _lowcore *)(unsigned long) store_prefix(); diff --git a/trunk/arch/s390/kernel/vdso32/.gitignore b/trunk/arch/s390/kernel/vdso32/.gitignore deleted file mode 100644 index e45fba9d0ced..000000000000 --- a/trunk/arch/s390/kernel/vdso32/.gitignore +++ /dev/null @@ -1 +0,0 @@ -vdso32.lds diff --git a/trunk/arch/s390/kernel/vdso64/.gitignore b/trunk/arch/s390/kernel/vdso64/.gitignore deleted file mode 100644 index 3fd18cf9fec2..000000000000 --- a/trunk/arch/s390/kernel/vdso64/.gitignore +++ /dev/null @@ -1 +0,0 @@ -vdso64.lds diff --git a/trunk/arch/s390/mm/fault.c b/trunk/arch/s390/mm/fault.c index 72cec9ecd96c..46ef3fd0663b 100644 --- a/trunk/arch/s390/mm/fault.c +++ b/trunk/arch/s390/mm/fault.c @@ -294,7 +294,7 @@ static inline int do_exception(struct pt_regs *regs, int access) down_read(&mm->mmap_sem); #ifdef CONFIG_PGSTE - if ((current->flags & PF_VCPU) && S390_lowcore.gmap) { + if (test_tsk_thread_flag(current, TIF_SIE) && S390_lowcore.gmap) { address = __gmap_fault(address, (struct gmap *) S390_lowcore.gmap); if (address == -EFAULT) { @@ -549,15 +549,19 @@ static void pfault_interrupt(struct ext_code ext_code, if ((subcode & 0xff00) != __SUBCODE_MASK) return; kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++; - /* Get the token (= pid of the affected task). */ - pid = sizeof(void *) == 4 ? param32 : param64; - rcu_read_lock(); - tsk = find_task_by_pid_ns(pid, &init_pid_ns); - if (tsk) - get_task_struct(tsk); - rcu_read_unlock(); - if (!tsk) - return; + if (subcode & 0x0080) { + /* Get the token (= pid of the affected task). */ + pid = sizeof(void *) == 4 ? param32 : param64; + rcu_read_lock(); + tsk = find_task_by_pid_ns(pid, &init_pid_ns); + if (tsk) + get_task_struct(tsk); + rcu_read_unlock(); + if (!tsk) + return; + } else { + tsk = current; + } spin_lock(&pfault_lock); if (subcode & 0x0080) { /* signal bit is set -> a page has been swapped in by VM */ @@ -570,7 +574,6 @@ static void pfault_interrupt(struct ext_code ext_code, tsk->thread.pfault_wait = 0; list_del(&tsk->thread.list); wake_up_process(tsk); - put_task_struct(tsk); } else { /* Completion interrupt was faster than initial * interrupt. Set pfault_wait to -1 so the initial @@ -582,35 +585,24 @@ static void pfault_interrupt(struct ext_code ext_code, if (tsk->state == TASK_RUNNING) tsk->thread.pfault_wait = -1; } + put_task_struct(tsk); } else { /* signal bit not set -> a real page is missing. */ - if (WARN_ON_ONCE(tsk != current)) - goto out; - if (tsk->thread.pfault_wait == 1) { - /* Already on the list with a reference: put to sleep */ - __set_task_state(tsk, TASK_UNINTERRUPTIBLE); - set_tsk_need_resched(tsk); - } else if (tsk->thread.pfault_wait == -1) { + if (tsk->thread.pfault_wait == -1) { /* Completion interrupt was faster than the initial * interrupt (pfault_wait == -1). Set pfault_wait * back to zero and exit. */ tsk->thread.pfault_wait = 0; } else { /* Initial interrupt arrived before completion - * interrupt. Let the task sleep. - * An extra task reference is needed since a different - * cpu may set the task state to TASK_RUNNING again - * before the scheduler is reached. */ - get_task_struct(tsk); + * interrupt. Let the task sleep. */ tsk->thread.pfault_wait = 1; list_add(&tsk->thread.list, &pfault_list); - __set_task_state(tsk, TASK_UNINTERRUPTIBLE); + set_task_state(tsk, TASK_UNINTERRUPTIBLE); set_tsk_need_resched(tsk); } } -out: spin_unlock(&pfault_lock); - put_task_struct(tsk); } static int __cpuinit pfault_cpu_notify(struct notifier_block *self, @@ -628,7 +620,6 @@ static int __cpuinit pfault_cpu_notify(struct notifier_block *self, list_del(&thread->list); tsk = container_of(thread, struct task_struct, thread); wake_up_process(tsk); - put_task_struct(tsk); } spin_unlock_irq(&pfault_lock); break; diff --git a/trunk/arch/s390/mm/hugetlbpage.c b/trunk/arch/s390/mm/hugetlbpage.c index 900de2b3cf28..597bb2d27c3c 100644 --- a/trunk/arch/s390/mm/hugetlbpage.c +++ b/trunk/arch/s390/mm/hugetlbpage.c @@ -58,8 +58,6 @@ void arch_release_hugepage(struct page *page) ptep = (pte_t *) page[1].index; if (!ptep) return; - clear_table((unsigned long *) ptep, _PAGE_TYPE_EMPTY, - PTRS_PER_PTE * sizeof(pte_t)); page_table_free(&init_mm, (unsigned long *) ptep); page[1].index = 0; } diff --git a/trunk/arch/s390/mm/maccess.c b/trunk/arch/s390/mm/maccess.c index 795a0a9bb2eb..e1335dc2b1b7 100644 --- a/trunk/arch/s390/mm/maccess.c +++ b/trunk/arch/s390/mm/maccess.c @@ -12,7 +12,6 @@ #include #include #include -#include #include /* @@ -167,69 +166,3 @@ int copy_from_user_real(void *dest, void __user *src, size_t count) free_page((unsigned long) buf); return rc; } - -/* - * Check if physical address is within prefix or zero page - */ -static int is_swapped(unsigned long addr) -{ - unsigned long lc; - int cpu; - - if (addr < sizeof(struct _lowcore)) - return 1; - for_each_online_cpu(cpu) { - lc = (unsigned long) lowcore_ptr[cpu]; - if (addr > lc + sizeof(struct _lowcore) - 1 || addr < lc) - continue; - return 1; - } - return 0; -} - -/* - * Return swapped prefix or zero page address - */ -static unsigned long get_swapped(unsigned long addr) -{ - unsigned long prefix = store_prefix(); - - if (addr < sizeof(struct _lowcore)) - return addr + prefix; - if (addr >= prefix && addr < prefix + sizeof(struct _lowcore)) - return addr - prefix; - return addr; -} - -/* - * Convert a physical pointer for /dev/mem access - * - * For swapped prefix pages a new buffer is returned that contains a copy of - * the absolute memory. The buffer size is maximum one page large. - */ -void *xlate_dev_mem_ptr(unsigned long addr) -{ - void *bounce = (void *) addr; - unsigned long size; - - get_online_cpus(); - preempt_disable(); - if (is_swapped(addr)) { - size = PAGE_SIZE - (addr & ~PAGE_MASK); - bounce = (void *) __get_free_page(GFP_ATOMIC); - if (bounce) - memcpy_real(bounce, (void *) get_swapped(addr), size); - } - preempt_enable(); - put_online_cpus(); - return bounce; -} - -/* - * Free converted buffer for /dev/mem access (if necessary) - */ -void unxlate_dev_mem_ptr(unsigned long addr, void *buf) -{ - if ((void *) addr != buf) - free_page((unsigned long) buf); -} diff --git a/trunk/arch/s390/mm/pgtable.c b/trunk/arch/s390/mm/pgtable.c index a3db5a3ea083..6e765bf00670 100644 --- a/trunk/arch/s390/mm/pgtable.c +++ b/trunk/arch/s390/mm/pgtable.c @@ -822,8 +822,6 @@ int s390_enable_sie(void) /* we copy the mm and let dup_mm create the page tables with_pgstes */ tsk->mm->context.alloc_pgste = 1; - /* make sure that both mms have a correct rss state */ - sync_mm_rss(tsk->mm); mm = dup_mm(tsk); tsk->mm->context.alloc_pgste = 0; if (!mm) diff --git a/trunk/arch/score/include/asm/thread_info.h b/trunk/arch/score/include/asm/thread_info.h index a18006e97f1c..2205c62284db 100644 --- a/trunk/arch/score/include/asm/thread_info.h +++ b/trunk/arch/score/include/asm/thread_info.h @@ -11,9 +11,10 @@ #include /* thread information allocation */ -#define THREAD_SIZE_ORDER (1) -#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) -#define THREAD_MASK (THREAD_SIZE - _AC(1,UL)) +#define THREAD_SIZE_ORDER (1) +#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) +#define THREAD_MASK (THREAD_SIZE - _AC(1,UL)) +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR #ifndef __ASSEMBLY__ @@ -70,6 +71,9 @@ struct thread_info { register struct thread_info *__current_thread_info __asm__("r28"); #define current_thread_info() __current_thread_info +#define alloc_thread_info_node(tsk, node) kmalloc_node(THREAD_SIZE, GFP_KERNEL, node) +#define free_thread_info(info) kfree(info) + #endif /* !__ASSEMBLY__ */ #define PREEMPT_ACTIVE 0x10000000 diff --git a/trunk/arch/score/kernel/Makefile b/trunk/arch/score/kernel/Makefile index fb1802b3f542..f218673b5d3d 100644 --- a/trunk/arch/score/kernel/Makefile +++ b/trunk/arch/score/kernel/Makefile @@ -4,7 +4,7 @@ extra-y := head.o vmlinux.lds -obj-y += entry.o irq.o process.o ptrace.o \ +obj-y += entry.o init_task.o irq.o process.o ptrace.o \ setup.o signal.o sys_score.o time.o traps.o \ sys_call_table.o diff --git a/trunk/arch/score/kernel/init_task.c b/trunk/arch/score/kernel/init_task.c new file mode 100644 index 000000000000..baa03ee217d1 --- /dev/null +++ b/trunk/arch/score/kernel/init_task.c @@ -0,0 +1,46 @@ +/* + * arch/score/kernel/init_task.c + * + * Score Processor version. + * + * Copyright (C) 2009 Sunplus Core Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); + +/* + * Initial thread structure. + * + * We need to make sure that this is THREAD_SIZE aligned due to the + * way process stacks are handled. This is done by having a special + * "init_task" linker map entry.. + */ +union thread_union init_thread_union __init_task_data = + { INIT_THREAD_INFO(init_task) }; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); +EXPORT_SYMBOL(init_task); diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig index 04a8cb4700af..ff9e033ce626 100644 --- a/trunk/arch/sh/Kconfig +++ b/trunk/arch/sh/Kconfig @@ -28,7 +28,6 @@ config SUPERH select RTC_LIB select GENERIC_ATOMIC64 select GENERIC_IRQ_SHOW - select GENERIC_SMP_IDLE_THREAD help The SuperH is a RISC processor targeted for use in embedded systems and consumer electronics; it was also used in the Sega Dreamcast @@ -153,6 +152,9 @@ config ARCH_NO_VIRT_TO_BUS config ARCH_HAS_DEFAULT_IDLE def_bool y +config ARCH_HAS_CPU_IDLE_WAIT + def_bool y + config NO_IOPORT def_bool !PCI depends on !SH_CAYMAN && !SH_SH4202_MICRODEV && !SH_SHMIN diff --git a/trunk/arch/sh/Makefile b/trunk/arch/sh/Makefile index e14a676a0c7d..3fc0f413777c 100644 --- a/trunk/arch/sh/Makefile +++ b/trunk/arch/sh/Makefile @@ -124,7 +124,7 @@ endif export ld-bfd BITS -head-y := arch/sh/kernel/head_$(BITS).o +head-y := arch/sh/kernel/init_task.o arch/sh/kernel/head_$(BITS).o core-y += arch/sh/kernel/ arch/sh/mm/ arch/sh/boards/ core-$(CONFIG_SH_FPU_EMU) += arch/sh/math-emu/ diff --git a/trunk/arch/sh/include/asm/processor.h b/trunk/arch/sh/include/asm/processor.h index 6dbc1be28a0f..a229c393826a 100644 --- a/trunk/arch/sh/include/asm/processor.h +++ b/trunk/arch/sh/include/asm/processor.h @@ -85,6 +85,10 @@ struct sh_cpuinfo { struct tlb_info itlb; struct tlb_info dtlb; +#ifdef CONFIG_SMP + struct task_struct *idle; +#endif + unsigned int phys_bits; unsigned long flags; } __attribute__ ((aligned(L1_CACHE_BYTES))); @@ -98,6 +102,7 @@ extern struct sh_cpuinfo cpu_data[]; #define cpu_relax() barrier() void default_idle(void); +void cpu_idle_wait(void); void stop_this_cpu(void *); /* Forward decl */ diff --git a/trunk/arch/sh/include/asm/thread_info.h b/trunk/arch/sh/include/asm/thread_info.h index b6902061d4dc..20ee40af16e9 100644 --- a/trunk/arch/sh/include/asm/thread_info.h +++ b/trunk/arch/sh/include/asm/thread_info.h @@ -88,13 +88,22 @@ static inline struct thread_info *current_thread_info(void) return ti; } +/* thread information allocation */ +#if THREAD_SHIFT >= PAGE_SHIFT + #define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT) +#endif + +extern struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node); +extern void free_thread_info(struct thread_info *ti); extern void arch_task_cache_init(void); +#define arch_task_cache_init arch_task_cache_init extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src); -extern void arch_release_task_struct(struct task_struct *tsk); extern void init_thread_xstate(void); +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + #endif /* __ASSEMBLY__ */ /* diff --git a/trunk/arch/sh/kernel/Makefile b/trunk/arch/sh/kernel/Makefile index 88571ff8eeec..77f7ae1d4647 100644 --- a/trunk/arch/sh/kernel/Makefile +++ b/trunk/arch/sh/kernel/Makefile @@ -2,7 +2,7 @@ # Makefile for the Linux/SuperH kernel. # -extra-y := head_$(BITS).o vmlinux.lds +extra-y := head_$(BITS).o init_task.o vmlinux.lds ifdef CONFIG_FUNCTION_TRACER # Do not profile debug and lowlevel utilities diff --git a/trunk/arch/sh/kernel/idle.c b/trunk/arch/sh/kernel/idle.c index 0c910163caa3..ee226e20c20c 100644 --- a/trunk/arch/sh/kernel/idle.c +++ b/trunk/arch/sh/kernel/idle.c @@ -132,6 +132,10 @@ void __init select_idle_routine(void) pm_idle = poll_idle; } +static void do_nothing(void *unused) +{ +} + void stop_this_cpu(void *unused) { local_irq_disable(); @@ -140,3 +144,19 @@ void stop_this_cpu(void *unused) for (;;) cpu_sleep(); } + +/* + * cpu_idle_wait - Used to ensure that all the CPUs discard old value of + * pm_idle and update to new pm_idle value. Required while changing pm_idle + * handler on SMP systems. + * + * Caller must have changed pm_idle to the new value before the call. Old + * pm_idle value will not be used by any CPU after the return of this function. + */ +void cpu_idle_wait(void) +{ + smp_mb(); + /* kick all the CPUs so that they exit out of pm_idle */ + smp_call_function(do_nothing, NULL, 1); +} +EXPORT_SYMBOL_GPL(cpu_idle_wait); diff --git a/trunk/arch/sh/kernel/init_task.c b/trunk/arch/sh/kernel/init_task.c new file mode 100644 index 000000000000..11f2ea556a6b --- /dev/null +++ b/trunk/arch/sh/kernel/init_task.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +struct pt_regs fake_swapper_regs; +/* + * Initial thread structure. + * + * We need to make sure that this is 8192-byte aligned due to the + * way process stacks are handled. This is done by having a special + * "init_task" linker map entry.. + */ +union thread_union init_thread_union __init_task_data = + { INIT_THREAD_INFO(init_task) }; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); + +EXPORT_SYMBOL(init_task); diff --git a/trunk/arch/sh/kernel/process.c b/trunk/arch/sh/kernel/process.c index f2621abdf01d..325f98b1736d 100644 --- a/trunk/arch/sh/kernel/process.c +++ b/trunk/arch/sh/kernel/process.c @@ -29,10 +29,52 @@ void free_thread_xstate(struct task_struct *tsk) } } -void arch_release_task_struct(struct task_struct *tsk) +#if THREAD_SHIFT < PAGE_SHIFT +static struct kmem_cache *thread_info_cache; + +struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node) +{ + struct thread_info *ti; +#ifdef CONFIG_DEBUG_STACK_USAGE + gfp_t mask = GFP_KERNEL | __GFP_ZERO; +#else + gfp_t mask = GFP_KERNEL; +#endif + + ti = kmem_cache_alloc_node(thread_info_cache, mask, node); + return ti; +} + +void free_thread_info(struct thread_info *ti) +{ + free_thread_xstate(ti->task); + kmem_cache_free(thread_info_cache, ti); +} + +void thread_info_cache_init(void) +{ + thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE, + THREAD_SIZE, SLAB_PANIC, NULL); +} +#else +struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node) +{ +#ifdef CONFIG_DEBUG_STACK_USAGE + gfp_t mask = GFP_KERNEL | __GFP_ZERO; +#else + gfp_t mask = GFP_KERNEL; +#endif + struct page *page = alloc_pages_node(node, mask, THREAD_SIZE_ORDER); + + return page ? page_address(page) : NULL; +} + +void free_thread_info(struct thread_info *ti) { - free_thread_xstate(tsk); + free_thread_xstate(ti->task); + free_pages((unsigned long)ti, THREAD_SIZE_ORDER); } +#endif /* THREAD_SHIFT < PAGE_SHIFT */ void arch_task_cache_init(void) { diff --git a/trunk/arch/sh/kernel/ptrace_32.c b/trunk/arch/sh/kernel/ptrace_32.c index 81f999a672f6..9698671444e6 100644 --- a/trunk/arch/sh/kernel/ptrace_32.c +++ b/trunk/arch/sh/kernel/ptrace_32.c @@ -503,7 +503,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) { long ret = 0; - secure_computing_strict(regs->regs[0]); + secure_computing(regs->regs[0]); if (test_thread_flag(TIF_SYSCALL_TRACE) && tracehook_report_syscall_entry(regs)) diff --git a/trunk/arch/sh/kernel/ptrace_64.c b/trunk/arch/sh/kernel/ptrace_64.c index af90339dadcd..bc81e07dc098 100644 --- a/trunk/arch/sh/kernel/ptrace_64.c +++ b/trunk/arch/sh/kernel/ptrace_64.c @@ -522,7 +522,7 @@ asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs) { long long ret = 0; - secure_computing_strict(regs->regs[9]); + secure_computing(regs->regs[9]); if (test_thread_flag(TIF_SYSCALL_TRACE) && tracehook_report_syscall_entry(regs)) diff --git a/trunk/arch/sh/kernel/smp.c b/trunk/arch/sh/kernel/smp.c index b86e9ca79455..eaebdf6a5c77 100644 --- a/trunk/arch/sh/kernel/smp.c +++ b/trunk/arch/sh/kernel/smp.c @@ -220,10 +220,22 @@ extern struct { void *thread_info; } stack_start; -int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tsk) +int __cpuinit __cpu_up(unsigned int cpu) { + struct task_struct *tsk; unsigned long timeout; + tsk = cpu_data[cpu].idle; + if (!tsk) { + tsk = fork_idle(cpu); + if (IS_ERR(tsk)) { + pr_err("Failed forking idle task for cpu %d\n", cpu); + return PTR_ERR(tsk); + } + + cpu_data[cpu].idle = tsk; + } + per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; /* Fill in data in head.S for secondary cpus */ diff --git a/trunk/arch/sparc/Kbuild b/trunk/arch/sparc/Kbuild deleted file mode 100644 index 5cd01161fd00..000000000000 --- a/trunk/arch/sparc/Kbuild +++ /dev/null @@ -1,8 +0,0 @@ -# -# core part of the sparc kernel -# - -obj-y += kernel/ -obj-y += mm/ -obj-y += math-emu/ -obj-y += net/ diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig index 1ea3fd954756..5f6acce45a0d 100644 --- a/trunk/arch/sparc/Kconfig +++ b/trunk/arch/sparc/Kconfig @@ -31,13 +31,11 @@ config SPARC select GENERIC_PCI_IOMAP select HAVE_NMI_WATCHDOG if SPARC64 select HAVE_BPF_JIT - select GENERIC_SMP_IDLE_THREAD config SPARC32 def_bool !64BIT select GENERIC_ATOMIC64 select CLZ_TAB - select ARCH_THREAD_INFO_ALLOCATOR config SPARC64 def_bool 64BIT @@ -64,7 +62,6 @@ config SPARC64 select IRQ_PREFLOW_FASTEOI select ARCH_HAVE_NMI_SAFE_CMPXCHG select HAVE_C_RECORDMCOUNT - select NO_BOOTMEM config ARCH_DEFCONFIG string @@ -77,12 +74,17 @@ config BITS default 32 if SPARC32 default 64 if SPARC64 +config ARCH_USES_GETTIMEOFFSET + bool + default y if SPARC32 + config GENERIC_CMOS_UPDATE bool default y config GENERIC_CLOCKEVENTS - def_bool y + bool + default y if SPARC64 config IOMMU_HELPER bool @@ -153,7 +155,7 @@ source "kernel/Kconfig.freezer" menu "Processor type and features" config SMP - bool "Symmetric multi-processing support" + bool "Symmetric multi-processing support (does not work on sun4/sun4c)" ---help--- This enables support for systems with more than one CPU. If you have a system with only one CPU, say N. If you have a system with more @@ -583,9 +585,6 @@ config SYSVIPC_COMPAT depends on COMPAT && SYSVIPC default y -config KEYS_COMPAT - def_bool y if COMPAT && KEYS - endmenu source "net/Kconfig" diff --git a/trunk/arch/sparc/Makefile b/trunk/arch/sparc/Makefile index 541b8b075c7d..0e5de13b56c5 100644 --- a/trunk/arch/sparc/Makefile +++ b/trunk/arch/sparc/Makefile @@ -19,27 +19,39 @@ ifeq ($(CONFIG_SPARC32),y) # sparc32 # -CHECKFLAGS += -D__sparc__ +# +# Uncomment the first KBUILD_CFLAGS if you are doing kgdb source level +# debugging of the kernel to get the proper debugging information. + +AS := $(AS) -32 LDFLAGS := -m elf32_sparc +CHECKFLAGS += -D__sparc__ export BITS := 32 UTS_MACHINE := sparc -KBUILD_CFLAGS += -m32 -mcpu=v8 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7 -KBUILD_AFLAGS += -m32 -Wa,-Av8 +#KBUILD_CFLAGS += -g -pipe -fcall-used-g5 -fcall-used-g7 +KBUILD_CFLAGS += -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7 +KBUILD_AFLAGS += -m32 -Wa,-Av8 + +#LDFLAGS_vmlinux = -N -Ttext 0xf0004000 +# Since 2.5.40, the first stage is left not btfix-ed. +# Actual linking is done with "make image". +LDFLAGS_vmlinux = -r else ##### # sparc64 # -CHECKFLAGS += -D__sparc__ -D__sparc_v9__ -D__arch64__ -m64 -LDFLAGS := -m elf64_sparc -export BITS := 64 -UTS_MACHINE := sparc64 +CHECKFLAGS += -D__sparc__ -D__sparc_v9__ -D__arch64__ -m64 -KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow -KBUILD_CFLAGS += -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare -KBUILD_CFLAGS += -Wa,--undeclared-regs +LDFLAGS := -m elf64_sparc +export BITS := 64 +UTS_MACHINE := sparc64 + +KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow \ + -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare \ + -Wa,--undeclared-regs KBUILD_CFLAGS += $(call cc-option,-mtune=ultrasparc3) KBUILD_AFLAGS += -m64 -mcpu=ultrasparc -Wa,--undeclared-regs @@ -50,15 +62,28 @@ endif endif head-y := arch/sparc/kernel/head_$(BITS).o +head-y += arch/sparc/kernel/init_task.o -# See arch/sparc/Kbuild for the core part of the kernel -core-y += arch/sparc/ +core-y += arch/sparc/kernel/ +core-y += arch/sparc/mm/ arch/sparc/math-emu/ +core-y += arch/sparc/net/ libs-y += arch/sparc/prom/ libs-y += arch/sparc/lib/ drivers-$(CONFIG_OPROFILE) += arch/sparc/oprofile/ +# Export what is needed by arch/sparc/boot/Makefile +export VMLINUX_INIT VMLINUX_MAIN +VMLINUX_INIT := $(head-y) $(init-y) +VMLINUX_MAIN := $(core-y) kernel/ mm/ fs/ ipc/ security/ crypto/ block/ +VMLINUX_MAIN += $(patsubst %/, %/lib.a, $(libs-y)) $(libs-y) +VMLINUX_MAIN += $(drivers-y) $(net-y) + +ifdef CONFIG_KALLSYMS +export kallsyms.o := .tmp_kallsyms2.o +endif + boot := arch/sparc/boot # Default target diff --git a/trunk/arch/sparc/boot/Makefile b/trunk/arch/sparc/boot/Makefile index 6e63afb128d9..d56d199c1aa8 100644 --- a/trunk/arch/sparc/boot/Makefile +++ b/trunk/arch/sparc/boot/Makefile @@ -6,8 +6,8 @@ ROOT_IMG := /usr/src/root.img ELFTOAOUT := elftoaout -hostprogs-y := piggyback -targets := tftpboot.img image zImage vmlinux.aout +hostprogs-y := piggyback btfixupprep +targets := tftpboot.img btfix.o btfix.S image zImage vmlinux.aout clean-files := System.map quiet_cmd_elftoaout = ELFTOAOUT $@ @@ -17,9 +17,58 @@ quiet_cmd_piggy = PIGGY $@ quiet_cmd_strip = STRIP $@ cmd_strip = $(STRIP) -R .comment -R .note -K sun4u_init -K _end -K _start $< -o $@ +ifeq ($(CONFIG_SPARC32),y) +quiet_cmd_btfix = BTFIX $@ + cmd_btfix = $(OBJDUMP) -x vmlinux | $(obj)/btfixupprep > $@ +quiet_cmd_sysmap = SYSMAP $(obj)/System.map + cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap +quiet_cmd_image = LD $@ + cmd_image = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_$(@F)) -o $@ + +define rule_image + $(if $($(quiet)cmd_image), \ + echo ' $($(quiet)cmd_image)' &&) \ + $(cmd_image); \ + $(if $($(quiet)cmd_sysmap), \ + echo ' $($(quiet)cmd_sysmap)' &&) \ + $(cmd_sysmap) $@ $(obj)/System.map; \ + if [ $$? -ne 0 ]; then \ + rm -f $@; \ + /bin/false; \ + fi; \ + echo 'cmd_$@ := $(cmd_image)' > $(@D)/.$(@F).cmd +endef + +BTOBJS := $(patsubst %/, %/built-in.o, $(VMLINUX_INIT)) +BTLIBS := $(patsubst %/, %/built-in.o, $(VMLINUX_MAIN)) +LDFLAGS_image := -T arch/sparc/kernel/vmlinux.lds $(BTOBJS) \ + --start-group $(BTLIBS) --end-group \ + $(kallsyms.o) $(obj)/btfix.o + +# Link the final image including btfixup'ed symbols. +# This is a replacement for the link done in the top-level Makefile. +# Note: No dependency on the prerequisite files since that would require +# make to try check if they are updated - and due to changes +# in gcc options (path for example) this would result in +# these files being recompiled for each build. +$(obj)/image: $(obj)/btfix.o FORCE + $(call if_changed_rule,image) + +$(obj)/zImage: $(obj)/image + $(call if_changed,strip) + @echo ' kernel: $@ is ready' + +$(obj)/btfix.S: $(obj)/btfixupprep vmlinux FORCE + $(call if_changed,btfix) + +endif + ifeq ($(CONFIG_SPARC64),y) # Actual linking +$(obj)/image: vmlinux FORCE + $(call if_changed,strip) + @echo ' kernel: $@ is ready' $(obj)/zImage: $(obj)/image $(call if_changed,gzip) @@ -30,10 +79,6 @@ $(obj)/vmlinux.aout: vmlinux FORCE @echo ' kernel: $@ is ready' else -$(obj)/zImage: $(obj)/image - $(call if_changed,strip) - @echo ' kernel: $@ is ready' - # The following lines make a readable image for U-Boot. # uImage - Binary file read by U-boot # uImage.o - object file of uImage for loading with a @@ -62,10 +107,6 @@ $(obj)/uImage: $(obj)/image.gz endif -$(obj)/image: vmlinux FORCE - $(call if_changed,strip) - @echo ' kernel: $@ is ready' - $(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback System.map $(ROOT_IMG) FORCE $(call if_changed,elftoaout) $(call if_changed,piggy) diff --git a/trunk/arch/sparc/boot/btfixupprep.c b/trunk/arch/sparc/boot/btfixupprep.c new file mode 100644 index 000000000000..da031159e2b7 --- /dev/null +++ b/trunk/arch/sparc/boot/btfixupprep.c @@ -0,0 +1,386 @@ +/* + Simple utility to prepare vmlinux image for sparc. + Resolves all BTFIXUP uses and settings and creates + a special .s object to link to the image. + + Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include +#include +#include +#include +#include +#include +#include + +#define MAXSYMS 1024 + +static char *symtab = "SYMBOL TABLE:"; +static char *relrec = "RELOCATION RECORDS FOR ["; +static int rellen; +static int symlen; +int mode; + +struct _btfixup; + +typedef struct _btfixuprel { + char *sect; + unsigned long offset; + struct _btfixup *f; + int frel; + struct _btfixuprel *next; +} btfixuprel; + +typedef struct _btfixup { + int type; + int setinitval; + unsigned int initval; + char *initvalstr; + char *name; + btfixuprel *rel; +} btfixup; + +btfixup array[MAXSYMS]; +int last = 0; +char buffer[1024]; +unsigned long lastfoffset = -1; +unsigned long lastfrelno; +btfixup *lastf; + +static void fatal(void) __attribute__((noreturn)); +static void fatal(void) +{ + fprintf(stderr, "Malformed output from objdump\n%s\n", buffer); + exit(1); +} + +static btfixup *find(int type, char *name) +{ + int i; + for (i = 0; i < last; i++) { + if (array[i].type == type && !strcmp(array[i].name, name)) + return array + i; + } + array[last].type = type; + array[last].name = strdup(name); + array[last].setinitval = 0; + if (!array[last].name) fatal(); + array[last].rel = NULL; + last++; + if (last >= MAXSYMS) { + fprintf(stderr, "Ugh. Something strange. More than %d different BTFIXUP symbols\n", MAXSYMS); + exit(1); + } + return array + last - 1; +} + +static void set_mode (char *buffer) +{ + for (mode = 0;; mode++) + if (buffer[mode] < '0' || buffer[mode] > '9') + break; + if (mode != 8 && mode != 16) + fatal(); +} + + +int main(int argc,char **argv) +{ + char *p, *q; + char *sect; + int i, j, k; + unsigned int initval; + int shift; + btfixup *f; + btfixuprel *r, **rr; + unsigned long offset; + char *initvalstr; + + symlen = strlen(symtab); + while (fgets (buffer, 1024, stdin) != NULL) + if (!strncmp (buffer, symtab, symlen)) + goto main0; + fatal(); +main0: + rellen = strlen(relrec); + while (fgets (buffer, 1024, stdin) != NULL) + if (!strncmp (buffer, relrec, rellen)) + goto main1; + fatal(); +main1: + sect = malloc(strlen (buffer + rellen) + 1); + if (!sect) fatal(); + strcpy (sect, buffer + rellen); + p = strchr (sect, ']'); + if (!p) fatal(); + *p = 0; + if (fgets (buffer, 1024, stdin) == NULL) + fatal(); + while (fgets (buffer, 1024, stdin) != NULL) { + int nbase; + if (!strncmp (buffer, relrec, rellen)) + goto main1; + if (mode == 0) + set_mode (buffer); + p = strchr (buffer, '\n'); + if (p) *p = 0; + if (strlen (buffer) < 22+mode) + continue; + if (strncmp (buffer + mode, " R_SPARC_", 9)) + continue; + nbase = 27 - 8 + mode; + if (buffer[nbase] != '_' || buffer[nbase+1] != '_' || buffer[nbase+2] != '_') + continue; + switch (buffer[nbase+3]) { + case 'f': /* CALL */ + case 'b': /* BLACKBOX */ + case 's': /* SIMM13 */ + case 'a': /* HALF */ + case 'h': /* SETHI */ + case 'i': /* INT */ + break; + default: + continue; + } + p = strchr (buffer + nbase+5, '+'); + if (p) *p = 0; + shift = nbase + 5; + if (buffer[nbase+4] == 's' && buffer[nbase+5] == '_') { + shift = nbase + 6; + if (strcmp (sect, ".init.text")) { + fprintf(stderr, + "Wrong use of '%s' BTFIXUPSET in '%s' section.\n" + "BTFIXUPSET_CALL can be used only in" + " __init sections\n", + buffer + shift, sect); + exit(1); + } + } else if (buffer[nbase+4] != '_') + continue; + if (!strcmp (sect, ".text.exit")) + continue; + if (strcmp (sect, ".text") && + strcmp (sect, ".init.text") && + strcmp (sect, ".fixup") && + (strcmp (sect, "__ksymtab") || buffer[nbase+3] != 'f')) { + if (buffer[nbase+3] == 'f') + fprintf(stderr, + "Wrong use of '%s' in '%s' section.\n" + " It can be used only in .text, .init.text," + " .fixup and __ksymtab\n", + buffer + shift, sect); + else + fprintf(stderr, + "Wrong use of '%s' in '%s' section.\n" + " It can be only used in .text, .init.text," + " and .fixup\n", buffer + shift, sect); + exit(1); + } + p = strstr (buffer + shift, "__btset_"); + if (p && buffer[nbase+4] == 's') { + fprintf(stderr, "__btset_ in BTFIXUP name can only be used when defining the variable, not for setting\n%s\n", buffer); + exit(1); + } + initval = 0; + initvalstr = NULL; + if (p) { + if (p[8] != '0' || p[9] != 'x') { + fprintf(stderr, "Pre-initialized values can be only initialized with hexadecimal constants starting 0x\n%s\n", buffer); + exit(1); + } + initval = strtoul(p + 10, &q, 16); + if (*q || !initval) { + fprintf(stderr, "Pre-initialized values can be only in the form name__btset_0xXXXXXXXX where X are hex digits.\nThey cannot be name__btset_0x00000000 though. Use BTFIXUPDEF_XX instead of BTFIXUPDEF_XX_INIT then.\n%s\n", buffer); + exit(1); + } + initvalstr = p + 10; + *p = 0; + } + f = find(buffer[nbase+3], buffer + shift); + if (buffer[nbase+4] == 's') + continue; + switch (buffer[nbase+3]) { + case 'f': + if (initval) { + fprintf(stderr, "Cannot use pre-initialized fixups for calls\n%s\n", buffer); + exit(1); + } + if (!strcmp (sect, "__ksymtab")) { + if (strncmp (buffer + mode+9, "32 ", 10)) { + fprintf(stderr, "BTFIXUP_CALL in EXPORT_SYMBOL results in relocation other than R_SPARC_32\n\%s\n", buffer); + exit(1); + } + } else if (strncmp (buffer + mode+9, "WDISP30 ", 10) && + strncmp (buffer + mode+9, "HI22 ", 10) && + strncmp (buffer + mode+9, "LO10 ", 10)) { + fprintf(stderr, "BTFIXUP_CALL results in relocation other than R_SPARC_WDISP30, R_SPARC_HI22 or R_SPARC_LO10\n%s\n", buffer); + exit(1); + } + break; + case 'b': + if (initval) { + fprintf(stderr, "Cannot use pre-initialized fixups for blackboxes\n%s\n", buffer); + exit(1); + } + if (strncmp (buffer + mode+9, "HI22 ", 10)) { + fprintf(stderr, "BTFIXUP_BLACKBOX results in relocation other than R_SPARC_HI22\n%s\n", buffer); + exit(1); + } + break; + case 's': + if (initval + 0x1000 >= 0x2000) { + fprintf(stderr, "Wrong initializer for SIMM13. Has to be from $fffff000 to $00000fff\n%s\n", buffer); + exit(1); + } + if (strncmp (buffer + mode+9, "13 ", 10)) { + fprintf(stderr, "BTFIXUP_SIMM13 results in relocation other than R_SPARC_13\n%s\n", buffer); + exit(1); + } + break; + case 'a': + if (initval + 0x1000 >= 0x2000 && (initval & 0x3ff)) { + fprintf(stderr, "Wrong initializer for HALF.\n%s\n", buffer); + exit(1); + } + if (strncmp (buffer + mode+9, "13 ", 10)) { + fprintf(stderr, "BTFIXUP_HALF results in relocation other than R_SPARC_13\n%s\n", buffer); + exit(1); + } + break; + case 'h': + if (initval & 0x3ff) { + fprintf(stderr, "Wrong initializer for SETHI. Cannot have set low 10 bits\n%s\n", buffer); + exit(1); + } + if (strncmp (buffer + mode+9, "HI22 ", 10)) { + fprintf(stderr, "BTFIXUP_SETHI results in relocation other than R_SPARC_HI22\n%s\n", buffer); + exit(1); + } + break; + case 'i': + if (initval) { + fprintf(stderr, "Cannot use pre-initialized fixups for INT\n%s\n", buffer); + exit(1); + } + if (strncmp (buffer + mode+9, "HI22 ", 10) && strncmp (buffer + mode+9, "LO10 ", 10)) { + fprintf(stderr, "BTFIXUP_INT results in relocation other than R_SPARC_HI22 and R_SPARC_LO10\n%s\n", buffer); + exit(1); + } + break; + } + if (!f->setinitval) { + f->initval = initval; + if (initvalstr) { + f->initvalstr = strdup(initvalstr); + if (!f->initvalstr) fatal(); + } + f->setinitval = 1; + } else if (f->initval != initval) { + fprintf(stderr, "Btfixup %s previously used with initializer %s which doesn't match with current initializer\n%s\n", + f->name, f->initvalstr ? : "0x00000000", buffer); + exit(1); + } else if (initval && strcmp(f->initvalstr, initvalstr)) { + fprintf(stderr, "Btfixup %s previously used with initializer %s which doesn't match with current initializer.\n" + "Initializers have to match literally as well.\n%s\n", + f->name, f->initvalstr, buffer); + exit(1); + } + offset = strtoul(buffer, &q, 16); + if (q != buffer + mode || (!offset && (mode == 8 ? strncmp (buffer, "00000000 ", 9) : strncmp (buffer, "0000000000000000 ", 17)))) { + fprintf(stderr, "Malformed relocation address in\n%s\n", buffer); + exit(1); + } + for (k = 0, r = f->rel, rr = &f->rel; r; rr = &r->next, r = r->next, k++) + if (r->offset == offset && !strcmp(r->sect, sect)) { + fprintf(stderr, "Ugh. One address has two relocation records\n"); + exit(1); + } + *rr = malloc(sizeof(btfixuprel)); + if (!*rr) fatal(); + (*rr)->offset = offset; + (*rr)->f = NULL; + if (buffer[nbase+3] == 'f') { + lastf = f; + lastfoffset = offset; + lastfrelno = k; + } else if (lastfoffset + 4 == offset) { + (*rr)->f = lastf; + (*rr)->frel = lastfrelno; + } + (*rr)->sect = sect; + (*rr)->next = NULL; + } + printf("! Generated by btfixupprep. Do not edit.\n\n"); + printf("\t.section\t\".data..init\",#alloc,#write\n\t.align\t4\n\n"); + printf("\t.global\t___btfixup_start\n___btfixup_start:\n\n"); + for (i = 0; i < last; i++) { + f = array + i; + printf("\t.global\t___%cs_%s\n", f->type, f->name); + if (f->type == 'f') + printf("___%cs_%s:\n\t.word 0x%08x,0,0,", f->type, f->name, f->type << 24); + else + printf("___%cs_%s:\n\t.word 0x%08x,0,", f->type, f->name, f->type << 24); + for (j = 0, r = f->rel; r != NULL; j++, r = r->next); + if (j) + printf("%d\n\t.word\t", j * 2); + else + printf("0\n"); + for (r = f->rel, j--; r != NULL; j--, r = r->next) { + if (!strcmp (r->sect, ".text")) + printf ("_stext+0x%08lx", r->offset); + else if (!strcmp (r->sect, ".init.text")) + printf ("__init_begin+0x%08lx", r->offset); + else if (!strcmp (r->sect, "__ksymtab")) + printf ("__start___ksymtab+0x%08lx", r->offset); + else if (!strcmp (r->sect, ".fixup")) + printf ("__start___fixup+0x%08lx", r->offset); + else + fatal(); + if (f->type == 'f' || !r->f) + printf (",0"); + else + printf (",___fs_%s+0x%08x", r->f->name, (4 + r->frel*2)*4 + 4); + if (j) printf (","); + else printf ("\n"); + } + printf("\n"); + } + printf("\n\t.global\t___btfixup_end\n___btfixup_end:\n"); + printf("\n\n! Define undefined references\n\n"); + for (i = 0; i < last; i++) { + f = array + i; + if (f->type == 'f') { + printf("\t.global\t___f_%s\n", f->name); + printf("___f_%s:\n", f->name); + } + } + printf("\tretl\n\t nop\n\n"); + for (i = 0; i < last; i++) { + f = array + i; + if (f->type != 'f') { + if (!f->initval) { + printf("\t.global\t___%c_%s\n", f->type, f->name); + printf("___%c_%s = 0\n", f->type, f->name); + } else { + printf("\t.global\t___%c_%s__btset_0x%s\n", f->type, f->name, f->initvalstr); + printf("___%c_%s__btset_0x%s = 0x%08x\n", f->type, f->name, f->initvalstr, f->initval); + } + } + } + printf("\n\n"); + exit(0); +} diff --git a/trunk/arch/sparc/include/asm/asi.h b/trunk/arch/sparc/include/asm/asi.h index cbb93e5141de..b2e3db63a64b 100644 --- a/trunk/arch/sparc/include/asm/asi.h +++ b/trunk/arch/sparc/include/asm/asi.h @@ -112,20 +112,6 @@ #define ASI_M_ACTION 0x4c /* Breakpoint Action Register (GNU/Viking) */ -/* LEON ASI */ -#define ASI_LEON_NOCACHE 0x01 - -#define ASI_LEON_DCACHE_MISS 0x01 - -#define ASI_LEON_CACHEREGS 0x02 -#define ASI_LEON_IFLUSH 0x10 -#define ASI_LEON_DFLUSH 0x11 - -#define ASI_LEON_MMUFLUSH 0x18 -#define ASI_LEON_MMUREGS 0x19 -#define ASI_LEON_BYPASS 0x1c -#define ASI_LEON_FLUSH_PAGE 0x10 - /* V9 Architecture mandary ASIs. */ #define ASI_N 0x04 /* Nucleus */ #define ASI_NL 0x0c /* Nucleus, little endian */ diff --git a/trunk/arch/sparc/include/asm/asmmacro.h b/trunk/arch/sparc/include/asm/asmmacro.h index 02a172fb193a..a995bf8aba3f 100644 --- a/trunk/arch/sparc/include/asm/asmmacro.h +++ b/trunk/arch/sparc/include/asm/asmmacro.h @@ -6,6 +6,17 @@ #ifndef _SPARC_ASMMACRO_H #define _SPARC_ASMMACRO_H +#include +#include + +#define GET_PROCESSOR4M_ID(reg) \ + rd %tbr, %reg; \ + srl %reg, 12, %reg; \ + and %reg, 3, %reg; + +#define GET_PROCESSOR4D_ID(reg) \ + lda [%g0] ASI_M_VIKING_TMP1, %reg; + /* All trap entry points _must_ begin with this macro or else you * lose. It makes sure the kernel has a proper window so that * c-code can be called. @@ -20,4 +31,10 @@ /* All traps low-level code here must end with this macro. */ #define RESTORE_ALL b ret_trap_entry; clr %l6; +/* sun4 probably wants half word accesses to ASI_SEGMAP, while sun4c+ + likes byte accesses. These are to avoid ifdef mania. */ + +#define lduXa lduba +#define stXa stba + #endif /* !(_SPARC_ASMMACRO_H) */ diff --git a/trunk/arch/sparc/include/asm/btfixup.h b/trunk/arch/sparc/include/asm/btfixup.h new file mode 100644 index 000000000000..797722cf69f2 --- /dev/null +++ b/trunk/arch/sparc/include/asm/btfixup.h @@ -0,0 +1,208 @@ +/* + * asm/btfixup.h: Macros for boot time linking. + * + * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + */ + +#ifndef _SPARC_BTFIXUP_H +#define _SPARC_BTFIXUP_H + +#include + +#ifndef __ASSEMBLY__ + +#ifdef MODULE +extern unsigned int ___illegal_use_of_BTFIXUP_SIMM13_in_module(void); +extern unsigned int ___illegal_use_of_BTFIXUP_SETHI_in_module(void); +extern unsigned int ___illegal_use_of_BTFIXUP_HALF_in_module(void); +extern unsigned int ___illegal_use_of_BTFIXUP_INT_in_module(void); + +#define BTFIXUP_SIMM13(__name) ___illegal_use_of_BTFIXUP_SIMM13_in_module() +#define BTFIXUP_HALF(__name) ___illegal_use_of_BTFIXUP_HALF_in_module() +#define BTFIXUP_SETHI(__name) ___illegal_use_of_BTFIXUP_SETHI_in_module() +#define BTFIXUP_INT(__name) ___illegal_use_of_BTFIXUP_INT_in_module() +#define BTFIXUP_BLACKBOX(__name) ___illegal_use_of_BTFIXUP_BLACKBOX_in_module + +#else + +#define BTFIXUP_SIMM13(__name) ___sf_##__name() +#define BTFIXUP_HALF(__name) ___af_##__name() +#define BTFIXUP_SETHI(__name) ___hf_##__name() +#define BTFIXUP_INT(__name) ((unsigned int)&___i_##__name) +/* This must be written in assembly and present in a sethi */ +#define BTFIXUP_BLACKBOX(__name) ___b_##__name +#endif /* MODULE */ + +/* Fixup call xx */ + +#define BTFIXUPDEF_CALL(__type, __name, __args...) \ + extern __type ___f_##__name(__args); \ + extern unsigned ___fs_##__name[3]; +#define BTFIXUPDEF_CALL_CONST(__type, __name, __args...) \ + extern __type ___f_##__name(__args) __attribute_const__; \ + extern unsigned ___fs_##__name[3]; +#define BTFIXUP_CALL(__name) ___f_##__name + +#define BTFIXUPDEF_BLACKBOX(__name) \ + extern unsigned ___bs_##__name[2]; + +/* Put bottom 13bits into some register variable */ + +#define BTFIXUPDEF_SIMM13(__name) \ + static inline unsigned int ___sf_##__name(void) __attribute_const__; \ + extern unsigned ___ss_##__name[2]; \ + static inline unsigned int ___sf_##__name(void) { \ + unsigned int ret; \ + __asm__ ("or %%g0, ___s_" #__name ", %0" : "=r"(ret)); \ + return ret; \ + } +#define BTFIXUPDEF_SIMM13_INIT(__name,__val) \ + static inline unsigned int ___sf_##__name(void) __attribute_const__; \ + extern unsigned ___ss_##__name[2]; \ + static inline unsigned int ___sf_##__name(void) { \ + unsigned int ret; \ + __asm__ ("or %%g0, ___s_" #__name "__btset_" #__val ", %0" : "=r"(ret));\ + return ret; \ + } + +/* Put either bottom 13 bits, or upper 22 bits into some register variable + * (depending on the value, this will lead into sethi FIX, reg; or + * mov FIX, reg; ) + */ + +#define BTFIXUPDEF_HALF(__name) \ + static inline unsigned int ___af_##__name(void) __attribute_const__; \ + extern unsigned ___as_##__name[2]; \ + static inline unsigned int ___af_##__name(void) { \ + unsigned int ret; \ + __asm__ ("or %%g0, ___a_" #__name ", %0" : "=r"(ret)); \ + return ret; \ + } +#define BTFIXUPDEF_HALF_INIT(__name,__val) \ + static inline unsigned int ___af_##__name(void) __attribute_const__; \ + extern unsigned ___as_##__name[2]; \ + static inline unsigned int ___af_##__name(void) { \ + unsigned int ret; \ + __asm__ ("or %%g0, ___a_" #__name "__btset_" #__val ", %0" : "=r"(ret));\ + return ret; \ + } + +/* Put upper 22 bits into some register variable */ + +#define BTFIXUPDEF_SETHI(__name) \ + static inline unsigned int ___hf_##__name(void) __attribute_const__; \ + extern unsigned ___hs_##__name[2]; \ + static inline unsigned int ___hf_##__name(void) { \ + unsigned int ret; \ + __asm__ ("sethi %%hi(___h_" #__name "), %0" : "=r"(ret)); \ + return ret; \ + } +#define BTFIXUPDEF_SETHI_INIT(__name,__val) \ + static inline unsigned int ___hf_##__name(void) __attribute_const__; \ + extern unsigned ___hs_##__name[2]; \ + static inline unsigned int ___hf_##__name(void) { \ + unsigned int ret; \ + __asm__ ("sethi %%hi(___h_" #__name "__btset_" #__val "), %0" : \ + "=r"(ret)); \ + return ret; \ + } + +/* Put a full 32bit integer into some register variable */ + +#define BTFIXUPDEF_INT(__name) \ + extern unsigned char ___i_##__name; \ + extern unsigned ___is_##__name[2]; + +#define BTFIXUPCALL_NORM 0x00000000 /* Always call */ +#define BTFIXUPCALL_NOP 0x01000000 /* Possibly optimize to nop */ +#define BTFIXUPCALL_RETINT(i) (0x90102000|((i) & 0x1fff)) /* Possibly optimize to mov i, %o0 */ +#define BTFIXUPCALL_ORINT(i) (0x90122000|((i) & 0x1fff)) /* Possibly optimize to or %o0, i, %o0 */ +#define BTFIXUPCALL_RETO0 0x01000000 /* Return first parameter, actually a nop */ +#define BTFIXUPCALL_ANDNINT(i) (0x902a2000|((i) & 0x1fff)) /* Possibly optimize to andn %o0, i, %o0 */ +#define BTFIXUPCALL_SWAPO0O1 0xd27a0000 /* Possibly optimize to swap [%o0],%o1 */ +#define BTFIXUPCALL_SWAPO0G0 0xc07a0000 /* Possibly optimize to swap [%o0],%g0 */ +#define BTFIXUPCALL_SWAPG1G2 0xc4784000 /* Possibly optimize to swap [%g1],%g2 */ +#define BTFIXUPCALL_STG0O0 0xc0220000 /* Possibly optimize to st %g0,[%o0] */ +#define BTFIXUPCALL_STO1O0 0xd2220000 /* Possibly optimize to st %o1,[%o0] */ + +#define BTFIXUPSET_CALL(__name, __addr, __insn) \ + do { \ + ___fs_##__name[0] |= 1; \ + ___fs_##__name[1] = (unsigned long)__addr; \ + ___fs_##__name[2] = __insn; \ + } while (0) + +#define BTFIXUPSET_BLACKBOX(__name, __func) \ + do { \ + ___bs_##__name[0] |= 1; \ + ___bs_##__name[1] = (unsigned long)__func; \ + } while (0) + +#define BTFIXUPCOPY_CALL(__name, __from) \ + do { \ + ___fs_##__name[0] |= 1; \ + ___fs_##__name[1] = ___fs_##__from[1]; \ + ___fs_##__name[2] = ___fs_##__from[2]; \ + } while (0) + +#define BTFIXUPSET_SIMM13(__name, __val) \ + do { \ + ___ss_##__name[0] |= 1; \ + ___ss_##__name[1] = (unsigned)__val; \ + } while (0) + +#define BTFIXUPCOPY_SIMM13(__name, __from) \ + do { \ + ___ss_##__name[0] |= 1; \ + ___ss_##__name[1] = ___ss_##__from[1]; \ + } while (0) + +#define BTFIXUPSET_HALF(__name, __val) \ + do { \ + ___as_##__name[0] |= 1; \ + ___as_##__name[1] = (unsigned)__val; \ + } while (0) + +#define BTFIXUPCOPY_HALF(__name, __from) \ + do { \ + ___as_##__name[0] |= 1; \ + ___as_##__name[1] = ___as_##__from[1]; \ + } while (0) + +#define BTFIXUPSET_SETHI(__name, __val) \ + do { \ + ___hs_##__name[0] |= 1; \ + ___hs_##__name[1] = (unsigned)__val; \ + } while (0) + +#define BTFIXUPCOPY_SETHI(__name, __from) \ + do { \ + ___hs_##__name[0] |= 1; \ + ___hs_##__name[1] = ___hs_##__from[1]; \ + } while (0) + +#define BTFIXUPSET_INT(__name, __val) \ + do { \ + ___is_##__name[0] |= 1; \ + ___is_##__name[1] = (unsigned)__val; \ + } while (0) + +#define BTFIXUPCOPY_INT(__name, __from) \ + do { \ + ___is_##__name[0] |= 1; \ + ___is_##__name[1] = ___is_##__from[1]; \ + } while (0) + +#define BTFIXUPVAL_CALL(__name) \ + ((unsigned long)___fs_##__name[1]) + +extern void btfixup(void); + +#else /* __ASSEMBLY__ */ + +#define BTFIXUP_SETHI(__name) %hi(___h_ ## __name) +#define BTFIXUP_SETHI_INIT(__name,__val) %hi(___h_ ## __name ## __btset_ ## __val) + +#endif /* __ASSEMBLY__ */ + +#endif /* !(_SPARC_BTFIXUP_H) */ diff --git a/trunk/arch/sparc/include/asm/cache.h b/trunk/arch/sparc/include/asm/cache.h index 5bb6991b4857..69358b590c91 100644 --- a/trunk/arch/sparc/include/asm/cache.h +++ b/trunk/arch/sparc/include/asm/cache.h @@ -22,4 +22,118 @@ #define __read_mostly __attribute__((__section__(".data..read_mostly"))) +#ifdef CONFIG_SPARC32 +#include + +/* Direct access to the instruction cache is provided through and + * alternate address space. The IDC bit must be off in the ICCR on + * HyperSparcs for these accesses to work. The code below does not do + * any checking, the caller must do so. These routines are for + * diagnostics only, but could end up being useful. Use with care. + * Also, you are asking for trouble if you execute these in one of the + * three instructions following a %asr/%psr access or modification. + */ + +/* First, cache-tag access. */ +static inline unsigned int get_icache_tag(int setnum, int tagnum) +{ + unsigned int vaddr, retval; + + vaddr = ((setnum&1) << 12) | ((tagnum&0x7f) << 5); + __asm__ __volatile__("lda [%1] %2, %0\n\t" : + "=r" (retval) : + "r" (vaddr), "i" (ASI_M_TXTC_TAG)); + return retval; +} + +static inline void put_icache_tag(int setnum, int tagnum, unsigned int entry) +{ + unsigned int vaddr; + + vaddr = ((setnum&1) << 12) | ((tagnum&0x7f) << 5); + __asm__ __volatile__("sta %0, [%1] %2\n\t" : : + "r" (entry), "r" (vaddr), "i" (ASI_M_TXTC_TAG) : + "memory"); +} + +/* Second cache-data access. The data is returned two-32bit quantities + * at a time. + */ +static inline void get_icache_data(int setnum, int tagnum, int subblock, + unsigned int *data) +{ + unsigned int value1, value2, vaddr; + + vaddr = ((setnum&0x1) << 12) | ((tagnum&0x7f) << 5) | + ((subblock&0x3) << 3); + __asm__ __volatile__("ldda [%2] %3, %%g2\n\t" + "or %%g0, %%g2, %0\n\t" + "or %%g0, %%g3, %1\n\t" : + "=r" (value1), "=r" (value2) : + "r" (vaddr), "i" (ASI_M_TXTC_DATA) : + "g2", "g3"); + data[0] = value1; data[1] = value2; +} + +static inline void put_icache_data(int setnum, int tagnum, int subblock, + unsigned int *data) +{ + unsigned int value1, value2, vaddr; + + vaddr = ((setnum&0x1) << 12) | ((tagnum&0x7f) << 5) | + ((subblock&0x3) << 3); + value1 = data[0]; value2 = data[1]; + __asm__ __volatile__("or %%g0, %0, %%g2\n\t" + "or %%g0, %1, %%g3\n\t" + "stda %%g2, [%2] %3\n\t" : : + "r" (value1), "r" (value2), + "r" (vaddr), "i" (ASI_M_TXTC_DATA) : + "g2", "g3", "memory" /* no joke */); +} + +/* Different types of flushes with the ICACHE. Some of the flushes + * affect both the ICACHE and the external cache. Others only clear + * the ICACHE entries on the cpu itself. V8's (most) allow + * granularity of flushes on the packet (element in line), whole line, + * and entire cache (ie. all lines) level. The ICACHE only flushes are + * ROSS HyperSparc specific and are in ross.h + */ + +/* Flushes which clear out both the on-chip and external caches */ +static inline void flush_ei_page(unsigned int addr) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_FLUSH_PAGE) : + "memory"); +} + +static inline void flush_ei_seg(unsigned int addr) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_FLUSH_SEG) : + "memory"); +} + +static inline void flush_ei_region(unsigned int addr) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_FLUSH_REGION) : + "memory"); +} + +static inline void flush_ei_ctx(unsigned int addr) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_FLUSH_CTX) : + "memory"); +} + +static inline void flush_ei_user(unsigned int addr) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_FLUSH_USER) : + "memory"); +} +#endif /* CONFIG_SPARC32 */ + #endif /* !(_SPARC_CACHE_H) */ diff --git a/trunk/arch/sparc/include/asm/cacheflush.h b/trunk/arch/sparc/include/asm/cacheflush.h index f6c4839b8388..049168087b19 100644 --- a/trunk/arch/sparc/include/asm/cacheflush.h +++ b/trunk/arch/sparc/include/asm/cacheflush.h @@ -1,9 +1,5 @@ #ifndef ___ASM_SPARC_CACHEFLUSH_H #define ___ASM_SPARC_CACHEFLUSH_H - -/* flush addr - to allow use of self-modifying code */ -#define flushi(addr) __asm__ __volatile__ ("flush %0" : : "r" (addr) : "memory") - #if defined(__sparc__) && defined(__arch64__) #include #else diff --git a/trunk/arch/sparc/include/asm/cacheflush_32.h b/trunk/arch/sparc/include/asm/cacheflush_32.h index bb014c24f318..68431b47a22a 100644 --- a/trunk/arch/sparc/include/asm/cacheflush_32.h +++ b/trunk/arch/sparc/include/asm/cacheflush_32.h @@ -1,18 +1,56 @@ #ifndef _SPARC_CACHEFLUSH_H #define _SPARC_CACHEFLUSH_H -#include - -#define flush_cache_all() \ - sparc32_cachetlb_ops->cache_all() -#define flush_cache_mm(mm) \ - sparc32_cachetlb_ops->cache_mm(mm) -#define flush_cache_dup_mm(mm) \ - sparc32_cachetlb_ops->cache_mm(mm) -#define flush_cache_range(vma,start,end) \ - sparc32_cachetlb_ops->cache_range(vma, start, end) -#define flush_cache_page(vma,addr,pfn) \ - sparc32_cachetlb_ops->cache_page(vma, addr) +#include /* Common for other includes */ +// #include from pgalloc.h +// #include from pgalloc.h + +// #include +#include + +/* + * Fine grained cache flushing. + */ +#ifdef CONFIG_SMP + +BTFIXUPDEF_CALL(void, local_flush_cache_all, void) +BTFIXUPDEF_CALL(void, local_flush_cache_mm, struct mm_struct *) +BTFIXUPDEF_CALL(void, local_flush_cache_range, struct vm_area_struct *, unsigned long, unsigned long) +BTFIXUPDEF_CALL(void, local_flush_cache_page, struct vm_area_struct *, unsigned long) + +#define local_flush_cache_all() BTFIXUP_CALL(local_flush_cache_all)() +#define local_flush_cache_mm(mm) BTFIXUP_CALL(local_flush_cache_mm)(mm) +#define local_flush_cache_range(vma,start,end) BTFIXUP_CALL(local_flush_cache_range)(vma,start,end) +#define local_flush_cache_page(vma,addr) BTFIXUP_CALL(local_flush_cache_page)(vma,addr) + +BTFIXUPDEF_CALL(void, local_flush_page_to_ram, unsigned long) +BTFIXUPDEF_CALL(void, local_flush_sig_insns, struct mm_struct *, unsigned long) + +#define local_flush_page_to_ram(addr) BTFIXUP_CALL(local_flush_page_to_ram)(addr) +#define local_flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(local_flush_sig_insns)(mm,insn_addr) + +extern void smp_flush_cache_all(void); +extern void smp_flush_cache_mm(struct mm_struct *mm); +extern void smp_flush_cache_range(struct vm_area_struct *vma, + unsigned long start, + unsigned long end); +extern void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page); + +extern void smp_flush_page_to_ram(unsigned long page); +extern void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr); + +#endif /* CONFIG_SMP */ + +BTFIXUPDEF_CALL(void, flush_cache_all, void) +BTFIXUPDEF_CALL(void, flush_cache_mm, struct mm_struct *) +BTFIXUPDEF_CALL(void, flush_cache_range, struct vm_area_struct *, unsigned long, unsigned long) +BTFIXUPDEF_CALL(void, flush_cache_page, struct vm_area_struct *, unsigned long) + +#define flush_cache_all() BTFIXUP_CALL(flush_cache_all)() +#define flush_cache_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm) +#define flush_cache_dup_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm) +#define flush_cache_range(vma,start,end) BTFIXUP_CALL(flush_cache_range)(vma,start,end) +#define flush_cache_page(vma,addr,pfn) BTFIXUP_CALL(flush_cache_page)(vma,addr) #define flush_icache_range(start, end) do { } while (0) #define flush_icache_page(vma, pg) do { } while (0) @@ -29,12 +67,11 @@ memcpy(dst, src, len); \ } while (0) -#define __flush_page_to_ram(addr) \ - sparc32_cachetlb_ops->page_to_ram(addr) -#define flush_sig_insns(mm,insn_addr) \ - sparc32_cachetlb_ops->sig_insns(mm, insn_addr) -#define flush_page_for_dma(addr) \ - sparc32_cachetlb_ops->page_for_dma(addr) +BTFIXUPDEF_CALL(void, __flush_page_to_ram, unsigned long) +BTFIXUPDEF_CALL(void, flush_sig_insns, struct mm_struct *, unsigned long) + +#define __flush_page_to_ram(addr) BTFIXUP_CALL(__flush_page_to_ram)(addr) +#define flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(flush_sig_insns)(mm,insn_addr) extern void sparc_flush_page_to_ram(struct page *page); diff --git a/trunk/arch/sparc/include/asm/cacheflush_64.h b/trunk/arch/sparc/include/asm/cacheflush_64.h index 301736d9e7a1..2efea2ff88b7 100644 --- a/trunk/arch/sparc/include/asm/cacheflush_64.h +++ b/trunk/arch/sparc/include/asm/cacheflush_64.h @@ -8,6 +8,9 @@ #include /* Cache flush operations. */ + + +#define flushi(addr) __asm__ __volatile__ ("flush %0" : : "r" (addr) : "memory") #define flushw_all() __asm__ __volatile__("flushw") extern void __flushw_user(void); diff --git a/trunk/arch/sparc/include/asm/cachetlb_32.h b/trunk/arch/sparc/include/asm/cachetlb_32.h deleted file mode 100644 index efb19889a083..000000000000 --- a/trunk/arch/sparc/include/asm/cachetlb_32.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _SPARC_CACHETLB_H -#define _SPARC_CACHETLB_H - -struct mm_struct; -struct vm_area_struct; - -struct sparc32_cachetlb_ops { - void (*cache_all)(void); - void (*cache_mm)(struct mm_struct *); - void (*cache_range)(struct vm_area_struct *, unsigned long, - unsigned long); - void (*cache_page)(struct vm_area_struct *, unsigned long); - - void (*tlb_all)(void); - void (*tlb_mm)(struct mm_struct *); - void (*tlb_range)(struct vm_area_struct *, unsigned long, - unsigned long); - void (*tlb_page)(struct vm_area_struct *, unsigned long); - - void (*page_to_ram)(unsigned long); - void (*sig_insns)(struct mm_struct *, unsigned long); - void (*page_for_dma)(unsigned long); -}; -extern const struct sparc32_cachetlb_ops *sparc32_cachetlb_ops; -#ifdef CONFIG_SMP -extern const struct sparc32_cachetlb_ops *local_ops; -#endif - -#endif /* SPARC_CACHETLB_H */ diff --git a/trunk/arch/sparc/include/asm/cmpxchg_32.h b/trunk/arch/sparc/include/asm/cmpxchg_32.h index 1fae1a02e3c2..c786b0a92b51 100644 --- a/trunk/arch/sparc/include/asm/cmpxchg_32.h +++ b/trunk/arch/sparc/include/asm/cmpxchg_32.h @@ -11,13 +11,40 @@ #ifndef __ARCH_SPARC_CMPXCHG__ #define __ARCH_SPARC_CMPXCHG__ +#include + +/* This has special calling conventions */ +#ifndef CONFIG_SMP +BTFIXUPDEF_CALL(void, ___xchg32, void) +#endif + static inline unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned long val) { +#ifdef CONFIG_SMP __asm__ __volatile__("swap [%2], %0" : "=&r" (val) : "0" (val), "r" (m) : "memory"); return val; +#else + register unsigned long *ptr asm("g1"); + register unsigned long ret asm("g2"); + + ptr = (unsigned long *) m; + ret = val; + + /* Note: this is magic and the nop there is + really needed. */ + __asm__ __volatile__( + "mov %%o7, %%g4\n\t" + "call ___f____xchg32\n\t" + " nop\n\t" + : "=&r" (ret) + : "0" (ret), "r" (ptr) + : "g3", "g4", "g7", "memory", "cc"); + + return ret; +#endif } extern void __xchg_called_with_bad_pointer(void); diff --git a/trunk/arch/sparc/include/asm/contregs.h b/trunk/arch/sparc/include/asm/contregs.h index b8abdfcf5555..48fa8a4ef357 100644 --- a/trunk/arch/sparc/include/asm/contregs.h +++ b/trunk/arch/sparc/include/asm/contregs.h @@ -7,6 +7,28 @@ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) */ +/* 3=sun3 + 4=sun4 (as in sun4 sysmaint student book) + c=sun4c (according to davem) */ + +#define AC_IDPROM 0x00000000 /* 34 ID PROM, R/O, byte, 32 bytes */ +#define AC_PAGEMAP 0x10000000 /* 3 Pagemap R/W, long */ +#define AC_SEGMAP 0x20000000 /* 3 Segment map, byte */ +#define AC_CONTEXT 0x30000000 /* 34c current mmu-context */ +#define AC_SENABLE 0x40000000 /* 34c system dvma/cache/reset enable reg*/ +#define AC_UDVMA_ENB 0x50000000 /* 34 Not used on Sun boards, byte */ +#define AC_BUS_ERROR 0x60000000 /* 34 Not cleared on read, byte. */ +#define AC_SYNC_ERR 0x60000000 /* c fault type */ +#define AC_SYNC_VA 0x60000004 /* c fault virtual address */ +#define AC_ASYNC_ERR 0x60000008 /* c asynchronous fault type */ +#define AC_ASYNC_VA 0x6000000c /* c async fault virtual address */ +#define AC_LEDS 0x70000000 /* 34 Zero turns on LEDs, byte */ +#define AC_CACHETAGS 0x80000000 /* 34c direct access to the VAC tags */ +#define AC_CACHEDDATA 0x90000000 /* 3 c direct access to the VAC data */ +#define AC_UDVMA_MAP 0xD0000000 /* 4 Not used on Sun boards, byte */ +#define AC_VME_VECTOR 0xE0000000 /* 4 For non-Autovector VME, byte */ +#define AC_BOOT_SCC 0xF0000000 /* 34 bypass to access Zilog 8530. byte.*/ + /* s=Swift, h=Ross_HyperSPARC, v=TI_Viking, t=Tsunami, r=Ross_Cypress */ #define AC_M_PCR 0x0000 /* shv Processor Control Reg */ #define AC_M_CTPR 0x0100 /* shv Context Table Pointer Reg */ diff --git a/trunk/arch/sparc/include/asm/cpu_type.h b/trunk/arch/sparc/include/asm/cpu_type.h index 84d7d83b8084..4ca184d95d82 100644 --- a/trunk/arch/sparc/include/asm/cpu_type.h +++ b/trunk/arch/sparc/include/asm/cpu_type.h @@ -5,24 +5,30 @@ * Sparc (general) CPU types */ enum sparc_cpu { - sun4m = 0x00, - sun4d = 0x01, - sun4e = 0x02, - sun4u = 0x03, /* V8 ploos ploos */ - sun_unknown = 0x04, - ap1000 = 0x05, /* almost a sun4m */ - sparc_leon = 0x06, /* Leon SoC */ + sun4 = 0x00, + sun4c = 0x01, + sun4m = 0x02, + sun4d = 0x03, + sun4e = 0x04, + sun4u = 0x05, /* V8 ploos ploos */ + sun_unknown = 0x06, + ap1000 = 0x07, /* almost a sun4m */ + sparc_leon = 0x08, /* Leon SoC */ }; #ifdef CONFIG_SPARC32 extern enum sparc_cpu sparc_cpu_model; +#define ARCH_SUN4C (sparc_cpu_model==sun4c) + #define SUN4M_NCPUS 4 /* Architectural limit of sun4m. */ #else #define sparc_cpu_model sun4u +/* This cannot ever be a sun4c :) That's just history. */ +#define ARCH_SUN4C 0 #endif #endif /* __ASM_CPU_TYPE_H */ diff --git a/trunk/arch/sparc/include/asm/cpudata_32.h b/trunk/arch/sparc/include/asm/cpudata_32.h index 0300d94c25b3..a4c5a938b936 100644 --- a/trunk/arch/sparc/include/asm/cpudata_32.h +++ b/trunk/arch/sparc/include/asm/cpudata_32.h @@ -14,6 +14,7 @@ typedef struct { unsigned long udelay_val; unsigned long clock_tick; + unsigned int multiplier; unsigned int counter; #ifdef CONFIG_SMP unsigned int irq_resched_count; diff --git a/trunk/arch/sparc/include/asm/cypress.h b/trunk/arch/sparc/include/asm/cypress.h new file mode 100644 index 000000000000..95e9772ea394 --- /dev/null +++ b/trunk/arch/sparc/include/asm/cypress.h @@ -0,0 +1,79 @@ +/* + * cypress.h: Cypress module specific definitions and defines. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_CYPRESS_H +#define _SPARC_CYPRESS_H + +/* Cypress chips have %psr 'impl' of '0001' and 'vers' of '0001'. */ + +/* The MMU control register fields on the Sparc Cypress 604/605 MMU's. + * + * --------------------------------------------------------------- + * |implvers| MCA | MCM |MV| MID |BM| C|RSV|MR|CM|CL|CE|RSV|NF|ME| + * --------------------------------------------------------------- + * 31 24 23-22 21-20 19 18-15 14 13 12 11 10 9 8 7-2 1 0 + * + * MCA: MultiChip Access -- Used for configuration of multiple + * CY7C604/605 cache units. + * MCM: MultiChip Mask -- Again, for multiple cache unit config. + * MV: MultiChip Valid -- Indicates MCM and MCA have valid settings. + * MID: ModuleID -- Unique processor ID for MBus transactions. (605 only) + * BM: Boot Mode -- 0 = not in boot mode, 1 = in boot mode + * C: Cacheable -- Indicates whether accesses are cacheable while + * the MMU is off. 0=no 1=yes + * MR: MemoryReflection -- Indicates whether the bus attached to the + * MBus supports memory reflection. 0=no 1=yes (605 only) + * CM: CacheMode -- Indicates whether the cache is operating in write + * through or copy-back mode. 0=write-through 1=copy-back + * CL: CacheLock -- Indicates if the entire cache is locked or not. + * 0=not-locked 1=locked (604 only) + * CE: CacheEnable -- Is the virtual cache on? 0=no 1=yes + * NF: NoFault -- Do faults generate traps? 0=yes 1=no + * ME: MmuEnable -- Is the MMU doing translations? 0=no 1=yes + */ + +#define CYPRESS_MCA 0x00c00000 +#define CYPRESS_MCM 0x00300000 +#define CYPRESS_MVALID 0x00080000 +#define CYPRESS_MIDMASK 0x00078000 /* Only on 605 */ +#define CYPRESS_BMODE 0x00004000 +#define CYPRESS_ACENABLE 0x00002000 +#define CYPRESS_MRFLCT 0x00000800 /* Only on 605 */ +#define CYPRESS_CMODE 0x00000400 +#define CYPRESS_CLOCK 0x00000200 /* Only on 604 */ +#define CYPRESS_CENABLE 0x00000100 +#define CYPRESS_NFAULT 0x00000002 +#define CYPRESS_MENABLE 0x00000001 + +static inline void cypress_flush_page(unsigned long page) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (page), "i" (ASI_M_FLUSH_PAGE)); +} + +static inline void cypress_flush_segment(unsigned long addr) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_FLUSH_SEG)); +} + +static inline void cypress_flush_region(unsigned long addr) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_FLUSH_REGION)); +} + +static inline void cypress_flush_context(void) +{ + __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : : + "i" (ASI_M_FLUSH_CTX)); +} + +/* XXX Displacement flushes for buggy chips and initial testing + * XXX go here. + */ + +#endif /* !(_SPARC_CYPRESS_H) */ diff --git a/trunk/arch/sparc/include/asm/dma.h b/trunk/arch/sparc/include/asm/dma.h index 3d434ef5eae3..b554927bbaf6 100644 --- a/trunk/arch/sparc/include/asm/dma.h +++ b/trunk/arch/sparc/include/asm/dma.h @@ -92,31 +92,27 @@ extern int isa_dma_bridge_buggy; #ifdef CONFIG_SPARC32 /* Routines for data transfer buffers. */ +BTFIXUPDEF_CALL(char *, mmu_lockarea, char *, unsigned long) +BTFIXUPDEF_CALL(void, mmu_unlockarea, char *, unsigned long) + +#define mmu_lockarea(vaddr,len) BTFIXUP_CALL(mmu_lockarea)(vaddr,len) +#define mmu_unlockarea(vaddr,len) BTFIXUP_CALL(mmu_unlockarea)(vaddr,len) + +struct page; struct device; struct scatterlist; -struct sparc32_dma_ops { - __u32 (*get_scsi_one)(struct device *, char *, unsigned long); - void (*get_scsi_sgl)(struct device *, struct scatterlist *, int); - void (*release_scsi_one)(struct device *, __u32, unsigned long); - void (*release_scsi_sgl)(struct device *, struct scatterlist *,int); -#ifdef CONFIG_SBUS - int (*map_dma_area)(struct device *, dma_addr_t *, unsigned long, unsigned long, int); - void (*unmap_dma_area)(struct device *, unsigned long, int); -#endif -}; -extern const struct sparc32_dma_ops *sparc32_dma_ops; - -#define mmu_get_scsi_one(dev,vaddr,len) \ - sparc32_dma_ops->get_scsi_one(dev, vaddr, len) -#define mmu_get_scsi_sgl(dev,sg,sz) \ - sparc32_dma_ops->get_scsi_sgl(dev, sg, sz) -#define mmu_release_scsi_one(dev,vaddr,len) \ - sparc32_dma_ops->release_scsi_one(dev, vaddr,len) -#define mmu_release_scsi_sgl(dev,sg,sz) \ - sparc32_dma_ops->release_scsi_sgl(dev, sg, sz) - -#ifdef CONFIG_SBUS +/* These are implementations for sbus_map_sg/sbus_unmap_sg... collapse later */ +BTFIXUPDEF_CALL(__u32, mmu_get_scsi_one, struct device *, char *, unsigned long) +BTFIXUPDEF_CALL(void, mmu_get_scsi_sgl, struct device *, struct scatterlist *, int) +BTFIXUPDEF_CALL(void, mmu_release_scsi_one, struct device *, __u32, unsigned long) +BTFIXUPDEF_CALL(void, mmu_release_scsi_sgl, struct device *, struct scatterlist *, int) + +#define mmu_get_scsi_one(dev,vaddr,len) BTFIXUP_CALL(mmu_get_scsi_one)(dev,vaddr,len) +#define mmu_get_scsi_sgl(dev,sg,sz) BTFIXUP_CALL(mmu_get_scsi_sgl)(dev,sg,sz) +#define mmu_release_scsi_one(dev,vaddr,len) BTFIXUP_CALL(mmu_release_scsi_one)(dev,vaddr,len) +#define mmu_release_scsi_sgl(dev,sg,sz) BTFIXUP_CALL(mmu_release_scsi_sgl)(dev,sg,sz) + /* * mmu_map/unmap are provided by iommu/iounit; Invalid to call on IIep. * @@ -127,17 +123,17 @@ extern const struct sparc32_dma_ops *sparc32_dma_ops; * Second mapping is for device visible address, or "bus" address. * The bus address is returned at '*pba'. * - * These functions seem distinct, but are hard to split. + * These functions seem distinct, but are hard to split. On sun4c, + * at least for now, 'a' is equal to bus address, and retured in *pba. * On sun4m, page attributes depend on the CPU type, so we have to * know if we are mapping RAM or I/O, so it has to be an additional argument * to a separate mapping function for CPU visible mappings. */ -#define sbus_map_dma_area(dev,pba,va,a,len) \ - sparc32_dma_ops->map_dma_area(dev, pba, va, a, len) -#define sbus_unmap_dma_area(dev,ba,len) \ - sparc32_dma_ops->unmap_dma_area(dev, ba, len) -#endif /* CONFIG_SBUS */ +BTFIXUPDEF_CALL(int, mmu_map_dma_area, struct device *, dma_addr_t *, unsigned long, unsigned long, int len) +BTFIXUPDEF_CALL(void, mmu_unmap_dma_area, struct device *, unsigned long busa, int len) +#define mmu_map_dma_area(dev,pba,va,a,len) BTFIXUP_CALL(mmu_map_dma_area)(dev,pba,va,a,len) +#define mmu_unmap_dma_area(dev,ba,len) BTFIXUP_CALL(mmu_unmap_dma_area)(dev,ba,len) #endif #endif /* !(_ASM_SPARC_DMA_H) */ diff --git a/trunk/arch/sparc/include/asm/elf_32.h b/trunk/arch/sparc/include/asm/elf_32.h index 2d4d755cba9e..4269ca6ad18a 100644 --- a/trunk/arch/sparc/include/asm/elf_32.h +++ b/trunk/arch/sparc/include/asm/elf_32.h @@ -118,9 +118,16 @@ typedef struct { instruction set this cpu supports. This can NOT be done in userspace on Sparc. */ -/* Most sun4m's have them all. */ -#define ELF_HWCAP (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | \ - HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV) +/* Sun4c has none of the capabilities, most sun4m's have them all. + * XXX This is gross, set some global variable at boot time. -DaveM + */ +#define ELF_HWCAP ((ARCH_SUN4C) ? 0 : \ + (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | \ + HWCAP_SPARC_SWAP | \ + ((srmmu_modtype != Cypress && \ + srmmu_modtype != Cypress_vE && \ + srmmu_modtype != Cypress_vD) ? \ + HWCAP_SPARC_MULDIV : 0))) /* This yields a string that ld.so will use to load implementation specific libraries for optimization. This is more specific in diff --git a/trunk/arch/sparc/include/asm/floppy_32.h b/trunk/arch/sparc/include/asm/floppy_32.h index fb3f16954c69..698d9559fead 100644 --- a/trunk/arch/sparc/include/asm/floppy_32.h +++ b/trunk/arch/sparc/include/asm/floppy_32.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -102,13 +103,25 @@ static struct sun_floppy_ops sun_fdops; /* Routines unique to each controller type on a Sun. */ static void sun_set_dor(unsigned char value, int fdc_82077) { - if (fdc_82077) + if (sparc_cpu_model == sun4c) { + unsigned int bits = 0; + if (value & 0x10) + bits |= AUXIO_FLPY_DSEL; + if ((value & 0x80) == 0) + bits |= AUXIO_FLPY_EJCT; + set_auxio(bits, (~bits) & (AUXIO_FLPY_DSEL|AUXIO_FLPY_EJCT)); + } + if (fdc_82077) { sun_fdc->dor_82077 = value; + } } static unsigned char sun_read_dir(void) { - return sun_fdc->dir_82077; + if (sparc_cpu_model == sun4c) + return (get_auxio() & AUXIO_FLPY_DCHG) ? 0x80 : 0; + else + return sun_fdc->dir_82077; } static unsigned char sun_82072_fd_inb(int port) @@ -229,7 +242,10 @@ static inline void virtual_dma_init(void) static inline void sun_fd_disable_dma(void) { doing_pdma = 0; - pdma_base = NULL; + if (pdma_base) { + mmu_unlockarea(pdma_base, pdma_areasize); + pdma_base = NULL; + } } static inline void sun_fd_set_dma_mode(int mode) @@ -259,6 +275,7 @@ static inline void sun_fd_set_dma_count(int length) static inline void sun_fd_enable_dma(void) { + pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size); pdma_base = pdma_vaddr; pdma_areasize = pdma_size; } @@ -284,36 +301,38 @@ static int sun_floppy_init(void) { struct platform_device *op; struct device_node *dp; - struct resource r; char state[128]; - phandle fd_node; - phandle tnode; + phandle tnode, fd_node; int num_regs; + struct resource r; use_virtual_dma = 1; /* Forget it if we aren't on a machine that could possibly * ever have a floppy drive. */ - if (sparc_cpu_model != sun4m) { + if((sparc_cpu_model != sun4c && sparc_cpu_model != sun4m) || + ((idprom->id_machtype == (SM_SUN4C | SM_4C_SLC)) || + (idprom->id_machtype == (SM_SUN4C | SM_4C_ELC)))) { /* We certainly don't have a floppy controller. */ goto no_sun_fdc; } /* Well, try to find one. */ tnode = prom_getchild(prom_root_node); fd_node = prom_searchsiblings(tnode, "obio"); - if (fd_node != 0) { + if(fd_node != 0) { tnode = prom_getchild(fd_node); fd_node = prom_searchsiblings(tnode, "SUNW,fdtwo"); } else { fd_node = prom_searchsiblings(tnode, "fd"); } - if (fd_node == 0) { + if(fd_node == 0) { goto no_sun_fdc; } /* The sun4m lets us know if the controller is actually usable. */ - if (prom_getproperty(fd_node, "status", state, sizeof(state)) != -1) { + if(sparc_cpu_model == sun4m && + prom_getproperty(fd_node, "status", state, sizeof(state)) != -1) { if(!strcmp(state, "disabled")) { goto no_sun_fdc; } @@ -324,12 +343,12 @@ static int sun_floppy_init(void) memset(&r, 0, sizeof(r)); r.flags = fd_regs[0].which_io; r.start = fd_regs[0].phys_addr; - sun_fdc = of_ioremap(&r, 0, fd_regs[0].reg_size, "floppy"); + sun_fdc = (struct sun_flpy_controller *) + of_ioremap(&r, 0, fd_regs[0].reg_size, "floppy"); /* Look up irq in platform_device. * We try "SUNW,fdtwo" and "fd" */ - op = NULL; for_each_node_by_name(dp, "SUNW,fdtwo") { op = of_find_device_by_node(dp); if (op) @@ -348,7 +367,7 @@ static int sun_floppy_init(void) FLOPPY_IRQ = op->archdata.irqs[0]; /* Last minute sanity check... */ - if (sun_fdc->status_82072 == 0xff) { + if(sun_fdc->status_82072 == 0xff) { sun_fdc = NULL; goto no_sun_fdc; } diff --git a/trunk/arch/sparc/include/asm/floppy_64.h b/trunk/arch/sparc/include/asm/floppy_64.h index e204f902e6c9..bcef1f5a2a6d 100644 --- a/trunk/arch/sparc/include/asm/floppy_64.h +++ b/trunk/arch/sparc/include/asm/floppy_64.h @@ -161,7 +161,10 @@ unsigned long pdma_areasize; static void sun_fd_disable_dma(void) { doing_pdma = 0; - pdma_base = NULL; + if (pdma_base) { + mmu_unlockarea(pdma_base, pdma_areasize); + pdma_base = NULL; + } } static void sun_fd_set_dma_mode(int mode) @@ -191,6 +194,7 @@ static void sun_fd_set_dma_count(int length) static void sun_fd_enable_dma(void) { + pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size); pdma_base = pdma_vaddr; pdma_areasize = pdma_size; } diff --git a/trunk/arch/sparc/include/asm/head_32.h b/trunk/arch/sparc/include/asm/head_32.h index a76874838f61..7c35491a8b53 100644 --- a/trunk/arch/sparc/include/asm/head_32.h +++ b/trunk/arch/sparc/include/asm/head_32.h @@ -2,8 +2,15 @@ #define __SPARC_HEAD_H #define KERNBASE 0xf0000000 /* First address the kernel will eventually be */ +#define LOAD_ADDR 0x4000 /* prom jumps to us here unless this is elf /boot */ +#define SUN4C_SEGSZ (1 << 18) +#define SRMMU_L1_KBASE_OFFSET ((KERNBASE>>24)<<2) /* Used in boot remapping. */ +#define INTS_ENAB 0x01 /* entry.S uses this. */ + +#define SUN4_PROM_VECTOR 0xFFE81000 /* SUN4 PROM needs to be hardwired */ #define WRITE_PAUSE nop; nop; nop; /* Have to do this after %wim/%psr chg */ +#define NOP_INSN 0x01000000 /* Used to patch sparc_save_state */ /* Here are some trap goodies */ @@ -11,7 +18,9 @@ #define TRAP_ENTRY(type, label) \ rd %psr, %l0; b label; rd %wim, %l3; nop; -/* Data/text faults */ +/* Data/text faults. Defaults to sun4c version at boot time. */ +#define SPARC_TFAULT rd %psr, %l0; rd %wim, %l3; b sun4c_fault; mov 1, %l7; +#define SPARC_DFAULT rd %psr, %l0; rd %wim, %l3; b sun4c_fault; mov 0, %l7; #define SRMMU_TFAULT rd %psr, %l0; rd %wim, %l3; b srmmu_fault; mov 1, %l7; #define SRMMU_DFAULT rd %psr, %l0; rd %wim, %l3; b srmmu_fault; mov 0, %l7; @@ -71,6 +80,16 @@ #define TRAP_ENTRY_INTERRUPT(int_level) \ mov int_level, %l7; rd %psr, %l0; b real_irq_entry; rd %wim, %l3; +/* NMI's (Non Maskable Interrupts) are special, you can't keep them + * from coming in, and basically if you get one, the shows over. ;( + * On the sun4c they are usually asynchronous memory errors, on the + * the sun4m they could be either due to mem errors or a software + * initiated interrupt from the prom/kern on an SMP box saying "I + * command you to do CPU tricks, read your mailbox for more info." + */ +#define NMI_TRAP \ + rd %wim, %l3; b linux_trap_nmi_sun4c; mov %psr, %l0; nop; + /* Window overflows/underflows are special and we need to try to be as * efficient as possible here.... */ diff --git a/trunk/arch/sparc/include/asm/leon.h b/trunk/arch/sparc/include/asm/leon.h index 07659124c140..a4e457f003ed 100644 --- a/trunk/arch/sparc/include/asm/leon.h +++ b/trunk/arch/sparc/include/asm/leon.h @@ -10,6 +10,19 @@ #ifdef CONFIG_SPARC_LEON +#define ASI_LEON_NOCACHE 0x01 + +#define ASI_LEON_DCACHE_MISS 0x1 + +#define ASI_LEON_CACHEREGS 0x02 +#define ASI_LEON_IFLUSH 0x10 +#define ASI_LEON_DFLUSH 0x11 + +#define ASI_LEON_MMUFLUSH 0x18 +#define ASI_LEON_MMUREGS 0x19 +#define ASI_LEON_BYPASS 0x1c +#define ASI_LEON_FLUSH_PAGE 0x10 + /* mmu register access, ASI_LEON_MMUREGS */ #define LEON_CNR_CTRL 0x000 #define LEON_CNR_CTXP 0x100 @@ -44,6 +57,29 @@ #define LEON_IRQMASK_R 0x0000fffe /* bit 15- 1 of lregs.irqmask */ #define LEON_IRQPRIO_R 0xfffe0000 /* bit 31-17 of lregs.irqmask */ +/* leon uart register definitions */ +#define LEON_OFF_UDATA 0x0 +#define LEON_OFF_USTAT 0x4 +#define LEON_OFF_UCTRL 0x8 +#define LEON_OFF_USCAL 0xc + +#define LEON_UCTRL_RE 0x01 +#define LEON_UCTRL_TE 0x02 +#define LEON_UCTRL_RI 0x04 +#define LEON_UCTRL_TI 0x08 +#define LEON_UCTRL_PS 0x10 +#define LEON_UCTRL_PE 0x20 +#define LEON_UCTRL_FL 0x40 +#define LEON_UCTRL_LB 0x80 + +#define LEON_USTAT_DR 0x01 +#define LEON_USTAT_TS 0x02 +#define LEON_USTAT_TH 0x04 +#define LEON_USTAT_BR 0x08 +#define LEON_USTAT_OV 0x10 +#define LEON_USTAT_PE 0x20 +#define LEON_USTAT_FE 0x40 + #define LEON_MCFG2_SRAMDIS 0x00002000 #define LEON_MCFG2_SDRAMEN 0x00004000 #define LEON_MCFG2_SRAMBANKSZ 0x00001e00 /* [12-9] */ @@ -53,6 +89,8 @@ #define LEON_TCNT0_MASK 0x7fffff +#define LEON_USTAT_ERROR (LEON_USTAT_OV | LEON_USTAT_PE | LEON_USTAT_FE) +/* no break yet */ #define ASI_LEON3_SYSCTRL 0x02 #define ASI_LEON3_SYSCTRL_ICFG 0x08 @@ -240,8 +278,6 @@ static inline int sparc_leon3_cpuid(void) #define LEON2_CFG_SSIZE_MASK 0x00007000UL #ifndef __ASSEMBLY__ -struct vm_area_struct; - extern unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr); extern void leon_flush_icache_all(void); extern void leon_flush_dcache_all(void); @@ -249,6 +285,15 @@ extern void leon_flush_cache_all(void); extern void leon_flush_tlb_all(void); extern int leon_flush_during_switch; extern int leon_flush_needed(void); + +struct vm_area_struct; +extern void leon_flush_icache_all(void); +extern void leon_flush_dcache_all(void); +extern void leon_flush_pcache_all(struct vm_area_struct *vma, unsigned long page); +extern void leon_flush_cache_all(void); +extern void leon_flush_tlb_all(void); +extern int leon_flush_during_switch; +extern int leon_flush_needed(void); extern void leon_flush_pcache_all(struct vm_area_struct *vma, unsigned long page); /* struct that hold LEON3 cache configuration registers */ @@ -270,19 +315,28 @@ struct leon2_cacheregs { #include struct device_node; -struct task_struct; extern unsigned int leon_build_device_irq(unsigned int real_irq, irq_flow_handler_t flow_handler, const char *name, int do_ack); extern void leon_update_virq_handling(unsigned int virq, irq_flow_handler_t flow_handler, const char *name, int do_ack); -extern void leon_init_timers(void); +extern void leon_clear_clock_irq(void); +extern void leon_load_profile_irq(int cpu, unsigned int limit); +extern void leon_init_timers(irq_handler_t counter_fn); +extern void leon_clear_clock_irq(void); +extern void leon_load_profile_irq(int cpu, unsigned int limit); extern void leon_trans_init(struct device_node *dp); extern void leon_node_init(struct device_node *dp, struct device_node ***nextp); +extern void leon_init_IRQ(void); +extern void leon_init(void); +extern unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr); extern void init_leon(void); extern void poke_leonsparc(void); extern void leon3_getCacheRegs(struct leon3_cacheregs *regs); +extern int leon_flush_needed(void); +extern void leon_switch_mm(void); +extern int srmmu_swprobe_trace; extern int leon3_ticker_irq; #ifdef CONFIG_SMP @@ -290,7 +344,7 @@ extern int leon_smp_nrcpus(void); extern void leon_clear_profile_irq(int cpu); extern void leon_smp_done(void); extern void leon_boot_cpus(void); -extern int leon_boot_one_cpu(int i, struct task_struct *); +extern int leon_boot_one_cpu(int i); void leon_init_smp(void); extern void cpu_idle(void); extern void init_IRQ(void); @@ -326,7 +380,7 @@ extern int leon_ipi_irq; #define init_leon() do {} while (0) #define leon_smp_done() do {} while (0) #define leon_boot_cpus() do {} while (0) -#define leon_boot_one_cpu(i, t) 1 +#define leon_boot_one_cpu(i) 1 #define leon_init_smp() do {} while (0) #endif /* !defined(CONFIG_SPARC_LEON) */ diff --git a/trunk/arch/sparc/include/asm/machines.h b/trunk/arch/sparc/include/asm/machines.h index fd6ddb05d1b7..cd9c099567e4 100644 --- a/trunk/arch/sparc/include/asm/machines.h +++ b/trunk/arch/sparc/include/asm/machines.h @@ -12,6 +12,11 @@ struct Sun_Machine_Models { unsigned char id_machtype; }; +/* Current number of machines we know about that has an IDPROM + * machtype entry including one entry for the 0x80 OBP machines. + */ +#define NUM_SUN_MACHINES 16 + /* The machine type in the idprom area looks like this: * * --------------- @@ -19,20 +24,36 @@ struct Sun_Machine_Models { * --------------- * 7 4 3 0 * - * The ARCH field determines the architecture line (sun4m, etc). + * The ARCH field determines the architecture line (sun4, sun4c, etc). * The MACH field determines the machine make within that architecture. */ #define SM_ARCH_MASK 0xf0 +#define SM_SUN4 0x20 #define M_LEON 0x30 +#define SM_SUN4C 0x50 #define SM_SUN4M 0x70 #define SM_SUN4M_OBP 0x80 #define SM_TYP_MASK 0x0f +/* Sun4 machines */ +#define SM_4_260 0x01 /* Sun 4/200 series */ +#define SM_4_110 0x02 /* Sun 4/100 series */ +#define SM_4_330 0x03 /* Sun 4/300 series */ +#define SM_4_470 0x04 /* Sun 4/400 series */ /* Leon machines */ #define M_LEON3_SOC 0x02 /* Leon3 SoC */ +/* Sun4c machines Full Name - PROM NAME */ +#define SM_4C_SS1 0x01 /* Sun4c SparcStation 1 - Sun 4/60 */ +#define SM_4C_IPC 0x02 /* Sun4c SparcStation IPC - Sun 4/40 */ +#define SM_4C_SS1PLUS 0x03 /* Sun4c SparcStation 1+ - Sun 4/65 */ +#define SM_4C_SLC 0x04 /* Sun4c SparcStation SLC - Sun 4/20 */ +#define SM_4C_SS2 0x05 /* Sun4c SparcStation 2 - Sun 4/75 */ +#define SM_4C_ELC 0x06 /* Sun4c SparcStation ELC - Sun 4/25 */ +#define SM_4C_IPX 0x07 /* Sun4c SparcStation IPX - Sun 4/50 */ + /* Sun4m machines, these predate the OpenBoot. These values only mean * something if the value in the ARCH field is SM_SUN4M, if it is * SM_SUN4M_OBP then you have the following situation: diff --git a/trunk/arch/sparc/include/asm/mbus.h b/trunk/arch/sparc/include/asm/mbus.h index 14128bcc5821..69f07a022ee6 100644 --- a/trunk/arch/sparc/include/asm/mbus.h +++ b/trunk/arch/sparc/include/asm/mbus.h @@ -8,10 +8,14 @@ #define _SPARC_MBUS_H #include /* HyperSparc stuff */ +#include /* Cypress Chips */ #include /* Ugh, bug city... */ enum mbus_module { HyperSparc = 0, + Cypress = 1, + Cypress_vE = 2, + Cypress_vD = 3, Swift_ok = 4, Swift_bad_c = 5, Swift_lots_o_bugs = 6, diff --git a/trunk/arch/sparc/include/asm/memreg.h b/trunk/arch/sparc/include/asm/memreg.h new file mode 100644 index 000000000000..845ad2b39183 --- /dev/null +++ b/trunk/arch/sparc/include/asm/memreg.h @@ -0,0 +1,51 @@ +#ifndef _SPARC_MEMREG_H +#define _SPARC_MEMREG_H +/* memreg.h: Definitions of the values found in the synchronous + * and asynchronous memory error registers when a fault + * occurs on the sun4c. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +/* First the synchronous error codes, these are usually just + * normal page faults. + */ + +#define SUN4C_SYNC_WDRESET 0x0001 /* watchdog reset */ +#define SUN4C_SYNC_SIZE 0x0002 /* bad access size? whuz this? */ +#define SUN4C_SYNC_PARITY 0x0008 /* bad ram chips caused a parity error */ +#define SUN4C_SYNC_SBUS 0x0010 /* the SBUS had some problems... */ +#define SUN4C_SYNC_NOMEM 0x0020 /* translation to non-existent ram */ +#define SUN4C_SYNC_PROT 0x0040 /* access violated pte protections */ +#define SUN4C_SYNC_NPRESENT 0x0080 /* pte said that page was not present */ +#define SUN4C_SYNC_BADWRITE 0x8000 /* while writing something went bogus */ + +#define SUN4C_SYNC_BOLIXED \ + (SUN4C_SYNC_WDRESET | SUN4C_SYNC_SIZE | SUN4C_SYNC_SBUS | \ + SUN4C_SYNC_NOMEM | SUN4C_SYNC_PARITY) + +/* Now the asynchronous error codes, these are almost always produced + * by the cache writing things back to memory and getting a bad translation. + * Bad DVMA transactions can cause these faults too. + */ + +#define SUN4C_ASYNC_BADDVMA 0x0010 /* error during DVMA access */ +#define SUN4C_ASYNC_NOMEM 0x0020 /* write back pointed to bad phys addr */ +#define SUN4C_ASYNC_BADWB 0x0080 /* write back points to non-present page */ + +/* Memory parity error register with associated bit constants. */ +#ifndef __ASSEMBLY__ +extern __volatile__ unsigned long __iomem *sun4c_memerr_reg; +#endif + +#define SUN4C_MPE_ERROR 0x80 /* Parity error detected. (ro) */ +#define SUN4C_MPE_MULTI 0x40 /* Multiple parity errors detected. (ro) */ +#define SUN4C_MPE_TEST 0x20 /* Write inverse parity. (rw) */ +#define SUN4C_MPE_CHECK 0x10 /* Enable parity checking. (rw) */ +#define SUN4C_MPE_ERR00 0x08 /* Parity error in bits 0-7. (ro) */ +#define SUN4C_MPE_ERR08 0x04 /* Parity error in bits 8-15. (ro) */ +#define SUN4C_MPE_ERR16 0x02 /* Parity error in bits 16-23. (ro) */ +#define SUN4C_MPE_ERR24 0x01 /* Parity error in bits 24-31. (ro) */ +#define SUN4C_MPE_ERRS 0x0F /* Bit mask for the error bits. (ro) */ + +#endif /* !(_SPARC_MEMREG_H) */ diff --git a/trunk/arch/sparc/include/asm/mmu_context_32.h b/trunk/arch/sparc/include/asm/mmu_context_32.h index 01456c900720..671a997b9e69 100644 --- a/trunk/arch/sparc/include/asm/mmu_context_32.h +++ b/trunk/arch/sparc/include/asm/mmu_context_32.h @@ -1,6 +1,8 @@ #ifndef __SPARC_MMU_CONTEXT_H #define __SPARC_MMU_CONTEXT_H +#include + #ifndef __ASSEMBLY__ #include @@ -21,11 +23,14 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) * all the page tables have been flushed. Our job is to destroy * any remaining processor-specific state. */ -void destroy_context(struct mm_struct *mm); +BTFIXUPDEF_CALL(void, destroy_context, struct mm_struct *) + +#define destroy_context(mm) BTFIXUP_CALL(destroy_context)(mm) /* Switch the current MM context. */ -void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, - struct task_struct *tsk); +BTFIXUPDEF_CALL(void, switch_mm, struct mm_struct *, struct mm_struct *, struct task_struct *) + +#define switch_mm(old_mm, mm, tsk) BTFIXUP_CALL(switch_mm)(old_mm, mm, tsk) #define deactivate_mm(tsk,mm) do { } while (0) diff --git a/trunk/arch/sparc/include/asm/obio.h b/trunk/arch/sparc/include/asm/obio.h index 910c1d9af1f8..4ade0c8a2c79 100644 --- a/trunk/arch/sparc/include/asm/obio.h +++ b/trunk/arch/sparc/include/asm/obio.h @@ -220,6 +220,19 @@ static inline void cc_set_igen(unsigned gen) "i" (ASI_M_MXCC)); } +/* +-------+-------------+-----------+------------------------------------+ + * | bcast | devid | sid | levels mask | + * +-------+-------------+-----------+------------------------------------+ + * 31 30 23 22 15 14 0 + */ +#define IGEN_MESSAGE(bcast, devid, sid, levels) \ + (((bcast) << 31) | ((devid) << 23) | ((sid) << 15) | (levels)) + +static inline void sun4d_send_ipi(int cpu, int level) +{ + cc_set_igen(IGEN_MESSAGE(0, cpu << 3, 6 + ((level >> 1) & 7), 1 << (level - 1))); +} + #endif /* !__ASSEMBLY__ */ #endif /* !(_SPARC_OBIO_H) */ diff --git a/trunk/arch/sparc/include/asm/oplib_32.h b/trunk/arch/sparc/include/asm/oplib_32.h index 27517879a6c2..71e5e9aeb67e 100644 --- a/trunk/arch/sparc/include/asm/oplib_32.h +++ b/trunk/arch/sparc/include/asm/oplib_32.h @@ -105,6 +105,14 @@ extern void prom_write(const char *buf, unsigned int len); extern int prom_startcpu(int cpunode, struct linux_prom_registers *context_table, int context, char *program_counter); +/* Sun4/sun4c specific memory-management startup hook. */ + +/* Map the passed segment in the given context at the passed + * virtual address. + */ +extern void prom_putsegment(int context, unsigned long virt_addr, + int physical_segment); + /* Initialize the memory lists based upon the prom version. */ void prom_meminit(void); diff --git a/trunk/arch/sparc/include/asm/page_32.h b/trunk/arch/sparc/include/asm/page_32.h index fab78a308ebf..bb5c2ac4055d 100644 --- a/trunk/arch/sparc/include/asm/page_32.h +++ b/trunk/arch/sparc/include/asm/page_32.h @@ -14,6 +14,8 @@ #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) +#include + #ifndef __ASSEMBLY__ #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) @@ -43,6 +45,12 @@ struct sparc_phys_banks { extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS+1]; +/* Cache alias structure. Entry is valid if context != -1. */ +struct cache_palias { + unsigned long vaddr; + int context; +}; + /* passing structs on the Sparc slow us down tremendously... */ /* #define STRICT_MM_TYPECHECKS */ @@ -108,7 +116,10 @@ typedef unsigned long iopgprot_t; typedef struct page *pgtable_t; extern unsigned long sparc_unmapped_base; -#define TASK_UNMAPPED_BASE sparc_unmapped_base + +BTFIXUPDEF_SETHI(sparc_unmapped_base) + +#define TASK_UNMAPPED_BASE BTFIXUP_SETHI(sparc_unmapped_base) #else /* !(__ASSEMBLY__) */ diff --git a/trunk/arch/sparc/include/asm/pgalloc_32.h b/trunk/arch/sparc/include/asm/pgalloc_32.h index e5b169b46d21..ca2b34456c4b 100644 --- a/trunk/arch/sparc/include/asm/pgalloc_32.h +++ b/trunk/arch/sparc/include/asm/pgalloc_32.h @@ -4,10 +4,8 @@ #include #include -#include -#include -#include #include +#include struct page; @@ -17,74 +15,54 @@ extern struct pgtable_cache_struct { unsigned long pgtable_cache_sz; unsigned long pgd_cache_sz; } pgt_quicklists; - -unsigned long srmmu_get_nocache(int size, int align); -void srmmu_free_nocache(unsigned long vaddr, int size); - #define pgd_quicklist (pgt_quicklists.pgd_cache) #define pmd_quicklist ((unsigned long *)0) #define pte_quicklist (pgt_quicklists.pte_cache) #define pgtable_cache_size (pgt_quicklists.pgtable_cache_sz) #define pgd_cache_size (pgt_quicklists.pgd_cache_sz) -#define check_pgt_cache() do { } while (0) +extern void check_pgt_cache(void); +BTFIXUPDEF_CALL(void, do_check_pgt_cache, int, int) +#define do_check_pgt_cache(low,high) BTFIXUP_CALL(do_check_pgt_cache)(low,high) + +BTFIXUPDEF_CALL(pgd_t *, get_pgd_fast, void) +#define get_pgd_fast() BTFIXUP_CALL(get_pgd_fast)() -pgd_t *get_pgd_fast(void); -static inline void free_pgd_fast(pgd_t *pgd) -{ - srmmu_free_nocache((unsigned long)pgd, SRMMU_PGD_TABLE_SIZE); -} +BTFIXUPDEF_CALL(void, free_pgd_fast, pgd_t *) +#define free_pgd_fast(pgd) BTFIXUP_CALL(free_pgd_fast)(pgd) #define pgd_free(mm, pgd) free_pgd_fast(pgd) #define pgd_alloc(mm) get_pgd_fast() -static inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp) -{ - unsigned long pa = __nocache_pa((unsigned long)pmdp); - - set_pte((pte_t *)pgdp, (SRMMU_ET_PTD | (pa >> 4))); -} - +BTFIXUPDEF_CALL(void, pgd_set, pgd_t *, pmd_t *) +#define pgd_set(pgdp,pmdp) BTFIXUP_CALL(pgd_set)(pgdp,pmdp) #define pgd_populate(MM, PGD, PMD) pgd_set(PGD, PMD) -static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, - unsigned long address) -{ - return (pmd_t *)srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, - SRMMU_PMD_TABLE_SIZE); -} +BTFIXUPDEF_CALL(pmd_t *, pmd_alloc_one, struct mm_struct *, unsigned long) +#define pmd_alloc_one(mm, address) BTFIXUP_CALL(pmd_alloc_one)(mm, address) -static inline void free_pmd_fast(pmd_t * pmd) -{ - srmmu_free_nocache((unsigned long)pmd, SRMMU_PMD_TABLE_SIZE); -} +BTFIXUPDEF_CALL(void, free_pmd_fast, pmd_t *) +#define free_pmd_fast(pmd) BTFIXUP_CALL(free_pmd_fast)(pmd) #define pmd_free(mm, pmd) free_pmd_fast(pmd) #define __pmd_free_tlb(tlb, pmd, addr) pmd_free((tlb)->mm, pmd) -void pmd_populate(struct mm_struct *mm, pmd_t *pmdp, struct page *ptep); +BTFIXUPDEF_CALL(void, pmd_populate, pmd_t *, struct page *) +#define pmd_populate(MM, PMD, PTE) BTFIXUP_CALL(pmd_populate)(PMD, PTE) #define pmd_pgtable(pmd) pmd_page(pmd) +BTFIXUPDEF_CALL(void, pmd_set, pmd_t *, pte_t *) +#define pmd_populate_kernel(MM, PMD, PTE) BTFIXUP_CALL(pmd_set)(PMD, PTE) -void pmd_set(pmd_t *pmdp, pte_t *ptep); -#define pmd_populate_kernel(MM, PMD, PTE) pmd_set(PMD, PTE) - -pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address); - -static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, - unsigned long address) -{ - return (pte_t *)srmmu_get_nocache(PTE_SIZE, PTE_SIZE); -} - - -static inline void free_pte_fast(pte_t *pte) -{ - srmmu_free_nocache((unsigned long)pte, PTE_SIZE); -} +BTFIXUPDEF_CALL(pgtable_t , pte_alloc_one, struct mm_struct *, unsigned long) +#define pte_alloc_one(mm, address) BTFIXUP_CALL(pte_alloc_one)(mm, address) +BTFIXUPDEF_CALL(pte_t *, pte_alloc_one_kernel, struct mm_struct *, unsigned long) +#define pte_alloc_one_kernel(mm, addr) BTFIXUP_CALL(pte_alloc_one_kernel)(mm, addr) -#define pte_free_kernel(mm, pte) free_pte_fast(pte) +BTFIXUPDEF_CALL(void, free_pte_fast, pte_t *) +#define pte_free_kernel(mm, pte) BTFIXUP_CALL(free_pte_fast)(pte) -void pte_free(struct mm_struct * mm, pgtable_t pte); +BTFIXUPDEF_CALL(void, pte_free, pgtable_t ) +#define pte_free(mm, pte) BTFIXUP_CALL(pte_free)(pte) #define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte) #endif /* _SPARC_PGALLOC_H */ diff --git a/trunk/arch/sparc/include/asm/pgtable_32.h b/trunk/arch/sparc/include/asm/pgtable_32.h index cbbbed5cb3aa..3d7101860e68 100644 --- a/trunk/arch/sparc/include/asm/pgtable_32.h +++ b/trunk/arch/sparc/include/asm/pgtable_32.h @@ -16,9 +16,11 @@ #include #include #include +#include #include -#include +#include #include +#include #include @@ -28,55 +30,87 @@ struct page; extern void load_mmu(void); extern unsigned long calc_highpages(void); +BTFIXUPDEF_SIMM13(pgdir_shift) +BTFIXUPDEF_SETHI(pgdir_size) +BTFIXUPDEF_SETHI(pgdir_mask) + +BTFIXUPDEF_SIMM13(ptrs_per_pmd) +BTFIXUPDEF_SIMM13(ptrs_per_pgd) +BTFIXUPDEF_SIMM13(user_ptrs_per_pgd) + #define pte_ERROR(e) __builtin_trap() #define pmd_ERROR(e) __builtin_trap() #define pgd_ERROR(e) __builtin_trap() -#define PMD_SHIFT 22 +BTFIXUPDEF_INT(page_none) +BTFIXUPDEF_INT(page_copy) +BTFIXUPDEF_INT(page_readonly) +BTFIXUPDEF_INT(page_kernel) + +#define PMD_SHIFT SUN4C_PMD_SHIFT #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) #define PMD_ALIGN(__addr) (((__addr) + ~PMD_MASK) & PMD_MASK) -#define PGDIR_SHIFT SRMMU_PGDIR_SHIFT -#define PGDIR_SIZE SRMMU_PGDIR_SIZE -#define PGDIR_MASK SRMMU_PGDIR_MASK +#define PGDIR_SHIFT BTFIXUP_SIMM13(pgdir_shift) +#define PGDIR_SIZE BTFIXUP_SETHI(pgdir_size) +#define PGDIR_MASK BTFIXUP_SETHI(pgdir_mask) #define PTRS_PER_PTE 1024 -#define PTRS_PER_PMD SRMMU_PTRS_PER_PMD -#define PTRS_PER_PGD SRMMU_PTRS_PER_PGD -#define USER_PTRS_PER_PGD PAGE_OFFSET / SRMMU_PGDIR_SIZE +#define PTRS_PER_PMD BTFIXUP_SIMM13(ptrs_per_pmd) +#define PTRS_PER_PGD BTFIXUP_SIMM13(ptrs_per_pgd) +#define USER_PTRS_PER_PGD BTFIXUP_SIMM13(user_ptrs_per_pgd) #define FIRST_USER_ADDRESS 0 #define PTE_SIZE (PTRS_PER_PTE*4) -#define PAGE_NONE SRMMU_PAGE_NONE -#define PAGE_SHARED SRMMU_PAGE_SHARED -#define PAGE_COPY SRMMU_PAGE_COPY -#define PAGE_READONLY SRMMU_PAGE_RDONLY -#define PAGE_KERNEL SRMMU_PAGE_KERNEL +#define PAGE_NONE __pgprot(BTFIXUP_INT(page_none)) +extern pgprot_t PAGE_SHARED; +#define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy)) +#define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly)) + +extern unsigned long page_kernel; + +#ifdef MODULE +#define PAGE_KERNEL page_kernel +#else +#define PAGE_KERNEL __pgprot(BTFIXUP_INT(page_kernel)) +#endif /* Top-level page directory */ extern pgd_t swapper_pg_dir[1024]; extern void paging_init(void); +/* Page table for 0-4MB for everybody, on the Sparc this + * holds the same as on the i386. + */ +extern pte_t pg0[1024]; +extern pte_t pg1[1024]; +extern pte_t pg2[1024]; +extern pte_t pg3[1024]; + extern unsigned long ptr_in_current_pgd; -/* xwr */ -#define __P000 PAGE_NONE -#define __P001 PAGE_READONLY -#define __P010 PAGE_COPY -#define __P011 PAGE_COPY -#define __P100 PAGE_READONLY -#define __P101 PAGE_READONLY -#define __P110 PAGE_COPY -#define __P111 PAGE_COPY - -#define __S000 PAGE_NONE -#define __S001 PAGE_READONLY -#define __S010 PAGE_SHARED -#define __S011 PAGE_SHARED -#define __S100 PAGE_READONLY -#define __S101 PAGE_READONLY -#define __S110 PAGE_SHARED -#define __S111 PAGE_SHARED +/* Here is a trick, since mmap.c need the initializer elements for + * protection_map[] to be constant at compile time, I set the following + * to all zeros. I set it to the real values after I link in the + * appropriate MMU page table routines at boot time. + */ +#define __P000 __pgprot(0) +#define __P001 __pgprot(0) +#define __P010 __pgprot(0) +#define __P011 __pgprot(0) +#define __P100 __pgprot(0) +#define __P101 __pgprot(0) +#define __P110 __pgprot(0) +#define __P111 __pgprot(0) + +#define __S000 __pgprot(0) +#define __S001 __pgprot(0) +#define __S010 __pgprot(0) +#define __S011 __pgprot(0) +#define __S100 __pgprot(0) +#define __S101 __pgprot(0) +#define __S110 __pgprot(0) +#define __S111 __pgprot(0) extern int num_contexts; @@ -103,137 +137,82 @@ extern unsigned long empty_zero_page; #define ZERO_PAGE(vaddr) (virt_to_page(&empty_zero_page)) /* - * In general all page table modifications should use the V8 atomic - * swap instruction. This insures the mmu and the cpu are in sync - * with respect to ref/mod bits in the page tables. - */ -static inline unsigned long srmmu_swap(unsigned long *addr, unsigned long value) -{ - __asm__ __volatile__("swap [%2], %0" : "=&r" (value) : "0" (value), "r" (addr)); - return value; -} - -/* Certain architectures need to do special things when pte's - * within a page table are directly modified. Thus, the following - * hook is made available. */ +BTFIXUPDEF_CALL_CONST(struct page *, pmd_page, pmd_t) +BTFIXUPDEF_CALL_CONST(unsigned long, pgd_page_vaddr, pgd_t) -static inline void set_pte(pte_t *ptep, pte_t pteval) -{ - srmmu_swap((unsigned long *)ptep, pte_val(pteval)); -} - -#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) - -static inline int srmmu_device_memory(unsigned long x) -{ - return ((x & 0xF0000000) != 0); -} - -static inline struct page *pmd_page(pmd_t pmd) -{ - if (srmmu_device_memory(pmd_val(pmd))) - BUG(); - return pfn_to_page((pmd_val(pmd) & SRMMU_PTD_PMASK) >> (PAGE_SHIFT-4)); -} - -static inline unsigned long pgd_page_vaddr(pgd_t pgd) -{ - if (srmmu_device_memory(pgd_val(pgd))) { - return ~0; - } else { - unsigned long v = pgd_val(pgd) & SRMMU_PTD_PMASK; - return (unsigned long)__nocache_va(v << 4); - } -} +#define pmd_page(pmd) BTFIXUP_CALL(pmd_page)(pmd) +#define pgd_page_vaddr(pgd) BTFIXUP_CALL(pgd_page_vaddr)(pgd) -static inline int pte_present(pte_t pte) -{ - return ((pte_val(pte) & SRMMU_ET_MASK) == SRMMU_ET_PTE); -} +BTFIXUPDEF_CALL_CONST(int, pte_present, pte_t) +BTFIXUPDEF_CALL(void, pte_clear, pte_t *) static inline int pte_none(pte_t pte) { return !pte_val(pte); } -static inline void __pte_clear(pte_t *ptep) -{ - set_pte(ptep, __pte(0)); -} - -static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) -{ - __pte_clear(ptep); -} - -static inline int pmd_bad(pmd_t pmd) -{ - return (pmd_val(pmd) & SRMMU_ET_MASK) != SRMMU_ET_PTD; -} +#define pte_present(pte) BTFIXUP_CALL(pte_present)(pte) +#define pte_clear(mm,addr,pte) BTFIXUP_CALL(pte_clear)(pte) -static inline int pmd_present(pmd_t pmd) -{ - return ((pmd_val(pmd) & SRMMU_ET_MASK) == SRMMU_ET_PTD); -} +BTFIXUPDEF_CALL_CONST(int, pmd_bad, pmd_t) +BTFIXUPDEF_CALL_CONST(int, pmd_present, pmd_t) +BTFIXUPDEF_CALL(void, pmd_clear, pmd_t *) static inline int pmd_none(pmd_t pmd) { return !pmd_val(pmd); } -static inline void pmd_clear(pmd_t *pmdp) -{ - int i; - for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++) - set_pte((pte_t *)&pmdp->pmdv[i], __pte(0)); -} +#define pmd_bad(pmd) BTFIXUP_CALL(pmd_bad)(pmd) +#define pmd_present(pmd) BTFIXUP_CALL(pmd_present)(pmd) +#define pmd_clear(pmd) BTFIXUP_CALL(pmd_clear)(pmd) -static inline int pgd_none(pgd_t pgd) -{ - return !(pgd_val(pgd) & 0xFFFFFFF); -} +BTFIXUPDEF_CALL_CONST(int, pgd_none, pgd_t) +BTFIXUPDEF_CALL_CONST(int, pgd_bad, pgd_t) +BTFIXUPDEF_CALL_CONST(int, pgd_present, pgd_t) +BTFIXUPDEF_CALL(void, pgd_clear, pgd_t *) -static inline int pgd_bad(pgd_t pgd) -{ - return (pgd_val(pgd) & SRMMU_ET_MASK) != SRMMU_ET_PTD; -} - -static inline int pgd_present(pgd_t pgd) -{ - return ((pgd_val(pgd) & SRMMU_ET_MASK) == SRMMU_ET_PTD); -} - -static inline void pgd_clear(pgd_t *pgdp) -{ - set_pte((pte_t *)pgdp, __pte(0)); -} +#define pgd_none(pgd) BTFIXUP_CALL(pgd_none)(pgd) +#define pgd_bad(pgd) BTFIXUP_CALL(pgd_bad)(pgd) +#define pgd_present(pgd) BTFIXUP_CALL(pgd_present)(pgd) +#define pgd_clear(pgd) BTFIXUP_CALL(pgd_clear)(pgd) /* * The following only work if pte_present() is true. * Undefined behaviour if not.. */ +BTFIXUPDEF_HALF(pte_writei) +BTFIXUPDEF_HALF(pte_dirtyi) +BTFIXUPDEF_HALF(pte_youngi) + +static int pte_write(pte_t pte) __attribute_const__; static inline int pte_write(pte_t pte) { - return pte_val(pte) & SRMMU_WRITE; + return pte_val(pte) & BTFIXUP_HALF(pte_writei); } +static int pte_dirty(pte_t pte) __attribute_const__; static inline int pte_dirty(pte_t pte) { - return pte_val(pte) & SRMMU_DIRTY; + return pte_val(pte) & BTFIXUP_HALF(pte_dirtyi); } +static int pte_young(pte_t pte) __attribute_const__; static inline int pte_young(pte_t pte) { - return pte_val(pte) & SRMMU_REF; + return pte_val(pte) & BTFIXUP_HALF(pte_youngi); } /* * The following only work if pte_present() is not true. */ +BTFIXUPDEF_HALF(pte_filei) + +static int pte_file(pte_t pte) __attribute_const__; static inline int pte_file(pte_t pte) { - return pte_val(pte) & SRMMU_FILE; + return pte_val(pte) & BTFIXUP_HALF(pte_filei); } static inline int pte_special(pte_t pte) @@ -241,85 +220,68 @@ static inline int pte_special(pte_t pte) return 0; } +/* + */ +BTFIXUPDEF_HALF(pte_wrprotecti) +BTFIXUPDEF_HALF(pte_mkcleani) +BTFIXUPDEF_HALF(pte_mkoldi) + +static pte_t pte_wrprotect(pte_t pte) __attribute_const__; static inline pte_t pte_wrprotect(pte_t pte) { - return __pte(pte_val(pte) & ~SRMMU_WRITE); + return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_wrprotecti)); } +static pte_t pte_mkclean(pte_t pte) __attribute_const__; static inline pte_t pte_mkclean(pte_t pte) { - return __pte(pte_val(pte) & ~SRMMU_DIRTY); + return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_mkcleani)); } +static pte_t pte_mkold(pte_t pte) __attribute_const__; static inline pte_t pte_mkold(pte_t pte) { - return __pte(pte_val(pte) & ~SRMMU_REF); + return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_mkoldi)); } -static inline pte_t pte_mkwrite(pte_t pte) -{ - return __pte(pte_val(pte) | SRMMU_WRITE); -} - -static inline pte_t pte_mkdirty(pte_t pte) -{ - return __pte(pte_val(pte) | SRMMU_DIRTY); -} +BTFIXUPDEF_CALL_CONST(pte_t, pte_mkwrite, pte_t) +BTFIXUPDEF_CALL_CONST(pte_t, pte_mkdirty, pte_t) +BTFIXUPDEF_CALL_CONST(pte_t, pte_mkyoung, pte_t) -static inline pte_t pte_mkyoung(pte_t pte) -{ - return __pte(pte_val(pte) | SRMMU_REF); -} +#define pte_mkwrite(pte) BTFIXUP_CALL(pte_mkwrite)(pte) +#define pte_mkdirty(pte) BTFIXUP_CALL(pte_mkdirty)(pte) +#define pte_mkyoung(pte) BTFIXUP_CALL(pte_mkyoung)(pte) #define pte_mkspecial(pte) (pte) #define pfn_pte(pfn, prot) mk_pte(pfn_to_page(pfn), prot) -static inline unsigned long pte_pfn(pte_t pte) -{ - if (srmmu_device_memory(pte_val(pte))) { - /* Just return something that will cause - * pfn_valid() to return false. This makes - * copy_one_pte() to just directly copy to - * PTE over. - */ - return ~0UL; - } - return (pte_val(pte) & SRMMU_PTE_PMASK) >> (PAGE_SHIFT-4); -} - +BTFIXUPDEF_CALL(unsigned long, pte_pfn, pte_t) +#define pte_pfn(pte) BTFIXUP_CALL(pte_pfn)(pte) #define pte_page(pte) pfn_to_page(pte_pfn(pte)) /* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. */ -static inline pte_t mk_pte(struct page *page, pgprot_t pgprot) -{ - return __pte((page_to_pfn(page) << (PAGE_SHIFT-4)) | pgprot_val(pgprot)); -} +BTFIXUPDEF_CALL_CONST(pte_t, mk_pte, struct page *, pgprot_t) -static inline pte_t mk_pte_phys(unsigned long page, pgprot_t pgprot) -{ - return __pte(((page) >> 4) | pgprot_val(pgprot)); -} +BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_phys, unsigned long, pgprot_t) +BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_io, unsigned long, pgprot_t, int) +BTFIXUPDEF_CALL_CONST(pgprot_t, pgprot_noncached, pgprot_t) -static inline pte_t mk_pte_io(unsigned long page, pgprot_t pgprot, int space) -{ - return __pte(((page) >> 4) | (space << 28) | pgprot_val(pgprot)); -} +#define mk_pte(page,pgprot) BTFIXUP_CALL(mk_pte)(page,pgprot) +#define mk_pte_phys(page,pgprot) BTFIXUP_CALL(mk_pte_phys)(page,pgprot) +#define mk_pte_io(page,pgprot,space) BTFIXUP_CALL(mk_pte_io)(page,pgprot,space) -#define pgprot_noncached pgprot_noncached -static inline pgprot_t pgprot_noncached(pgprot_t prot) -{ - prot &= ~__pgprot(SRMMU_CACHE); - return prot; -} +#define pgprot_noncached(pgprot) BTFIXUP_CALL(pgprot_noncached)(pgprot) + +BTFIXUPDEF_INT(pte_modify_mask) static pte_t pte_modify(pte_t pte, pgprot_t newprot) __attribute_const__; static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { - return __pte((pte_val(pte) & SRMMU_CHG_MASK) | + return __pte((pte_val(pte) & BTFIXUP_INT(pte_modify_mask)) | pgprot_val(newprot)); } @@ -332,69 +294,74 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #define pgd_offset_k(address) pgd_offset(&init_mm, address) /* Find an entry in the second-level page table.. */ -static inline pmd_t *pmd_offset(pgd_t * dir, unsigned long address) -{ - return (pmd_t *) pgd_page_vaddr(*dir) + - ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1)); -} +BTFIXUPDEF_CALL(pmd_t *, pmd_offset, pgd_t *, unsigned long) +#define pmd_offset(dir,addr) BTFIXUP_CALL(pmd_offset)(dir,addr) /* Find an entry in the third-level page table.. */ -pte_t *pte_offset_kernel(pmd_t * dir, unsigned long address); +BTFIXUPDEF_CALL(pte_t *, pte_offset_kernel, pmd_t *, unsigned long) +#define pte_offset_kernel(dir,addr) BTFIXUP_CALL(pte_offset_kernel)(dir,addr) /* - * This shortcut works on sun4m (and sun4d) because the nocache area is static. + * This shortcut works on sun4m (and sun4d) because the nocache area is static, + * and sun4c is guaranteed to have no highmem anyway. */ #define pte_offset_map(d, a) pte_offset_kernel(d,a) #define pte_unmap(pte) do{}while(0) +/* Certain architectures need to do special things when pte's + * within a page table are directly modified. Thus, the following + * hook is made available. + */ + +BTFIXUPDEF_CALL(void, set_pte, pte_t *, pte_t) + +#define set_pte(ptep,pteval) BTFIXUP_CALL(set_pte)(ptep,pteval) +#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) + struct seq_file; -void mmu_info(struct seq_file *m); +BTFIXUPDEF_CALL(void, mmu_info, struct seq_file *) + +#define mmu_info(p) BTFIXUP_CALL(mmu_info)(p) /* Fault handler stuff... */ #define FAULT_CODE_PROT 0x1 #define FAULT_CODE_WRITE 0x2 #define FAULT_CODE_USER 0x4 -#define update_mmu_cache(vma, address, ptep) do { } while (0) +BTFIXUPDEF_CALL(void, update_mmu_cache, struct vm_area_struct *, unsigned long, pte_t *) -void srmmu_mapiorange(unsigned int bus, unsigned long xpa, - unsigned long xva, unsigned int len); -void srmmu_unmapiorange(unsigned long virt_addr, unsigned int len); +#define update_mmu_cache(vma,addr,ptep) BTFIXUP_CALL(update_mmu_cache)(vma,addr,ptep) -/* Encode and de-code a swap entry */ -static inline unsigned long __swp_type(swp_entry_t entry) -{ - return (entry.val >> SRMMU_SWP_TYPE_SHIFT) & SRMMU_SWP_TYPE_MASK; -} +BTFIXUPDEF_CALL(void, sparc_mapiorange, unsigned int, unsigned long, + unsigned long, unsigned int) +BTFIXUPDEF_CALL(void, sparc_unmapiorange, unsigned long, unsigned int) +#define sparc_mapiorange(bus,pa,va,len) BTFIXUP_CALL(sparc_mapiorange)(bus,pa,va,len) +#define sparc_unmapiorange(va,len) BTFIXUP_CALL(sparc_unmapiorange)(va,len) -static inline unsigned long __swp_offset(swp_entry_t entry) -{ - return (entry.val >> SRMMU_SWP_OFF_SHIFT) & SRMMU_SWP_OFF_MASK; -} +extern int invalid_segment; -static inline swp_entry_t __swp_entry(unsigned long type, unsigned long offset) -{ - return (swp_entry_t) { - (type & SRMMU_SWP_TYPE_MASK) << SRMMU_SWP_TYPE_SHIFT - | (offset & SRMMU_SWP_OFF_MASK) << SRMMU_SWP_OFF_SHIFT }; -} +/* Encode and de-code a swap entry */ +BTFIXUPDEF_CALL(unsigned long, __swp_type, swp_entry_t) +BTFIXUPDEF_CALL(unsigned long, __swp_offset, swp_entry_t) +BTFIXUPDEF_CALL(swp_entry_t, __swp_entry, unsigned long, unsigned long) + +#define __swp_type(__x) BTFIXUP_CALL(__swp_type)(__x) +#define __swp_offset(__x) BTFIXUP_CALL(__swp_offset)(__x) +#define __swp_entry(__type,__off) BTFIXUP_CALL(__swp_entry)(__type,__off) #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) /* file-offset-in-pte helpers */ -static inline unsigned long pte_to_pgoff(pte_t pte) -{ - return pte_val(pte) >> SRMMU_PTE_FILE_SHIFT; -} +BTFIXUPDEF_CALL(unsigned long, pte_to_pgoff, pte_t pte); +BTFIXUPDEF_CALL(pte_t, pgoff_to_pte, unsigned long pgoff); -static inline pte_t pgoff_to_pte(unsigned long pgoff) -{ - return __pte((pgoff << SRMMU_PTE_FILE_SHIFT) | SRMMU_FILE); -} +#define pte_to_pgoff(pte) BTFIXUP_CALL(pte_to_pgoff)(pte) +#define pgoff_to_pte(off) BTFIXUP_CALL(pgoff_to_pte)(off) /* * This is made a constant because mm/fremap.c required a constant. + * Note that layout of these bits is different between sun4c.c and srmmu.c. */ #define PTE_FILE_MAX_BITS 24 @@ -432,6 +399,9 @@ static inline unsigned long __get_phys (unsigned long addr) { switch (sparc_cpu_model){ + case sun4: + case sun4c: + return sun4c_get_pte (addr) << PAGE_SHIFT; case sun4m: case sun4d: return ((srmmu_get_pte (addr) & 0xffffff00) << 4); @@ -444,6 +414,9 @@ static inline int __get_iospace (unsigned long addr) { switch (sparc_cpu_model){ + case sun4: + case sun4c: + return -1; /* Don't check iospace on sun4c */ case sun4m: case sun4d: return (srmmu_get_pte (addr) >> 28); @@ -490,7 +463,7 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma, set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry); \ flush_tlb_page(__vma, __address); \ } \ - __changed; \ + (sparc_cpu_model == sun4c) || __changed; \ }) #include @@ -498,8 +471,10 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma, #endif /* !(__ASSEMBLY__) */ #define VMALLOC_START _AC(0xfe600000,UL) +/* XXX Alter this when I get around to fixing sun4c - Anton */ #define VMALLOC_END _AC(0xffc00000,UL) + /* We provide our own get_unmapped_area to cope with VA holes for userland */ #define HAVE_ARCH_UNMAPPED_AREA diff --git a/trunk/arch/sparc/include/asm/pgtable_64.h b/trunk/arch/sparc/include/asm/pgtable_64.h index 61210db139fb..76e4a52aa85e 100644 --- a/trunk/arch/sparc/include/asm/pgtable_64.h +++ b/trunk/arch/sparc/include/asm/pgtable_64.h @@ -717,6 +717,10 @@ extern unsigned long find_ecache_flush_span(unsigned long size); struct seq_file; extern void mmu_info(struct seq_file *); +/* These do nothing with the way I have things setup. */ +#define mmu_lockarea(vaddr, len) (vaddr) +#define mmu_unlockarea(vaddr, len) do { } while(0) + struct vm_area_struct; extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *); diff --git a/trunk/arch/sparc/include/asm/pgtsrmmu.h b/trunk/arch/sparc/include/asm/pgtsrmmu.h index cb828703a63a..f6ae2b2b6870 100644 --- a/trunk/arch/sparc/include/asm/pgtsrmmu.h +++ b/trunk/arch/sparc/include/asm/pgtsrmmu.h @@ -173,6 +173,17 @@ static inline void srmmu_set_ctable_ptr(unsigned long paddr) "memory"); } +static inline unsigned long srmmu_get_ctable_ptr(void) +{ + unsigned int retval; + + __asm__ __volatile__("lda [%1] %2, %0\n\t" : + "=r" (retval) : + "r" (SRMMU_CTXTBL_PTR), + "i" (ASI_M_MMUREGS)); + return (retval & SRMMU_CTX_PMASK) << 4; +} + static inline void srmmu_set_context(int context) { __asm__ __volatile__("sta %0, [%1] %2\n\t" : : @@ -220,6 +231,42 @@ static inline void srmmu_flush_whole_tlb(void) } /* These flush types are not available on all chips... */ +static inline void srmmu_flush_tlb_ctx(void) +{ + __asm__ __volatile__("sta %%g0, [%0] %1\n\t": : + "r" (0x300), /* Flush TLB ctx.. */ + "i" (ASI_M_FLUSH_PROBE) : "memory"); + +} + +static inline void srmmu_flush_tlb_region(unsigned long addr) +{ + addr &= SRMMU_PGDIR_MASK; + __asm__ __volatile__("sta %%g0, [%0] %1\n\t": : + "r" (addr | 0x200), /* Flush TLB region.. */ + "i" (ASI_M_FLUSH_PROBE) : "memory"); + +} + + +static inline void srmmu_flush_tlb_segment(unsigned long addr) +{ + addr &= SRMMU_REAL_PMD_MASK; + __asm__ __volatile__("sta %%g0, [%0] %1\n\t": : + "r" (addr | 0x100), /* Flush TLB segment.. */ + "i" (ASI_M_FLUSH_PROBE) : "memory"); + +} + +static inline void srmmu_flush_tlb_page(unsigned long page) +{ + page &= PAGE_MASK; + __asm__ __volatile__("sta %%g0, [%0] %1\n\t": : + "r" (page), /* Flush TLB page.. */ + "i" (ASI_M_FLUSH_PROBE) : "memory"); + +} + #ifndef CONFIG_SPARC_LEON static inline unsigned long srmmu_hwprobe(unsigned long vaddr) { @@ -247,6 +294,9 @@ srmmu_get_pte (unsigned long addr) return entry; } +extern unsigned long (*srmmu_read_physical)(unsigned long paddr); +extern void (*srmmu_write_physical)(unsigned long paddr, unsigned long word); + #endif /* !(__ASSEMBLY__) */ #endif /* !(_SPARC_PGTSRMMU_H) */ diff --git a/trunk/arch/sparc/include/asm/pgtsun4c.h b/trunk/arch/sparc/include/asm/pgtsun4c.h new file mode 100644 index 000000000000..aeb25e912179 --- /dev/null +++ b/trunk/arch/sparc/include/asm/pgtsun4c.h @@ -0,0 +1,172 @@ +/* + * pgtsun4c.h: Sun4c specific pgtable.h defines and code. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ +#ifndef _SPARC_PGTSUN4C_H +#define _SPARC_PGTSUN4C_H + +#include + +/* PMD_SHIFT determines the size of the area a second-level page table can map */ +#define SUN4C_PMD_SHIFT 22 + +/* PGDIR_SHIFT determines what a third-level page table entry can map */ +#define SUN4C_PGDIR_SHIFT 22 +#define SUN4C_PGDIR_SIZE (1UL << SUN4C_PGDIR_SHIFT) +#define SUN4C_PGDIR_MASK (~(SUN4C_PGDIR_SIZE-1)) +#define SUN4C_PGDIR_ALIGN(addr) (((addr)+SUN4C_PGDIR_SIZE-1)&SUN4C_PGDIR_MASK) + +/* To represent how the sun4c mmu really lays things out. */ +#define SUN4C_REAL_PGDIR_SHIFT 18 +#define SUN4C_REAL_PGDIR_SIZE (1UL << SUN4C_REAL_PGDIR_SHIFT) +#define SUN4C_REAL_PGDIR_MASK (~(SUN4C_REAL_PGDIR_SIZE-1)) +#define SUN4C_REAL_PGDIR_ALIGN(addr) (((addr)+SUN4C_REAL_PGDIR_SIZE-1)&SUN4C_REAL_PGDIR_MASK) + +/* 16 bit PFN on sun4c */ +#define SUN4C_PFN_MASK 0xffff + +/* Don't increase these unless the structures in sun4c.c are fixed */ +#define SUN4C_MAX_SEGMAPS 256 +#define SUN4C_MAX_CONTEXTS 16 + +/* + * To be efficient, and not have to worry about allocating such + * a huge pgd, we make the kernel sun4c tables each hold 1024 + * entries and the pgd similarly just like the i386 tables. + */ +#define SUN4C_PTRS_PER_PTE 1024 +#define SUN4C_PTRS_PER_PMD 1 +#define SUN4C_PTRS_PER_PGD 1024 + +/* + * Sparc SUN4C pte fields. + */ +#define _SUN4C_PAGE_VALID 0x80000000 +#define _SUN4C_PAGE_SILENT_READ 0x80000000 /* synonym */ +#define _SUN4C_PAGE_DIRTY 0x40000000 +#define _SUN4C_PAGE_SILENT_WRITE 0x40000000 /* synonym */ +#define _SUN4C_PAGE_PRIV 0x20000000 /* privileged page */ +#define _SUN4C_PAGE_NOCACHE 0x10000000 /* non-cacheable page */ +#define _SUN4C_PAGE_PRESENT 0x08000000 /* implemented in software */ +#define _SUN4C_PAGE_IO 0x04000000 /* I/O page */ +#define _SUN4C_PAGE_FILE 0x02000000 /* implemented in software */ +#define _SUN4C_PAGE_READ 0x00800000 /* implemented in software */ +#define _SUN4C_PAGE_WRITE 0x00400000 /* implemented in software */ +#define _SUN4C_PAGE_ACCESSED 0x00200000 /* implemented in software */ +#define _SUN4C_PAGE_MODIFIED 0x00100000 /* implemented in software */ + +#define _SUN4C_READABLE (_SUN4C_PAGE_READ|_SUN4C_PAGE_SILENT_READ|\ + _SUN4C_PAGE_ACCESSED) +#define _SUN4C_WRITEABLE (_SUN4C_PAGE_WRITE|_SUN4C_PAGE_SILENT_WRITE|\ + _SUN4C_PAGE_MODIFIED) + +#define _SUN4C_PAGE_CHG_MASK (0xffff|_SUN4C_PAGE_ACCESSED|_SUN4C_PAGE_MODIFIED) + +#define SUN4C_PAGE_NONE __pgprot(_SUN4C_PAGE_PRESENT) +#define SUN4C_PAGE_SHARED __pgprot(_SUN4C_PAGE_PRESENT|_SUN4C_READABLE|\ + _SUN4C_PAGE_WRITE) +#define SUN4C_PAGE_COPY __pgprot(_SUN4C_PAGE_PRESENT|_SUN4C_READABLE) +#define SUN4C_PAGE_READONLY __pgprot(_SUN4C_PAGE_PRESENT|_SUN4C_READABLE) +#define SUN4C_PAGE_KERNEL __pgprot(_SUN4C_READABLE|_SUN4C_WRITEABLE|\ + _SUN4C_PAGE_DIRTY|_SUN4C_PAGE_PRIV) + +/* SUN4C swap entry encoding + * + * We use 5 bits for the type and 19 for the offset. This gives us + * 32 swapfiles of 4GB each. Encoding looks like: + * + * RRRRRRRRooooooooooooooooooottttt + * fedcba9876543210fedcba9876543210 + * + * The top 8 bits are reserved for protection and status bits, especially + * FILE and PRESENT. + */ +#define SUN4C_SWP_TYPE_MASK 0x1f +#define SUN4C_SWP_OFF_MASK 0x7ffff +#define SUN4C_SWP_OFF_SHIFT 5 + +#ifndef __ASSEMBLY__ + +static inline unsigned long sun4c_get_synchronous_error(void) +{ + unsigned long sync_err; + + __asm__ __volatile__("lda [%1] %2, %0\n\t" : + "=r" (sync_err) : + "r" (AC_SYNC_ERR), "i" (ASI_CONTROL)); + return sync_err; +} + +static inline unsigned long sun4c_get_synchronous_address(void) +{ + unsigned long sync_addr; + + __asm__ __volatile__("lda [%1] %2, %0\n\t" : + "=r" (sync_addr) : + "r" (AC_SYNC_VA), "i" (ASI_CONTROL)); + return sync_addr; +} + +/* SUN4C pte, segmap, and context manipulation */ +static inline unsigned long sun4c_get_segmap(unsigned long addr) +{ + register unsigned long entry; + + __asm__ __volatile__("\n\tlduba [%1] %2, %0\n\t" : + "=r" (entry) : + "r" (addr), "i" (ASI_SEGMAP)); + + return entry; +} + +static inline void sun4c_put_segmap(unsigned long addr, unsigned long entry) +{ + + __asm__ __volatile__("\n\tstba %1, [%0] %2; nop; nop; nop;\n\t" : : + "r" (addr), "r" (entry), + "i" (ASI_SEGMAP) + : "memory"); +} + +static inline unsigned long sun4c_get_pte(unsigned long addr) +{ + register unsigned long entry; + + __asm__ __volatile__("\n\tlda [%1] %2, %0\n\t" : + "=r" (entry) : + "r" (addr), "i" (ASI_PTE)); + return entry; +} + +static inline void sun4c_put_pte(unsigned long addr, unsigned long entry) +{ + __asm__ __volatile__("\n\tsta %1, [%0] %2; nop; nop; nop;\n\t" : : + "r" (addr), + "r" ((entry & ~(_SUN4C_PAGE_PRESENT))), "i" (ASI_PTE) + : "memory"); +} + +static inline int sun4c_get_context(void) +{ + register int ctx; + + __asm__ __volatile__("\n\tlduba [%1] %2, %0\n\t" : + "=r" (ctx) : + "r" (AC_CONTEXT), "i" (ASI_CONTROL)); + + return ctx; +} + +static inline int sun4c_set_context(int ctx) +{ + __asm__ __volatile__("\n\tstba %0, [%1] %2; nop; nop; nop;\n\t" : : + "r" (ctx), "r" (AC_CONTEXT), "i" (ASI_CONTROL) + : "memory"); + + return ctx; +} + +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(_SPARC_PGTSUN4C_H) */ diff --git a/trunk/arch/sparc/include/asm/processor_32.h b/trunk/arch/sparc/include/asm/processor_32.h index 9cbd854fdfdd..09521c6a5edb 100644 --- a/trunk/arch/sparc/include/asm/processor_32.h +++ b/trunk/arch/sparc/include/asm/processor_32.h @@ -16,6 +16,7 @@ #include #include #include +#include #include /* diff --git a/trunk/arch/sparc/include/asm/setup.h b/trunk/arch/sparc/include/asm/setup.h index 8a83699a5507..00497abec996 100644 --- a/trunk/arch/sparc/include/asm/setup.h +++ b/trunk/arch/sparc/include/asm/setup.h @@ -20,7 +20,10 @@ extern char reboot_command[]; * Only sun4d + leon may have boot_cpu_id != 0 */ extern unsigned char boot_cpu_id; +extern unsigned char boot_cpu_id4; +extern unsigned long empty_bad_page; +extern unsigned long empty_bad_page_table; extern unsigned long empty_zero_page; extern int serial_console; diff --git a/trunk/arch/sparc/include/asm/shmparam_32.h b/trunk/arch/sparc/include/asm/shmparam_32.h index 142825c8d3ac..59a1243c12f3 100644 --- a/trunk/arch/sparc/include/asm/shmparam_32.h +++ b/trunk/arch/sparc/include/asm/shmparam_32.h @@ -4,6 +4,8 @@ #define __ARCH_FORCE_SHMLBA 1 extern int vac_cache_size; -#define SHMLBA (vac_cache_size ? vac_cache_size : PAGE_SIZE) +#define SHMLBA (vac_cache_size ? vac_cache_size : \ + (sparc_cpu_model == sun4c ? (64 * 1024) : \ + (sparc_cpu_model == sun4 ? (128 * 1024) : PAGE_SIZE))) #endif /* _ASMSPARC_SHMPARAM_H */ diff --git a/trunk/arch/sparc/include/asm/smp_32.h b/trunk/arch/sparc/include/asm/smp_32.h index b73da3c5f10a..01c51c704341 100644 --- a/trunk/arch/sparc/include/asm/smp_32.h +++ b/trunk/arch/sparc/include/asm/smp_32.h @@ -8,6 +8,7 @@ #include #include +#include #ifndef __ASSEMBLY__ @@ -57,53 +58,104 @@ struct seq_file; void smp_bogo(struct seq_file *); void smp_info(struct seq_file *); -struct sparc32_ipi_ops { - void (*cross_call)(smpfunc_t func, cpumask_t mask, unsigned long arg1, - unsigned long arg2, unsigned long arg3, - unsigned long arg4); - void (*resched)(int cpu); - void (*single)(int cpu); - void (*mask_one)(int cpu); -}; -extern const struct sparc32_ipi_ops *sparc32_ipi_ops; - -static inline void xc0(smpfunc_t func) -{ - sparc32_ipi_ops->cross_call(func, *cpu_online_mask, 0, 0, 0, 0); -} +BTFIXUPDEF_CALL(void, smp_cross_call, smpfunc_t, cpumask_t, unsigned long, unsigned long, unsigned long, unsigned long) +BTFIXUPDEF_CALL(int, __hard_smp_processor_id, void) +BTFIXUPDEF_CALL(void, smp_ipi_resched, int); +BTFIXUPDEF_CALL(void, smp_ipi_single, int); +BTFIXUPDEF_CALL(void, smp_ipi_mask_one, int); +BTFIXUPDEF_BLACKBOX(hard_smp_processor_id) +BTFIXUPDEF_BLACKBOX(load_current) +#define smp_cross_call(func,mask,arg1,arg2,arg3,arg4) BTFIXUP_CALL(smp_cross_call)(func,mask,arg1,arg2,arg3,arg4) + +static inline void xc0(smpfunc_t func) { smp_cross_call(func, *cpu_online_mask, 0, 0, 0, 0); } static inline void xc1(smpfunc_t func, unsigned long arg1) -{ - sparc32_ipi_ops->cross_call(func, *cpu_online_mask, arg1, 0, 0, 0); -} +{ smp_cross_call(func, *cpu_online_mask, arg1, 0, 0, 0); } static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2) +{ smp_cross_call(func, *cpu_online_mask, arg1, arg2, 0, 0); } +static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2, + unsigned long arg3) +{ smp_cross_call(func, *cpu_online_mask, arg1, arg2, arg3, 0); } +static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2, + unsigned long arg3, unsigned long arg4) +{ smp_cross_call(func, *cpu_online_mask, arg1, arg2, arg3, arg4); } + +extern void arch_send_call_function_single_ipi(int cpu); +extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); + +static inline int cpu_logical_map(int cpu) { - sparc32_ipi_ops->cross_call(func, *cpu_online_mask, arg1, arg2, 0, 0); + return cpu; } -static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2, - unsigned long arg3) +static inline int hard_smp4m_processor_id(void) { - sparc32_ipi_ops->cross_call(func, *cpu_online_mask, - arg1, arg2, arg3, 0); + int cpuid; + + __asm__ __volatile__("rd %%tbr, %0\n\t" + "srl %0, 12, %0\n\t" + "and %0, 3, %0\n\t" : + "=&r" (cpuid)); + return cpuid; } -static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2, - unsigned long arg3, unsigned long arg4) +static inline int hard_smp4d_processor_id(void) { - sparc32_ipi_ops->cross_call(func, *cpu_online_mask, - arg1, arg2, arg3, arg4); + int cpuid; + + __asm__ __volatile__("lda [%%g0] %1, %0\n\t" : + "=&r" (cpuid) : "i" (ASI_M_VIKING_TMP1)); + return cpuid; } -extern void arch_send_call_function_single_ipi(int cpu); -extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); +extern inline int hard_smpleon_processor_id(void) +{ + int cpuid; + __asm__ __volatile__("rd %%asr17,%0\n\t" + "srl %0,28,%0" : + "=&r" (cpuid) : ); + return cpuid; +} -static inline int cpu_logical_map(int cpu) +#ifndef MODULE +static inline int hard_smp_processor_id(void) { - return cpu; + int cpuid; + + /* Black box - sun4m + __asm__ __volatile__("rd %%tbr, %0\n\t" + "srl %0, 12, %0\n\t" + "and %0, 3, %0\n\t" : + "=&r" (cpuid)); + - sun4d + __asm__ __volatile__("lda [%g0] ASI_M_VIKING_TMP1, %0\n\t" + "nop; nop" : + "=&r" (cpuid)); + - leon + __asm__ __volatile__( "rd %asr17, %0\n\t" + "srl %0, 0x1c, %0\n\t" + "nop\n\t" : + "=&r" (cpuid)); + See btfixup.h and btfixupprep.c to understand how a blackbox works. + */ + __asm__ __volatile__("sethi %%hi(___b_hard_smp_processor_id), %0\n\t" + "sethi %%hi(boot_cpu_id), %0\n\t" + "ldub [%0 + %%lo(boot_cpu_id)], %0\n\t" : + "=&r" (cpuid)); + return cpuid; } +#else +static inline int hard_smp_processor_id(void) +{ + int cpuid; -extern int hard_smp_processor_id(void); + __asm__ __volatile__("mov %%o7, %%g1\n\t" + "call ___f___hard_smp_processor_id\n\t" + " nop\n\t" + "mov %%g2, %0\n\t" : "=r"(cpuid) : : "g1", "g2"); + return cpuid; +} +#endif #define raw_smp_processor_id() (current_thread_info()->cpu) diff --git a/trunk/arch/sparc/include/asm/smpprim.h b/trunk/arch/sparc/include/asm/smpprim.h new file mode 100644 index 000000000000..eb849d862c64 --- /dev/null +++ b/trunk/arch/sparc/include/asm/smpprim.h @@ -0,0 +1,54 @@ +/* + * smpprim.h: SMP locking primitives on the Sparc + * + * God knows we won't be actually using this code for some time + * but I thought I'd write it since I knew how. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef __SPARC_SMPPRIM_H +#define __SPARC_SMPPRIM_H + +/* Test and set the unsigned byte at ADDR to 1. Returns the previous + * value. On the Sparc we use the ldstub instruction since it is + * atomic. + */ + +static inline __volatile__ char test_and_set(void *addr) +{ + char state = 0; + + __asm__ __volatile__("ldstub [%0], %1 ! test_and_set\n\t" + "=r" (addr), "=r" (state) : + "0" (addr), "1" (state) : "memory"); + + return state; +} + +/* Initialize a spin-lock. */ +static inline __volatile__ smp_initlock(void *spinlock) +{ + /* Unset the lock. */ + *((unsigned char *) spinlock) = 0; + + return; +} + +/* This routine spins until it acquires the lock at ADDR. */ +static inline __volatile__ smp_lock(void *addr) +{ + while(test_and_set(addr) == 0xff) + ; + + /* We now have the lock */ + return; +} + +/* This routine releases the lock at ADDR. */ +static inline __volatile__ smp_unlock(void *addr) +{ + *((unsigned char *) addr) = 0; +} + +#endif /* !(__SPARC_SMPPRIM_H) */ diff --git a/trunk/arch/sparc/include/asm/string_32.h b/trunk/arch/sparc/include/asm/string_32.h index 12f67857152e..edf196ee4ef8 100644 --- a/trunk/arch/sparc/include/asm/string_32.h +++ b/trunk/arch/sparc/include/asm/string_32.h @@ -61,7 +61,68 @@ extern int memcmp(const void *,const void *,__kernel_size_t); extern __kernel_size_t strlen(const char *); #define __HAVE_ARCH_STRNCMP -extern int strncmp(const char *, const char *, __kernel_size_t); + +extern int __strncmp(const char *, const char *, __kernel_size_t); + +static inline int __constant_strncmp(const char *src, const char *dest, __kernel_size_t count) +{ + register int retval; + switch(count) { + case 0: return 0; + case 1: return (src[0] - dest[0]); + case 2: retval = (src[0] - dest[0]); + if(!retval && src[0]) + retval = (src[1] - dest[1]); + return retval; + case 3: retval = (src[0] - dest[0]); + if(!retval && src[0]) { + retval = (src[1] - dest[1]); + if(!retval && src[1]) + retval = (src[2] - dest[2]); + } + return retval; + case 4: retval = (src[0] - dest[0]); + if(!retval && src[0]) { + retval = (src[1] - dest[1]); + if(!retval && src[1]) { + retval = (src[2] - dest[2]); + if (!retval && src[2]) + retval = (src[3] - dest[3]); + } + } + return retval; + case 5: retval = (src[0] - dest[0]); + if(!retval && src[0]) { + retval = (src[1] - dest[1]); + if(!retval && src[1]) { + retval = (src[2] - dest[2]); + if (!retval && src[2]) { + retval = (src[3] - dest[3]); + if (!retval && src[3]) + retval = (src[4] - dest[4]); + } + } + } + return retval; + default: + retval = (src[0] - dest[0]); + if(!retval && src[0]) { + retval = (src[1] - dest[1]); + if(!retval && src[1]) { + retval = (src[2] - dest[2]); + if(!retval && src[2]) + retval = __strncmp(src+3,dest+3,count-3); + } + } + return retval; + } +} + +#undef strncmp +#define strncmp(__arg0, __arg1, __arg2) \ +(__builtin_constant_p(__arg2) ? \ + __constant_strncmp(__arg0, __arg1, __arg2) : \ + __strncmp(__arg0, __arg1, __arg2)) #endif /* !EXPORT_SYMTAB_STROPS */ diff --git a/trunk/arch/sparc/include/asm/sysen.h b/trunk/arch/sparc/include/asm/sysen.h new file mode 100644 index 000000000000..6af34abde6e7 --- /dev/null +++ b/trunk/arch/sparc/include/asm/sysen.h @@ -0,0 +1,15 @@ +/* + * sysen.h: Bit fields within the "System Enable" register accessed via + * the ASI_CONTROL address space at address AC_SYSENABLE. + * + * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef _SPARC_SYSEN_H +#define _SPARC_SYSEN_H + +#define SENABLE_DVMA 0x20 /* enable dvma transfers */ +#define SENABLE_CACHE 0x10 /* enable VAC cache */ +#define SENABLE_RESET 0x04 /* reset whole machine, danger Will Robinson */ + +#endif /* _SPARC_SYSEN_H */ diff --git a/trunk/arch/sparc/include/asm/thread_info_32.h b/trunk/arch/sparc/include/asm/thread_info_32.h index 21a38946541d..c2a1080cdd3b 100644 --- a/trunk/arch/sparc/include/asm/thread_info_32.h +++ b/trunk/arch/sparc/include/asm/thread_info_32.h @@ -15,6 +15,7 @@ #ifndef __ASSEMBLY__ +#include #include #include @@ -79,8 +80,13 @@ register struct thread_info *current_thread_info_reg asm("g6"); */ #define THREAD_INFO_ORDER 1 -struct thread_info * alloc_thread_info_node(struct task_struct *tsk, int node); -void free_thread_info(struct thread_info *); +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + +BTFIXUPDEF_CALL(struct thread_info *, alloc_thread_info_node, int) +#define alloc_thread_info_node(tsk, node) BTFIXUP_CALL(alloc_thread_info_node)(node) + +BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *) +#define free_thread_info(ti) BTFIXUP_CALL(free_thread_info)(ti) #endif /* __ASSEMBLY__ */ diff --git a/trunk/arch/sparc/include/asm/thread_info_64.h b/trunk/arch/sparc/include/asm/thread_info_64.h index 7f0981b09451..01d057fe6a3f 100644 --- a/trunk/arch/sparc/include/asm/thread_info_64.h +++ b/trunk/arch/sparc/include/asm/thread_info_64.h @@ -138,11 +138,32 @@ register struct thread_info *current_thread_info_reg asm("g6"); /* thread information allocation */ #if PAGE_SHIFT == 13 -#define THREAD_SIZE_ORDER 1 +#define __THREAD_INFO_ORDER 1 #else /* PAGE_SHIFT == 13 */ -#define THREAD_SIZE_ORDER 0 +#define __THREAD_INFO_ORDER 0 #endif /* PAGE_SHIFT == 13 */ +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + +#ifdef CONFIG_DEBUG_STACK_USAGE +#define THREAD_FLAGS (GFP_KERNEL | __GFP_ZERO) +#else +#define THREAD_FLAGS (GFP_KERNEL) +#endif + +#define alloc_thread_info_node(tsk, node) \ +({ \ + struct page *page = alloc_pages_node(node, THREAD_FLAGS, \ + __THREAD_INFO_ORDER); \ + struct thread_info *ret; \ + \ + ret = page ? page_address(page) : NULL; \ + ret; \ +}) + +#define free_thread_info(ti) \ + free_pages((unsigned long)(ti),__THREAD_INFO_ORDER) + #define __thread_flag_byte_ptr(ti) \ ((unsigned char *)(&((ti)->flags))) #define __cur_thread_flag_byte_ptr __thread_flag_byte_ptr(current_thread_info()) diff --git a/trunk/arch/sparc/include/asm/timer_32.h b/trunk/arch/sparc/include/asm/timer_32.h index 72f40a546de3..1a91e11dd104 100644 --- a/trunk/arch/sparc/include/asm/timer_32.h +++ b/trunk/arch/sparc/include/asm/timer_32.h @@ -8,37 +8,14 @@ #ifndef _SPARC_TIMER_H #define _SPARC_TIMER_H -#include -#include - -#include - #include /* For SUN4M_NCPUS */ - -#define SBUS_CLOCK_RATE 2000000 /* 2MHz */ -#define TIMER_VALUE_SHIFT 9 -#define TIMER_VALUE_MASK 0x3fffff -#define TIMER_LIMIT_BIT (1 << 31) /* Bit 31 in Counter-Timer register */ - -/* The counter timer register has the value offset by 9 bits. - * From sun4m manual: - * When a counter reaches the value in the corresponding limit register, - * the Limit bit is set and the counter is set to 500 nS (i.e. 0x00000200). - * - * To compensate for this add one to the value. - */ -static inline unsigned int timer_value(unsigned int value) -{ - return (value + 1) << TIMER_VALUE_SHIFT; -} +#include extern __volatile__ unsigned int *master_l10_counter; -extern irqreturn_t notrace timer_interrupt(int dummy, void *dev_id); - -#ifdef CONFIG_SMP -DECLARE_PER_CPU(struct clock_event_device, sparc32_clockevent); -extern void register_percpu_ce(int cpu); -#endif +/* FIXME: Make do_[gs]ettimeofday btfixup calls */ +struct timespec; +BTFIXUPDEF_CALL(int, bus_do_settimeofday, struct timespec *tv) +#define bus_do_settimeofday(tv) BTFIXUP_CALL(bus_do_settimeofday)(tv) #endif /* !(_SPARC_TIMER_H) */ diff --git a/trunk/arch/sparc/include/asm/timex_32.h b/trunk/arch/sparc/include/asm/timex_32.h index b6ccdb0d6f7d..a254750e4c03 100644 --- a/trunk/arch/sparc/include/asm/timex_32.h +++ b/trunk/arch/sparc/include/asm/timex_32.h @@ -12,4 +12,5 @@ typedef unsigned long cycles_t; #define get_cycles() (0) +extern u32 (*do_arch_gettimeoffset)(void); #endif diff --git a/trunk/arch/sparc/include/asm/tlbflush_32.h b/trunk/arch/sparc/include/asm/tlbflush_32.h index a5c4142130f5..fe0a71abc9bb 100644 --- a/trunk/arch/sparc/include/asm/tlbflush_32.h +++ b/trunk/arch/sparc/include/asm/tlbflush_32.h @@ -1,16 +1,52 @@ #ifndef _SPARC_TLBFLUSH_H #define _SPARC_TLBFLUSH_H -#include - -#define flush_tlb_all() \ - sparc32_cachetlb_ops->tlb_all() -#define flush_tlb_mm(mm) \ - sparc32_cachetlb_ops->tlb_mm(mm) -#define flush_tlb_range(vma, start, end) \ - sparc32_cachetlb_ops->tlb_range(vma, start, end) -#define flush_tlb_page(vma, addr) \ - sparc32_cachetlb_ops->tlb_page(vma, addr) +#include +// #include + +/* + * TLB flushing: + * + * - flush_tlb() flushes the current mm struct TLBs XXX Exists? + * - flush_tlb_all() flushes all processes TLBs + * - flush_tlb_mm(mm) flushes the specified mm context TLB's + * - flush_tlb_page(vma, vmaddr) flushes one page + * - flush_tlb_range(vma, start, end) flushes a range of pages + * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages + */ + +#ifdef CONFIG_SMP + +BTFIXUPDEF_CALL(void, local_flush_tlb_all, void) +BTFIXUPDEF_CALL(void, local_flush_tlb_mm, struct mm_struct *) +BTFIXUPDEF_CALL(void, local_flush_tlb_range, struct vm_area_struct *, unsigned long, unsigned long) +BTFIXUPDEF_CALL(void, local_flush_tlb_page, struct vm_area_struct *, unsigned long) + +#define local_flush_tlb_all() BTFIXUP_CALL(local_flush_tlb_all)() +#define local_flush_tlb_mm(mm) BTFIXUP_CALL(local_flush_tlb_mm)(mm) +#define local_flush_tlb_range(vma,start,end) BTFIXUP_CALL(local_flush_tlb_range)(vma,start,end) +#define local_flush_tlb_page(vma,addr) BTFIXUP_CALL(local_flush_tlb_page)(vma,addr) + +extern void smp_flush_tlb_all(void); +extern void smp_flush_tlb_mm(struct mm_struct *mm); +extern void smp_flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, + unsigned long end); +extern void smp_flush_tlb_page(struct vm_area_struct *mm, unsigned long page); + +#endif /* CONFIG_SMP */ + +BTFIXUPDEF_CALL(void, flush_tlb_all, void) +BTFIXUPDEF_CALL(void, flush_tlb_mm, struct mm_struct *) +BTFIXUPDEF_CALL(void, flush_tlb_range, struct vm_area_struct *, unsigned long, unsigned long) +BTFIXUPDEF_CALL(void, flush_tlb_page, struct vm_area_struct *, unsigned long) + +#define flush_tlb_all() BTFIXUP_CALL(flush_tlb_all)() +#define flush_tlb_mm(mm) BTFIXUP_CALL(flush_tlb_mm)(mm) +#define flush_tlb_range(vma,start,end) BTFIXUP_CALL(flush_tlb_range)(vma,start,end) +#define flush_tlb_page(vma,addr) BTFIXUP_CALL(flush_tlb_page)(vma,addr) + +// #define flush_tlb() flush_tlb_mm(current->active_mm) /* XXX Sure? */ /* * This is a kludge, until I know better. --zaitcev XXX diff --git a/trunk/arch/sparc/include/asm/uaccess_32.h b/trunk/arch/sparc/include/asm/uaccess_32.h index d50c310f5d38..8303ac481034 100644 --- a/trunk/arch/sparc/include/asm/uaccess_32.h +++ b/trunk/arch/sparc/include/asm/uaccess_32.h @@ -12,6 +12,7 @@ #include #include #include +#include #endif #ifndef __ASSEMBLY__ diff --git a/trunk/arch/sparc/include/asm/vac-ops.h b/trunk/arch/sparc/include/asm/vac-ops.h new file mode 100644 index 000000000000..a63e88ef0426 --- /dev/null +++ b/trunk/arch/sparc/include/asm/vac-ops.h @@ -0,0 +1,127 @@ +#ifndef _SPARC_VAC_OPS_H +#define _SPARC_VAC_OPS_H + +/* vac-ops.h: Inline assembly routines to do operations on the Sparc + * VAC (virtual address cache) for the sun4c. + * + * Copyright (C) 1994, David S. Miller (davem@caip.rutgers.edu) + */ + +#include +#include +#include + +/* The SUN4C models have a virtually addressed write-through + * cache. + * + * The cache tags are directly accessible through an ASI and + * each have the form: + * + * ------------------------------------------------------------ + * | MBZ | CONTEXT | WRITE | PRIV | VALID | MBZ | TagID | MBZ | + * ------------------------------------------------------------ + * 31 25 24 22 21 20 19 18 16 15 2 1 0 + * + * MBZ: These bits are either unused and/or reserved and should + * be written as zeroes. + * + * CONTEXT: Records the context to which this cache line belongs. + * + * WRITE: A copy of the writable bit from the mmu pte access bits. + * + * PRIV: A copy of the privileged bit from the pte access bits. + * + * VALID: If set, this line is valid, else invalid. + * + * TagID: Fourteen bits of tag ID. + * + * Every virtual address is seen by the cache like this: + * + * ---------------------------------------- + * | RESV | TagID | LINE | BYTE-in-LINE | + * ---------------------------------------- + * 31 30 29 16 15 4 3 0 + * + * RESV: Unused/reserved. + * + * TagID: Used to match the Tag-ID in that vac tags. + * + * LINE: Which line within the cache + * + * BYTE-in-LINE: Which byte within the cache line. + */ + +/* Sun4c VAC Tags */ +#define S4CVACTAG_CID 0x01c00000 +#define S4CVACTAG_W 0x00200000 +#define S4CVACTAG_P 0x00100000 +#define S4CVACTAG_V 0x00080000 +#define S4CVACTAG_TID 0x0000fffc + +/* Sun4c VAC Virtual Address */ +/* These aren't used, why bother? (Anton) */ +#if 0 +#define S4CVACVA_TID 0x3fff0000 +#define S4CVACVA_LINE 0x0000fff0 +#define S4CVACVA_BIL 0x0000000f +#endif + +/* The indexing of cache lines creates a problem. Because the line + * field of a virtual address extends past the page offset within + * the virtual address it is possible to have what are called + * 'bad aliases' which will create inconsistencies. So we must make + * sure that within a context that if a physical page is mapped + * more than once, that 'extra' line bits are the same. If this is + * not the case, and thus is a 'bad alias' we must turn off the + * cacheable bit in the pte's of all such pages. + */ + +#define S4CVAC_BADBITS 0x0000f000 + +/* The following is true if vaddr1 and vaddr2 would cause + * a 'bad alias'. + */ +#define S4CVAC_BADALIAS(vaddr1, vaddr2) \ + ((((unsigned long) (vaddr1)) ^ ((unsigned long) (vaddr2))) & \ + (S4CVAC_BADBITS)) + +/* The following structure describes the characteristics of a sun4c + * VAC as probed from the prom during boot time. + */ +struct sun4c_vac_props { + unsigned int num_bytes; /* Size of the cache */ + unsigned int do_hwflushes; /* Hardware flushing available? */ + unsigned int linesize; /* Size of each line in bytes */ + unsigned int log2lsize; /* log2(linesize) */ + unsigned int on; /* VAC is enabled */ +}; + +extern struct sun4c_vac_props sun4c_vacinfo; + +/* sun4c_enable_vac() enables the sun4c virtual address cache. */ +static inline void sun4c_enable_vac(void) +{ + __asm__ __volatile__("lduba [%0] %1, %%g1\n\t" + "or %%g1, %2, %%g1\n\t" + "stba %%g1, [%0] %1\n\t" + : /* no outputs */ + : "r" ((unsigned int) AC_SENABLE), + "i" (ASI_CONTROL), "i" (SENABLE_CACHE) + : "g1", "memory"); + sun4c_vacinfo.on = 1; +} + +/* sun4c_disable_vac() disables the virtual address cache. */ +static inline void sun4c_disable_vac(void) +{ + __asm__ __volatile__("lduba [%0] %1, %%g1\n\t" + "andn %%g1, %2, %%g1\n\t" + "stba %%g1, [%0] %1\n\t" + : /* no outputs */ + : "r" ((unsigned int) AC_SENABLE), + "i" (ASI_CONTROL), "i" (SENABLE_CACHE) + : "g1", "memory"); + sun4c_vacinfo.on = 0; +} + +#endif /* !(_SPARC_VAC_OPS_H) */ diff --git a/trunk/arch/sparc/include/asm/vaddrs.h b/trunk/arch/sparc/include/asm/vaddrs.h index da6535d88a72..541e13755cec 100644 --- a/trunk/arch/sparc/include/asm/vaddrs.h +++ b/trunk/arch/sparc/include/asm/vaddrs.h @@ -34,6 +34,22 @@ #define IOBASE_VADDR 0xfe000000 #define IOBASE_END 0xfe600000 +/* + * On the sun4/4c we need a place + * to reliably map locked down kernel data. This includes the + * task_struct and kernel stack pages of each process plus the + * scsi buffers during dvma IO transfers, also the floppy buffers + * during pseudo dma which runs with traps off (no faults allowed). + * Some quick calculations yield: + * NR_TASKS <512> * (3 * PAGE_SIZE) == 0x600000 + * Subtract this from 0xc00000 and you get 0x927C0 of vm left + * over to map SCSI dvma + floppy pseudo-dma buffers. So be + * careful if you change NR_TASKS or else there won't be enough + * room for it all. + */ +#define SUN4C_LOCK_VADDR 0xff000000 +#define SUN4C_LOCK_END 0xffc00000 + #define KADB_DEBUGGER_BEGVM 0xffc00000 /* Where kern debugger is in virt-mem */ #define KADB_DEBUGGER_ENDVM 0xffd00000 #define DEBUG_FIRSTVADDR KADB_DEBUGGER_BEGVM diff --git a/trunk/arch/sparc/include/asm/winmacro.h b/trunk/arch/sparc/include/asm/winmacro.h index 9b7b21764cde..a9be04b0d049 100644 --- a/trunk/arch/sparc/include/asm/winmacro.h +++ b/trunk/arch/sparc/include/asm/winmacro.h @@ -103,24 +103,37 @@ st %scratch, [%cur_reg + TI_W_SAVED]; #ifdef CONFIG_SMP -#define LOAD_CURRENT(dest_reg, idreg) \ -661: rd %tbr, %idreg; \ - srl %idreg, 10, %idreg; \ - and %idreg, 0xc, %idreg; \ - .section .cpuid_patch, "ax"; \ - /* Instruction location. */ \ - .word 661b; \ - /* SUN4D implementation. */ \ - lda [%g0] ASI_M_VIKING_TMP1, %idreg; \ - sll %idreg, 2, %idreg; \ - nop; \ - /* LEON implementation. */ \ - rd %asr17, %idreg; \ - srl %idreg, 0x1c, %idreg; \ - sll %idreg, 0x02, %idreg; \ - .previous; \ - sethi %hi(current_set), %dest_reg; \ - or %dest_reg, %lo(current_set), %dest_reg;\ +/* Results of LOAD_CURRENT() after BTFIXUP for SUN4M, SUN4D & LEON (comments) */ +#define LOAD_CURRENT4M(dest_reg, idreg) \ + rd %tbr, %idreg; \ + sethi %hi(current_set), %dest_reg; \ + srl %idreg, 10, %idreg; \ + or %dest_reg, %lo(current_set), %dest_reg; \ + and %idreg, 0xc, %idreg; \ + ld [%idreg + %dest_reg], %dest_reg; + +#define LOAD_CURRENT4D(dest_reg, idreg) \ + lda [%g0] ASI_M_VIKING_TMP1, %idreg; \ + sethi %hi(C_LABEL(current_set)), %dest_reg; \ + sll %idreg, 2, %idreg; \ + or %dest_reg, %lo(C_LABEL(current_set)), %dest_reg; \ + ld [%idreg + %dest_reg], %dest_reg; + +#define LOAD_CURRENT_LEON(dest_reg, idreg) \ + rd %asr17, %idreg; \ + sethi %hi(current_set), %dest_reg; \ + srl %idreg, 0x1c, %idreg; \ + or %dest_reg, %lo(current_set), %dest_reg; \ + sll %idreg, 0x2, %idreg; \ + ld [%idreg + %dest_reg], %dest_reg; + +/* Blackbox - take care with this... - check smp4m and smp4d before changing this. */ +#define LOAD_CURRENT(dest_reg, idreg) \ + sethi %hi(___b_load_current), %idreg; \ + sethi %hi(current_set), %dest_reg; \ + sethi %hi(boot_cpu_id4), %idreg; \ + or %dest_reg, %lo(current_set), %dest_reg; \ + ldub [%idreg + %lo(boot_cpu_id4)], %idreg; \ ld [%idreg + %dest_reg], %dest_reg; #else #define LOAD_CURRENT(dest_reg, idreg) \ diff --git a/trunk/arch/sparc/kernel/Makefile b/trunk/arch/sparc/kernel/Makefile index 72308f9b0096..cb85458f89d2 100644 --- a/trunk/arch/sparc/kernel/Makefile +++ b/trunk/arch/sparc/kernel/Makefile @@ -6,6 +6,7 @@ asflags-y := -ansi ccflags-y := -Werror extra-y := head_$(BITS).o +extra-y += init_task.o # Undefine sparc when processing vmlinux.lds - it is used # And teach CPP we are doing $(BITS) builds (for this case) @@ -27,7 +28,7 @@ obj-y += traps_$(BITS).o # IRQ obj-y += irq_$(BITS).o -obj-$(CONFIG_SPARC32) += sun4m_irq.o sun4d_irq.o +obj-$(CONFIG_SPARC32) += sun4m_irq.o sun4c_irq.o sun4d_irq.o obj-y += process_$(BITS).o obj-y += signal_$(BITS).o @@ -45,6 +46,7 @@ obj-$(CONFIG_SPARC32) += tadpole.o obj-y += ptrace_$(BITS).o obj-y += unaligned_$(BITS).o obj-y += una_asm_$(BITS).o +obj-$(CONFIG_SPARC32) += muldiv.o obj-y += prom_common.o obj-y += prom_$(BITS).o obj-y += of_device_common.o diff --git a/trunk/arch/sparc/kernel/auxio_32.c b/trunk/arch/sparc/kernel/auxio_32.c index e20cc55fb768..56d0f52c3e62 100644 --- a/trunk/arch/sparc/kernel/auxio_32.c +++ b/trunk/arch/sparc/kernel/auxio_32.c @@ -32,6 +32,7 @@ void __init auxio_probe(void) switch (sparc_cpu_model) { case sparc_leon: case sun4d: + case sun4: return; default: break; @@ -64,8 +65,9 @@ void __init auxio_probe(void) r.start = auxregs[0].phys_addr; r.end = auxregs[0].phys_addr + auxregs[0].reg_size - 1; auxio_register = of_ioremap(&r, 0, auxregs[0].reg_size, "auxio"); - /* Fix the address on sun4m. */ - if ((((unsigned long) auxregs[0].phys_addr) & 3) == 3) + /* Fix the address on sun4m and sun4c. */ + if((((unsigned long) auxregs[0].phys_addr) & 3) == 3 || + sparc_cpu_model == sun4c) auxio_register += (3 - ((unsigned long)auxio_register & 3)); set_auxio(AUXIO_LED, 0); @@ -84,7 +86,12 @@ void set_auxio(unsigned char bits_on, unsigned char bits_off) unsigned char regval; unsigned long flags; spin_lock_irqsave(&auxio_lock, flags); - switch (sparc_cpu_model) { + switch(sparc_cpu_model) { + case sun4c: + regval = sbus_readb(auxio_register); + sbus_writeb(((regval | bits_on) & ~bits_off) | AUXIO_ORMEIN, + auxio_register); + break; case sun4m: if(!auxio_register) break; /* VME chassis sun4m, no auxio. */ diff --git a/trunk/arch/sparc/kernel/central.c b/trunk/arch/sparc/kernel/central.c index 9708851a8b9f..38d48a59879c 100644 --- a/trunk/arch/sparc/kernel/central.c +++ b/trunk/arch/sparc/kernel/central.c @@ -269,4 +269,4 @@ static int __init sunfire_init(void) return 0; } -fs_initcall(sunfire_init); +subsys_initcall(sunfire_init); diff --git a/trunk/arch/sparc/kernel/devices.c b/trunk/arch/sparc/kernel/devices.c index 3d465e87f7e2..6b2f56a6f8af 100644 --- a/trunk/arch/sparc/kernel/devices.c +++ b/trunk/arch/sparc/kernel/devices.c @@ -21,6 +21,7 @@ #include extern void clock_stop_probe(void); /* tadpole.c */ +extern void sun4c_probe_memerr_reg(void); static char *cpu_mid_prop(void) { @@ -138,4 +139,7 @@ void __init device_scan(void) auxio_power_probe(); } clock_stop_probe(); + + if (ARCH_SUN4C) + sun4c_probe_memerr_reg(); } diff --git a/trunk/arch/sparc/kernel/ds.c b/trunk/arch/sparc/kernel/ds.c index f09257c86107..b93c2c9ccb1d 100644 --- a/trunk/arch/sparc/kernel/ds.c +++ b/trunk/arch/sparc/kernel/ds.c @@ -868,7 +868,7 @@ void ldom_power_off(void) static void ds_conn_reset(struct ds_info *dp) { - printk(KERN_ERR "ds-%llu: ds_conn_reset() from %pf\n", + printk(KERN_ERR "ds-%llu: ds_conn_reset() from %p\n", dp->id, __builtin_return_address(0)); } diff --git a/trunk/arch/sparc/kernel/entry.S b/trunk/arch/sparc/kernel/entry.S index 2dbe1806e530..f445e98463e6 100644 --- a/trunk/arch/sparc/kernel/entry.S +++ b/trunk/arch/sparc/kernel/entry.S @@ -7,7 +7,6 @@ * Copyright (C) 1997 Anton Blanchard (anton@progsoc.uts.edu.au) */ -#include #include #include @@ -18,8 +17,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -124,11 +125,22 @@ floppy_tdone: set auxio_register, %l7 ld [%l7], %l7 - ldub [%l7], %l5 + set sparc_cpu_model, %l5 + ld [%l5], %l5 + subcc %l5, 1, %g0 /* enum { sun4c = 1 }; */ + be 1f + ldub [%l7], %l5 or %l5, 0xc2, %l5 stb %l5, [%l7] andn %l5, 0x02, %l5 + b 2f + nop + +1: + or %l5, 0xf4, %l5 + stb %l5, [%l7] + andn %l5, 0x04, %l5 2: /* Kill some time so the bits set */ @@ -254,11 +266,6 @@ smp4m_ticker: WRITE_PAUSE RESTORE_ALL -#define GET_PROCESSOR4M_ID(reg) \ - rd %tbr, %reg; \ - srl %reg, 12, %reg; \ - and %reg, 3, %reg; - /* Here is where we check for possible SMP IPI passed to us * on some level other than 15 which is the NMI and only used * for cross calls. That has a separate entry point below. @@ -321,7 +328,7 @@ linux_trap_ipi15_sun4m: ld [%o5 + %o0], %o5 ld [%o5 + 0x00], %o3 ! sun4m_irq_percpu[cpu]->pending andcc %o3, %o2, %g0 - be sun4m_nmi_error ! Must be an NMI async memory error + be 1f ! Must be an NMI async memory error st %o2, [%o5 + 0x04] ! sun4m_irq_percpu[cpu]->clear=0x80000000 WRITE_PAUSE ld [%o5 + 0x00], %g0 ! sun4m_irq_percpu[cpu]->pending @@ -335,6 +342,27 @@ linux_trap_ipi15_sun4m: nop b ret_trap_lockless_ipi clr %l6 +1: + /* NMI async memory error handling. */ + sethi %hi(0x80000000), %l4 + sethi %hi(sun4m_irq_global), %o5 + ld [%o5 + %lo(sun4m_irq_global)], %l5 + st %l4, [%l5 + 0x0c] ! sun4m_irq_global->mask_set=0x80000000 + WRITE_PAUSE + ld [%l5 + 0x00], %g0 ! sun4m_irq_global->pending + WRITE_PAUSE + or %l0, PSR_PIL, %l4 + wr %l4, 0x0, %psr + WRITE_PAUSE + wr %l4, PSR_ET, %psr + WRITE_PAUSE + call sun4m_nmi + nop + st %l4, [%l5 + 0x08] ! sun4m_irq_global->mask_clear=0x80000000 + WRITE_PAUSE + ld [%l5 + 0x00], %g0 ! sun4m_irq_global->pending + WRITE_PAUSE + RESTORE_ALL .globl smp4d_ticker /* SMP per-cpu ticker interrupts are handled specially. */ @@ -732,37 +760,326 @@ setcc_trap_handler: jmp %l2 ! advance over trap instruction rett %l2 + 0x4 ! like this... -sun4m_nmi_error: - /* NMI async memory error handling. */ - sethi %hi(0x80000000), %l4 - sethi %hi(sun4m_irq_global), %o5 - ld [%o5 + %lo(sun4m_irq_global)], %l5 - st %l4, [%l5 + 0x0c] ! sun4m_irq_global->mask_set=0x80000000 - WRITE_PAUSE - ld [%l5 + 0x00], %g0 ! sun4m_irq_global->pending - WRITE_PAUSE - or %l0, PSR_PIL, %l4 - wr %l4, 0x0, %psr - WRITE_PAUSE - wr %l4, PSR_ET, %psr - WRITE_PAUSE - call sun4m_nmi - nop - st %l4, [%l5 + 0x08] ! sun4m_irq_global->mask_clear=0x80000000 - WRITE_PAUSE - ld [%l5 + 0x00], %g0 ! sun4m_irq_global->pending + .align 4 + .globl linux_trap_nmi_sun4c +linux_trap_nmi_sun4c: + SAVE_ALL + + /* Ugh, we need to clear the IRQ line. This is now + * a very sun4c specific trap handler... + */ + sethi %hi(interrupt_enable), %l5 + ld [%l5 + %lo(interrupt_enable)], %l5 + ldub [%l5], %l6 + andn %l6, INTS_ENAB, %l6 + stb %l6, [%l5] + + /* Now it is safe to re-enable traps without recursion. */ + or %l0, PSR_PIL, %l0 + wr %l0, PSR_ET, %psr WRITE_PAUSE + + /* Now call the c-code with the pt_regs frame ptr and the + * memory error registers as arguments. The ordering chosen + * here is due to unlatching semantics. + */ + sethi %hi(AC_SYNC_ERR), %o0 + add %o0, 0x4, %o0 + lda [%o0] ASI_CONTROL, %o2 ! sync vaddr + sub %o0, 0x4, %o0 + lda [%o0] ASI_CONTROL, %o1 ! sync error + add %o0, 0xc, %o0 + lda [%o0] ASI_CONTROL, %o4 ! async vaddr + sub %o0, 0x4, %o0 + lda [%o0] ASI_CONTROL, %o3 ! async error + call sparc_lvl15_nmi + add %sp, STACKFRAME_SZ, %o0 + RESTORE_ALL -#ifndef CONFIG_SMP .align 4 - .globl linux_trap_ipi15_sun4m -linux_trap_ipi15_sun4m: - SAVE_ALL + .globl invalid_segment_patch1_ff + .globl invalid_segment_patch2_ff +invalid_segment_patch1_ff: cmp %l4, 0xff +invalid_segment_patch2_ff: mov 0xff, %l3 + + .align 4 + .globl invalid_segment_patch1_1ff + .globl invalid_segment_patch2_1ff +invalid_segment_patch1_1ff: cmp %l4, 0x1ff +invalid_segment_patch2_1ff: mov 0x1ff, %l3 + + .align 4 + .globl num_context_patch1_16, num_context_patch2_16 +num_context_patch1_16: mov 0x10, %l7 +num_context_patch2_16: mov 0x10, %l7 + + .align 4 + .globl vac_linesize_patch_32 +vac_linesize_patch_32: subcc %l7, 32, %l7 + + .align 4 + .globl vac_hwflush_patch1_on, vac_hwflush_patch2_on + +/* + * Ugly, but we can't use hardware flushing on the sun4 and we'd require + * two instructions (Anton) + */ +vac_hwflush_patch1_on: addcc %l7, -PAGE_SIZE, %l7 + +vac_hwflush_patch2_on: sta %g0, [%l3 + %l7] ASI_HWFLUSHSEG + + .globl invalid_segment_patch1, invalid_segment_patch2 + .globl num_context_patch1 + .globl vac_linesize_patch, vac_hwflush_patch1 + .globl vac_hwflush_patch2 + + .align 4 + .globl sun4c_fault + +! %l0 = %psr +! %l1 = %pc +! %l2 = %npc +! %l3 = %wim +! %l7 = 1 for textfault +! We want error in %l5, vaddr in %l6 +sun4c_fault: + sethi %hi(AC_SYNC_ERR), %l4 + add %l4, 0x4, %l6 ! AC_SYNC_VA in %l6 + lda [%l6] ASI_CONTROL, %l5 ! Address + lda [%l4] ASI_CONTROL, %l6 ! Error, retained for a bit + + andn %l5, 0xfff, %l5 ! Encode all info into l7 + srl %l6, 14, %l4 + + and %l4, 2, %l4 + or %l5, %l4, %l4 + + or %l4, %l7, %l7 ! l7 = [addr,write,txtfault] + + andcc %l0, PSR_PS, %g0 + be sun4c_fault_fromuser + andcc %l7, 1, %g0 ! Text fault? - ba sun4m_nmi_error + be 1f + sethi %hi(KERNBASE), %l4 + + mov %l1, %l5 ! PC + +1: + cmp %l5, %l4 + blu sun4c_fault_fromuser + sethi %hi(~((1 << SUN4C_REAL_PGDIR_SHIFT) - 1)), %l4 + + /* If the kernel references a bum kernel pointer, or a pte which + * points to a non existent page in ram, we will run this code + * _forever_ and lock up the machine!!!!! So we must check for + * this condition, the AC_SYNC_ERR bits are what we must examine. + * Also a parity error would make this happen as well. So we just + * check that we are in fact servicing a tlb miss and not some + * other type of fault for the kernel. + */ + andcc %l6, 0x80, %g0 + be sun4c_fault_fromuser + and %l5, %l4, %l5 + + /* Test for NULL pte_t * in vmalloc area. */ + sethi %hi(VMALLOC_START), %l4 + cmp %l5, %l4 + blu,a invalid_segment_patch1 + lduXa [%l5] ASI_SEGMAP, %l4 + + sethi %hi(swapper_pg_dir), %l4 + srl %l5, SUN4C_PGDIR_SHIFT, %l6 + or %l4, %lo(swapper_pg_dir), %l4 + sll %l6, 2, %l6 + ld [%l4 + %l6], %l4 + andcc %l4, PAGE_MASK, %g0 + be sun4c_fault_fromuser + lduXa [%l5] ASI_SEGMAP, %l4 + +invalid_segment_patch1: + cmp %l4, 0x7f + bne 1f + sethi %hi(sun4c_kfree_ring), %l4 + or %l4, %lo(sun4c_kfree_ring), %l4 + ld [%l4 + 0x18], %l3 + deccc %l3 ! do we have a free entry? + bcs,a 2f ! no, unmap one. + sethi %hi(sun4c_kernel_ring), %l4 + + st %l3, [%l4 + 0x18] ! sun4c_kfree_ring.num_entries-- + + ld [%l4 + 0x00], %l6 ! entry = sun4c_kfree_ring.ringhd.next + st %l5, [%l6 + 0x08] ! entry->vaddr = address + + ld [%l6 + 0x00], %l3 ! next = entry->next + ld [%l6 + 0x04], %l7 ! entry->prev + + st %l7, [%l3 + 0x04] ! next->prev = entry->prev + st %l3, [%l7 + 0x00] ! entry->prev->next = next + + sethi %hi(sun4c_kernel_ring), %l4 + or %l4, %lo(sun4c_kernel_ring), %l4 + ! head = &sun4c_kernel_ring.ringhd + + ld [%l4 + 0x00], %l7 ! head->next + + st %l4, [%l6 + 0x04] ! entry->prev = head + st %l7, [%l6 + 0x00] ! entry->next = head->next + st %l6, [%l7 + 0x04] ! head->next->prev = entry + + st %l6, [%l4 + 0x00] ! head->next = entry + + ld [%l4 + 0x18], %l3 + inc %l3 ! sun4c_kernel_ring.num_entries++ + st %l3, [%l4 + 0x18] + b 4f + ld [%l6 + 0x08], %l5 + +2: + or %l4, %lo(sun4c_kernel_ring), %l4 + ! head = &sun4c_kernel_ring.ringhd + + ld [%l4 + 0x04], %l6 ! entry = head->prev + + ld [%l6 + 0x08], %l3 ! tmp = entry->vaddr + + ! Flush segment from the cache. + sethi %hi((64 * 1024)), %l7 +9: +vac_hwflush_patch1: +vac_linesize_patch: + subcc %l7, 16, %l7 + bne 9b +vac_hwflush_patch2: + sta %g0, [%l3 + %l7] ASI_FLUSHSEG + + st %l5, [%l6 + 0x08] ! entry->vaddr = address + + ld [%l6 + 0x00], %l5 ! next = entry->next + ld [%l6 + 0x04], %l7 ! entry->prev + + st %l7, [%l5 + 0x04] ! next->prev = entry->prev + st %l5, [%l7 + 0x00] ! entry->prev->next = next + st %l4, [%l6 + 0x04] ! entry->prev = head + + ld [%l4 + 0x00], %l7 ! head->next + + st %l7, [%l6 + 0x00] ! entry->next = head->next + st %l6, [%l7 + 0x04] ! head->next->prev = entry + st %l6, [%l4 + 0x00] ! head->next = entry + + mov %l3, %l5 ! address = tmp + +4: +num_context_patch1: + mov 0x08, %l7 + + ld [%l6 + 0x08], %l4 + ldub [%l6 + 0x0c], %l3 + or %l4, %l3, %l4 ! encode new vaddr/pseg into l4 + + sethi %hi(AC_CONTEXT), %l3 + lduba [%l3] ASI_CONTROL, %l6 + + /* Invalidate old mapping, instantiate new mapping, + * for each context. Registers l6/l7 are live across + * this loop. + */ +3: deccc %l7 + sethi %hi(AC_CONTEXT), %l3 + stba %l7, [%l3] ASI_CONTROL +invalid_segment_patch2: + mov 0x7f, %l3 + stXa %l3, [%l5] ASI_SEGMAP + andn %l4, 0x1ff, %l3 + bne 3b + stXa %l4, [%l3] ASI_SEGMAP + + sethi %hi(AC_CONTEXT), %l3 + stba %l6, [%l3] ASI_CONTROL + + andn %l4, 0x1ff, %l5 + +1: + sethi %hi(VMALLOC_START), %l4 + cmp %l5, %l4 + + bgeu 1f + mov 1 << (SUN4C_REAL_PGDIR_SHIFT - PAGE_SHIFT), %l7 + + sethi %hi(KERNBASE), %l6 + + sub %l5, %l6, %l4 + srl %l4, PAGE_SHIFT, %l4 + sethi %hi((SUN4C_PAGE_KERNEL & 0xf4000000)), %l3 + or %l3, %l4, %l3 + + sethi %hi(PAGE_SIZE), %l4 + +2: + sta %l3, [%l5] ASI_PTE + deccc %l7 + inc %l3 + bne 2b + add %l5, %l4, %l5 + + b 7f + sethi %hi(sun4c_kernel_faults), %l4 + +1: + srl %l5, SUN4C_PGDIR_SHIFT, %l3 + sethi %hi(swapper_pg_dir), %l4 + or %l4, %lo(swapper_pg_dir), %l4 + sll %l3, 2, %l3 + ld [%l4 + %l3], %l4 + and %l4, PAGE_MASK, %l4 + + srl %l5, (PAGE_SHIFT - 2), %l6 + and %l6, ((SUN4C_PTRS_PER_PTE - 1) << 2), %l6 + add %l6, %l4, %l6 + + sethi %hi(PAGE_SIZE), %l4 + +2: + ld [%l6], %l3 + deccc %l7 + sta %l3, [%l5] ASI_PTE + add %l6, 0x4, %l6 + bne 2b + add %l5, %l4, %l5 + + sethi %hi(sun4c_kernel_faults), %l4 +7: + ld [%l4 + %lo(sun4c_kernel_faults)], %l3 + inc %l3 + st %l3, [%l4 + %lo(sun4c_kernel_faults)] + + /* Restore condition codes */ + wr %l0, 0x0, %psr + WRITE_PAUSE + jmp %l1 + rett %l2 + +sun4c_fault_fromuser: + SAVE_ALL nop -#endif /* CONFIG_SMP */ + + mov %l7, %o1 ! Decode the info from %l7 + mov %l7, %o2 + and %o1, 1, %o1 ! arg2 = text_faultp + mov %l7, %o3 + and %o2, 2, %o2 ! arg3 = writep + andn %o3, 0xfff, %o3 ! arg4 = faulting address + + wr %l0, PSR_ET, %psr + WRITE_PAUSE + + call do_sun4c_fault + add %sp, STACKFRAME_SZ, %o0 ! arg1 = pt_regs ptr + + RESTORE_ALL .align 4 .globl srmmu_fault @@ -1166,13 +1483,11 @@ fpload: .globl __ndelay __ndelay: save %sp, -STACKFRAME_SZ, %sp - mov %i0, %o0 ! round multiplier up so large ns ok - mov 0x1ae, %o1 ! 2**32 / (1 000 000 000 / HZ) - umul %o0, %o1, %o0 - rd %y, %o1 - mov %i1, %o1 ! udelay_val - umul %o0, %o1, %o0 - rd %y, %o1 + mov %i0, %o0 + call .umul ! round multiplier up so large ns ok + mov 0x1ae, %o1 ! 2**32 / (1 000 000 000 / HZ) + call .umul + mov %i1, %o1 ! udelay_val ba delay_continue mov %o1, %o0 ! >>32 later for better resolution @@ -1181,21 +1496,18 @@ __udelay: save %sp, -STACKFRAME_SZ, %sp mov %i0, %o0 sethi %hi(0x10c7), %o1 ! round multiplier up so large us ok - or %o1, %lo(0x10c7), %o1 ! 2**32 / 1 000 000 - umul %o0, %o1, %o0 - rd %y, %o1 - mov %i1, %o1 ! udelay_val - umul %o0, %o1, %o0 - rd %y, %o1 + call .umul + or %o1, %lo(0x10c7), %o1 ! 2**32 / 1 000 000 + call .umul + mov %i1, %o1 ! udelay_val sethi %hi(0x028f4b62), %l0 ! Add in rounding constant * 2**32, or %g0, %lo(0x028f4b62), %l0 addcc %o0, %l0, %o0 ! 2**32 * 0.009 999 bcs,a 3f add %o1, 0x01, %o1 3: - mov HZ, %o0 ! >>32 earlier for wider range - umul %o0, %o1, %o0 - rd %y, %o1 + call .umul + mov HZ, %o0 ! >>32 earlier for wider range delay_continue: cmp %o0, 0x0 @@ -1358,26 +1670,4 @@ flushw_all: ret restore -#ifdef CONFIG_SMP -ENTRY(hard_smp_processor_id) -661: rd %tbr, %g1 - srl %g1, 12, %o0 - and %o0, 3, %o0 - .section .cpuid_patch, "ax" - /* Instruction location. */ - .word 661b - /* SUN4D implementation. */ - lda [%g0] ASI_M_VIKING_TMP1, %o0 - nop - nop - /* LEON implementation. */ - rd %asr17, %o0 - srl %o0, 0x1c, %o0 - nop - .previous - retl - nop -ENDPROC(hard_smp_processor_id) -#endif - /* End of entry.S */ diff --git a/trunk/arch/sparc/kernel/etrap_32.S b/trunk/arch/sparc/kernel/etrap_32.S index 84b5f0d2afde..e806fcdc46db 100644 --- a/trunk/arch/sparc/kernel/etrap_32.S +++ b/trunk/arch/sparc/kernel/etrap_32.S @@ -216,7 +216,9 @@ tsetup_patch6: /* Call MMU-architecture dependent stack checking * routine. */ - b tsetup_srmmu_stackchk + .globl tsetup_mmu_patchme +tsetup_mmu_patchme: + b tsetup_sun4c_stackchk andcc %sp, 0x7, %g0 /* Architecture specific stack checking routines. When either @@ -226,6 +228,52 @@ tsetup_patch6: */ #define glob_tmp g1 +tsetup_sun4c_stackchk: + /* Done by caller: andcc %sp, 0x7, %g0 */ + bne trap_setup_user_stack_is_bolixed + sra %sp, 29, %glob_tmp + + add %glob_tmp, 0x1, %glob_tmp + andncc %glob_tmp, 0x1, %g0 + bne trap_setup_user_stack_is_bolixed + and %sp, 0xfff, %glob_tmp ! delay slot + + /* See if our dump area will be on more than one + * page. + */ + add %glob_tmp, 0x38, %glob_tmp + andncc %glob_tmp, 0xff8, %g0 + be tsetup_sun4c_onepage ! only one page to check + lda [%sp] ASI_PTE, %glob_tmp ! have to check first page anyways + +tsetup_sun4c_twopages: + /* Is first page ok permission wise? */ + srl %glob_tmp, 29, %glob_tmp + cmp %glob_tmp, 0x6 + bne trap_setup_user_stack_is_bolixed + add %sp, 0x38, %glob_tmp /* Is second page in vma hole? */ + + sra %glob_tmp, 29, %glob_tmp + add %glob_tmp, 0x1, %glob_tmp + andncc %glob_tmp, 0x1, %g0 + bne trap_setup_user_stack_is_bolixed + add %sp, 0x38, %glob_tmp + + lda [%glob_tmp] ASI_PTE, %glob_tmp + +tsetup_sun4c_onepage: + srl %glob_tmp, 29, %glob_tmp + cmp %glob_tmp, 0x6 ! can user write to it? + bne trap_setup_user_stack_is_bolixed ! failure + nop + + STORE_WINDOW(sp) + + restore %g0, %g0, %g0 + + jmpl %t_retpc + 0x8, %g0 + mov %t_kstack, %sp + .globl tsetup_srmmu_stackchk tsetup_srmmu_stackchk: /* Check results of callers andcc %sp, 0x7, %g0 */ diff --git a/trunk/arch/sparc/kernel/head_32.S b/trunk/arch/sparc/kernel/head_32.S index a0f5c20e4b9c..587785759838 100644 --- a/trunk/arch/sparc/kernel/head_32.S +++ b/trunk/arch/sparc/kernel/head_32.S @@ -26,9 +26,11 @@ #include /* SRMMU_PGDIR_SHIFT */ .data -/* The following are used with the prom_vector node-ops to figure out - * the cpu-type +/* + * The following are used with the prom_vector node-ops to figure out + * the cpu-type */ + .align 4 cputyp: .word 1 @@ -36,35 +38,384 @@ cputyp: .align 4 .globl cputypval cputypval: - .asciz "sun4m" + .asciz "sun4c" .ascii " " -/* Tested on SS-5, SS-10 */ +cputypvalend: +cputypvallen = cputypvar - cputypval + .align 4 +/* + * Sun people can't spell worth damn. "compatability" indeed. + * At least we *know* we can't spell, and use a spell-checker. + */ + +/* Uh, actually Linus it is I who cannot spell. Too much murky + * Sparc assembly will do this to ya. + */ cputypvar: + .asciz "compatability" + +/* Tested on SS-5, SS-10. Probably someone at Sun applied a spell-checker. */ + .align 4 +cputypvar_sun4m: .asciz "compatible" .align 4 -sun4c_notsup: - .asciz "Sparc-Linux sun4/sun4c support does no longer exist.\n\n" +sun4_notsup: + .asciz "Sparc-Linux sun4 support does no longer exist.\n\n" .align 4 sun4e_notsup: .asciz "Sparc-Linux sun4e support does not exist\n\n" .align 4 -/* The trap-table - located in the __HEAD section */ -#include "ttable_32.S" + /* The Sparc trap table, bootloader gives us control at _start. */ + __HEAD + .globl _stext, _start, __stext + .globl trapbase +_start: /* danger danger */ +__stext: +_stext: +trapbase: +#ifdef CONFIG_SMP +trapbase_cpu0: +#endif +/* We get control passed to us here at t_zero. */ +t_zero: b gokernel; nop; nop; nop; +t_tflt: SPARC_TFAULT /* Inst. Access Exception */ +t_bins: TRAP_ENTRY(0x2, bad_instruction) /* Illegal Instruction */ +t_pins: TRAP_ENTRY(0x3, priv_instruction) /* Privileged Instruction */ +t_fpd: TRAP_ENTRY(0x4, fpd_trap_handler) /* Floating Point Disabled */ +t_wovf: WINDOW_SPILL /* Window Overflow */ +t_wunf: WINDOW_FILL /* Window Underflow */ +t_mna: TRAP_ENTRY(0x7, mna_handler) /* Memory Address Not Aligned */ +t_fpe: TRAP_ENTRY(0x8, fpe_trap_handler) /* Floating Point Exception */ +t_dflt: SPARC_DFAULT /* Data Miss Exception */ +t_tio: TRAP_ENTRY(0xa, do_tag_overflow) /* Tagged Instruction Ovrflw */ +t_wpt: TRAP_ENTRY(0xb, do_watchpoint) /* Watchpoint Detected */ +t_badc: BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10) +t_irq1: TRAP_ENTRY_INTERRUPT(1) /* IRQ Software/SBUS Level 1 */ +t_irq2: TRAP_ENTRY_INTERRUPT(2) /* IRQ SBUS Level 2 */ +t_irq3: TRAP_ENTRY_INTERRUPT(3) /* IRQ SCSI/DMA/SBUS Level 3 */ +t_irq4: TRAP_ENTRY_INTERRUPT(4) /* IRQ Software Level 4 */ +t_irq5: TRAP_ENTRY_INTERRUPT(5) /* IRQ SBUS/Ethernet Level 5 */ +t_irq6: TRAP_ENTRY_INTERRUPT(6) /* IRQ Software Level 6 */ +t_irq7: TRAP_ENTRY_INTERRUPT(7) /* IRQ Video/SBUS Level 5 */ +t_irq8: TRAP_ENTRY_INTERRUPT(8) /* IRQ SBUS Level 6 */ +t_irq9: TRAP_ENTRY_INTERRUPT(9) /* IRQ SBUS Level 7 */ +t_irq10:TRAP_ENTRY_INTERRUPT(10) /* IRQ Timer #1 (one we use) */ +t_irq11:TRAP_ENTRY_INTERRUPT(11) /* IRQ Floppy Intr. */ +t_irq12:TRAP_ENTRY_INTERRUPT(12) /* IRQ Zilog serial chip */ +t_irq13:TRAP_ENTRY_INTERRUPT(13) /* IRQ Audio Intr. */ +t_irq14:TRAP_ENTRY_INTERRUPT(14) /* IRQ Timer #2 */ + .globl t_nmi +#ifndef CONFIG_SMP +t_nmi: NMI_TRAP /* Level 15 (NMI) */ +#else +t_nmi: TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m) +#endif +t_racc: TRAP_ENTRY(0x20, do_reg_access) /* General Register Access Error */ +t_iacce:BAD_TRAP(0x21) /* Instr Access Error */ +t_bad22:BAD_TRAP(0x22) BAD_TRAP(0x23) +t_cpdis:TRAP_ENTRY(0x24, do_cp_disabled) /* Co-Processor Disabled */ +t_uflsh:SKIP_TRAP(0x25, unimp_flush) /* Unimplemented FLUSH inst. */ +t_bad26:BAD_TRAP(0x26) BAD_TRAP(0x27) +t_cpexc:TRAP_ENTRY(0x28, do_cp_exception) /* Co-Processor Exception */ +t_dacce:SPARC_DFAULT /* Data Access Error */ +t_hwdz: TRAP_ENTRY(0x2a, do_hw_divzero) /* Division by zero, you lose... */ +t_dserr:BAD_TRAP(0x2b) /* Data Store Error */ +t_daccm:BAD_TRAP(0x2c) /* Data Access MMU-Miss */ +t_bad2d:BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31) +t_bad32:BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36) +t_bad37:BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b) +t_iaccm:BAD_TRAP(0x3c) /* Instr Access MMU-Miss */ +t_bad3d:BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40) BAD_TRAP(0x41) +t_bad42:BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45) BAD_TRAP(0x46) +t_bad47:BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) BAD_TRAP(0x4b) +t_bad4c:BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f) BAD_TRAP(0x50) +t_bad51:BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55) +t_bad56:BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a) +t_bad5b:BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f) +t_bad60:BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64) +t_bad65:BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69) +t_bad6a:BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e) +t_bad6f:BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73) +t_bad74:BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) +t_bad79:BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) +t_bad7e:BAD_TRAP(0x7e) BAD_TRAP(0x7f) +t_bad80:BAD_TRAP(0x80) /* SunOS System Call */ +t_sbkpt:BREAKPOINT_TRAP /* Software Breakpoint/KGDB */ +t_divz: TRAP_ENTRY(0x82, do_hw_divzero) /* Divide by zero trap */ +t_flwin:TRAP_ENTRY(0x83, do_flush_windows) /* Flush Windows Trap */ +t_clwin:BAD_TRAP(0x84) /* Clean Windows Trap */ +t_rchk: BAD_TRAP(0x85) /* Range Check */ +t_funal:BAD_TRAP(0x86) /* Fix Unaligned Access Trap */ +t_iovf: BAD_TRAP(0x87) /* Integer Overflow Trap */ +t_bad88:BAD_TRAP(0x88) /* Slowaris System Call */ +t_bad89:BAD_TRAP(0x89) /* Net-B.S. System Call */ +t_bad8a:BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) BAD_TRAP(0x8d) BAD_TRAP(0x8e) +t_bad8f:BAD_TRAP(0x8f) +t_linux:LINUX_SYSCALL_TRAP /* Linux System Call */ +t_bad91:BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) BAD_TRAP(0x95) +t_bad96:BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) BAD_TRAP(0x9a) +t_bad9b:BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) BAD_TRAP(0x9f) +t_getcc:GETCC_TRAP /* Get Condition Codes */ +t_setcc:SETCC_TRAP /* Set Condition Codes */ +t_getpsr:GETPSR_TRAP /* Get PSR Register */ +t_bada3:BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) +t_bada7:BAD_TRAP(0xa7) +t_bada8:BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) +t_badac:BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) +t_badb1:BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) +t_badb6:BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) +t_badbb:BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf) +t_badc0:BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4) +t_badc5:BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9) +t_badca:BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce) +t_badcf:BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3) +t_badd4:BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8) +t_badd9:BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd) +t_badde:BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2) +t_bade3:BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7) +t_bade8:BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec) +t_baded:BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) +t_badf2:BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) +t_badf7:BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) +t_badfc:BAD_TRAP(0xfc) +t_kgdb: KGDB_TRAP(0xfd) +dbtrap: BAD_TRAP(0xfe) /* Debugger/PROM breakpoint #1 */ +dbtrap2:BAD_TRAP(0xff) /* Debugger/PROM breakpoint #2 */ + + .globl end_traptable +end_traptable: + +#ifdef CONFIG_SMP + /* Trap tables for the other cpus. */ + .globl trapbase_cpu1, trapbase_cpu2, trapbase_cpu3 +trapbase_cpu1: + BAD_TRAP(0x0) SRMMU_TFAULT TRAP_ENTRY(0x2, bad_instruction) + TRAP_ENTRY(0x3, priv_instruction) TRAP_ENTRY(0x4, fpd_trap_handler) + WINDOW_SPILL WINDOW_FILL TRAP_ENTRY(0x7, mna_handler) + TRAP_ENTRY(0x8, fpe_trap_handler) SRMMU_DFAULT + TRAP_ENTRY(0xa, do_tag_overflow) TRAP_ENTRY(0xb, do_watchpoint) + BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10) + TRAP_ENTRY_INTERRUPT(1) TRAP_ENTRY_INTERRUPT(2) + TRAP_ENTRY_INTERRUPT(3) TRAP_ENTRY_INTERRUPT(4) + TRAP_ENTRY_INTERRUPT(5) TRAP_ENTRY_INTERRUPT(6) + TRAP_ENTRY_INTERRUPT(7) TRAP_ENTRY_INTERRUPT(8) + TRAP_ENTRY_INTERRUPT(9) TRAP_ENTRY_INTERRUPT(10) + TRAP_ENTRY_INTERRUPT(11) TRAP_ENTRY_INTERRUPT(12) + TRAP_ENTRY_INTERRUPT(13) TRAP_ENTRY_INTERRUPT(14) + TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m) + TRAP_ENTRY(0x20, do_reg_access) BAD_TRAP(0x21) BAD_TRAP(0x22) + BAD_TRAP(0x23) TRAP_ENTRY(0x24, do_cp_disabled) SKIP_TRAP(0x25, unimp_flush) + BAD_TRAP(0x26) BAD_TRAP(0x27) TRAP_ENTRY(0x28, do_cp_exception) + SRMMU_DFAULT TRAP_ENTRY(0x2a, do_hw_divzero) BAD_TRAP(0x2b) BAD_TRAP(0x2c) + BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31) + BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36) + BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b) + BAD_TRAP(0x3c) BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40) + BAD_TRAP(0x41) BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45) + BAD_TRAP(0x46) BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) + BAD_TRAP(0x4b) BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f) + BAD_TRAP(0x50) + BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55) + BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a) + BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f) + BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64) + BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69) + BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e) + BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73) + BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) + BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) + BAD_TRAP(0x7e) BAD_TRAP(0x7f) + BAD_TRAP(0x80) + BREAKPOINT_TRAP + TRAP_ENTRY(0x82, do_hw_divzero) + TRAP_ENTRY(0x83, do_flush_windows) BAD_TRAP(0x84) BAD_TRAP(0x85) + BAD_TRAP(0x86) BAD_TRAP(0x87) BAD_TRAP(0x88) + BAD_TRAP(0x89) BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) + BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f) + LINUX_SYSCALL_TRAP BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) + BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) + BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) + BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP GETPSR_TRAP + BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) + BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) + BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) + BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) + BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) + BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf) + BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4) + BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9) + BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce) + BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3) + BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8) + BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd) + BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2) + BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7) + BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec) + BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) + BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) + BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) + BAD_TRAP(0xfc) KGDB_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff) + +trapbase_cpu2: + BAD_TRAP(0x0) SRMMU_TFAULT TRAP_ENTRY(0x2, bad_instruction) + TRAP_ENTRY(0x3, priv_instruction) TRAP_ENTRY(0x4, fpd_trap_handler) + WINDOW_SPILL WINDOW_FILL TRAP_ENTRY(0x7, mna_handler) + TRAP_ENTRY(0x8, fpe_trap_handler) SRMMU_DFAULT + TRAP_ENTRY(0xa, do_tag_overflow) TRAP_ENTRY(0xb, do_watchpoint) + BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10) + TRAP_ENTRY_INTERRUPT(1) TRAP_ENTRY_INTERRUPT(2) + TRAP_ENTRY_INTERRUPT(3) TRAP_ENTRY_INTERRUPT(4) + TRAP_ENTRY_INTERRUPT(5) TRAP_ENTRY_INTERRUPT(6) + TRAP_ENTRY_INTERRUPT(7) TRAP_ENTRY_INTERRUPT(8) + TRAP_ENTRY_INTERRUPT(9) TRAP_ENTRY_INTERRUPT(10) + TRAP_ENTRY_INTERRUPT(11) TRAP_ENTRY_INTERRUPT(12) + TRAP_ENTRY_INTERRUPT(13) TRAP_ENTRY_INTERRUPT(14) + TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m) + TRAP_ENTRY(0x20, do_reg_access) BAD_TRAP(0x21) BAD_TRAP(0x22) + BAD_TRAP(0x23) TRAP_ENTRY(0x24, do_cp_disabled) SKIP_TRAP(0x25, unimp_flush) + BAD_TRAP(0x26) BAD_TRAP(0x27) TRAP_ENTRY(0x28, do_cp_exception) + SRMMU_DFAULT TRAP_ENTRY(0x2a, do_hw_divzero) BAD_TRAP(0x2b) BAD_TRAP(0x2c) + BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31) + BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36) + BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b) + BAD_TRAP(0x3c) BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40) + BAD_TRAP(0x41) BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45) + BAD_TRAP(0x46) BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) + BAD_TRAP(0x4b) BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f) + BAD_TRAP(0x50) + BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55) + BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a) + BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f) + BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64) + BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69) + BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e) + BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73) + BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) + BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) + BAD_TRAP(0x7e) BAD_TRAP(0x7f) + BAD_TRAP(0x80) + BREAKPOINT_TRAP + TRAP_ENTRY(0x82, do_hw_divzero) + TRAP_ENTRY(0x83, do_flush_windows) BAD_TRAP(0x84) BAD_TRAP(0x85) + BAD_TRAP(0x86) BAD_TRAP(0x87) BAD_TRAP(0x88) + BAD_TRAP(0x89) BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) + BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f) + LINUX_SYSCALL_TRAP BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) + BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) + BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) + BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP GETPSR_TRAP + BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) + BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) + BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) + BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) + BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) + BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf) + BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4) + BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9) + BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce) + BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3) + BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8) + BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd) + BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2) + BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7) + BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec) + BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) + BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) + BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) + BAD_TRAP(0xfc) KGDB_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff) + +trapbase_cpu3: + BAD_TRAP(0x0) SRMMU_TFAULT TRAP_ENTRY(0x2, bad_instruction) + TRAP_ENTRY(0x3, priv_instruction) TRAP_ENTRY(0x4, fpd_trap_handler) + WINDOW_SPILL WINDOW_FILL TRAP_ENTRY(0x7, mna_handler) + TRAP_ENTRY(0x8, fpe_trap_handler) SRMMU_DFAULT + TRAP_ENTRY(0xa, do_tag_overflow) TRAP_ENTRY(0xb, do_watchpoint) + BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10) + TRAP_ENTRY_INTERRUPT(1) TRAP_ENTRY_INTERRUPT(2) + TRAP_ENTRY_INTERRUPT(3) TRAP_ENTRY_INTERRUPT(4) + TRAP_ENTRY_INTERRUPT(5) TRAP_ENTRY_INTERRUPT(6) + TRAP_ENTRY_INTERRUPT(7) TRAP_ENTRY_INTERRUPT(8) + TRAP_ENTRY_INTERRUPT(9) TRAP_ENTRY_INTERRUPT(10) + TRAP_ENTRY_INTERRUPT(11) TRAP_ENTRY_INTERRUPT(12) + TRAP_ENTRY_INTERRUPT(13) TRAP_ENTRY_INTERRUPT(14) + TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m) + TRAP_ENTRY(0x20, do_reg_access) BAD_TRAP(0x21) BAD_TRAP(0x22) + BAD_TRAP(0x23) TRAP_ENTRY(0x24, do_cp_disabled) SKIP_TRAP(0x25, unimp_flush) + BAD_TRAP(0x26) BAD_TRAP(0x27) TRAP_ENTRY(0x28, do_cp_exception) + SRMMU_DFAULT TRAP_ENTRY(0x2a, do_hw_divzero) BAD_TRAP(0x2b) BAD_TRAP(0x2c) + BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31) + BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36) + BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b) + BAD_TRAP(0x3c) BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40) + BAD_TRAP(0x41) BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45) + BAD_TRAP(0x46) BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) + BAD_TRAP(0x4b) BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f) + BAD_TRAP(0x50) + BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55) + BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a) + BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f) + BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64) + BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69) + BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e) + BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73) + BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) + BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) + BAD_TRAP(0x7e) BAD_TRAP(0x7f) + BAD_TRAP(0x80) + BREAKPOINT_TRAP + TRAP_ENTRY(0x82, do_hw_divzero) + TRAP_ENTRY(0x83, do_flush_windows) BAD_TRAP(0x84) BAD_TRAP(0x85) + BAD_TRAP(0x86) BAD_TRAP(0x87) BAD_TRAP(0x88) + BAD_TRAP(0x89) BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) + BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f) + LINUX_SYSCALL_TRAP BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) + BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) + BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) + BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP GETPSR_TRAP + BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) + BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) + BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) + BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) + BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) + BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf) + BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4) + BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9) + BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce) + BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3) + BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8) + BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd) + BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2) + BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7) + BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec) + BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) + BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) + BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) + BAD_TRAP(0xfc) KGDB_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff) +#endif .align PAGE_SIZE /* This was the only reasonable way I could think of to properly align * these page-table data structures. */ + .globl pg0, pg1, pg2, pg3 + .globl empty_bad_page + .globl empty_bad_page_table + .globl empty_zero_page .globl swapper_pg_dir swapper_pg_dir: .skip PAGE_SIZE - .globl empty_zero_page +pg0: .skip PAGE_SIZE +pg1: .skip PAGE_SIZE +pg2: .skip PAGE_SIZE +pg3: .skip PAGE_SIZE +empty_bad_page: .skip PAGE_SIZE +empty_bad_page_table: .skip PAGE_SIZE empty_zero_page: .skip PAGE_SIZE .global root_flags @@ -172,10 +523,10 @@ copy_prom_lvl14: ldd [%g2 + 0x8], %g4 std %g4, [%g3 + 0x8] ! Copy proms handler -/* DON'T TOUCH %l0 thru %l5 in these remapping routines, - * we need their values afterwards! +/* Must determine whether we are on a sun4c MMU, SRMMU, or SUN4/400 MUTANT + * MMU so we can remap ourselves properly. DON'T TOUCH %l0 thru %l5 in these + * remapping routines, we need their values afterwards! */ - /* Now check whether we are already mapped, if we * are we can skip all this garbage coming up. */ @@ -184,29 +535,26 @@ copy_prom_done: be go_to_highmem ! this will be a nop then nop - /* Validate that we are in fact running on an - * SRMMU based cpu. - */ - set 0x4000, %g6 + set LOAD_ADDR, %g6 cmp %g7, %g6 - bne not_a_sun4 + bne remap_not_a_sun4 ! This is not a Sun4 nop -halt_sun4_or_sun4c: - ld [%g7 + 0x68], %o1 - set sun4c_notsup, %o0 - sub %o0, %l6, %o0 - call %o1 - nop - ba halt_me + or %g0, 0x1, %g1 + lduba [%g1] ASI_CONTROL, %g1 ! Only safe to try on Sun4. + subcc %g1, 0x24, %g0 ! Is this a mutant Sun4/400??? + be sun4_mutant_remap ! Ugh, it is... nop -not_a_sun4: - lda [%g0] ASI_M_MMUREGS, %g1 - andcc %g1, 1, %g0 - be halt_sun4_or_sun4c + b sun4_normal_remap ! regular sun4, 2 level mmu nop +remap_not_a_sun4: + lda [%g0] ASI_M_MMUREGS, %g1 ! same as ASI_PTE on sun4c + and %g1, 0x1, %g1 ! Test SRMMU Enable bit ;-) + cmp %g1, 0x0 + be sun4c_remap ! A sun4c MMU or normal Sun4 + nop srmmu_remap: /* First, check for a viking (TI) module. */ set 0x40000000, %g2 @@ -312,6 +660,72 @@ srmmu_nviking: b go_to_highmem nop ! wheee.... + /* This remaps the kernel on Sun4/4xx machines + * that have the Sun Mutant Three Level MMU. + * It's like a platypus, Sun didn't have the + * SRMMU in conception so they kludged the three + * level logic in the regular Sun4 MMU probably. + * + * Basically, you take each entry in the top level + * directory that maps the low 3MB starting at + * address zero and put the mapping in the KERNBASE + * slots. These top level pgd's are called regmaps. + */ +sun4_mutant_remap: + or %g0, %g0, %g3 ! source base + sethi %hi(KERNBASE), %g4 ! destination base + or %g4, %lo(KERNBASE), %g4 + sethi %hi(0x300000), %g5 + or %g5, %lo(0x300000), %g5 ! upper bound 3MB + or %g0, 0x1, %l6 + sll %l6, 24, %l6 ! Regmap mapping size + add %g3, 0x2, %g3 ! Base magic + add %g4, 0x2, %g4 ! Base magic + + /* Main remapping loop on Sun4-Mutant-MMU. + * "I am not an animal..." -Famous Mutant Person + */ +sun4_mutant_loop: + lduha [%g3] ASI_REGMAP, %g2 ! Get lower entry + stha %g2, [%g4] ASI_REGMAP ! Store in high entry + add %g4, %l6, %g4 ! Move up high memory ptr + subcc %g3, %g5, %g0 ! Reached our limit? + blu sun4_mutant_loop ! Nope, loop again + add %g3, %l6, %g3 ! delay, Move up low ptr + b go_to_highmem ! Jump to high memory. + nop + + /* The following is for non-4/4xx sun4 MMU's. */ +sun4_normal_remap: + mov 0, %g3 ! source base + set KERNBASE, %g4 ! destination base + set 0x300000, %g5 ! upper bound 3MB + mov 1, %l6 + sll %l6, 18, %l6 ! sun4 mmu segmap size +sun4_normal_loop: + lduha [%g3] ASI_SEGMAP, %g6 ! load phys_seg + stha %g6, [%g4] ASI_SEGMAP ! stort new virt mapping + add %g3, %l6, %g3 ! increment source pointer + subcc %g3, %g5, %g0 ! reached limit? + blu sun4_normal_loop ! nope, loop again + add %g4, %l6, %g4 ! delay, increment dest ptr + b go_to_highmem + nop + + /* The following works for Sun4c MMU's */ +sun4c_remap: + mov 0, %g3 ! source base + set KERNBASE, %g4 ! destination base + set 0x300000, %g5 ! upper bound 3MB + mov 1, %l6 + sll %l6, 18, %l6 ! sun4c mmu segmap size +sun4c_remap_loop: + lda [%g3] ASI_SEGMAP, %g6 ! load phys_seg + sta %g6, [%g4] ASI_SEGMAP ! store new virt mapping + add %g3, %l6, %g3 ! Increment source ptr + subcc %g3, %g5, %g0 ! Reached limit? + bl sun4c_remap_loop ! Nope, loop again + add %g4, %l6, %g4 ! delay, Increment dest ptr /* Now do a non-relative jump so that PC is in high-memory */ go_to_highmem: @@ -336,12 +750,35 @@ execute_in_high_mem: sethi %hi(linux_dbvec), %g1 st %o1, [%g1 + %lo(linux_dbvec)] + ld [%o0 + 0x4], %o3 + and %o3, 0x3, %o5 ! get the version + + cmp %o3, 0x2 ! a v2 prom? + be found_version + nop + + /* paul@sfe.com.au */ + cmp %o3, 0x3 ! a v3 prom? + be found_version + nop + +/* Old sun4's pass our load address into %o0 instead of the prom + * pointer. On sun4's you have to hard code the romvec pointer into + * your code. Sun probably still does that because they don't even + * trust their own "OpenBoot" specifications. + */ + set LOAD_ADDR, %g6 + cmp %o0, %g6 ! an old sun4? + be sun4_init + nop + +found_version: /* Get the machine type via the mysterious romvec node operations. */ - add %g7, 0x1c, %l1 + add %g7, 0x1c, %l1 ld [%l1], %l0 ld [%l0], %l0 - call %l0 + call %l0 or %g0, %g0, %o0 ! next_node(0) = first_node or %o0, %g0, %g6 @@ -349,13 +786,28 @@ execute_in_high_mem: or %o1, %lo(cputypvar), %o1 sethi %hi(cputypval), %o2 ! information, the string or %o2, %lo(cputypval), %o2 - ld [%l1], %l0 ! 'compatible' tells + ld [%l1], %l0 ! 'compatibility' tells ld [%l0 + 0xc], %l0 ! that we want 'sun4x' where - call %l0 ! x is one of 'm', 'd' or 'e'. - nop ! %o2 holds pointer + call %l0 ! x is one of '', 'c', 'm', + nop ! 'd' or 'e'. %o2 holds pointer ! to a buf where above string ! will get stored by the prom. + subcc %o0, %g0, %g0 + bpos got_prop ! Got the property + nop + + or %g6, %g0, %o0 + sethi %hi(cputypvar_sun4m), %o1 + or %o1, %lo(cputypvar_sun4m), %o1 + sethi %hi(cputypval), %o2 + or %o2, %lo(cputypval), %o2 + ld [%l1], %l0 + ld [%l0 + 0xc], %l0 + call %l0 + nop + +got_prop: #ifdef CONFIG_SPARC_LEON /* no cpu-type check is needed, it is a SPARC-LEON */ @@ -374,29 +826,45 @@ execute_in_high_mem: /* Update boot_cpu_id only on boot cpu */ stub %g1, [%g2 + %lo(boot_cpu_id)] - ba continue_boot + ba sun4c_continue_boot nop #endif - -/* Check to cputype. We may be booted on a sun4u (64 bit box), - * and sun4d needs special treatment. - */ - set cputypval, %o2 ldub [%o2 + 0x4], %l1 - cmp %l1, 'm' - be sun4m_init + cmp %l1, ' ' + be 1f + cmp %l1, 'c' + be 1f + cmp %l1, 'm' + be 1f cmp %l1, 's' - be sun4m_init + be 1f cmp %l1, 'd' - be sun4d_init + be 1f cmp %l1, 'e' be no_sun4e_here ! Could be a sun4e. nop b no_sun4u_here ! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :)) nop +1: set cputypval, %l1 + ldub [%l1 + 0x4], %l1 + cmp %l1, 'm' ! Test for sun4d, sun4e ? + be sun4m_init + cmp %l1, 's' ! Treat sun4s as sun4m + be sun4m_init + cmp %l1, 'd' ! Let us see how the beast will die + be sun4d_init + nop + + /* Jump into mmu context zero. */ + set AC_CONTEXT, %g1 + stba %g0, [%g1] ASI_CONTROL + + b sun4c_continue_boot + nop + /* CPUID in bootbus can be found at PA 0xff0140000 */ #define SUN4D_BOOTBUS_CPUID 0xf0140000 @@ -424,6 +892,66 @@ sun4d_init: /* Fall through to sun4m_init */ sun4m_init: + /* XXX Fucking Cypress... */ + lda [%g0] ASI_M_MMUREGS, %g5 + srl %g5, 28, %g4 + + cmp %g4, 1 + bne 1f + srl %g5, 24, %g4 + + and %g4, 0xf, %g4 + cmp %g4, 7 /* This would be a HyperSparc. */ + + bne 2f + nop + +1: + +#define PATCH_IT(dst, src) \ + set (dst), %g5; \ + set (src), %g4; \ + ld [%g4], %g3; \ + st %g3, [%g5]; \ + ld [%g4+0x4], %g3; \ + st %g3, [%g5+0x4]; + + /* Signed multiply. */ + PATCH_IT(.mul, .mul_patch) + PATCH_IT(.mul+0x08, .mul_patch+0x08) + + /* Signed remainder. */ + PATCH_IT(.rem, .rem_patch) + PATCH_IT(.rem+0x08, .rem_patch+0x08) + PATCH_IT(.rem+0x10, .rem_patch+0x10) + PATCH_IT(.rem+0x18, .rem_patch+0x18) + PATCH_IT(.rem+0x20, .rem_patch+0x20) + PATCH_IT(.rem+0x28, .rem_patch+0x28) + + /* Signed division. */ + PATCH_IT(.div, .div_patch) + PATCH_IT(.div+0x08, .div_patch+0x08) + PATCH_IT(.div+0x10, .div_patch+0x10) + PATCH_IT(.div+0x18, .div_patch+0x18) + PATCH_IT(.div+0x20, .div_patch+0x20) + + /* Unsigned multiply. */ + PATCH_IT(.umul, .umul_patch) + PATCH_IT(.umul+0x08, .umul_patch+0x08) + + /* Unsigned remainder. */ + PATCH_IT(.urem, .urem_patch) + PATCH_IT(.urem+0x08, .urem_patch+0x08) + PATCH_IT(.urem+0x10, .urem_patch+0x10) + PATCH_IT(.urem+0x18, .urem_patch+0x18) + + /* Unsigned division. */ + PATCH_IT(.udiv, .udiv_patch) + PATCH_IT(.udiv+0x08, .udiv_patch+0x08) + PATCH_IT(.udiv+0x10, .udiv_patch+0x10) + +#undef PATCH_IT + /* Ok, the PROM could have done funny things and apple cider could still * be sitting in the fault status/address registers. Read them all to * clear them so we don't get magic faults later on. @@ -434,7 +962,7 @@ sun4m_init: srl %o1, 28, %o1 ! Get a type of the CPU subcc %o1, 4, %g0 ! TI: Viking or MicroSPARC - be continue_boot + be sun4c_continue_boot nop set AC_M_SFSR, %o0 @@ -444,7 +972,7 @@ sun4m_init: /* Fujitsu MicroSPARC-II has no asynchronous flavors of FARs */ subcc %o1, 0, %g0 - be continue_boot + be sun4c_continue_boot nop set AC_M_AFSR, %o0 @@ -454,7 +982,8 @@ sun4m_init: nop -continue_boot: +sun4c_continue_boot: + /* Aieee, now set PC and nPC, enable traps, give ourselves a stack and it's * show-time! @@ -497,7 +1026,10 @@ continue_boot: mov %g0, %g3 stub %g3, [%g2 + %lo(boot_cpu_id)] -1: sll %g3, 2, %g3 +1: /* boot_cpu_id set. calculate boot_cpu_id4 = boot_cpu_id*4 */ + sll %g3, 2, %g3 + sethi %hi(boot_cpu_id4), %g2 + stub %g3, [%g2 + %lo(boot_cpu_id4)] /* Initialize the uwinmask value for init task just in case. * But first make current_set[boot_cpu_id] point to something useful. @@ -633,6 +1165,19 @@ continue_boot: call halt_me nop +sun4_init: + sethi %hi(SUN4_PROM_VECTOR+0x84), %o1 + ld [%o1 + %lo(SUN4_PROM_VECTOR+0x84)], %o1 + set sun4_notsup, %o0 + call %o1 /* printf */ + nop + sethi %hi(SUN4_PROM_VECTOR+0xc4), %o1 + ld [%o1 + %lo(SUN4_PROM_VECTOR+0xc4)], %o1 + call %o1 /* exittomon */ + nop +1: ba 1b ! Cannot exit into KMON + nop + no_sun4e_here: ld [%g7 + 0x68], %o1 set sun4e_notsup, %o0 diff --git a/trunk/arch/sparc/kernel/head_64.S b/trunk/arch/sparc/kernel/head_64.S index b42ddbf9651e..0d810c2f1d00 100644 --- a/trunk/arch/sparc/kernel/head_64.S +++ b/trunk/arch/sparc/kernel/head_64.S @@ -906,7 +906,7 @@ swapper_4m_tsb: * error and will instead write junk into the relocation and * you'll have an unbootable kernel. */ -#include "ttable_64.S" +#include "ttable.S" ! 0x0000000000428000 diff --git a/trunk/arch/sparc/kernel/idprom.c b/trunk/arch/sparc/kernel/idprom.c index 6bd75012109d..9167db40720e 100644 --- a/trunk/arch/sparc/kernel/idprom.c +++ b/trunk/arch/sparc/kernel/idprom.c @@ -25,9 +25,22 @@ static struct idprom idprom_buffer; * of the Sparc CPU and have a meaningful IDPROM machtype value that we * know about. See asm-sparc/machines.h for empirical constants. */ -static struct Sun_Machine_Models Sun_Machines[] = { -/* First, Leon */ +static struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES] = { +/* First, Sun4's */ +{ .name = "Sun 4/100 Series", .id_machtype = (SM_SUN4 | SM_4_110) }, +{ .name = "Sun 4/200 Series", .id_machtype = (SM_SUN4 | SM_4_260) }, +{ .name = "Sun 4/300 Series", .id_machtype = (SM_SUN4 | SM_4_330) }, +{ .name = "Sun 4/400 Series", .id_machtype = (SM_SUN4 | SM_4_470) }, +/* Now Leon */ { .name = "Leon3 System-on-a-Chip", .id_machtype = (M_LEON | M_LEON3_SOC) }, +/* Now, Sun4c's */ +{ .name = "Sun4c SparcStation 1", .id_machtype = (SM_SUN4C | SM_4C_SS1) }, +{ .name = "Sun4c SparcStation IPC", .id_machtype = (SM_SUN4C | SM_4C_IPC) }, +{ .name = "Sun4c SparcStation 1+", .id_machtype = (SM_SUN4C | SM_4C_SS1PLUS) }, +{ .name = "Sun4c SparcStation SLC", .id_machtype = (SM_SUN4C | SM_4C_SLC) }, +{ .name = "Sun4c SparcStation 2", .id_machtype = (SM_SUN4C | SM_4C_SS2) }, +{ .name = "Sun4c SparcStation ELC", .id_machtype = (SM_SUN4C | SM_4C_ELC) }, +{ .name = "Sun4c SparcStation IPX", .id_machtype = (SM_SUN4C | SM_4C_IPX) }, /* Finally, early Sun4m's */ { .name = "Sun4m SparcSystem600", .id_machtype = (SM_SUN4M | SM_4M_SS60) }, { .name = "Sun4m SparcStation10/20", .id_machtype = (SM_SUN4M | SM_4M_SS50) }, @@ -40,7 +53,7 @@ static void __init display_system_type(unsigned char machtype) char sysname[128]; register int i; - for (i = 0; i < ARRAY_SIZE(Sun_Machines); i++) { + for (i = 0; i < NUM_SUN_MACHINES; i++) { if (Sun_Machines[i].id_machtype == machtype) { if (machtype != (SM_SUN4M_OBP | 0x00) || prom_getproperty(prom_root_node, "banner-name", diff --git a/trunk/arch/sparc/kernel/init_task.c b/trunk/arch/sparc/kernel/init_task.c new file mode 100644 index 000000000000..35f141a9f506 --- /dev/null +++ b/trunk/arch/sparc/kernel/init_task.c @@ -0,0 +1,22 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +struct task_struct init_task = INIT_TASK(init_task); +EXPORT_SYMBOL(init_task); + +/* .text section in head.S is aligned at 8k boundary and this gets linked + * right after that so that the init_thread_union is aligned properly as well. + * If this is not aligned on a 8k boundary, then you should change code + * in etrap.S which assumes it. + */ +union thread_union init_thread_union __init_task_data = + { INIT_THREAD_INFO(init_task) }; diff --git a/trunk/arch/sparc/kernel/ioport.c b/trunk/arch/sparc/kernel/ioport.c index a2846f5e32d8..21bd73943f7f 100644 --- a/trunk/arch/sparc/kernel/ioport.c +++ b/trunk/arch/sparc/kernel/ioport.c @@ -50,8 +50,6 @@ #include #include -const struct sparc32_dma_ops *sparc32_dma_ops; - /* This function must make sure that caches and memory are coherent after DMA * On LEON systems without cache snooping it flushes the entire D-CACHE. */ @@ -231,7 +229,7 @@ _sparc_ioremap(struct resource *res, u32 bus, u32 pa, int sz) } pa &= PAGE_MASK; - srmmu_mapiorange(bus, pa, res->start, resource_size(res)); + sparc_mapiorange(bus, pa, res->start, resource_size(res)); return (void __iomem *)(unsigned long)(res->start + offset); } @@ -245,7 +243,7 @@ static void _sparc_free_io(struct resource *res) plen = resource_size(res); BUG_ON((plen & (PAGE_SIZE-1)) != 0); - srmmu_unmapiorange(res->start, plen); + sparc_unmapiorange(res->start, plen); release_resource(res); } @@ -294,13 +292,13 @@ static void *sbus_alloc_coherent(struct device *dev, size_t len, goto err_nova; } - // XXX The sbus_map_dma_area does this for us below, see comments. - // srmmu_mapiorange(0, virt_to_phys(va), res->start, len_total); + // XXX The mmu_map_dma_area does this for us below, see comments. + // sparc_mapiorange(0, virt_to_phys(va), res->start, len_total); /* * XXX That's where sdev would be used. Currently we load * all iommu tables with the same translations. */ - if (sbus_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0) + if (mmu_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0) goto err_noiommu; res->name = op->dev.of_node->name; @@ -345,7 +343,7 @@ static void sbus_free_coherent(struct device *dev, size_t n, void *p, kfree(res); pgv = virt_to_page(p); - sbus_unmap_dma_area(dev, ba, n); + mmu_unmap_dma_area(dev, ba, n); __free_pages(pgv, get_order(n)); } @@ -383,6 +381,11 @@ static int sbus_map_sg(struct device *dev, struct scatterlist *sg, int n, enum dma_data_direction dir, struct dma_attrs *attrs) { mmu_get_scsi_sgl(dev, sg, n); + + /* + * XXX sparc64 can return a partial length here. sun4c should do this + * but it currently panics if it can't fulfill the request - Anton + */ return n; } @@ -466,7 +469,7 @@ static void *pci32_alloc_coherent(struct device *dev, size_t len, printk("pci_alloc_consistent: cannot occupy 0x%lx", len_total); goto err_nova; } - srmmu_mapiorange(0, virt_to_phys(va), res->start, len_total); + sparc_mapiorange(0, virt_to_phys(va), res->start, len_total); *pba = virt_to_phys(va); /* equals virt_to_bus (R.I.P.) for us. */ return (void *) res->start; @@ -511,7 +514,7 @@ static void pci32_free_coherent(struct device *dev, size_t n, void *p, } dma_make_coherent(ba, n); - srmmu_unmapiorange((unsigned long)p, n); + sparc_unmapiorange((unsigned long)p, n); release_resource(res); kfree(res); diff --git a/trunk/arch/sparc/kernel/irq.h b/trunk/arch/sparc/kernel/irq.h index b66b6aad1d6d..5a021dd2f854 100644 --- a/trunk/arch/sparc/kernel/irq.h +++ b/trunk/arch/sparc/kernel/irq.h @@ -1,5 +1,6 @@ #include +#include #include struct irq_bucket { @@ -9,9 +10,6 @@ struct irq_bucket { unsigned int pil; }; -#define SUN4M_HARD_INT(x) (0x000000001 << (x)) -#define SUN4M_SOFT_INT(x) (0x000010000 << (x)) - #define SUN4D_MAX_BOARD 10 #define SUN4D_MAX_IRQ ((SUN4D_MAX_BOARD + 2) << 5) @@ -43,46 +41,52 @@ struct sun4m_irq_global { extern struct sun4m_irq_percpu __iomem *sun4m_irq_percpu[SUN4M_NCPUS]; extern struct sun4m_irq_global __iomem *sun4m_irq_global; -/* The following definitions describe the individual platform features: */ -#define FEAT_L10_CLOCKSOURCE (1 << 0) /* L10 timer is used as a clocksource */ -#define FEAT_L10_CLOCKEVENT (1 << 1) /* L10 timer is used as a clockevent */ -#define FEAT_L14_ONESHOT (1 << 2) /* L14 timer clockevent can oneshot */ - /* - * Platform specific configuration + * Platform specific irq configuration * The individual platforms assign their platform * specifics in their init functions. */ -struct sparc_config { - void (*init_timers)(void); +struct sparc_irq_config { + void (*init_timers)(irq_handler_t); unsigned int (*build_device_irq)(struct platform_device *op, unsigned int real_irq); - - /* generic clockevent features - see FEAT_* above */ - int features; - - /* clock rate used for clock event timer */ - int clock_rate; - - /* one period for clock source timer */ - unsigned int cs_period; - - /* function to obtain offsett for cs period */ - unsigned int (*get_cycles_offset)(void); - - void (*clear_clock_irq)(void); - void (*load_profile_irq)(int cpu, unsigned int limit); }; -extern struct sparc_config sparc_config; +extern struct sparc_irq_config sparc_irq_config; unsigned int irq_alloc(unsigned int real_irq, unsigned int pil); void irq_link(unsigned int irq); void irq_unlink(unsigned int irq); void handler_irq(unsigned int pil, struct pt_regs *regs); -unsigned long leon_get_irqmask(unsigned int irq); +/* Dave Redman (djhr@tadpole.co.uk) + * changed these to function pointers.. it saves cycles and will allow + * the irq dependencies to be split into different files at a later date + * sun4c_irq.c, sun4m_irq.c etc so we could reduce the kernel size. + * Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * Changed these to btfixup entities... It saves cycles :) + */ + +BTFIXUPDEF_CALL(void, clear_clock_irq, void) +BTFIXUPDEF_CALL(void, load_profile_irq, int, unsigned int) + +static inline void clear_clock_irq(void) +{ + BTFIXUP_CALL(clear_clock_irq)(); +} + +static inline void load_profile_irq(int cpu, int limit) +{ + BTFIXUP_CALL(load_profile_irq)(cpu, limit); +} #ifdef CONFIG_SMP +BTFIXUPDEF_CALL(void, set_cpu_int, int, int) +BTFIXUPDEF_CALL(void, clear_cpu_int, int, int) +BTFIXUPDEF_CALL(void, set_irq_udt, int) + +#define set_cpu_int(cpu,level) BTFIXUP_CALL(set_cpu_int)(cpu,level) +#define clear_cpu_int(cpu,level) BTFIXUP_CALL(clear_cpu_int)(cpu,level) +#define set_irq_udt(cpu) BTFIXUP_CALL(set_irq_udt)(cpu) /* All SUN4D IPIs are sent on this IRQ, may be shared with hard IRQs */ #define SUN4D_IPI_IRQ 13 diff --git a/trunk/arch/sparc/kernel/irq_32.c b/trunk/arch/sparc/kernel/irq_32.c index ae04914f7774..b2668afd1c34 100644 --- a/trunk/arch/sparc/kernel/irq_32.c +++ b/trunk/arch/sparc/kernel/irq_32.c @@ -23,8 +23,16 @@ #include "kernel.h" #include "irq.h" +#ifdef CONFIG_SMP +#define SMP_NOP2 "nop; nop;\n\t" +#define SMP_NOP3 "nop; nop; nop;\n\t" +#else +#define SMP_NOP2 +#define SMP_NOP3 +#endif /* SMP */ + /* platform specific irq setup */ -struct sparc_config sparc_config; +struct sparc_irq_config sparc_irq_config; unsigned long arch_local_irq_save(void) { @@ -33,6 +41,7 @@ unsigned long arch_local_irq_save(void) __asm__ __volatile__( "rd %%psr, %0\n\t" + SMP_NOP3 /* Sun4m + Cypress + SMP bug */ "or %0, %2, %1\n\t" "wr %1, 0, %%psr\n\t" "nop; nop; nop\n" @@ -50,6 +59,7 @@ void arch_local_irq_enable(void) __asm__ __volatile__( "rd %%psr, %0\n\t" + SMP_NOP3 /* Sun4m + Cypress + SMP bug */ "andn %0, %1, %0\n\t" "wr %0, 0, %%psr\n\t" "nop; nop; nop\n" @@ -66,6 +76,7 @@ void arch_local_irq_restore(unsigned long old_psr) __asm__ __volatile__( "rd %%psr, %0\n\t" "and %2, %1, %2\n\t" + SMP_NOP2 /* Sun4m + Cypress + SMP bug */ "andn %0, %1, %0\n\t" "wr %0, %2, %%psr\n\t" "nop; nop; nop\n" @@ -335,6 +346,11 @@ void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs) void __init init_IRQ(void) { switch (sparc_cpu_model) { + case sun4c: + case sun4: + sun4c_init_IRQ(); + break; + case sun4m: pcic_probe(); if (pcic_present()) @@ -355,5 +371,6 @@ void __init init_IRQ(void) prom_printf("Cannot initialize IRQs on this Sun machine..."); break; } + btfixup(); } diff --git a/trunk/arch/sparc/kernel/irq_64.c b/trunk/arch/sparc/kernel/irq_64.c index 9bcbbe2c4e7e..dff2c3d7d370 100644 --- a/trunk/arch/sparc/kernel/irq_64.c +++ b/trunk/arch/sparc/kernel/irq_64.c @@ -799,7 +799,7 @@ static void kill_prom_timer(void) prom_limit0 = prom_timers->limit0; prom_limit1 = prom_timers->limit1; - /* Just as in sun4c PROM uses timer which ticks at IRQ 14. + /* Just as in sun4c/sun4m PROM uses timer which ticks at IRQ 14. * We turn both off here just to be paranoid. */ prom_timers->limit0 = 0; diff --git a/trunk/arch/sparc/kernel/kernel.h b/trunk/arch/sparc/kernel/kernel.h index a86372d34587..fd6c36b1df74 100644 --- a/trunk/arch/sparc/kernel/kernel.h +++ b/trunk/arch/sparc/kernel/kernel.h @@ -32,6 +32,9 @@ extern void cpu_probe(void); /* traps_32.c */ extern void handle_hw_divzero(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr); +/* muldiv.c */ +extern int do_user_muldiv (struct pt_regs *, unsigned long); + /* irq_32.c */ extern struct irqaction static_irqaction[]; extern int static_irq_count; @@ -40,7 +43,12 @@ extern spinlock_t irq_action_lock; extern void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs); extern void init_IRQ(void); +/* sun4c_irq.c */ +extern void sun4c_init_IRQ(void); + /* sun4m_irq.c */ +extern unsigned int lvl14_resolution; + extern void sun4m_init_IRQ(void); extern void sun4m_unmask_profile_irq(void); extern void sun4m_clear_profile_irq(int cpu); @@ -77,6 +85,8 @@ extern unsigned int patchme_maybe_smp_msg[]; extern void floppy_hardint(void); /* trampoline_32.S */ +extern int __smp4m_processor_id(void); +extern int __smp4d_processor_id(void); extern unsigned long sun4m_cpu_startup; extern unsigned long sun4d_cpu_startup; diff --git a/trunk/arch/sparc/kernel/leon_kernel.c b/trunk/arch/sparc/kernel/leon_kernel.c index 77c1b916e4dd..35e43673c453 100644 --- a/trunk/arch/sparc/kernel/leon_kernel.c +++ b/trunk/arch/sparc/kernel/leon_kernel.c @@ -10,8 +10,6 @@ #include #include #include -#include -#include #include #include @@ -86,7 +84,7 @@ void leon_eirq_setup(unsigned int eirq) sparc_leon_eirq = eirq; } -unsigned long leon_get_irqmask(unsigned int irq) +static inline unsigned long get_irqmask(unsigned int irq) { unsigned long mask; @@ -212,7 +210,7 @@ unsigned int leon_build_device_irq(unsigned int real_irq, unsigned long mask; irq = 0; - mask = leon_get_irqmask(real_irq); + mask = get_irqmask(real_irq); if (mask == 0) goto out; @@ -252,38 +250,7 @@ void leon_update_virq_handling(unsigned int virq, irq_set_chip_data(virq, (void *)mask); } -static u32 leon_cycles_offset(void) -{ - u32 rld, val, off; - rld = LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].rld); - val = LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].val); - off = rld - val; - return rld - val; -} - -#ifdef CONFIG_SMP - -/* smp clockevent irq */ -irqreturn_t leon_percpu_timer_ce_interrupt(int irq, void *unused) -{ - struct clock_event_device *ce; - int cpu = smp_processor_id(); - - leon_clear_profile_irq(cpu); - - ce = &per_cpu(sparc32_clockevent, cpu); - - irq_enter(); - if (ce->event_handler) - ce->event_handler(ce); - irq_exit(); - - return IRQ_HANDLED; -} - -#endif /* CONFIG_SMP */ - -void __init leon_init_timers(void) +void __init leon_init_timers(irq_handler_t counter_fn) { int irq, eirq; struct device_node *rootnp, *np, *nnp; @@ -293,14 +260,6 @@ void __init leon_init_timers(void) int ampopts; int err; - sparc_config.get_cycles_offset = leon_cycles_offset; - sparc_config.cs_period = 1000000 / HZ; - sparc_config.features |= FEAT_L10_CLOCKSOURCE; - -#ifndef CONFIG_SMP - sparc_config.features |= FEAT_L10_CLOCKEVENT; -#endif - leondebug_irq_disable = 0; leon_debug_irqout = 0; master_l10_counter = (unsigned int *)&dummy_master_l10_counter; @@ -410,7 +369,7 @@ void __init leon_init_timers(void) leon_eirq_setup(eirq); irq = _leon_build_device_irq(NULL, leon3_gptimer_irq+leon3_gptimer_idx); - err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL); + err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL); if (err) { printk(KERN_ERR "unable to attach timer IRQ%d\n", irq); prom_halt(); @@ -427,7 +386,7 @@ void __init leon_init_timers(void) */ local_irq_save(flags); patchme_maybe_smp_msg[0] = 0x01000000; /* NOP out the branch */ - local_ops->cache_all(); + local_flush_cache_all(); local_irq_restore(flags); } #endif @@ -442,7 +401,7 @@ void __init leon_init_timers(void) /* Install per-cpu IRQ handler for broadcasted ticker */ irq = leon_build_device_irq(leon3_ticker_irq, handle_percpu_irq, "per-cpu", 0); - err = request_irq(irq, leon_percpu_timer_ce_interrupt, + err = request_irq(irq, leon_percpu_timer_interrupt, IRQF_PERCPU | IRQF_TIMER, "ticker", NULL); if (err) { @@ -463,12 +422,13 @@ void __init leon_init_timers(void) return; } -static void leon_clear_clock_irq(void) +void leon_clear_clock_irq(void) { } -static void leon_load_profile_irq(int cpu, unsigned int limit) +void leon_load_profile_irq(int cpu, unsigned int limit) { + BUG(); } void __init leon_trans_init(struct device_node *dp) @@ -497,6 +457,25 @@ void __init leon_node_init(struct device_node *dp, struct device_node ***nextp) } #ifdef CONFIG_SMP + +void leon_set_cpu_int(int cpu, int level) +{ + unsigned long mask; + mask = get_irqmask(level); + LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->force[cpu], mask); +} + +static void leon_clear_ipi(int cpu, int level) +{ + unsigned long mask; + mask = get_irqmask(level); + LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->force[cpu], mask<<16); +} + +static void leon_set_udt(int cpu) +{ +} + void leon_clear_profile_irq(int cpu) { } @@ -504,7 +483,7 @@ void leon_clear_profile_irq(int cpu) void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu) { unsigned long mask, flags, *addr; - mask = leon_get_irqmask(irq_nr); + mask = get_irqmask(irq_nr); spin_lock_irqsave(&leon_irq_lock, flags); addr = (unsigned long *)LEON_IMASK(cpu); LEON3_BYPASS_STORE_PA(addr, (LEON3_BYPASS_LOAD_PA(addr) | mask)); @@ -515,11 +494,20 @@ void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu) void __init leon_init_IRQ(void) { - sparc_config.init_timers = leon_init_timers; - sparc_config.build_device_irq = _leon_build_device_irq; - sparc_config.clock_rate = 1000000; - sparc_config.clear_clock_irq = leon_clear_clock_irq; - sparc_config.load_profile_irq = leon_load_profile_irq; + sparc_irq_config.init_timers = leon_init_timers; + sparc_irq_config.build_device_irq = _leon_build_device_irq; + + BTFIXUPSET_CALL(clear_clock_irq, leon_clear_clock_irq, + BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(load_profile_irq, leon_load_profile_irq, + BTFIXUPCALL_NOP); + +#ifdef CONFIG_SMP + BTFIXUPSET_CALL(set_cpu_int, leon_set_cpu_int, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(clear_cpu_int, leon_clear_ipi, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(set_irq_udt, leon_set_udt, BTFIXUPCALL_NORM); +#endif + } void __init leon_init(void) diff --git a/trunk/arch/sparc/kernel/leon_smp.c b/trunk/arch/sparc/kernel/leon_smp.c index a469090faf9f..160cac9c4036 100644 --- a/trunk/arch/sparc/kernel/leon_smp.c +++ b/trunk/arch/sparc/kernel/leon_smp.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -44,7 +43,6 @@ #include #include #include -#include #include "kernel.h" @@ -71,24 +69,26 @@ static inline unsigned long do_swap(volatile unsigned long *ptr, return val; } +static void smp_setup_percpu_timer(void); + void __cpuinit leon_callin(void) { - int cpuid = hard_smp_processor_id(); + int cpuid = hard_smpleon_processor_id(); - local_ops->cache_all(); - local_ops->tlb_all(); + local_flush_cache_all(); + local_flush_tlb_all(); leon_configure_cache_smp(); notify_cpu_starting(cpuid); /* Get our local ticker going. */ - register_percpu_ce(cpuid); + smp_setup_percpu_timer(); calibrate_delay(); smp_store_cpu_info(cpuid); - local_ops->cache_all(); - local_ops->tlb_all(); + local_flush_cache_all(); + local_flush_tlb_all(); /* * Unblock the master CPU _only_ when the scheduler state @@ -99,8 +99,8 @@ void __cpuinit leon_callin(void) */ do_swap(&cpu_callin_map[cpuid], 1); - local_ops->cache_all(); - local_ops->tlb_all(); + local_flush_cache_all(); + local_flush_tlb_all(); /* Fix idle thread fields. */ __asm__ __volatile__("ld [%0], %%g6\n\t" : : "r"(¤t_set[cpuid]) @@ -143,8 +143,8 @@ void __init leon_configure_cache_smp(void) } } - local_ops->cache_all(); - local_ops->tlb_all(); + local_flush_cache_all(); + local_flush_tlb_all(); } void leon_smp_setbroadcast(unsigned int mask) @@ -199,15 +199,21 @@ void __init leon_boot_cpus(void) leon_smp_setbroadcast(1 << LEON3_IRQ_TICKER); leon_configure_cache_smp(); - local_ops->cache_all(); + smp_setup_percpu_timer(); + local_flush_cache_all(); } -int __cpuinit leon_boot_one_cpu(int i, struct task_struct *idle) +int __cpuinit leon_boot_one_cpu(int i) { + + struct task_struct *p; int timeout; - current_set[i] = task_thread_info(idle); + /* Cook up an idler for this guy. */ + p = fork_idle(i); + + current_set[i] = task_thread_info(p); /* See trampoline.S:leon_smp_cpu_startup for details... * Initialize the contexts table @@ -221,7 +227,7 @@ int __cpuinit leon_boot_one_cpu(int i, struct task_struct *idle) /* whirrr, whirrr, whirrrrrrrrr... */ printk(KERN_INFO "Starting CPU %d : (irqmp: 0x%x)\n", (unsigned int)i, (unsigned int)&leon3_irqctrl_regs->mpstatus); - local_ops->cache_all(); + local_flush_cache_all(); /* Make sure all IRQs are of from the start for this new CPU */ LEON_BYPASS_STORE_PA(&leon3_irqctrl_regs->mask[i], 0); @@ -246,7 +252,7 @@ int __cpuinit leon_boot_one_cpu(int i, struct task_struct *idle) leon_enable_irq_cpu(leon_ipi_irq, i); } - local_ops->cache_all(); + local_flush_cache_all(); return 0; } @@ -266,7 +272,7 @@ void __init leon_smp_done(void) } } *prev = first; - local_ops->cache_all(); + local_flush_cache_all(); /* Free unneeded trap tables */ if (!cpu_present(1)) { @@ -332,7 +338,7 @@ static void __init leon_ipi_init(void) local_irq_save(flags); trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (leon_ipi_irq - 1)]; trap_table->inst_three += smpleon_ipi - real_irq_entry; - local_ops->cache_all(); + local_flush_cache_all(); local_irq_restore(flags); for_each_possible_cpu(cpu) { @@ -341,13 +347,6 @@ static void __init leon_ipi_init(void) } } -static void leon_send_ipi(int cpu, int level) -{ - unsigned long mask; - mask = leon_get_irqmask(level); - LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->force[cpu], mask); -} - static void leon_ipi_single(int cpu) { struct leon_ipi_work *work = &per_cpu(leon_ipi_work, cpu); @@ -356,7 +355,7 @@ static void leon_ipi_single(int cpu) work->single = 1; /* Generate IRQ on the CPU */ - leon_send_ipi(cpu, leon_ipi_irq); + set_cpu_int(cpu, leon_ipi_irq); } static void leon_ipi_mask_one(int cpu) @@ -367,7 +366,7 @@ static void leon_ipi_mask_one(int cpu) work->msk = 1; /* Generate IRQ on the CPU */ - leon_send_ipi(cpu, leon_ipi_irq); + set_cpu_int(cpu, leon_ipi_irq); } static void leon_ipi_resched(int cpu) @@ -378,7 +377,7 @@ static void leon_ipi_resched(int cpu) work->resched = 1; /* Generate IRQ on the CPU (any IRQ will cause resched) */ - leon_send_ipi(cpu, leon_ipi_irq); + set_cpu_int(cpu, leon_ipi_irq); } void leonsmp_ipi_interrupt(void) @@ -450,7 +449,7 @@ static void leon_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, if (cpumask_test_cpu(i, &mask)) { ccall_info.processors_in[i] = 0; ccall_info.processors_out[i] = 0; - leon_send_ipi(i, LEON3_IRQ_CROSS_CALL); + set_cpu_int(i, LEON3_IRQ_CROSS_CALL); } } @@ -493,19 +492,68 @@ void leon_cross_call_irq(void) ccall_info.processors_out[i] = 1; } -static const struct sparc32_ipi_ops leon_ipi_ops = { - .cross_call = leon_cross_call, - .resched = leon_ipi_resched, - .single = leon_ipi_single, - .mask_one = leon_ipi_mask_one, -}; +irqreturn_t leon_percpu_timer_interrupt(int irq, void *unused) +{ + int cpu = smp_processor_id(); + + leon_clear_profile_irq(cpu); + + profile_tick(CPU_PROFILING); + + if (!--prof_counter(cpu)) { + int user = user_mode(get_irq_regs()); + + update_process_times(user); + + prof_counter(cpu) = prof_multiplier(cpu); + } + + return IRQ_HANDLED; +} + +static void __init smp_setup_percpu_timer(void) +{ + int cpu = smp_processor_id(); + + prof_counter(cpu) = prof_multiplier(cpu) = 1; +} + +void __init leon_blackbox_id(unsigned *addr) +{ + int rd = *addr & 0x3e000000; + int rs1 = rd >> 11; + + /* patch places where ___b_hard_smp_processor_id appears */ + addr[0] = 0x81444000 | rd; /* rd %asr17, reg */ + addr[1] = 0x8130201c | rd | rs1; /* srl reg, 0x1c, reg */ + addr[2] = 0x01000000; /* nop */ +} + +void __init leon_blackbox_current(unsigned *addr) +{ + int rd = *addr & 0x3e000000; + int rs1 = rd >> 11; + + /* patch LOAD_CURRENT macro where ___b_load_current appears */ + addr[0] = 0x81444000 | rd; /* rd %asr17, reg */ + addr[2] = 0x8130201c | rd | rs1; /* srl reg, 0x1c, reg */ + addr[4] = 0x81282002 | rd | rs1; /* sll reg, 0x2, reg */ + +} void __init leon_init_smp(void) { /* Patch ipi15 trap table */ t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_leon - linux_trap_ipi15_sun4m); - sparc32_ipi_ops = &leon_ipi_ops; + BTFIXUPSET_BLACKBOX(hard_smp_processor_id, leon_blackbox_id); + BTFIXUPSET_BLACKBOX(load_current, leon_blackbox_current); + BTFIXUPSET_CALL(smp_cross_call, leon_cross_call, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(__hard_smp_processor_id, __leon_processor_id, + BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(smp_ipi_resched, leon_ipi_resched, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(smp_ipi_single, leon_ipi_single, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(smp_ipi_mask_one, leon_ipi_mask_one, BTFIXUPCALL_NORM); } #endif /* CONFIG_SPARC_LEON */ diff --git a/trunk/arch/sparc/kernel/module.c b/trunk/arch/sparc/kernel/module.c index 15e0a1693976..276359e1ff56 100644 --- a/trunk/arch/sparc/kernel/module.c +++ b/trunk/arch/sparc/kernel/module.c @@ -32,11 +32,26 @@ static void *module_map(unsigned long size) GFP_KERNEL, PAGE_KERNEL, -1, __builtin_return_address(0)); } + +static char *dot2underscore(char *name) +{ + return name; +} #else static void *module_map(unsigned long size) { return vmalloc(size); } + +/* Replace references to .func with _Func */ +static char *dot2underscore(char *name) +{ + if (name[0] == '.') { + name[0] = '_'; + name[1] = toupper(name[1]); + } + return name; +} #endif /* CONFIG_SPARC64 */ void *module_alloc(unsigned long size) @@ -78,8 +93,12 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, for (i = 1; i < sechdrs[symidx].sh_size / sizeof(Elf_Sym); i++) { if (sym[i].st_shndx == SHN_UNDEF) { - if (ELF_ST_TYPE(sym[i].st_info) == STT_REGISTER) + if (ELF_ST_TYPE(sym[i].st_info) == STT_REGISTER) { sym[i].st_shndx = SHN_ABS; + } else { + char *name = strtab + sym[i].st_name; + dot2underscore(name); + } } } return 0; diff --git a/trunk/arch/sparc/kernel/muldiv.c b/trunk/arch/sparc/kernel/muldiv.c new file mode 100644 index 000000000000..f7db516b07d8 --- /dev/null +++ b/trunk/arch/sparc/kernel/muldiv.c @@ -0,0 +1,238 @@ +/* + * muldiv.c: Hardware multiply/division illegal instruction trap + * for sun4c/sun4 (which do not have those instructions) + * + * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + * + * 2004-12-25 Krzysztof Helt (krzysztof.h1@wp.pl) + * - fixed registers constrains in inline assembly declarations + */ + +#include +#include +#include +#include +#include +#include + +#include "kernel.h" + +/* #define DEBUG_MULDIV */ + +static inline int has_imm13(int insn) +{ + return (insn & 0x2000); +} + +static inline int is_foocc(int insn) +{ + return (insn & 0x800000); +} + +static inline int sign_extend_imm13(int imm) +{ + return imm << 19 >> 19; +} + +static inline void advance(struct pt_regs *regs) +{ + regs->pc = regs->npc; + regs->npc += 4; +} + +static inline void maybe_flush_windows(unsigned int rs1, unsigned int rs2, + unsigned int rd) +{ + if(rs2 >= 16 || rs1 >= 16 || rd >= 16) { + /* Wheee... */ + __asm__ __volatile__("save %sp, -0x40, %sp\n\t" + "save %sp, -0x40, %sp\n\t" + "save %sp, -0x40, %sp\n\t" + "save %sp, -0x40, %sp\n\t" + "save %sp, -0x40, %sp\n\t" + "save %sp, -0x40, %sp\n\t" + "save %sp, -0x40, %sp\n\t" + "restore; restore; restore; restore;\n\t" + "restore; restore; restore;\n\t"); + } +} + +#define fetch_reg(reg, regs) ({ \ + struct reg_window32 __user *win; \ + register unsigned long ret; \ + \ + if (!(reg)) ret = 0; \ + else if ((reg) < 16) { \ + ret = regs->u_regs[(reg)]; \ + } else { \ + /* Ho hum, the slightly complicated case. */ \ + win = (struct reg_window32 __user *)regs->u_regs[UREG_FP];\ + if (get_user (ret, &win->locals[(reg) - 16])) return -1;\ + } \ + ret; \ +}) + +static inline int +store_reg(unsigned int result, unsigned int reg, struct pt_regs *regs) +{ + struct reg_window32 __user *win; + + if (!reg) + return 0; + if (reg < 16) { + regs->u_regs[reg] = result; + return 0; + } else { + /* need to use put_user() in this case: */ + win = (struct reg_window32 __user *) regs->u_regs[UREG_FP]; + return (put_user(result, &win->locals[reg - 16])); + } +} + +/* Should return 0 if mul/div emulation succeeded and SIGILL should + * not be issued. + */ +int do_user_muldiv(struct pt_regs *regs, unsigned long pc) +{ + unsigned int insn; + int inst; + unsigned int rs1, rs2, rdv; + + if (!pc) + return -1; /* This happens to often, I think */ + if (get_user (insn, (unsigned int __user *)pc)) + return -1; + if ((insn & 0xc1400000) != 0x80400000) + return -1; + inst = ((insn >> 19) & 0xf); + if ((inst & 0xe) != 10 && (inst & 0xe) != 14) + return -1; + + /* Now we know we have to do something with umul, smul, udiv or sdiv */ + rs1 = (insn >> 14) & 0x1f; + rs2 = insn & 0x1f; + rdv = (insn >> 25) & 0x1f; + if (has_imm13(insn)) { + maybe_flush_windows(rs1, 0, rdv); + rs2 = sign_extend_imm13(insn); + } else { + maybe_flush_windows(rs1, rs2, rdv); + rs2 = fetch_reg(rs2, regs); + } + rs1 = fetch_reg(rs1, regs); + switch (inst) { + case 10: /* umul */ +#ifdef DEBUG_MULDIV + printk ("unsigned muldiv: 0x%x * 0x%x = ", rs1, rs2); +#endif + __asm__ __volatile__ ("\n\t" + "mov %0, %%o0\n\t" + "call .umul\n\t" + " mov %1, %%o1\n\t" + "mov %%o0, %0\n\t" + "mov %%o1, %1\n\t" + : "=r" (rs1), "=r" (rs2) + : "0" (rs1), "1" (rs2) + : "o0", "o1", "o2", "o3", "o4", "o5", "o7", "cc"); +#ifdef DEBUG_MULDIV + printk ("0x%x%08x\n", rs2, rs1); +#endif + if (store_reg(rs1, rdv, regs)) + return -1; + regs->y = rs2; + break; + case 11: /* smul */ +#ifdef DEBUG_MULDIV + printk ("signed muldiv: 0x%x * 0x%x = ", rs1, rs2); +#endif + __asm__ __volatile__ ("\n\t" + "mov %0, %%o0\n\t" + "call .mul\n\t" + " mov %1, %%o1\n\t" + "mov %%o0, %0\n\t" + "mov %%o1, %1\n\t" + : "=r" (rs1), "=r" (rs2) + : "0" (rs1), "1" (rs2) + : "o0", "o1", "o2", "o3", "o4", "o5", "o7", "cc"); +#ifdef DEBUG_MULDIV + printk ("0x%x%08x\n", rs2, rs1); +#endif + if (store_reg(rs1, rdv, regs)) + return -1; + regs->y = rs2; + break; + case 14: /* udiv */ +#ifdef DEBUG_MULDIV + printk ("unsigned muldiv: 0x%x%08x / 0x%x = ", regs->y, rs1, rs2); +#endif + if (!rs2) { +#ifdef DEBUG_MULDIV + printk ("DIVISION BY ZERO\n"); +#endif + handle_hw_divzero (regs, pc, regs->npc, regs->psr); + return 0; + } + __asm__ __volatile__ ("\n\t" + "mov %2, %%o0\n\t" + "mov %0, %%o1\n\t" + "mov %%g0, %%o2\n\t" + "call __udivdi3\n\t" + " mov %1, %%o3\n\t" + "mov %%o1, %0\n\t" + "mov %%o0, %1\n\t" + : "=r" (rs1), "=r" (rs2) + : "r" (regs->y), "0" (rs1), "1" (rs2) + : "o0", "o1", "o2", "o3", "o4", "o5", "o7", + "g1", "g2", "g3", "cc"); +#ifdef DEBUG_MULDIV + printk ("0x%x\n", rs1); +#endif + if (store_reg(rs1, rdv, regs)) + return -1; + break; + case 15: /* sdiv */ +#ifdef DEBUG_MULDIV + printk ("signed muldiv: 0x%x%08x / 0x%x = ", regs->y, rs1, rs2); +#endif + if (!rs2) { +#ifdef DEBUG_MULDIV + printk ("DIVISION BY ZERO\n"); +#endif + handle_hw_divzero (regs, pc, regs->npc, regs->psr); + return 0; + } + __asm__ __volatile__ ("\n\t" + "mov %2, %%o0\n\t" + "mov %0, %%o1\n\t" + "mov %%g0, %%o2\n\t" + "call __divdi3\n\t" + " mov %1, %%o3\n\t" + "mov %%o1, %0\n\t" + "mov %%o0, %1\n\t" + : "=r" (rs1), "=r" (rs2) + : "r" (regs->y), "0" (rs1), "1" (rs2) + : "o0", "o1", "o2", "o3", "o4", "o5", "o7", + "g1", "g2", "g3", "cc"); +#ifdef DEBUG_MULDIV + printk ("0x%x\n", rs1); +#endif + if (store_reg(rs1, rdv, regs)) + return -1; + break; + } + if (is_foocc (insn)) { + regs->psr &= ~PSR_ICC; + if ((inst & 0xe) == 14) { + /* ?div */ + if (rs2) regs->psr |= PSR_V; + } + if (!rs1) regs->psr |= PSR_Z; + if (((int)rs1) < 0) regs->psr |= PSR_N; +#ifdef DEBUG_MULDIV + printk ("psr muldiv: %08x\n", regs->psr); +#endif + } + advance(regs); + return 0; +} diff --git a/trunk/arch/sparc/kernel/of_device_32.c b/trunk/arch/sparc/kernel/of_device_32.c index 185aa96fa5be..4ee8ce0d5d8d 100644 --- a/trunk/arch/sparc/kernel/of_device_32.c +++ b/trunk/arch/sparc/kernel/of_device_32.c @@ -356,7 +356,7 @@ static struct platform_device * __init scan_one_device(struct device_node *dp, op->archdata.num_irqs = len / sizeof(struct linux_prom_irqs); for (i = 0; i < op->archdata.num_irqs; i++) op->archdata.irqs[i] = - sparc_config.build_device_irq(op, intr[i].pri); + sparc_irq_config.build_device_irq(op, intr[i].pri); } else { const unsigned int *irq = of_get_property(dp, "interrupts", &len); @@ -365,7 +365,7 @@ static struct platform_device * __init scan_one_device(struct device_node *dp, op->archdata.num_irqs = len / sizeof(unsigned int); for (i = 0; i < op->archdata.num_irqs; i++) op->archdata.irqs[i] = - sparc_config.build_device_irq(op, irq[i]); + sparc_irq_config.build_device_irq(op, irq[i]); } else { op->archdata.num_irqs = 0; } diff --git a/trunk/arch/sparc/kernel/pcic.c b/trunk/arch/sparc/kernel/pcic.c index ded3f6090c3f..fcc148effaac 100644 --- a/trunk/arch/sparc/kernel/pcic.c +++ b/trunk/arch/sparc/kernel/pcic.c @@ -703,29 +703,32 @@ static void pcic_clear_clock_irq(void) pcic_timer_dummy = readl(pcic0.pcic_regs+PCI_SYS_LIMIT); } -/* CPU frequency is 100 MHz, timer increments every 4 CPU clocks */ -#define USECS_PER_JIFFY (1000000 / HZ) -#define TICK_TIMER_LIMIT ((100 * 1000000 / 4) / HZ) - -static unsigned int pcic_cycles_offset(void) +static irqreturn_t pcic_timer_handler (int irq, void *h) { - u32 value, count; + pcic_clear_clock_irq(); + xtime_update(1); +#ifndef CONFIG_SMP + update_process_times(user_mode(get_irq_regs())); +#endif + return IRQ_HANDLED; +} - value = readl(pcic0.pcic_regs + PCI_SYS_COUNTER); - count = value & ~PCI_SYS_COUNTER_OVERFLOW; +#define USECS_PER_JIFFY 10000 /* We have 100HZ "standard" timer for sparc */ +#define TICK_TIMER_LIMIT ((100*1000000/4)/100) - if (value & PCI_SYS_COUNTER_OVERFLOW) - count += TICK_TIMER_LIMIT; +u32 pci_gettimeoffset(void) +{ /* - * We divide all by HZ + * We divide all by 100 * to have microsecond resolution and to avoid overflow */ - count = ((count / HZ) * USECS_PER_JIFFY) / (TICK_TIMER_LIMIT / HZ); - - /* Coordinate with the sparc_config.clock_rate setting */ - return count * 2; + unsigned long count = + readl(pcic0.pcic_regs+PCI_SYS_COUNTER) & ~PCI_SYS_COUNTER_OVERFLOW; + count = ((count/100)*USECS_PER_JIFFY) / (TICK_TIMER_LIMIT/100); + return count * 1000; } + void __init pci_time_init(void) { struct linux_pcic *pcic = &pcic0; @@ -733,16 +736,9 @@ void __init pci_time_init(void) int timer_irq, irq; int err; -#ifndef CONFIG_SMP - /* - * The clock_rate is in SBUS dimension. - * We take into account this in pcic_cycles_offset() - */ - sparc_config.clock_rate = SBUS_CLOCK_RATE / HZ; - sparc_config.features |= FEAT_L10_CLOCKEVENT; -#endif - sparc_config.features |= FEAT_L10_CLOCKSOURCE; - sparc_config.get_cycles_offset = pcic_cycles_offset; + do_arch_gettimeoffset = pci_gettimeoffset; + + btfixup(); writel (TICK_TIMER_LIMIT, pcic->pcic_regs+PCI_SYS_LIMIT); /* PROM should set appropriate irq */ @@ -751,7 +747,7 @@ void __init pci_time_init(void) writel (PCI_COUNTER_IRQ_SET(timer_irq, 0), pcic->pcic_regs+PCI_COUNTER_IRQ); irq = pcic_build_device_irq(NULL, timer_irq); - err = request_irq(irq, timer_interrupt, + err = request_irq(irq, pcic_timer_handler, IRQF_TIMER, "timer", NULL); if (err) { prom_printf("time_init: unable to attach IRQ%d\n", timer_irq); @@ -879,9 +875,10 @@ static void pcic_load_profile_irq(int cpu, unsigned int limit) void __init sun4m_pci_init_IRQ(void) { - sparc_config.build_device_irq = pcic_build_device_irq; - sparc_config.clear_clock_irq = pcic_clear_clock_irq; - sparc_config.load_profile_irq = pcic_load_profile_irq; + sparc_irq_config.build_device_irq = pcic_build_device_irq; + + BTFIXUPSET_CALL(clear_clock_irq, pcic_clear_clock_irq, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(load_profile_irq, pcic_load_profile_irq, BTFIXUPCALL_NORM); } int pcibios_assign_resource(struct pci_dev *pdev, int resource) diff --git a/trunk/arch/sparc/kernel/process_32.c b/trunk/arch/sparc/kernel/process_32.c index fe6787cc62fc..efa07542e85f 100644 --- a/trunk/arch/sparc/kernel/process_32.c +++ b/trunk/arch/sparc/kernel/process_32.c @@ -67,6 +67,8 @@ struct thread_info *current_set[NR_CPUS]; #ifndef CONFIG_SMP +#define SUN4C_FAULT_HIGH 100 + /* * the idle loop on a Sparc... ;) */ @@ -74,6 +76,36 @@ void cpu_idle(void) { /* endless idle loop with no priority at all */ for (;;) { + if (ARCH_SUN4C) { + static int count = HZ; + static unsigned long last_jiffies; + static unsigned long last_faults; + static unsigned long fps; + unsigned long now; + unsigned long faults; + + extern unsigned long sun4c_kernel_faults; + extern void sun4c_grow_kernel_ring(void); + + local_irq_disable(); + now = jiffies; + count -= (now - last_jiffies); + last_jiffies = now; + if (count < 0) { + count += HZ; + faults = sun4c_kernel_faults; + fps = (fps + (faults - last_faults)) >> 1; + last_faults = faults; +#if 0 + printk("kernel faults / second = %ld\n", fps); +#endif + if (fps >= SUN4C_FAULT_HIGH) { + sun4c_grow_kernel_ring(); + } + } + local_irq_enable(); + } + if (pm_idle) { while (!need_resched()) (*pm_idle)(); @@ -82,6 +114,7 @@ void cpu_idle(void) cpu_relax(); } schedule_preempt_disabled(); + check_pgt_cache(); } } @@ -104,6 +137,7 @@ void cpu_idle(void) cpu_relax(); } schedule_preempt_disabled(); + check_pgt_cache(); } } @@ -145,6 +179,88 @@ void machine_power_off(void) machine_halt(); } +#if 0 + +static DEFINE_SPINLOCK(sparc_backtrace_lock); + +void __show_backtrace(unsigned long fp) +{ + struct reg_window32 *rw; + unsigned long flags; + int cpu = smp_processor_id(); + + spin_lock_irqsave(&sparc_backtrace_lock, flags); + + rw = (struct reg_window32 *)fp; + while(rw && (((unsigned long) rw) >= PAGE_OFFSET) && + !(((unsigned long) rw) & 0x7)) { + printk("CPU[%d]: ARGS[%08lx,%08lx,%08lx,%08lx,%08lx,%08lx] " + "FP[%08lx] CALLER[%08lx]: ", cpu, + rw->ins[0], rw->ins[1], rw->ins[2], rw->ins[3], + rw->ins[4], rw->ins[5], + rw->ins[6], + rw->ins[7]); + printk("%pS\n", (void *) rw->ins[7]); + rw = (struct reg_window32 *) rw->ins[6]; + } + spin_unlock_irqrestore(&sparc_backtrace_lock, flags); +} + +#define __SAVE __asm__ __volatile__("save %sp, -0x40, %sp\n\t") +#define __RESTORE __asm__ __volatile__("restore %g0, %g0, %g0\n\t") +#define __GET_FP(fp) __asm__ __volatile__("mov %%i6, %0" : "=r" (fp)) + +void show_backtrace(void) +{ + unsigned long fp; + + __SAVE; __SAVE; __SAVE; __SAVE; + __SAVE; __SAVE; __SAVE; __SAVE; + __RESTORE; __RESTORE; __RESTORE; __RESTORE; + __RESTORE; __RESTORE; __RESTORE; __RESTORE; + + __GET_FP(fp); + + __show_backtrace(fp); +} + +#ifdef CONFIG_SMP +void smp_show_backtrace_all_cpus(void) +{ + xc0((smpfunc_t) show_backtrace); + show_backtrace(); +} +#endif + +void show_stackframe(struct sparc_stackf *sf) +{ + unsigned long size; + unsigned long *stk; + int i; + + printk("l0: %08lx l1: %08lx l2: %08lx l3: %08lx " + "l4: %08lx l5: %08lx l6: %08lx l7: %08lx\n", + sf->locals[0], sf->locals[1], sf->locals[2], sf->locals[3], + sf->locals[4], sf->locals[5], sf->locals[6], sf->locals[7]); + printk("i0: %08lx i1: %08lx i2: %08lx i3: %08lx " + "i4: %08lx i5: %08lx fp: %08lx i7: %08lx\n", + sf->ins[0], sf->ins[1], sf->ins[2], sf->ins[3], + sf->ins[4], sf->ins[5], (unsigned long)sf->fp, sf->callers_pc); + printk("sp: %08lx x0: %08lx x1: %08lx x2: %08lx " + "x3: %08lx x4: %08lx x5: %08lx xx: %08lx\n", + (unsigned long)sf->structptr, sf->xargs[0], sf->xargs[1], + sf->xargs[2], sf->xargs[3], sf->xargs[4], sf->xargs[5], + sf->xxargs[0]); + size = ((unsigned long)sf->fp) - ((unsigned long)sf); + size -= STACKFRAME_SZ; + stk = (unsigned long *)((unsigned long)sf + STACKFRAME_SZ); + i = 0; + do { + printk("s%d: %08lx\n", i++, *stk++); + } while ((size -= sizeof(unsigned long))); +} +#endif + void show_regs(struct pt_regs *r) { struct reg_window32 *rw = (struct reg_window32 *) r->u_regs[14]; diff --git a/trunk/arch/sparc/kernel/ptrace_64.c b/trunk/arch/sparc/kernel/ptrace_64.c index 484dabac7045..6f97c0767995 100644 --- a/trunk/arch/sparc/kernel/ptrace_64.c +++ b/trunk/arch/sparc/kernel/ptrace_64.c @@ -1062,7 +1062,7 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs) int ret = 0; /* do the secure computing check first */ - secure_computing_strict(regs->u_regs[UREG_G1]); + secure_computing(regs->u_regs[UREG_G1]); if (test_thread_flag(TIF_SYSCALL_TRACE)) ret = tracehook_report_syscall_entry(regs); diff --git a/trunk/arch/sparc/kernel/rtrap_32.S b/trunk/arch/sparc/kernel/rtrap_32.S index 7abc24e2bf1a..5f5f74c2c2ca 100644 --- a/trunk/arch/sparc/kernel/rtrap_32.S +++ b/trunk/arch/sparc/kernel/rtrap_32.S @@ -128,12 +128,13 @@ rtrap_patch2: and %glob_tmp, 0xff, %glob_tmp wr %glob_tmp, 0x0, %wim - /* Here comes the architecture specific - * branch to the user stack checking routine - * for return from traps. - */ - b srmmu_rett_stackchk - andcc %fp, 0x7, %g0 + /* Here comes the architecture specific + * branch to the user stack checking routine + * for return from traps. + */ + .globl rtrap_mmu_patchme +rtrap_mmu_patchme: b sun4c_rett_stackchk + andcc %fp, 0x7, %g0 ret_trap_userwins_ok: LOAD_PT_PRIV(sp, t_psr, t_pc, t_npc) @@ -224,6 +225,69 @@ ret_trap_user_stack_is_bolixed: b signal_p ld [%curptr + TI_FLAGS], %g2 +sun4c_rett_stackchk: + be 1f + and %fp, 0xfff, %g1 ! delay slot + + b ret_trap_user_stack_is_bolixed + 0x4 + wr %t_wim, 0x0, %wim + + /* See if we have to check the sanity of one page or two */ +1: + add %g1, 0x38, %g1 + sra %fp, 29, %g2 + add %g2, 0x1, %g2 + andncc %g2, 0x1, %g0 + be 1f + andncc %g1, 0xff8, %g0 + + /* %sp is in vma hole, yuck */ + b ret_trap_user_stack_is_bolixed + 0x4 + wr %t_wim, 0x0, %wim + +1: + be sun4c_rett_onepage /* Only one page to check */ + lda [%fp] ASI_PTE, %g2 + +sun4c_rett_twopages: + add %fp, 0x38, %g1 + sra %g1, 29, %g2 + add %g2, 0x1, %g2 + andncc %g2, 0x1, %g0 + be 1f + lda [%g1] ASI_PTE, %g2 + + /* Second page is in vma hole */ + b ret_trap_user_stack_is_bolixed + 0x4 + wr %t_wim, 0x0, %wim + +1: + srl %g2, 29, %g2 + andcc %g2, 0x4, %g0 + bne sun4c_rett_onepage + lda [%fp] ASI_PTE, %g2 + + /* Second page has bad perms */ + b ret_trap_user_stack_is_bolixed + 0x4 + wr %t_wim, 0x0, %wim + +sun4c_rett_onepage: + srl %g2, 29, %g2 + andcc %g2, 0x4, %g0 + bne,a 1f + restore %g0, %g0, %g0 + + /* A page had bad page permissions, losing... */ + b ret_trap_user_stack_is_bolixed + 0x4 + wr %t_wim, 0x0, %wim + + /* Whee, things are ok, load the window and continue. */ +1: + LOAD_WINDOW(sp) + + b ret_trap_userwins_ok + save %g0, %g0, %g0 + .globl srmmu_rett_stackchk srmmu_rett_stackchk: bne ret_trap_user_stack_is_bolixed diff --git a/trunk/arch/sparc/kernel/rtrap_64.S b/trunk/arch/sparc/kernel/rtrap_64.S index afa2a9e3d0a0..9171fc238def 100644 --- a/trunk/arch/sparc/kernel/rtrap_64.S +++ b/trunk/arch/sparc/kernel/rtrap_64.S @@ -73,8 +73,18 @@ rtrap_nmi: ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 .globl rtrap_irq, rtrap, irqsz_patchme, rtrap_xcall rtrap_irq: rtrap: +#ifndef CONFIG_SMP + sethi %hi(__cpu_data), %l0 + lduw [%l0 + %lo(__cpu_data)], %l1 +#else + sethi %hi(__cpu_data), %l0 + or %l0, %lo(__cpu_data), %l0 + lduw [%l0 + %g5], %l1 +#endif + cmp %l1, 0 + /* mm/ultra.S:xcall_report_regs KNOWS about this load. */ - ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 + ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 rtrap_xcall: sethi %hi(0xf << 20), %l4 and %l1, %l4, %l4 diff --git a/trunk/arch/sparc/kernel/setup_32.c b/trunk/arch/sparc/kernel/setup_32.c index c052313f4dc5..d444468b27f6 100644 --- a/trunk/arch/sparc/kernel/setup_32.c +++ b/trunk/arch/sparc/kernel/setup_32.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -105,6 +106,7 @@ unsigned long cmdline_memory_size __initdata = 0; /* which CPU booted us (0xff = not set) */ unsigned char boot_cpu_id = 0xff; /* 0xff will make it into DATA section... */ +unsigned char boot_cpu_id4; /* boot_cpu_id << 2 */ static void prom_console_write(struct console *con, const char *s, unsigned n) @@ -180,6 +182,13 @@ static void __init boot_flags_init(char *commands) } } +/* This routine will in the future do all the nasty prom stuff + * to probe for the mmu type and its parameters, etc. This will + * also be where SMP things happen. + */ + +extern void sun4c_probe_vac(void); + extern unsigned short root_flags; extern unsigned short root_dev; extern unsigned short ram_flags; @@ -191,52 +200,6 @@ extern int root_mountflags; char reboot_command[COMMAND_LINE_SIZE]; -struct cpuid_patch_entry { - unsigned int addr; - unsigned int sun4d[3]; - unsigned int leon[3]; -}; -extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end; - -static void __init per_cpu_patch(void) -{ - struct cpuid_patch_entry *p; - - if (sparc_cpu_model == sun4m) { - /* Nothing to do, this is what the unpatched code - * targets. - */ - return; - } - - p = &__cpuid_patch; - while (p < &__cpuid_patch_end) { - unsigned long addr = p->addr; - unsigned int *insns; - - switch (sparc_cpu_model) { - case sun4d: - insns = &p->sun4d[0]; - break; - - case sparc_leon: - insns = &p->leon[0]; - break; - default: - prom_printf("Unknown cpu type, halting.\n"); - prom_halt(); - } - *(unsigned int *) (addr + 0) = insns[0]; - flushi(addr + 0); - *(unsigned int *) (addr + 4) = insns[1]; - flushi(addr + 4); - *(unsigned int *) (addr + 8) = insns[2]; - flushi(addr + 8); - - p++; - } -} - enum sparc_cpu sparc_cpu_model; EXPORT_SYMBOL(sparc_cpu_model); @@ -262,6 +225,10 @@ void __init setup_arch(char **cmdline_p) /* Set sparc_cpu_model */ sparc_cpu_model = sun_unknown; + if (!strcmp(&cputypval[0], "sun4 ")) + sparc_cpu_model = sun4; + if (!strcmp(&cputypval[0], "sun4c")) + sparc_cpu_model = sun4c; if (!strcmp(&cputypval[0], "sun4m")) sparc_cpu_model = sun4m; if (!strcmp(&cputypval[0], "sun4s")) @@ -277,6 +244,12 @@ void __init setup_arch(char **cmdline_p) printk("ARCH: "); switch(sparc_cpu_model) { + case sun4: + printk("SUN4\n"); + break; + case sun4c: + printk("SUN4C\n"); + break; case sun4m: printk("SUN4M\n"); break; @@ -302,6 +275,8 @@ void __init setup_arch(char **cmdline_p) #endif idprom_init(); + if (ARCH_SUN4C) + sun4c_probe_vac(); load_mmu(); phys_base = 0xffffffffUL; @@ -338,9 +313,6 @@ void __init setup_arch(char **cmdline_p) init_mm.context = (unsigned long) NO_CONTEXT; init_task.thread.kregs = &fake_swapper_regs; - /* Run-time patch instructions to match the cpu model */ - per_cpu_patch(); - paging_init(); smp_setup_cpu_possible_map(); diff --git a/trunk/arch/sparc/kernel/signal_32.c b/trunk/arch/sparc/kernel/signal_32.c index ac8e66b50f07..1e750e415d7a 100644 --- a/trunk/arch/sparc/kernel/signal_32.c +++ b/trunk/arch/sparc/kernel/signal_32.c @@ -217,9 +217,12 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) /* Checks if the fp is valid */ static inline int invalid_frame_pointer(void __user *fp, int fplen) { - if ((((unsigned long) fp) & 7) || !__access_ok((unsigned long)fp, fplen)) + if ((((unsigned long) fp) & 7) || + !__access_ok((unsigned long)fp, fplen) || + ((sparc_cpu_model == sun4 || sparc_cpu_model == sun4c) && + ((unsigned long) fp < 0xe0000000 && (unsigned long) fp >= 0x20000000))) return 1; - + return 0; } diff --git a/trunk/arch/sparc/kernel/smp_32.c b/trunk/arch/sparc/kernel/smp_32.c index 79db45e5134a..f671e7fd6ddc 100644 --- a/trunk/arch/sparc/kernel/smp_32.c +++ b/trunk/arch/sparc/kernel/smp_32.c @@ -40,8 +40,6 @@ volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,}; cpumask_t smp_commenced_mask = CPU_MASK_NONE; -const struct sparc32_ipi_ops *sparc32_ipi_ops; - /* The only guaranteed locking primitive available on all Sparc * processors is 'ldstub [%reg + immediate], %dest_reg' which atomically * places the current byte at the effective address into dest_reg and @@ -87,6 +85,14 @@ void __init smp_cpus_done(unsigned int max_cpus) (bogosum/(5000/HZ))%100); switch(sparc_cpu_model) { + case sun4: + printk("SUN4\n"); + BUG(); + break; + case sun4c: + printk("SUN4C\n"); + BUG(); + break; case sun4m: smp4m_smp_done(); break; @@ -126,7 +132,7 @@ void smp_send_reschedule(int cpu) * a single CPU. The trap handler needs only to do trap entry/return * to call schedule. */ - sparc32_ipi_ops->resched(cpu); + BTFIXUP_CALL(smp_ipi_resched)(cpu); } void smp_send_stop(void) @@ -136,7 +142,7 @@ void smp_send_stop(void) void arch_send_call_function_single_ipi(int cpu) { /* trigger one IPI single call on one CPU */ - sparc32_ipi_ops->single(cpu); + BTFIXUP_CALL(smp_ipi_single)(cpu); } void arch_send_call_function_ipi_mask(const struct cpumask *mask) @@ -145,7 +151,7 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask) /* trigger IPI mask call on each CPU */ for_each_cpu(cpu, mask) - sparc32_ipi_ops->mask_one(cpu); + BTFIXUP_CALL(smp_ipi_mask_one)(cpu); } void smp_resched_interrupt(void) @@ -173,9 +179,150 @@ void smp_call_function_interrupt(void) irq_exit(); } +void smp_flush_cache_all(void) +{ + xc0((smpfunc_t) BTFIXUP_CALL(local_flush_cache_all)); + local_flush_cache_all(); +} + +void smp_flush_tlb_all(void) +{ + xc0((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_all)); + local_flush_tlb_all(); +} + +void smp_flush_cache_mm(struct mm_struct *mm) +{ + if(mm->context != NO_CONTEXT) { + cpumask_t cpu_mask; + cpumask_copy(&cpu_mask, mm_cpumask(mm)); + cpumask_clear_cpu(smp_processor_id(), &cpu_mask); + if (!cpumask_empty(&cpu_mask)) + xc1((smpfunc_t) BTFIXUP_CALL(local_flush_cache_mm), (unsigned long) mm); + local_flush_cache_mm(mm); + } +} + +void smp_flush_tlb_mm(struct mm_struct *mm) +{ + if(mm->context != NO_CONTEXT) { + cpumask_t cpu_mask; + cpumask_copy(&cpu_mask, mm_cpumask(mm)); + cpumask_clear_cpu(smp_processor_id(), &cpu_mask); + if (!cpumask_empty(&cpu_mask)) { + xc1((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_mm), (unsigned long) mm); + if(atomic_read(&mm->mm_users) == 1 && current->active_mm == mm) + cpumask_copy(mm_cpumask(mm), + cpumask_of(smp_processor_id())); + } + local_flush_tlb_mm(mm); + } +} + +void smp_flush_cache_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + + if (mm->context != NO_CONTEXT) { + cpumask_t cpu_mask; + cpumask_copy(&cpu_mask, mm_cpumask(mm)); + cpumask_clear_cpu(smp_processor_id(), &cpu_mask); + if (!cpumask_empty(&cpu_mask)) + xc3((smpfunc_t) BTFIXUP_CALL(local_flush_cache_range), (unsigned long) vma, start, end); + local_flush_cache_range(vma, start, end); + } +} + +void smp_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + + if (mm->context != NO_CONTEXT) { + cpumask_t cpu_mask; + cpumask_copy(&cpu_mask, mm_cpumask(mm)); + cpumask_clear_cpu(smp_processor_id(), &cpu_mask); + if (!cpumask_empty(&cpu_mask)) + xc3((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_range), (unsigned long) vma, start, end); + local_flush_tlb_range(vma, start, end); + } +} + +void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page) +{ + struct mm_struct *mm = vma->vm_mm; + + if(mm->context != NO_CONTEXT) { + cpumask_t cpu_mask; + cpumask_copy(&cpu_mask, mm_cpumask(mm)); + cpumask_clear_cpu(smp_processor_id(), &cpu_mask); + if (!cpumask_empty(&cpu_mask)) + xc2((smpfunc_t) BTFIXUP_CALL(local_flush_cache_page), (unsigned long) vma, page); + local_flush_cache_page(vma, page); + } +} + +void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +{ + struct mm_struct *mm = vma->vm_mm; + + if(mm->context != NO_CONTEXT) { + cpumask_t cpu_mask; + cpumask_copy(&cpu_mask, mm_cpumask(mm)); + cpumask_clear_cpu(smp_processor_id(), &cpu_mask); + if (!cpumask_empty(&cpu_mask)) + xc2((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_page), (unsigned long) vma, page); + local_flush_tlb_page(vma, page); + } +} + +void smp_flush_page_to_ram(unsigned long page) +{ + /* Current theory is that those who call this are the one's + * who have just dirtied their cache with the pages contents + * in kernel space, therefore we only run this on local cpu. + * + * XXX This experiment failed, research further... -DaveM + */ +#if 1 + xc1((smpfunc_t) BTFIXUP_CALL(local_flush_page_to_ram), page); +#endif + local_flush_page_to_ram(page); +} + +void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr) +{ + cpumask_t cpu_mask; + cpumask_copy(&cpu_mask, mm_cpumask(mm)); + cpumask_clear_cpu(smp_processor_id(), &cpu_mask); + if (!cpumask_empty(&cpu_mask)) + xc2((smpfunc_t) BTFIXUP_CALL(local_flush_sig_insns), (unsigned long) mm, insn_addr); + local_flush_sig_insns(mm, insn_addr); +} + +extern unsigned int lvl14_resolution; + +/* /proc/profile writes can call this, don't __init it please. */ +static DEFINE_SPINLOCK(prof_setup_lock); + int setup_profiling_timer(unsigned int multiplier) { - return -EINVAL; + int i; + unsigned long flags; + + /* Prevent level14 ticker IRQ flooding. */ + if((!multiplier) || (lvl14_resolution / multiplier) < 500) + return -EINVAL; + + spin_lock_irqsave(&prof_setup_lock, flags); + for_each_possible_cpu(i) { + load_profile_irq(i, lvl14_resolution / multiplier); + prof_multiplier(i) = multiplier; + } + spin_unlock_irqrestore(&prof_setup_lock, flags); + + return 0; } void __init smp_prepare_cpus(unsigned int max_cpus) @@ -198,6 +345,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus) smp_store_cpu_info(boot_cpu_id); switch(sparc_cpu_model) { + case sun4: + printk("SUN4\n"); + BUG(); + break; + case sun4c: + printk("SUN4C\n"); + BUG(); + break; case sun4m: smp4m_boot_cpus(); break; @@ -256,21 +411,29 @@ void __init smp_prepare_boot_cpu(void) set_cpu_possible(cpuid, true); } -int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) +int __cpuinit __cpu_up(unsigned int cpu) { - extern int __cpuinit smp4m_boot_one_cpu(int, struct task_struct *); - extern int __cpuinit smp4d_boot_one_cpu(int, struct task_struct *); + extern int __cpuinit smp4m_boot_one_cpu(int); + extern int __cpuinit smp4d_boot_one_cpu(int); int ret=0; switch(sparc_cpu_model) { + case sun4: + printk("SUN4\n"); + BUG(); + break; + case sun4c: + printk("SUN4C\n"); + BUG(); + break; case sun4m: - ret = smp4m_boot_one_cpu(cpu, tidle); + ret = smp4m_boot_one_cpu(cpu); break; case sun4d: - ret = smp4d_boot_one_cpu(cpu, tidle); + ret = smp4d_boot_one_cpu(cpu); break; case sparc_leon: - ret = leon_boot_one_cpu(cpu, tidle); + ret = leon_boot_one_cpu(cpu); break; case sun4e: printk("SUN4E\n"); diff --git a/trunk/arch/sparc/kernel/smp_64.c b/trunk/arch/sparc/kernel/smp_64.c index f591598d92f6..3b1bd7c50164 100644 --- a/trunk/arch/sparc/kernel/smp_64.c +++ b/trunk/arch/sparc/kernel/smp_64.c @@ -343,17 +343,21 @@ extern unsigned long sparc64_cpu_startup; */ static struct thread_info *cpu_new_thread = NULL; -static int __cpuinit smp_boot_one_cpu(unsigned int cpu, struct task_struct *idle) +static int __cpuinit smp_boot_one_cpu(unsigned int cpu) { unsigned long entry = (unsigned long)(&sparc64_cpu_startup); unsigned long cookie = (unsigned long)(&cpu_new_thread); + struct task_struct *p; void *descr = NULL; int timeout, ret; + p = fork_idle(cpu); + if (IS_ERR(p)) + return PTR_ERR(p); callin_flag = 0; - cpu_new_thread = task_thread_info(idle); + cpu_new_thread = task_thread_info(p); if (tlb_type == hypervisor) { #if defined(CONFIG_SUN_LDOMS) && defined(CONFIG_HOTPLUG_CPU) @@ -1223,9 +1227,9 @@ void __devinit smp_fill_in_sib_core_maps(void) } } -int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) +int __cpuinit __cpu_up(unsigned int cpu) { - int ret = smp_boot_one_cpu(cpu, tidle); + int ret = smp_boot_one_cpu(cpu); if (!ret) { cpumask_set_cpu(cpu, &smp_commenced_mask); diff --git a/trunk/arch/sparc/kernel/sparc_ksyms_32.c b/trunk/arch/sparc/kernel/sparc_ksyms_32.c index e521c54560f9..baeab8720237 100644 --- a/trunk/arch/sparc/kernel/sparc_ksyms_32.c +++ b/trunk/arch/sparc/kernel/sparc_ksyms_32.c @@ -28,5 +28,19 @@ EXPORT_SYMBOL(__ndelay); EXPORT_SYMBOL(__ret_efault); EXPORT_SYMBOL(empty_zero_page); +/* Defined using magic */ +#ifndef CONFIG_SMP +EXPORT_SYMBOL(BTFIXUP_CALL(___xchg32)); +#else +EXPORT_SYMBOL(BTFIXUP_CALL(__hard_smp_processor_id)); +#endif +EXPORT_SYMBOL(BTFIXUP_CALL(mmu_unlockarea)); +EXPORT_SYMBOL(BTFIXUP_CALL(mmu_lockarea)); +EXPORT_SYMBOL(BTFIXUP_CALL(mmu_get_scsi_sgl)); +EXPORT_SYMBOL(BTFIXUP_CALL(mmu_get_scsi_one)); +EXPORT_SYMBOL(BTFIXUP_CALL(mmu_release_scsi_sgl)); +EXPORT_SYMBOL(BTFIXUP_CALL(mmu_release_scsi_one)); +EXPORT_SYMBOL(BTFIXUP_CALL(pgprot_noncached)); + /* Exporting a symbol from /init/main.c */ EXPORT_SYMBOL(saved_command_line); diff --git a/trunk/arch/sparc/kernel/sun4c_irq.c b/trunk/arch/sparc/kernel/sun4c_irq.c new file mode 100644 index 000000000000..f6bf25a2ff80 --- /dev/null +++ b/trunk/arch/sparc/kernel/sun4c_irq.c @@ -0,0 +1,264 @@ +/* + * sun4c irq support + * + * djhr: Hacked out of irq.c into a CPU dependent version. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) + * Copyright (C) 1995 Pete A. Zaitcev (zaitcev@yahoo.com) + * Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk) + */ + +#include + +#include +#include +#include +#include + +#include "irq.h" + +/* Sun4c interrupts are typically laid out as follows: + * + * 1 - Software interrupt, SBUS level 1 + * 2 - SBUS level 2 + * 3 - ESP SCSI, SBUS level 3 + * 4 - Software interrupt + * 5 - Lance ethernet, SBUS level 4 + * 6 - Software interrupt + * 7 - Graphics card, SBUS level 5 + * 8 - SBUS level 6 + * 9 - SBUS level 7 + * 10 - Counter timer + * 11 - Floppy + * 12 - Zilog uart + * 13 - CS4231 audio + * 14 - Profiling timer + * 15 - NMI + * + * The interrupt enable bits in the interrupt mask register are + * really only used to enable/disable the timer interrupts, and + * for signalling software interrupts. There is also a master + * interrupt enable bit in this register. + * + * Interrupts are enabled by setting the SUN4C_INT_* bits, they + * are disabled by clearing those bits. + */ + +/* + * Bit field defines for the interrupt registers on various + * Sparc machines. + */ + +/* The sun4c interrupt register. */ +#define SUN4C_INT_ENABLE 0x01 /* Allow interrupts. */ +#define SUN4C_INT_E14 0x80 /* Enable level 14 IRQ. */ +#define SUN4C_INT_E10 0x20 /* Enable level 10 IRQ. */ +#define SUN4C_INT_E8 0x10 /* Enable level 8 IRQ. */ +#define SUN4C_INT_E6 0x08 /* Enable level 6 IRQ. */ +#define SUN4C_INT_E4 0x04 /* Enable level 4 IRQ. */ +#define SUN4C_INT_E1 0x02 /* Enable level 1 IRQ. */ + +/* + * Pointer to the interrupt enable byte + * Used by entry.S + */ +unsigned char __iomem *interrupt_enable; + +static void sun4c_mask_irq(struct irq_data *data) +{ + unsigned long mask = (unsigned long)data->chip_data; + + if (mask) { + unsigned long flags; + + local_irq_save(flags); + mask = sbus_readb(interrupt_enable) & ~mask; + sbus_writeb(mask, interrupt_enable); + local_irq_restore(flags); + } +} + +static void sun4c_unmask_irq(struct irq_data *data) +{ + unsigned long mask = (unsigned long)data->chip_data; + + if (mask) { + unsigned long flags; + + local_irq_save(flags); + mask = sbus_readb(interrupt_enable) | mask; + sbus_writeb(mask, interrupt_enable); + local_irq_restore(flags); + } +} + +static unsigned int sun4c_startup_irq(struct irq_data *data) +{ + irq_link(data->irq); + sun4c_unmask_irq(data); + + return 0; +} + +static void sun4c_shutdown_irq(struct irq_data *data) +{ + sun4c_mask_irq(data); + irq_unlink(data->irq); +} + +static struct irq_chip sun4c_irq = { + .name = "sun4c", + .irq_startup = sun4c_startup_irq, + .irq_shutdown = sun4c_shutdown_irq, + .irq_mask = sun4c_mask_irq, + .irq_unmask = sun4c_unmask_irq, +}; + +static unsigned int sun4c_build_device_irq(struct platform_device *op, + unsigned int real_irq) +{ + unsigned int irq; + + if (real_irq >= 16) { + prom_printf("Bogus sun4c IRQ %u\n", real_irq); + prom_halt(); + } + + irq = irq_alloc(real_irq, real_irq); + if (irq) { + unsigned long mask = 0UL; + + switch (real_irq) { + case 1: + mask = SUN4C_INT_E1; + break; + case 8: + mask = SUN4C_INT_E8; + break; + case 10: + mask = SUN4C_INT_E10; + break; + case 14: + mask = SUN4C_INT_E14; + break; + default: + /* All the rest are either always enabled, + * or are for signalling software interrupts. + */ + break; + } + irq_set_chip_and_handler_name(irq, &sun4c_irq, + handle_level_irq, "level"); + irq_set_chip_data(irq, (void *)mask); + } + return irq; +} + +struct sun4c_timer_info { + u32 l10_count; + u32 l10_limit; + u32 l14_count; + u32 l14_limit; +}; + +static struct sun4c_timer_info __iomem *sun4c_timers; + +static void sun4c_clear_clock_irq(void) +{ + sbus_readl(&sun4c_timers->l10_limit); +} + +static void sun4c_load_profile_irq(int cpu, unsigned int limit) +{ + /* Errm.. not sure how to do this.. */ +} + +static void __init sun4c_init_timers(irq_handler_t counter_fn) +{ + const struct linux_prom_irqs *prom_irqs; + struct device_node *dp; + unsigned int irq; + const u32 *addr; + int err; + + dp = of_find_node_by_name(NULL, "counter-timer"); + if (!dp) { + prom_printf("sun4c_init_timers: Unable to find counter-timer\n"); + prom_halt(); + } + + addr = of_get_property(dp, "address", NULL); + if (!addr) { + prom_printf("sun4c_init_timers: No address property\n"); + prom_halt(); + } + + sun4c_timers = (void __iomem *) (unsigned long) addr[0]; + + prom_irqs = of_get_property(dp, "intr", NULL); + of_node_put(dp); + if (!prom_irqs) { + prom_printf("sun4c_init_timers: No intr property\n"); + prom_halt(); + } + + /* Have the level 10 timer tick at 100HZ. We don't touch the + * level 14 timer limit since we are letting the prom handle + * them until we have a real console driver so L1-A works. + */ + sbus_writel((((1000000/HZ) + 1) << 10), &sun4c_timers->l10_limit); + + master_l10_counter = &sun4c_timers->l10_count; + + irq = sun4c_build_device_irq(NULL, prom_irqs[0].pri); + err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL); + if (err) { + prom_printf("sun4c_init_timers: request_irq() fails with %d\n", err); + prom_halt(); + } + + /* disable timer interrupt */ + sun4c_mask_irq(irq_get_irq_data(irq)); +} + +#ifdef CONFIG_SMP +static void sun4c_nop(void) +{ +} +#endif + +void __init sun4c_init_IRQ(void) +{ + struct device_node *dp; + const u32 *addr; + + dp = of_find_node_by_name(NULL, "interrupt-enable"); + if (!dp) { + prom_printf("sun4c_init_IRQ: Unable to find interrupt-enable\n"); + prom_halt(); + } + + addr = of_get_property(dp, "address", NULL); + of_node_put(dp); + if (!addr) { + prom_printf("sun4c_init_IRQ: No address property\n"); + prom_halt(); + } + + interrupt_enable = (void __iomem *) (unsigned long) addr[0]; + + BTFIXUPSET_CALL(clear_clock_irq, sun4c_clear_clock_irq, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(load_profile_irq, sun4c_load_profile_irq, BTFIXUPCALL_NOP); + + sparc_irq_config.init_timers = sun4c_init_timers; + sparc_irq_config.build_device_irq = sun4c_build_device_irq; + +#ifdef CONFIG_SMP + BTFIXUPSET_CALL(set_cpu_int, sun4c_nop, BTFIXUPCALL_NOP); + BTFIXUPSET_CALL(clear_cpu_int, sun4c_nop, BTFIXUPCALL_NOP); + BTFIXUPSET_CALL(set_irq_udt, sun4c_nop, BTFIXUPCALL_NOP); +#endif + sbus_writeb(SUN4C_INT_ENABLE, interrupt_enable); + /* Cannot enable interrupts until OBP ticker is disabled. */ +} diff --git a/trunk/arch/sparc/kernel/sun4d_irq.c b/trunk/arch/sparc/kernel/sun4d_irq.c index e490ac9327c7..1d13c5bda0b1 100644 --- a/trunk/arch/sparc/kernel/sun4d_irq.c +++ b/trunk/arch/sparc/kernel/sun4d_irq.c @@ -15,7 +15,6 @@ #include #include #include -#include #include "kernel.h" #include "irq.h" @@ -244,6 +243,19 @@ struct irq_chip sun4d_irq = { }; #ifdef CONFIG_SMP +static void sun4d_set_cpu_int(int cpu, int level) +{ + sun4d_send_ipi(cpu, level); +} + +static void sun4d_clear_ipi(int cpu, int level) +{ +} + +static void sun4d_set_udt(int cpu) +{ +} + /* Setup IRQ distribution scheme. */ void __init sun4d_distribute_irqs(void) { @@ -270,8 +282,7 @@ static void sun4d_clear_clock_irq(void) static void sun4d_load_profile_irq(int cpu, unsigned int limit) { - unsigned int value = limit ? timer_value(limit) : 0; - bw_set_prof_limit(cpu, value); + bw_set_prof_limit(cpu, limit); } static void __init sun4d_load_profile_irqs(void) @@ -407,12 +418,12 @@ static void __init sun4d_fixup_trap_table(void) trap_table->inst_two = lvl14_save[1]; trap_table->inst_three = lvl14_save[2]; trap_table->inst_four = lvl14_save[3]; - local_ops->cache_all(); + local_flush_cache_all(); local_irq_restore(flags); #endif } -static void __init sun4d_init_timers(void) +static void __init sun4d_init_timers(irq_handler_t counter_fn) { struct device_node *dp; struct resource res; @@ -455,20 +466,12 @@ static void __init sun4d_init_timers(void) prom_halt(); } -#ifdef CONFIG_SMP - sparc_config.cs_period = SBUS_CLOCK_RATE * 2; /* 2 seconds */ -#else - sparc_config.cs_period = SBUS_CLOCK_RATE / HZ; /* 1/HZ sec */ - sparc_config.features |= FEAT_L10_CLOCKEVENT; -#endif - sparc_config.features |= FEAT_L10_CLOCKSOURCE; - sbus_writel(timer_value(sparc_config.cs_period), - &sun4d_timers->l10_timer_limit); + sbus_writel((((1000000/HZ) + 1) << 10), &sun4d_timers->l10_timer_limit); master_l10_counter = &sun4d_timers->l10_cur_count; irq = sun4d_build_timer_irq(board, SUN4D_TIMER_IRQ); - err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL); + err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL); if (err) { prom_printf("sun4d_init_timers: request_irq() failed with %d\n", err); @@ -506,11 +509,16 @@ void __init sun4d_init_IRQ(void) { local_irq_disable(); - sparc_config.init_timers = sun4d_init_timers; - sparc_config.build_device_irq = sun4d_build_device_irq; - sparc_config.clock_rate = SBUS_CLOCK_RATE; - sparc_config.clear_clock_irq = sun4d_clear_clock_irq; - sparc_config.load_profile_irq = sun4d_load_profile_irq; + BTFIXUPSET_CALL(clear_clock_irq, sun4d_clear_clock_irq, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(load_profile_irq, sun4d_load_profile_irq, BTFIXUPCALL_NORM); + sparc_irq_config.init_timers = sun4d_init_timers; + sparc_irq_config.build_device_irq = sun4d_build_device_irq; + +#ifdef CONFIG_SMP + BTFIXUPSET_CALL(set_cpu_int, sun4d_set_cpu_int, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(clear_cpu_int, sun4d_clear_ipi, BTFIXUPCALL_NOP); + BTFIXUPSET_CALL(set_irq_udt, sun4d_set_udt, BTFIXUPCALL_NOP); +#endif /* Cannot enable interrupts until OBP ticker is disabled. */ } diff --git a/trunk/arch/sparc/kernel/sun4d_smp.c b/trunk/arch/sparc/kernel/sun4d_smp.c index ddaea31de586..540b2fec09f0 100644 --- a/trunk/arch/sparc/kernel/sun4d_smp.c +++ b/trunk/arch/sparc/kernel/sun4d_smp.c @@ -6,20 +6,16 @@ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) */ -#include #include #include #include -#include #include -#include -#include -#include -#include -#include #include #include +#include +#include +#include #include "kernel.h" #include "irq.h" @@ -38,6 +34,7 @@ static inline unsigned long sun4d_swap(volatile unsigned long *ptr, unsigned lon } static void smp4d_ipi_init(void); +static void smp_setup_percpu_timer(void); static unsigned char cpu_leds[32]; @@ -52,7 +49,7 @@ static inline void show_leds(int cpuid) void __cpuinit smp4d_callin(void) { - int cpuid = hard_smp_processor_id(); + int cpuid = hard_smp4d_processor_id(); unsigned long flags; /* Show we are alive */ @@ -62,8 +59,8 @@ void __cpuinit smp4d_callin(void) /* Enable level15 interrupt, disable level14 interrupt for now */ cc_set_imsk((cc_get_imsk() & ~0x8000) | 0x4000); - local_ops->cache_all(); - local_ops->tlb_all(); + local_flush_cache_all(); + local_flush_tlb_all(); notify_cpu_starting(cpuid); /* @@ -73,17 +70,17 @@ void __cpuinit smp4d_callin(void) * to call the scheduler code. */ /* Get our local ticker going. */ - register_percpu_ce(cpuid); + smp_setup_percpu_timer(); calibrate_delay(); smp_store_cpu_info(cpuid); - local_ops->cache_all(); - local_ops->tlb_all(); + local_flush_cache_all(); + local_flush_tlb_all(); /* Allow master to continue. */ sun4d_swap((unsigned long *)&cpu_callin_map[cpuid], 1); - local_ops->cache_all(); - local_ops->tlb_all(); + local_flush_cache_all(); + local_flush_tlb_all(); while ((unsigned long)current_set[cpuid] < PAGE_OFFSET) barrier(); @@ -103,8 +100,8 @@ void __cpuinit smp4d_callin(void) atomic_inc(&init_mm.mm_count); current->active_mm = &init_mm; - local_ops->cache_all(); - local_ops->tlb_all(); + local_flush_cache_all(); + local_flush_tlb_all(); local_irq_enable(); /* We don't allow PIL 14 yet */ @@ -126,17 +123,22 @@ void __init smp4d_boot_cpus(void) smp4d_ipi_init(); if (boot_cpu_id) current_set[0] = NULL; - local_ops->cache_all(); + smp_setup_percpu_timer(); + local_flush_cache_all(); } -int __cpuinit smp4d_boot_one_cpu(int i, struct task_struct *idle) +int __cpuinit smp4d_boot_one_cpu(int i) { unsigned long *entry = &sun4d_cpu_startup; + struct task_struct *p; int timeout; int cpu_node; cpu_find_by_instance(i, &cpu_node, NULL); - current_set[i] = task_thread_info(idle); + /* Cook up an idler for this guy. */ + p = fork_idle(i); + current_set[i] = task_thread_info(p); + /* * Initialize the contexts table * Since the call to prom_startcpu() trashes the structure, @@ -148,7 +150,7 @@ int __cpuinit smp4d_boot_one_cpu(int i, struct task_struct *idle) /* whirrr, whirrr, whirrrrrrrrr... */ printk(KERN_INFO "Starting CPU %d at %p\n", i, entry); - local_ops->cache_all(); + local_flush_cache_all(); prom_startcpu(cpu_node, &smp_penguin_ctable, 0, (char *)entry); @@ -166,7 +168,7 @@ int __cpuinit smp4d_boot_one_cpu(int i, struct task_struct *idle) return -ENODEV; } - local_ops->cache_all(); + local_flush_cache_all(); return 0; } @@ -183,7 +185,7 @@ void __init smp4d_smp_done(void) prev = &cpu_data(i).next; } *prev = first; - local_ops->cache_all(); + local_flush_cache_all(); /* Ok, they are spinning and ready to go. */ smp_processors_ready = 1; @@ -231,20 +233,7 @@ void sun4d_ipi_interrupt(void) } } -/* +-------+-------------+-----------+------------------------------------+ - * | bcast | devid | sid | levels mask | - * +-------+-------------+-----------+------------------------------------+ - * 31 30 23 22 15 14 0 - */ -#define IGEN_MESSAGE(bcast, devid, sid, levels) \ - (((bcast) << 31) | ((devid) << 23) | ((sid) << 15) | (levels)) - -static void sun4d_send_ipi(int cpu, int level) -{ - cc_set_igen(IGEN_MESSAGE(0, cpu << 3, 6 + ((level >> 1) & 7), 1 << (level - 1))); -} - -static void sun4d_ipi_single(int cpu) +static void smp4d_ipi_single(int cpu) { struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu); @@ -255,7 +244,7 @@ static void sun4d_ipi_single(int cpu) sun4d_send_ipi(cpu, SUN4D_IPI_IRQ); } -static void sun4d_ipi_mask_one(int cpu) +static void smp4d_ipi_mask_one(int cpu) { struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu); @@ -266,7 +255,7 @@ static void sun4d_ipi_mask_one(int cpu) sun4d_send_ipi(cpu, SUN4D_IPI_IRQ); } -static void sun4d_ipi_resched(int cpu) +static void smp4d_ipi_resched(int cpu) { struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu); @@ -291,7 +280,7 @@ static struct smp_funcall { static DEFINE_SPINLOCK(cross_call_lock); /* Cross calls must be serialized, at least currently. */ -static void sun4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, +static void smp4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4) { @@ -363,7 +352,7 @@ static void sun4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, /* Running cross calls. */ void smp4d_cross_call_irq(void) { - int i = hard_smp_processor_id(); + int i = hard_smp4d_processor_id(); ccall_info.processors_in[i] = 1; ccall_info.func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3, @@ -374,8 +363,7 @@ void smp4d_cross_call_irq(void) void smp4d_percpu_timer_interrupt(struct pt_regs *regs) { struct pt_regs *old_regs; - int cpu = hard_smp_processor_id(); - struct clock_event_device *ce; + int cpu = hard_smp4d_processor_id(); static int cpu_tick[NR_CPUS]; static char led_mask[] = { 0xe, 0xd, 0xb, 0x7, 0xb, 0xd }; @@ -391,21 +379,45 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs) show_leds(cpu); } - ce = &per_cpu(sparc32_clockevent, cpu); + profile_tick(CPU_PROFILING); + + if (!--prof_counter(cpu)) { + int user = user_mode(regs); - irq_enter(); - ce->event_handler(ce); - irq_exit(); + irq_enter(); + update_process_times(user); + irq_exit(); + prof_counter(cpu) = prof_multiplier(cpu); + } set_irq_regs(old_regs); } -static const struct sparc32_ipi_ops sun4d_ipi_ops = { - .cross_call = sun4d_cross_call, - .resched = sun4d_ipi_resched, - .single = sun4d_ipi_single, - .mask_one = sun4d_ipi_mask_one, -}; +static void __cpuinit smp_setup_percpu_timer(void) +{ + int cpu = hard_smp4d_processor_id(); + + prof_counter(cpu) = prof_multiplier(cpu) = 1; + load_profile_irq(cpu, lvl14_resolution); +} + +void __init smp4d_blackbox_id(unsigned *addr) +{ + int rd = *addr & 0x3e000000; + + addr[0] = 0xc0800800 | rd; /* lda [%g0] ASI_M_VIKING_TMP1, reg */ + addr[1] = 0x01000000; /* nop */ + addr[2] = 0x01000000; /* nop */ +} + +void __init smp4d_blackbox_current(unsigned *addr) +{ + int rd = *addr & 0x3e000000; + + addr[0] = 0xc0800800 | rd; /* lda [%g0] ASI_M_VIKING_TMP1, reg */ + addr[2] = 0x81282002 | rd | (rd >> 11); /* sll reg, 2, reg */ + addr[4] = 0x01000000; /* nop */ +} void __init sun4d_init_smp(void) { @@ -414,7 +426,14 @@ void __init sun4d_init_smp(void) /* Patch ipi15 trap table */ t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_sun4d - linux_trap_ipi15_sun4m); - sparc32_ipi_ops = &sun4d_ipi_ops; + /* And set btfixup... */ + BTFIXUPSET_BLACKBOX(hard_smp_processor_id, smp4d_blackbox_id); + BTFIXUPSET_BLACKBOX(load_current, smp4d_blackbox_current); + BTFIXUPSET_CALL(smp_cross_call, smp4d_cross_call, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(__hard_smp_processor_id, __smp4d_processor_id, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(smp_ipi_resched, smp4d_ipi_resched, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(smp_ipi_single, smp4d_ipi_single, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(smp_ipi_mask_one, smp4d_ipi_mask_one, BTFIXUPCALL_NORM); for (i = 0; i < NR_CPUS; i++) { ccall_info.processors_in[i] = 1; diff --git a/trunk/arch/sparc/kernel/sun4m_irq.c b/trunk/arch/sparc/kernel/sun4m_irq.c index c5ade9d27a1d..e61165161dd3 100644 --- a/trunk/arch/sparc/kernel/sun4m_irq.c +++ b/trunk/arch/sparc/kernel/sun4m_irq.c @@ -112,6 +112,9 @@ struct sun4m_handler_data { #define SUN4M_INT_E14 0x00000080 #define SUN4M_INT_E10 0x00080000 +#define SUN4M_HARD_INT(x) (0x000000001 << (x)) +#define SUN4M_SOFT_INT(x) (0x000010000 << (x)) + #define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */ #define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */ #define SUN4M_INT_M2S_WRITE_ERR 0x20000000 /* write buffer error */ @@ -279,6 +282,23 @@ static unsigned int sun4m_build_device_irq(struct platform_device *op, return irq; } +#ifdef CONFIG_SMP +static void sun4m_send_ipi(int cpu, int level) +{ + sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->set); +} + +static void sun4m_clear_ipi(int cpu, int level) +{ + sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->clear); +} + +static void sun4m_set_udt(int cpu) +{ + sbus_writel(cpu, &sun4m_irq_global->interrupt_target); +} +#endif + struct sun4m_timer_percpu { u32 l14_limit; u32 l14_count; @@ -298,6 +318,9 @@ struct sun4m_timer_global { static struct sun4m_timer_global __iomem *timers_global; + +unsigned int lvl14_resolution = (((1000000/HZ) + 1) << 10); + static void sun4m_clear_clock_irq(void) { sbus_readl(&timers_global->l10_limit); @@ -346,11 +369,10 @@ void sun4m_clear_profile_irq(int cpu) static void sun4m_load_profile_irq(int cpu, unsigned int limit) { - unsigned int value = limit ? timer_value(limit) : 0; - sbus_writel(value, &timers_percpu[cpu]->l14_limit); + sbus_writel(limit, &timers_percpu[cpu]->l14_limit); } -static void __init sun4m_init_timers(void) +static void __init sun4m_init_timers(irq_handler_t counter_fn) { struct device_node *dp = of_find_node_by_name(NULL, "counter"); int i, err, len, num_cpu_timers; @@ -380,22 +402,13 @@ static void __init sun4m_init_timers(void) /* Every per-cpu timer works in timer mode */ sbus_writel(0x00000000, &timers_global->timer_config); -#ifdef CONFIG_SMP - sparc_config.cs_period = SBUS_CLOCK_RATE * 2; /* 2 seconds */ - sparc_config.features |= FEAT_L14_ONESHOT; -#else - sparc_config.cs_period = SBUS_CLOCK_RATE / HZ; /* 1/HZ sec */ - sparc_config.features |= FEAT_L10_CLOCKEVENT; -#endif - sparc_config.features |= FEAT_L10_CLOCKSOURCE; - sbus_writel(timer_value(sparc_config.cs_period), - &timers_global->l10_limit); + sbus_writel((((1000000/HZ) + 1) << 10), &timers_global->l10_limit); master_l10_counter = &timers_global->l10_count; irq = sun4m_build_device_irq(NULL, SUN4M_TIMER_IRQ); - err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL); + err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL); if (err) { printk(KERN_ERR "sun4m_init_timers: Register IRQ error %d.\n", err); @@ -421,7 +434,7 @@ static void __init sun4m_init_timers(void) trap_table->inst_two = lvl14_save[1]; trap_table->inst_three = lvl14_save[2]; trap_table->inst_four = lvl14_save[3]; - local_ops->cache_all(); + local_flush_cache_all(); local_irq_restore(flags); } #endif @@ -462,12 +475,17 @@ void __init sun4m_init_IRQ(void) if (num_cpu_iregs == 4) sbus_writel(0, &sun4m_irq_global->interrupt_target); - sparc_config.init_timers = sun4m_init_timers; - sparc_config.build_device_irq = sun4m_build_device_irq; - sparc_config.clock_rate = SBUS_CLOCK_RATE; - sparc_config.clear_clock_irq = sun4m_clear_clock_irq; - sparc_config.load_profile_irq = sun4m_load_profile_irq; + BTFIXUPSET_CALL(clear_clock_irq, sun4m_clear_clock_irq, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(load_profile_irq, sun4m_load_profile_irq, BTFIXUPCALL_NORM); + + sparc_irq_config.init_timers = sun4m_init_timers; + sparc_irq_config.build_device_irq = sun4m_build_device_irq; +#ifdef CONFIG_SMP + BTFIXUPSET_CALL(set_cpu_int, sun4m_send_ipi, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(clear_cpu_int, sun4m_clear_ipi, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(set_irq_udt, sun4m_set_udt, BTFIXUPCALL_NORM); +#endif /* Cannot enable interrupts until OBP ticker is disabled. */ } diff --git a/trunk/arch/sparc/kernel/sun4m_smp.c b/trunk/arch/sparc/kernel/sun4m_smp.c index 128af7304288..02db9a0412ce 100644 --- a/trunk/arch/sparc/kernel/sun4m_smp.c +++ b/trunk/arch/sparc/kernel/sun4m_smp.c @@ -4,18 +4,14 @@ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) */ -#include #include #include #include -#include #include #include #include #include -#include -#include #include "irq.h" #include "kernel.h" @@ -34,22 +30,26 @@ swap_ulong(volatile unsigned long *ptr, unsigned long val) return val; } +static void smp4m_ipi_init(void); +static void smp_setup_percpu_timer(void); + void __cpuinit smp4m_callin(void) { int cpuid = hard_smp_processor_id(); - local_ops->cache_all(); - local_ops->tlb_all(); + local_flush_cache_all(); + local_flush_tlb_all(); notify_cpu_starting(cpuid); - register_percpu_ce(cpuid); + /* Get our local ticker going. */ + smp_setup_percpu_timer(); calibrate_delay(); smp_store_cpu_info(cpuid); - local_ops->cache_all(); - local_ops->tlb_all(); + local_flush_cache_all(); + local_flush_tlb_all(); /* * Unblock the master CPU _only_ when the scheduler state @@ -61,8 +61,8 @@ void __cpuinit smp4m_callin(void) swap_ulong(&cpu_callin_map[cpuid], 1); /* XXX: What's up with all the flushes? */ - local_ops->cache_all(); - local_ops->tlb_all(); + local_flush_cache_all(); + local_flush_tlb_all(); /* Fix idle thread fields. */ __asm__ __volatile__("ld [%0], %%g6\n\t" @@ -86,19 +86,23 @@ void __cpuinit smp4m_callin(void) */ void __init smp4m_boot_cpus(void) { - sun4m_unmask_profile_irq(); - local_ops->cache_all(); + smp4m_ipi_init(); + smp_setup_percpu_timer(); + local_flush_cache_all(); } -int __cpuinit smp4m_boot_one_cpu(int i, struct task_struct *idle) +int __cpuinit smp4m_boot_one_cpu(int i) { unsigned long *entry = &sun4m_cpu_startup; + struct task_struct *p; int timeout; int cpu_node; cpu_find_by_mid(i, &cpu_node); - current_set[i] = task_thread_info(idle); + /* Cook up an idler for this guy. */ + p = fork_idle(i); + current_set[i] = task_thread_info(p); /* See trampoline.S for details... */ entry += ((i - 1) * 3); @@ -113,7 +117,7 @@ int __cpuinit smp4m_boot_one_cpu(int i, struct task_struct *idle) /* whirrr, whirrr, whirrrrrrrrr... */ printk(KERN_INFO "Starting CPU %d at %p\n", i, entry); - local_ops->cache_all(); + local_flush_cache_all(); prom_startcpu(cpu_node, &smp_penguin_ctable, 0, (char *)entry); /* wheee... it's going... */ @@ -128,7 +132,7 @@ int __cpuinit smp4m_boot_one_cpu(int i, struct task_struct *idle) return -ENODEV; } - local_ops->cache_all(); + local_flush_cache_all(); return 0; } @@ -145,29 +149,30 @@ void __init smp4m_smp_done(void) prev = &cpu_data(i).next; } *prev = first; - local_ops->cache_all(); + local_flush_cache_all(); /* Ok, they are spinning and ready to go. */ } -static void sun4m_send_ipi(int cpu, int level) + +/* Initialize IPIs on the SUN4M SMP machine */ +static void __init smp4m_ipi_init(void) { - sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->set); } -static void sun4m_ipi_resched(int cpu) +static void smp4m_ipi_resched(int cpu) { - sun4m_send_ipi(cpu, IRQ_IPI_RESCHED); + set_cpu_int(cpu, IRQ_IPI_RESCHED); } -static void sun4m_ipi_single(int cpu) +static void smp4m_ipi_single(int cpu) { - sun4m_send_ipi(cpu, IRQ_IPI_SINGLE); + set_cpu_int(cpu, IRQ_IPI_SINGLE); } -static void sun4m_ipi_mask_one(int cpu) +static void smp4m_ipi_mask_one(int cpu) { - sun4m_send_ipi(cpu, IRQ_IPI_MASK); + set_cpu_int(cpu, IRQ_IPI_MASK); } static struct smp_funcall { @@ -184,7 +189,7 @@ static struct smp_funcall { static DEFINE_SPINLOCK(cross_call_lock); /* Cross calls must be serialized, at least currently. */ -static void sun4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, +static void smp4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4) { @@ -211,7 +216,7 @@ static void sun4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, if (cpumask_test_cpu(i, &mask)) { ccall_info.processors_in[i] = 0; ccall_info.processors_out[i] = 0; - sun4m_send_ipi(i, IRQ_CROSS_CALL); + set_cpu_int(i, IRQ_CROSS_CALL); } else { ccall_info.processors_in[i] = 1; ccall_info.processors_out[i] = 1; @@ -255,33 +260,64 @@ void smp4m_cross_call_irq(void) void smp4m_percpu_timer_interrupt(struct pt_regs *regs) { struct pt_regs *old_regs; - struct clock_event_device *ce; int cpu = smp_processor_id(); old_regs = set_irq_regs(regs); - ce = &per_cpu(sparc32_clockevent, cpu); + sun4m_clear_profile_irq(cpu); + + profile_tick(CPU_PROFILING); - if (ce->mode & CLOCK_EVT_MODE_PERIODIC) - sun4m_clear_profile_irq(cpu); - else - sparc_config.load_profile_irq(cpu, 0); /* Is this needless? */ + if (!--prof_counter(cpu)) { + int user = user_mode(regs); - irq_enter(); - ce->event_handler(ce); - irq_exit(); + irq_enter(); + update_process_times(user); + irq_exit(); + prof_counter(cpu) = prof_multiplier(cpu); + } set_irq_regs(old_regs); } -static const struct sparc32_ipi_ops sun4m_ipi_ops = { - .cross_call = sun4m_cross_call, - .resched = sun4m_ipi_resched, - .single = sun4m_ipi_single, - .mask_one = sun4m_ipi_mask_one, -}; +static void __cpuinit smp_setup_percpu_timer(void) +{ + int cpu = smp_processor_id(); + + prof_counter(cpu) = prof_multiplier(cpu) = 1; + load_profile_irq(cpu, lvl14_resolution); + + if (cpu == boot_cpu_id) + sun4m_unmask_profile_irq(); +} + +static void __init smp4m_blackbox_id(unsigned *addr) +{ + int rd = *addr & 0x3e000000; + int rs1 = rd >> 11; + + addr[0] = 0x81580000 | rd; /* rd %tbr, reg */ + addr[1] = 0x8130200c | rd | rs1; /* srl reg, 0xc, reg */ + addr[2] = 0x80082003 | rd | rs1; /* and reg, 3, reg */ +} + +static void __init smp4m_blackbox_current(unsigned *addr) +{ + int rd = *addr & 0x3e000000; + int rs1 = rd >> 11; + + addr[0] = 0x81580000 | rd; /* rd %tbr, reg */ + addr[2] = 0x8130200a | rd | rs1; /* srl reg, 0xa, reg */ + addr[4] = 0x8008200c | rd | rs1; /* and reg, 0xc, reg */ +} void __init sun4m_init_smp(void) { - sparc32_ipi_ops = &sun4m_ipi_ops; + BTFIXUPSET_BLACKBOX(hard_smp_processor_id, smp4m_blackbox_id); + BTFIXUPSET_BLACKBOX(load_current, smp4m_blackbox_current); + BTFIXUPSET_CALL(smp_cross_call, smp4m_cross_call, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(__hard_smp_processor_id, __smp4m_processor_id, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(smp_ipi_resched, smp4m_ipi_resched, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(smp_ipi_single, smp4m_ipi_single, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(smp_ipi_mask_one, smp4m_ipi_mask_one, BTFIXUPCALL_NORM); } diff --git a/trunk/arch/sparc/kernel/sys_sparc_32.c b/trunk/arch/sparc/kernel/sys_sparc_32.c index 627e89af1d71..42b282fa6112 100644 --- a/trunk/arch/sparc/kernel/sys_sparc_32.c +++ b/trunk/arch/sparc/kernel/sys_sparc_32.c @@ -53,6 +53,8 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi /* See asm-sparc/uaccess.h */ if (len > TASK_SIZE - PAGE_SIZE) return -ENOMEM; + if (ARCH_SUN4C && len > 0x20000000) + return -ENOMEM; if (!addr) addr = TASK_UNMAPPED_BASE; @@ -63,6 +65,10 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { /* At this point: (!vmm || addr < vmm->vm_end). */ + if (ARCH_SUN4C && addr < 0xe0000000 && 0x20000000 - len < addr) { + addr = PAGE_OFFSET; + vmm = find_vma(current->mm, PAGE_OFFSET); + } if (TASK_SIZE - PAGE_SIZE - len < addr) return -ENOMEM; if (!vmm || addr + len <= vmm->vm_start) @@ -93,6 +99,11 @@ asmlinkage int sparc_pipe(struct pt_regs *regs) int sparc_mmap_check(unsigned long addr, unsigned long len) { + if (ARCH_SUN4C && + (len > 0x20000000 || + (addr < 0xe0000000 && addr + len > 0x20000000))) + return -EINVAL; + /* See asm-sparc/uaccess.h */ if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE) return -EINVAL; diff --git a/trunk/arch/sparc/kernel/systbls_64.S b/trunk/arch/sparc/kernel/systbls_64.S index 3a58e0d66f51..db86b1a0e9a9 100644 --- a/trunk/arch/sparc/kernel/systbls_64.S +++ b/trunk/arch/sparc/kernel/systbls_64.S @@ -74,7 +74,7 @@ sys_call_table32: .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy /*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid -/*280*/ .word sys32_tee, sys_add_key, sys_request_key, compat_sys_keyctl, compat_sys_openat +/*280*/ .word sys32_tee, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_fstatat64 /*290*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare diff --git a/trunk/arch/sparc/kernel/time_32.c b/trunk/arch/sparc/kernel/time_32.c index 953641549e82..7d0c088e8aba 100644 --- a/trunk/arch/sparc/kernel/time_32.c +++ b/trunk/arch/sparc/kernel/time_32.c @@ -26,8 +26,6 @@ #include #include #include -#include -#include #include #include #include @@ -42,24 +40,13 @@ #include #include #include +#include #include #include #include -#include #include "irq.h" -static __cacheline_aligned_in_smp DEFINE_SEQLOCK(timer_cs_lock); -static __volatile__ u64 timer_cs_internal_counter = 0; -static char timer_cs_enabled = 0; - -static struct clock_event_device timer_ce; -static char timer_ce_enabled = 0; - -#ifdef CONFIG_SMP -DEFINE_PER_CPU(struct clock_event_device, sparc32_clockevent); -#endif - DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); @@ -68,6 +55,7 @@ static int set_rtc_mmss(unsigned long); unsigned long profile_pc(struct pt_regs *regs) { extern char __copy_user_begin[], __copy_user_end[]; + extern char __atomic_begin[], __atomic_end[]; extern char __bzero_begin[], __bzero_end[]; unsigned long pc = regs->pc; @@ -75,6 +63,8 @@ unsigned long profile_pc(struct pt_regs *regs) if (in_lock_functions(pc) || (pc >= (unsigned long) __copy_user_begin && pc < (unsigned long) __copy_user_end) || + (pc >= (unsigned long) __atomic_begin && + pc < (unsigned long) __atomic_end) || (pc >= (unsigned long) __bzero_begin && pc < (unsigned long) __bzero_end)) pc = regs->u_regs[UREG_RETPC]; @@ -85,167 +75,35 @@ EXPORT_SYMBOL(profile_pc); __volatile__ unsigned int *master_l10_counter; +u32 (*do_arch_gettimeoffset)(void); + int update_persistent_clock(struct timespec now) { return set_rtc_mmss(now.tv_sec); } -irqreturn_t notrace timer_interrupt(int dummy, void *dev_id) -{ - if (timer_cs_enabled) { - write_seqlock(&timer_cs_lock); - timer_cs_internal_counter++; - sparc_config.clear_clock_irq(); - write_sequnlock(&timer_cs_lock); - } else { - sparc_config.clear_clock_irq(); - } - - if (timer_ce_enabled) - timer_ce.event_handler(&timer_ce); - - return IRQ_HANDLED; -} - -static void timer_ce_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - case CLOCK_EVT_MODE_RESUME: - timer_ce_enabled = 1; - break; - case CLOCK_EVT_MODE_SHUTDOWN: - timer_ce_enabled = 0; - break; - default: - break; - } - smp_mb(); -} - -static __init void setup_timer_ce(void) -{ - struct clock_event_device *ce = &timer_ce; - - BUG_ON(smp_processor_id() != boot_cpu_id); - - ce->name = "timer_ce"; - ce->rating = 100; - ce->features = CLOCK_EVT_FEAT_PERIODIC; - ce->set_mode = timer_ce_set_mode; - ce->cpumask = cpu_possible_mask; - ce->shift = 32; - ce->mult = div_sc(sparc_config.clock_rate, NSEC_PER_SEC, - ce->shift); - clockevents_register_device(ce); -} - -static unsigned int sbus_cycles_offset(void) -{ - unsigned int val, offset; - - val = *master_l10_counter; - offset = (val >> TIMER_VALUE_SHIFT) & TIMER_VALUE_MASK; - - /* Limit hit? */ - if (val & TIMER_LIMIT_BIT) - offset += sparc_config.cs_period; - - return offset; -} - -static cycle_t timer_cs_read(struct clocksource *cs) -{ - unsigned int seq, offset; - u64 cycles; - - do { - seq = read_seqbegin(&timer_cs_lock); - - cycles = timer_cs_internal_counter; - offset = sparc_config.get_cycles_offset(); - } while (read_seqretry(&timer_cs_lock, seq)); - - /* Count absolute cycles */ - cycles *= sparc_config.cs_period; - cycles += offset; - - return cycles; -} - -static struct clocksource timer_cs = { - .name = "timer_cs", - .rating = 100, - .read = timer_cs_read, - .mask = CLOCKSOURCE_MASK(64), - .shift = 2, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static __init int setup_timer_cs(void) -{ - timer_cs_enabled = 1; - timer_cs.mult = clocksource_hz2mult(sparc_config.clock_rate, - timer_cs.shift); +/* + * timer_interrupt() needs to keep up the real-time clock, + * as well as call the "xtime_update()" routine every clocktick + */ - return clocksource_register(&timer_cs); -} +#define TICK_SIZE (tick_nsec / 1000) -#ifdef CONFIG_SMP -static void percpu_ce_setup(enum clock_event_mode mode, - struct clock_event_device *evt) +static irqreturn_t timer_interrupt(int dummy, void *dev_id) { - int cpu = __first_cpu(evt->cpumask); - - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - sparc_config.load_profile_irq(cpu, - SBUS_CLOCK_RATE / HZ); - break; - case CLOCK_EVT_MODE_ONESHOT: - case CLOCK_EVT_MODE_SHUTDOWN: - case CLOCK_EVT_MODE_UNUSED: - sparc_config.load_profile_irq(cpu, 0); - break; - default: - break; - } -} +#ifndef CONFIG_SMP + profile_tick(CPU_PROFILING); +#endif -static int percpu_ce_set_next_event(unsigned long delta, - struct clock_event_device *evt) -{ - int cpu = __first_cpu(evt->cpumask); - unsigned int next = (unsigned int)delta; + clear_clock_irq(); - sparc_config.load_profile_irq(cpu, next); - return 0; -} + xtime_update(1); -void register_percpu_ce(int cpu) -{ - struct clock_event_device *ce = &per_cpu(sparc32_clockevent, cpu); - unsigned int features = CLOCK_EVT_FEAT_PERIODIC; - - if (sparc_config.features & FEAT_L14_ONESHOT) - features |= CLOCK_EVT_FEAT_ONESHOT; - - ce->name = "percpu_ce"; - ce->rating = 200; - ce->features = features; - ce->set_mode = percpu_ce_setup; - ce->set_next_event = percpu_ce_set_next_event; - ce->cpumask = cpumask_of(cpu); - ce->shift = 32; - ce->mult = div_sc(sparc_config.clock_rate, NSEC_PER_SEC, - ce->shift); - ce->max_delta_ns = clockevent_delta2ns(sparc_config.clock_rate, ce); - ce->min_delta_ns = clockevent_delta2ns(100, ce); - - clockevents_register_device(ce); -} +#ifndef CONFIG_SMP + update_process_times(user_mode(get_irq_regs())); #endif + return IRQ_HANDLED; +} static unsigned char mostek_read_byte(struct device *dev, u32 ofs) { @@ -337,28 +195,38 @@ static int __init clock_init(void) */ fs_initcall(clock_init); -static void __init sparc32_late_time_init(void) + +u32 sbus_do_gettimeoffset(void) { - if (sparc_config.features & FEAT_L10_CLOCKEVENT) - setup_timer_ce(); - if (sparc_config.features & FEAT_L10_CLOCKSOURCE) - setup_timer_cs(); -#ifdef CONFIG_SMP - register_percpu_ce(smp_processor_id()); -#endif + unsigned long val = *master_l10_counter; + unsigned long usec = (val >> 10) & 0x1fffff; + + /* Limit hit? */ + if (val & 0x80000000) + usec += 1000000 / HZ; + + return usec * 1000; +} + + +u32 arch_gettimeoffset(void) +{ + if (unlikely(!do_arch_gettimeoffset)) + return 0; + return do_arch_gettimeoffset(); } static void __init sbus_time_init(void) { - sparc_config.get_cycles_offset = sbus_cycles_offset; - sparc_config.init_timers(); + do_arch_gettimeoffset = sbus_do_gettimeoffset; + + btfixup(); + + sparc_irq_config.init_timers(timer_interrupt); } void __init time_init(void) { - sparc_config.features = 0; - late_time_init = sparc32_late_time_init; - if (pcic_present()) pci_time_init(); else diff --git a/trunk/arch/sparc/kernel/trampoline_32.S b/trunk/arch/sparc/kernel/trampoline_32.S index 7364ddc9e5aa..691f484e03b3 100644 --- a/trunk/arch/sparc/kernel/trampoline_32.S +++ b/trunk/arch/sparc/kernel/trampoline_32.S @@ -15,8 +15,8 @@ #include #include - .globl sun4m_cpu_startup - .globl sun4d_cpu_startup + .globl sun4m_cpu_startup, __smp4m_processor_id, __leon_processor_id + .globl sun4d_cpu_startup, __smp4d_processor_id __CPUINIT .align 4 @@ -94,6 +94,24 @@ smp_do_cpu_idle: call cpu_panic nop +__smp4m_processor_id: + rd %tbr, %g2 + srl %g2, 12, %g2 + and %g2, 3, %g2 + retl + mov %g1, %o7 + +__smp4d_processor_id: + lda [%g0] ASI_M_VIKING_TMP1, %g2 + retl + mov %g1, %o7 + +__leon_processor_id: + rd %asr17,%g2 + srl %g2,28,%g2 + retl + mov %g1, %o7 + /* CPUID in bootbus can be found at PA 0xff0140000 */ #define SUN4D_BOOTBUS_CPUID 0xf0140000 diff --git a/trunk/arch/sparc/kernel/traps_32.c b/trunk/arch/sparc/kernel/traps_32.c index a5785ea2a85d..d2de21333146 100644 --- a/trunk/arch/sparc/kernel/traps_32.c +++ b/trunk/arch/sparc/kernel/traps_32.c @@ -120,6 +120,8 @@ void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned lon printk("Ill instr. at pc=%08lx instruction is %08lx\n", regs->pc, *(unsigned long *)regs->pc); #endif + if (!do_user_muldiv (regs, pc)) + return; info.si_signo = SIGILL; info.si_errno = 0; diff --git a/trunk/arch/sparc/kernel/ttable_64.S b/trunk/arch/sparc/kernel/ttable.S similarity index 100% rename from trunk/arch/sparc/kernel/ttable_64.S rename to trunk/arch/sparc/kernel/ttable.S diff --git a/trunk/arch/sparc/kernel/ttable_32.S b/trunk/arch/sparc/kernel/ttable_32.S deleted file mode 100644 index 8a7a96ca676f..000000000000 --- a/trunk/arch/sparc/kernel/ttable_32.S +++ /dev/null @@ -1,417 +0,0 @@ -/* The Sparc trap table, bootloader gives us control at _start. */ - __HEAD - - .globl _start -_start: - - .globl _stext -_stext: - - .globl trapbase -trapbase: - -#ifdef CONFIG_SMP -trapbase_cpu0: -#endif -/* We get control passed to us here at t_zero. */ -t_zero: b gokernel; nop; nop; nop; -t_tflt: SRMMU_TFAULT /* Inst. Access Exception */ -t_bins: TRAP_ENTRY(0x2, bad_instruction) /* Illegal Instruction */ -t_pins: TRAP_ENTRY(0x3, priv_instruction) /* Privileged Instruction */ -t_fpd: TRAP_ENTRY(0x4, fpd_trap_handler) /* Floating Point Disabled */ -t_wovf: WINDOW_SPILL /* Window Overflow */ -t_wunf: WINDOW_FILL /* Window Underflow */ -t_mna: TRAP_ENTRY(0x7, mna_handler) /* Memory Address Not Aligned */ -t_fpe: TRAP_ENTRY(0x8, fpe_trap_handler) /* Floating Point Exception */ -t_dflt: SRMMU_DFAULT /* Data Miss Exception */ -t_tio: TRAP_ENTRY(0xa, do_tag_overflow) /* Tagged Instruction Ovrflw */ -t_wpt: TRAP_ENTRY(0xb, do_watchpoint) /* Watchpoint Detected */ -t_badc: BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10) -t_irq1: TRAP_ENTRY_INTERRUPT(1) /* IRQ Software/SBUS Level 1 */ -t_irq2: TRAP_ENTRY_INTERRUPT(2) /* IRQ SBUS Level 2 */ -t_irq3: TRAP_ENTRY_INTERRUPT(3) /* IRQ SCSI/DMA/SBUS Level 3 */ -t_irq4: TRAP_ENTRY_INTERRUPT(4) /* IRQ Software Level 4 */ -t_irq5: TRAP_ENTRY_INTERRUPT(5) /* IRQ SBUS/Ethernet Level 5 */ -t_irq6: TRAP_ENTRY_INTERRUPT(6) /* IRQ Software Level 6 */ -t_irq7: TRAP_ENTRY_INTERRUPT(7) /* IRQ Video/SBUS Level 5 */ -t_irq8: TRAP_ENTRY_INTERRUPT(8) /* IRQ SBUS Level 6 */ -t_irq9: TRAP_ENTRY_INTERRUPT(9) /* IRQ SBUS Level 7 */ -t_irq10:TRAP_ENTRY_INTERRUPT(10) /* IRQ Timer #1 (one we use) */ -t_irq11:TRAP_ENTRY_INTERRUPT(11) /* IRQ Floppy Intr. */ -t_irq12:TRAP_ENTRY_INTERRUPT(12) /* IRQ Zilog serial chip */ -t_irq13:TRAP_ENTRY_INTERRUPT(13) /* IRQ Audio Intr. */ -t_irq14:TRAP_ENTRY_INTERRUPT(14) /* IRQ Timer #2 */ - - .globl t_nmi -t_nmi: TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m) - -t_racc: TRAP_ENTRY(0x20, do_reg_access) /* General Register Access Error */ -t_iacce:BAD_TRAP(0x21) /* Instr Access Error */ -t_bad22:BAD_TRAP(0x22) - BAD_TRAP(0x23) -t_cpdis:TRAP_ENTRY(0x24, do_cp_disabled) /* Co-Processor Disabled */ -t_uflsh:SKIP_TRAP(0x25, unimp_flush) /* Unimplemented FLUSH inst. */ -t_bad26:BAD_TRAP(0x26) BAD_TRAP(0x27) -t_cpexc:TRAP_ENTRY(0x28, do_cp_exception) /* Co-Processor Exception */ -t_dacce:SRMMU_DFAULT /* Data Access Error */ -t_hwdz: TRAP_ENTRY(0x2a, do_hw_divzero) /* Division by zero, you lose... */ -t_dserr:BAD_TRAP(0x2b) /* Data Store Error */ -t_daccm:BAD_TRAP(0x2c) /* Data Access MMU-Miss */ -t_bad2d:BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31) -t_bad32:BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36) -t_bad37:BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b) -t_iaccm:BAD_TRAP(0x3c) /* Instr Access MMU-Miss */ -t_bad3d:BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40) BAD_TRAP(0x41) -t_bad42:BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45) BAD_TRAP(0x46) -t_bad47:BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) BAD_TRAP(0x4b) -t_bad4c:BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f) BAD_TRAP(0x50) -t_bad51:BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55) -t_bad56:BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a) -t_bad5b:BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f) -t_bad60:BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64) -t_bad65:BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69) -t_bad6a:BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e) -t_bad6f:BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73) -t_bad74:BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) -t_bad79:BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) -t_bad7e:BAD_TRAP(0x7e) BAD_TRAP(0x7f) -t_bad80:BAD_TRAP(0x80) /* SunOS System Call */ -t_sbkpt:BREAKPOINT_TRAP /* Software Breakpoint/KGDB */ -t_divz: TRAP_ENTRY(0x82, do_hw_divzero) /* Divide by zero trap */ -t_flwin:TRAP_ENTRY(0x83, do_flush_windows) /* Flush Windows Trap */ -t_clwin:BAD_TRAP(0x84) /* Clean Windows Trap */ -t_rchk: BAD_TRAP(0x85) /* Range Check */ -t_funal:BAD_TRAP(0x86) /* Fix Unaligned Access Trap */ -t_iovf: BAD_TRAP(0x87) /* Integer Overflow Trap */ -t_bad88:BAD_TRAP(0x88) /* Slowaris System Call */ -t_bad89:BAD_TRAP(0x89) /* Net-B.S. System Call */ -t_bad8a:BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) BAD_TRAP(0x8d) BAD_TRAP(0x8e) -t_bad8f:BAD_TRAP(0x8f) -t_linux:LINUX_SYSCALL_TRAP /* Linux System Call */ -t_bad91:BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) BAD_TRAP(0x95) -t_bad96:BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) BAD_TRAP(0x9a) -t_bad9b:BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) BAD_TRAP(0x9f) -t_getcc:GETCC_TRAP /* Get Condition Codes */ -t_setcc:SETCC_TRAP /* Set Condition Codes */ -t_getpsr:GETPSR_TRAP /* Get PSR Register */ -t_bada3:BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) -t_bada7:BAD_TRAP(0xa7) -t_bada8:BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) -t_badac:BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) -t_badb1:BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) -t_badb6:BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) -t_badbb:BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf) -t_badc0:BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4) -t_badc5:BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9) -t_badca:BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce) -t_badcf:BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3) -t_badd4:BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8) -t_badd9:BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd) -t_badde:BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2) -t_bade3:BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7) -t_bade8:BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec) -t_baded:BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) -t_badf2:BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) -t_badf7:BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) -t_badfc:BAD_TRAP(0xfc) -t_kgdb: KGDB_TRAP(0xfd) -dbtrap: BAD_TRAP(0xfe) /* Debugger/PROM breakpoint #1 */ -dbtrap2:BAD_TRAP(0xff) /* Debugger/PROM breakpoint #2 */ - - .globl end_traptable -end_traptable: - -#ifdef CONFIG_SMP - /* Trap tables for the other cpus. */ - .globl trapbase_cpu1, trapbase_cpu2, trapbase_cpu3 -trapbase_cpu1: - BAD_TRAP(0x0) - SRMMU_TFAULT - TRAP_ENTRY(0x2, bad_instruction) - TRAP_ENTRY(0x3, priv_instruction) - TRAP_ENTRY(0x4, fpd_trap_handler) - WINDOW_SPILL - WINDOW_FILL - TRAP_ENTRY(0x7, mna_handler) - TRAP_ENTRY(0x8, fpe_trap_handler) - SRMMU_DFAULT - TRAP_ENTRY(0xa, do_tag_overflow) - TRAP_ENTRY(0xb, do_watchpoint) - BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10) - TRAP_ENTRY_INTERRUPT(1) TRAP_ENTRY_INTERRUPT(2) - TRAP_ENTRY_INTERRUPT(3) TRAP_ENTRY_INTERRUPT(4) - TRAP_ENTRY_INTERRUPT(5) TRAP_ENTRY_INTERRUPT(6) - TRAP_ENTRY_INTERRUPT(7) TRAP_ENTRY_INTERRUPT(8) - TRAP_ENTRY_INTERRUPT(9) TRAP_ENTRY_INTERRUPT(10) - TRAP_ENTRY_INTERRUPT(11) TRAP_ENTRY_INTERRUPT(12) - TRAP_ENTRY_INTERRUPT(13) TRAP_ENTRY_INTERRUPT(14) - TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m) - TRAP_ENTRY(0x20, do_reg_access) - BAD_TRAP(0x21) - BAD_TRAP(0x22) - BAD_TRAP(0x23) - TRAP_ENTRY(0x24, do_cp_disabled) - SKIP_TRAP(0x25, unimp_flush) - BAD_TRAP(0x26) - BAD_TRAP(0x27) - TRAP_ENTRY(0x28, do_cp_exception) - SRMMU_DFAULT - TRAP_ENTRY(0x2a, do_hw_divzero) - BAD_TRAP(0x2b) - BAD_TRAP(0x2c) - BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31) - BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36) - BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b) - BAD_TRAP(0x3c) BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40) - BAD_TRAP(0x41) BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45) - BAD_TRAP(0x46) BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) - BAD_TRAP(0x4b) BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f) - BAD_TRAP(0x50) - BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55) - BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a) - BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f) - BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64) - BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69) - BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e) - BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73) - BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) - BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) - BAD_TRAP(0x7e) BAD_TRAP(0x7f) - BAD_TRAP(0x80) - BREAKPOINT_TRAP - TRAP_ENTRY(0x82, do_hw_divzero) - TRAP_ENTRY(0x83, do_flush_windows) - BAD_TRAP(0x84) BAD_TRAP(0x85) BAD_TRAP(0x86) - BAD_TRAP(0x87) BAD_TRAP(0x88) BAD_TRAP(0x89) - BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) - BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f) - LINUX_SYSCALL_TRAP BAD_TRAP(0x91) - BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) - BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) - BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) - BAD_TRAP(0x9f) - GETCC_TRAP - SETCC_TRAP - GETPSR_TRAP - BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) - BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) - BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) - BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) - BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) - BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf) - BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4) - BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9) - BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce) - BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3) - BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8) - BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd) - BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2) - BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7) - BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec) - BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) - BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) - BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) - BAD_TRAP(0xfc) - KGDB_TRAP(0xfd) - BAD_TRAP(0xfe) - BAD_TRAP(0xff) - -trapbase_cpu2: - BAD_TRAP(0x0) - SRMMU_TFAULT - TRAP_ENTRY(0x2, bad_instruction) - TRAP_ENTRY(0x3, priv_instruction) - TRAP_ENTRY(0x4, fpd_trap_handler) - WINDOW_SPILL - WINDOW_FILL - TRAP_ENTRY(0x7, mna_handler) - TRAP_ENTRY(0x8, fpe_trap_handler) - SRMMU_DFAULT - TRAP_ENTRY(0xa, do_tag_overflow) - TRAP_ENTRY(0xb, do_watchpoint) - BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10) - TRAP_ENTRY_INTERRUPT(1) - TRAP_ENTRY_INTERRUPT(2) - TRAP_ENTRY_INTERRUPT(3) - TRAP_ENTRY_INTERRUPT(4) - TRAP_ENTRY_INTERRUPT(5) - TRAP_ENTRY_INTERRUPT(6) - TRAP_ENTRY_INTERRUPT(7) - TRAP_ENTRY_INTERRUPT(8) - TRAP_ENTRY_INTERRUPT(9) - TRAP_ENTRY_INTERRUPT(10) - TRAP_ENTRY_INTERRUPT(11) - TRAP_ENTRY_INTERRUPT(12) - TRAP_ENTRY_INTERRUPT(13) - TRAP_ENTRY_INTERRUPT(14) - TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m) - TRAP_ENTRY(0x20, do_reg_access) - BAD_TRAP(0x21) - BAD_TRAP(0x22) - BAD_TRAP(0x23) - TRAP_ENTRY(0x24, do_cp_disabled) - SKIP_TRAP(0x25, unimp_flush) - BAD_TRAP(0x26) - BAD_TRAP(0x27) - TRAP_ENTRY(0x28, do_cp_exception) - SRMMU_DFAULT - TRAP_ENTRY(0x2a, do_hw_divzero) - BAD_TRAP(0x2b) - BAD_TRAP(0x2c) - BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31) - BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36) - BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b) - BAD_TRAP(0x3c) BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40) - BAD_TRAP(0x41) BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45) - BAD_TRAP(0x46) BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) - BAD_TRAP(0x4b) BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f) - BAD_TRAP(0x50) - BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55) - BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a) - BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f) - BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64) - BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69) - BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e) - BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73) - BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) - BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) - BAD_TRAP(0x7e) BAD_TRAP(0x7f) - BAD_TRAP(0x80) - BREAKPOINT_TRAP - TRAP_ENTRY(0x82, do_hw_divzero) - TRAP_ENTRY(0x83, do_flush_windows) - BAD_TRAP(0x84) - BAD_TRAP(0x85) - BAD_TRAP(0x86) BAD_TRAP(0x87) BAD_TRAP(0x88) - BAD_TRAP(0x89) BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) - BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f) - LINUX_SYSCALL_TRAP BAD_TRAP(0x91) - BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) - BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) - BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) - BAD_TRAP(0x9f) - GETCC_TRAP - SETCC_TRAP - GETPSR_TRAP - BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) - BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) - BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) - BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) - BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) - BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf) - BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4) - BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9) - BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce) - BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3) - BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8) - BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd) - BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2) - BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7) - BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec) - BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) - BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) - BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) - BAD_TRAP(0xfc) - KGDB_TRAP(0xfd) - BAD_TRAP(0xfe) - BAD_TRAP(0xff) - -trapbase_cpu3: - BAD_TRAP(0x0) - SRMMU_TFAULT - TRAP_ENTRY(0x2, bad_instruction) - TRAP_ENTRY(0x3, priv_instruction) - TRAP_ENTRY(0x4, fpd_trap_handler) - WINDOW_SPILL - WINDOW_FILL - TRAP_ENTRY(0x7, mna_handler) - TRAP_ENTRY(0x8, fpe_trap_handler) - SRMMU_DFAULT - TRAP_ENTRY(0xa, do_tag_overflow) - TRAP_ENTRY(0xb, do_watchpoint) - BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10) - TRAP_ENTRY_INTERRUPT(1) - TRAP_ENTRY_INTERRUPT(2) - TRAP_ENTRY_INTERRUPT(3) - TRAP_ENTRY_INTERRUPT(4) - TRAP_ENTRY_INTERRUPT(5) - TRAP_ENTRY_INTERRUPT(6) - TRAP_ENTRY_INTERRUPT(7) - TRAP_ENTRY_INTERRUPT(8) - TRAP_ENTRY_INTERRUPT(9) - TRAP_ENTRY_INTERRUPT(10) - TRAP_ENTRY_INTERRUPT(11) - TRAP_ENTRY_INTERRUPT(12) - TRAP_ENTRY_INTERRUPT(13) - TRAP_ENTRY_INTERRUPT(14) - TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m) - TRAP_ENTRY(0x20, do_reg_access) - BAD_TRAP(0x21) - BAD_TRAP(0x22) - BAD_TRAP(0x23) - TRAP_ENTRY(0x24, do_cp_disabled) - SKIP_TRAP(0x25, unimp_flush) - BAD_TRAP(0x26) - BAD_TRAP(0x27) - TRAP_ENTRY(0x28, do_cp_exception) - SRMMU_DFAULT - TRAP_ENTRY(0x2a, do_hw_divzero) - BAD_TRAP(0x2b) BAD_TRAP(0x2c) - BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31) - BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36) - BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b) - BAD_TRAP(0x3c) BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40) - BAD_TRAP(0x41) BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45) - BAD_TRAP(0x46) BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) - BAD_TRAP(0x4b) BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f) - BAD_TRAP(0x50) - BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55) - BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a) - BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f) - BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64) - BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69) - BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e) - BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73) - BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) - BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) - BAD_TRAP(0x7e) BAD_TRAP(0x7f) - BAD_TRAP(0x80) - BREAKPOINT_TRAP - TRAP_ENTRY(0x82, do_hw_divzero) - TRAP_ENTRY(0x83, do_flush_windows) - BAD_TRAP(0x84) BAD_TRAP(0x85) - BAD_TRAP(0x86) BAD_TRAP(0x87) BAD_TRAP(0x88) - BAD_TRAP(0x89) BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) - BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f) - LINUX_SYSCALL_TRAP - BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) - BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) - BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) - BAD_TRAP(0x9f) - GETCC_TRAP - SETCC_TRAP - GETPSR_TRAP - BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) - BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) - BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) - BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) - BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) - BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf) - BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4) - BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9) - BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce) - BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3) - BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8) - BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd) - BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2) - BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7) - BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec) - BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) - BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) - BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) - BAD_TRAP(0xfc) - KGDB_TRAP(0xfd) - BAD_TRAP(0xfe) - BAD_TRAP(0xff) - -#endif diff --git a/trunk/arch/sparc/kernel/unaligned_64.c b/trunk/arch/sparc/kernel/unaligned_64.c index f81d038f7340..dae85bc2eda5 100644 --- a/trunk/arch/sparc/kernel/unaligned_64.c +++ b/trunk/arch/sparc/kernel/unaligned_64.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/sparc/kernel/wof.S b/trunk/arch/sparc/kernel/wof.S index 4c2de3cf309b..3bbcd8dc9abf 100644 --- a/trunk/arch/sparc/kernel/wof.S +++ b/trunk/arch/sparc/kernel/wof.S @@ -163,8 +163,9 @@ spwin_fromuser: * the label 'spwin_user_stack_is_bolixed' which will take * care of things at that point. */ - b spwin_srmmu_stackchk - andcc %sp, 0x7, %g0 + .globl spwin_mmu_patchme +spwin_mmu_patchme: b spwin_sun4c_stackchk + andcc %sp, 0x7, %g0 spwin_good_ustack: /* LOCATION: Window to be saved */ @@ -305,6 +306,73 @@ spwin_bad_ustack_from_kernel: * As noted above %curptr cannot be touched by this routine at all. */ +spwin_sun4c_stackchk: + /* LOCATION: Window to be saved on the stack */ + + /* See if the stack is in the address space hole but first, + * check results of callers andcc %sp, 0x7, %g0 + */ + be 1f + sra %sp, 29, %glob_tmp + + rd %psr, %glob_tmp + b spwin_user_stack_is_bolixed + 0x4 + nop + +1: + add %glob_tmp, 0x1, %glob_tmp + andncc %glob_tmp, 0x1, %g0 + be 1f + and %sp, 0xfff, %glob_tmp ! delay slot + + rd %psr, %glob_tmp + b spwin_user_stack_is_bolixed + 0x4 + nop + + /* See if our dump area will be on more than one + * page. + */ +1: + add %glob_tmp, 0x38, %glob_tmp + andncc %glob_tmp, 0xff8, %g0 + be spwin_sun4c_onepage ! only one page to check + lda [%sp] ASI_PTE, %glob_tmp ! have to check first page anyways + +spwin_sun4c_twopages: + /* Is first page ok permission wise? */ + srl %glob_tmp, 29, %glob_tmp + cmp %glob_tmp, 0x6 + be 1f + add %sp, 0x38, %glob_tmp /* Is second page in vma hole? */ + + rd %psr, %glob_tmp + b spwin_user_stack_is_bolixed + 0x4 + nop + +1: + sra %glob_tmp, 29, %glob_tmp + add %glob_tmp, 0x1, %glob_tmp + andncc %glob_tmp, 0x1, %g0 + be 1f + add %sp, 0x38, %glob_tmp + + rd %psr, %glob_tmp + b spwin_user_stack_is_bolixed + 0x4 + nop + +1: + lda [%glob_tmp] ASI_PTE, %glob_tmp + +spwin_sun4c_onepage: + srl %glob_tmp, 29, %glob_tmp + cmp %glob_tmp, 0x6 ! can user write to it? + be spwin_good_ustack ! success + nop + + rd %psr, %glob_tmp + b spwin_user_stack_is_bolixed + 0x4 + nop + /* This is a generic SRMMU routine. As far as I know this * works for all current v8/srmmu implementations, we'll * see... diff --git a/trunk/arch/sparc/kernel/wuf.S b/trunk/arch/sparc/kernel/wuf.S index 9fde91a249e0..779ff750603d 100644 --- a/trunk/arch/sparc/kernel/wuf.S +++ b/trunk/arch/sparc/kernel/wuf.S @@ -131,9 +131,12 @@ fwin_from_user: /* LOCATION: Window 'W' */ - /* Branch to the stack validation routine */ - b srmmu_fwin_stackchk - andcc %sp, 0x7, %g0 + /* Branch to the architecture specific stack validation + * routine. They can be found below... + */ + .globl fwin_mmu_patchme +fwin_mmu_patchme: b sun4c_fwin_stackchk + andcc %sp, 0x7, %g0 #define STACK_OFFSET (THREAD_SIZE - TRACEREG_SZ - STACKFRAME_SZ) @@ -239,6 +242,57 @@ fwin_user_finish_up: * 'someone elses' window possibly. */ + .align 4 +sun4c_fwin_stackchk: + /* LOCATION: Window 'W' */ + + /* Caller did 'andcc %sp, 0x7, %g0' */ + be 1f + and %sp, 0xfff, %l0 ! delay slot + + b,a fwin_user_stack_is_bolixed + + /* See if we have to check the sanity of one page or two */ +1: + add %l0, 0x38, %l0 + sra %sp, 29, %l5 + add %l5, 0x1, %l5 + andncc %l5, 0x1, %g0 + be 1f + andncc %l0, 0xff8, %g0 + + b,a fwin_user_stack_is_bolixed /* %sp is in vma hole, yuck */ + +1: + be sun4c_fwin_onepage /* Only one page to check */ + lda [%sp] ASI_PTE, %l1 +sun4c_fwin_twopages: + add %sp, 0x38, %l0 + sra %l0, 29, %l5 + add %l5, 0x1, %l5 + andncc %l5, 0x1, %g0 + be 1f + lda [%l0] ASI_PTE, %l1 + + b,a fwin_user_stack_is_bolixed /* Second page in vma hole */ + +1: + srl %l1, 29, %l1 + andcc %l1, 0x4, %g0 + bne sun4c_fwin_onepage + lda [%sp] ASI_PTE, %l1 + + b,a fwin_user_stack_is_bolixed /* Second page has bad perms */ + +sun4c_fwin_onepage: + srl %l1, 29, %l1 + andcc %l1, 0x4, %g0 + bne fwin_user_stack_is_ok + nop + + /* A page had bad page permissions, losing... */ + b,a fwin_user_stack_is_bolixed + .globl srmmu_fwin_stackchk srmmu_fwin_stackchk: /* LOCATION: Window 'W' */ diff --git a/trunk/arch/sparc/lib/Makefile b/trunk/arch/sparc/lib/Makefile index 389628f50a15..a3fc4375a150 100644 --- a/trunk/arch/sparc/lib/Makefile +++ b/trunk/arch/sparc/lib/Makefile @@ -4,7 +4,7 @@ asflags-y := -ansi -DST_DIV0=0x02 ccflags-y := -Werror -lib-$(CONFIG_SPARC32) += ashrdi3.o +lib-$(CONFIG_SPARC32) += mul.o rem.o sdiv.o udiv.o umul.o urem.o ashrdi3.o lib-$(CONFIG_SPARC32) += memcpy.o memset.o lib-y += strlen.o lib-y += checksum_$(BITS).o @@ -13,7 +13,7 @@ lib-y += memscan_$(BITS).o memcmp.o strncmp_$(BITS).o lib-y += strncpy_from_user_$(BITS).o strlen_user_$(BITS).o lib-$(CONFIG_SPARC32) += divdi3.o udivdi3.o lib-$(CONFIG_SPARC32) += copy_user.o locks.o -lib-$(CONFIG_SPARC64) += atomic_64.o +lib-y += atomic_$(BITS).o lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o @@ -40,7 +40,7 @@ lib-$(CONFIG_SPARC64) += copy_in_user.o user_fixup.o memmove.o lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o obj-y += iomap.o -obj-$(CONFIG_SPARC32) += atomic32.o ucmpdi2.o +obj-$(CONFIG_SPARC32) += atomic32.o obj-y += ksyms.o obj-$(CONFIG_SPARC64) += PeeCeeI.o obj-y += usercopy.o diff --git a/trunk/arch/sparc/lib/ashldi3.S b/trunk/arch/sparc/lib/ashldi3.S index 86f60de07b0a..17912e608716 100644 --- a/trunk/arch/sparc/lib/ashldi3.S +++ b/trunk/arch/sparc/lib/ashldi3.S @@ -5,10 +5,10 @@ * Copyright (C) 1999 David S. Miller (davem@redhat.com) */ -#include - .text -ENTRY(__ashldi3) + .align 4 + .globl __ashldi3 +__ashldi3: cmp %o2, 0 be 9f mov 0x20, %g2 @@ -32,4 +32,3 @@ ENTRY(__ashldi3) 9: retl nop -ENDPROC(__ashldi3) diff --git a/trunk/arch/sparc/lib/ashrdi3.S b/trunk/arch/sparc/lib/ashrdi3.S index 6eb8ba2dd50e..85398fd6dcc9 100644 --- a/trunk/arch/sparc/lib/ashrdi3.S +++ b/trunk/arch/sparc/lib/ashrdi3.S @@ -5,10 +5,10 @@ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) */ -#include - .text -ENTRY(__ashrdi3) + .align 4 + .globl __ashrdi3 +__ashrdi3: tst %o2 be 3f or %g0, 32, %g2 @@ -34,4 +34,3 @@ ENTRY(__ashrdi3) 3: jmpl %o7 + 8, %g0 nop -ENDPROC(__ashrdi3) diff --git a/trunk/arch/sparc/lib/atomic_32.S b/trunk/arch/sparc/lib/atomic_32.S new file mode 100644 index 000000000000..eb6c7359cbd1 --- /dev/null +++ b/trunk/arch/sparc/lib/atomic_32.S @@ -0,0 +1,44 @@ +/* atomic.S: Move this stuff here for better ICACHE hit rates. + * + * Copyright (C) 1996 David S. Miller (davem@caipfs.rutgers.edu) + */ + +#include +#include + + .text + .align 4 + + .globl __atomic_begin +__atomic_begin: + +#ifndef CONFIG_SMP + .globl ___xchg32_sun4c +___xchg32_sun4c: + rd %psr, %g3 + andcc %g3, PSR_PIL, %g0 + bne 1f + nop + wr %g3, PSR_PIL, %psr + nop; nop; nop +1: + andcc %g3, PSR_PIL, %g0 + ld [%g1], %g7 + bne 1f + st %g2, [%g1] + wr %g3, 0x0, %psr + nop; nop; nop +1: + mov %g7, %g2 + jmpl %o7 + 8, %g0 + mov %g4, %o7 + + .globl ___xchg32_sun4md +___xchg32_sun4md: + swap [%g1], %g2 + jmpl %o7 + 8, %g0 + mov %g4, %o7 +#endif + + .globl __atomic_end +__atomic_end: diff --git a/trunk/arch/sparc/lib/atomic_64.S b/trunk/arch/sparc/lib/atomic_64.S index 4d502da3de78..59186e0fcf39 100644 --- a/trunk/arch/sparc/lib/atomic_64.S +++ b/trunk/arch/sparc/lib/atomic_64.S @@ -3,7 +3,6 @@ * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) */ -#include #include #include @@ -14,7 +13,9 @@ * memory barriers, and a second which returns * a value and does the barriers. */ -ENTRY(atomic_add) /* %o0 = increment, %o1 = atomic_ptr */ + .globl atomic_add + .type atomic_add,#function +atomic_add: /* %o0 = increment, %o1 = atomic_ptr */ BACKOFF_SETUP(%o2) 1: lduw [%o1], %g1 add %g1, %o0, %g7 @@ -25,9 +26,11 @@ ENTRY(atomic_add) /* %o0 = increment, %o1 = atomic_ptr */ retl nop 2: BACKOFF_SPIN(%o2, %o3, 1b) -ENDPROC(atomic_add) + .size atomic_add, .-atomic_add -ENTRY(atomic_sub) /* %o0 = decrement, %o1 = atomic_ptr */ + .globl atomic_sub + .type atomic_sub,#function +atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */ BACKOFF_SETUP(%o2) 1: lduw [%o1], %g1 sub %g1, %o0, %g7 @@ -38,9 +41,11 @@ ENTRY(atomic_sub) /* %o0 = decrement, %o1 = atomic_ptr */ retl nop 2: BACKOFF_SPIN(%o2, %o3, 1b) -ENDPROC(atomic_sub) + .size atomic_sub, .-atomic_sub -ENTRY(atomic_add_ret) /* %o0 = increment, %o1 = atomic_ptr */ + .globl atomic_add_ret + .type atomic_add_ret,#function +atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ BACKOFF_SETUP(%o2) 1: lduw [%o1], %g1 add %g1, %o0, %g7 @@ -51,9 +56,11 @@ ENTRY(atomic_add_ret) /* %o0 = increment, %o1 = atomic_ptr */ retl sra %g1, 0, %o0 2: BACKOFF_SPIN(%o2, %o3, 1b) -ENDPROC(atomic_add_ret) + .size atomic_add_ret, .-atomic_add_ret -ENTRY(atomic_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */ + .globl atomic_sub_ret + .type atomic_sub_ret,#function +atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ BACKOFF_SETUP(%o2) 1: lduw [%o1], %g1 sub %g1, %o0, %g7 @@ -64,9 +71,11 @@ ENTRY(atomic_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */ retl sra %g1, 0, %o0 2: BACKOFF_SPIN(%o2, %o3, 1b) -ENDPROC(atomic_sub_ret) + .size atomic_sub_ret, .-atomic_sub_ret -ENTRY(atomic64_add) /* %o0 = increment, %o1 = atomic_ptr */ + .globl atomic64_add + .type atomic64_add,#function +atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */ BACKOFF_SETUP(%o2) 1: ldx [%o1], %g1 add %g1, %o0, %g7 @@ -77,9 +86,11 @@ ENTRY(atomic64_add) /* %o0 = increment, %o1 = atomic_ptr */ retl nop 2: BACKOFF_SPIN(%o2, %o3, 1b) -ENDPROC(atomic64_add) + .size atomic64_add, .-atomic64_add -ENTRY(atomic64_sub) /* %o0 = decrement, %o1 = atomic_ptr */ + .globl atomic64_sub + .type atomic64_sub,#function +atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */ BACKOFF_SETUP(%o2) 1: ldx [%o1], %g1 sub %g1, %o0, %g7 @@ -90,9 +101,11 @@ ENTRY(atomic64_sub) /* %o0 = decrement, %o1 = atomic_ptr */ retl nop 2: BACKOFF_SPIN(%o2, %o3, 1b) -ENDPROC(atomic64_sub) + .size atomic64_sub, .-atomic64_sub -ENTRY(atomic64_add_ret) /* %o0 = increment, %o1 = atomic_ptr */ + .globl atomic64_add_ret + .type atomic64_add_ret,#function +atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ BACKOFF_SETUP(%o2) 1: ldx [%o1], %g1 add %g1, %o0, %g7 @@ -103,9 +116,11 @@ ENTRY(atomic64_add_ret) /* %o0 = increment, %o1 = atomic_ptr */ retl add %g1, %o0, %o0 2: BACKOFF_SPIN(%o2, %o3, 1b) -ENDPROC(atomic64_add_ret) + .size atomic64_add_ret, .-atomic64_add_ret -ENTRY(atomic64_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */ + .globl atomic64_sub_ret + .type atomic64_sub_ret,#function +atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ BACKOFF_SETUP(%o2) 1: ldx [%o1], %g1 sub %g1, %o0, %g7 @@ -116,4 +131,4 @@ ENTRY(atomic64_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */ retl sub %g1, %o0, %o0 2: BACKOFF_SPIN(%o2, %o3, 1b) -ENDPROC(atomic64_sub_ret) + .size atomic64_sub_ret, .-atomic64_sub_ret diff --git a/trunk/arch/sparc/lib/bitops.S b/trunk/arch/sparc/lib/bitops.S index 36f72cc0e67e..3dc61d5537c0 100644 --- a/trunk/arch/sparc/lib/bitops.S +++ b/trunk/arch/sparc/lib/bitops.S @@ -3,13 +3,14 @@ * Copyright (C) 2000, 2007 David S. Miller (davem@davemloft.net) */ -#include #include #include .text -ENTRY(test_and_set_bit) /* %o0=nr, %o1=addr */ + .globl test_and_set_bit + .type test_and_set_bit,#function +test_and_set_bit: /* %o0=nr, %o1=addr */ BACKOFF_SETUP(%o3) srlx %o0, 6, %g1 mov 1, %o2 @@ -28,9 +29,11 @@ ENTRY(test_and_set_bit) /* %o0=nr, %o1=addr */ retl nop 2: BACKOFF_SPIN(%o3, %o4, 1b) -ENDPROC(test_and_set_bit) + .size test_and_set_bit, .-test_and_set_bit -ENTRY(test_and_clear_bit) /* %o0=nr, %o1=addr */ + .globl test_and_clear_bit + .type test_and_clear_bit,#function +test_and_clear_bit: /* %o0=nr, %o1=addr */ BACKOFF_SETUP(%o3) srlx %o0, 6, %g1 mov 1, %o2 @@ -49,9 +52,11 @@ ENTRY(test_and_clear_bit) /* %o0=nr, %o1=addr */ retl nop 2: BACKOFF_SPIN(%o3, %o4, 1b) -ENDPROC(test_and_clear_bit) + .size test_and_clear_bit, .-test_and_clear_bit -ENTRY(test_and_change_bit) /* %o0=nr, %o1=addr */ + .globl test_and_change_bit + .type test_and_change_bit,#function +test_and_change_bit: /* %o0=nr, %o1=addr */ BACKOFF_SETUP(%o3) srlx %o0, 6, %g1 mov 1, %o2 @@ -70,9 +75,11 @@ ENTRY(test_and_change_bit) /* %o0=nr, %o1=addr */ retl nop 2: BACKOFF_SPIN(%o3, %o4, 1b) -ENDPROC(test_and_change_bit) + .size test_and_change_bit, .-test_and_change_bit -ENTRY(set_bit) /* %o0=nr, %o1=addr */ + .globl set_bit + .type set_bit,#function +set_bit: /* %o0=nr, %o1=addr */ BACKOFF_SETUP(%o3) srlx %o0, 6, %g1 mov 1, %o2 @@ -89,9 +96,11 @@ ENTRY(set_bit) /* %o0=nr, %o1=addr */ retl nop 2: BACKOFF_SPIN(%o3, %o4, 1b) -ENDPROC(set_bit) + .size set_bit, .-set_bit -ENTRY(clear_bit) /* %o0=nr, %o1=addr */ + .globl clear_bit + .type clear_bit,#function +clear_bit: /* %o0=nr, %o1=addr */ BACKOFF_SETUP(%o3) srlx %o0, 6, %g1 mov 1, %o2 @@ -108,9 +117,11 @@ ENTRY(clear_bit) /* %o0=nr, %o1=addr */ retl nop 2: BACKOFF_SPIN(%o3, %o4, 1b) -ENDPROC(clear_bit) + .size clear_bit, .-clear_bit -ENTRY(change_bit) /* %o0=nr, %o1=addr */ + .globl change_bit + .type change_bit,#function +change_bit: /* %o0=nr, %o1=addr */ BACKOFF_SETUP(%o3) srlx %o0, 6, %g1 mov 1, %o2 @@ -127,4 +138,4 @@ ENTRY(change_bit) /* %o0=nr, %o1=addr */ retl nop 2: BACKOFF_SPIN(%o3, %o4, 1b) -ENDPROC(change_bit) + .size change_bit, .-change_bit diff --git a/trunk/arch/sparc/lib/blockops.S b/trunk/arch/sparc/lib/blockops.S index 3c771011ff4b..804be87f9a42 100644 --- a/trunk/arch/sparc/lib/blockops.S +++ b/trunk/arch/sparc/lib/blockops.S @@ -4,7 +4,6 @@ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) */ -#include #include /* Zero out 64 bytes of memory at (buf + offset). @@ -45,7 +44,10 @@ */ .text -ENTRY(bzero_1page) + .align 4 + .globl bzero_1page, __copy_1page + +bzero_1page: /* NOTE: If you change the number of insns of this routine, please check * arch/sparc/mm/hypersparc.S */ /* %o0 = buf */ @@ -63,9 +65,8 @@ ENTRY(bzero_1page) retl nop -ENDPROC(bzero_1page) -ENTRY(__copy_1page) +__copy_1page: /* NOTE: If you change the number of insns of this routine, please check * arch/sparc/mm/hypersparc.S */ /* %o0 = dst, %o1 = src */ @@ -86,4 +87,3 @@ ENTRY(__copy_1page) retl nop -ENDPROC(__copy_1page) diff --git a/trunk/arch/sparc/lib/bzero.S b/trunk/arch/sparc/lib/bzero.S index 8c058114b649..615f401edf69 100644 --- a/trunk/arch/sparc/lib/bzero.S +++ b/trunk/arch/sparc/lib/bzero.S @@ -4,11 +4,11 @@ * Copyright (C) 2005 David S. Miller */ -#include - .text -ENTRY(memset) /* %o0=buf, %o1=pat, %o2=len */ + .globl memset + .type memset, #function +memset: /* %o0=buf, %o1=pat, %o2=len */ and %o1, 0xff, %o3 mov %o2, %o1 sllx %o3, 8, %g1 @@ -19,7 +19,9 @@ ENTRY(memset) /* %o0=buf, %o1=pat, %o2=len */ ba,pt %xcc, 1f or %g1, %o2, %o2 -ENTRY(__bzero) /* %o0=buf, %o1=len */ + .globl __bzero + .type __bzero, #function +__bzero: /* %o0=buf, %o1=len */ clr %o2 1: mov %o0, %o3 brz,pn %o1, __bzero_done @@ -76,8 +78,8 @@ __bzero_tiny: __bzero_done: retl mov %o3, %o0 -ENDPROC(__bzero) -ENDPROC(memset) + .size __bzero, .-__bzero + .size memset, .-memset #define EX_ST(x,y) \ 98: x,y; \ @@ -87,7 +89,9 @@ ENDPROC(memset) .text; \ .align 4; -ENTRY(__clear_user) /* %o0=buf, %o1=len */ + .globl __clear_user + .type __clear_user, #function +__clear_user: /* %o0=buf, %o1=len */ brz,pn %o1, __clear_user_done cmp %o1, 16 bl,pn %icc, __clear_user_tiny @@ -142,4 +146,4 @@ __clear_user_tiny: __clear_user_done: retl clr %o0 -ENDPROC(__clear_user) + .size __clear_user, .-__clear_user diff --git a/trunk/arch/sparc/lib/divdi3.S b/trunk/arch/sparc/lib/divdi3.S index 9614b48b6ef8..d74bc0925f2d 100644 --- a/trunk/arch/sparc/lib/divdi3.S +++ b/trunk/arch/sparc/lib/divdi3.S @@ -19,6 +19,7 @@ Boston, MA 02111-1307, USA. */ .text .align 4 + .global .udiv .globl __divdi3 __divdi3: save %sp,-104,%sp @@ -82,9 +83,8 @@ __divdi3: bne .LL85 mov %i0,%o2 mov 1,%o0 + call .udiv,0 mov 0,%o1 - wr %g0, 0, %y - udiv %o0, %o1, %o0 mov %o0,%o4 mov %i0,%o2 .LL85: diff --git a/trunk/arch/sparc/lib/ipcsum.S b/trunk/arch/sparc/lib/ipcsum.S index 4742d59029ee..58ca5b9a8778 100644 --- a/trunk/arch/sparc/lib/ipcsum.S +++ b/trunk/arch/sparc/lib/ipcsum.S @@ -1,7 +1,8 @@ -#include - .text -ENTRY(ip_fast_csum) /* %o0 = iph, %o1 = ihl */ + .align 32 + .globl ip_fast_csum + .type ip_fast_csum,#function +ip_fast_csum: /* %o0 = iph, %o1 = ihl */ sub %o1, 4, %g7 lduw [%o0 + 0x00], %o2 lduw [%o0 + 0x04], %g2 @@ -30,4 +31,4 @@ ENTRY(ip_fast_csum) /* %o0 = iph, %o1 = ihl */ set 0xffff, %o1 retl and %o2, %o1, %o0 -ENDPROC(ip_fast_csum) + .size ip_fast_csum, .-ip_fast_csum diff --git a/trunk/arch/sparc/lib/ksyms.c b/trunk/arch/sparc/lib/ksyms.c index 2dc30875c8bc..f73c2240fe60 100644 --- a/trunk/arch/sparc/lib/ksyms.c +++ b/trunk/arch/sparc/lib/ksyms.c @@ -56,11 +56,23 @@ extern int __divdi3(int, int); extern void (*__copy_1page)(void *, const void *); extern void (*bzero_1page)(void *); +extern int __strncmp(const char *, const char *, __kernel_size_t); + extern void ___rw_read_enter(void); extern void ___rw_read_try(void); extern void ___rw_read_exit(void); extern void ___rw_write_enter(void); +/* Alias functions whose names begin with "." and export the aliases. + * The module references will be fixed up by module_frob_arch_sections. + */ +extern int _Div(int, int); +extern int _Mul(int, int); +extern int _Rem(int, int); +extern unsigned _Udiv(unsigned, unsigned); +extern unsigned _Umul(unsigned, unsigned); +extern unsigned _Urem(unsigned, unsigned); + /* Networking helper routines. */ EXPORT_SYMBOL(__csum_partial_copy_sparc_generic); @@ -69,6 +81,9 @@ EXPORT_SYMBOL(__copy_1page); EXPORT_SYMBOL(__memmove); EXPORT_SYMBOL(bzero_1page); +/* string functions */ +EXPORT_SYMBOL(__strncmp); + /* Moving data to/from/in userspace. */ EXPORT_SYMBOL(__copy_user); @@ -85,6 +100,13 @@ EXPORT_SYMBOL(__ashldi3); EXPORT_SYMBOL(__lshrdi3); EXPORT_SYMBOL(__muldi3); EXPORT_SYMBOL(__divdi3); + +EXPORT_SYMBOL(_Rem); +EXPORT_SYMBOL(_Urem); +EXPORT_SYMBOL(_Mul); +EXPORT_SYMBOL(_Umul); +EXPORT_SYMBOL(_Div); +EXPORT_SYMBOL(_Udiv); #endif /* diff --git a/trunk/arch/sparc/lib/lshrdi3.S b/trunk/arch/sparc/lib/lshrdi3.S index 60ebc7cdbee0..47a1354c1602 100644 --- a/trunk/arch/sparc/lib/lshrdi3.S +++ b/trunk/arch/sparc/lib/lshrdi3.S @@ -1,6 +1,6 @@ -#include -ENTRY(__lshrdi3) + .globl __lshrdi3 +__lshrdi3: cmp %o2, 0 be 3f mov 0x20, %g2 @@ -24,4 +24,3 @@ ENTRY(__lshrdi3) 3: retl nop -ENDPROC(__lshrdi3) diff --git a/trunk/arch/sparc/lib/memmove.S b/trunk/arch/sparc/lib/memmove.S index b7f6334e159f..97395802c23c 100644 --- a/trunk/arch/sparc/lib/memmove.S +++ b/trunk/arch/sparc/lib/memmove.S @@ -4,10 +4,11 @@ * Copyright (C) 1996, 1997, 1998, 1999 Jakub Jelinek (jj@ultra.linux.cz) */ -#include - .text -ENTRY(memmove) /* o0=dst o1=src o2=len */ + .align 32 + .globl memmove + .type memmove,#function +memmove: /* o0=dst o1=src o2=len */ mov %o0, %g1 cmp %o0, %o1 bleu,pt %xcc, memcpy @@ -27,4 +28,4 @@ ENTRY(memmove) /* o0=dst o1=src o2=len */ retl mov %g1, %o0 -ENDPROC(memmove) + .size memmove, .-memmove diff --git a/trunk/arch/sparc/lib/mul.S b/trunk/arch/sparc/lib/mul.S new file mode 100644 index 000000000000..c45470d0b0ce --- /dev/null +++ b/trunk/arch/sparc/lib/mul.S @@ -0,0 +1,137 @@ +/* + * mul.S: This routine was taken from glibc-1.09 and is covered + * by the GNU Library General Public License Version 2. + */ + +/* + * Signed multiply, from Appendix E of the Sparc Version 8 + * Architecture Manual. + */ + +/* + * Returns %o0 * %o1 in %o1%o0 (i.e., %o1 holds the upper 32 bits of + * the 64-bit product). + * + * This code optimizes short (less than 13-bit) multiplies. + */ + + .globl .mul + .globl _Mul +.mul: +_Mul: /* needed for export */ + mov %o0, %y ! multiplier -> Y + andncc %o0, 0xfff, %g0 ! test bits 12..31 + be Lmul_shortway ! if zero, can do it the short way + andcc %g0, %g0, %o4 ! zero the partial product and clear N and V + + /* + * Long multiply. 32 steps, followed by a final shift step. + */ + mulscc %o4, %o1, %o4 ! 1 + mulscc %o4, %o1, %o4 ! 2 + mulscc %o4, %o1, %o4 ! 3 + mulscc %o4, %o1, %o4 ! 4 + mulscc %o4, %o1, %o4 ! 5 + mulscc %o4, %o1, %o4 ! 6 + mulscc %o4, %o1, %o4 ! 7 + mulscc %o4, %o1, %o4 ! 8 + mulscc %o4, %o1, %o4 ! 9 + mulscc %o4, %o1, %o4 ! 10 + mulscc %o4, %o1, %o4 ! 11 + mulscc %o4, %o1, %o4 ! 12 + mulscc %o4, %o1, %o4 ! 13 + mulscc %o4, %o1, %o4 ! 14 + mulscc %o4, %o1, %o4 ! 15 + mulscc %o4, %o1, %o4 ! 16 + mulscc %o4, %o1, %o4 ! 17 + mulscc %o4, %o1, %o4 ! 18 + mulscc %o4, %o1, %o4 ! 19 + mulscc %o4, %o1, %o4 ! 20 + mulscc %o4, %o1, %o4 ! 21 + mulscc %o4, %o1, %o4 ! 22 + mulscc %o4, %o1, %o4 ! 23 + mulscc %o4, %o1, %o4 ! 24 + mulscc %o4, %o1, %o4 ! 25 + mulscc %o4, %o1, %o4 ! 26 + mulscc %o4, %o1, %o4 ! 27 + mulscc %o4, %o1, %o4 ! 28 + mulscc %o4, %o1, %o4 ! 29 + mulscc %o4, %o1, %o4 ! 30 + mulscc %o4, %o1, %o4 ! 31 + mulscc %o4, %o1, %o4 ! 32 + mulscc %o4, %g0, %o4 ! final shift + + ! If %o0 was negative, the result is + ! (%o0 * %o1) + (%o1 << 32)) + ! We fix that here. + +#if 0 + tst %o0 + bge 1f + rd %y, %o0 + + ! %o0 was indeed negative; fix upper 32 bits of result by subtracting + ! %o1 (i.e., return %o4 - %o1 in %o1). + retl + sub %o4, %o1, %o1 + +1: + retl + mov %o4, %o1 +#else + /* Faster code adapted from tege@sics.se's code for umul.S. */ + sra %o0, 31, %o2 ! make mask from sign bit + and %o1, %o2, %o2 ! %o2 = 0 or %o1, depending on sign of %o0 + rd %y, %o0 ! get lower half of product + retl + sub %o4, %o2, %o1 ! subtract compensation + ! and put upper half in place +#endif + +Lmul_shortway: + /* + * Short multiply. 12 steps, followed by a final shift step. + * The resulting bits are off by 12 and (32-12) = 20 bit positions, + * but there is no problem with %o0 being negative (unlike above). + */ + mulscc %o4, %o1, %o4 ! 1 + mulscc %o4, %o1, %o4 ! 2 + mulscc %o4, %o1, %o4 ! 3 + mulscc %o4, %o1, %o4 ! 4 + mulscc %o4, %o1, %o4 ! 5 + mulscc %o4, %o1, %o4 ! 6 + mulscc %o4, %o1, %o4 ! 7 + mulscc %o4, %o1, %o4 ! 8 + mulscc %o4, %o1, %o4 ! 9 + mulscc %o4, %o1, %o4 ! 10 + mulscc %o4, %o1, %o4 ! 11 + mulscc %o4, %o1, %o4 ! 12 + mulscc %o4, %g0, %o4 ! final shift + + /* + * %o4 has 20 of the bits that should be in the low part of the + * result; %y has the bottom 12 (as %y's top 12). That is: + * + * %o4 %y + * +----------------+----------------+ + * | -12- | -20- | -12- | -20- | + * +------(---------+------)---------+ + * --hi-- ----low-part---- + * + * The upper 12 bits of %o4 should be sign-extended to form the + * high part of the product (i.e., highpart = %o4 >> 20). + */ + + rd %y, %o5 + sll %o4, 12, %o0 ! shift middle bits left 12 + srl %o5, 20, %o5 ! shift low bits right 20, zero fill at left + or %o5, %o0, %o0 ! construct low part of result + retl + sra %o4, 20, %o1 ! ... and extract high part of result + + .globl .mul_patch +.mul_patch: + smul %o0, %o1, %o0 + retl + rd %y, %o1 + nop diff --git a/trunk/arch/sparc/lib/muldi3.S b/trunk/arch/sparc/lib/muldi3.S index 9794939d1c12..7f17872d0603 100644 --- a/trunk/arch/sparc/lib/muldi3.S +++ b/trunk/arch/sparc/lib/muldi3.S @@ -63,12 +63,12 @@ __muldi3: rd %y, %o1 mov %o1, %l3 mov %i1, %o0 + call .umul mov %i2, %o1 - umul %o0, %o1, %o0 mov %o0, %l0 mov %i0, %o0 + call .umul mov %i3, %o1 - umul %o0, %o1, %o0 add %l0, %o0, %l0 mov %l2, %i0 add %l2, %l0, %i0 diff --git a/trunk/arch/sparc/lib/rem.S b/trunk/arch/sparc/lib/rem.S new file mode 100644 index 000000000000..42fb86252815 --- /dev/null +++ b/trunk/arch/sparc/lib/rem.S @@ -0,0 +1,384 @@ +/* + * rem.S: This routine was taken from glibc-1.09 and is covered + * by the GNU Library General Public License Version 2. + */ + + +/* This file is generated from divrem.m4; DO NOT EDIT! */ +/* + * Division and remainder, from Appendix E of the Sparc Version 8 + * Architecture Manual, with fixes from Gordon Irlam. + */ + +/* + * Input: dividend and divisor in %o0 and %o1 respectively. + * + * m4 parameters: + * .rem name of function to generate + * rem rem=div => %o0 / %o1; rem=rem => %o0 % %o1 + * true true=true => signed; true=false => unsigned + * + * Algorithm parameters: + * N how many bits per iteration we try to get (4) + * WORDSIZE total number of bits (32) + * + * Derived constants: + * TOPBITS number of bits in the top decade of a number + * + * Important variables: + * Q the partial quotient under development (initially 0) + * R the remainder so far, initially the dividend + * ITER number of main division loop iterations required; + * equal to ceil(log2(quotient) / N). Note that this + * is the log base (2^N) of the quotient. + * V the current comparand, initially divisor*2^(ITER*N-1) + * + * Cost: + * Current estimate for non-large dividend is + * ceil(log2(quotient) / N) * (10 + 7N/2) + C + * A large dividend is one greater than 2^(31-TOPBITS) and takes a + * different path, as the upper bits of the quotient must be developed + * one bit at a time. + */ + + + .globl .rem + .globl _Rem +.rem: +_Rem: /* needed for export */ + ! compute sign of result; if neither is negative, no problem + orcc %o1, %o0, %g0 ! either negative? + bge 2f ! no, go do the divide + mov %o0, %g2 ! compute sign in any case + + tst %o1 + bge 1f + tst %o0 + ! %o1 is definitely negative; %o0 might also be negative + bge 2f ! if %o0 not negative... + sub %g0, %o1, %o1 ! in any case, make %o1 nonneg +1: ! %o0 is negative, %o1 is nonnegative + sub %g0, %o0, %o0 ! make %o0 nonnegative +2: + + ! Ready to divide. Compute size of quotient; scale comparand. + orcc %o1, %g0, %o5 + bne 1f + mov %o0, %o3 + + ! Divide by zero trap. If it returns, return 0 (about as + ! wrong as possible, but that is what SunOS does...). + ta ST_DIV0 + retl + clr %o0 + +1: + cmp %o3, %o5 ! if %o1 exceeds %o0, done + blu Lgot_result ! (and algorithm fails otherwise) + clr %o2 + + sethi %hi(1 << (32 - 4 - 1)), %g1 + + cmp %o3, %g1 + blu Lnot_really_big + clr %o4 + + ! Here the dividend is >= 2**(31-N) or so. We must be careful here, + ! as our usual N-at-a-shot divide step will cause overflow and havoc. + ! The number of bits in the result here is N*ITER+SC, where SC <= N. + ! Compute ITER in an unorthodox manner: know we need to shift V into + ! the top decade: so do not even bother to compare to R. + 1: + cmp %o5, %g1 + bgeu 3f + mov 1, %g7 + + sll %o5, 4, %o5 + + b 1b + add %o4, 1, %o4 + + ! Now compute %g7. + 2: + addcc %o5, %o5, %o5 + + bcc Lnot_too_big + add %g7, 1, %g7 + + ! We get here if the %o1 overflowed while shifting. + ! This means that %o3 has the high-order bit set. + ! Restore %o5 and subtract from %o3. + sll %g1, 4, %g1 ! high order bit + srl %o5, 1, %o5 ! rest of %o5 + add %o5, %g1, %o5 + + b Ldo_single_div + sub %g7, 1, %g7 + + Lnot_too_big: + 3: + cmp %o5, %o3 + blu 2b + nop + + be Ldo_single_div + nop + /* NB: these are commented out in the V8-Sparc manual as well */ + /* (I do not understand this) */ + ! %o5 > %o3: went too far: back up 1 step + ! srl %o5, 1, %o5 + ! dec %g7 + ! do single-bit divide steps + ! + ! We have to be careful here. We know that %o3 >= %o5, so we can do the + ! first divide step without thinking. BUT, the others are conditional, + ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high- + ! order bit set in the first step, just falling into the regular + ! division loop will mess up the first time around. + ! So we unroll slightly... + Ldo_single_div: + subcc %g7, 1, %g7 + bl Lend_regular_divide + nop + + sub %o3, %o5, %o3 + mov 1, %o2 + + b Lend_single_divloop + nop + Lsingle_divloop: + sll %o2, 1, %o2 + + bl 1f + srl %o5, 1, %o5 + ! %o3 >= 0 + sub %o3, %o5, %o3 + + b 2f + add %o2, 1, %o2 + 1: ! %o3 < 0 + add %o3, %o5, %o3 + sub %o2, 1, %o2 + 2: + Lend_single_divloop: + subcc %g7, 1, %g7 + bge Lsingle_divloop + tst %o3 + + b,a Lend_regular_divide + +Lnot_really_big: +1: + sll %o5, 4, %o5 + cmp %o5, %o3 + bleu 1b + addcc %o4, 1, %o4 + be Lgot_result + sub %o4, 1, %o4 + + tst %o3 ! set up for initial iteration +Ldivloop: + sll %o2, 4, %o2 + ! depth 1, accumulated bits 0 + bl L.1.16 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 2, accumulated bits 1 + bl L.2.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits 3 + bl L.3.19 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 7 + bl L.4.23 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + + b 9f + add %o2, (7*2+1), %o2 + +L.4.23: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (7*2-1), %o2 + +L.3.19: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 5 + bl L.4.21 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (5*2+1), %o2 + +L.4.21: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (5*2-1), %o2 + +L.2.17: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits 1 + bl L.3.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 3 + bl L.4.19 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (3*2+1), %o2 + +L.4.19: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (3*2-1), %o2 + +L.3.17: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 1 + bl L.4.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (1*2+1), %o2 + +L.4.17: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (1*2-1), %o2 + +L.1.16: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 2, accumulated bits -1 + bl L.2.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits -1 + bl L.3.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -1 + bl L.4.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2+1), %o2 + +L.4.15: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2-1), %o2 + +L.3.15: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -3 + bl L.4.13 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2+1), %o2 + +L.4.13: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2-1), %o2 + +L.2.15: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits -3 + bl L.3.13 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -5 + bl L.4.11 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2+1), %o2 + +L.4.11: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2-1), %o2 + + +L.3.13: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -7 + bl L.4.9 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2+1), %o2 + +L.4.9: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2-1), %o2 + + 9: +Lend_regular_divide: + subcc %o4, 1, %o4 + bge Ldivloop + tst %o3 + + bl,a Lgot_result + ! non-restoring fixup here (one instruction only!) + add %o3, %o1, %o3 + +Lgot_result: + ! check to see if answer should be < 0 + tst %g2 + bl,a 1f + sub %g0, %o3, %o3 +1: + retl + mov %o3, %o0 + + .globl .rem_patch +.rem_patch: + sra %o0, 0x1f, %o4 + wr %o4, 0x0, %y + nop + nop + nop + sdivcc %o0, %o1, %o2 + bvs,a 1f + xnor %o2, %g0, %o2 +1: smul %o2, %o1, %o2 + retl + sub %o0, %o2, %o0 + nop diff --git a/trunk/arch/sparc/lib/sdiv.S b/trunk/arch/sparc/lib/sdiv.S new file mode 100644 index 000000000000..f0a0d4e4db78 --- /dev/null +++ b/trunk/arch/sparc/lib/sdiv.S @@ -0,0 +1,381 @@ +/* + * sdiv.S: This routine was taken from glibc-1.09 and is covered + * by the GNU Library General Public License Version 2. + */ + + +/* This file is generated from divrem.m4; DO NOT EDIT! */ +/* + * Division and remainder, from Appendix E of the Sparc Version 8 + * Architecture Manual, with fixes from Gordon Irlam. + */ + +/* + * Input: dividend and divisor in %o0 and %o1 respectively. + * + * m4 parameters: + * .div name of function to generate + * div div=div => %o0 / %o1; div=rem => %o0 % %o1 + * true true=true => signed; true=false => unsigned + * + * Algorithm parameters: + * N how many bits per iteration we try to get (4) + * WORDSIZE total number of bits (32) + * + * Derived constants: + * TOPBITS number of bits in the top decade of a number + * + * Important variables: + * Q the partial quotient under development (initially 0) + * R the remainder so far, initially the dividend + * ITER number of main division loop iterations required; + * equal to ceil(log2(quotient) / N). Note that this + * is the log base (2^N) of the quotient. + * V the current comparand, initially divisor*2^(ITER*N-1) + * + * Cost: + * Current estimate for non-large dividend is + * ceil(log2(quotient) / N) * (10 + 7N/2) + C + * A large dividend is one greater than 2^(31-TOPBITS) and takes a + * different path, as the upper bits of the quotient must be developed + * one bit at a time. + */ + + + .globl .div + .globl _Div +.div: +_Div: /* needed for export */ + ! compute sign of result; if neither is negative, no problem + orcc %o1, %o0, %g0 ! either negative? + bge 2f ! no, go do the divide + xor %o1, %o0, %g2 ! compute sign in any case + + tst %o1 + bge 1f + tst %o0 + ! %o1 is definitely negative; %o0 might also be negative + bge 2f ! if %o0 not negative... + sub %g0, %o1, %o1 ! in any case, make %o1 nonneg +1: ! %o0 is negative, %o1 is nonnegative + sub %g0, %o0, %o0 ! make %o0 nonnegative +2: + + ! Ready to divide. Compute size of quotient; scale comparand. + orcc %o1, %g0, %o5 + bne 1f + mov %o0, %o3 + + ! Divide by zero trap. If it returns, return 0 (about as + ! wrong as possible, but that is what SunOS does...). + ta ST_DIV0 + retl + clr %o0 + +1: + cmp %o3, %o5 ! if %o1 exceeds %o0, done + blu Lgot_result ! (and algorithm fails otherwise) + clr %o2 + + sethi %hi(1 << (32 - 4 - 1)), %g1 + + cmp %o3, %g1 + blu Lnot_really_big + clr %o4 + + ! Here the dividend is >= 2**(31-N) or so. We must be careful here, + ! as our usual N-at-a-shot divide step will cause overflow and havoc. + ! The number of bits in the result here is N*ITER+SC, where SC <= N. + ! Compute ITER in an unorthodox manner: know we need to shift V into + ! the top decade: so do not even bother to compare to R. + 1: + cmp %o5, %g1 + bgeu 3f + mov 1, %g7 + + sll %o5, 4, %o5 + + b 1b + add %o4, 1, %o4 + + ! Now compute %g7. + 2: + addcc %o5, %o5, %o5 + bcc Lnot_too_big + add %g7, 1, %g7 + + ! We get here if the %o1 overflowed while shifting. + ! This means that %o3 has the high-order bit set. + ! Restore %o5 and subtract from %o3. + sll %g1, 4, %g1 ! high order bit + srl %o5, 1, %o5 ! rest of %o5 + add %o5, %g1, %o5 + + b Ldo_single_div + sub %g7, 1, %g7 + + Lnot_too_big: + 3: + cmp %o5, %o3 + blu 2b + nop + + be Ldo_single_div + nop + /* NB: these are commented out in the V8-Sparc manual as well */ + /* (I do not understand this) */ + ! %o5 > %o3: went too far: back up 1 step + ! srl %o5, 1, %o5 + ! dec %g7 + ! do single-bit divide steps + ! + ! We have to be careful here. We know that %o3 >= %o5, so we can do the + ! first divide step without thinking. BUT, the others are conditional, + ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high- + ! order bit set in the first step, just falling into the regular + ! division loop will mess up the first time around. + ! So we unroll slightly... + Ldo_single_div: + subcc %g7, 1, %g7 + bl Lend_regular_divide + nop + + sub %o3, %o5, %o3 + mov 1, %o2 + + b Lend_single_divloop + nop + Lsingle_divloop: + sll %o2, 1, %o2 + + bl 1f + srl %o5, 1, %o5 + ! %o3 >= 0 + sub %o3, %o5, %o3 + + b 2f + add %o2, 1, %o2 + 1: ! %o3 < 0 + add %o3, %o5, %o3 + sub %o2, 1, %o2 + 2: + Lend_single_divloop: + subcc %g7, 1, %g7 + bge Lsingle_divloop + tst %o3 + + b,a Lend_regular_divide + +Lnot_really_big: +1: + sll %o5, 4, %o5 + cmp %o5, %o3 + bleu 1b + addcc %o4, 1, %o4 + + be Lgot_result + sub %o4, 1, %o4 + + tst %o3 ! set up for initial iteration +Ldivloop: + sll %o2, 4, %o2 + ! depth 1, accumulated bits 0 + bl L.1.16 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 2, accumulated bits 1 + bl L.2.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits 3 + bl L.3.19 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 7 + bl L.4.23 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (7*2+1), %o2 + +L.4.23: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (7*2-1), %o2 + +L.3.19: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 5 + bl L.4.21 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (5*2+1), %o2 + +L.4.21: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (5*2-1), %o2 + +L.2.17: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits 1 + bl L.3.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 3 + bl L.4.19 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (3*2+1), %o2 + +L.4.19: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (3*2-1), %o2 + + +L.3.17: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 1 + bl L.4.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (1*2+1), %o2 + +L.4.17: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (1*2-1), %o2 + +L.1.16: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 2, accumulated bits -1 + bl L.2.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits -1 + bl L.3.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -1 + bl L.4.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2+1), %o2 + +L.4.15: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2-1), %o2 + +L.3.15: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -3 + bl L.4.13 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2+1), %o2 + +L.4.13: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2-1), %o2 + +L.2.15: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits -3 + bl L.3.13 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -5 + bl L.4.11 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2+1), %o2 + +L.4.11: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2-1), %o2 + +L.3.13: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -7 + bl L.4.9 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2+1), %o2 + +L.4.9: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2-1), %o2 + + 9: +Lend_regular_divide: + subcc %o4, 1, %o4 + bge Ldivloop + tst %o3 + + bl,a Lgot_result + ! non-restoring fixup here (one instruction only!) + sub %o2, 1, %o2 + +Lgot_result: + ! check to see if answer should be < 0 + tst %g2 + bl,a 1f + sub %g0, %o2, %o2 +1: + retl + mov %o2, %o0 + + .globl .div_patch +.div_patch: + sra %o0, 0x1f, %o2 + wr %o2, 0x0, %y + nop + nop + nop + sdivcc %o0, %o1, %o0 + bvs,a 1f + xnor %o0, %g0, %o0 +1: retl + nop diff --git a/trunk/arch/sparc/lib/strlen_user_64.S b/trunk/arch/sparc/lib/strlen_user_64.S index c3df71fa4928..114ed111e251 100644 --- a/trunk/arch/sparc/lib/strlen_user_64.S +++ b/trunk/arch/sparc/lib/strlen_user_64.S @@ -8,16 +8,16 @@ * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) */ -#include #include #define LO_MAGIC 0x01010101 #define HI_MAGIC 0x80808080 .align 4 -ENTRY(__strlen_user) + .global __strlen_user, __strnlen_user +__strlen_user: sethi %hi(32768), %o1 -ENTRY(__strnlen_user) +__strnlen_user: mov %o1, %g1 mov %o0, %o1 andcc %o0, 3, %g0 @@ -78,8 +78,6 @@ ENTRY(__strnlen_user) mov 2, %o0 23: retl mov 3, %o0 -ENDPROC(__strlen_user) -ENDPROC(__strnlen_user) .section .fixup,#alloc,#execinstr .align 4 diff --git a/trunk/arch/sparc/lib/strncmp_32.S b/trunk/arch/sparc/lib/strncmp_32.S index c0d1b568c1c5..494ec664537a 100644 --- a/trunk/arch/sparc/lib/strncmp_32.S +++ b/trunk/arch/sparc/lib/strncmp_32.S @@ -3,10 +3,11 @@ * generic strncmp routine. */ -#include - .text -ENTRY(strncmp) + .align 4 + .global __strncmp, strncmp +__strncmp: +strncmp: mov %o0, %g3 mov 0, %o3 @@ -115,4 +116,3 @@ ENTRY(strncmp) and %g2, 0xff, %o0 retl sub %o3, %o0, %o0 -ENDPROC(strncmp) diff --git a/trunk/arch/sparc/lib/strncmp_64.S b/trunk/arch/sparc/lib/strncmp_64.S index 0656627166f3..980e83751556 100644 --- a/trunk/arch/sparc/lib/strncmp_64.S +++ b/trunk/arch/sparc/lib/strncmp_64.S @@ -4,11 +4,13 @@ * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) */ -#include #include .text -ENTRY(strncmp) + .align 32 + .globl strncmp + .type strncmp,#function +strncmp: brlez,pn %o2, 3f lduba [%o0] (ASI_PNF), %o3 1: @@ -27,4 +29,4 @@ ENTRY(strncmp) 3: retl clr %o0 -ENDPROC(strncmp) + .size strncmp, .-strncmp diff --git a/trunk/arch/sparc/lib/strncpy_from_user_32.S b/trunk/arch/sparc/lib/strncpy_from_user_32.S index db0ed2964bdb..d77198976a66 100644 --- a/trunk/arch/sparc/lib/strncpy_from_user_32.S +++ b/trunk/arch/sparc/lib/strncpy_from_user_32.S @@ -3,11 +3,11 @@ * Copyright(C) 1996 David S. Miller */ -#include #include #include .text + .align 4 /* Must return: * @@ -16,7 +16,8 @@ * bytes copied if we hit a null byte */ -ENTRY(__strncpy_from_user) + .globl __strncpy_from_user +__strncpy_from_user: /* %o0=dest, %o1=src, %o2=count */ mov %o2, %o3 1: @@ -34,7 +35,6 @@ ENTRY(__strncpy_from_user) add %o2, 1, %o0 retl sub %o3, %o0, %o0 -ENDPROC(__strncpy_from_user) .section .fixup,#alloc,#execinstr .align 4 diff --git a/trunk/arch/sparc/lib/strncpy_from_user_64.S b/trunk/arch/sparc/lib/strncpy_from_user_64.S index d1246b713077..511c8f136f95 100644 --- a/trunk/arch/sparc/lib/strncpy_from_user_64.S +++ b/trunk/arch/sparc/lib/strncpy_from_user_64.S @@ -4,7 +4,6 @@ * Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz) */ -#include #include #include @@ -13,6 +12,7 @@ 0: .xword 0x0101010101010101 .text + .align 32 /* Must return: * @@ -30,7 +30,9 @@ * and average length is 18 or so. */ -ENTRY(__strncpy_from_user) + .globl __strncpy_from_user + .type __strncpy_from_user,#function +__strncpy_from_user: /* %o0=dest, %o1=src, %o2=count */ andcc %o1, 7, %g0 ! IEU1 Group bne,pn %icc, 30f ! CTI @@ -121,7 +123,7 @@ ENTRY(__strncpy_from_user) mov %o2, %o0 2: retl add %o2, %o3, %o0 -ENDPROC(__strncpy_from_user) + .size __strncpy_from_user, .-__strncpy_from_user .section __ex_table,"a" .align 4 diff --git a/trunk/arch/sparc/lib/ucmpdi2.c b/trunk/arch/sparc/lib/ucmpdi2.c deleted file mode 100644 index 1e06ed500682..000000000000 --- a/trunk/arch/sparc/lib/ucmpdi2.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include "libgcc.h" - -word_type __ucmpdi2(unsigned long long a, unsigned long long b) -{ - const DWunion au = {.ll = a}; - const DWunion bu = {.ll = b}; - - if ((unsigned int) au.s.high < (unsigned int) bu.s.high) - return 0; - else if ((unsigned int) au.s.high > (unsigned int) bu.s.high) - return 2; - if ((unsigned int) au.s.low < (unsigned int) bu.s.low) - return 0; - else if ((unsigned int) au.s.low > (unsigned int) bu.s.low) - return 2; - return 1; -} -EXPORT_SYMBOL(__ucmpdi2); diff --git a/trunk/arch/sparc/lib/udiv.S b/trunk/arch/sparc/lib/udiv.S new file mode 100644 index 000000000000..2101405bdfcb --- /dev/null +++ b/trunk/arch/sparc/lib/udiv.S @@ -0,0 +1,357 @@ +/* + * udiv.S: This routine was taken from glibc-1.09 and is covered + * by the GNU Library General Public License Version 2. + */ + + +/* This file is generated from divrem.m4; DO NOT EDIT! */ +/* + * Division and remainder, from Appendix E of the Sparc Version 8 + * Architecture Manual, with fixes from Gordon Irlam. + */ + +/* + * Input: dividend and divisor in %o0 and %o1 respectively. + * + * m4 parameters: + * .udiv name of function to generate + * div div=div => %o0 / %o1; div=rem => %o0 % %o1 + * false false=true => signed; false=false => unsigned + * + * Algorithm parameters: + * N how many bits per iteration we try to get (4) + * WORDSIZE total number of bits (32) + * + * Derived constants: + * TOPBITS number of bits in the top decade of a number + * + * Important variables: + * Q the partial quotient under development (initially 0) + * R the remainder so far, initially the dividend + * ITER number of main division loop iterations required; + * equal to ceil(log2(quotient) / N). Note that this + * is the log base (2^N) of the quotient. + * V the current comparand, initially divisor*2^(ITER*N-1) + * + * Cost: + * Current estimate for non-large dividend is + * ceil(log2(quotient) / N) * (10 + 7N/2) + C + * A large dividend is one greater than 2^(31-TOPBITS) and takes a + * different path, as the upper bits of the quotient must be developed + * one bit at a time. + */ + + + .globl .udiv + .globl _Udiv +.udiv: +_Udiv: /* needed for export */ + + ! Ready to divide. Compute size of quotient; scale comparand. + orcc %o1, %g0, %o5 + bne 1f + mov %o0, %o3 + + ! Divide by zero trap. If it returns, return 0 (about as + ! wrong as possible, but that is what SunOS does...). + ta ST_DIV0 + retl + clr %o0 + +1: + cmp %o3, %o5 ! if %o1 exceeds %o0, done + blu Lgot_result ! (and algorithm fails otherwise) + clr %o2 + + sethi %hi(1 << (32 - 4 - 1)), %g1 + + cmp %o3, %g1 + blu Lnot_really_big + clr %o4 + + ! Here the dividend is >= 2**(31-N) or so. We must be careful here, + ! as our usual N-at-a-shot divide step will cause overflow and havoc. + ! The number of bits in the result here is N*ITER+SC, where SC <= N. + ! Compute ITER in an unorthodox manner: know we need to shift V into + ! the top decade: so do not even bother to compare to R. + 1: + cmp %o5, %g1 + bgeu 3f + mov 1, %g7 + + sll %o5, 4, %o5 + + b 1b + add %o4, 1, %o4 + + ! Now compute %g7. + 2: + addcc %o5, %o5, %o5 + bcc Lnot_too_big + add %g7, 1, %g7 + + ! We get here if the %o1 overflowed while shifting. + ! This means that %o3 has the high-order bit set. + ! Restore %o5 and subtract from %o3. + sll %g1, 4, %g1 ! high order bit + srl %o5, 1, %o5 ! rest of %o5 + add %o5, %g1, %o5 + + b Ldo_single_div + sub %g7, 1, %g7 + + Lnot_too_big: + 3: + cmp %o5, %o3 + blu 2b + nop + + be Ldo_single_div + nop + /* NB: these are commented out in the V8-Sparc manual as well */ + /* (I do not understand this) */ + ! %o5 > %o3: went too far: back up 1 step + ! srl %o5, 1, %o5 + ! dec %g7 + ! do single-bit divide steps + ! + ! We have to be careful here. We know that %o3 >= %o5, so we can do the + ! first divide step without thinking. BUT, the others are conditional, + ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high- + ! order bit set in the first step, just falling into the regular + ! division loop will mess up the first time around. + ! So we unroll slightly... + Ldo_single_div: + subcc %g7, 1, %g7 + bl Lend_regular_divide + nop + + sub %o3, %o5, %o3 + mov 1, %o2 + + b Lend_single_divloop + nop + Lsingle_divloop: + sll %o2, 1, %o2 + bl 1f + srl %o5, 1, %o5 + ! %o3 >= 0 + sub %o3, %o5, %o3 + b 2f + add %o2, 1, %o2 + 1: ! %o3 < 0 + add %o3, %o5, %o3 + sub %o2, 1, %o2 + 2: + Lend_single_divloop: + subcc %g7, 1, %g7 + bge Lsingle_divloop + tst %o3 + + b,a Lend_regular_divide + +Lnot_really_big: +1: + sll %o5, 4, %o5 + + cmp %o5, %o3 + bleu 1b + addcc %o4, 1, %o4 + + be Lgot_result + sub %o4, 1, %o4 + + tst %o3 ! set up for initial iteration +Ldivloop: + sll %o2, 4, %o2 + ! depth 1, accumulated bits 0 + bl L.1.16 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 2, accumulated bits 1 + bl L.2.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits 3 + bl L.3.19 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 7 + bl L.4.23 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (7*2+1), %o2 + +L.4.23: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (7*2-1), %o2 + +L.3.19: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 5 + bl L.4.21 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (5*2+1), %o2 + +L.4.21: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (5*2-1), %o2 + +L.2.17: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits 1 + bl L.3.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 3 + bl L.4.19 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (3*2+1), %o2 + +L.4.19: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (3*2-1), %o2 + +L.3.17: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 1 + bl L.4.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (1*2+1), %o2 + +L.4.17: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (1*2-1), %o2 + +L.1.16: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 2, accumulated bits -1 + bl L.2.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits -1 + bl L.3.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -1 + bl L.4.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2+1), %o2 + +L.4.15: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2-1), %o2 + +L.3.15: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -3 + bl L.4.13 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2+1), %o2 + +L.4.13: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2-1), %o2 + +L.2.15: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits -3 + bl L.3.13 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -5 + bl L.4.11 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2+1), %o2 + +L.4.11: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2-1), %o2 + +L.3.13: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -7 + bl L.4.9 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2+1), %o2 + +L.4.9: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2-1), %o2 + + 9: +Lend_regular_divide: + subcc %o4, 1, %o4 + bge Ldivloop + tst %o3 + + bl,a Lgot_result + ! non-restoring fixup here (one instruction only!) + sub %o2, 1, %o2 + +Lgot_result: + + retl + mov %o2, %o0 + + .globl .udiv_patch +.udiv_patch: + wr %g0, 0x0, %y + nop + nop + retl + udiv %o0, %o1, %o0 + nop diff --git a/trunk/arch/sparc/lib/udivdi3.S b/trunk/arch/sparc/lib/udivdi3.S index 24e0a355e2e8..b430f1f0ef62 100644 --- a/trunk/arch/sparc/lib/udivdi3.S +++ b/trunk/arch/sparc/lib/udivdi3.S @@ -60,9 +60,8 @@ __udivdi3: bne .LL77 mov %i0,%o2 mov 1,%o0 + call .udiv,0 mov 0,%o1 - wr %g0, 0, %y - udiv %o0, %o1, %o0 mov %o0,%o3 mov %i0,%o2 .LL77: diff --git a/trunk/arch/sparc/lib/umul.S b/trunk/arch/sparc/lib/umul.S new file mode 100644 index 000000000000..1f36ae682529 --- /dev/null +++ b/trunk/arch/sparc/lib/umul.S @@ -0,0 +1,171 @@ +/* + * umul.S: This routine was taken from glibc-1.09 and is covered + * by the GNU Library General Public License Version 2. + */ + + +/* + * Unsigned multiply. Returns %o0 * %o1 in %o1%o0 (i.e., %o1 holds the + * upper 32 bits of the 64-bit product). + * + * This code optimizes short (less than 13-bit) multiplies. Short + * multiplies require 25 instruction cycles, and long ones require + * 45 instruction cycles. + * + * On return, overflow has occurred (%o1 is not zero) if and only if + * the Z condition code is clear, allowing, e.g., the following: + * + * call .umul + * nop + * bnz overflow (or tnz) + */ + + .globl .umul + .globl _Umul +.umul: +_Umul: /* needed for export */ + or %o0, %o1, %o4 + mov %o0, %y ! multiplier -> Y + + andncc %o4, 0xfff, %g0 ! test bits 12..31 of *both* args + be Lmul_shortway ! if zero, can do it the short way + andcc %g0, %g0, %o4 ! zero the partial product and clear N and V + + /* + * Long multiply. 32 steps, followed by a final shift step. + */ + mulscc %o4, %o1, %o4 ! 1 + mulscc %o4, %o1, %o4 ! 2 + mulscc %o4, %o1, %o4 ! 3 + mulscc %o4, %o1, %o4 ! 4 + mulscc %o4, %o1, %o4 ! 5 + mulscc %o4, %o1, %o4 ! 6 + mulscc %o4, %o1, %o4 ! 7 + mulscc %o4, %o1, %o4 ! 8 + mulscc %o4, %o1, %o4 ! 9 + mulscc %o4, %o1, %o4 ! 10 + mulscc %o4, %o1, %o4 ! 11 + mulscc %o4, %o1, %o4 ! 12 + mulscc %o4, %o1, %o4 ! 13 + mulscc %o4, %o1, %o4 ! 14 + mulscc %o4, %o1, %o4 ! 15 + mulscc %o4, %o1, %o4 ! 16 + mulscc %o4, %o1, %o4 ! 17 + mulscc %o4, %o1, %o4 ! 18 + mulscc %o4, %o1, %o4 ! 19 + mulscc %o4, %o1, %o4 ! 20 + mulscc %o4, %o1, %o4 ! 21 + mulscc %o4, %o1, %o4 ! 22 + mulscc %o4, %o1, %o4 ! 23 + mulscc %o4, %o1, %o4 ! 24 + mulscc %o4, %o1, %o4 ! 25 + mulscc %o4, %o1, %o4 ! 26 + mulscc %o4, %o1, %o4 ! 27 + mulscc %o4, %o1, %o4 ! 28 + mulscc %o4, %o1, %o4 ! 29 + mulscc %o4, %o1, %o4 ! 30 + mulscc %o4, %o1, %o4 ! 31 + mulscc %o4, %o1, %o4 ! 32 + mulscc %o4, %g0, %o4 ! final shift + + + /* + * Normally, with the shift-and-add approach, if both numbers are + * positive you get the correct result. With 32-bit two's-complement + * numbers, -x is represented as + * + * x 32 + * ( 2 - ------ ) mod 2 * 2 + * 32 + * 2 + * + * (the `mod 2' subtracts 1 from 1.bbbb). To avoid lots of 2^32s, + * we can treat this as if the radix point were just to the left + * of the sign bit (multiply by 2^32), and get + * + * -x = (2 - x) mod 2 + * + * Then, ignoring the `mod 2's for convenience: + * + * x * y = xy + * -x * y = 2y - xy + * x * -y = 2x - xy + * -x * -y = 4 - 2x - 2y + xy + * + * For signed multiplies, we subtract (x << 32) from the partial + * product to fix this problem for negative multipliers (see mul.s). + * Because of the way the shift into the partial product is calculated + * (N xor V), this term is automatically removed for the multiplicand, + * so we don't have to adjust. + * + * But for unsigned multiplies, the high order bit wasn't a sign bit, + * and the correction is wrong. So for unsigned multiplies where the + * high order bit is one, we end up with xy - (y << 32). To fix it + * we add y << 32. + */ +#if 0 + tst %o1 + bl,a 1f ! if %o1 < 0 (high order bit = 1), + add %o4, %o0, %o4 ! %o4 += %o0 (add y to upper half) + +1: + rd %y, %o0 ! get lower half of product + retl + addcc %o4, %g0, %o1 ! put upper half in place and set Z for %o1==0 +#else + /* Faster code from tege@sics.se. */ + sra %o1, 31, %o2 ! make mask from sign bit + and %o0, %o2, %o2 ! %o2 = 0 or %o0, depending on sign of %o1 + rd %y, %o0 ! get lower half of product + retl + addcc %o4, %o2, %o1 ! add compensation and put upper half in place +#endif + +Lmul_shortway: + /* + * Short multiply. 12 steps, followed by a final shift step. + * The resulting bits are off by 12 and (32-12) = 20 bit positions, + * but there is no problem with %o0 being negative (unlike above), + * and overflow is impossible (the answer is at most 24 bits long). + */ + mulscc %o4, %o1, %o4 ! 1 + mulscc %o4, %o1, %o4 ! 2 + mulscc %o4, %o1, %o4 ! 3 + mulscc %o4, %o1, %o4 ! 4 + mulscc %o4, %o1, %o4 ! 5 + mulscc %o4, %o1, %o4 ! 6 + mulscc %o4, %o1, %o4 ! 7 + mulscc %o4, %o1, %o4 ! 8 + mulscc %o4, %o1, %o4 ! 9 + mulscc %o4, %o1, %o4 ! 10 + mulscc %o4, %o1, %o4 ! 11 + mulscc %o4, %o1, %o4 ! 12 + mulscc %o4, %g0, %o4 ! final shift + + /* + * %o4 has 20 of the bits that should be in the result; %y has + * the bottom 12 (as %y's top 12). That is: + * + * %o4 %y + * +----------------+----------------+ + * | -12- | -20- | -12- | -20- | + * +------(---------+------)---------+ + * -----result----- + * + * The 12 bits of %o4 left of the `result' area are all zero; + * in fact, all top 20 bits of %o4 are zero. + */ + + rd %y, %o5 + sll %o4, 12, %o0 ! shift middle bits left 12 + srl %o5, 20, %o5 ! shift low bits right 20 + or %o5, %o0, %o0 + retl + addcc %g0, %g0, %o1 ! %o1 = zero, and set Z + + .globl .umul_patch +.umul_patch: + umul %o0, %o1, %o0 + retl + rd %y, %o1 + nop diff --git a/trunk/arch/sparc/lib/urem.S b/trunk/arch/sparc/lib/urem.S new file mode 100644 index 000000000000..77123eb83c44 --- /dev/null +++ b/trunk/arch/sparc/lib/urem.S @@ -0,0 +1,357 @@ +/* + * urem.S: This routine was taken from glibc-1.09 and is covered + * by the GNU Library General Public License Version 2. + */ + +/* This file is generated from divrem.m4; DO NOT EDIT! */ +/* + * Division and remainder, from Appendix E of the Sparc Version 8 + * Architecture Manual, with fixes from Gordon Irlam. + */ + +/* + * Input: dividend and divisor in %o0 and %o1 respectively. + * + * m4 parameters: + * .urem name of function to generate + * rem rem=div => %o0 / %o1; rem=rem => %o0 % %o1 + * false false=true => signed; false=false => unsigned + * + * Algorithm parameters: + * N how many bits per iteration we try to get (4) + * WORDSIZE total number of bits (32) + * + * Derived constants: + * TOPBITS number of bits in the top decade of a number + * + * Important variables: + * Q the partial quotient under development (initially 0) + * R the remainder so far, initially the dividend + * ITER number of main division loop iterations required; + * equal to ceil(log2(quotient) / N). Note that this + * is the log base (2^N) of the quotient. + * V the current comparand, initially divisor*2^(ITER*N-1) + * + * Cost: + * Current estimate for non-large dividend is + * ceil(log2(quotient) / N) * (10 + 7N/2) + C + * A large dividend is one greater than 2^(31-TOPBITS) and takes a + * different path, as the upper bits of the quotient must be developed + * one bit at a time. + */ + + .globl .urem + .globl _Urem +.urem: +_Urem: /* needed for export */ + + ! Ready to divide. Compute size of quotient; scale comparand. + orcc %o1, %g0, %o5 + bne 1f + mov %o0, %o3 + + ! Divide by zero trap. If it returns, return 0 (about as + ! wrong as possible, but that is what SunOS does...). + ta ST_DIV0 + retl + clr %o0 + +1: + cmp %o3, %o5 ! if %o1 exceeds %o0, done + blu Lgot_result ! (and algorithm fails otherwise) + clr %o2 + + sethi %hi(1 << (32 - 4 - 1)), %g1 + + cmp %o3, %g1 + blu Lnot_really_big + clr %o4 + + ! Here the dividend is >= 2**(31-N) or so. We must be careful here, + ! as our usual N-at-a-shot divide step will cause overflow and havoc. + ! The number of bits in the result here is N*ITER+SC, where SC <= N. + ! Compute ITER in an unorthodox manner: know we need to shift V into + ! the top decade: so do not even bother to compare to R. + 1: + cmp %o5, %g1 + bgeu 3f + mov 1, %g7 + + sll %o5, 4, %o5 + + b 1b + add %o4, 1, %o4 + + ! Now compute %g7. + 2: + addcc %o5, %o5, %o5 + bcc Lnot_too_big + add %g7, 1, %g7 + + ! We get here if the %o1 overflowed while shifting. + ! This means that %o3 has the high-order bit set. + ! Restore %o5 and subtract from %o3. + sll %g1, 4, %g1 ! high order bit + srl %o5, 1, %o5 ! rest of %o5 + add %o5, %g1, %o5 + + b Ldo_single_div + sub %g7, 1, %g7 + + Lnot_too_big: + 3: + cmp %o5, %o3 + blu 2b + nop + + be Ldo_single_div + nop + /* NB: these are commented out in the V8-Sparc manual as well */ + /* (I do not understand this) */ + ! %o5 > %o3: went too far: back up 1 step + ! srl %o5, 1, %o5 + ! dec %g7 + ! do single-bit divide steps + ! + ! We have to be careful here. We know that %o3 >= %o5, so we can do the + ! first divide step without thinking. BUT, the others are conditional, + ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high- + ! order bit set in the first step, just falling into the regular + ! division loop will mess up the first time around. + ! So we unroll slightly... + Ldo_single_div: + subcc %g7, 1, %g7 + bl Lend_regular_divide + nop + + sub %o3, %o5, %o3 + mov 1, %o2 + + b Lend_single_divloop + nop + Lsingle_divloop: + sll %o2, 1, %o2 + bl 1f + srl %o5, 1, %o5 + ! %o3 >= 0 + sub %o3, %o5, %o3 + b 2f + add %o2, 1, %o2 + 1: ! %o3 < 0 + add %o3, %o5, %o3 + sub %o2, 1, %o2 + 2: + Lend_single_divloop: + subcc %g7, 1, %g7 + bge Lsingle_divloop + tst %o3 + + b,a Lend_regular_divide + +Lnot_really_big: +1: + sll %o5, 4, %o5 + + cmp %o5, %o3 + bleu 1b + addcc %o4, 1, %o4 + + be Lgot_result + sub %o4, 1, %o4 + + tst %o3 ! set up for initial iteration +Ldivloop: + sll %o2, 4, %o2 + ! depth 1, accumulated bits 0 + bl L.1.16 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 2, accumulated bits 1 + bl L.2.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits 3 + bl L.3.19 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 7 + bl L.4.23 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (7*2+1), %o2 + +L.4.23: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (7*2-1), %o2 + +L.3.19: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 5 + bl L.4.21 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (5*2+1), %o2 + +L.4.21: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (5*2-1), %o2 + +L.2.17: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits 1 + bl L.3.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 3 + bl L.4.19 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (3*2+1), %o2 + +L.4.19: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (3*2-1), %o2 + +L.3.17: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 1 + bl L.4.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (1*2+1), %o2 + +L.4.17: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (1*2-1), %o2 + +L.1.16: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 2, accumulated bits -1 + bl L.2.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits -1 + bl L.3.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -1 + bl L.4.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2+1), %o2 + +L.4.15: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2-1), %o2 + +L.3.15: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -3 + bl L.4.13 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2+1), %o2 + +L.4.13: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2-1), %o2 + +L.2.15: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits -3 + bl L.3.13 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -5 + bl L.4.11 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2+1), %o2 + +L.4.11: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2-1), %o2 + +L.3.13: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -7 + bl L.4.9 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2+1), %o2 + +L.4.9: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2-1), %o2 + + 9: +Lend_regular_divide: + subcc %o4, 1, %o4 + bge Ldivloop + tst %o3 + + bl,a Lgot_result + ! non-restoring fixup here (one instruction only!) + add %o3, %o1, %o3 + +Lgot_result: + + retl + mov %o3, %o0 + + .globl .urem_patch +.urem_patch: + wr %g0, 0x0, %y + nop + nop + nop + udiv %o0, %o1, %o2 + umul %o2, %o1, %o2 + retl + sub %o0, %o2, %o0 diff --git a/trunk/arch/sparc/lib/xor.S b/trunk/arch/sparc/lib/xor.S index 2c05641c3263..f44f58f40234 100644 --- a/trunk/arch/sparc/lib/xor.S +++ b/trunk/arch/sparc/lib/xor.S @@ -8,7 +8,6 @@ * Copyright (C) 2006 David S. Miller */ -#include #include #include #include @@ -20,9 +19,12 @@ * !(len & 127) && len >= 256 */ .text + .align 32 /* VIS versions. */ -ENTRY(xor_vis_2) + .globl xor_vis_2 + .type xor_vis_2,#function +xor_vis_2: rd %fprs, %o5 andcc %o5, FPRS_FEF|FPRS_DU, %g0 be,pt %icc, 0f @@ -89,9 +91,11 @@ ENTRY(xor_vis_2) wr %g1, %g0, %asi retl wr %g0, 0, %fprs -ENDPROC(xor_vis_2) + .size xor_vis_2, .-xor_vis_2 -ENTRY(xor_vis_3) + .globl xor_vis_3 + .type xor_vis_3,#function +xor_vis_3: rd %fprs, %o5 andcc %o5, FPRS_FEF|FPRS_DU, %g0 be,pt %icc, 0f @@ -155,9 +159,11 @@ ENTRY(xor_vis_3) wr %g1, %g0, %asi retl wr %g0, 0, %fprs -ENDPROC(xor_vis_3) + .size xor_vis_3, .-xor_vis_3 -ENTRY(xor_vis_4) + .globl xor_vis_4 + .type xor_vis_4,#function +xor_vis_4: rd %fprs, %o5 andcc %o5, FPRS_FEF|FPRS_DU, %g0 be,pt %icc, 0f @@ -240,9 +246,11 @@ ENTRY(xor_vis_4) wr %g1, %g0, %asi retl wr %g0, 0, %fprs -ENDPROC(xor_vis_4) + .size xor_vis_4, .-xor_vis_4 -ENTRY(xor_vis_5) + .globl xor_vis_5 + .type xor_vis_5,#function +xor_vis_5: save %sp, -192, %sp rd %fprs, %o5 andcc %o5, FPRS_FEF|FPRS_DU, %g0 @@ -346,10 +354,12 @@ ENTRY(xor_vis_5) wr %g0, 0, %fprs ret restore -ENDPROC(xor_vis_5) + .size xor_vis_5, .-xor_vis_5 /* Niagara versions. */ -ENTRY(xor_niagara_2) /* %o0=bytes, %o1=dest, %o2=src */ + .globl xor_niagara_2 + .type xor_niagara_2,#function +xor_niagara_2: /* %o0=bytes, %o1=dest, %o2=src */ save %sp, -192, %sp prefetch [%i1], #n_writes prefetch [%i2], #one_read @@ -392,9 +402,11 @@ ENTRY(xor_niagara_2) /* %o0=bytes, %o1=dest, %o2=src */ wr %g7, 0x0, %asi ret restore -ENDPROC(xor_niagara_2) + .size xor_niagara_2, .-xor_niagara_2 -ENTRY(xor_niagara_3) /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2 */ + .globl xor_niagara_3 + .type xor_niagara_3,#function +xor_niagara_3: /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2 */ save %sp, -192, %sp prefetch [%i1], #n_writes prefetch [%i2], #one_read @@ -453,9 +465,11 @@ ENTRY(xor_niagara_3) /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2 */ wr %g7, 0x0, %asi ret restore -ENDPROC(xor_niagara_3) + .size xor_niagara_3, .-xor_niagara_3 -ENTRY(xor_niagara_4) /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3 */ + .globl xor_niagara_4 + .type xor_niagara_4,#function +xor_niagara_4: /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3 */ save %sp, -192, %sp prefetch [%i1], #n_writes prefetch [%i2], #one_read @@ -535,9 +549,11 @@ ENTRY(xor_niagara_4) /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3 */ wr %g7, 0x0, %asi ret restore -ENDPROC(xor_niagara_4) + .size xor_niagara_4, .-xor_niagara_4 -ENTRY(xor_niagara_5) /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3, %o5=src4 */ + .globl xor_niagara_5 + .type xor_niagara_5,#function +xor_niagara_5: /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3, %o5=src4 */ save %sp, -192, %sp prefetch [%i1], #n_writes prefetch [%i2], #one_read @@ -633,4 +649,4 @@ ENTRY(xor_niagara_5) /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3, %o5=s wr %g7, 0x0, %asi ret restore -ENDPROC(xor_niagara_5) + .size xor_niagara_5, .-xor_niagara_5 diff --git a/trunk/arch/sparc/mm/Makefile b/trunk/arch/sparc/mm/Makefile index 69ffd3112fed..301421c11291 100644 --- a/trunk/arch/sparc/mm/Makefile +++ b/trunk/arch/sparc/mm/Makefile @@ -7,7 +7,8 @@ ccflags-y := -Werror obj-$(CONFIG_SPARC64) += ultra.o tlb.o tsb.o gup.o obj-y += fault_$(BITS).o obj-y += init_$(BITS).o -obj-$(CONFIG_SPARC32) += extable.o srmmu.o iommu.o io-unit.o +obj-$(CONFIG_SPARC32) += loadmmu.o +obj-$(CONFIG_SPARC32) += extable.o btfixup.o srmmu.o iommu.o io-unit.o obj-$(CONFIG_SPARC32) += hypersparc.o viking.o tsunami.o swift.o obj-$(CONFIG_SPARC_LEON)+= leon_mm.o @@ -16,3 +17,9 @@ obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o # Only used by sparc32 obj-$(CONFIG_HIGHMEM) += highmem.o + +ifdef CONFIG_SMP +obj-$(CONFIG_SPARC32) += nosun4c.o +else +obj-$(CONFIG_SPARC32) += sun4c.o +endif diff --git a/trunk/arch/sparc/mm/btfixup.c b/trunk/arch/sparc/mm/btfixup.c new file mode 100644 index 000000000000..09d6af22db2d --- /dev/null +++ b/trunk/arch/sparc/mm/btfixup.c @@ -0,0 +1,328 @@ +/* btfixup.c: Boot time code fixup and relocator, so that + * we can get rid of most indirect calls to achieve single + * image sun4c and srmmu kernel. + * + * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define BTFIXUP_OPTIMIZE_NOP +#define BTFIXUP_OPTIMIZE_OTHER + +extern char *srmmu_name; +static char version[] __initdata = "Boot time fixup v1.6. 4/Mar/98 Jakub Jelinek (jj@ultra.linux.cz). Patching kernel for "; +static char str_sun4c[] __initdata = "sun4c\n"; +static char str_srmmu[] __initdata = "srmmu[%s]/"; +static char str_iommu[] __initdata = "iommu\n"; +static char str_iounit[] __initdata = "io-unit\n"; + +static int visited __initdata = 0; +extern unsigned int ___btfixup_start[], ___btfixup_end[], __init_begin[], __init_end[], __init_text_end[]; +extern unsigned int _stext[], _end[], __start___ksymtab[], __stop___ksymtab[]; +static char wrong_f[] __initdata = "Trying to set f fixup %p to invalid function %08x\n"; +static char wrong_b[] __initdata = "Trying to set b fixup %p to invalid function %08x\n"; +static char wrong_s[] __initdata = "Trying to set s fixup %p to invalid value %08x\n"; +static char wrong_h[] __initdata = "Trying to set h fixup %p to invalid value %08x\n"; +static char wrong_a[] __initdata = "Trying to set a fixup %p to invalid value %08x\n"; +static char wrong[] __initdata = "Wrong address for %c fixup %p\n"; +static char insn_f[] __initdata = "Fixup f %p refers to weird instructions at %p[%08x,%08x]\n"; +static char insn_b[] __initdata = "Fixup b %p doesn't refer to a SETHI at %p[%08x]\n"; +static char insn_s[] __initdata = "Fixup s %p doesn't refer to an OR at %p[%08x]\n"; +static char insn_h[] __initdata = "Fixup h %p doesn't refer to a SETHI at %p[%08x]\n"; +static char insn_a[] __initdata = "Fixup a %p doesn't refer to a SETHI nor OR at %p[%08x]\n"; +static char insn_i[] __initdata = "Fixup i %p doesn't refer to a valid instruction at %p[%08x]\n"; +static char fca_und[] __initdata = "flush_cache_all undefined in btfixup()\n"; +static char wrong_setaddr[] __initdata = "Garbled CALL/INT patch at %p[%08x,%08x,%08x]=%08x\n"; + +#ifdef BTFIXUP_OPTIMIZE_OTHER +static void __init set_addr(unsigned int *addr, unsigned int q1, int fmangled, unsigned int value) +{ + if (!fmangled) + *addr = value; + else { + unsigned int *q = (unsigned int *)q1; + if (*addr == 0x01000000) { + /* Noped */ + *q = value; + } else if (addr[-1] == *q) { + /* Moved */ + addr[-1] = value; + *q = value; + } else { + prom_printf(wrong_setaddr, addr-1, addr[-1], *addr, *q, value); + prom_halt(); + } + } +} +#else +static inline void set_addr(unsigned int *addr, unsigned int q1, int fmangled, unsigned int value) +{ + *addr = value; +} +#endif + +void __init btfixup(void) +{ + unsigned int *p, *q; + int type, count; + unsigned insn; + unsigned *addr; + int fmangled = 0; + void (*flush_cacheall)(void); + + if (!visited) { + visited++; + printk(version); + if (ARCH_SUN4C) + printk(str_sun4c); + else { + printk(str_srmmu, srmmu_name); + if (sparc_cpu_model == sun4d) + printk(str_iounit); + else + printk(str_iommu); + } + } + for (p = ___btfixup_start; p < ___btfixup_end; ) { + count = p[2]; + q = p + 3; + switch (type = *(unsigned char *)p) { + case 'f': + count = p[3]; + q = p + 4; + if (((p[0] & 1) || p[1]) + && ((p[1] & 3) || (unsigned *)(p[1]) < _stext || (unsigned *)(p[1]) >= _end)) { + prom_printf(wrong_f, p, p[1]); + prom_halt(); + } + break; + case 'b': + if (p[1] < (unsigned long)__init_begin || p[1] >= (unsigned long)__init_text_end || (p[1] & 3)) { + prom_printf(wrong_b, p, p[1]); + prom_halt(); + } + break; + case 's': + if (p[1] + 0x1000 >= 0x2000) { + prom_printf(wrong_s, p, p[1]); + prom_halt(); + } + break; + case 'h': + if (p[1] & 0x3ff) { + prom_printf(wrong_h, p, p[1]); + prom_halt(); + } + break; + case 'a': + if (p[1] + 0x1000 >= 0x2000 && (p[1] & 0x3ff)) { + prom_printf(wrong_a, p, p[1]); + prom_halt(); + } + break; + } + if (p[0] & 1) { + p[0] &= ~1; + while (count) { + fmangled = 0; + addr = (unsigned *)*q; + if (addr < _stext || addr >= _end) { + prom_printf(wrong, type, p); + prom_halt(); + } + insn = *addr; +#ifdef BTFIXUP_OPTIMIZE_OTHER + if (type != 'f' && q[1]) { + insn = *(unsigned int *)q[1]; + if (!insn || insn == 1) + insn = *addr; + else + fmangled = 1; + } +#endif + switch (type) { + case 'f': /* CALL */ + if (addr >= __start___ksymtab && addr < __stop___ksymtab) { + *addr = p[1]; + break; + } else if (!q[1]) { + if ((insn & 0xc1c00000) == 0x01000000) { /* SETHI */ + *addr = (insn & 0xffc00000) | (p[1] >> 10); break; + } else if ((insn & 0xc1f82000) == 0x80102000) { /* OR X, %LO(i), Y */ + *addr = (insn & 0xffffe000) | (p[1] & 0x3ff); break; + } else if ((insn & 0xc0000000) != 0x40000000) { /* !CALL */ + bad_f: + prom_printf(insn_f, p, addr, insn, addr[1]); + prom_halt(); + } + } else if (q[1] != 1) + addr[1] = q[1]; + if (p[2] == BTFIXUPCALL_NORM) { + norm_f: + *addr = 0x40000000 | ((p[1] - (unsigned)addr) >> 2); + q[1] = 0; + break; + } +#ifndef BTFIXUP_OPTIMIZE_NOP + goto norm_f; +#else + if (!(addr[1] & 0x80000000)) { + if ((addr[1] & 0xc1c00000) != 0x01000000) /* !SETHI */ + goto bad_f; /* CALL, Bicc, FBfcc, CBccc are weird in delay slot, aren't they? */ + } else { + if ((addr[1] & 0x01800000) == 0x01800000) { + if ((addr[1] & 0x01f80000) == 0x01e80000) { + /* RESTORE */ + goto norm_f; /* It is dangerous to patch that */ + } + goto bad_f; + } + if ((addr[1] & 0xffffe003) == 0x9e03e000) { + /* ADD %O7, XX, %o7 */ + int displac = (addr[1] << 19); + + displac = (displac >> 21) + 2; + *addr = (0x10800000) + (displac & 0x3fffff); + q[1] = addr[1]; + addr[1] = p[2]; + break; + } + if ((addr[1] & 0x201f) == 0x200f || (addr[1] & 0x7c000) == 0x3c000) + goto norm_f; /* Someone is playing bad tricks with us: rs1 or rs2 is o7 */ + if ((addr[1] & 0x3e000000) == 0x1e000000) + goto norm_f; /* rd is %o7. We'd better take care. */ + } + if (p[2] == BTFIXUPCALL_NOP) { + *addr = 0x01000000; + q[1] = 1; + break; + } +#ifndef BTFIXUP_OPTIMIZE_OTHER + goto norm_f; +#else + if (addr[1] == 0x01000000) { /* NOP in the delay slot */ + q[1] = addr[1]; + *addr = p[2]; + break; + } + if ((addr[1] & 0xc0000000) != 0xc0000000) { + /* Not a memory operation */ + if ((addr[1] & 0x30000000) == 0x10000000) { + /* Ok, non-memory op with rd %oX */ + if ((addr[1] & 0x3e000000) == 0x1c000000) + goto bad_f; /* Aiee. Someone is playing strange %sp tricks */ + if ((addr[1] & 0x3e000000) > 0x12000000 || + ((addr[1] & 0x3e000000) == 0x12000000 && + p[2] != BTFIXUPCALL_STO1O0 && p[2] != BTFIXUPCALL_SWAPO0O1) || + ((p[2] & 0xffffe000) == BTFIXUPCALL_RETINT(0))) { + /* Nobody uses the result. We can nop it out. */ + *addr = p[2]; + q[1] = addr[1]; + addr[1] = 0x01000000; + break; + } + if ((addr[1] & 0xf1ffffe0) == 0x90100000) { + /* MOV %reg, %Ox */ + if ((addr[1] & 0x3e000000) == 0x10000000 && + (p[2] & 0x7c000) == 0x20000) { + /* Ok, it is call xx; mov reg, %o0 and call optimizes + to doing something on %o0. Patch the patch. */ + *addr = (p[2] & ~0x7c000) | ((addr[1] & 0x1f) << 14); + q[1] = addr[1]; + addr[1] = 0x01000000; + break; + } + if ((addr[1] & 0x3e000000) == 0x12000000 && + p[2] == BTFIXUPCALL_STO1O0) { + *addr = (p[2] & ~0x3e000000) | ((addr[1] & 0x1f) << 25); + q[1] = addr[1]; + addr[1] = 0x01000000; + break; + } + } + } + } + *addr = addr[1]; + q[1] = addr[1]; + addr[1] = p[2]; + break; +#endif /* BTFIXUP_OPTIMIZE_OTHER */ +#endif /* BTFIXUP_OPTIMIZE_NOP */ + case 'b': /* BLACKBOX */ + /* Has to be sethi i, xx */ + if ((insn & 0xc1c00000) != 0x01000000) { + prom_printf(insn_b, p, addr, insn); + prom_halt(); + } else { + void (*do_fixup)(unsigned *); + + do_fixup = (void (*)(unsigned *))p[1]; + do_fixup(addr); + } + break; + case 's': /* SIMM13 */ + /* Has to be or %g0, i, xx */ + if ((insn & 0xc1ffe000) != 0x80102000) { + prom_printf(insn_s, p, addr, insn); + prom_halt(); + } + set_addr(addr, q[1], fmangled, (insn & 0xffffe000) | (p[1] & 0x1fff)); + break; + case 'h': /* SETHI */ + /* Has to be sethi i, xx */ + if ((insn & 0xc1c00000) != 0x01000000) { + prom_printf(insn_h, p, addr, insn); + prom_halt(); + } + set_addr(addr, q[1], fmangled, (insn & 0xffc00000) | (p[1] >> 10)); + break; + case 'a': /* HALF */ + /* Has to be sethi i, xx or or %g0, i, xx */ + if ((insn & 0xc1c00000) != 0x01000000 && + (insn & 0xc1ffe000) != 0x80102000) { + prom_printf(insn_a, p, addr, insn); + prom_halt(); + } + if (p[1] & 0x3ff) + set_addr(addr, q[1], fmangled, + (insn & 0x3e000000) | 0x80102000 | (p[1] & 0x1fff)); + else + set_addr(addr, q[1], fmangled, + (insn & 0x3e000000) | 0x01000000 | (p[1] >> 10)); + break; + case 'i': /* INT */ + if ((insn & 0xc1c00000) == 0x01000000) /* %HI */ + set_addr(addr, q[1], fmangled, (insn & 0xffc00000) | (p[1] >> 10)); + else if ((insn & 0x80002000) == 0x80002000) /* %LO */ + set_addr(addr, q[1], fmangled, (insn & 0xffffe000) | (p[1] & 0x3ff)); + else { + prom_printf(insn_i, p, addr, insn); + prom_halt(); + } + break; + } + count -= 2; + q += 2; + } + } else + p = q + count; + } +#ifdef CONFIG_SMP + flush_cacheall = (void (*)(void))BTFIXUPVAL_CALL(local_flush_cache_all); +#else + flush_cacheall = (void (*)(void))BTFIXUPVAL_CALL(flush_cache_all); +#endif + if (!flush_cacheall) { + prom_printf(fca_und); + prom_halt(); + } + (*flush_cacheall)(); +} diff --git a/trunk/arch/sparc/mm/fault_32.c b/trunk/arch/sparc/mm/fault_32.c index f46cf6be3370..df3155a17991 100644 --- a/trunk/arch/sparc/mm/fault_32.c +++ b/trunk/arch/sparc/mm/fault_32.c @@ -24,19 +24,29 @@ #include #include +#include #include #include #include #include #include +extern int prom_node_root; + int show_unhandled_signals = 1; /* At boot time we determine these two values necessary for setting * up the segment maps and page table entries (pte's). */ -int num_contexts; +int num_segmaps, num_contexts; +int invalid_segment; + +/* various Virtual Address Cache parameters we find at boot time... */ + +int vac_size, vac_linesize, vac_do_hw_vac_flushes; +int vac_entries_per_context, vac_entries_per_segment; +int vac_entries_per_page; /* Return how much physical memory we have. */ unsigned long probe_memory(void) @@ -50,36 +60,55 @@ unsigned long probe_memory(void) return total; } +extern void sun4c_complete_all_stores(void); + +/* Whee, a level 15 NMI interrupt memory error. Let's have fun... */ +asmlinkage void sparc_lvl15_nmi(struct pt_regs *regs, unsigned long serr, + unsigned long svaddr, unsigned long aerr, + unsigned long avaddr) +{ + sun4c_complete_all_stores(); + printk("FAULT: NMI received\n"); + printk("SREGS: Synchronous Error %08lx\n", serr); + printk(" Synchronous Vaddr %08lx\n", svaddr); + printk(" Asynchronous Error %08lx\n", aerr); + printk(" Asynchronous Vaddr %08lx\n", avaddr); + if (sun4c_memerr_reg) + printk(" Memory Parity Error %08lx\n", *sun4c_memerr_reg); + printk("REGISTER DUMP:\n"); + show_regs(regs); + prom_halt(); +} + static void unhandled_fault(unsigned long, struct task_struct *, struct pt_regs *) __attribute__ ((noreturn)); -static void __noreturn unhandled_fault(unsigned long address, - struct task_struct *tsk, - struct pt_regs *regs) +static void unhandled_fault(unsigned long address, struct task_struct *tsk, + struct pt_regs *regs) { - if ((unsigned long) address < PAGE_SIZE) { + if((unsigned long) address < PAGE_SIZE) { printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference\n"); } else { - printk(KERN_ALERT "Unable to handle kernel paging request at virtual address %08lx\n", - address); + printk(KERN_ALERT "Unable to handle kernel paging request " + "at virtual address %08lx\n", address); } printk(KERN_ALERT "tsk->{mm,active_mm}->context = %08lx\n", (tsk->mm ? tsk->mm->context : tsk->active_mm->context)); printk(KERN_ALERT "tsk->{mm,active_mm}->pgd = %08lx\n", (tsk->mm ? (unsigned long) tsk->mm->pgd : - (unsigned long) tsk->active_mm->pgd)); + (unsigned long) tsk->active_mm->pgd)); die_if_kernel("Oops", regs); } -asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc, +asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc, unsigned long address) { struct pt_regs regs; unsigned long g2; unsigned int insn; int i; - + i = search_extables_range(ret_pc, &g2); switch (i) { case 3: @@ -99,14 +128,14 @@ asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc, /* for _from_ macros */ insn = *((unsigned int *) pc); if (!((insn >> 21) & 1) || ((insn>>19)&0x3f) == 15) - return 2; - break; + return 2; + break; default: break; } - memset(®s, 0, sizeof(regs)); + memset(®s, 0, sizeof (regs)); regs.pc = pc; regs.npc = pc + 4; __asm__ __volatile__( @@ -169,10 +198,11 @@ static unsigned long compute_si_addr(struct pt_regs *regs, int text_fault) if (text_fault) return regs->pc; - if (regs->psr & PSR_PS) + if (regs->psr & PSR_PS) { insn = *(unsigned int *) regs->pc; - else + } else { __get_user(insn, (unsigned int *) regs->pc); + } return safe_compute_effective_address(regs, insn); } @@ -198,7 +228,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, unsigned int flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | (write ? FAULT_FLAG_WRITE : 0)); - if (text_fault) + if(text_fault) address = regs->pc; /* @@ -211,32 +241,36 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, * nothing more. */ code = SEGV_MAPERR; - if (address >= TASK_SIZE) + if (!ARCH_SUN4C && address >= TASK_SIZE) goto vmalloc_fault; /* * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_atomic() || !mm) - goto no_context; + if (in_atomic() || !mm) + goto no_context; perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); retry: down_read(&mm->mmap_sem); - if (!from_user && address >= PAGE_OFFSET) + /* + * The kernel referencing a bad kernel pointer can lock up + * a sun4c machine completely, so we must attempt recovery. + */ + if(!from_user && address >= PAGE_OFFSET) goto bad_area; vma = find_vma(mm, address); - if (!vma) + if(!vma) goto bad_area; - if (vma->vm_start <= address) + if(vma->vm_start <= address) goto good_area; - if (!(vma->vm_flags & VM_GROWSDOWN)) + if(!(vma->vm_flags & VM_GROWSDOWN)) goto bad_area; - if (expand_stack(vma, address)) + if(expand_stack(vma, address)) goto bad_area; /* * Ok, we have a good vm_area for this memory access, so @@ -244,12 +278,12 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, */ good_area: code = SEGV_ACCERR; - if (write) { - if (!(vma->vm_flags & VM_WRITE)) + if(write) { + if(!(vma->vm_flags & VM_WRITE)) goto bad_area; } else { /* Allow reads even for write-only mappings */ - if (!(vma->vm_flags & (VM_READ | VM_EXEC))) + if(!(vma->vm_flags & (VM_READ | VM_EXEC))) goto bad_area; } @@ -315,16 +349,14 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, g2 = regs->u_regs[UREG_G2]; if (!from_user) { fixup = search_extables_range(regs->pc, &g2); - /* Values below 10 are reserved for other things */ - if (fixup > 10) { + if (fixup > 10) { /* Values below are reserved for other things */ extern const unsigned __memset_start[]; extern const unsigned __memset_end[]; extern const unsigned __csum_partial_copy_start[]; extern const unsigned __csum_partial_copy_end[]; #ifdef DEBUG_EXCEPTIONS - printk("Exception: PC<%08lx> faddr<%08lx>\n", - regs->pc, address); + printk("Exception: PC<%08lx> faddr<%08lx>\n", regs->pc, address); printk("EX_TABLE: insn<%08lx> fixup<%08x> g2<%08lx>\n", regs->pc, fixup, g2); #endif @@ -332,7 +364,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, regs->pc < (unsigned long)__memset_end) || (regs->pc >= (unsigned long)__csum_partial_copy_start && regs->pc < (unsigned long)__csum_partial_copy_end)) { - regs->u_regs[UREG_I4] = address; + regs->u_regs[UREG_I4] = address; regs->u_regs[UREG_I5] = regs->pc; } regs->u_regs[UREG_G2] = g2; @@ -341,8 +373,8 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, return; } } - - unhandled_fault(address, tsk, regs); + + unhandled_fault (address, tsk, regs); do_exit(SIGKILL); /* @@ -388,12 +420,97 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, if (pmd_present(*pmd) || !pmd_present(*pmd_k)) goto bad_area_nosemaphore; - *pmd = *pmd_k; return; } } +asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write, + unsigned long address) +{ + extern void sun4c_update_mmu_cache(struct vm_area_struct *, + unsigned long,pte_t *); + extern pte_t *sun4c_pte_offset_kernel(pmd_t *,unsigned long); + struct task_struct *tsk = current; + struct mm_struct *mm = tsk->mm; + pgd_t *pgdp; + pte_t *ptep; + + if (text_fault) { + address = regs->pc; + } else if (!write && + !(regs->psr & PSR_PS)) { + unsigned int insn, __user *ip; + + ip = (unsigned int __user *)regs->pc; + if (!get_user(insn, ip)) { + if ((insn & 0xc1680000) == 0xc0680000) + write = 1; + } + } + + if (!mm) { + /* We are oopsing. */ + do_sparc_fault(regs, text_fault, write, address); + BUG(); /* P3 Oops already, you bitch */ + } + + pgdp = pgd_offset(mm, address); + ptep = sun4c_pte_offset_kernel((pmd_t *) pgdp, address); + + if (pgd_val(*pgdp)) { + if (write) { + if ((pte_val(*ptep) & (_SUN4C_PAGE_WRITE|_SUN4C_PAGE_PRESENT)) + == (_SUN4C_PAGE_WRITE|_SUN4C_PAGE_PRESENT)) { + unsigned long flags; + + *ptep = __pte(pte_val(*ptep) | _SUN4C_PAGE_ACCESSED | + _SUN4C_PAGE_MODIFIED | + _SUN4C_PAGE_VALID | + _SUN4C_PAGE_DIRTY); + + local_irq_save(flags); + if (sun4c_get_segmap(address) != invalid_segment) { + sun4c_put_pte(address, pte_val(*ptep)); + local_irq_restore(flags); + return; + } + local_irq_restore(flags); + } + } else { + if ((pte_val(*ptep) & (_SUN4C_PAGE_READ|_SUN4C_PAGE_PRESENT)) + == (_SUN4C_PAGE_READ|_SUN4C_PAGE_PRESENT)) { + unsigned long flags; + + *ptep = __pte(pte_val(*ptep) | _SUN4C_PAGE_ACCESSED | + _SUN4C_PAGE_VALID); + + local_irq_save(flags); + if (sun4c_get_segmap(address) != invalid_segment) { + sun4c_put_pte(address, pte_val(*ptep)); + local_irq_restore(flags); + return; + } + local_irq_restore(flags); + } + } + } + + /* This conditional is 'interesting'. */ + if (pgd_val(*pgdp) && !(write && !(pte_val(*ptep) & _SUN4C_PAGE_WRITE)) + && (pte_val(*ptep) & _SUN4C_PAGE_VALID)) + /* Note: It is safe to not grab the MMAP semaphore here because + * we know that update_mmu_cache() will not sleep for + * any reason (at least not in the current implementation) + * and therefore there is no danger of another thread getting + * on the CPU and doing a shrink_mmap() on this vma. + */ + sun4c_update_mmu_cache (find_vma(current->mm, address), address, + ptep); + else + do_sparc_fault(regs, text_fault, write, address); +} + /* This always deals with user addresses. */ static void force_user_fault(unsigned long address, int write) { @@ -406,21 +523,21 @@ static void force_user_fault(unsigned long address, int write) down_read(&mm->mmap_sem); vma = find_vma(mm, address); - if (!vma) + if(!vma) goto bad_area; - if (vma->vm_start <= address) + if(vma->vm_start <= address) goto good_area; - if (!(vma->vm_flags & VM_GROWSDOWN)) + if(!(vma->vm_flags & VM_GROWSDOWN)) goto bad_area; - if (expand_stack(vma, address)) + if(expand_stack(vma, address)) goto bad_area; good_area: code = SEGV_ACCERR; - if (write) { - if (!(vma->vm_flags & VM_WRITE)) + if(write) { + if(!(vma->vm_flags & VM_WRITE)) goto bad_area; } else { - if (!(vma->vm_flags & (VM_READ | VM_EXEC))) + if(!(vma->vm_flags & (VM_READ | VM_EXEC))) goto bad_area; } switch (handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0)) { @@ -451,7 +568,7 @@ void window_overflow_fault(void) unsigned long sp; sp = current_thread_info()->rwbuf_stkptrs[0]; - if (((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) + if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) force_user_fault(sp + 0x38, 1); force_user_fault(sp, 1); @@ -460,7 +577,7 @@ void window_overflow_fault(void) void window_underflow_fault(unsigned long sp) { - if (((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) + if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) force_user_fault(sp + 0x38, 0); force_user_fault(sp, 0); @@ -472,7 +589,7 @@ void window_ret_fault(struct pt_regs *regs) unsigned long sp; sp = regs->u_regs[UREG_FP]; - if (((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) + if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) force_user_fault(sp + 0x38, 0); force_user_fault(sp, 0); diff --git a/trunk/arch/sparc/mm/init_32.c b/trunk/arch/sparc/mm/init_32.c index ef5c779ec855..c5f9021b1a01 100644 --- a/trunk/arch/sparc/mm/init_32.c +++ b/trunk/arch/sparc/mm/init_32.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -44,6 +45,9 @@ EXPORT_SYMBOL(phys_base); unsigned long pfn_base; EXPORT_SYMBOL(pfn_base); +unsigned long page_kernel; +EXPORT_SYMBOL(page_kernel); + struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS+1]; unsigned long sparc_unmapped_base; @@ -282,17 +286,45 @@ unsigned long __init bootmem_init(unsigned long *pages_avail) return max_pfn; } +/* + * check_pgt_cache + * + * This is called at the end of unmapping of VMA (zap_page_range), + * to rescan the page cache for architecture specific things, + * presumably something like sun4/sun4c PMEGs. Most architectures + * define check_pgt_cache empty. + * + * We simply copy the 2.4 implementation for now. + */ +static int pgt_cache_water[2] = { 25, 50 }; + +void check_pgt_cache(void) +{ + do_check_pgt_cache(pgt_cache_water[0], pgt_cache_water[1]); +} + /* * paging_init() sets up the page tables: We call the MMU specific * init routine based upon the Sun model type on the Sparc. * */ +extern void sun4c_paging_init(void); extern void srmmu_paging_init(void); extern void device_scan(void); +pgprot_t PAGE_SHARED __read_mostly; +EXPORT_SYMBOL(PAGE_SHARED); + void __init paging_init(void) { switch(sparc_cpu_model) { + case sun4c: + case sun4e: + case sun4: + sun4c_paging_init(); + sparc_unmapped_base = 0xe0000000; + BTFIXUPSET_SETHI(sparc_unmapped_base, 0xe0000000); + break; case sparc_leon: leon_init(); /* fall through */ @@ -300,6 +332,7 @@ void __init paging_init(void) case sun4d: srmmu_paging_init(); sparc_unmapped_base = 0x50000000; + BTFIXUPSET_SETHI(sparc_unmapped_base, 0x50000000); break; default: prom_printf("paging_init: Cannot init paging on this Sparc\n"); @@ -308,6 +341,24 @@ void __init paging_init(void) prom_halt(); } + /* Initialize the protection map with non-constant, MMU dependent values. */ + protection_map[0] = PAGE_NONE; + protection_map[1] = PAGE_READONLY; + protection_map[2] = PAGE_COPY; + protection_map[3] = PAGE_COPY; + protection_map[4] = PAGE_READONLY; + protection_map[5] = PAGE_READONLY; + protection_map[6] = PAGE_COPY; + protection_map[7] = PAGE_COPY; + protection_map[8] = PAGE_NONE; + protection_map[9] = PAGE_READONLY; + protection_map[10] = PAGE_SHARED; + protection_map[11] = PAGE_SHARED; + protection_map[12] = PAGE_READONLY; + protection_map[13] = PAGE_READONLY; + protection_map[14] = PAGE_SHARED; + protection_map[15] = PAGE_SHARED; + btfixup(); prom_build_devicetree(); of_fill_in_cpu_data(); device_scan(); diff --git a/trunk/arch/sparc/mm/init_64.c b/trunk/arch/sparc/mm/init_64.c index 6026fdd1b2ed..21faaeea85de 100644 --- a/trunk/arch/sparc/mm/init_64.c +++ b/trunk/arch/sparc/mm/init_64.c @@ -741,6 +741,7 @@ static void __init find_ramdisk(unsigned long phys_base) struct node_mem_mask { unsigned long mask; unsigned long val; + unsigned long bootmem_paddr; }; static struct node_mem_mask node_masks[MAX_NUMNODES]; static int num_node_masks; @@ -805,6 +806,12 @@ static u64 memblock_nid_range(u64 start, u64 end, int *nid) return start; } +#else +static u64 memblock_nid_range(u64 start, u64 end, int *nid) +{ + *nid = 0; + return end; +} #endif /* This must be invoked after performing all of the necessary @@ -813,11 +820,10 @@ static u64 memblock_nid_range(u64 start, u64 end, int *nid) */ static void __init allocate_node_data(int nid) { + unsigned long paddr, num_pages, start_pfn, end_pfn; struct pglist_data *p; - unsigned long start_pfn, end_pfn; -#ifdef CONFIG_NEED_MULTIPLE_NODES - unsigned long paddr; +#ifdef CONFIG_NEED_MULTIPLE_NODES paddr = memblock_alloc_try_nid(sizeof(struct pglist_data), SMP_CACHE_BYTES, nid); if (!paddr) { prom_printf("Cannot allocate pglist_data for nid[%d]\n", nid); @@ -826,7 +832,7 @@ static void __init allocate_node_data(int nid) NODE_DATA(nid) = __va(paddr); memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); - NODE_DATA(nid)->node_id = nid; + NODE_DATA(nid)->bdata = &bootmem_node_data[nid]; #endif p = NODE_DATA(nid); @@ -834,6 +840,18 @@ static void __init allocate_node_data(int nid) get_pfn_range_for_nid(nid, &start_pfn, &end_pfn); p->node_start_pfn = start_pfn; p->node_spanned_pages = end_pfn - start_pfn; + + if (p->node_spanned_pages) { + num_pages = bootmem_bootmap_pages(p->node_spanned_pages); + + paddr = memblock_alloc_try_nid(num_pages << PAGE_SHIFT, PAGE_SIZE, nid); + if (!paddr) { + prom_printf("Cannot allocate bootmap for nid[%d]\n", + nid); + prom_halt(); + } + node_masks[nid].bootmem_paddr = paddr; + } } static void init_node_masks_nonnuma(void) @@ -1274,9 +1292,75 @@ static void __init bootmem_init_nonnuma(void) node_set_online(0); } +static void __init reserve_range_in_node(int nid, unsigned long start, + unsigned long end) +{ + numadbg(" reserve_range_in_node(nid[%d],start[%lx],end[%lx]\n", + nid, start, end); + while (start < end) { + unsigned long this_end; + int n; + + this_end = memblock_nid_range(start, end, &n); + if (n == nid) { + numadbg(" MATCH reserving range [%lx:%lx]\n", + start, this_end); + reserve_bootmem_node(NODE_DATA(nid), start, + (this_end - start), BOOTMEM_DEFAULT); + } else + numadbg(" NO MATCH, advancing start to %lx\n", + this_end); + + start = this_end; + } +} + +static void __init trim_reserved_in_node(int nid) +{ + struct memblock_region *reg; + + numadbg(" trim_reserved_in_node(%d)\n", nid); + + for_each_memblock(reserved, reg) + reserve_range_in_node(nid, reg->base, reg->base + reg->size); +} + +static void __init bootmem_init_one_node(int nid) +{ + struct pglist_data *p; + + numadbg("bootmem_init_one_node(%d)\n", nid); + + p = NODE_DATA(nid); + + if (p->node_spanned_pages) { + unsigned long paddr = node_masks[nid].bootmem_paddr; + unsigned long end_pfn; + + end_pfn = p->node_start_pfn + p->node_spanned_pages; + + numadbg(" init_bootmem_node(%d, %lx, %lx, %lx)\n", + nid, paddr >> PAGE_SHIFT, p->node_start_pfn, end_pfn); + + init_bootmem_node(p, paddr >> PAGE_SHIFT, + p->node_start_pfn, end_pfn); + + numadbg(" free_bootmem_with_active_regions(%d, %lx)\n", + nid, end_pfn); + free_bootmem_with_active_regions(nid, end_pfn); + + trim_reserved_in_node(nid); + + numadbg(" sparse_memory_present_with_active_regions(%d)\n", + nid); + sparse_memory_present_with_active_regions(nid); + } +} + static unsigned long __init bootmem_init(unsigned long phys_base) { unsigned long end_pfn; + int nid; end_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT; max_pfn = max_low_pfn = end_pfn; @@ -1285,12 +1369,11 @@ static unsigned long __init bootmem_init(unsigned long phys_base) if (bootmem_init_numa() < 0) bootmem_init_nonnuma(); - /* Dump memblock with node info. */ - memblock_dump_all(); - /* XXX cpu notifier XXX */ - sparse_memory_present_with_active_regions(MAX_NUMNODES); + for_each_online_node(nid) + bootmem_init_one_node(nid); + sparse_init(); return end_pfn; @@ -1618,7 +1701,6 @@ void __init paging_init(void) { unsigned long end_pfn, shift, phys_base; unsigned long real_end, i; - int node; /* These build time checkes make sure that the dcache_dirty_cpu() * page->flags usage will work. @@ -1744,24 +1826,22 @@ void __init paging_init(void) #endif } - /* Setup bootmem... */ - last_valid_pfn = end_pfn = bootmem_init(phys_base); - /* Once the OF device tree and MDESC have been setup, we know * the list of possible cpus. Therefore we can allocate the * IRQ stacks. */ for_each_possible_cpu(i) { - node = cpu_to_node(i); - - softirq_stack[i] = __alloc_bootmem_node(NODE_DATA(node), - THREAD_SIZE, - THREAD_SIZE, 0); - hardirq_stack[i] = __alloc_bootmem_node(NODE_DATA(node), - THREAD_SIZE, - THREAD_SIZE, 0); + /* XXX Use node local allocations... XXX */ + softirq_stack[i] = __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); + hardirq_stack[i] = __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); } + /* Setup bootmem... */ + last_valid_pfn = end_pfn = bootmem_init(phys_base); + +#ifndef CONFIG_NEED_MULTIPLE_NODES + max_mapnr = last_valid_pfn; +#endif kernel_physical_mapping_init(); { @@ -1893,7 +1973,6 @@ void __init mem_init(void) free_all_bootmem_node(NODE_DATA(i)); } } - totalram_pages += free_low_memory_core_early(MAX_NUMNODES); } #else totalram_pages = free_all_bootmem(); diff --git a/trunk/arch/sparc/mm/io-unit.c b/trunk/arch/sparc/mm/io-unit.c index eb99862e9654..fc58c3e917df 100644 --- a/trunk/arch/sparc/mm/io-unit.c +++ b/trunk/arch/sparc/mm/io-unit.c @@ -197,7 +197,7 @@ static void iounit_release_scsi_sgl(struct device *dev, struct scatterlist *sg, } #ifdef CONFIG_SBUS -static int iounit_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va, unsigned long addr, int len) +static int iounit_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va, __u32 addr, int len) { struct iounit_struct *iounit = dev->archdata.iommu; unsigned long page, end; @@ -242,18 +242,29 @@ static void iounit_unmap_dma_area(struct device *dev, unsigned long addr, int le } #endif -static const struct sparc32_dma_ops iounit_dma_ops = { - .get_scsi_one = iounit_get_scsi_one, - .get_scsi_sgl = iounit_get_scsi_sgl, - .release_scsi_one = iounit_release_scsi_one, - .release_scsi_sgl = iounit_release_scsi_sgl, -#ifdef CONFIG_SBUS - .map_dma_area = iounit_map_dma_area, - .unmap_dma_area = iounit_unmap_dma_area, -#endif -}; +static char *iounit_lockarea(char *vaddr, unsigned long len) +{ +/* FIXME: Write this */ + return vaddr; +} + +static void iounit_unlockarea(char *vaddr, unsigned long len) +{ +/* FIXME: Write this */ +} void __init ld_mmu_iounit(void) { - sparc32_dma_ops = &iounit_dma_ops; + BTFIXUPSET_CALL(mmu_lockarea, iounit_lockarea, BTFIXUPCALL_RETO0); + BTFIXUPSET_CALL(mmu_unlockarea, iounit_unlockarea, BTFIXUPCALL_NOP); + + BTFIXUPSET_CALL(mmu_get_scsi_one, iounit_get_scsi_one, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(mmu_get_scsi_sgl, iounit_get_scsi_sgl, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(mmu_release_scsi_one, iounit_release_scsi_one, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(mmu_release_scsi_sgl, iounit_release_scsi_sgl, BTFIXUPCALL_NORM); + +#ifdef CONFIG_SBUS + BTFIXUPSET_CALL(mmu_map_dma_area, iounit_map_dma_area, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(mmu_unmap_dma_area, iounit_unmap_dma_area, BTFIXUPCALL_NORM); +#endif } diff --git a/trunk/arch/sparc/mm/iommu.c b/trunk/arch/sparc/mm/iommu.c index a8a58cad9d2b..07fc6a65d9b6 100644 --- a/trunk/arch/sparc/mm/iommu.c +++ b/trunk/arch/sparc/mm/iommu.c @@ -39,6 +39,8 @@ /* srmmu.c */ extern int viking_mxcc_present; +BTFIXUPDEF_CALL(void, flush_page_for_dma, unsigned long) +#define flush_page_for_dma(page) BTFIXUP_CALL(flush_page_for_dma)(page) extern int flush_page_for_dma_global; static int viking_flush; /* viking.S */ @@ -141,6 +143,7 @@ static int __init iommu_init(void) subsys_initcall(iommu_init); +/* This begs to be btfixup-ed by srmmu. */ /* Flush the iotlb entries to ram. */ /* This could be better if we didn't have to flush whole pages. */ static void iommu_flush_iotlb(iopte_t *iopte, unsigned int niopte) @@ -213,6 +216,11 @@ static u32 iommu_get_scsi_one(struct device *dev, char *vaddr, unsigned int len) return busa + off; } +static __u32 iommu_get_scsi_one_noflush(struct device *dev, char *vaddr, unsigned long len) +{ + return iommu_get_scsi_one(dev, vaddr, len); +} + static __u32 iommu_get_scsi_one_gflush(struct device *dev, char *vaddr, unsigned long len) { flush_page_for_dma(0); @@ -230,6 +238,19 @@ static __u32 iommu_get_scsi_one_pflush(struct device *dev, char *vaddr, unsigned return iommu_get_scsi_one(dev, vaddr, len); } +static void iommu_get_scsi_sgl_noflush(struct device *dev, struct scatterlist *sg, int sz) +{ + int n; + + while (sz != 0) { + --sz; + n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; + sg->dma_address = iommu_get_one(dev, sg_page(sg), n) + sg->offset; + sg->dma_length = sg->length; + sg = sg_next(sg); + } +} + static void iommu_get_scsi_sgl_gflush(struct device *dev, struct scatterlist *sg, int sz) { int n; @@ -405,36 +426,40 @@ static void iommu_unmap_dma_area(struct device *dev, unsigned long busa, int len } #endif -static const struct sparc32_dma_ops iommu_dma_gflush_ops = { - .get_scsi_one = iommu_get_scsi_one_gflush, - .get_scsi_sgl = iommu_get_scsi_sgl_gflush, - .release_scsi_one = iommu_release_scsi_one, - .release_scsi_sgl = iommu_release_scsi_sgl, -#ifdef CONFIG_SBUS - .map_dma_area = iommu_map_dma_area, - .unmap_dma_area = iommu_unmap_dma_area, -#endif -}; +static char *iommu_lockarea(char *vaddr, unsigned long len) +{ + return vaddr; +} -static const struct sparc32_dma_ops iommu_dma_pflush_ops = { - .get_scsi_one = iommu_get_scsi_one_pflush, - .get_scsi_sgl = iommu_get_scsi_sgl_pflush, - .release_scsi_one = iommu_release_scsi_one, - .release_scsi_sgl = iommu_release_scsi_sgl, -#ifdef CONFIG_SBUS - .map_dma_area = iommu_map_dma_area, - .unmap_dma_area = iommu_unmap_dma_area, -#endif -}; +static void iommu_unlockarea(char *vaddr, unsigned long len) +{ +} void __init ld_mmu_iommu(void) { - if (flush_page_for_dma_global) { + viking_flush = (BTFIXUPVAL_CALL(flush_page_for_dma) == (unsigned long)viking_flush_page); + BTFIXUPSET_CALL(mmu_lockarea, iommu_lockarea, BTFIXUPCALL_RETO0); + BTFIXUPSET_CALL(mmu_unlockarea, iommu_unlockarea, BTFIXUPCALL_NOP); + + if (!BTFIXUPVAL_CALL(flush_page_for_dma)) { + /* IO coherent chip */ + BTFIXUPSET_CALL(mmu_get_scsi_one, iommu_get_scsi_one_noflush, BTFIXUPCALL_RETO0); + BTFIXUPSET_CALL(mmu_get_scsi_sgl, iommu_get_scsi_sgl_noflush, BTFIXUPCALL_NORM); + } else if (flush_page_for_dma_global) { /* flush_page_for_dma flushes everything, no matter of what page is it */ - sparc32_dma_ops = &iommu_dma_gflush_ops; + BTFIXUPSET_CALL(mmu_get_scsi_one, iommu_get_scsi_one_gflush, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(mmu_get_scsi_sgl, iommu_get_scsi_sgl_gflush, BTFIXUPCALL_NORM); } else { - sparc32_dma_ops = &iommu_dma_pflush_ops; + BTFIXUPSET_CALL(mmu_get_scsi_one, iommu_get_scsi_one_pflush, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(mmu_get_scsi_sgl, iommu_get_scsi_sgl_pflush, BTFIXUPCALL_NORM); } + BTFIXUPSET_CALL(mmu_release_scsi_one, iommu_release_scsi_one, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(mmu_release_scsi_sgl, iommu_release_scsi_sgl, BTFIXUPCALL_NORM); + +#ifdef CONFIG_SBUS + BTFIXUPSET_CALL(mmu_map_dma_area, iommu_map_dma_area, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(mmu_unmap_dma_area, iommu_unmap_dma_area, BTFIXUPCALL_NORM); +#endif if (viking_mxcc_present || srmmu_modtype == HyperSparc) { dvma_prot = __pgprot(SRMMU_CACHE | SRMMU_ET_PTE | SRMMU_PRIV); diff --git a/trunk/arch/sparc/mm/leon_mm.c b/trunk/arch/sparc/mm/leon_mm.c index 4c67ae6e5023..13c2169822a8 100644 --- a/trunk/arch/sparc/mm/leon_mm.c +++ b/trunk/arch/sparc/mm/leon_mm.c @@ -15,23 +15,9 @@ #include #include -#include "srmmu.h" - int leon_flush_during_switch = 1; int srmmu_swprobe_trace; -static inline unsigned long leon_get_ctable_ptr(void) -{ - unsigned int retval; - - __asm__ __volatile__("lda [%1] %2, %0\n\t" : - "=r" (retval) : - "r" (SRMMU_CTXTBL_PTR), - "i" (ASI_LEON_MMUREGS)); - return (retval & SRMMU_CTX_PMASK) << 4; -} - - unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr) { @@ -47,10 +33,10 @@ unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr) if (srmmu_swprobe_trace) printk(KERN_INFO "swprobe: trace on\n"); - ctxtbl = leon_get_ctable_ptr(); + ctxtbl = srmmu_get_ctable_ptr(); if (!(ctxtbl)) { if (srmmu_swprobe_trace) - printk(KERN_INFO "swprobe: leon_get_ctable_ptr returned 0=>0\n"); + printk(KERN_INFO "swprobe: srmmu_get_ctable_ptr returned 0=>0\n"); return 0; } if (!_pfn_valid(PFN(ctxtbl))) { @@ -272,80 +258,3 @@ void leon_switch_mm(void) if (leon_flush_during_switch) leon_flush_cache_all(); } - -static void leon_flush_cache_mm(struct mm_struct *mm) -{ - leon_flush_cache_all(); -} - -static void leon_flush_cache_page(struct vm_area_struct *vma, unsigned long page) -{ - leon_flush_pcache_all(vma, page); -} - -static void leon_flush_cache_range(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - leon_flush_cache_all(); -} - -static void leon_flush_tlb_mm(struct mm_struct *mm) -{ - leon_flush_tlb_all(); -} - -static void leon_flush_tlb_page(struct vm_area_struct *vma, - unsigned long page) -{ - leon_flush_tlb_all(); -} - -static void leon_flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - leon_flush_tlb_all(); -} - -static void leon_flush_page_to_ram(unsigned long page) -{ - leon_flush_cache_all(); -} - -static void leon_flush_sig_insns(struct mm_struct *mm, unsigned long page) -{ - leon_flush_cache_all(); -} - -static void leon_flush_page_for_dma(unsigned long page) -{ - leon_flush_dcache_all(); -} - -void __init poke_leonsparc(void) -{ -} - -static const struct sparc32_cachetlb_ops leon_ops = { - .cache_all = leon_flush_cache_all, - .cache_mm = leon_flush_cache_mm, - .cache_page = leon_flush_cache_page, - .cache_range = leon_flush_cache_range, - .tlb_all = leon_flush_tlb_all, - .tlb_mm = leon_flush_tlb_mm, - .tlb_page = leon_flush_tlb_page, - .tlb_range = leon_flush_tlb_range, - .page_to_ram = leon_flush_page_to_ram, - .sig_insns = leon_flush_sig_insns, - .page_for_dma = leon_flush_page_for_dma, -}; - -void __init init_leon(void) -{ - srmmu_name = "LEON"; - sparc32_cachetlb_ops = &leon_ops; - poke_srmmu = poke_leonsparc; - - leon_flush_during_switch = leon_flush_needed(); -} diff --git a/trunk/arch/sparc/mm/loadmmu.c b/trunk/arch/sparc/mm/loadmmu.c new file mode 100644 index 000000000000..c5bf2a6c3858 --- /dev/null +++ b/trunk/arch/sparc/mm/loadmmu.c @@ -0,0 +1,43 @@ +/* + * loadmmu.c: This code loads up all the mm function pointers once the + * machine type has been determined. It also sets the static + * mmu values such as PAGE_NONE, etc. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + */ + +#include +#include +#include + +#include +#include +#include +#include + +struct ctx_list *ctx_list_pool; +struct ctx_list ctx_free; +struct ctx_list ctx_used; + +extern void ld_mmu_sun4c(void); +extern void ld_mmu_srmmu(void); + +void __init load_mmu(void) +{ + switch(sparc_cpu_model) { + case sun4c: + case sun4: + ld_mmu_sun4c(); + break; + case sun4m: + case sun4d: + case sparc_leon: + ld_mmu_srmmu(); + break; + default: + prom_printf("load_mmu: %d unsupported\n", (int)sparc_cpu_model); + prom_halt(); + } + btfixup(); +} diff --git a/trunk/arch/sparc/mm/nosun4c.c b/trunk/arch/sparc/mm/nosun4c.c new file mode 100644 index 000000000000..4e62c27147c4 --- /dev/null +++ b/trunk/arch/sparc/mm/nosun4c.c @@ -0,0 +1,77 @@ +/* + * nosun4c.c: This file is a bunch of dummies for SMP compiles, + * so that it does not need sun4c and avoid ifdefs. + * + * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + */ + +#include +#include +#include +#include + +static char shouldnothappen[] __initdata = "32bit SMP kernel only supports sun4m and sun4d\n"; + +/* Dummies */ +struct sun4c_mmu_ring { + unsigned long xxx1[3]; + unsigned char xxx2[2]; + int xxx3; +}; +struct sun4c_mmu_ring sun4c_kernel_ring; +struct sun4c_mmu_ring sun4c_kfree_ring; +unsigned long sun4c_kernel_faults; +unsigned long *sun4c_memerr_reg; + +static void __init should_not_happen(void) +{ + prom_printf(shouldnothappen); + prom_halt(); +} + +unsigned long __init sun4c_paging_init(unsigned long start_mem, unsigned long end_mem) +{ + should_not_happen(); + return 0; +} + +void __init ld_mmu_sun4c(void) +{ + should_not_happen(); +} + +void sun4c_mapioaddr(unsigned long physaddr, unsigned long virt_addr, int bus_type, int rdonly) +{ +} + +void sun4c_unmapioaddr(unsigned long virt_addr) +{ +} + +void sun4c_complete_all_stores(void) +{ +} + +pte_t *sun4c_pte_offset(pmd_t * dir, unsigned long address) +{ + return NULL; +} + +pte_t *sun4c_pte_offset_kernel(pmd_t *dir, unsigned long address) +{ + return NULL; +} + +void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) +{ +} + +void __init sun4c_probe_vac(void) +{ + should_not_happen(); +} + +void __init sun4c_probe_memerr_reg(void) +{ + should_not_happen(); +} diff --git a/trunk/arch/sparc/mm/srmmu.c b/trunk/arch/sparc/mm/srmmu.c index 8e97e0305b01..cbef74e793b8 100644 --- a/trunk/arch/sparc/mm/srmmu.c +++ b/trunk/arch/sparc/mm/srmmu.c @@ -48,37 +48,39 @@ #include #include -#include "srmmu.h" +#include enum mbus_module srmmu_modtype; static unsigned int hwbug_bitmask; int vac_cache_size; int vac_line_size; -struct ctx_list *ctx_list_pool; -struct ctx_list ctx_free; -struct ctx_list ctx_used; - extern struct resource sparc_iomap; extern unsigned long last_valid_pfn; -static pgd_t *srmmu_swapper_pg_dir; +extern unsigned long page_kernel; -const struct sparc32_cachetlb_ops *sparc32_cachetlb_ops; +static pgd_t *srmmu_swapper_pg_dir; #ifdef CONFIG_SMP -const struct sparc32_cachetlb_ops *local_ops; - #define FLUSH_BEGIN(mm) #define FLUSH_END #else -#define FLUSH_BEGIN(mm) if ((mm)->context != NO_CONTEXT) { +#define FLUSH_BEGIN(mm) if((mm)->context != NO_CONTEXT) { #define FLUSH_END } #endif +BTFIXUPDEF_CALL(void, flush_page_for_dma, unsigned long) +#define flush_page_for_dma(page) BTFIXUP_CALL(flush_page_for_dma)(page) + int flush_page_for_dma_global = 1; +#ifdef CONFIG_SMP +BTFIXUPDEF_CALL(void, local_flush_page_for_dma, unsigned long) +#define local_flush_page_for_dma(page) BTFIXUP_CALL(local_flush_page_for_dma)(page) +#endif + char *srmmu_name; ctxd_t *srmmu_ctx_table_phys; @@ -89,6 +91,28 @@ static DEFINE_SPINLOCK(srmmu_context_spinlock); static int is_hypersparc; +/* + * In general all page table modifications should use the V8 atomic + * swap instruction. This insures the mmu and the cpu are in sync + * with respect to ref/mod bits in the page tables. + */ +static inline unsigned long srmmu_swap(unsigned long *addr, unsigned long value) +{ + __asm__ __volatile__("swap [%2], %0" : "=&r" (value) : "0" (value), "r" (addr)); + return value; +} + +static inline void srmmu_set_pte(pte_t *ptep, pte_t pteval) +{ + srmmu_swap((unsigned long *)ptep, pte_val(pteval)); +} + +/* The very generic SRMMU page table operations. */ +static inline int srmmu_device_memory(unsigned long x) +{ + return ((x & 0xF0000000) != 0); +} + static int srmmu_cache_pagetables; /* these will be initialized in srmmu_nocache_calcsize() */ @@ -105,39 +129,145 @@ void *srmmu_nocache_pool; void *srmmu_nocache_bitmap; static struct bit_map srmmu_nocache_map; +static unsigned long srmmu_pte_pfn(pte_t pte) +{ + if (srmmu_device_memory(pte_val(pte))) { + /* Just return something that will cause + * pfn_valid() to return false. This makes + * copy_one_pte() to just directly copy to + * PTE over. + */ + return ~0UL; + } + return (pte_val(pte) & SRMMU_PTE_PMASK) >> (PAGE_SHIFT-4); +} + +static struct page *srmmu_pmd_page(pmd_t pmd) +{ + + if (srmmu_device_memory(pmd_val(pmd))) + BUG(); + return pfn_to_page((pmd_val(pmd) & SRMMU_PTD_PMASK) >> (PAGE_SHIFT-4)); +} + +static inline unsigned long srmmu_pgd_page(pgd_t pgd) +{ return srmmu_device_memory(pgd_val(pgd))?~0:(unsigned long)__nocache_va((pgd_val(pgd) & SRMMU_PTD_PMASK) << 4); } + + +static inline int srmmu_pte_none(pte_t pte) +{ return !(pte_val(pte) & 0xFFFFFFF); } + +static inline int srmmu_pte_present(pte_t pte) +{ return ((pte_val(pte) & SRMMU_ET_MASK) == SRMMU_ET_PTE); } + +static inline void srmmu_pte_clear(pte_t *ptep) +{ srmmu_set_pte(ptep, __pte(0)); } + static inline int srmmu_pmd_none(pmd_t pmd) { return !(pmd_val(pmd) & 0xFFFFFFF); } +static inline int srmmu_pmd_bad(pmd_t pmd) +{ return (pmd_val(pmd) & SRMMU_ET_MASK) != SRMMU_ET_PTD; } + +static inline int srmmu_pmd_present(pmd_t pmd) +{ return ((pmd_val(pmd) & SRMMU_ET_MASK) == SRMMU_ET_PTD); } + +static inline void srmmu_pmd_clear(pmd_t *pmdp) { + int i; + for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++) + srmmu_set_pte((pte_t *)&pmdp->pmdv[i], __pte(0)); +} + +static inline int srmmu_pgd_none(pgd_t pgd) +{ return !(pgd_val(pgd) & 0xFFFFFFF); } + +static inline int srmmu_pgd_bad(pgd_t pgd) +{ return (pgd_val(pgd) & SRMMU_ET_MASK) != SRMMU_ET_PTD; } + +static inline int srmmu_pgd_present(pgd_t pgd) +{ return ((pgd_val(pgd) & SRMMU_ET_MASK) == SRMMU_ET_PTD); } + +static inline void srmmu_pgd_clear(pgd_t * pgdp) +{ srmmu_set_pte((pte_t *)pgdp, __pte(0)); } + +static inline pte_t srmmu_pte_wrprotect(pte_t pte) +{ return __pte(pte_val(pte) & ~SRMMU_WRITE);} + +static inline pte_t srmmu_pte_mkclean(pte_t pte) +{ return __pte(pte_val(pte) & ~SRMMU_DIRTY);} + +static inline pte_t srmmu_pte_mkold(pte_t pte) +{ return __pte(pte_val(pte) & ~SRMMU_REF);} + +static inline pte_t srmmu_pte_mkwrite(pte_t pte) +{ return __pte(pte_val(pte) | SRMMU_WRITE);} + +static inline pte_t srmmu_pte_mkdirty(pte_t pte) +{ return __pte(pte_val(pte) | SRMMU_DIRTY);} + +static inline pte_t srmmu_pte_mkyoung(pte_t pte) +{ return __pte(pte_val(pte) | SRMMU_REF);} + +/* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + */ +static pte_t srmmu_mk_pte(struct page *page, pgprot_t pgprot) +{ return __pte((page_to_pfn(page) << (PAGE_SHIFT-4)) | pgprot_val(pgprot)); } + +static pte_t srmmu_mk_pte_phys(unsigned long page, pgprot_t pgprot) +{ return __pte(((page) >> 4) | pgprot_val(pgprot)); } + +static pte_t srmmu_mk_pte_io(unsigned long page, pgprot_t pgprot, int space) +{ return __pte(((page) >> 4) | (space << 28) | pgprot_val(pgprot)); } + /* XXX should we hyper_flush_whole_icache here - Anton */ static inline void srmmu_ctxd_set(ctxd_t *ctxp, pgd_t *pgdp) -{ set_pte((pte_t *)ctxp, (SRMMU_ET_PTD | (__nocache_pa((unsigned long) pgdp) >> 4))); } +{ srmmu_set_pte((pte_t *)ctxp, (SRMMU_ET_PTD | (__nocache_pa((unsigned long) pgdp) >> 4))); } -void pmd_set(pmd_t *pmdp, pte_t *ptep) +static inline void srmmu_pgd_set(pgd_t * pgdp, pmd_t * pmdp) +{ srmmu_set_pte((pte_t *)pgdp, (SRMMU_ET_PTD | (__nocache_pa((unsigned long) pmdp) >> 4))); } + +static void srmmu_pmd_set(pmd_t *pmdp, pte_t *ptep) { unsigned long ptp; /* Physical address, shifted right by 4 */ int i; ptp = __nocache_pa((unsigned long) ptep) >> 4; for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++) { - set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp); + srmmu_set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp); ptp += (SRMMU_REAL_PTRS_PER_PTE*sizeof(pte_t) >> 4); } } -void pmd_populate(struct mm_struct *mm, pmd_t *pmdp, struct page *ptep) +static void srmmu_pmd_populate(pmd_t *pmdp, struct page *ptep) { unsigned long ptp; /* Physical address, shifted right by 4 */ int i; ptp = page_to_pfn(ptep) << (PAGE_SHIFT-4); /* watch for overflow */ for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++) { - set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp); + srmmu_set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp); ptp += (SRMMU_REAL_PTRS_PER_PTE*sizeof(pte_t) >> 4); } } +static inline pte_t srmmu_pte_modify(pte_t pte, pgprot_t newprot) +{ return __pte((pte_val(pte) & SRMMU_CHG_MASK) | pgprot_val(newprot)); } + +/* to find an entry in a top-level page table... */ +static inline pgd_t *srmmu_pgd_offset(struct mm_struct * mm, unsigned long address) +{ return mm->pgd + (address >> SRMMU_PGDIR_SHIFT); } + +/* Find an entry in the second-level page table.. */ +static inline pmd_t *srmmu_pmd_offset(pgd_t * dir, unsigned long address) +{ + return (pmd_t *) srmmu_pgd_page(*dir) + + ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1)); +} + /* Find an entry in the third-level page table.. */ -pte_t *pte_offset_kernel(pmd_t * dir, unsigned long address) +static inline pte_t *srmmu_pte_offset(pmd_t * dir, unsigned long address) { void *pte; @@ -146,6 +276,23 @@ pte_t *pte_offset_kernel(pmd_t * dir, unsigned long address) ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); } +static unsigned long srmmu_swp_type(swp_entry_t entry) +{ + return (entry.val >> SRMMU_SWP_TYPE_SHIFT) & SRMMU_SWP_TYPE_MASK; +} + +static unsigned long srmmu_swp_offset(swp_entry_t entry) +{ + return (entry.val >> SRMMU_SWP_OFF_SHIFT) & SRMMU_SWP_OFF_MASK; +} + +static swp_entry_t srmmu_swp_entry(unsigned long type, unsigned long offset) +{ + return (swp_entry_t) { + (type & SRMMU_SWP_TYPE_MASK) << SRMMU_SWP_TYPE_SHIFT + | (offset & SRMMU_SWP_OFF_MASK) << SRMMU_SWP_OFF_SHIFT }; +} + /* * size: bytes to allocate in the nocache area. * align: bytes, number to align at. @@ -178,7 +325,7 @@ static unsigned long __srmmu_get_nocache(int size, int align) return (SRMMU_NOCACHE_VADDR + (offset << SRMMU_NOCACHE_BITMAP_SHIFT)); } -unsigned long srmmu_get_nocache(int size, int align) +static unsigned long srmmu_get_nocache(int size, int align) { unsigned long tmp; @@ -190,7 +337,7 @@ unsigned long srmmu_get_nocache(int size, int align) return tmp; } -void srmmu_free_nocache(unsigned long vaddr, int size) +static void srmmu_free_nocache(unsigned long vaddr, int size) { int offset; @@ -282,15 +429,15 @@ static void __init srmmu_nocache_init(void) while (vaddr < srmmu_nocache_end) { pgd = pgd_offset_k(vaddr); - pmd = pmd_offset(__nocache_fix(pgd), vaddr); - pte = pte_offset_kernel(__nocache_fix(pmd), vaddr); + pmd = srmmu_pmd_offset(__nocache_fix(pgd), vaddr); + pte = srmmu_pte_offset(__nocache_fix(pmd), vaddr); pteval = ((paddr >> 4) | SRMMU_ET_PTE | SRMMU_PRIV); if (srmmu_cache_pagetables) pteval |= SRMMU_CACHE; - set_pte(__nocache_fix(pte), __pte(pteval)); + srmmu_set_pte(__nocache_fix(pte), __pte(pteval)); vaddr += PAGE_SIZE; paddr += PAGE_SIZE; @@ -300,7 +447,7 @@ static void __init srmmu_nocache_init(void) flush_tlb_all(); } -pgd_t *get_pgd_fast(void) +static inline pgd_t *srmmu_get_pgd_fast(void) { pgd_t *pgd = NULL; @@ -315,6 +462,21 @@ pgd_t *get_pgd_fast(void) return pgd; } +static void srmmu_free_pgd_fast(pgd_t *pgd) +{ + srmmu_free_nocache((unsigned long)pgd, SRMMU_PGD_TABLE_SIZE); +} + +static pmd_t *srmmu_pmd_alloc_one(struct mm_struct *mm, unsigned long address) +{ + return (pmd_t *)srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE); +} + +static void srmmu_pmd_free(pmd_t * pmd) +{ + srmmu_free_nocache((unsigned long)pmd, SRMMU_PMD_TABLE_SIZE); +} + /* * Hardware needs alignment to 256 only, but we align to whole page size * to reduce fragmentation problems due to the buddy principle. @@ -323,19 +485,31 @@ pgd_t *get_pgd_fast(void) * Alignments up to the page size are the same for physical and virtual * addresses of the nocache area. */ -pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) +static pte_t * +srmmu_pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) +{ + return (pte_t *)srmmu_get_nocache(PTE_SIZE, PTE_SIZE); +} + +static pgtable_t +srmmu_pte_alloc_one(struct mm_struct *mm, unsigned long address) { unsigned long pte; struct page *page; - if ((pte = (unsigned long)pte_alloc_one_kernel(mm, address)) == 0) + if ((pte = (unsigned long)srmmu_pte_alloc_one_kernel(mm, address)) == 0) return NULL; page = pfn_to_page( __nocache_pa(pte) >> PAGE_SHIFT ); pgtable_page_ctor(page); return page; } -void pte_free(struct mm_struct *mm, pgtable_t pte) +static void srmmu_free_pte_fast(pte_t *pte) +{ + srmmu_free_nocache((unsigned long)pte, PTE_SIZE); +} + +static void srmmu_pte_free(pgtable_t pte) { unsigned long p; @@ -386,8 +560,8 @@ static inline void free_context(int context) } -void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, - struct task_struct *tsk) +static void srmmu_switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, + struct task_struct *tsk, int cpu) { if(mm->context == NO_CONTEXT) { spin_lock(&srmmu_context_spinlock); @@ -416,8 +590,8 @@ static inline void srmmu_mapioaddr(unsigned long physaddr, physaddr &= PAGE_MASK; pgdp = pgd_offset_k(virt_addr); - pmdp = pmd_offset(pgdp, virt_addr); - ptep = pte_offset_kernel(pmdp, virt_addr); + pmdp = srmmu_pmd_offset(pgdp, virt_addr); + ptep = srmmu_pte_offset(pmdp, virt_addr); tmp = (physaddr >> 4) | SRMMU_ET_PTE; /* @@ -428,11 +602,11 @@ static inline void srmmu_mapioaddr(unsigned long physaddr, tmp |= (bus_type << 28); tmp |= SRMMU_PRIV; __flush_page_to_ram(virt_addr); - set_pte(ptep, __pte(tmp)); + srmmu_set_pte(ptep, __pte(tmp)); } -void srmmu_mapiorange(unsigned int bus, unsigned long xpa, - unsigned long xva, unsigned int len) +static void srmmu_mapiorange(unsigned int bus, unsigned long xpa, + unsigned long xva, unsigned int len) { while (len != 0) { len -= PAGE_SIZE; @@ -450,14 +624,14 @@ static inline void srmmu_unmapioaddr(unsigned long virt_addr) pte_t *ptep; pgdp = pgd_offset_k(virt_addr); - pmdp = pmd_offset(pgdp, virt_addr); - ptep = pte_offset_kernel(pmdp, virt_addr); + pmdp = srmmu_pmd_offset(pgdp, virt_addr); + ptep = srmmu_pte_offset(pmdp, virt_addr); /* No need to flush uncacheable page. */ - __pte_clear(ptep); + srmmu_pte_clear(ptep); } -void srmmu_unmapiorange(unsigned long virt_addr, unsigned int len) +static void srmmu_unmapiorange(unsigned long virt_addr, unsigned int len) { while (len != 0) { len -= PAGE_SIZE; @@ -473,9 +647,10 @@ void srmmu_unmapiorange(unsigned long virt_addr, unsigned int len) * pool. As a side effect we are putting a little too much pressure * on the gfp() subsystem. This setup also makes the logic of the * iommu mapping code a lot easier as we can transparently handle - * mappings on the kernel stack without any special code. + * mappings on the kernel stack without any special code as we did + * need on the sun4c. */ -struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node) +static struct thread_info *srmmu_alloc_thread_info_node(int node) { struct thread_info *ret; @@ -489,7 +664,7 @@ struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node) return ret; } -void free_thread_info(struct thread_info *ti) +static void srmmu_free_thread_info(struct thread_info *ti) { free_pages((unsigned long)ti, THREAD_INFO_ORDER); } @@ -508,6 +683,38 @@ extern void tsunami_flush_tlb_range(struct vm_area_struct *vma, unsigned long st extern void tsunami_flush_tlb_page(struct vm_area_struct *vma, unsigned long page); extern void tsunami_setup_blockops(void); +/* + * Workaround, until we find what's going on with Swift. When low on memory, + * it sometimes loops in fault/handle_mm_fault incl. flush_tlb_page to find + * out it is already in page tables/ fault again on the same instruction. + * I really don't understand it, have checked it and contexts + * are right, flush_tlb_all is done as well, and it faults again... + * Strange. -jj + * + * The following code is a deadwood that may be necessary when + * we start to make precise page flushes again. --zaitcev + */ +static void swift_update_mmu_cache(struct vm_area_struct * vma, unsigned long address, pte_t *ptep) +{ +#if 0 + static unsigned long last; + unsigned int val; + /* unsigned int n; */ + + if (address == last) { + val = srmmu_hwprobe(address); + if (val != 0 && pte_val(*ptep) != val) { + printk("swift_update_mmu_cache: " + "addr %lx put %08x probed %08x from %p\n", + address, pte_val(*ptep), val, + __builtin_return_address(0)); + srmmu_flush_whole_tlb(); + } + } + last = address; +#endif +} + /* swift.S */ extern void swift_flush_cache_all(void); extern void swift_flush_cache_mm(struct mm_struct *mm); @@ -560,6 +767,244 @@ void swift_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) * with respect to cache coherency. */ +/* Cypress flushes. */ +static void cypress_flush_cache_all(void) +{ + volatile unsigned long cypress_sucks; + unsigned long faddr, tagval; + + flush_user_windows(); + for(faddr = 0; faddr < 0x10000; faddr += 0x20) { + __asm__ __volatile__("lda [%1 + %2] %3, %0\n\t" : + "=r" (tagval) : + "r" (faddr), "r" (0x40000), + "i" (ASI_M_DATAC_TAG)); + + /* If modified and valid, kick it. */ + if((tagval & 0x60) == 0x60) + cypress_sucks = *(unsigned long *)(0xf0020000 + faddr); + } +} + +static void cypress_flush_cache_mm(struct mm_struct *mm) +{ + register unsigned long a, b, c, d, e, f, g; + unsigned long flags, faddr; + int octx; + + FLUSH_BEGIN(mm) + flush_user_windows(); + local_irq_save(flags); + octx = srmmu_get_context(); + srmmu_set_context(mm->context); + a = 0x20; b = 0x40; c = 0x60; + d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0; + + faddr = (0x10000 - 0x100); + goto inside; + do { + faddr -= 0x100; + inside: + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" + "sta %%g0, [%0 + %2] %1\n\t" + "sta %%g0, [%0 + %3] %1\n\t" + "sta %%g0, [%0 + %4] %1\n\t" + "sta %%g0, [%0 + %5] %1\n\t" + "sta %%g0, [%0 + %6] %1\n\t" + "sta %%g0, [%0 + %7] %1\n\t" + "sta %%g0, [%0 + %8] %1\n\t" : : + "r" (faddr), "i" (ASI_M_FLUSH_CTX), + "r" (a), "r" (b), "r" (c), "r" (d), + "r" (e), "r" (f), "r" (g)); + } while(faddr); + srmmu_set_context(octx); + local_irq_restore(flags); + FLUSH_END +} + +static void cypress_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + register unsigned long a, b, c, d, e, f, g; + unsigned long flags, faddr; + int octx; + + FLUSH_BEGIN(mm) + flush_user_windows(); + local_irq_save(flags); + octx = srmmu_get_context(); + srmmu_set_context(mm->context); + a = 0x20; b = 0x40; c = 0x60; + d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0; + + start &= SRMMU_REAL_PMD_MASK; + while(start < end) { + faddr = (start + (0x10000 - 0x100)); + goto inside; + do { + faddr -= 0x100; + inside: + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" + "sta %%g0, [%0 + %2] %1\n\t" + "sta %%g0, [%0 + %3] %1\n\t" + "sta %%g0, [%0 + %4] %1\n\t" + "sta %%g0, [%0 + %5] %1\n\t" + "sta %%g0, [%0 + %6] %1\n\t" + "sta %%g0, [%0 + %7] %1\n\t" + "sta %%g0, [%0 + %8] %1\n\t" : : + "r" (faddr), + "i" (ASI_M_FLUSH_SEG), + "r" (a), "r" (b), "r" (c), "r" (d), + "r" (e), "r" (f), "r" (g)); + } while (faddr != start); + start += SRMMU_REAL_PMD_SIZE; + } + srmmu_set_context(octx); + local_irq_restore(flags); + FLUSH_END +} + +static void cypress_flush_cache_page(struct vm_area_struct *vma, unsigned long page) +{ + register unsigned long a, b, c, d, e, f, g; + struct mm_struct *mm = vma->vm_mm; + unsigned long flags, line; + int octx; + + FLUSH_BEGIN(mm) + flush_user_windows(); + local_irq_save(flags); + octx = srmmu_get_context(); + srmmu_set_context(mm->context); + a = 0x20; b = 0x40; c = 0x60; + d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0; + + page &= PAGE_MASK; + line = (page + PAGE_SIZE) - 0x100; + goto inside; + do { + line -= 0x100; + inside: + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" + "sta %%g0, [%0 + %2] %1\n\t" + "sta %%g0, [%0 + %3] %1\n\t" + "sta %%g0, [%0 + %4] %1\n\t" + "sta %%g0, [%0 + %5] %1\n\t" + "sta %%g0, [%0 + %6] %1\n\t" + "sta %%g0, [%0 + %7] %1\n\t" + "sta %%g0, [%0 + %8] %1\n\t" : : + "r" (line), + "i" (ASI_M_FLUSH_PAGE), + "r" (a), "r" (b), "r" (c), "r" (d), + "r" (e), "r" (f), "r" (g)); + } while(line != page); + srmmu_set_context(octx); + local_irq_restore(flags); + FLUSH_END +} + +/* Cypress is copy-back, at least that is how we configure it. */ +static void cypress_flush_page_to_ram(unsigned long page) +{ + register unsigned long a, b, c, d, e, f, g; + unsigned long line; + + a = 0x20; b = 0x40; c = 0x60; d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0; + page &= PAGE_MASK; + line = (page + PAGE_SIZE) - 0x100; + goto inside; + do { + line -= 0x100; + inside: + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" + "sta %%g0, [%0 + %2] %1\n\t" + "sta %%g0, [%0 + %3] %1\n\t" + "sta %%g0, [%0 + %4] %1\n\t" + "sta %%g0, [%0 + %5] %1\n\t" + "sta %%g0, [%0 + %6] %1\n\t" + "sta %%g0, [%0 + %7] %1\n\t" + "sta %%g0, [%0 + %8] %1\n\t" : : + "r" (line), + "i" (ASI_M_FLUSH_PAGE), + "r" (a), "r" (b), "r" (c), "r" (d), + "r" (e), "r" (f), "r" (g)); + } while(line != page); +} + +/* Cypress is also IO cache coherent. */ +static void cypress_flush_page_for_dma(unsigned long page) +{ +} + +/* Cypress has unified L2 VIPT, from which both instructions and data + * are stored. It does not have an onboard icache of any sort, therefore + * no flush is necessary. + */ +static void cypress_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr) +{ +} + +static void cypress_flush_tlb_all(void) +{ + srmmu_flush_whole_tlb(); +} + +static void cypress_flush_tlb_mm(struct mm_struct *mm) +{ + FLUSH_BEGIN(mm) + __asm__ __volatile__( + "lda [%0] %3, %%g5\n\t" + "sta %2, [%0] %3\n\t" + "sta %%g0, [%1] %4\n\t" + "sta %%g5, [%0] %3\n" + : /* no outputs */ + : "r" (SRMMU_CTX_REG), "r" (0x300), "r" (mm->context), + "i" (ASI_M_MMUREGS), "i" (ASI_M_FLUSH_PROBE) + : "g5"); + FLUSH_END +} + +static void cypress_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + unsigned long size; + + FLUSH_BEGIN(mm) + start &= SRMMU_PGDIR_MASK; + size = SRMMU_PGDIR_ALIGN(end) - start; + __asm__ __volatile__( + "lda [%0] %5, %%g5\n\t" + "sta %1, [%0] %5\n" + "1:\n\t" + "subcc %3, %4, %3\n\t" + "bne 1b\n\t" + " sta %%g0, [%2 + %3] %6\n\t" + "sta %%g5, [%0] %5\n" + : /* no outputs */ + : "r" (SRMMU_CTX_REG), "r" (mm->context), "r" (start | 0x200), + "r" (size), "r" (SRMMU_PGDIR_SIZE), "i" (ASI_M_MMUREGS), + "i" (ASI_M_FLUSH_PROBE) + : "g5", "cc"); + FLUSH_END +} + +static void cypress_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +{ + struct mm_struct *mm = vma->vm_mm; + + FLUSH_BEGIN(mm) + __asm__ __volatile__( + "lda [%0] %3, %%g5\n\t" + "sta %1, [%0] %3\n\t" + "sta %%g0, [%2] %4\n\t" + "sta %%g5, [%0] %3\n" + : /* no outputs */ + : "r" (SRMMU_CTX_REG), "r" (mm->context), "r" (page & PAGE_MASK), + "i" (ASI_M_MMUREGS), "i" (ASI_M_FLUSH_PROBE) + : "g5"); + FLUSH_END +} + /* viking.S */ extern void viking_flush_cache_all(void); extern void viking_flush_cache_mm(struct mm_struct *mm); @@ -620,21 +1065,21 @@ static void __init srmmu_early_allocate_ptable_skeleton(unsigned long start, while(start < end) { pgdp = pgd_offset_k(start); - if (pgd_none(*(pgd_t *)__nocache_fix(pgdp))) { + if(srmmu_pgd_none(*(pgd_t *)__nocache_fix(pgdp))) { pmdp = (pmd_t *) __srmmu_get_nocache( SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE); if (pmdp == NULL) early_pgtable_allocfail("pmd"); memset(__nocache_fix(pmdp), 0, SRMMU_PMD_TABLE_SIZE); - pgd_set(__nocache_fix(pgdp), pmdp); + srmmu_pgd_set(__nocache_fix(pgdp), pmdp); } - pmdp = pmd_offset(__nocache_fix(pgdp), start); + pmdp = srmmu_pmd_offset(__nocache_fix(pgdp), start); if(srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) { ptep = (pte_t *)__srmmu_get_nocache(PTE_SIZE, PTE_SIZE); if (ptep == NULL) early_pgtable_allocfail("pte"); memset(__nocache_fix(ptep), 0, PTE_SIZE); - pmd_set(__nocache_fix(pmdp), ptep); + srmmu_pmd_set(__nocache_fix(pmdp), ptep); } if (start > (0xffffffffUL - PMD_SIZE)) break; @@ -651,21 +1096,21 @@ static void __init srmmu_allocate_ptable_skeleton(unsigned long start, while(start < end) { pgdp = pgd_offset_k(start); - if (pgd_none(*pgdp)) { + if(srmmu_pgd_none(*pgdp)) { pmdp = (pmd_t *)__srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE); if (pmdp == NULL) early_pgtable_allocfail("pmd"); memset(pmdp, 0, SRMMU_PMD_TABLE_SIZE); - pgd_set(pgdp, pmdp); + srmmu_pgd_set(pgdp, pmdp); } - pmdp = pmd_offset(pgdp, start); + pmdp = srmmu_pmd_offset(pgdp, start); if(srmmu_pmd_none(*pmdp)) { ptep = (pte_t *) __srmmu_get_nocache(PTE_SIZE, PTE_SIZE); if (ptep == NULL) early_pgtable_allocfail("pte"); memset(ptep, 0, PTE_SIZE); - pmd_set(pmdp, ptep); + srmmu_pmd_set(pmdp, ptep); } if (start > (0xffffffffUL - PMD_SIZE)) break; @@ -717,21 +1162,21 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start, start += SRMMU_PGDIR_SIZE; continue; } - if (pgd_none(*(pgd_t *)__nocache_fix(pgdp))) { + if(srmmu_pgd_none(*(pgd_t *)__nocache_fix(pgdp))) { pmdp = (pmd_t *)__srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE); if (pmdp == NULL) early_pgtable_allocfail("pmd"); memset(__nocache_fix(pmdp), 0, SRMMU_PMD_TABLE_SIZE); - pgd_set(__nocache_fix(pgdp), pmdp); + srmmu_pgd_set(__nocache_fix(pgdp), pmdp); } - pmdp = pmd_offset(__nocache_fix(pgdp), start); + pmdp = srmmu_pmd_offset(__nocache_fix(pgdp), start); if(srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) { ptep = (pte_t *) __srmmu_get_nocache(PTE_SIZE, PTE_SIZE); if (ptep == NULL) early_pgtable_allocfail("pte"); memset(__nocache_fix(ptep), 0, PTE_SIZE); - pmd_set(__nocache_fix(pmdp), ptep); + srmmu_pmd_set(__nocache_fix(pmdp), ptep); } if(what == 1) { /* @@ -745,7 +1190,7 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start, start += SRMMU_REAL_PMD_SIZE; continue; } - ptep = pte_offset_kernel(__nocache_fix(pmdp), start); + ptep = srmmu_pte_offset(__nocache_fix(pmdp), start); *(pte_t *)__nocache_fix(ptep) = __pte(prompte); start += PAGE_SIZE; } @@ -786,6 +1231,13 @@ static unsigned long __init map_spbank(unsigned long vbase, int sp_entry) return vstart; } +static inline void memprobe_error(char *msg) +{ + prom_printf(msg); + prom_printf("Halting now...\n"); + prom_halt(); +} + static inline void map_kernel(void) { int i; @@ -797,6 +1249,8 @@ static inline void map_kernel(void) for (i = 0; sp_banks[i].num_bytes != 0; i++) { map_spbank((unsigned long)__va(sp_banks[i].base_addr), i); } + + BTFIXUPSET_SIMM13(user_ptrs_per_pgd, PAGE_OFFSET / SRMMU_PGDIR_SIZE); } /* Paging initialization on the Sparc Reference MMU. */ @@ -858,7 +1312,7 @@ void __init srmmu_paging_init(void) srmmu_set_ctable_ptr((unsigned long)srmmu_ctx_table_phys); #ifdef CONFIG_SMP /* Stop from hanging here... */ - local_ops->tlb_all(); + local_flush_tlb_all(); #else flush_tlb_all(); #endif @@ -872,8 +1326,8 @@ void __init srmmu_paging_init(void) srmmu_allocate_ptable_skeleton(PKMAP_BASE, PKMAP_END); pgd = pgd_offset_k(PKMAP_BASE); - pmd = pmd_offset(pgd, PKMAP_BASE); - pte = pte_offset_kernel(pmd, PKMAP_BASE); + pmd = srmmu_pmd_offset(pgd, PKMAP_BASE); + pte = srmmu_pte_offset(pmd, PKMAP_BASE); pkmap_page_table = pte; flush_cache_all(); @@ -905,7 +1359,7 @@ void __init srmmu_paging_init(void) } } -void mmu_info(struct seq_file *m) +static void srmmu_mmu_info(struct seq_file *m) { seq_printf(m, "MMU type\t: %s\n" @@ -918,7 +1372,11 @@ void mmu_info(struct seq_file *m) srmmu_nocache_map.used << SRMMU_NOCACHE_BITMAP_SHIFT); } -void destroy_context(struct mm_struct *mm) +static void srmmu_update_mmu_cache(struct vm_area_struct * vma, unsigned long address, pte_t pte) +{ +} + +static void srmmu_destroy_context(struct mm_struct *mm) { if(mm->context != NO_CONTEXT) { @@ -1016,20 +1474,6 @@ static void __cpuinit poke_hypersparc(void) clear = srmmu_get_fstatus(); } -static const struct sparc32_cachetlb_ops hypersparc_ops = { - .cache_all = hypersparc_flush_cache_all, - .cache_mm = hypersparc_flush_cache_mm, - .cache_page = hypersparc_flush_cache_page, - .cache_range = hypersparc_flush_cache_range, - .tlb_all = hypersparc_flush_tlb_all, - .tlb_mm = hypersparc_flush_tlb_mm, - .tlb_page = hypersparc_flush_tlb_page, - .tlb_range = hypersparc_flush_tlb_range, - .page_to_ram = hypersparc_flush_page_to_ram, - .sig_insns = hypersparc_flush_sig_insns, - .page_for_dma = hypersparc_flush_page_for_dma, -}; - static void __init init_hypersparc(void) { srmmu_name = "ROSS HyperSparc"; @@ -1038,13 +1482,118 @@ static void __init init_hypersparc(void) init_vac_layout(); is_hypersparc = 1; - sparc32_cachetlb_ops = &hypersparc_ops; + + BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pmd_clear, srmmu_pmd_clear, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pgd_clear, srmmu_pgd_clear, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_all, hypersparc_flush_cache_all, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_mm, hypersparc_flush_cache_mm, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_range, hypersparc_flush_cache_range, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_page, hypersparc_flush_cache_page, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(flush_tlb_all, hypersparc_flush_tlb_all, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_mm, hypersparc_flush_tlb_mm, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_range, hypersparc_flush_tlb_range, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_page, hypersparc_flush_tlb_page, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(__flush_page_to_ram, hypersparc_flush_page_to_ram, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_sig_insns, hypersparc_flush_sig_insns, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_page_for_dma, hypersparc_flush_page_for_dma, BTFIXUPCALL_NOP); + poke_srmmu = poke_hypersparc; hypersparc_setup_blockops(); } +static void __cpuinit poke_cypress(void) +{ + unsigned long mreg = srmmu_get_mmureg(); + unsigned long faddr, tagval; + volatile unsigned long cypress_sucks; + volatile unsigned long clear; + + clear = srmmu_get_faddr(); + clear = srmmu_get_fstatus(); + + if (!(mreg & CYPRESS_CENABLE)) { + for(faddr = 0x0; faddr < 0x10000; faddr += 20) { + __asm__ __volatile__("sta %%g0, [%0 + %1] %2\n\t" + "sta %%g0, [%0] %2\n\t" : : + "r" (faddr), "r" (0x40000), + "i" (ASI_M_DATAC_TAG)); + } + } else { + for(faddr = 0; faddr < 0x10000; faddr += 0x20) { + __asm__ __volatile__("lda [%1 + %2] %3, %0\n\t" : + "=r" (tagval) : + "r" (faddr), "r" (0x40000), + "i" (ASI_M_DATAC_TAG)); + + /* If modified and valid, kick it. */ + if((tagval & 0x60) == 0x60) + cypress_sucks = *(unsigned long *) + (0xf0020000 + faddr); + } + } + + /* And one more, for our good neighbor, Mr. Broken Cypress. */ + clear = srmmu_get_faddr(); + clear = srmmu_get_fstatus(); + + mreg |= (CYPRESS_CENABLE | CYPRESS_CMODE); + srmmu_set_mmureg(mreg); +} + +static void __init init_cypress_common(void) +{ + init_vac_layout(); + + BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pmd_clear, srmmu_pmd_clear, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pgd_clear, srmmu_pgd_clear, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_all, cypress_flush_cache_all, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_mm, cypress_flush_cache_mm, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_range, cypress_flush_cache_range, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_page, cypress_flush_cache_page, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(flush_tlb_all, cypress_flush_tlb_all, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_mm, cypress_flush_tlb_mm, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_page, cypress_flush_tlb_page, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_range, cypress_flush_tlb_range, BTFIXUPCALL_NORM); + + + BTFIXUPSET_CALL(__flush_page_to_ram, cypress_flush_page_to_ram, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_sig_insns, cypress_flush_sig_insns, BTFIXUPCALL_NOP); + BTFIXUPSET_CALL(flush_page_for_dma, cypress_flush_page_for_dma, BTFIXUPCALL_NOP); + + poke_srmmu = poke_cypress; +} + +static void __init init_cypress_604(void) +{ + srmmu_name = "ROSS Cypress-604(UP)"; + srmmu_modtype = Cypress; + init_cypress_common(); +} + +static void __init init_cypress_605(unsigned long mrev) +{ + srmmu_name = "ROSS Cypress-605(MP)"; + if(mrev == 0xe) { + srmmu_modtype = Cypress_vE; + hwbug_bitmask |= HWBUG_COPYBACK_BROKEN; + } else { + if(mrev == 0xd) { + srmmu_modtype = Cypress_vD; + hwbug_bitmask |= HWBUG_ASIFLUSH_BROKEN; + } else { + srmmu_modtype = Cypress; + } + } + init_cypress_common(); +} + static void __cpuinit poke_swift(void) { unsigned long mreg; @@ -1068,20 +1617,6 @@ static void __cpuinit poke_swift(void) srmmu_set_mmureg(mreg); } -static const struct sparc32_cachetlb_ops swift_ops = { - .cache_all = swift_flush_cache_all, - .cache_mm = swift_flush_cache_mm, - .cache_page = swift_flush_cache_page, - .cache_range = swift_flush_cache_range, - .tlb_all = swift_flush_tlb_all, - .tlb_mm = swift_flush_tlb_mm, - .tlb_page = swift_flush_tlb_page, - .tlb_range = swift_flush_tlb_range, - .page_to_ram = swift_flush_page_to_ram, - .sig_insns = swift_flush_sig_insns, - .page_for_dma = swift_flush_page_for_dma, -}; - #define SWIFT_MASKID_ADDR 0x10003018 static void __init init_swift(void) { @@ -1132,7 +1667,23 @@ static void __init init_swift(void) break; } - sparc32_cachetlb_ops = &swift_ops; + BTFIXUPSET_CALL(flush_cache_all, swift_flush_cache_all, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_mm, swift_flush_cache_mm, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_page, swift_flush_cache_page, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_range, swift_flush_cache_range, BTFIXUPCALL_NORM); + + + BTFIXUPSET_CALL(flush_tlb_all, swift_flush_tlb_all, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_mm, swift_flush_tlb_mm, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_page, swift_flush_tlb_page, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_range, swift_flush_tlb_range, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(__flush_page_to_ram, swift_flush_page_to_ram, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_sig_insns, swift_flush_sig_insns, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_page_for_dma, swift_flush_page_for_dma, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(update_mmu_cache, swift_update_mmu_cache, BTFIXUPCALL_NORM); + flush_page_for_dma_global = 0; /* @@ -1265,25 +1816,26 @@ static void __cpuinit poke_turbosparc(void) srmmu_set_mmureg(mreg); } -static const struct sparc32_cachetlb_ops turbosparc_ops = { - .cache_all = turbosparc_flush_cache_all, - .cache_mm = turbosparc_flush_cache_mm, - .cache_page = turbosparc_flush_cache_page, - .cache_range = turbosparc_flush_cache_range, - .tlb_all = turbosparc_flush_tlb_all, - .tlb_mm = turbosparc_flush_tlb_mm, - .tlb_page = turbosparc_flush_tlb_page, - .tlb_range = turbosparc_flush_tlb_range, - .page_to_ram = turbosparc_flush_page_to_ram, - .sig_insns = turbosparc_flush_sig_insns, - .page_for_dma = turbosparc_flush_page_for_dma, -}; - static void __init init_turbosparc(void) { srmmu_name = "Fujitsu TurboSparc"; srmmu_modtype = TurboSparc; - sparc32_cachetlb_ops = &turbosparc_ops; + + BTFIXUPSET_CALL(flush_cache_all, turbosparc_flush_cache_all, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_mm, turbosparc_flush_cache_mm, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_page, turbosparc_flush_cache_page, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_range, turbosparc_flush_cache_range, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(flush_tlb_all, turbosparc_flush_tlb_all, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_mm, turbosparc_flush_tlb_mm, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_page, turbosparc_flush_tlb_page, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_range, turbosparc_flush_tlb_range, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(__flush_page_to_ram, turbosparc_flush_page_to_ram, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(flush_sig_insns, turbosparc_flush_sig_insns, BTFIXUPCALL_NOP); + BTFIXUPSET_CALL(flush_page_for_dma, turbosparc_flush_page_for_dma, BTFIXUPCALL_NORM); + poke_srmmu = poke_turbosparc; } @@ -1298,20 +1850,6 @@ static void __cpuinit poke_tsunami(void) srmmu_set_mmureg(mreg); } -static const struct sparc32_cachetlb_ops tsunami_ops = { - .cache_all = tsunami_flush_cache_all, - .cache_mm = tsunami_flush_cache_mm, - .cache_page = tsunami_flush_cache_page, - .cache_range = tsunami_flush_cache_range, - .tlb_all = tsunami_flush_tlb_all, - .tlb_mm = tsunami_flush_tlb_mm, - .tlb_page = tsunami_flush_tlb_page, - .tlb_range = tsunami_flush_tlb_range, - .page_to_ram = tsunami_flush_page_to_ram, - .sig_insns = tsunami_flush_sig_insns, - .page_for_dma = tsunami_flush_page_for_dma, -}; - static void __init init_tsunami(void) { /* @@ -1322,7 +1860,22 @@ static void __init init_tsunami(void) srmmu_name = "TI Tsunami"; srmmu_modtype = Tsunami; - sparc32_cachetlb_ops = &tsunami_ops; + + BTFIXUPSET_CALL(flush_cache_all, tsunami_flush_cache_all, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_mm, tsunami_flush_cache_mm, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_page, tsunami_flush_cache_page, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_range, tsunami_flush_cache_range, BTFIXUPCALL_NORM); + + + BTFIXUPSET_CALL(flush_tlb_all, tsunami_flush_tlb_all, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_mm, tsunami_flush_tlb_mm, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_page, tsunami_flush_tlb_page, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_range, tsunami_flush_tlb_range, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(__flush_page_to_ram, tsunami_flush_page_to_ram, BTFIXUPCALL_NOP); + BTFIXUPSET_CALL(flush_sig_insns, tsunami_flush_sig_insns, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_page_for_dma, tsunami_flush_page_for_dma, BTFIXUPCALL_NORM); + poke_srmmu = poke_tsunami; tsunami_setup_blockops(); @@ -1333,7 +1886,7 @@ static void __cpuinit poke_viking(void) unsigned long mreg = srmmu_get_mmureg(); static int smp_catch; - if (viking_mxcc_present) { + if(viking_mxcc_present) { unsigned long mxcc_control = mxcc_get_creg(); mxcc_control |= (MXCC_CTL_ECE | MXCC_CTL_PRE | MXCC_CTL_MCE); @@ -1370,52 +1923,6 @@ static void __cpuinit poke_viking(void) srmmu_set_mmureg(mreg); } -static struct sparc32_cachetlb_ops viking_ops = { - .cache_all = viking_flush_cache_all, - .cache_mm = viking_flush_cache_mm, - .cache_page = viking_flush_cache_page, - .cache_range = viking_flush_cache_range, - .tlb_all = viking_flush_tlb_all, - .tlb_mm = viking_flush_tlb_mm, - .tlb_page = viking_flush_tlb_page, - .tlb_range = viking_flush_tlb_range, - .page_to_ram = viking_flush_page_to_ram, - .sig_insns = viking_flush_sig_insns, - .page_for_dma = viking_flush_page_for_dma, -}; - -#ifdef CONFIG_SMP -/* On sun4d the cpu broadcasts local TLB flushes, so we can just - * perform the local TLB flush and all the other cpus will see it. - * But, unfortunately, there is a bug in the sun4d XBUS backplane - * that requires that we add some synchronization to these flushes. - * - * The bug is that the fifo which keeps track of all the pending TLB - * broadcasts in the system is an entry or two too small, so if we - * have too many going at once we'll overflow that fifo and lose a TLB - * flush resulting in corruption. - * - * Our workaround is to take a global spinlock around the TLB flushes, - * which guarentees we won't ever have too many pending. It's a big - * hammer, but a semaphore like system to make sure we only have N TLB - * flushes going at once will require SMP locking anyways so there's - * no real value in trying any harder than this. - */ -static struct sparc32_cachetlb_ops viking_sun4d_smp_ops = { - .cache_all = viking_flush_cache_all, - .cache_mm = viking_flush_cache_mm, - .cache_page = viking_flush_cache_page, - .cache_range = viking_flush_cache_range, - .tlb_all = sun4dsmp_flush_tlb_all, - .tlb_mm = sun4dsmp_flush_tlb_mm, - .tlb_page = sun4dsmp_flush_tlb_page, - .tlb_range = sun4dsmp_flush_tlb_range, - .page_to_ram = viking_flush_page_to_ram, - .sig_insns = viking_flush_sig_insns, - .page_for_dma = viking_flush_page_for_dma, -}; -#endif - static void __init init_viking(void) { unsigned long mreg = srmmu_get_mmureg(); @@ -1426,6 +1933,10 @@ static void __init init_viking(void) viking_mxcc_present = 0; msi_set_sync(); + BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pmd_clear, srmmu_pmd_clear, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pgd_clear, srmmu_pgd_clear, BTFIXUPCALL_NORM); + /* * We need this to make sure old viking takes no hits * on it's cache for dma snoops to workaround the @@ -1433,28 +1944,84 @@ static void __init init_viking(void) * This is only necessary because of the new way in * which we use the IOMMU. */ - viking_ops.page_for_dma = viking_flush_page; -#ifdef CONFIG_SMP - viking_sun4d_smp_ops.page_for_dma = viking_flush_page; -#endif + BTFIXUPSET_CALL(flush_page_for_dma, viking_flush_page, BTFIXUPCALL_NORM); + flush_page_for_dma_global = 0; } else { srmmu_name = "TI Viking/MXCC"; viking_mxcc_present = 1; + srmmu_cache_pagetables = 1; + + /* MXCC vikings lack the DMA snooping bug. */ + BTFIXUPSET_CALL(flush_page_for_dma, viking_flush_page_for_dma, BTFIXUPCALL_NOP); } - sparc32_cachetlb_ops = (const struct sparc32_cachetlb_ops *) - &viking_ops; + BTFIXUPSET_CALL(flush_cache_all, viking_flush_cache_all, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_mm, viking_flush_cache_mm, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_page, viking_flush_cache_page, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_range, viking_flush_cache_range, BTFIXUPCALL_NORM); + #ifdef CONFIG_SMP - if (sparc_cpu_model == sun4d) - sparc32_cachetlb_ops = (const struct sparc32_cachetlb_ops *) - &viking_sun4d_smp_ops; + if (sparc_cpu_model == sun4d) { + BTFIXUPSET_CALL(flush_tlb_all, sun4dsmp_flush_tlb_all, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_mm, sun4dsmp_flush_tlb_mm, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_page, sun4dsmp_flush_tlb_page, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_range, sun4dsmp_flush_tlb_range, BTFIXUPCALL_NORM); + } else #endif + { + BTFIXUPSET_CALL(flush_tlb_all, viking_flush_tlb_all, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_mm, viking_flush_tlb_mm, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_page, viking_flush_tlb_page, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_range, viking_flush_tlb_range, BTFIXUPCALL_NORM); + } + + BTFIXUPSET_CALL(__flush_page_to_ram, viking_flush_page_to_ram, BTFIXUPCALL_NOP); + BTFIXUPSET_CALL(flush_sig_insns, viking_flush_sig_insns, BTFIXUPCALL_NOP); poke_srmmu = poke_viking; } +#ifdef CONFIG_SPARC_LEON + +void __init poke_leonsparc(void) +{ +} + +void __init init_leon(void) +{ + + srmmu_name = "LEON"; + + BTFIXUPSET_CALL(flush_cache_all, leon_flush_cache_all, + BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_mm, leon_flush_cache_all, + BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_page, leon_flush_pcache_all, + BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_range, leon_flush_cache_all, + BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_page_for_dma, leon_flush_dcache_all, + BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(flush_tlb_all, leon_flush_tlb_all, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_mm, leon_flush_tlb_all, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_page, leon_flush_tlb_all, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_range, leon_flush_tlb_all, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(__flush_page_to_ram, leon_flush_cache_all, + BTFIXUPCALL_NOP); + BTFIXUPSET_CALL(flush_sig_insns, leon_flush_cache_all, BTFIXUPCALL_NOP); + + poke_srmmu = poke_leonsparc; + + srmmu_cache_pagetables = 0; + + leon_flush_during_switch = leon_flush_needed(); +} +#endif + /* Probe for the srmmu chip version. */ static void __init get_srmmu_type(void) { @@ -1485,15 +2052,22 @@ static void __init get_srmmu_type(void) break; case 0: case 2: + /* Uniprocessor Cypress */ + init_cypress_604(); + break; case 10: case 11: case 12: + /* _REALLY OLD_ Cypress MP chips... */ case 13: case 14: case 15: + /* MP Cypress mmu/cache-controller */ + init_cypress_605(mod_rev); + break; default: - prom_printf("Sparc-Linux Cypress support does not longer exit.\n"); - prom_halt(); + /* Some other Cypress revision, assume a 605. */ + init_cypress_605(mod_rev); break; } return; @@ -1549,193 +2123,203 @@ static void __init get_srmmu_type(void) srmmu_is_bad(); } -#ifdef CONFIG_SMP -/* Local cross-calls. */ -static void smp_flush_page_for_dma(unsigned long page) +/* don't laugh, static pagetables */ +static void srmmu_check_pgt_cache(int low, int high) { - xc1((smpfunc_t) local_ops->page_for_dma, page); - local_ops->page_for_dma(page); } -static void smp_flush_cache_all(void) -{ - xc0((smpfunc_t) local_ops->cache_all); - local_ops->cache_all(); -} +extern unsigned long spwin_mmu_patchme, fwin_mmu_patchme, + tsetup_mmu_patchme, rtrap_mmu_patchme; -static void smp_flush_tlb_all(void) -{ - xc0((smpfunc_t) local_ops->tlb_all); - local_ops->tlb_all(); -} +extern unsigned long spwin_srmmu_stackchk, srmmu_fwin_stackchk, + tsetup_srmmu_stackchk, srmmu_rett_stackchk; -static void smp_flush_cache_mm(struct mm_struct *mm) -{ - if (mm->context != NO_CONTEXT) { - cpumask_t cpu_mask; - cpumask_copy(&cpu_mask, mm_cpumask(mm)); - cpumask_clear_cpu(smp_processor_id(), &cpu_mask); - if (!cpumask_empty(&cpu_mask)) - xc1((smpfunc_t) local_ops->cache_mm, (unsigned long) mm); - local_ops->cache_mm(mm); - } -} +extern unsigned long srmmu_fault; -static void smp_flush_tlb_mm(struct mm_struct *mm) +#define PATCH_BRANCH(insn, dest) do { \ + iaddr = &(insn); \ + daddr = &(dest); \ + *iaddr = SPARC_BRANCH((unsigned long) daddr, (unsigned long) iaddr); \ + } while(0) + +static void __init patch_window_trap_handlers(void) { - if (mm->context != NO_CONTEXT) { - cpumask_t cpu_mask; - cpumask_copy(&cpu_mask, mm_cpumask(mm)); - cpumask_clear_cpu(smp_processor_id(), &cpu_mask); - if (!cpumask_empty(&cpu_mask)) { - xc1((smpfunc_t) local_ops->tlb_mm, (unsigned long) mm); - if (atomic_read(&mm->mm_users) == 1 && current->active_mm == mm) - cpumask_copy(mm_cpumask(mm), - cpumask_of(smp_processor_id())); - } - local_ops->tlb_mm(mm); - } + unsigned long *iaddr, *daddr; + + PATCH_BRANCH(spwin_mmu_patchme, spwin_srmmu_stackchk); + PATCH_BRANCH(fwin_mmu_patchme, srmmu_fwin_stackchk); + PATCH_BRANCH(tsetup_mmu_patchme, tsetup_srmmu_stackchk); + PATCH_BRANCH(rtrap_mmu_patchme, srmmu_rett_stackchk); + PATCH_BRANCH(sparc_ttable[SP_TRAP_TFLT].inst_three, srmmu_fault); + PATCH_BRANCH(sparc_ttable[SP_TRAP_DFLT].inst_three, srmmu_fault); + PATCH_BRANCH(sparc_ttable[SP_TRAP_DACC].inst_three, srmmu_fault); } -static void smp_flush_cache_range(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) +#ifdef CONFIG_SMP +/* Local cross-calls. */ +static void smp_flush_page_for_dma(unsigned long page) { - struct mm_struct *mm = vma->vm_mm; - - if (mm->context != NO_CONTEXT) { - cpumask_t cpu_mask; - cpumask_copy(&cpu_mask, mm_cpumask(mm)); - cpumask_clear_cpu(smp_processor_id(), &cpu_mask); - if (!cpumask_empty(&cpu_mask)) - xc3((smpfunc_t) local_ops->cache_range, - (unsigned long) vma, start, end); - local_ops->cache_range(vma, start, end); - } + xc1((smpfunc_t) BTFIXUP_CALL(local_flush_page_for_dma), page); + local_flush_page_for_dma(page); } -static void smp_flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; +#endif - if (mm->context != NO_CONTEXT) { - cpumask_t cpu_mask; - cpumask_copy(&cpu_mask, mm_cpumask(mm)); - cpumask_clear_cpu(smp_processor_id(), &cpu_mask); - if (!cpumask_empty(&cpu_mask)) - xc3((smpfunc_t) local_ops->tlb_range, - (unsigned long) vma, start, end); - local_ops->tlb_range(vma, start, end); - } +static pte_t srmmu_pgoff_to_pte(unsigned long pgoff) +{ + return __pte((pgoff << SRMMU_PTE_FILE_SHIFT) | SRMMU_FILE); } -static void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page) +static unsigned long srmmu_pte_to_pgoff(pte_t pte) { - struct mm_struct *mm = vma->vm_mm; - - if (mm->context != NO_CONTEXT) { - cpumask_t cpu_mask; - cpumask_copy(&cpu_mask, mm_cpumask(mm)); - cpumask_clear_cpu(smp_processor_id(), &cpu_mask); - if (!cpumask_empty(&cpu_mask)) - xc2((smpfunc_t) local_ops->cache_page, - (unsigned long) vma, page); - local_ops->cache_page(vma, page); - } + return pte_val(pte) >> SRMMU_PTE_FILE_SHIFT; } -static void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +static pgprot_t srmmu_pgprot_noncached(pgprot_t prot) { - struct mm_struct *mm = vma->vm_mm; + prot &= ~__pgprot(SRMMU_CACHE); - if (mm->context != NO_CONTEXT) { - cpumask_t cpu_mask; - cpumask_copy(&cpu_mask, mm_cpumask(mm)); - cpumask_clear_cpu(smp_processor_id(), &cpu_mask); - if (!cpumask_empty(&cpu_mask)) - xc2((smpfunc_t) local_ops->tlb_page, - (unsigned long) vma, page); - local_ops->tlb_page(vma, page); - } + return prot; } -static void smp_flush_page_to_ram(unsigned long page) -{ - /* Current theory is that those who call this are the one's - * who have just dirtied their cache with the pages contents - * in kernel space, therefore we only run this on local cpu. - * - * XXX This experiment failed, research further... -DaveM - */ -#if 1 - xc1((smpfunc_t) local_ops->page_to_ram, page); -#endif - local_ops->page_to_ram(page); -} - -static void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr) -{ - cpumask_t cpu_mask; - cpumask_copy(&cpu_mask, mm_cpumask(mm)); - cpumask_clear_cpu(smp_processor_id(), &cpu_mask); - if (!cpumask_empty(&cpu_mask)) - xc2((smpfunc_t) local_ops->sig_insns, - (unsigned long) mm, insn_addr); - local_ops->sig_insns(mm, insn_addr); -} - -static struct sparc32_cachetlb_ops smp_cachetlb_ops = { - .cache_all = smp_flush_cache_all, - .cache_mm = smp_flush_cache_mm, - .cache_page = smp_flush_cache_page, - .cache_range = smp_flush_cache_range, - .tlb_all = smp_flush_tlb_all, - .tlb_mm = smp_flush_tlb_mm, - .tlb_page = smp_flush_tlb_page, - .tlb_range = smp_flush_tlb_range, - .page_to_ram = smp_flush_page_to_ram, - .sig_insns = smp_flush_sig_insns, - .page_for_dma = smp_flush_page_for_dma, -}; -#endif - /* Load up routines and constants for sun4m and sun4d mmu */ -void __init load_mmu(void) +void __init ld_mmu_srmmu(void) { extern void ld_mmu_iommu(void); extern void ld_mmu_iounit(void); + extern void ___xchg32_sun4md(void); + + BTFIXUPSET_SIMM13(pgdir_shift, SRMMU_PGDIR_SHIFT); + BTFIXUPSET_SETHI(pgdir_size, SRMMU_PGDIR_SIZE); + BTFIXUPSET_SETHI(pgdir_mask, SRMMU_PGDIR_MASK); + + BTFIXUPSET_SIMM13(ptrs_per_pmd, SRMMU_PTRS_PER_PMD); + BTFIXUPSET_SIMM13(ptrs_per_pgd, SRMMU_PTRS_PER_PGD); + + BTFIXUPSET_INT(page_none, pgprot_val(SRMMU_PAGE_NONE)); + PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED); + BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY)); + BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY)); + BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL)); + page_kernel = pgprot_val(SRMMU_PAGE_KERNEL); /* Functions */ + BTFIXUPSET_CALL(pgprot_noncached, srmmu_pgprot_noncached, BTFIXUPCALL_NORM); +#ifndef CONFIG_SMP + BTFIXUPSET_CALL(___xchg32, ___xchg32_sun4md, BTFIXUPCALL_SWAPG1G2); +#endif + BTFIXUPSET_CALL(do_check_pgt_cache, srmmu_check_pgt_cache, BTFIXUPCALL_NOP); + + BTFIXUPSET_CALL(set_pte, srmmu_set_pte, BTFIXUPCALL_SWAPO0O1); + BTFIXUPSET_CALL(switch_mm, srmmu_switch_mm, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(pte_pfn, srmmu_pte_pfn, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pmd_page, srmmu_pmd_page, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pgd_page_vaddr, srmmu_pgd_page, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(pte_present, srmmu_pte_present, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_SWAPO0G0); + + BTFIXUPSET_CALL(pmd_bad, srmmu_pmd_bad, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pmd_present, srmmu_pmd_present, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pmd_clear, srmmu_pmd_clear, BTFIXUPCALL_SWAPO0G0); + + BTFIXUPSET_CALL(pgd_none, srmmu_pgd_none, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pgd_bad, srmmu_pgd_bad, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pgd_present, srmmu_pgd_present, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pgd_clear, srmmu_pgd_clear, BTFIXUPCALL_SWAPO0G0); + + BTFIXUPSET_CALL(mk_pte, srmmu_mk_pte, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(mk_pte_phys, srmmu_mk_pte_phys, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(mk_pte_io, srmmu_mk_pte_io, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pgd_set, srmmu_pgd_set, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pmd_set, srmmu_pmd_set, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pmd_populate, srmmu_pmd_populate, BTFIXUPCALL_NORM); + + BTFIXUPSET_INT(pte_modify_mask, SRMMU_CHG_MASK); + BTFIXUPSET_CALL(pmd_offset, srmmu_pmd_offset, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pte_offset_kernel, srmmu_pte_offset, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(free_pte_fast, srmmu_free_pte_fast, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pte_free, srmmu_pte_free, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pte_alloc_one_kernel, srmmu_pte_alloc_one_kernel, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pte_alloc_one, srmmu_pte_alloc_one, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(free_pmd_fast, srmmu_pmd_free, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pmd_alloc_one, srmmu_pmd_alloc_one, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(free_pgd_fast, srmmu_free_pgd_fast, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(get_pgd_fast, srmmu_get_pgd_fast, BTFIXUPCALL_NORM); + + BTFIXUPSET_HALF(pte_writei, SRMMU_WRITE); + BTFIXUPSET_HALF(pte_dirtyi, SRMMU_DIRTY); + BTFIXUPSET_HALF(pte_youngi, SRMMU_REF); + BTFIXUPSET_HALF(pte_filei, SRMMU_FILE); + BTFIXUPSET_HALF(pte_wrprotecti, SRMMU_WRITE); + BTFIXUPSET_HALF(pte_mkcleani, SRMMU_DIRTY); + BTFIXUPSET_HALF(pte_mkoldi, SRMMU_REF); + BTFIXUPSET_CALL(pte_mkwrite, srmmu_pte_mkwrite, BTFIXUPCALL_ORINT(SRMMU_WRITE)); + BTFIXUPSET_CALL(pte_mkdirty, srmmu_pte_mkdirty, BTFIXUPCALL_ORINT(SRMMU_DIRTY)); + BTFIXUPSET_CALL(pte_mkyoung, srmmu_pte_mkyoung, BTFIXUPCALL_ORINT(SRMMU_REF)); + BTFIXUPSET_CALL(update_mmu_cache, srmmu_update_mmu_cache, BTFIXUPCALL_NOP); + BTFIXUPSET_CALL(destroy_context, srmmu_destroy_context, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(sparc_mapiorange, srmmu_mapiorange, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(sparc_unmapiorange, srmmu_unmapiorange, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(__swp_type, srmmu_swp_type, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(__swp_offset, srmmu_swp_offset, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(__swp_entry, srmmu_swp_entry, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(mmu_info, srmmu_mmu_info, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(alloc_thread_info_node, srmmu_alloc_thread_info_node, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(free_thread_info, srmmu_free_thread_info, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(pte_to_pgoff, srmmu_pte_to_pgoff, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pgoff_to_pte, srmmu_pgoff_to_pte, BTFIXUPCALL_NORM); + get_srmmu_type(); + patch_window_trap_handlers(); #ifdef CONFIG_SMP /* El switcheroo... */ - local_ops = sparc32_cachetlb_ops; - if (sparc_cpu_model == sun4d || sparc_cpu_model == sparc_leon) { - smp_cachetlb_ops.tlb_all = local_ops->tlb_all; - smp_cachetlb_ops.tlb_mm = local_ops->tlb_mm; - smp_cachetlb_ops.tlb_range = local_ops->tlb_range; - smp_cachetlb_ops.tlb_page = local_ops->tlb_page; + BTFIXUPCOPY_CALL(local_flush_cache_all, flush_cache_all); + BTFIXUPCOPY_CALL(local_flush_cache_mm, flush_cache_mm); + BTFIXUPCOPY_CALL(local_flush_cache_range, flush_cache_range); + BTFIXUPCOPY_CALL(local_flush_cache_page, flush_cache_page); + BTFIXUPCOPY_CALL(local_flush_tlb_all, flush_tlb_all); + BTFIXUPCOPY_CALL(local_flush_tlb_mm, flush_tlb_mm); + BTFIXUPCOPY_CALL(local_flush_tlb_range, flush_tlb_range); + BTFIXUPCOPY_CALL(local_flush_tlb_page, flush_tlb_page); + BTFIXUPCOPY_CALL(local_flush_page_to_ram, __flush_page_to_ram); + BTFIXUPCOPY_CALL(local_flush_sig_insns, flush_sig_insns); + BTFIXUPCOPY_CALL(local_flush_page_for_dma, flush_page_for_dma); + + BTFIXUPSET_CALL(flush_cache_all, smp_flush_cache_all, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_mm, smp_flush_cache_mm, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_range, smp_flush_cache_range, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_page, smp_flush_cache_page, BTFIXUPCALL_NORM); + if (sparc_cpu_model != sun4d && + sparc_cpu_model != sparc_leon) { + BTFIXUPSET_CALL(flush_tlb_all, smp_flush_tlb_all, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_mm, smp_flush_tlb_mm, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_range, smp_flush_tlb_range, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_page, smp_flush_tlb_page, BTFIXUPCALL_NORM); } + BTFIXUPSET_CALL(__flush_page_to_ram, smp_flush_page_to_ram, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_sig_insns, smp_flush_sig_insns, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_page_for_dma, smp_flush_page_for_dma, BTFIXUPCALL_NORM); if (poke_srmmu == poke_viking) { /* Avoid unnecessary cross calls. */ - smp_cachetlb_ops.cache_all = local_ops->cache_all; - smp_cachetlb_ops.cache_mm = local_ops->cache_mm; - smp_cachetlb_ops.cache_range = local_ops->cache_range; - smp_cachetlb_ops.cache_page = local_ops->cache_page; - - smp_cachetlb_ops.page_to_ram = local_ops->page_to_ram; - smp_cachetlb_ops.sig_insns = local_ops->sig_insns; - smp_cachetlb_ops.page_for_dma = local_ops->page_for_dma; + BTFIXUPCOPY_CALL(flush_cache_all, local_flush_cache_all); + BTFIXUPCOPY_CALL(flush_cache_mm, local_flush_cache_mm); + BTFIXUPCOPY_CALL(flush_cache_range, local_flush_cache_range); + BTFIXUPCOPY_CALL(flush_cache_page, local_flush_cache_page); + BTFIXUPCOPY_CALL(__flush_page_to_ram, local_flush_page_to_ram); + BTFIXUPCOPY_CALL(flush_sig_insns, local_flush_sig_insns); + BTFIXUPCOPY_CALL(flush_page_for_dma, local_flush_page_for_dma); } - - /* It really is const after this point. */ - sparc32_cachetlb_ops = (const struct sparc32_cachetlb_ops *) - &smp_cachetlb_ops; #endif if (sparc_cpu_model == sun4d) diff --git a/trunk/arch/sparc/mm/srmmu.h b/trunk/arch/sparc/mm/srmmu.h deleted file mode 100644 index 5703274ccf89..000000000000 --- a/trunk/arch/sparc/mm/srmmu.h +++ /dev/null @@ -1,4 +0,0 @@ -/* srmmu.c */ -extern char *srmmu_name; - -extern void (*poke_srmmu)(void); diff --git a/trunk/arch/sparc/mm/sun4c.c b/trunk/arch/sparc/mm/sun4c.c new file mode 100644 index 000000000000..1cf4f198709a --- /dev/null +++ b/trunk/arch/sparc/mm/sun4c.c @@ -0,0 +1,2166 @@ +/* sun4c.c: Doing in software what should be done in hardware. + * + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) + * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) + * Copyright (C) 1996 Andrew Tridgell (Andrew.Tridgell@anu.edu.au) + * Copyright (C) 1997-2000 Anton Blanchard (anton@samba.org) + * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + */ + +#define NR_TASK_BUCKETS 512 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Because of our dynamic kernel TLB miss strategy, and how + * our DVMA mapping allocation works, you _MUST_: + * + * 1) Disable interrupts _and_ not touch any dynamic kernel + * memory while messing with kernel MMU state. By + * dynamic memory I mean any object which is not in + * the kernel image itself or a thread_union (both of + * which are locked into the MMU). + * 2) Disable interrupts while messing with user MMU state. + */ + +extern int num_segmaps, num_contexts; + +extern unsigned long page_kernel; + +/* That's it, we prom_halt() on sun4c if the cache size is something other than 65536. + * So let's save some cycles and just use that everywhere except for that bootup + * sanity check. + */ +#define SUN4C_VAC_SIZE 65536 + +#define SUN4C_KERNEL_BUCKETS 32 + +/* Flushing the cache. */ +struct sun4c_vac_props sun4c_vacinfo; +unsigned long sun4c_kernel_faults; + +/* Invalidate every sun4c cache line tag. */ +static void __init sun4c_flush_all(void) +{ + unsigned long begin, end; + + if (sun4c_vacinfo.on) + panic("SUN4C: AIEEE, trying to invalidate vac while it is on."); + + /* Clear 'valid' bit in all cache line tags */ + begin = AC_CACHETAGS; + end = (AC_CACHETAGS + SUN4C_VAC_SIZE); + while (begin < end) { + __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : + "r" (begin), "i" (ASI_CONTROL)); + begin += sun4c_vacinfo.linesize; + } +} + +static void sun4c_flush_context_hw(void) +{ + unsigned long end = SUN4C_VAC_SIZE; + + __asm__ __volatile__( + "1: addcc %0, -4096, %0\n\t" + " bne 1b\n\t" + " sta %%g0, [%0] %2" + : "=&r" (end) + : "0" (end), "i" (ASI_HWFLUSHCONTEXT) + : "cc"); +} + +/* Must be called minimally with IRQs disabled. */ +static void sun4c_flush_segment_hw(unsigned long addr) +{ + if (sun4c_get_segmap(addr) != invalid_segment) { + unsigned long vac_size = SUN4C_VAC_SIZE; + + __asm__ __volatile__( + "1: addcc %0, -4096, %0\n\t" + " bne 1b\n\t" + " sta %%g0, [%2 + %0] %3" + : "=&r" (vac_size) + : "0" (vac_size), "r" (addr), "i" (ASI_HWFLUSHSEG) + : "cc"); + } +} + +/* File local boot time fixups. */ +BTFIXUPDEF_CALL(void, sun4c_flush_page, unsigned long) +BTFIXUPDEF_CALL(void, sun4c_flush_segment, unsigned long) +BTFIXUPDEF_CALL(void, sun4c_flush_context, void) + +#define sun4c_flush_page(addr) BTFIXUP_CALL(sun4c_flush_page)(addr) +#define sun4c_flush_segment(addr) BTFIXUP_CALL(sun4c_flush_segment)(addr) +#define sun4c_flush_context() BTFIXUP_CALL(sun4c_flush_context)() + +/* Must be called minimally with interrupts disabled. */ +static void sun4c_flush_page_hw(unsigned long addr) +{ + addr &= PAGE_MASK; + if ((int)sun4c_get_pte(addr) < 0) + __asm__ __volatile__("sta %%g0, [%0] %1" + : : "r" (addr), "i" (ASI_HWFLUSHPAGE)); +} + +/* Don't inline the software version as it eats too many cache lines if expanded. */ +static void sun4c_flush_context_sw(void) +{ + unsigned long nbytes = SUN4C_VAC_SIZE; + unsigned long lsize = sun4c_vacinfo.linesize; + + __asm__ __volatile__( + "add %2, %2, %%g1\n\t" + "add %2, %%g1, %%g2\n\t" + "add %2, %%g2, %%g3\n\t" + "add %2, %%g3, %%g4\n\t" + "add %2, %%g4, %%g5\n\t" + "add %2, %%g5, %%o4\n\t" + "add %2, %%o4, %%o5\n" + "1:\n\t" + "subcc %0, %%o5, %0\n\t" + "sta %%g0, [%0] %3\n\t" + "sta %%g0, [%0 + %2] %3\n\t" + "sta %%g0, [%0 + %%g1] %3\n\t" + "sta %%g0, [%0 + %%g2] %3\n\t" + "sta %%g0, [%0 + %%g3] %3\n\t" + "sta %%g0, [%0 + %%g4] %3\n\t" + "sta %%g0, [%0 + %%g5] %3\n\t" + "bg 1b\n\t" + " sta %%g0, [%1 + %%o4] %3\n" + : "=&r" (nbytes) + : "0" (nbytes), "r" (lsize), "i" (ASI_FLUSHCTX) + : "g1", "g2", "g3", "g4", "g5", "o4", "o5", "cc"); +} + +/* Don't inline the software version as it eats too many cache lines if expanded. */ +static void sun4c_flush_segment_sw(unsigned long addr) +{ + if (sun4c_get_segmap(addr) != invalid_segment) { + unsigned long nbytes = SUN4C_VAC_SIZE; + unsigned long lsize = sun4c_vacinfo.linesize; + + __asm__ __volatile__( + "add %2, %2, %%g1\n\t" + "add %2, %%g1, %%g2\n\t" + "add %2, %%g2, %%g3\n\t" + "add %2, %%g3, %%g4\n\t" + "add %2, %%g4, %%g5\n\t" + "add %2, %%g5, %%o4\n\t" + "add %2, %%o4, %%o5\n" + "1:\n\t" + "subcc %1, %%o5, %1\n\t" + "sta %%g0, [%0] %6\n\t" + "sta %%g0, [%0 + %2] %6\n\t" + "sta %%g0, [%0 + %%g1] %6\n\t" + "sta %%g0, [%0 + %%g2] %6\n\t" + "sta %%g0, [%0 + %%g3] %6\n\t" + "sta %%g0, [%0 + %%g4] %6\n\t" + "sta %%g0, [%0 + %%g5] %6\n\t" + "sta %%g0, [%0 + %%o4] %6\n\t" + "bg 1b\n\t" + " add %0, %%o5, %0\n" + : "=&r" (addr), "=&r" (nbytes), "=&r" (lsize) + : "0" (addr), "1" (nbytes), "2" (lsize), + "i" (ASI_FLUSHSEG) + : "g1", "g2", "g3", "g4", "g5", "o4", "o5", "cc"); + } +} + +/* Don't inline the software version as it eats too many cache lines if expanded. */ +static void sun4c_flush_page_sw(unsigned long addr) +{ + addr &= PAGE_MASK; + if ((sun4c_get_pte(addr) & (_SUN4C_PAGE_NOCACHE | _SUN4C_PAGE_VALID)) == + _SUN4C_PAGE_VALID) { + unsigned long left = PAGE_SIZE; + unsigned long lsize = sun4c_vacinfo.linesize; + + __asm__ __volatile__( + "add %2, %2, %%g1\n\t" + "add %2, %%g1, %%g2\n\t" + "add %2, %%g2, %%g3\n\t" + "add %2, %%g3, %%g4\n\t" + "add %2, %%g4, %%g5\n\t" + "add %2, %%g5, %%o4\n\t" + "add %2, %%o4, %%o5\n" + "1:\n\t" + "subcc %1, %%o5, %1\n\t" + "sta %%g0, [%0] %6\n\t" + "sta %%g0, [%0 + %2] %6\n\t" + "sta %%g0, [%0 + %%g1] %6\n\t" + "sta %%g0, [%0 + %%g2] %6\n\t" + "sta %%g0, [%0 + %%g3] %6\n\t" + "sta %%g0, [%0 + %%g4] %6\n\t" + "sta %%g0, [%0 + %%g5] %6\n\t" + "sta %%g0, [%0 + %%o4] %6\n\t" + "bg 1b\n\t" + " add %0, %%o5, %0\n" + : "=&r" (addr), "=&r" (left), "=&r" (lsize) + : "0" (addr), "1" (left), "2" (lsize), + "i" (ASI_FLUSHPG) + : "g1", "g2", "g3", "g4", "g5", "o4", "o5", "cc"); + } +} + +/* The sun4c's do have an on chip store buffer. And the way you + * clear them out isn't so obvious. The only way I can think of + * to accomplish this is to read the current context register, + * store the same value there, then read an external hardware + * register. + */ +void sun4c_complete_all_stores(void) +{ + volatile int _unused; + + _unused = sun4c_get_context(); + sun4c_set_context(_unused); + _unused = get_auxio(); +} + +/* Bootup utility functions. */ +static inline void sun4c_init_clean_segmap(unsigned char pseg) +{ + unsigned long vaddr; + + sun4c_put_segmap(0, pseg); + for (vaddr = 0; vaddr < SUN4C_REAL_PGDIR_SIZE; vaddr += PAGE_SIZE) + sun4c_put_pte(vaddr, 0); + sun4c_put_segmap(0, invalid_segment); +} + +static inline void sun4c_init_clean_mmu(unsigned long kernel_end) +{ + unsigned long vaddr; + unsigned char savectx, ctx; + + savectx = sun4c_get_context(); + for (ctx = 0; ctx < num_contexts; ctx++) { + sun4c_set_context(ctx); + for (vaddr = 0; vaddr < 0x20000000; vaddr += SUN4C_REAL_PGDIR_SIZE) + sun4c_put_segmap(vaddr, invalid_segment); + for (vaddr = 0xe0000000; vaddr < KERNBASE; vaddr += SUN4C_REAL_PGDIR_SIZE) + sun4c_put_segmap(vaddr, invalid_segment); + for (vaddr = kernel_end; vaddr < KADB_DEBUGGER_BEGVM; vaddr += SUN4C_REAL_PGDIR_SIZE) + sun4c_put_segmap(vaddr, invalid_segment); + for (vaddr = LINUX_OPPROM_ENDVM; vaddr; vaddr += SUN4C_REAL_PGDIR_SIZE) + sun4c_put_segmap(vaddr, invalid_segment); + } + sun4c_set_context(savectx); +} + +void __init sun4c_probe_vac(void) +{ + sun4c_disable_vac(); + + if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) || + (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) { + /* PROM on SS1 lacks this info, to be super safe we + * hard code it here since this arch is cast in stone. + */ + sun4c_vacinfo.num_bytes = 65536; + sun4c_vacinfo.linesize = 16; + } else { + sun4c_vacinfo.num_bytes = + prom_getintdefault(prom_root_node, "vac-size", 65536); + sun4c_vacinfo.linesize = + prom_getintdefault(prom_root_node, "vac-linesize", 16); + } + sun4c_vacinfo.do_hwflushes = + prom_getintdefault(prom_root_node, "vac-hwflush", 0); + + if (sun4c_vacinfo.do_hwflushes == 0) + sun4c_vacinfo.do_hwflushes = + prom_getintdefault(prom_root_node, "vac_hwflush", 0); + + if (sun4c_vacinfo.num_bytes != 65536) { + prom_printf("WEIRD Sun4C VAC cache size, " + "tell sparclinux@vger.kernel.org"); + prom_halt(); + } + + switch (sun4c_vacinfo.linesize) { + case 16: + sun4c_vacinfo.log2lsize = 4; + break; + case 32: + sun4c_vacinfo.log2lsize = 5; + break; + default: + prom_printf("probe_vac: Didn't expect vac-linesize of %d, halting\n", + sun4c_vacinfo.linesize); + prom_halt(); + } + + sun4c_flush_all(); + sun4c_enable_vac(); +} + +/* Patch instructions for the low level kernel fault handler. */ +extern unsigned long invalid_segment_patch1, invalid_segment_patch1_ff; +extern unsigned long invalid_segment_patch2, invalid_segment_patch2_ff; +extern unsigned long invalid_segment_patch1_1ff, invalid_segment_patch2_1ff; +extern unsigned long num_context_patch1, num_context_patch1_16; +extern unsigned long num_context_patch2_16; +extern unsigned long vac_linesize_patch, vac_linesize_patch_32; +extern unsigned long vac_hwflush_patch1, vac_hwflush_patch1_on; +extern unsigned long vac_hwflush_patch2, vac_hwflush_patch2_on; + +#define PATCH_INSN(src, dst) do { \ + daddr = &(dst); \ + iaddr = &(src); \ + *daddr = *iaddr; \ + } while (0) + +static void __init patch_kernel_fault_handler(void) +{ + unsigned long *iaddr, *daddr; + + switch (num_segmaps) { + case 128: + /* Default, nothing to do. */ + break; + case 256: + PATCH_INSN(invalid_segment_patch1_ff, + invalid_segment_patch1); + PATCH_INSN(invalid_segment_patch2_ff, + invalid_segment_patch2); + break; + case 512: + PATCH_INSN(invalid_segment_patch1_1ff, + invalid_segment_patch1); + PATCH_INSN(invalid_segment_patch2_1ff, + invalid_segment_patch2); + break; + default: + prom_printf("Unhandled number of segmaps: %d\n", + num_segmaps); + prom_halt(); + } + switch (num_contexts) { + case 8: + /* Default, nothing to do. */ + break; + case 16: + PATCH_INSN(num_context_patch1_16, + num_context_patch1); + break; + default: + prom_printf("Unhandled number of contexts: %d\n", + num_contexts); + prom_halt(); + } + + if (sun4c_vacinfo.do_hwflushes != 0) { + PATCH_INSN(vac_hwflush_patch1_on, vac_hwflush_patch1); + PATCH_INSN(vac_hwflush_patch2_on, vac_hwflush_patch2); + } else { + switch (sun4c_vacinfo.linesize) { + case 16: + /* Default, nothing to do. */ + break; + case 32: + PATCH_INSN(vac_linesize_patch_32, vac_linesize_patch); + break; + default: + prom_printf("Impossible VAC linesize %d, halting...\n", + sun4c_vacinfo.linesize); + prom_halt(); + } + } +} + +static void __init sun4c_probe_mmu(void) +{ + if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) || + (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) { + /* Hardcode these just to be safe, PROM on SS1 does + * not have this info available in the root node. + */ + num_segmaps = 128; + num_contexts = 8; + } else { + num_segmaps = + prom_getintdefault(prom_root_node, "mmu-npmg", 128); + num_contexts = + prom_getintdefault(prom_root_node, "mmu-nctx", 0x8); + } + patch_kernel_fault_handler(); +} + +volatile unsigned long __iomem *sun4c_memerr_reg = NULL; + +void __init sun4c_probe_memerr_reg(void) +{ + phandle node; + struct linux_prom_registers regs[1]; + + node = prom_getchild(prom_root_node); + node = prom_searchsiblings(prom_root_node, "memory-error"); + if (!node) + return; + if (prom_getproperty(node, "reg", (char *)regs, sizeof(regs)) <= 0) + return; + /* hmm I think regs[0].which_io is zero here anyways */ + sun4c_memerr_reg = ioremap(regs[0].phys_addr, regs[0].reg_size); +} + +static inline void sun4c_init_ss2_cache_bug(void) +{ + if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS2)) || + (idprom->id_machtype == (SM_SUN4C | SM_4C_IPX)) || + (idprom->id_machtype == (SM_SUN4C | SM_4C_ELC))) { + /* Whee.. */ + printk("SS2 cache bug detected, uncaching trap table page\n"); + sun4c_flush_page((unsigned int) &_start); + sun4c_put_pte(((unsigned long) &_start), + (sun4c_get_pte((unsigned long) &_start) | _SUN4C_PAGE_NOCACHE)); + } +} + +/* Addr is always aligned on a page boundary for us already. */ +static int sun4c_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va, + unsigned long addr, int len) +{ + unsigned long page, end; + + *pba = addr; + + end = PAGE_ALIGN((addr + len)); + while (addr < end) { + page = va; + sun4c_flush_page(page); + page -= PAGE_OFFSET; + page >>= PAGE_SHIFT; + page |= (_SUN4C_PAGE_VALID | _SUN4C_PAGE_DIRTY | + _SUN4C_PAGE_NOCACHE | _SUN4C_PAGE_PRIV); + sun4c_put_pte(addr, page); + addr += PAGE_SIZE; + va += PAGE_SIZE; + } + + return 0; +} + +static void sun4c_unmap_dma_area(struct device *dev, unsigned long busa, int len) +{ + /* Fortunately for us, bus_addr == uncached_virt in sun4c. */ + /* XXX Implement this */ +} + +/* TLB management. */ + +/* Don't change this struct without changing entry.S. This is used + * in the in-window kernel fault handler, and you don't want to mess + * with that. (See sun4c_fault in entry.S). + */ +struct sun4c_mmu_entry { + struct sun4c_mmu_entry *next; + struct sun4c_mmu_entry *prev; + unsigned long vaddr; + unsigned char pseg; + unsigned char locked; + + /* For user mappings only, and completely hidden from kernel + * TLB miss code. + */ + unsigned char ctx; + struct sun4c_mmu_entry *lru_next; + struct sun4c_mmu_entry *lru_prev; +}; + +static struct sun4c_mmu_entry mmu_entry_pool[SUN4C_MAX_SEGMAPS]; + +static void __init sun4c_init_mmu_entry_pool(void) +{ + int i; + + for (i=0; i < SUN4C_MAX_SEGMAPS; i++) { + mmu_entry_pool[i].pseg = i; + mmu_entry_pool[i].next = NULL; + mmu_entry_pool[i].prev = NULL; + mmu_entry_pool[i].vaddr = 0; + mmu_entry_pool[i].locked = 0; + mmu_entry_pool[i].ctx = 0; + mmu_entry_pool[i].lru_next = NULL; + mmu_entry_pool[i].lru_prev = NULL; + } + mmu_entry_pool[invalid_segment].locked = 1; +} + +static inline void fix_permissions(unsigned long vaddr, unsigned long bits_on, + unsigned long bits_off) +{ + unsigned long start, end; + + end = vaddr + SUN4C_REAL_PGDIR_SIZE; + for (start = vaddr; start < end; start += PAGE_SIZE) + if (sun4c_get_pte(start) & _SUN4C_PAGE_VALID) + sun4c_put_pte(start, (sun4c_get_pte(start) | bits_on) & + ~bits_off); +} + +static inline void sun4c_init_map_kernelprom(unsigned long kernel_end) +{ + unsigned long vaddr; + unsigned char pseg, ctx; + + for (vaddr = KADB_DEBUGGER_BEGVM; + vaddr < LINUX_OPPROM_ENDVM; + vaddr += SUN4C_REAL_PGDIR_SIZE) { + pseg = sun4c_get_segmap(vaddr); + if (pseg != invalid_segment) { + mmu_entry_pool[pseg].locked = 1; + for (ctx = 0; ctx < num_contexts; ctx++) + prom_putsegment(ctx, vaddr, pseg); + fix_permissions(vaddr, _SUN4C_PAGE_PRIV, 0); + } + } + + for (vaddr = KERNBASE; vaddr < kernel_end; vaddr += SUN4C_REAL_PGDIR_SIZE) { + pseg = sun4c_get_segmap(vaddr); + mmu_entry_pool[pseg].locked = 1; + for (ctx = 0; ctx < num_contexts; ctx++) + prom_putsegment(ctx, vaddr, pseg); + fix_permissions(vaddr, _SUN4C_PAGE_PRIV, _SUN4C_PAGE_NOCACHE); + } +} + +static void __init sun4c_init_lock_area(unsigned long start, unsigned long end) +{ + int i, ctx; + + while (start < end) { + for (i = 0; i < invalid_segment; i++) + if (!mmu_entry_pool[i].locked) + break; + mmu_entry_pool[i].locked = 1; + sun4c_init_clean_segmap(i); + for (ctx = 0; ctx < num_contexts; ctx++) + prom_putsegment(ctx, start, mmu_entry_pool[i].pseg); + start += SUN4C_REAL_PGDIR_SIZE; + } +} + +/* Don't change this struct without changing entry.S. This is used + * in the in-window kernel fault handler, and you don't want to mess + * with that. (See sun4c_fault in entry.S). + */ +struct sun4c_mmu_ring { + struct sun4c_mmu_entry ringhd; + int num_entries; +}; + +static struct sun4c_mmu_ring sun4c_context_ring[SUN4C_MAX_CONTEXTS]; /* used user entries */ +static struct sun4c_mmu_ring sun4c_ufree_ring; /* free user entries */ +static struct sun4c_mmu_ring sun4c_ulru_ring; /* LRU user entries */ +struct sun4c_mmu_ring sun4c_kernel_ring; /* used kernel entries */ +struct sun4c_mmu_ring sun4c_kfree_ring; /* free kernel entries */ + +static inline void sun4c_init_rings(void) +{ + int i; + + for (i = 0; i < SUN4C_MAX_CONTEXTS; i++) { + sun4c_context_ring[i].ringhd.next = + sun4c_context_ring[i].ringhd.prev = + &sun4c_context_ring[i].ringhd; + sun4c_context_ring[i].num_entries = 0; + } + sun4c_ufree_ring.ringhd.next = sun4c_ufree_ring.ringhd.prev = + &sun4c_ufree_ring.ringhd; + sun4c_ufree_ring.num_entries = 0; + sun4c_ulru_ring.ringhd.lru_next = sun4c_ulru_ring.ringhd.lru_prev = + &sun4c_ulru_ring.ringhd; + sun4c_ulru_ring.num_entries = 0; + sun4c_kernel_ring.ringhd.next = sun4c_kernel_ring.ringhd.prev = + &sun4c_kernel_ring.ringhd; + sun4c_kernel_ring.num_entries = 0; + sun4c_kfree_ring.ringhd.next = sun4c_kfree_ring.ringhd.prev = + &sun4c_kfree_ring.ringhd; + sun4c_kfree_ring.num_entries = 0; +} + +static void add_ring(struct sun4c_mmu_ring *ring, + struct sun4c_mmu_entry *entry) +{ + struct sun4c_mmu_entry *head = &ring->ringhd; + + entry->prev = head; + (entry->next = head->next)->prev = entry; + head->next = entry; + ring->num_entries++; +} + +static inline void add_lru(struct sun4c_mmu_entry *entry) +{ + struct sun4c_mmu_ring *ring = &sun4c_ulru_ring; + struct sun4c_mmu_entry *head = &ring->ringhd; + + entry->lru_next = head; + (entry->lru_prev = head->lru_prev)->lru_next = entry; + head->lru_prev = entry; +} + +static void add_ring_ordered(struct sun4c_mmu_ring *ring, + struct sun4c_mmu_entry *entry) +{ + struct sun4c_mmu_entry *head = &ring->ringhd; + unsigned long addr = entry->vaddr; + + while ((head->next != &ring->ringhd) && (head->next->vaddr < addr)) + head = head->next; + + entry->prev = head; + (entry->next = head->next)->prev = entry; + head->next = entry; + ring->num_entries++; + + add_lru(entry); +} + +static inline void remove_ring(struct sun4c_mmu_ring *ring, + struct sun4c_mmu_entry *entry) +{ + struct sun4c_mmu_entry *next = entry->next; + + (next->prev = entry->prev)->next = next; + ring->num_entries--; +} + +static void remove_lru(struct sun4c_mmu_entry *entry) +{ + struct sun4c_mmu_entry *next = entry->lru_next; + + (next->lru_prev = entry->lru_prev)->lru_next = next; +} + +static void free_user_entry(int ctx, struct sun4c_mmu_entry *entry) +{ + remove_ring(sun4c_context_ring+ctx, entry); + remove_lru(entry); + add_ring(&sun4c_ufree_ring, entry); +} + +static void free_kernel_entry(struct sun4c_mmu_entry *entry, + struct sun4c_mmu_ring *ring) +{ + remove_ring(ring, entry); + add_ring(&sun4c_kfree_ring, entry); +} + +static void __init sun4c_init_fill_kernel_ring(int howmany) +{ + int i; + + while (howmany) { + for (i = 0; i < invalid_segment; i++) + if (!mmu_entry_pool[i].locked) + break; + mmu_entry_pool[i].locked = 1; + sun4c_init_clean_segmap(i); + add_ring(&sun4c_kfree_ring, &mmu_entry_pool[i]); + howmany--; + } +} + +static void __init sun4c_init_fill_user_ring(void) +{ + int i; + + for (i = 0; i < invalid_segment; i++) { + if (mmu_entry_pool[i].locked) + continue; + sun4c_init_clean_segmap(i); + add_ring(&sun4c_ufree_ring, &mmu_entry_pool[i]); + } +} + +static void sun4c_kernel_unmap(struct sun4c_mmu_entry *kentry) +{ + int savectx, ctx; + + savectx = sun4c_get_context(); + for (ctx = 0; ctx < num_contexts; ctx++) { + sun4c_set_context(ctx); + sun4c_put_segmap(kentry->vaddr, invalid_segment); + } + sun4c_set_context(savectx); +} + +static void sun4c_kernel_map(struct sun4c_mmu_entry *kentry) +{ + int savectx, ctx; + + savectx = sun4c_get_context(); + for (ctx = 0; ctx < num_contexts; ctx++) { + sun4c_set_context(ctx); + sun4c_put_segmap(kentry->vaddr, kentry->pseg); + } + sun4c_set_context(savectx); +} + +#define sun4c_user_unmap(__entry) \ + sun4c_put_segmap((__entry)->vaddr, invalid_segment) + +static void sun4c_demap_context(struct sun4c_mmu_ring *crp, unsigned char ctx) +{ + struct sun4c_mmu_entry *head = &crp->ringhd; + unsigned long flags; + + local_irq_save(flags); + if (head->next != head) { + struct sun4c_mmu_entry *entry = head->next; + int savectx = sun4c_get_context(); + + flush_user_windows(); + sun4c_set_context(ctx); + sun4c_flush_context(); + do { + struct sun4c_mmu_entry *next = entry->next; + + sun4c_user_unmap(entry); + free_user_entry(ctx, entry); + + entry = next; + } while (entry != head); + sun4c_set_context(savectx); + } + local_irq_restore(flags); +} + +static int sun4c_user_taken_entries; /* This is how much we have. */ +static int max_user_taken_entries; /* This limits us and prevents deadlock. */ + +static struct sun4c_mmu_entry *sun4c_kernel_strategy(void) +{ + struct sun4c_mmu_entry *this_entry; + + /* If some are free, return first one. */ + if (sun4c_kfree_ring.num_entries) { + this_entry = sun4c_kfree_ring.ringhd.next; + return this_entry; + } + + /* Else free one up. */ + this_entry = sun4c_kernel_ring.ringhd.prev; + sun4c_flush_segment(this_entry->vaddr); + sun4c_kernel_unmap(this_entry); + free_kernel_entry(this_entry, &sun4c_kernel_ring); + this_entry = sun4c_kfree_ring.ringhd.next; + + return this_entry; +} + +/* Using this method to free up mmu entries eliminates a lot of + * potential races since we have a kernel that incurs tlb + * replacement faults. There may be performance penalties. + * + * NOTE: Must be called with interrupts disabled. + */ +static struct sun4c_mmu_entry *sun4c_user_strategy(void) +{ + struct sun4c_mmu_entry *entry; + unsigned char ctx; + int savectx; + + /* If some are free, return first one. */ + if (sun4c_ufree_ring.num_entries) { + entry = sun4c_ufree_ring.ringhd.next; + goto unlink_out; + } + + if (sun4c_user_taken_entries) { + entry = sun4c_kernel_strategy(); + sun4c_user_taken_entries--; + goto kunlink_out; + } + + /* Grab from the beginning of the LRU list. */ + entry = sun4c_ulru_ring.ringhd.lru_next; + ctx = entry->ctx; + + savectx = sun4c_get_context(); + flush_user_windows(); + sun4c_set_context(ctx); + sun4c_flush_segment(entry->vaddr); + sun4c_user_unmap(entry); + remove_ring(sun4c_context_ring + ctx, entry); + remove_lru(entry); + sun4c_set_context(savectx); + + return entry; + +unlink_out: + remove_ring(&sun4c_ufree_ring, entry); + return entry; +kunlink_out: + remove_ring(&sun4c_kfree_ring, entry); + return entry; +} + +/* NOTE: Must be called with interrupts disabled. */ +void sun4c_grow_kernel_ring(void) +{ + struct sun4c_mmu_entry *entry; + + /* Prevent deadlock condition. */ + if (sun4c_user_taken_entries >= max_user_taken_entries) + return; + + if (sun4c_ufree_ring.num_entries) { + entry = sun4c_ufree_ring.ringhd.next; + remove_ring(&sun4c_ufree_ring, entry); + add_ring(&sun4c_kfree_ring, entry); + sun4c_user_taken_entries++; + } +} + +/* 2 page buckets for task struct and kernel stack allocation. + * + * TASK_STACK_BEGIN + * bucket[0] + * bucket[1] + * [ ... ] + * bucket[NR_TASK_BUCKETS-1] + * TASK_STACK_BEGIN + (sizeof(struct task_bucket) * NR_TASK_BUCKETS) + * + * Each slot looks like: + * + * page 1 -- task struct + beginning of kernel stack + * page 2 -- rest of kernel stack + */ + +union task_union *sun4c_bucket[NR_TASK_BUCKETS]; + +static int sun4c_lowbucket_avail; + +#define BUCKET_EMPTY ((union task_union *) 0) +#define BUCKET_SHIFT (PAGE_SHIFT + 1) /* log2(sizeof(struct task_bucket)) */ +#define BUCKET_SIZE (1 << BUCKET_SHIFT) +#define BUCKET_NUM(addr) ((((addr) - SUN4C_LOCK_VADDR) >> BUCKET_SHIFT)) +#define BUCKET_ADDR(num) (((num) << BUCKET_SHIFT) + SUN4C_LOCK_VADDR) +#define BUCKET_PTE(page) \ + ((((page) - PAGE_OFFSET) >> PAGE_SHIFT) | pgprot_val(SUN4C_PAGE_KERNEL)) +#define BUCKET_PTE_PAGE(pte) \ + (PAGE_OFFSET + (((pte) & SUN4C_PFN_MASK) << PAGE_SHIFT)) + +static void get_locked_segment(unsigned long addr) +{ + struct sun4c_mmu_entry *stolen; + unsigned long flags; + + local_irq_save(flags); + addr &= SUN4C_REAL_PGDIR_MASK; + stolen = sun4c_user_strategy(); + max_user_taken_entries--; + stolen->vaddr = addr; + flush_user_windows(); + sun4c_kernel_map(stolen); + local_irq_restore(flags); +} + +static void free_locked_segment(unsigned long addr) +{ + struct sun4c_mmu_entry *entry; + unsigned long flags; + unsigned char pseg; + + local_irq_save(flags); + addr &= SUN4C_REAL_PGDIR_MASK; + pseg = sun4c_get_segmap(addr); + entry = &mmu_entry_pool[pseg]; + + flush_user_windows(); + sun4c_flush_segment(addr); + sun4c_kernel_unmap(entry); + add_ring(&sun4c_ufree_ring, entry); + max_user_taken_entries++; + local_irq_restore(flags); +} + +static inline void garbage_collect(int entry) +{ + int start, end; + + /* 32 buckets per segment... */ + entry &= ~31; + start = entry; + for (end = (start + 32); start < end; start++) + if (sun4c_bucket[start] != BUCKET_EMPTY) + return; + + /* Entire segment empty, release it. */ + free_locked_segment(BUCKET_ADDR(entry)); +} + +static struct thread_info *sun4c_alloc_thread_info_node(int node) +{ + unsigned long addr, pages; + int entry; + + pages = __get_free_pages(GFP_KERNEL, THREAD_INFO_ORDER); + if (!pages) + return NULL; + + for (entry = sun4c_lowbucket_avail; entry < NR_TASK_BUCKETS; entry++) + if (sun4c_bucket[entry] == BUCKET_EMPTY) + break; + if (entry == NR_TASK_BUCKETS) { + free_pages(pages, THREAD_INFO_ORDER); + return NULL; + } + if (entry >= sun4c_lowbucket_avail) + sun4c_lowbucket_avail = entry + 1; + + addr = BUCKET_ADDR(entry); + sun4c_bucket[entry] = (union task_union *) addr; + if(sun4c_get_segmap(addr) == invalid_segment) + get_locked_segment(addr); + + /* We are changing the virtual color of the page(s) + * so we must flush the cache to guarantee consistency. + */ + sun4c_flush_page(pages); + sun4c_flush_page(pages + PAGE_SIZE); + + sun4c_put_pte(addr, BUCKET_PTE(pages)); + sun4c_put_pte(addr + PAGE_SIZE, BUCKET_PTE(pages + PAGE_SIZE)); + +#ifdef CONFIG_DEBUG_STACK_USAGE + memset((void *)addr, 0, PAGE_SIZE << THREAD_INFO_ORDER); +#endif /* DEBUG_STACK_USAGE */ + + return (struct thread_info *) addr; +} + +static void sun4c_free_thread_info(struct thread_info *ti) +{ + unsigned long tiaddr = (unsigned long) ti; + unsigned long pages = BUCKET_PTE_PAGE(sun4c_get_pte(tiaddr)); + int entry = BUCKET_NUM(tiaddr); + + /* We are deleting a mapping, so the flush here is mandatory. */ + sun4c_flush_page(tiaddr); + sun4c_flush_page(tiaddr + PAGE_SIZE); + + sun4c_put_pte(tiaddr, 0); + sun4c_put_pte(tiaddr + PAGE_SIZE, 0); + + sun4c_bucket[entry] = BUCKET_EMPTY; + if (entry < sun4c_lowbucket_avail) + sun4c_lowbucket_avail = entry; + + free_pages(pages, THREAD_INFO_ORDER); + garbage_collect(entry); +} + +static void __init sun4c_init_buckets(void) +{ + int entry; + + if (sizeof(union thread_union) != (PAGE_SIZE << THREAD_INFO_ORDER)) { + extern void thread_info_size_is_bolixed_pete(void); + thread_info_size_is_bolixed_pete(); + } + + for (entry = 0; entry < NR_TASK_BUCKETS; entry++) + sun4c_bucket[entry] = BUCKET_EMPTY; + sun4c_lowbucket_avail = 0; +} + +static unsigned long sun4c_iobuffer_start; +static unsigned long sun4c_iobuffer_end; +static unsigned long sun4c_iobuffer_high; +static unsigned long *sun4c_iobuffer_map; +static int iobuffer_map_size; + +/* + * Alias our pages so they do not cause a trap. + * Also one page may be aliased into several I/O areas and we may + * finish these I/O separately. + */ +static char *sun4c_lockarea(char *vaddr, unsigned long size) +{ + unsigned long base, scan; + unsigned long npages; + unsigned long vpage; + unsigned long pte; + unsigned long apage; + unsigned long high; + unsigned long flags; + + npages = (((unsigned long)vaddr & ~PAGE_MASK) + + size + (PAGE_SIZE-1)) >> PAGE_SHIFT; + + local_irq_save(flags); + base = bitmap_find_next_zero_area(sun4c_iobuffer_map, iobuffer_map_size, + 0, npages, 0); + if (base >= iobuffer_map_size) + goto abend; + + high = ((base + npages) << PAGE_SHIFT) + sun4c_iobuffer_start; + high = SUN4C_REAL_PGDIR_ALIGN(high); + while (high > sun4c_iobuffer_high) { + get_locked_segment(sun4c_iobuffer_high); + sun4c_iobuffer_high += SUN4C_REAL_PGDIR_SIZE; + } + + vpage = ((unsigned long) vaddr) & PAGE_MASK; + for (scan = base; scan < base+npages; scan++) { + pte = ((vpage-PAGE_OFFSET) >> PAGE_SHIFT); + pte |= pgprot_val(SUN4C_PAGE_KERNEL); + pte |= _SUN4C_PAGE_NOCACHE; + set_bit(scan, sun4c_iobuffer_map); + apage = (scan << PAGE_SHIFT) + sun4c_iobuffer_start; + + /* Flush original mapping so we see the right things later. */ + sun4c_flush_page(vpage); + + sun4c_put_pte(apage, pte); + vpage += PAGE_SIZE; + } + local_irq_restore(flags); + return (char *) ((base << PAGE_SHIFT) + sun4c_iobuffer_start + + (((unsigned long) vaddr) & ~PAGE_MASK)); + +abend: + local_irq_restore(flags); + printk("DMA vaddr=0x%p size=%08lx\n", vaddr, size); + panic("Out of iobuffer table"); + return NULL; +} + +static void sun4c_unlockarea(char *vaddr, unsigned long size) +{ + unsigned long vpage, npages; + unsigned long flags; + int scan, high; + + vpage = (unsigned long)vaddr & PAGE_MASK; + npages = (((unsigned long)vaddr & ~PAGE_MASK) + + size + (PAGE_SIZE-1)) >> PAGE_SHIFT; + + local_irq_save(flags); + while (npages != 0) { + --npages; + + /* This mapping is marked non-cachable, no flush necessary. */ + sun4c_put_pte(vpage, 0); + clear_bit((vpage - sun4c_iobuffer_start) >> PAGE_SHIFT, + sun4c_iobuffer_map); + vpage += PAGE_SIZE; + } + + /* garbage collect */ + scan = (sun4c_iobuffer_high - sun4c_iobuffer_start) >> PAGE_SHIFT; + while (scan >= 0 && !sun4c_iobuffer_map[scan >> 5]) + scan -= 32; + scan += 32; + high = sun4c_iobuffer_start + (scan << PAGE_SHIFT); + high = SUN4C_REAL_PGDIR_ALIGN(high) + SUN4C_REAL_PGDIR_SIZE; + while (high < sun4c_iobuffer_high) { + sun4c_iobuffer_high -= SUN4C_REAL_PGDIR_SIZE; + free_locked_segment(sun4c_iobuffer_high); + } + local_irq_restore(flags); +} + +/* Note the scsi code at init time passes to here buffers + * which sit on the kernel stack, those are already locked + * by implication and fool the page locking code above + * if passed to by mistake. + */ +static __u32 sun4c_get_scsi_one(struct device *dev, char *bufptr, unsigned long len) +{ + unsigned long page; + + page = ((unsigned long)bufptr) & PAGE_MASK; + if (!virt_addr_valid(page)) { + sun4c_flush_page(page); + return (__u32)bufptr; /* already locked */ + } + return (__u32)sun4c_lockarea(bufptr, len); +} + +static void sun4c_get_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz) +{ + while (sz != 0) { + --sz; + sg->dma_address = (__u32)sun4c_lockarea(sg_virt(sg), sg->length); + sg->dma_length = sg->length; + sg = sg_next(sg); + } +} + +static void sun4c_release_scsi_one(struct device *dev, __u32 bufptr, unsigned long len) +{ + if (bufptr < sun4c_iobuffer_start) + return; /* On kernel stack or similar, see above */ + sun4c_unlockarea((char *)bufptr, len); +} + +static void sun4c_release_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz) +{ + while (sz != 0) { + --sz; + sun4c_unlockarea((char *)sg->dma_address, sg->length); + sg = sg_next(sg); + } +} + +#define TASK_ENTRY_SIZE BUCKET_SIZE /* see above */ +#define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1)) + +struct vm_area_struct sun4c_kstack_vma; + +static void __init sun4c_init_lock_areas(void) +{ + unsigned long sun4c_taskstack_start; + unsigned long sun4c_taskstack_end; + int bitmap_size; + + sun4c_init_buckets(); + sun4c_taskstack_start = SUN4C_LOCK_VADDR; + sun4c_taskstack_end = (sun4c_taskstack_start + + (TASK_ENTRY_SIZE * NR_TASK_BUCKETS)); + if (sun4c_taskstack_end >= SUN4C_LOCK_END) { + prom_printf("Too many tasks, decrease NR_TASK_BUCKETS please.\n"); + prom_halt(); + } + + sun4c_iobuffer_start = sun4c_iobuffer_high = + SUN4C_REAL_PGDIR_ALIGN(sun4c_taskstack_end); + sun4c_iobuffer_end = SUN4C_LOCK_END; + bitmap_size = (sun4c_iobuffer_end - sun4c_iobuffer_start) >> PAGE_SHIFT; + bitmap_size = (bitmap_size + 7) >> 3; + bitmap_size = LONG_ALIGN(bitmap_size); + iobuffer_map_size = bitmap_size << 3; + sun4c_iobuffer_map = __alloc_bootmem(bitmap_size, SMP_CACHE_BYTES, 0UL); + memset((void *) sun4c_iobuffer_map, 0, bitmap_size); + + sun4c_kstack_vma.vm_mm = &init_mm; + sun4c_kstack_vma.vm_start = sun4c_taskstack_start; + sun4c_kstack_vma.vm_end = sun4c_taskstack_end; + sun4c_kstack_vma.vm_page_prot = PAGE_SHARED; + sun4c_kstack_vma.vm_flags = VM_READ | VM_WRITE | VM_EXEC; + insert_vm_struct(&init_mm, &sun4c_kstack_vma); +} + +/* Cache flushing on the sun4c. */ +static void sun4c_flush_cache_all(void) +{ + unsigned long begin, end; + + flush_user_windows(); + begin = (KERNBASE + SUN4C_REAL_PGDIR_SIZE); + end = (begin + SUN4C_VAC_SIZE); + + if (sun4c_vacinfo.linesize == 32) { + while (begin < end) { + __asm__ __volatile__( + "ld [%0 + 0x00], %%g0\n\t" + "ld [%0 + 0x20], %%g0\n\t" + "ld [%0 + 0x40], %%g0\n\t" + "ld [%0 + 0x60], %%g0\n\t" + "ld [%0 + 0x80], %%g0\n\t" + "ld [%0 + 0xa0], %%g0\n\t" + "ld [%0 + 0xc0], %%g0\n\t" + "ld [%0 + 0xe0], %%g0\n\t" + "ld [%0 + 0x100], %%g0\n\t" + "ld [%0 + 0x120], %%g0\n\t" + "ld [%0 + 0x140], %%g0\n\t" + "ld [%0 + 0x160], %%g0\n\t" + "ld [%0 + 0x180], %%g0\n\t" + "ld [%0 + 0x1a0], %%g0\n\t" + "ld [%0 + 0x1c0], %%g0\n\t" + "ld [%0 + 0x1e0], %%g0\n" + : : "r" (begin)); + begin += 512; + } + } else { + while (begin < end) { + __asm__ __volatile__( + "ld [%0 + 0x00], %%g0\n\t" + "ld [%0 + 0x10], %%g0\n\t" + "ld [%0 + 0x20], %%g0\n\t" + "ld [%0 + 0x30], %%g0\n\t" + "ld [%0 + 0x40], %%g0\n\t" + "ld [%0 + 0x50], %%g0\n\t" + "ld [%0 + 0x60], %%g0\n\t" + "ld [%0 + 0x70], %%g0\n\t" + "ld [%0 + 0x80], %%g0\n\t" + "ld [%0 + 0x90], %%g0\n\t" + "ld [%0 + 0xa0], %%g0\n\t" + "ld [%0 + 0xb0], %%g0\n\t" + "ld [%0 + 0xc0], %%g0\n\t" + "ld [%0 + 0xd0], %%g0\n\t" + "ld [%0 + 0xe0], %%g0\n\t" + "ld [%0 + 0xf0], %%g0\n" + : : "r" (begin)); + begin += 256; + } + } +} + +static void sun4c_flush_cache_mm(struct mm_struct *mm) +{ + int new_ctx = mm->context; + + if (new_ctx != NO_CONTEXT) { + flush_user_windows(); + + if (sun4c_context_ring[new_ctx].num_entries) { + struct sun4c_mmu_entry *head = &sun4c_context_ring[new_ctx].ringhd; + unsigned long flags; + + local_irq_save(flags); + if (head->next != head) { + struct sun4c_mmu_entry *entry = head->next; + int savectx = sun4c_get_context(); + + sun4c_set_context(new_ctx); + sun4c_flush_context(); + do { + struct sun4c_mmu_entry *next = entry->next; + + sun4c_user_unmap(entry); + free_user_entry(new_ctx, entry); + + entry = next; + } while (entry != head); + sun4c_set_context(savectx); + } + local_irq_restore(flags); + } + } +} + +static void sun4c_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + int new_ctx = mm->context; + + if (new_ctx != NO_CONTEXT) { + struct sun4c_mmu_entry *head = &sun4c_context_ring[new_ctx].ringhd; + struct sun4c_mmu_entry *entry; + unsigned long flags; + + flush_user_windows(); + + local_irq_save(flags); + /* All user segmap chains are ordered on entry->vaddr. */ + for (entry = head->next; + (entry != head) && ((entry->vaddr+SUN4C_REAL_PGDIR_SIZE) < start); + entry = entry->next) + ; + + /* Tracing various job mixtures showed that this conditional + * only passes ~35% of the time for most worse case situations, + * therefore we avoid all of this gross overhead ~65% of the time. + */ + if ((entry != head) && (entry->vaddr < end)) { + int octx = sun4c_get_context(); + sun4c_set_context(new_ctx); + + /* At this point, always, (start >= entry->vaddr) and + * (entry->vaddr < end), once the latter condition + * ceases to hold, or we hit the end of the list, we + * exit the loop. The ordering of all user allocated + * segmaps makes this all work out so beautifully. + */ + do { + struct sun4c_mmu_entry *next = entry->next; + unsigned long realend; + + /* "realstart" is always >= entry->vaddr */ + realend = entry->vaddr + SUN4C_REAL_PGDIR_SIZE; + if (end < realend) + realend = end; + if ((realend - entry->vaddr) <= (PAGE_SIZE << 3)) { + unsigned long page = entry->vaddr; + while (page < realend) { + sun4c_flush_page(page); + page += PAGE_SIZE; + } + } else { + sun4c_flush_segment(entry->vaddr); + sun4c_user_unmap(entry); + free_user_entry(new_ctx, entry); + } + entry = next; + } while ((entry != head) && (entry->vaddr < end)); + sun4c_set_context(octx); + } + local_irq_restore(flags); + } +} + +static void sun4c_flush_cache_page(struct vm_area_struct *vma, unsigned long page) +{ + struct mm_struct *mm = vma->vm_mm; + int new_ctx = mm->context; + + /* Sun4c has no separate I/D caches so cannot optimize for non + * text page flushes. + */ + if (new_ctx != NO_CONTEXT) { + int octx = sun4c_get_context(); + unsigned long flags; + + flush_user_windows(); + local_irq_save(flags); + sun4c_set_context(new_ctx); + sun4c_flush_page(page); + sun4c_set_context(octx); + local_irq_restore(flags); + } +} + +static void sun4c_flush_page_to_ram(unsigned long page) +{ + unsigned long flags; + + local_irq_save(flags); + sun4c_flush_page(page); + local_irq_restore(flags); +} + +/* Sun4c cache is unified, both instructions and data live there, so + * no need to flush the on-stack instructions for new signal handlers. + */ +static void sun4c_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr) +{ +} + +/* TLB flushing on the sun4c. These routines count on the cache + * flushing code to flush the user register windows so that we need + * not do so when we get here. + */ + +static void sun4c_flush_tlb_all(void) +{ + struct sun4c_mmu_entry *this_entry, *next_entry; + unsigned long flags; + int savectx, ctx; + + local_irq_save(flags); + this_entry = sun4c_kernel_ring.ringhd.next; + savectx = sun4c_get_context(); + flush_user_windows(); + while (sun4c_kernel_ring.num_entries) { + next_entry = this_entry->next; + sun4c_flush_segment(this_entry->vaddr); + for (ctx = 0; ctx < num_contexts; ctx++) { + sun4c_set_context(ctx); + sun4c_put_segmap(this_entry->vaddr, invalid_segment); + } + free_kernel_entry(this_entry, &sun4c_kernel_ring); + this_entry = next_entry; + } + sun4c_set_context(savectx); + local_irq_restore(flags); +} + +static void sun4c_flush_tlb_mm(struct mm_struct *mm) +{ + int new_ctx = mm->context; + + if (new_ctx != NO_CONTEXT) { + struct sun4c_mmu_entry *head = &sun4c_context_ring[new_ctx].ringhd; + unsigned long flags; + + local_irq_save(flags); + if (head->next != head) { + struct sun4c_mmu_entry *entry = head->next; + int savectx = sun4c_get_context(); + + sun4c_set_context(new_ctx); + sun4c_flush_context(); + do { + struct sun4c_mmu_entry *next = entry->next; + + sun4c_user_unmap(entry); + free_user_entry(new_ctx, entry); + + entry = next; + } while (entry != head); + sun4c_set_context(savectx); + } + local_irq_restore(flags); + } +} + +static void sun4c_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + int new_ctx = mm->context; + + if (new_ctx != NO_CONTEXT) { + struct sun4c_mmu_entry *head = &sun4c_context_ring[new_ctx].ringhd; + struct sun4c_mmu_entry *entry; + unsigned long flags; + + local_irq_save(flags); + /* See commentary in sun4c_flush_cache_range(). */ + for (entry = head->next; + (entry != head) && ((entry->vaddr+SUN4C_REAL_PGDIR_SIZE) < start); + entry = entry->next) + ; + + if ((entry != head) && (entry->vaddr < end)) { + int octx = sun4c_get_context(); + + sun4c_set_context(new_ctx); + do { + struct sun4c_mmu_entry *next = entry->next; + + sun4c_flush_segment(entry->vaddr); + sun4c_user_unmap(entry); + free_user_entry(new_ctx, entry); + + entry = next; + } while ((entry != head) && (entry->vaddr < end)); + sun4c_set_context(octx); + } + local_irq_restore(flags); + } +} + +static void sun4c_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +{ + struct mm_struct *mm = vma->vm_mm; + int new_ctx = mm->context; + + if (new_ctx != NO_CONTEXT) { + int savectx = sun4c_get_context(); + unsigned long flags; + + local_irq_save(flags); + sun4c_set_context(new_ctx); + page &= PAGE_MASK; + sun4c_flush_page(page); + sun4c_put_pte(page, 0); + sun4c_set_context(savectx); + local_irq_restore(flags); + } +} + +static inline void sun4c_mapioaddr(unsigned long physaddr, unsigned long virt_addr) +{ + unsigned long page_entry, pg_iobits; + + pg_iobits = _SUN4C_PAGE_PRESENT | _SUN4C_READABLE | _SUN4C_WRITEABLE | + _SUN4C_PAGE_IO | _SUN4C_PAGE_NOCACHE; + + page_entry = ((physaddr >> PAGE_SHIFT) & SUN4C_PFN_MASK); + page_entry |= ((pg_iobits | _SUN4C_PAGE_PRIV) & ~(_SUN4C_PAGE_PRESENT)); + sun4c_put_pte(virt_addr, page_entry); +} + +static void sun4c_mapiorange(unsigned int bus, unsigned long xpa, + unsigned long xva, unsigned int len) +{ + while (len != 0) { + len -= PAGE_SIZE; + sun4c_mapioaddr(xpa, xva); + xva += PAGE_SIZE; + xpa += PAGE_SIZE; + } +} + +static void sun4c_unmapiorange(unsigned long virt_addr, unsigned int len) +{ + while (len != 0) { + len -= PAGE_SIZE; + sun4c_put_pte(virt_addr, 0); + virt_addr += PAGE_SIZE; + } +} + +static void sun4c_alloc_context(struct mm_struct *old_mm, struct mm_struct *mm) +{ + struct ctx_list *ctxp; + + ctxp = ctx_free.next; + if (ctxp != &ctx_free) { + remove_from_ctx_list(ctxp); + add_to_used_ctxlist(ctxp); + mm->context = ctxp->ctx_number; + ctxp->ctx_mm = mm; + return; + } + ctxp = ctx_used.next; + if (ctxp->ctx_mm == old_mm) + ctxp = ctxp->next; + remove_from_ctx_list(ctxp); + add_to_used_ctxlist(ctxp); + ctxp->ctx_mm->context = NO_CONTEXT; + ctxp->ctx_mm = mm; + mm->context = ctxp->ctx_number; + sun4c_demap_context(&sun4c_context_ring[ctxp->ctx_number], + ctxp->ctx_number); +} + +/* Switch the current MM context. */ +static void sun4c_switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, struct task_struct *tsk, int cpu) +{ + struct ctx_list *ctx; + int dirty = 0; + + if (mm->context == NO_CONTEXT) { + dirty = 1; + sun4c_alloc_context(old_mm, mm); + } else { + /* Update the LRU ring of contexts. */ + ctx = ctx_list_pool + mm->context; + remove_from_ctx_list(ctx); + add_to_used_ctxlist(ctx); + } + if (dirty || old_mm != mm) + sun4c_set_context(mm->context); +} + +static void sun4c_destroy_context(struct mm_struct *mm) +{ + struct ctx_list *ctx_old; + + if (mm->context != NO_CONTEXT) { + sun4c_demap_context(&sun4c_context_ring[mm->context], mm->context); + ctx_old = ctx_list_pool + mm->context; + remove_from_ctx_list(ctx_old); + add_to_free_ctxlist(ctx_old); + mm->context = NO_CONTEXT; + } +} + +static void sun4c_mmu_info(struct seq_file *m) +{ + int used_user_entries, i; + + used_user_entries = 0; + for (i = 0; i < num_contexts; i++) + used_user_entries += sun4c_context_ring[i].num_entries; + + seq_printf(m, + "vacsize\t\t: %d bytes\n" + "vachwflush\t: %s\n" + "vaclinesize\t: %d bytes\n" + "mmuctxs\t\t: %d\n" + "mmupsegs\t: %d\n" + "kernelpsegs\t: %d\n" + "kfreepsegs\t: %d\n" + "usedpsegs\t: %d\n" + "ufreepsegs\t: %d\n" + "user_taken\t: %d\n" + "max_taken\t: %d\n", + sun4c_vacinfo.num_bytes, + (sun4c_vacinfo.do_hwflushes ? "yes" : "no"), + sun4c_vacinfo.linesize, + num_contexts, + (invalid_segment + 1), + sun4c_kernel_ring.num_entries, + sun4c_kfree_ring.num_entries, + used_user_entries, + sun4c_ufree_ring.num_entries, + sun4c_user_taken_entries, + max_user_taken_entries); +} + +/* Nothing below here should touch the mmu hardware nor the mmu_entry + * data structures. + */ + +/* First the functions which the mid-level code uses to directly + * manipulate the software page tables. Some defines since we are + * emulating the i386 page directory layout. + */ +#define PGD_PRESENT 0x001 +#define PGD_RW 0x002 +#define PGD_USER 0x004 +#define PGD_ACCESSED 0x020 +#define PGD_DIRTY 0x040 +#define PGD_TABLE (PGD_PRESENT | PGD_RW | PGD_USER | PGD_ACCESSED | PGD_DIRTY) + +static void sun4c_set_pte(pte_t *ptep, pte_t pte) +{ + *ptep = pte; +} + +static void sun4c_pgd_set(pgd_t * pgdp, pmd_t * pmdp) +{ +} + +static void sun4c_pmd_set(pmd_t * pmdp, pte_t * ptep) +{ + pmdp->pmdv[0] = PGD_TABLE | (unsigned long) ptep; +} + +static void sun4c_pmd_populate(pmd_t * pmdp, struct page * ptep) +{ + if (page_address(ptep) == NULL) BUG(); /* No highmem on sun4c */ + pmdp->pmdv[0] = PGD_TABLE | (unsigned long) page_address(ptep); +} + +static int sun4c_pte_present(pte_t pte) +{ + return ((pte_val(pte) & (_SUN4C_PAGE_PRESENT | _SUN4C_PAGE_PRIV)) != 0); +} +static void sun4c_pte_clear(pte_t *ptep) { *ptep = __pte(0); } + +static int sun4c_pmd_bad(pmd_t pmd) +{ + return (((pmd_val(pmd) & ~PAGE_MASK) != PGD_TABLE) || + (!virt_addr_valid(pmd_val(pmd)))); +} + +static int sun4c_pmd_present(pmd_t pmd) +{ + return ((pmd_val(pmd) & PGD_PRESENT) != 0); +} + +#if 0 /* if PMD takes one word */ +static void sun4c_pmd_clear(pmd_t *pmdp) { *pmdp = __pmd(0); } +#else /* if pmd_t is a longish aggregate */ +static void sun4c_pmd_clear(pmd_t *pmdp) { + memset((void *)pmdp, 0, sizeof(pmd_t)); +} +#endif + +static int sun4c_pgd_none(pgd_t pgd) { return 0; } +static int sun4c_pgd_bad(pgd_t pgd) { return 0; } +static int sun4c_pgd_present(pgd_t pgd) { return 1; } +static void sun4c_pgd_clear(pgd_t * pgdp) { } + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +static pte_t sun4c_pte_mkwrite(pte_t pte) +{ + pte = __pte(pte_val(pte) | _SUN4C_PAGE_WRITE); + if (pte_val(pte) & _SUN4C_PAGE_MODIFIED) + pte = __pte(pte_val(pte) | _SUN4C_PAGE_SILENT_WRITE); + return pte; +} + +static pte_t sun4c_pte_mkdirty(pte_t pte) +{ + pte = __pte(pte_val(pte) | _SUN4C_PAGE_MODIFIED); + if (pte_val(pte) & _SUN4C_PAGE_WRITE) + pte = __pte(pte_val(pte) | _SUN4C_PAGE_SILENT_WRITE); + return pte; +} + +static pte_t sun4c_pte_mkyoung(pte_t pte) +{ + pte = __pte(pte_val(pte) | _SUN4C_PAGE_ACCESSED); + if (pte_val(pte) & _SUN4C_PAGE_READ) + pte = __pte(pte_val(pte) | _SUN4C_PAGE_SILENT_READ); + return pte; +} + +/* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + */ +static pte_t sun4c_mk_pte(struct page *page, pgprot_t pgprot) +{ + return __pte(page_to_pfn(page) | pgprot_val(pgprot)); +} + +static pte_t sun4c_mk_pte_phys(unsigned long phys_page, pgprot_t pgprot) +{ + return __pte((phys_page >> PAGE_SHIFT) | pgprot_val(pgprot)); +} + +static pte_t sun4c_mk_pte_io(unsigned long page, pgprot_t pgprot, int space) +{ + return __pte(((page - PAGE_OFFSET) >> PAGE_SHIFT) | pgprot_val(pgprot)); +} + +static unsigned long sun4c_pte_pfn(pte_t pte) +{ + return pte_val(pte) & SUN4C_PFN_MASK; +} + +static pte_t sun4c_pgoff_to_pte(unsigned long pgoff) +{ + return __pte(pgoff | _SUN4C_PAGE_FILE); +} + +static unsigned long sun4c_pte_to_pgoff(pte_t pte) +{ + return pte_val(pte) & ((1UL << PTE_FILE_MAX_BITS) - 1); +} + + +static inline unsigned long sun4c_pmd_page_v(pmd_t pmd) +{ + return (pmd_val(pmd) & PAGE_MASK); +} + +static struct page *sun4c_pmd_page(pmd_t pmd) +{ + return virt_to_page(sun4c_pmd_page_v(pmd)); +} + +static unsigned long sun4c_pgd_page(pgd_t pgd) { return 0; } + +/* to find an entry in a page-table-directory */ +static inline pgd_t *sun4c_pgd_offset(struct mm_struct * mm, unsigned long address) +{ + return mm->pgd + (address >> SUN4C_PGDIR_SHIFT); +} + +/* Find an entry in the second-level page table.. */ +static pmd_t *sun4c_pmd_offset(pgd_t * dir, unsigned long address) +{ + return (pmd_t *) dir; +} + +/* Find an entry in the third-level page table.. */ +pte_t *sun4c_pte_offset_kernel(pmd_t * dir, unsigned long address) +{ + return (pte_t *) sun4c_pmd_page_v(*dir) + + ((address >> PAGE_SHIFT) & (SUN4C_PTRS_PER_PTE - 1)); +} + +static unsigned long sun4c_swp_type(swp_entry_t entry) +{ + return (entry.val & SUN4C_SWP_TYPE_MASK); +} + +static unsigned long sun4c_swp_offset(swp_entry_t entry) +{ + return (entry.val >> SUN4C_SWP_OFF_SHIFT) & SUN4C_SWP_OFF_MASK; +} + +static swp_entry_t sun4c_swp_entry(unsigned long type, unsigned long offset) +{ + return (swp_entry_t) { + (offset & SUN4C_SWP_OFF_MASK) << SUN4C_SWP_OFF_SHIFT + | (type & SUN4C_SWP_TYPE_MASK) }; +} + +static void sun4c_free_pte_slow(pte_t *pte) +{ + free_page((unsigned long)pte); +} + +static void sun4c_free_pgd_slow(pgd_t *pgd) +{ + free_page((unsigned long)pgd); +} + +static pgd_t *sun4c_get_pgd_fast(void) +{ + unsigned long *ret; + + if ((ret = pgd_quicklist) != NULL) { + pgd_quicklist = (unsigned long *)(*ret); + ret[0] = ret[1]; + pgtable_cache_size--; + } else { + pgd_t *init; + + ret = (unsigned long *)__get_free_page(GFP_KERNEL); + memset (ret, 0, (KERNBASE / SUN4C_PGDIR_SIZE) * sizeof(pgd_t)); + init = sun4c_pgd_offset(&init_mm, 0); + memcpy (((pgd_t *)ret) + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, + (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); + } + return (pgd_t *)ret; +} + +static void sun4c_free_pgd_fast(pgd_t *pgd) +{ + *(unsigned long *)pgd = (unsigned long) pgd_quicklist; + pgd_quicklist = (unsigned long *) pgd; + pgtable_cache_size++; +} + + +static inline pte_t * +sun4c_pte_alloc_one_fast(struct mm_struct *mm, unsigned long address) +{ + unsigned long *ret; + + if ((ret = (unsigned long *)pte_quicklist) != NULL) { + pte_quicklist = (unsigned long *)(*ret); + ret[0] = ret[1]; + pgtable_cache_size--; + } + return (pte_t *)ret; +} + +static pte_t *sun4c_pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) +{ + pte_t *pte; + + if ((pte = sun4c_pte_alloc_one_fast(mm, address)) != NULL) + return pte; + + pte = (pte_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); + return pte; +} + +static pgtable_t sun4c_pte_alloc_one(struct mm_struct *mm, unsigned long address) +{ + pte_t *pte; + struct page *page; + + pte = sun4c_pte_alloc_one_kernel(mm, address); + if (pte == NULL) + return NULL; + page = virt_to_page(pte); + pgtable_page_ctor(page); + return page; +} + +static inline void sun4c_free_pte_fast(pte_t *pte) +{ + *(unsigned long *)pte = (unsigned long) pte_quicklist; + pte_quicklist = (unsigned long *) pte; + pgtable_cache_size++; +} + +static void sun4c_pte_free(pgtable_t pte) +{ + pgtable_page_dtor(pte); + sun4c_free_pte_fast(page_address(pte)); +} + +/* + * allocating and freeing a pmd is trivial: the 1-entry pmd is + * inside the pgd, so has no extra memory associated with it. + */ +static pmd_t *sun4c_pmd_alloc_one(struct mm_struct *mm, unsigned long address) +{ + BUG(); + return NULL; +} + +static void sun4c_free_pmd_fast(pmd_t * pmd) { } + +static void sun4c_check_pgt_cache(int low, int high) +{ + if (pgtable_cache_size > high) { + do { + if (pgd_quicklist) + sun4c_free_pgd_slow(sun4c_get_pgd_fast()); + if (pte_quicklist) + sun4c_free_pte_slow(sun4c_pte_alloc_one_fast(NULL, 0)); + } while (pgtable_cache_size > low); + } +} + +/* An experiment, turn off by default for now... -DaveM */ +#define SUN4C_PRELOAD_PSEG + +void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) +{ + unsigned long flags; + int pseg; + + if (vma->vm_mm->context == NO_CONTEXT) + return; + + local_irq_save(flags); + address &= PAGE_MASK; + if ((pseg = sun4c_get_segmap(address)) == invalid_segment) { + struct sun4c_mmu_entry *entry = sun4c_user_strategy(); + struct mm_struct *mm = vma->vm_mm; + unsigned long start, end; + + entry->vaddr = start = (address & SUN4C_REAL_PGDIR_MASK); + entry->ctx = mm->context; + add_ring_ordered(sun4c_context_ring + mm->context, entry); + sun4c_put_segmap(entry->vaddr, entry->pseg); + end = start + SUN4C_REAL_PGDIR_SIZE; + while (start < end) { +#ifdef SUN4C_PRELOAD_PSEG + pgd_t *pgdp = sun4c_pgd_offset(mm, start); + pte_t *ptep; + + if (!pgdp) + goto no_mapping; + ptep = sun4c_pte_offset_kernel((pmd_t *) pgdp, start); + if (!ptep || !(pte_val(*ptep) & _SUN4C_PAGE_PRESENT)) + goto no_mapping; + sun4c_put_pte(start, pte_val(*ptep)); + goto next; + + no_mapping: +#endif + sun4c_put_pte(start, 0); +#ifdef SUN4C_PRELOAD_PSEG + next: +#endif + start += PAGE_SIZE; + } +#ifndef SUN4C_PRELOAD_PSEG + sun4c_put_pte(address, pte_val(*ptep)); +#endif + local_irq_restore(flags); + return; + } else { + struct sun4c_mmu_entry *entry = &mmu_entry_pool[pseg]; + + remove_lru(entry); + add_lru(entry); + } + + sun4c_put_pte(address, pte_val(*ptep)); + local_irq_restore(flags); +} + +extern void sparc_context_init(int); +extern unsigned long bootmem_init(unsigned long *pages_avail); +extern unsigned long last_valid_pfn; + +void __init sun4c_paging_init(void) +{ + int i, cnt; + unsigned long kernel_end, vaddr; + extern struct resource sparc_iomap; + unsigned long end_pfn, pages_avail; + + kernel_end = (unsigned long) &_end; + kernel_end = SUN4C_REAL_PGDIR_ALIGN(kernel_end); + + pages_avail = 0; + last_valid_pfn = bootmem_init(&pages_avail); + end_pfn = last_valid_pfn; + + sun4c_probe_mmu(); + invalid_segment = (num_segmaps - 1); + sun4c_init_mmu_entry_pool(); + sun4c_init_rings(); + sun4c_init_map_kernelprom(kernel_end); + sun4c_init_clean_mmu(kernel_end); + sun4c_init_fill_kernel_ring(SUN4C_KERNEL_BUCKETS); + sun4c_init_lock_area(sparc_iomap.start, IOBASE_END); + sun4c_init_lock_area(DVMA_VADDR, DVMA_END); + sun4c_init_lock_areas(); + sun4c_init_fill_user_ring(); + + sun4c_set_context(0); + memset(swapper_pg_dir, 0, PAGE_SIZE); + memset(pg0, 0, PAGE_SIZE); + memset(pg1, 0, PAGE_SIZE); + memset(pg2, 0, PAGE_SIZE); + memset(pg3, 0, PAGE_SIZE); + + /* Save work later. */ + vaddr = VMALLOC_START; + swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg0); + vaddr += SUN4C_PGDIR_SIZE; + swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg1); + vaddr += SUN4C_PGDIR_SIZE; + swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg2); + vaddr += SUN4C_PGDIR_SIZE; + swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg3); + sun4c_init_ss2_cache_bug(); + sparc_context_init(num_contexts); + + { + unsigned long zones_size[MAX_NR_ZONES]; + unsigned long zholes_size[MAX_NR_ZONES]; + unsigned long npages; + int znum; + + for (znum = 0; znum < MAX_NR_ZONES; znum++) + zones_size[znum] = zholes_size[znum] = 0; + + npages = max_low_pfn - pfn_base; + + zones_size[ZONE_DMA] = npages; + zholes_size[ZONE_DMA] = npages - pages_avail; + + npages = highend_pfn - max_low_pfn; + zones_size[ZONE_HIGHMEM] = npages; + zholes_size[ZONE_HIGHMEM] = npages - calc_highpages(); + + free_area_init_node(0, zones_size, pfn_base, zholes_size); + } + + cnt = 0; + for (i = 0; i < num_segmaps; i++) + if (mmu_entry_pool[i].locked) + cnt++; + + max_user_taken_entries = num_segmaps - cnt - 40 - 1; + + printk("SUN4C: %d mmu entries for the kernel\n", cnt); +} + +static pgprot_t sun4c_pgprot_noncached(pgprot_t prot) +{ + prot |= __pgprot(_SUN4C_PAGE_IO | _SUN4C_PAGE_NOCACHE); + + return prot; +} + +/* Load up routines and constants for sun4c mmu */ +void __init ld_mmu_sun4c(void) +{ + extern void ___xchg32_sun4c(void); + + printk("Loading sun4c MMU routines\n"); + + /* First the constants */ + BTFIXUPSET_SIMM13(pgdir_shift, SUN4C_PGDIR_SHIFT); + BTFIXUPSET_SETHI(pgdir_size, SUN4C_PGDIR_SIZE); + BTFIXUPSET_SETHI(pgdir_mask, SUN4C_PGDIR_MASK); + + BTFIXUPSET_SIMM13(ptrs_per_pmd, SUN4C_PTRS_PER_PMD); + BTFIXUPSET_SIMM13(ptrs_per_pgd, SUN4C_PTRS_PER_PGD); + BTFIXUPSET_SIMM13(user_ptrs_per_pgd, KERNBASE / SUN4C_PGDIR_SIZE); + + BTFIXUPSET_INT(page_none, pgprot_val(SUN4C_PAGE_NONE)); + PAGE_SHARED = pgprot_val(SUN4C_PAGE_SHARED); + BTFIXUPSET_INT(page_copy, pgprot_val(SUN4C_PAGE_COPY)); + BTFIXUPSET_INT(page_readonly, pgprot_val(SUN4C_PAGE_READONLY)); + BTFIXUPSET_INT(page_kernel, pgprot_val(SUN4C_PAGE_KERNEL)); + page_kernel = pgprot_val(SUN4C_PAGE_KERNEL); + + /* Functions */ + BTFIXUPSET_CALL(pgprot_noncached, sun4c_pgprot_noncached, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(___xchg32, ___xchg32_sun4c, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(do_check_pgt_cache, sun4c_check_pgt_cache, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(flush_cache_all, sun4c_flush_cache_all, BTFIXUPCALL_NORM); + + if (sun4c_vacinfo.do_hwflushes) { + BTFIXUPSET_CALL(sun4c_flush_page, sun4c_flush_page_hw, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(sun4c_flush_segment, sun4c_flush_segment_hw, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(sun4c_flush_context, sun4c_flush_context_hw, BTFIXUPCALL_NORM); + } else { + BTFIXUPSET_CALL(sun4c_flush_page, sun4c_flush_page_sw, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(sun4c_flush_segment, sun4c_flush_segment_sw, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(sun4c_flush_context, sun4c_flush_context_sw, BTFIXUPCALL_NORM); + } + + BTFIXUPSET_CALL(flush_tlb_mm, sun4c_flush_tlb_mm, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_mm, sun4c_flush_cache_mm, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(destroy_context, sun4c_destroy_context, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(switch_mm, sun4c_switch_mm, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_page, sun4c_flush_cache_page, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_page, sun4c_flush_tlb_page, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_range, sun4c_flush_tlb_range, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_cache_range, sun4c_flush_cache_range, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(__flush_page_to_ram, sun4c_flush_page_to_ram, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(flush_tlb_all, sun4c_flush_tlb_all, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(flush_sig_insns, sun4c_flush_sig_insns, BTFIXUPCALL_NOP); + + BTFIXUPSET_CALL(set_pte, sun4c_set_pte, BTFIXUPCALL_STO1O0); + + BTFIXUPSET_CALL(pte_pfn, sun4c_pte_pfn, BTFIXUPCALL_NORM); +#if 0 /* PAGE_SHIFT <= 12 */ /* Eek. Investigate. XXX */ + BTFIXUPSET_CALL(pmd_page, sun4c_pmd_page, BTFIXUPCALL_ANDNINT(PAGE_SIZE - 1)); +#else + BTFIXUPSET_CALL(pmd_page, sun4c_pmd_page, BTFIXUPCALL_NORM); +#endif + BTFIXUPSET_CALL(pmd_set, sun4c_pmd_set, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pmd_populate, sun4c_pmd_populate, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(pte_present, sun4c_pte_present, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pte_clear, sun4c_pte_clear, BTFIXUPCALL_STG0O0); + + BTFIXUPSET_CALL(pmd_bad, sun4c_pmd_bad, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pmd_present, sun4c_pmd_present, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pmd_clear, sun4c_pmd_clear, BTFIXUPCALL_STG0O0); + + BTFIXUPSET_CALL(pgd_none, sun4c_pgd_none, BTFIXUPCALL_RETINT(0)); + BTFIXUPSET_CALL(pgd_bad, sun4c_pgd_bad, BTFIXUPCALL_RETINT(0)); + BTFIXUPSET_CALL(pgd_present, sun4c_pgd_present, BTFIXUPCALL_RETINT(1)); + BTFIXUPSET_CALL(pgd_clear, sun4c_pgd_clear, BTFIXUPCALL_NOP); + + BTFIXUPSET_CALL(mk_pte, sun4c_mk_pte, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(mk_pte_phys, sun4c_mk_pte_phys, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(mk_pte_io, sun4c_mk_pte_io, BTFIXUPCALL_NORM); + + BTFIXUPSET_INT(pte_modify_mask, _SUN4C_PAGE_CHG_MASK); + BTFIXUPSET_CALL(pmd_offset, sun4c_pmd_offset, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pte_offset_kernel, sun4c_pte_offset_kernel, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(free_pte_fast, sun4c_free_pte_fast, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pte_free, sun4c_pte_free, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pte_alloc_one_kernel, sun4c_pte_alloc_one_kernel, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pte_alloc_one, sun4c_pte_alloc_one, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(free_pmd_fast, sun4c_free_pmd_fast, BTFIXUPCALL_NOP); + BTFIXUPSET_CALL(pmd_alloc_one, sun4c_pmd_alloc_one, BTFIXUPCALL_RETO0); + BTFIXUPSET_CALL(free_pgd_fast, sun4c_free_pgd_fast, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(get_pgd_fast, sun4c_get_pgd_fast, BTFIXUPCALL_NORM); + + BTFIXUPSET_HALF(pte_writei, _SUN4C_PAGE_WRITE); + BTFIXUPSET_HALF(pte_dirtyi, _SUN4C_PAGE_MODIFIED); + BTFIXUPSET_HALF(pte_youngi, _SUN4C_PAGE_ACCESSED); + BTFIXUPSET_HALF(pte_filei, _SUN4C_PAGE_FILE); + BTFIXUPSET_HALF(pte_wrprotecti, _SUN4C_PAGE_WRITE|_SUN4C_PAGE_SILENT_WRITE); + BTFIXUPSET_HALF(pte_mkcleani, _SUN4C_PAGE_MODIFIED|_SUN4C_PAGE_SILENT_WRITE); + BTFIXUPSET_HALF(pte_mkoldi, _SUN4C_PAGE_ACCESSED|_SUN4C_PAGE_SILENT_READ); + BTFIXUPSET_CALL(pte_mkwrite, sun4c_pte_mkwrite, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pte_mkdirty, sun4c_pte_mkdirty, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pte_mkyoung, sun4c_pte_mkyoung, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(update_mmu_cache, sun4c_update_mmu_cache, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(pte_to_pgoff, sun4c_pte_to_pgoff, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pgoff_to_pte, sun4c_pgoff_to_pte, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(mmu_lockarea, sun4c_lockarea, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(mmu_unlockarea, sun4c_unlockarea, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(mmu_get_scsi_one, sun4c_get_scsi_one, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(mmu_get_scsi_sgl, sun4c_get_scsi_sgl, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(mmu_release_scsi_one, sun4c_release_scsi_one, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(mmu_release_scsi_sgl, sun4c_release_scsi_sgl, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(mmu_map_dma_area, sun4c_map_dma_area, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(mmu_unmap_dma_area, sun4c_unmap_dma_area, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(sparc_mapiorange, sun4c_mapiorange, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(sparc_unmapiorange, sun4c_unmapiorange, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(__swp_type, sun4c_swp_type, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(__swp_offset, sun4c_swp_offset, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(__swp_entry, sun4c_swp_entry, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(alloc_thread_info_node, sun4c_alloc_thread_info_node, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(free_thread_info, sun4c_free_thread_info, BTFIXUPCALL_NORM); + + BTFIXUPSET_CALL(mmu_info, sun4c_mmu_info, BTFIXUPCALL_NORM); + + /* These should _never_ get called with two level tables. */ + BTFIXUPSET_CALL(pgd_set, sun4c_pgd_set, BTFIXUPCALL_NOP); + BTFIXUPSET_CALL(pgd_page_vaddr, sun4c_pgd_page, BTFIXUPCALL_RETO0); +} diff --git a/trunk/arch/sparc/mm/ultra.S b/trunk/arch/sparc/mm/ultra.S index 874162a11ceb..b57a5942ba64 100644 --- a/trunk/arch/sparc/mm/ultra.S +++ b/trunk/arch/sparc/mm/ultra.S @@ -495,11 +495,11 @@ xcall_fetch_glob_regs: stx %o7, [%g1 + GR_SNAP_O7] stx %i7, [%g1 + GR_SNAP_I7] /* Don't try this at home kids... */ - rdpr %cwp, %g3 - sub %g3, 1, %g7 + rdpr %cwp, %g2 + sub %g2, 1, %g7 wrpr %g7, %cwp mov %i7, %g7 - wrpr %g3, %cwp + wrpr %g2, %cwp stx %g7, [%g1 + GR_SNAP_RPC] sethi %hi(trap_block), %g7 or %g7, %lo(trap_block), %g7 diff --git a/trunk/arch/sparc/mm/viking.S b/trunk/arch/sparc/mm/viking.S index bf8ee0613ae7..6dfcc13d3100 100644 --- a/trunk/arch/sparc/mm/viking.S +++ b/trunk/arch/sparc/mm/viking.S @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef CONFIG_SMP .data diff --git a/trunk/arch/sparc/prom/Makefile b/trunk/arch/sparc/prom/Makefile index 020300b18c0b..8287bbe88768 100644 --- a/trunk/arch/sparc/prom/Makefile +++ b/trunk/arch/sparc/prom/Makefile @@ -10,6 +10,7 @@ lib-$(CONFIG_SPARC32) += memory.o lib-y += misc_$(BITS).o lib-$(CONFIG_SPARC32) += mp.o lib-$(CONFIG_SPARC32) += ranges.o +lib-$(CONFIG_SPARC32) += segment.o lib-y += console_$(BITS).o lib-y += printf.o lib-y += tree_$(BITS).o diff --git a/trunk/arch/sparc/prom/segment.c b/trunk/arch/sparc/prom/segment.c new file mode 100644 index 000000000000..86a663f1d3c5 --- /dev/null +++ b/trunk/arch/sparc/prom/segment.c @@ -0,0 +1,28 @@ +/* + * segment.c: Prom routine to map segments in other contexts before + * a standalone is completely mapped. This is for sun4 and + * sun4c architectures only. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#include +#include +#include +#include +#include + +extern void restore_current(void); + +/* Set physical segment 'segment' at virtual address 'vaddr' in + * context 'ctx'. + */ +void +prom_putsegment(int ctx, unsigned long vaddr, int segment) +{ + unsigned long flags; + spin_lock_irqsave(&prom_lock, flags); + (*(romvec->pv_setctxt))(ctx, (char *) vaddr, segment); + restore_current(); + spin_unlock_irqrestore(&prom_lock, flags); +} diff --git a/trunk/arch/tile/Kconfig b/trunk/arch/tile/Kconfig index 74239dd77e06..96033e2d6845 100644 --- a/trunk/arch/tile/Kconfig +++ b/trunk/arch/tile/Kconfig @@ -11,7 +11,6 @@ config TILE select GENERIC_IRQ_PROBE select GENERIC_PENDING_IRQ if SMP select GENERIC_IRQ_SHOW - select HAVE_SYSCALL_WRAPPERS if TILEGX select SYS_HYPERVISOR select ARCH_HAVE_NMI_SAFE_CMPXCHG diff --git a/trunk/arch/tile/include/asm/thread_info.h b/trunk/arch/tile/include/asm/thread_info.h index 656c486e64fa..bc4f562bd459 100644 --- a/trunk/arch/tile/include/asm/thread_info.h +++ b/trunk/arch/tile/include/asm/thread_info.h @@ -77,14 +77,16 @@ struct thread_info { #ifndef __ASSEMBLY__ -void arch_release_thread_info(struct thread_info *info); - /* How to get the thread information struct from C. */ register unsigned long stack_pointer __asm__("sp"); #define current_thread_info() \ ((struct thread_info *)(stack_pointer & -THREAD_SIZE)) +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR +extern struct thread_info *alloc_thread_info_node(struct task_struct *task, int node); +extern void free_thread_info(struct thread_info *info); + /* Sit on a nap instruction until interrupted. */ extern void smp_nap(void); @@ -98,14 +100,9 @@ extern void cpu_idle_on_new_stack(struct thread_info *old_ti, #else /* __ASSEMBLY__ */ -/* - * How to get the thread information struct from assembly. - * Note that we use different macros since different architectures - * have different semantics in their "mm" instruction and we would - * like to guarantee that the macro expands to exactly one instruction. - */ +/* how to get the thread information struct from ASM */ #ifdef __tilegx__ -#define EXTRACT_THREAD_INFO(reg) mm reg, zero, LOG2_THREAD_SIZE, 63 +#define GET_THREAD_INFO(reg) move reg, sp; mm reg, zero, LOG2_THREAD_SIZE, 63 #else #define GET_THREAD_INFO(reg) mm reg, sp, zero, LOG2_THREAD_SIZE, 31 #endif diff --git a/trunk/arch/tile/kernel/Makefile b/trunk/arch/tile/kernel/Makefile index 0d826faf8f35..b4dbc057baad 100644 --- a/trunk/arch/tile/kernel/Makefile +++ b/trunk/arch/tile/kernel/Makefile @@ -3,7 +3,7 @@ # extra-y := vmlinux.lds head_$(BITS).o -obj-y := backtrace.o entry.o irq.o messaging.o \ +obj-y := backtrace.o entry.o init_task.o irq.o messaging.o \ pci-dma.o proc.o process.o ptrace.o reboot.o \ setup.o signal.o single_step.o stack.o sys.o sysfs.o time.o traps.o \ intvec_$(BITS).o regs_$(BITS).o tile-desc_$(BITS).o diff --git a/trunk/arch/tile/kernel/compat_signal.c b/trunk/arch/tile/kernel/compat_signal.c index cdef6e5ec022..77763ccd5a7d 100644 --- a/trunk/arch/tile/kernel/compat_signal.c +++ b/trunk/arch/tile/kernel/compat_signal.c @@ -403,17 +403,19 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, * Set up registers for signal handler. * Registers that we don't modify keep the value they had from * user-space at the time we took the signal. - * We always pass siginfo and mcontext, regardless of SA_SIGINFO, - * since some things rely on this (e.g. glibc's debug/segfault.c). */ regs->pc = ptr_to_compat_reg(ka->sa.sa_handler); regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */ regs->sp = ptr_to_compat_reg(frame); regs->lr = restorer; regs->regs[0] = (unsigned long) usig; - regs->regs[1] = ptr_to_compat_reg(&frame->info); - regs->regs[2] = ptr_to_compat_reg(&frame->uc); - regs->flags |= PT_FLAGS_CALLER_SAVES; + + if (ka->sa.sa_flags & SA_SIGINFO) { + /* Need extra arguments, so mark to restore caller-saves. */ + regs->regs[1] = ptr_to_compat_reg(&frame->info); + regs->regs[2] = ptr_to_compat_reg(&frame->uc); + regs->flags |= PT_FLAGS_CALLER_SAVES; + } /* * Notify any tracer that was single-stepping it. diff --git a/trunk/arch/tile/kernel/init_task.c b/trunk/arch/tile/kernel/init_task.c new file mode 100644 index 000000000000..928b31870669 --- /dev/null +++ b/trunk/arch/tile/kernel/init_task.c @@ -0,0 +1,59 @@ +/* + * Copyright 2010 Tilera Corporation. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for + * more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); + +/* + * Initial thread structure. + * + * We need to make sure that this is THREAD_SIZE aligned due to the + * way process stacks are handled. This is done by having a special + * "init_task" linker map entry.. + */ +union thread_union init_thread_union __init_task_data = { + INIT_THREAD_INFO(init_task) +}; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); +EXPORT_SYMBOL(init_task); + +/* + * per-CPU stack and boot info. + */ +DEFINE_PER_CPU(unsigned long, boot_sp) = + (unsigned long)init_stack + THREAD_SIZE; + +#ifdef CONFIG_SMP +DEFINE_PER_CPU(unsigned long, boot_pc) = (unsigned long)start_kernel; +#else +/* + * The variable must be __initdata since it references __init code. + * With CONFIG_SMP it is per-cpu data, which is exempt from validation. + */ +unsigned long __initdata boot_pc = (unsigned long)start_kernel; +#endif diff --git a/trunk/arch/tile/kernel/intvec_32.S b/trunk/arch/tile/kernel/intvec_32.S index 6943515100f8..5d56a1ef5ba5 100644 --- a/trunk/arch/tile/kernel/intvec_32.S +++ b/trunk/arch/tile/kernel/intvec_32.S @@ -838,18 +838,6 @@ STD_ENTRY(interrupt_return) .Lresume_userspace: FEEDBACK_REENTER(interrupt_return) - /* - * Use r33 to hold whether we have already loaded the callee-saves - * into ptregs. We don't want to do it twice in this loop, since - * then we'd clobber whatever changes are made by ptrace, etc. - * Get base of stack in r32. - */ - { - GET_THREAD_INFO(r32) - movei r33, 0 - } - -.Lretry_work_pending: /* * Disable interrupts so as to make sure we don't * miss an interrupt that sets any of the thread flags (like @@ -860,6 +848,9 @@ STD_ENTRY(interrupt_return) IRQ_DISABLE(r20, r21) TRACE_IRQS_OFF /* Note: clobbers registers r0-r29 */ + /* Get base of stack in r32; note r30/31 are used as arguments here. */ + GET_THREAD_INFO(r32) + /* Check to see if there is any work to do before returning to user. */ { @@ -875,18 +866,16 @@ STD_ENTRY(interrupt_return) /* * Make sure we have all the registers saved for signal - * handling, notify-resume, or single-step. Call out to C - * code to figure out exactly what we need to do for each flag bit, - * then if necessary, reload the flags and recheck. + * handling or single-step. Call out to C code to figure out + * exactly what we need to do for each flag bit, then if + * necessary, reload the flags and recheck. */ + push_extra_callee_saves r0 { PTREGS_PTR(r0, PTREGS_OFFSET_BASE) - bnz r33, 1f + jal do_work_pending } - push_extra_callee_saves r0 - movei r33, 1 -1: jal do_work_pending - bnz r0, .Lretry_work_pending + bnz r0, .Lresume_userspace /* * In the NMI case we @@ -1191,12 +1180,10 @@ handle_syscall: add r20, r20, tp lw r21, r20 addi r21, r21, 1 - { - sw r20, r21 - GET_THREAD_INFO(r31) - } + sw r20, r21 /* Trace syscalls, if requested. */ + GET_THREAD_INFO(r31) addi r31, r31, THREAD_INFO_FLAGS_OFFSET lw r30, r31 andi r30, r30, _TIF_SYSCALL_TRACE @@ -1375,10 +1362,7 @@ handle_ill: 3: /* set PC and continue */ lw r26, r24 - { - sw r28, r26 - GET_THREAD_INFO(r0) - } + sw r28, r26 /* * Clear TIF_SINGLESTEP to prevent recursion if we execute an ill. @@ -1386,6 +1370,7 @@ handle_ill: * need to clear it here and can't really impose on all other arches. * So what's another write between friends? */ + GET_THREAD_INFO(r0) addi r1, r0, THREAD_INFO_FLAGS_OFFSET { diff --git a/trunk/arch/tile/kernel/intvec_64.S b/trunk/arch/tile/kernel/intvec_64.S index 30ae76e50c44..49d9d6621682 100644 --- a/trunk/arch/tile/kernel/intvec_64.S +++ b/trunk/arch/tile/kernel/intvec_64.S @@ -646,20 +646,6 @@ STD_ENTRY(interrupt_return) .Lresume_userspace: FEEDBACK_REENTER(interrupt_return) - /* - * Use r33 to hold whether we have already loaded the callee-saves - * into ptregs. We don't want to do it twice in this loop, since - * then we'd clobber whatever changes are made by ptrace, etc. - */ - { - movei r33, 0 - move r32, sp - } - - /* Get base of stack in r32. */ - EXTRACT_THREAD_INFO(r32) - -.Lretry_work_pending: /* * Disable interrupts so as to make sure we don't * miss an interrupt that sets any of the thread flags (like @@ -670,6 +656,9 @@ STD_ENTRY(interrupt_return) IRQ_DISABLE(r20, r21) TRACE_IRQS_OFF /* Note: clobbers registers r0-r29 */ + /* Get base of stack in r32; note r30/31 are used as arguments here. */ + GET_THREAD_INFO(r32) + /* Check to see if there is any work to do before returning to user. */ { @@ -685,18 +674,16 @@ STD_ENTRY(interrupt_return) /* * Make sure we have all the registers saved for signal - * handling or notify-resume. Call out to C code to figure out + * handling or single-step. Call out to C code to figure out * exactly what we need to do for each flag bit, then if * necessary, reload the flags and recheck. */ + push_extra_callee_saves r0 { PTREGS_PTR(r0, PTREGS_OFFSET_BASE) - bnez r33, 1f + jal do_work_pending } - push_extra_callee_saves r0 - movei r33, 1 -1: jal do_work_pending - bnez r0, .Lretry_work_pending + bnez r0, .Lresume_userspace /* * In the NMI case we @@ -981,16 +968,11 @@ handle_syscall: shl16insli r20, r20, hw0(irq_stat + IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET) add r20, r20, tp ld4s r21, r20 - { - addi r21, r21, 1 - move r31, sp - } - { - st4 r20, r21 - EXTRACT_THREAD_INFO(r31) - } + addi r21, r21, 1 + st4 r20, r21 /* Trace syscalls, if requested. */ + GET_THREAD_INFO(r31) addi r31, r31, THREAD_INFO_FLAGS_OFFSET ld r30, r31 andi r30, r30, _TIF_SYSCALL_TRACE diff --git a/trunk/arch/tile/kernel/process.c b/trunk/arch/tile/kernel/process.c index f572c19c4082..2d5ef617bb39 100644 --- a/trunk/arch/tile/kernel/process.c +++ b/trunk/arch/tile/kernel/process.c @@ -114,10 +114,27 @@ void cpu_idle(void) } } +struct thread_info *alloc_thread_info_node(struct task_struct *task, int node) +{ + struct page *page; + gfp_t flags = GFP_KERNEL; + +#ifdef CONFIG_DEBUG_STACK_USAGE + flags |= __GFP_ZERO; +#endif + + page = alloc_pages_node(node, flags, THREAD_SIZE_ORDER); + if (!page) + return NULL; + + return (struct thread_info *)page_address(page); +} + /* - * Release a thread_info structure + * Free a thread_info node, and all of its derivative + * data structures. */ -void arch_release_thread_info(struct thread_info *info) +void free_thread_info(struct thread_info *info) { struct single_step_state *step_state = info->step_state; @@ -152,6 +169,8 @@ void arch_release_thread_info(struct thread_info *info) */ kfree(step_state); } + + free_pages((unsigned long)info, THREAD_SIZE_ORDER); } static void save_arch_state(struct thread_struct *t); @@ -548,10 +567,6 @@ struct task_struct *__sched _switch_to(struct task_struct *prev, */ int do_work_pending(struct pt_regs *regs, u32 thread_info_flags) { - /* If we enter in kernel mode, do nothing and exit the caller loop. */ - if (!user_mode(regs)) - return 0; - if (thread_info_flags & _TIF_NEED_RESCHED) { schedule(); return 1; @@ -574,7 +589,8 @@ int do_work_pending(struct pt_regs *regs, u32 thread_info_flags) return 1; } if (thread_info_flags & _TIF_SINGLESTEP) { - single_step_once(regs); + if ((regs->ex1 & SPR_EX_CONTEXT_1_1__PL_MASK) == 0) + single_step_once(regs); return 0; } panic("work_pending: bad flags %#x\n", thread_info_flags); diff --git a/trunk/arch/tile/kernel/setup.c b/trunk/arch/tile/kernel/setup.c index 98d80eb49ddb..bff23f476110 100644 --- a/trunk/arch/tile/kernel/setup.c +++ b/trunk/arch/tile/kernel/setup.c @@ -61,22 +61,6 @@ unsigned long __initdata node_free_pfn[MAX_NUMNODES]; static unsigned long __initdata node_percpu[MAX_NUMNODES]; -/* - * per-CPU stack and boot info. - */ -DEFINE_PER_CPU(unsigned long, boot_sp) = - (unsigned long)init_stack + THREAD_SIZE; - -#ifdef CONFIG_SMP -DEFINE_PER_CPU(unsigned long, boot_pc) = (unsigned long)start_kernel; -#else -/* - * The variable must be __initdata since it references __init code. - * With CONFIG_SMP it is per-cpu data, which is exempt from validation. - */ -unsigned long __initdata boot_pc = (unsigned long)start_kernel; -#endif - #ifdef CONFIG_HIGHMEM /* Page frame index of end of lowmem on each controller. */ unsigned long __cpuinitdata node_lowmem_end_pfn[MAX_NUMNODES]; diff --git a/trunk/arch/tile/kernel/smpboot.c b/trunk/arch/tile/kernel/smpboot.c index 84873fbe8f27..172aef7d3159 100644 --- a/trunk/arch/tile/kernel/smpboot.c +++ b/trunk/arch/tile/kernel/smpboot.c @@ -222,7 +222,7 @@ void __cpuinit online_secondary(void) cpu_idle(); } -int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) +int __cpuinit __cpu_up(unsigned int cpu) { /* Wait 5s total for all CPUs for them to come online */ static int timeout; diff --git a/trunk/arch/um/drivers/mconsole_kern.c b/trunk/arch/um/drivers/mconsole_kern.c index 88e466b159dc..43b39d61b538 100644 --- a/trunk/arch/um/drivers/mconsole_kern.c +++ b/trunk/arch/um/drivers/mconsole_kern.c @@ -705,7 +705,6 @@ static void stack_proc(void *arg) struct task_struct *from = current, *to = arg; to->thread.saved_task = from; - rcu_switch_from(from); switch_to(from, to, from); } diff --git a/trunk/arch/um/include/asm/processor-generic.h b/trunk/arch/um/include/asm/processor-generic.h index 7827394a5b6c..98d01bc4fa92 100644 --- a/trunk/arch/um/include/asm/processor-generic.h +++ b/trunk/arch/um/include/asm/processor-generic.h @@ -68,6 +68,8 @@ struct thread_struct { .request = { 0 } \ } +extern struct task_struct *alloc_task_struct_node(int node); + static inline void release_thread(struct task_struct *task) { } diff --git a/trunk/arch/um/kernel/Makefile b/trunk/arch/um/kernel/Makefile index babe21826e3e..65a1c3d690ea 100644 --- a/trunk/arch/um/kernel/Makefile +++ b/trunk/arch/um/kernel/Makefile @@ -10,7 +10,7 @@ CPPFLAGS_vmlinux.lds := -DSTART=$(LDS_START) \ extra-y := vmlinux.lds clean-files := -obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \ +obj-y = config.o exec.o exitcode.o init_task.o irq.o ksyms.o mem.o \ physmem.o process.o ptrace.o reboot.o sigio.o \ signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o \ um_arch.o umid.o skas/ diff --git a/trunk/arch/um/kernel/init_task.c b/trunk/arch/um/kernel/init_task.c new file mode 100644 index 000000000000..ddc9698b66ed --- /dev/null +++ b/trunk/arch/um/kernel/init_task.c @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,intel.linux}.com) + * Licensed under the GPL + */ + +#include "linux/sched.h" +#include "linux/init_task.h" +#include "linux/fs.h" +#include "linux/module.h" +#include "linux/mqueue.h" +#include "asm/uaccess.h" + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ + +struct task_struct init_task = INIT_TASK(init_task); + +EXPORT_SYMBOL(init_task); + +/* + * Initial thread structure. + * + * We need to make sure that this is aligned due to the + * way process stacks are handled. This is done by having a special + * "init_task" linker map entry.. + */ + +union thread_union init_thread_union __init_task_data = + { INIT_THREAD_INFO(init_task) }; + +union thread_union cpu0_irqstack + __attribute__((__section__(".data..init_irqstack"))) = + { INIT_THREAD_INFO(init_task) }; diff --git a/trunk/arch/um/kernel/smp.c b/trunk/arch/um/kernel/smp.c index a02b7e9e6b94..6f588e160fb0 100644 --- a/trunk/arch/um/kernel/smp.c +++ b/trunk/arch/um/kernel/smp.c @@ -140,7 +140,7 @@ void smp_prepare_boot_cpu(void) set_cpu_online(smp_processor_id(), true); } -int __cpu_up(unsigned int cpu, struct task_struct *tidle) +int __cpu_up(unsigned int cpu) { cpu_set(cpu, smp_commenced_mask); while (!cpu_online(cpu)) diff --git a/trunk/arch/um/kernel/um_arch.c b/trunk/arch/um/kernel/um_arch.c index 4db8770906ca..ba00eae45aad 100644 --- a/trunk/arch/um/kernel/um_arch.c +++ b/trunk/arch/um/kernel/um_arch.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -48,10 +47,6 @@ struct cpuinfo_um boot_cpu_data = { .ipi_pipe = { -1, -1 } }; -union thread_union cpu0_irqstack - __attribute__((__section__(".data..init_irqstack"))) = - { INIT_THREAD_INFO(init_task) }; - unsigned long thread_saved_pc(struct task_struct *task) { /* FIXME: Need to look up userspace_pid by cpu */ diff --git a/trunk/arch/unicore32/Makefile b/trunk/arch/unicore32/Makefile index b6f5c4c1eaf9..6af4bc415f2b 100644 --- a/trunk/arch/unicore32/Makefile +++ b/trunk/arch/unicore32/Makefile @@ -33,6 +33,7 @@ endif CHECKFLAGS += -D__unicore32__ head-y := arch/unicore32/kernel/head.o +head-y += arch/unicore32/kernel/init_task.o core-y += arch/unicore32/kernel/ core-y += arch/unicore32/mm/ diff --git a/trunk/arch/unicore32/kernel/Makefile b/trunk/arch/unicore32/kernel/Makefile index 324010156958..aeb0f181568e 100644 --- a/trunk/arch/unicore32/kernel/Makefile +++ b/trunk/arch/unicore32/kernel/Makefile @@ -29,4 +29,4 @@ obj-$(CONFIG_PUV3_NB0916) += puv3-nb0916.o head-y := head.o obj-$(CONFIG_DEBUG_LL) += debug.o -extra-y := $(head-y) vmlinux.lds +extra-y := $(head-y) init_task.o vmlinux.lds diff --git a/trunk/arch/unicore32/kernel/init_task.c b/trunk/arch/unicore32/kernel/init_task.c new file mode 100644 index 000000000000..a35a1e50e4f4 --- /dev/null +++ b/trunk/arch/unicore32/kernel/init_task.c @@ -0,0 +1,44 @@ +/* + * linux/arch/unicore32/kernel/init_task.c + * + * Code specific to PKUnity SoC and UniCore ISA + * + * Copyright (C) 2001-2010 GUAN Xue-tao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +/* + * Initial thread structure. + * + * We need to make sure that this is 8192-byte aligned due to the + * way process stacks are handled. This is done by making sure + * the linker maps this in the .text segment right after head.S, + * and making head.S ensure the proper alignment. + * + * The things we do for performance.. + */ +union thread_union init_thread_union __init_task_data = { + INIT_THREAD_INFO(init_task) }; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); +EXPORT_SYMBOL(init_task); diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index 2787fbec7aed..1d14cc6b79ad 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -77,13 +77,11 @@ config X86 select GENERIC_CLOCKEVENTS_MIN_ADJUST select IRQ_FORCED_THREADING select USE_GENERIC_SMP_HELPERS if SMP - select HAVE_BPF_JIT if X86_64 + select HAVE_BPF_JIT if (X86_64 && NET) select CLKEVT_I8253 select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_IOMAP - select DCACHE_WORD_ACCESS - select GENERIC_SMP_IDLE_THREAD - select HAVE_ARCH_SECCOMP_FILTER + select DCACHE_WORD_ACCESS if !DEBUG_PAGEALLOC config INSTRUCTION_DECODER def_bool (KPROBES || PERF_EVENTS) @@ -162,6 +160,9 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM def_bool X86_XADD +config ARCH_HAS_CPU_IDLE_WAIT + def_bool y + config GENERIC_CALIBRATE_DELAY def_bool y diff --git a/trunk/arch/x86/Makefile b/trunk/arch/x86/Makefile index 277418ff8b52..41a7237606a3 100644 --- a/trunk/arch/x86/Makefile +++ b/trunk/arch/x86/Makefile @@ -134,9 +134,6 @@ KBUILD_CFLAGS += $(call cc-option,-mno-avx,) KBUILD_CFLAGS += $(mflags-y) KBUILD_AFLAGS += $(mflags-y) -archscripts: - $(Q)$(MAKE) $(build)=arch/x86/tools relocs - ### # Syscall table generation @@ -149,6 +146,7 @@ archheaders: head-y := arch/x86/kernel/head_$(BITS).o head-y += arch/x86/kernel/head$(BITS).o head-y += arch/x86/kernel/head.o +head-y += arch/x86/kernel/init_task.o libs-y += arch/x86/lib/ diff --git a/trunk/arch/x86/boot/compressed/Makefile b/trunk/arch/x86/boot/compressed/Makefile index e398bb5d63bb..fd55a2ff3ad8 100644 --- a/trunk/arch/x86/boot/compressed/Makefile +++ b/trunk/arch/x86/boot/compressed/Makefile @@ -40,12 +40,13 @@ OBJCOPYFLAGS_vmlinux.bin := -R .comment -S $(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) -targets += vmlinux.bin.all vmlinux.relocs -CMD_RELOCS = arch/x86/tools/relocs +targets += vmlinux.bin.all vmlinux.relocs relocs +hostprogs-$(CONFIG_X86_NEED_RELOCS) += relocs + quiet_cmd_relocs = RELOCS $@ - cmd_relocs = $(CMD_RELOCS) $< > $@;$(CMD_RELOCS) --abs-relocs $< -$(obj)/vmlinux.relocs: vmlinux FORCE + cmd_relocs = $(obj)/relocs $< > $@;$(obj)/relocs --abs-relocs $< +$(obj)/vmlinux.relocs: vmlinux $(obj)/relocs FORCE $(call if_changed,relocs) vmlinux.bin.all-y := $(obj)/vmlinux.bin diff --git a/trunk/arch/x86/tools/relocs.c b/trunk/arch/x86/boot/compressed/relocs.c similarity index 76% rename from trunk/arch/x86/tools/relocs.c rename to trunk/arch/x86/boot/compressed/relocs.c index b43cfcd9bf40..d3c0b0277666 100644 --- a/trunk/arch/x86/tools/relocs.c +++ b/trunk/arch/x86/boot/compressed/relocs.c @@ -18,8 +18,6 @@ static void die(char *fmt, ...); static Elf32_Ehdr ehdr; static unsigned long reloc_count, reloc_idx; static unsigned long *relocs; -static unsigned long reloc16_count, reloc16_idx; -static unsigned long *relocs16; struct section { Elf32_Shdr shdr; @@ -30,86 +28,52 @@ struct section { }; static struct section *secs; -enum symtype { - S_ABS, - S_REL, - S_SEG, - S_LIN, - S_NSYMTYPES -}; - -static const char * const sym_regex_kernel[S_NSYMTYPES] = { /* * Following symbols have been audited. There values are constant and do * not change if bzImage is loaded at a different physical address than * the address for which it has been compiled. Don't warn user about * absolute relocations present w.r.t these symbols. */ - [S_ABS] = +static const char abs_sym_regex[] = "^(xen_irq_disable_direct_reloc$|" "xen_save_fl_direct_reloc$|" "VDSO|" - "__crc_)", + "__crc_)"; +static regex_t abs_sym_regex_c; +static int is_abs_reloc(const char *sym_name) +{ + return !regexec(&abs_sym_regex_c, sym_name, 0, NULL, 0); +} /* * These symbols are known to be relative, even if the linker marks them * as absolute (typically defined outside any section in the linker script.) */ - [S_REL] = - "^(__init_(begin|end)|" - "__x86_cpu_dev_(start|end)|" - "(__parainstructions|__alt_instructions)(|_end)|" - "(__iommu_table|__apicdrivers|__smp_locks)(|_end)|" - "_end)$" -}; - - -static const char * const sym_regex_realmode[S_NSYMTYPES] = { -/* - * These are 16-bit segment symbols when compiling 16-bit code. - */ - [S_SEG] = - "^real_mode_seg$", - -/* - * These are offsets belonging to segments, as opposed to linear addresses, - * when compiling 16-bit code. - */ - [S_LIN] = - "^pa_", -}; - -static const char * const *sym_regex; - -static regex_t sym_regex_c[S_NSYMTYPES]; -static int is_reloc(enum symtype type, const char *sym_name) +static const char rel_sym_regex[] = + "^_end$"; +static regex_t rel_sym_regex_c; +static int is_rel_reloc(const char *sym_name) { - return sym_regex[type] && - !regexec(&sym_regex_c[type], sym_name, 0, NULL, 0); + return !regexec(&rel_sym_regex_c, sym_name, 0, NULL, 0); } -static void regex_init(int use_real_mode) +static void regex_init(void) { char errbuf[128]; int err; - int i; - - if (use_real_mode) - sym_regex = sym_regex_realmode; - else - sym_regex = sym_regex_kernel; - - for (i = 0; i < S_NSYMTYPES; i++) { - if (!sym_regex[i]) - continue; - - err = regcomp(&sym_regex_c[i], sym_regex[i], - REG_EXTENDED|REG_NOSUB); + + err = regcomp(&abs_sym_regex_c, abs_sym_regex, + REG_EXTENDED|REG_NOSUB); + if (err) { + regerror(err, &abs_sym_regex_c, errbuf, sizeof errbuf); + die("%s", errbuf); + } - if (err) { - regerror(err, &sym_regex_c[i], errbuf, sizeof errbuf); - die("%s", errbuf); - } + err = regcomp(&rel_sym_regex_c, rel_sym_regex, + REG_EXTENDED|REG_NOSUB); + if (err) { + regerror(err, &rel_sym_regex_c, errbuf, sizeof errbuf); + die("%s", errbuf); } } @@ -190,10 +154,6 @@ static const char *rel_type(unsigned type) REL_TYPE(R_386_RELATIVE), REL_TYPE(R_386_GOTOFF), REL_TYPE(R_386_GOTPC), - REL_TYPE(R_386_8), - REL_TYPE(R_386_PC8), - REL_TYPE(R_386_16), - REL_TYPE(R_386_PC16), #undef REL_TYPE }; const char *name = "unknown type rel type name"; @@ -229,7 +189,7 @@ static const char *sym_name(const char *sym_strtab, Elf32_Sym *sym) name = sym_strtab + sym->st_name; } else { - name = sec_name(sym->st_shndx); + name = sec_name(secs[sym->st_shndx].shdr.sh_name); } return name; } @@ -443,11 +403,13 @@ static void print_absolute_symbols(void) for (i = 0; i < ehdr.e_shnum; i++) { struct section *sec = &secs[i]; char *sym_strtab; + Elf32_Sym *sh_symtab; int j; if (sec->shdr.sh_type != SHT_SYMTAB) { continue; } + sh_symtab = sec->symtab; sym_strtab = sec->link->strtab; for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) { Elf32_Sym *sym; @@ -512,7 +474,7 @@ static void print_absolute_relocs(void) * Before warning check if this absolute symbol * relocation is harmless. */ - if (is_reloc(S_ABS, name) || is_reloc(S_REL, name)) + if (is_abs_reloc(name) || is_rel_reloc(name)) continue; if (!printed) { @@ -536,8 +498,7 @@ static void print_absolute_relocs(void) printf("\n"); } -static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym), - int use_real_mode) +static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym)) { int i; /* Walk through the relocations */ @@ -562,67 +523,30 @@ static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym), Elf32_Rel *rel; Elf32_Sym *sym; unsigned r_type; - const char *symname; - int shn_abs; - rel = &sec->reltab[j]; sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; r_type = ELF32_R_TYPE(rel->r_info); - - shn_abs = sym->st_shndx == SHN_ABS; - + /* Don't visit relocations to absolute symbols */ + if (sym->st_shndx == SHN_ABS && + !is_rel_reloc(sym_name(sym_strtab, sym))) { + continue; + } switch (r_type) { case R_386_NONE: case R_386_PC32: - case R_386_PC16: - case R_386_PC8: /* * NONE can be ignored and and PC relative * relocations don't need to be adjusted. */ break; - - case R_386_16: - symname = sym_name(sym_strtab, sym); - if (!use_real_mode) - goto bad; - if (shn_abs) { - if (is_reloc(S_ABS, symname)) - break; - else if (!is_reloc(S_SEG, symname)) - goto bad; - } else { - if (is_reloc(S_LIN, symname)) - goto bad; - else - break; - } - visit(rel, sym); - break; - case R_386_32: - symname = sym_name(sym_strtab, sym); - if (shn_abs) { - if (is_reloc(S_ABS, symname)) - break; - else if (!is_reloc(S_REL, symname)) - goto bad; - } else { - if (use_real_mode && - !is_reloc(S_LIN, symname)) - break; - } + /* Visit relocations that need to be adjusted */ visit(rel, sym); break; default: die("Unsupported relocation type: %s (%d)\n", rel_type(r_type), r_type); break; - bad: - symname = sym_name(sym_strtab, sym); - die("Invalid %s %s relocation: %s\n", - shn_abs ? "absolute" : "relative", - rel_type(r_type), symname); } } } @@ -630,19 +554,13 @@ static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym), static void count_reloc(Elf32_Rel *rel, Elf32_Sym *sym) { - if (ELF32_R_TYPE(rel->r_info) == R_386_16) - reloc16_count++; - else - reloc_count++; + reloc_count += 1; } static void collect_reloc(Elf32_Rel *rel, Elf32_Sym *sym) { /* Remember the address that needs to be adjusted. */ - if (ELF32_R_TYPE(rel->r_info) == R_386_16) - relocs16[reloc16_idx++] = rel->r_offset; - else - relocs[reloc_idx++] = rel->r_offset; + relocs[reloc_idx++] = rel->r_offset; } static int cmp_relocs(const void *va, const void *vb) @@ -652,41 +570,23 @@ static int cmp_relocs(const void *va, const void *vb) return (*a == *b)? 0 : (*a > *b)? 1 : -1; } -static int write32(unsigned int v, FILE *f) -{ - unsigned char buf[4]; - - put_unaligned_le32(v, buf); - return fwrite(buf, 1, 4, f) == 4 ? 0 : -1; -} - -static void emit_relocs(int as_text, int use_real_mode) +static void emit_relocs(int as_text) { int i; /* Count how many relocations I have and allocate space for them. */ reloc_count = 0; - walk_relocs(count_reloc, use_real_mode); + walk_relocs(count_reloc); relocs = malloc(reloc_count * sizeof(relocs[0])); if (!relocs) { die("malloc of %d entries for relocs failed\n", reloc_count); } - - relocs16 = malloc(reloc16_count * sizeof(relocs[0])); - if (!relocs16) { - die("malloc of %d entries for relocs16 failed\n", - reloc16_count); - } /* Collect up the relocations */ reloc_idx = 0; - walk_relocs(collect_reloc, use_real_mode); - - if (reloc16_count && !use_real_mode) - die("Segment relocations found but --realmode not specified\n"); + walk_relocs(collect_reloc); /* Order the relocations for more efficient processing */ qsort(relocs, reloc_count, sizeof(relocs[0]), cmp_relocs); - qsort(relocs16, reloc16_count, sizeof(relocs16[0]), cmp_relocs); /* Print the relocations */ if (as_text) { @@ -695,83 +595,58 @@ static void emit_relocs(int as_text, int use_real_mode) */ printf(".section \".data.reloc\",\"a\"\n"); printf(".balign 4\n"); - if (use_real_mode) { - printf("\t.long %lu\n", reloc16_count); - for (i = 0; i < reloc16_count; i++) - printf("\t.long 0x%08lx\n", relocs16[i]); - printf("\t.long %lu\n", reloc_count); - for (i = 0; i < reloc_count; i++) { - printf("\t.long 0x%08lx\n", relocs[i]); - } - } else { - /* Print a stop */ - printf("\t.long 0x%08lx\n", (unsigned long)0); - for (i = 0; i < reloc_count; i++) { - printf("\t.long 0x%08lx\n", relocs[i]); - } + for (i = 0; i < reloc_count; i++) { + printf("\t .long 0x%08lx\n", relocs[i]); } - printf("\n"); } else { - if (use_real_mode) { - write32(reloc16_count, stdout); - for (i = 0; i < reloc16_count; i++) - write32(relocs16[i], stdout); - write32(reloc_count, stdout); - - /* Now print each relocation */ - for (i = 0; i < reloc_count; i++) - write32(relocs[i], stdout); - } else { - /* Print a stop */ - write32(0, stdout); - - /* Now print each relocation */ - for (i = 0; i < reloc_count; i++) { - write32(relocs[i], stdout); - } + unsigned char buf[4]; + /* Print a stop */ + fwrite("\0\0\0\0", 4, 1, stdout); + /* Now print each relocation */ + for (i = 0; i < reloc_count; i++) { + put_unaligned_le32(relocs[i], buf); + fwrite(buf, 4, 1, stdout); } } } static void usage(void) { - die("relocs [--abs-syms|--abs-relocs|--text|--realmode] vmlinux\n"); + die("relocs [--abs-syms |--abs-relocs | --text] vmlinux\n"); } int main(int argc, char **argv) { int show_absolute_syms, show_absolute_relocs; - int as_text, use_real_mode; + int as_text; const char *fname; FILE *fp; int i; + regex_init(); + show_absolute_syms = 0; show_absolute_relocs = 0; as_text = 0; - use_real_mode = 0; fname = NULL; for (i = 1; i < argc; i++) { char *arg = argv[i]; if (*arg == '-') { - if (strcmp(arg, "--abs-syms") == 0) { + if (strcmp(argv[1], "--abs-syms") == 0) { show_absolute_syms = 1; continue; } - if (strcmp(arg, "--abs-relocs") == 0) { + + if (strcmp(argv[1], "--abs-relocs") == 0) { show_absolute_relocs = 1; continue; } - if (strcmp(arg, "--text") == 0) { + else if (strcmp(argv[1], "--text") == 0) { as_text = 1; continue; } - if (strcmp(arg, "--realmode") == 0) { - use_real_mode = 1; - continue; - } } else if (!fname) { fname = arg; @@ -782,7 +657,6 @@ int main(int argc, char **argv) if (!fname) { usage(); } - regex_init(use_real_mode); fp = fopen(fname, "r"); if (!fp) { die("Cannot open %s: %s\n", @@ -801,6 +675,6 @@ int main(int argc, char **argv) print_absolute_relocs(); return 0; } - emit_relocs(as_text, use_real_mode); + emit_relocs(as_text); return 0; } diff --git a/trunk/arch/x86/ia32/ia32_aout.c b/trunk/arch/x86/ia32/ia32_aout.c index 07b3a68d2d29..4824fb45560f 100644 --- a/trunk/arch/x86/ia32/ia32_aout.c +++ b/trunk/arch/x86/ia32/ia32_aout.c @@ -294,7 +294,8 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) /* OK, This is the point of no return */ set_personality(PER_LINUX); - set_personality_ia32(false); + set_thread_flag(TIF_IA32); + current->mm->context.ia32_compat = 1; setup_new_exec(bprm); diff --git a/trunk/arch/x86/ia32/ia32_signal.c b/trunk/arch/x86/ia32/ia32_signal.c index 0b3f2354f6aa..a69245ba27e3 100644 --- a/trunk/arch/x86/ia32/ia32_signal.c +++ b/trunk/arch/x86/ia32/ia32_signal.c @@ -67,10 +67,6 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) switch (from->si_code >> 16) { case __SI_FAULT >> 16: break; - case __SI_SYS >> 16: - put_user_ex(from->si_syscall, &to->si_syscall); - put_user_ex(from->si_arch, &to->si_arch); - break; case __SI_CHLD >> 16: if (ia32) { put_user_ex(from->si_utime, &to->si_utime); diff --git a/trunk/arch/x86/include/asm/boot.h b/trunk/arch/x86/include/asm/boot.h index b13fe63bdc59..5e1a2eef3e7c 100644 --- a/trunk/arch/x86/include/asm/boot.h +++ b/trunk/arch/x86/include/asm/boot.h @@ -19,7 +19,7 @@ #ifdef CONFIG_X86_64 #define MIN_KERNEL_ALIGN_LG2 PMD_SHIFT #else -#define MIN_KERNEL_ALIGN_LG2 (PAGE_SHIFT + THREAD_SIZE_ORDER) +#define MIN_KERNEL_ALIGN_LG2 (PAGE_SHIFT + THREAD_ORDER) #endif #define MIN_KERNEL_ALIGN (_AC(1, UL) << MIN_KERNEL_ALIGN_LG2) diff --git a/trunk/arch/x86/include/asm/ia32.h b/trunk/arch/x86/include/asm/ia32.h index b04cbdb138cd..ee52760549f0 100644 --- a/trunk/arch/x86/include/asm/ia32.h +++ b/trunk/arch/x86/include/asm/ia32.h @@ -144,12 +144,6 @@ typedef struct compat_siginfo { int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ int _fd; } _sigpoll; - - struct { - unsigned int _call_addr; /* calling insn */ - int _syscall; /* triggering system call number */ - unsigned int _arch; /* AUDIT_ARCH_* of syscall */ - } _sigsys; } _sifields; } compat_siginfo_t; diff --git a/trunk/arch/x86/include/asm/irq_remapping.h b/trunk/arch/x86/include/asm/irq_remapping.h index 5fb9bbbd2f14..47d99934580f 100644 --- a/trunk/arch/x86/include/asm/irq_remapping.h +++ b/trunk/arch/x86/include/asm/irq_remapping.h @@ -1,101 +1,45 @@ -/* - * Copyright (C) 2012 Advanced Micro Devices, Inc. - * Author: Joerg Roedel - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * This header file contains the interface of the interrupt remapping code to - * the x86 interrupt management code. - */ +#ifndef _ASM_X86_IRQ_REMAPPING_H +#define _ASM_X86_IRQ_REMAPPING_H -#ifndef __X86_IRQ_REMAPPING_H -#define __X86_IRQ_REMAPPING_H - -#include +#define IRTE_DEST(dest) ((x2apic_mode) ? dest : dest << 8) #ifdef CONFIG_IRQ_REMAP - -extern int irq_remapping_enabled; - -extern void setup_irq_remapping_ops(void); -extern int irq_remapping_supported(void); -extern int irq_remapping_prepare(void); -extern int irq_remapping_enable(void); -extern void irq_remapping_disable(void); -extern int irq_remapping_reenable(int); -extern int irq_remap_enable_fault_handling(void); -extern int setup_ioapic_remapped_entry(int irq, - struct IO_APIC_route_entry *entry, - unsigned int destination, - int vector, - struct io_apic_irq_attr *attr); -extern int set_remapped_irq_affinity(struct irq_data *data, - const struct cpumask *mask, - bool force); -extern void free_remapped_irq(int irq); -extern void compose_remapped_msi_msg(struct pci_dev *pdev, - unsigned int irq, unsigned int dest, - struct msi_msg *msg, u8 hpet_id); -extern int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec); -extern int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq, - int index, int sub_handle); -extern int setup_hpet_msi_remapped(unsigned int irq, unsigned int id); - -#else /* CONFIG_IRQ_REMAP */ - -#define irq_remapping_enabled 0 - -static inline void setup_irq_remapping_ops(void) { } -static inline int irq_remapping_supported(void) { return 0; } -static inline int irq_remapping_prepare(void) { return -ENODEV; } -static inline int irq_remapping_enable(void) { return -ENODEV; } -static inline void irq_remapping_disable(void) { } -static inline int irq_remapping_reenable(int eim) { return -ENODEV; } -static inline int irq_remap_enable_fault_handling(void) { return -ENODEV; } -static inline int setup_ioapic_remapped_entry(int irq, - struct IO_APIC_route_entry *entry, - unsigned int destination, - int vector, - struct io_apic_irq_attr *attr) -{ - return -ENODEV; -} -static inline int set_remapped_irq_affinity(struct irq_data *data, - const struct cpumask *mask, - bool force) +static void irq_remap_modify_chip_defaults(struct irq_chip *chip); +static inline void prepare_irte(struct irte *irte, int vector, + unsigned int dest) { - return 0; + memset(irte, 0, sizeof(*irte)); + + irte->present = 1; + irte->dst_mode = apic->irq_dest_mode; + /* + * Trigger mode in the IRTE will always be edge, and for IO-APIC, the + * actual level or edge trigger will be setup in the IO-APIC + * RTE. This will help simplify level triggered irq migration. + * For more details, see the comments (in io_apic.c) explainig IO-APIC + * irq migration in the presence of interrupt-remapping. + */ + irte->trigger_mode = 0; + irte->dlvry_mode = apic->irq_delivery_mode; + irte->vector = vector; + irte->dest_id = IRTE_DEST(dest); + irte->redir_hint = 1; } -static inline void free_remapped_irq(int irq) { } -static inline void compose_remapped_msi_msg(struct pci_dev *pdev, - unsigned int irq, unsigned int dest, - struct msi_msg *msg, u8 hpet_id) +static inline bool irq_remapped(struct irq_cfg *cfg) { + return cfg->irq_2_iommu.iommu != NULL; } -static inline int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec) +#else +static void prepare_irte(struct irte *irte, int vector, unsigned int dest) { - return -ENODEV; } -static inline int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq, - int index, int sub_handle) +static inline bool irq_remapped(struct irq_cfg *cfg) { - return -ENODEV; + return false; } -static inline int setup_hpet_msi_remapped(unsigned int irq, unsigned int id) +static inline void irq_remap_modify_chip_defaults(struct irq_chip *chip) { - return -ENODEV; } -#endif /* CONFIG_IRQ_REMAP */ +#endif -#endif /* __X86_IRQ_REMAPPING_H */ +#endif /* _ASM_X86_IRQ_REMAPPING_H */ diff --git a/trunk/arch/x86/include/asm/kvm_para.h b/trunk/arch/x86/include/asm/kvm_para.h index 183922e13de1..734c3767cfac 100644 --- a/trunk/arch/x86/include/asm/kvm_para.h +++ b/trunk/arch/x86/include/asm/kvm_para.h @@ -170,9 +170,6 @@ static inline int kvm_para_available(void) unsigned int eax, ebx, ecx, edx; char signature[13]; - if (boot_cpu_data.cpuid_level < 0) - return 0; /* So we don't blow up on old processors */ - cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx); memcpy(signature + 0, &ebx, 4); memcpy(signature + 4, &ecx, 4); diff --git a/trunk/arch/x86/include/asm/nmi.h b/trunk/arch/x86/include/asm/nmi.h index 0e3793b821ef..fd3f9f18cf3f 100644 --- a/trunk/arch/x86/include/asm/nmi.h +++ b/trunk/arch/x86/include/asm/nmi.h @@ -27,8 +27,6 @@ void arch_trigger_all_cpu_backtrace(void); enum { NMI_LOCAL=0, NMI_UNKNOWN, - NMI_SERR, - NMI_IO_CHECK, NMI_MAX }; @@ -37,24 +35,8 @@ enum { typedef int (*nmi_handler_t)(unsigned int, struct pt_regs *); -struct nmiaction { - struct list_head list; - nmi_handler_t handler; - unsigned long flags; - const char *name; -}; - -#define register_nmi_handler(t, fn, fg, n) \ -({ \ - static struct nmiaction fn##_na = { \ - .handler = (fn), \ - .name = (n), \ - .flags = (fg), \ - }; \ - __register_nmi_handler((t), &fn##_na); \ -}) - -int __register_nmi_handler(unsigned int, struct nmiaction *); +int register_nmi_handler(unsigned int, nmi_handler_t, unsigned long, + const char *); void unregister_nmi_handler(unsigned int, const char *); diff --git a/trunk/arch/x86/include/asm/page_32_types.h b/trunk/arch/x86/include/asm/page_32_types.h index ef17af013475..ade619ff9e2a 100644 --- a/trunk/arch/x86/include/asm/page_32_types.h +++ b/trunk/arch/x86/include/asm/page_32_types.h @@ -15,8 +15,8 @@ */ #define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL) -#define THREAD_SIZE_ORDER 1 -#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) +#define THREAD_ORDER 1 +#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) #define STACKFAULT_STACK 0 #define DOUBLEFAULT_STACK 1 diff --git a/trunk/arch/x86/include/asm/page_64_types.h b/trunk/arch/x86/include/asm/page_64_types.h index 320f7bb95f76..7639dbf5d223 100644 --- a/trunk/arch/x86/include/asm/page_64_types.h +++ b/trunk/arch/x86/include/asm/page_64_types.h @@ -1,8 +1,8 @@ #ifndef _ASM_X86_PAGE_64_DEFS_H #define _ASM_X86_PAGE_64_DEFS_H -#define THREAD_SIZE_ORDER 1 -#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) +#define THREAD_ORDER 1 +#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) #define CURRENT_MASK (~(THREAD_SIZE - 1)) #define EXCEPTION_STACK_ORDER 0 diff --git a/trunk/arch/x86/include/asm/processor.h b/trunk/arch/x86/include/asm/processor.h index ccbb1ea99ccb..4fa7dcceb6c0 100644 --- a/trunk/arch/x86/include/asm/processor.h +++ b/trunk/arch/x86/include/asm/processor.h @@ -974,6 +974,8 @@ extern bool cpu_has_amd_erratum(const int *); #define cpu_has_amd_erratum(x) (false) #endif /* CONFIG_CPU_SUP_AMD */ +void cpu_idle_wait(void); + extern unsigned long arch_align_stack(unsigned long sp); extern void free_init_pages(char *what, unsigned long begin, unsigned long end); diff --git a/trunk/arch/x86/include/asm/smp.h b/trunk/arch/x86/include/asm/smp.h index f8cbc6f20e31..0434c400287c 100644 --- a/trunk/arch/x86/include/asm/smp.h +++ b/trunk/arch/x86/include/asm/smp.h @@ -62,8 +62,6 @@ DECLARE_EARLY_PER_CPU(int, x86_cpu_to_logical_apicid); /* Static state in head.S used to set up a CPU */ extern unsigned long stack_start; /* Initial stack pointer address */ -struct task_struct; - struct smp_ops { void (*smp_prepare_boot_cpu)(void); void (*smp_prepare_cpus)(unsigned max_cpus); @@ -72,7 +70,7 @@ struct smp_ops { void (*stop_other_cpus)(int wait); void (*smp_send_reschedule)(int cpu); - int (*cpu_up)(unsigned cpu, struct task_struct *tidle); + int (*cpu_up)(unsigned cpu); int (*cpu_disable)(void); void (*cpu_die)(unsigned int cpu); void (*play_dead)(void); @@ -115,9 +113,9 @@ static inline void smp_cpus_done(unsigned int max_cpus) smp_ops.smp_cpus_done(max_cpus); } -static inline int __cpu_up(unsigned int cpu, struct task_struct *tidle) +static inline int __cpu_up(unsigned int cpu) { - return smp_ops.cpu_up(cpu, tidle); + return smp_ops.cpu_up(cpu); } static inline int __cpu_disable(void) @@ -154,7 +152,7 @@ void cpu_disable_common(void); void native_smp_prepare_boot_cpu(void); void native_smp_prepare_cpus(unsigned int max_cpus); void native_smp_cpus_done(unsigned int max_cpus); -int native_cpu_up(unsigned int cpunum, struct task_struct *tidle); +int native_cpu_up(unsigned int cpunum); int native_cpu_disable(void); void native_cpu_die(unsigned int cpu); void native_play_dead(void); @@ -164,7 +162,6 @@ int wbinvd_on_all_cpus(void); void native_send_call_func_ipi(const struct cpumask *mask); void native_send_call_func_single_ipi(int cpu); -void x86_idle_thread_init(unsigned int cpu, struct task_struct *idle); void smp_store_cpu_info(int id); #define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu) diff --git a/trunk/arch/x86/include/asm/stat.h b/trunk/arch/x86/include/asm/stat.h index 7b3ddc348585..e0b1d9bbcbc6 100644 --- a/trunk/arch/x86/include/asm/stat.h +++ b/trunk/arch/x86/include/asm/stat.h @@ -25,12 +25,6 @@ struct stat { unsigned long __unused5; }; -/* We don't need to memset the whole thing just to initialize the padding */ -#define INIT_STRUCT_STAT_PADDING(st) do { \ - st.__unused4 = 0; \ - st.__unused5 = 0; \ -} while (0) - #define STAT64_HAS_BROKEN_ST_INO 1 /* This matches struct stat64 in glibc2.1, hence the absolutely @@ -69,12 +63,6 @@ struct stat64 { unsigned long long st_ino; }; -/* We don't need to memset the whole thing just to initialize the padding */ -#define INIT_STRUCT_STAT64_PADDING(st) do { \ - memset(&st.__pad0, 0, sizeof(st.__pad0)); \ - memset(&st.__pad3, 0, sizeof(st.__pad3)); \ -} while (0) - #else /* __i386__ */ struct stat { @@ -99,15 +87,6 @@ struct stat { unsigned long st_ctime_nsec; long __unused[3]; }; - -/* We don't need to memset the whole thing just to initialize the padding */ -#define INIT_STRUCT_STAT_PADDING(st) do { \ - st.__pad0 = 0; \ - st.__unused[0] = 0; \ - st.__unused[1] = 0; \ - st.__unused[2] = 0; \ -} while (0) - #endif /* for 32bit emulation and 32 bit kernels */ diff --git a/trunk/arch/x86/include/asm/syscall.h b/trunk/arch/x86/include/asm/syscall.h index 1ace47b62592..386b78686c4d 100644 --- a/trunk/arch/x86/include/asm/syscall.h +++ b/trunk/arch/x86/include/asm/syscall.h @@ -13,11 +13,9 @@ #ifndef _ASM_X86_SYSCALL_H #define _ASM_X86_SYSCALL_H -#include #include #include #include /* For NR_syscalls */ -#include /* for TS_COMPAT */ #include extern const unsigned long sys_call_table[]; @@ -90,12 +88,6 @@ static inline void syscall_set_arguments(struct task_struct *task, memcpy(®s->bx + i, args, n * sizeof(args[0])); } -static inline int syscall_get_arch(struct task_struct *task, - struct pt_regs *regs) -{ - return AUDIT_ARCH_I386; -} - #else /* CONFIG_X86_64 */ static inline void syscall_get_arguments(struct task_struct *task, @@ -220,25 +212,6 @@ static inline void syscall_set_arguments(struct task_struct *task, } } -static inline int syscall_get_arch(struct task_struct *task, - struct pt_regs *regs) -{ -#ifdef CONFIG_IA32_EMULATION - /* - * TS_COMPAT is set for 32-bit syscall entry and then - * remains set until we return to user mode. - * - * TIF_IA32 tasks should always have TS_COMPAT set at - * system call time. - * - * x32 tasks should be considered AUDIT_ARCH_X86_64. - */ - if (task_thread_info(task)->status & TS_COMPAT) - return AUDIT_ARCH_I386; -#endif - /* Both x32 and x86_64 are considered "64-bit". */ - return AUDIT_ARCH_X86_64; -} #endif /* CONFIG_X86_32 */ #endif /* _ASM_X86_SYSCALL_H */ diff --git a/trunk/arch/x86/include/asm/thread_info.h b/trunk/arch/x86/include/asm/thread_info.h index 73cfe0d309c9..ad6df8ccd715 100644 --- a/trunk/arch/x86/include/asm/thread_info.h +++ b/trunk/arch/x86/include/asm/thread_info.h @@ -155,6 +155,24 @@ struct thread_info { #define PREEMPT_ACTIVE 0x10000000 +/* thread information allocation */ +#ifdef CONFIG_DEBUG_STACK_USAGE +#define THREAD_FLAGS (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO) +#else +#define THREAD_FLAGS (GFP_KERNEL | __GFP_NOTRACK) +#endif + +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + +#define alloc_thread_info_node(tsk, node) \ +({ \ + struct page *page = alloc_pages_node(node, THREAD_FLAGS, \ + THREAD_ORDER); \ + struct thread_info *ret = page ? page_address(page) : NULL; \ + \ + ret; \ +}) + #ifdef CONFIG_X86_32 #define STACK_WARN (THREAD_SIZE/8) @@ -264,7 +282,8 @@ static inline bool is_ia32_task(void) #ifndef __ASSEMBLY__ extern void arch_task_cache_init(void); +extern void free_thread_info(struct thread_info *ti); extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src); -extern void arch_release_task_struct(struct task_struct *tsk); +#define arch_task_cache_init arch_task_cache_init #endif #endif /* _ASM_X86_THREAD_INFO_H */ diff --git a/trunk/arch/x86/include/asm/word-at-a-time.h b/trunk/arch/x86/include/asm/word-at-a-time.h index e58f03b206c3..6fe6767b7124 100644 --- a/trunk/arch/x86/include/asm/word-at-a-time.h +++ b/trunk/arch/x86/include/asm/word-at-a-time.h @@ -43,37 +43,4 @@ static inline unsigned long has_zero(unsigned long a) return ((a - REPEAT_BYTE(0x01)) & ~a) & REPEAT_BYTE(0x80); } -/* - * Load an unaligned word from kernel space. - * - * In the (very unlikely) case of the word being a page-crosser - * and the next page not being mapped, take the exception and - * return zeroes in the non-existing part. - */ -static inline unsigned long load_unaligned_zeropad(const void *addr) -{ - unsigned long ret, dummy; - - asm( - "1:\tmov %2,%0\n" - "2:\n" - ".section .fixup,\"ax\"\n" - "3:\t" - "lea %2,%1\n\t" - "and %3,%1\n\t" - "mov (%1),%0\n\t" - "leal %2,%%ecx\n\t" - "andl %4,%%ecx\n\t" - "shll $3,%%ecx\n\t" - "shr %%cl,%0\n\t" - "jmp 2b\n" - ".previous\n" - _ASM_EXTABLE(1b, 3b) - :"=&r" (ret),"=&c" (dummy) - :"m" (*(unsigned long *)addr), - "i" (-sizeof(unsigned long)), - "i" (sizeof(unsigned long)-1)); - return ret; -} - #endif /* _ASM_WORD_AT_A_TIME_H */ diff --git a/trunk/arch/x86/kernel/Makefile b/trunk/arch/x86/kernel/Makefile index 56ebd1f98447..532d2e090e6f 100644 --- a/trunk/arch/x86/kernel/Makefile +++ b/trunk/arch/x86/kernel/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -extra-y := head_$(BITS).o head$(BITS).o head.o vmlinux.lds +extra-y := head_$(BITS).o head$(BITS).o head.o init_task.o vmlinux.lds CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE) diff --git a/trunk/arch/x86/kernel/acpi/boot.c b/trunk/arch/x86/kernel/acpi/boot.c index 7c439fe4941b..a415b1f44365 100644 --- a/trunk/arch/x86/kernel/acpi/boot.c +++ b/trunk/arch/x86/kernel/acpi/boot.c @@ -593,7 +593,7 @@ void __init acpi_set_irq_model_ioapic(void) #ifdef CONFIG_ACPI_HOTPLUG_CPU #include -static void __cpuinit acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) +static void __cpuinitdata acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) { #ifdef CONFIG_ACPI_NUMA int nid; diff --git a/trunk/arch/x86/kernel/apic/apic.c b/trunk/arch/x86/kernel/apic/apic.c index 3722179a49db..edc24480469f 100644 --- a/trunk/arch/x86/kernel/apic/apic.c +++ b/trunk/arch/x86/kernel/apic/apic.c @@ -35,7 +35,6 @@ #include #include -#include #include #include #include @@ -1442,8 +1441,8 @@ void __init bsp_end_local_APIC_setup(void) * Now that local APIC setup is completed for BP, configure the fault * handling for interrupt remapping. */ - if (irq_remapping_enabled) - irq_remap_enable_fault_handling(); + if (intr_remapping_enabled) + enable_drhd_fault_handling(); } @@ -1518,7 +1517,7 @@ void enable_x2apic(void) int __init enable_IR(void) { #ifdef CONFIG_IRQ_REMAP - if (!irq_remapping_supported()) { + if (!intr_remapping_supported()) { pr_debug("intr-remapping not supported\n"); return -1; } @@ -1529,7 +1528,7 @@ int __init enable_IR(void) return -1; } - return irq_remapping_enable(); + return enable_intr_remapping(); #endif return -1; } @@ -1538,13 +1537,10 @@ void __init enable_IR_x2apic(void) { unsigned long flags; int ret, x2apic_enabled = 0; - int hardware_init_ret; + int dmar_table_init_ret; - /* Make sure irq_remap_ops are initialized */ - setup_irq_remapping_ops(); - - hardware_init_ret = irq_remapping_prepare(); - if (hardware_init_ret && !x2apic_supported()) + dmar_table_init_ret = dmar_table_init(); + if (dmar_table_init_ret && !x2apic_supported()) return; ret = save_ioapic_entries(); @@ -1560,7 +1556,7 @@ void __init enable_IR_x2apic(void) if (x2apic_preenabled && nox2apic) disable_x2apic(); - if (hardware_init_ret) + if (dmar_table_init_ret) ret = -1; else ret = enable_IR(); @@ -2180,8 +2176,8 @@ static int lapic_suspend(void) local_irq_save(flags); disable_local_APIC(); - if (irq_remapping_enabled) - irq_remapping_disable(); + if (intr_remapping_enabled) + disable_intr_remapping(); local_irq_restore(flags); return 0; @@ -2197,7 +2193,7 @@ static void lapic_resume(void) return; local_irq_save(flags); - if (irq_remapping_enabled) { + if (intr_remapping_enabled) { /* * IO-APIC and PIC have their own resume routines. * We just mask them here to make sure the interrupt @@ -2249,8 +2245,8 @@ static void lapic_resume(void) apic_write(APIC_ESR, 0); apic_read(APIC_ESR); - if (irq_remapping_enabled) - irq_remapping_reenable(x2apic_mode); + if (intr_remapping_enabled) + reenable_intr_remapping(x2apic_mode); local_irq_restore(flags); } diff --git a/trunk/arch/x86/kernel/apic/io_apic.c b/trunk/arch/x86/kernel/apic/io_apic.c index ef0648cd7084..e88300d8e80a 100644 --- a/trunk/arch/x86/kernel/apic/io_apic.c +++ b/trunk/arch/x86/kernel/apic/io_apic.c @@ -86,22 +86,6 @@ void __init set_io_apic_ops(const struct io_apic_ops *ops) io_apic_ops = *ops; } -#ifdef CONFIG_IRQ_REMAP -static void irq_remap_modify_chip_defaults(struct irq_chip *chip); -static inline bool irq_remapped(struct irq_cfg *cfg) -{ - return cfg->irq_2_iommu.iommu != NULL; -} -#else -static inline bool irq_remapped(struct irq_cfg *cfg) -{ - return false; -} -static inline void irq_remap_modify_chip_defaults(struct irq_chip *chip) -{ -} -#endif - /* * Is the SiS APIC rmw bug present ? * -1 = don't know, 0 = no, 1 = yes @@ -1377,13 +1361,77 @@ static void ioapic_register_intr(unsigned int irq, struct irq_cfg *cfg, fasteoi ? "fasteoi" : "edge"); } + +static int setup_ir_ioapic_entry(int irq, + struct IR_IO_APIC_route_entry *entry, + unsigned int destination, int vector, + struct io_apic_irq_attr *attr) +{ + int index; + struct irte irte; + int ioapic_id = mpc_ioapic_id(attr->ioapic); + struct intel_iommu *iommu = map_ioapic_to_ir(ioapic_id); + + if (!iommu) { + pr_warn("No mapping iommu for ioapic %d\n", ioapic_id); + return -ENODEV; + } + + index = alloc_irte(iommu, irq, 1); + if (index < 0) { + pr_warn("Failed to allocate IRTE for ioapic %d\n", ioapic_id); + return -ENOMEM; + } + + prepare_irte(&irte, vector, destination); + + /* Set source-id of interrupt request */ + set_ioapic_sid(&irte, ioapic_id); + + modify_irte(irq, &irte); + + apic_printk(APIC_VERBOSE, KERN_DEBUG "IOAPIC[%d]: " + "Set IRTE entry (P:%d FPD:%d Dst_Mode:%d " + "Redir_hint:%d Trig_Mode:%d Dlvry_Mode:%X " + "Avail:%X Vector:%02X Dest:%08X " + "SID:%04X SQ:%X SVT:%X)\n", + attr->ioapic, irte.present, irte.fpd, irte.dst_mode, + irte.redir_hint, irte.trigger_mode, irte.dlvry_mode, + irte.avail, irte.vector, irte.dest_id, + irte.sid, irte.sq, irte.svt); + + memset(entry, 0, sizeof(*entry)); + + entry->index2 = (index >> 15) & 0x1; + entry->zero = 0; + entry->format = 1; + entry->index = (index & 0x7fff); + /* + * IO-APIC RTE will be configured with virtual vector. + * irq handler will do the explicit EOI to the io-apic. + */ + entry->vector = attr->ioapic_pin; + entry->mask = 0; /* enable IRQ */ + entry->trigger = attr->trigger; + entry->polarity = attr->polarity; + + /* Mask level triggered irqs. + * Use IRQ_DELAYED_DISABLE for edge triggered irqs. + */ + if (attr->trigger) + entry->mask = 1; + + return 0; +} + static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry, unsigned int destination, int vector, struct io_apic_irq_attr *attr) { - if (irq_remapping_enabled) - return setup_ioapic_remapped_entry(irq, entry, destination, - vector, attr); + if (intr_remapping_enabled) + return setup_ir_ioapic_entry(irq, + (struct IR_IO_APIC_route_entry *)entry, + destination, vector, attr); memset(entry, 0, sizeof(*entry)); @@ -1540,7 +1588,7 @@ static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx, { struct IO_APIC_route_entry entry; - if (irq_remapping_enabled) + if (intr_remapping_enabled) return; memset(&entry, 0, sizeof(entry)); @@ -1626,7 +1674,7 @@ __apicdebuginit(void) print_IO_APIC(int ioapic_idx) printk(KERN_DEBUG ".... IRQ redirection table:\n"); - if (irq_remapping_enabled) { + if (intr_remapping_enabled) { printk(KERN_DEBUG " NR Indx Fmt Mask Trig IRR" " Pol Stat Indx2 Zero Vect:\n"); } else { @@ -1635,7 +1683,7 @@ __apicdebuginit(void) print_IO_APIC(int ioapic_idx) } for (i = 0; i <= reg_01.bits.entries; i++) { - if (irq_remapping_enabled) { + if (intr_remapping_enabled) { struct IO_APIC_route_entry entry; struct IR_IO_APIC_route_entry *ir_entry; @@ -2002,7 +2050,7 @@ void disable_IO_APIC(void) * IOAPIC RTE as well as interrupt-remapping table entry). * As this gets called during crash dump, keep this simple for now. */ - if (ioapic_i8259.pin != -1 && !irq_remapping_enabled) { + if (ioapic_i8259.pin != -1 && !intr_remapping_enabled) { struct IO_APIC_route_entry entry; memset(&entry, 0, sizeof(entry)); @@ -2026,7 +2074,7 @@ void disable_IO_APIC(void) * Use virtual wire A mode when interrupt remapping is enabled. */ if (cpu_has_apic || apic_from_smp_config()) - disconnect_bsp_APIC(!irq_remapping_enabled && + disconnect_bsp_APIC(!intr_remapping_enabled && ioapic_i8259.pin != -1); } @@ -2342,6 +2390,71 @@ ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, return ret; } +#ifdef CONFIG_IRQ_REMAP + +/* + * Migrate the IO-APIC irq in the presence of intr-remapping. + * + * For both level and edge triggered, irq migration is a simple atomic + * update(of vector and cpu destination) of IRTE and flush the hardware cache. + * + * For level triggered, we eliminate the io-apic RTE modification (with the + * updated vector information), by using a virtual vector (io-apic pin number). + * Real vector that is used for interrupting cpu will be coming from + * the interrupt-remapping table entry. + * + * As the migration is a simple atomic update of IRTE, the same mechanism + * is used to migrate MSI irq's in the presence of interrupt-remapping. + */ +static int +ir_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, + bool force) +{ + struct irq_cfg *cfg = data->chip_data; + unsigned int dest, irq = data->irq; + struct irte irte; + + if (!cpumask_intersects(mask, cpu_online_mask)) + return -EINVAL; + + if (get_irte(irq, &irte)) + return -EBUSY; + + if (assign_irq_vector(irq, cfg, mask)) + return -EBUSY; + + dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask); + + irte.vector = cfg->vector; + irte.dest_id = IRTE_DEST(dest); + + /* + * Atomically updates the IRTE with the new destination, vector + * and flushes the interrupt entry cache. + */ + modify_irte(irq, &irte); + + /* + * After this point, all the interrupts will start arriving + * at the new destination. So, time to cleanup the previous + * vector allocation. + */ + if (cfg->move_in_progress) + send_cleanup_vector(cfg); + + cpumask_copy(data->affinity, mask); + return 0; +} + +#else +static inline int +ir_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, + bool force) +{ + return 0; +} +#endif + asmlinkage void smp_irq_move_cleanup_interrupt(void) { unsigned vector, me; @@ -2586,7 +2699,7 @@ static void irq_remap_modify_chip_defaults(struct irq_chip *chip) chip->irq_eoi = ir_ack_apic_level; #ifdef CONFIG_SMP - chip->irq_set_affinity = set_remapped_irq_affinity; + chip->irq_set_affinity = ir_ioapic_set_affinity; #endif } #endif /* CONFIG_IRQ_REMAP */ @@ -2799,7 +2912,7 @@ static inline void __init check_timer(void) * 8259A. */ if (pin1 == -1) { - if (irq_remapping_enabled) + if (intr_remapping_enabled) panic("BIOS bug: timer not connected to IO-APIC"); pin1 = pin2; apic1 = apic2; @@ -2832,7 +2945,7 @@ static inline void __init check_timer(void) clear_IO_APIC_pin(0, pin1); goto out; } - if (irq_remapping_enabled) + if (intr_remapping_enabled) panic("timer doesn't work through Interrupt-remapped IO-APIC"); local_irq_disable(); clear_IO_APIC_pin(apic1, pin1); @@ -3056,7 +3169,7 @@ void destroy_irq(unsigned int irq) irq_set_status_flags(irq, IRQ_NOREQUEST|IRQ_NOPROBE); if (irq_remapped(cfg)) - free_remapped_irq(irq); + free_irte(irq); raw_spin_lock_irqsave(&vector_lock, flags); __clear_irq_vector(irq, cfg); raw_spin_unlock_irqrestore(&vector_lock, flags); @@ -3085,34 +3198,54 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); if (irq_remapped(cfg)) { - compose_remapped_msi_msg(pdev, irq, dest, msg, hpet_id); - return err; - } + struct irte irte; + int ir_index; + u16 sub_handle; + + ir_index = map_irq_to_irte_handle(irq, &sub_handle); + BUG_ON(ir_index == -1); + + prepare_irte(&irte, cfg->vector, dest); + + /* Set source-id of interrupt request */ + if (pdev) + set_msi_sid(&irte, pdev); + else + set_hpet_sid(&irte, hpet_id); + + modify_irte(irq, &irte); - if (x2apic_enabled()) - msg->address_hi = MSI_ADDR_BASE_HI | - MSI_ADDR_EXT_DEST_ID(dest); - else msg->address_hi = MSI_ADDR_BASE_HI; + msg->data = sub_handle; + msg->address_lo = MSI_ADDR_BASE_LO | MSI_ADDR_IR_EXT_INT | + MSI_ADDR_IR_SHV | + MSI_ADDR_IR_INDEX1(ir_index) | + MSI_ADDR_IR_INDEX2(ir_index); + } else { + if (x2apic_enabled()) + msg->address_hi = MSI_ADDR_BASE_HI | + MSI_ADDR_EXT_DEST_ID(dest); + else + msg->address_hi = MSI_ADDR_BASE_HI; - msg->address_lo = - MSI_ADDR_BASE_LO | - ((apic->irq_dest_mode == 0) ? - MSI_ADDR_DEST_MODE_PHYSICAL: - MSI_ADDR_DEST_MODE_LOGICAL) | - ((apic->irq_delivery_mode != dest_LowestPrio) ? - MSI_ADDR_REDIRECTION_CPU: - MSI_ADDR_REDIRECTION_LOWPRI) | - MSI_ADDR_DEST_ID(dest); - - msg->data = - MSI_DATA_TRIGGER_EDGE | - MSI_DATA_LEVEL_ASSERT | - ((apic->irq_delivery_mode != dest_LowestPrio) ? - MSI_DATA_DELIVERY_FIXED: - MSI_DATA_DELIVERY_LOWPRI) | - MSI_DATA_VECTOR(cfg->vector); + msg->address_lo = + MSI_ADDR_BASE_LO | + ((apic->irq_dest_mode == 0) ? + MSI_ADDR_DEST_MODE_PHYSICAL: + MSI_ADDR_DEST_MODE_LOGICAL) | + ((apic->irq_delivery_mode != dest_LowestPrio) ? + MSI_ADDR_REDIRECTION_CPU: + MSI_ADDR_REDIRECTION_LOWPRI) | + MSI_ADDR_DEST_ID(dest); + msg->data = + MSI_DATA_TRIGGER_EDGE | + MSI_DATA_LEVEL_ASSERT | + ((apic->irq_delivery_mode != dest_LowestPrio) ? + MSI_DATA_DELIVERY_FIXED: + MSI_DATA_DELIVERY_LOWPRI) | + MSI_DATA_VECTOR(cfg->vector); + } return err; } @@ -3155,6 +3288,33 @@ static struct irq_chip msi_chip = { .irq_retrigger = ioapic_retrigger_irq, }; +/* + * Map the PCI dev to the corresponding remapping hardware unit + * and allocate 'nvec' consecutive interrupt-remapping table entries + * in it. + */ +static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec) +{ + struct intel_iommu *iommu; + int index; + + iommu = map_dev_to_ir(dev); + if (!iommu) { + printk(KERN_ERR + "Unable to map PCI %s to iommu\n", pci_name(dev)); + return -ENOENT; + } + + index = alloc_irte(iommu, irq, nvec); + if (index < 0) { + printk(KERN_ERR + "Unable to allocate %d IRTE for PCI %s\n", nvec, + pci_name(dev)); + return -ENOSPC; + } + return index; +} + static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) { struct irq_chip *chip = &msi_chip; @@ -3185,6 +3345,7 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) int node, ret, sub_handle, index = 0; unsigned int irq, irq_want; struct msi_desc *msidesc; + struct intel_iommu *iommu = NULL; /* x86 doesn't support multiple MSI yet */ if (type == PCI_CAP_ID_MSI && nvec > 1) @@ -3198,7 +3359,7 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) if (irq == 0) return -1; irq_want = irq + 1; - if (!irq_remapping_enabled) + if (!intr_remapping_enabled) goto no_ir; if (!sub_handle) { @@ -3206,16 +3367,23 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) * allocate the consecutive block of IRTE's * for 'nvec' */ - index = msi_alloc_remapped_irq(dev, irq, nvec); + index = msi_alloc_irte(dev, irq, nvec); if (index < 0) { ret = index; goto error; } } else { - ret = msi_setup_remapped_irq(dev, irq, index, - sub_handle); - if (ret < 0) + iommu = map_dev_to_ir(dev); + if (!iommu) { + ret = -ENOENT; goto error; + } + /* + * setup the mapping between the irq and the IRTE + * base index, the sub_handle pointing to the + * appropriate interrupt remap table entry. + */ + set_irte_irq(irq, iommu, index, sub_handle); } no_ir: ret = setup_msi_irq(dev, msidesc, irq); @@ -3333,8 +3501,15 @@ int arch_setup_hpet_msi(unsigned int irq, unsigned int id) struct msi_msg msg; int ret; - if (irq_remapping_enabled) { - if (!setup_hpet_msi_remapped(irq, id)) + if (intr_remapping_enabled) { + struct intel_iommu *iommu = map_hpet_to_ir(id); + int index; + + if (!iommu) + return -1; + + index = alloc_irte(iommu, irq, 1); + if (index < 0) return -1; } @@ -3713,8 +3888,8 @@ void __init setup_ioapic_dest(void) else mask = apic->target_cpus(); - if (irq_remapping_enabled) - set_remapped_irq_affinity(idata, mask, false); + if (intr_remapping_enabled) + ir_ioapic_set_affinity(idata, mask, false); else ioapic_set_affinity(idata, mask, false); } diff --git a/trunk/arch/x86/kernel/apm_32.c b/trunk/arch/x86/kernel/apm_32.c index 07b0c0db466c..459e78cbf61e 100644 --- a/trunk/arch/x86/kernel/apm_32.c +++ b/trunk/arch/x86/kernel/apm_32.c @@ -2401,7 +2401,7 @@ static void __exit apm_exit(void) * (pm_idle), Wait for all processors to update cached/local * copies of pm_idle before proceeding. */ - kick_all_cpus_sync(); + cpu_idle_wait(); } if (((apm_info.bios.flags & APM_BIOS_DISENGAGED) == 0) && (apm_info.connection_version > 0x0100)) { diff --git a/trunk/arch/x86/kernel/cpu/amd.c b/trunk/arch/x86/kernel/cpu/amd.c index 146bb6218eec..1c67ca100e4c 100644 --- a/trunk/arch/x86/kernel/cpu/amd.c +++ b/trunk/arch/x86/kernel/cpu/amd.c @@ -580,24 +580,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) } } - /* re-enable TopologyExtensions if switched off by BIOS */ - if ((c->x86 == 0x15) && - (c->x86_model >= 0x10) && (c->x86_model <= 0x1f) && - !cpu_has(c, X86_FEATURE_TOPOEXT)) { - u64 val; - - if (!rdmsrl_amd_safe(0xc0011005, &val)) { - val |= 1ULL << 54; - wrmsrl_amd_safe(0xc0011005, val); - rdmsrl(0xc0011005, val); - if (val & (1ULL << 54)) { - set_cpu_cap(c, X86_FEATURE_TOPOEXT); - printk(KERN_INFO FW_INFO "CPU: Re-enabling " - "disabled Topology Extensions Support\n"); - } - } - } - cpu_detect_cache_sizes(c); /* Multi core CPU? */ diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce.c b/trunk/arch/x86/kernel/cpu/mcheck/mce.c index 11c9166c3337..d086a09c087d 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/mce.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/mce.c @@ -945,10 +945,9 @@ struct mce_info { atomic_t inuse; struct task_struct *t; __u64 paddr; - int restartable; } mce_info[MCE_INFO_MAX]; -static void mce_save_info(__u64 addr, int c) +static void mce_save_info(__u64 addr) { struct mce_info *mi; @@ -956,7 +955,6 @@ static void mce_save_info(__u64 addr, int c) if (atomic_cmpxchg(&mi->inuse, 0, 1) == 0) { mi->t = current; mi->paddr = addr; - mi->restartable = c; return; } } @@ -1132,7 +1130,7 @@ void do_machine_check(struct pt_regs *regs, long error_code) mce_panic("Fatal machine check on current CPU", &m, msg); if (worst == MCE_AR_SEVERITY) { /* schedule action before return to userland */ - mce_save_info(m.addr, m.mcgstatus & MCG_STATUS_RIPV); + mce_save_info(m.addr); set_thread_flag(TIF_MCE_NOTIFY); } else if (kill_it) { force_sig(SIGBUS, current); @@ -1181,13 +1179,7 @@ void mce_notify_process(void) pr_err("Uncorrected hardware memory error in user-access at %llx", mi->paddr); - /* - * We must call memory_failure() here even if the current process is - * doomed. We still need to mark the page as poisoned and alert any - * other users of the page. - */ - if (memory_failure(pfn, MCE_VECTOR, MF_ACTION_REQUIRED) < 0 || - mi->restartable == 0) { + if (memory_failure(pfn, MCE_VECTOR, MF_ACTION_REQUIRED) < 0) { pr_err("Memory error not recovered"); force_sig(SIGBUS, current); } diff --git a/trunk/arch/x86/kernel/init_task.c b/trunk/arch/x86/kernel/init_task.c new file mode 100644 index 000000000000..43e9ccf44947 --- /dev/null +++ b/trunk/arch/x86/kernel/init_task.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); + +/* + * Initial thread structure. + * + * We need to make sure that this is THREAD_SIZE aligned due to the + * way process stacks are handled. This is done by having a special + * "init_task" linker map entry.. + */ +union thread_union init_thread_union __init_task_data = + { INIT_THREAD_INFO(init_task) }; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); +EXPORT_SYMBOL(init_task); + +/* + * per-CPU TSS segments. Threads are completely 'soft' on Linux, + * no more per-task TSS's. The TSS size is kept cacheline-aligned + * so they are allowed to end up in the .data..cacheline_aligned + * section. Since TSS's are completely CPU-local, we want them + * on exact cacheline boundaries, to eliminate cacheline ping-pong. + */ +DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS; + diff --git a/trunk/arch/x86/kernel/irq_32.c b/trunk/arch/x86/kernel/irq_32.c index 344faf8d0d62..58b7f27cb3e9 100644 --- a/trunk/arch/x86/kernel/irq_32.c +++ b/trunk/arch/x86/kernel/irq_32.c @@ -127,8 +127,8 @@ void __cpuinit irq_ctx_init(int cpu) return; irqctx = page_address(alloc_pages_node(cpu_to_node(cpu), - THREADINFO_GFP, - THREAD_SIZE_ORDER)); + THREAD_FLAGS, + THREAD_ORDER)); memset(&irqctx->tinfo, 0, sizeof(struct thread_info)); irqctx->tinfo.cpu = cpu; irqctx->tinfo.preempt_count = HARDIRQ_OFFSET; @@ -137,8 +137,8 @@ void __cpuinit irq_ctx_init(int cpu) per_cpu(hardirq_ctx, cpu) = irqctx; irqctx = page_address(alloc_pages_node(cpu_to_node(cpu), - THREADINFO_GFP, - THREAD_SIZE_ORDER)); + THREAD_FLAGS, + THREAD_ORDER)); memset(&irqctx->tinfo, 0, sizeof(struct thread_info)); irqctx->tinfo.cpu = cpu; irqctx->tinfo.addr_limit = MAKE_MM_SEG(0); diff --git a/trunk/arch/x86/kernel/kvm.c b/trunk/arch/x86/kernel/kvm.c index e554e5ad2fe8..b8ba6e4a27e4 100644 --- a/trunk/arch/x86/kernel/kvm.c +++ b/trunk/arch/x86/kernel/kvm.c @@ -79,6 +79,7 @@ struct kvm_task_sleep_node { u32 token; int cpu; bool halted; + struct mm_struct *mm; }; static struct kvm_task_sleep_head { @@ -125,7 +126,9 @@ void kvm_async_pf_task_wait(u32 token) n.token = token; n.cpu = smp_processor_id(); + n.mm = current->active_mm; n.halted = idle || preempt_count() > 1; + atomic_inc(&n.mm->mm_count); init_waitqueue_head(&n.wq); hlist_add_head(&n.link, &b->list); spin_unlock(&b->lock); @@ -158,6 +161,9 @@ EXPORT_SYMBOL_GPL(kvm_async_pf_task_wait); static void apf_task_wake_one(struct kvm_task_sleep_node *n) { hlist_del_init(&n->link); + if (!n->mm) + return; + mmdrop(n->mm); if (n->halted) smp_send_reschedule(n->cpu); else if (waitqueue_active(&n->wq)) @@ -201,7 +207,7 @@ void kvm_async_pf_task_wake(u32 token) * async PF was not yet handled. * Add dummy entry for the token. */ - n = kzalloc(sizeof(*n), GFP_ATOMIC); + n = kmalloc(sizeof(*n), GFP_ATOMIC); if (!n) { /* * Allocation failed! Busy wait while other cpu @@ -213,6 +219,7 @@ void kvm_async_pf_task_wake(u32 token) } n->token = token; n->cpu = smp_processor_id(); + n->mm = NULL; init_waitqueue_head(&n->wq); hlist_add_head(&n->link, &b->list); } else diff --git a/trunk/arch/x86/kernel/microcode_intel.c b/trunk/arch/x86/kernel/microcode_intel.c index 0327e2b3c408..3ca42d0e43a2 100644 --- a/trunk/arch/x86/kernel/microcode_intel.c +++ b/trunk/arch/x86/kernel/microcode_intel.c @@ -147,6 +147,12 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig) memset(csig, 0, sizeof(*csig)); + if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || + cpu_has(c, X86_FEATURE_IA64)) { + pr_err("CPU%d not a capable Intel processor\n", cpu_num); + return -1; + } + csig->sig = cpuid_eax(0x00000001); if ((c->x86_model >= 5) || (c->x86 > 6)) { @@ -457,14 +463,6 @@ static struct microcode_ops microcode_intel_ops = { struct microcode_ops * __init init_intel_microcode(void) { - struct cpuinfo_x86 *c = &cpu_data(0); - - if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || - cpu_has(c, X86_FEATURE_IA64)) { - pr_err("Intel CPU family 0x%x not supported\n", c->x86); - return NULL; - } - return µcode_intel_ops; } diff --git a/trunk/arch/x86/kernel/nmi.c b/trunk/arch/x86/kernel/nmi.c index 585be4bd71a5..47acaf319165 100644 --- a/trunk/arch/x86/kernel/nmi.c +++ b/trunk/arch/x86/kernel/nmi.c @@ -31,6 +31,14 @@ #include #include +#define NMI_MAX_NAMELEN 16 +struct nmiaction { + struct list_head list; + nmi_handler_t handler; + unsigned int flags; + char *name; +}; + struct nmi_desc { spinlock_t lock; struct list_head head; @@ -46,14 +54,6 @@ static struct nmi_desc nmi_desc[NMI_MAX] = .lock = __SPIN_LOCK_UNLOCKED(&nmi_desc[1].lock), .head = LIST_HEAD_INIT(nmi_desc[1].head), }, - { - .lock = __SPIN_LOCK_UNLOCKED(&nmi_desc[2].lock), - .head = LIST_HEAD_INIT(nmi_desc[2].head), - }, - { - .lock = __SPIN_LOCK_UNLOCKED(&nmi_desc[3].lock), - .head = LIST_HEAD_INIT(nmi_desc[3].head), - }, }; @@ -107,14 +107,11 @@ static int notrace __kprobes nmi_handle(unsigned int type, struct pt_regs *regs, return handled; } -int __register_nmi_handler(unsigned int type, struct nmiaction *action) +static int __setup_nmi(unsigned int type, struct nmiaction *action) { struct nmi_desc *desc = nmi_to_desc(type); unsigned long flags; - if (!action->handler) - return -EINVAL; - spin_lock_irqsave(&desc->lock, flags); /* @@ -123,8 +120,6 @@ int __register_nmi_handler(unsigned int type, struct nmiaction *action) * to manage expectations */ WARN_ON_ONCE(type == NMI_UNKNOWN && !list_empty(&desc->head)); - WARN_ON_ONCE(type == NMI_SERR && !list_empty(&desc->head)); - WARN_ON_ONCE(type == NMI_IO_CHECK && !list_empty(&desc->head)); /* * some handlers need to be executed first otherwise a fake @@ -138,9 +133,8 @@ int __register_nmi_handler(unsigned int type, struct nmiaction *action) spin_unlock_irqrestore(&desc->lock, flags); return 0; } -EXPORT_SYMBOL(__register_nmi_handler); -void unregister_nmi_handler(unsigned int type, const char *name) +static struct nmiaction *__free_nmi(unsigned int type, const char *name) { struct nmi_desc *desc = nmi_to_desc(type); struct nmiaction *n; @@ -163,16 +157,61 @@ void unregister_nmi_handler(unsigned int type, const char *name) spin_unlock_irqrestore(&desc->lock, flags); synchronize_rcu(); + return (n); } + +int register_nmi_handler(unsigned int type, nmi_handler_t handler, + unsigned long nmiflags, const char *devname) +{ + struct nmiaction *action; + int retval = -ENOMEM; + + if (!handler) + return -EINVAL; + + action = kzalloc(sizeof(struct nmiaction), GFP_KERNEL); + if (!action) + goto fail_action; + + action->handler = handler; + action->flags = nmiflags; + action->name = kstrndup(devname, NMI_MAX_NAMELEN, GFP_KERNEL); + if (!action->name) + goto fail_action_name; + + retval = __setup_nmi(type, action); + + if (retval) + goto fail_setup_nmi; + + return retval; + +fail_setup_nmi: + kfree(action->name); +fail_action_name: + kfree(action); +fail_action: + + return retval; +} +EXPORT_SYMBOL_GPL(register_nmi_handler); + +void unregister_nmi_handler(unsigned int type, const char *name) +{ + struct nmiaction *a; + + a = __free_nmi(type, name); + if (a) { + kfree(a->name); + kfree(a); + } +} + EXPORT_SYMBOL_GPL(unregister_nmi_handler); static notrace __kprobes void pci_serr_error(unsigned char reason, struct pt_regs *regs) { - /* check to see if anyone registered against these types of errors */ - if (nmi_handle(NMI_SERR, regs, false)) - return; - pr_emerg("NMI: PCI system error (SERR) for reason %02x on CPU %d.\n", reason, smp_processor_id()); @@ -202,10 +241,6 @@ io_check_error(unsigned char reason, struct pt_regs *regs) { unsigned long i; - /* check to see if anyone registered against these types of errors */ - if (nmi_handle(NMI_IO_CHECK, regs, false)) - return; - pr_emerg( "NMI: IOCK error (debug interrupt?) for reason %02x on CPU %d.\n", reason, smp_processor_id()); diff --git a/trunk/arch/x86/kernel/process.c b/trunk/arch/x86/kernel/process.c index e8173154800d..1d92a5ab6e8b 100644 --- a/trunk/arch/x86/kernel/process.c +++ b/trunk/arch/x86/kernel/process.c @@ -27,15 +27,6 @@ #include #include -/* - * per-CPU TSS segments. Threads are completely 'soft' on Linux, - * no more per-task TSS's. The TSS size is kept cacheline-aligned - * so they are allowed to end up in the .data..cacheline_aligned - * section. Since TSS's are completely CPU-local, we want them - * on exact cacheline boundaries, to eliminate cacheline ping-pong. - */ -DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS; - #ifdef CONFIG_X86_64 static DEFINE_PER_CPU(unsigned char, is_idle); static ATOMIC_NOTIFIER_HEAD(idle_notifier); @@ -76,9 +67,10 @@ void free_thread_xstate(struct task_struct *tsk) fpu_free(&tsk->thread.fpu); } -void arch_release_task_struct(struct task_struct *tsk) +void free_thread_info(struct thread_info *ti) { - free_thread_xstate(tsk); + free_thread_xstate(ti->task); + free_pages((unsigned long)ti, THREAD_ORDER); } void arch_task_cache_init(void) @@ -524,6 +516,26 @@ void stop_this_cpu(void *dummy) } } +static void do_nothing(void *unused) +{ +} + +/* + * cpu_idle_wait - Used to ensure that all the CPUs discard old value of + * pm_idle and update to new pm_idle value. Required while changing pm_idle + * handler on SMP systems. + * + * Caller must have changed pm_idle to the new value before the call. Old + * pm_idle value will not be used by any CPU after the return of this function. + */ +void cpu_idle_wait(void) +{ + smp_mb(); + /* kick all the CPUs so that they exit out of pm_idle */ + smp_call_function(do_nothing, NULL, 1); +} +EXPORT_SYMBOL_GPL(cpu_idle_wait); + /* Default MONITOR/MWAIT with no hints, used for default C1 state */ static void mwait_idle(void) { diff --git a/trunk/arch/x86/kernel/process_64.c b/trunk/arch/x86/kernel/process_64.c index 43d8b48b23e6..733ca39f367e 100644 --- a/trunk/arch/x86/kernel/process_64.c +++ b/trunk/arch/x86/kernel/process_64.c @@ -423,7 +423,6 @@ void set_personality_ia32(bool x32) current_thread_info()->status |= TS_COMPAT; } } -EXPORT_SYMBOL_GPL(set_personality_ia32); unsigned long get_wchan(struct task_struct *p) { diff --git a/trunk/arch/x86/kernel/ptrace.c b/trunk/arch/x86/kernel/ptrace.c index 13b1990c7c58..685845cf16e0 100644 --- a/trunk/arch/x86/kernel/ptrace.c +++ b/trunk/arch/x86/kernel/ptrace.c @@ -1480,11 +1480,7 @@ long syscall_trace_enter(struct pt_regs *regs) regs->flags |= X86_EFLAGS_TF; /* do the secure computing check first */ - if (secure_computing(regs->orig_ax)) { - /* seccomp failures shouldn't expose any additional code. */ - ret = -1L; - goto out; - } + secure_computing(regs->orig_ax); if (unlikely(test_thread_flag(TIF_SYSCALL_EMU))) ret = -1L; @@ -1509,7 +1505,6 @@ long syscall_trace_enter(struct pt_regs *regs) regs->dx, regs->r10); #endif -out: return ret ?: regs->orig_ax; } diff --git a/trunk/arch/x86/kernel/setup_percpu.c b/trunk/arch/x86/kernel/setup_percpu.c index 5a98aa272184..71f4727da373 100644 --- a/trunk/arch/x86/kernel/setup_percpu.c +++ b/trunk/arch/x86/kernel/setup_percpu.c @@ -185,22 +185,10 @@ void __init setup_per_cpu_areas(void) #endif rc = -EINVAL; if (pcpu_chosen_fc != PCPU_FC_PAGE) { + const size_t atom_size = cpu_has_pse ? PMD_SIZE : PAGE_SIZE; const size_t dyn_size = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE - PERCPU_FIRST_CHUNK_RESERVE; - size_t atom_size; - /* - * On 64bit, use PMD_SIZE for atom_size so that embedded - * percpu areas are aligned to PMD. This, in the future, - * can also allow using PMD mappings in vmalloc area. Use - * PAGE_SIZE on 32bit as vmalloc space is highly contended - * and large vmalloc area allocs can easily fail. - */ -#ifdef CONFIG_X86_64 - atom_size = PMD_SIZE; -#else - atom_size = PAGE_SIZE; -#endif rc = pcpu_embed_first_chunk(PERCPU_FIRST_CHUNK_RESERVE, dyn_size, atom_size, pcpu_cpu_distance, diff --git a/trunk/arch/x86/kernel/smpboot.c b/trunk/arch/x86/kernel/smpboot.c index 3acaf51dfddb..6e1e406038c2 100644 --- a/trunk/arch/x86/kernel/smpboot.c +++ b/trunk/arch/x86/kernel/smpboot.c @@ -76,7 +76,19 @@ /* State of each CPU */ DEFINE_PER_CPU(int, cpu_state) = { 0 }; +/* Store all idle threads, this can be reused instead of creating +* a new thread. Also avoids complicated thread destroy functionality +* for idle threads. +*/ #ifdef CONFIG_HOTPLUG_CPU +/* + * Needed only for CONFIG_HOTPLUG_CPU because __cpuinitdata is + * removed after init for !CONFIG_HOTPLUG_CPU. + */ +static DEFINE_PER_CPU(struct task_struct *, idle_thread_array); +#define get_idle_for_cpu(x) (per_cpu(idle_thread_array, x)) +#define set_idle_for_cpu(x, p) (per_cpu(idle_thread_array, x) = (p)) + /* * We need this for trampoline_base protection from concurrent accesses when * off- and onlining cores wildly. @@ -85,16 +97,20 @@ static DEFINE_MUTEX(x86_cpu_hotplug_driver_mutex); void cpu_hotplug_driver_lock(void) { - mutex_lock(&x86_cpu_hotplug_driver_mutex); + mutex_lock(&x86_cpu_hotplug_driver_mutex); } void cpu_hotplug_driver_unlock(void) { - mutex_unlock(&x86_cpu_hotplug_driver_mutex); + mutex_unlock(&x86_cpu_hotplug_driver_mutex); } ssize_t arch_cpu_probe(const char *buf, size_t count) { return -1; } ssize_t arch_cpu_release(const char *buf, size_t count) { return -1; } +#else +static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ; +#define get_idle_for_cpu(x) (idle_thread_array[(x)]) +#define set_idle_for_cpu(x, p) (idle_thread_array[(x)] = (p)) #endif /* Number of siblings per CPU package */ @@ -602,6 +618,22 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) return (send_status | accept_status); } +struct create_idle { + struct work_struct work; + struct task_struct *idle; + struct completion done; + int cpu; +}; + +static void __cpuinit do_fork_idle(struct work_struct *work) +{ + struct create_idle *c_idle = + container_of(work, struct create_idle, work); + + c_idle->idle = fork_idle(c_idle->cpu); + complete(&c_idle->done); +} + /* reduce the number of lines printed when booting a large cpu count system */ static void __cpuinit announce_cpu(int cpu, int apicid) { @@ -628,31 +660,58 @@ static void __cpuinit announce_cpu(int cpu, int apicid) * Returns zero if CPU booted OK, else error code from * ->wakeup_secondary_cpu. */ -static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle) +static int __cpuinit do_boot_cpu(int apicid, int cpu) { unsigned long boot_error = 0; unsigned long start_ip; int timeout; + struct create_idle c_idle = { + .cpu = cpu, + .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done), + }; + + INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle); alternatives_smp_switch(1); - idle->thread.sp = (unsigned long) (((struct pt_regs *) - (THREAD_SIZE + task_stack_page(idle))) - 1); - per_cpu(current_task, cpu) = idle; + c_idle.idle = get_idle_for_cpu(cpu); + + /* + * We can't use kernel_thread since we must avoid to + * reschedule the child. + */ + if (c_idle.idle) { + c_idle.idle->thread.sp = (unsigned long) (((struct pt_regs *) + (THREAD_SIZE + task_stack_page(c_idle.idle))) - 1); + init_idle(c_idle.idle, cpu); + goto do_rest; + } + schedule_work(&c_idle.work); + wait_for_completion(&c_idle.done); + + if (IS_ERR(c_idle.idle)) { + printk("failed fork for CPU %d\n", cpu); + destroy_work_on_stack(&c_idle.work); + return PTR_ERR(c_idle.idle); + } + + set_idle_for_cpu(cpu, c_idle.idle); +do_rest: + per_cpu(current_task, cpu) = c_idle.idle; #ifdef CONFIG_X86_32 /* Stack for startup_32 can be just as for start_secondary onwards */ irq_ctx_init(cpu); #else - clear_tsk_thread_flag(idle, TIF_FORK); + clear_tsk_thread_flag(c_idle.idle, TIF_FORK); initial_gs = per_cpu_offset(cpu); per_cpu(kernel_stack, cpu) = - (unsigned long)task_stack_page(idle) - + (unsigned long)task_stack_page(c_idle.idle) - KERNEL_STACK_OFFSET + THREAD_SIZE; #endif early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); initial_code = (unsigned long)start_secondary; - stack_start = idle->thread.sp; + stack_start = c_idle.idle->thread.sp; /* start_ip had better be page-aligned! */ start_ip = trampoline_address(); @@ -754,10 +813,12 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle) */ smpboot_restore_warm_reset_vector(); } + + destroy_work_on_stack(&c_idle.work); return boot_error; } -int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle) +int __cpuinit native_cpu_up(unsigned int cpu) { int apicid = apic->cpu_present_to_apicid(cpu); unsigned long flags; @@ -790,7 +851,7 @@ int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle) per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; - err = do_boot_cpu(apicid, cpu, tidle); + err = do_boot_cpu(apicid, cpu); if (err) { pr_debug("do_boot_cpu failed %d\n", err); return -EIO; diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index 185a2b823a2d..91a5e989abcf 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -6581,7 +6581,6 @@ void kvm_arch_async_page_present(struct kvm_vcpu *vcpu, kvm_inject_page_fault(vcpu, &fault); } vcpu->arch.apf.halted = false; - vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; } bool kvm_arch_can_inject_async_page_present(struct kvm_vcpu *vcpu) diff --git a/trunk/arch/x86/lib/usercopy.c b/trunk/arch/x86/lib/usercopy.c index 2e4e4b02c37a..d6ae30bbd7bb 100644 --- a/trunk/arch/x86/lib/usercopy.c +++ b/trunk/arch/x86/lib/usercopy.c @@ -44,6 +44,13 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n) } EXPORT_SYMBOL_GPL(copy_from_user_nmi); +static inline unsigned long count_bytes(unsigned long mask) +{ + mask = (mask - 1) & ~mask; + mask >>= 7; + return count_masked_bytes(mask); +} + /* * Do a strncpy, return length of string without final '\0'. * 'count' is the user-supplied count (return 'count' if we @@ -62,19 +69,16 @@ static inline long do_strncpy_from_user(char *dst, const char __user *src, long max = count; while (max >= sizeof(unsigned long)) { - unsigned long c, mask; + unsigned long c; /* Fall back to byte-at-a-time if we get a page fault */ if (unlikely(__get_user(c,(unsigned long __user *)(src+res)))) break; - mask = has_zero(c); - if (mask) { - mask = (mask - 1) & ~mask; - mask >>= 7; - *(unsigned long *)(dst+res) = c & mask; - return res + count_masked_bytes(mask); - } + /* This can write a few bytes past the NUL character, but that's ok */ *(unsigned long *)(dst+res) = c; + c = has_zero(c); + if (c) + return res + count_bytes(c); res += sizeof(unsigned long); max -= sizeof(unsigned long); } diff --git a/trunk/arch/x86/pci/acpi.c b/trunk/arch/x86/pci/acpi.c index fc09c2754e08..ed2835e148b5 100644 --- a/trunk/arch/x86/pci/acpi.c +++ b/trunk/arch/x86/pci/acpi.c @@ -9,11 +9,11 @@ struct pci_root_info { struct acpi_device *bridge; - char name[16]; + char *name; unsigned int res_num; struct resource *res; + struct list_head *resources; int busnum; - struct pci_sysdata sd; }; static bool pci_use_crs = true; @@ -245,6 +245,13 @@ setup_resource(struct acpi_resource *acpi_res, void *data) return AE_OK; } +static bool resource_contains(struct resource *res, resource_size_t point) +{ + if (res->start <= point && point <= res->end) + return true; + return false; +} + static void coalesce_windows(struct pci_root_info *info, unsigned long type) { int i, j; @@ -265,7 +272,10 @@ static void coalesce_windows(struct pci_root_info *info, unsigned long type) * our resources no longer match the ACPI _CRS, but * the kernel resource tree doesn't allow overlaps. */ - if (resource_overlaps(res1, res2)) { + if (resource_contains(res1, res2->start) || + resource_contains(res1, res2->end) || + resource_contains(res2, res1->start) || + resource_contains(res2, res1->end)) { res1->start = min(res1->start, res2->start); res1->end = max(res1->end, res2->end); dev_info(&info->bridge->dev, @@ -277,8 +287,7 @@ static void coalesce_windows(struct pci_root_info *info, unsigned long type) } } -static void add_resources(struct pci_root_info *info, - struct list_head *resources) +static void add_resources(struct pci_root_info *info) { int i; struct resource *res, *root, *conflict; @@ -302,74 +311,53 @@ static void add_resources(struct pci_root_info *info, "ignoring host bridge window %pR (conflicts with %s %pR)\n", res, conflict->name, conflict); else - pci_add_resource(resources, res); + pci_add_resource(info->resources, res); } } -static void free_pci_root_info_res(struct pci_root_info *info) -{ - kfree(info->res); - info->res = NULL; - info->res_num = 0; -} - -static void __release_pci_root_info(struct pci_root_info *info) -{ - int i; - struct resource *res; - - for (i = 0; i < info->res_num; i++) { - res = &info->res[i]; - - if (!res->parent) - continue; - - if (!(res->flags & (IORESOURCE_MEM | IORESOURCE_IO))) - continue; - - release_resource(res); - } - - free_pci_root_info_res(info); - - kfree(info); -} -static void release_pci_root_info(struct pci_host_bridge *bridge) -{ - struct pci_root_info *info = bridge->release_data; - - __release_pci_root_info(info); -} - static void -probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device, - int busnum, int domain) +get_current_resources(struct acpi_device *device, int busnum, + int domain, struct list_head *resources) { + struct pci_root_info info; size_t size; - info->bridge = device; - info->res_num = 0; + info.bridge = device; + info.res_num = 0; + info.resources = resources; acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource, - info); - if (!info->res_num) + &info); + if (!info.res_num) return; - size = sizeof(*info->res) * info->res_num; - info->res_num = 0; - info->res = kmalloc(size, GFP_KERNEL); - if (!info->res) + size = sizeof(*info.res) * info.res_num; + info.res = kmalloc(size, GFP_KERNEL); + if (!info.res) return; - sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum); + info.name = kasprintf(GFP_KERNEL, "PCI Bus %04x:%02x", domain, busnum); + if (!info.name) + goto name_alloc_fail; + info.res_num = 0; acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, - info); + &info); + + if (pci_use_crs) { + add_resources(&info); + + return; + } + + kfree(info.name); + +name_alloc_fail: + kfree(info.res); } struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) { struct acpi_device *device = root->device; - struct pci_root_info *info = NULL; int domain = root->segment; int busnum = root->secondary.start; LIST_HEAD(resources); @@ -401,14 +389,17 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) if (node != -1 && !node_online(node)) node = -1; - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) { + /* Allocate per-root-bus (not per bus) arch-specific data. + * TODO: leak; this memory is never freed. + * It's arguable whether it's worth the trouble to care. + */ + sd = kzalloc(sizeof(*sd), GFP_KERNEL); + if (!sd) { printk(KERN_WARNING "pci_bus %04x:%02x: " "ignored (out of memory)\n", domain, busnum); return NULL; } - sd = &info->sd; sd->domain = domain; sd->node = node; /* @@ -422,32 +413,22 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) * be replaced by sd. */ memcpy(bus->sysdata, sd, sizeof(*sd)); - kfree(info); + kfree(sd); } else { - probe_pci_root_info(info, device, busnum, domain); + get_current_resources(device, busnum, domain, &resources); /* * _CRS with no apertures is normal, so only fall back to * defaults or native bridge info if we're ignoring _CRS. */ - if (pci_use_crs) - add_resources(info, &resources); - else { - free_pci_root_info_res(info); + if (!pci_use_crs) x86_pci_root_bus_resources(busnum, &resources); - } - bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd, &resources); - if (bus) { + if (bus) bus->subordinate = pci_scan_child_bus(bus); - pci_set_host_bridge_release( - to_pci_host_bridge(bus->bridge), - release_pci_root_info, info); - } else { + else pci_free_resource_list(&resources); - __release_pci_root_info(info); - } } /* After the PCI-E bus has been walked and all devices discovered, @@ -464,6 +445,9 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) } } + if (!bus) + kfree(sd); + if (bus && node != -1) { #ifdef CONFIG_ACPI_NUMA if (pxm >= 0) diff --git a/trunk/arch/x86/pci/amd_bus.c b/trunk/arch/x86/pci/amd_bus.c index 5aed49bff058..0567df3890e1 100644 --- a/trunk/arch/x86/pci/amd_bus.c +++ b/trunk/arch/x86/pci/amd_bus.c @@ -32,27 +32,6 @@ static struct pci_hostbridge_probe pci_probes[] __initdata = { #define RANGE_NUM 16 -static struct pci_root_info __init *find_pci_root_info(int node, int link) -{ - struct pci_root_info *info; - - /* find the position */ - list_for_each_entry(info, &pci_root_infos, list) - if (info->node == node && info->link == link) - return info; - - return NULL; -} - -static void __init set_mp_bus_range_to_node(int min_bus, int max_bus, int node) -{ -#ifdef CONFIG_NUMA - int j; - - for (j = min_bus; j <= max_bus; j++) - set_mp_bus_to_node(j, node); -#endif -} /** * early_fill_mp_bus_to_node() * called before pcibios_scan_root and pci_scan_bus @@ -62,6 +41,7 @@ static void __init set_mp_bus_range_to_node(int min_bus, int max_bus, int node) static int __init early_fill_mp_bus_info(void) { int i; + int j; unsigned bus; unsigned slot; int node; @@ -70,6 +50,7 @@ static int __init early_fill_mp_bus_info(void) int def_link; struct pci_root_info *info; u32 reg; + struct resource *res; u64 start; u64 end; struct range range[RANGE_NUM]; @@ -105,6 +86,7 @@ static int __init early_fill_mp_bus_info(void) if (!found) return 0; + pci_root_num = 0; for (i = 0; i < 4; i++) { int min_bus; int max_bus; @@ -117,11 +99,19 @@ static int __init early_fill_mp_bus_info(void) min_bus = (reg >> 16) & 0xff; max_bus = (reg >> 24) & 0xff; node = (reg >> 4) & 0x07; - set_mp_bus_range_to_node(min_bus, max_bus, node); +#ifdef CONFIG_NUMA + for (j = min_bus; j <= max_bus; j++) + set_mp_bus_to_node(j, node); +#endif link = (reg >> 8) & 0x03; - info = alloc_pci_root_info(min_bus, max_bus, node, link); + info = &pci_root_info[pci_root_num]; + info->bus_min = min_bus; + info->bus_max = max_bus; + info->node = node; + info->link = link; sprintf(info->name, "PCI Bus #%02x", min_bus); + pci_root_num++; } /* get the default node and link for left over res */ @@ -144,10 +134,16 @@ static int __init early_fill_mp_bus_info(void) link = (reg >> 4) & 0x03; end = (reg & 0xfff000) | 0xfff; - info = find_pci_root_info(node, link); - if (!info) + /* find the position */ + for (j = 0; j < pci_root_num; j++) { + info = &pci_root_info[j]; + if (info->node == node && info->link == link) + break; + } + if (j == pci_root_num) continue; /* not found */ + info = &pci_root_info[j]; printk(KERN_DEBUG "node %d link %d: io port [%llx, %llx]\n", node, link, start, end); @@ -159,8 +155,13 @@ static int __init early_fill_mp_bus_info(void) } /* add left over io port range to def node/link, [0, 0xffff] */ /* find the position */ - info = find_pci_root_info(def_node, def_link); - if (info) { + for (j = 0; j < pci_root_num; j++) { + info = &pci_root_info[j]; + if (info->node == def_node && info->link == def_link) + break; + } + if (j < pci_root_num) { + info = &pci_root_info[j]; for (i = 0; i < RANGE_NUM; i++) { if (!range[i].end) continue; @@ -213,10 +214,16 @@ static int __init early_fill_mp_bus_info(void) end <<= 8; end |= 0xffff; - info = find_pci_root_info(node, link); + /* find the position */ + for (j = 0; j < pci_root_num; j++) { + info = &pci_root_info[j]; + if (info->node == node && info->link == link) + break; + } + if (j == pci_root_num) + continue; /* not found */ - if (!info) - continue; + info = &pci_root_info[j]; printk(KERN_DEBUG "node %d link %d: mmio [%llx, %llx]", node, link, start, end); @@ -284,8 +291,14 @@ static int __init early_fill_mp_bus_info(void) * add left over mmio range to def node/link ? * that is tricky, just record range in from start_min to 4G */ - info = find_pci_root_info(def_node, def_link); - if (info) { + for (j = 0; j < pci_root_num; j++) { + info = &pci_root_info[j]; + if (info->node == def_node && info->link == def_link) + break; + } + if (j < pci_root_num) { + info = &pci_root_info[j]; + for (i = 0; i < RANGE_NUM; i++) { if (!range[i].end) continue; @@ -296,16 +309,20 @@ static int __init early_fill_mp_bus_info(void) } } - list_for_each_entry(info, &pci_root_infos, list) { + for (i = 0; i < pci_root_num; i++) { + int res_num; int busnum; - struct pci_root_res *root_res; + info = &pci_root_info[i]; + res_num = info->res_num; busnum = info->bus_min; printk(KERN_DEBUG "bus: [%02x, %02x] on node %x link %x\n", info->bus_min, info->bus_max, info->node, info->link); - list_for_each_entry(root_res, &info->resources, list) - printk(KERN_DEBUG "bus: %02x %pR\n", - busnum, &root_res->res); + for (j = 0; j < res_num; j++) { + res = &info->res[j]; + printk(KERN_DEBUG "bus: %02x index %x %pR\n", + busnum, j, res); + } } return 0; diff --git a/trunk/arch/x86/pci/broadcom_bus.c b/trunk/arch/x86/pci/broadcom_bus.c index 614392ced7d6..f3a7c569a403 100644 --- a/trunk/arch/x86/pci/broadcom_bus.c +++ b/trunk/arch/x86/pci/broadcom_bus.c @@ -22,15 +22,19 @@ static void __init cnb20le_res(u8 bus, u8 slot, u8 func) { struct pci_root_info *info; - struct pci_root_res *root_res; struct resource res; u16 word1, word2; u8 fbus, lbus; + int i; + + info = &pci_root_info[pci_root_num]; + pci_root_num++; /* read the PCI bus numbers */ fbus = read_pci_config_byte(bus, slot, func, 0x44); lbus = read_pci_config_byte(bus, slot, func, 0x45); - info = alloc_pci_root_info(fbus, lbus, 0, 0); + info->bus_min = fbus; + info->bus_max = lbus; /* * Add the legacy IDE ports on bus 0 @@ -82,8 +86,8 @@ static void __init cnb20le_res(u8 bus, u8 slot, u8 func) res.flags = IORESOURCE_BUS; printk(KERN_INFO "CNB20LE PCI Host Bridge (domain 0000 %pR)\n", &res); - list_for_each_entry(root_res, &info->resources, list) - printk(KERN_INFO "host bridge window %pR\n", &root_res->res); + for (i = 0; i < info->res_num; i++) + printk(KERN_INFO "host bridge window %pR\n", &info->res[i]); } static int __init broadcom_postcore_init(void) diff --git a/trunk/arch/x86/pci/bus_numa.c b/trunk/arch/x86/pci/bus_numa.c index 306579f7d0fd..fd3f65510e9d 100644 --- a/trunk/arch/x86/pci/bus_numa.c +++ b/trunk/arch/x86/pci/bus_numa.c @@ -4,38 +4,35 @@ #include "bus_numa.h" -LIST_HEAD(pci_root_infos); +int pci_root_num; +struct pci_root_info pci_root_info[PCI_ROOT_NR]; -static struct pci_root_info *x86_find_pci_root_info(int bus) +void x86_pci_root_bus_resources(int bus, struct list_head *resources) { + int i; + int j; struct pci_root_info *info; - if (list_empty(&pci_root_infos)) - return NULL; - - list_for_each_entry(info, &pci_root_infos, list) - if (info->bus_min == bus) - return info; - - return NULL; -} + if (!pci_root_num) + goto default_resources; -void x86_pci_root_bus_resources(int bus, struct list_head *resources) -{ - struct pci_root_info *info = x86_find_pci_root_info(bus); - struct pci_root_res *root_res; + for (i = 0; i < pci_root_num; i++) { + if (pci_root_info[i].bus_min == bus) + break; + } - if (!info) + if (i == pci_root_num) goto default_resources; printk(KERN_DEBUG "PCI: root bus %02x: hardware-probed resources\n", bus); - list_for_each_entry(root_res, &info->resources, list) { + info = &pci_root_info[i]; + for (j = 0; j < info->res_num; j++) { struct resource *res; struct resource *root; - res = &root_res->res; + res = &info->res[j]; pci_add_resource(resources, res); if (res->flags & IORESOURCE_IO) root = &ioport_resource; @@ -56,32 +53,11 @@ void x86_pci_root_bus_resources(int bus, struct list_head *resources) pci_add_resource(resources, &iomem_resource); } -struct pci_root_info __init *alloc_pci_root_info(int bus_min, int bus_max, - int node, int link) -{ - struct pci_root_info *info; - - info = kzalloc(sizeof(*info), GFP_KERNEL); - - if (!info) - return info; - - INIT_LIST_HEAD(&info->resources); - info->bus_min = bus_min; - info->bus_max = bus_max; - info->node = node; - info->link = link; - - list_add_tail(&info->list, &pci_root_infos); - - return info; -} - void __devinit update_res(struct pci_root_info *info, resource_size_t start, resource_size_t end, unsigned long flags, int merge) { + int i; struct resource *res; - struct pci_root_res *root_res; if (start > end) return; @@ -93,11 +69,11 @@ void __devinit update_res(struct pci_root_info *info, resource_size_t start, goto addit; /* try to merge it with old one */ - list_for_each_entry(root_res, &info->resources, list) { + for (i = 0; i < info->res_num; i++) { resource_size_t final_start, final_end; resource_size_t common_start, common_end; - res = &root_res->res; + res = &info->res[i]; if (res->flags != flags) continue; @@ -117,15 +93,14 @@ void __devinit update_res(struct pci_root_info *info, resource_size_t start, addit: /* need to add that */ - root_res = kzalloc(sizeof(*root_res), GFP_KERNEL); - if (!root_res) + if (info->res_num >= RES_NUM) return; - res = &root_res->res; + res = &info->res[info->res_num]; res->name = info->name; res->flags = flags; res->start = start; res->end = end; - - list_add_tail(&root_res->list, &info->resources); + res->child = NULL; + info->res_num++; } diff --git a/trunk/arch/x86/pci/bus_numa.h b/trunk/arch/x86/pci/bus_numa.h index 226a466b2b2b..804a4b40c31a 100644 --- a/trunk/arch/x86/pci/bus_numa.h +++ b/trunk/arch/x86/pci/bus_numa.h @@ -4,24 +4,22 @@ * sub bus (transparent) will use entres from 3 to store extra from * root, so need to make sure we have enough slot there. */ -struct pci_root_res { - struct list_head list; - struct resource res; -}; - +#define RES_NUM 16 struct pci_root_info { - struct list_head list; char name[12]; - struct list_head resources; + unsigned int res_num; + struct resource res[RES_NUM]; int bus_min; int bus_max; int node; int link; }; -extern struct list_head pci_root_infos; -struct pci_root_info *alloc_pci_root_info(int bus_min, int bus_max, - int node, int link); +/* 4 at this time, it may become to 32 */ +#define PCI_ROOT_NR 4 +extern int pci_root_num; +extern struct pci_root_info pci_root_info[PCI_ROOT_NR]; + extern void update_res(struct pci_root_info *info, resource_size_t start, resource_size_t end, unsigned long flags, int merge); #endif diff --git a/trunk/arch/x86/pci/common.c b/trunk/arch/x86/pci/common.c index 0ad990a20d4a..323481e06ef8 100644 --- a/trunk/arch/x86/pci/common.c +++ b/trunk/arch/x86/pci/common.c @@ -11,7 +11,6 @@ #include #include -#include #include #include #include @@ -230,14 +229,6 @@ static int __devinit assign_all_busses(const struct dmi_system_id *d) } #endif -static int __devinit set_scan_all(const struct dmi_system_id *d) -{ - printk(KERN_INFO "PCI: %s detected, enabling pci=pcie_scan_all\n", - d->ident); - pci_add_flags(PCI_SCAN_ALL_PCIE_DEVS); - return 0; -} - static const struct dmi_system_id __devinitconst pciprobe_dmi_table[] = { #ifdef __i386__ /* @@ -429,13 +420,6 @@ static const struct dmi_system_id __devinitconst pciprobe_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"), }, }, - { - .callback = set_scan_all, - .ident = "Stratus/NEC ftServer", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ftServer"), - }, - }, {} }; @@ -446,7 +430,9 @@ void __init dmi_check_pciprobe(void) struct pci_bus * __devinit pcibios_scan_root(int busnum) { + LIST_HEAD(resources); struct pci_bus *bus = NULL; + struct pci_sysdata *sd; while ((bus = pci_find_next_bus(bus)) != NULL) { if (bus->number == busnum) { @@ -455,10 +441,28 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum) } } - return pci_scan_bus_on_node(busnum, &pci_root_ops, - get_mp_bus_to_node(busnum)); -} + /* Allocate per-root-bus (not per bus) arch-specific data. + * TODO: leak; this memory is never freed. + * It's arguable whether it's worth the trouble to care. + */ + sd = kzalloc(sizeof(*sd), GFP_KERNEL); + if (!sd) { + printk(KERN_ERR "PCI: OOM, not probing PCI bus %02x\n", busnum); + return NULL; + } + + sd->node = get_mp_bus_to_node(busnum); + printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum); + x86_pci_root_bus_resources(busnum, &resources); + bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, sd, &resources); + if (!bus) { + pci_free_resource_list(&resources); + kfree(sd); + } + + return bus; +} void __init pcibios_set_cache_line_size(void) { struct cpuinfo_x86 *c = &boot_cpu_data; @@ -652,7 +656,6 @@ struct pci_bus * __devinit pci_scan_bus_on_node(int busno, struct pci_ops *ops, } sd->node = node; x86_pci_root_bus_resources(busno, &resources); - printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busno); bus = pci_scan_root_bus(NULL, busno, ops, sd, &resources); if (!bus) { pci_free_resource_list(&resources); diff --git a/trunk/arch/x86/pci/i386.c b/trunk/arch/x86/pci/i386.c index dd8ca6f7223b..831971e731f7 100644 --- a/trunk/arch/x86/pci/i386.c +++ b/trunk/arch/x86/pci/i386.c @@ -57,7 +57,7 @@ static struct pcibios_fwaddrmap *pcibios_fwaddrmap_lookup(struct pci_dev *dev) { struct pcibios_fwaddrmap *map; - WARN_ON_SMP(!spin_is_locked(&pcibios_fwaddrmap_lock)); + WARN_ON(!spin_is_locked(&pcibios_fwaddrmap_lock)); list_for_each_entry(map, &pcibios_fwaddrmappings, list) if (map->dev == dev) diff --git a/trunk/arch/x86/platform/geode/net5501.c b/trunk/arch/x86/platform/geode/net5501.c index 646e3b5b4bb6..66d377e334f7 100644 --- a/trunk/arch/x86/platform/geode/net5501.c +++ b/trunk/arch/x86/platform/geode/net5501.c @@ -63,7 +63,7 @@ static struct gpio_led net5501_leds[] = { .name = "net5501:1", .gpio = 6, .default_trigger = "default-on", - .active_low = 0, + .active_low = 1, }, }; diff --git a/trunk/arch/x86/tools/.gitignore b/trunk/arch/x86/tools/.gitignore deleted file mode 100644 index be0ed065249b..000000000000 --- a/trunk/arch/x86/tools/.gitignore +++ /dev/null @@ -1 +0,0 @@ -relocs diff --git a/trunk/arch/x86/tools/Makefile b/trunk/arch/x86/tools/Makefile index 733057b435b0..d511aa97533a 100644 --- a/trunk/arch/x86/tools/Makefile +++ b/trunk/arch/x86/tools/Makefile @@ -36,7 +36,3 @@ HOSTCFLAGS_insn_sanity.o := -Wall -I$(objtree)/arch/x86/lib/ -I$(srctree)/arch/x $(obj)/test_get_len.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/inat.c $(srctree)/arch/x86/include/asm/inat_types.h $(srctree)/arch/x86/include/asm/inat.h $(srctree)/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c $(obj)/insn_sanity.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/inat.c $(srctree)/arch/x86/include/asm/inat_types.h $(srctree)/arch/x86/include/asm/inat.h $(srctree)/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c - -HOST_EXTRACFLAGS += -I$(srctree)/tools/include -hostprogs-y += relocs -relocs: $(obj)/relocs diff --git a/trunk/arch/x86/xen/enlighten.c b/trunk/arch/x86/xen/enlighten.c index 95dccce8e979..a8f8844b8d32 100644 --- a/trunk/arch/x86/xen/enlighten.c +++ b/trunk/arch/x86/xen/enlighten.c @@ -63,7 +63,6 @@ #include #include #include -#include #ifdef CONFIG_ACPI #include @@ -810,40 +809,9 @@ static void xen_io_delay(void) } #ifdef CONFIG_X86_LOCAL_APIC -static unsigned long xen_set_apic_id(unsigned int x) -{ - WARN_ON(1); - return x; -} -static unsigned int xen_get_apic_id(unsigned long x) -{ - return ((x)>>24) & 0xFFu; -} static u32 xen_apic_read(u32 reg) { - struct xen_platform_op op = { - .cmd = XENPF_get_cpuinfo, - .interface_version = XENPF_INTERFACE_VERSION, - .u.pcpu_info.xen_cpuid = 0, - }; - int ret = 0; - - /* Shouldn't need this as APIC is turned off for PV, and we only - * get called on the bootup processor. But just in case. */ - if (!xen_initial_domain() || smp_processor_id()) - return 0; - - if (reg == APIC_LVR) - return 0x10; - - if (reg != APIC_ID) - return 0; - - ret = HYPERVISOR_dom0_op(&op); - if (ret) - return 0; - - return op.u.pcpu_info.apic_id << 24; + return 0; } static void xen_apic_write(u32 reg, u32 val) @@ -881,8 +849,6 @@ static void set_xen_basic_apic_ops(void) apic->icr_write = xen_apic_icr_write; apic->wait_icr_idle = xen_apic_wait_icr_idle; apic->safe_wait_icr_idle = xen_safe_apic_wait_icr_idle; - apic->set_apic_id = xen_set_apic_id; - apic->get_apic_id = xen_get_apic_id; } #endif @@ -1399,10 +1365,8 @@ asmlinkage void __init xen_start_kernel(void) /* Make sure ACS will be enabled */ pci_request_acs(); } -#ifdef CONFIG_PCI - /* PCI BIOS service won't work from a PV guest. */ - pci_probe &= ~PCI_PROBE_BIOS; -#endif + + xen_raw_console_write("about to get started...\n"); xen_setup_runstate_info(0); diff --git a/trunk/arch/x86/xen/mmu.c b/trunk/arch/x86/xen/mmu.c index 69f5857660ac..b8e279479a6b 100644 --- a/trunk/arch/x86/xen/mmu.c +++ b/trunk/arch/x86/xen/mmu.c @@ -353,13 +353,8 @@ static pteval_t pte_mfn_to_pfn(pteval_t val) { if (val & _PAGE_PRESENT) { unsigned long mfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT; - unsigned long pfn = mfn_to_pfn(mfn); - pteval_t flags = val & PTE_FLAGS_MASK; - if (unlikely(pfn == ~0)) - val = flags & ~_PAGE_PRESENT; - else - val = ((pteval_t)pfn << PAGE_SHIFT) | flags; + val = ((pteval_t)mfn_to_pfn(mfn) << PAGE_SHIFT) | flags; } return val; diff --git a/trunk/arch/x86/xen/smp.c b/trunk/arch/x86/xen/smp.c index 3700945ed0d5..0503c0c493a9 100644 --- a/trunk/arch/x86/xen/smp.c +++ b/trunk/arch/x86/xen/smp.c @@ -265,8 +265,18 @@ static void __init xen_smp_prepare_cpus(unsigned int max_cpus) set_cpu_possible(cpu, false); } - for_each_possible_cpu(cpu) + for_each_possible_cpu (cpu) { + struct task_struct *idle; + + if (cpu == 0) + continue; + + idle = fork_idle(cpu); + if (IS_ERR(idle)) + panic("failed fork for CPU %d", cpu); + set_cpu_present(cpu, true); + } } static int __cpuinit @@ -336,8 +346,9 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle) return 0; } -static int __cpuinit xen_cpu_up(unsigned int cpu, struct task_struct *idle) +static int __cpuinit xen_cpu_up(unsigned int cpu) { + struct task_struct *idle = idle_task(cpu); int rc; per_cpu(current_task, cpu) = idle; @@ -551,10 +562,10 @@ static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus) xen_init_lock_cpu(0); } -static int __cpuinit xen_hvm_cpu_up(unsigned int cpu, struct task_struct *tidle) +static int __cpuinit xen_hvm_cpu_up(unsigned int cpu) { int rc; - rc = native_cpu_up(cpu, tidle); + rc = native_cpu_up(cpu); WARN_ON (xen_smp_intr_init(cpu)); return rc; } diff --git a/trunk/arch/xtensa/configs/common_defconfig b/trunk/arch/xtensa/configs/common_defconfig index a182a4e6d688..b90038e40dd3 100644 --- a/trunk/arch/xtensa/configs/common_defconfig +++ b/trunk/arch/xtensa/configs/common_defconfig @@ -332,6 +332,11 @@ CONFIG_XT2000_SONIC=y # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# +# Token Ring devices +# +# CONFIG_TR is not set + # # Wireless LAN (non-hamradio) # diff --git a/trunk/arch/xtensa/kernel/Makefile b/trunk/arch/xtensa/kernel/Makefile index 59fc3fe15572..2d2728b3e862 100644 --- a/trunk/arch/xtensa/kernel/Makefile +++ b/trunk/arch/xtensa/kernel/Makefile @@ -6,7 +6,7 @@ extra-y := head.o vmlinux.lds obj-y := align.o entry.o irq.o coprocessor.o process.o ptrace.o \ setup.o signal.o syscall.o time.o traps.o vectors.o platform.o \ - pci-dma.o io.o + pci-dma.o init_task.o io.o obj-$(CONFIG_KGDB) += xtensa-stub.o obj-$(CONFIG_PCI) += pci.o diff --git a/trunk/arch/xtensa/kernel/init_task.c b/trunk/arch/xtensa/kernel/init_task.c new file mode 100644 index 000000000000..cd122fb7e48a --- /dev/null +++ b/trunk/arch/xtensa/kernel/init_task.c @@ -0,0 +1,31 @@ +/* + * arch/xtensa/kernel/init_task.c + * + * Xtensa Processor version. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2007 Tensilica Inc. + * + * Chris Zankel + */ + +#include +#include +#include +#include +#include +#include + +#include + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +union thread_union init_thread_union __init_task_data = + { INIT_THREAD_INFO(init_task) }; + +struct task_struct init_task = INIT_TASK(init_task); + +EXPORT_SYMBOL(init_task); diff --git a/trunk/block/genhd.c b/trunk/block/genhd.c index 9cf5583c90ff..df9816ede75b 100644 --- a/trunk/block/genhd.c +++ b/trunk/block/genhd.c @@ -743,7 +743,7 @@ void __init printk_all_partitions(void) struct hd_struct *part; char name_buf[BDEVNAME_SIZE]; char devt_buf[BDEVT_SIZE]; - char uuid_buf[PARTITION_META_INFO_UUIDLTH * 2 + 5]; + u8 uuid[PARTITION_META_INFO_UUIDLTH * 2 + 1]; /* * Don't show empty devices or things that have been @@ -762,16 +762,14 @@ void __init printk_all_partitions(void) while ((part = disk_part_iter_next(&piter))) { bool is_part0 = part == &disk->part0; - uuid_buf[0] = '\0'; + uuid[0] = 0; if (part->info) - snprintf(uuid_buf, sizeof(uuid_buf), "%pU", - part->info->uuid); + part_unpack_uuid(part->info->uuid, uuid); printk("%s%s %10llu %s %s", is_part0 ? "" : " ", bdevt_str(part_devt(part), devt_buf), (unsigned long long)part->nr_sects >> 1, - disk_name(disk, part->partno, name_buf), - uuid_buf); + disk_name(disk, part->partno, name_buf), uuid); if (is_part0) { if (disk->driverfs_dev != NULL && disk->driverfs_dev->driver != NULL) diff --git a/trunk/block/partitions/ibm.c b/trunk/block/partitions/ibm.c index 1104acac780b..d513a07f44bb 100644 --- a/trunk/block/partitions/ibm.c +++ b/trunk/block/partitions/ibm.c @@ -253,7 +253,7 @@ int ibm_partition(struct parsed_partitions *state) /* Are we not supposed to report this ? */ goto out_readerr; } else - printk(KERN_INFO "Expected Label VOL1 not " + printk(KERN_WARNING "Warning, expected Label VOL1 not " "found, treating as CDL formated Disk"); } diff --git a/trunk/drivers/acpi/bus.c b/trunk/drivers/acpi/bus.c index 3188da3df8da..3263b68cdfa3 100644 --- a/trunk/drivers/acpi/bus.c +++ b/trunk/drivers/acpi/bus.c @@ -250,10 +250,6 @@ static int __acpi_bus_set_power(struct acpi_device *device, int state) return -ENODEV; } - /* For D3cold we should execute _PS3, not _PS4. */ - if (state == ACPI_STATE_D3_COLD) - object_name[3] = '3'; - /* * Transition Power * ---------------- diff --git a/trunk/drivers/acpi/power.c b/trunk/drivers/acpi/power.c index 0500f719f63e..7049a7d27c4f 100644 --- a/trunk/drivers/acpi/power.c +++ b/trunk/drivers/acpi/power.c @@ -631,7 +631,7 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state) * We know a device's inferred power state when all the resources * required for a given D-state are 'on'. */ - for (i = ACPI_STATE_D0; i < ACPI_STATE_D3_HOT; i++) { + for (i = ACPI_STATE_D0; i < ACPI_STATE_D3; i++) { list = &device->power.states[i].resources; if (list->count < 1) continue; @@ -660,7 +660,7 @@ int acpi_power_on_resources(struct acpi_device *device, int state) int acpi_power_transition(struct acpi_device *device, int state) { - int result = 0; + int result; if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD)) return -EINVAL; @@ -679,11 +679,8 @@ int acpi_power_transition(struct acpi_device *device, int state) * (e.g. so the device doesn't lose power while transitioning). Then, * we dereference all power resources used in the current list. */ - if (state < ACPI_STATE_D3_COLD) - result = acpi_power_on_list( - &device->power.states[state].resources); - - if (!result && device->power.state < ACPI_STATE_D3_COLD) + result = acpi_power_on_list(&device->power.states[state].resources); + if (!result) acpi_power_off_list( &device->power.states[device->power.state].resources); diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c index 85cbfdccc97c..767e2dcb9616 100644 --- a/trunk/drivers/acpi/scan.c +++ b/trunk/drivers/acpi/scan.c @@ -869,7 +869,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) /* * Enumerate supported power management states */ - for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) { + for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) { struct acpi_device_power_state *ps = &device->power.states[i]; char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' }; @@ -884,18 +884,21 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) acpi_bus_add_power_resource(ps->resources.handles[j]); } + /* The exist of _PR3 indicates D3Cold support */ + if (i == ACPI_STATE_D3) { + status = acpi_get_handle(device->handle, object_name, &handle); + if (ACPI_SUCCESS(status)) + device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1; + } + /* Evaluate "_PSx" to see if we can do explicit sets */ object_name[2] = 'S'; status = acpi_get_handle(device->handle, object_name, &handle); if (ACPI_SUCCESS(status)) ps->flags.explicit_set = 1; - /* - * State is valid if there are means to put the device into it. - * D3hot is only valid if _PR3 present. - */ - if (ps->resources.count || - (ps->flags.explicit_set && i < ACPI_STATE_D3_HOT)) + /* State is valid if we have some power control */ + if (ps->resources.count || ps->flags.explicit_set) ps->flags.valid = 1; ps->power = -1; /* Unknown - driver assigned */ @@ -908,10 +911,6 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) device->power.states[ACPI_STATE_D3].flags.valid = 1; device->power.states[ACPI_STATE_D3].power = 0; - /* Set D3cold's explicit_set flag if _PS3 exists. */ - if (device->power.states[ACPI_STATE_D3_HOT].flags.explicit_set) - device->power.states[ACPI_STATE_D3_COLD].flags.explicit_set = 1; - acpi_bus_init_power(device); return 0; diff --git a/trunk/drivers/amba/bus.c b/trunk/drivers/amba/bus.c index b7e728517284..cc273226dbd0 100644 --- a/trunk/drivers/amba/bus.c +++ b/trunk/drivers/amba/bus.c @@ -527,9 +527,9 @@ int amba_device_add(struct amba_device *dev, struct resource *parent) if (ret) goto err_release; - if (dev->irq[0]) + if (dev->irq[0] && dev->irq[0] != NO_IRQ) ret = device_create_file(&dev->dev, &dev_attr_irq0); - if (ret == 0 && dev->irq[1]) + if (ret == 0 && dev->irq[1] && dev->irq[1] != NO_IRQ) ret = device_create_file(&dev->dev, &dev_attr_irq1); if (ret == 0) return ret; @@ -543,55 +543,6 @@ int amba_device_add(struct amba_device *dev, struct resource *parent) } EXPORT_SYMBOL_GPL(amba_device_add); -static struct amba_device * -amba_aphb_device_add(struct device *parent, const char *name, - resource_size_t base, size_t size, int irq1, int irq2, - void *pdata, unsigned int periphid, u64 dma_mask) -{ - struct amba_device *dev; - int ret; - - dev = amba_device_alloc(name, base, size); - if (!dev) - return ERR_PTR(-ENOMEM); - - dev->dma_mask = dma_mask; - dev->dev.coherent_dma_mask = dma_mask; - dev->irq[0] = irq1; - dev->irq[1] = irq2; - dev->periphid = periphid; - dev->dev.platform_data = pdata; - dev->dev.parent = parent; - - ret = amba_device_add(dev, &iomem_resource); - if (ret) { - amba_device_put(dev); - return ERR_PTR(ret); - } - - return dev; -} - -struct amba_device * -amba_apb_device_add(struct device *parent, const char *name, - resource_size_t base, size_t size, int irq1, int irq2, - void *pdata, unsigned int periphid) -{ - return amba_aphb_device_add(parent, name, base, size, irq1, irq2, pdata, - periphid, 0); -} -EXPORT_SYMBOL_GPL(amba_apb_device_add); - -struct amba_device * -amba_ahb_device_add(struct device *parent, const char *name, - resource_size_t base, size_t size, int irq1, int irq2, - void *pdata, unsigned int periphid) -{ - return amba_aphb_device_add(parent, name, base, size, irq1, irq2, pdata, - periphid, ~0ULL); -} -EXPORT_SYMBOL_GPL(amba_ahb_device_add); - static void amba_device_initialize(struct amba_device *dev, const char *name) { device_initialize(&dev->dev); diff --git a/trunk/drivers/base/regmap/Kconfig b/trunk/drivers/base/regmap/Kconfig index 9ef0a5326f17..0f6c7fb418e8 100644 --- a/trunk/drivers/base/regmap/Kconfig +++ b/trunk/drivers/base/regmap/Kconfig @@ -14,8 +14,5 @@ config REGMAP_I2C config REGMAP_SPI tristate -config REGMAP_MMIO - tristate - config REGMAP_IRQ bool diff --git a/trunk/drivers/base/regmap/Makefile b/trunk/drivers/base/regmap/Makefile index 5e75d1b683e2..defd57963c84 100644 --- a/trunk/drivers/base/regmap/Makefile +++ b/trunk/drivers/base/regmap/Makefile @@ -3,5 +3,4 @@ obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-lzo.o obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o -obj-$(CONFIG_REGMAP_MMIO) += regmap-mmio.o obj-$(CONFIG_REGMAP_IRQ) += regmap-irq.o diff --git a/trunk/drivers/base/regmap/internal.h b/trunk/drivers/base/regmap/internal.h index b986b8660b0c..fcafc5b2e651 100644 --- a/trunk/drivers/base/regmap/internal.h +++ b/trunk/drivers/base/regmap/internal.h @@ -26,30 +26,21 @@ struct regmap_format { size_t val_bytes; void (*format_write)(struct regmap *map, unsigned int reg, unsigned int val); - void (*format_reg)(void *buf, unsigned int reg, unsigned int shift); - void (*format_val)(void *buf, unsigned int val, unsigned int shift); + void (*format_reg)(void *buf, unsigned int reg); + void (*format_val)(void *buf, unsigned int val); unsigned int (*parse_val)(void *buf); }; -typedef void (*regmap_lock)(struct regmap *map); -typedef void (*regmap_unlock)(struct regmap *map); - struct regmap { - struct mutex mutex; - spinlock_t spinlock; - regmap_lock lock; - regmap_unlock unlock; + struct mutex lock; struct device *dev; /* Device we do I/O on */ void *work_buf; /* Scratch buffer used to format I/O */ struct regmap_format format; /* Buffer format */ const struct regmap_bus *bus; - void *bus_context; - const char *name; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs; - const char *debugfs_name; #endif unsigned int max_register; @@ -61,10 +52,6 @@ struct regmap { u8 read_flag_mask; u8 write_flag_mask; - /* number of bits to (left) shift the reg value when formatting*/ - int reg_shift; - int reg_stride; - /* regcache specific members */ const struct regcache_ops *cache_ops; enum regcache_type cache_type; @@ -92,9 +79,6 @@ struct regmap { struct reg_default *patch; int patch_regs; - - /* if set, converts bulk rw to single rw */ - bool use_single_rw; }; struct regcache_ops { @@ -117,11 +101,11 @@ int _regmap_write(struct regmap *map, unsigned int reg, #ifdef CONFIG_DEBUG_FS extern void regmap_debugfs_initcall(void); -extern void regmap_debugfs_init(struct regmap *map, const char *name); +extern void regmap_debugfs_init(struct regmap *map); extern void regmap_debugfs_exit(struct regmap *map); #else static inline void regmap_debugfs_initcall(void) { } -static inline void regmap_debugfs_init(struct regmap *map, const char *name) { } +static inline void regmap_debugfs_init(struct regmap *map) { } static inline void regmap_debugfs_exit(struct regmap *map) { } #endif diff --git a/trunk/drivers/base/regmap/regcache-lzo.c b/trunk/drivers/base/regmap/regcache-lzo.c index afd6aa91a0df..483b06d4a380 100644 --- a/trunk/drivers/base/regmap/regcache-lzo.c +++ b/trunk/drivers/base/regmap/regcache-lzo.c @@ -108,7 +108,7 @@ static int regcache_lzo_decompress_cache_block(struct regmap *map, static inline int regcache_lzo_get_blkindex(struct regmap *map, unsigned int reg) { - return ((reg / map->reg_stride) * map->cache_word_size) / + return (reg * map->cache_word_size) / DIV_ROUND_UP(map->cache_size_raw, regcache_lzo_block_count(map)); } @@ -116,10 +116,9 @@ static inline int regcache_lzo_get_blkindex(struct regmap *map, static inline int regcache_lzo_get_blkpos(struct regmap *map, unsigned int reg) { - return (reg / map->reg_stride) % - (DIV_ROUND_UP(map->cache_size_raw, - regcache_lzo_block_count(map)) / - map->cache_word_size); + return reg % (DIV_ROUND_UP(map->cache_size_raw, + regcache_lzo_block_count(map)) / + map->cache_word_size); } static inline int regcache_lzo_get_blksize(struct regmap *map) @@ -323,7 +322,7 @@ static int regcache_lzo_write(struct regmap *map, } /* set the bit so we know we have to sync this register */ - set_bit(reg / map->reg_stride, lzo_block->sync_bmp); + set_bit(reg, lzo_block->sync_bmp); kfree(tmp_dst); kfree(lzo_block->src); return 0; diff --git a/trunk/drivers/base/regmap/regcache-rbtree.c b/trunk/drivers/base/regmap/regcache-rbtree.c index e6732cf7c06e..92b779ee002b 100644 --- a/trunk/drivers/base/regmap/regcache-rbtree.c +++ b/trunk/drivers/base/regmap/regcache-rbtree.c @@ -39,12 +39,11 @@ struct regcache_rbtree_ctx { }; static inline void regcache_rbtree_get_base_top_reg( - struct regmap *map, struct regcache_rbtree_node *rbnode, unsigned int *base, unsigned int *top) { *base = rbnode->base_reg; - *top = rbnode->base_reg + ((rbnode->blklen - 1) * map->reg_stride); + *top = rbnode->base_reg + rbnode->blklen - 1; } static unsigned int regcache_rbtree_get_register( @@ -71,8 +70,7 @@ static struct regcache_rbtree_node *regcache_rbtree_lookup(struct regmap *map, rbnode = rbtree_ctx->cached_rbnode; if (rbnode) { - regcache_rbtree_get_base_top_reg(map, rbnode, &base_reg, - &top_reg); + regcache_rbtree_get_base_top_reg(rbnode, &base_reg, &top_reg); if (reg >= base_reg && reg <= top_reg) return rbnode; } @@ -80,8 +78,7 @@ static struct regcache_rbtree_node *regcache_rbtree_lookup(struct regmap *map, node = rbtree_ctx->root.rb_node; while (node) { rbnode = container_of(node, struct regcache_rbtree_node, node); - regcache_rbtree_get_base_top_reg(map, rbnode, &base_reg, - &top_reg); + regcache_rbtree_get_base_top_reg(rbnode, &base_reg, &top_reg); if (reg >= base_reg && reg <= top_reg) { rbtree_ctx->cached_rbnode = rbnode; return rbnode; @@ -95,7 +92,7 @@ static struct regcache_rbtree_node *regcache_rbtree_lookup(struct regmap *map, return NULL; } -static int regcache_rbtree_insert(struct regmap *map, struct rb_root *root, +static int regcache_rbtree_insert(struct rb_root *root, struct regcache_rbtree_node *rbnode) { struct rb_node **new, *parent; @@ -109,7 +106,7 @@ static int regcache_rbtree_insert(struct regmap *map, struct rb_root *root, rbnode_tmp = container_of(*new, struct regcache_rbtree_node, node); /* base and top registers of the current rbnode */ - regcache_rbtree_get_base_top_reg(map, rbnode_tmp, &base_reg_tmp, + regcache_rbtree_get_base_top_reg(rbnode_tmp, &base_reg_tmp, &top_reg_tmp); /* base register of the rbnode to be added */ base_reg = rbnode->base_reg; @@ -141,20 +138,19 @@ static int rbtree_show(struct seq_file *s, void *ignored) unsigned int base, top; int nodes = 0; int registers = 0; - int this_registers, average; + int average; - map->lock(map); + mutex_lock(&map->lock); for (node = rb_first(&rbtree_ctx->root); node != NULL; node = rb_next(node)) { n = container_of(node, struct regcache_rbtree_node, node); - regcache_rbtree_get_base_top_reg(map, n, &base, &top); - this_registers = ((top - base) / map->reg_stride) + 1; - seq_printf(s, "%x-%x (%d)\n", base, top, this_registers); + regcache_rbtree_get_base_top_reg(n, &base, &top); + seq_printf(s, "%x-%x (%d)\n", base, top, top - base + 1); nodes++; - registers += this_registers; + registers += top - base + 1; } if (nodes) @@ -165,7 +161,7 @@ static int rbtree_show(struct seq_file *s, void *ignored) seq_printf(s, "%d nodes, %d registers, average %d registers\n", nodes, registers, average); - map->unlock(map); + mutex_unlock(&map->lock); return 0; } @@ -259,7 +255,7 @@ static int regcache_rbtree_read(struct regmap *map, rbnode = regcache_rbtree_lookup(map, reg); if (rbnode) { - reg_tmp = (reg - rbnode->base_reg) / map->reg_stride; + reg_tmp = reg - rbnode->base_reg; *value = regcache_rbtree_get_register(rbnode, reg_tmp, map->cache_word_size); } else { @@ -314,7 +310,7 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg, */ rbnode = regcache_rbtree_lookup(map, reg); if (rbnode) { - reg_tmp = (reg - rbnode->base_reg) / map->reg_stride; + reg_tmp = reg - rbnode->base_reg; val = regcache_rbtree_get_register(rbnode, reg_tmp, map->cache_word_size); if (val == value) @@ -325,15 +321,13 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg, /* look for an adjacent register to the one we are about to add */ for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) { - rbnode_tmp = rb_entry(node, struct regcache_rbtree_node, - node); + rbnode_tmp = rb_entry(node, struct regcache_rbtree_node, node); for (i = 0; i < rbnode_tmp->blklen; i++) { - reg_tmp = rbnode_tmp->base_reg + - (i * map->reg_stride); - if (abs(reg_tmp - reg) != map->reg_stride) + reg_tmp = rbnode_tmp->base_reg + i; + if (abs(reg_tmp - reg) != 1) continue; /* decide where in the block to place our register */ - if (reg_tmp + map->reg_stride == reg) + if (reg_tmp + 1 == reg) pos = i + 1; else pos = i; @@ -363,7 +357,7 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg, return -ENOMEM; } regcache_rbtree_set_register(rbnode, 0, value, map->cache_word_size); - regcache_rbtree_insert(map, &rbtree_ctx->root, rbnode); + regcache_rbtree_insert(&rbtree_ctx->root, rbnode); rbtree_ctx->cached_rbnode = rbnode; } @@ -403,7 +397,7 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min, end = rbnode->blklen; for (i = base; i < end; i++) { - regtmp = rbnode->base_reg + (i * map->reg_stride); + regtmp = rbnode->base_reg + i; val = regcache_rbtree_get_register(rbnode, i, map->cache_word_size); diff --git a/trunk/drivers/base/regmap/regcache.c b/trunk/drivers/base/regmap/regcache.c index 835883bda977..74b69095def6 100644 --- a/trunk/drivers/base/regmap/regcache.c +++ b/trunk/drivers/base/regmap/regcache.c @@ -59,7 +59,7 @@ static int regcache_hw_init(struct regmap *map) for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) { val = regcache_get_val(map->reg_defaults_raw, i, map->cache_word_size); - if (regmap_volatile(map, i * map->reg_stride)) + if (regmap_volatile(map, i)) continue; count++; } @@ -76,9 +76,9 @@ static int regcache_hw_init(struct regmap *map) for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) { val = regcache_get_val(map->reg_defaults_raw, i, map->cache_word_size); - if (regmap_volatile(map, i * map->reg_stride)) + if (regmap_volatile(map, i)) continue; - map->reg_defaults[j].reg = i * map->reg_stride; + map->reg_defaults[j].reg = i; map->reg_defaults[j].def = val; j++; } @@ -98,10 +98,6 @@ int regcache_init(struct regmap *map, const struct regmap_config *config) int i; void *tmp_buf; - for (i = 0; i < config->num_reg_defaults; i++) - if (config->reg_defaults[i].reg % map->reg_stride) - return -EINVAL; - if (map->cache_type == REGCACHE_NONE) { map->cache_bypass = true; return 0; @@ -268,7 +264,7 @@ int regcache_sync(struct regmap *map) BUG_ON(!map->cache_ops || !map->cache_ops->sync); - map->lock(map); + mutex_lock(&map->lock); /* Remember the initial bypass state */ bypass = map->cache_bypass; dev_dbg(map->dev, "Syncing %s cache\n", @@ -282,10 +278,6 @@ int regcache_sync(struct regmap *map) /* Apply any patch first */ map->cache_bypass = 1; for (i = 0; i < map->patch_regs; i++) { - if (map->patch[i].reg % map->reg_stride) { - ret = -EINVAL; - goto out; - } ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def); if (ret != 0) { dev_err(map->dev, "Failed to write %x = %x: %d\n", @@ -304,7 +296,7 @@ int regcache_sync(struct regmap *map) trace_regcache_sync(map->dev, name, "stop"); /* Restore the bypass state */ map->cache_bypass = bypass; - map->unlock(map); + mutex_unlock(&map->lock); return ret; } @@ -331,7 +323,7 @@ int regcache_sync_region(struct regmap *map, unsigned int min, BUG_ON(!map->cache_ops || !map->cache_ops->sync); - map->lock(map); + mutex_lock(&map->lock); /* Remember the initial bypass state */ bypass = map->cache_bypass; @@ -350,7 +342,7 @@ int regcache_sync_region(struct regmap *map, unsigned int min, trace_regcache_sync(map->dev, name, "stop region"); /* Restore the bypass state */ map->cache_bypass = bypass; - map->unlock(map); + mutex_unlock(&map->lock); return ret; } @@ -370,11 +362,11 @@ EXPORT_SYMBOL_GPL(regcache_sync_region); */ void regcache_cache_only(struct regmap *map, bool enable) { - map->lock(map); + mutex_lock(&map->lock); WARN_ON(map->cache_bypass && enable); map->cache_only = enable; trace_regmap_cache_only(map->dev, enable); - map->unlock(map); + mutex_unlock(&map->lock); } EXPORT_SYMBOL_GPL(regcache_cache_only); @@ -389,9 +381,9 @@ EXPORT_SYMBOL_GPL(regcache_cache_only); */ void regcache_mark_dirty(struct regmap *map) { - map->lock(map); + mutex_lock(&map->lock); map->cache_dirty = true; - map->unlock(map); + mutex_unlock(&map->lock); } EXPORT_SYMBOL_GPL(regcache_mark_dirty); @@ -408,11 +400,11 @@ EXPORT_SYMBOL_GPL(regcache_mark_dirty); */ void regcache_cache_bypass(struct regmap *map, bool enable) { - map->lock(map); + mutex_lock(&map->lock); WARN_ON(map->cache_only && enable); map->cache_bypass = enable; trace_regmap_cache_bypass(map->dev, enable); - map->unlock(map); + mutex_unlock(&map->lock); } EXPORT_SYMBOL_GPL(regcache_cache_bypass); diff --git a/trunk/drivers/base/regmap/regmap-debugfs.c b/trunk/drivers/base/regmap/regmap-debugfs.c index bb1ff175b962..251eb70f83e7 100644 --- a/trunk/drivers/base/regmap/regmap-debugfs.c +++ b/trunk/drivers/base/regmap/regmap-debugfs.c @@ -80,7 +80,7 @@ static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf, val_len = 2 * map->format.val_bytes; tot_len = reg_len + val_len + 3; /* : \n */ - for (i = 0; i <= map->max_register; i += map->reg_stride) { + for (i = 0; i < map->max_register + 1; i++) { if (!regmap_readable(map, i)) continue; @@ -197,7 +197,7 @@ static ssize_t regmap_access_read_file(struct file *file, reg_len = regmap_calc_reg_len(map->max_register, buf, count); tot_len = reg_len + 10; /* ': R W V P\n' */ - for (i = 0; i <= map->max_register; i += map->reg_stride) { + for (i = 0; i < map->max_register + 1; i++) { /* Ignore registers which are neither readable nor writable */ if (!regmap_readable(map, i) && !regmap_writeable(map, i)) continue; @@ -242,17 +242,10 @@ static const struct file_operations regmap_access_fops = { .llseek = default_llseek, }; -void regmap_debugfs_init(struct regmap *map, const char *name) +void regmap_debugfs_init(struct regmap *map) { - if (name) { - map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s", - dev_name(map->dev), name); - name = map->debugfs_name; - } else { - name = dev_name(map->dev); - } - - map->debugfs = debugfs_create_dir(name, regmap_debugfs_root); + map->debugfs = debugfs_create_dir(dev_name(map->dev), + regmap_debugfs_root); if (!map->debugfs) { dev_warn(map->dev, "Failed to create debugfs directory\n"); return; @@ -281,7 +274,6 @@ void regmap_debugfs_init(struct regmap *map, const char *name) void regmap_debugfs_exit(struct regmap *map) { debugfs_remove_recursive(map->debugfs); - kfree(map->debugfs_name); } void regmap_debugfs_initcall(void) diff --git a/trunk/drivers/base/regmap/regmap-i2c.c b/trunk/drivers/base/regmap/regmap-i2c.c index 5f6b2478bf17..9a3a8c564389 100644 --- a/trunk/drivers/base/regmap/regmap-i2c.c +++ b/trunk/drivers/base/regmap/regmap-i2c.c @@ -15,9 +15,8 @@ #include #include -static int regmap_i2c_write(void *context, const void *data, size_t count) +static int regmap_i2c_write(struct device *dev, const void *data, size_t count) { - struct device *dev = context; struct i2c_client *i2c = to_i2c_client(dev); int ret; @@ -30,11 +29,10 @@ static int regmap_i2c_write(void *context, const void *data, size_t count) return -EIO; } -static int regmap_i2c_gather_write(void *context, +static int regmap_i2c_gather_write(struct device *dev, const void *reg, size_t reg_size, const void *val, size_t val_size) { - struct device *dev = context; struct i2c_client *i2c = to_i2c_client(dev); struct i2c_msg xfer[2]; int ret; @@ -64,11 +62,10 @@ static int regmap_i2c_gather_write(void *context, return -EIO; } -static int regmap_i2c_read(void *context, +static int regmap_i2c_read(struct device *dev, const void *reg, size_t reg_size, void *val, size_t val_size) { - struct device *dev = context; struct i2c_client *i2c = to_i2c_client(dev); struct i2c_msg xfer[2]; int ret; @@ -110,7 +107,7 @@ static struct regmap_bus regmap_i2c = { struct regmap *regmap_init_i2c(struct i2c_client *i2c, const struct regmap_config *config) { - return regmap_init(&i2c->dev, ®map_i2c, &i2c->dev, config); + return regmap_init(&i2c->dev, ®map_i2c, config); } EXPORT_SYMBOL_GPL(regmap_init_i2c); @@ -127,7 +124,7 @@ EXPORT_SYMBOL_GPL(regmap_init_i2c); struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c, const struct regmap_config *config) { - return devm_regmap_init(&i2c->dev, ®map_i2c, &i2c->dev, config); + return devm_regmap_init(&i2c->dev, ®map_i2c, config); } EXPORT_SYMBOL_GPL(devm_regmap_init_i2c); diff --git a/trunk/drivers/base/regmap/regmap-irq.c b/trunk/drivers/base/regmap/regmap-irq.c index 4fac4b9be88f..1befaa7a31cb 100644 --- a/trunk/drivers/base/regmap/regmap-irq.c +++ b/trunk/drivers/base/regmap/regmap-irq.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include "internal.h" @@ -27,20 +26,18 @@ struct regmap_irq_chip_data { struct regmap_irq_chip *chip; int irq_base; - struct irq_domain *domain; + void *status_reg_buf; unsigned int *status_buf; unsigned int *mask_buf; unsigned int *mask_buf_def; - - unsigned int irq_reg_stride; }; static inline const struct regmap_irq *irq_to_regmap_irq(struct regmap_irq_chip_data *data, int irq) { - return &data->chip->irqs[irq]; + return &data->chip->irqs[irq - data->irq_base]; } static void regmap_irq_lock(struct irq_data *data) @@ -53,7 +50,6 @@ static void regmap_irq_lock(struct irq_data *data) static void regmap_irq_sync_unlock(struct irq_data *data) { struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); - struct regmap *map = d->map; int i, ret; /* @@ -62,13 +58,11 @@ static void regmap_irq_sync_unlock(struct irq_data *data) * suppress pointless writes. */ for (i = 0; i < d->chip->num_regs; i++) { - ret = regmap_update_bits(d->map, d->chip->mask_base + - (i * map->reg_stride * - d->irq_reg_stride), + ret = regmap_update_bits(d->map, d->chip->mask_base + i, d->mask_buf_def[i], d->mask_buf[i]); if (ret != 0) dev_err(d->map->dev, "Failed to sync masks in %x\n", - d->chip->mask_base + (i * map->reg_stride)); + d->chip->mask_base + i); } mutex_unlock(&d->lock); @@ -77,19 +71,17 @@ static void regmap_irq_sync_unlock(struct irq_data *data) static void regmap_irq_enable(struct irq_data *data) { struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); - struct regmap *map = d->map; - const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq); + const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->irq); - d->mask_buf[irq_data->reg_offset / map->reg_stride] &= ~irq_data->mask; + d->mask_buf[irq_data->reg_offset] &= ~irq_data->mask; } static void regmap_irq_disable(struct irq_data *data) { struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); - struct regmap *map = d->map; - const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq); + const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->irq); - d->mask_buf[irq_data->reg_offset / map->reg_stride] |= irq_data->mask; + d->mask_buf[irq_data->reg_offset] |= irq_data->mask; } static struct irq_chip regmap_irq_chip = { @@ -106,8 +98,18 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) struct regmap_irq_chip *chip = data->chip; struct regmap *map = data->map; int ret, i; + u8 *buf8 = data->status_reg_buf; + u16 *buf16 = data->status_reg_buf; + u32 *buf32 = data->status_reg_buf; bool handled = false; + ret = regmap_bulk_read(map, chip->status_base, data->status_reg_buf, + chip->num_regs); + if (ret != 0) { + dev_err(map->dev, "Failed to read IRQ status: %d\n", ret); + return IRQ_NONE; + } + /* * Ignore masked IRQs and ack if we need to; we ack early so * there is no race between handling and acknowleding the @@ -116,34 +118,36 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) * doing a write per register. */ for (i = 0; i < data->chip->num_regs; i++) { - ret = regmap_read(map, chip->status_base + (i * map->reg_stride - * data->irq_reg_stride), - &data->status_buf[i]); - - if (ret != 0) { - dev_err(map->dev, "Failed to read IRQ status: %d\n", - ret); + switch (map->format.val_bytes) { + case 1: + data->status_buf[i] = buf8[i]; + break; + case 2: + data->status_buf[i] = buf16[i]; + break; + case 4: + data->status_buf[i] = buf32[i]; + break; + default: + BUG(); return IRQ_NONE; } data->status_buf[i] &= ~data->mask_buf[i]; if (data->status_buf[i] && chip->ack_base) { - ret = regmap_write(map, chip->ack_base + - (i * map->reg_stride * - data->irq_reg_stride), + ret = regmap_write(map, chip->ack_base + i, data->status_buf[i]); if (ret != 0) dev_err(map->dev, "Failed to ack 0x%x: %d\n", - chip->ack_base + (i * map->reg_stride), - ret); + chip->ack_base + i, ret); } } for (i = 0; i < chip->num_irqs; i++) { - if (data->status_buf[chip->irqs[i].reg_offset / - map->reg_stride] & chip->irqs[i].mask) { - handle_nested_irq(irq_find_mapping(data->domain, i)); + if (data->status_buf[chip->irqs[i].reg_offset] & + chip->irqs[i].mask) { + handle_nested_irq(data->irq_base + i); handled = true; } } @@ -154,31 +158,6 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) return IRQ_NONE; } -static int regmap_irq_map(struct irq_domain *h, unsigned int virq, - irq_hw_number_t hw) -{ - struct regmap_irq_chip_data *data = h->host_data; - - irq_set_chip_data(virq, data); - irq_set_chip_and_handler(virq, ®map_irq_chip, handle_edge_irq); - irq_set_nested_thread(virq, 1); - - /* ARM needs us to explicitly flag the IRQ as valid - * and will set them noprobe when we do so. */ -#ifdef CONFIG_ARM - set_irq_flags(virq, IRQF_VALID); -#else - irq_set_noprobe(virq); -#endif - - return 0; -} - -static struct irq_domain_ops regmap_domain_ops = { - .map = regmap_irq_map, - .xlate = irq_domain_xlate_twocell, -}; - /** * regmap_add_irq_chip(): Use standard regmap IRQ controller handling * @@ -199,37 +178,30 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, struct regmap_irq_chip_data **data) { struct regmap_irq_chip_data *d; - int i; + int cur_irq, i; int ret = -ENOMEM; - for (i = 0; i < chip->num_irqs; i++) { - if (chip->irqs[i].reg_offset % map->reg_stride) - return -EINVAL; - if (chip->irqs[i].reg_offset / map->reg_stride >= - chip->num_regs) - return -EINVAL; - } - - if (irq_base) { - irq_base = irq_alloc_descs(irq_base, 0, chip->num_irqs, 0); - if (irq_base < 0) { - dev_warn(map->dev, "Failed to allocate IRQs: %d\n", - irq_base); - return irq_base; - } + irq_base = irq_alloc_descs(irq_base, 0, chip->num_irqs, 0); + if (irq_base < 0) { + dev_warn(map->dev, "Failed to allocate IRQs: %d\n", + irq_base); + return irq_base; } d = kzalloc(sizeof(*d), GFP_KERNEL); if (!d) return -ENOMEM; - *data = d; - d->status_buf = kzalloc(sizeof(unsigned int) * chip->num_regs, GFP_KERNEL); if (!d->status_buf) goto err_alloc; + d->status_reg_buf = kzalloc(map->format.val_bytes * chip->num_regs, + GFP_KERNEL); + if (!d->status_reg_buf) + goto err_alloc; + d->mask_buf = kzalloc(sizeof(unsigned int) * chip->num_regs, GFP_KERNEL); if (!d->mask_buf) @@ -243,59 +215,54 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, d->map = map; d->chip = chip; d->irq_base = irq_base; - - if (chip->irq_reg_stride) - d->irq_reg_stride = chip->irq_reg_stride; - else - d->irq_reg_stride = 1; - mutex_init(&d->lock); for (i = 0; i < chip->num_irqs; i++) - d->mask_buf_def[chip->irqs[i].reg_offset / map->reg_stride] + d->mask_buf_def[chip->irqs[i].reg_offset] |= chip->irqs[i].mask; /* Mask all the interrupts by default */ for (i = 0; i < chip->num_regs; i++) { d->mask_buf[i] = d->mask_buf_def[i]; - ret = regmap_write(map, chip->mask_base + (i * map->reg_stride - * d->irq_reg_stride), - d->mask_buf[i]); + ret = regmap_write(map, chip->mask_base + i, d->mask_buf[i]); if (ret != 0) { dev_err(map->dev, "Failed to set masks in 0x%x: %d\n", - chip->mask_base + (i * map->reg_stride), ret); + chip->mask_base + i, ret); goto err_alloc; } } - if (irq_base) - d->domain = irq_domain_add_legacy(map->dev->of_node, - chip->num_irqs, irq_base, 0, - ®map_domain_ops, d); - else - d->domain = irq_domain_add_linear(map->dev->of_node, - chip->num_irqs, - ®map_domain_ops, d); - if (!d->domain) { - dev_err(map->dev, "Failed to create IRQ domain\n"); - ret = -ENOMEM; - goto err_alloc; + /* Register them with genirq */ + for (cur_irq = irq_base; + cur_irq < chip->num_irqs + irq_base; + cur_irq++) { + irq_set_chip_data(cur_irq, d); + irq_set_chip_and_handler(cur_irq, ®map_irq_chip, + handle_edge_irq); + irq_set_nested_thread(cur_irq, 1); + + /* ARM needs us to explicitly flag the IRQ as valid + * and will set them noprobe when we do so. */ +#ifdef CONFIG_ARM + set_irq_flags(cur_irq, IRQF_VALID); +#else + irq_set_noprobe(cur_irq); +#endif } ret = request_threaded_irq(irq, NULL, regmap_irq_thread, irq_flags, chip->name, d); if (ret != 0) { dev_err(map->dev, "Failed to request IRQ %d: %d\n", irq, ret); - goto err_domain; + goto err_alloc; } return 0; -err_domain: - /* Should really dispose of the domain but... */ err_alloc: kfree(d->mask_buf_def); kfree(d->mask_buf); + kfree(d->status_reg_buf); kfree(d->status_buf); kfree(d); return ret; @@ -314,9 +281,9 @@ void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d) return; free_irq(irq, d); - /* We should unmap the domain but... */ kfree(d->mask_buf_def); kfree(d->mask_buf); + kfree(d->status_reg_buf); kfree(d->status_buf); kfree(d); } @@ -331,21 +298,6 @@ EXPORT_SYMBOL_GPL(regmap_del_irq_chip); */ int regmap_irq_chip_get_base(struct regmap_irq_chip_data *data) { - WARN_ON(!data->irq_base); return data->irq_base; } EXPORT_SYMBOL_GPL(regmap_irq_chip_get_base); - -/** - * regmap_irq_get_virq(): Map an interrupt on a chip to a virtual IRQ - * - * Useful for drivers to request their own IRQs. - * - * @data: regmap_irq controller to operate on. - * @irq: index of the interrupt requested in the chip IRQs - */ -int regmap_irq_get_virq(struct regmap_irq_chip_data *data, int irq) -{ - return irq_create_mapping(data->domain, irq); -} -EXPORT_SYMBOL_GPL(regmap_irq_get_virq); diff --git a/trunk/drivers/base/regmap/regmap-mmio.c b/trunk/drivers/base/regmap/regmap-mmio.c deleted file mode 100644 index febd6de6c8ac..000000000000 --- a/trunk/drivers/base/regmap/regmap-mmio.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Register map access API - MMIO support - * - * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -struct regmap_mmio_context { - void __iomem *regs; - unsigned val_bytes; -}; - -static int regmap_mmio_gather_write(void *context, - const void *reg, size_t reg_size, - const void *val, size_t val_size) -{ - struct regmap_mmio_context *ctx = context; - u32 offset; - - BUG_ON(reg_size != 4); - - offset = be32_to_cpup(reg); - - while (val_size) { - switch (ctx->val_bytes) { - case 1: - writeb(*(u8 *)val, ctx->regs + offset); - break; - case 2: - writew(be16_to_cpup(val), ctx->regs + offset); - break; - case 4: - writel(be32_to_cpup(val), ctx->regs + offset); - break; -#ifdef CONFIG_64BIT - case 8: - writeq(be64_to_cpup(val), ctx->regs + offset); - break; -#endif - default: - /* Should be caught by regmap_mmio_check_config */ - BUG(); - } - val_size -= ctx->val_bytes; - val += ctx->val_bytes; - offset += ctx->val_bytes; - } - - return 0; -} - -static int regmap_mmio_write(void *context, const void *data, size_t count) -{ - BUG_ON(count < 4); - - return regmap_mmio_gather_write(context, data, 4, data + 4, count - 4); -} - -static int regmap_mmio_read(void *context, - const void *reg, size_t reg_size, - void *val, size_t val_size) -{ - struct regmap_mmio_context *ctx = context; - u32 offset; - - BUG_ON(reg_size != 4); - - offset = be32_to_cpup(reg); - - while (val_size) { - switch (ctx->val_bytes) { - case 1: - *(u8 *)val = readb(ctx->regs + offset); - break; - case 2: - *(u16 *)val = cpu_to_be16(readw(ctx->regs + offset)); - break; - case 4: - *(u32 *)val = cpu_to_be32(readl(ctx->regs + offset)); - break; -#ifdef CONFIG_64BIT - case 8: - *(u64 *)val = cpu_to_be32(readq(ctx->regs + offset)); - break; -#endif - default: - /* Should be caught by regmap_mmio_check_config */ - BUG(); - } - val_size -= ctx->val_bytes; - val += ctx->val_bytes; - offset += ctx->val_bytes; - } - - return 0; -} - -static void regmap_mmio_free_context(void *context) -{ - kfree(context); -} - -static struct regmap_bus regmap_mmio = { - .fast_io = true, - .write = regmap_mmio_write, - .gather_write = regmap_mmio_gather_write, - .read = regmap_mmio_read, - .free_context = regmap_mmio_free_context, -}; - -struct regmap_mmio_context *regmap_mmio_gen_context(void __iomem *regs, - const struct regmap_config *config) -{ - struct regmap_mmio_context *ctx; - int min_stride; - - if (config->reg_bits != 32) - return ERR_PTR(-EINVAL); - - if (config->pad_bits) - return ERR_PTR(-EINVAL); - - switch (config->val_bits) { - case 8: - /* The core treats 0 as 1 */ - min_stride = 0; - break; - case 16: - min_stride = 2; - break; - case 32: - min_stride = 4; - break; -#ifdef CONFIG_64BIT - case 64: - min_stride = 8; - break; -#endif - break; - default: - return ERR_PTR(-EINVAL); - } - - if (config->reg_stride < min_stride) - return ERR_PTR(-EINVAL); - - ctx = kzalloc(GFP_KERNEL, sizeof(*ctx)); - if (!ctx) - return ERR_PTR(-ENOMEM); - - ctx->regs = regs; - ctx->val_bytes = config->val_bits / 8; - - return ctx; -} - -/** - * regmap_init_mmio(): Initialise register map - * - * @dev: Device that will be interacted with - * @regs: Pointer to memory-mapped IO region - * @config: Configuration for register map - * - * The return value will be an ERR_PTR() on error or a valid pointer to - * a struct regmap. - */ -struct regmap *regmap_init_mmio(struct device *dev, - void __iomem *regs, - const struct regmap_config *config) -{ - struct regmap_mmio_context *ctx; - - ctx = regmap_mmio_gen_context(regs, config); - if (IS_ERR(ctx)) - return ERR_CAST(ctx); - - return regmap_init(dev, ®map_mmio, ctx, config); -} -EXPORT_SYMBOL_GPL(regmap_init_mmio); - -/** - * devm_regmap_init_mmio(): Initialise managed register map - * - * @dev: Device that will be interacted with - * @regs: Pointer to memory-mapped IO region - * @config: Configuration for register map - * - * The return value will be an ERR_PTR() on error or a valid pointer - * to a struct regmap. The regmap will be automatically freed by the - * device management code. - */ -struct regmap *devm_regmap_init_mmio(struct device *dev, - void __iomem *regs, - const struct regmap_config *config) -{ - struct regmap_mmio_context *ctx; - - ctx = regmap_mmio_gen_context(regs, config); - if (IS_ERR(ctx)) - return ERR_CAST(ctx); - - return devm_regmap_init(dev, ®map_mmio, ctx, config); -} -EXPORT_SYMBOL_GPL(devm_regmap_init_mmio); - -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/base/regmap/regmap-spi.c b/trunk/drivers/base/regmap/regmap-spi.c index ffa46a92ad33..7c0c35a39c33 100644 --- a/trunk/drivers/base/regmap/regmap-spi.c +++ b/trunk/drivers/base/regmap/regmap-spi.c @@ -15,19 +15,17 @@ #include #include -static int regmap_spi_write(void *context, const void *data, size_t count) +static int regmap_spi_write(struct device *dev, const void *data, size_t count) { - struct device *dev = context; struct spi_device *spi = to_spi_device(dev); return spi_write(spi, data, count); } -static int regmap_spi_gather_write(void *context, +static int regmap_spi_gather_write(struct device *dev, const void *reg, size_t reg_len, const void *val, size_t val_len) { - struct device *dev = context; struct spi_device *spi = to_spi_device(dev); struct spi_message m; struct spi_transfer t[2] = { { .tx_buf = reg, .len = reg_len, }, @@ -40,11 +38,10 @@ static int regmap_spi_gather_write(void *context, return spi_sync(spi, &m); } -static int regmap_spi_read(void *context, +static int regmap_spi_read(struct device *dev, const void *reg, size_t reg_size, void *val, size_t val_size) { - struct device *dev = context; struct spi_device *spi = to_spi_device(dev); return spi_write_then_read(spi, reg, reg_size, val, val_size); @@ -69,7 +66,7 @@ static struct regmap_bus regmap_spi = { struct regmap *regmap_init_spi(struct spi_device *spi, const struct regmap_config *config) { - return regmap_init(&spi->dev, ®map_spi, &spi->dev, config); + return regmap_init(&spi->dev, ®map_spi, config); } EXPORT_SYMBOL_GPL(regmap_init_spi); @@ -86,7 +83,7 @@ EXPORT_SYMBOL_GPL(regmap_init_spi); struct regmap *devm_regmap_init_spi(struct spi_device *spi, const struct regmap_config *config) { - return devm_regmap_init(&spi->dev, ®map_spi, &spi->dev, config); + return devm_regmap_init(&spi->dev, ®map_spi, config); } EXPORT_SYMBOL_GPL(devm_regmap_init_spi); diff --git a/trunk/drivers/base/regmap/regmap.c b/trunk/drivers/base/regmap/regmap.c index 0bcda488f11c..7a3f535e481c 100644 --- a/trunk/drivers/base/regmap/regmap.c +++ b/trunk/drivers/base/regmap/regmap.c @@ -112,36 +112,25 @@ static void regmap_format_10_14_write(struct regmap *map, out[0] = reg >> 2; } -static void regmap_format_8(void *buf, unsigned int val, unsigned int shift) +static void regmap_format_8(void *buf, unsigned int val) { u8 *b = buf; - b[0] = val << shift; + b[0] = val; } -static void regmap_format_16(void *buf, unsigned int val, unsigned int shift) +static void regmap_format_16(void *buf, unsigned int val) { __be16 *b = buf; - b[0] = cpu_to_be16(val << shift); + b[0] = cpu_to_be16(val); } -static void regmap_format_24(void *buf, unsigned int val, unsigned int shift) -{ - u8 *b = buf; - - val <<= shift; - - b[0] = val >> 16; - b[1] = val >> 8; - b[2] = val; -} - -static void regmap_format_32(void *buf, unsigned int val, unsigned int shift) +static void regmap_format_32(void *buf, unsigned int val) { __be32 *b = buf; - b[0] = cpu_to_be32(val << shift); + b[0] = cpu_to_be32(val); } static unsigned int regmap_parse_8(void *buf) @@ -160,16 +149,6 @@ static unsigned int regmap_parse_16(void *buf) return b[0]; } -static unsigned int regmap_parse_24(void *buf) -{ - u8 *b = buf; - unsigned int ret = b[2]; - ret |= ((unsigned int)b[1]) << 8; - ret |= ((unsigned int)b[0]) << 16; - - return ret; -} - static unsigned int regmap_parse_32(void *buf) { __be32 *b = buf; @@ -179,41 +158,11 @@ static unsigned int regmap_parse_32(void *buf) return b[0]; } -static void regmap_lock_mutex(struct regmap *map) -{ - mutex_lock(&map->mutex); -} - -static void regmap_unlock_mutex(struct regmap *map) -{ - mutex_unlock(&map->mutex); -} - -static void regmap_lock_spinlock(struct regmap *map) -{ - spin_lock(&map->spinlock); -} - -static void regmap_unlock_spinlock(struct regmap *map) -{ - spin_unlock(&map->spinlock); -} - -static void dev_get_regmap_release(struct device *dev, void *res) -{ - /* - * We don't actually have anything to do here; the goal here - * is not to manage the regmap but to provide a simple way to - * get the regmap back given a struct device. - */ -} - /** * regmap_init(): Initialise register map * * @dev: Device that will be interacted with * @bus: Bus-specific callbacks to use with device - * @bus_context: Data passed to bus-specific callbacks * @config: Configuration for register map * * The return value will be an ERR_PTR() on error or a valid pointer to @@ -222,10 +171,9 @@ static void dev_get_regmap_release(struct device *dev, void *res) */ struct regmap *regmap_init(struct device *dev, const struct regmap_bus *bus, - void *bus_context, const struct regmap_config *config) { - struct regmap *map, **m; + struct regmap *map; int ret = -EINVAL; if (!bus || !config) @@ -237,36 +185,20 @@ struct regmap *regmap_init(struct device *dev, goto err; } - if (bus->fast_io) { - spin_lock_init(&map->spinlock); - map->lock = regmap_lock_spinlock; - map->unlock = regmap_unlock_spinlock; - } else { - mutex_init(&map->mutex); - map->lock = regmap_lock_mutex; - map->unlock = regmap_unlock_mutex; - } + mutex_init(&map->lock); map->format.buf_size = (config->reg_bits + config->val_bits) / 8; map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8); map->format.pad_bytes = config->pad_bits / 8; map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8); map->format.buf_size += map->format.pad_bytes; - map->reg_shift = config->pad_bits % 8; - if (config->reg_stride) - map->reg_stride = config->reg_stride; - else - map->reg_stride = 1; - map->use_single_rw = config->use_single_rw; map->dev = dev; map->bus = bus; - map->bus_context = bus_context; map->max_register = config->max_register; map->writeable_reg = config->writeable_reg; map->readable_reg = config->readable_reg; map->volatile_reg = config->volatile_reg; map->precious_reg = config->precious_reg; map->cache_type = config->cache_type; - map->name = config->name; if (config->read_flag_mask || config->write_flag_mask) { map->read_flag_mask = config->read_flag_mask; @@ -275,7 +207,7 @@ struct regmap *regmap_init(struct device *dev, map->read_flag_mask = bus->read_flag_mask; } - switch (config->reg_bits + map->reg_shift) { + switch (config->reg_bits) { case 2: switch (config->val_bits) { case 6: @@ -341,19 +273,12 @@ struct regmap *regmap_init(struct device *dev, map->format.format_val = regmap_format_16; map->format.parse_val = regmap_parse_16; break; - case 24: - map->format.format_val = regmap_format_24; - map->format.parse_val = regmap_parse_24; - break; case 32: map->format.format_val = regmap_format_32; map->format.parse_val = regmap_parse_32; break; } - if (map->format.format_write) - map->use_single_rw = true; - if (!map->format.format_write && !(map->format.format_reg && map->format.format_val)) goto err_map; @@ -364,25 +289,14 @@ struct regmap *regmap_init(struct device *dev, goto err_map; } - regmap_debugfs_init(map, config->name); + regmap_debugfs_init(map); ret = regcache_init(map, config); if (ret < 0) goto err_free_workbuf; - /* Add a devres resource for dev_get_regmap() */ - m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL); - if (!m) { - ret = -ENOMEM; - goto err_cache; - } - *m = map; - devres_add(dev, m); - return map; -err_cache: - regcache_exit(map); err_free_workbuf: kfree(map->work_buf); err_map: @@ -402,7 +316,6 @@ static void devm_regmap_release(struct device *dev, void *res) * * @dev: Device that will be interacted with * @bus: Bus-specific callbacks to use with device - * @bus_context: Data passed to bus-specific callbacks * @config: Configuration for register map * * The return value will be an ERR_PTR() on error or a valid pointer @@ -412,7 +325,6 @@ static void devm_regmap_release(struct device *dev, void *res) */ struct regmap *devm_regmap_init(struct device *dev, const struct regmap_bus *bus, - void *bus_context, const struct regmap_config *config) { struct regmap **ptr, *regmap; @@ -421,7 +333,7 @@ struct regmap *devm_regmap_init(struct device *dev, if (!ptr) return ERR_PTR(-ENOMEM); - regmap = regmap_init(dev, bus, bus_context, config); + regmap = regmap_init(dev, bus, config); if (!IS_ERR(regmap)) { *ptr = regmap; devres_add(dev, ptr); @@ -448,7 +360,7 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config) { int ret; - map->lock(map); + mutex_lock(&map->lock); regcache_exit(map); regmap_debugfs_exit(map); @@ -460,14 +372,14 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config) map->precious_reg = config->precious_reg; map->cache_type = config->cache_type; - regmap_debugfs_init(map, config->name); + regmap_debugfs_init(map); map->cache_bypass = false; map->cache_only = false; ret = regcache_init(map, config); - map->unlock(map); + mutex_unlock(&map->lock); return ret; } @@ -479,51 +391,11 @@ void regmap_exit(struct regmap *map) { regcache_exit(map); regmap_debugfs_exit(map); - if (map->bus->free_context) - map->bus->free_context(map->bus_context); kfree(map->work_buf); kfree(map); } EXPORT_SYMBOL_GPL(regmap_exit); -static int dev_get_regmap_match(struct device *dev, void *res, void *data) -{ - struct regmap **r = res; - if (!r || !*r) { - WARN_ON(!r || !*r); - return 0; - } - - /* If the user didn't specify a name match any */ - if (data) - return (*r)->name == data; - else - return 1; -} - -/** - * dev_get_regmap(): Obtain the regmap (if any) for a device - * - * @dev: Device to retrieve the map for - * @name: Optional name for the register map, usually NULL. - * - * Returns the regmap for the device if one is present, or NULL. If - * name is specified then it must match the name specified when - * registering the device, if it is NULL then the first regmap found - * will be used. Devices with multiple register maps are very rare, - * generic code should normally not need to specify a name. - */ -struct regmap *dev_get_regmap(struct device *dev, const char *name) -{ - struct regmap **r = devres_find(dev, dev_get_regmap_release, - dev_get_regmap_match, (void *)name); - - if (!r) - return NULL; - return *r; -} -EXPORT_SYMBOL_GPL(dev_get_regmap); - static int _regmap_raw_write(struct regmap *map, unsigned int reg, const void *val, size_t val_len) { @@ -536,8 +408,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, /* Check for unwritable registers before we start */ if (map->writeable_reg) for (i = 0; i < val_len / map->format.val_bytes; i++) - if (!map->writeable_reg(map->dev, - reg + (i * map->reg_stride))) + if (!map->writeable_reg(map->dev, reg + i)) return -EINVAL; if (!map->cache_bypass && map->format.parse_val) { @@ -546,8 +417,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, for (i = 0; i < val_len / val_bytes; i++) { memcpy(map->work_buf, val + (i * val_bytes), val_bytes); ival = map->format.parse_val(map->work_buf); - ret = regcache_write(map, reg + (i * map->reg_stride), - ival); + ret = regcache_write(map, reg + i, ival); if (ret) { dev_err(map->dev, "Error in caching of register: %u ret: %d\n", @@ -561,7 +431,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, } } - map->format.format_reg(map->work_buf, reg, map->reg_shift); + map->format.format_reg(map->work_buf, reg); u8[0] |= map->write_flag_mask; @@ -574,12 +444,12 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, */ if (val == (map->work_buf + map->format.pad_bytes + map->format.reg_bytes)) - ret = map->bus->write(map->bus_context, map->work_buf, + ret = map->bus->write(map->dev, map->work_buf, map->format.reg_bytes + map->format.pad_bytes + val_len); else if (map->bus->gather_write) - ret = map->bus->gather_write(map->bus_context, map->work_buf, + ret = map->bus->gather_write(map->dev, map->work_buf, map->format.reg_bytes + map->format.pad_bytes, val, val_len); @@ -594,7 +464,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, memcpy(buf, map->work_buf, map->format.reg_bytes); memcpy(buf + map->format.reg_bytes + map->format.pad_bytes, val, val_len); - ret = map->bus->write(map->bus_context, buf, len); + ret = map->bus->write(map->dev, buf, len); kfree(buf); } @@ -628,7 +498,7 @@ int _regmap_write(struct regmap *map, unsigned int reg, trace_regmap_hw_write_start(map->dev, reg, 1); - ret = map->bus->write(map->bus_context, map->work_buf, + ret = map->bus->write(map->dev, map->work_buf, map->format.buf_size); trace_regmap_hw_write_done(map->dev, reg, 1); @@ -636,7 +506,7 @@ int _regmap_write(struct regmap *map, unsigned int reg, return ret; } else { map->format.format_val(map->work_buf + map->format.reg_bytes - + map->format.pad_bytes, val, 0); + + map->format.pad_bytes, val); return _regmap_raw_write(map, reg, map->work_buf + map->format.reg_bytes + @@ -659,14 +529,11 @@ int regmap_write(struct regmap *map, unsigned int reg, unsigned int val) { int ret; - if (reg % map->reg_stride) - return -EINVAL; - - map->lock(map); + mutex_lock(&map->lock); ret = _regmap_write(map, reg, val); - map->unlock(map); + mutex_unlock(&map->lock); return ret; } @@ -693,16 +560,11 @@ int regmap_raw_write(struct regmap *map, unsigned int reg, { int ret; - if (val_len % map->format.val_bytes) - return -EINVAL; - if (reg % map->reg_stride) - return -EINVAL; - - map->lock(map); + mutex_lock(&map->lock); ret = _regmap_raw_write(map, reg, val, val_len); - map->unlock(map); + mutex_unlock(&map->lock); return ret; } @@ -731,10 +593,8 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, if (!map->format.parse_val) return -EINVAL; - if (reg % map->reg_stride) - return -EINVAL; - map->lock(map); + mutex_lock(&map->lock); /* No formatting is require if val_byte is 1 */ if (val_bytes == 1) { @@ -749,28 +609,13 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, for (i = 0; i < val_count * val_bytes; i += val_bytes) map->format.parse_val(wval + i); } - /* - * Some devices does not support bulk write, for - * them we have a series of single write operations. - */ - if (map->use_single_rw) { - for (i = 0; i < val_count; i++) { - ret = regmap_raw_write(map, - reg + (i * map->reg_stride), - val + (i * val_bytes), - val_bytes); - if (ret != 0) - return ret; - } - } else { - ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count); - } + ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count); if (val_bytes != 1) kfree(wval); out: - map->unlock(map); + mutex_unlock(&map->lock); return ret; } EXPORT_SYMBOL_GPL(regmap_bulk_write); @@ -781,7 +626,7 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, u8 *u8 = map->work_buf; int ret; - map->format.format_reg(map->work_buf, reg, map->reg_shift); + map->format.format_reg(map->work_buf, reg); /* * Some buses or devices flag reads by setting the high bits in the @@ -794,7 +639,7 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, trace_regmap_hw_read_start(map->dev, reg, val_len / map->format.val_bytes); - ret = map->bus->read(map->bus_context, map->work_buf, + ret = map->bus->read(map->dev, map->work_buf, map->format.reg_bytes + map->format.pad_bytes, val, val_len); @@ -827,9 +672,6 @@ static int _regmap_read(struct regmap *map, unsigned int reg, trace_regmap_reg_read(map->dev, reg, *val); } - if (ret == 0 && !map->cache_bypass) - regcache_write(map, reg, *val); - return ret; } @@ -847,14 +689,11 @@ int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val) { int ret; - if (reg % map->reg_stride) - return -EINVAL; - - map->lock(map); + mutex_lock(&map->lock); ret = _regmap_read(map, reg, val); - map->unlock(map); + mutex_unlock(&map->lock); return ret; } @@ -879,12 +718,7 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val, unsigned int v; int ret, i; - if (val_len % map->format.val_bytes) - return -EINVAL; - if (reg % map->reg_stride) - return -EINVAL; - - map->lock(map); + mutex_lock(&map->lock); if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass || map->cache_type == REGCACHE_NONE) { @@ -896,17 +730,16 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val, * cost as we expect to hit the cache. */ for (i = 0; i < val_count; i++) { - ret = _regmap_read(map, reg + (i * map->reg_stride), - &v); + ret = _regmap_read(map, reg + i, &v); if (ret != 0) goto out; - map->format.format_val(val + (i * val_bytes), v, 0); + map->format.format_val(val + (i * val_bytes), v); } } out: - map->unlock(map); + mutex_unlock(&map->lock); return ret; } @@ -932,40 +765,19 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val, if (!map->format.parse_val) return -EINVAL; - if (reg % map->reg_stride) - return -EINVAL; if (vol || map->cache_type == REGCACHE_NONE) { - /* - * Some devices does not support bulk read, for - * them we have a series of single read operations. - */ - if (map->use_single_rw) { - for (i = 0; i < val_count; i++) { - ret = regmap_raw_read(map, - reg + (i * map->reg_stride), - val + (i * val_bytes), - val_bytes); - if (ret != 0) - return ret; - } - } else { - ret = regmap_raw_read(map, reg, val, - val_bytes * val_count); - if (ret != 0) - return ret; - } + ret = regmap_raw_read(map, reg, val, val_bytes * val_count); + if (ret != 0) + return ret; for (i = 0; i < val_count * val_bytes; i += val_bytes) map->format.parse_val(val + i); } else { for (i = 0; i < val_count; i++) { - unsigned int ival; - ret = regmap_read(map, reg + (i * map->reg_stride), - &ival); + ret = regmap_read(map, reg + i, val + (i * val_bytes)); if (ret != 0) return ret; - memcpy(val + (i * val_bytes), &ival, val_bytes); } } @@ -980,7 +792,7 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg, int ret; unsigned int tmp, orig; - map->lock(map); + mutex_lock(&map->lock); ret = _regmap_read(map, reg, &orig); if (ret != 0) @@ -997,7 +809,7 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg, } out: - map->unlock(map); + mutex_unlock(&map->lock); return ret; } @@ -1064,7 +876,7 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs, if (map->patch) return -EBUSY; - map->lock(map); + mutex_lock(&map->lock); bypass = map->cache_bypass; @@ -1092,7 +904,7 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs, out: map->cache_bypass = bypass; - map->unlock(map); + mutex_unlock(&map->lock); return ret; } diff --git a/trunk/drivers/block/DAC960.c b/trunk/drivers/block/DAC960.c index 9a13e889837e..8db9089127c5 100644 --- a/trunk/drivers/block/DAC960.c +++ b/trunk/drivers/block/DAC960.c @@ -6580,21 +6580,24 @@ static const struct file_operations dac960_user_command_proc_fops = { static void DAC960_CreateProcEntries(DAC960_Controller_T *Controller) { + struct proc_dir_entry *StatusProcEntry; struct proc_dir_entry *ControllerProcEntry; + struct proc_dir_entry *UserCommandProcEntry; if (DAC960_ProcDirectoryEntry == NULL) { - DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL); - proc_create("status", 0, DAC960_ProcDirectoryEntry, - &dac960_proc_fops); + DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL); + StatusProcEntry = proc_create("status", 0, + DAC960_ProcDirectoryEntry, + &dac960_proc_fops); } - sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber); - ControllerProcEntry = proc_mkdir(Controller->ControllerName, - DAC960_ProcDirectoryEntry); - proc_create_data("initial_status", 0, ControllerProcEntry, &dac960_initial_status_proc_fops, Controller); - proc_create_data("current_status", 0, ControllerProcEntry, &dac960_current_status_proc_fops, Controller); - proc_create_data("user_command", S_IWUSR | S_IRUSR, ControllerProcEntry, &dac960_user_command_proc_fops, Controller); - Controller->ControllerProcEntry = ControllerProcEntry; + sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber); + ControllerProcEntry = proc_mkdir(Controller->ControllerName, + DAC960_ProcDirectoryEntry); + proc_create_data("initial_status", 0, ControllerProcEntry, &dac960_initial_status_proc_fops, Controller); + proc_create_data("current_status", 0, ControllerProcEntry, &dac960_current_status_proc_fops, Controller); + UserCommandProcEntry = proc_create_data("user_command", S_IWUSR | S_IRUSR, ControllerProcEntry, &dac960_user_command_proc_fops, Controller); + Controller->ControllerProcEntry = ControllerProcEntry; } diff --git a/trunk/drivers/block/drbd/drbd_nl.c b/trunk/drivers/block/drbd/drbd_nl.c index 946166e13953..abfaacaaf346 100644 --- a/trunk/drivers/block/drbd/drbd_nl.c +++ b/trunk/drivers/block/drbd/drbd_nl.c @@ -2297,7 +2297,7 @@ static void drbd_connector_callback(struct cn_msg *req, struct netlink_skb_parms return; } - if (!capable(CAP_SYS_ADMIN)) { + if (!cap_raised(current_cap(), CAP_SYS_ADMIN)) { retcode = ERR_PERM; goto fail; } diff --git a/trunk/drivers/block/mtip32xx/mtip32xx.c b/trunk/drivers/block/mtip32xx/mtip32xx.c index 304000c3d433..00f9fc992090 100644 --- a/trunk/drivers/block/mtip32xx/mtip32xx.c +++ b/trunk/drivers/block/mtip32xx/mtip32xx.c @@ -2510,10 +2510,8 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, up(&dd->port->cmd_slot); return NULL; } - if (unlikely(*tag < 0)) { - up(&dd->port->cmd_slot); + if (unlikely(*tag < 0)) return NULL; - } return dd->port->commands[*tag].sg; } diff --git a/trunk/drivers/block/virtio_blk.c b/trunk/drivers/block/virtio_blk.c index 693187df7601..0d39f2f4294a 100644 --- a/trunk/drivers/block/virtio_blk.c +++ b/trunk/drivers/block/virtio_blk.c @@ -29,6 +29,9 @@ struct virtio_blk /* The disk structure for the kernel. */ struct gendisk *disk; + /* Request tracking. */ + struct list_head reqs; + mempool_t *pool; /* Process context for config space updates */ @@ -52,6 +55,7 @@ struct virtio_blk struct virtblk_req { + struct list_head list; struct request *req; struct virtio_blk_outhdr out_hdr; struct virtio_scsi_inhdr in_hdr; @@ -95,6 +99,7 @@ static void blk_done(struct virtqueue *vq) } __blk_end_request_all(vbr->req, error); + list_del(&vbr->list); mempool_free(vbr, vblk->pool); } /* In case queue is stopped waiting for more buffers. */ @@ -179,6 +184,7 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, return false; } + list_add_tail(&vbr->list, &vblk->reqs); return true; } @@ -431,6 +437,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) goto out_free_index; } + INIT_LIST_HEAD(&vblk->reqs); spin_lock_init(&vblk->lock); vblk->vdev = vdev; vblk->sg_elems = sg_elems; @@ -576,29 +583,21 @@ static void __devexit virtblk_remove(struct virtio_device *vdev) { struct virtio_blk *vblk = vdev->priv; int index = vblk->index; - struct virtblk_req *vbr; - unsigned long flags; /* Prevent config work handler from accessing the device. */ mutex_lock(&vblk->config_lock); vblk->config_enable = false; mutex_unlock(&vblk->config_lock); + /* Nothing should be pending. */ + BUG_ON(!list_empty(&vblk->reqs)); + /* Stop all the virtqueues. */ vdev->config->reset(vdev); flush_work(&vblk->config_work); del_gendisk(vblk->disk); - - /* Abort requests dispatched to driver. */ - spin_lock_irqsave(&vblk->lock, flags); - while ((vbr = virtqueue_detach_unused_buf(vblk->vq))) { - __blk_end_request_all(vbr->req, -EIO); - mempool_free(vbr, vblk->pool); - } - spin_unlock_irqrestore(&vblk->lock, flags); - blk_cleanup_queue(vblk->disk->queue); put_disk(vblk->disk); mempool_destroy(vblk->pool); diff --git a/trunk/drivers/char/virtio_console.c b/trunk/drivers/char/virtio_console.c index cdf2f5451c76..ddf86b6500b7 100644 --- a/trunk/drivers/char/virtio_console.c +++ b/trunk/drivers/char/virtio_console.c @@ -1895,13 +1895,6 @@ static int virtcons_restore(struct virtio_device *vdev) /* Get port open/close status on the host */ send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1); - - /* - * If a port was open at the time of suspending, we - * have to let the host know that it's still open. - */ - if (port->guest_connected) - send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 1); } return 0; } diff --git a/trunk/drivers/clk/clkdev.c b/trunk/drivers/clk/clkdev.c index c535cf8c5770..6db161f64ae0 100644 --- a/trunk/drivers/clk/clkdev.c +++ b/trunk/drivers/clk/clkdev.c @@ -35,12 +35,7 @@ static DEFINE_MUTEX(clocks_mutex); static struct clk_lookup *clk_find(const char *dev_id, const char *con_id) { struct clk_lookup *p, *cl = NULL; - int match, best_found = 0, best_possible = 0; - - if (dev_id) - best_possible += 2; - if (con_id) - best_possible += 1; + int match, best = 0; list_for_each_entry(p, &clocks, node) { match = 0; @@ -55,10 +50,10 @@ static struct clk_lookup *clk_find(const char *dev_id, const char *con_id) match += 1; } - if (match > best_found) { + if (match > best) { cl = p; - if (match != best_possible) - best_found = match; + if (match != 3) + best = match; else break; } @@ -94,51 +89,6 @@ void clk_put(struct clk *clk) } EXPORT_SYMBOL(clk_put); -static void devm_clk_release(struct device *dev, void *res) -{ - clk_put(*(struct clk **)res); -} - -struct clk *devm_clk_get(struct device *dev, const char *id) -{ - struct clk **ptr, *clk; - - ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return ERR_PTR(-ENOMEM); - - clk = clk_get(dev, id); - if (!IS_ERR(clk)) { - *ptr = clk; - devres_add(dev, ptr); - } else { - devres_free(ptr); - } - - return clk; -} -EXPORT_SYMBOL(devm_clk_get); - -static int devm_clk_match(struct device *dev, void *res, void *data) -{ - struct clk **c = res; - if (!c || !*c) { - WARN_ON(!c || !*c); - return 0; - } - return *c == data; -} - -void devm_clk_put(struct device *dev, struct clk *clk) -{ - int ret; - - ret = devres_destroy(dev, devm_clk_release, devm_clk_match, clk); - - WARN_ON(ret); -} -EXPORT_SYMBOL(devm_clk_put); - void clkdev_add(struct clk_lookup *cl) { mutex_lock(&clocks_mutex); @@ -166,9 +116,8 @@ struct clk_lookup_alloc { char con_id[MAX_CON_ID]; }; -static struct clk_lookup * __init_refok -vclkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, - va_list ap) +struct clk_lookup * __init_refok +clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...) { struct clk_lookup_alloc *cla; @@ -183,25 +132,16 @@ vclkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, } if (dev_fmt) { + va_list ap; + + va_start(ap, dev_fmt); vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap); cla->cl.dev_id = cla->dev_id; + va_end(ap); } return &cla->cl; } - -struct clk_lookup * __init_refok -clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...) -{ - struct clk_lookup *cl; - va_list ap; - - va_start(ap, dev_fmt); - cl = vclkdev_alloc(clk, con_id, dev_fmt, ap); - va_end(ap); - - return cl; -} EXPORT_SYMBOL(clkdev_alloc); int clk_add_alias(const char *alias, const char *alias_dev_name, char *id, @@ -233,65 +173,3 @@ void clkdev_drop(struct clk_lookup *cl) kfree(cl); } EXPORT_SYMBOL(clkdev_drop); - -/** - * clk_register_clkdev - register one clock lookup for a struct clk - * @clk: struct clk to associate with all clk_lookups - * @con_id: connection ID string on device - * @dev_id: format string describing device name - * - * con_id or dev_id may be NULL as a wildcard, just as in the rest of - * clkdev. - * - * To make things easier for mass registration, we detect error clks - * from a previous clk_register() call, and return the error code for - * those. This is to permit this function to be called immediately - * after clk_register(). - */ -int clk_register_clkdev(struct clk *clk, const char *con_id, - const char *dev_fmt, ...) -{ - struct clk_lookup *cl; - va_list ap; - - if (IS_ERR(clk)) - return PTR_ERR(clk); - - va_start(ap, dev_fmt); - cl = vclkdev_alloc(clk, con_id, dev_fmt, ap); - va_end(ap); - - if (!cl) - return -ENOMEM; - - clkdev_add(cl); - - return 0; -} - -/** - * clk_register_clkdevs - register a set of clk_lookup for a struct clk - * @clk: struct clk to associate with all clk_lookups - * @cl: array of clk_lookup structures with con_id and dev_id pre-initialized - * @num: number of clk_lookup structures to register - * - * To make things easier for mass registration, we detect error clks - * from a previous clk_register() call, and return the error code for - * those. This is to permit this function to be called immediately - * after clk_register(). - */ -int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num) -{ - unsigned i; - - if (IS_ERR(clk)) - return PTR_ERR(clk); - - for (i = 0; i < num; i++, cl++) { - cl->clk = clk; - clkdev_add(cl); - } - - return 0; -} -EXPORT_SYMBOL(clk_register_clkdevs); diff --git a/trunk/drivers/cpuidle/cpuidle.c b/trunk/drivers/cpuidle/cpuidle.c index d90519cec880..2f0083a51a9a 100644 --- a/trunk/drivers/cpuidle/cpuidle.c +++ b/trunk/drivers/cpuidle/cpuidle.c @@ -40,6 +40,17 @@ void disable_cpuidle(void) off = 1; } +#if defined(CONFIG_ARCH_HAS_CPU_IDLE_WAIT) +static void cpuidle_kick_cpus(void) +{ + cpu_idle_wait(); +} +#elif defined(CONFIG_SMP) +# error "Arch needs cpu_idle_wait() equivalent here" +#else /* !CONFIG_ARCH_HAS_CPU_IDLE_WAIT && !CONFIG_SMP */ +static void cpuidle_kick_cpus(void) {} +#endif + static int __cpuidle_register_device(struct cpuidle_device *dev); static inline int cpuidle_enter(struct cpuidle_device *dev, @@ -175,7 +186,7 @@ void cpuidle_uninstall_idle_handler(void) { if (enabled_devices) { initialized = 0; - kick_all_cpus_sync(); + cpuidle_kick_cpus(); } } diff --git a/trunk/drivers/crypto/Kconfig b/trunk/drivers/crypto/Kconfig index 371f13cc38eb..ab9abb46d01a 100644 --- a/trunk/drivers/crypto/Kconfig +++ b/trunk/drivers/crypto/Kconfig @@ -111,7 +111,6 @@ config CRYPTO_DES_S390 depends on S390 select CRYPTO_ALGAPI select CRYPTO_BLKCIPHER - select CRYPTO_DES help This is the s390 hardware accelerated implementation of the DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3). @@ -165,7 +164,6 @@ config CRYPTO_DEV_MV_CESA select CRYPTO_ALGAPI select CRYPTO_AES select CRYPTO_BLKCIPHER2 - select CRYPTO_HASH help This driver allows you to utilize the Cryptographic Engines and Security Accelerator (CESA) which can be found on the Marvell Orion diff --git a/trunk/drivers/dma/at_hdmac.c b/trunk/drivers/dma/at_hdmac.c index bf0d7e4e345b..445fdf811695 100644 --- a/trunk/drivers/dma/at_hdmac.c +++ b/trunk/drivers/dma/at_hdmac.c @@ -245,9 +245,7 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc) dev_vdbg(chan2dev(&atchan->chan_common), "descriptor %u complete\n", txd->cookie); - /* mark the descriptor as complete for non cyclic cases only */ - if (!atc_chan_is_cyclic(atchan)) - dma_cookie_complete(txd); + dma_cookie_complete(txd); /* move children to free_list */ list_splice_init(&desc->tx_list, &atchan->free_list); diff --git a/trunk/drivers/dma/ep93xx_dma.c b/trunk/drivers/dma/ep93xx_dma.c index f6e9b572b998..e6f133b78dc2 100644 --- a/trunk/drivers/dma/ep93xx_dma.c +++ b/trunk/drivers/dma/ep93xx_dma.c @@ -703,9 +703,7 @@ static void ep93xx_dma_tasklet(unsigned long data) desc = ep93xx_dma_get_active(edmac); if (desc) { if (desc->complete) { - /* mark descriptor complete for non cyclic case only */ - if (!test_bit(EP93XX_DMA_IS_CYCLIC, &edmac->flags)) - dma_cookie_complete(&desc->txd); + dma_cookie_complete(&desc->txd); list_splice_init(&edmac->active, &list); } callback = desc->txd.callback; diff --git a/trunk/drivers/dma/pl330.c b/trunk/drivers/dma/pl330.c index fa3fb21e60be..2ee6e23930ad 100644 --- a/trunk/drivers/dma/pl330.c +++ b/trunk/drivers/dma/pl330.c @@ -2322,8 +2322,7 @@ static void pl330_tasklet(unsigned long data) /* Pick up ripe tomatoes */ list_for_each_entry_safe(desc, _dt, &pch->work_list, node) if (desc->status == DONE) { - if (pch->cyclic) - dma_cookie_complete(&desc->txd); + dma_cookie_complete(&desc->txd); list_move_tail(&desc->node, &list); } diff --git a/trunk/drivers/gpio/gpio-omap.c b/trunk/drivers/gpio/gpio-omap.c index 4461540653a8..1adc2ec1e383 100644 --- a/trunk/drivers/gpio/gpio-omap.c +++ b/trunk/drivers/gpio/gpio-omap.c @@ -965,15 +965,18 @@ static void omap_gpio_mod_init(struct gpio_bank *bank) } _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->irqenable_inv); - _gpio_rmw(base, bank->regs->irqstatus, l, !bank->regs->irqenable_inv); + _gpio_rmw(base, bank->regs->irqstatus, l, + bank->regs->irqenable_inv == false); + _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->debounce_en != 0); + _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->ctrl != 0); if (bank->regs->debounce_en) - __raw_writel(0, base + bank->regs->debounce_en); + _gpio_rmw(base, bank->regs->debounce_en, 0, 1); /* Save OE default value (0xffffffff) in the context */ bank->context.oe = __raw_readl(bank->base + bank->regs->direction); /* Initialize interface clk ungated, module enabled */ if (bank->regs->ctrl) - __raw_writel(0, base + bank->regs->ctrl); + _gpio_rmw(base, bank->regs->ctrl, 0, 1); } static __devinit void diff --git a/trunk/drivers/gpio/gpio-pch.c b/trunk/drivers/gpio/gpio-pch.c index 2cd958e0b822..e8729cc2ba2b 100644 --- a/trunk/drivers/gpio/gpio-pch.c +++ b/trunk/drivers/gpio/gpio-pch.c @@ -230,12 +230,16 @@ static void pch_gpio_setup(struct pch_gpio *chip) static int pch_irq_type(struct irq_data *d, unsigned int type) { - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - struct pch_gpio *chip = gc->private; - u32 im, im_pos, val; + u32 im; u32 __iomem *im_reg; + u32 ien; + u32 im_pos; + int ch; unsigned long flags; - int ch, irq = d->irq; + u32 val; + int irq = d->irq; + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + struct pch_gpio *chip = gc->private; ch = irq - chip->irq_base; if (irq <= chip->irq_base + 7) { @@ -266,22 +270,30 @@ static int pch_irq_type(struct irq_data *d, unsigned int type) case IRQ_TYPE_LEVEL_LOW: val = PCH_LEVEL_L; break; + case IRQ_TYPE_PROBE: + goto end; default: - goto unlock; + dev_warn(chip->dev, "%s: unknown type(%dd)", + __func__, type); + goto end; } /* Set interrupt mode */ im = ioread32(im_reg) & ~(PCH_IM_MASK << (im_pos * 4)); iowrite32(im | (val << (im_pos * 4)), im_reg); - /* And the handler */ - if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) - __irq_set_handler_locked(d->irq, handle_level_irq); - else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) - __irq_set_handler_locked(d->irq, handle_edge_irq); + /* iclr */ + iowrite32(BIT(ch), &chip->reg->iclr); -unlock: + /* IMASKCLR */ + iowrite32(BIT(ch), &chip->reg->imaskclr); + + /* Enable interrupt */ + ien = ioread32(&chip->reg->ien); + iowrite32(ien | BIT(ch), &chip->reg->ien); +end: spin_unlock_irqrestore(&chip->spinlock, flags); + return 0; } @@ -301,24 +313,18 @@ static void pch_irq_mask(struct irq_data *d) iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->imask); } -static void pch_irq_ack(struct irq_data *d) -{ - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - struct pch_gpio *chip = gc->private; - - iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->iclr); -} - static irqreturn_t pch_gpio_handler(int irq, void *dev_id) { struct pch_gpio *chip = dev_id; u32 reg_val = ioread32(&chip->reg->istatus); - int i, ret = IRQ_NONE; + int i; + int ret = IRQ_NONE; for (i = 0; i < gpio_pins[chip->ioh]; i++) { if (reg_val & BIT(i)) { dev_dbg(chip->dev, "%s:[%d]:irq=%d status=0x%x\n", __func__, i, irq, reg_val); + iowrite32(BIT(i), &chip->reg->iclr); generic_handle_irq(chip->irq_base + i); ret = IRQ_HANDLED; } @@ -337,7 +343,6 @@ static __devinit void pch_gpio_alloc_generic_chip(struct pch_gpio *chip, gc->private = chip; ct = gc->chip_types; - ct->chip.irq_ack = pch_irq_ack; ct->chip.irq_mask = pch_irq_mask; ct->chip.irq_unmask = pch_irq_unmask; ct->chip.irq_set_type = pch_irq_type; @@ -352,7 +357,6 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev, s32 ret; struct pch_gpio *chip; int irq_base; - u32 msk; chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) @@ -404,13 +408,8 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev, } chip->irq_base = irq_base; - /* Mask all interrupts, but enable them */ - msk = (1 << gpio_pins[chip->ioh]) - 1; - iowrite32(msk, &chip->reg->imask); - iowrite32(msk, &chip->reg->ien); - ret = request_irq(pdev->irq, pch_gpio_handler, - IRQF_SHARED, KBUILD_MODNAME, chip); + IRQF_SHARED, KBUILD_MODNAME, chip); if (ret != 0) { dev_err(&pdev->dev, "%s request_irq failed\n", __func__); @@ -419,6 +418,8 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev, pch_gpio_alloc_generic_chip(chip, irq_base, gpio_pins[chip->ioh]); + /* Initialize interrupt ien register */ + iowrite32(0, &chip->reg->ien); end: return 0; diff --git a/trunk/drivers/gpio/gpio-samsung.c b/trunk/drivers/gpio/gpio-samsung.c index e991d9171961..19d6fc0229c3 100644 --- a/trunk/drivers/gpio/gpio-samsung.c +++ b/trunk/drivers/gpio/gpio-samsung.c @@ -452,14 +452,12 @@ static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = { }; #endif -#if defined(CONFIG_ARCH_EXYNOS4) || defined(CONFIG_ARCH_EXYNOS5) static struct samsung_gpio_cfg exynos_gpio_cfg = { .set_pull = exynos_gpio_setpull, .get_pull = exynos_gpio_getpull, .set_config = samsung_gpio_setcfg_4bit, .get_config = samsung_gpio_getcfg_4bit, }; -#endif #if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450) static struct samsung_gpio_cfg s5p64x0_gpio_cfg_rbank = { @@ -2125,8 +2123,8 @@ static struct samsung_gpio_chip s5pv210_gpios_4bit[] = { * uses the above macro and depends on the banks being listed in order here. */ -#ifdef CONFIG_ARCH_EXYNOS4 static struct samsung_gpio_chip exynos4_gpios_1[] = { +#ifdef CONFIG_ARCH_EXYNOS4 { .chip = { .base = EXYNOS4_GPA0(0), @@ -2224,11 +2222,11 @@ static struct samsung_gpio_chip exynos4_gpios_1[] = { .label = "GPF3", }, }, -}; #endif +}; -#ifdef CONFIG_ARCH_EXYNOS4 static struct samsung_gpio_chip exynos4_gpios_2[] = { +#ifdef CONFIG_ARCH_EXYNOS4 { .chip = { .base = EXYNOS4_GPJ0(0), @@ -2369,11 +2367,11 @@ static struct samsung_gpio_chip exynos4_gpios_2[] = { .to_irq = samsung_gpiolib_to_irq, }, }, -}; #endif +}; -#ifdef CONFIG_ARCH_EXYNOS4 static struct samsung_gpio_chip exynos4_gpios_3[] = { +#ifdef CONFIG_ARCH_EXYNOS4 { .chip = { .base = EXYNOS4_GPZ(0), @@ -2381,8 +2379,8 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = { .label = "GPZ", }, }, -}; #endif +}; #ifdef CONFIG_ARCH_EXYNOS5 static struct samsung_gpio_chip exynos5_gpios_1[] = { @@ -2721,9 +2719,7 @@ static __init int samsung_gpiolib_init(void) { struct samsung_gpio_chip *chip; int i, nr_chips; -#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS5250) void __iomem *gpio_base1, *gpio_base2, *gpio_base3, *gpio_base4; -#endif int group = 0; samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs)); @@ -2975,7 +2971,6 @@ static __init int samsung_gpiolib_init(void) return 0; -#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS5250) err_ioremap4: iounmap(gpio_base3); err_ioremap3: @@ -2984,7 +2979,6 @@ static __init int samsung_gpiolib_init(void) iounmap(gpio_base1); err_ioremap1: return -ENOMEM; -#endif } core_initcall(samsung_gpiolib_init); diff --git a/trunk/drivers/gpu/drm/i915/i915_debugfs.c b/trunk/drivers/gpu/drm/i915/i915_debugfs.c index e6162a1681f0..b505b70dba05 100644 --- a/trunk/drivers/gpu/drm/i915/i915_debugfs.c +++ b/trunk/drivers/gpu/drm/i915/i915_debugfs.c @@ -1224,9 +1224,6 @@ static int i915_emon_status(struct seq_file *m, void *unused) unsigned long temp, chipset, gfx; int ret; - if (!IS_GEN5(dev)) - return -ENODEV; - ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) return ret; diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index ba60f3c8f911..785f67f963ef 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -1701,9 +1701,6 @@ void i915_update_gfx_val(struct drm_i915_private *dev_priv) unsigned long diffms; u32 count; - if (dev_priv->info->gen != 5) - return; - getrawmonotonic(&now); diff1 = timespec_sub(now, dev_priv->last_time2); @@ -2124,14 +2121,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, (unsigned long) dev); - if (IS_GEN5(dev)) { - spin_lock(&mchdev_lock); - i915_mch_dev = dev_priv; - dev_priv->mchdev_lock = &mchdev_lock; - spin_unlock(&mchdev_lock); + spin_lock(&mchdev_lock); + i915_mch_dev = dev_priv; + dev_priv->mchdev_lock = &mchdev_lock; + spin_unlock(&mchdev_lock); - ips_ping_for_i915_load(); - } + ips_ping_for_i915_load(); return 0; diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index 1b1cf3b3ff51..5908cd563400 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -7072,6 +7072,9 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc) struct drm_device *dev = crtc->dev; drm_i915_private_t *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; + int dpll_reg = DPLL(pipe); + int dpll = I915_READ(dpll_reg); if (HAS_PCH_SPLIT(dev)) return; @@ -7084,15 +7087,10 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc) * the manual case. */ if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) { - int pipe = intel_crtc->pipe; - int dpll_reg = DPLL(pipe); - u32 dpll; - DRM_DEBUG_DRIVER("downclocking LVDS\n"); assert_panel_unlocked(dev_priv, pipe); - dpll = I915_READ(dpll_reg); dpll |= DISPLAY_RATE_SELECT_FPA1; I915_WRITE(dpll_reg, dpll); intel_wait_for_vblank(dev, pipe); @@ -7100,6 +7098,7 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc) if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) DRM_DEBUG_DRIVER("failed to downclock LVDS!\n"); } + } /** diff --git a/trunk/drivers/gpu/drm/i915/intel_hdmi.c b/trunk/drivers/gpu/drm/i915/intel_hdmi.c index 2d7f47b56b6a..cae3e5f17a49 100644 --- a/trunk/drivers/gpu/drm/i915/intel_hdmi.c +++ b/trunk/drivers/gpu/drm/i915/intel_hdmi.c @@ -136,7 +136,7 @@ static void i9xx_write_infoframe(struct drm_encoder *encoder, val &= ~VIDEO_DIP_SELECT_MASK; - I915_WRITE(VIDEO_DIP_CTL, VIDEO_DIP_ENABLE | val | port | flags); + I915_WRITE(VIDEO_DIP_CTL, val | port | flags); for (i = 0; i < len; i += 4) { I915_WRITE(VIDEO_DIP_DATA, *data); diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index 9c71183629c2..30e2c82101de 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -750,7 +750,7 @@ static const struct dmi_system_id intel_no_lvds[] = { .ident = "Hewlett-Packard t5745", .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "hp t5745"), + DMI_MATCH(DMI_BOARD_NAME, "hp t5745"), }, }, { @@ -758,7 +758,7 @@ static const struct dmi_system_id intel_no_lvds[] = { .ident = "Hewlett-Packard st5747", .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "hp st5747"), + DMI_MATCH(DMI_BOARD_NAME, "hp st5747"), }, }, { diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c index 62892a826ede..80fce51e2f43 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -398,8 +398,10 @@ static int init_render_ring(struct intel_ring_buffer *ring) return ret; } + if (INTEL_INFO(dev)->gen >= 6) { + I915_WRITE(INSTPM, + INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING); - if (IS_GEN6(dev)) { /* From the Sandybridge PRM, volume 1 part 3, page 24: * "If this bit is set, STCunit will have LRA as replacement * policy. [...] This bit must be reset. LRA replacement @@ -409,11 +411,6 @@ static int init_render_ring(struct intel_ring_buffer *ring) CM0_STC_EVICT_DISABLE_LRA_SNB << CM0_MASK_SHIFT); } - if (INTEL_INFO(dev)->gen >= 6) { - I915_WRITE(INSTPM, - INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING); - } - return ret; } diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo.c b/trunk/drivers/gpu/drm/i915/intel_sdvo.c index ae5e748f39bb..232d77d07d8b 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo.c +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo.c @@ -1220,14 +1220,8 @@ static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct in static int intel_sdvo_supports_hotplug(struct intel_sdvo *intel_sdvo) { - struct drm_device *dev = intel_sdvo->base.base.dev; u8 response[2]; - /* HW Erratum: SDVO Hotplug is broken on all i945G chips, there's noise - * on the line. */ - if (IS_I945G(dev) || IS_I945GM(dev)) - return false; - return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, &response, 2) && response[0]; } diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_i2c.c b/trunk/drivers/gpu/drm/nouveau/nouveau_i2c.c index 77e564667b5c..e2be95af2e52 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_i2c.c @@ -29,6 +29,10 @@ #include "nouveau_i2c.h" #include "nouveau_hw.h" +#define T_TIMEOUT 2200000 +#define T_RISEFALL 1000 +#define T_HOLD 5000 + static void i2c_drive_scl(void *data, int state) { @@ -109,6 +113,175 @@ i2c_sense_sda(void *data) return 0; } +static void +i2c_delay(struct nouveau_i2c_chan *port, u32 nsec) +{ + udelay((nsec + 500) / 1000); +} + +static bool +i2c_raise_scl(struct nouveau_i2c_chan *port) +{ + u32 timeout = T_TIMEOUT / T_RISEFALL; + + i2c_drive_scl(port, 1); + do { + i2c_delay(port, T_RISEFALL); + } while (!i2c_sense_scl(port) && --timeout); + + return timeout != 0; +} + +static int +i2c_start(struct nouveau_i2c_chan *port) +{ + int ret = 0; + + port->state = i2c_sense_scl(port); + port->state |= i2c_sense_sda(port) << 1; + if (port->state != 3) { + i2c_drive_scl(port, 0); + i2c_drive_sda(port, 1); + if (!i2c_raise_scl(port)) + ret = -EBUSY; + } + + i2c_drive_sda(port, 0); + i2c_delay(port, T_HOLD); + i2c_drive_scl(port, 0); + i2c_delay(port, T_HOLD); + return ret; +} + +static void +i2c_stop(struct nouveau_i2c_chan *port) +{ + i2c_drive_scl(port, 0); + i2c_drive_sda(port, 0); + i2c_delay(port, T_RISEFALL); + + i2c_drive_scl(port, 1); + i2c_delay(port, T_HOLD); + i2c_drive_sda(port, 1); + i2c_delay(port, T_HOLD); +} + +static int +i2c_bitw(struct nouveau_i2c_chan *port, int sda) +{ + i2c_drive_sda(port, sda); + i2c_delay(port, T_RISEFALL); + + if (!i2c_raise_scl(port)) + return -ETIMEDOUT; + i2c_delay(port, T_HOLD); + + i2c_drive_scl(port, 0); + i2c_delay(port, T_HOLD); + return 0; +} + +static int +i2c_bitr(struct nouveau_i2c_chan *port) +{ + int sda; + + i2c_drive_sda(port, 1); + i2c_delay(port, T_RISEFALL); + + if (!i2c_raise_scl(port)) + return -ETIMEDOUT; + i2c_delay(port, T_HOLD); + + sda = i2c_sense_sda(port); + + i2c_drive_scl(port, 0); + i2c_delay(port, T_HOLD); + return sda; +} + +static int +i2c_get_byte(struct nouveau_i2c_chan *port, u8 *byte, bool last) +{ + int i, bit; + + *byte = 0; + for (i = 7; i >= 0; i--) { + bit = i2c_bitr(port); + if (bit < 0) + return bit; + *byte |= bit << i; + } + + return i2c_bitw(port, last ? 1 : 0); +} + +static int +i2c_put_byte(struct nouveau_i2c_chan *port, u8 byte) +{ + int i, ret; + for (i = 7; i >= 0; i--) { + ret = i2c_bitw(port, !!(byte & (1 << i))); + if (ret < 0) + return ret; + } + + ret = i2c_bitr(port); + if (ret == 1) /* nack */ + ret = -EIO; + return ret; +} + +static int +i2c_addr(struct nouveau_i2c_chan *port, struct i2c_msg *msg) +{ + u32 addr = msg->addr << 1; + if (msg->flags & I2C_M_RD) + addr |= 1; + return i2c_put_byte(port, addr); +} + +static int +i2c_bit_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) +{ + struct nouveau_i2c_chan *port = (struct nouveau_i2c_chan *)adap; + struct i2c_msg *msg = msgs; + int ret = 0, mcnt = num; + + while (!ret && mcnt--) { + u8 remaining = msg->len; + u8 *ptr = msg->buf; + + ret = i2c_start(port); + if (ret == 0) + ret = i2c_addr(port, msg); + + if (msg->flags & I2C_M_RD) { + while (!ret && remaining--) + ret = i2c_get_byte(port, ptr++, !remaining); + } else { + while (!ret && remaining--) + ret = i2c_put_byte(port, *ptr++); + } + + msg++; + } + + i2c_stop(port); + return (ret < 0) ? ret : num; +} + +static u32 +i2c_bit_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +const struct i2c_algorithm nouveau_i2c_bit_algo = { + .master_xfer = i2c_bit_xfer, + .functionality = i2c_bit_func +}; + static const uint32_t nv50_i2c_port[] = { 0x00e138, 0x00e150, 0x00e168, 0x00e180, 0x00e254, 0x00e274, 0x00e764, 0x00e780, @@ -211,10 +384,12 @@ nouveau_i2c_init(struct drm_device *dev) case 0: /* NV04:NV50 */ port->drive = entry[0]; port->sense = entry[1]; + port->adapter.algo = &nouveau_i2c_bit_algo; break; case 4: /* NV4E */ port->drive = 0x600800 + entry[1]; port->sense = port->drive; + port->adapter.algo = &nouveau_i2c_bit_algo; break; case 5: /* NV50- */ port->drive = entry[0] & 0x0f; @@ -227,6 +402,7 @@ nouveau_i2c_init(struct drm_device *dev) port->drive = 0x00d014 + (port->drive * 0x20); port->sense = port->drive; } + port->adapter.algo = &nouveau_i2c_bit_algo; break; case 6: /* NV50- DP AUX */ port->drive = entry[0]; @@ -237,7 +413,7 @@ nouveau_i2c_init(struct drm_device *dev) break; } - if (!port->adapter.algo && !port->drive) { + if (!port->adapter.algo) { NV_ERROR(dev, "I2C%d: type %d index %x/%x unknown\n", i, port->type, port->drive, port->sense); kfree(port); @@ -253,26 +429,7 @@ nouveau_i2c_init(struct drm_device *dev) port->dcb = ROM32(entry[0]); i2c_set_adapdata(&port->adapter, i2c); - if (port->adapter.algo != &nouveau_dp_i2c_algo) { - port->adapter.algo_data = &port->bit; - port->bit.udelay = 10; - port->bit.timeout = usecs_to_jiffies(2200); - port->bit.data = port; - port->bit.setsda = i2c_drive_sda; - port->bit.setscl = i2c_drive_scl; - port->bit.getsda = i2c_sense_sda; - port->bit.getscl = i2c_sense_scl; - - i2c_drive_scl(port, 0); - i2c_drive_sda(port, 1); - i2c_drive_scl(port, 1); - - ret = i2c_bit_add_bus(&port->adapter); - } else { - port->adapter.algo = &nouveau_dp_i2c_algo; - ret = i2c_add_adapter(&port->adapter); - } - + ret = i2c_add_adapter(&port->adapter); if (ret) { NV_ERROR(dev, "I2C%d: failed register: %d\n", i, ret); kfree(port); diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_i2c.h b/trunk/drivers/gpu/drm/nouveau/nouveau_i2c.h index 1d083893a4d7..4d2e4e9031be 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_i2c.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_i2c.h @@ -34,7 +34,6 @@ struct nouveau_i2c_chan { struct i2c_adapter adapter; struct drm_device *dev; - struct i2c_algo_bit_data bit; struct list_head head; u8 index; u8 type; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_device.c b/trunk/drivers/gpu/drm/radeon/radeon_device.c index 5992502a3448..ea7df16e2f84 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_device.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_device.c @@ -241,8 +241,8 @@ int radeon_wb_init(struct radeon_device *rdev) rdev->wb.use_event = true; } } - /* always use writeback/events on NI, APUs */ - if (rdev->family >= CHIP_PALM) { + /* always use writeback/events on NI */ + if (ASIC_IS_DCE5(rdev)) { rdev->wb.enabled = true; rdev->wb.use_event = true; } diff --git a/trunk/drivers/ieee802154/Kconfig b/trunk/drivers/ieee802154/Kconfig index 15c064073701..9b9f43aa2f85 100644 --- a/trunk/drivers/ieee802154/Kconfig +++ b/trunk/drivers/ieee802154/Kconfig @@ -19,12 +19,4 @@ config IEEE802154_FAKEHARD This driver can also be built as a module. To do so say M here. The module will be called 'fakehard'. -config IEEE802154_FAKELB - depends on IEEE802154_DRIVERS && MAC802154 - tristate "IEEE 802.15.4 loopback driver" - ---help--- - Say Y here to enable the fake driver that can emulate a net - of several interconnected radio devices. - This driver can also be built as a module. To do so say M here. - The module will be called 'fakelb'. diff --git a/trunk/drivers/ieee802154/Makefile b/trunk/drivers/ieee802154/Makefile index ea784ea6f0f8..800a3894af0d 100644 --- a/trunk/drivers/ieee802154/Makefile +++ b/trunk/drivers/ieee802154/Makefile @@ -1,2 +1 @@ obj-$(CONFIG_IEEE802154_FAKEHARD) += fakehard.o -obj-$(CONFIG_IEEE802154_FAKELB) += fakelb.o diff --git a/trunk/drivers/ieee802154/fakelb.c b/trunk/drivers/ieee802154/fakelb.c deleted file mode 100644 index e7456fcd0913..000000000000 --- a/trunk/drivers/ieee802154/fakelb.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Loopback IEEE 802.15.4 interface - * - * Copyright 2007-2012 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Sergey Lapin - * Dmitry Eremin-Solenikov - * Alexander Smirnov - */ - -#include -#include -#include -#include -#include -#include -#include - -static int numlbs = 1; - -struct fakelb_dev_priv { - struct ieee802154_dev *dev; - - struct list_head list; - struct fakelb_priv *fake; - - spinlock_t lock; - bool working; -}; - -struct fakelb_priv { - struct list_head list; - rwlock_t lock; -}; - -static int -fakelb_hw_ed(struct ieee802154_dev *dev, u8 *level) -{ - might_sleep(); - BUG_ON(!level); - *level = 0xbe; - - return 0; -} - -static int -fakelb_hw_channel(struct ieee802154_dev *dev, int page, int channel) -{ - pr_debug("set channel to %d\n", channel); - - might_sleep(); - dev->phy->current_page = page; - dev->phy->current_channel = channel; - - return 0; -} - -static void -fakelb_hw_deliver(struct fakelb_dev_priv *priv, struct sk_buff *skb) -{ - struct sk_buff *newskb; - - spin_lock(&priv->lock); - if (priv->working) { - newskb = pskb_copy(skb, GFP_ATOMIC); - ieee802154_rx_irqsafe(priv->dev, newskb, 0xcc); - } - spin_unlock(&priv->lock); -} - -static int -fakelb_hw_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) -{ - struct fakelb_dev_priv *priv = dev->priv; - struct fakelb_priv *fake = priv->fake; - - might_sleep(); - - read_lock_bh(&fake->lock); - if (priv->list.next == priv->list.prev) { - /* we are the only one device */ - fakelb_hw_deliver(priv, skb); - } else { - struct fakelb_dev_priv *dp; - list_for_each_entry(dp, &priv->fake->list, list) { - if (dp != priv && - (dp->dev->phy->current_channel == - priv->dev->phy->current_channel)) - fakelb_hw_deliver(dp, skb); - } - } - read_unlock_bh(&fake->lock); - - return 0; -} - -static int -fakelb_hw_start(struct ieee802154_dev *dev) { - struct fakelb_dev_priv *priv = dev->priv; - int ret = 0; - - spin_lock(&priv->lock); - if (priv->working) - ret = -EBUSY; - else - priv->working = 1; - spin_unlock(&priv->lock); - - return ret; -} - -static void -fakelb_hw_stop(struct ieee802154_dev *dev) { - struct fakelb_dev_priv *priv = dev->priv; - - spin_lock(&priv->lock); - priv->working = 0; - spin_unlock(&priv->lock); -} - -static struct ieee802154_ops fakelb_ops = { - .owner = THIS_MODULE, - .xmit = fakelb_hw_xmit, - .ed = fakelb_hw_ed, - .set_channel = fakelb_hw_channel, - .start = fakelb_hw_start, - .stop = fakelb_hw_stop, -}; - -/* Number of dummy devices to be set up by this module. */ -module_param(numlbs, int, 0); -MODULE_PARM_DESC(numlbs, " number of pseudo devices"); - -static int fakelb_add_one(struct device *dev, struct fakelb_priv *fake) -{ - struct fakelb_dev_priv *priv; - int err; - struct ieee802154_dev *ieee; - - ieee = ieee802154_alloc_device(sizeof(*priv), &fakelb_ops); - if (!ieee) - return -ENOMEM; - - priv = ieee->priv; - priv->dev = ieee; - - /* 868 MHz BPSK 802.15.4-2003 */ - ieee->phy->channels_supported[0] |= 1; - /* 915 MHz BPSK 802.15.4-2003 */ - ieee->phy->channels_supported[0] |= 0x7fe; - /* 2.4 GHz O-QPSK 802.15.4-2003 */ - ieee->phy->channels_supported[0] |= 0x7FFF800; - /* 868 MHz ASK 802.15.4-2006 */ - ieee->phy->channels_supported[1] |= 1; - /* 915 MHz ASK 802.15.4-2006 */ - ieee->phy->channels_supported[1] |= 0x7fe; - /* 868 MHz O-QPSK 802.15.4-2006 */ - ieee->phy->channels_supported[2] |= 1; - /* 915 MHz O-QPSK 802.15.4-2006 */ - ieee->phy->channels_supported[2] |= 0x7fe; - /* 2.4 GHz CSS 802.15.4a-2007 */ - ieee->phy->channels_supported[3] |= 0x3fff; - /* UWB Sub-gigahertz 802.15.4a-2007 */ - ieee->phy->channels_supported[4] |= 1; - /* UWB Low band 802.15.4a-2007 */ - ieee->phy->channels_supported[4] |= 0x1e; - /* UWB High band 802.15.4a-2007 */ - ieee->phy->channels_supported[4] |= 0xffe0; - /* 750 MHz O-QPSK 802.15.4c-2009 */ - ieee->phy->channels_supported[5] |= 0xf; - /* 750 MHz MPSK 802.15.4c-2009 */ - ieee->phy->channels_supported[5] |= 0xf0; - /* 950 MHz BPSK 802.15.4d-2009 */ - ieee->phy->channels_supported[6] |= 0x3ff; - /* 950 MHz GFSK 802.15.4d-2009 */ - ieee->phy->channels_supported[6] |= 0x3ffc00; - - INIT_LIST_HEAD(&priv->list); - priv->fake = fake; - - spin_lock_init(&priv->lock); - - ieee->parent = dev; - - err = ieee802154_register_device(ieee); - if (err) - goto err_reg; - - write_lock_bh(&fake->lock); - list_add_tail(&priv->list, &fake->list); - write_unlock_bh(&fake->lock); - - return 0; - -err_reg: - ieee802154_free_device(priv->dev); - return err; -} - -static void fakelb_del(struct fakelb_dev_priv *priv) -{ - write_lock_bh(&priv->fake->lock); - list_del(&priv->list); - write_unlock_bh(&priv->fake->lock); - - ieee802154_unregister_device(priv->dev); - ieee802154_free_device(priv->dev); -} - -static int __devinit fakelb_probe(struct platform_device *pdev) -{ - struct fakelb_priv *priv; - struct fakelb_dev_priv *dp; - int err = -ENOMEM; - int i; - - priv = kzalloc(sizeof(struct fakelb_priv), GFP_KERNEL); - if (!priv) - goto err_alloc; - - INIT_LIST_HEAD(&priv->list); - rwlock_init(&priv->lock); - - for (i = 0; i < numlbs; i++) { - err = fakelb_add_one(&pdev->dev, priv); - if (err < 0) - goto err_slave; - } - - platform_set_drvdata(pdev, priv); - dev_info(&pdev->dev, "added ieee802154 hardware\n"); - return 0; - -err_slave: - list_for_each_entry(dp, &priv->list, list) - fakelb_del(dp); - kfree(priv); -err_alloc: - return err; -} - -static int __devexit fakelb_remove(struct platform_device *pdev) -{ - struct fakelb_priv *priv = platform_get_drvdata(pdev); - struct fakelb_dev_priv *dp, *temp; - - list_for_each_entry_safe(dp, temp, &priv->list, list) - fakelb_del(dp); - kfree(priv); - - return 0; -} - -static struct platform_device *ieee802154fake_dev; - -static struct platform_driver ieee802154fake_driver = { - .probe = fakelb_probe, - .remove = __devexit_p(fakelb_remove), - .driver = { - .name = "ieee802154fakelb", - .owner = THIS_MODULE, - }, -}; - -static __init int fakelb_init_module(void) -{ - ieee802154fake_dev = platform_device_register_simple( - "ieee802154fakelb", -1, NULL, 0); - return platform_driver_register(&ieee802154fake_driver); -} - -static __exit void fake_remove_module(void) -{ - platform_driver_unregister(&ieee802154fake_driver); - platform_device_unregister(ieee802154fake_dev); -} - -module_init(fakelb_init_module); -module_exit(fake_remove_module); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/infiniband/Kconfig b/trunk/drivers/infiniband/Kconfig index a0f29c1d03bc..eb0add311dc8 100644 --- a/trunk/drivers/infiniband/Kconfig +++ b/trunk/drivers/infiniband/Kconfig @@ -51,7 +51,6 @@ source "drivers/infiniband/hw/cxgb3/Kconfig" source "drivers/infiniband/hw/cxgb4/Kconfig" source "drivers/infiniband/hw/mlx4/Kconfig" source "drivers/infiniband/hw/nes/Kconfig" -source "drivers/infiniband/hw/ocrdma/Kconfig" source "drivers/infiniband/ulp/ipoib/Kconfig" diff --git a/trunk/drivers/infiniband/Makefile b/trunk/drivers/infiniband/Makefile index bf846a14b9d3..a3b2d8eac86e 100644 --- a/trunk/drivers/infiniband/Makefile +++ b/trunk/drivers/infiniband/Makefile @@ -8,7 +8,6 @@ obj-$(CONFIG_INFINIBAND_CXGB3) += hw/cxgb3/ obj-$(CONFIG_INFINIBAND_CXGB4) += hw/cxgb4/ obj-$(CONFIG_MLX4_INFINIBAND) += hw/mlx4/ obj-$(CONFIG_INFINIBAND_NES) += hw/nes/ -obj-$(CONFIG_INFINIBAND_OCRDMA) += hw/ocrdma/ obj-$(CONFIG_INFINIBAND_IPOIB) += ulp/ipoib/ obj-$(CONFIG_INFINIBAND_SRP) += ulp/srp/ obj-$(CONFIG_INFINIBAND_SRPT) += ulp/srpt/ diff --git a/trunk/drivers/infiniband/core/cma.c b/trunk/drivers/infiniband/core/cma.c index 55d5642eb10a..59fbd704a1ec 100644 --- a/trunk/drivers/infiniband/core/cma.c +++ b/trunk/drivers/infiniband/core/cma.c @@ -1219,13 +1219,13 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) } if (!conn_id) { ret = -ENOMEM; - goto err1; + goto out; } mutex_lock_nested(&conn_id->handler_mutex, SINGLE_DEPTH_NESTING); ret = cma_acquire_dev(conn_id); if (ret) - goto err2; + goto release_conn_id; conn_id->cm_id.ib = cm_id; cm_id->context = conn_id; @@ -1237,33 +1237,31 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) */ atomic_inc(&conn_id->refcount); ret = conn_id->id.event_handler(&conn_id->id, &event); - if (ret) - goto err3; - - /* - * Acquire mutex to prevent user executing rdma_destroy_id() - * while we're accessing the cm_id. - */ - mutex_lock(&lock); - if (cma_comp(conn_id, RDMA_CM_CONNECT) && (conn_id->id.qp_type != IB_QPT_UD)) - ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0); - mutex_unlock(&lock); - mutex_unlock(&conn_id->handler_mutex); - mutex_unlock(&listen_id->handler_mutex); + if (!ret) { + /* + * Acquire mutex to prevent user executing rdma_destroy_id() + * while we're accessing the cm_id. + */ + mutex_lock(&lock); + if (cma_comp(conn_id, RDMA_CM_CONNECT) && (conn_id->id.qp_type != IB_QPT_UD)) + ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0); + mutex_unlock(&lock); + mutex_unlock(&conn_id->handler_mutex); + cma_deref_id(conn_id); + goto out; + } cma_deref_id(conn_id); - return 0; -err3: - cma_deref_id(conn_id); /* Destroy the CM ID by returning a non-zero value. */ conn_id->cm_id.ib = NULL; -err2: + +release_conn_id: cma_exch(conn_id, RDMA_CM_DESTROYING); mutex_unlock(&conn_id->handler_mutex); -err1: + rdma_destroy_id(&conn_id->id); + +out: mutex_unlock(&listen_id->handler_mutex); - if (conn_id) - rdma_destroy_id(&conn_id->id); return ret; } diff --git a/trunk/drivers/infiniband/core/umem.c b/trunk/drivers/infiniband/core/umem.c index a84112322071..71f0c0f7df94 100644 --- a/trunk/drivers/infiniband/core/umem.c +++ b/trunk/drivers/infiniband/core/umem.c @@ -269,7 +269,7 @@ void ib_umem_release(struct ib_umem *umem) } else down_write(&mm->mmap_sem); - current->mm->pinned_vm -= diff; + current->mm->locked_vm -= diff; up_write(&mm->mmap_sem); mmput(mm); kfree(umem); diff --git a/trunk/drivers/infiniband/core/uverbs_cmd.c b/trunk/drivers/infiniband/core/uverbs_cmd.c index f9d0d7c413a2..4d27e4c3fe34 100644 --- a/trunk/drivers/infiniband/core/uverbs_cmd.c +++ b/trunk/drivers/infiniband/core/uverbs_cmd.c @@ -41,18 +41,13 @@ #include "uverbs.h" -struct uverbs_lock_class { - struct lock_class_key key; - char name[16]; -}; - -static struct uverbs_lock_class pd_lock_class = { .name = "PD-uobj" }; -static struct uverbs_lock_class mr_lock_class = { .name = "MR-uobj" }; -static struct uverbs_lock_class cq_lock_class = { .name = "CQ-uobj" }; -static struct uverbs_lock_class qp_lock_class = { .name = "QP-uobj" }; -static struct uverbs_lock_class ah_lock_class = { .name = "AH-uobj" }; -static struct uverbs_lock_class srq_lock_class = { .name = "SRQ-uobj" }; -static struct uverbs_lock_class xrcd_lock_class = { .name = "XRCD-uobj" }; +static struct lock_class_key pd_lock_key; +static struct lock_class_key mr_lock_key; +static struct lock_class_key cq_lock_key; +static struct lock_class_key qp_lock_key; +static struct lock_class_key ah_lock_key; +static struct lock_class_key srq_lock_key; +static struct lock_class_key xrcd_lock_key; #define INIT_UDATA(udata, ibuf, obuf, ilen, olen) \ do { \ @@ -88,13 +83,13 @@ static struct uverbs_lock_class xrcd_lock_class = { .name = "XRCD-uobj" }; */ static void init_uobj(struct ib_uobject *uobj, u64 user_handle, - struct ib_ucontext *context, struct uverbs_lock_class *c) + struct ib_ucontext *context, struct lock_class_key *key) { uobj->user_handle = user_handle; uobj->context = context; kref_init(&uobj->ref); init_rwsem(&uobj->mutex); - lockdep_set_class_and_name(&uobj->mutex, &c->key, c->name); + lockdep_set_class(&uobj->mutex, key); uobj->live = 0; } @@ -527,7 +522,7 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file, if (!uobj) return -ENOMEM; - init_uobj(uobj, 0, file->ucontext, &pd_lock_class); + init_uobj(uobj, 0, file->ucontext, &pd_lock_key); down_write(&uobj->mutex); pd = file->device->ib_dev->alloc_pd(file->device->ib_dev, @@ -755,7 +750,7 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file, goto err_tree_mutex_unlock; } - init_uobj(&obj->uobject, 0, file->ucontext, &xrcd_lock_class); + init_uobj(&obj->uobject, 0, file->ucontext, &xrcd_lock_key); down_write(&obj->uobject.mutex); @@ -952,7 +947,7 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, if (!uobj) return -ENOMEM; - init_uobj(uobj, 0, file->ucontext, &mr_lock_class); + init_uobj(uobj, 0, file->ucontext, &mr_lock_key); down_write(&uobj->mutex); pd = idr_read_pd(cmd.pd_handle, file->ucontext); @@ -1120,7 +1115,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, if (!obj) return -ENOMEM; - init_uobj(&obj->uobject, cmd.user_handle, file->ucontext, &cq_lock_class); + init_uobj(&obj->uobject, cmd.user_handle, file->ucontext, &cq_lock_key); down_write(&obj->uobject.mutex); if (cmd.comp_channel >= 0) { @@ -1404,9 +1399,6 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - if (cmd.qp_type == IB_QPT_RAW_PACKET && !capable(CAP_NET_RAW)) - return -EPERM; - INIT_UDATA(&udata, buf + sizeof cmd, (unsigned long) cmd.response + sizeof resp, in_len - sizeof cmd, out_len - sizeof resp); @@ -1415,7 +1407,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, if (!obj) return -ENOMEM; - init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext, &qp_lock_class); + init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext, &qp_lock_key); down_write(&obj->uevent.uobject.mutex); if (cmd.qp_type == IB_QPT_XRC_TGT) { @@ -1426,6 +1418,13 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, } device = xrcd->device; } else { + pd = idr_read_pd(cmd.pd_handle, file->ucontext); + scq = idr_read_cq(cmd.send_cq_handle, file->ucontext, 0); + if (!pd || !scq) { + ret = -EINVAL; + goto err_put; + } + if (cmd.qp_type == IB_QPT_XRC_INI) { cmd.max_recv_wr = cmd.max_recv_sge = 0; } else { @@ -1436,24 +1435,13 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, goto err_put; } } - - if (cmd.recv_cq_handle != cmd.send_cq_handle) { - rcq = idr_read_cq(cmd.recv_cq_handle, file->ucontext, 0); - if (!rcq) { - ret = -EINVAL; - goto err_put; - } + rcq = (cmd.recv_cq_handle == cmd.send_cq_handle) ? + scq : idr_read_cq(cmd.recv_cq_handle, file->ucontext, 1); + if (!rcq) { + ret = -EINVAL; + goto err_put; } } - - scq = idr_read_cq(cmd.send_cq_handle, file->ucontext, !!rcq); - rcq = rcq ?: scq; - pd = idr_read_pd(cmd.pd_handle, file->ucontext); - if (!pd || !scq) { - ret = -EINVAL; - goto err_put; - } - device = pd->device; } @@ -1597,7 +1585,7 @@ ssize_t ib_uverbs_open_qp(struct ib_uverbs_file *file, if (!obj) return -ENOMEM; - init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext, &qp_lock_class); + init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext, &qp_lock_key); down_write(&obj->uevent.uobject.mutex); xrcd = idr_read_xrcd(cmd.pd_handle, file->ucontext, &xrcd_uobj); @@ -2284,7 +2272,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file, if (!uobj) return -ENOMEM; - init_uobj(uobj, cmd.user_handle, file->ucontext, &ah_lock_class); + init_uobj(uobj, cmd.user_handle, file->ucontext, &ah_lock_key); down_write(&uobj->mutex); pd = idr_read_pd(cmd.pd_handle, file->ucontext); @@ -2488,30 +2476,30 @@ static int __uverbs_create_xsrq(struct ib_uverbs_file *file, if (!obj) return -ENOMEM; - init_uobj(&obj->uevent.uobject, cmd->user_handle, file->ucontext, &srq_lock_class); + init_uobj(&obj->uevent.uobject, cmd->user_handle, file->ucontext, &srq_lock_key); down_write(&obj->uevent.uobject.mutex); + pd = idr_read_pd(cmd->pd_handle, file->ucontext); + if (!pd) { + ret = -EINVAL; + goto err; + } + if (cmd->srq_type == IB_SRQT_XRC) { + attr.ext.xrc.cq = idr_read_cq(cmd->cq_handle, file->ucontext, 0); + if (!attr.ext.xrc.cq) { + ret = -EINVAL; + goto err_put_pd; + } + attr.ext.xrc.xrcd = idr_read_xrcd(cmd->xrcd_handle, file->ucontext, &xrcd_uobj); if (!attr.ext.xrc.xrcd) { ret = -EINVAL; - goto err; + goto err_put_cq; } obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object, uobject); atomic_inc(&obj->uxrcd->refcnt); - - attr.ext.xrc.cq = idr_read_cq(cmd->cq_handle, file->ucontext, 0); - if (!attr.ext.xrc.cq) { - ret = -EINVAL; - goto err_put_xrcd; - } - } - - pd = idr_read_pd(cmd->pd_handle, file->ucontext); - if (!pd) { - ret = -EINVAL; - goto err_put_cq; } attr.event_handler = ib_uverbs_srq_event_handler; @@ -2588,17 +2576,17 @@ static int __uverbs_create_xsrq(struct ib_uverbs_file *file, ib_destroy_srq(srq); err_put: - put_pd_read(pd); + if (cmd->srq_type == IB_SRQT_XRC) { + atomic_dec(&obj->uxrcd->refcnt); + put_uobj_read(xrcd_uobj); + } err_put_cq: if (cmd->srq_type == IB_SRQT_XRC) put_cq_read(attr.ext.xrc.cq); -err_put_xrcd: - if (cmd->srq_type == IB_SRQT_XRC) { - atomic_dec(&obj->uxrcd->refcnt); - put_uobj_read(xrcd_uobj); - } +err_put_pd: + put_pd_read(pd); err: put_uobj_write(&obj->uevent.uobject); diff --git a/trunk/drivers/infiniband/core/verbs.c b/trunk/drivers/infiniband/core/verbs.c index 30f199e8579f..575b78045aaf 100644 --- a/trunk/drivers/infiniband/core/verbs.c +++ b/trunk/drivers/infiniband/core/verbs.c @@ -479,7 +479,6 @@ static const struct { [IB_QPT_UD] = (IB_QP_PKEY_INDEX | IB_QP_PORT | IB_QP_QKEY), - [IB_QPT_RAW_PACKET] = IB_QP_PORT, [IB_QPT_UC] = (IB_QP_PKEY_INDEX | IB_QP_PORT | IB_QP_ACCESS_FLAGS), @@ -1184,33 +1183,23 @@ EXPORT_SYMBOL(ib_dealloc_fmr); int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid) { - int ret; - if (!qp->device->attach_mcast) return -ENOSYS; if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD) return -EINVAL; - ret = qp->device->attach_mcast(qp, gid, lid); - if (!ret) - atomic_inc(&qp->usecnt); - return ret; + return qp->device->attach_mcast(qp, gid, lid); } EXPORT_SYMBOL(ib_attach_mcast); int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid) { - int ret; - if (!qp->device->detach_mcast) return -ENOSYS; if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD) return -EINVAL; - ret = qp->device->detach_mcast(qp, gid, lid); - if (!ret) - atomic_dec(&qp->usecnt); - return ret; + return qp->device->detach_mcast(qp, gid, lid); } EXPORT_SYMBOL(ib_detach_mcast); diff --git a/trunk/drivers/infiniband/hw/cxgb4/Makefile b/trunk/drivers/infiniband/hw/cxgb4/Makefile index e11cf7299945..46b878ca2c3b 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/Makefile +++ b/trunk/drivers/infiniband/hw/cxgb4/Makefile @@ -2,4 +2,4 @@ ccflags-y := -Idrivers/net/ethernet/chelsio/cxgb4 obj-$(CONFIG_INFINIBAND_CXGB4) += iw_cxgb4.o -iw_cxgb4-y := device.o cm.o provider.o mem.o cq.o qp.o resource.o ev.o id_table.o +iw_cxgb4-y := device.o cm.o provider.o mem.o cq.o qp.o resource.o ev.o diff --git a/trunk/drivers/infiniband/hw/cxgb4/cm.c b/trunk/drivers/infiniband/hw/cxgb4/cm.c index 55ab284e22f2..92b4c2b0308b 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/cm.c +++ b/trunk/drivers/infiniband/hw/cxgb4/cm.c @@ -1362,10 +1362,7 @@ static int abort_rpl(struct c4iw_dev *dev, struct sk_buff *skb) ep = lookup_tid(t, tid); PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); - if (!ep) { - printk(KERN_WARNING MOD "Abort rpl to freed endpoint\n"); - return 0; - } + BUG_ON(!ep); mutex_lock(&ep->com.mutex); switch (ep->com.state) { case ABORTING: @@ -1413,24 +1410,6 @@ static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb) return 0; } - /* - * Log interesting failures. - */ - switch (status) { - case CPL_ERR_CONN_RESET: - case CPL_ERR_CONN_TIMEDOUT: - break; - default: - printk(KERN_INFO MOD "Active open failure - " - "atid %u status %u errno %d %pI4:%u->%pI4:%u\n", - atid, status, status2errno(status), - &ep->com.local_addr.sin_addr.s_addr, - ntohs(ep->com.local_addr.sin_port), - &ep->com.remote_addr.sin_addr.s_addr, - ntohs(ep->com.remote_addr.sin_port)); - break; - } - connect_reply_upcall(ep, status2errno(status)); state_set(&ep->com, DEAD); @@ -1614,7 +1593,7 @@ static int import_ep(struct c4iw_ep *ep, __be32 peer_ip, struct dst_entry *dst, n, n->dev, 0); if (!ep->l2t) goto out; - ep->mtu = dst_mtu(dst); + ep->mtu = dst_mtu(ep->dst); ep->tx_chan = cxgb4_port_chan(n->dev); ep->smac_idx = (cxgb4_port_viid(n->dev) & 0x7F) << 1; step = cdev->rdev.lldi.ntxq / @@ -2677,12 +2656,6 @@ static int peer_abort_intr(struct c4iw_dev *dev, struct sk_buff *skb) unsigned int tid = GET_TID(req); ep = lookup_tid(t, tid); - if (!ep) { - printk(KERN_WARNING MOD - "Abort on non-existent endpoint, tid %d\n", tid); - kfree_skb(skb); - return 0; - } if (is_neg_adv_abort(req->status)) { PDBG("%s neg_adv_abort ep %p tid %u\n", __func__, ep, ep->hwtid); @@ -2694,8 +2667,11 @@ static int peer_abort_intr(struct c4iw_dev *dev, struct sk_buff *skb) /* * Wake up any threads in rdma_init() or rdma_fini(). + * However, this is not needed if com state is just + * MPA_REQ_SENT */ - c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET); + if (ep->com.state != MPA_REQ_SENT) + c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET); sched(dev, skb); return 0; } diff --git a/trunk/drivers/infiniband/hw/cxgb4/device.c b/trunk/drivers/infiniband/hw/cxgb4/device.c index cb4ecd783700..6d0df6ec161b 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/device.c +++ b/trunk/drivers/infiniband/hw/cxgb4/device.c @@ -32,7 +32,6 @@ #include #include #include -#include #include @@ -45,12 +44,6 @@ MODULE_DESCRIPTION("Chelsio T4 RDMA Driver"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(DRV_VERSION); -struct uld_ctx { - struct list_head entry; - struct cxgb4_lld_info lldi; - struct c4iw_dev *dev; -}; - static LIST_HEAD(uld_ctx_list); static DEFINE_MUTEX(dev_mutex); @@ -122,7 +115,7 @@ static int qp_release(struct inode *inode, struct file *file) printk(KERN_INFO "%s null qpd?\n", __func__); return 0; } - vfree(qpd->buf); + kfree(qpd->buf); kfree(qpd); return 0; } @@ -146,7 +139,7 @@ static int qp_open(struct inode *inode, struct file *file) spin_unlock_irq(&qpd->devp->lock); qpd->bufsize = count * 128; - qpd->buf = vmalloc(qpd->bufsize); + qpd->buf = kmalloc(qpd->bufsize, GFP_KERNEL); if (!qpd->buf) { ret = -ENOMEM; goto err1; @@ -247,81 +240,6 @@ static const struct file_operations stag_debugfs_fops = { .llseek = default_llseek, }; -static char *db_state_str[] = {"NORMAL", "FLOW_CONTROL", "RECOVERY"}; - -static int stats_show(struct seq_file *seq, void *v) -{ - struct c4iw_dev *dev = seq->private; - - seq_printf(seq, " Object: %10s %10s %10s %10s\n", "Total", "Current", - "Max", "Fail"); - seq_printf(seq, " PDID: %10llu %10llu %10llu %10llu\n", - dev->rdev.stats.pd.total, dev->rdev.stats.pd.cur, - dev->rdev.stats.pd.max, dev->rdev.stats.pd.fail); - seq_printf(seq, " QID: %10llu %10llu %10llu %10llu\n", - dev->rdev.stats.qid.total, dev->rdev.stats.qid.cur, - dev->rdev.stats.qid.max, dev->rdev.stats.qid.fail); - seq_printf(seq, " TPTMEM: %10llu %10llu %10llu %10llu\n", - dev->rdev.stats.stag.total, dev->rdev.stats.stag.cur, - dev->rdev.stats.stag.max, dev->rdev.stats.stag.fail); - seq_printf(seq, " PBLMEM: %10llu %10llu %10llu %10llu\n", - dev->rdev.stats.pbl.total, dev->rdev.stats.pbl.cur, - dev->rdev.stats.pbl.max, dev->rdev.stats.pbl.fail); - seq_printf(seq, " RQTMEM: %10llu %10llu %10llu %10llu\n", - dev->rdev.stats.rqt.total, dev->rdev.stats.rqt.cur, - dev->rdev.stats.rqt.max, dev->rdev.stats.rqt.fail); - seq_printf(seq, " OCQPMEM: %10llu %10llu %10llu %10llu\n", - dev->rdev.stats.ocqp.total, dev->rdev.stats.ocqp.cur, - dev->rdev.stats.ocqp.max, dev->rdev.stats.ocqp.fail); - seq_printf(seq, " DB FULL: %10llu\n", dev->rdev.stats.db_full); - seq_printf(seq, " DB EMPTY: %10llu\n", dev->rdev.stats.db_empty); - seq_printf(seq, " DB DROP: %10llu\n", dev->rdev.stats.db_drop); - seq_printf(seq, " DB State: %s Transitions %llu\n", - db_state_str[dev->db_state], - dev->rdev.stats.db_state_transitions); - return 0; -} - -static int stats_open(struct inode *inode, struct file *file) -{ - return single_open(file, stats_show, inode->i_private); -} - -static ssize_t stats_clear(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct c4iw_dev *dev = ((struct seq_file *)file->private_data)->private; - - mutex_lock(&dev->rdev.stats.lock); - dev->rdev.stats.pd.max = 0; - dev->rdev.stats.pd.fail = 0; - dev->rdev.stats.qid.max = 0; - dev->rdev.stats.qid.fail = 0; - dev->rdev.stats.stag.max = 0; - dev->rdev.stats.stag.fail = 0; - dev->rdev.stats.pbl.max = 0; - dev->rdev.stats.pbl.fail = 0; - dev->rdev.stats.rqt.max = 0; - dev->rdev.stats.rqt.fail = 0; - dev->rdev.stats.ocqp.max = 0; - dev->rdev.stats.ocqp.fail = 0; - dev->rdev.stats.db_full = 0; - dev->rdev.stats.db_empty = 0; - dev->rdev.stats.db_drop = 0; - dev->rdev.stats.db_state_transitions = 0; - mutex_unlock(&dev->rdev.stats.lock); - return count; -} - -static const struct file_operations stats_debugfs_fops = { - .owner = THIS_MODULE, - .open = stats_open, - .release = single_release, - .read = seq_read, - .llseek = seq_lseek, - .write = stats_clear, -}; - static int setup_debugfs(struct c4iw_dev *devp) { struct dentry *de; @@ -338,12 +256,6 @@ static int setup_debugfs(struct c4iw_dev *devp) (void *)devp, &stag_debugfs_fops); if (de && de->d_inode) de->d_inode->i_size = 4096; - - de = debugfs_create_file("stats", S_IWUSR, devp->debugfs_root, - (void *)devp, &stats_debugfs_fops); - if (de && de->d_inode) - de->d_inode->i_size = 4096; - return 0; } @@ -357,13 +269,9 @@ void c4iw_release_dev_ucontext(struct c4iw_rdev *rdev, list_for_each_safe(pos, nxt, &uctx->qpids) { entry = list_entry(pos, struct c4iw_qid_list, entry); list_del_init(&entry->entry); - if (!(entry->qid & rdev->qpmask)) { - c4iw_put_resource(&rdev->resource.qid_table, - entry->qid); - mutex_lock(&rdev->stats.lock); - rdev->stats.qid.cur -= rdev->qpmask + 1; - mutex_unlock(&rdev->stats.lock); - } + if (!(entry->qid & rdev->qpmask)) + c4iw_put_resource(&rdev->resource.qid_fifo, entry->qid, + &rdev->resource.qid_fifo_lock); kfree(entry); } @@ -424,13 +332,6 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev) goto err1; } - rdev->stats.pd.total = T4_MAX_NUM_PD; - rdev->stats.stag.total = rdev->lldi.vr->stag.size; - rdev->stats.pbl.total = rdev->lldi.vr->pbl.size; - rdev->stats.rqt.total = rdev->lldi.vr->rq.size; - rdev->stats.ocqp.total = rdev->lldi.vr->ocq.size; - rdev->stats.qid.total = rdev->lldi.vr->qp.size; - err = c4iw_init_resource(rdev, c4iw_num_stags(rdev), T4_MAX_NUM_PD); if (err) { printk(KERN_ERR MOD "error %d initializing resources\n", err); @@ -469,6 +370,12 @@ static void c4iw_rdev_close(struct c4iw_rdev *rdev) c4iw_destroy_resource(&rdev->resource); } +struct uld_ctx { + struct list_head entry; + struct cxgb4_lld_info lldi; + struct c4iw_dev *dev; +}; + static void c4iw_dealloc(struct uld_ctx *ctx) { c4iw_rdev_close(&ctx->dev->rdev); @@ -533,8 +440,6 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) idr_init(&devp->qpidr); idr_init(&devp->mmidr); spin_lock_init(&devp->lock); - mutex_init(&devp->rdev.stats.lock); - mutex_init(&devp->db_mutex); if (c4iw_debugfs_root) { devp->debugfs_root = debugfs_create_dir( @@ -680,234 +585,11 @@ static int c4iw_uld_state_change(void *handle, enum cxgb4_state new_state) return 0; } -static int disable_qp_db(int id, void *p, void *data) -{ - struct c4iw_qp *qp = p; - - t4_disable_wq_db(&qp->wq); - return 0; -} - -static void stop_queues(struct uld_ctx *ctx) -{ - spin_lock_irq(&ctx->dev->lock); - if (ctx->dev->db_state == NORMAL) { - ctx->dev->rdev.stats.db_state_transitions++; - ctx->dev->db_state = FLOW_CONTROL; - idr_for_each(&ctx->dev->qpidr, disable_qp_db, NULL); - } - spin_unlock_irq(&ctx->dev->lock); -} - -static int enable_qp_db(int id, void *p, void *data) -{ - struct c4iw_qp *qp = p; - - t4_enable_wq_db(&qp->wq); - return 0; -} - -static void resume_queues(struct uld_ctx *ctx) -{ - spin_lock_irq(&ctx->dev->lock); - if (ctx->dev->qpcnt <= db_fc_threshold && - ctx->dev->db_state == FLOW_CONTROL) { - ctx->dev->db_state = NORMAL; - ctx->dev->rdev.stats.db_state_transitions++; - idr_for_each(&ctx->dev->qpidr, enable_qp_db, NULL); - } - spin_unlock_irq(&ctx->dev->lock); -} - -struct qp_list { - unsigned idx; - struct c4iw_qp **qps; -}; - -static int add_and_ref_qp(int id, void *p, void *data) -{ - struct qp_list *qp_listp = data; - struct c4iw_qp *qp = p; - - c4iw_qp_add_ref(&qp->ibqp); - qp_listp->qps[qp_listp->idx++] = qp; - return 0; -} - -static int count_qps(int id, void *p, void *data) -{ - unsigned *countp = data; - (*countp)++; - return 0; -} - -static void deref_qps(struct qp_list qp_list) -{ - int idx; - - for (idx = 0; idx < qp_list.idx; idx++) - c4iw_qp_rem_ref(&qp_list.qps[idx]->ibqp); -} - -static void recover_lost_dbs(struct uld_ctx *ctx, struct qp_list *qp_list) -{ - int idx; - int ret; - - for (idx = 0; idx < qp_list->idx; idx++) { - struct c4iw_qp *qp = qp_list->qps[idx]; - - ret = cxgb4_sync_txq_pidx(qp->rhp->rdev.lldi.ports[0], - qp->wq.sq.qid, - t4_sq_host_wq_pidx(&qp->wq), - t4_sq_wq_size(&qp->wq)); - if (ret) { - printk(KERN_ERR MOD "%s: Fatal error - " - "DB overflow recovery failed - " - "error syncing SQ qid %u\n", - pci_name(ctx->lldi.pdev), qp->wq.sq.qid); - return; - } - - ret = cxgb4_sync_txq_pidx(qp->rhp->rdev.lldi.ports[0], - qp->wq.rq.qid, - t4_rq_host_wq_pidx(&qp->wq), - t4_rq_wq_size(&qp->wq)); - - if (ret) { - printk(KERN_ERR MOD "%s: Fatal error - " - "DB overflow recovery failed - " - "error syncing RQ qid %u\n", - pci_name(ctx->lldi.pdev), qp->wq.rq.qid); - return; - } - - /* Wait for the dbfifo to drain */ - while (cxgb4_dbfifo_count(qp->rhp->rdev.lldi.ports[0], 1) > 0) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(usecs_to_jiffies(10)); - } - } -} - -static void recover_queues(struct uld_ctx *ctx) -{ - int count = 0; - struct qp_list qp_list; - int ret; - - /* lock out kernel db ringers */ - mutex_lock(&ctx->dev->db_mutex); - - /* put all queues in to recovery mode */ - spin_lock_irq(&ctx->dev->lock); - ctx->dev->db_state = RECOVERY; - ctx->dev->rdev.stats.db_state_transitions++; - idr_for_each(&ctx->dev->qpidr, disable_qp_db, NULL); - spin_unlock_irq(&ctx->dev->lock); - - /* slow everybody down */ - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(usecs_to_jiffies(1000)); - - /* Wait for the dbfifo to completely drain. */ - while (cxgb4_dbfifo_count(ctx->dev->rdev.lldi.ports[0], 1) > 0) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(usecs_to_jiffies(10)); - } - - /* flush the SGE contexts */ - ret = cxgb4_flush_eq_cache(ctx->dev->rdev.lldi.ports[0]); - if (ret) { - printk(KERN_ERR MOD "%s: Fatal error - DB overflow recovery failed\n", - pci_name(ctx->lldi.pdev)); - goto out; - } - - /* Count active queues so we can build a list of queues to recover */ - spin_lock_irq(&ctx->dev->lock); - idr_for_each(&ctx->dev->qpidr, count_qps, &count); - - qp_list.qps = kzalloc(count * sizeof *qp_list.qps, GFP_ATOMIC); - if (!qp_list.qps) { - printk(KERN_ERR MOD "%s: Fatal error - DB overflow recovery failed\n", - pci_name(ctx->lldi.pdev)); - spin_unlock_irq(&ctx->dev->lock); - goto out; - } - qp_list.idx = 0; - - /* add and ref each qp so it doesn't get freed */ - idr_for_each(&ctx->dev->qpidr, add_and_ref_qp, &qp_list); - - spin_unlock_irq(&ctx->dev->lock); - - /* now traverse the list in a safe context to recover the db state*/ - recover_lost_dbs(ctx, &qp_list); - - /* we're almost done! deref the qps and clean up */ - deref_qps(qp_list); - kfree(qp_list.qps); - - /* Wait for the dbfifo to completely drain again */ - while (cxgb4_dbfifo_count(ctx->dev->rdev.lldi.ports[0], 1) > 0) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(usecs_to_jiffies(10)); - } - - /* resume the queues */ - spin_lock_irq(&ctx->dev->lock); - if (ctx->dev->qpcnt > db_fc_threshold) - ctx->dev->db_state = FLOW_CONTROL; - else { - ctx->dev->db_state = NORMAL; - idr_for_each(&ctx->dev->qpidr, enable_qp_db, NULL); - } - ctx->dev->rdev.stats.db_state_transitions++; - spin_unlock_irq(&ctx->dev->lock); - -out: - /* start up kernel db ringers again */ - mutex_unlock(&ctx->dev->db_mutex); -} - -static int c4iw_uld_control(void *handle, enum cxgb4_control control, ...) -{ - struct uld_ctx *ctx = handle; - - switch (control) { - case CXGB4_CONTROL_DB_FULL: - stop_queues(ctx); - mutex_lock(&ctx->dev->rdev.stats.lock); - ctx->dev->rdev.stats.db_full++; - mutex_unlock(&ctx->dev->rdev.stats.lock); - break; - case CXGB4_CONTROL_DB_EMPTY: - resume_queues(ctx); - mutex_lock(&ctx->dev->rdev.stats.lock); - ctx->dev->rdev.stats.db_empty++; - mutex_unlock(&ctx->dev->rdev.stats.lock); - break; - case CXGB4_CONTROL_DB_DROP: - recover_queues(ctx); - mutex_lock(&ctx->dev->rdev.stats.lock); - ctx->dev->rdev.stats.db_drop++; - mutex_unlock(&ctx->dev->rdev.stats.lock); - break; - default: - printk(KERN_WARNING MOD "%s: unknown control cmd %u\n", - pci_name(ctx->lldi.pdev), control); - break; - } - return 0; -} - static struct cxgb4_uld_info c4iw_uld_info = { .name = DRV_NAME, .add = c4iw_uld_add, .rx_handler = c4iw_uld_rx_handler, .state_change = c4iw_uld_state_change, - .control = c4iw_uld_control, }; static int __init c4iw_init_module(void) diff --git a/trunk/drivers/infiniband/hw/cxgb4/ev.c b/trunk/drivers/infiniband/hw/cxgb4/ev.c index cf2f6b47617a..397cb36cf103 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/ev.c +++ b/trunk/drivers/infiniband/hw/cxgb4/ev.c @@ -84,7 +84,7 @@ void c4iw_ev_dispatch(struct c4iw_dev *dev, struct t4_cqe *err_cqe) struct c4iw_qp *qhp; u32 cqid; - spin_lock_irq(&dev->lock); + spin_lock(&dev->lock); qhp = get_qhp(dev, CQE_QPID(err_cqe)); if (!qhp) { printk(KERN_ERR MOD "BAD AE qpid 0x%x opcode %d " @@ -93,7 +93,7 @@ void c4iw_ev_dispatch(struct c4iw_dev *dev, struct t4_cqe *err_cqe) CQE_OPCODE(err_cqe), CQE_STATUS(err_cqe), CQE_TYPE(err_cqe), CQE_WRID_HI(err_cqe), CQE_WRID_LOW(err_cqe)); - spin_unlock_irq(&dev->lock); + spin_unlock(&dev->lock); goto out; } @@ -109,13 +109,13 @@ void c4iw_ev_dispatch(struct c4iw_dev *dev, struct t4_cqe *err_cqe) CQE_OPCODE(err_cqe), CQE_STATUS(err_cqe), CQE_TYPE(err_cqe), CQE_WRID_HI(err_cqe), CQE_WRID_LOW(err_cqe)); - spin_unlock_irq(&dev->lock); + spin_unlock(&dev->lock); goto out; } c4iw_qp_add_ref(&qhp->ibqp); atomic_inc(&chp->refcnt); - spin_unlock_irq(&dev->lock); + spin_unlock(&dev->lock); /* Bad incoming write */ if (RQ_TYPE(err_cqe) && diff --git a/trunk/drivers/infiniband/hw/cxgb4/id_table.c b/trunk/drivers/infiniband/hw/cxgb4/id_table.c deleted file mode 100644 index f95e5df30db2..000000000000 --- a/trunk/drivers/infiniband/hw/cxgb4/id_table.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2011 Chelsio Communications. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include -#include -#include "iw_cxgb4.h" - -#define RANDOM_SKIP 16 - -/* - * Trivial bitmap-based allocator. If the random flag is set, the - * allocator is designed to: - * - pseudo-randomize the id returned such that it is not trivially predictable. - * - avoid reuse of recently used id (at the expense of predictability) - */ -u32 c4iw_id_alloc(struct c4iw_id_table *alloc) -{ - unsigned long flags; - u32 obj; - - spin_lock_irqsave(&alloc->lock, flags); - - obj = find_next_zero_bit(alloc->table, alloc->max, alloc->last); - if (obj >= alloc->max) - obj = find_first_zero_bit(alloc->table, alloc->max); - - if (obj < alloc->max) { - if (alloc->flags & C4IW_ID_TABLE_F_RANDOM) - alloc->last += random32() % RANDOM_SKIP; - else - alloc->last = obj + 1; - if (alloc->last >= alloc->max) - alloc->last = 0; - set_bit(obj, alloc->table); - obj += alloc->start; - } else - obj = -1; - - spin_unlock_irqrestore(&alloc->lock, flags); - return obj; -} - -void c4iw_id_free(struct c4iw_id_table *alloc, u32 obj) -{ - unsigned long flags; - - obj -= alloc->start; - BUG_ON((int)obj < 0); - - spin_lock_irqsave(&alloc->lock, flags); - clear_bit(obj, alloc->table); - spin_unlock_irqrestore(&alloc->lock, flags); -} - -int c4iw_id_table_alloc(struct c4iw_id_table *alloc, u32 start, u32 num, - u32 reserved, u32 flags) -{ - int i; - - alloc->start = start; - alloc->flags = flags; - if (flags & C4IW_ID_TABLE_F_RANDOM) - alloc->last = random32() % RANDOM_SKIP; - else - alloc->last = 0; - alloc->max = num; - spin_lock_init(&alloc->lock); - alloc->table = kmalloc(BITS_TO_LONGS(num) * sizeof(long), - GFP_KERNEL); - if (!alloc->table) - return -ENOMEM; - - bitmap_zero(alloc->table, num); - if (!(alloc->flags & C4IW_ID_TABLE_F_EMPTY)) - for (i = 0; i < reserved; ++i) - set_bit(i, alloc->table); - - return 0; -} - -void c4iw_id_table_free(struct c4iw_id_table *alloc) -{ - kfree(alloc->table); -} diff --git a/trunk/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/trunk/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index 9beb3a9f0336..1357c5bf209b 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/trunk/drivers/infiniband/hw/cxgb4/iw_cxgb4.h @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -78,22 +79,13 @@ static inline void *cplhdr(struct sk_buff *skb) return skb->data; } -#define C4IW_ID_TABLE_F_RANDOM 1 /* Pseudo-randomize the id's returned */ -#define C4IW_ID_TABLE_F_EMPTY 2 /* Table is initially empty */ - -struct c4iw_id_table { - u32 flags; - u32 start; /* logical minimal id */ - u32 last; /* hint for find */ - u32 max; - spinlock_t lock; - unsigned long *table; -}; - struct c4iw_resource { - struct c4iw_id_table tpt_table; - struct c4iw_id_table qid_table; - struct c4iw_id_table pdid_table; + struct kfifo tpt_fifo; + spinlock_t tpt_fifo_lock; + struct kfifo qid_fifo; + spinlock_t qid_fifo_lock; + struct kfifo pdid_fifo; + spinlock_t pdid_fifo_lock; }; struct c4iw_qid_list { @@ -111,27 +103,6 @@ enum c4iw_rdev_flags { T4_FATAL_ERROR = (1<<0), }; -struct c4iw_stat { - u64 total; - u64 cur; - u64 max; - u64 fail; -}; - -struct c4iw_stats { - struct mutex lock; - struct c4iw_stat qid; - struct c4iw_stat pd; - struct c4iw_stat stag; - struct c4iw_stat pbl; - struct c4iw_stat rqt; - struct c4iw_stat ocqp; - u64 db_full; - u64 db_empty; - u64 db_drop; - u64 db_state_transitions; -}; - struct c4iw_rdev { struct c4iw_resource resource; unsigned long qpshift; @@ -146,7 +117,6 @@ struct c4iw_rdev { struct cxgb4_lld_info lldi; unsigned long oc_mw_pa; void __iomem *oc_mw_kva; - struct c4iw_stats stats; }; static inline int c4iw_fatal_error(struct c4iw_rdev *rdev) @@ -205,12 +175,6 @@ static inline int c4iw_wait_for_reply(struct c4iw_rdev *rdev, return wr_waitp->ret; } -enum db_state { - NORMAL = 0, - FLOW_CONTROL = 1, - RECOVERY = 2 -}; - struct c4iw_dev { struct ib_device ibdev; struct c4iw_rdev rdev; @@ -219,10 +183,7 @@ struct c4iw_dev { struct idr qpidr; struct idr mmidr; spinlock_t lock; - struct mutex db_mutex; struct dentry *debugfs_root; - enum db_state db_state; - int qpcnt; }; static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev) @@ -250,57 +211,29 @@ static inline struct c4iw_mr *get_mhp(struct c4iw_dev *rhp, u32 mmid) return idr_find(&rhp->mmidr, mmid); } -static inline int _insert_handle(struct c4iw_dev *rhp, struct idr *idr, - void *handle, u32 id, int lock) +static inline int insert_handle(struct c4iw_dev *rhp, struct idr *idr, + void *handle, u32 id) { int ret; int newid; do { - if (!idr_pre_get(idr, lock ? GFP_KERNEL : GFP_ATOMIC)) + if (!idr_pre_get(idr, GFP_KERNEL)) return -ENOMEM; - if (lock) - spin_lock_irq(&rhp->lock); + spin_lock_irq(&rhp->lock); ret = idr_get_new_above(idr, handle, id, &newid); - BUG_ON(!ret && newid != id); - if (lock) - spin_unlock_irq(&rhp->lock); + BUG_ON(newid != id); + spin_unlock_irq(&rhp->lock); } while (ret == -EAGAIN); return ret; } -static inline int insert_handle(struct c4iw_dev *rhp, struct idr *idr, - void *handle, u32 id) -{ - return _insert_handle(rhp, idr, handle, id, 1); -} - -static inline int insert_handle_nolock(struct c4iw_dev *rhp, struct idr *idr, - void *handle, u32 id) -{ - return _insert_handle(rhp, idr, handle, id, 0); -} - -static inline void _remove_handle(struct c4iw_dev *rhp, struct idr *idr, - u32 id, int lock) -{ - if (lock) - spin_lock_irq(&rhp->lock); - idr_remove(idr, id); - if (lock) - spin_unlock_irq(&rhp->lock); -} - static inline void remove_handle(struct c4iw_dev *rhp, struct idr *idr, u32 id) { - _remove_handle(rhp, idr, id, 1); -} - -static inline void remove_handle_nolock(struct c4iw_dev *rhp, - struct idr *idr, u32 id) -{ - _remove_handle(rhp, idr, id, 0); + spin_lock_irq(&rhp->lock); + idr_remove(idr, id); + spin_unlock_irq(&rhp->lock); } struct c4iw_pd { @@ -420,8 +353,6 @@ struct c4iw_qp_attributes { struct c4iw_ep *llp_stream_handle; u8 layer_etype; u8 ecode; - u16 sq_db_inc; - u16 rq_db_inc; }; struct c4iw_qp { @@ -496,8 +427,6 @@ static inline void insert_mmap(struct c4iw_ucontext *ucontext, enum c4iw_qp_attr_mask { C4IW_QP_ATTR_NEXT_STATE = 1 << 0, - C4IW_QP_ATTR_SQ_DB = 1<<1, - C4IW_QP_ATTR_RQ_DB = 1<<2, C4IW_QP_ATTR_ENABLE_RDMA_READ = 1 << 7, C4IW_QP_ATTR_ENABLE_RDMA_WRITE = 1 << 8, C4IW_QP_ATTR_ENABLE_RDMA_BIND = 1 << 9, @@ -551,23 +480,6 @@ static inline int c4iw_convert_state(enum ib_qp_state ib_state) } } -static inline int to_ib_qp_state(int c4iw_qp_state) -{ - switch (c4iw_qp_state) { - case C4IW_QP_STATE_IDLE: - return IB_QPS_INIT; - case C4IW_QP_STATE_RTS: - return IB_QPS_RTS; - case C4IW_QP_STATE_CLOSING: - return IB_QPS_SQD; - case C4IW_QP_STATE_TERMINATE: - return IB_QPS_SQE; - case C4IW_QP_STATE_ERROR: - return IB_QPS_ERR; - } - return IB_QPS_ERR; -} - static inline u32 c4iw_ib_to_tpt_access(int a) { return (a & IB_ACCESS_REMOTE_WRITE ? FW_RI_MEM_ACCESS_REM_WRITE : 0) | @@ -781,20 +693,14 @@ static inline int compute_wscale(int win) return wscale; } -u32 c4iw_id_alloc(struct c4iw_id_table *alloc); -void c4iw_id_free(struct c4iw_id_table *alloc, u32 obj); -int c4iw_id_table_alloc(struct c4iw_id_table *alloc, u32 start, u32 num, - u32 reserved, u32 flags); -void c4iw_id_table_free(struct c4iw_id_table *alloc); - typedef int (*c4iw_handler_func)(struct c4iw_dev *dev, struct sk_buff *skb); int c4iw_ep_redirect(void *ctx, struct dst_entry *old, struct dst_entry *new, struct l2t_entry *l2t); void c4iw_put_qpid(struct c4iw_rdev *rdev, u32 qpid, struct c4iw_dev_ucontext *uctx); -u32 c4iw_get_resource(struct c4iw_id_table *id_table); -void c4iw_put_resource(struct c4iw_id_table *id_table, u32 entry); +u32 c4iw_get_resource(struct kfifo *fifo, spinlock_t *lock); +void c4iw_put_resource(struct kfifo *fifo, u32 entry, spinlock_t *lock); int c4iw_init_resource(struct c4iw_rdev *rdev, u32 nr_tpt, u32 nr_pdid); int c4iw_init_ctrl_qp(struct c4iw_rdev *rdev); int c4iw_pblpool_create(struct c4iw_rdev *rdev); @@ -863,8 +769,6 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_udata *udata); int c4iw_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, struct ib_udata *udata); -int c4iw_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, - int attr_mask, struct ib_qp_init_attr *init_attr); struct ib_qp *c4iw_get_qp(struct ib_device *dev, int qpn); u32 c4iw_rqtpool_alloc(struct c4iw_rdev *rdev, int size); void c4iw_rqtpool_free(struct c4iw_rdev *rdev, u32 addr, int size); @@ -893,7 +797,5 @@ void c4iw_ev_dispatch(struct c4iw_dev *dev, struct t4_cqe *err_cqe); extern struct cxgb4_client t4c_client; extern c4iw_handler_func c4iw_handlers[NUM_CPL_CMDS]; extern int c4iw_max_read_depth; -extern int db_fc_threshold; - #endif diff --git a/trunk/drivers/infiniband/hw/cxgb4/mem.c b/trunk/drivers/infiniband/hw/cxgb4/mem.c index 57e07c61ace2..40c835309e49 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/mem.c +++ b/trunk/drivers/infiniband/hw/cxgb4/mem.c @@ -131,14 +131,10 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry, stag_idx = (*stag) >> 8; if ((!reset_tpt_entry) && (*stag == T4_STAG_UNSET)) { - stag_idx = c4iw_get_resource(&rdev->resource.tpt_table); + stag_idx = c4iw_get_resource(&rdev->resource.tpt_fifo, + &rdev->resource.tpt_fifo_lock); if (!stag_idx) return -ENOMEM; - mutex_lock(&rdev->stats.lock); - rdev->stats.stag.cur += 32; - if (rdev->stats.stag.cur > rdev->stats.stag.max) - rdev->stats.stag.max = rdev->stats.stag.cur; - mutex_unlock(&rdev->stats.lock); *stag = (stag_idx << 8) | (atomic_inc_return(&key) & 0xff); } PDBG("%s stag_state 0x%0x type 0x%0x pdid 0x%0x, stag_idx 0x%x\n", @@ -169,12 +165,9 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry, (rdev->lldi.vr->stag.start >> 5), sizeof(tpt), &tpt); - if (reset_tpt_entry) { - c4iw_put_resource(&rdev->resource.tpt_table, stag_idx); - mutex_lock(&rdev->stats.lock); - rdev->stats.stag.cur -= 32; - mutex_unlock(&rdev->stats.lock); - } + if (reset_tpt_entry) + c4iw_put_resource(&rdev->resource.tpt_fifo, stag_idx, + &rdev->resource.tpt_fifo_lock); return err; } @@ -693,8 +686,8 @@ int c4iw_dealloc_mw(struct ib_mw *mw) mhp = to_c4iw_mw(mw); rhp = mhp->rhp; mmid = (mw->rkey) >> 8; - remove_handle(rhp, &rhp->mmidr, mmid); deallocate_window(&rhp->rdev, mhp->attr.stag); + remove_handle(rhp, &rhp->mmidr, mmid); kfree(mhp); PDBG("%s ib_mw %p mmid 0x%x ptr %p\n", __func__, mw, mmid, mhp); return 0; @@ -796,12 +789,12 @@ int c4iw_dereg_mr(struct ib_mr *ib_mr) mhp = to_c4iw_mr(ib_mr); rhp = mhp->rhp; mmid = mhp->attr.stag >> 8; - remove_handle(rhp, &rhp->mmidr, mmid); dereg_mem(&rhp->rdev, mhp->attr.stag, mhp->attr.pbl_size, mhp->attr.pbl_addr); if (mhp->attr.pbl_size) c4iw_pblpool_free(&mhp->rhp->rdev, mhp->attr.pbl_addr, mhp->attr.pbl_size << 3); + remove_handle(rhp, &rhp->mmidr, mmid); if (mhp->kva) kfree((void *) (unsigned long) mhp->kva); if (mhp->umem) diff --git a/trunk/drivers/infiniband/hw/cxgb4/provider.c b/trunk/drivers/infiniband/hw/cxgb4/provider.c index e084fdc6da7f..be1c18f44400 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/provider.c +++ b/trunk/drivers/infiniband/hw/cxgb4/provider.c @@ -188,10 +188,8 @@ static int c4iw_deallocate_pd(struct ib_pd *pd) php = to_c4iw_pd(pd); rhp = php->rhp; PDBG("%s ibpd %p pdid 0x%x\n", __func__, pd, php->pdid); - c4iw_put_resource(&rhp->rdev.resource.pdid_table, php->pdid); - mutex_lock(&rhp->rdev.stats.lock); - rhp->rdev.stats.pd.cur--; - mutex_unlock(&rhp->rdev.stats.lock); + c4iw_put_resource(&rhp->rdev.resource.pdid_fifo, php->pdid, + &rhp->rdev.resource.pdid_fifo_lock); kfree(php); return 0; } @@ -206,12 +204,14 @@ static struct ib_pd *c4iw_allocate_pd(struct ib_device *ibdev, PDBG("%s ibdev %p\n", __func__, ibdev); rhp = (struct c4iw_dev *) ibdev; - pdid = c4iw_get_resource(&rhp->rdev.resource.pdid_table); + pdid = c4iw_get_resource(&rhp->rdev.resource.pdid_fifo, + &rhp->rdev.resource.pdid_fifo_lock); if (!pdid) return ERR_PTR(-EINVAL); php = kzalloc(sizeof(*php), GFP_KERNEL); if (!php) { - c4iw_put_resource(&rhp->rdev.resource.pdid_table, pdid); + c4iw_put_resource(&rhp->rdev.resource.pdid_fifo, pdid, + &rhp->rdev.resource.pdid_fifo_lock); return ERR_PTR(-ENOMEM); } php->pdid = pdid; @@ -222,11 +222,6 @@ static struct ib_pd *c4iw_allocate_pd(struct ib_device *ibdev, return ERR_PTR(-EFAULT); } } - mutex_lock(&rhp->rdev.stats.lock); - rhp->rdev.stats.pd.cur++; - if (rhp->rdev.stats.pd.cur > rhp->rdev.stats.pd.max) - rhp->rdev.stats.pd.max = rhp->rdev.stats.pd.cur; - mutex_unlock(&rhp->rdev.stats.lock); PDBG("%s pdid 0x%0x ptr 0x%p\n", __func__, pdid, php); return &php->ibpd; } @@ -443,7 +438,6 @@ int c4iw_register_device(struct c4iw_dev *dev) (1ull << IB_USER_VERBS_CMD_REQ_NOTIFY_CQ) | (1ull << IB_USER_VERBS_CMD_CREATE_QP) | (1ull << IB_USER_VERBS_CMD_MODIFY_QP) | - (1ull << IB_USER_VERBS_CMD_QUERY_QP) | (1ull << IB_USER_VERBS_CMD_POLL_CQ) | (1ull << IB_USER_VERBS_CMD_DESTROY_QP) | (1ull << IB_USER_VERBS_CMD_POST_SEND) | @@ -466,7 +460,6 @@ int c4iw_register_device(struct c4iw_dev *dev) dev->ibdev.destroy_ah = c4iw_ah_destroy; dev->ibdev.create_qp = c4iw_create_qp; dev->ibdev.modify_qp = c4iw_ib_modify_qp; - dev->ibdev.query_qp = c4iw_ib_query_qp; dev->ibdev.destroy_qp = c4iw_destroy_qp; dev->ibdev.create_cq = c4iw_create_cq; dev->ibdev.destroy_cq = c4iw_destroy_cq; diff --git a/trunk/drivers/infiniband/hw/cxgb4/qp.c b/trunk/drivers/infiniband/hw/cxgb4/qp.c index 45aedf1d9338..5f940aeaab1e 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/qp.c +++ b/trunk/drivers/infiniband/hw/cxgb4/qp.c @@ -34,19 +34,10 @@ #include "iw_cxgb4.h" -static int db_delay_usecs = 1; -module_param(db_delay_usecs, int, 0644); -MODULE_PARM_DESC(db_delay_usecs, "Usecs to delay awaiting db fifo to drain"); - static int ocqp_support = 1; module_param(ocqp_support, int, 0644); MODULE_PARM_DESC(ocqp_support, "Support on-chip SQs (default=1)"); -int db_fc_threshold = 2000; -module_param(db_fc_threshold, int, 0644); -MODULE_PARM_DESC(db_fc_threshold, "QP count/threshold that triggers automatic " - "db flow control mode (default = 2000)"); - static void set_state(struct c4iw_qp *qhp, enum c4iw_qp_state state) { unsigned long flag; @@ -1137,35 +1128,6 @@ static int rdma_init(struct c4iw_dev *rhp, struct c4iw_qp *qhp) return ret; } -/* - * Called by the library when the qp has user dbs disabled due to - * a DB_FULL condition. This function will single-thread all user - * DB rings to avoid overflowing the hw db-fifo. - */ -static int ring_kernel_db(struct c4iw_qp *qhp, u32 qid, u16 inc) -{ - int delay = db_delay_usecs; - - mutex_lock(&qhp->rhp->db_mutex); - do { - - /* - * The interrupt threshold is dbfifo_int_thresh << 6. So - * make sure we don't cross that and generate an interrupt. - */ - if (cxgb4_dbfifo_count(qhp->rhp->rdev.lldi.ports[0], 1) < - (qhp->rhp->rdev.lldi.dbfifo_int_thresh << 5)) { - writel(V_QID(qid) | V_PIDX(inc), qhp->wq.db); - break; - } - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(usecs_to_jiffies(delay)); - delay = min(delay << 1, 2000); - } while (1); - mutex_unlock(&qhp->rhp->db_mutex); - return 0; -} - int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, enum c4iw_qp_attr_mask mask, struct c4iw_qp_attributes *attrs, @@ -1214,15 +1176,6 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, qhp->attr = newattr; } - if (mask & C4IW_QP_ATTR_SQ_DB) { - ret = ring_kernel_db(qhp, qhp->wq.sq.qid, attrs->sq_db_inc); - goto out; - } - if (mask & C4IW_QP_ATTR_RQ_DB) { - ret = ring_kernel_db(qhp, qhp->wq.rq.qid, attrs->rq_db_inc); - goto out; - } - if (!(mask & C4IW_QP_ATTR_NEXT_STATE)) goto out; if (qhp->attr.state == attrs->next_state) @@ -1399,14 +1352,6 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, return ret; } -static int enable_qp_db(int id, void *p, void *data) -{ - struct c4iw_qp *qp = p; - - t4_enable_wq_db(&qp->wq); - return 0; -} - int c4iw_destroy_qp(struct ib_qp *ib_qp) { struct c4iw_dev *rhp; @@ -1424,16 +1369,7 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp) c4iw_modify_qp(rhp, qhp, C4IW_QP_ATTR_NEXT_STATE, &attrs, 0); wait_event(qhp->wait, !qhp->ep); - spin_lock_irq(&rhp->lock); - remove_handle_nolock(rhp, &rhp->qpidr, qhp->wq.sq.qid); - rhp->qpcnt--; - BUG_ON(rhp->qpcnt < 0); - if (rhp->qpcnt <= db_fc_threshold && rhp->db_state == FLOW_CONTROL) { - rhp->rdev.stats.db_state_transitions++; - rhp->db_state = NORMAL; - idr_for_each(&rhp->qpidr, enable_qp_db, NULL); - } - spin_unlock_irq(&rhp->lock); + remove_handle(rhp, &rhp->qpidr, qhp->wq.sq.qid); atomic_dec(&qhp->refcnt); wait_event(qhp->wait, !atomic_read(&qhp->refcnt)); @@ -1447,14 +1383,6 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp) return 0; } -static int disable_qp_db(int id, void *p, void *data) -{ - struct c4iw_qp *qp = p; - - t4_disable_wq_db(&qp->wq); - return 0; -} - struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, struct ib_udata *udata) { @@ -1541,16 +1469,7 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, init_waitqueue_head(&qhp->wait); atomic_set(&qhp->refcnt, 1); - spin_lock_irq(&rhp->lock); - if (rhp->db_state != NORMAL) - t4_disable_wq_db(&qhp->wq); - if (++rhp->qpcnt > db_fc_threshold && rhp->db_state == NORMAL) { - rhp->rdev.stats.db_state_transitions++; - rhp->db_state = FLOW_CONTROL; - idr_for_each(&rhp->qpidr, disable_qp_db, NULL); - } - ret = insert_handle_nolock(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid); - spin_unlock_irq(&rhp->lock); + ret = insert_handle(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid); if (ret) goto err2; @@ -1694,15 +1613,6 @@ int c4iw_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, C4IW_QP_ATTR_ENABLE_RDMA_WRITE | C4IW_QP_ATTR_ENABLE_RDMA_BIND) : 0; - /* - * Use SQ_PSN and RQ_PSN to pass in IDX_INC values for - * ringing the queue db when we're in DB_FULL mode. - */ - attrs.sq_db_inc = attr->sq_psn; - attrs.rq_db_inc = attr->rq_psn; - mask |= (attr_mask & IB_QP_SQ_PSN) ? C4IW_QP_ATTR_SQ_DB : 0; - mask |= (attr_mask & IB_QP_RQ_PSN) ? C4IW_QP_ATTR_RQ_DB : 0; - return c4iw_modify_qp(rhp, qhp, mask, &attrs, 0); } @@ -1711,14 +1621,3 @@ struct ib_qp *c4iw_get_qp(struct ib_device *dev, int qpn) PDBG("%s ib_dev %p qpn 0x%x\n", __func__, dev, qpn); return (struct ib_qp *)get_qhp(to_c4iw_dev(dev), qpn); } - -int c4iw_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, - int attr_mask, struct ib_qp_init_attr *init_attr) -{ - struct c4iw_qp *qhp = to_c4iw_qp(ibqp); - - memset(attr, 0, sizeof *attr); - memset(init_attr, 0, sizeof *init_attr); - attr->qp_state = to_ib_qp_state(qhp->attr.state); - return 0; -} diff --git a/trunk/drivers/infiniband/hw/cxgb4/resource.c b/trunk/drivers/infiniband/hw/cxgb4/resource.c index cdef4d7fb6d8..407ff3924150 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/resource.c +++ b/trunk/drivers/infiniband/hw/cxgb4/resource.c @@ -30,25 +30,96 @@ * SOFTWARE. */ /* Crude resource management */ +#include +#include +#include +#include #include +#include #include #include #include "iw_cxgb4.h" -static int c4iw_init_qid_table(struct c4iw_rdev *rdev) +#define RANDOM_SIZE 16 + +static int __c4iw_init_resource_fifo(struct kfifo *fifo, + spinlock_t *fifo_lock, + u32 nr, u32 skip_low, + u32 skip_high, + int random) +{ + u32 i, j, entry = 0, idx; + u32 random_bytes; + u32 rarray[16]; + spin_lock_init(fifo_lock); + + if (kfifo_alloc(fifo, nr * sizeof(u32), GFP_KERNEL)) + return -ENOMEM; + + for (i = 0; i < skip_low + skip_high; i++) + kfifo_in(fifo, (unsigned char *) &entry, sizeof(u32)); + if (random) { + j = 0; + random_bytes = random32(); + for (i = 0; i < RANDOM_SIZE; i++) + rarray[i] = i + skip_low; + for (i = skip_low + RANDOM_SIZE; i < nr - skip_high; i++) { + if (j >= RANDOM_SIZE) { + j = 0; + random_bytes = random32(); + } + idx = (random_bytes >> (j * 2)) & 0xF; + kfifo_in(fifo, + (unsigned char *) &rarray[idx], + sizeof(u32)); + rarray[idx] = i; + j++; + } + for (i = 0; i < RANDOM_SIZE; i++) + kfifo_in(fifo, + (unsigned char *) &rarray[i], + sizeof(u32)); + } else + for (i = skip_low; i < nr - skip_high; i++) + kfifo_in(fifo, (unsigned char *) &i, sizeof(u32)); + + for (i = 0; i < skip_low + skip_high; i++) + if (kfifo_out_locked(fifo, (unsigned char *) &entry, + sizeof(u32), fifo_lock)) + break; + return 0; +} + +static int c4iw_init_resource_fifo(struct kfifo *fifo, spinlock_t * fifo_lock, + u32 nr, u32 skip_low, u32 skip_high) +{ + return __c4iw_init_resource_fifo(fifo, fifo_lock, nr, skip_low, + skip_high, 0); +} + +static int c4iw_init_resource_fifo_random(struct kfifo *fifo, + spinlock_t *fifo_lock, + u32 nr, u32 skip_low, u32 skip_high) +{ + return __c4iw_init_resource_fifo(fifo, fifo_lock, nr, skip_low, + skip_high, 1); +} + +static int c4iw_init_qid_fifo(struct c4iw_rdev *rdev) { u32 i; - if (c4iw_id_table_alloc(&rdev->resource.qid_table, - rdev->lldi.vr->qp.start, - rdev->lldi.vr->qp.size, - rdev->lldi.vr->qp.size, 0)) + spin_lock_init(&rdev->resource.qid_fifo_lock); + + if (kfifo_alloc(&rdev->resource.qid_fifo, rdev->lldi.vr->qp.size * + sizeof(u32), GFP_KERNEL)) return -ENOMEM; for (i = rdev->lldi.vr->qp.start; - i < rdev->lldi.vr->qp.start + rdev->lldi.vr->qp.size; i++) + i < rdev->lldi.vr->qp.start + rdev->lldi.vr->qp.size; i++) if (!(i & rdev->qpmask)) - c4iw_id_free(&rdev->resource.qid_table, i); + kfifo_in(&rdev->resource.qid_fifo, + (unsigned char *) &i, sizeof(u32)); return 0; } @@ -56,42 +127,44 @@ static int c4iw_init_qid_table(struct c4iw_rdev *rdev) int c4iw_init_resource(struct c4iw_rdev *rdev, u32 nr_tpt, u32 nr_pdid) { int err = 0; - err = c4iw_id_table_alloc(&rdev->resource.tpt_table, 0, nr_tpt, 1, - C4IW_ID_TABLE_F_RANDOM); + err = c4iw_init_resource_fifo_random(&rdev->resource.tpt_fifo, + &rdev->resource.tpt_fifo_lock, + nr_tpt, 1, 0); if (err) goto tpt_err; - err = c4iw_init_qid_table(rdev); + err = c4iw_init_qid_fifo(rdev); if (err) goto qid_err; - err = c4iw_id_table_alloc(&rdev->resource.pdid_table, 0, - nr_pdid, 1, 0); + err = c4iw_init_resource_fifo(&rdev->resource.pdid_fifo, + &rdev->resource.pdid_fifo_lock, + nr_pdid, 1, 0); if (err) goto pdid_err; return 0; - pdid_err: - c4iw_id_table_free(&rdev->resource.qid_table); - qid_err: - c4iw_id_table_free(&rdev->resource.tpt_table); - tpt_err: +pdid_err: + kfifo_free(&rdev->resource.qid_fifo); +qid_err: + kfifo_free(&rdev->resource.tpt_fifo); +tpt_err: return -ENOMEM; } /* * returns 0 if no resource available */ -u32 c4iw_get_resource(struct c4iw_id_table *id_table) +u32 c4iw_get_resource(struct kfifo *fifo, spinlock_t *lock) { u32 entry; - entry = c4iw_id_alloc(id_table); - if (entry == (u32)(-1)) + if (kfifo_out_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock)) + return entry; + else return 0; - return entry; } -void c4iw_put_resource(struct c4iw_id_table *id_table, u32 entry) +void c4iw_put_resource(struct kfifo *fifo, u32 entry, spinlock_t *lock) { PDBG("%s entry 0x%x\n", __func__, entry); - c4iw_id_free(id_table, entry); + kfifo_in_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock); } u32 c4iw_get_cqid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx) @@ -108,12 +181,10 @@ u32 c4iw_get_cqid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx) qid = entry->qid; kfree(entry); } else { - qid = c4iw_get_resource(&rdev->resource.qid_table); + qid = c4iw_get_resource(&rdev->resource.qid_fifo, + &rdev->resource.qid_fifo_lock); if (!qid) goto out; - mutex_lock(&rdev->stats.lock); - rdev->stats.qid.cur += rdev->qpmask + 1; - mutex_unlock(&rdev->stats.lock); for (i = qid+1; i & rdev->qpmask; i++) { entry = kmalloc(sizeof *entry, GFP_KERNEL); if (!entry) @@ -142,10 +213,6 @@ u32 c4iw_get_cqid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx) out: mutex_unlock(&uctx->lock); PDBG("%s qid 0x%x\n", __func__, qid); - mutex_lock(&rdev->stats.lock); - if (rdev->stats.qid.cur > rdev->stats.qid.max) - rdev->stats.qid.max = rdev->stats.qid.cur; - mutex_unlock(&rdev->stats.lock); return qid; } @@ -178,12 +245,10 @@ u32 c4iw_get_qpid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx) qid = entry->qid; kfree(entry); } else { - qid = c4iw_get_resource(&rdev->resource.qid_table); + qid = c4iw_get_resource(&rdev->resource.qid_fifo, + &rdev->resource.qid_fifo_lock); if (!qid) goto out; - mutex_lock(&rdev->stats.lock); - rdev->stats.qid.cur += rdev->qpmask + 1; - mutex_unlock(&rdev->stats.lock); for (i = qid+1; i & rdev->qpmask; i++) { entry = kmalloc(sizeof *entry, GFP_KERNEL); if (!entry) @@ -212,10 +277,6 @@ u32 c4iw_get_qpid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx) out: mutex_unlock(&uctx->lock); PDBG("%s qid 0x%x\n", __func__, qid); - mutex_lock(&rdev->stats.lock); - if (rdev->stats.qid.cur > rdev->stats.qid.max) - rdev->stats.qid.max = rdev->stats.qid.cur; - mutex_unlock(&rdev->stats.lock); return qid; } @@ -236,9 +297,9 @@ void c4iw_put_qpid(struct c4iw_rdev *rdev, u32 qid, void c4iw_destroy_resource(struct c4iw_resource *rscp) { - c4iw_id_table_free(&rscp->tpt_table); - c4iw_id_table_free(&rscp->qid_table); - c4iw_id_table_free(&rscp->pdid_table); + kfifo_free(&rscp->tpt_fifo); + kfifo_free(&rscp->qid_fifo); + kfifo_free(&rscp->pdid_fifo); } /* @@ -251,23 +312,15 @@ u32 c4iw_pblpool_alloc(struct c4iw_rdev *rdev, int size) { unsigned long addr = gen_pool_alloc(rdev->pbl_pool, size); PDBG("%s addr 0x%x size %d\n", __func__, (u32)addr, size); - mutex_lock(&rdev->stats.lock); - if (addr) { - rdev->stats.pbl.cur += roundup(size, 1 << MIN_PBL_SHIFT); - if (rdev->stats.pbl.cur > rdev->stats.pbl.max) - rdev->stats.pbl.max = rdev->stats.pbl.cur; - } else - rdev->stats.pbl.fail++; - mutex_unlock(&rdev->stats.lock); + if (!addr) + printk_ratelimited(KERN_WARNING MOD "%s: Out of PBL memory\n", + pci_name(rdev->lldi.pdev)); return (u32)addr; } void c4iw_pblpool_free(struct c4iw_rdev *rdev, u32 addr, int size) { PDBG("%s addr 0x%x size %d\n", __func__, addr, size); - mutex_lock(&rdev->stats.lock); - rdev->stats.pbl.cur -= roundup(size, 1 << MIN_PBL_SHIFT); - mutex_unlock(&rdev->stats.lock); gen_pool_free(rdev->pbl_pool, (unsigned long)addr, size); } @@ -324,23 +377,12 @@ u32 c4iw_rqtpool_alloc(struct c4iw_rdev *rdev, int size) if (!addr) printk_ratelimited(KERN_WARNING MOD "%s: Out of RQT memory\n", pci_name(rdev->lldi.pdev)); - mutex_lock(&rdev->stats.lock); - if (addr) { - rdev->stats.rqt.cur += roundup(size << 6, 1 << MIN_RQT_SHIFT); - if (rdev->stats.rqt.cur > rdev->stats.rqt.max) - rdev->stats.rqt.max = rdev->stats.rqt.cur; - } else - rdev->stats.rqt.fail++; - mutex_unlock(&rdev->stats.lock); return (u32)addr; } void c4iw_rqtpool_free(struct c4iw_rdev *rdev, u32 addr, int size) { PDBG("%s addr 0x%x size %d\n", __func__, addr, size << 6); - mutex_lock(&rdev->stats.lock); - rdev->stats.rqt.cur -= roundup(size << 6, 1 << MIN_RQT_SHIFT); - mutex_unlock(&rdev->stats.lock); gen_pool_free(rdev->rqt_pool, (unsigned long)addr, size << 6); } @@ -391,22 +433,12 @@ u32 c4iw_ocqp_pool_alloc(struct c4iw_rdev *rdev, int size) { unsigned long addr = gen_pool_alloc(rdev->ocqp_pool, size); PDBG("%s addr 0x%x size %d\n", __func__, (u32)addr, size); - if (addr) { - mutex_lock(&rdev->stats.lock); - rdev->stats.ocqp.cur += roundup(size, 1 << MIN_OCQP_SHIFT); - if (rdev->stats.ocqp.cur > rdev->stats.ocqp.max) - rdev->stats.ocqp.max = rdev->stats.ocqp.cur; - mutex_unlock(&rdev->stats.lock); - } return (u32)addr; } void c4iw_ocqp_pool_free(struct c4iw_rdev *rdev, u32 addr, int size) { PDBG("%s addr 0x%x size %d\n", __func__, addr, size); - mutex_lock(&rdev->stats.lock); - rdev->stats.ocqp.cur -= roundup(size, 1 << MIN_OCQP_SHIFT); - mutex_unlock(&rdev->stats.lock); gen_pool_free(rdev->ocqp_pool, (unsigned long)addr, size); } diff --git a/trunk/drivers/infiniband/hw/cxgb4/t4.h b/trunk/drivers/infiniband/hw/cxgb4/t4.h index 16f26ab29302..c0221eec8817 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/t4.h +++ b/trunk/drivers/infiniband/hw/cxgb4/t4.h @@ -62,10 +62,6 @@ struct t4_status_page { __be16 pidx; u8 qp_err; /* flit 1 - sw owns */ u8 db_off; - u8 pad; - u16 host_wq_pidx; - u16 host_cidx; - u16 host_pidx; }; #define T4_EQ_ENTRY_SIZE 64 @@ -379,16 +375,6 @@ static inline void t4_rq_consume(struct t4_wq *wq) wq->rq.cidx = 0; } -static inline u16 t4_rq_host_wq_pidx(struct t4_wq *wq) -{ - return wq->rq.queue[wq->rq.size].status.host_wq_pidx; -} - -static inline u16 t4_rq_wq_size(struct t4_wq *wq) -{ - return wq->rq.size * T4_RQ_NUM_SLOTS; -} - static inline int t4_sq_onchip(struct t4_sq *sq) { return sq->flags & T4_SQ_ONCHIP; @@ -426,16 +412,6 @@ static inline void t4_sq_consume(struct t4_wq *wq) wq->sq.cidx = 0; } -static inline u16 t4_sq_host_wq_pidx(struct t4_wq *wq) -{ - return wq->sq.queue[wq->sq.size].status.host_wq_pidx; -} - -static inline u16 t4_sq_wq_size(struct t4_wq *wq) -{ - return wq->sq.size * T4_SQ_NUM_SLOTS; -} - static inline void t4_ring_sq_db(struct t4_wq *wq, u16 inc) { wmb(); diff --git a/trunk/drivers/infiniband/hw/cxgb4/user.h b/trunk/drivers/infiniband/hw/cxgb4/user.h index 32b754c35ab7..e6669d54770e 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/user.h +++ b/trunk/drivers/infiniband/hw/cxgb4/user.h @@ -32,7 +32,7 @@ #ifndef __C4IW_USER_H__ #define __C4IW_USER_H__ -#define C4IW_UVERBS_ABI_VERSION 2 +#define C4IW_UVERBS_ABI_VERSION 1 /* * Make sure that all structs defined in this file remain laid out so diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_iba6110.c b/trunk/drivers/infiniband/hw/ipath/ipath_iba6110.c index 7cc305488a3d..1d7aea132a09 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_iba6110.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_iba6110.c @@ -596,7 +596,8 @@ static void ipath_ht_handle_hwerrors(struct ipath_devdata *dd, char *msg, ipath_format_hwerrors(hwerrs, ipath_6110_hwerror_msgs, - ARRAY_SIZE(ipath_6110_hwerror_msgs), + sizeof(ipath_6110_hwerror_msgs) / + sizeof(ipath_6110_hwerror_msgs[0]), msg, msgl); if (hwerrs & (_IPATH_HTLINK0_CRCBITS | _IPATH_HTLINK1_CRCBITS)) diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_intr.c b/trunk/drivers/infiniband/hw/ipath/ipath_intr.c index 26dfbc8ee0f1..c0a03ac03ee7 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_intr.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_intr.c @@ -209,7 +209,8 @@ void ipath_format_hwerrors(u64 hwerrs, { int i; const int glen = - ARRAY_SIZE(ipath_generic_hwerror_msgs); + sizeof(ipath_generic_hwerror_msgs) / + sizeof(ipath_generic_hwerror_msgs[0]); for (i=0; icqn); return; } @@ -222,9 +222,6 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev, int entries, int vector uar = &dev->priv_uar; } - if (dev->eq_table) - vector = dev->eq_table[vector % ibdev->num_comp_vectors]; - err = mlx4_cq_alloc(dev->dev, entries, &cq->buf.mtt, uar, cq->db.dma, &cq->mcq, vector, 0); if (err) @@ -466,7 +463,7 @@ static void dump_cqe(void *cqe) { __be32 *buf = cqe; - pr_debug("CQE contents %08x %08x %08x %08x %08x %08x %08x %08x\n", + printk(KERN_DEBUG "CQE contents %08x %08x %08x %08x %08x %08x %08x %08x\n", be32_to_cpu(buf[0]), be32_to_cpu(buf[1]), be32_to_cpu(buf[2]), be32_to_cpu(buf[3]), be32_to_cpu(buf[4]), be32_to_cpu(buf[5]), be32_to_cpu(buf[6]), be32_to_cpu(buf[7])); @@ -476,7 +473,7 @@ static void mlx4_ib_handle_error_cqe(struct mlx4_err_cqe *cqe, struct ib_wc *wc) { if (cqe->syndrome == MLX4_CQE_SYNDROME_LOCAL_QP_OP_ERR) { - pr_debug("local QP operation err " + printk(KERN_DEBUG "local QP operation err " "(QPN %06x, WQE index %x, vendor syndrome %02x, " "opcode = %02x)\n", be32_to_cpu(cqe->my_qpn), be16_to_cpu(cqe->wqe_index), @@ -579,7 +576,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq, if (unlikely((cqe->owner_sr_opcode & MLX4_CQE_OPCODE_MASK) == MLX4_OPCODE_NOP && is_send)) { - pr_warn("Completion for NOP opcode detected!\n"); + printk(KERN_WARNING "Completion for NOP opcode detected!\n"); return -EINVAL; } @@ -609,7 +606,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq, mqp = __mlx4_qp_lookup(to_mdev(cq->ibcq.device)->dev, be32_to_cpu(cqe->vlan_my_qpn)); if (unlikely(!mqp)) { - pr_warn("CQ %06x with entry for unknown QPN %06x\n", + printk(KERN_WARNING "CQ %06x with entry for unknown QPN %06x\n", cq->mcq.cqn, be32_to_cpu(cqe->vlan_my_qpn) & MLX4_CQE_QPN_MASK); return -EINVAL; } diff --git a/trunk/drivers/infiniband/hw/mlx4/main.c b/trunk/drivers/infiniband/hw/mlx4/main.c index ee1c577238f7..b948b6dd5d55 100644 --- a/trunk/drivers/infiniband/hw/mlx4/main.c +++ b/trunk/drivers/infiniband/hw/mlx4/main.c @@ -789,7 +789,7 @@ static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) list_del(&ge->list); kfree(ge); } else - pr_warn("could not find mgid entry\n"); + printk(KERN_WARNING "could not find mgid entry\n"); mutex_unlock(&mqp->mutex); @@ -902,7 +902,7 @@ static void update_gids_task(struct work_struct *work) mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) { - pr_warn("update gid table failed %ld\n", PTR_ERR(mailbox)); + printk(KERN_WARNING "update gid table failed %ld\n", PTR_ERR(mailbox)); return; } @@ -913,7 +913,7 @@ static void update_gids_task(struct work_struct *work) 1, MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); if (err) - pr_warn("set port command failed\n"); + printk(KERN_WARNING "set port command failed\n"); else { memcpy(gw->dev->iboe.gid_table[gw->port - 1], gw->gids, sizeof gw->gids); event.device = &gw->dev->ib_dev; @@ -1076,98 +1076,18 @@ static int mlx4_ib_netdev_event(struct notifier_block *this, unsigned long event return NOTIFY_DONE; } -static void mlx4_ib_alloc_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) -{ - char name[32]; - int eq_per_port = 0; - int added_eqs = 0; - int total_eqs = 0; - int i, j, eq; - - /* Init eq table */ - ibdev->eq_table = NULL; - ibdev->eq_added = 0; - - /* Legacy mode? */ - if (dev->caps.comp_pool == 0) - return; - - eq_per_port = rounddown_pow_of_two(dev->caps.comp_pool/ - dev->caps.num_ports); - - /* Init eq table */ - added_eqs = 0; - mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB) - added_eqs += eq_per_port; - - total_eqs = dev->caps.num_comp_vectors + added_eqs; - - ibdev->eq_table = kzalloc(total_eqs * sizeof(int), GFP_KERNEL); - if (!ibdev->eq_table) - return; - - ibdev->eq_added = added_eqs; - - eq = 0; - mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB) { - for (j = 0; j < eq_per_port; j++) { - sprintf(name, "mlx4-ib-%d-%d@%s", - i, j, dev->pdev->bus->name); - /* Set IRQ for specific name (per ring) */ - if (mlx4_assign_eq(dev, name, &ibdev->eq_table[eq])) { - /* Use legacy (same as mlx4_en driver) */ - pr_warn("Can't allocate EQ %d; reverting to legacy\n", eq); - ibdev->eq_table[eq] = - (eq % dev->caps.num_comp_vectors); - } - eq++; - } - } - - /* Fill the reset of the vector with legacy EQ */ - for (i = 0, eq = added_eqs; i < dev->caps.num_comp_vectors; i++) - ibdev->eq_table[eq++] = i; - - /* Advertise the new number of EQs to clients */ - ibdev->ib_dev.num_comp_vectors = total_eqs; -} - -static void mlx4_ib_free_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) -{ - int i; - int total_eqs; - - /* Reset the advertised EQ number */ - ibdev->ib_dev.num_comp_vectors = dev->caps.num_comp_vectors; - - /* Free only the added eqs */ - for (i = 0; i < ibdev->eq_added; i++) { - /* Don't free legacy eqs if used */ - if (ibdev->eq_table[i] <= dev->caps.num_comp_vectors) - continue; - mlx4_release_eq(dev, ibdev->eq_table[i]); - } - - total_eqs = dev->caps.num_comp_vectors + ibdev->eq_added; - memset(ibdev->eq_table, 0, total_eqs * sizeof(int)); - kfree(ibdev->eq_table); - - ibdev->eq_table = NULL; - ibdev->eq_added = 0; -} - static void *mlx4_ib_add(struct mlx4_dev *dev) { struct mlx4_ib_dev *ibdev; int num_ports = 0; - int i, j; + int i; int err; struct mlx4_ib_iboe *iboe; - pr_info_once("%s", mlx4_ib_version); + printk_once(KERN_INFO "%s", mlx4_ib_version); if (mlx4_is_mfunc(dev)) { - pr_warn("IB not yet supported in SRIOV\n"); + printk(KERN_WARNING "IB not yet supported in SRIOV\n"); return NULL; } @@ -1290,8 +1210,6 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) (1ull << IB_USER_VERBS_CMD_CLOSE_XRCD); } - mlx4_ib_alloc_eqs(dev, ibdev); - spin_lock_init(&iboe->lock); if (init_node_data(ibdev)) @@ -1323,9 +1241,9 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) goto err_reg; } - for (j = 0; j < ARRAY_SIZE(mlx4_class_attributes); ++j) { + for (i = 0; i < ARRAY_SIZE(mlx4_class_attributes); ++i) { if (device_create_file(&ibdev->ib_dev.dev, - mlx4_class_attributes[j])) + mlx4_class_attributes[i])) goto err_notif; } @@ -1335,7 +1253,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) err_notif: if (unregister_netdevice_notifier(&ibdev->iboe.nb)) - pr_warn("failure unregistering notifier\n"); + printk(KERN_WARNING "failure unregistering notifier\n"); flush_workqueue(wq); err_reg: @@ -1370,7 +1288,7 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr) ib_unregister_device(&ibdev->ib_dev); if (ibdev->iboe.nb.notifier_call) { if (unregister_netdevice_notifier(&ibdev->iboe.nb)) - pr_warn("failure unregistering notifier\n"); + printk(KERN_WARNING "failure unregistering notifier\n"); ibdev->iboe.nb.notifier_call = NULL; } iounmap(ibdev->uar_map); @@ -1380,8 +1298,6 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr) mlx4_foreach_port(p, dev, MLX4_PORT_TYPE_IB) mlx4_CLOSE_PORT(dev, p); - mlx4_ib_free_eqs(dev, ibdev); - mlx4_uar_free(dev, &ibdev->priv_uar); mlx4_pd_free(dev, ibdev->priv_pdn); ib_dealloc_device(&ibdev->ib_dev); diff --git a/trunk/drivers/infiniband/hw/mlx4/mlx4_ib.h b/trunk/drivers/infiniband/hw/mlx4/mlx4_ib.h index e62297cc77cc..ed80345c99ae 100644 --- a/trunk/drivers/infiniband/hw/mlx4/mlx4_ib.h +++ b/trunk/drivers/infiniband/hw/mlx4/mlx4_ib.h @@ -202,8 +202,6 @@ struct mlx4_ib_dev { bool ib_active; struct mlx4_ib_iboe iboe; int counters[MLX4_MAX_PORTS]; - int *eq_table; - int eq_added; }; static inline struct mlx4_ib_dev *to_mdev(struct ib_device *ibdev) diff --git a/trunk/drivers/infiniband/hw/mlx4/mr.c b/trunk/drivers/infiniband/hw/mlx4/mr.c index bbaf6176f207..dca55b19a6f1 100644 --- a/trunk/drivers/infiniband/hw/mlx4/mr.c +++ b/trunk/drivers/infiniband/hw/mlx4/mr.c @@ -338,7 +338,7 @@ int mlx4_ib_unmap_fmr(struct list_head *fmr_list) err = mlx4_SYNC_TPT(mdev); if (err) - pr_warn("SYNC_TPT error %d when " + printk(KERN_WARNING "mlx4_ib: SYNC_TPT error %d when " "unmapping FMRs\n", err); return 0; diff --git a/trunk/drivers/infiniband/hw/mlx4/qp.c b/trunk/drivers/infiniband/hw/mlx4/qp.c index ceb33327091a..3a7848966627 100644 --- a/trunk/drivers/infiniband/hw/mlx4/qp.c +++ b/trunk/drivers/infiniband/hw/mlx4/qp.c @@ -84,11 +84,6 @@ enum { MLX4_IB_CACHE_LINE_SIZE = 64, }; -enum { - MLX4_RAW_QP_MTU = 7, - MLX4_RAW_QP_MSGMAX = 31, -}; - static const __be32 mlx4_ib_opcode[] = { [IB_WR_SEND] = cpu_to_be32(MLX4_OPCODE_SEND), [IB_WR_LSO] = cpu_to_be32(MLX4_OPCODE_LSO), @@ -261,7 +256,7 @@ static void mlx4_ib_qp_event(struct mlx4_qp *qp, enum mlx4_event type) event.event = IB_EVENT_QP_ACCESS_ERR; break; default: - pr_warn("Unexpected event type %d " + printk(KERN_WARNING "mlx4_ib: Unexpected event type %d " "on QP %06x\n", type, qp->qpn); return; } @@ -578,12 +573,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, if (sqpn) { qpn = sqpn; } else { - /* Raw packet QPNs must be aligned to 8 bits. If not, the WQE - * BlueFlame setup flow wrongly causes VLAN insertion. */ - if (init_attr->qp_type == IB_QPT_RAW_PACKET) - err = mlx4_qp_reserve_range(dev->dev, 1, 1 << 8, &qpn); - else - err = mlx4_qp_reserve_range(dev->dev, 1, 1, &qpn); + err = mlx4_qp_reserve_range(dev->dev, 1, 1, &qpn); if (err) goto err_wrid; } @@ -725,7 +715,7 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp, if (qp->state != IB_QPS_RESET) if (mlx4_qp_modify(dev->dev, NULL, to_mlx4_state(qp->state), MLX4_QP_STATE_RST, NULL, 0, 0, &qp->mqp)) - pr_warn("modify QP %06x to RESET failed.\n", + printk(KERN_WARNING "mlx4_ib: modify QP %06x to RESET failed.\n", qp->mqp.qpn); get_cqs(qp, &send_cq, &recv_cq); @@ -801,7 +791,6 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, case IB_QPT_RC: case IB_QPT_UC: case IB_QPT_UD: - case IB_QPT_RAW_PACKET: { qp = kzalloc(sizeof *qp, GFP_KERNEL); if (!qp) @@ -883,8 +872,7 @@ static int to_mlx4_st(enum ib_qp_type type) case IB_QPT_XRC_INI: case IB_QPT_XRC_TGT: return MLX4_QP_ST_XRC; case IB_QPT_SMI: - case IB_QPT_GSI: - case IB_QPT_RAW_PACKET: return MLX4_QP_ST_MLX; + case IB_QPT_GSI: return MLX4_QP_ST_MLX; default: return -1; } } @@ -958,7 +946,7 @@ static int mlx4_set_path(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah, if (ah->ah_flags & IB_AH_GRH) { if (ah->grh.sgid_index >= dev->dev->caps.gid_table_len[port]) { - pr_err("sgid_index (%u) too large. max is %d\n", + printk(KERN_ERR "sgid_index (%u) too large. max is %d\n", ah->grh.sgid_index, dev->dev->caps.gid_table_len[port] - 1); return -1; } @@ -1054,8 +1042,6 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, if (ibqp->qp_type == IB_QPT_GSI || ibqp->qp_type == IB_QPT_SMI) context->mtu_msgmax = (IB_MTU_4096 << 5) | 11; - else if (ibqp->qp_type == IB_QPT_RAW_PACKET) - context->mtu_msgmax = (MLX4_RAW_QP_MTU << 5) | MLX4_RAW_QP_MSGMAX; else if (ibqp->qp_type == IB_QPT_UD) { if (qp->flags & MLX4_IB_QP_LSO) context->mtu_msgmax = (IB_MTU_4096 << 5) | @@ -1064,7 +1050,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, context->mtu_msgmax = (IB_MTU_4096 << 5) | 12; } else if (attr_mask & IB_QP_PATH_MTU) { if (attr->path_mtu < IB_MTU_256 || attr->path_mtu > IB_MTU_4096) { - pr_err("path MTU (%u) is invalid\n", + printk(KERN_ERR "path MTU (%u) is invalid\n", attr->path_mtu); goto out; } @@ -1214,8 +1200,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR && (ibqp->qp_type == IB_QPT_GSI || ibqp->qp_type == IB_QPT_SMI || - ibqp->qp_type == IB_QPT_UD || - ibqp->qp_type == IB_QPT_RAW_PACKET)) { + ibqp->qp_type == IB_QPT_UD)) { context->pri_path.sched_queue = (qp->port - 1) << 6; if (is_qp0(dev, qp)) context->pri_path.sched_queue |= MLX4_IB_DEFAULT_QP0_SCHED_QUEUE; @@ -1281,7 +1266,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, if (is_qp0(dev, qp)) { if (cur_state != IB_QPS_RTR && new_state == IB_QPS_RTR) if (mlx4_INIT_PORT(dev->dev, qp->port)) - pr_warn("INIT_PORT failed for port %d\n", + printk(KERN_WARNING "INIT_PORT failed for port %d\n", qp->port); if (cur_state != IB_QPS_RESET && cur_state != IB_QPS_ERR && @@ -1334,11 +1319,6 @@ int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, goto out; } - if ((attr_mask & IB_QP_PORT) && (ibqp->qp_type == IB_QPT_RAW_PACKET) && - (rdma_port_get_link_layer(&dev->ib_dev, attr->port_num) != - IB_LINK_LAYER_ETHERNET)) - goto out; - if (attr_mask & IB_QP_PKEY_INDEX) { int p = attr_mask & IB_QP_PORT ? attr->port_num : qp->port; if (attr->pkey_index >= dev->dev->caps.pkey_table_len[p]) @@ -1444,9 +1424,6 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr, if (is_eth) { u8 *smac; - u16 pcp = (be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) >> 29) << 13; - - mlx->sched_prio = cpu_to_be16(pcp); memcpy(sqp->ud_header.eth.dmac_h, ah->av.eth.mac, 6); /* FIXME: cache smac value? */ @@ -1457,7 +1434,10 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr, if (!is_vlan) { sqp->ud_header.eth.type = cpu_to_be16(MLX4_IB_IBOE_ETHERTYPE); } else { + u16 pcp; + sqp->ud_header.vlan.type = cpu_to_be16(MLX4_IB_IBOE_ETHERTYPE); + pcp = (be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) >> 29) << 13; sqp->ud_header.vlan.tag = cpu_to_be16(vlan | pcp); } } else { @@ -1480,16 +1460,16 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr, header_size = ib_ud_header_pack(&sqp->ud_header, sqp->header_buf); if (0) { - pr_err("built UD header of size %d:\n", header_size); + printk(KERN_ERR "built UD header of size %d:\n", header_size); for (i = 0; i < header_size / 4; ++i) { if (i % 8 == 0) - pr_err(" [%02x] ", i * 4); - pr_cont(" %08x", - be32_to_cpu(((__be32 *) sqp->header_buf)[i])); + printk(" [%02x] ", i * 4); + printk(" %08x", + be32_to_cpu(((__be32 *) sqp->header_buf)[i])); if ((i + 1) % 8 == 0) - pr_cont("\n"); + printk("\n"); } - pr_err("\n"); + printk("\n"); } /* diff --git a/trunk/drivers/infiniband/hw/mlx4/srq.c b/trunk/drivers/infiniband/hw/mlx4/srq.c index 60c5fb025fc7..39542f3703b8 100644 --- a/trunk/drivers/infiniband/hw/mlx4/srq.c +++ b/trunk/drivers/infiniband/hw/mlx4/srq.c @@ -59,7 +59,7 @@ static void mlx4_ib_srq_event(struct mlx4_srq *srq, enum mlx4_event type) event.event = IB_EVENT_SRQ_ERR; break; default: - pr_warn("Unexpected event type %d " + printk(KERN_WARNING "mlx4_ib: Unexpected event type %d " "on SRQ %06x\n", type, srq->srqn); return; } diff --git a/trunk/drivers/infiniband/hw/nes/nes_cm.c b/trunk/drivers/infiniband/hw/nes/nes_cm.c index 020e95c4c4b9..71edfbbcce1c 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_cm.c +++ b/trunk/drivers/infiniband/hw/nes/nes_cm.c @@ -2884,8 +2884,7 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp) ibevent.device = nesqp->ibqp.device; ibevent.event = nesqp->terminate_eventtype; ibevent.element.qp = &nesqp->ibqp; - if (nesqp->ibqp.event_handler) - nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context); + nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context); } } @@ -3321,10 +3320,6 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) nesqp->private_data_len = conn_param->private_data_len; nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32((u32)conn_param->ord); - /* space for rdma0 read msg */ - if (conn_param->ord == 0) - nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32(1); - nes_debug(NES_DBG_CM, "requested ord = 0x%08X.\n", (u32)conn_param->ord); nes_debug(NES_DBG_CM, "mpa private data len =%u\n", conn_param->private_data_len); diff --git a/trunk/drivers/infiniband/hw/ocrdma/Kconfig b/trunk/drivers/infiniband/hw/ocrdma/Kconfig deleted file mode 100644 index b5b6056c8518..000000000000 --- a/trunk/drivers/infiniband/hw/ocrdma/Kconfig +++ /dev/null @@ -1,8 +0,0 @@ -config INFINIBAND_OCRDMA - tristate "Emulex One Connect HCA support" - depends on ETHERNET && NETDEVICES && PCI && (IPV6 || IPV6=n) - select NET_VENDOR_EMULEX - select BE2NET - ---help--- - This driver provides low-level InfiniBand over Ethernet - support for Emulex One Connect host channel adapters (HCAs). diff --git a/trunk/drivers/infiniband/hw/ocrdma/Makefile b/trunk/drivers/infiniband/hw/ocrdma/Makefile deleted file mode 100644 index 06a5bed12e43..000000000000 --- a/trunk/drivers/infiniband/hw/ocrdma/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -ccflags-y := -Idrivers/net/ethernet/emulex/benet - -obj-$(CONFIG_INFINIBAND_OCRDMA) += ocrdma.o - -ocrdma-y := ocrdma_main.o ocrdma_verbs.o ocrdma_hw.o ocrdma_ah.o diff --git a/trunk/drivers/infiniband/hw/ocrdma/ocrdma.h b/trunk/drivers/infiniband/hw/ocrdma/ocrdma.h deleted file mode 100644 index 85a69c958559..000000000000 --- a/trunk/drivers/infiniband/hw/ocrdma/ocrdma.h +++ /dev/null @@ -1,393 +0,0 @@ -/******************************************************************* - * This file is part of the Emulex RoCE Device Driver for * - * RoCE (RDMA over Converged Ethernet) adapters. * - * Copyright (C) 2008-2012 Emulex. All rights reserved. * - * EMULEX and SLI are trademarks of Emulex. * - * www.emulex.com * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of version 2 of the GNU General * - * Public License as published by the Free Software Foundation. * - * This program is distributed in the hope that it will be useful. * - * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * - * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * - * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE * - * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD * - * TO BE LEGALLY INVALID. See the GNU General Public License for * - * more details, a copy of which can be found in the file COPYING * - * included with this package. * - * - * Contact Information: - * linux-drivers@emulex.com - * - * Emulex - * 3333 Susan Street - * Costa Mesa, CA 92626 - *******************************************************************/ - -#ifndef __OCRDMA_H__ -#define __OCRDMA_H__ - -#include -#include -#include -#include - -#include -#include - -#include -#include "ocrdma_sli.h" - -#define OCRDMA_ROCE_DEV_VERSION "1.0.0" -#define OCRDMA_NODE_DESC "Emulex OneConnect RoCE HCA" - -#define ocrdma_err(format, arg...) printk(KERN_ERR format, ##arg) - -#define OCRDMA_MAX_AH 512 - -#define OCRDMA_UVERBS(CMD_NAME) (1ull << IB_USER_VERBS_CMD_##CMD_NAME) - -struct ocrdma_dev_attr { - u8 fw_ver[32]; - u32 vendor_id; - u32 device_id; - u16 max_pd; - u16 max_cq; - u16 max_cqe; - u16 max_qp; - u16 max_wqe; - u16 max_rqe; - u32 max_inline_data; - int max_send_sge; - int max_recv_sge; - int max_mr; - u64 max_mr_size; - u32 max_num_mr_pbl; - int max_fmr; - int max_map_per_fmr; - int max_pages_per_frmr; - u16 max_ord_per_qp; - u16 max_ird_per_qp; - - int device_cap_flags; - u8 cq_overflow_detect; - u8 srq_supported; - - u32 wqe_size; - u32 rqe_size; - u32 ird_page_size; - u8 local_ca_ack_delay; - u8 ird; - u8 num_ird_pages; -}; - -struct ocrdma_pbl { - void *va; - dma_addr_t pa; -}; - -struct ocrdma_queue_info { - void *va; - dma_addr_t dma; - u32 size; - u16 len; - u16 entry_size; /* Size of an element in the queue */ - u16 id; /* qid, where to ring the doorbell. */ - u16 head, tail; - bool created; - atomic_t used; /* Number of valid elements in the queue */ -}; - -struct ocrdma_eq { - struct ocrdma_queue_info q; - u32 vector; - int cq_cnt; - struct ocrdma_dev *dev; - char irq_name[32]; -}; - -struct ocrdma_mq { - struct ocrdma_queue_info sq; - struct ocrdma_queue_info cq; - bool rearm_cq; -}; - -struct mqe_ctx { - struct mutex lock; /* for serializing mailbox commands on MQ */ - wait_queue_head_t cmd_wait; - u32 tag; - u16 cqe_status; - u16 ext_status; - bool cmd_done; -}; - -struct ocrdma_dev { - struct ib_device ibdev; - struct ocrdma_dev_attr attr; - - struct mutex dev_lock; /* provides syncronise access to device data */ - spinlock_t flush_q_lock ____cacheline_aligned; - - struct ocrdma_cq **cq_tbl; - struct ocrdma_qp **qp_tbl; - - struct ocrdma_eq meq; - struct ocrdma_eq *qp_eq_tbl; - int eq_cnt; - u16 base_eqid; - u16 max_eq; - - union ib_gid *sgid_tbl; - /* provided synchronization to sgid table for - * updating gid entries triggered by notifier. - */ - spinlock_t sgid_lock; - - int gsi_qp_created; - struct ocrdma_cq *gsi_sqcq; - struct ocrdma_cq *gsi_rqcq; - - struct { - struct ocrdma_av *va; - dma_addr_t pa; - u32 size; - u32 num_ah; - /* provide synchronization for av - * entry allocations. - */ - spinlock_t lock; - u32 ahid; - struct ocrdma_pbl pbl; - } av_tbl; - - void *mbx_cmd; - struct ocrdma_mq mq; - struct mqe_ctx mqe_ctx; - - struct be_dev_info nic_info; - - struct list_head entry; - struct rcu_head rcu; - int id; -}; - -struct ocrdma_cq { - struct ib_cq ibcq; - struct ocrdma_dev *dev; - struct ocrdma_cqe *va; - u32 phase; - u32 getp; /* pointer to pending wrs to - * return to stack, wrap arounds - * at max_hw_cqe - */ - u32 max_hw_cqe; - bool phase_change; - bool armed, solicited; - bool arm_needed; - - spinlock_t cq_lock ____cacheline_aligned; /* provide synchronization - * to cq polling - */ - /* syncronizes cq completion handler invoked from multiple context */ - spinlock_t comp_handler_lock ____cacheline_aligned; - u16 id; - u16 eqn; - - struct ocrdma_ucontext *ucontext; - dma_addr_t pa; - u32 len; - atomic_t use_cnt; - - /* head of all qp's sq and rq for which cqes need to be flushed - * by the software. - */ - struct list_head sq_head, rq_head; -}; - -struct ocrdma_pd { - struct ib_pd ibpd; - struct ocrdma_dev *dev; - struct ocrdma_ucontext *uctx; - atomic_t use_cnt; - u32 id; - int num_dpp_qp; - u32 dpp_page; - bool dpp_enabled; -}; - -struct ocrdma_ah { - struct ib_ah ibah; - struct ocrdma_dev *dev; - struct ocrdma_av *av; - u16 sgid_index; - u32 id; -}; - -struct ocrdma_qp_hwq_info { - u8 *va; /* virtual address */ - u32 max_sges; - u32 head, tail; - u32 entry_size; - u32 max_cnt; - u32 max_wqe_idx; - u32 free_delta; - u16 dbid; /* qid, where to ring the doorbell. */ - u32 len; - dma_addr_t pa; -}; - -struct ocrdma_srq { - struct ib_srq ibsrq; - struct ocrdma_dev *dev; - u8 __iomem *db; - /* provide synchronization to multiple context(s) posting rqe */ - spinlock_t q_lock ____cacheline_aligned; - - struct ocrdma_qp_hwq_info rq; - struct ocrdma_pd *pd; - atomic_t use_cnt; - u32 id; - u64 *rqe_wr_id_tbl; - u32 *idx_bit_fields; - u32 bit_fields_len; -}; - -struct ocrdma_qp { - struct ib_qp ibqp; - struct ocrdma_dev *dev; - - u8 __iomem *sq_db; - /* provide synchronization to multiple context(s) posting wqe, rqe */ - spinlock_t q_lock ____cacheline_aligned; - struct ocrdma_qp_hwq_info sq; - struct { - uint64_t wrid; - uint16_t dpp_wqe_idx; - uint16_t dpp_wqe; - uint8_t signaled; - uint8_t rsvd[3]; - } *wqe_wr_id_tbl; - u32 max_inline_data; - struct ocrdma_cq *sq_cq; - /* list maintained per CQ to flush SQ errors */ - struct list_head sq_entry; - - u8 __iomem *rq_db; - struct ocrdma_qp_hwq_info rq; - u64 *rqe_wr_id_tbl; - struct ocrdma_cq *rq_cq; - struct ocrdma_srq *srq; - /* list maintained per CQ to flush RQ errors */ - struct list_head rq_entry; - - enum ocrdma_qp_state state; /* QP state */ - int cap_flags; - u32 max_ord, max_ird; - - u32 id; - struct ocrdma_pd *pd; - - enum ib_qp_type qp_type; - - int sgid_idx; - u32 qkey; - bool dpp_enabled; - u8 *ird_q_va; -}; - -#define OCRDMA_GET_NUM_POSTED_SHIFT_VAL(qp) \ - (((qp->dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) && \ - (qp->id < 64)) ? 24 : 16) - -struct ocrdma_hw_mr { - struct ocrdma_dev *dev; - u32 lkey; - u8 fr_mr; - u8 remote_atomic; - u8 remote_rd; - u8 remote_wr; - u8 local_rd; - u8 local_wr; - u8 mw_bind; - u8 rsvd; - u64 len; - struct ocrdma_pbl *pbl_table; - u32 num_pbls; - u32 num_pbes; - u32 pbl_size; - u32 pbe_size; - u64 fbo; - u64 va; -}; - -struct ocrdma_mr { - struct ib_mr ibmr; - struct ib_umem *umem; - struct ocrdma_hw_mr hwmr; - struct ocrdma_pd *pd; -}; - -struct ocrdma_ucontext { - struct ib_ucontext ibucontext; - struct ocrdma_dev *dev; - - struct list_head mm_head; - struct mutex mm_list_lock; /* protects list entries of mm type */ - struct { - u32 *va; - dma_addr_t pa; - u32 len; - } ah_tbl; -}; - -struct ocrdma_mm { - struct { - u64 phy_addr; - unsigned long len; - } key; - struct list_head entry; -}; - -static inline struct ocrdma_dev *get_ocrdma_dev(struct ib_device *ibdev) -{ - return container_of(ibdev, struct ocrdma_dev, ibdev); -} - -static inline struct ocrdma_ucontext *get_ocrdma_ucontext(struct ib_ucontext - *ibucontext) -{ - return container_of(ibucontext, struct ocrdma_ucontext, ibucontext); -} - -static inline struct ocrdma_pd *get_ocrdma_pd(struct ib_pd *ibpd) -{ - return container_of(ibpd, struct ocrdma_pd, ibpd); -} - -static inline struct ocrdma_cq *get_ocrdma_cq(struct ib_cq *ibcq) -{ - return container_of(ibcq, struct ocrdma_cq, ibcq); -} - -static inline struct ocrdma_qp *get_ocrdma_qp(struct ib_qp *ibqp) -{ - return container_of(ibqp, struct ocrdma_qp, ibqp); -} - -static inline struct ocrdma_mr *get_ocrdma_mr(struct ib_mr *ibmr) -{ - return container_of(ibmr, struct ocrdma_mr, ibmr); -} - -static inline struct ocrdma_ah *get_ocrdma_ah(struct ib_ah *ibah) -{ - return container_of(ibah, struct ocrdma_ah, ibah); -} - -static inline struct ocrdma_srq *get_ocrdma_srq(struct ib_srq *ibsrq) -{ - return container_of(ibsrq, struct ocrdma_srq, ibsrq); -} - -#endif diff --git a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_abi.h b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_abi.h deleted file mode 100644 index a411a4e3193d..000000000000 --- a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_abi.h +++ /dev/null @@ -1,134 +0,0 @@ -/******************************************************************* - * This file is part of the Emulex RoCE Device Driver for * - * RoCE (RDMA over Converged Ethernet) adapters. * - * Copyright (C) 2008-2012 Emulex. All rights reserved. * - * EMULEX and SLI are trademarks of Emulex. * - * www.emulex.com * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of version 2 of the GNU General * - * Public License as published by the Free Software Foundation. * - * This program is distributed in the hope that it will be useful. * - * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * - * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * - * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE * - * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD * - * TO BE LEGALLY INVALID. See the GNU General Public License for * - * more details, a copy of which can be found in the file COPYING * - * included with this package. * - * - * Contact Information: - * linux-drivers@emulex.com - * - * Emulex - * 3333 Susan Street - * Costa Mesa, CA 92626 - *******************************************************************/ - -#ifndef __OCRDMA_ABI_H__ -#define __OCRDMA_ABI_H__ - -struct ocrdma_alloc_ucontext_resp { - u32 dev_id; - u32 wqe_size; - u32 max_inline_data; - u32 dpp_wqe_size; - u64 ah_tbl_page; - u32 ah_tbl_len; - u32 rsvd; - u8 fw_ver[32]; - u32 rqe_size; - u64 rsvd1; -} __packed; - -/* user kernel communication data structures. */ -struct ocrdma_alloc_pd_ureq { - u64 rsvd1; -} __packed; - -struct ocrdma_alloc_pd_uresp { - u32 id; - u32 dpp_enabled; - u32 dpp_page_addr_hi; - u32 dpp_page_addr_lo; - u64 rsvd1; -} __packed; - -struct ocrdma_create_cq_ureq { - u32 dpp_cq; - u32 rsvd; -} __packed; - -#define MAX_CQ_PAGES 8 -struct ocrdma_create_cq_uresp { - u32 cq_id; - u32 page_size; - u32 num_pages; - u32 max_hw_cqe; - u64 page_addr[MAX_CQ_PAGES]; - u64 db_page_addr; - u32 db_page_size; - u32 phase_change; - u64 rsvd1; - u64 rsvd2; -} __packed; - -#define MAX_QP_PAGES 8 -#define MAX_UD_AV_PAGES 8 - -struct ocrdma_create_qp_ureq { - u8 enable_dpp_cq; - u8 rsvd; - u16 dpp_cq_id; - u32 rsvd1; -}; - -struct ocrdma_create_qp_uresp { - u16 qp_id; - u16 sq_dbid; - u16 rq_dbid; - u16 resv0; - u32 sq_page_size; - u32 rq_page_size; - u32 num_sq_pages; - u32 num_rq_pages; - u64 sq_page_addr[MAX_QP_PAGES]; - u64 rq_page_addr[MAX_QP_PAGES]; - u64 db_page_addr; - u32 db_page_size; - u32 dpp_credit; - u32 dpp_offset; - u32 rsvd1; - u32 num_wqe_allocated; - u32 num_rqe_allocated; - u32 free_wqe_delta; - u32 free_rqe_delta; - u32 db_sq_offset; - u32 db_rq_offset; - u32 db_shift; - u64 rsvd2; - u64 rsvd3; -} __packed; - -struct ocrdma_create_srq_uresp { - u16 rq_dbid; - u16 resv0; - u32 resv1; - - u32 rq_page_size; - u32 num_rq_pages; - - u64 rq_page_addr[MAX_QP_PAGES]; - u64 db_page_addr; - - u32 db_page_size; - u32 num_rqe_allocated; - u32 db_rq_offset; - u32 db_shift; - - u32 free_rqe_delta; - u32 rsvd2; - u64 rsvd3; -} __packed; - -#endif /* __OCRDMA_ABI_H__ */ diff --git a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_ah.c b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_ah.c deleted file mode 100644 index a877a8ed7907..000000000000 --- a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_ah.c +++ /dev/null @@ -1,172 +0,0 @@ -/******************************************************************* - * This file is part of the Emulex RoCE Device Driver for * - * RoCE (RDMA over Converged Ethernet) adapters. * - * Copyright (C) 2008-2012 Emulex. All rights reserved. * - * EMULEX and SLI are trademarks of Emulex. * - * www.emulex.com * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of version 2 of the GNU General * - * Public License as published by the Free Software Foundation. * - * This program is distributed in the hope that it will be useful. * - * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * - * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * - * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE * - * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD * - * TO BE LEGALLY INVALID. See the GNU General Public License for * - * more details, a copy of which can be found in the file COPYING * - * included with this package. * - * - * Contact Information: - * linux-drivers@emulex.com - * - * Emulex - * 3333 Susan Street - * Costa Mesa, CA 92626 - *******************************************************************/ - -#include -#include - -#include -#include - -#include "ocrdma.h" -#include "ocrdma_verbs.h" -#include "ocrdma_ah.h" -#include "ocrdma_hw.h" - -static inline int set_av_attr(struct ocrdma_ah *ah, - struct ib_ah_attr *attr, int pdid) -{ - int status = 0; - u16 vlan_tag; bool vlan_enabled = false; - struct ocrdma_dev *dev = ah->dev; - struct ocrdma_eth_vlan eth; - struct ocrdma_grh grh; - int eth_sz; - - memset(ð, 0, sizeof(eth)); - memset(&grh, 0, sizeof(grh)); - - ah->sgid_index = attr->grh.sgid_index; - - vlan_tag = rdma_get_vlan_id(&attr->grh.dgid); - if (vlan_tag && (vlan_tag < 0x1000)) { - eth.eth_type = cpu_to_be16(0x8100); - eth.roce_eth_type = cpu_to_be16(OCRDMA_ROCE_ETH_TYPE); - vlan_tag |= (attr->sl & 7) << 13; - eth.vlan_tag = cpu_to_be16(vlan_tag); - eth_sz = sizeof(struct ocrdma_eth_vlan); - vlan_enabled = true; - } else { - eth.eth_type = cpu_to_be16(OCRDMA_ROCE_ETH_TYPE); - eth_sz = sizeof(struct ocrdma_eth_basic); - } - memcpy(ð.smac[0], &dev->nic_info.mac_addr[0], ETH_ALEN); - status = ocrdma_resolve_dgid(dev, &attr->grh.dgid, ð.dmac[0]); - if (status) - return status; - status = ocrdma_query_gid(&dev->ibdev, 1, attr->grh.sgid_index, - (union ib_gid *)&grh.sgid[0]); - if (status) - return status; - - grh.tclass_flow = cpu_to_be32((6 << 28) | - (attr->grh.traffic_class << 24) | - attr->grh.flow_label); - /* 0x1b is next header value in GRH */ - grh.pdid_hoplimit = cpu_to_be32((pdid << 16) | - (0x1b << 8) | attr->grh.hop_limit); - - memcpy(&grh.dgid[0], attr->grh.dgid.raw, sizeof(attr->grh.dgid.raw)); - memcpy(&ah->av->eth_hdr, ð, eth_sz); - memcpy((u8 *)ah->av + eth_sz, &grh, sizeof(struct ocrdma_grh)); - if (vlan_enabled) - ah->av->valid |= OCRDMA_AV_VLAN_VALID; - return status; -} - -struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr) -{ - u32 *ahid_addr; - int status; - struct ocrdma_ah *ah; - struct ocrdma_pd *pd = get_ocrdma_pd(ibpd); - struct ocrdma_dev *dev = pd->dev; - - if (!(attr->ah_flags & IB_AH_GRH)) - return ERR_PTR(-EINVAL); - - ah = kzalloc(sizeof *ah, GFP_ATOMIC); - if (!ah) - return ERR_PTR(-ENOMEM); - ah->dev = pd->dev; - - status = ocrdma_alloc_av(dev, ah); - if (status) - goto av_err; - status = set_av_attr(ah, attr, pd->id); - if (status) - goto av_conf_err; - - /* if pd is for the user process, pass the ah_id to user space */ - if ((pd->uctx) && (pd->uctx->ah_tbl.va)) { - ahid_addr = pd->uctx->ah_tbl.va + attr->dlid; - *ahid_addr = ah->id; - } - return &ah->ibah; - -av_conf_err: - ocrdma_free_av(dev, ah); -av_err: - kfree(ah); - return ERR_PTR(status); -} - -int ocrdma_destroy_ah(struct ib_ah *ibah) -{ - struct ocrdma_ah *ah = get_ocrdma_ah(ibah); - ocrdma_free_av(ah->dev, ah); - kfree(ah); - return 0; -} - -int ocrdma_query_ah(struct ib_ah *ibah, struct ib_ah_attr *attr) -{ - struct ocrdma_ah *ah = get_ocrdma_ah(ibah); - struct ocrdma_av *av = ah->av; - struct ocrdma_grh *grh; - attr->ah_flags |= IB_AH_GRH; - if (ah->av->valid & Bit(1)) { - grh = (struct ocrdma_grh *)((u8 *)ah->av + - sizeof(struct ocrdma_eth_vlan)); - attr->sl = be16_to_cpu(av->eth_hdr.vlan_tag) >> 13; - } else { - grh = (struct ocrdma_grh *)((u8 *)ah->av + - sizeof(struct ocrdma_eth_basic)); - attr->sl = 0; - } - memcpy(&attr->grh.dgid.raw[0], &grh->dgid[0], sizeof(grh->dgid)); - attr->grh.sgid_index = ah->sgid_index; - attr->grh.hop_limit = be32_to_cpu(grh->pdid_hoplimit) & 0xff; - attr->grh.traffic_class = be32_to_cpu(grh->tclass_flow) >> 24; - attr->grh.flow_label = be32_to_cpu(grh->tclass_flow) & 0x00ffffffff; - return 0; -} - -int ocrdma_modify_ah(struct ib_ah *ibah, struct ib_ah_attr *attr) -{ - /* modify_ah is unsupported */ - return -ENOSYS; -} - -int ocrdma_process_mad(struct ib_device *ibdev, - int process_mad_flags, - u8 port_num, - struct ib_wc *in_wc, - struct ib_grh *in_grh, - struct ib_mad *in_mad, struct ib_mad *out_mad) -{ - return IB_MAD_RESULT_SUCCESS; -} diff --git a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_ah.h b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_ah.h deleted file mode 100644 index 8ac49e7f96d1..000000000000 --- a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_ah.h +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************* - * This file is part of the Emulex RoCE Device Driver for * - * RoCE (RDMA over Converged Ethernet) adapters. * - * Copyright (C) 2008-2012 Emulex. All rights reserved. * - * EMULEX and SLI are trademarks of Emulex. * - * www.emulex.com * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of version 2 of the GNU General * - * Public License as published by the Free Software Foundation. * - * This program is distributed in the hope that it will be useful. * - * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * - * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * - * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE * - * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD * - * TO BE LEGALLY INVALID. See the GNU General Public License for * - * more details, a copy of which can be found in the file COPYING * - * included with this package. * - * - * Contact Information: - * linux-drivers@emulex.com - * - * Emulex - * 3333 Susan Street - * Costa Mesa, CA 92626 - *******************************************************************/ - -#ifndef __OCRDMA_AH_H__ -#define __OCRDMA_AH_H__ - -struct ib_ah *ocrdma_create_ah(struct ib_pd *, struct ib_ah_attr *); -int ocrdma_destroy_ah(struct ib_ah *); -int ocrdma_query_ah(struct ib_ah *, struct ib_ah_attr *); -int ocrdma_modify_ah(struct ib_ah *, struct ib_ah_attr *); - -int ocrdma_process_mad(struct ib_device *, - int process_mad_flags, - u8 port_num, - struct ib_wc *in_wc, - struct ib_grh *in_grh, - struct ib_mad *in_mad, struct ib_mad *out_mad); -#endif /* __OCRDMA_AH_H__ */ diff --git a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_hw.c deleted file mode 100644 index 9b204b1ba336..000000000000 --- a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_hw.c +++ /dev/null @@ -1,2640 +0,0 @@ -/******************************************************************* - * This file is part of the Emulex RoCE Device Driver for * - * RoCE (RDMA over Converged Ethernet) CNA Adapters. * - * Copyright (C) 2008-2012 Emulex. All rights reserved. * - * EMULEX and SLI are trademarks of Emulex. * - * www.emulex.com * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of version 2 of the GNU General * - * Public License as published by the Free Software Foundation. * - * This program is distributed in the hope that it will be useful. * - * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * - * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * - * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE * - * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD * - * TO BE LEGALLY INVALID. See the GNU General Public License for * - * more details, a copy of which can be found in the file COPYING * - * included with this package. * - * - * Contact Information: - * linux-drivers@emulex.com - * - * Emulex - * 3333 Susan Street - * Costa Mesa, CA 92626 - *******************************************************************/ - -#include -#include -#include -#include - -#include -#include -#include - -#include "ocrdma.h" -#include "ocrdma_hw.h" -#include "ocrdma_verbs.h" -#include "ocrdma_ah.h" - -enum mbx_status { - OCRDMA_MBX_STATUS_FAILED = 1, - OCRDMA_MBX_STATUS_ILLEGAL_FIELD = 3, - OCRDMA_MBX_STATUS_OOR = 100, - OCRDMA_MBX_STATUS_INVALID_PD = 101, - OCRDMA_MBX_STATUS_PD_INUSE = 102, - OCRDMA_MBX_STATUS_INVALID_CQ = 103, - OCRDMA_MBX_STATUS_INVALID_QP = 104, - OCRDMA_MBX_STATUS_INVALID_LKEY = 105, - OCRDMA_MBX_STATUS_ORD_EXCEEDS = 106, - OCRDMA_MBX_STATUS_IRD_EXCEEDS = 107, - OCRDMA_MBX_STATUS_SENDQ_WQE_EXCEEDS = 108, - OCRDMA_MBX_STATUS_RECVQ_RQE_EXCEEDS = 109, - OCRDMA_MBX_STATUS_SGE_SEND_EXCEEDS = 110, - OCRDMA_MBX_STATUS_SGE_WRITE_EXCEEDS = 111, - OCRDMA_MBX_STATUS_SGE_RECV_EXCEEDS = 112, - OCRDMA_MBX_STATUS_INVALID_STATE_CHANGE = 113, - OCRDMA_MBX_STATUS_MW_BOUND = 114, - OCRDMA_MBX_STATUS_INVALID_VA = 115, - OCRDMA_MBX_STATUS_INVALID_LENGTH = 116, - OCRDMA_MBX_STATUS_INVALID_FBO = 117, - OCRDMA_MBX_STATUS_INVALID_ACC_RIGHTS = 118, - OCRDMA_MBX_STATUS_INVALID_PBE_SIZE = 119, - OCRDMA_MBX_STATUS_INVALID_PBL_ENTRY = 120, - OCRDMA_MBX_STATUS_INVALID_PBL_SHIFT = 121, - OCRDMA_MBX_STATUS_INVALID_SRQ_ID = 129, - OCRDMA_MBX_STATUS_SRQ_ERROR = 133, - OCRDMA_MBX_STATUS_RQE_EXCEEDS = 134, - OCRDMA_MBX_STATUS_MTU_EXCEEDS = 135, - OCRDMA_MBX_STATUS_MAX_QP_EXCEEDS = 136, - OCRDMA_MBX_STATUS_SRQ_LIMIT_EXCEEDS = 137, - OCRDMA_MBX_STATUS_SRQ_SIZE_UNDERUNS = 138, - OCRDMA_MBX_STATUS_QP_BOUND = 130, - OCRDMA_MBX_STATUS_INVALID_CHANGE = 139, - OCRDMA_MBX_STATUS_ATOMIC_OPS_UNSUP = 140, - OCRDMA_MBX_STATUS_INVALID_RNR_NAK_TIMER = 141, - OCRDMA_MBX_STATUS_MW_STILL_BOUND = 142, - OCRDMA_MBX_STATUS_PKEY_INDEX_INVALID = 143, - OCRDMA_MBX_STATUS_PKEY_INDEX_EXCEEDS = 144 -}; - -enum additional_status { - OCRDMA_MBX_ADDI_STATUS_INSUFFICIENT_RESOURCES = 22 -}; - -enum cqe_status { - OCRDMA_MBX_CQE_STATUS_INSUFFICIENT_PRIVILEDGES = 1, - OCRDMA_MBX_CQE_STATUS_INVALID_PARAMETER = 2, - OCRDMA_MBX_CQE_STATUS_INSUFFICIENT_RESOURCES = 3, - OCRDMA_MBX_CQE_STATUS_QUEUE_FLUSHING = 4, - OCRDMA_MBX_CQE_STATUS_DMA_FAILED = 5 -}; - -static inline void *ocrdma_get_eqe(struct ocrdma_eq *eq) -{ - return (u8 *)eq->q.va + (eq->q.tail * sizeof(struct ocrdma_eqe)); -} - -static inline void ocrdma_eq_inc_tail(struct ocrdma_eq *eq) -{ - eq->q.tail = (eq->q.tail + 1) & (OCRDMA_EQ_LEN - 1); -} - -static inline void *ocrdma_get_mcqe(struct ocrdma_dev *dev) -{ - struct ocrdma_mcqe *cqe = (struct ocrdma_mcqe *) - ((u8 *) dev->mq.cq.va + - (dev->mq.cq.tail * sizeof(struct ocrdma_mcqe))); - - if (!(le32_to_cpu(cqe->valid_ae_cmpl_cons) & OCRDMA_MCQE_VALID_MASK)) - return NULL; - return cqe; -} - -static inline void ocrdma_mcq_inc_tail(struct ocrdma_dev *dev) -{ - dev->mq.cq.tail = (dev->mq.cq.tail + 1) & (OCRDMA_MQ_CQ_LEN - 1); -} - -static inline struct ocrdma_mqe *ocrdma_get_mqe(struct ocrdma_dev *dev) -{ - return (struct ocrdma_mqe *)((u8 *) dev->mq.sq.va + - (dev->mq.sq.head * - sizeof(struct ocrdma_mqe))); -} - -static inline void ocrdma_mq_inc_head(struct ocrdma_dev *dev) -{ - dev->mq.sq.head = (dev->mq.sq.head + 1) & (OCRDMA_MQ_LEN - 1); - atomic_inc(&dev->mq.sq.used); -} - -static inline void *ocrdma_get_mqe_rsp(struct ocrdma_dev *dev) -{ - return (void *)((u8 *) dev->mq.sq.va + - (dev->mqe_ctx.tag * sizeof(struct ocrdma_mqe))); -} - -enum ib_qp_state get_ibqp_state(enum ocrdma_qp_state qps) -{ - switch (qps) { - case OCRDMA_QPS_RST: - return IB_QPS_RESET; - case OCRDMA_QPS_INIT: - return IB_QPS_INIT; - case OCRDMA_QPS_RTR: - return IB_QPS_RTR; - case OCRDMA_QPS_RTS: - return IB_QPS_RTS; - case OCRDMA_QPS_SQD: - case OCRDMA_QPS_SQ_DRAINING: - return IB_QPS_SQD; - case OCRDMA_QPS_SQE: - return IB_QPS_SQE; - case OCRDMA_QPS_ERR: - return IB_QPS_ERR; - }; - return IB_QPS_ERR; -} - -static enum ocrdma_qp_state get_ocrdma_qp_state(enum ib_qp_state qps) -{ - switch (qps) { - case IB_QPS_RESET: - return OCRDMA_QPS_RST; - case IB_QPS_INIT: - return OCRDMA_QPS_INIT; - case IB_QPS_RTR: - return OCRDMA_QPS_RTR; - case IB_QPS_RTS: - return OCRDMA_QPS_RTS; - case IB_QPS_SQD: - return OCRDMA_QPS_SQD; - case IB_QPS_SQE: - return OCRDMA_QPS_SQE; - case IB_QPS_ERR: - return OCRDMA_QPS_ERR; - }; - return OCRDMA_QPS_ERR; -} - -static int ocrdma_get_mbx_errno(u32 status) -{ - int err_num = -EFAULT; - u8 mbox_status = (status & OCRDMA_MBX_RSP_STATUS_MASK) >> - OCRDMA_MBX_RSP_STATUS_SHIFT; - u8 add_status = (status & OCRDMA_MBX_RSP_ASTATUS_MASK) >> - OCRDMA_MBX_RSP_ASTATUS_SHIFT; - - switch (mbox_status) { - case OCRDMA_MBX_STATUS_OOR: - case OCRDMA_MBX_STATUS_MAX_QP_EXCEEDS: - err_num = -EAGAIN; - break; - - case OCRDMA_MBX_STATUS_INVALID_PD: - case OCRDMA_MBX_STATUS_INVALID_CQ: - case OCRDMA_MBX_STATUS_INVALID_SRQ_ID: - case OCRDMA_MBX_STATUS_INVALID_QP: - case OCRDMA_MBX_STATUS_INVALID_CHANGE: - case OCRDMA_MBX_STATUS_MTU_EXCEEDS: - case OCRDMA_MBX_STATUS_INVALID_RNR_NAK_TIMER: - case OCRDMA_MBX_STATUS_PKEY_INDEX_INVALID: - case OCRDMA_MBX_STATUS_PKEY_INDEX_EXCEEDS: - case OCRDMA_MBX_STATUS_ILLEGAL_FIELD: - case OCRDMA_MBX_STATUS_INVALID_PBL_ENTRY: - case OCRDMA_MBX_STATUS_INVALID_LKEY: - case OCRDMA_MBX_STATUS_INVALID_VA: - case OCRDMA_MBX_STATUS_INVALID_LENGTH: - case OCRDMA_MBX_STATUS_INVALID_FBO: - case OCRDMA_MBX_STATUS_INVALID_ACC_RIGHTS: - case OCRDMA_MBX_STATUS_INVALID_PBE_SIZE: - case OCRDMA_MBX_STATUS_ATOMIC_OPS_UNSUP: - case OCRDMA_MBX_STATUS_SRQ_ERROR: - case OCRDMA_MBX_STATUS_SRQ_SIZE_UNDERUNS: - err_num = -EINVAL; - break; - - case OCRDMA_MBX_STATUS_PD_INUSE: - case OCRDMA_MBX_STATUS_QP_BOUND: - case OCRDMA_MBX_STATUS_MW_STILL_BOUND: - case OCRDMA_MBX_STATUS_MW_BOUND: - err_num = -EBUSY; - break; - - case OCRDMA_MBX_STATUS_RECVQ_RQE_EXCEEDS: - case OCRDMA_MBX_STATUS_SGE_RECV_EXCEEDS: - case OCRDMA_MBX_STATUS_RQE_EXCEEDS: - case OCRDMA_MBX_STATUS_SRQ_LIMIT_EXCEEDS: - case OCRDMA_MBX_STATUS_ORD_EXCEEDS: - case OCRDMA_MBX_STATUS_IRD_EXCEEDS: - case OCRDMA_MBX_STATUS_SENDQ_WQE_EXCEEDS: - case OCRDMA_MBX_STATUS_SGE_SEND_EXCEEDS: - case OCRDMA_MBX_STATUS_SGE_WRITE_EXCEEDS: - err_num = -ENOBUFS; - break; - - case OCRDMA_MBX_STATUS_FAILED: - switch (add_status) { - case OCRDMA_MBX_ADDI_STATUS_INSUFFICIENT_RESOURCES: - err_num = -EAGAIN; - break; - } - default: - err_num = -EFAULT; - } - return err_num; -} - -static int ocrdma_get_mbx_cqe_errno(u16 cqe_status) -{ - int err_num = -EINVAL; - - switch (cqe_status) { - case OCRDMA_MBX_CQE_STATUS_INSUFFICIENT_PRIVILEDGES: - err_num = -EPERM; - break; - case OCRDMA_MBX_CQE_STATUS_INVALID_PARAMETER: - err_num = -EINVAL; - break; - case OCRDMA_MBX_CQE_STATUS_INSUFFICIENT_RESOURCES: - case OCRDMA_MBX_CQE_STATUS_QUEUE_FLUSHING: - err_num = -EAGAIN; - break; - case OCRDMA_MBX_CQE_STATUS_DMA_FAILED: - err_num = -EIO; - break; - } - return err_num; -} - -void ocrdma_ring_cq_db(struct ocrdma_dev *dev, u16 cq_id, bool armed, - bool solicited, u16 cqe_popped) -{ - u32 val = cq_id & OCRDMA_DB_CQ_RING_ID_MASK; - - val |= ((cq_id & OCRDMA_DB_CQ_RING_ID_EXT_MASK) << - OCRDMA_DB_CQ_RING_ID_EXT_MASK_SHIFT); - - if (armed) - val |= (1 << OCRDMA_DB_CQ_REARM_SHIFT); - if (solicited) - val |= (1 << OCRDMA_DB_CQ_SOLICIT_SHIFT); - val |= (cqe_popped << OCRDMA_DB_CQ_NUM_POPPED_SHIFT); - iowrite32(val, dev->nic_info.db + OCRDMA_DB_CQ_OFFSET); -} - -static void ocrdma_ring_mq_db(struct ocrdma_dev *dev) -{ - u32 val = 0; - - val |= dev->mq.sq.id & OCRDMA_MQ_ID_MASK; - val |= 1 << OCRDMA_MQ_NUM_MQE_SHIFT; - iowrite32(val, dev->nic_info.db + OCRDMA_DB_MQ_OFFSET); -} - -static void ocrdma_ring_eq_db(struct ocrdma_dev *dev, u16 eq_id, - bool arm, bool clear_int, u16 num_eqe) -{ - u32 val = 0; - - val |= eq_id & OCRDMA_EQ_ID_MASK; - val |= ((eq_id & OCRDMA_EQ_ID_EXT_MASK) << OCRDMA_EQ_ID_EXT_MASK_SHIFT); - if (arm) - val |= (1 << OCRDMA_REARM_SHIFT); - if (clear_int) - val |= (1 << OCRDMA_EQ_CLR_SHIFT); - val |= (1 << OCRDMA_EQ_TYPE_SHIFT); - val |= (num_eqe << OCRDMA_NUM_EQE_SHIFT); - iowrite32(val, dev->nic_info.db + OCRDMA_DB_EQ_OFFSET); -} - -static void ocrdma_init_mch(struct ocrdma_mbx_hdr *cmd_hdr, - u8 opcode, u8 subsys, u32 cmd_len) -{ - cmd_hdr->subsys_op = (opcode | (subsys << OCRDMA_MCH_SUBSYS_SHIFT)); - cmd_hdr->timeout = 20; /* seconds */ - cmd_hdr->cmd_len = cmd_len - sizeof(struct ocrdma_mbx_hdr); -} - -static void *ocrdma_init_emb_mqe(u8 opcode, u32 cmd_len) -{ - struct ocrdma_mqe *mqe; - - mqe = kzalloc(sizeof(struct ocrdma_mqe), GFP_KERNEL); - if (!mqe) - return NULL; - mqe->hdr.spcl_sge_cnt_emb |= - (OCRDMA_MQE_EMBEDDED << OCRDMA_MQE_HDR_EMB_SHIFT) & - OCRDMA_MQE_HDR_EMB_MASK; - mqe->hdr.pyld_len = cmd_len - sizeof(struct ocrdma_mqe_hdr); - - ocrdma_init_mch(&mqe->u.emb_req.mch, opcode, OCRDMA_SUBSYS_ROCE, - mqe->hdr.pyld_len); - return mqe; -} - -static void ocrdma_free_q(struct ocrdma_dev *dev, struct ocrdma_queue_info *q) -{ - dma_free_coherent(&dev->nic_info.pdev->dev, q->size, q->va, q->dma); -} - -static int ocrdma_alloc_q(struct ocrdma_dev *dev, - struct ocrdma_queue_info *q, u16 len, u16 entry_size) -{ - memset(q, 0, sizeof(*q)); - q->len = len; - q->entry_size = entry_size; - q->size = len * entry_size; - q->va = dma_alloc_coherent(&dev->nic_info.pdev->dev, q->size, - &q->dma, GFP_KERNEL); - if (!q->va) - return -ENOMEM; - memset(q->va, 0, q->size); - return 0; -} - -static void ocrdma_build_q_pages(struct ocrdma_pa *q_pa, int cnt, - dma_addr_t host_pa, int hw_page_size) -{ - int i; - - for (i = 0; i < cnt; i++) { - q_pa[i].lo = (u32) (host_pa & 0xffffffff); - q_pa[i].hi = (u32) upper_32_bits(host_pa); - host_pa += hw_page_size; - } -} - -static void ocrdma_assign_eq_vect_gen2(struct ocrdma_dev *dev, - struct ocrdma_eq *eq) -{ - /* assign vector and update vector id for next EQ */ - eq->vector = dev->nic_info.msix.start_vector; - dev->nic_info.msix.start_vector += 1; -} - -static void ocrdma_free_eq_vect_gen2(struct ocrdma_dev *dev) -{ - /* this assumes that EQs are freed in exactly reverse order - * as its allocation. - */ - dev->nic_info.msix.start_vector -= 1; -} - -static int ocrdma_mbx_delete_q(struct ocrdma_dev *dev, struct ocrdma_queue_info *q, - int queue_type) -{ - u8 opcode = 0; - int status; - struct ocrdma_delete_q_req *cmd = dev->mbx_cmd; - - switch (queue_type) { - case QTYPE_MCCQ: - opcode = OCRDMA_CMD_DELETE_MQ; - break; - case QTYPE_CQ: - opcode = OCRDMA_CMD_DELETE_CQ; - break; - case QTYPE_EQ: - opcode = OCRDMA_CMD_DELETE_EQ; - break; - default: - BUG(); - } - memset(cmd, 0, sizeof(*cmd)); - ocrdma_init_mch(&cmd->req, opcode, OCRDMA_SUBSYS_COMMON, sizeof(*cmd)); - cmd->id = q->id; - - status = be_roce_mcc_cmd(dev->nic_info.netdev, - cmd, sizeof(*cmd), NULL, NULL); - if (!status) - q->created = false; - return status; -} - -static int ocrdma_mbx_create_eq(struct ocrdma_dev *dev, struct ocrdma_eq *eq) -{ - int status; - struct ocrdma_create_eq_req *cmd = dev->mbx_cmd; - struct ocrdma_create_eq_rsp *rsp = dev->mbx_cmd; - - memset(cmd, 0, sizeof(*cmd)); - ocrdma_init_mch(&cmd->req, OCRDMA_CMD_CREATE_EQ, OCRDMA_SUBSYS_COMMON, - sizeof(*cmd)); - if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) - cmd->req.rsvd_version = 0; - else - cmd->req.rsvd_version = 2; - - cmd->num_pages = 4; - cmd->valid = OCRDMA_CREATE_EQ_VALID; - cmd->cnt = 4 << OCRDMA_CREATE_EQ_CNT_SHIFT; - - ocrdma_build_q_pages(&cmd->pa[0], cmd->num_pages, eq->q.dma, - PAGE_SIZE_4K); - status = be_roce_mcc_cmd(dev->nic_info.netdev, cmd, sizeof(*cmd), NULL, - NULL); - if (!status) { - eq->q.id = rsp->vector_eqid & 0xffff; - if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) - ocrdma_assign_eq_vect_gen2(dev, eq); - else { - eq->vector = (rsp->vector_eqid >> 16) & 0xffff; - dev->nic_info.msix.start_vector += 1; - } - eq->q.created = true; - } - return status; -} - -static int ocrdma_create_eq(struct ocrdma_dev *dev, - struct ocrdma_eq *eq, u16 q_len) -{ - int status; - - status = ocrdma_alloc_q(dev, &eq->q, OCRDMA_EQ_LEN, - sizeof(struct ocrdma_eqe)); - if (status) - return status; - - status = ocrdma_mbx_create_eq(dev, eq); - if (status) - goto mbx_err; - eq->dev = dev; - ocrdma_ring_eq_db(dev, eq->q.id, true, true, 0); - - return 0; -mbx_err: - ocrdma_free_q(dev, &eq->q); - return status; -} - -static int ocrdma_get_irq(struct ocrdma_dev *dev, struct ocrdma_eq *eq) -{ - int irq; - - if (dev->nic_info.intr_mode == BE_INTERRUPT_MODE_INTX) - irq = dev->nic_info.pdev->irq; - else - irq = dev->nic_info.msix.vector_list[eq->vector]; - return irq; -} - -static void _ocrdma_destroy_eq(struct ocrdma_dev *dev, struct ocrdma_eq *eq) -{ - if (eq->q.created) { - ocrdma_mbx_delete_q(dev, &eq->q, QTYPE_EQ); - if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) - ocrdma_free_eq_vect_gen2(dev); - ocrdma_free_q(dev, &eq->q); - } -} - -static void ocrdma_destroy_eq(struct ocrdma_dev *dev, struct ocrdma_eq *eq) -{ - int irq; - - /* disarm EQ so that interrupts are not generated - * during freeing and EQ delete is in progress. - */ - ocrdma_ring_eq_db(dev, eq->q.id, false, false, 0); - - irq = ocrdma_get_irq(dev, eq); - free_irq(irq, eq); - _ocrdma_destroy_eq(dev, eq); -} - -static void ocrdma_destroy_qp_eqs(struct ocrdma_dev *dev) -{ - int i; - - /* deallocate the data path eqs */ - for (i = 0; i < dev->eq_cnt; i++) - ocrdma_destroy_eq(dev, &dev->qp_eq_tbl[i]); -} - -static int ocrdma_mbx_mq_cq_create(struct ocrdma_dev *dev, - struct ocrdma_queue_info *cq, - struct ocrdma_queue_info *eq) -{ - struct ocrdma_create_cq_cmd *cmd = dev->mbx_cmd; - struct ocrdma_create_cq_cmd_rsp *rsp = dev->mbx_cmd; - int status; - - memset(cmd, 0, sizeof(*cmd)); - ocrdma_init_mch(&cmd->req, OCRDMA_CMD_CREATE_CQ, - OCRDMA_SUBSYS_COMMON, sizeof(*cmd)); - - cmd->pgsz_pgcnt = PAGES_4K_SPANNED(cq->va, cq->size); - cmd->ev_cnt_flags = OCRDMA_CREATE_CQ_DEF_FLAGS; - cmd->eqn = (eq->id << OCRDMA_CREATE_CQ_EQID_SHIFT); - - ocrdma_build_q_pages(&cmd->pa[0], cmd->pgsz_pgcnt, - cq->dma, PAGE_SIZE_4K); - status = be_roce_mcc_cmd(dev->nic_info.netdev, - cmd, sizeof(*cmd), NULL, NULL); - if (!status) { - cq->id = (rsp->cq_id & OCRDMA_CREATE_CQ_RSP_CQ_ID_MASK); - cq->created = true; - } - return status; -} - -static u32 ocrdma_encoded_q_len(int q_len) -{ - u32 len_encoded = fls(q_len); /* log2(len) + 1 */ - - if (len_encoded == 16) - len_encoded = 0; - return len_encoded; -} - -static int ocrdma_mbx_create_mq(struct ocrdma_dev *dev, - struct ocrdma_queue_info *mq, - struct ocrdma_queue_info *cq) -{ - int num_pages, status; - struct ocrdma_create_mq_req *cmd = dev->mbx_cmd; - struct ocrdma_create_mq_rsp *rsp = dev->mbx_cmd; - struct ocrdma_pa *pa; - - memset(cmd, 0, sizeof(*cmd)); - num_pages = PAGES_4K_SPANNED(mq->va, mq->size); - - if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { - ocrdma_init_mch(&cmd->req, OCRDMA_CMD_CREATE_MQ, - OCRDMA_SUBSYS_COMMON, sizeof(*cmd)); - cmd->v0.pages = num_pages; - cmd->v0.async_cqid_valid = OCRDMA_CREATE_MQ_ASYNC_CQ_VALID; - cmd->v0.async_cqid_valid = (cq->id << 1); - cmd->v0.cqid_ringsize |= (ocrdma_encoded_q_len(mq->len) << - OCRDMA_CREATE_MQ_RING_SIZE_SHIFT); - cmd->v0.cqid_ringsize |= - (cq->id << OCRDMA_CREATE_MQ_V0_CQ_ID_SHIFT); - cmd->v0.valid = OCRDMA_CREATE_MQ_VALID; - pa = &cmd->v0.pa[0]; - } else { - ocrdma_init_mch(&cmd->req, OCRDMA_CMD_CREATE_MQ_EXT, - OCRDMA_SUBSYS_COMMON, sizeof(*cmd)); - cmd->req.rsvd_version = 1; - cmd->v1.cqid_pages = num_pages; - cmd->v1.cqid_pages |= (cq->id << OCRDMA_CREATE_MQ_CQ_ID_SHIFT); - cmd->v1.async_cqid_valid = OCRDMA_CREATE_MQ_ASYNC_CQ_VALID; - cmd->v1.async_event_bitmap = Bit(20); - cmd->v1.async_cqid_ringsize = cq->id; - cmd->v1.async_cqid_ringsize |= (ocrdma_encoded_q_len(mq->len) << - OCRDMA_CREATE_MQ_RING_SIZE_SHIFT); - cmd->v1.valid = OCRDMA_CREATE_MQ_VALID; - pa = &cmd->v1.pa[0]; - } - ocrdma_build_q_pages(pa, num_pages, mq->dma, PAGE_SIZE_4K); - status = be_roce_mcc_cmd(dev->nic_info.netdev, - cmd, sizeof(*cmd), NULL, NULL); - if (!status) { - mq->id = rsp->id; - mq->created = true; - } - return status; -} - -static int ocrdma_create_mq(struct ocrdma_dev *dev) -{ - int status; - - /* Alloc completion queue for Mailbox queue */ - status = ocrdma_alloc_q(dev, &dev->mq.cq, OCRDMA_MQ_CQ_LEN, - sizeof(struct ocrdma_mcqe)); - if (status) - goto alloc_err; - - status = ocrdma_mbx_mq_cq_create(dev, &dev->mq.cq, &dev->meq.q); - if (status) - goto mbx_cq_free; - - memset(&dev->mqe_ctx, 0, sizeof(dev->mqe_ctx)); - init_waitqueue_head(&dev->mqe_ctx.cmd_wait); - mutex_init(&dev->mqe_ctx.lock); - - /* Alloc Mailbox queue */ - status = ocrdma_alloc_q(dev, &dev->mq.sq, OCRDMA_MQ_LEN, - sizeof(struct ocrdma_mqe)); - if (status) - goto mbx_cq_destroy; - status = ocrdma_mbx_create_mq(dev, &dev->mq.sq, &dev->mq.cq); - if (status) - goto mbx_q_free; - ocrdma_ring_cq_db(dev, dev->mq.cq.id, true, false, 0); - return 0; - -mbx_q_free: - ocrdma_free_q(dev, &dev->mq.sq); -mbx_cq_destroy: - ocrdma_mbx_delete_q(dev, &dev->mq.cq, QTYPE_CQ); -mbx_cq_free: - ocrdma_free_q(dev, &dev->mq.cq); -alloc_err: - return status; -} - -static void ocrdma_destroy_mq(struct ocrdma_dev *dev) -{ - struct ocrdma_queue_info *mbxq, *cq; - - /* mqe_ctx lock synchronizes with any other pending cmds. */ - mutex_lock(&dev->mqe_ctx.lock); - mbxq = &dev->mq.sq; - if (mbxq->created) { - ocrdma_mbx_delete_q(dev, mbxq, QTYPE_MCCQ); - ocrdma_free_q(dev, mbxq); - } - mutex_unlock(&dev->mqe_ctx.lock); - - cq = &dev->mq.cq; - if (cq->created) { - ocrdma_mbx_delete_q(dev, cq, QTYPE_CQ); - ocrdma_free_q(dev, cq); - } -} - -static void ocrdma_process_qpcat_error(struct ocrdma_dev *dev, - struct ocrdma_qp *qp) -{ - enum ib_qp_state new_ib_qps = IB_QPS_ERR; - enum ib_qp_state old_ib_qps; - - if (qp == NULL) - BUG(); - ocrdma_qp_state_machine(qp, new_ib_qps, &old_ib_qps); -} - -static void ocrdma_dispatch_ibevent(struct ocrdma_dev *dev, - struct ocrdma_ae_mcqe *cqe) -{ - struct ocrdma_qp *qp = NULL; - struct ocrdma_cq *cq = NULL; - struct ib_event ib_evt; - int cq_event = 0; - int qp_event = 1; - int srq_event = 0; - int dev_event = 0; - int type = (cqe->valid_ae_event & OCRDMA_AE_MCQE_EVENT_TYPE_MASK) >> - OCRDMA_AE_MCQE_EVENT_TYPE_SHIFT; - - if (cqe->qpvalid_qpid & OCRDMA_AE_MCQE_QPVALID) - qp = dev->qp_tbl[cqe->qpvalid_qpid & OCRDMA_AE_MCQE_QPID_MASK]; - if (cqe->cqvalid_cqid & OCRDMA_AE_MCQE_CQVALID) - cq = dev->cq_tbl[cqe->cqvalid_cqid & OCRDMA_AE_MCQE_CQID_MASK]; - - ib_evt.device = &dev->ibdev; - - switch (type) { - case OCRDMA_CQ_ERROR: - ib_evt.element.cq = &cq->ibcq; - ib_evt.event = IB_EVENT_CQ_ERR; - cq_event = 1; - qp_event = 0; - break; - case OCRDMA_CQ_OVERRUN_ERROR: - ib_evt.element.cq = &cq->ibcq; - ib_evt.event = IB_EVENT_CQ_ERR; - break; - case OCRDMA_CQ_QPCAT_ERROR: - ib_evt.element.qp = &qp->ibqp; - ib_evt.event = IB_EVENT_QP_FATAL; - ocrdma_process_qpcat_error(dev, qp); - break; - case OCRDMA_QP_ACCESS_ERROR: - ib_evt.element.qp = &qp->ibqp; - ib_evt.event = IB_EVENT_QP_ACCESS_ERR; - break; - case OCRDMA_QP_COMM_EST_EVENT: - ib_evt.element.qp = &qp->ibqp; - ib_evt.event = IB_EVENT_COMM_EST; - break; - case OCRDMA_SQ_DRAINED_EVENT: - ib_evt.element.qp = &qp->ibqp; - ib_evt.event = IB_EVENT_SQ_DRAINED; - break; - case OCRDMA_DEVICE_FATAL_EVENT: - ib_evt.element.port_num = 1; - ib_evt.event = IB_EVENT_DEVICE_FATAL; - qp_event = 0; - dev_event = 1; - break; - case OCRDMA_SRQCAT_ERROR: - ib_evt.element.srq = &qp->srq->ibsrq; - ib_evt.event = IB_EVENT_SRQ_ERR; - srq_event = 1; - qp_event = 0; - break; - case OCRDMA_SRQ_LIMIT_EVENT: - ib_evt.element.srq = &qp->srq->ibsrq; - ib_evt.event = IB_EVENT_QP_LAST_WQE_REACHED; - srq_event = 1; - qp_event = 0; - break; - case OCRDMA_QP_LAST_WQE_EVENT: - ib_evt.element.qp = &qp->ibqp; - ib_evt.event = IB_EVENT_QP_LAST_WQE_REACHED; - break; - default: - cq_event = 0; - qp_event = 0; - srq_event = 0; - dev_event = 0; - ocrdma_err("%s() unknown type=0x%x\n", __func__, type); - break; - } - - if (qp_event) { - if (qp->ibqp.event_handler) - qp->ibqp.event_handler(&ib_evt, qp->ibqp.qp_context); - } else if (cq_event) { - if (cq->ibcq.event_handler) - cq->ibcq.event_handler(&ib_evt, cq->ibcq.cq_context); - } else if (srq_event) { - if (qp->srq->ibsrq.event_handler) - qp->srq->ibsrq.event_handler(&ib_evt, - qp->srq->ibsrq. - srq_context); - } else if (dev_event) - ib_dispatch_event(&ib_evt); - -} - -static void ocrdma_process_acqe(struct ocrdma_dev *dev, void *ae_cqe) -{ - /* async CQE processing */ - struct ocrdma_ae_mcqe *cqe = ae_cqe; - u32 evt_code = (cqe->valid_ae_event & OCRDMA_AE_MCQE_EVENT_CODE_MASK) >> - OCRDMA_AE_MCQE_EVENT_CODE_SHIFT; - - if (evt_code == OCRDMA_ASYNC_EVE_CODE) - ocrdma_dispatch_ibevent(dev, cqe); - else - ocrdma_err("%s(%d) invalid evt code=0x%x\n", - __func__, dev->id, evt_code); -} - -static void ocrdma_process_mcqe(struct ocrdma_dev *dev, struct ocrdma_mcqe *cqe) -{ - if (dev->mqe_ctx.tag == cqe->tag_lo && dev->mqe_ctx.cmd_done == false) { - dev->mqe_ctx.cqe_status = (cqe->status & - OCRDMA_MCQE_STATUS_MASK) >> OCRDMA_MCQE_STATUS_SHIFT; - dev->mqe_ctx.ext_status = - (cqe->status & OCRDMA_MCQE_ESTATUS_MASK) - >> OCRDMA_MCQE_ESTATUS_SHIFT; - dev->mqe_ctx.cmd_done = true; - wake_up(&dev->mqe_ctx.cmd_wait); - } else - ocrdma_err("%s() cqe for invalid tag0x%x.expected=0x%x\n", - __func__, cqe->tag_lo, dev->mqe_ctx.tag); -} - -static int ocrdma_mq_cq_handler(struct ocrdma_dev *dev, u16 cq_id) -{ - u16 cqe_popped = 0; - struct ocrdma_mcqe *cqe; - - while (1) { - cqe = ocrdma_get_mcqe(dev); - if (cqe == NULL) - break; - ocrdma_le32_to_cpu(cqe, sizeof(*cqe)); - cqe_popped += 1; - if (cqe->valid_ae_cmpl_cons & OCRDMA_MCQE_AE_MASK) - ocrdma_process_acqe(dev, cqe); - else if (cqe->valid_ae_cmpl_cons & OCRDMA_MCQE_CMPL_MASK) - ocrdma_process_mcqe(dev, cqe); - else - ocrdma_err("%s() cqe->compl is not set.\n", __func__); - memset(cqe, 0, sizeof(struct ocrdma_mcqe)); - ocrdma_mcq_inc_tail(dev); - } - ocrdma_ring_cq_db(dev, dev->mq.cq.id, true, false, cqe_popped); - return 0; -} - -static void ocrdma_qp_buddy_cq_handler(struct ocrdma_dev *dev, - struct ocrdma_cq *cq) -{ - unsigned long flags; - struct ocrdma_qp *qp; - bool buddy_cq_found = false; - /* Go through list of QPs in error state which are using this CQ - * and invoke its callback handler to trigger CQE processing for - * error/flushed CQE. It is rare to find more than few entries in - * this list as most consumers stops after getting error CQE. - * List is traversed only once when a matching buddy cq found for a QP. - */ - spin_lock_irqsave(&dev->flush_q_lock, flags); - list_for_each_entry(qp, &cq->sq_head, sq_entry) { - if (qp->srq) - continue; - /* if wq and rq share the same cq, than comp_handler - * is already invoked. - */ - if (qp->sq_cq == qp->rq_cq) - continue; - /* if completion came on sq, rq's cq is buddy cq. - * if completion came on rq, sq's cq is buddy cq. - */ - if (qp->sq_cq == cq) - cq = qp->rq_cq; - else - cq = qp->sq_cq; - buddy_cq_found = true; - break; - } - spin_unlock_irqrestore(&dev->flush_q_lock, flags); - if (buddy_cq_found == false) - return; - if (cq->ibcq.comp_handler) { - spin_lock_irqsave(&cq->comp_handler_lock, flags); - (*cq->ibcq.comp_handler) (&cq->ibcq, cq->ibcq.cq_context); - spin_unlock_irqrestore(&cq->comp_handler_lock, flags); - } -} - -static void ocrdma_qp_cq_handler(struct ocrdma_dev *dev, u16 cq_idx) -{ - unsigned long flags; - struct ocrdma_cq *cq; - - if (cq_idx >= OCRDMA_MAX_CQ) - BUG(); - - cq = dev->cq_tbl[cq_idx]; - if (cq == NULL) { - ocrdma_err("%s%d invalid id=0x%x\n", __func__, dev->id, cq_idx); - return; - } - spin_lock_irqsave(&cq->cq_lock, flags); - cq->armed = false; - cq->solicited = false; - spin_unlock_irqrestore(&cq->cq_lock, flags); - - ocrdma_ring_cq_db(dev, cq->id, false, false, 0); - - if (cq->ibcq.comp_handler) { - spin_lock_irqsave(&cq->comp_handler_lock, flags); - (*cq->ibcq.comp_handler) (&cq->ibcq, cq->ibcq.cq_context); - spin_unlock_irqrestore(&cq->comp_handler_lock, flags); - } - ocrdma_qp_buddy_cq_handler(dev, cq); -} - -static void ocrdma_cq_handler(struct ocrdma_dev *dev, u16 cq_id) -{ - /* process the MQ-CQE. */ - if (cq_id == dev->mq.cq.id) - ocrdma_mq_cq_handler(dev, cq_id); - else - ocrdma_qp_cq_handler(dev, cq_id); -} - -static irqreturn_t ocrdma_irq_handler(int irq, void *handle) -{ - struct ocrdma_eq *eq = handle; - struct ocrdma_dev *dev = eq->dev; - struct ocrdma_eqe eqe; - struct ocrdma_eqe *ptr; - u16 eqe_popped = 0; - u16 cq_id; - while (1) { - ptr = ocrdma_get_eqe(eq); - eqe = *ptr; - ocrdma_le32_to_cpu(&eqe, sizeof(eqe)); - if ((eqe.id_valid & OCRDMA_EQE_VALID_MASK) == 0) - break; - eqe_popped += 1; - ptr->id_valid = 0; - /* check whether its CQE or not. */ - if ((eqe.id_valid & OCRDMA_EQE_FOR_CQE_MASK) == 0) { - cq_id = eqe.id_valid >> OCRDMA_EQE_RESOURCE_ID_SHIFT; - ocrdma_cq_handler(dev, cq_id); - } - ocrdma_eq_inc_tail(eq); - } - ocrdma_ring_eq_db(dev, eq->q.id, true, true, eqe_popped); - /* Ring EQ doorbell with num_popped to 0 to enable interrupts again. */ - if (dev->nic_info.intr_mode == BE_INTERRUPT_MODE_INTX) - ocrdma_ring_eq_db(dev, eq->q.id, true, true, 0); - return IRQ_HANDLED; -} - -static void ocrdma_post_mqe(struct ocrdma_dev *dev, struct ocrdma_mqe *cmd) -{ - struct ocrdma_mqe *mqe; - - dev->mqe_ctx.tag = dev->mq.sq.head; - dev->mqe_ctx.cmd_done = false; - mqe = ocrdma_get_mqe(dev); - cmd->hdr.tag_lo = dev->mq.sq.head; - ocrdma_copy_cpu_to_le32(mqe, cmd, sizeof(*mqe)); - /* make sure descriptor is written before ringing doorbell */ - wmb(); - ocrdma_mq_inc_head(dev); - ocrdma_ring_mq_db(dev); -} - -static int ocrdma_wait_mqe_cmpl(struct ocrdma_dev *dev) -{ - long status; - /* 30 sec timeout */ - status = wait_event_timeout(dev->mqe_ctx.cmd_wait, - (dev->mqe_ctx.cmd_done != false), - msecs_to_jiffies(30000)); - if (status) - return 0; - else - return -1; -} - -/* issue a mailbox command on the MQ */ -static int ocrdma_mbx_cmd(struct ocrdma_dev *dev, struct ocrdma_mqe *mqe) -{ - int status = 0; - u16 cqe_status, ext_status; - struct ocrdma_mqe *rsp; - - mutex_lock(&dev->mqe_ctx.lock); - ocrdma_post_mqe(dev, mqe); - status = ocrdma_wait_mqe_cmpl(dev); - if (status) - goto mbx_err; - cqe_status = dev->mqe_ctx.cqe_status; - ext_status = dev->mqe_ctx.ext_status; - rsp = ocrdma_get_mqe_rsp(dev); - ocrdma_copy_le32_to_cpu(mqe, rsp, (sizeof(*mqe))); - if (cqe_status || ext_status) { - ocrdma_err - ("%s() opcode=0x%x, cqe_status=0x%x, ext_status=0x%x\n", - __func__, - (rsp->u.rsp.subsys_op & OCRDMA_MBX_RSP_OPCODE_MASK) >> - OCRDMA_MBX_RSP_OPCODE_SHIFT, cqe_status, ext_status); - status = ocrdma_get_mbx_cqe_errno(cqe_status); - goto mbx_err; - } - if (mqe->u.rsp.status & OCRDMA_MBX_RSP_STATUS_MASK) - status = ocrdma_get_mbx_errno(mqe->u.rsp.status); -mbx_err: - mutex_unlock(&dev->mqe_ctx.lock); - return status; -} - -static void ocrdma_get_attr(struct ocrdma_dev *dev, - struct ocrdma_dev_attr *attr, - struct ocrdma_mbx_query_config *rsp) -{ - int max_q_mem; - - attr->max_pd = - (rsp->max_pd_ca_ack_delay & OCRDMA_MBX_QUERY_CFG_MAX_PD_MASK) >> - OCRDMA_MBX_QUERY_CFG_MAX_PD_SHIFT; - attr->max_qp = - (rsp->qp_srq_cq_ird_ord & OCRDMA_MBX_QUERY_CFG_MAX_QP_MASK) >> - OCRDMA_MBX_QUERY_CFG_MAX_QP_SHIFT; - attr->max_send_sge = ((rsp->max_write_send_sge & - OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK) >> - OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT); - attr->max_recv_sge = (rsp->max_write_send_sge & - OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK) >> - OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT; - attr->max_ord_per_qp = (rsp->max_ird_ord_per_qp & - OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK) >> - OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT; - attr->max_ird_per_qp = (rsp->max_ird_ord_per_qp & - OCRDMA_MBX_QUERY_CFG_MAX_IRD_PER_QP_MASK) >> - OCRDMA_MBX_QUERY_CFG_MAX_IRD_PER_QP_SHIFT; - attr->cq_overflow_detect = (rsp->qp_srq_cq_ird_ord & - OCRDMA_MBX_QUERY_CFG_CQ_OVERFLOW_MASK) >> - OCRDMA_MBX_QUERY_CFG_CQ_OVERFLOW_SHIFT; - attr->srq_supported = (rsp->qp_srq_cq_ird_ord & - OCRDMA_MBX_QUERY_CFG_SRQ_SUPPORTED_MASK) >> - OCRDMA_MBX_QUERY_CFG_SRQ_SUPPORTED_SHIFT; - attr->local_ca_ack_delay = (rsp->max_pd_ca_ack_delay & - OCRDMA_MBX_QUERY_CFG_CA_ACK_DELAY_MASK) >> - OCRDMA_MBX_QUERY_CFG_CA_ACK_DELAY_SHIFT; - attr->max_mr = rsp->max_mr; - attr->max_mr_size = ~0ull; - attr->max_fmr = 0; - attr->max_pages_per_frmr = rsp->max_pages_per_frmr; - attr->max_num_mr_pbl = rsp->max_num_mr_pbl; - attr->max_cqe = rsp->max_cq_cqes_per_cq & - OCRDMA_MBX_QUERY_CFG_MAX_CQES_PER_CQ_MASK; - attr->wqe_size = ((rsp->wqe_rqe_stride_max_dpp_cqs & - OCRDMA_MBX_QUERY_CFG_MAX_WQE_SIZE_MASK) >> - OCRDMA_MBX_QUERY_CFG_MAX_WQE_SIZE_OFFSET) * - OCRDMA_WQE_STRIDE; - attr->rqe_size = ((rsp->wqe_rqe_stride_max_dpp_cqs & - OCRDMA_MBX_QUERY_CFG_MAX_RQE_SIZE_MASK) >> - OCRDMA_MBX_QUERY_CFG_MAX_RQE_SIZE_OFFSET) * - OCRDMA_WQE_STRIDE; - attr->max_inline_data = - attr->wqe_size - (sizeof(struct ocrdma_hdr_wqe) + - sizeof(struct ocrdma_sge)); - max_q_mem = OCRDMA_Q_PAGE_BASE_SIZE << (OCRDMA_MAX_Q_PAGE_SIZE_CNT - 1); - /* hw can queue one less then the configured size, - * so publish less by one to stack. - */ - if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { - dev->attr.max_wqe = max_q_mem / dev->attr.wqe_size; - attr->ird = 1; - attr->ird_page_size = OCRDMA_MIN_Q_PAGE_SIZE; - attr->num_ird_pages = MAX_OCRDMA_IRD_PAGES; - } else - dev->attr.max_wqe = (max_q_mem / dev->attr.wqe_size) - 1; - dev->attr.max_rqe = (max_q_mem / dev->attr.rqe_size) - 1; -} - -static int ocrdma_check_fw_config(struct ocrdma_dev *dev, - struct ocrdma_fw_conf_rsp *conf) -{ - u32 fn_mode; - - fn_mode = conf->fn_mode & OCRDMA_FN_MODE_RDMA; - if (fn_mode != OCRDMA_FN_MODE_RDMA) - return -EINVAL; - dev->base_eqid = conf->base_eqid; - dev->max_eq = conf->max_eq; - dev->attr.max_cq = OCRDMA_MAX_CQ - 1; - return 0; -} - -/* can be issued only during init time. */ -static int ocrdma_mbx_query_fw_ver(struct ocrdma_dev *dev) -{ - int status = -ENOMEM; - struct ocrdma_mqe *cmd; - struct ocrdma_fw_ver_rsp *rsp; - - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_GET_FW_VER, sizeof(*cmd)); - if (!cmd) - return -ENOMEM; - ocrdma_init_mch((struct ocrdma_mbx_hdr *)&cmd->u.cmd[0], - OCRDMA_CMD_GET_FW_VER, - OCRDMA_SUBSYS_COMMON, sizeof(*cmd)); - - status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); - if (status) - goto mbx_err; - rsp = (struct ocrdma_fw_ver_rsp *)cmd; - memset(&dev->attr.fw_ver[0], 0, sizeof(dev->attr.fw_ver)); - memcpy(&dev->attr.fw_ver[0], &rsp->running_ver[0], - sizeof(rsp->running_ver)); - ocrdma_le32_to_cpu(dev->attr.fw_ver, sizeof(rsp->running_ver)); -mbx_err: - kfree(cmd); - return status; -} - -/* can be issued only during init time. */ -static int ocrdma_mbx_query_fw_config(struct ocrdma_dev *dev) -{ - int status = -ENOMEM; - struct ocrdma_mqe *cmd; - struct ocrdma_fw_conf_rsp *rsp; - - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_GET_FW_CONFIG, sizeof(*cmd)); - if (!cmd) - return -ENOMEM; - ocrdma_init_mch((struct ocrdma_mbx_hdr *)&cmd->u.cmd[0], - OCRDMA_CMD_GET_FW_CONFIG, - OCRDMA_SUBSYS_COMMON, sizeof(*cmd)); - status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); - if (status) - goto mbx_err; - rsp = (struct ocrdma_fw_conf_rsp *)cmd; - status = ocrdma_check_fw_config(dev, rsp); -mbx_err: - kfree(cmd); - return status; -} - -static int ocrdma_mbx_query_dev(struct ocrdma_dev *dev) -{ - int status = -ENOMEM; - struct ocrdma_mbx_query_config *rsp; - struct ocrdma_mqe *cmd; - - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_QUERY_CONFIG, sizeof(*cmd)); - if (!cmd) - return status; - status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); - if (status) - goto mbx_err; - rsp = (struct ocrdma_mbx_query_config *)cmd; - ocrdma_get_attr(dev, &dev->attr, rsp); -mbx_err: - kfree(cmd); - return status; -} - -int ocrdma_mbx_alloc_pd(struct ocrdma_dev *dev, struct ocrdma_pd *pd) -{ - int status = -ENOMEM; - struct ocrdma_alloc_pd *cmd; - struct ocrdma_alloc_pd_rsp *rsp; - - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_ALLOC_PD, sizeof(*cmd)); - if (!cmd) - return status; - if (pd->dpp_enabled) - cmd->enable_dpp_rsvd |= OCRDMA_ALLOC_PD_ENABLE_DPP; - status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); - if (status) - goto mbx_err; - rsp = (struct ocrdma_alloc_pd_rsp *)cmd; - pd->id = rsp->dpp_page_pdid & OCRDMA_ALLOC_PD_RSP_PDID_MASK; - if (rsp->dpp_page_pdid & OCRDMA_ALLOC_PD_RSP_DPP) { - pd->dpp_enabled = true; - pd->dpp_page = rsp->dpp_page_pdid >> - OCRDMA_ALLOC_PD_RSP_DPP_PAGE_SHIFT; - } else { - pd->dpp_enabled = false; - pd->num_dpp_qp = 0; - } -mbx_err: - kfree(cmd); - return status; -} - -int ocrdma_mbx_dealloc_pd(struct ocrdma_dev *dev, struct ocrdma_pd *pd) -{ - int status = -ENOMEM; - struct ocrdma_dealloc_pd *cmd; - - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_DEALLOC_PD, sizeof(*cmd)); - if (!cmd) - return status; - cmd->id = pd->id; - status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); - kfree(cmd); - return status; -} - -static int ocrdma_build_q_conf(u32 *num_entries, int entry_size, - int *num_pages, int *page_size) -{ - int i; - int mem_size; - - *num_entries = roundup_pow_of_two(*num_entries); - mem_size = *num_entries * entry_size; - /* find the possible lowest possible multiplier */ - for (i = 0; i < OCRDMA_MAX_Q_PAGE_SIZE_CNT; i++) { - if (mem_size <= (OCRDMA_Q_PAGE_BASE_SIZE << i)) - break; - } - if (i >= OCRDMA_MAX_Q_PAGE_SIZE_CNT) - return -EINVAL; - mem_size = roundup(mem_size, - ((OCRDMA_Q_PAGE_BASE_SIZE << i) / OCRDMA_MAX_Q_PAGES)); - *num_pages = - mem_size / ((OCRDMA_Q_PAGE_BASE_SIZE << i) / OCRDMA_MAX_Q_PAGES); - *page_size = ((OCRDMA_Q_PAGE_BASE_SIZE << i) / OCRDMA_MAX_Q_PAGES); - *num_entries = mem_size / entry_size; - return 0; -} - -static int ocrdma_mbx_create_ah_tbl(struct ocrdma_dev *dev) -{ - int i ; - int status = 0; - int max_ah; - struct ocrdma_create_ah_tbl *cmd; - struct ocrdma_create_ah_tbl_rsp *rsp; - struct pci_dev *pdev = dev->nic_info.pdev; - dma_addr_t pa; - struct ocrdma_pbe *pbes; - - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_CREATE_AH_TBL, sizeof(*cmd)); - if (!cmd) - return status; - - max_ah = OCRDMA_MAX_AH; - dev->av_tbl.size = sizeof(struct ocrdma_av) * max_ah; - - /* number of PBEs in PBL */ - cmd->ah_conf = (OCRDMA_AH_TBL_PAGES << - OCRDMA_CREATE_AH_NUM_PAGES_SHIFT) & - OCRDMA_CREATE_AH_NUM_PAGES_MASK; - - /* page size */ - for (i = 0; i < OCRDMA_MAX_Q_PAGE_SIZE_CNT; i++) { - if (PAGE_SIZE == (OCRDMA_MIN_Q_PAGE_SIZE << i)) - break; - } - cmd->ah_conf |= (i << OCRDMA_CREATE_AH_PAGE_SIZE_SHIFT) & - OCRDMA_CREATE_AH_PAGE_SIZE_MASK; - - /* ah_entry size */ - cmd->ah_conf |= (sizeof(struct ocrdma_av) << - OCRDMA_CREATE_AH_ENTRY_SIZE_SHIFT) & - OCRDMA_CREATE_AH_ENTRY_SIZE_MASK; - - dev->av_tbl.pbl.va = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, - &dev->av_tbl.pbl.pa, - GFP_KERNEL); - if (dev->av_tbl.pbl.va == NULL) - goto mem_err; - - dev->av_tbl.va = dma_alloc_coherent(&pdev->dev, dev->av_tbl.size, - &pa, GFP_KERNEL); - if (dev->av_tbl.va == NULL) - goto mem_err_ah; - dev->av_tbl.pa = pa; - dev->av_tbl.num_ah = max_ah; - memset(dev->av_tbl.va, 0, dev->av_tbl.size); - - pbes = (struct ocrdma_pbe *)dev->av_tbl.pbl.va; - for (i = 0; i < dev->av_tbl.size / OCRDMA_MIN_Q_PAGE_SIZE; i++) { - pbes[i].pa_lo = (u32) (pa & 0xffffffff); - pbes[i].pa_hi = (u32) upper_32_bits(pa); - pa += PAGE_SIZE; - } - cmd->tbl_addr[0].lo = (u32)(dev->av_tbl.pbl.pa & 0xFFFFFFFF); - cmd->tbl_addr[0].hi = (u32)upper_32_bits(dev->av_tbl.pbl.pa); - status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); - if (status) - goto mbx_err; - rsp = (struct ocrdma_create_ah_tbl_rsp *)cmd; - dev->av_tbl.ahid = rsp->ahid & 0xFFFF; - kfree(cmd); - return 0; - -mbx_err: - dma_free_coherent(&pdev->dev, dev->av_tbl.size, dev->av_tbl.va, - dev->av_tbl.pa); - dev->av_tbl.va = NULL; -mem_err_ah: - dma_free_coherent(&pdev->dev, PAGE_SIZE, dev->av_tbl.pbl.va, - dev->av_tbl.pbl.pa); - dev->av_tbl.pbl.va = NULL; - dev->av_tbl.size = 0; -mem_err: - kfree(cmd); - return status; -} - -static void ocrdma_mbx_delete_ah_tbl(struct ocrdma_dev *dev) -{ - struct ocrdma_delete_ah_tbl *cmd; - struct pci_dev *pdev = dev->nic_info.pdev; - - if (dev->av_tbl.va == NULL) - return; - - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_DELETE_AH_TBL, sizeof(*cmd)); - if (!cmd) - return; - cmd->ahid = dev->av_tbl.ahid; - - ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); - dma_free_coherent(&pdev->dev, dev->av_tbl.size, dev->av_tbl.va, - dev->av_tbl.pa); - dma_free_coherent(&pdev->dev, PAGE_SIZE, dev->av_tbl.pbl.va, - dev->av_tbl.pbl.pa); - kfree(cmd); -} - -/* Multiple CQs uses the EQ. This routine returns least used - * EQ to associate with CQ. This will distributes the interrupt - * processing and CPU load to associated EQ, vector and so to that CPU. - */ -static u16 ocrdma_bind_eq(struct ocrdma_dev *dev) -{ - int i, selected_eq = 0, cq_cnt = 0; - u16 eq_id; - - mutex_lock(&dev->dev_lock); - cq_cnt = dev->qp_eq_tbl[0].cq_cnt; - eq_id = dev->qp_eq_tbl[0].q.id; - /* find the EQ which is has the least number of - * CQs associated with it. - */ - for (i = 0; i < dev->eq_cnt; i++) { - if (dev->qp_eq_tbl[i].cq_cnt < cq_cnt) { - cq_cnt = dev->qp_eq_tbl[i].cq_cnt; - eq_id = dev->qp_eq_tbl[i].q.id; - selected_eq = i; - } - } - dev->qp_eq_tbl[selected_eq].cq_cnt += 1; - mutex_unlock(&dev->dev_lock); - return eq_id; -} - -static void ocrdma_unbind_eq(struct ocrdma_dev *dev, u16 eq_id) -{ - int i; - - mutex_lock(&dev->dev_lock); - for (i = 0; i < dev->eq_cnt; i++) { - if (dev->qp_eq_tbl[i].q.id != eq_id) - continue; - dev->qp_eq_tbl[i].cq_cnt -= 1; - break; - } - mutex_unlock(&dev->dev_lock); -} - -int ocrdma_mbx_create_cq(struct ocrdma_dev *dev, struct ocrdma_cq *cq, - int entries, int dpp_cq) -{ - int status = -ENOMEM; int max_hw_cqe; - struct pci_dev *pdev = dev->nic_info.pdev; - struct ocrdma_create_cq *cmd; - struct ocrdma_create_cq_rsp *rsp; - u32 hw_pages, cqe_size, page_size, cqe_count; - - if (dpp_cq) - return -EINVAL; - if (entries > dev->attr.max_cqe) { - ocrdma_err("%s(%d) max_cqe=0x%x, requester_cqe=0x%x\n", - __func__, dev->id, dev->attr.max_cqe, entries); - return -EINVAL; - } - if (dpp_cq && (dev->nic_info.dev_family != OCRDMA_GEN2_FAMILY)) - return -EINVAL; - - if (dpp_cq) { - cq->max_hw_cqe = 1; - max_hw_cqe = 1; - cqe_size = OCRDMA_DPP_CQE_SIZE; - hw_pages = 1; - } else { - cq->max_hw_cqe = dev->attr.max_cqe; - max_hw_cqe = dev->attr.max_cqe; - cqe_size = sizeof(struct ocrdma_cqe); - hw_pages = OCRDMA_CREATE_CQ_MAX_PAGES; - } - - cq->len = roundup(max_hw_cqe * cqe_size, OCRDMA_MIN_Q_PAGE_SIZE); - - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_CREATE_CQ, sizeof(*cmd)); - if (!cmd) - return -ENOMEM; - ocrdma_init_mch(&cmd->cmd.req, OCRDMA_CMD_CREATE_CQ, - OCRDMA_SUBSYS_COMMON, sizeof(*cmd)); - cq->va = dma_alloc_coherent(&pdev->dev, cq->len, &cq->pa, GFP_KERNEL); - if (!cq->va) { - status = -ENOMEM; - goto mem_err; - } - memset(cq->va, 0, cq->len); - page_size = cq->len / hw_pages; - cmd->cmd.pgsz_pgcnt = (page_size / OCRDMA_MIN_Q_PAGE_SIZE) << - OCRDMA_CREATE_CQ_PAGE_SIZE_SHIFT; - cmd->cmd.pgsz_pgcnt |= hw_pages; - cmd->cmd.ev_cnt_flags = OCRDMA_CREATE_CQ_DEF_FLAGS; - - if (dev->eq_cnt < 0) - goto eq_err; - cq->eqn = ocrdma_bind_eq(dev); - cmd->cmd.req.rsvd_version = OCRDMA_CREATE_CQ_VER2; - cqe_count = cq->len / cqe_size; - if (cqe_count > 1024) - /* Set cnt to 3 to indicate more than 1024 cq entries */ - cmd->cmd.ev_cnt_flags |= (0x3 << OCRDMA_CREATE_CQ_CNT_SHIFT); - else { - u8 count = 0; - switch (cqe_count) { - case 256: - count = 0; - break; - case 512: - count = 1; - break; - case 1024: - count = 2; - break; - default: - goto mbx_err; - } - cmd->cmd.ev_cnt_flags |= (count << OCRDMA_CREATE_CQ_CNT_SHIFT); - } - /* shared eq between all the consumer cqs. */ - cmd->cmd.eqn = cq->eqn; - if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { - if (dpp_cq) - cmd->cmd.pgsz_pgcnt |= OCRDMA_CREATE_CQ_DPP << - OCRDMA_CREATE_CQ_TYPE_SHIFT; - cq->phase_change = false; - cmd->cmd.cqe_count = (cq->len / cqe_size); - } else { - cmd->cmd.cqe_count = (cq->len / cqe_size) - 1; - cmd->cmd.ev_cnt_flags |= OCRDMA_CREATE_CQ_FLAGS_AUTO_VALID; - cq->phase_change = true; - } - - ocrdma_build_q_pages(&cmd->cmd.pa[0], hw_pages, cq->pa, page_size); - status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); - if (status) - goto mbx_err; - - rsp = (struct ocrdma_create_cq_rsp *)cmd; - cq->id = (u16) (rsp->rsp.cq_id & OCRDMA_CREATE_CQ_RSP_CQ_ID_MASK); - kfree(cmd); - return 0; -mbx_err: - ocrdma_unbind_eq(dev, cq->eqn); -eq_err: - dma_free_coherent(&pdev->dev, cq->len, cq->va, cq->pa); -mem_err: - kfree(cmd); - return status; -} - -int ocrdma_mbx_destroy_cq(struct ocrdma_dev *dev, struct ocrdma_cq *cq) -{ - int status = -ENOMEM; - struct ocrdma_destroy_cq *cmd; - - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_DELETE_CQ, sizeof(*cmd)); - if (!cmd) - return status; - ocrdma_init_mch(&cmd->req, OCRDMA_CMD_DELETE_CQ, - OCRDMA_SUBSYS_COMMON, sizeof(*cmd)); - - cmd->bypass_flush_qid |= - (cq->id << OCRDMA_DESTROY_CQ_QID_SHIFT) & - OCRDMA_DESTROY_CQ_QID_MASK; - - ocrdma_unbind_eq(dev, cq->eqn); - status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); - if (status) - goto mbx_err; - dma_free_coherent(&dev->nic_info.pdev->dev, cq->len, cq->va, cq->pa); -mbx_err: - kfree(cmd); - return status; -} - -int ocrdma_mbx_alloc_lkey(struct ocrdma_dev *dev, struct ocrdma_hw_mr *hwmr, - u32 pdid, int addr_check) -{ - int status = -ENOMEM; - struct ocrdma_alloc_lkey *cmd; - struct ocrdma_alloc_lkey_rsp *rsp; - - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_ALLOC_LKEY, sizeof(*cmd)); - if (!cmd) - return status; - cmd->pdid = pdid; - cmd->pbl_sz_flags |= addr_check; - cmd->pbl_sz_flags |= (hwmr->fr_mr << OCRDMA_ALLOC_LKEY_FMR_SHIFT); - cmd->pbl_sz_flags |= - (hwmr->remote_wr << OCRDMA_ALLOC_LKEY_REMOTE_WR_SHIFT); - cmd->pbl_sz_flags |= - (hwmr->remote_rd << OCRDMA_ALLOC_LKEY_REMOTE_RD_SHIFT); - cmd->pbl_sz_flags |= - (hwmr->local_wr << OCRDMA_ALLOC_LKEY_LOCAL_WR_SHIFT); - cmd->pbl_sz_flags |= - (hwmr->remote_atomic << OCRDMA_ALLOC_LKEY_REMOTE_ATOMIC_SHIFT); - cmd->pbl_sz_flags |= - (hwmr->num_pbls << OCRDMA_ALLOC_LKEY_PBL_SIZE_SHIFT); - - status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); - if (status) - goto mbx_err; - rsp = (struct ocrdma_alloc_lkey_rsp *)cmd; - hwmr->lkey = rsp->lrkey; -mbx_err: - kfree(cmd); - return status; -} - -int ocrdma_mbx_dealloc_lkey(struct ocrdma_dev *dev, int fr_mr, u32 lkey) -{ - int status = -ENOMEM; - struct ocrdma_dealloc_lkey *cmd; - - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_DEALLOC_LKEY, sizeof(*cmd)); - if (!cmd) - return -ENOMEM; - cmd->lkey = lkey; - cmd->rsvd_frmr = fr_mr ? 1 : 0; - status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); - if (status) - goto mbx_err; -mbx_err: - kfree(cmd); - return status; -} - -static int ocrdma_mbx_reg_mr(struct ocrdma_dev *dev, struct ocrdma_hw_mr *hwmr, - u32 pdid, u32 pbl_cnt, u32 pbe_size, u32 last) -{ - int status = -ENOMEM; - int i; - struct ocrdma_reg_nsmr *cmd; - struct ocrdma_reg_nsmr_rsp *rsp; - - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_REGISTER_NSMR, sizeof(*cmd)); - if (!cmd) - return -ENOMEM; - cmd->num_pbl_pdid = - pdid | (hwmr->num_pbls << OCRDMA_REG_NSMR_NUM_PBL_SHIFT); - - cmd->flags_hpage_pbe_sz |= (hwmr->remote_wr << - OCRDMA_REG_NSMR_REMOTE_WR_SHIFT); - cmd->flags_hpage_pbe_sz |= (hwmr->remote_rd << - OCRDMA_REG_NSMR_REMOTE_RD_SHIFT); - cmd->flags_hpage_pbe_sz |= (hwmr->local_wr << - OCRDMA_REG_NSMR_LOCAL_WR_SHIFT); - cmd->flags_hpage_pbe_sz |= (hwmr->remote_atomic << - OCRDMA_REG_NSMR_REMOTE_ATOMIC_SHIFT); - cmd->flags_hpage_pbe_sz |= (hwmr->mw_bind << - OCRDMA_REG_NSMR_BIND_MEMWIN_SHIFT); - cmd->flags_hpage_pbe_sz |= (last << OCRDMA_REG_NSMR_LAST_SHIFT); - - cmd->flags_hpage_pbe_sz |= (hwmr->pbe_size / OCRDMA_MIN_HPAGE_SIZE); - cmd->flags_hpage_pbe_sz |= (hwmr->pbl_size / OCRDMA_MIN_HPAGE_SIZE) << - OCRDMA_REG_NSMR_HPAGE_SIZE_SHIFT; - cmd->totlen_low = hwmr->len; - cmd->totlen_high = upper_32_bits(hwmr->len); - cmd->fbo_low = (u32) (hwmr->fbo & 0xffffffff); - cmd->fbo_high = (u32) upper_32_bits(hwmr->fbo); - cmd->va_loaddr = (u32) hwmr->va; - cmd->va_hiaddr = (u32) upper_32_bits(hwmr->va); - - for (i = 0; i < pbl_cnt; i++) { - cmd->pbl[i].lo = (u32) (hwmr->pbl_table[i].pa & 0xffffffff); - cmd->pbl[i].hi = upper_32_bits(hwmr->pbl_table[i].pa); - } - status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); - if (status) - goto mbx_err; - rsp = (struct ocrdma_reg_nsmr_rsp *)cmd; - hwmr->lkey = rsp->lrkey; -mbx_err: - kfree(cmd); - return status; -} - -static int ocrdma_mbx_reg_mr_cont(struct ocrdma_dev *dev, - struct ocrdma_hw_mr *hwmr, u32 pbl_cnt, - u32 pbl_offset, u32 last) -{ - int status = -ENOMEM; - int i; - struct ocrdma_reg_nsmr_cont *cmd; - - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_REGISTER_NSMR_CONT, sizeof(*cmd)); - if (!cmd) - return -ENOMEM; - cmd->lrkey = hwmr->lkey; - cmd->num_pbl_offset = (pbl_cnt << OCRDMA_REG_NSMR_CONT_NUM_PBL_SHIFT) | - (pbl_offset & OCRDMA_REG_NSMR_CONT_PBL_SHIFT_MASK); - cmd->last = last << OCRDMA_REG_NSMR_CONT_LAST_SHIFT; - - for (i = 0; i < pbl_cnt; i++) { - cmd->pbl[i].lo = - (u32) (hwmr->pbl_table[i + pbl_offset].pa & 0xffffffff); - cmd->pbl[i].hi = - upper_32_bits(hwmr->pbl_table[i + pbl_offset].pa); - } - status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); - if (status) - goto mbx_err; -mbx_err: - kfree(cmd); - return status; -} - -int ocrdma_reg_mr(struct ocrdma_dev *dev, - struct ocrdma_hw_mr *hwmr, u32 pdid, int acc) -{ - int status; - u32 last = 0; - u32 cur_pbl_cnt, pbl_offset; - u32 pending_pbl_cnt = hwmr->num_pbls; - - pbl_offset = 0; - cur_pbl_cnt = min(pending_pbl_cnt, MAX_OCRDMA_NSMR_PBL); - if (cur_pbl_cnt == pending_pbl_cnt) - last = 1; - - status = ocrdma_mbx_reg_mr(dev, hwmr, pdid, - cur_pbl_cnt, hwmr->pbe_size, last); - if (status) { - ocrdma_err("%s() status=%d\n", __func__, status); - return status; - } - /* if there is no more pbls to register then exit. */ - if (last) - return 0; - - while (!last) { - pbl_offset += cur_pbl_cnt; - pending_pbl_cnt -= cur_pbl_cnt; - cur_pbl_cnt = min(pending_pbl_cnt, MAX_OCRDMA_NSMR_PBL); - /* if we reach the end of the pbls, then need to set the last - * bit, indicating no more pbls to register for this memory key. - */ - if (cur_pbl_cnt == pending_pbl_cnt) - last = 1; - - status = ocrdma_mbx_reg_mr_cont(dev, hwmr, cur_pbl_cnt, - pbl_offset, last); - if (status) - break; - } - if (status) - ocrdma_err("%s() err. status=%d\n", __func__, status); - - return status; -} - -bool ocrdma_is_qp_in_sq_flushlist(struct ocrdma_cq *cq, struct ocrdma_qp *qp) -{ - struct ocrdma_qp *tmp; - bool found = false; - list_for_each_entry(tmp, &cq->sq_head, sq_entry) { - if (qp == tmp) { - found = true; - break; - } - } - return found; -} - -bool ocrdma_is_qp_in_rq_flushlist(struct ocrdma_cq *cq, struct ocrdma_qp *qp) -{ - struct ocrdma_qp *tmp; - bool found = false; - list_for_each_entry(tmp, &cq->rq_head, rq_entry) { - if (qp == tmp) { - found = true; - break; - } - } - return found; -} - -void ocrdma_flush_qp(struct ocrdma_qp *qp) -{ - bool found; - unsigned long flags; - - spin_lock_irqsave(&qp->dev->flush_q_lock, flags); - found = ocrdma_is_qp_in_sq_flushlist(qp->sq_cq, qp); - if (!found) - list_add_tail(&qp->sq_entry, &qp->sq_cq->sq_head); - if (!qp->srq) { - found = ocrdma_is_qp_in_rq_flushlist(qp->rq_cq, qp); - if (!found) - list_add_tail(&qp->rq_entry, &qp->rq_cq->rq_head); - } - spin_unlock_irqrestore(&qp->dev->flush_q_lock, flags); -} - -int ocrdma_qp_state_machine(struct ocrdma_qp *qp, enum ib_qp_state new_ib_state, - enum ib_qp_state *old_ib_state) -{ - unsigned long flags; - int status = 0; - enum ocrdma_qp_state new_state; - new_state = get_ocrdma_qp_state(new_ib_state); - - /* sync with wqe and rqe posting */ - spin_lock_irqsave(&qp->q_lock, flags); - - if (old_ib_state) - *old_ib_state = get_ibqp_state(qp->state); - if (new_state == qp->state) { - spin_unlock_irqrestore(&qp->q_lock, flags); - return 1; - } - - switch (qp->state) { - case OCRDMA_QPS_RST: - switch (new_state) { - case OCRDMA_QPS_RST: - case OCRDMA_QPS_INIT: - break; - default: - status = -EINVAL; - break; - }; - break; - case OCRDMA_QPS_INIT: - /* qps: INIT->XXX */ - switch (new_state) { - case OCRDMA_QPS_INIT: - case OCRDMA_QPS_RTR: - break; - case OCRDMA_QPS_ERR: - ocrdma_flush_qp(qp); - break; - default: - status = -EINVAL; - break; - }; - break; - case OCRDMA_QPS_RTR: - /* qps: RTS->XXX */ - switch (new_state) { - case OCRDMA_QPS_RTS: - break; - case OCRDMA_QPS_ERR: - ocrdma_flush_qp(qp); - break; - default: - status = -EINVAL; - break; - }; - break; - case OCRDMA_QPS_RTS: - /* qps: RTS->XXX */ - switch (new_state) { - case OCRDMA_QPS_SQD: - case OCRDMA_QPS_SQE: - break; - case OCRDMA_QPS_ERR: - ocrdma_flush_qp(qp); - break; - default: - status = -EINVAL; - break; - }; - break; - case OCRDMA_QPS_SQD: - /* qps: SQD->XXX */ - switch (new_state) { - case OCRDMA_QPS_RTS: - case OCRDMA_QPS_SQE: - case OCRDMA_QPS_ERR: - break; - default: - status = -EINVAL; - break; - }; - break; - case OCRDMA_QPS_SQE: - switch (new_state) { - case OCRDMA_QPS_RTS: - case OCRDMA_QPS_ERR: - break; - default: - status = -EINVAL; - break; - }; - break; - case OCRDMA_QPS_ERR: - /* qps: ERR->XXX */ - switch (new_state) { - case OCRDMA_QPS_RST: - break; - default: - status = -EINVAL; - break; - }; - break; - default: - status = -EINVAL; - break; - }; - if (!status) - qp->state = new_state; - - spin_unlock_irqrestore(&qp->q_lock, flags); - return status; -} - -static u32 ocrdma_set_create_qp_mbx_access_flags(struct ocrdma_qp *qp) -{ - u32 flags = 0; - if (qp->cap_flags & OCRDMA_QP_INB_RD) - flags |= OCRDMA_CREATE_QP_REQ_INB_RDEN_MASK; - if (qp->cap_flags & OCRDMA_QP_INB_WR) - flags |= OCRDMA_CREATE_QP_REQ_INB_WREN_MASK; - if (qp->cap_flags & OCRDMA_QP_MW_BIND) - flags |= OCRDMA_CREATE_QP_REQ_BIND_MEMWIN_MASK; - if (qp->cap_flags & OCRDMA_QP_LKEY0) - flags |= OCRDMA_CREATE_QP_REQ_ZERO_LKEYEN_MASK; - if (qp->cap_flags & OCRDMA_QP_FAST_REG) - flags |= OCRDMA_CREATE_QP_REQ_FMR_EN_MASK; - return flags; -} - -static int ocrdma_set_create_qp_sq_cmd(struct ocrdma_create_qp_req *cmd, - struct ib_qp_init_attr *attrs, - struct ocrdma_qp *qp) -{ - int status; - u32 len, hw_pages, hw_page_size; - dma_addr_t pa; - struct ocrdma_dev *dev = qp->dev; - struct pci_dev *pdev = dev->nic_info.pdev; - u32 max_wqe_allocated; - u32 max_sges = attrs->cap.max_send_sge; - - max_wqe_allocated = attrs->cap.max_send_wr; - /* need to allocate one extra to for GEN1 family */ - if (dev->nic_info.dev_family != OCRDMA_GEN2_FAMILY) - max_wqe_allocated += 1; - - status = ocrdma_build_q_conf(&max_wqe_allocated, - dev->attr.wqe_size, &hw_pages, &hw_page_size); - if (status) { - ocrdma_err("%s() req. max_send_wr=0x%x\n", __func__, - max_wqe_allocated); - return -EINVAL; - } - qp->sq.max_cnt = max_wqe_allocated; - len = (hw_pages * hw_page_size); - - qp->sq.va = dma_alloc_coherent(&pdev->dev, len, &pa, GFP_KERNEL); - if (!qp->sq.va) - return -EINVAL; - memset(qp->sq.va, 0, len); - qp->sq.len = len; - qp->sq.pa = pa; - qp->sq.entry_size = dev->attr.wqe_size; - ocrdma_build_q_pages(&cmd->wq_addr[0], hw_pages, pa, hw_page_size); - - cmd->type_pgsz_pdn |= (ilog2(hw_page_size / OCRDMA_MIN_Q_PAGE_SIZE) - << OCRDMA_CREATE_QP_REQ_SQ_PAGE_SIZE_SHIFT); - cmd->num_wq_rq_pages |= (hw_pages << - OCRDMA_CREATE_QP_REQ_NUM_WQ_PAGES_SHIFT) & - OCRDMA_CREATE_QP_REQ_NUM_WQ_PAGES_MASK; - cmd->max_sge_send_write |= (max_sges << - OCRDMA_CREATE_QP_REQ_MAX_SGE_SEND_SHIFT) & - OCRDMA_CREATE_QP_REQ_MAX_SGE_SEND_MASK; - cmd->max_sge_send_write |= (max_sges << - OCRDMA_CREATE_QP_REQ_MAX_SGE_WRITE_SHIFT) & - OCRDMA_CREATE_QP_REQ_MAX_SGE_WRITE_MASK; - cmd->max_wqe_rqe |= (ilog2(qp->sq.max_cnt) << - OCRDMA_CREATE_QP_REQ_MAX_WQE_SHIFT) & - OCRDMA_CREATE_QP_REQ_MAX_WQE_MASK; - cmd->wqe_rqe_size |= (dev->attr.wqe_size << - OCRDMA_CREATE_QP_REQ_WQE_SIZE_SHIFT) & - OCRDMA_CREATE_QP_REQ_WQE_SIZE_MASK; - return 0; -} - -static int ocrdma_set_create_qp_rq_cmd(struct ocrdma_create_qp_req *cmd, - struct ib_qp_init_attr *attrs, - struct ocrdma_qp *qp) -{ - int status; - u32 len, hw_pages, hw_page_size; - dma_addr_t pa = 0; - struct ocrdma_dev *dev = qp->dev; - struct pci_dev *pdev = dev->nic_info.pdev; - u32 max_rqe_allocated = attrs->cap.max_recv_wr + 1; - - status = ocrdma_build_q_conf(&max_rqe_allocated, dev->attr.rqe_size, - &hw_pages, &hw_page_size); - if (status) { - ocrdma_err("%s() req. max_recv_wr=0x%x\n", __func__, - attrs->cap.max_recv_wr + 1); - return status; - } - qp->rq.max_cnt = max_rqe_allocated; - len = (hw_pages * hw_page_size); - - qp->rq.va = dma_alloc_coherent(&pdev->dev, len, &pa, GFP_KERNEL); - if (!qp->rq.va) - return status; - memset(qp->rq.va, 0, len); - qp->rq.pa = pa; - qp->rq.len = len; - qp->rq.entry_size = dev->attr.rqe_size; - - ocrdma_build_q_pages(&cmd->rq_addr[0], hw_pages, pa, hw_page_size); - cmd->type_pgsz_pdn |= (ilog2(hw_page_size / OCRDMA_MIN_Q_PAGE_SIZE) << - OCRDMA_CREATE_QP_REQ_RQ_PAGE_SIZE_SHIFT); - cmd->num_wq_rq_pages |= - (hw_pages << OCRDMA_CREATE_QP_REQ_NUM_RQ_PAGES_SHIFT) & - OCRDMA_CREATE_QP_REQ_NUM_RQ_PAGES_MASK; - cmd->max_sge_recv_flags |= (attrs->cap.max_recv_sge << - OCRDMA_CREATE_QP_REQ_MAX_SGE_RECV_SHIFT) & - OCRDMA_CREATE_QP_REQ_MAX_SGE_RECV_MASK; - cmd->max_wqe_rqe |= (ilog2(qp->rq.max_cnt) << - OCRDMA_CREATE_QP_REQ_MAX_RQE_SHIFT) & - OCRDMA_CREATE_QP_REQ_MAX_RQE_MASK; - cmd->wqe_rqe_size |= (dev->attr.rqe_size << - OCRDMA_CREATE_QP_REQ_RQE_SIZE_SHIFT) & - OCRDMA_CREATE_QP_REQ_RQE_SIZE_MASK; - return 0; -} - -static void ocrdma_set_create_qp_dpp_cmd(struct ocrdma_create_qp_req *cmd, - struct ocrdma_pd *pd, - struct ocrdma_qp *qp, - u8 enable_dpp_cq, u16 dpp_cq_id) -{ - pd->num_dpp_qp--; - qp->dpp_enabled = true; - cmd->max_sge_recv_flags |= OCRDMA_CREATE_QP_REQ_ENABLE_DPP_MASK; - if (!enable_dpp_cq) - return; - cmd->max_sge_recv_flags |= OCRDMA_CREATE_QP_REQ_ENABLE_DPP_MASK; - cmd->dpp_credits_cqid = dpp_cq_id; - cmd->dpp_credits_cqid |= OCRDMA_CREATE_QP_REQ_DPP_CREDIT_LIMIT << - OCRDMA_CREATE_QP_REQ_DPP_CREDIT_SHIFT; -} - -static int ocrdma_set_create_qp_ird_cmd(struct ocrdma_create_qp_req *cmd, - struct ocrdma_qp *qp) -{ - struct ocrdma_dev *dev = qp->dev; - struct pci_dev *pdev = dev->nic_info.pdev; - dma_addr_t pa = 0; - int ird_page_size = dev->attr.ird_page_size; - int ird_q_len = dev->attr.num_ird_pages * ird_page_size; - - if (dev->attr.ird == 0) - return 0; - - qp->ird_q_va = dma_alloc_coherent(&pdev->dev, ird_q_len, - &pa, GFP_KERNEL); - if (!qp->ird_q_va) - return -ENOMEM; - memset(qp->ird_q_va, 0, ird_q_len); - ocrdma_build_q_pages(&cmd->ird_addr[0], dev->attr.num_ird_pages, - pa, ird_page_size); - return 0; -} - -static void ocrdma_get_create_qp_rsp(struct ocrdma_create_qp_rsp *rsp, - struct ocrdma_qp *qp, - struct ib_qp_init_attr *attrs, - u16 *dpp_offset, u16 *dpp_credit_lmt) -{ - u32 max_wqe_allocated, max_rqe_allocated; - qp->id = rsp->qp_id & OCRDMA_CREATE_QP_RSP_QP_ID_MASK; - qp->rq.dbid = rsp->sq_rq_id & OCRDMA_CREATE_QP_RSP_RQ_ID_MASK; - qp->sq.dbid = rsp->sq_rq_id >> OCRDMA_CREATE_QP_RSP_SQ_ID_SHIFT; - qp->max_ird = rsp->max_ord_ird & OCRDMA_CREATE_QP_RSP_MAX_IRD_MASK; - qp->max_ord = (rsp->max_ord_ird >> OCRDMA_CREATE_QP_RSP_MAX_ORD_SHIFT); - qp->dpp_enabled = false; - if (rsp->dpp_response & OCRDMA_CREATE_QP_RSP_DPP_ENABLED_MASK) { - qp->dpp_enabled = true; - *dpp_credit_lmt = (rsp->dpp_response & - OCRDMA_CREATE_QP_RSP_DPP_CREDITS_MASK) >> - OCRDMA_CREATE_QP_RSP_DPP_CREDITS_SHIFT; - *dpp_offset = (rsp->dpp_response & - OCRDMA_CREATE_QP_RSP_DPP_PAGE_OFFSET_MASK) >> - OCRDMA_CREATE_QP_RSP_DPP_PAGE_OFFSET_SHIFT; - } - max_wqe_allocated = - rsp->max_wqe_rqe >> OCRDMA_CREATE_QP_RSP_MAX_WQE_SHIFT; - max_wqe_allocated = 1 << max_wqe_allocated; - max_rqe_allocated = 1 << ((u16)rsp->max_wqe_rqe); - - if (qp->dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { - qp->sq.free_delta = 0; - qp->rq.free_delta = 1; - } else - qp->sq.free_delta = 1; - - qp->sq.max_cnt = max_wqe_allocated; - qp->sq.max_wqe_idx = max_wqe_allocated - 1; - - if (!attrs->srq) { - qp->rq.max_cnt = max_rqe_allocated; - qp->rq.max_wqe_idx = max_rqe_allocated - 1; - qp->rq.free_delta = 1; - } -} - -int ocrdma_mbx_create_qp(struct ocrdma_qp *qp, struct ib_qp_init_attr *attrs, - u8 enable_dpp_cq, u16 dpp_cq_id, u16 *dpp_offset, - u16 *dpp_credit_lmt) -{ - int status = -ENOMEM; - u32 flags = 0; - struct ocrdma_dev *dev = qp->dev; - struct ocrdma_pd *pd = qp->pd; - struct pci_dev *pdev = dev->nic_info.pdev; - struct ocrdma_cq *cq; - struct ocrdma_create_qp_req *cmd; - struct ocrdma_create_qp_rsp *rsp; - int qptype; - - switch (attrs->qp_type) { - case IB_QPT_GSI: - qptype = OCRDMA_QPT_GSI; - break; - case IB_QPT_RC: - qptype = OCRDMA_QPT_RC; - break; - case IB_QPT_UD: - qptype = OCRDMA_QPT_UD; - break; - default: - return -EINVAL; - }; - - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_CREATE_QP, sizeof(*cmd)); - if (!cmd) - return status; - cmd->type_pgsz_pdn |= (qptype << OCRDMA_CREATE_QP_REQ_QPT_SHIFT) & - OCRDMA_CREATE_QP_REQ_QPT_MASK; - status = ocrdma_set_create_qp_sq_cmd(cmd, attrs, qp); - if (status) - goto sq_err; - - if (attrs->srq) { - struct ocrdma_srq *srq = get_ocrdma_srq(attrs->srq); - cmd->max_sge_recv_flags |= OCRDMA_CREATE_QP_REQ_USE_SRQ_MASK; - cmd->rq_addr[0].lo = srq->id; - qp->srq = srq; - } else { - status = ocrdma_set_create_qp_rq_cmd(cmd, attrs, qp); - if (status) - goto rq_err; - } - - status = ocrdma_set_create_qp_ird_cmd(cmd, qp); - if (status) - goto mbx_err; - - cmd->type_pgsz_pdn |= (pd->id << OCRDMA_CREATE_QP_REQ_PD_ID_SHIFT) & - OCRDMA_CREATE_QP_REQ_PD_ID_MASK; - - flags = ocrdma_set_create_qp_mbx_access_flags(qp); - - cmd->max_sge_recv_flags |= flags; - cmd->max_ord_ird |= (dev->attr.max_ord_per_qp << - OCRDMA_CREATE_QP_REQ_MAX_ORD_SHIFT) & - OCRDMA_CREATE_QP_REQ_MAX_ORD_MASK; - cmd->max_ord_ird |= (dev->attr.max_ird_per_qp << - OCRDMA_CREATE_QP_REQ_MAX_IRD_SHIFT) & - OCRDMA_CREATE_QP_REQ_MAX_IRD_MASK; - cq = get_ocrdma_cq(attrs->send_cq); - cmd->wq_rq_cqid |= (cq->id << OCRDMA_CREATE_QP_REQ_WQ_CQID_SHIFT) & - OCRDMA_CREATE_QP_REQ_WQ_CQID_MASK; - qp->sq_cq = cq; - cq = get_ocrdma_cq(attrs->recv_cq); - cmd->wq_rq_cqid |= (cq->id << OCRDMA_CREATE_QP_REQ_RQ_CQID_SHIFT) & - OCRDMA_CREATE_QP_REQ_RQ_CQID_MASK; - qp->rq_cq = cq; - - if (pd->dpp_enabled && attrs->cap.max_inline_data && pd->num_dpp_qp && - (attrs->cap.max_inline_data <= dev->attr.max_inline_data)) - ocrdma_set_create_qp_dpp_cmd(cmd, pd, qp, enable_dpp_cq, - dpp_cq_id); - - status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); - if (status) - goto mbx_err; - rsp = (struct ocrdma_create_qp_rsp *)cmd; - ocrdma_get_create_qp_rsp(rsp, qp, attrs, dpp_offset, dpp_credit_lmt); - qp->state = OCRDMA_QPS_RST; - kfree(cmd); - return 0; -mbx_err: - if (qp->rq.va) - dma_free_coherent(&pdev->dev, qp->rq.len, qp->rq.va, qp->rq.pa); -rq_err: - ocrdma_err("%s(%d) rq_err\n", __func__, dev->id); - dma_free_coherent(&pdev->dev, qp->sq.len, qp->sq.va, qp->sq.pa); -sq_err: - ocrdma_err("%s(%d) sq_err\n", __func__, dev->id); - kfree(cmd); - return status; -} - -int ocrdma_mbx_query_qp(struct ocrdma_dev *dev, struct ocrdma_qp *qp, - struct ocrdma_qp_params *param) -{ - int status = -ENOMEM; - struct ocrdma_query_qp *cmd; - struct ocrdma_query_qp_rsp *rsp; - - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_QUERY_QP, sizeof(*cmd)); - if (!cmd) - return status; - cmd->qp_id = qp->id; - status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); - if (status) - goto mbx_err; - rsp = (struct ocrdma_query_qp_rsp *)cmd; - memcpy(param, &rsp->params, sizeof(struct ocrdma_qp_params)); -mbx_err: - kfree(cmd); - return status; -} - -int ocrdma_resolve_dgid(struct ocrdma_dev *dev, union ib_gid *dgid, - u8 *mac_addr) -{ - struct in6_addr in6; - - memcpy(&in6, dgid, sizeof in6); - if (rdma_is_multicast_addr(&in6)) - rdma_get_mcast_mac(&in6, mac_addr); - else if (rdma_link_local_addr(&in6)) - rdma_get_ll_mac(&in6, mac_addr); - else { - ocrdma_err("%s() fail to resolve mac_addr.\n", __func__); - return -EINVAL; - } - return 0; -} - -static void ocrdma_set_av_params(struct ocrdma_qp *qp, - struct ocrdma_modify_qp *cmd, - struct ib_qp_attr *attrs) -{ - struct ib_ah_attr *ah_attr = &attrs->ah_attr; - union ib_gid sgid; - u32 vlan_id; - u8 mac_addr[6]; - if ((ah_attr->ah_flags & IB_AH_GRH) == 0) - return; - cmd->params.tclass_sq_psn |= - (ah_attr->grh.traffic_class << OCRDMA_QP_PARAMS_TCLASS_SHIFT); - cmd->params.rnt_rc_sl_fl |= - (ah_attr->grh.flow_label & OCRDMA_QP_PARAMS_FLOW_LABEL_MASK); - cmd->params.hop_lmt_rq_psn |= - (ah_attr->grh.hop_limit << OCRDMA_QP_PARAMS_HOP_LMT_SHIFT); - cmd->flags |= OCRDMA_QP_PARA_FLOW_LBL_VALID; - memcpy(&cmd->params.dgid[0], &ah_attr->grh.dgid.raw[0], - sizeof(cmd->params.dgid)); - ocrdma_query_gid(&qp->dev->ibdev, 1, - ah_attr->grh.sgid_index, &sgid); - qp->sgid_idx = ah_attr->grh.sgid_index; - memcpy(&cmd->params.sgid[0], &sgid.raw[0], sizeof(cmd->params.sgid)); - ocrdma_resolve_dgid(qp->dev, &ah_attr->grh.dgid, &mac_addr[0]); - cmd->params.dmac_b0_to_b3 = mac_addr[0] | (mac_addr[1] << 8) | - (mac_addr[2] << 16) | (mac_addr[3] << 24); - /* convert them to LE format. */ - ocrdma_cpu_to_le32(&cmd->params.dgid[0], sizeof(cmd->params.dgid)); - ocrdma_cpu_to_le32(&cmd->params.sgid[0], sizeof(cmd->params.sgid)); - cmd->params.vlan_dmac_b4_to_b5 = mac_addr[4] | (mac_addr[5] << 8); - vlan_id = rdma_get_vlan_id(&sgid); - if (vlan_id && (vlan_id < 0x1000)) { - cmd->params.vlan_dmac_b4_to_b5 |= - vlan_id << OCRDMA_QP_PARAMS_VLAN_SHIFT; - cmd->flags |= OCRDMA_QP_PARA_VLAN_EN_VALID; - } -} - -static int ocrdma_set_qp_params(struct ocrdma_qp *qp, - struct ocrdma_modify_qp *cmd, - struct ib_qp_attr *attrs, int attr_mask, - enum ib_qp_state old_qps) -{ - int status = 0; - struct net_device *netdev = qp->dev->nic_info.netdev; - int eth_mtu = iboe_get_mtu(netdev->mtu); - - if (attr_mask & IB_QP_PKEY_INDEX) { - cmd->params.path_mtu_pkey_indx |= (attrs->pkey_index & - OCRDMA_QP_PARAMS_PKEY_INDEX_MASK); - cmd->flags |= OCRDMA_QP_PARA_PKEY_VALID; - } - if (attr_mask & IB_QP_QKEY) { - qp->qkey = attrs->qkey; - cmd->params.qkey = attrs->qkey; - cmd->flags |= OCRDMA_QP_PARA_QKEY_VALID; - } - if (attr_mask & IB_QP_AV) - ocrdma_set_av_params(qp, cmd, attrs); - else if (qp->qp_type == IB_QPT_GSI || qp->qp_type == IB_QPT_UD) { - /* set the default mac address for UD, GSI QPs */ - cmd->params.dmac_b0_to_b3 = qp->dev->nic_info.mac_addr[0] | - (qp->dev->nic_info.mac_addr[1] << 8) | - (qp->dev->nic_info.mac_addr[2] << 16) | - (qp->dev->nic_info.mac_addr[3] << 24); - cmd->params.vlan_dmac_b4_to_b5 = qp->dev->nic_info.mac_addr[4] | - (qp->dev->nic_info.mac_addr[5] << 8); - } - if ((attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY) && - attrs->en_sqd_async_notify) { - cmd->params.max_sge_recv_flags |= - OCRDMA_QP_PARAMS_FLAGS_SQD_ASYNC; - cmd->flags |= OCRDMA_QP_PARA_DST_QPN_VALID; - } - if (attr_mask & IB_QP_DEST_QPN) { - cmd->params.ack_to_rnr_rtc_dest_qpn |= (attrs->dest_qp_num & - OCRDMA_QP_PARAMS_DEST_QPN_MASK); - cmd->flags |= OCRDMA_QP_PARA_DST_QPN_VALID; - } - if (attr_mask & IB_QP_PATH_MTU) { - if (ib_mtu_enum_to_int(eth_mtu) < - ib_mtu_enum_to_int(attrs->path_mtu)) { - status = -EINVAL; - goto pmtu_err; - } - cmd->params.path_mtu_pkey_indx |= - (ib_mtu_enum_to_int(attrs->path_mtu) << - OCRDMA_QP_PARAMS_PATH_MTU_SHIFT) & - OCRDMA_QP_PARAMS_PATH_MTU_MASK; - cmd->flags |= OCRDMA_QP_PARA_PMTU_VALID; - } - if (attr_mask & IB_QP_TIMEOUT) { - cmd->params.ack_to_rnr_rtc_dest_qpn |= attrs->timeout << - OCRDMA_QP_PARAMS_ACK_TIMEOUT_SHIFT; - cmd->flags |= OCRDMA_QP_PARA_ACK_TO_VALID; - } - if (attr_mask & IB_QP_RETRY_CNT) { - cmd->params.rnt_rc_sl_fl |= (attrs->retry_cnt << - OCRDMA_QP_PARAMS_RETRY_CNT_SHIFT) & - OCRDMA_QP_PARAMS_RETRY_CNT_MASK; - cmd->flags |= OCRDMA_QP_PARA_RETRY_CNT_VALID; - } - if (attr_mask & IB_QP_MIN_RNR_TIMER) { - cmd->params.rnt_rc_sl_fl |= (attrs->min_rnr_timer << - OCRDMA_QP_PARAMS_RNR_NAK_TIMER_SHIFT) & - OCRDMA_QP_PARAMS_RNR_NAK_TIMER_MASK; - cmd->flags |= OCRDMA_QP_PARA_RNT_VALID; - } - if (attr_mask & IB_QP_RNR_RETRY) { - cmd->params.ack_to_rnr_rtc_dest_qpn |= (attrs->rnr_retry << - OCRDMA_QP_PARAMS_RNR_RETRY_CNT_SHIFT) - & OCRDMA_QP_PARAMS_RNR_RETRY_CNT_MASK; - cmd->flags |= OCRDMA_QP_PARA_RRC_VALID; - } - if (attr_mask & IB_QP_SQ_PSN) { - cmd->params.tclass_sq_psn |= (attrs->sq_psn & 0x00ffffff); - cmd->flags |= OCRDMA_QP_PARA_SQPSN_VALID; - } - if (attr_mask & IB_QP_RQ_PSN) { - cmd->params.hop_lmt_rq_psn |= (attrs->rq_psn & 0x00ffffff); - cmd->flags |= OCRDMA_QP_PARA_RQPSN_VALID; - } - if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) { - if (attrs->max_rd_atomic > qp->dev->attr.max_ord_per_qp) { - status = -EINVAL; - goto pmtu_err; - } - qp->max_ord = attrs->max_rd_atomic; - cmd->flags |= OCRDMA_QP_PARA_MAX_ORD_VALID; - } - if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) { - if (attrs->max_dest_rd_atomic > qp->dev->attr.max_ird_per_qp) { - status = -EINVAL; - goto pmtu_err; - } - qp->max_ird = attrs->max_dest_rd_atomic; - cmd->flags |= OCRDMA_QP_PARA_MAX_IRD_VALID; - } - cmd->params.max_ord_ird = (qp->max_ord << - OCRDMA_QP_PARAMS_MAX_ORD_SHIFT) | - (qp->max_ird & OCRDMA_QP_PARAMS_MAX_IRD_MASK); -pmtu_err: - return status; -} - -int ocrdma_mbx_modify_qp(struct ocrdma_dev *dev, struct ocrdma_qp *qp, - struct ib_qp_attr *attrs, int attr_mask, - enum ib_qp_state old_qps) -{ - int status = -ENOMEM; - struct ocrdma_modify_qp *cmd; - - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_MODIFY_QP, sizeof(*cmd)); - if (!cmd) - return status; - - cmd->params.id = qp->id; - cmd->flags = 0; - if (attr_mask & IB_QP_STATE) { - cmd->params.max_sge_recv_flags |= - (get_ocrdma_qp_state(attrs->qp_state) << - OCRDMA_QP_PARAMS_STATE_SHIFT) & - OCRDMA_QP_PARAMS_STATE_MASK; - cmd->flags |= OCRDMA_QP_PARA_QPS_VALID; - } else - cmd->params.max_sge_recv_flags |= - (qp->state << OCRDMA_QP_PARAMS_STATE_SHIFT) & - OCRDMA_QP_PARAMS_STATE_MASK; - status = ocrdma_set_qp_params(qp, cmd, attrs, attr_mask, old_qps); - if (status) - goto mbx_err; - status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); - if (status) - goto mbx_err; - -mbx_err: - kfree(cmd); - return status; -} - -int ocrdma_mbx_destroy_qp(struct ocrdma_dev *dev, struct ocrdma_qp *qp) -{ - int status = -ENOMEM; - struct ocrdma_destroy_qp *cmd; - struct pci_dev *pdev = dev->nic_info.pdev; - - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_DELETE_QP, sizeof(*cmd)); - if (!cmd) - return status; - cmd->qp_id = qp->id; - status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); - if (status) - goto mbx_err; - -mbx_err: - kfree(cmd); - if (qp->sq.va) - dma_free_coherent(&pdev->dev, qp->sq.len, qp->sq.va, qp->sq.pa); - if (!qp->srq && qp->rq.va) - dma_free_coherent(&pdev->dev, qp->rq.len, qp->rq.va, qp->rq.pa); - if (qp->dpp_enabled) - qp->pd->num_dpp_qp++; - return status; -} - -int ocrdma_mbx_create_srq(struct ocrdma_srq *srq, - struct ib_srq_init_attr *srq_attr, - struct ocrdma_pd *pd) -{ - int status = -ENOMEM; - int hw_pages, hw_page_size; - int len; - struct ocrdma_create_srq_rsp *rsp; - struct ocrdma_create_srq *cmd; - dma_addr_t pa; - struct ocrdma_dev *dev = srq->dev; - struct pci_dev *pdev = dev->nic_info.pdev; - u32 max_rqe_allocated; - - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_CREATE_SRQ, sizeof(*cmd)); - if (!cmd) - return status; - - cmd->pgsz_pdid = pd->id & OCRDMA_CREATE_SRQ_PD_ID_MASK; - max_rqe_allocated = srq_attr->attr.max_wr + 1; - status = ocrdma_build_q_conf(&max_rqe_allocated, - dev->attr.rqe_size, - &hw_pages, &hw_page_size); - if (status) { - ocrdma_err("%s() req. max_wr=0x%x\n", __func__, - srq_attr->attr.max_wr); - status = -EINVAL; - goto ret; - } - len = hw_pages * hw_page_size; - srq->rq.va = dma_alloc_coherent(&pdev->dev, len, &pa, GFP_KERNEL); - if (!srq->rq.va) { - status = -ENOMEM; - goto ret; - } - ocrdma_build_q_pages(&cmd->rq_addr[0], hw_pages, pa, hw_page_size); - - srq->rq.entry_size = dev->attr.rqe_size; - srq->rq.pa = pa; - srq->rq.len = len; - srq->rq.max_cnt = max_rqe_allocated; - - cmd->max_sge_rqe = ilog2(max_rqe_allocated); - cmd->max_sge_rqe |= srq_attr->attr.max_sge << - OCRDMA_CREATE_SRQ_MAX_SGE_RECV_SHIFT; - - cmd->pgsz_pdid |= (ilog2(hw_page_size / OCRDMA_MIN_Q_PAGE_SIZE) - << OCRDMA_CREATE_SRQ_PG_SZ_SHIFT); - cmd->pages_rqe_sz |= (dev->attr.rqe_size - << OCRDMA_CREATE_SRQ_RQE_SIZE_SHIFT) - & OCRDMA_CREATE_SRQ_RQE_SIZE_MASK; - cmd->pages_rqe_sz |= hw_pages << OCRDMA_CREATE_SRQ_NUM_RQ_PAGES_SHIFT; - - status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); - if (status) - goto mbx_err; - rsp = (struct ocrdma_create_srq_rsp *)cmd; - srq->id = rsp->id; - srq->rq.dbid = rsp->id; - max_rqe_allocated = ((rsp->max_sge_rqe_allocated & - OCRDMA_CREATE_SRQ_RSP_MAX_RQE_ALLOCATED_MASK) >> - OCRDMA_CREATE_SRQ_RSP_MAX_RQE_ALLOCATED_SHIFT); - max_rqe_allocated = (1 << max_rqe_allocated); - srq->rq.max_cnt = max_rqe_allocated; - srq->rq.max_wqe_idx = max_rqe_allocated - 1; - srq->rq.max_sges = (rsp->max_sge_rqe_allocated & - OCRDMA_CREATE_SRQ_RSP_MAX_SGE_RECV_ALLOCATED_MASK) >> - OCRDMA_CREATE_SRQ_RSP_MAX_SGE_RECV_ALLOCATED_SHIFT; - goto ret; -mbx_err: - dma_free_coherent(&pdev->dev, srq->rq.len, srq->rq.va, pa); -ret: - kfree(cmd); - return status; -} - -int ocrdma_mbx_modify_srq(struct ocrdma_srq *srq, struct ib_srq_attr *srq_attr) -{ - int status = -ENOMEM; - struct ocrdma_modify_srq *cmd; - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_CREATE_SRQ, sizeof(*cmd)); - if (!cmd) - return status; - cmd->id = srq->id; - cmd->limit_max_rqe |= srq_attr->srq_limit << - OCRDMA_MODIFY_SRQ_LIMIT_SHIFT; - status = ocrdma_mbx_cmd(srq->dev, (struct ocrdma_mqe *)cmd); - kfree(cmd); - return status; -} - -int ocrdma_mbx_query_srq(struct ocrdma_srq *srq, struct ib_srq_attr *srq_attr) -{ - int status = -ENOMEM; - struct ocrdma_query_srq *cmd; - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_CREATE_SRQ, sizeof(*cmd)); - if (!cmd) - return status; - cmd->id = srq->rq.dbid; - status = ocrdma_mbx_cmd(srq->dev, (struct ocrdma_mqe *)cmd); - if (status == 0) { - struct ocrdma_query_srq_rsp *rsp = - (struct ocrdma_query_srq_rsp *)cmd; - srq_attr->max_sge = - rsp->srq_lmt_max_sge & - OCRDMA_QUERY_SRQ_RSP_MAX_SGE_RECV_MASK; - srq_attr->max_wr = - rsp->max_rqe_pdid >> OCRDMA_QUERY_SRQ_RSP_MAX_RQE_SHIFT; - srq_attr->srq_limit = rsp->srq_lmt_max_sge >> - OCRDMA_QUERY_SRQ_RSP_SRQ_LIMIT_SHIFT; - } - kfree(cmd); - return status; -} - -int ocrdma_mbx_destroy_srq(struct ocrdma_dev *dev, struct ocrdma_srq *srq) -{ - int status = -ENOMEM; - struct ocrdma_destroy_srq *cmd; - struct pci_dev *pdev = dev->nic_info.pdev; - cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_DELETE_SRQ, sizeof(*cmd)); - if (!cmd) - return status; - cmd->id = srq->id; - status = ocrdma_mbx_cmd(srq->dev, (struct ocrdma_mqe *)cmd); - if (srq->rq.va) - dma_free_coherent(&pdev->dev, srq->rq.len, - srq->rq.va, srq->rq.pa); - kfree(cmd); - return status; -} - -int ocrdma_alloc_av(struct ocrdma_dev *dev, struct ocrdma_ah *ah) -{ - int i; - int status = -EINVAL; - struct ocrdma_av *av; - unsigned long flags; - - av = dev->av_tbl.va; - spin_lock_irqsave(&dev->av_tbl.lock, flags); - for (i = 0; i < dev->av_tbl.num_ah; i++) { - if (av->valid == 0) { - av->valid = OCRDMA_AV_VALID; - ah->av = av; - ah->id = i; - status = 0; - break; - } - av++; - } - if (i == dev->av_tbl.num_ah) - status = -EAGAIN; - spin_unlock_irqrestore(&dev->av_tbl.lock, flags); - return status; -} - -int ocrdma_free_av(struct ocrdma_dev *dev, struct ocrdma_ah *ah) -{ - unsigned long flags; - spin_lock_irqsave(&dev->av_tbl.lock, flags); - ah->av->valid = 0; - spin_unlock_irqrestore(&dev->av_tbl.lock, flags); - return 0; -} - -static int ocrdma_create_mq_eq(struct ocrdma_dev *dev) -{ - int status; - int irq; - unsigned long flags = 0; - int num_eq = 0; - - if (dev->nic_info.intr_mode == BE_INTERRUPT_MODE_INTX) - flags = IRQF_SHARED; - else { - num_eq = dev->nic_info.msix.num_vectors - - dev->nic_info.msix.start_vector; - /* minimum two vectors/eq are required for rdma to work. - * one for control path and one for data path. - */ - if (num_eq < 2) - return -EBUSY; - } - - status = ocrdma_create_eq(dev, &dev->meq, OCRDMA_EQ_LEN); - if (status) - return status; - sprintf(dev->meq.irq_name, "ocrdma_mq%d", dev->id); - irq = ocrdma_get_irq(dev, &dev->meq); - status = request_irq(irq, ocrdma_irq_handler, flags, dev->meq.irq_name, - &dev->meq); - if (status) - _ocrdma_destroy_eq(dev, &dev->meq); - return status; -} - -static int ocrdma_create_qp_eqs(struct ocrdma_dev *dev) -{ - int num_eq, i, status = 0; - int irq; - unsigned long flags = 0; - - num_eq = dev->nic_info.msix.num_vectors - - dev->nic_info.msix.start_vector; - if (dev->nic_info.intr_mode == BE_INTERRUPT_MODE_INTX) { - num_eq = 1; - flags = IRQF_SHARED; - } else - num_eq = min_t(u32, num_eq, num_online_cpus()); - dev->qp_eq_tbl = kzalloc(sizeof(struct ocrdma_eq) * num_eq, GFP_KERNEL); - if (!dev->qp_eq_tbl) - return -ENOMEM; - - for (i = 0; i < num_eq; i++) { - status = ocrdma_create_eq(dev, &dev->qp_eq_tbl[i], - OCRDMA_EQ_LEN); - if (status) { - status = -EINVAL; - break; - } - sprintf(dev->qp_eq_tbl[i].irq_name, "ocrdma_qp%d-%d", - dev->id, i); - irq = ocrdma_get_irq(dev, &dev->qp_eq_tbl[i]); - status = request_irq(irq, ocrdma_irq_handler, flags, - dev->qp_eq_tbl[i].irq_name, - &dev->qp_eq_tbl[i]); - if (status) { - _ocrdma_destroy_eq(dev, &dev->qp_eq_tbl[i]); - status = -EINVAL; - break; - } - dev->eq_cnt += 1; - } - /* one eq is sufficient for data path to work */ - if (dev->eq_cnt >= 1) - return 0; - if (status) - ocrdma_destroy_qp_eqs(dev); - return status; -} - -int ocrdma_init_hw(struct ocrdma_dev *dev) -{ - int status; - /* set up control path eq */ - status = ocrdma_create_mq_eq(dev); - if (status) - return status; - /* set up data path eq */ - status = ocrdma_create_qp_eqs(dev); - if (status) - goto qpeq_err; - status = ocrdma_create_mq(dev); - if (status) - goto mq_err; - status = ocrdma_mbx_query_fw_config(dev); - if (status) - goto conf_err; - status = ocrdma_mbx_query_dev(dev); - if (status) - goto conf_err; - status = ocrdma_mbx_query_fw_ver(dev); - if (status) - goto conf_err; - status = ocrdma_mbx_create_ah_tbl(dev); - if (status) - goto conf_err; - return 0; - -conf_err: - ocrdma_destroy_mq(dev); -mq_err: - ocrdma_destroy_qp_eqs(dev); -qpeq_err: - ocrdma_destroy_eq(dev, &dev->meq); - ocrdma_err("%s() status=%d\n", __func__, status); - return status; -} - -void ocrdma_cleanup_hw(struct ocrdma_dev *dev) -{ - ocrdma_mbx_delete_ah_tbl(dev); - - /* cleanup the data path eqs */ - ocrdma_destroy_qp_eqs(dev); - - /* cleanup the control path */ - ocrdma_destroy_mq(dev); - ocrdma_destroy_eq(dev, &dev->meq); -} diff --git a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_hw.h b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_hw.h deleted file mode 100644 index be5db77404db..000000000000 --- a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_hw.h +++ /dev/null @@ -1,132 +0,0 @@ -/******************************************************************* - * This file is part of the Emulex RoCE Device Driver for * - * RoCE (RDMA over Converged Ethernet) CNA Adapters. * - * Copyright (C) 2008-2012 Emulex. All rights reserved. * - * EMULEX and SLI are trademarks of Emulex. * - * www.emulex.com * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of version 2 of the GNU General * - * Public License as published by the Free Software Foundation. * - * This program is distributed in the hope that it will be useful. * - * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * - * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * - * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE * - * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD * - * TO BE LEGALLY INVALID. See the GNU General Public License for * - * more details, a copy of which can be found in the file COPYING * - * included with this package. * - * - * Contact Information: - * linux-drivers@emulex.com - * - * Emulex - * 3333 Susan Street - * Costa Mesa, CA 92626 - *******************************************************************/ - -#ifndef __OCRDMA_HW_H__ -#define __OCRDMA_HW_H__ - -#include "ocrdma_sli.h" - -static inline void ocrdma_cpu_to_le32(void *dst, u32 len) -{ -#ifdef __BIG_ENDIAN - int i = 0; - u32 *src_ptr = dst; - u32 *dst_ptr = dst; - for (; i < (len / 4); i++) - *(dst_ptr + i) = cpu_to_le32p(src_ptr + i); -#endif -} - -static inline void ocrdma_le32_to_cpu(void *dst, u32 len) -{ -#ifdef __BIG_ENDIAN - int i = 0; - u32 *src_ptr = dst; - u32 *dst_ptr = dst; - for (; i < (len / sizeof(u32)); i++) - *(dst_ptr + i) = le32_to_cpu(*(src_ptr + i)); -#endif -} - -static inline void ocrdma_copy_cpu_to_le32(void *dst, void *src, u32 len) -{ -#ifdef __BIG_ENDIAN - int i = 0; - u32 *src_ptr = src; - u32 *dst_ptr = dst; - for (; i < (len / sizeof(u32)); i++) - *(dst_ptr + i) = cpu_to_le32p(src_ptr + i); -#else - memcpy(dst, src, len); -#endif -} - -static inline void ocrdma_copy_le32_to_cpu(void *dst, void *src, u32 len) -{ -#ifdef __BIG_ENDIAN - int i = 0; - u32 *src_ptr = src; - u32 *dst_ptr = dst; - for (; i < len / sizeof(u32); i++) - *(dst_ptr + i) = le32_to_cpu(*(src_ptr + i)); -#else - memcpy(dst, src, len); -#endif -} - -int ocrdma_init_hw(struct ocrdma_dev *); -void ocrdma_cleanup_hw(struct ocrdma_dev *); - -enum ib_qp_state get_ibqp_state(enum ocrdma_qp_state qps); -void ocrdma_ring_cq_db(struct ocrdma_dev *, u16 cq_id, bool armed, - bool solicited, u16 cqe_popped); - -/* verbs specific mailbox commands */ -int ocrdma_query_config(struct ocrdma_dev *, - struct ocrdma_mbx_query_config *config); -int ocrdma_resolve_dgid(struct ocrdma_dev *, union ib_gid *dgid, u8 *mac_addr); - -int ocrdma_mbx_alloc_pd(struct ocrdma_dev *, struct ocrdma_pd *); -int ocrdma_mbx_dealloc_pd(struct ocrdma_dev *, struct ocrdma_pd *); - -int ocrdma_mbx_alloc_lkey(struct ocrdma_dev *, struct ocrdma_hw_mr *hwmr, - u32 pd_id, int addr_check); -int ocrdma_mbx_dealloc_lkey(struct ocrdma_dev *, int fmr, u32 lkey); - -int ocrdma_reg_mr(struct ocrdma_dev *, struct ocrdma_hw_mr *hwmr, - u32 pd_id, int acc); -int ocrdma_mbx_create_cq(struct ocrdma_dev *, struct ocrdma_cq *, - int entries, int dpp_cq); -int ocrdma_mbx_destroy_cq(struct ocrdma_dev *, struct ocrdma_cq *); - -int ocrdma_mbx_create_qp(struct ocrdma_qp *, struct ib_qp_init_attr *attrs, - u8 enable_dpp_cq, u16 dpp_cq_id, u16 *dpp_offset, - u16 *dpp_credit_lmt); -int ocrdma_mbx_modify_qp(struct ocrdma_dev *, struct ocrdma_qp *, - struct ib_qp_attr *attrs, int attr_mask, - enum ib_qp_state old_qps); -int ocrdma_mbx_query_qp(struct ocrdma_dev *, struct ocrdma_qp *, - struct ocrdma_qp_params *param); -int ocrdma_mbx_destroy_qp(struct ocrdma_dev *, struct ocrdma_qp *); - -int ocrdma_mbx_create_srq(struct ocrdma_srq *, - struct ib_srq_init_attr *, - struct ocrdma_pd *); -int ocrdma_mbx_modify_srq(struct ocrdma_srq *, struct ib_srq_attr *); -int ocrdma_mbx_query_srq(struct ocrdma_srq *, struct ib_srq_attr *); -int ocrdma_mbx_destroy_srq(struct ocrdma_dev *, struct ocrdma_srq *); - -int ocrdma_alloc_av(struct ocrdma_dev *, struct ocrdma_ah *); -int ocrdma_free_av(struct ocrdma_dev *, struct ocrdma_ah *); - -int ocrdma_qp_state_machine(struct ocrdma_qp *, enum ib_qp_state new_state, - enum ib_qp_state *old_ib_state); -bool ocrdma_is_qp_in_sq_flushlist(struct ocrdma_cq *, struct ocrdma_qp *); -bool ocrdma_is_qp_in_rq_flushlist(struct ocrdma_cq *, struct ocrdma_qp *); -void ocrdma_flush_qp(struct ocrdma_qp *); - -#endif /* __OCRDMA_HW_H__ */ diff --git a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_main.c deleted file mode 100644 index a20d16eaae71..000000000000 --- a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_main.c +++ /dev/null @@ -1,577 +0,0 @@ -/******************************************************************* - * This file is part of the Emulex RoCE Device Driver for * - * RoCE (RDMA over Converged Ethernet) adapters. * - * Copyright (C) 2008-2012 Emulex. All rights reserved. * - * EMULEX and SLI are trademarks of Emulex. * - * www.emulex.com * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of version 2 of the GNU General * - * Public License as published by the Free Software Foundation. * - * This program is distributed in the hope that it will be useful. * - * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * - * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * - * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE * - * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD * - * TO BE LEGALLY INVALID. See the GNU General Public License for * - * more details, a copy of which can be found in the file COPYING * - * included with this package. * - * - * Contact Information: - * linux-drivers@emulex.com - * - * Emulex - * 3333 Susan Street - * Costa Mesa, CA 92626 - *******************************************************************/ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "ocrdma.h" -#include "ocrdma_verbs.h" -#include "ocrdma_ah.h" -#include "be_roce.h" -#include "ocrdma_hw.h" - -MODULE_VERSION(OCRDMA_ROCE_DEV_VERSION); -MODULE_DESCRIPTION("Emulex RoCE HCA Driver"); -MODULE_AUTHOR("Emulex Corporation"); -MODULE_LICENSE("GPL"); - -static LIST_HEAD(ocrdma_dev_list); -static DEFINE_SPINLOCK(ocrdma_devlist_lock); -static DEFINE_IDR(ocrdma_dev_id); - -static union ib_gid ocrdma_zero_sgid; - -static int ocrdma_get_instance(void) -{ - int instance = 0; - - /* Assign an unused number */ - if (!idr_pre_get(&ocrdma_dev_id, GFP_KERNEL)) - return -1; - if (idr_get_new(&ocrdma_dev_id, NULL, &instance)) - return -1; - return instance; -} - -void ocrdma_get_guid(struct ocrdma_dev *dev, u8 *guid) -{ - u8 mac_addr[6]; - - memcpy(&mac_addr[0], &dev->nic_info.mac_addr[0], ETH_ALEN); - guid[0] = mac_addr[0] ^ 2; - guid[1] = mac_addr[1]; - guid[2] = mac_addr[2]; - guid[3] = 0xff; - guid[4] = 0xfe; - guid[5] = mac_addr[3]; - guid[6] = mac_addr[4]; - guid[7] = mac_addr[5]; -} - -static void ocrdma_build_sgid_mac(union ib_gid *sgid, unsigned char *mac_addr, - bool is_vlan, u16 vlan_id) -{ - sgid->global.subnet_prefix = cpu_to_be64(0xfe80000000000000LL); - sgid->raw[8] = mac_addr[0] ^ 2; - sgid->raw[9] = mac_addr[1]; - sgid->raw[10] = mac_addr[2]; - if (is_vlan) { - sgid->raw[11] = vlan_id >> 8; - sgid->raw[12] = vlan_id & 0xff; - } else { - sgid->raw[11] = 0xff; - sgid->raw[12] = 0xfe; - } - sgid->raw[13] = mac_addr[3]; - sgid->raw[14] = mac_addr[4]; - sgid->raw[15] = mac_addr[5]; -} - -static void ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, - bool is_vlan, u16 vlan_id) -{ - int i; - bool found = false; - union ib_gid new_sgid; - int free_idx = OCRDMA_MAX_SGID; - unsigned long flags; - - memset(&ocrdma_zero_sgid, 0, sizeof(union ib_gid)); - - ocrdma_build_sgid_mac(&new_sgid, mac_addr, is_vlan, vlan_id); - - spin_lock_irqsave(&dev->sgid_lock, flags); - for (i = 0; i < OCRDMA_MAX_SGID; i++) { - if (!memcmp(&dev->sgid_tbl[i], &ocrdma_zero_sgid, - sizeof(union ib_gid))) { - /* found free entry */ - if (!found) { - free_idx = i; - found = true; - break; - } - } else if (!memcmp(&dev->sgid_tbl[i], &new_sgid, - sizeof(union ib_gid))) { - /* entry already present, no addition is required. */ - spin_unlock_irqrestore(&dev->sgid_lock, flags); - return; - } - } - /* if entry doesn't exist and if table has some space, add entry */ - if (found) - memcpy(&dev->sgid_tbl[free_idx], &new_sgid, - sizeof(union ib_gid)); - spin_unlock_irqrestore(&dev->sgid_lock, flags); -} - -static bool ocrdma_del_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, - bool is_vlan, u16 vlan_id) -{ - int found = false; - int i; - union ib_gid sgid; - unsigned long flags; - - ocrdma_build_sgid_mac(&sgid, mac_addr, is_vlan, vlan_id); - - spin_lock_irqsave(&dev->sgid_lock, flags); - /* first is default sgid, which cannot be deleted. */ - for (i = 1; i < OCRDMA_MAX_SGID; i++) { - if (!memcmp(&dev->sgid_tbl[i], &sgid, sizeof(union ib_gid))) { - /* found matching entry */ - memset(&dev->sgid_tbl[i], 0, sizeof(union ib_gid)); - found = true; - break; - } - } - spin_unlock_irqrestore(&dev->sgid_lock, flags); - return found; -} - -static void ocrdma_add_default_sgid(struct ocrdma_dev *dev) -{ - /* GID Index 0 - Invariant manufacturer-assigned EUI-64 */ - union ib_gid *sgid = &dev->sgid_tbl[0]; - - sgid->global.subnet_prefix = cpu_to_be64(0xfe80000000000000LL); - ocrdma_get_guid(dev, &sgid->raw[8]); -} - -static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) -{ - struct net_device *netdev, *tmp; - u16 vlan_id; - bool is_vlan; - - netdev = dev->nic_info.netdev; - - ocrdma_add_default_sgid(dev); - - rcu_read_lock(); - for_each_netdev_rcu(&init_net, tmp) { - if (netdev == tmp || vlan_dev_real_dev(tmp) == netdev) { - if (!netif_running(tmp) || !netif_oper_up(tmp)) - continue; - if (netdev != tmp) { - vlan_id = vlan_dev_vlan_id(tmp); - is_vlan = true; - } else { - is_vlan = false; - vlan_id = 0; - tmp = netdev; - } - ocrdma_add_sgid(dev, tmp->dev_addr, is_vlan, vlan_id); - } - } - rcu_read_unlock(); - return 0; -} - -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - -static int ocrdma_inet6addr_event(struct notifier_block *notifier, - unsigned long event, void *ptr) -{ - struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; - struct net_device *event_netdev = ifa->idev->dev; - struct net_device *netdev = NULL; - struct ib_event gid_event; - struct ocrdma_dev *dev; - bool found = false; - bool is_vlan = false; - u16 vid = 0; - - netdev = vlan_dev_real_dev(event_netdev); - if (netdev != event_netdev) { - is_vlan = true; - vid = vlan_dev_vlan_id(event_netdev); - } - rcu_read_lock(); - list_for_each_entry_rcu(dev, &ocrdma_dev_list, entry) { - if (dev->nic_info.netdev == netdev) { - found = true; - break; - } - } - rcu_read_unlock(); - - if (!found) - return NOTIFY_DONE; - if (!rdma_link_local_addr((struct in6_addr *)&ifa->addr)) - return NOTIFY_DONE; - - mutex_lock(&dev->dev_lock); - switch (event) { - case NETDEV_UP: - ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid); - break; - case NETDEV_DOWN: - found = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid); - if (found) { - /* found the matching entry, notify - * the consumers about it - */ - gid_event.device = &dev->ibdev; - gid_event.element.port_num = 1; - gid_event.event = IB_EVENT_GID_CHANGE; - ib_dispatch_event(&gid_event); - } - break; - default: - break; - } - mutex_unlock(&dev->dev_lock); - return NOTIFY_OK; -} - -static struct notifier_block ocrdma_inet6addr_notifier = { - .notifier_call = ocrdma_inet6addr_event -}; - -#endif /* IPV6 */ - -static enum rdma_link_layer ocrdma_link_layer(struct ib_device *device, - u8 port_num) -{ - return IB_LINK_LAYER_ETHERNET; -} - -static int ocrdma_register_device(struct ocrdma_dev *dev) -{ - strlcpy(dev->ibdev.name, "ocrdma%d", IB_DEVICE_NAME_MAX); - ocrdma_get_guid(dev, (u8 *)&dev->ibdev.node_guid); - memcpy(dev->ibdev.node_desc, OCRDMA_NODE_DESC, - sizeof(OCRDMA_NODE_DESC)); - dev->ibdev.owner = THIS_MODULE; - dev->ibdev.uverbs_cmd_mask = - OCRDMA_UVERBS(GET_CONTEXT) | - OCRDMA_UVERBS(QUERY_DEVICE) | - OCRDMA_UVERBS(QUERY_PORT) | - OCRDMA_UVERBS(ALLOC_PD) | - OCRDMA_UVERBS(DEALLOC_PD) | - OCRDMA_UVERBS(REG_MR) | - OCRDMA_UVERBS(DEREG_MR) | - OCRDMA_UVERBS(CREATE_COMP_CHANNEL) | - OCRDMA_UVERBS(CREATE_CQ) | - OCRDMA_UVERBS(RESIZE_CQ) | - OCRDMA_UVERBS(DESTROY_CQ) | - OCRDMA_UVERBS(REQ_NOTIFY_CQ) | - OCRDMA_UVERBS(CREATE_QP) | - OCRDMA_UVERBS(MODIFY_QP) | - OCRDMA_UVERBS(QUERY_QP) | - OCRDMA_UVERBS(DESTROY_QP) | - OCRDMA_UVERBS(POLL_CQ) | - OCRDMA_UVERBS(POST_SEND) | - OCRDMA_UVERBS(POST_RECV); - - dev->ibdev.uverbs_cmd_mask |= - OCRDMA_UVERBS(CREATE_AH) | - OCRDMA_UVERBS(MODIFY_AH) | - OCRDMA_UVERBS(QUERY_AH) | - OCRDMA_UVERBS(DESTROY_AH); - - dev->ibdev.node_type = RDMA_NODE_IB_CA; - dev->ibdev.phys_port_cnt = 1; - dev->ibdev.num_comp_vectors = 1; - - /* mandatory verbs. */ - dev->ibdev.query_device = ocrdma_query_device; - dev->ibdev.query_port = ocrdma_query_port; - dev->ibdev.modify_port = ocrdma_modify_port; - dev->ibdev.query_gid = ocrdma_query_gid; - dev->ibdev.get_link_layer = ocrdma_link_layer; - dev->ibdev.alloc_pd = ocrdma_alloc_pd; - dev->ibdev.dealloc_pd = ocrdma_dealloc_pd; - - dev->ibdev.create_cq = ocrdma_create_cq; - dev->ibdev.destroy_cq = ocrdma_destroy_cq; - dev->ibdev.resize_cq = ocrdma_resize_cq; - - dev->ibdev.create_qp = ocrdma_create_qp; - dev->ibdev.modify_qp = ocrdma_modify_qp; - dev->ibdev.query_qp = ocrdma_query_qp; - dev->ibdev.destroy_qp = ocrdma_destroy_qp; - - dev->ibdev.query_pkey = ocrdma_query_pkey; - dev->ibdev.create_ah = ocrdma_create_ah; - dev->ibdev.destroy_ah = ocrdma_destroy_ah; - dev->ibdev.query_ah = ocrdma_query_ah; - dev->ibdev.modify_ah = ocrdma_modify_ah; - - dev->ibdev.poll_cq = ocrdma_poll_cq; - dev->ibdev.post_send = ocrdma_post_send; - dev->ibdev.post_recv = ocrdma_post_recv; - dev->ibdev.req_notify_cq = ocrdma_arm_cq; - - dev->ibdev.get_dma_mr = ocrdma_get_dma_mr; - dev->ibdev.dereg_mr = ocrdma_dereg_mr; - dev->ibdev.reg_user_mr = ocrdma_reg_user_mr; - - /* mandatory to support user space verbs consumer. */ - dev->ibdev.alloc_ucontext = ocrdma_alloc_ucontext; - dev->ibdev.dealloc_ucontext = ocrdma_dealloc_ucontext; - dev->ibdev.mmap = ocrdma_mmap; - dev->ibdev.dma_device = &dev->nic_info.pdev->dev; - - dev->ibdev.process_mad = ocrdma_process_mad; - - if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { - dev->ibdev.uverbs_cmd_mask |= - OCRDMA_UVERBS(CREATE_SRQ) | - OCRDMA_UVERBS(MODIFY_SRQ) | - OCRDMA_UVERBS(QUERY_SRQ) | - OCRDMA_UVERBS(DESTROY_SRQ) | - OCRDMA_UVERBS(POST_SRQ_RECV); - - dev->ibdev.create_srq = ocrdma_create_srq; - dev->ibdev.modify_srq = ocrdma_modify_srq; - dev->ibdev.query_srq = ocrdma_query_srq; - dev->ibdev.destroy_srq = ocrdma_destroy_srq; - dev->ibdev.post_srq_recv = ocrdma_post_srq_recv; - } - return ib_register_device(&dev->ibdev, NULL); -} - -static int ocrdma_alloc_resources(struct ocrdma_dev *dev) -{ - mutex_init(&dev->dev_lock); - dev->sgid_tbl = kzalloc(sizeof(union ib_gid) * - OCRDMA_MAX_SGID, GFP_KERNEL); - if (!dev->sgid_tbl) - goto alloc_err; - spin_lock_init(&dev->sgid_lock); - - dev->cq_tbl = kzalloc(sizeof(struct ocrdma_cq *) * - OCRDMA_MAX_CQ, GFP_KERNEL); - if (!dev->cq_tbl) - goto alloc_err; - - if (dev->attr.max_qp) { - dev->qp_tbl = kzalloc(sizeof(struct ocrdma_qp *) * - OCRDMA_MAX_QP, GFP_KERNEL); - if (!dev->qp_tbl) - goto alloc_err; - } - spin_lock_init(&dev->av_tbl.lock); - spin_lock_init(&dev->flush_q_lock); - return 0; -alloc_err: - ocrdma_err("%s(%d) error.\n", __func__, dev->id); - return -ENOMEM; -} - -static void ocrdma_free_resources(struct ocrdma_dev *dev) -{ - kfree(dev->qp_tbl); - kfree(dev->cq_tbl); - kfree(dev->sgid_tbl); -} - -static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info) -{ - int status = 0; - struct ocrdma_dev *dev; - - dev = (struct ocrdma_dev *)ib_alloc_device(sizeof(struct ocrdma_dev)); - if (!dev) { - ocrdma_err("Unable to allocate ib device\n"); - return NULL; - } - dev->mbx_cmd = kzalloc(sizeof(struct ocrdma_mqe_emb_cmd), GFP_KERNEL); - if (!dev->mbx_cmd) - goto idr_err; - - memcpy(&dev->nic_info, dev_info, sizeof(*dev_info)); - dev->id = ocrdma_get_instance(); - if (dev->id < 0) - goto idr_err; - - status = ocrdma_init_hw(dev); - if (status) - goto init_err; - - status = ocrdma_alloc_resources(dev); - if (status) - goto alloc_err; - - status = ocrdma_build_sgid_tbl(dev); - if (status) - goto alloc_err; - - status = ocrdma_register_device(dev); - if (status) - goto alloc_err; - - spin_lock(&ocrdma_devlist_lock); - list_add_tail_rcu(&dev->entry, &ocrdma_dev_list); - spin_unlock(&ocrdma_devlist_lock); - return dev; - -alloc_err: - ocrdma_free_resources(dev); - ocrdma_cleanup_hw(dev); -init_err: - idr_remove(&ocrdma_dev_id, dev->id); -idr_err: - kfree(dev->mbx_cmd); - ib_dealloc_device(&dev->ibdev); - ocrdma_err("%s() leaving. ret=%d\n", __func__, status); - return NULL; -} - -static void ocrdma_remove_free(struct rcu_head *rcu) -{ - struct ocrdma_dev *dev = container_of(rcu, struct ocrdma_dev, rcu); - - ocrdma_free_resources(dev); - ocrdma_cleanup_hw(dev); - - idr_remove(&ocrdma_dev_id, dev->id); - kfree(dev->mbx_cmd); - ib_dealloc_device(&dev->ibdev); -} - -static void ocrdma_remove(struct ocrdma_dev *dev) -{ - /* first unregister with stack to stop all the active traffic - * of the registered clients. - */ - ib_unregister_device(&dev->ibdev); - - spin_lock(&ocrdma_devlist_lock); - list_del_rcu(&dev->entry); - spin_unlock(&ocrdma_devlist_lock); - call_rcu(&dev->rcu, ocrdma_remove_free); -} - -static int ocrdma_open(struct ocrdma_dev *dev) -{ - struct ib_event port_event; - - port_event.event = IB_EVENT_PORT_ACTIVE; - port_event.element.port_num = 1; - port_event.device = &dev->ibdev; - ib_dispatch_event(&port_event); - return 0; -} - -static int ocrdma_close(struct ocrdma_dev *dev) -{ - int i; - struct ocrdma_qp *qp, **cur_qp; - struct ib_event err_event; - struct ib_qp_attr attrs; - int attr_mask = IB_QP_STATE; - - attrs.qp_state = IB_QPS_ERR; - mutex_lock(&dev->dev_lock); - if (dev->qp_tbl) { - cur_qp = dev->qp_tbl; - for (i = 0; i < OCRDMA_MAX_QP; i++) { - qp = cur_qp[i]; - if (qp) { - /* change the QP state to ERROR */ - _ocrdma_modify_qp(&qp->ibqp, &attrs, attr_mask); - - err_event.event = IB_EVENT_QP_FATAL; - err_event.element.qp = &qp->ibqp; - err_event.device = &dev->ibdev; - ib_dispatch_event(&err_event); - } - } - } - mutex_unlock(&dev->dev_lock); - - err_event.event = IB_EVENT_PORT_ERR; - err_event.element.port_num = 1; - err_event.device = &dev->ibdev; - ib_dispatch_event(&err_event); - return 0; -} - -/* event handling via NIC driver ensures that all the NIC specific - * initialization done before RoCE driver notifies - * event to stack. - */ -static void ocrdma_event_handler(struct ocrdma_dev *dev, u32 event) -{ - switch (event) { - case BE_DEV_UP: - ocrdma_open(dev); - break; - case BE_DEV_DOWN: - ocrdma_close(dev); - break; - }; -} - -static struct ocrdma_driver ocrdma_drv = { - .name = "ocrdma_driver", - .add = ocrdma_add, - .remove = ocrdma_remove, - .state_change_handler = ocrdma_event_handler, -}; - -static void ocrdma_unregister_inet6addr_notifier(void) -{ -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - unregister_inet6addr_notifier(&ocrdma_inet6addr_notifier); -#endif -} - -static int __init ocrdma_init_module(void) -{ - int status; - -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - status = register_inet6addr_notifier(&ocrdma_inet6addr_notifier); - if (status) - return status; -#endif - - status = be_roce_register_driver(&ocrdma_drv); - if (status) - ocrdma_unregister_inet6addr_notifier(); - - return status; -} - -static void __exit ocrdma_exit_module(void) -{ - be_roce_unregister_driver(&ocrdma_drv); - ocrdma_unregister_inet6addr_notifier(); -} - -module_init(ocrdma_init_module); -module_exit(ocrdma_exit_module); diff --git a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_sli.h deleted file mode 100644 index 7fd80cc0f037..000000000000 --- a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_sli.h +++ /dev/null @@ -1,1672 +0,0 @@ -/******************************************************************* - * This file is part of the Emulex RoCE Device Driver for * - * RoCE (RDMA over Converged Ethernet) adapters. * - * Copyright (C) 2008-2012 Emulex. All rights reserved. * - * EMULEX and SLI are trademarks of Emulex. * - * www.emulex.com * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of version 2 of the GNU General * - * Public License as published by the Free Software Foundation. * - * This program is distributed in the hope that it will be useful. * - * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * - * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * - * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE * - * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD * - * TO BE LEGALLY INVALID. See the GNU General Public License for * - * more details, a copy of which can be found in the file COPYING * - * included with this package. * - * - * Contact Information: - * linux-drivers@emulex.com - * - * Emulex - * 3333 Susan Street - * Costa Mesa, CA 92626 - *******************************************************************/ - -#ifndef __OCRDMA_SLI_H__ -#define __OCRDMA_SLI_H__ - -#define Bit(_b) (1 << (_b)) - -#define OCRDMA_GEN1_FAMILY 0xB -#define OCRDMA_GEN2_FAMILY 0x2 - -#define OCRDMA_SUBSYS_ROCE 10 -enum { - OCRDMA_CMD_QUERY_CONFIG = 1, - OCRDMA_CMD_ALLOC_PD, - OCRDMA_CMD_DEALLOC_PD, - - OCRDMA_CMD_CREATE_AH_TBL, - OCRDMA_CMD_DELETE_AH_TBL, - - OCRDMA_CMD_CREATE_QP, - OCRDMA_CMD_QUERY_QP, - OCRDMA_CMD_MODIFY_QP, - OCRDMA_CMD_DELETE_QP, - - OCRDMA_CMD_RSVD1, - OCRDMA_CMD_ALLOC_LKEY, - OCRDMA_CMD_DEALLOC_LKEY, - OCRDMA_CMD_REGISTER_NSMR, - OCRDMA_CMD_REREGISTER_NSMR, - OCRDMA_CMD_REGISTER_NSMR_CONT, - OCRDMA_CMD_QUERY_NSMR, - OCRDMA_CMD_ALLOC_MW, - OCRDMA_CMD_QUERY_MW, - - OCRDMA_CMD_CREATE_SRQ, - OCRDMA_CMD_QUERY_SRQ, - OCRDMA_CMD_MODIFY_SRQ, - OCRDMA_CMD_DELETE_SRQ, - - OCRDMA_CMD_ATTACH_MCAST, - OCRDMA_CMD_DETACH_MCAST, - - OCRDMA_CMD_MAX -}; - -#define OCRDMA_SUBSYS_COMMON 1 -enum { - OCRDMA_CMD_CREATE_CQ = 12, - OCRDMA_CMD_CREATE_EQ = 13, - OCRDMA_CMD_CREATE_MQ = 21, - OCRDMA_CMD_GET_FW_VER = 35, - OCRDMA_CMD_DELETE_MQ = 53, - OCRDMA_CMD_DELETE_CQ = 54, - OCRDMA_CMD_DELETE_EQ = 55, - OCRDMA_CMD_GET_FW_CONFIG = 58, - OCRDMA_CMD_CREATE_MQ_EXT = 90 -}; - -enum { - QTYPE_EQ = 1, - QTYPE_CQ = 2, - QTYPE_MCCQ = 3 -}; - -#define OCRDMA_MAX_SGID (8) - -#define OCRDMA_MAX_QP 2048 -#define OCRDMA_MAX_CQ 2048 - -enum { - OCRDMA_DB_RQ_OFFSET = 0xE0, - OCRDMA_DB_GEN2_RQ1_OFFSET = 0x100, - OCRDMA_DB_GEN2_RQ2_OFFSET = 0xC0, - OCRDMA_DB_SQ_OFFSET = 0x60, - OCRDMA_DB_GEN2_SQ_OFFSET = 0x1C0, - OCRDMA_DB_SRQ_OFFSET = OCRDMA_DB_RQ_OFFSET, - OCRDMA_DB_GEN2_SRQ_OFFSET = OCRDMA_DB_GEN2_RQ1_OFFSET, - OCRDMA_DB_CQ_OFFSET = 0x120, - OCRDMA_DB_EQ_OFFSET = OCRDMA_DB_CQ_OFFSET, - OCRDMA_DB_MQ_OFFSET = 0x140 -}; - -#define OCRDMA_DB_CQ_RING_ID_MASK 0x3FF /* bits 0 - 9 */ -#define OCRDMA_DB_CQ_RING_ID_EXT_MASK 0x0C00 /* bits 10-11 of qid at 12-11 */ -/* qid #2 msbits at 12-11 */ -#define OCRDMA_DB_CQ_RING_ID_EXT_MASK_SHIFT 0x1 -#define OCRDMA_DB_CQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */ -/* Rearm bit */ -#define OCRDMA_DB_CQ_REARM_SHIFT (29) /* bit 29 */ -/* solicited bit */ -#define OCRDMA_DB_CQ_SOLICIT_SHIFT (31) /* bit 31 */ - -#define OCRDMA_EQ_ID_MASK 0x1FF /* bits 0 - 8 */ -#define OCRDMA_EQ_ID_EXT_MASK 0x3e00 /* bits 9-13 */ -#define OCRDMA_EQ_ID_EXT_MASK_SHIFT (2) /* qid bits 9-13 at 11-15 */ - -/* Clear the interrupt for this eq */ -#define OCRDMA_EQ_CLR_SHIFT (9) /* bit 9 */ -/* Must be 1 */ -#define OCRDMA_EQ_TYPE_SHIFT (10) /* bit 10 */ -/* Number of event entries processed */ -#define OCRDMA_NUM_EQE_SHIFT (16) /* bits 16 - 28 */ -/* Rearm bit */ -#define OCRDMA_REARM_SHIFT (29) /* bit 29 */ - -#define OCRDMA_MQ_ID_MASK 0x7FF /* bits 0 - 10 */ -/* Number of entries posted */ -#define OCRDMA_MQ_NUM_MQE_SHIFT (16) /* bits 16 - 29 */ - -#define OCRDMA_MIN_HPAGE_SIZE (4096) - -#define OCRDMA_MIN_Q_PAGE_SIZE (4096) -#define OCRDMA_MAX_Q_PAGES (8) - -/* -# 0: 4K Bytes -# 1: 8K Bytes -# 2: 16K Bytes -# 3: 32K Bytes -# 4: 64K Bytes -*/ -#define OCRDMA_MAX_Q_PAGE_SIZE_CNT (5) -#define OCRDMA_Q_PAGE_BASE_SIZE (OCRDMA_MIN_Q_PAGE_SIZE * OCRDMA_MAX_Q_PAGES) - -#define MAX_OCRDMA_QP_PAGES (8) -#define OCRDMA_MAX_WQE_MEM_SIZE (MAX_OCRDMA_QP_PAGES * OCRDMA_MIN_HQ_PAGE_SIZE) - -#define OCRDMA_CREATE_CQ_MAX_PAGES (4) -#define OCRDMA_DPP_CQE_SIZE (4) - -#define OCRDMA_GEN2_MAX_CQE 1024 -#define OCRDMA_GEN2_CQ_PAGE_SIZE 4096 -#define OCRDMA_GEN2_WQE_SIZE 256 -#define OCRDMA_MAX_CQE 4095 -#define OCRDMA_CQ_PAGE_SIZE 16384 -#define OCRDMA_WQE_SIZE 128 -#define OCRDMA_WQE_STRIDE 8 -#define OCRDMA_WQE_ALIGN_BYTES 16 - -#define MAX_OCRDMA_SRQ_PAGES MAX_OCRDMA_QP_PAGES - -enum { - OCRDMA_MCH_OPCODE_SHIFT = 0, - OCRDMA_MCH_OPCODE_MASK = 0xFF, - OCRDMA_MCH_SUBSYS_SHIFT = 8, - OCRDMA_MCH_SUBSYS_MASK = 0xFF00 -}; - -/* mailbox cmd header */ -struct ocrdma_mbx_hdr { - u32 subsys_op; - u32 timeout; /* in seconds */ - u32 cmd_len; - u32 rsvd_version; -} __packed; - -enum { - OCRDMA_MBX_RSP_OPCODE_SHIFT = 0, - OCRDMA_MBX_RSP_OPCODE_MASK = 0xFF, - OCRDMA_MBX_RSP_SUBSYS_SHIFT = 8, - OCRDMA_MBX_RSP_SUBSYS_MASK = 0xFF << OCRDMA_MBX_RSP_SUBSYS_SHIFT, - - OCRDMA_MBX_RSP_STATUS_SHIFT = 0, - OCRDMA_MBX_RSP_STATUS_MASK = 0xFF, - OCRDMA_MBX_RSP_ASTATUS_SHIFT = 8, - OCRDMA_MBX_RSP_ASTATUS_MASK = 0xFF << OCRDMA_MBX_RSP_ASTATUS_SHIFT -}; - -/* mailbox cmd response */ -struct ocrdma_mbx_rsp { - u32 subsys_op; - u32 status; - u32 rsp_len; - u32 add_rsp_len; -} __packed; - -enum { - OCRDMA_MQE_EMBEDDED = 1, - OCRDMA_MQE_NONEMBEDDED = 0 -}; - -struct ocrdma_mqe_sge { - u32 pa_lo; - u32 pa_hi; - u32 len; -} __packed; - -enum { - OCRDMA_MQE_HDR_EMB_SHIFT = 0, - OCRDMA_MQE_HDR_EMB_MASK = Bit(0), - OCRDMA_MQE_HDR_SGE_CNT_SHIFT = 3, - OCRDMA_MQE_HDR_SGE_CNT_MASK = 0x1F << OCRDMA_MQE_HDR_SGE_CNT_SHIFT, - OCRDMA_MQE_HDR_SPECIAL_SHIFT = 24, - OCRDMA_MQE_HDR_SPECIAL_MASK = 0xFF << OCRDMA_MQE_HDR_SPECIAL_SHIFT -}; - -struct ocrdma_mqe_hdr { - u32 spcl_sge_cnt_emb; - u32 pyld_len; - u32 tag_lo; - u32 tag_hi; - u32 rsvd3; -} __packed; - -struct ocrdma_mqe_emb_cmd { - struct ocrdma_mbx_hdr mch; - u8 pyld[220]; -} __packed; - -struct ocrdma_mqe { - struct ocrdma_mqe_hdr hdr; - union { - struct ocrdma_mqe_emb_cmd emb_req; - struct { - struct ocrdma_mqe_sge sge[19]; - } nonemb_req; - u8 cmd[236]; - struct ocrdma_mbx_rsp rsp; - } u; -} __packed; - -#define OCRDMA_EQ_LEN 4096 -#define OCRDMA_MQ_CQ_LEN 256 -#define OCRDMA_MQ_LEN 128 - -#define PAGE_SHIFT_4K 12 -#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) - -/* Returns number of pages spanned by the data starting at the given addr */ -#define PAGES_4K_SPANNED(_address, size) \ - ((u32)((((size_t)(_address) & (PAGE_SIZE_4K - 1)) + \ - (size) + (PAGE_SIZE_4K - 1)) >> PAGE_SHIFT_4K)) - -struct ocrdma_delete_q_req { - struct ocrdma_mbx_hdr req; - u32 id; -} __packed; - -struct ocrdma_pa { - u32 lo; - u32 hi; -} __packed; - -#define MAX_OCRDMA_EQ_PAGES (8) -struct ocrdma_create_eq_req { - struct ocrdma_mbx_hdr req; - u32 num_pages; - u32 valid; - u32 cnt; - u32 delay; - u32 rsvd; - struct ocrdma_pa pa[MAX_OCRDMA_EQ_PAGES]; -} __packed; - -enum { - OCRDMA_CREATE_EQ_VALID = Bit(29), - OCRDMA_CREATE_EQ_CNT_SHIFT = 26, - OCRDMA_CREATE_CQ_DELAY_SHIFT = 13, -}; - -struct ocrdma_create_eq_rsp { - struct ocrdma_mbx_rsp rsp; - u32 vector_eqid; -}; - -#define OCRDMA_EQ_MINOR_OTHER (0x1) - -enum { - OCRDMA_MCQE_STATUS_SHIFT = 0, - OCRDMA_MCQE_STATUS_MASK = 0xFFFF, - OCRDMA_MCQE_ESTATUS_SHIFT = 16, - OCRDMA_MCQE_ESTATUS_MASK = 0xFFFF << OCRDMA_MCQE_ESTATUS_SHIFT, - OCRDMA_MCQE_CONS_SHIFT = 27, - OCRDMA_MCQE_CONS_MASK = Bit(27), - OCRDMA_MCQE_CMPL_SHIFT = 28, - OCRDMA_MCQE_CMPL_MASK = Bit(28), - OCRDMA_MCQE_AE_SHIFT = 30, - OCRDMA_MCQE_AE_MASK = Bit(30), - OCRDMA_MCQE_VALID_SHIFT = 31, - OCRDMA_MCQE_VALID_MASK = Bit(31) -}; - -struct ocrdma_mcqe { - u32 status; - u32 tag_lo; - u32 tag_hi; - u32 valid_ae_cmpl_cons; -} __packed; - -enum { - OCRDMA_AE_MCQE_QPVALID = Bit(31), - OCRDMA_AE_MCQE_QPID_MASK = 0xFFFF, - - OCRDMA_AE_MCQE_CQVALID = Bit(31), - OCRDMA_AE_MCQE_CQID_MASK = 0xFFFF, - OCRDMA_AE_MCQE_VALID = Bit(31), - OCRDMA_AE_MCQE_AE = Bit(30), - OCRDMA_AE_MCQE_EVENT_TYPE_SHIFT = 16, - OCRDMA_AE_MCQE_EVENT_TYPE_MASK = - 0xFF << OCRDMA_AE_MCQE_EVENT_TYPE_SHIFT, - OCRDMA_AE_MCQE_EVENT_CODE_SHIFT = 8, - OCRDMA_AE_MCQE_EVENT_CODE_MASK = - 0xFF << OCRDMA_AE_MCQE_EVENT_CODE_SHIFT -}; -struct ocrdma_ae_mcqe { - u32 qpvalid_qpid; - u32 cqvalid_cqid; - u32 evt_tag; - u32 valid_ae_event; -} __packed; - -enum { - OCRDMA_AE_MPA_MCQE_REQ_ID_SHIFT = 16, - OCRDMA_AE_MPA_MCQE_REQ_ID_MASK = 0xFFFF << - OCRDMA_AE_MPA_MCQE_REQ_ID_SHIFT, - - OCRDMA_AE_MPA_MCQE_EVENT_CODE_SHIFT = 8, - OCRDMA_AE_MPA_MCQE_EVENT_CODE_MASK = 0xFF << - OCRDMA_AE_MPA_MCQE_EVENT_CODE_SHIFT, - OCRDMA_AE_MPA_MCQE_EVENT_TYPE_SHIFT = 16, - OCRDMA_AE_MPA_MCQE_EVENT_TYPE_MASK = 0xFF << - OCRDMA_AE_MPA_MCQE_EVENT_TYPE_SHIFT, - OCRDMA_AE_MPA_MCQE_EVENT_AE_SHIFT = 30, - OCRDMA_AE_MPA_MCQE_EVENT_AE_MASK = Bit(30), - OCRDMA_AE_MPA_MCQE_EVENT_VALID_SHIFT = 31, - OCRDMA_AE_MPA_MCQE_EVENT_VALID_MASK = Bit(31) -}; - -struct ocrdma_ae_mpa_mcqe { - u32 req_id; - u32 w1; - u32 w2; - u32 valid_ae_event; -} __packed; - -enum { - OCRDMA_AE_QP_MCQE_NEW_QP_STATE_SHIFT = 0, - OCRDMA_AE_QP_MCQE_NEW_QP_STATE_MASK = 0xFFFF, - OCRDMA_AE_QP_MCQE_QP_ID_SHIFT = 16, - OCRDMA_AE_QP_MCQE_QP_ID_MASK = 0xFFFF << - OCRDMA_AE_QP_MCQE_QP_ID_SHIFT, - - OCRDMA_AE_QP_MCQE_EVENT_CODE_SHIFT = 8, - OCRDMA_AE_QP_MCQE_EVENT_CODE_MASK = 0xFF << - OCRDMA_AE_QP_MCQE_EVENT_CODE_SHIFT, - OCRDMA_AE_QP_MCQE_EVENT_TYPE_SHIFT = 16, - OCRDMA_AE_QP_MCQE_EVENT_TYPE_MASK = 0xFF << - OCRDMA_AE_QP_MCQE_EVENT_TYPE_SHIFT, - OCRDMA_AE_QP_MCQE_EVENT_AE_SHIFT = 30, - OCRDMA_AE_QP_MCQE_EVENT_AE_MASK = Bit(30), - OCRDMA_AE_QP_MCQE_EVENT_VALID_SHIFT = 31, - OCRDMA_AE_QP_MCQE_EVENT_VALID_MASK = Bit(31) -}; - -struct ocrdma_ae_qp_mcqe { - u32 qp_id_state; - u32 w1; - u32 w2; - u32 valid_ae_event; -} __packed; - -#define OCRDMA_ASYNC_EVE_CODE 0x14 - -enum OCRDMA_ASYNC_EVENT_TYPE { - OCRDMA_CQ_ERROR = 0x00, - OCRDMA_CQ_OVERRUN_ERROR = 0x01, - OCRDMA_CQ_QPCAT_ERROR = 0x02, - OCRDMA_QP_ACCESS_ERROR = 0x03, - OCRDMA_QP_COMM_EST_EVENT = 0x04, - OCRDMA_SQ_DRAINED_EVENT = 0x05, - OCRDMA_DEVICE_FATAL_EVENT = 0x08, - OCRDMA_SRQCAT_ERROR = 0x0E, - OCRDMA_SRQ_LIMIT_EVENT = 0x0F, - OCRDMA_QP_LAST_WQE_EVENT = 0x10 -}; - -/* mailbox command request and responses */ -enum { - OCRDMA_MBX_QUERY_CFG_CQ_OVERFLOW_SHIFT = 2, - OCRDMA_MBX_QUERY_CFG_CQ_OVERFLOW_MASK = Bit(2), - OCRDMA_MBX_QUERY_CFG_SRQ_SUPPORTED_SHIFT = 3, - OCRDMA_MBX_QUERY_CFG_SRQ_SUPPORTED_MASK = Bit(3), - OCRDMA_MBX_QUERY_CFG_MAX_QP_SHIFT = 8, - OCRDMA_MBX_QUERY_CFG_MAX_QP_MASK = 0xFFFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_QP_SHIFT, - - OCRDMA_MBX_QUERY_CFG_MAX_PD_SHIFT = 16, - OCRDMA_MBX_QUERY_CFG_MAX_PD_MASK = 0xFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_PD_SHIFT, - OCRDMA_MBX_QUERY_CFG_CA_ACK_DELAY_SHIFT = 8, - OCRDMA_MBX_QUERY_CFG_CA_ACK_DELAY_MASK = 0xFF << - OCRDMA_MBX_QUERY_CFG_CA_ACK_DELAY_SHIFT, - - OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT = 0, - OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK = 0xFFFF, - - OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT = 0, - OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK = 0xFFFF, - OCRDMA_MBX_QUERY_CFG_MAX_IRD_PER_QP_SHIFT = 16, - OCRDMA_MBX_QUERY_CFG_MAX_IRD_PER_QP_MASK = 0xFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_IRD_PER_QP_SHIFT, - - OCRDMA_MBX_QUERY_CFG_MAX_WQE_SIZE_OFFSET = 24, - OCRDMA_MBX_QUERY_CFG_MAX_WQE_SIZE_MASK = 0xFF << - OCRDMA_MBX_QUERY_CFG_MAX_WQE_SIZE_OFFSET, - OCRDMA_MBX_QUERY_CFG_MAX_RQE_SIZE_OFFSET = 16, - OCRDMA_MBX_QUERY_CFG_MAX_RQE_SIZE_MASK = 0xFF << - OCRDMA_MBX_QUERY_CFG_MAX_RQE_SIZE_OFFSET, - OCRDMA_MBX_QUERY_CFG_MAX_DPP_CQES_OFFSET = 0, - OCRDMA_MBX_QUERY_CFG_MAX_DPP_CQES_MASK = 0xFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_DPP_CQES_OFFSET, - - OCRDMA_MBX_QUERY_CFG_MAX_SRQ_OFFSET = 16, - OCRDMA_MBX_QUERY_CFG_MAX_SRQ_MASK = 0xFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_SRQ_OFFSET, - OCRDMA_MBX_QUERY_CFG_MAX_RPIR_QPS_OFFSET = 0, - OCRDMA_MBX_QUERY_CFG_MAX_RPIR_QPS_MASK = 0xFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_RPIR_QPS_OFFSET, - - OCRDMA_MBX_QUERY_CFG_MAX_DPP_PDS_OFFSET = 16, - OCRDMA_MBX_QUERY_CFG_MAX_DPP_PDS_MASK = 0xFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_DPP_PDS_OFFSET, - OCRDMA_MBX_QUERY_CFG_MAX_DPP_CREDITS_OFFSET = 0, - OCRDMA_MBX_QUERY_CFG_MAX_DPP_CREDITS_MASK = 0xFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_DPP_CREDITS_OFFSET, - - OCRDMA_MBX_QUERY_CFG_MAX_DPP_QPS_OFFSET = 0, - OCRDMA_MBX_QUERY_CFG_MAX_DPP_QPS_MASK = 0xFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_DPP_QPS_OFFSET, - - OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET = 16, - OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_MASK = 0xFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET, - OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_OFFSET = 0, - OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_MASK = 0xFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET, - - OCRDMA_MBX_QUERY_CFG_MAX_CQ_OFFSET = 16, - OCRDMA_MBX_QUERY_CFG_MAX_CQ_MASK = 0xFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_CQ_OFFSET, - OCRDMA_MBX_QUERY_CFG_MAX_CQES_PER_CQ_OFFSET = 0, - OCRDMA_MBX_QUERY_CFG_MAX_CQES_PER_CQ_MASK = 0xFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_CQES_PER_CQ_OFFSET, - - OCRDMA_MBX_QUERY_CFG_MAX_SRQ_RQE_OFFSET = 16, - OCRDMA_MBX_QUERY_CFG_MAX_SRQ_RQE_MASK = 0xFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_SRQ_RQE_OFFSET, - OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_OFFSET = 0, - OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_MASK = 0xFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_OFFSET, -}; - -struct ocrdma_mbx_query_config { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rsp; - u32 qp_srq_cq_ird_ord; - u32 max_pd_ca_ack_delay; - u32 max_write_send_sge; - u32 max_ird_ord_per_qp; - u32 max_shared_ird_ord; - u32 max_mr; - u64 max_mr_size; - u32 max_num_mr_pbl; - u32 max_mw; - u32 max_fmr; - u32 max_pages_per_frmr; - u32 max_mcast_group; - u32 max_mcast_qp_attach; - u32 max_total_mcast_qp_attach; - u32 wqe_rqe_stride_max_dpp_cqs; - u32 max_srq_rpir_qps; - u32 max_dpp_pds_credits; - u32 max_dpp_credits_pds_per_pd; - u32 max_wqes_rqes_per_q; - u32 max_cq_cqes_per_cq; - u32 max_srq_rqe_sge; -} __packed; - -struct ocrdma_fw_ver_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rsp; - - u8 running_ver[32]; -} __packed; - -struct ocrdma_fw_conf_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rsp; - - u32 config_num; - u32 asic_revision; - u32 phy_port; - u32 fn_mode; - struct { - u32 mode; - u32 nic_wqid_base; - u32 nic_wq_tot; - u32 prot_wqid_base; - u32 prot_wq_tot; - u32 prot_rqid_base; - u32 prot_rqid_tot; - u32 rsvd[6]; - } ulp[2]; - u32 fn_capabilities; - u32 rsvd1; - u32 rsvd2; - u32 base_eqid; - u32 max_eq; - -} __packed; - -enum { - OCRDMA_FN_MODE_RDMA = 0x4 -}; - -enum { - OCRDMA_CREATE_CQ_VER2 = 2, - - OCRDMA_CREATE_CQ_PAGE_CNT_MASK = 0xFFFF, - OCRDMA_CREATE_CQ_PAGE_SIZE_SHIFT = 16, - OCRDMA_CREATE_CQ_PAGE_SIZE_MASK = 0xFF, - - OCRDMA_CREATE_CQ_COALESCWM_SHIFT = 12, - OCRDMA_CREATE_CQ_COALESCWM_MASK = Bit(13) | Bit(12), - OCRDMA_CREATE_CQ_FLAGS_NODELAY = Bit(14), - OCRDMA_CREATE_CQ_FLAGS_AUTO_VALID = Bit(15), - - OCRDMA_CREATE_CQ_EQ_ID_MASK = 0xFFFF, - OCRDMA_CREATE_CQ_CQE_COUNT_MASK = 0xFFFF -}; - -enum { - OCRDMA_CREATE_CQ_VER0 = 0, - OCRDMA_CREATE_CQ_DPP = 1, - OCRDMA_CREATE_CQ_TYPE_SHIFT = 24, - OCRDMA_CREATE_CQ_EQID_SHIFT = 22, - - OCRDMA_CREATE_CQ_CNT_SHIFT = 27, - OCRDMA_CREATE_CQ_FLAGS_VALID = Bit(29), - OCRDMA_CREATE_CQ_FLAGS_EVENTABLE = Bit(31), - OCRDMA_CREATE_CQ_DEF_FLAGS = OCRDMA_CREATE_CQ_FLAGS_VALID | - OCRDMA_CREATE_CQ_FLAGS_EVENTABLE | - OCRDMA_CREATE_CQ_FLAGS_NODELAY -}; - -struct ocrdma_create_cq_cmd { - struct ocrdma_mbx_hdr req; - u32 pgsz_pgcnt; - u32 ev_cnt_flags; - u32 eqn; - u32 cqe_count; - u32 rsvd6; - struct ocrdma_pa pa[OCRDMA_CREATE_CQ_MAX_PAGES]; -}; - -struct ocrdma_create_cq { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_create_cq_cmd cmd; -} __packed; - -enum { - OCRDMA_CREATE_CQ_RSP_CQ_ID_MASK = 0xFFFF -}; - -struct ocrdma_create_cq_cmd_rsp { - struct ocrdma_mbx_rsp rsp; - u32 cq_id; -} __packed; - -struct ocrdma_create_cq_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_create_cq_cmd_rsp rsp; -} __packed; - -enum { - OCRDMA_CREATE_MQ_V0_CQ_ID_SHIFT = 22, - OCRDMA_CREATE_MQ_CQ_ID_SHIFT = 16, - OCRDMA_CREATE_MQ_RING_SIZE_SHIFT = 16, - OCRDMA_CREATE_MQ_VALID = Bit(31), - OCRDMA_CREATE_MQ_ASYNC_CQ_VALID = Bit(0) -}; - -struct ocrdma_create_mq_v0 { - u32 pages; - u32 cqid_ringsize; - u32 valid; - u32 async_cqid_valid; - u32 rsvd; - struct ocrdma_pa pa[8]; -} __packed; - -struct ocrdma_create_mq_v1 { - u32 cqid_pages; - u32 async_event_bitmap; - u32 async_cqid_ringsize; - u32 valid; - u32 async_cqid_valid; - u32 rsvd; - struct ocrdma_pa pa[8]; -} __packed; - -struct ocrdma_create_mq_req { - struct ocrdma_mbx_hdr req; - union { - struct ocrdma_create_mq_v0 v0; - struct ocrdma_create_mq_v1 v1; - }; -} __packed; - -struct ocrdma_create_mq_rsp { - struct ocrdma_mbx_rsp rsp; - u32 id; -} __packed; - -enum { - OCRDMA_DESTROY_CQ_QID_SHIFT = 0, - OCRDMA_DESTROY_CQ_QID_MASK = 0xFFFF, - OCRDMA_DESTROY_CQ_QID_BYPASS_FLUSH_SHIFT = 16, - OCRDMA_DESTROY_CQ_QID_BYPASS_FLUSH_MASK = 0xFFFF << - OCRDMA_DESTROY_CQ_QID_BYPASS_FLUSH_SHIFT -}; - -struct ocrdma_destroy_cq { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_hdr req; - - u32 bypass_flush_qid; -} __packed; - -struct ocrdma_destroy_cq_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rsp; -} __packed; - -enum { - OCRDMA_QPT_GSI = 1, - OCRDMA_QPT_RC = 2, - OCRDMA_QPT_UD = 4, -}; - -enum { - OCRDMA_CREATE_QP_REQ_PD_ID_SHIFT = 0, - OCRDMA_CREATE_QP_REQ_PD_ID_MASK = 0xFFFF, - OCRDMA_CREATE_QP_REQ_SQ_PAGE_SIZE_SHIFT = 16, - OCRDMA_CREATE_QP_REQ_RQ_PAGE_SIZE_SHIFT = 19, - OCRDMA_CREATE_QP_REQ_QPT_SHIFT = 29, - OCRDMA_CREATE_QP_REQ_QPT_MASK = Bit(31) | Bit(30) | Bit(29), - - OCRDMA_CREATE_QP_REQ_MAX_RQE_SHIFT = 0, - OCRDMA_CREATE_QP_REQ_MAX_RQE_MASK = 0xFFFF, - OCRDMA_CREATE_QP_REQ_MAX_WQE_SHIFT = 16, - OCRDMA_CREATE_QP_REQ_MAX_WQE_MASK = 0xFFFF << - OCRDMA_CREATE_QP_REQ_MAX_WQE_SHIFT, - - OCRDMA_CREATE_QP_REQ_MAX_SGE_WRITE_SHIFT = 0, - OCRDMA_CREATE_QP_REQ_MAX_SGE_WRITE_MASK = 0xFFFF, - OCRDMA_CREATE_QP_REQ_MAX_SGE_SEND_SHIFT = 16, - OCRDMA_CREATE_QP_REQ_MAX_SGE_SEND_MASK = 0xFFFF << - OCRDMA_CREATE_QP_REQ_MAX_SGE_SEND_SHIFT, - - OCRDMA_CREATE_QP_REQ_FMR_EN_SHIFT = 0, - OCRDMA_CREATE_QP_REQ_FMR_EN_MASK = Bit(0), - OCRDMA_CREATE_QP_REQ_ZERO_LKEYEN_SHIFT = 1, - OCRDMA_CREATE_QP_REQ_ZERO_LKEYEN_MASK = Bit(1), - OCRDMA_CREATE_QP_REQ_BIND_MEMWIN_SHIFT = 2, - OCRDMA_CREATE_QP_REQ_BIND_MEMWIN_MASK = Bit(2), - OCRDMA_CREATE_QP_REQ_INB_WREN_SHIFT = 3, - OCRDMA_CREATE_QP_REQ_INB_WREN_MASK = Bit(3), - OCRDMA_CREATE_QP_REQ_INB_RDEN_SHIFT = 4, - OCRDMA_CREATE_QP_REQ_INB_RDEN_MASK = Bit(4), - OCRDMA_CREATE_QP_REQ_USE_SRQ_SHIFT = 5, - OCRDMA_CREATE_QP_REQ_USE_SRQ_MASK = Bit(5), - OCRDMA_CREATE_QP_REQ_ENABLE_RPIR_SHIFT = 6, - OCRDMA_CREATE_QP_REQ_ENABLE_RPIR_MASK = Bit(6), - OCRDMA_CREATE_QP_REQ_ENABLE_DPP_SHIFT = 7, - OCRDMA_CREATE_QP_REQ_ENABLE_DPP_MASK = Bit(7), - OCRDMA_CREATE_QP_REQ_ENABLE_DPP_CQ_SHIFT = 8, - OCRDMA_CREATE_QP_REQ_ENABLE_DPP_CQ_MASK = Bit(8), - OCRDMA_CREATE_QP_REQ_MAX_SGE_RECV_SHIFT = 16, - OCRDMA_CREATE_QP_REQ_MAX_SGE_RECV_MASK = 0xFFFF << - OCRDMA_CREATE_QP_REQ_MAX_SGE_RECV_SHIFT, - - OCRDMA_CREATE_QP_REQ_MAX_IRD_SHIFT = 0, - OCRDMA_CREATE_QP_REQ_MAX_IRD_MASK = 0xFFFF, - OCRDMA_CREATE_QP_REQ_MAX_ORD_SHIFT = 16, - OCRDMA_CREATE_QP_REQ_MAX_ORD_MASK = 0xFFFF << - OCRDMA_CREATE_QP_REQ_MAX_ORD_SHIFT, - - OCRDMA_CREATE_QP_REQ_NUM_RQ_PAGES_SHIFT = 0, - OCRDMA_CREATE_QP_REQ_NUM_RQ_PAGES_MASK = 0xFFFF, - OCRDMA_CREATE_QP_REQ_NUM_WQ_PAGES_SHIFT = 16, - OCRDMA_CREATE_QP_REQ_NUM_WQ_PAGES_MASK = 0xFFFF << - OCRDMA_CREATE_QP_REQ_NUM_WQ_PAGES_SHIFT, - - OCRDMA_CREATE_QP_REQ_RQE_SIZE_SHIFT = 0, - OCRDMA_CREATE_QP_REQ_RQE_SIZE_MASK = 0xFFFF, - OCRDMA_CREATE_QP_REQ_WQE_SIZE_SHIFT = 16, - OCRDMA_CREATE_QP_REQ_WQE_SIZE_MASK = 0xFFFF << - OCRDMA_CREATE_QP_REQ_WQE_SIZE_SHIFT, - - OCRDMA_CREATE_QP_REQ_RQ_CQID_SHIFT = 0, - OCRDMA_CREATE_QP_REQ_RQ_CQID_MASK = 0xFFFF, - OCRDMA_CREATE_QP_REQ_WQ_CQID_SHIFT = 16, - OCRDMA_CREATE_QP_REQ_WQ_CQID_MASK = 0xFFFF << - OCRDMA_CREATE_QP_REQ_WQ_CQID_SHIFT, - - OCRDMA_CREATE_QP_REQ_DPP_CQPID_SHIFT = 0, - OCRDMA_CREATE_QP_REQ_DPP_CQPID_MASK = 0xFFFF, - OCRDMA_CREATE_QP_REQ_DPP_CREDIT_SHIFT = 16, - OCRDMA_CREATE_QP_REQ_DPP_CREDIT_MASK = 0xFFFF << - OCRDMA_CREATE_QP_REQ_DPP_CREDIT_SHIFT -}; - -enum { - OCRDMA_CREATE_QP_REQ_DPP_CREDIT_LIMIT = 16, - OCRDMA_CREATE_QP_RSP_DPP_PAGE_SHIFT = 1 -}; - -#define MAX_OCRDMA_IRD_PAGES 4 - -enum ocrdma_qp_flags { - OCRDMA_QP_MW_BIND = 1, - OCRDMA_QP_LKEY0 = (1 << 1), - OCRDMA_QP_FAST_REG = (1 << 2), - OCRDMA_QP_INB_RD = (1 << 6), - OCRDMA_QP_INB_WR = (1 << 7), -}; - -enum ocrdma_qp_state { - OCRDMA_QPS_RST = 0, - OCRDMA_QPS_INIT = 1, - OCRDMA_QPS_RTR = 2, - OCRDMA_QPS_RTS = 3, - OCRDMA_QPS_SQE = 4, - OCRDMA_QPS_SQ_DRAINING = 5, - OCRDMA_QPS_ERR = 6, - OCRDMA_QPS_SQD = 7 -}; - -struct ocrdma_create_qp_req { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_hdr req; - - u32 type_pgsz_pdn; - u32 max_wqe_rqe; - u32 max_sge_send_write; - u32 max_sge_recv_flags; - u32 max_ord_ird; - u32 num_wq_rq_pages; - u32 wqe_rqe_size; - u32 wq_rq_cqid; - struct ocrdma_pa wq_addr[MAX_OCRDMA_QP_PAGES]; - struct ocrdma_pa rq_addr[MAX_OCRDMA_QP_PAGES]; - u32 dpp_credits_cqid; - u32 rpir_lkey; - struct ocrdma_pa ird_addr[MAX_OCRDMA_IRD_PAGES]; -} __packed; - -enum { - OCRDMA_CREATE_QP_RSP_QP_ID_SHIFT = 0, - OCRDMA_CREATE_QP_RSP_QP_ID_MASK = 0xFFFF, - - OCRDMA_CREATE_QP_RSP_MAX_RQE_SHIFT = 0, - OCRDMA_CREATE_QP_RSP_MAX_RQE_MASK = 0xFFFF, - OCRDMA_CREATE_QP_RSP_MAX_WQE_SHIFT = 16, - OCRDMA_CREATE_QP_RSP_MAX_WQE_MASK = 0xFFFF << - OCRDMA_CREATE_QP_RSP_MAX_WQE_SHIFT, - - OCRDMA_CREATE_QP_RSP_MAX_SGE_WRITE_SHIFT = 0, - OCRDMA_CREATE_QP_RSP_MAX_SGE_WRITE_MASK = 0xFFFF, - OCRDMA_CREATE_QP_RSP_MAX_SGE_SEND_SHIFT = 16, - OCRDMA_CREATE_QP_RSP_MAX_SGE_SEND_MASK = 0xFFFF << - OCRDMA_CREATE_QP_RSP_MAX_SGE_SEND_SHIFT, - - OCRDMA_CREATE_QP_RSP_MAX_SGE_RECV_SHIFT = 16, - OCRDMA_CREATE_QP_RSP_MAX_SGE_RECV_MASK = 0xFFFF << - OCRDMA_CREATE_QP_RSP_MAX_SGE_RECV_SHIFT, - - OCRDMA_CREATE_QP_RSP_MAX_IRD_SHIFT = 0, - OCRDMA_CREATE_QP_RSP_MAX_IRD_MASK = 0xFFFF, - OCRDMA_CREATE_QP_RSP_MAX_ORD_SHIFT = 16, - OCRDMA_CREATE_QP_RSP_MAX_ORD_MASK = 0xFFFF << - OCRDMA_CREATE_QP_RSP_MAX_ORD_SHIFT, - - OCRDMA_CREATE_QP_RSP_RQ_ID_SHIFT = 0, - OCRDMA_CREATE_QP_RSP_RQ_ID_MASK = 0xFFFF, - OCRDMA_CREATE_QP_RSP_SQ_ID_SHIFT = 16, - OCRDMA_CREATE_QP_RSP_SQ_ID_MASK = 0xFFFF << - OCRDMA_CREATE_QP_RSP_SQ_ID_SHIFT, - - OCRDMA_CREATE_QP_RSP_DPP_ENABLED_MASK = Bit(0), - OCRDMA_CREATE_QP_RSP_DPP_PAGE_OFFSET_SHIFT = 1, - OCRDMA_CREATE_QP_RSP_DPP_PAGE_OFFSET_MASK = 0x7FFF << - OCRDMA_CREATE_QP_RSP_DPP_PAGE_OFFSET_SHIFT, - OCRDMA_CREATE_QP_RSP_DPP_CREDITS_SHIFT = 16, - OCRDMA_CREATE_QP_RSP_DPP_CREDITS_MASK = 0xFFFF << - OCRDMA_CREATE_QP_RSP_DPP_CREDITS_SHIFT, -}; - -struct ocrdma_create_qp_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rsp; - - u32 qp_id; - u32 max_wqe_rqe; - u32 max_sge_send_write; - u32 max_sge_recv; - u32 max_ord_ird; - u32 sq_rq_id; - u32 dpp_response; -} __packed; - -struct ocrdma_destroy_qp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_hdr req; - u32 qp_id; -} __packed; - -struct ocrdma_destroy_qp_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rsp; -} __packed; - -enum { - OCRDMA_MODIFY_QP_ID_SHIFT = 0, - OCRDMA_MODIFY_QP_ID_MASK = 0xFFFF, - - OCRDMA_QP_PARA_QPS_VALID = Bit(0), - OCRDMA_QP_PARA_SQD_ASYNC_VALID = Bit(1), - OCRDMA_QP_PARA_PKEY_VALID = Bit(2), - OCRDMA_QP_PARA_QKEY_VALID = Bit(3), - OCRDMA_QP_PARA_PMTU_VALID = Bit(4), - OCRDMA_QP_PARA_ACK_TO_VALID = Bit(5), - OCRDMA_QP_PARA_RETRY_CNT_VALID = Bit(6), - OCRDMA_QP_PARA_RRC_VALID = Bit(7), - OCRDMA_QP_PARA_RQPSN_VALID = Bit(8), - OCRDMA_QP_PARA_MAX_IRD_VALID = Bit(9), - OCRDMA_QP_PARA_MAX_ORD_VALID = Bit(10), - OCRDMA_QP_PARA_RNT_VALID = Bit(11), - OCRDMA_QP_PARA_SQPSN_VALID = Bit(12), - OCRDMA_QP_PARA_DST_QPN_VALID = Bit(13), - OCRDMA_QP_PARA_MAX_WQE_VALID = Bit(14), - OCRDMA_QP_PARA_MAX_RQE_VALID = Bit(15), - OCRDMA_QP_PARA_SGE_SEND_VALID = Bit(16), - OCRDMA_QP_PARA_SGE_RECV_VALID = Bit(17), - OCRDMA_QP_PARA_SGE_WR_VALID = Bit(18), - OCRDMA_QP_PARA_INB_RDEN_VALID = Bit(19), - OCRDMA_QP_PARA_INB_WREN_VALID = Bit(20), - OCRDMA_QP_PARA_FLOW_LBL_VALID = Bit(21), - OCRDMA_QP_PARA_BIND_EN_VALID = Bit(22), - OCRDMA_QP_PARA_ZLKEY_EN_VALID = Bit(23), - OCRDMA_QP_PARA_FMR_EN_VALID = Bit(24), - OCRDMA_QP_PARA_INBAT_EN_VALID = Bit(25), - OCRDMA_QP_PARA_VLAN_EN_VALID = Bit(26), - - OCRDMA_MODIFY_QP_FLAGS_RD = Bit(0), - OCRDMA_MODIFY_QP_FLAGS_WR = Bit(1), - OCRDMA_MODIFY_QP_FLAGS_SEND = Bit(2), - OCRDMA_MODIFY_QP_FLAGS_ATOMIC = Bit(3) -}; - -enum { - OCRDMA_QP_PARAMS_SRQ_ID_SHIFT = 0, - OCRDMA_QP_PARAMS_SRQ_ID_MASK = 0xFFFF, - - OCRDMA_QP_PARAMS_MAX_RQE_SHIFT = 0, - OCRDMA_QP_PARAMS_MAX_RQE_MASK = 0xFFFF, - OCRDMA_QP_PARAMS_MAX_WQE_SHIFT = 16, - OCRDMA_QP_PARAMS_MAX_WQE_MASK = 0xFFFF << - OCRDMA_QP_PARAMS_MAX_WQE_SHIFT, - - OCRDMA_QP_PARAMS_MAX_SGE_WRITE_SHIFT = 0, - OCRDMA_QP_PARAMS_MAX_SGE_WRITE_MASK = 0xFFFF, - OCRDMA_QP_PARAMS_MAX_SGE_SEND_SHIFT = 16, - OCRDMA_QP_PARAMS_MAX_SGE_SEND_MASK = 0xFFFF << - OCRDMA_QP_PARAMS_MAX_SGE_SEND_SHIFT, - - OCRDMA_QP_PARAMS_FLAGS_FMR_EN = Bit(0), - OCRDMA_QP_PARAMS_FLAGS_LKEY_0_EN = Bit(1), - OCRDMA_QP_PARAMS_FLAGS_BIND_MW_EN = Bit(2), - OCRDMA_QP_PARAMS_FLAGS_INBWR_EN = Bit(3), - OCRDMA_QP_PARAMS_FLAGS_INBRD_EN = Bit(4), - OCRDMA_QP_PARAMS_STATE_SHIFT = 5, - OCRDMA_QP_PARAMS_STATE_MASK = Bit(5) | Bit(6) | Bit(7), - OCRDMA_QP_PARAMS_FLAGS_SQD_ASYNC = Bit(8), - OCRDMA_QP_PARAMS_FLAGS_INB_ATEN = Bit(9), - OCRDMA_QP_PARAMS_MAX_SGE_RECV_SHIFT = 16, - OCRDMA_QP_PARAMS_MAX_SGE_RECV_MASK = 0xFFFF << - OCRDMA_QP_PARAMS_MAX_SGE_RECV_SHIFT, - - OCRDMA_QP_PARAMS_MAX_IRD_SHIFT = 0, - OCRDMA_QP_PARAMS_MAX_IRD_MASK = 0xFFFF, - OCRDMA_QP_PARAMS_MAX_ORD_SHIFT = 16, - OCRDMA_QP_PARAMS_MAX_ORD_MASK = 0xFFFF << - OCRDMA_QP_PARAMS_MAX_ORD_SHIFT, - - OCRDMA_QP_PARAMS_RQ_CQID_SHIFT = 0, - OCRDMA_QP_PARAMS_RQ_CQID_MASK = 0xFFFF, - OCRDMA_QP_PARAMS_WQ_CQID_SHIFT = 16, - OCRDMA_QP_PARAMS_WQ_CQID_MASK = 0xFFFF << - OCRDMA_QP_PARAMS_WQ_CQID_SHIFT, - - OCRDMA_QP_PARAMS_RQ_PSN_SHIFT = 0, - OCRDMA_QP_PARAMS_RQ_PSN_MASK = 0xFFFFFF, - OCRDMA_QP_PARAMS_HOP_LMT_SHIFT = 24, - OCRDMA_QP_PARAMS_HOP_LMT_MASK = 0xFF << - OCRDMA_QP_PARAMS_HOP_LMT_SHIFT, - - OCRDMA_QP_PARAMS_SQ_PSN_SHIFT = 0, - OCRDMA_QP_PARAMS_SQ_PSN_MASK = 0xFFFFFF, - OCRDMA_QP_PARAMS_TCLASS_SHIFT = 24, - OCRDMA_QP_PARAMS_TCLASS_MASK = 0xFF << - OCRDMA_QP_PARAMS_TCLASS_SHIFT, - - OCRDMA_QP_PARAMS_DEST_QPN_SHIFT = 0, - OCRDMA_QP_PARAMS_DEST_QPN_MASK = 0xFFFFFF, - OCRDMA_QP_PARAMS_RNR_RETRY_CNT_SHIFT = 24, - OCRDMA_QP_PARAMS_RNR_RETRY_CNT_MASK = 0x7 << - OCRDMA_QP_PARAMS_RNR_RETRY_CNT_SHIFT, - OCRDMA_QP_PARAMS_ACK_TIMEOUT_SHIFT = 27, - OCRDMA_QP_PARAMS_ACK_TIMEOUT_MASK = 0x1F << - OCRDMA_QP_PARAMS_ACK_TIMEOUT_SHIFT, - - OCRDMA_QP_PARAMS_PKEY_IDNEX_SHIFT = 0, - OCRDMA_QP_PARAMS_PKEY_INDEX_MASK = 0xFFFF, - OCRDMA_QP_PARAMS_PATH_MTU_SHIFT = 18, - OCRDMA_QP_PARAMS_PATH_MTU_MASK = 0x3FFF << - OCRDMA_QP_PARAMS_PATH_MTU_SHIFT, - - OCRDMA_QP_PARAMS_FLOW_LABEL_SHIFT = 0, - OCRDMA_QP_PARAMS_FLOW_LABEL_MASK = 0xFFFFF, - OCRDMA_QP_PARAMS_SL_SHIFT = 20, - OCRDMA_QP_PARAMS_SL_MASK = 0xF << - OCRDMA_QP_PARAMS_SL_SHIFT, - OCRDMA_QP_PARAMS_RETRY_CNT_SHIFT = 24, - OCRDMA_QP_PARAMS_RETRY_CNT_MASK = 0x7 << - OCRDMA_QP_PARAMS_RETRY_CNT_SHIFT, - OCRDMA_QP_PARAMS_RNR_NAK_TIMER_SHIFT = 27, - OCRDMA_QP_PARAMS_RNR_NAK_TIMER_MASK = 0x1F << - OCRDMA_QP_PARAMS_RNR_NAK_TIMER_SHIFT, - - OCRDMA_QP_PARAMS_DMAC_B4_TO_B5_SHIFT = 0, - OCRDMA_QP_PARAMS_DMAC_B4_TO_B5_MASK = 0xFFFF, - OCRDMA_QP_PARAMS_VLAN_SHIFT = 16, - OCRDMA_QP_PARAMS_VLAN_MASK = 0xFFFF << - OCRDMA_QP_PARAMS_VLAN_SHIFT -}; - -struct ocrdma_qp_params { - u32 id; - u32 max_wqe_rqe; - u32 max_sge_send_write; - u32 max_sge_recv_flags; - u32 max_ord_ird; - u32 wq_rq_cqid; - u32 hop_lmt_rq_psn; - u32 tclass_sq_psn; - u32 ack_to_rnr_rtc_dest_qpn; - u32 path_mtu_pkey_indx; - u32 rnt_rc_sl_fl; - u8 sgid[16]; - u8 dgid[16]; - u32 dmac_b0_to_b3; - u32 vlan_dmac_b4_to_b5; - u32 qkey; -} __packed; - - -struct ocrdma_modify_qp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_hdr req; - - struct ocrdma_qp_params params; - u32 flags; - u32 rdma_flags; - u32 num_outstanding_atomic_rd; -} __packed; - -enum { - OCRDMA_MODIFY_QP_RSP_MAX_RQE_SHIFT = 0, - OCRDMA_MODIFY_QP_RSP_MAX_RQE_MASK = 0xFFFF, - OCRDMA_MODIFY_QP_RSP_MAX_WQE_SHIFT = 16, - OCRDMA_MODIFY_QP_RSP_MAX_WQE_MASK = 0xFFFF << - OCRDMA_MODIFY_QP_RSP_MAX_WQE_SHIFT, - - OCRDMA_MODIFY_QP_RSP_MAX_IRD_SHIFT = 0, - OCRDMA_MODIFY_QP_RSP_MAX_IRD_MASK = 0xFFFF, - OCRDMA_MODIFY_QP_RSP_MAX_ORD_SHIFT = 16, - OCRDMA_MODIFY_QP_RSP_MAX_ORD_MASK = 0xFFFF << - OCRDMA_MODIFY_QP_RSP_MAX_ORD_SHIFT -}; -struct ocrdma_modify_qp_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rsp; - - u32 max_wqe_rqe; - u32 max_ord_ird; -} __packed; - -struct ocrdma_query_qp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_hdr req; - -#define OCRDMA_QUERY_UP_QP_ID_SHIFT 0 -#define OCRDMA_QUERY_UP_QP_ID_MASK 0xFFFFFF - u32 qp_id; -} __packed; - -struct ocrdma_query_qp_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rsp; - struct ocrdma_qp_params params; -} __packed; - -enum { - OCRDMA_CREATE_SRQ_PD_ID_SHIFT = 0, - OCRDMA_CREATE_SRQ_PD_ID_MASK = 0xFFFF, - OCRDMA_CREATE_SRQ_PG_SZ_SHIFT = 16, - OCRDMA_CREATE_SRQ_PG_SZ_MASK = 0x3 << - OCRDMA_CREATE_SRQ_PG_SZ_SHIFT, - - OCRDMA_CREATE_SRQ_MAX_RQE_SHIFT = 0, - OCRDMA_CREATE_SRQ_MAX_SGE_RECV_SHIFT = 16, - OCRDMA_CREATE_SRQ_MAX_SGE_RECV_MASK = 0xFFFF << - OCRDMA_CREATE_SRQ_MAX_SGE_RECV_SHIFT, - - OCRDMA_CREATE_SRQ_RQE_SIZE_SHIFT = 0, - OCRDMA_CREATE_SRQ_RQE_SIZE_MASK = 0xFFFF, - OCRDMA_CREATE_SRQ_NUM_RQ_PAGES_SHIFT = 16, - OCRDMA_CREATE_SRQ_NUM_RQ_PAGES_MASK = 0xFFFF << - OCRDMA_CREATE_SRQ_NUM_RQ_PAGES_SHIFT -}; - -struct ocrdma_create_srq { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_hdr req; - - u32 pgsz_pdid; - u32 max_sge_rqe; - u32 pages_rqe_sz; - struct ocrdma_pa rq_addr[MAX_OCRDMA_SRQ_PAGES]; -} __packed; - -enum { - OCRDMA_CREATE_SRQ_RSP_SRQ_ID_SHIFT = 0, - OCRDMA_CREATE_SRQ_RSP_SRQ_ID_MASK = 0xFFFFFF, - - OCRDMA_CREATE_SRQ_RSP_MAX_RQE_ALLOCATED_SHIFT = 0, - OCRDMA_CREATE_SRQ_RSP_MAX_RQE_ALLOCATED_MASK = 0xFFFF, - OCRDMA_CREATE_SRQ_RSP_MAX_SGE_RECV_ALLOCATED_SHIFT = 16, - OCRDMA_CREATE_SRQ_RSP_MAX_SGE_RECV_ALLOCATED_MASK = 0xFFFF << - OCRDMA_CREATE_SRQ_RSP_MAX_SGE_RECV_ALLOCATED_SHIFT -}; - -struct ocrdma_create_srq_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rsp; - - u32 id; - u32 max_sge_rqe_allocated; -} __packed; - -enum { - OCRDMA_MODIFY_SRQ_ID_SHIFT = 0, - OCRDMA_MODIFY_SRQ_ID_MASK = 0xFFFFFF, - - OCRDMA_MODIFY_SRQ_MAX_RQE_SHIFT = 0, - OCRDMA_MODIFY_SRQ_MAX_RQE_MASK = 0xFFFF, - OCRDMA_MODIFY_SRQ_LIMIT_SHIFT = 16, - OCRDMA_MODIFY_SRQ__LIMIT_MASK = 0xFFFF << - OCRDMA_MODIFY_SRQ_LIMIT_SHIFT -}; - -struct ocrdma_modify_srq { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rep; - - u32 id; - u32 limit_max_rqe; -} __packed; - -enum { - OCRDMA_QUERY_SRQ_ID_SHIFT = 0, - OCRDMA_QUERY_SRQ_ID_MASK = 0xFFFFFF -}; - -struct ocrdma_query_srq { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp req; - - u32 id; -} __packed; - -enum { - OCRDMA_QUERY_SRQ_RSP_PD_ID_SHIFT = 0, - OCRDMA_QUERY_SRQ_RSP_PD_ID_MASK = 0xFFFF, - OCRDMA_QUERY_SRQ_RSP_MAX_RQE_SHIFT = 16, - OCRDMA_QUERY_SRQ_RSP_MAX_RQE_MASK = 0xFFFF << - OCRDMA_QUERY_SRQ_RSP_MAX_RQE_SHIFT, - - OCRDMA_QUERY_SRQ_RSP_MAX_SGE_RECV_SHIFT = 0, - OCRDMA_QUERY_SRQ_RSP_MAX_SGE_RECV_MASK = 0xFFFF, - OCRDMA_QUERY_SRQ_RSP_SRQ_LIMIT_SHIFT = 16, - OCRDMA_QUERY_SRQ_RSP_SRQ_LIMIT_MASK = 0xFFFF << - OCRDMA_QUERY_SRQ_RSP_SRQ_LIMIT_SHIFT -}; - -struct ocrdma_query_srq_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp req; - - u32 max_rqe_pdid; - u32 srq_lmt_max_sge; -} __packed; - -enum { - OCRDMA_DESTROY_SRQ_ID_SHIFT = 0, - OCRDMA_DESTROY_SRQ_ID_MASK = 0xFFFFFF -}; - -struct ocrdma_destroy_srq { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp req; - - u32 id; -} __packed; - -enum { - OCRDMA_ALLOC_PD_ENABLE_DPP = BIT(16), - OCRDMA_PD_MAX_DPP_ENABLED_QP = 8, - OCRDMA_DPP_PAGE_SIZE = 4096 -}; - -struct ocrdma_alloc_pd { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_hdr req; - u32 enable_dpp_rsvd; -} __packed; - -enum { - OCRDMA_ALLOC_PD_RSP_DPP = Bit(16), - OCRDMA_ALLOC_PD_RSP_DPP_PAGE_SHIFT = 20, - OCRDMA_ALLOC_PD_RSP_PDID_MASK = 0xFFFF, -}; - -struct ocrdma_alloc_pd_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rsp; - u32 dpp_page_pdid; -} __packed; - -struct ocrdma_dealloc_pd { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_hdr req; - u32 id; -} __packed; - -struct ocrdma_dealloc_pd_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rsp; -} __packed; - -enum { - OCRDMA_ADDR_CHECK_ENABLE = 1, - OCRDMA_ADDR_CHECK_DISABLE = 0 -}; - -enum { - OCRDMA_ALLOC_LKEY_PD_ID_SHIFT = 0, - OCRDMA_ALLOC_LKEY_PD_ID_MASK = 0xFFFF, - - OCRDMA_ALLOC_LKEY_ADDR_CHECK_SHIFT = 0, - OCRDMA_ALLOC_LKEY_ADDR_CHECK_MASK = Bit(0), - OCRDMA_ALLOC_LKEY_FMR_SHIFT = 1, - OCRDMA_ALLOC_LKEY_FMR_MASK = Bit(1), - OCRDMA_ALLOC_LKEY_REMOTE_INV_SHIFT = 2, - OCRDMA_ALLOC_LKEY_REMOTE_INV_MASK = Bit(2), - OCRDMA_ALLOC_LKEY_REMOTE_WR_SHIFT = 3, - OCRDMA_ALLOC_LKEY_REMOTE_WR_MASK = Bit(3), - OCRDMA_ALLOC_LKEY_REMOTE_RD_SHIFT = 4, - OCRDMA_ALLOC_LKEY_REMOTE_RD_MASK = Bit(4), - OCRDMA_ALLOC_LKEY_LOCAL_WR_SHIFT = 5, - OCRDMA_ALLOC_LKEY_LOCAL_WR_MASK = Bit(5), - OCRDMA_ALLOC_LKEY_REMOTE_ATOMIC_MASK = Bit(6), - OCRDMA_ALLOC_LKEY_REMOTE_ATOMIC_SHIFT = 6, - OCRDMA_ALLOC_LKEY_PBL_SIZE_SHIFT = 16, - OCRDMA_ALLOC_LKEY_PBL_SIZE_MASK = 0xFFFF << - OCRDMA_ALLOC_LKEY_PBL_SIZE_SHIFT -}; - -struct ocrdma_alloc_lkey { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_hdr req; - - u32 pdid; - u32 pbl_sz_flags; -} __packed; - -struct ocrdma_alloc_lkey_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rsp; - - u32 lrkey; - u32 num_pbl_rsvd; -} __packed; - -struct ocrdma_dealloc_lkey { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_hdr req; - - u32 lkey; - u32 rsvd_frmr; -} __packed; - -struct ocrdma_dealloc_lkey_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rsp; -} __packed; - -#define MAX_OCRDMA_NSMR_PBL (u32)22 -#define MAX_OCRDMA_PBL_SIZE 65536 -#define MAX_OCRDMA_PBL_PER_LKEY 32767 - -enum { - OCRDMA_REG_NSMR_LRKEY_INDEX_SHIFT = 0, - OCRDMA_REG_NSMR_LRKEY_INDEX_MASK = 0xFFFFFF, - OCRDMA_REG_NSMR_LRKEY_SHIFT = 24, - OCRDMA_REG_NSMR_LRKEY_MASK = 0xFF << - OCRDMA_REG_NSMR_LRKEY_SHIFT, - - OCRDMA_REG_NSMR_PD_ID_SHIFT = 0, - OCRDMA_REG_NSMR_PD_ID_MASK = 0xFFFF, - OCRDMA_REG_NSMR_NUM_PBL_SHIFT = 16, - OCRDMA_REG_NSMR_NUM_PBL_MASK = 0xFFFF << - OCRDMA_REG_NSMR_NUM_PBL_SHIFT, - - OCRDMA_REG_NSMR_PBE_SIZE_SHIFT = 0, - OCRDMA_REG_NSMR_PBE_SIZE_MASK = 0xFFFF, - OCRDMA_REG_NSMR_HPAGE_SIZE_SHIFT = 16, - OCRDMA_REG_NSMR_HPAGE_SIZE_MASK = 0xFF << - OCRDMA_REG_NSMR_HPAGE_SIZE_SHIFT, - OCRDMA_REG_NSMR_BIND_MEMWIN_SHIFT = 24, - OCRDMA_REG_NSMR_BIND_MEMWIN_MASK = Bit(24), - OCRDMA_REG_NSMR_ZB_SHIFT = 25, - OCRDMA_REG_NSMR_ZB_SHIFT_MASK = Bit(25), - OCRDMA_REG_NSMR_REMOTE_INV_SHIFT = 26, - OCRDMA_REG_NSMR_REMOTE_INV_MASK = Bit(26), - OCRDMA_REG_NSMR_REMOTE_WR_SHIFT = 27, - OCRDMA_REG_NSMR_REMOTE_WR_MASK = Bit(27), - OCRDMA_REG_NSMR_REMOTE_RD_SHIFT = 28, - OCRDMA_REG_NSMR_REMOTE_RD_MASK = Bit(28), - OCRDMA_REG_NSMR_LOCAL_WR_SHIFT = 29, - OCRDMA_REG_NSMR_LOCAL_WR_MASK = Bit(29), - OCRDMA_REG_NSMR_REMOTE_ATOMIC_SHIFT = 30, - OCRDMA_REG_NSMR_REMOTE_ATOMIC_MASK = Bit(30), - OCRDMA_REG_NSMR_LAST_SHIFT = 31, - OCRDMA_REG_NSMR_LAST_MASK = Bit(31) -}; - -struct ocrdma_reg_nsmr { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_hdr cmd; - - u32 lrkey_key_index; - u32 num_pbl_pdid; - u32 flags_hpage_pbe_sz; - u32 totlen_low; - u32 totlen_high; - u32 fbo_low; - u32 fbo_high; - u32 va_loaddr; - u32 va_hiaddr; - struct ocrdma_pa pbl[MAX_OCRDMA_NSMR_PBL]; -} __packed; - -enum { - OCRDMA_REG_NSMR_CONT_PBL_SHIFT = 0, - OCRDMA_REG_NSMR_CONT_PBL_SHIFT_MASK = 0xFFFF, - OCRDMA_REG_NSMR_CONT_NUM_PBL_SHIFT = 16, - OCRDMA_REG_NSMR_CONT_NUM_PBL_MASK = 0xFFFF << - OCRDMA_REG_NSMR_CONT_NUM_PBL_SHIFT, - - OCRDMA_REG_NSMR_CONT_LAST_SHIFT = 31, - OCRDMA_REG_NSMR_CONT_LAST_MASK = Bit(31) -}; - -struct ocrdma_reg_nsmr_cont { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_hdr cmd; - - u32 lrkey; - u32 num_pbl_offset; - u32 last; - - struct ocrdma_pa pbl[MAX_OCRDMA_NSMR_PBL]; -} __packed; - -struct ocrdma_pbe { - u32 pa_hi; - u32 pa_lo; -} __packed; - -enum { - OCRDMA_REG_NSMR_RSP_NUM_PBL_SHIFT = 16, - OCRDMA_REG_NSMR_RSP_NUM_PBL_MASK = 0xFFFF0000 -}; -struct ocrdma_reg_nsmr_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rsp; - - u32 lrkey; - u32 num_pbl; -} __packed; - -enum { - OCRDMA_REG_NSMR_CONT_RSP_LRKEY_INDEX_SHIFT = 0, - OCRDMA_REG_NSMR_CONT_RSP_LRKEY_INDEX_MASK = 0xFFFFFF, - OCRDMA_REG_NSMR_CONT_RSP_LRKEY_SHIFT = 24, - OCRDMA_REG_NSMR_CONT_RSP_LRKEY_MASK = 0xFF << - OCRDMA_REG_NSMR_CONT_RSP_LRKEY_SHIFT, - - OCRDMA_REG_NSMR_CONT_RSP_NUM_PBL_SHIFT = 16, - OCRDMA_REG_NSMR_CONT_RSP_NUM_PBL_MASK = 0xFFFF << - OCRDMA_REG_NSMR_CONT_RSP_NUM_PBL_SHIFT -}; - -struct ocrdma_reg_nsmr_cont_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rsp; - - u32 lrkey_key_index; - u32 num_pbl; -} __packed; - -enum { - OCRDMA_ALLOC_MW_PD_ID_SHIFT = 0, - OCRDMA_ALLOC_MW_PD_ID_MASK = 0xFFFF -}; - -struct ocrdma_alloc_mw { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_hdr req; - - u32 pdid; -} __packed; - -enum { - OCRDMA_ALLOC_MW_RSP_LRKEY_INDEX_SHIFT = 0, - OCRDMA_ALLOC_MW_RSP_LRKEY_INDEX_MASK = 0xFFFFFF -}; - -struct ocrdma_alloc_mw_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rsp; - - u32 lrkey_index; -} __packed; - -struct ocrdma_attach_mcast { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_hdr req; - u32 qp_id; - u8 mgid[16]; - u32 mac_b0_to_b3; - u32 vlan_mac_b4_to_b5; -} __packed; - -struct ocrdma_attach_mcast_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rsp; -} __packed; - -struct ocrdma_detach_mcast { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_hdr req; - u32 qp_id; - u8 mgid[16]; - u32 mac_b0_to_b3; - u32 vlan_mac_b4_to_b5; -} __packed; - -struct ocrdma_detach_mcast_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rsp; -} __packed; - -enum { - OCRDMA_CREATE_AH_NUM_PAGES_SHIFT = 19, - OCRDMA_CREATE_AH_NUM_PAGES_MASK = 0xF << - OCRDMA_CREATE_AH_NUM_PAGES_SHIFT, - - OCRDMA_CREATE_AH_PAGE_SIZE_SHIFT = 16, - OCRDMA_CREATE_AH_PAGE_SIZE_MASK = 0x7 << - OCRDMA_CREATE_AH_PAGE_SIZE_SHIFT, - - OCRDMA_CREATE_AH_ENTRY_SIZE_SHIFT = 23, - OCRDMA_CREATE_AH_ENTRY_SIZE_MASK = 0x1FF << - OCRDMA_CREATE_AH_ENTRY_SIZE_SHIFT, -}; - -#define OCRDMA_AH_TBL_PAGES 8 - -struct ocrdma_create_ah_tbl { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_hdr req; - - u32 ah_conf; - struct ocrdma_pa tbl_addr[8]; -} __packed; - -struct ocrdma_create_ah_tbl_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rsp; - u32 ahid; -} __packed; - -struct ocrdma_delete_ah_tbl { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_hdr req; - u32 ahid; -} __packed; - -struct ocrdma_delete_ah_tbl_rsp { - struct ocrdma_mqe_hdr hdr; - struct ocrdma_mbx_rsp rsp; -} __packed; - -enum { - OCRDMA_EQE_VALID_SHIFT = 0, - OCRDMA_EQE_VALID_MASK = Bit(0), - OCRDMA_EQE_FOR_CQE_MASK = 0xFFFE, - OCRDMA_EQE_RESOURCE_ID_SHIFT = 16, - OCRDMA_EQE_RESOURCE_ID_MASK = 0xFFFF << - OCRDMA_EQE_RESOURCE_ID_SHIFT, -}; - -struct ocrdma_eqe { - u32 id_valid; -} __packed; - -enum OCRDMA_CQE_STATUS { - OCRDMA_CQE_SUCCESS = 0, - OCRDMA_CQE_LOC_LEN_ERR, - OCRDMA_CQE_LOC_QP_OP_ERR, - OCRDMA_CQE_LOC_EEC_OP_ERR, - OCRDMA_CQE_LOC_PROT_ERR, - OCRDMA_CQE_WR_FLUSH_ERR, - OCRDMA_CQE_MW_BIND_ERR, - OCRDMA_CQE_BAD_RESP_ERR, - OCRDMA_CQE_LOC_ACCESS_ERR, - OCRDMA_CQE_REM_INV_REQ_ERR, - OCRDMA_CQE_REM_ACCESS_ERR, - OCRDMA_CQE_REM_OP_ERR, - OCRDMA_CQE_RETRY_EXC_ERR, - OCRDMA_CQE_RNR_RETRY_EXC_ERR, - OCRDMA_CQE_LOC_RDD_VIOL_ERR, - OCRDMA_CQE_REM_INV_RD_REQ_ERR, - OCRDMA_CQE_REM_ABORT_ERR, - OCRDMA_CQE_INV_EECN_ERR, - OCRDMA_CQE_INV_EEC_STATE_ERR, - OCRDMA_CQE_FATAL_ERR, - OCRDMA_CQE_RESP_TIMEOUT_ERR, - OCRDMA_CQE_GENERAL_ERR -}; - -enum { - /* w0 */ - OCRDMA_CQE_WQEIDX_SHIFT = 0, - OCRDMA_CQE_WQEIDX_MASK = 0xFFFF, - - /* w1 */ - OCRDMA_CQE_UD_XFER_LEN_SHIFT = 16, - OCRDMA_CQE_PKEY_SHIFT = 0, - OCRDMA_CQE_PKEY_MASK = 0xFFFF, - - /* w2 */ - OCRDMA_CQE_QPN_SHIFT = 0, - OCRDMA_CQE_QPN_MASK = 0x0000FFFF, - - OCRDMA_CQE_BUFTAG_SHIFT = 16, - OCRDMA_CQE_BUFTAG_MASK = 0xFFFF << OCRDMA_CQE_BUFTAG_SHIFT, - - /* w3 */ - OCRDMA_CQE_UD_STATUS_SHIFT = 24, - OCRDMA_CQE_UD_STATUS_MASK = 0x7 << OCRDMA_CQE_UD_STATUS_SHIFT, - OCRDMA_CQE_STATUS_SHIFT = 16, - OCRDMA_CQE_STATUS_MASK = 0xFF << OCRDMA_CQE_STATUS_SHIFT, - OCRDMA_CQE_VALID = Bit(31), - OCRDMA_CQE_INVALIDATE = Bit(30), - OCRDMA_CQE_QTYPE = Bit(29), - OCRDMA_CQE_IMM = Bit(28), - OCRDMA_CQE_WRITE_IMM = Bit(27), - OCRDMA_CQE_QTYPE_SQ = 0, - OCRDMA_CQE_QTYPE_RQ = 1, - OCRDMA_CQE_SRCQP_MASK = 0xFFFFFF -}; - -struct ocrdma_cqe { - union { - /* w0 to w2 */ - struct { - u32 wqeidx; - u32 bytes_xfered; - u32 qpn; - } wq; - struct { - u32 lkey_immdt; - u32 rxlen; - u32 buftag_qpn; - } rq; - struct { - u32 lkey_immdt; - u32 rxlen_pkey; - u32 buftag_qpn; - } ud; - struct { - u32 word_0; - u32 word_1; - u32 qpn; - } cmn; - }; - u32 flags_status_srcqpn; /* w3 */ -} __packed; - -#define is_cqe_valid(cq, cqe) \ - (((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_VALID)\ - == cq->phase) ? 1 : 0) -#define is_cqe_for_sq(cqe) \ - ((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_QTYPE) ? 0 : 1) -#define is_cqe_for_rq(cqe) \ - ((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_QTYPE) ? 1 : 0) -#define is_cqe_invalidated(cqe) \ - ((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_INVALIDATE) ? \ - 1 : 0) -#define is_cqe_imm(cqe) \ - ((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_IMM) ? 1 : 0) -#define is_cqe_wr_imm(cqe) \ - ((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_WRITE_IMM) ? 1 : 0) - -struct ocrdma_sge { - u32 addr_hi; - u32 addr_lo; - u32 lrkey; - u32 len; -} __packed; - -enum { - OCRDMA_FLAG_SIG = 0x1, - OCRDMA_FLAG_INV = 0x2, - OCRDMA_FLAG_FENCE_L = 0x4, - OCRDMA_FLAG_FENCE_R = 0x8, - OCRDMA_FLAG_SOLICIT = 0x10, - OCRDMA_FLAG_IMM = 0x20, - - /* Stag flags */ - OCRDMA_LKEY_FLAG_LOCAL_WR = 0x1, - OCRDMA_LKEY_FLAG_REMOTE_RD = 0x2, - OCRDMA_LKEY_FLAG_REMOTE_WR = 0x4, - OCRDMA_LKEY_FLAG_VATO = 0x8, -}; - -enum OCRDMA_WQE_OPCODE { - OCRDMA_WRITE = 0x06, - OCRDMA_READ = 0x0C, - OCRDMA_RESV0 = 0x02, - OCRDMA_SEND = 0x00, - OCRDMA_CMP_SWP = 0x14, - OCRDMA_BIND_MW = 0x10, - OCRDMA_RESV1 = 0x0A, - OCRDMA_LKEY_INV = 0x15, - OCRDMA_FETCH_ADD = 0x13, - OCRDMA_POST_RQ = 0x12 -}; - -enum { - OCRDMA_TYPE_INLINE = 0x0, - OCRDMA_TYPE_LKEY = 0x1, -}; - -enum { - OCRDMA_WQE_OPCODE_SHIFT = 0, - OCRDMA_WQE_OPCODE_MASK = 0x0000001F, - OCRDMA_WQE_FLAGS_SHIFT = 5, - OCRDMA_WQE_TYPE_SHIFT = 16, - OCRDMA_WQE_TYPE_MASK = 0x00030000, - OCRDMA_WQE_SIZE_SHIFT = 18, - OCRDMA_WQE_SIZE_MASK = 0xFF, - OCRDMA_WQE_NXT_WQE_SIZE_SHIFT = 25, - - OCRDMA_WQE_LKEY_FLAGS_SHIFT = 0, - OCRDMA_WQE_LKEY_FLAGS_MASK = 0xF -}; - -/* header WQE for all the SQ and RQ operations */ -struct ocrdma_hdr_wqe { - u32 cw; - union { - u32 rsvd_tag; - u32 rsvd_lkey_flags; - }; - union { - u32 immdt; - u32 lkey; - }; - u32 total_len; -} __packed; - -struct ocrdma_ewqe_ud_hdr { - u32 rsvd_dest_qpn; - u32 qkey; - u32 rsvd_ahid; - u32 rsvd; -} __packed; - -struct ocrdma_eth_basic { - u8 dmac[6]; - u8 smac[6]; - __be16 eth_type; -} __packed; - -struct ocrdma_eth_vlan { - u8 dmac[6]; - u8 smac[6]; - __be16 eth_type; - __be16 vlan_tag; -#define OCRDMA_ROCE_ETH_TYPE 0x8915 - __be16 roce_eth_type; -} __packed; - -struct ocrdma_grh { - __be32 tclass_flow; - __be32 pdid_hoplimit; - u8 sgid[16]; - u8 dgid[16]; - u16 rsvd; -} __packed; - -#define OCRDMA_AV_VALID Bit(0) -#define OCRDMA_AV_VLAN_VALID Bit(1) - -struct ocrdma_av { - struct ocrdma_eth_vlan eth_hdr; - struct ocrdma_grh grh; - u32 valid; -} __packed; - -#endif /* __OCRDMA_SLI_H__ */ diff --git a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c deleted file mode 100644 index e9f74d1b48f6..000000000000 --- a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ /dev/null @@ -1,2537 +0,0 @@ -/******************************************************************* - * This file is part of the Emulex RoCE Device Driver for * - * RoCE (RDMA over Converged Ethernet) adapters. * - * Copyright (C) 2008-2012 Emulex. All rights reserved. * - * EMULEX and SLI are trademarks of Emulex. * - * www.emulex.com * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of version 2 of the GNU General * - * Public License as published by the Free Software Foundation. * - * This program is distributed in the hope that it will be useful. * - * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * - * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * - * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE * - * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD * - * TO BE LEGALLY INVALID. See the GNU General Public License for * - * more details, a copy of which can be found in the file COPYING * - * included with this package. * - * - * Contact Information: - * linux-drivers@emulex.com - * - * Emulex - * 3333 Susan Street - * Costa Mesa, CA 92626 - *******************************************************************/ - -#include -#include -#include -#include -#include -#include - -#include "ocrdma.h" -#include "ocrdma_hw.h" -#include "ocrdma_verbs.h" -#include "ocrdma_abi.h" - -int ocrdma_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey) -{ - if (index > 1) - return -EINVAL; - - *pkey = 0xffff; - return 0; -} - -int ocrdma_query_gid(struct ib_device *ibdev, u8 port, - int index, union ib_gid *sgid) -{ - struct ocrdma_dev *dev; - - dev = get_ocrdma_dev(ibdev); - memset(sgid, 0, sizeof(*sgid)); - if (index > OCRDMA_MAX_SGID) - return -EINVAL; - - memcpy(sgid, &dev->sgid_tbl[index], sizeof(*sgid)); - - return 0; -} - -int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr) -{ - struct ocrdma_dev *dev = get_ocrdma_dev(ibdev); - - memset(attr, 0, sizeof *attr); - memcpy(&attr->fw_ver, &dev->attr.fw_ver[0], - min(sizeof(dev->attr.fw_ver), sizeof(attr->fw_ver))); - ocrdma_get_guid(dev, (u8 *)&attr->sys_image_guid); - attr->max_mr_size = ~0ull; - attr->page_size_cap = 0xffff000; - attr->vendor_id = dev->nic_info.pdev->vendor; - attr->vendor_part_id = dev->nic_info.pdev->device; - attr->hw_ver = 0; - attr->max_qp = dev->attr.max_qp; - attr->max_ah = dev->attr.max_qp; - attr->max_qp_wr = dev->attr.max_wqe; - - attr->device_cap_flags = IB_DEVICE_CURR_QP_STATE_MOD | - IB_DEVICE_RC_RNR_NAK_GEN | - IB_DEVICE_SHUTDOWN_PORT | - IB_DEVICE_SYS_IMAGE_GUID | - IB_DEVICE_LOCAL_DMA_LKEY; - attr->max_sge = dev->attr.max_send_sge; - attr->max_sge_rd = dev->attr.max_send_sge; - attr->max_cq = dev->attr.max_cq; - attr->max_cqe = dev->attr.max_cqe; - attr->max_mr = dev->attr.max_mr; - attr->max_mw = 0; - attr->max_pd = dev->attr.max_pd; - attr->atomic_cap = 0; - attr->max_fmr = 0; - attr->max_map_per_fmr = 0; - attr->max_qp_rd_atom = - min(dev->attr.max_ord_per_qp, dev->attr.max_ird_per_qp); - attr->max_qp_init_rd_atom = dev->attr.max_ord_per_qp; - attr->max_srq = (dev->attr.max_qp - 1); - attr->max_srq_sge = attr->max_sge; - attr->max_srq_wr = dev->attr.max_rqe; - attr->local_ca_ack_delay = dev->attr.local_ca_ack_delay; - attr->max_fast_reg_page_list_len = 0; - attr->max_pkeys = 1; - return 0; -} - -int ocrdma_query_port(struct ib_device *ibdev, - u8 port, struct ib_port_attr *props) -{ - enum ib_port_state port_state; - struct ocrdma_dev *dev; - struct net_device *netdev; - - dev = get_ocrdma_dev(ibdev); - if (port > 1) { - ocrdma_err("%s(%d) invalid_port=0x%x\n", __func__, - dev->id, port); - return -EINVAL; - } - netdev = dev->nic_info.netdev; - if (netif_running(netdev) && netif_oper_up(netdev)) { - port_state = IB_PORT_ACTIVE; - props->phys_state = 5; - } else { - port_state = IB_PORT_DOWN; - props->phys_state = 3; - } - props->max_mtu = IB_MTU_4096; - props->active_mtu = iboe_get_mtu(netdev->mtu); - props->lid = 0; - props->lmc = 0; - props->sm_lid = 0; - props->sm_sl = 0; - props->state = port_state; - props->port_cap_flags = - IB_PORT_CM_SUP | - IB_PORT_REINIT_SUP | - IB_PORT_DEVICE_MGMT_SUP | IB_PORT_VENDOR_CLASS_SUP; - props->gid_tbl_len = OCRDMA_MAX_SGID; - props->pkey_tbl_len = 1; - props->bad_pkey_cntr = 0; - props->qkey_viol_cntr = 0; - props->active_width = IB_WIDTH_1X; - props->active_speed = 4; - props->max_msg_sz = 0x80000000; - props->max_vl_num = 4; - return 0; -} - -int ocrdma_modify_port(struct ib_device *ibdev, u8 port, int mask, - struct ib_port_modify *props) -{ - struct ocrdma_dev *dev; - - dev = get_ocrdma_dev(ibdev); - if (port > 1) { - ocrdma_err("%s(%d) invalid_port=0x%x\n", __func__, - dev->id, port); - return -EINVAL; - } - return 0; -} - -static int ocrdma_add_mmap(struct ocrdma_ucontext *uctx, u64 phy_addr, - unsigned long len) -{ - struct ocrdma_mm *mm; - - mm = kzalloc(sizeof(*mm), GFP_KERNEL); - if (mm == NULL) - return -ENOMEM; - mm->key.phy_addr = phy_addr; - mm->key.len = len; - INIT_LIST_HEAD(&mm->entry); - - mutex_lock(&uctx->mm_list_lock); - list_add_tail(&mm->entry, &uctx->mm_head); - mutex_unlock(&uctx->mm_list_lock); - return 0; -} - -static void ocrdma_del_mmap(struct ocrdma_ucontext *uctx, u64 phy_addr, - unsigned long len) -{ - struct ocrdma_mm *mm, *tmp; - - mutex_lock(&uctx->mm_list_lock); - list_for_each_entry_safe(mm, tmp, &uctx->mm_head, entry) { - if (len != mm->key.len || phy_addr != mm->key.phy_addr) - continue; - - list_del(&mm->entry); - kfree(mm); - break; - } - mutex_unlock(&uctx->mm_list_lock); -} - -static bool ocrdma_search_mmap(struct ocrdma_ucontext *uctx, u64 phy_addr, - unsigned long len) -{ - bool found = false; - struct ocrdma_mm *mm; - - mutex_lock(&uctx->mm_list_lock); - list_for_each_entry(mm, &uctx->mm_head, entry) { - if (len != mm->key.len || phy_addr != mm->key.phy_addr) - continue; - - found = true; - break; - } - mutex_unlock(&uctx->mm_list_lock); - return found; -} - -struct ib_ucontext *ocrdma_alloc_ucontext(struct ib_device *ibdev, - struct ib_udata *udata) -{ - int status; - struct ocrdma_ucontext *ctx; - struct ocrdma_alloc_ucontext_resp resp; - struct ocrdma_dev *dev = get_ocrdma_dev(ibdev); - struct pci_dev *pdev = dev->nic_info.pdev; - u32 map_len = roundup(sizeof(u32) * 2048, PAGE_SIZE); - - if (!udata) - return ERR_PTR(-EFAULT); - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return ERR_PTR(-ENOMEM); - ctx->dev = dev; - INIT_LIST_HEAD(&ctx->mm_head); - mutex_init(&ctx->mm_list_lock); - - ctx->ah_tbl.va = dma_alloc_coherent(&pdev->dev, map_len, - &ctx->ah_tbl.pa, GFP_KERNEL); - if (!ctx->ah_tbl.va) { - kfree(ctx); - return ERR_PTR(-ENOMEM); - } - memset(ctx->ah_tbl.va, 0, map_len); - ctx->ah_tbl.len = map_len; - - resp.ah_tbl_len = ctx->ah_tbl.len; - resp.ah_tbl_page = ctx->ah_tbl.pa; - - status = ocrdma_add_mmap(ctx, resp.ah_tbl_page, resp.ah_tbl_len); - if (status) - goto map_err; - resp.dev_id = dev->id; - resp.max_inline_data = dev->attr.max_inline_data; - resp.wqe_size = dev->attr.wqe_size; - resp.rqe_size = dev->attr.rqe_size; - resp.dpp_wqe_size = dev->attr.wqe_size; - resp.rsvd = 0; - - memcpy(resp.fw_ver, dev->attr.fw_ver, sizeof(resp.fw_ver)); - status = ib_copy_to_udata(udata, &resp, sizeof(resp)); - if (status) - goto cpy_err; - return &ctx->ibucontext; - -cpy_err: - ocrdma_del_mmap(ctx, ctx->ah_tbl.pa, ctx->ah_tbl.len); -map_err: - dma_free_coherent(&pdev->dev, ctx->ah_tbl.len, ctx->ah_tbl.va, - ctx->ah_tbl.pa); - kfree(ctx); - return ERR_PTR(status); -} - -int ocrdma_dealloc_ucontext(struct ib_ucontext *ibctx) -{ - struct ocrdma_mm *mm, *tmp; - struct ocrdma_ucontext *uctx = get_ocrdma_ucontext(ibctx); - struct pci_dev *pdev = uctx->dev->nic_info.pdev; - - ocrdma_del_mmap(uctx, uctx->ah_tbl.pa, uctx->ah_tbl.len); - dma_free_coherent(&pdev->dev, uctx->ah_tbl.len, uctx->ah_tbl.va, - uctx->ah_tbl.pa); - - list_for_each_entry_safe(mm, tmp, &uctx->mm_head, entry) { - list_del(&mm->entry); - kfree(mm); - } - kfree(uctx); - return 0; -} - -int ocrdma_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) -{ - struct ocrdma_ucontext *ucontext = get_ocrdma_ucontext(context); - struct ocrdma_dev *dev = ucontext->dev; - unsigned long vm_page = vma->vm_pgoff << PAGE_SHIFT; - u64 unmapped_db = (u64) dev->nic_info.unmapped_db; - unsigned long len = (vma->vm_end - vma->vm_start); - int status = 0; - bool found; - - if (vma->vm_start & (PAGE_SIZE - 1)) - return -EINVAL; - found = ocrdma_search_mmap(ucontext, vma->vm_pgoff << PAGE_SHIFT, len); - if (!found) - return -EINVAL; - - if ((vm_page >= unmapped_db) && (vm_page <= (unmapped_db + - dev->nic_info.db_total_size)) && - (len <= dev->nic_info.db_page_size)) { - /* doorbell mapping */ - status = io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, - len, vma->vm_page_prot); - } else if (dev->nic_info.dpp_unmapped_len && - (vm_page >= (u64) dev->nic_info.dpp_unmapped_addr) && - (vm_page <= (u64) (dev->nic_info.dpp_unmapped_addr + - dev->nic_info.dpp_unmapped_len)) && - (len <= dev->nic_info.dpp_unmapped_len)) { - /* dpp area mapping */ - vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); - status = io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, - len, vma->vm_page_prot); - } else { - /* queue memory mapping */ - status = remap_pfn_range(vma, vma->vm_start, - vma->vm_pgoff, len, vma->vm_page_prot); - } - return status; -} - -static int ocrdma_copy_pd_uresp(struct ocrdma_pd *pd, - struct ib_ucontext *ib_ctx, - struct ib_udata *udata) -{ - int status; - u64 db_page_addr; - u64 dpp_page_addr = 0; - u32 db_page_size; - struct ocrdma_alloc_pd_uresp rsp; - struct ocrdma_ucontext *uctx = get_ocrdma_ucontext(ib_ctx); - - rsp.id = pd->id; - rsp.dpp_enabled = pd->dpp_enabled; - db_page_addr = pd->dev->nic_info.unmapped_db + - (pd->id * pd->dev->nic_info.db_page_size); - db_page_size = pd->dev->nic_info.db_page_size; - - status = ocrdma_add_mmap(uctx, db_page_addr, db_page_size); - if (status) - return status; - - if (pd->dpp_enabled) { - dpp_page_addr = pd->dev->nic_info.dpp_unmapped_addr + - (pd->id * OCRDMA_DPP_PAGE_SIZE); - status = ocrdma_add_mmap(uctx, dpp_page_addr, - OCRDMA_DPP_PAGE_SIZE); - if (status) - goto dpp_map_err; - rsp.dpp_page_addr_hi = upper_32_bits(dpp_page_addr); - rsp.dpp_page_addr_lo = dpp_page_addr; - } - - status = ib_copy_to_udata(udata, &rsp, sizeof(rsp)); - if (status) - goto ucopy_err; - - pd->uctx = uctx; - return 0; - -ucopy_err: - if (pd->dpp_enabled) - ocrdma_del_mmap(pd->uctx, dpp_page_addr, OCRDMA_DPP_PAGE_SIZE); -dpp_map_err: - ocrdma_del_mmap(pd->uctx, db_page_addr, db_page_size); - return status; -} - -struct ib_pd *ocrdma_alloc_pd(struct ib_device *ibdev, - struct ib_ucontext *context, - struct ib_udata *udata) -{ - struct ocrdma_dev *dev = get_ocrdma_dev(ibdev); - struct ocrdma_pd *pd; - int status; - - pd = kzalloc(sizeof(*pd), GFP_KERNEL); - if (!pd) - return ERR_PTR(-ENOMEM); - pd->dev = dev; - if (udata && context) { - pd->dpp_enabled = (dev->nic_info.dev_family == - OCRDMA_GEN2_FAMILY) ? true : false; - pd->num_dpp_qp = - pd->dpp_enabled ? OCRDMA_PD_MAX_DPP_ENABLED_QP : 0; - } - status = ocrdma_mbx_alloc_pd(dev, pd); - if (status) { - kfree(pd); - return ERR_PTR(status); - } - atomic_set(&pd->use_cnt, 0); - - if (udata && context) { - status = ocrdma_copy_pd_uresp(pd, context, udata); - if (status) - goto err; - } - return &pd->ibpd; - -err: - ocrdma_dealloc_pd(&pd->ibpd); - return ERR_PTR(status); -} - -int ocrdma_dealloc_pd(struct ib_pd *ibpd) -{ - struct ocrdma_pd *pd = get_ocrdma_pd(ibpd); - struct ocrdma_dev *dev = pd->dev; - int status; - u64 usr_db; - - if (atomic_read(&pd->use_cnt)) { - ocrdma_err("%s(%d) pd=0x%x is in use.\n", - __func__, dev->id, pd->id); - status = -EFAULT; - goto dealloc_err; - } - status = ocrdma_mbx_dealloc_pd(dev, pd); - if (pd->uctx) { - u64 dpp_db = dev->nic_info.dpp_unmapped_addr + - (pd->id * OCRDMA_DPP_PAGE_SIZE); - if (pd->dpp_enabled) - ocrdma_del_mmap(pd->uctx, dpp_db, OCRDMA_DPP_PAGE_SIZE); - usr_db = dev->nic_info.unmapped_db + - (pd->id * dev->nic_info.db_page_size); - ocrdma_del_mmap(pd->uctx, usr_db, dev->nic_info.db_page_size); - } - kfree(pd); -dealloc_err: - return status; -} - -static struct ocrdma_mr *ocrdma_alloc_lkey(struct ib_pd *ibpd, - int acc, u32 num_pbls, - u32 addr_check) -{ - int status; - struct ocrdma_mr *mr; - struct ocrdma_pd *pd = get_ocrdma_pd(ibpd); - struct ocrdma_dev *dev = pd->dev; - - if (acc & IB_ACCESS_REMOTE_WRITE && !(acc & IB_ACCESS_LOCAL_WRITE)) { - ocrdma_err("%s(%d) leaving err, invalid access rights\n", - __func__, dev->id); - return ERR_PTR(-EINVAL); - } - - mr = kzalloc(sizeof(*mr), GFP_KERNEL); - if (!mr) - return ERR_PTR(-ENOMEM); - mr->hwmr.dev = dev; - mr->hwmr.fr_mr = 0; - mr->hwmr.local_rd = 1; - mr->hwmr.remote_rd = (acc & IB_ACCESS_REMOTE_READ) ? 1 : 0; - mr->hwmr.remote_wr = (acc & IB_ACCESS_REMOTE_WRITE) ? 1 : 0; - mr->hwmr.local_wr = (acc & IB_ACCESS_LOCAL_WRITE) ? 1 : 0; - mr->hwmr.mw_bind = (acc & IB_ACCESS_MW_BIND) ? 1 : 0; - mr->hwmr.remote_atomic = (acc & IB_ACCESS_REMOTE_ATOMIC) ? 1 : 0; - mr->hwmr.num_pbls = num_pbls; - - status = ocrdma_mbx_alloc_lkey(dev, &mr->hwmr, pd->id, addr_check); - if (status) { - kfree(mr); - return ERR_PTR(-ENOMEM); - } - mr->pd = pd; - atomic_inc(&pd->use_cnt); - mr->ibmr.lkey = mr->hwmr.lkey; - if (mr->hwmr.remote_wr || mr->hwmr.remote_rd) - mr->ibmr.rkey = mr->hwmr.lkey; - return mr; -} - -struct ib_mr *ocrdma_get_dma_mr(struct ib_pd *ibpd, int acc) -{ - struct ocrdma_mr *mr; - - mr = ocrdma_alloc_lkey(ibpd, acc, 0, OCRDMA_ADDR_CHECK_DISABLE); - if (IS_ERR(mr)) - return ERR_CAST(mr); - - return &mr->ibmr; -} - -static void ocrdma_free_mr_pbl_tbl(struct ocrdma_dev *dev, - struct ocrdma_hw_mr *mr) -{ - struct pci_dev *pdev = dev->nic_info.pdev; - int i = 0; - - if (mr->pbl_table) { - for (i = 0; i < mr->num_pbls; i++) { - if (!mr->pbl_table[i].va) - continue; - dma_free_coherent(&pdev->dev, mr->pbl_size, - mr->pbl_table[i].va, - mr->pbl_table[i].pa); - } - kfree(mr->pbl_table); - mr->pbl_table = NULL; - } -} - -static int ocrdma_get_pbl_info(struct ocrdma_mr *mr, u32 num_pbes) -{ - u32 num_pbls = 0; - u32 idx = 0; - int status = 0; - u32 pbl_size; - - do { - pbl_size = OCRDMA_MIN_HPAGE_SIZE * (1 << idx); - if (pbl_size > MAX_OCRDMA_PBL_SIZE) { - status = -EFAULT; - break; - } - num_pbls = roundup(num_pbes, (pbl_size / sizeof(u64))); - num_pbls = num_pbls / (pbl_size / sizeof(u64)); - idx++; - } while (num_pbls >= mr->hwmr.dev->attr.max_num_mr_pbl); - - mr->hwmr.num_pbes = num_pbes; - mr->hwmr.num_pbls = num_pbls; - mr->hwmr.pbl_size = pbl_size; - return status; -} - -static int ocrdma_build_pbl_tbl(struct ocrdma_dev *dev, struct ocrdma_hw_mr *mr) -{ - int status = 0; - int i; - u32 dma_len = mr->pbl_size; - struct pci_dev *pdev = dev->nic_info.pdev; - void *va; - dma_addr_t pa; - - mr->pbl_table = kzalloc(sizeof(struct ocrdma_pbl) * - mr->num_pbls, GFP_KERNEL); - - if (!mr->pbl_table) - return -ENOMEM; - - for (i = 0; i < mr->num_pbls; i++) { - va = dma_alloc_coherent(&pdev->dev, dma_len, &pa, GFP_KERNEL); - if (!va) { - ocrdma_free_mr_pbl_tbl(dev, mr); - status = -ENOMEM; - break; - } - memset(va, 0, dma_len); - mr->pbl_table[i].va = va; - mr->pbl_table[i].pa = pa; - } - return status; -} - -static void build_user_pbes(struct ocrdma_dev *dev, struct ocrdma_mr *mr, - u32 num_pbes) -{ - struct ocrdma_pbe *pbe; - struct ib_umem_chunk *chunk; - struct ocrdma_pbl *pbl_tbl = mr->hwmr.pbl_table; - struct ib_umem *umem = mr->umem; - int i, shift, pg_cnt, pages, pbe_cnt, total_num_pbes = 0; - - if (!mr->hwmr.num_pbes) - return; - - pbe = (struct ocrdma_pbe *)pbl_tbl->va; - pbe_cnt = 0; - - shift = ilog2(umem->page_size); - - list_for_each_entry(chunk, &umem->chunk_list, list) { - /* get all the dma regions from the chunk. */ - for (i = 0; i < chunk->nmap; i++) { - pages = sg_dma_len(&chunk->page_list[i]) >> shift; - for (pg_cnt = 0; pg_cnt < pages; pg_cnt++) { - /* store the page address in pbe */ - pbe->pa_lo = - cpu_to_le32(sg_dma_address - (&chunk->page_list[i]) + - (umem->page_size * pg_cnt)); - pbe->pa_hi = - cpu_to_le32(upper_32_bits - ((sg_dma_address - (&chunk->page_list[i]) + - umem->page_size * pg_cnt))); - pbe_cnt += 1; - total_num_pbes += 1; - pbe++; - - /* if done building pbes, issue the mbx cmd. */ - if (total_num_pbes == num_pbes) - return; - - /* if the given pbl is full storing the pbes, - * move to next pbl. - */ - if (pbe_cnt == - (mr->hwmr.pbl_size / sizeof(u64))) { - pbl_tbl++; - pbe = (struct ocrdma_pbe *)pbl_tbl->va; - pbe_cnt = 0; - } - } - } - } -} - -struct ib_mr *ocrdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len, - u64 usr_addr, int acc, struct ib_udata *udata) -{ - int status = -ENOMEM; - struct ocrdma_dev *dev; - struct ocrdma_mr *mr; - struct ocrdma_pd *pd; - u32 num_pbes; - - pd = get_ocrdma_pd(ibpd); - dev = pd->dev; - - if (acc & IB_ACCESS_REMOTE_WRITE && !(acc & IB_ACCESS_LOCAL_WRITE)) - return ERR_PTR(-EINVAL); - - mr = kzalloc(sizeof(*mr), GFP_KERNEL); - if (!mr) - return ERR_PTR(status); - mr->hwmr.dev = dev; - mr->umem = ib_umem_get(ibpd->uobject->context, start, len, acc, 0); - if (IS_ERR(mr->umem)) { - status = -EFAULT; - goto umem_err; - } - num_pbes = ib_umem_page_count(mr->umem); - status = ocrdma_get_pbl_info(mr, num_pbes); - if (status) - goto umem_err; - - mr->hwmr.pbe_size = mr->umem->page_size; - mr->hwmr.fbo = mr->umem->offset; - mr->hwmr.va = usr_addr; - mr->hwmr.len = len; - mr->hwmr.remote_wr = (acc & IB_ACCESS_REMOTE_WRITE) ? 1 : 0; - mr->hwmr.remote_rd = (acc & IB_ACCESS_REMOTE_READ) ? 1 : 0; - mr->hwmr.local_wr = (acc & IB_ACCESS_LOCAL_WRITE) ? 1 : 0; - mr->hwmr.local_rd = 1; - mr->hwmr.remote_atomic = (acc & IB_ACCESS_REMOTE_ATOMIC) ? 1 : 0; - status = ocrdma_build_pbl_tbl(dev, &mr->hwmr); - if (status) - goto umem_err; - build_user_pbes(dev, mr, num_pbes); - status = ocrdma_reg_mr(dev, &mr->hwmr, pd->id, acc); - if (status) - goto mbx_err; - mr->pd = pd; - atomic_inc(&pd->use_cnt); - mr->ibmr.lkey = mr->hwmr.lkey; - if (mr->hwmr.remote_wr || mr->hwmr.remote_rd) - mr->ibmr.rkey = mr->hwmr.lkey; - - return &mr->ibmr; - -mbx_err: - ocrdma_free_mr_pbl_tbl(dev, &mr->hwmr); -umem_err: - kfree(mr); - return ERR_PTR(status); -} - -int ocrdma_dereg_mr(struct ib_mr *ib_mr) -{ - struct ocrdma_mr *mr = get_ocrdma_mr(ib_mr); - struct ocrdma_dev *dev = mr->hwmr.dev; - int status; - - status = ocrdma_mbx_dealloc_lkey(dev, mr->hwmr.fr_mr, mr->hwmr.lkey); - - if (mr->hwmr.fr_mr == 0) - ocrdma_free_mr_pbl_tbl(dev, &mr->hwmr); - - atomic_dec(&mr->pd->use_cnt); - /* it could be user registered memory. */ - if (mr->umem) - ib_umem_release(mr->umem); - kfree(mr); - return status; -} - -static int ocrdma_copy_cq_uresp(struct ocrdma_cq *cq, struct ib_udata *udata, - struct ib_ucontext *ib_ctx) -{ - int status; - struct ocrdma_ucontext *uctx; - struct ocrdma_create_cq_uresp uresp; - - uresp.cq_id = cq->id; - uresp.page_size = cq->len; - uresp.num_pages = 1; - uresp.max_hw_cqe = cq->max_hw_cqe; - uresp.page_addr[0] = cq->pa; - uresp.db_page_addr = cq->dev->nic_info.unmapped_db; - uresp.db_page_size = cq->dev->nic_info.db_page_size; - uresp.phase_change = cq->phase_change ? 1 : 0; - status = ib_copy_to_udata(udata, &uresp, sizeof(uresp)); - if (status) { - ocrdma_err("%s(%d) copy error cqid=0x%x.\n", - __func__, cq->dev->id, cq->id); - goto err; - } - uctx = get_ocrdma_ucontext(ib_ctx); - status = ocrdma_add_mmap(uctx, uresp.db_page_addr, uresp.db_page_size); - if (status) - goto err; - status = ocrdma_add_mmap(uctx, uresp.page_addr[0], uresp.page_size); - if (status) { - ocrdma_del_mmap(uctx, uresp.db_page_addr, uresp.db_page_size); - goto err; - } - cq->ucontext = uctx; -err: - return status; -} - -struct ib_cq *ocrdma_create_cq(struct ib_device *ibdev, int entries, int vector, - struct ib_ucontext *ib_ctx, - struct ib_udata *udata) -{ - struct ocrdma_cq *cq; - struct ocrdma_dev *dev = get_ocrdma_dev(ibdev); - int status; - struct ocrdma_create_cq_ureq ureq; - - if (udata) { - if (ib_copy_from_udata(&ureq, udata, sizeof(ureq))) - return ERR_PTR(-EFAULT); - } else - ureq.dpp_cq = 0; - cq = kzalloc(sizeof(*cq), GFP_KERNEL); - if (!cq) - return ERR_PTR(-ENOMEM); - - spin_lock_init(&cq->cq_lock); - spin_lock_init(&cq->comp_handler_lock); - atomic_set(&cq->use_cnt, 0); - INIT_LIST_HEAD(&cq->sq_head); - INIT_LIST_HEAD(&cq->rq_head); - cq->dev = dev; - - status = ocrdma_mbx_create_cq(dev, cq, entries, ureq.dpp_cq); - if (status) { - kfree(cq); - return ERR_PTR(status); - } - if (ib_ctx) { - status = ocrdma_copy_cq_uresp(cq, udata, ib_ctx); - if (status) - goto ctx_err; - } - cq->phase = OCRDMA_CQE_VALID; - cq->arm_needed = true; - dev->cq_tbl[cq->id] = cq; - - return &cq->ibcq; - -ctx_err: - ocrdma_mbx_destroy_cq(dev, cq); - kfree(cq); - return ERR_PTR(status); -} - -int ocrdma_resize_cq(struct ib_cq *ibcq, int new_cnt, - struct ib_udata *udata) -{ - int status = 0; - struct ocrdma_cq *cq = get_ocrdma_cq(ibcq); - - if (new_cnt < 1 || new_cnt > cq->max_hw_cqe) { - status = -EINVAL; - return status; - } - ibcq->cqe = new_cnt; - return status; -} - -int ocrdma_destroy_cq(struct ib_cq *ibcq) -{ - int status; - struct ocrdma_cq *cq = get_ocrdma_cq(ibcq); - struct ocrdma_dev *dev = cq->dev; - - if (atomic_read(&cq->use_cnt)) - return -EINVAL; - - status = ocrdma_mbx_destroy_cq(dev, cq); - - if (cq->ucontext) { - ocrdma_del_mmap(cq->ucontext, (u64) cq->pa, cq->len); - ocrdma_del_mmap(cq->ucontext, dev->nic_info.unmapped_db, - dev->nic_info.db_page_size); - } - dev->cq_tbl[cq->id] = NULL; - - kfree(cq); - return status; -} - -static int ocrdma_add_qpn_map(struct ocrdma_dev *dev, struct ocrdma_qp *qp) -{ - int status = -EINVAL; - - if (qp->id < OCRDMA_MAX_QP && dev->qp_tbl[qp->id] == NULL) { - dev->qp_tbl[qp->id] = qp; - status = 0; - } - return status; -} - -static void ocrdma_del_qpn_map(struct ocrdma_dev *dev, struct ocrdma_qp *qp) -{ - dev->qp_tbl[qp->id] = NULL; -} - -static int ocrdma_check_qp_params(struct ib_pd *ibpd, struct ocrdma_dev *dev, - struct ib_qp_init_attr *attrs) -{ - if (attrs->qp_type != IB_QPT_GSI && - attrs->qp_type != IB_QPT_RC && - attrs->qp_type != IB_QPT_UD) { - ocrdma_err("%s(%d) unsupported qp type=0x%x requested\n", - __func__, dev->id, attrs->qp_type); - return -EINVAL; - } - if (attrs->cap.max_send_wr > dev->attr.max_wqe) { - ocrdma_err("%s(%d) unsupported send_wr=0x%x requested\n", - __func__, dev->id, attrs->cap.max_send_wr); - ocrdma_err("%s(%d) supported send_wr=0x%x\n", - __func__, dev->id, dev->attr.max_wqe); - return -EINVAL; - } - if (!attrs->srq && (attrs->cap.max_recv_wr > dev->attr.max_rqe)) { - ocrdma_err("%s(%d) unsupported recv_wr=0x%x requested\n", - __func__, dev->id, attrs->cap.max_recv_wr); - ocrdma_err("%s(%d) supported recv_wr=0x%x\n", - __func__, dev->id, dev->attr.max_rqe); - return -EINVAL; - } - if (attrs->cap.max_inline_data > dev->attr.max_inline_data) { - ocrdma_err("%s(%d) unsupported inline data size=0x%x" - " requested\n", __func__, dev->id, - attrs->cap.max_inline_data); - ocrdma_err("%s(%d) supported inline data size=0x%x\n", - __func__, dev->id, dev->attr.max_inline_data); - return -EINVAL; - } - if (attrs->cap.max_send_sge > dev->attr.max_send_sge) { - ocrdma_err("%s(%d) unsupported send_sge=0x%x requested\n", - __func__, dev->id, attrs->cap.max_send_sge); - ocrdma_err("%s(%d) supported send_sge=0x%x\n", - __func__, dev->id, dev->attr.max_send_sge); - return -EINVAL; - } - if (attrs->cap.max_recv_sge > dev->attr.max_recv_sge) { - ocrdma_err("%s(%d) unsupported recv_sge=0x%x requested\n", - __func__, dev->id, attrs->cap.max_recv_sge); - ocrdma_err("%s(%d) supported recv_sge=0x%x\n", - __func__, dev->id, dev->attr.max_recv_sge); - return -EINVAL; - } - /* unprivileged user space cannot create special QP */ - if (ibpd->uobject && attrs->qp_type == IB_QPT_GSI) { - ocrdma_err - ("%s(%d) Userspace can't create special QPs of type=0x%x\n", - __func__, dev->id, attrs->qp_type); - return -EINVAL; - } - /* allow creating only one GSI type of QP */ - if (attrs->qp_type == IB_QPT_GSI && dev->gsi_qp_created) { - ocrdma_err("%s(%d) GSI special QPs already created.\n", - __func__, dev->id); - return -EINVAL; - } - /* verify consumer QPs are not trying to use GSI QP's CQ */ - if ((attrs->qp_type != IB_QPT_GSI) && (dev->gsi_qp_created)) { - if ((dev->gsi_sqcq == get_ocrdma_cq(attrs->send_cq)) || - (dev->gsi_sqcq == get_ocrdma_cq(attrs->send_cq))) { - ocrdma_err("%s(%d) Consumer QP cannot use GSI CQs.\n", - __func__, dev->id); - return -EINVAL; - } - } - return 0; -} - -static int ocrdma_copy_qp_uresp(struct ocrdma_qp *qp, - struct ib_udata *udata, int dpp_offset, - int dpp_credit_lmt, int srq) -{ - int status = 0; - u64 usr_db; - struct ocrdma_create_qp_uresp uresp; - struct ocrdma_dev *dev = qp->dev; - struct ocrdma_pd *pd = qp->pd; - - memset(&uresp, 0, sizeof(uresp)); - usr_db = dev->nic_info.unmapped_db + - (pd->id * dev->nic_info.db_page_size); - uresp.qp_id = qp->id; - uresp.sq_dbid = qp->sq.dbid; - uresp.num_sq_pages = 1; - uresp.sq_page_size = qp->sq.len; - uresp.sq_page_addr[0] = qp->sq.pa; - uresp.num_wqe_allocated = qp->sq.max_cnt; - if (!srq) { - uresp.rq_dbid = qp->rq.dbid; - uresp.num_rq_pages = 1; - uresp.rq_page_size = qp->rq.len; - uresp.rq_page_addr[0] = qp->rq.pa; - uresp.num_rqe_allocated = qp->rq.max_cnt; - } - uresp.db_page_addr = usr_db; - uresp.db_page_size = dev->nic_info.db_page_size; - if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { - uresp.db_sq_offset = OCRDMA_DB_GEN2_SQ_OFFSET; - uresp.db_rq_offset = ((qp->id & 0xFFFF) < 128) ? - OCRDMA_DB_GEN2_RQ1_OFFSET : OCRDMA_DB_GEN2_RQ2_OFFSET; - uresp.db_shift = (qp->id < 128) ? 24 : 16; - } else { - uresp.db_sq_offset = OCRDMA_DB_SQ_OFFSET; - uresp.db_rq_offset = OCRDMA_DB_RQ_OFFSET; - uresp.db_shift = 16; - } - uresp.free_wqe_delta = qp->sq.free_delta; - uresp.free_rqe_delta = qp->rq.free_delta; - - if (qp->dpp_enabled) { - uresp.dpp_credit = dpp_credit_lmt; - uresp.dpp_offset = dpp_offset; - } - status = ib_copy_to_udata(udata, &uresp, sizeof(uresp)); - if (status) { - ocrdma_err("%s(%d) user copy error.\n", __func__, dev->id); - goto err; - } - status = ocrdma_add_mmap(pd->uctx, uresp.sq_page_addr[0], - uresp.sq_page_size); - if (status) - goto err; - - if (!srq) { - status = ocrdma_add_mmap(pd->uctx, uresp.rq_page_addr[0], - uresp.rq_page_size); - if (status) - goto rq_map_err; - } - return status; -rq_map_err: - ocrdma_del_mmap(pd->uctx, uresp.sq_page_addr[0], uresp.sq_page_size); -err: - return status; -} - -static void ocrdma_set_qp_db(struct ocrdma_dev *dev, struct ocrdma_qp *qp, - struct ocrdma_pd *pd) -{ - if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { - qp->sq_db = dev->nic_info.db + - (pd->id * dev->nic_info.db_page_size) + - OCRDMA_DB_GEN2_SQ_OFFSET; - qp->rq_db = dev->nic_info.db + - (pd->id * dev->nic_info.db_page_size) + - ((qp->id < 128) ? - OCRDMA_DB_GEN2_RQ1_OFFSET : OCRDMA_DB_GEN2_RQ2_OFFSET); - } else { - qp->sq_db = dev->nic_info.db + - (pd->id * dev->nic_info.db_page_size) + - OCRDMA_DB_SQ_OFFSET; - qp->rq_db = dev->nic_info.db + - (pd->id * dev->nic_info.db_page_size) + - OCRDMA_DB_RQ_OFFSET; - } -} - -static int ocrdma_alloc_wr_id_tbl(struct ocrdma_qp *qp) -{ - qp->wqe_wr_id_tbl = - kzalloc(sizeof(*(qp->wqe_wr_id_tbl)) * qp->sq.max_cnt, - GFP_KERNEL); - if (qp->wqe_wr_id_tbl == NULL) - return -ENOMEM; - qp->rqe_wr_id_tbl = - kzalloc(sizeof(u64) * qp->rq.max_cnt, GFP_KERNEL); - if (qp->rqe_wr_id_tbl == NULL) - return -ENOMEM; - - return 0; -} - -static void ocrdma_set_qp_init_params(struct ocrdma_qp *qp, - struct ocrdma_pd *pd, - struct ib_qp_init_attr *attrs) -{ - qp->pd = pd; - spin_lock_init(&qp->q_lock); - INIT_LIST_HEAD(&qp->sq_entry); - INIT_LIST_HEAD(&qp->rq_entry); - - qp->qp_type = attrs->qp_type; - qp->cap_flags = OCRDMA_QP_INB_RD | OCRDMA_QP_INB_WR; - qp->max_inline_data = attrs->cap.max_inline_data; - qp->sq.max_sges = attrs->cap.max_send_sge; - qp->rq.max_sges = attrs->cap.max_recv_sge; - qp->state = OCRDMA_QPS_RST; -} - -static void ocrdma_set_qp_use_cnt(struct ocrdma_qp *qp, struct ocrdma_pd *pd) -{ - atomic_inc(&pd->use_cnt); - atomic_inc(&qp->sq_cq->use_cnt); - atomic_inc(&qp->rq_cq->use_cnt); - if (qp->srq) - atomic_inc(&qp->srq->use_cnt); - qp->ibqp.qp_num = qp->id; -} - -static void ocrdma_store_gsi_qp_cq(struct ocrdma_dev *dev, - struct ib_qp_init_attr *attrs) -{ - if (attrs->qp_type == IB_QPT_GSI) { - dev->gsi_qp_created = 1; - dev->gsi_sqcq = get_ocrdma_cq(attrs->send_cq); - dev->gsi_rqcq = get_ocrdma_cq(attrs->recv_cq); - } -} - -struct ib_qp *ocrdma_create_qp(struct ib_pd *ibpd, - struct ib_qp_init_attr *attrs, - struct ib_udata *udata) -{ - int status; - struct ocrdma_pd *pd = get_ocrdma_pd(ibpd); - struct ocrdma_qp *qp; - struct ocrdma_dev *dev = pd->dev; - struct ocrdma_create_qp_ureq ureq; - u16 dpp_credit_lmt, dpp_offset; - - status = ocrdma_check_qp_params(ibpd, dev, attrs); - if (status) - goto gen_err; - - memset(&ureq, 0, sizeof(ureq)); - if (udata) { - if (ib_copy_from_udata(&ureq, udata, sizeof(ureq))) - return ERR_PTR(-EFAULT); - } - qp = kzalloc(sizeof(*qp), GFP_KERNEL); - if (!qp) { - status = -ENOMEM; - goto gen_err; - } - qp->dev = dev; - ocrdma_set_qp_init_params(qp, pd, attrs); - - mutex_lock(&dev->dev_lock); - status = ocrdma_mbx_create_qp(qp, attrs, ureq.enable_dpp_cq, - ureq.dpp_cq_id, - &dpp_offset, &dpp_credit_lmt); - if (status) - goto mbx_err; - - /* user space QP's wr_id table are managed in library */ - if (udata == NULL) { - qp->cap_flags |= (OCRDMA_QP_MW_BIND | OCRDMA_QP_LKEY0 | - OCRDMA_QP_FAST_REG); - status = ocrdma_alloc_wr_id_tbl(qp); - if (status) - goto map_err; - } - - status = ocrdma_add_qpn_map(dev, qp); - if (status) - goto map_err; - ocrdma_set_qp_db(dev, qp, pd); - if (udata) { - status = ocrdma_copy_qp_uresp(qp, udata, dpp_offset, - dpp_credit_lmt, - (attrs->srq != NULL)); - if (status) - goto cpy_err; - } - ocrdma_store_gsi_qp_cq(dev, attrs); - ocrdma_set_qp_use_cnt(qp, pd); - mutex_unlock(&dev->dev_lock); - return &qp->ibqp; - -cpy_err: - ocrdma_del_qpn_map(dev, qp); -map_err: - ocrdma_mbx_destroy_qp(dev, qp); -mbx_err: - mutex_unlock(&dev->dev_lock); - kfree(qp->wqe_wr_id_tbl); - kfree(qp->rqe_wr_id_tbl); - kfree(qp); - ocrdma_err("%s(%d) error=%d\n", __func__, dev->id, status); -gen_err: - return ERR_PTR(status); -} - -int _ocrdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, - int attr_mask) -{ - int status = 0; - struct ocrdma_qp *qp; - struct ocrdma_dev *dev; - enum ib_qp_state old_qps; - - qp = get_ocrdma_qp(ibqp); - dev = qp->dev; - if (attr_mask & IB_QP_STATE) - status = ocrdma_qp_state_machine(qp, attr->qp_state, &old_qps); - /* if new and previous states are same hw doesn't need to - * know about it. - */ - if (status < 0) - return status; - status = ocrdma_mbx_modify_qp(dev, qp, attr, attr_mask, old_qps); - return status; -} - -int ocrdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, - int attr_mask, struct ib_udata *udata) -{ - unsigned long flags; - int status = -EINVAL; - struct ocrdma_qp *qp; - struct ocrdma_dev *dev; - enum ib_qp_state old_qps, new_qps; - - qp = get_ocrdma_qp(ibqp); - dev = qp->dev; - - /* syncronize with multiple context trying to change, retrive qps */ - mutex_lock(&dev->dev_lock); - /* syncronize with wqe, rqe posting and cqe processing contexts */ - spin_lock_irqsave(&qp->q_lock, flags); - old_qps = get_ibqp_state(qp->state); - if (attr_mask & IB_QP_STATE) - new_qps = attr->qp_state; - else - new_qps = old_qps; - spin_unlock_irqrestore(&qp->q_lock, flags); - - if (!ib_modify_qp_is_ok(old_qps, new_qps, ibqp->qp_type, attr_mask)) { - ocrdma_err("%s(%d) invalid attribute mask=0x%x specified for " - "qpn=0x%x of type=0x%x old_qps=0x%x, new_qps=0x%x\n", - __func__, dev->id, attr_mask, qp->id, ibqp->qp_type, - old_qps, new_qps); - goto param_err; - } - - status = _ocrdma_modify_qp(ibqp, attr, attr_mask); - if (status > 0) - status = 0; -param_err: - mutex_unlock(&dev->dev_lock); - return status; -} - -static enum ib_mtu ocrdma_mtu_int_to_enum(u16 mtu) -{ - switch (mtu) { - case 256: - return IB_MTU_256; - case 512: - return IB_MTU_512; - case 1024: - return IB_MTU_1024; - case 2048: - return IB_MTU_2048; - case 4096: - return IB_MTU_4096; - default: - return IB_MTU_1024; - } -} - -static int ocrdma_to_ib_qp_acc_flags(int qp_cap_flags) -{ - int ib_qp_acc_flags = 0; - - if (qp_cap_flags & OCRDMA_QP_INB_WR) - ib_qp_acc_flags |= IB_ACCESS_REMOTE_WRITE; - if (qp_cap_flags & OCRDMA_QP_INB_RD) - ib_qp_acc_flags |= IB_ACCESS_LOCAL_WRITE; - return ib_qp_acc_flags; -} - -int ocrdma_query_qp(struct ib_qp *ibqp, - struct ib_qp_attr *qp_attr, - int attr_mask, struct ib_qp_init_attr *qp_init_attr) -{ - int status; - u32 qp_state; - struct ocrdma_qp_params params; - struct ocrdma_qp *qp = get_ocrdma_qp(ibqp); - struct ocrdma_dev *dev = qp->dev; - - memset(¶ms, 0, sizeof(params)); - mutex_lock(&dev->dev_lock); - status = ocrdma_mbx_query_qp(dev, qp, ¶ms); - mutex_unlock(&dev->dev_lock); - if (status) - goto mbx_err; - qp_attr->qp_state = get_ibqp_state(IB_QPS_INIT); - qp_attr->cur_qp_state = get_ibqp_state(IB_QPS_INIT); - qp_attr->path_mtu = - ocrdma_mtu_int_to_enum(params.path_mtu_pkey_indx & - OCRDMA_QP_PARAMS_PATH_MTU_MASK) >> - OCRDMA_QP_PARAMS_PATH_MTU_SHIFT; - qp_attr->path_mig_state = IB_MIG_MIGRATED; - qp_attr->rq_psn = params.hop_lmt_rq_psn & OCRDMA_QP_PARAMS_RQ_PSN_MASK; - qp_attr->sq_psn = params.tclass_sq_psn & OCRDMA_QP_PARAMS_SQ_PSN_MASK; - qp_attr->dest_qp_num = - params.ack_to_rnr_rtc_dest_qpn & OCRDMA_QP_PARAMS_DEST_QPN_MASK; - - qp_attr->qp_access_flags = ocrdma_to_ib_qp_acc_flags(qp->cap_flags); - qp_attr->cap.max_send_wr = qp->sq.max_cnt - 1; - qp_attr->cap.max_recv_wr = qp->rq.max_cnt - 1; - qp_attr->cap.max_send_sge = qp->sq.max_sges; - qp_attr->cap.max_recv_sge = qp->rq.max_sges; - qp_attr->cap.max_inline_data = dev->attr.max_inline_data; - qp_init_attr->cap = qp_attr->cap; - memcpy(&qp_attr->ah_attr.grh.dgid, ¶ms.dgid[0], - sizeof(params.dgid)); - qp_attr->ah_attr.grh.flow_label = params.rnt_rc_sl_fl & - OCRDMA_QP_PARAMS_FLOW_LABEL_MASK; - qp_attr->ah_attr.grh.sgid_index = qp->sgid_idx; - qp_attr->ah_attr.grh.hop_limit = (params.hop_lmt_rq_psn & - OCRDMA_QP_PARAMS_HOP_LMT_MASK) >> - OCRDMA_QP_PARAMS_HOP_LMT_SHIFT; - qp_attr->ah_attr.grh.traffic_class = (params.tclass_sq_psn & - OCRDMA_QP_PARAMS_SQ_PSN_MASK) >> - OCRDMA_QP_PARAMS_TCLASS_SHIFT; - - qp_attr->ah_attr.ah_flags = IB_AH_GRH; - qp_attr->ah_attr.port_num = 1; - qp_attr->ah_attr.sl = (params.rnt_rc_sl_fl & - OCRDMA_QP_PARAMS_SL_MASK) >> - OCRDMA_QP_PARAMS_SL_SHIFT; - qp_attr->timeout = (params.ack_to_rnr_rtc_dest_qpn & - OCRDMA_QP_PARAMS_ACK_TIMEOUT_MASK) >> - OCRDMA_QP_PARAMS_ACK_TIMEOUT_SHIFT; - qp_attr->rnr_retry = (params.ack_to_rnr_rtc_dest_qpn & - OCRDMA_QP_PARAMS_RNR_RETRY_CNT_MASK) >> - OCRDMA_QP_PARAMS_RNR_RETRY_CNT_SHIFT; - qp_attr->retry_cnt = - (params.rnt_rc_sl_fl & OCRDMA_QP_PARAMS_RETRY_CNT_MASK) >> - OCRDMA_QP_PARAMS_RETRY_CNT_SHIFT; - qp_attr->min_rnr_timer = 0; - qp_attr->pkey_index = 0; - qp_attr->port_num = 1; - qp_attr->ah_attr.src_path_bits = 0; - qp_attr->ah_attr.static_rate = 0; - qp_attr->alt_pkey_index = 0; - qp_attr->alt_port_num = 0; - qp_attr->alt_timeout = 0; - memset(&qp_attr->alt_ah_attr, 0, sizeof(qp_attr->alt_ah_attr)); - qp_state = (params.max_sge_recv_flags & OCRDMA_QP_PARAMS_STATE_MASK) >> - OCRDMA_QP_PARAMS_STATE_SHIFT; - qp_attr->sq_draining = (qp_state == OCRDMA_QPS_SQ_DRAINING) ? 1 : 0; - qp_attr->max_dest_rd_atomic = - params.max_ord_ird >> OCRDMA_QP_PARAMS_MAX_ORD_SHIFT; - qp_attr->max_rd_atomic = - params.max_ord_ird & OCRDMA_QP_PARAMS_MAX_IRD_MASK; - qp_attr->en_sqd_async_notify = (params.max_sge_recv_flags & - OCRDMA_QP_PARAMS_FLAGS_SQD_ASYNC) ? 1 : 0; -mbx_err: - return status; -} - -static void ocrdma_srq_toggle_bit(struct ocrdma_srq *srq, int idx) -{ - int i = idx / 32; - unsigned int mask = (1 << (idx % 32)); - - if (srq->idx_bit_fields[i] & mask) - srq->idx_bit_fields[i] &= ~mask; - else - srq->idx_bit_fields[i] |= mask; -} - -static int ocrdma_hwq_free_cnt(struct ocrdma_qp_hwq_info *q) -{ - int free_cnt; - if (q->head >= q->tail) - free_cnt = (q->max_cnt - q->head) + q->tail; - else - free_cnt = q->tail - q->head; - if (q->free_delta) - free_cnt -= q->free_delta; - return free_cnt; -} - -static int is_hw_sq_empty(struct ocrdma_qp *qp) -{ - return (qp->sq.tail == qp->sq.head && - ocrdma_hwq_free_cnt(&qp->sq) ? 1 : 0); -} - -static int is_hw_rq_empty(struct ocrdma_qp *qp) -{ - return (qp->rq.tail == qp->rq.head) ? 1 : 0; -} - -static void *ocrdma_hwq_head(struct ocrdma_qp_hwq_info *q) -{ - return q->va + (q->head * q->entry_size); -} - -static void *ocrdma_hwq_head_from_idx(struct ocrdma_qp_hwq_info *q, - u32 idx) -{ - return q->va + (idx * q->entry_size); -} - -static void ocrdma_hwq_inc_head(struct ocrdma_qp_hwq_info *q) -{ - q->head = (q->head + 1) & q->max_wqe_idx; -} - -static void ocrdma_hwq_inc_tail(struct ocrdma_qp_hwq_info *q) -{ - q->tail = (q->tail + 1) & q->max_wqe_idx; -} - -/* discard the cqe for a given QP */ -static void ocrdma_discard_cqes(struct ocrdma_qp *qp, struct ocrdma_cq *cq) -{ - unsigned long cq_flags; - unsigned long flags; - int discard_cnt = 0; - u32 cur_getp, stop_getp; - struct ocrdma_cqe *cqe; - u32 qpn = 0; - - spin_lock_irqsave(&cq->cq_lock, cq_flags); - - /* traverse through the CQEs in the hw CQ, - * find the matching CQE for a given qp, - * mark the matching one discarded by clearing qpn. - * ring the doorbell in the poll_cq() as - * we don't complete out of order cqe. - */ - - cur_getp = cq->getp; - /* find upto when do we reap the cq. */ - stop_getp = cur_getp; - do { - if (is_hw_sq_empty(qp) && (!qp->srq && is_hw_rq_empty(qp))) - break; - - cqe = cq->va + cur_getp; - /* if (a) done reaping whole hw cq, or - * (b) qp_xq becomes empty. - * then exit - */ - qpn = cqe->cmn.qpn & OCRDMA_CQE_QPN_MASK; - /* if previously discarded cqe found, skip that too. */ - /* check for matching qp */ - if (qpn == 0 || qpn != qp->id) - goto skip_cqe; - - /* mark cqe discarded so that it is not picked up later - * in the poll_cq(). - */ - discard_cnt += 1; - cqe->cmn.qpn = 0; - if (is_cqe_for_sq(cqe)) - ocrdma_hwq_inc_tail(&qp->sq); - else { - if (qp->srq) { - spin_lock_irqsave(&qp->srq->q_lock, flags); - ocrdma_hwq_inc_tail(&qp->srq->rq); - ocrdma_srq_toggle_bit(qp->srq, cur_getp); - spin_unlock_irqrestore(&qp->srq->q_lock, flags); - - } else - ocrdma_hwq_inc_tail(&qp->rq); - } -skip_cqe: - cur_getp = (cur_getp + 1) % cq->max_hw_cqe; - } while (cur_getp != stop_getp); - spin_unlock_irqrestore(&cq->cq_lock, cq_flags); -} - -static void ocrdma_del_flush_qp(struct ocrdma_qp *qp) -{ - int found = false; - unsigned long flags; - struct ocrdma_dev *dev = qp->dev; - /* sync with any active CQ poll */ - - spin_lock_irqsave(&dev->flush_q_lock, flags); - found = ocrdma_is_qp_in_sq_flushlist(qp->sq_cq, qp); - if (found) - list_del(&qp->sq_entry); - if (!qp->srq) { - found = ocrdma_is_qp_in_rq_flushlist(qp->rq_cq, qp); - if (found) - list_del(&qp->rq_entry); - } - spin_unlock_irqrestore(&dev->flush_q_lock, flags); -} - -int ocrdma_destroy_qp(struct ib_qp *ibqp) -{ - int status; - struct ocrdma_pd *pd; - struct ocrdma_qp *qp; - struct ocrdma_dev *dev; - struct ib_qp_attr attrs; - int attr_mask = IB_QP_STATE; - unsigned long flags; - - qp = get_ocrdma_qp(ibqp); - dev = qp->dev; - - attrs.qp_state = IB_QPS_ERR; - pd = qp->pd; - - /* change the QP state to ERROR */ - _ocrdma_modify_qp(ibqp, &attrs, attr_mask); - - /* ensure that CQEs for newly created QP (whose id may be same with - * one which just getting destroyed are same), dont get - * discarded until the old CQEs are discarded. - */ - mutex_lock(&dev->dev_lock); - status = ocrdma_mbx_destroy_qp(dev, qp); - - /* - * acquire CQ lock while destroy is in progress, in order to - * protect against proessing in-flight CQEs for this QP. - */ - spin_lock_irqsave(&qp->sq_cq->cq_lock, flags); - if (qp->rq_cq && (qp->rq_cq != qp->sq_cq)) - spin_lock(&qp->rq_cq->cq_lock); - - ocrdma_del_qpn_map(dev, qp); - - if (qp->rq_cq && (qp->rq_cq != qp->sq_cq)) - spin_unlock(&qp->rq_cq->cq_lock); - spin_unlock_irqrestore(&qp->sq_cq->cq_lock, flags); - - if (!pd->uctx) { - ocrdma_discard_cqes(qp, qp->sq_cq); - ocrdma_discard_cqes(qp, qp->rq_cq); - } - mutex_unlock(&dev->dev_lock); - - if (pd->uctx) { - ocrdma_del_mmap(pd->uctx, (u64) qp->sq.pa, qp->sq.len); - if (!qp->srq) - ocrdma_del_mmap(pd->uctx, (u64) qp->rq.pa, qp->rq.len); - } - - ocrdma_del_flush_qp(qp); - - atomic_dec(&qp->pd->use_cnt); - atomic_dec(&qp->sq_cq->use_cnt); - atomic_dec(&qp->rq_cq->use_cnt); - if (qp->srq) - atomic_dec(&qp->srq->use_cnt); - kfree(qp->wqe_wr_id_tbl); - kfree(qp->rqe_wr_id_tbl); - kfree(qp); - return status; -} - -static int ocrdma_copy_srq_uresp(struct ocrdma_srq *srq, struct ib_udata *udata) -{ - int status; - struct ocrdma_create_srq_uresp uresp; - - uresp.rq_dbid = srq->rq.dbid; - uresp.num_rq_pages = 1; - uresp.rq_page_addr[0] = srq->rq.pa; - uresp.rq_page_size = srq->rq.len; - uresp.db_page_addr = srq->dev->nic_info.unmapped_db + - (srq->pd->id * srq->dev->nic_info.db_page_size); - uresp.db_page_size = srq->dev->nic_info.db_page_size; - uresp.num_rqe_allocated = srq->rq.max_cnt; - uresp.free_rqe_delta = 1; - if (srq->dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { - uresp.db_rq_offset = OCRDMA_DB_GEN2_RQ1_OFFSET; - uresp.db_shift = 24; - } else { - uresp.db_rq_offset = OCRDMA_DB_RQ_OFFSET; - uresp.db_shift = 16; - } - - status = ib_copy_to_udata(udata, &uresp, sizeof(uresp)); - if (status) - return status; - status = ocrdma_add_mmap(srq->pd->uctx, uresp.rq_page_addr[0], - uresp.rq_page_size); - if (status) - return status; - return status; -} - -struct ib_srq *ocrdma_create_srq(struct ib_pd *ibpd, - struct ib_srq_init_attr *init_attr, - struct ib_udata *udata) -{ - int status = -ENOMEM; - struct ocrdma_pd *pd = get_ocrdma_pd(ibpd); - struct ocrdma_dev *dev = pd->dev; - struct ocrdma_srq *srq; - - if (init_attr->attr.max_sge > dev->attr.max_recv_sge) - return ERR_PTR(-EINVAL); - if (init_attr->attr.max_wr > dev->attr.max_rqe) - return ERR_PTR(-EINVAL); - - srq = kzalloc(sizeof(*srq), GFP_KERNEL); - if (!srq) - return ERR_PTR(status); - - spin_lock_init(&srq->q_lock); - srq->dev = dev; - srq->pd = pd; - srq->db = dev->nic_info.db + (pd->id * dev->nic_info.db_page_size); - status = ocrdma_mbx_create_srq(srq, init_attr, pd); - if (status) - goto err; - - if (udata == NULL) { - srq->rqe_wr_id_tbl = kzalloc(sizeof(u64) * srq->rq.max_cnt, - GFP_KERNEL); - if (srq->rqe_wr_id_tbl == NULL) - goto arm_err; - - srq->bit_fields_len = (srq->rq.max_cnt / 32) + - (srq->rq.max_cnt % 32 ? 1 : 0); - srq->idx_bit_fields = - kmalloc(srq->bit_fields_len * sizeof(u32), GFP_KERNEL); - if (srq->idx_bit_fields == NULL) - goto arm_err; - memset(srq->idx_bit_fields, 0xff, - srq->bit_fields_len * sizeof(u32)); - } - - if (init_attr->attr.srq_limit) { - status = ocrdma_mbx_modify_srq(srq, &init_attr->attr); - if (status) - goto arm_err; - } - - atomic_set(&srq->use_cnt, 0); - if (udata) { - status = ocrdma_copy_srq_uresp(srq, udata); - if (status) - goto arm_err; - } - - atomic_inc(&pd->use_cnt); - return &srq->ibsrq; - -arm_err: - ocrdma_mbx_destroy_srq(dev, srq); -err: - kfree(srq->rqe_wr_id_tbl); - kfree(srq->idx_bit_fields); - kfree(srq); - return ERR_PTR(status); -} - -int ocrdma_modify_srq(struct ib_srq *ibsrq, - struct ib_srq_attr *srq_attr, - enum ib_srq_attr_mask srq_attr_mask, - struct ib_udata *udata) -{ - int status = 0; - struct ocrdma_srq *srq; - - srq = get_ocrdma_srq(ibsrq); - if (srq_attr_mask & IB_SRQ_MAX_WR) - status = -EINVAL; - else - status = ocrdma_mbx_modify_srq(srq, srq_attr); - return status; -} - -int ocrdma_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr) -{ - int status; - struct ocrdma_srq *srq; - - srq = get_ocrdma_srq(ibsrq); - status = ocrdma_mbx_query_srq(srq, srq_attr); - return status; -} - -int ocrdma_destroy_srq(struct ib_srq *ibsrq) -{ - int status; - struct ocrdma_srq *srq; - struct ocrdma_dev *dev; - - srq = get_ocrdma_srq(ibsrq); - dev = srq->dev; - if (atomic_read(&srq->use_cnt)) { - ocrdma_err("%s(%d) err, srq=0x%x in use\n", - __func__, dev->id, srq->id); - return -EAGAIN; - } - - status = ocrdma_mbx_destroy_srq(dev, srq); - - if (srq->pd->uctx) - ocrdma_del_mmap(srq->pd->uctx, (u64) srq->rq.pa, srq->rq.len); - - atomic_dec(&srq->pd->use_cnt); - kfree(srq->idx_bit_fields); - kfree(srq->rqe_wr_id_tbl); - kfree(srq); - return status; -} - -/* unprivileged verbs and their support functions. */ -static void ocrdma_build_ud_hdr(struct ocrdma_qp *qp, - struct ocrdma_hdr_wqe *hdr, - struct ib_send_wr *wr) -{ - struct ocrdma_ewqe_ud_hdr *ud_hdr = - (struct ocrdma_ewqe_ud_hdr *)(hdr + 1); - struct ocrdma_ah *ah = get_ocrdma_ah(wr->wr.ud.ah); - - ud_hdr->rsvd_dest_qpn = wr->wr.ud.remote_qpn; - if (qp->qp_type == IB_QPT_GSI) - ud_hdr->qkey = qp->qkey; - else - ud_hdr->qkey = wr->wr.ud.remote_qkey; - ud_hdr->rsvd_ahid = ah->id; -} - -static void ocrdma_build_sges(struct ocrdma_hdr_wqe *hdr, - struct ocrdma_sge *sge, int num_sge, - struct ib_sge *sg_list) -{ - int i; - - for (i = 0; i < num_sge; i++) { - sge[i].lrkey = sg_list[i].lkey; - sge[i].addr_lo = sg_list[i].addr; - sge[i].addr_hi = upper_32_bits(sg_list[i].addr); - sge[i].len = sg_list[i].length; - hdr->total_len += sg_list[i].length; - } - if (num_sge == 0) - memset(sge, 0, sizeof(*sge)); -} - -static int ocrdma_build_inline_sges(struct ocrdma_qp *qp, - struct ocrdma_hdr_wqe *hdr, - struct ocrdma_sge *sge, - struct ib_send_wr *wr, u32 wqe_size) -{ - if (wr->send_flags & IB_SEND_INLINE) { - if (wr->sg_list[0].length > qp->max_inline_data) { - ocrdma_err("%s() supported_len=0x%x," - " unspported len req=0x%x\n", __func__, - qp->max_inline_data, wr->sg_list[0].length); - return -EINVAL; - } - memcpy(sge, - (void *)(unsigned long)wr->sg_list[0].addr, - wr->sg_list[0].length); - hdr->total_len = wr->sg_list[0].length; - wqe_size += roundup(hdr->total_len, OCRDMA_WQE_ALIGN_BYTES); - hdr->cw |= (OCRDMA_TYPE_INLINE << OCRDMA_WQE_TYPE_SHIFT); - } else { - ocrdma_build_sges(hdr, sge, wr->num_sge, wr->sg_list); - if (wr->num_sge) - wqe_size += (wr->num_sge * sizeof(struct ocrdma_sge)); - else - wqe_size += sizeof(struct ocrdma_sge); - hdr->cw |= (OCRDMA_TYPE_LKEY << OCRDMA_WQE_TYPE_SHIFT); - } - hdr->cw |= ((wqe_size / OCRDMA_WQE_STRIDE) << OCRDMA_WQE_SIZE_SHIFT); - return 0; -} - -static int ocrdma_build_send(struct ocrdma_qp *qp, struct ocrdma_hdr_wqe *hdr, - struct ib_send_wr *wr) -{ - int status; - struct ocrdma_sge *sge; - u32 wqe_size = sizeof(*hdr); - - if (qp->qp_type == IB_QPT_UD || qp->qp_type == IB_QPT_GSI) { - ocrdma_build_ud_hdr(qp, hdr, wr); - sge = (struct ocrdma_sge *)(hdr + 2); - wqe_size += sizeof(struct ocrdma_ewqe_ud_hdr); - } else - sge = (struct ocrdma_sge *)(hdr + 1); - - status = ocrdma_build_inline_sges(qp, hdr, sge, wr, wqe_size); - return status; -} - -static int ocrdma_build_write(struct ocrdma_qp *qp, struct ocrdma_hdr_wqe *hdr, - struct ib_send_wr *wr) -{ - int status; - struct ocrdma_sge *ext_rw = (struct ocrdma_sge *)(hdr + 1); - struct ocrdma_sge *sge = ext_rw + 1; - u32 wqe_size = sizeof(*hdr) + sizeof(*ext_rw); - - status = ocrdma_build_inline_sges(qp, hdr, sge, wr, wqe_size); - if (status) - return status; - ext_rw->addr_lo = wr->wr.rdma.remote_addr; - ext_rw->addr_hi = upper_32_bits(wr->wr.rdma.remote_addr); - ext_rw->lrkey = wr->wr.rdma.rkey; - ext_rw->len = hdr->total_len; - return 0; -} - -static void ocrdma_build_read(struct ocrdma_qp *qp, struct ocrdma_hdr_wqe *hdr, - struct ib_send_wr *wr) -{ - struct ocrdma_sge *ext_rw = (struct ocrdma_sge *)(hdr + 1); - struct ocrdma_sge *sge = ext_rw + 1; - u32 wqe_size = ((wr->num_sge + 1) * sizeof(struct ocrdma_sge)) + - sizeof(struct ocrdma_hdr_wqe); - - ocrdma_build_sges(hdr, sge, wr->num_sge, wr->sg_list); - hdr->cw |= ((wqe_size / OCRDMA_WQE_STRIDE) << OCRDMA_WQE_SIZE_SHIFT); - hdr->cw |= (OCRDMA_READ << OCRDMA_WQE_OPCODE_SHIFT); - hdr->cw |= (OCRDMA_TYPE_LKEY << OCRDMA_WQE_TYPE_SHIFT); - - ext_rw->addr_lo = wr->wr.rdma.remote_addr; - ext_rw->addr_hi = upper_32_bits(wr->wr.rdma.remote_addr); - ext_rw->lrkey = wr->wr.rdma.rkey; - ext_rw->len = hdr->total_len; -} - -static void ocrdma_ring_sq_db(struct ocrdma_qp *qp) -{ - u32 val = qp->sq.dbid | (1 << 16); - - iowrite32(val, qp->sq_db); -} - -int ocrdma_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, - struct ib_send_wr **bad_wr) -{ - int status = 0; - struct ocrdma_qp *qp = get_ocrdma_qp(ibqp); - struct ocrdma_hdr_wqe *hdr; - unsigned long flags; - - spin_lock_irqsave(&qp->q_lock, flags); - if (qp->state != OCRDMA_QPS_RTS && qp->state != OCRDMA_QPS_SQD) { - spin_unlock_irqrestore(&qp->q_lock, flags); - return -EINVAL; - } - - while (wr) { - if (ocrdma_hwq_free_cnt(&qp->sq) == 0 || - wr->num_sge > qp->sq.max_sges) { - status = -ENOMEM; - break; - } - hdr = ocrdma_hwq_head(&qp->sq); - hdr->cw = 0; - if (wr->send_flags & IB_SEND_SIGNALED) - hdr->cw |= (OCRDMA_FLAG_SIG << OCRDMA_WQE_FLAGS_SHIFT); - if (wr->send_flags & IB_SEND_FENCE) - hdr->cw |= - (OCRDMA_FLAG_FENCE_L << OCRDMA_WQE_FLAGS_SHIFT); - if (wr->send_flags & IB_SEND_SOLICITED) - hdr->cw |= - (OCRDMA_FLAG_SOLICIT << OCRDMA_WQE_FLAGS_SHIFT); - hdr->total_len = 0; - switch (wr->opcode) { - case IB_WR_SEND_WITH_IMM: - hdr->cw |= (OCRDMA_FLAG_IMM << OCRDMA_WQE_FLAGS_SHIFT); - hdr->immdt = ntohl(wr->ex.imm_data); - case IB_WR_SEND: - hdr->cw |= (OCRDMA_SEND << OCRDMA_WQE_OPCODE_SHIFT); - ocrdma_build_send(qp, hdr, wr); - break; - case IB_WR_SEND_WITH_INV: - hdr->cw |= (OCRDMA_FLAG_INV << OCRDMA_WQE_FLAGS_SHIFT); - hdr->cw |= (OCRDMA_SEND << OCRDMA_WQE_OPCODE_SHIFT); - hdr->lkey = wr->ex.invalidate_rkey; - status = ocrdma_build_send(qp, hdr, wr); - break; - case IB_WR_RDMA_WRITE_WITH_IMM: - hdr->cw |= (OCRDMA_FLAG_IMM << OCRDMA_WQE_FLAGS_SHIFT); - hdr->immdt = ntohl(wr->ex.imm_data); - case IB_WR_RDMA_WRITE: - hdr->cw |= (OCRDMA_WRITE << OCRDMA_WQE_OPCODE_SHIFT); - status = ocrdma_build_write(qp, hdr, wr); - break; - case IB_WR_RDMA_READ_WITH_INV: - hdr->cw |= (OCRDMA_FLAG_INV << OCRDMA_WQE_FLAGS_SHIFT); - case IB_WR_RDMA_READ: - ocrdma_build_read(qp, hdr, wr); - break; - case IB_WR_LOCAL_INV: - hdr->cw |= - (OCRDMA_LKEY_INV << OCRDMA_WQE_OPCODE_SHIFT); - hdr->cw |= (sizeof(struct ocrdma_hdr_wqe) / - OCRDMA_WQE_STRIDE) << OCRDMA_WQE_SIZE_SHIFT; - hdr->lkey = wr->ex.invalidate_rkey; - break; - default: - status = -EINVAL; - break; - } - if (status) { - *bad_wr = wr; - break; - } - if (wr->send_flags & IB_SEND_SIGNALED) - qp->wqe_wr_id_tbl[qp->sq.head].signaled = 1; - else - qp->wqe_wr_id_tbl[qp->sq.head].signaled = 0; - qp->wqe_wr_id_tbl[qp->sq.head].wrid = wr->wr_id; - ocrdma_cpu_to_le32(hdr, ((hdr->cw >> OCRDMA_WQE_SIZE_SHIFT) & - OCRDMA_WQE_SIZE_MASK) * OCRDMA_WQE_STRIDE); - /* make sure wqe is written before adapter can access it */ - wmb(); - /* inform hw to start processing it */ - ocrdma_ring_sq_db(qp); - - /* update pointer, counter for next wr */ - ocrdma_hwq_inc_head(&qp->sq); - wr = wr->next; - } - spin_unlock_irqrestore(&qp->q_lock, flags); - return status; -} - -static void ocrdma_ring_rq_db(struct ocrdma_qp *qp) -{ - u32 val = qp->rq.dbid | (1 << OCRDMA_GET_NUM_POSTED_SHIFT_VAL(qp)); - - iowrite32(val, qp->rq_db); -} - -static void ocrdma_build_rqe(struct ocrdma_hdr_wqe *rqe, struct ib_recv_wr *wr, - u16 tag) -{ - u32 wqe_size = 0; - struct ocrdma_sge *sge; - if (wr->num_sge) - wqe_size = (wr->num_sge * sizeof(*sge)) + sizeof(*rqe); - else - wqe_size = sizeof(*sge) + sizeof(*rqe); - - rqe->cw = ((wqe_size / OCRDMA_WQE_STRIDE) << - OCRDMA_WQE_SIZE_SHIFT); - rqe->cw |= (OCRDMA_FLAG_SIG << OCRDMA_WQE_FLAGS_SHIFT); - rqe->cw |= (OCRDMA_TYPE_LKEY << OCRDMA_WQE_TYPE_SHIFT); - rqe->total_len = 0; - rqe->rsvd_tag = tag; - sge = (struct ocrdma_sge *)(rqe + 1); - ocrdma_build_sges(rqe, sge, wr->num_sge, wr->sg_list); - ocrdma_cpu_to_le32(rqe, wqe_size); -} - -int ocrdma_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr, - struct ib_recv_wr **bad_wr) -{ - int status = 0; - unsigned long flags; - struct ocrdma_qp *qp = get_ocrdma_qp(ibqp); - struct ocrdma_hdr_wqe *rqe; - - spin_lock_irqsave(&qp->q_lock, flags); - if (qp->state == OCRDMA_QPS_RST || qp->state == OCRDMA_QPS_ERR) { - spin_unlock_irqrestore(&qp->q_lock, flags); - *bad_wr = wr; - return -EINVAL; - } - while (wr) { - if (ocrdma_hwq_free_cnt(&qp->rq) == 0 || - wr->num_sge > qp->rq.max_sges) { - *bad_wr = wr; - status = -ENOMEM; - break; - } - rqe = ocrdma_hwq_head(&qp->rq); - ocrdma_build_rqe(rqe, wr, 0); - - qp->rqe_wr_id_tbl[qp->rq.head] = wr->wr_id; - /* make sure rqe is written before adapter can access it */ - wmb(); - - /* inform hw to start processing it */ - ocrdma_ring_rq_db(qp); - - /* update pointer, counter for next wr */ - ocrdma_hwq_inc_head(&qp->rq); - wr = wr->next; - } - spin_unlock_irqrestore(&qp->q_lock, flags); - return status; -} - -/* cqe for srq's rqe can potentially arrive out of order. - * index gives the entry in the shadow table where to store - * the wr_id. tag/index is returned in cqe to reference back - * for a given rqe. - */ -static int ocrdma_srq_get_idx(struct ocrdma_srq *srq) -{ - int row = 0; - int indx = 0; - - for (row = 0; row < srq->bit_fields_len; row++) { - if (srq->idx_bit_fields[row]) { - indx = ffs(srq->idx_bit_fields[row]); - indx = (row * 32) + (indx - 1); - if (indx >= srq->rq.max_cnt) - BUG(); - ocrdma_srq_toggle_bit(srq, indx); - break; - } - } - - if (row == srq->bit_fields_len) - BUG(); - return indx; -} - -static void ocrdma_ring_srq_db(struct ocrdma_srq *srq) -{ - u32 val = srq->rq.dbid | (1 << 16); - - iowrite32(val, srq->db + OCRDMA_DB_GEN2_SRQ_OFFSET); -} - -int ocrdma_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr, - struct ib_recv_wr **bad_wr) -{ - int status = 0; - unsigned long flags; - struct ocrdma_srq *srq; - struct ocrdma_hdr_wqe *rqe; - u16 tag; - - srq = get_ocrdma_srq(ibsrq); - - spin_lock_irqsave(&srq->q_lock, flags); - while (wr) { - if (ocrdma_hwq_free_cnt(&srq->rq) == 0 || - wr->num_sge > srq->rq.max_sges) { - status = -ENOMEM; - *bad_wr = wr; - break; - } - tag = ocrdma_srq_get_idx(srq); - rqe = ocrdma_hwq_head(&srq->rq); - ocrdma_build_rqe(rqe, wr, tag); - - srq->rqe_wr_id_tbl[tag] = wr->wr_id; - /* make sure rqe is written before adapter can perform DMA */ - wmb(); - /* inform hw to start processing it */ - ocrdma_ring_srq_db(srq); - /* update pointer, counter for next wr */ - ocrdma_hwq_inc_head(&srq->rq); - wr = wr->next; - } - spin_unlock_irqrestore(&srq->q_lock, flags); - return status; -} - -static enum ib_wc_status ocrdma_to_ibwc_err(u16 status) -{ - enum ib_wc_status ibwc_status = IB_WC_GENERAL_ERR; - - switch (status) { - case OCRDMA_CQE_GENERAL_ERR: - ibwc_status = IB_WC_GENERAL_ERR; - break; - case OCRDMA_CQE_LOC_LEN_ERR: - ibwc_status = IB_WC_LOC_LEN_ERR; - break; - case OCRDMA_CQE_LOC_QP_OP_ERR: - ibwc_status = IB_WC_LOC_QP_OP_ERR; - break; - case OCRDMA_CQE_LOC_EEC_OP_ERR: - ibwc_status = IB_WC_LOC_EEC_OP_ERR; - break; - case OCRDMA_CQE_LOC_PROT_ERR: - ibwc_status = IB_WC_LOC_PROT_ERR; - break; - case OCRDMA_CQE_WR_FLUSH_ERR: - ibwc_status = IB_WC_WR_FLUSH_ERR; - break; - case OCRDMA_CQE_MW_BIND_ERR: - ibwc_status = IB_WC_MW_BIND_ERR; - break; - case OCRDMA_CQE_BAD_RESP_ERR: - ibwc_status = IB_WC_BAD_RESP_ERR; - break; - case OCRDMA_CQE_LOC_ACCESS_ERR: - ibwc_status = IB_WC_LOC_ACCESS_ERR; - break; - case OCRDMA_CQE_REM_INV_REQ_ERR: - ibwc_status = IB_WC_REM_INV_REQ_ERR; - break; - case OCRDMA_CQE_REM_ACCESS_ERR: - ibwc_status = IB_WC_REM_ACCESS_ERR; - break; - case OCRDMA_CQE_REM_OP_ERR: - ibwc_status = IB_WC_REM_OP_ERR; - break; - case OCRDMA_CQE_RETRY_EXC_ERR: - ibwc_status = IB_WC_RETRY_EXC_ERR; - break; - case OCRDMA_CQE_RNR_RETRY_EXC_ERR: - ibwc_status = IB_WC_RNR_RETRY_EXC_ERR; - break; - case OCRDMA_CQE_LOC_RDD_VIOL_ERR: - ibwc_status = IB_WC_LOC_RDD_VIOL_ERR; - break; - case OCRDMA_CQE_REM_INV_RD_REQ_ERR: - ibwc_status = IB_WC_REM_INV_RD_REQ_ERR; - break; - case OCRDMA_CQE_REM_ABORT_ERR: - ibwc_status = IB_WC_REM_ABORT_ERR; - break; - case OCRDMA_CQE_INV_EECN_ERR: - ibwc_status = IB_WC_INV_EECN_ERR; - break; - case OCRDMA_CQE_INV_EEC_STATE_ERR: - ibwc_status = IB_WC_INV_EEC_STATE_ERR; - break; - case OCRDMA_CQE_FATAL_ERR: - ibwc_status = IB_WC_FATAL_ERR; - break; - case OCRDMA_CQE_RESP_TIMEOUT_ERR: - ibwc_status = IB_WC_RESP_TIMEOUT_ERR; - break; - default: - ibwc_status = IB_WC_GENERAL_ERR; - break; - }; - return ibwc_status; -} - -static void ocrdma_update_wc(struct ocrdma_qp *qp, struct ib_wc *ibwc, - u32 wqe_idx) -{ - struct ocrdma_hdr_wqe *hdr; - struct ocrdma_sge *rw; - int opcode; - - hdr = ocrdma_hwq_head_from_idx(&qp->sq, wqe_idx); - - ibwc->wr_id = qp->wqe_wr_id_tbl[wqe_idx].wrid; - /* Undo the hdr->cw swap */ - opcode = le32_to_cpu(hdr->cw) & OCRDMA_WQE_OPCODE_MASK; - switch (opcode) { - case OCRDMA_WRITE: - ibwc->opcode = IB_WC_RDMA_WRITE; - break; - case OCRDMA_READ: - rw = (struct ocrdma_sge *)(hdr + 1); - ibwc->opcode = IB_WC_RDMA_READ; - ibwc->byte_len = rw->len; - break; - case OCRDMA_SEND: - ibwc->opcode = IB_WC_SEND; - break; - case OCRDMA_LKEY_INV: - ibwc->opcode = IB_WC_LOCAL_INV; - break; - default: - ibwc->status = IB_WC_GENERAL_ERR; - ocrdma_err("%s() invalid opcode received = 0x%x\n", - __func__, hdr->cw & OCRDMA_WQE_OPCODE_MASK); - break; - }; -} - -static void ocrdma_set_cqe_status_flushed(struct ocrdma_qp *qp, - struct ocrdma_cqe *cqe) -{ - if (is_cqe_for_sq(cqe)) { - cqe->flags_status_srcqpn = cpu_to_le32(le32_to_cpu( - cqe->flags_status_srcqpn) & - ~OCRDMA_CQE_STATUS_MASK); - cqe->flags_status_srcqpn = cpu_to_le32(le32_to_cpu( - cqe->flags_status_srcqpn) | - (OCRDMA_CQE_WR_FLUSH_ERR << - OCRDMA_CQE_STATUS_SHIFT)); - } else { - if (qp->qp_type == IB_QPT_UD || qp->qp_type == IB_QPT_GSI) { - cqe->flags_status_srcqpn = cpu_to_le32(le32_to_cpu( - cqe->flags_status_srcqpn) & - ~OCRDMA_CQE_UD_STATUS_MASK); - cqe->flags_status_srcqpn = cpu_to_le32(le32_to_cpu( - cqe->flags_status_srcqpn) | - (OCRDMA_CQE_WR_FLUSH_ERR << - OCRDMA_CQE_UD_STATUS_SHIFT)); - } else { - cqe->flags_status_srcqpn = cpu_to_le32(le32_to_cpu( - cqe->flags_status_srcqpn) & - ~OCRDMA_CQE_STATUS_MASK); - cqe->flags_status_srcqpn = cpu_to_le32(le32_to_cpu( - cqe->flags_status_srcqpn) | - (OCRDMA_CQE_WR_FLUSH_ERR << - OCRDMA_CQE_STATUS_SHIFT)); - } - } -} - -static bool ocrdma_update_err_cqe(struct ib_wc *ibwc, struct ocrdma_cqe *cqe, - struct ocrdma_qp *qp, int status) -{ - bool expand = false; - - ibwc->byte_len = 0; - ibwc->qp = &qp->ibqp; - ibwc->status = ocrdma_to_ibwc_err(status); - - ocrdma_flush_qp(qp); - ocrdma_qp_state_machine(qp, IB_QPS_ERR, NULL); - - /* if wqe/rqe pending for which cqe needs to be returned, - * trigger inflating it. - */ - if (!is_hw_rq_empty(qp) || !is_hw_sq_empty(qp)) { - expand = true; - ocrdma_set_cqe_status_flushed(qp, cqe); - } - return expand; -} - -static int ocrdma_update_err_rcqe(struct ib_wc *ibwc, struct ocrdma_cqe *cqe, - struct ocrdma_qp *qp, int status) -{ - ibwc->opcode = IB_WC_RECV; - ibwc->wr_id = qp->rqe_wr_id_tbl[qp->rq.tail]; - ocrdma_hwq_inc_tail(&qp->rq); - - return ocrdma_update_err_cqe(ibwc, cqe, qp, status); -} - -static int ocrdma_update_err_scqe(struct ib_wc *ibwc, struct ocrdma_cqe *cqe, - struct ocrdma_qp *qp, int status) -{ - ocrdma_update_wc(qp, ibwc, qp->sq.tail); - ocrdma_hwq_inc_tail(&qp->sq); - - return ocrdma_update_err_cqe(ibwc, cqe, qp, status); -} - - -static bool ocrdma_poll_err_scqe(struct ocrdma_qp *qp, - struct ocrdma_cqe *cqe, struct ib_wc *ibwc, - bool *polled, bool *stop) -{ - bool expand; - int status = (le32_to_cpu(cqe->flags_status_srcqpn) & - OCRDMA_CQE_STATUS_MASK) >> OCRDMA_CQE_STATUS_SHIFT; - - /* when hw sq is empty, but rq is not empty, so we continue - * to keep the cqe in order to get the cq event again. - */ - if (is_hw_sq_empty(qp) && !is_hw_rq_empty(qp)) { - /* when cq for rq and sq is same, it is safe to return - * flush cqe for RQEs. - */ - if (!qp->srq && (qp->sq_cq == qp->rq_cq)) { - *polled = true; - status = OCRDMA_CQE_WR_FLUSH_ERR; - expand = ocrdma_update_err_rcqe(ibwc, cqe, qp, status); - } else { - /* stop processing further cqe as this cqe is used for - * triggering cq event on buddy cq of RQ. - * When QP is destroyed, this cqe will be removed - * from the cq's hardware q. - */ - *polled = false; - *stop = true; - expand = false; - } - } else { - *polled = true; - expand = ocrdma_update_err_scqe(ibwc, cqe, qp, status); - } - return expand; -} - -static bool ocrdma_poll_success_scqe(struct ocrdma_qp *qp, - struct ocrdma_cqe *cqe, - struct ib_wc *ibwc, bool *polled) -{ - bool expand = false; - int tail = qp->sq.tail; - u32 wqe_idx; - - if (!qp->wqe_wr_id_tbl[tail].signaled) { - expand = true; /* CQE cannot be consumed yet */ - *polled = false; /* WC cannot be consumed yet */ - } else { - ibwc->status = IB_WC_SUCCESS; - ibwc->wc_flags = 0; - ibwc->qp = &qp->ibqp; - ocrdma_update_wc(qp, ibwc, tail); - *polled = true; - wqe_idx = le32_to_cpu(cqe->wq.wqeidx) & OCRDMA_CQE_WQEIDX_MASK; - if (tail != wqe_idx) - expand = true; /* Coalesced CQE can't be consumed yet */ - } - ocrdma_hwq_inc_tail(&qp->sq); - return expand; -} - -static bool ocrdma_poll_scqe(struct ocrdma_qp *qp, struct ocrdma_cqe *cqe, - struct ib_wc *ibwc, bool *polled, bool *stop) -{ - int status; - bool expand; - - status = (le32_to_cpu(cqe->flags_status_srcqpn) & - OCRDMA_CQE_STATUS_MASK) >> OCRDMA_CQE_STATUS_SHIFT; - - if (status == OCRDMA_CQE_SUCCESS) - expand = ocrdma_poll_success_scqe(qp, cqe, ibwc, polled); - else - expand = ocrdma_poll_err_scqe(qp, cqe, ibwc, polled, stop); - return expand; -} - -static int ocrdma_update_ud_rcqe(struct ib_wc *ibwc, struct ocrdma_cqe *cqe) -{ - int status; - - status = (le32_to_cpu(cqe->flags_status_srcqpn) & - OCRDMA_CQE_UD_STATUS_MASK) >> OCRDMA_CQE_UD_STATUS_SHIFT; - ibwc->src_qp = le32_to_cpu(cqe->flags_status_srcqpn) & - OCRDMA_CQE_SRCQP_MASK; - ibwc->pkey_index = le32_to_cpu(cqe->ud.rxlen_pkey) & - OCRDMA_CQE_PKEY_MASK; - ibwc->wc_flags = IB_WC_GRH; - ibwc->byte_len = (le32_to_cpu(cqe->ud.rxlen_pkey) >> - OCRDMA_CQE_UD_XFER_LEN_SHIFT); - return status; -} - -static void ocrdma_update_free_srq_cqe(struct ib_wc *ibwc, - struct ocrdma_cqe *cqe, - struct ocrdma_qp *qp) -{ - unsigned long flags; - struct ocrdma_srq *srq; - u32 wqe_idx; - - srq = get_ocrdma_srq(qp->ibqp.srq); - wqe_idx = le32_to_cpu(cqe->rq.buftag_qpn) >> OCRDMA_CQE_BUFTAG_SHIFT; - ibwc->wr_id = srq->rqe_wr_id_tbl[wqe_idx]; - spin_lock_irqsave(&srq->q_lock, flags); - ocrdma_srq_toggle_bit(srq, wqe_idx); - spin_unlock_irqrestore(&srq->q_lock, flags); - ocrdma_hwq_inc_tail(&srq->rq); -} - -static bool ocrdma_poll_err_rcqe(struct ocrdma_qp *qp, struct ocrdma_cqe *cqe, - struct ib_wc *ibwc, bool *polled, bool *stop, - int status) -{ - bool expand; - - /* when hw_rq is empty, but wq is not empty, so continue - * to keep the cqe to get the cq event again. - */ - if (is_hw_rq_empty(qp) && !is_hw_sq_empty(qp)) { - if (!qp->srq && (qp->sq_cq == qp->rq_cq)) { - *polled = true; - status = OCRDMA_CQE_WR_FLUSH_ERR; - expand = ocrdma_update_err_scqe(ibwc, cqe, qp, status); - } else { - *polled = false; - *stop = true; - expand = false; - } - } else - expand = ocrdma_update_err_rcqe(ibwc, cqe, qp, status); - return expand; -} - -static void ocrdma_poll_success_rcqe(struct ocrdma_qp *qp, - struct ocrdma_cqe *cqe, struct ib_wc *ibwc) -{ - ibwc->opcode = IB_WC_RECV; - ibwc->qp = &qp->ibqp; - ibwc->status = IB_WC_SUCCESS; - - if (qp->qp_type == IB_QPT_UD || qp->qp_type == IB_QPT_GSI) - ocrdma_update_ud_rcqe(ibwc, cqe); - else - ibwc->byte_len = le32_to_cpu(cqe->rq.rxlen); - - if (is_cqe_imm(cqe)) { - ibwc->ex.imm_data = htonl(le32_to_cpu(cqe->rq.lkey_immdt)); - ibwc->wc_flags |= IB_WC_WITH_IMM; - } else if (is_cqe_wr_imm(cqe)) { - ibwc->opcode = IB_WC_RECV_RDMA_WITH_IMM; - ibwc->ex.imm_data = htonl(le32_to_cpu(cqe->rq.lkey_immdt)); - ibwc->wc_flags |= IB_WC_WITH_IMM; - } else if (is_cqe_invalidated(cqe)) { - ibwc->ex.invalidate_rkey = le32_to_cpu(cqe->rq.lkey_immdt); - ibwc->wc_flags |= IB_WC_WITH_INVALIDATE; - } - if (qp->ibqp.srq) - ocrdma_update_free_srq_cqe(ibwc, cqe, qp); - else { - ibwc->wr_id = qp->rqe_wr_id_tbl[qp->rq.tail]; - ocrdma_hwq_inc_tail(&qp->rq); - } -} - -static bool ocrdma_poll_rcqe(struct ocrdma_qp *qp, struct ocrdma_cqe *cqe, - struct ib_wc *ibwc, bool *polled, bool *stop) -{ - int status; - bool expand = false; - - ibwc->wc_flags = 0; - if (qp->qp_type == IB_QPT_UD || qp->qp_type == IB_QPT_GSI) - status = (le32_to_cpu(cqe->flags_status_srcqpn) & - OCRDMA_CQE_UD_STATUS_MASK) >> - OCRDMA_CQE_UD_STATUS_SHIFT; - else - status = (le32_to_cpu(cqe->flags_status_srcqpn) & - OCRDMA_CQE_STATUS_MASK) >> OCRDMA_CQE_STATUS_SHIFT; - - if (status == OCRDMA_CQE_SUCCESS) { - *polled = true; - ocrdma_poll_success_rcqe(qp, cqe, ibwc); - } else { - expand = ocrdma_poll_err_rcqe(qp, cqe, ibwc, polled, stop, - status); - } - return expand; -} - -static void ocrdma_change_cq_phase(struct ocrdma_cq *cq, struct ocrdma_cqe *cqe, - u16 cur_getp) -{ - if (cq->phase_change) { - if (cur_getp == 0) - cq->phase = (~cq->phase & OCRDMA_CQE_VALID); - } else - /* clear valid bit */ - cqe->flags_status_srcqpn = 0; -} - -static int ocrdma_poll_hwcq(struct ocrdma_cq *cq, int num_entries, - struct ib_wc *ibwc) -{ - u16 qpn = 0; - int i = 0; - bool expand = false; - int polled_hw_cqes = 0; - struct ocrdma_qp *qp = NULL; - struct ocrdma_dev *dev = cq->dev; - struct ocrdma_cqe *cqe; - u16 cur_getp; bool polled = false; bool stop = false; - - cur_getp = cq->getp; - while (num_entries) { - cqe = cq->va + cur_getp; - /* check whether valid cqe or not */ - if (!is_cqe_valid(cq, cqe)) - break; - qpn = (le32_to_cpu(cqe->cmn.qpn) & OCRDMA_CQE_QPN_MASK); - /* ignore discarded cqe */ - if (qpn == 0) - goto skip_cqe; - qp = dev->qp_tbl[qpn]; - BUG_ON(qp == NULL); - - if (is_cqe_for_sq(cqe)) { - expand = ocrdma_poll_scqe(qp, cqe, ibwc, &polled, - &stop); - } else { - expand = ocrdma_poll_rcqe(qp, cqe, ibwc, &polled, - &stop); - } - if (expand) - goto expand_cqe; - if (stop) - goto stop_cqe; - /* clear qpn to avoid duplicate processing by discard_cqe() */ - cqe->cmn.qpn = 0; -skip_cqe: - polled_hw_cqes += 1; - cur_getp = (cur_getp + 1) % cq->max_hw_cqe; - ocrdma_change_cq_phase(cq, cqe, cur_getp); -expand_cqe: - if (polled) { - num_entries -= 1; - i += 1; - ibwc = ibwc + 1; - polled = false; - } - } -stop_cqe: - cq->getp = cur_getp; - if (polled_hw_cqes || expand || stop) { - ocrdma_ring_cq_db(dev, cq->id, cq->armed, cq->solicited, - polled_hw_cqes); - } - return i; -} - -/* insert error cqe if the QP's SQ or RQ's CQ matches the CQ under poll. */ -static int ocrdma_add_err_cqe(struct ocrdma_cq *cq, int num_entries, - struct ocrdma_qp *qp, struct ib_wc *ibwc) -{ - int err_cqes = 0; - - while (num_entries) { - if (is_hw_sq_empty(qp) && is_hw_rq_empty(qp)) - break; - if (!is_hw_sq_empty(qp) && qp->sq_cq == cq) { - ocrdma_update_wc(qp, ibwc, qp->sq.tail); - ocrdma_hwq_inc_tail(&qp->sq); - } else if (!is_hw_rq_empty(qp) && qp->rq_cq == cq) { - ibwc->wr_id = qp->rqe_wr_id_tbl[qp->rq.tail]; - ocrdma_hwq_inc_tail(&qp->rq); - } else - return err_cqes; - ibwc->byte_len = 0; - ibwc->status = IB_WC_WR_FLUSH_ERR; - ibwc = ibwc + 1; - err_cqes += 1; - num_entries -= 1; - } - return err_cqes; -} - -int ocrdma_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) -{ - int cqes_to_poll = num_entries; - struct ocrdma_cq *cq = NULL; - unsigned long flags; - struct ocrdma_dev *dev; - int num_os_cqe = 0, err_cqes = 0; - struct ocrdma_qp *qp; - - cq = get_ocrdma_cq(ibcq); - dev = cq->dev; - - /* poll cqes from adapter CQ */ - spin_lock_irqsave(&cq->cq_lock, flags); - num_os_cqe = ocrdma_poll_hwcq(cq, cqes_to_poll, wc); - spin_unlock_irqrestore(&cq->cq_lock, flags); - cqes_to_poll -= num_os_cqe; - - if (cqes_to_poll) { - wc = wc + num_os_cqe; - /* adapter returns single error cqe when qp moves to - * error state. So insert error cqes with wc_status as - * FLUSHED for pending WQEs and RQEs of QP's SQ and RQ - * respectively which uses this CQ. - */ - spin_lock_irqsave(&dev->flush_q_lock, flags); - list_for_each_entry(qp, &cq->sq_head, sq_entry) { - if (cqes_to_poll == 0) - break; - err_cqes = ocrdma_add_err_cqe(cq, cqes_to_poll, qp, wc); - cqes_to_poll -= err_cqes; - num_os_cqe += err_cqes; - wc = wc + err_cqes; - } - spin_unlock_irqrestore(&dev->flush_q_lock, flags); - } - return num_os_cqe; -} - -int ocrdma_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags cq_flags) -{ - struct ocrdma_cq *cq; - unsigned long flags; - struct ocrdma_dev *dev; - u16 cq_id; - u16 cur_getp; - struct ocrdma_cqe *cqe; - - cq = get_ocrdma_cq(ibcq); - cq_id = cq->id; - dev = cq->dev; - - spin_lock_irqsave(&cq->cq_lock, flags); - if (cq_flags & IB_CQ_NEXT_COMP || cq_flags & IB_CQ_SOLICITED) - cq->armed = true; - if (cq_flags & IB_CQ_SOLICITED) - cq->solicited = true; - - cur_getp = cq->getp; - cqe = cq->va + cur_getp; - - /* check whether any valid cqe exist or not, if not then safe to - * arm. If cqe is not yet consumed, then let it get consumed and then - * we arm it to avoid false interrupts. - */ - if (!is_cqe_valid(cq, cqe) || cq->arm_needed) { - cq->arm_needed = false; - ocrdma_ring_cq_db(dev, cq_id, cq->armed, cq->solicited, 0); - } - spin_unlock_irqrestore(&cq->cq_lock, flags); - return 0; -} diff --git a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h b/trunk/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h deleted file mode 100644 index e6483439f25f..000000000000 --- a/trunk/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h +++ /dev/null @@ -1,94 +0,0 @@ -/******************************************************************* - * This file is part of the Emulex RoCE Device Driver for * - * RoCE (RDMA over Converged Ethernet) adapters. * - * Copyright (C) 2008-2012 Emulex. All rights reserved. * - * EMULEX and SLI are trademarks of Emulex. * - * www.emulex.com * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of version 2 of the GNU General * - * Public License as published by the Free Software Foundation. * - * This program is distributed in the hope that it will be useful. * - * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * - * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * - * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE * - * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD * - * TO BE LEGALLY INVALID. See the GNU General Public License for * - * more details, a copy of which can be found in the file COPYING * - * included with this package. * - * - * Contact Information: - * linux-drivers@emulex.com - * - * Emulex - * 3333 Susan Street - * Costa Mesa, CA 92626 - *******************************************************************/ - -#ifndef __OCRDMA_VERBS_H__ -#define __OCRDMA_VERBS_H__ - -#include -int ocrdma_post_send(struct ib_qp *, struct ib_send_wr *, - struct ib_send_wr **bad_wr); -int ocrdma_post_recv(struct ib_qp *, struct ib_recv_wr *, - struct ib_recv_wr **bad_wr); - -int ocrdma_poll_cq(struct ib_cq *, int num_entries, struct ib_wc *wc); -int ocrdma_arm_cq(struct ib_cq *, enum ib_cq_notify_flags flags); - -int ocrdma_query_device(struct ib_device *, struct ib_device_attr *props); -int ocrdma_query_port(struct ib_device *, u8 port, struct ib_port_attr *props); -int ocrdma_modify_port(struct ib_device *, u8 port, int mask, - struct ib_port_modify *props); - -void ocrdma_get_guid(struct ocrdma_dev *, u8 *guid); -int ocrdma_query_gid(struct ib_device *, u8 port, - int index, union ib_gid *gid); -int ocrdma_query_pkey(struct ib_device *, u8 port, u16 index, u16 *pkey); - -struct ib_ucontext *ocrdma_alloc_ucontext(struct ib_device *, - struct ib_udata *); -int ocrdma_dealloc_ucontext(struct ib_ucontext *); - -int ocrdma_mmap(struct ib_ucontext *, struct vm_area_struct *vma); - -struct ib_pd *ocrdma_alloc_pd(struct ib_device *, - struct ib_ucontext *, struct ib_udata *); -int ocrdma_dealloc_pd(struct ib_pd *pd); - -struct ib_cq *ocrdma_create_cq(struct ib_device *, int entries, int vector, - struct ib_ucontext *, struct ib_udata *); -int ocrdma_resize_cq(struct ib_cq *, int cqe, struct ib_udata *); -int ocrdma_destroy_cq(struct ib_cq *); - -struct ib_qp *ocrdma_create_qp(struct ib_pd *, - struct ib_qp_init_attr *attrs, - struct ib_udata *); -int _ocrdma_modify_qp(struct ib_qp *, struct ib_qp_attr *attr, - int attr_mask); -int ocrdma_modify_qp(struct ib_qp *, struct ib_qp_attr *attr, - int attr_mask, struct ib_udata *udata); -int ocrdma_query_qp(struct ib_qp *, - struct ib_qp_attr *qp_attr, - int qp_attr_mask, struct ib_qp_init_attr *); -int ocrdma_destroy_qp(struct ib_qp *); - -struct ib_srq *ocrdma_create_srq(struct ib_pd *, struct ib_srq_init_attr *, - struct ib_udata *); -int ocrdma_modify_srq(struct ib_srq *, struct ib_srq_attr *, - enum ib_srq_attr_mask, struct ib_udata *); -int ocrdma_query_srq(struct ib_srq *, struct ib_srq_attr *); -int ocrdma_destroy_srq(struct ib_srq *); -int ocrdma_post_srq_recv(struct ib_srq *, struct ib_recv_wr *, - struct ib_recv_wr **bad_recv_wr); - -int ocrdma_dereg_mr(struct ib_mr *); -struct ib_mr *ocrdma_get_dma_mr(struct ib_pd *, int acc); -struct ib_mr *ocrdma_reg_kernel_mr(struct ib_pd *, - struct ib_phys_buf *buffer_list, - int num_phys_buf, int acc, u64 *iova_start); -struct ib_mr *ocrdma_reg_user_mr(struct ib_pd *, u64 start, u64 length, - u64 virt, int acc, struct ib_udata *); - -#endif /* __OCRDMA_VERBS_H__ */ diff --git a/trunk/drivers/infiniband/hw/qib/qib.h b/trunk/drivers/infiniband/hw/qib/qib.h index 7e62f4137148..6b811e3e8bd1 100644 --- a/trunk/drivers/infiniband/hw/qib/qib.h +++ b/trunk/drivers/infiniband/hw/qib/qib.h @@ -530,6 +530,8 @@ struct qib_pportdata { /* qib_lflags driver is waiting for */ u32 state_wanted; spinlock_t lflags_lock; + /* number of (port-specific) interrupts for this port -- saturates... */ + u32 int_counter; /* ref count for each pkey */ atomic_t pkeyrefs[4]; @@ -541,26 +543,24 @@ struct qib_pportdata { u64 *statusp; /* SendDMA related entries */ - - /* read mostly */ - struct qib_sdma_desc *sdma_descq; + spinlock_t sdma_lock; struct qib_sdma_state sdma_state; - dma_addr_t sdma_descq_phys; - volatile __le64 *sdma_head_dma; /* DMA'ed by chip */ - dma_addr_t sdma_head_phys; - u16 sdma_descq_cnt; - - /* read/write using lock */ - spinlock_t sdma_lock ____cacheline_aligned_in_smp; - struct list_head sdma_activelist; + unsigned long sdma_buf_jiffies; + struct qib_sdma_desc *sdma_descq; u64 sdma_descq_added; u64 sdma_descq_removed; + u16 sdma_descq_cnt; u16 sdma_descq_tail; u16 sdma_descq_head; + u16 sdma_next_intr; + u16 sdma_reset_wait; u8 sdma_generation; + struct tasklet_struct sdma_sw_clean_up_task; + struct list_head sdma_activelist; - struct tasklet_struct sdma_sw_clean_up_task - ____cacheline_aligned_in_smp; + dma_addr_t sdma_descq_phys; + volatile __le64 *sdma_head_dma; /* DMA'ed by chip */ + dma_addr_t sdma_head_phys; wait_queue_head_t state_wait; /* for state_wanted */ @@ -873,14 +873,7 @@ struct qib_devdata { * pio_writing. */ spinlock_t pioavail_lock; - /* - * index of last buffer to optimize search for next - */ - u32 last_pio; - /* - * min kernel pio buffer to optimize search - */ - u32 min_kernel_pio; + /* * Shadow copies of registers; size indicates read access size. * Most of them are readonly, but some are write-only register, diff --git a/trunk/drivers/infiniband/hw/qib/qib_driver.c b/trunk/drivers/infiniband/hw/qib/qib_driver.c index 8895cfec5019..6fc9365ba8a6 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_driver.c +++ b/trunk/drivers/infiniband/hw/qib/qib_driver.c @@ -38,7 +38,6 @@ #include #include #include -#include #include "qib.h" @@ -482,10 +481,8 @@ u32 qib_kreceive(struct qib_ctxtdata *rcd, u32 *llic, u32 *npkts) etail = qib_hdrget_index(rhf_addr); updegr = 1; if (tlen > sizeof(*hdr) || - etype >= RCVHQ_RCV_TYPE_NON_KD) { + etype >= RCVHQ_RCV_TYPE_NON_KD) ebuf = qib_get_egrbuf(rcd, etail); - prefetch_range(ebuf, tlen - sizeof(*hdr)); - } } if (!eflags) { u16 lrh_len = be16_to_cpu(hdr->lrh[2]) << 2; diff --git a/trunk/drivers/infiniband/hw/qib/qib_iba6120.c b/trunk/drivers/infiniband/hw/qib/qib_iba6120.c index 4d352b90750a..d0c64d514813 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_iba6120.c +++ b/trunk/drivers/infiniband/hw/qib/qib_iba6120.c @@ -3132,7 +3132,6 @@ static void get_6120_chip_params(struct qib_devdata *dd) val = qib_read_kreg64(dd, kr_sendpiobufcnt); dd->piobcnt2k = val & ~0U; dd->piobcnt4k = val >> 32; - dd->last_pio = dd->piobcnt4k + dd->piobcnt2k - 1; /* these may be adjusted in init_chip_wc_pat() */ dd->pio2kbase = (u32 __iomem *) (((char __iomem *)dd->kregbase) + dd->pio2k_bufbase); diff --git a/trunk/drivers/infiniband/hw/qib/qib_iba7220.c b/trunk/drivers/infiniband/hw/qib/qib_iba7220.c index 86a0ba7ca0c2..3c722f79d6f6 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_iba7220.c +++ b/trunk/drivers/infiniband/hw/qib/qib_iba7220.c @@ -4157,7 +4157,6 @@ static int qib_init_7220_variables(struct qib_devdata *dd) dd->cspec->sdmabufcnt; dd->lastctxt_piobuf = dd->cspec->lastbuf_for_pio - sbufs; dd->cspec->lastbuf_for_pio--; /* range is <= , not < */ - dd->last_pio = dd->cspec->lastbuf_for_pio; dd->pbufsctxt = dd->lastctxt_piobuf / (dd->cfgctxts - dd->first_user_ctxt); diff --git a/trunk/drivers/infiniband/hw/qib/qib_iba7322.c b/trunk/drivers/infiniband/hw/qib/qib_iba7322.c index c881e744c091..060b96064469 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/trunk/drivers/infiniband/hw/qib/qib_iba7322.c @@ -6379,7 +6379,6 @@ static int qib_init_7322_variables(struct qib_devdata *dd) dd->cspec->sdmabufcnt; dd->lastctxt_piobuf = dd->cspec->lastbuf_for_pio - sbufs; dd->cspec->lastbuf_for_pio--; /* range is <= , not < */ - dd->last_pio = dd->cspec->lastbuf_for_pio; dd->pbufsctxt = (dd->cfgctxts > dd->first_user_ctxt) ? dd->lastctxt_piobuf / (dd->cfgctxts - dd->first_user_ctxt) : 0; @@ -7709,7 +7708,7 @@ static int serdes_7322_init_new(struct qib_pportdata *ppd) ibsd_wr_allchans(ppd, 5, 0, BMASK(0, 0)); msleep(20); /* Set Frequency Loop Bandwidth */ - ibsd_wr_allchans(ppd, 2, (15 << 5), BMASK(8, 5)); + ibsd_wr_allchans(ppd, 2, (7 << 5), BMASK(8, 5)); /* Enable Frequency Loop */ ibsd_wr_allchans(ppd, 2, (1 << 4), BMASK(4, 4)); /* Set Timing Loop Bandwidth */ diff --git a/trunk/drivers/infiniband/hw/qib/qib_init.c b/trunk/drivers/infiniband/hw/qib/qib_init.c index dc14e100a7f1..cf0cd30adc8d 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_init.c +++ b/trunk/drivers/infiniband/hw/qib/qib_init.c @@ -102,8 +102,6 @@ void qib_set_ctxtcnt(struct qib_devdata *dd) dd->cfgctxts = qib_cfgctxts; else dd->cfgctxts = dd->ctxtcnt; - dd->freectxts = (dd->first_user_ctxt > dd->cfgctxts) ? 0 : - dd->cfgctxts - dd->first_user_ctxt; } /* @@ -404,6 +402,7 @@ static void enable_chip(struct qib_devdata *dd) if (rcd) dd->f_rcvctrl(rcd->ppd, rcvmask, i); } + dd->freectxts = dd->cfgctxts - dd->first_user_ctxt; } static void verify_interrupt(unsigned long opaque) diff --git a/trunk/drivers/infiniband/hw/qib/qib_mad.c b/trunk/drivers/infiniband/hw/qib/qib_mad.c index 43390217a026..c4ff788823b5 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_mad.c +++ b/trunk/drivers/infiniband/hw/qib/qib_mad.c @@ -396,7 +396,6 @@ static int get_linkdowndefaultstate(struct qib_pportdata *ppd) static int check_mkey(struct qib_ibport *ibp, struct ib_smp *smp, int mad_flags) { - int valid_mkey = 0; int ret = 0; /* Is the mkey in the process of expiring? */ @@ -407,36 +406,23 @@ static int check_mkey(struct qib_ibport *ibp, struct ib_smp *smp, int mad_flags) ibp->mkeyprot = 0; } - if ((mad_flags & IB_MAD_IGNORE_MKEY) || ibp->mkey == 0 || - ibp->mkey == smp->mkey) - valid_mkey = 1; - - /* Unset lease timeout on any valid Get/Set/TrapRepress */ - if (valid_mkey && ibp->mkey_lease_timeout && - (smp->method == IB_MGMT_METHOD_GET || - smp->method == IB_MGMT_METHOD_SET || - smp->method == IB_MGMT_METHOD_TRAP_REPRESS)) + /* M_Key checking depends on Portinfo:M_Key_protect_bits */ + if ((mad_flags & IB_MAD_IGNORE_MKEY) == 0 && ibp->mkey != 0 && + ibp->mkey != smp->mkey && + (smp->method == IB_MGMT_METHOD_SET || + smp->method == IB_MGMT_METHOD_TRAP_REPRESS || + (smp->method == IB_MGMT_METHOD_GET && ibp->mkeyprot >= 2))) { + if (ibp->mkey_violations != 0xFFFF) + ++ibp->mkey_violations; + if (!ibp->mkey_lease_timeout && ibp->mkey_lease_period) + ibp->mkey_lease_timeout = jiffies + + ibp->mkey_lease_period * HZ; + /* Generate a trap notice. */ + qib_bad_mkey(ibp, smp); + ret = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED; + } else if (ibp->mkey_lease_timeout) ibp->mkey_lease_timeout = 0; - if (!valid_mkey) { - switch (smp->method) { - case IB_MGMT_METHOD_GET: - /* Bad mkey not a violation below level 2 */ - if (ibp->mkeyprot < 2) - break; - case IB_MGMT_METHOD_SET: - case IB_MGMT_METHOD_TRAP_REPRESS: - if (ibp->mkey_violations != 0xFFFF) - ++ibp->mkey_violations; - if (!ibp->mkey_lease_timeout && ibp->mkey_lease_period) - ibp->mkey_lease_timeout = jiffies + - ibp->mkey_lease_period * HZ; - /* Generate a trap notice. */ - qib_bad_mkey(ibp, smp); - ret = 1; - } - } - return ret; } @@ -464,7 +450,6 @@ static int subn_get_portinfo(struct ib_smp *smp, struct ib_device *ibdev, ibp = to_iport(ibdev, port_num); ret = check_mkey(ibp, smp, 0); if (ret) - ret = IB_MAD_RESULT_FAILURE; goto bail; } } @@ -646,7 +631,7 @@ static int subn_set_portinfo(struct ib_smp *smp, struct ib_device *ibdev, struct qib_devdata *dd; struct qib_pportdata *ppd; struct qib_ibport *ibp; - u8 clientrereg = (pip->clientrereg_resv_subnetto & 0x80); + char clientrereg = 0; unsigned long flags; u16 lid, smlid; u8 lwe; @@ -796,6 +781,12 @@ static int subn_set_portinfo(struct ib_smp *smp, struct ib_device *ibdev, ibp->subnet_timeout = pip->clientrereg_resv_subnetto & 0x1F; + if (pip->clientrereg_resv_subnetto & 0x80) { + clientrereg = 1; + event.event = IB_EVENT_CLIENT_REREGISTER; + ib_dispatch_event(&event); + } + /* * Do the port state change now that the other link parameters * have been set. @@ -853,15 +844,10 @@ static int subn_set_portinfo(struct ib_smp *smp, struct ib_device *ibdev, smp->status |= IB_SMP_INVALID_FIELD; } - if (clientrereg) { - event.event = IB_EVENT_CLIENT_REREGISTER; - ib_dispatch_event(&event); - } - ret = subn_get_portinfo(smp, ibdev, port); - /* restore re-reg bit per o14-12.2.1 */ - pip->clientrereg_resv_subnetto |= clientrereg; + if (clientrereg) + pip->clientrereg_resv_subnetto |= 0x80; goto get_only; @@ -1849,7 +1835,6 @@ static int process_subn(struct ib_device *ibdev, int mad_flags, port_num && port_num <= ibdev->phys_port_cnt && port != port_num) (void) check_mkey(to_iport(ibdev, port_num), smp, 0); - ret = IB_MAD_RESULT_FAILURE; goto bail; } diff --git a/trunk/drivers/infiniband/hw/qib/qib_qp.c b/trunk/drivers/infiniband/hw/qib/qib_qp.c index 1ce56b51ab1a..7e7e16fbee99 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_qp.c +++ b/trunk/drivers/infiniband/hw/qib/qib_qp.c @@ -1038,11 +1038,6 @@ struct ib_qp *qib_create_qp(struct ib_pd *ibpd, goto bail_swq; } RCU_INIT_POINTER(qp->next, NULL); - qp->s_hdr = kzalloc(sizeof(*qp->s_hdr), GFP_KERNEL); - if (!qp->s_hdr) { - ret = ERR_PTR(-ENOMEM); - goto bail_qp; - } qp->timeout_jiffies = usecs_to_jiffies((4096UL * (1UL << qp->timeout)) / 1000UL); @@ -1164,7 +1159,6 @@ struct ib_qp *qib_create_qp(struct ib_pd *ibpd, vfree(qp->r_rq.wq); free_qpn(&dev->qpn_table, qp->ibqp.qp_num); bail_qp: - kfree(qp->s_hdr); kfree(qp); bail_swq: vfree(swq); @@ -1220,7 +1214,6 @@ int qib_destroy_qp(struct ib_qp *ibqp) else vfree(qp->r_rq.wq); vfree(qp->s_wq); - kfree(qp->s_hdr); kfree(qp); return 0; } diff --git a/trunk/drivers/infiniband/hw/qib/qib_rc.c b/trunk/drivers/infiniband/hw/qib/qib_rc.c index b641416148eb..765b4cbaa020 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_rc.c +++ b/trunk/drivers/infiniband/hw/qib/qib_rc.c @@ -244,9 +244,9 @@ int qib_make_rc_req(struct qib_qp *qp) int ret = 0; int delta; - ohdr = &qp->s_hdr->u.oth; + ohdr = &qp->s_hdr.u.oth; if (qp->remote_ah_attr.ah_flags & IB_AH_GRH) - ohdr = &qp->s_hdr->u.l.oth; + ohdr = &qp->s_hdr.u.l.oth; /* * The lock is needed to synchronize between the sending tasklet, diff --git a/trunk/drivers/infiniband/hw/qib/qib_ruc.c b/trunk/drivers/infiniband/hw/qib/qib_ruc.c index c0ee7e095d81..b4b37e47321a 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_ruc.c +++ b/trunk/drivers/infiniband/hw/qib/qib_ruc.c @@ -688,17 +688,17 @@ void qib_make_ruc_header(struct qib_qp *qp, struct qib_other_headers *ohdr, nwords = (qp->s_cur_size + extra_bytes) >> 2; lrh0 = QIB_LRH_BTH; if (unlikely(qp->remote_ah_attr.ah_flags & IB_AH_GRH)) { - qp->s_hdrwords += qib_make_grh(ibp, &qp->s_hdr->u.l.grh, + qp->s_hdrwords += qib_make_grh(ibp, &qp->s_hdr.u.l.grh, &qp->remote_ah_attr.grh, qp->s_hdrwords, nwords); lrh0 = QIB_LRH_GRH; } lrh0 |= ibp->sl_to_vl[qp->remote_ah_attr.sl] << 12 | qp->remote_ah_attr.sl << 4; - qp->s_hdr->lrh[0] = cpu_to_be16(lrh0); - qp->s_hdr->lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid); - qp->s_hdr->lrh[2] = cpu_to_be16(qp->s_hdrwords + nwords + SIZE_OF_CRC); - qp->s_hdr->lrh[3] = cpu_to_be16(ppd_from_ibp(ibp)->lid | + qp->s_hdr.lrh[0] = cpu_to_be16(lrh0); + qp->s_hdr.lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid); + qp->s_hdr.lrh[2] = cpu_to_be16(qp->s_hdrwords + nwords + SIZE_OF_CRC); + qp->s_hdr.lrh[3] = cpu_to_be16(ppd_from_ibp(ibp)->lid | qp->remote_ah_attr.src_path_bits); bth0 |= qib_get_pkey(ibp, qp->s_pkey_index); bth0 |= extra_bytes << 20; @@ -758,7 +758,7 @@ void qib_do_send(struct work_struct *work) * If the packet cannot be sent now, return and * the send tasklet will be woken up later. */ - if (qib_verbs_send(qp, qp->s_hdr, qp->s_hdrwords, + if (qib_verbs_send(qp, &qp->s_hdr, qp->s_hdrwords, qp->s_cur_sge, qp->s_cur_size)) break; /* Record that s_hdr is empty. */ diff --git a/trunk/drivers/infiniband/hw/qib/qib_sysfs.c b/trunk/drivers/infiniband/hw/qib/qib_sysfs.c index dd9cd49d0979..dae51604cfcd 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_sysfs.c +++ b/trunk/drivers/infiniband/hw/qib/qib_sysfs.c @@ -503,11 +503,8 @@ static ssize_t show_nctxts(struct device *device, struct qib_devdata *dd = dd_from_dev(dev); /* Return the number of user ports (contexts) available. */ - /* The calculation below deals with a special case where - * cfgctxts is set to 1 on a single-port board. */ - return scnprintf(buf, PAGE_SIZE, "%u\n", - (dd->first_user_ctxt > dd->cfgctxts) ? 0 : - (dd->cfgctxts - dd->first_user_ctxt)); + return scnprintf(buf, PAGE_SIZE, "%u\n", dd->cfgctxts - + dd->first_user_ctxt); } static ssize_t show_nfreectxts(struct device *device, diff --git a/trunk/drivers/infiniband/hw/qib/qib_tx.c b/trunk/drivers/infiniband/hw/qib/qib_tx.c index 31d3561400a4..1bf626c40172 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_tx.c +++ b/trunk/drivers/infiniband/hw/qib/qib_tx.c @@ -295,7 +295,6 @@ u32 __iomem *qib_getsendbuf_range(struct qib_devdata *dd, u32 *pbufnum, nbufs = last - first + 1; /* number in range to check */ if (dd->upd_pio_shadow) { -update_shadow: /* * Minor optimization. If we had no buffers on last call, * start out by doing the update; continue and do scan even @@ -305,39 +304,37 @@ u32 __iomem *qib_getsendbuf_range(struct qib_devdata *dd, u32 *pbufnum, updated++; } i = first; +rescan: /* * While test_and_set_bit() is atomic, we do that and then the * change_bit(), and the pair is not. See if this is the cause * of the remaining armlaunch errors. */ spin_lock_irqsave(&dd->pioavail_lock, flags); - if (dd->last_pio >= first && dd->last_pio <= last) - i = dd->last_pio + 1; - if (!first) - /* adjust to min possible */ - nbufs = last - dd->min_kernel_pio + 1; for (j = 0; j < nbufs; j++, i++) { if (i > last) - i = !first ? dd->min_kernel_pio : first; + i = first; if (__test_and_set_bit((2 * i) + 1, shadow)) continue; /* flip generation bit */ __change_bit(2 * i, shadow); /* remember that the buffer can be written to now */ __set_bit(i, dd->pio_writing); - if (!first && first != last) /* first == last on VL15, avoid */ - dd->last_pio = i; break; } spin_unlock_irqrestore(&dd->pioavail_lock, flags); if (j == nbufs) { - if (!updated) + if (!updated) { /* * First time through; shadow exhausted, but may be * buffers available, try an update and then rescan. */ - goto update_shadow; + update_send_bufs(dd); + updated++; + i = first; + goto rescan; + } no_send_bufs(dd); buf = NULL; } else { @@ -425,20 +422,14 @@ void qib_chg_pioavailkernel(struct qib_devdata *dd, unsigned start, __clear_bit(QLOGIC_IB_SENDPIOAVAIL_CHECK_SHIFT + start, dd->pioavailshadow); __set_bit(start, dd->pioavailkernel); - if ((start >> 1) < dd->min_kernel_pio) - dd->min_kernel_pio = start >> 1; } else { __set_bit(start + QLOGIC_IB_SENDPIOAVAIL_BUSY_SHIFT, dd->pioavailshadow); __clear_bit(start, dd->pioavailkernel); - if ((start >> 1) > dd->min_kernel_pio) - dd->min_kernel_pio = start >> 1; } start += 2; } - if (dd->min_kernel_pio > 0 && dd->last_pio < dd->min_kernel_pio - 1) - dd->last_pio = dd->min_kernel_pio - 1; spin_unlock_irqrestore(&dd->pioavail_lock, flags); dd->f_txchk_change(dd, ostart, len, avail, rcd); diff --git a/trunk/drivers/infiniband/hw/qib/qib_uc.c b/trunk/drivers/infiniband/hw/qib/qib_uc.c index ce7387ff5d91..7ce2ac2ed219 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_uc.c +++ b/trunk/drivers/infiniband/hw/qib/qib_uc.c @@ -72,9 +72,9 @@ int qib_make_uc_req(struct qib_qp *qp) goto done; } - ohdr = &qp->s_hdr->u.oth; + ohdr = &qp->s_hdr.u.oth; if (qp->remote_ah_attr.ah_flags & IB_AH_GRH) - ohdr = &qp->s_hdr->u.l.oth; + ohdr = &qp->s_hdr.u.l.oth; /* header size in 32-bit words LRH+BTH = (8+12)/4. */ hwords = 5; diff --git a/trunk/drivers/infiniband/hw/qib/qib_ud.c b/trunk/drivers/infiniband/hw/qib/qib_ud.c index a468bf2d4465..828609fa4d28 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_ud.c +++ b/trunk/drivers/infiniband/hw/qib/qib_ud.c @@ -321,11 +321,11 @@ int qib_make_ud_req(struct qib_qp *qp) if (ah_attr->ah_flags & IB_AH_GRH) { /* Header size in 32-bit words. */ - qp->s_hdrwords += qib_make_grh(ibp, &qp->s_hdr->u.l.grh, + qp->s_hdrwords += qib_make_grh(ibp, &qp->s_hdr.u.l.grh, &ah_attr->grh, qp->s_hdrwords, nwords); lrh0 = QIB_LRH_GRH; - ohdr = &qp->s_hdr->u.l.oth; + ohdr = &qp->s_hdr.u.l.oth; /* * Don't worry about sending to locally attached multicast * QPs. It is unspecified by the spec. what happens. @@ -333,7 +333,7 @@ int qib_make_ud_req(struct qib_qp *qp) } else { /* Header size in 32-bit words. */ lrh0 = QIB_LRH_BTH; - ohdr = &qp->s_hdr->u.oth; + ohdr = &qp->s_hdr.u.oth; } if (wqe->wr.opcode == IB_WR_SEND_WITH_IMM) { qp->s_hdrwords++; @@ -346,15 +346,15 @@ int qib_make_ud_req(struct qib_qp *qp) lrh0 |= 0xF000; /* Set VL (see ch. 13.5.3.1) */ else lrh0 |= ibp->sl_to_vl[ah_attr->sl] << 12; - qp->s_hdr->lrh[0] = cpu_to_be16(lrh0); - qp->s_hdr->lrh[1] = cpu_to_be16(ah_attr->dlid); /* DEST LID */ - qp->s_hdr->lrh[2] = cpu_to_be16(qp->s_hdrwords + nwords + SIZE_OF_CRC); + qp->s_hdr.lrh[0] = cpu_to_be16(lrh0); + qp->s_hdr.lrh[1] = cpu_to_be16(ah_attr->dlid); /* DEST LID */ + qp->s_hdr.lrh[2] = cpu_to_be16(qp->s_hdrwords + nwords + SIZE_OF_CRC); lid = ppd->lid; if (lid) { lid |= ah_attr->src_path_bits & ((1 << ppd->lmc) - 1); - qp->s_hdr->lrh[3] = cpu_to_be16(lid); + qp->s_hdr.lrh[3] = cpu_to_be16(lid); } else - qp->s_hdr->lrh[3] = IB_LID_PERMISSIVE; + qp->s_hdr.lrh[3] = IB_LID_PERMISSIVE; if (wqe->wr.send_flags & IB_SEND_SOLICITED) bth0 |= IB_BTH_SOLICITED; bth0 |= extra_bytes << 20; diff --git a/trunk/drivers/infiniband/hw/qib/qib_verbs.h b/trunk/drivers/infiniband/hw/qib/qib_verbs.h index 487606024659..0c19ef0c4123 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_verbs.h +++ b/trunk/drivers/infiniband/hw/qib/qib_verbs.h @@ -367,10 +367,9 @@ struct qib_rwq { struct qib_rq { struct qib_rwq *wq; + spinlock_t lock; /* protect changes in this struct */ u32 size; /* size of RWQE array */ u8 max_sge; - spinlock_t lock /* protect changes in this struct */ - ____cacheline_aligned_in_smp; }; struct qib_srq { @@ -413,75 +412,31 @@ struct qib_ack_entry { */ struct qib_qp { struct ib_qp ibqp; - /* read mostly fields above and below */ + struct qib_qp *next; /* link list for QPN hash table */ + struct qib_qp *timer_next; /* link list for qib_ib_timer() */ + struct list_head iowait; /* link for wait PIO buf */ + struct list_head rspwait; /* link for waititing to respond */ struct ib_ah_attr remote_ah_attr; struct ib_ah_attr alt_ah_attr; - struct qib_qp *next; /* link list for QPN hash table */ - struct qib_swqe *s_wq; /* send work queue */ - struct qib_mmap_info *ip; - struct qib_ib_header *s_hdr; /* next packet header to send */ - unsigned long timeout_jiffies; /* computed from timeout */ - - enum ib_mtu path_mtu; - u32 remote_qpn; - u32 pmtu; /* decoded from path_mtu */ - u32 qkey; /* QKEY for this QP (for UD or RD) */ - u32 s_size; /* send work queue size */ - u32 s_rnr_timeout; /* number of milliseconds for RNR timeout */ - - u8 state; /* QP state */ - u8 qp_access_flags; - u8 alt_timeout; /* Alternate path timeout for this QP */ - u8 timeout; /* Timeout for this QP */ - u8 s_srate; - u8 s_mig_state; - u8 port_num; - u8 s_pkey_index; /* PKEY index to use */ - u8 s_alt_pkey_index; /* Alternate path PKEY index to use */ - u8 r_max_rd_atomic; /* max number of RDMA read/atomic to receive */ - u8 s_max_rd_atomic; /* max number of RDMA read/atomic to send */ - u8 s_retry_cnt; /* number of times to retry */ - u8 s_rnr_retry_cnt; - u8 r_min_rnr_timer; /* retry timeout value for RNR NAKs */ - u8 s_max_sge; /* size of s_wq->sg_list */ - u8 s_draining; - - /* start of read/write fields */ - - atomic_t refcount ____cacheline_aligned_in_smp; + struct qib_ib_header s_hdr; /* next packet header to send */ + atomic_t refcount; wait_queue_head_t wait; - - - struct qib_ack_entry s_ack_queue[QIB_MAX_RDMA_ATOMIC + 1] - ____cacheline_aligned_in_smp; - struct qib_sge_state s_rdma_read_sge; - - spinlock_t r_lock ____cacheline_aligned_in_smp; /* used for APM */ - unsigned long r_aflags; - u64 r_wr_id; /* ID for current receive WQE */ - u32 r_ack_psn; /* PSN for next ACK or atomic ACK */ - u32 r_len; /* total length of r_sge */ - u32 r_rcv_len; /* receive data len processed */ - u32 r_psn; /* expected rcv packet sequence number */ - u32 r_msn; /* message sequence number */ - - u8 r_state; /* opcode of last packet received */ - u8 r_flags; - u8 r_head_ack_queue; /* index into s_ack_queue[] */ - - struct list_head rspwait; /* link for waititing to respond */ - - struct qib_sge_state r_sge; /* current receive data */ - struct qib_rq r_rq; /* receive work queue */ - - spinlock_t s_lock ____cacheline_aligned_in_smp; + wait_queue_head_t wait_dma; + struct timer_list s_timer; + struct work_struct s_work; + struct qib_mmap_info *ip; struct qib_sge_state *s_cur_sge; - u32 s_flags; struct qib_verbs_txreq *s_tx; - struct qib_swqe *s_wqe; - struct qib_sge_state s_sge; /* current send request data */ struct qib_mregion *s_rdma_mr; + struct qib_sge_state s_sge; /* current send request data */ + struct qib_ack_entry s_ack_queue[QIB_MAX_RDMA_ATOMIC + 1]; + struct qib_sge_state s_ack_rdma_sge; + struct qib_sge_state s_rdma_read_sge; + struct qib_sge_state r_sge; /* current receive data */ + spinlock_t r_lock; /* used for APM */ + spinlock_t s_lock; atomic_t s_dma_busy; + u32 s_flags; u32 s_cur_size; /* size of send packet in bytes */ u32 s_len; /* total length of s_sge */ u32 s_rdma_read_len; /* total length of s_rdma_read_sge */ @@ -492,34 +447,60 @@ struct qib_qp { u32 s_psn; /* current packet sequence number */ u32 s_ack_rdma_psn; /* PSN for sending RDMA read responses */ u32 s_ack_psn; /* PSN for acking sends and RDMA writes */ - u32 s_head; /* new entries added here */ - u32 s_tail; /* next entry to process */ - u32 s_cur; /* current work queue entry */ - u32 s_acked; /* last un-ACK'ed entry */ - u32 s_last; /* last completed entry */ - u32 s_ssn; /* SSN of tail entry */ - u32 s_lsn; /* limit sequence number (credit) */ + u32 s_rnr_timeout; /* number of milliseconds for RNR timeout */ + u32 r_ack_psn; /* PSN for next ACK or atomic ACK */ + u64 r_wr_id; /* ID for current receive WQE */ + unsigned long r_aflags; + u32 r_len; /* total length of r_sge */ + u32 r_rcv_len; /* receive data len processed */ + u32 r_psn; /* expected rcv packet sequence number */ + u32 r_msn; /* message sequence number */ u16 s_hdrwords; /* size of s_hdr in 32 bit words */ u16 s_rdma_ack_cnt; + u8 state; /* QP state */ u8 s_state; /* opcode of last packet sent */ u8 s_ack_state; /* opcode of packet to ACK */ u8 s_nak_state; /* non-zero if NAK is pending */ + u8 r_state; /* opcode of last packet received */ u8 r_nak_state; /* non-zero if NAK is pending */ + u8 r_min_rnr_timer; /* retry timeout value for RNR NAKs */ + u8 r_flags; + u8 r_max_rd_atomic; /* max number of RDMA read/atomic to receive */ + u8 r_head_ack_queue; /* index into s_ack_queue[] */ + u8 qp_access_flags; + u8 s_max_sge; /* size of s_wq->sg_list */ + u8 s_retry_cnt; /* number of times to retry */ + u8 s_rnr_retry_cnt; u8 s_retry; /* requester retry counter */ u8 s_rnr_retry; /* requester RNR retry counter */ + u8 s_pkey_index; /* PKEY index to use */ + u8 s_alt_pkey_index; /* Alternate path PKEY index to use */ + u8 s_max_rd_atomic; /* max number of RDMA read/atomic to send */ u8 s_num_rd_atomic; /* number of RDMA read/atomic pending */ u8 s_tail_ack_queue; /* index into s_ack_queue[] */ - - struct qib_sge_state s_ack_rdma_sge; - struct timer_list s_timer; - struct list_head iowait; /* link for wait PIO buf */ - - struct work_struct s_work; - - wait_queue_head_t wait_dma; - - struct qib_sge r_sg_list[0] /* verified SGEs */ - ____cacheline_aligned_in_smp; + u8 s_srate; + u8 s_draining; + u8 s_mig_state; + u8 timeout; /* Timeout for this QP */ + u8 alt_timeout; /* Alternate path timeout for this QP */ + u8 port_num; + enum ib_mtu path_mtu; + u32 pmtu; /* decoded from path_mtu */ + u32 remote_qpn; + u32 qkey; /* QKEY for this QP (for UD or RD) */ + u32 s_size; /* send work queue size */ + u32 s_head; /* new entries added here */ + u32 s_tail; /* next entry to process */ + u32 s_cur; /* current work queue entry */ + u32 s_acked; /* last un-ACK'ed entry */ + u32 s_last; /* last completed entry */ + u32 s_ssn; /* SSN of tail entry */ + u32 s_lsn; /* limit sequence number (credit) */ + unsigned long timeout_jiffies; /* computed from timeout */ + struct qib_swqe *s_wq; /* send work queue */ + struct qib_swqe *s_wqe; + struct qib_rq r_rq; /* receive work queue */ + struct qib_sge r_sg_list[0]; /* verified SGEs */ }; /* diff --git a/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c b/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c index 0ab8c9cc3a78..db43b3117168 100644 --- a/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -573,9 +573,10 @@ iscsi_iser_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, err = iser_connect(ib_conn, NULL, (struct sockaddr_in *)dst_addr, non_blocking); - if (err) + if (err) { + iscsi_destroy_endpoint(ep); return ERR_PTR(err); - + } return ep; } diff --git a/trunk/drivers/infiniband/ulp/iser/iser_verbs.c b/trunk/drivers/infiniband/ulp/iser/iser_verbs.c index 2dddabd8fcf9..14224ba44fd8 100644 --- a/trunk/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/trunk/drivers/infiniband/ulp/iser/iser_verbs.c @@ -613,9 +613,8 @@ int iser_connect(struct iser_conn *ib_conn, ib_conn->cma_id = NULL; addr_failure: ib_conn->state = ISER_CONN_DOWN; - iser_conn_put(ib_conn, 1); /* deref ib conn's cma id */ connect_failure: - iser_conn_put(ib_conn, 1); /* deref ib conn deallocate */ + iser_conn_release(ib_conn, 1); return err; } diff --git a/trunk/drivers/infiniband/ulp/srpt/ib_srpt.c b/trunk/drivers/infiniband/ulp/srpt/ib_srpt.c index 5f6b7f63cdef..daf21b899999 100644 --- a/trunk/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/trunk/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -1099,8 +1099,9 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch, dir = cmd->data_direction; BUG_ON(dir == DMA_NONE); - ioctx->sg = sg = sg_orig = cmd->t_data_sg; - ioctx->sg_cnt = sg_cnt = cmd->t_data_nents; + transport_do_task_sg_chain(cmd); + ioctx->sg = sg = sg_orig = cmd->t_tasks_sg_chained; + ioctx->sg_cnt = sg_cnt = cmd->t_tasks_sg_chained_no; count = ib_dma_map_sg(ch->sport->sdev->device, sg, sg_cnt, opposite_dma_dir(dir)); @@ -1768,7 +1769,7 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch, kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref); goto send_sense; } - ret = target_setup_cmd_from_cdb(cmd, srp_cmd->cdb); + ret = transport_generic_allocate_tasks(cmd, srp_cmd->cdb); if (ret < 0) { kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref); if (cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) { @@ -4003,6 +4004,9 @@ static int __init srpt_init_module(void) srpt_target->tf_ops = srpt_template; + /* Enable SG chaining */ + srpt_target->tf_ops.task_sg_chaining = true; + /* * Set up default attribute lists. */ diff --git a/trunk/drivers/iommu/Makefile b/trunk/drivers/iommu/Makefile index 3e5e82ae9f0d..7ad7a3bc1242 100644 --- a/trunk/drivers/iommu/Makefile +++ b/trunk/drivers/iommu/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o obj-$(CONFIG_DMAR_TABLE) += dmar.o obj-$(CONFIG_INTEL_IOMMU) += iova.o intel-iommu.o -obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o +obj-$(CONFIG_IRQ_REMAP) += intr_remapping.o obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o obj-$(CONFIG_OMAP_IOVMM) += omap-iovmm.o obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o diff --git a/trunk/drivers/iommu/dmar.c b/trunk/drivers/iommu/dmar.c index 3a74e4410fc0..35c1e17fce1d 100644 --- a/trunk/drivers/iommu/dmar.c +++ b/trunk/drivers/iommu/dmar.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #define PREFIX "DMAR: " @@ -556,7 +555,7 @@ int __init detect_intel_iommu(void) dmar = (struct acpi_table_dmar *) dmar_tbl; - if (ret && irq_remapping_enabled && cpu_has_x2apic && + if (ret && intr_remapping_enabled && cpu_has_x2apic && dmar->flags & 0x1) printk(KERN_INFO "Queued invalidation will be enabled to support x2apic and Intr-remapping.\n"); @@ -1042,7 +1041,7 @@ static const char *dma_remap_fault_reasons[] = "non-zero reserved fields in PTE", }; -static const char *irq_remap_fault_reasons[] = +static const char *intr_remap_fault_reasons[] = { "Detected reserved fields in the decoded interrupt-remapped request", "Interrupt index exceeded the interrupt-remapping table size", @@ -1057,10 +1056,10 @@ static const char *irq_remap_fault_reasons[] = const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type) { - if (fault_reason >= 0x20 && (fault_reason - 0x20 < - ARRAY_SIZE(irq_remap_fault_reasons))) { + if (fault_reason >= 0x20 && (fault_reason <= 0x20 + + ARRAY_SIZE(intr_remap_fault_reasons))) { *fault_type = INTR_REMAP; - return irq_remap_fault_reasons[fault_reason - 0x20]; + return intr_remap_fault_reasons[fault_reason - 0x20]; } else if (fault_reason < ARRAY_SIZE(dma_remap_fault_reasons)) { *fault_type = DMA_REMAP; return dma_remap_fault_reasons[fault_reason]; diff --git a/trunk/drivers/iommu/intel-iommu.c b/trunk/drivers/iommu/intel-iommu.c index bf2fbaad5e22..f93d5ac8f81c 100644 --- a/trunk/drivers/iommu/intel-iommu.c +++ b/trunk/drivers/iommu/intel-iommu.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include @@ -4083,7 +4082,7 @@ static int intel_iommu_domain_has_cap(struct iommu_domain *domain, if (cap == IOMMU_CAP_CACHE_COHERENCY) return dmar_domain->iommu_snooping; if (cap == IOMMU_CAP_INTR_REMAP) - return irq_remapping_enabled; + return intr_remapping_enabled; return 0; } diff --git a/trunk/drivers/iommu/intel_irq_remapping.c b/trunk/drivers/iommu/intr_remapping.c similarity index 66% rename from trunk/drivers/iommu/intel_irq_remapping.c rename to trunk/drivers/iommu/intr_remapping.c index 6d347064b8b0..6777ca049471 100644 --- a/trunk/drivers/iommu/intel_irq_remapping.c +++ b/trunk/drivers/iommu/intr_remapping.c @@ -10,33 +10,49 @@ #include #include #include +#include "intr_remapping.h" #include -#include #include -#include -#include "irq_remapping.h" +static struct ioapic_scope ir_ioapic[MAX_IO_APICS]; +static struct hpet_scope ir_hpet[MAX_HPET_TBS]; +static int ir_ioapic_num, ir_hpet_num; +int intr_remapping_enabled; -struct ioapic_scope { - struct intel_iommu *iommu; - unsigned int id; - unsigned int bus; /* PCI bus number */ - unsigned int devfn; /* PCI devfn number */ -}; +static int disable_intremap; +static int disable_sourceid_checking; +static int no_x2apic_optout; -struct hpet_scope { - struct intel_iommu *iommu; - u8 id; - unsigned int bus; - unsigned int devfn; -}; +static __init int setup_nointremap(char *str) +{ + disable_intremap = 1; + return 0; +} +early_param("nointremap", setup_nointremap); -#define IR_X2APIC_MODE(mode) (mode ? (1 << 11) : 0) -#define IRTE_DEST(dest) ((x2apic_mode) ? dest : dest << 8) +static __init int setup_intremap(char *str) +{ + if (!str) + return -EINVAL; -static struct ioapic_scope ir_ioapic[MAX_IO_APICS]; -static struct hpet_scope ir_hpet[MAX_HPET_TBS]; -static int ir_ioapic_num, ir_hpet_num; + while (*str) { + if (!strncmp(str, "on", 2)) + disable_intremap = 0; + else if (!strncmp(str, "off", 3)) + disable_intremap = 1; + else if (!strncmp(str, "nosid", 5)) + disable_sourceid_checking = 1; + else if (!strncmp(str, "no_x2apic_optout", 16)) + no_x2apic_optout = 1; + + str += strcspn(str, ","); + while (*str == ',') + str++; + } + + return 0; +} +early_param("intremap", setup_intremap); static DEFINE_RAW_SPINLOCK(irq_2_ir_lock); @@ -64,7 +80,7 @@ int get_irte(int irq, struct irte *entry) return 0; } -static int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) +int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) { struct ir_table *table = iommu->ir_table; struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); @@ -136,7 +152,7 @@ static int qi_flush_iec(struct intel_iommu *iommu, int index, int mask) return qi_submit_sync(&desc, iommu); } -static int map_irq_to_irte_handle(int irq, u16 *sub_handle) +int map_irq_to_irte_handle(int irq, u16 *sub_handle) { struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); unsigned long flags; @@ -152,7 +168,7 @@ static int map_irq_to_irte_handle(int irq, u16 *sub_handle) return index; } -static int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) +int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) { struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); unsigned long flags; @@ -172,7 +188,7 @@ static int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subha return 0; } -static int modify_irte(int irq, struct irte *irte_modified) +int modify_irte(int irq, struct irte *irte_modified) { struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); struct intel_iommu *iommu; @@ -200,7 +216,7 @@ static int modify_irte(int irq, struct irte *irte_modified) return rc; } -static struct intel_iommu *map_hpet_to_ir(u8 hpet_id) +struct intel_iommu *map_hpet_to_ir(u8 hpet_id) { int i; @@ -210,7 +226,7 @@ static struct intel_iommu *map_hpet_to_ir(u8 hpet_id) return NULL; } -static struct intel_iommu *map_ioapic_to_ir(int apic) +struct intel_iommu *map_ioapic_to_ir(int apic) { int i; @@ -220,7 +236,7 @@ static struct intel_iommu *map_ioapic_to_ir(int apic) return NULL; } -static struct intel_iommu *map_dev_to_ir(struct pci_dev *dev) +struct intel_iommu *map_dev_to_ir(struct pci_dev *dev) { struct dmar_drhd_unit *drhd; @@ -254,7 +270,7 @@ static int clear_entries(struct irq_2_iommu *irq_iommu) return qi_flush_iec(iommu, index, irq_iommu->irte_mask); } -static int free_irte(int irq) +int free_irte(int irq) { struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); unsigned long flags; @@ -312,7 +328,7 @@ static void set_irte_sid(struct irte *irte, unsigned int svt, irte->sid = sid; } -static int set_ioapic_sid(struct irte *irte, int apic) +int set_ioapic_sid(struct irte *irte, int apic) { int i; u16 sid = 0; @@ -337,7 +353,7 @@ static int set_ioapic_sid(struct irte *irte, int apic) return 0; } -static int set_hpet_sid(struct irte *irte, u8 id) +int set_hpet_sid(struct irte *irte, u8 id) { int i; u16 sid = 0; @@ -367,7 +383,7 @@ static int set_hpet_sid(struct irte *irte, u8 id) return 0; } -static int set_msi_sid(struct irte *irte, struct pci_dev *dev) +int set_msi_sid(struct irte *irte, struct pci_dev *dev) { struct pci_dev *bridge; @@ -394,7 +410,7 @@ static int set_msi_sid(struct irte *irte, struct pci_dev *dev) return 0; } -static void iommu_set_irq_remapping(struct intel_iommu *iommu, int mode) +static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode) { u64 addr; u32 sts; @@ -434,7 +450,7 @@ static void iommu_set_irq_remapping(struct intel_iommu *iommu, int mode) } -static int intel_setup_irq_remapping(struct intel_iommu *iommu, int mode) +static int setup_intr_remapping(struct intel_iommu *iommu, int mode) { struct ir_table *ir_table; struct page *pages; @@ -457,14 +473,14 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu, int mode) ir_table->base = page_address(pages); - iommu_set_irq_remapping(iommu, mode); + iommu_set_intr_remapping(iommu, mode); return 0; } /* * Disable Interrupt Remapping. */ -static void iommu_disable_irq_remapping(struct intel_iommu *iommu) +static void iommu_disable_intr_remapping(struct intel_iommu *iommu) { unsigned long flags; u32 sts; @@ -503,11 +519,11 @@ static int __init dmar_x2apic_optout(void) return dmar->flags & DMAR_X2APIC_OPT_OUT; } -static int __init intel_irq_remapping_supported(void) +int __init intr_remapping_supported(void) { struct dmar_drhd_unit *drhd; - if (disable_irq_remap) + if (disable_intremap) return 0; if (!dmar_ir_support()) @@ -523,7 +539,7 @@ static int __init intel_irq_remapping_supported(void) return 1; } -static int __init intel_enable_irq_remapping(void) +int __init enable_intr_remapping(void) { struct dmar_drhd_unit *drhd; int setup = 0; @@ -561,7 +577,7 @@ static int __init intel_enable_irq_remapping(void) * Disable intr remapping and queued invalidation, if already * enabled prior to OS handover. */ - iommu_disable_irq_remapping(iommu); + iommu_disable_intr_remapping(iommu); dmar_disable_qi(iommu); } @@ -607,7 +623,7 @@ static int __init intel_enable_irq_remapping(void) if (!ecap_ir_support(iommu->ecap)) continue; - if (intel_setup_irq_remapping(iommu, eim)) + if (setup_intr_remapping(iommu, eim)) goto error; setup = 1; @@ -616,7 +632,7 @@ static int __init intel_enable_irq_remapping(void) if (!setup) goto error; - irq_remapping_enabled = 1; + intr_remapping_enabled = 1; pr_info("Enabled IRQ remapping in %s mode\n", eim ? "x2apic" : "xapic"); return eim ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE; @@ -759,14 +775,14 @@ int __init parse_ioapics_under_ir(void) int __init ir_dev_scope_init(void) { - if (!irq_remapping_enabled) + if (!intr_remapping_enabled) return 0; return dmar_dev_scope_init(); } rootfs_initcall(ir_dev_scope_init); -static void disable_irq_remapping(void) +void disable_intr_remapping(void) { struct dmar_drhd_unit *drhd; struct intel_iommu *iommu = NULL; @@ -778,11 +794,11 @@ static void disable_irq_remapping(void) if (!ecap_ir_support(iommu->ecap)) continue; - iommu_disable_irq_remapping(iommu); + iommu_disable_intr_remapping(iommu); } } -static int reenable_irq_remapping(int eim) +int reenable_intr_remapping(int eim) { struct dmar_drhd_unit *drhd; int setup = 0; @@ -800,7 +816,7 @@ static int reenable_irq_remapping(int eim) continue; /* Set up interrupt remapping for iommu.*/ - iommu_set_irq_remapping(iommu, eim); + iommu_set_intr_remapping(iommu, eim); setup = 1; } @@ -816,254 +832,3 @@ static int reenable_irq_remapping(int eim) return -1; } -static void prepare_irte(struct irte *irte, int vector, - unsigned int dest) -{ - memset(irte, 0, sizeof(*irte)); - - irte->present = 1; - irte->dst_mode = apic->irq_dest_mode; - /* - * Trigger mode in the IRTE will always be edge, and for IO-APIC, the - * actual level or edge trigger will be setup in the IO-APIC - * RTE. This will help simplify level triggered irq migration. - * For more details, see the comments (in io_apic.c) explainig IO-APIC - * irq migration in the presence of interrupt-remapping. - */ - irte->trigger_mode = 0; - irte->dlvry_mode = apic->irq_delivery_mode; - irte->vector = vector; - irte->dest_id = IRTE_DEST(dest); - irte->redir_hint = 1; -} - -static int intel_setup_ioapic_entry(int irq, - struct IO_APIC_route_entry *route_entry, - unsigned int destination, int vector, - struct io_apic_irq_attr *attr) -{ - int ioapic_id = mpc_ioapic_id(attr->ioapic); - struct intel_iommu *iommu = map_ioapic_to_ir(ioapic_id); - struct IR_IO_APIC_route_entry *entry; - struct irte irte; - int index; - - if (!iommu) { - pr_warn("No mapping iommu for ioapic %d\n", ioapic_id); - return -ENODEV; - } - - entry = (struct IR_IO_APIC_route_entry *)route_entry; - - index = alloc_irte(iommu, irq, 1); - if (index < 0) { - pr_warn("Failed to allocate IRTE for ioapic %d\n", ioapic_id); - return -ENOMEM; - } - - prepare_irte(&irte, vector, destination); - - /* Set source-id of interrupt request */ - set_ioapic_sid(&irte, ioapic_id); - - modify_irte(irq, &irte); - - apic_printk(APIC_VERBOSE, KERN_DEBUG "IOAPIC[%d]: " - "Set IRTE entry (P:%d FPD:%d Dst_Mode:%d " - "Redir_hint:%d Trig_Mode:%d Dlvry_Mode:%X " - "Avail:%X Vector:%02X Dest:%08X " - "SID:%04X SQ:%X SVT:%X)\n", - attr->ioapic, irte.present, irte.fpd, irte.dst_mode, - irte.redir_hint, irte.trigger_mode, irte.dlvry_mode, - irte.avail, irte.vector, irte.dest_id, - irte.sid, irte.sq, irte.svt); - - memset(entry, 0, sizeof(*entry)); - - entry->index2 = (index >> 15) & 0x1; - entry->zero = 0; - entry->format = 1; - entry->index = (index & 0x7fff); - /* - * IO-APIC RTE will be configured with virtual vector. - * irq handler will do the explicit EOI to the io-apic. - */ - entry->vector = attr->ioapic_pin; - entry->mask = 0; /* enable IRQ */ - entry->trigger = attr->trigger; - entry->polarity = attr->polarity; - - /* Mask level triggered irqs. - * Use IRQ_DELAYED_DISABLE for edge triggered irqs. - */ - if (attr->trigger) - entry->mask = 1; - - return 0; -} - -#ifdef CONFIG_SMP -/* - * Migrate the IO-APIC irq in the presence of intr-remapping. - * - * For both level and edge triggered, irq migration is a simple atomic - * update(of vector and cpu destination) of IRTE and flush the hardware cache. - * - * For level triggered, we eliminate the io-apic RTE modification (with the - * updated vector information), by using a virtual vector (io-apic pin number). - * Real vector that is used for interrupting cpu will be coming from - * the interrupt-remapping table entry. - * - * As the migration is a simple atomic update of IRTE, the same mechanism - * is used to migrate MSI irq's in the presence of interrupt-remapping. - */ -static int -intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, - bool force) -{ - struct irq_cfg *cfg = data->chip_data; - unsigned int dest, irq = data->irq; - struct irte irte; - - if (!cpumask_intersects(mask, cpu_online_mask)) - return -EINVAL; - - if (get_irte(irq, &irte)) - return -EBUSY; - - if (assign_irq_vector(irq, cfg, mask)) - return -EBUSY; - - dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask); - - irte.vector = cfg->vector; - irte.dest_id = IRTE_DEST(dest); - - /* - * Atomically updates the IRTE with the new destination, vector - * and flushes the interrupt entry cache. - */ - modify_irte(irq, &irte); - - /* - * After this point, all the interrupts will start arriving - * at the new destination. So, time to cleanup the previous - * vector allocation. - */ - if (cfg->move_in_progress) - send_cleanup_vector(cfg); - - cpumask_copy(data->affinity, mask); - return 0; -} -#endif - -static void intel_compose_msi_msg(struct pci_dev *pdev, - unsigned int irq, unsigned int dest, - struct msi_msg *msg, u8 hpet_id) -{ - struct irq_cfg *cfg; - struct irte irte; - u16 sub_handle = 0; - int ir_index; - - cfg = irq_get_chip_data(irq); - - ir_index = map_irq_to_irte_handle(irq, &sub_handle); - BUG_ON(ir_index == -1); - - prepare_irte(&irte, cfg->vector, dest); - - /* Set source-id of interrupt request */ - if (pdev) - set_msi_sid(&irte, pdev); - else - set_hpet_sid(&irte, hpet_id); - - modify_irte(irq, &irte); - - msg->address_hi = MSI_ADDR_BASE_HI; - msg->data = sub_handle; - msg->address_lo = MSI_ADDR_BASE_LO | MSI_ADDR_IR_EXT_INT | - MSI_ADDR_IR_SHV | - MSI_ADDR_IR_INDEX1(ir_index) | - MSI_ADDR_IR_INDEX2(ir_index); -} - -/* - * Map the PCI dev to the corresponding remapping hardware unit - * and allocate 'nvec' consecutive interrupt-remapping table entries - * in it. - */ -static int intel_msi_alloc_irq(struct pci_dev *dev, int irq, int nvec) -{ - struct intel_iommu *iommu; - int index; - - iommu = map_dev_to_ir(dev); - if (!iommu) { - printk(KERN_ERR - "Unable to map PCI %s to iommu\n", pci_name(dev)); - return -ENOENT; - } - - index = alloc_irte(iommu, irq, nvec); - if (index < 0) { - printk(KERN_ERR - "Unable to allocate %d IRTE for PCI %s\n", nvec, - pci_name(dev)); - return -ENOSPC; - } - return index; -} - -static int intel_msi_setup_irq(struct pci_dev *pdev, unsigned int irq, - int index, int sub_handle) -{ - struct intel_iommu *iommu; - - iommu = map_dev_to_ir(pdev); - if (!iommu) - return -ENOENT; - /* - * setup the mapping between the irq and the IRTE - * base index, the sub_handle pointing to the - * appropriate interrupt remap table entry. - */ - set_irte_irq(irq, iommu, index, sub_handle); - - return 0; -} - -static int intel_setup_hpet_msi(unsigned int irq, unsigned int id) -{ - struct intel_iommu *iommu = map_hpet_to_ir(id); - int index; - - if (!iommu) - return -1; - - index = alloc_irte(iommu, irq, 1); - if (index < 0) - return -1; - - return 0; -} - -struct irq_remap_ops intel_irq_remap_ops = { - .supported = intel_irq_remapping_supported, - .prepare = dmar_table_init, - .enable = intel_enable_irq_remapping, - .disable = disable_irq_remapping, - .reenable = reenable_irq_remapping, - .enable_faulting = enable_drhd_fault_handling, - .setup_ioapic_entry = intel_setup_ioapic_entry, -#ifdef CONFIG_SMP - .set_affinity = intel_ioapic_set_affinity, -#endif - .free_irq = free_irte, - .compose_msi_msg = intel_compose_msi_msg, - .msi_alloc_irq = intel_msi_alloc_irq, - .msi_setup_irq = intel_msi_setup_irq, - .setup_hpet_msi = intel_setup_hpet_msi, -}; diff --git a/trunk/drivers/iommu/intr_remapping.h b/trunk/drivers/iommu/intr_remapping.h new file mode 100644 index 000000000000..5662fecfee60 --- /dev/null +++ b/trunk/drivers/iommu/intr_remapping.h @@ -0,0 +1,17 @@ +#include + +struct ioapic_scope { + struct intel_iommu *iommu; + unsigned int id; + unsigned int bus; /* PCI bus number */ + unsigned int devfn; /* PCI devfn number */ +}; + +struct hpet_scope { + struct intel_iommu *iommu; + u8 id; + unsigned int bus; + unsigned int devfn; +}; + +#define IR_X2APIC_MODE(mode) (mode ? (1 << 11) : 0) diff --git a/trunk/drivers/iommu/irq_remapping.c b/trunk/drivers/iommu/irq_remapping.c deleted file mode 100644 index 40cda8e98d87..000000000000 --- a/trunk/drivers/iommu/irq_remapping.c +++ /dev/null @@ -1,166 +0,0 @@ -#include -#include -#include - -#include "irq_remapping.h" - -int irq_remapping_enabled; - -int disable_irq_remap; -int disable_sourceid_checking; -int no_x2apic_optout; - -static struct irq_remap_ops *remap_ops; - -static __init int setup_nointremap(char *str) -{ - disable_irq_remap = 1; - return 0; -} -early_param("nointremap", setup_nointremap); - -static __init int setup_irqremap(char *str) -{ - if (!str) - return -EINVAL; - - while (*str) { - if (!strncmp(str, "on", 2)) - disable_irq_remap = 0; - else if (!strncmp(str, "off", 3)) - disable_irq_remap = 1; - else if (!strncmp(str, "nosid", 5)) - disable_sourceid_checking = 1; - else if (!strncmp(str, "no_x2apic_optout", 16)) - no_x2apic_optout = 1; - - str += strcspn(str, ","); - while (*str == ',') - str++; - } - - return 0; -} -early_param("intremap", setup_irqremap); - -void __init setup_irq_remapping_ops(void) -{ - remap_ops = &intel_irq_remap_ops; -} - -int irq_remapping_supported(void) -{ - if (disable_irq_remap) - return 0; - - if (!remap_ops || !remap_ops->supported) - return 0; - - return remap_ops->supported(); -} - -int __init irq_remapping_prepare(void) -{ - if (!remap_ops || !remap_ops->prepare) - return -ENODEV; - - return remap_ops->prepare(); -} - -int __init irq_remapping_enable(void) -{ - if (!remap_ops || !remap_ops->enable) - return -ENODEV; - - return remap_ops->enable(); -} - -void irq_remapping_disable(void) -{ - if (!remap_ops || !remap_ops->disable) - return; - - remap_ops->disable(); -} - -int irq_remapping_reenable(int mode) -{ - if (!remap_ops || !remap_ops->reenable) - return 0; - - return remap_ops->reenable(mode); -} - -int __init irq_remap_enable_fault_handling(void) -{ - if (!remap_ops || !remap_ops->enable_faulting) - return -ENODEV; - - return remap_ops->enable_faulting(); -} - -int setup_ioapic_remapped_entry(int irq, - struct IO_APIC_route_entry *entry, - unsigned int destination, int vector, - struct io_apic_irq_attr *attr) -{ - if (!remap_ops || !remap_ops->setup_ioapic_entry) - return -ENODEV; - - return remap_ops->setup_ioapic_entry(irq, entry, destination, - vector, attr); -} - -#ifdef CONFIG_SMP -int set_remapped_irq_affinity(struct irq_data *data, const struct cpumask *mask, - bool force) -{ - if (!remap_ops || !remap_ops->set_affinity) - return 0; - - return remap_ops->set_affinity(data, mask, force); -} -#endif - -void free_remapped_irq(int irq) -{ - if (!remap_ops || !remap_ops->free_irq) - return; - - remap_ops->free_irq(irq); -} - -void compose_remapped_msi_msg(struct pci_dev *pdev, - unsigned int irq, unsigned int dest, - struct msi_msg *msg, u8 hpet_id) -{ - if (!remap_ops || !remap_ops->compose_msi_msg) - return; - - remap_ops->compose_msi_msg(pdev, irq, dest, msg, hpet_id); -} - -int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec) -{ - if (!remap_ops || !remap_ops->msi_alloc_irq) - return -ENODEV; - - return remap_ops->msi_alloc_irq(pdev, irq, nvec); -} - -int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq, - int index, int sub_handle) -{ - if (!remap_ops || !remap_ops->msi_setup_irq) - return -ENODEV; - - return remap_ops->msi_setup_irq(pdev, irq, index, sub_handle); -} - -int setup_hpet_msi_remapped(unsigned int irq, unsigned int id) -{ - if (!remap_ops || !remap_ops->setup_hpet_msi) - return -ENODEV; - - return remap_ops->setup_hpet_msi(irq, id); -} diff --git a/trunk/drivers/iommu/irq_remapping.h b/trunk/drivers/iommu/irq_remapping.h deleted file mode 100644 index be9d72950c51..000000000000 --- a/trunk/drivers/iommu/irq_remapping.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2012 Advanced Micro Devices, Inc. - * Author: Joerg Roedel - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * This header file contains stuff that is shared between different interrupt - * remapping drivers but with no need to be visible outside of the IOMMU layer. - */ - -#ifndef __IRQ_REMAPPING_H -#define __IRQ_REMAPPING_H - -#ifdef CONFIG_IRQ_REMAP - -struct IO_APIC_route_entry; -struct io_apic_irq_attr; -struct irq_data; -struct cpumask; -struct pci_dev; -struct msi_msg; - -extern int disable_irq_remap; -extern int disable_sourceid_checking; -extern int no_x2apic_optout; - -struct irq_remap_ops { - /* Check whether Interrupt Remapping is supported */ - int (*supported)(void); - - /* Initializes hardware and makes it ready for remapping interrupts */ - int (*prepare)(void); - - /* Enables the remapping hardware */ - int (*enable)(void); - - /* Disables the remapping hardware */ - void (*disable)(void); - - /* Reenables the remapping hardware */ - int (*reenable)(int); - - /* Enable fault handling */ - int (*enable_faulting)(void); - - /* IO-APIC setup routine */ - int (*setup_ioapic_entry)(int irq, struct IO_APIC_route_entry *, - unsigned int, int, - struct io_apic_irq_attr *); - -#ifdef CONFIG_SMP - /* Set the CPU affinity of a remapped interrupt */ - int (*set_affinity)(struct irq_data *data, const struct cpumask *mask, - bool force); -#endif - - /* Free an IRQ */ - int (*free_irq)(int); - - /* Create MSI msg to use for interrupt remapping */ - void (*compose_msi_msg)(struct pci_dev *, - unsigned int, unsigned int, - struct msi_msg *, u8); - - /* Allocate remapping resources for MSI */ - int (*msi_alloc_irq)(struct pci_dev *, int, int); - - /* Setup the remapped MSI irq */ - int (*msi_setup_irq)(struct pci_dev *, unsigned int, int, int); - - /* Setup interrupt remapping for an HPET MSI */ - int (*setup_hpet_msi)(unsigned int, unsigned int); -}; - -extern struct irq_remap_ops intel_irq_remap_ops; - -#endif /* CONFIG_IRQ_REMAP */ - -#endif /* __IRQ_REMAPPING_H */ diff --git a/trunk/drivers/isdn/hardware/mISDN/avmfritz.c b/trunk/drivers/isdn/hardware/mISDN/avmfritz.c index c08fc605e56b..6bf2c58795a3 100644 --- a/trunk/drivers/isdn/hardware/mISDN/avmfritz.c +++ b/trunk/drivers/isdn/hardware/mISDN/avmfritz.c @@ -30,7 +30,7 @@ #include "ipac.h" -#define AVMFRITZ_REV "2.3" +#define AVMFRITZ_REV "2.1" static int AVM_cnt; static int debug; @@ -69,7 +69,6 @@ enum { #define HDLC_MODE_TRANS 0x02 #define HDLC_MODE_CCR_7 0x04 #define HDLC_MODE_CCR_16 0x08 -#define HDLC_FIFO_SIZE_128 0x20 #define HDLC_MODE_TESTLOOP 0x80 #define HDLC_INT_XPR 0x80 @@ -81,16 +80,13 @@ enum { #define HDLC_STAT_RDO 0x10 #define HDLC_STAT_CRCVFRRAB 0x0E #define HDLC_STAT_CRCVFR 0x06 -#define HDLC_STAT_RML_MASK_V1 0x3f00 -#define HDLC_STAT_RML_MASK_V2 0x7f00 +#define HDLC_STAT_RML_MASK 0x3f00 #define HDLC_CMD_XRS 0x80 #define HDLC_CMD_XME 0x01 #define HDLC_CMD_RRS 0x20 #define HDLC_CMD_XML_MASK 0x3f00 - -#define HDLC_FIFO_SIZE_V1 32 -#define HDLC_FIFO_SIZE_V2 128 +#define HDLC_FIFO_SIZE 32 /* Fritz PCI v2.0 */ @@ -350,14 +346,11 @@ modehdlc(struct bchannel *bch, int protocol) { struct fritzcard *fc = bch->hw; struct hdlc_hw *hdlc; - u8 mode; hdlc = &fc->hdlc[(bch->nr - 1) & 1]; pr_debug("%s: hdlc %c protocol %x-->%x ch %d\n", fc->name, '@' + bch->nr, bch->state, protocol, bch->nr); hdlc->ctrl.ctrl = 0; - mode = (fc->type == AVM_FRITZ_PCIV2) ? HDLC_FIFO_SIZE_128 : 0; - switch (protocol) { case -1: /* used for init */ bch->state = -1; @@ -365,7 +358,7 @@ modehdlc(struct bchannel *bch, int protocol) if (bch->state == ISDN_P_NONE) break; hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS; - hdlc->ctrl.sr.mode = mode | HDLC_MODE_TRANS; + hdlc->ctrl.sr.mode = HDLC_MODE_TRANS; write_ctrl(bch, 5); bch->state = ISDN_P_NONE; test_and_clear_bit(FLG_HDLC, &bch->Flags); @@ -374,7 +367,7 @@ modehdlc(struct bchannel *bch, int protocol) case ISDN_P_B_RAW: bch->state = protocol; hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS; - hdlc->ctrl.sr.mode = mode | HDLC_MODE_TRANS; + hdlc->ctrl.sr.mode = HDLC_MODE_TRANS; write_ctrl(bch, 5); hdlc->ctrl.sr.cmd = HDLC_CMD_XRS; write_ctrl(bch, 1); @@ -384,7 +377,7 @@ modehdlc(struct bchannel *bch, int protocol) case ISDN_P_B_HDLC: bch->state = protocol; hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS; - hdlc->ctrl.sr.mode = mode | HDLC_MODE_ITF_FLG; + hdlc->ctrl.sr.mode = HDLC_MODE_ITF_FLG; write_ctrl(bch, 5); hdlc->ctrl.sr.cmd = HDLC_CMD_XRS; write_ctrl(bch, 1); @@ -404,40 +397,39 @@ hdlc_empty_fifo(struct bchannel *bch, int count) u32 *ptr; u8 *p; u32 val, addr; - int cnt; + int cnt = 0; struct fritzcard *fc = bch->hw; pr_debug("%s: %s %d\n", fc->name, __func__, count); - if (test_bit(FLG_RX_OFF, &bch->Flags)) { - p = NULL; - bch->dropcnt += count; - } else { - cnt = bchannel_get_rxbuf(bch, count); - if (cnt < 0) { - pr_warning("%s.B%d: No bufferspace for %d bytes\n", - fc->name, bch->nr, count); + if (!bch->rx_skb) { + bch->rx_skb = mI_alloc_skb(bch->maxlen, GFP_ATOMIC); + if (!bch->rx_skb) { + pr_info("%s: B receive out of memory\n", + fc->name); return; } - p = skb_put(bch->rx_skb, count); } + if ((bch->rx_skb->len + count) > bch->maxlen) { + pr_debug("%s: overrun %d\n", fc->name, + bch->rx_skb->len + count); + return; + } + p = skb_put(bch->rx_skb, count); ptr = (u32 *)p; - if (fc->type == AVM_FRITZ_PCIV2) + if (AVM_FRITZ_PCIV2 == fc->type) addr = fc->addr + (bch->nr == 2 ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1); else { addr = fc->addr + CHIP_WINDOW; outl(bch->nr == 2 ? AVM_HDLC_2 : AVM_HDLC_1, fc->addr); } - cnt = 0; while (cnt < count) { val = le32_to_cpu(inl(addr)); - if (p) { - put_unaligned(val, ptr); - ptr++; - } + put_unaligned(val, ptr); + ptr++; cnt += 4; } - if (p && (debug & DEBUG_HW_BFIFO)) { + if (debug & DEBUG_HW_BFIFO) { snprintf(fc->log, LOG_SIZE, "B%1d-recv %s %d ", bch->nr, fc->name, count); print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count); @@ -449,43 +441,30 @@ hdlc_fill_fifo(struct bchannel *bch) { struct fritzcard *fc = bch->hw; struct hdlc_hw *hdlc; - int count, fs, cnt = 0, idx, fillempty = 0; + int count, cnt = 0; u8 *p; u32 *ptr, val, addr; - idx = (bch->nr - 1) & 1; - hdlc = &fc->hdlc[idx]; - fs = (fc->type == AVM_FRITZ_PCIV2) ? - HDLC_FIFO_SIZE_V2 : HDLC_FIFO_SIZE_V1; - if (!bch->tx_skb) { - if (!test_bit(FLG_TX_EMPTY, &bch->Flags)) - return; - count = fs; - p = bch->fill; - fillempty = 1; - } else { - count = bch->tx_skb->len - bch->tx_idx; - if (count <= 0) - return; - p = bch->tx_skb->data + bch->tx_idx; - } + hdlc = &fc->hdlc[(bch->nr - 1) & 1]; + if (!bch->tx_skb) + return; + count = bch->tx_skb->len - bch->tx_idx; + if (count <= 0) + return; + p = bch->tx_skb->data + bch->tx_idx; hdlc->ctrl.sr.cmd &= ~HDLC_CMD_XME; - if (count > fs) { - count = fs; + if (count > HDLC_FIFO_SIZE) { + count = HDLC_FIFO_SIZE; } else { if (test_bit(FLG_HDLC, &bch->Flags)) hdlc->ctrl.sr.cmd |= HDLC_CMD_XME; } + pr_debug("%s: %s %d/%d/%d", fc->name, __func__, count, + bch->tx_idx, bch->tx_skb->len); ptr = (u32 *)p; - if (fillempty) { - pr_debug("%s.B%d: %d/%d/%d", fc->name, bch->nr, count, - bch->tx_idx, bch->tx_skb->len); - bch->tx_idx += count; - } else { - pr_debug("%s.B%d: fillempty %d\n", fc->name, bch->nr, count); - } - hdlc->ctrl.sr.xml = ((count == fs) ? 0 : count); - if (fc->type == AVM_FRITZ_PCIV2) { + bch->tx_idx += count; + hdlc->ctrl.sr.xml = ((count == HDLC_FIFO_SIZE) ? 0 : count); + if (AVM_FRITZ_PCIV2 == fc->type) { __write_ctrl_pciv2(fc, hdlc, bch->nr); addr = fc->addr + (bch->nr == 2 ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1); @@ -493,21 +472,13 @@ hdlc_fill_fifo(struct bchannel *bch) __write_ctrl_pci(fc, hdlc, bch->nr); addr = fc->addr + CHIP_WINDOW; } - if (fillempty) { - while (cnt < count) { - /* all bytes the same - no worry about endian */ - outl(*ptr, addr); - cnt += 4; - } - } else { - while (cnt < count) { - val = get_unaligned(ptr); - outl(cpu_to_le32(val), addr); - ptr++; - cnt += 4; - } + while (cnt < count) { + val = get_unaligned(ptr); + outl(cpu_to_le32(val), addr); + ptr++; + cnt += 4; } - if ((debug & DEBUG_HW_BFIFO) && !fillempty) { + if (debug & DEBUG_HW_BFIFO) { snprintf(fc->log, LOG_SIZE, "B%1d-send %s %d ", bch->nr, fc->name, count); print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count); @@ -517,17 +488,17 @@ hdlc_fill_fifo(struct bchannel *bch) static void HDLC_irq_xpr(struct bchannel *bch) { - if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len) { + if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len) hdlc_fill_fifo(bch); - } else { - if (bch->tx_skb) + else { + if (bch->tx_skb) { + /* send confirm, on trans, free on hdlc. */ + if (test_bit(FLG_TRANSPARENT, &bch->Flags)) + confirm_Bsend(bch); dev_kfree_skb(bch->tx_skb); - if (get_next_bframe(bch)) { - hdlc_fill_fifo(bch); - test_and_clear_bit(FLG_TX_EMPTY, &bch->Flags); - } else if (test_bit(FLG_TX_EMPTY, &bch->Flags)) { - hdlc_fill_fifo(bch); } + if (get_next_bframe(bch)) + hdlc_fill_fifo(bch); } } @@ -535,23 +506,13 @@ static void HDLC_irq(struct bchannel *bch, u32 stat) { struct fritzcard *fc = bch->hw; - int len, fs; - u32 rmlMask; + int len; struct hdlc_hw *hdlc; hdlc = &fc->hdlc[(bch->nr - 1) & 1]; pr_debug("%s: ch%d stat %#x\n", fc->name, bch->nr, stat); - if (fc->type == AVM_FRITZ_PCIV2) { - rmlMask = HDLC_STAT_RML_MASK_V2; - fs = HDLC_FIFO_SIZE_V2; - } else { - rmlMask = HDLC_STAT_RML_MASK_V1; - fs = HDLC_FIFO_SIZE_V1; - } if (stat & HDLC_INT_RPR) { if (stat & HDLC_STAT_RDO) { - pr_warning("%s: ch%d stat %x RDO\n", - fc->name, bch->nr, stat); hdlc->ctrl.sr.xml = 0; hdlc->ctrl.sr.cmd |= HDLC_CMD_RRS; write_ctrl(bch, 1); @@ -560,21 +521,21 @@ HDLC_irq(struct bchannel *bch, u32 stat) if (bch->rx_skb) skb_trim(bch->rx_skb, 0); } else { - len = (stat & rmlMask) >> 8; + len = (stat & HDLC_STAT_RML_MASK) >> 8; if (!len) - len = fs; + len = 32; hdlc_empty_fifo(bch, len); if (!bch->rx_skb) goto handle_tx; - if (test_bit(FLG_TRANSPARENT, &bch->Flags)) { - recv_Bchannel(bch, 0, false); - } else if (stat & HDLC_STAT_RME) { - if ((stat & HDLC_STAT_CRCVFRRAB) == - HDLC_STAT_CRCVFR) { - recv_Bchannel(bch, 0, false); + if ((stat & HDLC_STAT_RME) || test_bit(FLG_TRANSPARENT, + &bch->Flags)) { + if (((stat & HDLC_STAT_CRCVFRRAB) == + HDLC_STAT_CRCVFR) || + test_bit(FLG_TRANSPARENT, &bch->Flags)) { + recv_Bchannel(bch, 0); } else { - pr_warning("%s: got invalid frame\n", - fc->name); + pr_debug("%s: got invalid frame\n", + fc->name); skb_trim(bch->rx_skb, 0); } } @@ -586,13 +547,16 @@ HDLC_irq(struct bchannel *bch, u32 stat) * restart transmitting the whole frame on HDLC * in transparent mode we send the next data */ - pr_warning("%s: ch%d stat %x XDU %s\n", fc->name, bch->nr, - stat, bch->tx_skb ? "tx_skb" : "no tx_skb"); + if (bch->tx_skb) + pr_debug("%s: ch%d XDU len(%d) idx(%d) Flags(%lx)\n", + fc->name, bch->nr, bch->tx_skb->len, + bch->tx_idx, bch->Flags); + else + pr_debug("%s: ch%d XDU no tx_skb Flags(%lx)\n", + fc->name, bch->nr, bch->Flags); if (bch->tx_skb && bch->tx_skb->len) { if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) bch->tx_idx = 0; - } else if (test_bit(FLG_FILLEMPTY, &bch->Flags)) { - test_and_set_bit(FLG_TX_EMPTY, &bch->Flags); } hdlc->ctrl.sr.xml = 0; hdlc->ctrl.sr.cmd |= HDLC_CMD_XRS; @@ -695,17 +659,22 @@ avm_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb) struct fritzcard *fc = bch->hw; int ret = -EINVAL; struct mISDNhead *hh = mISDN_HEAD_P(skb); - unsigned long flags; + u32 id; + u_long flags; switch (hh->prim) { case PH_DATA_REQ: spin_lock_irqsave(&fc->lock, flags); ret = bchannel_senddata(bch, skb); if (ret > 0) { /* direct TX */ + id = hh->id; /* skb can be freed */ hdlc_fill_fifo(bch); ret = 0; - } - spin_unlock_irqrestore(&fc->lock, flags); + spin_unlock_irqrestore(&fc->lock, flags); + if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) + queue_ch_frame(ch, PH_DATA_CNF, id, NULL); + } else + spin_unlock_irqrestore(&fc->lock, flags); return ret; case PH_ACTIVATE_REQ: spin_lock_irqsave(&fc->lock, flags); @@ -814,7 +783,7 @@ init_card(struct fritzcard *fc) inithdlc(fc); enable_hwirq(fc); /* RESET Receiver and Transmitter */ - if (fc->type == AVM_FRITZ_PCIV2) { + if (AVM_FRITZ_PCIV2 == fc->type) { WriteISAC_V2(fc, ISACX_MASK, 0); WriteISAC_V2(fc, ISACX_CMDRD, 0x41); } else { @@ -841,7 +810,21 @@ init_card(struct fritzcard *fc) static int channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) { - return mISDN_ctrl_bchannel(bch, cq); + int ret = 0; + struct fritzcard *fc = bch->hw; + + switch (cq->op) { + case MISDN_CTRL_GETOP: + cq->op = 0; + break; + /* Nothing implemented yet */ + case MISDN_CTRL_FILL_EMPTY: + default: + pr_info("%s: %s unknown Op %x\n", fc->name, __func__, cq->op); + ret = -EINVAL; + break; + } + return ret; } static int @@ -856,10 +839,14 @@ avm_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) switch (cmd) { case CLOSE_CHANNEL: test_and_clear_bit(FLG_OPEN, &bch->Flags); - spin_lock_irqsave(&fc->lock, flags); - mISDN_freebchannel(bch); - modehdlc(bch, ISDN_P_NONE); - spin_unlock_irqrestore(&fc->lock, flags); + if (test_bit(FLG_ACTIVE, &bch->Flags)) { + spin_lock_irqsave(&fc->lock, flags); + mISDN_freebchannel(bch); + test_and_clear_bit(FLG_TX_BUSY, &bch->Flags); + test_and_clear_bit(FLG_ACTIVE, &bch->Flags); + modehdlc(bch, ISDN_P_NONE); + spin_unlock_irqrestore(&fc->lock, flags); + } ch->protocol = ISDN_P_NONE; ch->peer = NULL; module_put(THIS_MODULE); @@ -914,6 +901,7 @@ open_bchannel(struct fritzcard *fc, struct channel_req *rq) bch = &fc->bch[rq->adr.channel - 1]; if (test_and_set_bit(FLG_OPEN, &bch->Flags)) return -EBUSY; /* b-channel can be only open once */ + test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); bch->ch.protocol = rq->protocol; rq->ch = &bch->ch; return 0; @@ -1036,7 +1024,6 @@ static int __devinit setup_instance(struct fritzcard *card) { int i, err; - unsigned short minsize; u_long flags; snprintf(card->name, MISDN_MAX_IDLEN - 1, "AVM.%d", AVM_cnt + 1); @@ -1056,11 +1043,7 @@ setup_instance(struct fritzcard *card) for (i = 0; i < 2; i++) { card->bch[i].nr = i + 1; set_channelmap(i + 1, card->isac.dch.dev.channelmap); - if (AVM_FRITZ_PCIV2 == card->type) - minsize = HDLC_FIFO_SIZE_V2; - else - minsize = HDLC_FIFO_SIZE_V1; - mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM, minsize); + mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM); card->bch[i].hw = card; card->bch[i].ch.send = avm_l2l1B; card->bch[i].ch.ctrl = avm_bctrl; diff --git a/trunk/drivers/isdn/hardware/mISDN/hfcmulti.c b/trunk/drivers/isdn/hardware/mISDN/hfcmulti.c index 5e402cf2e795..4c128e4bb5cf 100644 --- a/trunk/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/trunk/drivers/isdn/hardware/mISDN/hfcmulti.c @@ -1171,7 +1171,7 @@ init_chip(struct hfc_multi *hc) hc->DTMFbase = 0x1000; if (test_bit(HFC_CHIP_EXRAM_128, &hc->chip)) { if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: changing to 128K external RAM\n", + printk(KERN_DEBUG "%s: changing to 128K extenal RAM\n", __func__); hc->hw.r_ctrl |= V_EXT_RAM; hc->hw.r_ram_sz = 1; @@ -1182,7 +1182,7 @@ init_chip(struct hfc_multi *hc) } if (test_bit(HFC_CHIP_EXRAM_512, &hc->chip)) { if (debug & DEBUG_HFCMULTI_INIT) - printk(KERN_DEBUG "%s: changing to 512K external RAM\n", + printk(KERN_DEBUG "%s: changing to 512K extenal RAM\n", __func__); hc->hw.r_ctrl |= V_EXT_RAM; hc->hw.r_ram_sz = 2; @@ -2166,9 +2166,13 @@ hfcmulti_tx(struct hfc_multi *hc, int ch) HFC_wait_nodebug(hc); } - dev_kfree_skb(*sp); + /* send confirm, since get_net_bframe will not do it with trans */ + if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags)) + confirm_Bsend(bch); + /* check for next frame */ - if (bch && get_next_bframe(bch)) { + dev_kfree_skb(*sp); + if (bch && get_next_bframe(bch)) { /* hdlc is confirmed here */ len = (*sp)->len; goto next_frame; } @@ -2196,20 +2200,24 @@ hfcmulti_rx(struct hfc_multi *hc, int ch) int f1 = 0, f2 = 0; /* = 0, to make GCC happy */ int again = 0; struct bchannel *bch; - struct dchannel *dch = NULL; + struct dchannel *dch; struct sk_buff *skb, **sp = NULL; int maxlen; bch = hc->chan[ch].bch; - if (bch) { - if (!test_bit(FLG_ACTIVE, &bch->Flags)) - return; - } else if (hc->chan[ch].dch) { - dch = hc->chan[ch].dch; + dch = hc->chan[ch].dch; + if ((!dch) && (!bch)) + return; + if (dch) { if (!test_bit(FLG_ACTIVE, &dch->Flags)) return; + sp = &dch->rx_skb; + maxlen = dch->maxlen; } else { - return; + if (!test_bit(FLG_ACTIVE, &bch->Flags)) + return; + sp = &bch->rx_skb; + maxlen = bch->maxlen; } next_frame: /* on first AND before getting next valid frame, R_FIFO must be written @@ -2224,11 +2232,8 @@ hfcmulti_rx(struct hfc_multi *hc, int ch) HFC_wait_nodebug(hc); /* ignore if rx is off BUT change fifo (above) to start pending TX */ - if (hc->chan[ch].rx_off) { - if (bch) - bch->dropcnt += poll; /* not exact but fair enough */ + if (hc->chan[ch].rx_off) return; - } if (dch || test_bit(FLG_HDLC, &bch->Flags)) { f1 = HFC_inb_nodebug(hc, A_F1); @@ -2259,25 +2264,12 @@ hfcmulti_rx(struct hfc_multi *hc, int ch) if (Zsize <= 0) return; - if (bch) { - maxlen = bchannel_get_rxbuf(bch, Zsize); - if (maxlen < 0) { - pr_warning("card%d.B%d: No bufferspace for %d bytes\n", - hc->id + 1, bch->nr, Zsize); - return; - } - sp = &bch->rx_skb; - maxlen = bch->maxlen; - } else { /* Dchannel */ - sp = &dch->rx_skb; - maxlen = dch->maxlen + 3; + if (*sp == NULL) { + *sp = mI_alloc_skb(maxlen + 3, GFP_ATOMIC); if (*sp == NULL) { - *sp = mI_alloc_skb(maxlen, GFP_ATOMIC); - if (*sp == NULL) { - pr_warning("card%d: No mem for dch rx_skb\n", - hc->id + 1); - return; - } + printk(KERN_DEBUG "%s: No mem for rx_skb\n", + __func__); + return; } } /* show activity */ @@ -2293,7 +2285,7 @@ hfcmulti_rx(struct hfc_multi *hc, int ch) Zsize, z1, z2, (f1 == f2) ? "fragment" : "COMPLETE", f1, f2, Zsize + (*sp)->len, again); /* HDLC */ - if ((Zsize + (*sp)->len) > maxlen) { + if ((Zsize + (*sp)->len) > (maxlen + 3)) { if (debug & DEBUG_HFCMULTI_FIFO) printk(KERN_DEBUG "%s(card %d): hdlc-frame too large.\n", @@ -2355,7 +2347,7 @@ hfcmulti_rx(struct hfc_multi *hc, int ch) if (dch) recv_Dchannel(dch); else - recv_Bchannel(bch, MISDN_ID_ANY, false); + recv_Bchannel(bch, MISDN_ID_ANY); *sp = skb; again++; goto next_frame; @@ -2363,14 +2355,32 @@ hfcmulti_rx(struct hfc_multi *hc, int ch) /* there is an incomplete frame */ } else { /* transparent */ + if (Zsize > skb_tailroom(*sp)) + Zsize = skb_tailroom(*sp); hc->read_fifo(hc, skb_put(*sp, Zsize), Zsize); + if (((*sp)->len) < MISDN_COPY_SIZE) { + skb = *sp; + *sp = mI_alloc_skb(skb->len, GFP_ATOMIC); + if (*sp) { + memcpy(skb_put(*sp, skb->len), + skb->data, skb->len); + skb_trim(skb, 0); + } else { + printk(KERN_DEBUG "%s: No mem\n", __func__); + *sp = skb; + skb = NULL; + } + } else { + skb = NULL; + } if (debug & DEBUG_HFCMULTI_FIFO) printk(KERN_DEBUG "%s(card %d): fifo(%d) reading %d bytes " "(z1=%04x, z2=%04x) TRANS\n", __func__, hc->id + 1, ch, Zsize, z1, z2); /* only bch is transparent */ - recv_Bchannel(bch, hc->chan[ch].Zfill, false); + recv_Bchannel(bch, hc->chan[ch].Zfill); + *sp = skb; } } @@ -3472,7 +3482,8 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb) struct hfc_multi *hc = bch->hw; int ret = -EINVAL; struct mISDNhead *hh = mISDN_HEAD_P(skb); - unsigned long flags; + unsigned int id; + u_long flags; switch (hh->prim) { case PH_DATA_REQ: @@ -3481,13 +3492,19 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb) spin_lock_irqsave(&hc->lock, flags); ret = bchannel_senddata(bch, skb); if (ret > 0) { /* direct TX */ + id = hh->id; /* skb can be freed */ hfcmulti_tx(hc, bch->slot); ret = 0; /* start fifo */ HFC_outb_nodebug(hc, R_FIFO, 0); HFC_wait_nodebug(hc); - } - spin_unlock_irqrestore(&hc->lock, flags); + if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) { + spin_unlock_irqrestore(&hc->lock, flags); + queue_ch_frame(ch, PH_DATA_CNF, id, NULL); + } else + spin_unlock_irqrestore(&hc->lock, flags); + } else + spin_unlock_irqrestore(&hc->lock, flags); return ret; case PH_ACTIVATE_REQ: if (debug & DEBUG_HFCMULTI_MSG) @@ -3577,11 +3594,10 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) switch (cq->op) { case MISDN_CTRL_GETOP: - ret = mISDN_ctrl_bchannel(bch, cq); - cq->op |= MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP; + cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP + | MISDN_CTRL_RX_OFF | MISDN_CTRL_FILL_EMPTY; break; case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */ - ret = mISDN_ctrl_bchannel(bch, cq); hc->chan[bch->slot].rx_off = !!cq->p1; if (!hc->chan[bch->slot].rx_off) { /* reset fifo on rx on */ @@ -3594,10 +3610,11 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) printk(KERN_DEBUG "%s: RX_OFF request (nr=%d off=%d)\n", __func__, bch->nr, hc->chan[bch->slot].rx_off); break; - case MISDN_CTRL_FILL_EMPTY: - ret = mISDN_ctrl_bchannel(bch, cq); - hc->silence = bch->fill[0]; - memset(hc->silence_data, hc->silence, sizeof(hc->silence_data)); + case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */ + test_and_set_bit(FLG_FILLEMPTY, &bch->Flags); + if (debug & DEBUG_HFCMULTI_MSG) + printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d " + "off=%d)\n", __func__, bch->nr, !!cq->p1); break; case MISDN_CTRL_HW_FEATURES: /* fill features structure */ if (debug & DEBUG_HFCMULTI_MSG) @@ -3686,7 +3703,9 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) ret = -EINVAL; break; default: - ret = mISDN_ctrl_bchannel(bch, cq); + printk(KERN_WARNING "%s: unknown Op %x\n", + __func__, cq->op); + ret = -EINVAL; break; } return ret; @@ -3706,7 +3725,8 @@ hfcm_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg) switch (cmd) { case CLOSE_CHANNEL: test_and_clear_bit(FLG_OPEN, &bch->Flags); - deactivate_bchannel(bch); /* locked there */ + if (test_bit(FLG_ACTIVE, &bch->Flags)) + deactivate_bchannel(bch); /* locked there */ ch->protocol = ISDN_P_NONE; ch->peer = NULL; module_put(THIS_MODULE); @@ -4120,6 +4140,7 @@ open_bchannel(struct hfc_multi *hc, struct dchannel *dch, } if (test_and_set_bit(FLG_OPEN, &bch->Flags)) return -EBUSY; /* b-channel can be only open once */ + test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); bch->ch.protocol = rq->protocol; hc->chan[ch].rx_off = 0; rq->ch = &bch->ch; @@ -4855,7 +4876,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m, int pt) bch->nr = ch; bch->slot = ch; bch->debug = debug; - mISDN_initbchannel(bch, MAX_DATA_MEM, poll >> 1); + mISDN_initbchannel(bch, MAX_DATA_MEM); bch->hw = hc; bch->ch.send = handle_bmsg; bch->ch.ctrl = hfcm_bctrl; @@ -4928,7 +4949,7 @@ init_multi_port(struct hfc_multi *hc, int pt) bch->nr = ch + 1; bch->slot = i + ch; bch->debug = debug; - mISDN_initbchannel(bch, MAX_DATA_MEM, poll >> 1); + mISDN_initbchannel(bch, MAX_DATA_MEM); bch->hw = hc; bch->ch.send = handle_bmsg; bch->ch.ctrl = hfcm_bctrl; diff --git a/trunk/drivers/isdn/hardware/mISDN/hfcpci.c b/trunk/drivers/isdn/hardware/mISDN/hfcpci.c index 81363ffa5357..5fe993e2dee9 100644 --- a/trunk/drivers/isdn/hardware/mISDN/hfcpci.c +++ b/trunk/drivers/isdn/hardware/mISDN/hfcpci.c @@ -453,7 +453,7 @@ hfcpci_empty_bfifo(struct bchannel *bch, struct bzfifo *bz, } bz->za[new_f2].z2 = cpu_to_le16(new_z2); bz->f2 = new_f2; /* next buffer */ - recv_Bchannel(bch, MISDN_ID_ANY, false); + recv_Bchannel(bch, MISDN_ID_ANY); } } @@ -565,6 +565,11 @@ hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *rxbz, if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) new_z2 -= B_FIFO_SIZE; /* buffer wrap */ + if (fcnt_rx > MAX_DATA_SIZE) { /* flush, if oversized */ + *z2r = cpu_to_le16(new_z2); /* new position */ + return; + } + fcnt_tx = le16_to_cpu(*z2t) - le16_to_cpu(*z1t); if (fcnt_tx <= 0) fcnt_tx += B_FIFO_SIZE; @@ -572,16 +577,8 @@ hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *rxbz, fcnt_tx = B_FIFO_SIZE - fcnt_tx; /* remaining bytes to send (bytes in tx-fifo) */ - if (test_bit(FLG_RX_OFF, &bch->Flags)) { - bch->dropcnt += fcnt_rx; - *z2r = cpu_to_le16(new_z2); - return; - } - maxlen = bchannel_get_rxbuf(bch, fcnt_rx); - if (maxlen < 0) { - pr_warning("B%d: No bufferspace for %d bytes\n", - bch->nr, fcnt_rx); - } else { + bch->rx_skb = mI_alloc_skb(fcnt_rx, GFP_ATOMIC); + if (bch->rx_skb) { ptr = skb_put(bch->rx_skb, fcnt_rx); if (le16_to_cpu(*z2r) + fcnt_rx <= B_FIFO_SIZE + B_SUB_VAL) maxlen = fcnt_rx; /* complete transfer */ @@ -599,8 +596,10 @@ hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *rxbz, ptr1 = bdata; /* start of buffer */ memcpy(ptr, ptr1, fcnt_rx); /* rest */ } - recv_Bchannel(bch, fcnt_tx, false); /* bch, id, !force */ - } + recv_Bchannel(bch, fcnt_tx); /* bch, id */ + } else + printk(KERN_WARNING "HFCPCI: receive out of memory\n"); + *z2r = cpu_to_le16(new_z2); /* new position */ } @@ -761,14 +760,9 @@ hfcpci_fill_fifo(struct bchannel *bch) if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO)) printk(KERN_DEBUG "%s\n", __func__); - if ((!bch->tx_skb) || bch->tx_skb->len == 0) { - if (!test_bit(FLG_FILLEMPTY, &bch->Flags) && - !test_bit(FLG_TRANSPARENT, &bch->Flags)) - return; - count = HFCPCI_FILLEMPTY; - } else { - count = bch->tx_skb->len - bch->tx_idx; - } + if ((!bch->tx_skb) || bch->tx_skb->len <= 0) + return; + count = bch->tx_skb->len - bch->tx_idx; if ((bch->nr & 2) && (!hc->hw.bswapped)) { bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2; bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.txdat_b2; @@ -787,10 +781,16 @@ hfcpci_fill_fifo(struct bchannel *bch) fcnt = le16_to_cpu(*z2t) - le16_to_cpu(*z1t); if (fcnt <= 0) fcnt += B_FIFO_SIZE; - if (test_bit(FLG_FILLEMPTY, &bch->Flags)) { - /* fcnt contains available bytes in fifo */ - if (count > fcnt) - count = fcnt; + /* fcnt contains available bytes in fifo */ + fcnt = B_FIFO_SIZE - fcnt; + /* remaining bytes to send (bytes in fifo) */ + + /* "fill fifo if empty" feature */ + if (test_bit(FLG_FILLEMPTY, &bch->Flags) && !fcnt) { + /* printk(KERN_DEBUG "%s: buffer empty, so we have " + "underrun\n", __func__); */ + /* fill buffer, to prevent future underrun */ + count = HFCPCI_FILLEMPTY; new_z1 = le16_to_cpu(*z1t) + count; /* new buffer Position */ if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL)) @@ -802,20 +802,17 @@ hfcpci_fill_fifo(struct bchannel *bch) printk(KERN_DEBUG "hfcpci_FFt fillempty " "fcnt(%d) maxl(%d) nz1(%x) dst(%p)\n", fcnt, maxlen, new_z1, dst); + fcnt += count; if (maxlen > count) maxlen = count; /* limit size */ - memset(dst, bch->fill[0], maxlen); /* first copy */ + memset(dst, 0x2a, maxlen); /* first copy */ count -= maxlen; /* remaining bytes */ if (count) { dst = bdata; /* start of buffer */ - memset(dst, bch->fill[0], count); + memset(dst, 0x2a, count); } *z1t = cpu_to_le16(new_z1); /* now send data */ - return; } - /* fcnt contains available bytes in fifo */ - fcnt = B_FIFO_SIZE - fcnt; - /* remaining bytes to send (bytes in fifo) */ next_t_frame: count = bch->tx_skb->len - bch->tx_idx; @@ -852,6 +849,9 @@ hfcpci_fill_fifo(struct bchannel *bch) *z1t = cpu_to_le16(new_z1); /* now send data */ if (bch->tx_idx < bch->tx_skb->len) return; + /* send confirm, on trans, free on hdlc. */ + if (test_bit(FLG_TRANSPARENT, &bch->Flags)) + confirm_Bsend(bch); dev_kfree_skb(bch->tx_skb); if (get_next_bframe(bch)) goto next_t_frame; @@ -1533,7 +1533,24 @@ deactivate_bchannel(struct bchannel *bch) static int channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) { - return mISDN_ctrl_bchannel(bch, cq); + int ret = 0; + + switch (cq->op) { + case MISDN_CTRL_GETOP: + cq->op = MISDN_CTRL_FILL_EMPTY; + break; + case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */ + test_and_set_bit(FLG_FILLEMPTY, &bch->Flags); + if (debug & DEBUG_HW_OPEN) + printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d " + "off=%d)\n", __func__, bch->nr, !!cq->p1); + break; + default: + printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op); + ret = -EINVAL; + break; + } + return ret; } static int hfc_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg) @@ -1564,7 +1581,8 @@ hfc_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg) break; case CLOSE_CHANNEL: test_and_clear_bit(FLG_OPEN, &bch->Flags); - deactivate_bchannel(bch); + if (test_bit(FLG_ACTIVE, &bch->Flags)) + deactivate_bchannel(bch); ch->protocol = ISDN_P_NONE; ch->peer = NULL; module_put(THIS_MODULE); @@ -1674,17 +1692,22 @@ hfcpci_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb) struct hfc_pci *hc = bch->hw; int ret = -EINVAL; struct mISDNhead *hh = mISDN_HEAD_P(skb); - unsigned long flags; + unsigned int id; + u_long flags; switch (hh->prim) { case PH_DATA_REQ: spin_lock_irqsave(&hc->lock, flags); ret = bchannel_senddata(bch, skb); if (ret > 0) { /* direct TX */ + id = hh->id; /* skb can be freed */ hfcpci_fill_fifo(bch); ret = 0; - } - spin_unlock_irqrestore(&hc->lock, flags); + spin_unlock_irqrestore(&hc->lock, flags); + if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) + queue_ch_frame(ch, PH_DATA_CNF, id, NULL); + } else + spin_unlock_irqrestore(&hc->lock, flags); return ret; case PH_ACTIVATE_REQ: spin_lock_irqsave(&hc->lock, flags); @@ -1949,6 +1972,7 @@ open_bchannel(struct hfc_pci *hc, struct channel_req *rq) bch = &hc->bch[rq->adr.channel - 1]; if (test_and_set_bit(FLG_OPEN, &bch->Flags)) return -EBUSY; /* b-channel can be only open once */ + test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); bch->ch.protocol = rq->protocol; rq->ch = &bch->ch; /* TODO: E-channel */ if (!try_module_get(THIS_MODULE)) @@ -2100,7 +2124,7 @@ setup_card(struct hfc_pci *card) card->bch[i].nr = i + 1; set_channelmap(i + 1, card->dch.dev.channelmap); card->bch[i].debug = debug; - mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM, poll >> 1); + mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM); card->bch[i].hw = card; card->bch[i].ch.send = hfcpci_l2l1B; card->bch[i].ch.ctrl = hfc_bctrl; diff --git a/trunk/drivers/isdn/hardware/mISDN/hfcsusb.c b/trunk/drivers/isdn/hardware/mISDN/hfcsusb.c index 83206e453d4e..8cde2a0538ab 100644 --- a/trunk/drivers/isdn/hardware/mISDN/hfcsusb.c +++ b/trunk/drivers/isdn/hardware/mISDN/hfcsusb.c @@ -226,12 +226,19 @@ hfcusb_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb) if (debug & DBG_HFC_CALL_TRACE) printk(KERN_DEBUG "%s: %s PH_DATA_REQ ret(%i)\n", hw->name, __func__, ret); - if (ret > 0) + if (ret > 0) { + /* + * other l1 drivers don't send early confirms on + * transp data, but hfcsusb does because tx_next + * skb is needed in tx_iso_complete() + */ + queue_ch_frame(ch, PH_DATA_CNF, hh->id, NULL); ret = 0; + } return ret; case PH_ACTIVATE_REQ: if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) { - hfcsusb_start_endpoint(hw, bch->nr - 1); + hfcsusb_start_endpoint(hw, bch->nr); ret = hfcsusb_setup_bch(bch, ch->protocol); } else ret = 0; @@ -491,9 +498,16 @@ open_bchannel(struct hfcsusb *hw, struct channel_req *rq) bch = &hw->bch[rq->adr.channel - 1]; if (test_and_set_bit(FLG_OPEN, &bch->Flags)) return -EBUSY; /* b-channel can be only open once */ + test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); bch->ch.protocol = rq->protocol; rq->ch = &bch->ch; + /* start USB endpoint for bchannel */ + if (rq->adr.channel == 1) + hfcsusb_start_endpoint(hw, HFC_CHAN_B1); + else + hfcsusb_start_endpoint(hw, HFC_CHAN_B2); + if (!try_module_get(THIS_MODULE)) printk(KERN_WARNING "%s: %s:cannot get module\n", hw->name, __func__); @@ -805,7 +819,24 @@ hfcsusb_ph_command(struct hfcsusb *hw, u_char command) static int channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) { - return mISDN_ctrl_bchannel(bch, cq); + int ret = 0; + + switch (cq->op) { + case MISDN_CTRL_GETOP: + cq->op = MISDN_CTRL_FILL_EMPTY; + break; + case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */ + test_and_set_bit(FLG_FILLEMPTY, &bch->Flags); + if (debug & DEBUG_HW_OPEN) + printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d " + "off=%d)\n", __func__, bch->nr, !!cq->p1); + break; + default: + printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op); + ret = -EINVAL; + break; + } + return ret; } /* collect data from incoming interrupt or isochron USB data */ @@ -842,21 +873,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len, hdlc = 1; } if (fifo->bch) { - if (test_bit(FLG_RX_OFF, &fifo->bch->Flags)) { - fifo->bch->dropcnt += len; - spin_unlock(&hw->lock); - return; - } - maxlen = bchannel_get_rxbuf(fifo->bch, len); rx_skb = fifo->bch->rx_skb; - if (maxlen < 0) { - if (rx_skb) - skb_trim(rx_skb, 0); - pr_warning("%s.B%d: No bufferspace for %d bytes\n", - hw->name, fifo->bch->nr, len); - spin_unlock(&hw->lock); - return; - } maxlen = fifo->bch->maxlen; hdlc = test_bit(FLG_HDLC, &fifo->bch->Flags); } @@ -866,22 +883,25 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len, hdlc = 1; } - if (fifo->dch || fifo->ech) { - if (!rx_skb) { - rx_skb = mI_alloc_skb(maxlen, GFP_ATOMIC); - if (rx_skb) { - if (fifo->dch) - fifo->dch->rx_skb = rx_skb; - if (fifo->ech) - fifo->ech->rx_skb = rx_skb; - skb_trim(rx_skb, 0); - } else { - printk(KERN_DEBUG "%s: %s: No mem for rx_skb\n", - hw->name, __func__); - spin_unlock(&hw->lock); - return; - } + if (!rx_skb) { + rx_skb = mI_alloc_skb(maxlen, GFP_ATOMIC); + if (rx_skb) { + if (fifo->dch) + fifo->dch->rx_skb = rx_skb; + if (fifo->bch) + fifo->bch->rx_skb = rx_skb; + if (fifo->ech) + fifo->ech->rx_skb = rx_skb; + skb_trim(rx_skb, 0); + } else { + printk(KERN_DEBUG "%s: %s: No mem for rx_skb\n", + hw->name, __func__); + spin_unlock(&hw->lock); + return; } + } + + if (fifo->dch || fifo->ech) { /* D/E-Channel SKB range check */ if ((rx_skb->len + len) >= MAX_DFRAME_LEN_L1) { printk(KERN_DEBUG "%s: %s: sbk mem exceeded " @@ -891,6 +911,16 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len, spin_unlock(&hw->lock); return; } + } else if (fifo->bch) { + /* B-Channel SKB range check */ + if ((rx_skb->len + len) >= (MAX_BCH_SIZE + 3)) { + printk(KERN_DEBUG "%s: %s: sbk mem exceeded " + "for fifo(%d) HFCUSB_B_RX\n", + hw->name, __func__, fifon); + skb_trim(rx_skb, 0); + spin_unlock(&hw->lock); + return; + } } memcpy(skb_put(rx_skb, len), data, len); @@ -918,8 +948,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len, if (fifo->dch) recv_Dchannel(fifo->dch); if (fifo->bch) - recv_Bchannel(fifo->bch, MISDN_ID_ANY, - 0); + recv_Bchannel(fifo->bch, MISDN_ID_ANY); if (fifo->ech) recv_Echannel(fifo->ech, &hw->dch); @@ -940,7 +969,8 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len, } } else { /* deliver transparent data to layer2 */ - recv_Bchannel(fifo->bch, MISDN_ID_ANY, false); + if (rx_skb->len >= poll) + recv_Bchannel(fifo->bch, MISDN_ID_ANY); } spin_unlock(&hw->lock); } @@ -1170,8 +1200,8 @@ tx_iso_complete(struct urb *urb) int k, tx_offset, num_isoc_packets, sink, remain, current_len, errcode, hdlc, i; int *tx_idx; - int frame_complete, fifon, status, fillempty = 0; - __u8 threshbit, *p; + int frame_complete, fifon, status; + __u8 threshbit; spin_lock(&hw->lock); if (fifo->stop_gracefull) { @@ -1189,9 +1219,6 @@ tx_iso_complete(struct urb *urb) tx_skb = fifo->bch->tx_skb; tx_idx = &fifo->bch->tx_idx; hdlc = test_bit(FLG_HDLC, &fifo->bch->Flags); - if (!tx_skb && !hdlc && - test_bit(FLG_FILLEMPTY, &fifo->bch->Flags)) - fillempty = 1; } else { printk(KERN_DEBUG "%s: %s: neither BCH nor DCH\n", hw->name, __func__); @@ -1250,8 +1277,6 @@ tx_iso_complete(struct urb *urb) /* Generate next ISO Packets */ if (tx_skb) remain = tx_skb->len - *tx_idx; - else if (fillempty) - remain = 15; /* > not complete */ else remain = 0; @@ -1282,20 +1307,15 @@ tx_iso_complete(struct urb *urb) } /* copy tx data to iso-urb buffer */ - p = context_iso_urb->buffer + tx_offset + 1; - if (fillempty) { - memset(p, fifo->bch->fill[0], - current_len); - } else { - memcpy(p, (tx_skb->data + *tx_idx), - current_len); - *tx_idx += current_len; - } + memcpy(context_iso_urb->buffer + tx_offset + 1, + (tx_skb->data + *tx_idx), current_len); + *tx_idx += current_len; + urb->iso_frame_desc[k].offset = tx_offset; urb->iso_frame_desc[k].length = current_len + 1; /* USB data log for every D ISO out */ - if ((fifon == HFCUSB_D_RX) && !fillempty && + if ((fifon == HFCUSB_D_RX) && (debug & DBG_HFC_USB_VERBOSE)) { printk(KERN_DEBUG "%s: %s (%d/%d) offs(%d) len(%d) ", @@ -1345,8 +1365,12 @@ tx_iso_complete(struct urb *urb) if (fifo->dch && get_next_dframe(fifo->dch)) tx_skb = fifo->dch->tx_skb; else if (fifo->bch && - get_next_bframe(fifo->bch)) + get_next_bframe(fifo->bch)) { + if (test_bit(FLG_TRANSPARENT, + &fifo->bch->Flags)) + confirm_Bsend(fifo->bch); tx_skb = fifo->bch->tx_skb; + } } } errcode = usb_submit_urb(urb, GFP_ATOMIC); @@ -1788,7 +1812,7 @@ deactivate_bchannel(struct bchannel *bch) mISDN_clear_bchannel(bch); spin_unlock_irqrestore(&hw->lock, flags); hfcsusb_setup_bch(bch, ISDN_P_NONE); - hfcsusb_stop_endpoint(hw, bch->nr - 1); + hfcsusb_stop_endpoint(hw, bch->nr); } /* @@ -1812,7 +1836,8 @@ hfc_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg) case CLOSE_CHANNEL: test_and_clear_bit(FLG_OPEN, &bch->Flags); - deactivate_bchannel(bch); + if (test_bit(FLG_ACTIVE, &bch->Flags)) + deactivate_bchannel(bch); ch->protocol = ISDN_P_NONE; ch->peer = NULL; module_put(THIS_MODULE); @@ -1858,7 +1883,7 @@ setup_instance(struct hfcsusb *hw, struct device *parent) hw->bch[i].nr = i + 1; set_channelmap(i + 1, hw->dch.dev.channelmap); hw->bch[i].debug = debug; - mISDN_initbchannel(&hw->bch[i], MAX_DATA_MEM, poll >> 1); + mISDN_initbchannel(&hw->bch[i], MAX_DATA_MEM); hw->bch[i].hw = hw; hw->bch[i].ch.send = hfcusb_l2l1B; hw->bch[i].ch.ctrl = hfc_bctrl; diff --git a/trunk/drivers/isdn/hardware/mISDN/hfcsusb.h b/trunk/drivers/isdn/hardware/mISDN/hfcsusb.h index 4157311d569d..cb1231b08f78 100644 --- a/trunk/drivers/isdn/hardware/mISDN/hfcsusb.h +++ b/trunk/drivers/isdn/hardware/mISDN/hfcsusb.h @@ -410,12 +410,6 @@ static struct usb_device_id hfcsusb_idtab[] = { {LED_SCHEME1, {0x88, -64, -32, -16}, "ZyXEL OMNI.NET USB II"}), }, - { - USB_DEVICE(0x1ae7, 0x0525), - .driver_info = (unsigned long) &((struct hfcsusb_vdata) - {LED_SCHEME1, {0x88, -64, -32, -16}, - "X-Tensions USB ISDN TA XC-525"}), - }, { } }; diff --git a/trunk/drivers/isdn/hardware/mISDN/mISDNipac.c b/trunk/drivers/isdn/hardware/mISDN/mISDNipac.c index 752e0825591f..92d4a78bc0a5 100644 --- a/trunk/drivers/isdn/hardware/mISDN/mISDNipac.c +++ b/trunk/drivers/isdn/hardware/mISDN/mISDNipac.c @@ -933,21 +933,22 @@ static void hscx_empty_fifo(struct hscx_hw *hscx, u8 count) { u8 *p; - int maxlen; pr_debug("%s: B%1d %d\n", hscx->ip->name, hscx->bch.nr, count); - if (test_bit(FLG_RX_OFF, &hscx->bch.Flags)) { - hscx->bch.dropcnt += count; - hscx_cmdr(hscx, 0x80); /* RMC */ - return; + if (!hscx->bch.rx_skb) { + hscx->bch.rx_skb = mI_alloc_skb(hscx->bch.maxlen, GFP_ATOMIC); + if (!hscx->bch.rx_skb) { + pr_info("%s: B receive out of memory\n", + hscx->ip->name); + hscx_cmdr(hscx, 0x80); /* RMC */ + return; + } } - maxlen = bchannel_get_rxbuf(&hscx->bch, count); - if (maxlen < 0) { + if ((hscx->bch.rx_skb->len + count) > hscx->bch.maxlen) { + pr_debug("%s: overrun %d\n", hscx->ip->name, + hscx->bch.rx_skb->len + count); + skb_trim(hscx->bch.rx_skb, 0); hscx_cmdr(hscx, 0x80); /* RMC */ - if (hscx->bch.rx_skb) - skb_trim(hscx->bch.rx_skb, 0); - pr_warning("%s.B%d: No bufferspace for %d bytes\n", - hscx->ip->name, hscx->bch.nr, count); return; } p = skb_put(hscx->bch.rx_skb, count); @@ -974,28 +975,22 @@ hscx_fill_fifo(struct hscx_hw *hscx) int count, more; u8 *p; - if (!hscx->bch.tx_skb) { - if (!test_bit(FLG_TX_EMPTY, &hscx->bch.Flags)) - return; + if (!hscx->bch.tx_skb) + return; + count = hscx->bch.tx_skb->len - hscx->bch.tx_idx; + if (count <= 0) + return; + p = hscx->bch.tx_skb->data + hscx->bch.tx_idx; + + more = test_bit(FLG_TRANSPARENT, &hscx->bch.Flags) ? 1 : 0; + if (count > hscx->fifo_size) { count = hscx->fifo_size; more = 1; - p = hscx->log; - memset(p, hscx->bch.fill[0], count); - } else { - count = hscx->bch.tx_skb->len - hscx->bch.tx_idx; - if (count <= 0) - return; - p = hscx->bch.tx_skb->data + hscx->bch.tx_idx; - - more = test_bit(FLG_TRANSPARENT, &hscx->bch.Flags) ? 1 : 0; - if (count > hscx->fifo_size) { - count = hscx->fifo_size; - more = 1; - } - pr_debug("%s: B%1d %d/%d/%d\n", hscx->ip->name, hscx->bch.nr, - count, hscx->bch.tx_idx, hscx->bch.tx_skb->len); - hscx->bch.tx_idx += count; } + pr_debug("%s: B%1d %d/%d/%d\n", hscx->ip->name, hscx->bch.nr, count, + hscx->bch.tx_idx, hscx->bch.tx_skb->len); + hscx->bch.tx_idx += count; + if (hscx->ip->type & IPAC_TYPE_IPACX) hscx->ip->write_fifo(hscx->ip->hw, hscx->off + IPACX_XFIFOB, p, count); @@ -1006,7 +1001,7 @@ hscx_fill_fifo(struct hscx_hw *hscx) } hscx_cmdr(hscx, more ? 0x08 : 0x0a); - if (hscx->bch.tx_skb && (hscx->bch.debug & DEBUG_HW_BFIFO)) { + if (hscx->bch.debug & DEBUG_HW_BFIFO) { snprintf(hscx->log, 64, "B%1d-send %s %d ", hscx->bch.nr, hscx->ip->name, count); print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count); @@ -1016,17 +1011,17 @@ hscx_fill_fifo(struct hscx_hw *hscx) static void hscx_xpr(struct hscx_hw *hx) { - if (hx->bch.tx_skb && hx->bch.tx_idx < hx->bch.tx_skb->len) { + if (hx->bch.tx_skb && hx->bch.tx_idx < hx->bch.tx_skb->len) hscx_fill_fifo(hx); - } else { - if (hx->bch.tx_skb) + else { + if (hx->bch.tx_skb) { + /* send confirm, on trans, free on hdlc. */ + if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) + confirm_Bsend(&hx->bch); dev_kfree_skb(hx->bch.tx_skb); - if (get_next_bframe(&hx->bch)) { - hscx_fill_fifo(hx); - test_and_clear_bit(FLG_TX_EMPTY, &hx->bch.Flags); - } else if (test_bit(FLG_TX_EMPTY, &hx->bch.Flags)) { - hscx_fill_fifo(hx); } + if (get_next_bframe(&hx->bch)) + hscx_fill_fifo(hx); } } @@ -1078,7 +1073,7 @@ ipac_rme(struct hscx_hw *hx) skb_trim(hx->bch.rx_skb, 0); } else { skb_trim(hx->bch.rx_skb, hx->bch.rx_skb->len - 1); - recv_Bchannel(&hx->bch, 0, false); + recv_Bchannel(&hx->bch, 0); } } @@ -1129,8 +1124,11 @@ ipac_irq(struct hscx_hw *hx, u8 ista) if (istab & IPACX_B_RPF) { hscx_empty_fifo(hx, hx->fifo_size); - if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) - recv_Bchannel(&hx->bch, 0, false); + if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) { + /* receive transparent audio data */ + if (hx->bch.rx_skb) + recv_Bchannel(&hx->bch, 0); + } } if (istab & IPACX_B_RFO) { @@ -1143,9 +1141,7 @@ ipac_irq(struct hscx_hw *hx, u8 ista) if (istab & IPACX_B_XDU) { if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) { - if (test_bit(FLG_FILLEMPTY, &hx->bch.Flags)) - test_and_set_bit(FLG_TX_EMPTY, &hx->bch.Flags); - hscx_xpr(hx); + hscx_fill_fifo(hx); return; } pr_debug("%s: B%1d XDU error at len %d\n", hx->ip->name, @@ -1346,17 +1342,22 @@ hscx_l2l1(struct mISDNchannel *ch, struct sk_buff *skb) struct hscx_hw *hx = container_of(bch, struct hscx_hw, bch); int ret = -EINVAL; struct mISDNhead *hh = mISDN_HEAD_P(skb); - unsigned long flags; + u32 id; + u_long flags; switch (hh->prim) { case PH_DATA_REQ: spin_lock_irqsave(hx->ip->hwlock, flags); ret = bchannel_senddata(bch, skb); if (ret > 0) { /* direct TX */ + id = hh->id; /* skb can be freed */ ret = 0; hscx_fill_fifo(hx); - } - spin_unlock_irqrestore(hx->ip->hwlock, flags); + spin_unlock_irqrestore(hx->ip->hwlock, flags); + if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) + queue_ch_frame(ch, PH_DATA_CNF, id, NULL); + } else + spin_unlock_irqrestore(hx->ip->hwlock, flags); return ret; case PH_ACTIVATE_REQ: spin_lock_irqsave(hx->ip->hwlock, flags); @@ -1391,7 +1392,20 @@ hscx_l2l1(struct mISDNchannel *ch, struct sk_buff *skb) static int channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) { - return mISDN_ctrl_bchannel(bch, cq); + int ret = 0; + + switch (cq->op) { + case MISDN_CTRL_GETOP: + cq->op = 0; + break; + /* Nothing implemented yet */ + case MISDN_CTRL_FILL_EMPTY: + default: + pr_info("%s: unknown Op %x\n", __func__, cq->op); + ret = -EINVAL; + break; + } + return ret; } static int @@ -1406,10 +1420,15 @@ hscx_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) switch (cmd) { case CLOSE_CHANNEL: test_and_clear_bit(FLG_OPEN, &bch->Flags); - spin_lock_irqsave(hx->ip->hwlock, flags); - mISDN_freebchannel(bch); - hscx_mode(hx, ISDN_P_NONE); - spin_unlock_irqrestore(hx->ip->hwlock, flags); + if (test_bit(FLG_ACTIVE, &bch->Flags)) { + spin_lock_irqsave(hx->ip->hwlock, flags); + mISDN_freebchannel(bch); + hscx_mode(hx, ISDN_P_NONE); + spin_unlock_irqrestore(hx->ip->hwlock, flags); + } else { + skb_queue_purge(&bch->rqueue); + bch->rcount = 0; + } ch->protocol = ISDN_P_NONE; ch->peer = NULL; module_put(hx->ip->owner); @@ -1609,8 +1628,7 @@ mISDNipac_init(struct ipac_hw *ipac, void *hw) set_channelmap(i + 1, ipac->isac.dch.dev.channelmap); list_add(&ipac->hscx[i].bch.ch.list, &ipac->isac.dch.dev.bchannels); - mISDN_initbchannel(&ipac->hscx[i].bch, MAX_DATA_MEM, - ipac->hscx[i].fifo_size); + mISDN_initbchannel(&ipac->hscx[i].bch, MAX_DATA_MEM); ipac->hscx[i].bch.ch.nr = i + 1; ipac->hscx[i].bch.ch.send = &hscx_l2l1; ipac->hscx[i].bch.ch.ctrl = hscx_bctrl; diff --git a/trunk/drivers/isdn/hardware/mISDN/mISDNisar.c b/trunk/drivers/isdn/hardware/mISDN/mISDNisar.c index be5973ded6d6..9a6da6edcfa8 100644 --- a/trunk/drivers/isdn/hardware/mISDN/mISDNisar.c +++ b/trunk/drivers/isdn/hardware/mISDN/mISDNisar.c @@ -421,19 +421,13 @@ deliver_status(struct isar_ch *ch, int status) static inline void isar_rcv_frame(struct isar_ch *ch) { - u8 *ptr; - int maxlen; + u8 *ptr; if (!ch->is->clsb) { pr_debug("%s; ISAR zero len frame\n", ch->is->name); ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); return; } - if (test_bit(FLG_RX_OFF, &ch->bch.Flags)) { - ch->bch.dropcnt += ch->is->clsb; - ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); - return; - } switch (ch->bch.state) { case ISDN_P_NONE: pr_debug("%s: ISAR protocol 0 spurious IIS_RDATA %x/%x/%x\n", @@ -443,22 +437,36 @@ isar_rcv_frame(struct isar_ch *ch) case ISDN_P_B_RAW: case ISDN_P_B_L2DTMF: case ISDN_P_B_MODEM_ASYNC: - maxlen = bchannel_get_rxbuf(&ch->bch, ch->is->clsb); - if (maxlen < 0) { - pr_warning("%s.B%d: No bufferspace for %d bytes\n", - ch->is->name, ch->bch.nr, ch->is->clsb); - ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); - break; + if (!ch->bch.rx_skb) { + ch->bch.rx_skb = mI_alloc_skb(ch->bch.maxlen, + GFP_ATOMIC); + if (unlikely(!ch->bch.rx_skb)) { + pr_info("%s: B receive out of memory\n", + ch->is->name); + ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); + break; + } } rcv_mbox(ch->is, skb_put(ch->bch.rx_skb, ch->is->clsb)); - recv_Bchannel(&ch->bch, 0, false); + recv_Bchannel(&ch->bch, 0); break; case ISDN_P_B_HDLC: - maxlen = bchannel_get_rxbuf(&ch->bch, ch->is->clsb); - if (maxlen < 0) { - pr_warning("%s.B%d: No bufferspace for %d bytes\n", - ch->is->name, ch->bch.nr, ch->is->clsb); + if (!ch->bch.rx_skb) { + ch->bch.rx_skb = mI_alloc_skb(ch->bch.maxlen, + GFP_ATOMIC); + if (unlikely(!ch->bch.rx_skb)) { + pr_info("%s: B receive out of memory\n", + ch->is->name); + ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); + break; + } + } + if ((ch->bch.rx_skb->len + ch->is->clsb) > + (ch->bch.maxlen + 2)) { + pr_debug("%s: incoming packet too large\n", + ch->is->name); ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); + skb_trim(ch->bch.rx_skb, 0); break; } if (ch->is->cmsb & HDLC_ERROR) { @@ -486,7 +494,7 @@ isar_rcv_frame(struct isar_ch *ch) break; } skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2); - recv_Bchannel(&ch->bch, 0, false); + recv_Bchannel(&ch->bch, 0); } break; case ISDN_P_B_T30_FAX: @@ -522,7 +530,7 @@ isar_rcv_frame(struct isar_ch *ch) ch->state = STFAX_ESCAPE; /* set_skb_flag(skb, DF_NOMOREDATA); */ } - recv_Bchannel(&ch->bch, 0, false); + recv_Bchannel(&ch->bch, 0); if (ch->is->cmsb & SART_NMD) deliver_status(ch, HW_MOD_NOCARR); break; @@ -562,7 +570,7 @@ isar_rcv_frame(struct isar_ch *ch) break; } skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2); - recv_Bchannel(&ch->bch, 0, false); + recv_Bchannel(&ch->bch, 0); } if (ch->is->cmsb & SART_NMD) { /* ABORT */ pr_debug("%s: isar_rcv_frame: no more data\n", @@ -590,25 +598,16 @@ isar_fill_fifo(struct isar_ch *ch) u8 msb; u8 *ptr; - pr_debug("%s: ch%d tx_skb %d tx_idx %d\n", ch->is->name, ch->bch.nr, - ch->bch.tx_skb ? ch->bch.tx_skb->len : -1, ch->bch.tx_idx); - if (!(ch->is->bstat & - (ch->dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2))) - return; - if (!ch->bch.tx_skb) { - if (!test_bit(FLG_TX_EMPTY, &ch->bch.Flags) || - (ch->bch.state != ISDN_P_B_RAW)) - return; - count = ch->mml; - /* use the card buffer */ - memset(ch->is->buf, ch->bch.fill[0], count); - send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA, - 0, count, ch->is->buf); + pr_debug("%s: ch%d tx_skb %p tx_idx %d\n", + ch->is->name, ch->bch.nr, ch->bch.tx_skb, ch->bch.tx_idx); + if (!ch->bch.tx_skb) return; - } count = ch->bch.tx_skb->len - ch->bch.tx_idx; if (count <= 0) return; + if (!(ch->is->bstat & + (ch->dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2))) + return; if (count > ch->mml) { msb = 0; count = ch->mml; @@ -687,9 +686,9 @@ sel_bch_isar(struct isar_hw *isar, u8 dpath) static void send_next(struct isar_ch *ch) { - pr_debug("%s: %s ch%d tx_skb %d tx_idx %d\n", ch->is->name, __func__, - ch->bch.nr, ch->bch.tx_skb ? ch->bch.tx_skb->len : -1, - ch->bch.tx_idx); + pr_debug("%s: %s ch%d tx_skb %p tx_idx %d\n", + ch->is->name, __func__, ch->bch.nr, + ch->bch.tx_skb, ch->bch.tx_idx); if (ch->bch.state == ISDN_P_B_T30_FAX) { if (ch->cmd == PCTRL_CMD_FTH) { if (test_bit(FLG_LASTDATA, &ch->bch.Flags)) { @@ -703,14 +702,15 @@ send_next(struct isar_ch *ch) } } } - if (ch->bch.tx_skb) + if (ch->bch.tx_skb) { + /* send confirm, on trans, free on hdlc. */ + if (test_bit(FLG_TRANSPARENT, &ch->bch.Flags)) + confirm_Bsend(&ch->bch); dev_kfree_skb(ch->bch.tx_skb); - if (get_next_bframe(&ch->bch)) { - isar_fill_fifo(ch); - test_and_clear_bit(FLG_TX_EMPTY, &ch->bch.Flags); - } else if (test_bit(FLG_TX_EMPTY, &ch->bch.Flags)) { + } + if (get_next_bframe(&ch->bch)) isar_fill_fifo(ch); - } else { + else { if (test_and_clear_bit(FLG_DLEETX, &ch->bch.Flags)) { if (test_and_clear_bit(FLG_LASTDATA, &ch->bch.Flags)) { @@ -724,8 +724,6 @@ send_next(struct isar_ch *ch) } else { deliver_status(ch, HW_MOD_CONNECT); } - } else if (test_bit(FLG_FILLEMPTY, &ch->bch.Flags)) { - test_and_set_bit(FLG_TX_EMPTY, &ch->bch.Flags); } } } @@ -1489,10 +1487,14 @@ isar_l2l1(struct mISDNchannel *ch, struct sk_buff *skb) spin_lock_irqsave(ich->is->hwlock, flags); ret = bchannel_senddata(bch, skb); if (ret > 0) { /* direct TX */ + id = hh->id; /* skb can be freed */ ret = 0; isar_fill_fifo(ich); - } - spin_unlock_irqrestore(ich->is->hwlock, flags); + spin_unlock_irqrestore(ich->is->hwlock, flags); + if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) + queue_ch_frame(ch, PH_DATA_CNF, id, NULL); + } else + spin_unlock_irqrestore(ich->is->hwlock, flags); return ret; case PH_ACTIVATE_REQ: spin_lock_irqsave(ich->is->hwlock, flags); @@ -1573,7 +1575,20 @@ isar_l2l1(struct mISDNchannel *ch, struct sk_buff *skb) static int channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) { - return mISDN_ctrl_bchannel(bch, cq); + int ret = 0; + + switch (cq->op) { + case MISDN_CTRL_GETOP: + cq->op = 0; + break; + /* Nothing implemented yet */ + case MISDN_CTRL_FILL_EMPTY: + default: + pr_info("%s: unknown Op %x\n", __func__, cq->op); + ret = -EINVAL; + break; + } + return ret; } static int @@ -1588,10 +1603,15 @@ isar_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) switch (cmd) { case CLOSE_CHANNEL: test_and_clear_bit(FLG_OPEN, &bch->Flags); - spin_lock_irqsave(ich->is->hwlock, flags); - mISDN_freebchannel(bch); - modeisar(ich, ISDN_P_NONE); - spin_unlock_irqrestore(ich->is->hwlock, flags); + if (test_bit(FLG_ACTIVE, &bch->Flags)) { + spin_lock_irqsave(ich->is->hwlock, flags); + mISDN_freebchannel(bch); + modeisar(ich, ISDN_P_NONE); + spin_unlock_irqrestore(ich->is->hwlock, flags); + } else { + skb_queue_purge(&bch->rqueue); + bch->rcount = 0; + } ch->protocol = ISDN_P_NONE; ch->peer = NULL; module_put(ich->is->owner); @@ -1657,6 +1677,7 @@ isar_open(struct isar_hw *isar, struct channel_req *rq) bch = &isar->ch[rq->adr.channel - 1].bch; if (test_and_set_bit(FLG_OPEN, &bch->Flags)) return -EBUSY; /* b-channel can be only open once */ + test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); bch->ch.protocol = rq->protocol; rq->ch = &bch->ch; return 0; @@ -1670,7 +1691,7 @@ mISDNisar_init(struct isar_hw *isar, void *hw) isar->hw = hw; for (i = 0; i < 2; i++) { isar->ch[i].bch.nr = i + 1; - mISDN_initbchannel(&isar->ch[i].bch, MAX_DATA_MEM, 32); + mISDN_initbchannel(&isar->ch[i].bch, MAX_DATA_MEM); isar->ch[i].bch.ch.nr = i + 1; isar->ch[i].bch.ch.send = &isar_l2l1; isar->ch[i].bch.ch.ctrl = isar_bctrl; diff --git a/trunk/drivers/isdn/hardware/mISDN/netjet.c b/trunk/drivers/isdn/hardware/mISDN/netjet.c index c3e3e7686273..27998d7188a5 100644 --- a/trunk/drivers/isdn/hardware/mISDN/netjet.c +++ b/trunk/drivers/isdn/hardware/mISDN/netjet.c @@ -386,20 +386,24 @@ read_dma(struct tiger_ch *bc, u32 idx, int cnt) bc->bch.nr, idx); } bc->lastrx = idx; - if (test_bit(FLG_RX_OFF, &bc->bch.Flags)) { - bc->bch.dropcnt += cnt; - return; - } - stat = bchannel_get_rxbuf(&bc->bch, cnt); - /* only transparent use the count here, HDLC overun is detected later */ - if (stat == ENOMEM) { - pr_warning("%s.B%d: No memory for %d bytes\n", - card->name, bc->bch.nr, cnt); - return; + if (!bc->bch.rx_skb) { + bc->bch.rx_skb = mI_alloc_skb(bc->bch.maxlen, GFP_ATOMIC); + if (!bc->bch.rx_skb) { + pr_info("%s: B%1d receive out of memory\n", + card->name, bc->bch.nr); + return; + } } - if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags)) + + if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags)) { + if ((bc->bch.rx_skb->len + cnt) > bc->bch.maxlen) { + pr_debug("%s: B%1d overrun %d\n", card->name, + bc->bch.nr, bc->bch.rx_skb->len + cnt); + skb_trim(bc->bch.rx_skb, 0); + return; + } p = skb_put(bc->bch.rx_skb, cnt); - else + } else p = bc->hrbuf; for (i = 0; i < cnt; i++) { @@ -410,45 +414,48 @@ read_dma(struct tiger_ch *bc, u32 idx, int cnt) idx = 0; p[i] = val & 0xff; } - - if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags)) { - recv_Bchannel(&bc->bch, 0, false); - return; - } - pn = bc->hrbuf; - while (cnt > 0) { +next_frame: + if (test_bit(FLG_HDLC, &bc->bch.Flags)) { stat = isdnhdlc_decode(&bc->hrecv, pn, cnt, &i, bc->bch.rx_skb->data, bc->bch.maxlen); - if (stat > 0) { /* valid frame received */ + if (stat > 0) /* valid frame received */ p = skb_put(bc->bch.rx_skb, stat); - if (debug & DEBUG_HW_BFIFO) { - snprintf(card->log, LOG_SIZE, - "B%1d-recv %s %d ", bc->bch.nr, - card->name, stat); - print_hex_dump_bytes(card->log, - DUMP_PREFIX_OFFSET, p, - stat); - } - recv_Bchannel(&bc->bch, 0, false); - stat = bchannel_get_rxbuf(&bc->bch, bc->bch.maxlen); - if (stat < 0) { - pr_warning("%s.B%d: No memory for %d bytes\n", - card->name, bc->bch.nr, cnt); - return; - } - } else if (stat == -HDLC_CRC_ERROR) { + else if (stat == -HDLC_CRC_ERROR) pr_info("%s: B%1d receive frame CRC error\n", card->name, bc->bch.nr); - } else if (stat == -HDLC_FRAMING_ERROR) { + else if (stat == -HDLC_FRAMING_ERROR) pr_info("%s: B%1d receive framing error\n", card->name, bc->bch.nr); - } else if (stat == -HDLC_LENGTH_ERROR) { + else if (stat == -HDLC_LENGTH_ERROR) pr_info("%s: B%1d receive frame too long (> %d)\n", card->name, bc->bch.nr, bc->bch.maxlen); + } else + stat = cnt; + + if (stat > 0) { + if (debug & DEBUG_HW_BFIFO) { + snprintf(card->log, LOG_SIZE, "B%1d-recv %s %d ", + bc->bch.nr, card->name, stat); + print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, + p, stat); } + recv_Bchannel(&bc->bch, 0); + } + if (test_bit(FLG_HDLC, &bc->bch.Flags)) { pn += i; cnt -= i; + if (!bc->bch.rx_skb) { + bc->bch.rx_skb = mI_alloc_skb(bc->bch.maxlen, + GFP_ATOMIC); + if (!bc->bch.rx_skb) { + pr_info("%s: B%1d receive out of memory\n", + card->name, bc->bch.nr); + return; + } + } + if (cnt > 0) + goto next_frame; } } @@ -537,31 +544,22 @@ static void fill_dma(struct tiger_ch *bc) { struct tiger_hw *card = bc->bch.hw; - int count, i, fillempty = 0; - u32 m, v, n = 0; + int count, i; + u32 m, v; u8 *p; if (bc->free == 0) return; - if (!bc->bch.tx_skb) { - if (!test_bit(FLG_TX_EMPTY, &bc->bch.Flags)) - return; - fillempty = 1; - count = card->send.size >> 1; - p = bc->bch.fill; - } else { - count = bc->bch.tx_skb->len - bc->bch.tx_idx; - if (count <= 0) - return; - pr_debug("%s: %s B%1d %d/%d/%d/%d state %x idx %d/%d\n", - card->name, __func__, bc->bch.nr, count, bc->free, - bc->bch.tx_idx, bc->bch.tx_skb->len, bc->txstate, - bc->idx, card->send.idx); - p = bc->bch.tx_skb->data + bc->bch.tx_idx; - } + count = bc->bch.tx_skb->len - bc->bch.tx_idx; + if (count <= 0) + return; + pr_debug("%s: %s B%1d %d/%d/%d/%d state %x idx %d/%d\n", card->name, + __func__, bc->bch.nr, count, bc->free, bc->bch.tx_idx, + bc->bch.tx_skb->len, bc->txstate, bc->idx, card->send.idx); if (bc->txstate & (TX_IDLE | TX_INIT | TX_UNDERRUN)) resync(bc, card); - if (test_bit(FLG_HDLC, &bc->bch.Flags) && !fillempty) { + p = bc->bch.tx_skb->data + bc->bch.tx_idx; + if (test_bit(FLG_HDLC, &bc->bch.Flags)) { count = isdnhdlc_encode(&bc->hsend, p, count, &i, bc->hsbuf, bc->free); pr_debug("%s: B%1d hdlc encoded %d in %d\n", card->name, @@ -572,33 +570,17 @@ fill_dma(struct tiger_ch *bc) } else { if (count > bc->free) count = bc->free; - if (!fillempty) - bc->bch.tx_idx += count; + bc->bch.tx_idx += count; bc->free -= count; } m = (bc->bch.nr & 1) ? 0xffffff00 : 0xffff00ff; - if (fillempty) { - n = p[0]; - if (!(bc->bch.nr & 1)) - n <<= 8; - for (i = 0; i < count; i++) { - if (bc->idx >= card->send.size) - bc->idx = 0; - v = card->send.start[bc->idx]; - v &= m; - v |= n; - card->send.start[bc->idx++] = v; - } - } else { - for (i = 0; i < count; i++) { - if (bc->idx >= card->send.size) - bc->idx = 0; - v = card->send.start[bc->idx]; - v &= m; - n = p[i]; - v |= (bc->bch.nr & 1) ? n : n << 8; - card->send.start[bc->idx++] = v; - } + for (i = 0; i < count; i++) { + if (bc->idx >= card->send.size) + bc->idx = 0; + v = card->send.start[bc->idx]; + v &= m; + v |= (bc->bch.nr & 1) ? (u32)(p[i]) : ((u32)(p[i])) << 8; + card->send.start[bc->idx++] = v; } if (debug & DEBUG_HW_BFIFO) { snprintf(card->log, LOG_SIZE, "B%1d-send %s %d ", @@ -613,26 +595,21 @@ fill_dma(struct tiger_ch *bc) static int bc_next_frame(struct tiger_ch *bc) { - int ret = 1; - - if (bc->bch.tx_skb && bc->bch.tx_idx < bc->bch.tx_skb->len) { + if (bc->bch.tx_skb && bc->bch.tx_idx < bc->bch.tx_skb->len) fill_dma(bc); - } else { - if (bc->bch.tx_skb) + else { + if (bc->bch.tx_skb) { + /* send confirm, on trans, free on hdlc. */ + if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags)) + confirm_Bsend(&bc->bch); dev_kfree_skb(bc->bch.tx_skb); - if (get_next_bframe(&bc->bch)) { - fill_dma(bc); - test_and_clear_bit(FLG_TX_EMPTY, &bc->bch.Flags); - } else if (test_bit(FLG_TX_EMPTY, &bc->bch.Flags)) { - fill_dma(bc); - } else if (test_bit(FLG_FILLEMPTY, &bc->bch.Flags)) { - test_and_set_bit(FLG_TX_EMPTY, &bc->bch.Flags); - ret = 0; - } else { - ret = 0; } + if (get_next_bframe(&bc->bch)) + fill_dma(bc); + else + return 0; } - return ret; + return 1; } static void @@ -755,17 +732,22 @@ nj_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb) struct tiger_ch *bc = container_of(bch, struct tiger_ch, bch); struct tiger_hw *card = bch->hw; struct mISDNhead *hh = mISDN_HEAD_P(skb); - unsigned long flags; + u32 id; + u_long flags; switch (hh->prim) { case PH_DATA_REQ: spin_lock_irqsave(&card->lock, flags); ret = bchannel_senddata(bch, skb); if (ret > 0) { /* direct TX */ + id = hh->id; /* skb can be freed */ fill_dma(bc); ret = 0; - } - spin_unlock_irqrestore(&card->lock, flags); + spin_unlock_irqrestore(&card->lock, flags); + if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) + queue_ch_frame(ch, PH_DATA_CNF, id, NULL); + } else + spin_unlock_irqrestore(&card->lock, flags); return ret; case PH_ACTIVATE_REQ: spin_lock_irqsave(&card->lock, flags); @@ -796,7 +778,21 @@ nj_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb) static int channel_bctrl(struct tiger_ch *bc, struct mISDN_ctrl_req *cq) { - return mISDN_ctrl_bchannel(&bc->bch, cq); + int ret = 0; + struct tiger_hw *card = bc->bch.hw; + + switch (cq->op) { + case MISDN_CTRL_GETOP: + cq->op = 0; + break; + /* Nothing implemented yet */ + case MISDN_CTRL_FILL_EMPTY: + default: + pr_info("%s: %s unknown Op %x\n", card->name, __func__, cq->op); + ret = -EINVAL; + break; + } + return ret; } static int @@ -812,10 +808,14 @@ nj_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) switch (cmd) { case CLOSE_CHANNEL: test_and_clear_bit(FLG_OPEN, &bch->Flags); - spin_lock_irqsave(&card->lock, flags); - mISDN_freebchannel(bch); - mode_tiger(bc, ISDN_P_NONE); - spin_unlock_irqrestore(&card->lock, flags); + if (test_bit(FLG_ACTIVE, &bch->Flags)) { + spin_lock_irqsave(&card->lock, flags); + mISDN_freebchannel(bch); + test_and_clear_bit(FLG_TX_BUSY, &bch->Flags); + test_and_clear_bit(FLG_ACTIVE, &bch->Flags); + mode_tiger(bc, ISDN_P_NONE); + spin_unlock_irqrestore(&card->lock, flags); + } ch->protocol = ISDN_P_NONE; ch->peer = NULL; module_put(THIS_MODULE); @@ -1030,8 +1030,7 @@ setup_instance(struct tiger_hw *card) for (i = 0; i < 2; i++) { card->bc[i].bch.nr = i + 1; set_channelmap(i + 1, card->isac.dch.dev.channelmap); - mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM, - NJ_DMA_RXSIZE >> 1); + mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM); card->bc[i].bch.hw = card; card->bc[i].bch.ch.send = nj_l2l1B; card->bc[i].bch.ch.ctrl = nj_bctrl; diff --git a/trunk/drivers/isdn/hardware/mISDN/w6692.c b/trunk/drivers/isdn/hardware/mISDN/w6692.c index 26a86b846099..1d044670ff66 100644 --- a/trunk/drivers/isdn/hardware/mISDN/w6692.c +++ b/trunk/drivers/isdn/hardware/mISDN/w6692.c @@ -465,7 +465,6 @@ W6692_empty_Bfifo(struct w6692_ch *wch, int count) { struct w6692_hw *card = wch->bch.hw; u8 *ptr; - int maxlen; pr_debug("%s: empty_Bfifo %d\n", card->name, count); if (unlikely(wch->bch.state == ISDN_P_NONE)) { @@ -475,18 +474,20 @@ W6692_empty_Bfifo(struct w6692_ch *wch, int count) skb_trim(wch->bch.rx_skb, 0); return; } - if (test_bit(FLG_RX_OFF, &wch->bch.Flags)) { - wch->bch.dropcnt += count; - WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT); - return; + if (!wch->bch.rx_skb) { + wch->bch.rx_skb = mI_alloc_skb(wch->bch.maxlen, GFP_ATOMIC); + if (unlikely(!wch->bch.rx_skb)) { + pr_info("%s: B receive out of memory\n", card->name); + WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | + W_B_CMDR_RACT); + return; + } } - maxlen = bchannel_get_rxbuf(&wch->bch, count); - if (maxlen < 0) { + if (wch->bch.rx_skb->len + count > wch->bch.maxlen) { + pr_debug("%s: empty_Bfifo incoming packet too large\n", + card->name); WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT); - if (wch->bch.rx_skb) - skb_trim(wch->bch.rx_skb, 0); - pr_warning("%s.B%d: No bufferspace for %d bytes\n", - card->name, wch->bch.nr, count); + skb_trim(wch->bch.rx_skb, 0); return; } ptr = skb_put(wch->bch.rx_skb, count); @@ -503,22 +504,16 @@ static void W6692_fill_Bfifo(struct w6692_ch *wch) { struct w6692_hw *card = wch->bch.hw; - int count, fillempty = 0; + int count; u8 *ptr, cmd = W_B_CMDR_RACT | W_B_CMDR_XMS; pr_debug("%s: fill Bfifo\n", card->name); - if (!wch->bch.tx_skb) { - if (!test_bit(FLG_TX_EMPTY, &wch->bch.Flags)) - return; - ptr = wch->bch.fill; - count = W_B_FIFO_THRESH; - fillempty = 1; - } else { - count = wch->bch.tx_skb->len - wch->bch.tx_idx; - if (count <= 0) - return; - ptr = wch->bch.tx_skb->data + wch->bch.tx_idx; - } + if (!wch->bch.tx_skb) + return; + count = wch->bch.tx_skb->len - wch->bch.tx_idx; + if (count <= 0) + return; + ptr = wch->bch.tx_skb->data + wch->bch.tx_idx; if (count > W_B_FIFO_THRESH) count = W_B_FIFO_THRESH; else if (test_bit(FLG_HDLC, &wch->bch.Flags)) @@ -527,16 +522,9 @@ W6692_fill_Bfifo(struct w6692_ch *wch) pr_debug("%s: fill Bfifo%d/%d\n", card->name, count, wch->bch.tx_idx); wch->bch.tx_idx += count; - if (fillempty) { - while (count > 0) { - outsb(wch->addr + W_B_XFIFO, ptr, MISDN_BCH_FILL_SIZE); - count -= MISDN_BCH_FILL_SIZE; - } - } else { - outsb(wch->addr + W_B_XFIFO, ptr, count); - } + outsb(wch->addr + W_B_XFIFO, ptr, count); WriteW6692B(wch, W_B_CMDR, cmd); - if ((debug & DEBUG_HW_BFIFO) && !fillempty) { + if (debug & DEBUG_HW_DFIFO) { snprintf(card->log, 63, "B%1d-send %s %d ", wch->bch.nr, card->name, count); print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count); @@ -650,17 +638,17 @@ w6692_mode(struct w6692_ch *wch, u32 pr) static void send_next(struct w6692_ch *wch) { - if (wch->bch.tx_skb && wch->bch.tx_idx < wch->bch.tx_skb->len) { + if (wch->bch.tx_skb && wch->bch.tx_idx < wch->bch.tx_skb->len) W6692_fill_Bfifo(wch); - } else { - if (wch->bch.tx_skb) + else { + if (wch->bch.tx_skb) { + /* send confirm, on trans, free on hdlc. */ + if (test_bit(FLG_TRANSPARENT, &wch->bch.Flags)) + confirm_Bsend(&wch->bch); dev_kfree_skb(wch->bch.tx_skb); - if (get_next_bframe(&wch->bch)) { - W6692_fill_Bfifo(wch); - test_and_clear_bit(FLG_TX_EMPTY, &wch->bch.Flags); - } else if (test_bit(FLG_TX_EMPTY, &wch->bch.Flags)) { - W6692_fill_Bfifo(wch); } + if (get_next_bframe(&wch->bch)) + W6692_fill_Bfifo(wch); } } @@ -710,7 +698,7 @@ W6692B_interrupt(struct w6692_hw *card, int ch) if (count == 0) count = W_B_FIFO_THRESH; W6692_empty_Bfifo(wch, count); - recv_Bchannel(&wch->bch, 0, false); + recv_Bchannel(&wch->bch, 0); } } if (stat & W_B_EXI_RMR) { @@ -726,8 +714,9 @@ W6692B_interrupt(struct w6692_hw *card, int ch) W_B_CMDR_RRST | W_B_CMDR_RACT); } else { W6692_empty_Bfifo(wch, W_B_FIFO_THRESH); - if (test_bit(FLG_TRANSPARENT, &wch->bch.Flags)) - recv_Bchannel(&wch->bch, 0, false); + if (test_bit(FLG_TRANSPARENT, &wch->bch.Flags) && + wch->bch.rx_skb && (wch->bch.rx_skb->len > 0)) + recv_Bchannel(&wch->bch, 0); } } if (stat & W_B_EXI_RDOV) { @@ -749,8 +738,8 @@ W6692B_interrupt(struct w6692_hw *card, int ch) wch->bch.nr, star); } if (star & W_B_STAR_XDOW) { - pr_warning("%s: B%d XDOW proto=%x\n", card->name, - wch->bch.nr, wch->bch.state); + pr_debug("%s: B%d XDOW proto=%x\n", card->name, + wch->bch.nr, wch->bch.state); #ifdef ERROR_STATISTIC wch->bch.err_xdu++; #endif @@ -763,21 +752,20 @@ W6692B_interrupt(struct w6692_hw *card, int ch) } } send_next(wch); - if (star & W_B_STAR_XDOW) + if (stat & W_B_EXI_XDUN) return; /* handle XDOW only once */ } if (stat & W_B_EXI_XDUN) { - pr_warning("%s: B%d XDUN proto=%x\n", card->name, - wch->bch.nr, wch->bch.state); + pr_debug("%s: B%d XDUN proto=%x\n", card->name, + wch->bch.nr, wch->bch.state); #ifdef ERROR_STATISTIC wch->bch.err_xdu++; #endif - /* resend - no XRST needed */ + WriteW6692B(wch, W_B_CMDR, W_B_CMDR_XRST | W_B_CMDR_RACT); + /* resend */ if (wch->bch.tx_skb) { if (!test_bit(FLG_TRANSPARENT, &wch->bch.Flags)) wch->bch.tx_idx = 0; - } else if (test_bit(FLG_FILLEMPTY, &wch->bch.Flags)) { - test_and_set_bit(FLG_TX_EMPTY, &wch->bch.Flags); } send_next(wch); } @@ -956,17 +944,22 @@ w6692_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb) struct w6692_hw *card = bch->hw; int ret = -EINVAL; struct mISDNhead *hh = mISDN_HEAD_P(skb); - unsigned long flags; + u32 id; + u_long flags; switch (hh->prim) { case PH_DATA_REQ: spin_lock_irqsave(&card->lock, flags); ret = bchannel_senddata(bch, skb); if (ret > 0) { /* direct TX */ + id = hh->id; /* skb can be freed */ ret = 0; W6692_fill_Bfifo(bc); - } - spin_unlock_irqrestore(&card->lock, flags); + spin_unlock_irqrestore(&card->lock, flags); + if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) + queue_ch_frame(ch, PH_DATA_CNF, id, NULL); + } else + spin_unlock_irqrestore(&card->lock, flags); return ret; case PH_ACTIVATE_REQ: spin_lock_irqsave(&card->lock, flags); @@ -1001,7 +994,20 @@ w6692_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb) static int channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) { - return mISDN_ctrl_bchannel(bch, cq); + int ret = 0; + + switch (cq->op) { + case MISDN_CTRL_GETOP: + cq->op = 0; + break; + /* Nothing implemented yet */ + case MISDN_CTRL_FILL_EMPTY: + default: + pr_info("%s: unknown Op %x\n", __func__, cq->op); + ret = -EINVAL; + break; + } + return ret; } static int @@ -1016,6 +1022,7 @@ open_bchannel(struct w6692_hw *card, struct channel_req *rq) bch = &card->bc[rq->adr.channel - 1].bch; if (test_and_set_bit(FLG_OPEN, &bch->Flags)) return -EBUSY; /* b-channel can be only open once */ + test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); bch->ch.protocol = rq->protocol; rq->ch = &bch->ch; return 0; @@ -1054,10 +1061,15 @@ w6692_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) switch (cmd) { case CLOSE_CHANNEL: test_and_clear_bit(FLG_OPEN, &bch->Flags); - spin_lock_irqsave(&card->lock, flags); - mISDN_freebchannel(bch); - w6692_mode(bc, ISDN_P_NONE); - spin_unlock_irqrestore(&card->lock, flags); + if (test_bit(FLG_ACTIVE, &bch->Flags)) { + spin_lock_irqsave(&card->lock, flags); + mISDN_freebchannel(bch); + w6692_mode(bc, ISDN_P_NONE); + spin_unlock_irqrestore(&card->lock, flags); + } else { + skb_queue_purge(&bch->rqueue); + bch->rcount = 0; + } ch->protocol = ISDN_P_NONE; ch->peer = NULL; module_put(THIS_MODULE); @@ -1311,8 +1323,7 @@ setup_instance(struct w6692_hw *card) card->dch.hw = card; card->dch.dev.nrbchan = 2; for (i = 0; i < 2; i++) { - mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM, - W_B_FIFO_THRESH); + mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM); card->bc[i].bch.hw = card; card->bc[i].bch.nr = i + 1; card->bc[i].bch.ch.nr = i + 1; diff --git a/trunk/drivers/isdn/i4l/isdn_bsdcomp.c b/trunk/drivers/isdn/i4l/isdn_bsdcomp.c index 8837ac5a492d..c59e8d2c0675 100644 --- a/trunk/drivers/isdn/i4l/isdn_bsdcomp.c +++ b/trunk/drivers/isdn/i4l/isdn_bsdcomp.c @@ -612,7 +612,7 @@ static int bsd_compress(void *state, struct sk_buff *skb_in, struct sk_buff *skb db->n_bits++; /* If output length is too large then this is an incompressible frame. */ - if (!skb_out || skb_out->len >= skb_in->len) { + if (!skb_out || (skb_out && skb_out->len >= skb_in->len)) { ++db->incomp_count; db->incomp_bytes += isize; return 0; diff --git a/trunk/drivers/isdn/mISDN/dsp_core.c b/trunk/drivers/isdn/mISDN/dsp_core.c index 28c99c623bcd..2ac2d7a25a9f 100644 --- a/trunk/drivers/isdn/mISDN/dsp_core.c +++ b/trunk/drivers/isdn/mISDN/dsp_core.c @@ -268,7 +268,6 @@ dsp_fill_empty(struct dsp *dsp) } cq.op = MISDN_CTRL_FILL_EMPTY; cq.p1 = 1; - cq.p2 = dsp_silence; if (dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq)) { printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n", __func__); diff --git a/trunk/drivers/isdn/mISDN/hwchannel.c b/trunk/drivers/isdn/mISDN/hwchannel.c index ef34fd40867c..c74c363554c4 100644 --- a/trunk/drivers/isdn/mISDN/hwchannel.c +++ b/trunk/drivers/isdn/mISDN/hwchannel.c @@ -81,16 +81,10 @@ mISDN_initdchannel(struct dchannel *ch, int maxlen, void *phf) EXPORT_SYMBOL(mISDN_initdchannel); int -mISDN_initbchannel(struct bchannel *ch, unsigned short maxlen, - unsigned short minlen) +mISDN_initbchannel(struct bchannel *ch, int maxlen) { ch->Flags = 0; - ch->minlen = minlen; - ch->next_minlen = minlen; - ch->init_minlen = minlen; ch->maxlen = maxlen; - ch->next_maxlen = maxlen; - ch->init_maxlen = maxlen; ch->hw = NULL; ch->rx_skb = NULL; ch->tx_skb = NULL; @@ -140,14 +134,6 @@ mISDN_clear_bchannel(struct bchannel *ch) test_and_clear_bit(FLG_TX_BUSY, &ch->Flags); test_and_clear_bit(FLG_TX_NEXT, &ch->Flags); test_and_clear_bit(FLG_ACTIVE, &ch->Flags); - test_and_clear_bit(FLG_FILLEMPTY, &ch->Flags); - test_and_clear_bit(FLG_TX_EMPTY, &ch->Flags); - test_and_clear_bit(FLG_RX_OFF, &ch->Flags); - ch->dropcnt = 0; - ch->minlen = ch->init_minlen; - ch->next_minlen = ch->init_minlen; - ch->maxlen = ch->init_maxlen; - ch->next_maxlen = ch->init_maxlen; } EXPORT_SYMBOL(mISDN_clear_bchannel); @@ -162,51 +148,6 @@ mISDN_freebchannel(struct bchannel *ch) } EXPORT_SYMBOL(mISDN_freebchannel); -int -mISDN_ctrl_bchannel(struct bchannel *bch, struct mISDN_ctrl_req *cq) -{ - int ret = 0; - - switch (cq->op) { - case MISDN_CTRL_GETOP: - cq->op = MISDN_CTRL_RX_BUFFER | MISDN_CTRL_FILL_EMPTY | - MISDN_CTRL_RX_OFF; - break; - case MISDN_CTRL_FILL_EMPTY: - if (cq->p1) { - memset(bch->fill, cq->p2 & 0xff, MISDN_BCH_FILL_SIZE); - test_and_set_bit(FLG_FILLEMPTY, &bch->Flags); - } else { - test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); - } - break; - case MISDN_CTRL_RX_OFF: - /* read back dropped byte count */ - cq->p2 = bch->dropcnt; - if (cq->p1) - test_and_set_bit(FLG_RX_OFF, &bch->Flags); - else - test_and_clear_bit(FLG_RX_OFF, &bch->Flags); - bch->dropcnt = 0; - break; - case MISDN_CTRL_RX_BUFFER: - if (cq->p2 > MISDN_CTRL_RX_SIZE_IGNORE) - bch->next_maxlen = cq->p2; - if (cq->p1 > MISDN_CTRL_RX_SIZE_IGNORE) - bch->next_minlen = cq->p1; - /* we return the old values */ - cq->p1 = bch->minlen; - cq->p2 = bch->maxlen; - break; - default: - pr_info("mISDN unhandled control %x operation\n", cq->op); - ret = -EINVAL; - break; - } - return ret; -} -EXPORT_SYMBOL(mISDN_ctrl_bchannel); - static inline u_int get_sapi_tei(u_char *p) { @@ -256,37 +197,24 @@ recv_Echannel(struct dchannel *ech, struct dchannel *dch) EXPORT_SYMBOL(recv_Echannel); void -recv_Bchannel(struct bchannel *bch, unsigned int id, bool force) +recv_Bchannel(struct bchannel *bch, unsigned int id) { struct mISDNhead *hh; - /* if allocation did fail upper functions still may call us */ - if (unlikely(!bch->rx_skb)) + hh = mISDN_HEAD_P(bch->rx_skb); + hh->prim = PH_DATA_IND; + hh->id = id; + if (bch->rcount >= 64) { + printk(KERN_WARNING "B-channel %p receive queue overflow, " + "flushing!\n", bch); + skb_queue_purge(&bch->rqueue); + bch->rcount = 0; return; - if (unlikely(!bch->rx_skb->len)) { - /* we have no data to send - this may happen after recovery - * from overflow or too small allocation. - * We need to free the buffer here */ - dev_kfree_skb(bch->rx_skb); - bch->rx_skb = NULL; - } else { - if (test_bit(FLG_TRANSPARENT, &bch->Flags) && - (bch->rx_skb->len < bch->minlen) && !force) - return; - hh = mISDN_HEAD_P(bch->rx_skb); - hh->prim = PH_DATA_IND; - hh->id = id; - if (bch->rcount >= 64) { - printk(KERN_WARNING - "B%d receive queue overflow - flushing!\n", - bch->nr); - skb_queue_purge(&bch->rqueue); - } - bch->rcount++; - skb_queue_tail(&bch->rqueue, bch->rx_skb); - bch->rx_skb = NULL; - schedule_event(bch, FLG_RECVQUEUE); } + bch->rcount++; + skb_queue_tail(&bch->rqueue, bch->rx_skb); + bch->rx_skb = NULL; + schedule_event(bch, FLG_RECVQUEUE); } EXPORT_SYMBOL(recv_Bchannel); @@ -344,7 +272,7 @@ get_next_dframe(struct dchannel *dch) } EXPORT_SYMBOL(get_next_dframe); -static void +void confirm_Bsend(struct bchannel *bch) { struct sk_buff *skb; @@ -366,6 +294,7 @@ confirm_Bsend(struct bchannel *bch) skb_queue_tail(&bch->rqueue, skb); schedule_event(bch, FLG_RECVQUEUE); } +EXPORT_SYMBOL(confirm_Bsend); int get_next_bframe(struct bchannel *bch) @@ -376,8 +305,8 @@ get_next_bframe(struct bchannel *bch) if (bch->tx_skb) { bch->next_skb = NULL; test_and_clear_bit(FLG_TX_NEXT, &bch->Flags); - /* confirm imediately to allow next data */ - confirm_Bsend(bch); + if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) + confirm_Bsend(bch); /* not for transparent */ return 1; } else { test_and_clear_bit(FLG_TX_NEXT, &bch->Flags); @@ -466,62 +395,7 @@ bchannel_senddata(struct bchannel *ch, struct sk_buff *skb) /* write to fifo */ ch->tx_skb = skb; ch->tx_idx = 0; - confirm_Bsend(ch); return 1; } } EXPORT_SYMBOL(bchannel_senddata); - -/* The function allocates a new receive skb on demand with a size for the - * requirements of the current protocol. It returns the tailroom of the - * receive skb or an error. - */ -int -bchannel_get_rxbuf(struct bchannel *bch, int reqlen) -{ - int len; - - if (bch->rx_skb) { - len = skb_tailroom(bch->rx_skb); - if (len < reqlen) { - pr_warning("B%d no space for %d (only %d) bytes\n", - bch->nr, reqlen, len); - if (test_bit(FLG_TRANSPARENT, &bch->Flags)) { - /* send what we have now and try a new buffer */ - recv_Bchannel(bch, 0, true); - } else { - /* on HDLC we have to drop too big frames */ - return -EMSGSIZE; - } - } else { - return len; - } - } - /* update current min/max length first */ - if (unlikely(bch->maxlen != bch->next_maxlen)) - bch->maxlen = bch->next_maxlen; - if (unlikely(bch->minlen != bch->next_minlen)) - bch->minlen = bch->next_minlen; - if (unlikely(reqlen > bch->maxlen)) - return -EMSGSIZE; - if (test_bit(FLG_TRANSPARENT, &bch->Flags)) { - if (reqlen >= bch->minlen) { - len = reqlen; - } else { - len = 2 * bch->minlen; - if (len > bch->maxlen) - len = bch->maxlen; - } - } else { - /* with HDLC we do not know the length yet */ - len = bch->maxlen; - } - bch->rx_skb = mI_alloc_skb(len, GFP_ATOMIC); - if (!bch->rx_skb) { - pr_warning("B%d receive no memory for %d bytes\n", - bch->nr, len); - len = -ENOMEM; - } - return len; -} -EXPORT_SYMBOL(bchannel_get_rxbuf); diff --git a/trunk/drivers/isdn/mISDN/l1oip_core.c b/trunk/drivers/isdn/mISDN/l1oip_core.c index db50f788855d..0f88acf1185f 100644 --- a/trunk/drivers/isdn/mISDN/l1oip_core.c +++ b/trunk/drivers/isdn/mISDN/l1oip_core.c @@ -1420,7 +1420,7 @@ init_card(struct l1oip *hc, int pri, int bundle) bch->nr = i + ch; bch->slot = i + ch; bch->debug = debug; - mISDN_initbchannel(bch, MAX_DATA_MEM, 0); + mISDN_initbchannel(bch, MAX_DATA_MEM); bch->hw = hc; bch->ch.send = handle_bmsg; bch->ch.ctrl = l1oip_bctrl; diff --git a/trunk/drivers/leds/leds-netxbig.c b/trunk/drivers/leds/leds-netxbig.c index 73973fdbd8be..d8433f2d53bc 100644 --- a/trunk/drivers/leds/leds-netxbig.c +++ b/trunk/drivers/leds/leds-netxbig.c @@ -112,7 +112,7 @@ static int __devinit gpio_ext_init(struct netxbig_gpio_ext *gpio_ext) return err; } -static void gpio_ext_free(struct netxbig_gpio_ext *gpio_ext) +static void __devexit gpio_ext_free(struct netxbig_gpio_ext *gpio_ext) { int i; @@ -294,7 +294,7 @@ static ssize_t netxbig_led_sata_show(struct device *dev, static DEVICE_ATTR(sata, 0644, netxbig_led_sata_show, netxbig_led_sata_store); -static void delete_netxbig_led(struct netxbig_led_data *led_dat) +static void __devexit delete_netxbig_led(struct netxbig_led_data *led_dat) { if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) device_remove_file(led_dat->cdev.dev, &dev_attr_sata); diff --git a/trunk/drivers/leds/leds-ns2.c b/trunk/drivers/leds/leds-ns2.c index 01cf89ec6944..2f0a14421a73 100644 --- a/trunk/drivers/leds/leds-ns2.c +++ b/trunk/drivers/leds/leds-ns2.c @@ -255,7 +255,7 @@ create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat, return ret; } -static void delete_ns2_led(struct ns2_led_data *led_dat) +static void __devexit delete_ns2_led(struct ns2_led_data *led_dat) { device_remove_file(led_dat->cdev.dev, &dev_attr_sata); led_classdev_unregister(&led_dat->cdev); diff --git a/trunk/drivers/md/bitmap.c b/trunk/drivers/md/bitmap.c index 17e2b472e16d..97e73e555d11 100644 --- a/trunk/drivers/md/bitmap.c +++ b/trunk/drivers/md/bitmap.c @@ -1727,7 +1727,8 @@ int bitmap_create(struct mddev *mddev) bitmap->chunkshift = (ffz(~mddev->bitmap_info.chunksize) - BITMAP_BLOCK_SHIFT); - chunks = (blocks + (1 << bitmap->chunkshift) - 1) >> + /* now that chunksize and chunkshift are set, we can use these macros */ + chunks = (blocks + bitmap->chunkshift - 1) >> bitmap->chunkshift; pages = (chunks + PAGE_COUNTER_RATIO - 1) / PAGE_COUNTER_RATIO; diff --git a/trunk/drivers/md/bitmap.h b/trunk/drivers/md/bitmap.h index b44b0aba2d47..55ca5aec84e4 100644 --- a/trunk/drivers/md/bitmap.h +++ b/trunk/drivers/md/bitmap.h @@ -101,6 +101,9 @@ typedef __u16 bitmap_counter_t; #define BITMAP_BLOCK_SHIFT 9 +/* how many blocks per chunk? (this is variable) */ +#define CHUNK_BLOCK_RATIO(bitmap) ((bitmap)->mddev->bitmap_info.chunksize >> BITMAP_BLOCK_SHIFT) + #endif /* diff --git a/trunk/drivers/md/dm-log-userspace-transfer.c b/trunk/drivers/md/dm-log-userspace-transfer.c index 08d9a207259a..1f23e048f077 100644 --- a/trunk/drivers/md/dm-log-userspace-transfer.c +++ b/trunk/drivers/md/dm-log-userspace-transfer.c @@ -134,7 +134,7 @@ static void cn_ulog_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) { struct dm_ulog_request *tfr = (struct dm_ulog_request *)(msg + 1); - if (!capable(CAP_SYS_ADMIN)) + if (!cap_raised(current_cap(), CAP_SYS_ADMIN)) return; spin_lock(&receiving_list_lock); diff --git a/trunk/drivers/md/dm-mpath.c b/trunk/drivers/md/dm-mpath.c index 754f38f8a692..922a3385eead 100644 --- a/trunk/drivers/md/dm-mpath.c +++ b/trunk/drivers/md/dm-mpath.c @@ -718,8 +718,8 @@ static int parse_hw_handler(struct dm_arg_set *as, struct multipath *m) return 0; m->hw_handler_name = kstrdup(dm_shift_arg(as), GFP_KERNEL); - if (!try_then_request_module(scsi_dh_handler_exist(m->hw_handler_name), - "scsi_dh_%s", m->hw_handler_name)) { + request_module("scsi_dh_%s", m->hw_handler_name); + if (scsi_dh_handler_exist(m->hw_handler_name) == 0) { ti->error = "unknown hardware handler type"; ret = -EINVAL; goto fail; diff --git a/trunk/drivers/md/dm-thin.c b/trunk/drivers/md/dm-thin.c index eb3d138ff55a..213ae32a0fc4 100644 --- a/trunk/drivers/md/dm-thin.c +++ b/trunk/drivers/md/dm-thin.c @@ -279,10 +279,8 @@ static void __cell_release(struct cell *cell, struct bio_list *inmates) hlist_del(&cell->list); - if (inmates) { - bio_list_add(inmates, cell->holder); - bio_list_merge(inmates, &cell->bios); - } + bio_list_add(inmates, cell->holder); + bio_list_merge(inmates, &cell->bios); mempool_free(cell, prison->cell_pool); } @@ -305,10 +303,9 @@ static void cell_release(struct cell *cell, struct bio_list *bios) */ static void __cell_release_singleton(struct cell *cell, struct bio *bio) { + hlist_del(&cell->list); BUG_ON(cell->holder != bio); BUG_ON(!bio_list_empty(&cell->bios)); - - __cell_release(cell, NULL); } static void cell_release_singleton(struct cell *cell, struct bio *bio) @@ -1180,7 +1177,6 @@ static void no_space(struct cell *cell) static void process_discard(struct thin_c *tc, struct bio *bio) { int r; - unsigned long flags; struct pool *pool = tc->pool; struct cell *cell, *cell2; struct cell_key key, key2; @@ -1222,9 +1218,7 @@ static void process_discard(struct thin_c *tc, struct bio *bio) m->bio = bio; if (!ds_add_work(&pool->all_io_ds, &m->list)) { - spin_lock_irqsave(&pool->lock, flags); list_add(&m->list, &pool->prepared_discards); - spin_unlock_irqrestore(&pool->lock, flags); wake_worker(pool); } } else { @@ -1632,21 +1626,6 @@ static int bind_control_target(struct pool *pool, struct dm_target *ti) pool->low_water_blocks = pt->low_water_blocks; pool->pf = pt->pf; - /* - * If discard_passdown was enabled verify that the data device - * supports discards. Disable discard_passdown if not; otherwise - * -EOPNOTSUPP will be returned. - */ - if (pt->pf.discard_passdown) { - struct request_queue *q = bdev_get_queue(pt->data_dev->bdev); - if (!q || !blk_queue_discard(q)) { - char buf[BDEVNAME_SIZE]; - DMWARN("Discard unsupported by data device (%s): Disabling discard passdown.", - bdevname(pt->data_dev->bdev, buf)); - pool->pf.discard_passdown = 0; - } - } - return 0; } @@ -2003,6 +1982,19 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) goto out_flags_changed; } + /* + * If discard_passdown was enabled verify that the data device + * supports discards. Disable discard_passdown if not; otherwise + * -EOPNOTSUPP will be returned. + */ + if (pf.discard_passdown) { + struct request_queue *q = bdev_get_queue(data_dev->bdev); + if (!q || !blk_queue_discard(q)) { + DMWARN("Discard unsupported by data device: Disabling discard passdown."); + pf.discard_passdown = 0; + } + } + pt->pool = pool; pt->ti = ti; pt->metadata_dev = metadata_dev; @@ -2387,7 +2379,7 @@ static int pool_status(struct dm_target *ti, status_type_t type, (unsigned long long)pt->low_water_blocks); count = !pool->pf.zero_new_blocks + !pool->pf.discard_enabled + - !pt->pf.discard_passdown; + !pool->pf.discard_passdown; DMEMIT("%u ", count); if (!pool->pf.zero_new_blocks) @@ -2396,7 +2388,7 @@ static int pool_status(struct dm_target *ti, status_type_t type, if (!pool->pf.discard_enabled) DMEMIT("ignore_discard "); - if (!pt->pf.discard_passdown) + if (!pool->pf.discard_passdown) DMEMIT("no_discard_passdown "); break; @@ -2634,10 +2626,8 @@ static int thin_endio(struct dm_target *ti, if (h->all_io_entry) { INIT_LIST_HEAD(&work); ds_dec(h->all_io_entry, &work); - spin_lock_irqsave(&pool->lock, flags); list_for_each_entry_safe(m, tmp, &work, list) list_add(&m->list, &pool->prepared_discards); - spin_unlock_irqrestore(&pool->lock, flags); } mempool_free(h, pool->endio_hook_pool); @@ -2769,6 +2759,6 @@ static void dm_thin_exit(void) module_init(dm_thin_init); module_exit(dm_thin_exit); -MODULE_DESCRIPTION(DM_NAME " thin provisioning target"); +MODULE_DESCRIPTION(DM_NAME "device-mapper thin provisioning target"); MODULE_AUTHOR("Joe Thornber "); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 01233d855eb2..477eb2e180c0 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -391,8 +391,6 @@ void mddev_suspend(struct mddev *mddev) synchronize_rcu(); wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0); mddev->pers->quiesce(mddev, 1); - - del_timer_sync(&mddev->safemode_timer); } EXPORT_SYMBOL_GPL(mddev_suspend); diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index 3f91c2e1dfe7..c8dbb84d5357 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -3164,40 +3164,12 @@ raid10_size(struct mddev *mddev, sector_t sectors, int raid_disks) return size << conf->chunk_shift; } -static void calc_sectors(struct r10conf *conf, sector_t size) -{ - /* Calculate the number of sectors-per-device that will - * actually be used, and set conf->dev_sectors and - * conf->stride - */ - - size = size >> conf->chunk_shift; - sector_div(size, conf->far_copies); - size = size * conf->raid_disks; - sector_div(size, conf->near_copies); - /* 'size' is now the number of chunks in the array */ - /* calculate "used chunks per device" */ - size = size * conf->copies; - - /* We need to round up when dividing by raid_disks to - * get the stride size. - */ - size = DIV_ROUND_UP_SECTOR_T(size, conf->raid_disks); - - conf->dev_sectors = size << conf->chunk_shift; - - if (conf->far_offset) - conf->stride = 1 << conf->chunk_shift; - else { - sector_div(size, conf->far_copies); - conf->stride = size << conf->chunk_shift; - } -} static struct r10conf *setup_conf(struct mddev *mddev) { struct r10conf *conf = NULL; int nc, fc, fo; + sector_t stride, size; int err = -EINVAL; if (mddev->new_chunk_sectors < (PAGE_SIZE >> 9) || @@ -3247,7 +3219,28 @@ static struct r10conf *setup_conf(struct mddev *mddev) if (!conf->r10bio_pool) goto out; - calc_sectors(conf, mddev->dev_sectors); + size = mddev->dev_sectors >> conf->chunk_shift; + sector_div(size, fc); + size = size * conf->raid_disks; + sector_div(size, nc); + /* 'size' is now the number of chunks in the array */ + /* calculate "used chunks per device" in 'stride' */ + stride = size * conf->copies; + + /* We need to round up when dividing by raid_disks to + * get the stride size. + */ + stride += conf->raid_disks - 1; + sector_div(stride, conf->raid_disks); + + conf->dev_sectors = stride << conf->chunk_shift; + + if (fo) + stride = 1; + else + sector_div(stride, fc); + conf->stride = stride << conf->chunk_shift; + spin_lock_init(&conf->device_lock); INIT_LIST_HEAD(&conf->retry_list); @@ -3475,8 +3468,7 @@ static int raid10_resize(struct mddev *mddev, sector_t sectors) mddev->recovery_cp = oldsize; set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); } - calc_sectors(conf, sectors); - mddev->dev_sectors = conf->dev_sectors; + mddev->dev_sectors = sectors; mddev->resync_max_sectors = size; return 0; } diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c index cb888d835a89..0f64d7182657 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1921,10 +1921,6 @@ static int dtv_set_frontend(struct dvb_frontend *fe) } else { /* default values */ switch (c->delivery_system) { - case SYS_DVBS: - case SYS_DVBS2: - case SYS_ISDBS: - case SYS_TURBO: case SYS_DVBC_ANNEX_A: case SYS_DVBC_ANNEX_C: fepriv->min_delay = HZ / 20; diff --git a/trunk/drivers/media/rc/ene_ir.c b/trunk/drivers/media/rc/ene_ir.c index bef5296173c9..860c112e0fd2 100644 --- a/trunk/drivers/media/rc/ene_ir.c +++ b/trunk/drivers/media/rc/ene_ir.c @@ -1018,6 +1018,22 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) spin_lock_init(&dev->hw_lock); + /* claim the resources */ + error = -EBUSY; + dev->hw_io = pnp_port_start(pnp_dev, 0); + if (!request_region(dev->hw_io, ENE_IO_SIZE, ENE_DRIVER_NAME)) { + dev->hw_io = -1; + dev->irq = -1; + goto error; + } + + dev->irq = pnp_irq(pnp_dev, 0); + if (request_irq(dev->irq, ene_isr, + IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) { + dev->irq = -1; + goto error; + } + pnp_set_drvdata(pnp_dev, dev); dev->pnp_dev = pnp_dev; @@ -1070,22 +1086,6 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) device_set_wakeup_capable(&pnp_dev->dev, true); device_set_wakeup_enable(&pnp_dev->dev, true); - /* claim the resources */ - error = -EBUSY; - dev->hw_io = pnp_port_start(pnp_dev, 0); - if (!request_region(dev->hw_io, ENE_IO_SIZE, ENE_DRIVER_NAME)) { - dev->hw_io = -1; - dev->irq = -1; - goto error; - } - - dev->irq = pnp_irq(pnp_dev, 0); - if (request_irq(dev->irq, ene_isr, - IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) { - dev->irq = -1; - goto error; - } - error = rc_register_device(rdev); if (error < 0) goto error; diff --git a/trunk/drivers/media/rc/fintek-cir.c b/trunk/drivers/media/rc/fintek-cir.c index 4a3a238bcfbc..392d4be91f8f 100644 --- a/trunk/drivers/media/rc/fintek-cir.c +++ b/trunk/drivers/media/rc/fintek-cir.c @@ -197,7 +197,7 @@ static int fintek_hw_detect(struct fintek_dev *fintek) /* * Newer reviews of this chipset uses port 8 instead of 5 */ - if ((chip != 0x0408) && (chip != 0x0804)) + if ((chip != 0x0408) || (chip != 0x0804)) fintek->logical_dev_cir = LOGICAL_DEV_CIR_REV2; else fintek->logical_dev_cir = LOGICAL_DEV_CIR_REV1; @@ -514,6 +514,16 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id spin_lock_init(&fintek->fintek_lock); + ret = -EBUSY; + /* now claim resources */ + if (!request_region(fintek->cir_addr, + fintek->cir_port_len, FINTEK_DRIVER_NAME)) + goto failure; + + if (request_irq(fintek->cir_irq, fintek_cir_isr, IRQF_SHARED, + FINTEK_DRIVER_NAME, (void *)fintek)) + goto failure; + pnp_set_drvdata(pdev, fintek); fintek->pdev = pdev; @@ -548,16 +558,6 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */ rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD); - ret = -EBUSY; - /* now claim resources */ - if (!request_region(fintek->cir_addr, - fintek->cir_port_len, FINTEK_DRIVER_NAME)) - goto failure; - - if (request_irq(fintek->cir_irq, fintek_cir_isr, IRQF_SHARED, - FINTEK_DRIVER_NAME, (void *)fintek)) - goto failure; - ret = rc_register_device(rdev); if (ret) goto failure; diff --git a/trunk/drivers/media/rc/ite-cir.c b/trunk/drivers/media/rc/ite-cir.c index 0e49c99abf68..682009d76cdf 100644 --- a/trunk/drivers/media/rc/ite-cir.c +++ b/trunk/drivers/media/rc/ite-cir.c @@ -1515,6 +1515,16 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id /* initialize raw event */ init_ir_raw_event(&itdev->rawir); + ret = -EBUSY; + /* now claim resources */ + if (!request_region(itdev->cir_addr, + dev_desc->io_region_size, ITE_DRIVER_NAME)) + goto failure; + + if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED, + ITE_DRIVER_NAME, (void *)itdev)) + goto failure; + /* set driver data into the pnp device */ pnp_set_drvdata(pdev, itdev); itdev->pdev = pdev; @@ -1590,16 +1600,6 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id rdev->driver_name = ITE_DRIVER_NAME; rdev->map_name = RC_MAP_RC6_MCE; - ret = -EBUSY; - /* now claim resources */ - if (!request_region(itdev->cir_addr, - dev_desc->io_region_size, ITE_DRIVER_NAME)) - goto failure; - - if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED, - ITE_DRIVER_NAME, (void *)itdev)) - goto failure; - ret = rc_register_device(rdev); if (ret) goto failure; diff --git a/trunk/drivers/media/rc/nuvoton-cir.c b/trunk/drivers/media/rc/nuvoton-cir.c index 8b2c071ac0ab..144f3f55d765 100644 --- a/trunk/drivers/media/rc/nuvoton-cir.c +++ b/trunk/drivers/media/rc/nuvoton-cir.c @@ -1021,6 +1021,24 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) spin_lock_init(&nvt->nvt_lock); spin_lock_init(&nvt->tx.lock); + ret = -EBUSY; + /* now claim resources */ + if (!request_region(nvt->cir_addr, + CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) + goto failure; + + if (request_irq(nvt->cir_irq, nvt_cir_isr, IRQF_SHARED, + NVT_DRIVER_NAME, (void *)nvt)) + goto failure; + + if (!request_region(nvt->cir_wake_addr, + CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) + goto failure; + + if (request_irq(nvt->cir_wake_irq, nvt_cir_wake_isr, IRQF_SHARED, + NVT_DRIVER_NAME, (void *)nvt)) + goto failure; + pnp_set_drvdata(pdev, nvt); nvt->pdev = pdev; @@ -1067,24 +1085,6 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) rdev->tx_resolution = XYZ; #endif - ret = -EBUSY; - /* now claim resources */ - if (!request_region(nvt->cir_addr, - CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) - goto failure; - - if (request_irq(nvt->cir_irq, nvt_cir_isr, IRQF_SHARED, - NVT_DRIVER_NAME, (void *)nvt)) - goto failure; - - if (!request_region(nvt->cir_wake_addr, - CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) - goto failure; - - if (request_irq(nvt->cir_wake_irq, nvt_cir_wake_isr, IRQF_SHARED, - NVT_DRIVER_NAME, (void *)nvt)) - goto failure; - ret = rc_register_device(rdev); if (ret) goto failure; diff --git a/trunk/drivers/media/rc/winbond-cir.c b/trunk/drivers/media/rc/winbond-cir.c index 342c2c8c1ddf..af526586fa26 100644 --- a/trunk/drivers/media/rc/winbond-cir.c +++ b/trunk/drivers/media/rc/winbond-cir.c @@ -991,10 +991,39 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) "(w: 0x%lX, e: 0x%lX, s: 0x%lX, i: %u)\n", data->wbase, data->ebase, data->sbase, data->irq); + if (!request_region(data->wbase, WAKEUP_IOMEM_LEN, DRVNAME)) { + dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", + data->wbase, data->wbase + WAKEUP_IOMEM_LEN - 1); + err = -EBUSY; + goto exit_free_data; + } + + if (!request_region(data->ebase, EHFUNC_IOMEM_LEN, DRVNAME)) { + dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", + data->ebase, data->ebase + EHFUNC_IOMEM_LEN - 1); + err = -EBUSY; + goto exit_release_wbase; + } + + if (!request_region(data->sbase, SP_IOMEM_LEN, DRVNAME)) { + dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", + data->sbase, data->sbase + SP_IOMEM_LEN - 1); + err = -EBUSY; + goto exit_release_ebase; + } + + err = request_irq(data->irq, wbcir_irq_handler, + IRQF_DISABLED, DRVNAME, device); + if (err) { + dev_err(dev, "Failed to claim IRQ %u\n", data->irq); + err = -EBUSY; + goto exit_release_sbase; + } + led_trigger_register_simple("cir-tx", &data->txtrigger); if (!data->txtrigger) { err = -ENOMEM; - goto exit_free_data; + goto exit_free_irq; } led_trigger_register_simple("cir-rx", &data->rxtrigger); @@ -1033,38 +1062,9 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) data->dev->priv = data; data->dev->dev.parent = &device->dev; - if (!request_region(data->wbase, WAKEUP_IOMEM_LEN, DRVNAME)) { - dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", - data->wbase, data->wbase + WAKEUP_IOMEM_LEN - 1); - err = -EBUSY; - goto exit_free_rc; - } - - if (!request_region(data->ebase, EHFUNC_IOMEM_LEN, DRVNAME)) { - dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", - data->ebase, data->ebase + EHFUNC_IOMEM_LEN - 1); - err = -EBUSY; - goto exit_release_wbase; - } - - if (!request_region(data->sbase, SP_IOMEM_LEN, DRVNAME)) { - dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", - data->sbase, data->sbase + SP_IOMEM_LEN - 1); - err = -EBUSY; - goto exit_release_ebase; - } - - err = request_irq(data->irq, wbcir_irq_handler, - IRQF_DISABLED, DRVNAME, device); - if (err) { - dev_err(dev, "Failed to claim IRQ %u\n", data->irq); - err = -EBUSY; - goto exit_release_sbase; - } - err = rc_register_device(data->dev); if (err) - goto exit_free_irq; + goto exit_free_rc; device_init_wakeup(&device->dev, 1); @@ -1072,14 +1072,6 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) return 0; -exit_free_irq: - free_irq(data->irq, device); -exit_release_sbase: - release_region(data->sbase, SP_IOMEM_LEN); -exit_release_ebase: - release_region(data->ebase, EHFUNC_IOMEM_LEN); -exit_release_wbase: - release_region(data->wbase, WAKEUP_IOMEM_LEN); exit_free_rc: rc_free_device(data->dev); exit_unregister_led: @@ -1088,6 +1080,14 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) led_trigger_unregister_simple(data->rxtrigger); exit_unregister_txtrigger: led_trigger_unregister_simple(data->txtrigger); +exit_free_irq: + free_irq(data->irq, device); +exit_release_sbase: + release_region(data->sbase, SP_IOMEM_LEN); +exit_release_ebase: + release_region(data->ebase, EHFUNC_IOMEM_LEN); +exit_release_wbase: + release_region(data->wbase, WAKEUP_IOMEM_LEN); exit_free_data: kfree(data); pnp_set_drvdata(device, NULL); diff --git a/trunk/drivers/media/video/gspca/sonixj.c b/trunk/drivers/media/video/gspca/sonixj.c index 863c755dd2b7..db8e5084df06 100644 --- a/trunk/drivers/media/video/gspca/sonixj.c +++ b/trunk/drivers/media/video/gspca/sonixj.c @@ -2923,10 +2923,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, * not the JPEG end of frame ('ff d9'). */ - /* count the packets and their size */ - sd->npkt++; - sd->pktsz += len; - /*fixme: assumption about the following code: * - there can be only one marker in a packet */ @@ -2949,6 +2945,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, data += i; } + /* count the packets and their size */ + sd->npkt++; + sd->pktsz += len; + /* search backwards if there is a marker in the packet */ for (i = len - 1; --i >= 0; ) { if (data[i] != 0xff) { diff --git a/trunk/drivers/media/video/marvell-ccic/mmp-driver.c b/trunk/drivers/media/video/marvell-ccic/mmp-driver.c index c4c17fe76c0d..d23552323f45 100644 --- a/trunk/drivers/media/video/marvell-ccic/mmp-driver.c +++ b/trunk/drivers/media/video/marvell-ccic/mmp-driver.c @@ -181,6 +181,7 @@ static int mmpcam_probe(struct platform_device *pdev) INIT_LIST_HEAD(&cam->devlist); mcam = &cam->mcam; + mcam->platform = MHP_Armada610; mcam->plat_power_up = mmpcam_power_up; mcam->plat_power_down = mmpcam_power_down; mcam->dev = &pdev->dev; diff --git a/trunk/drivers/media/video/s5p-fimc/fimc-capture.c b/trunk/drivers/media/video/s5p-fimc/fimc-capture.c index 7e9b2c612b03..b06efd208328 100644 --- a/trunk/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/trunk/drivers/media/video/s5p-fimc/fimc-capture.c @@ -246,37 +246,28 @@ int fimc_capture_resume(struct fimc_dev *fimc) } -static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt, +static unsigned int get_plane_size(struct fimc_frame *fr, unsigned int plane) +{ + if (!fr || plane >= fr->fmt->memplanes) + return 0; + return fr->f_width * fr->f_height * fr->fmt->depth[plane] / 8; +} + +static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt, unsigned int *num_buffers, unsigned int *num_planes, unsigned int sizes[], void *allocators[]) { - const struct v4l2_pix_format_mplane *pixm = NULL; struct fimc_ctx *ctx = vq->drv_priv; - struct fimc_frame *frame = &ctx->d_frame; - struct fimc_fmt *fmt = frame->fmt; - unsigned long wh; + struct fimc_fmt *fmt = ctx->d_frame.fmt; int i; - if (pfmt) { - pixm = &pfmt->fmt.pix_mp; - fmt = fimc_find_format(&pixm->pixelformat, NULL, - FMT_FLAGS_CAM | FMT_FLAGS_M2M, -1); - wh = pixm->width * pixm->height; - } else { - wh = frame->f_width * frame->f_height; - } - - if (fmt == NULL) + if (!fmt) return -EINVAL; *num_planes = fmt->memplanes; for (i = 0; i < fmt->memplanes; i++) { - unsigned int size = (wh * fmt->depth[i]) / 8; - if (pixm) - sizes[i] = max(size, pixm->plane_fmt[i].sizeimage); - else - sizes[i] = size; + sizes[i] = get_plane_size(&ctx->d_frame, i); allocators[i] = ctx->fimc_dev->alloc_ctx; } @@ -1392,7 +1383,7 @@ static int fimc_subdev_set_crop(struct v4l2_subdev *sd, fimc_capture_try_crop(ctx, r, crop->pad); if (crop->which == V4L2_SUBDEV_FORMAT_TRY) { - mutex_unlock(&fimc->lock); + mutex_lock(&fimc->lock); *v4l2_subdev_get_try_crop(fh, crop->pad) = *r; return 0; } diff --git a/trunk/drivers/media/video/s5p-fimc/fimc-core.c b/trunk/drivers/media/video/s5p-fimc/fimc-core.c index e09ba7b0076e..e184e650022a 100644 --- a/trunk/drivers/media/video/s5p-fimc/fimc-core.c +++ b/trunk/drivers/media/video/s5p-fimc/fimc-core.c @@ -1048,14 +1048,14 @@ static int fimc_m2m_g_fmt_mplane(struct file *file, void *fh, * @mask: the color flags to match * @index: offset in the fimc_formats array, ignored if negative */ -struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code, +struct fimc_fmt *fimc_find_format(u32 *pixelformat, u32 *mbus_code, unsigned int mask, int index) { struct fimc_fmt *fmt, *def_fmt = NULL; unsigned int i; int id = 0; - if (index >= (int)ARRAY_SIZE(fimc_formats)) + if (index >= ARRAY_SIZE(fimc_formats)) return NULL; for (i = 0; i < ARRAY_SIZE(fimc_formats); ++i) { diff --git a/trunk/drivers/media/video/s5p-fimc/fimc-core.h b/trunk/drivers/media/video/s5p-fimc/fimc-core.h index 84fd83550bd7..a18291e648e2 100644 --- a/trunk/drivers/media/video/s5p-fimc/fimc-core.h +++ b/trunk/drivers/media/video/s5p-fimc/fimc-core.h @@ -718,7 +718,7 @@ void fimc_alpha_ctrl_update(struct fimc_ctx *ctx); int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f); void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height, struct v4l2_pix_format_mplane *pix); -struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code, +struct fimc_fmt *fimc_find_format(u32 *pixelformat, u32 *mbus_code, unsigned int mask, int index); int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh, diff --git a/trunk/drivers/media/video/soc_camera.c b/trunk/drivers/media/video/soc_camera.c index aedb970d13f6..eb25756a07af 100644 --- a/trunk/drivers/media/video/soc_camera.c +++ b/trunk/drivers/media/video/soc_camera.c @@ -530,10 +530,7 @@ static int soc_camera_open(struct file *file) if (icl->reset) icl->reset(icd->pdev); - /* Don't mess with the host during probe */ - mutex_lock(&ici->host_lock); ret = ici->ops->add(icd); - mutex_unlock(&ici->host_lock); if (ret < 0) { dev_err(icd->pdev, "Couldn't activate the camera: %d\n", ret); goto eiciadd; @@ -959,7 +956,7 @@ static void scan_add_host(struct soc_camera_host *ici) { struct soc_camera_device *icd; - mutex_lock(&ici->host_lock); + mutex_lock(&list_lock); list_for_each_entry(icd, &devices, list) { if (icd->iface == ici->nr) { @@ -970,7 +967,7 @@ static void scan_add_host(struct soc_camera_host *ici) } } - mutex_unlock(&ici->host_lock); + mutex_unlock(&list_lock); } #ifdef CONFIG_I2C_BOARDINFO @@ -1316,7 +1313,6 @@ int soc_camera_host_register(struct soc_camera_host *ici) list_add_tail(&ici->list, &hosts); mutex_unlock(&list_lock); - mutex_init(&ici->host_lock); scan_add_host(ici); return 0; diff --git a/trunk/drivers/media/video/videobuf2-dma-contig.c b/trunk/drivers/media/video/videobuf2-dma-contig.c index 4b7132660a93..f17ad98fcc5f 100644 --- a/trunk/drivers/media/video/videobuf2-dma-contig.c +++ b/trunk/drivers/media/video/videobuf2-dma-contig.c @@ -15,7 +15,6 @@ #include #include -#include #include struct vb2_dc_conf { @@ -86,7 +85,7 @@ static void *vb2_dma_contig_vaddr(void *buf_priv) { struct vb2_dc_buf *buf = buf_priv; if (!buf) - return NULL; + return 0; return buf->vaddr; } diff --git a/trunk/drivers/media/video/videobuf2-memops.c b/trunk/drivers/media/video/videobuf2-memops.c index 504cd4cbe29e..c41cb60245d6 100644 --- a/trunk/drivers/media/video/videobuf2-memops.c +++ b/trunk/drivers/media/video/videobuf2-memops.c @@ -55,7 +55,6 @@ struct vm_area_struct *vb2_get_vma(struct vm_area_struct *vma) return vma_copy; } -EXPORT_SYMBOL_GPL(vb2_get_vma); /** * vb2_put_userptr() - release a userspace virtual memory area diff --git a/trunk/drivers/message/fusion/mptlan.h b/trunk/drivers/message/fusion/mptlan.h index 69e9d5463564..c171afa93239 100644 --- a/trunk/drivers/message/fusion/mptlan.h +++ b/trunk/drivers/message/fusion/mptlan.h @@ -69,6 +69,7 @@ #include #include #include +// #include #include #include diff --git a/trunk/drivers/mfd/Kconfig b/trunk/drivers/mfd/Kconfig index b5a0032f616e..11e44386fa9b 100644 --- a/trunk/drivers/mfd/Kconfig +++ b/trunk/drivers/mfd/Kconfig @@ -162,7 +162,6 @@ config MFD_TPS6586X bool "TPS6586x Power Management chips" depends on I2C=y && GPIOLIB && GENERIC_HARDIRQS select MFD_CORE - depends on REGULATOR help If you say yes here you get support for the TPS6586X series of Power Management chips. @@ -377,7 +376,6 @@ config PMIC_DA9052 config MFD_DA9052_SPI bool "Support Dialog Semiconductor DA9052/53 PMIC variants with SPI" - select IRQ_DOMAIN select REGMAP_SPI select REGMAP_IRQ select PMIC_DA9052 @@ -390,7 +388,6 @@ config MFD_DA9052_SPI config MFD_DA9052_I2C bool "Support Dialog Semiconductor DA9052/53 PMIC variants with I2C" - select IRQ_DOMAIN select REGMAP_I2C select REGMAP_IRQ select PMIC_DA9052 @@ -561,7 +558,6 @@ config MFD_WM8994 bool "Support Wolfson Microelectronics WM8994" select MFD_CORE select REGMAP_I2C - select IRQ_DOMAIN select REGMAP_IRQ depends on I2C=y && GENERIC_HARDIRQS help @@ -892,16 +888,6 @@ config MFD_ANATOP MFD controller. This controller embeds regulator and thermal devices for Freescale i.MX platforms. -config MFD_PALMAS - bool "Support for the TI Palmas series chips" - select MFD_CORE - select REGMAP_I2C - select REGMAP_IRQ - depends on I2C=y - help - If you say yes here you get support for the Palmas - series of PMIC chips from Texas Instruments. - endmenu endif diff --git a/trunk/drivers/mfd/Makefile b/trunk/drivers/mfd/Makefile index 77293e150239..05fa538c5efe 100644 --- a/trunk/drivers/mfd/Makefile +++ b/trunk/drivers/mfd/Makefile @@ -113,8 +113,6 @@ obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o obj-$(CONFIG_MFD_TPS65090) += tps65090.o obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o -obj-$(CONFIG_MFD_PALMAS) += palmas.o obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o obj-$(CONFIG_MFD_S5M_CORE) += s5m-core.o s5m-irq.o obj-$(CONFIG_MFD_ANATOP) += anatop-mfd.o -obj-$(CONFIG_MFD_LM3533) += lm3533-core.o lm3533-ctrlbank.o diff --git a/trunk/drivers/mfd/da9052-core.c b/trunk/drivers/mfd/da9052-core.c index 7776aff46269..7ff313fe9fb1 100644 --- a/trunk/drivers/mfd/da9052-core.c +++ b/trunk/drivers/mfd/da9052-core.c @@ -659,11 +659,12 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id) ret = regmap_add_irq_chip(da9052->regmap, da9052->chip_irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT, da9052->irq_base, &da9052_regmap_irq_chip, - &da9052->irq_data); + NULL); if (ret < 0) goto regmap_err; - da9052->irq_base = regmap_irq_chip_get_base(da9052->irq_data); + desc = irq_to_desc(da9052->chip_irq); + da9052->irq_base = regmap_irq_chip_get_base(desc->action->dev_id); ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info, ARRAY_SIZE(da9052_subdev_info), NULL, 0); @@ -680,7 +681,8 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id) void da9052_device_exit(struct da9052 *da9052) { - regmap_del_irq_chip(da9052->chip_irq, da9052->irq_data); + regmap_del_irq_chip(da9052->chip_irq, + irq_get_irq_data(da9052->irq_base)->chip_data); mfd_remove_devices(da9052->dev); } diff --git a/trunk/drivers/mfd/palmas.c b/trunk/drivers/mfd/palmas.c deleted file mode 100644 index 00c0aba7eba0..000000000000 --- a/trunk/drivers/mfd/palmas.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - * TI Palmas MFD Driver - * - * Copyright 2011-2012 Texas Instruments Inc. - * - * Author: Graeme Gregory - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static const struct resource gpadc_resource[] = { - { - .name = "EOC_SW", - .start = PALMAS_GPADC_EOC_SW_IRQ, - .end = PALMAS_GPADC_EOC_SW_IRQ, - .flags = IORESOURCE_IRQ, - } -}; - -static const struct resource usb_resource[] = { - { - .name = "ID", - .start = PALMAS_ID_OTG_IRQ, - .end = PALMAS_ID_OTG_IRQ, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ID_WAKEUP", - .start = PALMAS_ID_IRQ, - .end = PALMAS_ID_IRQ, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS", - .start = PALMAS_VBUS_OTG_IRQ, - .end = PALMAS_VBUS_OTG_IRQ, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS_WAKEUP", - .start = PALMAS_VBUS_IRQ, - .end = PALMAS_VBUS_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -static const struct resource rtc_resource[] = { - { - .name = "RTC_ALARM", - .start = PALMAS_RTC_ALARM_IRQ, - .end = PALMAS_RTC_ALARM_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -static const struct resource pwron_resource[] = { - { - .name = "PWRON_BUTTON", - .start = PALMAS_PWRON_IRQ, - .end = PALMAS_PWRON_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -enum palmas_ids { - PALMAS_PMIC_ID, - PALMAS_GPIO_ID, - PALMAS_LEDS_ID, - PALMAS_WDT_ID, - PALMAS_RTC_ID, - PALMAS_PWRBUTTON_ID, - PALMAS_GPADC_ID, - PALMAS_RESOURCE_ID, - PALMAS_CLK_ID, - PALMAS_PWM_ID, - PALMAS_USB_ID, -}; - -static const struct mfd_cell palmas_children[] = { - { - .name = "palmas-pmic", - .id = PALMAS_PMIC_ID, - }, - { - .name = "palmas-gpio", - .id = PALMAS_GPIO_ID, - }, - { - .name = "palmas-leds", - .id = PALMAS_LEDS_ID, - }, - { - .name = "palmas-wdt", - .id = PALMAS_WDT_ID, - }, - { - .name = "palmas-rtc", - .num_resources = ARRAY_SIZE(rtc_resource), - .resources = rtc_resource, - .id = PALMAS_RTC_ID, - }, - { - .name = "palmas-pwrbutton", - .num_resources = ARRAY_SIZE(pwron_resource), - .resources = pwron_resource, - .id = PALMAS_PWRBUTTON_ID, - }, - { - .name = "palmas-gpadc", - .num_resources = ARRAY_SIZE(gpadc_resource), - .resources = gpadc_resource, - .id = PALMAS_GPADC_ID, - }, - { - .name = "palmas-resource", - .id = PALMAS_RESOURCE_ID, - }, - { - .name = "palmas-clk", - .id = PALMAS_CLK_ID, - }, - { - .name = "palmas-pwm", - .id = PALMAS_PWM_ID, - }, - { - .name = "palmas-usb", - .num_resources = ARRAY_SIZE(usb_resource), - .resources = usb_resource, - .id = PALMAS_USB_ID, - } -}; - -static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = { - { - .reg_bits = 8, - .val_bits = 8, - .max_register = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, - PALMAS_PRIMARY_SECONDARY_PAD3), - }, - { - .reg_bits = 8, - .val_bits = 8, - .max_register = PALMAS_BASE_TO_REG(PALMAS_GPADC_BASE, - PALMAS_GPADC_SMPS_VSEL_MONITORING), - }, - { - .reg_bits = 8, - .val_bits = 8, - .max_register = PALMAS_BASE_TO_REG(PALMAS_TRIM_GPADC_BASE, - PALMAS_GPADC_TRIM16), - }, -}; - -static const struct regmap_irq palmas_irqs[] = { - /* INT1 IRQs */ - [PALMAS_CHARG_DET_N_VBUS_OVV_IRQ] = { - .mask = PALMAS_INT1_STATUS_CHARG_DET_N_VBUS_OVV, - }, - [PALMAS_PWRON_IRQ] = { - .mask = PALMAS_INT1_STATUS_PWRON, - }, - [PALMAS_LONG_PRESS_KEY_IRQ] = { - .mask = PALMAS_INT1_STATUS_LONG_PRESS_KEY, - }, - [PALMAS_RPWRON_IRQ] = { - .mask = PALMAS_INT1_STATUS_RPWRON, - }, - [PALMAS_PWRDOWN_IRQ] = { - .mask = PALMAS_INT1_STATUS_PWRDOWN, - }, - [PALMAS_HOTDIE_IRQ] = { - .mask = PALMAS_INT1_STATUS_HOTDIE, - }, - [PALMAS_VSYS_MON_IRQ] = { - .mask = PALMAS_INT1_STATUS_VSYS_MON, - }, - [PALMAS_VBAT_MON_IRQ] = { - .mask = PALMAS_INT1_STATUS_VBAT_MON, - }, - /* INT2 IRQs*/ - [PALMAS_RTC_ALARM_IRQ] = { - .mask = PALMAS_INT2_STATUS_RTC_ALARM, - .reg_offset = 1, - }, - [PALMAS_RTC_TIMER_IRQ] = { - .mask = PALMAS_INT2_STATUS_RTC_TIMER, - .reg_offset = 1, - }, - [PALMAS_WDT_IRQ] = { - .mask = PALMAS_INT2_STATUS_WDT, - .reg_offset = 1, - }, - [PALMAS_BATREMOVAL_IRQ] = { - .mask = PALMAS_INT2_STATUS_BATREMOVAL, - .reg_offset = 1, - }, - [PALMAS_RESET_IN_IRQ] = { - .mask = PALMAS_INT2_STATUS_RESET_IN, - .reg_offset = 1, - }, - [PALMAS_FBI_BB_IRQ] = { - .mask = PALMAS_INT2_STATUS_FBI_BB, - .reg_offset = 1, - }, - [PALMAS_SHORT_IRQ] = { - .mask = PALMAS_INT2_STATUS_SHORT, - .reg_offset = 1, - }, - [PALMAS_VAC_ACOK_IRQ] = { - .mask = PALMAS_INT2_STATUS_VAC_ACOK, - .reg_offset = 1, - }, - /* INT3 IRQs */ - [PALMAS_GPADC_AUTO_0_IRQ] = { - .mask = PALMAS_INT3_STATUS_GPADC_AUTO_0, - .reg_offset = 2, - }, - [PALMAS_GPADC_AUTO_1_IRQ] = { - .mask = PALMAS_INT3_STATUS_GPADC_AUTO_1, - .reg_offset = 2, - }, - [PALMAS_GPADC_EOC_SW_IRQ] = { - .mask = PALMAS_INT3_STATUS_GPADC_EOC_SW, - .reg_offset = 2, - }, - [PALMAS_GPADC_EOC_RT_IRQ] = { - .mask = PALMAS_INT3_STATUS_GPADC_EOC_RT, - .reg_offset = 2, - }, - [PALMAS_ID_OTG_IRQ] = { - .mask = PALMAS_INT3_STATUS_ID_OTG, - .reg_offset = 2, - }, - [PALMAS_ID_IRQ] = { - .mask = PALMAS_INT3_STATUS_ID, - .reg_offset = 2, - }, - [PALMAS_VBUS_OTG_IRQ] = { - .mask = PALMAS_INT3_STATUS_VBUS_OTG, - .reg_offset = 2, - }, - [PALMAS_VBUS_IRQ] = { - .mask = PALMAS_INT3_STATUS_VBUS, - .reg_offset = 2, - }, - /* INT4 IRQs */ - [PALMAS_GPIO_0_IRQ] = { - .mask = PALMAS_INT4_STATUS_GPIO_0, - .reg_offset = 3, - }, - [PALMAS_GPIO_1_IRQ] = { - .mask = PALMAS_INT4_STATUS_GPIO_1, - .reg_offset = 3, - }, - [PALMAS_GPIO_2_IRQ] = { - .mask = PALMAS_INT4_STATUS_GPIO_2, - .reg_offset = 3, - }, - [PALMAS_GPIO_3_IRQ] = { - .mask = PALMAS_INT4_STATUS_GPIO_3, - .reg_offset = 3, - }, - [PALMAS_GPIO_4_IRQ] = { - .mask = PALMAS_INT4_STATUS_GPIO_4, - .reg_offset = 3, - }, - [PALMAS_GPIO_5_IRQ] = { - .mask = PALMAS_INT4_STATUS_GPIO_5, - .reg_offset = 3, - }, - [PALMAS_GPIO_6_IRQ] = { - .mask = PALMAS_INT4_STATUS_GPIO_6, - .reg_offset = 3, - }, - [PALMAS_GPIO_7_IRQ] = { - .mask = PALMAS_INT4_STATUS_GPIO_7, - .reg_offset = 3, - }, -}; - -static struct regmap_irq_chip palmas_irq_chip = { - .name = "palmas", - .irqs = palmas_irqs, - .num_irqs = ARRAY_SIZE(palmas_irqs), - - .num_regs = 4, - .irq_reg_stride = 5, - .status_base = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, - PALMAS_INT1_STATUS), - .mask_base = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, - PALMAS_INT1_MASK), -}; - -static int __devinit palmas_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct palmas *palmas; - struct palmas_platform_data *pdata; - int ret = 0, i; - unsigned int reg, addr; - int slave; - struct mfd_cell *children; - - pdata = dev_get_platdata(&i2c->dev); - if (!pdata) - return -EINVAL; - - palmas = devm_kzalloc(&i2c->dev, sizeof(struct palmas), GFP_KERNEL); - if (palmas == NULL) - return -ENOMEM; - - i2c_set_clientdata(i2c, palmas); - palmas->dev = &i2c->dev; - palmas->id = id->driver_data; - palmas->irq = i2c->irq; - - for (i = 0; i < PALMAS_NUM_CLIENTS; i++) { - if (i == 0) - palmas->i2c_clients[i] = i2c; - else { - palmas->i2c_clients[i] = - i2c_new_dummy(i2c->adapter, - i2c->addr + i); - if (!palmas->i2c_clients[i]) { - dev_err(palmas->dev, - "can't attach client %d\n", i); - ret = -ENOMEM; - goto err; - } - } - palmas->regmap[i] = devm_regmap_init_i2c(palmas->i2c_clients[i], - &palmas_regmap_config[i]); - if (IS_ERR(palmas->regmap[i])) { - ret = PTR_ERR(palmas->regmap[i]); - dev_err(palmas->dev, - "Failed to allocate regmap %d, err: %d\n", - i, ret); - goto err; - } - } - - ret = regmap_add_irq_chip(palmas->regmap[1], palmas->irq, - IRQF_ONESHOT | IRQF_TRIGGER_LOW, -1, &palmas_irq_chip, - &palmas->irq_data); - if (ret < 0) - goto err; - - slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE); - addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, - PALMAS_PRIMARY_SECONDARY_PAD1); - - if (pdata->mux_from_pdata) { - reg = pdata->pad1; - ret = regmap_write(palmas->regmap[slave], addr, reg); - if (ret) - goto err; - } else { - ret = regmap_read(palmas->regmap[slave], addr, ®); - if (ret) - goto err; - } - - if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_0)) - palmas->gpio_muxed |= PALMAS_GPIO_0_MUXED; - if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK)) - palmas->gpio_muxed |= PALMAS_GPIO_1_MUXED; - else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK) == - (2 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT)) - palmas->led_muxed |= PALMAS_LED1_MUXED; - else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK) == - (3 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT)) - palmas->pwm_muxed |= PALMAS_PWM1_MUXED; - if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK)) - palmas->gpio_muxed |= PALMAS_GPIO_2_MUXED; - else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK) == - (2 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_SHIFT)) - palmas->led_muxed |= PALMAS_LED2_MUXED; - else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK) == - (3 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_SHIFT)) - palmas->pwm_muxed |= PALMAS_PWM2_MUXED; - if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_3)) - palmas->gpio_muxed |= PALMAS_GPIO_3_MUXED; - - addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, - PALMAS_PRIMARY_SECONDARY_PAD2); - - if (pdata->mux_from_pdata) { - reg = pdata->pad2; - ret = regmap_write(palmas->regmap[slave], addr, reg); - if (ret) - goto err; - } else { - ret = regmap_read(palmas->regmap[slave], addr, ®); - if (ret) - goto err; - } - - if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_4)) - palmas->gpio_muxed |= PALMAS_GPIO_4_MUXED; - if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_5_MASK)) - palmas->gpio_muxed |= PALMAS_GPIO_5_MUXED; - if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_6)) - palmas->gpio_muxed |= PALMAS_GPIO_6_MUXED; - if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_7_MASK)) - palmas->gpio_muxed |= PALMAS_GPIO_7_MUXED; - - dev_info(palmas->dev, "Muxing GPIO %x, PWM %x, LED %x\n", - palmas->gpio_muxed, palmas->pwm_muxed, - palmas->led_muxed); - - reg = pdata->power_ctrl; - - slave = PALMAS_BASE_TO_SLAVE(PALMAS_PMU_CONTROL_BASE); - addr = PALMAS_BASE_TO_REG(PALMAS_PMU_CONTROL_BASE, PALMAS_POWER_CTRL); - - ret = regmap_write(palmas->regmap[slave], addr, reg); - if (ret) - goto err; - - children = kmemdup(palmas_children, sizeof(palmas_children), - GFP_KERNEL); - if (!children) { - ret = -ENOMEM; - goto err; - } - - ret = mfd_add_devices(palmas->dev, -1, - children, ARRAY_SIZE(palmas_children), - NULL, regmap_irq_chip_get_base(palmas->irq_data)); - kfree(children); - - if (ret < 0) - goto err; - - return ret; - -err: - mfd_remove_devices(palmas->dev); - kfree(palmas); - return ret; -} - -static int palmas_i2c_remove(struct i2c_client *i2c) -{ - struct palmas *palmas = i2c_get_clientdata(i2c); - - mfd_remove_devices(palmas->dev); - regmap_del_irq_chip(palmas->irq, palmas->irq_data); - - return 0; -} - -static const struct i2c_device_id palmas_i2c_id[] = { - { "palmas", }, - { "twl6035", }, - { "twl6037", }, - { "tps65913", }, -}; -MODULE_DEVICE_TABLE(i2c, palmas_i2c_id); - -static struct of_device_id __devinitdata of_palmas_match_tbl[] = { - { .compatible = "ti,palmas", }, - { /* end */ } -}; - -static struct i2c_driver palmas_i2c_driver = { - .driver = { - .name = "palmas", - .of_match_table = of_palmas_match_tbl, - .owner = THIS_MODULE, - }, - .probe = palmas_i2c_probe, - .remove = palmas_i2c_remove, - .id_table = palmas_i2c_id, -}; - -static int __init palmas_i2c_init(void) -{ - return i2c_add_driver(&palmas_i2c_driver); -} -/* init early so consumer devices can complete system boot */ -subsys_initcall(palmas_i2c_init); - -static void __exit palmas_i2c_exit(void) -{ - i2c_del_driver(&palmas_i2c_driver); -} -module_exit(palmas_i2c_exit); - -MODULE_AUTHOR("Graeme Gregory "); -MODULE_DESCRIPTION("Palmas chip family multi-function driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/mfd/tps65090.c b/trunk/drivers/mfd/tps65090.c index 47f802bf1848..a66d4df51293 100644 --- a/trunk/drivers/mfd/tps65090.c +++ b/trunk/drivers/mfd/tps65090.c @@ -78,6 +78,17 @@ static struct mfd_cell tps65090s[] = { }, }; +struct tps65090 { + struct mutex lock; + struct device *dev; + struct i2c_client *client; + struct regmap *rmap; + struct irq_chip irq_chip; + struct mutex irq_lock; + int irq_base; + unsigned int id; +}; + int tps65090_write(struct device *dev, int reg, uint8_t val) { struct tps65090 *tps = dev_get_drvdata(dev); diff --git a/trunk/drivers/mfd/tps6586x.c b/trunk/drivers/mfd/tps6586x.c index c84b5506d5fb..a5ddf31b60ca 100644 --- a/trunk/drivers/mfd/tps6586x.c +++ b/trunk/drivers/mfd/tps6586x.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -461,7 +460,6 @@ static int __devinit tps6586x_add_subdevs(struct tps6586x *tps6586x, pdev->dev.parent = tps6586x->dev; pdev->dev.platform_data = subdev->platform_data; - pdev->dev.of_node = subdev->of_node; ret = platform_device_add(pdev); if (ret) { @@ -476,86 +474,6 @@ static int __devinit tps6586x_add_subdevs(struct tps6586x *tps6586x, return ret; } -#ifdef CONFIG_OF -static struct of_regulator_match tps6586x_matches[] = { - { .name = "sm0", .driver_data = (void *)TPS6586X_ID_SM_0 }, - { .name = "sm1", .driver_data = (void *)TPS6586X_ID_SM_1 }, - { .name = "sm2", .driver_data = (void *)TPS6586X_ID_SM_2 }, - { .name = "ldo0", .driver_data = (void *)TPS6586X_ID_LDO_0 }, - { .name = "ldo1", .driver_data = (void *)TPS6586X_ID_LDO_1 }, - { .name = "ldo2", .driver_data = (void *)TPS6586X_ID_LDO_2 }, - { .name = "ldo3", .driver_data = (void *)TPS6586X_ID_LDO_3 }, - { .name = "ldo4", .driver_data = (void *)TPS6586X_ID_LDO_4 }, - { .name = "ldo5", .driver_data = (void *)TPS6586X_ID_LDO_5 }, - { .name = "ldo6", .driver_data = (void *)TPS6586X_ID_LDO_6 }, - { .name = "ldo7", .driver_data = (void *)TPS6586X_ID_LDO_7 }, - { .name = "ldo8", .driver_data = (void *)TPS6586X_ID_LDO_8 }, - { .name = "ldo9", .driver_data = (void *)TPS6586X_ID_LDO_9 }, - { .name = "ldo_rtc", .driver_data = (void *)TPS6586X_ID_LDO_RTC }, -}; - -static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client) -{ - const unsigned int num = ARRAY_SIZE(tps6586x_matches); - struct device_node *np = client->dev.of_node; - struct tps6586x_platform_data *pdata; - struct tps6586x_subdev_info *devs; - struct device_node *regs; - unsigned int count; - unsigned int i, j; - int err; - - regs = of_find_node_by_name(np, "regulators"); - if (!regs) - return NULL; - - err = of_regulator_match(&client->dev, regs, tps6586x_matches, num); - if (err < 0) { - of_node_put(regs); - return NULL; - } - - of_node_put(regs); - count = err; - - devs = devm_kzalloc(&client->dev, count * sizeof(*devs), GFP_KERNEL); - if (!devs) - return NULL; - - for (i = 0, j = 0; i < num && j < count; i++) { - if (!tps6586x_matches[i].init_data) - continue; - - devs[j].name = "tps6586x-regulator"; - devs[j].platform_data = tps6586x_matches[i].init_data; - devs[j].id = (int)tps6586x_matches[i].driver_data; - devs[j].of_node = tps6586x_matches[i].of_node; - j++; - } - - pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return NULL; - - pdata->num_subdevs = count; - pdata->subdevs = devs; - pdata->gpio_base = -1; - pdata->irq_base = -1; - - return pdata; -} - -static struct of_device_id tps6586x_of_match[] = { - { .compatible = "ti,tps6586x", }, - { }, -}; -#else -static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client) -{ - return NULL; -} -#endif - static int __devinit tps6586x_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -563,9 +481,6 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client, struct tps6586x *tps6586x; int ret; - if (!pdata && client->dev.of_node) - pdata = tps6586x_parse_dt(client); - if (!pdata) { dev_err(&client->dev, "tps6586x requires platform data\n"); return -ENOTSUPP; @@ -658,7 +573,6 @@ static struct i2c_driver tps6586x_driver = { .driver = { .name = "tps6586x", .owner = THIS_MODULE, - .of_match_table = of_match_ptr(tps6586x_of_match), }, .probe = tps6586x_i2c_probe, .remove = __devexit_p(tps6586x_i2c_remove), diff --git a/trunk/drivers/mfd/twl-core.c b/trunk/drivers/mfd/twl-core.c index 6fc90befa79e..7c2267e71f8b 100644 --- a/trunk/drivers/mfd/twl-core.c +++ b/trunk/drivers/mfd/twl-core.c @@ -224,6 +224,13 @@ #define HIGH_PERF_SQ (1 << 3) #define CK32K_LOWPWR_EN (1 << 7) + +/* chip-specific feature flags, for i2c_device_id.driver_data */ +#define TWL4030_VAUX2 BIT(0) /* pre-5030 voltage ranges */ +#define TPS_SUBSET BIT(1) /* tps659[23]0 have fewer LDOs */ +#define TWL5031 BIT(2) /* twl5031 has different registers */ +#define TWL6030_CLASS BIT(3) /* TWL6030 class */ + /*----------------------------------------------------------------------*/ /* is driver active, bound to a chip? */ diff --git a/trunk/drivers/mfd/wm8994-irq.c b/trunk/drivers/mfd/wm8994-irq.c index f1837f669755..46b20c445ecf 100644 --- a/trunk/drivers/mfd/wm8994-irq.c +++ b/trunk/drivers/mfd/wm8994-irq.c @@ -147,6 +147,12 @@ int wm8994_irq_init(struct wm8994 *wm8994) return 0; } + if (!wm8994->irq_base) { + dev_err(wm8994->dev, + "No interrupt base specified, no interrupts\n"); + return 0; + } + ret = regmap_add_irq_chip(wm8994->regmap, wm8994->irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, wm8994->irq_base, &wm8994_irq_chip, diff --git a/trunk/drivers/mmc/host/mmci.c b/trunk/drivers/mmc/host/mmci.c index b6f38421d541..032b84791a16 100644 --- a/trunk/drivers/mmc/host/mmci.c +++ b/trunk/drivers/mmc/host/mmci.c @@ -94,17 +94,6 @@ static struct variant_data variant_u300 = { .signal_direction = true, }; -static struct variant_data variant_nomadik = { - .fifosize = 16 * 4, - .fifohalfsize = 8 * 4, - .clkreg = MCI_CLK_ENABLE, - .datalength_bits = 24, - .sdio = true, - .st_clkdiv = true, - .pwrreg_powerup = MCI_PWR_ON, - .signal_direction = true, -}; - static struct variant_data variant_ux500 = { .fifosize = 30 * 4, .fifohalfsize = 8 * 4, @@ -1408,7 +1397,7 @@ static int __devinit mmci_probe(struct amba_device *dev, if (ret) goto unmap; - if (!dev->irq[1]) + if (dev->irq[1] == NO_IRQ || !dev->irq[1]) host->singleirq = true; else { ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED, @@ -1579,11 +1568,6 @@ static struct amba_id mmci_ids[] = { .mask = 0x00ffffff, .data = &variant_u300, }, - { - .id = 0x10180180, - .mask = 0xf0ffffff, - .data = &variant_nomadik, - }, { .id = 0x00280180, .mask = 0x00ffffff, diff --git a/trunk/drivers/mtd/mtdchar.c b/trunk/drivers/mtd/mtdchar.c index f2f482bec573..58fc65f5c817 100644 --- a/trunk/drivers/mtd/mtdchar.c +++ b/trunk/drivers/mtd/mtdchar.c @@ -376,7 +376,7 @@ static int otp_select_filemode(struct mtd_file_info *mfi, int mode) * Make a fake call to mtd_read_fact_prot_reg() to check if OTP * operations are supported. */ - if (mtd_read_fact_prot_reg(mtd, -1, 0, &retlen, NULL) == -EOPNOTSUPP) + if (mtd_read_fact_prot_reg(mtd, -1, -1, &retlen, NULL) == -EOPNOTSUPP) return -EOPNOTSUPP; switch (mode) { diff --git a/trunk/drivers/mtd/nand/ams-delta.c b/trunk/drivers/mtd/nand/ams-delta.c index 861ca8f7e47d..73416951f4c1 100644 --- a/trunk/drivers/mtd/nand/ams-delta.c +++ b/trunk/drivers/mtd/nand/ams-delta.c @@ -212,17 +212,18 @@ static int __devinit ams_delta_init(struct platform_device *pdev) /* Link the private data with the MTD structure */ ams_delta_mtd->priv = this; - /* - * Don't try to request the memory region from here, - * it should have been already requested from the - * gpio-omap driver and requesting it again would fail. - */ + if (!request_mem_region(res->start, resource_size(res), + dev_name(&pdev->dev))) { + dev_err(&pdev->dev, "request_mem_region failed\n"); + err = -EBUSY; + goto out_free; + } io_base = ioremap(res->start, resource_size(res)); if (io_base == NULL) { dev_err(&pdev->dev, "ioremap failed\n"); err = -EIO; - goto out_free; + goto out_release_io; } this->priv = io_base; @@ -270,6 +271,8 @@ static int __devinit ams_delta_init(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); gpio_free(AMS_DELTA_GPIO_PIN_NAND_RB); iounmap(io_base); +out_release_io: + release_mem_region(res->start, resource_size(res)); out_free: kfree(ams_delta_mtd); out: @@ -282,6 +285,7 @@ static int __devinit ams_delta_init(struct platform_device *pdev) static int __devexit ams_delta_cleanup(struct platform_device *pdev) { void __iomem *io_base = platform_get_drvdata(pdev); + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); /* Release resources, unregister device */ nand_release(ams_delta_mtd); @@ -289,6 +293,7 @@ static int __devexit ams_delta_cleanup(struct platform_device *pdev) gpio_free_array(_mandatory_gpio, ARRAY_SIZE(_mandatory_gpio)); gpio_free(AMS_DELTA_GPIO_PIN_NAND_RB); iounmap(io_base); + release_mem_region(res->start, resource_size(res)); /* Free the MTD device structure */ kfree(ams_delta_mtd); diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index 0c2bd806950e..b98285446a5a 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -66,7 +66,10 @@ config DUMMY . To compile this driver as a module, choose M here: the module - will be called dummy. + will be called dummy. If you want to use more than one dummy + device at a time, you need to compile this driver as a module. + Instead of 'dummy', the devices will then be called 'dummy0', + 'dummy1' etc. config EQUALIZER tristate "EQL (serial line load balancing) support" @@ -282,6 +285,8 @@ source "drivers/net/slip/Kconfig" source "drivers/s390/net/Kconfig" +source "drivers/net/tokenring/Kconfig" + source "drivers/net/usb/Kconfig" source "drivers/net/wireless/Kconfig" diff --git a/trunk/drivers/net/Makefile b/trunk/drivers/net/Makefile index 3d375ca128a6..a6b8ce11a22f 100644 --- a/trunk/drivers/net/Makefile +++ b/trunk/drivers/net/Makefile @@ -50,6 +50,7 @@ obj-$(CONFIG_SLIP) += slip/ obj-$(CONFIG_SLHC) += slip/ obj-$(CONFIG_NET_SB1000) += sb1000.o obj-$(CONFIG_SUNGEM_PHY) += sungem_phy.o +obj-$(CONFIG_TR) += tokenring/ obj-$(CONFIG_WAN) += wan/ obj-$(CONFIG_WLAN) += wireless/ obj-$(CONFIG_WIMAX) += wimax/ diff --git a/trunk/drivers/net/Space.c b/trunk/drivers/net/Space.c index e3f0faca98d0..88bbd8ffa7fe 100644 --- a/trunk/drivers/net/Space.c +++ b/trunk/drivers/net/Space.c @@ -29,6 +29,7 @@ */ #include #include +#include #include #include #include @@ -133,9 +134,22 @@ static struct devprobe2 eisa_probes[] __initdata = { {NULL, 0}, }; +static struct devprobe2 mca_probes[] __initdata = { +#ifdef CONFIG_NE2_MCA + {ne2_probe, 0}, +#endif +#ifdef CONFIG_ELMC /* 3c523 */ + {elmc_probe, 0}, +#endif +#ifdef CONFIG_ELMC_II /* 3c527 */ + {mc32_probe, 0}, +#endif + {NULL, 0}, +}; + /* * ISA probes that touch addresses < 0x400 (including those that also - * look for EISA/PCI cards in addition to ISA cards). + * look for EISA/PCI/MCA cards in addition to ISA cards). */ static struct devprobe2 isa_probes[] __initdata = { #if defined(CONFIG_HP100) && defined(CONFIG_ISA) /* ISA, EISA */ @@ -265,10 +279,51 @@ static void __init ethif_probe2(int unit) (void)( probe_list2(unit, m68k_probes, base_addr == 0) && probe_list2(unit, eisa_probes, base_addr == 0) && + probe_list2(unit, mca_probes, base_addr == 0) && probe_list2(unit, isa_probes, base_addr == 0) && probe_list2(unit, parport_probes, base_addr == 0)); } +#ifdef CONFIG_TR +/* Token-ring device probe */ +extern int ibmtr_probe_card(struct net_device *); +extern struct net_device *smctr_probe(int unit); + +static struct devprobe2 tr_probes2[] __initdata = { +#ifdef CONFIG_SMCTR + {smctr_probe, 0}, +#endif + {NULL, 0}, +}; + +static __init int trif_probe(int unit) +{ + int err = -ENODEV; +#ifdef CONFIG_IBMTR + struct net_device *dev = alloc_trdev(0); + if (!dev) + return -ENOMEM; + + sprintf(dev->name, "tr%d", unit); + netdev_boot_setup_check(dev); + err = ibmtr_probe_card(dev); + if (err) + free_netdev(dev); +#endif + return err; +} + +static void __init trif_probe2(int unit) +{ + unsigned long base_addr = netdev_boot_base("tr", unit); + + if (base_addr == 1) + return; + probe_list2(unit, tr_probes2, base_addr == 0); +} +#endif + + /* Statically configured drivers -- order matters here. */ static int __init net_olddevs_init(void) { @@ -277,6 +332,11 @@ static int __init net_olddevs_init(void) #ifdef CONFIG_SBNI for (num = 0; num < 8; ++num) sbni_probe(num); +#endif +#ifdef CONFIG_TR + for (num = 0; num < 8; ++num) + if (!trif_probe(num)) + trif_probe2(num); #endif for (num = 0; num < 8; ++num) ethif_probe2(num); diff --git a/trunk/drivers/net/bonding/bond_3ad.c b/trunk/drivers/net/bonding/bond_3ad.c index 3463b469e657..793b00138275 100644 --- a/trunk/drivers/net/bonding/bond_3ad.c +++ b/trunk/drivers/net/bonding/bond_3ad.c @@ -2173,10 +2173,9 @@ void bond_3ad_state_machine_handler(struct work_struct *work) * received frames (loopback). Since only the payload is given to this * function, it check for loopback. */ -static int bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u16 length) +static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u16 length) { struct port *port; - int ret = RX_HANDLER_ANOTHER; if (length >= sizeof(struct lacpdu)) { @@ -2185,12 +2184,11 @@ static int bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u1 if (!port->slave) { pr_warning("%s: Warning: port of slave %s is uninitialized\n", slave->dev->name, slave->dev->master->name); - return ret; + return; } switch (lacpdu->subtype) { case AD_TYPE_LACPDU: - ret = RX_HANDLER_CONSUMED; pr_debug("Received LACPDU on port %d\n", port->actor_port_number); /* Protect against concurrent state machines */ @@ -2200,7 +2198,6 @@ static int bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u1 break; case AD_TYPE_MARKER: - ret = RX_HANDLER_CONSUMED; // No need to convert fields to Little Endian since we don't use the marker's fields. switch (((struct bond_marker *)lacpdu)->tlv_type) { @@ -2222,7 +2219,6 @@ static int bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u1 } } } - return ret; } /** @@ -2460,20 +2456,18 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } -int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond, +void bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond, struct slave *slave) { - int ret = RX_HANDLER_ANOTHER; if (skb->protocol != PKT_TYPE_LACPDU) - return ret; + return; if (!pskb_may_pull(skb, sizeof(struct lacpdu))) - return ret; + return; read_lock(&bond->lock); - ret = bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len); + bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len); read_unlock(&bond->lock); - return ret; } /* diff --git a/trunk/drivers/net/bonding/bond_3ad.h b/trunk/drivers/net/bonding/bond_3ad.h index 5ee7e3c45db7..235b2cc58b28 100644 --- a/trunk/drivers/net/bonding/bond_3ad.h +++ b/trunk/drivers/net/bonding/bond_3ad.h @@ -274,7 +274,7 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave); void bond_3ad_handle_link_change(struct slave *slave, char link); int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); -int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond, +void bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond, struct slave *slave); int bond_3ad_set_carrier(struct bonding *bond); void bond_3ad_update_lacp_rate(struct bonding *bond); diff --git a/trunk/drivers/net/bonding/bond_alb.c b/trunk/drivers/net/bonding/bond_alb.c index 0f59c1564e53..9abfde479316 100644 --- a/trunk/drivers/net/bonding/bond_alb.c +++ b/trunk/drivers/net/bonding/bond_alb.c @@ -332,7 +332,7 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp) if ((client_info->assigned) && (client_info->ip_src == arp->ip_dst) && (client_info->ip_dst == arp->ip_src) && - (!ether_addr_equal_64bits(client_info->mac_dst, arp->mac_src))) { + (compare_ether_addr_64bits(client_info->mac_dst, arp->mac_src))) { /* update the clients MAC address */ memcpy(client_info->mac_dst, arp->mac_src, ETH_ALEN); client_info->ntt = 1; @@ -342,26 +342,26 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp) _unlock_rx_hashtbl_bh(bond); } -static int rlb_arp_recv(struct sk_buff *skb, struct bonding *bond, +static void rlb_arp_recv(struct sk_buff *skb, struct bonding *bond, struct slave *slave) { struct arp_pkt *arp; if (skb->protocol != cpu_to_be16(ETH_P_ARP)) - goto out; + return; arp = (struct arp_pkt *) skb->data; if (!arp) { pr_debug("Packet has no ARP data\n"); - goto out; + return; } if (!pskb_may_pull(skb, arp_hdr_len(bond->dev))) - goto out; + return; if (skb->len < sizeof(struct arp_pkt)) { pr_debug("Packet is too small to be an ARP\n"); - goto out; + return; } if (arp->op_code == htons(ARPOP_REPLY)) { @@ -369,8 +369,6 @@ static int rlb_arp_recv(struct sk_buff *skb, struct bonding *bond, rlb_update_entry_from_arp(bond, arp); pr_debug("Server received an ARP Reply from client\n"); } -out: - return RX_HANDLER_ANOTHER; } /* Caller must hold bond lock for read */ @@ -450,8 +448,8 @@ static void rlb_clear_slave(struct bonding *bond, struct slave *slave) if (assigned_slave) { rx_hash_table[index].slave = assigned_slave; - if (!ether_addr_equal_64bits(rx_hash_table[index].mac_dst, - mac_bcast)) { + if (compare_ether_addr_64bits(rx_hash_table[index].mac_dst, + mac_bcast)) { bond_info->rx_hashtbl[index].ntt = 1; bond_info->rx_ntt = 1; /* A slave has been removed from the @@ -563,7 +561,7 @@ static void rlb_req_update_slave_clients(struct bonding *bond, struct slave *sla client_info = &(bond_info->rx_hashtbl[hash_index]); if ((client_info->slave == slave) && - !ether_addr_equal_64bits(client_info->mac_dst, mac_bcast)) { + compare_ether_addr_64bits(client_info->mac_dst, mac_bcast)) { client_info->ntt = 1; ntt = 1; } @@ -602,9 +600,9 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, __be32 src_ip) * unicast mac address. */ if ((client_info->ip_src == src_ip) && - !ether_addr_equal_64bits(client_info->slave->dev->dev_addr, - bond->dev->dev_addr) && - !ether_addr_equal_64bits(client_info->mac_dst, mac_bcast)) { + compare_ether_addr_64bits(client_info->slave->dev->dev_addr, + bond->dev->dev_addr) && + compare_ether_addr_64bits(client_info->mac_dst, mac_bcast)) { client_info->ntt = 1; bond_info->rx_ntt = 1; } @@ -631,7 +629,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon if ((client_info->ip_src == arp->ip_src) && (client_info->ip_dst == arp->ip_dst)) { /* the entry is already assigned to this client */ - if (!ether_addr_equal_64bits(arp->mac_dst, mac_bcast)) { + if (compare_ether_addr_64bits(arp->mac_dst, mac_bcast)) { /* update mac address from arp */ memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN); } @@ -666,7 +664,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN); client_info->slave = assigned_slave; - if (!ether_addr_equal_64bits(client_info->mac_dst, mac_bcast)) { + if (compare_ether_addr_64bits(client_info->mac_dst, mac_bcast)) { client_info->ntt = 1; bond->alb_info.rx_ntt = 1; } else { @@ -1011,18 +1009,18 @@ static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *sla int perm_curr_diff; int perm_bond_diff; - perm_curr_diff = !ether_addr_equal_64bits(slave->perm_hwaddr, - slave->dev->dev_addr); - perm_bond_diff = !ether_addr_equal_64bits(slave->perm_hwaddr, - bond->dev->dev_addr); + perm_curr_diff = compare_ether_addr_64bits(slave->perm_hwaddr, + slave->dev->dev_addr); + perm_bond_diff = compare_ether_addr_64bits(slave->perm_hwaddr, + bond->dev->dev_addr); if (perm_curr_diff && perm_bond_diff) { struct slave *tmp_slave; int i, found = 0; bond_for_each_slave(bond, tmp_slave, i) { - if (ether_addr_equal_64bits(slave->perm_hwaddr, - tmp_slave->dev->dev_addr)) { + if (!compare_ether_addr_64bits(slave->perm_hwaddr, + tmp_slave->dev->dev_addr)) { found = 1; break; } @@ -1076,10 +1074,10 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav * check uniqueness of slave's mac address against the other * slaves in the bond. */ - if (!ether_addr_equal_64bits(slave->perm_hwaddr, bond->dev->dev_addr)) { + if (compare_ether_addr_64bits(slave->perm_hwaddr, bond->dev->dev_addr)) { bond_for_each_slave(bond, tmp_slave1, i) { - if (ether_addr_equal_64bits(tmp_slave1->dev->dev_addr, - slave->dev->dev_addr)) { + if (!compare_ether_addr_64bits(tmp_slave1->dev->dev_addr, + slave->dev->dev_addr)) { found = 1; break; } @@ -1101,8 +1099,8 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav bond_for_each_slave(bond, tmp_slave1, i) { found = 0; bond_for_each_slave(bond, tmp_slave2, j) { - if (ether_addr_equal_64bits(tmp_slave1->perm_hwaddr, - tmp_slave2->dev->dev_addr)) { + if (!compare_ether_addr_64bits(tmp_slave1->perm_hwaddr, + tmp_slave2->dev->dev_addr)) { found = 1; break; } @@ -1117,8 +1115,8 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav } if (!has_bond_addr) { - if (ether_addr_equal_64bits(tmp_slave1->dev->dev_addr, - bond->dev->dev_addr)) { + if (!compare_ether_addr_64bits(tmp_slave1->dev->dev_addr, + bond->dev->dev_addr)) { has_bond_addr = tmp_slave1; } @@ -1259,7 +1257,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) case ETH_P_IP: { const struct iphdr *iph = ip_hdr(skb); - if (ether_addr_equal_64bits(eth_data->h_dest, mac_bcast) || + if (!compare_ether_addr_64bits(eth_data->h_dest, mac_bcast) || (iph->daddr == ip_bcast) || (iph->protocol == IPPROTO_IGMP)) { do_tx_balance = 0; @@ -1273,7 +1271,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) /* IPv6 doesn't really use broadcast mac address, but leave * that here just in case. */ - if (ether_addr_equal_64bits(eth_data->h_dest, mac_bcast)) { + if (!compare_ether_addr_64bits(eth_data->h_dest, mac_bcast)) { do_tx_balance = 0; break; } @@ -1281,7 +1279,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) /* IPv6 uses all-nodes multicast as an equivalent to * broadcasts in IPv4. */ - if (ether_addr_equal_64bits(eth_data->h_dest, mac_v6_allmcast)) { + if (!compare_ether_addr_64bits(eth_data->h_dest, mac_v6_allmcast)) { do_tx_balance = 0; break; } @@ -1605,8 +1603,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave struct slave *tmp_slave; /* find slave that is holding the bond's mac address */ bond_for_each_slave(bond, tmp_slave, i) { - if (ether_addr_equal_64bits(tmp_slave->dev->dev_addr, - bond->dev->dev_addr)) { + if (!compare_ether_addr_64bits(tmp_slave->dev->dev_addr, + bond->dev->dev_addr)) { swap_slave = tmp_slave; break; } @@ -1683,8 +1681,8 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr) swap_slave = NULL; bond_for_each_slave(bond, slave, i) { - if (ether_addr_equal_64bits(slave->dev->dev_addr, - bond_dev->dev_addr)) { + if (!compare_ether_addr_64bits(slave->dev->dev_addr, + bond_dev->dev_addr)) { swap_slave = slave; break; } diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index 2ee8cf9e8a3b..16dbf53e314b 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -1444,9 +1444,8 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) struct sk_buff *skb = *pskb; struct slave *slave; struct bonding *bond; - int (*recv_probe)(struct sk_buff *, struct bonding *, + void (*recv_probe)(struct sk_buff *, struct bonding *, struct slave *); - int ret = RX_HANDLER_ANOTHER; skb = skb_share_check(skb, GFP_ATOMIC); if (unlikely(!skb)) @@ -1465,12 +1464,8 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC); if (likely(nskb)) { - ret = recv_probe(nskb, bond, slave); + recv_probe(nskb, bond, slave); dev_kfree_skb(nskb); - if (ret == RX_HANDLER_CONSUMED) { - consume_skb(skb); - return ret; - } } } @@ -1492,7 +1487,7 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) memcpy(eth_hdr(skb)->h_dest, bond->dev->dev_addr, ETH_ALEN); } - return ret; + return RX_HANDLER_ANOTHER; } /* enslave device to bond device */ @@ -1966,7 +1961,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) write_lock_bh(&bond->lock); if (!bond->params.fail_over_mac) { - if (ether_addr_equal(bond_dev->dev_addr, slave->perm_hwaddr) && + if (!compare_ether_addr(bond_dev->dev_addr, slave->perm_hwaddr) && bond->slave_cnt > 1) pr_warning("%s: Warning: the permanent HWaddr of %s - %pM - is still in use by %s. Set the HWaddr of %s to a different address to avoid conflicts.\n", bond_dev->name, slave_dev->name, @@ -2737,7 +2732,7 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 } } -static int bond_arp_rcv(struct sk_buff *skb, struct bonding *bond, +static void bond_arp_rcv(struct sk_buff *skb, struct bonding *bond, struct slave *slave) { struct arphdr *arp; @@ -2745,7 +2740,7 @@ static int bond_arp_rcv(struct sk_buff *skb, struct bonding *bond, __be32 sip, tip; if (skb->protocol != __cpu_to_be16(ETH_P_ARP)) - return RX_HANDLER_ANOTHER; + return; read_lock(&bond->lock); @@ -2790,7 +2785,6 @@ static int bond_arp_rcv(struct sk_buff *skb, struct bonding *bond, out_unlock: read_unlock(&bond->lock); - return RX_HANDLER_ANOTHER; } /* diff --git a/trunk/drivers/net/bonding/bonding.h b/trunk/drivers/net/bonding/bonding.h index 4581aa5ccaba..9f2bae6616d3 100644 --- a/trunk/drivers/net/bonding/bonding.h +++ b/trunk/drivers/net/bonding/bonding.h @@ -218,7 +218,7 @@ struct bonding { struct slave *primary_slave; bool force_primary; s32 slave_cnt; /* never change this value outside the attach/detach wrappers */ - int (*recv_probe)(struct sk_buff *, struct bonding *, + void (*recv_probe)(struct sk_buff *, struct bonding *, struct slave *); rwlock_t lock; rwlock_t curr_slave_lock; diff --git a/trunk/drivers/net/ethernet/3com/3c509.c b/trunk/drivers/net/ethernet/3com/3c509.c index 1a8eef2c3d58..41719da2e178 100644 --- a/trunk/drivers/net/ethernet/3com/3c509.c +++ b/trunk/drivers/net/ethernet/3com/3c509.c @@ -69,6 +69,7 @@ #define TX_TIMEOUT (400*HZ/1000) #include +#include #include #include #include @@ -101,7 +102,7 @@ static int el3_debug = 2; #endif /* Used to do a global count of all the cards in the system. Must be - * a global variable so that the eisa probe routines can increment + * a global variable so that the mca/eisa probe routines can increment * it */ static int el3_cards = 0; #define EL3_MAX_CARDS 8 @@ -162,7 +163,7 @@ enum RxFilter { */ #define SKB_QUEUE_SIZE 64 -enum el3_cardtype { EL3_ISA, EL3_PNP, EL3_EISA }; +enum el3_cardtype { EL3_ISA, EL3_PNP, EL3_MCA, EL3_EISA }; struct el3_private { spinlock_t lock; @@ -504,6 +505,41 @@ static struct eisa_driver el3_eisa_driver = { static int eisa_registered; #endif +#ifdef CONFIG_MCA +static int el3_mca_probe(struct device *dev); + +static short el3_mca_adapter_ids[] __initdata = { + 0x627c, + 0x627d, + 0x62db, + 0x62f6, + 0x62f7, + 0x0000 +}; + +static char *el3_mca_adapter_names[] __initdata = { + "3Com 3c529 EtherLink III (10base2)", + "3Com 3c529 EtherLink III (10baseT)", + "3Com 3c529 EtherLink III (test mode)", + "3Com 3c529 EtherLink III (TP or coax)", + "3Com 3c529 EtherLink III (TP)", + NULL +}; + +static struct mca_driver el3_mca_driver = { + .id_table = el3_mca_adapter_ids, + .driver = { + .name = "3c529", + .bus = &mca_bus_type, + .probe = el3_mca_probe, + .remove = __devexit_p(el3_device_remove), + .suspend = el3_suspend, + .resume = el3_resume, + }, +}; +static int mca_registered; +#endif /* CONFIG_MCA */ + static const struct net_device_ops netdev_ops = { .ndo_open = el3_open, .ndo_stop = el3_close, @@ -564,6 +600,76 @@ static void el3_common_remove (struct net_device *dev) free_netdev (dev); } +#ifdef CONFIG_MCA +static int __init el3_mca_probe(struct device *device) +{ + /* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch, + * heavily modified by Chris Beauregard + * (cpbeaure@csclub.uwaterloo.ca) to support standard MCA + * probing. + * + * redone for multi-card detection by ZP Gu (zpg@castle.net) + * now works as a module */ + + short i; + int ioaddr, irq, if_port; + __be16 phys_addr[3]; + struct net_device *dev = NULL; + u_char pos4, pos5; + struct mca_device *mdev = to_mca_device(device); + int slot = mdev->slot; + int err; + + pos4 = mca_device_read_stored_pos(mdev, 4); + pos5 = mca_device_read_stored_pos(mdev, 5); + + ioaddr = ((short)((pos4&0xfc)|0x02)) << 8; + irq = pos5 & 0x0f; + + + pr_info("3c529: found %s at slot %d\n", + el3_mca_adapter_names[mdev->index], slot + 1); + + /* claim the slot */ + strncpy(mdev->name, el3_mca_adapter_names[mdev->index], + sizeof(mdev->name)); + mca_device_set_claim(mdev, 1); + + if_port = pos4 & 0x03; + + irq = mca_device_transform_irq(mdev, irq); + ioaddr = mca_device_transform_ioport(mdev, ioaddr); + if (el3_debug > 2) { + pr_debug("3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port); + } + EL3WINDOW(0); + for (i = 0; i < 3; i++) + phys_addr[i] = htons(read_eeprom(ioaddr, i)); + + dev = alloc_etherdev(sizeof (struct el3_private)); + if (dev == NULL) { + release_region(ioaddr, EL3_IO_EXTENT); + return -ENOMEM; + } + + netdev_boot_setup_check(dev); + + el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_MCA); + dev_set_drvdata(device, dev); + err = el3_common_init(dev); + + if (err) { + dev_set_drvdata(device, NULL); + free_netdev(dev); + return -ENOMEM; + } + + el3_devs[el3_cards++] = dev; + return 0; +} + +#endif /* CONFIG_MCA */ + #ifdef CONFIG_EISA static int __init el3_eisa_probe (struct device *device) { @@ -1441,6 +1547,11 @@ static int __init el3_init_module(void) if (!ret) eisa_registered = 1; #endif +#ifdef CONFIG_MCA + ret = mca_register_driver(&el3_mca_driver); + if (!ret) + mca_registered = 1; +#endif #ifdef CONFIG_PNP if (pnp_registered) @@ -1451,6 +1562,10 @@ static int __init el3_init_module(void) #ifdef CONFIG_EISA if (eisa_registered) ret = 0; +#endif +#ifdef CONFIG_MCA + if (mca_registered) + ret = 0; #endif return ret; } @@ -1469,6 +1584,10 @@ static void __exit el3_cleanup_module(void) if (eisa_registered) eisa_driver_unregister(&el3_eisa_driver); #endif +#ifdef CONFIG_MCA + if (mca_registered) + mca_unregister_driver(&el3_mca_driver); +#endif } module_init (el3_init_module); diff --git a/trunk/drivers/net/ethernet/8390/Kconfig b/trunk/drivers/net/ethernet/8390/Kconfig index 2e538676924d..910895c5ec97 100644 --- a/trunk/drivers/net/ethernet/8390/Kconfig +++ b/trunk/drivers/net/ethernet/8390/Kconfig @@ -182,6 +182,18 @@ config NE2000 To compile this driver as a module, choose M here. The module will be called ne. +config NE2_MCA + tristate "NE/2 (ne2000 MCA version) support" + depends on MCA_LEGACY + select CRC32 + ---help--- + If you have a network (Ethernet) card of this type, say Y and read + the Ethernet-HOWTO, available from + . + + To compile this driver as a module, choose M here. The module + will be called ne2. + config NE2K_PCI tristate "PCI NE2000 and clones support (see help)" depends on PCI @@ -255,6 +267,18 @@ config STNIC If unsure, say N. +config ULTRAMCA + tristate "SMC Ultra MCA support" + depends on MCA + select CRC32 + ---help--- + If you have a network (Ethernet) card of this type and are running + an MCA based system (PS/2), say Y and read the Ethernet-HOWTO, + available from . + + To compile this driver as a module, choose M here. The module + will be called smc-mca. + config ULTRA tristate "SMC Ultra support" depends on ISA diff --git a/trunk/drivers/net/ethernet/8390/Makefile b/trunk/drivers/net/ethernet/8390/Makefile index d13790b7fd27..3337d7fb4344 100644 --- a/trunk/drivers/net/ethernet/8390/Makefile +++ b/trunk/drivers/net/ethernet/8390/Makefile @@ -24,5 +24,6 @@ obj-$(CONFIG_PCMCIA_PCNET) += pcnet_cs.o 8390.o obj-$(CONFIG_STNIC) += stnic.o 8390.o obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o obj-$(CONFIG_ULTRA32) += smc-ultra32.o 8390.o +obj-$(CONFIG_ULTRAMCA) += smc-mca.o 8390.o obj-$(CONFIG_WD80x3) += wd.o 8390.o obj-$(CONFIG_ZORRO8390) += zorro8390.o 8390.o diff --git a/trunk/drivers/net/ethernet/8390/ne2.c b/trunk/drivers/net/ethernet/8390/ne2.c new file mode 100644 index 000000000000..ef85839f43d8 --- /dev/null +++ b/trunk/drivers/net/ethernet/8390/ne2.c @@ -0,0 +1,798 @@ +/* ne2.c: A NE/2 Ethernet Driver for Linux. */ +/* + Based on the NE2000 driver written by Donald Becker (1992-94). + modified by Wim Dumon (Apr 1996) + + This software may be used and distributed according to the terms + of the GNU General Public License, incorporated herein by reference. + + The author may be reached as wimpie@linux.cc.kuleuven.ac.be + + Currently supported: NE/2 + This patch was never tested on other MCA-ethernet adapters, but it + might work. Just give it a try and let me know if you have problems. + Also mail me if it really works, please! + + Changelog: + Mon Feb 3 16:26:02 MET 1997 + - adapted the driver to work with the 2.1.25 kernel + - multiple ne2 support (untested) + - module support (untested) + + Fri Aug 28 00:18:36 CET 1998 (David Weinehall) + - fixed a few minor typos + - made the MODULE_PARM conditional (it only works with the v2.1.x kernels) + - fixed the module support (Now it's working...) + + Mon Sep 7 19:01:44 CET 1998 (David Weinehall) + - added support for Arco Electronics AE/2-card (experimental) + + Mon Sep 14 09:53:42 CET 1998 (David Weinehall) + - added support for Compex ENET-16MC/P (experimental) + + Tue Sep 15 16:21:12 CET 1998 (David Weinehall, Magnus Jonsson, Tomas Ogren) + - Miscellaneous bugfixes + + Tue Sep 19 16:21:12 CET 1998 (Magnus Jonsson) + - Cleanup + + Wed Sep 23 14:33:34 CET 1998 (David Weinehall) + - Restructuring and rewriting for v2.1.x compliance + + Wed Oct 14 17:19:21 CET 1998 (David Weinehall) + - Added code that unregisters irq and proc-info + - Version# bump + + Mon Nov 16 15:28:23 CET 1998 (Wim Dumon) + - pass 'dev' as last parameter of request_irq in stead of 'NULL' + + Wed Feb 7 21:24:00 CET 2001 (Alfred Arnold) + - added support for the D-Link DE-320CT + + * WARNING + ------- + This is alpha-test software. It is not guaranteed to work. As a + matter of fact, I'm quite sure there are *LOTS* of bugs in here. I + would like to hear from you if you use this driver, even if it works. + If it doesn't work, be sure to send me a mail with the problems ! +*/ + +static const char *version = "ne2.c:v0.91 Nov 16 1998 Wim Dumon \n"; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "8390.h" + +#define DRV_NAME "ne2" + +/* Some defines that people can play with if so inclined. */ + +/* Do we perform extra sanity checks on stuff ? */ +/* #define NE_SANITY_CHECK */ + +/* Do we implement the read before write bugfix ? */ +/* #define NE_RW_BUGFIX */ + +/* Do we have a non std. amount of memory? (in units of 256 byte pages) */ +/* #define PACKETBUF_MEMSIZE 0x40 */ + + +/* ---- No user-serviceable parts below ---- */ + +#define NE_BASE (dev->base_addr) +#define NE_CMD 0x00 +#define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */ +#define NE_RESET 0x20 /* Issue a read to reset, a write to clear. */ +#define NE_IO_EXTENT 0x30 + +#define NE1SM_START_PG 0x20 /* First page of TX buffer */ +#define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */ +#define NESM_START_PG 0x40 /* First page of TX buffer */ +#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ + +/* From the .ADF file: */ +static unsigned int addresses[7] __initdata = + {0x1000, 0x2020, 0x8020, 0xa0a0, 0xb0b0, 0xc0c0, 0xc3d0}; +static int irqs[4] __initdata = {3, 4, 5, 9}; + +/* From the D-Link ADF file: */ +static unsigned int dlink_addresses[4] __initdata = + {0x300, 0x320, 0x340, 0x360}; +static int dlink_irqs[8] __initdata = {3, 4, 5, 9, 10, 11, 14, 15}; + +struct ne2_adapters_t { + unsigned int id; + char *name; +}; + +static struct ne2_adapters_t ne2_adapters[] __initdata = { + { 0x6354, "Arco Ethernet Adapter AE/2" }, + { 0x70DE, "Compex ENET-16 MC/P" }, + { 0x7154, "Novell Ethernet Adapter NE/2" }, + { 0x56ea, "D-Link DE-320CT" }, + { 0x0000, NULL } +}; + +extern int netcard_probe(struct net_device *dev); + +static int ne2_probe1(struct net_device *dev, int slot); + +static void ne_reset_8390(struct net_device *dev); +static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, + int ring_page); +static void ne_block_input(struct net_device *dev, int count, + struct sk_buff *skb, int ring_offset); +static void ne_block_output(struct net_device *dev, const int count, + const unsigned char *buf, const int start_page); + + +/* + * special code to read the DE-320's MAC address EEPROM. In contrast to a + * standard NE design, this is a serial EEPROM (93C46) that has to be read + * bit by bit. The EEPROM cotrol port at base + 0x1e has the following + * layout: + * + * Bit 0 = Data out (read from EEPROM) + * Bit 1 = Data in (write to EEPROM) + * Bit 2 = Clock + * Bit 3 = Chip Select + * Bit 7 = ~50 kHz clock for defined delays + * + */ + +static void __init dlink_put_eeprom(unsigned char value, unsigned int addr) +{ + int z; + unsigned char v1, v2; + + /* write the value to the NIC EEPROM register */ + + outb(value, addr + 0x1e); + + /* now wait the clock line to toggle twice. Effectively, we are + waiting (at least) for one clock cycle */ + + for (z = 0; z < 2; z++) { + do { + v1 = inb(addr + 0x1e); + v2 = inb(addr + 0x1e); + } + while (!((v1 ^ v2) & 0x80)); + } +} + +static void __init dlink_send_eeprom_bit(unsigned int bit, unsigned int addr) +{ + /* shift data bit into correct position */ + + bit = bit << 1; + + /* write value, keep clock line high for two cycles */ + + dlink_put_eeprom(0x09 | bit, addr); + dlink_put_eeprom(0x0d | bit, addr); + dlink_put_eeprom(0x0d | bit, addr); + dlink_put_eeprom(0x09 | bit, addr); +} + +static void __init dlink_send_eeprom_word(unsigned int value, unsigned int len, unsigned int addr) +{ + int z; + + /* adjust bits so that they are left-aligned in a 16-bit-word */ + + value = value << (16 - len); + + /* shift bits out to the EEPROM */ + + for (z = 0; z < len; z++) { + dlink_send_eeprom_bit((value & 0x8000) >> 15, addr); + value = value << 1; + } +} + +static unsigned int __init dlink_get_eeprom(unsigned int eeaddr, unsigned int addr) +{ + int z; + unsigned int value = 0; + + /* pull the CS line low for a moment. This resets the EEPROM- + internal logic, and makes it ready for a new command. */ + + dlink_put_eeprom(0x01, addr); + dlink_put_eeprom(0x09, addr); + + /* send one start bit, read command (1 - 0), plus the address to + the EEPROM */ + + dlink_send_eeprom_word(0x0180 | (eeaddr & 0x3f), 9, addr); + + /* get the data word. We clock by sending 0s to the EEPROM, which + get ignored during the read process */ + + for (z = 0; z < 16; z++) { + dlink_send_eeprom_bit(0, addr); + value = (value << 1) | (inb(addr + 0x1e) & 0x01); + } + + return value; +} + +/* + * Note that at boot, this probe only picks up one card at a time. + */ + +static int __init do_ne2_probe(struct net_device *dev) +{ + static int current_mca_slot = -1; + int i; + int adapter_found = 0; + + /* Do not check any supplied i/o locations. + POS registers usually don't fail :) */ + + /* MCA cards have POS registers. + Autodetecting MCA cards is extremely simple. + Just search for the card. */ + + for(i = 0; (ne2_adapters[i].name != NULL) && !adapter_found; i++) { + current_mca_slot = + mca_find_unused_adapter(ne2_adapters[i].id, 0); + + if((current_mca_slot != MCA_NOTFOUND) && !adapter_found) { + int res; + mca_set_adapter_name(current_mca_slot, + ne2_adapters[i].name); + mca_mark_as_used(current_mca_slot); + + res = ne2_probe1(dev, current_mca_slot); + if (res) + mca_mark_as_unused(current_mca_slot); + return res; + } + } + return -ENODEV; +} + +#ifndef MODULE +struct net_device * __init ne2_probe(int unit) +{ + struct net_device *dev = alloc_eip_netdev(); + int err; + + if (!dev) + return ERR_PTR(-ENOMEM); + + sprintf(dev->name, "eth%d", unit); + netdev_boot_setup_check(dev); + + err = do_ne2_probe(dev); + if (err) + goto out; + return dev; +out: + free_netdev(dev); + return ERR_PTR(err); +} +#endif + +static int ne2_procinfo(char *buf, int slot, struct net_device *dev) +{ + int len=0; + + len += sprintf(buf+len, "The NE/2 Ethernet Adapter\n" ); + len += sprintf(buf+len, "Driver written by Wim Dumon "); + len += sprintf(buf+len, "\n"); + len += sprintf(buf+len, "Modified by "); + len += sprintf(buf+len, "David Weinehall \n"); + len += sprintf(buf+len, "and by Magnus Jonsson \n"); + len += sprintf(buf+len, "Based on the original NE2000 drivers\n" ); + len += sprintf(buf+len, "Base IO: %#x\n", (unsigned int)dev->base_addr); + len += sprintf(buf+len, "IRQ : %d\n", dev->irq); + len += sprintf(buf+len, "HW addr : %pM\n", dev->dev_addr); + + return len; +} + +static int __init ne2_probe1(struct net_device *dev, int slot) +{ + int i, base_addr, irq, retval; + unsigned char POS; + unsigned char SA_prom[32]; + const char *name = "NE/2"; + int start_page, stop_page; + static unsigned version_printed; + + if (ei_debug && version_printed++ == 0) + printk(version); + + printk("NE/2 ethercard found in slot %d:", slot); + + /* Read base IO and IRQ from the POS-registers */ + POS = mca_read_stored_pos(slot, 2); + if(!(POS % 2)) { + printk(" disabled.\n"); + return -ENODEV; + } + + /* handle different POS register structure for D-Link card */ + + if (mca_read_stored_pos(slot, 0) == 0xea) { + base_addr = dlink_addresses[(POS >> 5) & 0x03]; + irq = dlink_irqs[(POS >> 2) & 0x07]; + } + else { + i = (POS & 0xE)>>1; + /* printk("Halleluja sdog, als er na de pijl een 1 staat is 1 - 1 == 0" + " en zou het moeten werken -> %d\n", i); + The above line was for remote testing, thanx to sdog ... */ + base_addr = addresses[i - 1]; + irq = irqs[(POS & 0x60)>>5]; + } + + if (!request_region(base_addr, NE_IO_EXTENT, DRV_NAME)) + return -EBUSY; + +#ifdef DEBUG + printk("POS info : pos 2 = %#x ; base = %#x ; irq = %ld\n", POS, + base_addr, irq); +#endif + +#ifndef CRYNWR_WAY + /* Reset the card the way they do it in the Crynwr packet driver */ + for (i=0; i<8; i++) + outb(0x0, base_addr + NE_RESET); + inb(base_addr + NE_RESET); + outb(0x21, base_addr + NE_CMD); + if (inb(base_addr + NE_CMD) != 0x21) { + printk("NE/2 adapter not responding\n"); + retval = -ENODEV; + goto out; + } + + /* In the crynwr sources they do a RAM-test here. I skip it. I suppose + my RAM is okay. Suppose your memory is broken. Then this test + should fail and you won't be able to use your card. But if I do not + test, you won't be able to use your card, neither. So this test + won't help you. */ + +#else /* _I_ never tested it this way .. Go ahead and try ...*/ + /* Reset card. Who knows what dain-bramaged state it was left in. */ + { + unsigned long reset_start_time = jiffies; + + /* DON'T change these to inb_p/outb_p or reset will fail on + clones.. */ + outb(inb(base_addr + NE_RESET), base_addr + NE_RESET); + + while ((inb_p(base_addr + EN0_ISR) & ENISR_RESET) == 0) + if (time_after(jiffies, reset_start_time + 2*HZ/100)) { + printk(" not found (no reset ack).\n"); + retval = -ENODEV; + goto out; + } + + outb_p(0xff, base_addr + EN0_ISR); /* Ack all intr. */ + } +#endif + + + /* Read the 16 bytes of station address PROM. + We must first initialize registers, similar to + NS8390p_init(eifdev, 0). + We can't reliably read the SAPROM address without this. + (I learned the hard way!). */ + { + struct { + unsigned char value, offset; + } program_seq[] = { + /* Select page 0 */ + {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, + {0x49, EN0_DCFG}, /* Set WORD-wide (0x49) access. */ + {0x00, EN0_RCNTLO}, /* Clear the count regs. */ + {0x00, EN0_RCNTHI}, + {0x00, EN0_IMR}, /* Mask completion irq. */ + {0xFF, EN0_ISR}, + {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ + {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ + {32, EN0_RCNTLO}, + {0x00, EN0_RCNTHI}, + {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ + {0x00, EN0_RSARHI}, + {E8390_RREAD+E8390_START, E8390_CMD}, + }; + + for (i = 0; i < ARRAY_SIZE(program_seq); i++) + outb_p(program_seq[i].value, base_addr + + program_seq[i].offset); + + } + for(i = 0; i < 6 /*sizeof(SA_prom)*/; i+=1) { + SA_prom[i] = inb(base_addr + NE_DATAPORT); + } + + /* I don't know whether the previous sequence includes the general + board reset procedure, so better don't omit it and just overwrite + the garbage read from a DE-320 with correct stuff. */ + + if (mca_read_stored_pos(slot, 0) == 0xea) { + unsigned int v; + + for (i = 0; i < 3; i++) { + v = dlink_get_eeprom(i, base_addr); + SA_prom[(i << 1) ] = v & 0xff; + SA_prom[(i << 1) + 1] = (v >> 8) & 0xff; + } + } + + start_page = NESM_START_PG; + stop_page = NESM_STOP_PG; + + dev->irq=irq; + + /* Snarf the interrupt now. There's no point in waiting since we cannot + share and the board will usually be enabled. */ + retval = request_irq(dev->irq, eip_interrupt, 0, DRV_NAME, dev); + if (retval) { + printk (" unable to get IRQ %d (irqval=%d).\n", + dev->irq, retval); + goto out; + } + + dev->base_addr = base_addr; + + for (i = 0; i < ETH_ALEN; i++) + dev->dev_addr[i] = SA_prom[i]; + + printk(" %pM\n", dev->dev_addr); + + printk("%s: %s found at %#x, using IRQ %d.\n", + dev->name, name, base_addr, dev->irq); + + mca_set_adapter_procfn(slot, (MCA_ProcFn) ne2_procinfo, dev); + + ei_status.name = name; + ei_status.tx_start_page = start_page; + ei_status.stop_page = stop_page; + ei_status.word16 = (2 == 2); + + ei_status.rx_start_page = start_page + TX_PAGES; +#ifdef PACKETBUF_MEMSIZE + /* Allow the packet buffer size to be overridden by know-it-alls. */ + ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE; +#endif + + ei_status.reset_8390 = &ne_reset_8390; + ei_status.block_input = &ne_block_input; + ei_status.block_output = &ne_block_output; + ei_status.get_8390_hdr = &ne_get_8390_hdr; + + ei_status.priv = slot; + + dev->netdev_ops = &eip_netdev_ops; + NS8390p_init(dev, 0); + + retval = register_netdev(dev); + if (retval) + goto out1; + return 0; +out1: + mca_set_adapter_procfn( ei_status.priv, NULL, NULL); + free_irq(dev->irq, dev); +out: + release_region(base_addr, NE_IO_EXTENT); + return retval; +} + +/* Hard reset the card. This used to pause for the same period that a + 8390 reset command required, but that shouldn't be necessary. */ +static void ne_reset_8390(struct net_device *dev) +{ + unsigned long reset_start_time = jiffies; + + if (ei_debug > 1) + printk("resetting the 8390 t=%ld...", jiffies); + + /* DON'T change these to inb_p/outb_p or reset will fail on clones. */ + outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); + + ei_status.txing = 0; + ei_status.dmaing = 0; + + /* This check _should_not_ be necessary, omit eventually. */ + while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) + if (time_after(jiffies, reset_start_time + 2*HZ/100)) { + printk("%s: ne_reset_8390() did not complete.\n", + dev->name); + break; + } + outb_p(ENISR_RESET, NE_BASE + EN0_ISR); /* Ack intr. */ +} + +/* Grab the 8390 specific header. Similar to the block_input routine, but + we don't need to be concerned with ring wrap as the header will be at + the start of a page, so we optimize accordingly. */ + +static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, + int ring_page) +{ + + int nic_base = dev->base_addr; + + /* This *shouldn't* happen. + If it does, it's the last thing you'll see */ + if (ei_status.dmaing) { + printk("%s: DMAing conflict in ne_get_8390_hdr " + "[DMAstat:%d][irqlock:%d].\n", + dev->name, ei_status.dmaing, ei_status.irqlock); + return; + } + + ei_status.dmaing |= 0x01; + outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); + outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); + outb_p(0, nic_base + EN0_RCNTHI); + outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */ + outb_p(ring_page, nic_base + EN0_RSARHI); + outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); + + if (ei_status.word16) + insw(NE_BASE + NE_DATAPORT, hdr, + sizeof(struct e8390_pkt_hdr)>>1); + else + insb(NE_BASE + NE_DATAPORT, hdr, + sizeof(struct e8390_pkt_hdr)); + + outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ + ei_status.dmaing &= ~0x01; +} + +/* Block input and output, similar to the Crynwr packet driver. If you + are porting to a new ethercard, look at the packet driver source for + hints. The NEx000 doesn't share the on-board packet memory -- you have + to put the packet out through the "remote DMA" dataport using outb. */ + +static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, + int ring_offset) +{ +#ifdef NE_SANITY_CHECK + int xfer_count = count; +#endif + int nic_base = dev->base_addr; + char *buf = skb->data; + + /* This *shouldn't* happen. + If it does, it's the last thing you'll see */ + if (ei_status.dmaing) { + printk("%s: DMAing conflict in ne_block_input " + "[DMAstat:%d][irqlock:%d].\n", + dev->name, ei_status.dmaing, ei_status.irqlock); + return; + } + ei_status.dmaing |= 0x01; + outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); + outb_p(count & 0xff, nic_base + EN0_RCNTLO); + outb_p(count >> 8, nic_base + EN0_RCNTHI); + outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO); + outb_p(ring_offset >> 8, nic_base + EN0_RSARHI); + outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); + if (ei_status.word16) { + insw(NE_BASE + NE_DATAPORT,buf,count>>1); + if (count & 0x01) { + buf[count-1] = inb(NE_BASE + NE_DATAPORT); +#ifdef NE_SANITY_CHECK + xfer_count++; +#endif + } + } else { + insb(NE_BASE + NE_DATAPORT, buf, count); + } + +#ifdef NE_SANITY_CHECK + /* This was for the ALPHA version only, but enough people have + been encountering problems so it is still here. If you see + this message you either 1) have a slightly incompatible clone + or 2) have noise/speed problems with your bus. */ + if (ei_debug > 1) { /* DMA termination address check... */ + int addr, tries = 20; + do { + /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here + -- it's broken for Rx on some cards! */ + int high = inb_p(nic_base + EN0_RSARHI); + int low = inb_p(nic_base + EN0_RSARLO); + addr = (high << 8) + low; + if (((ring_offset + xfer_count) & 0xff) == low) + break; + } while (--tries > 0); + if (tries <= 0) + printk("%s: RX transfer address mismatch," + "%#4.4x (expected) vs. %#4.4x (actual).\n", + dev->name, ring_offset + xfer_count, addr); + } +#endif + outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ + ei_status.dmaing &= ~0x01; +} + +static void ne_block_output(struct net_device *dev, int count, + const unsigned char *buf, const int start_page) +{ + int nic_base = NE_BASE; + unsigned long dma_start; +#ifdef NE_SANITY_CHECK + int retries = 0; +#endif + + /* Round the count up for word writes. Do we need to do this? + What effect will an odd byte count have on the 8390? + I should check someday. */ + if (ei_status.word16 && (count & 0x01)) + count++; + + /* This *shouldn't* happen. + If it does, it's the last thing you'll see */ + if (ei_status.dmaing) { + printk("%s: DMAing conflict in ne_block_output." + "[DMAstat:%d][irqlock:%d]\n", + dev->name, ei_status.dmaing, ei_status.irqlock); + return; + } + ei_status.dmaing |= 0x01; + /* We should already be in page 0, but to be safe... */ + outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); + +#ifdef NE_SANITY_CHECK +retry: +#endif + +#ifdef NE8390_RW_BUGFIX + /* Handle the read-before-write bug the same way as the + Crynwr packet driver -- the NatSemi method doesn't work. + Actually this doesn't always work either, but if you have + problems with your NEx000 this is better than nothing! */ + outb_p(0x42, nic_base + EN0_RCNTLO); + outb_p(0x00, nic_base + EN0_RCNTHI); + outb_p(0x42, nic_base + EN0_RSARLO); + outb_p(0x00, nic_base + EN0_RSARHI); + outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); + /* Make certain that the dummy read has occurred. */ + SLOW_DOWN_IO; + SLOW_DOWN_IO; + SLOW_DOWN_IO; +#endif + + outb_p(ENISR_RDC, nic_base + EN0_ISR); + + /* Now the normal output. */ + outb_p(count & 0xff, nic_base + EN0_RCNTLO); + outb_p(count >> 8, nic_base + EN0_RCNTHI); + outb_p(0x00, nic_base + EN0_RSARLO); + outb_p(start_page, nic_base + EN0_RSARHI); + + outb_p(E8390_RWRITE+E8390_START, nic_base + NE_CMD); + if (ei_status.word16) { + outsw(NE_BASE + NE_DATAPORT, buf, count>>1); + } else { + outsb(NE_BASE + NE_DATAPORT, buf, count); + } + + dma_start = jiffies; + +#ifdef NE_SANITY_CHECK + /* This was for the ALPHA version only, but enough people have + been encountering problems so it is still here. */ + + if (ei_debug > 1) { /* DMA termination address check... */ + int addr, tries = 20; + do { + int high = inb_p(nic_base + EN0_RSARHI); + int low = inb_p(nic_base + EN0_RSARLO); + addr = (high << 8) + low; + if ((start_page << 8) + count == addr) + break; + } while (--tries > 0); + if (tries <= 0) { + printk("%s: Tx packet transfer address mismatch," + "%#4.4x (expected) vs. %#4.4x (actual).\n", + dev->name, (start_page << 8) + count, addr); + if (retries++ == 0) + goto retry; + } + } +#endif + + while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0) + if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ + printk("%s: timeout waiting for Tx RDC.\n", dev->name); + ne_reset_8390(dev); + NS8390p_init(dev, 1); + break; + } + + outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ + ei_status.dmaing &= ~0x01; +} + + +#ifdef MODULE +#define MAX_NE_CARDS 4 /* Max number of NE cards per module */ +static struct net_device *dev_ne[MAX_NE_CARDS]; +static int io[MAX_NE_CARDS]; +static int irq[MAX_NE_CARDS]; +static int bad[MAX_NE_CARDS]; /* 0xbad = bad sig or no reset ack */ +MODULE_LICENSE("GPL"); + +module_param_array(io, int, NULL, 0); +module_param_array(irq, int, NULL, 0); +module_param_array(bad, int, NULL, 0); +MODULE_PARM_DESC(io, "(ignored)"); +MODULE_PARM_DESC(irq, "(ignored)"); +MODULE_PARM_DESC(bad, "(ignored)"); + +/* Module code fixed by David Weinehall */ + +int __init init_module(void) +{ + struct net_device *dev; + int this_dev, found = 0; + + for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { + dev = alloc_eip_netdev(); + if (!dev) + break; + dev->irq = irq[this_dev]; + dev->mem_end = bad[this_dev]; + dev->base_addr = io[this_dev]; + if (do_ne2_probe(dev) == 0) { + dev_ne[found++] = dev; + continue; + } + free_netdev(dev); + break; + } + if (found) + return 0; + printk(KERN_WARNING "ne2.c: No NE/2 card found\n"); + return -ENXIO; +} + +static void cleanup_card(struct net_device *dev) +{ + mca_mark_as_unused(ei_status.priv); + mca_set_adapter_procfn( ei_status.priv, NULL, NULL); + free_irq(dev->irq, dev); + release_region(dev->base_addr, NE_IO_EXTENT); +} + +void __exit cleanup_module(void) +{ + int this_dev; + + for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { + struct net_device *dev = dev_ne[this_dev]; + if (dev) { + unregister_netdev(dev); + cleanup_card(dev); + free_netdev(dev); + } + } +} +#endif /* MODULE */ diff --git a/trunk/drivers/net/ethernet/8390/smc-mca.c b/trunk/drivers/net/ethernet/8390/smc-mca.c new file mode 100644 index 000000000000..7a68590f2804 --- /dev/null +++ b/trunk/drivers/net/ethernet/8390/smc-mca.c @@ -0,0 +1,575 @@ +/* smc-mca.c: A SMC Ultra ethernet driver for linux. */ +/* + Most of this driver, except for ultramca_probe is nearly + verbatim from smc-ultra.c by Donald Becker. The rest is + written and copyright 1996 by David Weis, weisd3458@uni.edu + + This is a driver for the SMC Ultra and SMC EtherEZ ethercards. + + This driver uses the cards in the 8390-compatible, shared memory mode. + Most of the run-time complexity is handled by the generic code in + 8390.c. + + This driver enables the shared memory only when doing the actual data + transfers to avoid a bug in early version of the card that corrupted + data transferred by a AHA1542. + + This driver does not support the programmed-I/O data transfer mode of + the EtherEZ. That support (if available) is smc-ez.c. Nor does it + use the non-8390-compatible "Altego" mode. (No support currently planned.) + + Changelog: + + Paul Gortmaker : multiple card support for module users. + David Weis : Micro Channel-ized it. + Tom Sightler : Added support for IBM PS/2 Ethernet Adapter/A + Christopher Turcksin : Changed MCA-probe so that multiple adapters are + found correctly (Jul 16, 1997) + Chris Beauregard : Tried to merge the two changes above (Dec 15, 1997) + Tom Sightler : Fixed minor detection bug caused by above merge + Tom Sightler : Added support for three more Western Digital + MCA-adapters + Tom Sightler : Added support for 2.2.x mca_find_unused_adapter + Hartmut Schmidt : - Modified parameter detection to handle each + card differently depending on a switch-list + - 'card_ver' removed from the adapter list + - Some minor bug fixes +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "8390.h" + +#define DRV_NAME "smc-mca" + +static int ultramca_open(struct net_device *dev); +static void ultramca_reset_8390(struct net_device *dev); +static void ultramca_get_8390_hdr(struct net_device *dev, + struct e8390_pkt_hdr *hdr, + int ring_page); +static void ultramca_block_input(struct net_device *dev, int count, + struct sk_buff *skb, + int ring_offset); +static void ultramca_block_output(struct net_device *dev, int count, + const unsigned char *buf, + const int start_page); +static int ultramca_close_card(struct net_device *dev); + +#define START_PG 0x00 /* First page of TX buffer */ + +#define ULTRA_CMDREG 0 /* Offset to ASIC command register. */ +#define ULTRA_RESET 0x80 /* Board reset, in ULTRA_CMDREG. */ +#define ULTRA_MEMENB 0x40 /* Enable the shared memory. */ +#define ULTRA_NIC_OFFSET 16 /* NIC register offset from the base_addr. */ +#define ULTRA_IO_EXTENT 32 +#define EN0_ERWCNT 0x08 /* Early receive warning count. */ + +#define _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A 0 +#define _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A 1 +#define _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A 2 +#define _6fc1_WD_Starcard_PLUS_A_WD8003ST_A 3 +#define _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A 4 +#define _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A 5 +#define _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A 6 +#define _efe5_IBM_PS2_Adapter_A_for_Ethernet 7 + +struct smc_mca_adapters_t { + unsigned int id; + char *name; +}; + +#define MAX_ULTRAMCA_CARDS 4 /* Max number of Ultra cards per module */ + +static int ultra_io[MAX_ULTRAMCA_CARDS]; +static int ultra_irq[MAX_ULTRAMCA_CARDS]; +MODULE_LICENSE("GPL"); + +module_param_array(ultra_io, int, NULL, 0); +module_param_array(ultra_irq, int, NULL, 0); +MODULE_PARM_DESC(ultra_io, "SMC Ultra/EtherEZ MCA I/O base address(es)"); +MODULE_PARM_DESC(ultra_irq, "SMC Ultra/EtherEZ MCA IRQ number(s)"); + +static const struct { + unsigned int base_addr; +} addr_table[] = { + { 0x0800 }, + { 0x1800 }, + { 0x2800 }, + { 0x3800 }, + { 0x4800 }, + { 0x5800 }, + { 0x6800 }, + { 0x7800 }, + { 0x8800 }, + { 0x9800 }, + { 0xa800 }, + { 0xb800 }, + { 0xc800 }, + { 0xd800 }, + { 0xe800 }, + { 0xf800 } +}; + +#define MEM_MASK 64 + +static const struct { + unsigned char mem_index; + unsigned long mem_start; + unsigned char num_pages; +} mem_table[] = { + { 16, 0x0c0000, 40 }, + { 18, 0x0c4000, 40 }, + { 20, 0x0c8000, 40 }, + { 22, 0x0cc000, 40 }, + { 24, 0x0d0000, 40 }, + { 26, 0x0d4000, 40 }, + { 28, 0x0d8000, 40 }, + { 30, 0x0dc000, 40 }, + {144, 0xfc0000, 40 }, + {148, 0xfc8000, 40 }, + {154, 0xfd0000, 40 }, + {156, 0xfd8000, 40 }, + { 0, 0x0c0000, 20 }, + { 1, 0x0c2000, 20 }, + { 2, 0x0c4000, 20 }, + { 3, 0x0c6000, 20 } +}; + +#define IRQ_MASK 243 +static const struct { + unsigned char new_irq; + unsigned char old_irq; +} irq_table[] = { + { 3, 3 }, + { 4, 4 }, + { 10, 10 }, + { 14, 15 } +}; + +static short smc_mca_adapter_ids[] __initdata = { + 0x61c8, + 0x61c9, + 0x6fc0, + 0x6fc1, + 0x6fc2, + 0xefd4, + 0xefd5, + 0xefe5, + 0x0000 +}; + +static char *smc_mca_adapter_names[] __initdata = { + "SMC Ethercard PLUS Elite/A BNC/AUI (WD8013EP/A)", + "SMC Ethercard PLUS Elite/A UTP/AUI (WD8013WP/A)", + "WD Ethercard PLUS/A (WD8003E/A or WD8003ET/A)", + "WD Starcard PLUS/A (WD8003ST/A)", + "WD Ethercard PLUS 10T/A (WD8003W/A)", + "IBM PS/2 Adapter/A for Ethernet UTP/AUI (WD8013WP/A)", + "IBM PS/2 Adapter/A for Ethernet BNC/AUI (WD8013EP/A)", + "IBM PS/2 Adapter/A for Ethernet", + NULL +}; + +static int ultra_found = 0; + + +static const struct net_device_ops ultramca_netdev_ops = { + .ndo_open = ultramca_open, + .ndo_stop = ultramca_close_card, + + .ndo_start_xmit = ei_start_xmit, + .ndo_tx_timeout = ei_tx_timeout, + .ndo_get_stats = ei_get_stats, + .ndo_set_rx_mode = ei_set_multicast_list, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, + .ndo_change_mtu = eth_change_mtu, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = ei_poll, +#endif +}; + +static int __init ultramca_probe(struct device *gen_dev) +{ + unsigned short ioaddr; + struct net_device *dev; + unsigned char reg4, num_pages; + struct mca_device *mca_dev = to_mca_device(gen_dev); + char slot = mca_dev->slot; + unsigned char pos2 = 0xff, pos3 = 0xff, pos4 = 0xff, pos5 = 0xff; + int i, rc; + int adapter = mca_dev->index; + int tbase = 0; + int tirq = 0; + int base_addr = ultra_io[ultra_found]; + int irq = ultra_irq[ultra_found]; + + if (base_addr || irq) { + printk(KERN_INFO "Probing for SMC MCA adapter"); + if (base_addr) { + printk(KERN_INFO " at I/O address 0x%04x%c", + base_addr, irq ? ' ' : '\n'); + } + if (irq) { + printk(KERN_INFO "using irq %d\n", irq); + } + } + + tirq = 0; + tbase = 0; + + /* If we're trying to match a specificied irq or io address, + * we'll reject the adapter found unless it's the one we're + * looking for */ + + pos2 = mca_device_read_stored_pos(mca_dev, 2); /* io_addr */ + pos3 = mca_device_read_stored_pos(mca_dev, 3); /* shared mem */ + pos4 = mca_device_read_stored_pos(mca_dev, 4); /* ROM bios addr range */ + pos5 = mca_device_read_stored_pos(mca_dev, 5); /* irq, media and RIPL */ + + /* Test the following conditions: + * - If an irq parameter is supplied, compare it + * with the irq of the adapter we found + * - If a base_addr paramater is given, compare it + * with the base_addr of the adapter we found + * - Check that the irq and the base_addr of the + * adapter we found is not already in use by + * this driver + */ + + switch (mca_dev->index) { + case _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A: + case _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A: + case _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A: + case _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A: + { + tbase = addr_table[(pos2 & 0xf0) >> 4].base_addr; + tirq = irq_table[(pos5 & 0xc) >> 2].new_irq; + break; + } + case _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A: + case _6fc1_WD_Starcard_PLUS_A_WD8003ST_A: + case _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A: + case _efe5_IBM_PS2_Adapter_A_for_Ethernet: + { + tbase = ((pos2 & 0x0fe) * 0x10); + tirq = irq_table[(pos5 & 3)].old_irq; + break; + } + } + + if(!tirq || !tbase || + (irq && irq != tirq) || + (base_addr && tbase != base_addr)) + /* FIXME: we're trying to force the ordering of the + * devices here, there should be a way of getting this + * to happen */ + return -ENXIO; + + /* Adapter found. */ + dev = alloc_ei_netdev(); + if(!dev) + return -ENODEV; + + SET_NETDEV_DEV(dev, gen_dev); + mca_device_set_name(mca_dev, smc_mca_adapter_names[adapter]); + mca_device_set_claim(mca_dev, 1); + + printk(KERN_INFO "smc_mca: %s found in slot %d\n", + smc_mca_adapter_names[adapter], slot + 1); + + ultra_found++; + + dev->base_addr = ioaddr = mca_device_transform_ioport(mca_dev, tbase); + dev->irq = mca_device_transform_irq(mca_dev, tirq); + dev->mem_start = 0; + num_pages = 40; + + switch (adapter) { /* card-# in const array above [hs] */ + case _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A: + case _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A: + { + for (i = 0; i < 16; i++) { /* taking 16 counts + * up to 15 [hs] */ + if (mem_table[i].mem_index == (pos3 & ~MEM_MASK)) { + dev->mem_start = (unsigned long) + mca_device_transform_memory(mca_dev, (void *)mem_table[i].mem_start); + num_pages = mem_table[i].num_pages; + } + } + break; + } + case _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A: + case _6fc1_WD_Starcard_PLUS_A_WD8003ST_A: + case _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A: + case _efe5_IBM_PS2_Adapter_A_for_Ethernet: + { + dev->mem_start = (unsigned long) + mca_device_transform_memory(mca_dev, (void *)((pos3 & 0xfc) * 0x1000)); + num_pages = 0x40; + break; + } + case _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A: + case _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A: + { + /* courtesy of gamera@quartz.ocn.ne.jp, pos3 indicates + * the index of the 0x2000 step. + * beware different number of pages [hs] + */ + dev->mem_start = (unsigned long) + mca_device_transform_memory(mca_dev, (void *)(0xc0000 + (0x2000 * (pos3 & 0xf)))); + num_pages = 0x20 + (2 * (pos3 & 0x10)); + break; + } + } + + /* sanity check, shouldn't happen */ + if (dev->mem_start == 0) { + rc = -ENODEV; + goto err_unclaim; + } + + if (!request_region(ioaddr, ULTRA_IO_EXTENT, DRV_NAME)) { + rc = -ENODEV; + goto err_unclaim; + } + + reg4 = inb(ioaddr + 4) & 0x7f; + outb(reg4, ioaddr + 4); + + for (i = 0; i < 6; i++) + dev->dev_addr[i] = inb(ioaddr + 8 + i); + + printk(KERN_INFO "smc_mca[%d]: Parameters: %#3x, %pM", + slot + 1, ioaddr, dev->dev_addr); + + /* Switch from the station address to the alternate register set + * and read the useful registers there. + */ + + outb(0x80 | reg4, ioaddr + 4); + + /* Enable FINE16 mode to avoid BIOS ROM width mismatches @ reboot. + */ + + outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c); + + /* Switch back to the station address register set so that + * the MS-DOS driver can find the card after a warm boot. + */ + + outb(reg4, ioaddr + 4); + + dev_set_drvdata(gen_dev, dev); + + /* The 8390 isn't at the base address, so fake the offset + */ + + dev->base_addr = ioaddr + ULTRA_NIC_OFFSET; + + ei_status.name = "SMC Ultra MCA"; + ei_status.word16 = 1; + ei_status.tx_start_page = START_PG; + ei_status.rx_start_page = START_PG + TX_PAGES; + ei_status.stop_page = num_pages; + + ei_status.mem = ioremap(dev->mem_start, (ei_status.stop_page - START_PG) * 256); + if (!ei_status.mem) { + rc = -ENOMEM; + goto err_release_region; + } + + dev->mem_end = dev->mem_start + (ei_status.stop_page - START_PG) * 256; + + printk(", IRQ %d memory %#lx-%#lx.\n", + dev->irq, dev->mem_start, dev->mem_end - 1); + + ei_status.reset_8390 = &ultramca_reset_8390; + ei_status.block_input = &ultramca_block_input; + ei_status.block_output = &ultramca_block_output; + ei_status.get_8390_hdr = &ultramca_get_8390_hdr; + + ei_status.priv = slot; + + dev->netdev_ops = &ultramca_netdev_ops; + + NS8390_init(dev, 0); + + rc = register_netdev(dev); + if (rc) + goto err_unmap; + + return 0; + +err_unmap: + iounmap(ei_status.mem); +err_release_region: + release_region(ioaddr, ULTRA_IO_EXTENT); +err_unclaim: + mca_device_set_claim(mca_dev, 0); + free_netdev(dev); + return rc; +} + +static int ultramca_open(struct net_device *dev) +{ + int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ + int retval; + + if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) + return retval; + + outb(ULTRA_MEMENB, ioaddr); /* Enable memory */ + outb(0x80, ioaddr + 5); /* ??? */ + outb(0x01, ioaddr + 6); /* Enable interrupts and memory. */ + outb(0x04, ioaddr + 5); /* ??? */ + + /* Set the early receive warning level in window 0 high enough not + * to receive ERW interrupts. + */ + + /* outb_p(E8390_NODMA + E8390_PAGE0, dev->base_addr); + * outb(0xff, dev->base_addr + EN0_ERWCNT); + */ + + ei_open(dev); + return 0; +} + +static void ultramca_reset_8390(struct net_device *dev) +{ + int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ + + outb(ULTRA_RESET, ioaddr); + if (ei_debug > 1) + printk("resetting Ultra, t=%ld...", jiffies); + ei_status.txing = 0; + + outb(0x80, ioaddr + 5); /* ??? */ + outb(0x01, ioaddr + 6); /* Enable interrupts and memory. */ + + if (ei_debug > 1) + printk("reset done\n"); +} + +/* Grab the 8390 specific header. Similar to the block_input routine, but + * we don't need to be concerned with ring wrap as the header will be at + * the start of a page, so we optimize accordingly. + */ + +static void ultramca_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +{ + void __iomem *hdr_start = ei_status.mem + ((ring_page - START_PG) << 8); + +#ifdef notdef + /* Officially this is what we are doing, but the readl() is faster */ + memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); +#else + ((unsigned int*)hdr)[0] = readl(hdr_start); +#endif +} + +/* Block input and output are easy on shared memory ethercards, the only + * complication is when the ring buffer wraps. + */ + +static void ultramca_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) +{ + void __iomem *xfer_start = ei_status.mem + ring_offset - START_PG * 256; + + if (ring_offset + count > ei_status.stop_page * 256) { + /* We must wrap the input move. */ + int semi_count = ei_status.stop_page * 256 - ring_offset; + memcpy_fromio(skb->data, xfer_start, semi_count); + count -= semi_count; + memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count); + } else { + memcpy_fromio(skb->data, xfer_start, count); + } + +} + +static void ultramca_block_output(struct net_device *dev, int count, const unsigned char *buf, + int start_page) +{ + void __iomem *shmem = ei_status.mem + ((start_page - START_PG) << 8); + + memcpy_toio(shmem, buf, count); +} + +static int ultramca_close_card(struct net_device *dev) +{ + int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ + + netif_stop_queue(dev); + + if (ei_debug > 1) + printk("%s: Shutting down ethercard.\n", dev->name); + + outb(0x00, ioaddr + 6); /* Disable interrupts. */ + free_irq(dev->irq, dev); + + NS8390_init(dev, 0); + /* We should someday disable shared memory and change to 8-bit mode + * "just in case"... + */ + + return 0; +} + +static int ultramca_remove(struct device *gen_dev) +{ + struct mca_device *mca_dev = to_mca_device(gen_dev); + struct net_device *dev = dev_get_drvdata(gen_dev); + + if (dev) { + /* NB: ultra_close_card() does free_irq */ + int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; + + unregister_netdev(dev); + mca_device_set_claim(mca_dev, 0); + release_region(ioaddr, ULTRA_IO_EXTENT); + iounmap(ei_status.mem); + free_netdev(dev); + } + return 0; +} + + +static struct mca_driver ultra_driver = { + .id_table = smc_mca_adapter_ids, + .driver = { + .name = "smc-mca", + .bus = &mca_bus_type, + .probe = ultramca_probe, + .remove = ultramca_remove, + } +}; + +static int __init ultramca_init_module(void) +{ + if(!MCA_bus) + return -ENXIO; + + mca_register_driver(&ultra_driver); + + return ultra_found ? 0 : -ENXIO; +} + +static void __exit ultramca_cleanup_module(void) +{ + mca_unregister_driver(&ultra_driver); +} +module_init(ultramca_init_module); +module_exit(ultramca_cleanup_module); + diff --git a/trunk/drivers/net/ethernet/amd/ariadne.c b/trunk/drivers/net/ethernet/amd/ariadne.c index f2958df9a1e4..f4c228e4d76c 100644 --- a/trunk/drivers/net/ethernet/amd/ariadne.c +++ b/trunk/drivers/net/ethernet/amd/ariadne.c @@ -213,10 +213,10 @@ static int ariadne_rx(struct net_device *dev) (const void *)priv->rx_buff[entry], pkt_len); skb->protocol = eth_type_trans(skb, dev); - netdev_dbg(dev, "RX pkt type 0x%04x from %pM to %pM data %p len %u\n", + netdev_dbg(dev, "RX pkt type 0x%04x from %pM to %pM data 0x%08x len %d\n", ((u_short *)skb->data)[6], skb->data + 6, skb->data, - skb->data, skb->len); + (int)skb->data, (int)skb->len); netif_rx(skb); dev->stats.rx_packets++; @@ -566,10 +566,10 @@ static netdev_tx_t ariadne_start_xmit(struct sk_buff *skb, /* Fill in a Tx ring entry */ - netdev_dbg(dev, "TX pkt type 0x%04x from %pM to %pM data %p len %u\n", + netdev_dbg(dev, "TX pkt type 0x%04x from %pM to %pM data 0x%08x len %d\n", ((u_short *)skb->data)[6], skb->data + 6, skb->data, - skb->data, skb->len); + (int)skb->data, (int)skb->len); local_irq_save(flags); diff --git a/trunk/drivers/net/ethernet/amd/atarilance.c b/trunk/drivers/net/ethernet/amd/atarilance.c index 84219df72f51..70ed79c46245 100644 --- a/trunk/drivers/net/ethernet/amd/atarilance.c +++ b/trunk/drivers/net/ethernet/amd/atarilance.c @@ -558,18 +558,21 @@ static unsigned long __init lance_probe1( struct net_device *dev, printk( "Lance: request for irq %d failed\n", IRQ_AUTO_5 ); return 0; } - dev->irq = IRQ_AUTO_5; + dev->irq = (unsigned short)IRQ_AUTO_5; } else { - /* For VME-RieblCards, request a free VME int */ - unsigned int irq = atari_register_vme_int(); + /* For VME-RieblCards, request a free VME int; + * (This must be unsigned long, since dev->irq is short and the + * IRQ_MACHSPEC bit would be cut off...) + */ + unsigned long irq = atari_register_vme_int(); if (!irq) { printk( "Lance: request for VME interrupt failed\n" ); return 0; } if (request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO, "Riebl-VME Ethernet", dev)) { - printk( "Lance: request for irq %u failed\n", irq ); + printk( "Lance: request for irq %ld failed\n", irq ); return 0; } dev->irq = irq; diff --git a/trunk/drivers/net/ethernet/amd/depca.c b/trunk/drivers/net/ethernet/amd/depca.c index c771de71612a..86dd95766a64 100644 --- a/trunk/drivers/net/ethernet/amd/depca.c +++ b/trunk/drivers/net/ethernet/amd/depca.c @@ -155,10 +155,23 @@ 2 depca's in a PC). ************************************************************************ - Support for MCA EtherWORKS cards added 11-3-98. (MCA since deleted) + Support for MCA EtherWORKS cards added 11-3-98. Verified to work with up to 2 DE212 cards in a system (although not fully stress-tested). + Currently known bugs/limitations: + + Note: with the MCA stuff as a module, it trusts the MCA configuration, + not the command line for IRQ and memory address. You can + specify them if you want, but it will throw your values out. + You still have to pass the IO address it was configured as + though. + + ************************************************************************ + TO DO: + ------ + + Revision History ---------------- @@ -248,6 +261,10 @@ #include #include +#ifdef CONFIG_MCA +#include +#endif + #ifdef CONFIG_EISA #include #endif @@ -343,6 +360,44 @@ static struct eisa_driver depca_eisa_driver = { }; #endif +#ifdef CONFIG_MCA +/* +** Adapter ID for the MCA EtherWORKS DE210/212 adapter +*/ +#define DE210_ID 0x628d +#define DE212_ID 0x6def + +static short depca_mca_adapter_ids[] = { + DE210_ID, + DE212_ID, + 0x0000 +}; + +static char *depca_mca_adapter_name[] = { + "DEC EtherWORKS MC Adapter (DE210)", + "DEC EtherWORKS MC Adapter (DE212)", + NULL +}; + +static enum depca_type depca_mca_adapter_type[] = { + de210, + de212, + 0 +}; + +static int depca_mca_probe (struct device *); + +static struct mca_driver depca_mca_driver = { + .id_table = depca_mca_adapter_ids, + .driver = { + .name = depca_string, + .bus = &mca_bus_type, + .probe = depca_mca_probe, + .remove = __devexit_p(depca_device_remove), + }, +}; +#endif + static int depca_isa_probe (struct platform_device *); static int __devexit depca_isa_remove(struct platform_device *pdev) @@ -409,7 +464,8 @@ struct depca_private { char adapter_name[DEPCA_STRLEN]; /* /proc/ioports string */ enum depca_type adapter; /* Adapter type */ enum { - DEPCA_BUS_ISA = 1, + DEPCA_BUS_MCA = 1, + DEPCA_BUS_ISA, DEPCA_BUS_EISA, } depca_bus; /* type of bus */ struct depca_init init_block; /* Shadow Initialization block */ @@ -568,6 +624,12 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device) dev_name(device), depca_signature[lp->adapter], ioaddr); switch (lp->depca_bus) { +#ifdef CONFIG_MCA + case DEPCA_BUS_MCA: + printk(" (MCA slot %d)", to_mca_device(device)->slot + 1); + break; +#endif + #ifdef CONFIG_EISA case DEPCA_BUS_EISA: printk(" (EISA slot %d)", to_eisa_device(device)->slot); @@ -599,7 +661,10 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device) if (nicsr & BUF) { nicsr &= ~BS; /* DEPCA RAM in top 32k */ netRAM -= 32; - mem_start += 0x8000; + + /* Only EISA/ISA needs start address to be re-computed */ + if (lp->depca_bus != DEPCA_BUS_MCA) + mem_start += 0x8000; } if ((mem_len = (NUM_RX_DESC * (sizeof(struct depca_rx_desc) + RX_BUFF_SZ) + NUM_TX_DESC * (sizeof(struct depca_tx_desc) + TX_BUFF_SZ) + sizeof(struct depca_init))) @@ -1014,8 +1079,7 @@ static int depca_rx(struct net_device *dev) } else { lp->pktStats.multicast++; } - } else if (ether_addr_equal(buf, - dev->dev_addr)) { + } else if (compare_ether_addr(buf, dev->dev_addr) == 0) { lp->pktStats.unicast++; } @@ -1260,6 +1324,130 @@ static int __init depca_common_init (u_long ioaddr, struct net_device **devp) return status; } +#ifdef CONFIG_MCA +/* +** Microchannel bus I/O device probe +*/ +static int __init depca_mca_probe(struct device *device) +{ + unsigned char pos[2]; + unsigned char where; + unsigned long iobase, mem_start; + int irq, err; + struct mca_device *mdev = to_mca_device (device); + struct net_device *dev; + struct depca_private *lp; + + /* + ** Search for the adapter. If an address has been given, search + ** specifically for the card at that address. Otherwise find the + ** first card in the system. + */ + + pos[0] = mca_device_read_stored_pos(mdev, 2); + pos[1] = mca_device_read_stored_pos(mdev, 3); + + /* + ** IO of card is handled by bits 1 and 2 of pos0. + ** + ** bit2 bit1 IO + ** 0 0 0x2c00 + ** 0 1 0x2c10 + ** 1 0 0x2c20 + ** 1 1 0x2c30 + */ + where = (pos[0] & 6) >> 1; + iobase = 0x2c00 + (0x10 * where); + + /* + ** Found the adapter we were looking for. Now start setting it up. + ** + ** First work on decoding the IRQ. It's stored in the lower 4 bits + ** of pos1. Bits are as follows (from the ADF file): + ** + ** Bits + ** 3 2 1 0 IRQ + ** -------------------- + ** 0 0 1 0 5 + ** 0 0 0 1 9 + ** 0 1 0 0 10 + ** 1 0 0 0 11 + */ + where = pos[1] & 0x0f; + switch (where) { + case 1: + irq = 9; + break; + case 2: + irq = 5; + break; + case 4: + irq = 10; + break; + case 8: + irq = 11; + break; + default: + printk("%s: mca_probe IRQ error. You should never get here (%d).\n", mdev->name, where); + return -EINVAL; + } + + /* + ** Shared memory address of adapter is stored in bits 3-5 of pos0. + ** They are mapped as follows: + ** + ** Bit + ** 5 4 3 Memory Addresses + ** 0 0 0 C0000-CFFFF (64K) + ** 1 0 0 C8000-CFFFF (32K) + ** 0 0 1 D0000-DFFFF (64K) + ** 1 0 1 D8000-DFFFF (32K) + ** 0 1 0 E0000-EFFFF (64K) + ** 1 1 0 E8000-EFFFF (32K) + */ + where = (pos[0] & 0x18) >> 3; + mem_start = 0xc0000 + (where * 0x10000); + if (pos[0] & 0x20) { + mem_start += 0x8000; + } + + /* claim the slot */ + strncpy(mdev->name, depca_mca_adapter_name[mdev->index], + sizeof(mdev->name)); + mca_device_set_claim(mdev, 1); + + /* + ** Get everything allocated and initialized... (almost just + ** like the ISA and EISA probes) + */ + irq = mca_device_transform_irq(mdev, irq); + iobase = mca_device_transform_ioport(mdev, iobase); + + if ((err = depca_common_init (iobase, &dev))) + goto out_unclaim; + + dev->irq = irq; + dev->base_addr = iobase; + lp = netdev_priv(dev); + lp->depca_bus = DEPCA_BUS_MCA; + lp->adapter = depca_mca_adapter_type[mdev->index]; + lp->mem_start = mem_start; + + if ((err = depca_hw_init(dev, device))) + goto out_free; + + return 0; + + out_free: + free_netdev (dev); + release_region (iobase, DEPCA_TOTAL_SIZE); + out_unclaim: + mca_device_set_claim(mdev, 0); + + return err; +} +#endif + /* ** ISA bus I/O device probe */ @@ -1870,10 +2058,15 @@ static int __init depca_module_init (void) { int err = 0; +#ifdef CONFIG_MCA + err = mca_register_driver(&depca_mca_driver); + if (err) + goto err; +#endif #ifdef CONFIG_EISA err = eisa_driver_register(&depca_eisa_driver); if (err) - goto err_eisa; + goto err_mca; #endif err = platform_driver_register(&depca_isa_driver); if (err) @@ -1885,6 +2078,11 @@ static int __init depca_module_init (void) err_eisa: #ifdef CONFIG_EISA eisa_driver_unregister(&depca_eisa_driver); +err_mca: +#endif +#ifdef CONFIG_MCA + mca_unregister_driver(&depca_mca_driver); +err: #endif return err; } @@ -1892,6 +2090,9 @@ static int __init depca_module_init (void) static void __exit depca_module_exit (void) { int i; +#ifdef CONFIG_MCA + mca_unregister_driver (&depca_mca_driver); +#endif #ifdef CONFIG_EISA eisa_driver_unregister (&depca_eisa_driver); #endif diff --git a/trunk/drivers/net/ethernet/broadcom/tg3.c b/trunk/drivers/net/ethernet/broadcom/tg3.c index d55df3290174..39b92f5ed7dd 100644 --- a/trunk/drivers/net/ethernet/broadcom/tg3.c +++ b/trunk/drivers/net/ethernet/broadcom/tg3.c @@ -195,6 +195,15 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits) #define TG3_RX_OFFSET(tp) (NET_SKB_PAD) #endif +/* This driver uses the new build_skb() API providing a frag as skb->head + * This strategy permits better GRO aggregation, better TCP coalescing, and + * better splice() implementation (avoids a copy from head to a page), at + * minimal memory cost. + * In this 2048 bytes block, we have enough room to store the MTU=1500 frame + * and the struct skb_shared_info. + */ +#define TG3_FRAGSIZE 2048 + /* minimum number of free TX descriptors required to wake up TX process */ #define TG3_TX_WAKEUP_THRESH(tnapi) ((tnapi)->tx_pending / 4) #define TG3_TX_BD_DMA_MAX_2K 2048 @@ -5622,6 +5631,25 @@ static void tg3_tx(struct tg3_napi *tnapi) } } +static void *tg3_frag_alloc(struct tg3_rx_prodring_set *tpr) +{ + void *data; + + if (tpr->rx_page_size < TG3_FRAGSIZE) { + struct page *page = alloc_page(GFP_ATOMIC); + + if (!page) + return NULL; + atomic_add((PAGE_SIZE / TG3_FRAGSIZE) - 1, &page->_count); + tpr->rx_page_addr = page_address(page); + tpr->rx_page_size = PAGE_SIZE; + } + data = tpr->rx_page_addr; + tpr->rx_page_addr += TG3_FRAGSIZE; + tpr->rx_page_size -= TG3_FRAGSIZE; + return data; +} + static void tg3_frag_free(bool is_frag, void *data) { if (is_frag) @@ -5640,7 +5668,7 @@ static void tg3_rx_data_free(struct tg3 *tp, struct ring_info *ri, u32 map_sz) pci_unmap_single(tp->pdev, dma_unmap_addr(ri, mapping), map_sz, PCI_DMA_FROMDEVICE); - tg3_frag_free(skb_size <= PAGE_SIZE, ri->data); + tg3_frag_free(skb_size <= TG3_FRAGSIZE, ri->data); ri->data = NULL; } @@ -5693,9 +5721,9 @@ static int tg3_alloc_rx_data(struct tg3 *tp, struct tg3_rx_prodring_set *tpr, */ skb_size = SKB_DATA_ALIGN(data_size + TG3_RX_OFFSET(tp)) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); - if (skb_size <= PAGE_SIZE) { - data = netdev_alloc_frag(skb_size); - *frag_size = skb_size; + if (skb_size <= TG3_FRAGSIZE) { + data = tg3_frag_alloc(tpr); + *frag_size = TG3_FRAGSIZE; } else { data = kmalloc(skb_size, GFP_ATOMIC); *frag_size = 0; @@ -5708,7 +5736,7 @@ static int tg3_alloc_rx_data(struct tg3 *tp, struct tg3_rx_prodring_set *tpr, data_size, PCI_DMA_FROMDEVICE); if (unlikely(pci_dma_mapping_error(tp->pdev, mapping))) { - tg3_frag_free(skb_size <= PAGE_SIZE, data); + tg3_frag_free(skb_size <= TG3_FRAGSIZE, data); return -EIO; } diff --git a/trunk/drivers/net/ethernet/broadcom/tg3.h b/trunk/drivers/net/ethernet/broadcom/tg3.h index 93865f899a4f..7c855455d937 100644 --- a/trunk/drivers/net/ethernet/broadcom/tg3.h +++ b/trunk/drivers/net/ethernet/broadcom/tg3.h @@ -2815,6 +2815,8 @@ struct tg3_rx_prodring_set { struct ring_info *rx_jmb_buffers; dma_addr_t rx_std_mapping; dma_addr_t rx_jmb_mapping; + void *rx_page_addr; + unsigned int rx_page_size; }; #define TG3_IRQ_MAX_VECS_RSS 5 diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index ec2dafe8ae5b..0fe18850c838 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -51,8 +51,6 @@ #define FW_VERSION_MINOR 1 #define FW_VERSION_MICRO 0 -#define CH_WARN(adap, fmt, ...) dev_warn(adap->pdev_dev, fmt, ## __VA_ARGS__) - enum { MAX_NPORTS = 4, /* max # of ports */ SERNUM_LEN = 24, /* Serial # length */ @@ -66,15 +64,6 @@ enum { MEM_MC }; -enum { - MEMWIN0_APERTURE = 65536, - MEMWIN0_BASE = 0x30000, - MEMWIN1_APERTURE = 32768, - MEMWIN1_BASE = 0x28000, - MEMWIN2_APERTURE = 2048, - MEMWIN2_BASE = 0x1b800, -}; - enum dev_master { MASTER_CANT, MASTER_MAY, @@ -414,9 +403,6 @@ struct sge_txq { struct tx_sw_desc *sdesc; /* address of SW Tx descriptor ring */ struct sge_qstat *stat; /* queue status entry */ dma_addr_t phys_addr; /* physical address of the ring */ - spinlock_t db_lock; - int db_disabled; - unsigned short db_pidx; }; struct sge_eth_txq { /* state for an SGE Ethernet Tx queue */ @@ -489,7 +475,6 @@ struct adapter { void __iomem *regs; struct pci_dev *pdev; struct device *pdev_dev; - unsigned int mbox; unsigned int fn; unsigned int flags; @@ -519,8 +504,6 @@ struct adapter { void **tid_release_head; spinlock_t tid_release_lock; struct work_struct tid_release_task; - struct work_struct db_full_task; - struct work_struct db_drop_task; bool tid_release_task_busy; struct dentry *debugfs_root; @@ -622,7 +605,6 @@ irqreturn_t t4_sge_intr_msix(int irq, void *cookie); void t4_sge_init(struct adapter *adap); void t4_sge_start(struct adapter *adap); void t4_sge_stop(struct adapter *adap); -extern int dbfifo_int_thresh; #define for_each_port(adapter, iter) \ for (iter = 0; iter < (adapter)->params.nports; ++iter) @@ -737,9 +719,4 @@ int t4_ctrl_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int eqid); int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl); -void t4_db_full(struct adapter *adapter); -void t4_db_dropped(struct adapter *adapter); -int t4_mem_win_read_len(struct adapter *adap, u32 addr, __be32 *data, int len); -int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox, - u32 addr, u32 val); #endif /* __CXGB4_H__ */ diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index e1f96fbb48c1..b126b98065a9 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -148,6 +148,15 @@ static unsigned int pfvfres_pmask(struct adapter *adapter, } #endif +enum { + MEMWIN0_APERTURE = 65536, + MEMWIN0_BASE = 0x30000, + MEMWIN1_APERTURE = 32768, + MEMWIN1_BASE = 0x28000, + MEMWIN2_APERTURE = 2048, + MEMWIN2_BASE = 0x1b800, +}; + enum { MAX_TXQ_ENTRIES = 16384, MAX_CTRL_TXQ_ENTRIES = 1024, @@ -362,15 +371,6 @@ static int set_addr_filters(const struct net_device *dev, bool sleep) uhash | mhash, sleep); } -int dbfifo_int_thresh = 10; /* 10 == 640 entry threshold */ -module_param(dbfifo_int_thresh, int, 0644); -MODULE_PARM_DESC(dbfifo_int_thresh, "doorbell fifo interrupt threshold"); - -int dbfifo_drain_delay = 1000; /* usecs to sleep while draining the dbfifo */ -module_param(dbfifo_drain_delay, int, 0644); -MODULE_PARM_DESC(dbfifo_drain_delay, - "usecs to sleep while draining the dbfifo"); - /* * Set Rx properties of a port, such as promiscruity, address filters, and MTU. * If @mtu is -1 it is left unchanged. @@ -389,8 +389,6 @@ static int set_rxmode(struct net_device *dev, int mtu, bool sleep_ok) return ret; } -static struct workqueue_struct *workq; - /** * link_start - enable a port * @dev: the port to enable @@ -2198,7 +2196,7 @@ static void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan, adap->tid_release_head = (void **)((uintptr_t)p | chan); if (!adap->tid_release_task_busy) { adap->tid_release_task_busy = true; - queue_work(workq, &adap->tid_release_task); + schedule_work(&adap->tid_release_task); } spin_unlock_bh(&adap->tid_release_lock); } @@ -2368,16 +2366,6 @@ unsigned int cxgb4_port_chan(const struct net_device *dev) } EXPORT_SYMBOL(cxgb4_port_chan); -unsigned int cxgb4_dbfifo_count(const struct net_device *dev, int lpfifo) -{ - struct adapter *adap = netdev2adap(dev); - u32 v; - - v = t4_read_reg(adap, A_SGE_DBFIFO_STATUS); - return lpfifo ? G_LP_COUNT(v) : G_HP_COUNT(v); -} -EXPORT_SYMBOL(cxgb4_dbfifo_count); - /** * cxgb4_port_viid - get the VI id of a port * @dev: the net device for the port @@ -2425,59 +2413,6 @@ void cxgb4_iscsi_init(struct net_device *dev, unsigned int tag_mask, } EXPORT_SYMBOL(cxgb4_iscsi_init); -int cxgb4_flush_eq_cache(struct net_device *dev) -{ - struct adapter *adap = netdev2adap(dev); - int ret; - - ret = t4_fwaddrspace_write(adap, adap->mbox, - 0xe1000000 + A_SGE_CTXT_CMD, 0x20000000); - return ret; -} -EXPORT_SYMBOL(cxgb4_flush_eq_cache); - -static int read_eq_indices(struct adapter *adap, u16 qid, u16 *pidx, u16 *cidx) -{ - u32 addr = t4_read_reg(adap, A_SGE_DBQ_CTXT_BADDR) + 24 * qid + 8; - __be64 indices; - int ret; - - ret = t4_mem_win_read_len(adap, addr, (__be32 *)&indices, 8); - if (!ret) { - indices = be64_to_cpu(indices); - *cidx = (indices >> 25) & 0xffff; - *pidx = (indices >> 9) & 0xffff; - } - return ret; -} - -int cxgb4_sync_txq_pidx(struct net_device *dev, u16 qid, u16 pidx, - u16 size) -{ - struct adapter *adap = netdev2adap(dev); - u16 hw_pidx, hw_cidx; - int ret; - - ret = read_eq_indices(adap, qid, &hw_pidx, &hw_cidx); - if (ret) - goto out; - - if (pidx != hw_pidx) { - u16 delta; - - if (pidx >= hw_pidx) - delta = pidx - hw_pidx; - else - delta = size - hw_pidx + pidx; - wmb(); - t4_write_reg(adap, MYPF_REG(A_SGE_PF_KDOORBELL), - V_QID(qid) | V_PIDX(delta)); - } -out: - return ret; -} -EXPORT_SYMBOL(cxgb4_sync_txq_pidx); - static struct pci_driver cxgb4_driver; static void check_neigh_update(struct neighbour *neigh) @@ -2511,144 +2446,6 @@ static struct notifier_block cxgb4_netevent_nb = { .notifier_call = netevent_cb }; -static void drain_db_fifo(struct adapter *adap, int usecs) -{ - u32 v; - - do { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(usecs_to_jiffies(usecs)); - v = t4_read_reg(adap, A_SGE_DBFIFO_STATUS); - if (G_LP_COUNT(v) == 0 && G_HP_COUNT(v) == 0) - break; - } while (1); -} - -static void disable_txq_db(struct sge_txq *q) -{ - spin_lock_irq(&q->db_lock); - q->db_disabled = 1; - spin_unlock_irq(&q->db_lock); -} - -static void enable_txq_db(struct sge_txq *q) -{ - spin_lock_irq(&q->db_lock); - q->db_disabled = 0; - spin_unlock_irq(&q->db_lock); -} - -static void disable_dbs(struct adapter *adap) -{ - int i; - - for_each_ethrxq(&adap->sge, i) - disable_txq_db(&adap->sge.ethtxq[i].q); - for_each_ofldrxq(&adap->sge, i) - disable_txq_db(&adap->sge.ofldtxq[i].q); - for_each_port(adap, i) - disable_txq_db(&adap->sge.ctrlq[i].q); -} - -static void enable_dbs(struct adapter *adap) -{ - int i; - - for_each_ethrxq(&adap->sge, i) - enable_txq_db(&adap->sge.ethtxq[i].q); - for_each_ofldrxq(&adap->sge, i) - enable_txq_db(&adap->sge.ofldtxq[i].q); - for_each_port(adap, i) - enable_txq_db(&adap->sge.ctrlq[i].q); -} - -static void sync_txq_pidx(struct adapter *adap, struct sge_txq *q) -{ - u16 hw_pidx, hw_cidx; - int ret; - - spin_lock_bh(&q->db_lock); - ret = read_eq_indices(adap, (u16)q->cntxt_id, &hw_pidx, &hw_cidx); - if (ret) - goto out; - if (q->db_pidx != hw_pidx) { - u16 delta; - - if (q->db_pidx >= hw_pidx) - delta = q->db_pidx - hw_pidx; - else - delta = q->size - hw_pidx + q->db_pidx; - wmb(); - t4_write_reg(adap, MYPF_REG(A_SGE_PF_KDOORBELL), - V_QID(q->cntxt_id) | V_PIDX(delta)); - } -out: - q->db_disabled = 0; - spin_unlock_bh(&q->db_lock); - if (ret) - CH_WARN(adap, "DB drop recovery failed.\n"); -} -static void recover_all_queues(struct adapter *adap) -{ - int i; - - for_each_ethrxq(&adap->sge, i) - sync_txq_pidx(adap, &adap->sge.ethtxq[i].q); - for_each_ofldrxq(&adap->sge, i) - sync_txq_pidx(adap, &adap->sge.ofldtxq[i].q); - for_each_port(adap, i) - sync_txq_pidx(adap, &adap->sge.ctrlq[i].q); -} - -static void notify_rdma_uld(struct adapter *adap, enum cxgb4_control cmd) -{ - mutex_lock(&uld_mutex); - if (adap->uld_handle[CXGB4_ULD_RDMA]) - ulds[CXGB4_ULD_RDMA].control(adap->uld_handle[CXGB4_ULD_RDMA], - cmd); - mutex_unlock(&uld_mutex); -} - -static void process_db_full(struct work_struct *work) -{ - struct adapter *adap; - - adap = container_of(work, struct adapter, db_full_task); - - notify_rdma_uld(adap, CXGB4_CONTROL_DB_FULL); - drain_db_fifo(adap, dbfifo_drain_delay); - t4_set_reg_field(adap, A_SGE_INT_ENABLE3, - F_DBFIFO_HP_INT | F_DBFIFO_LP_INT, - F_DBFIFO_HP_INT | F_DBFIFO_LP_INT); - notify_rdma_uld(adap, CXGB4_CONTROL_DB_EMPTY); -} - -static void process_db_drop(struct work_struct *work) -{ - struct adapter *adap; - - adap = container_of(work, struct adapter, db_drop_task); - - t4_set_reg_field(adap, A_SGE_DOORBELL_CONTROL, F_DROPPED_DB, 0); - disable_dbs(adap); - notify_rdma_uld(adap, CXGB4_CONTROL_DB_DROP); - drain_db_fifo(adap, 1); - recover_all_queues(adap); - enable_dbs(adap); -} - -void t4_db_full(struct adapter *adap) -{ - t4_set_reg_field(adap, A_SGE_INT_ENABLE3, - F_DBFIFO_HP_INT | F_DBFIFO_LP_INT, 0); - queue_work(workq, &adap->db_full_task); -} - -void t4_db_dropped(struct adapter *adap) -{ - queue_work(workq, &adap->db_drop_task); -} - static void uld_attach(struct adapter *adap, unsigned int uld) { void *handle; @@ -2682,7 +2479,6 @@ static void uld_attach(struct adapter *adap, unsigned int uld) lli.gts_reg = adap->regs + MYPF_REG(SGE_PF_GTS); lli.db_reg = adap->regs + MYPF_REG(SGE_PF_KDOORBELL); lli.fw_vers = adap->params.fw_vers; - lli.dbfifo_int_thresh = dbfifo_int_thresh; handle = ulds[uld].add(&lli); if (IS_ERR(handle)) { @@ -2853,8 +2649,6 @@ static void cxgb_down(struct adapter *adapter) { t4_intr_disable(adapter); cancel_work_sync(&adapter->tid_release_task); - cancel_work_sync(&adapter->db_full_task); - cancel_work_sync(&adapter->db_drop_task); adapter->tid_release_task_busy = false; adapter->tid_release_head = NULL; @@ -3799,7 +3593,6 @@ static int __devinit init_one(struct pci_dev *pdev, adapter->pdev = pdev; adapter->pdev_dev = &pdev->dev; - adapter->mbox = func; adapter->fn = func; adapter->msg_enable = dflt_msg_enable; memset(adapter->chan_map, 0xff, sizeof(adapter->chan_map)); @@ -3808,8 +3601,6 @@ static int __devinit init_one(struct pci_dev *pdev, spin_lock_init(&adapter->tid_release_lock); INIT_WORK(&adapter->tid_release_task, process_tid_release_list); - INIT_WORK(&adapter->db_full_task, process_db_full); - INIT_WORK(&adapter->db_drop_task, process_db_drop); err = t4_prep_adapter(adapter); if (err) @@ -3997,10 +3788,6 @@ static int __init cxgb4_init_module(void) { int ret; - workq = create_singlethread_workqueue("cxgb4"); - if (!workq) - return -ENOMEM; - /* Debugfs support is optional, just warn if this fails */ cxgb4_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); if (!cxgb4_debugfs_root) @@ -4016,8 +3803,6 @@ static void __exit cxgb4_cleanup_module(void) { pci_unregister_driver(&cxgb4_driver); debugfs_remove(cxgb4_debugfs_root); /* NULL ok */ - flush_workqueue(workq); - destroy_workqueue(workq); } module_init(cxgb4_init_module); diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h index d79980c5fc63..b1d39b8d141a 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h +++ b/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h @@ -163,12 +163,6 @@ enum cxgb4_state { CXGB4_STATE_DETACH }; -enum cxgb4_control { - CXGB4_CONTROL_DB_FULL, - CXGB4_CONTROL_DB_EMPTY, - CXGB4_CONTROL_DB_DROP, -}; - struct pci_dev; struct l2t_data; struct net_device; @@ -218,7 +212,6 @@ struct cxgb4_lld_info { unsigned short ucq_density; /* # of user CQs/page */ void __iomem *gts_reg; /* address of GTS register */ void __iomem *db_reg; /* address of kernel doorbell */ - int dbfifo_int_thresh; /* doorbell fifo int threshold */ }; struct cxgb4_uld_info { @@ -227,13 +220,11 @@ struct cxgb4_uld_info { int (*rx_handler)(void *handle, const __be64 *rsp, const struct pkt_gl *gl); int (*state_change)(void *handle, enum cxgb4_state new_state); - int (*control)(void *handle, enum cxgb4_control control, ...); }; int cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p); int cxgb4_unregister_uld(enum cxgb4_uld type); int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb); -unsigned int cxgb4_dbfifo_count(const struct net_device *dev, int lpfifo); unsigned int cxgb4_port_chan(const struct net_device *dev); unsigned int cxgb4_port_viid(const struct net_device *dev); unsigned int cxgb4_port_idx(const struct net_device *dev); @@ -245,6 +236,4 @@ void cxgb4_iscsi_init(struct net_device *dev, unsigned int tag_mask, const unsigned int *pgsz_order); struct sk_buff *cxgb4_pktgl_to_skb(const struct pkt_gl *gl, unsigned int skb_len, unsigned int pull_len); -int cxgb4_sync_txq_pidx(struct net_device *dev, u16 qid, u16 pidx, u16 size); -int cxgb4_flush_eq_cache(struct net_device *dev); #endif /* !__CXGB4_OFLD_H */ diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb4/sge.c b/trunk/drivers/net/ethernet/chelsio/cxgb4/sge.c index e111d974afd8..2dae7959f000 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/trunk/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -767,13 +767,8 @@ static void write_sgl(const struct sk_buff *skb, struct sge_txq *q, static inline void ring_tx_db(struct adapter *adap, struct sge_txq *q, int n) { wmb(); /* write descriptors before telling HW */ - spin_lock(&q->db_lock); - if (!q->db_disabled) { - t4_write_reg(adap, MYPF_REG(A_SGE_PF_KDOORBELL), - V_QID(q->cntxt_id) | V_PIDX(n)); - } - q->db_pidx = q->pidx; - spin_unlock(&q->db_lock); + t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL), + QID(q->cntxt_id) | PIDX(n)); } /** @@ -2086,7 +2081,6 @@ static void init_txq(struct adapter *adap, struct sge_txq *q, unsigned int id) q->stops = q->restarts = 0; q->stat = (void *)&q->desc[q->size]; q->cntxt_id = id; - spin_lock_init(&q->db_lock); adap->sge.egr_map[id - adap->sge.egr_start] = q; } @@ -2421,18 +2415,6 @@ void t4_sge_init(struct adapter *adap) RXPKTCPLMODE | (STAT_LEN == 128 ? EGRSTATUSPAGESIZE : 0)); - /* - * Set up to drop DOORBELL writes when the DOORBELL FIFO overflows - * and generate an interrupt when this occurs so we can recover. - */ - t4_set_reg_field(adap, A_SGE_DBFIFO_STATUS, - V_HP_INT_THRESH(M_HP_INT_THRESH) | - V_LP_INT_THRESH(M_LP_INT_THRESH), - V_HP_INT_THRESH(dbfifo_int_thresh) | - V_LP_INT_THRESH(dbfifo_int_thresh)); - t4_set_reg_field(adap, A_SGE_DOORBELL_CONTROL, F_ENABLE_DROP, - F_ENABLE_DROP); - for (i = v = 0; i < 32; i += 4) v |= (PAGE_SHIFT - 10) << i; t4_write_reg(adap, SGE_HOST_PAGE_SIZE, v); diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 32e1dd566a14..d1ec111aebd8 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -868,14 +868,11 @@ int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port) return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); } -typedef void (*int_handler_t)(struct adapter *adap); - struct intr_info { unsigned int mask; /* bits to check in interrupt status */ const char *msg; /* message to print or NULL */ short stat_idx; /* stat counter to increment or -1 */ unsigned short fatal; /* whether the condition reported is fatal */ - int_handler_t int_handler; /* platform-specific int handler */ }; /** @@ -908,8 +905,6 @@ static int t4_handle_intr_status(struct adapter *adapter, unsigned int reg, } else if (acts->msg && printk_ratelimit()) dev_warn(adapter->pdev_dev, "%s (0x%x)\n", acts->msg, status & acts->mask); - if (acts->int_handler) - acts->int_handler(adapter); mask |= acts->mask; } status &= mask; @@ -1018,9 +1013,7 @@ static void sge_intr_handler(struct adapter *adapter) { ERR_INVALID_CIDX_INC, "SGE GTS CIDX increment too large", -1, 0 }, { ERR_CPL_OPCODE_0, "SGE received 0-length CPL", -1, 0 }, - { F_DBFIFO_LP_INT, NULL, -1, 0, t4_db_full }, - { F_DBFIFO_HP_INT, NULL, -1, 0, t4_db_full }, - { F_ERR_DROPPED_DB, NULL, -1, 0, t4_db_dropped }, + { ERR_DROPPED_DB, "SGE doorbell dropped", -1, 0 }, { ERR_DATA_CPL_ON_HIGH_QID1 | ERR_DATA_CPL_ON_HIGH_QID0, "SGE IQID > 1023 received CPL for FL", -1, 0 }, { ERR_BAD_DB_PIDX3, "SGE DBP 3 pidx increment too large", -1, @@ -1041,10 +1034,10 @@ static void sge_intr_handler(struct adapter *adapter) }; v = (u64)t4_read_reg(adapter, SGE_INT_CAUSE1) | - ((u64)t4_read_reg(adapter, SGE_INT_CAUSE2) << 32); + ((u64)t4_read_reg(adapter, SGE_INT_CAUSE2) << 32); if (v) { dev_alert(adapter->pdev_dev, "SGE parity error (%#llx)\n", - (unsigned long long)v); + (unsigned long long)v); t4_write_reg(adapter, SGE_INT_CAUSE1, v); t4_write_reg(adapter, SGE_INT_CAUSE2, v >> 32); } @@ -1520,7 +1513,6 @@ void t4_intr_enable(struct adapter *adapter) ERR_BAD_DB_PIDX2 | ERR_BAD_DB_PIDX1 | ERR_BAD_DB_PIDX0 | ERR_ING_CTXT_PRIO | ERR_EGR_CTXT_PRIO | INGRESS_SIZE_ERR | - F_DBFIFO_HP_INT | F_DBFIFO_LP_INT | EGRESS_SIZE_ERR); t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE), PF_INTR_MASK); t4_set_reg_field(adapter, PL_INT_MAP0, 0, 1 << pf); @@ -1994,54 +1986,6 @@ int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map, (var).retval_len16 = htonl(FW_LEN16(var)); \ } while (0) -int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox, - u32 addr, u32 val) -{ - struct fw_ldst_cmd c; - - memset(&c, 0, sizeof(c)); - c.op_to_addrspace = htonl(V_FW_CMD_OP(FW_LDST_CMD) | F_FW_CMD_REQUEST | - F_FW_CMD_WRITE | - V_FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_FIRMWARE)); - c.cycles_to_len16 = htonl(FW_LEN16(c)); - c.u.addrval.addr = htonl(addr); - c.u.addrval.val = htonl(val); - - return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); -} - -/* - * t4_mem_win_read_len - read memory through PCIE memory window - * @adap: the adapter - * @addr: address of first byte requested aligned on 32b. - * @data: len bytes to hold the data read - * @len: amount of data to read from window. Must be <= - * MEMWIN0_APERATURE after adjusting for 16B alignment - * requirements of the the memory window. - * - * Read len bytes of data from MC starting at @addr. - */ -int t4_mem_win_read_len(struct adapter *adap, u32 addr, __be32 *data, int len) -{ - int i; - int off; - - /* - * Align on a 16B boundary. - */ - off = addr & 15; - if ((addr & 3) || (len + off) > MEMWIN0_APERTURE) - return -EINVAL; - - t4_write_reg(adap, A_PCIE_MEM_ACCESS_OFFSET, addr & ~15); - t4_read_reg(adap, A_PCIE_MEM_ACCESS_OFFSET); - - for (i = 0; i < len; i += 4) - *data++ = t4_read_reg(adap, (MEMWIN0_BASE + off + i)); - - return 0; -} - /** * t4_mdio_rd - read a PHY register through MDIO * @adap: the adapter diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h index 111fc323f155..0adc5bcec7c4 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +++ b/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h @@ -190,59 +190,6 @@ #define SGE_DEBUG_DATA_LOW 0x10d4 #define SGE_INGRESS_QUEUES_PER_PAGE_PF 0x10f4 -#define S_LP_INT_THRESH 12 -#define V_LP_INT_THRESH(x) ((x) << S_LP_INT_THRESH) -#define S_HP_INT_THRESH 28 -#define V_HP_INT_THRESH(x) ((x) << S_HP_INT_THRESH) -#define A_SGE_DBFIFO_STATUS 0x10a4 - -#define S_ENABLE_DROP 13 -#define V_ENABLE_DROP(x) ((x) << S_ENABLE_DROP) -#define F_ENABLE_DROP V_ENABLE_DROP(1U) -#define A_SGE_DOORBELL_CONTROL 0x10a8 - -#define A_SGE_CTXT_CMD 0x11fc -#define A_SGE_DBQ_CTXT_BADDR 0x1084 - -#define A_SGE_PF_KDOORBELL 0x0 - -#define S_QID 15 -#define V_QID(x) ((x) << S_QID) - -#define S_PIDX 0 -#define V_PIDX(x) ((x) << S_PIDX) - -#define M_LP_COUNT 0x7ffU -#define S_LP_COUNT 0 -#define G_LP_COUNT(x) (((x) >> S_LP_COUNT) & M_LP_COUNT) - -#define M_HP_COUNT 0x7ffU -#define S_HP_COUNT 16 -#define G_HP_COUNT(x) (((x) >> S_HP_COUNT) & M_HP_COUNT) - -#define A_SGE_INT_ENABLE3 0x1040 - -#define S_DBFIFO_HP_INT 8 -#define V_DBFIFO_HP_INT(x) ((x) << S_DBFIFO_HP_INT) -#define F_DBFIFO_HP_INT V_DBFIFO_HP_INT(1U) - -#define S_DBFIFO_LP_INT 7 -#define V_DBFIFO_LP_INT(x) ((x) << S_DBFIFO_LP_INT) -#define F_DBFIFO_LP_INT V_DBFIFO_LP_INT(1U) - -#define S_DROPPED_DB 0 -#define V_DROPPED_DB(x) ((x) << S_DROPPED_DB) -#define F_DROPPED_DB V_DROPPED_DB(1U) - -#define S_ERR_DROPPED_DB 18 -#define V_ERR_DROPPED_DB(x) ((x) << S_ERR_DROPPED_DB) -#define F_ERR_DROPPED_DB V_ERR_DROPPED_DB(1U) - -#define A_PCIE_MEM_ACCESS_OFFSET 0x306c - -#define M_HP_INT_THRESH 0xfU -#define M_LP_INT_THRESH 0xfU - #define PCIE_PF_CLI 0x44 #define PCIE_INT_CAUSE 0x3004 #define UNXSPLCPLERR 0x20000000U diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/trunk/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index ad53f796b574..edcfd7ec7802 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +++ b/trunk/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h @@ -1620,19 +1620,4 @@ struct fw_hdr { #define FW_HDR_FW_VER_MINOR_GET(x) (((x) >> 16) & 0xff) #define FW_HDR_FW_VER_MICRO_GET(x) (((x) >> 8) & 0xff) #define FW_HDR_FW_VER_BUILD_GET(x) (((x) >> 0) & 0xff) - -#define S_FW_CMD_OP 24 -#define V_FW_CMD_OP(x) ((x) << S_FW_CMD_OP) - -#define S_FW_CMD_REQUEST 23 -#define V_FW_CMD_REQUEST(x) ((x) << S_FW_CMD_REQUEST) -#define F_FW_CMD_REQUEST V_FW_CMD_REQUEST(1U) - -#define S_FW_CMD_WRITE 21 -#define V_FW_CMD_WRITE(x) ((x) << S_FW_CMD_WRITE) -#define F_FW_CMD_WRITE V_FW_CMD_WRITE(1U) - -#define S_FW_LDST_CMD_ADDRSPACE 0 -#define V_FW_LDST_CMD_ADDRSPACE(x) ((x) << S_FW_LDST_CMD_ADDRSPACE) - #endif /* _T4FW_INTERFACE_H_ */ diff --git a/trunk/drivers/net/ethernet/cirrus/cs89x0.c b/trunk/drivers/net/ethernet/cirrus/cs89x0.c index 845b2020f291..b9406cbfc180 100644 --- a/trunk/drivers/net/ethernet/cirrus/cs89x0.c +++ b/trunk/drivers/net/ethernet/cirrus/cs89x0.c @@ -1,27 +1,105 @@ /* cs89x0.c: A Crystal Semiconductor (Now Cirrus Logic) CS89[02]0 - * driver for linux. - * Written 1996 by Russell Nelson, with reference to skeleton.c - * written 1993-1994 by Donald Becker. - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * The author may be reached at nelson@crynwr.com, Crynwr - * Software, 521 Pleasant Valley Rd., Potsdam, NY 13676 - * - * Other contributors: - * Mike Cruse : mcruse@cti-ltd.com - * Russ Nelson - * Melody Lee : ethernet@crystal.cirrus.com - * Alan Cox - * Andrew Morton - * Oskar Schirmer : oskar@scara.com - * Deepak Saxena : dsaxena@plexity.net - * Dmitry Pervushin : dpervushin@ru.mvista.com - * Deepak Saxena : dsaxena@plexity.net - * Domenico Andreoli : cavokz@gmail.com + * driver for linux. */ +/* + Written 1996 by Russell Nelson, with reference to skeleton.c + written 1993-1994 by Donald Becker. + + This software may be used and distributed according to the terms + of the GNU General Public License, incorporated herein by reference. + + The author may be reached at nelson@crynwr.com, Crynwr + Software, 521 Pleasant Valley Rd., Potsdam, NY 13676 + + Changelog: + + Mike Cruse : mcruse@cti-ltd.com + : Changes for Linux 2.0 compatibility. + : Added dev_id parameter in net_interrupt(), + : request_irq() and free_irq(). Just NULL for now. + + Mike Cruse : Added MOD_INC_USE_COUNT and MOD_DEC_USE_COUNT macros + : in net_open() and net_close() so kerneld would know + : that the module is in use and wouldn't eject the + : driver prematurely. + + Mike Cruse : Rewrote init_module() and cleanup_module using 8390.c + : as an example. Disabled autoprobing in init_module(), + : not a good thing to do to other devices while Linux + : is running from all accounts. + + Russ Nelson : Jul 13 1998. Added RxOnly DMA support. + + Melody Lee : Aug 10 1999. Changes for Linux 2.2.5 compatibility. + : email: ethernet@crystal.cirrus.com + + Alan Cox : Removed 1.2 support, added 2.1 extra counters. + + Andrew Morton : Kernel 2.3.48 + : Handle kmalloc() failures + : Other resource allocation fixes + : Add SMP locks + : Integrate Russ Nelson's ALLOW_DMA functionality back in. + : If ALLOW_DMA is true, make DMA runtime selectable + : Folded in changes from Cirrus (Melody Lee + : ) + : Don't call netif_wake_queue() in net_send_packet() + : Fixed an out-of-mem bug in dma_rx() + : Updated Documentation/networking/cs89x0.txt + + Andrew Morton : Kernel 2.3.99-pre1 + : Use skb_reserve to longword align IP header (two places) + : Remove a delay loop from dma_rx() + : Replace '100' with HZ + : Clean up a couple of skb API abuses + : Added 'cs89x0_dma=N' kernel boot option + : Correctly initialise lp->lock in non-module compile + + Andrew Morton : Kernel 2.3.99-pre4-1 + : MOD_INC/DEC race fix (see + : http://www.uwsg.indiana.edu/hypermail/linux/kernel/0003.3/1532.html) + + Andrew Morton : Kernel 2.4.0-test7-pre2 + : Enhanced EEPROM support to cover more devices, + : abstracted IRQ mapping to support CONFIG_ARCH_CLPS7500 arch + : (Jason Gunthorpe ) + + Andrew Morton : Kernel 2.4.0-test11-pre4 + : Use dev->name in request_*() (Andrey Panin) + : Fix an error-path memleak in init_module() + : Preserve return value from request_irq() + : Fix type of `media' module parm (Keith Owens) + : Use SET_MODULE_OWNER() + : Tidied up strange request_irq() abuse in net_open(). + + Andrew Morton : Kernel 2.4.3-pre1 + : Request correct number of pages for DMA (Hugh Dickens) + : Select PP_ChipID _after_ unregister_netdev in cleanup_module() + : because unregister_netdev() calls get_stats. + : Make `version[]' __initdata + : Uninlined the read/write reg/word functions. + + Oskar Schirmer : oskar@scara.com + : HiCO.SH4 (superh) support added (irq#1, cs89x0_media=) + + Deepak Saxena : dsaxena@plexity.net + : Intel IXDP2x01 (XScale ixp2x00 NPU) platform support + + Dmitry Pervushin : dpervushin@ru.mvista.com + : PNX010X platform support + + Deepak Saxena : dsaxena@plexity.net + : Intel IXDP2351 platform support + + Dmitry Pervushin : dpervushin@ru.mvista.com + : PNX010X platform support + + Domenico Andreoli : cavokz@gmail.com + : QQ2440 platform support + +*/ + /* * Set this to zero to disable DMA code @@ -41,12 +119,14 @@ */ #define DEBUGGING 1 -/* Sources: - * Crynwr packet driver epktisa. - * Crystal Semiconductor data sheets. - */ +/* + Sources: + + Crynwr packet driver epktisa. -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + Crystal Semiconductor data sheets. + +*/ #include #include @@ -67,8 +147,8 @@ #include #include #include -#include +#include #include #include #if ALLOW_DMA @@ -77,55 +157,35 @@ #include "cs89x0.h" -#define cs89_dbg(val, level, fmt, ...) \ -do { \ - if (val <= net_debug) \ - pr_##level(fmt, ##__VA_ARGS__); \ -} while (0) - static char version[] __initdata = - "v2.4.3-pre1 Russell Nelson , Andrew Morton"; +"cs89x0.c: v2.4.3-pre1 Russell Nelson , Andrew Morton\n"; #define DRV_NAME "cs89x0" /* First, a few definitions that the brave might change. - * A zero-terminated list of I/O addresses to be probed. Some special flags.. - * Addr & 1 = Read back the address port, look for signature and reset - * the page window before probing - * Addr & 3 = Reset the page window and probe - * The CLPS eval board has the Cirrus chip at 0x80090300, in ARM IO space, - * but it is possible that a Cirrus board could be plugged into the ISA - * slots. - */ + A zero-terminated list of I/O addresses to be probed. Some special flags.. + Addr & 1 = Read back the address port, look for signature and reset + the page window before probing + Addr & 3 = Reset the page window and probe + The CLPS eval board has the Cirrus chip at 0x80090300, in ARM IO space, + but it is possible that a Cirrus board could be plugged into the ISA + slots. */ /* The cs8900 has 4 IRQ pins, software selectable. cs8900_irq_map maps - * them to system IRQ numbers. This mapping is card specific and is set to - * the configuration of the Cirrus Eval board for this chip. - */ + them to system IRQ numbers. This mapping is card specific and is set to + the configuration of the Cirrus Eval board for this chip. */ #if defined(CONFIG_MACH_IXDP2351) #define CS89x0_NONISA_IRQ -static unsigned int netcard_portlist[] __used __initdata = { - IXDP2351_VIRT_CS8900_BASE, 0 -}; -static unsigned int cs8900_irq_map[] = { - IRQ_IXDP2351_CS8900, 0, 0, 0 -}; +static unsigned int netcard_portlist[] __used __initdata = {IXDP2351_VIRT_CS8900_BASE, 0}; +static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0}; #elif defined(CONFIG_ARCH_IXDP2X01) #define CS89x0_NONISA_IRQ -static unsigned int netcard_portlist[] __used __initdata = { - IXDP2X01_CS8900_VIRT_BASE, 0 -}; -static unsigned int cs8900_irq_map[] = { - IRQ_IXDP2X01_CS8900, 0, 0, 0 -}; +static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0}; +static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0}; #else #ifndef CONFIG_CS89x0_PLATFORM -static unsigned int netcard_portlist[] __used __initdata = { - 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, - 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0 -}; -static unsigned int cs8900_irq_map[] = { - 10, 11, 12, 5 -}; +static unsigned int netcard_portlist[] __used __initdata = + { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0}; +static unsigned int cs8900_irq_map[] = {10,11,12,5}; #endif #endif @@ -162,8 +222,6 @@ struct net_local { int send_underrun; /* keep track of how many underruns in a row we get */ int force; /* force various values; see FORCE* above. */ spinlock_t lock; - void __iomem *virt_addr;/* CS89x0 virtual address. */ - unsigned long size; /* Length of CS89x0 memory region. */ #if ALLOW_DMA int use_dma; /* Flag: we're using dma */ int dma; /* DMA channel */ @@ -172,42 +230,119 @@ struct net_local { unsigned char *end_dma_buff; /* points to the end of the buffer */ unsigned char *rx_dma_ptr; /* points to the next packet */ #endif +#ifdef CONFIG_CS89x0_PLATFORM + void __iomem *virt_addr;/* Virtual address for accessing the CS89x0. */ + unsigned long phys_addr;/* Physical address for accessing the CS89x0. */ + unsigned long size; /* Length of CS89x0 memory region. */ +#endif }; +/* Index to functions, as function prototypes. */ + +static int cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular); +static int net_open(struct net_device *dev); +static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev); +static irqreturn_t net_interrupt(int irq, void *dev_id); +static void set_multicast_list(struct net_device *dev); +static void net_timeout(struct net_device *dev); +static void net_rx(struct net_device *dev); +static int net_close(struct net_device *dev); +static struct net_device_stats *net_get_stats(struct net_device *dev); +static void reset_chip(struct net_device *dev); +static int get_eeprom_data(struct net_device *dev, int off, int len, int *buffer); +static int get_eeprom_cksum(int off, int len, int *buffer); +static int set_mac_address(struct net_device *dev, void *addr); +static void count_rx_errors(int status, struct net_device *dev); +#ifdef CONFIG_NET_POLL_CONTROLLER +static void net_poll_controller(struct net_device *dev); +#endif +#if ALLOW_DMA +static void get_dma_channel(struct net_device *dev); +static void release_dma_buff(struct net_local *lp); +#endif + /* Example routines you must write ;->. */ #define tx_done(dev) 1 /* * Permit 'cs89x0_dma=N' in the kernel boot environment */ -#if !defined(MODULE) -#if ALLOW_DMA +#if !defined(MODULE) && (ALLOW_DMA != 0) static int g_cs89x0_dma; static int __init dma_fn(char *str) { - g_cs89x0_dma = simple_strtol(str, NULL, 0); + g_cs89x0_dma = simple_strtol(str,NULL,0); return 1; } __setup("cs89x0_dma=", dma_fn); -#endif /* ALLOW_DMA */ +#endif /* !defined(MODULE) && (ALLOW_DMA != 0) */ +#ifndef MODULE static int g_cs89x0_media__force; static int __init media_fn(char *str) { - if (!strcmp(str, "rj45")) - g_cs89x0_media__force = FORCE_RJ45; - else if (!strcmp(str, "aui")) - g_cs89x0_media__force = FORCE_AUI; - else if (!strcmp(str, "bnc")) - g_cs89x0_media__force = FORCE_BNC; - + if (!strcmp(str, "rj45")) g_cs89x0_media__force = FORCE_RJ45; + else if (!strcmp(str, "aui")) g_cs89x0_media__force = FORCE_AUI; + else if (!strcmp(str, "bnc")) g_cs89x0_media__force = FORCE_BNC; return 1; } __setup("cs89x0_media=", media_fn); + + +#ifndef CONFIG_CS89x0_PLATFORM +/* Check for a network adaptor of this type, and return '0' iff one exists. + If dev->base_addr == 0, probe all likely locations. + If dev->base_addr == 1, always return failure. + If dev->base_addr == 2, allocate space for the device and return success + (detachable devices only). + Return 0 on success. + */ + +struct net_device * __init cs89x0_probe(int unit) +{ + struct net_device *dev = alloc_etherdev(sizeof(struct net_local)); + unsigned *port; + int err = 0; + int irq; + int io; + + if (!dev) + return ERR_PTR(-ENODEV); + + sprintf(dev->name, "eth%d", unit); + netdev_boot_setup_check(dev); + io = dev->base_addr; + irq = dev->irq; + + if (net_debug) + printk("cs89x0:cs89x0_probe(0x%x)\n", io); + + if (io > 0x1ff) { /* Check a single specified location. */ + err = cs89x0_probe1(dev, io, 0); + } else if (io != 0) { /* Don't probe at all. */ + err = -ENXIO; + } else { + for (port = netcard_portlist; *port; port++) { + if (cs89x0_probe1(dev, *port, 0) == 0) + break; + dev->irq = irq; + } + if (!*port) + err = -ENODEV; + } + if (err) + goto out; + return dev; +out: + free_netdev(dev); + printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected. Be sure to disable PnP with SETUP\n"); + return ERR_PTR(err); +} +#endif #endif #if defined(CONFIG_MACH_IXDP2351) @@ -234,22 +369,36 @@ writeword(unsigned long base_addr, int portno, u16 value) { __raw_writel(value, base_addr + (portno << 1)); } +#else +static u16 +readword(unsigned long base_addr, int portno) +{ + return inw(base_addr + portno); +} + +static void +writeword(unsigned long base_addr, int portno, u16 value) +{ + outw(value, base_addr + portno); +} #endif -static void readwords(struct net_local *lp, int portno, void *buf, int length) +static void +readwords(unsigned long base_addr, int portno, void *buf, int length) { u8 *buf8 = (u8 *)buf; do { u16 tmp16; - tmp16 = ioread16(lp->virt_addr + portno); + tmp16 = readword(base_addr, portno); *buf8++ = (u8)tmp16; *buf8++ = (u8)(tmp16 >> 8); } while (--length); } -static void writewords(struct net_local *lp, int portno, void *buf, int length) +static void +writewords(unsigned long base_addr, int portno, void *buf, int length) { u8 *buf8 = (u8 *)buf; @@ -258,37 +407,32 @@ static void writewords(struct net_local *lp, int portno, void *buf, int length) tmp16 = *buf8++; tmp16 |= (*buf8++) << 8; - iowrite16(tmp16, lp->virt_addr + portno); + writeword(base_addr, portno, tmp16); } while (--length); } static u16 readreg(struct net_device *dev, u16 regno) { - struct net_local *lp = netdev_priv(dev); - - iowrite16(regno, lp->virt_addr + ADD_PORT); - return ioread16(lp->virt_addr + DATA_PORT); + writeword(dev->base_addr, ADD_PORT, regno); + return readword(dev->base_addr, DATA_PORT); } static void writereg(struct net_device *dev, u16 regno, u16 value) { - struct net_local *lp = netdev_priv(dev); - - iowrite16(regno, lp->virt_addr + ADD_PORT); - iowrite16(value, lp->virt_addr + DATA_PORT); + writeword(dev->base_addr, ADD_PORT, regno); + writeword(dev->base_addr, DATA_PORT, value); } static int __init wait_eeprom_ready(struct net_device *dev) { int timeout = jiffies; - /* check to see if the EEPROM is ready, - * a timeout is used just in case EEPROM is ready when - * SI_BUSY in the PP_SelfST is clear - */ - while (readreg(dev, PP_SelfST) & SI_BUSY) + /* check to see if the EEPROM is ready, a timeout is used - + just in case EEPROM is ready when SI_BUSY in the + PP_SelfST is clear */ + while(readreg(dev, PP_SelfST) & SI_BUSY) if (jiffies - timeout >= 40) return -1; return 0; @@ -299,19 +443,17 @@ get_eeprom_data(struct net_device *dev, int off, int len, int *buffer) { int i; - cs89_dbg(3, info, "EEPROM data from %x for %x:", off, len); + if (net_debug > 3) printk("EEPROM data from %x for %x:\n",off,len); for (i = 0; i < len; i++) { - if (wait_eeprom_ready(dev) < 0) - return -1; + if (wait_eeprom_ready(dev) < 0) return -1; /* Now send the EEPROM read command and EEPROM location to read */ writereg(dev, PP_EECMD, (off + i) | EEPROM_READ_CMD); - if (wait_eeprom_ready(dev) < 0) - return -1; + if (wait_eeprom_ready(dev) < 0) return -1; buffer[i] = readreg(dev, PP_EEData); - cs89_dbg(3, cont, " %04x", buffer[i]); + if (net_debug > 3) printk("%04x ", buffer[i]); } - cs89_dbg(3, cont, "\n"); - return 0; + if (net_debug > 3) printk("\n"); + return 0; } static int __init @@ -328,149 +470,442 @@ get_eeprom_cksum(int off, int len, int *buffer) return -1; } -static void -write_irq(struct net_device *dev, int chip_type, int irq) -{ - int i; - - if (chip_type == CS8900) { -#ifndef CONFIG_CS89x0_PLATFORM - /* Search the mapping table for the corresponding IRQ pin. */ - for (i = 0; i != ARRAY_SIZE(cs8900_irq_map); i++) - if (cs8900_irq_map[i] == irq) - break; - /* Not found */ - if (i == ARRAY_SIZE(cs8900_irq_map)) - i = 3; -#else - /* INTRQ0 pin is used for interrupt generation. */ - i = 0; -#endif - writereg(dev, PP_CS8900_ISAINT, i); - } else { - writereg(dev, PP_CS8920_ISAINT, irq); - } -} - -static void -count_rx_errors(int status, struct net_device *dev) +#ifdef CONFIG_NET_POLL_CONTROLLER +/* + * Polling receive - used by netconsole and other diagnostic tools + * to allow network i/o with interrupts disabled. + */ +static void net_poll_controller(struct net_device *dev) { - dev->stats.rx_errors++; - if (status & RX_RUNT) - dev->stats.rx_length_errors++; - if (status & RX_EXTRA_DATA) - dev->stats.rx_length_errors++; - if ((status & RX_CRC_ERROR) && !(status & (RX_EXTRA_DATA | RX_RUNT))) - /* per str 172 */ - dev->stats.rx_crc_errors++; - if (status & RX_DRIBBLE) - dev->stats.rx_frame_errors++; + disable_irq(dev->irq); + net_interrupt(dev->irq, dev); + enable_irq(dev->irq); } +#endif -/********************************* - * This page contains DMA routines - *********************************/ - -#if ALLOW_DMA +static const struct net_device_ops net_ops = { + .ndo_open = net_open, + .ndo_stop = net_close, + .ndo_tx_timeout = net_timeout, + .ndo_start_xmit = net_send_packet, + .ndo_get_stats = net_get_stats, + .ndo_set_rx_mode = set_multicast_list, + .ndo_set_mac_address = set_mac_address, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = net_poll_controller, +#endif + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, +}; -#define dma_page_eq(ptr1, ptr2) ((long)(ptr1) >> 17 == (long)(ptr2) >> 17) +/* This is the real probe routine. Linux has a history of friendly device + probes on the ISA bus. A good device probes avoids doing writes, and + verifies that the correct device exists and functions. + Return 0 on success. + */ -static void -get_dma_channel(struct net_device *dev) +static int __init +cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular) { struct net_local *lp = netdev_priv(dev); + static unsigned version_printed; + int i; + int tmp; + unsigned rev_type = 0; + int eeprom_buff[CHKSUM_LEN]; + int retval; - if (lp->dma) { - dev->dma = lp->dma; - lp->isa_config |= ISA_RxDMA; - } else { - if ((lp->isa_config & ANY_ISA_DMA) == 0) - return; - dev->dma = lp->isa_config & DMA_NO_MASK; - if (lp->chip_type == CS8900) - dev->dma += 5; - if (dev->dma < 5 || dev->dma > 7) { - lp->isa_config &= ~ANY_ISA_DMA; - return; + /* Initialize the device structure. */ + if (!modular) { + memset(lp, 0, sizeof(*lp)); + spin_lock_init(&lp->lock); +#ifndef MODULE +#if ALLOW_DMA + if (g_cs89x0_dma) { + lp->use_dma = 1; + lp->dma = g_cs89x0_dma; + lp->dmasize = 16; /* Could make this an option... */ } - } -} +#endif + lp->force = g_cs89x0_media__force; +#endif -static void -write_dma(struct net_device *dev, int chip_type, int dma) -{ - struct net_local *lp = netdev_priv(dev); - if ((lp->isa_config & ANY_ISA_DMA) == 0) - return; - if (chip_type == CS8900) - writereg(dev, PP_CS8900_ISADMA, dma - 5); - else - writereg(dev, PP_CS8920_ISADMA, dma); -} + } -static void -set_dma_cfg(struct net_device *dev) -{ - struct net_local *lp = netdev_priv(dev); + /* Grab the region so we can find another board if autoIRQ fails. */ + /* WTF is going on here? */ + if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, DRV_NAME)) { + printk(KERN_ERR "%s: request_region(0x%lx, 0x%x) failed\n", + DRV_NAME, ioaddr, NETCARD_IO_EXTENT); + retval = -EBUSY; + goto out1; + } - if (lp->use_dma) { - if ((lp->isa_config & ANY_ISA_DMA) == 0) { - cs89_dbg(3, err, "set_dma_cfg(): no DMA\n"); - return; - } - if (lp->isa_config & ISA_RxDMA) { - lp->curr_rx_cfg |= RX_DMA_ONLY; - cs89_dbg(3, info, "set_dma_cfg(): RX_DMA_ONLY\n"); - } else { - lp->curr_rx_cfg |= AUTO_RX_DMA; /* not that we support it... */ - cs89_dbg(3, info, "set_dma_cfg(): AUTO_RX_DMA\n"); - } + /* if they give us an odd I/O address, then do ONE write to + the address port, to get it back to address zero, where we + expect to find the EISA signature word. An IO with a base of 0x3 + will skip the test for the ADD_PORT. */ + if (ioaddr & 1) { + if (net_debug > 1) + printk(KERN_INFO "%s: odd ioaddr 0x%lx\n", dev->name, ioaddr); + if ((ioaddr & 2) != 2) + if ((readword(ioaddr & ~3, ADD_PORT) & ADD_MASK) != ADD_SIG) { + printk(KERN_ERR "%s: bad signature 0x%x\n", + dev->name, readword(ioaddr & ~3, ADD_PORT)); + retval = -ENODEV; + goto out2; + } } -} -static int -dma_bufcfg(struct net_device *dev) -{ - struct net_local *lp = netdev_priv(dev); - if (lp->use_dma) - return (lp->isa_config & ANY_ISA_DMA) ? RX_DMA_ENBL : 0; - else - return 0; -} + ioaddr &= ~3; + printk(KERN_DEBUG "PP_addr at %lx[%x]: 0x%x\n", + ioaddr, ADD_PORT, readword(ioaddr, ADD_PORT)); + writeword(ioaddr, ADD_PORT, PP_ChipID); -static int -dma_busctl(struct net_device *dev) -{ - int retval = 0; - struct net_local *lp = netdev_priv(dev); - if (lp->use_dma) { - if (lp->isa_config & ANY_ISA_DMA) - retval |= RESET_RX_DMA; /* Reset the DMA pointer */ - if (lp->isa_config & DMA_BURST) - retval |= DMA_BURST_MODE; /* Does ISA config specify DMA burst ? */ - if (lp->dmasize == 64) - retval |= RX_DMA_SIZE_64K; /* did they ask for 64K? */ - retval |= MEMORY_ON; /* we need memory enabled to use DMA. */ + tmp = readword(ioaddr, DATA_PORT); + if (tmp != CHIP_EISA_ID_SIG) { + printk(KERN_DEBUG "%s: incorrect signature at %lx[%x]: 0x%x!=" + CHIP_EISA_ID_SIG_STR "\n", + dev->name, ioaddr, DATA_PORT, tmp); + retval = -ENODEV; + goto out2; } - return retval; -} - -static void -dma_rx(struct net_device *dev) -{ - struct net_local *lp = netdev_priv(dev); - struct sk_buff *skb; - int status, length; - unsigned char *bp = lp->rx_dma_ptr; - status = bp[0] + (bp[1] << 8); - length = bp[2] + (bp[3] << 8); - bp += 4; + /* Fill in the 'dev' fields. */ + dev->base_addr = ioaddr; - cs89_dbg(5, debug, "%s: receiving DMA packet at %lx, status %x, length %x\n", - dev->name, (unsigned long)bp, status, length); + /* get the chip type */ + rev_type = readreg(dev, PRODUCT_ID_ADD); + lp->chip_type = rev_type &~ REVISON_BITS; + lp->chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A'; - if ((status & RX_OK) == 0) { + /* Check the chip type and revision in order to set the correct send command + CS8920 revision C and CS8900 revision F can use the faster send. */ + lp->send_cmd = TX_AFTER_381; + if (lp->chip_type == CS8900 && lp->chip_revision >= 'F') + lp->send_cmd = TX_NOW; + if (lp->chip_type != CS8900 && lp->chip_revision >= 'C') + lp->send_cmd = TX_NOW; + + if (net_debug && version_printed++ == 0) + printk(version); + + printk(KERN_INFO "%s: cs89%c0%s rev %c found at %#3lx ", + dev->name, + lp->chip_type==CS8900?'0':'2', + lp->chip_type==CS8920M?"M":"", + lp->chip_revision, + dev->base_addr); + + reset_chip(dev); + + /* Here we read the current configuration of the chip. If there + is no Extended EEPROM then the idea is to not disturb the chip + configuration, it should have been correctly setup by automatic + EEPROM read on reset. So, if the chip says it read the EEPROM + the driver will always do *something* instead of complain that + adapter_cnf is 0. */ + + + if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) == + (EEPROM_OK|EEPROM_PRESENT)) { + /* Load the MAC. */ + for (i=0; i < ETH_ALEN/2; i++) { + unsigned int Addr; + Addr = readreg(dev, PP_IA+i*2); + dev->dev_addr[i*2] = Addr & 0xFF; + dev->dev_addr[i*2+1] = Addr >> 8; + } + + /* Load the Adapter Configuration. + Note: Barring any more specific information from some + other source (ie EEPROM+Schematics), we would not know + how to operate a 10Base2 interface on the AUI port. + However, since we do read the status of HCB1 and use + settings that always result in calls to control_dc_dc(dev,0) + a BNC interface should work if the enable pin + (dc/dc converter) is on HCB1. It will be called AUI + however. */ + + lp->adapter_cnf = 0; + i = readreg(dev, PP_LineCTL); + /* Preserve the setting of the HCB1 pin. */ + if ((i & (HCB1 | HCB1_ENBL)) == (HCB1 | HCB1_ENBL)) + lp->adapter_cnf |= A_CNF_DC_DC_POLARITY; + /* Save the sqelch bit */ + if ((i & LOW_RX_SQUELCH) == LOW_RX_SQUELCH) + lp->adapter_cnf |= A_CNF_EXTND_10B_2 | A_CNF_LOW_RX_SQUELCH; + /* Check if the card is in 10Base-t only mode */ + if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == 0) + lp->adapter_cnf |= A_CNF_10B_T | A_CNF_MEDIA_10B_T; + /* Check if the card is in AUI only mode */ + if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == AUI_ONLY) + lp->adapter_cnf |= A_CNF_AUI | A_CNF_MEDIA_AUI; + /* Check if the card is in Auto mode. */ + if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == AUTO_AUI_10BASET) + lp->adapter_cnf |= A_CNF_AUI | A_CNF_10B_T | + A_CNF_MEDIA_AUI | A_CNF_MEDIA_10B_T | A_CNF_MEDIA_AUTO; + + if (net_debug > 1) + printk(KERN_INFO "%s: PP_LineCTL=0x%x, adapter_cnf=0x%x\n", + dev->name, i, lp->adapter_cnf); + + /* IRQ. Other chips already probe, see below. */ + if (lp->chip_type == CS8900) + lp->isa_config = readreg(dev, PP_CS8900_ISAINT) & INT_NO_MASK; + + printk( "[Cirrus EEPROM] "); + } + + printk("\n"); + + /* First check to see if an EEPROM is attached. */ + + if ((readreg(dev, PP_SelfST) & EEPROM_PRESENT) == 0) + printk(KERN_WARNING "cs89x0: No EEPROM, relying on command line....\n"); + else if (get_eeprom_data(dev, START_EEPROM_DATA,CHKSUM_LEN,eeprom_buff) < 0) { + printk(KERN_WARNING "\ncs89x0: EEPROM read failed, relying on command line.\n"); + } else if (get_eeprom_cksum(START_EEPROM_DATA,CHKSUM_LEN,eeprom_buff) < 0) { + /* Check if the chip was able to read its own configuration starting + at 0 in the EEPROM*/ + if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) != + (EEPROM_OK|EEPROM_PRESENT)) + printk(KERN_WARNING "cs89x0: Extended EEPROM checksum bad and no Cirrus EEPROM, relying on command line\n"); + + } else { + /* This reads an extended EEPROM that is not documented + in the CS8900 datasheet. */ + + /* get transmission control word but keep the autonegotiation bits */ + if (!lp->auto_neg_cnf) lp->auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET/2]; + /* Store adapter configuration */ + if (!lp->adapter_cnf) lp->adapter_cnf = eeprom_buff[ADAPTER_CNF_OFFSET/2]; + /* Store ISA configuration */ + lp->isa_config = eeprom_buff[ISA_CNF_OFFSET/2]; + dev->mem_start = eeprom_buff[PACKET_PAGE_OFFSET/2] << 8; + + /* eeprom_buff has 32-bit ints, so we can't just memcpy it */ + /* store the initial memory base address */ + for (i = 0; i < ETH_ALEN/2; i++) { + dev->dev_addr[i*2] = eeprom_buff[i]; + dev->dev_addr[i*2+1] = eeprom_buff[i] >> 8; + } + if (net_debug > 1) + printk(KERN_DEBUG "%s: new adapter_cnf: 0x%x\n", + dev->name, lp->adapter_cnf); + } + + /* allow them to force multiple transceivers. If they force multiple, autosense */ + { + int count = 0; + if (lp->force & FORCE_RJ45) {lp->adapter_cnf |= A_CNF_10B_T; count++; } + if (lp->force & FORCE_AUI) {lp->adapter_cnf |= A_CNF_AUI; count++; } + if (lp->force & FORCE_BNC) {lp->adapter_cnf |= A_CNF_10B_2; count++; } + if (count > 1) {lp->adapter_cnf |= A_CNF_MEDIA_AUTO; } + else if (lp->force & FORCE_RJ45){lp->adapter_cnf |= A_CNF_MEDIA_10B_T; } + else if (lp->force & FORCE_AUI) {lp->adapter_cnf |= A_CNF_MEDIA_AUI; } + else if (lp->force & FORCE_BNC) {lp->adapter_cnf |= A_CNF_MEDIA_10B_2; } + } + + if (net_debug > 1) + printk(KERN_DEBUG "%s: after force 0x%x, adapter_cnf=0x%x\n", + dev->name, lp->force, lp->adapter_cnf); + + /* FIXME: We don't let you set dc-dc polarity or low RX squelch from the command line: add it here */ + + /* FIXME: We don't let you set the IMM bit from the command line: add it to lp->auto_neg_cnf here */ + + /* FIXME: we don't set the Ethernet address on the command line. Use + ifconfig IFACE hw ether AABBCCDDEEFF */ + + printk(KERN_INFO "cs89x0 media %s%s%s", + (lp->adapter_cnf & A_CNF_10B_T)?"RJ-45,":"", + (lp->adapter_cnf & A_CNF_AUI)?"AUI,":"", + (lp->adapter_cnf & A_CNF_10B_2)?"BNC,":""); + + lp->irq_map = 0xffff; + + /* If this is a CS8900 then no pnp soft */ + if (lp->chip_type != CS8900 && + /* Check if the ISA IRQ has been set */ + (i = readreg(dev, PP_CS8920_ISAINT) & 0xff, + (i != 0 && i < CS8920_NO_INTS))) { + if (!dev->irq) + dev->irq = i; + } else { + i = lp->isa_config & INT_NO_MASK; +#ifndef CONFIG_CS89x0_PLATFORM + if (lp->chip_type == CS8900) { +#ifdef CS89x0_NONISA_IRQ + i = cs8900_irq_map[0]; +#else + /* Translate the IRQ using the IRQ mapping table. */ + if (i >= ARRAY_SIZE(cs8900_irq_map)) + printk("\ncs89x0: invalid ISA interrupt number %d\n", i); + else + i = cs8900_irq_map[i]; + + lp->irq_map = CS8900_IRQ_MAP; /* fixed IRQ map for CS8900 */ + } else { + int irq_map_buff[IRQ_MAP_LEN/2]; + + if (get_eeprom_data(dev, IRQ_MAP_EEPROM_DATA, + IRQ_MAP_LEN/2, + irq_map_buff) >= 0) { + if ((irq_map_buff[0] & 0xff) == PNP_IRQ_FRMT) + lp->irq_map = (irq_map_buff[0]>>8) | (irq_map_buff[1] << 8); + } +#endif + } +#endif + if (!dev->irq) + dev->irq = i; + } + + printk(" IRQ %d", dev->irq); + +#if ALLOW_DMA + if (lp->use_dma) { + get_dma_channel(dev); + printk(", DMA %d", dev->dma); + } + else +#endif + { + printk(", programmed I/O"); + } + + /* print the ethernet address. */ + printk(", MAC %pM", dev->dev_addr); + + dev->netdev_ops = &net_ops; + dev->watchdog_timeo = HZ; + + printk("\n"); + if (net_debug) + printk("cs89x0_probe1() successful\n"); + + retval = register_netdev(dev); + if (retval) + goto out3; + return 0; +out3: + writeword(dev->base_addr, ADD_PORT, PP_ChipID); +out2: + release_region(ioaddr & ~3, NETCARD_IO_EXTENT); +out1: + return retval; +} + + +/********************************* + * This page contains DMA routines +**********************************/ + +#if ALLOW_DMA + +#define dma_page_eq(ptr1, ptr2) ((long)(ptr1)>>17 == (long)(ptr2)>>17) + +static void +get_dma_channel(struct net_device *dev) +{ + struct net_local *lp = netdev_priv(dev); + + if (lp->dma) { + dev->dma = lp->dma; + lp->isa_config |= ISA_RxDMA; + } else { + if ((lp->isa_config & ANY_ISA_DMA) == 0) + return; + dev->dma = lp->isa_config & DMA_NO_MASK; + if (lp->chip_type == CS8900) + dev->dma += 5; + if (dev->dma < 5 || dev->dma > 7) { + lp->isa_config &= ~ANY_ISA_DMA; + return; + } + } +} + +static void +write_dma(struct net_device *dev, int chip_type, int dma) +{ + struct net_local *lp = netdev_priv(dev); + if ((lp->isa_config & ANY_ISA_DMA) == 0) + return; + if (chip_type == CS8900) { + writereg(dev, PP_CS8900_ISADMA, dma-5); + } else { + writereg(dev, PP_CS8920_ISADMA, dma); + } +} + +static void +set_dma_cfg(struct net_device *dev) +{ + struct net_local *lp = netdev_priv(dev); + + if (lp->use_dma) { + if ((lp->isa_config & ANY_ISA_DMA) == 0) { + if (net_debug > 3) + printk("set_dma_cfg(): no DMA\n"); + return; + } + if (lp->isa_config & ISA_RxDMA) { + lp->curr_rx_cfg |= RX_DMA_ONLY; + if (net_debug > 3) + printk("set_dma_cfg(): RX_DMA_ONLY\n"); + } else { + lp->curr_rx_cfg |= AUTO_RX_DMA; /* not that we support it... */ + if (net_debug > 3) + printk("set_dma_cfg(): AUTO_RX_DMA\n"); + } + } +} + +static int +dma_bufcfg(struct net_device *dev) +{ + struct net_local *lp = netdev_priv(dev); + if (lp->use_dma) + return (lp->isa_config & ANY_ISA_DMA)? RX_DMA_ENBL : 0; + else + return 0; +} + +static int +dma_busctl(struct net_device *dev) +{ + int retval = 0; + struct net_local *lp = netdev_priv(dev); + if (lp->use_dma) { + if (lp->isa_config & ANY_ISA_DMA) + retval |= RESET_RX_DMA; /* Reset the DMA pointer */ + if (lp->isa_config & DMA_BURST) + retval |= DMA_BURST_MODE; /* Does ISA config specify DMA burst ? */ + if (lp->dmasize == 64) + retval |= RX_DMA_SIZE_64K; /* did they ask for 64K? */ + retval |= MEMORY_ON; /* we need memory enabled to use DMA. */ + } + return retval; +} + +static void +dma_rx(struct net_device *dev) +{ + struct net_local *lp = netdev_priv(dev); + struct sk_buff *skb; + int status, length; + unsigned char *bp = lp->rx_dma_ptr; + + status = bp[0] + (bp[1]<<8); + length = bp[2] + (bp[3]<<8); + bp += 4; + if (net_debug > 5) { + printk( "%s: receiving DMA packet at %lx, status %x, length %x\n", + dev->name, (unsigned long)bp, status, length); + } + if ((status & RX_OK) == 0) { count_rx_errors(status, dev); goto skip_this_frame; } @@ -478,16 +913,14 @@ dma_rx(struct net_device *dev) /* Malloc up new buffer. */ skb = netdev_alloc_skb(dev, length + 2); if (skb == NULL) { - /* I don't think we want to do this to a stressed system */ - cs89_dbg(0, err, "%s: Memory squeeze, dropping packet\n", - dev->name); + if (net_debug) /* I don't think we want to do this to a stressed system */ + printk("%s: Memory squeeze, dropping packet.\n", dev->name); dev->stats.rx_dropped++; /* AKPM: advance bp to the next frame */ skip_this_frame: bp += (length + 3) & ~3; - if (bp >= lp->end_dma_buff) - bp -= lp->dmasize * 1024; + if (bp >= lp->end_dma_buff) bp -= lp->dmasize*1024; lp->rx_dma_ptr = bp; return; } @@ -495,38 +928,63 @@ dma_rx(struct net_device *dev) if (bp + length > lp->end_dma_buff) { int semi_cnt = lp->end_dma_buff - bp; - memcpy(skb_put(skb, semi_cnt), bp, semi_cnt); - memcpy(skb_put(skb, length - semi_cnt), lp->dma_buff, + memcpy(skb_put(skb,semi_cnt), bp, semi_cnt); + memcpy(skb_put(skb,length - semi_cnt), lp->dma_buff, length - semi_cnt); } else { - memcpy(skb_put(skb, length), bp, length); + memcpy(skb_put(skb,length), bp, length); } bp += (length + 3) & ~3; - if (bp >= lp->end_dma_buff) - bp -= lp->dmasize*1024; + if (bp >= lp->end_dma_buff) bp -= lp->dmasize*1024; lp->rx_dma_ptr = bp; - cs89_dbg(3, info, "%s: received %d byte DMA packet of type %x\n", - dev->name, length, - ((skb->data[ETH_ALEN + ETH_ALEN] << 8) | - skb->data[ETH_ALEN + ETH_ALEN + 1])); - - skb->protocol = eth_type_trans(skb, dev); + if (net_debug > 3) { + printk( "%s: received %d byte DMA packet of type %x\n", + dev->name, length, + (skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]); + } + skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); dev->stats.rx_packets++; dev->stats.rx_bytes += length; } -static void release_dma_buff(struct net_local *lp) +#endif /* ALLOW_DMA */ + +static void __init reset_chip(struct net_device *dev) { - if (lp->dma_buff) { - free_pages((unsigned long)(lp->dma_buff), - get_order(lp->dmasize * 1024)); - lp->dma_buff = NULL; +#if !defined(CONFIG_MACH_MX31ADS) +#if !defined(CS89x0_NONISA_IRQ) + struct net_local *lp = netdev_priv(dev); + int ioaddr = dev->base_addr; +#endif /* CS89x0_NONISA_IRQ */ + int reset_start_time; + + writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET); + + /* wait 30 ms */ + msleep(30); + +#if !defined(CS89x0_NONISA_IRQ) + if (lp->chip_type != CS8900) { + /* Hardware problem requires PNP registers to be reconfigured after a reset */ + writeword(ioaddr, ADD_PORT, PP_CS8920_ISAINT); + outb(dev->irq, ioaddr + DATA_PORT); + outb(0, ioaddr + DATA_PORT + 1); + + writeword(ioaddr, ADD_PORT, PP_CS8920_ISAMemB); + outb((dev->mem_start >> 16) & 0xff, ioaddr + DATA_PORT); + outb((dev->mem_start >> 8) & 0xff, ioaddr + DATA_PORT + 1); } +#endif /* CS89x0_NONISA_IRQ */ + + /* Wait until the chip is reset */ + reset_start_time = jiffies; + while( (readreg(dev, PP_SelfST) & INIT_DONE) == 0 && jiffies - reset_start_time < 2) + ; +#endif /* !CONFIG_MACH_MX31ADS */ } -#endif /* ALLOW_DMA */ static void control_dc_dc(struct net_device *dev, int on_not_off) @@ -535,9 +993,8 @@ control_dc_dc(struct net_device *dev, int on_not_off) unsigned int selfcontrol; int timenow = jiffies; /* control the DC to DC convertor in the SelfControl register. - * Note: This is hooked up to a general purpose pin, might not - * always be a DC to DC convertor. - */ + Note: This is hooked up to a general purpose pin, might not + always be a DC to DC convertor. */ selfcontrol = HCB1_ENBL; /* Enable the HCB1 bit as an output */ if (((lp->adapter_cnf & A_CNF_DC_DC_POLARITY) != 0) ^ on_not_off) @@ -551,49 +1008,6 @@ control_dc_dc(struct net_device *dev, int on_not_off) ; } -/* send a test packet - return true if carrier bits are ok */ -static int -send_test_pkt(struct net_device *dev) -{ - struct net_local *lp = netdev_priv(dev); - char test_packet[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 46, /* A 46 in network order */ - 0, 0, /* DSAP=0 & SSAP=0 fields */ - 0xf3, 0 /* Control (Test Req + P bit set) */ - }; - long timenow = jiffies; - - writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_TX_ON); - - memcpy(test_packet, dev->dev_addr, ETH_ALEN); - memcpy(test_packet + ETH_ALEN, dev->dev_addr, ETH_ALEN); - - iowrite16(TX_AFTER_ALL, lp->virt_addr + TX_CMD_PORT); - iowrite16(ETH_ZLEN, lp->virt_addr + TX_LEN_PORT); - - /* Test to see if the chip has allocated memory for the packet */ - while (jiffies - timenow < 5) - if (readreg(dev, PP_BusST) & READY_FOR_TX_NOW) - break; - if (jiffies - timenow >= 5) - return 0; /* this shouldn't happen */ - - /* Write the contents of the packet */ - writewords(lp, TX_FRAME_PORT, test_packet, (ETH_ZLEN + 1) >> 1); - - cs89_dbg(1, debug, "Sending test packet "); - /* wait a couple of jiffies for packet to be received */ - for (timenow = jiffies; jiffies - timenow < 3;) - ; - if ((readreg(dev, PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) { - cs89_dbg(1, cont, "succeeded\n"); - return 1; - } - cs89_dbg(1, cont, "failed\n"); - return 0; -} - #define DETECTED_NONE 0 #define DETECTED_RJ45H 1 #define DETECTED_RJ45F 2 @@ -607,46 +1021,40 @@ detect_tp(struct net_device *dev) int timenow = jiffies; int fdx; - cs89_dbg(1, debug, "%s: Attempting TP\n", dev->name); + if (net_debug > 1) printk("%s: Attempting TP\n", dev->name); - /* If connected to another full duplex capable 10-Base-T card - * the link pulses seem to be lost when the auto detect bit in - * the LineCTL is set. To overcome this the auto detect bit will - * be cleared whilst testing the 10-Base-T interface. This would - * not be necessary for the sparrow chip but is simpler to do it - * anyway. - */ - writereg(dev, PP_LineCTL, lp->linectl & ~AUI_ONLY); + /* If connected to another full duplex capable 10-Base-T card the link pulses + seem to be lost when the auto detect bit in the LineCTL is set. + To overcome this the auto detect bit will be cleared whilst testing the + 10-Base-T interface. This would not be necessary for the sparrow chip but + is simpler to do it anyway. */ + writereg(dev, PP_LineCTL, lp->linectl &~ AUI_ONLY); control_dc_dc(dev, 0); - /* Delay for the hardware to work out if the TP cable is present - * - 150ms - */ - for (timenow = jiffies; jiffies - timenow < 15;) - ; + /* Delay for the hardware to work out if the TP cable is present - 150ms */ + for (timenow = jiffies; jiffies - timenow < 15; ) + ; if ((readreg(dev, PP_LineST) & LINK_OK) == 0) return DETECTED_NONE; if (lp->chip_type == CS8900) { - switch (lp->force & 0xf0) { + switch (lp->force & 0xf0) { #if 0 - case FORCE_AUTO: - pr_info("%s: cs8900 doesn't autonegotiate\n", - dev->name); - return DETECTED_NONE; + case FORCE_AUTO: + printk("%s: cs8900 doesn't autonegotiate\n",dev->name); + return DETECTED_NONE; #endif - /* CS8900 doesn't support AUTO, change to HALF*/ - case FORCE_AUTO: + /* CS8900 doesn't support AUTO, change to HALF*/ + case FORCE_AUTO: lp->force &= ~FORCE_AUTO; - lp->force |= FORCE_HALF; + lp->force |= FORCE_HALF; break; case FORCE_HALF: break; - case FORCE_FULL: - writereg(dev, PP_TestCTL, - readreg(dev, PP_TestCTL) | FDX_8900); + case FORCE_FULL: + writereg(dev, PP_TestCTL, readreg(dev, PP_TestCTL) | FDX_8900); break; - } + } fdx = readreg(dev, PP_TestCTL) & FDX_8900; } else { switch (lp->force & 0xf0) { @@ -659,15 +1067,15 @@ detect_tp(struct net_device *dev) case FORCE_FULL: lp->auto_neg_cnf = RE_NEG_NOW | ALLOW_FDX; break; - } + } writereg(dev, PP_AutoNegCTL, lp->auto_neg_cnf & AUTO_NEG_MASK); if ((lp->auto_neg_cnf & AUTO_NEG_BITS) == AUTO_NEG_ENABLE) { - pr_info("%s: negotiating duplex...\n", dev->name); + printk(KERN_INFO "%s: negotiating duplex...\n",dev->name); while (readreg(dev, PP_AutoNegST) & AUTO_NEG_BUSY) { if (jiffies - timenow > 4000) { - pr_err("**** Full / half duplex auto-negotiation timed out ****\n"); + printk(KERN_ERR "**** Full / half duplex auto-negotiation timed out ****\n"); break; } } @@ -680,31 +1088,56 @@ detect_tp(struct net_device *dev) return DETECTED_RJ45H; } +/* send a test packet - return true if carrier bits are ok */ static int -detect_bnc(struct net_device *dev) +send_test_pkt(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + char test_packet[] = { 0,0,0,0,0,0, 0,0,0,0,0,0, + 0, 46, /* A 46 in network order */ + 0, 0, /* DSAP=0 & SSAP=0 fields */ + 0xf3, 0 /* Control (Test Req + P bit set) */ }; + long timenow = jiffies; - cs89_dbg(1, debug, "%s: Attempting BNC\n", dev->name); - control_dc_dc(dev, 1); + writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_TX_ON); - writereg(dev, PP_LineCTL, (lp->linectl & ~AUTO_AUI_10BASET) | AUI_ONLY); + memcpy(test_packet, dev->dev_addr, ETH_ALEN); + memcpy(test_packet+ETH_ALEN, dev->dev_addr, ETH_ALEN); - if (send_test_pkt(dev)) - return DETECTED_BNC; - else - return DETECTED_NONE; + writeword(dev->base_addr, TX_CMD_PORT, TX_AFTER_ALL); + writeword(dev->base_addr, TX_LEN_PORT, ETH_ZLEN); + + /* Test to see if the chip has allocated memory for the packet */ + while (jiffies - timenow < 5) + if (readreg(dev, PP_BusST) & READY_FOR_TX_NOW) + break; + if (jiffies - timenow >= 5) + return 0; /* this shouldn't happen */ + + /* Write the contents of the packet */ + writewords(dev->base_addr, TX_FRAME_PORT,test_packet,(ETH_ZLEN+1) >>1); + + if (net_debug > 1) printk("Sending test packet "); + /* wait a couple of jiffies for packet to be received */ + for (timenow = jiffies; jiffies - timenow < 3; ) + ; + if ((readreg(dev, PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) { + if (net_debug > 1) printk("succeeded\n"); + return 1; + } + if (net_debug > 1) printk("failed\n"); + return 0; } + static int detect_aui(struct net_device *dev) { struct net_local *lp = netdev_priv(dev); - cs89_dbg(1, debug, "%s: Attempting AUI\n", dev->name); + if (net_debug > 1) printk("%s: Attempting AUI\n", dev->name); control_dc_dc(dev, 0); - writereg(dev, PP_LineCTL, (lp->linectl & ~AUTO_AUI_10BASET) | AUI_ONLY); + writereg(dev, PP_LineCTL, (lp->linectl &~ AUTO_AUI_10BASET) | AUI_ONLY); if (send_test_pkt(dev)) return DETECTED_AUI; @@ -712,154 +1145,45 @@ detect_aui(struct net_device *dev) return DETECTED_NONE; } -/* We have a good packet(s), get it/them out of the buffers. */ -static void -net_rx(struct net_device *dev) +static int +detect_bnc(struct net_device *dev) { struct net_local *lp = netdev_priv(dev); - struct sk_buff *skb; - int status, length; - - status = ioread16(lp->virt_addr + RX_FRAME_PORT); - length = ioread16(lp->virt_addr + RX_FRAME_PORT); - - if ((status & RX_OK) == 0) { - count_rx_errors(status, dev); - return; - } - /* Malloc up new buffer. */ - skb = netdev_alloc_skb(dev, length + 2); - if (skb == NULL) { -#if 0 /* Again, this seems a cruel thing to do */ - pr_warn("%s: Memory squeeze, dropping packet\n", dev->name); -#endif - dev->stats.rx_dropped++; - return; - } - skb_reserve(skb, 2); /* longword align L3 header */ - - readwords(lp, RX_FRAME_PORT, skb_put(skb, length), length >> 1); - if (length & 1) - skb->data[length-1] = ioread16(lp->virt_addr + RX_FRAME_PORT); + if (net_debug > 1) printk("%s: Attempting BNC\n", dev->name); + control_dc_dc(dev, 1); - cs89_dbg(3, debug, "%s: received %d byte packet of type %x\n", - dev->name, length, - (skb->data[ETH_ALEN + ETH_ALEN] << 8) | - skb->data[ETH_ALEN + ETH_ALEN + 1]); + writereg(dev, PP_LineCTL, (lp->linectl &~ AUTO_AUI_10BASET) | AUI_ONLY); - skb->protocol = eth_type_trans(skb, dev); - netif_rx(skb); - dev->stats.rx_packets++; - dev->stats.rx_bytes += length; + if (send_test_pkt(dev)) + return DETECTED_BNC; + else + return DETECTED_NONE; } -/* The typical workload of the driver: - * Handle the network interface interrupts. - */ -static irqreturn_t net_interrupt(int irq, void *dev_id) +static void +write_irq(struct net_device *dev, int chip_type, int irq) { - struct net_device *dev = dev_id; - struct net_local *lp; - int status; - int handled = 0; - - lp = netdev_priv(dev); + int i; - /* we MUST read all the events out of the ISQ, otherwise we'll never - * get interrupted again. As a consequence, we can't have any limit - * on the number of times we loop in the interrupt handler. The - * hardware guarantees that eventually we'll run out of events. Of - * course, if you're on a slow machine, and packets are arriving - * faster than you can read them off, you're screwed. Hasta la - * vista, baby! - */ - while ((status = ioread16(lp->virt_addr + ISQ_PORT))) { - cs89_dbg(4, debug, "%s: event=%04x\n", dev->name, status); - handled = 1; - switch (status & ISQ_EVENT_MASK) { - case ISQ_RECEIVER_EVENT: - /* Got a packet(s). */ - net_rx(dev); - break; - case ISQ_TRANSMITTER_EVENT: - dev->stats.tx_packets++; - netif_wake_queue(dev); /* Inform upper layers. */ - if ((status & (TX_OK | - TX_LOST_CRS | - TX_SQE_ERROR | - TX_LATE_COL | - TX_16_COL)) != TX_OK) { - if ((status & TX_OK) == 0) - dev->stats.tx_errors++; - if (status & TX_LOST_CRS) - dev->stats.tx_carrier_errors++; - if (status & TX_SQE_ERROR) - dev->stats.tx_heartbeat_errors++; - if (status & TX_LATE_COL) - dev->stats.tx_window_errors++; - if (status & TX_16_COL) - dev->stats.tx_aborted_errors++; - } - break; - case ISQ_BUFFER_EVENT: - if (status & READY_FOR_TX) { - /* we tried to transmit a packet earlier, - * but inexplicably ran out of buffers. - * That shouldn't happen since we only ever - * load one packet. Shrug. Do the right - * thing anyway. - */ - netif_wake_queue(dev); /* Inform upper layers. */ - } - if (status & TX_UNDERRUN) { - cs89_dbg(0, err, "%s: transmit underrun\n", - dev->name); - lp->send_underrun++; - if (lp->send_underrun == 3) - lp->send_cmd = TX_AFTER_381; - else if (lp->send_underrun == 6) - lp->send_cmd = TX_AFTER_ALL; - /* transmit cycle is done, although - * frame wasn't transmitted - this - * avoids having to wait for the upper - * layers to timeout on us, in the - * event of a tx underrun - */ - netif_wake_queue(dev); /* Inform upper layers. */ - } -#if ALLOW_DMA - if (lp->use_dma && (status & RX_DMA)) { - int count = readreg(dev, PP_DmaFrameCnt); - while (count) { - cs89_dbg(5, debug, - "%s: receiving %d DMA frames\n", - dev->name, count); - if (count > 1) - cs89_dbg(2, debug, - "%s: receiving %d DMA frames\n", - dev->name, count); - dma_rx(dev); - if (--count == 0) - count = readreg(dev, PP_DmaFrameCnt); - if (count > 0) - cs89_dbg(2, debug, - "%s: continuing with %d DMA frames\n", - dev->name, count); - } - } + if (chip_type == CS8900) { +#ifndef CONFIG_CS89x0_PLATFORM + /* Search the mapping table for the corresponding IRQ pin. */ + for (i = 0; i != ARRAY_SIZE(cs8900_irq_map); i++) + if (cs8900_irq_map[i] == irq) + break; + /* Not found */ + if (i == ARRAY_SIZE(cs8900_irq_map)) + i = 3; +#else + /* INTRQ0 pin is used for interrupt generation. */ + i = 0; #endif - break; - case ISQ_RX_MISS_EVENT: - dev->stats.rx_missed_errors += (status >> 6); - break; - case ISQ_TX_COL_EVENT: - dev->stats.collisions += (status >> 6); - break; - } + writereg(dev, PP_CS8900_ISAINT, i); + } else { + writereg(dev, PP_CS8920_ISAINT, irq); } - return IRQ_RETVAL(handled); } /* Open/initialize the board. This is called (in the current kernel) @@ -868,7 +1192,7 @@ static irqreturn_t net_interrupt(int irq, void *dev_id) This routine should set everything up anew at each open, even registers that "should" only need to be set once at boot, so that there is non-reboot way to recover if something goes wrong. -*/ + */ /* AKPM: do we need to do any locking here? */ @@ -884,15 +1208,14 @@ net_open(struct net_device *dev) /* Allow interrupts to be generated by the chip */ /* Cirrus' release had this: */ #if 0 - writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL) | ENABLE_IRQ); + writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ ); #endif /* And 2.3.47 had this: */ writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON); for (i = 2; i < CS8920_NO_INTS; i++) { if ((1 << i) & lp->irq_map) { - if (request_irq(i, net_interrupt, 0, dev->name, - dev) == 0) { + if (request_irq(i, net_interrupt, 0, dev->name, dev) == 0) { dev->irq = i; write_irq(dev, lp->chip_type, i); /* writereg(dev, PP_BufCFG, GENERATE_SW_INTERRUPT); */ @@ -903,21 +1226,23 @@ net_open(struct net_device *dev) if (i >= CS8920_NO_INTS) { writereg(dev, PP_BusCTL, 0); /* disable interrupts. */ - pr_err("can't get an interrupt\n"); + printk(KERN_ERR "cs89x0: can't get an interrupt\n"); ret = -EAGAIN; goto bad_out; } - } else { + } + else + { #if !defined(CS89x0_NONISA_IRQ) && !defined(CONFIG_CS89x0_PLATFORM) if (((1 << dev->irq) & lp->irq_map) == 0) { - pr_err("%s: IRQ %d is not in our map of allowable IRQs, which is %x\n", - dev->name, dev->irq, lp->irq_map); + printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n", + dev->name, dev->irq, lp->irq_map); ret = -EAGAIN; goto bad_out; } #endif /* FIXME: Cirrus' release had this: */ - writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ); + writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ ); /* And 2.3.47 had this: */ #if 0 writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON); @@ -925,168 +1250,147 @@ net_open(struct net_device *dev) write_irq(dev, lp->chip_type, dev->irq); ret = request_irq(dev->irq, net_interrupt, 0, dev->name, dev); if (ret) { - pr_err("request_irq(%d) failed\n", dev->irq); + printk(KERN_ERR "cs89x0: request_irq(%d) failed\n", dev->irq); goto bad_out; } } #if ALLOW_DMA - if (lp->use_dma && (lp->isa_config & ANY_ISA_DMA)) { - unsigned long flags; - lp->dma_buff = (unsigned char *)__get_dma_pages(GFP_KERNEL, - get_order(lp->dmasize * 1024)); - if (!lp->dma_buff) { - pr_err("%s: cannot get %dK memory for DMA\n", - dev->name, lp->dmasize); - goto release_irq; - } - cs89_dbg(1, debug, "%s: dma %lx %lx\n", - dev->name, - (unsigned long)lp->dma_buff, - (unsigned long)isa_virt_to_bus(lp->dma_buff)); - if ((unsigned long)lp->dma_buff >= MAX_DMA_ADDRESS || - !dma_page_eq(lp->dma_buff, - lp->dma_buff + lp->dmasize * 1024 - 1)) { - pr_err("%s: not usable as DMA buffer\n", dev->name); - goto release_irq; - } - memset(lp->dma_buff, 0, lp->dmasize * 1024); /* Why? */ - if (request_dma(dev->dma, dev->name)) { - pr_err("%s: cannot get dma channel %d\n", - dev->name, dev->dma); - goto release_irq; + if (lp->use_dma) { + if (lp->isa_config & ANY_ISA_DMA) { + unsigned long flags; + lp->dma_buff = (unsigned char *)__get_dma_pages(GFP_KERNEL, + get_order(lp->dmasize * 1024)); + + if (!lp->dma_buff) { + printk(KERN_ERR "%s: cannot get %dK memory for DMA\n", dev->name, lp->dmasize); + goto release_irq; + } + if (net_debug > 1) { + printk( "%s: dma %lx %lx\n", + dev->name, + (unsigned long)lp->dma_buff, + (unsigned long)isa_virt_to_bus(lp->dma_buff)); + } + if ((unsigned long) lp->dma_buff >= MAX_DMA_ADDRESS || + !dma_page_eq(lp->dma_buff, lp->dma_buff+lp->dmasize*1024-1)) { + printk(KERN_ERR "%s: not usable as DMA buffer\n", dev->name); + goto release_irq; + } + memset(lp->dma_buff, 0, lp->dmasize * 1024); /* Why? */ + if (request_dma(dev->dma, dev->name)) { + printk(KERN_ERR "%s: cannot get dma channel %d\n", dev->name, dev->dma); + goto release_irq; + } + write_dma(dev, lp->chip_type, dev->dma); + lp->rx_dma_ptr = lp->dma_buff; + lp->end_dma_buff = lp->dma_buff + lp->dmasize*1024; + spin_lock_irqsave(&lp->lock, flags); + disable_dma(dev->dma); + clear_dma_ff(dev->dma); + set_dma_mode(dev->dma, DMA_RX_MODE); /* auto_init as well */ + set_dma_addr(dev->dma, isa_virt_to_bus(lp->dma_buff)); + set_dma_count(dev->dma, lp->dmasize*1024); + enable_dma(dev->dma); + spin_unlock_irqrestore(&lp->lock, flags); } - write_dma(dev, lp->chip_type, dev->dma); - lp->rx_dma_ptr = lp->dma_buff; - lp->end_dma_buff = lp->dma_buff + lp->dmasize * 1024; - spin_lock_irqsave(&lp->lock, flags); - disable_dma(dev->dma); - clear_dma_ff(dev->dma); - set_dma_mode(dev->dma, DMA_RX_MODE); /* auto_init as well */ - set_dma_addr(dev->dma, isa_virt_to_bus(lp->dma_buff)); - set_dma_count(dev->dma, lp->dmasize * 1024); - enable_dma(dev->dma); - spin_unlock_irqrestore(&lp->lock, flags); } #endif /* ALLOW_DMA */ /* set the Ethernet address */ - for (i = 0; i < ETH_ALEN / 2; i++) - writereg(dev, PP_IA + i * 2, - (dev->dev_addr[i * 2] | - (dev->dev_addr[i * 2 + 1] << 8))); + for (i=0; i < ETH_ALEN/2; i++) + writereg(dev, PP_IA+i*2, dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] << 8)); /* while we're testing the interface, leave interrupts disabled */ writereg(dev, PP_BusCTL, MEMORY_ON); /* Set the LineCTL quintuplet based on adapter configuration read from EEPROM */ - if ((lp->adapter_cnf & A_CNF_EXTND_10B_2) && - (lp->adapter_cnf & A_CNF_LOW_RX_SQUELCH)) - lp->linectl = LOW_RX_SQUELCH; + if ((lp->adapter_cnf & A_CNF_EXTND_10B_2) && (lp->adapter_cnf & A_CNF_LOW_RX_SQUELCH)) + lp->linectl = LOW_RX_SQUELCH; else - lp->linectl = 0; - - /* check to make sure that they have the "right" hardware available */ - switch (lp->adapter_cnf & A_CNF_MEDIA_TYPE) { - case A_CNF_MEDIA_10B_T: - result = lp->adapter_cnf & A_CNF_10B_T; - break; - case A_CNF_MEDIA_AUI: - result = lp->adapter_cnf & A_CNF_AUI; - break; - case A_CNF_MEDIA_10B_2: - result = lp->adapter_cnf & A_CNF_10B_2; - break; - default: - result = lp->adapter_cnf & (A_CNF_10B_T | - A_CNF_AUI | - A_CNF_10B_2); - } - if (!result) { - pr_err("%s: EEPROM is configured for unavailable media\n", - dev->name); + lp->linectl = 0; + + /* check to make sure that they have the "right" hardware available */ + switch(lp->adapter_cnf & A_CNF_MEDIA_TYPE) { + case A_CNF_MEDIA_10B_T: result = lp->adapter_cnf & A_CNF_10B_T; break; + case A_CNF_MEDIA_AUI: result = lp->adapter_cnf & A_CNF_AUI; break; + case A_CNF_MEDIA_10B_2: result = lp->adapter_cnf & A_CNF_10B_2; break; + default: result = lp->adapter_cnf & (A_CNF_10B_T | A_CNF_AUI | A_CNF_10B_2); + } + if (!result) { + printk(KERN_ERR "%s: EEPROM is configured for unavailable media\n", dev->name); release_dma: #if ALLOW_DMA free_dma(dev->dma); release_irq: release_dma_buff(lp); #endif - writereg(dev, PP_LineCTL, - readreg(dev, PP_LineCTL) & ~(SERIAL_TX_ON | SERIAL_RX_ON)); - free_irq(dev->irq, dev); + writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) & ~(SERIAL_TX_ON | SERIAL_RX_ON)); + free_irq(dev->irq, dev); ret = -EAGAIN; goto bad_out; } - /* set the hardware to the configured choice */ - switch (lp->adapter_cnf & A_CNF_MEDIA_TYPE) { + /* set the hardware to the configured choice */ + switch(lp->adapter_cnf & A_CNF_MEDIA_TYPE) { case A_CNF_MEDIA_10B_T: - result = detect_tp(dev); - if (result == DETECTED_NONE) { - pr_warn("%s: 10Base-T (RJ-45) has no cable\n", - dev->name); - if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */ - result = DETECTED_RJ45H; /* Yes! I don't care if I see a link pulse */ - } + result = detect_tp(dev); + if (result==DETECTED_NONE) { + printk(KERN_WARNING "%s: 10Base-T (RJ-45) has no cable\n", dev->name); + if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */ + result = DETECTED_RJ45H; /* Yes! I don't care if I see a link pulse */ + } break; case A_CNF_MEDIA_AUI: - result = detect_aui(dev); - if (result == DETECTED_NONE) { - pr_warn("%s: 10Base-5 (AUI) has no cable\n", dev->name); - if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */ - result = DETECTED_AUI; /* Yes! I don't care if I see a carrrier */ - } + result = detect_aui(dev); + if (result==DETECTED_NONE) { + printk(KERN_WARNING "%s: 10Base-5 (AUI) has no cable\n", dev->name); + if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */ + result = DETECTED_AUI; /* Yes! I don't care if I see a carrrier */ + } break; case A_CNF_MEDIA_10B_2: - result = detect_bnc(dev); - if (result == DETECTED_NONE) { - pr_warn("%s: 10Base-2 (BNC) has no cable\n", dev->name); - if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */ - result = DETECTED_BNC; /* Yes! I don't care if I can xmit a packet */ - } + result = detect_bnc(dev); + if (result==DETECTED_NONE) { + printk(KERN_WARNING "%s: 10Base-2 (BNC) has no cable\n", dev->name); + if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */ + result = DETECTED_BNC; /* Yes! I don't care if I can xmit a packet */ + } break; case A_CNF_MEDIA_AUTO: writereg(dev, PP_LineCTL, lp->linectl | AUTO_AUI_10BASET); - if (lp->adapter_cnf & A_CNF_10B_T) { - result = detect_tp(dev); - if (result != DETECTED_NONE) + if (lp->adapter_cnf & A_CNF_10B_T) + if ((result = detect_tp(dev)) != DETECTED_NONE) break; - } - if (lp->adapter_cnf & A_CNF_AUI) { - result = detect_aui(dev); - if (result != DETECTED_NONE) + if (lp->adapter_cnf & A_CNF_AUI) + if ((result = detect_aui(dev)) != DETECTED_NONE) break; - } - if (lp->adapter_cnf & A_CNF_10B_2) { - result = detect_bnc(dev); - if (result != DETECTED_NONE) + if (lp->adapter_cnf & A_CNF_10B_2) + if ((result = detect_bnc(dev)) != DETECTED_NONE) break; - } - pr_err("%s: no media detected\n", dev->name); + printk(KERN_ERR "%s: no media detected\n", dev->name); goto release_dma; } - switch (result) { + switch(result) { case DETECTED_NONE: - pr_err("%s: no network cable attached to configured media\n", - dev->name); + printk(KERN_ERR "%s: no network cable attached to configured media\n", dev->name); goto release_dma; case DETECTED_RJ45H: - pr_info("%s: using half-duplex 10Base-T (RJ-45)\n", dev->name); + printk(KERN_INFO "%s: using half-duplex 10Base-T (RJ-45)\n", dev->name); break; case DETECTED_RJ45F: - pr_info("%s: using full-duplex 10Base-T (RJ-45)\n", dev->name); + printk(KERN_INFO "%s: using full-duplex 10Base-T (RJ-45)\n", dev->name); break; case DETECTED_AUI: - pr_info("%s: using 10Base-5 (AUI)\n", dev->name); + printk(KERN_INFO "%s: using 10Base-5 (AUI)\n", dev->name); break; case DETECTED_BNC: - pr_info("%s: using 10Base-2 (BNC)\n", dev->name); + printk(KERN_INFO "%s: using 10Base-2 (BNC)\n", dev->name); break; } /* Turn on both receive and transmit operations */ - writereg(dev, PP_LineCTL, - readreg(dev, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON); + writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON); /* Receive only error free packets addressed to this card */ lp->rx_mode = 0; @@ -1101,653 +1405,358 @@ net_open(struct net_device *dev) #endif writereg(dev, PP_RxCFG, lp->curr_rx_cfg); - writereg(dev, PP_TxCFG, (TX_LOST_CRS_ENBL | - TX_SQE_ERROR_ENBL | - TX_OK_ENBL | - TX_LATE_COL_ENBL | - TX_JBR_ENBL | - TX_ANY_COL_ENBL | - TX_16_COL_ENBL)); + writereg(dev, PP_TxCFG, TX_LOST_CRS_ENBL | TX_SQE_ERROR_ENBL | TX_OK_ENBL | + TX_LATE_COL_ENBL | TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL); - writereg(dev, PP_BufCFG, (READY_FOR_TX_ENBL | - RX_MISS_COUNT_OVRFLOW_ENBL | + writereg(dev, PP_BufCFG, READY_FOR_TX_ENBL | RX_MISS_COUNT_OVRFLOW_ENBL | #if ALLOW_DMA - dma_bufcfg(dev) | + dma_bufcfg(dev) | #endif - TX_COL_COUNT_OVRFLOW_ENBL | - TX_UNDERRUN_ENBL)); + TX_COL_COUNT_OVRFLOW_ENBL | TX_UNDERRUN_ENBL); /* now that we've got our act together, enable everything */ - writereg(dev, PP_BusCTL, (ENABLE_IRQ - | (dev->mem_start ? MEMORY_ON : 0) /* turn memory on */ + writereg(dev, PP_BusCTL, ENABLE_IRQ + | (dev->mem_start?MEMORY_ON : 0) /* turn memory on */ #if ALLOW_DMA - | dma_busctl(dev) + | dma_busctl(dev) #endif - )); - netif_start_queue(dev); - cs89_dbg(1, debug, "net_open() succeeded\n"); + ); + netif_start_queue(dev); + if (net_debug > 1) + printk("cs89x0: net_open() succeeded\n"); return 0; bad_out: return ret; } -/* The inverse routine to net_open(). */ -static int -net_close(struct net_device *dev) -{ -#if ALLOW_DMA - struct net_local *lp = netdev_priv(dev); -#endif - - netif_stop_queue(dev); - - writereg(dev, PP_RxCFG, 0); - writereg(dev, PP_TxCFG, 0); - writereg(dev, PP_BufCFG, 0); - writereg(dev, PP_BusCTL, 0); - - free_irq(dev->irq, dev); - -#if ALLOW_DMA - if (lp->use_dma && lp->dma) { - free_dma(dev->dma); - release_dma_buff(lp); - } -#endif - - /* Update the statistics here. */ - return 0; -} - -/* Get the current statistics. - * This may be called with the card open or closed. - */ -static struct net_device_stats * -net_get_stats(struct net_device *dev) -{ - struct net_local *lp = netdev_priv(dev); - unsigned long flags; - - spin_lock_irqsave(&lp->lock, flags); - /* Update the statistics from the device registers. */ - dev->stats.rx_missed_errors += (readreg(dev, PP_RxMiss) >> 6); - dev->stats.collisions += (readreg(dev, PP_TxCol) >> 6); - spin_unlock_irqrestore(&lp->lock, flags); - - return &dev->stats; -} - static void net_timeout(struct net_device *dev) { /* If we get here, some higher level has decided we are broken. There should really be a "kick me" function call instead. */ - cs89_dbg(0, err, "%s: transmit timed out, %s?\n", - dev->name, - tx_done(dev) ? "IRQ conflict" : "network cable problem"); + if (net_debug > 0) printk("%s: transmit timed out, %s?\n", dev->name, + tx_done(dev) ? "IRQ conflict ?" : "network cable problem"); /* Try to restart the adaptor. */ netif_wake_queue(dev); } -static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t net_send_packet(struct sk_buff *skb,struct net_device *dev) { struct net_local *lp = netdev_priv(dev); unsigned long flags; - cs89_dbg(3, debug, "%s: sent %d byte packet of type %x\n", - dev->name, skb->len, - ((skb->data[ETH_ALEN + ETH_ALEN] << 8) | - skb->data[ETH_ALEN + ETH_ALEN + 1])); + if (net_debug > 3) { + printk("%s: sent %d byte packet of type %x\n", + dev->name, skb->len, + (skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]); + } /* keep the upload from being interrupted, since we - * ask the chip to start transmitting before the - * whole packet has been completely uploaded. - */ + ask the chip to start transmitting before the + whole packet has been completely uploaded. */ spin_lock_irqsave(&lp->lock, flags); netif_stop_queue(dev); /* initiate a transmit sequence */ - iowrite16(lp->send_cmd, lp->virt_addr + TX_CMD_PORT); - iowrite16(skb->len, lp->virt_addr + TX_LEN_PORT); + writeword(dev->base_addr, TX_CMD_PORT, lp->send_cmd); + writeword(dev->base_addr, TX_LEN_PORT, skb->len); /* Test to see if the chip has allocated memory for the packet */ if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) { - /* Gasp! It hasn't. But that shouldn't happen since + /* + * Gasp! It hasn't. But that shouldn't happen since * we're waiting for TxOk, so return 1 and requeue this packet. */ spin_unlock_irqrestore(&lp->lock, flags); - cs89_dbg(0, err, "Tx buffer not free!\n"); + if (net_debug) printk("cs89x0: Tx buffer not free!\n"); return NETDEV_TX_BUSY; } /* Write the contents of the packet */ - writewords(lp, TX_FRAME_PORT, skb->data, (skb->len + 1) >> 1); + writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1); spin_unlock_irqrestore(&lp->lock, flags); dev->stats.tx_bytes += skb->len; - dev_kfree_skb(skb); + dev_kfree_skb (skb); - /* We DO NOT call netif_wake_queue() here. + /* + * We DO NOT call netif_wake_queue() here. * We also DO NOT call netif_start_queue(). * * Either of these would cause another bottom half run through - * net_send_packet() before this packet has fully gone out. - * That causes us to hit the "Gasp!" above and the send is rescheduled. - * it runs like a dog. We just return and wait for the Tx completion - * interrupt handler to restart the netdevice layer + * net_send_packet() before this packet has fully gone out. That causes + * us to hit the "Gasp!" above and the send is rescheduled. it runs like + * a dog. We just return and wait for the Tx completion interrupt handler + * to restart the netdevice layer */ return NETDEV_TX_OK; } -static void set_multicast_list(struct net_device *dev) -{ - struct net_local *lp = netdev_priv(dev); - unsigned long flags; - - spin_lock_irqsave(&lp->lock, flags); - if (dev->flags & IFF_PROMISC) - lp->rx_mode = RX_ALL_ACCEPT; - else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev)) - /* The multicast-accept list is initialized to accept-all, - * and we rely on higher-level filtering for now. - */ - lp->rx_mode = RX_MULTCAST_ACCEPT; - else - lp->rx_mode = 0; - - writereg(dev, PP_RxCTL, DEF_RX_ACCEPT | lp->rx_mode); - - /* in promiscuous mode, we accept errored packets, - * so we have to enable interrupts on them also - */ - writereg(dev, PP_RxCFG, - (lp->curr_rx_cfg | - (lp->rx_mode == RX_ALL_ACCEPT) - ? (RX_CRC_ERROR_ENBL | RX_RUNT_ENBL | RX_EXTRA_DATA_ENBL) - : 0)); - spin_unlock_irqrestore(&lp->lock, flags); -} - -static int set_mac_address(struct net_device *dev, void *p) -{ - int i; - struct sockaddr *addr = p; - - if (netif_running(dev)) - return -EBUSY; - - memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - - cs89_dbg(0, debug, "%s: Setting MAC address to %pM\n", - dev->name, dev->dev_addr); - - /* set the Ethernet address */ - for (i = 0; i < ETH_ALEN / 2; i++) - writereg(dev, PP_IA + i * 2, - (dev->dev_addr[i * 2] | - (dev->dev_addr[i * 2 + 1] << 8))); - - return 0; -} - -#ifdef CONFIG_NET_POLL_CONTROLLER -/* - * Polling receive - used by netconsole and other diagnostic tools - * to allow network i/o with interrupts disabled. - */ -static void net_poll_controller(struct net_device *dev) -{ - disable_irq(dev->irq); - net_interrupt(dev->irq, dev); - enable_irq(dev->irq); -} -#endif - -static const struct net_device_ops net_ops = { - .ndo_open = net_open, - .ndo_stop = net_close, - .ndo_tx_timeout = net_timeout, - .ndo_start_xmit = net_send_packet, - .ndo_get_stats = net_get_stats, - .ndo_set_rx_mode = set_multicast_list, - .ndo_set_mac_address = set_mac_address, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = net_poll_controller, -#endif - .ndo_change_mtu = eth_change_mtu, - .ndo_validate_addr = eth_validate_addr, -}; - -static void __init reset_chip(struct net_device *dev) -{ -#if !defined(CONFIG_MACH_MX31ADS) -#if !defined(CS89x0_NONISA_IRQ) - struct net_local *lp = netdev_priv(dev); -#endif /* CS89x0_NONISA_IRQ */ - int reset_start_time; - - writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET); - - /* wait 30 ms */ - msleep(30); - -#if !defined(CS89x0_NONISA_IRQ) - if (lp->chip_type != CS8900) { - /* Hardware problem requires PNP registers to be reconfigured after a reset */ - iowrite16(PP_CS8920_ISAINT, lp->virt_addr + ADD_PORT); - iowrite8(dev->irq, lp->virt_addr + DATA_PORT); - iowrite8(0, lp->virt_addr + DATA_PORT + 1); - - iowrite16(PP_CS8920_ISAMemB, lp->virt_addr + ADD_PORT); - iowrite8((dev->mem_start >> 16) & 0xff, - lp->virt_addr + DATA_PORT); - iowrite8((dev->mem_start >> 8) & 0xff, - lp->virt_addr + DATA_PORT + 1); - } -#endif /* CS89x0_NONISA_IRQ */ - - /* Wait until the chip is reset */ - reset_start_time = jiffies; - while ((readreg(dev, PP_SelfST) & INIT_DONE) == 0 && - jiffies - reset_start_time < 2) - ; -#endif /* !CONFIG_MACH_MX31ADS */ -} +/* The typical workload of the driver: + Handle the network interface interrupts. */ -/* This is the real probe routine. - * Linux has a history of friendly device probes on the ISA bus. - * A good device probes avoids doing writes, and - * verifies that the correct device exists and functions. - * Return 0 on success. - */ -static int __init -cs89x0_probe1(struct net_device *dev, void __iomem *ioaddr, int modular) +static irqreturn_t net_interrupt(int irq, void *dev_id) { - struct net_local *lp = netdev_priv(dev); - int i; - int tmp; - unsigned rev_type = 0; - int eeprom_buff[CHKSUM_LEN]; - int retval; - - /* Initialize the device structure. */ - if (!modular) { - memset(lp, 0, sizeof(*lp)); - spin_lock_init(&lp->lock); -#ifndef MODULE -#if ALLOW_DMA - if (g_cs89x0_dma) { - lp->use_dma = 1; - lp->dma = g_cs89x0_dma; - lp->dmasize = 16; /* Could make this an option... */ - } -#endif - lp->force = g_cs89x0_media__force; -#endif - } - - pr_debug("PP_addr at %p[%x]: 0x%x\n", - ioaddr, ADD_PORT, ioread16(ioaddr + ADD_PORT)); - iowrite16(PP_ChipID, ioaddr + ADD_PORT); - - tmp = ioread16(ioaddr + DATA_PORT); - if (tmp != CHIP_EISA_ID_SIG) { - pr_debug("%s: incorrect signature at %p[%x]: 0x%x!=" - CHIP_EISA_ID_SIG_STR "\n", - dev->name, ioaddr, DATA_PORT, tmp); - retval = -ENODEV; - goto out1; - } - - lp->virt_addr = ioaddr; - - /* get the chip type */ - rev_type = readreg(dev, PRODUCT_ID_ADD); - lp->chip_type = rev_type & ~REVISON_BITS; - lp->chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A'; - - /* Check the chip type and revision in order to set the correct - * send command. CS8920 revision C and CS8900 revision F can use - * the faster send. - */ - lp->send_cmd = TX_AFTER_381; - if (lp->chip_type == CS8900 && lp->chip_revision >= 'F') - lp->send_cmd = TX_NOW; - if (lp->chip_type != CS8900 && lp->chip_revision >= 'C') - lp->send_cmd = TX_NOW; - - pr_info_once("%s\n", version); - - pr_info("%s: cs89%c0%s rev %c found at %p ", - dev->name, - lp->chip_type == CS8900 ? '0' : '2', - lp->chip_type == CS8920M ? "M" : "", - lp->chip_revision, - lp->virt_addr); - - reset_chip(dev); - - /* Here we read the current configuration of the chip. - * If there is no Extended EEPROM then the idea is to not disturb - * the chip configuration, it should have been correctly setup by - * automatic EEPROM read on reset. So, if the chip says it read - * the EEPROM the driver will always do *something* instead of - * complain that adapter_cnf is 0. - */ - - if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) == - (EEPROM_OK | EEPROM_PRESENT)) { - /* Load the MAC. */ - for (i = 0; i < ETH_ALEN / 2; i++) { - unsigned int Addr; - Addr = readreg(dev, PP_IA + i * 2); - dev->dev_addr[i * 2] = Addr & 0xFF; - dev->dev_addr[i * 2 + 1] = Addr >> 8; - } - - /* Load the Adapter Configuration. - * Note: Barring any more specific information from some - * other source (ie EEPROM+Schematics), we would not know - * how to operate a 10Base2 interface on the AUI port. - * However, since we do read the status of HCB1 and use - * settings that always result in calls to control_dc_dc(dev,0) - * a BNC interface should work if the enable pin - * (dc/dc converter) is on HCB1. - * It will be called AUI however. - */ - - lp->adapter_cnf = 0; - i = readreg(dev, PP_LineCTL); - /* Preserve the setting of the HCB1 pin. */ - if ((i & (HCB1 | HCB1_ENBL)) == (HCB1 | HCB1_ENBL)) - lp->adapter_cnf |= A_CNF_DC_DC_POLARITY; - /* Save the sqelch bit */ - if ((i & LOW_RX_SQUELCH) == LOW_RX_SQUELCH) - lp->adapter_cnf |= A_CNF_EXTND_10B_2 | A_CNF_LOW_RX_SQUELCH; - /* Check if the card is in 10Base-t only mode */ - if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == 0) - lp->adapter_cnf |= A_CNF_10B_T | A_CNF_MEDIA_10B_T; - /* Check if the card is in AUI only mode */ - if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == AUI_ONLY) - lp->adapter_cnf |= A_CNF_AUI | A_CNF_MEDIA_AUI; - /* Check if the card is in Auto mode. */ - if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == AUTO_AUI_10BASET) - lp->adapter_cnf |= A_CNF_AUI | A_CNF_10B_T | - A_CNF_MEDIA_AUI | A_CNF_MEDIA_10B_T | A_CNF_MEDIA_AUTO; - - cs89_dbg(1, info, "%s: PP_LineCTL=0x%x, adapter_cnf=0x%x\n", - dev->name, i, lp->adapter_cnf); + struct net_device *dev = dev_id; + struct net_local *lp; + int ioaddr, status; + int handled = 0; - /* IRQ. Other chips already probe, see below. */ - if (lp->chip_type == CS8900) - lp->isa_config = readreg(dev, PP_CS8900_ISAINT) & INT_NO_MASK; + ioaddr = dev->base_addr; + lp = netdev_priv(dev); - pr_cont("[Cirrus EEPROM] "); + /* we MUST read all the events out of the ISQ, otherwise we'll never + get interrupted again. As a consequence, we can't have any limit + on the number of times we loop in the interrupt handler. The + hardware guarantees that eventually we'll run out of events. Of + course, if you're on a slow machine, and packets are arriving + faster than you can read them off, you're screwed. Hasta la + vista, baby! */ + while ((status = readword(dev->base_addr, ISQ_PORT))) { + if (net_debug > 4)printk("%s: event=%04x\n", dev->name, status); + handled = 1; + switch(status & ISQ_EVENT_MASK) { + case ISQ_RECEIVER_EVENT: + /* Got a packet(s). */ + net_rx(dev); + break; + case ISQ_TRANSMITTER_EVENT: + dev->stats.tx_packets++; + netif_wake_queue(dev); /* Inform upper layers. */ + if ((status & ( TX_OK | + TX_LOST_CRS | + TX_SQE_ERROR | + TX_LATE_COL | + TX_16_COL)) != TX_OK) { + if ((status & TX_OK) == 0) + dev->stats.tx_errors++; + if (status & TX_LOST_CRS) + dev->stats.tx_carrier_errors++; + if (status & TX_SQE_ERROR) + dev->stats.tx_heartbeat_errors++; + if (status & TX_LATE_COL) + dev->stats.tx_window_errors++; + if (status & TX_16_COL) + dev->stats.tx_aborted_errors++; + } + break; + case ISQ_BUFFER_EVENT: + if (status & READY_FOR_TX) { + /* we tried to transmit a packet earlier, + but inexplicably ran out of buffers. + That shouldn't happen since we only ever + load one packet. Shrug. Do the right + thing anyway. */ + netif_wake_queue(dev); /* Inform upper layers. */ + } + if (status & TX_UNDERRUN) { + if (net_debug > 0) printk("%s: transmit underrun\n", dev->name); + lp->send_underrun++; + if (lp->send_underrun == 3) lp->send_cmd = TX_AFTER_381; + else if (lp->send_underrun == 6) lp->send_cmd = TX_AFTER_ALL; + /* transmit cycle is done, although + frame wasn't transmitted - this + avoids having to wait for the upper + layers to timeout on us, in the + event of a tx underrun */ + netif_wake_queue(dev); /* Inform upper layers. */ + } +#if ALLOW_DMA + if (lp->use_dma && (status & RX_DMA)) { + int count = readreg(dev, PP_DmaFrameCnt); + while(count) { + if (net_debug > 5) + printk("%s: receiving %d DMA frames\n", dev->name, count); + if (net_debug > 2 && count >1) + printk("%s: receiving %d DMA frames\n", dev->name, count); + dma_rx(dev); + if (--count == 0) + count = readreg(dev, PP_DmaFrameCnt); + if (net_debug > 2 && count > 0) + printk("%s: continuing with %d DMA frames\n", dev->name, count); + } + } +#endif + break; + case ISQ_RX_MISS_EVENT: + dev->stats.rx_missed_errors += (status >> 6); + break; + case ISQ_TX_COL_EVENT: + dev->stats.collisions += (status >> 6); + break; + } } + return IRQ_RETVAL(handled); +} - pr_cont("\n"); - - /* First check to see if an EEPROM is attached. */ +static void +count_rx_errors(int status, struct net_device *dev) +{ + dev->stats.rx_errors++; + if (status & RX_RUNT) + dev->stats.rx_length_errors++; + if (status & RX_EXTRA_DATA) + dev->stats.rx_length_errors++; + if ((status & RX_CRC_ERROR) && !(status & (RX_EXTRA_DATA|RX_RUNT))) + /* per str 172 */ + dev->stats.rx_crc_errors++; + if (status & RX_DRIBBLE) + dev->stats.rx_frame_errors++; +} - if ((readreg(dev, PP_SelfST) & EEPROM_PRESENT) == 0) - pr_warn("No EEPROM, relying on command line....\n"); - else if (get_eeprom_data(dev, START_EEPROM_DATA, CHKSUM_LEN, eeprom_buff) < 0) { - pr_warn("EEPROM read failed, relying on command line\n"); - } else if (get_eeprom_cksum(START_EEPROM_DATA, CHKSUM_LEN, eeprom_buff) < 0) { - /* Check if the chip was able to read its own configuration starting - at 0 in the EEPROM*/ - if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) != - (EEPROM_OK | EEPROM_PRESENT)) - pr_warn("Extended EEPROM checksum bad and no Cirrus EEPROM, relying on command line\n"); +/* We have a good packet(s), get it/them out of the buffers. */ +static void +net_rx(struct net_device *dev) +{ + struct sk_buff *skb; + int status, length; - } else { - /* This reads an extended EEPROM that is not documented - * in the CS8900 datasheet. - */ + int ioaddr = dev->base_addr; + status = readword(ioaddr, RX_FRAME_PORT); + length = readword(ioaddr, RX_FRAME_PORT); - /* get transmission control word but keep the autonegotiation bits */ - if (!lp->auto_neg_cnf) - lp->auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET / 2]; - /* Store adapter configuration */ - if (!lp->adapter_cnf) - lp->adapter_cnf = eeprom_buff[ADAPTER_CNF_OFFSET / 2]; - /* Store ISA configuration */ - lp->isa_config = eeprom_buff[ISA_CNF_OFFSET / 2]; - dev->mem_start = eeprom_buff[PACKET_PAGE_OFFSET / 2] << 8; - - /* eeprom_buff has 32-bit ints, so we can't just memcpy it */ - /* store the initial memory base address */ - for (i = 0; i < ETH_ALEN / 2; i++) { - dev->dev_addr[i * 2] = eeprom_buff[i]; - dev->dev_addr[i * 2 + 1] = eeprom_buff[i] >> 8; - } - cs89_dbg(1, debug, "%s: new adapter_cnf: 0x%x\n", - dev->name, lp->adapter_cnf); + if ((status & RX_OK) == 0) { + count_rx_errors(status, dev); + return; } - /* allow them to force multiple transceivers. If they force multiple, autosense */ - { - int count = 0; - if (lp->force & FORCE_RJ45) { - lp->adapter_cnf |= A_CNF_10B_T; - count++; - } - if (lp->force & FORCE_AUI) { - lp->adapter_cnf |= A_CNF_AUI; - count++; - } - if (lp->force & FORCE_BNC) { - lp->adapter_cnf |= A_CNF_10B_2; - count++; - } - if (count > 1) - lp->adapter_cnf |= A_CNF_MEDIA_AUTO; - else if (lp->force & FORCE_RJ45) - lp->adapter_cnf |= A_CNF_MEDIA_10B_T; - else if (lp->force & FORCE_AUI) - lp->adapter_cnf |= A_CNF_MEDIA_AUI; - else if (lp->force & FORCE_BNC) - lp->adapter_cnf |= A_CNF_MEDIA_10B_2; + /* Malloc up new buffer. */ + skb = netdev_alloc_skb(dev, length + 2); + if (skb == NULL) { +#if 0 /* Again, this seems a cruel thing to do */ + printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name); +#endif + dev->stats.rx_dropped++; + return; } + skb_reserve(skb, 2); /* longword align L3 header */ - cs89_dbg(1, debug, "%s: after force 0x%x, adapter_cnf=0x%x\n", - dev->name, lp->force, lp->adapter_cnf); - - /* FIXME: We don't let you set dc-dc polarity or low RX squelch from the command line: add it here */ - - /* FIXME: We don't let you set the IMM bit from the command line: add it to lp->auto_neg_cnf here */ - - /* FIXME: we don't set the Ethernet address on the command line. Use - * ifconfig IFACE hw ether AABBCCDDEEFF - */ - - pr_info("media %s%s%s", - (lp->adapter_cnf & A_CNF_10B_T) ? "RJ-45," : "", - (lp->adapter_cnf & A_CNF_AUI) ? "AUI," : "", - (lp->adapter_cnf & A_CNF_10B_2) ? "BNC," : ""); - - lp->irq_map = 0xffff; + readwords(ioaddr, RX_FRAME_PORT, skb_put(skb, length), length >> 1); + if (length & 1) + skb->data[length-1] = readword(ioaddr, RX_FRAME_PORT); - /* If this is a CS8900 then no pnp soft */ - if (lp->chip_type != CS8900 && - /* Check if the ISA IRQ has been set */ - (i = readreg(dev, PP_CS8920_ISAINT) & 0xff, - (i != 0 && i < CS8920_NO_INTS))) { - if (!dev->irq) - dev->irq = i; - } else { - i = lp->isa_config & INT_NO_MASK; -#ifndef CONFIG_CS89x0_PLATFORM - if (lp->chip_type == CS8900) { -#ifdef CS89x0_NONISA_IRQ - i = cs8900_irq_map[0]; -#else - /* Translate the IRQ using the IRQ mapping table. */ - if (i >= ARRAY_SIZE(cs8900_irq_map)) - pr_err("invalid ISA interrupt number %d\n", i); - else - i = cs8900_irq_map[i]; + if (net_debug > 3) { + printk( "%s: received %d byte packet of type %x\n", + dev->name, length, + (skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]); + } - lp->irq_map = CS8900_IRQ_MAP; /* fixed IRQ map for CS8900 */ - } else { - int irq_map_buff[IRQ_MAP_LEN/2]; + skb->protocol=eth_type_trans(skb,dev); + netif_rx(skb); + dev->stats.rx_packets++; + dev->stats.rx_bytes += length; +} - if (get_eeprom_data(dev, IRQ_MAP_EEPROM_DATA, - IRQ_MAP_LEN / 2, - irq_map_buff) >= 0) { - if ((irq_map_buff[0] & 0xff) == PNP_IRQ_FRMT) - lp->irq_map = ((irq_map_buff[0] >> 8) | - (irq_map_buff[1] << 8)); - } -#endif - } -#endif - if (!dev->irq) - dev->irq = i; +#if ALLOW_DMA +static void release_dma_buff(struct net_local *lp) +{ + if (lp->dma_buff) { + free_pages((unsigned long)(lp->dma_buff), get_order(lp->dmasize * 1024)); + lp->dma_buff = NULL; } +} +#endif - pr_cont(" IRQ %d", dev->irq); - +/* The inverse routine to net_open(). */ +static int +net_close(struct net_device *dev) +{ #if ALLOW_DMA - if (lp->use_dma) { - get_dma_channel(dev); - pr_cont(", DMA %d", dev->dma); - } else + struct net_local *lp = netdev_priv(dev); #endif - pr_cont(", programmed I/O"); - /* print the ethernet address. */ - pr_cont(", MAC %pM\n", dev->dev_addr); + netif_stop_queue(dev); - dev->netdev_ops = &net_ops; - dev->watchdog_timeo = HZ; + writereg(dev, PP_RxCFG, 0); + writereg(dev, PP_TxCFG, 0); + writereg(dev, PP_BufCFG, 0); + writereg(dev, PP_BusCTL, 0); - cs89_dbg(0, info, "cs89x0_probe1() successful\n"); + free_irq(dev->irq, dev); - retval = register_netdev(dev); - if (retval) - goto out2; +#if ALLOW_DMA + if (lp->use_dma && lp->dma) { + free_dma(dev->dma); + release_dma_buff(lp); + } +#endif + + /* Update the statistics here. */ return 0; -out2: - iowrite16(PP_ChipID, lp->virt_addr + ADD_PORT); -out1: - return retval; } -#ifndef CONFIG_CS89x0_PLATFORM -/* - * This function converts the I/O port addres used by the cs89x0_probe() and - * init_module() functions to the I/O memory address used by the - * cs89x0_probe1() function. - */ -static int __init -cs89x0_ioport_probe(struct net_device *dev, unsigned long ioport, int modular) +/* Get the current statistics. This may be called with the card open or + closed. */ +static struct net_device_stats * +net_get_stats(struct net_device *dev) { struct net_local *lp = netdev_priv(dev); - int ret; - void __iomem *io_mem; + unsigned long flags; - if (!lp) - return -ENOMEM; + spin_lock_irqsave(&lp->lock, flags); + /* Update the statistics from the device registers. */ + dev->stats.rx_missed_errors += (readreg(dev, PP_RxMiss) >> 6); + dev->stats.collisions += (readreg(dev, PP_TxCol) >> 6); + spin_unlock_irqrestore(&lp->lock, flags); - dev->base_addr = ioport; + return &dev->stats; +} - if (!request_region(ioport, NETCARD_IO_EXTENT, DRV_NAME)) { - ret = -EBUSY; - goto out; - } +static void set_multicast_list(struct net_device *dev) +{ + struct net_local *lp = netdev_priv(dev); + unsigned long flags; - io_mem = ioport_map(ioport & ~3, NETCARD_IO_EXTENT); - if (!io_mem) { - ret = -ENOMEM; - goto release; + spin_lock_irqsave(&lp->lock, flags); + if(dev->flags&IFF_PROMISC) + { + lp->rx_mode = RX_ALL_ACCEPT; } - - /* if they give us an odd I/O address, then do ONE write to - * the address port, to get it back to address zero, where we - * expect to find the EISA signature word. An IO with a base of 0x3 - * will skip the test for the ADD_PORT. - */ - if (ioport & 1) { - cs89_dbg(1, info, "%s: odd ioaddr 0x%lx\n", dev->name, ioport); - if ((ioport & 2) != 2) { - if ((ioread16(io_mem + ADD_PORT) & ADD_MASK) != - ADD_SIG) { - pr_err("%s: bad signature 0x%x\n", - dev->name, ioread16(io_mem + ADD_PORT)); - ret = -ENODEV; - goto unmap; - } - } + else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev)) + { + /* The multicast-accept list is initialized to accept-all, and we + rely on higher-level filtering for now. */ + lp->rx_mode = RX_MULTCAST_ACCEPT; } + else + lp->rx_mode = 0; - ret = cs89x0_probe1(dev, io_mem, modular); - if (!ret) - goto out; -unmap: - ioport_unmap(io_mem); -release: - release_region(ioport, NETCARD_IO_EXTENT); -out: - return ret; + writereg(dev, PP_RxCTL, DEF_RX_ACCEPT | lp->rx_mode); + + /* in promiscuous mode, we accept errored packets, so we have to enable interrupts on them also */ + writereg(dev, PP_RxCFG, lp->curr_rx_cfg | + (lp->rx_mode == RX_ALL_ACCEPT? (RX_CRC_ERROR_ENBL|RX_RUNT_ENBL|RX_EXTRA_DATA_ENBL) : 0)); + spin_unlock_irqrestore(&lp->lock, flags); } -#ifndef MODULE -/* Check for a network adaptor of this type, and return '0' iff one exists. - * If dev->base_addr == 0, probe all likely locations. - * If dev->base_addr == 1, always return failure. - * If dev->base_addr == 2, allocate space for the device and return success - * (detachable devices only). - * Return 0 on success. - */ -struct net_device * __init cs89x0_probe(int unit) +static int set_mac_address(struct net_device *dev, void *p) { - struct net_device *dev = alloc_etherdev(sizeof(struct net_local)); - unsigned *port; - int err = 0; - int irq; - int io; + int i; + struct sockaddr *addr = p; - if (!dev) - return ERR_PTR(-ENODEV); + if (netif_running(dev)) + return -EBUSY; - sprintf(dev->name, "eth%d", unit); - netdev_boot_setup_check(dev); - io = dev->base_addr; - irq = dev->irq; + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - cs89_dbg(0, info, "cs89x0_probe(0x%x)\n", io); + if (net_debug) + printk("%s: Setting MAC address to %pM.\n", + dev->name, dev->dev_addr); - if (io > 0x1ff) { /* Check a single specified location. */ - err = cs89x0_ioport_probe(dev, io, 0); - } else if (io != 0) { /* Don't probe at all. */ - err = -ENXIO; - } else { - for (port = netcard_portlist; *port; port++) { - if (cs89x0_ioport_probe(dev, *port, 0) == 0) - break; - dev->irq = irq; - } - if (!*port) - err = -ENODEV; - } - if (err) - goto out; - return dev; -out: - free_netdev(dev); - pr_warn("no cs8900 or cs8920 detected. Be sure to disable PnP with SETUP\n"); - return ERR_PTR(err); + /* set the Ethernet address */ + for (i=0; i < ETH_ALEN/2; i++) + writereg(dev, PP_IA+i*2, dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] << 8)); + + return 0; } -#endif -#endif #if defined(MODULE) && !defined(CONFIG_CS89x0_PLATFORM) static struct net_device *dev_cs89x0; -/* Support the 'debug' module parm even if we're compiled for non-debug to +/* + * Support the 'debug' module parm even if we're compiled for non-debug to * avoid breaking someone's startup scripts */ @@ -1755,11 +1764,11 @@ static int io; static int irq; static int debug; static char media[8]; -static int duplex = -1; +static int duplex=-1; static int use_dma; /* These generate unused var warnings if ALLOW_DMA = 0 */ static int dma; -static int dmasize = 16; /* or 64 */ +static int dmasize=16; /* or 64 */ module_param(io, int, 0); module_param(irq, int, 0); @@ -1792,28 +1801,32 @@ MODULE_PARM_DESC(use_dma , "(ignored)"); MODULE_AUTHOR("Mike Cruse, Russwll Nelson , Andrew Morton"); MODULE_LICENSE("GPL"); + /* - * media=t - specify media type - * or media=2 - * or media=aui - * or medai=auto - * duplex=0 - specify forced half/full/autonegotiate duplex - * debug=# - debug level - * - * Default Chip Configuration: - * DMA Burst = enabled - * IOCHRDY Enabled = enabled - * UseSA = enabled - * CS8900 defaults to half-duplex if not specified on command-line - * CS8920 defaults to autoneg if not specified on command-line - * Use reset defaults for other config parameters - * - * Assumptions: - * media type specified is supported (circuitry is present) - * if memory address is > 1MB, then required mem decode hw is present - * if 10B-2, then agent other than driver will enable DC/DC converter - * (hw or software util) - */ +* media=t - specify media type + or media=2 + or media=aui + or medai=auto +* duplex=0 - specify forced half/full/autonegotiate duplex +* debug=# - debug level + + +* Default Chip Configuration: + * DMA Burst = enabled + * IOCHRDY Enabled = enabled + * UseSA = enabled + * CS8900 defaults to half-duplex if not specified on command-line + * CS8920 defaults to autoneg if not specified on command-line + * Use reset defaults for other config parameters + +* Assumptions: + * media type specified is supported (circuitry is present) + * if memory address is > 1MB, then required mem decode hw is present + * if 10B-2, then agent other than driver will enable DC/DC converter + (hw or software util) + + +*/ int __init init_module(void) { @@ -1843,8 +1856,8 @@ int __init init_module(void) spin_lock_init(&lp->lock); - /* boy, they'd better get these right */ - if (!strcmp(media, "rj45")) + /* boy, they'd better get these right */ + if (!strcmp(media, "rj45")) lp->adapter_cnf = A_CNF_MEDIA_10B_T | A_CNF_10B_T; else if (!strcmp(media, "aui")) lp->adapter_cnf = A_CNF_MEDIA_AUI | A_CNF_AUI; @@ -1853,28 +1866,27 @@ int __init init_module(void) else lp->adapter_cnf = A_CNF_MEDIA_10B_T | A_CNF_10B_T; - if (duplex == -1) + if (duplex==-1) lp->auto_neg_cnf = AUTO_NEG_ENABLE; - if (io == 0) { - pr_err("Module autoprobing not allowed\n"); - pr_err("Append io=0xNNN\n"); - ret = -EPERM; + if (io == 0) { + printk(KERN_ERR "cs89x0.c: Module autoprobing not allowed.\n"); + printk(KERN_ERR "cs89x0.c: Append io=0xNNN\n"); + ret = -EPERM; goto out; - } else if (io <= 0x1ff) { + } else if (io <= 0x1ff) { ret = -ENXIO; goto out; } #if ALLOW_DMA if (use_dma && dmasize != 16 && dmasize != 64) { - pr_err("dma size must be either 16K or 64K, not %dK\n", - dmasize); + printk(KERN_ERR "cs89x0.c: dma size must be either 16K or 64K, not %dK\n", dmasize); ret = -EPERM; goto out; } #endif - ret = cs89x0_ioport_probe(dev, io, 1); + ret = cs89x0_probe1(dev, io, 1); if (ret) goto out; @@ -1888,11 +1900,8 @@ int __init init_module(void) void __exit cleanup_module(void) { - struct net_local *lp = netdev_priv(dev_cs89x0); - unregister_netdev(dev_cs89x0); - iowrite16(PP_ChipID, lp->virt_addr + ADD_PORT); - ioport_unmap(lp->virt_addr); + writeword(dev_cs89x0->base_addr, ADD_PORT, PP_ChipID); release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT); free_netdev(dev_cs89x0); } @@ -1904,7 +1913,6 @@ static int __init cs89x0_platform_probe(struct platform_device *pdev) struct net_device *dev = alloc_etherdev(sizeof(struct net_local)); struct net_local *lp; struct resource *mem_res; - void __iomem *virt_addr; int err; if (!dev) @@ -1915,28 +1923,29 @@ static int __init cs89x0_platform_probe(struct platform_device *pdev) mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); dev->irq = platform_get_irq(pdev, 0); if (mem_res == NULL || dev->irq <= 0) { - dev_warn(&dev->dev, "memory/interrupt resource missing\n"); + dev_warn(&dev->dev, "memory/interrupt resource missing.\n"); err = -ENXIO; goto free; } + lp->phys_addr = mem_res->start; lp->size = resource_size(mem_res); - if (!request_mem_region(mem_res->start, lp->size, DRV_NAME)) { - dev_warn(&dev->dev, "request_mem_region() failed\n"); + if (!request_mem_region(lp->phys_addr, lp->size, DRV_NAME)) { + dev_warn(&dev->dev, "request_mem_region() failed.\n"); err = -EBUSY; goto free; } - virt_addr = ioremap(mem_res->start, lp->size); - if (!virt_addr) { - dev_warn(&dev->dev, "ioremap() failed\n"); + lp->virt_addr = ioremap(lp->phys_addr, lp->size); + if (!lp->virt_addr) { + dev_warn(&dev->dev, "ioremap() failed.\n"); err = -ENOMEM; goto release; } - err = cs89x0_probe1(dev, virt_addr, 0); + err = cs89x0_probe1(dev, (unsigned long)lp->virt_addr, 0); if (err) { - dev_warn(&dev->dev, "no cs8900 or cs8920 detected\n"); + dev_warn(&dev->dev, "no cs8900 or cs8920 detected.\n"); goto unmap; } @@ -1944,9 +1953,9 @@ static int __init cs89x0_platform_probe(struct platform_device *pdev) return 0; unmap: - iounmap(virt_addr); + iounmap(lp->virt_addr); release: - release_mem_region(mem_res->start, lp->size); + release_mem_region(lp->phys_addr, lp->size); free: free_netdev(dev); return err; @@ -1956,16 +1965,10 @@ static int cs89x0_platform_remove(struct platform_device *pdev) { struct net_device *dev = platform_get_drvdata(pdev); struct net_local *lp = netdev_priv(dev); - struct resource *mem_res; - /* This platform_get_resource() call will not return NULL, because - * the same call in cs89x0_platform_probe() has returned a non NULL - * value. - */ - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); unregister_netdev(dev); iounmap(lp->virt_addr); - release_mem_region(mem_res->start, lp->size); + release_mem_region(lp->phys_addr, lp->size); free_netdev(dev); return 0; } @@ -1993,3 +1996,13 @@ static void __exit cs89x0_cleanup(void) module_exit(cs89x0_cleanup); #endif /* CONFIG_CS89x0_PLATFORM */ + +/* + * Local variables: + * version-control: t + * kept-new-versions: 5 + * c-indent-level: 8 + * tab-width: 8 + * End: + * + */ diff --git a/trunk/drivers/net/ethernet/cisco/enic/enic_main.c b/trunk/drivers/net/ethernet/cisco/enic/enic_main.c index 8132c785cea8..d7ac6c17547c 100644 --- a/trunk/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/trunk/drivers/net/ethernet/cisco/enic/enic_main.c @@ -944,7 +944,8 @@ static void enic_update_multicast_addr_list(struct enic *enic) for (i = 0; i < enic->mc_count; i++) { for (j = 0; j < mc_count; j++) - if (ether_addr_equal(enic->mc_addr[i], mc_addr[j])) + if (compare_ether_addr(enic->mc_addr[i], + mc_addr[j]) == 0) break; if (j == mc_count) enic_dev_del_addr(enic, enic->mc_addr[i]); @@ -952,7 +953,8 @@ static void enic_update_multicast_addr_list(struct enic *enic) for (i = 0; i < mc_count; i++) { for (j = 0; j < enic->mc_count; j++) - if (ether_addr_equal(mc_addr[i], enic->mc_addr[j])) + if (compare_ether_addr(mc_addr[i], + enic->mc_addr[j]) == 0) break; if (j == enic->mc_count) enic_dev_add_addr(enic, mc_addr[i]); @@ -997,7 +999,8 @@ static void enic_update_unicast_addr_list(struct enic *enic) for (i = 0; i < enic->uc_count; i++) { for (j = 0; j < uc_count; j++) - if (ether_addr_equal(enic->uc_addr[i], uc_addr[j])) + if (compare_ether_addr(enic->uc_addr[i], + uc_addr[j]) == 0) break; if (j == uc_count) enic_dev_del_addr(enic, enic->uc_addr[i]); @@ -1005,7 +1008,8 @@ static void enic_update_unicast_addr_list(struct enic *enic) for (i = 0; i < uc_count; i++) { for (j = 0; j < enic->uc_count; j++) - if (ether_addr_equal(uc_addr[i], enic->uc_addr[j])) + if (compare_ether_addr(uc_addr[i], + enic->uc_addr[j]) == 0) break; if (j == enic->uc_count) enic_dev_add_addr(enic, uc_addr[i]); diff --git a/trunk/drivers/net/ethernet/davicom/Kconfig b/trunk/drivers/net/ethernet/davicom/Kconfig index 9745fe5e8039..972b62b31837 100644 --- a/trunk/drivers/net/ethernet/davicom/Kconfig +++ b/trunk/drivers/net/ethernet/davicom/Kconfig @@ -4,7 +4,7 @@ config DM9000 tristate "DM9000 support" - depends on ARM || BLACKFIN || MIPS || COLDFIRE + depends on ARM || BLACKFIN || MIPS select CRC32 select NET_CORE select MII diff --git a/trunk/drivers/net/ethernet/dec/ewrk3.c b/trunk/drivers/net/ethernet/dec/ewrk3.c index 17ae8c619680..1879f84a25a3 100644 --- a/trunk/drivers/net/ethernet/dec/ewrk3.c +++ b/trunk/drivers/net/ethernet/dec/ewrk3.c @@ -1016,8 +1016,7 @@ static int ewrk3_rx(struct net_device *dev) } else { lp->pktStats.multicast++; } - } else if (ether_addr_equal(p, - dev->dev_addr)) { + } else if (compare_ether_addr(p, dev->dev_addr) == 0) { lp->pktStats.unicast++; } lp->pktStats.bins[0]++; /* Duplicates stats.rx_packets */ diff --git a/trunk/drivers/net/ethernet/dec/tulip/de4x5.c b/trunk/drivers/net/ethernet/dec/tulip/de4x5.c index d3cd489d11a2..18b106cc6d2b 100644 --- a/trunk/drivers/net/ethernet/dec/tulip/de4x5.c +++ b/trunk/drivers/net/ethernet/dec/tulip/de4x5.c @@ -1874,7 +1874,7 @@ de4x5_local_stats(struct net_device *dev, char *buf, int pkt_len) } else { lp->pktStats.multicast++; } - } else if (ether_addr_equal(buf, dev->dev_addr)) { + } else if (compare_ether_addr(buf, dev->dev_addr) == 0) { lp->pktStats.unicast++; } diff --git a/trunk/drivers/net/ethernet/emulex/benet/Makefile b/trunk/drivers/net/ethernet/emulex/benet/Makefile index 1a91b276940d..a60cd8051135 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/Makefile +++ b/trunk/drivers/net/ethernet/emulex/benet/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_BE2NET) += be2net.o -be2net-y := be_main.o be_cmds.o be_ethtool.o be_roce.o +be2net-y := be_main.o be_cmds.o be_ethtool.o diff --git a/trunk/drivers/net/ethernet/emulex/benet/be.h b/trunk/drivers/net/ethernet/emulex/benet/be.h index c5c4c0e83bd1..c3ee9103ff4f 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be.h +++ b/trunk/drivers/net/ethernet/emulex/benet/be.h @@ -32,7 +32,6 @@ #include #include "be_hw.h" -#include "be_roce.h" #define DRV_VER "4.2.220u" #define DRV_NAME "be2net" @@ -103,8 +102,7 @@ static inline char *nic_name(struct pci_dev *pdev) #define MAX_RX_QS (MAX_RSS_QS + 1) /* RSS qs + 1 def Rx */ #define MAX_TX_QS 8 -#define MAX_ROCE_EQS 5 -#define MAX_MSIX_VECTORS (MAX_RSS_QS + MAX_ROCE_EQS) /* RSS qs + RoCE */ +#define MAX_MSIX_VECTORS MAX_RSS_QS #define BE_TX_BUDGET 256 #define BE_NAPI_WEIGHT 64 #define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */ @@ -315,11 +313,6 @@ struct be_vf_cfg { u32 tx_rate; }; -enum vf_state { - ENABLED = 0, - ASSIGNED = 1 -}; - #define BE_FLAGS_LINK_STATUS_INIT 1 #define BE_FLAGS_WORKER_SCHEDULED (1 << 3) #define BE_UC_PMAC_COUNT 30 @@ -407,23 +400,11 @@ struct be_adapter { u32 tx_fc; /* Tx flow control */ bool stats_cmd_sent; u8 generation; /* BladeEngine ASIC generation */ - u32 if_type; - struct { - u8 __iomem *base; /* Door Bell */ - u32 size; - u32 total_size; - u64 io_addr; - } roce_db; - u32 num_msix_roce_vec; - struct ocrdma_dev *ocrdma_dev; - struct list_head entry; - u32 flash_status; struct completion flash_compl; - u32 num_vfs; /* Number of VFs provisioned by PF driver */ - u32 dev_num_vfs; /* Number of VFs supported by HW */ - u8 virtfn; + u32 num_vfs; + u8 is_virtfn; struct be_vf_cfg *vf_cfg; bool be3_native; u32 sli_family; @@ -434,13 +415,10 @@ struct be_adapter { bool wol; u32 max_pmac_cnt; /* Max secondary UC MACs programmable */ u32 uc_macs; /* Count of secondary UC MAC programmed */ - u32 msg_enable; }; -#define be_physfn(adapter) (!adapter->virtfn) +#define be_physfn(adapter) (!adapter->is_virtfn) #define sriov_enabled(adapter) (adapter->num_vfs > 0) -#define sriov_want(adapter) (adapter->dev_num_vfs && num_vfs && \ - be_physfn(adapter)) #define for_all_vfs(adapter, vf_cfg, i) \ for (i = 0, vf_cfg = &adapter->vf_cfg[i]; i < adapter->num_vfs; \ i++, vf_cfg++) @@ -454,10 +432,6 @@ struct be_adapter { #define lancer_chip(adapter) ((adapter->pdev->device == OC_DEVICE_ID3) || \ (adapter->pdev->device == OC_DEVICE_ID4)) -#define be_roce_supported(adapter) ((adapter->if_type == SLI_INTF_TYPE_3 || \ - adapter->sli_family == SKYHAWK_SLI_FAMILY) && \ - (adapter->function_mode & RDMA_ENABLED)) - extern const struct ethtool_ops be_ethtool_ops; #define msix_enabled(adapter) (adapter->num_msix_vec > 0) @@ -573,6 +547,14 @@ static inline u8 is_udp_pkt(struct sk_buff *skb) return val; } +static inline void be_check_sriov_fn_type(struct be_adapter *adapter) +{ + u32 sli_intf; + + pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf); + adapter->is_virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0; +} + static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac) { u32 addr; @@ -614,12 +596,6 @@ static inline bool be_is_wol_excluded(struct be_adapter *adapter) } } -static inline bool be_type_2_3(struct be_adapter *adapter) -{ - return (adapter->if_type == SLI_INTF_TYPE_2 || - adapter->if_type == SLI_INTF_TYPE_3) ? true : false; -} - extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, u16 num_popped); extern void be_link_status_update(struct be_adapter *adapter, u8 link_status); @@ -627,18 +603,4 @@ extern void be_parse_stats(struct be_adapter *adapter); extern int be_load_fw(struct be_adapter *adapter, u8 *func); extern bool be_is_wol_supported(struct be_adapter *adapter); extern bool be_pause_supported(struct be_adapter *adapter); -extern u32 be_get_fw_log_level(struct be_adapter *adapter); - -/* - * internal function to initialize-cleanup roce device. - */ -extern void be_roce_dev_add(struct be_adapter *); -extern void be_roce_dev_remove(struct be_adapter *); - -/* - * internal function to open-close roce device during ifup-ifdown. - */ -extern void be_roce_dev_open(struct be_adapter *); -extern void be_roce_dev_close(struct be_adapter *); - #endif /* BE_H */ diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_cmds.c b/trunk/drivers/net/ethernet/emulex/benet/be_cmds.c index 8d06ea381741..43167e863955 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/trunk/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -15,7 +15,6 @@ * Costa Mesa, CA 92626 */ -#include #include "be.h" #include "be_cmds.h" @@ -2590,98 +2589,4 @@ int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter) mutex_unlock(&adapter->mbox_lock); pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma); return status; - -} -int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter, - struct be_dma_mem *cmd) -{ - struct be_mcc_wrb *wrb; - struct be_cmd_req_get_ext_fat_caps *req; - int status; - - if (mutex_lock_interruptible(&adapter->mbox_lock)) - return -1; - - wrb = wrb_from_mbox(adapter); - if (!wrb) { - status = -EBUSY; - goto err; - } - - req = cmd->va; - be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_GET_EXT_FAT_CAPABILITES, - cmd->size, wrb, cmd); - req->parameter_type = cpu_to_le32(1); - - status = be_mbox_notify_wait(adapter); -err: - mutex_unlock(&adapter->mbox_lock); - return status; -} - -int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter, - struct be_dma_mem *cmd, - struct be_fat_conf_params *configs) -{ - struct be_mcc_wrb *wrb; - struct be_cmd_req_set_ext_fat_caps *req; - int status; - - spin_lock_bh(&adapter->mcc_lock); - - wrb = wrb_from_mccq(adapter); - if (!wrb) { - status = -EBUSY; - goto err; - } - - req = cmd->va; - memcpy(&req->set_params, configs, sizeof(struct be_fat_conf_params)); - be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_SET_EXT_FAT_CAPABILITES, - cmd->size, wrb, cmd); - - status = be_mcc_notify_wait(adapter); -err: - spin_unlock_bh(&adapter->mcc_lock); - return status; -} - -int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload, - int wrb_payload_size, u16 *cmd_status, u16 *ext_status) -{ - struct be_adapter *adapter = netdev_priv(netdev_handle); - struct be_mcc_wrb *wrb; - struct be_cmd_req_hdr *hdr = (struct be_cmd_req_hdr *) wrb_payload; - struct be_cmd_req_hdr *req; - struct be_cmd_resp_hdr *resp; - int status; - - spin_lock_bh(&adapter->mcc_lock); - - wrb = wrb_from_mccq(adapter); - if (!wrb) { - status = -EBUSY; - goto err; - } - req = embedded_payload(wrb); - resp = embedded_payload(wrb); - - be_wrb_cmd_hdr_prepare(req, hdr->subsystem, - hdr->opcode, wrb_payload_size, wrb, NULL); - memcpy(req, wrb_payload, wrb_payload_size); - be_dws_cpu_to_le(req, wrb_payload_size); - - status = be_mcc_notify_wait(adapter); - if (cmd_status) - *cmd_status = (status & 0xffff); - if (ext_status) - *ext_status = 0; - memcpy(wrb_payload, resp, sizeof(*resp) + resp->response_length); - be_dws_le_to_cpu(wrb_payload, sizeof(*resp) + resp->response_length); -err: - spin_unlock_bh(&adapter->mcc_lock); - return status; } -EXPORT_SYMBOL(be_roce_mcc_cmd); diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_cmds.h b/trunk/drivers/net/ethernet/emulex/benet/be_cmds.h index 9625bf420c16..944f031bd31e 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/trunk/drivers/net/ethernet/emulex/benet/be_cmds.h @@ -189,8 +189,6 @@ struct be_mcc_mailbox { #define OPCODE_COMMON_GET_PHY_DETAILS 102 #define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP 103 #define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121 -#define OPCODE_COMMON_GET_EXT_FAT_CAPABILITES 125 -#define OPCODE_COMMON_SET_EXT_FAT_CAPABILITES 126 #define OPCODE_COMMON_GET_MAC_LIST 147 #define OPCODE_COMMON_SET_MAC_LIST 148 #define OPCODE_COMMON_GET_HSW_CONFIG 152 @@ -1062,7 +1060,6 @@ struct be_cmd_resp_modify_eq_delay { /* The HW can come up in either of the following multi-channel modes * based on the skew/IPL. */ -#define RDMA_ENABLED 0x4 #define FLEX10_MODE 0x400 #define VNIC_MODE 0x20000 #define UMC_ENABLED 0x1000000 @@ -1605,56 +1602,6 @@ static inline void *be_erx_stats_from_cmd(struct be_adapter *adapter) } } - -/************** get fat capabilites *******************/ -#define MAX_MODULES 27 -#define MAX_MODES 4 -#define MODE_UART 0 -#define FW_LOG_LEVEL_DEFAULT 48 -#define FW_LOG_LEVEL_FATAL 64 - -struct ext_fat_mode { - u8 mode; - u8 rsvd0; - u16 port_mask; - u32 dbg_lvl; - u64 fun_mask; -} __packed; - -struct ext_fat_modules { - u8 modules_str[32]; - u32 modules_id; - u32 num_modes; - struct ext_fat_mode trace_lvl[MAX_MODES]; -} __packed; - -struct be_fat_conf_params { - u32 max_log_entries; - u32 log_entry_size; - u8 log_type; - u8 max_log_funs; - u8 max_log_ports; - u8 rsvd0; - u32 supp_modes; - u32 num_modules; - struct ext_fat_modules module[MAX_MODULES]; -} __packed; - -struct be_cmd_req_get_ext_fat_caps { - struct be_cmd_req_hdr hdr; - u32 parameter_type; -}; - -struct be_cmd_resp_get_ext_fat_caps { - struct be_cmd_resp_hdr hdr; - struct be_fat_conf_params get_params; -}; - -struct be_cmd_req_set_ext_fat_caps { - struct be_cmd_req_hdr hdr; - struct be_fat_conf_params set_params; -}; - extern int be_pci_fnum_get(struct be_adapter *adapter); extern int be_cmd_POST(struct be_adapter *adapter); extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, @@ -1760,9 +1707,4 @@ extern int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid, extern int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid, u32 domain, u16 intf_id); extern int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter); -extern int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter, - struct be_dma_mem *cmd); -extern int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter, - struct be_dma_mem *cmd, - struct be_fat_conf_params *cfgs); diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_ethtool.c b/trunk/drivers/net/ethernet/emulex/benet/be_ethtool.c index 63e51d476900..747f68fa976d 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_ethtool.c +++ b/trunk/drivers/net/ethernet/emulex/benet/be_ethtool.c @@ -878,81 +878,6 @@ be_read_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, return status; } -static u32 be_get_msg_level(struct net_device *netdev) -{ - struct be_adapter *adapter = netdev_priv(netdev); - - if (lancer_chip(adapter)) { - dev_err(&adapter->pdev->dev, "Operation not supported\n"); - return -EOPNOTSUPP; - } - - return adapter->msg_enable; -} - -static void be_set_fw_log_level(struct be_adapter *adapter, u32 level) -{ - struct be_dma_mem extfat_cmd; - struct be_fat_conf_params *cfgs; - int status; - int i, j; - - memset(&extfat_cmd, 0, sizeof(struct be_dma_mem)); - extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps); - extfat_cmd.va = pci_alloc_consistent(adapter->pdev, extfat_cmd.size, - &extfat_cmd.dma); - if (!extfat_cmd.va) { - dev_err(&adapter->pdev->dev, "%s: Memory allocation failure\n", - __func__); - goto err; - } - status = be_cmd_get_ext_fat_capabilites(adapter, &extfat_cmd); - if (!status) { - cfgs = (struct be_fat_conf_params *)(extfat_cmd.va + - sizeof(struct be_cmd_resp_hdr)); - for (i = 0; i < cfgs->num_modules; i++) { - for (j = 0; j < cfgs->module[i].num_modes; j++) { - if (cfgs->module[i].trace_lvl[j].mode == - MODE_UART) - cfgs->module[i].trace_lvl[j].dbg_lvl = - cpu_to_le32(level); - } - } - status = be_cmd_set_ext_fat_capabilites(adapter, &extfat_cmd, - cfgs); - if (status) - dev_err(&adapter->pdev->dev, - "Message level set failed\n"); - } else { - dev_err(&adapter->pdev->dev, "Message level get failed\n"); - } - - pci_free_consistent(adapter->pdev, extfat_cmd.size, extfat_cmd.va, - extfat_cmd.dma); -err: - return; -} - -static void be_set_msg_level(struct net_device *netdev, u32 level) -{ - struct be_adapter *adapter = netdev_priv(netdev); - - if (lancer_chip(adapter)) { - dev_err(&adapter->pdev->dev, "Operation not supported\n"); - return; - } - - if (adapter->msg_enable == level) - return; - - if ((level & NETIF_MSG_HW) != (adapter->msg_enable & NETIF_MSG_HW)) - be_set_fw_log_level(adapter, level & NETIF_MSG_HW ? - FW_LOG_LEVEL_DEFAULT : FW_LOG_LEVEL_FATAL); - adapter->msg_enable = level; - - return; -} - const struct ethtool_ops be_ethtool_ops = { .get_settings = be_get_settings, .get_drvinfo = be_get_drvinfo, @@ -968,8 +893,6 @@ const struct ethtool_ops be_ethtool_ops = { .set_pauseparam = be_set_pauseparam, .get_strings = be_get_stat_strings, .set_phys_id = be_set_phys_id, - .get_msglevel = be_get_msg_level, - .set_msglevel = be_set_msg_level, .get_sset_count = be_get_sset_count, .get_ethtool_stats = be_get_ethtool_stats, .get_regs_len = be_get_reg_len, diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_hw.h b/trunk/drivers/net/ethernet/emulex/benet/be_hw.h index d9fb0c501fa1..0949aa609164 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_hw.h +++ b/trunk/drivers/net/ethernet/emulex/benet/be_hw.h @@ -58,8 +58,6 @@ #define SLI_PORT_CONTROL_IP_MASK 0x08000000 -#define PCICFG_CUST_SCRATCHPAD_CSR 0x1EC - /********* Memory BAR register ************/ #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc /* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt @@ -100,13 +98,11 @@ #define SLI_INTF_REV_SHIFT 4 #define SLI_INTF_FT_MASK 0x00000001 -#define SLI_INTF_TYPE_2 2 -#define SLI_INTF_TYPE_3 3 /* SLI family */ #define BE_SLI_FAMILY 0x0 #define LANCER_A0_SLI_FAMILY 0xA -#define SKYHAWK_SLI_FAMILY 0x2 + /********* ISR0 Register offset **********/ #define CEV_ISR0_OFFSET 0xC18 diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_main.c b/trunk/drivers/net/ethernet/emulex/benet/be_main.c index 08efd308d78a..6d5d30be0481 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_main.c +++ b/trunk/drivers/net/ethernet/emulex/benet/be_main.c @@ -1049,29 +1049,6 @@ static int be_set_vf_tx_rate(struct net_device *netdev, return status; } -static int be_find_vfs(struct be_adapter *adapter, int vf_state) -{ - struct pci_dev *dev, *pdev = adapter->pdev; - int vfs = 0, assigned_vfs = 0, pos, vf_fn; - u16 offset, stride; - - pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); - pci_read_config_word(pdev, pos + PCI_SRIOV_VF_OFFSET, &offset); - pci_read_config_word(pdev, pos + PCI_SRIOV_VF_STRIDE, &stride); - - dev = pci_get_device(pdev->vendor, PCI_ANY_ID, NULL); - while (dev) { - vf_fn = (pdev->devfn + offset + stride * vfs) & 0xFFFF; - if (dev->is_virtfn && dev->devfn == vf_fn) { - vfs++; - if (dev->dev_flags & PCI_DEV_FLAGS_ASSIGNED) - assigned_vfs++; - } - dev = pci_get_device(pdev->vendor, PCI_ANY_ID, dev); - } - return (vf_state == ASSIGNED) ? assigned_vfs : vfs; -} - static void be_eqd_update(struct be_adapter *adapter, struct be_eq_obj *eqo) { struct be_rx_stats *stats = rx_stats(&adapter->rx_obj[eqo->idx]); @@ -1812,9 +1789,9 @@ static void be_tx_queues_destroy(struct be_adapter *adapter) static int be_num_txqs_want(struct be_adapter *adapter) { - if (sriov_want(adapter) || be_is_mc(adapter) || - lancer_chip(adapter) || !be_physfn(adapter) || - adapter->generation == BE_GEN2) + if (sriov_enabled(adapter) || be_is_mc(adapter) || + lancer_chip(adapter) || !be_physfn(adapter) || + adapter->generation == BE_GEN2) return 1; else return MAX_TX_QS; @@ -2141,7 +2118,7 @@ static void be_msix_disable(struct be_adapter *adapter) static uint be_num_rss_want(struct be_adapter *adapter) { if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) && - !sriov_want(adapter) && be_physfn(adapter) && + adapter->num_vfs == 0 && be_physfn(adapter) && !be_is_mc(adapter)) return (adapter->be3_native) ? BE3_MAX_RSS_QS : BE2_MAX_RSS_QS; else @@ -2151,17 +2128,10 @@ static uint be_num_rss_want(struct be_adapter *adapter) static void be_msix_enable(struct be_adapter *adapter) { #define BE_MIN_MSIX_VECTORS 1 - int i, status, num_vec, num_roce_vec = 0; + int i, status, num_vec; /* If RSS queues are not used, need a vec for default RX Q */ num_vec = min(be_num_rss_want(adapter), num_online_cpus()); - if (be_roce_supported(adapter)) { - num_roce_vec = min_t(u32, MAX_ROCE_MSIX_VECTORS, - (num_online_cpus() + 1)); - num_roce_vec = min(num_roce_vec, MAX_ROCE_EQS); - num_vec += num_roce_vec; - num_vec = min(num_vec, MAX_MSIX_VECTORS); - } num_vec = max(num_vec, BE_MIN_MSIX_VECTORS); for (i = 0; i < num_vec; i++) @@ -2178,20 +2148,57 @@ static void be_msix_enable(struct be_adapter *adapter) } return; done: - if (be_roce_supported(adapter)) { - if (num_vec > num_roce_vec) { - adapter->num_msix_vec = num_vec - num_roce_vec; - adapter->num_msix_roce_vec = - num_vec - adapter->num_msix_vec; - } else { - adapter->num_msix_vec = num_vec; - adapter->num_msix_roce_vec = 0; - } - } else - adapter->num_msix_vec = num_vec; + adapter->num_msix_vec = num_vec; return; } +static int be_sriov_enable(struct be_adapter *adapter) +{ + be_check_sriov_fn_type(adapter); + +#ifdef CONFIG_PCI_IOV + if (be_physfn(adapter) && num_vfs) { + int status, pos; + u16 dev_vfs; + + pos = pci_find_ext_capability(adapter->pdev, + PCI_EXT_CAP_ID_SRIOV); + pci_read_config_word(adapter->pdev, + pos + PCI_SRIOV_TOTAL_VF, &dev_vfs); + + adapter->num_vfs = min_t(u16, num_vfs, dev_vfs); + if (adapter->num_vfs != num_vfs) + dev_info(&adapter->pdev->dev, + "Device supports %d VFs and not %d\n", + adapter->num_vfs, num_vfs); + + status = pci_enable_sriov(adapter->pdev, adapter->num_vfs); + if (status) + adapter->num_vfs = 0; + + if (adapter->num_vfs) { + adapter->vf_cfg = kcalloc(num_vfs, + sizeof(struct be_vf_cfg), + GFP_KERNEL); + if (!adapter->vf_cfg) + return -ENOMEM; + } + } +#endif + return 0; +} + +static void be_sriov_disable(struct be_adapter *adapter) +{ +#ifdef CONFIG_PCI_IOV + if (sriov_enabled(adapter)) { + pci_disable_sriov(adapter->pdev); + kfree(adapter->vf_cfg); + adapter->num_vfs = 0; + } +#endif +} + static inline int be_msix_vec_get(struct be_adapter *adapter, struct be_eq_obj *eqo) { @@ -2300,8 +2307,6 @@ static int be_close(struct net_device *netdev) struct be_eq_obj *eqo; int i; - be_roce_dev_close(adapter); - be_async_mcc_disable(adapter); if (!lancer_chip(adapter)) @@ -2410,7 +2415,6 @@ static int be_open(struct net_device *netdev) if (!status) be_link_status_update(adapter, link_status); - be_roce_dev_open(adapter); return 0; err: be_close(adapter->netdev); @@ -2496,11 +2500,6 @@ static void be_vf_clear(struct be_adapter *adapter) struct be_vf_cfg *vf_cfg; u32 vf; - if (be_find_vfs(adapter, ASSIGNED)) { - dev_warn(&adapter->pdev->dev, "VFs are assigned to VMs\n"); - goto done; - } - for_all_vfs(adapter, vf_cfg, vf) { if (lancer_chip(adapter)) be_cmd_set_mac_list(adapter, NULL, 0, vf + 1); @@ -2510,10 +2509,6 @@ static void be_vf_clear(struct be_adapter *adapter) be_cmd_if_destroy(adapter, vf_cfg->if_handle, vf + 1); } - pci_disable_sriov(adapter->pdev); -done: - kfree(adapter->vf_cfg); - adapter->num_vfs = 0; } static int be_clear(struct be_adapter *adapter) @@ -2543,60 +2538,29 @@ static int be_clear(struct be_adapter *adapter) be_cmd_fw_clean(adapter); be_msix_disable(adapter); - pci_write_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, 0); + kfree(adapter->pmac_id); return 0; } -static int be_vf_setup_init(struct be_adapter *adapter) +static void be_vf_setup_init(struct be_adapter *adapter) { struct be_vf_cfg *vf_cfg; int vf; - adapter->vf_cfg = kcalloc(adapter->num_vfs, sizeof(*vf_cfg), - GFP_KERNEL); - if (!adapter->vf_cfg) - return -ENOMEM; - for_all_vfs(adapter, vf_cfg, vf) { vf_cfg->if_handle = -1; vf_cfg->pmac_id = -1; } - return 0; } static int be_vf_setup(struct be_adapter *adapter) { struct be_vf_cfg *vf_cfg; - struct device *dev = &adapter->pdev->dev; u32 cap_flags, en_flags, vf; u16 def_vlan, lnk_speed; - int status, enabled_vfs; - - enabled_vfs = be_find_vfs(adapter, ENABLED); - if (enabled_vfs) { - dev_warn(dev, "%d VFs are already enabled\n", enabled_vfs); - dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs); - return 0; - } - - if (num_vfs > adapter->dev_num_vfs) { - dev_warn(dev, "Device supports %d VFs and not %d\n", - adapter->dev_num_vfs, num_vfs); - num_vfs = adapter->dev_num_vfs; - } - - status = pci_enable_sriov(adapter->pdev, num_vfs); - if (!status) { - adapter->num_vfs = num_vfs; - } else { - /* Platform doesn't support SRIOV though device supports it */ - dev_warn(dev, "SRIOV enable failed\n"); - return 0; - } + int status; - status = be_vf_setup_init(adapter); - if (status) - goto err; + be_vf_setup_init(adapter); cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_MULTICAST; @@ -2607,11 +2571,9 @@ static int be_vf_setup(struct be_adapter *adapter) goto err; } - if (!enabled_vfs) { - status = be_vf_eth_addr_config(adapter); - if (status) - goto err; - } + status = be_vf_eth_addr_config(adapter); + if (status) + goto err; for_all_vfs(adapter, vf_cfg, vf) { status = be_cmd_link_status_query(adapter, NULL, &lnk_speed, @@ -2668,25 +2630,9 @@ static int be_add_mac_from_list(struct be_adapter *adapter, u8 *mac) return status; } -/* Routine to query per function resource limits */ -static int be_get_config(struct be_adapter *adapter) -{ - int pos; - u16 dev_num_vfs; - - pos = pci_find_ext_capability(adapter->pdev, PCI_EXT_CAP_ID_SRIOV); - if (pos) { - pci_read_config_word(adapter->pdev, pos + PCI_SRIOV_TOTAL_VF, - &dev_num_vfs); - adapter->dev_num_vfs = dev_num_vfs; - } - return 0; -} - static int be_setup(struct be_adapter *adapter) { struct net_device *netdev = adapter->netdev; - struct device *dev = &adapter->pdev->dev; u32 cap_flags, en_flags; u32 tx_fc, rx_fc; int status; @@ -2694,8 +2640,6 @@ static int be_setup(struct be_adapter *adapter) be_setup_init(adapter); - be_get_config(adapter); - be_cmd_req_native_mode(adapter); be_msix_enable(adapter); @@ -2774,11 +2718,10 @@ static int be_setup(struct be_adapter *adapter) pcie_set_readrq(adapter->pdev, 4096); - if (be_physfn(adapter) && num_vfs) { - if (adapter->dev_num_vfs) - be_vf_setup(adapter); - else - dev_warn(dev, "device doesn't support SRIOV\n"); + if (sriov_enabled(adapter)) { + status = be_vf_setup(adapter); + if (status) + goto err; } be_cmd_get_phy_info(adapter); @@ -2788,7 +2731,6 @@ static int be_setup(struct be_adapter *adapter) schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); adapter->flags |= BE_FLAGS_WORKER_SCHEDULED; - pci_write_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, 1); return 0; err: be_clear(adapter); @@ -3252,24 +3194,6 @@ static void be_unmap_pci_bars(struct be_adapter *adapter) iounmap(adapter->csr); if (adapter->db) iounmap(adapter->db); - if (adapter->roce_db.base) - pci_iounmap(adapter->pdev, adapter->roce_db.base); -} - -static int lancer_roce_map_pci_bars(struct be_adapter *adapter) -{ - struct pci_dev *pdev = adapter->pdev; - u8 __iomem *addr; - - addr = pci_iomap(pdev, 2, 0); - if (addr == NULL) - return -ENOMEM; - - adapter->roce_db.base = addr; - adapter->roce_db.io_addr = pci_resource_start(pdev, 2); - adapter->roce_db.size = 8192; - adapter->roce_db.total_size = pci_resource_len(pdev, 2); - return 0; } static int be_map_pci_bars(struct be_adapter *adapter) @@ -3278,18 +3202,11 @@ static int be_map_pci_bars(struct be_adapter *adapter) int db_reg; if (lancer_chip(adapter)) { - if (be_type_2_3(adapter)) { - addr = ioremap_nocache( - pci_resource_start(adapter->pdev, 0), - pci_resource_len(adapter->pdev, 0)); - if (addr == NULL) - return -ENOMEM; - adapter->db = addr; - } - if (adapter->if_type == SLI_INTF_TYPE_3) { - if (lancer_roce_map_pci_bars(adapter)) - goto pci_map_err; - } + addr = ioremap_nocache(pci_resource_start(adapter->pdev, 0), + pci_resource_len(adapter->pdev, 0)); + if (addr == NULL) + return -ENOMEM; + adapter->db = addr; return 0; } @@ -3314,19 +3231,14 @@ static int be_map_pci_bars(struct be_adapter *adapter) if (addr == NULL) goto pci_map_err; adapter->db = addr; - if (adapter->sli_family == SKYHAWK_SLI_FAMILY) { - adapter->roce_db.size = 4096; - adapter->roce_db.io_addr = - pci_resource_start(adapter->pdev, db_reg); - adapter->roce_db.total_size = - pci_resource_len(adapter->pdev, db_reg); - } + return 0; pci_map_err: be_unmap_pci_bars(adapter); return -ENOMEM; } + static void be_ctrl_cleanup(struct be_adapter *adapter) { struct be_dma_mem *mem = &adapter->mbox_mem_alloced; @@ -3432,8 +3344,6 @@ static void __devexit be_remove(struct pci_dev *pdev) if (!adapter) return; - be_roce_dev_remove(adapter); - unregister_netdev(adapter->netdev); be_clear(adapter); @@ -3442,6 +3352,8 @@ static void __devexit be_remove(struct pci_dev *pdev) be_ctrl_cleanup(adapter); + be_sriov_disable(adapter); + pci_set_drvdata(pdev, NULL); pci_release_regions(pdev); pci_disable_device(pdev); @@ -3455,43 +3367,9 @@ bool be_is_wol_supported(struct be_adapter *adapter) !be_is_wol_excluded(adapter)) ? true : false; } -u32 be_get_fw_log_level(struct be_adapter *adapter) -{ - struct be_dma_mem extfat_cmd; - struct be_fat_conf_params *cfgs; - int status; - u32 level = 0; - int j; - - memset(&extfat_cmd, 0, sizeof(struct be_dma_mem)); - extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps); - extfat_cmd.va = pci_alloc_consistent(adapter->pdev, extfat_cmd.size, - &extfat_cmd.dma); - - if (!extfat_cmd.va) { - dev_err(&adapter->pdev->dev, "%s: Memory allocation failure\n", - __func__); - goto err; - } - - status = be_cmd_get_ext_fat_capabilites(adapter, &extfat_cmd); - if (!status) { - cfgs = (struct be_fat_conf_params *)(extfat_cmd.va + - sizeof(struct be_cmd_resp_hdr)); - for (j = 0; j < cfgs->module[0].num_modes; j++) { - if (cfgs->module[0].trace_lvl[j].mode == MODE_UART) - level = cfgs->module[0].trace_lvl[j].dbg_lvl; - } - } - pci_free_consistent(adapter->pdev, extfat_cmd.size, extfat_cmd.va, - extfat_cmd.dma); -err: - return level; -} -static int be_get_initial_config(struct be_adapter *adapter) +static int be_get_config(struct be_adapter *adapter) { int status; - u32 level; status = be_cmd_query_fw_cfg(adapter, &adapter->port_num, &adapter->function_mode, &adapter->function_caps); @@ -3529,13 +3407,10 @@ static int be_get_initial_config(struct be_adapter *adapter) if (be_is_wol_supported(adapter)) adapter->wol = true; - level = be_get_fw_log_level(adapter); - adapter->msg_enable = level <= FW_LOG_LEVEL_DEFAULT ? NETIF_MSG_HW : 0; - return 0; } -static int be_dev_type_check(struct be_adapter *adapter) +static int be_dev_family_check(struct be_adapter *adapter) { struct pci_dev *pdev = adapter->pdev; u32 sli_intf = 0, if_type; @@ -3547,27 +3422,17 @@ static int be_dev_type_check(struct be_adapter *adapter) break; case BE_DEVICE_ID2: case OC_DEVICE_ID2: + case OC_DEVICE_ID5: adapter->generation = BE_GEN3; break; case OC_DEVICE_ID3: case OC_DEVICE_ID4: pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf); - adapter->if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >> - SLI_INTF_IF_TYPE_SHIFT; if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >> SLI_INTF_IF_TYPE_SHIFT; + if (((sli_intf & SLI_INTF_VALID_MASK) != SLI_INTF_VALID) || - !be_type_2_3(adapter)) { - dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n"); - return -EINVAL; - } - adapter->sli_family = ((sli_intf & SLI_INTF_FAMILY_MASK) >> - SLI_INTF_FAMILY_SHIFT); - adapter->generation = BE_GEN3; - break; - case OC_DEVICE_ID5: - pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf); - if ((sli_intf & SLI_INTF_VALID_MASK) != SLI_INTF_VALID) { + if_type != 0x02) { dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n"); return -EINVAL; } @@ -3578,9 +3443,6 @@ static int be_dev_type_check(struct be_adapter *adapter) default: adapter->generation = 0; } - - pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf); - adapter->virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0; return 0; } @@ -3724,14 +3586,6 @@ static void be_worker(struct work_struct *work) schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); } -static bool be_reset_required(struct be_adapter *adapter) -{ - u32 reg; - - pci_read_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, ®); - return reg; -} - static int __devinit be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) { @@ -3757,7 +3611,7 @@ static int __devinit be_probe(struct pci_dev *pdev, adapter->pdev = pdev; pci_set_drvdata(pdev, adapter); - status = be_dev_type_check(adapter); + status = be_dev_family_check(adapter); if (status) goto free_netdev; @@ -3775,10 +3629,14 @@ static int __devinit be_probe(struct pci_dev *pdev, } } - status = be_ctrl_init(adapter); + status = be_sriov_enable(adapter); if (status) goto free_netdev; + status = be_ctrl_init(adapter); + if (status) + goto disable_sriov; + if (lancer_chip(adapter)) { status = lancer_wait_ready(adapter); if (!status) { @@ -3804,11 +3662,9 @@ static int __devinit be_probe(struct pci_dev *pdev, if (status) goto ctrl_clean; - if (be_reset_required(adapter)) { - status = be_cmd_reset_function(adapter); - if (status) - goto ctrl_clean; - } + status = be_cmd_reset_function(adapter); + if (status) + goto ctrl_clean; /* The INTR bit may be set in the card when probed by a kdump kernel * after a crash. @@ -3820,7 +3676,7 @@ static int __devinit be_probe(struct pci_dev *pdev, if (status) goto ctrl_clean; - status = be_get_initial_config(adapter); + status = be_get_config(adapter); if (status) goto stats_clean; @@ -3836,8 +3692,6 @@ static int __devinit be_probe(struct pci_dev *pdev, if (status != 0) goto unsetup; - be_roce_dev_add(adapter); - dev_info(&pdev->dev, "%s: %s port %d\n", netdev->name, nic_name(pdev), adapter->port_num); @@ -3851,6 +3705,8 @@ static int __devinit be_probe(struct pci_dev *pdev, be_stats_cleanup(adapter); ctrl_clean: be_ctrl_cleanup(adapter); +disable_sriov: + be_sriov_disable(adapter); free_netdev: free_netdev(netdev); pci_set_drvdata(pdev, NULL); diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_roce.c b/trunk/drivers/net/ethernet/emulex/benet/be_roce.c deleted file mode 100644 index deecc44b3617..000000000000 --- a/trunk/drivers/net/ethernet/emulex/benet/be_roce.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (C) 2005 - 2011 Emulex - * All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. The full GNU General - * Public License is included in this distribution in the file called COPYING. - * - * Contact Information: - * linux-drivers@emulex.com - * - * Emulex - * 3333 Susan Street - * Costa Mesa, CA 92626 - */ - -#include -#include -#include -#include - -#include "be.h" -#include "be_cmds.h" - -static struct ocrdma_driver *ocrdma_drv; -static LIST_HEAD(be_adapter_list); -static DEFINE_MUTEX(be_adapter_list_lock); - -static void _be_roce_dev_add(struct be_adapter *adapter) -{ - struct be_dev_info dev_info; - int i, num_vec; - struct pci_dev *pdev = adapter->pdev; - - if (!ocrdma_drv) - return; - if (pdev->device == OC_DEVICE_ID5) { - /* only msix is supported on these devices */ - if (!msix_enabled(adapter)) - return; - /* DPP region address and length */ - dev_info.dpp_unmapped_addr = pci_resource_start(pdev, 2); - dev_info.dpp_unmapped_len = pci_resource_len(pdev, 2); - } else { - dev_info.dpp_unmapped_addr = 0; - dev_info.dpp_unmapped_len = 0; - } - dev_info.pdev = adapter->pdev; - if (adapter->sli_family == SKYHAWK_SLI_FAMILY) - dev_info.db = adapter->db; - else - dev_info.db = adapter->roce_db.base; - dev_info.unmapped_db = adapter->roce_db.io_addr; - dev_info.db_page_size = adapter->roce_db.size; - dev_info.db_total_size = adapter->roce_db.total_size; - dev_info.netdev = adapter->netdev; - memcpy(dev_info.mac_addr, adapter->netdev->dev_addr, ETH_ALEN); - dev_info.dev_family = adapter->sli_family; - if (msix_enabled(adapter)) { - /* provide all the vectors, so that EQ creation response - * can decide which one to use. - */ - num_vec = adapter->num_msix_vec + adapter->num_msix_roce_vec; - dev_info.intr_mode = BE_INTERRUPT_MODE_MSIX; - dev_info.msix.num_vectors = min(num_vec, MAX_ROCE_MSIX_VECTORS); - /* provide start index of the vector, - * so in case of linear usage, - * it can use the base as starting point. - */ - dev_info.msix.start_vector = adapter->num_evt_qs; - for (i = 0; i < dev_info.msix.num_vectors; i++) { - dev_info.msix.vector_list[i] = - adapter->msix_entries[i].vector; - } - } else { - dev_info.msix.num_vectors = 0; - dev_info.intr_mode = BE_INTERRUPT_MODE_INTX; - } - adapter->ocrdma_dev = ocrdma_drv->add(&dev_info); -} - -void be_roce_dev_add(struct be_adapter *adapter) -{ - if (be_roce_supported(adapter)) { - INIT_LIST_HEAD(&adapter->entry); - mutex_lock(&be_adapter_list_lock); - list_add_tail(&adapter->entry, &be_adapter_list); - - /* invoke add() routine of roce driver only if - * valid driver registered with add method and add() is not yet - * invoked on a given adapter. - */ - _be_roce_dev_add(adapter); - mutex_unlock(&be_adapter_list_lock); - } -} - -void _be_roce_dev_remove(struct be_adapter *adapter) -{ - if (ocrdma_drv && ocrdma_drv->remove && adapter->ocrdma_dev) - ocrdma_drv->remove(adapter->ocrdma_dev); - adapter->ocrdma_dev = NULL; -} - -void be_roce_dev_remove(struct be_adapter *adapter) -{ - if (be_roce_supported(adapter)) { - mutex_lock(&be_adapter_list_lock); - _be_roce_dev_remove(adapter); - list_del(&adapter->entry); - mutex_unlock(&be_adapter_list_lock); - } -} - -void _be_roce_dev_open(struct be_adapter *adapter) -{ - if (ocrdma_drv && adapter->ocrdma_dev && - ocrdma_drv->state_change_handler) - ocrdma_drv->state_change_handler(adapter->ocrdma_dev, 0); -} - -void be_roce_dev_open(struct be_adapter *adapter) -{ - if (be_roce_supported(adapter)) { - mutex_lock(&be_adapter_list_lock); - _be_roce_dev_open(adapter); - mutex_unlock(&be_adapter_list_lock); - } -} - -void _be_roce_dev_close(struct be_adapter *adapter) -{ - if (ocrdma_drv && adapter->ocrdma_dev && - ocrdma_drv->state_change_handler) - ocrdma_drv->state_change_handler(adapter->ocrdma_dev, 1); -} - -void be_roce_dev_close(struct be_adapter *adapter) -{ - if (be_roce_supported(adapter)) { - mutex_lock(&be_adapter_list_lock); - _be_roce_dev_close(adapter); - mutex_unlock(&be_adapter_list_lock); - } -} - -int be_roce_register_driver(struct ocrdma_driver *drv) -{ - struct be_adapter *dev; - - mutex_lock(&be_adapter_list_lock); - if (ocrdma_drv) { - mutex_unlock(&be_adapter_list_lock); - return -EINVAL; - } - ocrdma_drv = drv; - list_for_each_entry(dev, &be_adapter_list, entry) { - struct net_device *netdev; - _be_roce_dev_add(dev); - netdev = dev->netdev; - if (netif_running(netdev) && netif_oper_up(netdev)) - _be_roce_dev_open(dev); - } - mutex_unlock(&be_adapter_list_lock); - return 0; -} -EXPORT_SYMBOL(be_roce_register_driver); - -void be_roce_unregister_driver(struct ocrdma_driver *drv) -{ - struct be_adapter *dev; - - mutex_lock(&be_adapter_list_lock); - list_for_each_entry(dev, &be_adapter_list, entry) { - if (dev->ocrdma_dev) - _be_roce_dev_remove(dev); - } - ocrdma_drv = NULL; - mutex_unlock(&be_adapter_list_lock); -} -EXPORT_SYMBOL(be_roce_unregister_driver); diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_roce.h b/trunk/drivers/net/ethernet/emulex/benet/be_roce.h deleted file mode 100644 index db4ea8081c07..000000000000 --- a/trunk/drivers/net/ethernet/emulex/benet/be_roce.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2005 - 2011 Emulex - * All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. The full GNU General - * Public License is included in this distribution in the file called COPYING. - * - * Contact Information: - * linux-drivers@emulex.com - * - * Emulex - * 3333 Susan Street - * Costa Mesa, CA 92626 - */ - -#ifndef BE_ROCE_H -#define BE_ROCE_H - -#include -#include - -struct ocrdma_dev; - -enum be_interrupt_mode { - BE_INTERRUPT_MODE_MSIX = 0, - BE_INTERRUPT_MODE_INTX = 1, - BE_INTERRUPT_MODE_MSI = 2, -}; - -#define MAX_ROCE_MSIX_VECTORS 16 -struct be_dev_info { - u8 __iomem *db; - u64 unmapped_db; - u32 db_page_size; - u32 db_total_size; - u64 dpp_unmapped_addr; - u32 dpp_unmapped_len; - struct pci_dev *pdev; - struct net_device *netdev; - u8 mac_addr[ETH_ALEN]; - u32 dev_family; - enum be_interrupt_mode intr_mode; - struct { - int num_vectors; - int start_vector; - u32 vector_list[MAX_ROCE_MSIX_VECTORS]; - } msix; -}; - -/* ocrdma driver register's the callback functions with nic driver. */ -struct ocrdma_driver { - unsigned char name[32]; - struct ocrdma_dev *(*add) (struct be_dev_info *dev_info); - void (*remove) (struct ocrdma_dev *); - void (*state_change_handler) (struct ocrdma_dev *, u32 new_state); -}; - -enum { - BE_DEV_UP = 0, - BE_DEV_DOWN = 1 -}; - -/* APIs for RoCE driver to register callback handlers, - * which will be invoked when device is added, removed, ifup, ifdown - */ -int be_roce_register_driver(struct ocrdma_driver *drv); -void be_roce_unregister_driver(struct ocrdma_driver *drv); - -/* API for RoCE driver to issue mailbox commands */ -int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload, - int wrb_payload_size, u16 *cmd_status, u16 *ext_status); - -#endif /* BE_ROCE_H */ diff --git a/trunk/drivers/net/ethernet/freescale/gianfar.c b/trunk/drivers/net/ethernet/freescale/gianfar.c index 0741aded9eb0..1adb0245b9dd 100644 --- a/trunk/drivers/net/ethernet/freescale/gianfar.c +++ b/trunk/drivers/net/ethernet/freescale/gianfar.c @@ -1082,7 +1082,7 @@ static int gfar_probe(struct platform_device *ofdev) if (dev->features & NETIF_F_IP_CSUM || priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER) - dev->needed_headroom = GMAC_FCB_LEN; + dev->hard_header_len += GMAC_FCB_LEN; /* Program the isrg regs only if number of grps > 1 */ if (priv->num_grps > 1) { diff --git a/trunk/drivers/net/ethernet/fujitsu/at1700.c b/trunk/drivers/net/ethernet/fujitsu/at1700.c index 4b80dc4531ad..3d94797c8f9b 100644 --- a/trunk/drivers/net/ethernet/fujitsu/at1700.c +++ b/trunk/drivers/net/ethernet/fujitsu/at1700.c @@ -27,7 +27,7 @@ ATI provided their EEPROM configuration code header file. Thanks to NIIBE Yutaka for bug fixes. - MCA bus (AT1720) support (now deleted) by Rene Schmit + MCA bus (AT1720) support by Rene Schmit Bugs: The MB86965 has a design flaw that makes all probes unreliable. Not @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -78,6 +79,24 @@ static unsigned at1700_probe_list[] __initdata = { 0x260, 0x280, 0x2a0, 0x240, 0x340, 0x320, 0x380, 0x300, 0 }; +/* + * MCA + */ +#ifdef CONFIG_MCA_LEGACY +static int at1700_ioaddr_pattern[] __initdata = { + 0x00, 0x04, 0x01, 0x05, 0x02, 0x06, 0x03, 0x07 +}; + +static int at1700_mca_probe_list[] __initdata = { + 0x400, 0x1400, 0x2400, 0x3400, 0x4400, 0x5400, 0x6400, 0x7400, 0 +}; + +static int at1700_irq_pattern[] __initdata = { + 0x00, 0x00, 0x00, 0x30, 0x70, 0xb0, 0x00, 0x00, + 0x00, 0xf0, 0x34, 0x74, 0xb4, 0x00, 0x00, 0xf4, 0x00 +}; +#endif + /* use 0 for production, 1 for verification, >2 for debug */ #ifndef NET_DEBUG #define NET_DEBUG 1 @@ -95,6 +114,7 @@ struct net_local { uint tx_queue_ready:1; /* Tx queue is ready to be sent. */ uint rx_started:1; /* Packets are Rxing. */ uchar tx_queue; /* Number of packet on the Tx queue. */ + char mca_slot; /* -1 means ISA */ ushort tx_queue_len; /* Current length of the Tx queue. */ }; @@ -146,6 +166,21 @@ static void set_rx_mode(struct net_device *dev); static void net_tx_timeout (struct net_device *dev); +#ifdef CONFIG_MCA_LEGACY +struct at1720_mca_adapters_struct { + char* name; + int id; +}; +/* rEnE : maybe there are others I don't know off... */ + +static struct at1720_mca_adapters_struct at1720_mca_adapters[] __initdata = { + { "Allied Telesys AT1720AT", 0x6410 }, + { "Allied Telesys AT1720BT", 0x6413 }, + { "Allied Telesys AT1720T", 0x6416 }, + { NULL, 0 }, +}; +#endif + /* Check for a network adaptor of this type, and return '0' iff one exists. If dev->base_addr == 0, probe all likely locations. If dev->base_addr == 1, always return failure. @@ -159,6 +194,11 @@ static int irq; static void cleanup_card(struct net_device *dev) { +#ifdef CONFIG_MCA_LEGACY + struct net_local *lp = netdev_priv(dev); + if (lp->mca_slot >= 0) + mca_mark_as_unused(lp->mca_slot); +#endif free_irq(dev->irq, NULL); release_region(dev->base_addr, AT1700_IO_EXTENT); } @@ -233,7 +273,7 @@ static int __init at1700_probe1(struct net_device *dev, int ioaddr) static const char fmv_irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15}; static const char at1700_irqmap[8] = {3, 4, 5, 9, 10, 11, 14, 15}; unsigned int i, irq, is_fmv18x = 0, is_at1700 = 0; - int ret = -ENODEV; + int slot, ret = -ENODEV; struct net_local *lp = netdev_priv(dev); if (!request_region(ioaddr, AT1700_IO_EXTENT, DRV_NAME)) @@ -248,6 +288,64 @@ static int __init at1700_probe1(struct net_device *dev, int ioaddr) ioaddr, read_eeprom(ioaddr, 4), read_eeprom(ioaddr, 5), read_eeprom(ioaddr, 6), inw(ioaddr + EEPROM_Ctrl)); #endif + +#ifdef CONFIG_MCA_LEGACY + /* rEnE (rene@bss.lu): got this from 3c509 driver source , adapted for AT1720 */ + + /* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch, heavily + modified by Chris Beauregard (cpbeaure@csclub.uwaterloo.ca) + to support standard MCA probing. */ + + /* redone for multi-card detection by ZP Gu (zpg@castle.net) */ + /* now works as a module */ + + if (MCA_bus) { + int j; + int l_i; + u_char pos3, pos4; + + for (j = 0; at1720_mca_adapters[j].name != NULL; j ++) { + slot = 0; + while (slot != MCA_NOTFOUND) { + + slot = mca_find_unused_adapter( at1720_mca_adapters[j].id, slot ); + if (slot == MCA_NOTFOUND) break; + + /* if we get this far, an adapter has been detected and is + enabled */ + + pos3 = mca_read_stored_pos( slot, 3 ); + pos4 = mca_read_stored_pos( slot, 4 ); + + for (l_i = 0; l_i < 8; l_i++) + if (( pos3 & 0x07) == at1700_ioaddr_pattern[l_i]) + break; + ioaddr = at1700_mca_probe_list[l_i]; + + for (irq = 0; irq < 0x10; irq++) + if (((((pos4>>4) & 0x0f) | (pos3 & 0xf0)) & 0xff) == at1700_irq_pattern[irq]) + break; + + /* probing for a card at a particular IO/IRQ */ + if ((dev->irq && dev->irq != irq) || + (dev->base_addr && dev->base_addr != ioaddr)) { + slot++; /* probing next slot */ + continue; + } + + dev->irq = irq; + + /* claim the slot */ + mca_set_adapter_name( slot, at1720_mca_adapters[j].name ); + mca_mark_as_used(slot); + + goto found; + } + } + /* if we get here, we didn't find an MCA adapter - try ISA */ + } +#endif + slot = -1; /* We must check for the EEPROM-config boards first, else accessing IOCONFIG0 will move the board! */ if (at1700_probe_list[inb(ioaddr + IOCONFIG1) & 0x07] == ioaddr && @@ -262,7 +360,11 @@ static int __init at1700_probe1(struct net_device *dev, int ioaddr) goto err_out; } - /* Reset the internal state machines. */ +#ifdef CONFIG_MCA_LEGACY +found: +#endif + + /* Reset the internal state machines. */ outb(0, ioaddr + RESET); if (is_at1700) { @@ -278,11 +380,11 @@ static int __init at1700_probe1(struct net_device *dev, int ioaddr) break; } if (i == 8) { - goto err_out; + goto err_mca; } } else { if (fmv18x_probe_list[inb(ioaddr + IOCONFIG) & 0x07] != ioaddr) - goto err_out; + goto err_mca; irq = fmv_irqmap[(inb(ioaddr + IOCONFIG)>>6) & 0x03]; } } @@ -362,17 +464,23 @@ static int __init at1700_probe1(struct net_device *dev, int ioaddr) spin_lock_init(&lp->lock); lp->jumpered = is_fmv18x; + lp->mca_slot = slot; /* Snarf the interrupt vector now. */ ret = request_irq(irq, net_interrupt, 0, DRV_NAME, dev); if (ret) { printk(KERN_ERR "AT1700 at %#3x is unusable due to a " "conflict on IRQ %d.\n", ioaddr, irq); - goto err_out; + goto err_mca; } return 0; +err_mca: +#ifdef CONFIG_MCA_LEGACY + if (slot >= 0) + mca_mark_as_unused(slot); +#endif err_out: release_region(ioaddr, AT1700_IO_EXTENT); return ret; diff --git a/trunk/drivers/net/ethernet/i825xx/3c523.c b/trunk/drivers/net/ethernet/i825xx/3c523.c new file mode 100644 index 000000000000..8451ecd4c1ec --- /dev/null +++ b/trunk/drivers/net/ethernet/i825xx/3c523.c @@ -0,0 +1,1312 @@ +/* + net-3-driver for the 3c523 Etherlink/MC card (i82586 Ethernet chip) + + + This is an extension to the Linux operating system, and is covered by the + same GNU General Public License that covers that work. + + Copyright 1995, 1996 by Chris Beauregard (cpbeaure@undergrad.math.uwaterloo.ca) + + This is basically Michael Hipp's ni52 driver, with a new probing + algorithm and some minor changes to the 82586 CA and reset routines. + Thanks a lot Michael for a really clean i82586 implementation! Unless + otherwise documented in ni52.c, any bugs are mine. + + Contrary to the Ethernet-HOWTO, this isn't based on the 3c507 driver in + any way. The ni52 is a lot easier to modify. + + sources: + ni52.c + + Crynwr packet driver collection was a great reference for my first + attempt at this sucker. The 3c507 driver also helped, until I noticed + that ni52.c was a lot nicer. + + EtherLink/MC: Micro Channel Ethernet Adapter Technical Reference + Manual, courtesy of 3Com CardFacts, documents the 3c523-specific + stuff. Information on CardFacts is found in the Ethernet HOWTO. + Also see + + Microprocessor Communications Support Chips, T.J. Byers, ISBN + 0-444-01224-9, has a section on the i82586. It tells you just enough + to know that you really don't want to learn how to program the chip. + + The original device probe code was stolen from ps2esdi.c + + Known Problems: + Since most of the code was stolen from ni52.c, you'll run across the + same bugs in the 0.62 version of ni52.c, plus maybe a few because of + the 3c523 idiosynchacies. The 3c523 has 16K of RAM though, so there + shouldn't be the overrun problem that the 8K ni52 has. + + This driver is for a 16K adapter. It should work fine on the 64K + adapters, but it will only use one of the 4 banks of RAM. Modifying + this for the 64K version would require a lot of heinous bank + switching, which I'm sure not interested in doing. If you try to + implement a bank switching version, you'll basically have to remember + what bank is enabled and do a switch every time you access a memory + location that's not current. You'll also have to remap pointers on + the driver side, because it only knows about 16K of the memory. + Anyone desperate or masochistic enough to try? + + It seems to be stable now when multiple transmit buffers are used. I + can't see any performance difference, but then I'm working on a 386SX. + + Multicast doesn't work. It doesn't even pretend to work. Don't use + it. Don't compile your kernel with multicast support. I don't know + why. + + Features: + This driver is useable as a loadable module. If you try to specify an + IRQ or a IO address (via insmod 3c523.o irq=xx io=0xyyy), it will + search the MCA slots until it finds a 3c523 with the specified + parameters. + + This driver does support multiple ethernet cards when used as a module + (up to MAX_3C523_CARDS, the default being 4) + + This has been tested with both BNC and TP versions, internal and + external transceivers. Haven't tested with the 64K version (that I + know of). + + History: + Jan 1st, 1996 + first public release + Feb 4th, 1996 + update to 1.3.59, incorporated multicast diffs from ni52.c + Feb 15th, 1996 + added shared irq support + Apr 1999 + added support for multiple cards when used as a module + added option to disable multicast as is causes problems + Ganesh Sittampalam + Stuart Adamson + Nov 2001 + added support for ethtool (jgarzik) + + $Header: /fsys2/home/chrisb/linux-1.3.59-MCA/drivers/net/RCS/3c523.c,v 1.1 1996/02/05 01:53:46 chrisb Exp chrisb $ + */ + +#define DRV_NAME "3c523" +#define DRV_VERSION "17-Nov-2001" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "3c523.h" + +/*************************************************************************/ +#define DEBUG /* debug on */ +#define SYSBUSVAL 0 /* 1 = 8 Bit, 0 = 16 bit - 3c523 only does 16 bit */ +#undef ELMC_MULTICAST /* Disable multicast support as it is somewhat seriously broken at the moment */ + +#define make32(ptr16) (p->memtop + (short) (ptr16) ) +#define make24(ptr32) ((char *) (ptr32) - p->base) +#define make16(ptr32) ((unsigned short) ((unsigned long) (ptr32) - (unsigned long) p->memtop )) + +/*************************************************************************/ +/* + Tables to which we can map values in the configuration registers. + */ +static int irq_table[] __initdata = { + 12, 7, 3, 9 +}; + +static int csr_table[] __initdata = { + 0x300, 0x1300, 0x2300, 0x3300 +}; + +static int shm_table[] __initdata = { + 0x0c0000, 0x0c8000, 0x0d0000, 0x0d8000 +}; + +/******************* how to calculate the buffers ***************************** + + + * IMPORTANT NOTE: if you configure only one NUM_XMIT_BUFFS, the driver works + * --------------- in a different (more stable?) mode. Only in this mode it's + * possible to configure the driver with 'NO_NOPCOMMANDS' + +sizeof(scp)=12; sizeof(scb)=16; sizeof(iscp)=8; +sizeof(scp)+sizeof(iscp)+sizeof(scb) = 36 = INIT +sizeof(rfd) = 24; sizeof(rbd) = 12; +sizeof(tbd) = 8; sizeof(transmit_cmd) = 16; +sizeof(nop_cmd) = 8; + + * if you don't know the driver, better do not change this values: */ + +#define RECV_BUFF_SIZE 1524 /* slightly oversized */ +#define XMIT_BUFF_SIZE 1524 /* slightly oversized */ +#define NUM_XMIT_BUFFS 1 /* config for both, 8K and 16K shmem */ +#define NUM_RECV_BUFFS_8 4 /* config for 8K shared mem */ +#define NUM_RECV_BUFFS_16 9 /* config for 16K shared mem */ + +#if (NUM_XMIT_BUFFS == 1) +#define NO_NOPCOMMANDS /* only possible with NUM_XMIT_BUFFS=1 */ +#endif + +/**************************************************************************/ + +#define DELAY(x) { mdelay(32 * x); } + +/* a much shorter delay: */ +#define DELAY_16(); { udelay(16) ; } + +/* wait for command with timeout: */ +#define WAIT_4_SCB_CMD() { int i; \ + for(i=0;i<1024;i++) { \ + if(!p->scb->cmd) break; \ + DELAY_16(); \ + if(i == 1023) { \ + pr_warning("%s:%d: scb_cmd timed out .. resetting i82586\n",\ + dev->name,__LINE__); \ + elmc_id_reset586(); } } } + +static irqreturn_t elmc_interrupt(int irq, void *dev_id); +static int elmc_open(struct net_device *dev); +static int elmc_close(struct net_device *dev); +static netdev_tx_t elmc_send_packet(struct sk_buff *, struct net_device *); +static struct net_device_stats *elmc_get_stats(struct net_device *dev); +static void elmc_timeout(struct net_device *dev); +#ifdef ELMC_MULTICAST +static void set_multicast_list(struct net_device *dev); +#endif +static const struct ethtool_ops netdev_ethtool_ops; + +/* helper-functions */ +static int init586(struct net_device *dev); +static int check586(struct net_device *dev, unsigned long where, unsigned size); +static void alloc586(struct net_device *dev); +static void startrecv586(struct net_device *dev); +static void *alloc_rfa(struct net_device *dev, void *ptr); +static void elmc_rcv_int(struct net_device *dev); +static void elmc_xmt_int(struct net_device *dev); +static void elmc_rnr_int(struct net_device *dev); + +struct priv { + unsigned long base; + char *memtop; + unsigned long mapped_start; /* Start of ioremap */ + volatile struct rfd_struct *rfd_last, *rfd_top, *rfd_first; + volatile struct scp_struct *scp; /* volatile is important */ + volatile struct iscp_struct *iscp; /* volatile is important */ + volatile struct scb_struct *scb; /* volatile is important */ + volatile struct tbd_struct *xmit_buffs[NUM_XMIT_BUFFS]; +#if (NUM_XMIT_BUFFS == 1) + volatile struct transmit_cmd_struct *xmit_cmds[2]; + volatile struct nop_cmd_struct *nop_cmds[2]; +#else + volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS]; + volatile struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS]; +#endif + volatile int nop_point, num_recv_buffs; + volatile char *xmit_cbuffs[NUM_XMIT_BUFFS]; + volatile int xmit_count, xmit_last; + volatile int slot; +}; + +#define elmc_attn586() {elmc_do_attn586(dev->base_addr,ELMC_CTRL_INTE);} +#define elmc_reset586() {elmc_do_reset586(dev->base_addr,ELMC_CTRL_INTE);} + +/* with interrupts disabled - this will clear the interrupt bit in the + 3c523 control register, and won't put it back. This effectively + disables interrupts on the card. */ +#define elmc_id_attn586() {elmc_do_attn586(dev->base_addr,0);} +#define elmc_id_reset586() {elmc_do_reset586(dev->base_addr,0);} + +/*************************************************************************/ +/* + Do a Channel Attention on the 3c523. This is extremely board dependent. + */ +static void elmc_do_attn586(int ioaddr, int ints) +{ + /* the 3c523 requires a minimum of 500 ns. The delays here might be + a little too large, and hence they may cut the performance of the + card slightly. If someone who knows a little more about Linux + timing would care to play with these, I'd appreciate it. */ + + /* this bit masking stuff is crap. I'd rather have separate + registers with strobe triggers for each of these functions. + Ya take what ya got. */ + + outb(ELMC_CTRL_RST | 0x3 | ELMC_CTRL_CA | ints, ioaddr + ELMC_CTRL); + DELAY_16(); /* > 500 ns */ + outb(ELMC_CTRL_RST | 0x3 | ints, ioaddr + ELMC_CTRL); +} + +/*************************************************************************/ +/* + Reset the 82586 on the 3c523. Also very board dependent. + */ +static void elmc_do_reset586(int ioaddr, int ints) +{ + /* toggle the RST bit low then high */ + outb(0x3 | ELMC_CTRL_LBK, ioaddr + ELMC_CTRL); + DELAY_16(); /* > 500 ns */ + outb(ELMC_CTRL_RST | ELMC_CTRL_LBK | 0x3, ioaddr + ELMC_CTRL); + + elmc_do_attn586(ioaddr, ints); +} + +/********************************************** + * close device + */ + +static int elmc_close(struct net_device *dev) +{ + netif_stop_queue(dev); + elmc_id_reset586(); /* the hard way to stop the receiver */ + free_irq(dev->irq, dev); + return 0; +} + +/********************************************** + * open device + */ + +static int elmc_open(struct net_device *dev) +{ + int ret; + + elmc_id_attn586(); /* disable interrupts */ + + ret = request_irq(dev->irq, elmc_interrupt, IRQF_SHARED, + dev->name, dev); + if (ret) { + pr_err("%s: couldn't get irq %d\n", dev->name, dev->irq); + elmc_id_reset586(); + return ret; + } + alloc586(dev); + init586(dev); + startrecv586(dev); + netif_start_queue(dev); + return 0; /* most done by init */ +} + +/********************************************** + * Check to see if there's an 82586 out there. + */ + +static int __init check586(struct net_device *dev, unsigned long where, unsigned size) +{ + struct priv *p = netdev_priv(dev); + char *iscp_addrs[2]; + int i = 0; + + p->base = (unsigned long) isa_bus_to_virt((unsigned long)where) + size - 0x01000000; + p->memtop = isa_bus_to_virt((unsigned long)where) + size; + p->scp = (struct scp_struct *)(p->base + SCP_DEFAULT_ADDRESS); + memset((char *) p->scp, 0, sizeof(struct scp_struct)); + p->scp->sysbus = SYSBUSVAL; /* 1 = 8Bit-Bus, 0 = 16 Bit */ + + iscp_addrs[0] = isa_bus_to_virt((unsigned long)where); + iscp_addrs[1] = (char *) p->scp - sizeof(struct iscp_struct); + + for (i = 0; i < 2; i++) { + p->iscp = (struct iscp_struct *) iscp_addrs[i]; + memset((char *) p->iscp, 0, sizeof(struct iscp_struct)); + + p->scp->iscp = make24(p->iscp); + p->iscp->busy = 1; + + elmc_id_reset586(); + + /* reset586 does an implicit CA */ + + /* apparently, you sometimes have to kick the 82586 twice... */ + elmc_id_attn586(); + DELAY(1); + + if (p->iscp->busy) { /* i82586 clears 'busy' after successful init */ + return 0; + } + } + return 1; +} + +/****************************************************************** + * set iscp at the right place, called by elmc_probe and open586. + */ + +static void alloc586(struct net_device *dev) +{ + struct priv *p = netdev_priv(dev); + + elmc_id_reset586(); + DELAY(2); + + p->scp = (struct scp_struct *) (p->base + SCP_DEFAULT_ADDRESS); + p->scb = (struct scb_struct *) isa_bus_to_virt(dev->mem_start); + p->iscp = (struct iscp_struct *) ((char *) p->scp - sizeof(struct iscp_struct)); + + memset((char *) p->iscp, 0, sizeof(struct iscp_struct)); + memset((char *) p->scp, 0, sizeof(struct scp_struct)); + + p->scp->iscp = make24(p->iscp); + p->scp->sysbus = SYSBUSVAL; + p->iscp->scb_offset = make16(p->scb); + + p->iscp->busy = 1; + elmc_id_reset586(); + elmc_id_attn586(); + + DELAY(2); + + if (p->iscp->busy) + pr_err("%s: Init-Problems (alloc).\n", dev->name); + + memset((char *) p->scb, 0, sizeof(struct scb_struct)); +} + +/*****************************************************************/ + +static int elmc_getinfo(char *buf, int slot, void *d) +{ + int len = 0; + struct net_device *dev = d; + + if (dev == NULL) + return len; + + len += sprintf(buf + len, "Revision: 0x%x\n", + inb(dev->base_addr + ELMC_REVISION) & 0xf); + len += sprintf(buf + len, "IRQ: %d\n", dev->irq); + len += sprintf(buf + len, "IO Address: %#lx-%#lx\n", dev->base_addr, + dev->base_addr + ELMC_IO_EXTENT); + len += sprintf(buf + len, "Memory: %#lx-%#lx\n", dev->mem_start, + dev->mem_end - 1); + len += sprintf(buf + len, "Transceiver: %s\n", dev->if_port ? + "External" : "Internal"); + len += sprintf(buf + len, "Device: %s\n", dev->name); + len += sprintf(buf + len, "Hardware Address: %pM\n", + dev->dev_addr); + + return len; +} /* elmc_getinfo() */ + +static const struct net_device_ops netdev_ops = { + .ndo_open = elmc_open, + .ndo_stop = elmc_close, + .ndo_get_stats = elmc_get_stats, + .ndo_start_xmit = elmc_send_packet, + .ndo_tx_timeout = elmc_timeout, +#ifdef ELMC_MULTICAST + .ndo_set_rx_mode = set_multicast_list, +#endif + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + +/*****************************************************************/ + +static int __init do_elmc_probe(struct net_device *dev) +{ + static int slot; + int base_addr = dev->base_addr; + int irq = dev->irq; + u_char status = 0; + u_char revision = 0; + int i = 0; + unsigned int size = 0; + int retval; + struct priv *pr = netdev_priv(dev); + + if (MCA_bus == 0) { + return -ENODEV; + } + /* search through the slots for the 3c523. */ + slot = mca_find_adapter(ELMC_MCA_ID, 0); + while (slot != -1) { + status = mca_read_stored_pos(slot, 2); + + dev->irq=irq_table[(status & ELMC_STATUS_IRQ_SELECT) >> 6]; + dev->base_addr=csr_table[(status & ELMC_STATUS_CSR_SELECT) >> 1]; + + /* + If we're trying to match a specified irq or IO address, + we'll reject a match unless it's what we're looking for. + Also reject it if the card is already in use. + */ + + if ((irq && irq != dev->irq) || + (base_addr && base_addr != dev->base_addr)) { + slot = mca_find_adapter(ELMC_MCA_ID, slot + 1); + continue; + } + if (!request_region(dev->base_addr, ELMC_IO_EXTENT, DRV_NAME)) { + slot = mca_find_adapter(ELMC_MCA_ID, slot + 1); + continue; + } + + /* found what we're looking for... */ + break; + } + + /* we didn't find any 3c523 in the slots we checked for */ + if (slot == MCA_NOTFOUND) + return (base_addr || irq) ? -ENXIO : -ENODEV; + + mca_set_adapter_name(slot, "3Com 3c523 Etherlink/MC"); + mca_set_adapter_procfn(slot, (MCA_ProcFn) elmc_getinfo, dev); + + /* if we get this far, adapter has been found - carry on */ + pr_info("%s: 3c523 adapter found in slot %d\n", dev->name, slot + 1); + + /* Now we extract configuration info from the card. + The 3c523 provides information in two of the POS registers, but + the second one is only needed if we want to tell the card what IRQ + to use. I suspect that whoever sets the thing up initially would + prefer we don't screw with those things. + + Note that we read the status info when we found the card... + + See 3c523.h for more details. + */ + + /* revision is stored in the first 4 bits of the revision register */ + revision = inb(dev->base_addr + ELMC_REVISION) & 0xf; + + /* according to docs, we read the interrupt and write it back to + the IRQ select register, since the POST might not configure the IRQ + properly. */ + switch (dev->irq) { + case 3: + mca_write_pos(slot, 3, 0x04); + break; + case 7: + mca_write_pos(slot, 3, 0x02); + break; + case 9: + mca_write_pos(slot, 3, 0x08); + break; + case 12: + mca_write_pos(slot, 3, 0x01); + break; + } + + pr->slot = slot; + + pr_info("%s: 3Com 3c523 Rev 0x%x at %#lx\n", dev->name, (int) revision, + dev->base_addr); + + /* Determine if we're using the on-board transceiver (i.e. coax) or + an external one. The information is pretty much useless, but I + guess it's worth brownie points. */ + dev->if_port = (status & ELMC_STATUS_DISABLE_THIN); + + /* The 3c523 has a 24K chunk of memory. The first 16K is the + shared memory, while the last 8K is for the EtherStart BIOS ROM. + Which we don't care much about here. We'll just tell Linux that + we're using 16K. MCA won't permit address space conflicts caused + by not mapping the other 8K. */ + dev->mem_start = shm_table[(status & ELMC_STATUS_MEMORY_SELECT) >> 3]; + + /* We're using MCA, so it's a given that the information about memory + size is correct. The Crynwr drivers do something like this. */ + + elmc_id_reset586(); /* seems like a good idea before checking it... */ + + size = 0x4000; /* check for 16K mem */ + if (!check586(dev, dev->mem_start, size)) { + pr_err("%s: memprobe, Can't find memory at 0x%lx!\n", dev->name, + dev->mem_start); + retval = -ENODEV; + goto err_out; + } + dev->mem_end = dev->mem_start + size; /* set mem_end showed by 'ifconfig' */ + + pr->memtop = isa_bus_to_virt(dev->mem_start) + size; + pr->base = (unsigned long) isa_bus_to_virt(dev->mem_start) + size - 0x01000000; + alloc586(dev); + + elmc_id_reset586(); /* make sure it doesn't generate spurious ints */ + + /* set number of receive-buffs according to memsize */ + pr->num_recv_buffs = NUM_RECV_BUFFS_16; + + /* dump all the assorted information */ + pr_info("%s: IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->name, + dev->irq, dev->if_port ? "ex" : "in", + dev->mem_start, dev->mem_end - 1); + + /* The hardware address for the 3c523 is stored in the first six + bytes of the IO address. */ + for (i = 0; i < 6; i++) + dev->dev_addr[i] = inb(dev->base_addr + i); + + pr_info("%s: hardware address %pM\n", + dev->name, dev->dev_addr); + + dev->netdev_ops = &netdev_ops; + dev->watchdog_timeo = HZ; + dev->ethtool_ops = &netdev_ethtool_ops; + + /* note that we haven't actually requested the IRQ from the kernel. + That gets done in elmc_open(). I'm not sure that's such a good idea, + but it works, so I'll go with it. */ + +#ifndef ELMC_MULTICAST + dev->flags&=~IFF_MULTICAST; /* Multicast doesn't work */ +#endif + + retval = register_netdev(dev); + if (retval) + goto err_out; + + return 0; +err_out: + mca_set_adapter_procfn(slot, NULL, NULL); + release_region(dev->base_addr, ELMC_IO_EXTENT); + return retval; +} + +#ifdef MODULE +static void cleanup_card(struct net_device *dev) +{ + mca_set_adapter_procfn(((struct priv *)netdev_priv(dev))->slot, + NULL, NULL); + release_region(dev->base_addr, ELMC_IO_EXTENT); +} +#else +struct net_device * __init elmc_probe(int unit) +{ + struct net_device *dev = alloc_etherdev(sizeof(struct priv)); + int err; + + if (!dev) + return ERR_PTR(-ENOMEM); + + sprintf(dev->name, "eth%d", unit); + netdev_boot_setup_check(dev); + + err = do_elmc_probe(dev); + if (err) + goto out; + return dev; +out: + free_netdev(dev); + return ERR_PTR(err); +} +#endif + +/********************************************** + * init the chip (elmc-interrupt should be disabled?!) + * needs a correct 'allocated' memory + */ + +static int init586(struct net_device *dev) +{ + void *ptr; + unsigned long s; + int i, result = 0; + struct priv *p = netdev_priv(dev); + volatile struct configure_cmd_struct *cfg_cmd; + volatile struct iasetup_cmd_struct *ias_cmd; + volatile struct tdr_cmd_struct *tdr_cmd; + volatile struct mcsetup_cmd_struct *mc_cmd; + struct netdev_hw_addr *ha; + int num_addrs = netdev_mc_count(dev); + + ptr = (void *) ((char *) p->scb + sizeof(struct scb_struct)); + + cfg_cmd = (struct configure_cmd_struct *) ptr; /* configure-command */ + cfg_cmd->cmd_status = 0; + cfg_cmd->cmd_cmd = CMD_CONFIGURE | CMD_LAST; + cfg_cmd->cmd_link = 0xffff; + + cfg_cmd->byte_cnt = 0x0a; /* number of cfg bytes */ + cfg_cmd->fifo = 0x08; /* fifo-limit (8=tx:32/rx:64) */ + cfg_cmd->sav_bf = 0x40; /* hold or discard bad recv frames (bit 7) */ + cfg_cmd->adr_len = 0x2e; /* addr_len |!src_insert |pre-len |loopback */ + cfg_cmd->priority = 0x00; + cfg_cmd->ifs = 0x60; + cfg_cmd->time_low = 0x00; + cfg_cmd->time_high = 0xf2; + cfg_cmd->promisc = 0; + if (dev->flags & (IFF_ALLMULTI | IFF_PROMISC)) + cfg_cmd->promisc = 1; + cfg_cmd->carr_coll = 0x00; + + p->scb->cbl_offset = make16(cfg_cmd); + + p->scb->cmd = CUC_START; /* cmd.-unit start */ + elmc_id_attn586(); + + s = jiffies; /* warning: only active with interrupts on !! */ + while (!(cfg_cmd->cmd_status & STAT_COMPL)) { + if (time_after(jiffies, s + 30*HZ/100)) + break; + } + + if ((cfg_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_COMPL | STAT_OK)) { + pr_warning("%s (elmc): configure command failed: %x\n", dev->name, cfg_cmd->cmd_status); + return 1; + } + /* + * individual address setup + */ + ias_cmd = (struct iasetup_cmd_struct *) ptr; + + ias_cmd->cmd_status = 0; + ias_cmd->cmd_cmd = CMD_IASETUP | CMD_LAST; + ias_cmd->cmd_link = 0xffff; + + memcpy((char *) &ias_cmd->iaddr, (char *) dev->dev_addr, ETH_ALEN); + + p->scb->cbl_offset = make16(ias_cmd); + + p->scb->cmd = CUC_START; /* cmd.-unit start */ + elmc_id_attn586(); + + s = jiffies; + while (!(ias_cmd->cmd_status & STAT_COMPL)) { + if (time_after(jiffies, s + 30*HZ/100)) + break; + } + + if ((ias_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_OK | STAT_COMPL)) { + pr_warning("%s (elmc): individual address setup command failed: %04x\n", + dev->name, ias_cmd->cmd_status); + return 1; + } + /* + * TDR, wire check .. e.g. no resistor e.t.c + */ + tdr_cmd = (struct tdr_cmd_struct *) ptr; + + tdr_cmd->cmd_status = 0; + tdr_cmd->cmd_cmd = CMD_TDR | CMD_LAST; + tdr_cmd->cmd_link = 0xffff; + tdr_cmd->status = 0; + + p->scb->cbl_offset = make16(tdr_cmd); + + p->scb->cmd = CUC_START; /* cmd.-unit start */ + elmc_attn586(); + + s = jiffies; + while (!(tdr_cmd->cmd_status & STAT_COMPL)) { + if (time_after(jiffies, s + 30*HZ/100)) { + pr_warning("%s: %d Problems while running the TDR.\n", dev->name, __LINE__); + result = 1; + break; + } + } + + if (!result) { + DELAY(2); /* wait for result */ + result = tdr_cmd->status; + + p->scb->cmd = p->scb->status & STAT_MASK; + elmc_id_attn586(); /* ack the interrupts */ + + if (result & TDR_LNK_OK) { + /* empty */ + } else if (result & TDR_XCVR_PRB) { + pr_warning("%s: TDR: Transceiver problem!\n", dev->name); + } else if (result & TDR_ET_OPN) { + pr_warning("%s: TDR: No correct termination %d clocks away.\n", dev->name, result & TDR_TIMEMASK); + } else if (result & TDR_ET_SRT) { + if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */ + pr_warning("%s: TDR: Detected a short circuit %d clocks away.\n", dev->name, result & TDR_TIMEMASK); + } else { + pr_warning("%s: TDR: Unknown status %04x\n", dev->name, result); + } + } + /* + * ack interrupts + */ + p->scb->cmd = p->scb->status & STAT_MASK; + elmc_id_attn586(); + + /* + * alloc nop/xmit-cmds + */ +#if (NUM_XMIT_BUFFS == 1) + for (i = 0; i < 2; i++) { + p->nop_cmds[i] = (struct nop_cmd_struct *) ptr; + p->nop_cmds[i]->cmd_cmd = CMD_NOP; + p->nop_cmds[i]->cmd_status = 0; + p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i])); + ptr = (char *) ptr + sizeof(struct nop_cmd_struct); + } + p->xmit_cmds[0] = (struct transmit_cmd_struct *) ptr; /* transmit cmd/buff 0 */ + ptr = (char *) ptr + sizeof(struct transmit_cmd_struct); +#else + for (i = 0; i < NUM_XMIT_BUFFS; i++) { + p->nop_cmds[i] = (struct nop_cmd_struct *) ptr; + p->nop_cmds[i]->cmd_cmd = CMD_NOP; + p->nop_cmds[i]->cmd_status = 0; + p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i])); + ptr = (char *) ptr + sizeof(struct nop_cmd_struct); + p->xmit_cmds[i] = (struct transmit_cmd_struct *) ptr; /*transmit cmd/buff 0 */ + ptr = (char *) ptr + sizeof(struct transmit_cmd_struct); + } +#endif + + ptr = alloc_rfa(dev, (void *) ptr); /* init receive-frame-area */ + + /* + * Multicast setup + */ + + if (num_addrs) { + /* I don't understand this: do we really need memory after the init? */ + int len = ((char *) p->iscp - (char *) ptr - 8) / 6; + if (len <= 0) { + pr_err("%s: Ooooops, no memory for MC-Setup!\n", dev->name); + } else { + if (len < num_addrs) { + num_addrs = len; + pr_warning("%s: Sorry, can only apply %d MC-Address(es).\n", + dev->name, num_addrs); + } + mc_cmd = (struct mcsetup_cmd_struct *) ptr; + mc_cmd->cmd_status = 0; + mc_cmd->cmd_cmd = CMD_MCSETUP | CMD_LAST; + mc_cmd->cmd_link = 0xffff; + mc_cmd->mc_cnt = num_addrs * 6; + i = 0; + netdev_for_each_mc_addr(ha, dev) + memcpy((char *) mc_cmd->mc_list[i++], + ha->addr, 6); + p->scb->cbl_offset = make16(mc_cmd); + p->scb->cmd = CUC_START; + elmc_id_attn586(); + s = jiffies; + while (!(mc_cmd->cmd_status & STAT_COMPL)) { + if (time_after(jiffies, s + 30*HZ/100)) + break; + } + if (!(mc_cmd->cmd_status & STAT_COMPL)) { + pr_warning("%s: Can't apply multicast-address-list.\n", dev->name); + } + } + } + /* + * alloc xmit-buffs / init xmit_cmds + */ + for (i = 0; i < NUM_XMIT_BUFFS; i++) { + p->xmit_cbuffs[i] = (char *) ptr; /* char-buffs */ + ptr = (char *) ptr + XMIT_BUFF_SIZE; + p->xmit_buffs[i] = (struct tbd_struct *) ptr; /* TBD */ + ptr = (char *) ptr + sizeof(struct tbd_struct); + if ((void *) ptr > (void *) p->iscp) { + pr_err("%s: not enough shared-mem for your configuration!\n", dev->name); + return 1; + } + memset((char *) (p->xmit_cmds[i]), 0, sizeof(struct transmit_cmd_struct)); + memset((char *) (p->xmit_buffs[i]), 0, sizeof(struct tbd_struct)); + p->xmit_cmds[i]->cmd_status = STAT_COMPL; + p->xmit_cmds[i]->cmd_cmd = CMD_XMIT | CMD_INT; + p->xmit_cmds[i]->tbd_offset = make16((p->xmit_buffs[i])); + p->xmit_buffs[i]->next = 0xffff; + p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i])); + } + + p->xmit_count = 0; + p->xmit_last = 0; +#ifndef NO_NOPCOMMANDS + p->nop_point = 0; +#endif + + /* + * 'start transmitter' (nop-loop) + */ +#ifndef NO_NOPCOMMANDS + p->scb->cbl_offset = make16(p->nop_cmds[0]); + p->scb->cmd = CUC_START; + elmc_id_attn586(); + WAIT_4_SCB_CMD(); +#else + p->xmit_cmds[0]->cmd_link = 0xffff; + p->xmit_cmds[0]->cmd_cmd = CMD_XMIT | CMD_LAST | CMD_INT; +#endif + + return 0; +} + +/****************************************************** + * This is a helper routine for elmc_rnr_int() and init586(). + * It sets up the Receive Frame Area (RFA). + */ + +static void *alloc_rfa(struct net_device *dev, void *ptr) +{ + volatile struct rfd_struct *rfd = (struct rfd_struct *) ptr; + volatile struct rbd_struct *rbd; + int i; + struct priv *p = netdev_priv(dev); + + memset((char *) rfd, 0, sizeof(struct rfd_struct) * p->num_recv_buffs); + p->rfd_first = rfd; + + for (i = 0; i < p->num_recv_buffs; i++) { + rfd[i].next = make16(rfd + (i + 1) % p->num_recv_buffs); + } + rfd[p->num_recv_buffs - 1].last = RFD_SUSP; /* RU suspend */ + + ptr = (void *) (rfd + p->num_recv_buffs); + + rbd = (struct rbd_struct *) ptr; + ptr = (void *) (rbd + p->num_recv_buffs); + + /* clr descriptors */ + memset((char *) rbd, 0, sizeof(struct rbd_struct) * p->num_recv_buffs); + + for (i = 0; i < p->num_recv_buffs; i++) { + rbd[i].next = make16((rbd + (i + 1) % p->num_recv_buffs)); + rbd[i].size = RECV_BUFF_SIZE; + rbd[i].buffer = make24(ptr); + ptr = (char *) ptr + RECV_BUFF_SIZE; + } + + p->rfd_top = p->rfd_first; + p->rfd_last = p->rfd_first + p->num_recv_buffs - 1; + + p->scb->rfa_offset = make16(p->rfd_first); + p->rfd_first->rbd_offset = make16(rbd); + + return ptr; +} + + +/************************************************** + * Interrupt Handler ... + */ + +static irqreturn_t +elmc_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + unsigned short stat; + struct priv *p; + + if (!netif_running(dev)) { + /* The 3c523 has this habit of generating interrupts during the + reset. I'm not sure if the ni52 has this same problem, but it's + really annoying if we haven't finished initializing it. I was + hoping all the elmc_id_* commands would disable this, but I + might have missed a few. */ + + elmc_id_attn586(); /* ack inter. and disable any more */ + return IRQ_HANDLED; + } else if (!(ELMC_CTRL_INT & inb(dev->base_addr + ELMC_CTRL))) { + /* wasn't this device */ + return IRQ_NONE; + } + /* reading ELMC_CTRL also clears the INT bit. */ + + p = netdev_priv(dev); + + while ((stat = p->scb->status & STAT_MASK)) + { + p->scb->cmd = stat; + elmc_attn586(); /* ack inter. */ + + if (stat & STAT_CX) { + /* command with I-bit set complete */ + elmc_xmt_int(dev); + } + if (stat & STAT_FR) { + /* received a frame */ + elmc_rcv_int(dev); + } +#ifndef NO_NOPCOMMANDS + if (stat & STAT_CNA) { + /* CU went 'not ready' */ + if (netif_running(dev)) { + pr_warning("%s: oops! CU has left active state. stat: %04x/%04x.\n", + dev->name, (int) stat, (int) p->scb->status); + } + } +#endif + + if (stat & STAT_RNR) { + /* RU went 'not ready' */ + + if (p->scb->status & RU_SUSPEND) { + /* special case: RU_SUSPEND */ + + WAIT_4_SCB_CMD(); + p->scb->cmd = RUC_RESUME; + elmc_attn586(); + } else { + pr_warning("%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n", + dev->name, (int) stat, (int) p->scb->status); + elmc_rnr_int(dev); + } + } + WAIT_4_SCB_CMD(); /* wait for ack. (elmc_xmt_int can be faster than ack!!) */ + if (p->scb->cmd) { /* timed out? */ + break; + } + } + return IRQ_HANDLED; +} + +/******************************************************* + * receive-interrupt + */ + +static void elmc_rcv_int(struct net_device *dev) +{ + int status; + unsigned short totlen; + struct sk_buff *skb; + struct rbd_struct *rbd; + struct priv *p = netdev_priv(dev); + + for (; (status = p->rfd_top->status) & STAT_COMPL;) { + rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset); + + if (status & STAT_OK) { /* frame received without error? */ + if ((totlen = rbd->status) & RBD_LAST) { /* the first and the last buffer? */ + totlen &= RBD_MASK; /* length of this frame */ + rbd->status = 0; + skb = netdev_alloc_skb(dev, totlen + 2); + if (skb != NULL) { + skb_reserve(skb, 2); /* 16 byte alignment */ + skb_put(skb,totlen); + skb_copy_to_linear_data(skb, (char *) p->base+(unsigned long) rbd->buffer,totlen); + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); + dev->stats.rx_packets++; + dev->stats.rx_bytes += totlen; + } else { + dev->stats.rx_dropped++; + } + } else { + pr_warning("%s: received oversized frame.\n", dev->name); + dev->stats.rx_dropped++; + } + } else { /* frame !(ok), only with 'save-bad-frames' */ + pr_warning("%s: oops! rfd-error-status: %04x\n", dev->name, status); + dev->stats.rx_errors++; + } + p->rfd_top->status = 0; + p->rfd_top->last = RFD_SUSP; + p->rfd_last->last = 0; /* delete RU_SUSP */ + p->rfd_last = p->rfd_top; + p->rfd_top = (struct rfd_struct *) make32(p->rfd_top->next); /* step to next RFD */ + } +} + +/********************************************************** + * handle 'Receiver went not ready'. + */ + +static void elmc_rnr_int(struct net_device *dev) +{ + struct priv *p = netdev_priv(dev); + + dev->stats.rx_errors++; + + WAIT_4_SCB_CMD(); /* wait for the last cmd */ + p->scb->cmd = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */ + elmc_attn586(); + WAIT_4_SCB_CMD(); /* wait for accept cmd. */ + + alloc_rfa(dev, (char *) p->rfd_first); + startrecv586(dev); /* restart RU */ + + pr_warning("%s: Receive-Unit restarted. Status: %04x\n", dev->name, p->scb->status); + +} + +/********************************************************** + * handle xmit - interrupt + */ + +static void elmc_xmt_int(struct net_device *dev) +{ + int status; + struct priv *p = netdev_priv(dev); + + status = p->xmit_cmds[p->xmit_last]->cmd_status; + if (!(status & STAT_COMPL)) { + pr_warning("%s: strange .. xmit-int without a 'COMPLETE'\n", dev->name); + } + if (status & STAT_OK) { + dev->stats.tx_packets++; + dev->stats.collisions += (status & TCMD_MAXCOLLMASK); + } else { + dev->stats.tx_errors++; + if (status & TCMD_LATECOLL) { + pr_warning("%s: late collision detected.\n", dev->name); + dev->stats.collisions++; + } else if (status & TCMD_NOCARRIER) { + dev->stats.tx_carrier_errors++; + pr_warning("%s: no carrier detected.\n", dev->name); + } else if (status & TCMD_LOSTCTS) { + pr_warning("%s: loss of CTS detected.\n", dev->name); + } else if (status & TCMD_UNDERRUN) { + dev->stats.tx_fifo_errors++; + pr_warning("%s: DMA underrun detected.\n", dev->name); + } else if (status & TCMD_MAXCOLL) { + pr_warning("%s: Max. collisions exceeded.\n", dev->name); + dev->stats.collisions += 16; + } + } + +#if (NUM_XMIT_BUFFS != 1) + if ((++p->xmit_last) == NUM_XMIT_BUFFS) { + p->xmit_last = 0; + } +#endif + + netif_wake_queue(dev); +} + +/*********************************************************** + * (re)start the receiver + */ + +static void startrecv586(struct net_device *dev) +{ + struct priv *p = netdev_priv(dev); + + p->scb->rfa_offset = make16(p->rfd_first); + p->scb->cmd = RUC_START; + elmc_attn586(); /* start cmd. */ + WAIT_4_SCB_CMD(); /* wait for accept cmd. (no timeout!!) */ +} + +/****************************************************** + * timeout + */ + +static void elmc_timeout(struct net_device *dev) +{ + struct priv *p = netdev_priv(dev); + /* COMMAND-UNIT active? */ + if (p->scb->status & CU_ACTIVE) { + pr_debug("%s: strange ... timeout with CU active?!?\n", dev->name); + pr_debug("%s: X0: %04x N0: %04x N1: %04x %d\n", dev->name, + (int)p->xmit_cmds[0]->cmd_status, + (int)p->nop_cmds[0]->cmd_status, + (int)p->nop_cmds[1]->cmd_status, (int)p->nop_point); + p->scb->cmd = CUC_ABORT; + elmc_attn586(); + WAIT_4_SCB_CMD(); + p->scb->cbl_offset = make16(p->nop_cmds[p->nop_point]); + p->scb->cmd = CUC_START; + elmc_attn586(); + WAIT_4_SCB_CMD(); + netif_wake_queue(dev); + } else { + pr_debug("%s: xmitter timed out, try to restart! stat: %04x\n", + dev->name, p->scb->status); + pr_debug("%s: command-stats: %04x %04x\n", dev->name, + p->xmit_cmds[0]->cmd_status, p->xmit_cmds[1]->cmd_status); + elmc_close(dev); + elmc_open(dev); + } +} + +/****************************************************** + * send frame + */ + +static netdev_tx_t elmc_send_packet(struct sk_buff *skb, struct net_device *dev) +{ + int len; + int i; +#ifndef NO_NOPCOMMANDS + int next_nop; +#endif + struct priv *p = netdev_priv(dev); + + netif_stop_queue(dev); + + len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; + + if (len != skb->len) + memset((char *) p->xmit_cbuffs[p->xmit_count], 0, ETH_ZLEN); + skb_copy_from_linear_data(skb, (char *) p->xmit_cbuffs[p->xmit_count], skb->len); + +#if (NUM_XMIT_BUFFS == 1) +#ifdef NO_NOPCOMMANDS + p->xmit_buffs[0]->size = TBD_LAST | len; + for (i = 0; i < 16; i++) { + p->scb->cbl_offset = make16(p->xmit_cmds[0]); + p->scb->cmd = CUC_START; + p->xmit_cmds[0]->cmd_status = 0; + elmc_attn586(); + if (!i) { + dev_kfree_skb(skb); + } + WAIT_4_SCB_CMD(); + if ((p->scb->status & CU_ACTIVE)) { /* test it, because CU sometimes doesn't start immediately */ + break; + } + if (p->xmit_cmds[0]->cmd_status) { + break; + } + if (i == 15) { + pr_warning("%s: Can't start transmit-command.\n", dev->name); + } + } +#else + next_nop = (p->nop_point + 1) & 0x1; + p->xmit_buffs[0]->size = TBD_LAST | len; + + p->xmit_cmds[0]->cmd_link = p->nop_cmds[next_nop]->cmd_link + = make16((p->nop_cmds[next_nop])); + p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0; + + p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0])); + p->nop_point = next_nop; + dev_kfree_skb(skb); +#endif +#else + p->xmit_buffs[p->xmit_count]->size = TBD_LAST | len; + if ((next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS) { + next_nop = 0; + } + p->xmit_cmds[p->xmit_count]->cmd_status = 0; + p->xmit_cmds[p->xmit_count]->cmd_link = p->nop_cmds[next_nop]->cmd_link + = make16((p->nop_cmds[next_nop])); + p->nop_cmds[next_nop]->cmd_status = 0; + p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count])); + p->xmit_count = next_nop; + if (p->xmit_count != p->xmit_last) + netif_wake_queue(dev); + dev_kfree_skb(skb); +#endif + return NETDEV_TX_OK; +} + +/******************************************* + * Someone wanna have the statistics + */ + +static struct net_device_stats *elmc_get_stats(struct net_device *dev) +{ + struct priv *p = netdev_priv(dev); + unsigned short crc, aln, rsc, ovrn; + + crc = p->scb->crc_errs; /* get error-statistic from the ni82586 */ + p->scb->crc_errs -= crc; + aln = p->scb->aln_errs; + p->scb->aln_errs -= aln; + rsc = p->scb->rsc_errs; + p->scb->rsc_errs -= rsc; + ovrn = p->scb->ovrn_errs; + p->scb->ovrn_errs -= ovrn; + + dev->stats.rx_crc_errors += crc; + dev->stats.rx_fifo_errors += ovrn; + dev->stats.rx_frame_errors += aln; + dev->stats.rx_dropped += rsc; + + return &dev->stats; +} + +/******************************************************** + * Set MC list .. + */ + +#ifdef ELMC_MULTICAST +static void set_multicast_list(struct net_device *dev) +{ + if (!dev->start) { + /* without a running interface, promiscuous doesn't work */ + return; + } + dev->start = 0; + alloc586(dev); + init586(dev); + startrecv586(dev); + dev->start = 1; +} +#endif + +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "MCA 0x%lx", dev->base_addr); +} + +static const struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, +}; + +#ifdef MODULE + +/* Increase if needed ;) */ +#define MAX_3C523_CARDS 4 + +static struct net_device *dev_elmc[MAX_3C523_CARDS]; +static int irq[MAX_3C523_CARDS]; +static int io[MAX_3C523_CARDS]; +module_param_array(irq, int, NULL, 0); +module_param_array(io, int, NULL, 0); +MODULE_PARM_DESC(io, "EtherLink/MC I/O base address(es)"); +MODULE_PARM_DESC(irq, "EtherLink/MC IRQ number(s)"); +MODULE_LICENSE("GPL"); + +int __init init_module(void) +{ + int this_dev,found = 0; + + /* Loop until we either can't find any more cards, or we have MAX_3C523_CARDS */ + for(this_dev=0; this_devirq=irq[this_dev]; + dev->base_addr=io[this_dev]; + if (do_elmc_probe(dev) == 0) { + dev_elmc[this_dev] = dev; + found++; + continue; + } + free_netdev(dev); + if (io[this_dev]==0) + break; + pr_warning("3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]); + } + + if(found==0) { + if (io[0]==0) + pr_notice("3c523.c: No 3c523 cards found\n"); + return -ENXIO; + } else return 0; +} + +void __exit cleanup_module(void) +{ + int this_dev; + for (this_dev=0; this_dev + * Heavily modified by Richard Procter + * + * Based on skeleton.c written 1993-94 by Donald Becker and ne2.c + * (for the MCA stuff) written by Wim Dumon. + * + * Thanks to 3Com for making this possible by providing me with the + * documentation. + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + */ + +#define DRV_NAME "3c527" +#define DRV_VERSION "0.7-SMP" +#define DRV_RELDATE "2003/09/21" + +static const char *version = +DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Richard Procter \n"; + +/** + * DOC: Traps for the unwary + * + * The diagram (Figure 1-1) and the POS summary disagree with the + * "Interrupt Level" section in the manual. + * + * The manual contradicts itself when describing the minimum number + * buffers in the 'configure lists' command. + * My card accepts a buffer config of 4/4. + * + * Setting the SAV BP bit does not save bad packets, but + * only enables RX on-card stats collection. + * + * The documentation in places seems to miss things. In actual fact + * I've always eventually found everything is documented, it just + * requires careful study. + * + * DOC: Theory Of Operation + * + * The 3com 3c527 is a 32bit MCA bus mastering adapter with a large + * amount of on board intelligence that housekeeps a somewhat dumber + * Intel NIC. For performance we want to keep the transmit queue deep + * as the card can transmit packets while fetching others from main + * memory by bus master DMA. Transmission and reception are driven by + * circular buffer queues. + * + * The mailboxes can be used for controlling how the card traverses + * its buffer rings, but are used only for initial setup in this + * implementation. The exec mailbox allows a variety of commands to + * be executed. Each command must complete before the next is + * executed. Primarily we use the exec mailbox for controlling the + * multicast lists. We have to do a certain amount of interesting + * hoop jumping as the multicast list changes can occur in interrupt + * state when the card has an exec command pending. We defer such + * events until the command completion interrupt. + * + * A copy break scheme (taken from 3c59x.c) is employed whereby + * received frames exceeding a configurable length are passed + * directly to the higher networking layers without incuring a copy, + * in what amounts to a time/space trade-off. + * + * The card also keeps a large amount of statistical information + * on-board. In a perfect world, these could be used safely at no + * cost. However, lacking information to the contrary, processing + * them without races would involve so much extra complexity as to + * make it unworthwhile to do so. In the end, a hybrid SW/HW + * implementation was made necessary --- see mc32_update_stats(). + * + * DOC: Notes + * + * It should be possible to use two or more cards, but at this stage + * only by loading two copies of the same module. + * + * The on-board 82586 NIC has trouble receiving multiple + * back-to-back frames and so is likely to drop packets from fast + * senders. +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "3c527.h" + +MODULE_LICENSE("GPL"); + +/* + * The name of the card. Is used for messages and in the requests for + * io regions, irqs and dma channels + */ +static const char* cardname = DRV_NAME; + +/* use 0 for production, 1 for verification, >2 for debug */ +#ifndef NET_DEBUG +#define NET_DEBUG 2 +#endif + +static unsigned int mc32_debug = NET_DEBUG; + +/* The number of low I/O ports used by the ethercard. */ +#define MC32_IO_EXTENT 8 + +/* As implemented, values must be a power-of-2 -- 4/8/16/32 */ +#define TX_RING_LEN 32 /* Typically the card supports 37 */ +#define RX_RING_LEN 8 /* " " " */ + +/* Copy break point, see above for details. + * Setting to > 1512 effectively disables this feature. */ +#define RX_COPYBREAK 200 /* Value from 3c59x.c */ + +/* Issue the 82586 workaround command - this is for "busy lans", but + * basically means for all lans now days - has a performance (latency) + * cost, but best set. */ +static const int WORKAROUND_82586=1; + +/* Pointers to buffers and their on-card records */ +struct mc32_ring_desc +{ + volatile struct skb_header *p; + struct sk_buff *skb; +}; + +/* Information that needs to be kept for each board. */ +struct mc32_local +{ + int slot; + + u32 base; + volatile struct mc32_mailbox *rx_box; + volatile struct mc32_mailbox *tx_box; + volatile struct mc32_mailbox *exec_box; + volatile struct mc32_stats *stats; /* Start of on-card statistics */ + u16 tx_chain; /* Transmit list start offset */ + u16 rx_chain; /* Receive list start offset */ + u16 tx_len; /* Transmit list count */ + u16 rx_len; /* Receive list count */ + + u16 xceiver_desired_state; /* HALTED or RUNNING */ + u16 cmd_nonblocking; /* Thread is uninterested in command result */ + u16 mc_reload_wait; /* A multicast load request is pending */ + u32 mc_list_valid; /* True when the mclist is set */ + + struct mc32_ring_desc tx_ring[TX_RING_LEN]; /* Host Transmit ring */ + struct mc32_ring_desc rx_ring[RX_RING_LEN]; /* Host Receive ring */ + + atomic_t tx_count; /* buffers left */ + atomic_t tx_ring_head; /* index to tx en-queue end */ + u16 tx_ring_tail; /* index to tx de-queue end */ + + u16 rx_ring_tail; /* index to rx de-queue end */ + + struct semaphore cmd_mutex; /* Serialises issuing of execute commands */ + struct completion execution_cmd; /* Card has completed an execute command */ + struct completion xceiver_cmd; /* Card has completed a tx or rx command */ +}; + +/* The station (ethernet) address prefix, used for a sanity check. */ +#define SA_ADDR0 0x02 +#define SA_ADDR1 0x60 +#define SA_ADDR2 0xAC + +struct mca_adapters_t { + unsigned int id; + char *name; +}; + +static const struct mca_adapters_t mc32_adapters[] = { + { 0x0041, "3COM EtherLink MC/32" }, + { 0x8EF5, "IBM High Performance Lan Adapter" }, + { 0x0000, NULL } +}; + + +/* Macros for ring index manipulations */ +static inline u16 next_rx(u16 rx) { return (rx+1)&(RX_RING_LEN-1); }; +static inline u16 prev_rx(u16 rx) { return (rx-1)&(RX_RING_LEN-1); }; + +static inline u16 next_tx(u16 tx) { return (tx+1)&(TX_RING_LEN-1); }; + + +/* Index to functions, as function prototypes. */ +static int mc32_probe1(struct net_device *dev, int ioaddr); +static int mc32_command(struct net_device *dev, u16 cmd, void *data, int len); +static int mc32_open(struct net_device *dev); +static void mc32_timeout(struct net_device *dev); +static netdev_tx_t mc32_send_packet(struct sk_buff *skb, + struct net_device *dev); +static irqreturn_t mc32_interrupt(int irq, void *dev_id); +static int mc32_close(struct net_device *dev); +static struct net_device_stats *mc32_get_stats(struct net_device *dev); +static void mc32_set_multicast_list(struct net_device *dev); +static void mc32_reset_multicast_list(struct net_device *dev); +static const struct ethtool_ops netdev_ethtool_ops; + +static void cleanup_card(struct net_device *dev) +{ + struct mc32_local *lp = netdev_priv(dev); + unsigned slot = lp->slot; + mca_mark_as_unused(slot); + mca_set_adapter_name(slot, NULL); + free_irq(dev->irq, dev); + release_region(dev->base_addr, MC32_IO_EXTENT); +} + +/** + * mc32_probe - Search for supported boards + * @unit: interface number to use + * + * Because MCA bus is a real bus and we can scan for cards we could do a + * single scan for all boards here. Right now we use the passed in device + * structure and scan for only one board. This needs fixing for modules + * in particular. + */ + +struct net_device *__init mc32_probe(int unit) +{ + struct net_device *dev = alloc_etherdev(sizeof(struct mc32_local)); + static int current_mca_slot = -1; + int i; + int err; + + if (!dev) + return ERR_PTR(-ENOMEM); + + if (unit >= 0) + sprintf(dev->name, "eth%d", unit); + + /* Do not check any supplied i/o locations. + POS registers usually don't fail :) */ + + /* MCA cards have POS registers. + Autodetecting MCA cards is extremely simple. + Just search for the card. */ + + for(i = 0; (mc32_adapters[i].name != NULL); i++) { + current_mca_slot = + mca_find_unused_adapter(mc32_adapters[i].id, 0); + + if(current_mca_slot != MCA_NOTFOUND) { + if(!mc32_probe1(dev, current_mca_slot)) + { + mca_set_adapter_name(current_mca_slot, + mc32_adapters[i].name); + mca_mark_as_used(current_mca_slot); + err = register_netdev(dev); + if (err) { + cleanup_card(dev); + free_netdev(dev); + dev = ERR_PTR(err); + } + return dev; + } + + } + } + free_netdev(dev); + return ERR_PTR(-ENODEV); +} + +static const struct net_device_ops netdev_ops = { + .ndo_open = mc32_open, + .ndo_stop = mc32_close, + .ndo_start_xmit = mc32_send_packet, + .ndo_get_stats = mc32_get_stats, + .ndo_set_rx_mode = mc32_set_multicast_list, + .ndo_tx_timeout = mc32_timeout, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + +/** + * mc32_probe1 - Check a given slot for a board and test the card + * @dev: Device structure to fill in + * @slot: The MCA bus slot being used by this card + * + * Decode the slot data and configure the card structures. Having done this we + * can reset the card and configure it. The card does a full self test cycle + * in firmware so we have to wait for it to return and post us either a + * failure case or some addresses we use to find the board internals. + */ + +static int __init mc32_probe1(struct net_device *dev, int slot) +{ + static unsigned version_printed; + int i, err; + u8 POS; + u32 base; + struct mc32_local *lp = netdev_priv(dev); + static const u16 mca_io_bases[] = { + 0x7280,0x7290, + 0x7680,0x7690, + 0x7A80,0x7A90, + 0x7E80,0x7E90 + }; + static const u32 mca_mem_bases[] = { + 0x00C0000, + 0x00C4000, + 0x00C8000, + 0x00CC000, + 0x00D0000, + 0x00D4000, + 0x00D8000, + 0x00DC000 + }; + static const char * const failures[] = { + "Processor instruction", + "Processor data bus", + "Processor data bus", + "Processor data bus", + "Adapter bus", + "ROM checksum", + "Base RAM", + "Extended RAM", + "82586 internal loopback", + "82586 initialisation failure", + "Adapter list configuration error" + }; + + /* Time to play MCA games */ + + if (mc32_debug && version_printed++ == 0) + pr_debug("%s", version); + + pr_info("%s: %s found in slot %d: ", dev->name, cardname, slot); + + POS = mca_read_stored_pos(slot, 2); + + if(!(POS&1)) + { + pr_cont("disabled.\n"); + return -ENODEV; + } + + /* Fill in the 'dev' fields. */ + dev->base_addr = mca_io_bases[(POS>>1)&7]; + dev->mem_start = mca_mem_bases[(POS>>4)&7]; + + POS = mca_read_stored_pos(slot, 4); + if(!(POS&1)) + { + pr_cont("memory window disabled.\n"); + return -ENODEV; + } + + POS = mca_read_stored_pos(slot, 5); + + i=(POS>>4)&3; + if(i==3) + { + pr_cont("invalid memory window.\n"); + return -ENODEV; + } + + i*=16384; + i+=16384; + + dev->mem_end=dev->mem_start + i; + + dev->irq = ((POS>>2)&3)+9; + + if(!request_region(dev->base_addr, MC32_IO_EXTENT, cardname)) + { + pr_cont("io 0x%3lX, which is busy.\n", dev->base_addr); + return -EBUSY; + } + + pr_cont("io 0x%3lX irq %d mem 0x%lX (%dK)\n", + dev->base_addr, dev->irq, dev->mem_start, i/1024); + + + /* We ought to set the cache line size here.. */ + + + /* + * Go PROM browsing + */ + + /* Retrieve and print the ethernet address. */ + for (i = 0; i < 6; i++) + { + mca_write_pos(slot, 6, i+12); + mca_write_pos(slot, 7, 0); + + dev->dev_addr[i] = mca_read_pos(slot,3); + } + + pr_info("%s: Address %pM ", dev->name, dev->dev_addr); + + mca_write_pos(slot, 6, 0); + mca_write_pos(slot, 7, 0); + + POS = mca_read_stored_pos(slot, 4); + + if(POS&2) + pr_cont(": BNC port selected.\n"); + else + pr_cont(": AUI port selected.\n"); + + POS=inb(dev->base_addr+HOST_CTRL); + POS|=HOST_CTRL_ATTN|HOST_CTRL_RESET; + POS&=~HOST_CTRL_INTE; + outb(POS, dev->base_addr+HOST_CTRL); + /* Reset adapter */ + udelay(100); + /* Reset off */ + POS&=~(HOST_CTRL_ATTN|HOST_CTRL_RESET); + outb(POS, dev->base_addr+HOST_CTRL); + + udelay(300); + + /* + * Grab the IRQ + */ + + err = request_irq(dev->irq, mc32_interrupt, IRQF_SHARED, DRV_NAME, dev); + if (err) { + release_region(dev->base_addr, MC32_IO_EXTENT); + pr_err("%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq); + goto err_exit_ports; + } + + memset(lp, 0, sizeof(struct mc32_local)); + lp->slot = slot; + + i=0; + + base = inb(dev->base_addr); + + while(base == 0xFF) + { + i++; + if(i == 1000) + { + pr_err("%s: failed to boot adapter.\n", dev->name); + err = -ENODEV; + goto err_exit_irq; + } + udelay(1000); + if(inb(dev->base_addr+2)&(1<<5)) + base = inb(dev->base_addr); + } + + if(base>0) + { + if(base < 0x0C) + pr_err("%s: %s%s.\n", dev->name, failures[base-1], + base<0x0A?" test failure":""); + else + pr_err("%s: unknown failure %d.\n", dev->name, base); + err = -ENODEV; + goto err_exit_irq; + } + + base=0; + for(i=0;i<4;i++) + { + int n=0; + + while(!(inb(dev->base_addr+2)&(1<<5))) + { + n++; + udelay(50); + if(n>100) + { + pr_err("%s: mailbox read fail (%d).\n", dev->name, i); + err = -ENODEV; + goto err_exit_irq; + } + } + + base|=(inb(dev->base_addr)<<(8*i)); + } + + lp->exec_box=isa_bus_to_virt(dev->mem_start+base); + + base=lp->exec_box->data[1]<<16|lp->exec_box->data[0]; + + lp->base = dev->mem_start+base; + + lp->rx_box=isa_bus_to_virt(lp->base + lp->exec_box->data[2]); + lp->tx_box=isa_bus_to_virt(lp->base + lp->exec_box->data[3]); + + lp->stats = isa_bus_to_virt(lp->base + lp->exec_box->data[5]); + + /* + * Descriptor chains (card relative) + */ + + lp->tx_chain = lp->exec_box->data[8]; /* Transmit list start offset */ + lp->rx_chain = lp->exec_box->data[10]; /* Receive list start offset */ + lp->tx_len = lp->exec_box->data[9]; /* Transmit list count */ + lp->rx_len = lp->exec_box->data[11]; /* Receive list count */ + + sema_init(&lp->cmd_mutex, 0); + init_completion(&lp->execution_cmd); + init_completion(&lp->xceiver_cmd); + + pr_info("%s: Firmware Rev %d. %d RX buffers, %d TX buffers. Base of 0x%08X.\n", + dev->name, lp->exec_box->data[12], lp->rx_len, lp->tx_len, lp->base); + + dev->netdev_ops = &netdev_ops; + dev->watchdog_timeo = HZ*5; /* Board does all the work */ + dev->ethtool_ops = &netdev_ethtool_ops; + + return 0; + +err_exit_irq: + free_irq(dev->irq, dev); +err_exit_ports: + release_region(dev->base_addr, MC32_IO_EXTENT); + return err; +} + + +/** + * mc32_ready_poll - wait until we can feed it a command + * @dev: The device to wait for + * + * Wait until the card becomes ready to accept a command via the + * command register. This tells us nothing about the completion + * status of any pending commands and takes very little time at all. + */ + +static inline void mc32_ready_poll(struct net_device *dev) +{ + int ioaddr = dev->base_addr; + while(!(inb(ioaddr+HOST_STATUS)&HOST_STATUS_CRR)); +} + + +/** + * mc32_command_nowait - send a command non blocking + * @dev: The 3c527 to issue the command to + * @cmd: The command word to write to the mailbox + * @data: A data block if the command expects one + * @len: Length of the data block + * + * Send a command from interrupt state. If there is a command + * currently being executed then we return an error of -1. It + * simply isn't viable to wait around as commands may be + * slow. This can theoretically be starved on SMP, but it's hard + * to see a realistic situation. We do not wait for the command + * to complete --- we rely on the interrupt handler to tidy up + * after us. + */ + +static int mc32_command_nowait(struct net_device *dev, u16 cmd, void *data, int len) +{ + struct mc32_local *lp = netdev_priv(dev); + int ioaddr = dev->base_addr; + int ret = -1; + + if (down_trylock(&lp->cmd_mutex) == 0) + { + lp->cmd_nonblocking=1; + lp->exec_box->mbox=0; + lp->exec_box->mbox=cmd; + memcpy((void *)lp->exec_box->data, data, len); + barrier(); /* the memcpy forgot the volatile so be sure */ + + /* Send the command */ + mc32_ready_poll(dev); + outb(1<<6, ioaddr+HOST_CMD); + + ret = 0; + + /* Interrupt handler will signal mutex on completion */ + } + + return ret; +} + + +/** + * mc32_command - send a command and sleep until completion + * @dev: The 3c527 card to issue the command to + * @cmd: The command word to write to the mailbox + * @data: A data block if the command expects one + * @len: Length of the data block + * + * Sends exec commands in a user context. This permits us to wait around + * for the replies and also to wait for the command buffer to complete + * from a previous command before we execute our command. After our + * command completes we will attempt any pending multicast reload + * we blocked off by hogging the exec buffer. + * + * You feed the card a command, you wait, it interrupts you get a + * reply. All well and good. The complication arises because you use + * commands for filter list changes which come in at bh level from things + * like IPV6 group stuff. + */ + +static int mc32_command(struct net_device *dev, u16 cmd, void *data, int len) +{ + struct mc32_local *lp = netdev_priv(dev); + int ioaddr = dev->base_addr; + int ret = 0; + + down(&lp->cmd_mutex); + + /* + * My Turn + */ + + lp->cmd_nonblocking=0; + lp->exec_box->mbox=0; + lp->exec_box->mbox=cmd; + memcpy((void *)lp->exec_box->data, data, len); + barrier(); /* the memcpy forgot the volatile so be sure */ + + mc32_ready_poll(dev); + outb(1<<6, ioaddr+HOST_CMD); + + wait_for_completion(&lp->execution_cmd); + + if(lp->exec_box->mbox&(1<<13)) + ret = -1; + + up(&lp->cmd_mutex); + + /* + * A multicast set got blocked - try it now + */ + + if(lp->mc_reload_wait) + { + mc32_reset_multicast_list(dev); + } + + return ret; +} + + +/** + * mc32_start_transceiver - tell board to restart tx/rx + * @dev: The 3c527 card to issue the command to + * + * This may be called from the interrupt state, where it is used + * to restart the rx ring if the card runs out of rx buffers. + * + * We must first check if it's ok to (re)start the transceiver. See + * mc32_close for details. + */ + +static void mc32_start_transceiver(struct net_device *dev) { + + struct mc32_local *lp = netdev_priv(dev); + int ioaddr = dev->base_addr; + + /* Ignore RX overflow on device closure */ + if (lp->xceiver_desired_state==HALTED) + return; + + /* Give the card the offset to the post-EOL-bit RX descriptor */ + mc32_ready_poll(dev); + lp->rx_box->mbox=0; + lp->rx_box->data[0]=lp->rx_ring[prev_rx(lp->rx_ring_tail)].p->next; + outb(HOST_CMD_START_RX, ioaddr+HOST_CMD); + + mc32_ready_poll(dev); + lp->tx_box->mbox=0; + outb(HOST_CMD_RESTRT_TX, ioaddr+HOST_CMD); /* card ignores this on RX restart */ + + /* We are not interrupted on start completion */ +} + + +/** + * mc32_halt_transceiver - tell board to stop tx/rx + * @dev: The 3c527 card to issue the command to + * + * We issue the commands to halt the card's transceiver. In fact, + * after some experimenting we now simply tell the card to + * suspend. When issuing aborts occasionally odd things happened. + * + * We then sleep until the card has notified us that both rx and + * tx have been suspended. + */ + +static void mc32_halt_transceiver(struct net_device *dev) +{ + struct mc32_local *lp = netdev_priv(dev); + int ioaddr = dev->base_addr; + + mc32_ready_poll(dev); + lp->rx_box->mbox=0; + outb(HOST_CMD_SUSPND_RX, ioaddr+HOST_CMD); + wait_for_completion(&lp->xceiver_cmd); + + mc32_ready_poll(dev); + lp->tx_box->mbox=0; + outb(HOST_CMD_SUSPND_TX, ioaddr+HOST_CMD); + wait_for_completion(&lp->xceiver_cmd); +} + + +/** + * mc32_load_rx_ring - load the ring of receive buffers + * @dev: 3c527 to build the ring for + * + * This initialises the on-card and driver datastructures to + * the point where mc32_start_transceiver() can be called. + * + * The card sets up the receive ring for us. We are required to use the + * ring it provides, although the size of the ring is configurable. + * + * We allocate an sk_buff for each ring entry in turn and + * initialise its house-keeping info. At the same time, we read + * each 'next' pointer in our rx_ring array. This reduces slow + * shared-memory reads and makes it easy to access predecessor + * descriptors. + * + * We then set the end-of-list bit for the last entry so that the + * card will know when it has run out of buffers. + */ + +static int mc32_load_rx_ring(struct net_device *dev) +{ + struct mc32_local *lp = netdev_priv(dev); + int i; + u16 rx_base; + volatile struct skb_header *p; + + rx_base=lp->rx_chain; + + for(i=0; irx_ring[i].skb=alloc_skb(1532, GFP_KERNEL); + if (lp->rx_ring[i].skb==NULL) { + for (;i>=0;i--) + kfree_skb(lp->rx_ring[i].skb); + return -ENOBUFS; + } + skb_reserve(lp->rx_ring[i].skb, 18); + + p=isa_bus_to_virt(lp->base+rx_base); + + p->control=0; + p->data=isa_virt_to_bus(lp->rx_ring[i].skb->data); + p->status=0; + p->length=1532; + + lp->rx_ring[i].p=p; + rx_base=p->next; + } + + lp->rx_ring[i-1].p->control |= CONTROL_EOL; + + lp->rx_ring_tail=0; + + return 0; +} + + +/** + * mc32_flush_rx_ring - free the ring of receive buffers + * @lp: Local data of 3c527 to flush the rx ring of + * + * Free the buffer for each ring slot. This may be called + * before mc32_load_rx_ring(), eg. on error in mc32_open(). + * Requires rx skb pointers to point to a valid skb, or NULL. + */ + +static void mc32_flush_rx_ring(struct net_device *dev) +{ + struct mc32_local *lp = netdev_priv(dev); + int i; + + for(i=0; i < RX_RING_LEN; i++) + { + if (lp->rx_ring[i].skb) { + dev_kfree_skb(lp->rx_ring[i].skb); + lp->rx_ring[i].skb = NULL; + } + lp->rx_ring[i].p=NULL; + } +} + + +/** + * mc32_load_tx_ring - load transmit ring + * @dev: The 3c527 card to issue the command to + * + * This sets up the host transmit data-structures. + * + * First, we obtain from the card it's current position in the tx + * ring, so that we will know where to begin transmitting + * packets. + * + * Then, we read the 'next' pointers from the on-card tx ring into + * our tx_ring array to reduce slow shared-mem reads. Finally, we + * intitalise the tx house keeping variables. + * + */ + +static void mc32_load_tx_ring(struct net_device *dev) +{ + struct mc32_local *lp = netdev_priv(dev); + volatile struct skb_header *p; + int i; + u16 tx_base; + + tx_base=lp->tx_box->data[0]; + + for(i=0 ; ibase+tx_base); + lp->tx_ring[i].p=p; + lp->tx_ring[i].skb=NULL; + + tx_base=p->next; + } + + /* -1 so that tx_ring_head cannot "lap" tx_ring_tail */ + /* see mc32_tx_ring */ + + atomic_set(&lp->tx_count, TX_RING_LEN-1); + atomic_set(&lp->tx_ring_head, 0); + lp->tx_ring_tail=0; +} + + +/** + * mc32_flush_tx_ring - free transmit ring + * @lp: Local data of 3c527 to flush the tx ring of + * + * If the ring is non-empty, zip over the it, freeing any + * allocated skb_buffs. The tx ring house-keeping variables are + * then reset. Requires rx skb pointers to point to a valid skb, + * or NULL. + */ + +static void mc32_flush_tx_ring(struct net_device *dev) +{ + struct mc32_local *lp = netdev_priv(dev); + int i; + + for (i=0; i < TX_RING_LEN; i++) + { + if (lp->tx_ring[i].skb) + { + dev_kfree_skb(lp->tx_ring[i].skb); + lp->tx_ring[i].skb = NULL; + } + } + + atomic_set(&lp->tx_count, 0); + atomic_set(&lp->tx_ring_head, 0); + lp->tx_ring_tail=0; +} + + +/** + * mc32_open - handle 'up' of card + * @dev: device to open + * + * The user is trying to bring the card into ready state. This requires + * a brief dialogue with the card. Firstly we enable interrupts and then + * 'indications'. Without these enabled the card doesn't bother telling + * us what it has done. This had me puzzled for a week. + * + * We configure the number of card descriptors, then load the network + * address and multicast filters. Turn on the workaround mode. This + * works around a bug in the 82586 - it asks the firmware to do + * so. It has a performance (latency) hit but is needed on busy + * [read most] lans. We load the ring with buffers then we kick it + * all off. + */ + +static int mc32_open(struct net_device *dev) +{ + int ioaddr = dev->base_addr; + struct mc32_local *lp = netdev_priv(dev); + u8 one=1; + u8 regs; + u16 descnumbuffs[2] = {TX_RING_LEN, RX_RING_LEN}; + + /* + * Interrupts enabled + */ + + regs=inb(ioaddr+HOST_CTRL); + regs|=HOST_CTRL_INTE; + outb(regs, ioaddr+HOST_CTRL); + + /* + * Allow ourselves to issue commands + */ + + up(&lp->cmd_mutex); + + + /* + * Send the indications on command + */ + + mc32_command(dev, 4, &one, 2); + + /* + * Poke it to make sure it's really dead. + */ + + mc32_halt_transceiver(dev); + mc32_flush_tx_ring(dev); + + /* + * Ask card to set up on-card descriptors to our spec + */ + + if(mc32_command(dev, 8, descnumbuffs, 4)) { + pr_info("%s: %s rejected our buffer configuration!\n", + dev->name, cardname); + mc32_close(dev); + return -ENOBUFS; + } + + /* Report new configuration */ + mc32_command(dev, 6, NULL, 0); + + lp->tx_chain = lp->exec_box->data[8]; /* Transmit list start offset */ + lp->rx_chain = lp->exec_box->data[10]; /* Receive list start offset */ + lp->tx_len = lp->exec_box->data[9]; /* Transmit list count */ + lp->rx_len = lp->exec_box->data[11]; /* Receive list count */ + + /* Set Network Address */ + mc32_command(dev, 1, dev->dev_addr, 6); + + /* Set the filters */ + mc32_set_multicast_list(dev); + + if (WORKAROUND_82586) { + u16 zero_word=0; + mc32_command(dev, 0x0D, &zero_word, 2); /* 82586 bug workaround on */ + } + + mc32_load_tx_ring(dev); + + if(mc32_load_rx_ring(dev)) + { + mc32_close(dev); + return -ENOBUFS; + } + + lp->xceiver_desired_state = RUNNING; + + /* And finally, set the ball rolling... */ + mc32_start_transceiver(dev); + + netif_start_queue(dev); + + return 0; +} + + +/** + * mc32_timeout - handle a timeout from the network layer + * @dev: 3c527 that timed out + * + * Handle a timeout on transmit from the 3c527. This normally means + * bad things as the hardware handles cable timeouts and mess for + * us. + * + */ + +static void mc32_timeout(struct net_device *dev) +{ + pr_warning("%s: transmit timed out?\n", dev->name); + /* Try to restart the adaptor. */ + netif_wake_queue(dev); +} + + +/** + * mc32_send_packet - queue a frame for transmit + * @skb: buffer to transmit + * @dev: 3c527 to send it out of + * + * Transmit a buffer. This normally means throwing the buffer onto + * the transmit queue as the queue is quite large. If the queue is + * full then we set tx_busy and return. Once the interrupt handler + * gets messages telling it to reclaim transmit queue entries, we will + * clear tx_busy and the kernel will start calling this again. + * + * We do not disable interrupts or acquire any locks; this can + * run concurrently with mc32_tx_ring(), and the function itself + * is serialised at a higher layer. However, similarly for the + * card itself, we must ensure that we update tx_ring_head only + * after we've established a valid packet on the tx ring (and + * before we let the card "see" it, to prevent it racing with the + * irq handler). + * + */ + +static netdev_tx_t mc32_send_packet(struct sk_buff *skb, + struct net_device *dev) +{ + struct mc32_local *lp = netdev_priv(dev); + u32 head = atomic_read(&lp->tx_ring_head); + + volatile struct skb_header *p, *np; + + netif_stop_queue(dev); + + if(atomic_read(&lp->tx_count)==0) { + return NETDEV_TX_BUSY; + } + + if (skb_padto(skb, ETH_ZLEN)) { + netif_wake_queue(dev); + return NETDEV_TX_OK; + } + + atomic_dec(&lp->tx_count); + + /* P is the last sending/sent buffer as a pointer */ + p=lp->tx_ring[head].p; + + head = next_tx(head); + + /* NP is the buffer we will be loading */ + np=lp->tx_ring[head].p; + + /* We will need this to flush the buffer out */ + lp->tx_ring[head].skb=skb; + + np->length = unlikely(skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len; + np->data = isa_virt_to_bus(skb->data); + np->status = 0; + np->control = CONTROL_EOP | CONTROL_EOL; + wmb(); + + /* + * The new frame has been setup; we can now + * let the interrupt handler and card "see" it + */ + + atomic_set(&lp->tx_ring_head, head); + p->control &= ~CONTROL_EOL; + + netif_wake_queue(dev); + return NETDEV_TX_OK; +} + + +/** + * mc32_update_stats - pull off the on board statistics + * @dev: 3c527 to service + * + * + * Query and reset the on-card stats. There's the small possibility + * of a race here, which would result in an underestimation of + * actual errors. As such, we'd prefer to keep all our stats + * collection in software. As a rule, we do. However it can't be + * used for rx errors and collisions as, by default, the card discards + * bad rx packets. + * + * Setting the SAV BP in the rx filter command supposedly + * stops this behaviour. However, testing shows that it only seems to + * enable the collation of on-card rx statistics --- the driver + * never sees an RX descriptor with an error status set. + * + */ + +static void mc32_update_stats(struct net_device *dev) +{ + struct mc32_local *lp = netdev_priv(dev); + volatile struct mc32_stats *st = lp->stats; + + u32 rx_errors=0; + + rx_errors+=dev->stats.rx_crc_errors +=st->rx_crc_errors; + st->rx_crc_errors=0; + rx_errors+=dev->stats.rx_fifo_errors +=st->rx_overrun_errors; + st->rx_overrun_errors=0; + rx_errors+=dev->stats.rx_frame_errors +=st->rx_alignment_errors; + st->rx_alignment_errors=0; + rx_errors+=dev->stats.rx_length_errors+=st->rx_tooshort_errors; + st->rx_tooshort_errors=0; + rx_errors+=dev->stats.rx_missed_errors+=st->rx_outofresource_errors; + st->rx_outofresource_errors=0; + dev->stats.rx_errors=rx_errors; + + /* Number of packets which saw one collision */ + dev->stats.collisions+=st->dataC[10]; + st->dataC[10]=0; + + /* Number of packets which saw 2--15 collisions */ + dev->stats.collisions+=st->dataC[11]; + st->dataC[11]=0; +} + + +/** + * mc32_rx_ring - process the receive ring + * @dev: 3c527 that needs its receive ring processing + * + * + * We have received one or more indications from the card that a + * receive has completed. The buffer ring thus contains dirty + * entries. We walk the ring by iterating over the circular rx_ring + * array, starting at the next dirty buffer (which happens to be the + * one we finished up at last time around). + * + * For each completed packet, we will either copy it and pass it up + * the stack or, if the packet is near MTU sized, we allocate + * another buffer and flip the old one up the stack. + * + * We must succeed in keeping a buffer on the ring. If necessary we + * will toss a received packet rather than lose a ring entry. Once + * the first uncompleted descriptor is found, we move the + * End-Of-List bit to include the buffers just processed. + * + */ + +static void mc32_rx_ring(struct net_device *dev) +{ + struct mc32_local *lp = netdev_priv(dev); + volatile struct skb_header *p; + u16 rx_ring_tail; + u16 rx_old_tail; + int x=0; + + rx_old_tail = rx_ring_tail = lp->rx_ring_tail; + + do + { + p=lp->rx_ring[rx_ring_tail].p; + + if(!(p->status & (1<<7))) { /* Not COMPLETED */ + break; + } + if(p->status & (1<<6)) /* COMPLETED_OK */ + { + + u16 length=p->length; + struct sk_buff *skb; + struct sk_buff *newskb; + + /* Try to save time by avoiding a copy on big frames */ + + if ((length > RX_COPYBREAK) && + ((newskb = netdev_alloc_skb(dev, 1532)) != NULL)) + { + skb=lp->rx_ring[rx_ring_tail].skb; + skb_put(skb, length); + + skb_reserve(newskb,18); + lp->rx_ring[rx_ring_tail].skb=newskb; + p->data=isa_virt_to_bus(newskb->data); + } + else + { + skb = netdev_alloc_skb(dev, length + 2); + + if(skb==NULL) { + dev->stats.rx_dropped++; + goto dropped; + } + + skb_reserve(skb,2); + memcpy(skb_put(skb, length), + lp->rx_ring[rx_ring_tail].skb->data, length); + } + + skb->protocol=eth_type_trans(skb,dev); + dev->stats.rx_packets++; + dev->stats.rx_bytes += length; + netif_rx(skb); + } + + dropped: + p->length = 1532; + p->status = 0; + + rx_ring_tail=next_rx(rx_ring_tail); + } + while(x++<48); + + /* If there was actually a frame to be processed, place the EOL bit */ + /* at the descriptor prior to the one to be filled next */ + + if (rx_ring_tail != rx_old_tail) + { + lp->rx_ring[prev_rx(rx_ring_tail)].p->control |= CONTROL_EOL; + lp->rx_ring[prev_rx(rx_old_tail)].p->control &= ~CONTROL_EOL; + + lp->rx_ring_tail=rx_ring_tail; + } +} + + +/** + * mc32_tx_ring - process completed transmits + * @dev: 3c527 that needs its transmit ring processing + * + * + * This operates in a similar fashion to mc32_rx_ring. We iterate + * over the transmit ring. For each descriptor which has been + * processed by the card, we free its associated buffer and note + * any errors. This continues until the transmit ring is emptied + * or we reach a descriptor that hasn't yet been processed by the + * card. + * + */ + +static void mc32_tx_ring(struct net_device *dev) +{ + struct mc32_local *lp = netdev_priv(dev); + volatile struct skb_header *np; + + /* + * We rely on head==tail to mean 'queue empty'. + * This is why lp->tx_count=TX_RING_LEN-1: in order to prevent + * tx_ring_head wrapping to tail and confusing a 'queue empty' + * condition with 'queue full' + */ + + while (lp->tx_ring_tail != atomic_read(&lp->tx_ring_head)) + { + u16 t; + + t=next_tx(lp->tx_ring_tail); + np=lp->tx_ring[t].p; + + if(!(np->status & (1<<7))) + { + /* Not COMPLETED */ + break; + } + dev->stats.tx_packets++; + if(!(np->status & (1<<6))) /* Not COMPLETED_OK */ + { + dev->stats.tx_errors++; + + switch(np->status&0x0F) + { + case 1: + dev->stats.tx_aborted_errors++; + break; /* Max collisions */ + case 2: + dev->stats.tx_fifo_errors++; + break; + case 3: + dev->stats.tx_carrier_errors++; + break; + case 4: + dev->stats.tx_window_errors++; + break; /* CTS Lost */ + case 5: + dev->stats.tx_aborted_errors++; + break; /* Transmit timeout */ + } + } + /* Packets are sent in order - this is + basically a FIFO queue of buffers matching + the card ring */ + dev->stats.tx_bytes+=lp->tx_ring[t].skb->len; + dev_kfree_skb_irq(lp->tx_ring[t].skb); + lp->tx_ring[t].skb=NULL; + atomic_inc(&lp->tx_count); + netif_wake_queue(dev); + + lp->tx_ring_tail=t; + } + +} + + +/** + * mc32_interrupt - handle an interrupt from a 3c527 + * @irq: Interrupt number + * @dev_id: 3c527 that requires servicing + * @regs: Registers (unused) + * + * + * An interrupt is raised whenever the 3c527 writes to the command + * register. This register contains the message it wishes to send us + * packed into a single byte field. We keep reading status entries + * until we have processed all the control items, but simply count + * transmit and receive reports. When all reports are in we empty the + * transceiver rings as appropriate. This saves the overhead of + * multiple command requests. + * + * Because MCA is level-triggered, we shouldn't miss indications. + * Therefore, we needn't ask the card to suspend interrupts within + * this handler. The card receives an implicit acknowledgment of the + * current interrupt when we read the command register. + * + */ + +static irqreturn_t mc32_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct mc32_local *lp; + int ioaddr, status, boguscount = 0; + int rx_event = 0; + int tx_event = 0; + + ioaddr = dev->base_addr; + lp = netdev_priv(dev); + + /* See whats cooking */ + + while((inb(ioaddr+HOST_STATUS)&HOST_STATUS_CWR) && boguscount++<2000) + { + status=inb(ioaddr+HOST_CMD); + + pr_debug("Status TX%d RX%d EX%d OV%d BC%d\n", + (status&7), (status>>3)&7, (status>>6)&1, + (status>>7)&1, boguscount); + + switch(status&7) + { + case 0: + break; + case 6: /* TX fail */ + case 2: /* TX ok */ + tx_event = 1; + break; + case 3: /* Halt */ + case 4: /* Abort */ + complete(&lp->xceiver_cmd); + break; + default: + pr_notice("%s: strange tx ack %d\n", dev->name, status&7); + } + status>>=3; + switch(status&7) + { + case 0: + break; + case 2: /* RX */ + rx_event=1; + break; + case 3: /* Halt */ + case 4: /* Abort */ + complete(&lp->xceiver_cmd); + break; + case 6: + /* Out of RX buffers stat */ + /* Must restart rx */ + dev->stats.rx_dropped++; + mc32_rx_ring(dev); + mc32_start_transceiver(dev); + break; + default: + pr_notice("%s: strange rx ack %d\n", + dev->name, status&7); + } + status>>=3; + if(status&1) + { + /* + * No thread is waiting: we need to tidy + * up ourself. + */ + + if (lp->cmd_nonblocking) { + up(&lp->cmd_mutex); + if (lp->mc_reload_wait) + mc32_reset_multicast_list(dev); + } + else complete(&lp->execution_cmd); + } + if(status&2) + { + /* + * We get interrupted once per + * counter that is about to overflow. + */ + + mc32_update_stats(dev); + } + } + + + /* + * Process the transmit and receive rings + */ + + if(tx_event) + mc32_tx_ring(dev); + + if(rx_event) + mc32_rx_ring(dev); + + return IRQ_HANDLED; +} + + +/** + * mc32_close - user configuring the 3c527 down + * @dev: 3c527 card to shut down + * + * The 3c527 is a bus mastering device. We must be careful how we + * shut it down. It may also be running shared interrupt so we have + * to be sure to silence it properly + * + * We indicate that the card is closing to the rest of the + * driver. Otherwise, it is possible that the card may run out + * of receive buffers and restart the transceiver while we're + * trying to close it. + * + * We abort any receive and transmits going on and then wait until + * any pending exec commands have completed in other code threads. + * In theory we can't get here while that is true, in practice I am + * paranoid + * + * We turn off the interrupt enable for the board to be sure it can't + * intefere with other devices. + */ + +static int mc32_close(struct net_device *dev) +{ + struct mc32_local *lp = netdev_priv(dev); + int ioaddr = dev->base_addr; + + u8 regs; + u16 one=1; + + lp->xceiver_desired_state = HALTED; + netif_stop_queue(dev); + + /* + * Send the indications on command (handy debug check) + */ + + mc32_command(dev, 4, &one, 2); + + /* Shut down the transceiver */ + + mc32_halt_transceiver(dev); + + /* Ensure we issue no more commands beyond this point */ + + down(&lp->cmd_mutex); + + /* Ok the card is now stopping */ + + regs=inb(ioaddr+HOST_CTRL); + regs&=~HOST_CTRL_INTE; + outb(regs, ioaddr+HOST_CTRL); + + mc32_flush_rx_ring(dev); + mc32_flush_tx_ring(dev); + + mc32_update_stats(dev); + + return 0; +} + + +/** + * mc32_get_stats - hand back stats to network layer + * @dev: The 3c527 card to handle + * + * We've collected all the stats we can in software already. Now + * it's time to update those kept on-card and return the lot. + * + */ + +static struct net_device_stats *mc32_get_stats(struct net_device *dev) +{ + mc32_update_stats(dev); + return &dev->stats; +} + + +/** + * do_mc32_set_multicast_list - attempt to update multicasts + * @dev: 3c527 device to load the list on + * @retry: indicates this is not the first call. + * + * + * Actually set or clear the multicast filter for this adaptor. The + * locking issues are handled by this routine. We have to track + * state as it may take multiple calls to get the command sequence + * completed. We just keep trying to schedule the loads until we + * manage to process them all. + * + * num_addrs == -1 Promiscuous mode, receive all packets + * + * num_addrs == 0 Normal mode, clear multicast list + * + * num_addrs > 0 Multicast mode, receive normal and MC packets, + * and do best-effort filtering. + * + * See mc32_update_stats() regards setting the SAV BP bit. + * + */ + +static void do_mc32_set_multicast_list(struct net_device *dev, int retry) +{ + struct mc32_local *lp = netdev_priv(dev); + u16 filt = (1<<2); /* Save Bad Packets, for stats purposes */ + + if ((dev->flags&IFF_PROMISC) || + (dev->flags&IFF_ALLMULTI) || + netdev_mc_count(dev) > 10) + /* Enable promiscuous mode */ + filt |= 1; + else if (!netdev_mc_empty(dev)) + { + unsigned char block[62]; + unsigned char *bp; + struct netdev_hw_addr *ha; + + if(retry==0) + lp->mc_list_valid = 0; + if(!lp->mc_list_valid) + { + block[1]=0; + block[0]=netdev_mc_count(dev); + bp=block+2; + + netdev_for_each_mc_addr(ha, dev) { + memcpy(bp, ha->addr, 6); + bp+=6; + } + if(mc32_command_nowait(dev, 2, block, + 2+6*netdev_mc_count(dev))==-1) + { + lp->mc_reload_wait = 1; + return; + } + lp->mc_list_valid=1; + } + } + + if(mc32_command_nowait(dev, 0, &filt, 2)==-1) + { + lp->mc_reload_wait = 1; + } + else { + lp->mc_reload_wait = 0; + } +} + + +/** + * mc32_set_multicast_list - queue multicast list update + * @dev: The 3c527 to use + * + * Commence loading the multicast list. This is called when the kernel + * changes the lists. It will override any pending list we are trying to + * load. + */ + +static void mc32_set_multicast_list(struct net_device *dev) +{ + do_mc32_set_multicast_list(dev,0); +} + + +/** + * mc32_reset_multicast_list - reset multicast list + * @dev: The 3c527 to use + * + * Attempt the next step in loading the multicast lists. If this attempt + * fails to complete then it will be scheduled and this function called + * again later from elsewhere. + */ + +static void mc32_reset_multicast_list(struct net_device *dev) +{ + do_mc32_set_multicast_list(dev,1); +} + +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + sprintf(info->bus_info, "MCA 0x%lx", dev->base_addr); +} + +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return mc32_debug; +} + +static void netdev_set_msglevel(struct net_device *dev, u32 level) +{ + mc32_debug = level; +} + +static const struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, +}; + +#ifdef MODULE + +static struct net_device *this_device; + +/** + * init_module - entry point + * + * Probe and locate a 3c527 card. This really should probe and locate + * all the 3c527 cards in the machine not just one of them. Yes you can + * insmod multiple modules for now but it's a hack. + */ + +int __init init_module(void) +{ + this_device = mc32_probe(-1); + if (IS_ERR(this_device)) + return PTR_ERR(this_device); + return 0; +} + +/** + * cleanup_module - free resources for an unload + * + * Unloading time. We release the MCA bus resources and the interrupt + * at which point everything is ready to unload. The card must be stopped + * at this point or we would not have been called. When we unload we + * leave the card stopped but not totally shut down. When the card is + * initialized it must be rebooted or the rings reloaded before any + * transmit operations are allowed to start scribbling into memory. + */ + +void __exit cleanup_module(void) +{ + unregister_netdev(this_device); + cleanup_card(this_device); + free_netdev(this_device); +} + +#endif /* MODULE */ diff --git a/trunk/drivers/net/ethernet/i825xx/3c527.h b/trunk/drivers/net/ethernet/i825xx/3c527.h new file mode 100644 index 000000000000..d693b8d15cde --- /dev/null +++ b/trunk/drivers/net/ethernet/i825xx/3c527.h @@ -0,0 +1,81 @@ +/* + * 3COM "EtherLink MC/32" Descriptions + */ + +/* + * Registers + */ + +#define HOST_CMD 0 +#define HOST_CMD_START_RX (1<<3) +#define HOST_CMD_SUSPND_RX (3<<3) +#define HOST_CMD_RESTRT_RX (5<<3) + +#define HOST_CMD_SUSPND_TX 3 +#define HOST_CMD_RESTRT_TX 5 + + +#define HOST_STATUS 2 +#define HOST_STATUS_CRR (1<<6) +#define HOST_STATUS_CWR (1<<5) + + +#define HOST_CTRL 6 +#define HOST_CTRL_ATTN (1<<7) +#define HOST_CTRL_RESET (1<<6) +#define HOST_CTRL_INTE (1<<2) + +#define HOST_RAMPAGE 8 + +#define HALTED 0 +#define RUNNING 1 + +struct mc32_mailbox +{ + u16 mbox; + u16 data[1]; +} __packed; + +struct skb_header +{ + u8 status; + u8 control; + u16 next; /* Do not change! */ + u16 length; + u32 data; +} __packed; + +struct mc32_stats +{ + /* RX Errors */ + u32 rx_crc_errors; + u32 rx_alignment_errors; + u32 rx_overrun_errors; + u32 rx_tooshort_errors; + u32 rx_toolong_errors; + u32 rx_outofresource_errors; + + u32 rx_discarded; /* via card pattern match filter */ + + /* TX Errors */ + u32 tx_max_collisions; + u32 tx_carrier_errors; + u32 tx_underrun_errors; + u32 tx_cts_errors; + u32 tx_timeout_errors; + + /* various cruft */ + u32 dataA[6]; + u16 dataB[5]; + u32 dataC[14]; +} __packed; + +#define STATUS_MASK 0x0F +#define COMPLETED (1<<7) +#define COMPLETED_OK (1<<6) +#define BUFFER_BUSY (1<<5) + +#define CONTROL_EOP (1<<7) /* End Of Packet */ +#define CONTROL_EOL (1<<6) /* End of List */ + +#define MCA_MC32_ID 0x0041 /* Our MCA ident */ diff --git a/trunk/drivers/net/ethernet/i825xx/Kconfig b/trunk/drivers/net/ethernet/i825xx/Kconfig index fed5080a6b62..ca1ae985c6df 100644 --- a/trunk/drivers/net/ethernet/i825xx/Kconfig +++ b/trunk/drivers/net/ethernet/i825xx/Kconfig @@ -43,6 +43,28 @@ config EL16 To compile this driver as a module, choose M here. The module will be called 3c507. +config ELMC + tristate "3c523 \"EtherLink/MC\" support" + depends on MCA_LEGACY + ---help--- + If you have a network (Ethernet) card of this type, say Y and read + the Ethernet-HOWTO, available from + . + + To compile this driver as a module, choose M here. The module + will be called 3c523. + +config ELMC_II + tristate "3c527 \"EtherLink/MC 32\" support (EXPERIMENTAL)" + depends on MCA && MCA_LEGACY + ---help--- + If you have a network (Ethernet) card of this type, say Y and read + the Ethernet-HOWTO, available from + . + + To compile this driver as a module, choose M here. The module + will be called 3c527. + config ARM_ETHER1 tristate "Acorn Ether1 support" depends on ARM && ARCH_ACORN diff --git a/trunk/drivers/net/ethernet/i825xx/Makefile b/trunk/drivers/net/ethernet/i825xx/Makefile index 6adff85e8ecc..f68a3694968a 100644 --- a/trunk/drivers/net/ethernet/i825xx/Makefile +++ b/trunk/drivers/net/ethernet/i825xx/Makefile @@ -7,6 +7,8 @@ obj-$(CONFIG_EEXPRESS) += eexpress.o obj-$(CONFIG_EEXPRESS_PRO) += eepro.o obj-$(CONFIG_ELPLUS) += 3c505.o obj-$(CONFIG_EL16) += 3c507.o +obj-$(CONFIG_ELMC) += 3c523.o +obj-$(CONFIG_ELMC_II) += 3c527.o obj-$(CONFIG_LP486E) += lp486e.o obj-$(CONFIG_NI52) += ni52.o obj-$(CONFIG_SUN3_82586) += sun3_82586.o diff --git a/trunk/drivers/net/ethernet/i825xx/eexpress.c b/trunk/drivers/net/ethernet/i825xx/eexpress.c index 7a6a2f04c5b1..cc2e66ad4436 100644 --- a/trunk/drivers/net/ethernet/i825xx/eexpress.c +++ b/trunk/drivers/net/ethernet/i825xx/eexpress.c @@ -9,7 +9,7 @@ * Many modifications, and currently maintained, by * Philip Blundell * Added the Compaq LTE Alan Cox - * Added MCA support Adam Fritzler (now deleted) + * Added MCA support Adam Fritzler * * Note - this driver is experimental still - it has problems on faster * machines. Someone needs to sit down and go through it line by line with @@ -111,6 +111,7 @@ #include #include #include +#include #include #include #include @@ -226,6 +227,16 @@ static unsigned short start_code[] = { /* maps irq number to EtherExpress magic value */ static char irqrmap[] = { 0,0,1,2,3,4,0,0,0,1,5,6,0,0,0,0 }; +#ifdef CONFIG_MCA_LEGACY +/* mapping of the first four bits of the second POS register */ +static unsigned short mca_iomap[] = { + 0x270, 0x260, 0x250, 0x240, 0x230, 0x220, 0x210, 0x200, + 0x370, 0x360, 0x350, 0x340, 0x330, 0x320, 0x310, 0x300 +}; +/* bits 5-7 of the second POS register */ +static char mca_irqmap[] = { 12, 9, 3, 4, 5, 10, 11, 15 }; +#endif + /* * Prototypes for Linux interface */ @@ -329,6 +340,53 @@ static int __init do_express_probe(struct net_device *dev) dev->if_port = 0xff; /* not set */ +#ifdef CONFIG_MCA_LEGACY + if (MCA_bus) { + int slot = 0; + + /* + * Only find one card at a time. Subsequent calls + * will find others, however, proper multicard MCA + * probing and setup can't be done with the + * old-style Space.c init routines. -- ASF + */ + while (slot != MCA_NOTFOUND) { + int pos0, pos1; + + slot = mca_find_unused_adapter(0x628B, slot); + if (slot == MCA_NOTFOUND) + break; + + pos0 = mca_read_stored_pos(slot, 2); + pos1 = mca_read_stored_pos(slot, 3); + ioaddr = mca_iomap[pos1&0xf]; + + dev->irq = mca_irqmap[(pos1>>4)&0x7]; + + /* + * XXX: Transceiver selection is done + * differently on the MCA version. + * How to get it to select something + * other than external/AUI is currently + * unknown. This code is just for looks. -- ASF + */ + if ((pos0 & 0x7) == 0x1) + dev->if_port = AUI; + else if ((pos0 & 0x7) == 0x5) { + if (pos1 & 0x80) + dev->if_port = BNC; + else + dev->if_port = TPE; + } + + mca_set_adapter_name(slot, "Intel EtherExpress 16 MCA"); + mca_set_adapter_procfn(slot, NULL, dev); + mca_mark_as_used(slot); + + break; + } + } +#endif if (ioaddr&0xfe00) { if (!request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress")) return -EBUSY; diff --git a/trunk/drivers/net/ethernet/ibm/ehea/ehea_main.c b/trunk/drivers/net/ethernet/ibm/ehea/ehea_main.c index f4d2da0db1b1..c9069a28832b 100644 --- a/trunk/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/trunk/drivers/net/ethernet/ibm/ehea/ehea_main.c @@ -3335,8 +3335,6 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev, goto out_shutdown_ports; } - /* Handle any events that might be pending. */ - tasklet_hi_schedule(&adapter->neq_tasklet); ret = 0; goto out; diff --git a/trunk/drivers/net/ethernet/intel/Kconfig b/trunk/drivers/net/ethernet/intel/Kconfig index 79b07ec6726f..546efe30c9b8 100644 --- a/trunk/drivers/net/ethernet/intel/Kconfig +++ b/trunk/drivers/net/ethernet/intel/Kconfig @@ -220,17 +220,6 @@ config IXGBE_DCB If unsure, say N. -config IXGBE_PTP - bool "PTP Clock Support" - default n - depends on IXGBE && PTP_1588_CLOCK - ---help--- - Say Y here if you want support for 1588 Timestamping with a - PHC device, using the PTP 1588 Clock support. This is - required to enable timestamping support for the device. - - If unsure, say N. - config IXGBEVF tristate "Intel(R) 82599 Virtual Function Ethernet support" depends on PCI_MSI diff --git a/trunk/drivers/net/ethernet/intel/e1000/e1000_main.c b/trunk/drivers/net/ethernet/intel/e1000/e1000_main.c index 95731c841044..f1aef68e1e83 100644 --- a/trunk/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/trunk/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -493,11 +493,7 @@ static void e1000_power_down_phy(struct e1000_adapter *adapter) static void e1000_down_and_stop(struct e1000_adapter *adapter) { set_bit(__E1000_DOWN, &adapter->flags); - - /* Only kill reset task if adapter is not resetting */ - if (!test_bit(__E1000_RESETTING, &adapter->flags)) - cancel_work_sync(&adapter->reset_task); - + cancel_work_sync(&adapter->reset_task); cancel_delayed_work_sync(&adapter->watchdog_task); cancel_delayed_work_sync(&adapter->phy_info_task); cancel_delayed_work_sync(&adapter->fifo_stall_task); @@ -4070,11 +4066,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, /* errors is only valid for DD + EOP descriptors */ if (unlikely((status & E1000_RXD_STAT_EOP) && (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) { - u8 *mapped; - u8 last_byte; - - mapped = page_address(buffer_info->page); - last_byte = *(mapped + length - 1); + u8 last_byte = *(skb->data + length - 1); if (TBI_ACCEPT(hw, status, rx_desc->errors, length, last_byte)) { spin_lock_irqsave(&adapter->stats_lock, @@ -4399,6 +4391,30 @@ e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter, break; } + /* Fix for errata 23, can't cross 64kB boundary */ + if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) { + struct sk_buff *oldskb = skb; + e_err(rx_err, "skb align check failed: %u bytes at " + "%p\n", bufsz, skb->data); + /* Try again, without freeing the previous */ + skb = netdev_alloc_skb_ip_align(netdev, bufsz); + /* Failed allocation, critical failure */ + if (!skb) { + dev_kfree_skb(oldskb); + adapter->alloc_rx_buff_failed++; + break; + } + + if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) { + /* give up */ + dev_kfree_skb(skb); + dev_kfree_skb(oldskb); + break; /* while (cleaned_count--) */ + } + + /* Use new allocation */ + dev_kfree_skb(oldskb); + } buffer_info->skb = skb; buffer_info->length = adapter->rx_buffer_len; check_page: diff --git a/trunk/drivers/net/ethernet/intel/e1000e/defines.h b/trunk/drivers/net/ethernet/intel/e1000e/defines.h index 351a4097b2ba..11c46661af09 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/defines.h +++ b/trunk/drivers/net/ethernet/intel/e1000e/defines.h @@ -76,7 +76,7 @@ /* Extended Device Control */ #define E1000_CTRL_EXT_LPCD 0x00000004 /* LCD Power Cycle Done */ #define E1000_CTRL_EXT_SDP3_DATA 0x00000080 /* Value of SW Definable Pin 3 */ -#define E1000_CTRL_EXT_FORCE_SMBUS 0x00000800 /* Force SMBus mode */ +#define E1000_CTRL_EXT_FORCE_SMBUS 0x00000004 /* Force SMBus mode*/ #define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */ #define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */ #define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */ diff --git a/trunk/drivers/net/ethernet/intel/e1000e/param.c b/trunk/drivers/net/ethernet/intel/e1000e/param.c index 55cc1565bc2f..42444d14aae6 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/param.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/param.c @@ -344,16 +344,50 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) if (num_InterruptThrottleRate > bd) { adapter->itr = InterruptThrottleRate[bd]; - - /* - * Make sure a message is printed for non-special - * values. And in case of an invalid option, display - * warning, use default and go through itr/itr_setting - * adjustment logic below - */ - if ((adapter->itr > 4) && - e1000_validate_option(&adapter->itr, &opt, adapter)) - adapter->itr = opt.def; + switch (adapter->itr) { + case 0: + e_info("%s turned off\n", opt.name); + break; + case 1: + e_info("%s set to dynamic mode\n", opt.name); + adapter->itr_setting = adapter->itr; + adapter->itr = 20000; + break; + case 3: + e_info("%s set to dynamic conservative mode\n", + opt.name); + adapter->itr_setting = adapter->itr; + adapter->itr = 20000; + break; + case 4: + e_info("%s set to simplified (2000-8000 ints) mode\n", + opt.name); + adapter->itr_setting = 4; + break; + default: + /* + * Save the setting, because the dynamic bits + * change itr. + */ + if (e1000_validate_option(&adapter->itr, &opt, + adapter) && + (adapter->itr == 3)) { + /* + * In case of invalid user value, + * default to conservative mode. + */ + adapter->itr_setting = adapter->itr; + adapter->itr = 20000; + } else { + /* + * Clear the lower two bits because + * they are used as control. + */ + adapter->itr_setting = + adapter->itr & ~3; + } + break; + } } else { /* * If no option specified, use default value and go @@ -365,7 +399,7 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) * Make sure a message is printed for non-special * default values */ - if (adapter->itr > 4) + if (adapter->itr > 40) e_info("%s set to default %d\n", opt.name, adapter->itr); } diff --git a/trunk/drivers/net/ethernet/intel/igb/Makefile b/trunk/drivers/net/ethernet/intel/igb/Makefile index 97c197fd4a8e..4bd16e266414 100644 --- a/trunk/drivers/net/ethernet/intel/igb/Makefile +++ b/trunk/drivers/net/ethernet/intel/igb/Makefile @@ -33,7 +33,6 @@ obj-$(CONFIG_IGB) += igb.o igb-objs := igb_main.o igb_ethtool.o e1000_82575.o \ - e1000_mac.o e1000_nvm.o e1000_phy.o e1000_mbx.o \ - e1000_i210.o + e1000_mac.o e1000_nvm.o e1000_phy.o e1000_mbx.o igb-$(CONFIG_IGB_PTP) += igb_ptp.o diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_82575.c b/trunk/drivers/net/ethernet/intel/igb/e1000_82575.c index e65083958421..08bdc33715ee 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_82575.c @@ -36,7 +36,6 @@ #include "e1000_mac.h" #include "e1000_82575.h" -#include "e1000_i210.h" static s32 igb_get_invariants_82575(struct e1000_hw *); static s32 igb_acquire_phy_82575(struct e1000_hw *); @@ -53,8 +52,6 @@ static s32 igb_write_phy_reg_82580(struct e1000_hw *, u32, u16); static s32 igb_reset_hw_82575(struct e1000_hw *); static s32 igb_reset_hw_82580(struct e1000_hw *); static s32 igb_set_d0_lplu_state_82575(struct e1000_hw *, bool); -static s32 igb_set_d0_lplu_state_82580(struct e1000_hw *, bool); -static s32 igb_set_d3_lplu_state_82580(struct e1000_hw *, bool); static s32 igb_setup_copper_link_82575(struct e1000_hw *); static s32 igb_setup_serdes_link_82575(struct e1000_hw *); static s32 igb_write_phy_reg_sgmii_82575(struct e1000_hw *, u32, u16); @@ -99,8 +96,6 @@ static bool igb_sgmii_uses_mdio_82575(struct e1000_hw *hw) break; case e1000_82580: case e1000_i350: - case e1000_i210: - case e1000_i211: reg = rd32(E1000_MDICNFG); ext_mdio = !!(reg & E1000_MDICNFG_EXT_MDIO); break; @@ -155,17 +150,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) case E1000_DEV_ID_I350_SGMII: mac->type = e1000_i350; break; - case E1000_DEV_ID_I210_COPPER: - case E1000_DEV_ID_I210_COPPER_OEM1: - case E1000_DEV_ID_I210_COPPER_IT: - case E1000_DEV_ID_I210_FIBER: - case E1000_DEV_ID_I210_SERDES: - case E1000_DEV_ID_I210_SGMII: - mac->type = e1000_i210; - break; - case E1000_DEV_ID_I211_COPPER: - mac->type = e1000_i211; - break; default: return -E1000_ERR_MAC_INIT; break; @@ -198,44 +182,26 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) /* Set mta register count */ mac->mta_reg_count = 128; /* Set rar entry count */ - switch (mac->type) { - case e1000_82576: + mac->rar_entry_count = E1000_RAR_ENTRIES_82575; + if (mac->type == e1000_82576) mac->rar_entry_count = E1000_RAR_ENTRIES_82576; - break; - case e1000_82580: + if (mac->type == e1000_82580) mac->rar_entry_count = E1000_RAR_ENTRIES_82580; - break; - case e1000_i350: - case e1000_i210: - case e1000_i211: + if (mac->type == e1000_i350) mac->rar_entry_count = E1000_RAR_ENTRIES_I350; - break; - default: - mac->rar_entry_count = E1000_RAR_ENTRIES_82575; - break; - } /* reset */ if (mac->type >= e1000_82580) mac->ops.reset_hw = igb_reset_hw_82580; else mac->ops.reset_hw = igb_reset_hw_82575; - - if (mac->type >= e1000_i210) { - mac->ops.acquire_swfw_sync = igb_acquire_swfw_sync_i210; - mac->ops.release_swfw_sync = igb_release_swfw_sync_i210; - } else { - mac->ops.acquire_swfw_sync = igb_acquire_swfw_sync_82575; - mac->ops.release_swfw_sync = igb_release_swfw_sync_82575; - } - /* Set if part includes ASF firmware */ mac->asf_firmware_present = true; /* Set if manageability features are enabled. */ mac->arc_subsystem_valid = (rd32(E1000_FWSM) & E1000_FWSM_MODE_MASK) ? true : false; - /* enable EEE on i350 parts and later parts */ - if (mac->type >= e1000_i350) + /* enable EEE on i350 parts */ + if (mac->type == e1000_i350) dev_spec->eee_disable = false; else dev_spec->eee_disable = true; @@ -247,6 +213,26 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) /* NVM initialization */ eecd = rd32(E1000_EECD); + + nvm->opcode_bits = 8; + nvm->delay_usec = 1; + switch (nvm->override) { + case e1000_nvm_override_spi_large: + nvm->page_size = 32; + nvm->address_bits = 16; + break; + case e1000_nvm_override_spi_small: + nvm->page_size = 8; + nvm->address_bits = 8; + break; + default: + nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8; + nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8; + break; + } + + nvm->type = e1000_nvm_eeprom_spi; + size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> E1000_EECD_SIZE_EX_SHIFT); @@ -256,33 +242,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) */ size += NVM_WORD_SIZE_BASE_SHIFT; - nvm->word_size = 1 << size; - if (hw->mac.type < e1000_i210) { - nvm->opcode_bits = 8; - nvm->delay_usec = 1; - switch (nvm->override) { - case e1000_nvm_override_spi_large: - nvm->page_size = 32; - nvm->address_bits = 16; - break; - case e1000_nvm_override_spi_small: - nvm->page_size = 8; - nvm->address_bits = 8; - break; - default: - nvm->page_size = eecd - & E1000_EECD_ADDR_BITS ? 32 : 8; - nvm->address_bits = eecd - & E1000_EECD_ADDR_BITS ? 16 : 8; - break; - } - if (nvm->word_size == (1 << 15)) - nvm->page_size = 128; - - nvm->type = e1000_nvm_eeprom_spi; - } else - nvm->type = e1000_nvm_flash_hw; - /* * Check for invalid size */ @@ -290,60 +249,32 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) pr_notice("The NVM size is not valid, defaulting to 32K\n"); size = 15; } + nvm->word_size = 1 << size; + if (nvm->word_size == (1 << 15)) + nvm->page_size = 128; /* NVM Function Pointers */ + nvm->ops.acquire = igb_acquire_nvm_82575; + if (nvm->word_size < (1 << 15)) + nvm->ops.read = igb_read_nvm_eerd; + else + nvm->ops.read = igb_read_nvm_spi; + + nvm->ops.release = igb_release_nvm_82575; switch (hw->mac.type) { case e1000_82580: nvm->ops.validate = igb_validate_nvm_checksum_82580; nvm->ops.update = igb_update_nvm_checksum_82580; - nvm->ops.acquire = igb_acquire_nvm_82575; - nvm->ops.release = igb_release_nvm_82575; - if (nvm->word_size < (1 << 15)) - nvm->ops.read = igb_read_nvm_eerd; - else - nvm->ops.read = igb_read_nvm_spi; - nvm->ops.write = igb_write_nvm_spi; break; case e1000_i350: nvm->ops.validate = igb_validate_nvm_checksum_i350; nvm->ops.update = igb_update_nvm_checksum_i350; - nvm->ops.acquire = igb_acquire_nvm_82575; - nvm->ops.release = igb_release_nvm_82575; - if (nvm->word_size < (1 << 15)) - nvm->ops.read = igb_read_nvm_eerd; - else - nvm->ops.read = igb_read_nvm_spi; - nvm->ops.write = igb_write_nvm_spi; - break; - case e1000_i210: - nvm->ops.validate = igb_validate_nvm_checksum_i210; - nvm->ops.update = igb_update_nvm_checksum_i210; - nvm->ops.acquire = igb_acquire_nvm_i210; - nvm->ops.release = igb_release_nvm_i210; - nvm->ops.read = igb_read_nvm_srrd_i210; - nvm->ops.valid_led_default = igb_valid_led_default_i210; - break; - case e1000_i211: - nvm->ops.acquire = igb_acquire_nvm_i210; - nvm->ops.release = igb_release_nvm_i210; - nvm->ops.read = igb_read_nvm_i211; - nvm->ops.valid_led_default = igb_valid_led_default_i210; - nvm->ops.validate = NULL; - nvm->ops.update = NULL; - nvm->ops.write = NULL; break; default: nvm->ops.validate = igb_validate_nvm_checksum; nvm->ops.update = igb_update_nvm_checksum; - nvm->ops.acquire = igb_acquire_nvm_82575; - nvm->ops.release = igb_release_nvm_82575; - if (nvm->word_size < (1 << 15)) - nvm->ops.read = igb_read_nvm_eerd; - else - nvm->ops.read = igb_read_nvm_spi; - nvm->ops.write = igb_write_nvm_spi; - break; } + nvm->ops.write = igb_write_nvm_spi; /* if part supports SR-IOV then initialize mailbox parameters */ switch (mac->type) { @@ -381,13 +312,9 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) if (igb_sgmii_active_82575(hw) && !igb_sgmii_uses_mdio_82575(hw)) { phy->ops.read_reg = igb_read_phy_reg_sgmii_82575; phy->ops.write_reg = igb_write_phy_reg_sgmii_82575; - } else if ((hw->mac.type == e1000_82580) - || (hw->mac.type == e1000_i350)) { + } else if (hw->mac.type >= e1000_82580) { phy->ops.read_reg = igb_read_phy_reg_82580; phy->ops.write_reg = igb_write_phy_reg_82580; - } else if (hw->phy.type >= e1000_phy_i210) { - phy->ops.read_reg = igb_read_phy_reg_gs40g; - phy->ops.write_reg = igb_write_phy_reg_gs40g; } else { phy->ops.read_reg = igb_read_phy_reg_igp; phy->ops.write_reg = igb_write_phy_reg_igp; @@ -416,14 +343,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) else phy->ops.get_cable_length = igb_get_cable_length_m88; - if (phy->id == I210_I_PHY_ID) { - phy->ops.get_cable_length = - igb_get_cable_length_m88_gen2; - phy->ops.set_d0_lplu_state = - igb_set_d0_lplu_state_82580; - phy->ops.set_d3_lplu_state = - igb_set_d3_lplu_state_82580; - } phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_m88; break; case IGP03E1000_E_PHY_ID: @@ -440,17 +359,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_82580; phy->ops.get_cable_length = igb_get_cable_length_82580; phy->ops.get_phy_info = igb_get_phy_info_82580; - phy->ops.set_d0_lplu_state = igb_set_d0_lplu_state_82580; - phy->ops.set_d3_lplu_state = igb_set_d3_lplu_state_82580; - break; - case I210_I_PHY_ID: - phy->type = e1000_phy_i210; - phy->ops.get_phy_info = igb_get_phy_info_m88; - phy->ops.check_polarity = igb_check_polarity_m88; - phy->ops.get_cable_length = igb_get_cable_length_m88_gen2; - phy->ops.set_d0_lplu_state = igb_set_d0_lplu_state_82580; - phy->ops.set_d3_lplu_state = igb_set_d3_lplu_state_82580; - phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_m88; break; default: return -E1000_ERR_PHY; @@ -477,7 +385,7 @@ static s32 igb_acquire_phy_82575(struct e1000_hw *hw) else if (hw->bus.func == E1000_FUNC_3) mask = E1000_SWFW_PHY3_SM; - return hw->mac.ops.acquire_swfw_sync(hw, mask); + return igb_acquire_swfw_sync_82575(hw, mask); } /** @@ -498,7 +406,7 @@ static void igb_release_phy_82575(struct e1000_hw *hw) else if (hw->bus.func == E1000_FUNC_3) mask = E1000_SWFW_PHY3_SM; - hw->mac.ops.release_swfw_sync(hw, mask); + igb_release_swfw_sync_82575(hw, mask); } /** @@ -602,8 +510,6 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw) break; case e1000_82580: case e1000_i350: - case e1000_i210: - case e1000_i211: mdic = rd32(E1000_MDICNFG); mdic &= E1000_MDICNFG_PHY_MASK; phy->addr = mdic >> E1000_MDICNFG_PHY_SHIFT; @@ -767,96 +673,6 @@ static s32 igb_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active) return ret_val; } -/** - * igb_set_d0_lplu_state_82580 - Set Low Power Linkup D0 state - * @hw: pointer to the HW structure - * @active: true to enable LPLU, false to disable - * - * Sets the LPLU D0 state according to the active flag. When - * activating LPLU this function also disables smart speed - * and vice versa. LPLU will not be activated unless the - * device autonegotiation advertisement meets standards of - * either 10 or 10/100 or 10/100/1000 at all duplexes. - * This is a function pointer entry point only called by - * PHY setup routines. - **/ -static s32 igb_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active) -{ - struct e1000_phy_info *phy = &hw->phy; - s32 ret_val = 0; - u16 data; - - data = rd32(E1000_82580_PHY_POWER_MGMT); - - if (active) { - data |= E1000_82580_PM_D0_LPLU; - - /* When LPLU is enabled, we should disable SmartSpeed */ - data &= ~E1000_82580_PM_SPD; - } else { - data &= ~E1000_82580_PM_D0_LPLU; - - /* - * LPLU and SmartSpeed are mutually exclusive. LPLU is used - * during Dx states where the power conservation is most - * important. During driver activity we should enable - * SmartSpeed, so performance is maintained. - */ - if (phy->smart_speed == e1000_smart_speed_on) - data |= E1000_82580_PM_SPD; - else if (phy->smart_speed == e1000_smart_speed_off) - data &= ~E1000_82580_PM_SPD; } - - wr32(E1000_82580_PHY_POWER_MGMT, data); - return ret_val; -} - -/** - * igb_set_d3_lplu_state_82580 - Sets low power link up state for D3 - * @hw: pointer to the HW structure - * @active: boolean used to enable/disable lplu - * - * Success returns 0, Failure returns 1 - * - * The low power link up (lplu) state is set to the power management level D3 - * and SmartSpeed is disabled when active is true, else clear lplu for D3 - * and enable Smartspeed. LPLU and Smartspeed are mutually exclusive. LPLU - * is used during Dx states where the power conservation is most important. - * During driver activity, SmartSpeed should be enabled so performance is - * maintained. - **/ -s32 igb_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active) -{ - struct e1000_phy_info *phy = &hw->phy; - s32 ret_val = 0; - u16 data; - - data = rd32(E1000_82580_PHY_POWER_MGMT); - - if (!active) { - data &= ~E1000_82580_PM_D3_LPLU; - /* - * LPLU and SmartSpeed are mutually exclusive. LPLU is used - * during Dx states where the power conservation is most - * important. During driver activity we should enable - * SmartSpeed, so performance is maintained. - */ - if (phy->smart_speed == e1000_smart_speed_on) - data |= E1000_82580_PM_SPD; - else if (phy->smart_speed == e1000_smart_speed_off) - data &= ~E1000_82580_PM_SPD; - } else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) || - (phy->autoneg_advertised == E1000_ALL_NOT_GIG) || - (phy->autoneg_advertised == E1000_ALL_10_SPEED)) { - data |= E1000_82580_PM_D3_LPLU; - /* When LPLU is enabled, we should disable SmartSpeed */ - data &= ~E1000_82580_PM_SPD; - } - - wr32(E1000_82580_PHY_POWER_MGMT, data); - return ret_val; -} - /** * igb_acquire_nvm_82575 - Request for access to EEPROM * @hw: pointer to the HW structure @@ -870,14 +686,14 @@ static s32 igb_acquire_nvm_82575(struct e1000_hw *hw) { s32 ret_val; - ret_val = hw->mac.ops.acquire_swfw_sync(hw, E1000_SWFW_EEP_SM); + ret_val = igb_acquire_swfw_sync_82575(hw, E1000_SWFW_EEP_SM); if (ret_val) goto out; ret_val = igb_acquire_nvm(hw); if (ret_val) - hw->mac.ops.release_swfw_sync(hw, E1000_SWFW_EEP_SM); + igb_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM); out: return ret_val; @@ -893,7 +709,7 @@ static s32 igb_acquire_nvm_82575(struct e1000_hw *hw) static void igb_release_nvm_82575(struct e1000_hw *hw) { igb_release_nvm(hw); - hw->mac.ops.release_swfw_sync(hw, E1000_SWFW_EEP_SM); + igb_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM); } /** @@ -1264,6 +1080,7 @@ static s32 igb_init_hw_82575(struct e1000_hw *hw) * is no link. */ igb_clear_hw_cntrs_82575(hw); + return ret_val; } @@ -1300,7 +1117,6 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw) } } switch (hw->phy.type) { - case e1000_phy_i210: case e1000_phy_m88: if (hw->phy.id == I347AT4_E_PHY_ID || hw->phy.id == M88E1112_E_PHY_ID) @@ -1941,7 +1757,7 @@ static s32 igb_reset_hw_82580(struct e1000_hw *hw) /* Determine whether or not a global dev reset is requested */ if (global_device_reset && - hw->mac.ops.acquire_swfw_sync(hw, swmbsw_mask)) + igb_acquire_swfw_sync_82575(hw, swmbsw_mask)) global_device_reset = false; if (global_device_reset && @@ -1987,7 +1803,7 @@ static s32 igb_reset_hw_82580(struct e1000_hw *hw) /* Release semaphore */ if (global_device_reset) - hw->mac.ops.release_swfw_sync(hw, swmbsw_mask); + igb_release_swfw_sync_82575(hw, swmbsw_mask); return ret_val; } diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_82575.h b/trunk/drivers/net/ethernet/intel/igb/e1000_82575.h index e85c453f5428..b927d79ab536 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_82575.h +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_82575.h @@ -55,11 +55,10 @@ extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw); #define E1000_SRRCTL_DROP_EN 0x80000000 #define E1000_SRRCTL_TIMESTAMP 0x40000000 - #define E1000_MRQC_ENABLE_RSS_4Q 0x00000002 #define E1000_MRQC_ENABLE_VMDQ 0x00000003 -#define E1000_MRQC_RSS_FIELD_IPV4_UDP 0x00400000 #define E1000_MRQC_ENABLE_VMDQ_RSS_2Q 0x00000005 +#define E1000_MRQC_RSS_FIELD_IPV4_UDP 0x00400000 #define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000 #define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000 diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_defines.h b/trunk/drivers/net/ethernet/intel/igb/e1000_defines.h index ec7e4fe3e3ee..89eb1f85b9fa 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_defines.h +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_defines.h @@ -301,8 +301,6 @@ * transactions */ #define E1000_DMACR_DMAC_LX_SHIFT 28 #define E1000_DMACR_DMAC_EN 0x80000000 /* Enable DMA Coalescing */ -/* DMA Coalescing BMC-to-OS Watchdog Enable */ -#define E1000_DMACR_DC_BMC2OSW_EN 0x00008000 #define E1000_DMCTXTH_DMCTTHR_MASK 0x00000FFF /* DMA Coalescing Transmit * Threshold */ @@ -460,7 +458,6 @@ #define E1000_ERR_INVALID_ARGUMENT 16 #define E1000_ERR_NO_SPACE 17 #define E1000_ERR_NVM_PBA_SECTION 18 -#define E1000_ERR_INVM_VALUE_NOT_FOUND 19 /* Loop limit on how long we wait for auto-negotiation to complete */ #define COPPER_LINK_UP_LIMIT 10 @@ -598,25 +595,6 @@ #define E1000_EECD_AUTO_RD 0x00000200 /* NVM Auto Read done */ #define E1000_EECD_SIZE_EX_MASK 0x00007800 /* NVM Size */ #define E1000_EECD_SIZE_EX_SHIFT 11 -#define E1000_EECD_FLUPD_I210 0x00800000 /* Update FLASH */ -#define E1000_EECD_FLUDONE_I210 0x04000000 /* Update FLASH done*/ -#define E1000_FLUDONE_ATTEMPTS 20000 -#define E1000_EERD_EEWR_MAX_COUNT 512 /* buffered EEPROM words rw */ -#define E1000_I210_FIFO_SEL_RX 0x00 -#define E1000_I210_FIFO_SEL_TX_QAV(_i) (0x02 + (_i)) -#define E1000_I210_FIFO_SEL_TX_LEGACY E1000_I210_FIFO_SEL_TX_QAV(0) -#define E1000_I210_FIFO_SEL_BMC2OS_TX 0x06 -#define E1000_I210_FIFO_SEL_BMC2OS_RX 0x01 -#define E1000_EECD_FLUPD_I210 0x00800000 /* Update FLASH */ -#define E1000_EECD_FLUDONE_I210 0x04000000 /* Update FLASH done*/ -#define E1000_FLUDONE_ATTEMPTS 20000 -#define E1000_EERD_EEWR_MAX_COUNT 512 /* buffered EEPROM words rw */ -#define E1000_I210_FIFO_SEL_RX 0x00 -#define E1000_I210_FIFO_SEL_TX_QAV(_i) (0x02 + (_i)) -#define E1000_I210_FIFO_SEL_TX_LEGACY E1000_I210_FIFO_SEL_TX_QAV(0) -#define E1000_I210_FIFO_SEL_BMC2OS_TX 0x06 -#define E1000_I210_FIFO_SEL_BMC2OS_RX 0x01 - /* Offset to data in NVM read/write registers */ #define E1000_NVM_RW_REG_DATA 16 @@ -635,16 +613,6 @@ #define NVM_CHECKSUM_REG 0x003F #define NVM_COMPATIBILITY_REG_3 0x0003 #define NVM_COMPATIBILITY_BIT_MASK 0x8000 -#define NVM_MAC_ADDR 0x0000 -#define NVM_SUB_DEV_ID 0x000B -#define NVM_SUB_VEN_ID 0x000C -#define NVM_DEV_ID 0x000D -#define NVM_VEN_ID 0x000E -#define NVM_INIT_CTRL_2 0x000F -#define NVM_INIT_CTRL_4 0x0013 -#define NVM_LED_1_CFG 0x001C -#define NVM_LED_0_2_CFG 0x001F - #define E1000_NVM_CFG_DONE_PORT_0 0x040000 /* MNG config cycle done */ #define E1000_NVM_CFG_DONE_PORT_1 0x080000 /* ...for second port */ @@ -671,7 +639,6 @@ #define NVM_PBA_OFFSET_0 8 #define NVM_PBA_OFFSET_1 9 -#define NVM_RESERVED_WORD 0xFFFF #define NVM_PBA_PTR_GUARD 0xFAFA #define NVM_WORD_SIZE_BASE_SHIFT 6 @@ -729,7 +696,6 @@ #define I82580_I_PHY_ID 0x015403A0 #define I350_I_PHY_ID 0x015403B0 #define M88_VENDOR 0x0141 -#define I210_I_PHY_ID 0x01410C00 /* M88E1000 Specific Registers */ #define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */ @@ -849,7 +815,6 @@ #define E1000_IPCNFG_EEE_100M_AN 0x00000004 /* EEE Enable 100M AN */ #define E1000_EEER_TX_LPI_EN 0x00010000 /* EEE Tx LPI Enable */ #define E1000_EEER_RX_LPI_EN 0x00020000 /* EEE Rx LPI Enable */ -#define E1000_EEER_FRC_AN 0x10000000 /* Enable EEE in loopback */ #define E1000_EEER_LPI_FC 0x00040000 /* EEE Enable on FC */ /* SerDes Control */ diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_hw.h b/trunk/drivers/net/ethernet/intel/igb/e1000_hw.h index c2a51dcda550..f67cbd3fa307 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_hw.h +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_hw.h @@ -63,13 +63,6 @@ struct e1000_hw; #define E1000_DEV_ID_I350_FIBER 0x1522 #define E1000_DEV_ID_I350_SERDES 0x1523 #define E1000_DEV_ID_I350_SGMII 0x1524 -#define E1000_DEV_ID_I210_COPPER 0x1533 -#define E1000_DEV_ID_I210_COPPER_OEM1 0x1534 -#define E1000_DEV_ID_I210_COPPER_IT 0x1535 -#define E1000_DEV_ID_I210_FIBER 0x1536 -#define E1000_DEV_ID_I210_SERDES 0x1537 -#define E1000_DEV_ID_I210_SGMII 0x1538 -#define E1000_DEV_ID_I211_COPPER 0x1539 #define E1000_REVISION_2 2 #define E1000_REVISION_4 4 @@ -90,8 +83,6 @@ enum e1000_mac_type { e1000_82576, e1000_82580, e1000_i350, - e1000_i210, - e1000_i211, e1000_num_macs /* List is 1-based, so subtract 1 for true count. */ }; @@ -126,7 +117,6 @@ enum e1000_phy_type { e1000_phy_igp_3, e1000_phy_ife, e1000_phy_82580, - e1000_phy_i210, }; enum e1000_bus_type { @@ -323,9 +313,6 @@ struct e1000_mac_operations { void (*rar_set)(struct e1000_hw *, u8 *, u32); s32 (*read_mac_addr)(struct e1000_hw *); s32 (*get_speed_and_duplex)(struct e1000_hw *, u16 *, u16 *); - s32 (*acquire_swfw_sync)(struct e1000_hw *, u16); - void (*release_swfw_sync)(struct e1000_hw *, u16); - }; struct e1000_phy_operations { @@ -351,7 +338,6 @@ struct e1000_nvm_operations { s32 (*write)(struct e1000_hw *, u16, u16, u16 *); s32 (*update)(struct e1000_hw *); s32 (*validate)(struct e1000_hw *); - s32 (*valid_led_default)(struct e1000_hw *, u16 *); }; struct e1000_info { diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_i210.c b/trunk/drivers/net/ethernet/intel/igb/e1000_i210.c deleted file mode 100644 index 77a5f939bc74..000000000000 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_i210.c +++ /dev/null @@ -1,603 +0,0 @@ -/******************************************************************************* - - Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. - - This program is free software; you can redistribute it and/or modify it - under the terms and conditions of the GNU General Public License, - version 2, as published by the Free Software Foundation. - - This program is distributed in the hope it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - - The full GNU General Public License is included in this distribution in - the file called "COPYING". - - Contact Information: - e1000-devel Mailing List - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -******************************************************************************/ - -/* e1000_i210 - * e1000_i211 - */ - -#include -#include - -#include "e1000_hw.h" -#include "e1000_i210.h" - -static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw); -static void igb_put_hw_semaphore_i210(struct e1000_hw *hw); -static s32 igb_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words, - u16 *data); -static s32 igb_pool_flash_update_done_i210(struct e1000_hw *hw); - -/** - * igb_acquire_nvm_i210 - Request for access to EEPROM - * @hw: pointer to the HW structure - * - * Acquire the necessary semaphores for exclusive access to the EEPROM. - * Set the EEPROM access request bit and wait for EEPROM access grant bit. - * Return successful if access grant bit set, else clear the request for - * EEPROM access and return -E1000_ERR_NVM (-1). - **/ -s32 igb_acquire_nvm_i210(struct e1000_hw *hw) -{ - return igb_acquire_swfw_sync_i210(hw, E1000_SWFW_EEP_SM); -} - -/** - * igb_release_nvm_i210 - Release exclusive access to EEPROM - * @hw: pointer to the HW structure - * - * Stop any current commands to the EEPROM and clear the EEPROM request bit, - * then release the semaphores acquired. - **/ -void igb_release_nvm_i210(struct e1000_hw *hw) -{ - igb_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM); -} - -/** - * igb_acquire_swfw_sync_i210 - Acquire SW/FW semaphore - * @hw: pointer to the HW structure - * @mask: specifies which semaphore to acquire - * - * Acquire the SW/FW semaphore to access the PHY or NVM. The mask - * will also specify which port we're acquiring the lock for. - **/ -s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask) -{ - u32 swfw_sync; - u32 swmask = mask; - u32 fwmask = mask << 16; - s32 ret_val = E1000_SUCCESS; - s32 i = 0, timeout = 200; /* FIXME: find real value to use here */ - - while (i < timeout) { - if (igb_get_hw_semaphore_i210(hw)) { - ret_val = -E1000_ERR_SWFW_SYNC; - goto out; - } - - swfw_sync = rd32(E1000_SW_FW_SYNC); - if (!(swfw_sync & fwmask)) - break; - - /* - * Firmware currently using resource (fwmask) - */ - igb_put_hw_semaphore_i210(hw); - mdelay(5); - i++; - } - - if (i == timeout) { - hw_dbg("Driver can't access resource, SW_FW_SYNC timeout.\n"); - ret_val = -E1000_ERR_SWFW_SYNC; - goto out; - } - - swfw_sync |= swmask; - wr32(E1000_SW_FW_SYNC, swfw_sync); - - igb_put_hw_semaphore_i210(hw); -out: - return ret_val; -} - -/** - * igb_release_swfw_sync_i210 - Release SW/FW semaphore - * @hw: pointer to the HW structure - * @mask: specifies which semaphore to acquire - * - * Release the SW/FW semaphore used to access the PHY or NVM. The mask - * will also specify which port we're releasing the lock for. - **/ -void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask) -{ - u32 swfw_sync; - - while (igb_get_hw_semaphore_i210(hw) != E1000_SUCCESS) - ; /* Empty */ - - swfw_sync = rd32(E1000_SW_FW_SYNC); - swfw_sync &= ~mask; - wr32(E1000_SW_FW_SYNC, swfw_sync); - - igb_put_hw_semaphore_i210(hw); -} - -/** - * igb_get_hw_semaphore_i210 - Acquire hardware semaphore - * @hw: pointer to the HW structure - * - * Acquire the HW semaphore to access the PHY or NVM - **/ -static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw) -{ - u32 swsm; - s32 ret_val = E1000_SUCCESS; - s32 timeout = hw->nvm.word_size + 1; - s32 i = 0; - - /* Get the FW semaphore. */ - for (i = 0; i < timeout; i++) { - swsm = rd32(E1000_SWSM); - wr32(E1000_SWSM, swsm | E1000_SWSM_SWESMBI); - - /* Semaphore acquired if bit latched */ - if (rd32(E1000_SWSM) & E1000_SWSM_SWESMBI) - break; - - udelay(50); - } - - if (i == timeout) { - /* Release semaphores */ - igb_put_hw_semaphore(hw); - hw_dbg("Driver can't access the NVM\n"); - ret_val = -E1000_ERR_NVM; - goto out; - } - -out: - return ret_val; -} - -/** - * igb_put_hw_semaphore_i210 - Release hardware semaphore - * @hw: pointer to the HW structure - * - * Release hardware semaphore used to access the PHY or NVM - **/ -static void igb_put_hw_semaphore_i210(struct e1000_hw *hw) -{ - u32 swsm; - - swsm = rd32(E1000_SWSM); - - swsm &= ~E1000_SWSM_SWESMBI; - - wr32(E1000_SWSM, swsm); -} - -/** - * igb_read_nvm_srrd_i210 - Reads Shadow Ram using EERD register - * @hw: pointer to the HW structure - * @offset: offset of word in the Shadow Ram to read - * @words: number of words to read - * @data: word read from the Shadow Ram - * - * Reads a 16 bit word from the Shadow Ram using the EERD register. - * Uses necessary synchronization semaphores. - **/ -s32 igb_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, u16 words, - u16 *data) -{ - s32 status = E1000_SUCCESS; - u16 i, count; - - /* We cannot hold synchronization semaphores for too long, - * because of forceful takeover procedure. However it is more efficient - * to read in bursts than synchronizing access for each word. */ - for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) { - count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ? - E1000_EERD_EEWR_MAX_COUNT : (words - i); - if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) { - status = igb_read_nvm_eerd(hw, offset, count, - data + i); - hw->nvm.ops.release(hw); - } else { - status = E1000_ERR_SWFW_SYNC; - } - - if (status != E1000_SUCCESS) - break; - } - - return status; -} - -/** - * igb_write_nvm_srwr_i210 - Write to Shadow RAM using EEWR - * @hw: pointer to the HW structure - * @offset: offset within the Shadow RAM to be written to - * @words: number of words to write - * @data: 16 bit word(s) to be written to the Shadow RAM - * - * Writes data to Shadow RAM at offset using EEWR register. - * - * If e1000_update_nvm_checksum is not called after this function , the - * data will not be committed to FLASH and also Shadow RAM will most likely - * contain an invalid checksum. - * - * If error code is returned, data and Shadow RAM may be inconsistent - buffer - * partially written. - **/ -s32 igb_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words, - u16 *data) -{ - s32 status = E1000_SUCCESS; - u16 i, count; - - /* We cannot hold synchronization semaphores for too long, - * because of forceful takeover procedure. However it is more efficient - * to write in bursts than synchronizing access for each word. */ - for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) { - count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ? - E1000_EERD_EEWR_MAX_COUNT : (words - i); - if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) { - status = igb_write_nvm_srwr(hw, offset, count, - data + i); - hw->nvm.ops.release(hw); - } else { - status = E1000_ERR_SWFW_SYNC; - } - - if (status != E1000_SUCCESS) - break; - } - - return status; -} - -/** - * igb_write_nvm_srwr - Write to Shadow Ram using EEWR - * @hw: pointer to the HW structure - * @offset: offset within the Shadow Ram to be written to - * @words: number of words to write - * @data: 16 bit word(s) to be written to the Shadow Ram - * - * Writes data to Shadow Ram at offset using EEWR register. - * - * If igb_update_nvm_checksum is not called after this function , the - * Shadow Ram will most likely contain an invalid checksum. - **/ -static s32 igb_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words, - u16 *data) -{ - struct e1000_nvm_info *nvm = &hw->nvm; - u32 i, k, eewr = 0; - u32 attempts = 100000; - s32 ret_val = E1000_SUCCESS; - - /* - * A check for invalid values: offset too large, too many words, - * too many words for the offset, and not enough words. - */ - if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || - (words == 0)) { - hw_dbg("nvm parameter(s) out of bounds\n"); - ret_val = -E1000_ERR_NVM; - goto out; - } - - for (i = 0; i < words; i++) { - eewr = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) | - (data[i] << E1000_NVM_RW_REG_DATA) | - E1000_NVM_RW_REG_START; - - wr32(E1000_SRWR, eewr); - - for (k = 0; k < attempts; k++) { - if (E1000_NVM_RW_REG_DONE & - rd32(E1000_SRWR)) { - ret_val = E1000_SUCCESS; - break; - } - udelay(5); - } - - if (ret_val != E1000_SUCCESS) { - hw_dbg("Shadow RAM write EEWR timed out\n"); - break; - } - } - -out: - return ret_val; -} - -/** - * igb_read_nvm_i211 - Read NVM wrapper function for I211 - * @hw: pointer to the HW structure - * @address: the word address (aka eeprom offset) to read - * @data: pointer to the data read - * - * Wrapper function to return data formerly found in the NVM. - **/ -s32 igb_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words, - u16 *data) -{ - s32 ret_val = E1000_SUCCESS; - - /* Only the MAC addr is required to be present in the iNVM */ - switch (offset) { - case NVM_MAC_ADDR: - ret_val = igb_read_invm_i211(hw, offset, &data[0]); - ret_val |= igb_read_invm_i211(hw, offset+1, &data[1]); - ret_val |= igb_read_invm_i211(hw, offset+2, &data[2]); - if (ret_val != E1000_SUCCESS) - hw_dbg("MAC Addr not found in iNVM\n"); - break; - case NVM_ID_LED_SETTINGS: - case NVM_INIT_CTRL_2: - case NVM_INIT_CTRL_4: - case NVM_LED_1_CFG: - case NVM_LED_0_2_CFG: - igb_read_invm_i211(hw, offset, data); - break; - case NVM_COMPAT: - *data = ID_LED_DEFAULT_I210; - break; - case NVM_SUB_DEV_ID: - *data = hw->subsystem_device_id; - break; - case NVM_SUB_VEN_ID: - *data = hw->subsystem_vendor_id; - break; - case NVM_DEV_ID: - *data = hw->device_id; - break; - case NVM_VEN_ID: - *data = hw->vendor_id; - break; - default: - hw_dbg("NVM word 0x%02x is not mapped.\n", offset); - *data = NVM_RESERVED_WORD; - break; - } - return ret_val; -} - -/** - * igb_read_invm_i211 - Reads OTP - * @hw: pointer to the HW structure - * @address: the word address (aka eeprom offset) to read - * @data: pointer to the data read - * - * Reads 16-bit words from the OTP. Return error when the word is not - * stored in OTP. - **/ -s32 igb_read_invm_i211(struct e1000_hw *hw, u16 address, u16 *data) -{ - s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND; - u32 invm_dword; - u16 i; - u8 record_type, word_address; - - for (i = 0; i < E1000_INVM_SIZE; i++) { - invm_dword = rd32(E1000_INVM_DATA_REG(i)); - /* Get record type */ - record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword); - if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE) - break; - if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE) - i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS; - if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE) - i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS; - if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) { - word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword); - if (word_address == (u8)address) { - *data = INVM_DWORD_TO_WORD_DATA(invm_dword); - hw_dbg("Read INVM Word 0x%02x = %x", - address, *data); - status = E1000_SUCCESS; - break; - } - } - } - if (status != E1000_SUCCESS) - hw_dbg("Requested word 0x%02x not found in OTP\n", address); - return status; -} - -/** - * igb_validate_nvm_checksum_i210 - Validate EEPROM checksum - * @hw: pointer to the HW structure - * - * Calculates the EEPROM checksum by reading/adding each word of the EEPROM - * and then verifies that the sum of the EEPROM is equal to 0xBABA. - **/ -s32 igb_validate_nvm_checksum_i210(struct e1000_hw *hw) -{ - s32 status = E1000_SUCCESS; - s32 (*read_op_ptr)(struct e1000_hw *, u16, u16, u16 *); - - if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) { - - /* - * Replace the read function with semaphore grabbing with - * the one that skips this for a while. - * We have semaphore taken already here. - */ - read_op_ptr = hw->nvm.ops.read; - hw->nvm.ops.read = igb_read_nvm_eerd; - - status = igb_validate_nvm_checksum(hw); - - /* Revert original read operation. */ - hw->nvm.ops.read = read_op_ptr; - - hw->nvm.ops.release(hw); - } else { - status = E1000_ERR_SWFW_SYNC; - } - - return status; -} - - -/** - * igb_update_nvm_checksum_i210 - Update EEPROM checksum - * @hw: pointer to the HW structure - * - * Updates the EEPROM checksum by reading/adding each word of the EEPROM - * up to the checksum. Then calculates the EEPROM checksum and writes the - * value to the EEPROM. Next commit EEPROM data onto the Flash. - **/ -s32 igb_update_nvm_checksum_i210(struct e1000_hw *hw) -{ - s32 ret_val = E1000_SUCCESS; - u16 checksum = 0; - u16 i, nvm_data; - - /* - * Read the first word from the EEPROM. If this times out or fails, do - * not continue or we could be in for a very long wait while every - * EEPROM read fails - */ - ret_val = igb_read_nvm_eerd(hw, 0, 1, &nvm_data); - if (ret_val != E1000_SUCCESS) { - hw_dbg("EEPROM read failed\n"); - goto out; - } - - if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) { - /* - * Do not use hw->nvm.ops.write, hw->nvm.ops.read - * because we do not want to take the synchronization - * semaphores twice here. - */ - - for (i = 0; i < NVM_CHECKSUM_REG; i++) { - ret_val = igb_read_nvm_eerd(hw, i, 1, &nvm_data); - if (ret_val) { - hw->nvm.ops.release(hw); - hw_dbg("NVM Read Error while updating checksum.\n"); - goto out; - } - checksum += nvm_data; - } - checksum = (u16) NVM_SUM - checksum; - ret_val = igb_write_nvm_srwr(hw, NVM_CHECKSUM_REG, 1, - &checksum); - if (ret_val != E1000_SUCCESS) { - hw->nvm.ops.release(hw); - hw_dbg("NVM Write Error while updating checksum.\n"); - goto out; - } - - hw->nvm.ops.release(hw); - - ret_val = igb_update_flash_i210(hw); - } else { - ret_val = -E1000_ERR_SWFW_SYNC; - } -out: - return ret_val; -} - -/** - * igb_update_flash_i210 - Commit EEPROM to the flash - * @hw: pointer to the HW structure - * - **/ -s32 igb_update_flash_i210(struct e1000_hw *hw) -{ - s32 ret_val = E1000_SUCCESS; - u32 flup; - - ret_val = igb_pool_flash_update_done_i210(hw); - if (ret_val == -E1000_ERR_NVM) { - hw_dbg("Flash update time out\n"); - goto out; - } - - flup = rd32(E1000_EECD) | E1000_EECD_FLUPD_I210; - wr32(E1000_EECD, flup); - - ret_val = igb_pool_flash_update_done_i210(hw); - if (ret_val == E1000_SUCCESS) - hw_dbg("Flash update complete\n"); - else - hw_dbg("Flash update time out\n"); - -out: - return ret_val; -} - -/** - * igb_pool_flash_update_done_i210 - Pool FLUDONE status. - * @hw: pointer to the HW structure - * - **/ -s32 igb_pool_flash_update_done_i210(struct e1000_hw *hw) -{ - s32 ret_val = -E1000_ERR_NVM; - u32 i, reg; - - for (i = 0; i < E1000_FLUDONE_ATTEMPTS; i++) { - reg = rd32(E1000_EECD); - if (reg & E1000_EECD_FLUDONE_I210) { - ret_val = E1000_SUCCESS; - break; - } - udelay(5); - } - - return ret_val; -} - -/** - * igb_valid_led_default_i210 - Verify a valid default LED config - * @hw: pointer to the HW structure - * @data: pointer to the NVM (EEPROM) - * - * Read the EEPROM for the current default LED configuration. If the - * LED configuration is not valid, set to a valid LED configuration. - **/ -s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data) -{ - s32 ret_val; - - ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data); - if (ret_val) { - hw_dbg("NVM Read Error\n"); - goto out; - } - - if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) { - switch (hw->phy.media_type) { - case e1000_media_type_internal_serdes: - *data = ID_LED_DEFAULT_I210_SERDES; - break; - case e1000_media_type_copper: - default: - *data = ID_LED_DEFAULT_I210; - break; - } - } -out: - return ret_val; -} diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_i210.h b/trunk/drivers/net/ethernet/intel/igb/e1000_i210.h deleted file mode 100644 index 5dc2bd3f50bc..000000000000 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_i210.h +++ /dev/null @@ -1,76 +0,0 @@ -/******************************************************************************* - - Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2012 Intel Corporation. - - This program is free software; you can redistribute it and/or modify it - under the terms and conditions of the GNU General Public License, - version 2, as published by the Free Software Foundation. - - This program is distributed in the hope it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - - The full GNU General Public License is included in this distribution in - the file called "COPYING". - - Contact Information: - e1000-devel Mailing List - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -*******************************************************************************/ - -#ifndef _E1000_I210_H_ -#define _E1000_I210_H_ - -extern s32 igb_update_flash_i210(struct e1000_hw *hw); -extern s32 igb_update_nvm_checksum_i210(struct e1000_hw *hw); -extern s32 igb_validate_nvm_checksum_i210(struct e1000_hw *hw); -extern s32 igb_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, - u16 words, u16 *data); -extern s32 igb_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, - u16 words, u16 *data); -extern s32 igb_read_invm_i211(struct e1000_hw *hw, u16 address, u16 *data); -extern s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask); -extern void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask); -extern s32 igb_acquire_nvm_i210(struct e1000_hw *hw); -extern void igb_release_nvm_i210(struct e1000_hw *hw); -extern s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data); -extern s32 igb_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words, - u16 *data); - -#define E1000_STM_OPCODE 0xDB00 -#define E1000_EEPROM_FLASH_SIZE_WORD 0x11 - -#define INVM_DWORD_TO_RECORD_TYPE(invm_dword) \ - (u8)((invm_dword) & 0x7) -#define INVM_DWORD_TO_WORD_ADDRESS(invm_dword) \ - (u8)(((invm_dword) & 0x0000FE00) >> 9) -#define INVM_DWORD_TO_WORD_DATA(invm_dword) \ - (u16)(((invm_dword) & 0xFFFF0000) >> 16) - -enum E1000_INVM_STRUCTURE_TYPE { - E1000_INVM_UNINITIALIZED_STRUCTURE = 0x00, - E1000_INVM_WORD_AUTOLOAD_STRUCTURE = 0x01, - E1000_INVM_CSR_AUTOLOAD_STRUCTURE = 0x02, - E1000_INVM_PHY_REGISTER_AUTOLOAD_STRUCTURE = 0x03, - E1000_INVM_RSA_KEY_SHA256_STRUCTURE = 0x04, - E1000_INVM_INVALIDATED_STRUCTURE = 0x0F, -}; - -#define E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS 8 -#define E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS 1 - -#define ID_LED_DEFAULT_I210 ((ID_LED_OFF1_ON2 << 8) | \ - (ID_LED_OFF1_OFF2 << 4) | \ - (ID_LED_DEF1_DEF2)) -#define ID_LED_DEFAULT_I210_SERDES ((ID_LED_DEF1_DEF2 << 8) | \ - (ID_LED_DEF1_DEF2 << 4) | \ - (ID_LED_DEF1_DEF2)) - -#endif diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_mac.c b/trunk/drivers/net/ethernet/intel/igb/e1000_mac.c index 819c145ac762..f57338afd71f 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_mac.c +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_mac.c @@ -658,7 +658,6 @@ s32 igb_setup_link(struct e1000_hw *hw) ret_val = igb_set_fc_watermarks(hw); out: - return ret_val; } diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_nvm.c b/trunk/drivers/net/ethernet/intel/igb/e1000_nvm.c index aa5fcdf3f357..fa2c6ba62139 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_nvm.c +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_nvm.c @@ -710,3 +710,4 @@ s32 igb_update_nvm_checksum(struct e1000_hw *hw) out: return ret_val; } + diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_phy.c b/trunk/drivers/net/ethernet/intel/igb/e1000_phy.c index 7be98b6f1052..789de5b83aad 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_phy.c +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_phy.c @@ -35,7 +35,6 @@ static s32 igb_phy_setup_autoneg(struct e1000_hw *hw); static void igb_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl); static s32 igb_wait_autoneg(struct e1000_hw *hw); -static s32 igb_set_master_slave_mode(struct e1000_hw *hw); /* Cable length tables */ static const u16 e1000_m88_cable_length_table[] = @@ -571,11 +570,6 @@ s32 igb_copper_link_setup_m88(struct e1000_hw *hw) hw_dbg("Error committing the PHY changes\n"); goto out; } - if (phy->type == e1000_phy_i210) { - ret_val = igb_set_master_slave_mode(hw); - if (ret_val) - return ret_val; - } out: return ret_val; @@ -1219,22 +1213,12 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw) goto out; if (!link) { - bool reset_dsp = true; - - switch (hw->phy.id) { - case I347AT4_E_PHY_ID: - case M88E1112_E_PHY_ID: - case I210_I_PHY_ID: - reset_dsp = false; - break; - default: - if (hw->phy.type != e1000_phy_m88) - reset_dsp = false; - break; - } - if (!reset_dsp) + if (hw->phy.type != e1000_phy_m88 || + hw->phy.id == I347AT4_E_PHY_ID || + hw->phy.id == M88E1112_E_PHY_ID) { hw_dbg("Link taking longer than expected.\n"); - else { + } else { + /* * We didn't get link. * Reset the DSP and cross our fingers. @@ -1259,8 +1243,7 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw) if (hw->phy.type != e1000_phy_m88 || hw->phy.id == I347AT4_E_PHY_ID || - hw->phy.id == M88E1112_E_PHY_ID || - hw->phy.id == I210_I_PHY_ID) + hw->phy.id == M88E1112_E_PHY_ID) goto out; ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); @@ -1458,7 +1441,6 @@ s32 igb_check_downshift(struct e1000_hw *hw) u16 phy_data, offset, mask; switch (phy->type) { - case e1000_phy_i210: case e1000_phy_m88: case e1000_phy_gg82563: offset = M88E1000_PHY_SPEC_STATUS; @@ -1494,7 +1476,7 @@ s32 igb_check_downshift(struct e1000_hw *hw) * * Polarity is determined based on the PHY specific status register. **/ -s32 igb_check_polarity_m88(struct e1000_hw *hw) +static s32 igb_check_polarity_m88(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -1683,7 +1665,6 @@ s32 igb_get_cable_length_m88_gen2(struct e1000_hw *hw) u16 phy_data, phy_data2, index, default_page, is_cm; switch (hw->phy.id) { - case I210_I_PHY_ID: case I347AT4_E_PHY_ID: /* Remember the original page select and set it to 7 */ ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT, @@ -2148,16 +2129,10 @@ s32 igb_phy_init_script_igp3(struct e1000_hw *hw) void igb_power_up_phy_copper(struct e1000_hw *hw) { u16 mii_reg = 0; - u16 power_reg = 0; /* The PHY will retain its settings across a power down/up cycle */ hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg); mii_reg &= ~MII_CR_POWER_DOWN; - if (hw->phy.type == e1000_phy_i210) { - hw->phy.ops.read_reg(hw, GS40G_COPPER_SPEC, &power_reg); - power_reg &= ~GS40G_CS_POWER_DOWN; - hw->phy.ops.write_reg(hw, GS40G_COPPER_SPEC, power_reg); - } hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg); } @@ -2171,18 +2146,10 @@ void igb_power_up_phy_copper(struct e1000_hw *hw) void igb_power_down_phy_copper(struct e1000_hw *hw) { u16 mii_reg = 0; - u16 power_reg = 0; /* The PHY will retain its settings across a power down/up cycle */ hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg); mii_reg |= MII_CR_POWER_DOWN; - - /* i210 Phy requires an additional bit for power up/down */ - if (hw->phy.type == e1000_phy_i210) { - hw->phy.ops.read_reg(hw, GS40G_COPPER_SPEC, &power_reg); - power_reg |= GS40G_CS_POWER_DOWN; - hw->phy.ops.write_reg(hw, GS40G_COPPER_SPEC, power_reg); - } hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg); msleep(1); } @@ -2378,103 +2345,3 @@ s32 igb_get_cable_length_82580(struct e1000_hw *hw) out: return ret_val; } - -/** - * igb_write_phy_reg_gs40g - Write GS40G PHY register - * @hw: pointer to the HW structure - * @offset: lower half is register offset to write to - * upper half is page to use. - * @data: data to write at register offset - * - * Acquires semaphore, if necessary, then writes the data to PHY register - * at the offset. Release any acquired semaphores before exiting. - **/ -s32 igb_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data) -{ - s32 ret_val; - u16 page = offset >> GS40G_PAGE_SHIFT; - - offset = offset & GS40G_OFFSET_MASK; - ret_val = hw->phy.ops.acquire(hw); - if (ret_val) - return ret_val; - - ret_val = igb_write_phy_reg_mdic(hw, GS40G_PAGE_SELECT, page); - if (ret_val) - goto release; - ret_val = igb_write_phy_reg_mdic(hw, offset, data); - -release: - hw->phy.ops.release(hw); - return ret_val; -} - -/** - * igb_read_phy_reg_gs40g - Read GS40G PHY register - * @hw: pointer to the HW structure - * @offset: lower half is register offset to read to - * upper half is page to use. - * @data: data to read at register offset - * - * Acquires semaphore, if necessary, then reads the data in the PHY register - * at the offset. Release any acquired semaphores before exiting. - **/ -s32 igb_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data) -{ - s32 ret_val; - u16 page = offset >> GS40G_PAGE_SHIFT; - - offset = offset & GS40G_OFFSET_MASK; - ret_val = hw->phy.ops.acquire(hw); - if (ret_val) - return ret_val; - - ret_val = igb_write_phy_reg_mdic(hw, GS40G_PAGE_SELECT, page); - if (ret_val) - goto release; - ret_val = igb_read_phy_reg_mdic(hw, offset, data); - -release: - hw->phy.ops.release(hw); - return ret_val; -} - -/** - * igb_set_master_slave_mode - Setup PHY for Master/slave mode - * @hw: pointer to the HW structure - * - * Sets up Master/slave mode - **/ -static s32 igb_set_master_slave_mode(struct e1000_hw *hw) -{ - s32 ret_val; - u16 phy_data; - - /* Resolve Master/Slave mode */ - ret_val = hw->phy.ops.read_reg(hw, PHY_1000T_CTRL, &phy_data); - if (ret_val) - return ret_val; - - /* load defaults for future use */ - hw->phy.original_ms_type = (phy_data & CR_1000T_MS_ENABLE) ? - ((phy_data & CR_1000T_MS_VALUE) ? - e1000_ms_force_master : - e1000_ms_force_slave) : e1000_ms_auto; - - switch (hw->phy.ms_type) { - case e1000_ms_force_master: - phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE); - break; - case e1000_ms_force_slave: - phy_data |= CR_1000T_MS_ENABLE; - phy_data &= ~(CR_1000T_MS_VALUE); - break; - case e1000_ms_auto: - phy_data &= ~CR_1000T_MS_ENABLE; - /* fall-through */ - default: - break; - } - - return hw->phy.ops.write_reg(hw, PHY_1000T_CTRL, phy_data); -} diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_phy.h b/trunk/drivers/net/ethernet/intel/igb/e1000_phy.h index 34e40619f16b..4c32ac66ff39 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_phy.h +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_phy.h @@ -73,9 +73,6 @@ s32 igb_copper_link_setup_82580(struct e1000_hw *hw); s32 igb_get_phy_info_82580(struct e1000_hw *hw); s32 igb_phy_force_speed_duplex_82580(struct e1000_hw *hw); s32 igb_get_cable_length_82580(struct e1000_hw *hw); -s32 igb_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data); -s32 igb_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data); -s32 igb_check_polarity_m88(struct e1000_hw *hw); /* IGP01E1000 Specific Registers */ #define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */ @@ -117,13 +114,6 @@ s32 igb_check_polarity_m88(struct e1000_hw *hw); /* I82580 PHY Diagnostics Status */ #define I82580_DSTATUS_CABLE_LENGTH 0x03FC #define I82580_DSTATUS_CABLE_LENGTH_SHIFT 2 - -/* 82580 PHY Power Management */ -#define E1000_82580_PHY_POWER_MGMT 0xE14 -#define E1000_82580_PM_SPD 0x0001 /* Smart Power Down */ -#define E1000_82580_PM_D0_LPLU 0x0002 /* For D0a states */ -#define E1000_82580_PM_D3_LPLU 0x0004 /* For all other states */ - /* Enable flexible speed on link-up */ #define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */ #define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */ @@ -143,16 +133,4 @@ s32 igb_check_polarity_m88(struct e1000_hw *hw); #define E1000_CABLE_LENGTH_UNDEFINED 0xFF -/* GS40G - I210 PHY defines */ -#define GS40G_PAGE_SELECT 0x16 -#define GS40G_PAGE_SHIFT 16 -#define GS40G_OFFSET_MASK 0xFFFF -#define GS40G_PAGE_2 0x20000 -#define GS40G_MAC_REG2 0x15 -#define GS40G_MAC_LB 0x4140 -#define GS40G_MAC_SPEED_1G 0X0006 -#define GS40G_COPPER_SPEC 0x0010 -#define GS40G_CS_POWER_DOWN 0x0002 -#define GS40G_LINE_LB 0x4000 - #endif diff --git a/trunk/drivers/net/ethernet/intel/igb/e1000_regs.h b/trunk/drivers/net/ethernet/intel/igb/e1000_regs.h index 35d1e4f2c92c..ccdf36d503fd 100644 --- a/trunk/drivers/net/ethernet/intel/igb/e1000_regs.h +++ b/trunk/drivers/net/ethernet/intel/igb/e1000_regs.h @@ -352,18 +352,4 @@ #define E1000_O2BGPTC 0x08FE4 /* OS2BMC packets received by BMC */ #define E1000_O2BSPC 0x0415C /* OS2BMC packets transmitted by host */ -#define E1000_SRWR 0x12018 /* Shadow Ram Write Register - RW */ -#define E1000_I210_FLMNGCTL 0x12038 -#define E1000_I210_FLMNGDATA 0x1203C -#define E1000_I210_FLMNGCNT 0x12040 - -#define E1000_I210_FLSWCTL 0x12048 -#define E1000_I210_FLSWDATA 0x1204C -#define E1000_I210_FLSWCNT 0x12050 - -#define E1000_I210_FLA 0x1201C - -#define E1000_INVM_DATA_REG(_n) (0x12120 + 4*(_n)) -#define E1000_INVM_SIZE 64 /* Number of INVM Data Registers */ - #endif diff --git a/trunk/drivers/net/ethernet/intel/igb/igb.h b/trunk/drivers/net/ethernet/intel/igb/igb.h index ae6d3f393a54..3758ad246742 100644 --- a/trunk/drivers/net/ethernet/intel/igb/igb.h +++ b/trunk/drivers/net/ethernet/intel/igb/igb.h @@ -65,13 +65,10 @@ struct igb_adapter; #define MAX_Q_VECTORS 8 /* Transmit and receive queues */ -#define IGB_MAX_RX_QUEUES ((adapter->vfs_allocated_count ? 2 : \ - (hw->mac.type > e1000_82575 ? 8 : 4))) -#define IGB_MAX_RX_QUEUES_I210 4 -#define IGB_MAX_RX_QUEUES_I211 2 +#define IGB_MAX_RX_QUEUES (adapter->vfs_allocated_count ? 2 : \ + (hw->mac.type > e1000_82575 ? 8 : 4)) #define IGB_MAX_TX_QUEUES 16 -#define IGB_MAX_TX_QUEUES_I210 4 -#define IGB_MAX_TX_QUEUES_I211 2 + #define IGB_MAX_VF_MC_ENTRIES 30 #define IGB_MAX_VF_FUNCTIONS 8 #define IGB_MAX_VFTA_ENTRIES 128 diff --git a/trunk/drivers/net/ethernet/intel/igb/igb_ethtool.c b/trunk/drivers/net/ethernet/intel/igb/igb_ethtool.c index 812d4f963bd1..e10821a0f249 100644 --- a/trunk/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/trunk/drivers/net/ethernet/intel/igb/igb_ethtool.c @@ -335,7 +335,7 @@ static void igb_set_msglevel(struct net_device *netdev, u32 data) static int igb_get_regs_len(struct net_device *netdev) { -#define IGB_REGS_LEN 739 +#define IGB_REGS_LEN 551 return IGB_REGS_LEN * sizeof(u32); } @@ -552,49 +552,10 @@ static void igb_get_regs(struct net_device *netdev, regs_buff[548] = rd32(E1000_TDFT); regs_buff[549] = rd32(E1000_TDFHS); regs_buff[550] = rd32(E1000_TDFPC); - - if (hw->mac.type > e1000_82580) { - regs_buff[551] = adapter->stats.o2bgptc; - regs_buff[552] = adapter->stats.b2ospc; - regs_buff[553] = adapter->stats.o2bspc; - regs_buff[554] = adapter->stats.b2ogprc; - } - - if (hw->mac.type != e1000_82576) - return; - for (i = 0; i < 12; i++) - regs_buff[555 + i] = rd32(E1000_SRRCTL(i + 4)); - for (i = 0; i < 4; i++) - regs_buff[567 + i] = rd32(E1000_PSRTYPE(i + 4)); - for (i = 0; i < 12; i++) - regs_buff[571 + i] = rd32(E1000_RDBAL(i + 4)); - for (i = 0; i < 12; i++) - regs_buff[583 + i] = rd32(E1000_RDBAH(i + 4)); - for (i = 0; i < 12; i++) - regs_buff[595 + i] = rd32(E1000_RDLEN(i + 4)); - for (i = 0; i < 12; i++) - regs_buff[607 + i] = rd32(E1000_RDH(i + 4)); - for (i = 0; i < 12; i++) - regs_buff[619 + i] = rd32(E1000_RDT(i + 4)); - for (i = 0; i < 12; i++) - regs_buff[631 + i] = rd32(E1000_RXDCTL(i + 4)); - - for (i = 0; i < 12; i++) - regs_buff[643 + i] = rd32(E1000_TDBAL(i + 4)); - for (i = 0; i < 12; i++) - regs_buff[655 + i] = rd32(E1000_TDBAH(i + 4)); - for (i = 0; i < 12; i++) - regs_buff[667 + i] = rd32(E1000_TDLEN(i + 4)); - for (i = 0; i < 12; i++) - regs_buff[679 + i] = rd32(E1000_TDH(i + 4)); - for (i = 0; i < 12; i++) - regs_buff[691 + i] = rd32(E1000_TDT(i + 4)); - for (i = 0; i < 12; i++) - regs_buff[703 + i] = rd32(E1000_TXDCTL(i + 4)); - for (i = 0; i < 12; i++) - regs_buff[715 + i] = rd32(E1000_TDWBAL(i + 4)); - for (i = 0; i < 12; i++) - regs_buff[727 + i] = rd32(E1000_TDWBAH(i + 4)); + regs_buff[551] = adapter->stats.o2bgptc; + regs_buff[552] = adapter->stats.b2ospc; + regs_buff[553] = adapter->stats.o2bspc; + regs_buff[554] = adapter->stats.b2ogprc; } static int igb_get_eeprom_len(struct net_device *netdev) @@ -663,9 +624,6 @@ static int igb_set_eeprom(struct net_device *netdev, if (eeprom->len == 0) return -EOPNOTSUPP; - if (hw->mac.type == e1000_i211) - return -EOPNOTSUPP; - if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16))) return -EFAULT; @@ -893,36 +851,6 @@ struct igb_reg_test { #define TABLE64_TEST_LO 5 #define TABLE64_TEST_HI 6 -/* i210 reg test */ -static struct igb_reg_test reg_test_i210[] = { - { E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, - { E1000_FCAH, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF }, - { E1000_FCT, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF }, - { E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, - { E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, - { E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, - /* RDH is read-only for i210, only test RDT. */ - { E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, - { E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 }, - { E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, - { E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF }, - { E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, - { E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, - { E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, - { E1000_TDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, - { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 }, - { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB }, - { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF }, - { E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 }, - { E1000_RA, 0, 16, TABLE64_TEST_LO, - 0xFFFFFFFF, 0xFFFFFFFF }, - { E1000_RA, 0, 16, TABLE64_TEST_HI, - 0x900FFFFF, 0xFFFFFFFF }, - { E1000_MTA, 0, 128, TABLE32_TEST, - 0xFFFFFFFF, 0xFFFFFFFF }, - { 0, 0, 0, 0, 0 } -}; - /* i350 reg test */ static struct igb_reg_test reg_test_i350[] = { { E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, @@ -1145,11 +1073,6 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data) test = reg_test_i350; toggle = 0x7FEFF3FF; break; - case e1000_i210: - case e1000_i211: - test = reg_test_i210; - toggle = 0x7FEFF3FF; - break; case e1000_82580: test = reg_test_82580; toggle = 0x7FEFF3FF; @@ -1231,14 +1154,24 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data) static int igb_eeprom_test(struct igb_adapter *adapter, u64 *data) { - *data = 0; + u16 temp; + u16 checksum = 0; + u16 i; - /* Validate eeprom on all parts but i211 */ - if (adapter->hw.mac.type != e1000_i211) { - if (adapter->hw.nvm.ops.validate(&adapter->hw) < 0) - *data = 2; + *data = 0; + /* Read and add up the contents of the EEPROM */ + for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) { + if ((adapter->hw.nvm.ops.read(&adapter->hw, i, 1, &temp)) < 0) { + *data = 1; + break; + } + checksum += temp; } + /* If Checksum is not Correct return error else test passed */ + if ((checksum != (u16) NVM_SUM) && !(*data)) + *data = 2; + return *data; } @@ -1303,8 +1236,6 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data) ics_mask = 0x77DCFED5; break; case e1000_i350: - case e1000_i210: - case e1000_i211: ics_mask = 0x77DCFED5; break; default: @@ -1471,35 +1402,23 @@ static int igb_integrated_phy_loopback(struct igb_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; u32 ctrl_reg = 0; - u16 phy_reg = 0; hw->mac.autoneg = false; - switch (hw->phy.type) { - case e1000_phy_m88: + if (hw->phy.type == e1000_phy_m88) { /* Auto-MDI/MDIX Off */ igb_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, 0x0808); /* reset to update Auto-MDI/MDIX */ igb_write_phy_reg(hw, PHY_CONTROL, 0x9140); /* autoneg off */ igb_write_phy_reg(hw, PHY_CONTROL, 0x8140); - break; - case e1000_phy_82580: + } else if (hw->phy.type == e1000_phy_82580) { /* enable MII loopback */ igb_write_phy_reg(hw, I82580_PHY_LBK_CTRL, 0x8041); - break; - case e1000_phy_i210: - /* set loopback speed in PHY */ - igb_read_phy_reg(hw, (GS40G_PAGE_SELECT & GS40G_PAGE_2), - &phy_reg); - phy_reg |= GS40G_MAC_SPEED_1G; - igb_write_phy_reg(hw, (GS40G_PAGE_SELECT & GS40G_PAGE_2), - phy_reg); - ctrl_reg = rd32(E1000_CTRL_EXT); - default: - break; } + ctrl_reg = rd32(E1000_CTRL); + /* force 1000, set loopback */ igb_write_phy_reg(hw, PHY_CONTROL, 0x4140); @@ -1512,7 +1431,7 @@ static int igb_integrated_phy_loopback(struct igb_adapter *adapter) E1000_CTRL_FD | /* Force Duplex to FULL */ E1000_CTRL_SLU); /* Set link up enable bit */ - if ((hw->phy.type == e1000_phy_m88) || (hw->phy.type == e1000_phy_i210)) + if (hw->phy.type == e1000_phy_m88) ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */ wr32(E1000_CTRL, ctrl_reg); @@ -1520,7 +1439,7 @@ static int igb_integrated_phy_loopback(struct igb_adapter *adapter) /* Disable the receiver on the PHY so when a cable is plugged in, the * PHY does not begin to autoneg when a cable is reconnected to the NIC. */ - if ((hw->phy.type == e1000_phy_m88) || (hw->phy.type == e1000_phy_i210)) + if (hw->phy.type == e1000_phy_m88) igb_phy_disable_receiver(adapter); udelay(500); @@ -1785,14 +1704,6 @@ static int igb_loopback_test(struct igb_adapter *adapter, u64 *data) *data = 0; goto out; } - if ((adapter->hw.mac.type == e1000_i210) - || (adapter->hw.mac.type == e1000_i210)) { - dev_err(&adapter->pdev->dev, - "Loopback test not supported " - "on this part at this time.\n"); - *data = 0; - goto out; - } *data = igb_setup_desc_rings(adapter); if (*data) goto out; diff --git a/trunk/drivers/net/ethernet/intel/igb/igb_main.c b/trunk/drivers/net/ethernet/intel/igb/igb_main.c index dd3bfe8cd36c..80d52d2dfea3 100644 --- a/trunk/drivers/net/ethernet/intel/igb/igb_main.c +++ b/trunk/drivers/net/ethernet/intel/igb/igb_main.c @@ -75,11 +75,6 @@ static const struct e1000_info *igb_info_tbl[] = { }; static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = { - { PCI_VDEVICE(INTEL, E1000_DEV_ID_I211_COPPER), board_82575 }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_COPPER), board_82575 }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_FIBER), board_82575 }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_SERDES), board_82575 }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_SGMII), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_COPPER), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_FIBER), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_SERDES), board_82575 }, @@ -646,8 +641,6 @@ static void igb_cache_ring_register(struct igb_adapter *adapter) case e1000_82575: case e1000_82580: case e1000_i350: - case e1000_i210: - case e1000_i211: default: for (; i < adapter->num_rx_queues; i++) adapter->rx_ring[i]->reg_idx = rbase_offset + i; @@ -734,11 +727,8 @@ static int igb_alloc_queues(struct igb_adapter *adapter) if (adapter->hw.mac.type >= e1000_82576) set_bit(IGB_RING_FLAG_RX_SCTP_CSUM, &ring->flags); - /* - * On i350, i210, and i211, loopback VLAN packets - * have the tag byte-swapped. - * */ - if (adapter->hw.mac.type >= e1000_i350) + /* On i350, loopback VLAN packets have the tag byte-swapped. */ + if (adapter->hw.mac.type == e1000_i350) set_bit(IGB_RING_FLAG_RX_LB_VLAN_BSWAP, &ring->flags); adapter->rx_ring[i] = ring; @@ -832,8 +822,6 @@ static void igb_assign_vector(struct igb_q_vector *q_vector, int msix_vector) break; case e1000_82580: case e1000_i350: - case e1000_i210: - case e1000_i211: /* * On 82580 and newer adapters the scheme is similar to 82576 * however instead of ordering column-major we have things @@ -900,8 +888,6 @@ static void igb_configure_msix(struct igb_adapter *adapter) case e1000_82576: case e1000_82580: case e1000_i350: - case e1000_i210: - case e1000_i211: /* Turn on MSI-X capability first, or our settings * won't stick. And it will take days to debug. */ wr32(E1000_GPIE, E1000_GPIE_MSIX_MODE | @@ -1048,11 +1034,6 @@ static int igb_set_interrupt_capability(struct igb_adapter *adapter) if (!(adapter->flags & IGB_FLAG_QUEUE_PAIRS)) numvecs += adapter->num_tx_queues; - /* i210 and i211 can only have 4 MSIX vectors for rx/tx queues. */ - if ((adapter->hw.mac.type == e1000_i210) - || (adapter->hw.mac.type == e1000_i211)) - numvecs = 4; - /* store the number of vectors reserved for queues */ adapter->num_q_vectors = numvecs; @@ -1060,7 +1041,6 @@ static int igb_set_interrupt_capability(struct igb_adapter *adapter) numvecs++; adapter->msix_entries = kcalloc(numvecs, sizeof(struct msix_entry), GFP_KERNEL); - if (!adapter->msix_entries) goto msi_only; @@ -1103,12 +1083,9 @@ static int igb_set_interrupt_capability(struct igb_adapter *adapter) adapter->flags |= IGB_FLAG_HAS_MSI; out: /* Notify the stack of the (possibly) reduced queue counts. */ - rtnl_lock(); netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues); - err = netif_set_real_num_rx_queues(adapter->netdev, - adapter->num_rx_queues); - rtnl_unlock(); - return err; + return netif_set_real_num_rx_queues(adapter->netdev, + adapter->num_rx_queues); } /** @@ -1654,8 +1631,6 @@ void igb_reset(struct igb_adapter *adapter) pba &= E1000_RXPBS_SIZE_MASK_82576; break; case e1000_82575: - case e1000_i210: - case e1000_i211: default: pba = E1000_PBA_34K; break; @@ -1851,7 +1826,7 @@ static int __devinit igb_probe(struct pci_dev *pdev, */ if (pdev->is_virtfn) { WARN(1, KERN_ERR "%s (%hx:%hx) should not be a VF!\n", - pci_name(pdev), pdev->vendor, pdev->device); + pci_name(pdev), pdev->vendor, pdev->device); return -EINVAL; } @@ -2005,16 +1980,11 @@ static int __devinit igb_probe(struct pci_dev *pdev, * known good starting state */ hw->mac.ops.reset_hw(hw); - /* - * make sure the NVM is good , i211 parts have special NVM that - * doesn't contain a checksum - */ - if (hw->mac.type != e1000_i211) { - if (hw->nvm.ops.validate(hw) < 0) { - dev_err(&pdev->dev, "The NVM Checksum Is Not Valid\n"); - err = -EIO; - goto err_eeprom; - } + /* make sure the NVM is good */ + if (hw->nvm.ops.validate(hw) < 0) { + dev_err(&pdev->dev, "The NVM Checksum Is Not Valid\n"); + err = -EIO; + goto err_eeprom; } /* copy the MAC address out of the NVM */ @@ -2148,8 +2118,6 @@ static int __devinit igb_probe(struct pci_dev *pdev, adapter->num_rx_queues, adapter->num_tx_queues); switch (hw->mac.type) { case e1000_i350: - case e1000_i210: - case e1000_i211: igb_set_eee_i350(hw); break; default: @@ -2276,14 +2244,9 @@ static void __devinit igb_probe_vfs(struct igb_adapter * adapter) { #ifdef CONFIG_PCI_IOV struct pci_dev *pdev = adapter->pdev; - struct e1000_hw *hw = &adapter->hw; int old_vfs = igb_find_enabled_vfs(adapter); int i; - /* Virtualization features not supported on i210 family. */ - if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211)) - return; - if (old_vfs) { dev_info(&pdev->dev, "%d pre-allocated VFs found - override " "max_vfs setting of %d\n", old_vfs, max_vfs); @@ -2295,7 +2258,6 @@ static void __devinit igb_probe_vfs(struct igb_adapter * adapter) adapter->vf_data = kcalloc(adapter->vfs_allocated_count, sizeof(struct vf_data_storage), GFP_KERNEL); - /* if allocation failed then we do not support SR-IOV */ if (!adapter->vf_data) { adapter->vfs_allocated_count = 0; @@ -2370,28 +2332,11 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter) } else adapter->vfs_allocated_count = max_vfs; break; - case e1000_i210: - case e1000_i211: - adapter->vfs_allocated_count = 0; - break; default: break; } #endif /* CONFIG_PCI_IOV */ - switch (hw->mac.type) { - case e1000_i210: - adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES_I210, - num_online_cpus()); - break; - case e1000_i211: - adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES_I211, - num_online_cpus()); - break; - default: - adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES, - num_online_cpus()); - break; - } + adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES, num_online_cpus()); /* i350 cannot do RSS and SR-IOV at the same time */ if (hw->mac.type == e1000_i350 && adapter->vfs_allocated_count) adapter->rss_queues = 1; @@ -2421,7 +2366,7 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter) /* Explicitly disable IRQ since the NIC can be in any state. */ igb_irq_disable(adapter); - if (hw->mac.type >= e1000_i350) + if (hw->mac.type == e1000_i350) adapter->flags &= ~IGB_FLAG_DMAC; set_bit(__IGB_DOWN, &adapter->state); @@ -2874,17 +2819,6 @@ static void igb_setup_mrqc(struct igb_adapter *adapter) /* Don't need to set TUOFL or IPOFL, they default to 1 */ wr32(E1000_RXCSUM, rxcsum); - /* - * Generate RSS hash based on TCP port numbers and/or - * IPv4/v6 src and dst addresses since UDP cannot be - * hashed reliably due to IP fragmentation - */ - - mrqc = E1000_MRQC_RSS_FIELD_IPV4 | - E1000_MRQC_RSS_FIELD_IPV4_TCP | - E1000_MRQC_RSS_FIELD_IPV6 | - E1000_MRQC_RSS_FIELD_IPV6_TCP | - E1000_MRQC_RSS_FIELD_IPV6_TCP_EX; /* If VMDq is enabled then we set the appropriate mode for that, else * we default to RSS so that an RSS hash is calculated per packet even @@ -2900,15 +2834,25 @@ static void igb_setup_mrqc(struct igb_adapter *adapter) wr32(E1000_VT_CTL, vtctl); } if (adapter->rss_queues > 1) - mrqc |= E1000_MRQC_ENABLE_VMDQ_RSS_2Q; + mrqc = E1000_MRQC_ENABLE_VMDQ_RSS_2Q; else - mrqc |= E1000_MRQC_ENABLE_VMDQ; + mrqc = E1000_MRQC_ENABLE_VMDQ; } else { - if (hw->mac.type != e1000_i211) - mrqc |= E1000_MRQC_ENABLE_RSS_4Q; + mrqc = E1000_MRQC_ENABLE_RSS_4Q; } igb_vmm_control(adapter); + /* + * Generate RSS hash based on TCP port numbers and/or + * IPv4/v6 src and dst addresses since UDP cannot be + * hashed reliably due to IP fragmentation + */ + mrqc |= E1000_MRQC_RSS_FIELD_IPV4 | + E1000_MRQC_RSS_FIELD_IPV4_TCP | + E1000_MRQC_RSS_FIELD_IPV6 | + E1000_MRQC_RSS_FIELD_IPV6_TCP | + E1000_MRQC_RSS_FIELD_IPV6_TCP_EX; + wr32(E1000_MRQC, mrqc); } @@ -3510,7 +3454,7 @@ static void igb_set_rx_mode(struct net_device *netdev) * we will have issues with VLAN tag stripping not being done for frames * that are only arriving because we are the default pool */ - if ((hw->mac.type < e1000_82576) || (hw->mac.type > e1000_i350)) + if (hw->mac.type < e1000_82576) return; vmolr |= rd32(E1000_VMOLR(vfn)) & @@ -3607,7 +3551,7 @@ static bool igb_thermal_sensor_event(struct e1000_hw *hw, u32 event) bool ret = false; u32 ctrl_ext, thstat; - /* check for thermal sensor event on i350 copper only */ + /* check for thermal sensor event on i350, copper only */ if (hw->mac.type == e1000_i350) { thstat = rd32(E1000_THSTAT); ctrl_ext = rd32(E1000_CTRL_EXT); @@ -6709,7 +6653,18 @@ static int igb_resume(struct device *dev) pci_enable_wake(pdev, PCI_D3hot, 0); pci_enable_wake(pdev, PCI_D3cold, 0); - if (igb_init_interrupt_scheme(adapter)) { + if (!rtnl_is_locked()) { + /* + * shut up ASSERT_RTNL() warning in + * netif_set_real_num_tx/rx_queues. + */ + rtnl_lock(); + err = igb_init_interrupt_scheme(adapter); + rtnl_unlock(); + } else { + err = igb_init_interrupt_scheme(adapter); + } + if (err) { dev_err(&pdev->dev, "Unable to allocate memory for queues\n"); return -ENOMEM; } @@ -7072,8 +7027,6 @@ static void igb_vmm_control(struct igb_adapter *adapter) switch (hw->mac.type) { case e1000_82575: - case e1000_i210: - case e1000_i211: default: /* replication is not supported for 82575 */ return; @@ -7147,9 +7100,6 @@ static void igb_init_dmac(struct igb_adapter *adapter, u32 pba) /* watchdog timer= +-1000 usec in 32usec intervals */ reg |= (1000 >> 5); - - /* Disable BMC-to-OS Watchdog Enable */ - reg &= ~E1000_DMACR_DC_BMC2OSW_EN; wr32(E1000_DMACR, reg); /* diff --git a/trunk/drivers/net/ethernet/intel/igb/igb_ptp.c b/trunk/drivers/net/ethernet/intel/igb/igb_ptp.c index d5ee7fa50723..c9b71c5bc475 100644 --- a/trunk/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/trunk/drivers/net/ethernet/intel/igb/igb_ptp.c @@ -262,8 +262,6 @@ void igb_ptp_init(struct igb_adapter *adapter) struct e1000_hw *hw = &adapter->hw; switch (hw->mac.type) { - case e1000_i210: - case e1000_i211: case e1000_i350: case e1000_82580: adapter->caps.owner = THIS_MODULE; @@ -364,8 +362,6 @@ void igb_systim_to_hwtstamp(struct igb_adapter *adapter, unsigned long flags; switch (adapter->hw.mac.type) { - case e1000_i210: - case e1000_i211: case e1000_i350: case e1000_82580: case e1000_82576: diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/Makefile b/trunk/drivers/net/ethernet/intel/ixgbe/Makefile index 0bdf06bc5c49..0708d7eb4668 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/Makefile +++ b/trunk/drivers/net/ethernet/intel/ixgbe/Makefile @@ -39,6 +39,4 @@ ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \ ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \ ixgbe_dcb_82599.o ixgbe_dcb_nl.o -ixgbe-$(CONFIG_IXGBE_PTP) += ixgbe_ptp.o - ixgbe-$(CONFIG_FCOE:m=y) += ixgbe_fcoe.o diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 3ef3c5284e52..425f86432f90 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -36,12 +36,6 @@ #include #include -#ifdef CONFIG_IXGBE_PTP -#include -#include -#include -#endif /* CONFIG_IXGBE_PTP */ - #include "ixgbe_type.h" #include "ixgbe_common.h" #include "ixgbe_dcb.h" @@ -102,7 +96,6 @@ #define IXGBE_TX_FLAGS_FCOE (u32)(1 << 5) #define IXGBE_TX_FLAGS_FSO (u32)(1 << 6) #define IXGBE_TX_FLAGS_TXSW (u32)(1 << 7) -#define IXGBE_TX_FLAGS_TSTAMP (u32)(1 << 8) #define IXGBE_TX_FLAGS_VLAN_MASK 0xffff0000 #define IXGBE_TX_FLAGS_VLAN_PRIO_MASK 0xe0000000 #define IXGBE_TX_FLAGS_VLAN_PRIO_SHIFT 29 @@ -465,8 +458,6 @@ struct ixgbe_adapter { #define IXGBE_FLAG2_FDIR_REQUIRES_REINIT (u32)(1 << 7) #define IXGBE_FLAG2_RSS_FIELD_IPV4_UDP (u32)(1 << 8) #define IXGBE_FLAG2_RSS_FIELD_IPV6_UDP (u32)(1 << 9) -#define IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED (u32)(1 << 10) -#define IXGBE_FLAG2_PTP_PPS_ENABLED (u32)(1 << 11) /* Tx fast path data */ int num_tx_queues; @@ -554,17 +545,6 @@ struct ixgbe_adapter { u32 interrupt_event; u32 led_reg; -#ifdef CONFIG_IXGBE_PTP - struct ptp_clock *ptp_clock; - struct ptp_clock_info ptp_caps; - unsigned long last_overflow_check; - spinlock_t tmreg_lock; - struct cyclecounter cc; - struct timecounter tc; - u32 base_incval; - u32 cycle_speed; -#endif /* CONFIG_IXGBE_PTP */ - /* SR-IOV */ DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS); unsigned int num_vfs; @@ -672,15 +652,12 @@ extern void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input, union ixgbe_atr_input *mask); extern void ixgbe_set_rx_mode(struct net_device *netdev); #ifdef CONFIG_IXGBE_DCB -extern void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter); extern int ixgbe_setup_tc(struct net_device *dev, u8 tc); #endif extern void ixgbe_tx_ctxtdesc(struct ixgbe_ring *, u32, u32, u32, u32); extern void ixgbe_do_reset(struct net_device *netdev); -#ifdef CONFIG_IXGBE_HWMON extern void ixgbe_sysfs_exit(struct ixgbe_adapter *adapter); extern int ixgbe_sysfs_init(struct ixgbe_adapter *adapter); -#endif /* CONFIG_IXGBE_HWMON */ #ifdef IXGBE_FCOE extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter); extern int ixgbe_fso(struct ixgbe_ring *tx_ring, @@ -711,18 +688,4 @@ static inline struct netdev_queue *txring_txq(const struct ixgbe_ring *ring) return netdev_get_tx_queue(ring->netdev, ring->queue_index); } -#ifdef CONFIG_IXGBE_PTP -extern void ixgbe_ptp_init(struct ixgbe_adapter *adapter); -extern void ixgbe_ptp_stop(struct ixgbe_adapter *adapter); -extern void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter); -extern void ixgbe_ptp_tx_hwtstamp(struct ixgbe_q_vector *q_vector, - struct sk_buff *skb); -extern void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, - struct sk_buff *skb); -extern int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, - struct ifreq *ifr, int cmd); -extern void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter); -extern void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr); -#endif /* CONFIG_IXGBE_PTP */ - #endif /* _IXGBE_H_ */ diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c index 77ac41feb0fe..c7e51b85b8b6 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c @@ -2561,7 +2561,7 @@ s32 ixgbe_disable_rx_buff_generic(struct ixgbe_hw *hw) break; else /* Use interrupt-safe sleep just in case */ - udelay(1000); + udelay(10); } /* For informational purposes only */ diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c index 87592b458c9c..d3695edfcb8b 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c @@ -191,46 +191,53 @@ s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, */ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en) { - u32 fcrtl, reg; + u32 reg; u8 i; - /* Enable Transmit Priority Flow Control */ - reg = IXGBE_READ_REG(hw, IXGBE_RMCS); - reg &= ~IXGBE_RMCS_TFCE_802_3X; - reg |= IXGBE_RMCS_TFCE_PRIORITY; - IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg); - - /* Enable Receive Priority Flow Control */ - reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); - reg &= ~(IXGBE_FCTRL_RPFCE | IXGBE_FCTRL_RFCE); - - if (pfc_en) + if (pfc_en) { + /* Enable Transmit Priority Flow Control */ + reg = IXGBE_READ_REG(hw, IXGBE_RMCS); + reg &= ~IXGBE_RMCS_TFCE_802_3X; + /* correct the reporting of our flow control status */ + reg |= IXGBE_RMCS_TFCE_PRIORITY; + IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg); + + /* Enable Receive Priority Flow Control */ + reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); + reg &= ~IXGBE_FCTRL_RFCE; reg |= IXGBE_FCTRL_RPFCE; + IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg); - IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg); + /* Configure pause time */ + for (i = 0; i < (MAX_TRAFFIC_CLASS >> 1); i++) + IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), 0x68006800); - fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE; - /* Configure PFC Tx thresholds per TC */ - for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { - if (!(pfc_en & (1 << i))) { - IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0); - IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0); - continue; - } - - reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN; - IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl); - IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg); + /* Configure flow control refresh threshold value */ + IXGBE_WRITE_REG(hw, IXGBE_FCRTV, 0x3400); } - /* Configure pause time */ - reg = hw->fc.pause_time * 0x00010001; - for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++) - IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); + /* + * Configure flow control thresholds and enable priority flow control + * for each traffic class. + */ + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { + int enabled = pfc_en & (1 << i); + + reg = hw->fc.low_water << 10; + + if (enabled == pfc_enabled_tx || + enabled == pfc_enabled_full) + reg |= IXGBE_FCRTL_XONE; - /* Configure flow control refresh threshold value */ - IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2); + IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), reg); + reg = hw->fc.high_water[i] << 10; + if (enabled == pfc_enabled_tx || + enabled == pfc_enabled_full) + reg |= IXGBE_FCRTH_FCEN; + + IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg); + } return 0; } diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c index 4eac80d01857..65913c5a616e 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c @@ -211,42 +211,24 @@ s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, */ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc) { - u32 i, j, fcrtl, reg; + u32 i, j, reg; u8 max_tc = 0; - /* Enable Transmit Priority Flow Control */ - IXGBE_WRITE_REG(hw, IXGBE_FCCFG, IXGBE_FCCFG_TFCE_PRIORITY); - - /* Enable Receive Priority Flow Control */ - reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); - reg |= IXGBE_MFLCN_DPF; - - /* - * X540 supports per TC Rx priority flow control. So - * clear all TCs and only enable those that should be - * enabled. - */ - reg &= ~(IXGBE_MFLCN_RPFCE_MASK | IXGBE_MFLCN_RFCE); - - if (hw->mac.type == ixgbe_mac_X540) - reg |= pfc_en << IXGBE_MFLCN_RPFCE_SHIFT; - - if (pfc_en) - reg |= IXGBE_MFLCN_RPFCE; - - IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg); - - for (i = 0; i < MAX_USER_PRIORITY; i++) { + for (i = 0; i < MAX_USER_PRIORITY; i++) if (prio_tc[i] > max_tc) max_tc = prio_tc[i]; - } - - fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE; /* Configure PFC Tx thresholds per TC */ - for (i = 0; i <= max_tc; i++) { + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { int enabled = 0; + if (i > max_tc) { + reg = 0; + IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg); + IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg); + continue; + } + for (j = 0; j < MAX_USER_PRIORITY; j++) { if ((prio_tc[j] == i) && (pfc_en & (1 << j))) { enabled = 1; @@ -254,29 +236,50 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc) } } - if (enabled) { - reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN; - IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl); - } else { - reg = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 32; - IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0); - } + reg = hw->fc.low_water << 10; + if (enabled) + reg |= IXGBE_FCRTL_XONE; + IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg); + + reg = hw->fc.high_water[i] << 10; + if (enabled) + reg |= IXGBE_FCRTH_FCEN; IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg); } - for (; i < MAX_TRAFFIC_CLASS; i++) { - IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0); - IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), 0); - } + if (pfc_en) { + /* Configure pause time (2 TCs per register) */ + reg = hw->fc.pause_time | (hw->fc.pause_time << 16); + for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++) + IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); + + /* Configure flow control refresh threshold value */ + IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2); + + + reg = IXGBE_FCCFG_TFCE_PRIORITY; + IXGBE_WRITE_REG(hw, IXGBE_FCCFG, reg); + /* + * Enable Receive PFC + * 82599 will always honor XOFF frames we receive when + * we are in PFC mode however X540 only honors enabled + * traffic classes. + */ + reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); + reg &= ~IXGBE_MFLCN_RFCE; + reg |= IXGBE_MFLCN_RPFCE | IXGBE_MFLCN_DPF; + + if (hw->mac.type == ixgbe_mac_X540) { + reg &= ~IXGBE_MFLCN_RPFCE_MASK; + reg |= pfc_en << IXGBE_MFLCN_RPFCE_SHIFT; + } - /* Configure pause time (2 TCs per register) */ - reg = hw->fc.pause_time * 0x00010001; - for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++) - IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); + IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg); - /* Configure flow control refresh threshold value */ - IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2); + } else { + hw->mac.ops.fc_enable(hw); + } return 0; } diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c index 5164a21b13ca..a09d6b4f0ab0 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c @@ -338,8 +338,6 @@ static void ixgbe_dcbnl_devreset(struct net_device *dev) static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - struct ixgbe_dcb_config *dcb_cfg = &adapter->dcb_cfg; - struct ixgbe_hw *hw = &adapter->hw; int ret = DCB_NO_HW_CHG; int i; @@ -352,6 +350,32 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) if (!adapter->dcb_set_bitmap) return ret; + if (adapter->dcb_cfg.pfc_mode_enable) { + switch (adapter->hw.mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + if (adapter->hw.fc.current_mode != ixgbe_fc_pfc) + adapter->last_lfc_mode = + adapter->hw.fc.current_mode; + break; + default: + break; + } + adapter->hw.fc.requested_mode = ixgbe_fc_pfc; + } else { + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: + adapter->hw.fc.requested_mode = ixgbe_fc_none; + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + adapter->hw.fc.requested_mode = adapter->last_lfc_mode; + break; + default: + break; + } + } + if (adapter->dcb_set_bitmap & (BIT_PG_TX|BIT_PG_RX)) { u16 refill[MAX_TRAFFIC_CLASS], max[MAX_TRAFFIC_CLASS]; u8 bwg_id[MAX_TRAFFIC_CLASS], prio_type[MAX_TRAFFIC_CLASS]; @@ -364,19 +388,23 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE); #endif - ixgbe_dcb_calculate_tc_credits(hw, dcb_cfg, max_frame, - DCB_TX_CONFIG); - ixgbe_dcb_calculate_tc_credits(hw, dcb_cfg, max_frame, - DCB_RX_CONFIG); + ixgbe_dcb_calculate_tc_credits(&adapter->hw, &adapter->dcb_cfg, + max_frame, DCB_TX_CONFIG); + ixgbe_dcb_calculate_tc_credits(&adapter->hw, &adapter->dcb_cfg, + max_frame, DCB_RX_CONFIG); - ixgbe_dcb_unpack_refill(dcb_cfg, DCB_TX_CONFIG, refill); - ixgbe_dcb_unpack_max(dcb_cfg, max); - ixgbe_dcb_unpack_bwgid(dcb_cfg, DCB_TX_CONFIG, bwg_id); - ixgbe_dcb_unpack_prio(dcb_cfg, DCB_TX_CONFIG, prio_type); - ixgbe_dcb_unpack_map(dcb_cfg, DCB_TX_CONFIG, prio_tc); + ixgbe_dcb_unpack_refill(&adapter->dcb_cfg, + DCB_TX_CONFIG, refill); + ixgbe_dcb_unpack_max(&adapter->dcb_cfg, max); + ixgbe_dcb_unpack_bwgid(&adapter->dcb_cfg, + DCB_TX_CONFIG, bwg_id); + ixgbe_dcb_unpack_prio(&adapter->dcb_cfg, + DCB_TX_CONFIG, prio_type); + ixgbe_dcb_unpack_map(&adapter->dcb_cfg, + DCB_TX_CONFIG, prio_tc); - ixgbe_dcb_hw_ets_config(hw, refill, max, bwg_id, - prio_type, prio_tc); + ixgbe_dcb_hw_ets_config(&adapter->hw, refill, max, + bwg_id, prio_type, prio_tc); for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) netdev_set_prio_tc_map(netdev, i, prio_tc[i]); @@ -385,22 +413,20 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) } if (adapter->dcb_set_bitmap & BIT_PFC) { - if (dcb_cfg->pfc_mode_enable) { - u8 pfc_en; - u8 prio_tc[MAX_USER_PRIORITY]; - - ixgbe_dcb_unpack_map(dcb_cfg, DCB_TX_CONFIG, prio_tc); - ixgbe_dcb_unpack_pfc(dcb_cfg, &pfc_en); - ixgbe_dcb_hw_pfc_config(hw, pfc_en, prio_tc); - } else { - hw->mac.ops.fc_enable(hw); - } - - ixgbe_set_rx_drop_en(adapter); + u8 pfc_en; + u8 prio_tc[MAX_USER_PRIORITY]; - ret = DCB_HW_CHG; + ixgbe_dcb_unpack_map(&adapter->dcb_cfg, + DCB_TX_CONFIG, prio_tc); + ixgbe_dcb_unpack_pfc(&adapter->dcb_cfg, &pfc_en); + ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc_en, prio_tc); + if (ret != DCB_HW_CHG_RST) + ret = DCB_HW_CHG; } + if (adapter->dcb_cfg.pfc_mode_enable) + adapter->hw.fc.current_mode = ixgbe_fc_pfc; + #ifdef IXGBE_FCOE /* Reprogam FCoE hardware offloads when the traffic class * FCoE is using changes. This happens if the APP info @@ -621,9 +647,7 @@ static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev, struct ieee_pfc *pfc) { struct ixgbe_adapter *adapter = netdev_priv(dev); - struct ixgbe_hw *hw = &adapter->hw; u8 *prio_tc; - int err; if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) return -EINVAL; @@ -635,18 +659,16 @@ static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev, return -ENOMEM; } + if (pfc->pfc_en) { + adapter->last_lfc_mode = adapter->hw.fc.current_mode; + adapter->hw.fc.current_mode = ixgbe_fc_pfc; + } else { + adapter->hw.fc.current_mode = adapter->last_lfc_mode; + } + prio_tc = adapter->ixgbe_ieee_ets->prio_tc; memcpy(adapter->ixgbe_ieee_pfc, pfc, sizeof(*adapter->ixgbe_ieee_pfc)); - - /* Enable link flow control parameters if PFC is disabled */ - if (pfc->pfc_en) - err = ixgbe_dcb_hw_pfc_config(hw, pfc->pfc_en, prio_tc); - else - err = hw->mac.ops.fc_enable(hw); - - ixgbe_set_rx_drop_en(adapter); - - return err; + return ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc->pfc_en, prio_tc); } static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev, diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 3178f1ec3711..cca3e9c4a08a 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -391,6 +391,11 @@ static void ixgbe_get_pauseparam(struct net_device *netdev, } else if (hw->fc.current_mode == ixgbe_fc_full) { pause->rx_pause = 1; pause->tx_pause = 1; +#ifdef CONFIG_DCB + } else if (hw->fc.current_mode == ixgbe_fc_pfc) { + pause->rx_pause = 0; + pause->tx_pause = 0; +#endif } } @@ -399,14 +404,21 @@ static int ixgbe_set_pauseparam(struct net_device *netdev, { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; - struct ixgbe_fc_info fc = hw->fc; + struct ixgbe_fc_info fc; - /* 82598 does no support link flow control with DCB enabled */ - if ((hw->mac.type == ixgbe_mac_82598EB) && - (adapter->flags & IXGBE_FLAG_DCB_ENABLED)) +#ifdef CONFIG_DCB + if (adapter->dcb_cfg.pfc_mode_enable || + ((hw->mac.type == ixgbe_mac_82598EB) && + (adapter->flags & IXGBE_FLAG_DCB_ENABLED))) return -EINVAL; - fc.disable_fc_autoneg = (pause->autoneg != AUTONEG_ENABLE); +#endif + fc = hw->fc; + + if (pause->autoneg != AUTONEG_ENABLE) + fc.disable_fc_autoneg = true; + else + fc.disable_fc_autoneg = false; if ((pause->rx_pause && pause->tx_pause) || pause->autoneg) fc.requested_mode = ixgbe_fc_full; @@ -414,8 +426,14 @@ static int ixgbe_set_pauseparam(struct net_device *netdev, fc.requested_mode = ixgbe_fc_rx_pause; else if (!pause->rx_pause && pause->tx_pause) fc.requested_mode = ixgbe_fc_tx_pause; - else + else if (!pause->rx_pause && !pause->tx_pause) fc.requested_mode = ixgbe_fc_none; + else + return -EINVAL; + +#ifdef CONFIG_DCB + adapter->last_lfc_mode = fc.requested_mode; +#endif /* if the thing changed then we'll update and use new autoneg */ if (memcmp(&fc, &hw->fc, sizeof(struct ixgbe_fc_info))) { @@ -2696,46 +2714,6 @@ static int ixgbe_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd) return ret; } -static int ixgbe_get_ts_info(struct net_device *dev, - struct ethtool_ts_info *info) -{ - struct ixgbe_adapter *adapter = netdev_priv(dev); - - switch (adapter->hw.mac.type) { -#ifdef CONFIG_IXGBE_PTP - case ixgbe_mac_X540: - case ixgbe_mac_82599EB: - info->so_timestamping = - SOF_TIMESTAMPING_TX_HARDWARE | - SOF_TIMESTAMPING_RX_HARDWARE | - SOF_TIMESTAMPING_RAW_HARDWARE; - - if (adapter->ptp_clock) - info->phc_index = ptp_clock_index(adapter->ptp_clock); - else - info->phc_index = -1; - - info->tx_types = - (1 << HWTSTAMP_TX_OFF) | - (1 << HWTSTAMP_TX_ON); - - info->rx_filters = - (1 << HWTSTAMP_FILTER_NONE) | - (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) | - (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) | - (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | - (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) | - (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | - (1 << HWTSTAMP_FILTER_SOME); - break; -#endif /* CONFIG_IXGBE_PTP */ - default: - return ethtool_op_get_ts_info(dev, info); - break; - } - return 0; -} - static const struct ethtool_ops ixgbe_ethtool_ops = { .get_settings = ixgbe_get_settings, .set_settings = ixgbe_set_settings, @@ -2764,7 +2742,6 @@ static const struct ethtool_ops ixgbe_ethtool_ops = { .set_coalesce = ixgbe_set_coalesce, .get_rxnfc = ixgbe_get_rxnfc, .set_rxnfc = ixgbe_set_rxnfc, - .get_ts_info = ixgbe_get_ts_info, }; void ixgbe_set_ethtool_ops(struct net_device *netdev) diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index bf20457ea23a..ea3cb710c2dd 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -63,8 +63,8 @@ static char ixgbe_default_device_descr[] = "Intel(R) 10 Gigabit Network Connection"; #endif #define MAJ 3 -#define MIN 9 -#define BUILD 15 +#define MIN 8 +#define BUILD 21 #define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \ __stringify(BUILD) "-k" const char ixgbe_driver_version[] = DRV_VERSION; @@ -610,50 +610,39 @@ void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *ring, /* tx_buffer must be completely set up in the transmit path */ } -static void ixgbe_update_xoff_rx_lfc(struct ixgbe_adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - struct ixgbe_hw_stats *hwstats = &adapter->stats; - int i; - u32 data; - - if ((hw->fc.current_mode != ixgbe_fc_full) && - (hw->fc.current_mode != ixgbe_fc_rx_pause)) - return; - - switch (hw->mac.type) { - case ixgbe_mac_82598EB: - data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); - break; - default: - data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); - } - hwstats->lxoffrxc += data; - - /* refill credits (no tx hang) if we received xoff */ - if (!data) - return; - - for (i = 0; i < adapter->num_tx_queues; i++) - clear_bit(__IXGBE_HANG_CHECK_ARMED, - &adapter->tx_ring[i]->state); -} - static void ixgbe_update_xoff_received(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw_stats *hwstats = &adapter->stats; + u32 data = 0; u32 xoff[8] = {0}; int i; - bool pfc_en = adapter->dcb_cfg.pfc_mode_enable; - if (adapter->ixgbe_ieee_pfc) - pfc_en |= !!(adapter->ixgbe_ieee_pfc->pfc_en); + if ((hw->fc.current_mode == ixgbe_fc_full) || + (hw->fc.current_mode == ixgbe_fc_rx_pause)) { + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); + break; + default: + data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); + } + hwstats->lxoffrxc += data; - if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED) || !pfc_en) { - ixgbe_update_xoff_rx_lfc(adapter); + /* refill credits (no tx hang) if we received xoff */ + if (!data) + return; + + for (i = 0; i < adapter->num_tx_queues; i++) + clear_bit(__IXGBE_HANG_CHECK_ARMED, + &adapter->tx_ring[i]->state); + return; + } else if (((adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE) && + !(adapter->dcb_cfg.pfc_mode_enable)) || + ((adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) && + adapter->ixgbe_ieee_pfc && + !(adapter->ixgbe_ieee_pfc->pfc_en))) return; - } /* update stats for each tc, only valid with PFC enabled */ for (i = 0; i < MAX_TX_PACKET_BUFFERS; i++) { @@ -789,13 +778,6 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, total_bytes += tx_buffer->bytecount; total_packets += tx_buffer->gso_segs; -#ifdef CONFIG_IXGBE_PTP - if (unlikely(tx_buffer->tx_flags & - IXGBE_TX_FLAGS_TSTAMP)) - ixgbe_ptp_tx_hwtstamp(q_vector, - tx_buffer->skb); - -#endif /* free the skb */ dev_kfree_skb_any(tx_buffer->skb); @@ -1396,11 +1378,6 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring, ixgbe_rx_checksum(rx_ring, rx_desc, skb); -#ifdef CONFIG_IXGBE_PTP - if (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS)) - ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector, skb); -#endif - if (ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) { u16 vid = le16_to_cpu(rx_desc->wb.upper.vlan); __vlan_hwaccel_put_tag(skb, vid); @@ -2322,9 +2299,6 @@ static irqreturn_t ixgbe_msix_other(int irq, void *data) } ixgbe_check_fan_failure(adapter, eicr); -#ifdef CONFIG_IXGBE_PTP - ixgbe_ptp_check_pps_event(adapter, eicr); -#endif /* re-enable the original interrupt state, no lsc, no queues */ if (!test_bit(__IXGBE_DOWN, &adapter->state)) @@ -2517,9 +2491,6 @@ static irqreturn_t ixgbe_intr(int irq, void *data) } ixgbe_check_fan_failure(adapter, eicr); -#ifdef CONFIG_IXGBE_PTP - ixgbe_ptp_check_pps_event(adapter, eicr); -#endif /* would disable interrupts here but EIAM disabled it */ napi_schedule(&q_vector->napi); @@ -2789,61 +2760,6 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter) ixgbe_configure_tx_ring(adapter, adapter->tx_ring[i]); } -static void ixgbe_enable_rx_drop(struct ixgbe_adapter *adapter, - struct ixgbe_ring *ring) -{ - struct ixgbe_hw *hw = &adapter->hw; - u8 reg_idx = ring->reg_idx; - u32 srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(reg_idx)); - - srrctl |= IXGBE_SRRCTL_DROP_EN; - - IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(reg_idx), srrctl); -} - -static void ixgbe_disable_rx_drop(struct ixgbe_adapter *adapter, - struct ixgbe_ring *ring) -{ - struct ixgbe_hw *hw = &adapter->hw; - u8 reg_idx = ring->reg_idx; - u32 srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(reg_idx)); - - srrctl &= ~IXGBE_SRRCTL_DROP_EN; - - IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(reg_idx), srrctl); -} - -#ifdef CONFIG_IXGBE_DCB -void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter) -#else -static void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter) -#endif -{ - int i; - bool pfc_en = adapter->dcb_cfg.pfc_mode_enable; - - if (adapter->ixgbe_ieee_pfc) - pfc_en |= !!(adapter->ixgbe_ieee_pfc->pfc_en); - - /* - * We should set the drop enable bit if: - * SR-IOV is enabled - * or - * Number of Rx queues > 1 and flow control is disabled - * - * This allows us to avoid head of line blocking for security - * and performance reasons. - */ - if (adapter->num_vfs || (adapter->num_rx_queues > 1 && - !(adapter->hw.fc.current_mode & ixgbe_fc_tx_pause) && !pfc_en)) { - for (i = 0; i < adapter->num_rx_queues; i++) - ixgbe_enable_rx_drop(adapter, adapter->rx_ring[i]); - } else { - for (i = 0; i < adapter->num_rx_queues; i++) - ixgbe_disable_rx_drop(adapter, adapter->rx_ring[i]); - } -} - #define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2 static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, @@ -4487,6 +4403,9 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) /* default flow control settings */ hw->fc.requested_mode = ixgbe_fc_full; hw->fc.current_mode = ixgbe_fc_full; /* init for ethtool output */ +#ifdef CONFIG_DCB + adapter->last_lfc_mode = hw->fc.current_mode; +#endif ixgbe_pbthresh_setup(adapter); hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE; hw->fc.send_xon = true; @@ -5349,10 +5268,8 @@ static void ixgbe_watchdog_update_link(struct ixgbe_adapter *adapter) if (adapter->ixgbe_ieee_pfc) pfc_en |= !!(adapter->ixgbe_ieee_pfc->pfc_en); - if (link_up && !((adapter->flags & IXGBE_FLAG_DCB_ENABLED) && pfc_en)) { + if (link_up && !((adapter->flags & IXGBE_FLAG_DCB_ENABLED) && pfc_en)) hw->mac.ops.fc_enable(hw); - ixgbe_set_rx_drop_en(adapter); - } if (link_up || time_after(jiffies, (adapter->link_check_timeout + @@ -5405,11 +5322,6 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter) flow_rx = false; break; } - -#ifdef CONFIG_IXGBE_PTP - ixgbe_ptp_start_cyclecounter(adapter); -#endif - e_info(drv, "NIC Link is Up %s, Flow Control: %s\n", (link_speed == IXGBE_LINK_SPEED_10GB_FULL ? "10 Gbps" : @@ -5447,10 +5359,6 @@ static void ixgbe_watchdog_link_is_down(struct ixgbe_adapter *adapter) if (ixgbe_is_sfp(hw) && hw->mac.type == ixgbe_mac_82598EB) adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP; -#ifdef CONFIG_IXGBE_PTP - ixgbe_ptp_start_cyclecounter(adapter); -#endif - e_info(drv, "NIC Link is Down\n"); netif_carrier_off(netdev); } @@ -5750,9 +5658,6 @@ static void ixgbe_service_task(struct work_struct *work) ixgbe_watchdog_subtask(adapter); ixgbe_fdir_reinit_subtask(adapter); ixgbe_check_hang_subtask(adapter); -#ifdef CONFIG_IXGBE_PTP - ixgbe_ptp_overflow_check(adapter); -#endif ixgbe_service_event_complete(adapter); } @@ -5903,11 +5808,6 @@ static __le32 ixgbe_tx_cmd_type(u32 tx_flags) if (tx_flags & IXGBE_TX_FLAGS_HW_VLAN) cmd_type |= cpu_to_le32(IXGBE_ADVTXD_DCMD_VLE); -#ifdef CONFIG_IXGBE_PTP - if (tx_flags & IXGBE_TX_FLAGS_TSTAMP) - cmd_type |= cpu_to_le32(IXGBE_ADVTXD_MAC_TSTAMP); -#endif - /* set segmentation enable bits for TSO/FSO */ #ifdef IXGBE_FCOE if (tx_flags & (IXGBE_TX_FLAGS_TSO | IXGBE_TX_FLAGS_FSO)) @@ -6298,15 +6198,6 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, tx_flags |= IXGBE_TX_FLAGS_SW_VLAN; } - skb_tx_timestamp(skb); - -#ifdef CONFIG_IXGBE_PTP - if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { - skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; - tx_flags |= IXGBE_TX_FLAGS_TSTAMP; - } -#endif - #ifdef CONFIG_PCI_IOV /* * Use the l2switch_enable flag - would be false if the DMA @@ -6459,14 +6350,7 @@ static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - switch (cmd) { -#ifdef CONFIG_IXGBE_PTP - case SIOCSHWTSTAMP: - return ixgbe_ptp_hwtstamp_ioctl(adapter, req, cmd); -#endif - default: - return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd); - } + return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd); } /** @@ -6658,17 +6542,15 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc) if (tc) { netdev_set_num_tc(dev, tc); + adapter->last_lfc_mode = adapter->hw.fc.current_mode; adapter->flags |= IXGBE_FLAG_DCB_ENABLED; adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; - if (adapter->hw.mac.type == ixgbe_mac_82598EB) { - adapter->last_lfc_mode = adapter->hw.fc.requested_mode; + if (adapter->hw.mac.type == ixgbe_mac_82598EB) adapter->hw.fc.requested_mode = ixgbe_fc_none; - } } else { netdev_reset_tc(dev); - if (adapter->hw.mac.type == ixgbe_mac_82598EB) - adapter->hw.fc.requested_mode = adapter->last_lfc_mode; + adapter->hw.fc.requested_mode = adapter->last_lfc_mode; adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; @@ -7253,10 +7135,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); -#ifdef CONFIG_IXGBE_PTP - ixgbe_ptp_init(adapter); -#endif /* CONFIG_IXGBE_PTP*/ - /* save off EEPROM version number */ hw->eeprom.ops.read(hw, 0x2e, &adapter->eeprom_verh); hw->eeprom.ops.read(hw, 0x2d, &adapter->eeprom_verl); @@ -7344,10 +7222,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, e_dev_info("%s\n", ixgbe_default_device_descr); cards_found++; -#ifdef CONFIG_IXGBE_HWMON if (ixgbe_sysfs_init(adapter)) e_err(probe, "failed to allocate sysfs resources\n"); -#endif /* CONFIG_IXGBE_HWMON */ return 0; @@ -7387,10 +7263,6 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) set_bit(__IXGBE_DOWN, &adapter->state); cancel_work_sync(&adapter->service_task); -#ifdef CONFIG_IXGBE_PTP - ixgbe_ptp_stop(adapter); -#endif - #ifdef CONFIG_IXGBE_DCA if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED; @@ -7399,9 +7271,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) } #endif -#ifdef CONFIG_IXGBE_HWMON ixgbe_sysfs_exit(adapter); -#endif /* CONFIG_IXGBE_HWMON */ #ifdef IXGBE_FCOE if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c deleted file mode 100644 index ddc6a4d19302..000000000000 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ /dev/null @@ -1,900 +0,0 @@ -/******************************************************************************* - - Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2012 Intel Corporation. - - This program is free software; you can redistribute it and/or modify it - under the terms and conditions of the GNU General Public License, - version 2, as published by the Free Software Foundation. - - This program is distributed in the hope it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - - The full GNU General Public License is included in this distribution in - the file called "COPYING". - - Contact Information: - e1000-devel Mailing List - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -*******************************************************************************/ -#include "ixgbe.h" -#include - -/* - * The 82599 and the X540 do not have true 64bit nanosecond scale - * counter registers. Instead, SYSTIME is defined by a fixed point - * system which allows the user to define the scale counter increment - * value at every level change of the oscillator driving the SYSTIME - * value. For both devices the TIMINCA:IV field defines this - * increment. On the X540 device, 31 bits are provided. However on the - * 82599 only provides 24 bits. The time unit is determined by the - * clock frequency of the oscillator in combination with the TIMINCA - * register. When these devices link at 10Gb the oscillator has a - * period of 6.4ns. In order to convert the scale counter into - * nanoseconds the cyclecounter and timecounter structures are - * used. The SYSTIME registers need to be converted to ns values by use - * of only a right shift (division by power of 2). The following math - * determines the largest incvalue that will fit into the available - * bits in the TIMINCA register. - * - * PeriodWidth: Number of bits to store the clock period - * MaxWidth: The maximum width value of the TIMINCA register - * Period: The clock period for the oscillator - * round(): discard the fractional portion of the calculation - * - * Period * [ 2 ^ ( MaxWidth - PeriodWidth ) ] - * - * For the X540, MaxWidth is 31 bits, and the base period is 6.4 ns - * For the 82599, MaxWidth is 24 bits, and the base period is 6.4 ns - * - * The period also changes based on the link speed: - * At 10Gb link or no link, the period remains the same. - * At 1Gb link, the period is multiplied by 10. (64ns) - * At 100Mb link, the period is multiplied by 100. (640ns) - * - * The calculated value allows us to right shift the SYSTIME register - * value in order to quickly convert it into a nanosecond clock, - * while allowing for the maximum possible adjustment value. - * - * These diagrams are only for the 10Gb link period - * - * SYSTIMEH SYSTIMEL - * +--------------+ +--------------+ - * X540 | 32 | | 1 | 3 | 28 | - * *--------------+ +--------------+ - * \________ 36 bits ______/ fract - * - * +--------------+ +--------------+ - * 82599 | 32 | | 8 | 3 | 21 | - * *--------------+ +--------------+ - * \________ 43 bits ______/ fract - * - * The 36 bit X540 SYSTIME overflows every - * 2^36 * 10^-9 / 60 = 1.14 minutes or 69 seconds - * - * The 43 bit 82599 SYSTIME overflows every - * 2^43 * 10^-9 / 3600 = 2.4 hours - */ -#define IXGBE_INCVAL_10GB 0x66666666 -#define IXGBE_INCVAL_1GB 0x40000000 -#define IXGBE_INCVAL_100 0x50000000 - -#define IXGBE_INCVAL_SHIFT_10GB 28 -#define IXGBE_INCVAL_SHIFT_1GB 24 -#define IXGBE_INCVAL_SHIFT_100 21 - -#define IXGBE_INCVAL_SHIFT_82599 7 -#define IXGBE_INCPER_SHIFT_82599 24 -#define IXGBE_MAX_TIMEADJ_VALUE 0x7FFFFFFFFFFFFFFFULL - -#define IXGBE_OVERFLOW_PERIOD (HZ * 30) - -#ifndef NSECS_PER_SEC -#define NSECS_PER_SEC 1000000000ULL -#endif - -/** - * ixgbe_ptp_read - read raw cycle counter (to be used by time counter) - * @cc - the cyclecounter structure - * - * this function reads the cyclecounter registers and is called by the - * cyclecounter structure used to construct a ns counter from the - * arbitrary fixed point registers - */ -static cycle_t ixgbe_ptp_read(const struct cyclecounter *cc) -{ - struct ixgbe_adapter *adapter = - container_of(cc, struct ixgbe_adapter, cc); - struct ixgbe_hw *hw = &adapter->hw; - u64 stamp = 0; - - stamp |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIML); - stamp |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32; - - return stamp; -} - -/** - * ixgbe_ptp_adjfreq - * @ptp - the ptp clock structure - * @ppb - parts per billion adjustment from base - * - * adjust the frequency of the ptp cycle counter by the - * indicated ppb from the base frequency. - */ -static int ixgbe_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) -{ - struct ixgbe_adapter *adapter = - container_of(ptp, struct ixgbe_adapter, ptp_caps); - struct ixgbe_hw *hw = &adapter->hw; - u64 freq; - u32 diff, incval; - int neg_adj = 0; - - if (ppb < 0) { - neg_adj = 1; - ppb = -ppb; - } - - smp_mb(); - incval = ACCESS_ONCE(adapter->base_incval); - - freq = incval; - freq *= ppb; - diff = div_u64(freq, 1000000000ULL); - - incval = neg_adj ? (incval - diff) : (incval + diff); - - switch (hw->mac.type) { - case ixgbe_mac_X540: - IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, incval); - break; - case ixgbe_mac_82599EB: - IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, - (1 << IXGBE_INCPER_SHIFT_82599) | - incval); - break; - default: - break; - } - - return 0; -} - -/** - * ixgbe_ptp_adjtime - * @ptp - the ptp clock structure - * @delta - offset to adjust the cycle counter by - * - * adjust the timer by resetting the timecounter structure. - */ -static int ixgbe_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) -{ - struct ixgbe_adapter *adapter = - container_of(ptp, struct ixgbe_adapter, ptp_caps); - unsigned long flags; - u64 now; - - spin_lock_irqsave(&adapter->tmreg_lock, flags); - - now = timecounter_read(&adapter->tc); - now += delta; - - /* reset the timecounter */ - timecounter_init(&adapter->tc, - &adapter->cc, - now); - - spin_unlock_irqrestore(&adapter->tmreg_lock, flags); - return 0; -} - -/** - * ixgbe_ptp_gettime - * @ptp - the ptp clock structure - * @ts - timespec structure to hold the current time value - * - * read the timecounter and return the correct value on ns, - * after converting it into a struct timespec. - */ -static int ixgbe_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts) -{ - struct ixgbe_adapter *adapter = - container_of(ptp, struct ixgbe_adapter, ptp_caps); - u64 ns; - u32 remainder; - unsigned long flags; - - spin_lock_irqsave(&adapter->tmreg_lock, flags); - ns = timecounter_read(&adapter->tc); - spin_unlock_irqrestore(&adapter->tmreg_lock, flags); - - ts->tv_sec = div_u64_rem(ns, 1000000000ULL, &remainder); - ts->tv_nsec = remainder; - - return 0; -} - -/** - * ixgbe_ptp_settime - * @ptp - the ptp clock structure - * @ts - the timespec containing the new time for the cycle counter - * - * reset the timecounter to use a new base value instead of the kernel - * wall timer value. - */ -static int ixgbe_ptp_settime(struct ptp_clock_info *ptp, - const struct timespec *ts) -{ - struct ixgbe_adapter *adapter = - container_of(ptp, struct ixgbe_adapter, ptp_caps); - u64 ns; - unsigned long flags; - - ns = ts->tv_sec * 1000000000ULL; - ns += ts->tv_nsec; - - /* reset the timecounter */ - spin_lock_irqsave(&adapter->tmreg_lock, flags); - timecounter_init(&adapter->tc, &adapter->cc, ns); - spin_unlock_irqrestore(&adapter->tmreg_lock, flags); - - return 0; -} - -/** - * ixgbe_ptp_enable - * @ptp - the ptp clock structure - * @rq - the requested feature to change - * @on - whether to enable or disable the feature - * - * enable (or disable) ancillary features of the phc subsystem. - * our driver only supports the PPS feature on the X540 - */ -static int ixgbe_ptp_enable(struct ptp_clock_info *ptp, - struct ptp_clock_request *rq, int on) -{ - struct ixgbe_adapter *adapter = - container_of(ptp, struct ixgbe_adapter, ptp_caps); - - /** - * When PPS is enabled, unmask the interrupt for the ClockOut - * feature, so that the interrupt handler can send the PPS - * event when the clock SDP triggers. Clear mask when PPS is - * disabled - */ - if (rq->type == PTP_CLK_REQ_PPS) { - switch (adapter->hw.mac.type) { - case ixgbe_mac_X540: - if (on) - adapter->flags2 |= IXGBE_FLAG2_PTP_PPS_ENABLED; - else - adapter->flags2 &= - ~IXGBE_FLAG2_PTP_PPS_ENABLED; - return 0; - default: - break; - } - } - - return -ENOTSUPP; -} - -/** - * ixgbe_ptp_check_pps_event - * @adapter - the private adapter structure - * @eicr - the interrupt cause register value - * - * This function is called by the interrupt routine when checking for - * interrupts. It will check and handle a pps event. - */ -void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr) -{ - struct ixgbe_hw *hw = &adapter->hw; - struct ptp_clock_event event; - - event.type = PTP_CLOCK_PPS; - - /* Make sure ptp clock is valid, and PPS event enabled */ - if (!adapter->ptp_clock || - !(adapter->flags2 & IXGBE_FLAG2_PTP_PPS_ENABLED)) - return; - - switch (hw->mac.type) { - case ixgbe_mac_X540: - if (eicr & IXGBE_EICR_TIMESYNC) - ptp_clock_event(adapter->ptp_clock, &event); - break; - default: - break; - } -} - -/** - * ixgbe_ptp_enable_sdp - * @hw - the hardware private structure - * @shift - the clock shift for calculating nanoseconds - * - * this function enables the clock out feature on the sdp0 for the - * X540 device. It will create a 1second periodic output that can be - * used as the PPS (via an interrupt). - * - * It calculates when the systime will be on an exact second, and then - * aligns the start of the PPS signal to that value. The shift is - * necessary because it can change based on the link speed. - */ -static void ixgbe_ptp_enable_sdp(struct ixgbe_hw *hw, int shift) -{ - u32 esdp, tsauxc, clktiml, clktimh, trgttiml, trgttimh; - u64 clock_edge = 0; - u32 rem; - - switch (hw->mac.type) { - case ixgbe_mac_X540: - esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); - - /* - * enable the SDP0 pin as output, and connected to the native - * function for Timesync (ClockOut) - */ - esdp |= (IXGBE_ESDP_SDP0_DIR | - IXGBE_ESDP_SDP0_NATIVE); - - /* - * enable the Clock Out feature on SDP0, and allow interrupts - * to occur when the pin changes - */ - tsauxc = (IXGBE_TSAUXC_EN_CLK | - IXGBE_TSAUXC_SYNCLK | - IXGBE_TSAUXC_SDP0_INT); - - /* clock period (or pulse length) */ - clktiml = (u32)(NSECS_PER_SEC << shift); - clktimh = (u32)((NSECS_PER_SEC << shift) >> 32); - - clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIML); - clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32; - - /* - * account for the fact that we can't do u64 division - * with remainder, by converting the clock values into - * nanoseconds first - */ - clock_edge >>= shift; - div_u64_rem(clock_edge, NSECS_PER_SEC, &rem); - clock_edge += (NSECS_PER_SEC - rem); - clock_edge <<= shift; - - /* specify the initial clock start time */ - trgttiml = (u32)clock_edge; - trgttimh = (u32)(clock_edge >> 32); - - IXGBE_WRITE_REG(hw, IXGBE_CLKTIML, clktiml); - IXGBE_WRITE_REG(hw, IXGBE_CLKTIMH, clktimh); - IXGBE_WRITE_REG(hw, IXGBE_TRGTTIML0, trgttiml); - IXGBE_WRITE_REG(hw, IXGBE_TRGTTIMH0, trgttimh); - - IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); - IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, tsauxc); - - IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EICR_TIMESYNC); - break; - default: - break; - } -} - -/** - * ixgbe_ptp_disable_sdp - * @hw - the private hardware structure - * - * this function disables the auxiliary SDP clock out feature - */ -static void ixgbe_ptp_disable_sdp(struct ixgbe_hw *hw) -{ - IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EICR_TIMESYNC); - IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0); -} - -/** - * ixgbe_ptp_overflow_check - delayed work to detect SYSTIME overflow - * @work: structure containing information about this work task - * - * this work function is scheduled to continue reading the timecounter - * in order to prevent missing when the system time registers wrap - * around. This needs to be run approximately twice a minute when no - * PTP activity is occurring. - */ -void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter) -{ - unsigned long elapsed_jiffies = adapter->last_overflow_check - jiffies; - struct timespec ts; - - if ((adapter->flags2 & IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED) && - (elapsed_jiffies >= IXGBE_OVERFLOW_PERIOD)) { - ixgbe_ptp_gettime(&adapter->ptp_caps, &ts); - adapter->last_overflow_check = jiffies; - } -} - -/** - * ixgbe_ptp_tx_hwtstamp - utility function which checks for TX time stamp - * @q_vector: structure containing interrupt and ring information - * @skb: particular skb to send timestamp with - * - * if the timestamp is valid, we convert it into the timecounter ns - * value, then store that result into the shhwtstamps structure which - * is passed up the network stack - */ -void ixgbe_ptp_tx_hwtstamp(struct ixgbe_q_vector *q_vector, - struct sk_buff *skb) -{ - struct ixgbe_adapter *adapter; - struct ixgbe_hw *hw; - struct skb_shared_hwtstamps shhwtstamps; - u64 regval = 0, ns; - u32 tsynctxctl; - unsigned long flags; - - /* we cannot process timestamps on a ring without a q_vector */ - if (!q_vector || !q_vector->adapter) - return; - - adapter = q_vector->adapter; - hw = &adapter->hw; - - tsynctxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL); - regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPL); - regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPH) << 32; - - /* - * if TX timestamp is not valid, exit after clearing the - * timestamp registers - */ - if (!(tsynctxctl & IXGBE_TSYNCTXCTL_VALID)) - return; - - spin_lock_irqsave(&adapter->tmreg_lock, flags); - ns = timecounter_cyc2time(&adapter->tc, regval); - spin_unlock_irqrestore(&adapter->tmreg_lock, flags); - - memset(&shhwtstamps, 0, sizeof(shhwtstamps)); - shhwtstamps.hwtstamp = ns_to_ktime(ns); - skb_tstamp_tx(skb, &shhwtstamps); -} - -/** - * ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp - * @q_vector: structure containing interrupt and ring information - * @skb: particular skb to send timestamp with - * - * if the timestamp is valid, we convert it into the timecounter ns - * value, then store that result into the shhwtstamps structure which - * is passed up the network stack - */ -void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, - struct sk_buff *skb) -{ - struct ixgbe_adapter *adapter; - struct ixgbe_hw *hw; - struct skb_shared_hwtstamps *shhwtstamps; - u64 regval = 0, ns; - u32 tsyncrxctl; - unsigned long flags; - - /* we cannot process timestamps on a ring without a q_vector */ - if (!q_vector || !q_vector->adapter) - return; - - adapter = q_vector->adapter; - hw = &adapter->hw; - - tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); - regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL); - regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32; - - /* - * If this bit is set, then the RX registers contain the time stamp. No - * other packet will be time stamped until we read these registers, so - * read the registers to make them available again. Because only one - * packet can be time stamped at a time, we know that the register - * values must belong to this one here and therefore we don't need to - * compare any of the additional attributes stored for it. - * - * If nothing went wrong, then it should have a skb_shared_tx that we - * can turn into a skb_shared_hwtstamps. - */ - if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID)) - return; - - spin_lock_irqsave(&adapter->tmreg_lock, flags); - ns = timecounter_cyc2time(&adapter->tc, regval); - spin_unlock_irqrestore(&adapter->tmreg_lock, flags); - - shhwtstamps = skb_hwtstamps(skb); - shhwtstamps->hwtstamp = ns_to_ktime(ns); -} - -/** - * ixgbe_ptp_hwtstamp_ioctl - control hardware time stamping - * @adapter: pointer to adapter struct - * @ifreq: ioctl data - * @cmd: particular ioctl requested - * - * Outgoing time stamping can be enabled and disabled. Play nice and - * disable it when requested, although it shouldn't case any overhead - * when no packet needs it. At most one packet in the queue may be - * marked for time stamping, otherwise it would be impossible to tell - * for sure to which packet the hardware time stamp belongs. - * - * Incoming time stamping has to be configured via the hardware - * filters. Not all combinations are supported, in particular event - * type has to be specified. Matching the kind of event packet is - * not supported, with the exception of "all V2 events regardless of - * level 2 or 4". - */ -int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, - struct ifreq *ifr, int cmd) -{ - struct ixgbe_hw *hw = &adapter->hw; - struct hwtstamp_config config; - u32 tsync_tx_ctl = IXGBE_TSYNCTXCTL_ENABLED; - u32 tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED; - u32 tsync_rx_mtrl = 0; - bool is_l4 = false; - bool is_l2 = false; - u32 regval; - - if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) - return -EFAULT; - - /* reserved for future extensions */ - if (config.flags) - return -EINVAL; - - switch (config.tx_type) { - case HWTSTAMP_TX_OFF: - tsync_tx_ctl = 0; - case HWTSTAMP_TX_ON: - break; - default: - return -ERANGE; - } - - switch (config.rx_filter) { - case HWTSTAMP_FILTER_NONE: - tsync_rx_ctl = 0; - break; - case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: - tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; - tsync_rx_mtrl = IXGBE_RXMTRL_V1_SYNC_MSG; - is_l4 = true; - break; - case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: - tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; - tsync_rx_mtrl = IXGBE_RXMTRL_V1_DELAY_REQ_MSG; - is_l4 = true; - break; - case HWTSTAMP_FILTER_PTP_V2_SYNC: - case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: - case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: - tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2; - tsync_rx_mtrl = IXGBE_RXMTRL_V2_SYNC_MSG; - is_l2 = true; - is_l4 = true; - config.rx_filter = HWTSTAMP_FILTER_SOME; - break; - case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: - case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: - case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: - tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2; - tsync_rx_mtrl = IXGBE_RXMTRL_V2_DELAY_REQ_MSG; - is_l2 = true; - is_l4 = true; - config.rx_filter = HWTSTAMP_FILTER_SOME; - break; - case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: - case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: - case HWTSTAMP_FILTER_PTP_V2_EVENT: - tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2; - config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; - is_l2 = true; - is_l4 = true; - break; - case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: - case HWTSTAMP_FILTER_ALL: - default: - /* - * register RXMTRL must be set, therefore it is not - * possible to time stamp both V1 Sync and Delay_Req messages - * and hardware does not support timestamping all packets - * => return error - */ - return -ERANGE; - } - - if (hw->mac.type == ixgbe_mac_82598EB) { - if (tsync_rx_ctl | tsync_tx_ctl) - return -ERANGE; - return 0; - } - - /* define ethertype filter for timestamped packets */ - if (is_l2) - IXGBE_WRITE_REG(hw, IXGBE_ETQF(3), - (IXGBE_ETQF_FILTER_EN | /* enable filter */ - IXGBE_ETQF_1588 | /* enable timestamping */ - ETH_P_1588)); /* 1588 eth protocol type */ - else - IXGBE_WRITE_REG(hw, IXGBE_ETQF(3), 0); - -#define PTP_PORT 319 - /* L4 Queue Filter[3]: filter by destination port and protocol */ - if (is_l4) { - u32 ftqf = (IXGBE_FTQF_PROTOCOL_UDP /* UDP */ - | IXGBE_FTQF_POOL_MASK_EN /* Pool not compared */ - | IXGBE_FTQF_QUEUE_ENABLE); - - ftqf |= ((IXGBE_FTQF_PROTOCOL_COMP_MASK /* protocol check */ - & IXGBE_FTQF_DEST_PORT_MASK /* dest check */ - & IXGBE_FTQF_SOURCE_PORT_MASK) /* source check */ - << IXGBE_FTQF_5TUPLE_MASK_SHIFT); - - IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(3), - (3 << IXGBE_IMIR_RX_QUEUE_SHIFT_82599 | - IXGBE_IMIR_SIZE_BP_82599)); - - /* enable port check */ - IXGBE_WRITE_REG(hw, IXGBE_SDPQF(3), - (htons(PTP_PORT) | - htons(PTP_PORT) << 16)); - - IXGBE_WRITE_REG(hw, IXGBE_FTQF(3), ftqf); - - tsync_rx_mtrl |= PTP_PORT << 16; - } else { - IXGBE_WRITE_REG(hw, IXGBE_FTQF(3), 0); - } - - /* enable/disable TX */ - regval = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL); - regval &= ~IXGBE_TSYNCTXCTL_ENABLED; - regval |= tsync_tx_ctl; - IXGBE_WRITE_REG(hw, IXGBE_TSYNCTXCTL, regval); - - /* enable/disable RX */ - regval = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); - regval &= ~(IXGBE_TSYNCRXCTL_ENABLED | IXGBE_TSYNCRXCTL_TYPE_MASK); - regval |= tsync_rx_ctl; - IXGBE_WRITE_REG(hw, IXGBE_TSYNCRXCTL, regval); - - /* define which PTP packets are time stamped */ - IXGBE_WRITE_REG(hw, IXGBE_RXMTRL, tsync_rx_mtrl); - - IXGBE_WRITE_FLUSH(hw); - - /* clear TX/RX time stamp registers, just to be sure */ - regval = IXGBE_READ_REG(hw, IXGBE_TXSTMPH); - regval = IXGBE_READ_REG(hw, IXGBE_RXSTMPH); - - return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? - -EFAULT : 0; -} - -/** - * ixgbe_ptp_start_cyclecounter - create the cycle counter from hw - * @adapter - pointer to the adapter structure - * - * this function initializes the timecounter and cyclecounter - * structures for use in generated a ns counter from the arbitrary - * fixed point cycles registers in the hardware. - * - * A change in link speed impacts the frequency of the DMA clock on - * the device, which is used to generate the cycle counter - * registers. Therefor this function is called whenever the link speed - * changes. - * - * This function also turns on the SDP pin for clock out feature (X540 - * only), because this is where the shift is first calculated. - */ -void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - u32 incval = 0; - u32 shift = 0; - u32 cycle_speed; - unsigned long flags; - - /** - * Determine what speed we need to set the cyclecounter - * for. It should be different for 100Mb, 1Gb, and 10Gb. Treat - * unknown speeds as 10Gb. (Hence why we can't just copy the - * link_speed. - */ - switch (adapter->link_speed) { - case IXGBE_LINK_SPEED_100_FULL: - case IXGBE_LINK_SPEED_1GB_FULL: - case IXGBE_LINK_SPEED_10GB_FULL: - cycle_speed = adapter->link_speed; - break; - default: - /* cycle speed should be 10Gb when there is no link */ - cycle_speed = IXGBE_LINK_SPEED_10GB_FULL; - break; - } - - /* Bail if the cycle speed didn't change */ - if (adapter->cycle_speed == cycle_speed) - return; - - /* disable the SDP clock out */ - ixgbe_ptp_disable_sdp(hw); - - /** - * Scale the NIC cycle counter by a large factor so that - * relatively small corrections to the frequency can be added - * or subtracted. The drawbacks of a large factor include - * (a) the clock register overflows more quickly, (b) the cycle - * counter structure must be able to convert the systime value - * to nanoseconds using only a multiplier and a right-shift, - * and (c) the value must fit within the timinca register space - * => math based on internal DMA clock rate and available bits - */ - switch (cycle_speed) { - case IXGBE_LINK_SPEED_100_FULL: - incval = IXGBE_INCVAL_100; - shift = IXGBE_INCVAL_SHIFT_100; - break; - case IXGBE_LINK_SPEED_1GB_FULL: - incval = IXGBE_INCVAL_1GB; - shift = IXGBE_INCVAL_SHIFT_1GB; - break; - case IXGBE_LINK_SPEED_10GB_FULL: - incval = IXGBE_INCVAL_10GB; - shift = IXGBE_INCVAL_SHIFT_10GB; - break; - } - - /** - * Modify the calculated values to fit within the correct - * number of bits specified by the hardware. The 82599 doesn't - * have the same space as the X540, so bitshift the calculated - * values to fit. - */ - switch (hw->mac.type) { - case ixgbe_mac_X540: - IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, incval); - break; - case ixgbe_mac_82599EB: - incval >>= IXGBE_INCVAL_SHIFT_82599; - shift -= IXGBE_INCVAL_SHIFT_82599; - IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, - (1 << IXGBE_INCPER_SHIFT_82599) | - incval); - break; - default: - /* other devices aren't supported */ - return; - } - - /* reset the system time registers */ - IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0x00000000); - IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0x00000000); - IXGBE_WRITE_FLUSH(hw); - - /* now that the shift has been calculated and the systime - * registers reset, (re-)enable the Clock out feature*/ - ixgbe_ptp_enable_sdp(hw, shift); - - /* store the new cycle speed */ - adapter->cycle_speed = cycle_speed; - - ACCESS_ONCE(adapter->base_incval) = incval; - smp_mb(); - - /* grab the ptp lock */ - spin_lock_irqsave(&adapter->tmreg_lock, flags); - - memset(&adapter->cc, 0, sizeof(adapter->cc)); - adapter->cc.read = ixgbe_ptp_read; - adapter->cc.mask = CLOCKSOURCE_MASK(64); - adapter->cc.shift = shift; - adapter->cc.mult = 1; - - /* reset the ns time counter */ - timecounter_init(&adapter->tc, &adapter->cc, - ktime_to_ns(ktime_get_real())); - - spin_unlock_irqrestore(&adapter->tmreg_lock, flags); -} - -/** - * ixgbe_ptp_init - * @adapter - the ixgbe private adapter structure - * - * This function performs the required steps for enabling ptp - * support. If ptp support has already been loaded it simply calls the - * cyclecounter init routine and exits. - */ -void ixgbe_ptp_init(struct ixgbe_adapter *adapter) -{ - struct net_device *netdev = adapter->netdev; - - switch (adapter->hw.mac.type) { - case ixgbe_mac_X540: - snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr); - adapter->ptp_caps.owner = THIS_MODULE; - adapter->ptp_caps.max_adj = 250000000; - adapter->ptp_caps.n_alarm = 0; - adapter->ptp_caps.n_ext_ts = 0; - adapter->ptp_caps.n_per_out = 0; - adapter->ptp_caps.pps = 1; - adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq; - adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime; - adapter->ptp_caps.gettime = ixgbe_ptp_gettime; - adapter->ptp_caps.settime = ixgbe_ptp_settime; - adapter->ptp_caps.enable = ixgbe_ptp_enable; - break; - case ixgbe_mac_82599EB: - snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr); - adapter->ptp_caps.owner = THIS_MODULE; - adapter->ptp_caps.max_adj = 250000000; - adapter->ptp_caps.n_alarm = 0; - adapter->ptp_caps.n_ext_ts = 0; - adapter->ptp_caps.n_per_out = 0; - adapter->ptp_caps.pps = 0; - adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq; - adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime; - adapter->ptp_caps.gettime = ixgbe_ptp_gettime; - adapter->ptp_caps.settime = ixgbe_ptp_settime; - adapter->ptp_caps.enable = ixgbe_ptp_enable; - break; - default: - adapter->ptp_clock = NULL; - return; - } - - spin_lock_init(&adapter->tmreg_lock); - - ixgbe_ptp_start_cyclecounter(adapter); - - /* (Re)start the overflow check */ - adapter->flags2 |= IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED; - - adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps); - if (IS_ERR(adapter->ptp_clock)) { - adapter->ptp_clock = NULL; - e_dev_err("ptp_clock_register failed\n"); - } else - e_dev_info("registered PHC device on %s\n", netdev->name); - - return; -} - -/** - * ixgbe_ptp_stop - disable ptp device and stop the overflow check - * @adapter: pointer to adapter struct - * - * this function stops the ptp support, and cancels the delayed work. - */ -void ixgbe_ptp_stop(struct ixgbe_adapter *adapter) -{ - ixgbe_ptp_disable_sdp(&adapter->hw); - - /* stop the overflow check task */ - adapter->flags2 &= ~IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED; - - if (adapter->ptp_clock) { - ptp_clock_unregister(adapter->ptp_clock); - adapter->ptp_clock = NULL; - e_dev_info("removed PHC on %s\n", - adapter->netdev->name); - } -} diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index 2d971d18696e..39856371acb1 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c @@ -544,18 +544,13 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf); - if (retval) { + if (retval) pr_err("Error receiving message from VF\n"); - return retval; - } /* this is a message we already processed, do nothing */ if (msgbuf[0] & (IXGBE_VT_MSGTYPE_ACK | IXGBE_VT_MSGTYPE_NACK)) return retval; - /* flush the ack before we write any messages back */ - IXGBE_WRITE_FLUSH(hw); - /* * until the vf completes a virtual function reset it should not be * allowed to start any configuration. @@ -640,14 +635,14 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) } break; case IXGBE_VF_SET_MACVLAN: - index = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> - IXGBE_VT_MSGINFO_SHIFT; - if (adapter->vfinfo[vf].pf_set_mac && index > 0) { + if (adapter->vfinfo[vf].pf_set_mac) { e_warn(drv, "VF %d requested MACVLAN filter but is " "administratively denied\n", vf); retval = -1; break; } + index = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> + IXGBE_VT_MSGINFO_SHIFT; /* * If the VF is allowed to set MAC filters then turn off * anti-spoofing to avoid false positives. An index diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c index 1d80b1cefa6a..f81c166dc5a8 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c @@ -37,7 +37,12 @@ #include #include +/* + * This file provides a sysfs interface to export information from the + * driver. The information presented is READ-ONLY. + */ #ifdef CONFIG_IXGBE_HWMON + /* hwmon callback functions */ static ssize_t ixgbe_hwmon_show_location(struct device *dev, struct device_attribute *attr, @@ -157,13 +162,17 @@ static int ixgbe_add_hwmon_attr(struct ixgbe_adapter *adapter, return rc; } +#endif /* CONFIG_IXGBE_HWMON */ static void ixgbe_sysfs_del_adapter(struct ixgbe_adapter *adapter) { +#ifdef CONFIG_IXGBE_HWMON int i; +#endif /* CONFIG_IXGBE_HWMON */ if (adapter == NULL) return; +#ifdef CONFIG_IXGBE_HWMON for (i = 0; i < adapter->ixgbe_hwmon_buff.n_hwmon; i++) { device_remove_file(&adapter->pdev->dev, @@ -174,6 +183,12 @@ static void ixgbe_sysfs_del_adapter(struct ixgbe_adapter *adapter) if (adapter->ixgbe_hwmon_buff.device) hwmon_device_unregister(adapter->ixgbe_hwmon_buff.device); +#endif /* CONFIG_IXGBE_HWMON */ + + if (adapter->info_kobj != NULL) { + kobject_put(adapter->info_kobj); + adapter->info_kobj = NULL; + } } /* called from ixgbe_main.c */ @@ -185,19 +200,32 @@ void ixgbe_sysfs_exit(struct ixgbe_adapter *adapter) /* called from ixgbe_main.c */ int ixgbe_sysfs_init(struct ixgbe_adapter *adapter) { +#ifdef CONFIG_IXGBE_HWMON struct hwmon_buff *ixgbe_hwmon = &adapter->ixgbe_hwmon_buff; unsigned int i; int n_attrs; +#endif /* CONFIG_IXGBE_HWMON */ + struct net_device *netdev = adapter->netdev; int rc = 0; + /* create info kobj and attribute listings in kobj */ + adapter->info_kobj = kobject_create_and_add("info", &netdev->dev.kobj); + if (adapter->info_kobj == NULL) { + rc = -ENOMEM; + goto err; + } + +#ifdef CONFIG_IXGBE_HWMON /* If this method isn't defined we don't support thermals */ if (adapter->hw.mac.ops.init_thermal_sensor_thresh == NULL) { - goto exit; + rc = -EPERM; + goto err; } /* Don't create thermal hwmon interface if no sensors present */ - if (adapter->hw.mac.ops.init_thermal_sensor_thresh(&adapter->hw)) - goto exit; + rc = adapter->hw.mac.ops.init_thermal_sensor_thresh(&adapter->hw); + if (rc) + goto err; /* * Allocation space for max attributs @@ -233,6 +261,7 @@ int ixgbe_sysfs_init(struct ixgbe_adapter *adapter) if (rc) goto err; } +#endif /* CONFIG_IXGBE_HWMON */ goto exit; @@ -241,5 +270,4 @@ int ixgbe_sysfs_init(struct ixgbe_adapter *adapter) exit: return rc; } -#endif /* CONFIG_IXGBE_HWMON */ diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h index 204848d2448c..5e64c77255e9 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h @@ -824,8 +824,6 @@ struct ixgbe_thermal_sensor_data { #define IXGBE_TRGTTIMH0 0x08C28 /* Target Time Register 0 High - RW */ #define IXGBE_TRGTTIML1 0x08C2C /* Target Time Register 1 Low - RW */ #define IXGBE_TRGTTIMH1 0x08C30 /* Target Time Register 1 High - RW */ -#define IXGBE_CLKTIML 0x08C34 /* Clock Out Time Register Low - RW */ -#define IXGBE_CLKTIMH 0x08C38 /* Clock Out Time Register High - RW */ #define IXGBE_FREQOUT0 0x08C34 /* Frequency Out 0 Control register - RW */ #define IXGBE_FREQOUT1 0x08C38 /* Frequency Out 1 Control register - RW */ #define IXGBE_AUXSTMPL0 0x08C3C /* Auxiliary Time Stamp 0 register Low - RO */ @@ -1311,7 +1309,6 @@ enum { #define IXGBE_EICR_LINKSEC 0x00200000 /* PN Threshold */ #define IXGBE_EICR_MNG 0x00400000 /* Manageability Event Interrupt */ #define IXGBE_EICR_TS 0x00800000 /* Thermal Sensor Event */ -#define IXGBE_EICR_TIMESYNC 0x01000000 /* Timesync Event */ #define IXGBE_EICR_GPI_SDP0 0x01000000 /* Gen Purpose Interrupt on SDP0 */ #define IXGBE_EICR_GPI_SDP1 0x02000000 /* Gen Purpose Interrupt on SDP1 */ #define IXGBE_EICR_GPI_SDP2 0x04000000 /* Gen Purpose Interrupt on SDP2 */ @@ -1329,7 +1326,6 @@ enum { #define IXGBE_EICS_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */ #define IXGBE_EICS_LSC IXGBE_EICR_LSC /* Link Status Change */ #define IXGBE_EICS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */ -#define IXGBE_EICS_TIMESYNC IXGBE_EICR_TIMESYNC /* Timesync Event */ #define IXGBE_EICS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */ #define IXGBE_EICS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */ #define IXGBE_EICS_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */ @@ -1348,7 +1344,6 @@ enum { #define IXGBE_EIMS_LSC IXGBE_EICR_LSC /* Link Status Change */ #define IXGBE_EIMS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */ #define IXGBE_EIMS_TS IXGBE_EICR_TS /* Thermel Sensor Event */ -#define IXGBE_EIMS_TIMESYNC IXGBE_EICR_TIMESYNC /* Timesync Event */ #define IXGBE_EIMS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */ #define IXGBE_EIMS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */ #define IXGBE_EIMS_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */ @@ -1366,7 +1361,6 @@ enum { #define IXGBE_EIMC_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */ #define IXGBE_EIMC_LSC IXGBE_EICR_LSC /* Link Status Change */ #define IXGBE_EIMC_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */ -#define IXGBE_EIMC_TIMESYNC IXGBE_EICR_TIMESYNC /* Timesync Event */ #define IXGBE_EIMC_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */ #define IXGBE_EIMC_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */ #define IXGBE_EIMC_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */ @@ -1507,10 +1501,8 @@ enum { #define IXGBE_ESDP_SDP4 0x00000010 /* SDP4 Data Value */ #define IXGBE_ESDP_SDP5 0x00000020 /* SDP5 Data Value */ #define IXGBE_ESDP_SDP6 0x00000040 /* SDP6 Data Value */ -#define IXGBE_ESDP_SDP0_DIR 0x00000100 /* SDP0 IO direction */ #define IXGBE_ESDP_SDP4_DIR 0x00000004 /* SDP4 IO direction */ #define IXGBE_ESDP_SDP5_DIR 0x00002000 /* SDP5 IO direction */ -#define IXGBE_ESDP_SDP0_NATIVE 0x00010000 /* SDP0 Native Function */ /* LEDCTL Bit Masks */ #define IXGBE_LED_IVRT_BASE 0x00000040 @@ -1887,40 +1879,6 @@ enum { #define IXGBE_RXDCTL_RLPML_EN 0x00008000 #define IXGBE_RXDCTL_VME 0x40000000 /* VLAN mode enable */ -#define IXGBE_TSAUXC_EN_CLK 0x00000004 -#define IXGBE_TSAUXC_SYNCLK 0x00000008 -#define IXGBE_TSAUXC_SDP0_INT 0x00000040 - -#define IXGBE_TSYNCTXCTL_VALID 0x00000001 /* Tx timestamp valid */ -#define IXGBE_TSYNCTXCTL_ENABLED 0x00000010 /* Tx timestamping enabled */ - -#define IXGBE_TSYNCRXCTL_VALID 0x00000001 /* Rx timestamp valid */ -#define IXGBE_TSYNCRXCTL_TYPE_MASK 0x0000000E /* Rx type mask */ -#define IXGBE_TSYNCRXCTL_TYPE_L2_V2 0x00 -#define IXGBE_TSYNCRXCTL_TYPE_L4_V1 0x02 -#define IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2 0x04 -#define IXGBE_TSYNCRXCTL_TYPE_EVENT_V2 0x0A -#define IXGBE_TSYNCRXCTL_ENABLED 0x00000010 /* Rx Timestamping enabled */ - -#define IXGBE_RXMTRL_V1_CTRLT_MASK 0x000000FF -#define IXGBE_RXMTRL_V1_SYNC_MSG 0x00 -#define IXGBE_RXMTRL_V1_DELAY_REQ_MSG 0x01 -#define IXGBE_RXMTRL_V1_FOLLOWUP_MSG 0x02 -#define IXGBE_RXMTRL_V1_DELAY_RESP_MSG 0x03 -#define IXGBE_RXMTRL_V1_MGMT_MSG 0x04 - -#define IXGBE_RXMTRL_V2_MSGID_MASK 0x0000FF00 -#define IXGBE_RXMTRL_V2_SYNC_MSG 0x0000 -#define IXGBE_RXMTRL_V2_DELAY_REQ_MSG 0x0100 -#define IXGBE_RXMTRL_V2_PDELAY_REQ_MSG 0x0200 -#define IXGBE_RXMTRL_V2_PDELAY_RESP_MSG 0x0300 -#define IXGBE_RXMTRL_V2_FOLLOWUP_MSG 0x0800 -#define IXGBE_RXMTRL_V2_DELAY_RESP_MSG 0x0900 -#define IXGBE_RXMTRL_V2_PDELAY_FOLLOWUP_MSG 0x0A00 -#define IXGBE_RXMTRL_V2_ANNOUNCE_MSG 0x0B00 -#define IXGBE_RXMTRL_V2_SIGNALING_MSG 0x0C00 -#define IXGBE_RXMTRL_V2_MGMT_MSG 0x0D00 - #define IXGBE_FCTRL_SBP 0x00000002 /* Store Bad Packet */ #define IXGBE_FCTRL_MPE 0x00000100 /* Multicast Promiscuous Ena*/ #define IXGBE_FCTRL_UPE 0x00000200 /* Unicast Promiscuous Ena */ @@ -2050,7 +2008,6 @@ enum { #define IXGBE_RXDADV_STAT_FCSTAT_NODDP 0x00000010 /* 01: Ctxt w/o DDP */ #define IXGBE_RXDADV_STAT_FCSTAT_FCPRSP 0x00000020 /* 10: Recv. FCP_RSP */ #define IXGBE_RXDADV_STAT_FCSTAT_DDP 0x00000030 /* 11: Ctxt w/ DDP */ -#define IXGBE_RXDADV_STAT_TS 0x00010000 /* IEEE 1588 Time Stamp */ /* PSRTYPE bit definitions */ #define IXGBE_PSRTYPE_TCPHDR 0x00000010 @@ -2328,7 +2285,6 @@ struct ixgbe_adv_tx_context_desc { /* Adv Transmit Descriptor Config Masks */ #define IXGBE_ADVTXD_DTALEN_MASK 0x0000FFFF /* Data buf length(bytes) */ #define IXGBE_ADVTXD_MAC_LINKSEC 0x00040000 /* Insert LinkSec */ -#define IXGBE_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE 1588 Time Stamp */ #define IXGBE_ADVTXD_IPSEC_SA_INDEX_MASK 0x000003FF /* IPSec SA index */ #define IXGBE_ADVTXD_IPSEC_ESP_LEN_MASK 0x000001FF /* IPSec ESP length */ #define IXGBE_ADVTXD_DTYP_MASK 0x00F00000 /* DTYP mask */ @@ -2617,6 +2573,9 @@ enum ixgbe_fc_mode { ixgbe_fc_rx_pause, ixgbe_fc_tx_pause, ixgbe_fc_full, +#ifdef CONFIG_DCB + ixgbe_fc_pfc, +#endif ixgbe_fc_default }; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/alloc.c b/trunk/drivers/net/ethernet/mellanox/mlx4/alloc.c index 06fef5b44f77..8be20e7ea3d1 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/alloc.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/alloc.c @@ -124,6 +124,9 @@ void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt) spin_lock(&bitmap->lock); bitmap_clear(bitmap->table, obj, cnt); + bitmap->last = min(bitmap->last, obj); + bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top) + & bitmap->mask; bitmap->avail += cnt; spin_unlock(&bitmap->lock); } diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/cmd.c b/trunk/drivers/net/ethernet/mellanox/mlx4/cmd.c index 1bcead1fa2f6..773c70ea3f62 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/cmd.c @@ -1254,6 +1254,7 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd, struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_slave_state *slave_state = priv->mfunc.master.slave_state; u32 reply; + u32 slave_status = 0; u8 is_going_down = 0; int i; @@ -1273,8 +1274,10 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd, } /*check if we are in the middle of FLR process, if so return "retry" status to the slave*/ - if (MLX4_COMM_CMD_FLR == slave_state[slave].last_cmd) + if (MLX4_COMM_CMD_FLR == slave_state[slave].last_cmd) { + slave_status = MLX4_DELAY_RESET_SLAVE; goto inform_slave_state; + } /* write the version in the event field */ reply |= mlx4_comm_get_version(); @@ -1554,7 +1557,7 @@ int mlx4_multi_func_init(struct mlx4_dev *dev) return 0; err_resource: - mlx4_free_resource_tracker(dev, RES_TR_FREE_ALL); + mlx4_free_resource_tracker(dev); err_thread: flush_workqueue(priv->mfunc.master.comm_wq); destroy_workqueue(priv->mfunc.master.comm_wq); diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/en_main.c b/trunk/drivers/net/ethernet/mellanox/mlx4/en_main.c index 988b2424e1c6..346fdb2e92a6 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/en_main.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/en_main.c @@ -101,8 +101,6 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev) int i; params->udp_rss = udp_rss; - params->num_tx_rings_p_up = min_t(int, num_online_cpus(), - MLX4_EN_MAX_TX_RING_P_UP); if (params->udp_rss && !(mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_UDP_RSS)) { mlx4_warn(mdev, "UDP RSS is not supported on this device.\n"); @@ -115,8 +113,8 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev) params->prof[i].tx_ppp = pfctx; params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE; params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE; - params->prof[i].tx_ring_num = params->num_tx_rings_p_up * - MLX4_EN_NUM_UP; + params->prof[i].tx_ring_num = MLX4_EN_NUM_TX_RINGS + + MLX4_EN_NUM_PPP_RINGS; params->prof[i].rss_rings = 0; } diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 926d8aac941c..eaa8fadf19c0 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -47,22 +47,9 @@ static int mlx4_en_setup_tc(struct net_device *dev, u8 up) { - struct mlx4_en_priv *priv = netdev_priv(dev); - int i; - unsigned int q, offset = 0; - - if (up && up != MLX4_EN_NUM_UP) + if (up != MLX4_EN_NUM_UP) return -EINVAL; - netdev_set_num_tc(dev, up); - - /* Partition Tx queues evenly amongst UP's */ - q = priv->tx_ring_num / up; - for (i = 0; i < up; i++) { - netdev_set_tc_queue(dev, i, q, offset); - offset += q; - } - return 0; } @@ -674,7 +661,7 @@ int mlx4_en_start_port(struct net_device *dev) /* Configure ring */ tx_ring = &priv->tx_ring[i]; err = mlx4_en_activate_tx_ring(priv, tx_ring, cq->mcq.cqn, - i / priv->mdev->profile.num_tx_rings_p_up); + max(0, i - MLX4_EN_NUM_TX_RINGS)); if (err) { en_err(priv, "Failed allocating Tx ring\n"); mlx4_en_deactivate_cq(priv, cq); @@ -999,9 +986,6 @@ void mlx4_en_destroy_netdev(struct net_device *dev) mlx4_en_free_resources(priv); - kfree(priv->tx_ring); - kfree(priv->tx_cq); - free_netdev(dev); } @@ -1107,18 +1091,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, priv->ctrl_flags = cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE | MLX4_WQE_CTRL_SOLICITED); priv->tx_ring_num = prof->tx_ring_num; - priv->tx_ring = kzalloc(sizeof(struct mlx4_en_tx_ring) * - priv->tx_ring_num, GFP_KERNEL); - if (!priv->tx_ring) { - err = -ENOMEM; - goto out; - } - priv->tx_cq = kzalloc(sizeof(struct mlx4_en_cq) * priv->tx_ring_num, - GFP_KERNEL); - if (!priv->tx_cq) { - err = -ENOMEM; - goto out; - } priv->rx_ring_num = prof->rx_ring_num; priv->mac_index = -1; priv->msg_enable = MLX4_EN_MSG_LEVEL; @@ -1166,6 +1138,15 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, netif_set_real_num_tx_queues(dev, priv->tx_ring_num); netif_set_real_num_rx_queues(dev, priv->rx_ring_num); + netdev_set_num_tc(dev, MLX4_EN_NUM_UP); + + /* First 9 rings are for UP 0 */ + netdev_set_tc_queue(dev, 0, MLX4_EN_NUM_TX_RINGS + 1, 0); + + /* Partition Tx queues evenly amongst UP's 1-7 */ + for (i = 1; i < MLX4_EN_NUM_UP; i++) + netdev_set_tc_queue(dev, i, 1, MLX4_EN_NUM_TX_RINGS + i); + SET_ETHTOOL_OPS(dev, &mlx4_en_ethtool_ops); /* Set defualt MAC */ diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/trunk/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 019d856b1334..9a38483feb92 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/en_tx.c @@ -525,17 +525,14 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *sk u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb) { - struct mlx4_en_priv *priv = netdev_priv(dev); - u16 rings_p_up = priv->mdev->profile.num_tx_rings_p_up; - u8 up = 0; - - if (dev->num_tc) - return skb_tx_hash(dev, skb); + u16 vlan_tag = 0; - if (vlan_tx_tag_present(skb)) - up = vlan_tx_tag_get(skb) >> VLAN_PRIO_SHIFT; + if (vlan_tx_tag_present(skb)) { + vlan_tag = vlan_tx_tag_get(skb); + return MLX4_EN_NUM_TX_RINGS + (vlan_tag >> 13); + } - return __skb_tx_hash(dev, skb, rings_p_up) + up * rings_p_up; + return skb_tx_hash(dev, skb); } static void mlx4_bf_copy(void __iomem *dst, unsigned long *src, unsigned bytecnt) diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/fw.c b/trunk/drivers/net/ethernet/mellanox/mlx4/fw.c index 68f5cd6cb3c7..2a02ba522e60 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -118,20 +118,6 @@ static void dump_dev_cap_flags(struct mlx4_dev *dev, u64 flags) mlx4_dbg(dev, " %s\n", fname[i]); } -static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags) -{ - static const char * const fname[] = { - [0] = "RSS support", - [1] = "RSS Toeplitz Hash Function support", - [2] = "RSS XOR Hash Function support" - }; - int i; - - for (i = 0; i < ARRAY_SIZE(fname); ++i) - if (fname[i] && (flags & (1LL << i))) - mlx4_dbg(dev, " %s\n", fname[i]); -} - int mlx4_MOD_STAT_CFG(struct mlx4_dev *dev, struct mlx4_mod_stat_cfg *cfg) { struct mlx4_cmd_mailbox *mailbox; @@ -360,7 +346,6 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) #define QUERY_DEV_CAP_MAX_REQ_QP_OFFSET 0x29 #define QUERY_DEV_CAP_MAX_RES_QP_OFFSET 0x2b #define QUERY_DEV_CAP_MAX_GSO_OFFSET 0x2d -#define QUERY_DEV_CAP_RSS_OFFSET 0x2e #define QUERY_DEV_CAP_MAX_RDMA_OFFSET 0x2f #define QUERY_DEV_CAP_RSZ_SRQ_OFFSET 0x33 #define QUERY_DEV_CAP_ACK_DELAY_OFFSET 0x35 @@ -405,7 +390,6 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) #define QUERY_DEV_CAP_RSVD_LKEY_OFFSET 0x98 #define QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET 0xa0 - dev_cap->flags2 = 0; mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); @@ -455,17 +439,6 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) else dev_cap->max_gso_sz = 1 << field; - MLX4_GET(field, outbox, QUERY_DEV_CAP_RSS_OFFSET); - if (field & 0x20) - dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_RSS_XOR; - if (field & 0x10) - dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_RSS_TOP; - field &= 0xf; - if (field) { - dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_RSS; - dev_cap->max_rss_tbl_sz = 1 << field; - } else - dev_cap->max_rss_tbl_sz = 0; MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_RDMA_OFFSET); dev_cap->max_rdma_global = 1 << (field & 0x3f); MLX4_GET(field, outbox, QUERY_DEV_CAP_ACK_DELAY_OFFSET); @@ -659,10 +632,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev_cap->max_rq_desc_sz, dev_cap->max_rq_sg); mlx4_dbg(dev, "Max GSO size: %d\n", dev_cap->max_gso_sz); mlx4_dbg(dev, "Max counters: %d\n", dev_cap->max_counters); - mlx4_dbg(dev, "Max RSS Table size: %d\n", dev_cap->max_rss_tbl_sz); dump_dev_cap_flags(dev, dev_cap->flags); - dump_dev_cap_flags2(dev, dev_cap->flags2); out: mlx4_free_cmd_mailbox(dev, mailbox); @@ -1193,8 +1164,9 @@ int mlx4_INIT_PORT_wrapper(struct mlx4_dev *dev, int slave, MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); if (err) return err; + priv->mfunc.master.slave_state[slave].init_port_mask |= + (1 << port); } - priv->mfunc.master.slave_state[slave].init_port_mask |= (1 << port); ++priv->mfunc.master.init_port_ref[port]; return 0; } diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/fw.h b/trunk/drivers/net/ethernet/mellanox/mlx4/fw.h index 64c0399e4b78..e1a5fa56bcbc 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/fw.h +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/fw.h @@ -79,7 +79,6 @@ struct mlx4_dev_cap { u64 trans_code[MLX4_MAX_PORTS + 1]; u16 stat_rate_support; u64 flags; - u64 flags2; int reserved_uars; int uar_size; int min_page_sz; @@ -111,7 +110,6 @@ struct mlx4_dev_cap { u32 reserved_lkey; u64 max_icm_sz; int max_gso_sz; - int max_rss_tbl_sz; u8 supported_port_types[MLX4_MAX_PORTS + 1]; u8 suggested_type[MLX4_MAX_PORTS + 1]; u8 default_sense[MLX4_MAX_PORTS + 1]; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/main.c b/trunk/drivers/net/ethernet/mellanox/mlx4/main.c index 2e024a68fa81..8bb05b46db86 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/main.c @@ -272,12 +272,10 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev->caps.max_msg_sz = dev_cap->max_msg_sz; dev->caps.page_size_cap = ~(u32) (dev_cap->min_page_sz - 1); dev->caps.flags = dev_cap->flags; - dev->caps.flags2 = dev_cap->flags2; dev->caps.bmme_flags = dev_cap->bmme_flags; dev->caps.reserved_lkey = dev_cap->reserved_lkey; dev->caps.stat_rate_support = dev_cap->stat_rate_support; dev->caps.max_gso_sz = dev_cap->max_gso_sz; - dev->caps.max_rss_tbl_sz = dev_cap->max_rss_tbl_sz; /* Sense port always allowed on supported devices for ConnectX1 and 2 */ if (dev->pdev->device != 0x1003) @@ -1308,7 +1306,7 @@ static void mlx4_cleanup_counters_table(struct mlx4_dev *dev) mlx4_bitmap_cleanup(&mlx4_priv(dev)->counters_bitmap); } -int __mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx) +int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx) { struct mlx4_priv *priv = mlx4_priv(dev); @@ -1321,44 +1319,13 @@ int __mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx) return 0; } - -int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx) -{ - u64 out_param; - int err; - - if (mlx4_is_mfunc(dev)) { - err = mlx4_cmd_imm(dev, 0, &out_param, RES_COUNTER, - RES_OP_RESERVE, MLX4_CMD_ALLOC_RES, - MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); - if (!err) - *idx = get_param_l(&out_param); - - return err; - } - return __mlx4_counter_alloc(dev, idx); -} EXPORT_SYMBOL_GPL(mlx4_counter_alloc); -void __mlx4_counter_free(struct mlx4_dev *dev, u32 idx) +void mlx4_counter_free(struct mlx4_dev *dev, u32 idx) { mlx4_bitmap_free(&mlx4_priv(dev)->counters_bitmap, idx); return; } - -void mlx4_counter_free(struct mlx4_dev *dev, u32 idx) -{ - u64 in_param; - - if (mlx4_is_mfunc(dev)) { - set_param_l(&in_param, idx); - mlx4_cmd(dev, in_param, RES_COUNTER, RES_OP_RESERVE, - MLX4_CMD_FREE_RES, MLX4_CMD_TIME_CLASS_A, - MLX4_CMD_WRAPPED); - return; - } - __mlx4_counter_free(dev, idx); -} EXPORT_SYMBOL_GPL(mlx4_counter_free); static int mlx4_setup_hca(struct mlx4_dev *dev) @@ -1898,6 +1865,7 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) mlx4_err(dev, "Failed to enable sriov," "continuing without sriov enabled" " (err = %d).\n", err); + num_vfs = 0; err = 0; } else { mlx4_warn(dev, "Running in master mode\n"); @@ -2054,7 +2022,7 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) mlx4_cmd_cleanup(dev); err_sriov: - if (dev->flags & MLX4_FLAG_SRIOV) + if (num_vfs && (dev->flags & MLX4_FLAG_SRIOV)) pci_disable_sriov(pdev); err_rel_own: @@ -2102,10 +2070,6 @@ static void mlx4_remove_one(struct pci_dev *pdev) mlx4_CLOSE_PORT(dev, p); } - if (mlx4_is_master(dev)) - mlx4_free_resource_tracker(dev, - RES_TR_FREE_SLAVES_ONLY); - mlx4_cleanup_counters_table(dev); mlx4_cleanup_mcg_table(dev); mlx4_cleanup_qp_table(dev); @@ -2118,8 +2082,7 @@ static void mlx4_remove_one(struct pci_dev *pdev) mlx4_cleanup_pd_table(dev); if (mlx4_is_master(dev)) - mlx4_free_resource_tracker(dev, - RES_TR_FREE_STRUCTS_ONLY); + mlx4_free_resource_tracker(dev); iounmap(priv->kar); mlx4_uar_free(dev, &priv->driver_uar); @@ -2136,7 +2099,7 @@ static void mlx4_remove_one(struct pci_dev *pdev) if (dev->flags & MLX4_FLAG_MSI_X) pci_disable_msix(pdev); - if (dev->flags & MLX4_FLAG_SRIOV) { + if (num_vfs && (dev->flags & MLX4_FLAG_SRIOV)) { mlx4_warn(dev, "Disabling sriov\n"); pci_disable_sriov(pdev); } diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/mcg.c b/trunk/drivers/net/ethernet/mellanox/mlx4/mcg.c index f4a8f98e402a..4799e824052f 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/mcg.c @@ -357,6 +357,7 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port, u32 prot; int i; bool found; + int last_index; int err; struct mlx4_priv *priv = mlx4_priv(dev); @@ -418,6 +419,7 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port, if (err) goto out_mailbox; } + last_index = entry->index; } /* add the new qpn to list of promisc qps */ diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 86b6e5a2fabf..cd56f1aea4b5 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -146,11 +146,6 @@ enum mlx4_alloc_mode { RES_OP_MAP_ICM, }; -enum mlx4_res_tracker_free_type { - RES_TR_FREE_ALL, - RES_TR_FREE_SLAVES_ONLY, - RES_TR_FREE_STRUCTS_ONLY, -}; /* *Virtual HCR structures. @@ -876,10 +871,6 @@ void __mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac); int __mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac); int __mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt, int start_index, int npages, u64 *page_list); -int __mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx); -void __mlx4_counter_free(struct mlx4_dev *dev, u32 idx); -int __mlx4_xrcd_alloc(struct mlx4_dev *dev, u32 *xrcdn); -void __mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn); void mlx4_start_catas_poll(struct mlx4_dev *dev); void mlx4_stop_catas_poll(struct mlx4_dev *dev); @@ -1036,8 +1027,7 @@ int mlx4_get_slave_from_resource_id(struct mlx4_dev *dev, void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave_id); int mlx4_init_resource_tracker(struct mlx4_dev *dev); -void mlx4_free_resource_tracker(struct mlx4_dev *dev, - enum mlx4_res_tracker_free_type type); +void mlx4_free_resource_tracker(struct mlx4_dev *dev); int mlx4_SET_PORT_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr, diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 6ae350921b1a..5d876375a132 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -111,7 +111,9 @@ enum { #define MLX4_EN_MIN_TX_SIZE (4096 / TXBB_SIZE) #define MLX4_EN_SMALL_PKT_SIZE 64 -#define MLX4_EN_MAX_TX_RING_P_UP 32 +#define MLX4_EN_NUM_TX_RINGS 8 +#define MLX4_EN_NUM_PPP_RINGS 8 +#define MAX_TX_RINGS (MLX4_EN_NUM_TX_RINGS + MLX4_EN_NUM_PPP_RINGS) #define MLX4_EN_NUM_UP 8 #define MLX4_EN_DEF_TX_RING_SIZE 512 #define MLX4_EN_DEF_RX_RING_SIZE 1024 @@ -337,7 +339,6 @@ struct mlx4_en_profile { u32 active_ports; u32 small_pkt_int; u8 no_reset; - u8 num_tx_rings_p_up; struct mlx4_en_port_profile prof[MLX4_MAX_PORTS + 1]; }; @@ -476,9 +477,9 @@ struct mlx4_en_priv { u16 num_frags; u16 log_rx_info; - struct mlx4_en_tx_ring *tx_ring; + struct mlx4_en_tx_ring tx_ring[MAX_TX_RINGS]; struct mlx4_en_rx_ring rx_ring[MAX_RX_RINGS]; - struct mlx4_en_cq *tx_cq; + struct mlx4_en_cq tx_cq[MAX_TX_RINGS]; struct mlx4_en_cq rx_cq[MAX_RX_RINGS]; struct work_struct mcast_task; struct work_struct mac_task; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/mr.c b/trunk/drivers/net/ethernet/mellanox/mlx4/mr.c index af55b7ce5341..fe2ac8449c19 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/mr.c @@ -788,6 +788,7 @@ int mlx4_fmr_alloc(struct mlx4_dev *dev, u32 pd, u32 access, int max_pages, int max_maps, u8 page_shift, struct mlx4_fmr *fmr) { struct mlx4_priv *priv = mlx4_priv(dev); + u64 mtt_offset; int err = -ENOMEM; if (max_maps > dev->caps.max_fmr_maps) @@ -810,6 +811,8 @@ int mlx4_fmr_alloc(struct mlx4_dev *dev, u32 pd, u32 access, int max_pages, if (err) return err; + mtt_offset = fmr->mr.mtt.offset * dev->caps.mtt_entry_sz; + fmr->mtts = mlx4_table_find(&priv->mr_table.mtt_table, fmr->mr.mtt.offset, &fmr->dma_handle); @@ -892,6 +895,6 @@ EXPORT_SYMBOL_GPL(mlx4_fmr_free); int mlx4_SYNC_TPT(struct mlx4_dev *dev) { return mlx4_cmd(dev, 0, 0, 0, MLX4_CMD_SYNC_TPT, 1000, - MLX4_CMD_NATIVE); + MLX4_CMD_WRAPPED); } EXPORT_SYMBOL_GPL(mlx4_SYNC_TPT); diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/pd.c b/trunk/drivers/net/ethernet/mellanox/mlx4/pd.c index 1ac88637ad9d..db4746d0dca7 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/pd.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/pd.c @@ -63,7 +63,7 @@ void mlx4_pd_free(struct mlx4_dev *dev, u32 pdn) } EXPORT_SYMBOL_GPL(mlx4_pd_free); -int __mlx4_xrcd_alloc(struct mlx4_dev *dev, u32 *xrcdn) +int mlx4_xrcd_alloc(struct mlx4_dev *dev, u32 *xrcdn) { struct mlx4_priv *priv = mlx4_priv(dev); @@ -73,46 +73,11 @@ int __mlx4_xrcd_alloc(struct mlx4_dev *dev, u32 *xrcdn) return 0; } - -int mlx4_xrcd_alloc(struct mlx4_dev *dev, u32 *xrcdn) -{ - u64 out_param; - int err; - - if (mlx4_is_mfunc(dev)) { - err = mlx4_cmd_imm(dev, 0, &out_param, - RES_XRCD, RES_OP_RESERVE, - MLX4_CMD_ALLOC_RES, - MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); - if (err) - return err; - - *xrcdn = get_param_l(&out_param); - return 0; - } - return __mlx4_xrcd_alloc(dev, xrcdn); -} EXPORT_SYMBOL_GPL(mlx4_xrcd_alloc); -void __mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn) -{ - mlx4_bitmap_free(&mlx4_priv(dev)->xrcd_bitmap, xrcdn); -} - void mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn) { - u64 in_param; - int err; - - if (mlx4_is_mfunc(dev)) { - set_param_l(&in_param, xrcdn); - err = mlx4_cmd(dev, in_param, RES_XRCD, - RES_OP_RESERVE, MLX4_CMD_FREE_RES, - MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); - if (err) - mlx4_warn(dev, "Failed to release xrcdn %d\n", xrcdn); - } else - __mlx4_xrcd_free(dev, xrcdn); + mlx4_bitmap_free(&mlx4_priv(dev)->xrcd_bitmap, xrcdn); } EXPORT_SYMBOL_GPL(mlx4_xrcd_free); diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/port.c b/trunk/drivers/net/ethernet/mellanox/mlx4/port.c index 1fe2c7a8b40c..55b12e6bed87 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/port.c @@ -338,12 +338,13 @@ EXPORT_SYMBOL_GPL(__mlx4_unregister_mac); void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac) { u64 out_param; + int err; if (mlx4_is_mfunc(dev)) { set_param_l(&out_param, port); - (void) mlx4_cmd_imm(dev, mac, &out_param, RES_MAC, - RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES, - MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); + err = mlx4_cmd_imm(dev, mac, &out_param, RES_MAC, + RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES, + MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); return; } __mlx4_unregister_mac(dev, port, mac); diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/trunk/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index b45d0e7f6ab0..8752e6e08169 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -89,6 +89,17 @@ enum res_qp_states { RES_QP_HW }; +static inline const char *qp_states_str(enum res_qp_states state) +{ + switch (state) { + case RES_QP_BUSY: return "RES_QP_BUSY"; + case RES_QP_RESERVED: return "RES_QP_RESERVED"; + case RES_QP_MAPPED: return "RES_QP_MAPPED"; + case RES_QP_HW: return "RES_QP_HW"; + default: return "Unknown"; + } +} + struct res_qp { struct res_common com; struct res_mtt *mtt; @@ -162,6 +173,16 @@ enum res_srq_states { RES_SRQ_HW, }; +static inline const char *srq_states_str(enum res_srq_states state) +{ + switch (state) { + case RES_SRQ_BUSY: return "RES_SRQ_BUSY"; + case RES_SRQ_ALLOCATED: return "RES_SRQ_ALLOCATED"; + case RES_SRQ_HW: return "RES_SRQ_HW"; + default: return "Unknown"; + } +} + struct res_srq { struct res_common com; struct res_mtt *mtt; @@ -174,17 +195,16 @@ enum res_counter_states { RES_COUNTER_ALLOCATED, }; -struct res_counter { - struct res_common com; - int port; -}; - -enum res_xrcdn_states { - RES_XRCD_BUSY = RES_ANY_BUSY, - RES_XRCD_ALLOCATED, -}; +static inline const char *counter_states_str(enum res_counter_states state) +{ + switch (state) { + case RES_COUNTER_BUSY: return "RES_COUNTER_BUSY"; + case RES_COUNTER_ALLOCATED: return "RES_COUNTER_ALLOCATED"; + default: return "Unknown"; + } +} -struct res_xrcdn { +struct res_counter { struct res_common com; int port; }; @@ -201,7 +221,6 @@ static const char *ResourceType(enum mlx4_resource rt) case RES_MAC: return "RES_MAC"; case RES_EQ: return "RES_EQ"; case RES_COUNTER: return "RES_COUNTER"; - case RES_XRCD: return "RES_XRCD"; default: return "Unknown resource type !!!"; }; } @@ -235,23 +254,16 @@ int mlx4_init_resource_tracker(struct mlx4_dev *dev) return 0 ; } -void mlx4_free_resource_tracker(struct mlx4_dev *dev, - enum mlx4_res_tracker_free_type type) +void mlx4_free_resource_tracker(struct mlx4_dev *dev) { struct mlx4_priv *priv = mlx4_priv(dev); int i; if (priv->mfunc.master.res_tracker.slave_list) { - if (type != RES_TR_FREE_STRUCTS_ONLY) - for (i = 0 ; i < dev->num_slaves; i++) - if (type == RES_TR_FREE_ALL || - dev->caps.function != i) - mlx4_delete_all_resources_for_slave(dev, i); - - if (type != RES_TR_FREE_SLAVES_ONLY) { - kfree(priv->mfunc.master.res_tracker.slave_list); - priv->mfunc.master.res_tracker.slave_list = NULL; - } + for (i = 0 ; i < dev->num_slaves; i++) + mlx4_delete_all_resources_for_slave(dev, i); + + kfree(priv->mfunc.master.res_tracker.slave_list); } } @@ -459,20 +471,6 @@ static struct res_common *alloc_counter_tr(int id) return &ret->com; } -static struct res_common *alloc_xrcdn_tr(int id) -{ - struct res_xrcdn *ret; - - ret = kzalloc(sizeof *ret, GFP_KERNEL); - if (!ret) - return NULL; - - ret->com.res_id = id; - ret->com.state = RES_XRCD_ALLOCATED; - - return &ret->com; -} - static struct res_common *alloc_tr(int id, enum mlx4_resource type, int slave, int extra) { @@ -503,9 +501,7 @@ static struct res_common *alloc_tr(int id, enum mlx4_resource type, int slave, case RES_COUNTER: ret = alloc_counter_tr(id); break; - case RES_XRCD: - ret = alloc_xrcdn_tr(id); - break; + default: return NULL; } @@ -628,16 +624,6 @@ static int remove_counter_ok(struct res_counter *res) return 0; } -static int remove_xrcdn_ok(struct res_xrcdn *res) -{ - if (res->com.state == RES_XRCD_BUSY) - return -EBUSY; - else if (res->com.state != RES_XRCD_ALLOCATED) - return -EPERM; - - return 0; -} - static int remove_cq_ok(struct res_cq *res) { if (res->com.state == RES_CQ_BUSY) @@ -677,8 +663,6 @@ static int remove_ok(struct res_common *res, enum mlx4_resource type, int extra) return remove_eq_ok((struct res_eq *)res); case RES_COUNTER: return remove_counter_ok((struct res_counter *)res); - case RES_XRCD: - return remove_xrcdn_ok((struct res_xrcdn *)res); default: return -EINVAL; } @@ -1285,50 +1269,6 @@ static int vlan_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd, return 0; } -static int counter_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd, - u64 in_param, u64 *out_param) -{ - u32 index; - int err; - - if (op != RES_OP_RESERVE) - return -EINVAL; - - err = __mlx4_counter_alloc(dev, &index); - if (err) - return err; - - err = add_res_range(dev, slave, index, 1, RES_COUNTER, 0); - if (err) - __mlx4_counter_free(dev, index); - else - set_param_l(out_param, index); - - return err; -} - -static int xrcdn_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd, - u64 in_param, u64 *out_param) -{ - u32 xrcdn; - int err; - - if (op != RES_OP_RESERVE) - return -EINVAL; - - err = __mlx4_xrcd_alloc(dev, &xrcdn); - if (err) - return err; - - err = add_res_range(dev, slave, xrcdn, 1, RES_XRCD, 0); - if (err) - __mlx4_xrcd_free(dev, xrcdn); - else - set_param_l(out_param, xrcdn); - - return err; -} - int mlx4_ALLOC_RES_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr, struct mlx4_cmd_mailbox *inbox, @@ -1374,16 +1314,6 @@ int mlx4_ALLOC_RES_wrapper(struct mlx4_dev *dev, int slave, vhcr->in_param, &vhcr->out_param); break; - case RES_COUNTER: - err = counter_alloc_res(dev, slave, vhcr->op_modifier, alop, - vhcr->in_param, &vhcr->out_param); - break; - - case RES_XRCD: - err = xrcdn_alloc_res(dev, slave, vhcr->op_modifier, alop, - vhcr->in_param, &vhcr->out_param); - break; - default: err = -EINVAL; break; @@ -1566,44 +1496,6 @@ static int vlan_free_res(struct mlx4_dev *dev, int slave, int op, int cmd, return 0; } -static int counter_free_res(struct mlx4_dev *dev, int slave, int op, int cmd, - u64 in_param, u64 *out_param) -{ - int index; - int err; - - if (op != RES_OP_RESERVE) - return -EINVAL; - - index = get_param_l(&in_param); - err = rem_res_range(dev, slave, index, 1, RES_COUNTER, 0); - if (err) - return err; - - __mlx4_counter_free(dev, index); - - return err; -} - -static int xrcdn_free_res(struct mlx4_dev *dev, int slave, int op, int cmd, - u64 in_param, u64 *out_param) -{ - int xrcdn; - int err; - - if (op != RES_OP_RESERVE) - return -EINVAL; - - xrcdn = get_param_l(&in_param); - err = rem_res_range(dev, slave, xrcdn, 1, RES_XRCD, 0); - if (err) - return err; - - __mlx4_xrcd_free(dev, xrcdn); - - return err; -} - int mlx4_FREE_RES_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr, struct mlx4_cmd_mailbox *inbox, @@ -1649,15 +1541,6 @@ int mlx4_FREE_RES_wrapper(struct mlx4_dev *dev, int slave, vhcr->in_param, &vhcr->out_param); break; - case RES_COUNTER: - err = counter_free_res(dev, slave, vhcr->op_modifier, alop, - vhcr->in_param, &vhcr->out_param); - break; - - case RES_XRCD: - err = xrcdn_free_res(dev, slave, vhcr->op_modifier, alop, - vhcr->in_param, &vhcr->out_param); - default: break; } @@ -2653,7 +2536,7 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_qp qp; /* dummy for calling attach/detach */ u8 *gid = inbox->buf; enum mlx4_protocol prot = (vhcr->in_modifier >> 28) & 0x7; - int err; + int err, err1; int qpn; struct res_qp *rqp; int attach = vhcr->op_modifier; @@ -2688,7 +2571,7 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave, ex_rem: /* ignore error return below, already in error */ - (void) rem_mcg_res(dev, slave, rqp, gid, prot, type); + err1 = rem_mcg_res(dev, slave, rqp, gid, prot, type); ex_put: put_res(dev, slave, qpn, RES_QP); @@ -2721,12 +2604,13 @@ static void detach_qp(struct mlx4_dev *dev, int slave, struct res_qp *rqp) { struct res_gid *rgid; struct res_gid *tmp; + int err; struct mlx4_qp qp; /* dummy for calling attach/detach */ list_for_each_entry_safe(rgid, tmp, &rqp->mcg_list, list) { qp.qpn = rqp->local_qpn; - (void) mlx4_qp_detach_common(dev, &qp, rgid->gid, rgid->prot, - rgid->steer); + err = mlx4_qp_detach_common(dev, &qp, rgid->gid, rgid->prot, + rgid->steer); list_del(&rgid->list); kfree(rgid); } @@ -3152,13 +3036,14 @@ static void rem_slave_eqs(struct mlx4_dev *dev, int slave) MLX4_CMD_HW2SW_EQ, MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); - if (err) - mlx4_dbg(dev, "rem_slave_eqs: failed" - " to move slave %d eqs %d to" - " SW ownership\n", slave, eqn); + mlx4_dbg(dev, "rem_slave_eqs: failed" + " to move slave %d eqs %d to" + " SW ownership\n", slave, eqn); mlx4_free_cmd_mailbox(dev, mailbox); - atomic_dec(&eq->mtt->ref_count); - state = RES_EQ_RESERVED; + if (!err) { + atomic_dec(&eq->mtt->ref_count); + state = RES_EQ_RESERVED; + } break; default: @@ -3171,64 +3056,6 @@ static void rem_slave_eqs(struct mlx4_dev *dev, int slave) spin_unlock_irq(mlx4_tlock(dev)); } -static void rem_slave_counters(struct mlx4_dev *dev, int slave) -{ - struct mlx4_priv *priv = mlx4_priv(dev); - struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker; - struct list_head *counter_list = - &tracker->slave_list[slave].res_list[RES_COUNTER]; - struct res_counter *counter; - struct res_counter *tmp; - int err; - int index; - - err = move_all_busy(dev, slave, RES_COUNTER); - if (err) - mlx4_warn(dev, "rem_slave_counters: Could not move all counters to " - "busy for slave %d\n", slave); - - spin_lock_irq(mlx4_tlock(dev)); - list_for_each_entry_safe(counter, tmp, counter_list, com.list) { - if (counter->com.owner == slave) { - index = counter->com.res_id; - radix_tree_delete(&tracker->res_tree[RES_COUNTER], index); - list_del(&counter->com.list); - kfree(counter); - __mlx4_counter_free(dev, index); - } - } - spin_unlock_irq(mlx4_tlock(dev)); -} - -static void rem_slave_xrcdns(struct mlx4_dev *dev, int slave) -{ - struct mlx4_priv *priv = mlx4_priv(dev); - struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker; - struct list_head *xrcdn_list = - &tracker->slave_list[slave].res_list[RES_XRCD]; - struct res_xrcdn *xrcd; - struct res_xrcdn *tmp; - int err; - int xrcdn; - - err = move_all_busy(dev, slave, RES_XRCD); - if (err) - mlx4_warn(dev, "rem_slave_xrcdns: Could not move all xrcdns to " - "busy for slave %d\n", slave); - - spin_lock_irq(mlx4_tlock(dev)); - list_for_each_entry_safe(xrcd, tmp, xrcdn_list, com.list) { - if (xrcd->com.owner == slave) { - xrcdn = xrcd->com.res_id; - radix_tree_delete(&tracker->res_tree[RES_XRCD], xrcdn); - list_del(&xrcd->com.list); - kfree(xrcd); - __mlx4_xrcd_free(dev, xrcdn); - } - } - spin_unlock_irq(mlx4_tlock(dev)); -} - void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave) { struct mlx4_priv *priv = mlx4_priv(dev); @@ -3242,7 +3069,5 @@ void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave) rem_slave_mrs(dev, slave); rem_slave_eqs(dev, slave); rem_slave_mtts(dev, slave); - rem_slave_counters(dev, slave); - rem_slave_xrcdns(dev, slave); mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex); } diff --git a/trunk/drivers/net/ethernet/micrel/ks8851.c b/trunk/drivers/net/ethernet/micrel/ks8851.c index 5e313e9a252f..f8dda009d3c0 100644 --- a/trunk/drivers/net/ethernet/micrel/ks8851.c +++ b/trunk/drivers/net/ethernet/micrel/ks8851.c @@ -618,8 +618,10 @@ static void ks8851_irq_work(struct work_struct *work) netif_dbg(ks, intr, ks->netdev, "%s: status 0x%04x\n", __func__, status); - if (status & IRQ_LCI) + if (status & IRQ_LCI) { + /* should do something about checking link status */ handled |= IRQ_LCI; + } if (status & IRQ_LDI) { u16 pmecr = ks8851_rdreg16(ks, KS_PMECR); @@ -682,9 +684,6 @@ static void ks8851_irq_work(struct work_struct *work) mutex_unlock(&ks->lock); - if (status & IRQ_LCI) - mii_check_link(&ks->mii); - if (status & IRQ_TXI) netif_wake_queue(ks->netdev); diff --git a/trunk/drivers/net/ethernet/natsemi/Kconfig b/trunk/drivers/net/ethernet/natsemi/Kconfig index f157334579fd..eb836f770f50 100644 --- a/trunk/drivers/net/ethernet/natsemi/Kconfig +++ b/trunk/drivers/net/ethernet/natsemi/Kconfig @@ -6,8 +6,9 @@ config NET_VENDOR_NATSEMI bool "National Semi-conductor devices" default y depends on AMIGA_PCMCIA || ARM || EISA || EXPERIMENTAL || H8300 || \ - ISA || M32R || MAC || MACH_JAZZ || MACH_TX49XX || MIPS || \ - PCI || PCMCIA || SUPERH || XTENSA_PLATFORM_XT2000 || ZORRO + ISA || M32R || MAC || MACH_JAZZ || MACH_TX49XX || MCA || \ + MCA_LEGACY || MIPS || PCI || PCMCIA || SUPERH || \ + XTENSA_PLATFORM_XT2000 || ZORRO ---help--- If you have a network (Ethernet) card belonging to this class, say Y and read the Ethernet-HOWTO, available from @@ -20,6 +21,21 @@ config NET_VENDOR_NATSEMI if NET_VENDOR_NATSEMI +config IBMLANA + tristate "IBM LAN Adapter/A support" + depends on MCA + ---help--- + This is a Micro Channel Ethernet adapter. You need to set + CONFIG_MCA to use this driver. It is both available as an in-kernel + driver and as a module. + + To compile this driver as a module, choose M here. The only + currently supported card is the IBM LAN Adapter/A for Ethernet. It + will both support 16K and 32K memory windows, however a 32K window + gives a better security against packet losses. Usage of multiple + boards with this driver should be possible, but has not been tested + up to now due to lack of hardware. + config MACSONIC tristate "Macintosh SONIC based ethernet (onboard, NuBus, LC, CS)" depends on MAC diff --git a/trunk/drivers/net/ethernet/natsemi/Makefile b/trunk/drivers/net/ethernet/natsemi/Makefile index 764c532a96d1..9aa5dea52b3e 100644 --- a/trunk/drivers/net/ethernet/natsemi/Makefile +++ b/trunk/drivers/net/ethernet/natsemi/Makefile @@ -2,6 +2,7 @@ # Makefile for the National Semi-conductor Sonic devices. # +obj-$(CONFIG_IBMLANA) += ibmlana.o obj-$(CONFIG_MACSONIC) += macsonic.o obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o obj-$(CONFIG_NATSEMI) += natsemi.o diff --git a/trunk/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h b/trunk/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h index b07311eaa693..9f3dbc4feadc 100644 --- a/trunk/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h +++ b/trunk/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h @@ -584,6 +584,7 @@ struct pch_gbe_hw_stats { /** * struct pch_gbe_adapter - board specific private data structure * @stats_lock: Spinlock structure for status + * @tx_queue_lock: Spinlock structure for transmit * @ethtool_lock: Spinlock structure for ethtool * @irq_sem: Semaphore for interrupt * @netdev: Pointer of network device structure @@ -608,6 +609,7 @@ struct pch_gbe_hw_stats { struct pch_gbe_adapter { spinlock_t stats_lock; + spinlock_t tx_queue_lock; spinlock_t ethtool_lock; atomic_t irq_sem; struct net_device *netdev; diff --git a/trunk/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/trunk/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index 3787c64ee71c..9dc7e5023671 100644 --- a/trunk/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/trunk/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -645,11 +645,14 @@ static void pch_gbe_mac_set_pause_packet(struct pch_gbe_hw *hw) */ static int pch_gbe_alloc_queues(struct pch_gbe_adapter *adapter) { - adapter->tx_ring = kzalloc(sizeof(*adapter->tx_ring), GFP_KERNEL); + int size; + + size = (int)sizeof(struct pch_gbe_tx_ring); + adapter->tx_ring = kzalloc(size, GFP_KERNEL); if (!adapter->tx_ring) return -ENOMEM; - - adapter->rx_ring = kzalloc(sizeof(*adapter->rx_ring), GFP_KERNEL); + size = (int)sizeof(struct pch_gbe_rx_ring); + adapter->rx_ring = kzalloc(size, GFP_KERNEL); if (!adapter->rx_ring) { kfree(adapter->tx_ring); return -ENOMEM; @@ -1166,6 +1169,7 @@ static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter, struct sk_buff *tmp_skb; unsigned int frame_ctrl; unsigned int ring_num; + unsigned long flags; /*-- Set frame control --*/ frame_ctrl = 0; @@ -1212,14 +1216,14 @@ static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter, } } } - + spin_lock_irqsave(&tx_ring->tx_lock, flags); ring_num = tx_ring->next_to_use; if (unlikely((ring_num + 1) == tx_ring->count)) tx_ring->next_to_use = 0; else tx_ring->next_to_use = ring_num + 1; - + spin_unlock_irqrestore(&tx_ring->tx_lock, flags); buffer_info = &tx_ring->buffer_info[ring_num]; tmp_skb = buffer_info->skb; @@ -1521,7 +1525,7 @@ pch_gbe_alloc_rx_buffers_pool(struct pch_gbe_adapter *adapter, &rx_ring->rx_buff_pool_logic, GFP_KERNEL); if (!rx_ring->rx_buff_pool) { - pr_err("Unable to allocate memory for the receive pool buffer\n"); + pr_err("Unable to allocate memory for the receive poll buffer\n"); return -ENOMEM; } memset(rx_ring->rx_buff_pool, 0, size); @@ -1640,17 +1644,15 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter, pr_debug("called pch_gbe_unmap_and_free_tx_resource() %d count\n", cleaned_count); /* Recover from running out of Tx resources in xmit_frame */ - spin_lock(&tx_ring->tx_lock); if (unlikely(cleaned && (netif_queue_stopped(adapter->netdev)))) { netif_wake_queue(adapter->netdev); adapter->stats.tx_restart_count++; pr_debug("Tx wake queue\n"); } - + spin_lock(&adapter->tx_queue_lock); tx_ring->next_to_clean = i; - + spin_unlock(&adapter->tx_queue_lock); pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean); - spin_unlock(&tx_ring->tx_lock); return cleaned; } @@ -2041,6 +2043,7 @@ static int pch_gbe_sw_init(struct pch_gbe_adapter *adapter) return -ENOMEM; } spin_lock_init(&adapter->hw.miim_lock); + spin_lock_init(&adapter->tx_queue_lock); spin_lock_init(&adapter->stats_lock); spin_lock_init(&adapter->ethtool_lock); atomic_set(&adapter->irq_sem, 0); @@ -2145,10 +2148,10 @@ static int pch_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) tx_ring->next_to_use, tx_ring->next_to_clean); return NETDEV_TX_BUSY; } + spin_unlock_irqrestore(&tx_ring->tx_lock, flags); /* CRC,ITAG no support */ pch_gbe_tx_queue(adapter, tx_ring, skb); - spin_unlock_irqrestore(&tx_ring->tx_lock, flags); return NETDEV_TX_OK; } diff --git a/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic.h b/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic.h index 37ccbe54e62d..b5de8a7b90f1 100644 --- a/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic.h +++ b/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic.h @@ -53,8 +53,8 @@ #define _NETXEN_NIC_LINUX_MAJOR 4 #define _NETXEN_NIC_LINUX_MINOR 0 -#define _NETXEN_NIC_LINUX_SUBVERSION 79 -#define NETXEN_NIC_LINUX_VERSIONID "4.0.79" +#define _NETXEN_NIC_LINUX_SUBVERSION 78 +#define NETXEN_NIC_LINUX_VERSIONID "4.0.78" #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) #define _major(v) (((v) >> 24) & 0xff) @@ -419,8 +419,6 @@ struct rcv_desc { (((sts_data) >> 52) & 0x1) #define netxen_get_lro_sts_seq_number(sts_data) \ ((sts_data) & 0x0FFFFFFFF) -#define netxen_get_lro_sts_mss(sts_data1) \ - ((sts_data1 >> 32) & 0x0FFFF) struct status_desc { @@ -796,7 +794,6 @@ struct netxen_cmd_args { #define NX_CAP0_JUMBO_CONTIGUOUS NX_CAP_BIT(0, 7) #define NX_CAP0_LRO_CONTIGUOUS NX_CAP_BIT(0, 8) #define NX_CAP0_HW_LRO NX_CAP_BIT(0, 10) -#define NX_CAP0_HW_LRO_MSS NX_CAP_BIT(0, 21) /* * Context state @@ -1076,8 +1073,6 @@ typedef struct { #define NX_FW_CAPABILITY_FVLANTX (1 << 9) #define NX_FW_CAPABILITY_HW_LRO (1 << 10) #define NX_FW_CAPABILITY_GBE_LINK_CFG (1 << 11) -#define NX_FW_CAPABILITY_MORE_CAPS (1 << 31) -#define NX_FW_CAPABILITY_2_LRO_MAX_TCP_SEG (1 << 2) /* module types */ #define LINKEVENT_MODULE_NOT_PRESENT 1 @@ -1160,7 +1155,6 @@ typedef struct { #define NETXEN_NIC_BRIDGE_ENABLED 0X10 #define NETXEN_NIC_DIAG_ENABLED 0x20 #define NETXEN_FW_RESET_OWNER 0x40 -#define NETXEN_FW_MSS_CAP 0x80 #define NETXEN_IS_MSI_FAMILY(adapter) \ ((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED)) @@ -1207,9 +1201,6 @@ typedef struct { #define NX_FORCE_FW_RESET 0xdeaddead -/* Fw dump levels */ -static const u32 FW_DUMP_LEVELS[] = { 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff }; - /* Flash read/write address */ #define NX_FW_DUMP_REG1 0x00130060 #define NX_FW_DUMP_REG2 0x001e0000 @@ -1823,13 +1814,6 @@ struct netxen_brdinfo { char short_name[NETXEN_MAX_SHORT_NAME]; }; -struct netxen_dimm_cfg { - u8 presence; - u8 mem_type; - u8 dimm_type; - u32 size; -}; - static const struct netxen_brdinfo netxen_boards[] = { {NETXEN_BRDTYPE_P2_SB31_10G_CX4, 1, "XGb CX4"}, {NETXEN_BRDTYPE_P2_SB31_10G_HMEZ, 1, "XGb HMEZ"}, diff --git a/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c b/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c index 7f556a84925d..f3c0057a802b 100644 --- a/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c +++ b/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c @@ -229,7 +229,7 @@ netxen_setup_minidump(struct netxen_adapter *adapter) adapter->mdump.md_template; adapter->mdump.md_capture_buff = NULL; adapter->mdump.fw_supports_md = 1; - adapter->mdump.md_enabled = 0; + adapter->mdump.md_enabled = 1; return err; @@ -328,9 +328,6 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) cap = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN); cap |= (NX_CAP0_JUMBO_CONTIGUOUS | NX_CAP0_LRO_CONTIGUOUS); - if (adapter->flags & NETXEN_FW_MSS_CAP) - cap |= NX_CAP0_HW_LRO_MSS; - prq->capabilities[0] = cpu_to_le32(cap); prq->host_int_crb_mode = cpu_to_le32(NX_HOST_INT_CRB_MODE_SHARED); diff --git a/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c b/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c index 39730403782f..8c39299331a2 100644 --- a/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c +++ b/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c @@ -834,7 +834,7 @@ netxen_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump) static int netxen_set_dump(struct net_device *netdev, struct ethtool_dump *val) { - int i; + int ret = 0; struct netxen_adapter *adapter = netdev_priv(netdev); struct netxen_minidump *mdump = &adapter->mdump; @@ -844,7 +844,7 @@ netxen_set_dump(struct net_device *netdev, struct ethtool_dump *val) mdump->md_enabled = 1; if (adapter->fw_mdump_rdy) { netdev_info(netdev, "Previous dump not cleared, not forcing dump\n"); - return 0; + return ret; } netdev_info(netdev, "Forcing a fw dump\n"); nx_dev_request_reset(adapter); @@ -867,21 +867,19 @@ netxen_set_dump(struct net_device *netdev, struct ethtool_dump *val) adapter->flags &= ~NETXEN_FW_RESET_OWNER; break; default: - for (i = 0; i < ARRAY_SIZE(FW_DUMP_LEVELS); i++) { - if (val->flag == FW_DUMP_LEVELS[i]) { - mdump->md_capture_mask = val->flag; - netdev_info(netdev, - "Driver mask changed to: 0x%x\n", + if (val->flag <= NX_DUMP_MASK_MAX && + val->flag >= NX_DUMP_MASK_MIN) { + mdump->md_capture_mask = val->flag & 0xff; + netdev_info(netdev, "Driver mask changed to: 0x%x\n", mdump->md_capture_mask); - return 0; - } + break; } netdev_info(netdev, "Invalid dump level: 0x%x\n", val->flag); return -EINVAL; } - return 0; + return ret; } static int diff --git a/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h b/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h index 28e076960bcb..b1a897cd9a8d 100644 --- a/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h +++ b/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h @@ -776,7 +776,6 @@ enum { #define CRB_SW_INT_MASK_3 (NETXEN_NIC_REG(0x1e8)) #define CRB_FW_CAPABILITIES_1 (NETXEN_CAM_RAM(0x128)) -#define CRB_FW_CAPABILITIES_2 (NETXEN_CAM_RAM(0x12c)) #define CRB_MAC_BLOCK_START (NETXEN_CAM_RAM(0x1c0)) /* @@ -956,31 +955,6 @@ enum { #define NX_CRB_DEV_REF_COUNT (NETXEN_CAM_RAM(0x138)) #define NX_CRB_DEV_STATE (NETXEN_CAM_RAM(0x140)) -/* MiniDIMM related macros */ -#define NETXEN_DIMM_CAPABILITY (NETXEN_CAM_RAM(0x258)) -#define NETXEN_DIMM_PRESENT 0x1 -#define NETXEN_DIMM_MEMTYPE_DDR2_SDRAM 0x2 -#define NETXEN_DIMM_SIZE 0x4 -#define NETXEN_DIMM_MEMTYPE(VAL) ((VAL >> 3) & 0xf) -#define NETXEN_DIMM_NUMROWS(VAL) ((VAL >> 7) & 0xf) -#define NETXEN_DIMM_NUMCOLS(VAL) ((VAL >> 11) & 0xf) -#define NETXEN_DIMM_NUMRANKS(VAL) ((VAL >> 15) & 0x3) -#define NETXEN_DIMM_DATAWIDTH(VAL) ((VAL >> 18) & 0x3) -#define NETXEN_DIMM_NUMBANKS(VAL) ((VAL >> 21) & 0xf) -#define NETXEN_DIMM_TYPE(VAL) ((VAL >> 25) & 0x3f) -#define NETXEN_DIMM_VALID_FLAG 0x80000000 - -#define NETXEN_DIMM_MEM_DDR2_SDRAM 0x8 - -#define NETXEN_DIMM_STD_MEM_SIZE 512 - -#define NETXEN_DIMM_TYPE_RDIMM 0x1 -#define NETXEN_DIMM_TYPE_UDIMM 0x2 -#define NETXEN_DIMM_TYPE_SO_DIMM 0x4 -#define NETXEN_DIMM_TYPE_Micro_DIMM 0x8 -#define NETXEN_DIMM_TYPE_Mini_RDIMM 0x10 -#define NETXEN_DIMM_TYPE_Mini_UDIMM 0x20 - /* Device State */ #define NX_DEV_COLD 1 #define NX_DEV_INITALIZING 2 diff --git a/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c index 0d725dc91bcb..718b27440351 100644 --- a/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c +++ b/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c @@ -1131,6 +1131,7 @@ netxen_validate_firmware(struct netxen_adapter *adapter) _build(file_fw_ver)); return -EINVAL; } + val = nx_get_bios_version(adapter); netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios); if ((__force u32)val != bios) { @@ -1660,9 +1661,6 @@ netxen_process_lro(struct netxen_adapter *adapter, length = skb->len; - if (adapter->flags & NETXEN_FW_MSS_CAP) - skb_shinfo(skb)->gso_size = netxen_get_lro_sts_mss(sts_data1); - netif_receive_skb(skb); adapter->stats.lro_pkts++; diff --git a/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index 342b3a79bd0f..65a718f9ccd3 100644 --- a/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -1184,7 +1184,6 @@ netxen_nic_attach(struct netxen_adapter *adapter) int err, ring; struct nx_host_rds_ring *rds_ring; struct nx_host_tx_ring *tx_ring; - u32 capab2; if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) return 0; @@ -1193,13 +1192,6 @@ netxen_nic_attach(struct netxen_adapter *adapter) if (err) return err; - adapter->flags &= ~NETXEN_FW_MSS_CAP; - if (adapter->capabilities & NX_FW_CAPABILITY_MORE_CAPS) { - capab2 = NXRD32(adapter, CRB_FW_CAPABILITIES_2); - if (capab2 & NX_FW_CAPABILITY_2_LRO_MAX_TCP_SEG) - adapter->flags |= NETXEN_FW_MSS_CAP; - } - err = netxen_napi_add(adapter, netdev); if (err) return err; @@ -1818,6 +1810,7 @@ netxen_tso_check(struct net_device *netdev, flags = FLAGS_VLAN_TAGGED; } else if (vlan_tx_tag_present(skb)) { + flags = FLAGS_VLAN_OOB; vid = vlan_tx_tag_get(skb); netxen_set_tx_vlan_tci(first_desc, vid); @@ -2933,134 +2926,6 @@ static struct bin_attribute bin_attr_mem = { .write = netxen_sysfs_write_mem, }; -static ssize_t -netxen_sysfs_read_dimm(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, - char *buf, loff_t offset, size_t size) -{ - struct device *dev = container_of(kobj, struct device, kobj); - struct netxen_adapter *adapter = dev_get_drvdata(dev); - struct net_device *netdev = adapter->netdev; - struct netxen_dimm_cfg dimm; - u8 dw, rows, cols, banks, ranks; - u32 val; - - if (size != sizeof(struct netxen_dimm_cfg)) { - netdev_err(netdev, "Invalid size\n"); - return -1; - } - - memset(&dimm, 0, sizeof(struct netxen_dimm_cfg)); - val = NXRD32(adapter, NETXEN_DIMM_CAPABILITY); - - /* Checks if DIMM info is valid. */ - if (val & NETXEN_DIMM_VALID_FLAG) { - netdev_err(netdev, "Invalid DIMM flag\n"); - dimm.presence = 0xff; - goto out; - } - - rows = NETXEN_DIMM_NUMROWS(val); - cols = NETXEN_DIMM_NUMCOLS(val); - ranks = NETXEN_DIMM_NUMRANKS(val); - banks = NETXEN_DIMM_NUMBANKS(val); - dw = NETXEN_DIMM_DATAWIDTH(val); - - dimm.presence = (val & NETXEN_DIMM_PRESENT); - - /* Checks if DIMM info is present. */ - if (!dimm.presence) { - netdev_err(netdev, "DIMM not present\n"); - goto out; - } - - dimm.dimm_type = NETXEN_DIMM_TYPE(val); - - switch (dimm.dimm_type) { - case NETXEN_DIMM_TYPE_RDIMM: - case NETXEN_DIMM_TYPE_UDIMM: - case NETXEN_DIMM_TYPE_SO_DIMM: - case NETXEN_DIMM_TYPE_Micro_DIMM: - case NETXEN_DIMM_TYPE_Mini_RDIMM: - case NETXEN_DIMM_TYPE_Mini_UDIMM: - break; - default: - netdev_err(netdev, "Invalid DIMM type %x\n", dimm.dimm_type); - goto out; - } - - if (val & NETXEN_DIMM_MEMTYPE_DDR2_SDRAM) - dimm.mem_type = NETXEN_DIMM_MEM_DDR2_SDRAM; - else - dimm.mem_type = NETXEN_DIMM_MEMTYPE(val); - - if (val & NETXEN_DIMM_SIZE) { - dimm.size = NETXEN_DIMM_STD_MEM_SIZE; - goto out; - } - - if (!rows) { - netdev_err(netdev, "Invalid no of rows %x\n", rows); - goto out; - } - - if (!cols) { - netdev_err(netdev, "Invalid no of columns %x\n", cols); - goto out; - } - - if (!banks) { - netdev_err(netdev, "Invalid no of banks %x\n", banks); - goto out; - } - - ranks += 1; - - switch (dw) { - case 0x0: - dw = 32; - break; - case 0x1: - dw = 33; - break; - case 0x2: - dw = 36; - break; - case 0x3: - dw = 64; - break; - case 0x4: - dw = 72; - break; - case 0x5: - dw = 80; - break; - case 0x6: - dw = 128; - break; - case 0x7: - dw = 144; - break; - default: - netdev_err(netdev, "Invalid data-width %x\n", dw); - goto out; - } - - dimm.size = ((1 << rows) * (1 << cols) * dw * banks * ranks) / 8; - /* Size returned in MB. */ - dimm.size = (dimm.size) / 0x100000; -out: - memcpy(buf, &dimm, sizeof(struct netxen_dimm_cfg)); - return sizeof(struct netxen_dimm_cfg); - -} - -static struct bin_attribute bin_attr_dimm = { - .attr = { .name = "dimm", .mode = (S_IRUGO | S_IWUSR) }, - .size = 0, - .read = netxen_sysfs_read_dimm, -}; - static void netxen_create_sysfs_entries(struct netxen_adapter *adapter) @@ -3098,8 +2963,6 @@ netxen_create_diag_entries(struct netxen_adapter *adapter) dev_info(dev, "failed to create crb sysfs entry\n"); if (device_create_bin_file(dev, &bin_attr_mem)) dev_info(dev, "failed to create mem sysfs entry\n"); - if (device_create_bin_file(dev, &bin_attr_dimm)) - dev_info(dev, "failed to create dimm sysfs entry\n"); } @@ -3112,7 +2975,6 @@ netxen_remove_diag_entries(struct netxen_adapter *adapter) device_remove_file(dev, &dev_attr_diag_mode); device_remove_bin_file(dev, &bin_attr_crb); device_remove_bin_file(dev, &bin_attr_mem); - device_remove_bin_file(dev, &bin_attr_dimm); } #ifdef CONFIG_INET diff --git a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index 9e9e78a5c4d7..735423f7273f 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c @@ -1232,12 +1232,7 @@ qlcnic_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump) dump->len = fw_dump->tmpl_hdr->size + fw_dump->size; else dump->len = 0; - - if (!fw_dump->enable) - dump->flag = ETH_FW_DUMP_DISABLE; - else - dump->flag = fw_dump->tmpl_hdr->drv_cap_mask; - + dump->flag = fw_dump->tmpl_hdr->drv_cap_mask; dump->version = adapter->fw_version; return 0; } diff --git a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 46e77a2c5121..5c4713521d4c 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -1965,7 +1965,7 @@ qlcnic_send_filter(struct qlcnic_adapter *adapter, __le16 vlan_id = 0; u8 hindex; - if (ether_addr_equal(phdr->h_source, adapter->mac_addr)) + if (!compare_ether_addr(phdr->h_source, adapter->mac_addr)) return; if (adapter->fhash.fnum >= adapter->fhash.fmax) @@ -2235,7 +2235,8 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if (adapter->flags & QLCNIC_MACSPOOF) { phdr = (struct ethhdr *)skb->data; - if (!ether_addr_equal(phdr->h_source, adapter->mac_addr)) + if (compare_ether_addr(phdr->h_source, + adapter->mac_addr)) goto drop_packet; } diff --git a/trunk/drivers/net/ethernet/realtek/r8169.c b/trunk/drivers/net/ethernet/realtek/r8169.c index 4f74b9762c29..00628d84342f 100644 --- a/trunk/drivers/net/ethernet/realtek/r8169.c +++ b/trunk/drivers/net/ethernet/realtek/r8169.c @@ -63,12 +63,8 @@ #define R8169_MSG_DEFAULT \ (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN) -#define TX_SLOTS_AVAIL(tp) \ - (tp->dirty_tx + NUM_TX_DESC - tp->cur_tx) - -/* A skbuff with nr_frags needs nr_frags+1 entries in the tx queue */ -#define TX_FRAGS_READY_FOR(tp,nr_frags) \ - (TX_SLOTS_AVAIL(tp) >= (nr_frags + 1)) +#define TX_BUFFS_AVAIL(tp) \ + (tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1) /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). The RTL chips use a 64 element hash table based on the Ethernet CRC. */ @@ -5498,7 +5494,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, u32 opts[2]; int frags; - if (unlikely(!TX_FRAGS_READY_FOR(tp, skb_shinfo(skb)->nr_frags))) { + if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) { netif_err(tp, drv, dev, "BUG! Tx Ring full when queue awake!\n"); goto err_stop_0; } @@ -5552,7 +5548,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, mmiowb(); - if (!TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) { + if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) { /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must * not miss a ring update when it notices a stopped queue. */ @@ -5566,7 +5562,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, * can't. */ smp_mb(); - if (TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) + if (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS) netif_wake_queue(dev); } @@ -5689,7 +5685,7 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp) */ smp_mb(); if (netif_queue_stopped(dev) && - TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) { + (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)) { netif_wake_queue(dev); } /* diff --git a/trunk/drivers/net/ethernet/sfc/efx.c b/trunk/drivers/net/ethernet/sfc/efx.c index b95f2e1b33f0..3cbfbffe3f00 100644 --- a/trunk/drivers/net/ethernet/sfc/efx.c +++ b/trunk/drivers/net/ethernet/sfc/efx.c @@ -656,30 +656,25 @@ static void efx_stop_datapath(struct efx_nic *efx) struct efx_channel *channel; struct efx_tx_queue *tx_queue; struct efx_rx_queue *rx_queue; - struct pci_dev *dev = efx->pci_dev; int rc; EFX_ASSERT_RESET_SERIALISED(efx); BUG_ON(efx->port_enabled); - /* Only perform flush if dma is enabled */ - if (dev->is_busmaster) { - rc = efx_nic_flush_queues(efx); - - if (rc && EFX_WORKAROUND_7803(efx)) { - /* Schedule a reset to recover from the flush failure. The - * descriptor caches reference memory we're about to free, - * but falcon_reconfigure_mac_wrapper() won't reconnect - * the MACs because of the pending reset. */ - netif_err(efx, drv, efx->net_dev, - "Resetting to recover from flush failure\n"); - efx_schedule_reset(efx, RESET_TYPE_ALL); - } else if (rc) { - netif_err(efx, drv, efx->net_dev, "failed to flush queues\n"); - } else { - netif_dbg(efx, drv, efx->net_dev, - "successfully flushed all queues\n"); - } + rc = efx_nic_flush_queues(efx); + if (rc && EFX_WORKAROUND_7803(efx)) { + /* Schedule a reset to recover from the flush failure. The + * descriptor caches reference memory we're about to free, + * but falcon_reconfigure_mac_wrapper() won't reconnect + * the MACs because of the pending reset. */ + netif_err(efx, drv, efx->net_dev, + "Resetting to recover from flush failure\n"); + efx_schedule_reset(efx, RESET_TYPE_ALL); + } else if (rc) { + netif_err(efx, drv, efx->net_dev, "failed to flush queues\n"); + } else { + netif_dbg(efx, drv, efx->net_dev, + "successfully flushed all queues\n"); } efx_for_each_channel(channel, efx) { @@ -1354,7 +1349,7 @@ static int efx_probe_interrupts(struct efx_nic *efx) } /* RSS might be usable on VFs even if it is disabled on the PF */ - efx->rss_spread = ((efx->n_rx_channels > 1 || !efx_sriov_wanted(efx)) ? + efx->rss_spread = (efx->n_rx_channels > 1 ? efx->n_rx_channels : efx_vf_size(efx)); return 0; @@ -2497,8 +2492,8 @@ static void efx_pci_remove(struct pci_dev *pci_dev) efx_fini_io(efx); netif_dbg(efx, drv, efx->net_dev, "shutdown successful\n"); - efx_fini_struct(efx); pci_set_drvdata(pci_dev, NULL); + efx_fini_struct(efx); free_netdev(efx->net_dev); }; @@ -2700,7 +2695,6 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, fail2: efx_fini_struct(efx); fail1: - pci_set_drvdata(pci_dev, NULL); WARN_ON(rc > 0); netif_dbg(efx, drv, efx->net_dev, "initialisation failed. rc=%d\n", rc); free_netdev(net_dev); diff --git a/trunk/drivers/net/ethernet/sfc/ethtool.c b/trunk/drivers/net/ethernet/sfc/ethtool.c index 03ded364c8da..f22f45f515a8 100644 --- a/trunk/drivers/net/ethernet/sfc/ethtool.c +++ b/trunk/drivers/net/ethernet/sfc/ethtool.c @@ -1023,7 +1023,7 @@ static int efx_ethtool_set_class_rule(struct efx_nic *efx, return -EINVAL; /* Is it a default UC or MC filter? */ - if (ether_addr_equal(mac_mask->h_dest, mac_addr_mc_mask) && + if (!compare_ether_addr(mac_mask->h_dest, mac_addr_mc_mask) && vlan_tag_mask == 0) { if (is_multicast_ether_addr(mac_entry->h_dest)) rc = efx_filter_set_mc_def(&spec); @@ -1108,39 +1108,6 @@ static int efx_ethtool_set_rxfh_indir(struct net_device *net_dev, return 0; } -static int efx_ethtool_get_module_eeprom(struct net_device *net_dev, - struct ethtool_eeprom *ee, - u8 *data) -{ - struct efx_nic *efx = netdev_priv(net_dev); - int ret; - - if (!efx->phy_op || !efx->phy_op->get_module_eeprom) - return -EOPNOTSUPP; - - mutex_lock(&efx->mac_lock); - ret = efx->phy_op->get_module_eeprom(efx, ee, data); - mutex_unlock(&efx->mac_lock); - - return ret; -} - -static int efx_ethtool_get_module_info(struct net_device *net_dev, - struct ethtool_modinfo *modinfo) -{ - struct efx_nic *efx = netdev_priv(net_dev); - int ret; - - if (!efx->phy_op || !efx->phy_op->get_module_info) - return -EOPNOTSUPP; - - mutex_lock(&efx->mac_lock); - ret = efx->phy_op->get_module_info(efx, modinfo); - mutex_unlock(&efx->mac_lock); - - return ret; -} - const struct ethtool_ops efx_ethtool_ops = { .get_settings = efx_ethtool_get_settings, .set_settings = efx_ethtool_set_settings, @@ -1170,6 +1137,4 @@ const struct ethtool_ops efx_ethtool_ops = { .get_rxfh_indir_size = efx_ethtool_get_rxfh_indir_size, .get_rxfh_indir = efx_ethtool_get_rxfh_indir, .set_rxfh_indir = efx_ethtool_set_rxfh_indir, - .get_module_info = efx_ethtool_get_module_info, - .get_module_eeprom = efx_ethtool_get_module_eeprom, }; diff --git a/trunk/drivers/net/ethernet/sfc/mcdi_phy.c b/trunk/drivers/net/ethernet/sfc/mcdi_phy.c index 13cb40fe90c1..7bcad899a936 100644 --- a/trunk/drivers/net/ethernet/sfc/mcdi_phy.c +++ b/trunk/drivers/net/ethernet/sfc/mcdi_phy.c @@ -739,80 +739,6 @@ static const char *efx_mcdi_phy_test_name(struct efx_nic *efx, return NULL; } -#define SFP_PAGE_SIZE 128 -#define SFP_NUM_PAGES 2 -static int efx_mcdi_phy_get_module_eeprom(struct efx_nic *efx, - struct ethtool_eeprom *ee, u8 *data) -{ - u8 outbuf[MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMAX]; - u8 inbuf[MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN]; - size_t outlen; - int rc; - unsigned int payload_len; - unsigned int space_remaining = ee->len; - unsigned int page; - unsigned int page_off; - unsigned int to_copy; - u8 *user_data = data; - - BUILD_BUG_ON(SFP_PAGE_SIZE * SFP_NUM_PAGES != ETH_MODULE_SFF_8079_LEN); - - page_off = ee->offset % SFP_PAGE_SIZE; - page = ee->offset / SFP_PAGE_SIZE; - - while (space_remaining && (page < SFP_NUM_PAGES)) { - MCDI_SET_DWORD(inbuf, GET_PHY_MEDIA_INFO_IN_PAGE, page); - - rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_MEDIA_INFO, - inbuf, sizeof(inbuf), - outbuf, sizeof(outbuf), - &outlen); - if (rc) - return rc; - - if (outlen < (MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST + - SFP_PAGE_SIZE)) - return -EIO; - - payload_len = MCDI_DWORD(outbuf, - GET_PHY_MEDIA_INFO_OUT_DATALEN); - if (payload_len != SFP_PAGE_SIZE) - return -EIO; - - /* Copy as much as we can into data */ - payload_len -= page_off; - to_copy = (space_remaining < payload_len) ? - space_remaining : payload_len; - - memcpy(user_data, - outbuf + page_off + - MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST, - to_copy); - - space_remaining -= to_copy; - user_data += to_copy; - page_off = 0; - page++; - } - - return 0; -} - -static int efx_mcdi_phy_get_module_info(struct efx_nic *efx, - struct ethtool_modinfo *modinfo) -{ - struct efx_mcdi_phy_data *phy_cfg = efx->phy_data; - - switch (phy_cfg->media) { - case MC_CMD_MEDIA_SFP_PLUS: - modinfo->type = ETH_MODULE_SFF_8079; - modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN; - return 0; - default: - return -EOPNOTSUPP; - } -} - const struct efx_phy_operations efx_mcdi_phy_ops = { .probe = efx_mcdi_phy_probe, .init = efx_port_dummy_op_int, @@ -825,6 +751,4 @@ const struct efx_phy_operations efx_mcdi_phy_ops = { .test_alive = efx_mcdi_phy_test_alive, .run_tests = efx_mcdi_phy_run_tests, .test_name = efx_mcdi_phy_test_name, - .get_module_eeprom = efx_mcdi_phy_get_module_eeprom, - .get_module_info = efx_mcdi_phy_get_module_info, }; diff --git a/trunk/drivers/net/ethernet/sfc/net_driver.h b/trunk/drivers/net/ethernet/sfc/net_driver.h index 0e575359af17..f0385e1fb2d8 100644 --- a/trunk/drivers/net/ethernet/sfc/net_driver.h +++ b/trunk/drivers/net/ethernet/sfc/net_driver.h @@ -252,6 +252,8 @@ struct efx_rx_page_state { * @max_fill: RX descriptor maximum fill level (<= ring size) * @fast_fill_trigger: RX descriptor fill level that will trigger a fast fill * (<= @max_fill) + * @fast_fill_limit: The level to which a fast fill will fill + * (@fast_fill_trigger <= @fast_fill_limit <= @max_fill) * @min_fill: RX descriptor minimum non-zero fill level. * This records the minimum fill level observed when a ring * refill was triggered. @@ -272,6 +274,7 @@ struct efx_rx_queue { int removed_count; unsigned int max_fill; unsigned int fast_fill_trigger; + unsigned int fast_fill_limit; unsigned int min_fill; unsigned int min_overfill; unsigned int alloc_page_count; @@ -519,11 +522,6 @@ struct efx_phy_operations { int (*test_alive) (struct efx_nic *efx); const char *(*test_name) (struct efx_nic *efx, unsigned int index); int (*run_tests) (struct efx_nic *efx, int *results, unsigned flags); - int (*get_module_eeprom) (struct efx_nic *efx, - struct ethtool_eeprom *ee, - u8 *data); - int (*get_module_info) (struct efx_nic *efx, - struct ethtool_modinfo *modinfo); }; /** diff --git a/trunk/drivers/net/ethernet/sfc/qt202x_phy.c b/trunk/drivers/net/ethernet/sfc/qt202x_phy.c index 326a28637f3c..8a7caf88ffb6 100644 --- a/trunk/drivers/net/ethernet/sfc/qt202x_phy.c +++ b/trunk/drivers/net/ethernet/sfc/qt202x_phy.c @@ -449,37 +449,6 @@ static void qt202x_phy_remove(struct efx_nic *efx) efx->phy_data = NULL; } -static int qt202x_phy_get_module_info(struct efx_nic *efx, - struct ethtool_modinfo *modinfo) -{ - modinfo->type = ETH_MODULE_SFF_8079; - modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN; - return 0; -} - -static int qt202x_phy_get_module_eeprom(struct efx_nic *efx, - struct ethtool_eeprom *ee, u8 *data) -{ - int mmd, reg_base, rc, i; - - if (efx->phy_type == PHY_TYPE_QT2025C) { - mmd = MDIO_MMD_PCS; - reg_base = 0xd000; - } else { - mmd = MDIO_MMD_PMAPMD; - reg_base = 0x8007; - } - - for (i = 0; i < ee->len; i++) { - rc = efx_mdio_read(efx, mmd, reg_base + ee->offset + i); - if (rc < 0) - return rc; - data[i] = rc; - } - - return 0; -} - const struct efx_phy_operations falcon_qt202x_phy_ops = { .probe = qt202x_phy_probe, .init = qt202x_phy_init, @@ -490,6 +459,4 @@ const struct efx_phy_operations falcon_qt202x_phy_ops = { .get_settings = qt202x_phy_get_settings, .set_settings = efx_mdio_set_settings, .test_alive = efx_mdio_test_alive, - .get_module_eeprom = qt202x_phy_get_module_eeprom, - .get_module_info = qt202x_phy_get_module_info, }; diff --git a/trunk/drivers/net/ethernet/sfc/rx.c b/trunk/drivers/net/ethernet/sfc/rx.c index 243e91f3dff9..763fa2fe1a38 100644 --- a/trunk/drivers/net/ethernet/sfc/rx.c +++ b/trunk/drivers/net/ethernet/sfc/rx.c @@ -76,7 +76,12 @@ static int rx_alloc_method = RX_ALLOC_METHOD_AUTO; /* This is the percentage fill level below which new RX descriptors * will be added to the RX descriptor ring. */ -static unsigned int rx_refill_threshold; +static unsigned int rx_refill_threshold = 90; + +/* This is the percentage fill level to which an RX queue will be refilled + * when the "RX refill threshold" is reached. + */ +static unsigned int rx_refill_limit = 95; /* * RX maximum head room required. @@ -337,7 +342,7 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel, * efx_fast_push_rx_descriptors - push new RX descriptors quickly * @rx_queue: RX descriptor queue * This will aim to fill the RX descriptor queue up to - * @rx_queue->@max_fill. If there is insufficient atomic + * @rx_queue->@fast_fill_limit. If there is insufficient atomic * memory to do so, a slow fill will be scheduled. * * The caller must provide serialisation (none is used here). In practise, @@ -362,14 +367,15 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) rx_queue->min_fill = fill_level; } - space = rx_queue->max_fill - fill_level; - EFX_BUG_ON_PARANOID(space < EFX_RX_BATCH); + space = rx_queue->fast_fill_limit - fill_level; + if (space < EFX_RX_BATCH) + goto out; netif_vdbg(rx_queue->efx, rx_status, rx_queue->efx->net_dev, "RX queue %d fast-filling descriptor ring from" " level %d to level %d using %s allocation\n", efx_rx_queue_index(rx_queue), fill_level, - rx_queue->max_fill, + rx_queue->fast_fill_limit, channel->rx_alloc_push_pages ? "page" : "skb"); do { @@ -675,7 +681,7 @@ int efx_probe_rx_queue(struct efx_rx_queue *rx_queue) void efx_init_rx_queue(struct efx_rx_queue *rx_queue) { struct efx_nic *efx = rx_queue->efx; - unsigned int max_fill, trigger, max_trigger; + unsigned int max_fill, trigger, limit; netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev, "initialising RX queue %d\n", efx_rx_queue_index(rx_queue)); @@ -688,17 +694,12 @@ void efx_init_rx_queue(struct efx_rx_queue *rx_queue) /* Initialise limit fields */ max_fill = efx->rxq_entries - EFX_RXD_HEAD_ROOM; - max_trigger = max_fill - EFX_RX_BATCH; - if (rx_refill_threshold != 0) { - trigger = max_fill * min(rx_refill_threshold, 100U) / 100U; - if (trigger > max_trigger) - trigger = max_trigger; - } else { - trigger = max_trigger; - } + trigger = max_fill * min(rx_refill_threshold, 100U) / 100U; + limit = max_fill * min(rx_refill_limit, 100U) / 100U; rx_queue->max_fill = max_fill; rx_queue->fast_fill_trigger = trigger; + rx_queue->fast_fill_limit = limit; /* Set up RX descriptor ring */ rx_queue->enabled = true; @@ -745,5 +746,5 @@ MODULE_PARM_DESC(rx_alloc_method, "Allocation method used for RX buffers"); module_param(rx_refill_threshold, uint, 0444); MODULE_PARM_DESC(rx_refill_threshold, - "RX descriptor ring refill threshold (%)"); + "RX descriptor ring fast/slow fill threshold (%)"); diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/common.h b/trunk/drivers/net/ethernet/stmicro/stmmac/common.h index bcd54d6e94fd..f5dedcbf4651 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/common.h @@ -247,8 +247,8 @@ struct stmmac_desc_ops { struct stmmac_dma_ops { /* DMA core initialization */ - int (*init) (void __iomem *ioaddr, int pbl, int fb, int mb, - int burst_len, u32 dma_tx, u32 dma_rx); + int (*init) (void __iomem *ioaddr, int pbl, int fb, int burst_len, + u32 dma_tx, u32 dma_rx); /* Dump DMA registers */ void (*dump_regs) (void __iomem *ioaddr); /* Set tx/rx threshold in the csr6 register @@ -280,7 +280,7 @@ struct stmmac_ops { /* Handle extra events on specific interrupts hw dependent */ void (*host_irq_status) (void __iomem *ioaddr); /* Multicast filter setting */ - void (*set_filter) (struct net_device *dev, int id); + void (*set_filter) (struct net_device *dev); /* Flow control setting */ void (*flow_ctrl) (void __iomem *ioaddr, unsigned int duplex, unsigned int fc, unsigned int pause_time); diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h index 23478bf4ed7a..54339a78e358 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h @@ -61,11 +61,9 @@ enum power_event { }; /* GMAC HW ADDR regs */ -#define GMAC_ADDR_HIGH(reg) (((reg > 15) ? 0x00000800 : 0x00000040) + \ - (reg * 8)) -#define GMAC_ADDR_LOW(reg) (((reg > 15) ? 0x00000804 : 0x00000044) + \ - (reg * 8)) -#define GMAC_MAX_PERFECT_ADDRESSES 32 +#define GMAC_ADDR_HIGH(reg) (0x00000040+(reg * 8)) +#define GMAC_ADDR_LOW(reg) (0x00000044+(reg * 8)) +#define GMAC_MAX_UNICAST_ADDRESSES 16 #define GMAC_AN_CTRL 0x000000c0 /* AN control */ #define GMAC_AN_STATUS 0x000000c4 /* AN status */ @@ -141,7 +139,6 @@ enum rx_tx_priority_ratio { }; #define DMA_BUS_MODE_FB 0x00010000 /* Fixed burst */ -#define DMA_BUS_MODE_MB 0x04000000 /* Mixed burst */ #define DMA_BUS_MODE_RPBL_MASK 0x003e0000 /* Rx-Programmable Burst Len */ #define DMA_BUS_MODE_RPBL_SHIFT 17 #define DMA_BUS_MODE_USP 0x00800000 @@ -208,7 +205,4 @@ enum rtc_control { #define GMAC_MMC_TX_INTR 0x108 #define GMAC_MMC_RX_CSUM_OFFLOAD 0x208 -/* Synopsys Core versions */ -#define DWMAC_CORE_3_40 34 - extern const struct stmmac_dma_ops dwmac1000_dma_ops; diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index b5e4d02f15c9..e7cbcd99c2cb 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -84,11 +84,10 @@ static void dwmac1000_get_umac_addr(void __iomem *ioaddr, unsigned char *addr, GMAC_ADDR_LOW(reg_n)); } -static void dwmac1000_set_filter(struct net_device *dev, int id) +static void dwmac1000_set_filter(struct net_device *dev) { void __iomem *ioaddr = (void __iomem *) dev->base_addr; unsigned int value = 0; - unsigned int perfect_addr_number; CHIP_DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n", __func__, netdev_mc_count(dev), netdev_uc_count(dev)); @@ -122,14 +121,8 @@ static void dwmac1000_set_filter(struct net_device *dev, int id) writel(mc_filter[1], ioaddr + GMAC_HASH_HIGH); } - /* Extra 16 regs are available in cores newer than the 3.40. */ - if (id > DWMAC_CORE_3_40) - perfect_addr_number = GMAC_MAX_PERFECT_ADDRESSES; - else - perfect_addr_number = GMAC_MAX_PERFECT_ADDRESSES / 2; - /* Handle multiple unicast addresses (perfect filtering)*/ - if (netdev_uc_count(dev) > perfect_addr_number) + if (netdev_uc_count(dev) > GMAC_MAX_UNICAST_ADDRESSES) /* Switch to promiscuous mode is more than 16 addrs are required */ value |= GMAC_FRAME_FILTER_PR; diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c index 033500090f55..3675c5731565 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c @@ -31,7 +31,7 @@ #include "dwmac_dma.h" static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb, - int mb, int burst_len, u32 dma_tx, u32 dma_rx) + int burst_len, u32 dma_tx, u32 dma_rx) { u32 value = readl(ioaddr + DMA_BUS_MODE); int limit; @@ -66,10 +66,6 @@ static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb, if (fb) value |= DMA_BUS_MODE_FB; - /* Mixed Burst has no effect when fb is set */ - if (mb) - value |= DMA_BUS_MODE_MB; - #ifdef CONFIG_STMMAC_DA value |= DMA_BUS_MODE_DA; /* Rx has priority over tx */ #endif diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c index 19e0f4eed2bc..efde50ff03f8 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c @@ -89,7 +89,7 @@ static void dwmac100_get_umac_addr(void __iomem *ioaddr, unsigned char *addr, stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW); } -static void dwmac100_set_filter(struct net_device *dev, int id) +static void dwmac100_set_filter(struct net_device *dev) { void __iomem *ioaddr = (void __iomem *) dev->base_addr; u32 value = readl(ioaddr + MAC_CONTROL); diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c b/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c index c2b4d55a79b6..92ed2e07609e 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c @@ -33,7 +33,7 @@ #include "dwmac_dma.h" static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, int fb, - int mb, int burst_len, u32 dma_tx, u32 dma_rx) + int burst_len, u32 dma_tx, u32 dma_rx) { u32 value = readl(ioaddr + DMA_BUS_MODE); int limit; diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c index 4e0e18a44fcc..f20aa12931d0 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c @@ -31,8 +31,6 @@ #define DWMAC_LIB_DBG(fmt, args...) do { } while (0) #endif -#define GMAC_HI_REG_AE 0x80000000 - /* CSR1 enables the transmit DMA to check for new descriptor */ void dwmac_enable_dma_transmission(void __iomem *ioaddr) { @@ -235,11 +233,7 @@ void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6], unsigned long data; data = (addr[5] << 8) | addr[4]; - /* For MAC Addr registers se have to set the Address Enable (AE) - * bit that has no effect on the High Reg 0 where the bit 31 (MO) - * is RO. - */ - writel(data | GMAC_HI_REG_AE, ioaddr + high); + writel(data, ioaddr + high); data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0]; writel(data, ioaddr + low); } diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 6b5d060ee9de..db2de9a49952 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -85,7 +85,6 @@ struct stmmac_priv { struct clk *stmmac_clk; #endif int clk_csr; - int synopsys_id; }; extern int phyaddr; diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 70966330f44e..1a4cf8128f91 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -925,7 +925,6 @@ static void stmmac_check_ether_addr(struct stmmac_priv *priv) static int stmmac_init_dma_engine(struct stmmac_priv *priv) { int pbl = DEFAULT_DMA_PBL, fixed_burst = 0, burst_len = 0; - int mixed_burst = 0; /* Some DMA parameters can be passed from the platform; * in case of these are not passed we keep a default @@ -933,11 +932,10 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv) if (priv->plat->dma_cfg) { pbl = priv->plat->dma_cfg->pbl; fixed_burst = priv->plat->dma_cfg->fixed_burst; - mixed_burst = priv->plat->dma_cfg->mixed_burst; burst_len = priv->plat->dma_cfg->burst_len; } - return priv->hw->dma->init(priv->ioaddr, pbl, fixed_burst, mixed_burst, + return priv->hw->dma->init(priv->ioaddr, pbl, fixed_burst, burst_len, priv->dma_tx_phy, priv->dma_rx_phy); } @@ -1467,7 +1465,7 @@ static void stmmac_set_rx_mode(struct net_device *dev) struct stmmac_priv *priv = netdev_priv(dev); spin_lock(&priv->lock); - priv->hw->mac->set_filter(dev, priv->synopsys_id); + priv->hw->mac->set_filter(dev); spin_unlock(&priv->lock); } @@ -1640,7 +1638,7 @@ static const struct file_operations stmmac_rings_status_fops = { .open = stmmac_sysfs_ring_open, .read = seq_read, .llseek = seq_lseek, - .release = single_release, + .release = seq_release, }; static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v) @@ -1712,7 +1710,7 @@ static const struct file_operations stmmac_dma_cap_fops = { .open = stmmac_sysfs_dma_cap_open, .read = seq_read, .llseek = seq_lseek, - .release = single_release, + .release = seq_release, }; static int stmmac_init_fs(struct net_device *dev) @@ -1808,7 +1806,7 @@ static int stmmac_hw_init(struct stmmac_priv *priv) priv->hw->ring = &ring_mode_ops; /* Get and dump the chip ID */ - priv->synopsys_id = stmmac_get_synopsys_id(priv); + stmmac_get_synopsys_id(priv); /* Get the HW capability (new GMAC newer than 3.50a) */ priv->hw_cap_support = stmmac_get_hw_features(priv); @@ -1989,7 +1987,6 @@ int stmmac_suspend(struct net_device *ndev) { struct stmmac_priv *priv = netdev_priv(ndev); int dis_ic = 0; - unsigned long flags; if (!ndev || !netif_running(ndev)) return 0; @@ -1997,7 +1994,7 @@ int stmmac_suspend(struct net_device *ndev) if (priv->phydev) phy_stop(priv->phydev); - spin_lock_irqsave(&priv->lock, flags); + spin_lock(&priv->lock); netif_device_detach(ndev); netif_stop_queue(ndev); @@ -2025,19 +2022,18 @@ int stmmac_suspend(struct net_device *ndev) /* Disable clock in case of PWM is off */ stmmac_clk_disable(priv); } - spin_unlock_irqrestore(&priv->lock, flags); + spin_unlock(&priv->lock); return 0; } int stmmac_resume(struct net_device *ndev) { struct stmmac_priv *priv = netdev_priv(ndev); - unsigned long flags; if (!netif_running(ndev)) return 0; - spin_lock_irqsave(&priv->lock, flags); + spin_lock(&priv->lock); /* Power Down bit, into the PM register, is cleared * automatically as soon as a magic packet or a Wake-up frame @@ -2065,7 +2061,7 @@ int stmmac_resume(struct net_device *ndev) netif_start_queue(ndev); - spin_unlock_irqrestore(&priv->lock, flags); + spin_unlock(&priv->lock); if (priv->phydev) phy_start(priv->phydev); diff --git a/trunk/drivers/net/ethernet/sun/sunvnet.c b/trunk/drivers/net/ethernet/sun/sunvnet.c index a108db35924e..38e3ae9155b7 100644 --- a/trunk/drivers/net/ethernet/sun/sunvnet.c +++ b/trunk/drivers/net/ethernet/sun/sunvnet.c @@ -618,7 +618,7 @@ struct vnet_port *__tx_port_find(struct vnet *vp, struct sk_buff *skb) struct vnet_port *port; hlist_for_each_entry(port, n, hp, hash) { - if (ether_addr_equal(port->raddr, skb->data)) + if (!compare_ether_addr(port->raddr, skb->data)) return port; } port = NULL; diff --git a/trunk/drivers/net/ethernet/tile/tilepro.c b/trunk/drivers/net/ethernet/tile/tilepro.c index 96070e9b50dc..3d501ec7fad7 100644 --- a/trunk/drivers/net/ethernet/tile/tilepro.c +++ b/trunk/drivers/net/ethernet/tile/tilepro.c @@ -843,7 +843,7 @@ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index) if (!is_multicast_ether_addr(buf)) { /* Filter packets not for our address. */ const u8 *mine = dev->dev_addr; - filter = !ether_addr_equal(mine, buf); + filter = compare_ether_addr(mine, buf); } } diff --git a/trunk/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c b/trunk/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c index 961c8321451f..5c14f82c4954 100644 --- a/trunk/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c +++ b/trunk/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c @@ -1590,8 +1590,8 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl) found = 0; oldest = NULL; list_for_each_entry(target, &wl->network_list, list) { - if (ether_addr_equal(&target->hwinfo->bssid[2], - &scan_info->bssid[2])) { + if (!compare_ether_addr(&target->hwinfo->bssid[2], + &scan_info->bssid[2])) { found = 1; pr_debug("%s: same BBS found scanned list\n", __func__); @@ -1691,8 +1691,8 @@ struct gelic_wl_scan_info *gelic_wl_find_best_bss(struct gelic_wl_info *wl) /* If bss specified, check it only */ if (test_bit(GELIC_WL_STAT_BSSID_SET, &wl->stat)) { - if (ether_addr_equal(&scan_info->hwinfo->bssid[2], - wl->bssid)) { + if (!compare_ether_addr(&scan_info->hwinfo->bssid[2], + wl->bssid)) { best_bss = scan_info; pr_debug("%s: bssid matched\n", __func__); break; diff --git a/trunk/drivers/net/hyperv/hyperv_net.h b/trunk/drivers/net/hyperv/hyperv_net.h index 4ffcd57b011b..c35824552792 100644 --- a/trunk/drivers/net/hyperv/hyperv_net.h +++ b/trunk/drivers/net/hyperv/hyperv_net.h @@ -27,7 +27,6 @@ #include #include -#include /* Fwd declaration */ struct hv_netvsc_packet; @@ -507,6 +506,295 @@ struct netvsc_device { void *extension; }; + +/* Status codes */ + + +#ifndef STATUS_SUCCESS +#define STATUS_SUCCESS (0x00000000L) +#endif + +#ifndef STATUS_UNSUCCESSFUL +#define STATUS_UNSUCCESSFUL (0xC0000001L) +#endif + +#ifndef STATUS_PENDING +#define STATUS_PENDING (0x00000103L) +#endif + +#ifndef STATUS_INSUFFICIENT_RESOURCES +#define STATUS_INSUFFICIENT_RESOURCES (0xC000009AL) +#endif + +#ifndef STATUS_BUFFER_OVERFLOW +#define STATUS_BUFFER_OVERFLOW (0x80000005L) +#endif + +#ifndef STATUS_NOT_SUPPORTED +#define STATUS_NOT_SUPPORTED (0xC00000BBL) +#endif + +#define RNDIS_STATUS_SUCCESS (STATUS_SUCCESS) +#define RNDIS_STATUS_PENDING (STATUS_PENDING) +#define RNDIS_STATUS_NOT_RECOGNIZED (0x00010001L) +#define RNDIS_STATUS_NOT_COPIED (0x00010002L) +#define RNDIS_STATUS_NOT_ACCEPTED (0x00010003L) +#define RNDIS_STATUS_CALL_ACTIVE (0x00010007L) + +#define RNDIS_STATUS_ONLINE (0x40010003L) +#define RNDIS_STATUS_RESET_START (0x40010004L) +#define RNDIS_STATUS_RESET_END (0x40010005L) +#define RNDIS_STATUS_RING_STATUS (0x40010006L) +#define RNDIS_STATUS_CLOSED (0x40010007L) +#define RNDIS_STATUS_WAN_LINE_UP (0x40010008L) +#define RNDIS_STATUS_WAN_LINE_DOWN (0x40010009L) +#define RNDIS_STATUS_WAN_FRAGMENT (0x4001000AL) +#define RNDIS_STATUS_MEDIA_CONNECT (0x4001000BL) +#define RNDIS_STATUS_MEDIA_DISCONNECT (0x4001000CL) +#define RNDIS_STATUS_HARDWARE_LINE_UP (0x4001000DL) +#define RNDIS_STATUS_HARDWARE_LINE_DOWN (0x4001000EL) +#define RNDIS_STATUS_INTERFACE_UP (0x4001000FL) +#define RNDIS_STATUS_INTERFACE_DOWN (0x40010010L) +#define RNDIS_STATUS_MEDIA_BUSY (0x40010011L) +#define RNDIS_STATUS_MEDIA_SPECIFIC_INDICATION (0x40010012L) +#define RNDIS_STATUS_WW_INDICATION RDIA_SPECIFIC_INDICATION +#define RNDIS_STATUS_LINK_SPEED_CHANGE (0x40010013L) + +#define RNDIS_STATUS_NOT_RESETTABLE (0x80010001L) +#define RNDIS_STATUS_SOFT_ERRORS (0x80010003L) +#define RNDIS_STATUS_HARD_ERRORS (0x80010004L) +#define RNDIS_STATUS_BUFFER_OVERFLOW (STATUS_BUFFER_OVERFLOW) + +#define RNDIS_STATUS_FAILURE (STATUS_UNSUCCESSFUL) +#define RNDIS_STATUS_RESOURCES (STATUS_INSUFFICIENT_RESOURCES) +#define RNDIS_STATUS_CLOSING (0xC0010002L) +#define RNDIS_STATUS_BAD_VERSION (0xC0010004L) +#define RNDIS_STATUS_BAD_CHARACTERISTICS (0xC0010005L) +#define RNDIS_STATUS_ADAPTER_NOT_FOUND (0xC0010006L) +#define RNDIS_STATUS_OPEN_FAILED (0xC0010007L) +#define RNDIS_STATUS_DEVICE_FAILED (0xC0010008L) +#define RNDIS_STATUS_MULTICAST_FULL (0xC0010009L) +#define RNDIS_STATUS_MULTICAST_EXISTS (0xC001000AL) +#define RNDIS_STATUS_MULTICAST_NOT_FOUND (0xC001000BL) +#define RNDIS_STATUS_REQUEST_ABORTED (0xC001000CL) +#define RNDIS_STATUS_RESET_IN_PROGRESS (0xC001000DL) +#define RNDIS_STATUS_CLOSING_INDICATING (0xC001000EL) +#define RNDIS_STATUS_NOT_SUPPORTED (STATUS_NOT_SUPPORTED) +#define RNDIS_STATUS_INVALID_PACKET (0xC001000FL) +#define RNDIS_STATUS_OPEN_LIST_FULL (0xC0010010L) +#define RNDIS_STATUS_ADAPTER_NOT_READY (0xC0010011L) +#define RNDIS_STATUS_ADAPTER_NOT_OPEN (0xC0010012L) +#define RNDIS_STATUS_NOT_INDICATING (0xC0010013L) +#define RNDIS_STATUS_INVALID_LENGTH (0xC0010014L) +#define RNDIS_STATUS_INVALID_DATA (0xC0010015L) +#define RNDIS_STATUS_BUFFER_TOO_SHORT (0xC0010016L) +#define RNDIS_STATUS_INVALID_OID (0xC0010017L) +#define RNDIS_STATUS_ADAPTER_REMOVED (0xC0010018L) +#define RNDIS_STATUS_UNSUPPORTED_MEDIA (0xC0010019L) +#define RNDIS_STATUS_GROUP_ADDRESS_IN_USE (0xC001001AL) +#define RNDIS_STATUS_FILE_NOT_FOUND (0xC001001BL) +#define RNDIS_STATUS_ERROR_READING_FILE (0xC001001CL) +#define RNDIS_STATUS_ALREADY_MAPPED (0xC001001DL) +#define RNDIS_STATUS_RESOURCE_CONFLICT (0xC001001EL) +#define RNDIS_STATUS_NO_CABLE (0xC001001FL) + +#define RNDIS_STATUS_INVALID_SAP (0xC0010020L) +#define RNDIS_STATUS_SAP_IN_USE (0xC0010021L) +#define RNDIS_STATUS_INVALID_ADDRESS (0xC0010022L) +#define RNDIS_STATUS_VC_NOT_ACTIVATED (0xC0010023L) +#define RNDIS_STATUS_DEST_OUT_OF_ORDER (0xC0010024L) +#define RNDIS_STATUS_VC_NOT_AVAILABLE (0xC0010025L) +#define RNDIS_STATUS_CELLRATE_NOT_AVAILABLE (0xC0010026L) +#define RNDIS_STATUS_INCOMPATABLE_QOS (0xC0010027L) +#define RNDIS_STATUS_AAL_PARAMS_UNSUPPORTED (0xC0010028L) +#define RNDIS_STATUS_NO_ROUTE_TO_DESTINATION (0xC0010029L) + +#define RNDIS_STATUS_TOKEN_RING_OPEN_ERROR (0xC0011000L) + +/* Object Identifiers used by NdisRequest Query/Set Information */ +/* General Objects */ +#define RNDIS_OID_GEN_SUPPORTED_LIST 0x00010101 +#define RNDIS_OID_GEN_HARDWARE_STATUS 0x00010102 +#define RNDIS_OID_GEN_MEDIA_SUPPORTED 0x00010103 +#define RNDIS_OID_GEN_MEDIA_IN_USE 0x00010104 +#define RNDIS_OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 +#define RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 +#define RNDIS_OID_GEN_LINK_SPEED 0x00010107 +#define RNDIS_OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 +#define RNDIS_OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 +#define RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A +#define RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B +#define RNDIS_OID_GEN_VENDOR_ID 0x0001010C +#define RNDIS_OID_GEN_VENDOR_DESCRIPTION 0x0001010D +#define RNDIS_OID_GEN_CURRENT_PACKET_FILTER 0x0001010E +#define RNDIS_OID_GEN_CURRENT_LOOKAHEAD 0x0001010F +#define RNDIS_OID_GEN_DRIVER_VERSION 0x00010110 +#define RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 +#define RNDIS_OID_GEN_PROTOCOL_OPTIONS 0x00010112 +#define RNDIS_OID_GEN_MAC_OPTIONS 0x00010113 +#define RNDIS_OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 +#define RNDIS_OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 +#define RNDIS_OID_GEN_VENDOR_DRIVER_VERSION 0x00010116 +#define RNDIS_OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118 +#define RNDIS_OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119 +#define RNDIS_OID_GEN_MACHINE_NAME 0x0001021A +#define RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B + +#define RNDIS_OID_GEN_XMIT_OK 0x00020101 +#define RNDIS_OID_GEN_RCV_OK 0x00020102 +#define RNDIS_OID_GEN_XMIT_ERROR 0x00020103 +#define RNDIS_OID_GEN_RCV_ERROR 0x00020104 +#define RNDIS_OID_GEN_RCV_NO_BUFFER 0x00020105 + +#define RNDIS_OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 +#define RNDIS_OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 +#define RNDIS_OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 +#define RNDIS_OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 +#define RNDIS_OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 +#define RNDIS_OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 +#define RNDIS_OID_GEN_DIRECTED_BYTES_RCV 0x00020207 +#define RNDIS_OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 +#define RNDIS_OID_GEN_MULTICAST_BYTES_RCV 0x00020209 +#define RNDIS_OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A +#define RNDIS_OID_GEN_BROADCAST_BYTES_RCV 0x0002020B +#define RNDIS_OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C + +#define RNDIS_OID_GEN_RCV_CRC_ERROR 0x0002020D +#define RNDIS_OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E + +#define RNDIS_OID_GEN_GET_TIME_CAPS 0x0002020F +#define RNDIS_OID_GEN_GET_NETCARD_TIME 0x00020210 + +/* These are connection-oriented general OIDs. */ +/* These replace the above OIDs for connection-oriented media. */ +#define RNDIS_OID_GEN_CO_SUPPORTED_LIST 0x00010101 +#define RNDIS_OID_GEN_CO_HARDWARE_STATUS 0x00010102 +#define RNDIS_OID_GEN_CO_MEDIA_SUPPORTED 0x00010103 +#define RNDIS_OID_GEN_CO_MEDIA_IN_USE 0x00010104 +#define RNDIS_OID_GEN_CO_LINK_SPEED 0x00010105 +#define RNDIS_OID_GEN_CO_VENDOR_ID 0x00010106 +#define RNDIS_OID_GEN_CO_VENDOR_DESCRIPTION 0x00010107 +#define RNDIS_OID_GEN_CO_DRIVER_VERSION 0x00010108 +#define RNDIS_OID_GEN_CO_PROTOCOL_OPTIONS 0x00010109 +#define RNDIS_OID_GEN_CO_MAC_OPTIONS 0x0001010A +#define RNDIS_OID_GEN_CO_MEDIA_CONNECT_STATUS 0x0001010B +#define RNDIS_OID_GEN_CO_VENDOR_DRIVER_VERSION 0x0001010C +#define RNDIS_OID_GEN_CO_MINIMUM_LINK_SPEED 0x0001010D + +#define RNDIS_OID_GEN_CO_GET_TIME_CAPS 0x00010201 +#define RNDIS_OID_GEN_CO_GET_NETCARD_TIME 0x00010202 + +/* These are connection-oriented statistics OIDs. */ +#define RNDIS_OID_GEN_CO_XMIT_PDUS_OK 0x00020101 +#define RNDIS_OID_GEN_CO_RCV_PDUS_OK 0x00020102 +#define RNDIS_OID_GEN_CO_XMIT_PDUS_ERROR 0x00020103 +#define RNDIS_OID_GEN_CO_RCV_PDUS_ERROR 0x00020104 +#define RNDIS_OID_GEN_CO_RCV_PDUS_NO_BUFFER 0x00020105 + + +#define RNDIS_OID_GEN_CO_RCV_CRC_ERROR 0x00020201 +#define RNDIS_OID_GEN_CO_TRANSMIT_QUEUE_LENGTH 0x00020202 +#define RNDIS_OID_GEN_CO_BYTES_XMIT 0x00020203 +#define RNDIS_OID_GEN_CO_BYTES_RCV 0x00020204 +#define RNDIS_OID_GEN_CO_BYTES_XMIT_OUTSTANDING 0x00020205 +#define RNDIS_OID_GEN_CO_NETCARD_LOAD 0x00020206 + +/* These are objects for Connection-oriented media call-managers. */ +#define RNDIS_OID_CO_ADD_PVC 0xFF000001 +#define RNDIS_OID_CO_DELETE_PVC 0xFF000002 +#define RNDIS_OID_CO_GET_CALL_INFORMATION 0xFF000003 +#define RNDIS_OID_CO_ADD_ADDRESS 0xFF000004 +#define RNDIS_OID_CO_DELETE_ADDRESS 0xFF000005 +#define RNDIS_OID_CO_GET_ADDRESSES 0xFF000006 +#define RNDIS_OID_CO_ADDRESS_CHANGE 0xFF000007 +#define RNDIS_OID_CO_SIGNALING_ENABLED 0xFF000008 +#define RNDIS_OID_CO_SIGNALING_DISABLED 0xFF000009 + +/* 802.3 Objects (Ethernet) */ +#define RNDIS_OID_802_3_PERMANENT_ADDRESS 0x01010101 +#define RNDIS_OID_802_3_CURRENT_ADDRESS 0x01010102 +#define RNDIS_OID_802_3_MULTICAST_LIST 0x01010103 +#define RNDIS_OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 +#define RNDIS_OID_802_3_MAC_OPTIONS 0x01010105 + +#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001 + +#define RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 +#define RNDIS_OID_802_3_XMIT_ONE_COLLISION 0x01020102 +#define RNDIS_OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 + +#define RNDIS_OID_802_3_XMIT_DEFERRED 0x01020201 +#define RNDIS_OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 +#define RNDIS_OID_802_3_RCV_OVERRUN 0x01020203 +#define RNDIS_OID_802_3_XMIT_UNDERRUN 0x01020204 +#define RNDIS_OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 +#define RNDIS_OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 +#define RNDIS_OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 + +/* Remote NDIS message types */ +#define REMOTE_NDIS_PACKET_MSG 0x00000001 +#define REMOTE_NDIS_INITIALIZE_MSG 0x00000002 +#define REMOTE_NDIS_HALT_MSG 0x00000003 +#define REMOTE_NDIS_QUERY_MSG 0x00000004 +#define REMOTE_NDIS_SET_MSG 0x00000005 +#define REMOTE_NDIS_RESET_MSG 0x00000006 +#define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007 +#define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008 + +#define REMOTE_CONDIS_MP_CREATE_VC_MSG 0x00008001 +#define REMOTE_CONDIS_MP_DELETE_VC_MSG 0x00008002 +#define REMOTE_CONDIS_MP_ACTIVATE_VC_MSG 0x00008005 +#define REMOTE_CONDIS_MP_DEACTIVATE_VC_MSG 0x00008006 +#define REMOTE_CONDIS_INDICATE_STATUS_MSG 0x00008007 + +/* Remote NDIS message completion types */ +#define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002 +#define REMOTE_NDIS_QUERY_CMPLT 0x80000004 +#define REMOTE_NDIS_SET_CMPLT 0x80000005 +#define REMOTE_NDIS_RESET_CMPLT 0x80000006 +#define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008 + +#define REMOTE_CONDIS_MP_CREATE_VC_CMPLT 0x80008001 +#define REMOTE_CONDIS_MP_DELETE_VC_CMPLT 0x80008002 +#define REMOTE_CONDIS_MP_ACTIVATE_VC_CMPLT 0x80008005 +#define REMOTE_CONDIS_MP_DEACTIVATE_VC_CMPLT 0x80008006 + +/* + * Reserved message type for private communication between lower-layer host + * driver and remote device, if necessary. + */ +#define REMOTE_NDIS_BUS_MSG 0xff000001 + +/* Defines for DeviceFlags in struct rndis_initialize_complete */ +#define RNDIS_DF_CONNECTIONLESS 0x00000001 +#define RNDIS_DF_CONNECTION_ORIENTED 0x00000002 +#define RNDIS_DF_RAW_DATA 0x00000004 + +/* Remote NDIS medium types. */ +#define RNDIS_MEDIUM_802_3 0x00000000 +#define RNDIS_MEDIUM_802_5 0x00000001 +#define RNDIS_MEDIUM_FDDI 0x00000002 +#define RNDIS_MEDIUM_WAN 0x00000003 +#define RNDIS_MEDIUM_LOCAL_TALK 0x00000004 +#define RNDIS_MEDIUM_ARCNET_RAW 0x00000006 +#define RNDIS_MEDIUM_ARCNET_878_2 0x00000007 +#define RNDIS_MEDIUM_ATM 0x00000008 +#define RNDIS_MEDIUM_WIRELESS_WAN 0x00000009 +#define RNDIS_MEDIUM_IRDA 0x0000000a +#define RNDIS_MEDIUM_CO_WAN 0x0000000b +/* Not a real medium, defined as an upper-bound */ +#define RNDIS_MEDIUM_MAX 0x0000000d + + +/* Remote NDIS medium connection states. */ +#define RNDIS_MEDIA_STATE_CONNECTED 0x00000000 +#define RNDIS_MEDIA_STATE_DISCONNECTED 0x00000001 + +/* Remote NDIS version numbers */ +#define RNDIS_MAJOR_VERSION 0x00000001 +#define RNDIS_MINOR_VERSION 0x00000000 + + /* NdisInitialize message */ struct rndis_initialize_request { u32 req_id; diff --git a/trunk/drivers/net/hyperv/rndis_filter.c b/trunk/drivers/net/hyperv/rndis_filter.c index 981ebb115637..d6be64bcefd4 100644 --- a/trunk/drivers/net/hyperv/rndis_filter.c +++ b/trunk/drivers/net/hyperv/rndis_filter.c @@ -129,8 +129,8 @@ static void dump_rndis_message(struct hv_device *hv_dev, netdev = net_device->ndev; switch (rndis_msg->ndis_msg_type) { - case RNDIS_MSG_PACKET: - netdev_dbg(netdev, "RNDIS_MSG_PACKET (len %u, " + case REMOTE_NDIS_PACKET_MSG: + netdev_dbg(netdev, "REMOTE_NDIS_PACKET_MSG (len %u, " "data offset %u data len %u, # oob %u, " "oob offset %u, oob len %u, pkt offset %u, " "pkt len %u\n", @@ -144,8 +144,8 @@ static void dump_rndis_message(struct hv_device *hv_dev, rndis_msg->msg.pkt.per_pkt_info_len); break; - case RNDIS_MSG_INIT_C: - netdev_dbg(netdev, "RNDIS_MSG_INIT_C " + case REMOTE_NDIS_INITIALIZE_CMPLT: + netdev_dbg(netdev, "REMOTE_NDIS_INITIALIZE_CMPLT " "(len %u, id 0x%x, status 0x%x, major %d, minor %d, " "device flags %d, max xfer size 0x%x, max pkts %u, " "pkt aligned %u)\n", @@ -162,8 +162,8 @@ static void dump_rndis_message(struct hv_device *hv_dev, pkt_alignment_factor); break; - case RNDIS_MSG_QUERY_C: - netdev_dbg(netdev, "RNDIS_MSG_QUERY_C " + case REMOTE_NDIS_QUERY_CMPLT: + netdev_dbg(netdev, "REMOTE_NDIS_QUERY_CMPLT " "(len %u, id 0x%x, status 0x%x, buf len %u, " "buf offset %u)\n", rndis_msg->msg_len, @@ -175,16 +175,16 @@ static void dump_rndis_message(struct hv_device *hv_dev, info_buf_offset); break; - case RNDIS_MSG_SET_C: + case REMOTE_NDIS_SET_CMPLT: netdev_dbg(netdev, - "RNDIS_MSG_SET_C (len %u, id 0x%x, status 0x%x)\n", + "REMOTE_NDIS_SET_CMPLT (len %u, id 0x%x, status 0x%x)\n", rndis_msg->msg_len, rndis_msg->msg.set_complete.req_id, rndis_msg->msg.set_complete.status); break; - case RNDIS_MSG_INDICATE: - netdev_dbg(netdev, "RNDIS_MSG_INDICATE " + case REMOTE_NDIS_INDICATE_STATUS_MSG: + netdev_dbg(netdev, "REMOTE_NDIS_INDICATE_STATUS_MSG " "(len %u, status 0x%x, buf len %u, buf offset %u)\n", rndis_msg->msg_len, rndis_msg->msg.indicate_status.status, @@ -264,14 +264,14 @@ static void rndis_filter_receive_response(struct rndis_device *dev, sizeof(struct rndis_filter_packet)); if (resp->ndis_msg_type == - RNDIS_MSG_RESET_C) { + REMOTE_NDIS_RESET_CMPLT) { /* does not have a request id field */ request->response_msg.msg.reset_complete. - status = RNDIS_STATUS_BUFFER_OVERFLOW; + status = STATUS_BUFFER_OVERFLOW; } else { request->response_msg.msg. init_complete.status = - RNDIS_STATUS_BUFFER_OVERFLOW; + STATUS_BUFFER_OVERFLOW; } } @@ -415,19 +415,19 @@ int rndis_filter_receive(struct hv_device *dev, dump_rndis_message(dev, rndis_msg); switch (rndis_msg->ndis_msg_type) { - case RNDIS_MSG_PACKET: + case REMOTE_NDIS_PACKET_MSG: /* data msg */ rndis_filter_receive_data(rndis_dev, rndis_msg, pkt); break; - case RNDIS_MSG_INIT_C: - case RNDIS_MSG_QUERY_C: - case RNDIS_MSG_SET_C: + case REMOTE_NDIS_INITIALIZE_CMPLT: + case REMOTE_NDIS_QUERY_CMPLT: + case REMOTE_NDIS_SET_CMPLT: /* completion msgs */ rndis_filter_receive_response(rndis_dev, rndis_msg); break; - case RNDIS_MSG_INDICATE: + case REMOTE_NDIS_INDICATE_STATUS_MSG: /* notification msgs */ rndis_filter_receive_indicate_status(rndis_dev, rndis_msg); break; @@ -456,7 +456,7 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid, return -EINVAL; *result_size = 0; - request = get_rndis_request(dev, RNDIS_MSG_QUERY, + request = get_rndis_request(dev, REMOTE_NDIS_QUERY_MSG, RNDIS_MESSAGE_SIZE(struct rndis_query_request)); if (!request) { ret = -ENOMEM; @@ -536,7 +536,7 @@ int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter) ndev = dev->net_dev->ndev; - request = get_rndis_request(dev, RNDIS_MSG_SET, + request = get_rndis_request(dev, REMOTE_NDIS_SET_MSG, RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32)); if (!request) { @@ -588,7 +588,7 @@ static int rndis_filter_init_device(struct rndis_device *dev) u32 status; int ret, t; - request = get_rndis_request(dev, RNDIS_MSG_INIT, + request = get_rndis_request(dev, REMOTE_NDIS_INITIALIZE_MSG, RNDIS_MESSAGE_SIZE(struct rndis_initialize_request)); if (!request) { ret = -ENOMEM; @@ -641,7 +641,7 @@ static void rndis_filter_halt_device(struct rndis_device *dev) struct rndis_halt_request *halt; /* Attempt to do a rndis device halt */ - request = get_rndis_request(dev, RNDIS_MSG_HALT, + request = get_rndis_request(dev, REMOTE_NDIS_HALT_MSG, RNDIS_MESSAGE_SIZE(struct rndis_halt_request)); if (!request) goto cleanup; @@ -805,7 +805,7 @@ int rndis_filter_send(struct hv_device *dev, if (isvlan) rndis_msg_size += NDIS_VLAN_PPI_SIZE; - rndis_msg->ndis_msg_type = RNDIS_MSG_PACKET; + rndis_msg->ndis_msg_type = REMOTE_NDIS_PACKET_MSG; rndis_msg->msg_len = pkt->total_data_buflen + rndis_msg_size; diff --git a/trunk/drivers/net/macvlan.c b/trunk/drivers/net/macvlan.c index 66a9bfe7b1c8..9653ed6998fe 100644 --- a/trunk/drivers/net/macvlan.c +++ b/trunk/drivers/net/macvlan.c @@ -57,7 +57,7 @@ static struct macvlan_dev *macvlan_hash_lookup(const struct macvlan_port *port, struct hlist_node *n; hlist_for_each_entry_rcu(vlan, n, &port->vlan_hash[addr[5]], hlist) { - if (ether_addr_equal_64bits(vlan->dev->dev_addr, addr)) + if (!compare_ether_addr_64bits(vlan->dev->dev_addr, addr)) return vlan; } return NULL; @@ -96,7 +96,7 @@ static int macvlan_addr_busy(const struct macvlan_port *port, * currently in use by the underlying device or * another macvlan. */ - if (ether_addr_equal_64bits(port->dev->dev_addr, addr)) + if (!compare_ether_addr_64bits(port->dev->dev_addr, addr)) return 1; if (macvlan_hash_lookup(port, addr)) @@ -118,7 +118,8 @@ static int macvlan_broadcast_one(struct sk_buff *skb, return vlan->forward(dev, skb); skb->dev = dev; - if (ether_addr_equal_64bits(eth->h_dest, dev->broadcast)) + if (!compare_ether_addr_64bits(eth->h_dest, + dev->broadcast)) skb->pkt_type = PACKET_BROADCAST; else skb->pkt_type = PACKET_MULTICAST; @@ -258,7 +259,7 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) xmit_world: skb->ip_summed = ip_summed; - skb->dev = vlan->lowerdev; + skb_set_dev(skb, vlan->lowerdev); return dev_queue_xmit(skb); } diff --git a/trunk/drivers/net/macvtap.c b/trunk/drivers/net/macvtap.c index 2ee56de7b0ca..163559c16988 100644 --- a/trunk/drivers/net/macvtap.c +++ b/trunk/drivers/net/macvtap.c @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -783,8 +782,6 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, struct macvlan_dev *vlan; int ret; int vnet_hdr_len = 0; - int vlan_offset = 0; - int copied; if (q->flags & IFF_VNET_HDR) { struct virtio_net_hdr vnet_hdr; @@ -799,48 +796,18 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, sizeof(vnet_hdr))) return -EFAULT; } - copied = vnet_hdr_len; - - if (!vlan_tx_tag_present(skb)) - len = min_t(int, skb->len, len); - else { - int copy; - struct { - __be16 h_vlan_proto; - __be16 h_vlan_TCI; - } veth; - veth.h_vlan_proto = htons(ETH_P_8021Q); - veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb)); - - vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); - len = min_t(int, skb->len + VLAN_HLEN, len); - - copy = min_t(int, vlan_offset, len); - ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); - len -= copy; - copied += copy; - if (ret || !len) - goto done; - - copy = min_t(int, sizeof(veth), len); - ret = memcpy_toiovecend(iv, (void *)&veth, copied, copy); - len -= copy; - copied += copy; - if (ret || !len) - goto done; - } - ret = skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len); - copied += len; + len = min_t(int, skb->len, len); + + ret = skb_copy_datagram_const_iovec(skb, 0, iv, vnet_hdr_len, len); -done: rcu_read_lock_bh(); vlan = rcu_dereference_bh(q->vlan); if (vlan) - macvlan_count_rx(vlan, copied - vnet_hdr_len, ret == 0, 0); + macvlan_count_rx(vlan, len, ret == 0, 0); rcu_read_unlock_bh(); - return ret ? ret : copied; + return ret ? ret : (len + vnet_hdr_len); } static ssize_t macvtap_do_read(struct macvtap_queue *q, struct kiocb *iocb, diff --git a/trunk/drivers/net/phy/mdio_bus.c b/trunk/drivers/net/phy/mdio_bus.c index 683ef1ce5519..83d5c9f55686 100644 --- a/trunk/drivers/net/phy/mdio_bus.c +++ b/trunk/drivers/net/phy/mdio_bus.c @@ -88,7 +88,7 @@ static struct class mdio_bus_class = { .dev_release = mdiobus_release, }; -#if IS_ENABLED(CONFIG_OF_MDIO) +#ifdef CONFIG_OF_MDIO /* Helper function for of_mdio_find_bus */ static int of_mdio_bus_match(struct device *dev, void *mdio_bus_np) { diff --git a/trunk/drivers/net/phy/phy_device.c b/trunk/drivers/net/phy/phy_device.c index de86a5582224..e8c42d6a7d1c 100644 --- a/trunk/drivers/net/phy/phy_device.c +++ b/trunk/drivers/net/phy/phy_device.c @@ -207,7 +207,7 @@ static struct phy_device* phy_device_create(struct mii_bus *bus, * Description: Reads the ID registers of the PHY at @addr on the * @bus, stores it in @phy_id and returns zero on success. */ -static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id) +int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id) { int phy_reg; @@ -230,6 +230,7 @@ static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id) return 0; } +EXPORT_SYMBOL(get_phy_id); /** * get_phy_device - reads the specified PHY device and returns its @phy_device struct diff --git a/trunk/drivers/net/ppp/ppp_async.c b/trunk/drivers/net/ppp/ppp_async.c index a031f6b456b4..af95a98fd86f 100644 --- a/trunk/drivers/net/ppp/ppp_async.c +++ b/trunk/drivers/net/ppp/ppp_async.c @@ -613,7 +613,7 @@ ppp_async_encode(struct asyncppp *ap) *buf++ = PPP_FLAG; ap->olim = buf; - consume_skb(ap->tpkt); + kfree_skb(ap->tpkt); ap->tpkt = NULL; return 1; } diff --git a/trunk/drivers/net/ppp/ppp_generic.c b/trunk/drivers/net/ppp/ppp_generic.c index 5c0557222f20..21d7151fb0ab 100644 --- a/trunk/drivers/net/ppp/ppp_generic.c +++ b/trunk/drivers/net/ppp/ppp_generic.c @@ -1092,13 +1092,13 @@ pad_compress_skb(struct ppp *ppp, struct sk_buff *skb) new_skb->data, skb->len + 2, compressor_skb_size); if (len > 0 && (ppp->flags & SC_CCP_UP)) { - consume_skb(skb); + kfree_skb(skb); skb = new_skb; skb_put(skb, len); skb_pull(skb, 2); /* pull off A/C bytes */ } else if (len == 0) { /* didn't compress, or CCP not up yet */ - consume_skb(new_skb); + kfree_skb(new_skb); new_skb = skb; } else { /* @@ -1112,7 +1112,7 @@ pad_compress_skb(struct ppp *ppp, struct sk_buff *skb) if (net_ratelimit()) netdev_err(ppp->dev, "ppp: compressor dropped pkt\n"); kfree_skb(skb); - consume_skb(new_skb); + kfree_skb(new_skb); new_skb = NULL; } return new_skb; @@ -1178,7 +1178,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) !(ppp->flags & SC_NO_TCP_CCID)); if (cp == skb->data + 2) { /* didn't compress */ - consume_skb(new_skb); + kfree_skb(new_skb); } else { if (cp[0] & SL_TYPE_COMPRESSED_TCP) { proto = PPP_VJC_COMP; @@ -1187,7 +1187,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) proto = PPP_VJC_UNCOMP; cp[0] = skb->data[2]; } - consume_skb(skb); + kfree_skb(skb); skb = new_skb; cp = skb_put(skb, len + 2); cp[0] = 0; @@ -1703,7 +1703,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) } skb_reserve(ns, 2); skb_copy_bits(skb, 0, skb_put(ns, skb->len), skb->len); - consume_skb(skb); + kfree_skb(skb); skb = ns; } else @@ -1851,7 +1851,7 @@ ppp_decompress_frame(struct ppp *ppp, struct sk_buff *skb) goto err; } - consume_skb(skb); + kfree_skb(skb); skb = ns; skb_put(skb, len); skb_pull(skb, 2); /* pull off the A/C bytes */ diff --git a/trunk/drivers/net/ppp/ppp_synctty.c b/trunk/drivers/net/ppp/ppp_synctty.c index 1a12033d2efa..55e466c511d5 100644 --- a/trunk/drivers/net/ppp/ppp_synctty.c +++ b/trunk/drivers/net/ppp/ppp_synctty.c @@ -588,7 +588,7 @@ ppp_sync_txmunge(struct syncppp *ap, struct sk_buff *skb) skb_reserve(npkt,2); skb_copy_from_linear_data(skb, skb_put(npkt, skb->len), skb->len); - consume_skb(skb); + kfree_skb(skb); skb = npkt; } skb_push(skb,2); @@ -656,7 +656,7 @@ ppp_sync_push(struct syncppp *ap) if (sent < ap->tpkt->len) { tty_stuffed = 1; } else { - consume_skb(ap->tpkt); + kfree_skb(ap->tpkt); ap->tpkt = NULL; clear_bit(XMIT_FULL, &ap->xmit_flags); done = 1; diff --git a/trunk/drivers/net/ppp/pppoe.c b/trunk/drivers/net/ppp/pppoe.c index cbf7047decc0..2fa1a9b6f498 100644 --- a/trunk/drivers/net/ppp/pppoe.c +++ b/trunk/drivers/net/ppp/pppoe.c @@ -201,7 +201,7 @@ static int __set_item(struct pppoe_net *pn, struct pppox_sock *po) return 0; } -static void __delete_item(struct pppoe_net *pn, __be16 sid, +static struct pppox_sock *__delete_item(struct pppoe_net *pn, __be16 sid, char *addr, int ifindex) { int hash = hash_item(sid, addr); @@ -220,6 +220,8 @@ static void __delete_item(struct pppoe_net *pn, __be16 sid, src = &ret->next; ret = ret->next; } + + return ret; } /********************************************************************** @@ -262,12 +264,16 @@ static inline struct pppox_sock *get_item_by_addr(struct net *net, return pppox_sock; } -static inline void delete_item(struct pppoe_net *pn, __be16 sid, +static inline struct pppox_sock *delete_item(struct pppoe_net *pn, __be16 sid, char *addr, int ifindex) { + struct pppox_sock *ret; + write_lock_bh(&pn->hash_lock); - __delete_item(pn, sid, addr, ifindex); + ret = __delete_item(pn, sid, addr, ifindex); write_unlock_bh(&pn->hash_lock); + + return ret; } /*************************************************************************** @@ -984,10 +990,8 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock, if (skb) { total_len = min_t(size_t, total_len, skb->len); error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len); - if (error == 0) { - consume_skb(skb); - return total_len; - } + if (error == 0) + error = total_len; } kfree_skb(skb); diff --git a/trunk/drivers/net/ppp/pptp.c b/trunk/drivers/net/ppp/pptp.c index 1c98321b56cc..72b50f57e7b2 100644 --- a/trunk/drivers/net/ppp/pptp.c +++ b/trunk/drivers/net/ppp/pptp.c @@ -209,7 +209,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) } if (skb->sk) skb_set_owner_w(new_skb, skb->sk); - consume_skb(skb); + kfree_skb(skb); skb = new_skb; } diff --git a/trunk/drivers/net/tokenring/3c359.c b/trunk/drivers/net/tokenring/3c359.c new file mode 100644 index 000000000000..0924f572f59b --- /dev/null +++ b/trunk/drivers/net/tokenring/3c359.c @@ -0,0 +1,1831 @@ +/* + * 3c359.c (c) 2000 Mike Phillips (mikep@linuxtr.net) All Rights Reserved + * + * Linux driver for 3Com 3c359 Tokenlink Velocity XL PCI NIC + * + * Base Driver Olympic: + * Written 1999 Peter De Schrijver & Mike Phillips + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * 7/17/00 - Clean up, version number 0.9.0. Ready to release to the world. + * + * 2/16/01 - Port up to kernel 2.4.2 ready for submission into the kernel. + * 3/05/01 - Last clean up stuff before submission. + * 2/15/01 - Finally, update to new pci api. + * + * To Do: + */ + +/* + * Technical Card Details + * + * All access to data is done with 16/8 bit transfers. The transfer + * method really sucks. You can only read or write one location at a time. + * + * Also, the microcode for the card must be uploaded if the card does not have + * the flashrom on board. This is a 28K bloat in the driver when compiled + * as a module. + * + * Rx is very simple, status into a ring of descriptors, dma data transfer, + * interrupts to tell us when a packet is received. + * + * Tx is a little more interesting. Similar scenario, descriptor and dma data + * transfers, but we don't have to interrupt the card to tell it another packet + * is ready for transmission, we are just doing simple memory writes, not io or mmio + * writes. The card can be set up to simply poll on the next + * descriptor pointer and when this value is non-zero will automatically download + * the next packet. The card then interrupts us when the packet is done. + * + */ + +#define XL_DEBUG 0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "3c359.h" + +static char version[] __devinitdata = +"3c359.c v1.2.0 2/17/01 - Mike Phillips (mikep@linuxtr.net)" ; + +#define FW_NAME "3com/3C359.bin" +MODULE_AUTHOR("Mike Phillips ") ; +MODULE_DESCRIPTION("3Com 3C359 Velocity XL Token Ring Adapter Driver\n") ; +MODULE_FIRMWARE(FW_NAME); + +/* Module parameters */ + +/* Ring Speed 0,4,16 + * 0 = Autosense + * 4,16 = Selected speed only, no autosense + * This allows the card to be the first on the ring + * and become the active monitor. + * + * WARNING: Some hubs will allow you to insert + * at the wrong speed. + * + * The adapter will _not_ fail to open if there are no + * active monitors on the ring, it will simply open up in + * its last known ringspeed if no ringspeed is specified. + */ + +static int ringspeed[XL_MAX_ADAPTERS] = {0,} ; + +module_param_array(ringspeed, int, NULL, 0); +MODULE_PARM_DESC(ringspeed,"3c359: Ringspeed selection - 4,16 or 0") ; + +/* Packet buffer size */ + +static int pkt_buf_sz[XL_MAX_ADAPTERS] = {0,} ; + +module_param_array(pkt_buf_sz, int, NULL, 0) ; +MODULE_PARM_DESC(pkt_buf_sz,"3c359: Initial buffer size") ; +/* Message Level */ + +static int message_level[XL_MAX_ADAPTERS] = {0,} ; + +module_param_array(message_level, int, NULL, 0) ; +MODULE_PARM_DESC(message_level, "3c359: Level of reported messages") ; +/* + * This is a real nasty way of doing this, but otherwise you + * will be stuck with 1555 lines of hex #'s in the code. + */ + +static DEFINE_PCI_DEVICE_TABLE(xl_pci_tbl) = +{ + {PCI_VENDOR_ID_3COM,PCI_DEVICE_ID_3COM_3C359, PCI_ANY_ID, PCI_ANY_ID, }, + { } /* terminate list */ +}; +MODULE_DEVICE_TABLE(pci,xl_pci_tbl) ; + +static int xl_init(struct net_device *dev); +static int xl_open(struct net_device *dev); +static int xl_open_hw(struct net_device *dev) ; +static int xl_hw_reset(struct net_device *dev); +static netdev_tx_t xl_xmit(struct sk_buff *skb, struct net_device *dev); +static void xl_dn_comp(struct net_device *dev); +static int xl_close(struct net_device *dev); +static void xl_set_rx_mode(struct net_device *dev); +static irqreturn_t xl_interrupt(int irq, void *dev_id); +static int xl_set_mac_address(struct net_device *dev, void *addr) ; +static void xl_arb_cmd(struct net_device *dev); +static void xl_asb_cmd(struct net_device *dev) ; +static void xl_srb_cmd(struct net_device *dev, int srb_cmd) ; +static void xl_wait_misr_flags(struct net_device *dev) ; +static int xl_change_mtu(struct net_device *dev, int mtu); +static void xl_srb_bh(struct net_device *dev) ; +static void xl_asb_bh(struct net_device *dev) ; +static void xl_reset(struct net_device *dev) ; +static void xl_freemem(struct net_device *dev) ; + + +/* EEProm Access Functions */ +static u16 xl_ee_read(struct net_device *dev, int ee_addr) ; +static void xl_ee_write(struct net_device *dev, int ee_addr, u16 ee_value) ; + +/* Debugging functions */ +#if XL_DEBUG +static void print_tx_state(struct net_device *dev) ; +static void print_rx_state(struct net_device *dev) ; + +static void print_tx_state(struct net_device *dev) +{ + + struct xl_private *xl_priv = netdev_priv(dev); + struct xl_tx_desc *txd ; + u8 __iomem *xl_mmio = xl_priv->xl_mmio ; + int i ; + + printk("tx_ring_head: %d, tx_ring_tail: %d, free_ent: %d\n",xl_priv->tx_ring_head, + xl_priv->tx_ring_tail, xl_priv->free_ring_entries) ; + printk("Ring , Address , FSH , DnNextPtr, Buffer, Buffer_Len\n"); + for (i = 0; i < 16; i++) { + txd = &(xl_priv->xl_tx_ring[i]) ; + printk("%d, %08lx, %08x, %08x, %08x, %08x\n", i, virt_to_bus(txd), + txd->framestartheader, txd->dnnextptr, txd->buffer, txd->buffer_length ) ; + } + + printk("DNLISTPTR = %04x\n", readl(xl_mmio + MMIO_DNLISTPTR) ); + + printk("DmaCtl = %04x\n", readl(xl_mmio + MMIO_DMA_CTRL) ); + printk("Queue status = %0x\n",netif_running(dev) ) ; +} + +static void print_rx_state(struct net_device *dev) +{ + + struct xl_private *xl_priv = netdev_priv(dev); + struct xl_rx_desc *rxd ; + u8 __iomem *xl_mmio = xl_priv->xl_mmio ; + int i ; + + printk("rx_ring_tail: %d\n", xl_priv->rx_ring_tail); + printk("Ring , Address , FrameState , UPNextPtr, FragAddr, Frag_Len\n"); + for (i = 0; i < 16; i++) { + /* rxd = (struct xl_rx_desc *)xl_priv->rx_ring_dma_addr + (i * sizeof(struct xl_rx_desc)) ; */ + rxd = &(xl_priv->xl_rx_ring[i]) ; + printk("%d, %08lx, %08x, %08x, %08x, %08x\n", i, virt_to_bus(rxd), + rxd->framestatus, rxd->upnextptr, rxd->upfragaddr, rxd->upfraglen ) ; + } + + printk("UPLISTPTR = %04x\n", readl(xl_mmio + MMIO_UPLISTPTR)); + + printk("DmaCtl = %04x\n", readl(xl_mmio + MMIO_DMA_CTRL)); + printk("Queue status = %0x\n",netif_running(dev)); +} +#endif + +/* + * Read values from the on-board EEProm. This looks very strange + * but you have to wait for the EEProm to get/set the value before + * passing/getting the next value from the nic. As with all requests + * on this nic it has to be done in two stages, a) tell the nic which + * memory address you want to access and b) pass/get the value from the nic. + * With the EEProm, you have to wait before and between access a) and b). + * As this is only read at initialization time and the wait period is very + * small we shouldn't have to worry about scheduling issues. + */ + +static u16 xl_ee_read(struct net_device *dev, int ee_addr) +{ + struct xl_private *xl_priv = netdev_priv(dev); + u8 __iomem *xl_mmio = xl_priv->xl_mmio ; + + /* Wait for EEProm to not be busy */ + writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ; + + /* Tell EEProm what we want to do and where */ + writel(IO_WORD_WRITE | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writew(EEREAD + ee_addr, xl_mmio + MMIO_MACDATA) ; + + /* Wait for EEProm to not be busy */ + writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ; + + /* Tell EEProm what we want to do and where */ + writel(IO_WORD_WRITE | EECONTROL , xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writew(EEREAD + ee_addr, xl_mmio + MMIO_MACDATA) ; + + /* Finally read the value from the EEProm */ + writel(IO_WORD_READ | EEDATA , xl_mmio + MMIO_MAC_ACCESS_CMD) ; + return readw(xl_mmio + MMIO_MACDATA) ; +} + +/* + * Write values to the onboard eeprom. As with eeprom read you need to + * set which location to write, wait, value to write, wait, with the + * added twist of having to enable eeprom writes as well. + */ + +static void xl_ee_write(struct net_device *dev, int ee_addr, u16 ee_value) +{ + struct xl_private *xl_priv = netdev_priv(dev); + u8 __iomem *xl_mmio = xl_priv->xl_mmio ; + + /* Wait for EEProm to not be busy */ + writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ; + + /* Enable write/erase */ + writel(IO_WORD_WRITE | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writew(EE_ENABLE_WRITE, xl_mmio + MMIO_MACDATA) ; + + /* Wait for EEProm to not be busy */ + writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ; + + /* Put the value we want to write into EEDATA */ + writel(IO_WORD_WRITE | EEDATA, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writew(ee_value, xl_mmio + MMIO_MACDATA) ; + + /* Tell EEProm to write eevalue into ee_addr */ + writel(IO_WORD_WRITE | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writew(EEWRITE + ee_addr, xl_mmio + MMIO_MACDATA) ; + + /* Wait for EEProm to not be busy, to ensure write gets done */ + writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ; + + return ; +} + +static const struct net_device_ops xl_netdev_ops = { + .ndo_open = xl_open, + .ndo_stop = xl_close, + .ndo_start_xmit = xl_xmit, + .ndo_change_mtu = xl_change_mtu, + .ndo_set_rx_mode = xl_set_rx_mode, + .ndo_set_mac_address = xl_set_mac_address, +}; + +static int __devinit xl_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct net_device *dev ; + struct xl_private *xl_priv ; + static int card_no = -1 ; + int i ; + + card_no++ ; + + if (pci_enable_device(pdev)) { + return -ENODEV ; + } + + pci_set_master(pdev); + + if ((i = pci_request_regions(pdev,"3c359"))) { + return i ; + } + + /* + * Allowing init_trdev to allocate the private data will align + * xl_private on a 32 bytes boundary which we need for the rx/tx + * descriptors + */ + + dev = alloc_trdev(sizeof(struct xl_private)) ; + if (!dev) { + pci_release_regions(pdev) ; + return -ENOMEM ; + } + xl_priv = netdev_priv(dev); + +#if XL_DEBUG + printk("pci_device: %p, dev:%p, dev->priv: %p, ba[0]: %10x, ba[1]:%10x\n", + pdev, dev, netdev_priv(dev), (unsigned int)pdev->resource[0].start, (unsigned int)pdev->resource[1].start); +#endif + + dev->irq=pdev->irq; + dev->base_addr=pci_resource_start(pdev,0) ; + xl_priv->xl_card_name = pci_name(pdev); + xl_priv->xl_mmio=ioremap(pci_resource_start(pdev,1), XL_IO_SPACE); + xl_priv->pdev = pdev ; + + if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000) ) + xl_priv->pkt_buf_sz = PKT_BUF_SZ ; + else + xl_priv->pkt_buf_sz = pkt_buf_sz[card_no] ; + + dev->mtu = xl_priv->pkt_buf_sz - TR_HLEN ; + xl_priv->xl_ring_speed = ringspeed[card_no] ; + xl_priv->xl_message_level = message_level[card_no] ; + xl_priv->xl_functional_addr[0] = xl_priv->xl_functional_addr[1] = xl_priv->xl_functional_addr[2] = xl_priv->xl_functional_addr[3] = 0 ; + xl_priv->xl_copy_all_options = 0 ; + + if((i = xl_init(dev))) { + iounmap(xl_priv->xl_mmio) ; + free_netdev(dev) ; + pci_release_regions(pdev) ; + return i ; + } + + dev->netdev_ops = &xl_netdev_ops; + SET_NETDEV_DEV(dev, &pdev->dev); + + pci_set_drvdata(pdev,dev) ; + if ((i = register_netdev(dev))) { + printk(KERN_ERR "3C359, register netdev failed\n") ; + pci_set_drvdata(pdev,NULL) ; + iounmap(xl_priv->xl_mmio) ; + free_netdev(dev) ; + pci_release_regions(pdev) ; + return i ; + } + + printk(KERN_INFO "3C359: %s registered as: %s\n",xl_priv->xl_card_name,dev->name) ; + + return 0; +} + +static int xl_init_firmware(struct xl_private *xl_priv) +{ + int err; + + err = request_firmware(&xl_priv->fw, FW_NAME, &xl_priv->pdev->dev); + if (err) { + printk(KERN_ERR "Failed to load firmware \"%s\"\n", FW_NAME); + return err; + } + + if (xl_priv->fw->size < 16) { + printk(KERN_ERR "Bogus length %zu in \"%s\"\n", + xl_priv->fw->size, FW_NAME); + release_firmware(xl_priv->fw); + err = -EINVAL; + } + + return err; +} + +static int __devinit xl_init(struct net_device *dev) +{ + struct xl_private *xl_priv = netdev_priv(dev); + int err; + + printk(KERN_INFO "%s\n", version); + printk(KERN_INFO "%s: I/O at %hx, MMIO at %p, using irq %d\n", + xl_priv->xl_card_name, (unsigned int)dev->base_addr ,xl_priv->xl_mmio, dev->irq); + + spin_lock_init(&xl_priv->xl_lock) ; + + err = xl_init_firmware(xl_priv); + if (err == 0) + err = xl_hw_reset(dev); + + return err; +} + + +/* + * Hardware reset. This needs to be a separate entity as we need to reset the card + * when we change the EEProm settings. + */ + +static int xl_hw_reset(struct net_device *dev) +{ + struct xl_private *xl_priv = netdev_priv(dev); + u8 __iomem *xl_mmio = xl_priv->xl_mmio ; + unsigned long t ; + u16 i ; + u16 result_16 ; + u8 result_8 ; + u16 start ; + int j ; + + if (xl_priv->fw == NULL) + return -EINVAL; + + /* + * Reset the card. If the card has got the microcode on board, we have + * missed the initialization interrupt, so we must always do this. + */ + + writew( GLOBAL_RESET, xl_mmio + MMIO_COMMAND ) ; + + /* + * Must wait for cmdInProgress bit (12) to clear before continuing with + * card configuration. + */ + + t=jiffies; + while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { + schedule(); + if (time_after(jiffies, t + 40 * HZ)) { + printk(KERN_ERR "%s: 3COM 3C359 Velocity XL card not responding to global reset.\n", dev->name); + return -ENODEV; + } + } + + /* + * Enable pmbar by setting bit in CPAttention + */ + + writel( (IO_BYTE_READ | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ; + result_8 = readb(xl_mmio + MMIO_MACDATA) ; + result_8 = result_8 | CPA_PMBARVIS ; + writel( (IO_BYTE_WRITE | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(result_8, xl_mmio + MMIO_MACDATA) ; + + /* + * Read cpHold bit in pmbar, if cleared we have got Flashrom on board. + * If not, we need to upload the microcode to the card + */ + + writel( (IO_WORD_READ | PMBAR),xl_mmio + MMIO_MAC_ACCESS_CMD); + +#if XL_DEBUG + printk(KERN_INFO "Read from PMBAR = %04x\n", readw(xl_mmio + MMIO_MACDATA)); +#endif + + if ( readw( (xl_mmio + MMIO_MACDATA)) & PMB_CPHOLD ) { + + /* Set PmBar, privateMemoryBase bits (8:2) to 0 */ + + writel( (IO_WORD_READ | PMBAR),xl_mmio + MMIO_MAC_ACCESS_CMD); + result_16 = readw(xl_mmio + MMIO_MACDATA) ; + result_16 = result_16 & ~((0x7F) << 2) ; + writel( (IO_WORD_WRITE | PMBAR), xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writew(result_16,xl_mmio + MMIO_MACDATA) ; + + /* Set CPAttention, memWrEn bit */ + + writel( (IO_BYTE_READ | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ; + result_8 = readb(xl_mmio + MMIO_MACDATA) ; + result_8 = result_8 | CPA_MEMWREN ; + writel( (IO_BYTE_WRITE | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(result_8, xl_mmio + MMIO_MACDATA) ; + + /* + * Now to write the microcode into the shared ram + * The microcode must finish at position 0xFFFF, + * so we must subtract to get the start position for the code + * + * Looks strange but ensures compiler only uses + * 16 bit unsigned int + */ + start = (0xFFFF - (xl_priv->fw->size) + 1) ; + + printk(KERN_INFO "3C359: Uploading Microcode: "); + + for (i = start, j = 0; j < xl_priv->fw->size; i++, j++) { + writel(MEM_BYTE_WRITE | 0XD0000 | i, + xl_mmio + MMIO_MAC_ACCESS_CMD); + writeb(xl_priv->fw->data[j], xl_mmio + MMIO_MACDATA); + if (j % 1024 == 0) + printk("."); + } + printk("\n") ; + + for (i = 0; i < 16; i++) { + writel((MEM_BYTE_WRITE | 0xDFFF0) + i, + xl_mmio + MMIO_MAC_ACCESS_CMD); + writeb(xl_priv->fw->data[xl_priv->fw->size - 16 + i], + xl_mmio + MMIO_MACDATA); + } + + /* + * Have to write the start address of the upload to FFF4, but + * the address must be >> 4. You do not want to know how long + * it took me to discover this. + */ + + writel(MEM_WORD_WRITE | 0xDFFF4, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writew(start >> 4, xl_mmio + MMIO_MACDATA); + + /* Clear the CPAttention, memWrEn Bit */ + + writel( (IO_BYTE_READ | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ; + result_8 = readb(xl_mmio + MMIO_MACDATA) ; + result_8 = result_8 & ~CPA_MEMWREN ; + writel( (IO_BYTE_WRITE | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(result_8, xl_mmio + MMIO_MACDATA) ; + + /* Clear the cpHold bit in pmbar */ + + writel( (IO_WORD_READ | PMBAR),xl_mmio + MMIO_MAC_ACCESS_CMD); + result_16 = readw(xl_mmio + MMIO_MACDATA) ; + result_16 = result_16 & ~PMB_CPHOLD ; + writel( (IO_WORD_WRITE | PMBAR), xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writew(result_16,xl_mmio + MMIO_MACDATA) ; + + + } /* If microcode upload required */ + + /* + * The card should now go though a self test procedure and get itself ready + * to be opened, we must wait for an srb response with the initialization + * information. + */ + +#if XL_DEBUG + printk(KERN_INFO "%s: Microcode uploaded, must wait for the self test to complete\n", dev->name); +#endif + + writew(SETINDENABLE | 0xFFF, xl_mmio + MMIO_COMMAND) ; + + t=jiffies; + while ( !(readw(xl_mmio + MMIO_INTSTATUS_AUTO) & INTSTAT_SRB) ) { + schedule(); + if (time_after(jiffies, t + 15 * HZ)) { + printk(KERN_ERR "3COM 3C359 Velocity XL card not responding.\n"); + return -ENODEV; + } + } + + /* + * Write the RxBufArea with D000, RxEarlyThresh, TxStartThresh, + * DnPriReqThresh, read the tech docs if you want to know what + * values they need to be. + */ + + writel(MMIO_WORD_WRITE | RXBUFAREA, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writew(0xD000, xl_mmio + MMIO_MACDATA) ; + + writel(MMIO_WORD_WRITE | RXEARLYTHRESH, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writew(0X0020, xl_mmio + MMIO_MACDATA) ; + + writew( SETTXSTARTTHRESH | 0x40 , xl_mmio + MMIO_COMMAND) ; + + writeb(0x04, xl_mmio + MMIO_DNBURSTTHRESH) ; + writeb(0x04, xl_mmio + DNPRIREQTHRESH) ; + + /* + * Read WRBR to provide the location of the srb block, have to use byte reads not word reads. + * Tech docs have this wrong !!!! + */ + + writel(MMIO_BYTE_READ | WRBR, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + xl_priv->srb = readb(xl_mmio + MMIO_MACDATA) << 8 ; + writel( (MMIO_BYTE_READ | WRBR) + 1, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + xl_priv->srb = xl_priv->srb | readb(xl_mmio + MMIO_MACDATA) ; + +#if XL_DEBUG + writel(IO_WORD_READ | SWITCHSETTINGS, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + if ( readw(xl_mmio + MMIO_MACDATA) & 2) { + printk(KERN_INFO "Default ring speed 4 mbps\n"); + } else { + printk(KERN_INFO "Default ring speed 16 mbps\n"); + } + printk(KERN_INFO "%s: xl_priv->srb = %04x\n",xl_priv->xl_card_name, xl_priv->srb); +#endif + + return 0; +} + +static int xl_open(struct net_device *dev) +{ + struct xl_private *xl_priv=netdev_priv(dev); + u8 __iomem *xl_mmio = xl_priv->xl_mmio ; + u8 i ; + __le16 hwaddr[3] ; /* Should be u8[6] but we get word return values */ + int open_err ; + + u16 switchsettings, switchsettings_eeprom ; + + if (request_irq(dev->irq, xl_interrupt, IRQF_SHARED , "3c359", dev)) + return -EAGAIN; + + /* + * Read the information from the EEPROM that we need. + */ + + hwaddr[0] = cpu_to_le16(xl_ee_read(dev,0x10)); + hwaddr[1] = cpu_to_le16(xl_ee_read(dev,0x11)); + hwaddr[2] = cpu_to_le16(xl_ee_read(dev,0x12)); + + /* Ring speed */ + + switchsettings_eeprom = xl_ee_read(dev,0x08) ; + switchsettings = switchsettings_eeprom ; + + if (xl_priv->xl_ring_speed != 0) { + if (xl_priv->xl_ring_speed == 4) + switchsettings = switchsettings | 0x02 ; + else + switchsettings = switchsettings & ~0x02 ; + } + + /* Only write EEProm if there has been a change */ + if (switchsettings != switchsettings_eeprom) { + xl_ee_write(dev,0x08,switchsettings) ; + /* Hardware reset after changing EEProm */ + xl_hw_reset(dev) ; + } + + memcpy(dev->dev_addr,hwaddr,dev->addr_len) ; + + open_err = xl_open_hw(dev) ; + + /* + * This really needs to be cleaned up with better error reporting. + */ + + if (open_err != 0) { /* Something went wrong with the open command */ + if (open_err & 0x07) { /* Wrong speed, retry at different speed */ + printk(KERN_WARNING "%s: Open Error, retrying at different ringspeed\n", dev->name); + switchsettings = switchsettings ^ 2 ; + xl_ee_write(dev,0x08,switchsettings) ; + xl_hw_reset(dev) ; + open_err = xl_open_hw(dev) ; + if (open_err != 0) { + printk(KERN_WARNING "%s: Open error returned a second time, we're bombing out now\n", dev->name); + free_irq(dev->irq,dev) ; + return -ENODEV ; + } + } else { + printk(KERN_WARNING "%s: Open Error = %04x\n", dev->name, open_err) ; + free_irq(dev->irq,dev) ; + return -ENODEV ; + } + } + + /* + * Now to set up the Rx and Tx buffer structures + */ + /* These MUST be on 8 byte boundaries */ + xl_priv->xl_tx_ring = kzalloc((sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE) + 7, GFP_DMA | GFP_KERNEL); + if (xl_priv->xl_tx_ring == NULL) { + free_irq(dev->irq,dev); + return -ENOMEM; + } + xl_priv->xl_rx_ring = kzalloc((sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE) +7, GFP_DMA | GFP_KERNEL); + if (xl_priv->xl_rx_ring == NULL) { + free_irq(dev->irq,dev); + kfree(xl_priv->xl_tx_ring); + return -ENOMEM; + } + + /* Setup Rx Ring */ + for (i=0 ; i < XL_RX_RING_SIZE ; i++) { + struct sk_buff *skb ; + + skb = dev_alloc_skb(xl_priv->pkt_buf_sz) ; + if (skb==NULL) + break ; + + skb->dev = dev ; + xl_priv->xl_rx_ring[i].upfragaddr = cpu_to_le32(pci_map_single(xl_priv->pdev, skb->data,xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE)); + xl_priv->xl_rx_ring[i].upfraglen = cpu_to_le32(xl_priv->pkt_buf_sz) | RXUPLASTFRAG; + xl_priv->rx_ring_skb[i] = skb ; + } + + if (i==0) { + printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled\n",dev->name); + free_irq(dev->irq,dev) ; + kfree(xl_priv->xl_tx_ring); + kfree(xl_priv->xl_rx_ring); + return -EIO ; + } + + xl_priv->rx_ring_no = i ; + xl_priv->rx_ring_tail = 0 ; + xl_priv->rx_ring_dma_addr = pci_map_single(xl_priv->pdev,xl_priv->xl_rx_ring, sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE, PCI_DMA_TODEVICE) ; + for (i=0;i<(xl_priv->rx_ring_no-1);i++) { + xl_priv->xl_rx_ring[i].upnextptr = cpu_to_le32(xl_priv->rx_ring_dma_addr + (sizeof (struct xl_rx_desc) * (i+1))); + } + xl_priv->xl_rx_ring[i].upnextptr = 0 ; + + writel(xl_priv->rx_ring_dma_addr, xl_mmio + MMIO_UPLISTPTR) ; + + /* Setup Tx Ring */ + + xl_priv->tx_ring_dma_addr = pci_map_single(xl_priv->pdev,xl_priv->xl_tx_ring, sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE,PCI_DMA_TODEVICE) ; + + xl_priv->tx_ring_head = 1 ; + xl_priv->tx_ring_tail = 255 ; /* Special marker for first packet */ + xl_priv->free_ring_entries = XL_TX_RING_SIZE ; + + /* + * Setup the first dummy DPD entry for polling to start working. + */ + + xl_priv->xl_tx_ring[0].framestartheader = TXDPDEMPTY; + xl_priv->xl_tx_ring[0].buffer = 0 ; + xl_priv->xl_tx_ring[0].buffer_length = 0 ; + xl_priv->xl_tx_ring[0].dnnextptr = 0 ; + + writel(xl_priv->tx_ring_dma_addr, xl_mmio + MMIO_DNLISTPTR) ; + writel(DNUNSTALL, xl_mmio + MMIO_COMMAND) ; + writel(UPUNSTALL, xl_mmio + MMIO_COMMAND) ; + writel(DNENABLE, xl_mmio + MMIO_COMMAND) ; + writeb(0x40, xl_mmio + MMIO_DNPOLL) ; + + /* + * Enable interrupts on the card + */ + + writel(SETINTENABLE | INT_MASK, xl_mmio + MMIO_COMMAND) ; + writel(SETINDENABLE | INT_MASK, xl_mmio + MMIO_COMMAND) ; + + netif_start_queue(dev) ; + return 0; + +} + +static int xl_open_hw(struct net_device *dev) +{ + struct xl_private *xl_priv=netdev_priv(dev); + u8 __iomem *xl_mmio = xl_priv->xl_mmio ; + u16 vsoff ; + char ver_str[33]; + int open_err ; + int i ; + unsigned long t ; + + /* + * Okay, let's build up the Open.NIC srb command + * + */ + + writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb), xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(OPEN_NIC, xl_mmio + MMIO_MACDATA) ; + + /* + * Use this as a test byte, if it comes back with the same value, the command didn't work + */ + + writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb)+ 2, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(0xff,xl_mmio + MMIO_MACDATA) ; + + /* Open options */ + writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + 8, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(0x00, xl_mmio + MMIO_MACDATA) ; + writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + 9, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(0x00, xl_mmio + MMIO_MACDATA) ; + + /* + * Node address, be careful here, the docs say you can just put zeros here and it will use + * the hardware address, it doesn't, you must include the node address in the open command. + */ + + if (xl_priv->xl_laa[0]) { /* If using a LAA address */ + for (i=10;i<16;i++) { + writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(xl_priv->xl_laa[i-10],xl_mmio + MMIO_MACDATA) ; + } + memcpy(dev->dev_addr,xl_priv->xl_laa,dev->addr_len) ; + } else { /* Regular hardware address */ + for (i=10;i<16;i++) { + writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(dev->dev_addr[i-10], xl_mmio + MMIO_MACDATA) ; + } + } + + /* Default everything else to 0 */ + for (i = 16; i < 34; i++) { + writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(0x00,xl_mmio + MMIO_MACDATA) ; + } + + /* + * Set the csrb bit in the MISR register + */ + + xl_wait_misr_flags(dev) ; + writel(MEM_BYTE_WRITE | MF_CSRB, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(0xFF, xl_mmio + MMIO_MACDATA) ; + writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(MISR_CSRB , xl_mmio + MMIO_MACDATA) ; + + /* + * Now wait for the command to run + */ + + t=jiffies; + while (! (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_SRB)) { + schedule(); + if (time_after(jiffies, t + 40 * HZ)) { + printk(KERN_ERR "3COM 3C359 Velocity XL card not responding.\n"); + break ; + } + } + + /* + * Let's interpret the open response + */ + + writel( (MEM_BYTE_READ | 0xD0000 | xl_priv->srb)+2, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + if (readb(xl_mmio + MMIO_MACDATA)!=0) { + open_err = readb(xl_mmio + MMIO_MACDATA) << 8 ; + writel( (MEM_BYTE_READ | 0xD0000 | xl_priv->srb) + 7, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + open_err |= readb(xl_mmio + MMIO_MACDATA) ; + return open_err ; + } else { + writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 8, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + xl_priv->asb = swab16(readw(xl_mmio + MMIO_MACDATA)) ; + printk(KERN_INFO "%s: Adapter Opened Details: ",dev->name) ; + printk("ASB: %04x",xl_priv->asb ) ; + writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 10, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + printk(", SRB: %04x",swab16(readw(xl_mmio + MMIO_MACDATA)) ) ; + + writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 12, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + xl_priv->arb = swab16(readw(xl_mmio + MMIO_MACDATA)) ; + printk(", ARB: %04x\n",xl_priv->arb ); + writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 14, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + vsoff = swab16(readw(xl_mmio + MMIO_MACDATA)) ; + + /* + * Interesting, sending the individual characters directly to printk was causing klogd to use + * use 100% of processor time, so we build up the string and print that instead. + */ + + for (i=0;i<0x20;i++) { + writel( (MEM_BYTE_READ | 0xD0000 | vsoff) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + ver_str[i] = readb(xl_mmio + MMIO_MACDATA) ; + } + ver_str[i] = '\0' ; + printk(KERN_INFO "%s: Microcode version String: %s\n",dev->name,ver_str); + } + + /* + * Issue the AckInterrupt + */ + writew(ACK_INTERRUPT | SRBRACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; + + return 0 ; +} + +/* + * There are two ways of implementing rx on the 359 NIC, either + * interrupt driven or polling. We are going to uses interrupts, + * it is the easier way of doing things. + * + * The Rx works with a ring of Rx descriptors. At initialise time the ring + * entries point to the next entry except for the last entry in the ring + * which points to 0. The card is programmed with the location of the first + * available descriptor and keeps reading the next_ptr until next_ptr is set + * to 0. Hopefully with a ring size of 16 the card will never get to read a next_ptr + * of 0. As the Rx interrupt is received we copy the frame up to the protocol layers + * and then point the end of the ring to our current position and point our current + * position to 0, therefore making the current position the last position on the ring. + * The last position on the ring therefore loops continually loops around the rx ring. + * + * rx_ring_tail is the position on the ring to process next. (Think of a snake, the head + * expands as the card adds new packets and we go around eating the tail processing the + * packets.) + * + * Undoubtably it could be streamlined and improved upon, but at the moment it works + * and the fast path through the routine is fine. + * + * adv_rx_ring could be inlined to increase performance, but its called a *lot* of times + * in xl_rx so would increase the size of the function significantly. + */ + +static void adv_rx_ring(struct net_device *dev) /* Advance rx_ring, cut down on bloat in xl_rx */ +{ + struct xl_private *xl_priv=netdev_priv(dev); + int n = xl_priv->rx_ring_tail; + int prev_ring_loc; + + prev_ring_loc = (n + XL_RX_RING_SIZE - 1) & (XL_RX_RING_SIZE - 1); + xl_priv->xl_rx_ring[prev_ring_loc].upnextptr = cpu_to_le32(xl_priv->rx_ring_dma_addr + (sizeof (struct xl_rx_desc) * n)); + xl_priv->xl_rx_ring[n].framestatus = 0; + xl_priv->xl_rx_ring[n].upnextptr = 0; + xl_priv->rx_ring_tail++; + xl_priv->rx_ring_tail &= (XL_RX_RING_SIZE-1); +} + +static void xl_rx(struct net_device *dev) +{ + struct xl_private *xl_priv=netdev_priv(dev); + u8 __iomem * xl_mmio = xl_priv->xl_mmio ; + struct sk_buff *skb, *skb2 ; + int frame_length = 0, copy_len = 0 ; + int temp_ring_loc ; + + /* + * Receive the next frame, loop around the ring until all frames + * have been received. + */ + + while (xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].framestatus & (RXUPDCOMPLETE | RXUPDFULL) ) { /* Descriptor to process */ + + if (xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].framestatus & RXUPDFULL ) { /* UpdFull, Multiple Descriptors used for the frame */ + + /* + * This is a pain, you need to go through all the descriptors until the last one + * for this frame to find the framelength + */ + + temp_ring_loc = xl_priv->rx_ring_tail ; + + while (xl_priv->xl_rx_ring[temp_ring_loc].framestatus & RXUPDFULL ) { + temp_ring_loc++ ; + temp_ring_loc &= (XL_RX_RING_SIZE-1) ; + } + + frame_length = le32_to_cpu(xl_priv->xl_rx_ring[temp_ring_loc].framestatus) & 0x7FFF; + + skb = dev_alloc_skb(frame_length) ; + + if (skb==NULL) { /* No memory for frame, still need to roll forward the rx ring */ + printk(KERN_WARNING "%s: dev_alloc_skb failed - multi buffer !\n", dev->name) ; + while (xl_priv->rx_ring_tail != temp_ring_loc) + adv_rx_ring(dev) ; + + adv_rx_ring(dev) ; /* One more time just for luck :) */ + dev->stats.rx_dropped++ ; + + writel(ACK_INTERRUPT | UPCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ; + return ; + } + + while (xl_priv->rx_ring_tail != temp_ring_loc) { + copy_len = le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfraglen) & 0x7FFF; + frame_length -= copy_len ; + pci_dma_sync_single_for_cpu(xl_priv->pdev,le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr),xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE); + skb_copy_from_linear_data(xl_priv->rx_ring_skb[xl_priv->rx_ring_tail], + skb_put(skb, copy_len), + copy_len); + pci_dma_sync_single_for_device(xl_priv->pdev,le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr),xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE); + adv_rx_ring(dev) ; + } + + /* Now we have found the last fragment */ + pci_dma_sync_single_for_cpu(xl_priv->pdev,le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr),xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE); + skb_copy_from_linear_data(xl_priv->rx_ring_skb[xl_priv->rx_ring_tail], + skb_put(skb,copy_len), frame_length); +/* memcpy(skb_put(skb,frame_length), bus_to_virt(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr), frame_length) ; */ + pci_dma_sync_single_for_device(xl_priv->pdev,le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr),xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE); + adv_rx_ring(dev) ; + skb->protocol = tr_type_trans(skb,dev) ; + netif_rx(skb) ; + + } else { /* Single Descriptor Used, simply swap buffers over, fast path */ + + frame_length = le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].framestatus) & 0x7FFF; + + skb = dev_alloc_skb(xl_priv->pkt_buf_sz) ; + + if (skb==NULL) { /* Still need to fix the rx ring */ + printk(KERN_WARNING "%s: dev_alloc_skb failed in rx, single buffer\n",dev->name); + adv_rx_ring(dev) ; + dev->stats.rx_dropped++ ; + writel(ACK_INTERRUPT | UPCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ; + return ; + } + + skb2 = xl_priv->rx_ring_skb[xl_priv->rx_ring_tail] ; + pci_unmap_single(xl_priv->pdev, le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr), xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; + skb_put(skb2, frame_length) ; + skb2->protocol = tr_type_trans(skb2,dev) ; + + xl_priv->rx_ring_skb[xl_priv->rx_ring_tail] = skb ; + xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr = cpu_to_le32(pci_map_single(xl_priv->pdev,skb->data,xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE)); + xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfraglen = cpu_to_le32(xl_priv->pkt_buf_sz) | RXUPLASTFRAG; + adv_rx_ring(dev) ; + dev->stats.rx_packets++ ; + dev->stats.rx_bytes += frame_length ; + + netif_rx(skb2) ; + } /* if multiple buffers */ + } /* while packet to do */ + + /* Clear the updComplete interrupt */ + writel(ACK_INTERRUPT | UPCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ; + return ; +} + +/* + * This is ruthless, it doesn't care what state the card is in it will + * completely reset the adapter. + */ + +static void xl_reset(struct net_device *dev) +{ + struct xl_private *xl_priv=netdev_priv(dev); + u8 __iomem * xl_mmio = xl_priv->xl_mmio ; + unsigned long t; + + writew( GLOBAL_RESET, xl_mmio + MMIO_COMMAND ) ; + + /* + * Must wait for cmdInProgress bit (12) to clear before continuing with + * card configuration. + */ + + t=jiffies; + while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { + if (time_after(jiffies, t + 40 * HZ)) { + printk(KERN_ERR "3COM 3C359 Velocity XL card not responding.\n"); + break ; + } + } + +} + +static void xl_freemem(struct net_device *dev) +{ + struct xl_private *xl_priv=netdev_priv(dev); + int i ; + + for (i=0;irx_ring_skb[xl_priv->rx_ring_tail]) ; + pci_unmap_single(xl_priv->pdev,le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr),xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE); + xl_priv->rx_ring_tail++ ; + xl_priv->rx_ring_tail &= XL_RX_RING_SIZE-1; + } + + /* unmap ring */ + pci_unmap_single(xl_priv->pdev,xl_priv->rx_ring_dma_addr, sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE, PCI_DMA_FROMDEVICE) ; + + pci_unmap_single(xl_priv->pdev,xl_priv->tx_ring_dma_addr, sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE, PCI_DMA_TODEVICE) ; + + kfree(xl_priv->xl_rx_ring) ; + kfree(xl_priv->xl_tx_ring) ; + + return ; +} + +static irqreturn_t xl_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = (struct net_device *)dev_id; + struct xl_private *xl_priv =netdev_priv(dev); + u8 __iomem * xl_mmio = xl_priv->xl_mmio ; + u16 intstatus, macstatus ; + + intstatus = readw(xl_mmio + MMIO_INTSTATUS) ; + + if (!(intstatus & 1)) /* We didn't generate the interrupt */ + return IRQ_NONE; + + spin_lock(&xl_priv->xl_lock) ; + + /* + * Process the interrupt + */ + /* + * Something fishy going on here, we shouldn't get 0001 ints, not fatal though. + */ + if (intstatus == 0x0001) { + writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; + printk(KERN_INFO "%s: 00001 int received\n",dev->name); + } else { + if (intstatus & (HOSTERRINT | SRBRINT | ARBCINT | UPCOMPINT | DNCOMPINT | HARDERRINT | (1<<8) | TXUNDERRUN | ASBFINT)) { + + /* + * Host Error. + * It may be possible to recover from this, but usually it means something + * is seriously fubar, so we just close the adapter. + */ + + if (intstatus & HOSTERRINT) { + printk(KERN_WARNING "%s: Host Error, performing global reset, intstatus = %04x\n",dev->name,intstatus); + writew( GLOBAL_RESET, xl_mmio + MMIO_COMMAND ) ; + printk(KERN_WARNING "%s: Resetting hardware:\n", dev->name); + netif_stop_queue(dev) ; + xl_freemem(dev) ; + free_irq(dev->irq,dev); + xl_reset(dev) ; + writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; + spin_unlock(&xl_priv->xl_lock) ; + return IRQ_HANDLED; + } /* Host Error */ + + if (intstatus & SRBRINT ) { /* Srbc interrupt */ + writel(ACK_INTERRUPT | SRBRACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; + if (xl_priv->srb_queued) + xl_srb_bh(dev) ; + } /* SRBR Interrupt */ + + if (intstatus & TXUNDERRUN) { /* Issue DnReset command */ + writel(DNRESET, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { /* Wait for command to run */ + /* !!! FIX-ME !!!! + Must put a timeout check here ! */ + /* Empty Loop */ + } + printk(KERN_WARNING "%s: TX Underrun received\n",dev->name); + writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; + } /* TxUnderRun */ + + if (intstatus & ARBCINT ) { /* Arbc interrupt */ + xl_arb_cmd(dev) ; + } /* Arbc */ + + if (intstatus & ASBFINT) { + if (xl_priv->asb_queued == 1) { + xl_asb_cmd(dev) ; + } else if (xl_priv->asb_queued == 2) { + xl_asb_bh(dev) ; + } else { + writel(ACK_INTERRUPT | LATCH_ACK | ASBFACK, xl_mmio + MMIO_COMMAND) ; + } + } /* Asbf */ + + if (intstatus & UPCOMPINT ) /* UpComplete */ + xl_rx(dev) ; + + if (intstatus & DNCOMPINT ) /* DnComplete */ + xl_dn_comp(dev) ; + + if (intstatus & HARDERRINT ) { /* Hardware error */ + writel(MMIO_WORD_READ | MACSTATUS, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + macstatus = readw(xl_mmio + MMIO_MACDATA) ; + printk(KERN_WARNING "%s: MacStatusError, details: ", dev->name); + if (macstatus & (1<<14)) + printk(KERN_WARNING "tchk error: Unrecoverable error\n"); + if (macstatus & (1<<3)) + printk(KERN_WARNING "eint error: Internal watchdog timer expired\n"); + if (macstatus & (1<<2)) + printk(KERN_WARNING "aint error: Host tried to perform invalid operation\n"); + printk(KERN_WARNING "Instatus = %02x, macstatus = %02x\n",intstatus,macstatus) ; + printk(KERN_WARNING "%s: Resetting hardware:\n", dev->name); + netif_stop_queue(dev) ; + xl_freemem(dev) ; + free_irq(dev->irq,dev); + unregister_netdev(dev) ; + free_netdev(dev) ; + xl_reset(dev) ; + writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; + spin_unlock(&xl_priv->xl_lock) ; + return IRQ_HANDLED; + } + } else { + printk(KERN_WARNING "%s: Received Unknown interrupt : %04x\n", dev->name, intstatus); + writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; + } + } + + /* Turn interrupts back on */ + + writel( SETINDENABLE | INT_MASK, xl_mmio + MMIO_COMMAND) ; + writel( SETINTENABLE | INT_MASK, xl_mmio + MMIO_COMMAND) ; + + spin_unlock(&xl_priv->xl_lock) ; + return IRQ_HANDLED; +} + +/* + * Tx - Polling configuration + */ + +static netdev_tx_t xl_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct xl_private *xl_priv=netdev_priv(dev); + struct xl_tx_desc *txd ; + int tx_head, tx_tail, tx_prev ; + unsigned long flags ; + + spin_lock_irqsave(&xl_priv->xl_lock,flags) ; + + netif_stop_queue(dev) ; + + if (xl_priv->free_ring_entries > 1 ) { + /* + * Set up the descriptor for the packet + */ + tx_head = xl_priv->tx_ring_head ; + tx_tail = xl_priv->tx_ring_tail ; + + txd = &(xl_priv->xl_tx_ring[tx_head]) ; + txd->dnnextptr = 0 ; + txd->framestartheader = cpu_to_le32(skb->len) | TXDNINDICATE; + txd->buffer = cpu_to_le32(pci_map_single(xl_priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE)); + txd->buffer_length = cpu_to_le32(skb->len) | TXDNFRAGLAST; + xl_priv->tx_ring_skb[tx_head] = skb ; + dev->stats.tx_packets++ ; + dev->stats.tx_bytes += skb->len ; + + /* + * Set the nextptr of the previous descriptor equal to this descriptor, add XL_TX_RING_SIZE -1 + * to ensure no negative numbers in unsigned locations. + */ + + tx_prev = (xl_priv->tx_ring_head + XL_TX_RING_SIZE - 1) & (XL_TX_RING_SIZE - 1) ; + + xl_priv->tx_ring_head++ ; + xl_priv->tx_ring_head &= (XL_TX_RING_SIZE - 1) ; + xl_priv->free_ring_entries-- ; + + xl_priv->xl_tx_ring[tx_prev].dnnextptr = cpu_to_le32(xl_priv->tx_ring_dma_addr + (sizeof (struct xl_tx_desc) * tx_head)); + + /* Sneaky, by doing a read on DnListPtr we can force the card to poll on the DnNextPtr */ + /* readl(xl_mmio + MMIO_DNLISTPTR) ; */ + + netif_wake_queue(dev) ; + + spin_unlock_irqrestore(&xl_priv->xl_lock,flags) ; + + return NETDEV_TX_OK; + } else { + spin_unlock_irqrestore(&xl_priv->xl_lock,flags) ; + return NETDEV_TX_BUSY; + } + +} + +/* + * The NIC has told us that a packet has been downloaded onto the card, we must + * find out which packet it has done, clear the skb and information for the packet + * then advance around the ring for all transmitted packets + */ + +static void xl_dn_comp(struct net_device *dev) +{ + struct xl_private *xl_priv=netdev_priv(dev); + u8 __iomem * xl_mmio = xl_priv->xl_mmio ; + struct xl_tx_desc *txd ; + + + if (xl_priv->tx_ring_tail == 255) {/* First time */ + xl_priv->xl_tx_ring[0].framestartheader = 0 ; + xl_priv->xl_tx_ring[0].dnnextptr = 0 ; + xl_priv->tx_ring_tail = 1 ; + } + + while (xl_priv->xl_tx_ring[xl_priv->tx_ring_tail].framestartheader & TXDNCOMPLETE ) { + txd = &(xl_priv->xl_tx_ring[xl_priv->tx_ring_tail]) ; + pci_unmap_single(xl_priv->pdev, le32_to_cpu(txd->buffer), xl_priv->tx_ring_skb[xl_priv->tx_ring_tail]->len, PCI_DMA_TODEVICE); + txd->framestartheader = 0 ; + txd->buffer = cpu_to_le32(0xdeadbeef); + txd->buffer_length = 0 ; + dev_kfree_skb_irq(xl_priv->tx_ring_skb[xl_priv->tx_ring_tail]) ; + xl_priv->tx_ring_tail++ ; + xl_priv->tx_ring_tail &= (XL_TX_RING_SIZE - 1) ; + xl_priv->free_ring_entries++ ; + } + + netif_wake_queue(dev) ; + + writel(ACK_INTERRUPT | DNCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ; +} + +/* + * Close the adapter properly. + * This srb reply cannot be handled from interrupt context as we have + * to free the interrupt from the driver. + */ + +static int xl_close(struct net_device *dev) +{ + struct xl_private *xl_priv = netdev_priv(dev); + u8 __iomem * xl_mmio = xl_priv->xl_mmio ; + unsigned long t ; + + netif_stop_queue(dev) ; + + /* + * Close the adapter, need to stall the rx and tx queues. + */ + + writew(DNSTALL, xl_mmio + MMIO_COMMAND) ; + t=jiffies; + while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { + schedule(); + if (time_after(jiffies, t + 10 * HZ)) { + printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-DNSTALL not responding.\n", dev->name); + break ; + } + } + writew(DNDISABLE, xl_mmio + MMIO_COMMAND) ; + t=jiffies; + while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { + schedule(); + if (time_after(jiffies, t + 10 * HZ)) { + printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-DNDISABLE not responding.\n", dev->name); + break ; + } + } + writew(UPSTALL, xl_mmio + MMIO_COMMAND) ; + t=jiffies; + while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { + schedule(); + if (time_after(jiffies, t + 10 * HZ)) { + printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-UPSTALL not responding.\n", dev->name); + break ; + } + } + + /* Turn off interrupts, we will still get the indication though + * so we can trap it + */ + + writel(SETINTENABLE, xl_mmio + MMIO_COMMAND) ; + + xl_srb_cmd(dev,CLOSE_NIC) ; + + t=jiffies; + while (!(readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_SRB)) { + schedule(); + if (time_after(jiffies, t + 10 * HZ)) { + printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-CLOSENIC not responding.\n", dev->name); + break ; + } + } + /* Read the srb response from the adapter */ + + writel(MEM_BYTE_READ | 0xd0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD); + if (readb(xl_mmio + MMIO_MACDATA) != CLOSE_NIC) { + printk(KERN_INFO "%s: CLOSE_NIC did not get a CLOSE_NIC response\n",dev->name); + } else { + writel((MEM_BYTE_READ | 0xd0000 | xl_priv->srb) +2, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + if (readb(xl_mmio + MMIO_MACDATA)==0) { + printk(KERN_INFO "%s: Adapter has been closed\n",dev->name); + writew(ACK_INTERRUPT | SRBRACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; + + xl_freemem(dev) ; + free_irq(dev->irq,dev) ; + } else { + printk(KERN_INFO "%s: Close nic command returned error code %02x\n",dev->name, readb(xl_mmio + MMIO_MACDATA)) ; + } + } + + /* Reset the upload and download logic */ + + writew(UPRESET, xl_mmio + MMIO_COMMAND) ; + t=jiffies; + while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { + schedule(); + if (time_after(jiffies, t + 10 * HZ)) { + printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-UPRESET not responding.\n", dev->name); + break ; + } + } + writew(DNRESET, xl_mmio + MMIO_COMMAND) ; + t=jiffies; + while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { + schedule(); + if (time_after(jiffies, t + 10 * HZ)) { + printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-DNRESET not responding.\n", dev->name); + break ; + } + } + xl_hw_reset(dev) ; + return 0 ; +} + +static void xl_set_rx_mode(struct net_device *dev) +{ + struct xl_private *xl_priv = netdev_priv(dev); + struct netdev_hw_addr *ha; + unsigned char dev_mc_address[4] ; + u16 options ; + + if (dev->flags & IFF_PROMISC) + options = 0x0004 ; + else + options = 0x0000 ; + + if (options ^ xl_priv->xl_copy_all_options) { /* Changed, must send command */ + xl_priv->xl_copy_all_options = options ; + xl_srb_cmd(dev, SET_RECEIVE_MODE) ; + return ; + } + + dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ; + + netdev_for_each_mc_addr(ha, dev) { + dev_mc_address[0] |= ha->addr[2]; + dev_mc_address[1] |= ha->addr[3]; + dev_mc_address[2] |= ha->addr[4]; + dev_mc_address[3] |= ha->addr[5]; + } + + if (memcmp(xl_priv->xl_functional_addr,dev_mc_address,4) != 0) { /* Options have changed, run the command */ + memcpy(xl_priv->xl_functional_addr, dev_mc_address,4) ; + xl_srb_cmd(dev, SET_FUNC_ADDRESS) ; + } + return ; +} + + +/* + * We issued an srb command and now we must read + * the response from the completed command. + */ + +static void xl_srb_bh(struct net_device *dev) +{ + struct xl_private *xl_priv = netdev_priv(dev); + u8 __iomem * xl_mmio = xl_priv->xl_mmio ; + u8 srb_cmd, ret_code ; + int i ; + + writel(MEM_BYTE_READ | 0xd0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + srb_cmd = readb(xl_mmio + MMIO_MACDATA) ; + writel((MEM_BYTE_READ | 0xd0000 | xl_priv->srb) +2, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + ret_code = readb(xl_mmio + MMIO_MACDATA) ; + + /* Ret_code is standard across all commands */ + + switch (ret_code) { + case 1: + printk(KERN_INFO "%s: Command: %d - Invalid Command code\n",dev->name,srb_cmd) ; + break ; + case 4: + printk(KERN_INFO "%s: Command: %d - Adapter is closed, must be open for this command\n",dev->name,srb_cmd); + break ; + + case 6: + printk(KERN_INFO "%s: Command: %d - Options Invalid for command\n",dev->name,srb_cmd); + break ; + + case 0: /* Successful command execution */ + switch (srb_cmd) { + case READ_LOG: /* Returns 14 bytes of data from the NIC */ + if(xl_priv->xl_message_level) + printk(KERN_INFO "%s: READ.LOG 14 bytes of data ",dev->name) ; + /* + * We still have to read the log even if message_level = 0 and we don't want + * to see it + */ + for (i=0;i<14;i++) { + writel(MEM_BYTE_READ | 0xd0000 | xl_priv->srb | i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + if(xl_priv->xl_message_level) + printk("%02x:",readb(xl_mmio + MMIO_MACDATA)) ; + } + printk("\n") ; + break ; + case SET_FUNC_ADDRESS: + if(xl_priv->xl_message_level) + printk(KERN_INFO "%s: Functional Address Set\n",dev->name); + break ; + case CLOSE_NIC: + if(xl_priv->xl_message_level) + printk(KERN_INFO "%s: Received CLOSE_NIC interrupt in interrupt handler\n",dev->name); + break ; + case SET_MULTICAST_MODE: + if(xl_priv->xl_message_level) + printk(KERN_INFO "%s: Multicast options successfully changed\n",dev->name) ; + break ; + case SET_RECEIVE_MODE: + if(xl_priv->xl_message_level) { + if (xl_priv->xl_copy_all_options == 0x0004) + printk(KERN_INFO "%s: Entering promiscuous mode\n", dev->name); + else + printk(KERN_INFO "%s: Entering normal receive mode\n",dev->name); + } + break ; + + } /* switch */ + break ; + } /* switch */ + return ; +} + +static int xl_set_mac_address (struct net_device *dev, void *addr) +{ + struct sockaddr *saddr = addr ; + struct xl_private *xl_priv = netdev_priv(dev); + + if (netif_running(dev)) { + printk(KERN_WARNING "%s: Cannot set mac/laa address while card is open\n", dev->name) ; + return -EIO ; + } + + memcpy(xl_priv->xl_laa, saddr->sa_data,dev->addr_len) ; + + if (xl_priv->xl_message_level) { + printk(KERN_INFO "%s: MAC/LAA Set to = %x.%x.%x.%x.%x.%x\n",dev->name, xl_priv->xl_laa[0], + xl_priv->xl_laa[1], xl_priv->xl_laa[2], + xl_priv->xl_laa[3], xl_priv->xl_laa[4], + xl_priv->xl_laa[5]); + } + + return 0 ; +} + +static void xl_arb_cmd(struct net_device *dev) +{ + struct xl_private *xl_priv = netdev_priv(dev); + u8 __iomem * xl_mmio = xl_priv->xl_mmio ; + u8 arb_cmd ; + u16 lan_status, lan_status_diff ; + + writel( ( MEM_BYTE_READ | 0xD0000 | xl_priv->arb), xl_mmio + MMIO_MAC_ACCESS_CMD) ; + arb_cmd = readb(xl_mmio + MMIO_MACDATA) ; + + if (arb_cmd == RING_STATUS_CHANGE) { /* Ring.Status.Change */ + writel( ( (MEM_WORD_READ | 0xD0000 | xl_priv->arb) + 6), xl_mmio + MMIO_MAC_ACCESS_CMD) ; + + printk(KERN_INFO "%s: Ring Status Change: New Status = %04x\n", dev->name, swab16(readw(xl_mmio + MMIO_MACDATA) )) ; + + lan_status = swab16(readw(xl_mmio + MMIO_MACDATA)); + + /* Acknowledge interrupt, this tells nic we are done with the arb */ + writel(ACK_INTERRUPT | ARBCACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; + + lan_status_diff = xl_priv->xl_lan_status ^ lan_status ; + + if (lan_status_diff & (LSC_LWF | LSC_ARW | LSC_FPE | LSC_RR) ) { + if (lan_status_diff & LSC_LWF) + printk(KERN_WARNING "%s: Short circuit detected on the lobe\n",dev->name); + if (lan_status_diff & LSC_ARW) + printk(KERN_WARNING "%s: Auto removal error\n",dev->name); + if (lan_status_diff & LSC_FPE) + printk(KERN_WARNING "%s: FDX Protocol Error\n",dev->name); + if (lan_status_diff & LSC_RR) + printk(KERN_WARNING "%s: Force remove MAC frame received\n",dev->name); + + /* Adapter has been closed by the hardware */ + + netif_stop_queue(dev); + xl_freemem(dev) ; + free_irq(dev->irq,dev); + + printk(KERN_WARNING "%s: Adapter has been closed\n", dev->name); + } /* If serious error */ + + if (xl_priv->xl_message_level) { + if (lan_status_diff & LSC_SIG_LOSS) + printk(KERN_WARNING "%s: No receive signal detected\n", dev->name); + if (lan_status_diff & LSC_HARD_ERR) + printk(KERN_INFO "%s: Beaconing\n",dev->name); + if (lan_status_diff & LSC_SOFT_ERR) + printk(KERN_WARNING "%s: Adapter transmitted Soft Error Report Mac Frame\n",dev->name); + if (lan_status_diff & LSC_TRAN_BCN) + printk(KERN_INFO "%s: We are transmitting the beacon, aaah\n",dev->name); + if (lan_status_diff & LSC_SS) + printk(KERN_INFO "%s: Single Station on the ring\n", dev->name); + if (lan_status_diff & LSC_RING_REC) + printk(KERN_INFO "%s: Ring recovery ongoing\n",dev->name); + if (lan_status_diff & LSC_FDX_MODE) + printk(KERN_INFO "%s: Operating in FDX mode\n",dev->name); + } + + if (lan_status_diff & LSC_CO) { + if (xl_priv->xl_message_level) + printk(KERN_INFO "%s: Counter Overflow\n", dev->name); + /* Issue READ.LOG command */ + xl_srb_cmd(dev, READ_LOG) ; + } + + /* There is no command in the tech docs to issue the read_sr_counters */ + if (lan_status_diff & LSC_SR_CO) { + if (xl_priv->xl_message_level) + printk(KERN_INFO "%s: Source routing counters overflow\n", dev->name); + } + + xl_priv->xl_lan_status = lan_status ; + + } /* Lan.change.status */ + else if ( arb_cmd == RECEIVE_DATA) { /* Received.Data */ +#if XL_DEBUG + printk(KERN_INFO "Received.Data\n"); +#endif + writel( ((MEM_WORD_READ | 0xD0000 | xl_priv->arb) + 6), xl_mmio + MMIO_MAC_ACCESS_CMD) ; + xl_priv->mac_buffer = swab16(readw(xl_mmio + MMIO_MACDATA)) ; + + /* Now we are going to be really basic here and not do anything + * with the data at all. The tech docs do not give me enough + * information to calculate the buffers properly so we're + * just going to tell the nic that we've dealt with the frame + * anyway. + */ + + /* Acknowledge interrupt, this tells nic we are done with the arb */ + writel(ACK_INTERRUPT | ARBCACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; + + /* Is the ASB free ? */ + + xl_priv->asb_queued = 0 ; + writel( ((MEM_BYTE_READ | 0xD0000 | xl_priv->asb) + 2), xl_mmio + MMIO_MAC_ACCESS_CMD) ; + if (readb(xl_mmio + MMIO_MACDATA) != 0xff) { + xl_priv->asb_queued = 1 ; + + xl_wait_misr_flags(dev) ; + + writel(MEM_BYTE_WRITE | MF_ASBFR, xl_mmio + MMIO_MAC_ACCESS_CMD); + writeb(0xff, xl_mmio + MMIO_MACDATA) ; + writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(MISR_ASBFR, xl_mmio + MMIO_MACDATA) ; + return ; + /* Drop out and wait for the bottom half to be run */ + } + + xl_asb_cmd(dev) ; + + } else { + printk(KERN_WARNING "%s: Received unknown arb (xl_priv) command: %02x\n",dev->name,arb_cmd); + } + + /* Acknowledge the arb interrupt */ + + writel(ACK_INTERRUPT | ARBCACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ; + + return ; +} + + +/* + * There is only one asb command, but we can get called from different + * places. + */ + +static void xl_asb_cmd(struct net_device *dev) +{ + struct xl_private *xl_priv = netdev_priv(dev); + u8 __iomem * xl_mmio = xl_priv->xl_mmio ; + + if (xl_priv->asb_queued == 1) + writel(ACK_INTERRUPT | LATCH_ACK | ASBFACK, xl_mmio + MMIO_COMMAND) ; + + writel(MEM_BYTE_WRITE | 0xd0000 | xl_priv->asb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(0x81, xl_mmio + MMIO_MACDATA) ; + + writel(MEM_WORD_WRITE | 0xd0000 | xl_priv->asb | 6, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writew(swab16(xl_priv->mac_buffer), xl_mmio + MMIO_MACDATA) ; + + xl_wait_misr_flags(dev) ; + + writel(MEM_BYTE_WRITE | MF_RASB, xl_mmio + MMIO_MAC_ACCESS_CMD); + writeb(0xff, xl_mmio + MMIO_MACDATA) ; + + writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(MISR_RASB, xl_mmio + MMIO_MACDATA) ; + + xl_priv->asb_queued = 2 ; + + return ; +} + +/* + * This will only get called if there was an error + * from the asb cmd. + */ +static void xl_asb_bh(struct net_device *dev) +{ + struct xl_private *xl_priv = netdev_priv(dev); + u8 __iomem * xl_mmio = xl_priv->xl_mmio ; + u8 ret_code ; + + writel(MMIO_BYTE_READ | 0xd0000 | xl_priv->asb | 2, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + ret_code = readb(xl_mmio + MMIO_MACDATA) ; + switch (ret_code) { + case 0x01: + printk(KERN_INFO "%s: ASB Command, unrecognized command code\n",dev->name); + break ; + case 0x26: + printk(KERN_INFO "%s: ASB Command, unexpected receive buffer\n", dev->name); + break ; + case 0x40: + printk(KERN_INFO "%s: ASB Command, Invalid Station ID\n", dev->name); + break ; + } + xl_priv->asb_queued = 0 ; + writel(ACK_INTERRUPT | LATCH_ACK | ASBFACK, xl_mmio + MMIO_COMMAND) ; + return ; +} + +/* + * Issue srb commands to the nic + */ + +static void xl_srb_cmd(struct net_device *dev, int srb_cmd) +{ + struct xl_private *xl_priv = netdev_priv(dev); + u8 __iomem * xl_mmio = xl_priv->xl_mmio ; + + switch (srb_cmd) { + case READ_LOG: + writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(READ_LOG, xl_mmio + MMIO_MACDATA) ; + break; + + case CLOSE_NIC: + writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(CLOSE_NIC, xl_mmio + MMIO_MACDATA) ; + break ; + + case SET_RECEIVE_MODE: + writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(SET_RECEIVE_MODE, xl_mmio + MMIO_MACDATA) ; + writel(MEM_WORD_WRITE | 0xD0000 | xl_priv->srb | 4, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writew(xl_priv->xl_copy_all_options, xl_mmio + MMIO_MACDATA) ; + break ; + + case SET_FUNC_ADDRESS: + writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(SET_FUNC_ADDRESS, xl_mmio + MMIO_MACDATA) ; + writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 6 , xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(xl_priv->xl_functional_addr[0], xl_mmio + MMIO_MACDATA) ; + writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 7 , xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(xl_priv->xl_functional_addr[1], xl_mmio + MMIO_MACDATA) ; + writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 8 , xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(xl_priv->xl_functional_addr[2], xl_mmio + MMIO_MACDATA) ; + writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 9 , xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(xl_priv->xl_functional_addr[3], xl_mmio + MMIO_MACDATA) ; + break ; + } /* switch */ + + + xl_wait_misr_flags(dev) ; + + /* Write 0xff to the CSRB flag */ + writel(MEM_BYTE_WRITE | MF_CSRB , xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(0xFF, xl_mmio + MMIO_MACDATA) ; + /* Set csrb bit in MISR register to process command */ + writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(MISR_CSRB, xl_mmio + MMIO_MACDATA) ; + xl_priv->srb_queued = 1 ; + + return ; +} + +/* + * This is nasty, to use the MISR command you have to wait for 6 memory locations + * to be zero. This is the way the driver does on other OS'es so we should be ok with + * the empty loop. + */ + +static void xl_wait_misr_flags(struct net_device *dev) +{ + struct xl_private *xl_priv = netdev_priv(dev); + u8 __iomem * xl_mmio = xl_priv->xl_mmio ; + + int i ; + + writel(MMIO_BYTE_READ | MISR_RW, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + if (readb(xl_mmio + MMIO_MACDATA) != 0) { /* Misr not clear */ + for (i=0; i<6; i++) { + writel(MEM_BYTE_READ | 0xDFFE0 | i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + while (readb(xl_mmio + MMIO_MACDATA) != 0) { + ; /* Empty Loop */ + } + } + } + + writel(MMIO_BYTE_WRITE | MISR_AND, xl_mmio + MMIO_MAC_ACCESS_CMD) ; + writeb(0x80, xl_mmio + MMIO_MACDATA) ; + + return ; +} + +/* + * Change mtu size, this should work the same as olympic + */ + +static int xl_change_mtu(struct net_device *dev, int mtu) +{ + struct xl_private *xl_priv = netdev_priv(dev); + u16 max_mtu ; + + if (xl_priv->xl_ring_speed == 4) + max_mtu = 4500 ; + else + max_mtu = 18000 ; + + if (mtu > max_mtu) + return -EINVAL ; + if (mtu < 100) + return -EINVAL ; + + dev->mtu = mtu ; + xl_priv->pkt_buf_sz = mtu + TR_HLEN ; + + return 0 ; +} + +static void __devexit xl_remove_one (struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct xl_private *xl_priv=netdev_priv(dev); + + release_firmware(xl_priv->fw); + unregister_netdev(dev); + iounmap(xl_priv->xl_mmio) ; + pci_release_regions(pdev) ; + pci_set_drvdata(pdev,NULL) ; + free_netdev(dev); + return ; +} + +static struct pci_driver xl_3c359_driver = { + .name = "3c359", + .id_table = xl_pci_tbl, + .probe = xl_probe, + .remove = __devexit_p(xl_remove_one), +}; + +module_pci_driver(xl_3c359_driver); + +MODULE_LICENSE("GPL") ; diff --git a/trunk/drivers/net/tokenring/3c359.h b/trunk/drivers/net/tokenring/3c359.h new file mode 100644 index 000000000000..bcb1a6b4a4c7 --- /dev/null +++ b/trunk/drivers/net/tokenring/3c359.h @@ -0,0 +1,291 @@ +/* + * 3c359.h (c) 2000 Mike Phillips (mikep@linuxtr.net) All Rights Reserved + * + * Linux driver for 3Com 3C359 Token Link PCI XL cards. + * + * This software may be used and distributed according to the terms + * of the GNU General Public License Version 2 or (at your option) + * any later verion, incorporated herein by reference. + */ + +/* Memory Access Commands */ +#define IO_BYTE_READ 0x28 << 24 +#define IO_BYTE_WRITE 0x18 << 24 +#define IO_WORD_READ 0x20 << 24 +#define IO_WORD_WRITE 0x10 << 24 +#define MMIO_BYTE_READ 0x88 << 24 +#define MMIO_BYTE_WRITE 0x48 << 24 +#define MMIO_WORD_READ 0x80 << 24 +#define MMIO_WORD_WRITE 0x40 << 24 +#define MEM_BYTE_READ 0x8C << 24 +#define MEM_BYTE_WRITE 0x4C << 24 +#define MEM_WORD_READ 0x84 << 24 +#define MEM_WORD_WRITE 0x44 << 24 + +#define PMBAR 0x1C80 +#define PMB_CPHOLD (1<<10) + +#define CPATTENTION 0x180D +#define CPA_PMBARVIS (1<<7) +#define CPA_MEMWREN (1<<6) + +#define SWITCHSETTINGS 0x1C88 +#define EECONTROL 0x1C8A +#define EEDATA 0x1C8C +#define EEREAD 0x0080 +#define EEWRITE 0x0040 +#define EEERASE 0x0060 +#define EE_ENABLE_WRITE 0x0030 +#define EEBUSY (1<<15) + +#define WRBR 0xCDE02 +#define WWOR 0xCDE04 +#define WWCR 0xCDE06 +#define MACSTATUS 0xCDE08 +#define MISR_RW 0xCDE0B +#define MISR_AND 0xCDE2B +#define MISR_SET 0xCDE4B +#define RXBUFAREA 0xCDE10 +#define RXEARLYTHRESH 0xCDE12 +#define TXSTARTTHRESH 0x58 +#define DNPRIREQTHRESH 0x2C + +#define MISR_CSRB (1<<5) +#define MISR_RASB (1<<4) +#define MISR_SRBFR (1<<3) +#define MISR_ASBFR (1<<2) +#define MISR_ARBF (1<<1) + +/* MISR Flags memory locations */ +#define MF_SSBF 0xDFFE0 +#define MF_ARBF 0xDFFE1 +#define MF_ASBFR 0xDFFE2 +#define MF_SRBFR 0xDFFE3 +#define MF_RASB 0xDFFE4 +#define MF_CSRB 0xDFFE5 + +#define MMIO_MACDATA 0x10 +#define MMIO_MAC_ACCESS_CMD 0x14 +#define MMIO_TIMER 0x1A +#define MMIO_DMA_CTRL 0x20 +#define MMIO_DNLISTPTR 0x24 +#define MMIO_HASHFILTER 0x28 +#define MMIO_CONFIG 0x29 +#define MMIO_DNPRIREQTHRESH 0x2C +#define MMIO_DNPOLL 0x2D +#define MMIO_UPPKTSTATUS 0x30 +#define MMIO_FREETIMER 0x34 +#define MMIO_COUNTDOWN 0x36 +#define MMIO_UPLISTPTR 0x38 +#define MMIO_UPPOLL 0x3C +#define MMIO_UPBURSTTHRESH 0x40 +#define MMIO_DNBURSTTHRESH 0x41 +#define MMIO_INTSTATUS_AUTO 0x56 +#define MMIO_TXSTARTTHRESH 0x58 +#define MMIO_INTERRUPTENABLE 0x5A +#define MMIO_INDICATIONENABLE 0x5C +#define MMIO_COMMAND 0x5E /* These two are meant to be the same */ +#define MMIO_INTSTATUS 0x5E /* Makes the code more readable this way */ +#define INTSTAT_CMD_IN_PROGRESS (1<<12) +#define INTSTAT_SRB (1<<14) +#define INTSTAT_INTLATCH (1<<0) + +/* Indication / Interrupt Mask + * Annoyingly the bits to be set in the indication and interrupt enable + * do not match with the actual bits received in the interrupt, although + * they are in the same order. + * The mapping for the indication / interrupt are: + * Bit Indication / Interrupt + * 0 HostError + * 1 txcomplete + * 2 updneeded + * 3 rxcomplete + * 4 intrequested + * 5 macerror + * 6 dncomplete + * 7 upcomplete + * 8 txunderrun + * 9 asbf + * 10 srbr + * 11 arbc + * + * The only ones we don't want to receive are txcomplete and rxcomplete + * we use dncomplete and upcomplete instead. + */ + +#define INT_MASK 0xFF5 + +/* Note the subtle difference here, IND and INT */ + +#define SETINDENABLE (8<<12) +#define SETINTENABLE (7<<12) +#define SRBBIT (1<<10) +#define ASBBIT (1<<9) +#define ARBBIT (1<<11) + +#define SRB 0xDFE90 +#define ASB 0xDFED0 +#define ARB 0xD0000 +#define SCRATCH 0xDFEF0 + +#define INT_REQUEST 0x6000 /* (6 << 12) */ +#define ACK_INTERRUPT 0x6800 /* (13 <<11) */ +#define GLOBAL_RESET 0x00 +#define DNDISABLE 0x5000 +#define DNENABLE 0x4800 +#define DNSTALL 0x3002 +#define DNRESET 0x5800 +#define DNUNSTALL 0x3003 +#define UPRESET 0x2800 +#define UPSTALL 0x3000 +#define UPUNSTALL 0x3001 +#define SETCONFIG 0x4000 +#define SETTXSTARTTHRESH 0x9800 + +/* Received Interrupts */ +#define ASBFINT (1<<13) +#define SRBRINT (1<<14) +#define ARBCINT (1<<15) +#define TXUNDERRUN (1<<11) + +#define UPCOMPINT (1<<10) +#define DNCOMPINT (1<<9) +#define HARDERRINT (1<<7) +#define RXCOMPLETE (1<<4) +#define TXCOMPINT (1<<2) +#define HOSTERRINT (1<<1) + +/* Receive descriptor bits */ +#define RXOVERRUN cpu_to_le32(1<<19) +#define RXFC cpu_to_le32(1<<21) +#define RXAR cpu_to_le32(1<<22) +#define RXUPDCOMPLETE cpu_to_le32(1<<23) +#define RXUPDFULL cpu_to_le32(1<<24) +#define RXUPLASTFRAG cpu_to_le32(1<<31) + +/* Transmit descriptor bits */ +#define TXDNCOMPLETE cpu_to_le32(1<<16) +#define TXTXINDICATE cpu_to_le32(1<<27) +#define TXDPDEMPTY cpu_to_le32(1<<29) +#define TXDNINDICATE cpu_to_le32(1<<31) +#define TXDNFRAGLAST cpu_to_le32(1<<31) + +/* Interrupts to Acknowledge */ +#define LATCH_ACK 1 +#define TXCOMPACK (1<<1) +#define INTREQACK (1<<2) +#define DNCOMPACK (1<<3) +#define UPCOMPACK (1<<4) +#define ASBFACK (1<<5) +#define SRBRACK (1<<6) +#define ARBCACK (1<<7) + +#define XL_IO_SPACE 128 +#define SRB_COMMAND_SIZE 50 + +/* Adapter Commands */ +#define REQUEST_INT 0x00 +#define MODIFY_OPEN_PARMS 0x01 +#define RESTORE_OPEN_PARMS 0x02 +#define OPEN_NIC 0x03 +#define CLOSE_NIC 0x04 +#define SET_SLEEP_MODE 0x05 +#define SET_GROUP_ADDRESS 0x06 +#define SET_FUNC_ADDRESS 0x07 +#define READ_LOG 0x08 +#define SET_MULTICAST_MODE 0x0C +#define CHANGE_WAKEUP_PATTERN 0x0D +#define GET_STATISTICS 0x13 +#define SET_RECEIVE_MODE 0x1F + +/* ARB Commands */ +#define RECEIVE_DATA 0x81 +#define RING_STATUS_CHANGE 0x84 + +/* ASB Commands */ +#define ASB_RECEIVE_DATE 0x81 + +/* Defines for LAN STATUS CHANGE reports */ +#define LSC_SIG_LOSS 0x8000 +#define LSC_HARD_ERR 0x4000 +#define LSC_SOFT_ERR 0x2000 +#define LSC_TRAN_BCN 0x1000 +#define LSC_LWF 0x0800 +#define LSC_ARW 0x0400 +#define LSC_FPE 0x0200 +#define LSC_RR 0x0100 +#define LSC_CO 0x0080 +#define LSC_SS 0x0040 +#define LSC_RING_REC 0x0020 +#define LSC_SR_CO 0x0010 +#define LSC_FDX_MODE 0x0004 + +#define XL_MAX_ADAPTERS 8 /* 0x08 __MODULE_STRING can't hand 0xnn */ + +/* 3c359 defaults for buffers */ + +#define XL_RX_RING_SIZE 16 /* must be a power of 2 */ +#define XL_TX_RING_SIZE 16 /* must be a power of 2 */ + +#define PKT_BUF_SZ 4096 /* Default packet size */ + +/* 3c359 data structures */ + +struct xl_tx_desc { + __le32 dnnextptr; + __le32 framestartheader; + __le32 buffer; + __le32 buffer_length; +}; + +struct xl_rx_desc { + __le32 upnextptr; + __le32 framestatus; + __le32 upfragaddr; + __le32 upfraglen; +}; + +struct xl_private { + + + /* These two structures must be aligned on 8 byte boundaries */ + + /* struct xl_rx_desc xl_rx_ring[XL_RX_RING_SIZE]; */ + /* struct xl_tx_desc xl_tx_ring[XL_TX_RING_SIZE]; */ + struct xl_rx_desc *xl_rx_ring ; + struct xl_tx_desc *xl_tx_ring ; + struct sk_buff *tx_ring_skb[XL_TX_RING_SIZE], *rx_ring_skb[XL_RX_RING_SIZE]; + int tx_ring_head, tx_ring_tail ; + int rx_ring_tail, rx_ring_no ; + int free_ring_entries ; + + u16 srb; + u16 arb; + u16 asb; + + u8 __iomem *xl_mmio; + const char *xl_card_name; + struct pci_dev *pdev ; + + spinlock_t xl_lock ; + + volatile int srb_queued; + struct wait_queue *srb_wait; + volatile int asb_queued; + + u16 mac_buffer ; + u16 xl_lan_status ; + u8 xl_ring_speed ; + u16 pkt_buf_sz ; + u8 xl_message_level; + u16 xl_copy_all_options ; + unsigned char xl_functional_addr[4] ; + u16 xl_addr_table_addr, xl_parms_addr ; + u8 xl_laa[6] ; + u32 rx_ring_dma_addr ; + u32 tx_ring_dma_addr ; + + /* firmware section */ + const struct firmware *fw; +}; + diff --git a/trunk/drivers/net/tokenring/Kconfig b/trunk/drivers/net/tokenring/Kconfig new file mode 100644 index 000000000000..ef3bb1326e4f --- /dev/null +++ b/trunk/drivers/net/tokenring/Kconfig @@ -0,0 +1,199 @@ +# +# Token Ring driver configuration +# + +# So far, we only have PCI, ISA, and MCA token ring devices +menuconfig TR + bool "Token Ring driver support" + depends on NETDEVICES && !UML + depends on (PCI || ISA || MCA || CCW || PCMCIA) + help + Token Ring is IBM's way of communication on a local network; the + rest of the world uses Ethernet. To participate on a Token Ring + network, you need a special Token ring network card. If you are + connected to such a Token Ring network and want to use your Token + Ring card under Linux, say Y here and to the driver for your + particular card below and read the Token-Ring mini-HOWTO, available + from . Most people can + say N here. + +if TR + +config WANT_LLC + def_bool y + select LLC + +config PCMCIA_IBMTR + tristate "IBM PCMCIA tokenring adapter support" + depends on IBMTR!=y && PCMCIA + ---help--- + Say Y here if you intend to attach this type of Token Ring PCMCIA + card to your computer. You then also need to say Y to "Token Ring + driver support". + + To compile this driver as a module, choose M here: the module will be + called ibmtr_cs. + +config IBMTR + tristate "IBM Tropic chipset based adapter support" + depends on ISA || MCA + ---help--- + This is support for all IBM Token Ring cards that don't use DMA. If + you have such a beast, say Y and read the Token-Ring mini-HOWTO, + available from . + + Warning: this driver will almost definitely fail if more than one + active Token Ring card is present. + + To compile this driver as a module, choose M here: the module will be + called ibmtr. + +config IBMOL + tristate "IBM Olympic chipset PCI adapter support" + depends on PCI + ---help--- + This is support for all non-Lanstreamer IBM PCI Token Ring Cards. + Specifically this is all IBM PCI, PCI Wake On Lan, PCI II, PCI II + Wake On Lan, and PCI 100/16/4 adapters. + + If you have such an adapter, say Y and read the Token-Ring + mini-HOWTO, available from . + + To compile this driver as a module, choose M here: the module will be + called olympic. + + Also read or check the + Linux Token Ring Project site for the latest information at + . + +config IBMLS + tristate "IBM Lanstreamer chipset PCI adapter support" + depends on PCI && !64BIT + help + This is support for IBM Lanstreamer PCI Token Ring Cards. + + If you have such an adapter, say Y and read the Token-Ring + mini-HOWTO, available from . + + To compile this driver as a module, choose M here: the module will be + called lanstreamer. + +config 3C359 + tristate "3Com 3C359 Token Link Velocity XL adapter support" + depends on PCI + ---help--- + This is support for the 3Com PCI Velocity XL cards, specifically + the 3Com 3C359, please note this is not for the 3C339 cards, you + should use the tms380 driver instead. + + If you have such an adapter, say Y and read the Token-Ring + mini-HOWTO, available from . + + To compile this driver as a module, choose M here: the module will be + called 3c359. + + Also read the file or check the + Linux Token Ring Project site for the latest information at + + +config TMS380TR + tristate "Generic TMS380 Token Ring ISA/PCI adapter support" + depends on PCI || ISA || MCA + select FW_LOADER + ---help--- + This driver provides generic support for token ring adapters + based on the Texas Instruments TMS380 series chipsets. This + includes the SysKonnect TR4/16(+) ISA (SK-4190), SysKonnect + TR4/16(+) PCI (SK-4590), SysKonnect TR4/16 PCI (SK-4591), + Compaq 4/16 PCI, Thomas-Conrad TC4048 4/16 PCI, and several + Madge adapters. If you say Y here, you will be asked to select + which cards to support below. If you're using modules, each + class of card will be supported by a separate module. + + If you have such an adapter and would like to use it, say Y and + read the Token-Ring mini-HOWTO, available from + . + + Also read the file or + check . + + To compile this driver as a module, choose M here: the module will be + called tms380tr. + +config TMSPCI + tristate "Generic TMS380 PCI support" + depends on TMS380TR && PCI + ---help--- + This tms380 module supports generic TMS380-based PCI cards. + + These cards are known to work: + - Compaq 4/16 TR PCI + - SysKonnect TR4/16 PCI (SK-4590/SK-4591) + - Thomas-Conrad TC4048 PCI 4/16 + - 3Com Token Link Velocity + + To compile this driver as a module, choose M here: the module will be + called tmspci. + +config SKISA + tristate "SysKonnect TR4/16 ISA support" + depends on TMS380TR && ISA && ISA_DMA_API + help + This tms380 module supports SysKonnect TR4/16 ISA cards. + + These cards are known to work: + - SysKonnect TR4/16 ISA (SK-4190) + + To compile this driver as a module, choose M here: the module will be + called skisa. + +config PROTEON + tristate "Proteon ISA support" + depends on TMS380TR && ISA && ISA_DMA_API + help + This tms380 module supports Proteon ISA cards. + + These cards are known to work: + - Proteon 1392 + - Proteon 1392 plus + + To compile this driver as a module, choose M here: the module will be + called proteon. + +config ABYSS + tristate "Madge Smart 16/4 PCI Mk2 support" + depends on TMS380TR && PCI + help + This tms380 module supports the Madge Smart 16/4 PCI Mk2 + cards (51-02). + + To compile this driver as a module, choose M here: the module will be + called abyss. + +config MADGEMC + tristate "Madge Smart 16/4 Ringnode MicroChannel" + depends on TMS380TR && MCA + help + This tms380 module supports the Madge Smart 16/4 MC16 and MC32 + MicroChannel adapters. + + To compile this driver as a module, choose M here: the module will be + called madgemc. + +config SMCTR + tristate "SMC ISA/MCA adapter support" + depends on (ISA || MCA_LEGACY) && (BROKEN || !64BIT) + ---help--- + This is support for the ISA and MCA SMC Token Ring cards, + specifically SMC TokenCard Elite (8115T) and SMC TokenCard Elite/A + (8115T/A) adapters. + + If you have such an adapter and would like to use it, say Y or M and + read the Token-Ring mini-HOWTO, available from + and the file + . + + To compile this driver as a module, choose M here: the module will be + called smctr. + +endif # TR diff --git a/trunk/drivers/net/tokenring/Makefile b/trunk/drivers/net/tokenring/Makefile new file mode 100644 index 000000000000..f1be8d97b7a8 --- /dev/null +++ b/trunk/drivers/net/tokenring/Makefile @@ -0,0 +1,16 @@ +# +# Makefile for drivers/net/tokenring +# + +obj-$(CONFIG_PCMCIA_IBMTR) += ibmtr_cs.o +obj-$(CONFIG_IBMTR) += ibmtr.o +obj-$(CONFIG_IBMOL) += olympic.o +obj-$(CONFIG_IBMLS) += lanstreamer.o +obj-$(CONFIG_TMS380TR) += tms380tr.o +obj-$(CONFIG_ABYSS) += abyss.o +obj-$(CONFIG_MADGEMC) += madgemc.o +obj-$(CONFIG_PROTEON) += proteon.o +obj-$(CONFIG_TMSPCI) += tmspci.o +obj-$(CONFIG_SKISA) += skisa.o +obj-$(CONFIG_SMCTR) += smctr.o +obj-$(CONFIG_3C359) += 3c359.o diff --git a/trunk/drivers/net/tokenring/abyss.c b/trunk/drivers/net/tokenring/abyss.c new file mode 100644 index 000000000000..b715e6b444da --- /dev/null +++ b/trunk/drivers/net/tokenring/abyss.c @@ -0,0 +1,468 @@ +/* + * abyss.c: Network driver for the Madge Smart 16/4 PCI Mk2 token ring card. + * + * Written 1999-2000 by Adam Fritzler + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * This driver module supports the following cards: + * - Madge Smart 16/4 PCI Mk2 + * + * Maintainer(s): + * AF Adam Fritzler + * + * Modification History: + * 30-Dec-99 AF Split off from the tms380tr driver. + * 22-Jan-00 AF Updated to use indirect read/writes + * 23-Nov-00 JG New PCI API, cleanups + * + * + * TODO: + * 1. See if we can use MMIO instead of inb/outb/inw/outw + * 2. Add support for Mk1 (has AT24 attached to the PCI + * config registers) + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "tms380tr.h" +#include "abyss.h" /* Madge-specific constants */ + +static char version[] __devinitdata = +"abyss.c: v1.02 23/11/2000 by Adam Fritzler\n"; + +#define ABYSS_IO_EXTENT 64 + +static DEFINE_PCI_DEVICE_TABLE(abyss_pci_tbl) = { + { PCI_VENDOR_ID_MADGE, PCI_DEVICE_ID_MADGE_MK2, + PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_TOKEN_RING << 8, 0x00ffffff, }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(pci, abyss_pci_tbl); + +MODULE_LICENSE("GPL"); + +static int abyss_open(struct net_device *dev); +static int abyss_close(struct net_device *dev); +static void abyss_enable(struct net_device *dev); +static int abyss_chipset_init(struct net_device *dev); +static void abyss_read_eeprom(struct net_device *dev); +static unsigned short abyss_setnselout_pins(struct net_device *dev); + +static void at24_writedatabyte(unsigned long regaddr, unsigned char byte); +static int at24_sendfullcmd(unsigned long regaddr, unsigned char cmd, unsigned char addr); +static int at24_sendcmd(unsigned long regaddr, unsigned char cmd); +static unsigned char at24_readdatabit(unsigned long regaddr); +static unsigned char at24_readdatabyte(unsigned long regaddr); +static int at24_waitforack(unsigned long regaddr); +static int at24_waitfornack(unsigned long regaddr); +static void at24_setlines(unsigned long regaddr, unsigned char clock, unsigned char data); +static void at24_start(unsigned long regaddr); +static unsigned char at24_readb(unsigned long regaddr, unsigned char addr); + +static unsigned short abyss_sifreadb(struct net_device *dev, unsigned short reg) +{ + return inb(dev->base_addr + reg); +} + +static unsigned short abyss_sifreadw(struct net_device *dev, unsigned short reg) +{ + return inw(dev->base_addr + reg); +} + +static void abyss_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg) +{ + outb(val, dev->base_addr + reg); +} + +static void abyss_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg) +{ + outw(val, dev->base_addr + reg); +} + +static struct net_device_ops abyss_netdev_ops; + +static int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + static int versionprinted; + struct net_device *dev; + struct net_local *tp; + int ret, pci_irq_line; + unsigned long pci_ioaddr; + + if (versionprinted++ == 0) + printk("%s", version); + + if (pci_enable_device(pdev)) + return -EIO; + + /* Remove I/O space marker in bit 0. */ + pci_irq_line = pdev->irq; + pci_ioaddr = pci_resource_start (pdev, 0); + + /* At this point we have found a valid card. */ + + dev = alloc_trdev(sizeof(struct net_local)); + if (!dev) + return -ENOMEM; + + if (!request_region(pci_ioaddr, ABYSS_IO_EXTENT, dev->name)) { + ret = -EBUSY; + goto err_out_trdev; + } + + ret = request_irq(pdev->irq, tms380tr_interrupt, IRQF_SHARED, + dev->name, dev); + if (ret) + goto err_out_region; + + dev->base_addr = pci_ioaddr; + dev->irq = pci_irq_line; + + printk("%s: Madge Smart 16/4 PCI Mk2 (Abyss)\n", dev->name); + printk("%s: IO: %#4lx IRQ: %d\n", + dev->name, pci_ioaddr, dev->irq); + /* + * The TMS SIF registers lay 0x10 above the card base address. + */ + dev->base_addr += 0x10; + + ret = tmsdev_init(dev, &pdev->dev); + if (ret) { + printk("%s: unable to get memory for dev->priv.\n", + dev->name); + goto err_out_irq; + } + + abyss_read_eeprom(dev); + + printk("%s: Ring Station Address: %pM\n", dev->name, dev->dev_addr); + + tp = netdev_priv(dev); + tp->setnselout = abyss_setnselout_pins; + tp->sifreadb = abyss_sifreadb; + tp->sifreadw = abyss_sifreadw; + tp->sifwriteb = abyss_sifwriteb; + tp->sifwritew = abyss_sifwritew; + + memcpy(tp->ProductID, "Madge PCI 16/4 Mk2", PROD_ID_SIZE + 1); + + dev->netdev_ops = &abyss_netdev_ops; + + pci_set_drvdata(pdev, dev); + SET_NETDEV_DEV(dev, &pdev->dev); + + ret = register_netdev(dev); + if (ret) + goto err_out_tmsdev; + return 0; + +err_out_tmsdev: + pci_set_drvdata(pdev, NULL); + tmsdev_term(dev); +err_out_irq: + free_irq(pdev->irq, dev); +err_out_region: + release_region(pci_ioaddr, ABYSS_IO_EXTENT); +err_out_trdev: + free_netdev(dev); + return ret; +} + +static unsigned short abyss_setnselout_pins(struct net_device *dev) +{ + unsigned short val = 0; + struct net_local *tp = netdev_priv(dev); + + if(tp->DataRate == SPEED_4) + val |= 0x01; /* Set 4Mbps */ + else + val |= 0x00; /* Set 16Mbps */ + + return val; +} + +/* + * The following Madge boards should use this code: + * - Smart 16/4 PCI Mk2 (Abyss) + * - Smart 16/4 PCI Mk1 (PCI T) + * - Smart 16/4 Client Plus PnP (Big Apple) + * - Smart 16/4 Cardbus Mk2 + * + * These access an Atmel AT24 SEEPROM using their glue chip registers. + * + */ +static void at24_writedatabyte(unsigned long regaddr, unsigned char byte) +{ + int i; + + for (i = 0; i < 8; i++) { + at24_setlines(regaddr, 0, (byte >> (7-i))&0x01); + at24_setlines(regaddr, 1, (byte >> (7-i))&0x01); + at24_setlines(regaddr, 0, (byte >> (7-i))&0x01); + } +} + +static int at24_sendfullcmd(unsigned long regaddr, unsigned char cmd, unsigned char addr) +{ + if (at24_sendcmd(regaddr, cmd)) { + at24_writedatabyte(regaddr, addr); + return at24_waitforack(regaddr); + } + return 0; +} + +static int at24_sendcmd(unsigned long regaddr, unsigned char cmd) +{ + int i; + + for (i = 0; i < 10; i++) { + at24_start(regaddr); + at24_writedatabyte(regaddr, cmd); + if (at24_waitforack(regaddr)) + return 1; + } + return 0; +} + +static unsigned char at24_readdatabit(unsigned long regaddr) +{ + unsigned char val; + + at24_setlines(regaddr, 0, 1); + at24_setlines(regaddr, 1, 1); + val = (inb(regaddr) & AT24_DATA)?1:0; + at24_setlines(regaddr, 1, 1); + at24_setlines(regaddr, 0, 1); + return val; +} + +static unsigned char at24_readdatabyte(unsigned long regaddr) +{ + unsigned char data = 0; + int i; + + for (i = 0; i < 8; i++) { + data <<= 1; + data |= at24_readdatabit(regaddr); + } + + return data; +} + +static int at24_waitforack(unsigned long regaddr) +{ + int i; + + for (i = 0; i < 10; i++) { + if ((at24_readdatabit(regaddr) & 0x01) == 0x00) + return 1; + } + return 0; +} + +static int at24_waitfornack(unsigned long regaddr) +{ + int i; + for (i = 0; i < 10; i++) { + if ((at24_readdatabit(regaddr) & 0x01) == 0x01) + return 1; + } + return 0; +} + +static void at24_setlines(unsigned long regaddr, unsigned char clock, unsigned char data) +{ + unsigned char val = AT24_ENABLE; + if (clock) + val |= AT24_CLOCK; + if (data) + val |= AT24_DATA; + + outb(val, regaddr); + tms380tr_wait(20); /* Very necessary. */ +} + +static void at24_start(unsigned long regaddr) +{ + at24_setlines(regaddr, 0, 1); + at24_setlines(regaddr, 1, 1); + at24_setlines(regaddr, 1, 0); + at24_setlines(regaddr, 0, 1); +} + +static unsigned char at24_readb(unsigned long regaddr, unsigned char addr) +{ + unsigned char data = 0xff; + + if (at24_sendfullcmd(regaddr, AT24_WRITE, addr)) { + if (at24_sendcmd(regaddr, AT24_READ)) { + data = at24_readdatabyte(regaddr); + if (!at24_waitfornack(regaddr)) + data = 0xff; + } + } + return data; +} + + +/* + * Enable basic functions of the Madge chipset needed + * for initialization. + */ +static void abyss_enable(struct net_device *dev) +{ + unsigned char reset_reg; + unsigned long ioaddr; + + ioaddr = dev->base_addr; + reset_reg = inb(ioaddr + PCIBM2_RESET_REG); + reset_reg |= PCIBM2_RESET_REG_CHIP_NRES; + outb(reset_reg, ioaddr + PCIBM2_RESET_REG); + tms380tr_wait(100); +} + +/* + * Enable the functions of the Madge chipset needed for + * full working order. + */ +static int abyss_chipset_init(struct net_device *dev) +{ + unsigned char reset_reg; + unsigned long ioaddr; + + ioaddr = dev->base_addr; + + reset_reg = inb(ioaddr + PCIBM2_RESET_REG); + + reset_reg |= PCIBM2_RESET_REG_CHIP_NRES; + outb(reset_reg, ioaddr + PCIBM2_RESET_REG); + + reset_reg &= ~(PCIBM2_RESET_REG_CHIP_NRES | + PCIBM2_RESET_REG_FIFO_NRES | + PCIBM2_RESET_REG_SIF_NRES); + outb(reset_reg, ioaddr + PCIBM2_RESET_REG); + + tms380tr_wait(100); + + reset_reg |= PCIBM2_RESET_REG_CHIP_NRES; + outb(reset_reg, ioaddr + PCIBM2_RESET_REG); + + reset_reg |= PCIBM2_RESET_REG_SIF_NRES; + outb(reset_reg, ioaddr + PCIBM2_RESET_REG); + + reset_reg |= PCIBM2_RESET_REG_FIFO_NRES; + outb(reset_reg, ioaddr + PCIBM2_RESET_REG); + + outb(PCIBM2_INT_CONTROL_REG_SINTEN | + PCIBM2_INT_CONTROL_REG_PCI_ERR_ENABLE, + ioaddr + PCIBM2_INT_CONTROL_REG); + + outb(30, ioaddr + PCIBM2_FIFO_THRESHOLD); + + return 0; +} + +static inline void abyss_chipset_close(struct net_device *dev) +{ + unsigned long ioaddr; + + ioaddr = dev->base_addr; + outb(0, ioaddr + PCIBM2_RESET_REG); +} + +/* + * Read configuration data from the AT24 SEEPROM on Madge cards. + * + */ +static void abyss_read_eeprom(struct net_device *dev) +{ + struct net_local *tp; + unsigned long ioaddr; + unsigned short val; + int i; + + tp = netdev_priv(dev); + ioaddr = dev->base_addr; + + /* Must enable glue chip first */ + abyss_enable(dev); + + val = at24_readb(ioaddr + PCIBM2_SEEPROM_REG, + PCIBM2_SEEPROM_RING_SPEED); + tp->DataRate = val?SPEED_4:SPEED_16; /* set open speed */ + printk("%s: SEEPROM: ring speed: %dMb/sec\n", dev->name, tp->DataRate); + + val = at24_readb(ioaddr + PCIBM2_SEEPROM_REG, + PCIBM2_SEEPROM_RAM_SIZE) * 128; + printk("%s: SEEPROM: adapter RAM: %dkb\n", dev->name, val); + + dev->addr_len = 6; + for (i = 0; i < 6; i++) + dev->dev_addr[i] = at24_readb(ioaddr + PCIBM2_SEEPROM_REG, + PCIBM2_SEEPROM_BIA+i); +} + +static int abyss_open(struct net_device *dev) +{ + abyss_chipset_init(dev); + tms380tr_open(dev); + return 0; +} + +static int abyss_close(struct net_device *dev) +{ + tms380tr_close(dev); + abyss_chipset_close(dev); + return 0; +} + +static void __devexit abyss_detach (struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + + BUG_ON(!dev); + unregister_netdev(dev); + release_region(dev->base_addr-0x10, ABYSS_IO_EXTENT); + free_irq(dev->irq, dev); + tmsdev_term(dev); + free_netdev(dev); + pci_set_drvdata(pdev, NULL); +} + +static struct pci_driver abyss_driver = { + .name = "abyss", + .id_table = abyss_pci_tbl, + .probe = abyss_attach, + .remove = __devexit_p(abyss_detach), +}; + +static int __init abyss_init (void) +{ + abyss_netdev_ops = tms380tr_netdev_ops; + + abyss_netdev_ops.ndo_open = abyss_open; + abyss_netdev_ops.ndo_stop = abyss_close; + + return pci_register_driver(&abyss_driver); +} + +static void __exit abyss_rmmod (void) +{ + pci_unregister_driver (&abyss_driver); +} + +module_init(abyss_init); +module_exit(abyss_rmmod); + diff --git a/trunk/drivers/net/tokenring/abyss.h b/trunk/drivers/net/tokenring/abyss.h new file mode 100644 index 000000000000..b0a473b89133 --- /dev/null +++ b/trunk/drivers/net/tokenring/abyss.h @@ -0,0 +1,58 @@ +/* + * abyss.h: Header for the abyss tms380tr module + * + * Authors: + * - Adam Fritzler + */ + +#ifndef __LINUX_MADGETR_H +#define __LINUX_MADGETR_H + +#ifdef __KERNEL__ + +/* + * For Madge Smart 16/4 PCI Mk2. Since we increment the base address + * to get everything correct for the TMS SIF, we do these as negatives + * as they fall below the SIF in addressing. + */ +#define PCIBM2_INT_STATUS_REG ((short)-15)/* 0x01 */ +#define PCIBM2_INT_CONTROL_REG ((short)-14)/* 0x02 */ +#define PCIBM2_RESET_REG ((short)-12)/* 0x04 */ +#define PCIBM2_SEEPROM_REG ((short)-9) /* 0x07 */ + +#define PCIBM2_INT_CONTROL_REG_SINTEN 0x02 +#define PCIBM2_INT_CONTROL_REG_PCI_ERR_ENABLE 0x80 +#define PCIBM2_INT_STATUS_REG_PCI_ERR 0x80 + +#define PCIBM2_RESET_REG_CHIP_NRES 0x01 +#define PCIBM2_RESET_REG_FIFO_NRES 0x02 +#define PCIBM2_RESET_REG_SIF_NRES 0x04 + +#define PCIBM2_FIFO_THRESHOLD 0x21 +#define PCIBM2_BURST_LENGTH 0x22 + +/* + * Bits in PCIBM2_SEEPROM_REG. + */ +#define AT24_ENABLE 0x04 +#define AT24_DATA 0x02 +#define AT24_CLOCK 0x01 + +/* + * AT24 Commands. + */ +#define AT24_WRITE 0xA0 +#define AT24_READ 0xA1 + +/* + * Addresses in AT24 SEEPROM. + */ +#define PCIBM2_SEEPROM_BIA 0x12 +#define PCIBM2_SEEPROM_RING_SPEED 0x18 +#define PCIBM2_SEEPROM_RAM_SIZE 0x1A +#define PCIBM2_SEEPROM_HWF1 0x1C +#define PCIBM2_SEEPROM_HWF2 0x1E + + +#endif /* __KERNEL__ */ +#endif /* __LINUX_MADGETR_H */ diff --git a/trunk/drivers/net/tokenring/ibmtr.c b/trunk/drivers/net/tokenring/ibmtr.c new file mode 100644 index 000000000000..b5c8c18f5046 --- /dev/null +++ b/trunk/drivers/net/tokenring/ibmtr.c @@ -0,0 +1,1964 @@ +/* ibmtr.c: A shared-memory IBM Token Ring 16/4 driver for linux + * + * Written 1993 by Mark Swanson and Peter De Schrijver. + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * This device driver should work with Any IBM Token Ring Card that does + * not use DMA. + * + * I used Donald Becker's (becker@scyld.com) device driver work + * as a base for most of my initial work. + * + * Changes by Peter De Schrijver + * (Peter.Deschrijver@linux.cc.kuleuven.ac.be) : + * + * + changed name to ibmtr.c in anticipation of other tr boards. + * + changed reset code and adapter open code. + * + added SAP open code. + * + a first attempt to write interrupt, transmit and receive routines. + * + * Changes by David W. Morris (dwm@shell.portal.com) : + * 941003 dwm: - Restructure tok_probe for multiple adapters, devices. + * + Add comments, misc reorg for clarity. + * + Flatten interrupt handler levels. + * + * Changes by Farzad Farid (farzy@zen.via.ecp.fr) + * and Pascal Andre (andre@chimay.via.ecp.fr) (March 9 1995) : + * + multi ring support clean up. + * + RFC1042 compliance enhanced. + * + * Changes by Pascal Andre (andre@chimay.via.ecp.fr) (September 7 1995) : + * + bug correction in tr_tx + * + removed redundant information display + * + some code reworking + * + * Changes by Michel Lespinasse (walken@via.ecp.fr), + * Yann Doussot (doussot@via.ecp.fr) and Pascal Andre (andre@via.ecp.fr) + * (February 18, 1996) : + * + modified shared memory and mmio access port the driver to + * alpha platform (structure access -> readb/writeb) + * + * Changes by Steve Kipisz (bungy@ibm.net or kipisz@vnet.ibm.com) + * (January 18 1996): + * + swapped WWOR and WWCR in ibmtr.h + * + moved some init code from tok_probe into trdev_init. The + * PCMCIA code can call trdev_init to complete initializing + * the driver. + * + added -DPCMCIA to support PCMCIA + * + detecting PCMCIA Card Removal in interrupt handler. If + * ISRP is FF, then a PCMCIA card has been removed + * 10/2000 Burt needed a new method to avoid crashing the OS + * + * Changes by Paul Norton (pnorton@cts.com) : + * + restructured the READ.LOG logic to prevent the transmit SRB + * from being rudely overwritten before the transmit cycle is + * complete. (August 15 1996) + * + completed multiple adapter support. (November 20 1996) + * + implemented csum_partial_copy in tr_rx and increased receive + * buffer size and count. Minor fixes. (March 15, 1997) + * + * Changes by Christopher Turcksin + * + Now compiles ok as a module again. + * + * Changes by Paul Norton (pnorton@ieee.org) : + * + moved the header manipulation code in tr_tx and tr_rx to + * net/802/tr.c. (July 12 1997) + * + add retry and timeout on open if cable disconnected. (May 5 1998) + * + lifted 2000 byte mtu limit. now depends on shared-RAM size. + * May 25 1998) + * + can't allocate 2k recv buff at 8k shared-RAM. (20 October 1998) + * + * Changes by Joel Sloan (jjs@c-me.com) : + * + disable verbose debug messages by default - to enable verbose + * debugging, edit the IBMTR_DEBUG_MESSAGES define below + * + * Changes by Mike Phillips : + * + Added extra #ifdef's to work with new PCMCIA Token Ring Code. + * The PCMCIA code now just sets up the card so it can be recognized + * by ibmtr_probe. Also checks allocated memory vs. on-board memory + * for correct figure to use. + * + * Changes by Tim Hockin (thockin@isunix.it.ilstu.edu) : + * + added spinlocks for SMP sanity (10 March 1999) + * + * Changes by Jochen Friedrich to enable RFC1469 Option 2 multicasting + * i.e. using functional address C0 00 00 04 00 00 to transmit and + * receive multicast packets. + * + * Changes by Mike Sullivan (based on original sram patch by Dave Grothe + * to support windowing into on adapter shared ram. + * i.e. Use LANAID to setup a PnP configuration with 16K RAM. Paging + * will shift this 16K window over the entire available shared RAM. + * + * Changes by Peter De Schrijver (p2@mind.be) : + * + fixed a problem with PCMCIA card removal + * + * Change by Mike Sullivan et al.: + * + added turbo card support. No need to use lanaid to configure + * the adapter into isa compatibility mode. + * + * Changes by Burt Silverman to allow the computer to behave nicely when + * a cable is pulled or not in place, or a PCMCIA card is removed hot. + */ + +/* change the define of IBMTR_DEBUG_MESSAGES to a nonzero value +in the event that chatty debug messages are desired - jjs 12/30/98 */ + +#define IBMTR_DEBUG_MESSAGES 0 + +#include +#include + +#ifdef PCMCIA /* required for ibmtr_cs.c to build */ +#undef MODULE /* yes, really */ +#undef ENABLE_PAGING +#else +#define ENABLE_PAGING 1 +#endif + +/* changes the output format of driver initialization */ +#define TR_VERBOSE 0 + +/* some 95 OS send many non UI frame; this allow removing the warning */ +#define TR_FILTERNONUI 1 + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define DPRINTK(format, args...) printk("%s: " format, dev->name , ## args) +#define DPRINTD(format, args...) DummyCall("%s: " format, dev->name , ## args) + +/* version and credits */ +#ifndef PCMCIA +static char version[] __devinitdata = + "\nibmtr.c: v1.3.57 8/ 7/94 Peter De Schrijver and Mark Swanson\n" + " v2.1.125 10/20/98 Paul Norton \n" + " v2.2.0 12/30/98 Joel Sloan \n" + " v2.2.1 02/08/00 Mike Sullivan \n" + " v2.2.2 07/27/00 Burt Silverman \n" + " v2.4.0 03/01/01 Mike Sullivan \n"; +#endif + +/* this allows displaying full adapter information */ + +static char *channel_def[] __devinitdata = { "ISA", "MCA", "ISA P&P" }; + +static char pcchannelid[] __devinitdata = { + 0x05, 0x00, 0x04, 0x09, + 0x04, 0x03, 0x04, 0x0f, + 0x03, 0x06, 0x03, 0x01, + 0x03, 0x01, 0x03, 0x00, + 0x03, 0x09, 0x03, 0x09, + 0x03, 0x00, 0x02, 0x00 +}; + +static char mcchannelid[] __devinitdata = { + 0x04, 0x0d, 0x04, 0x01, + 0x05, 0x02, 0x05, 0x03, + 0x03, 0x06, 0x03, 0x03, + 0x05, 0x08, 0x03, 0x04, + 0x03, 0x05, 0x03, 0x01, + 0x03, 0x08, 0x02, 0x00 +}; + +static char __devinit *adapter_def(char type) +{ + switch (type) { + case 0xF: return "PC Adapter | PC Adapter II | Adapter/A"; + case 0xE: return "16/4 Adapter | 16/4 Adapter/A (long)"; + case 0xD: return "16/4 Adapter/A (short) | 16/4 ISA-16 Adapter"; + case 0xC: return "Auto 16/4 Adapter"; + default: return "adapter (unknown type)"; + } +}; + +#define TRC_INIT 0x01 /* Trace initialization & PROBEs */ +#define TRC_INITV 0x02 /* verbose init trace points */ +static unsigned char ibmtr_debug_trace = 0; + +static int ibmtr_probe1(struct net_device *dev, int ioaddr); +static unsigned char get_sram_size(struct tok_info *adapt_info); +static int trdev_init(struct net_device *dev); +static int tok_open(struct net_device *dev); +static int tok_init_card(struct net_device *dev); +static void tok_open_adapter(unsigned long dev_addr); +static void open_sap(unsigned char type, struct net_device *dev); +static void tok_set_multicast_list(struct net_device *dev); +static netdev_tx_t tok_send_packet(struct sk_buff *skb, + struct net_device *dev); +static int tok_close(struct net_device *dev); +static irqreturn_t tok_interrupt(int irq, void *dev_id); +static void initial_tok_int(struct net_device *dev); +static void tr_tx(struct net_device *dev); +static void tr_rx(struct net_device *dev); +static void ibmtr_reset_timer(struct timer_list*tmr,struct net_device *dev); +static void tok_rerun(unsigned long dev_addr); +static void ibmtr_readlog(struct net_device *dev); +static int ibmtr_change_mtu(struct net_device *dev, int mtu); +static void find_turbo_adapters(int *iolist); + +static int ibmtr_portlist[IBMTR_MAX_ADAPTERS+1] __devinitdata = { + 0xa20, 0xa24, 0, 0, 0 +}; +static int __devinitdata turbo_io[IBMTR_MAX_ADAPTERS] = {0}; +static int __devinitdata turbo_irq[IBMTR_MAX_ADAPTERS] = {0}; +static int __devinitdata turbo_searched = 0; + +#ifndef PCMCIA +static __u32 ibmtr_mem_base __devinitdata = 0xd0000; +#endif + +static void __devinit PrtChanID(char *pcid, short stride) +{ + short i, j; + for (i = 0, j = 0; i < 24; i++, j += stride) + printk("%1x", ((int) pcid[j]) & 0x0f); + printk("\n"); +} + +static void __devinit HWPrtChanID(void __iomem *pcid, short stride) +{ + short i, j; + for (i = 0, j = 0; i < 24; i++, j += stride) + printk("%1x", ((int) readb(pcid + j)) & 0x0f); + printk("\n"); +} + +/* We have to ioremap every checked address, because isa_readb is + * going away. + */ + +static void __devinit find_turbo_adapters(int *iolist) +{ + int ram_addr; + int index=0; + void __iomem *chanid; + int found_turbo=0; + unsigned char *tchanid, ctemp; + int i, j; + unsigned long jif; + void __iomem *ram_mapped ; + + if (turbo_searched == 1) return; + turbo_searched=1; + for (ram_addr=0xC0000; ram_addr < 0xE0000; ram_addr+=0x2000) { + + __u32 intf_tbl=0; + + found_turbo=1; + ram_mapped = ioremap((u32)ram_addr,0x1fff) ; + if (ram_mapped==NULL) + continue ; + chanid=(CHANNEL_ID + ram_mapped); + tchanid=pcchannelid; + ctemp=readb(chanid) & 0x0f; + if (ctemp != *tchanid) continue; + for (i=2,j=1; i<=46; i=i+2,j++) { + if ((readb(chanid+i) & 0x0f) != tchanid[j]){ + found_turbo=0; + break; + } + } + if (!found_turbo) continue; + + writeb(0x90, ram_mapped+0x1E01); + for(i=2; i<0x0f; i++) { + writeb(0x00, ram_mapped+0x1E01+i); + } + writeb(0x00, ram_mapped+0x1E01); + for(jif=jiffies+TR_BUSY_INTERVAL; time_before_eq(jiffies,jif);); + intf_tbl=ntohs(readw(ram_mapped+ACA_OFFSET+ACA_RW+WRBR_EVEN)); + if (intf_tbl) { +#if IBMTR_DEBUG_MESSAGES + printk("ibmtr::find_turbo_adapters, Turbo found at " + "ram_addr %x\n",ram_addr); + printk("ibmtr::find_turbo_adapters, interface_table "); + for(i=0; i<6; i++) { + printk("%x:",readb(ram_addr+intf_tbl+i)); + } + printk("\n"); +#endif + turbo_io[index]=ntohs(readw(ram_mapped+intf_tbl+4)); + turbo_irq[index]=readb(ram_mapped+intf_tbl+3); + outb(0, turbo_io[index] + ADAPTRESET); + for(jif=jiffies+TR_RST_TIME;time_before_eq(jiffies,jif);); + outb(0, turbo_io[index] + ADAPTRESETREL); + index++; + continue; + } +#if IBMTR_DEBUG_MESSAGES + printk("ibmtr::find_turbo_adapters, ibmtr card found at" + " %x but not a Turbo model\n",ram_addr); +#endif + iounmap(ram_mapped) ; + } /* for */ + for(i=0; ibase_addr) { + outb(0,dev->base_addr+ADAPTRESET); + + schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */ + + outb(0,dev->base_addr+ADAPTRESETREL); + } + +#ifndef PCMCIA + free_irq(dev->irq, dev); + release_region(dev->base_addr, IBMTR_IO_EXTENT); + + { + struct tok_info *ti = netdev_priv(dev); + iounmap(ti->mmio); + iounmap(ti->sram_virt); + } +#endif +} + +/**************************************************************************** + * ibmtr_probe(): Routine specified in the network device structure + * to probe for an IBM Token Ring Adapter. Routine outline: + * I. Interrogate hardware to determine if an adapter exists + * and what the speeds and feeds are + * II. Setup data structures to control execution based upon + * adapter characteristics. + * + * We expect ibmtr_probe to be called once for each device entry + * which references it. + ****************************************************************************/ + +static int __devinit ibmtr_probe(struct net_device *dev) +{ + int i; + int base_addr = dev->base_addr; + + if (base_addr && base_addr <= 0x1ff) /* Don't probe at all. */ + return -ENXIO; + if (base_addr > 0x1ff) { /* Check a single specified location. */ + if (!ibmtr_probe1(dev, base_addr)) return 0; + return -ENODEV; + } + find_turbo_adapters(ibmtr_portlist); + for (i = 0; ibmtr_portlist[i]; i++) { + int ioaddr = ibmtr_portlist[i]; + + if (!ibmtr_probe1(dev, ioaddr)) return 0; + } + return -ENODEV; +} + +int __devinit ibmtr_probe_card(struct net_device *dev) +{ + int err = ibmtr_probe(dev); + if (!err) { + err = register_netdev(dev); + if (err) + ibmtr_cleanup_card(dev); + } + return err; +} + +/*****************************************************************************/ + +static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr) +{ + + unsigned char segment, intr=0, irq=0, i, j, cardpresent=NOTOK, temp=0; + void __iomem * t_mmio = NULL; + struct tok_info *ti = netdev_priv(dev); + void __iomem *cd_chanid; + unsigned char *tchanid, ctemp; +#ifndef PCMCIA + unsigned char t_irq=0; + unsigned long timeout; + static int version_printed; +#endif + + /* Query the adapter PIO base port which will return + * indication of where MMIO was placed. We also have a + * coded interrupt number. + */ + segment = inb(PIOaddr); + if (segment < 0x40 || segment > 0xe0) { + /* Out of range values so we'll assume non-existent IO device + * but this is not necessarily a problem, esp if a turbo + * adapter is being used. */ +#if IBMTR_DEBUG_MESSAGES + DPRINTK("ibmtr_probe1(): unhappy that inb(0x%X) == 0x%X, " + "Hardware Problem?\n",PIOaddr,segment); +#endif + return -ENODEV; + } + /* + * Compute the linear base address of the MMIO area + * as LINUX doesn't care about segments + */ + t_mmio = ioremap(((__u32) (segment & 0xfc) << 11) + 0x80000,2048); + if (!t_mmio) { + DPRINTK("Cannot remap mmiobase memory area") ; + return -ENODEV ; + } + intr = segment & 0x03; /* low bits is coded interrupt # */ + if (ibmtr_debug_trace & TRC_INIT) + DPRINTK("PIOaddr: %4hx seg/intr: %2x mmio base: %p intr: %d\n" + , PIOaddr, (int) segment, t_mmio, (int) intr); + + /* + * Now we will compare expected 'channelid' strings with + * what we is there to learn of ISA/MCA or not TR card + */ +#ifdef PCMCIA + iounmap(t_mmio); + t_mmio = ti->mmio; /*BMS to get virtual address */ + irq = ti->irq; /*BMS to display the irq! */ +#endif + cd_chanid = (CHANNEL_ID + t_mmio); /* for efficiency */ + tchanid = pcchannelid; + cardpresent = TR_ISA; /* try ISA */ + + /* Suboptimize knowing first byte different */ + ctemp = readb(cd_chanid) & 0x0f; + if (ctemp != *tchanid) { /* NOT ISA card, try MCA */ + tchanid = mcchannelid; + cardpresent = TR_MCA; + if (ctemp != *tchanid) /* Neither ISA nor MCA */ + cardpresent = NOTOK; + } + if (cardpresent != NOTOK) { + /* Know presumed type, try rest of ID */ + for (i = 2, j = 1; i <= 46; i = i + 2, j++) { + if( (readb(cd_chanid+i)&0x0f) == tchanid[j]) continue; + /* match failed, not TR card */ + cardpresent = NOTOK; + break; + } + } + /* + * If we have an ISA board check for the ISA P&P version, + * as it has different IRQ settings + */ + if (cardpresent == TR_ISA && (readb(AIPFID + t_mmio) == 0x0e)) + cardpresent = TR_ISAPNP; + if (cardpresent == NOTOK) { /* "channel_id" did not match, report */ + if (!(ibmtr_debug_trace & TRC_INIT)) { +#ifndef PCMCIA + iounmap(t_mmio); +#endif + return -ENODEV; + } + DPRINTK( "Channel ID string not found for PIOaddr: %4hx\n", + PIOaddr); + DPRINTK("Expected for ISA: "); + PrtChanID(pcchannelid, 1); + DPRINTK(" found: "); +/* BMS Note that this can be misleading, when hardware is flaky, because you + are reading it a second time here. So with my flaky hardware, I'll see my- + self in this block, with the HW ID matching the ISA ID exactly! */ + HWPrtChanID(cd_chanid, 2); + DPRINTK("Expected for MCA: "); + PrtChanID(mcchannelid, 1); + } + /* Now, setup some of the pl0 buffers for this driver.. */ + /* If called from PCMCIA, it is already set up, so no need to + waste the memory, just use the existing structure */ +#ifndef PCMCIA + ti->mmio = t_mmio; + for (i = 0; i < IBMTR_MAX_ADAPTERS; i++) { + if (turbo_io[i] != PIOaddr) + continue; +#if IBMTR_DEBUG_MESSAGES + printk("ibmtr::tr_probe1, setting PIOaddr %x to Turbo\n", + PIOaddr); +#endif + ti->turbo = 1; + t_irq = turbo_irq[i]; + } +#endif /* !PCMCIA */ + ti->readlog_pending = 0; + init_waitqueue_head(&ti->wait_for_reset); + + /* if PCMCIA, the card can be recognized as either TR_ISA or TR_ISAPNP + * depending which card is inserted. */ + +#ifndef PCMCIA + switch (cardpresent) { + case TR_ISA: + if (intr == 0) irq = 9; /* irq2 really is irq9 */ + if (intr == 1) irq = 3; + if (intr == 2) irq = 6; + if (intr == 3) irq = 7; + ti->adapter_int_enable = PIOaddr + ADAPTINTREL; + break; + case TR_MCA: + if (intr == 0) irq = 9; + if (intr == 1) irq = 3; + if (intr == 2) irq = 10; + if (intr == 3) irq = 11; + ti->global_int_enable = 0; + ti->adapter_int_enable = 0; + ti->sram_phys=(__u32)(inb(PIOaddr+ADAPTRESETREL) & 0xfe) << 12; + break; + case TR_ISAPNP: + if (!t_irq) { + if (intr == 0) irq = 9; + if (intr == 1) irq = 3; + if (intr == 2) irq = 10; + if (intr == 3) irq = 11; + } else + irq=t_irq; + timeout = jiffies + TR_SPIN_INTERVAL; + while (!readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)){ + if (!time_after(jiffies, timeout)) continue; + DPRINTK( "Hardware timeout during initialization.\n"); + iounmap(t_mmio); + return -ENODEV; + } + ti->sram_phys = + ((__u32)readb(ti->mmio+ACA_OFFSET+ACA_RW+RRR_EVEN)<<12); + ti->adapter_int_enable = PIOaddr + ADAPTINTREL; + break; + } /*end switch (cardpresent) */ +#endif /*not PCMCIA */ + + if (ibmtr_debug_trace & TRC_INIT) { /* just report int */ + DPRINTK("irq=%d", irq); + printk(", sram_phys=0x%x", ti->sram_phys); + if(ibmtr_debug_trace&TRC_INITV){ /* full chat in verbose only */ + DPRINTK(", ti->mmio=%p", ti->mmio); + printk(", segment=%02X", segment); + } + printk(".\n"); + } + + /* Get hw address of token ring card */ + j = 0; + for (i = 0; i < 0x18; i = i + 2) { + /* technical reference states to do this */ + temp = readb(ti->mmio + AIP + i) & 0x0f; + ti->hw_address[j] = temp; + if (j & 1) + dev->dev_addr[(j / 2)] = + ti->hw_address[j]+ (ti->hw_address[j - 1] << 4); + ++j; + } + /* get Adapter type: 'F' = Adapter/A, 'E' = 16/4 Adapter II,... */ + ti->adapter_type = readb(ti->mmio + AIPADAPTYPE); + + /* get Data Rate: F=4Mb, E=16Mb, D=4Mb & 16Mb ?? */ + ti->data_rate = readb(ti->mmio + AIPDATARATE); + + /* Get Early Token Release support?: F=no, E=4Mb, D=16Mb, C=4&16Mb */ + ti->token_release = readb(ti->mmio + AIPEARLYTOKEN); + + /* How much shared RAM is on adapter ? */ + if (ti->turbo) { + ti->avail_shared_ram=127; + } else { + ti->avail_shared_ram = get_sram_size(ti);/*in 512 byte units */ + } + /* We need to set or do a bunch of work here based on previous results*/ + /* Support paging? What sizes?: F=no, E=16k, D=32k, C=16 & 32k */ + ti->shared_ram_paging = readb(ti->mmio + AIPSHRAMPAGE); + + /* Available DHB 4Mb size: F=2048, E=4096, D=4464 */ + switch (readb(ti->mmio + AIP4MBDHB)) { + case 0xe: ti->dhb_size4mb = 4096; break; + case 0xd: ti->dhb_size4mb = 4464; break; + default: ti->dhb_size4mb = 2048; break; + } + + /* Available DHB 16Mb size: F=2048, E=4096, D=8192, C=16384, B=17960 */ + switch (readb(ti->mmio + AIP16MBDHB)) { + case 0xe: ti->dhb_size16mb = 4096; break; + case 0xd: ti->dhb_size16mb = 8192; break; + case 0xc: ti->dhb_size16mb = 16384; break; + case 0xb: ti->dhb_size16mb = 17960; break; + default: ti->dhb_size16mb = 2048; break; + } + + /* We must figure out how much shared memory space this adapter + * will occupy so that if there are two adapters we can fit both + * in. Given a choice, we will limit this adapter to 32K. The + * maximum space will will use for two adapters is 64K so if the + * adapter we are working on demands 64K (it also doesn't support + * paging), then only one adapter can be supported. + */ + + /* + * determine how much of total RAM is mapped into PC space + */ + ti->mapped_ram_size= /*sixteen to onehundredtwentyeight 512byte blocks*/ + 1<< ((readb(ti->mmio+ACA_OFFSET+ACA_RW+RRR_ODD) >> 2 & 0x03) + 4); + ti->page_mask = 0; + if (ti->turbo) ti->page_mask=0xf0; + else if (ti->shared_ram_paging == 0xf); /* No paging in adapter */ + else { +#ifdef ENABLE_PAGING + unsigned char pg_size = 0; + /* BMS: page size: PCMCIA, use configuration register; + ISAPNP, use LANAIDC config tool from www.ibm.com */ + switch (ti->shared_ram_paging) { + case 0xf: + break; + case 0xe: + ti->page_mask = (ti->mapped_ram_size == 32) ? 0xc0 : 0; + pg_size = 32; /* 16KB page size */ + break; + case 0xd: + ti->page_mask = (ti->mapped_ram_size == 64) ? 0x80 : 0; + pg_size = 64; /* 32KB page size */ + break; + case 0xc: + switch (ti->mapped_ram_size) { + case 32: + ti->page_mask = 0xc0; + pg_size = 32; + break; + case 64: + ti->page_mask = 0x80; + pg_size = 64; + break; + } + break; + default: + DPRINTK("Unknown shared ram paging info %01X\n", + ti->shared_ram_paging); + iounmap(t_mmio); + return -ENODEV; + break; + } /*end switch shared_ram_paging */ + + if (ibmtr_debug_trace & TRC_INIT) + DPRINTK("Shared RAM paging code: %02X, " + "mapped RAM size: %dK, shared RAM size: %dK, " + "page mask: %02X\n:", + ti->shared_ram_paging, ti->mapped_ram_size / 2, + ti->avail_shared_ram / 2, ti->page_mask); +#endif /*ENABLE_PAGING */ + } + +#ifndef PCMCIA + /* finish figuring the shared RAM address */ + if (cardpresent == TR_ISA) { + static const __u32 ram_bndry_mask[] = { + 0xffffe000, 0xffffc000, 0xffff8000, 0xffff0000 + }; + __u32 new_base, rrr_32, chk_base, rbm; + + rrr_32=readb(ti->mmio+ACA_OFFSET+ACA_RW+RRR_ODD) >> 2 & 0x03; + rbm = ram_bndry_mask[rrr_32]; + new_base = (ibmtr_mem_base + (~rbm)) & rbm;/* up to boundary */ + chk_base = new_base + (ti->mapped_ram_size << 9); + if (chk_base > (ibmtr_mem_base + IBMTR_SHARED_RAM_SIZE)) { + DPRINTK("Shared RAM for this adapter (%05x) exceeds " + "driver limit (%05x), adapter not started.\n", + chk_base, ibmtr_mem_base + IBMTR_SHARED_RAM_SIZE); + iounmap(t_mmio); + return -ENODEV; + } else { /* seems cool, record what we have figured out */ + ti->sram_base = new_base >> 12; + ibmtr_mem_base = chk_base; + } + } + else ti->sram_base = ti->sram_phys >> 12; + + /* The PCMCIA has already got the interrupt line and the io port, + so no chance of anybody else getting it - MLP */ + if (request_irq(dev->irq = irq, tok_interrupt, 0, "ibmtr", dev) != 0) { + DPRINTK("Could not grab irq %d. Halting Token Ring driver.\n", + irq); + iounmap(t_mmio); + return -ENODEV; + } + /*?? Now, allocate some of the PIO PORTs for this driver.. */ + /* record PIOaddr range as busy */ + if (!request_region(PIOaddr, IBMTR_IO_EXTENT, "ibmtr")) { + DPRINTK("Could not grab PIO range. Halting driver.\n"); + free_irq(dev->irq, dev); + iounmap(t_mmio); + return -EBUSY; + } + + if (!version_printed++) { + printk(version); + } +#endif /* !PCMCIA */ + DPRINTK("%s %s found\n", + channel_def[cardpresent - 1], adapter_def(ti->adapter_type)); + DPRINTK("using irq %d, PIOaddr %hx, %dK shared RAM.\n", + irq, PIOaddr, ti->mapped_ram_size / 2); + DPRINTK("Hardware address : %pM\n", dev->dev_addr); + if (ti->page_mask) + DPRINTK("Shared RAM paging enabled. " + "Page size: %uK Shared Ram size %dK\n", + ((ti->page_mask^0xff)+1) >>2, ti->avail_shared_ram / 2); + else + DPRINTK("Shared RAM paging disabled. ti->page_mask %x\n", + ti->page_mask); + + /* Calculate the maximum DHB we can use */ + /* two cases where avail_shared_ram doesn't equal mapped_ram_size: + 1. avail_shared_ram is 127 but mapped_ram_size is 128 (typical) + 2. user has configured adapter for less than avail_shared_ram + but is not using paging (she should use paging, I believe) + */ + if (!ti->page_mask) { + ti->avail_shared_ram= + min(ti->mapped_ram_size,ti->avail_shared_ram); + } + + switch (ti->avail_shared_ram) { + case 16: /* 8KB shared RAM */ + ti->dhb_size4mb = min(ti->dhb_size4mb, (unsigned short)2048); + ti->rbuf_len4 = 1032; + ti->rbuf_cnt4=2; + ti->dhb_size16mb = min(ti->dhb_size16mb, (unsigned short)2048); + ti->rbuf_len16 = 1032; + ti->rbuf_cnt16=2; + break; + case 32: /* 16KB shared RAM */ + ti->dhb_size4mb = min(ti->dhb_size4mb, (unsigned short)4464); + ti->rbuf_len4 = 1032; + ti->rbuf_cnt4=4; + ti->dhb_size16mb = min(ti->dhb_size16mb, (unsigned short)4096); + ti->rbuf_len16 = 1032; /*1024 usable */ + ti->rbuf_cnt16=4; + break; + case 64: /* 32KB shared RAM */ + ti->dhb_size4mb = min(ti->dhb_size4mb, (unsigned short)4464); + ti->rbuf_len4 = 1032; + ti->rbuf_cnt4=6; + ti->dhb_size16mb = min(ti->dhb_size16mb, (unsigned short)10240); + ti->rbuf_len16 = 1032; + ti->rbuf_cnt16=6; + break; + case 127: /* 63.5KB shared RAM */ + ti->dhb_size4mb = min(ti->dhb_size4mb, (unsigned short)4464); + ti->rbuf_len4 = 1032; + ti->rbuf_cnt4=6; + ti->dhb_size16mb = min(ti->dhb_size16mb, (unsigned short)16384); + ti->rbuf_len16 = 1032; + ti->rbuf_cnt16=16; + break; + case 128: /* 64KB shared RAM */ + ti->dhb_size4mb = min(ti->dhb_size4mb, (unsigned short)4464); + ti->rbuf_len4 = 1032; + ti->rbuf_cnt4=6; + ti->dhb_size16mb = min(ti->dhb_size16mb, (unsigned short)17960); + ti->rbuf_len16 = 1032; + ti->rbuf_cnt16=16; + break; + default: + ti->dhb_size4mb = 2048; + ti->rbuf_len4 = 1032; + ti->rbuf_cnt4=2; + ti->dhb_size16mb = 2048; + ti->rbuf_len16 = 1032; + ti->rbuf_cnt16=2; + break; + } + /* this formula is not smart enough for the paging case + ti->rbuf_cnt = (ti->avail_shared_ram * BLOCKSZ - ADAPT_PRIVATE - + ARBLENGTH - SSBLENGTH - DLC_MAX_SAP * SAPLENGTH - + DLC_MAX_STA * STALENGTH - ti->dhb_sizemb * NUM_DHB - + SRBLENGTH - ASBLENGTH) / ti->rbuf_len; + */ + ti->maxmtu16 = (ti->rbuf_len16 - 8) * ti->rbuf_cnt16 - TR_HLEN; + ti->maxmtu4 = (ti->rbuf_len4 - 8) * ti->rbuf_cnt4 - TR_HLEN; + /*BMS assuming 18 bytes of Routing Information (usually works) */ + DPRINTK("Maximum Receive Internet Protocol MTU 16Mbps: %d, 4Mbps: %d\n", + ti->maxmtu16, ti->maxmtu4); + + dev->base_addr = PIOaddr; /* set the value for device */ + dev->mem_start = ti->sram_base << 12; + dev->mem_end = dev->mem_start + (ti->mapped_ram_size << 9) - 1; + trdev_init(dev); + return 0; /* Return 0 to indicate we have found a Token Ring card. */ +} /*ibmtr_probe1() */ + +/*****************************************************************************/ + +/* query the adapter for the size of shared RAM */ +/* the function returns the RAM size in units of 512 bytes */ + +static unsigned char __devinit get_sram_size(struct tok_info *adapt_info) +{ + unsigned char avail_sram_code; + static unsigned char size_code[] = { 0, 16, 32, 64, 127, 128 }; + /* Adapter gives + 'F' -- use RRR bits 3,2 + 'E' -- 8kb 'D' -- 16kb + 'C' -- 32kb 'A' -- 64KB + 'B' - 64KB less 512 bytes at top + (WARNING ... must zero top bytes in INIT */ + + avail_sram_code = 0xf - readb(adapt_info->mmio + AIPAVAILSHRAM); + if (avail_sram_code) return size_code[avail_sram_code]; + else /* for code 'F', must compute size from RRR(3,2) bits */ + return 1 << + ((readb(adapt_info->mmio+ACA_OFFSET+ACA_RW+RRR_ODD)>>2&3)+4); +} + +/*****************************************************************************/ + +static const struct net_device_ops trdev_netdev_ops = { + .ndo_open = tok_open, + .ndo_stop = tok_close, + .ndo_start_xmit = tok_send_packet, + .ndo_set_rx_mode = tok_set_multicast_list, + .ndo_change_mtu = ibmtr_change_mtu, +}; + +static int __devinit trdev_init(struct net_device *dev) +{ + struct tok_info *ti = netdev_priv(dev); + + SET_PAGE(ti->srb_page); + ti->open_failure = NO ; + dev->netdev_ops = &trdev_netdev_ops; + + return 0; +} + +/*****************************************************************************/ + +static int tok_init_card(struct net_device *dev) +{ + struct tok_info *ti; + short PIOaddr; + unsigned long i; + + PIOaddr = dev->base_addr; + ti = netdev_priv(dev); + /* Special processing for first interrupt after reset */ + ti->do_tok_int = FIRST_INT; + /* Reset adapter */ + writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN); + outb(0, PIOaddr + ADAPTRESET); + + schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */ + + outb(0, PIOaddr + ADAPTRESETREL); +#ifdef ENABLE_PAGING + if (ti->page_mask) + writeb(SRPR_ENABLE_PAGING,ti->mmio+ACA_OFFSET+ACA_RW+SRPR_EVEN); +#endif + writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); + i = sleep_on_timeout(&ti->wait_for_reset, 4 * HZ); + return i? 0 : -EAGAIN; +} + +/*****************************************************************************/ +static int tok_open(struct net_device *dev) +{ + struct tok_info *ti = netdev_priv(dev); + int i; + + /*the case we were left in a failure state during a previous open */ + if (ti->open_failure == YES) { + DPRINTK("Last time you were disconnected, how about now?\n"); + printk("You can't insert with an ICS connector half-cocked.\n"); + } + + ti->open_status = CLOSED; /* CLOSED or OPEN */ + ti->sap_status = CLOSED; /* CLOSED or OPEN */ + ti->open_failure = NO; /* NO or YES */ + ti->open_mode = MANUAL; /* MANUAL or AUTOMATIC */ + + ti->sram_phys &= ~1; /* to reverse what we do in tok_close */ + /* init the spinlock */ + spin_lock_init(&ti->lock); + init_timer(&ti->tr_timer); + + i = tok_init_card(dev); + if (i) return i; + + while (1){ + tok_open_adapter((unsigned long) dev); + i= interruptible_sleep_on_timeout(&ti->wait_for_reset, 25 * HZ); + /* sig catch: estimate opening adapter takes more than .5 sec*/ + if (i>(245*HZ)/10) break; /* fancier than if (i==25*HZ) */ + if (i==0) break; + if (ti->open_status == OPEN && ti->sap_status==OPEN) { + netif_start_queue(dev); + DPRINTK("Adapter is up and running\n"); + return 0; + } + i=schedule_timeout_interruptible(TR_RETRY_INTERVAL); + /* wait 30 seconds */ + if(i!=0) break; /*prob. a signal, like the i>24*HZ case above */ + } + outb(0, dev->base_addr + ADAPTRESET);/* kill pending interrupts*/ + DPRINTK("TERMINATED via signal\n"); /*BMS useful */ + return -EAGAIN; +} + +/*****************************************************************************/ + +#define COMMAND_OFST 0 +#define OPEN_OPTIONS_OFST 8 +#define NUM_RCV_BUF_OFST 24 +#define RCV_BUF_LEN_OFST 26 +#define DHB_LENGTH_OFST 28 +#define NUM_DHB_OFST 30 +#define DLC_MAX_SAP_OFST 32 +#define DLC_MAX_STA_OFST 33 + +static void tok_open_adapter(unsigned long dev_addr) +{ + struct net_device *dev = (struct net_device *) dev_addr; + struct tok_info *ti; + int i; + + ti = netdev_priv(dev); + SET_PAGE(ti->init_srb_page); + writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD); + for (i = 0; i < sizeof(struct dir_open_adapter); i++) + writeb(0, ti->init_srb + i); + writeb(DIR_OPEN_ADAPTER, ti->init_srb + COMMAND_OFST); + writew(htons(OPEN_PASS_BCON_MAC), ti->init_srb + OPEN_OPTIONS_OFST); + if (ti->ring_speed == 16) { + writew(htons(ti->dhb_size16mb), ti->init_srb + DHB_LENGTH_OFST); + writew(htons(ti->rbuf_cnt16), ti->init_srb + NUM_RCV_BUF_OFST); + writew(htons(ti->rbuf_len16), ti->init_srb + RCV_BUF_LEN_OFST); + } else { + writew(htons(ti->dhb_size4mb), ti->init_srb + DHB_LENGTH_OFST); + writew(htons(ti->rbuf_cnt4), ti->init_srb + NUM_RCV_BUF_OFST); + writew(htons(ti->rbuf_len4), ti->init_srb + RCV_BUF_LEN_OFST); + } + writeb(NUM_DHB, /* always 2 */ ti->init_srb + NUM_DHB_OFST); + writeb(DLC_MAX_SAP, ti->init_srb + DLC_MAX_SAP_OFST); + writeb(DLC_MAX_STA, ti->init_srb + DLC_MAX_STA_OFST); + ti->srb = ti->init_srb; /* We use this one in the interrupt handler */ + ti->srb_page = ti->init_srb_page; + DPRINTK("Opening adapter: Xmit bfrs: %d X %d, Rcv bfrs: %d X %d\n", + readb(ti->init_srb + NUM_DHB_OFST), + ntohs(readw(ti->init_srb + DHB_LENGTH_OFST)), + ntohs(readw(ti->init_srb + NUM_RCV_BUF_OFST)), + ntohs(readw(ti->init_srb + RCV_BUF_LEN_OFST))); + writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); + writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); +} + +/*****************************************************************************/ + +static void open_sap(unsigned char type, struct net_device *dev) +{ + int i; + struct tok_info *ti = netdev_priv(dev); + + SET_PAGE(ti->srb_page); + for (i = 0; i < sizeof(struct dlc_open_sap); i++) + writeb(0, ti->srb + i); + +#define MAX_I_FIELD_OFST 14 +#define SAP_VALUE_OFST 16 +#define SAP_OPTIONS_OFST 17 +#define STATION_COUNT_OFST 18 + + writeb(DLC_OPEN_SAP, ti->srb + COMMAND_OFST); + writew(htons(MAX_I_FIELD), ti->srb + MAX_I_FIELD_OFST); + writeb(SAP_OPEN_IND_SAP | SAP_OPEN_PRIORITY, ti->srb+ SAP_OPTIONS_OFST); + writeb(SAP_OPEN_STATION_CNT, ti->srb + STATION_COUNT_OFST); + writeb(type, ti->srb + SAP_VALUE_OFST); + writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); +} + + +/*****************************************************************************/ + +static void tok_set_multicast_list(struct net_device *dev) +{ + struct tok_info *ti = netdev_priv(dev); + struct netdev_hw_addr *ha; + unsigned char address[4]; + + int i; + + /*BMS the next line is CRUCIAL or you may be sad when you */ + /*BMS ifconfig tr down or hot unplug a PCMCIA card ??hownowbrowncow*/ + if (/*BMSHELPdev->start == 0 ||*/ ti->open_status != OPEN) return; + address[0] = address[1] = address[2] = address[3] = 0; + netdev_for_each_mc_addr(ha, dev) { + address[0] |= ha->addr[2]; + address[1] |= ha->addr[3]; + address[2] |= ha->addr[4]; + address[3] |= ha->addr[5]; + } + SET_PAGE(ti->srb_page); + for (i = 0; i < sizeof(struct srb_set_funct_addr); i++) + writeb(0, ti->srb + i); + +#define FUNCT_ADDRESS_OFST 6 + + writeb(DIR_SET_FUNC_ADDR, ti->srb + COMMAND_OFST); + for (i = 0; i < 4; i++) + writeb(address[i], ti->srb + FUNCT_ADDRESS_OFST + i); + writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); +#if TR_VERBOSE + DPRINTK("Setting functional address: "); + for (i=0;i<4;i++) printk("%02X ", address[i]); + printk("\n"); +#endif +} + +/*****************************************************************************/ + +#define STATION_ID_OFST 4 + +static netdev_tx_t tok_send_packet(struct sk_buff *skb, + struct net_device *dev) +{ + struct tok_info *ti; + unsigned long flags; + ti = netdev_priv(dev); + + netif_stop_queue(dev); + + /* lock against other CPUs */ + spin_lock_irqsave(&(ti->lock), flags); + + /* Save skb; we'll need it when the adapter asks for the data */ + ti->current_skb = skb; + SET_PAGE(ti->srb_page); + writeb(XMIT_UI_FRAME, ti->srb + COMMAND_OFST); + writew(ti->exsap_station_id, ti->srb + STATION_ID_OFST); + writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + spin_unlock_irqrestore(&(ti->lock), flags); + return NETDEV_TX_OK; +} + +/*****************************************************************************/ + +static int tok_close(struct net_device *dev) +{ + struct tok_info *ti = netdev_priv(dev); + + /* Important for PCMCIA hot unplug, otherwise, we'll pull the card, */ + /* unloading the module from memory, and then if a timer pops, ouch */ + del_timer_sync(&ti->tr_timer); + outb(0, dev->base_addr + ADAPTRESET); + ti->sram_phys |= 1; + ti->open_status = CLOSED; + + netif_stop_queue(dev); + DPRINTK("Adapter is closed.\n"); + return 0; +} + +/*****************************************************************************/ + +#define RETCODE_OFST 2 +#define OPEN_ERROR_CODE_OFST 6 +#define ASB_ADDRESS_OFST 8 +#define SRB_ADDRESS_OFST 10 +#define ARB_ADDRESS_OFST 12 +#define SSB_ADDRESS_OFST 14 + +static char *printphase[]= {"Lobe media test","Physical insertion", + "Address verification","Roll call poll","Request Parameters"}; +static char *printerror[]={"Function failure","Signal loss","Reserved", + "Frequency error","Timeout","Ring failure","Ring beaconing", + "Duplicate node address", + "Parameter request-retry count exceeded","Remove received", + "IMPL force received","Duplicate modifier", + "No monitor detected","Monitor contention failed for RPL"}; + +static void __iomem *map_address(struct tok_info *ti, unsigned index, __u8 *page) +{ + if (ti->page_mask) { + *page = (index >> 8) & ti->page_mask; + index &= ~(ti->page_mask << 8); + } + return ti->sram_virt + index; +} + +static void dir_open_adapter (struct net_device *dev) +{ + struct tok_info *ti = netdev_priv(dev); + unsigned char ret_code; + __u16 err; + + ti->srb = map_address(ti, + ntohs(readw(ti->init_srb + SRB_ADDRESS_OFST)), + &ti->srb_page); + ti->ssb = map_address(ti, + ntohs(readw(ti->init_srb + SSB_ADDRESS_OFST)), + &ti->ssb_page); + ti->arb = map_address(ti, + ntohs(readw(ti->init_srb + ARB_ADDRESS_OFST)), + &ti->arb_page); + ti->asb = map_address(ti, + ntohs(readw(ti->init_srb + ASB_ADDRESS_OFST)), + &ti->asb_page); + ti->current_skb = NULL; + ret_code = readb(ti->init_srb + RETCODE_OFST); + err = ntohs(readw(ti->init_srb + OPEN_ERROR_CODE_OFST)); + if (!ret_code) { + ti->open_status = OPEN; /* TR adapter is now available */ + if (ti->open_mode == AUTOMATIC) { + DPRINTK("Adapter reopened.\n"); + } + writeb(~SRB_RESP_INT, ti->mmio+ACA_OFFSET+ACA_RESET+ISRP_ODD); + open_sap(EXTENDED_SAP, dev); + return; + } + ti->open_failure = YES; + if (ret_code == 7){ + if (err == 0x24) { + if (!ti->auto_speedsave) { + DPRINTK("Open failed: Adapter speed must match " + "ring speed if Automatic Ring Speed Save is " + "disabled.\n"); + ti->open_action = FAIL; + }else + DPRINTK("Retrying open to adjust to " + "ring speed, "); + } else if (err == 0x2d) { + DPRINTK("Physical Insertion: No Monitor Detected, "); + printk("retrying after %ds delay...\n", + TR_RETRY_INTERVAL/HZ); + } else if (err == 0x11) { + DPRINTK("Lobe Media Function Failure (0x11), "); + printk(" retrying after %ds delay...\n", + TR_RETRY_INTERVAL/HZ); + } else { + char **prphase = printphase; + char **prerror = printerror; + int pnr = err / 16 - 1; + int enr = err % 16 - 1; + DPRINTK("TR Adapter misc open failure, error code = "); + if (pnr < 0 || pnr >= ARRAY_SIZE(printphase) || + enr < 0 || + enr >= ARRAY_SIZE(printerror)) + printk("0x%x, invalid Phase/Error.", err); + else + printk("0x%x, Phase: %s, Error: %s\n", err, + prphase[pnr], prerror[enr]); + printk(" retrying after %ds delay...\n", + TR_RETRY_INTERVAL/HZ); + } + } else DPRINTK("open failed: ret_code = %02X..., ", ret_code); + if (ti->open_action != FAIL) { + if (ti->open_mode==AUTOMATIC){ + ti->open_action = REOPEN; + ibmtr_reset_timer(&(ti->tr_timer), dev); + return; + } + wake_up(&ti->wait_for_reset); + return; + } + DPRINTK("FAILURE, CAPUT\n"); +} + +/******************************************************************************/ + +static irqreturn_t tok_interrupt(int irq, void *dev_id) +{ + unsigned char status; + /* unsigned char status_even ; */ + struct tok_info *ti; + struct net_device *dev; +#ifdef ENABLE_PAGING + unsigned char save_srpr; +#endif + + dev = dev_id; +#if TR_VERBOSE + DPRINTK("Int from tok_driver, dev : %p irq%d\n", dev,irq); +#endif + ti = netdev_priv(dev); + if (ti->sram_phys & 1) + return IRQ_NONE; /* PCMCIA card extraction flag */ + spin_lock(&(ti->lock)); +#ifdef ENABLE_PAGING + save_srpr = readb(ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN); +#endif + + /* Disable interrupts till processing is finished */ + writeb((~INT_ENABLE), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN); + + /* Reset interrupt for ISA boards */ + if (ti->adapter_int_enable) + outb(0, ti->adapter_int_enable); + else /* used for PCMCIA cards */ + outb(0, ti->global_int_enable); + if (ti->do_tok_int == FIRST_INT){ + initial_tok_int(dev); +#ifdef ENABLE_PAGING + writeb(save_srpr, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN); +#endif + spin_unlock(&(ti->lock)); + return IRQ_HANDLED; + } + /* Begin interrupt handler HERE inline to avoid the extra + levels of logic and call depth for the original solution. */ + status = readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_ODD); + /*BMSstatus_even = readb (ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN) */ + /*BMSdebugprintk("tok_interrupt: ISRP_ODD = 0x%x ISRP_EVEN = 0x%x\n", */ + /*BMS status,status_even); */ + + if (status & ADAP_CHK_INT) { + int i; + void __iomem *check_reason; + __u8 check_reason_page = 0; + check_reason = map_address(ti, + ntohs(readw(ti->mmio+ ACA_OFFSET+ACA_RW + WWCR_EVEN)), + &check_reason_page); + SET_PAGE(check_reason_page); + + DPRINTK("Adapter check interrupt\n"); + DPRINTK("8 reason bytes follow: "); + for (i = 0; i < 8; i++, check_reason++) + printk("%02X ", (int) readb(check_reason)); + printk("\n"); + writeb(~ADAP_CHK_INT, ti->mmio+ ACA_OFFSET+ACA_RESET+ ISRP_ODD); + status = readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRA_EVEN); + DPRINTK("ISRA_EVEN == 0x02%x\n",status); + ti->open_status = CLOSED; + ti->sap_status = CLOSED; + ti->open_mode = AUTOMATIC; + netif_carrier_off(dev); + netif_stop_queue(dev); + ti->open_action = RESTART; + outb(0, dev->base_addr + ADAPTRESET); + ibmtr_reset_timer(&(ti->tr_timer), dev);/*BMS try to reopen*/ + spin_unlock(&(ti->lock)); + return IRQ_HANDLED; + } + if (readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN) + & (TCR_INT | ERR_INT | ACCESS_INT)) { + DPRINTK("adapter error: ISRP_EVEN : %02x\n", + (int)readb(ti->mmio+ ACA_OFFSET + ACA_RW + ISRP_EVEN)); + writeb(~(TCR_INT | ERR_INT | ACCESS_INT), + ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN); + status= readb(ti->mmio+ ACA_OFFSET + ACA_RW + ISRA_EVEN);/*BMS*/ + DPRINTK("ISRA_EVEN == 0x02%x\n",status);/*BMS*/ + writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); +#ifdef ENABLE_PAGING + writeb(save_srpr, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN); +#endif + spin_unlock(&(ti->lock)); + return IRQ_HANDLED; + } + if (status & SRB_RESP_INT) { /* SRB response */ + SET_PAGE(ti->srb_page); +#if TR_VERBOSE + DPRINTK("SRB resp: cmd=%02X rsp=%02X\n", + readb(ti->srb), readb(ti->srb + RETCODE_OFST)); +#endif + switch (readb(ti->srb)) { /* SRB command check */ + case XMIT_DIR_FRAME:{ + unsigned char xmit_ret_code; + xmit_ret_code = readb(ti->srb + RETCODE_OFST); + if (xmit_ret_code == 0xff) break; + DPRINTK("error on xmit_dir_frame request: %02X\n", + xmit_ret_code); + if (ti->current_skb) { + dev_kfree_skb_irq(ti->current_skb); + ti->current_skb = NULL; + } + /*dev->tbusy = 0;*/ + netif_wake_queue(dev); + if (ti->readlog_pending) + ibmtr_readlog(dev); + break; + } + case XMIT_UI_FRAME:{ + unsigned char xmit_ret_code; + + xmit_ret_code = readb(ti->srb + RETCODE_OFST); + if (xmit_ret_code == 0xff) break; + DPRINTK("error on xmit_ui_frame request: %02X\n", + xmit_ret_code); + if (ti->current_skb) { + dev_kfree_skb_irq(ti->current_skb); + ti->current_skb = NULL; + } + netif_wake_queue(dev); + if (ti->readlog_pending) + ibmtr_readlog(dev); + break; + } + case DIR_OPEN_ADAPTER: + dir_open_adapter(dev); + break; + case DLC_OPEN_SAP: + if (readb(ti->srb + RETCODE_OFST)) { + DPRINTK("open_sap failed: ret_code = %02X, " + "retrying\n", + (int) readb(ti->srb + RETCODE_OFST)); + ti->open_action = REOPEN; + ibmtr_reset_timer(&(ti->tr_timer), dev); + break; + } + ti->exsap_station_id = readw(ti->srb + STATION_ID_OFST); + ti->sap_status = OPEN;/* TR adapter is now available */ + if (ti->open_mode==MANUAL){ + wake_up(&ti->wait_for_reset); + break; + } + netif_wake_queue(dev); + netif_carrier_on(dev); + break; + case DIR_INTERRUPT: + case DIR_MOD_OPEN_PARAMS: + case DIR_SET_GRP_ADDR: + case DIR_SET_FUNC_ADDR: + case DLC_CLOSE_SAP: + if (readb(ti->srb + RETCODE_OFST)) + DPRINTK("error on %02X: %02X\n", + (int) readb(ti->srb + COMMAND_OFST), + (int) readb(ti->srb + RETCODE_OFST)); + break; + case DIR_READ_LOG: + if (readb(ti->srb + RETCODE_OFST)){ + DPRINTK("error on dir_read_log: %02X\n", + (int) readb(ti->srb + RETCODE_OFST)); + netif_wake_queue(dev); + break; + } +#if IBMTR_DEBUG_MESSAGES + +#define LINE_ERRORS_OFST 0 +#define INTERNAL_ERRORS_OFST 1 +#define BURST_ERRORS_OFST 2 +#define AC_ERRORS_OFST 3 +#define ABORT_DELIMITERS_OFST 4 +#define LOST_FRAMES_OFST 6 +#define RECV_CONGEST_COUNT_OFST 7 +#define FRAME_COPIED_ERRORS_OFST 8 +#define FREQUENCY_ERRORS_OFST 9 +#define TOKEN_ERRORS_OFST 10 + + DPRINTK("Line errors %02X, Internal errors %02X, " + "Burst errors %02X\n" "A/C errors %02X, " + "Abort delimiters %02X, Lost frames %02X\n" + "Receive congestion count %02X, " + "Frame copied errors %02X\nFrequency errors %02X, " + "Token errors %02X\n", + (int) readb(ti->srb + LINE_ERRORS_OFST), + (int) readb(ti->srb + INTERNAL_ERRORS_OFST), + (int) readb(ti->srb + BURST_ERRORS_OFST), + (int) readb(ti->srb + AC_ERRORS_OFST), + (int) readb(ti->srb + ABORT_DELIMITERS_OFST), + (int) readb(ti->srb + LOST_FRAMES_OFST), + (int) readb(ti->srb + RECV_CONGEST_COUNT_OFST), + (int) readb(ti->srb + FRAME_COPIED_ERRORS_OFST), + (int) readb(ti->srb + FREQUENCY_ERRORS_OFST), + (int) readb(ti->srb + TOKEN_ERRORS_OFST)); +#endif + netif_wake_queue(dev); + break; + default: + DPRINTK("Unknown command %02X encountered\n", + (int) readb(ti->srb)); + } /* end switch SRB command check */ + writeb(~SRB_RESP_INT, ti->mmio+ ACA_OFFSET+ACA_RESET+ ISRP_ODD); + } /* if SRB response */ + if (status & ASB_FREE_INT) { /* ASB response */ + SET_PAGE(ti->asb_page); +#if TR_VERBOSE + DPRINTK("ASB resp: cmd=%02X\n", readb(ti->asb)); +#endif + + switch (readb(ti->asb)) { /* ASB command check */ + case REC_DATA: + case XMIT_UI_FRAME: + case XMIT_DIR_FRAME: + break; + default: + DPRINTK("unknown command in asb %02X\n", + (int) readb(ti->asb)); + } /* switch ASB command check */ + if (readb(ti->asb + 2) != 0xff) /* checks ret_code */ + DPRINTK("ASB error %02X in cmd %02X\n", + (int) readb(ti->asb + 2), (int) readb(ti->asb)); + writeb(~ASB_FREE_INT, ti->mmio+ ACA_OFFSET+ACA_RESET+ ISRP_ODD); + } /* if ASB response */ + +#define STATUS_OFST 6 +#define NETW_STATUS_OFST 6 + + if (status & ARB_CMD_INT) { /* ARB response */ + SET_PAGE(ti->arb_page); +#if TR_VERBOSE + DPRINTK("ARB resp: cmd=%02X\n", readb(ti->arb)); +#endif + + switch (readb(ti->arb)) { /* ARB command check */ + case DLC_STATUS: + DPRINTK("DLC_STATUS new status: %02X on station %02X\n", + ntohs(readw(ti->arb + STATUS_OFST)), + ntohs(readw(ti->arb+ STATION_ID_OFST))); + break; + case REC_DATA: + tr_rx(dev); + break; + case RING_STAT_CHANGE:{ + unsigned short ring_status; + ring_status= ntohs(readw(ti->arb + NETW_STATUS_OFST)); + if (ibmtr_debug_trace & TRC_INIT) + DPRINTK("Ring Status Change...(0x%x)\n", + ring_status); + if(ring_status& (REMOVE_RECV|AUTO_REMOVAL|LOBE_FAULT)){ + netif_stop_queue(dev); + netif_carrier_off(dev); + DPRINTK("Remove received, or Auto-removal error" + ", or Lobe fault\n"); + DPRINTK("We'll try to reopen the closed adapter" + " after a %d second delay.\n", + TR_RETRY_INTERVAL/HZ); + /*I was confused: I saw the TR reopening but */ + /*forgot:with an RJ45 in an RJ45/ICS adapter */ + /*but adapter not in the ring, the TR will */ + /* open, and then soon close and come here. */ + ti->open_mode = AUTOMATIC; + ti->open_status = CLOSED; /*12/2000 BMS*/ + ti->open_action = REOPEN; + ibmtr_reset_timer(&(ti->tr_timer), dev); + } else if (ring_status & LOG_OVERFLOW) { + if(netif_queue_stopped(dev)) + ti->readlog_pending = 1; + else + ibmtr_readlog(dev); + } + break; + } + case XMIT_DATA_REQ: + tr_tx(dev); + break; + default: + DPRINTK("Unknown command %02X in arb\n", + (int) readb(ti->arb)); + break; + } /* switch ARB command check */ + writeb(~ARB_CMD_INT, ti->mmio+ ACA_OFFSET+ACA_RESET + ISRP_ODD); + writeb(ARB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + } /* if ARB response */ + if (status & SSB_RESP_INT) { /* SSB response */ + unsigned char retcode; + SET_PAGE(ti->ssb_page); +#if TR_VERBOSE + DPRINTK("SSB resp: cmd=%02X rsp=%02X\n", + readb(ti->ssb), readb(ti->ssb + 2)); +#endif + + switch (readb(ti->ssb)) { /* SSB command check */ + case XMIT_DIR_FRAME: + case XMIT_UI_FRAME: + retcode = readb(ti->ssb + 2); + if (retcode && (retcode != 0x22))/* checks ret_code */ + DPRINTK("xmit ret_code: %02X xmit error code: " + "%02X\n", + (int)retcode, (int)readb(ti->ssb + 6)); + else + dev->stats.tx_packets++; + break; + case XMIT_XID_CMD: + DPRINTK("xmit xid ret_code: %02X\n", + (int) readb(ti->ssb + 2)); + default: + DPRINTK("Unknown command %02X in ssb\n", + (int) readb(ti->ssb)); + } /* SSB command check */ + writeb(~SSB_RESP_INT, ti->mmio+ ACA_OFFSET+ACA_RESET+ ISRP_ODD); + writeb(SSB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + } /* if SSB response */ +#ifdef ENABLE_PAGING + writeb(save_srpr, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN); +#endif + writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); + spin_unlock(&(ti->lock)); + return IRQ_HANDLED; +} /*tok_interrupt */ + +/*****************************************************************************/ + +#define INIT_STATUS_OFST 1 +#define INIT_STATUS_2_OFST 2 +#define ENCODED_ADDRESS_OFST 8 + +static void initial_tok_int(struct net_device *dev) +{ + + __u32 encoded_addr, hw_encoded_addr; + struct tok_info *ti; + unsigned char init_status; /*BMS 12/2000*/ + + ti = netdev_priv(dev); + + ti->do_tok_int = NOT_FIRST; + + /* we assign the shared-ram address for ISA devices */ + writeb(ti->sram_base, ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN); +#ifndef PCMCIA + ti->sram_virt = ioremap(((__u32)ti->sram_base << 12), ti->avail_shared_ram); +#endif + ti->init_srb = map_address(ti, + ntohs(readw(ti->mmio + ACA_OFFSET + WRBR_EVEN)), + &ti->init_srb_page); + if (ti->page_mask && ti->avail_shared_ram == 127) { + void __iomem *last_512; + __u8 last_512_page=0; + int i; + last_512 = map_address(ti, 0xfe00, &last_512_page); + /* initialize high section of ram (if necessary) */ + SET_PAGE(last_512_page); + for (i = 0; i < 512; i++) + writeb(0, last_512 + i); + } + SET_PAGE(ti->init_srb_page); + +#if TR_VERBOSE + { + int i; + + DPRINTK("ti->init_srb_page=0x%x\n", ti->init_srb_page); + DPRINTK("init_srb(%p):", ti->init_srb ); + for (i = 0; i < 20; i++) + printk("%02X ", (int) readb(ti->init_srb + i)); + printk("\n"); + } +#endif + + hw_encoded_addr = readw(ti->init_srb + ENCODED_ADDRESS_OFST); + encoded_addr = ntohs(hw_encoded_addr); + init_status= /*BMS 12/2000 check for shallow mode possibility (Turbo)*/ + readb(ti->init_srb+offsetof(struct srb_init_response,init_status)); + /*printk("Initial interrupt: init_status= 0x%02x\n",init_status);*/ + ti->ring_speed = init_status & 0x01 ? 16 : 4; + DPRINTK("Initial interrupt : %d Mbps, shared RAM base %08x.\n", + ti->ring_speed, (unsigned int)dev->mem_start); + ti->auto_speedsave = (readb(ti->init_srb+INIT_STATUS_2_OFST) & 4) != 0; + + if (ti->open_mode == MANUAL) wake_up(&ti->wait_for_reset); + else tok_open_adapter((unsigned long)dev); + +} /*initial_tok_int() */ + +/*****************************************************************************/ + +#define CMD_CORRELATE_OFST 1 +#define DHB_ADDRESS_OFST 6 + +#define FRAME_LENGTH_OFST 6 +#define HEADER_LENGTH_OFST 8 +#define RSAP_VALUE_OFST 9 + +static void tr_tx(struct net_device *dev) +{ + struct tok_info *ti = netdev_priv(dev); + struct trh_hdr *trhdr = (struct trh_hdr *) ti->current_skb->data; + unsigned int hdr_len; + __u32 dhb=0,dhb_base; + void __iomem *dhbuf = NULL; + unsigned char xmit_command; + int i,dhb_len=0x4000,src_len,src_offset; + struct trllc *llc; + struct srb_xmit xsrb; + __u8 dhb_page = 0; + __u8 llc_ssap; + + SET_PAGE(ti->asb_page); + + if (readb(ti->asb+RETCODE_OFST) != 0xFF) DPRINTK("ASB not free !!!\n"); + + /* in providing the transmit interrupts, is telling us it is ready for + data and providing a shared memory address for us to stuff with data. + Here we compute the effective address where we will place data. + */ + SET_PAGE(ti->arb_page); + dhb=dhb_base=ntohs(readw(ti->arb + DHB_ADDRESS_OFST)); + if (ti->page_mask) { + dhb_page = (dhb_base >> 8) & ti->page_mask; + dhb=dhb_base & ~(ti->page_mask << 8); + } + dhbuf = ti->sram_virt + dhb; + + /* Figure out the size of the 802.5 header */ + if (!(trhdr->saddr[0] & 0x80)) /* RIF present? */ + hdr_len = sizeof(struct trh_hdr) - TR_MAXRIFLEN; + else + hdr_len = ((ntohs(trhdr->rcf) & TR_RCF_LEN_MASK) >> 8) + + sizeof(struct trh_hdr) - TR_MAXRIFLEN; + + llc = (struct trllc *) (ti->current_skb->data + hdr_len); + + llc_ssap = llc->ssap; + SET_PAGE(ti->srb_page); + memcpy_fromio(&xsrb, ti->srb, sizeof(xsrb)); + SET_PAGE(ti->asb_page); + xmit_command = xsrb.command; + + writeb(xmit_command, ti->asb + COMMAND_OFST); + writew(xsrb.station_id, ti->asb + STATION_ID_OFST); + writeb(llc_ssap, ti->asb + RSAP_VALUE_OFST); + writeb(xsrb.cmd_corr, ti->asb + CMD_CORRELATE_OFST); + writeb(0, ti->asb + RETCODE_OFST); + if ((xmit_command == XMIT_XID_CMD) || (xmit_command == XMIT_TEST_CMD)) { + writew(htons(0x11), ti->asb + FRAME_LENGTH_OFST); + writeb(0x0e, ti->asb + HEADER_LENGTH_OFST); + SET_PAGE(dhb_page); + writeb(AC, dhbuf); + writeb(LLC_FRAME, dhbuf + 1); + for (i = 0; i < TR_ALEN; i++) + writeb((int) 0x0FF, dhbuf + i + 2); + for (i = 0; i < TR_ALEN; i++) + writeb(0, dhbuf + i + TR_ALEN + 2); + writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + return; + } + /* + * the token ring packet is copied from sk_buff to the adapter + * buffer identified in the command data received with the interrupt. + */ + writeb(hdr_len, ti->asb + HEADER_LENGTH_OFST); + writew(htons(ti->current_skb->len), ti->asb + FRAME_LENGTH_OFST); + src_len=ti->current_skb->len; + src_offset=0; + dhb=dhb_base; + while(1) { + if (ti->page_mask) { + dhb_page=(dhb >> 8) & ti->page_mask; + dhb=dhb & ~(ti->page_mask << 8); + dhb_len=0x4000-dhb; /* remaining size of this page */ + } + dhbuf = ti->sram_virt + dhb; + SET_PAGE(dhb_page); + if (src_len > dhb_len) { + memcpy_toio(dhbuf,&ti->current_skb->data[src_offset], + dhb_len); + src_len -= dhb_len; + src_offset += dhb_len; + dhb_base+=dhb_len; + dhb=dhb_base; + continue; + } + memcpy_toio(dhbuf, &ti->current_skb->data[src_offset], src_len); + break; + } + writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + dev->stats.tx_bytes += ti->current_skb->len; + dev_kfree_skb_irq(ti->current_skb); + ti->current_skb = NULL; + netif_wake_queue(dev); + if (ti->readlog_pending) + ibmtr_readlog(dev); +} /*tr_tx */ + +/*****************************************************************************/ + + +#define RECEIVE_BUFFER_OFST 6 +#define LAN_HDR_LENGTH_OFST 8 +#define DLC_HDR_LENGTH_OFST 9 + +#define DSAP_OFST 0 +#define SSAP_OFST 1 +#define LLC_OFST 2 +#define PROTID_OFST 3 +#define ETHERTYPE_OFST 6 + +static void tr_rx(struct net_device *dev) +{ + struct tok_info *ti = netdev_priv(dev); + __u32 rbuffer; + void __iomem *rbuf, *rbufdata, *llc; + __u8 rbuffer_page = 0; + unsigned char *data; + unsigned int rbuffer_len, lan_hdr_len, hdr_len, ip_len, length; + unsigned char dlc_hdr_len; + struct sk_buff *skb; + unsigned int skb_size = 0; + int IPv4_p = 0; + unsigned int chksum = 0; + struct iphdr *iph; + struct arb_rec_req rarb; + + SET_PAGE(ti->arb_page); + memcpy_fromio(&rarb, ti->arb, sizeof(rarb)); + rbuffer = ntohs(rarb.rec_buf_addr) ; + rbuf = map_address(ti, rbuffer, &rbuffer_page); + + SET_PAGE(ti->asb_page); + + if (readb(ti->asb + RETCODE_OFST) !=0xFF) DPRINTK("ASB not free !!!\n"); + + writeb(REC_DATA, ti->asb + COMMAND_OFST); + writew(rarb.station_id, ti->asb + STATION_ID_OFST); + writew(rarb.rec_buf_addr, ti->asb + RECEIVE_BUFFER_OFST); + + lan_hdr_len = rarb.lan_hdr_len; + if (lan_hdr_len > sizeof(struct trh_hdr)) { + DPRINTK("Linux cannot handle greater than 18 bytes RIF\n"); + return; + } /*BMS I added this above just to be very safe */ + dlc_hdr_len = readb(ti->arb + DLC_HDR_LENGTH_OFST); + hdr_len = lan_hdr_len + sizeof(struct trllc) + sizeof(struct iphdr); + + SET_PAGE(rbuffer_page); + llc = rbuf + offsetof(struct rec_buf, data) + lan_hdr_len; + +#if TR_VERBOSE + DPRINTK("offsetof data: %02X lan_hdr_len: %02X\n", + (__u32) offsetof(struct rec_buf, data), (unsigned int) lan_hdr_len); + DPRINTK("llc: %08X rec_buf_addr: %04X dev->mem_start: %lX\n", + llc, ntohs(rarb.rec_buf_addr), dev->mem_start); + DPRINTK("dsap: %02X, ssap: %02X, llc: %02X, protid: %02X%02X%02X, " + "ethertype: %04X\n", + (int) readb(llc + DSAP_OFST), (int) readb(llc + SSAP_OFST), + (int) readb(llc + LLC_OFST), (int) readb(llc + PROTID_OFST), + (int) readb(llc+PROTID_OFST+1),(int)readb(llc+PROTID_OFST + 2), + (int) ntohs(readw(llc + ETHERTYPE_OFST))); +#endif + if (readb(llc + offsetof(struct trllc, llc)) != UI_CMD) { + SET_PAGE(ti->asb_page); + writeb(DATA_LOST, ti->asb + RETCODE_OFST); + dev->stats.rx_dropped++; + writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + return; + } + length = ntohs(rarb.frame_len); + if (readb(llc + DSAP_OFST) == EXTENDED_SAP && + readb(llc + SSAP_OFST) == EXTENDED_SAP && + length >= hdr_len) IPv4_p = 1; +#if TR_VERBOSE +#define SADDR_OFST 8 +#define DADDR_OFST 2 + + if (!IPv4_p) { + + void __iomem *trhhdr = rbuf + offsetof(struct rec_buf, data); + u8 saddr[6]; + u8 daddr[6]; + int i; + for (i = 0 ; i < 6 ; i++) + saddr[i] = readb(trhhdr + SADDR_OFST + i); + for (i = 0 ; i < 6 ; i++) + daddr[i] = readb(trhhdr + DADDR_OFST + i); + DPRINTK("Probably non-IP frame received.\n"); + DPRINTK("ssap: %02X dsap: %02X " + "saddr: %pM daddr: %pM\n", + readb(llc + SSAP_OFST), readb(llc + DSAP_OFST), + saddr, daddr); + } +#endif + + /*BMS handle the case she comes in with few hops but leaves with many */ + skb_size=length-lan_hdr_len+sizeof(struct trh_hdr)+sizeof(struct trllc); + + if (!(skb = dev_alloc_skb(skb_size))) { + DPRINTK("out of memory. frame dropped.\n"); + dev->stats.rx_dropped++; + SET_PAGE(ti->asb_page); + writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code)); + writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + return; + } + /*BMS again, if she comes in with few but leaves with many */ + skb_reserve(skb, sizeof(struct trh_hdr) - lan_hdr_len); + skb_put(skb, length); + data = skb->data; + rbuffer_len = ntohs(readw(rbuf + offsetof(struct rec_buf, buf_len))); + rbufdata = rbuf + offsetof(struct rec_buf, data); + + if (IPv4_p) { + /* Copy the headers without checksumming */ + memcpy_fromio(data, rbufdata, hdr_len); + + /* Watch for padded packets and bogons */ + iph= (struct iphdr *)(data+ lan_hdr_len + sizeof(struct trllc)); + ip_len = ntohs(iph->tot_len) - sizeof(struct iphdr); + length -= hdr_len; + if ((ip_len <= length) && (ip_len > 7)) + length = ip_len; + data += hdr_len; + rbuffer_len -= hdr_len; + rbufdata += hdr_len; + } + /* Copy the payload... */ +#define BUFFER_POINTER_OFST 2 +#define BUFFER_LENGTH_OFST 6 + for (;;) { + if (ibmtr_debug_trace&TRC_INITV && length < rbuffer_len) + DPRINTK("CURIOUS, length=%d < rbuffer_len=%d\n", + length,rbuffer_len); + if (IPv4_p) + chksum=csum_partial_copy_nocheck((void*)rbufdata, + data,lengthasb_page); + writeb(0, ti->asb + offsetof(struct asb_rec, ret_code)); + + writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + + dev->stats.rx_bytes += skb->len; + dev->stats.rx_packets++; + + skb->protocol = tr_type_trans(skb, dev); + if (IPv4_p) { + skb->csum = chksum; + skb->ip_summed = CHECKSUM_COMPLETE; + } + netif_rx(skb); +} /*tr_rx */ + +/*****************************************************************************/ + +static void ibmtr_reset_timer(struct timer_list *tmr, struct net_device *dev) +{ + tmr->expires = jiffies + TR_RETRY_INTERVAL; + tmr->data = (unsigned long) dev; + tmr->function = tok_rerun; + init_timer(tmr); + add_timer(tmr); +} + +/*****************************************************************************/ + +static void tok_rerun(unsigned long dev_addr) +{ + struct net_device *dev = (struct net_device *)dev_addr; + struct tok_info *ti = netdev_priv(dev); + + if ( ti->open_action == RESTART){ + ti->do_tok_int = FIRST_INT; + outb(0, dev->base_addr + ADAPTRESETREL); +#ifdef ENABLE_PAGING + if (ti->page_mask) + writeb(SRPR_ENABLE_PAGING, + ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN); +#endif + + writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); + } else + tok_open_adapter(dev_addr); +} + +/*****************************************************************************/ + +static void ibmtr_readlog(struct net_device *dev) +{ + struct tok_info *ti; + + ti = netdev_priv(dev); + + ti->readlog_pending = 0; + SET_PAGE(ti->srb_page); + writeb(DIR_READ_LOG, ti->srb); + writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); + writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + + netif_stop_queue(dev); + +} + +/*****************************************************************************/ + +static int ibmtr_change_mtu(struct net_device *dev, int mtu) +{ + struct tok_info *ti = netdev_priv(dev); + + if (ti->ring_speed == 16 && mtu > ti->maxmtu16) + return -EINVAL; + if (ti->ring_speed == 4 && mtu > ti->maxmtu4) + return -EINVAL; + dev->mtu = mtu; + return 0; +} + +/*****************************************************************************/ +#ifdef MODULE + +/* 3COM 3C619C supports 8 interrupts, 32 I/O ports */ +static struct net_device *dev_ibmtr[IBMTR_MAX_ADAPTERS]; +static int io[IBMTR_MAX_ADAPTERS] = { 0xa20, 0xa24 }; +static int irq[IBMTR_MAX_ADAPTERS]; +static int mem[IBMTR_MAX_ADAPTERS]; + +MODULE_LICENSE("GPL"); + +module_param_array(io, int, NULL, 0); +module_param_array(irq, int, NULL, 0); +module_param_array(mem, int, NULL, 0); + +static int __init ibmtr_init(void) +{ + int i; + int count=0; + + find_turbo_adapters(io); + + for (i = 0; i < IBMTR_MAX_ADAPTERS && io[i]; i++) { + struct net_device *dev; + irq[i] = 0; + mem[i] = 0; + dev = alloc_trdev(sizeof(struct tok_info)); + if (dev == NULL) { + if (i == 0) + return -ENOMEM; + break; + } + dev->base_addr = io[i]; + dev->irq = irq[i]; + dev->mem_start = mem[i]; + + if (ibmtr_probe_card(dev)) { + free_netdev(dev); + continue; + } + dev_ibmtr[i] = dev; + count++; + } + if (count) return 0; + printk("ibmtr: register_netdev() returned non-zero.\n"); + return -EIO; +} +module_init(ibmtr_init); + +static void __exit ibmtr_cleanup(void) +{ + int i; + + for (i = 0; i < IBMTR_MAX_ADAPTERS; i++){ + if (!dev_ibmtr[i]) + continue; + unregister_netdev(dev_ibmtr[i]); + ibmtr_cleanup_card(dev_ibmtr[i]); + free_netdev(dev_ibmtr[i]); + } +} +module_exit(ibmtr_cleanup); +#endif diff --git a/trunk/drivers/net/tokenring/ibmtr_cs.c b/trunk/drivers/net/tokenring/ibmtr_cs.c new file mode 100644 index 000000000000..356e28e4881b --- /dev/null +++ b/trunk/drivers/net/tokenring/ibmtr_cs.c @@ -0,0 +1,370 @@ +/*====================================================================== + + A PCMCIA token-ring driver for IBM-based cards + + This driver supports the IBM PCMCIA Token-Ring Card. + Written by Steve Kipisz, kipisz@vnet.ibm.com or + bungy@ibm.net + + Written 1995,1996. + + This code is based on pcnet_cs.c from David Hinds. + + V2.2.0 February 1999 - Mike Phillips phillim@amtrak.com + + Linux V2.2.x presented significant changes to the underlying + ibmtr.c code. Mainly the code became a lot more organized and + modular. + + This caused the old PCMCIA Token Ring driver to give up and go + home early. Instead of just patching the old code to make it + work, the PCMCIA code has been streamlined, updated and possibly + improved. + + This code now only contains code required for the Card Services. + All we do here is set the card up enough so that the real ibmtr.c + driver can find it and work with it properly. + + i.e. We set up the io port, irq, mmio memory and shared ram + memory. This enables ibmtr_probe in ibmtr.c to find the card and + configure it as though it was a normal ISA and/or PnP card. + + CHANGES + + v2.2.5 April 1999 Mike Phillips (phillim@amtrak.com) + Obscure bug fix, required changed to ibmtr.c not ibmtr_cs.c + + v2.2.7 May 1999 Mike Phillips (phillim@amtrak.com) + Updated to version 2.2.7 to match the first version of the kernel + that the modification to ibmtr.c were incorporated into. + + v2.2.17 July 2000 Burt Silverman (burts@us.ibm.com) + Address translation feature of PCMCIA controller is usable so + memory windows can be placed in High memory (meaning above + 0xFFFFF.) + +======================================================================*/ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#define PCMCIA +#include "ibmtr.c" + + +/*====================================================================*/ + +/* Parameters that can be set with 'insmod' */ + +/* MMIO base address */ +static u_long mmiobase = 0xce000; + +/* SRAM base address */ +static u_long srambase = 0xd0000; + +/* SRAM size 8,16,32,64 */ +static u_long sramsize = 64; + +/* Ringspeed 4,16 */ +static int ringspeed = 16; + +module_param(mmiobase, ulong, 0); +module_param(srambase, ulong, 0); +module_param(sramsize, ulong, 0); +module_param(ringspeed, int, 0); +MODULE_LICENSE("GPL"); + +/*====================================================================*/ + +static int ibmtr_config(struct pcmcia_device *link); +static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase); +static void ibmtr_release(struct pcmcia_device *link); +static void ibmtr_detach(struct pcmcia_device *p_dev); + +/*====================================================================*/ + +typedef struct ibmtr_dev_t { + struct pcmcia_device *p_dev; + struct net_device *dev; + struct tok_info *ti; +} ibmtr_dev_t; + +static irqreturn_t ibmtr_interrupt(int irq, void *dev_id) { + ibmtr_dev_t *info = dev_id; + struct net_device *dev = info->dev; + return tok_interrupt(irq, dev); +}; + +static int __devinit ibmtr_attach(struct pcmcia_device *link) +{ + ibmtr_dev_t *info; + struct net_device *dev; + + dev_dbg(&link->dev, "ibmtr_attach()\n"); + + /* Create new token-ring device */ + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) return -ENOMEM; + dev = alloc_trdev(sizeof(struct tok_info)); + if (!dev) { + kfree(info); + return -ENOMEM; + } + + info->p_dev = link; + link->priv = info; + info->ti = netdev_priv(dev); + + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; + link->resource[0]->end = 4; + link->config_flags |= CONF_ENABLE_IRQ; + link->config_regs = PRESENT_OPTION; + + info->dev = dev; + + return ibmtr_config(link); +} /* ibmtr_attach */ + +static void ibmtr_detach(struct pcmcia_device *link) +{ + struct ibmtr_dev_t *info = link->priv; + struct net_device *dev = info->dev; + struct tok_info *ti = netdev_priv(dev); + + dev_dbg(&link->dev, "ibmtr_detach\n"); + + /* + * When the card removal interrupt hits tok_interrupt(), + * bail out early, so we don't crash the machine + */ + ti->sram_phys |= 1; + + unregister_netdev(dev); + + del_timer_sync(&(ti->tr_timer)); + + ibmtr_release(link); + + free_netdev(dev); + kfree(info); +} /* ibmtr_detach */ + +static int __devinit ibmtr_config(struct pcmcia_device *link) +{ + ibmtr_dev_t *info = link->priv; + struct net_device *dev = info->dev; + struct tok_info *ti = netdev_priv(dev); + int i, ret; + + dev_dbg(&link->dev, "ibmtr_config\n"); + + link->io_lines = 16; + link->config_index = 0x61; + + /* Determine if this is PRIMARY or ALTERNATE. */ + + /* Try PRIMARY card at 0xA20-0xA23 */ + link->resource[0]->start = 0xA20; + i = pcmcia_request_io(link); + if (i != 0) { + /* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */ + link->resource[0]->start = 0xA24; + ret = pcmcia_request_io(link); + if (ret) + goto failed; + } + dev->base_addr = link->resource[0]->start; + + ret = pcmcia_request_exclusive_irq(link, ibmtr_interrupt); + if (ret) + goto failed; + dev->irq = link->irq; + ti->irq = link->irq; + ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq); + + /* Allocate the MMIO memory window */ + link->resource[2]->flags |= WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE; + link->resource[2]->flags |= WIN_USE_WAIT; + link->resource[2]->start = 0; + link->resource[2]->end = 0x2000; + ret = pcmcia_request_window(link, link->resource[2], 250); + if (ret) + goto failed; + + ret = pcmcia_map_mem_page(link, link->resource[2], mmiobase); + if (ret) + goto failed; + ti->mmio = ioremap(link->resource[2]->start, + resource_size(link->resource[2])); + + /* Allocate the SRAM memory window */ + link->resource[3]->flags = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE; + link->resource[3]->flags |= WIN_USE_WAIT; + link->resource[3]->start = 0; + link->resource[3]->end = sramsize * 1024; + ret = pcmcia_request_window(link, link->resource[3], 250); + if (ret) + goto failed; + + ret = pcmcia_map_mem_page(link, link->resource[3], srambase); + if (ret) + goto failed; + + ti->sram_base = srambase >> 12; + ti->sram_virt = ioremap(link->resource[3]->start, + resource_size(link->resource[3])); + ti->sram_phys = link->resource[3]->start; + + ret = pcmcia_enable_device(link); + if (ret) + goto failed; + + /* Set up the Token-Ring Controller Configuration Register and + turn on the card. Check the "Local Area Network Credit Card + Adapters Technical Reference" SC30-3585 for this info. */ + ibmtr_hw_setup(dev, mmiobase); + + SET_NETDEV_DEV(dev, &link->dev); + + i = ibmtr_probe_card(dev); + if (i != 0) { + pr_notice("register_netdev() failed\n"); + goto failed; + } + + netdev_info(dev, "port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n", + dev->base_addr, dev->irq, + (u_long)ti->mmio, (u_long)(ti->sram_base << 12), + dev->dev_addr); + return 0; + +failed: + ibmtr_release(link); + return -ENODEV; +} /* ibmtr_config */ + +static void ibmtr_release(struct pcmcia_device *link) +{ + ibmtr_dev_t *info = link->priv; + struct net_device *dev = info->dev; + + dev_dbg(&link->dev, "ibmtr_release\n"); + + if (link->resource[2]->end) { + struct tok_info *ti = netdev_priv(dev); + iounmap(ti->mmio); + } + pcmcia_disable_device(link); +} + +static int ibmtr_suspend(struct pcmcia_device *link) +{ + ibmtr_dev_t *info = link->priv; + struct net_device *dev = info->dev; + + if (link->open) + netif_device_detach(dev); + + return 0; +} + +static int __devinit ibmtr_resume(struct pcmcia_device *link) +{ + ibmtr_dev_t *info = link->priv; + struct net_device *dev = info->dev; + + if (link->open) { + ibmtr_probe(dev); /* really? */ + netif_device_attach(dev); + } + + return 0; +} + + +/*====================================================================*/ + +static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase) +{ + int i; + + /* Bizarre IBM behavior, there are 16 bits of information we + need to set, but the card only allows us to send 4 bits at a + time. For each byte sent to base_addr, bits 7-4 tell the + card which part of the 16 bits we are setting, bits 3-0 contain + the actual information */ + + /* First nibble provides 4 bits of mmio */ + i = (mmiobase >> 16) & 0x0F; + outb(i, dev->base_addr); + + /* Second nibble provides 3 bits of mmio */ + i = 0x10 | ((mmiobase >> 12) & 0x0E); + outb(i, dev->base_addr); + + /* Third nibble, hard-coded values */ + i = 0x26; + outb(i, dev->base_addr); + + /* Fourth nibble sets shared ram page size */ + + /* 8 = 00, 16 = 01, 32 = 10, 64 = 11 */ + i = (sramsize >> 4) & 0x07; + i = ((i == 4) ? 3 : i) << 2; + i |= 0x30; + + if (ringspeed == 16) + i |= 2; + if (dev->base_addr == 0xA24) + i |= 1; + outb(i, dev->base_addr); + + /* 0x40 will release the card for use */ + outb(0x40, dev->base_addr); +} + +static const struct pcmcia_device_id ibmtr_ids[] = { + PCMCIA_DEVICE_PROD_ID12("3Com", "TokenLink Velocity PC Card", 0x41240e5b, 0x82c3734e), + PCMCIA_DEVICE_PROD_ID12("IBM", "TOKEN RING", 0xb569a6e5, 0xbf8eed47), + PCMCIA_DEVICE_NULL, +}; +MODULE_DEVICE_TABLE(pcmcia, ibmtr_ids); + +static struct pcmcia_driver ibmtr_cs_driver = { + .owner = THIS_MODULE, + .name = "ibmtr_cs", + .probe = ibmtr_attach, + .remove = ibmtr_detach, + .id_table = ibmtr_ids, + .suspend = ibmtr_suspend, + .resume = ibmtr_resume, +}; + +static int __init init_ibmtr_cs(void) +{ + return pcmcia_register_driver(&ibmtr_cs_driver); +} + +static void __exit exit_ibmtr_cs(void) +{ + pcmcia_unregister_driver(&ibmtr_cs_driver); +} + +module_init(init_ibmtr_cs); +module_exit(exit_ibmtr_cs); diff --git a/trunk/drivers/net/tokenring/lanstreamer.c b/trunk/drivers/net/tokenring/lanstreamer.c new file mode 100644 index 000000000000..97e4c65c1e29 --- /dev/null +++ b/trunk/drivers/net/tokenring/lanstreamer.c @@ -0,0 +1,1909 @@ +/* + * lanstreamer.c -- driver for the IBM Auto LANStreamer PCI Adapter + * + * Written By: Mike Sullivan, IBM Corporation + * + * Copyright (C) 1999 IBM Corporation + * + * Linux driver for IBM PCI tokenring cards based on the LanStreamer MPC + * chipset. + * + * This driver is based on the olympic driver for IBM PCI TokenRing cards (Pit/Pit-Phy/Olympic + * chipsets) written by: + * 1999 Peter De Schrijver All Rights Reserved + * 1999 Mike Phillips (phillim@amtrak.com) + * + * Base Driver Skeleton: + * Written 1993-94 by Donald Becker. + * + * Copyright 1993 United States Government as represented by the + * Director, National Security Agency. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * NO WARRANTY + * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT + * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is + * solely responsible for determining the appropriateness of using and + * distributing the Program and assumes all risks associated with its + * exercise of rights under this Agreement, including but not limited to + * the risks and costs of program errors, damage to or loss of data, + * programs or equipment, and unavailability or interruption of operations. + * + * DISCLAIMER OF LIABILITY + * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED + * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * 12/10/99 - Alpha Release 0.1.0 + * First release to the public + * 03/03/00 - Merged to kernel, indented -kr -i8 -bri0, fixed some missing + * malloc free checks, reviewed code. + * 03/13/00 - Added spinlocks for smp + * 03/08/01 - Added support for module_init() and module_exit() + * 08/15/01 - Added ioctl() functionality for debugging, changed netif_*_queue + * calls and other incorrectness - Kent Yoder + * 11/05/01 - Restructured the interrupt function, added delays, reduced the + * the number of TX descriptors to 1, which together can prevent + * the card from locking up the box - + * 09/27/02 - New PCI interface + bug fix. - + * 11/13/02 - Removed free_irq calls which could cause a hang, added + * netif_carrier_{on|off} - + * + * To Do: + * + * + * If Problems do Occur + * Most problems can be rectified by either closing and opening the interface + * (ifconfig down and up) or rmmod and insmod'ing the driver (a bit difficult + * if compiled into the kernel). + */ + +/* Change STREAMER_DEBUG to 1 to get verbose, and I mean really verbose, messages */ + +#define STREAMER_DEBUG 0 +#define STREAMER_DEBUG_PACKETS 0 + +/* Change STREAMER_NETWORK_MONITOR to receive mac frames through the arb channel. + * Will also create a /proc/net/streamer_tr entry if proc_fs is compiled into the + * kernel. + * Intended to be used to create a ring-error reporting network module + * i.e. it will give you the source address of beaconers on the ring + */ + +#define STREAMER_NETWORK_MONITOR 0 + +/* #define CONFIG_PROC_FS */ + +/* + * Allow or disallow ioctl's for debugging + */ + +#define STREAMER_IOCTL 0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "lanstreamer.h" + +#if (BITS_PER_LONG == 64) +#error broken on 64-bit: stores pointer to rx_ring->buffer in 32-bit int +#endif + + +/* I've got to put some intelligence into the version number so that Peter and I know + * which version of the code somebody has got. + * Version Number = a.b.c.d where a.b.c is the level of code and d is the latest author. + * So 0.0.1.pds = Peter, 0.0.1.mlp = Mike + * + * Official releases will only have an a.b.c version number format. + */ + +static char version[] = "LanStreamer.c v0.4.0 03/08/01 - Mike Sullivan\n" + " v0.5.3 11/13/02 - Kent Yoder"; + +static DEFINE_PCI_DEVICE_TABLE(streamer_pci_tbl) = { + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_TR, PCI_ANY_ID, PCI_ANY_ID,}, + {} /* terminating entry */ +}; +MODULE_DEVICE_TABLE(pci,streamer_pci_tbl); + + +static char *open_maj_error[] = { + "No error", "Lobe Media Test", "Physical Insertion", + "Address Verification", "Neighbor Notification (Ring Poll)", + "Request Parameters", "FDX Registration Request", + "FDX Lobe Media Test", "FDX Duplicate Address Check", + "Unknown stage" +}; + +static char *open_min_error[] = { + "No error", "Function Failure", "Signal Lost", "Wire Fault", + "Ring Speed Mismatch", "Timeout", "Ring Failure", "Ring Beaconing", + "Duplicate Node Address", "Request Parameters", "Remove Received", + "Reserved", "Reserved", "No Monitor Detected for RPL", + "Monitor Contention failer for RPL", "FDX Protocol Error" +}; + +/* Module parameters */ + +/* Ring Speed 0,4,16 + * 0 = Autosense + * 4,16 = Selected speed only, no autosense + * This allows the card to be the first on the ring + * and become the active monitor. + * + * WARNING: Some hubs will allow you to insert + * at the wrong speed + */ + +static int ringspeed[STREAMER_MAX_ADAPTERS] = { 0, }; + +module_param_array(ringspeed, int, NULL, 0); + +/* Packet buffer size */ + +static int pkt_buf_sz[STREAMER_MAX_ADAPTERS] = { 0, }; + +module_param_array(pkt_buf_sz, int, NULL, 0); + +/* Message Level */ + +static int message_level[STREAMER_MAX_ADAPTERS] = { 1, }; + +module_param_array(message_level, int, NULL, 0); + +#if STREAMER_IOCTL +static int streamer_ioctl(struct net_device *, struct ifreq *, int); +#endif + +static int streamer_reset(struct net_device *dev); +static int streamer_open(struct net_device *dev); +static netdev_tx_t streamer_xmit(struct sk_buff *skb, + struct net_device *dev); +static int streamer_close(struct net_device *dev); +static void streamer_set_rx_mode(struct net_device *dev); +static irqreturn_t streamer_interrupt(int irq, void *dev_id); +static int streamer_set_mac_address(struct net_device *dev, void *addr); +static void streamer_arb_cmd(struct net_device *dev); +static int streamer_change_mtu(struct net_device *dev, int mtu); +static void streamer_srb_bh(struct net_device *dev); +static void streamer_asb_bh(struct net_device *dev); +#if STREAMER_NETWORK_MONITOR +#ifdef CONFIG_PROC_FS +static int streamer_proc_info(char *buffer, char **start, off_t offset, + int length, int *eof, void *data); +static int sprintf_info(char *buffer, struct net_device *dev); +struct streamer_private *dev_streamer=NULL; +#endif +#endif + +static const struct net_device_ops streamer_netdev_ops = { + .ndo_open = streamer_open, + .ndo_stop = streamer_close, + .ndo_start_xmit = streamer_xmit, + .ndo_change_mtu = streamer_change_mtu, +#if STREAMER_IOCTL + .ndo_do_ioctl = streamer_ioctl, +#endif + .ndo_set_rx_mode = streamer_set_rx_mode, + .ndo_set_mac_address = streamer_set_mac_address, +}; + +static int __devinit streamer_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct net_device *dev; + struct streamer_private *streamer_priv; + unsigned long pio_start, pio_end, pio_flags, pio_len; + unsigned long mmio_start, mmio_end, mmio_flags, mmio_len; + int rc = 0; + static int card_no=-1; + u16 pcr; + +#if STREAMER_DEBUG + printk("lanstreamer::streamer_init_one, entry pdev %p\n",pdev); +#endif + + card_no++; + dev = alloc_trdev(sizeof(*streamer_priv)); + if (dev==NULL) { + printk(KERN_ERR "lanstreamer: out of memory.\n"); + return -ENOMEM; + } + + streamer_priv = netdev_priv(dev); + +#if STREAMER_NETWORK_MONITOR +#ifdef CONFIG_PROC_FS + if (!dev_streamer) + create_proc_read_entry("streamer_tr", 0, init_net.proc_net, + streamer_proc_info, NULL); + streamer_priv->next = dev_streamer; + dev_streamer = streamer_priv; +#endif +#endif + + rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (rc) { + printk(KERN_ERR "%s: No suitable PCI mapping available.\n", + dev->name); + rc = -ENODEV; + goto err_out; + } + + rc = pci_enable_device(pdev); + if (rc) { + printk(KERN_ERR "lanstreamer: unable to enable pci device\n"); + rc=-EIO; + goto err_out; + } + + pci_set_master(pdev); + + rc = pci_set_mwi(pdev); + if (rc) { + printk(KERN_ERR "lanstreamer: unable to enable MWI on pci device\n"); + goto err_out_disable; + } + + pio_start = pci_resource_start(pdev, 0); + pio_end = pci_resource_end(pdev, 0); + pio_flags = pci_resource_flags(pdev, 0); + pio_len = pci_resource_len(pdev, 0); + + mmio_start = pci_resource_start(pdev, 1); + mmio_end = pci_resource_end(pdev, 1); + mmio_flags = pci_resource_flags(pdev, 1); + mmio_len = pci_resource_len(pdev, 1); + +#if STREAMER_DEBUG + printk("lanstreamer: pio_start %x pio_end %x pio_len %x pio_flags %x\n", + pio_start, pio_end, pio_len, pio_flags); + printk("lanstreamer: mmio_start %x mmio_end %x mmio_len %x mmio_flags %x\n", + mmio_start, mmio_end, mmio_flags, mmio_len); +#endif + + if (!request_region(pio_start, pio_len, "lanstreamer")) { + printk(KERN_ERR "lanstreamer: unable to get pci io addr %lx\n", + pio_start); + rc= -EBUSY; + goto err_out_mwi; + } + + if (!request_mem_region(mmio_start, mmio_len, "lanstreamer")) { + printk(KERN_ERR "lanstreamer: unable to get pci mmio addr %lx\n", + mmio_start); + rc= -EBUSY; + goto err_out_free_pio; + } + + streamer_priv->streamer_mmio=ioremap(mmio_start, mmio_len); + if (streamer_priv->streamer_mmio == NULL) { + printk(KERN_ERR "lanstreamer: unable to remap MMIO %lx\n", + mmio_start); + rc= -EIO; + goto err_out_free_mmio; + } + + init_waitqueue_head(&streamer_priv->srb_wait); + init_waitqueue_head(&streamer_priv->trb_wait); + + dev->netdev_ops = &streamer_netdev_ops; + dev->irq = pdev->irq; + dev->base_addr=pio_start; + SET_NETDEV_DEV(dev, &pdev->dev); + + streamer_priv->streamer_card_name = (char *)pdev->resource[0].name; + streamer_priv->pci_dev = pdev; + + if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000)) + streamer_priv->pkt_buf_sz = PKT_BUF_SZ; + else + streamer_priv->pkt_buf_sz = pkt_buf_sz[card_no]; + + streamer_priv->streamer_ring_speed = ringspeed[card_no]; + streamer_priv->streamer_message_level = message_level[card_no]; + + pci_set_drvdata(pdev, dev); + + spin_lock_init(&streamer_priv->streamer_lock); + + pci_read_config_word (pdev, PCI_COMMAND, &pcr); + pcr |= PCI_COMMAND_SERR; + pci_write_config_word (pdev, PCI_COMMAND, pcr); + + printk("%s\n", version); + printk("%s: %s. I/O at %hx, MMIO at %p, using irq %d\n",dev->name, + streamer_priv->streamer_card_name, + (unsigned int) dev->base_addr, + streamer_priv->streamer_mmio, + dev->irq); + + if (streamer_reset(dev)) + goto err_out_unmap; + + rc = register_netdev(dev); + if (rc) + goto err_out_unmap; + return 0; + +err_out_unmap: + iounmap(streamer_priv->streamer_mmio); +err_out_free_mmio: + release_mem_region(mmio_start, mmio_len); +err_out_free_pio: + release_region(pio_start, pio_len); +err_out_mwi: + pci_clear_mwi(pdev); +err_out_disable: + pci_disable_device(pdev); +err_out: + free_netdev(dev); +#if STREAMER_DEBUG + printk("lanstreamer: Exit error %x\n",rc); +#endif + return rc; +} + +static void __devexit streamer_remove_one(struct pci_dev *pdev) +{ + struct net_device *dev=pci_get_drvdata(pdev); + struct streamer_private *streamer_priv; + +#if STREAMER_DEBUG + printk("lanstreamer::streamer_remove_one entry pdev %p\n",pdev); +#endif + + if (dev == NULL) { + printk(KERN_ERR "lanstreamer::streamer_remove_one, ERROR dev is NULL\n"); + return; + } + + streamer_priv=netdev_priv(dev); + if (streamer_priv == NULL) { + printk(KERN_ERR "lanstreamer::streamer_remove_one, ERROR dev->priv is NULL\n"); + return; + } + +#if STREAMER_NETWORK_MONITOR +#ifdef CONFIG_PROC_FS + { + struct streamer_private **p, **next; + + for (p = &dev_streamer; *p; p = next) { + next = &(*p)->next; + if (*p == streamer_priv) { + *p = *next; + break; + } + } + if (!dev_streamer) + remove_proc_entry("streamer_tr", init_net.proc_net); + } +#endif +#endif + + unregister_netdev(dev); + iounmap(streamer_priv->streamer_mmio); + release_mem_region(pci_resource_start(pdev, 1), pci_resource_len(pdev,1)); + release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev,0)); + pci_clear_mwi(pdev); + pci_disable_device(pdev); + free_netdev(dev); + pci_set_drvdata(pdev, NULL); +} + + +static int streamer_reset(struct net_device *dev) +{ + struct streamer_private *streamer_priv; + __u8 __iomem *streamer_mmio; + unsigned long t; + unsigned int uaa_addr; + struct sk_buff *skb = NULL; + __u16 misr; + + streamer_priv = netdev_priv(dev); + streamer_mmio = streamer_priv->streamer_mmio; + + writew(readw(streamer_mmio + BCTL) | BCTL_SOFTRESET, streamer_mmio + BCTL); + t = jiffies; + /* Hold soft reset bit for a while */ + ssleep(1); + + writew(readw(streamer_mmio + BCTL) & ~BCTL_SOFTRESET, + streamer_mmio + BCTL); + +#if STREAMER_DEBUG + printk("BCTL: %x\n", readw(streamer_mmio + BCTL)); + printk("GPR: %x\n", readw(streamer_mmio + GPR)); + printk("SISRMASK: %x\n", readw(streamer_mmio + SISR_MASK)); +#endif + writew(readw(streamer_mmio + BCTL) | (BCTL_RX_FIFO_8 | BCTL_TX_FIFO_8), streamer_mmio + BCTL ); + + if (streamer_priv->streamer_ring_speed == 0) { /* Autosense */ + writew(readw(streamer_mmio + GPR) | GPR_AUTOSENSE, + streamer_mmio + GPR); + if (streamer_priv->streamer_message_level) + printk(KERN_INFO "%s: Ringspeed autosense mode on\n", + dev->name); + } else if (streamer_priv->streamer_ring_speed == 16) { + if (streamer_priv->streamer_message_level) + printk(KERN_INFO "%s: Trying to open at 16 Mbps as requested\n", + dev->name); + writew(GPR_16MBPS, streamer_mmio + GPR); + } else if (streamer_priv->streamer_ring_speed == 4) { + if (streamer_priv->streamer_message_level) + printk(KERN_INFO "%s: Trying to open at 4 Mbps as requested\n", + dev->name); + writew(0, streamer_mmio + GPR); + } + + skb = dev_alloc_skb(streamer_priv->pkt_buf_sz); + if (!skb) { + printk(KERN_INFO "%s: skb allocation for diagnostics failed...proceeding\n", + dev->name); + } else { + struct streamer_rx_desc *rx_ring; + u8 *data; + + rx_ring=(struct streamer_rx_desc *)skb->data; + data=((u8 *)skb->data)+sizeof(struct streamer_rx_desc); + rx_ring->forward=0; + rx_ring->status=0; + rx_ring->buffer=cpu_to_le32(pci_map_single(streamer_priv->pci_dev, data, + 512, PCI_DMA_FROMDEVICE)); + rx_ring->framelen_buflen=512; + writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, rx_ring, 512, PCI_DMA_FROMDEVICE)), + streamer_mmio+RXBDA); + } + +#if STREAMER_DEBUG + printk("GPR = %x\n", readw(streamer_mmio + GPR)); +#endif + /* start solo init */ + writew(SISR_MI, streamer_mmio + SISR_MASK_SUM); + + while (!((readw(streamer_mmio + SISR)) & SISR_SRB_REPLY)) { + msleep_interruptible(100); + if (time_after(jiffies, t + 40 * HZ)) { + printk(KERN_ERR + "IBM PCI tokenring card not responding\n"); + release_region(dev->base_addr, STREAMER_IO_SPACE); + if (skb) + dev_kfree_skb(skb); + return -1; + } + } + writew(~SISR_SRB_REPLY, streamer_mmio + SISR_RUM); + misr = readw(streamer_mmio + MISR_RUM); + writew(~misr, streamer_mmio + MISR_RUM); + + if (skb) + dev_kfree_skb(skb); /* release skb used for diagnostics */ + +#if STREAMER_DEBUG + printk("LAPWWO: %x, LAPA: %x LAPE: %x\n", + readw(streamer_mmio + LAPWWO), readw(streamer_mmio + LAPA), + readw(streamer_mmio + LAPE)); +#endif + +#if STREAMER_DEBUG + { + int i; + writew(readw(streamer_mmio + LAPWWO), + streamer_mmio + LAPA); + printk("initialization response srb dump: "); + for (i = 0; i < 10; i++) + printk("%x:", + ntohs(readw(streamer_mmio + LAPDINC))); + printk("\n"); + } +#endif + + writew(readw(streamer_mmio + LAPWWO) + 6, streamer_mmio + LAPA); + if (readw(streamer_mmio + LAPD)) { + printk(KERN_INFO "tokenring card initialization failed. errorcode : %x\n", + ntohs(readw(streamer_mmio + LAPD))); + release_region(dev->base_addr, STREAMER_IO_SPACE); + return -1; + } + + writew(readw(streamer_mmio + LAPWWO) + 8, streamer_mmio + LAPA); + uaa_addr = ntohs(readw(streamer_mmio + LAPDINC)); + readw(streamer_mmio + LAPDINC); /* skip over Level.Addr field */ + streamer_priv->streamer_addr_table_addr = ntohs(readw(streamer_mmio + LAPDINC)); + streamer_priv->streamer_parms_addr = ntohs(readw(streamer_mmio + LAPDINC)); + +#if STREAMER_DEBUG + printk("UAA resides at %x\n", uaa_addr); +#endif + + /* setup uaa area for access with LAPD */ + { + int i; + __u16 addr; + writew(uaa_addr, streamer_mmio + LAPA); + for (i = 0; i < 6; i += 2) { + addr=ntohs(readw(streamer_mmio+LAPDINC)); + dev->dev_addr[i]= (addr >> 8) & 0xff; + dev->dev_addr[i+1]= addr & 0xff; + } +#if STREAMER_DEBUG + printk("Adapter address: %pM\n", dev->dev_addr); +#endif + } + return 0; +} + +static int streamer_open(struct net_device *dev) +{ + struct streamer_private *streamer_priv = netdev_priv(dev); + __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; + unsigned long flags; + char open_error[255]; + int i, open_finished = 1; + __u16 srb_word; + __u16 srb_open; + int rc; + + if (readw(streamer_mmio+BMCTL_SUM) & BMCTL_RX_ENABLED) { + rc=streamer_reset(dev); + } + + if (request_irq(dev->irq, streamer_interrupt, IRQF_SHARED, "lanstreamer", dev)) { + return -EAGAIN; + } +#if STREAMER_DEBUG + printk("BMCTL: %x\n", readw(streamer_mmio + BMCTL_SUM)); + printk("pending ints: %x\n", readw(streamer_mmio + SISR)); +#endif + + writew(SISR_MI | SISR_SRB_REPLY, streamer_mmio + SISR_MASK); /* more ints later, doesn't stop arb cmd interrupt */ + writew(LISR_LIE, streamer_mmio + LISR); /* more ints later */ + + /* adapter is closed, so SRB is pointed to by LAPWWO */ + writew(readw(streamer_mmio + LAPWWO), streamer_mmio + LAPA); + +#if STREAMER_DEBUG + printk("LAPWWO: %x, LAPA: %x\n", readw(streamer_mmio + LAPWWO), + readw(streamer_mmio + LAPA)); + printk("LAPE: %x\n", readw(streamer_mmio + LAPE)); + printk("SISR Mask = %04x\n", readw(streamer_mmio + SISR_MASK)); +#endif + do { + for (i = 0; i < SRB_COMMAND_SIZE; i += 2) { + writew(0, streamer_mmio + LAPDINC); + } + + writew(readw(streamer_mmio+LAPWWO),streamer_mmio+LAPA); + writew(htons(SRB_OPEN_ADAPTER<<8),streamer_mmio+LAPDINC) ; /* open */ + writew(htons(STREAMER_CLEAR_RET_CODE<<8),streamer_mmio+LAPDINC); + writew(STREAMER_CLEAR_RET_CODE, streamer_mmio + LAPDINC); + + writew(readw(streamer_mmio + LAPWWO) + 8, streamer_mmio + LAPA); +#if STREAMER_NETWORK_MONITOR + /* If Network Monitor, instruct card to copy MAC frames through the ARB */ + writew(htons(OPEN_ADAPTER_ENABLE_FDX | OPEN_ADAPTER_PASS_ADC_MAC | OPEN_ADAPTER_PASS_ATT_MAC | OPEN_ADAPTER_PASS_BEACON), streamer_mmio + LAPDINC); /* offset 8 word contains open options */ +#else + writew(htons(OPEN_ADAPTER_ENABLE_FDX), streamer_mmio + LAPDINC); /* Offset 8 word contains Open.Options */ +#endif + + if (streamer_priv->streamer_laa[0]) { + writew(readw(streamer_mmio + LAPWWO) + 12, streamer_mmio + LAPA); + writew(htons((streamer_priv->streamer_laa[0] << 8) | + streamer_priv->streamer_laa[1]),streamer_mmio+LAPDINC); + writew(htons((streamer_priv->streamer_laa[2] << 8) | + streamer_priv->streamer_laa[3]),streamer_mmio+LAPDINC); + writew(htons((streamer_priv->streamer_laa[4] << 8) | + streamer_priv->streamer_laa[5]),streamer_mmio+LAPDINC); + memcpy(dev->dev_addr, streamer_priv->streamer_laa, dev->addr_len); + } + + /* save off srb open offset */ + srb_open = readw(streamer_mmio + LAPWWO); +#if STREAMER_DEBUG + writew(readw(streamer_mmio + LAPWWO), + streamer_mmio + LAPA); + printk("srb open request:\n"); + for (i = 0; i < 16; i++) { + printk("%x:", ntohs(readw(streamer_mmio + LAPDINC))); + } + printk("\n"); +#endif + spin_lock_irqsave(&streamer_priv->streamer_lock, flags); + streamer_priv->srb_queued = 1; + + /* signal solo that SRB command has been issued */ + writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM); + spin_unlock_irqrestore(&streamer_priv->streamer_lock, flags); + + while (streamer_priv->srb_queued) { + interruptible_sleep_on_timeout(&streamer_priv->srb_wait, 5 * HZ); + if (signal_pending(current)) { + printk(KERN_WARNING "%s: SRB timed out.\n", dev->name); + printk(KERN_WARNING "SISR=%x MISR=%x, LISR=%x\n", + readw(streamer_mmio + SISR), + readw(streamer_mmio + MISR_RUM), + readw(streamer_mmio + LISR)); + streamer_priv->srb_queued = 0; + break; + } + } + +#if STREAMER_DEBUG + printk("SISR_MASK: %x\n", readw(streamer_mmio + SISR_MASK)); + printk("srb open response:\n"); + writew(srb_open, streamer_mmio + LAPA); + for (i = 0; i < 10; i++) { + printk("%x:", + ntohs(readw(streamer_mmio + LAPDINC))); + } +#endif + + /* If we get the same return response as we set, the interrupt wasn't raised and the open + * timed out. + */ + writew(srb_open + 2, streamer_mmio + LAPA); + srb_word = ntohs(readw(streamer_mmio + LAPD)) >> 8; + if (srb_word == STREAMER_CLEAR_RET_CODE) { + printk(KERN_WARNING "%s: Adapter Open time out or error.\n", + dev->name); + return -EIO; + } + + if (srb_word != 0) { + if (srb_word == 0x07) { + if (!streamer_priv->streamer_ring_speed && open_finished) { /* Autosense , first time around */ + printk(KERN_WARNING "%s: Retrying at different ring speed\n", + dev->name); + open_finished = 0; + } else { + __u16 error_code; + + writew(srb_open + 6, streamer_mmio + LAPA); + error_code = ntohs(readw(streamer_mmio + LAPD)); + strcpy(open_error, open_maj_error[(error_code & 0xf0) >> 4]); + strcat(open_error, " - "); + strcat(open_error, open_min_error[(error_code & 0x0f)]); + + if (!streamer_priv->streamer_ring_speed && + ((error_code & 0x0f) == 0x0d)) + { + printk(KERN_WARNING "%s: Tried to autosense ring speed with no monitors present\n", dev->name); + printk(KERN_WARNING "%s: Please try again with a specified ring speed\n", dev->name); + free_irq(dev->irq, dev); + return -EIO; + } + + printk(KERN_WARNING "%s: %s\n", + dev->name, open_error); + free_irq(dev->irq, dev); + return -EIO; + + } /* if autosense && open_finished */ + } else { + printk(KERN_WARNING "%s: Bad OPEN response: %x\n", + dev->name, srb_word); + free_irq(dev->irq, dev); + return -EIO; + } + } else + open_finished = 1; + } while (!(open_finished)); /* Will only loop if ring speed mismatch re-open attempted && autosense is on */ + + writew(srb_open + 18, streamer_mmio + LAPA); + srb_word=ntohs(readw(streamer_mmio+LAPD)) >> 8; + if (srb_word & (1 << 3)) + if (streamer_priv->streamer_message_level) + printk(KERN_INFO "%s: Opened in FDX Mode\n", dev->name); + + if (srb_word & 1) + streamer_priv->streamer_ring_speed = 16; + else + streamer_priv->streamer_ring_speed = 4; + + if (streamer_priv->streamer_message_level) + printk(KERN_INFO "%s: Opened in %d Mbps mode\n", + dev->name, + streamer_priv->streamer_ring_speed); + + writew(srb_open + 8, streamer_mmio + LAPA); + streamer_priv->asb = ntohs(readw(streamer_mmio + LAPDINC)); + streamer_priv->srb = ntohs(readw(streamer_mmio + LAPDINC)); + streamer_priv->arb = ntohs(readw(streamer_mmio + LAPDINC)); + readw(streamer_mmio + LAPDINC); /* offset 14 word is rsvd */ + streamer_priv->trb = ntohs(readw(streamer_mmio + LAPDINC)); + + streamer_priv->streamer_receive_options = 0x00; + streamer_priv->streamer_copy_all_options = 0; + + /* setup rx ring */ + /* enable rx channel */ + writew(~BMCTL_RX_DIS, streamer_mmio + BMCTL_RUM); + + /* setup rx descriptors */ + streamer_priv->streamer_rx_ring= + kmalloc( sizeof(struct streamer_rx_desc)* + STREAMER_RX_RING_SIZE,GFP_KERNEL); + if (!streamer_priv->streamer_rx_ring) { + printk(KERN_WARNING "%s ALLOC of streamer rx ring FAILED!!\n",dev->name); + return -EIO; + } + + for (i = 0; i < STREAMER_RX_RING_SIZE; i++) { + struct sk_buff *skb; + + skb = dev_alloc_skb(streamer_priv->pkt_buf_sz); + if (skb == NULL) + break; + + skb->dev = dev; + + streamer_priv->streamer_rx_ring[i].forward = + cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_rx_ring[i + 1], + sizeof(struct streamer_rx_desc), PCI_DMA_FROMDEVICE)); + streamer_priv->streamer_rx_ring[i].status = 0; + streamer_priv->streamer_rx_ring[i].buffer = + cpu_to_le32(pci_map_single(streamer_priv->pci_dev, skb->data, + streamer_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE)); + streamer_priv->streamer_rx_ring[i].framelen_buflen = streamer_priv->pkt_buf_sz; + streamer_priv->rx_ring_skb[i] = skb; + } + streamer_priv->streamer_rx_ring[STREAMER_RX_RING_SIZE - 1].forward = + cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_rx_ring[0], + sizeof(struct streamer_rx_desc), PCI_DMA_FROMDEVICE)); + + if (i == 0) { + printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled\n", dev->name); + free_irq(dev->irq, dev); + return -EIO; + } + + streamer_priv->rx_ring_last_received = STREAMER_RX_RING_SIZE - 1; /* last processed rx status */ + + writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_rx_ring[0], + sizeof(struct streamer_rx_desc), PCI_DMA_TODEVICE)), + streamer_mmio + RXBDA); + writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_rx_ring[STREAMER_RX_RING_SIZE - 1], + sizeof(struct streamer_rx_desc), PCI_DMA_TODEVICE)), + streamer_mmio + RXLBDA); + + /* set bus master interrupt event mask */ + writew(MISR_RX_NOBUF | MISR_RX_EOF, streamer_mmio + MISR_MASK); + + + /* setup tx ring */ + streamer_priv->streamer_tx_ring=kmalloc(sizeof(struct streamer_tx_desc)* + STREAMER_TX_RING_SIZE,GFP_KERNEL); + if (!streamer_priv->streamer_tx_ring) { + printk(KERN_WARNING "%s ALLOC of streamer_tx_ring FAILED\n",dev->name); + return -EIO; + } + + writew(~BMCTL_TX2_DIS, streamer_mmio + BMCTL_RUM); /* Enables TX channel 2 */ + for (i = 0; i < STREAMER_TX_RING_SIZE; i++) { + streamer_priv->streamer_tx_ring[i].forward = cpu_to_le32(pci_map_single(streamer_priv->pci_dev, + &streamer_priv->streamer_tx_ring[i + 1], + sizeof(struct streamer_tx_desc), + PCI_DMA_TODEVICE)); + streamer_priv->streamer_tx_ring[i].status = 0; + streamer_priv->streamer_tx_ring[i].bufcnt_framelen = 0; + streamer_priv->streamer_tx_ring[i].buffer = 0; + streamer_priv->streamer_tx_ring[i].buflen = 0; + streamer_priv->streamer_tx_ring[i].rsvd1 = 0; + streamer_priv->streamer_tx_ring[i].rsvd2 = 0; + streamer_priv->streamer_tx_ring[i].rsvd3 = 0; + } + streamer_priv->streamer_tx_ring[STREAMER_TX_RING_SIZE - 1].forward = + cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_tx_ring[0], + sizeof(struct streamer_tx_desc), PCI_DMA_TODEVICE)); + + streamer_priv->free_tx_ring_entries = STREAMER_TX_RING_SIZE; + streamer_priv->tx_ring_free = 0; /* next entry in tx ring to use */ + streamer_priv->tx_ring_last_status = STREAMER_TX_RING_SIZE - 1; + + /* set Busmaster interrupt event mask (handle receives on interrupt only */ + writew(MISR_TX2_EOF | MISR_RX_NOBUF | MISR_RX_EOF, streamer_mmio + MISR_MASK); + /* set system event interrupt mask */ + writew(SISR_ADAPTER_CHECK | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_ASB_FREE, streamer_mmio + SISR_MASK_SUM); + +#if STREAMER_DEBUG + printk("BMCTL: %x\n", readw(streamer_mmio + BMCTL_SUM)); + printk("SISR MASK: %x\n", readw(streamer_mmio + SISR_MASK)); +#endif + +#if STREAMER_NETWORK_MONITOR + + writew(streamer_priv->streamer_addr_table_addr, streamer_mmio + LAPA); + printk("%s: Node Address: %04x:%04x:%04x\n", dev->name, + ntohs(readw(streamer_mmio + LAPDINC)), + ntohs(readw(streamer_mmio + LAPDINC)), + ntohs(readw(streamer_mmio + LAPDINC))); + readw(streamer_mmio + LAPDINC); + readw(streamer_mmio + LAPDINC); + printk("%s: Functional Address: %04x:%04x\n", dev->name, + ntohs(readw(streamer_mmio + LAPDINC)), + ntohs(readw(streamer_mmio + LAPDINC))); + + writew(streamer_priv->streamer_parms_addr + 4, + streamer_mmio + LAPA); + printk("%s: NAUN Address: %04x:%04x:%04x\n", dev->name, + ntohs(readw(streamer_mmio + LAPDINC)), + ntohs(readw(streamer_mmio + LAPDINC)), + ntohs(readw(streamer_mmio + LAPDINC))); +#endif + + netif_start_queue(dev); + netif_carrier_on(dev); + return 0; +} + +/* + * When we enter the rx routine we do not know how many frames have been + * queued on the rx channel. Therefore we start at the next rx status + * position and travel around the receive ring until we have completed + * all the frames. + * + * This means that we may process the frame before we receive the end + * of frame interrupt. This is why we always test the status instead + * of blindly processing the next frame. + * + */ +static void streamer_rx(struct net_device *dev) +{ + struct streamer_private *streamer_priv = + netdev_priv(dev); + __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; + struct streamer_rx_desc *rx_desc; + int rx_ring_last_received, length, frame_length, buffer_cnt = 0; + struct sk_buff *skb, *skb2; + + /* setup the next rx descriptor to be received */ + rx_desc = &streamer_priv->streamer_rx_ring[(streamer_priv->rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1)]; + rx_ring_last_received = streamer_priv->rx_ring_last_received; + + while (rx_desc->status & 0x01000000) { /* While processed descriptors are available */ + if (rx_ring_last_received != streamer_priv->rx_ring_last_received) + { + printk(KERN_WARNING "RX Error 1 rx_ring_last_received not the same %x %x\n", + rx_ring_last_received, streamer_priv->rx_ring_last_received); + } + streamer_priv->rx_ring_last_received = (streamer_priv->rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1); + rx_ring_last_received = streamer_priv->rx_ring_last_received; + + length = rx_desc->framelen_buflen & 0xffff; /* buffer length */ + frame_length = (rx_desc->framelen_buflen >> 16) & 0xffff; + + if (rx_desc->status & 0x7E830000) { /* errors */ + if (streamer_priv->streamer_message_level) { + printk(KERN_WARNING "%s: Rx Error %x\n", + dev->name, rx_desc->status); + } + } else { /* received without errors */ + if (rx_desc->status & 0x80000000) { /* frame complete */ + buffer_cnt = 1; + skb = dev_alloc_skb(streamer_priv->pkt_buf_sz); + } else { + skb = dev_alloc_skb(frame_length); + } + + if (skb == NULL) + { + printk(KERN_WARNING "%s: Not enough memory to copy packet to upper layers.\n", dev->name); + dev->stats.rx_dropped++; + } else { /* we allocated an skb OK */ + if (buffer_cnt == 1) { + /* release the DMA mapping */ + pci_unmap_single(streamer_priv->pci_dev, + le32_to_cpu(streamer_priv->streamer_rx_ring[rx_ring_last_received].buffer), + streamer_priv->pkt_buf_sz, + PCI_DMA_FROMDEVICE); + skb2 = streamer_priv->rx_ring_skb[rx_ring_last_received]; +#if STREAMER_DEBUG_PACKETS + { + int i; + printk("streamer_rx packet print: skb->data2 %p skb->head %p\n", skb2->data, skb2->head); + for (i = 0; i < frame_length; i++) + { + printk("%x:", skb2->data[i]); + if (((i + 1) % 16) == 0) + printk("\n"); + } + printk("\n"); + } +#endif + skb_put(skb2, length); + skb2->protocol = tr_type_trans(skb2, dev); + /* recycle this descriptor */ + streamer_priv->streamer_rx_ring[rx_ring_last_received].status = 0; + streamer_priv->streamer_rx_ring[rx_ring_last_received].framelen_buflen = streamer_priv->pkt_buf_sz; + streamer_priv->streamer_rx_ring[rx_ring_last_received].buffer = + cpu_to_le32(pci_map_single(streamer_priv->pci_dev, skb->data, streamer_priv->pkt_buf_sz, + PCI_DMA_FROMDEVICE)); + streamer_priv->rx_ring_skb[rx_ring_last_received] = skb; + /* place recycled descriptor back on the adapter */ + writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, + &streamer_priv->streamer_rx_ring[rx_ring_last_received], + sizeof(struct streamer_rx_desc), PCI_DMA_FROMDEVICE)), + streamer_mmio + RXLBDA); + /* pass the received skb up to the protocol */ + netif_rx(skb2); + } else { + do { /* Walk the buffers */ + pci_unmap_single(streamer_priv->pci_dev, le32_to_cpu(rx_desc->buffer), length, PCI_DMA_FROMDEVICE), + memcpy(skb_put(skb, length), (void *)rx_desc->buffer, length); /* copy this fragment */ + streamer_priv->streamer_rx_ring[rx_ring_last_received].status = 0; + streamer_priv->streamer_rx_ring[rx_ring_last_received].framelen_buflen = streamer_priv->pkt_buf_sz; + + /* give descriptor back to the adapter */ + writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, + &streamer_priv->streamer_rx_ring[rx_ring_last_received], + length, PCI_DMA_FROMDEVICE)), + streamer_mmio + RXLBDA); + + if (rx_desc->status & 0x80000000) + break; /* this descriptor completes the frame */ + + /* else get the next pending descriptor */ + if (rx_ring_last_received!= streamer_priv->rx_ring_last_received) + { + printk("RX Error rx_ring_last_received not the same %x %x\n", + rx_ring_last_received, + streamer_priv->rx_ring_last_received); + } + rx_desc = &streamer_priv->streamer_rx_ring[(streamer_priv->rx_ring_last_received+1) & (STREAMER_RX_RING_SIZE-1)]; + + length = rx_desc->framelen_buflen & 0xffff; /* buffer length */ + streamer_priv->rx_ring_last_received = (streamer_priv->rx_ring_last_received+1) & (STREAMER_RX_RING_SIZE - 1); + rx_ring_last_received = streamer_priv->rx_ring_last_received; + } while (1); + + skb->protocol = tr_type_trans(skb, dev); + /* send up to the protocol */ + netif_rx(skb); + } + dev->stats.rx_packets++; + dev->stats.rx_bytes += length; + } /* if skb == null */ + } /* end received without errors */ + + /* try the next one */ + rx_desc = &streamer_priv->streamer_rx_ring[(rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1)]; + } /* end for all completed rx descriptors */ +} + +static irqreturn_t streamer_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = (struct net_device *) dev_id; + struct streamer_private *streamer_priv = + netdev_priv(dev); + __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; + __u16 sisr; + __u16 misr; + u8 max_intr = MAX_INTR; + + spin_lock(&streamer_priv->streamer_lock); + sisr = readw(streamer_mmio + SISR); + + while((sisr & (SISR_MI | SISR_SRB_REPLY | SISR_ADAPTER_CHECK | SISR_ASB_FREE | + SISR_ARB_CMD | SISR_TRB_REPLY | SISR_PAR_ERR | SISR_SERR_ERR)) && + (max_intr > 0)) { + + if(sisr & SISR_PAR_ERR) { + writew(~SISR_PAR_ERR, streamer_mmio + SISR_RUM); + (void)readw(streamer_mmio + SISR_RUM); + } + + else if(sisr & SISR_SERR_ERR) { + writew(~SISR_SERR_ERR, streamer_mmio + SISR_RUM); + (void)readw(streamer_mmio + SISR_RUM); + } + + else if(sisr & SISR_MI) { + misr = readw(streamer_mmio + MISR_RUM); + + if (misr & MISR_TX2_EOF) { + while(streamer_priv->streamer_tx_ring[(streamer_priv->tx_ring_last_status + 1) & (STREAMER_TX_RING_SIZE - 1)].status) { + streamer_priv->tx_ring_last_status = (streamer_priv->tx_ring_last_status + 1) & (STREAMER_TX_RING_SIZE - 1); + streamer_priv->free_tx_ring_entries++; + dev->stats.tx_bytes += streamer_priv->tx_ring_skb[streamer_priv->tx_ring_last_status]->len; + dev->stats.tx_packets++; + dev_kfree_skb_irq(streamer_priv->tx_ring_skb[streamer_priv->tx_ring_last_status]); + streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].buffer = 0xdeadbeef; + streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].status = 0; + streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].bufcnt_framelen = 0; + streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].buflen = 0; + streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].rsvd1 = 0; + streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].rsvd2 = 0; + streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].rsvd3 = 0; + } + netif_wake_queue(dev); + } + + if (misr & MISR_RX_EOF) { + streamer_rx(dev); + } + /* MISR_RX_EOF */ + + if (misr & MISR_RX_NOBUF) { + /* According to the documentation, we don't have to do anything, + * but trapping it keeps it out of /var/log/messages. + */ + } /* SISR_RX_NOBUF */ + + writew(~misr, streamer_mmio + MISR_RUM); + (void)readw(streamer_mmio + MISR_RUM); + } + + else if (sisr & SISR_SRB_REPLY) { + if (streamer_priv->srb_queued == 1) { + wake_up_interruptible(&streamer_priv->srb_wait); + } else if (streamer_priv->srb_queued == 2) { + streamer_srb_bh(dev); + } + streamer_priv->srb_queued = 0; + + writew(~SISR_SRB_REPLY, streamer_mmio + SISR_RUM); + (void)readw(streamer_mmio + SISR_RUM); + } + + else if (sisr & SISR_ADAPTER_CHECK) { + printk(KERN_WARNING "%s: Adapter Check Interrupt Raised, 8 bytes of information follow:\n", dev->name); + writel(readl(streamer_mmio + LAPWWO), streamer_mmio + LAPA); + printk(KERN_WARNING "%s: Words %x:%x:%x:%x:\n", + dev->name, readw(streamer_mmio + LAPDINC), + ntohs(readw(streamer_mmio + LAPDINC)), + ntohs(readw(streamer_mmio + LAPDINC)), + ntohs(readw(streamer_mmio + LAPDINC))); + netif_stop_queue(dev); + netif_carrier_off(dev); + printk(KERN_WARNING "%s: Adapter must be manually reset.\n", dev->name); + } + + /* SISR_ADAPTER_CHECK */ + else if (sisr & SISR_ASB_FREE) { + /* Wake up anything that is waiting for the asb response */ + if (streamer_priv->asb_queued) { + streamer_asb_bh(dev); + } + writew(~SISR_ASB_FREE, streamer_mmio + SISR_RUM); + (void)readw(streamer_mmio + SISR_RUM); + } + /* SISR_ASB_FREE */ + else if (sisr & SISR_ARB_CMD) { + streamer_arb_cmd(dev); + writew(~SISR_ARB_CMD, streamer_mmio + SISR_RUM); + (void)readw(streamer_mmio + SISR_RUM); + } + /* SISR_ARB_CMD */ + else if (sisr & SISR_TRB_REPLY) { + /* Wake up anything that is waiting for the trb response */ + if (streamer_priv->trb_queued) { + wake_up_interruptible(&streamer_priv-> + trb_wait); + } + streamer_priv->trb_queued = 0; + writew(~SISR_TRB_REPLY, streamer_mmio + SISR_RUM); + (void)readw(streamer_mmio + SISR_RUM); + } + /* SISR_TRB_REPLY */ + + sisr = readw(streamer_mmio + SISR); + max_intr--; + } /* while() */ + + spin_unlock(&streamer_priv->streamer_lock) ; + return IRQ_HANDLED; +} + +static netdev_tx_t streamer_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct streamer_private *streamer_priv = + netdev_priv(dev); + __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; + unsigned long flags ; + + spin_lock_irqsave(&streamer_priv->streamer_lock, flags); + + if (streamer_priv->free_tx_ring_entries) { + streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].status = 0; + streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].bufcnt_framelen = 0x00020000 | skb->len; + streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].buffer = + cpu_to_le32(pci_map_single(streamer_priv->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE)); + streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd1 = skb->len; + streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd2 = 0; + streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd3 = 0; + streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].buflen = skb->len; + + streamer_priv->tx_ring_skb[streamer_priv->tx_ring_free] = skb; + streamer_priv->free_tx_ring_entries--; +#if STREAMER_DEBUG_PACKETS + { + int i; + printk("streamer_xmit packet print:\n"); + for (i = 0; i < skb->len; i++) { + printk("%x:", skb->data[i]); + if (((i + 1) % 16) == 0) + printk("\n"); + } + printk("\n"); + } +#endif + + writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, + &streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free], + sizeof(struct streamer_tx_desc), PCI_DMA_TODEVICE)), + streamer_mmio + TX2LFDA); + (void)readl(streamer_mmio + TX2LFDA); + + streamer_priv->tx_ring_free = (streamer_priv->tx_ring_free + 1) & (STREAMER_TX_RING_SIZE - 1); + spin_unlock_irqrestore(&streamer_priv->streamer_lock,flags); + return NETDEV_TX_OK; + } else { + netif_stop_queue(dev); + spin_unlock_irqrestore(&streamer_priv->streamer_lock,flags); + return NETDEV_TX_BUSY; + } +} + + +static int streamer_close(struct net_device *dev) +{ + struct streamer_private *streamer_priv = + netdev_priv(dev); + __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; + unsigned long flags; + int i; + + netif_stop_queue(dev); + netif_carrier_off(dev); + writew(streamer_priv->srb, streamer_mmio + LAPA); + writew(htons(SRB_CLOSE_ADAPTER << 8),streamer_mmio+LAPDINC); + writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC); + + spin_lock_irqsave(&streamer_priv->streamer_lock, flags); + + streamer_priv->srb_queued = 1; + writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM); + + spin_unlock_irqrestore(&streamer_priv->streamer_lock, flags); + + while (streamer_priv->srb_queued) + { + interruptible_sleep_on_timeout(&streamer_priv->srb_wait, + jiffies + 60 * HZ); + if (signal_pending(current)) + { + printk(KERN_WARNING "%s: SRB timed out.\n", dev->name); + printk(KERN_WARNING "SISR=%x MISR=%x LISR=%x\n", + readw(streamer_mmio + SISR), + readw(streamer_mmio + MISR_RUM), + readw(streamer_mmio + LISR)); + streamer_priv->srb_queued = 0; + break; + } + } + + streamer_priv->rx_ring_last_received = (streamer_priv->rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1); + + for (i = 0; i < STREAMER_RX_RING_SIZE; i++) { + if (streamer_priv->rx_ring_skb[streamer_priv->rx_ring_last_received]) { + dev_kfree_skb(streamer_priv->rx_ring_skb[streamer_priv->rx_ring_last_received]); + } + streamer_priv->rx_ring_last_received = (streamer_priv->rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1); + } + + /* reset tx/rx fifo's and busmaster logic */ + + /* TBD. Add graceful way to reset the LLC channel without doing a soft reset. + writel(readl(streamer_mmio+BCTL)|(3<<13),streamer_mmio+BCTL); + udelay(1); + writel(readl(streamer_mmio+BCTL)&~(3<<13),streamer_mmio+BCTL); + */ + +#if STREAMER_DEBUG + writew(streamer_priv->srb, streamer_mmio + LAPA); + printk("srb): "); + for (i = 0; i < 2; i++) { + printk("%x ", ntohs(readw(streamer_mmio + LAPDINC))); + } + printk("\n"); +#endif + free_irq(dev->irq, dev); + return 0; +} + +static void streamer_set_rx_mode(struct net_device *dev) +{ + struct streamer_private *streamer_priv = + netdev_priv(dev); + __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; + __u8 options = 0; + struct netdev_hw_addr *ha; + unsigned char dev_mc_address[5]; + + writel(streamer_priv->srb, streamer_mmio + LAPA); + options = streamer_priv->streamer_copy_all_options; + + if (dev->flags & IFF_PROMISC) + options |= (3 << 5); /* All LLC and MAC frames, all through the main rx channel */ + else + options &= ~(3 << 5); + + /* Only issue the srb if there is a change in options */ + + if ((options ^ streamer_priv->streamer_copy_all_options)) + { + /* Now to issue the srb command to alter the copy.all.options */ + writew(htons(SRB_MODIFY_RECEIVE_OPTIONS << 8), streamer_mmio+LAPDINC); + writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC); + writew(htons((streamer_priv->streamer_receive_options << 8) | options),streamer_mmio+LAPDINC); + writew(htons(0x4a41),streamer_mmio+LAPDINC); + writew(htons(0x4d45),streamer_mmio+LAPDINC); + writew(htons(0x5320),streamer_mmio+LAPDINC); + writew(0x2020, streamer_mmio + LAPDINC); + + streamer_priv->srb_queued = 2; /* Can't sleep, use srb_bh */ + + writel(LISR_SRB_CMD, streamer_mmio + LISR_SUM); + + streamer_priv->streamer_copy_all_options = options; + return; + } + + /* Set the functional addresses we need for multicast */ + writel(streamer_priv->srb,streamer_mmio+LAPA); + dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ; + + netdev_for_each_mc_addr(ha, dev) { + dev_mc_address[0] |= ha->addr[2]; + dev_mc_address[1] |= ha->addr[3]; + dev_mc_address[2] |= ha->addr[4]; + dev_mc_address[3] |= ha->addr[5]; + } + + writew(htons(SRB_SET_FUNC_ADDRESS << 8),streamer_mmio+LAPDINC); + writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC); + writew(0,streamer_mmio+LAPDINC); + writew(htons( (dev_mc_address[0] << 8) | dev_mc_address[1]),streamer_mmio+LAPDINC); + writew(htons( (dev_mc_address[2] << 8) | dev_mc_address[3]),streamer_mmio+LAPDINC); + streamer_priv->srb_queued = 2 ; + writel(LISR_SRB_CMD,streamer_mmio+LISR_SUM); +} + +static void streamer_srb_bh(struct net_device *dev) +{ + struct streamer_private *streamer_priv = netdev_priv(dev); + __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; + __u16 srb_word; + + writew(streamer_priv->srb, streamer_mmio + LAPA); + srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; + + switch (srb_word) { + + /* SRB_MODIFY_RECEIVE_OPTIONS i.e. set_multicast_list options (promiscuous) + * At some point we should do something if we get an error, such as + * resetting the IFF_PROMISC flag in dev + */ + + case SRB_MODIFY_RECEIVE_OPTIONS: + srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; + + switch (srb_word) { + case 0x01: + printk(KERN_WARNING "%s: Unrecognized srb command\n", dev->name); + break; + case 0x04: + printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name); + break; + default: + if (streamer_priv->streamer_message_level) + printk(KERN_WARNING "%s: Receive Options Modified to %x,%x\n", + dev->name, + streamer_priv->streamer_copy_all_options, + streamer_priv->streamer_receive_options); + break; + } /* switch srb[2] */ + break; + + + /* SRB_SET_GROUP_ADDRESS - Multicast group setting + */ + case SRB_SET_GROUP_ADDRESS: + srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; + switch (srb_word) { + case 0x00: + break; + case 0x01: + printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name); + break; + case 0x04: + printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name); + break; + case 0x3c: + printk(KERN_WARNING "%s: Group/Functional address indicator bits not set correctly\n", dev->name); + break; + case 0x3e: /* If we ever implement individual multicast addresses, will need to deal with this */ + printk(KERN_WARNING "%s: Group address registers full\n", dev->name); + break; + case 0x55: + printk(KERN_INFO "%s: Group Address already set.\n", dev->name); + break; + default: + break; + } /* switch srb[2] */ + break; + + + /* SRB_RESET_GROUP_ADDRESS - Remove a multicast address from group list + */ + case SRB_RESET_GROUP_ADDRESS: + srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; + switch (srb_word) { + case 0x00: + break; + case 0x01: + printk(KERN_WARNING "%s: Unrecognized srb command\n", dev->name); + break; + case 0x04: + printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name); + break; + case 0x39: /* Must deal with this if individual multicast addresses used */ + printk(KERN_INFO "%s: Group address not found\n", dev->name); + break; + default: + break; + } /* switch srb[2] */ + break; + + + /* SRB_SET_FUNC_ADDRESS - Called by the set_rx_mode + */ + + case SRB_SET_FUNC_ADDRESS: + srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; + switch (srb_word) { + case 0x00: + if (streamer_priv->streamer_message_level) + printk(KERN_INFO "%s: Functional Address Mask Set\n", dev->name); + break; + case 0x01: + printk(KERN_WARNING "%s: Unrecognized srb command\n", dev->name); + break; + case 0x04: + printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name); + break; + default: + break; + } /* switch srb[2] */ + break; + + /* SRB_READ_LOG - Read and reset the adapter error counters + */ + + case SRB_READ_LOG: + srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; + switch (srb_word) { + case 0x00: + { + int i; + if (streamer_priv->streamer_message_level) + printk(KERN_INFO "%s: Read Log command complete\n", dev->name); + printk("Read Log statistics: "); + writew(streamer_priv->srb + 6, + streamer_mmio + LAPA); + for (i = 0; i < 5; i++) { + printk("%x:", ntohs(readw(streamer_mmio + LAPDINC))); + } + printk("\n"); + } + break; + case 0x01: + printk(KERN_WARNING "%s: Unrecognized srb command\n", dev->name); + break; + case 0x04: + printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name); + break; + + } /* switch srb[2] */ + break; + + /* SRB_READ_SR_COUNTERS - Read and reset the source routing bridge related counters */ + + case SRB_READ_SR_COUNTERS: + srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; + switch (srb_word) { + case 0x00: + if (streamer_priv->streamer_message_level) + printk(KERN_INFO "%s: Read Source Routing Counters issued\n", dev->name); + break; + case 0x01: + printk(KERN_WARNING "%s: Unrecognized srb command\n", dev->name); + break; + case 0x04: + printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name); + break; + default: + break; + } /* switch srb[2] */ + break; + + default: + printk(KERN_WARNING "%s: Unrecognized srb bh return value.\n", dev->name); + break; + } /* switch srb[0] */ +} + +static int streamer_set_mac_address(struct net_device *dev, void *addr) +{ + struct sockaddr *saddr = addr; + struct streamer_private *streamer_priv = netdev_priv(dev); + + if (netif_running(dev)) + { + printk(KERN_WARNING "%s: Cannot set mac/laa address while card is open\n", dev->name); + return -EIO; + } + + memcpy(streamer_priv->streamer_laa, saddr->sa_data, dev->addr_len); + + if (streamer_priv->streamer_message_level) { + printk(KERN_INFO "%s: MAC/LAA Set to = %x.%x.%x.%x.%x.%x\n", + dev->name, streamer_priv->streamer_laa[0], + streamer_priv->streamer_laa[1], + streamer_priv->streamer_laa[2], + streamer_priv->streamer_laa[3], + streamer_priv->streamer_laa[4], + streamer_priv->streamer_laa[5]); + } + return 0; +} + +static void streamer_arb_cmd(struct net_device *dev) +{ + struct streamer_private *streamer_priv = + netdev_priv(dev); + __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; + __u8 header_len; + __u16 frame_len, buffer_len; + struct sk_buff *mac_frame; + __u8 frame_data[256]; + __u16 buff_off; + __u16 lan_status = 0, lan_status_diff; /* Initialize to stop compiler warning */ + __u8 fdx_prot_error; + __u16 next_ptr; + __u16 arb_word; + +#if STREAMER_NETWORK_MONITOR + struct trh_hdr *mac_hdr; +#endif + + writew(streamer_priv->arb, streamer_mmio + LAPA); + arb_word=ntohs(readw(streamer_mmio+LAPD)) >> 8; + + if (arb_word == ARB_RECEIVE_DATA) { /* Receive.data, MAC frames */ + writew(streamer_priv->arb + 6, streamer_mmio + LAPA); + streamer_priv->mac_rx_buffer = buff_off = ntohs(readw(streamer_mmio + LAPDINC)); + header_len=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; /* 802.5 Token-Ring Header Length */ + frame_len = ntohs(readw(streamer_mmio + LAPDINC)); + +#if STREAMER_DEBUG + { + int i; + __u16 next; + __u8 status; + __u16 len; + + writew(ntohs(buff_off), streamer_mmio + LAPA); /*setup window to frame data */ + next = htons(readw(streamer_mmio + LAPDINC)); + status = + ntohs(readw(streamer_mmio + LAPDINC)) & 0xff; + len = ntohs(readw(streamer_mmio + LAPDINC)); + + /* print out 1st 14 bytes of frame data */ + for (i = 0; i < 7; i++) { + printk("Loc %d = %04x\n", i, + ntohs(readw + (streamer_mmio + LAPDINC))); + } + + printk("next %04x, fs %02x, len %04x\n", next, + status, len); + } +#endif + if (!(mac_frame = dev_alloc_skb(frame_len))) { + printk(KERN_WARNING "%s: Memory squeeze, dropping frame.\n", + dev->name); + goto drop_frame; + } + /* Walk the buffer chain, creating the frame */ + + do { + int i; + __u16 rx_word; + + writew(htons(buff_off), streamer_mmio + LAPA); /* setup window to frame data */ + next_ptr = ntohs(readw(streamer_mmio + LAPDINC)); + readw(streamer_mmio + LAPDINC); /* read thru status word */ + buffer_len = ntohs(readw(streamer_mmio + LAPDINC)); + + if (buffer_len > 256) + break; + + i = 0; + while (i < buffer_len) { + rx_word=ntohs(readw(streamer_mmio+LAPDINC)); + frame_data[i]=rx_word >> 8; + frame_data[i+1]=rx_word & 0xff; + i += 2; + } + + memcpy(skb_put(mac_frame, buffer_len), + frame_data, buffer_len); + } while (next_ptr && (buff_off = next_ptr)); + + mac_frame->protocol = tr_type_trans(mac_frame, dev); +#if STREAMER_NETWORK_MONITOR + printk(KERN_WARNING "%s: Received MAC Frame, details:\n", + dev->name); + mac_hdr = tr_hdr(mac_frame); + printk(KERN_WARNING + "%s: MAC Frame Dest. Addr: %pM\n", + dev->name, mac_hdr->daddr); + printk(KERN_WARNING + "%s: MAC Frame Srce. Addr: %pM\n", + dev->name, mac_hdr->saddr); +#endif + netif_rx(mac_frame); + + /* Now tell the card we have dealt with the received frame */ +drop_frame: + /* Set LISR Bit 1 */ + writel(LISR_ARB_FREE, streamer_priv->streamer_mmio + LISR_SUM); + + /* Is the ASB free ? */ + + if (!(readl(streamer_priv->streamer_mmio + SISR) & SISR_ASB_FREE)) + { + streamer_priv->asb_queued = 1; + writel(LISR_ASB_FREE_REQ, streamer_priv->streamer_mmio + LISR_SUM); + return; + /* Drop out and wait for the bottom half to be run */ + } + + + writew(streamer_priv->asb, streamer_mmio + LAPA); + writew(htons(ASB_RECEIVE_DATA << 8), streamer_mmio+LAPDINC); + writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC); + writew(0, streamer_mmio + LAPDINC); + writew(htons(streamer_priv->mac_rx_buffer), streamer_mmio + LAPD); + + writel(LISR_ASB_REPLY | LISR_ASB_FREE_REQ, streamer_priv->streamer_mmio + LISR_SUM); + + streamer_priv->asb_queued = 2; + return; + + } else if (arb_word == ARB_LAN_CHANGE_STATUS) { /* Lan.change.status */ + writew(streamer_priv->arb + 6, streamer_mmio + LAPA); + lan_status = ntohs(readw(streamer_mmio + LAPDINC)); + fdx_prot_error = ntohs(readw(streamer_mmio+LAPD)) >> 8; + + /* Issue ARB Free */ + writew(LISR_ARB_FREE, streamer_priv->streamer_mmio + LISR_SUM); + + lan_status_diff = (streamer_priv->streamer_lan_status ^ lan_status) & + lan_status; + + if (lan_status_diff & (LSC_LWF | LSC_ARW | LSC_FPE | LSC_RR)) + { + if (lan_status_diff & LSC_LWF) + printk(KERN_WARNING "%s: Short circuit detected on the lobe\n", dev->name); + if (lan_status_diff & LSC_ARW) + printk(KERN_WARNING "%s: Auto removal error\n", dev->name); + if (lan_status_diff & LSC_FPE) + printk(KERN_WARNING "%s: FDX Protocol Error\n", dev->name); + if (lan_status_diff & LSC_RR) + printk(KERN_WARNING "%s: Force remove MAC frame received\n", dev->name); + + /* Adapter has been closed by the hardware */ + + /* reset tx/rx fifo's and busmaster logic */ + + /* @TBD. no llc reset on autostreamer writel(readl(streamer_mmio+BCTL)|(3<<13),streamer_mmio+BCTL); + udelay(1); + writel(readl(streamer_mmio+BCTL)&~(3<<13),streamer_mmio+BCTL); */ + + netif_stop_queue(dev); + netif_carrier_off(dev); + printk(KERN_WARNING "%s: Adapter must be manually reset.\n", dev->name); + } + /* If serious error */ + if (streamer_priv->streamer_message_level) { + if (lan_status_diff & LSC_SIG_LOSS) + printk(KERN_WARNING "%s: No receive signal detected\n", dev->name); + if (lan_status_diff & LSC_HARD_ERR) + printk(KERN_INFO "%s: Beaconing\n", dev->name); + if (lan_status_diff & LSC_SOFT_ERR) + printk(KERN_WARNING "%s: Adapter transmitted Soft Error Report Mac Frame\n", dev->name); + if (lan_status_diff & LSC_TRAN_BCN) + printk(KERN_INFO "%s: We are transmitting the beacon, aaah\n", dev->name); + if (lan_status_diff & LSC_SS) + printk(KERN_INFO "%s: Single Station on the ring\n", dev->name); + if (lan_status_diff & LSC_RING_REC) + printk(KERN_INFO "%s: Ring recovery ongoing\n", dev->name); + if (lan_status_diff & LSC_FDX_MODE) + printk(KERN_INFO "%s: Operating in FDX mode\n", dev->name); + } + + if (lan_status_diff & LSC_CO) { + if (streamer_priv->streamer_message_level) + printk(KERN_INFO "%s: Counter Overflow\n", dev->name); + + /* Issue READ.LOG command */ + + writew(streamer_priv->srb, streamer_mmio + LAPA); + writew(htons(SRB_READ_LOG << 8),streamer_mmio+LAPDINC); + writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC); + writew(0, streamer_mmio + LAPDINC); + streamer_priv->srb_queued = 2; /* Can't sleep, use srb_bh */ + + writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM); + } + + if (lan_status_diff & LSC_SR_CO) { + if (streamer_priv->streamer_message_level) + printk(KERN_INFO "%s: Source routing counters overflow\n", dev->name); + + /* Issue a READ.SR.COUNTERS */ + writew(streamer_priv->srb, streamer_mmio + LAPA); + writew(htons(SRB_READ_SR_COUNTERS << 8), + streamer_mmio+LAPDINC); + writew(htons(STREAMER_CLEAR_RET_CODE << 8), + streamer_mmio+LAPDINC); + streamer_priv->srb_queued = 2; /* Can't sleep, use srb_bh */ + writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM); + + } + streamer_priv->streamer_lan_status = lan_status; + } /* Lan.change.status */ + else + printk(KERN_WARNING "%s: Unknown arb command\n", dev->name); +} + +static void streamer_asb_bh(struct net_device *dev) +{ + struct streamer_private *streamer_priv = + netdev_priv(dev); + __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; + + if (streamer_priv->asb_queued == 1) + { + /* Dropped through the first time */ + + writew(streamer_priv->asb, streamer_mmio + LAPA); + writew(htons(ASB_RECEIVE_DATA << 8),streamer_mmio+LAPDINC); + writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC); + writew(0, streamer_mmio + LAPDINC); + writew(htons(streamer_priv->mac_rx_buffer), streamer_mmio + LAPD); + + writel(LISR_ASB_REPLY | LISR_ASB_FREE_REQ, streamer_priv->streamer_mmio + LISR_SUM); + streamer_priv->asb_queued = 2; + + return; + } + + if (streamer_priv->asb_queued == 2) { + __u8 rc; + writew(streamer_priv->asb + 2, streamer_mmio + LAPA); + rc=ntohs(readw(streamer_mmio+LAPD)) >> 8; + switch (rc) { + case 0x01: + printk(KERN_WARNING "%s: Unrecognized command code\n", dev->name); + break; + case 0x26: + printk(KERN_WARNING "%s: Unrecognized buffer address\n", dev->name); + break; + case 0xFF: + /* Valid response, everything should be ok again */ + break; + default: + printk(KERN_WARNING "%s: Invalid return code in asb\n", dev->name); + break; + } + } + streamer_priv->asb_queued = 0; +} + +static int streamer_change_mtu(struct net_device *dev, int mtu) +{ + struct streamer_private *streamer_priv = + netdev_priv(dev); + __u16 max_mtu; + + if (streamer_priv->streamer_ring_speed == 4) + max_mtu = 4500; + else + max_mtu = 18000; + + if (mtu > max_mtu) + return -EINVAL; + if (mtu < 100) + return -EINVAL; + + dev->mtu = mtu; + streamer_priv->pkt_buf_sz = mtu + TR_HLEN; + + return 0; +} + +#if STREAMER_NETWORK_MONITOR +#ifdef CONFIG_PROC_FS +static int streamer_proc_info(char *buffer, char **start, off_t offset, + int length, int *eof, void *data) +{ + struct streamer_private *sdev=NULL; + struct pci_dev *pci_device = NULL; + int len = 0; + off_t begin = 0; + off_t pos = 0; + int size; + + struct net_device *dev; + + size = sprintf(buffer, "IBM LanStreamer/MPC Chipset Token Ring Adapters\n"); + + pos += size; + len += size; + + for(sdev=dev_streamer; sdev; sdev=sdev->next) { + pci_device=sdev->pci_dev; + dev=pci_get_drvdata(pci_device); + + size = sprintf_info(buffer + len, dev); + len += size; + pos = begin + len; + + if (pos < offset) { + len = 0; + begin = pos; + } + if (pos > offset + length) + break; + } /* for */ + + *start = buffer + (offset - begin); /* Start of wanted data */ + len -= (offset - begin); /* Start slop */ + if (len > length) + len = length; /* Ending slop */ + return len; +} + +static int sprintf_info(char *buffer, struct net_device *dev) +{ + struct streamer_private *streamer_priv = + netdev_priv(dev); + __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; + struct streamer_adapter_addr_table sat; + struct streamer_parameters_table spt; + int size = 0; + int i; + + writew(streamer_priv->streamer_addr_table_addr, streamer_mmio + LAPA); + for (i = 0; i < 14; i += 2) { + __u16 io_word; + __u8 *datap = (__u8 *) & sat; + io_word=ntohs(readw(streamer_mmio+LAPDINC)); + datap[size]=io_word >> 8; + datap[size+1]=io_word & 0xff; + } + writew(streamer_priv->streamer_parms_addr, streamer_mmio + LAPA); + for (i = 0; i < 68; i += 2) { + __u16 io_word; + __u8 *datap = (__u8 *) & spt; + io_word=ntohs(readw(streamer_mmio+LAPDINC)); + datap[size]=io_word >> 8; + datap[size+1]=io_word & 0xff; + } + + size = sprintf(buffer, "\n%6s: Adapter Address : Node Address : Functional Addr\n", dev->name); + + size += sprintf(buffer + size, + "%6s: %pM : %pM : %02x:%02x:%02x:%02x\n", + dev->name, dev->dev_addr, sat.node_addr, + sat.func_addr[0], sat.func_addr[1], + sat.func_addr[2], sat.func_addr[3]); + + size += sprintf(buffer + size, "\n%6s: Token Ring Parameters Table:\n", dev->name); + + size += sprintf(buffer + size, "%6s: Physical Addr : Up Node Address : Poll Address : AccPri : Auth Src : Att Code :\n", dev->name); + + size += sprintf(buffer + size, + "%6s: %02x:%02x:%02x:%02x : %pM : %pM : %04x : %04x : %04x :\n", + dev->name, spt.phys_addr[0], spt.phys_addr[1], + spt.phys_addr[2], spt.phys_addr[3], + spt.up_node_addr, spt.poll_addr, + ntohs(spt.acc_priority), ntohs(spt.auth_source_class), + ntohs(spt.att_code)); + + size += sprintf(buffer + size, "%6s: Source Address : Bcn T : Maj. V : Lan St : Lcl Rg : Mon Err : Frame Correl : \n", dev->name); + + size += sprintf(buffer + size, + "%6s: %pM : %04x : %04x : %04x : %04x : %04x : %04x : \n", + dev->name, spt.source_addr, + ntohs(spt.beacon_type), ntohs(spt.major_vector), + ntohs(spt.lan_status), ntohs(spt.local_ring), + ntohs(spt.mon_error), ntohs(spt.frame_correl)); + + size += sprintf(buffer + size, "%6s: Beacon Details : Tx : Rx : NAUN Node Address : NAUN Node Phys : \n", + dev->name); + + size += sprintf(buffer + size, + "%6s: : %02x : %02x : %pM : %02x:%02x:%02x:%02x : \n", + dev->name, ntohs(spt.beacon_transmit), + ntohs(spt.beacon_receive), + spt.beacon_naun, + spt.beacon_phys[0], spt.beacon_phys[1], + spt.beacon_phys[2], spt.beacon_phys[3]); + return size; +} +#endif +#endif + +static struct pci_driver streamer_pci_driver = { + .name = "lanstreamer", + .id_table = streamer_pci_tbl, + .probe = streamer_init_one, + .remove = __devexit_p(streamer_remove_one), +}; + +module_pci_driver(streamer_pci_driver); + +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/net/tokenring/lanstreamer.h b/trunk/drivers/net/tokenring/lanstreamer.h new file mode 100644 index 000000000000..3c58d6a3fbc9 --- /dev/null +++ b/trunk/drivers/net/tokenring/lanstreamer.h @@ -0,0 +1,343 @@ +/* + * lanstreamer.h -- driver for the IBM Auto LANStreamer PCI Adapter + * + * Written By: Mike Sullivan, IBM Corporation + * + * Copyright (C) 1999 IBM Corporation + * + * Linux driver for IBM PCI tokenring cards based on the LanStreamer MPC + * chipset. + * + * This driver is based on the olympic driver for IBM PCI TokenRing cards (Pit/Pit-Phy/Olympic + * chipsets) written by: + * 1999 Peter De Schrijver All Rights Reserved + * 1999 Mike Phillips (phillim@amtrak.com) + * + * Base Driver Skeleton: + * Written 1993-94 by Donald Becker. + * + * Copyright 1993 United States Government as represented by the + * Director, National Security Agency. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * NO WARRANTY + * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT + * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is + * solely responsible for determining the appropriateness of using and + * distributing the Program and assumes all risks associated with its + * exercise of rights under this Agreement, including but not limited to + * the risks and costs of program errors, damage to or loss of data, + * programs or equipment, and unavailability or interruption of operations. + * + * DISCLAIMER OF LIABILITY + * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED + * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * 12/10/99 - Alpha Release 0.1.0 + * First release to the public + * 08/15/01 - Added ioctl() definitions and others - Kent Yoder + * + */ + +/* MAX_INTR - the maximum number of times we can loop + * inside the interrupt function before returning + * control to the OS (maximum value is 256) + */ +#define MAX_INTR 5 + +#define CLS 0x0C +#define MLR 0x86 +#define LTR 0x0D + +#define BCTL 0x60 +#define BCTL_SOFTRESET (1<<15) +#define BCTL_RX_FIFO_8 (1<<1) +#define BCTL_TX_FIFO_8 (1<<3) + +#define GPR 0x4a +#define GPR_AUTOSENSE (1<<2) +#define GPR_16MBPS (1<<3) + +#define LISR 0x10 +#define LISR_SUM 0x12 +#define LISR_RUM 0x14 + +#define LISR_LIE (1<<15) +#define LISR_SLIM (1<<13) +#define LISR_SLI (1<<12) +#define LISR_BPEI (1<<9) +#define LISR_BPE (1<<8) +#define LISR_SRB_CMD (1<<5) +#define LISR_ASB_REPLY (1<<4) +#define LISR_ASB_FREE_REQ (1<<2) +#define LISR_ARB_FREE (1<<1) +#define LISR_TRB_FRAME (1<<0) + +#define SISR 0x16 +#define SISR_SUM 0x18 +#define SISR_RUM 0x1A +#define SISR_MASK 0x54 +#define SISR_MASK_SUM 0x56 +#define SISR_MASK_RUM 0x58 + +#define SISR_MI (1<<15) +#define SISR_SERR_ERR (1<<14) +#define SISR_TIMER (1<<11) +#define SISR_LAP_PAR_ERR (1<<10) +#define SISR_LAP_ACC_ERR (1<<9) +#define SISR_PAR_ERR (1<<8) +#define SISR_ADAPTER_CHECK (1<<6) +#define SISR_SRB_REPLY (1<<5) +#define SISR_ASB_FREE (1<<4) +#define SISR_ARB_CMD (1<<3) +#define SISR_TRB_REPLY (1<<2) + +#define MISR_RUM 0x5A +#define MISR_MASK 0x5C +#define MISR_MASK_RUM 0x5E + +#define MISR_TX2_IDLE (1<<15) +#define MISR_TX2_NO_STATUS (1<<14) +#define MISR_TX2_HALT (1<<13) +#define MISR_TX2_EOF (1<<12) +#define MISR_TX1_IDLE (1<<11) +#define MISR_TX1_NO_STATUS (1<<10) +#define MISR_TX1_HALT (1<<9) +#define MISR_TX1_EOF (1<<8) +#define MISR_RX_NOBUF (1<<5) +#define MISR_RX_EOB (1<<4) +#define MISR_RX_NO_STATUS (1<<2) +#define MISR_RX_HALT (1<<1) +#define MISR_RX_EOF (1<<0) + +#define LAPA 0x62 +#define LAPE 0x64 +#define LAPD 0x66 +#define LAPDINC 0x68 +#define LAPWWO 0x6A +#define LAPWWC 0x6C +#define LAPCTL 0x6E + +#define TIMER 0x4E4 + +#define BMCTL_SUM 0x50 +#define BMCTL_RUM 0x52 +#define BMCTL_TX1_DIS (1<<14) +#define BMCTL_TX2_DIS (1<<10) +#define BMCTL_RX_DIS (1<<6) +#define BMCTL_RX_ENABLED (1<<5) + +#define RXLBDA 0x90 +#define RXBDA 0x94 +#define RXSTAT 0x98 +#define RXDBA 0x9C + +#define TX1LFDA 0xA0 +#define TX1FDA 0xA4 +#define TX1STAT 0xA8 +#define TX1DBA 0xAC +#define TX2LFDA 0xB0 +#define TX2FDA 0xB4 +#define TX2STAT 0xB8 +#define TX2DBA 0xBC + +#define STREAMER_IO_SPACE 256 + +#define SRB_COMMAND_SIZE 50 + +#define STREAMER_MAX_ADAPTERS 8 /* 0x08 __MODULE_STRING can't hand 0xnn */ + +/* Defines for LAN STATUS CHANGE reports */ +#define LSC_SIG_LOSS 0x8000 +#define LSC_HARD_ERR 0x4000 +#define LSC_SOFT_ERR 0x2000 +#define LSC_TRAN_BCN 0x1000 +#define LSC_LWF 0x0800 +#define LSC_ARW 0x0400 +#define LSC_FPE 0x0200 +#define LSC_RR 0x0100 +#define LSC_CO 0x0080 +#define LSC_SS 0x0040 +#define LSC_RING_REC 0x0020 +#define LSC_SR_CO 0x0010 +#define LSC_FDX_MODE 0x0004 + +/* Defines for OPEN ADAPTER command */ + +#define OPEN_ADAPTER_EXT_WRAP (1<<15) +#define OPEN_ADAPTER_DIS_HARDEE (1<<14) +#define OPEN_ADAPTER_DIS_SOFTERR (1<<13) +#define OPEN_ADAPTER_PASS_ADC_MAC (1<<12) +#define OPEN_ADAPTER_PASS_ATT_MAC (1<<11) +#define OPEN_ADAPTER_ENABLE_EC (1<<10) +#define OPEN_ADAPTER_CONTENDER (1<<8) +#define OPEN_ADAPTER_PASS_BEACON (1<<7) +#define OPEN_ADAPTER_ENABLE_FDX (1<<6) +#define OPEN_ADAPTER_ENABLE_RPL (1<<5) +#define OPEN_ADAPTER_INHIBIT_ETR (1<<4) +#define OPEN_ADAPTER_INTERNAL_WRAP (1<<3) + + +/* Defines for SRB Commands */ +#define SRB_CLOSE_ADAPTER 0x04 +#define SRB_CONFIGURE_BRIDGE 0x0c +#define SRB_CONFIGURE_HP_CHANNEL 0x13 +#define SRB_MODIFY_BRIDGE_PARMS 0x15 +#define SRB_MODIFY_OPEN_OPTIONS 0x01 +#define SRB_MODIFY_RECEIVE_OPTIONS 0x17 +#define SRB_NO_OPERATION 0x00 +#define SRB_OPEN_ADAPTER 0x03 +#define SRB_READ_LOG 0x08 +#define SRB_READ_SR_COUNTERS 0x16 +#define SRB_RESET_GROUP_ADDRESS 0x02 +#define SRB_RESET_TARGET_SEGMETN 0x14 +#define SRB_SAVE_CONFIGURATION 0x1b +#define SRB_SET_BRIDGE_PARMS 0x09 +#define SRB_SET_FUNC_ADDRESS 0x07 +#define SRB_SET_GROUP_ADDRESS 0x06 +#define SRB_SET_TARGET_SEGMENT 0x05 + +/* Clear return code */ +#define STREAMER_CLEAR_RET_CODE 0xfe + +/* ARB Commands */ +#define ARB_RECEIVE_DATA 0x81 +#define ARB_LAN_CHANGE_STATUS 0x84 + +/* ASB Response commands */ +#define ASB_RECEIVE_DATA 0x81 + + +/* Streamer defaults for buffers */ + +#define STREAMER_RX_RING_SIZE 16 /* should be a power of 2 */ +/* Setting the number of TX descriptors to 1 is a workaround for an + * undocumented hardware problem with the lanstreamer board. Setting + * this to something higher may slightly increase the throughput you + * can get from the card, but at the risk of locking up the box. - + * + */ +#define STREAMER_TX_RING_SIZE 1 /* should be a power of 2 */ + +#define PKT_BUF_SZ 4096 /* Default packet size */ + +/* Streamer data structures */ + +struct streamer_tx_desc { + __u32 forward; + __u32 status; + __u32 bufcnt_framelen; + __u32 buffer; + __u32 buflen; + __u32 rsvd1; + __u32 rsvd2; + __u32 rsvd3; +}; + +struct streamer_rx_desc { + __u32 forward; + __u32 status; + __u32 buffer; + __u32 framelen_buflen; +}; + +struct mac_receive_buffer { + __u16 next; + __u8 padding; + __u8 frame_status; + __u16 buffer_length; + __u8 frame_data; +}; + +struct streamer_private { + + __u16 srb; + __u16 trb; + __u16 arb; + __u16 asb; + + struct streamer_private *next; + struct pci_dev *pci_dev; + __u8 __iomem *streamer_mmio; + char *streamer_card_name; + + spinlock_t streamer_lock; + + volatile int srb_queued; /* True if an SRB is still posted */ + wait_queue_head_t srb_wait; + + volatile int asb_queued; /* True if an ASB is posted */ + + volatile int trb_queued; /* True if a TRB is posted */ + wait_queue_head_t trb_wait; + + struct streamer_rx_desc *streamer_rx_ring; + struct streamer_tx_desc *streamer_tx_ring; + struct sk_buff *tx_ring_skb[STREAMER_TX_RING_SIZE], + *rx_ring_skb[STREAMER_RX_RING_SIZE]; + int tx_ring_free, tx_ring_last_status, rx_ring_last_received, + free_tx_ring_entries; + + __u16 streamer_lan_status; + __u8 streamer_ring_speed; + __u16 pkt_buf_sz; + __u8 streamer_receive_options, streamer_copy_all_options, + streamer_message_level; + __u16 streamer_addr_table_addr, streamer_parms_addr; + __u16 mac_rx_buffer; + __u8 streamer_laa[6]; +}; + +struct streamer_adapter_addr_table { + + __u8 node_addr[6]; + __u8 reserved[4]; + __u8 func_addr[4]; +}; + +struct streamer_parameters_table { + + __u8 phys_addr[4]; + __u8 up_node_addr[6]; + __u8 up_phys_addr[4]; + __u8 poll_addr[6]; + __u16 reserved; + __u16 acc_priority; + __u16 auth_source_class; + __u16 att_code; + __u8 source_addr[6]; + __u16 beacon_type; + __u16 major_vector; + __u16 lan_status; + __u16 soft_error_time; + __u16 reserved1; + __u16 local_ring; + __u16 mon_error; + __u16 beacon_transmit; + __u16 beacon_receive; + __u16 frame_correl; + __u8 beacon_naun[6]; + __u32 reserved2; + __u8 beacon_phys[4]; +}; diff --git a/trunk/drivers/net/tokenring/madgemc.c b/trunk/drivers/net/tokenring/madgemc.c new file mode 100644 index 000000000000..28adcdf3b14c --- /dev/null +++ b/trunk/drivers/net/tokenring/madgemc.c @@ -0,0 +1,761 @@ +/* + * madgemc.c: Driver for the Madge Smart 16/4 MC16 MCA token ring card. + * + * Written 2000 by Adam Fritzler + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * This driver module supports the following cards: + * - Madge Smart 16/4 Ringnode MC16 + * - Madge Smart 16/4 Ringnode MC32 (??) + * + * Maintainer(s): + * AF Adam Fritzler + * + * Modification History: + * 16-Jan-00 AF Created + * + */ +static const char version[] = "madgemc.c: v0.91 23/01/2000 by Adam Fritzler\n"; + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "tms380tr.h" +#include "madgemc.h" /* Madge-specific constants */ + +#define MADGEMC_IO_EXTENT 32 +#define MADGEMC_SIF_OFFSET 0x08 + +struct card_info { + /* + * These are read from the BIA ROM. + */ + unsigned int manid; + unsigned int cardtype; + unsigned int cardrev; + unsigned int ramsize; + + /* + * These are read from the MCA POS registers. + */ + unsigned int burstmode:2; + unsigned int fairness:1; /* 0 = Fair, 1 = Unfair */ + unsigned int arblevel:4; + unsigned int ringspeed:2; /* 0 = 4mb, 1 = 16, 2 = Auto/none */ + unsigned int cabletype:1; /* 0 = RJ45, 1 = DB9 */ +}; + +static int madgemc_open(struct net_device *dev); +static int madgemc_close(struct net_device *dev); +static int madgemc_chipset_init(struct net_device *dev); +static void madgemc_read_rom(struct net_device *dev, struct card_info *card); +static unsigned short madgemc_setnselout_pins(struct net_device *dev); +static void madgemc_setcabletype(struct net_device *dev, int type); + +static int madgemc_mcaproc(char *buf, int slot, void *d); + +static void madgemc_setregpage(struct net_device *dev, int page); +static void madgemc_setsifsel(struct net_device *dev, int val); +static void madgemc_setint(struct net_device *dev, int val); + +static irqreturn_t madgemc_interrupt(int irq, void *dev_id); + +/* + * These work around paging, however they don't guarantee you're on the + * right page. + */ +#define SIFREADB(reg) (inb(dev->base_addr + ((reg<0x8)?reg:reg-0x8))) +#define SIFWRITEB(val, reg) (outb(val, dev->base_addr + ((reg<0x8)?reg:reg-0x8))) +#define SIFREADW(reg) (inw(dev->base_addr + ((reg<0x8)?reg:reg-0x8))) +#define SIFWRITEW(val, reg) (outw(val, dev->base_addr + ((reg<0x8)?reg:reg-0x8))) + +/* + * Read a byte-length value from the register. + */ +static unsigned short madgemc_sifreadb(struct net_device *dev, unsigned short reg) +{ + unsigned short ret; + if (reg<0x8) + ret = SIFREADB(reg); + else { + madgemc_setregpage(dev, 1); + ret = SIFREADB(reg); + madgemc_setregpage(dev, 0); + } + return ret; +} + +/* + * Write a byte-length value to a register. + */ +static void madgemc_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg) +{ + if (reg<0x8) + SIFWRITEB(val, reg); + else { + madgemc_setregpage(dev, 1); + SIFWRITEB(val, reg); + madgemc_setregpage(dev, 0); + } +} + +/* + * Read a word-length value from a register + */ +static unsigned short madgemc_sifreadw(struct net_device *dev, unsigned short reg) +{ + unsigned short ret; + if (reg<0x8) + ret = SIFREADW(reg); + else { + madgemc_setregpage(dev, 1); + ret = SIFREADW(reg); + madgemc_setregpage(dev, 0); + } + return ret; +} + +/* + * Write a word-length value to a register. + */ +static void madgemc_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg) +{ + if (reg<0x8) + SIFWRITEW(val, reg); + else { + madgemc_setregpage(dev, 1); + SIFWRITEW(val, reg); + madgemc_setregpage(dev, 0); + } +} + +static struct net_device_ops madgemc_netdev_ops __read_mostly; + +static int __devinit madgemc_probe(struct device *device) +{ + static int versionprinted; + struct net_device *dev; + struct net_local *tp; + struct card_info *card; + struct mca_device *mdev = to_mca_device(device); + int ret = 0; + + if (versionprinted++ == 0) + printk("%s", version); + + if(mca_device_claimed(mdev)) + return -EBUSY; + mca_device_set_claim(mdev, 1); + + dev = alloc_trdev(sizeof(struct net_local)); + if (!dev) { + printk("madgemc: unable to allocate dev space\n"); + mca_device_set_claim(mdev, 0); + ret = -ENOMEM; + goto getout; + } + + dev->netdev_ops = &madgemc_netdev_ops; + + card = kmalloc(sizeof(struct card_info), GFP_KERNEL); + if (card==NULL) { + ret = -ENOMEM; + goto getout1; + } + + /* + * Parse configuration information. This all comes + * directly from the publicly available @002d.ADF. + * Get it from Madge or your local ADF library. + */ + + /* + * Base address + */ + dev->base_addr = 0x0a20 + + ((mdev->pos[2] & MC16_POS2_ADDR2)?0x0400:0) + + ((mdev->pos[0] & MC16_POS0_ADDR1)?0x1000:0) + + ((mdev->pos[3] & MC16_POS3_ADDR3)?0x2000:0); + + /* + * Interrupt line + */ + switch(mdev->pos[0] >> 6) { /* upper two bits */ + case 0x1: dev->irq = 3; break; + case 0x2: dev->irq = 9; break; /* IRQ 2 = IRQ 9 */ + case 0x3: dev->irq = 10; break; + default: dev->irq = 0; break; + } + + if (dev->irq == 0) { + printk("%s: invalid IRQ\n", dev->name); + ret = -EBUSY; + goto getout2; + } + + if (!request_region(dev->base_addr, MADGEMC_IO_EXTENT, + "madgemc")) { + printk(KERN_INFO "madgemc: unable to setup Smart MC in slot %d because of I/O base conflict at 0x%04lx\n", mdev->slot, dev->base_addr); + dev->base_addr += MADGEMC_SIF_OFFSET; + ret = -EBUSY; + goto getout2; + } + dev->base_addr += MADGEMC_SIF_OFFSET; + + /* + * Arbitration Level + */ + card->arblevel = ((mdev->pos[0] >> 1) & 0x7) + 8; + + /* + * Burst mode and Fairness + */ + card->burstmode = ((mdev->pos[2] >> 6) & 0x3); + card->fairness = ((mdev->pos[2] >> 4) & 0x1); + + /* + * Ring Speed + */ + if ((mdev->pos[1] >> 2)&0x1) + card->ringspeed = 2; /* not selected */ + else if ((mdev->pos[2] >> 5) & 0x1) + card->ringspeed = 1; /* 16Mb */ + else + card->ringspeed = 0; /* 4Mb */ + + /* + * Cable type + */ + if ((mdev->pos[1] >> 6)&0x1) + card->cabletype = 1; /* STP/DB9 */ + else + card->cabletype = 0; /* UTP/RJ-45 */ + + + /* + * ROM Info. This requires us to actually twiddle + * bits on the card, so we must ensure above that + * the base address is free of conflict (request_region above). + */ + madgemc_read_rom(dev, card); + + if (card->manid != 0x4d) { /* something went wrong */ + printk(KERN_INFO "%s: Madge MC ROM read failed (unknown manufacturer ID %02x)\n", dev->name, card->manid); + goto getout3; + } + + if ((card->cardtype != 0x08) && (card->cardtype != 0x0d)) { + printk(KERN_INFO "%s: Madge MC ROM read failed (unknown card ID %02x)\n", dev->name, card->cardtype); + ret = -EIO; + goto getout3; + } + + /* All cards except Rev 0 and 1 MC16's have 256kb of RAM */ + if ((card->cardtype == 0x08) && (card->cardrev <= 0x01)) + card->ramsize = 128; + else + card->ramsize = 256; + + printk("%s: %s Rev %d at 0x%04lx IRQ %d\n", + dev->name, + (card->cardtype == 0x08)?MADGEMC16_CARDNAME: + MADGEMC32_CARDNAME, card->cardrev, + dev->base_addr, dev->irq); + + if (card->cardtype == 0x0d) + printk("%s: Warning: MC32 support is experimental and highly untested\n", dev->name); + + if (card->ringspeed==2) { /* Unknown */ + printk("%s: Warning: Ring speed not set in POS -- Please run the reference disk and set it!\n", dev->name); + card->ringspeed = 1; /* default to 16mb */ + } + + printk("%s: RAM Size: %dKB\n", dev->name, card->ramsize); + + printk("%s: Ring Speed: %dMb/sec on %s\n", dev->name, + (card->ringspeed)?16:4, + card->cabletype?"STP/DB9":"UTP/RJ-45"); + printk("%s: Arbitration Level: %d\n", dev->name, + card->arblevel); + + printk("%s: Burst Mode: ", dev->name); + switch(card->burstmode) { + case 0: printk("Cycle steal"); break; + case 1: printk("Limited burst"); break; + case 2: printk("Delayed release"); break; + case 3: printk("Immediate release"); break; + } + printk(" (%s)\n", (card->fairness)?"Unfair":"Fair"); + + + /* + * Enable SIF before we assign the interrupt handler, + * just in case we get spurious interrupts that need + * handling. + */ + outb(0, dev->base_addr + MC_CONTROL_REG0); /* sanity */ + madgemc_setsifsel(dev, 1); + if (request_irq(dev->irq, madgemc_interrupt, IRQF_SHARED, + "madgemc", dev)) { + ret = -EBUSY; + goto getout3; + } + + madgemc_chipset_init(dev); /* enables interrupts! */ + madgemc_setcabletype(dev, card->cabletype); + + /* Setup MCA structures */ + mca_device_set_name(mdev, (card->cardtype == 0x08)?MADGEMC16_CARDNAME:MADGEMC32_CARDNAME); + mca_set_adapter_procfn(mdev->slot, madgemc_mcaproc, dev); + + printk("%s: Ring Station Address: %pM\n", + dev->name, dev->dev_addr); + + if (tmsdev_init(dev, device)) { + printk("%s: unable to get memory for dev->priv.\n", + dev->name); + ret = -ENOMEM; + goto getout4; + } + tp = netdev_priv(dev); + + /* + * The MC16 is physically a 32bit card. However, Madge + * insists on calling it 16bit, so I'll assume here that + * they know what they're talking about. Cut off DMA + * at 16mb. + */ + tp->setnselout = madgemc_setnselout_pins; + tp->sifwriteb = madgemc_sifwriteb; + tp->sifreadb = madgemc_sifreadb; + tp->sifwritew = madgemc_sifwritew; + tp->sifreadw = madgemc_sifreadw; + tp->DataRate = (card->ringspeed)?SPEED_16:SPEED_4; + + memcpy(tp->ProductID, "Madge MCA 16/4 ", PROD_ID_SIZE + 1); + + tp->tmspriv = card; + dev_set_drvdata(device, dev); + + if (register_netdev(dev) == 0) + return 0; + + dev_set_drvdata(device, NULL); + ret = -ENOMEM; +getout4: + free_irq(dev->irq, dev); +getout3: + release_region(dev->base_addr-MADGEMC_SIF_OFFSET, + MADGEMC_IO_EXTENT); +getout2: + kfree(card); +getout1: + free_netdev(dev); +getout: + mca_device_set_claim(mdev, 0); + return ret; +} + +/* + * Handle interrupts generated by the card + * + * The MicroChannel Madge cards need slightly more handling + * after an interrupt than other TMS380 cards do. + * + * First we must make sure it was this card that generated the + * interrupt (since interrupt sharing is allowed). Then, + * because we're using level-triggered interrupts (as is + * standard on MCA), we must toggle the interrupt line + * on the card in order to claim and acknowledge the interrupt. + * Once that is done, the interrupt should be handlable in + * the normal tms380tr_interrupt() routine. + * + * There's two ways we can check to see if the interrupt is ours, + * both with their own disadvantages... + * + * 1) Read in the SIFSTS register from the TMS controller. This + * is guaranteed to be accurate, however, there's a fairly + * large performance penalty for doing so: the Madge chips + * must request the register from the Eagle, the Eagle must + * read them from its internal bus, and then take the route + * back out again, for a 16bit read. + * + * 2) Use the MC_CONTROL_REG0_SINTR bit from the Madge ASICs. + * The major disadvantage here is that the accuracy of the + * bit is in question. However, it cuts out the extra read + * cycles it takes to read the Eagle's SIF, as its only an + * 8bit read, and theoretically the Madge bit is directly + * connected to the interrupt latch coming out of the Eagle + * hardware (that statement is not verified). + * + * I can't determine which of these methods has the best win. For now, + * we make a compromise. Use the Madge way for the first interrupt, + * which should be the fast-path, and then once we hit the first + * interrupt, keep on trying using the SIF method until we've + * exhausted all contiguous interrupts. + * + */ +static irqreturn_t madgemc_interrupt(int irq, void *dev_id) +{ + int pending,reg1; + struct net_device *dev; + + if (!dev_id) { + printk("madgemc_interrupt: was not passed a dev_id!\n"); + return IRQ_NONE; + } + + dev = dev_id; + + /* Make sure its really us. -- the Madge way */ + pending = inb(dev->base_addr + MC_CONTROL_REG0); + if (!(pending & MC_CONTROL_REG0_SINTR)) + return IRQ_NONE; /* not our interrupt */ + + /* + * Since we're level-triggered, we may miss the rising edge + * of the next interrupt while we're off handling this one, + * so keep checking until the SIF verifies that it has nothing + * left for us to do. + */ + pending = STS_SYSTEM_IRQ; + do { + if (pending & STS_SYSTEM_IRQ) { + + /* Toggle the interrupt to reset the latch on card */ + reg1 = inb(dev->base_addr + MC_CONTROL_REG1); + outb(reg1 ^ MC_CONTROL_REG1_SINTEN, + dev->base_addr + MC_CONTROL_REG1); + outb(reg1, dev->base_addr + MC_CONTROL_REG1); + + /* Continue handling as normal */ + tms380tr_interrupt(irq, dev_id); + + pending = SIFREADW(SIFSTS); /* restart - the SIF way */ + + } else + return IRQ_HANDLED; + } while (1); + + return IRQ_HANDLED; /* not reachable */ +} + +/* + * Set the card to the preferred ring speed. + * + * Unlike newer cards, the MC16/32 have their speed selection + * circuit connected to the Madge ASICs and not to the TMS380 + * NSELOUT pins. Set the ASIC bits correctly here, and return + * zero to leave the TMS NSELOUT bits unaffected. + * + */ +static unsigned short madgemc_setnselout_pins(struct net_device *dev) +{ + unsigned char reg1; + struct net_local *tp = netdev_priv(dev); + + reg1 = inb(dev->base_addr + MC_CONTROL_REG1); + + if(tp->DataRate == SPEED_16) + reg1 |= MC_CONTROL_REG1_SPEED_SEL; /* add for 16mb */ + else if (reg1 & MC_CONTROL_REG1_SPEED_SEL) + reg1 ^= MC_CONTROL_REG1_SPEED_SEL; /* remove for 4mb */ + outb(reg1, dev->base_addr + MC_CONTROL_REG1); + + return 0; /* no change */ +} + +/* + * Set the register page. This equates to the SRSX line + * on the TMS380Cx6. + * + * Register selection is normally done via three contiguous + * bits. However, some boards (such as the MC16/32) use only + * two bits, plus a separate bit in the glue chip. This + * sets the SRSX bit (the top bit). See page 4-17 in the + * Yellow Book for which registers are affected. + * + */ +static void madgemc_setregpage(struct net_device *dev, int page) +{ + static int reg1; + + reg1 = inb(dev->base_addr + MC_CONTROL_REG1); + if ((page == 0) && (reg1 & MC_CONTROL_REG1_SRSX)) { + outb(reg1 ^ MC_CONTROL_REG1_SRSX, + dev->base_addr + MC_CONTROL_REG1); + } + else if (page == 1) { + outb(reg1 | MC_CONTROL_REG1_SRSX, + dev->base_addr + MC_CONTROL_REG1); + } + reg1 = inb(dev->base_addr + MC_CONTROL_REG1); +} + +/* + * The SIF registers are not mapped into register space by default + * Set this to 1 to map them, 0 to map the BIA ROM. + * + */ +static void madgemc_setsifsel(struct net_device *dev, int val) +{ + unsigned int reg0; + + reg0 = inb(dev->base_addr + MC_CONTROL_REG0); + if ((val == 0) && (reg0 & MC_CONTROL_REG0_SIFSEL)) { + outb(reg0 ^ MC_CONTROL_REG0_SIFSEL, + dev->base_addr + MC_CONTROL_REG0); + } else if (val == 1) { + outb(reg0 | MC_CONTROL_REG0_SIFSEL, + dev->base_addr + MC_CONTROL_REG0); + } + reg0 = inb(dev->base_addr + MC_CONTROL_REG0); +} + +/* + * Enable SIF interrupts + * + * This does not enable interrupts in the SIF, but rather + * enables SIF interrupts to be passed onto the host. + * + */ +static void madgemc_setint(struct net_device *dev, int val) +{ + unsigned int reg1; + + reg1 = inb(dev->base_addr + MC_CONTROL_REG1); + if ((val == 0) && (reg1 & MC_CONTROL_REG1_SINTEN)) { + outb(reg1 ^ MC_CONTROL_REG1_SINTEN, + dev->base_addr + MC_CONTROL_REG1); + } else if (val == 1) { + outb(reg1 | MC_CONTROL_REG1_SINTEN, + dev->base_addr + MC_CONTROL_REG1); + } +} + +/* + * Cable type is set via control register 7. Bit zero high + * for UTP, low for STP. + */ +static void madgemc_setcabletype(struct net_device *dev, int type) +{ + outb((type==0)?MC_CONTROL_REG7_CABLEUTP:MC_CONTROL_REG7_CABLESTP, + dev->base_addr + MC_CONTROL_REG7); +} + +/* + * Enable the functions of the Madge chipset needed for + * full working order. + */ +static int madgemc_chipset_init(struct net_device *dev) +{ + outb(0, dev->base_addr + MC_CONTROL_REG1); /* pull SRESET low */ + tms380tr_wait(100); /* wait for card to reset */ + + /* bring back into normal operating mode */ + outb(MC_CONTROL_REG1_NSRESET, dev->base_addr + MC_CONTROL_REG1); + + /* map SIF registers */ + madgemc_setsifsel(dev, 1); + + /* enable SIF interrupts */ + madgemc_setint(dev, 1); + + return 0; +} + +/* + * Disable the board, and put back into power-up state. + */ +static void madgemc_chipset_close(struct net_device *dev) +{ + /* disable interrupts */ + madgemc_setint(dev, 0); + /* unmap SIF registers */ + madgemc_setsifsel(dev, 0); +} + +/* + * Read the card type (MC16 or MC32) from the card. + * + * The configuration registers are stored in two separate + * pages. Pages are flipped by clearing bit 3 of CONTROL_REG0 (PAGE) + * for page zero, or setting bit 3 for page one. + * + * Page zero contains the following data: + * Byte 0: Manufacturer ID (0x4D -- ASCII "M") + * Byte 1: Card type: + * 0x08 for MC16 + * 0x0D for MC32 + * Byte 2: Card revision + * Byte 3: Mirror of POS config register 0 + * Byte 4: Mirror of POS 1 + * Byte 5: Mirror of POS 2 + * + * Page one contains the following data: + * Byte 0: Unused + * Byte 1-6: BIA, MSB to LSB. + * + * Note that to read the BIA, we must unmap the SIF registers + * by clearing bit 2 of CONTROL_REG0 (SIFSEL), as the data + * will reside in the same logical location. For this reason, + * _never_ read the BIA while the Eagle processor is running! + * The SIF will be completely inaccessible until the BIA operation + * is complete. + * + */ +static void madgemc_read_rom(struct net_device *dev, struct card_info *card) +{ + unsigned long ioaddr; + unsigned char reg0, reg1, tmpreg0, i; + + ioaddr = dev->base_addr; + + reg0 = inb(ioaddr + MC_CONTROL_REG0); + reg1 = inb(ioaddr + MC_CONTROL_REG1); + + /* Switch to page zero and unmap SIF */ + tmpreg0 = reg0 & ~(MC_CONTROL_REG0_PAGE + MC_CONTROL_REG0_SIFSEL); + outb(tmpreg0, ioaddr + MC_CONTROL_REG0); + + card->manid = inb(ioaddr + MC_ROM_MANUFACTURERID); + card->cardtype = inb(ioaddr + MC_ROM_ADAPTERID); + card->cardrev = inb(ioaddr + MC_ROM_REVISION); + + /* Switch to rom page one */ + outb(tmpreg0 | MC_CONTROL_REG0_PAGE, ioaddr + MC_CONTROL_REG0); + + /* Read BIA */ + dev->addr_len = 6; + for (i = 0; i < 6; i++) + dev->dev_addr[i] = inb(ioaddr + MC_ROM_BIA_START + i); + + /* Restore original register values */ + outb(reg0, ioaddr + MC_CONTROL_REG0); + outb(reg1, ioaddr + MC_CONTROL_REG1); +} + +static int madgemc_open(struct net_device *dev) +{ + /* + * Go ahead and reinitialize the chipset again, just to + * make sure we didn't get left in a bad state. + */ + madgemc_chipset_init(dev); + tms380tr_open(dev); + return 0; +} + +static int madgemc_close(struct net_device *dev) +{ + tms380tr_close(dev); + madgemc_chipset_close(dev); + return 0; +} + +/* + * Give some details available from /proc/mca/slotX + */ +static int madgemc_mcaproc(char *buf, int slot, void *d) +{ + struct net_device *dev = (struct net_device *)d; + struct net_local *tp = netdev_priv(dev); + struct card_info *curcard = tp->tmspriv; + int len = 0; + + len += sprintf(buf+len, "-------\n"); + if (curcard) { + len += sprintf(buf+len, "Card Revision: %d\n", curcard->cardrev); + len += sprintf(buf+len, "RAM Size: %dkb\n", curcard->ramsize); + len += sprintf(buf+len, "Cable type: %s\n", (curcard->cabletype)?"STP/DB9":"UTP/RJ-45"); + len += sprintf(buf+len, "Configured ring speed: %dMb/sec\n", (curcard->ringspeed)?16:4); + len += sprintf(buf+len, "Running ring speed: %dMb/sec\n", (tp->DataRate==SPEED_16)?16:4); + len += sprintf(buf+len, "Device: %s\n", dev->name); + len += sprintf(buf+len, "IO Port: 0x%04lx\n", dev->base_addr); + len += sprintf(buf+len, "IRQ: %d\n", dev->irq); + len += sprintf(buf+len, "Arbitration Level: %d\n", curcard->arblevel); + len += sprintf(buf+len, "Burst Mode: "); + switch(curcard->burstmode) { + case 0: len += sprintf(buf+len, "Cycle steal"); break; + case 1: len += sprintf(buf+len, "Limited burst"); break; + case 2: len += sprintf(buf+len, "Delayed release"); break; + case 3: len += sprintf(buf+len, "Immediate release"); break; + } + len += sprintf(buf+len, " (%s)\n", (curcard->fairness)?"Unfair":"Fair"); + + len += sprintf(buf+len, "Ring Station Address: %pM\n", + dev->dev_addr); + } else + len += sprintf(buf+len, "Card not configured\n"); + + return len; +} + +static int __devexit madgemc_remove(struct device *device) +{ + struct net_device *dev = dev_get_drvdata(device); + struct net_local *tp; + struct card_info *card; + + BUG_ON(!dev); + + tp = netdev_priv(dev); + card = tp->tmspriv; + kfree(card); + tp->tmspriv = NULL; + + unregister_netdev(dev); + release_region(dev->base_addr-MADGEMC_SIF_OFFSET, MADGEMC_IO_EXTENT); + free_irq(dev->irq, dev); + tmsdev_term(dev); + free_netdev(dev); + dev_set_drvdata(device, NULL); + + return 0; +} + +static short madgemc_adapter_ids[] __initdata = { + 0x002d, + 0x0000 +}; + +static struct mca_driver madgemc_driver = { + .id_table = madgemc_adapter_ids, + .driver = { + .name = "madgemc", + .bus = &mca_bus_type, + .probe = madgemc_probe, + .remove = __devexit_p(madgemc_remove), + }, +}; + +static int __init madgemc_init (void) +{ + madgemc_netdev_ops = tms380tr_netdev_ops; + madgemc_netdev_ops.ndo_open = madgemc_open; + madgemc_netdev_ops.ndo_stop = madgemc_close; + + return mca_register_driver (&madgemc_driver); +} + +static void __exit madgemc_exit (void) +{ + mca_unregister_driver (&madgemc_driver); +} + +module_init(madgemc_init); +module_exit(madgemc_exit); + +MODULE_LICENSE("GPL"); + diff --git a/trunk/drivers/net/tokenring/madgemc.h b/trunk/drivers/net/tokenring/madgemc.h new file mode 100644 index 000000000000..fe88e272c531 --- /dev/null +++ b/trunk/drivers/net/tokenring/madgemc.h @@ -0,0 +1,70 @@ +/* + * madgemc.h: Header for the madgemc tms380tr module + * + * Authors: + * - Adam Fritzler + */ + +#ifndef __LINUX_MADGEMC_H +#define __LINUX_MADGEMC_H + +#ifdef __KERNEL__ + +#define MADGEMC16_CARDNAME "Madge Smart 16/4 MC16 Ringnode" +#define MADGEMC32_CARDNAME "Madge Smart 16/4 MC32 Ringnode" + +/* + * Bit definitions for the POS config registers + */ +#define MC16_POS0_ADDR1 0x20 +#define MC16_POS2_ADDR2 0x04 +#define MC16_POS3_ADDR3 0x20 + +#define MC_CONTROL_REG0 ((long)-8) /* 0x00 */ +#define MC_CONTROL_REG1 ((long)-7) /* 0x01 */ +#define MC_ADAPTER_POS_REG0 ((long)-6) /* 0x02 */ +#define MC_ADAPTER_POS_REG1 ((long)-5) /* 0x03 */ +#define MC_ADAPTER_POS_REG2 ((long)-4) /* 0x04 */ +#define MC_ADAPTER_REG5_UNUSED ((long)-3) /* 0x05 */ +#define MC_ADAPTER_REG6_UNUSED ((long)-2) /* 0x06 */ +#define MC_CONTROL_REG7 ((long)-1) /* 0x07 */ + +#define MC_CONTROL_REG0_UNKNOWN1 0x01 +#define MC_CONTROL_REG0_UNKNOWN2 0x02 +#define MC_CONTROL_REG0_SIFSEL 0x04 +#define MC_CONTROL_REG0_PAGE 0x08 +#define MC_CONTROL_REG0_TESTINTERRUPT 0x10 +#define MC_CONTROL_REG0_UNKNOWN20 0x20 +#define MC_CONTROL_REG0_SINTR 0x40 +#define MC_CONTROL_REG0_UNKNOWN80 0x80 + +#define MC_CONTROL_REG1_SINTEN 0x01 +#define MC_CONTROL_REG1_BITOFDEATH 0x02 +#define MC_CONTROL_REG1_NSRESET 0x04 +#define MC_CONTROL_REG1_UNKNOWN8 0x08 +#define MC_CONTROL_REG1_UNKNOWN10 0x10 +#define MC_CONTROL_REG1_UNKNOWN20 0x20 +#define MC_CONTROL_REG1_SRSX 0x40 +#define MC_CONTROL_REG1_SPEED_SEL 0x80 + +#define MC_CONTROL_REG7_CABLESTP 0x00 +#define MC_CONTROL_REG7_CABLEUTP 0x01 + +/* + * ROM Page Zero + */ +#define MC_ROM_MANUFACTURERID 0x00 +#define MC_ROM_ADAPTERID 0x01 +#define MC_ROM_REVISION 0x02 +#define MC_ROM_CONFIG0 0x03 +#define MC_ROM_CONFIG1 0x04 +#define MC_ROM_CONFIG2 0x05 + +/* + * ROM Page One + */ +#define MC_ROM_UNUSED_BYTE 0x00 +#define MC_ROM_BIA_START 0x01 + +#endif /* __KERNEL__ */ +#endif /* __LINUX_MADGEMC_H */ diff --git a/trunk/drivers/net/tokenring/olympic.c b/trunk/drivers/net/tokenring/olympic.c new file mode 100644 index 000000000000..4d45fe8bd206 --- /dev/null +++ b/trunk/drivers/net/tokenring/olympic.c @@ -0,0 +1,1737 @@ +/* + * olympic.c (c) 1999 Peter De Schrijver All Rights Reserved + * 1999/2000 Mike Phillips (mikep@linuxtr.net) + * + * Linux driver for IBM PCI tokenring cards based on the Pit/Pit-Phy/Olympic + * chipset. + * + * Base Driver Skeleton: + * Written 1993-94 by Donald Becker. + * + * Copyright 1993 United States Government as represented by the + * Director, National Security Agency. + * + * Thanks to Erik De Cock, Adrian Bridgett and Frank Fiene for their + * assistance and perserverance with the testing of this driver. + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * 4/27/99 - Alpha Release 0.1.0 + * First release to the public + * + * 6/8/99 - Official Release 0.2.0 + * Merged into the kernel code + * 8/18/99 - Updated driver for 2.3.13 kernel to use new pci + * resource. Driver also reports the card name returned by + * the pci resource. + * 1/11/00 - Added spinlocks for smp + * 2/23/00 - Updated to dev_kfree_irq + * 3/10/00 - Fixed FDX enable which triggered other bugs also + * squashed. + * 5/20/00 - Changes to handle Olympic on LinuxPPC. Endian changes. + * The odd thing about the changes is that the fix for + * endian issues with the big-endian data in the arb, asb... + * was to always swab() the bytes, no matter what CPU. + * That's because the read[wl]() functions always swap the + * bytes on the way in on PPC. + * Fixing the hardware descriptors was another matter, + * because they weren't going through read[wl](), there all + * the results had to be in memory in le32 values. kdaaker + * + * 12/23/00 - Added minimal Cardbus support (Thanks Donald). + * + * 03/09/01 - Add new pci api, dev_base_lock, general clean up. + * + * 03/27/01 - Add new dma pci (Thanks to Kyle Lucke) and alloc_trdev + * Change proc_fs behaviour, now one entry per adapter. + * + * 04/09/01 - Couple of bug fixes to the dma unmaps and ejecting the + * adapter when live does not take the system down with it. + * + * 06/02/01 - Clean up, copy skb for small packets + * + * 06/22/01 - Add EISR error handling routines + * + * 07/19/01 - Improve bad LAA reporting, strip out freemem + * into a separate function, its called from 3 + * different places now. + * 02/09/02 - Replaced sleep_on. + * 03/01/02 - Replace access to several registers from 32 bit to + * 16 bit. Fixes alignment errors on PPC 64 bit machines. + * Thanks to Al Trautman for this one. + * 03/10/02 - Fix BUG in arb_cmd. Bug was there all along but was + * silently ignored until the error checking code + * went into version 1.0.0 + * 06/04/02 - Add correct start up sequence for the cardbus adapters. + * Required for strict compliance with pci power mgmt specs. + * To Do: + * + * Wake on lan + * + * If Problems do Occur + * Most problems can be rectified by either closing and opening the interface + * (ifconfig down and up) or rmmod and insmod'ing the driver (a bit difficult + * if compiled into the kernel). + */ + +/* Change OLYMPIC_DEBUG to 1 to get verbose, and I mean really verbose, messages */ + +#define OLYMPIC_DEBUG 0 + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "olympic.h" + +/* I've got to put some intelligence into the version number so that Peter and I know + * which version of the code somebody has got. + * Version Number = a.b.c.d where a.b.c is the level of code and d is the latest author. + * So 0.0.1.pds = Peter, 0.0.1.mlp = Mike + * + * Official releases will only have an a.b.c version number format. + */ + +static char version[] = +"Olympic.c v1.0.5 6/04/02 - Peter De Schrijver & Mike Phillips" ; + +static char *open_maj_error[] = {"No error", "Lobe Media Test", "Physical Insertion", + "Address Verification", "Neighbor Notification (Ring Poll)", + "Request Parameters","FDX Registration Request", + "FDX Duplicate Address Check", "Station registration Query Wait", + "Unknown stage"}; + +static char *open_min_error[] = {"No error", "Function Failure", "Signal Lost", "Wire Fault", + "Ring Speed Mismatch", "Timeout","Ring Failure","Ring Beaconing", + "Duplicate Node Address","Request Parameters","Remove Received", + "Reserved", "Reserved", "No Monitor Detected for RPL", + "Monitor Contention failer for RPL", "FDX Protocol Error"}; + +/* Module parameters */ + +MODULE_AUTHOR("Mike Phillips ") ; +MODULE_DESCRIPTION("Olympic PCI/Cardbus Chipset Driver") ; + +/* Ring Speed 0,4,16,100 + * 0 = Autosense + * 4,16 = Selected speed only, no autosense + * This allows the card to be the first on the ring + * and become the active monitor. + * 100 = Nothing at present, 100mbps is autodetected + * if FDX is turned on. May be implemented in the future to + * fail if 100mpbs is not detected. + * + * WARNING: Some hubs will allow you to insert + * at the wrong speed + */ + +static int ringspeed[OLYMPIC_MAX_ADAPTERS] = {0,} ; +module_param_array(ringspeed, int, NULL, 0); + +/* Packet buffer size */ + +static int pkt_buf_sz[OLYMPIC_MAX_ADAPTERS] = {0,} ; +module_param_array(pkt_buf_sz, int, NULL, 0) ; + +/* Message Level */ + +static int message_level[OLYMPIC_MAX_ADAPTERS] = {0,} ; +module_param_array(message_level, int, NULL, 0) ; + +/* Change network_monitor to receive mac frames through the arb channel. + * Will also create a /proc/net/olympic_tr%d entry, where %d is the tr + * device, i.e. tr0, tr1 etc. + * Intended to be used to create a ring-error reporting network module + * i.e. it will give you the source address of beaconers on the ring + */ +static int network_monitor[OLYMPIC_MAX_ADAPTERS] = {0,}; +module_param_array(network_monitor, int, NULL, 0); + +static DEFINE_PCI_DEVICE_TABLE(olympic_pci_tbl) = { + {PCI_VENDOR_ID_IBM,PCI_DEVICE_ID_IBM_TR_WAKE,PCI_ANY_ID,PCI_ANY_ID,}, + { } /* Terminating Entry */ +}; +MODULE_DEVICE_TABLE(pci,olympic_pci_tbl) ; + + +static int olympic_probe(struct pci_dev *pdev, const struct pci_device_id *ent); +static int olympic_init(struct net_device *dev); +static int olympic_open(struct net_device *dev); +static netdev_tx_t olympic_xmit(struct sk_buff *skb, + struct net_device *dev); +static int olympic_close(struct net_device *dev); +static void olympic_set_rx_mode(struct net_device *dev); +static void olympic_freemem(struct net_device *dev) ; +static irqreturn_t olympic_interrupt(int irq, void *dev_id); +static int olympic_set_mac_address(struct net_device *dev, void *addr) ; +static void olympic_arb_cmd(struct net_device *dev); +static int olympic_change_mtu(struct net_device *dev, int mtu); +static void olympic_srb_bh(struct net_device *dev) ; +static void olympic_asb_bh(struct net_device *dev) ; +static const struct file_operations olympic_proc_ops; + +static const struct net_device_ops olympic_netdev_ops = { + .ndo_open = olympic_open, + .ndo_stop = olympic_close, + .ndo_start_xmit = olympic_xmit, + .ndo_change_mtu = olympic_change_mtu, + .ndo_set_rx_mode = olympic_set_rx_mode, + .ndo_set_mac_address = olympic_set_mac_address, +}; + +static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + struct net_device *dev ; + struct olympic_private *olympic_priv; + static int card_no = -1 ; + int i ; + + card_no++ ; + + if ((i = pci_enable_device(pdev))) { + return i ; + } + + pci_set_master(pdev); + + if ((i = pci_request_regions(pdev,"olympic"))) { + goto op_disable_dev; + } + + dev = alloc_trdev(sizeof(struct olympic_private)) ; + if (!dev) { + i = -ENOMEM; + goto op_release_dev; + } + + olympic_priv = netdev_priv(dev) ; + + spin_lock_init(&olympic_priv->olympic_lock) ; + + init_waitqueue_head(&olympic_priv->srb_wait); + init_waitqueue_head(&olympic_priv->trb_wait); +#if OLYMPIC_DEBUG + printk(KERN_INFO "pci_device: %p, dev:%p, dev->priv: %p\n", pdev, dev, netdev_priv(dev)); +#endif + dev->irq=pdev->irq; + dev->base_addr=pci_resource_start(pdev, 0); + olympic_priv->olympic_card_name = pci_name(pdev); + olympic_priv->pdev = pdev; + olympic_priv->olympic_mmio = ioremap(pci_resource_start(pdev,1),256); + olympic_priv->olympic_lap = ioremap(pci_resource_start(pdev,2),2048); + if (!olympic_priv->olympic_mmio || !olympic_priv->olympic_lap) { + goto op_free_iomap; + } + + if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000) ) + olympic_priv->pkt_buf_sz = PKT_BUF_SZ ; + else + olympic_priv->pkt_buf_sz = pkt_buf_sz[card_no] ; + + dev->mtu = olympic_priv->pkt_buf_sz - TR_HLEN ; + olympic_priv->olympic_ring_speed = ringspeed[card_no] ; + olympic_priv->olympic_message_level = message_level[card_no] ; + olympic_priv->olympic_network_monitor = network_monitor[card_no]; + + if ((i = olympic_init(dev))) { + goto op_free_iomap; + } + + dev->netdev_ops = &olympic_netdev_ops; + SET_NETDEV_DEV(dev, &pdev->dev); + + pci_set_drvdata(pdev,dev) ; + register_netdev(dev) ; + printk("Olympic: %s registered as: %s\n",olympic_priv->olympic_card_name,dev->name); + if (olympic_priv->olympic_network_monitor) { /* Must go after register_netdev as we need the device name */ + char proc_name[20] ; + strcpy(proc_name,"olympic_") ; + strcat(proc_name,dev->name) ; + proc_create_data(proc_name, 0, init_net.proc_net, &olympic_proc_ops, dev); + printk("Olympic: Network Monitor information: /proc/%s\n",proc_name); + } + return 0 ; + +op_free_iomap: + if (olympic_priv->olympic_mmio) + iounmap(olympic_priv->olympic_mmio); + if (olympic_priv->olympic_lap) + iounmap(olympic_priv->olympic_lap); + + free_netdev(dev); +op_release_dev: + pci_release_regions(pdev); + +op_disable_dev: + pci_disable_device(pdev); + return i; +} + +static int olympic_init(struct net_device *dev) +{ + struct olympic_private *olympic_priv; + u8 __iomem *olympic_mmio, *init_srb,*adapter_addr; + unsigned long t; + unsigned int uaa_addr; + + olympic_priv=netdev_priv(dev); + olympic_mmio=olympic_priv->olympic_mmio; + + printk("%s\n", version); + printk("%s. I/O at %hx, MMIO at %p, LAP at %p, using irq %d\n", olympic_priv->olympic_card_name, (unsigned int) dev->base_addr,olympic_priv->olympic_mmio, olympic_priv->olympic_lap, dev->irq); + + writel(readl(olympic_mmio+BCTL) | BCTL_SOFTRESET,olympic_mmio+BCTL); + t=jiffies; + while((readl(olympic_mmio+BCTL)) & BCTL_SOFTRESET) { + schedule(); + if(time_after(jiffies, t + 40*HZ)) { + printk(KERN_ERR "IBM PCI tokenring card not responding.\n"); + return -ENODEV; + } + } + + + /* Needed for cardbus */ + if(!(readl(olympic_mmio+BCTL) & BCTL_MODE_INDICATOR)) { + writel(readl(olympic_priv->olympic_mmio+FERMASK)|FERMASK_INT_BIT, olympic_mmio+FERMASK); + } + +#if OLYMPIC_DEBUG + printk("BCTL: %x\n",readl(olympic_mmio+BCTL)); + printk("GPR: %x\n",readw(olympic_mmio+GPR)); + printk("SISRMASK: %x\n",readl(olympic_mmio+SISR_MASK)); +#endif + /* Aaaahhh, You have got to be real careful setting GPR, the card + holds the previous values from flash memory, including autosense + and ring speed */ + + writel(readl(olympic_mmio+BCTL)|BCTL_MIMREB,olympic_mmio+BCTL); + + if (olympic_priv->olympic_ring_speed == 0) { /* Autosense */ + writew(readw(olympic_mmio+GPR)|GPR_AUTOSENSE,olympic_mmio+GPR); + if (olympic_priv->olympic_message_level) + printk(KERN_INFO "%s: Ringspeed autosense mode on\n",olympic_priv->olympic_card_name); + } else if (olympic_priv->olympic_ring_speed == 16) { + if (olympic_priv->olympic_message_level) + printk(KERN_INFO "%s: Trying to open at 16 Mbps as requested\n", olympic_priv->olympic_card_name); + writew(GPR_16MBPS, olympic_mmio+GPR); + } else if (olympic_priv->olympic_ring_speed == 4) { + if (olympic_priv->olympic_message_level) + printk(KERN_INFO "%s: Trying to open at 4 Mbps as requested\n", olympic_priv->olympic_card_name) ; + writew(0, olympic_mmio+GPR); + } + + writew(readw(olympic_mmio+GPR)|GPR_NEPTUNE_BF,olympic_mmio+GPR); + +#if OLYMPIC_DEBUG + printk("GPR = %x\n",readw(olympic_mmio + GPR) ) ; +#endif + /* Solo has been paused to meet the Cardbus power + * specs if the adapter is cardbus. Check to + * see its been paused and then restart solo. The + * adapter should set the pause bit within 1 second. + */ + + if(!(readl(olympic_mmio+BCTL) & BCTL_MODE_INDICATOR)) { + t=jiffies; + while (!(readl(olympic_mmio+CLKCTL) & CLKCTL_PAUSE)) { + schedule() ; + if(time_after(jiffies, t + 2*HZ)) { + printk(KERN_ERR "IBM Cardbus tokenring adapter not responsing.\n") ; + return -ENODEV; + } + } + writel(readl(olympic_mmio+CLKCTL) & ~CLKCTL_PAUSE, olympic_mmio+CLKCTL) ; + } + + /* start solo init */ + writel((1<<15),olympic_mmio+SISR_MASK_SUM); + + t=jiffies; + while(!((readl(olympic_mmio+SISR_RR)) & SISR_SRB_REPLY)) { + schedule(); + if(time_after(jiffies, t + 15*HZ)) { + printk(KERN_ERR "IBM PCI tokenring card not responding.\n"); + return -ENODEV; + } + } + + writel(readw(olympic_mmio+LAPWWO),olympic_mmio+LAPA); + +#if OLYMPIC_DEBUG + printk("LAPWWO: %x, LAPA: %x\n",readl(olympic_mmio+LAPWWO), readl(olympic_mmio+LAPA)); +#endif + + init_srb=olympic_priv->olympic_lap + ((readw(olympic_mmio+LAPWWO)) & (~0xf800)); + +#if OLYMPIC_DEBUG +{ + int i; + printk("init_srb(%p): ",init_srb); + for(i=0;i<20;i++) + printk("%x ",readb(init_srb+i)); + printk("\n"); +} +#endif + if(readw(init_srb+6)) { + printk(KERN_INFO "tokenring card initialization failed. errorcode : %x\n",readw(init_srb+6)); + return -ENODEV; + } + + if (olympic_priv->olympic_message_level) { + if ( readb(init_srb +2) & 0x40) { + printk(KERN_INFO "Olympic: Adapter is FDX capable.\n") ; + } else { + printk(KERN_INFO "Olympic: Adapter cannot do FDX.\n"); + } + } + + uaa_addr=swab16(readw(init_srb+8)); + +#if OLYMPIC_DEBUG + printk("UAA resides at %x\n",uaa_addr); +#endif + + writel(uaa_addr,olympic_mmio+LAPA); + adapter_addr=olympic_priv->olympic_lap + (uaa_addr & (~0xf800)); + + memcpy_fromio(&dev->dev_addr[0], adapter_addr,6); + +#if OLYMPIC_DEBUG + printk("adapter address: %pM\n", dev->dev_addr); +#endif + + olympic_priv->olympic_addr_table_addr = swab16(readw(init_srb + 12)); + olympic_priv->olympic_parms_addr = swab16(readw(init_srb + 14)); + + return 0; + +} + +static int olympic_open(struct net_device *dev) +{ + struct olympic_private *olympic_priv=netdev_priv(dev); + u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio,*init_srb; + unsigned long flags, t; + int i, open_finished = 1 ; + u8 resp, err; + + DECLARE_WAITQUEUE(wait,current) ; + + olympic_init(dev); + + if (request_irq(dev->irq, olympic_interrupt, IRQF_SHARED , "olympic", + dev)) + return -EAGAIN; + +#if OLYMPIC_DEBUG + printk("BMCTL: %x\n",readl(olympic_mmio+BMCTL_SUM)); + printk("pending ints: %x\n",readl(olympic_mmio+SISR_RR)); +#endif + + writel(SISR_MI,olympic_mmio+SISR_MASK_SUM); + + writel(SISR_MI | SISR_SRB_REPLY, olympic_mmio+SISR_MASK); /* more ints later, doesn't stop arb cmd interrupt */ + + writel(LISR_LIE,olympic_mmio+LISR); /* more ints later */ + + /* adapter is closed, so SRB is pointed to by LAPWWO */ + + writel(readw(olympic_mmio+LAPWWO),olympic_mmio+LAPA); + init_srb=olympic_priv->olympic_lap + ((readw(olympic_mmio+LAPWWO)) & (~0xf800)); + +#if OLYMPIC_DEBUG + printk("LAPWWO: %x, LAPA: %x\n",readw(olympic_mmio+LAPWWO), readl(olympic_mmio+LAPA)); + printk("SISR Mask = %04x\n", readl(olympic_mmio+SISR_MASK)); + printk("Before the open command\n"); +#endif + do { + memset_io(init_srb,0,SRB_COMMAND_SIZE); + + writeb(SRB_OPEN_ADAPTER,init_srb) ; /* open */ + writeb(OLYMPIC_CLEAR_RET_CODE,init_srb+2); + + /* If Network Monitor, instruct card to copy MAC frames through the ARB */ + if (olympic_priv->olympic_network_monitor) + writew(swab16(OPEN_ADAPTER_ENABLE_FDX | OPEN_ADAPTER_PASS_ADC_MAC | OPEN_ADAPTER_PASS_ATT_MAC | OPEN_ADAPTER_PASS_BEACON), init_srb+8); + else + writew(swab16(OPEN_ADAPTER_ENABLE_FDX), init_srb+8); + + /* Test OR of first 3 bytes as its totally possible for + * someone to set the first 2 bytes to be zero, although this + * is an error, the first byte must have bit 6 set to 1 */ + + if (olympic_priv->olympic_laa[0] | olympic_priv->olympic_laa[1] | olympic_priv->olympic_laa[2]) { + writeb(olympic_priv->olympic_laa[0],init_srb+12); + writeb(olympic_priv->olympic_laa[1],init_srb+13); + writeb(olympic_priv->olympic_laa[2],init_srb+14); + writeb(olympic_priv->olympic_laa[3],init_srb+15); + writeb(olympic_priv->olympic_laa[4],init_srb+16); + writeb(olympic_priv->olympic_laa[5],init_srb+17); + memcpy(dev->dev_addr,olympic_priv->olympic_laa,dev->addr_len) ; + } + writeb(1,init_srb+30); + + spin_lock_irqsave(&olympic_priv->olympic_lock,flags); + olympic_priv->srb_queued=1; + + writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM); + spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags); + + t = jiffies ; + + add_wait_queue(&olympic_priv->srb_wait,&wait) ; + set_current_state(TASK_INTERRUPTIBLE) ; + + while(olympic_priv->srb_queued) { + schedule() ; + if(signal_pending(current)) { + printk(KERN_WARNING "%s: Signal received in open.\n", + dev->name); + printk(KERN_WARNING "SISR=%x LISR=%x\n", + readl(olympic_mmio+SISR), + readl(olympic_mmio+LISR)); + olympic_priv->srb_queued=0; + break; + } + if (time_after(jiffies, t + 10*HZ)) { + printk(KERN_WARNING "%s: SRB timed out.\n",dev->name); + olympic_priv->srb_queued=0; + break ; + } + set_current_state(TASK_INTERRUPTIBLE) ; + } + remove_wait_queue(&olympic_priv->srb_wait,&wait) ; + set_current_state(TASK_RUNNING) ; + olympic_priv->srb_queued = 0 ; +#if OLYMPIC_DEBUG + printk("init_srb(%p): ",init_srb); + for(i=0;i<20;i++) + printk("%02x ",readb(init_srb+i)); + printk("\n"); +#endif + + /* If we get the same return response as we set, the interrupt wasn't raised and the open + * timed out. + */ + + switch (resp = readb(init_srb+2)) { + case OLYMPIC_CLEAR_RET_CODE: + printk(KERN_WARNING "%s: Adapter Open time out or error.\n", dev->name) ; + goto out; + case 0: + open_finished = 1; + break; + case 0x07: + if (!olympic_priv->olympic_ring_speed && open_finished) { /* Autosense , first time around */ + printk(KERN_WARNING "%s: Retrying at different ring speed\n", dev->name); + open_finished = 0 ; + continue; + } + + err = readb(init_srb+7); + + if (!olympic_priv->olympic_ring_speed && ((err & 0x0f) == 0x0d)) { + printk(KERN_WARNING "%s: Tried to autosense ring speed with no monitors present\n",dev->name); + printk(KERN_WARNING "%s: Please try again with a specified ring speed\n",dev->name); + } else { + printk(KERN_WARNING "%s: %s - %s\n", dev->name, + open_maj_error[(err & 0xf0) >> 4], + open_min_error[(err & 0x0f)]); + } + goto out; + + case 0x32: + printk(KERN_WARNING "%s: Invalid LAA: %pM\n", + dev->name, olympic_priv->olympic_laa); + goto out; + + default: + printk(KERN_WARNING "%s: Bad OPEN response: %x\n", dev->name, resp); + goto out; + + } + } while (!(open_finished)) ; /* Will only loop if ring speed mismatch re-open attempted && autosense is on */ + + if (readb(init_srb+18) & (1<<3)) + if (olympic_priv->olympic_message_level) + printk(KERN_INFO "%s: Opened in FDX Mode\n",dev->name); + + if (readb(init_srb+18) & (1<<1)) + olympic_priv->olympic_ring_speed = 100 ; + else if (readb(init_srb+18) & 1) + olympic_priv->olympic_ring_speed = 16 ; + else + olympic_priv->olympic_ring_speed = 4 ; + + if (olympic_priv->olympic_message_level) + printk(KERN_INFO "%s: Opened in %d Mbps mode\n",dev->name, olympic_priv->olympic_ring_speed); + + olympic_priv->asb = swab16(readw(init_srb+8)); + olympic_priv->srb = swab16(readw(init_srb+10)); + olympic_priv->arb = swab16(readw(init_srb+12)); + olympic_priv->trb = swab16(readw(init_srb+16)); + + olympic_priv->olympic_receive_options = 0x01 ; + olympic_priv->olympic_copy_all_options = 0 ; + + /* setup rx ring */ + + writel((3<<16),olympic_mmio+BMCTL_RWM); /* Ensure end of frame generated interrupts */ + + writel(BMCTL_RX_DIS|3,olympic_mmio+BMCTL_RWM); /* Yes, this the enables RX channel */ + + for(i=0;ipkt_buf_sz); + if(skb == NULL) + break; + + skb->dev = dev; + + olympic_priv->olympic_rx_ring[i].buffer = cpu_to_le32(pci_map_single(olympic_priv->pdev, + skb->data,olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE)) ; + olympic_priv->olympic_rx_ring[i].res_length = cpu_to_le32(olympic_priv->pkt_buf_sz); + olympic_priv->rx_ring_skb[i]=skb; + } + + if (i==0) { + printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled\n",dev->name); + goto out; + } + + olympic_priv->rx_ring_dma_addr = pci_map_single(olympic_priv->pdev,olympic_priv->olympic_rx_ring, + sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE); + writel(olympic_priv->rx_ring_dma_addr, olympic_mmio+RXDESCQ); + writel(olympic_priv->rx_ring_dma_addr, olympic_mmio+RXCDA); + writew(i, olympic_mmio+RXDESCQCNT); + + olympic_priv->rx_status_ring_dma_addr = pci_map_single(olympic_priv->pdev, olympic_priv->olympic_rx_status_ring, + sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE); + writel(olympic_priv->rx_status_ring_dma_addr, olympic_mmio+RXSTATQ); + writel(olympic_priv->rx_status_ring_dma_addr, olympic_mmio+RXCSA); + + olympic_priv->rx_ring_last_received = OLYMPIC_RX_RING_SIZE - 1; /* last processed rx status */ + olympic_priv->rx_status_last_received = OLYMPIC_RX_RING_SIZE - 1; + + writew(i, olympic_mmio+RXSTATQCNT); + +#if OLYMPIC_DEBUG + printk("# of rx buffers: %d, RXENQ: %x\n",i, readw(olympic_mmio+RXENQ)); + printk("RXCSA: %x, rx_status_ring[0]: %p\n",readl(olympic_mmio+RXCSA),&olympic_priv->olympic_rx_status_ring[0]); + printk(" stat_ring[1]: %p, stat_ring[2]: %p, stat_ring[3]: %p\n", &(olympic_priv->olympic_rx_status_ring[1]), &(olympic_priv->olympic_rx_status_ring[2]), &(olympic_priv->olympic_rx_status_ring[3]) ); + printk(" stat_ring[4]: %p, stat_ring[5]: %p, stat_ring[6]: %p\n", &(olympic_priv->olympic_rx_status_ring[4]), &(olympic_priv->olympic_rx_status_ring[5]), &(olympic_priv->olympic_rx_status_ring[6]) ); + printk(" stat_ring[7]: %p\n", &(olympic_priv->olympic_rx_status_ring[7]) ); + + printk("RXCDA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCDA),&olympic_priv->olympic_rx_ring[0]); + printk("Rx_ring_dma_addr = %08x, rx_status_dma_addr = %08x\n", + olympic_priv->rx_ring_dma_addr,olympic_priv->rx_status_ring_dma_addr) ; +#endif + + writew((((readw(olympic_mmio+RXENQ)) & 0x8000) ^ 0x8000) | i,olympic_mmio+RXENQ); + +#if OLYMPIC_DEBUG + printk("# of rx buffers: %d, RXENQ: %x\n",i, readw(olympic_mmio+RXENQ)); + printk("RXCSA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCSA),&olympic_priv->olympic_rx_status_ring[0]); + printk("RXCDA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCDA),&olympic_priv->olympic_rx_ring[0]); +#endif + + writel(SISR_RX_STATUS | SISR_RX_NOBUF,olympic_mmio+SISR_MASK_SUM); + + /* setup tx ring */ + + writel(BMCTL_TX1_DIS,olympic_mmio+BMCTL_RWM); /* Yes, this enables TX channel 1 */ + for(i=0;iolympic_tx_ring[i].buffer=cpu_to_le32(0xdeadbeef); + + olympic_priv->free_tx_ring_entries=OLYMPIC_TX_RING_SIZE; + olympic_priv->tx_ring_dma_addr = pci_map_single(olympic_priv->pdev,olympic_priv->olympic_tx_ring, + sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE,PCI_DMA_TODEVICE) ; + writel(olympic_priv->tx_ring_dma_addr, olympic_mmio+TXDESCQ_1); + writel(olympic_priv->tx_ring_dma_addr, olympic_mmio+TXCDA_1); + writew(OLYMPIC_TX_RING_SIZE, olympic_mmio+TXDESCQCNT_1); + + olympic_priv->tx_status_ring_dma_addr = pci_map_single(olympic_priv->pdev, olympic_priv->olympic_tx_status_ring, + sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE); + writel(olympic_priv->tx_status_ring_dma_addr,olympic_mmio+TXSTATQ_1); + writel(olympic_priv->tx_status_ring_dma_addr,olympic_mmio+TXCSA_1); + writew(OLYMPIC_TX_RING_SIZE,olympic_mmio+TXSTATQCNT_1); + + olympic_priv->tx_ring_free=0; /* next entry in tx ring to use */ + olympic_priv->tx_ring_last_status=OLYMPIC_TX_RING_SIZE-1; /* last processed tx status */ + + writel(0xffffffff, olympic_mmio+EISR_RWM) ; /* clean the eisr */ + writel(0,olympic_mmio+EISR) ; + writel(EISR_MASK_OPTIONS,olympic_mmio+EISR_MASK) ; /* enables most of the TX error interrupts */ + writel(SISR_TX1_EOF | SISR_ADAPTER_CHECK | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_ASB_FREE | SISR_ERR,olympic_mmio+SISR_MASK_SUM); + +#if OLYMPIC_DEBUG + printk("BMCTL: %x\n",readl(olympic_mmio+BMCTL_SUM)); + printk("SISR MASK: %x\n",readl(olympic_mmio+SISR_MASK)); +#endif + + if (olympic_priv->olympic_network_monitor) { + u8 __iomem *oat; + u8 __iomem *opt; + u8 addr[6]; + oat = (olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr); + opt = (olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr); + + for (i = 0; i < 6; i++) + addr[i] = readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+i); + printk("%s: Node Address: %pM\n", dev->name, addr); + printk("%s: Functional Address: %02x:%02x:%02x:%02x\n",dev->name, + readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)), + readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+1), + readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+2), + readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+3)); + + for (i = 0; i < 6; i++) + addr[i] = readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+i); + printk("%s: NAUN Address: %pM\n", dev->name, addr); + } + + netif_start_queue(dev); + return 0; + +out: + free_irq(dev->irq, dev); + return -EIO; +} + +/* + * When we enter the rx routine we do not know how many frames have been + * queued on the rx channel. Therefore we start at the next rx status + * position and travel around the receive ring until we have completed + * all the frames. + * + * This means that we may process the frame before we receive the end + * of frame interrupt. This is why we always test the status instead + * of blindly processing the next frame. + * + * We also remove the last 4 bytes from the packet as well, these are + * just token ring trailer info and upset protocols that don't check + * their own length, i.e. SNA. + * + */ +static void olympic_rx(struct net_device *dev) +{ + struct olympic_private *olympic_priv=netdev_priv(dev); + u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio; + struct olympic_rx_status *rx_status; + struct olympic_rx_desc *rx_desc ; + int rx_ring_last_received,length, buffer_cnt, cpy_length, frag_len; + struct sk_buff *skb, *skb2; + int i; + + rx_status=&(olympic_priv->olympic_rx_status_ring[(olympic_priv->rx_status_last_received + 1) & (OLYMPIC_RX_RING_SIZE - 1)]) ; + + while (rx_status->status_buffercnt) { + u32 l_status_buffercnt; + + olympic_priv->rx_status_last_received++ ; + olympic_priv->rx_status_last_received &= (OLYMPIC_RX_RING_SIZE -1); +#if OLYMPIC_DEBUG + printk("rx status: %x rx len: %x\n", le32_to_cpu(rx_status->status_buffercnt), le32_to_cpu(rx_status->fragmentcnt_framelen)); +#endif + length = le32_to_cpu(rx_status->fragmentcnt_framelen) & 0xffff; + buffer_cnt = le32_to_cpu(rx_status->status_buffercnt) & 0xffff; + i = buffer_cnt ; /* Need buffer_cnt later for rxenq update */ + frag_len = le32_to_cpu(rx_status->fragmentcnt_framelen) >> 16; + +#if OLYMPIC_DEBUG + printk("length: %x, frag_len: %x, buffer_cnt: %x\n", length, frag_len, buffer_cnt); +#endif + l_status_buffercnt = le32_to_cpu(rx_status->status_buffercnt); + if(l_status_buffercnt & 0xC0000000) { + if (l_status_buffercnt & 0x3B000000) { + if (olympic_priv->olympic_message_level) { + if (l_status_buffercnt & (1<<29)) /* Rx Frame Truncated */ + printk(KERN_WARNING "%s: Rx Frame Truncated\n",dev->name); + if (l_status_buffercnt & (1<<28)) /*Rx receive overrun */ + printk(KERN_WARNING "%s: Rx Frame Receive overrun\n",dev->name); + if (l_status_buffercnt & (1<<27)) /* No receive buffers */ + printk(KERN_WARNING "%s: No receive buffers\n",dev->name); + if (l_status_buffercnt & (1<<25)) /* Receive frame error detect */ + printk(KERN_WARNING "%s: Receive frame error detect\n",dev->name); + if (l_status_buffercnt & (1<<24)) /* Received Error Detect */ + printk(KERN_WARNING "%s: Received Error Detect\n",dev->name); + } + olympic_priv->rx_ring_last_received += i ; + olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1) ; + dev->stats.rx_errors++; + } else { + + if (buffer_cnt == 1) { + skb = dev_alloc_skb(max_t(int, olympic_priv->pkt_buf_sz,length)) ; + } else { + skb = dev_alloc_skb(length) ; + } + + if (skb == NULL) { + printk(KERN_WARNING "%s: Not enough memory to copy packet to upper layers.\n",dev->name) ; + dev->stats.rx_dropped++; + /* Update counters even though we don't transfer the frame */ + olympic_priv->rx_ring_last_received += i ; + olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1) ; + } else { + /* Optimise based upon number of buffers used. + If only one buffer is used we can simply swap the buffers around. + If more than one then we must use the new buffer and copy the information + first. Ideally all frames would be in a single buffer, this can be tuned by + altering the buffer size. If the length of the packet is less than + 1500 bytes we're going to copy it over anyway to stop packets getting + dropped from sockets with buffers smaller than our pkt_buf_sz. */ + + if (buffer_cnt==1) { + olympic_priv->rx_ring_last_received++ ; + olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1); + rx_ring_last_received = olympic_priv->rx_ring_last_received ; + if (length > 1500) { + skb2=olympic_priv->rx_ring_skb[rx_ring_last_received] ; + /* unmap buffer */ + pci_unmap_single(olympic_priv->pdev, + le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer), + olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; + skb_put(skb2,length-4); + skb2->protocol = tr_type_trans(skb2,dev); + olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer = + cpu_to_le32(pci_map_single(olympic_priv->pdev, skb->data, + olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE)); + olympic_priv->olympic_rx_ring[rx_ring_last_received].res_length = + cpu_to_le32(olympic_priv->pkt_buf_sz); + olympic_priv->rx_ring_skb[rx_ring_last_received] = skb ; + netif_rx(skb2) ; + } else { + pci_dma_sync_single_for_cpu(olympic_priv->pdev, + le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer), + olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; + skb_copy_from_linear_data(olympic_priv->rx_ring_skb[rx_ring_last_received], + skb_put(skb,length - 4), + length - 4); + pci_dma_sync_single_for_device(olympic_priv->pdev, + le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer), + olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; + skb->protocol = tr_type_trans(skb,dev) ; + netif_rx(skb) ; + } + } else { + do { /* Walk the buffers */ + olympic_priv->rx_ring_last_received++ ; + olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1); + rx_ring_last_received = olympic_priv->rx_ring_last_received ; + pci_dma_sync_single_for_cpu(olympic_priv->pdev, + le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer), + olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; + rx_desc = &(olympic_priv->olympic_rx_ring[rx_ring_last_received]); + cpy_length = (i == 1 ? frag_len : le32_to_cpu(rx_desc->res_length)); + skb_copy_from_linear_data(olympic_priv->rx_ring_skb[rx_ring_last_received], + skb_put(skb, cpy_length), + cpy_length); + pci_dma_sync_single_for_device(olympic_priv->pdev, + le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer), + olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ; + } while (--i) ; + skb_trim(skb,skb->len-4) ; + skb->protocol = tr_type_trans(skb,dev); + netif_rx(skb) ; + } + dev->stats.rx_packets++ ; + dev->stats.rx_bytes += length ; + } /* if skb == null */ + } /* If status & 0x3b */ + + } else { /*if buffercnt & 0xC */ + olympic_priv->rx_ring_last_received += i ; + olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE - 1) ; + } + + rx_status->fragmentcnt_framelen = 0 ; + rx_status->status_buffercnt = 0 ; + rx_status = &(olympic_priv->olympic_rx_status_ring[(olympic_priv->rx_status_last_received+1) & (OLYMPIC_RX_RING_SIZE -1) ]); + + writew((((readw(olympic_mmio+RXENQ)) & 0x8000) ^ 0x8000) | buffer_cnt , olympic_mmio+RXENQ); + } /* while */ + +} + +static void olympic_freemem(struct net_device *dev) +{ + struct olympic_private *olympic_priv=netdev_priv(dev); + int i; + + for(i=0;irx_ring_skb[olympic_priv->rx_status_last_received] != NULL) { + dev_kfree_skb_irq(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]); + olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received] = NULL; + } + if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer != cpu_to_le32(0xdeadbeef)) { + pci_unmap_single(olympic_priv->pdev, + le32_to_cpu(olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer), + olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE); + } + olympic_priv->rx_status_last_received++; + olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1; + } + /* unmap rings */ + pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_status_ring_dma_addr, + sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE); + pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_ring_dma_addr, + sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE); + + pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_status_ring_dma_addr, + sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE); + pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_ring_dma_addr, + sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE, PCI_DMA_TODEVICE); + + return ; +} + +static irqreturn_t olympic_interrupt(int irq, void *dev_id) +{ + struct net_device *dev= (struct net_device *)dev_id; + struct olympic_private *olympic_priv=netdev_priv(dev); + u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio; + u32 sisr; + u8 __iomem *adapter_check_area ; + + /* + * Read sisr but don't reset it yet. + * The indication bit may have been set but the interrupt latch + * bit may not be set, so we'd lose the interrupt later. + */ + sisr=readl(olympic_mmio+SISR) ; + if (!(sisr & SISR_MI)) /* Interrupt isn't for us */ + return IRQ_NONE; + sisr=readl(olympic_mmio+SISR_RR) ; /* Read & Reset sisr */ + + spin_lock(&olympic_priv->olympic_lock); + + /* Hotswap gives us this on removal */ + if (sisr == 0xffffffff) { + printk(KERN_WARNING "%s: Hotswap adapter removal.\n",dev->name) ; + spin_unlock(&olympic_priv->olympic_lock) ; + return IRQ_NONE; + } + + if (sisr & (SISR_SRB_REPLY | SISR_TX1_EOF | SISR_RX_STATUS | SISR_ADAPTER_CHECK | + SISR_ASB_FREE | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_RX_NOBUF | SISR_ERR)) { + + /* If we ever get this the adapter is seriously dead. Only a reset is going to + * bring it back to life. We're talking pci bus errors and such like :( */ + if((sisr & SISR_ERR) && (readl(olympic_mmio+EISR) & EISR_MASK_OPTIONS)) { + printk(KERN_ERR "Olympic: EISR Error, EISR=%08x\n",readl(olympic_mmio+EISR)) ; + printk(KERN_ERR "The adapter must be reset to clear this condition.\n") ; + printk(KERN_ERR "Please report this error to the driver maintainer and/\n") ; + printk(KERN_ERR "or the linux-tr mailing list.\n") ; + wake_up_interruptible(&olympic_priv->srb_wait); + spin_unlock(&olympic_priv->olympic_lock) ; + return IRQ_HANDLED; + } /* SISR_ERR */ + + if(sisr & SISR_SRB_REPLY) { + if(olympic_priv->srb_queued==1) { + wake_up_interruptible(&olympic_priv->srb_wait); + } else if (olympic_priv->srb_queued==2) { + olympic_srb_bh(dev) ; + } + olympic_priv->srb_queued=0; + } /* SISR_SRB_REPLY */ + + /* We shouldn't ever miss the Tx interrupt, but the you never know, hence the loop to ensure + we get all tx completions. */ + if (sisr & SISR_TX1_EOF) { + while(olympic_priv->olympic_tx_status_ring[(olympic_priv->tx_ring_last_status + 1) & (OLYMPIC_TX_RING_SIZE-1)].status) { + olympic_priv->tx_ring_last_status++; + olympic_priv->tx_ring_last_status &= (OLYMPIC_TX_RING_SIZE-1); + olympic_priv->free_tx_ring_entries++; + dev->stats.tx_bytes += olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len; + dev->stats.tx_packets++ ; + pci_unmap_single(olympic_priv->pdev, + le32_to_cpu(olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer), + olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len,PCI_DMA_TODEVICE); + dev_kfree_skb_irq(olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]); + olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer=cpu_to_le32(0xdeadbeef); + olympic_priv->olympic_tx_status_ring[olympic_priv->tx_ring_last_status].status=0; + } + netif_wake_queue(dev); + } /* SISR_TX1_EOF */ + + if (sisr & SISR_RX_STATUS) { + olympic_rx(dev); + } /* SISR_RX_STATUS */ + + if (sisr & SISR_ADAPTER_CHECK) { + netif_stop_queue(dev); + printk(KERN_WARNING "%s: Adapter Check Interrupt Raised, 8 bytes of information follow:\n", dev->name); + writel(readl(olympic_mmio+LAPWWC),olympic_mmio+LAPA); + adapter_check_area = olympic_priv->olympic_lap + ((readl(olympic_mmio+LAPWWC)) & (~0xf800)) ; + printk(KERN_WARNING "%s: Bytes %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, readb(adapter_check_area+0), readb(adapter_check_area+1), readb(adapter_check_area+2), readb(adapter_check_area+3), readb(adapter_check_area+4), readb(adapter_check_area+5), readb(adapter_check_area+6), readb(adapter_check_area+7)) ; + spin_unlock(&olympic_priv->olympic_lock) ; + return IRQ_HANDLED; + } /* SISR_ADAPTER_CHECK */ + + if (sisr & SISR_ASB_FREE) { + /* Wake up anything that is waiting for the asb response */ + if (olympic_priv->asb_queued) { + olympic_asb_bh(dev) ; + } + } /* SISR_ASB_FREE */ + + if (sisr & SISR_ARB_CMD) { + olympic_arb_cmd(dev) ; + } /* SISR_ARB_CMD */ + + if (sisr & SISR_TRB_REPLY) { + /* Wake up anything that is waiting for the trb response */ + if (olympic_priv->trb_queued) { + wake_up_interruptible(&olympic_priv->trb_wait); + } + olympic_priv->trb_queued = 0 ; + } /* SISR_TRB_REPLY */ + + if (sisr & SISR_RX_NOBUF) { + /* According to the documentation, we don't have to do anything, but trapping it keeps it out of + /var/log/messages. */ + } /* SISR_RX_NOBUF */ + } else { + printk(KERN_WARNING "%s: Unexpected interrupt: %x\n",dev->name, sisr); + printk(KERN_WARNING "%s: SISR_MASK: %x\n",dev->name, readl(olympic_mmio+SISR_MASK)) ; + } /* One if the interrupts we want */ + writel(SISR_MI,olympic_mmio+SISR_MASK_SUM); + + spin_unlock(&olympic_priv->olympic_lock) ; + return IRQ_HANDLED; +} + +static netdev_tx_t olympic_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct olympic_private *olympic_priv=netdev_priv(dev); + u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio; + unsigned long flags ; + + spin_lock_irqsave(&olympic_priv->olympic_lock, flags); + + netif_stop_queue(dev); + + if(olympic_priv->free_tx_ring_entries) { + olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].buffer = + cpu_to_le32(pci_map_single(olympic_priv->pdev, skb->data, skb->len,PCI_DMA_TODEVICE)); + olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].status_length = cpu_to_le32(skb->len | (0x80000000)); + olympic_priv->tx_ring_skb[olympic_priv->tx_ring_free]=skb; + olympic_priv->free_tx_ring_entries--; + + olympic_priv->tx_ring_free++; + olympic_priv->tx_ring_free &= (OLYMPIC_TX_RING_SIZE-1); + writew((((readw(olympic_mmio+TXENQ_1)) & 0x8000) ^ 0x8000) | 1,olympic_mmio+TXENQ_1); + netif_wake_queue(dev); + spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags); + return NETDEV_TX_OK; + } else { + spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags); + return NETDEV_TX_BUSY; + } + +} + + +static int olympic_close(struct net_device *dev) +{ + struct olympic_private *olympic_priv=netdev_priv(dev); + u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio,*srb; + unsigned long t,flags; + + DECLARE_WAITQUEUE(wait,current) ; + + netif_stop_queue(dev); + + writel(olympic_priv->srb,olympic_mmio+LAPA); + srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800)); + + writeb(SRB_CLOSE_ADAPTER,srb+0); + writeb(0,srb+1); + writeb(OLYMPIC_CLEAR_RET_CODE,srb+2); + + add_wait_queue(&olympic_priv->srb_wait,&wait) ; + set_current_state(TASK_INTERRUPTIBLE) ; + + spin_lock_irqsave(&olympic_priv->olympic_lock,flags); + olympic_priv->srb_queued=1; + + writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM); + spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags); + + while(olympic_priv->srb_queued) { + + t = schedule_timeout_interruptible(60*HZ); + + if(signal_pending(current)) { + printk(KERN_WARNING "%s: SRB timed out.\n",dev->name); + printk(KERN_WARNING "SISR=%x MISR=%x\n",readl(olympic_mmio+SISR),readl(olympic_mmio+LISR)); + olympic_priv->srb_queued=0; + break; + } + + if (t == 0) { + printk(KERN_WARNING "%s: SRB timed out. May not be fatal.\n",dev->name); + } + olympic_priv->srb_queued=0; + } + remove_wait_queue(&olympic_priv->srb_wait,&wait) ; + + olympic_priv->rx_status_last_received++; + olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1; + + olympic_freemem(dev) ; + + /* reset tx/rx fifo's and busmaster logic */ + + writel(readl(olympic_mmio+BCTL)|(3<<13),olympic_mmio+BCTL); + udelay(1); + writel(readl(olympic_mmio+BCTL)&~(3<<13),olympic_mmio+BCTL); + +#if OLYMPIC_DEBUG + { + int i ; + printk("srb(%p): ",srb); + for(i=0;i<4;i++) + printk("%x ",readb(srb+i)); + printk("\n"); + } +#endif + free_irq(dev->irq,dev); + + return 0; + +} + +static void olympic_set_rx_mode(struct net_device *dev) +{ + struct olympic_private *olympic_priv = netdev_priv(dev); + u8 __iomem *olympic_mmio = olympic_priv->olympic_mmio ; + u8 options = 0; + u8 __iomem *srb; + struct netdev_hw_addr *ha; + unsigned char dev_mc_address[4] ; + + writel(olympic_priv->srb,olympic_mmio+LAPA); + srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800)); + options = olympic_priv->olympic_copy_all_options; + + if (dev->flags&IFF_PROMISC) + options |= 0x61 ; + else + options &= ~0x61 ; + + /* Only issue the srb if there is a change in options */ + + if ((options ^ olympic_priv->olympic_copy_all_options)) { + + /* Now to issue the srb command to alter the copy.all.options */ + + writeb(SRB_MODIFY_RECEIVE_OPTIONS,srb); + writeb(0,srb+1); + writeb(OLYMPIC_CLEAR_RET_CODE,srb+2); + writeb(0,srb+3); + writeb(olympic_priv->olympic_receive_options,srb+4); + writeb(options,srb+5); + + olympic_priv->srb_queued=2; /* Can't sleep, use srb_bh */ + + writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM); + + olympic_priv->olympic_copy_all_options = options ; + + return ; + } + + /* Set the functional addresses we need for multicast */ + + dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ; + + netdev_for_each_mc_addr(ha, dev) { + dev_mc_address[0] |= ha->addr[2]; + dev_mc_address[1] |= ha->addr[3]; + dev_mc_address[2] |= ha->addr[4]; + dev_mc_address[3] |= ha->addr[5]; + } + + writeb(SRB_SET_FUNC_ADDRESS,srb+0); + writeb(0,srb+1); + writeb(OLYMPIC_CLEAR_RET_CODE,srb+2); + writeb(0,srb+3); + writeb(0,srb+4); + writeb(0,srb+5); + writeb(dev_mc_address[0],srb+6); + writeb(dev_mc_address[1],srb+7); + writeb(dev_mc_address[2],srb+8); + writeb(dev_mc_address[3],srb+9); + + olympic_priv->srb_queued = 2 ; + writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM); + +} + +static void olympic_srb_bh(struct net_device *dev) +{ + struct olympic_private *olympic_priv = netdev_priv(dev); + u8 __iomem *olympic_mmio = olympic_priv->olympic_mmio ; + u8 __iomem *srb; + + writel(olympic_priv->srb,olympic_mmio+LAPA); + srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800)); + + switch (readb(srb)) { + + /* SRB_MODIFY_RECEIVE_OPTIONS i.e. set_multicast_list options (promiscuous) + * At some point we should do something if we get an error, such as + * resetting the IFF_PROMISC flag in dev + */ + + case SRB_MODIFY_RECEIVE_OPTIONS: + switch (readb(srb+2)) { + case 0x01: + printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name) ; + break ; + case 0x04: + printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name); + break ; + default: + if (olympic_priv->olympic_message_level) + printk(KERN_WARNING "%s: Receive Options Modified to %x,%x\n",dev->name,olympic_priv->olympic_copy_all_options, olympic_priv->olympic_receive_options) ; + break ; + } /* switch srb[2] */ + break ; + + /* SRB_SET_GROUP_ADDRESS - Multicast group setting + */ + + case SRB_SET_GROUP_ADDRESS: + switch (readb(srb+2)) { + case 0x00: + break ; + case 0x01: + printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name); + break ; + case 0x04: + printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name); + break ; + case 0x3c: + printk(KERN_WARNING "%s: Group/Functional address indicator bits not set correctly\n",dev->name) ; + break ; + case 0x3e: /* If we ever implement individual multicast addresses, will need to deal with this */ + printk(KERN_WARNING "%s: Group address registers full\n",dev->name) ; + break ; + case 0x55: + printk(KERN_INFO "%s: Group Address already set.\n",dev->name) ; + break ; + default: + break ; + } /* switch srb[2] */ + break ; + + /* SRB_RESET_GROUP_ADDRESS - Remove a multicast address from group list + */ + + case SRB_RESET_GROUP_ADDRESS: + switch (readb(srb+2)) { + case 0x00: + break ; + case 0x01: + printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name); + break ; + case 0x04: + printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ; + break ; + case 0x39: /* Must deal with this if individual multicast addresses used */ + printk(KERN_INFO "%s: Group address not found\n",dev->name); + break ; + default: + break ; + } /* switch srb[2] */ + break ; + + + /* SRB_SET_FUNC_ADDRESS - Called by the set_rx_mode + */ + + case SRB_SET_FUNC_ADDRESS: + switch (readb(srb+2)) { + case 0x00: + if (olympic_priv->olympic_message_level) + printk(KERN_INFO "%s: Functional Address Mask Set\n",dev->name); + break ; + case 0x01: + printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name); + break ; + case 0x04: + printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ; + break ; + default: + break ; + } /* switch srb[2] */ + break ; + + /* SRB_READ_LOG - Read and reset the adapter error counters + */ + + case SRB_READ_LOG: + switch (readb(srb+2)) { + case 0x00: + if (olympic_priv->olympic_message_level) + printk(KERN_INFO "%s: Read Log issued\n",dev->name) ; + break ; + case 0x01: + printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name); + break ; + case 0x04: + printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ; + break ; + + } /* switch srb[2] */ + break ; + + /* SRB_READ_SR_COUNTERS - Read and reset the source routing bridge related counters */ + + case SRB_READ_SR_COUNTERS: + switch (readb(srb+2)) { + case 0x00: + if (olympic_priv->olympic_message_level) + printk(KERN_INFO "%s: Read Source Routing Counters issued\n",dev->name) ; + break ; + case 0x01: + printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name); + break ; + case 0x04: + printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ; + break ; + default: + break ; + } /* switch srb[2] */ + break ; + + default: + printk(KERN_WARNING "%s: Unrecognized srb bh return value.\n",dev->name); + break ; + } /* switch srb[0] */ + +} + +static int olympic_set_mac_address (struct net_device *dev, void *addr) +{ + struct sockaddr *saddr = addr ; + struct olympic_private *olympic_priv = netdev_priv(dev); + + if (netif_running(dev)) { + printk(KERN_WARNING "%s: Cannot set mac/laa address while card is open\n", dev->name) ; + return -EIO ; + } + + memcpy(olympic_priv->olympic_laa, saddr->sa_data,dev->addr_len) ; + + if (olympic_priv->olympic_message_level) { + printk(KERN_INFO "%s: MAC/LAA Set to = %x.%x.%x.%x.%x.%x\n",dev->name, olympic_priv->olympic_laa[0], + olympic_priv->olympic_laa[1], olympic_priv->olympic_laa[2], + olympic_priv->olympic_laa[3], olympic_priv->olympic_laa[4], + olympic_priv->olympic_laa[5]); + } + + return 0 ; +} + +static void olympic_arb_cmd(struct net_device *dev) +{ + struct olympic_private *olympic_priv = netdev_priv(dev); + u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio; + u8 __iomem *arb_block, *asb_block, *srb ; + u8 header_len ; + u16 frame_len, buffer_len ; + struct sk_buff *mac_frame ; + u8 __iomem *buf_ptr ; + u8 __iomem *frame_data ; + u16 buff_off ; + u16 lan_status = 0, lan_status_diff ; /* Initialize to stop compiler warning */ + u8 fdx_prot_error ; + u16 next_ptr; + + arb_block = (olympic_priv->olympic_lap + olympic_priv->arb) ; + asb_block = (olympic_priv->olympic_lap + olympic_priv->asb) ; + srb = (olympic_priv->olympic_lap + olympic_priv->srb) ; + + if (readb(arb_block+0) == ARB_RECEIVE_DATA) { /* Receive.data, MAC frames */ + + header_len = readb(arb_block+8) ; /* 802.5 Token-Ring Header Length */ + frame_len = swab16(readw(arb_block + 10)) ; + + buff_off = swab16(readw(arb_block + 6)) ; + + buf_ptr = olympic_priv->olympic_lap + buff_off ; + +#if OLYMPIC_DEBUG +{ + int i; + frame_data = buf_ptr+offsetof(struct mac_receive_buffer,frame_data) ; + + for (i=0 ; i < 14 ; i++) { + printk("Loc %d = %02x\n",i,readb(frame_data + i)); + } + + printk("next %04x, fs %02x, len %04x\n",readw(buf_ptr+offsetof(struct mac_receive_buffer,next)), readb(buf_ptr+offsetof(struct mac_receive_buffer,frame_status)), readw(buf_ptr+offsetof(struct mac_receive_buffer,buffer_length))); +} +#endif + mac_frame = dev_alloc_skb(frame_len) ; + if (!mac_frame) { + printk(KERN_WARNING "%s: Memory squeeze, dropping frame.\n", dev->name); + goto drop_frame; + } + + /* Walk the buffer chain, creating the frame */ + + do { + frame_data = buf_ptr+offsetof(struct mac_receive_buffer,frame_data) ; + buffer_len = swab16(readw(buf_ptr+offsetof(struct mac_receive_buffer,buffer_length))); + memcpy_fromio(skb_put(mac_frame, buffer_len), frame_data , buffer_len ) ; + next_ptr=readw(buf_ptr+offsetof(struct mac_receive_buffer,next)); + } while (next_ptr && (buf_ptr=olympic_priv->olympic_lap + swab16(next_ptr))); + + mac_frame->protocol = tr_type_trans(mac_frame, dev); + + if (olympic_priv->olympic_network_monitor) { + struct trh_hdr *mac_hdr; + printk(KERN_WARNING "%s: Received MAC Frame, details:\n",dev->name); + mac_hdr = tr_hdr(mac_frame); + printk(KERN_WARNING "%s: MAC Frame Dest. Addr: %pM\n", + dev->name, mac_hdr->daddr); + printk(KERN_WARNING "%s: MAC Frame Srce. Addr: %pM\n", + dev->name, mac_hdr->saddr); + } + netif_rx(mac_frame); + +drop_frame: + /* Now tell the card we have dealt with the received frame */ + + /* Set LISR Bit 1 */ + writel(LISR_ARB_FREE,olympic_priv->olympic_mmio + LISR_SUM); + + /* Is the ASB free ? */ + + if (readb(asb_block + 2) != 0xff) { + olympic_priv->asb_queued = 1 ; + writel(LISR_ASB_FREE_REQ,olympic_priv->olympic_mmio+LISR_SUM); + return ; + /* Drop out and wait for the bottom half to be run */ + } + + writeb(ASB_RECEIVE_DATA,asb_block); /* Receive data */ + writeb(OLYMPIC_CLEAR_RET_CODE,asb_block+2); /* Necessary ?? */ + writeb(readb(arb_block+6),asb_block+6); /* Must send the address back to the adapter */ + writeb(readb(arb_block+7),asb_block+7); /* To let it know we have dealt with the data */ + + writel(LISR_ASB_REPLY | LISR_ASB_FREE_REQ,olympic_priv->olympic_mmio+LISR_SUM); + + olympic_priv->asb_queued = 2 ; + + return ; + + } else if (readb(arb_block) == ARB_LAN_CHANGE_STATUS) { /* Lan.change.status */ + lan_status = swab16(readw(arb_block+6)); + fdx_prot_error = readb(arb_block+8) ; + + /* Issue ARB Free */ + writel(LISR_ARB_FREE,olympic_priv->olympic_mmio+LISR_SUM); + + lan_status_diff = olympic_priv->olympic_lan_status ^ lan_status ; + + if (lan_status_diff & (LSC_LWF | LSC_ARW | LSC_FPE | LSC_RR) ) { + if (lan_status_diff & LSC_LWF) + printk(KERN_WARNING "%s: Short circuit detected on the lobe\n",dev->name); + if (lan_status_diff & LSC_ARW) + printk(KERN_WARNING "%s: Auto removal error\n",dev->name); + if (lan_status_diff & LSC_FPE) + printk(KERN_WARNING "%s: FDX Protocol Error\n",dev->name); + if (lan_status_diff & LSC_RR) + printk(KERN_WARNING "%s: Force remove MAC frame received\n",dev->name); + + /* Adapter has been closed by the hardware */ + + /* reset tx/rx fifo's and busmaster logic */ + + writel(readl(olympic_mmio+BCTL)|(3<<13),olympic_mmio+BCTL); + udelay(1); + writel(readl(olympic_mmio+BCTL)&~(3<<13),olympic_mmio+BCTL); + netif_stop_queue(dev); + olympic_priv->srb = readw(olympic_priv->olympic_lap + LAPWWO) ; + printk(KERN_WARNING "%s: Adapter has been closed\n", dev->name); + } /* If serious error */ + + if (olympic_priv->olympic_message_level) { + if (lan_status_diff & LSC_SIG_LOSS) + printk(KERN_WARNING "%s: No receive signal detected\n", dev->name); + if (lan_status_diff & LSC_HARD_ERR) + printk(KERN_INFO "%s: Beaconing\n",dev->name); + if (lan_status_diff & LSC_SOFT_ERR) + printk(KERN_WARNING "%s: Adapter transmitted Soft Error Report Mac Frame\n",dev->name); + if (lan_status_diff & LSC_TRAN_BCN) + printk(KERN_INFO "%s: We are transmitting the beacon, aaah\n",dev->name); + if (lan_status_diff & LSC_SS) + printk(KERN_INFO "%s: Single Station on the ring\n", dev->name); + if (lan_status_diff & LSC_RING_REC) + printk(KERN_INFO "%s: Ring recovery ongoing\n",dev->name); + if (lan_status_diff & LSC_FDX_MODE) + printk(KERN_INFO "%s: Operating in FDX mode\n",dev->name); + } + + if (lan_status_diff & LSC_CO) { + + if (olympic_priv->olympic_message_level) + printk(KERN_INFO "%s: Counter Overflow\n", dev->name); + + /* Issue READ.LOG command */ + + writeb(SRB_READ_LOG, srb); + writeb(0,srb+1); + writeb(OLYMPIC_CLEAR_RET_CODE,srb+2); + writeb(0,srb+3); + writeb(0,srb+4); + writeb(0,srb+5); + + olympic_priv->srb_queued=2; /* Can't sleep, use srb_bh */ + + writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM); + + } + + if (lan_status_diff & LSC_SR_CO) { + + if (olympic_priv->olympic_message_level) + printk(KERN_INFO "%s: Source routing counters overflow\n", dev->name); + + /* Issue a READ.SR.COUNTERS */ + + writeb(SRB_READ_SR_COUNTERS,srb); + writeb(0,srb+1); + writeb(OLYMPIC_CLEAR_RET_CODE,srb+2); + writeb(0,srb+3); + + olympic_priv->srb_queued=2; /* Can't sleep, use srb_bh */ + + writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM); + + } + + olympic_priv->olympic_lan_status = lan_status ; + + } /* Lan.change.status */ + else + printk(KERN_WARNING "%s: Unknown arb command\n", dev->name); +} + +static void olympic_asb_bh(struct net_device *dev) +{ + struct olympic_private *olympic_priv = netdev_priv(dev); + u8 __iomem *arb_block, *asb_block ; + + arb_block = (olympic_priv->olympic_lap + olympic_priv->arb) ; + asb_block = (olympic_priv->olympic_lap + olympic_priv->asb) ; + + if (olympic_priv->asb_queued == 1) { /* Dropped through the first time */ + + writeb(ASB_RECEIVE_DATA,asb_block); /* Receive data */ + writeb(OLYMPIC_CLEAR_RET_CODE,asb_block+2); /* Necessary ?? */ + writeb(readb(arb_block+6),asb_block+6); /* Must send the address back to the adapter */ + writeb(readb(arb_block+7),asb_block+7); /* To let it know we have dealt with the data */ + + writel(LISR_ASB_REPLY | LISR_ASB_FREE_REQ,olympic_priv->olympic_mmio+LISR_SUM); + olympic_priv->asb_queued = 2 ; + + return ; + } + + if (olympic_priv->asb_queued == 2) { + switch (readb(asb_block+2)) { + case 0x01: + printk(KERN_WARNING "%s: Unrecognized command code\n", dev->name); + break ; + case 0x26: + printk(KERN_WARNING "%s: Unrecognized buffer address\n", dev->name); + break ; + case 0xFF: + /* Valid response, everything should be ok again */ + break ; + default: + printk(KERN_WARNING "%s: Invalid return code in asb\n",dev->name); + break ; + } + } + olympic_priv->asb_queued = 0 ; +} + +static int olympic_change_mtu(struct net_device *dev, int mtu) +{ + struct olympic_private *olympic_priv = netdev_priv(dev); + u16 max_mtu ; + + if (olympic_priv->olympic_ring_speed == 4) + max_mtu = 4500 ; + else + max_mtu = 18000 ; + + if (mtu > max_mtu) + return -EINVAL ; + if (mtu < 100) + return -EINVAL ; + + dev->mtu = mtu ; + olympic_priv->pkt_buf_sz = mtu + TR_HLEN ; + + return 0 ; +} + +static int olympic_proc_show(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + struct olympic_private *olympic_priv=netdev_priv(dev); + u8 __iomem *oat = (olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ; + u8 __iomem *opt = (olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr) ; + u8 addr[6]; + u8 addr2[6]; + int i; + + seq_printf(m, + "IBM Pit/Pit-Phy/Olympic Chipset Token Ring Adapter %s\n",dev->name); + seq_printf(m, "\n%6s: Adapter Address : Node Address : Functional Addr\n", + dev->name); + + for (i = 0 ; i < 6 ; i++) + addr[i] = readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr) + i); + + seq_printf(m, "%6s: %pM : %pM : %02x:%02x:%02x:%02x\n", + dev->name, + dev->dev_addr, addr, + readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)), + readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+1), + readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+2), + readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+3)); + + seq_printf(m, "\n%6s: Token Ring Parameters Table:\n", dev->name); + + seq_printf(m, "%6s: Physical Addr : Up Node Address : Poll Address : AccPri : Auth Src : Att Code :\n", + dev->name) ; + + for (i = 0 ; i < 6 ; i++) + addr[i] = readb(opt+offsetof(struct olympic_parameters_table, up_node_addr) + i); + for (i = 0 ; i < 6 ; i++) + addr2[i] = readb(opt+offsetof(struct olympic_parameters_table, poll_addr) + i); + + seq_printf(m, "%6s: %02x:%02x:%02x:%02x : %pM : %pM : %04x : %04x : %04x :\n", + dev->name, + readb(opt+offsetof(struct olympic_parameters_table, phys_addr)), + readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+1), + readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+2), + readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+3), + addr, addr2, + swab16(readw(opt+offsetof(struct olympic_parameters_table, acc_priority))), + swab16(readw(opt+offsetof(struct olympic_parameters_table, auth_source_class))), + swab16(readw(opt+offsetof(struct olympic_parameters_table, att_code)))); + + seq_printf(m, "%6s: Source Address : Bcn T : Maj. V : Lan St : Lcl Rg : Mon Err : Frame Correl : \n", + dev->name) ; + + for (i = 0 ; i < 6 ; i++) + addr[i] = readb(opt+offsetof(struct olympic_parameters_table, source_addr) + i); + seq_printf(m, "%6s: %pM : %04x : %04x : %04x : %04x : %04x : %04x : \n", + dev->name, addr, + swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_type))), + swab16(readw(opt+offsetof(struct olympic_parameters_table, major_vector))), + swab16(readw(opt+offsetof(struct olympic_parameters_table, lan_status))), + swab16(readw(opt+offsetof(struct olympic_parameters_table, local_ring))), + swab16(readw(opt+offsetof(struct olympic_parameters_table, mon_error))), + swab16(readw(opt+offsetof(struct olympic_parameters_table, frame_correl)))); + + seq_printf(m, "%6s: Beacon Details : Tx : Rx : NAUN Node Address : NAUN Node Phys : \n", + dev->name) ; + + for (i = 0 ; i < 6 ; i++) + addr[i] = readb(opt+offsetof(struct olympic_parameters_table, beacon_naun) + i); + seq_printf(m, "%6s: : %02x : %02x : %pM : %02x:%02x:%02x:%02x : \n", + dev->name, + swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_transmit))), + swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_receive))), + addr, + readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)), + readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+1), + readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+2), + readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+3)); + + return 0; +} + +static int olympic_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, olympic_proc_show, PDE(inode)->data); +} + +static const struct file_operations olympic_proc_ops = { + .open = olympic_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void __devexit olympic_remove_one(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev) ; + struct olympic_private *olympic_priv=netdev_priv(dev); + + if (olympic_priv->olympic_network_monitor) { + char proc_name[20] ; + strcpy(proc_name,"olympic_") ; + strcat(proc_name,dev->name) ; + remove_proc_entry(proc_name,init_net.proc_net); + } + unregister_netdev(dev) ; + iounmap(olympic_priv->olympic_mmio) ; + iounmap(olympic_priv->olympic_lap) ; + pci_release_regions(pdev) ; + pci_set_drvdata(pdev,NULL) ; + free_netdev(dev) ; +} + +static struct pci_driver olympic_driver = { + .name = "olympic", + .id_table = olympic_pci_tbl, + .probe = olympic_probe, + .remove = __devexit_p(olympic_remove_one), +}; + +module_pci_driver(olympic_driver); + +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/net/tokenring/olympic.h b/trunk/drivers/net/tokenring/olympic.h new file mode 100644 index 000000000000..30631bae4c94 --- /dev/null +++ b/trunk/drivers/net/tokenring/olympic.h @@ -0,0 +1,321 @@ +/* + * olympic.h (c) 1999 Peter De Schrijver All Rights Reserved + * 1999,2000 Mike Phillips (mikep@linuxtr.net) + * + * Linux driver for IBM PCI tokenring cards based on the olympic and the PIT/PHY chipset. + * + * Base Driver Skeleton: + * Written 1993-94 by Donald Becker. + * + * Copyright 1993 United States Government as represented by the + * Director, National Security Agency. + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + */ + +#define CID 0x4e + +#define BCTL 0x70 +#define BCTL_SOFTRESET (1<<15) +#define BCTL_MIMREB (1<<6) +#define BCTL_MODE_INDICATOR (1<<5) + +#define GPR 0x4a +#define GPR_OPTI_BF (1<<6) +#define GPR_NEPTUNE_BF (1<<4) +#define GPR_AUTOSENSE (1<<2) +#define GPR_16MBPS (1<<3) + +#define PAG 0x85 +#define LBC 0x8e + +#define LISR 0x10 +#define LISR_SUM 0x14 +#define LISR_RWM 0x18 + +#define LISR_LIE (1<<15) +#define LISR_SLIM (1<<13) +#define LISR_SLI (1<<12) +#define LISR_PCMSRMASK (1<<11) +#define LISR_PCMSRINT (1<<10) +#define LISR_WOLMASK (1<<9) +#define LISR_WOL (1<<8) +#define LISR_SRB_CMD (1<<5) +#define LISR_ASB_REPLY (1<<4) +#define LISR_ASB_FREE_REQ (1<<2) +#define LISR_ARB_FREE (1<<1) +#define LISR_TRB_FRAME (1<<0) + +#define SISR 0x20 +#define SISR_SUM 0x24 +#define SISR_RWM 0x28 +#define SISR_RR 0x2C +#define SISR_RESMASK 0x30 +#define SISR_MASK 0x54 +#define SISR_MASK_SUM 0x58 +#define SISR_MASK_RWM 0x5C + +#define SISR_TX2_IDLE (1<<31) +#define SISR_TX2_HALT (1<<29) +#define SISR_TX2_EOF (1<<28) +#define SISR_TX1_IDLE (1<<27) +#define SISR_TX1_HALT (1<<25) +#define SISR_TX1_EOF (1<<24) +#define SISR_TIMEOUT (1<<23) +#define SISR_RX_NOBUF (1<<22) +#define SISR_RX_STATUS (1<<21) +#define SISR_RX_HALT (1<<18) +#define SISR_RX_EOF_EARLY (1<<16) +#define SISR_MI (1<<15) +#define SISR_PI (1<<13) +#define SISR_ERR (1<<9) +#define SISR_ADAPTER_CHECK (1<<6) +#define SISR_SRB_REPLY (1<<5) +#define SISR_ASB_FREE (1<<4) +#define SISR_ARB_CMD (1<<3) +#define SISR_TRB_REPLY (1<<2) + +#define EISR 0x34 +#define EISR_RWM 0x38 +#define EISR_MASK 0x3c +#define EISR_MASK_OPTIONS 0x001FFF7F + +#define LAPA 0x60 +#define LAPWWO 0x64 +#define LAPWWC 0x68 +#define LAPCTL 0x6C +#define LAIPD 0x78 +#define LAIPDDINC 0x7C + +#define TIMER 0x50 + +#define CLKCTL 0x74 +#define CLKCTL_PAUSE (1<<15) + +#define PM_CON 0x4 + +#define BMCTL_SUM 0x40 +#define BMCTL_RWM 0x44 +#define BMCTL_TX2_DIS (1<<30) +#define BMCTL_TX1_DIS (1<<26) +#define BMCTL_RX_DIS (1<<22) + +#define BMASR 0xcc + +#define RXDESCQ 0x90 +#define RXDESCQCNT 0x94 +#define RXCDA 0x98 +#define RXENQ 0x9C +#define RXSTATQ 0xA0 +#define RXSTATQCNT 0xA4 +#define RXCSA 0xA8 +#define RXCLEN 0xAC +#define RXHLEN 0xAE + +#define TXDESCQ_1 0xb0 +#define TXDESCQ_2 0xd0 +#define TXDESCQCNT_1 0xb4 +#define TXDESCQCNT_2 0xd4 +#define TXCDA_1 0xb8 +#define TXCDA_2 0xd8 +#define TXENQ_1 0xbc +#define TXENQ_2 0xdc +#define TXSTATQ_1 0xc0 +#define TXSTATQ_2 0xe0 +#define TXSTATQCNT_1 0xc4 +#define TXSTATQCNT_2 0xe4 +#define TXCSA_1 0xc8 +#define TXCSA_2 0xe8 +/* Cardbus */ +#define FERMASK 0xf4 +#define FERMASK_INT_BIT (1<<15) + +#define OLYMPIC_IO_SPACE 256 + +#define SRB_COMMAND_SIZE 50 + +#define OLYMPIC_MAX_ADAPTERS 8 /* 0x08 __MODULE_STRING can't hand 0xnn */ + +/* Defines for LAN STATUS CHANGE reports */ +#define LSC_SIG_LOSS 0x8000 +#define LSC_HARD_ERR 0x4000 +#define LSC_SOFT_ERR 0x2000 +#define LSC_TRAN_BCN 0x1000 +#define LSC_LWF 0x0800 +#define LSC_ARW 0x0400 +#define LSC_FPE 0x0200 +#define LSC_RR 0x0100 +#define LSC_CO 0x0080 +#define LSC_SS 0x0040 +#define LSC_RING_REC 0x0020 +#define LSC_SR_CO 0x0010 +#define LSC_FDX_MODE 0x0004 + +/* Defines for OPEN ADAPTER command */ + +#define OPEN_ADAPTER_EXT_WRAP (1<<15) +#define OPEN_ADAPTER_DIS_HARDEE (1<<14) +#define OPEN_ADAPTER_DIS_SOFTERR (1<<13) +#define OPEN_ADAPTER_PASS_ADC_MAC (1<<12) +#define OPEN_ADAPTER_PASS_ATT_MAC (1<<11) +#define OPEN_ADAPTER_ENABLE_EC (1<<10) +#define OPEN_ADAPTER_CONTENDER (1<<8) +#define OPEN_ADAPTER_PASS_BEACON (1<<7) +#define OPEN_ADAPTER_ENABLE_FDX (1<<6) +#define OPEN_ADAPTER_ENABLE_RPL (1<<5) +#define OPEN_ADAPTER_INHIBIT_ETR (1<<4) +#define OPEN_ADAPTER_INTERNAL_WRAP (1<<3) +#define OPEN_ADAPTER_USE_OPTS2 (1<<0) + +#define OPEN_ADAPTER_2_ENABLE_ONNOW (1<<15) + +/* Defines for SRB Commands */ + +#define SRB_ACCESS_REGISTER 0x1f +#define SRB_CLOSE_ADAPTER 0x04 +#define SRB_CONFIGURE_BRIDGE 0x0c +#define SRB_CONFIGURE_WAKEUP_EVENT 0x1a +#define SRB_MODIFY_BRIDGE_PARMS 0x15 +#define SRB_MODIFY_OPEN_OPTIONS 0x01 +#define SRB_MODIFY_RECEIVE_OPTIONS 0x17 +#define SRB_NO_OPERATION 0x00 +#define SRB_OPEN_ADAPTER 0x03 +#define SRB_READ_LOG 0x08 +#define SRB_READ_SR_COUNTERS 0x16 +#define SRB_RESET_GROUP_ADDRESS 0x02 +#define SRB_SAVE_CONFIGURATION 0x1b +#define SRB_SET_BRIDGE_PARMS 0x09 +#define SRB_SET_BRIDGE_TARGETS 0x10 +#define SRB_SET_FUNC_ADDRESS 0x07 +#define SRB_SET_GROUP_ADDRESS 0x06 +#define SRB_SET_GROUP_ADDR_OPTIONS 0x11 +#define SRB_UPDATE_WAKEUP_PATTERN 0x19 + +/* Clear return code */ + +#define OLYMPIC_CLEAR_RET_CODE 0xfe + +/* ARB Commands */ +#define ARB_RECEIVE_DATA 0x81 +#define ARB_LAN_CHANGE_STATUS 0x84 +/* ASB Response commands */ + +#define ASB_RECEIVE_DATA 0x81 + + +/* Olympic defaults for buffers */ + +#define OLYMPIC_RX_RING_SIZE 16 /* should be a power of 2 */ +#define OLYMPIC_TX_RING_SIZE 8 /* should be a power of 2 */ + +#define PKT_BUF_SZ 4096 /* Default packet size */ + +/* Olympic data structures */ + +/* xxxx These structures are all little endian in hardware. */ + +struct olympic_tx_desc { + __le32 buffer; + __le32 status_length; +}; + +struct olympic_tx_status { + __le32 status; +}; + +struct olympic_rx_desc { + __le32 buffer; + __le32 res_length; +}; + +struct olympic_rx_status { + __le32 fragmentcnt_framelen; + __le32 status_buffercnt; +}; +/* xxxx END These structures are all little endian in hardware. */ +/* xxxx There may be more, but I'm pretty sure about these */ + +struct mac_receive_buffer { + __le16 next ; + u8 padding ; + u8 frame_status ; + __le16 buffer_length ; + u8 frame_data ; +}; + +struct olympic_private { + + u16 srb; /* be16 */ + u16 trb; /* be16 */ + u16 arb; /* be16 */ + u16 asb; /* be16 */ + + u8 __iomem *olympic_mmio; + u8 __iomem *olympic_lap; + struct pci_dev *pdev ; + const char *olympic_card_name; + + spinlock_t olympic_lock ; + + volatile int srb_queued; /* True if an SRB is still posted */ + wait_queue_head_t srb_wait; + + volatile int asb_queued; /* True if an ASB is posted */ + + volatile int trb_queued; /* True if a TRB is posted */ + wait_queue_head_t trb_wait ; + + /* These must be on a 4 byte boundary. */ + struct olympic_rx_desc olympic_rx_ring[OLYMPIC_RX_RING_SIZE]; + struct olympic_tx_desc olympic_tx_ring[OLYMPIC_TX_RING_SIZE]; + struct olympic_rx_status olympic_rx_status_ring[OLYMPIC_RX_RING_SIZE]; + struct olympic_tx_status olympic_tx_status_ring[OLYMPIC_TX_RING_SIZE]; + + struct sk_buff *tx_ring_skb[OLYMPIC_TX_RING_SIZE], *rx_ring_skb[OLYMPIC_RX_RING_SIZE]; + int tx_ring_free, tx_ring_last_status, rx_ring_last_received,rx_status_last_received, free_tx_ring_entries; + + u16 olympic_lan_status ; + u8 olympic_ring_speed ; + u16 pkt_buf_sz ; + u8 olympic_receive_options, olympic_copy_all_options,olympic_message_level, olympic_network_monitor; + u16 olympic_addr_table_addr, olympic_parms_addr ; + u8 olympic_laa[6] ; + u32 rx_ring_dma_addr; + u32 rx_status_ring_dma_addr; + u32 tx_ring_dma_addr; + u32 tx_status_ring_dma_addr; +}; + +struct olympic_adapter_addr_table { + + u8 node_addr[6] ; + u8 reserved[4] ; + u8 func_addr[4] ; +} ; + +struct olympic_parameters_table { + + u8 phys_addr[4] ; + u8 up_node_addr[6] ; + u8 up_phys_addr[4] ; + u8 poll_addr[6] ; + u16 reserved ; + u16 acc_priority ; + u16 auth_source_class ; + u16 att_code ; + u8 source_addr[6] ; + u16 beacon_type ; + u16 major_vector ; + u16 lan_status ; + u16 soft_error_time ; + u16 reserved1 ; + u16 local_ring ; + u16 mon_error ; + u16 beacon_transmit ; + u16 beacon_receive ; + u16 frame_correl ; + u8 beacon_naun[6] ; + u32 reserved2 ; + u8 beacon_phys[4] ; +}; diff --git a/trunk/drivers/net/tokenring/proteon.c b/trunk/drivers/net/tokenring/proteon.c new file mode 100644 index 000000000000..62d90e40f9ec --- /dev/null +++ b/trunk/drivers/net/tokenring/proteon.c @@ -0,0 +1,422 @@ +/* + * proteon.c: A network driver for Proteon ISA token ring cards. + * + * Based on tmspci written 1999 by Adam Fritzler + * + * Written 2003 by Jochen Friedrich + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * This driver module supports the following cards: + * - Proteon 1392, 1392+ + * + * Maintainer(s): + * AF Adam Fritzler + * JF Jochen Friedrich jochen@scram.de + * + * Modification History: + * 02-Jan-03 JF Created + * + */ +static const char version[] = "proteon.c: v1.00 02/01/2003 by Jochen Friedrich\n"; + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "tms380tr.h" + +#define PROTEON_IO_EXTENT 32 + +/* A zero-terminated list of I/O addresses to be probed. */ +static unsigned int portlist[] __initdata = { + 0x0A20, 0x0E20, 0x1A20, 0x1E20, 0x2A20, 0x2E20, 0x3A20, 0x3E20,// Prot. + 0x4A20, 0x4E20, 0x5A20, 0x5E20, 0x6A20, 0x6E20, 0x7A20, 0x7E20,// Prot. + 0x8A20, 0x8E20, 0x9A20, 0x9E20, 0xAA20, 0xAE20, 0xBA20, 0xBE20,// Prot. + 0xCA20, 0xCE20, 0xDA20, 0xDE20, 0xEA20, 0xEE20, 0xFA20, 0xFE20,// Prot. + 0 +}; + +/* A zero-terminated list of IRQs to be probed. */ +static unsigned short irqlist[] = { + 7, 6, 5, 4, 3, 12, 11, 10, 9, + 0 +}; + +/* A zero-terminated list of DMAs to be probed. */ +static int dmalist[] __initdata = { + 5, 6, 7, + 0 +}; + +static char cardname[] = "Proteon 1392\0"; +static u64 dma_mask = ISA_MAX_ADDRESS; +static int proteon_open(struct net_device *dev); +static void proteon_read_eeprom(struct net_device *dev); +static unsigned short proteon_setnselout_pins(struct net_device *dev); + +static unsigned short proteon_sifreadb(struct net_device *dev, unsigned short reg) +{ + return inb(dev->base_addr + reg); +} + +static unsigned short proteon_sifreadw(struct net_device *dev, unsigned short reg) +{ + return inw(dev->base_addr + reg); +} + +static void proteon_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg) +{ + outb(val, dev->base_addr + reg); +} + +static void proteon_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg) +{ + outw(val, dev->base_addr + reg); +} + +static int __init proteon_probe1(struct net_device *dev, int ioaddr) +{ + unsigned char chk1, chk2; + int i; + + if (!request_region(ioaddr, PROTEON_IO_EXTENT, cardname)) + return -ENODEV; + + + chk1 = inb(ioaddr + 0x1f); /* Get Proteon ID reg 1 */ + if (chk1 != 0x1f) + goto nodev; + + chk1 = inb(ioaddr + 0x1e) & 0x07; /* Get Proteon ID reg 0 */ + for (i=0; i<16; i++) { + chk2 = inb(ioaddr + 0x1e) & 0x07; + if (((chk1 + 1) & 0x07) != chk2) + goto nodev; + chk1 = chk2; + } + + dev->base_addr = ioaddr; + return 0; +nodev: + release_region(ioaddr, PROTEON_IO_EXTENT); + return -ENODEV; +} + +static struct net_device_ops proteon_netdev_ops __read_mostly; + +static int __init setup_card(struct net_device *dev, struct device *pdev) +{ + struct net_local *tp; + static int versionprinted; + const unsigned *port; + int j,err = 0; + + if (!dev) + return -ENOMEM; + + if (dev->base_addr) /* probe specific location */ + err = proteon_probe1(dev, dev->base_addr); + else { + for (port = portlist; *port; port++) { + err = proteon_probe1(dev, *port); + if (!err) + break; + } + } + if (err) + goto out5; + + /* At this point we have found a valid card. */ + + if (versionprinted++ == 0) + printk(KERN_DEBUG "%s", version); + + err = -EIO; + pdev->dma_mask = &dma_mask; + if (tmsdev_init(dev, pdev)) + goto out4; + + dev->base_addr &= ~3; + + proteon_read_eeprom(dev); + + printk(KERN_DEBUG "proteon.c: Ring Station Address: %pM\n", + dev->dev_addr); + + tp = netdev_priv(dev); + tp->setnselout = proteon_setnselout_pins; + + tp->sifreadb = proteon_sifreadb; + tp->sifreadw = proteon_sifreadw; + tp->sifwriteb = proteon_sifwriteb; + tp->sifwritew = proteon_sifwritew; + + memcpy(tp->ProductID, cardname, PROD_ID_SIZE + 1); + + tp->tmspriv = NULL; + + dev->netdev_ops = &proteon_netdev_ops; + + if (dev->irq == 0) + { + for(j = 0; irqlist[j] != 0; j++) + { + dev->irq = irqlist[j]; + if (!request_irq(dev->irq, tms380tr_interrupt, 0, + cardname, dev)) + break; + } + + if(irqlist[j] == 0) + { + printk(KERN_INFO "proteon.c: AutoSelect no IRQ available\n"); + goto out3; + } + } + else + { + for(j = 0; irqlist[j] != 0; j++) + if (irqlist[j] == dev->irq) + break; + if (irqlist[j] == 0) + { + printk(KERN_INFO "proteon.c: Illegal IRQ %d specified\n", + dev->irq); + goto out3; + } + if (request_irq(dev->irq, tms380tr_interrupt, 0, + cardname, dev)) + { + printk(KERN_INFO "proteon.c: Selected IRQ %d not available\n", + dev->irq); + goto out3; + } + } + + if (dev->dma == 0) + { + for(j = 0; dmalist[j] != 0; j++) + { + dev->dma = dmalist[j]; + if (!request_dma(dev->dma, cardname)) + break; + } + + if(dmalist[j] == 0) + { + printk(KERN_INFO "proteon.c: AutoSelect no DMA available\n"); + goto out2; + } + } + else + { + for(j = 0; dmalist[j] != 0; j++) + if (dmalist[j] == dev->dma) + break; + if (dmalist[j] == 0) + { + printk(KERN_INFO "proteon.c: Illegal DMA %d specified\n", + dev->dma); + goto out2; + } + if (request_dma(dev->dma, cardname)) + { + printk(KERN_INFO "proteon.c: Selected DMA %d not available\n", + dev->dma); + goto out2; + } + } + + err = register_netdev(dev); + if (err) + goto out; + + printk(KERN_DEBUG "%s: IO: %#4lx IRQ: %d DMA: %d\n", + dev->name, dev->base_addr, dev->irq, dev->dma); + + return 0; +out: + free_dma(dev->dma); +out2: + free_irq(dev->irq, dev); +out3: + tmsdev_term(dev); +out4: + release_region(dev->base_addr, PROTEON_IO_EXTENT); +out5: + return err; +} + +/* + * Reads MAC address from adapter RAM, which should've read it from + * the onboard ROM. + * + * Calling this on a board that does not support it can be a very + * dangerous thing. The Madge board, for instance, will lock your + * machine hard when this is called. Luckily, its supported in a + * separate driver. --ASF + */ +static void proteon_read_eeprom(struct net_device *dev) +{ + int i; + + /* Address: 0000:0000 */ + proteon_sifwritew(dev, 0, SIFADX); + proteon_sifwritew(dev, 0, SIFADR); + + /* Read six byte MAC address data */ + dev->addr_len = 6; + for(i = 0; i < 6; i++) + dev->dev_addr[i] = proteon_sifreadw(dev, SIFINC) >> 8; +} + +static unsigned short proteon_setnselout_pins(struct net_device *dev) +{ + return 0; +} + +static int proteon_open(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned short val = 0; + int i; + + /* Proteon reset sequence */ + outb(0, dev->base_addr + 0x11); + mdelay(20); + outb(0x04, dev->base_addr + 0x11); + mdelay(20); + outb(0, dev->base_addr + 0x11); + mdelay(100); + + /* set control/status reg */ + val = inb(dev->base_addr + 0x11); + val |= 0x78; + val &= 0xf9; + if(tp->DataRate == SPEED_4) + val |= 0x20; + else + val &= ~0x20; + + outb(val, dev->base_addr + 0x11); + outb(0xff, dev->base_addr + 0x12); + for(i = 0; irqlist[i] != 0; i++) + { + if(irqlist[i] == dev->irq) + break; + } + val = i; + i = (7 - dev->dma) << 4; + val |= i; + outb(val, dev->base_addr + 0x13); + + return tms380tr_open(dev); +} + +#define ISATR_MAX_ADAPTERS 3 + +static int io[ISATR_MAX_ADAPTERS]; +static int irq[ISATR_MAX_ADAPTERS]; +static int dma[ISATR_MAX_ADAPTERS]; + +MODULE_LICENSE("GPL"); + +module_param_array(io, int, NULL, 0); +module_param_array(irq, int, NULL, 0); +module_param_array(dma, int, NULL, 0); + +static struct platform_device *proteon_dev[ISATR_MAX_ADAPTERS]; + +static struct platform_driver proteon_driver = { + .driver = { + .name = "proteon", + }, +}; + +static int __init proteon_init(void) +{ + struct net_device *dev; + struct platform_device *pdev; + int i, num = 0, err = 0; + + proteon_netdev_ops = tms380tr_netdev_ops; + proteon_netdev_ops.ndo_open = proteon_open; + proteon_netdev_ops.ndo_stop = tms380tr_close; + + err = platform_driver_register(&proteon_driver); + if (err) + return err; + + for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { + dev = alloc_trdev(sizeof(struct net_local)); + if (!dev) + continue; + + dev->base_addr = io[i]; + dev->irq = irq[i]; + dev->dma = dma[i]; + pdev = platform_device_register_simple("proteon", + i, NULL, 0); + if (IS_ERR(pdev)) { + free_netdev(dev); + continue; + } + err = setup_card(dev, &pdev->dev); + if (!err) { + proteon_dev[i] = pdev; + platform_set_drvdata(pdev, dev); + ++num; + } else { + platform_device_unregister(pdev); + free_netdev(dev); + } + } + + printk(KERN_NOTICE "proteon.c: %d cards found.\n", num); + /* Probe for cards. */ + if (num == 0) { + printk(KERN_NOTICE "proteon.c: No cards found.\n"); + platform_driver_unregister(&proteon_driver); + return -ENODEV; + } + return 0; +} + +static void __exit proteon_cleanup(void) +{ + struct net_device *dev; + int i; + + for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { + struct platform_device *pdev = proteon_dev[i]; + + if (!pdev) + continue; + dev = platform_get_drvdata(pdev); + unregister_netdev(dev); + release_region(dev->base_addr, PROTEON_IO_EXTENT); + free_irq(dev->irq, dev); + free_dma(dev->dma); + tmsdev_term(dev); + free_netdev(dev); + platform_set_drvdata(pdev, NULL); + platform_device_unregister(pdev); + } + platform_driver_unregister(&proteon_driver); +} + +module_init(proteon_init); +module_exit(proteon_cleanup); diff --git a/trunk/drivers/net/tokenring/skisa.c b/trunk/drivers/net/tokenring/skisa.c new file mode 100644 index 000000000000..ee11e93dc30e --- /dev/null +++ b/trunk/drivers/net/tokenring/skisa.c @@ -0,0 +1,432 @@ +/* + * skisa.c: A network driver for SK-NET TMS380-based ISA token ring cards. + * + * Based on tmspci written 1999 by Adam Fritzler + * + * Written 2000 by Jochen Friedrich + * Dedicated to my girlfriend Steffi Bopp + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * This driver module supports the following cards: + * - SysKonnect TR4/16(+) ISA (SK-4190) + * + * Maintainer(s): + * AF Adam Fritzler + * JF Jochen Friedrich jochen@scram.de + * + * Modification History: + * 14-Jan-01 JF Created + * 28-Oct-02 JF Fixed probe of card for static compilation. + * Fixed module init to not make hotplug go wild. + * 09-Nov-02 JF Fixed early bail out on out of memory + * situations if multiple cards are found. + * Cleaned up some unnecessary console SPAM. + * 09-Dec-02 JF Fixed module reference counting. + * 02-Jan-03 JF Renamed to skisa.c + * + */ +static const char version[] = "skisa.c: v1.03 09/12/2002 by Jochen Friedrich\n"; + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "tms380tr.h" + +#define SK_ISA_IO_EXTENT 32 + +/* A zero-terminated list of I/O addresses to be probed. */ +static unsigned int portlist[] __initdata = { + 0x0A20, 0x1A20, 0x0B20, 0x1B20, 0x0980, 0x1980, 0x0900, 0x1900,// SK + 0 +}; + +/* A zero-terminated list of IRQs to be probed. + * Used again after initial probe for sktr_chipset_init, called from sktr_open. + */ +static const unsigned short irqlist[] = { + 3, 5, 9, 10, 11, 12, 15, + 0 +}; + +/* A zero-terminated list of DMAs to be probed. */ +static int dmalist[] __initdata = { + 5, 6, 7, + 0 +}; + +static char isa_cardname[] = "SK NET TR 4/16 ISA\0"; +static u64 dma_mask = ISA_MAX_ADDRESS; +static int sk_isa_open(struct net_device *dev); +static void sk_isa_read_eeprom(struct net_device *dev); +static unsigned short sk_isa_setnselout_pins(struct net_device *dev); + +static unsigned short sk_isa_sifreadb(struct net_device *dev, unsigned short reg) +{ + return inb(dev->base_addr + reg); +} + +static unsigned short sk_isa_sifreadw(struct net_device *dev, unsigned short reg) +{ + return inw(dev->base_addr + reg); +} + +static void sk_isa_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg) +{ + outb(val, dev->base_addr + reg); +} + +static void sk_isa_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg) +{ + outw(val, dev->base_addr + reg); +} + + +static int __init sk_isa_probe1(struct net_device *dev, int ioaddr) +{ + unsigned char old, chk1, chk2; + + if (!request_region(ioaddr, SK_ISA_IO_EXTENT, isa_cardname)) + return -ENODEV; + + old = inb(ioaddr + SIFADR); /* Get the old SIFADR value */ + + chk1 = 0; /* Begin with check value 0 */ + do { + /* Write new SIFADR value */ + outb(chk1, ioaddr + SIFADR); + + /* Read, invert and write */ + chk2 = inb(ioaddr + SIFADD); + chk2 ^= 0x0FE; + outb(chk2, ioaddr + SIFADR); + + /* Read, invert and compare */ + chk2 = inb(ioaddr + SIFADD); + chk2 ^= 0x0FE; + + if(chk1 != chk2) { + release_region(ioaddr, SK_ISA_IO_EXTENT); + return -ENODEV; + } + + chk1 -= 2; + } while(chk1 != 0); /* Repeat 128 times (all byte values) */ + + /* Restore the SIFADR value */ + outb(old, ioaddr + SIFADR); + + dev->base_addr = ioaddr; + return 0; +} + +static struct net_device_ops sk_isa_netdev_ops __read_mostly; + +static int __init setup_card(struct net_device *dev, struct device *pdev) +{ + struct net_local *tp; + static int versionprinted; + const unsigned *port; + int j, err = 0; + + if (!dev) + return -ENOMEM; + + if (dev->base_addr) /* probe specific location */ + err = sk_isa_probe1(dev, dev->base_addr); + else { + for (port = portlist; *port; port++) { + err = sk_isa_probe1(dev, *port); + if (!err) + break; + } + } + if (err) + goto out5; + + /* At this point we have found a valid card. */ + + if (versionprinted++ == 0) + printk(KERN_DEBUG "%s", version); + + err = -EIO; + pdev->dma_mask = &dma_mask; + if (tmsdev_init(dev, pdev)) + goto out4; + + dev->base_addr &= ~3; + + sk_isa_read_eeprom(dev); + + printk(KERN_DEBUG "skisa.c: Ring Station Address: %pM\n", + dev->dev_addr); + + tp = netdev_priv(dev); + tp->setnselout = sk_isa_setnselout_pins; + + tp->sifreadb = sk_isa_sifreadb; + tp->sifreadw = sk_isa_sifreadw; + tp->sifwriteb = sk_isa_sifwriteb; + tp->sifwritew = sk_isa_sifwritew; + + memcpy(tp->ProductID, isa_cardname, PROD_ID_SIZE + 1); + + tp->tmspriv = NULL; + + dev->netdev_ops = &sk_isa_netdev_ops; + + if (dev->irq == 0) + { + for(j = 0; irqlist[j] != 0; j++) + { + dev->irq = irqlist[j]; + if (!request_irq(dev->irq, tms380tr_interrupt, 0, + isa_cardname, dev)) + break; + } + + if(irqlist[j] == 0) + { + printk(KERN_INFO "skisa.c: AutoSelect no IRQ available\n"); + goto out3; + } + } + else + { + for(j = 0; irqlist[j] != 0; j++) + if (irqlist[j] == dev->irq) + break; + if (irqlist[j] == 0) + { + printk(KERN_INFO "skisa.c: Illegal IRQ %d specified\n", + dev->irq); + goto out3; + } + if (request_irq(dev->irq, tms380tr_interrupt, 0, + isa_cardname, dev)) + { + printk(KERN_INFO "skisa.c: Selected IRQ %d not available\n", + dev->irq); + goto out3; + } + } + + if (dev->dma == 0) + { + for(j = 0; dmalist[j] != 0; j++) + { + dev->dma = dmalist[j]; + if (!request_dma(dev->dma, isa_cardname)) + break; + } + + if(dmalist[j] == 0) + { + printk(KERN_INFO "skisa.c: AutoSelect no DMA available\n"); + goto out2; + } + } + else + { + for(j = 0; dmalist[j] != 0; j++) + if (dmalist[j] == dev->dma) + break; + if (dmalist[j] == 0) + { + printk(KERN_INFO "skisa.c: Illegal DMA %d specified\n", + dev->dma); + goto out2; + } + if (request_dma(dev->dma, isa_cardname)) + { + printk(KERN_INFO "skisa.c: Selected DMA %d not available\n", + dev->dma); + goto out2; + } + } + + err = register_netdev(dev); + if (err) + goto out; + + printk(KERN_DEBUG "%s: IO: %#4lx IRQ: %d DMA: %d\n", + dev->name, dev->base_addr, dev->irq, dev->dma); + + return 0; +out: + free_dma(dev->dma); +out2: + free_irq(dev->irq, dev); +out3: + tmsdev_term(dev); +out4: + release_region(dev->base_addr, SK_ISA_IO_EXTENT); +out5: + return err; +} + +/* + * Reads MAC address from adapter RAM, which should've read it from + * the onboard ROM. + * + * Calling this on a board that does not support it can be a very + * dangerous thing. The Madge board, for instance, will lock your + * machine hard when this is called. Luckily, its supported in a + * separate driver. --ASF + */ +static void sk_isa_read_eeprom(struct net_device *dev) +{ + int i; + + /* Address: 0000:0000 */ + sk_isa_sifwritew(dev, 0, SIFADX); + sk_isa_sifwritew(dev, 0, SIFADR); + + /* Read six byte MAC address data */ + dev->addr_len = 6; + for(i = 0; i < 6; i++) + dev->dev_addr[i] = sk_isa_sifreadw(dev, SIFINC) >> 8; +} + +static unsigned short sk_isa_setnselout_pins(struct net_device *dev) +{ + return 0; +} + +static int sk_isa_open(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned short val = 0; + unsigned short oldval; + int i; + + val = 0; + for(i = 0; irqlist[i] != 0; i++) + { + if(irqlist[i] == dev->irq) + break; + } + + val |= CYCLE_TIME << 2; + val |= i << 4; + i = dev->dma - 5; + val |= i; + if(tp->DataRate == SPEED_4) + val |= LINE_SPEED_BIT; + else + val &= ~LINE_SPEED_BIT; + oldval = sk_isa_sifreadb(dev, POSREG); + /* Leave cycle bits alone */ + oldval |= 0xf3; + val &= oldval; + sk_isa_sifwriteb(dev, val, POSREG); + + return tms380tr_open(dev); +} + +#define ISATR_MAX_ADAPTERS 3 + +static int io[ISATR_MAX_ADAPTERS]; +static int irq[ISATR_MAX_ADAPTERS]; +static int dma[ISATR_MAX_ADAPTERS]; + +MODULE_LICENSE("GPL"); + +module_param_array(io, int, NULL, 0); +module_param_array(irq, int, NULL, 0); +module_param_array(dma, int, NULL, 0); + +static struct platform_device *sk_isa_dev[ISATR_MAX_ADAPTERS]; + +static struct platform_driver sk_isa_driver = { + .driver = { + .name = "skisa", + }, +}; + +static int __init sk_isa_init(void) +{ + struct net_device *dev; + struct platform_device *pdev; + int i, num = 0, err = 0; + + sk_isa_netdev_ops = tms380tr_netdev_ops; + sk_isa_netdev_ops.ndo_open = sk_isa_open; + sk_isa_netdev_ops.ndo_stop = tms380tr_close; + + err = platform_driver_register(&sk_isa_driver); + if (err) + return err; + + for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { + dev = alloc_trdev(sizeof(struct net_local)); + if (!dev) + continue; + + dev->base_addr = io[i]; + dev->irq = irq[i]; + dev->dma = dma[i]; + pdev = platform_device_register_simple("skisa", + i, NULL, 0); + if (IS_ERR(pdev)) { + free_netdev(dev); + continue; + } + err = setup_card(dev, &pdev->dev); + if (!err) { + sk_isa_dev[i] = pdev; + platform_set_drvdata(sk_isa_dev[i], dev); + ++num; + } else { + platform_device_unregister(pdev); + free_netdev(dev); + } + } + + printk(KERN_NOTICE "skisa.c: %d cards found.\n", num); + /* Probe for cards. */ + if (num == 0) { + printk(KERN_NOTICE "skisa.c: No cards found.\n"); + platform_driver_unregister(&sk_isa_driver); + return -ENODEV; + } + return 0; +} + +static void __exit sk_isa_cleanup(void) +{ + struct net_device *dev; + int i; + + for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { + struct platform_device *pdev = sk_isa_dev[i]; + + if (!pdev) + continue; + dev = platform_get_drvdata(pdev); + unregister_netdev(dev); + release_region(dev->base_addr, SK_ISA_IO_EXTENT); + free_irq(dev->irq, dev); + free_dma(dev->dma); + tmsdev_term(dev); + free_netdev(dev); + platform_set_drvdata(pdev, NULL); + platform_device_unregister(pdev); + } + platform_driver_unregister(&sk_isa_driver); +} + +module_init(sk_isa_init); +module_exit(sk_isa_cleanup); diff --git a/trunk/drivers/net/tokenring/smctr.c b/trunk/drivers/net/tokenring/smctr.c new file mode 100644 index 000000000000..cb35fb79e016 --- /dev/null +++ b/trunk/drivers/net/tokenring/smctr.c @@ -0,0 +1,5717 @@ +/* + * smctr.c: A network driver for the SMC Token Ring Adapters. + * + * Written by Jay Schulist + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * This device driver works with the following SMC adapters: + * - SMC TokenCard Elite (8115T, chips 825/584) + * - SMC TokenCard Elite/A MCA (8115T/A, chips 825/594) + * + * Source(s): + * - SMC TokenCard SDK. + * + * Maintainer(s): + * JS Jay Schulist + * + * Changes: + * 07102000 JS Fixed a timing problem in smctr_wait_cmd(); + * Also added a bit more discriptive error msgs. + * 07122000 JS Fixed problem with detecting a card with + * module io/irq/mem specified. + * + * To do: + * 1. Multicast support. + * + * Initial 2.5 cleanup Alan Cox 2002/10/28 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if BITS_PER_LONG == 64 +#error FIXME: driver does not support 64-bit platforms +#endif + +#include "smctr.h" /* Our Stuff */ + +static const char version[] __initdata = + KERN_INFO "smctr.c: v1.4 7/12/00 by jschlst@samba.org\n"; +static const char cardname[] = "smctr"; + + +#define SMCTR_IO_EXTENT 20 + +#ifdef CONFIG_MCA_LEGACY +static unsigned int smctr_posid = 0x6ec6; +#endif + +static int ringspeed; + +/* SMC Name of the Adapter. */ +static char smctr_name[] = "SMC TokenCard"; +static char *smctr_model = "Unknown"; + +/* Use 0 for production, 1 for verification, 2 for debug, and + * 3 for very verbose debug. + */ +#ifndef SMCTR_DEBUG +#define SMCTR_DEBUG 1 +#endif +static unsigned int smctr_debug = SMCTR_DEBUG; + +/* smctr.c prototypes and functions are arranged alphabeticly + * for clearity, maintainability and pure old fashion fun. + */ +/* A */ +static int smctr_alloc_shared_memory(struct net_device *dev); + +/* B */ +static int smctr_bypass_state(struct net_device *dev); + +/* C */ +static int smctr_checksum_firmware(struct net_device *dev); +static int __init smctr_chk_isa(struct net_device *dev); +static int smctr_chg_rx_mask(struct net_device *dev); +static int smctr_clear_int(struct net_device *dev); +static int smctr_clear_trc_reset(int ioaddr); +static int smctr_close(struct net_device *dev); + +/* D */ +static int smctr_decode_firmware(struct net_device *dev, + const struct firmware *fw); +static int smctr_disable_16bit(struct net_device *dev); +static int smctr_disable_adapter_ctrl_store(struct net_device *dev); +static int smctr_disable_bic_int(struct net_device *dev); + +/* E */ +static int smctr_enable_16bit(struct net_device *dev); +static int smctr_enable_adapter_ctrl_store(struct net_device *dev); +static int smctr_enable_adapter_ram(struct net_device *dev); +static int smctr_enable_bic_int(struct net_device *dev); + +/* G */ +static int __init smctr_get_boardid(struct net_device *dev, int mca); +static int smctr_get_group_address(struct net_device *dev); +static int smctr_get_functional_address(struct net_device *dev); +static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev); +static int smctr_get_physical_drop_number(struct net_device *dev); +static __u8 *smctr_get_rx_pointer(struct net_device *dev, short queue); +static int smctr_get_station_id(struct net_device *dev); +static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue, + __u16 bytes_count); +static int smctr_get_upstream_neighbor_addr(struct net_device *dev); + +/* H */ +static int smctr_hardware_send_packet(struct net_device *dev, + struct net_local *tp); +/* I */ +static int smctr_init_acbs(struct net_device *dev); +static int smctr_init_adapter(struct net_device *dev); +static int smctr_init_card_real(struct net_device *dev); +static int smctr_init_rx_bdbs(struct net_device *dev); +static int smctr_init_rx_fcbs(struct net_device *dev); +static int smctr_init_shared_memory(struct net_device *dev); +static int smctr_init_tx_bdbs(struct net_device *dev); +static int smctr_init_tx_fcbs(struct net_device *dev); +static int smctr_internal_self_test(struct net_device *dev); +static irqreturn_t smctr_interrupt(int irq, void *dev_id); +static int smctr_issue_enable_int_cmd(struct net_device *dev, + __u16 interrupt_enable_mask); +static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, + __u16 ibits); +static int smctr_issue_init_timers_cmd(struct net_device *dev); +static int smctr_issue_init_txrx_cmd(struct net_device *dev); +static int smctr_issue_insert_cmd(struct net_device *dev); +static int smctr_issue_read_ring_status_cmd(struct net_device *dev); +static int smctr_issue_read_word_cmd(struct net_device *dev, __u16 aword_cnt); +static int smctr_issue_remove_cmd(struct net_device *dev); +static int smctr_issue_resume_acb_cmd(struct net_device *dev); +static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue); +static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue); +static int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue); +static int smctr_issue_test_internal_rom_cmd(struct net_device *dev); +static int smctr_issue_test_hic_cmd(struct net_device *dev); +static int smctr_issue_test_mac_reg_cmd(struct net_device *dev); +static int smctr_issue_trc_loopback_cmd(struct net_device *dev); +static int smctr_issue_tri_loopback_cmd(struct net_device *dev); +static int smctr_issue_write_byte_cmd(struct net_device *dev, + short aword_cnt, void *byte); +static int smctr_issue_write_word_cmd(struct net_device *dev, + short aword_cnt, void *word); + +/* J */ +static int smctr_join_complete_state(struct net_device *dev); + +/* L */ +static int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev); +static int smctr_load_firmware(struct net_device *dev); +static int smctr_load_node_addr(struct net_device *dev); +static int smctr_lobe_media_test(struct net_device *dev); +static int smctr_lobe_media_test_cmd(struct net_device *dev); +static int smctr_lobe_media_test_state(struct net_device *dev); + +/* M */ +static int smctr_make_8025_hdr(struct net_device *dev, + MAC_HEADER *rmf, MAC_HEADER *tmf, __u16 ac_fc); +static int smctr_make_access_pri(struct net_device *dev, + MAC_SUB_VECTOR *tsv); +static int smctr_make_addr_mod(struct net_device *dev, MAC_SUB_VECTOR *tsv); +static int smctr_make_auth_funct_class(struct net_device *dev, + MAC_SUB_VECTOR *tsv); +static int smctr_make_corr(struct net_device *dev, + MAC_SUB_VECTOR *tsv, __u16 correlator); +static int smctr_make_funct_addr(struct net_device *dev, + MAC_SUB_VECTOR *tsv); +static int smctr_make_group_addr(struct net_device *dev, + MAC_SUB_VECTOR *tsv); +static int smctr_make_phy_drop_num(struct net_device *dev, + MAC_SUB_VECTOR *tsv); +static int smctr_make_product_id(struct net_device *dev, MAC_SUB_VECTOR *tsv); +static int smctr_make_station_id(struct net_device *dev, MAC_SUB_VECTOR *tsv); +static int smctr_make_ring_station_status(struct net_device *dev, + MAC_SUB_VECTOR *tsv); +static int smctr_make_ring_station_version(struct net_device *dev, + MAC_SUB_VECTOR *tsv); +static int smctr_make_tx_status_code(struct net_device *dev, + MAC_SUB_VECTOR *tsv, __u16 tx_fstatus); +static int smctr_make_upstream_neighbor_addr(struct net_device *dev, + MAC_SUB_VECTOR *tsv); +static int smctr_make_wrap_data(struct net_device *dev, + MAC_SUB_VECTOR *tsv); + +/* O */ +static int smctr_open(struct net_device *dev); +static int smctr_open_tr(struct net_device *dev); + +/* P */ +struct net_device *smctr_probe(int unit); +static int __init smctr_probe1(struct net_device *dev, int ioaddr); +static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, + struct net_device *dev, __u16 rx_status); + +/* R */ +static int smctr_ram_memory_test(struct net_device *dev); +static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf, + __u16 *correlator); +static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf, + __u16 *correlator); +static int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf); +static int smctr_rcv_rq_addr_state_attch(struct net_device *dev, + MAC_HEADER *rmf, __u16 *correlator); +static int smctr_rcv_unknown(struct net_device *dev, MAC_HEADER *rmf, + __u16 *correlator); +static int smctr_reset_adapter(struct net_device *dev); +static int smctr_restart_tx_chain(struct net_device *dev, short queue); +static int smctr_ring_status_chg(struct net_device *dev); +static int smctr_rx_frame(struct net_device *dev); + +/* S */ +static int smctr_send_dat(struct net_device *dev); +static netdev_tx_t smctr_send_packet(struct sk_buff *skb, + struct net_device *dev); +static int smctr_send_lobe_media_test(struct net_device *dev); +static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf, + __u16 correlator); +static int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf, + __u16 correlator); +static int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf, + __u16 correlator); +static int smctr_send_rpt_tx_forward(struct net_device *dev, + MAC_HEADER *rmf, __u16 tx_fstatus); +static int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf, + __u16 rcode, __u16 correlator); +static int smctr_send_rq_init(struct net_device *dev); +static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf, + __u16 *tx_fstatus); +static int smctr_set_auth_access_pri(struct net_device *dev, + MAC_SUB_VECTOR *rsv); +static int smctr_set_auth_funct_class(struct net_device *dev, + MAC_SUB_VECTOR *rsv); +static int smctr_set_corr(struct net_device *dev, MAC_SUB_VECTOR *rsv, + __u16 *correlator); +static int smctr_set_error_timer_value(struct net_device *dev, + MAC_SUB_VECTOR *rsv); +static int smctr_set_frame_forward(struct net_device *dev, + MAC_SUB_VECTOR *rsv, __u8 dc_sc); +static int smctr_set_local_ring_num(struct net_device *dev, + MAC_SUB_VECTOR *rsv); +static unsigned short smctr_set_ctrl_attention(struct net_device *dev); +static void smctr_set_multicast_list(struct net_device *dev); +static int smctr_set_page(struct net_device *dev, __u8 *buf); +static int smctr_set_phy_drop(struct net_device *dev, + MAC_SUB_VECTOR *rsv); +static int smctr_set_ring_speed(struct net_device *dev); +static int smctr_set_rx_look_ahead(struct net_device *dev); +static int smctr_set_trc_reset(int ioaddr); +static int smctr_setup_single_cmd(struct net_device *dev, + __u16 command, __u16 subcommand); +static int smctr_setup_single_cmd_w_data(struct net_device *dev, + __u16 command, __u16 subcommand); +static char *smctr_malloc(struct net_device *dev, __u16 size); +static int smctr_status_chg(struct net_device *dev); + +/* T */ +static void smctr_timeout(struct net_device *dev); +static int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb, + __u16 queue); +static __u16 smctr_tx_complete(struct net_device *dev, __u16 queue); +static unsigned short smctr_tx_move_frame(struct net_device *dev, + struct sk_buff *skb, __u8 *pbuff, unsigned int bytes); + +/* U */ +static int smctr_update_err_stats(struct net_device *dev); +static int smctr_update_rx_chain(struct net_device *dev, __u16 queue); +static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb, + __u16 queue); + +/* W */ +static int smctr_wait_cmd(struct net_device *dev); +static int smctr_wait_while_cbusy(struct net_device *dev); + +#define TO_256_BYTE_BOUNDRY(X) (((X + 0xff) & 0xff00) - X) +#define TO_PARAGRAPH_BOUNDRY(X) (((X + 0x0f) & 0xfff0) - X) +#define PARAGRAPH_BOUNDRY(X) smctr_malloc(dev, TO_PARAGRAPH_BOUNDRY(X)) + +/* Allocate Adapter Shared Memory. + * IMPORTANT NOTE: Any changes to this function MUST be mirrored in the + * function "get_num_rx_bdbs" below!!! + * + * Order of memory allocation: + * + * 0. Initial System Configuration Block Pointer + * 1. System Configuration Block + * 2. System Control Block + * 3. Action Command Block + * 4. Interrupt Status Block + * + * 5. MAC TX FCB'S + * 6. NON-MAC TX FCB'S + * 7. MAC TX BDB'S + * 8. NON-MAC TX BDB'S + * 9. MAC RX FCB'S + * 10. NON-MAC RX FCB'S + * 11. MAC RX BDB'S + * 12. NON-MAC RX BDB'S + * 13. MAC TX Data Buffer( 1, 256 byte buffer) + * 14. MAC RX Data Buffer( 1, 256 byte buffer) + * + * 15. NON-MAC TX Data Buffer + * 16. NON-MAC RX Data Buffer + */ +static int smctr_alloc_shared_memory(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_alloc_shared_memory\n", dev->name); + + /* Allocate initial System Control Block pointer. + * This pointer is located in the last page, last offset - 4. + */ + tp->iscpb_ptr = (ISCPBlock *)(tp->ram_access + ((__u32)64 * 0x400) + - (long)ISCP_BLOCK_SIZE); + + /* Allocate System Control Blocks. */ + tp->scgb_ptr = (SCGBlock *)smctr_malloc(dev, sizeof(SCGBlock)); + PARAGRAPH_BOUNDRY(tp->sh_mem_used); + + tp->sclb_ptr = (SCLBlock *)smctr_malloc(dev, sizeof(SCLBlock)); + PARAGRAPH_BOUNDRY(tp->sh_mem_used); + + tp->acb_head = (ACBlock *)smctr_malloc(dev, + sizeof(ACBlock)*tp->num_acbs); + PARAGRAPH_BOUNDRY(tp->sh_mem_used); + + tp->isb_ptr = (ISBlock *)smctr_malloc(dev, sizeof(ISBlock)); + PARAGRAPH_BOUNDRY(tp->sh_mem_used); + + tp->misc_command_data = (__u16 *)smctr_malloc(dev, MISC_DATA_SIZE); + PARAGRAPH_BOUNDRY(tp->sh_mem_used); + + /* Allocate transmit FCBs. */ + tp->tx_fcb_head[MAC_QUEUE] = (FCBlock *)smctr_malloc(dev, + sizeof(FCBlock) * tp->num_tx_fcbs[MAC_QUEUE]); + + tp->tx_fcb_head[NON_MAC_QUEUE] = (FCBlock *)smctr_malloc(dev, + sizeof(FCBlock) * tp->num_tx_fcbs[NON_MAC_QUEUE]); + + tp->tx_fcb_head[BUG_QUEUE] = (FCBlock *)smctr_malloc(dev, + sizeof(FCBlock) * tp->num_tx_fcbs[BUG_QUEUE]); + + /* Allocate transmit BDBs. */ + tp->tx_bdb_head[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, + sizeof(BDBlock) * tp->num_tx_bdbs[MAC_QUEUE]); + + tp->tx_bdb_head[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, + sizeof(BDBlock) * tp->num_tx_bdbs[NON_MAC_QUEUE]); + + tp->tx_bdb_head[BUG_QUEUE] = (BDBlock *)smctr_malloc(dev, + sizeof(BDBlock) * tp->num_tx_bdbs[BUG_QUEUE]); + + /* Allocate receive FCBs. */ + tp->rx_fcb_head[MAC_QUEUE] = (FCBlock *)smctr_malloc(dev, + sizeof(FCBlock) * tp->num_rx_fcbs[MAC_QUEUE]); + + tp->rx_fcb_head[NON_MAC_QUEUE] = (FCBlock *)smctr_malloc(dev, + sizeof(FCBlock) * tp->num_rx_fcbs[NON_MAC_QUEUE]); + + /* Allocate receive BDBs. */ + tp->rx_bdb_head[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, + sizeof(BDBlock) * tp->num_rx_bdbs[MAC_QUEUE]); + + tp->rx_bdb_end[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, 0); + + tp->rx_bdb_head[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, + sizeof(BDBlock) * tp->num_rx_bdbs[NON_MAC_QUEUE]); + + tp->rx_bdb_end[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, 0); + + /* Allocate MAC transmit buffers. + * MAC Tx Buffers doen't have to be on an ODD Boundary. + */ + tp->tx_buff_head[MAC_QUEUE] + = (__u16 *)smctr_malloc(dev, tp->tx_buff_size[MAC_QUEUE]); + tp->tx_buff_curr[MAC_QUEUE] = tp->tx_buff_head[MAC_QUEUE]; + tp->tx_buff_end [MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0); + + /* Allocate BUG transmit buffers. */ + tp->tx_buff_head[BUG_QUEUE] + = (__u16 *)smctr_malloc(dev, tp->tx_buff_size[BUG_QUEUE]); + tp->tx_buff_curr[BUG_QUEUE] = tp->tx_buff_head[BUG_QUEUE]; + tp->tx_buff_end[BUG_QUEUE] = (__u16 *)smctr_malloc(dev, 0); + + /* Allocate MAC receive data buffers. + * MAC Rx buffer doesn't have to be on a 256 byte boundary. + */ + tp->rx_buff_head[MAC_QUEUE] = (__u16 *)smctr_malloc(dev, + RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[MAC_QUEUE]); + tp->rx_buff_end[MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0); + + /* Allocate Non-MAC transmit buffers. + * ?? For maximum Netware performance, put Tx Buffers on + * ODD Boundary and then restore malloc to Even Boundrys. + */ + smctr_malloc(dev, 1L); + tp->tx_buff_head[NON_MAC_QUEUE] + = (__u16 *)smctr_malloc(dev, tp->tx_buff_size[NON_MAC_QUEUE]); + tp->tx_buff_curr[NON_MAC_QUEUE] = tp->tx_buff_head[NON_MAC_QUEUE]; + tp->tx_buff_end [NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0); + smctr_malloc(dev, 1L); + + /* Allocate Non-MAC receive data buffers. + * To guarantee a minimum of 256 contiguous memory to + * UM_Receive_Packet's lookahead pointer, before a page + * change or ring end is encountered, place each rx buffer on + * a 256 byte boundary. + */ + smctr_malloc(dev, TO_256_BYTE_BOUNDRY(tp->sh_mem_used)); + tp->rx_buff_head[NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev, + RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[NON_MAC_QUEUE]); + tp->rx_buff_end[NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0); + + return 0; +} + +/* Enter Bypass state. */ +static int smctr_bypass_state(struct net_device *dev) +{ + int err; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_bypass_state\n", dev->name); + + err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, JS_BYPASS_STATE); + + return err; +} + +static int smctr_checksum_firmware(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + __u16 i, checksum = 0; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_checksum_firmware\n", dev->name); + + smctr_enable_adapter_ctrl_store(dev); + + for(i = 0; i < CS_RAM_SIZE; i += 2) + checksum += *((__u16 *)(tp->ram_access + i)); + + tp->microcode_version = *(__u16 *)(tp->ram_access + + CS_RAM_VERSION_OFFSET); + tp->microcode_version >>= 8; + + smctr_disable_adapter_ctrl_store(dev); + + if(checksum) + return checksum; + + return 0; +} + +static int __init smctr_chk_mca(struct net_device *dev) +{ +#ifdef CONFIG_MCA_LEGACY + struct net_local *tp = netdev_priv(dev); + int current_slot; + __u8 r1, r2, r3, r4, r5; + + current_slot = mca_find_unused_adapter(smctr_posid, 0); + if(current_slot == MCA_NOTFOUND) + return -ENODEV; + + mca_set_adapter_name(current_slot, smctr_name); + mca_mark_as_used(current_slot); + tp->slot_num = current_slot; + + r1 = mca_read_stored_pos(tp->slot_num, 2); + r2 = mca_read_stored_pos(tp->slot_num, 3); + + if(tp->slot_num) + outb(CNFG_POS_CONTROL_REG, (__u8)((tp->slot_num - 1) | CNFG_SLOT_ENABLE_BIT)); + else + outb(CNFG_POS_CONTROL_REG, (__u8)((tp->slot_num) | CNFG_SLOT_ENABLE_BIT)); + + r1 = inb(CNFG_POS_REG1); + r2 = inb(CNFG_POS_REG0); + + tp->bic_type = BIC_594_CHIP; + + /* IO */ + r2 = mca_read_stored_pos(tp->slot_num, 2); + r2 &= 0xF0; + dev->base_addr = ((__u16)r2 << 8) + (__u16)0x800; + request_region(dev->base_addr, SMCTR_IO_EXTENT, smctr_name); + + /* IRQ */ + r5 = mca_read_stored_pos(tp->slot_num, 5); + r5 &= 0xC; + switch(r5) + { + case 0: + dev->irq = 3; + break; + + case 0x4: + dev->irq = 4; + break; + + case 0x8: + dev->irq = 10; + break; + + default: + dev->irq = 15; + break; + } + if (request_irq(dev->irq, smctr_interrupt, IRQF_SHARED, smctr_name, dev)) { + release_region(dev->base_addr, SMCTR_IO_EXTENT); + return -ENODEV; + } + + /* Get RAM base */ + r3 = mca_read_stored_pos(tp->slot_num, 3); + tp->ram_base = ((__u32)(r3 & 0x7) << 13) + 0x0C0000; + if (r3 & 0x8) + tp->ram_base += 0x010000; + if (r3 & 0x80) + tp->ram_base += 0xF00000; + + /* Get Ram Size */ + r3 &= 0x30; + r3 >>= 4; + + tp->ram_usable = (__u16)CNFG_SIZE_8KB << r3; + tp->ram_size = (__u16)CNFG_SIZE_64KB; + tp->board_id |= TOKEN_MEDIA; + + r4 = mca_read_stored_pos(tp->slot_num, 4); + tp->rom_base = ((__u32)(r4 & 0x7) << 13) + 0x0C0000; + if (r4 & 0x8) + tp->rom_base += 0x010000; + + /* Get ROM size. */ + r4 >>= 4; + switch (r4) { + case 0: + tp->rom_size = CNFG_SIZE_8KB; + break; + case 1: + tp->rom_size = CNFG_SIZE_16KB; + break; + case 2: + tp->rom_size = CNFG_SIZE_32KB; + break; + default: + tp->rom_size = ROM_DISABLE; + } + + /* Get Media Type. */ + r5 = mca_read_stored_pos(tp->slot_num, 5); + r5 &= CNFG_MEDIA_TYPE_MASK; + switch(r5) + { + case (0): + tp->media_type = MEDIA_STP_4; + break; + + case (1): + tp->media_type = MEDIA_STP_16; + break; + + case (3): + tp->media_type = MEDIA_UTP_16; + break; + + default: + tp->media_type = MEDIA_UTP_4; + break; + } + tp->media_menu = 14; + + r2 = mca_read_stored_pos(tp->slot_num, 2); + if(!(r2 & 0x02)) + tp->mode_bits |= EARLY_TOKEN_REL; + + /* Disable slot */ + outb(CNFG_POS_CONTROL_REG, 0); + + tp->board_id = smctr_get_boardid(dev, 1); + switch(tp->board_id & 0xffff) + { + case WD8115TA: + smctr_model = "8115T/A"; + break; + + case WD8115T: + if(tp->extra_info & CHIP_REV_MASK) + smctr_model = "8115T rev XE"; + else + smctr_model = "8115T rev XD"; + break; + + default: + smctr_model = "Unknown"; + break; + } + + return 0; +#else + return -1; +#endif /* CONFIG_MCA_LEGACY */ +} + +static int smctr_chg_rx_mask(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + int err = 0; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_chg_rx_mask\n", dev->name); + + smctr_enable_16bit(dev); + smctr_set_page(dev, (__u8 *)tp->ram_access); + + if(tp->mode_bits & LOOPING_MODE_MASK) + tp->config_word0 |= RX_OWN_BIT; + else + tp->config_word0 &= ~RX_OWN_BIT; + + if(tp->receive_mask & PROMISCUOUS_MODE) + tp->config_word0 |= PROMISCUOUS_BIT; + else + tp->config_word0 &= ~PROMISCUOUS_BIT; + + if(tp->receive_mask & ACCEPT_ERR_PACKETS) + tp->config_word0 |= SAVBAD_BIT; + else + tp->config_word0 &= ~SAVBAD_BIT; + + if(tp->receive_mask & ACCEPT_ATT_MAC_FRAMES) + tp->config_word0 |= RXATMAC; + else + tp->config_word0 &= ~RXATMAC; + + if(tp->receive_mask & ACCEPT_MULTI_PROM) + tp->config_word1 |= MULTICAST_ADDRESS_BIT; + else + tp->config_word1 &= ~MULTICAST_ADDRESS_BIT; + + if(tp->receive_mask & ACCEPT_SOURCE_ROUTING_SPANNING) + tp->config_word1 |= SOURCE_ROUTING_SPANNING_BITS; + else + { + if(tp->receive_mask & ACCEPT_SOURCE_ROUTING) + tp->config_word1 |= SOURCE_ROUTING_EXPLORER_BIT; + else + tp->config_word1 &= ~SOURCE_ROUTING_SPANNING_BITS; + } + + if((err = smctr_issue_write_word_cmd(dev, RW_CONFIG_REGISTER_0, + &tp->config_word0))) + { + return err; + } + + if((err = smctr_issue_write_word_cmd(dev, RW_CONFIG_REGISTER_1, + &tp->config_word1))) + { + return err; + } + + smctr_disable_16bit(dev); + + return 0; +} + +static int smctr_clear_int(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + + outb((tp->trc_mask | CSR_CLRTINT), dev->base_addr + CSR); + + return 0; +} + +static int smctr_clear_trc_reset(int ioaddr) +{ + __u8 r; + + r = inb(ioaddr + MSR); + outb(~MSR_RST & r, ioaddr + MSR); + + return 0; +} + +/* + * The inverse routine to smctr_open(). + */ +static int smctr_close(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + struct sk_buff *skb; + int err; + + netif_stop_queue(dev); + + tp->cleanup = 1; + + /* Check to see if adapter is already in a closed state. */ + if(tp->status != OPEN) + return 0; + + smctr_enable_16bit(dev); + smctr_set_page(dev, (__u8 *)tp->ram_access); + + if((err = smctr_issue_remove_cmd(dev))) + { + smctr_disable_16bit(dev); + return err; + } + + for(;;) + { + skb = skb_dequeue(&tp->SendSkbQueue); + if(skb == NULL) + break; + tp->QueueSkb++; + dev_kfree_skb(skb); + } + + + return 0; +} + +static int smctr_decode_firmware(struct net_device *dev, + const struct firmware *fw) +{ + struct net_local *tp = netdev_priv(dev); + short bit = 0x80, shift = 12; + DECODE_TREE_NODE *tree; + short branch, tsize; + __u16 buff = 0; + long weight; + __u8 *ucode; + __u16 *mem; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_decode_firmware\n", dev->name); + + weight = *(long *)(fw->data + WEIGHT_OFFSET); + tsize = *(__u8 *)(fw->data + TREE_SIZE_OFFSET); + tree = (DECODE_TREE_NODE *)(fw->data + TREE_OFFSET); + ucode = (__u8 *)(fw->data + TREE_OFFSET + + (tsize * sizeof(DECODE_TREE_NODE))); + mem = (__u16 *)(tp->ram_access); + + while(weight) + { + branch = ROOT; + while((tree + branch)->tag != LEAF && weight) + { + branch = *ucode & bit ? (tree + branch)->llink + : (tree + branch)->rlink; + + bit >>= 1; + weight--; + + if(bit == 0) + { + bit = 0x80; + ucode++; + } + } + + buff |= (tree + branch)->info << shift; + shift -= 4; + + if(shift < 0) + { + *(mem++) = SWAP_BYTES(buff); + buff = 0; + shift = 12; + } + } + + /* The following assumes the Control Store Memory has + * been initialized to zero. If the last partial word + * is zero, it will not be written. + */ + if(buff) + *(mem++) = SWAP_BYTES(buff); + + return 0; +} + +static int smctr_disable_16bit(struct net_device *dev) +{ + return 0; +} + +/* + * On Exit, Adapter is: + * 1. TRC is in a reset state and un-initialized. + * 2. Adapter memory is enabled. + * 3. Control Store memory is out of context (-WCSS is 1). + */ +static int smctr_disable_adapter_ctrl_store(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + int ioaddr = dev->base_addr; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_disable_adapter_ctrl_store\n", dev->name); + + tp->trc_mask |= CSR_WCSS; + outb(tp->trc_mask, ioaddr + CSR); + + return 0; +} + +static int smctr_disable_bic_int(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + int ioaddr = dev->base_addr; + + tp->trc_mask = CSR_MSK_ALL | CSR_MSKCBUSY + | CSR_MSKTINT | CSR_WCSS; + outb(tp->trc_mask, ioaddr + CSR); + + return 0; +} + +static int smctr_enable_16bit(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + __u8 r; + + if(tp->adapter_bus == BUS_ISA16_TYPE) + { + r = inb(dev->base_addr + LAAR); + outb((r | LAAR_MEM16ENB), dev->base_addr + LAAR); + } + + return 0; +} + +/* + * To enable the adapter control store memory: + * 1. Adapter must be in a RESET state. + * 2. Adapter memory must be enabled. + * 3. Control Store Memory is in context (-WCSS is 0). + */ +static int smctr_enable_adapter_ctrl_store(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + int ioaddr = dev->base_addr; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_enable_adapter_ctrl_store\n", dev->name); + + smctr_set_trc_reset(ioaddr); + smctr_enable_adapter_ram(dev); + + tp->trc_mask &= ~CSR_WCSS; + outb(tp->trc_mask, ioaddr + CSR); + + return 0; +} + +static int smctr_enable_adapter_ram(struct net_device *dev) +{ + int ioaddr = dev->base_addr; + __u8 r; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_enable_adapter_ram\n", dev->name); + + r = inb(ioaddr + MSR); + outb(MSR_MEMB | r, ioaddr + MSR); + + return 0; +} + +static int smctr_enable_bic_int(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + int ioaddr = dev->base_addr; + __u8 r; + + switch(tp->bic_type) + { + case (BIC_584_CHIP): + tp->trc_mask = CSR_MSKCBUSY | CSR_WCSS; + outb(tp->trc_mask, ioaddr + CSR); + r = inb(ioaddr + IRR); + outb(r | IRR_IEN, ioaddr + IRR); + break; + + case (BIC_594_CHIP): + tp->trc_mask = CSR_MSKCBUSY | CSR_WCSS; + outb(tp->trc_mask, ioaddr + CSR); + r = inb(ioaddr + IMCCR); + outb(r | IMCCR_EIL, ioaddr + IMCCR); + break; + } + + return 0; +} + +static int __init smctr_chk_isa(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + int ioaddr = dev->base_addr; + __u8 r1, r2, b, chksum = 0; + __u16 r; + int i; + int err = -ENODEV; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_chk_isa %#4x\n", dev->name, ioaddr); + + if((ioaddr & 0x1F) != 0) + goto out; + + /* Grab the region so that no one else tries to probe our ioports. */ + if (!request_region(ioaddr, SMCTR_IO_EXTENT, smctr_name)) { + err = -EBUSY; + goto out; + } + + /* Checksum SMC node address */ + for(i = 0; i < 8; i++) + { + b = inb(ioaddr + LAR0 + i); + chksum += b; + } + + if (chksum != NODE_ADDR_CKSUM) + goto out2; + + b = inb(ioaddr + BDID); + if(b != BRD_ID_8115T) + { + printk(KERN_ERR "%s: The adapter found is not supported\n", dev->name); + goto out2; + } + + /* Check for 8115T Board ID */ + r2 = 0; + for(r = 0; r < 8; r++) + { + r1 = inb(ioaddr + 0x8 + r); + r2 += r1; + } + + /* value of RegF adds up the sum to 0xFF */ + if((r2 != 0xFF) && (r2 != 0xEE)) + goto out2; + + /* Get adapter ID */ + tp->board_id = smctr_get_boardid(dev, 0); + switch(tp->board_id & 0xffff) + { + case WD8115TA: + smctr_model = "8115T/A"; + break; + + case WD8115T: + if(tp->extra_info & CHIP_REV_MASK) + smctr_model = "8115T rev XE"; + else + smctr_model = "8115T rev XD"; + break; + + default: + smctr_model = "Unknown"; + break; + } + + /* Store BIC type. */ + tp->bic_type = BIC_584_CHIP; + tp->nic_type = NIC_825_CHIP; + + /* Copy Ram Size */ + tp->ram_usable = CNFG_SIZE_16KB; + tp->ram_size = CNFG_SIZE_64KB; + + /* Get 58x Ram Base */ + r1 = inb(ioaddr); + r1 &= 0x3F; + + r2 = inb(ioaddr + CNFG_LAAR_584); + r2 &= CNFG_LAAR_MASK; + r2 <<= 3; + r2 |= ((r1 & 0x38) >> 3); + + tp->ram_base = ((__u32)r2 << 16) + (((__u32)(r1 & 0x7)) << 13); + + /* Get 584 Irq */ + r1 = 0; + r1 = inb(ioaddr + CNFG_ICR_583); + r1 &= CNFG_ICR_IR2_584; + + r2 = inb(ioaddr + CNFG_IRR_583); + r2 &= CNFG_IRR_IRQS; /* 0x60 */ + r2 >>= 5; + + switch(r2) + { + case 0: + if(r1 == 0) + dev->irq = 2; + else + dev->irq = 10; + break; + + case 1: + if(r1 == 0) + dev->irq = 3; + else + dev->irq = 11; + break; + + case 2: + if(r1 == 0) + { + if(tp->extra_info & ALTERNATE_IRQ_BIT) + dev->irq = 5; + else + dev->irq = 4; + } + else + dev->irq = 15; + break; + + case 3: + if(r1 == 0) + dev->irq = 7; + else + dev->irq = 4; + break; + + default: + printk(KERN_ERR "%s: No IRQ found aborting\n", dev->name); + goto out2; + } + + if (request_irq(dev->irq, smctr_interrupt, IRQF_SHARED, smctr_name, dev)) + goto out2; + + /* Get 58x Rom Base */ + r1 = inb(ioaddr + CNFG_BIO_583); + r1 &= 0x3E; + r1 |= 0x40; + + tp->rom_base = (__u32)r1 << 13; + + /* Get 58x Rom Size */ + r1 = inb(ioaddr + CNFG_BIO_583); + r1 &= 0xC0; + if(r1 == 0) + tp->rom_size = ROM_DISABLE; + else + { + r1 >>= 6; + tp->rom_size = (__u16)CNFG_SIZE_8KB << r1; + } + + /* Get 58x Boot Status */ + r1 = inb(ioaddr + CNFG_GP2); + + tp->mode_bits &= (~BOOT_STATUS_MASK); + + if(r1 & CNFG_GP2_BOOT_NIBBLE) + tp->mode_bits |= BOOT_TYPE_1; + + /* Get 58x Zero Wait State */ + tp->mode_bits &= (~ZERO_WAIT_STATE_MASK); + + r1 = inb(ioaddr + CNFG_IRR_583); + + if(r1 & CNFG_IRR_ZWS) + tp->mode_bits |= ZERO_WAIT_STATE_8_BIT; + + if(tp->board_id & BOARD_16BIT) + { + r1 = inb(ioaddr + CNFG_LAAR_584); + + if(r1 & CNFG_LAAR_ZWS) + tp->mode_bits |= ZERO_WAIT_STATE_16_BIT; + } + + /* Get 584 Media Menu */ + tp->media_menu = 14; + r1 = inb(ioaddr + CNFG_IRR_583); + + tp->mode_bits &= 0xf8ff; /* (~CNFG_INTERFACE_TYPE_MASK) */ + if((tp->board_id & TOKEN_MEDIA) == TOKEN_MEDIA) + { + /* Get Advanced Features */ + if(((r1 & 0x6) >> 1) == 0x3) + tp->media_type |= MEDIA_UTP_16; + else + { + if(((r1 & 0x6) >> 1) == 0x2) + tp->media_type |= MEDIA_STP_16; + else + { + if(((r1 & 0x6) >> 1) == 0x1) + tp->media_type |= MEDIA_UTP_4; + + else + tp->media_type |= MEDIA_STP_4; + } + } + + r1 = inb(ioaddr + CNFG_GP2); + if(!(r1 & 0x2) ) /* GP2_ETRD */ + tp->mode_bits |= EARLY_TOKEN_REL; + + /* see if the chip is corrupted + if(smctr_read_584_chksum(ioaddr)) + { + printk(KERN_ERR "%s: EEPROM Checksum Failure\n", dev->name); + free_irq(dev->irq, dev); + goto out2; + } + */ + } + + return 0; + +out2: + release_region(ioaddr, SMCTR_IO_EXTENT); +out: + return err; +} + +static int __init smctr_get_boardid(struct net_device *dev, int mca) +{ + struct net_local *tp = netdev_priv(dev); + int ioaddr = dev->base_addr; + __u8 r, r1, IdByte; + __u16 BoardIdMask; + + tp->board_id = BoardIdMask = 0; + + if(mca) + { + BoardIdMask |= (MICROCHANNEL+INTERFACE_CHIP+TOKEN_MEDIA+PAGED_RAM+BOARD_16BIT); + tp->extra_info |= (INTERFACE_594_CHIP+RAM_SIZE_64K+NIC_825_BIT+ALTERNATE_IRQ_BIT+SLOT_16BIT); + } + else + { + BoardIdMask|=(INTERFACE_CHIP+TOKEN_MEDIA+PAGED_RAM+BOARD_16BIT); + tp->extra_info |= (INTERFACE_584_CHIP + RAM_SIZE_64K + + NIC_825_BIT + ALTERNATE_IRQ_BIT); + } + + if(!mca) + { + r = inb(ioaddr + BID_REG_1); + r &= 0x0c; + outb(r, ioaddr + BID_REG_1); + r = inb(ioaddr + BID_REG_1); + + if(r & BID_SIXTEEN_BIT_BIT) + { + tp->extra_info |= SLOT_16BIT; + tp->adapter_bus = BUS_ISA16_TYPE; + } + else + tp->adapter_bus = BUS_ISA8_TYPE; + } + else + tp->adapter_bus = BUS_MCA_TYPE; + + /* Get Board Id Byte */ + IdByte = inb(ioaddr + BID_BOARD_ID_BYTE); + + /* if Major version > 1.0 then + * return; + */ + if(IdByte & 0xF8) + return -1; + + r1 = inb(ioaddr + BID_REG_1); + r1 &= BID_ICR_MASK; + r1 |= BID_OTHER_BIT; + + outb(r1, ioaddr + BID_REG_1); + r1 = inb(ioaddr + BID_REG_3); + + r1 &= BID_EAR_MASK; + r1 |= BID_ENGR_PAGE; + + outb(r1, ioaddr + BID_REG_3); + r1 = inb(ioaddr + BID_REG_1); + r1 &= BID_ICR_MASK; + r1 |= (BID_RLA | BID_OTHER_BIT); + + outb(r1, ioaddr + BID_REG_1); + + r1 = inb(ioaddr + BID_REG_1); + while(r1 & BID_RECALL_DONE_MASK) + r1 = inb(ioaddr + BID_REG_1); + + r = inb(ioaddr + BID_LAR_0 + BID_REG_6); + + /* clear chip rev bits */ + tp->extra_info &= ~CHIP_REV_MASK; + tp->extra_info |= ((r & BID_EEPROM_CHIP_REV_MASK) << 6); + + r1 = inb(ioaddr + BID_REG_1); + r1 &= BID_ICR_MASK; + r1 |= BID_OTHER_BIT; + + outb(r1, ioaddr + BID_REG_1); + r1 = inb(ioaddr + BID_REG_3); + + r1 &= BID_EAR_MASK; + r1 |= BID_EA6; + + outb(r1, ioaddr + BID_REG_3); + r1 = inb(ioaddr + BID_REG_1); + + r1 &= BID_ICR_MASK; + r1 |= BID_RLA; + + outb(r1, ioaddr + BID_REG_1); + r1 = inb(ioaddr + BID_REG_1); + + while(r1 & BID_RECALL_DONE_MASK) + r1 = inb(ioaddr + BID_REG_1); + + return BoardIdMask; +} + +static int smctr_get_group_address(struct net_device *dev) +{ + smctr_issue_read_word_cmd(dev, RW_INDIVIDUAL_GROUP_ADDR); + + return smctr_wait_cmd(dev); +} + +static int smctr_get_functional_address(struct net_device *dev) +{ + smctr_issue_read_word_cmd(dev, RW_FUNCTIONAL_ADDR); + + return smctr_wait_cmd(dev); +} + +/* Calculate number of Non-MAC receive BDB's and data buffers. + * This function must simulate allocateing shared memory exactly + * as the allocate_shared_memory function above. + */ +static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned int mem_used = 0; + + /* Allocate System Control Blocks. */ + mem_used += sizeof(SCGBlock); + + mem_used += TO_PARAGRAPH_BOUNDRY(mem_used); + mem_used += sizeof(SCLBlock); + + mem_used += TO_PARAGRAPH_BOUNDRY(mem_used); + mem_used += sizeof(ACBlock) * tp->num_acbs; + + mem_used += TO_PARAGRAPH_BOUNDRY(mem_used); + mem_used += sizeof(ISBlock); + + mem_used += TO_PARAGRAPH_BOUNDRY(mem_used); + mem_used += MISC_DATA_SIZE; + + /* Allocate transmit FCB's. */ + mem_used += TO_PARAGRAPH_BOUNDRY(mem_used); + + mem_used += sizeof(FCBlock) * tp->num_tx_fcbs[MAC_QUEUE]; + mem_used += sizeof(FCBlock) * tp->num_tx_fcbs[NON_MAC_QUEUE]; + mem_used += sizeof(FCBlock) * tp->num_tx_fcbs[BUG_QUEUE]; + + /* Allocate transmit BDBs. */ + mem_used += sizeof(BDBlock) * tp->num_tx_bdbs[MAC_QUEUE]; + mem_used += sizeof(BDBlock) * tp->num_tx_bdbs[NON_MAC_QUEUE]; + mem_used += sizeof(BDBlock) * tp->num_tx_bdbs[BUG_QUEUE]; + + /* Allocate receive FCBs. */ + mem_used += sizeof(FCBlock) * tp->num_rx_fcbs[MAC_QUEUE]; + mem_used += sizeof(FCBlock) * tp->num_rx_fcbs[NON_MAC_QUEUE]; + + /* Allocate receive BDBs. */ + mem_used += sizeof(BDBlock) * tp->num_rx_bdbs[MAC_QUEUE]; + + /* Allocate MAC transmit buffers. + * MAC transmit buffers don't have to be on an ODD Boundary. + */ + mem_used += tp->tx_buff_size[MAC_QUEUE]; + + /* Allocate BUG transmit buffers. */ + mem_used += tp->tx_buff_size[BUG_QUEUE]; + + /* Allocate MAC receive data buffers. + * MAC receive buffers don't have to be on a 256 byte boundary. + */ + mem_used += RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[MAC_QUEUE]; + + /* Allocate Non-MAC transmit buffers. + * For maximum Netware performance, put Tx Buffers on + * ODD Boundary,and then restore malloc to Even Boundrys. + */ + mem_used += 1L; + mem_used += tp->tx_buff_size[NON_MAC_QUEUE]; + mem_used += 1L; + + /* CALCULATE NUMBER OF NON-MAC RX BDB'S + * AND NON-MAC RX DATA BUFFERS + * + * Make sure the mem_used offset at this point is the + * same as in allocate_shared memory or the following + * boundary adjustment will be incorrect (i.e. not allocating + * the non-mac receive buffers above cannot change the 256 + * byte offset). + * + * Since this cannot be guaranteed, adding the full 256 bytes + * to the amount of shared memory used at this point will guaranteed + * that the rx data buffers do not overflow shared memory. + */ + mem_used += 0x100; + + return (0xffff - mem_used) / (RX_DATA_BUFFER_SIZE + sizeof(BDBlock)); +} + +static int smctr_get_physical_drop_number(struct net_device *dev) +{ + smctr_issue_read_word_cmd(dev, RW_PHYSICAL_DROP_NUMBER); + + return smctr_wait_cmd(dev); +} + +static __u8 * smctr_get_rx_pointer(struct net_device *dev, short queue) +{ + struct net_local *tp = netdev_priv(dev); + BDBlock *bdb; + + bdb = (BDBlock *)((__u32)tp->ram_access + + (__u32)(tp->rx_fcb_curr[queue]->trc_bdb_ptr)); + + tp->rx_fcb_curr[queue]->bdb_ptr = bdb; + + return (__u8 *)bdb->data_block_ptr; +} + +static int smctr_get_station_id(struct net_device *dev) +{ + smctr_issue_read_word_cmd(dev, RW_INDIVIDUAL_MAC_ADDRESS); + + return smctr_wait_cmd(dev); +} + +/* + * Get the current statistics. This may be called with the card open + * or closed. + */ +static struct net_device_stats *smctr_get_stats(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + + return (struct net_device_stats *)&tp->MacStat; +} + +static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue, + __u16 bytes_count) +{ + struct net_local *tp = netdev_priv(dev); + FCBlock *pFCB; + BDBlock *pbdb; + unsigned short alloc_size; + unsigned short *temp; + + if(smctr_debug > 20) + printk(KERN_DEBUG "smctr_get_tx_fcb\n"); + + /* check if there is enough FCB blocks */ + if(tp->num_tx_fcbs_used[queue] >= tp->num_tx_fcbs[queue]) + return (FCBlock *)(-1L); + + /* round off the input pkt size to the nearest even number */ + alloc_size = (bytes_count + 1) & 0xfffe; + + /* check if enough mem */ + if((tp->tx_buff_used[queue] + alloc_size) > tp->tx_buff_size[queue]) + return (FCBlock *)(-1L); + + /* check if past the end ; + * if exactly enough mem to end of ring, alloc from front. + * this avoids update of curr when curr = end + */ + if(((unsigned long)(tp->tx_buff_curr[queue]) + alloc_size) + >= (unsigned long)(tp->tx_buff_end[queue])) + { + /* check if enough memory from ring head */ + alloc_size = alloc_size + + (__u16)((__u32)tp->tx_buff_end[queue] + - (__u32)tp->tx_buff_curr[queue]); + + if((tp->tx_buff_used[queue] + alloc_size) + > tp->tx_buff_size[queue]) + { + return (FCBlock *)(-1L); + } + + /* ring wrap */ + tp->tx_buff_curr[queue] = tp->tx_buff_head[queue]; + } + + tp->tx_buff_used[queue] += alloc_size; + tp->num_tx_fcbs_used[queue]++; + tp->tx_fcb_curr[queue]->frame_length = bytes_count; + tp->tx_fcb_curr[queue]->memory_alloc = alloc_size; + temp = tp->tx_buff_curr[queue]; + tp->tx_buff_curr[queue] + = (__u16 *)((__u32)temp + (__u32)((bytes_count + 1) & 0xfffe)); + + pbdb = tp->tx_fcb_curr[queue]->bdb_ptr; + pbdb->buffer_length = bytes_count; + pbdb->data_block_ptr = temp; + pbdb->trc_data_block_ptr = TRC_POINTER(temp); + + pFCB = tp->tx_fcb_curr[queue]; + tp->tx_fcb_curr[queue] = tp->tx_fcb_curr[queue]->next_ptr; + + return pFCB; +} + +static int smctr_get_upstream_neighbor_addr(struct net_device *dev) +{ + smctr_issue_read_word_cmd(dev, RW_UPSTREAM_NEIGHBOR_ADDRESS); + + return smctr_wait_cmd(dev); +} + +static int smctr_hardware_send_packet(struct net_device *dev, + struct net_local *tp) +{ + struct tr_statistics *tstat = &tp->MacStat; + struct sk_buff *skb; + FCBlock *fcb; + + if(smctr_debug > 10) + printk(KERN_DEBUG"%s: smctr_hardware_send_packet\n", dev->name); + + if(tp->status != OPEN) + return -1; + + if(tp->monitor_state_ready != 1) + return -1; + + for(;;) + { + /* Send first buffer from queue */ + skb = skb_dequeue(&tp->SendSkbQueue); + if(skb == NULL) + return -1; + + tp->QueueSkb++; + + if(skb->len < SMC_HEADER_SIZE || skb->len > tp->max_packet_size) + return -1; + + smctr_enable_16bit(dev); + smctr_set_page(dev, (__u8 *)tp->ram_access); + + if((fcb = smctr_get_tx_fcb(dev, NON_MAC_QUEUE, skb->len)) + == (FCBlock *)(-1L)) + { + smctr_disable_16bit(dev); + return -1; + } + + smctr_tx_move_frame(dev, skb, + (__u8 *)fcb->bdb_ptr->data_block_ptr, skb->len); + + smctr_set_page(dev, (__u8 *)fcb); + + smctr_trc_send_packet(dev, fcb, NON_MAC_QUEUE); + dev_kfree_skb(skb); + + tstat->tx_packets++; + + smctr_disable_16bit(dev); + } + + return 0; +} + +static int smctr_init_acbs(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned int i; + ACBlock *acb; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_init_acbs\n", dev->name); + + acb = tp->acb_head; + acb->cmd_done_status = (ACB_COMMAND_DONE | ACB_COMMAND_SUCCESSFUL); + acb->cmd_info = ACB_CHAIN_END; + acb->cmd = 0; + acb->subcmd = 0; + acb->data_offset_lo = 0; + acb->data_offset_hi = 0; + acb->next_ptr + = (ACBlock *)(((char *)acb) + sizeof(ACBlock)); + acb->trc_next_ptr = TRC_POINTER(acb->next_ptr); + + for(i = 1; i < tp->num_acbs; i++) + { + acb = acb->next_ptr; + acb->cmd_done_status + = (ACB_COMMAND_DONE | ACB_COMMAND_SUCCESSFUL); + acb->cmd_info = ACB_CHAIN_END; + acb->cmd = 0; + acb->subcmd = 0; + acb->data_offset_lo = 0; + acb->data_offset_hi = 0; + acb->next_ptr + = (ACBlock *)(((char *)acb) + sizeof(ACBlock)); + acb->trc_next_ptr = TRC_POINTER(acb->next_ptr); + } + + acb->next_ptr = tp->acb_head; + acb->trc_next_ptr = TRC_POINTER(tp->acb_head); + tp->acb_next = tp->acb_head->next_ptr; + tp->acb_curr = tp->acb_head->next_ptr; + tp->num_acbs_used = 0; + + return 0; +} + +static int smctr_init_adapter(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + int err; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_init_adapter\n", dev->name); + + tp->status = CLOSED; + tp->page_offset_mask = (tp->ram_usable * 1024) - 1; + skb_queue_head_init(&tp->SendSkbQueue); + tp->QueueSkb = MAX_TX_QUEUE; + + if(!(tp->group_address_0 & 0x0080)) + tp->group_address_0 |= 0x00C0; + + if(!(tp->functional_address_0 & 0x00C0)) + tp->functional_address_0 |= 0x00C0; + + tp->functional_address[0] &= 0xFF7F; + + if(tp->authorized_function_classes == 0) + tp->authorized_function_classes = 0x7FFF; + + if(tp->authorized_access_priority == 0) + tp->authorized_access_priority = 0x06; + + smctr_disable_bic_int(dev); + smctr_set_trc_reset(dev->base_addr); + + smctr_enable_16bit(dev); + smctr_set_page(dev, (__u8 *)tp->ram_access); + + if(smctr_checksum_firmware(dev)) + { + printk(KERN_ERR "%s: Previously loaded firmware is missing\n",dev->name); + return -ENOENT; + } + + if((err = smctr_ram_memory_test(dev))) + { + printk(KERN_ERR "%s: RAM memory test failed.\n", dev->name); + return -EIO; + } + + smctr_set_rx_look_ahead(dev); + smctr_load_node_addr(dev); + + /* Initialize adapter for Internal Self Test. */ + smctr_reset_adapter(dev); + if((err = smctr_init_card_real(dev))) + { + printk(KERN_ERR "%s: Initialization of card failed (%d)\n", + dev->name, err); + return -EINVAL; + } + + /* This routine clobbers the TRC's internal registers. */ + if((err = smctr_internal_self_test(dev))) + { + printk(KERN_ERR "%s: Card failed internal self test (%d)\n", + dev->name, err); + return -EINVAL; + } + + /* Re-Initialize adapter's internal registers */ + smctr_reset_adapter(dev); + if((err = smctr_init_card_real(dev))) + { + printk(KERN_ERR "%s: Initialization of card failed (%d)\n", + dev->name, err); + return -EINVAL; + } + + smctr_enable_bic_int(dev); + + if((err = smctr_issue_enable_int_cmd(dev, TRC_INTERRUPT_ENABLE_MASK))) + return err; + + smctr_disable_16bit(dev); + + return 0; +} + +static int smctr_init_card_real(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + int err = 0; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_init_card_real\n", dev->name); + + tp->sh_mem_used = 0; + tp->num_acbs = NUM_OF_ACBS; + + /* Range Check Max Packet Size */ + if(tp->max_packet_size < 256) + tp->max_packet_size = 256; + else + { + if(tp->max_packet_size > NON_MAC_TX_BUFFER_MEMORY) + tp->max_packet_size = NON_MAC_TX_BUFFER_MEMORY; + } + + tp->num_of_tx_buffs = (NON_MAC_TX_BUFFER_MEMORY + / tp->max_packet_size) - 1; + + if(tp->num_of_tx_buffs > NUM_NON_MAC_TX_FCBS) + tp->num_of_tx_buffs = NUM_NON_MAC_TX_FCBS; + else + { + if(tp->num_of_tx_buffs == 0) + tp->num_of_tx_buffs = 1; + } + + /* Tx queue constants */ + tp->num_tx_fcbs [BUG_QUEUE] = NUM_BUG_TX_FCBS; + tp->num_tx_bdbs [BUG_QUEUE] = NUM_BUG_TX_BDBS; + tp->tx_buff_size [BUG_QUEUE] = BUG_TX_BUFFER_MEMORY; + tp->tx_buff_used [BUG_QUEUE] = 0; + tp->tx_queue_status [BUG_QUEUE] = NOT_TRANSMITING; + + tp->num_tx_fcbs [MAC_QUEUE] = NUM_MAC_TX_FCBS; + tp->num_tx_bdbs [MAC_QUEUE] = NUM_MAC_TX_BDBS; + tp->tx_buff_size [MAC_QUEUE] = MAC_TX_BUFFER_MEMORY; + tp->tx_buff_used [MAC_QUEUE] = 0; + tp->tx_queue_status [MAC_QUEUE] = NOT_TRANSMITING; + + tp->num_tx_fcbs [NON_MAC_QUEUE] = NUM_NON_MAC_TX_FCBS; + tp->num_tx_bdbs [NON_MAC_QUEUE] = NUM_NON_MAC_TX_BDBS; + tp->tx_buff_size [NON_MAC_QUEUE] = NON_MAC_TX_BUFFER_MEMORY; + tp->tx_buff_used [NON_MAC_QUEUE] = 0; + tp->tx_queue_status [NON_MAC_QUEUE] = NOT_TRANSMITING; + + /* Receive Queue Constants */ + tp->num_rx_fcbs[MAC_QUEUE] = NUM_MAC_RX_FCBS; + tp->num_rx_bdbs[MAC_QUEUE] = NUM_MAC_RX_BDBS; + + if(tp->extra_info & CHIP_REV_MASK) + tp->num_rx_fcbs[NON_MAC_QUEUE] = 78; /* 825 Rev. XE */ + else + tp->num_rx_fcbs[NON_MAC_QUEUE] = 7; /* 825 Rev. XD */ + + tp->num_rx_bdbs[NON_MAC_QUEUE] = smctr_get_num_rx_bdbs(dev); + + smctr_alloc_shared_memory(dev); + smctr_init_shared_memory(dev); + + if((err = smctr_issue_init_timers_cmd(dev))) + return err; + + if((err = smctr_issue_init_txrx_cmd(dev))) + { + printk(KERN_ERR "%s: Hardware failure\n", dev->name); + return err; + } + + return 0; +} + +static int smctr_init_rx_bdbs(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned int i, j; + BDBlock *bdb; + __u16 *buf; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_init_rx_bdbs\n", dev->name); + + for(i = 0; i < NUM_RX_QS_USED; i++) + { + bdb = tp->rx_bdb_head[i]; + buf = tp->rx_buff_head[i]; + bdb->info = (BDB_CHAIN_END | BDB_NO_WARNING); + bdb->buffer_length = RX_DATA_BUFFER_SIZE; + bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock)); + bdb->data_block_ptr = buf; + bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr); + + if(i == NON_MAC_QUEUE) + bdb->trc_data_block_ptr = RX_BUFF_TRC_POINTER(buf); + else + bdb->trc_data_block_ptr = TRC_POINTER(buf); + + for(j = 1; j < tp->num_rx_bdbs[i]; j++) + { + bdb->next_ptr->back_ptr = bdb; + bdb = bdb->next_ptr; + buf = (__u16 *)((char *)buf + RX_DATA_BUFFER_SIZE); + bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING); + bdb->buffer_length = RX_DATA_BUFFER_SIZE; + bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock)); + bdb->data_block_ptr = buf; + bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr); + + if(i == NON_MAC_QUEUE) + bdb->trc_data_block_ptr = RX_BUFF_TRC_POINTER(buf); + else + bdb->trc_data_block_ptr = TRC_POINTER(buf); + } + + bdb->next_ptr = tp->rx_bdb_head[i]; + bdb->trc_next_ptr = TRC_POINTER(tp->rx_bdb_head[i]); + + tp->rx_bdb_head[i]->back_ptr = bdb; + tp->rx_bdb_curr[i] = tp->rx_bdb_head[i]->next_ptr; + } + + return 0; +} + +static int smctr_init_rx_fcbs(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned int i, j; + FCBlock *fcb; + + for(i = 0; i < NUM_RX_QS_USED; i++) + { + fcb = tp->rx_fcb_head[i]; + fcb->frame_status = 0; + fcb->frame_length = 0; + fcb->info = FCB_CHAIN_END; + fcb->next_ptr = (FCBlock *)(((char*)fcb) + sizeof(FCBlock)); + if(i == NON_MAC_QUEUE) + fcb->trc_next_ptr = RX_FCB_TRC_POINTER(fcb->next_ptr); + else + fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr); + + for(j = 1; j < tp->num_rx_fcbs[i]; j++) + { + fcb->next_ptr->back_ptr = fcb; + fcb = fcb->next_ptr; + fcb->frame_status = 0; + fcb->frame_length = 0; + fcb->info = FCB_WARNING; + fcb->next_ptr + = (FCBlock *)(((char *)fcb) + sizeof(FCBlock)); + + if(i == NON_MAC_QUEUE) + fcb->trc_next_ptr + = RX_FCB_TRC_POINTER(fcb->next_ptr); + else + fcb->trc_next_ptr + = TRC_POINTER(fcb->next_ptr); + } + + fcb->next_ptr = tp->rx_fcb_head[i]; + + if(i == NON_MAC_QUEUE) + fcb->trc_next_ptr = RX_FCB_TRC_POINTER(fcb->next_ptr); + else + fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr); + + tp->rx_fcb_head[i]->back_ptr = fcb; + tp->rx_fcb_curr[i] = tp->rx_fcb_head[i]->next_ptr; + } + + return 0; +} + +static int smctr_init_shared_memory(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned int i; + __u32 *iscpb; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_init_shared_memory\n", dev->name); + + smctr_set_page(dev, (__u8 *)(unsigned int)tp->iscpb_ptr); + + /* Initialize Initial System Configuration Point. (ISCP) */ + iscpb = (__u32 *)PAGE_POINTER(&tp->iscpb_ptr->trc_scgb_ptr); + *iscpb = (__u32)(SWAP_WORDS(TRC_POINTER(tp->scgb_ptr))); + + smctr_set_page(dev, (__u8 *)tp->ram_access); + + /* Initialize System Configuration Pointers. (SCP) */ + tp->scgb_ptr->config = (SCGB_ADDRESS_POINTER_FORMAT + | SCGB_MULTI_WORD_CONTROL | SCGB_DATA_FORMAT + | SCGB_BURST_LENGTH); + + tp->scgb_ptr->trc_sclb_ptr = TRC_POINTER(tp->sclb_ptr); + tp->scgb_ptr->trc_acb_ptr = TRC_POINTER(tp->acb_head); + tp->scgb_ptr->trc_isb_ptr = TRC_POINTER(tp->isb_ptr); + tp->scgb_ptr->isbsiz = (sizeof(ISBlock)) - 2; + + /* Initialize System Control Block. (SCB) */ + tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_NOP; + tp->sclb_ptr->iack_code = 0; + tp->sclb_ptr->resume_control = 0; + tp->sclb_ptr->int_mask_control = 0; + tp->sclb_ptr->int_mask_state = 0; + + /* Initialize Interrupt Status Block. (ISB) */ + for(i = 0; i < NUM_OF_INTERRUPTS; i++) + { + tp->isb_ptr->IStatus[i].IType = 0xf0; + tp->isb_ptr->IStatus[i].ISubtype = 0; + } + + tp->current_isb_index = 0; + + /* Initialize Action Command Block. (ACB) */ + smctr_init_acbs(dev); + + /* Initialize transmit FCB's and BDB's. */ + smctr_link_tx_fcbs_to_bdbs(dev); + smctr_init_tx_bdbs(dev); + smctr_init_tx_fcbs(dev); + + /* Initialize receive FCB's and BDB's. */ + smctr_init_rx_bdbs(dev); + smctr_init_rx_fcbs(dev); + + return 0; +} + +static int smctr_init_tx_bdbs(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned int i, j; + BDBlock *bdb; + + for(i = 0; i < NUM_TX_QS_USED; i++) + { + bdb = tp->tx_bdb_head[i]; + bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING); + bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock)); + bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr); + + for(j = 1; j < tp->num_tx_bdbs[i]; j++) + { + bdb->next_ptr->back_ptr = bdb; + bdb = bdb->next_ptr; + bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING); + bdb->next_ptr + = (BDBlock *)(((char *)bdb) + sizeof( BDBlock)); bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr); + } + + bdb->next_ptr = tp->tx_bdb_head[i]; + bdb->trc_next_ptr = TRC_POINTER(tp->tx_bdb_head[i]); + tp->tx_bdb_head[i]->back_ptr = bdb; + } + + return 0; +} + +static int smctr_init_tx_fcbs(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned int i, j; + FCBlock *fcb; + + for(i = 0; i < NUM_TX_QS_USED; i++) + { + fcb = tp->tx_fcb_head[i]; + fcb->frame_status = 0; + fcb->frame_length = 0; + fcb->info = FCB_CHAIN_END; + fcb->next_ptr = (FCBlock *)(((char *)fcb) + sizeof(FCBlock)); + fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr); + + for(j = 1; j < tp->num_tx_fcbs[i]; j++) + { + fcb->next_ptr->back_ptr = fcb; + fcb = fcb->next_ptr; + fcb->frame_status = 0; + fcb->frame_length = 0; + fcb->info = FCB_CHAIN_END; + fcb->next_ptr + = (FCBlock *)(((char *)fcb) + sizeof(FCBlock)); + fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr); + } + + fcb->next_ptr = tp->tx_fcb_head[i]; + fcb->trc_next_ptr = TRC_POINTER(tp->tx_fcb_head[i]); + + tp->tx_fcb_head[i]->back_ptr = fcb; + tp->tx_fcb_end[i] = tp->tx_fcb_head[i]->next_ptr; + tp->tx_fcb_curr[i] = tp->tx_fcb_head[i]->next_ptr; + tp->num_tx_fcbs_used[i] = 0; + } + + return 0; +} + +static int smctr_internal_self_test(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + int err; + + if((err = smctr_issue_test_internal_rom_cmd(dev))) + return err; + + if((err = smctr_wait_cmd(dev))) + return err; + + if(tp->acb_head->cmd_done_status & 0xff) + return -1; + + if((err = smctr_issue_test_hic_cmd(dev))) + return err; + + if((err = smctr_wait_cmd(dev))) + return err; + + if(tp->acb_head->cmd_done_status & 0xff) + return -1; + + if((err = smctr_issue_test_mac_reg_cmd(dev))) + return err; + + if((err = smctr_wait_cmd(dev))) + return err; + + if(tp->acb_head->cmd_done_status & 0xff) + return -1; + + return 0; +} + +/* + * The typical workload of the driver: Handle the network interface interrupts. + */ +static irqreturn_t smctr_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct net_local *tp; + int ioaddr; + __u16 interrupt_unmask_bits = 0, interrupt_ack_code = 0xff00; + __u16 err1, err = NOT_MY_INTERRUPT; + __u8 isb_type, isb_subtype; + __u16 isb_index; + + ioaddr = dev->base_addr; + tp = netdev_priv(dev); + + if(tp->status == NOT_INITIALIZED) + return IRQ_NONE; + + spin_lock(&tp->lock); + + smctr_disable_bic_int(dev); + smctr_enable_16bit(dev); + + smctr_clear_int(dev); + + /* First read the LSB */ + while((tp->isb_ptr->IStatus[tp->current_isb_index].IType & 0xf0) == 0) + { + isb_index = tp->current_isb_index; + isb_type = tp->isb_ptr->IStatus[isb_index].IType; + isb_subtype = tp->isb_ptr->IStatus[isb_index].ISubtype; + + (tp->current_isb_index)++; + if(tp->current_isb_index == NUM_OF_INTERRUPTS) + tp->current_isb_index = 0; + + if(isb_type >= 0x10) + { + smctr_disable_16bit(dev); + spin_unlock(&tp->lock); + return IRQ_HANDLED; + } + + err = HARDWARE_FAILED; + interrupt_ack_code = isb_index; + tp->isb_ptr->IStatus[isb_index].IType |= 0xf0; + + interrupt_unmask_bits |= (1 << (__u16)isb_type); + + switch(isb_type) + { + case ISB_IMC_MAC_TYPE_3: + smctr_disable_16bit(dev); + + switch(isb_subtype) + { + case 0: + tp->monitor_state = MS_MONITOR_FSM_INACTIVE; + break; + + case 1: + tp->monitor_state = MS_REPEAT_BEACON_STATE; + break; + + case 2: + tp->monitor_state = MS_REPEAT_CLAIM_TOKEN_STATE; + break; + + case 3: + tp->monitor_state = MS_TRANSMIT_CLAIM_TOKEN_STATE; break; + + case 4: + tp->monitor_state = MS_STANDBY_MONITOR_STATE; + break; + + case 5: + tp->monitor_state = MS_TRANSMIT_BEACON_STATE; + break; + + case 6: + tp->monitor_state = MS_ACTIVE_MONITOR_STATE; + break; + + case 7: + tp->monitor_state = MS_TRANSMIT_RING_PURGE_STATE; + break; + + case 8: /* diagnostic state */ + break; + + case 9: + tp->monitor_state = MS_BEACON_TEST_STATE; + if(smctr_lobe_media_test(dev)) + { + tp->ring_status_flags = RING_STATUS_CHANGED; + tp->ring_status = AUTO_REMOVAL_ERROR; + smctr_ring_status_chg(dev); + smctr_bypass_state(dev); + } + else + smctr_issue_insert_cmd(dev); + break; + + /* case 0x0a-0xff, illegal states */ + default: + break; + } + + tp->ring_status_flags = MONITOR_STATE_CHANGED; + err = smctr_ring_status_chg(dev); + + smctr_enable_16bit(dev); + break; + + /* Type 0x02 - MAC Error Counters Interrupt + * One or more MAC Error Counter is half full + * MAC Error Counters + * Lost_FR_Error_Counter + * RCV_Congestion_Counter + * FR_copied_Error_Counter + * FREQ_Error_Counter + * Token_Error_Counter + * Line_Error_Counter + * Internal_Error_Count + */ + case ISB_IMC_MAC_ERROR_COUNTERS: + /* Read 802.5 Error Counters */ + err = smctr_issue_read_ring_status_cmd(dev); + break; + + /* Type 0x04 - MAC Type 2 Interrupt + * HOST needs to enqueue MAC Frame for transmission + * SubType Bit 15 - RQ_INIT_PDU( Request Initialization) * Changed from RQ_INIT_PDU to + * TRC_Status_Changed_Indicate + */ + case ISB_IMC_MAC_TYPE_2: + err = smctr_issue_read_ring_status_cmd(dev); + break; + + + /* Type 0x05 - TX Frame Interrupt (FI). */ + case ISB_IMC_TX_FRAME: + /* BUG QUEUE for TRC stuck receive BUG */ + if(isb_subtype & TX_PENDING_PRIORITY_2) + { + if((err = smctr_tx_complete(dev, BUG_QUEUE)) != SUCCESS) + break; + } + + /* NON-MAC frames only */ + if(isb_subtype & TX_PENDING_PRIORITY_1) + { + if((err = smctr_tx_complete(dev, NON_MAC_QUEUE)) != SUCCESS) + break; + } + + /* MAC frames only */ + if(isb_subtype & TX_PENDING_PRIORITY_0) + err = smctr_tx_complete(dev, MAC_QUEUE); break; + + /* Type 0x06 - TX END OF QUEUE (FE) */ + case ISB_IMC_END_OF_TX_QUEUE: + /* BUG queue */ + if(isb_subtype & TX_PENDING_PRIORITY_2) + { + /* ok to clear Receive FIFO overrun + * imask send_BUG now completes. + */ + interrupt_unmask_bits |= 0x800; + + tp->tx_queue_status[BUG_QUEUE] = NOT_TRANSMITING; + if((err = smctr_tx_complete(dev, BUG_QUEUE)) != SUCCESS) + break; + if((err = smctr_restart_tx_chain(dev, BUG_QUEUE)) != SUCCESS) + break; + } + + /* NON-MAC queue only */ + if(isb_subtype & TX_PENDING_PRIORITY_1) + { + tp->tx_queue_status[NON_MAC_QUEUE] = NOT_TRANSMITING; + if((err = smctr_tx_complete(dev, NON_MAC_QUEUE)) != SUCCESS) + break; + if((err = smctr_restart_tx_chain(dev, NON_MAC_QUEUE)) != SUCCESS) + break; + } + + /* MAC queue only */ + if(isb_subtype & TX_PENDING_PRIORITY_0) + { + tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING; + if((err = smctr_tx_complete(dev, MAC_QUEUE)) != SUCCESS) + break; + + err = smctr_restart_tx_chain(dev, MAC_QUEUE); + } + break; + + /* Type 0x07 - NON-MAC RX Resource Interrupt + * Subtype bit 12 - (BW) BDB warning + * Subtype bit 13 - (FW) FCB warning + * Subtype bit 14 - (BE) BDB End of chain + * Subtype bit 15 - (FE) FCB End of chain + */ + case ISB_IMC_NON_MAC_RX_RESOURCE: + tp->rx_fifo_overrun_count = 0; + tp->receive_queue_number = NON_MAC_QUEUE; + err1 = smctr_rx_frame(dev); + + if(isb_subtype & NON_MAC_RX_RESOURCE_FE) + { + if((err = smctr_issue_resume_rx_fcb_cmd( dev, NON_MAC_QUEUE)) != SUCCESS) break; + + if(tp->ptr_rx_fcb_overruns) + (*tp->ptr_rx_fcb_overruns)++; + } + + if(isb_subtype & NON_MAC_RX_RESOURCE_BE) + { + if((err = smctr_issue_resume_rx_bdb_cmd( dev, NON_MAC_QUEUE)) != SUCCESS) break; + + if(tp->ptr_rx_bdb_overruns) + (*tp->ptr_rx_bdb_overruns)++; + } + err = err1; + break; + + /* Type 0x08 - MAC RX Resource Interrupt + * Subtype bit 12 - (BW) BDB warning + * Subtype bit 13 - (FW) FCB warning + * Subtype bit 14 - (BE) BDB End of chain + * Subtype bit 15 - (FE) FCB End of chain + */ + case ISB_IMC_MAC_RX_RESOURCE: + tp->receive_queue_number = MAC_QUEUE; + err1 = smctr_rx_frame(dev); + + if(isb_subtype & MAC_RX_RESOURCE_FE) + { + if((err = smctr_issue_resume_rx_fcb_cmd( dev, MAC_QUEUE)) != SUCCESS) + break; + + if(tp->ptr_rx_fcb_overruns) + (*tp->ptr_rx_fcb_overruns)++; + } + + if(isb_subtype & MAC_RX_RESOURCE_BE) + { + if((err = smctr_issue_resume_rx_bdb_cmd( dev, MAC_QUEUE)) != SUCCESS) + break; + + if(tp->ptr_rx_bdb_overruns) + (*tp->ptr_rx_bdb_overruns)++; + } + err = err1; + break; + + /* Type 0x09 - NON_MAC RX Frame Interrupt */ + case ISB_IMC_NON_MAC_RX_FRAME: + tp->rx_fifo_overrun_count = 0; + tp->receive_queue_number = NON_MAC_QUEUE; + err = smctr_rx_frame(dev); + break; + + /* Type 0x0A - MAC RX Frame Interrupt */ + case ISB_IMC_MAC_RX_FRAME: + tp->receive_queue_number = MAC_QUEUE; + err = smctr_rx_frame(dev); + break; + + /* Type 0x0B - TRC status + * TRC has encountered an error condition + * subtype bit 14 - transmit FIFO underrun + * subtype bit 15 - receive FIFO overrun + */ + case ISB_IMC_TRC_FIFO_STATUS: + if(isb_subtype & TRC_FIFO_STATUS_TX_UNDERRUN) + { + if(tp->ptr_tx_fifo_underruns) + (*tp->ptr_tx_fifo_underruns)++; + } + + if(isb_subtype & TRC_FIFO_STATUS_RX_OVERRUN) + { + /* update overrun stuck receive counter + * if >= 3, has to clear it by sending + * back to back frames. We pick + * DAT(duplicate address MAC frame) + */ + tp->rx_fifo_overrun_count++; + + if(tp->rx_fifo_overrun_count >= 3) + { + tp->rx_fifo_overrun_count = 0; + + /* delay clearing fifo overrun + * imask till send_BUG tx + * complete posted + */ + interrupt_unmask_bits &= (~0x800); + printk(KERN_CRIT "Jay please send bug\n");// smctr_send_bug(dev); + } + + if(tp->ptr_rx_fifo_overruns) + (*tp->ptr_rx_fifo_overruns)++; + } + + err = SUCCESS; + break; + + /* Type 0x0C - Action Command Status Interrupt + * Subtype bit 14 - CB end of command chain (CE) + * Subtype bit 15 - CB command interrupt (CI) + */ + case ISB_IMC_COMMAND_STATUS: + err = SUCCESS; + if(tp->acb_head->cmd == ACB_CMD_HIC_NOP) + { + printk(KERN_ERR "i1\n"); + smctr_disable_16bit(dev); + + /* XXXXXXXXXXXXXXXXX */ + /* err = UM_Interrupt(dev); */ + + smctr_enable_16bit(dev); + } + else + { + if((tp->acb_head->cmd + == ACB_CMD_READ_TRC_STATUS) && + (tp->acb_head->subcmd + == RW_TRC_STATUS_BLOCK)) + { + if(tp->ptr_bcn_type) + { + *(tp->ptr_bcn_type) + = (__u32)((SBlock *)tp->misc_command_data)->BCN_Type; + } + + if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & ERROR_COUNTERS_CHANGED) + { + smctr_update_err_stats(dev); + } + + if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & TI_NDIS_RING_STATUS_CHANGED) + { + tp->ring_status + = ((SBlock*)tp->misc_command_data)->TI_NDIS_Ring_Status; + smctr_disable_16bit(dev); + err = smctr_ring_status_chg(dev); + smctr_enable_16bit(dev); + if((tp->ring_status & REMOVE_RECEIVED) && + (tp->config_word0 & NO_AUTOREMOVE)) + { + smctr_issue_remove_cmd(dev); + } + + if(err != SUCCESS) + { + tp->acb_pending = 0; + break; + } + } + + if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & UNA_CHANGED) + { + if(tp->ptr_una) + { + tp->ptr_una[0] = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[0]); + tp->ptr_una[1] = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[1]); + tp->ptr_una[2] = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[2]); + } + + } + + if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & READY_TO_SEND_RQ_INIT) { + err = smctr_send_rq_init(dev); + } + } + } + + tp->acb_pending = 0; + break; + + /* Type 0x0D - MAC Type 1 interrupt + * Subtype -- 00 FR_BCN received at S12 + * 01 FR_BCN received at S21 + * 02 FR_DAT(DA=MA, A<>0) received at S21 + * 03 TSM_EXP at S21 + * 04 FR_REMOVE received at S42 + * 05 TBR_EXP, BR_FLAG_SET at S42 + * 06 TBT_EXP at S53 + */ + case ISB_IMC_MAC_TYPE_1: + if(isb_subtype > 8) + { + err = HARDWARE_FAILED; + break; + } + + err = SUCCESS; + switch(isb_subtype) + { + case 0: + tp->join_state = JS_BYPASS_STATE; + if(tp->status != CLOSED) + { + tp->status = CLOSED; + err = smctr_status_chg(dev); + } + break; + + case 1: + tp->join_state = JS_LOBE_TEST_STATE; + break; + + case 2: + tp->join_state = JS_DETECT_MONITOR_PRESENT_STATE; + break; + + case 3: + tp->join_state = JS_AWAIT_NEW_MONITOR_STATE; + break; + + case 4: + tp->join_state = JS_DUPLICATE_ADDRESS_TEST_STATE; + break; + + case 5: + tp->join_state = JS_NEIGHBOR_NOTIFICATION_STATE; + break; + + case 6: + tp->join_state = JS_REQUEST_INITIALIZATION_STATE; + break; + + case 7: + tp->join_state = JS_JOIN_COMPLETE_STATE; + tp->status = OPEN; + err = smctr_status_chg(dev); + break; + + case 8: + tp->join_state = JS_BYPASS_WAIT_STATE; + break; + } + break ; + + /* Type 0x0E - TRC Initialization Sequence Interrupt + * Subtype -- 00-FF Initializatin sequence complete + */ + case ISB_IMC_TRC_INTRNL_TST_STATUS: + tp->status = INITIALIZED; + smctr_disable_16bit(dev); + err = smctr_status_chg(dev); + smctr_enable_16bit(dev); + break; + + /* other interrupt types, illegal */ + default: + break; + } + + if(err != SUCCESS) + break; + } + + /* Checking the ack code instead of the unmask bits here is because : + * while fixing the stuck receive, DAT frame are sent and mask off + * FIFO overrun interrupt temporarily (interrupt_unmask_bits = 0) + * but we still want to issue ack to ISB + */ + if(!(interrupt_ack_code & 0xff00)) + smctr_issue_int_ack(dev, interrupt_ack_code, interrupt_unmask_bits); + + smctr_disable_16bit(dev); + smctr_enable_bic_int(dev); + spin_unlock(&tp->lock); + + return IRQ_HANDLED; +} + +static int smctr_issue_enable_int_cmd(struct net_device *dev, + __u16 interrupt_enable_mask) +{ + struct net_local *tp = netdev_priv(dev); + int err; + + if((err = smctr_wait_while_cbusy(dev))) + return err; + + tp->sclb_ptr->int_mask_control = interrupt_enable_mask; + tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_CLEAR_INTERRUPT_MASK; + + smctr_set_ctrl_attention(dev); + + return 0; +} + +static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, __u16 ibits) +{ + struct net_local *tp = netdev_priv(dev); + + if(smctr_wait_while_cbusy(dev)) + return -1; + + tp->sclb_ptr->int_mask_control = ibits; + tp->sclb_ptr->iack_code = iack_code << 1; /* use the offset from base */ tp->sclb_ptr->resume_control = 0; + tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_IACK_CODE_VALID | SCLB_CMD_CLEAR_INTERRUPT_MASK; + + smctr_set_ctrl_attention(dev); + + return 0; +} + +static int smctr_issue_init_timers_cmd(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned int i; + int err; + __u16 *pTimer_Struc = (__u16 *)tp->misc_command_data; + + if((err = smctr_wait_while_cbusy(dev))) + return err; + + if((err = smctr_wait_cmd(dev))) + return err; + + tp->config_word0 = THDREN | DMA_TRIGGER | USETPT | NO_AUTOREMOVE; + tp->config_word1 = 0; + + if((tp->media_type == MEDIA_STP_16) || + (tp->media_type == MEDIA_UTP_16) || + (tp->media_type == MEDIA_STP_16_UTP_16)) + { + tp->config_word0 |= FREQ_16MB_BIT; + } + + if(tp->mode_bits & EARLY_TOKEN_REL) + tp->config_word0 |= ETREN; + + if(tp->mode_bits & LOOPING_MODE_MASK) + tp->config_word0 |= RX_OWN_BIT; + else + tp->config_word0 &= ~RX_OWN_BIT; + + if(tp->receive_mask & PROMISCUOUS_MODE) + tp->config_word0 |= PROMISCUOUS_BIT; + else + tp->config_word0 &= ~PROMISCUOUS_BIT; + + if(tp->receive_mask & ACCEPT_ERR_PACKETS) + tp->config_word0 |= SAVBAD_BIT; + else + tp->config_word0 &= ~SAVBAD_BIT; + + if(tp->receive_mask & ACCEPT_ATT_MAC_FRAMES) + tp->config_word0 |= RXATMAC; + else + tp->config_word0 &= ~RXATMAC; + + if(tp->receive_mask & ACCEPT_MULTI_PROM) + tp->config_word1 |= MULTICAST_ADDRESS_BIT; + else + tp->config_word1 &= ~MULTICAST_ADDRESS_BIT; + + if(tp->receive_mask & ACCEPT_SOURCE_ROUTING_SPANNING) + tp->config_word1 |= SOURCE_ROUTING_SPANNING_BITS; + else + { + if(tp->receive_mask & ACCEPT_SOURCE_ROUTING) + tp->config_word1 |= SOURCE_ROUTING_EXPLORER_BIT; + else + tp->config_word1 &= ~SOURCE_ROUTING_SPANNING_BITS; + } + + if((tp->media_type == MEDIA_STP_16) || + (tp->media_type == MEDIA_UTP_16) || + (tp->media_type == MEDIA_STP_16_UTP_16)) + { + tp->config_word1 |= INTERFRAME_SPACING_16; + } + else + tp->config_word1 |= INTERFRAME_SPACING_4; + + *pTimer_Struc++ = tp->config_word0; + *pTimer_Struc++ = tp->config_word1; + + if((tp->media_type == MEDIA_STP_4) || + (tp->media_type == MEDIA_UTP_4) || + (tp->media_type == MEDIA_STP_4_UTP_4)) + { + *pTimer_Struc++ = 0x00FA; /* prescale */ + *pTimer_Struc++ = 0x2710; /* TPT_limit */ + *pTimer_Struc++ = 0x2710; /* TQP_limit */ + *pTimer_Struc++ = 0x0A28; /* TNT_limit */ + *pTimer_Struc++ = 0x3E80; /* TBT_limit */ + *pTimer_Struc++ = 0x3A98; /* TSM_limit */ + *pTimer_Struc++ = 0x1B58; /* TAM_limit */ + *pTimer_Struc++ = 0x00C8; /* TBR_limit */ + *pTimer_Struc++ = 0x07D0; /* TER_limit */ + *pTimer_Struc++ = 0x000A; /* TGT_limit */ + *pTimer_Struc++ = 0x1162; /* THT_limit */ + *pTimer_Struc++ = 0x07D0; /* TRR_limit */ + *pTimer_Struc++ = 0x1388; /* TVX_limit */ + *pTimer_Struc++ = 0x0000; /* reserved */ + } + else + { + *pTimer_Struc++ = 0x03E8; /* prescale */ + *pTimer_Struc++ = 0x9C40; /* TPT_limit */ + *pTimer_Struc++ = 0x9C40; /* TQP_limit */ + *pTimer_Struc++ = 0x0A28; /* TNT_limit */ + *pTimer_Struc++ = 0x3E80; /* TBT_limit */ + *pTimer_Struc++ = 0x3A98; /* TSM_limit */ + *pTimer_Struc++ = 0x1B58; /* TAM_limit */ + *pTimer_Struc++ = 0x00C8; /* TBR_limit */ + *pTimer_Struc++ = 0x07D0; /* TER_limit */ + *pTimer_Struc++ = 0x000A; /* TGT_limit */ + *pTimer_Struc++ = 0x4588; /* THT_limit */ + *pTimer_Struc++ = 0x1F40; /* TRR_limit */ + *pTimer_Struc++ = 0x4E20; /* TVX_limit */ + *pTimer_Struc++ = 0x0000; /* reserved */ + } + + /* Set node address. */ + *pTimer_Struc++ = dev->dev_addr[0] << 8 + | (dev->dev_addr[1] & 0xFF); + *pTimer_Struc++ = dev->dev_addr[2] << 8 + | (dev->dev_addr[3] & 0xFF); + *pTimer_Struc++ = dev->dev_addr[4] << 8 + | (dev->dev_addr[5] & 0xFF); + + /* Set group address. */ + *pTimer_Struc++ = tp->group_address_0 << 8 + | tp->group_address_0 >> 8; + *pTimer_Struc++ = tp->group_address[0] << 8 + | tp->group_address[0] >> 8; + *pTimer_Struc++ = tp->group_address[1] << 8 + | tp->group_address[1] >> 8; + + /* Set functional address. */ + *pTimer_Struc++ = tp->functional_address_0 << 8 + | tp->functional_address_0 >> 8; + *pTimer_Struc++ = tp->functional_address[0] << 8 + | tp->functional_address[0] >> 8; + *pTimer_Struc++ = tp->functional_address[1] << 8 + | tp->functional_address[1] >> 8; + + /* Set Bit-Wise group address. */ + *pTimer_Struc++ = tp->bitwise_group_address[0] << 8 + | tp->bitwise_group_address[0] >> 8; + *pTimer_Struc++ = tp->bitwise_group_address[1] << 8 + | tp->bitwise_group_address[1] >> 8; + + /* Set ring number address. */ + *pTimer_Struc++ = tp->source_ring_number; + *pTimer_Struc++ = tp->target_ring_number; + + /* Physical drop number. */ + *pTimer_Struc++ = (unsigned short)0; + *pTimer_Struc++ = (unsigned short)0; + + /* Product instance ID. */ + for(i = 0; i < 9; i++) + *pTimer_Struc++ = (unsigned short)0; + + err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_INIT_TRC_TIMERS, 0); + + return err; +} + +static int smctr_issue_init_txrx_cmd(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned int i; + int err; + void **txrx_ptrs = (void *)tp->misc_command_data; + + if((err = smctr_wait_while_cbusy(dev))) + return err; + + if((err = smctr_wait_cmd(dev))) + { + printk(KERN_ERR "%s: Hardware failure\n", dev->name); + return err; + } + + /* Initialize Transmit Queue Pointers that are used, to point to + * a single FCB. + */ + for(i = 0; i < NUM_TX_QS_USED; i++) + *txrx_ptrs++ = (void *)TRC_POINTER(tp->tx_fcb_head[i]); + + /* Initialize Transmit Queue Pointers that are NOT used to ZERO. */ + for(; i < MAX_TX_QS; i++) + *txrx_ptrs++ = (void *)0; + + /* Initialize Receive Queue Pointers (MAC and Non-MAC) that are + * used, to point to a single FCB and a BDB chain of buffers. + */ + for(i = 0; i < NUM_RX_QS_USED; i++) + { + *txrx_ptrs++ = (void *)TRC_POINTER(tp->rx_fcb_head[i]); + *txrx_ptrs++ = (void *)TRC_POINTER(tp->rx_bdb_head[i]); + } + + /* Initialize Receive Queue Pointers that are NOT used to ZERO. */ + for(; i < MAX_RX_QS; i++) + { + *txrx_ptrs++ = (void *)0; + *txrx_ptrs++ = (void *)0; + } + + err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_INIT_TX_RX, 0); + + return err; +} + +static int smctr_issue_insert_cmd(struct net_device *dev) +{ + int err; + + err = smctr_setup_single_cmd(dev, ACB_CMD_INSERT, ACB_SUB_CMD_NOP); + + return err; +} + +static int smctr_issue_read_ring_status_cmd(struct net_device *dev) +{ + int err; + + if((err = smctr_wait_while_cbusy(dev))) + return err; + + if((err = smctr_wait_cmd(dev))) + return err; + + err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_READ_TRC_STATUS, + RW_TRC_STATUS_BLOCK); + + return err; +} + +static int smctr_issue_read_word_cmd(struct net_device *dev, __u16 aword_cnt) +{ + int err; + + if((err = smctr_wait_while_cbusy(dev))) + return err; + + if((err = smctr_wait_cmd(dev))) + return err; + + err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_READ_VALUE, + aword_cnt); + + return err; +} + +static int smctr_issue_remove_cmd(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + int err; + + if((err = smctr_wait_while_cbusy(dev))) + return err; + + tp->sclb_ptr->resume_control = 0; + tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_REMOVE; + + smctr_set_ctrl_attention(dev); + + return 0; +} + +static int smctr_issue_resume_acb_cmd(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + int err; + + if((err = smctr_wait_while_cbusy(dev))) + return err; + + tp->sclb_ptr->resume_control = SCLB_RC_ACB; + tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_RESUME_CONTROL_VALID; + + tp->acb_pending = 1; + + smctr_set_ctrl_attention(dev); + + return 0; +} + +static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue) +{ + struct net_local *tp = netdev_priv(dev); + int err; + + if((err = smctr_wait_while_cbusy(dev))) + return err; + + if(queue == MAC_QUEUE) + tp->sclb_ptr->resume_control = SCLB_RC_RX_MAC_BDB; + else + tp->sclb_ptr->resume_control = SCLB_RC_RX_NON_MAC_BDB; + + tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_RESUME_CONTROL_VALID; + + smctr_set_ctrl_attention(dev); + + return 0; +} + +static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue) +{ + struct net_local *tp = netdev_priv(dev); + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_issue_resume_rx_fcb_cmd\n", dev->name); + + if(smctr_wait_while_cbusy(dev)) + return -1; + + if(queue == MAC_QUEUE) + tp->sclb_ptr->resume_control = SCLB_RC_RX_MAC_FCB; + else + tp->sclb_ptr->resume_control = SCLB_RC_RX_NON_MAC_FCB; + + tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_RESUME_CONTROL_VALID; + + smctr_set_ctrl_attention(dev); + + return 0; +} + +static int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue) +{ + struct net_local *tp = netdev_priv(dev); + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_issue_resume_tx_fcb_cmd\n", dev->name); + + if(smctr_wait_while_cbusy(dev)) + return -1; + + tp->sclb_ptr->resume_control = (SCLB_RC_TFCB0 << queue); + tp->sclb_ptr->valid_command = SCLB_RESUME_CONTROL_VALID | SCLB_VALID; + + smctr_set_ctrl_attention(dev); + + return 0; +} + +static int smctr_issue_test_internal_rom_cmd(struct net_device *dev) +{ + int err; + + err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, + TRC_INTERNAL_ROM_TEST); + + return err; +} + +static int smctr_issue_test_hic_cmd(struct net_device *dev) +{ + int err; + + err = smctr_setup_single_cmd(dev, ACB_CMD_HIC_TEST, + TRC_HOST_INTERFACE_REG_TEST); + + return err; +} + +static int smctr_issue_test_mac_reg_cmd(struct net_device *dev) +{ + int err; + + err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, + TRC_MAC_REGISTERS_TEST); + + return err; +} + +static int smctr_issue_trc_loopback_cmd(struct net_device *dev) +{ + int err; + + err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, + TRC_INTERNAL_LOOPBACK); + + return err; +} + +static int smctr_issue_tri_loopback_cmd(struct net_device *dev) +{ + int err; + + err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, + TRC_TRI_LOOPBACK); + + return err; +} + +static int smctr_issue_write_byte_cmd(struct net_device *dev, + short aword_cnt, void *byte) +{ + struct net_local *tp = netdev_priv(dev); + unsigned int iword, ibyte; + int err; + + if((err = smctr_wait_while_cbusy(dev))) + return err; + + if((err = smctr_wait_cmd(dev))) + return err; + + for(iword = 0, ibyte = 0; iword < (unsigned int)(aword_cnt & 0xff); + iword++, ibyte += 2) + { + tp->misc_command_data[iword] = (*((__u8 *)byte + ibyte) << 8) + | (*((__u8 *)byte + ibyte + 1)); + } + + return smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE, + aword_cnt); +} + +static int smctr_issue_write_word_cmd(struct net_device *dev, + short aword_cnt, void *word) +{ + struct net_local *tp = netdev_priv(dev); + unsigned int i, err; + + if((err = smctr_wait_while_cbusy(dev))) + return err; + + if((err = smctr_wait_cmd(dev))) + return err; + + for(i = 0; i < (unsigned int)(aword_cnt & 0xff); i++) + tp->misc_command_data[i] = *((__u16 *)word + i); + + err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE, + aword_cnt); + + return err; +} + +static int smctr_join_complete_state(struct net_device *dev) +{ + int err; + + err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, + JS_JOIN_COMPLETE_STATE); + + return err; +} + +static int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned int i, j; + FCBlock *fcb; + BDBlock *bdb; + + for(i = 0; i < NUM_TX_QS_USED; i++) + { + fcb = tp->tx_fcb_head[i]; + bdb = tp->tx_bdb_head[i]; + + for(j = 0; j < tp->num_tx_fcbs[i]; j++) + { + fcb->bdb_ptr = bdb; + fcb->trc_bdb_ptr = TRC_POINTER(bdb); + fcb = (FCBlock *)((char *)fcb + sizeof(FCBlock)); + bdb = (BDBlock *)((char *)bdb + sizeof(BDBlock)); + } + } + + return 0; +} + +static int smctr_load_firmware(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + const struct firmware *fw; + __u16 i, checksum = 0; + int err = 0; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_load_firmware\n", dev->name); + + if (request_firmware(&fw, "tr_smctr.bin", &dev->dev)) { + printk(KERN_ERR "%s: firmware not found\n", dev->name); + return UCODE_NOT_PRESENT; + } + + tp->num_of_tx_buffs = 4; + tp->mode_bits |= UMAC; + tp->receive_mask = 0; + tp->max_packet_size = 4177; + + /* Can only upload the firmware once per adapter reset. */ + if (tp->microcode_version != 0) { + err = (UCODE_PRESENT); + goto out; + } + + /* Verify the firmware exists and is there in the right amount. */ + if (!fw->data || + (*(fw->data + UCODE_VERSION_OFFSET) < UCODE_VERSION)) + { + err = (UCODE_NOT_PRESENT); + goto out; + } + + /* UCODE_SIZE is not included in Checksum. */ + for(i = 0; i < *((__u16 *)(fw->data + UCODE_SIZE_OFFSET)); i += 2) + checksum += *((__u16 *)(fw->data + 2 + i)); + if (checksum) { + err = (UCODE_NOT_PRESENT); + goto out; + } + + /* At this point we have a valid firmware image, lets kick it on up. */ + smctr_enable_adapter_ram(dev); + smctr_enable_16bit(dev); + smctr_set_page(dev, (__u8 *)tp->ram_access); + + if((smctr_checksum_firmware(dev)) || + (*(fw->data + UCODE_VERSION_OFFSET) > tp->microcode_version)) + { + smctr_enable_adapter_ctrl_store(dev); + + /* Zero out ram space for firmware. */ + for(i = 0; i < CS_RAM_SIZE; i += 2) + *((__u16 *)(tp->ram_access + i)) = 0; + + smctr_decode_firmware(dev, fw); + + tp->microcode_version = *(fw->data + UCODE_VERSION_OFFSET); *((__u16 *)(tp->ram_access + CS_RAM_VERSION_OFFSET)) + = (tp->microcode_version << 8); + *((__u16 *)(tp->ram_access + CS_RAM_CHECKSUM_OFFSET)) + = ~(tp->microcode_version << 8) + 1; + + smctr_disable_adapter_ctrl_store(dev); + + if(smctr_checksum_firmware(dev)) + err = HARDWARE_FAILED; + } + else + err = UCODE_PRESENT; + + smctr_disable_16bit(dev); + out: + release_firmware(fw); + return err; +} + +static int smctr_load_node_addr(struct net_device *dev) +{ + int ioaddr = dev->base_addr; + unsigned int i; + __u8 r; + + for(i = 0; i < 6; i++) + { + r = inb(ioaddr + LAR0 + i); + dev->dev_addr[i] = (char)r; + } + dev->addr_len = 6; + + return 0; +} + +/* Lobe Media Test. + * During the transmission of the initial 1500 lobe media MAC frames, + * the phase lock loop in the 805 chip may lock, and then un-lock, causing + * the 825 to go into a PURGE state. When performing a PURGE, the MCT + * microcode will not transmit any frames given to it by the host, and + * will consequently cause a timeout. + * + * NOTE 1: If the monitor_state is MS_BEACON_TEST_STATE, all transmit + * queues other than the one used for the lobe_media_test should be + * disabled.!? + * + * NOTE 2: If the monitor_state is MS_BEACON_TEST_STATE and the receive_mask + * has any multi-cast or promiscuous bits set, the receive_mask needs to + * be changed to clear the multi-cast or promiscuous mode bits, the lobe_test + * run, and then the receive mask set back to its original value if the test + * is successful. + */ +static int smctr_lobe_media_test(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned int i, perror = 0; + unsigned short saved_rcv_mask; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_lobe_media_test\n", dev->name); + + /* Clear receive mask for lobe test. */ + saved_rcv_mask = tp->receive_mask; + tp->receive_mask = 0; + + smctr_chg_rx_mask(dev); + + /* Setup the lobe media test. */ + smctr_lobe_media_test_cmd(dev); + if(smctr_wait_cmd(dev)) + goto err; + + /* Tx lobe media test frames. */ + for(i = 0; i < 1500; ++i) + { + if(smctr_send_lobe_media_test(dev)) + { + if(perror) + goto err; + else + { + perror = 1; + if(smctr_lobe_media_test_cmd(dev)) + goto err; + } + } + } + + if(smctr_send_dat(dev)) + { + if(smctr_send_dat(dev)) + goto err; + } + + /* Check if any frames received during test. */ + if((tp->rx_fcb_curr[MAC_QUEUE]->frame_status) || + (tp->rx_fcb_curr[NON_MAC_QUEUE]->frame_status)) + goto err; + + /* Set receive mask to "Promisc" mode. */ + tp->receive_mask = saved_rcv_mask; + + smctr_chg_rx_mask(dev); + + return 0; +err: + smctr_reset_adapter(dev); + tp->status = CLOSED; + return LOBE_MEDIA_TEST_FAILED; +} + +static int smctr_lobe_media_test_cmd(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + int err; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_lobe_media_test_cmd\n", dev->name); + + /* Change to lobe media test state. */ + if(tp->monitor_state != MS_BEACON_TEST_STATE) + { + smctr_lobe_media_test_state(dev); + if(smctr_wait_cmd(dev)) + { + printk(KERN_ERR "Lobe Failed test state\n"); + return LOBE_MEDIA_TEST_FAILED; + } + } + + err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, + TRC_LOBE_MEDIA_TEST); + + return err; +} + +static int smctr_lobe_media_test_state(struct net_device *dev) +{ + int err; + + err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, + JS_LOBE_TEST_STATE); + + return err; +} + +static int smctr_make_8025_hdr(struct net_device *dev, + MAC_HEADER *rmf, MAC_HEADER *tmf, __u16 ac_fc) +{ + tmf->ac = MSB(ac_fc); /* msb is access control */ + tmf->fc = LSB(ac_fc); /* lsb is frame control */ + + tmf->sa[0] = dev->dev_addr[0]; + tmf->sa[1] = dev->dev_addr[1]; + tmf->sa[2] = dev->dev_addr[2]; + tmf->sa[3] = dev->dev_addr[3]; + tmf->sa[4] = dev->dev_addr[4]; + tmf->sa[5] = dev->dev_addr[5]; + + switch(tmf->vc) + { + /* Send RQ_INIT to RPS */ + case RQ_INIT: + tmf->da[0] = 0xc0; + tmf->da[1] = 0x00; + tmf->da[2] = 0x00; + tmf->da[3] = 0x00; + tmf->da[4] = 0x00; + tmf->da[5] = 0x02; + break; + + /* Send RPT_TX_FORWARD to CRS */ + case RPT_TX_FORWARD: + tmf->da[0] = 0xc0; + tmf->da[1] = 0x00; + tmf->da[2] = 0x00; + tmf->da[3] = 0x00; + tmf->da[4] = 0x00; + tmf->da[5] = 0x10; + break; + + /* Everything else goes to sender */ + default: + tmf->da[0] = rmf->sa[0]; + tmf->da[1] = rmf->sa[1]; + tmf->da[2] = rmf->sa[2]; + tmf->da[3] = rmf->sa[3]; + tmf->da[4] = rmf->sa[4]; + tmf->da[5] = rmf->sa[5]; + break; + } + + return 0; +} + +static int smctr_make_access_pri(struct net_device *dev, MAC_SUB_VECTOR *tsv) +{ + struct net_local *tp = netdev_priv(dev); + + tsv->svi = AUTHORIZED_ACCESS_PRIORITY; + tsv->svl = S_AUTHORIZED_ACCESS_PRIORITY; + + tsv->svv[0] = MSB(tp->authorized_access_priority); + tsv->svv[1] = LSB(tp->authorized_access_priority); + + return 0; +} + +static int smctr_make_addr_mod(struct net_device *dev, MAC_SUB_VECTOR *tsv) +{ + tsv->svi = ADDRESS_MODIFER; + tsv->svl = S_ADDRESS_MODIFER; + + tsv->svv[0] = 0; + tsv->svv[1] = 0; + + return 0; +} + +static int smctr_make_auth_funct_class(struct net_device *dev, + MAC_SUB_VECTOR *tsv) +{ + struct net_local *tp = netdev_priv(dev); + + tsv->svi = AUTHORIZED_FUNCTION_CLASS; + tsv->svl = S_AUTHORIZED_FUNCTION_CLASS; + + tsv->svv[0] = MSB(tp->authorized_function_classes); + tsv->svv[1] = LSB(tp->authorized_function_classes); + + return 0; +} + +static int smctr_make_corr(struct net_device *dev, + MAC_SUB_VECTOR *tsv, __u16 correlator) +{ + tsv->svi = CORRELATOR; + tsv->svl = S_CORRELATOR; + + tsv->svv[0] = MSB(correlator); + tsv->svv[1] = LSB(correlator); + + return 0; +} + +static int smctr_make_funct_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv) +{ + struct net_local *tp = netdev_priv(dev); + + smctr_get_functional_address(dev); + + tsv->svi = FUNCTIONAL_ADDRESS; + tsv->svl = S_FUNCTIONAL_ADDRESS; + + tsv->svv[0] = MSB(tp->misc_command_data[0]); + tsv->svv[1] = LSB(tp->misc_command_data[0]); + + tsv->svv[2] = MSB(tp->misc_command_data[1]); + tsv->svv[3] = LSB(tp->misc_command_data[1]); + + return 0; +} + +static int smctr_make_group_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv) +{ + struct net_local *tp = netdev_priv(dev); + + smctr_get_group_address(dev); + + tsv->svi = GROUP_ADDRESS; + tsv->svl = S_GROUP_ADDRESS; + + tsv->svv[0] = MSB(tp->misc_command_data[0]); + tsv->svv[1] = LSB(tp->misc_command_data[0]); + + tsv->svv[2] = MSB(tp->misc_command_data[1]); + tsv->svv[3] = LSB(tp->misc_command_data[1]); + + /* Set Group Address Sub-vector to all zeros if only the + * Group Address/Functional Address Indicator is set. + */ + if(tsv->svv[0] == 0x80 && tsv->svv[1] == 0x00 && + tsv->svv[2] == 0x00 && tsv->svv[3] == 0x00) + tsv->svv[0] = 0x00; + + return 0; +} + +static int smctr_make_phy_drop_num(struct net_device *dev, + MAC_SUB_VECTOR *tsv) +{ + struct net_local *tp = netdev_priv(dev); + + smctr_get_physical_drop_number(dev); + + tsv->svi = PHYSICAL_DROP; + tsv->svl = S_PHYSICAL_DROP; + + tsv->svv[0] = MSB(tp->misc_command_data[0]); + tsv->svv[1] = LSB(tp->misc_command_data[0]); + + tsv->svv[2] = MSB(tp->misc_command_data[1]); + tsv->svv[3] = LSB(tp->misc_command_data[1]); + + return 0; +} + +static int smctr_make_product_id(struct net_device *dev, MAC_SUB_VECTOR *tsv) +{ + int i; + + tsv->svi = PRODUCT_INSTANCE_ID; + tsv->svl = S_PRODUCT_INSTANCE_ID; + + for(i = 0; i < 18; i++) + tsv->svv[i] = 0xF0; + + return 0; +} + +static int smctr_make_station_id(struct net_device *dev, MAC_SUB_VECTOR *tsv) +{ + struct net_local *tp = netdev_priv(dev); + + smctr_get_station_id(dev); + + tsv->svi = STATION_IDENTIFER; + tsv->svl = S_STATION_IDENTIFER; + + tsv->svv[0] = MSB(tp->misc_command_data[0]); + tsv->svv[1] = LSB(tp->misc_command_data[0]); + + tsv->svv[2] = MSB(tp->misc_command_data[1]); + tsv->svv[3] = LSB(tp->misc_command_data[1]); + + tsv->svv[4] = MSB(tp->misc_command_data[2]); + tsv->svv[5] = LSB(tp->misc_command_data[2]); + + return 0; +} + +static int smctr_make_ring_station_status(struct net_device *dev, + MAC_SUB_VECTOR * tsv) +{ + tsv->svi = RING_STATION_STATUS; + tsv->svl = S_RING_STATION_STATUS; + + tsv->svv[0] = 0; + tsv->svv[1] = 0; + tsv->svv[2] = 0; + tsv->svv[3] = 0; + tsv->svv[4] = 0; + tsv->svv[5] = 0; + + return 0; +} + +static int smctr_make_ring_station_version(struct net_device *dev, + MAC_SUB_VECTOR *tsv) +{ + struct net_local *tp = netdev_priv(dev); + + tsv->svi = RING_STATION_VERSION_NUMBER; + tsv->svl = S_RING_STATION_VERSION_NUMBER; + + tsv->svv[0] = 0xe2; /* EBCDIC - S */ + tsv->svv[1] = 0xd4; /* EBCDIC - M */ + tsv->svv[2] = 0xc3; /* EBCDIC - C */ + tsv->svv[3] = 0x40; /* EBCDIC - */ + tsv->svv[4] = 0xe5; /* EBCDIC - V */ + tsv->svv[5] = 0xF0 + (tp->microcode_version >> 4); + tsv->svv[6] = 0xF0 + (tp->microcode_version & 0x0f); + tsv->svv[7] = 0x40; /* EBCDIC - */ + tsv->svv[8] = 0xe7; /* EBCDIC - X */ + + if(tp->extra_info & CHIP_REV_MASK) + tsv->svv[9] = 0xc5; /* EBCDIC - E */ + else + tsv->svv[9] = 0xc4; /* EBCDIC - D */ + + return 0; +} + +static int smctr_make_tx_status_code(struct net_device *dev, + MAC_SUB_VECTOR *tsv, __u16 tx_fstatus) +{ + tsv->svi = TRANSMIT_STATUS_CODE; + tsv->svl = S_TRANSMIT_STATUS_CODE; + + tsv->svv[0] = ((tx_fstatus & 0x0100 >> 6) | IBM_PASS_SOURCE_ADDR); + + /* Stripped frame status of Transmitted Frame */ + tsv->svv[1] = tx_fstatus & 0xff; + + return 0; +} + +static int smctr_make_upstream_neighbor_addr(struct net_device *dev, + MAC_SUB_VECTOR *tsv) +{ + struct net_local *tp = netdev_priv(dev); + + smctr_get_upstream_neighbor_addr(dev); + + tsv->svi = UPSTREAM_NEIGHBOR_ADDRESS; + tsv->svl = S_UPSTREAM_NEIGHBOR_ADDRESS; + + tsv->svv[0] = MSB(tp->misc_command_data[0]); + tsv->svv[1] = LSB(tp->misc_command_data[0]); + + tsv->svv[2] = MSB(tp->misc_command_data[1]); + tsv->svv[3] = LSB(tp->misc_command_data[1]); + + tsv->svv[4] = MSB(tp->misc_command_data[2]); + tsv->svv[5] = LSB(tp->misc_command_data[2]); + + return 0; +} + +static int smctr_make_wrap_data(struct net_device *dev, MAC_SUB_VECTOR *tsv) +{ + tsv->svi = WRAP_DATA; + tsv->svl = S_WRAP_DATA; + + return 0; +} + +/* + * Open/initialize the board. This is called sometime after + * booting when the 'ifconfig' program is run. + * + * This routine should set everything up anew at each open, even + * registers that "should" only need to be set once at boot, so that + * there is non-reboot way to recover if something goes wrong. + */ +static int smctr_open(struct net_device *dev) +{ + int err; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_open\n", dev->name); + + err = smctr_init_adapter(dev); + if(err < 0) + return err; + + return err; +} + +/* Interrupt driven open of Token card. */ +static int smctr_open_tr(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned long flags; + int err; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_open_tr\n", dev->name); + + /* Now we can actually open the adapter. */ + if(tp->status == OPEN) + return 0; + if(tp->status != INITIALIZED) + return -1; + + /* FIXME: it would work a lot better if we masked the irq sources + on the card here, then we could skip the locking and poll nicely */ + spin_lock_irqsave(&tp->lock, flags); + + smctr_set_page(dev, (__u8 *)tp->ram_access); + + if((err = smctr_issue_resume_rx_fcb_cmd(dev, (short)MAC_QUEUE))) + goto out; + + if((err = smctr_issue_resume_rx_bdb_cmd(dev, (short)MAC_QUEUE))) + goto out; + + if((err = smctr_issue_resume_rx_fcb_cmd(dev, (short)NON_MAC_QUEUE))) + goto out; + + if((err = smctr_issue_resume_rx_bdb_cmd(dev, (short)NON_MAC_QUEUE))) + goto out; + + tp->status = CLOSED; + + /* Insert into the Ring or Enter Loopback Mode. */ + if((tp->mode_bits & LOOPING_MODE_MASK) == LOOPBACK_MODE_1) + { + tp->status = CLOSED; + + if(!(err = smctr_issue_trc_loopback_cmd(dev))) + { + if(!(err = smctr_wait_cmd(dev))) + tp->status = OPEN; + } + + smctr_status_chg(dev); + } + else + { + if((tp->mode_bits & LOOPING_MODE_MASK) == LOOPBACK_MODE_2) + { + tp->status = CLOSED; + if(!(err = smctr_issue_tri_loopback_cmd(dev))) + { + if(!(err = smctr_wait_cmd(dev))) + tp->status = OPEN; + } + + smctr_status_chg(dev); + } + else + { + if((tp->mode_bits & LOOPING_MODE_MASK) + == LOOPBACK_MODE_3) + { + tp->status = CLOSED; + if(!(err = smctr_lobe_media_test_cmd(dev))) + { + if(!(err = smctr_wait_cmd(dev))) + tp->status = OPEN; + } + smctr_status_chg(dev); + } + else + { + if(!(err = smctr_lobe_media_test(dev))) + err = smctr_issue_insert_cmd(dev); + else + { + if(err == LOBE_MEDIA_TEST_FAILED) + printk(KERN_WARNING "%s: Lobe Media Test Failure - Check cable?\n", dev->name); + } + } + } + } + +out: + spin_unlock_irqrestore(&tp->lock, flags); + + return err; +} + +/* Check for a network adapter of this type, + * and return device structure if one exists. + */ +struct net_device __init *smctr_probe(int unit) +{ + struct net_device *dev = alloc_trdev(sizeof(struct net_local)); + static const unsigned ports[] = { + 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0, 0x300, + 0x320, 0x340, 0x360, 0x380, 0 + }; + const unsigned *port; + int err = 0; + + if (!dev) + return ERR_PTR(-ENOMEM); + + if (unit >= 0) { + sprintf(dev->name, "tr%d", unit); + netdev_boot_setup_check(dev); + } + + if (dev->base_addr > 0x1ff) /* Check a single specified location. */ + err = smctr_probe1(dev, dev->base_addr); + else if(dev->base_addr != 0) /* Don't probe at all. */ + err =-ENXIO; + else { + for (port = ports; *port; port++) { + err = smctr_probe1(dev, *port); + if (!err) + break; + } + } + if (err) + goto out; + err = register_netdev(dev); + if (err) + goto out1; + return dev; +out1: +#ifdef CONFIG_MCA_LEGACY + { struct net_local *tp = netdev_priv(dev); + if (tp->slot_num) + mca_mark_as_unused(tp->slot_num); + } +#endif + release_region(dev->base_addr, SMCTR_IO_EXTENT); + free_irq(dev->irq, dev); +out: + free_netdev(dev); + return ERR_PTR(err); +} + +static const struct net_device_ops smctr_netdev_ops = { + .ndo_open = smctr_open, + .ndo_stop = smctr_close, + .ndo_start_xmit = smctr_send_packet, + .ndo_tx_timeout = smctr_timeout, + .ndo_get_stats = smctr_get_stats, + .ndo_set_rx_mode = smctr_set_multicast_list, +}; + +static int __init smctr_probe1(struct net_device *dev, int ioaddr) +{ + static unsigned version_printed; + struct net_local *tp = netdev_priv(dev); + int err; + __u32 *ram; + + if(smctr_debug && version_printed++ == 0) + printk(version); + + spin_lock_init(&tp->lock); + dev->base_addr = ioaddr; + + /* Actually detect an adapter now. */ + err = smctr_chk_isa(dev); + if(err < 0) + { + if ((err = smctr_chk_mca(dev)) < 0) { + err = -ENODEV; + goto out; + } + } + + tp = netdev_priv(dev); + dev->mem_start = tp->ram_base; + dev->mem_end = dev->mem_start + 0x10000; + ram = (__u32 *)phys_to_virt(dev->mem_start); + tp->ram_access = *(__u32 *)&ram; + tp->status = NOT_INITIALIZED; + + err = smctr_load_firmware(dev); + if(err != UCODE_PRESENT && err != SUCCESS) + { + printk(KERN_ERR "%s: Firmware load failed (%d)\n", dev->name, err); + err = -EIO; + goto out; + } + + /* Allow user to specify ring speed on module insert. */ + if(ringspeed == 4) + tp->media_type = MEDIA_UTP_4; + else + tp->media_type = MEDIA_UTP_16; + + printk(KERN_INFO "%s: %s %s at Io %#4x, Irq %d, Rom %#4x, Ram %#4x.\n", + dev->name, smctr_name, smctr_model, + (unsigned int)dev->base_addr, + dev->irq, tp->rom_base, tp->ram_base); + + dev->netdev_ops = &smctr_netdev_ops; + dev->watchdog_timeo = HZ; + return 0; + +out: + return err; +} + +static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, + struct net_device *dev, __u16 rx_status) +{ + struct net_local *tp = netdev_priv(dev); + struct sk_buff *skb; + __u16 rcode, correlator; + int err = 0; + __u8 xframe = 1; + + rmf->vl = SWAP_BYTES(rmf->vl); + if(rx_status & FCB_RX_STATUS_DA_MATCHED) + { + switch(rmf->vc) + { + /* Received MAC Frames Processed by RS. */ + case INIT: + if((rcode = smctr_rcv_init(dev, rmf, &correlator)) == HARDWARE_FAILED) + { + return rcode; + } + + if((err = smctr_send_rsp(dev, rmf, rcode, + correlator))) + { + return err; + } + break; + + case CHG_PARM: + if((rcode = smctr_rcv_chg_param(dev, rmf, + &correlator)) ==HARDWARE_FAILED) + { + return rcode; + } + + if((err = smctr_send_rsp(dev, rmf, rcode, + correlator))) + { + return err; + } + break; + + case RQ_ADDR: + if((rcode = smctr_rcv_rq_addr_state_attch(dev, + rmf, &correlator)) != POSITIVE_ACK) + { + if(rcode == HARDWARE_FAILED) + return rcode; + else + return smctr_send_rsp(dev, rmf, + rcode, correlator); + } + + if((err = smctr_send_rpt_addr(dev, rmf, + correlator))) + { + return err; + } + break; + + case RQ_ATTCH: + if((rcode = smctr_rcv_rq_addr_state_attch(dev, + rmf, &correlator)) != POSITIVE_ACK) + { + if(rcode == HARDWARE_FAILED) + return rcode; + else + return smctr_send_rsp(dev, rmf, + rcode, + correlator); + } + + if((err = smctr_send_rpt_attch(dev, rmf, + correlator))) + { + return err; + } + break; + + case RQ_STATE: + if((rcode = smctr_rcv_rq_addr_state_attch(dev, + rmf, &correlator)) != POSITIVE_ACK) + { + if(rcode == HARDWARE_FAILED) + return rcode; + else + return smctr_send_rsp(dev, rmf, + rcode, + correlator); + } + + if((err = smctr_send_rpt_state(dev, rmf, + correlator))) + { + return err; + } + break; + + case TX_FORWARD: { + __u16 uninitialized_var(tx_fstatus); + + if((rcode = smctr_rcv_tx_forward(dev, rmf)) + != POSITIVE_ACK) + { + if(rcode == HARDWARE_FAILED) + return rcode; + else + return smctr_send_rsp(dev, rmf, + rcode, + correlator); + } + + if((err = smctr_send_tx_forward(dev, rmf, + &tx_fstatus)) == HARDWARE_FAILED) + { + return err; + } + + if(err == A_FRAME_WAS_FORWARDED) + { + if((err = smctr_send_rpt_tx_forward(dev, + rmf, tx_fstatus)) + == HARDWARE_FAILED) + { + return err; + } + } + break; + } + + /* Received MAC Frames Processed by CRS/REM/RPS. */ + case RSP: + case RQ_INIT: + case RPT_NEW_MON: + case RPT_SUA_CHG: + case RPT_ACTIVE_ERR: + case RPT_NN_INCMP: + case RPT_ERROR: + case RPT_ATTCH: + case RPT_STATE: + case RPT_ADDR: + break; + + /* Rcvd Att. MAC Frame (if RXATMAC set) or UNKNOWN */ + default: + xframe = 0; + if(!(tp->receive_mask & ACCEPT_ATT_MAC_FRAMES)) + { + rcode = smctr_rcv_unknown(dev, rmf, + &correlator); + if((err = smctr_send_rsp(dev, rmf,rcode, + correlator))) + { + return err; + } + } + + break; + } + } + else + { + /* 1. DA doesn't match (Promiscuous Mode). + * 2. Parse for Extended MAC Frame Type. + */ + switch(rmf->vc) + { + case RSP: + case INIT: + case RQ_INIT: + case RQ_ADDR: + case RQ_ATTCH: + case RQ_STATE: + case CHG_PARM: + case RPT_ADDR: + case RPT_ERROR: + case RPT_ATTCH: + case RPT_STATE: + case RPT_NEW_MON: + case RPT_SUA_CHG: + case RPT_NN_INCMP: + case RPT_ACTIVE_ERR: + break; + + default: + xframe = 0; + break; + } + } + + /* NOTE: UNKNOWN MAC frames will NOT be passed up unless + * ACCEPT_ATT_MAC_FRAMES is set. + */ + if(((tp->receive_mask & ACCEPT_ATT_MAC_FRAMES) && + (xframe == (__u8)0)) || + ((tp->receive_mask & ACCEPT_EXT_MAC_FRAMES) && + (xframe == (__u8)1))) + { + rmf->vl = SWAP_BYTES(rmf->vl); + + if (!(skb = dev_alloc_skb(size))) + return -ENOMEM; + skb->len = size; + + /* Slide data into a sleek skb. */ + skb_put(skb, skb->len); + skb_copy_to_linear_data(skb, rmf, skb->len); + + /* Update Counters */ + tp->MacStat.rx_packets++; + tp->MacStat.rx_bytes += skb->len; + + /* Kick the packet on up. */ + skb->protocol = tr_type_trans(skb, dev); + netif_rx(skb); + err = 0; + } + + return err; +} + +/* Adapter RAM test. Incremental word ODD boundary data test. */ +static int smctr_ram_memory_test(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + __u16 page, pages_of_ram, start_pattern = 0, word_pattern = 0, + word_read = 0, err_word = 0, err_pattern = 0; + unsigned int err_offset; + __u32 j, pword; + __u8 err = 0; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_ram_memory_test\n", dev->name); + + start_pattern = 0x0001; + pages_of_ram = tp->ram_size / tp->ram_usable; + pword = tp->ram_access; + + /* Incremental word ODD boundary test. */ + for(page = 0; (page < pages_of_ram) && (~err); + page++, start_pattern += 0x8000) + { + smctr_set_page(dev, (__u8 *)(tp->ram_access + + (page * tp->ram_usable * 1024) + 1)); + word_pattern = start_pattern; + + for(j = 1; j < (__u32)(tp->ram_usable * 1024) - 1; j += 2) + *(__u16 *)(pword + j) = word_pattern++; + + word_pattern = start_pattern; + + for(j = 1; j < (__u32)(tp->ram_usable * 1024) - 1 && (~err); + j += 2, word_pattern++) + { + word_read = *(__u16 *)(pword + j); + if(word_read != word_pattern) + { + err = (__u8)1; + err_offset = j; + err_word = word_read; + err_pattern = word_pattern; + return RAM_TEST_FAILED; + } + } + } + + /* Zero out memory. */ + for(page = 0; page < pages_of_ram && (~err); page++) + { + smctr_set_page(dev, (__u8 *)(tp->ram_access + + (page * tp->ram_usable * 1024))); + word_pattern = 0; + + for(j = 0; j < (__u32)tp->ram_usable * 1024; j +=2) + *(__u16 *)(pword + j) = word_pattern; + + for(j =0; j < (__u32)tp->ram_usable * 1024 && (~err); j += 2) + { + word_read = *(__u16 *)(pword + j); + if(word_read != word_pattern) + { + err = (__u8)1; + err_offset = j; + err_word = word_read; + err_pattern = word_pattern; + return RAM_TEST_FAILED; + } + } + } + + smctr_set_page(dev, (__u8 *)tp->ram_access); + + return 0; +} + +static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf, + __u16 *correlator) +{ + MAC_SUB_VECTOR *rsv; + signed short vlen; + __u16 rcode = POSITIVE_ACK; + unsigned int svectors = F_NO_SUB_VECTORS_FOUND; + + /* This Frame can only come from a CRS */ + if((rmf->dc_sc & SC_MASK) != SC_CRS) + return E_INAPPROPRIATE_SOURCE_CLASS; + + /* Remove MVID Length from total length. */ + vlen = (signed short)rmf->vl - 4; + + /* Point to First SVID */ + rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER)); + + /* Search for Appropriate SVID's. */ + while((vlen > 0) && (rcode == POSITIVE_ACK)) + { + switch(rsv->svi) + { + case CORRELATOR: + svectors |= F_CORRELATOR; + rcode = smctr_set_corr(dev, rsv, correlator); + break; + + case LOCAL_RING_NUMBER: + svectors |= F_LOCAL_RING_NUMBER; + rcode = smctr_set_local_ring_num(dev, rsv); + break; + + case ASSIGN_PHYSICAL_DROP: + svectors |= F_ASSIGN_PHYSICAL_DROP; + rcode = smctr_set_phy_drop(dev, rsv); + break; + + case ERROR_TIMER_VALUE: + svectors |= F_ERROR_TIMER_VALUE; + rcode = smctr_set_error_timer_value(dev, rsv); + break; + + case AUTHORIZED_FUNCTION_CLASS: + svectors |= F_AUTHORIZED_FUNCTION_CLASS; + rcode = smctr_set_auth_funct_class(dev, rsv); + break; + + case AUTHORIZED_ACCESS_PRIORITY: + svectors |= F_AUTHORIZED_ACCESS_PRIORITY; + rcode = smctr_set_auth_access_pri(dev, rsv); + break; + + default: + rcode = E_SUB_VECTOR_UNKNOWN; + break; + } + + /* Let Sender Know if SUM of SV length's is + * larger then length in MVID length field + */ + if((vlen -= rsv->svl) < 0) + rcode = E_VECTOR_LENGTH_ERROR; + + rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); + } + + if(rcode == POSITIVE_ACK) + { + /* Let Sender Know if MVID length field + * is larger then SUM of SV length's + */ + if(vlen != 0) + rcode = E_VECTOR_LENGTH_ERROR; + else + { + /* Let Sender Know if Expected SVID Missing */ + if((svectors & R_CHG_PARM) ^ R_CHG_PARM) + rcode = E_MISSING_SUB_VECTOR; + } + } + + return rcode; +} + +static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf, + __u16 *correlator) +{ + MAC_SUB_VECTOR *rsv; + signed short vlen; + __u16 rcode = POSITIVE_ACK; + unsigned int svectors = F_NO_SUB_VECTORS_FOUND; + + /* This Frame can only come from a RPS */ + if((rmf->dc_sc & SC_MASK) != SC_RPS) + return E_INAPPROPRIATE_SOURCE_CLASS; + + /* Remove MVID Length from total length. */ + vlen = (signed short)rmf->vl - 4; + + /* Point to First SVID */ + rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER)); + + /* Search for Appropriate SVID's */ + while((vlen > 0) && (rcode == POSITIVE_ACK)) + { + switch(rsv->svi) + { + case CORRELATOR: + svectors |= F_CORRELATOR; + rcode = smctr_set_corr(dev, rsv, correlator); + break; + + case LOCAL_RING_NUMBER: + svectors |= F_LOCAL_RING_NUMBER; + rcode = smctr_set_local_ring_num(dev, rsv); + break; + + case ASSIGN_PHYSICAL_DROP: + svectors |= F_ASSIGN_PHYSICAL_DROP; + rcode = smctr_set_phy_drop(dev, rsv); + break; + + case ERROR_TIMER_VALUE: + svectors |= F_ERROR_TIMER_VALUE; + rcode = smctr_set_error_timer_value(dev, rsv); + break; + + default: + rcode = E_SUB_VECTOR_UNKNOWN; + break; + } + + /* Let Sender Know if SUM of SV length's is + * larger then length in MVID length field + */ + if((vlen -= rsv->svl) < 0) + rcode = E_VECTOR_LENGTH_ERROR; + + rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); + } + + if(rcode == POSITIVE_ACK) + { + /* Let Sender Know if MVID length field + * is larger then SUM of SV length's + */ + if(vlen != 0) + rcode = E_VECTOR_LENGTH_ERROR; + else + { + /* Let Sender Know if Expected SV Missing */ + if((svectors & R_INIT) ^ R_INIT) + rcode = E_MISSING_SUB_VECTOR; + } + } + + return rcode; +} + +static int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf) +{ + MAC_SUB_VECTOR *rsv; + signed short vlen; + __u16 rcode = POSITIVE_ACK; + unsigned int svectors = F_NO_SUB_VECTORS_FOUND; + + /* This Frame can only come from a CRS */ + if((rmf->dc_sc & SC_MASK) != SC_CRS) + return E_INAPPROPRIATE_SOURCE_CLASS; + + /* Remove MVID Length from total length */ + vlen = (signed short)rmf->vl - 4; + + /* Point to First SVID */ + rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER)); + + /* Search for Appropriate SVID's */ + while((vlen > 0) && (rcode == POSITIVE_ACK)) + { + switch(rsv->svi) + { + case FRAME_FORWARD: + svectors |= F_FRAME_FORWARD; + rcode = smctr_set_frame_forward(dev, rsv, + rmf->dc_sc); + break; + + default: + rcode = E_SUB_VECTOR_UNKNOWN; + break; + } + + /* Let Sender Know if SUM of SV length's is + * larger then length in MVID length field + */ + if((vlen -= rsv->svl) < 0) + rcode = E_VECTOR_LENGTH_ERROR; + + rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); + } + + if(rcode == POSITIVE_ACK) + { + /* Let Sender Know if MVID length field + * is larger then SUM of SV length's + */ + if(vlen != 0) + rcode = E_VECTOR_LENGTH_ERROR; + else + { + /* Let Sender Know if Expected SV Missing */ + if((svectors & R_TX_FORWARD) ^ R_TX_FORWARD) + rcode = E_MISSING_SUB_VECTOR; + } + } + + return rcode; +} + +static int smctr_rcv_rq_addr_state_attch(struct net_device *dev, + MAC_HEADER *rmf, __u16 *correlator) +{ + MAC_SUB_VECTOR *rsv; + signed short vlen; + __u16 rcode = POSITIVE_ACK; + unsigned int svectors = F_NO_SUB_VECTORS_FOUND; + + /* Remove MVID Length from total length */ + vlen = (signed short)rmf->vl - 4; + + /* Point to First SVID */ + rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER)); + + /* Search for Appropriate SVID's */ + while((vlen > 0) && (rcode == POSITIVE_ACK)) + { + switch(rsv->svi) + { + case CORRELATOR: + svectors |= F_CORRELATOR; + rcode = smctr_set_corr(dev, rsv, correlator); + break; + + default: + rcode = E_SUB_VECTOR_UNKNOWN; + break; + } + + /* Let Sender Know if SUM of SV length's is + * larger then length in MVID length field + */ + if((vlen -= rsv->svl) < 0) + rcode = E_VECTOR_LENGTH_ERROR; + + rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); + } + + if(rcode == POSITIVE_ACK) + { + /* Let Sender Know if MVID length field + * is larger then SUM of SV length's + */ + if(vlen != 0) + rcode = E_VECTOR_LENGTH_ERROR; + else + { + /* Let Sender Know if Expected SVID Missing */ + if((svectors & R_RQ_ATTCH_STATE_ADDR) + ^ R_RQ_ATTCH_STATE_ADDR) + rcode = E_MISSING_SUB_VECTOR; + } + } + + return rcode; +} + +static int smctr_rcv_unknown(struct net_device *dev, MAC_HEADER *rmf, + __u16 *correlator) +{ + MAC_SUB_VECTOR *rsv; + signed short vlen; + + *correlator = 0; + + /* Remove MVID Length from total length */ + vlen = (signed short)rmf->vl - 4; + + /* Point to First SVID */ + rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER)); + + /* Search for CORRELATOR for RSP to UNKNOWN */ + while((vlen > 0) && (*correlator == 0)) + { + switch(rsv->svi) + { + case CORRELATOR: + smctr_set_corr(dev, rsv, correlator); + break; + + default: + break; + } + + vlen -= rsv->svl; + rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); + } + + return E_UNRECOGNIZED_VECTOR_ID; +} + +/* + * Reset the 825 NIC and exit w: + * 1. The NIC reset cleared (non-reset state), halted and un-initialized. + * 2. TINT masked. + * 3. CBUSY masked. + * 4. TINT clear. + * 5. CBUSY clear. + */ +static int smctr_reset_adapter(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + int ioaddr = dev->base_addr; + + /* Reseting the NIC will put it in a halted and un-initialized state. */ smctr_set_trc_reset(ioaddr); + mdelay(200); /* ~2 ms */ + + smctr_clear_trc_reset(ioaddr); + mdelay(200); /* ~2 ms */ + + /* Remove any latched interrupts that occurred prior to reseting the + * adapter or possibily caused by line glitches due to the reset. + */ + outb(tp->trc_mask | CSR_CLRTINT | CSR_CLRCBUSY, ioaddr + CSR); + + return 0; +} + +static int smctr_restart_tx_chain(struct net_device *dev, short queue) +{ + struct net_local *tp = netdev_priv(dev); + int err = 0; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_restart_tx_chain\n", dev->name); + + if(tp->num_tx_fcbs_used[queue] != 0 && + tp->tx_queue_status[queue] == NOT_TRANSMITING) + { + tp->tx_queue_status[queue] = TRANSMITING; + err = smctr_issue_resume_tx_fcb_cmd(dev, queue); + } + + return err; +} + +static int smctr_ring_status_chg(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_ring_status_chg\n", dev->name); + + /* Check for ring_status_flag: whenever MONITOR_STATE_BIT + * Bit is set, check value of monitor_state, only then we + * enable and start transmit/receive timeout (if and only + * if it is MS_ACTIVE_MONITOR_STATE or MS_STANDBY_MONITOR_STATE) + */ + if(tp->ring_status_flags == MONITOR_STATE_CHANGED) + { + if((tp->monitor_state == MS_ACTIVE_MONITOR_STATE) || + (tp->monitor_state == MS_STANDBY_MONITOR_STATE)) + { + tp->monitor_state_ready = 1; + } + else + { + /* if adapter is NOT in either active monitor + * or standby monitor state => Disable + * transmit/receive timeout. + */ + tp->monitor_state_ready = 0; + + /* Ring speed problem, switching to auto mode. */ + if(tp->monitor_state == MS_MONITOR_FSM_INACTIVE && + !tp->cleanup) + { + printk(KERN_INFO "%s: Incorrect ring speed switching.\n", + dev->name); + smctr_set_ring_speed(dev); + } + } + } + + if(!(tp->ring_status_flags & RING_STATUS_CHANGED)) + return 0; + + switch(tp->ring_status) + { + case RING_RECOVERY: + printk(KERN_INFO "%s: Ring Recovery\n", dev->name); + break; + + case SINGLE_STATION: + printk(KERN_INFO "%s: Single Statinon\n", dev->name); + break; + + case COUNTER_OVERFLOW: + printk(KERN_INFO "%s: Counter Overflow\n", dev->name); + break; + + case REMOVE_RECEIVED: + printk(KERN_INFO "%s: Remove Received\n", dev->name); + break; + + case AUTO_REMOVAL_ERROR: + printk(KERN_INFO "%s: Auto Remove Error\n", dev->name); + break; + + case LOBE_WIRE_FAULT: + printk(KERN_INFO "%s: Lobe Wire Fault\n", dev->name); + break; + + case TRANSMIT_BEACON: + printk(KERN_INFO "%s: Transmit Beacon\n", dev->name); + break; + + case SOFT_ERROR: + printk(KERN_INFO "%s: Soft Error\n", dev->name); + break; + + case HARD_ERROR: + printk(KERN_INFO "%s: Hard Error\n", dev->name); + break; + + case SIGNAL_LOSS: + printk(KERN_INFO "%s: Signal Loss\n", dev->name); + break; + + default: + printk(KERN_INFO "%s: Unknown ring status change\n", + dev->name); + break; + } + + return 0; +} + +static int smctr_rx_frame(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + __u16 queue, status, rx_size, err = 0; + __u8 *pbuff; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_rx_frame\n", dev->name); + + queue = tp->receive_queue_number; + + while((status = tp->rx_fcb_curr[queue]->frame_status) != SUCCESS) + { + err = HARDWARE_FAILED; + + if(((status & 0x007f) == 0) || + ((tp->receive_mask & ACCEPT_ERR_PACKETS) != 0)) + { + /* frame length less the CRC (4 bytes) + FS (1 byte) */ + rx_size = tp->rx_fcb_curr[queue]->frame_length - 5; + + pbuff = smctr_get_rx_pointer(dev, queue); + + smctr_set_page(dev, pbuff); + smctr_disable_16bit(dev); + + /* pbuff points to addr within one page */ + pbuff = (__u8 *)PAGE_POINTER(pbuff); + + if(queue == NON_MAC_QUEUE) + { + struct sk_buff *skb; + + skb = dev_alloc_skb(rx_size); + if (skb) { + skb_put(skb, rx_size); + + skb_copy_to_linear_data(skb, pbuff, rx_size); + + /* Update Counters */ + tp->MacStat.rx_packets++; + tp->MacStat.rx_bytes += skb->len; + + /* Kick the packet on up. */ + skb->protocol = tr_type_trans(skb, dev); + netif_rx(skb); + } else { + } + } + else + smctr_process_rx_packet((MAC_HEADER *)pbuff, + rx_size, dev, status); + } + + smctr_enable_16bit(dev); + smctr_set_page(dev, (__u8 *)tp->ram_access); + smctr_update_rx_chain(dev, queue); + + if(err != SUCCESS) + break; + } + + return err; +} + +static int smctr_send_dat(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned int i, err; + MAC_HEADER *tmf; + FCBlock *fcb; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_send_dat\n", dev->name); + + if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, + sizeof(MAC_HEADER))) == (FCBlock *)(-1L)) + { + return OUT_OF_RESOURCES; + } + + /* Initialize DAT Data Fields. */ + tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; + tmf->ac = MSB(AC_FC_DAT); + tmf->fc = LSB(AC_FC_DAT); + + for(i = 0; i < 6; i++) + { + tmf->sa[i] = dev->dev_addr[i]; + tmf->da[i] = dev->dev_addr[i]; + + } + + tmf->vc = DAT; + tmf->dc_sc = DC_RS | SC_RS; + tmf->vl = 4; + tmf->vl = SWAP_BYTES(tmf->vl); + + /* Start Transmit. */ + if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) + return err; + + /* Wait for Transmit to Complete */ + for(i = 0; i < 10000; i++) + { + if(fcb->frame_status & FCB_COMMAND_DONE) + break; + mdelay(1); + } + + /* Check if GOOD frame Tx'ed. */ + if(!(fcb->frame_status & FCB_COMMAND_DONE) || + fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS)) + { + return INITIALIZE_FAILED; + } + + /* De-allocated Tx FCB and Frame Buffer + * The FCB must be de-allocated manually if executing with + * interrupts disabled, other wise the ISR (LM_Service_Events) + * will de-allocate it when the interrupt occurs. + */ + tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING; + smctr_update_tx_chain(dev, fcb, MAC_QUEUE); + + return 0; +} + +static void smctr_timeout(struct net_device *dev) +{ + /* + * If we get here, some higher level has decided we are broken. + * There should really be a "kick me" function call instead. + * + * Resetting the token ring adapter takes a long time so just + * fake transmission time and go on trying. Our own timeout + * routine is in sktr_timer_chk() + */ + dev->trans_start = jiffies; /* prevent tx timeout */ + netif_wake_queue(dev); +} + +/* + * Gets skb from system, queues it and checks if it can be sent + */ +static netdev_tx_t smctr_send_packet(struct sk_buff *skb, + struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_send_packet\n", dev->name); + + /* + * Block a transmit overlap + */ + + netif_stop_queue(dev); + + if(tp->QueueSkb == 0) + return NETDEV_TX_BUSY; /* Return with tbusy set: queue full */ + + tp->QueueSkb--; + skb_queue_tail(&tp->SendSkbQueue, skb); + smctr_hardware_send_packet(dev, tp); + if(tp->QueueSkb > 0) + netif_wake_queue(dev); + + return NETDEV_TX_OK; +} + +static int smctr_send_lobe_media_test(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + MAC_SUB_VECTOR *tsv; + MAC_HEADER *tmf; + FCBlock *fcb; + __u32 i; + int err; + + if(smctr_debug > 15) + printk(KERN_DEBUG "%s: smctr_send_lobe_media_test\n", dev->name); + + if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(struct trh_hdr) + + S_WRAP_DATA + S_WRAP_DATA)) == (FCBlock *)(-1L)) + { + return OUT_OF_RESOURCES; + } + + /* Initialize DAT Data Fields. */ + tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; + tmf->ac = MSB(AC_FC_LOBE_MEDIA_TEST); + tmf->fc = LSB(AC_FC_LOBE_MEDIA_TEST); + + for(i = 0; i < 6; i++) + { + tmf->da[i] = 0; + tmf->sa[i] = dev->dev_addr[i]; + } + + tmf->vc = LOBE_MEDIA_TEST; + tmf->dc_sc = DC_RS | SC_RS; + tmf->vl = 4; + + tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); + smctr_make_wrap_data(dev, tsv); + tmf->vl += tsv->svl; + + tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); + smctr_make_wrap_data(dev, tsv); + tmf->vl += tsv->svl; + + /* Start Transmit. */ + tmf->vl = SWAP_BYTES(tmf->vl); + if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) + return err; + + /* Wait for Transmit to Complete. (10 ms). */ + for(i=0; i < 10000; i++) + { + if(fcb->frame_status & FCB_COMMAND_DONE) + break; + mdelay(1); + } + + /* Check if GOOD frame Tx'ed */ + if(!(fcb->frame_status & FCB_COMMAND_DONE) || + fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS)) + { + return LOBE_MEDIA_TEST_FAILED; + } + + /* De-allocated Tx FCB and Frame Buffer + * The FCB must be de-allocated manually if executing with + * interrupts disabled, other wise the ISR (LM_Service_Events) + * will de-allocate it when the interrupt occurs. + */ + tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING; + smctr_update_tx_chain(dev, fcb, MAC_QUEUE); + + return 0; +} + +static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf, + __u16 correlator) +{ + MAC_HEADER *tmf; + MAC_SUB_VECTOR *tsv; + FCBlock *fcb; + + if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) + + S_CORRELATOR + S_PHYSICAL_DROP + S_UPSTREAM_NEIGHBOR_ADDRESS + + S_ADDRESS_MODIFER + S_GROUP_ADDRESS + S_FUNCTIONAL_ADDRESS)) + == (FCBlock *)(-1L)) + { + return 0; + } + + tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; + tmf->vc = RPT_ADDR; + tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4; + tmf->vl = 4; + + smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_ADDR); + + tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); + smctr_make_corr(dev, tsv, correlator); + + tmf->vl += tsv->svl; + tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); + smctr_make_phy_drop_num(dev, tsv); + + tmf->vl += tsv->svl; + tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); + smctr_make_upstream_neighbor_addr(dev, tsv); + + tmf->vl += tsv->svl; + tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); + smctr_make_addr_mod(dev, tsv); + + tmf->vl += tsv->svl; + tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); + smctr_make_group_addr(dev, tsv); + + tmf->vl += tsv->svl; + tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); + smctr_make_funct_addr(dev, tsv); + + tmf->vl += tsv->svl; + + /* Subtract out MVID and MVL which is + * include in both vl and MAC_HEADER + */ +/* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4; + fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4; +*/ + tmf->vl = SWAP_BYTES(tmf->vl); + + return smctr_trc_send_packet(dev, fcb, MAC_QUEUE); +} + +static int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf, + __u16 correlator) +{ + MAC_HEADER *tmf; + MAC_SUB_VECTOR *tsv; + FCBlock *fcb; + + if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) + + S_CORRELATOR + S_PRODUCT_INSTANCE_ID + S_FUNCTIONAL_ADDRESS + + S_AUTHORIZED_FUNCTION_CLASS + S_AUTHORIZED_ACCESS_PRIORITY)) + == (FCBlock *)(-1L)) + { + return 0; + } + + tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; + tmf->vc = RPT_ATTCH; + tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4; + tmf->vl = 4; + + smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_ATTCH); + + tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); + smctr_make_corr(dev, tsv, correlator); + + tmf->vl += tsv->svl; + tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); + smctr_make_product_id(dev, tsv); + + tmf->vl += tsv->svl; + tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); + smctr_make_funct_addr(dev, tsv); + + tmf->vl += tsv->svl; + tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); + smctr_make_auth_funct_class(dev, tsv); + + tmf->vl += tsv->svl; + tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); + smctr_make_access_pri(dev, tsv); + + tmf->vl += tsv->svl; + + /* Subtract out MVID and MVL which is + * include in both vl and MAC_HEADER + */ +/* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4; + fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4; +*/ + tmf->vl = SWAP_BYTES(tmf->vl); + + return smctr_trc_send_packet(dev, fcb, MAC_QUEUE); +} + +static int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf, + __u16 correlator) +{ + MAC_HEADER *tmf; + MAC_SUB_VECTOR *tsv; + FCBlock *fcb; + + if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) + + S_CORRELATOR + S_RING_STATION_VERSION_NUMBER + + S_RING_STATION_STATUS + S_STATION_IDENTIFER)) + == (FCBlock *)(-1L)) + { + return 0; + } + + tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; + tmf->vc = RPT_STATE; + tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4; + tmf->vl = 4; + + smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_STATE); + + tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); + smctr_make_corr(dev, tsv, correlator); + + tmf->vl += tsv->svl; + tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); + smctr_make_ring_station_version(dev, tsv); + + tmf->vl += tsv->svl; + tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); + smctr_make_ring_station_status(dev, tsv); + + tmf->vl += tsv->svl; + tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); + smctr_make_station_id(dev, tsv); + + tmf->vl += tsv->svl; + + /* Subtract out MVID and MVL which is + * include in both vl and MAC_HEADER + */ +/* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4; + fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4; +*/ + tmf->vl = SWAP_BYTES(tmf->vl); + + return smctr_trc_send_packet(dev, fcb, MAC_QUEUE); +} + +static int smctr_send_rpt_tx_forward(struct net_device *dev, + MAC_HEADER *rmf, __u16 tx_fstatus) +{ + MAC_HEADER *tmf; + MAC_SUB_VECTOR *tsv; + FCBlock *fcb; + + if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) + + S_TRANSMIT_STATUS_CODE)) == (FCBlock *)(-1L)) + { + return 0; + } + + tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; + tmf->vc = RPT_TX_FORWARD; + tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4; + tmf->vl = 4; + + smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_TX_FORWARD); + + tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); + smctr_make_tx_status_code(dev, tsv, tx_fstatus); + + tmf->vl += tsv->svl; + + /* Subtract out MVID and MVL which is + * include in both vl and MAC_HEADER + */ +/* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4; + fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4; +*/ + tmf->vl = SWAP_BYTES(tmf->vl); + + return smctr_trc_send_packet(dev, fcb, MAC_QUEUE); +} + +static int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf, + __u16 rcode, __u16 correlator) +{ + MAC_HEADER *tmf; + MAC_SUB_VECTOR *tsv; + FCBlock *fcb; + + if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) + + S_CORRELATOR + S_RESPONSE_CODE)) == (FCBlock *)(-1L)) + { + return 0; + } + + tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; + tmf->vc = RSP; + tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4; + tmf->vl = 4; + + smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RSP); + + tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); + smctr_make_corr(dev, tsv, correlator); + + return 0; +} + +static int smctr_send_rq_init(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + MAC_HEADER *tmf; + MAC_SUB_VECTOR *tsv; + FCBlock *fcb; + unsigned int i, count = 0; + __u16 fstatus; + int err; + + do { + if(((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) + + S_PRODUCT_INSTANCE_ID + S_UPSTREAM_NEIGHBOR_ADDRESS + + S_RING_STATION_VERSION_NUMBER + S_ADDRESS_MODIFER)) + == (FCBlock *)(-1L))) + { + return 0; + } + + tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; + tmf->vc = RQ_INIT; + tmf->dc_sc = DC_RPS | SC_RS; + tmf->vl = 4; + + smctr_make_8025_hdr(dev, NULL, tmf, AC_FC_RQ_INIT); + + tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); + smctr_make_product_id(dev, tsv); + + tmf->vl += tsv->svl; + tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); + smctr_make_upstream_neighbor_addr(dev, tsv); + + tmf->vl += tsv->svl; + tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); + smctr_make_ring_station_version(dev, tsv); + + tmf->vl += tsv->svl; + tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl); + smctr_make_addr_mod(dev, tsv); + + tmf->vl += tsv->svl; + + /* Subtract out MVID and MVL which is + * include in both vl and MAC_HEADER + */ +/* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4; + fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4; +*/ + tmf->vl = SWAP_BYTES(tmf->vl); + + if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) + return err; + + /* Wait for Transmit to Complete */ + for(i = 0; i < 10000; i++) + { + if(fcb->frame_status & FCB_COMMAND_DONE) + break; + mdelay(1); + } + + /* Check if GOOD frame Tx'ed */ + fstatus = fcb->frame_status; + + if(!(fstatus & FCB_COMMAND_DONE)) + return HARDWARE_FAILED; + + if(!(fstatus & FCB_TX_STATUS_E)) + count++; + + /* De-allocated Tx FCB and Frame Buffer + * The FCB must be de-allocated manually if executing with + * interrupts disabled, other wise the ISR (LM_Service_Events) + * will de-allocate it when the interrupt occurs. + */ + tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING; + smctr_update_tx_chain(dev, fcb, MAC_QUEUE); + } while(count < 4 && ((fstatus & FCB_TX_AC_BITS) ^ FCB_TX_AC_BITS)); + + return smctr_join_complete_state(dev); +} + +static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf, + __u16 *tx_fstatus) +{ + struct net_local *tp = netdev_priv(dev); + FCBlock *fcb; + unsigned int i; + int err; + + /* Check if this is the END POINT of the Transmit Forward Chain. */ + if(rmf->vl <= 18) + return 0; + + /* Allocate Transmit FCB only by requesting 0 bytes + * of data buffer. + */ + if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, 0)) == (FCBlock *)(-1L)) + return 0; + + /* Set pointer to Transmit Frame Buffer to the data + * portion of the received TX Forward frame, making + * sure to skip over the Vector Code (vc) and Vector + * length (vl). + */ + fcb->bdb_ptr->trc_data_block_ptr = TRC_POINTER((__u32)rmf + + sizeof(MAC_HEADER) + 2); + fcb->bdb_ptr->data_block_ptr = (__u16 *)((__u32)rmf + + sizeof(MAC_HEADER) + 2); + + fcb->frame_length = rmf->vl - 4 - 2; + fcb->bdb_ptr->buffer_length = rmf->vl - 4 - 2; + + if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) + return err; + + /* Wait for Transmit to Complete */ + for(i = 0; i < 10000; i++) + { + if(fcb->frame_status & FCB_COMMAND_DONE) + break; + mdelay(1); + } + + /* Check if GOOD frame Tx'ed */ + if(!(fcb->frame_status & FCB_COMMAND_DONE)) + { + if((err = smctr_issue_resume_tx_fcb_cmd(dev, MAC_QUEUE))) + return err; + + for(i = 0; i < 10000; i++) + { + if(fcb->frame_status & FCB_COMMAND_DONE) + break; + mdelay(1); + } + + if(!(fcb->frame_status & FCB_COMMAND_DONE)) + return HARDWARE_FAILED; + } + + *tx_fstatus = fcb->frame_status; + + return A_FRAME_WAS_FORWARDED; +} + +static int smctr_set_auth_access_pri(struct net_device *dev, + MAC_SUB_VECTOR *rsv) +{ + struct net_local *tp = netdev_priv(dev); + + if(rsv->svl != S_AUTHORIZED_ACCESS_PRIORITY) + return E_SUB_VECTOR_LENGTH_ERROR; + + tp->authorized_access_priority = (rsv->svv[0] << 8 | rsv->svv[1]); + + return POSITIVE_ACK; +} + +static int smctr_set_auth_funct_class(struct net_device *dev, + MAC_SUB_VECTOR *rsv) +{ + struct net_local *tp = netdev_priv(dev); + + if(rsv->svl != S_AUTHORIZED_FUNCTION_CLASS) + return E_SUB_VECTOR_LENGTH_ERROR; + + tp->authorized_function_classes = (rsv->svv[0] << 8 | rsv->svv[1]); + + return POSITIVE_ACK; +} + +static int smctr_set_corr(struct net_device *dev, MAC_SUB_VECTOR *rsv, + __u16 *correlator) +{ + if(rsv->svl != S_CORRELATOR) + return E_SUB_VECTOR_LENGTH_ERROR; + + *correlator = (rsv->svv[0] << 8 | rsv->svv[1]); + + return POSITIVE_ACK; +} + +static int smctr_set_error_timer_value(struct net_device *dev, + MAC_SUB_VECTOR *rsv) +{ + __u16 err_tval; + int err; + + if(rsv->svl != S_ERROR_TIMER_VALUE) + return E_SUB_VECTOR_LENGTH_ERROR; + + err_tval = (rsv->svv[0] << 8 | rsv->svv[1])*10; + + smctr_issue_write_word_cmd(dev, RW_TER_THRESHOLD, &err_tval); + + if((err = smctr_wait_cmd(dev))) + return err; + + return POSITIVE_ACK; +} + +static int smctr_set_frame_forward(struct net_device *dev, + MAC_SUB_VECTOR *rsv, __u8 dc_sc) +{ + if((rsv->svl < 2) || (rsv->svl > S_FRAME_FORWARD)) + return E_SUB_VECTOR_LENGTH_ERROR; + + if((dc_sc & DC_MASK) != DC_CRS) + { + if(rsv->svl >= 2 && rsv->svl < 20) + return E_TRANSMIT_FORWARD_INVALID; + + if((rsv->svv[0] != 0) || (rsv->svv[1] != 0)) + return E_TRANSMIT_FORWARD_INVALID; + } + + return POSITIVE_ACK; +} + +static int smctr_set_local_ring_num(struct net_device *dev, + MAC_SUB_VECTOR *rsv) +{ + struct net_local *tp = netdev_priv(dev); + + if(rsv->svl != S_LOCAL_RING_NUMBER) + return E_SUB_VECTOR_LENGTH_ERROR; + + if(tp->ptr_local_ring_num) + *(__u16 *)(tp->ptr_local_ring_num) + = (rsv->svv[0] << 8 | rsv->svv[1]); + + return POSITIVE_ACK; +} + +static unsigned short smctr_set_ctrl_attention(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + int ioaddr = dev->base_addr; + + if(tp->bic_type == BIC_585_CHIP) + outb((tp->trc_mask | HWR_CA), ioaddr + HWR); + else + { + outb((tp->trc_mask | CSR_CA), ioaddr + CSR); + outb(tp->trc_mask, ioaddr + CSR); + } + + return 0; +} + +static void smctr_set_multicast_list(struct net_device *dev) +{ + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_set_multicast_list\n", dev->name); +} + +static int smctr_set_page(struct net_device *dev, __u8 *buf) +{ + struct net_local *tp = netdev_priv(dev); + __u8 amask; + __u32 tptr; + + tptr = (__u32)buf - (__u32)tp->ram_access; + amask = (__u8)((tptr & PR_PAGE_MASK) >> 8); + outb(amask, dev->base_addr + PR); + + return 0; +} + +static int smctr_set_phy_drop(struct net_device *dev, MAC_SUB_VECTOR *rsv) +{ + int err; + + if(rsv->svl != S_PHYSICAL_DROP) + return E_SUB_VECTOR_LENGTH_ERROR; + + smctr_issue_write_byte_cmd(dev, RW_PHYSICAL_DROP_NUMBER, &rsv->svv[0]); + if((err = smctr_wait_cmd(dev))) + return err; + + return POSITIVE_ACK; +} + +/* Reset the ring speed to the opposite of what it was. This auto-pilot + * mode requires a complete reset and re-init of the adapter. + */ +static int smctr_set_ring_speed(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + int err; + + if(tp->media_type == MEDIA_UTP_16) + tp->media_type = MEDIA_UTP_4; + else + tp->media_type = MEDIA_UTP_16; + + smctr_enable_16bit(dev); + + /* Re-Initialize adapter's internal registers */ + smctr_reset_adapter(dev); + + if((err = smctr_init_card_real(dev))) + return err; + + smctr_enable_bic_int(dev); + + if((err = smctr_issue_enable_int_cmd(dev, TRC_INTERRUPT_ENABLE_MASK))) + return err; + + smctr_disable_16bit(dev); + + return 0; +} + +static int smctr_set_rx_look_ahead(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + __u16 sword, rword; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_set_rx_look_ahead_flag\n", dev->name); + + tp->adapter_flags &= ~(FORCED_16BIT_MODE); + tp->adapter_flags |= RX_VALID_LOOKAHEAD; + + if(tp->adapter_bus == BUS_ISA16_TYPE) + { + sword = *((__u16 *)(tp->ram_access)); + *((__u16 *)(tp->ram_access)) = 0x1234; + + smctr_disable_16bit(dev); + rword = *((__u16 *)(tp->ram_access)); + smctr_enable_16bit(dev); + + if(rword != 0x1234) + tp->adapter_flags |= FORCED_16BIT_MODE; + + *((__u16 *)(tp->ram_access)) = sword; + } + + return 0; +} + +static int smctr_set_trc_reset(int ioaddr) +{ + __u8 r; + + r = inb(ioaddr + MSR); + outb(MSR_RST | r, ioaddr + MSR); + + return 0; +} + +/* + * This function can be called if the adapter is busy or not. + */ +static int smctr_setup_single_cmd(struct net_device *dev, + __u16 command, __u16 subcommand) +{ + struct net_local *tp = netdev_priv(dev); + unsigned int err; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_setup_single_cmd\n", dev->name); + + if((err = smctr_wait_while_cbusy(dev))) + return err; + + if((err = (unsigned int)smctr_wait_cmd(dev))) + return err; + + tp->acb_head->cmd_done_status = 0; + tp->acb_head->cmd = command; + tp->acb_head->subcmd = subcommand; + + err = smctr_issue_resume_acb_cmd(dev); + + return err; +} + +/* + * This function can not be called with the adapter busy. + */ +static int smctr_setup_single_cmd_w_data(struct net_device *dev, + __u16 command, __u16 subcommand) +{ + struct net_local *tp = netdev_priv(dev); + + tp->acb_head->cmd_done_status = ACB_COMMAND_NOT_DONE; + tp->acb_head->cmd = command; + tp->acb_head->subcmd = subcommand; + tp->acb_head->data_offset_lo + = (__u16)TRC_POINTER(tp->misc_command_data); + + return smctr_issue_resume_acb_cmd(dev); +} + +static char *smctr_malloc(struct net_device *dev, __u16 size) +{ + struct net_local *tp = netdev_priv(dev); + char *m; + + m = (char *)(tp->ram_access + tp->sh_mem_used); + tp->sh_mem_used += (__u32)size; + + return m; +} + +static int smctr_status_chg(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_status_chg\n", dev->name); + + switch(tp->status) + { + case OPEN: + break; + + case CLOSED: + break; + + /* Interrupt driven open() completion. XXX */ + case INITIALIZED: + tp->group_address_0 = 0; + tp->group_address[0] = 0; + tp->group_address[1] = 0; + tp->functional_address_0 = 0; + tp->functional_address[0] = 0; + tp->functional_address[1] = 0; + smctr_open_tr(dev); + break; + + default: + printk(KERN_INFO "%s: status change unknown %x\n", + dev->name, tp->status); + break; + } + + return 0; +} + +static int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb, + __u16 queue) +{ + struct net_local *tp = netdev_priv(dev); + int err = 0; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_trc_send_packet\n", dev->name); + + fcb->info = FCB_CHAIN_END | FCB_ENABLE_TFS; + if(tp->num_tx_fcbs[queue] != 1) + fcb->back_ptr->info = FCB_INTERRUPT_ENABLE | FCB_ENABLE_TFS; + + if(tp->tx_queue_status[queue] == NOT_TRANSMITING) + { + tp->tx_queue_status[queue] = TRANSMITING; + err = smctr_issue_resume_tx_fcb_cmd(dev, queue); + } + + return err; +} + +static __u16 smctr_tx_complete(struct net_device *dev, __u16 queue) +{ + struct net_local *tp = netdev_priv(dev); + __u16 status, err = 0; + int cstatus; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_tx_complete\n", dev->name); + + while((status = tp->tx_fcb_end[queue]->frame_status) != SUCCESS) + { + if(status & 0x7e00 ) + { + err = HARDWARE_FAILED; + break; + } + + if((err = smctr_update_tx_chain(dev, tp->tx_fcb_end[queue], + queue)) != SUCCESS) + break; + + smctr_disable_16bit(dev); + + if(tp->mode_bits & UMAC) + { + if(!(status & (FCB_TX_STATUS_AR1 | FCB_TX_STATUS_AR2))) + cstatus = NO_SUCH_DESTINATION; + else + { + if(!(status & (FCB_TX_STATUS_CR1 | FCB_TX_STATUS_CR2))) + cstatus = DEST_OUT_OF_RESOURCES; + else + { + if(status & FCB_TX_STATUS_E) + cstatus = MAX_COLLISIONS; + else + cstatus = SUCCESS; + } + } + } + else + cstatus = SUCCESS; + + if(queue == BUG_QUEUE) + err = SUCCESS; + + smctr_enable_16bit(dev); + if(err != SUCCESS) + break; + } + + return err; +} + +static unsigned short smctr_tx_move_frame(struct net_device *dev, + struct sk_buff *skb, __u8 *pbuff, unsigned int bytes) +{ + struct net_local *tp = netdev_priv(dev); + unsigned int ram_usable; + __u32 flen, len, offset = 0; + __u8 *frag, *page; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_tx_move_frame\n", dev->name); + + ram_usable = ((unsigned int)tp->ram_usable) << 10; + frag = skb->data; + flen = skb->len; + + while(flen > 0 && bytes > 0) + { + smctr_set_page(dev, pbuff); + + offset = SMC_PAGE_OFFSET(pbuff); + + if(offset + flen > ram_usable) + len = ram_usable - offset; + else + len = flen; + + if(len > bytes) + len = bytes; + + page = (char *) (offset + tp->ram_access); + memcpy(page, frag, len); + + flen -=len; + bytes -= len; + frag += len; + pbuff += len; + } + + return 0; +} + +/* Update the error statistic counters for this adapter. */ +static int smctr_update_err_stats(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + struct tr_statistics *tstat = &tp->MacStat; + + if(tstat->internal_errors) + tstat->internal_errors + += *(tp->misc_command_data + 0) & 0x00ff; + + if(tstat->line_errors) + tstat->line_errors += *(tp->misc_command_data + 0) >> 8; + + if(tstat->A_C_errors) + tstat->A_C_errors += *(tp->misc_command_data + 1) & 0x00ff; + + if(tstat->burst_errors) + tstat->burst_errors += *(tp->misc_command_data + 1) >> 8; + + if(tstat->abort_delimiters) + tstat->abort_delimiters += *(tp->misc_command_data + 2) >> 8; + + if(tstat->recv_congest_count) + tstat->recv_congest_count + += *(tp->misc_command_data + 3) & 0x00ff; + + if(tstat->lost_frames) + tstat->lost_frames + += *(tp->misc_command_data + 3) >> 8; + + if(tstat->frequency_errors) + tstat->frequency_errors += *(tp->misc_command_data + 4) & 0x00ff; + + if(tstat->frame_copied_errors) + tstat->frame_copied_errors + += *(tp->misc_command_data + 4) >> 8; + + if(tstat->token_errors) + tstat->token_errors += *(tp->misc_command_data + 5) >> 8; + + return 0; +} + +static int smctr_update_rx_chain(struct net_device *dev, __u16 queue) +{ + struct net_local *tp = netdev_priv(dev); + FCBlock *fcb; + BDBlock *bdb; + __u16 size, len; + + fcb = tp->rx_fcb_curr[queue]; + len = fcb->frame_length; + + fcb->frame_status = 0; + fcb->info = FCB_CHAIN_END; + fcb->back_ptr->info = FCB_WARNING; + + tp->rx_fcb_curr[queue] = tp->rx_fcb_curr[queue]->next_ptr; + + /* update RX BDBs */ + size = (len >> RX_BDB_SIZE_SHIFT); + if(len & RX_DATA_BUFFER_SIZE_MASK) + size += sizeof(BDBlock); + size &= (~RX_BDB_SIZE_MASK); + + /* check if wrap around */ + bdb = (BDBlock *)((__u32)(tp->rx_bdb_curr[queue]) + (__u32)(size)); + if((__u32)bdb >= (__u32)tp->rx_bdb_end[queue]) + { + bdb = (BDBlock *)((__u32)(tp->rx_bdb_head[queue]) + + (__u32)(bdb) - (__u32)(tp->rx_bdb_end[queue])); + } + + bdb->back_ptr->info = BDB_CHAIN_END; + tp->rx_bdb_curr[queue]->back_ptr->info = BDB_NOT_CHAIN_END; + tp->rx_bdb_curr[queue] = bdb; + + return 0; +} + +static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb, + __u16 queue) +{ + struct net_local *tp = netdev_priv(dev); + + if(smctr_debug > 20) + printk(KERN_DEBUG "smctr_update_tx_chain\n"); + + if(tp->num_tx_fcbs_used[queue] <= 0) + return HARDWARE_FAILED; + else + { + if(tp->tx_buff_used[queue] < fcb->memory_alloc) + { + tp->tx_buff_used[queue] = 0; + return HARDWARE_FAILED; + } + + tp->tx_buff_used[queue] -= fcb->memory_alloc; + + /* if all transmit buffer are cleared + * need to set the tx_buff_curr[] to tx_buff_head[] + * otherwise, tx buffer will be segregate and cannot + * accommodate and buffer greater than (curr - head) and + * (end - curr) since we do not allow wrap around allocation. + */ + if(tp->tx_buff_used[queue] == 0) + tp->tx_buff_curr[queue] = tp->tx_buff_head[queue]; + + tp->num_tx_fcbs_used[queue]--; + fcb->frame_status = 0; + tp->tx_fcb_end[queue] = fcb->next_ptr; + netif_wake_queue(dev); + return 0; + } +} + +static int smctr_wait_cmd(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned int loop_count = 0x20000; + + if(smctr_debug > 10) + printk(KERN_DEBUG "%s: smctr_wait_cmd\n", dev->name); + + while(loop_count) + { + if(tp->acb_head->cmd_done_status & ACB_COMMAND_DONE) + break; + udelay(1); + loop_count--; + } + + if(loop_count == 0) + return HARDWARE_FAILED; + + if(tp->acb_head->cmd_done_status & 0xff) + return HARDWARE_FAILED; + + return 0; +} + +static int smctr_wait_while_cbusy(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned int timeout = 0x20000; + int ioaddr = dev->base_addr; + __u8 r; + + if(tp->bic_type == BIC_585_CHIP) + { + while(timeout) + { + r = inb(ioaddr + HWR); + if((r & HWR_CBUSY) == 0) + break; + timeout--; + } + } + else + { + while(timeout) + { + r = inb(ioaddr + CSR); + if((r & CSR_CBUSY) == 0) + break; + timeout--; + } + } + + if(timeout) + return 0; + else + return HARDWARE_FAILED; +} + +#ifdef MODULE + +static struct net_device* dev_smctr[SMCTR_MAX_ADAPTERS]; +static int io[SMCTR_MAX_ADAPTERS]; +static int irq[SMCTR_MAX_ADAPTERS]; + +MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("tr_smctr.bin"); + +module_param_array(io, int, NULL, 0); +module_param_array(irq, int, NULL, 0); +module_param(ringspeed, int, 0); + +static struct net_device * __init setup_card(int n) +{ + struct net_device *dev = alloc_trdev(sizeof(struct net_local)); + int err; + + if (!dev) + return ERR_PTR(-ENOMEM); + + dev->irq = irq[n]; + err = smctr_probe1(dev, io[n]); + if (err) + goto out; + + err = register_netdev(dev); + if (err) + goto out1; + return dev; + out1: +#ifdef CONFIG_MCA_LEGACY + { struct net_local *tp = netdev_priv(dev); + if (tp->slot_num) + mca_mark_as_unused(tp->slot_num); + } +#endif + release_region(dev->base_addr, SMCTR_IO_EXTENT); + free_irq(dev->irq, dev); +out: + free_netdev(dev); + return ERR_PTR(err); +} + +int __init init_module(void) +{ + int i, found = 0; + struct net_device *dev; + + for(i = 0; i < SMCTR_MAX_ADAPTERS; i++) { + dev = io[0]? setup_card(i) : smctr_probe(-1); + if (!IS_ERR(dev)) { + ++found; + dev_smctr[i] = dev; + } + } + + return found ? 0 : -ENODEV; +} + +void __exit cleanup_module(void) +{ + int i; + + for(i = 0; i < SMCTR_MAX_ADAPTERS; i++) { + struct net_device *dev = dev_smctr[i]; + + if (dev) { + + unregister_netdev(dev); +#ifdef CONFIG_MCA_LEGACY + { struct net_local *tp = netdev_priv(dev); + if (tp->slot_num) + mca_mark_as_unused(tp->slot_num); + } +#endif + release_region(dev->base_addr, SMCTR_IO_EXTENT); + if (dev->irq) + free_irq(dev->irq, dev); + + free_netdev(dev); + } + } +} +#endif /* MODULE */ diff --git a/trunk/drivers/net/tokenring/smctr.h b/trunk/drivers/net/tokenring/smctr.h new file mode 100644 index 000000000000..6e5700ab4fc3 --- /dev/null +++ b/trunk/drivers/net/tokenring/smctr.h @@ -0,0 +1,1585 @@ +/* smctr.h: SMC Token Ring driver header for Linux + * + * Authors: + * - Jay Schulist + */ + +#ifndef __LINUX_SMCTR_H +#define __LINUX_SMCTR_H + +#ifdef __KERNEL__ + +#define MAX_TX_QUEUE 10 + +#define SMC_HEADER_SIZE 14 + +#define SMC_PAGE_OFFSET(X) (((unsigned long)(X) - tp->ram_access) & tp->page_offset_mask) + +#define INIT 0x0D +#define RQ_ATTCH 0x10 +#define RQ_STATE 0x0F +#define RQ_ADDR 0x0E +#define CHG_PARM 0x0C +#define RSP 0x00 +#define TX_FORWARD 0x09 + +#define AC_FC_DAT ((3<<13) | 1) +#define DAT 0x07 + +#define RPT_NEW_MON 0x25 +#define RPT_SUA_CHG 0x26 +#define RPT_ACTIVE_ERR 0x28 +#define RPT_NN_INCMP 0x27 +#define RPT_ERROR 0x29 + +#define RQ_INIT 0x20 +#define RPT_ATTCH 0x24 +#define RPT_STATE 0x23 +#define RPT_ADDR 0x22 + +#define POSITIVE_ACK 0x0001 +#define A_FRAME_WAS_FORWARDED 0x8888 + +#define GROUP_ADDRESS 0x2B +#define PHYSICAL_DROP 0x0B +#define AUTHORIZED_ACCESS_PRIORITY 0x07 +#define AUTHORIZED_FUNCTION_CLASS 0x06 +#define FUNCTIONAL_ADDRESS 0x2C +#define RING_STATION_STATUS 0x29 +#define TRANSMIT_STATUS_CODE 0x2A +#define IBM_PASS_SOURCE_ADDR 0x01 +#define AC_FC_RPT_TX_FORWARD ((0<<13) | 0) +#define AC_FC_RPT_STATE ((0<<13) | 0) +#define AC_FC_RPT_ADDR ((0<<13) | 0) +#define CORRELATOR 0x09 + +#define POSITIVE_ACK 0x0001 /* */ +#define E_MAC_DATA_INCOMPLETE 0x8001 /* not used */ +#define E_VECTOR_LENGTH_ERROR 0x8002 /* */ +#define E_UNRECOGNIZED_VECTOR_ID 0x8003 /* */ +#define E_INAPPROPRIATE_SOURCE_CLASS 0x8004 /* */ +#define E_SUB_VECTOR_LENGTH_ERROR 0x8005 /* */ +#define E_TRANSMIT_FORWARD_INVALID 0x8006 /* def. by IBM */ +#define E_MISSING_SUB_VECTOR 0x8007 /* */ +#define E_SUB_VECTOR_UNKNOWN 0x8008 /* */ +#define E_MAC_HEADER_TOO_LONG 0x8009 /* */ +#define E_FUNCTION_DISABLED 0x800A /* not used */ + +#define A_FRAME_WAS_FORWARDED 0x8888 /* used by send_TX_FORWARD */ + +#define UPSTREAM_NEIGHBOR_ADDRESS 0x02 +#define LOCAL_RING_NUMBER 0x03 +#define ASSIGN_PHYSICAL_DROP 0x04 +#define ERROR_TIMER_VALUE 0x05 +#define AUTHORIZED_FUNCTION_CLASS 0x06 +#define AUTHORIZED_ACCESS_PRIORITY 0x07 +#define CORRELATOR 0x09 +#define PHYSICAL_DROP 0x0B +#define RESPONSE_CODE 0x20 +#define ADDRESS_MODIFER 0x21 +#define PRODUCT_INSTANCE_ID 0x22 +#define RING_STATION_VERSION_NUMBER 0x23 +#define WRAP_DATA 0x26 +#define FRAME_FORWARD 0x27 +#define STATION_IDENTIFER 0x28 +#define RING_STATION_STATUS 0x29 +#define TRANSMIT_STATUS_CODE 0x2A +#define GROUP_ADDRESS 0x2B +#define FUNCTIONAL_ADDRESS 0x2C + +#define F_NO_SUB_VECTORS_FOUND 0x0000 +#define F_UPSTREAM_NEIGHBOR_ADDRESS 0x0001 +#define F_LOCAL_RING_NUMBER 0x0002 +#define F_ASSIGN_PHYSICAL_DROP 0x0004 +#define F_ERROR_TIMER_VALUE 0x0008 +#define F_AUTHORIZED_FUNCTION_CLASS 0x0010 +#define F_AUTHORIZED_ACCESS_PRIORITY 0x0020 +#define F_CORRELATOR 0x0040 +#define F_PHYSICAL_DROP 0x0080 +#define F_RESPONSE_CODE 0x0100 +#define F_PRODUCT_INSTANCE_ID 0x0200 +#define F_RING_STATION_VERSION_NUMBER 0x0400 +#define F_STATION_IDENTIFER 0x0800 +#define F_RING_STATION_STATUS 0x1000 +#define F_GROUP_ADDRESS 0x2000 +#define F_FUNCTIONAL_ADDRESS 0x4000 +#define F_FRAME_FORWARD 0x8000 + +#define R_INIT 0x00 +#define R_RQ_ATTCH_STATE_ADDR 0x00 +#define R_CHG_PARM 0x00 +#define R_TX_FORWARD F_FRAME_FORWARD + + +#define UPSTREAM_NEIGHBOR_ADDRESS 0x02 +#define ADDRESS_MODIFER 0x21 +#define RING_STATION_VERSION_NUMBER 0x23 +#define PRODUCT_INSTANCE_ID 0x22 + +#define RPT_TX_FORWARD 0x2A + +#define AC_FC_INIT (3<<13) | 0 /* */ +#define AC_FC_RQ_INIT ((3<<13) | 0) /* */ +#define AC_FC_RQ_ATTCH (3<<13) | 0 /* DC = SC of rx frame */ +#define AC_FC_RQ_STATE (3<<13) | 0 /* DC = SC of rx frame */ +#define AC_FC_RQ_ADDR (3<<13) | 0 /* DC = SC of rx frame */ +#define AC_FC_CHG_PARM (3<<13) | 0 /* */ +#define AC_FC_RSP (0<<13) | 0 /* DC = SC of rx frame */ +#define AC_FC_RPT_ATTCH (0<<13) | 0 + +#define S_UPSTREAM_NEIGHBOR_ADDRESS 6 + 2 +#define S_LOCAL_RING_NUMBER 2 + 2 +#define S_ASSIGN_PHYSICAL_DROP 4 + 2 +#define S_ERROR_TIMER_VALUE 2 + 2 +#define S_AUTHORIZED_FUNCTION_CLASS 2 + 2 +#define S_AUTHORIZED_ACCESS_PRIORITY 2 + 2 +#define S_CORRELATOR 2 + 2 +#define S_PHYSICAL_DROP 4 + 2 +#define S_RESPONSE_CODE 4 + 2 +#define S_ADDRESS_MODIFER 2 + 2 +#define S_PRODUCT_INSTANCE_ID 18 + 2 +#define S_RING_STATION_VERSION_NUMBER 10 + 2 +#define S_STATION_IDENTIFER 6 + 2 +#define S_RING_STATION_STATUS 6 + 2 +#define S_GROUP_ADDRESS 4 + 2 +#define S_FUNCTIONAL_ADDRESS 4 + 2 +#define S_FRAME_FORWARD 252 + 2 +#define S_TRANSMIT_STATUS_CODE 2 + 2 + +#define ISB_IMC_RES0 0x0000 /* */ +#define ISB_IMC_MAC_TYPE_3 0x0001 /* MAC_ARC_INDICATE */ +#define ISB_IMC_MAC_ERROR_COUNTERS 0x0002 /* */ +#define ISB_IMC_RES1 0x0003 /* */ +#define ISB_IMC_MAC_TYPE_2 0x0004 /* QUE_MAC_INDICATE */ +#define ISB_IMC_TX_FRAME 0x0005 /* */ +#define ISB_IMC_END_OF_TX_QUEUE 0x0006 /* */ +#define ISB_IMC_NON_MAC_RX_RESOURCE 0x0007 /* */ +#define ISB_IMC_MAC_RX_RESOURCE 0x0008 /* */ +#define ISB_IMC_NON_MAC_RX_FRAME 0x0009 /* */ +#define ISB_IMC_MAC_RX_FRAME 0x000A /* */ +#define ISB_IMC_TRC_FIFO_STATUS 0x000B /* */ +#define ISB_IMC_COMMAND_STATUS 0x000C /* */ +#define ISB_IMC_MAC_TYPE_1 0x000D /* Self Removed */ +#define ISB_IMC_TRC_INTRNL_TST_STATUS 0x000E /* */ +#define ISB_IMC_RES2 0x000F /* */ + +#define NON_MAC_RX_RESOURCE_BW 0x10 /* shifted right 8 bits */ +#define NON_MAC_RX_RESOURCE_FW 0x20 /* shifted right 8 bits */ +#define NON_MAC_RX_RESOURCE_BE 0x40 /* shifted right 8 bits */ +#define NON_MAC_RX_RESOURCE_FE 0x80 /* shifted right 8 bits */ +#define RAW_NON_MAC_RX_RESOURCE_BW 0x1000 /* */ +#define RAW_NON_MAC_RX_RESOURCE_FW 0x2000 /* */ +#define RAW_NON_MAC_RX_RESOURCE_BE 0x4000 /* */ +#define RAW_NON_MAC_RX_RESOURCE_FE 0x8000 /* */ + +#define MAC_RX_RESOURCE_BW 0x10 /* shifted right 8 bits */ +#define MAC_RX_RESOURCE_FW 0x20 /* shifted right 8 bits */ +#define MAC_RX_RESOURCE_BE 0x40 /* shifted right 8 bits */ +#define MAC_RX_RESOURCE_FE 0x80 /* shifted right 8 bits */ +#define RAW_MAC_RX_RESOURCE_BW 0x1000 /* */ +#define RAW_MAC_RX_RESOURCE_FW 0x2000 /* */ +#define RAW_MAC_RX_RESOURCE_BE 0x4000 /* */ +#define RAW_MAC_RX_RESOURCE_FE 0x8000 /* */ + +#define TRC_FIFO_STATUS_TX_UNDERRUN 0x40 /* shifted right 8 bits */ +#define TRC_FIFO_STATUS_RX_OVERRUN 0x80 /* shifted right 8 bits */ +#define RAW_TRC_FIFO_STATUS_TX_UNDERRUN 0x4000 /* */ +#define RAW_TRC_FIFO_STATUS_RX_OVERRUN 0x8000 /* */ + +#define CSR_CLRTINT 0x08 + +#define MSB(X) ((__u8)((__u16) X >> 8)) +#define LSB(X) ((__u8)((__u16) X & 0xff)) + +#define AC_FC_LOBE_MEDIA_TEST ((3<<13) | 0) +#define S_WRAP_DATA 248 + 2 /* 500 + 2 */ +#define WRAP_DATA 0x26 +#define LOBE_MEDIA_TEST 0x08 + +/* Destination Class (dc) */ + +#define DC_MASK 0xF0 +#define DC_RS 0x00 +#define DC_CRS 0x40 +#define DC_RPS 0x50 +#define DC_REM 0x60 + +/* Source Classes (sc) */ + +#define SC_MASK 0x0F +#define SC_RS 0x00 +#define SC_CRS 0x04 +#define SC_RPS 0x05 +#define SC_REM 0x06 + +#define PR 0x11 +#define PR_PAGE_MASK 0x0C000 + +#define MICROCHANNEL 0x0008 +#define INTERFACE_CHIP 0x0010 +#define BOARD_16BIT 0x0040 +#define PAGED_RAM 0x0080 +#define WD8115TA (TOKEN_MEDIA | MICROCHANNEL | INTERFACE_CHIP | PAGED_RAM) +#define WD8115T (TOKEN_MEDIA | INTERFACE_CHIP | BOARD_16BIT | PAGED_RAM) + +#define BRD_ID_8316 0x50 + +#define r587_SER 0x001 +#define SER_DIN 0x80 +#define SER_DOUT 0x40 +#define SER_CLK 0x20 +#define SER_ECS 0x10 +#define SER_E806 0x08 +#define SER_PNP 0x04 +#define SER_BIO 0x02 +#define SER_16B 0x01 + +#define r587_IDR 0x004 +#define IDR_IRQ_MASK 0x0F0 +#define IDR_DCS_MASK 0x007 +#define IDR_RWS 0x008 + + +#define r587_BIO 0x003 +#define BIO_ENB 0x080 +#define BIO_MASK 0x03F + +#define r587_PCR 0x005 +#define PCR_RAMS 0x040 + + + +#define NUM_ADDR_BITS 8 + +#define ISA_MAX_ADDRESS 0x00ffffff + +#define SMCTR_MAX_ADAPTERS 7 + +#define MC_TABLE_ENTRIES 16 + +#define MAXFRAGMENTS 32 + +#define CHIP_REV_MASK 0x3000 + +#define MAX_TX_QS 8 +#define NUM_TX_QS_USED 3 + +#define MAX_RX_QS 2 +#define NUM_RX_QS_USED 2 + +#define INTEL_DATA_FORMAT 0x4000 +#define INTEL_ADDRESS_POINTER_FORMAT 0x8000 +#define PAGE_POINTER(X) ((((unsigned long)(X) - tp->ram_access) & tp->page_offset_mask) + tp->ram_access) +#define SWAP_WORDS(X) (((X & 0xFFFF) << 16) | (X >> 16)) + +#define INTERFACE_CHIP 0x0010 /* Soft Config Adapter */ +#define ADVANCED_FEATURES 0x0020 /* Adv. netw. interface features */ +#define BOARD_16BIT 0x0040 /* 16 bit capability */ +#define PAGED_RAM 0x0080 /* Adapter has paged RAM */ + +#define PAGED_ROM 0x0100 /* Adapter has paged ROM */ + +#define RAM_SIZE_UNKNOWN 0x0000 /* Unknown RAM size */ +#define RAM_SIZE_0K 0x0001 /* 0K RAM */ +#define RAM_SIZE_8K 0x0002 /* 8k RAM */ +#define RAM_SIZE_16K 0x0003 /* 16k RAM */ +#define RAM_SIZE_32K 0x0004 /* 32k RAM */ +#define RAM_SIZE_64K 0x0005 /* 64k RAM */ +#define RAM_SIZE_RESERVED_6 0x0006 /* Reserved RAM size */ +#define RAM_SIZE_RESERVED_7 0x0007 /* Reserved RAM size */ +#define RAM_SIZE_MASK 0x0007 /* Isolates RAM Size */ + +#define TOKEN_MEDIA 0x0005 + +#define BID_REG_0 0x00 +#define BID_REG_1 0x01 +#define BID_REG_2 0x02 +#define BID_REG_3 0x03 +#define BID_REG_4 0x04 +#define BID_REG_5 0x05 +#define BID_REG_6 0x06 +#define BID_REG_7 0x07 +#define BID_LAR_0 0x08 +#define BID_LAR_1 0x09 +#define BID_LAR_2 0x0A +#define BID_LAR_3 0x0B +#define BID_LAR_4 0x0C +#define BID_LAR_5 0x0D + +#define BID_BOARD_ID_BYTE 0x0E +#define BID_CHCKSM_BYTE 0x0F +#define BID_LAR_OFFSET 0x08 + +#define BID_MSZ_583_BIT 0x08 +#define BID_SIXTEEN_BIT_BIT 0x01 + +#define BID_BOARD_REV_MASK 0x1E + +#define BID_MEDIA_TYPE_BIT 0x01 +#define BID_SOFT_CONFIG_BIT 0x20 +#define BID_RAM_SIZE_BIT 0x40 +#define BID_BUS_TYPE_BIT 0x80 + +#define BID_CR 0x10 + +#define BID_TXP 0x04 /* Transmit Packet Command */ + +#define BID_TCR_DIFF 0x0D /* Transmit Configuration Register */ + +#define BID_TCR_VAL 0x18 /* Value to Test 8390 or 690 */ +#define BID_PS0 0x00 /* Register Page Select 0 */ +#define BID_PS1 0x40 /* Register Page Select 1 */ +#define BID_PS2 0x80 /* Register Page Select 2 */ +#define BID_PS_MASK 0x3F /* For Masking Off Page Select Bits */ + +#define BID_EEPROM_0 0x08 +#define BID_EEPROM_1 0x09 +#define BID_EEPROM_2 0x0A +#define BID_EEPROM_3 0x0B +#define BID_EEPROM_4 0x0C +#define BID_EEPROM_5 0x0D +#define BID_EEPROM_6 0x0E +#define BID_EEPROM_7 0x0F + +#define BID_OTHER_BIT 0x02 +#define BID_ICR_MASK 0x0C +#define BID_EAR_MASK 0x0F +#define BID_ENGR_PAGE 0x0A0 +#define BID_RLA 0x10 +#define BID_EA6 0x80 +#define BID_RECALL_DONE_MASK 0x10 +#define BID_BID_EEPROM_OVERRIDE 0xFFB0 +#define BID_EXTRA_EEPROM_OVERRIDE 0xFFD0 +#define BID_EEPROM_MEDIA_MASK 0x07 +#define BID_STARLAN_TYPE 0x00 +#define BID_ETHERNET_TYPE 0x01 +#define BID_TP_TYPE 0x02 +#define BID_EW_TYPE 0x03 +#define BID_TOKEN_RING_TYPE 0x04 +#define BID_UTP2_TYPE 0x05 +#define BID_EEPROM_IRQ_MASK 0x18 +#define BID_PRIMARY_IRQ 0x00 +#define BID_ALTERNATE_IRQ_1 0x08 +#define BID_ALTERNATE_IRQ_2 0x10 +#define BID_ALTERNATE_IRQ_3 0x18 +#define BID_EEPROM_RAM_SIZE_MASK 0xE0 +#define BID_EEPROM_RAM_SIZE_RES1 0x00 +#define BID_EEPROM_RAM_SIZE_RES2 0x20 +#define BID_EEPROM_RAM_SIZE_8K 0x40 +#define BID_EEPROM_RAM_SIZE_16K 0x60 +#define BID_EEPROM_RAM_SIZE_32K 0x80 +#define BID_EEPROM_RAM_SIZE_64K 0xA0 +#define BID_EEPROM_RAM_SIZE_RES3 0xC0 +#define BID_EEPROM_RAM_SIZE_RES4 0xE0 +#define BID_EEPROM_BUS_TYPE_MASK 0x07 +#define BID_EEPROM_BUS_TYPE_AT 0x00 +#define BID_EEPROM_BUS_TYPE_MCA 0x01 +#define BID_EEPROM_BUS_TYPE_EISA 0x02 +#define BID_EEPROM_BUS_TYPE_NEC 0x03 +#define BID_EEPROM_BUS_SIZE_MASK 0x18 +#define BID_EEPROM_BUS_SIZE_8BIT 0x00 +#define BID_EEPROM_BUS_SIZE_16BIT 0x08 +#define BID_EEPROM_BUS_SIZE_32BIT 0x10 +#define BID_EEPROM_BUS_SIZE_64BIT 0x18 +#define BID_EEPROM_BUS_MASTER 0x20 +#define BID_EEPROM_RAM_PAGING 0x40 +#define BID_EEPROM_ROM_PAGING 0x80 +#define BID_EEPROM_PAGING_MASK 0xC0 +#define BID_EEPROM_LOW_COST 0x08 +#define BID_EEPROM_IO_MAPPED 0x10 +#define BID_EEPROM_HMI 0x01 +#define BID_EEPROM_AUTO_MEDIA_DETECT 0x01 +#define BID_EEPROM_CHIP_REV_MASK 0x0C + +#define BID_EEPROM_LAN_ADDR 0x30 + +#define BID_EEPROM_MEDIA_OPTION 0x54 +#define BID_EEPROM_MEDIA_UTP 0x01 +#define BID_EEPROM_4MB_RING 0x08 +#define BID_EEPROM_16MB_RING 0x10 +#define BID_EEPROM_MEDIA_STP 0x40 + +#define BID_EEPROM_MISC_DATA 0x56 +#define BID_EEPROM_EARLY_TOKEN_RELEASE 0x02 + +#define CNFG_ID_8003E 0x6fc0 +#define CNFG_ID_8003S 0x6fc1 +#define CNFG_ID_8003W 0x6fc2 +#define CNFG_ID_8115TRA 0x6ec6 +#define CNFG_ID_8013E 0x61C8 +#define CNFG_ID_8013W 0x61C9 +#define CNFG_ID_BISTRO03E 0xEFE5 +#define CNFG_ID_BISTRO13E 0xEFD5 +#define CNFG_ID_BISTRO13W 0xEFD4 +#define CNFG_MSR_583 0x0 +#define CNFG_ICR_583 0x1 +#define CNFG_IAR_583 0x2 +#define CNFG_BIO_583 0x3 +#define CNFG_EAR_583 0x3 +#define CNFG_IRR_583 0x4 +#define CNFG_LAAR_584 0x5 +#define CNFG_GP2 0x7 +#define CNFG_LAAR_MASK 0x1F +#define CNFG_LAAR_ZWS 0x20 +#define CNFG_LAAR_L16E 0x40 +#define CNFG_ICR_IR2_584 0x04 +#define CNFG_ICR_MASK 0x08 +#define CNFG_ICR_MSZ 0x08 +#define CNFG_ICR_RLA 0x10 +#define CNFG_ICR_STO 0x80 +#define CNFG_IRR_IRQS 0x60 +#define CNFG_IRR_IEN 0x80 +#define CNFG_IRR_ZWS 0x01 +#define CNFG_GP2_BOOT_NIBBLE 0x0F +#define CNFG_IRR_OUT2 0x04 +#define CNFG_IRR_OUT1 0x02 + +#define CNFG_SIZE_8KB 8 +#define CNFG_SIZE_16KB 16 +#define CNFG_SIZE_32KB 32 +#define CNFG_SIZE_64KB 64 +#define CNFG_SIZE_128KB 128 +#define CNFG_SIZE_256KB 256 +#define ROM_DISABLE 0x0 + +#define CNFG_SLOT_ENABLE_BIT 0x08 + +#define CNFG_POS_CONTROL_REG 0x096 +#define CNFG_POS_REG0 0x100 +#define CNFG_POS_REG1 0x101 +#define CNFG_POS_REG2 0x102 +#define CNFG_POS_REG3 0x103 +#define CNFG_POS_REG4 0x104 +#define CNFG_POS_REG5 0x105 + +#define CNFG_ADAPTER_TYPE_MASK 0x0e + +#define SLOT_16BIT 0x0008 +#define INTERFACE_5X3_CHIP 0x0000 /* 0000 = 583 or 593 chips */ +#define NIC_690_BIT 0x0010 /* NIC is 690 */ +#define ALTERNATE_IRQ_BIT 0x0020 /* Alternate IRQ is used */ +#define INTERFACE_584_CHIP 0x0040 /* 0001 = 584 chip */ +#define INTERFACE_594_CHIP 0x0080 /* 0010 = 594 chip */ +#define INTERFACE_585_CHIP 0x0100 /* 0100 = 585/790 chip */ +#define INTERFACE_CHIP_MASK 0x03C0 /* Isolates Intfc Chip Type */ + +#define BOARD_16BIT 0x0040 +#define NODE_ADDR_CKSUM 0xEE +#define BRD_ID_8115T 0x04 + +#define NIC_825_BIT 0x0400 /* TRC 83C825 NIC */ +#define NIC_790_BIT 0x0800 /* NIC is 83C790 Ethernet */ + +#define CHIP_REV_MASK 0x3000 + +#define HWR_CBUSY 0x02 +#define HWR_CA 0x01 + +#define MAC_QUEUE 0 +#define NON_MAC_QUEUE 1 +#define BUG_QUEUE 2 /* NO RECEIVE QUEUE, ONLY TX */ + +#define NUM_MAC_TX_FCBS 8 +#define NUM_MAC_TX_BDBS NUM_MAC_TX_FCBS +#define NUM_MAC_RX_FCBS 7 +#define NUM_MAC_RX_BDBS 8 + +#define NUM_NON_MAC_TX_FCBS 6 +#define NUM_NON_MAC_TX_BDBS NUM_NON_MAC_TX_FCBS + +#define NUM_NON_MAC_RX_BDBS 0 /* CALCULATED DYNAMICALLY */ + +#define NUM_BUG_TX_FCBS 8 +#define NUM_BUG_TX_BDBS NUM_BUG_TX_FCBS + +#define MAC_TX_BUFFER_MEMORY 1024 +#define NON_MAC_TX_BUFFER_MEMORY (20 * 1024) +#define BUG_TX_BUFFER_MEMORY (NUM_BUG_TX_FCBS * 32) + +#define RX_BUFFER_MEMORY 0 /* CALCULATED DYNAMICALLY */ +#define RX_DATA_BUFFER_SIZE 256 +#define RX_BDB_SIZE_SHIFT 3 /* log2(RX_DATA_BUFFER_SIZE)-log2(sizeof(BDBlock)) */ +#define RX_BDB_SIZE_MASK (sizeof(BDBlock) - 1) +#define RX_DATA_BUFFER_SIZE_MASK (RX_DATA_BUFFER_SIZE-1) + +#define NUM_OF_INTERRUPTS 0x20 + +#define NOT_TRANSMITING 0 +#define TRANSMITING 1 + +#define TRC_INTERRUPT_ENABLE_MASK 0x7FF6 + +#define UCODE_VERSION 0x58 + +#define UCODE_SIZE_OFFSET 0x0000 /* WORD */ +#define UCODE_CHECKSUM_OFFSET 0x0002 /* WORD */ +#define UCODE_VERSION_OFFSET 0x0004 /* BYTE */ + +#define CS_RAM_SIZE 0X2000 +#define CS_RAM_CHECKSUM_OFFSET 0x1FFE /* WORD 1FFE(MSB)-1FFF(LSB)*/ +#define CS_RAM_VERSION_OFFSET 0x1FFC /* WORD 1FFC(MSB)-1FFD(LSB)*/ + +#define MISC_DATA_SIZE 128 +#define NUM_OF_ACBS 1 + +#define ACB_COMMAND_NOT_DONE 0x0000 /* Init, command not done */ +#define ACB_COMMAND_DONE 0x8000 /* TRC says command done */ +#define ACB_COMMAND_STATUS_MASK 0x00FF /* low byte is status */ +#define ACB_COMMAND_SUCCESSFUL 0x0000 /* means cmd was successful */ +#define ACB_NOT_CHAIN_END 0x0000 /* tell TRC more CBs in chain */ +#define ACB_CHAIN_END 0x8000 /* tell TRC last CB in chain */ +#define ACB_COMMAND_NO_INTERRUPT 0x0000 /* tell TRC no INT after CB */ +#define ACB_COMMAND_INTERRUPT 0x2000 /* tell TRC to INT after CB */ +#define ACB_SUB_CMD_NOP 0x0000 +#define ACB_CMD_HIC_NOP 0x0080 +#define ACB_CMD_MCT_NOP 0x0000 +#define ACB_CMD_MCT_TEST 0x0001 +#define ACB_CMD_HIC_TEST 0x0081 +#define ACB_CMD_INSERT 0x0002 +#define ACB_CMD_REMOVE 0x0003 +#define ACB_CMD_MCT_WRITE_VALUE 0x0004 +#define ACB_CMD_HIC_WRITE_VALUE 0x0084 +#define ACB_CMD_MCT_READ_VALUE 0x0005 +#define ACB_CMD_HIC_READ_VALUE 0x0085 +#define ACB_CMD_INIT_TX_RX 0x0086 +#define ACB_CMD_INIT_TRC_TIMERS 0x0006 +#define ACB_CMD_READ_TRC_STATUS 0x0007 +#define ACB_CMD_CHANGE_JOIN_STATE 0x0008 +#define ACB_CMD_RESERVED_9 0x0009 +#define ACB_CMD_RESERVED_A 0x000A +#define ACB_CMD_RESERVED_B 0x000B +#define ACB_CMD_RESERVED_C 0x000C +#define ACB_CMD_RESERVED_D 0x000D +#define ACB_CMD_RESERVED_E 0x000E +#define ACB_CMD_RESERVED_F 0x000F + +#define TRC_MAC_REGISTERS_TEST 0x0000 +#define TRC_INTERNAL_LOOPBACK 0x0001 +#define TRC_TRI_LOOPBACK 0x0002 +#define TRC_INTERNAL_ROM_TEST 0x0003 +#define TRC_LOBE_MEDIA_TEST 0x0004 +#define TRC_ANALOG_TEST 0x0005 +#define TRC_HOST_INTERFACE_REG_TEST 0x0003 + +#define TEST_DMA_1 0x0000 +#define TEST_DMA_2 0x0001 +#define TEST_MCT_ROM 0x0002 +#define HIC_INTERNAL_DIAG 0x0003 + +#define ABORT_TRANSMIT_PRIORITY_0 0x0001 +#define ABORT_TRANSMIT_PRIORITY_1 0x0002 +#define ABORT_TRANSMIT_PRIORITY_2 0x0004 +#define ABORT_TRANSMIT_PRIORITY_3 0x0008 +#define ABORT_TRANSMIT_PRIORITY_4 0x0010 +#define ABORT_TRANSMIT_PRIORITY_5 0x0020 +#define ABORT_TRANSMIT_PRIORITY_6 0x0040 +#define ABORT_TRANSMIT_PRIORITY_7 0x0080 + +#define TX_PENDING_PRIORITY_0 0x0001 +#define TX_PENDING_PRIORITY_1 0x0002 +#define TX_PENDING_PRIORITY_2 0x0004 +#define TX_PENDING_PRIORITY_3 0x0008 +#define TX_PENDING_PRIORITY_4 0x0010 +#define TX_PENDING_PRIORITY_5 0x0020 +#define TX_PENDING_PRIORITY_6 0x0040 +#define TX_PENDING_PRIORITY_7 0x0080 + +#define FCB_FRAME_LENGTH 0x100 +#define FCB_COMMAND_DONE 0x8000 /* FCB Word 0 */ +#define FCB_NOT_CHAIN_END 0x0000 /* FCB Word 1 */ +#define FCB_CHAIN_END 0x8000 +#define FCB_NO_WARNING 0x0000 +#define FCB_WARNING 0x4000 +#define FCB_INTERRUPT_DISABLE 0x0000 +#define FCB_INTERRUPT_ENABLE 0x2000 + +#define FCB_ENABLE_IMA 0x0008 +#define FCB_ENABLE_TES 0x0004 /* Guarantee Tx before Int */ +#define FCB_ENABLE_TFS 0x0002 /* Post Tx Frame Status */ +#define FCB_ENABLE_NTC 0x0001 /* No Tx CRC */ + +#define FCB_TX_STATUS_CR2 0x0004 +#define FCB_TX_STATUS_AR2 0x0008 +#define FCB_TX_STATUS_CR1 0x0040 +#define FCB_TX_STATUS_AR1 0x0080 +#define FCB_TX_AC_BITS (FCB_TX_STATUS_AR1+FCB_TX_STATUS_AR2+FCB_TX_STATUS_CR1+FCB_TX_STATUS_CR2) +#define FCB_TX_STATUS_E 0x0100 + +#define FCB_RX_STATUS_ANY_ERROR 0x0001 +#define FCB_RX_STATUS_FCS_ERROR 0x0002 + +#define FCB_RX_STATUS_IA_MATCHED 0x0400 +#define FCB_RX_STATUS_IGA_BSGA_MATCHED 0x0500 +#define FCB_RX_STATUS_FA_MATCHED 0x0600 +#define FCB_RX_STATUS_BA_MATCHED 0x0700 +#define FCB_RX_STATUS_DA_MATCHED 0x0400 +#define FCB_RX_STATUS_SOURCE_ROUTING 0x0800 + +#define BDB_BUFFER_SIZE 0x100 +#define BDB_NOT_CHAIN_END 0x0000 +#define BDB_CHAIN_END 0x8000 +#define BDB_NO_WARNING 0x0000 +#define BDB_WARNING 0x4000 + +#define ERROR_COUNTERS_CHANGED 0x0001 +#define TI_NDIS_RING_STATUS_CHANGED 0x0002 +#define UNA_CHANGED 0x0004 +#define READY_TO_SEND_RQ_INIT 0x0008 + +#define SCGB_ADDRESS_POINTER_FORMAT INTEL_ADDRESS_POINTER_FORMAT +#define SCGB_DATA_FORMAT INTEL_DATA_FORMAT +#define SCGB_MULTI_WORD_CONTROL 0 +#define SCGB_BURST_LENGTH 0x000E /* DMA Burst Length */ + +#define SCGB_CONFIG (INTEL_ADDRESS_POINTER_FORMAT+INTEL_DATA_FORMAT+SCGB_BURST_LENGTH) + +#define ISCP_BLOCK_SIZE 0x0A +#define RAM_SIZE 0x10000 +#define INIT_SYS_CONFIG_PTR_OFFSET (RAM_SIZE-ISCP_BLOCK_SIZE) +#define SCGP_BLOCK_OFFSET 0 + +#define SCLB_NOT_VALID 0x0000 /* Initially, SCLB not valid */ +#define SCLB_VALID 0x8000 /* Host tells TRC SCLB valid */ +#define SCLB_PROCESSED 0x0000 /* TRC says SCLB processed */ +#define SCLB_RESUME_CONTROL_NOT_VALID 0x0000 /* Initially, RC not valid */ +#define SCLB_RESUME_CONTROL_VALID 0x4000 /* Host tells TRC RC valid */ +#define SCLB_IACK_CODE_NOT_VALID 0x0000 /* Initially, IACK not valid */ +#define SCLB_IACK_CODE_VALID 0x2000 /* Host tells TRC IACK valid */ +#define SCLB_CMD_NOP 0x0000 +#define SCLB_CMD_REMOVE 0x0001 +#define SCLB_CMD_SUSPEND_ACB_CHAIN 0x0002 +#define SCLB_CMD_SET_INTERRUPT_MASK 0x0003 +#define SCLB_CMD_CLEAR_INTERRUPT_MASK 0x0004 +#define SCLB_CMD_RESERVED_5 0x0005 +#define SCLB_CMD_RESERVED_6 0x0006 +#define SCLB_CMD_RESERVED_7 0x0007 +#define SCLB_CMD_RESERVED_8 0x0008 +#define SCLB_CMD_RESERVED_9 0x0009 +#define SCLB_CMD_RESERVED_A 0x000A +#define SCLB_CMD_RESERVED_B 0x000B +#define SCLB_CMD_RESERVED_C 0x000C +#define SCLB_CMD_RESERVED_D 0x000D +#define SCLB_CMD_RESERVED_E 0x000E +#define SCLB_CMD_RESERVED_F 0x000F + +#define SCLB_RC_ACB 0x0001 /* Action Command Block Chain */ +#define SCLB_RC_RES0 0x0002 /* Always Zero */ +#define SCLB_RC_RES1 0x0004 /* Always Zero */ +#define SCLB_RC_RES2 0x0008 /* Always Zero */ +#define SCLB_RC_RX_MAC_FCB 0x0010 /* RX_MAC_FCB Chain */ +#define SCLB_RC_RX_MAC_BDB 0x0020 /* RX_MAC_BDB Chain */ +#define SCLB_RC_RX_NON_MAC_FCB 0x0040 /* RX_NON_MAC_FCB Chain */ +#define SCLB_RC_RX_NON_MAC_BDB 0x0080 /* RX_NON_MAC_BDB Chain */ +#define SCLB_RC_TFCB0 0x0100 /* TX Priority 0 FCB Chain */ +#define SCLB_RC_TFCB1 0x0200 /* TX Priority 1 FCB Chain */ +#define SCLB_RC_TFCB2 0x0400 /* TX Priority 2 FCB Chain */ +#define SCLB_RC_TFCB3 0x0800 /* TX Priority 3 FCB Chain */ +#define SCLB_RC_TFCB4 0x1000 /* TX Priority 4 FCB Chain */ +#define SCLB_RC_TFCB5 0x2000 /* TX Priority 5 FCB Chain */ +#define SCLB_RC_TFCB6 0x4000 /* TX Priority 6 FCB Chain */ +#define SCLB_RC_TFCB7 0x8000 /* TX Priority 7 FCB Chain */ + +#define SCLB_IMC_RES0 0x0001 /* */ +#define SCLB_IMC_MAC_TYPE_3 0x0002 /* MAC_ARC_INDICATE */ +#define SCLB_IMC_MAC_ERROR_COUNTERS 0x0004 /* */ +#define SCLB_IMC_RES1 0x0008 /* */ +#define SCLB_IMC_MAC_TYPE_2 0x0010 /* QUE_MAC_INDICATE */ +#define SCLB_IMC_TX_FRAME 0x0020 /* */ +#define SCLB_IMC_END_OF_TX_QUEUE 0x0040 /* */ +#define SCLB_IMC_NON_MAC_RX_RESOURCE 0x0080 /* */ +#define SCLB_IMC_MAC_RX_RESOURCE 0x0100 /* */ +#define SCLB_IMC_NON_MAC_RX_FRAME 0x0200 /* */ +#define SCLB_IMC_MAC_RX_FRAME 0x0400 /* */ +#define SCLB_IMC_TRC_FIFO_STATUS 0x0800 /* */ +#define SCLB_IMC_COMMAND_STATUS 0x1000 /* */ +#define SCLB_IMC_MAC_TYPE_1 0x2000 /* Self Removed */ +#define SCLB_IMC_TRC_INTRNL_TST_STATUS 0x4000 /* */ +#define SCLB_IMC_RES2 0x8000 /* */ + +#define DMA_TRIGGER 0x0004 +#define FREQ_16MB_BIT 0x0010 +#define THDREN 0x0020 +#define CFG0_RSV1 0x0040 +#define CFG0_RSV2 0x0080 +#define ETREN 0x0100 +#define RX_OWN_BIT 0x0200 +#define RXATMAC 0x0400 +#define PROMISCUOUS_BIT 0x0800 +#define USETPT 0x1000 +#define SAVBAD_BIT 0x2000 +#define ONEQUE 0x4000 +#define NO_AUTOREMOVE 0x8000 + +#define RX_FCB_AREA_8316 0x00000000 +#define RX_BUFF_AREA_8316 0x00000000 + +#define TRC_POINTER(X) ((unsigned long)(X) - tp->ram_access) +#define RX_FCB_TRC_POINTER(X) ((unsigned long)(X) - tp->ram_access + RX_FCB_AREA_8316) +#define RX_BUFF_TRC_POINTER(X) ((unsigned long)(X) - tp->ram_access + RX_BUFF_AREA_8316) + +// Offset 0: MSR - Memory Select Register +// +#define r587_MSR 0x000 // Register Offset +//#define MSR_RST 0x080 // LAN Controller Reset +#define MSR_MENB 0x040 // Shared Memory Enable +#define MSR_RA18 0x020 // Ram Address bit 18 (583, 584, 587) +#define MSR_RA17 0x010 // Ram Address bit 17 (583, 584, 585/790) +#define MSR_RA16 0x008 // Ram Address bit 16 (583, 584, 585/790) +#define MSR_RA15 0x004 // Ram Address bit 15 (583, 584, 585/790) +#define MSR_RA14 0x002 // Ram Address bit 14 (583, 584, 585/790) +#define MSR_RA13 0x001 // Ram Address bit 13 (583, 584, 585/790) + +#define MSR_MASK 0x03F // Mask for Address bits RA18-RA13 (583, 584, 587) + +#define MSR 0x00 +#define IRR 0x04 +#define HWR 0x04 +#define LAAR 0x05 +#define IMCCR 0x05 +#define LAR0 0x08 +#define BDID 0x0E // Adapter ID byte register offset +#define CSR 0x10 +#define PR 0x11 + +#define MSR_RST 0x80 +#define MSR_MEMB 0x40 +#define MSR_0WS 0x20 + +#define FORCED_16BIT_MODE 0x0002 + +#define INTERFRAME_SPACING_16 0x0003 /* 6 bytes */ +#define INTERFRAME_SPACING_4 0x0001 /* 2 bytes */ +#define MULTICAST_ADDRESS_BIT 0x0010 +#define NON_SRC_ROUTING_BIT 0x0020 + +#define LOOPING_MODE_MASK 0x0007 + +/* + * Decode firmware defines. + */ +#define SWAP_BYTES(X) ((X & 0xff) << 8) | (X >> 8) +#define WEIGHT_OFFSET 5 +#define TREE_SIZE_OFFSET 9 +#define TREE_OFFSET 11 + +/* The Huffman Encoding Tree is constructed of these nodes. */ +typedef struct { + __u8 llink; /* Short version of above node. */ + __u8 tag; + __u8 info; /* This node is used on decodes. */ + __u8 rlink; +} DECODE_TREE_NODE; + +#define ROOT 0 /* Branch value. */ +#define LEAF 0 /* Tag field value. */ +#define BRANCH 1 /* Tag field value. */ + +/* + * Multicast Table Structure + */ +typedef struct { + __u8 address[6]; + __u8 instance_count; +} McTable; + +/* + * Fragment Descriptor Definition + */ +typedef struct { + __u8 *fragment_ptr; + __u32 fragment_length; +} FragmentStructure; + +/* + * Data Buffer Structure Definition + */ +typedef struct { + __u32 fragment_count; + FragmentStructure fragment_list[MAXFRAGMENTS]; +} DataBufferStructure; + +#pragma pack(1) +typedef struct { + __u8 IType; + __u8 ISubtype; +} Interrupt_Status_Word; + +#pragma pack(1) +typedef struct BDBlockType { + __u16 info; /* 02 */ + __u32 trc_next_ptr; /* 06 */ + __u32 trc_data_block_ptr; /* 10 */ + __u16 buffer_length; /* 12 */ + + __u16 *data_block_ptr; /* 16 */ + struct BDBlockType *next_ptr; /* 20 */ + struct BDBlockType *back_ptr; /* 24 */ + __u8 filler[8]; /* 32 */ +} BDBlock; + +#pragma pack(1) +typedef struct FCBlockType { + __u16 frame_status; /* 02 */ + __u16 info; /* 04 */ + __u32 trc_next_ptr; /* 08 */ + __u32 trc_bdb_ptr; /* 12 */ + __u16 frame_length; /* 14 */ + + BDBlock *bdb_ptr; /* 18 */ + struct FCBlockType *next_ptr; /* 22 */ + struct FCBlockType *back_ptr; /* 26 */ + __u16 memory_alloc; /* 28 */ + __u8 filler[4]; /* 32 */ + +} FCBlock; + +#pragma pack(1) +typedef struct SBlockType{ + __u8 Internal_Error_Count; + __u8 Line_Error_Count; + __u8 AC_Error_Count; + __u8 Burst_Error_Count; + __u8 RESERVED_COUNTER_0; + __u8 AD_TRANS_Count; + __u8 RCV_Congestion_Count; + __u8 Lost_FR_Error_Count; + __u8 FREQ_Error_Count; + __u8 FR_Copied_Error_Count; + __u8 RESERVED_COUNTER_1; + __u8 Token_Error_Count; + + __u16 TI_NDIS_Ring_Status; + __u16 BCN_Type; + __u16 Error_Code; + __u16 SA_of_Last_AMP_SMP[3]; + __u16 UNA[3]; + __u16 Ucode_Version_Number; + __u16 Status_CHG_Indicate; + __u16 RESERVED_STATUS_0; +} SBlock; + +#pragma pack(1) +typedef struct ACBlockType { + __u16 cmd_done_status; /* 02 */ + __u16 cmd_info; /* 04 */ + __u32 trc_next_ptr; /* 08 */ + __u16 cmd; /* 10 */ + __u16 subcmd; /* 12 */ + __u16 data_offset_lo; /* 14 */ + __u16 data_offset_hi; /* 16 */ + + struct ACBlockType *next_ptr; /* 20 */ + + __u8 filler[12]; /* 32 */ +} ACBlock; + +#define NUM_OF_INTERRUPTS 0x20 + +#pragma pack(1) +typedef struct { + Interrupt_Status_Word IStatus[NUM_OF_INTERRUPTS]; +} ISBlock; + +#pragma pack(1) +typedef struct { + __u16 valid_command; /* 02 */ + __u16 iack_code; /* 04 */ + __u16 resume_control; /* 06 */ + __u16 int_mask_control; /* 08 */ + __u16 int_mask_state; /* 10 */ + + __u8 filler[6]; /* 16 */ +} SCLBlock; + +#pragma pack(1) +typedef struct +{ + __u16 config; /* 02 */ + __u32 trc_sclb_ptr; /* 06 */ + __u32 trc_acb_ptr; /* 10 */ + __u32 trc_isb_ptr; /* 14 */ + __u16 isbsiz; /* 16 */ + + SCLBlock *sclb_ptr; /* 20 */ + ACBlock *acb_ptr; /* 24 */ + ISBlock *isb_ptr; /* 28 */ + + __u16 Non_Mac_Rx_Bdbs; /* 30 DEBUG */ + __u8 filler[2]; /* 32 */ + +} SCGBlock; + +#pragma pack(1) +typedef struct +{ + __u32 trc_scgb_ptr; + SCGBlock *scgb_ptr; +} ISCPBlock; +#pragma pack() + +typedef struct net_local { + ISCPBlock *iscpb_ptr; + SCGBlock *scgb_ptr; + SCLBlock *sclb_ptr; + ISBlock *isb_ptr; + + ACBlock *acb_head; + ACBlock *acb_curr; + ACBlock *acb_next; + + __u8 adapter_name[12]; + + __u16 num_rx_bdbs [NUM_RX_QS_USED]; + __u16 num_rx_fcbs [NUM_RX_QS_USED]; + + __u16 num_tx_bdbs [NUM_TX_QS_USED]; + __u16 num_tx_fcbs [NUM_TX_QS_USED]; + + __u16 num_of_tx_buffs; + + __u16 tx_buff_size [NUM_TX_QS_USED]; + __u16 tx_buff_used [NUM_TX_QS_USED]; + __u16 tx_queue_status [NUM_TX_QS_USED]; + + FCBlock *tx_fcb_head[NUM_TX_QS_USED]; + FCBlock *tx_fcb_curr[NUM_TX_QS_USED]; + FCBlock *tx_fcb_end[NUM_TX_QS_USED]; + BDBlock *tx_bdb_head[NUM_TX_QS_USED]; + __u16 *tx_buff_head[NUM_TX_QS_USED]; + __u16 *tx_buff_end[NUM_TX_QS_USED]; + __u16 *tx_buff_curr[NUM_TX_QS_USED]; + __u16 num_tx_fcbs_used[NUM_TX_QS_USED]; + + FCBlock *rx_fcb_head[NUM_RX_QS_USED]; + FCBlock *rx_fcb_curr[NUM_RX_QS_USED]; + BDBlock *rx_bdb_head[NUM_RX_QS_USED]; + BDBlock *rx_bdb_curr[NUM_RX_QS_USED]; + BDBlock *rx_bdb_end[NUM_RX_QS_USED]; + __u16 *rx_buff_head[NUM_RX_QS_USED]; + __u16 *rx_buff_end[NUM_RX_QS_USED]; + + __u32 *ptr_local_ring_num; + + __u32 sh_mem_used; + + __u16 page_offset_mask; + + __u16 authorized_function_classes; + __u16 authorized_access_priority; + + __u16 num_acbs; + __u16 num_acbs_used; + __u16 acb_pending; + + __u16 current_isb_index; + + __u8 monitor_state; + __u8 monitor_state_ready; + __u16 ring_status; + __u8 ring_status_flags; + __u8 state; + + __u8 join_state; + + __u8 slot_num; + __u16 pos_id; + + __u32 *ptr_una; + __u32 *ptr_bcn_type; + __u32 *ptr_tx_fifo_underruns; + __u32 *ptr_rx_fifo_underruns; + __u32 *ptr_rx_fifo_overruns; + __u32 *ptr_tx_fifo_overruns; + __u32 *ptr_tx_fcb_overruns; + __u32 *ptr_rx_fcb_overruns; + __u32 *ptr_tx_bdb_overruns; + __u32 *ptr_rx_bdb_overruns; + + __u16 receive_queue_number; + + __u8 rx_fifo_overrun_count; + __u8 tx_fifo_overrun_count; + + __u16 adapter_flags; + __u16 adapter_flags1; + __u16 *misc_command_data; + __u16 max_packet_size; + + __u16 config_word0; + __u16 config_word1; + + __u8 trc_mask; + + __u16 source_ring_number; + __u16 target_ring_number; + + __u16 microcode_version; + + __u16 bic_type; + __u16 nic_type; + __u16 board_id; + + __u16 rom_size; + __u32 rom_base; + __u16 ram_size; + __u16 ram_usable; + __u32 ram_base; + __u32 ram_access; + + __u16 extra_info; + __u16 mode_bits; + __u16 media_menu; + __u16 media_type; + __u16 adapter_bus; + + __u16 status; + __u16 receive_mask; + + __u16 group_address_0; + __u16 group_address[2]; + __u16 functional_address_0; + __u16 functional_address[2]; + __u16 bitwise_group_address[2]; + + __u8 cleanup; + + struct sk_buff_head SendSkbQueue; + __u16 QueueSkb; + + struct tr_statistics MacStat; /* MAC statistics structure */ + + spinlock_t lock; +} NET_LOCAL; + +/************************************ + * SNMP-ON-BOARD Agent Link Structure + ************************************/ + +typedef struct { + __u8 LnkSigStr[12]; /* signature string "SmcLinkTable" */ + __u8 LnkDrvTyp; /* 1=Redbox ODI, 2=ODI DOS, 3=ODI OS/2, 4=NDIS DOS */ + __u8 LnkFlg; /* 0 if no agent linked, 1 if agent linked */ + void *LnkNfo; /* routine which returns pointer to NIC info */ + void *LnkAgtRcv; /* pointer to agent receive trap entry */ + void *LnkAgtXmt; /* pointer to agent transmit trap +entry */ +void *LnkGet; /* pointer to NIC receive data +copy routine */ + void *LnkSnd; /* pointer to NIC send routine +*/ + void *LnkRst; /* pointer to NIC driver reset +routine */ + void *LnkMib; /* pointer to MIB data base */ + void *LnkMibAct; /* pointer to MIB action routine list */ + __u16 LnkCntOffset; /* offset to error counters */ + __u16 LnkCntNum; /* number of error counters */ + __u16 LnkCntSize; /* size of error counters i.e. 32 = 32 bits */ + void *LnkISR; /* pointer to interrupt vector */ + __u8 LnkFrmTyp; /* 1=Ethernet, 2=Token Ring */ + __u8 LnkDrvVer1 ; /* driver major version */ + __u8 LnkDrvVer2 ; /* driver minor version */ +} AgentLink; + +/* + * Definitions for pcm_card_flags(bit_mapped) + */ +#define REG_COMPLETE 0x0001 +#define INSERTED 0x0002 +#define PCC_INSERTED 0x0004 /* 1=currently inserted, 0=cur removed */ + +/* + * Adapter RAM test patterns + */ +#define RAM_PATTERN_1 0x55AA +#define RAM_PATTERN_2 0x9249 +#define RAM_PATTERN_3 0xDB6D + +/* + * definitions for RAM test + */ +#define ROM_SIGNATURE 0xAA55 +#define MIN_ROM_SIZE 0x2000 + +/* + * Return Codes + */ +#define SUCCESS 0x0000 +#define ADAPTER_AND_CONFIG 0x0001 +#define ADAPTER_NO_CONFIG 0x0002 +#define NOT_MY_INTERRUPT 0x0003 +#define FRAME_REJECTED 0x0004 +#define EVENTS_DISABLED 0x0005 +#define OUT_OF_RESOURCES 0x0006 +#define INVALID_PARAMETER 0x0007 +#define INVALID_FUNCTION 0x0008 +#define INITIALIZE_FAILED 0x0009 +#define CLOSE_FAILED 0x000A +#define MAX_COLLISIONS 0x000B +#define NO_SUCH_DESTINATION 0x000C +#define BUFFER_TOO_SMALL_ERROR 0x000D +#define ADAPTER_CLOSED 0x000E +#define UCODE_NOT_PRESENT 0x000F +#define FIFO_UNDERRUN 0x0010 +#define DEST_OUT_OF_RESOURCES 0x0011 +#define ADAPTER_NOT_INITIALIZED 0x0012 +#define PENDING 0x0013 +#define UCODE_PRESENT 0x0014 +#define NOT_INIT_BY_BRIDGE 0x0015 + +#define OPEN_FAILED 0x0080 +#define HARDWARE_FAILED 0x0081 +#define SELF_TEST_FAILED 0x0082 +#define RAM_TEST_FAILED 0x0083 +#define RAM_CONFLICT 0x0084 +#define ROM_CONFLICT 0x0085 +#define UNKNOWN_ADAPTER 0x0086 +#define CONFIG_ERROR 0x0087 +#define CONFIG_WARNING 0x0088 +#define NO_FIXED_CNFG 0x0089 +#define EEROM_CKSUM_ERROR 0x008A +#define ROM_SIGNATURE_ERROR 0x008B +#define ROM_CHECKSUM_ERROR 0x008C +#define ROM_SIZE_ERROR 0x008D +#define UNSUPPORTED_NIC_CHIP 0x008E +#define NIC_REG_ERROR 0x008F +#define BIC_REG_ERROR 0x0090 +#define MICROCODE_TEST_ERROR 0x0091 +#define LOBE_MEDIA_TEST_FAILED 0x0092 + +#define ADAPTER_FOUND_LAN_CORRUPT 0x009B + +#define ADAPTER_NOT_FOUND 0xFFFF + +#define ILLEGAL_FUNCTION INVALID_FUNCTION + +/* Errors */ +#define IO_BASE_INVALID 0x0001 +#define IO_BASE_RANGE 0x0002 +#define IRQ_INVALID 0x0004 +#define IRQ_RANGE 0x0008 +#define RAM_BASE_INVALID 0x0010 +#define RAM_BASE_RANGE 0x0020 +#define RAM_SIZE_RANGE 0x0040 +#define MEDIA_INVALID 0x0800 + +/* Warnings */ +#define IRQ_MISMATCH 0x0080 +#define RAM_BASE_MISMATCH 0x0100 +#define RAM_SIZE_MISMATCH 0x0200 +#define BUS_MODE_MISMATCH 0x0400 + +#define RX_CRC_ERROR 0x01 +#define RX_ALIGNMENT_ERROR 0x02 +#define RX_HW_FAILED 0x80 + +/* + * Definitions for the field RING_STATUS_FLAGS + */ +#define RING_STATUS_CHANGED 0X01 +#define MONITOR_STATE_CHANGED 0X02 +#define JOIN_STATE_CHANGED 0X04 + +/* + * Definitions for the field JOIN_STATE + */ +#define JS_BYPASS_STATE 0x00 +#define JS_LOBE_TEST_STATE 0x01 +#define JS_DETECT_MONITOR_PRESENT_STATE 0x02 +#define JS_AWAIT_NEW_MONITOR_STATE 0x03 +#define JS_DUPLICATE_ADDRESS_TEST_STATE 0x04 +#define JS_NEIGHBOR_NOTIFICATION_STATE 0x05 +#define JS_REQUEST_INITIALIZATION_STATE 0x06 +#define JS_JOIN_COMPLETE_STATE 0x07 +#define JS_BYPASS_WAIT_STATE 0x08 + +/* + * Definitions for the field MONITOR_STATE + */ +#define MS_MONITOR_FSM_INACTIVE 0x00 +#define MS_REPEAT_BEACON_STATE 0x01 +#define MS_REPEAT_CLAIM_TOKEN_STATE 0x02 +#define MS_TRANSMIT_CLAIM_TOKEN_STATE 0x03 +#define MS_STANDBY_MONITOR_STATE 0x04 +#define MS_TRANSMIT_BEACON_STATE 0x05 +#define MS_ACTIVE_MONITOR_STATE 0x06 +#define MS_TRANSMIT_RING_PURGE_STATE 0x07 +#define MS_BEACON_TEST_STATE 0x09 + +/* + * Definitions for the bit-field RING_STATUS + */ +#define SIGNAL_LOSS 0x8000 +#define HARD_ERROR 0x4000 +#define SOFT_ERROR 0x2000 +#define TRANSMIT_BEACON 0x1000 +#define LOBE_WIRE_FAULT 0x0800 +#define AUTO_REMOVAL_ERROR 0x0400 +#define REMOVE_RECEIVED 0x0100 +#define COUNTER_OVERFLOW 0x0080 +#define SINGLE_STATION 0x0040 +#define RING_RECOVERY 0x0020 + +/* + * Definitions for the field BUS_TYPE + */ +#define AT_BUS 0x00 +#define MCA_BUS 0x01 +#define EISA_BUS 0x02 +#define PCI_BUS 0x03 +#define PCMCIA_BUS 0x04 + +/* + * Definitions for adapter_flags + */ +#define RX_VALID_LOOKAHEAD 0x0001 +#define FORCED_16BIT_MODE 0x0002 +#define ADAPTER_DISABLED 0x0004 +#define TRANSMIT_CHAIN_INT 0x0008 +#define EARLY_RX_FRAME 0x0010 +#define EARLY_TX 0x0020 +#define EARLY_RX_COPY 0x0040 +#define USES_PHYSICAL_ADDR 0x0080 /* Rsvd for DEC PCI and 9232 */ +#define NEEDS_PHYSICAL_ADDR 0x0100 /* Reserved*/ +#define RX_STATUS_PENDING 0x0200 +#define ERX_DISABLED 0x0400 /* EARLY_RX_ENABLE rcv_mask */ +#define ENABLE_TX_PENDING 0x0800 +#define ENABLE_RX_PENDING 0x1000 +#define PERM_CLOSE 0x2000 +#define IO_MAPPED 0x4000 /* IOmapped bus interface 795 */ +#define ETX_DISABLED 0x8000 + + +/* + * Definitions for adapter_flags1 + */ +#define TX_PHY_RX_VIRT 0x0001 +#define NEEDS_HOST_RAM 0x0002 +#define NEEDS_MEDIA_TYPE 0x0004 +#define EARLY_RX_DONE 0x0008 +#define PNP_BOOT_BIT 0x0010 /* activates PnP & config on power-up */ + /* clear => regular PnP operation */ +#define PNP_ENABLE 0x0020 /* regular PnP operation clear => */ + /* no PnP, overrides PNP_BOOT_BIT */ +#define SATURN_ENABLE 0x0040 + +#define ADAPTER_REMOVABLE 0x0080 /* adapter is hot swappable */ +#define TX_PHY 0x0100 /* Uses physical address for tx bufs */ +#define RX_PHY 0x0200 /* Uses physical address for rx bufs */ +#define TX_VIRT 0x0400 /* Uses virtual addr for tx bufs */ +#define RX_VIRT 0x0800 +#define NEEDS_SERVICE 0x1000 + +/* + * Adapter Status Codes + */ +#define OPEN 0x0001 +#define INITIALIZED 0x0002 +#define CLOSED 0x0003 +#define FAILED 0x0005 +#define NOT_INITIALIZED 0x0006 +#define IO_CONFLICT 0x0007 +#define CARD_REMOVED 0x0008 +#define CARD_INSERTED 0x0009 + +/* + * Mode Bit Definitions + */ +#define INTERRUPT_STATUS_BIT 0x8000 /* PC Interrupt Line: 0 = Not Enabled */ +#define BOOT_STATUS_MASK 0x6000 /* Mask to isolate BOOT_STATUS */ +#define BOOT_INHIBIT 0x0000 /* BOOT_STATUS is 'inhibited' */ +#define BOOT_TYPE_1 0x2000 /* Unused BOOT_STATUS value */ +#define BOOT_TYPE_2 0x4000 /* Unused BOOT_STATUS value */ +#define BOOT_TYPE_3 0x6000 /* Unused BOOT_STATUS value */ +#define ZERO_WAIT_STATE_MASK 0x1800 /* Mask to isolate Wait State flags */ +#define ZERO_WAIT_STATE_8_BIT 0x1000 /* 0 = Disabled (Inserts Wait States) */ +#define ZERO_WAIT_STATE_16_BIT 0x0800 /* 0 = Disabled (Inserts Wait States) */ +#define LOOPING_MODE_MASK 0x0007 +#define LOOPBACK_MODE_0 0x0000 +#define LOOPBACK_MODE_1 0x0001 +#define LOOPBACK_MODE_2 0x0002 +#define LOOPBACK_MODE_3 0x0003 +#define LOOPBACK_MODE_4 0x0004 +#define LOOPBACK_MODE_5 0x0005 +#define LOOPBACK_MODE_6 0x0006 +#define LOOPBACK_MODE_7 0x0007 +#define AUTO_MEDIA_DETECT 0x0008 +#define MANUAL_CRC 0x0010 +#define EARLY_TOKEN_REL 0x0020 /* Early Token Release for Token Ring */ +#define UMAC 0x0040 +#define UTP2_PORT 0x0080 /* For 8216T2, 0=port A, 1=Port B. */ +#define BNC_10BT_INTERFACE 0x0600 /* BNC and UTP current media set */ +#define UTP_INTERFACE 0x0500 /* Ethernet UTP Only. */ +#define BNC_INTERFACE 0x0400 +#define AUI_INTERFACE 0x0300 +#define AUI_10BT_INTERFACE 0x0200 +#define STARLAN_10_INTERFACE 0x0100 +#define INTERFACE_TYPE_MASK 0x0700 + +/* + * Media Type Bit Definitions + * + * legend: TP = Twisted Pair + * STP = Shielded twisted pair + * UTP = Unshielded twisted pair + */ + +#define CNFG_MEDIA_TYPE_MASK 0x001e /* POS Register 3 Mask */ + +#define MEDIA_S10 0x0000 /* Ethernet adapter, TP. */ +#define MEDIA_AUI_UTP 0x0001 /* Ethernet adapter, AUI/UTP media */ +#define MEDIA_BNC 0x0002 /* Ethernet adapter, BNC media. */ +#define MEDIA_AUI 0x0003 /* Ethernet Adapter, AUI media. */ +#define MEDIA_STP_16 0x0004 /* TokenRing adap, 16Mbit STP. */ +#define MEDIA_STP_4 0x0005 /* TokenRing adap, 4Mbit STP. */ +#define MEDIA_UTP_16 0x0006 /* TokenRing adap, 16Mbit UTP. */ +#define MEDIA_UTP_4 0x0007 /* TokenRing adap, 4Mbit UTP. */ +#define MEDIA_UTP 0x0008 /* Ethernet adapter, UTP media (no AUI) +*/ +#define MEDIA_BNC_UTP 0x0010 /* Ethernet adapter, BNC/UTP media */ +#define MEDIA_UTPFD 0x0011 /* Ethernet adapter, TP full duplex */ +#define MEDIA_UTPNL 0x0012 /* Ethernet adapter, TP with link integrity test disabled */ +#define MEDIA_AUI_BNC 0x0013 /* Ethernet adapter, AUI/BNC media */ +#define MEDIA_AUI_BNC_UTP 0x0014 /* Ethernet adapter, AUI_BNC/UTP */ +#define MEDIA_UTPA 0x0015 /* Ethernet UTP-10Mbps Ports A */ +#define MEDIA_UTPB 0x0016 /* Ethernet UTP-10Mbps Ports B */ +#define MEDIA_STP_16_UTP_16 0x0017 /* Token Ring STP-16Mbps/UTP-16Mbps */ +#define MEDIA_STP_4_UTP_4 0x0018 /* Token Ring STP-4Mbps/UTP-4Mbps */ + +#define MEDIA_STP100_UTP100 0x0020 /* Ethernet STP-100Mbps/UTP-100Mbps */ +#define MEDIA_UTP100FD 0x0021 /* Ethernet UTP-100Mbps, full duplex */ +#define MEDIA_UTP100 0x0022 /* Ethernet UTP-100Mbps */ + + +#define MEDIA_UNKNOWN 0xFFFF /* Unknown adapter/media type */ + +/* + * Definitions for the field: + * media_type2 + */ +#define MEDIA_TYPE_MII 0x0001 +#define MEDIA_TYPE_UTP 0x0002 +#define MEDIA_TYPE_BNC 0x0004 +#define MEDIA_TYPE_AUI 0x0008 +#define MEDIA_TYPE_S10 0x0010 +#define MEDIA_TYPE_AUTO_SENSE 0x1000 +#define MEDIA_TYPE_AUTO_DETECT 0x4000 +#define MEDIA_TYPE_AUTO_NEGOTIATE 0x8000 + +/* + * Definitions for the field: + * line_speed + */ +#define LINE_SPEED_UNKNOWN 0x0000 +#define LINE_SPEED_4 0x0001 +#define LINE_SPEED_10 0x0002 +#define LINE_SPEED_16 0x0004 +#define LINE_SPEED_100 0x0008 +#define LINE_SPEED_T4 0x0008 /* 100BaseT4 aliased for 9332BVT */ +#define LINE_SPEED_FULL_DUPLEX 0x8000 + +/* + * Definitions for the field: + * bic_type (Bus interface chip type) + */ +#define BIC_NO_CHIP 0x0000 /* Bus interface chip not implemented */ +#define BIC_583_CHIP 0x0001 /* 83C583 bus interface chip */ +#define BIC_584_CHIP 0x0002 /* 83C584 bus interface chip */ +#define BIC_585_CHIP 0x0003 /* 83C585 bus interface chip */ +#define BIC_593_CHIP 0x0004 /* 83C593 bus interface chip */ +#define BIC_594_CHIP 0x0005 /* 83C594 bus interface chip */ +#define BIC_564_CHIP 0x0006 /* PCMCIA Bus interface chip */ +#define BIC_790_CHIP 0x0007 /* 83C790 bus i-face/Ethernet NIC chip */ +#define BIC_571_CHIP 0x0008 /* 83C571 EISA bus master i-face */ +#define BIC_587_CHIP 0x0009 /* Token Ring AT bus master i-face */ +#define BIC_574_CHIP 0x0010 /* FEAST bus interface chip */ +#define BIC_8432_CHIP 0x0011 /* 8432 bus i-face/Ethernet NIC(DEC PCI) */ +#define BIC_9332_CHIP 0x0012 /* 9332 bus i-face/100Mbps Ether NIC(DEC PCI) */ +#define BIC_8432E_CHIP 0x0013 /* 8432 Enhanced bus iface/Ethernet NIC(DEC) */ +#define BIC_EPIC100_CHIP 0x0014 /* EPIC/100 10/100 Mbps Ethernet BIC/NIC */ +#define BIC_C94_CHIP 0x0015 /* 91C94 bus i-face in PCMCIA mode */ +#define BIC_X8020_CHIP 0x0016 /* Xilinx PCMCIA multi-func i-face */ + +/* + * Definitions for the field: + * nic_type (Bus interface chip type) + */ +#define NIC_UNK_CHIP 0x0000 /* Unknown NIC chip */ +#define NIC_8390_CHIP 0x0001 /* DP8390 Ethernet NIC */ +#define NIC_690_CHIP 0x0002 /* 83C690 Ethernet NIC */ +#define NIC_825_CHIP 0x0003 /* 83C825 Token Ring NIC */ +/* #define NIC_???_CHIP 0x0004 */ /* Not used */ +/* #define NIC_???_CHIP 0x0005 */ /* Not used */ +/* #define NIC_???_CHIP 0x0006 */ /* Not used */ +#define NIC_790_CHIP 0x0007 /* 83C790 bus i-face/Ethernet NIC chip */ +#define NIC_C100_CHIP 0x0010 /* FEAST 100Mbps Ethernet NIC */ +#define NIC_8432_CHIP 0x0011 /* 8432 bus i-face/Ethernet NIC(DEC PCI) */ +#define NIC_9332_CHIP 0x0012 /* 9332 bus i-face/100Mbps Ether NIC(DEC PCI) */ +#define NIC_8432E_CHIP 0x0013 /* 8432 enhanced bus iface/Ethernet NIC(DEC) */ +#define NIC_EPIC100_CHIP 0x0014 /* EPIC/100 10/100 Mbps Ethernet BIC/NIC */ +#define NIC_C94_CHIP 0x0015 /* 91C94 PC Card with multi func */ + +/* + * Definitions for the field: + * adapter_type The adapter_type field describes the adapter/bus + * configuration. + */ +#define BUS_ISA16_TYPE 0x0001 /* 16 bit adap in 16 bit (E)ISA slot */ +#define BUS_ISA8_TYPE 0x0002 /* 8/16b adap in 8 bit XT/(E)ISA slot */ +#define BUS_MCA_TYPE 0x0003 /* Micro Channel adapter */ + +/* + * Receive Mask definitions + */ +#define ACCEPT_MULTICAST 0x0001 +#define ACCEPT_BROADCAST 0x0002 +#define PROMISCUOUS_MODE 0x0004 +#define ACCEPT_SOURCE_ROUTING 0x0008 +#define ACCEPT_ERR_PACKETS 0x0010 +#define ACCEPT_ATT_MAC_FRAMES 0x0020 +#define ACCEPT_MULTI_PROM 0x0040 +#define TRANSMIT_ONLY 0x0080 +#define ACCEPT_EXT_MAC_FRAMES 0x0100 +#define EARLY_RX_ENABLE 0x0200 +#define PKT_SIZE_NOT_NEEDED 0x0400 +#define ACCEPT_SOURCE_ROUTING_SPANNING 0x0808 + +#define ACCEPT_ALL_MAC_FRAMES 0x0120 + +/* + * config_mode defs + */ +#define STORE_EEROM 0x0001 /* Store config in EEROM. */ +#define STORE_REGS 0x0002 /* Store config in register set. */ + +/* + * equates for lmac_flags in adapter structure (Ethernet) + */ +#define MEM_DISABLE 0x0001 +#define RX_STATUS_POLL 0x0002 +#define USE_RE_BIT 0x0004 +/*#define RESERVED 0x0008 */ +/*#define RESERVED 0x0010 */ +/*#define RESERVED 0x0020 */ +/*#define RESERVED 0x0040 */ +/*#define RESERVED 0x0080 */ +/*#define RESERVED 0x0100 */ +/*#define RESERVED 0x0200 */ +/*#define RESERVED 0x0400 */ +/*#define RESERVED 0x0800 */ +/*#define RESERVED 0x1000 */ +/*#define RESERVED 0x2000 */ +/*#define RESERVED 0x4000 */ +/*#define RESERVED 0x8000 */ + +/* media_opts & media_set Fields bit defs for Ethernet ... */ +#define MED_OPT_BNC 0x01 +#define MED_OPT_UTP 0x02 +#define MED_OPT_AUI 0x04 +#define MED_OPT_10MB 0x08 +#define MED_OPT_100MB 0x10 +#define MED_OPT_S10 0x20 + +/* media_opts & media_set Fields bit defs for Token Ring ... */ +#define MED_OPT_4MB 0x08 +#define MED_OPT_16MB 0x10 +#define MED_OPT_STP 0x40 + +#define MAX_8023_SIZE 1500 /* Max 802.3 size of frame. */ +#define DEFAULT_ERX_VALUE 4 /* Number of 16-byte blocks for 790B early Rx. */ +#define DEFAULT_ETX_VALUE 32 /* Number of bytes for 790B early Tx. */ +#define DEFAULT_TX_RETRIES 3 /* Number of transmit retries */ +#define LPBK_FRAME_SIZE 1024 /* Default loopback frame for Rx calibration test. */ +#define MAX_LOOKAHEAD_SIZE 252 /* Max lookahead size for ethernet. */ + +#define RW_MAC_STATE 0x1101 +#define RW_SA_OF_LAST_AMP_OR_SMP 0x2803 +#define RW_PHYSICAL_DROP_NUMBER 0x3B02 +#define RW_UPSTREAM_NEIGHBOR_ADDRESS 0x3E03 +#define RW_PRODUCT_INSTANCE_ID 0x4B09 + +#define RW_TRC_STATUS_BLOCK 0x5412 + +#define RW_MAC_ERROR_COUNTERS_NO_CLEAR 0x8006 +#define RW_MAC_ERROR_COUNTER_CLEAR 0x7A06 +#define RW_CONFIG_REGISTER_0 0xA001 +#define RW_CONFIG_REGISTER_1 0xA101 +#define RW_PRESCALE_TIMER_THRESHOLD 0xA201 +#define RW_TPT_THRESHOLD 0xA301 +#define RW_TQP_THRESHOLD 0xA401 +#define RW_TNT_THRESHOLD 0xA501 +#define RW_TBT_THRESHOLD 0xA601 +#define RW_TSM_THRESHOLD 0xA701 +#define RW_TAM_THRESHOLD 0xA801 +#define RW_TBR_THRESHOLD 0xA901 +#define RW_TER_THRESHOLD 0xAA01 +#define RW_TGT_THRESHOLD 0xAB01 +#define RW_THT_THRESHOLD 0xAC01 +#define RW_TRR_THRESHOLD 0xAD01 +#define RW_TVX_THRESHOLD 0xAE01 +#define RW_INDIVIDUAL_MAC_ADDRESS 0xB003 + +#define RW_INDIVIDUAL_GROUP_ADDRESS 0xB303 /* all of group addr */ +#define RW_INDIVIDUAL_GROUP_ADDR_WORD_0 0xB301 /* 1st word of group addr */ +#define RW_INDIVIDUAL_GROUP_ADDR 0xB402 /* 2nd-3rd word of group addr */ +#define RW_FUNCTIONAL_ADDRESS 0xB603 /* all of functional addr */ +#define RW_FUNCTIONAL_ADDR_WORD_0 0xB601 /* 1st word of func addr */ +#define RW_FUNCTIONAL_ADDR 0xB702 /* 2nd-3rd word func addr */ + +#define RW_BIT_SIGNIFICANT_GROUP_ADDR 0xB902 +#define RW_SOURCE_RING_BRIDGE_NUMBER 0xBB01 +#define RW_TARGET_RING_NUMBER 0xBC01 + +#define RW_HIC_INTERRUPT_MASK 0xC601 + +#define SOURCE_ROUTING_SPANNING_BITS 0x00C0 /* Spanning Tree Frames */ +#define SOURCE_ROUTING_EXPLORER_BIT 0x0040 /* Explorer and Single Route */ + + /* write */ + +#define CSR_MSK_ALL 0x80 // Bic 587 Only +#define CSR_MSKTINT 0x20 +#define CSR_MSKCBUSY 0x10 +#define CSR_CLRTINT 0x08 +#define CSR_CLRCBUSY 0x04 +#define CSR_WCSS 0x02 +#define CSR_CA 0x01 + + /* read */ + +#define CSR_TINT 0x20 +#define CSR_CINT 0x10 +#define CSR_TSTAT 0x08 +#define CSR_CSTAT 0x04 +#define CSR_FAULT 0x02 +#define CSR_CBUSY 0x01 + +#define LAAR_MEM16ENB 0x80 +#define Zws16 0x20 + +#define IRR_IEN 0x80 +#define Zws8 0x01 + +#define IMCCR_EIL 0x04 + +typedef struct { + __u8 ac; /* Access Control */ + __u8 fc; /* Frame Control */ + __u8 da[6]; /* Dest Addr */ + __u8 sa[6]; /* Source Addr */ + + __u16 vl; /* Vector Length */ + __u8 dc_sc; /* Dest/Source Class */ + __u8 vc; /* Vector Code */ + } MAC_HEADER; + +#define MAX_SUB_VECTOR_INFO (RX_DATA_BUFFER_SIZE - sizeof(MAC_HEADER) - 2) + +typedef struct + { + __u8 svl; /* Sub-vector Length */ + __u8 svi; /* Sub-vector Code */ + __u8 svv[MAX_SUB_VECTOR_INFO]; /* Sub-vector Info */ + } MAC_SUB_VECTOR; + +#endif /* __KERNEL__ */ +#endif /* __LINUX_SMCTR_H */ diff --git a/trunk/drivers/net/tokenring/tms380tr.c b/trunk/drivers/net/tokenring/tms380tr.c new file mode 100644 index 000000000000..b5e0855e4b39 --- /dev/null +++ b/trunk/drivers/net/tokenring/tms380tr.c @@ -0,0 +1,2306 @@ +/* + * tms380tr.c: A network driver library for Texas Instruments TMS380-based + * Token Ring Adapters. + * + * Originally sktr.c: Written 1997 by Christoph Goos + * + * A fine result of the Linux Systems Network Architecture Project. + * http://www.vanheusden.com/sna/ + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * The following modules are currently available for card support: + * - tmspci (Generic PCI card support) + * - abyss (Madge PCI support) + * - tmsisa (SysKonnect TR4/16 ISA) + * + * Sources: + * - The hardware related parts of this driver are take from + * the SysKonnect Token Ring driver for Windows NT. + * - I used the IBM Token Ring driver 'ibmtr.c' as a base for this + * driver, as well as the 'skeleton.c' driver by Donald Becker. + * - Also various other drivers in the linux source tree were taken + * as samples for some tasks. + * - TI TMS380 Second-Generation Token Ring User's Guide + * - TI datasheets for respective chips + * - David Hein at Texas Instruments + * - Various Madge employees + * + * Maintainer(s): + * JS Jay Schulist jschlst@samba.org + * CG Christoph Goos cgoos@syskonnect.de + * AF Adam Fritzler + * MLP Mike Phillips phillim@amtrak.com + * JF Jochen Friedrich jochen@scram.de + * + * Modification History: + * 29-Aug-97 CG Created + * 04-Apr-98 CG Fixed problems caused by tok_timer_check + * 10-Apr-98 CG Fixed lockups at cable disconnection + * 27-May-98 JS Formated to Linux Kernel Format + * 31-May-98 JS Hacked in PCI support + * 16-Jun-98 JS Modulized for multiple cards with one driver + * Sep-99 AF Renamed to tms380tr (supports more than SK's) + * 23-Sep-99 AF Added Compaq and Thomas-Conrad PCI support + * Fixed a bug causing double copies on PCI + * Fixed for new multicast stuff (2.2/2.3) + * 25-Sep-99 AF Uped TPL_NUM from 3 to 9 + * Removed extraneous 'No free TPL' + * 22-Dec-99 AF Added Madge PCI Mk2 support and generalized + * parts of the initilization procedure. + * 30-Dec-99 AF Turned tms380tr into a library ala 8390. + * Madge support is provided in the abyss module + * Generic PCI support is in the tmspci module. + * 30-Nov-00 JF Updated PCI code to support IO MMU via + * pci_map_static(). Alpha uses this MMU for ISA + * as well. + * 14-Jan-01 JF Fix DMA on ifdown/ifup sequences. Some + * cleanup. + * 13-Jan-02 JF Add spinlock to fix race condition. + * 09-Nov-02 JF Fixed printks to not SPAM the console during + * normal operation. + * 30-Dec-02 JF Removed incorrect __init from + * tms380tr_init_card. + * 22-Jul-05 JF Converted to dma-mapping. + * + * To do: + * 1. Multi/Broadcast packet handling (this may have fixed itself) + * 2. Write a sktrisa module that includes the old ISA support (done) + * 3. Allow modules to load their own microcode + * 4. Speed up the BUD process -- freezing the kernel for 3+sec is + * quite unacceptable. + * 5. Still a few remaining stalls when the cable is unplugged. + */ + +#ifdef MODULE +static const char version[] = "tms380tr.c: v1.10 30/12/2002 by Christoph Goos, Adam Fritzler\n"; +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "tms380tr.h" /* Our Stuff */ + +/* Use 0 for production, 1 for verification, 2 for debug, and + * 3 for very verbose debug. + */ +#ifndef TMS380TR_DEBUG +#define TMS380TR_DEBUG 0 +#endif +static unsigned int tms380tr_debug = TMS380TR_DEBUG; + +/* Index to functions, as function prototypes. + * Alphabetical by function name. + */ + +/* "A" */ +/* "B" */ +static int tms380tr_bringup_diags(struct net_device *dev); +/* "C" */ +static void tms380tr_cancel_tx_queue(struct net_local* tp); +static int tms380tr_chipset_init(struct net_device *dev); +static void tms380tr_chk_irq(struct net_device *dev); +static void tms380tr_chk_outstanding_cmds(struct net_device *dev); +static void tms380tr_chk_src_addr(unsigned char *frame, unsigned char *hw_addr); +static unsigned char tms380tr_chk_ssb(struct net_local *tp, unsigned short IrqType); +int tms380tr_close(struct net_device *dev); +static void tms380tr_cmd_status_irq(struct net_device *dev); +/* "D" */ +static void tms380tr_disable_interrupts(struct net_device *dev); +#if TMS380TR_DEBUG > 0 +static void tms380tr_dump(unsigned char *Data, int length); +#endif +/* "E" */ +static void tms380tr_enable_interrupts(struct net_device *dev); +static void tms380tr_exec_cmd(struct net_device *dev, unsigned short Command); +static void tms380tr_exec_sifcmd(struct net_device *dev, unsigned int WriteValue); +/* "F" */ +/* "G" */ +static struct net_device_stats *tms380tr_get_stats(struct net_device *dev); +/* "H" */ +static netdev_tx_t tms380tr_hardware_send_packet(struct sk_buff *skb, + struct net_device *dev); +/* "I" */ +static int tms380tr_init_adapter(struct net_device *dev); +static void tms380tr_init_ipb(struct net_local *tp); +static void tms380tr_init_net_local(struct net_device *dev); +static void tms380tr_init_opb(struct net_device *dev); +/* "M" */ +/* "O" */ +int tms380tr_open(struct net_device *dev); +static void tms380tr_open_adapter(struct net_device *dev); +/* "P" */ +/* "R" */ +static void tms380tr_rcv_status_irq(struct net_device *dev); +static int tms380tr_read_ptr(struct net_device *dev); +static void tms380tr_read_ram(struct net_device *dev, unsigned char *Data, + unsigned short Address, int Length); +static int tms380tr_reset_adapter(struct net_device *dev); +static void tms380tr_reset_interrupt(struct net_device *dev); +static void tms380tr_ring_status_irq(struct net_device *dev); +/* "S" */ +static netdev_tx_t tms380tr_send_packet(struct sk_buff *skb, + struct net_device *dev); +static void tms380tr_set_multicast_list(struct net_device *dev); +static int tms380tr_set_mac_address(struct net_device *dev, void *addr); +/* "T" */ +static void tms380tr_timer_chk(unsigned long data); +static void tms380tr_timer_end_wait(unsigned long data); +static void tms380tr_tx_status_irq(struct net_device *dev); +/* "U" */ +static void tms380tr_update_rcv_stats(struct net_local *tp, + unsigned char DataPtr[], unsigned int Length); +/* "W" */ +void tms380tr_wait(unsigned long time); +static void tms380tr_write_rpl_status(RPL *rpl, unsigned int Status); +static void tms380tr_write_tpl_status(TPL *tpl, unsigned int Status); + +#define SIFREADB(reg) \ + (((struct net_local *)netdev_priv(dev))->sifreadb(dev, reg)) +#define SIFWRITEB(val, reg) \ + (((struct net_local *)netdev_priv(dev))->sifwriteb(dev, val, reg)) +#define SIFREADW(reg) \ + (((struct net_local *)netdev_priv(dev))->sifreadw(dev, reg)) +#define SIFWRITEW(val, reg) \ + (((struct net_local *)netdev_priv(dev))->sifwritew(dev, val, reg)) + + + +#if 0 /* TMS380TR_DEBUG > 0 */ +static int madgemc_sifprobe(struct net_device *dev) +{ + unsigned char old, chk1, chk2; + + old = SIFREADB(SIFADR); /* Get the old SIFADR value */ + + chk1 = 0; /* Begin with check value 0 */ + do { + madgemc_setregpage(dev, 0); + /* Write new SIFADR value */ + SIFWRITEB(chk1, SIFADR); + chk2 = SIFREADB(SIFADR); + if (chk2 != chk1) + return -1; + + madgemc_setregpage(dev, 1); + /* Read, invert and write */ + chk2 = SIFREADB(SIFADD); + if (chk2 != chk1) + return -1; + + madgemc_setregpage(dev, 0); + chk2 ^= 0x0FE; + SIFWRITEB(chk2, SIFADR); + + /* Read, invert and compare */ + madgemc_setregpage(dev, 1); + chk2 = SIFREADB(SIFADD); + madgemc_setregpage(dev, 0); + chk2 ^= 0x0FE; + + if(chk1 != chk2) + return -1; /* No adapter */ + chk1 -= 2; + } while(chk1 != 0); /* Repeat 128 times (all byte values) */ + + madgemc_setregpage(dev, 0); /* sanity */ + /* Restore the SIFADR value */ + SIFWRITEB(old, SIFADR); + + return 0; +} +#endif + +/* + * Open/initialize the board. This is called sometime after + * booting when the 'ifconfig' program is run. + * + * This routine should set everything up anew at each open, even + * registers that "should" only need to be set once at boot, so that + * there is non-reboot way to recover if something goes wrong. + */ +int tms380tr_open(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + int err; + + /* init the spinlock */ + spin_lock_init(&tp->lock); + init_timer(&tp->timer); + + /* Reset the hardware here. Don't forget to set the station address. */ + +#if defined(CONFIG_ISA) && defined(CONFIG_ISA_DMA_API) + if(dev->dma > 0) + { + unsigned long flags=claim_dma_lock(); + disable_dma(dev->dma); + set_dma_mode(dev->dma, DMA_MODE_CASCADE); + enable_dma(dev->dma); + release_dma_lock(flags); + } +#endif + + err = tms380tr_chipset_init(dev); + if(err) + { + printk(KERN_INFO "%s: Chipset initialization error\n", + dev->name); + return -1; + } + + tp->timer.expires = jiffies + 30*HZ; + tp->timer.function = tms380tr_timer_end_wait; + tp->timer.data = (unsigned long)dev; + add_timer(&tp->timer); + + printk(KERN_DEBUG "%s: Adapter RAM size: %dK\n", + dev->name, tms380tr_read_ptr(dev)); + + tms380tr_enable_interrupts(dev); + tms380tr_open_adapter(dev); + + netif_start_queue(dev); + + /* Wait for interrupt from hardware. If interrupt does not come, + * there will be a timeout from the timer. + */ + tp->Sleeping = 1; + interruptible_sleep_on(&tp->wait_for_tok_int); + del_timer(&tp->timer); + + /* If AdapterVirtOpenFlag is 1, the adapter is now open for use */ + if(tp->AdapterVirtOpenFlag == 0) + { + tms380tr_disable_interrupts(dev); + return -1; + } + + tp->StartTime = jiffies; + + /* Start function control timer */ + tp->timer.expires = jiffies + 2*HZ; + tp->timer.function = tms380tr_timer_chk; + tp->timer.data = (unsigned long)dev; + add_timer(&tp->timer); + + return 0; +} + +/* + * Timeout function while waiting for event + */ +static void tms380tr_timer_end_wait(unsigned long data) +{ + struct net_device *dev = (struct net_device*)data; + struct net_local *tp = netdev_priv(dev); + + if(tp->Sleeping) + { + tp->Sleeping = 0; + wake_up_interruptible(&tp->wait_for_tok_int); + } +} + +/* + * Initialize the chipset + */ +static int tms380tr_chipset_init(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + int err; + + tms380tr_init_ipb(tp); + tms380tr_init_opb(dev); + tms380tr_init_net_local(dev); + + if(tms380tr_debug > 3) + printk(KERN_DEBUG "%s: Resetting adapter...\n", dev->name); + err = tms380tr_reset_adapter(dev); + if(err < 0) + return -1; + + if(tms380tr_debug > 3) + printk(KERN_DEBUG "%s: Bringup diags...\n", dev->name); + err = tms380tr_bringup_diags(dev); + if(err < 0) + return -1; + + if(tms380tr_debug > 3) + printk(KERN_DEBUG "%s: Init adapter...\n", dev->name); + err = tms380tr_init_adapter(dev); + if(err < 0) + return -1; + + if(tms380tr_debug > 3) + printk(KERN_DEBUG "%s: Done!\n", dev->name); + return 0; +} + +/* + * Initializes the net_local structure. + */ +static void tms380tr_init_net_local(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + int i; + dma_addr_t dmabuf; + + tp->scb.CMD = 0; + tp->scb.Parm[0] = 0; + tp->scb.Parm[1] = 0; + + tp->ssb.STS = 0; + tp->ssb.Parm[0] = 0; + tp->ssb.Parm[1] = 0; + tp->ssb.Parm[2] = 0; + + tp->CMDqueue = 0; + + tp->AdapterOpenFlag = 0; + tp->AdapterVirtOpenFlag = 0; + tp->ScbInUse = 0; + tp->OpenCommandIssued = 0; + tp->ReOpenInProgress = 0; + tp->HaltInProgress = 0; + tp->TransmitHaltScheduled = 0; + tp->LobeWireFaultLogged = 0; + tp->LastOpenStatus = 0; + tp->MaxPacketSize = DEFAULT_PACKET_SIZE; + + /* Create circular chain of transmit lists */ + for (i = 0; i < TPL_NUM; i++) + { + tp->Tpl[i].NextTPLAddr = htonl(((char *)(&tp->Tpl[(i+1) % TPL_NUM]) - (char *)tp) + tp->dmabuffer); /* DMA buffer may be MMU driven */ + tp->Tpl[i].Status = 0; + tp->Tpl[i].FrameSize = 0; + tp->Tpl[i].FragList[0].DataCount = 0; + tp->Tpl[i].FragList[0].DataAddr = 0; + tp->Tpl[i].NextTPLPtr = &tp->Tpl[(i+1) % TPL_NUM]; + tp->Tpl[i].MData = NULL; + tp->Tpl[i].TPLIndex = i; + tp->Tpl[i].DMABuff = 0; + tp->Tpl[i].BusyFlag = 0; + } + + tp->TplFree = tp->TplBusy = &tp->Tpl[0]; + + /* Create circular chain of receive lists */ + for (i = 0; i < RPL_NUM; i++) + { + tp->Rpl[i].NextRPLAddr = htonl(((char *)(&tp->Rpl[(i+1) % RPL_NUM]) - (char *)tp) + tp->dmabuffer); /* DMA buffer may be MMU driven */ + tp->Rpl[i].Status = (RX_VALID | RX_START_FRAME | RX_END_FRAME | RX_FRAME_IRQ); + tp->Rpl[i].FrameSize = 0; + tp->Rpl[i].FragList[0].DataCount = cpu_to_be16((unsigned short)tp->MaxPacketSize); + + /* Alloc skb and point adapter to data area */ + tp->Rpl[i].Skb = dev_alloc_skb(tp->MaxPacketSize); + tp->Rpl[i].DMABuff = 0; + + /* skb == NULL ? then use local buffer */ + if(tp->Rpl[i].Skb == NULL) + { + tp->Rpl[i].SkbStat = SKB_UNAVAILABLE; + tp->Rpl[i].FragList[0].DataAddr = htonl(((char *)tp->LocalRxBuffers[i] - (char *)tp) + tp->dmabuffer); + tp->Rpl[i].MData = tp->LocalRxBuffers[i]; + } + else /* SKB != NULL */ + { + tp->Rpl[i].Skb->dev = dev; + skb_put(tp->Rpl[i].Skb, tp->MaxPacketSize); + + /* data unreachable for DMA ? then use local buffer */ + dmabuf = dma_map_single(tp->pdev, tp->Rpl[i].Skb->data, tp->MaxPacketSize, DMA_FROM_DEVICE); + if(tp->dmalimit && (dmabuf + tp->MaxPacketSize > tp->dmalimit)) + { + tp->Rpl[i].SkbStat = SKB_DATA_COPY; + tp->Rpl[i].FragList[0].DataAddr = htonl(((char *)tp->LocalRxBuffers[i] - (char *)tp) + tp->dmabuffer); + tp->Rpl[i].MData = tp->LocalRxBuffers[i]; + } + else /* DMA directly in skb->data */ + { + tp->Rpl[i].SkbStat = SKB_DMA_DIRECT; + tp->Rpl[i].FragList[0].DataAddr = htonl(dmabuf); + tp->Rpl[i].MData = tp->Rpl[i].Skb->data; + tp->Rpl[i].DMABuff = dmabuf; + } + } + + tp->Rpl[i].NextRPLPtr = &tp->Rpl[(i+1) % RPL_NUM]; + tp->Rpl[i].RPLIndex = i; + } + + tp->RplHead = &tp->Rpl[0]; + tp->RplTail = &tp->Rpl[RPL_NUM-1]; + tp->RplTail->Status = (RX_START_FRAME | RX_END_FRAME | RX_FRAME_IRQ); +} + +/* + * Initializes the initialisation parameter block. + */ +static void tms380tr_init_ipb(struct net_local *tp) +{ + tp->ipb.Init_Options = BURST_MODE; + tp->ipb.CMD_Status_IV = 0; + tp->ipb.TX_IV = 0; + tp->ipb.RX_IV = 0; + tp->ipb.Ring_Status_IV = 0; + tp->ipb.SCB_Clear_IV = 0; + tp->ipb.Adapter_CHK_IV = 0; + tp->ipb.RX_Burst_Size = BURST_SIZE; + tp->ipb.TX_Burst_Size = BURST_SIZE; + tp->ipb.DMA_Abort_Thrhld = DMA_RETRIES; + tp->ipb.SCB_Addr = 0; + tp->ipb.SSB_Addr = 0; +} + +/* + * Initializes the open parameter block. + */ +static void tms380tr_init_opb(struct net_device *dev) +{ + struct net_local *tp; + unsigned long Addr; + unsigned short RplSize = RPL_SIZE; + unsigned short TplSize = TPL_SIZE; + unsigned short BufferSize = BUFFER_SIZE; + int i; + + tp = netdev_priv(dev); + + tp->ocpl.OPENOptions = 0; + tp->ocpl.OPENOptions |= ENABLE_FULL_DUPLEX_SELECTION; + tp->ocpl.FullDuplex = 0; + tp->ocpl.FullDuplex |= OPEN_FULL_DUPLEX_OFF; + + /* + * Set node address + * + * We go ahead and put it in the OPB even though on + * most of the generic adapters this isn't required. + * Its simpler this way. -- ASF + */ + for (i=0;i<6;i++) + tp->ocpl.NodeAddr[i] = ((unsigned char *)dev->dev_addr)[i]; + + tp->ocpl.GroupAddr = 0; + tp->ocpl.FunctAddr = 0; + tp->ocpl.RxListSize = cpu_to_be16((unsigned short)RplSize); + tp->ocpl.TxListSize = cpu_to_be16((unsigned short)TplSize); + tp->ocpl.BufSize = cpu_to_be16((unsigned short)BufferSize); + tp->ocpl.Reserved = 0; + tp->ocpl.TXBufMin = TX_BUF_MIN; + tp->ocpl.TXBufMax = TX_BUF_MAX; + + Addr = htonl(((char *)tp->ProductID - (char *)tp) + tp->dmabuffer); + + tp->ocpl.ProdIDAddr[0] = LOWORD(Addr); + tp->ocpl.ProdIDAddr[1] = HIWORD(Addr); +} + +/* + * Send OPEN command to adapter + */ +static void tms380tr_open_adapter(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + + if(tp->OpenCommandIssued) + return; + + tp->OpenCommandIssued = 1; + tms380tr_exec_cmd(dev, OC_OPEN); +} + +/* + * Clear the adapter's interrupt flag. Clear system interrupt enable + * (SINTEN): disable adapter to system interrupts. + */ +static void tms380tr_disable_interrupts(struct net_device *dev) +{ + SIFWRITEB(0, SIFACL); +} + +/* + * Set the adapter's interrupt flag. Set system interrupt enable + * (SINTEN): enable adapter to system interrupts. + */ +static void tms380tr_enable_interrupts(struct net_device *dev) +{ + SIFWRITEB(ACL_SINTEN, SIFACL); +} + +/* + * Put command in command queue, try to execute it. + */ +static void tms380tr_exec_cmd(struct net_device *dev, unsigned short Command) +{ + struct net_local *tp = netdev_priv(dev); + + tp->CMDqueue |= Command; + tms380tr_chk_outstanding_cmds(dev); +} + +static void tms380tr_timeout(struct net_device *dev) +{ + /* + * If we get here, some higher level has decided we are broken. + * There should really be a "kick me" function call instead. + * + * Resetting the token ring adapter takes a long time so just + * fake transmission time and go on trying. Our own timeout + * routine is in tms380tr_timer_chk() + */ + dev->trans_start = jiffies; /* prevent tx timeout */ + netif_wake_queue(dev); +} + +/* + * Gets skb from system, queues it and checks if it can be sent + */ +static netdev_tx_t tms380tr_send_packet(struct sk_buff *skb, + struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + netdev_tx_t rc; + + rc = tms380tr_hardware_send_packet(skb, dev); + if(tp->TplFree->NextTPLPtr->BusyFlag) + netif_stop_queue(dev); + return rc; +} + +/* + * Move frames into adapter tx queue + */ +static netdev_tx_t tms380tr_hardware_send_packet(struct sk_buff *skb, + struct net_device *dev) +{ + TPL *tpl; + short length; + unsigned char *buf; + unsigned long flags; + int i; + dma_addr_t dmabuf, newbuf; + struct net_local *tp = netdev_priv(dev); + + /* Try to get a free TPL from the chain. + * + * NOTE: We *must* always leave one unused TPL in the chain, + * because otherwise the adapter might send frames twice. + */ + spin_lock_irqsave(&tp->lock, flags); + if(tp->TplFree->NextTPLPtr->BusyFlag) { /* No free TPL */ + if (tms380tr_debug > 0) + printk(KERN_DEBUG "%s: No free TPL\n", dev->name); + spin_unlock_irqrestore(&tp->lock, flags); + return NETDEV_TX_BUSY; + } + + dmabuf = 0; + + /* Is buffer reachable for Busmaster-DMA? */ + + length = skb->len; + dmabuf = dma_map_single(tp->pdev, skb->data, length, DMA_TO_DEVICE); + if(tp->dmalimit && (dmabuf + length > tp->dmalimit)) { + /* Copy frame to local buffer */ + dma_unmap_single(tp->pdev, dmabuf, length, DMA_TO_DEVICE); + dmabuf = 0; + i = tp->TplFree->TPLIndex; + buf = tp->LocalTxBuffers[i]; + skb_copy_from_linear_data(skb, buf, length); + newbuf = ((char *)buf - (char *)tp) + tp->dmabuffer; + } + else { + /* Send direct from skb->data */ + newbuf = dmabuf; + buf = skb->data; + } + /* Source address in packet? */ + tms380tr_chk_src_addr(buf, dev->dev_addr); + tp->LastSendTime = jiffies; + tpl = tp->TplFree; /* Get the "free" TPL */ + tpl->BusyFlag = 1; /* Mark TPL as busy */ + tp->TplFree = tpl->NextTPLPtr; + + /* Save the skb for delayed return of skb to system */ + tpl->Skb = skb; + tpl->DMABuff = dmabuf; + tpl->FragList[0].DataCount = cpu_to_be16((unsigned short)length); + tpl->FragList[0].DataAddr = htonl(newbuf); + + /* Write the data length in the transmit list. */ + tpl->FrameSize = cpu_to_be16((unsigned short)length); + tpl->MData = buf; + + /* Transmit the frame and set the status values. */ + tms380tr_write_tpl_status(tpl, TX_VALID | TX_START_FRAME + | TX_END_FRAME | TX_PASS_SRC_ADDR + | TX_FRAME_IRQ); + + /* Let adapter send the frame. */ + tms380tr_exec_sifcmd(dev, CMD_TX_VALID); + spin_unlock_irqrestore(&tp->lock, flags); + + return NETDEV_TX_OK; +} + +/* + * Write the given value to the 'Status' field of the specified TPL. + * NOTE: This function should be used whenever the status of any TPL must be + * modified by the driver, because the compiler may otherwise change the + * order of instructions such that writing the TPL status may be executed at + * an undesirable time. When this function is used, the status is always + * written when the function is called. + */ +static void tms380tr_write_tpl_status(TPL *tpl, unsigned int Status) +{ + tpl->Status = Status; +} + +static void tms380tr_chk_src_addr(unsigned char *frame, unsigned char *hw_addr) +{ + unsigned char SRBit; + + if((((unsigned long)frame[8]) & ~0x80) != 0) /* Compare 4 bytes */ + return; + if((unsigned short)frame[12] != 0) /* Compare 2 bytes */ + return; + + SRBit = frame[8] & 0x80; + memcpy(&frame[8], hw_addr, 6); + frame[8] |= SRBit; +} + +/* + * The timer routine: Check if adapter still open and working, reopen if not. + */ +static void tms380tr_timer_chk(unsigned long data) +{ + struct net_device *dev = (struct net_device*)data; + struct net_local *tp = netdev_priv(dev); + + if(tp->HaltInProgress) + return; + + tms380tr_chk_outstanding_cmds(dev); + if(time_before(tp->LastSendTime + SEND_TIMEOUT, jiffies) && + (tp->TplFree != tp->TplBusy)) + { + /* Anything to send, but stalled too long */ + tp->LastSendTime = jiffies; + tms380tr_exec_cmd(dev, OC_CLOSE); /* Does reopen automatically */ + } + + tp->timer.expires = jiffies + 2*HZ; + add_timer(&tp->timer); + + if(tp->AdapterOpenFlag || tp->ReOpenInProgress) + return; + tp->ReOpenInProgress = 1; + tms380tr_open_adapter(dev); +} + +/* + * The typical workload of the driver: Handle the network interface interrupts. + */ +irqreturn_t tms380tr_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct net_local *tp; + unsigned short irq_type; + int handled = 0; + + tp = netdev_priv(dev); + + irq_type = SIFREADW(SIFSTS); + + while(irq_type & STS_SYSTEM_IRQ) { + handled = 1; + irq_type &= STS_IRQ_MASK; + + if(!tms380tr_chk_ssb(tp, irq_type)) { + printk(KERN_DEBUG "%s: DATA LATE occurred\n", dev->name); + break; + } + + switch(irq_type) { + case STS_IRQ_RECEIVE_STATUS: + tms380tr_reset_interrupt(dev); + tms380tr_rcv_status_irq(dev); + break; + + case STS_IRQ_TRANSMIT_STATUS: + /* Check if TRANSMIT.HALT command is complete */ + if(tp->ssb.Parm[0] & COMMAND_COMPLETE) { + tp->TransmitCommandActive = 0; + tp->TransmitHaltScheduled = 0; + + /* Issue a new transmit command. */ + tms380tr_exec_cmd(dev, OC_TRANSMIT); + } + + tms380tr_reset_interrupt(dev); + tms380tr_tx_status_irq(dev); + break; + + case STS_IRQ_COMMAND_STATUS: + /* The SSB contains status of last command + * other than receive/transmit. + */ + tms380tr_cmd_status_irq(dev); + break; + + case STS_IRQ_SCB_CLEAR: + /* The SCB is free for another command. */ + tp->ScbInUse = 0; + tms380tr_chk_outstanding_cmds(dev); + break; + + case STS_IRQ_RING_STATUS: + tms380tr_ring_status_irq(dev); + break; + + case STS_IRQ_ADAPTER_CHECK: + tms380tr_chk_irq(dev); + break; + + case STS_IRQ_LLC_STATUS: + printk(KERN_DEBUG "tms380tr: unexpected LLC status IRQ\n"); + break; + + case STS_IRQ_TIMER: + printk(KERN_DEBUG "tms380tr: unexpected Timer IRQ\n"); + break; + + case STS_IRQ_RECEIVE_PENDING: + printk(KERN_DEBUG "tms380tr: unexpected Receive Pending IRQ\n"); + break; + + default: + printk(KERN_DEBUG "Unknown Token Ring IRQ (0x%04x)\n", irq_type); + break; + } + + /* Reset system interrupt if not already done. */ + if(irq_type != STS_IRQ_TRANSMIT_STATUS && + irq_type != STS_IRQ_RECEIVE_STATUS) { + tms380tr_reset_interrupt(dev); + } + + irq_type = SIFREADW(SIFSTS); + } + + return IRQ_RETVAL(handled); +} + +/* + * Reset the INTERRUPT SYSTEM bit and issue SSB CLEAR command. + */ +static void tms380tr_reset_interrupt(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + SSB *ssb = &tp->ssb; + + /* + * [Workaround for "Data Late"] + * Set all fields of the SSB to well-defined values so we can + * check if the adapter has written the SSB. + */ + + ssb->STS = (unsigned short) -1; + ssb->Parm[0] = (unsigned short) -1; + ssb->Parm[1] = (unsigned short) -1; + ssb->Parm[2] = (unsigned short) -1; + + /* Free SSB by issuing SSB_CLEAR command after reading IRQ code + * and clear STS_SYSTEM_IRQ bit: enable adapter for further interrupts. + */ + tms380tr_exec_sifcmd(dev, CMD_SSB_CLEAR | CMD_CLEAR_SYSTEM_IRQ); +} + +/* + * Check if the SSB has actually been written by the adapter. + */ +static unsigned char tms380tr_chk_ssb(struct net_local *tp, unsigned short IrqType) +{ + SSB *ssb = &tp->ssb; /* The address of the SSB. */ + + /* C 0 1 2 INTERRUPT CODE + * - - - - -------------- + * 1 1 1 1 TRANSMIT STATUS + * 1 1 1 1 RECEIVE STATUS + * 1 ? ? 0 COMMAND STATUS + * 0 0 0 0 SCB CLEAR + * 1 1 0 0 RING STATUS + * 0 0 0 0 ADAPTER CHECK + * + * 0 = SSB field not affected by interrupt + * 1 = SSB field is affected by interrupt + * + * C = SSB ADDRESS +0: COMMAND + * 0 = SSB ADDRESS +2: STATUS 0 + * 1 = SSB ADDRESS +4: STATUS 1 + * 2 = SSB ADDRESS +6: STATUS 2 + */ + + /* Check if this interrupt does use the SSB. */ + + if(IrqType != STS_IRQ_TRANSMIT_STATUS && + IrqType != STS_IRQ_RECEIVE_STATUS && + IrqType != STS_IRQ_COMMAND_STATUS && + IrqType != STS_IRQ_RING_STATUS) + { + return 1; /* SSB not involved. */ + } + + /* Note: All fields of the SSB have been set to all ones (-1) after it + * has last been used by the software (see DriverIsr()). + * + * Check if the affected SSB fields are still unchanged. + */ + + if(ssb->STS == (unsigned short) -1) + return 0; /* Command field not yet available. */ + if(IrqType == STS_IRQ_COMMAND_STATUS) + return 1; /* Status fields not always affected. */ + if(ssb->Parm[0] == (unsigned short) -1) + return 0; /* Status 1 field not yet available. */ + if(IrqType == STS_IRQ_RING_STATUS) + return 1; /* Status 2 & 3 fields not affected. */ + + /* Note: At this point, the interrupt is either TRANSMIT or RECEIVE. */ + if(ssb->Parm[1] == (unsigned short) -1) + return 0; /* Status 2 field not yet available. */ + if(ssb->Parm[2] == (unsigned short) -1) + return 0; /* Status 3 field not yet available. */ + + return 1; /* All SSB fields have been written by the adapter. */ +} + +/* + * Evaluates the command results status in the SSB status field. + */ +static void tms380tr_cmd_status_irq(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned short ssb_cmd, ssb_parm_0; + unsigned short ssb_parm_1; + char *open_err = "Open error -"; + char *code_err = "Open code -"; + + /* Copy the ssb values to local variables */ + ssb_cmd = tp->ssb.STS; + ssb_parm_0 = tp->ssb.Parm[0]; + ssb_parm_1 = tp->ssb.Parm[1]; + + if(ssb_cmd == OPEN) + { + tp->Sleeping = 0; + if(!tp->ReOpenInProgress) + wake_up_interruptible(&tp->wait_for_tok_int); + + tp->OpenCommandIssued = 0; + tp->ScbInUse = 0; + + if((ssb_parm_0 & 0x00FF) == GOOD_COMPLETION) + { + /* Success, the adapter is open. */ + tp->LobeWireFaultLogged = 0; + tp->AdapterOpenFlag = 1; + tp->AdapterVirtOpenFlag = 1; + tp->TransmitCommandActive = 0; + tms380tr_exec_cmd(dev, OC_TRANSMIT); + tms380tr_exec_cmd(dev, OC_RECEIVE); + + if(tp->ReOpenInProgress) + tp->ReOpenInProgress = 0; + + return; + } + else /* The adapter did not open. */ + { + if(ssb_parm_0 & NODE_ADDR_ERROR) + printk(KERN_INFO "%s: Node address error\n", + dev->name); + if(ssb_parm_0 & LIST_SIZE_ERROR) + printk(KERN_INFO "%s: List size error\n", + dev->name); + if(ssb_parm_0 & BUF_SIZE_ERROR) + printk(KERN_INFO "%s: Buffer size error\n", + dev->name); + if(ssb_parm_0 & TX_BUF_COUNT_ERROR) + printk(KERN_INFO "%s: Tx buffer count error\n", + dev->name); + if(ssb_parm_0 & INVALID_OPEN_OPTION) + printk(KERN_INFO "%s: Invalid open option\n", + dev->name); + if(ssb_parm_0 & OPEN_ERROR) + { + /* Show the open phase. */ + switch(ssb_parm_0 & OPEN_PHASES_MASK) + { + case LOBE_MEDIA_TEST: + if(!tp->LobeWireFaultLogged) + { + tp->LobeWireFaultLogged = 1; + printk(KERN_INFO "%s: %s Lobe wire fault (check cable !).\n", dev->name, open_err); + } + tp->ReOpenInProgress = 1; + tp->AdapterOpenFlag = 0; + tp->AdapterVirtOpenFlag = 1; + tms380tr_open_adapter(dev); + return; + + case PHYSICAL_INSERTION: + printk(KERN_INFO "%s: %s Physical insertion.\n", dev->name, open_err); + break; + + case ADDRESS_VERIFICATION: + printk(KERN_INFO "%s: %s Address verification.\n", dev->name, open_err); + break; + + case PARTICIPATION_IN_RING_POLL: + printk(KERN_INFO "%s: %s Participation in ring poll.\n", dev->name, open_err); + break; + + case REQUEST_INITIALISATION: + printk(KERN_INFO "%s: %s Request initialisation.\n", dev->name, open_err); + break; + + case FULLDUPLEX_CHECK: + printk(KERN_INFO "%s: %s Full duplex check.\n", dev->name, open_err); + break; + + default: + printk(KERN_INFO "%s: %s Unknown open phase\n", dev->name, open_err); + break; + } + + /* Show the open errors. */ + switch(ssb_parm_0 & OPEN_ERROR_CODES_MASK) + { + case OPEN_FUNCTION_FAILURE: + printk(KERN_INFO "%s: %s OPEN_FUNCTION_FAILURE", dev->name, code_err); + tp->LastOpenStatus = + OPEN_FUNCTION_FAILURE; + break; + + case OPEN_SIGNAL_LOSS: + printk(KERN_INFO "%s: %s OPEN_SIGNAL_LOSS\n", dev->name, code_err); + tp->LastOpenStatus = + OPEN_SIGNAL_LOSS; + break; + + case OPEN_TIMEOUT: + printk(KERN_INFO "%s: %s OPEN_TIMEOUT\n", dev->name, code_err); + tp->LastOpenStatus = + OPEN_TIMEOUT; + break; + + case OPEN_RING_FAILURE: + printk(KERN_INFO "%s: %s OPEN_RING_FAILURE\n", dev->name, code_err); + tp->LastOpenStatus = + OPEN_RING_FAILURE; + break; + + case OPEN_RING_BEACONING: + printk(KERN_INFO "%s: %s OPEN_RING_BEACONING\n", dev->name, code_err); + tp->LastOpenStatus = + OPEN_RING_BEACONING; + break; + + case OPEN_DUPLICATE_NODEADDR: + printk(KERN_INFO "%s: %s OPEN_DUPLICATE_NODEADDR\n", dev->name, code_err); + tp->LastOpenStatus = + OPEN_DUPLICATE_NODEADDR; + break; + + case OPEN_REQUEST_INIT: + printk(KERN_INFO "%s: %s OPEN_REQUEST_INIT\n", dev->name, code_err); + tp->LastOpenStatus = + OPEN_REQUEST_INIT; + break; + + case OPEN_REMOVE_RECEIVED: + printk(KERN_INFO "%s: %s OPEN_REMOVE_RECEIVED", dev->name, code_err); + tp->LastOpenStatus = + OPEN_REMOVE_RECEIVED; + break; + + case OPEN_FULLDUPLEX_SET: + printk(KERN_INFO "%s: %s OPEN_FULLDUPLEX_SET\n", dev->name, code_err); + tp->LastOpenStatus = + OPEN_FULLDUPLEX_SET; + break; + + default: + printk(KERN_INFO "%s: %s Unknown open err code", dev->name, code_err); + tp->LastOpenStatus = + OPEN_FUNCTION_FAILURE; + break; + } + } + + tp->AdapterOpenFlag = 0; + tp->AdapterVirtOpenFlag = 0; + + return; + } + } + else + { + if(ssb_cmd != READ_ERROR_LOG) + return; + + /* Add values from the error log table to the MAC + * statistics counters and update the errorlogtable + * memory. + */ + tp->MacStat.line_errors += tp->errorlogtable.Line_Error; + tp->MacStat.burst_errors += tp->errorlogtable.Burst_Error; + tp->MacStat.A_C_errors += tp->errorlogtable.ARI_FCI_Error; + tp->MacStat.lost_frames += tp->errorlogtable.Lost_Frame_Error; + tp->MacStat.recv_congest_count += tp->errorlogtable.Rx_Congest_Error; + tp->MacStat.rx_errors += tp->errorlogtable.Rx_Congest_Error; + tp->MacStat.frame_copied_errors += tp->errorlogtable.Frame_Copied_Error; + tp->MacStat.token_errors += tp->errorlogtable.Token_Error; + tp->MacStat.dummy1 += tp->errorlogtable.DMA_Bus_Error; + tp->MacStat.dummy1 += tp->errorlogtable.DMA_Parity_Error; + tp->MacStat.abort_delimiters += tp->errorlogtable.AbortDelimeters; + tp->MacStat.frequency_errors += tp->errorlogtable.Frequency_Error; + tp->MacStat.internal_errors += tp->errorlogtable.Internal_Error; + } +} + +/* + * The inverse routine to tms380tr_open(). + */ +int tms380tr_close(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + netif_stop_queue(dev); + + del_timer(&tp->timer); + + /* Flush the Tx and disable Rx here. */ + + tp->HaltInProgress = 1; + tms380tr_exec_cmd(dev, OC_CLOSE); + tp->timer.expires = jiffies + 1*HZ; + tp->timer.function = tms380tr_timer_end_wait; + tp->timer.data = (unsigned long)dev; + add_timer(&tp->timer); + + tms380tr_enable_interrupts(dev); + + tp->Sleeping = 1; + interruptible_sleep_on(&tp->wait_for_tok_int); + tp->TransmitCommandActive = 0; + + del_timer(&tp->timer); + tms380tr_disable_interrupts(dev); + +#if defined(CONFIG_ISA) && defined(CONFIG_ISA_DMA_API) + if(dev->dma > 0) + { + unsigned long flags=claim_dma_lock(); + disable_dma(dev->dma); + release_dma_lock(flags); + } +#endif + + SIFWRITEW(0xFF00, SIFCMD); +#if 0 + if(dev->dma > 0) /* what the? */ + SIFWRITEB(0xff, POSREG); +#endif + tms380tr_cancel_tx_queue(tp); + + return 0; +} + +/* + * Get the current statistics. This may be called with the card open + * or closed. + */ +static struct net_device_stats *tms380tr_get_stats(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + + return (struct net_device_stats *)&tp->MacStat; +} + +/* + * Set or clear the multicast filter for this adapter. + */ +static void tms380tr_set_multicast_list(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned int OpenOptions; + + OpenOptions = tp->ocpl.OPENOptions & + ~(PASS_ADAPTER_MAC_FRAMES + | PASS_ATTENTION_FRAMES + | PASS_BEACON_MAC_FRAMES + | COPY_ALL_MAC_FRAMES + | COPY_ALL_NON_MAC_FRAMES); + + tp->ocpl.FunctAddr = 0; + + if(dev->flags & IFF_PROMISC) + /* Enable promiscuous mode */ + OpenOptions |= COPY_ALL_NON_MAC_FRAMES | + COPY_ALL_MAC_FRAMES; + else + { + if(dev->flags & IFF_ALLMULTI) + { + /* Disable promiscuous mode, use normal mode. */ + tp->ocpl.FunctAddr = 0xFFFFFFFF; + } + else + { + struct netdev_hw_addr *ha; + + netdev_for_each_mc_addr(ha, dev) { + ((char *)(&tp->ocpl.FunctAddr))[0] |= + ha->addr[2]; + ((char *)(&tp->ocpl.FunctAddr))[1] |= + ha->addr[3]; + ((char *)(&tp->ocpl.FunctAddr))[2] |= + ha->addr[4]; + ((char *)(&tp->ocpl.FunctAddr))[3] |= + ha->addr[5]; + } + } + tms380tr_exec_cmd(dev, OC_SET_FUNCT_ADDR); + } + + tp->ocpl.OPENOptions = OpenOptions; + tms380tr_exec_cmd(dev, OC_MODIFY_OPEN_PARMS); +} + +/* + * Wait for some time (microseconds) + */ +void tms380tr_wait(unsigned long time) +{ +#if 0 + long tmp; + + tmp = jiffies + time/(1000000/HZ); + do { + tmp = schedule_timeout_interruptible(tmp); + } while(time_after(tmp, jiffies)); +#else + mdelay(time / 1000); +#endif +} + +/* + * Write a command value to the SIFCMD register + */ +static void tms380tr_exec_sifcmd(struct net_device *dev, unsigned int WriteValue) +{ + unsigned short cmd; + unsigned short SifStsValue; + unsigned long loop_counter; + + WriteValue = ((WriteValue ^ CMD_SYSTEM_IRQ) | CMD_INTERRUPT_ADAPTER); + cmd = (unsigned short)WriteValue; + loop_counter = 0,5 * 800000; + do { + SifStsValue = SIFREADW(SIFSTS); + } while((SifStsValue & CMD_INTERRUPT_ADAPTER) && loop_counter--); + SIFWRITEW(cmd, SIFCMD); +} + +/* + * Processes adapter hardware reset, halts adapter and downloads firmware, + * clears the halt bit. + */ +static int tms380tr_reset_adapter(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned short *fw_ptr; + unsigned short count, c, count2; + const struct firmware *fw_entry = NULL; + + if (request_firmware(&fw_entry, "tms380tr.bin", tp->pdev) != 0) { + printk(KERN_ALERT "%s: firmware %s is missing, cannot start.\n", + dev->name, "tms380tr.bin"); + return -1; + } + + fw_ptr = (unsigned short *)fw_entry->data; + count2 = fw_entry->size / 2; + + /* Hardware adapter reset */ + SIFWRITEW(ACL_ARESET, SIFACL); + tms380tr_wait(40); + + c = SIFREADW(SIFACL); + tms380tr_wait(20); + + if(dev->dma == 0) /* For PCI adapters */ + { + c &= ~(ACL_NSELOUT0 | ACL_NSELOUT1); /* Clear bits */ + if(tp->setnselout) + c |= (*tp->setnselout)(dev); + } + + /* In case a command is pending - forget it */ + tp->ScbInUse = 0; + + c &= ~ACL_ARESET; /* Clear adapter reset bit */ + c |= ACL_CPHALT; /* Halt adapter CPU, allow download */ + c |= ACL_BOOT; + c |= ACL_SINTEN; + c &= ~ACL_PSDMAEN; /* Clear pseudo dma bit */ + SIFWRITEW(c, SIFACL); + tms380tr_wait(40); + + count = 0; + /* Download firmware via DIO interface: */ + do { + if (count2 < 3) continue; + + /* Download first address part */ + SIFWRITEW(*fw_ptr, SIFADX); + fw_ptr++; + count2--; + /* Download second address part */ + SIFWRITEW(*fw_ptr, SIFADD); + fw_ptr++; + count2--; + + if((count = *fw_ptr) != 0) /* Load loop counter */ + { + fw_ptr++; /* Download block data */ + count2--; + if (count > count2) continue; + + for(; count > 0; count--) + { + SIFWRITEW(*fw_ptr, SIFINC); + fw_ptr++; + count2--; + } + } + else /* Stop, if last block downloaded */ + { + c = SIFREADW(SIFACL); + c &= (~ACL_CPHALT | ACL_SINTEN); + + /* Clear CPHALT and start BUD */ + SIFWRITEW(c, SIFACL); + release_firmware(fw_entry); + return 1; + } + } while(count == 0); + + release_firmware(fw_entry); + printk(KERN_INFO "%s: Adapter Download Failed\n", dev->name); + return -1; +} + +MODULE_FIRMWARE("tms380tr.bin"); + +/* + * Starts bring up diagnostics of token ring adapter and evaluates + * diagnostic results. + */ +static int tms380tr_bringup_diags(struct net_device *dev) +{ + int loop_cnt, retry_cnt; + unsigned short Status; + + tms380tr_wait(HALF_SECOND); + tms380tr_exec_sifcmd(dev, EXEC_SOFT_RESET); + tms380tr_wait(HALF_SECOND); + + retry_cnt = BUD_MAX_RETRIES; /* maximal number of retrys */ + + do { + retry_cnt--; + if(tms380tr_debug > 3) + printk(KERN_DEBUG "BUD-Status: "); + loop_cnt = BUD_MAX_LOOPCNT; /* maximum: three seconds*/ + do { /* Inspect BUD results */ + loop_cnt--; + tms380tr_wait(HALF_SECOND); + Status = SIFREADW(SIFSTS); + Status &= STS_MASK; + + if(tms380tr_debug > 3) + printk(KERN_DEBUG " %04X\n", Status); + /* BUD successfully completed */ + if(Status == STS_INITIALIZE) + return 1; + /* Unrecoverable hardware error, BUD not completed? */ + } while((loop_cnt > 0) && ((Status & (STS_ERROR | STS_TEST)) + != (STS_ERROR | STS_TEST))); + + /* Error preventing completion of BUD */ + if(retry_cnt > 0) + { + printk(KERN_INFO "%s: Adapter Software Reset.\n", + dev->name); + tms380tr_exec_sifcmd(dev, EXEC_SOFT_RESET); + tms380tr_wait(HALF_SECOND); + } + } while(retry_cnt > 0); + + Status = SIFREADW(SIFSTS); + + printk(KERN_INFO "%s: Hardware error\n", dev->name); + /* Hardware error occurred! */ + Status &= 0x001f; + if (Status & 0x0010) + printk(KERN_INFO "%s: BUD Error: Timeout\n", dev->name); + else if ((Status & 0x000f) > 6) + printk(KERN_INFO "%s: BUD Error: Illegal Failure\n", dev->name); + else + printk(KERN_INFO "%s: Bring Up Diagnostics Error (%04X) occurred\n", dev->name, Status & 0x000f); + + return -1; +} + +/* + * Copy initialisation data to adapter memory, beginning at address + * 1:0A00; Starting DMA test and evaluating result bits. + */ +static int tms380tr_init_adapter(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + + const unsigned char SCB_Test[6] = {0x00, 0x00, 0xC1, 0xE2, 0xD4, 0x8B}; + const unsigned char SSB_Test[8] = {0xFF, 0xFF, 0xD1, 0xD7, + 0xC5, 0xD9, 0xC3, 0xD4}; + void *ptr = (void *)&tp->ipb; + unsigned short *ipb_ptr = (unsigned short *)ptr; + unsigned char *cb_ptr = (unsigned char *) &tp->scb; + unsigned char *sb_ptr = (unsigned char *) &tp->ssb; + unsigned short Status; + int i, loop_cnt, retry_cnt; + + /* Normalize: byte order low/high, word order high/low! (only IPB!) */ + tp->ipb.SCB_Addr = SWAPW(((char *)&tp->scb - (char *)tp) + tp->dmabuffer); + tp->ipb.SSB_Addr = SWAPW(((char *)&tp->ssb - (char *)tp) + tp->dmabuffer); + + if(tms380tr_debug > 3) + { + printk(KERN_DEBUG "%s: buffer (real): %lx\n", dev->name, (long) &tp->scb); + printk(KERN_DEBUG "%s: buffer (virt): %lx\n", dev->name, (long) ((char *)&tp->scb - (char *)tp) + (long) tp->dmabuffer); + printk(KERN_DEBUG "%s: buffer (DMA) : %lx\n", dev->name, (long) tp->dmabuffer); + printk(KERN_DEBUG "%s: buffer (tp) : %lx\n", dev->name, (long) tp); + } + /* Maximum: three initialization retries */ + retry_cnt = INIT_MAX_RETRIES; + + do { + retry_cnt--; + + /* Transfer initialization block */ + SIFWRITEW(0x0001, SIFADX); + + /* To address 0001:0A00 of adapter RAM */ + SIFWRITEW(0x0A00, SIFADD); + + /* Write 11 words to adapter RAM */ + for(i = 0; i < 11; i++) + SIFWRITEW(ipb_ptr[i], SIFINC); + + /* Execute SCB adapter command */ + tms380tr_exec_sifcmd(dev, CMD_EXECUTE); + + loop_cnt = INIT_MAX_LOOPCNT; /* Maximum: 11 seconds */ + + /* While remaining retries, no error and not completed */ + do { + Status = 0; + loop_cnt--; + tms380tr_wait(HALF_SECOND); + + /* Mask interesting status bits */ + Status = SIFREADW(SIFSTS); + Status &= STS_MASK; + } while(((Status &(STS_INITIALIZE | STS_ERROR | STS_TEST)) != 0) && + ((Status & STS_ERROR) == 0) && (loop_cnt != 0)); + + if((Status & (STS_INITIALIZE | STS_ERROR | STS_TEST)) == 0) + { + /* Initialization completed without error */ + i = 0; + do { /* Test if contents of SCB is valid */ + if(SCB_Test[i] != *(cb_ptr + i)) + { + printk(KERN_INFO "%s: DMA failed\n", dev->name); + /* DMA data error: wrong data in SCB */ + return -1; + } + i++; + } while(i < 6); + + i = 0; + do { /* Test if contents of SSB is valid */ + if(SSB_Test[i] != *(sb_ptr + i)) + /* DMA data error: wrong data in SSB */ + return -1; + i++; + } while (i < 8); + + return 1; /* Adapter successfully initialized */ + } + else + { + if((Status & STS_ERROR) != 0) + { + /* Initialization error occurred */ + Status = SIFREADW(SIFSTS); + Status &= STS_ERROR_MASK; + /* ShowInitialisationErrorCode(Status); */ + printk(KERN_INFO "%s: Status error: %d\n", dev->name, Status); + return -1; /* Unrecoverable error */ + } + else + { + if(retry_cnt > 0) + { + /* Reset adapter and try init again */ + tms380tr_exec_sifcmd(dev, EXEC_SOFT_RESET); + tms380tr_wait(HALF_SECOND); + } + } + } + } while(retry_cnt > 0); + + printk(KERN_INFO "%s: Retry exceeded\n", dev->name); + return -1; +} + +/* + * Check for outstanding commands in command queue and tries to execute + * command immediately. Corresponding command flag in command queue is cleared. + */ +static void tms380tr_chk_outstanding_cmds(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned long Addr = 0; + + if(tp->CMDqueue == 0) + return; /* No command execution */ + + /* If SCB in use: no command */ + if(tp->ScbInUse == 1) + return; + + /* Check if adapter is opened, avoiding COMMAND_REJECT + * interrupt by the adapter! + */ + if (tp->AdapterOpenFlag == 0) { + if (tp->CMDqueue & OC_OPEN) { + /* Execute OPEN command */ + tp->CMDqueue ^= OC_OPEN; + + Addr = htonl(((char *)&tp->ocpl - (char *)tp) + tp->dmabuffer); + tp->scb.Parm[0] = LOWORD(Addr); + tp->scb.Parm[1] = HIWORD(Addr); + tp->scb.CMD = OPEN; + } else + /* No OPEN command queued, but adapter closed. Note: + * We'll try to re-open the adapter in DriverPoll() + */ + return; /* No adapter command issued */ + } else { + /* Adapter is open; evaluate command queue: try to execute + * outstanding commands (depending on priority!) CLOSE + * command queued + */ + if (tp->CMDqueue & OC_CLOSE) { + tp->CMDqueue ^= OC_CLOSE; + tp->AdapterOpenFlag = 0; + tp->scb.Parm[0] = 0; /* Parm[0], Parm[1] are ignored */ + tp->scb.Parm[1] = 0; /* but should be set to zero! */ + tp->scb.CMD = CLOSE; + if(!tp->HaltInProgress) + tp->CMDqueue |= OC_OPEN; /* re-open adapter */ + else + tp->CMDqueue = 0; /* no more commands */ + } else if (tp->CMDqueue & OC_RECEIVE) { + tp->CMDqueue ^= OC_RECEIVE; + Addr = htonl(((char *)tp->RplHead - (char *)tp) + tp->dmabuffer); + tp->scb.Parm[0] = LOWORD(Addr); + tp->scb.Parm[1] = HIWORD(Addr); + tp->scb.CMD = RECEIVE; + } else if (tp->CMDqueue & OC_TRANSMIT_HALT) { + /* NOTE: TRANSMIT.HALT must be checked + * before TRANSMIT. + */ + tp->CMDqueue ^= OC_TRANSMIT_HALT; + tp->scb.CMD = TRANSMIT_HALT; + + /* Parm[0] and Parm[1] are ignored + * but should be set to zero! + */ + tp->scb.Parm[0] = 0; + tp->scb.Parm[1] = 0; + } else if (tp->CMDqueue & OC_TRANSMIT) { + /* NOTE: TRANSMIT must be + * checked after TRANSMIT.HALT + */ + if (tp->TransmitCommandActive) { + if (!tp->TransmitHaltScheduled) { + tp->TransmitHaltScheduled = 1; + tms380tr_exec_cmd(dev, OC_TRANSMIT_HALT); + } + tp->TransmitCommandActive = 0; + return; + } + + tp->CMDqueue ^= OC_TRANSMIT; + tms380tr_cancel_tx_queue(tp); + Addr = htonl(((char *)tp->TplBusy - (char *)tp) + tp->dmabuffer); + tp->scb.Parm[0] = LOWORD(Addr); + tp->scb.Parm[1] = HIWORD(Addr); + tp->scb.CMD = TRANSMIT; + tp->TransmitCommandActive = 1; + } else if (tp->CMDqueue & OC_MODIFY_OPEN_PARMS) { + tp->CMDqueue ^= OC_MODIFY_OPEN_PARMS; + tp->scb.Parm[0] = tp->ocpl.OPENOptions; /* new OPEN options*/ + tp->scb.Parm[0] |= ENABLE_FULL_DUPLEX_SELECTION; + tp->scb.Parm[1] = 0; /* is ignored but should be zero */ + tp->scb.CMD = MODIFY_OPEN_PARMS; + } else if (tp->CMDqueue & OC_SET_FUNCT_ADDR) { + tp->CMDqueue ^= OC_SET_FUNCT_ADDR; + tp->scb.Parm[0] = LOWORD(tp->ocpl.FunctAddr); + tp->scb.Parm[1] = HIWORD(tp->ocpl.FunctAddr); + tp->scb.CMD = SET_FUNCT_ADDR; + } else if (tp->CMDqueue & OC_SET_GROUP_ADDR) { + tp->CMDqueue ^= OC_SET_GROUP_ADDR; + tp->scb.Parm[0] = LOWORD(tp->ocpl.GroupAddr); + tp->scb.Parm[1] = HIWORD(tp->ocpl.GroupAddr); + tp->scb.CMD = SET_GROUP_ADDR; + } else if (tp->CMDqueue & OC_READ_ERROR_LOG) { + tp->CMDqueue ^= OC_READ_ERROR_LOG; + Addr = htonl(((char *)&tp->errorlogtable - (char *)tp) + tp->dmabuffer); + tp->scb.Parm[0] = LOWORD(Addr); + tp->scb.Parm[1] = HIWORD(Addr); + tp->scb.CMD = READ_ERROR_LOG; + } else { + printk(KERN_WARNING "CheckForOutstandingCommand: unknown Command\n"); + tp->CMDqueue = 0; + return; + } + } + + tp->ScbInUse = 1; /* Set semaphore: SCB in use. */ + + /* Execute SCB and generate IRQ when done. */ + tms380tr_exec_sifcmd(dev, CMD_EXECUTE | CMD_SCB_REQUEST); +} + +/* + * IRQ conditions: signal loss on the ring, transmit or receive of beacon + * frames (disabled if bit 1 of OPEN option is set); report error MAC + * frame transmit (disabled if bit 2 of OPEN option is set); open or short + * circuit fault on the lobe is detected; remove MAC frame received; + * error counter overflow (255); opened adapter is the only station in ring. + * After some of the IRQs the adapter is closed! + */ +static void tms380tr_ring_status_irq(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + + tp->CurrentRingStatus = be16_to_cpu((unsigned short)tp->ssb.Parm[0]); + + /* First: fill up statistics */ + if(tp->ssb.Parm[0] & SIGNAL_LOSS) + { + printk(KERN_INFO "%s: Signal Loss\n", dev->name); + tp->MacStat.line_errors++; + } + + /* Adapter is closed, but initialized */ + if(tp->ssb.Parm[0] & LOBE_WIRE_FAULT) + { + printk(KERN_INFO "%s: Lobe Wire Fault, Reopen Adapter\n", + dev->name); + tp->MacStat.line_errors++; + } + + if(tp->ssb.Parm[0] & RING_RECOVERY) + printk(KERN_INFO "%s: Ring Recovery\n", dev->name); + + /* Counter overflow: read error log */ + if(tp->ssb.Parm[0] & COUNTER_OVERFLOW) + { + printk(KERN_INFO "%s: Counter Overflow\n", dev->name); + tms380tr_exec_cmd(dev, OC_READ_ERROR_LOG); + } + + /* Adapter is closed, but initialized */ + if(tp->ssb.Parm[0] & REMOVE_RECEIVED) + printk(KERN_INFO "%s: Remove Received, Reopen Adapter\n", + dev->name); + + /* Adapter is closed, but initialized */ + if(tp->ssb.Parm[0] & AUTO_REMOVAL_ERROR) + printk(KERN_INFO "%s: Auto Removal Error, Reopen Adapter\n", + dev->name); + + if(tp->ssb.Parm[0] & HARD_ERROR) + printk(KERN_INFO "%s: Hard Error\n", dev->name); + + if(tp->ssb.Parm[0] & SOFT_ERROR) + printk(KERN_INFO "%s: Soft Error\n", dev->name); + + if(tp->ssb.Parm[0] & TRANSMIT_BEACON) + printk(KERN_INFO "%s: Transmit Beacon\n", dev->name); + + if(tp->ssb.Parm[0] & SINGLE_STATION) + printk(KERN_INFO "%s: Single Station\n", dev->name); + + /* Check if adapter has been closed */ + if(tp->ssb.Parm[0] & ADAPTER_CLOSED) + { + printk(KERN_INFO "%s: Adapter closed (Reopening)," + "CurrentRingStat %x\n", + dev->name, tp->CurrentRingStatus); + tp->AdapterOpenFlag = 0; + tms380tr_open_adapter(dev); + } +} + +/* + * Issued if adapter has encountered an unrecoverable hardware + * or software error. + */ +static void tms380tr_chk_irq(struct net_device *dev) +{ + int i; + unsigned short AdapterCheckBlock[4]; + struct net_local *tp = netdev_priv(dev); + + tp->AdapterOpenFlag = 0; /* Adapter closed now */ + + /* Page number of adapter memory */ + SIFWRITEW(0x0001, SIFADX); + /* Address offset */ + SIFWRITEW(CHECKADDR, SIFADR); + + /* Reading 8 byte adapter check block. */ + for(i = 0; i < 4; i++) + AdapterCheckBlock[i] = SIFREADW(SIFINC); + + if(tms380tr_debug > 3) + { + printk(KERN_DEBUG "%s: AdapterCheckBlock: ", dev->name); + for (i = 0; i < 4; i++) + printk("%04X", AdapterCheckBlock[i]); + printk("\n"); + } + + switch(AdapterCheckBlock[0]) + { + case DIO_PARITY: + printk(KERN_INFO "%s: DIO parity error\n", dev->name); + break; + + case DMA_READ_ABORT: + printk(KERN_INFO "%s DMA read operation aborted:\n", + dev->name); + switch (AdapterCheckBlock[1]) + { + case 0: + printk(KERN_INFO "Timeout\n"); + printk(KERN_INFO "Address: %04X %04X\n", + AdapterCheckBlock[2], + AdapterCheckBlock[3]); + break; + + case 1: + printk(KERN_INFO "Parity error\n"); + printk(KERN_INFO "Address: %04X %04X\n", + AdapterCheckBlock[2], + AdapterCheckBlock[3]); + break; + + case 2: + printk(KERN_INFO "Bus error\n"); + printk(KERN_INFO "Address: %04X %04X\n", + AdapterCheckBlock[2], + AdapterCheckBlock[3]); + break; + + default: + printk(KERN_INFO "Unknown error.\n"); + break; + } + break; + + case DMA_WRITE_ABORT: + printk(KERN_INFO "%s: DMA write operation aborted:\n", + dev->name); + switch (AdapterCheckBlock[1]) + { + case 0: + printk(KERN_INFO "Timeout\n"); + printk(KERN_INFO "Address: %04X %04X\n", + AdapterCheckBlock[2], + AdapterCheckBlock[3]); + break; + + case 1: + printk(KERN_INFO "Parity error\n"); + printk(KERN_INFO "Address: %04X %04X\n", + AdapterCheckBlock[2], + AdapterCheckBlock[3]); + break; + + case 2: + printk(KERN_INFO "Bus error\n"); + printk(KERN_INFO "Address: %04X %04X\n", + AdapterCheckBlock[2], + AdapterCheckBlock[3]); + break; + + default: + printk(KERN_INFO "Unknown error.\n"); + break; + } + break; + + case ILLEGAL_OP_CODE: + printk(KERN_INFO "%s: Illegal operation code in firmware\n", + dev->name); + /* Parm[0-3]: adapter internal register R13-R15 */ + break; + + case PARITY_ERRORS: + printk(KERN_INFO "%s: Adapter internal bus parity error\n", + dev->name); + /* Parm[0-3]: adapter internal register R13-R15 */ + break; + + case RAM_DATA_ERROR: + printk(KERN_INFO "%s: RAM data error\n", dev->name); + /* Parm[0-1]: MSW/LSW address of RAM location. */ + break; + + case RAM_PARITY_ERROR: + printk(KERN_INFO "%s: RAM parity error\n", dev->name); + /* Parm[0-1]: MSW/LSW address of RAM location. */ + break; + + case RING_UNDERRUN: + printk(KERN_INFO "%s: Internal DMA underrun detected\n", + dev->name); + break; + + case INVALID_IRQ: + printk(KERN_INFO "%s: Unrecognized interrupt detected\n", + dev->name); + /* Parm[0-3]: adapter internal register R13-R15 */ + break; + + case INVALID_ERROR_IRQ: + printk(KERN_INFO "%s: Unrecognized error interrupt detected\n", + dev->name); + /* Parm[0-3]: adapter internal register R13-R15 */ + break; + + case INVALID_XOP: + printk(KERN_INFO "%s: Unrecognized XOP request detected\n", + dev->name); + /* Parm[0-3]: adapter internal register R13-R15 */ + break; + + default: + printk(KERN_INFO "%s: Unknown status", dev->name); + break; + } + + if(tms380tr_chipset_init(dev) == 1) + { + /* Restart of firmware successful */ + tp->AdapterOpenFlag = 1; + } +} + +/* + * Internal adapter pointer to RAM data are copied from adapter into + * host system. + */ +static int tms380tr_read_ptr(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned short adapterram; + + tms380tr_read_ram(dev, (unsigned char *)&tp->intptrs.BurnedInAddrPtr, + ADAPTER_INT_PTRS, 16); + tms380tr_read_ram(dev, (unsigned char *)&adapterram, + cpu_to_be16((unsigned short)tp->intptrs.AdapterRAMPtr), 2); + return be16_to_cpu(adapterram); +} + +/* + * Reads a number of bytes from adapter to system memory. + */ +static void tms380tr_read_ram(struct net_device *dev, unsigned char *Data, + unsigned short Address, int Length) +{ + int i; + unsigned short old_sifadx, old_sifadr, InWord; + + /* Save the current values */ + old_sifadx = SIFREADW(SIFADX); + old_sifadr = SIFREADW(SIFADR); + + /* Page number of adapter memory */ + SIFWRITEW(0x0001, SIFADX); + /* Address offset in adapter RAM */ + SIFWRITEW(Address, SIFADR); + + /* Copy len byte from adapter memory to system data area. */ + i = 0; + for(;;) + { + InWord = SIFREADW(SIFINC); + + *(Data + i) = HIBYTE(InWord); /* Write first byte */ + if(++i == Length) /* All is done break */ + break; + + *(Data + i) = LOBYTE(InWord); /* Write second byte */ + if (++i == Length) /* All is done break */ + break; + } + + /* Restore original values */ + SIFWRITEW(old_sifadx, SIFADX); + SIFWRITEW(old_sifadr, SIFADR); +} + +/* + * Cancel all queued packets in the transmission queue. + */ +static void tms380tr_cancel_tx_queue(struct net_local* tp) +{ + TPL *tpl; + + /* + * NOTE: There must not be an active TRANSMIT command pending, when + * this function is called. + */ + if(tp->TransmitCommandActive) + return; + + for(;;) + { + tpl = tp->TplBusy; + if(!tpl->BusyFlag) + break; + /* "Remove" TPL from busy list. */ + tp->TplBusy = tpl->NextTPLPtr; + tms380tr_write_tpl_status(tpl, 0); /* Clear VALID bit */ + tpl->BusyFlag = 0; /* "free" TPL */ + + printk(KERN_INFO "Cancel tx (%08lXh).\n", (unsigned long)tpl); + if (tpl->DMABuff) + dma_unmap_single(tp->pdev, tpl->DMABuff, tpl->Skb->len, DMA_TO_DEVICE); + dev_kfree_skb_any(tpl->Skb); + } +} + +/* + * This function is called whenever a transmit interrupt is generated by the + * adapter. For a command complete interrupt, it is checked if we have to + * issue a new transmit command or not. + */ +static void tms380tr_tx_status_irq(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned char HighByte, HighAc, LowAc; + TPL *tpl; + + /* NOTE: At this point the SSB from TRANSMIT STATUS is no longer + * available, because the CLEAR SSB command has already been issued. + * + * Process all complete transmissions. + */ + + for(;;) + { + tpl = tp->TplBusy; + if(!tpl->BusyFlag || (tpl->Status + & (TX_VALID | TX_FRAME_COMPLETE)) + != TX_FRAME_COMPLETE) + { + break; + } + + /* "Remove" TPL from busy list. */ + tp->TplBusy = tpl->NextTPLPtr ; + + /* Check the transmit status field only for directed frames*/ + if(DIRECTED_FRAME(tpl) && (tpl->Status & TX_ERROR) == 0) + { + HighByte = GET_TRANSMIT_STATUS_HIGH_BYTE(tpl->Status); + HighAc = GET_FRAME_STATUS_HIGH_AC(HighByte); + LowAc = GET_FRAME_STATUS_LOW_AC(HighByte); + + if((HighAc != LowAc) || (HighAc == AC_NOT_RECOGNIZED)) + { + printk(KERN_DEBUG "%s: (DA=%08lX not recognized)\n", + dev->name, + *(unsigned long *)&tpl->MData[2+2]); + } + else + { + if(tms380tr_debug > 3) + printk(KERN_DEBUG "%s: Directed frame tx'd\n", + dev->name); + } + } + else + { + if(!DIRECTED_FRAME(tpl)) + { + if(tms380tr_debug > 3) + printk(KERN_DEBUG "%s: Broadcast frame tx'd\n", + dev->name); + } + } + + tp->MacStat.tx_packets++; + if (tpl->DMABuff) + dma_unmap_single(tp->pdev, tpl->DMABuff, tpl->Skb->len, DMA_TO_DEVICE); + dev_kfree_skb_irq(tpl->Skb); + tpl->BusyFlag = 0; /* "free" TPL */ + } + + if(!tp->TplFree->NextTPLPtr->BusyFlag) + netif_wake_queue(dev); +} + +/* + * Called if a frame receive interrupt is generated by the adapter. + * Check if the frame is valid and indicate it to system. + */ +static void tms380tr_rcv_status_irq(struct net_device *dev) +{ + struct net_local *tp = netdev_priv(dev); + unsigned char *ReceiveDataPtr; + struct sk_buff *skb; + unsigned int Length, Length2; + RPL *rpl; + RPL *SaveHead; + dma_addr_t dmabuf; + + /* NOTE: At this point the SSB from RECEIVE STATUS is no longer + * available, because the CLEAR SSB command has already been issued. + * + * Process all complete receives. + */ + + for(;;) + { + rpl = tp->RplHead; + if(rpl->Status & RX_VALID) + break; /* RPL still in use by adapter */ + + /* Forward RPLHead pointer to next list. */ + SaveHead = tp->RplHead; + tp->RplHead = rpl->NextRPLPtr; + + /* Get the frame size (Byte swap for Intel). + * Do this early (see workaround comment below) + */ + Length = be16_to_cpu(rpl->FrameSize); + + /* Check if the Frame_Start, Frame_End and + * Frame_Complete bits are set. + */ + if((rpl->Status & VALID_SINGLE_BUFFER_FRAME) + == VALID_SINGLE_BUFFER_FRAME) + { + ReceiveDataPtr = rpl->MData; + + /* Workaround for delayed write of FrameSize on ISA + * (FrameSize is false but valid-bit is reset) + * Frame size is set to zero when the RPL is freed. + * Length2 is there because there have also been + * cases where the FrameSize was partially written + */ + Length2 = be16_to_cpu(rpl->FrameSize); + + if(Length == 0 || Length != Length2) + { + tp->RplHead = SaveHead; + break; /* Return to tms380tr_interrupt */ + } + tms380tr_update_rcv_stats(tp,ReceiveDataPtr,Length); + + if(tms380tr_debug > 3) + printk(KERN_DEBUG "%s: Packet Length %04X (%d)\n", + dev->name, Length, Length); + + /* Indicate the received frame to system the + * adapter does the Source-Routing padding for + * us. See: OpenOptions in tms380tr_init_opb() + */ + skb = rpl->Skb; + if(rpl->SkbStat == SKB_UNAVAILABLE) + { + /* Try again to allocate skb */ + skb = dev_alloc_skb(tp->MaxPacketSize); + if(skb == NULL) + { + /* Update Stats ?? */ + } + else + { + skb_put(skb, tp->MaxPacketSize); + rpl->SkbStat = SKB_DATA_COPY; + ReceiveDataPtr = rpl->MData; + } + } + + if(skb && (rpl->SkbStat == SKB_DATA_COPY || + rpl->SkbStat == SKB_DMA_DIRECT)) + { + if(rpl->SkbStat == SKB_DATA_COPY) + skb_copy_to_linear_data(skb, ReceiveDataPtr, + Length); + + /* Deliver frame to system */ + rpl->Skb = NULL; + skb_trim(skb,Length); + skb->protocol = tr_type_trans(skb,dev); + netif_rx(skb); + } + } + else /* Invalid frame */ + { + if(rpl->Skb != NULL) + dev_kfree_skb_irq(rpl->Skb); + + /* Skip list. */ + if(rpl->Status & RX_START_FRAME) + /* Frame start bit is set -> overflow. */ + tp->MacStat.rx_errors++; + } + if (rpl->DMABuff) + dma_unmap_single(tp->pdev, rpl->DMABuff, tp->MaxPacketSize, DMA_TO_DEVICE); + rpl->DMABuff = 0; + + /* Allocate new skb for rpl */ + rpl->Skb = dev_alloc_skb(tp->MaxPacketSize); + /* skb == NULL ? then use local buffer */ + if(rpl->Skb == NULL) + { + rpl->SkbStat = SKB_UNAVAILABLE; + rpl->FragList[0].DataAddr = htonl(((char *)tp->LocalRxBuffers[rpl->RPLIndex] - (char *)tp) + tp->dmabuffer); + rpl->MData = tp->LocalRxBuffers[rpl->RPLIndex]; + } + else /* skb != NULL */ + { + rpl->Skb->dev = dev; + skb_put(rpl->Skb, tp->MaxPacketSize); + + /* Data unreachable for DMA ? then use local buffer */ + dmabuf = dma_map_single(tp->pdev, rpl->Skb->data, tp->MaxPacketSize, DMA_FROM_DEVICE); + if(tp->dmalimit && (dmabuf + tp->MaxPacketSize > tp->dmalimit)) + { + rpl->SkbStat = SKB_DATA_COPY; + rpl->FragList[0].DataAddr = htonl(((char *)tp->LocalRxBuffers[rpl->RPLIndex] - (char *)tp) + tp->dmabuffer); + rpl->MData = tp->LocalRxBuffers[rpl->RPLIndex]; + } + else + { + /* DMA directly in skb->data */ + rpl->SkbStat = SKB_DMA_DIRECT; + rpl->FragList[0].DataAddr = htonl(dmabuf); + rpl->MData = rpl->Skb->data; + rpl->DMABuff = dmabuf; + } + } + + rpl->FragList[0].DataCount = cpu_to_be16((unsigned short)tp->MaxPacketSize); + rpl->FrameSize = 0; + + /* Pass the last RPL back to the adapter */ + tp->RplTail->FrameSize = 0; + + /* Reset the CSTAT field in the list. */ + tms380tr_write_rpl_status(tp->RplTail, RX_VALID | RX_FRAME_IRQ); + + /* Current RPL becomes last one in list. */ + tp->RplTail = tp->RplTail->NextRPLPtr; + + /* Inform adapter about RPL valid. */ + tms380tr_exec_sifcmd(dev, CMD_RX_VALID); + } +} + +/* + * This function should be used whenever the status of any RPL must be + * modified by the driver, because the compiler may otherwise change the + * order of instructions such that writing the RPL status may be executed + * at an undesirable time. When this function is used, the status is + * always written when the function is called. + */ +static void tms380tr_write_rpl_status(RPL *rpl, unsigned int Status) +{ + rpl->Status = Status; +} + +/* + * The function updates the statistic counters in mac->MacStat. + * It differtiates between directed and broadcast/multicast ( ==functional) + * frames. + */ +static void tms380tr_update_rcv_stats(struct net_local *tp, unsigned char DataPtr[], + unsigned int Length) +{ + tp->MacStat.rx_packets++; + tp->MacStat.rx_bytes += Length; + + /* Test functional bit */ + if(DataPtr[2] & GROUP_BIT) + tp->MacStat.multicast++; +} + +static int tms380tr_set_mac_address(struct net_device *dev, void *addr) +{ + struct net_local *tp = netdev_priv(dev); + struct sockaddr *saddr = addr; + + if (tp->AdapterOpenFlag || tp->AdapterVirtOpenFlag) { + printk(KERN_WARNING "%s: Cannot set MAC/LAA address while card is open\n", dev->name); + return -EIO; + } + memcpy(dev->dev_addr, saddr->sa_data, dev->addr_len); + return 0; +} + +#if TMS380TR_DEBUG > 0 +/* + * Dump Packet (data) + */ +static void tms380tr_dump(unsigned char *Data, int length) +{ + int i, j; + + for (i = 0, j = 0; i < length / 8; i++, j += 8) + { + printk(KERN_DEBUG "%02x %02x %02x %02x %02x %02x %02x %02x\n", + Data[j+0],Data[j+1],Data[j+2],Data[j+3], + Data[j+4],Data[j+5],Data[j+6],Data[j+7]); + } +} +#endif + +void tmsdev_term(struct net_device *dev) +{ + struct net_local *tp; + + tp = netdev_priv(dev); + dma_unmap_single(tp->pdev, tp->dmabuffer, sizeof(struct net_local), + DMA_BIDIRECTIONAL); +} + +const struct net_device_ops tms380tr_netdev_ops = { + .ndo_open = tms380tr_open, + .ndo_stop = tms380tr_close, + .ndo_start_xmit = tms380tr_send_packet, + .ndo_tx_timeout = tms380tr_timeout, + .ndo_get_stats = tms380tr_get_stats, + .ndo_set_rx_mode = tms380tr_set_multicast_list, + .ndo_set_mac_address = tms380tr_set_mac_address, +}; +EXPORT_SYMBOL(tms380tr_netdev_ops); + +int tmsdev_init(struct net_device *dev, struct device *pdev) +{ + struct net_local *tms_local; + + memset(netdev_priv(dev), 0, sizeof(struct net_local)); + tms_local = netdev_priv(dev); + init_waitqueue_head(&tms_local->wait_for_tok_int); + if (pdev->dma_mask) + tms_local->dmalimit = *pdev->dma_mask; + else + return -ENOMEM; + tms_local->pdev = pdev; + tms_local->dmabuffer = dma_map_single(pdev, (void *)tms_local, + sizeof(struct net_local), DMA_BIDIRECTIONAL); + if (tms_local->dmabuffer + sizeof(struct net_local) > + tms_local->dmalimit) + { + printk(KERN_INFO "%s: Memory not accessible for DMA\n", + dev->name); + tmsdev_term(dev); + return -ENOMEM; + } + + dev->netdev_ops = &tms380tr_netdev_ops; + dev->watchdog_timeo = HZ; + + return 0; +} + +EXPORT_SYMBOL(tms380tr_open); +EXPORT_SYMBOL(tms380tr_close); +EXPORT_SYMBOL(tms380tr_interrupt); +EXPORT_SYMBOL(tmsdev_init); +EXPORT_SYMBOL(tmsdev_term); +EXPORT_SYMBOL(tms380tr_wait); + +#ifdef MODULE + +static struct module *TMS380_module = NULL; + +int init_module(void) +{ + printk(KERN_DEBUG "%s", version); + + TMS380_module = &__this_module; + return 0; +} + +void cleanup_module(void) +{ + TMS380_module = NULL; +} +#endif + +MODULE_LICENSE("GPL"); + diff --git a/trunk/drivers/net/tokenring/tms380tr.h b/trunk/drivers/net/tokenring/tms380tr.h new file mode 100644 index 000000000000..e5a617c586c2 --- /dev/null +++ b/trunk/drivers/net/tokenring/tms380tr.h @@ -0,0 +1,1141 @@ +/* + * tms380tr.h: TI TMS380 Token Ring driver for Linux + * + * Authors: + * - Christoph Goos + * - Adam Fritzler + */ + +#ifndef __LINUX_TMS380TR_H +#define __LINUX_TMS380TR_H + +#ifdef __KERNEL__ + +#include + +/* module prototypes */ +extern const struct net_device_ops tms380tr_netdev_ops; +int tms380tr_open(struct net_device *dev); +int tms380tr_close(struct net_device *dev); +irqreturn_t tms380tr_interrupt(int irq, void *dev_id); +int tmsdev_init(struct net_device *dev, struct device *pdev); +void tmsdev_term(struct net_device *dev); +void tms380tr_wait(unsigned long time); + +#define TMS380TR_MAX_ADAPTERS 7 + +#define SEND_TIMEOUT 10*HZ + +#define TR_RCF_LONGEST_FRAME_MASK 0x0070 +#define TR_RCF_FRAME4K 0x0030 + +/*------------------------------------------------------------------*/ +/* Bit order for adapter communication with DMA */ +/* -------------------------------------------------------------- */ +/* Bit 8 | 9| 10| 11|| 12| 13| 14| 15|| 0| 1| 2| 3|| 4| 5| 6| 7| */ +/* -------------------------------------------------------------- */ +/* The bytes in a word must be byte swapped. Also, if a double */ +/* word is used for storage, then the words, as well as the bytes, */ +/* must be swapped. */ +/* Bit order for adapter communication with DIO */ +/* -------------------------------------------------------------- */ +/* Bit 0 | 1| 2| 3|| 4| 5| 6| 7|| 8| 9| 10| 11|| 12| 13| 14| 15| */ +/* -------------------------------------------------------------- */ +/*------------------------------------------------------------------*/ + +/* Swap words of a long. */ +#define SWAPW(x) (((x) << 16) | ((x) >> 16)) + +/* Get the low byte of a word. */ +#define LOBYTE(w) ((unsigned char)(w)) + +/* Get the high byte of a word. */ +#define HIBYTE(w) ((unsigned char)((unsigned short)(w) >> 8)) + +/* Get the low word of a long. */ +#define LOWORD(l) ((unsigned short)(l)) + +/* Get the high word of a long. */ +#define HIWORD(l) ((unsigned short)((unsigned long)(l) >> 16)) + + + +/* Token ring adapter I/O addresses for normal mode. */ + +/* + * The SIF registers. Common to all adapters. + */ +/* Basic SIF (SRSX = 0) */ +#define SIFDAT 0x00 /* SIF/DMA data. */ +#define SIFINC 0x02 /* IO Word data with auto increment. */ +#define SIFINH 0x03 /* IO Byte data with auto increment. */ +#define SIFADR 0x04 /* SIF/DMA Address. */ +#define SIFCMD 0x06 /* SIF Command. */ +#define SIFSTS 0x06 /* SIF Status. */ + +/* "Extended" SIF (SRSX = 1) */ +#define SIFACL 0x08 /* SIF Adapter Control Register. */ +#define SIFADD 0x0a /* SIF/DMA Address. -- 0x0a */ +#define SIFADX 0x0c /* 0x0c */ +#define DMALEN 0x0e /* SIF DMA length. -- 0x0e */ + +/* + * POS Registers. Only for ISA Adapters. + */ +#define POSREG 0x10 /* Adapter Program Option Select (POS) + * Register: base IO address + 16 byte. + */ +#define POSREG_2 24L /* only for TR4/16+ adapter + * base IO address + 24 byte. -- 0x18 + */ + +/* SIFCMD command codes (high-low) */ +#define CMD_INTERRUPT_ADAPTER 0x8000 /* Cause internal adapter interrupt */ +#define CMD_ADAPTER_RESET 0x4000 /* Hardware reset of adapter */ +#define CMD_SSB_CLEAR 0x2000 /* Acknowledge to adapter to + * system interrupts. + */ +#define CMD_EXECUTE 0x1000 /* Execute SCB command */ +#define CMD_SCB_REQUEST 0x0800 /* Request adapter to interrupt + * system when SCB is available for + * another command. + */ +#define CMD_RX_CONTINUE 0x0400 /* Continue receive after odd pointer + * stop. (odd pointer receive method) + */ +#define CMD_RX_VALID 0x0200 /* Now actual RPL is valid. */ +#define CMD_TX_VALID 0x0100 /* Now actual TPL is valid. (valid + * bit receive/transmit method) + */ +#define CMD_SYSTEM_IRQ 0x0080 /* Adapter-to-attached-system + * interrupt is reset. + */ +#define CMD_CLEAR_SYSTEM_IRQ 0x0080 /* Clear SYSTEM_INTERRUPT bit. + * (write: 1=ignore, 0=reset) + */ +#define EXEC_SOFT_RESET 0xFF00 /* adapter soft reset. (restart + * adapter after hardware reset) + */ + + +/* ACL commands (high-low) */ +#define ACL_SWHLDA 0x0800 /* Software hold acknowledge. */ +#define ACL_SWDDIR 0x0400 /* Data transfer direction. */ +#define ACL_SWHRQ 0x0200 /* Pseudo DMA operation. */ +#define ACL_PSDMAEN 0x0100 /* Enable pseudo system DMA. */ +#define ACL_ARESET 0x0080 /* Adapter hardware reset command. + * (held in reset condition as + * long as bit is set) + */ +#define ACL_CPHALT 0x0040 /* Communication processor halt. + * (can only be set while ACL_ARESET + * bit is set; prevents adapter + * processor from executing code while + * downloading firmware) + */ +#define ACL_BOOT 0x0020 +#define ACL_SINTEN 0x0008 /* System interrupt enable/disable + * (1/0): can be written if ACL_ARESET + * is zero. + */ +#define ACL_PEN 0x0004 + +#define ACL_NSELOUT0 0x0002 +#define ACL_NSELOUT1 0x0001 /* NSELOUTx have a card-specific + * meaning for setting ring speed. + */ + +#define PS_DMA_MASK (ACL_SWHRQ | ACL_PSDMAEN) + + +/* SIFSTS register return codes (high-low) */ +#define STS_SYSTEM_IRQ 0x0080 /* Adapter-to-attached-system + * interrupt is valid. + */ +#define STS_INITIALIZE 0x0040 /* INITIALIZE status. (ready to + * initialize) + */ +#define STS_TEST 0x0020 /* TEST status. (BUD not completed) */ +#define STS_ERROR 0x0010 /* ERROR status. (unrecoverable + * HW error occurred) + */ +#define STS_MASK 0x00F0 /* Mask interesting status bits. */ +#define STS_ERROR_MASK 0x000F /* Get Error Code by masking the + * interrupt code bits. + */ +#define ADAPTER_INT_PTRS 0x0A00 /* Address offset of adapter internal + * pointers 01:0a00 (high-low) have to + * be read after init and before open. + */ + + +/* Interrupt Codes (only MAC IRQs) */ +#define STS_IRQ_ADAPTER_CHECK 0x0000 /* unrecoverable hardware or + * software error. + */ +#define STS_IRQ_RING_STATUS 0x0004 /* SSB is updated with ring status. */ +#define STS_IRQ_LLC_STATUS 0x0005 /* Not used in MAC-only microcode */ +#define STS_IRQ_SCB_CLEAR 0x0006 /* SCB clear, following an + * SCB_REQUEST IRQ. + */ +#define STS_IRQ_TIMER 0x0007 /* Not normally used in MAC ucode */ +#define STS_IRQ_COMMAND_STATUS 0x0008 /* SSB is updated with command + * status. + */ +#define STS_IRQ_RECEIVE_STATUS 0x000A /* SSB is updated with receive + * status. + */ +#define STS_IRQ_TRANSMIT_STATUS 0x000C /* SSB is updated with transmit + * status + */ +#define STS_IRQ_RECEIVE_PENDING 0x000E /* Not used in MAC-only microcode */ +#define STS_IRQ_MASK 0x000F /* = STS_ERROR_MASK. */ + + +/* TRANSMIT_STATUS completion code: (SSB.Parm[0]) */ +#define COMMAND_COMPLETE 0x0080 /* TRANSMIT command completed + * (avoid this!) issue another transmit + * to send additional frames. + */ +#define FRAME_COMPLETE 0x0040 /* Frame has been transmitted; + * INTERRUPT_FRAME bit was set in the + * CSTAT request; indication of possibly + * more than one frame transmissions! + * SSB.Parm[0-1]: 32 bit pointer to + * TPL of last frame. + */ +#define LIST_ERROR 0x0020 /* Error in one of the TPLs that + * compose the frame; TRANSMIT + * terminated; Parm[1-2]: 32bit pointer + * to TPL which starts the error + * frame; error details in bits 8-13. + * (14?) + */ +#define FRAME_SIZE_ERROR 0x8000 /* FRAME_SIZE does not equal the sum of + * the valid DATA_COUNT fields; + * FRAME_SIZE less than header plus + * information field. (15 bytes + + * routing field) Or if FRAME_SIZE + * was specified as zero in one list. + */ +#define TX_THRESHOLD 0x4000 /* FRAME_SIZE greater than (BUFFER_SIZE + * - 9) * TX_BUF_MAX. + */ +#define ODD_ADDRESS 0x2000 /* Odd forward pointer value is + * read on a list without END_FRAME + * indication. + */ +#define FRAME_ERROR 0x1000 /* START_FRAME bit (not) anticipated, + * but (not) set. + */ +#define ACCESS_PRIORITY_ERROR 0x0800 /* Access priority requested has not + * been allowed. + */ +#define UNENABLED_MAC_FRAME 0x0400 /* MAC frame has source class of zero + * or MAC frame PCF ATTN field is + * greater than one. + */ +#define ILLEGAL_FRAME_FORMAT 0x0200 /* Bit 0 or FC field was set to one. */ + + +/* + * Since we need to support some functions even if the adapter is in a + * CLOSED state, we have a (pseudo-) command queue which holds commands + * that are outstandig to be executed. + * + * Each time a command completes, an interrupt occurs and the next + * command is executed. The command queue is actually a simple word with + * a bit for each outstandig command. Therefore the commands will not be + * executed in the order they have been queued. + * + * The following defines the command code bits and the command queue: + */ +#define OC_OPEN 0x0001 /* OPEN command */ +#define OC_TRANSMIT 0x0002 /* TRANSMIT command */ +#define OC_TRANSMIT_HALT 0x0004 /* TRANSMIT_HALT command */ +#define OC_RECEIVE 0x0008 /* RECEIVE command */ +#define OC_CLOSE 0x0010 /* CLOSE command */ +#define OC_SET_GROUP_ADDR 0x0020 /* SET_GROUP_ADDR command */ +#define OC_SET_FUNCT_ADDR 0x0040 /* SET_FUNCT_ADDR command */ +#define OC_READ_ERROR_LOG 0x0080 /* READ_ERROR_LOG command */ +#define OC_READ_ADAPTER 0x0100 /* READ_ADAPTER command */ +#define OC_MODIFY_OPEN_PARMS 0x0400 /* MODIFY_OPEN_PARMS command */ +#define OC_RESTORE_OPEN_PARMS 0x0800 /* RESTORE_OPEN_PARMS command */ +#define OC_SET_FIRST_16_GROUP 0x1000 /* SET_FIRST_16_GROUP command */ +#define OC_SET_BRIDGE_PARMS 0x2000 /* SET_BRIDGE_PARMS command */ +#define OC_CONFIG_BRIDGE_PARMS 0x4000 /* CONFIG_BRIDGE_PARMS command */ + +#define OPEN 0x0300 /* C: open command. S: completion. */ +#define TRANSMIT 0x0400 /* C: transmit command. S: completion + * status. (reject: COMMAND_REJECT if + * adapter not opened, TRANSMIT already + * issued or address passed in the SCB + * not word aligned) + */ +#define TRANSMIT_HALT 0x0500 /* C: interrupt TX TPL chain; if no + * TRANSMIT command issued, the command + * is ignored (completion with TRANSMIT + * status (0x0400)!) + */ +#define RECEIVE 0x0600 /* C: receive command. S: completion + * status. (reject: COMMAND_REJECT if + * adapter not opened, RECEIVE already + * issued or address passed in the SCB + * not word aligned) + */ +#define CLOSE 0x0700 /* C: close adapter. S: completion. + * (COMMAND_REJECT if adapter not open) + */ +#define SET_GROUP_ADDR 0x0800 /* C: alter adapter group address after + * OPEN. S: completion. (COMMAND_REJECT + * if adapter not open) + */ +#define SET_FUNCT_ADDR 0x0900 /* C: alter adapter functional address + * after OPEN. S: completion. + * (COMMAND_REJECT if adapter not open) + */ +#define READ_ERROR_LOG 0x0A00 /* C: read adapter error counters. + * S: completion. (command ignored + * if adapter not open!) + */ +#define READ_ADAPTER 0x0B00 /* C: read data from adapter memory. + * (important: after init and before + * open!) S: completion. (ADAPTER_CHECK + * interrupt if undefined storage area + * read) + */ +#define MODIFY_OPEN_PARMS 0x0D00 /* C: modify some adapter operational + * parameters. (bit correspondend to + * WRAP_INTERFACE is ignored) + * S: completion. (reject: + * COMMAND_REJECT) + */ +#define RESTORE_OPEN_PARMS 0x0E00 /* C: modify some adapter operational + * parameters. (bit correspondend + * to WRAP_INTERFACE is ignored) + * S: completion. (reject: + * COMMAND_REJECT) + */ +#define SET_FIRST_16_GROUP 0x0F00 /* C: alter the first two bytes in + * adapter group address. + * S: completion. (reject: + * COMMAND_REJECT) + */ +#define SET_BRIDGE_PARMS 0x1000 /* C: values and conditions for the + * adapter hardware to use when frames + * are copied for forwarding. + * S: completion. (reject: + * COMMAND_REJECT) + */ +#define CONFIG_BRIDGE_PARMS 0x1100 /* C: .. + * S: completion. (reject: + * COMMAND_REJECT) + */ + +#define SPEED_4 4 +#define SPEED_16 16 /* Default transmission speed */ + + +/* Initialization Parameter Block (IPB); word alignment necessary! */ +#define BURST_SIZE 0x0018 /* Default burst size */ +#define BURST_MODE 0x9F00 /* Burst mode enable */ +#define DMA_RETRIES 0x0505 /* Magic DMA retry number... */ + +#define CYCLE_TIME 3 /* Default AT-bus cycle time: 500 ns + * (later adapter version: fix cycle time!) + */ +#define LINE_SPEED_BIT 0x80 + +/* Macro definition for the wait function. */ +#define ONE_SECOND_TICKS 1000000 +#define HALF_SECOND (ONE_SECOND_TICKS / 2) +#define ONE_SECOND (ONE_SECOND_TICKS) +#define TWO_SECONDS (ONE_SECOND_TICKS * 2) +#define THREE_SECONDS (ONE_SECOND_TICKS * 3) +#define FOUR_SECONDS (ONE_SECOND_TICKS * 4) +#define FIVE_SECONDS (ONE_SECOND_TICKS * 5) + +#define BUFFER_SIZE 2048 /* Buffers on Adapter */ + +#pragma pack(1) +typedef struct { + unsigned short Init_Options; /* Initialize with burst mode; + * LLC disabled. (MAC only) + */ + + /* Interrupt vectors the adapter places on attached system bus. */ + u_int8_t CMD_Status_IV; /* Interrupt vector: command status. */ + u_int8_t TX_IV; /* Interrupt vector: transmit. */ + u_int8_t RX_IV; /* Interrupt vector: receive. */ + u_int8_t Ring_Status_IV; /* Interrupt vector: ring status. */ + u_int8_t SCB_Clear_IV; /* Interrupt vector: SCB clear. */ + u_int8_t Adapter_CHK_IV; /* Interrupt vector: adapter check. */ + + u_int16_t RX_Burst_Size; /* Max. number of transfer cycles. */ + u_int16_t TX_Burst_Size; /* During DMA burst; even value! */ + u_int16_t DMA_Abort_Thrhld; /* Number of DMA retries. */ + + u_int32_t SCB_Addr; /* SCB address: even, word aligned, high-low */ + u_int32_t SSB_Addr; /* SSB address: even, word aligned, high-low */ +} IPB, *IPB_Ptr; +#pragma pack() + +/* + * OPEN Command Parameter List (OCPL) (can be reused, if the adapter has to + * be reopened) + */ +#define BUFFER_SIZE 2048 /* Buffers on Adapter. */ +#define TPL_SIZE 8+6*TX_FRAG_NUM /* Depending on fragments per TPL. */ +#define RPL_SIZE 14 /* (with TI firmware v2.26 handling + * up to nine fragments possible) + */ +#define TX_BUF_MIN 20 /* ??? (Stephan: calculation with */ +#define TX_BUF_MAX 40 /* BUFFER_SIZE and MAX_FRAME_SIZE) ??? + */ +#define DISABLE_EARLY_TOKEN_RELEASE 0x1000 + +/* OPEN Options (high-low) */ +#define WRAP_INTERFACE 0x0080 /* Inserting omitted for test + * purposes; transmit data appears + * as receive data. (useful for + * testing; change: CLOSE necessary) + */ +#define DISABLE_HARD_ERROR 0x0040 /* On HARD_ERROR & TRANSMIT_BEACON + * no RING.STATUS interrupt. + */ +#define DISABLE_SOFT_ERROR 0x0020 /* On SOFT_ERROR, no RING.STATUS + * interrupt. + */ +#define PASS_ADAPTER_MAC_FRAMES 0x0010 /* Passing unsupported MAC frames + * to system. + */ +#define PASS_ATTENTION_FRAMES 0x0008 /* All changed attention MAC frames are + * passed to the system. + */ +#define PAD_ROUTING_FIELD 0x0004 /* Routing field is padded to 18 + * bytes. + */ +#define FRAME_HOLD 0x0002 /*Adapter waits for entire frame before + * initiating DMA transfer; otherwise: + * DMA transfer initiation if internal + * buffer filled. + */ +#define CONTENDER 0x0001 /* Adapter participates in the monitor + * contention process. + */ +#define PASS_BEACON_MAC_FRAMES 0x8000 /* Adapter passes beacon MAC frames + * to the system. + */ +#define EARLY_TOKEN_RELEASE 0x1000 /* Only valid in 16 Mbps operation; + * 0 = ETR. (no effect in 4 Mbps + * operation) + */ +#define COPY_ALL_MAC_FRAMES 0x0400 /* All MAC frames are copied to + * the system. (after OPEN: duplicate + * address test (DAT) MAC frame is + * first received frame copied to the + * system) + */ +#define COPY_ALL_NON_MAC_FRAMES 0x0200 /* All non MAC frames are copied to + * the system. + */ +#define PASS_FIRST_BUF_ONLY 0x0100 /* Passes only first internal buffer + * of each received frame; FrameSize + * of RPLs must contain internal + * BUFFER_SIZE bits for promiscuous mode. + */ +#define ENABLE_FULL_DUPLEX_SELECTION 0x2000 + /* Enable the use of full-duplex + * settings with bits in byte 22 in + * ocpl. (new feature in firmware + * version 3.09) + */ + +/* Full-duplex settings */ +#define OPEN_FULL_DUPLEX_OFF 0x0000 +#define OPEN_FULL_DUPLEX_ON 0x00c0 +#define OPEN_FULL_DUPLEX_AUTO 0x0080 + +#define PROD_ID_SIZE 18 /* Length of product ID. */ + +#define TX_FRAG_NUM 3 /* Number of fragments used in one TPL. */ +#define TX_MORE_FRAGMENTS 0x8000 /* Bit set in DataCount to indicate more + * fragments following. + */ + +/* XXX is there some better way to do this? */ +#define ISA_MAX_ADDRESS 0x00ffffff +#define PCI_MAX_ADDRESS 0xffffffff + +#pragma pack(1) +typedef struct { + u_int16_t OPENOptions; + u_int8_t NodeAddr[6]; /* Adapter node address; use ROM + * address + */ + u_int32_t GroupAddr; /* Multicast: high order + * bytes = 0xC000 + */ + u_int32_t FunctAddr; /* High order bytes = 0xC000 */ + __be16 RxListSize; /* RPL size: 0 (=26), 14, 20 or + * 26 bytes read by the adapter. + * (Depending on the number of + * fragments/list) + */ + __be16 TxListSize; /* TPL size */ + __be16 BufSize; /* Is automatically rounded up to the + * nearest nK boundary. + */ + u_int16_t FullDuplex; + u_int16_t Reserved; + u_int8_t TXBufMin; /* Number of adapter buffers reserved + * for transmission a minimum of 2 + * buffers must be allocated. + */ + u_int8_t TXBufMax; /* Maximum number of adapter buffers + * for transmit; a minimum of 2 buffers + * must be available for receive. + * Default: 6 + */ + u_int16_t ProdIDAddr[2];/* Pointer to product ID. */ +} OPB, *OPB_Ptr; +#pragma pack() + +/* + * SCB: adapter commands enabled by the host system started by writing + * CMD_INTERRUPT_ADAPTER | CMD_EXECUTE (|SCB_REQUEST) to the SIFCMD IO + * register. (special case: | CMD_SYSTEM_IRQ for initialization) + */ +#pragma pack(1) +typedef struct { + u_int16_t CMD; /* Command code */ + u_int16_t Parm[2]; /* Pointer to Command Parameter Block */ +} SCB; /* System Command Block (32 bit physical address; big endian)*/ +#pragma pack() + +/* + * SSB: adapter command return status can be evaluated after COMMAND_STATUS + * adapter to system interrupt after reading SSB, the availability of the SSB + * has to be told the adapter by writing CMD_INTERRUPT_ADAPTER | CMD_SSB_CLEAR + * in the SIFCMD IO register. + */ +#pragma pack(1) +typedef struct { + u_int16_t STS; /* Status code */ + u_int16_t Parm[3]; /* Parameter or pointer to Status Parameter + * Block. + */ +} SSB; /* System Status Block (big endian - physical address) */ +#pragma pack() + +typedef struct { + unsigned short BurnedInAddrPtr; /* Pointer to adapter burned in + * address. (BIA) + */ + unsigned short SoftwareLevelPtr;/* Pointer to software level data. */ + unsigned short AdapterAddrPtr; /* Pointer to adapter addresses. */ + unsigned short AdapterParmsPtr; /* Pointer to adapter parameters. */ + unsigned short MACBufferPtr; /* Pointer to MAC buffer. (internal) */ + unsigned short LLCCountersPtr; /* Pointer to LLC counters. */ + unsigned short SpeedFlagPtr; /* Pointer to data rate flag. + * (4/16 Mbps) + */ + unsigned short AdapterRAMPtr; /* Pointer to adapter RAM found. (KB) */ +} INTPTRS; /* Adapter internal pointers */ + +#pragma pack(1) +typedef struct { + u_int8_t Line_Error; /* Line error: code violation in + * frame or in a token, or FCS error. + */ + u_int8_t Internal_Error; /* IBM specific. (Reserved_1) */ + u_int8_t Burst_Error; + u_int8_t ARI_FCI_Error; /* ARI/FCI bit zero in AMP or + * SMP MAC frame. + */ + u_int8_t AbortDelimeters; /* IBM specific. (Reserved_2) */ + u_int8_t Reserved_3; + u_int8_t Lost_Frame_Error; /* Receive of end of transmitted + * frame failed. + */ + u_int8_t Rx_Congest_Error; /* Adapter in repeat mode has not + * enough buffer space to copy incoming + * frame. + */ + u_int8_t Frame_Copied_Error; /* ARI bit not zero in frame + * addressed to adapter. + */ + u_int8_t Frequency_Error; /* IBM specific. (Reserved_4) */ + u_int8_t Token_Error; /* (active only in monitor station) */ + u_int8_t Reserved_5; + u_int8_t DMA_Bus_Error; /* DMA bus errors not exceeding the + * abort thresholds. + */ + u_int8_t DMA_Parity_Error; /* DMA parity errors not exceeding + * the abort thresholds. + */ +} ERRORTAB; /* Adapter error counters */ +#pragma pack() + + +/*--------------------- Send and Receive definitions -------------------*/ +#pragma pack(1) +typedef struct { + __be16 DataCount; /* Value 0, even and odd values are + * permitted; value is unaltered most + * significant bit set: following + * fragments last fragment: most + * significant bit is not evaluated. + * (???) + */ + __be32 DataAddr; /* Pointer to frame data fragment; + * even or odd. + */ +} Fragment; +#pragma pack() + +#define MAX_FRAG_NUMBERS 9 /* Maximal number of fragments possible to use + * in one RPL/TPL. (depending on TI firmware + * version) + */ + +/* + * AC (1), FC (1), Dst (6), Src (6), RIF (18), Data (4472) = 4504 + * The packet size can be one of the follows: 548, 1502, 2084, 4504, 8176, + * 11439, 17832. Refer to TMS380 Second Generation Token Ring User's Guide + * Page 2-27. + */ +#define HEADER_SIZE (1 + 1 + 6 + 6) +#define SRC_SIZE 18 +#define MIN_DATA_SIZE 516 +#define DEFAULT_DATA_SIZE 4472 +#define MAX_DATA_SIZE 17800 + +#define DEFAULT_PACKET_SIZE (HEADER_SIZE + SRC_SIZE + DEFAULT_DATA_SIZE) +#define MIN_PACKET_SIZE (HEADER_SIZE + SRC_SIZE + MIN_DATA_SIZE) +#define MAX_PACKET_SIZE (HEADER_SIZE + SRC_SIZE + MAX_DATA_SIZE) + +/* + * Macros to deal with the frame status field. + */ +#define AC_NOT_RECOGNIZED 0x00 +#define GROUP_BIT 0x80 +#define GET_TRANSMIT_STATUS_HIGH_BYTE(Ts) ((unsigned char)((Ts) >> 8)) +#define GET_FRAME_STATUS_HIGH_AC(Fs) ((unsigned char)(((Fs) & 0xC0) >> 6)) +#define GET_FRAME_STATUS_LOW_AC(Fs) ((unsigned char)(((Fs) & 0x0C) >> 2)) +#define DIRECTED_FRAME(Context) (!((Context)->MData[2] & GROUP_BIT)) + + +/*--------------------- Send Functions ---------------------------------*/ +/* define TX_CSTAT _REQUEST (R) and _COMPLETE (C) values (high-low) */ + +#define TX_VALID 0x0080 /* R: set via TRANSMIT.VALID interrupt. + * C: always reset to zero! + */ +#define TX_FRAME_COMPLETE 0x0040 /* R: must be reset to zero. + * C: set to one. + */ +#define TX_START_FRAME 0x0020 /* R: start of a frame: 1 + * C: unchanged. + */ +#define TX_END_FRAME 0x0010 /* R: end of a frame: 1 + * C: unchanged. + */ +#define TX_FRAME_IRQ 0x0008 /* R: request interrupt generation + * after transmission. + * C: unchanged. + */ +#define TX_ERROR 0x0004 /* R: reserved. + * C: set to one if Error occurred. + */ +#define TX_INTERFRAME_WAIT 0x0004 +#define TX_PASS_CRC 0x0002 /* R: set if CRC value is already + * calculated. (valid only in + * FRAME_START TPL) + * C: unchanged. + */ +#define TX_PASS_SRC_ADDR 0x0001 /* R: adapter uses explicit frame + * source address and does not overwrite + * with the adapter node address. + * (valid only in FRAME_START TPL) + * + * C: unchanged. + */ +#define TX_STRIP_FS 0xFF00 /* R: reserved. + * C: if no Transmission Error, + * field contains copy of FS byte after + * stripping of frame. + */ + +/* + * Structure of Transmit Parameter Lists (TPLs) (only one frame every TPL, + * but possibly multiple TPLs for one frame) the length of the TPLs has to be + * initialized in the OPL. (OPEN parameter list) + */ +#define TPL_NUM 3 /* Number of Transmit Parameter Lists. + * !! MUST BE >= 3 !! + */ + +#pragma pack(1) +typedef struct s_TPL TPL; + +struct s_TPL { /* Transmit Parameter List (align on even word boundaries) */ + __be32 NextTPLAddr; /* Pointer to next TPL in chain; if + * pointer is odd: this is the last + * TPL. Pointing to itself can cause + * problems! + */ + volatile u_int16_t Status; /* Initialized by the adapter: + * CSTAT_REQUEST important: update least + * significant bit first! Set by the + * adapter: CSTAT_COMPLETE status. + */ + __be16 FrameSize; /* Number of bytes to be transmitted + * as a frame including AC/FC, + * Destination, Source, Routing field + * not including CRC, FS, End Delimiter + * (valid only if START_FRAME bit in + * CSTAT nonzero) must not be zero in + * any list; maximum value: (BUFFER_SIZE + * - 8) * TX_BUF_MAX sum of DataCount + * values in FragmentList must equal + * Frame_Size value in START_FRAME TPL! + * frame data fragment list. + */ + + /* TPL/RPL size in OPEN parameter list depending on maximal + * numbers of fragments used in one parameter list. + */ + Fragment FragList[TX_FRAG_NUM]; /* Maximum: nine frame fragments in one + * TPL actual version of firmware: 9 + * fragments possible. + */ +#pragma pack() + + /* Special proprietary data and precalculations */ + + TPL *NextTPLPtr; /* Pointer to next TPL in chain. */ + unsigned char *MData; + struct sk_buff *Skb; + unsigned char TPLIndex; + volatile unsigned char BusyFlag;/* Flag: TPL busy? */ + dma_addr_t DMABuff; /* DMA IO bus address from dma_map */ +}; + +/* ---------------------Receive Functions-------------------------------* + * define RECEIVE_CSTAT_REQUEST (R) and RECEIVE_CSTAT_COMPLETE (C) values. + * (high-low) + */ +#define RX_VALID 0x0080 /* R: set; tell adapter with + * RECEIVE.VALID interrupt. + * C: reset to zero. + */ +#define RX_FRAME_COMPLETE 0x0040 /* R: must be reset to zero, + * C: set to one. + */ +#define RX_START_FRAME 0x0020 /* R: must be reset to zero. + * C: set to one on the list. + */ +#define RX_END_FRAME 0x0010 /* R: must be reset to zero. + * C: set to one on the list + * that ends the frame. + */ +#define RX_FRAME_IRQ 0x0008 /* R: request interrupt generation + * after receive. + * C: unchanged. + */ +#define RX_INTERFRAME_WAIT 0x0004 /* R: after receiving a frame: + * interrupt and wait for a + * RECEIVE.CONTINUE. + * C: unchanged. + */ +#define RX_PASS_CRC 0x0002 /* R: if set, the adapter includes + * the CRC in data passed. (last four + * bytes; valid only if FRAME_START is + * set) + * C: set, if CRC is included in + * received data. + */ +#define RX_PASS_SRC_ADDR 0x0001 /* R: adapter uses explicit frame + * source address and does not + * overwrite with the adapter node + * address. (valid only if FRAME_START + * is set) + * C: unchanged. + */ +#define RX_RECEIVE_FS 0xFC00 /* R: reserved; must be reset to zero. + * C: on lists with START_FRAME, field + * contains frame status field from + * received frame; otherwise cleared. + */ +#define RX_ADDR_MATCH 0x0300 /* R: reserved; must be reset to zero. + * C: address match code mask. + */ +#define RX_STATUS_MASK 0x00FF /* Mask for receive status bits. */ + +#define RX_INTERN_ADDR_MATCH 0x0100 /* C: internally address match. */ +#define RX_EXTERN_ADDR_MATCH 0x0200 /* C: externally matched via + * XMATCH/XFAIL interface. + */ +#define RX_INTEXT_ADDR_MATCH 0x0300 /* C: internally and externally + * matched. + */ +#define RX_READY (RX_VALID | RX_FRAME_IRQ) /* Ready for receive. */ + +/* Constants for Command Status Interrupt. + * COMMAND_REJECT status field bit functions (SSB.Parm[0]) + */ +#define ILLEGAL_COMMAND 0x0080 /* Set if an unknown command + * is issued to the adapter + */ +#define ADDRESS_ERROR 0x0040 /* Set if any address field in + * the SCB is odd. (not word aligned) + */ +#define ADAPTER_OPEN 0x0020 /* Command issued illegal with + * open adapter. + */ +#define ADAPTER_CLOSE 0x0010 /* Command issued illegal with + * closed adapter. + */ +#define SAME_COMMAND 0x0008 /* Command issued with same command + * already executing. + */ + +/* OPEN_COMPLETION values (SSB.Parm[0], MSB) */ +#define NODE_ADDR_ERROR 0x0040 /* Wrong address or BIA read + * zero address. + */ +#define LIST_SIZE_ERROR 0x0020 /* If List_Size value not in 0, + * 14, 20, 26. + */ +#define BUF_SIZE_ERROR 0x0010 /* Not enough available memory for + * two buffers. + */ +#define TX_BUF_COUNT_ERROR 0x0004 /* Remaining receive buffers less than + * two. + */ +#define OPEN_ERROR 0x0002 /* Error during ring insertion; more + * information in bits 8-15. + */ + +/* Standard return codes */ +#define GOOD_COMPLETION 0x0080 /* =OPEN_SUCCESSFULL */ +#define INVALID_OPEN_OPTION 0x0001 /* OPEN options are not supported by + * the adapter. + */ + +/* OPEN phases; details of OPEN_ERROR (SSB.Parm[0], LSB) */ +#define OPEN_PHASES_MASK 0xF000 /* Check only the bits 8-11. */ +#define LOBE_MEDIA_TEST 0x1000 +#define PHYSICAL_INSERTION 0x2000 +#define ADDRESS_VERIFICATION 0x3000 +#define PARTICIPATION_IN_RING_POLL 0x4000 +#define REQUEST_INITIALISATION 0x5000 +#define FULLDUPLEX_CHECK 0x6000 + +/* OPEN error codes; details of OPEN_ERROR (SSB.Parm[0], LSB) */ +#define OPEN_ERROR_CODES_MASK 0x0F00 /* Check only the bits 12-15. */ +#define OPEN_FUNCTION_FAILURE 0x0100 /* Unable to transmit to itself or + * frames received before insertion. + */ +#define OPEN_SIGNAL_LOSS 0x0200 /* Signal loss condition detected at + * receiver. + */ +#define OPEN_TIMEOUT 0x0500 /* Insertion timer expired before + * logical insertion. + */ +#define OPEN_RING_FAILURE 0x0600 /* Unable to receive own ring purge + * MAC frames. + */ +#define OPEN_RING_BEACONING 0x0700 /* Beacon MAC frame received after + * ring insertion. + */ +#define OPEN_DUPLICATE_NODEADDR 0x0800 /* Other station in ring found + * with the same address. + */ +#define OPEN_REQUEST_INIT 0x0900 /* RPS present but does not respond. */ +#define OPEN_REMOVE_RECEIVED 0x0A00 /* Adapter received a remove adapter + * MAC frame. + */ +#define OPEN_FULLDUPLEX_SET 0x0D00 /* Got this with full duplex on when + * trying to connect to a normal ring. + */ + +/* SET_BRIDGE_PARMS return codes: */ +#define BRIDGE_INVALID_MAX_LEN 0x4000 /* MAX_ROUTING_FIELD_LENGTH odd, + * less than 6 or > 30. + */ +#define BRIDGE_INVALID_SRC_RING 0x2000 /* SOURCE_RING number zero, too large + * or = TARGET_RING. + */ +#define BRIDGE_INVALID_TRG_RING 0x1000 /* TARGET_RING number zero, too large + * or = SOURCE_RING. + */ +#define BRIDGE_INVALID_BRDGE_NO 0x0800 /* BRIDGE_NUMBER too large. */ +#define BRIDGE_INVALID_OPTIONS 0x0400 /* Invalid bridge options. */ +#define BRIDGE_DIAGS_FAILED 0x0200 /* Diagnostics of TMS380SRA failed. */ +#define BRIDGE_NO_SRA 0x0100 /* The TMS380SRA does not exist in HW + * configuration. + */ + +/* + * Bring Up Diagnostics error codes. + */ +#define BUD_INITIAL_ERROR 0x0 +#define BUD_CHECKSUM_ERROR 0x1 +#define BUD_ADAPTER_RAM_ERROR 0x2 +#define BUD_INSTRUCTION_ERROR 0x3 +#define BUD_CONTEXT_ERROR 0x4 +#define BUD_PROTOCOL_ERROR 0x5 +#define BUD_INTERFACE_ERROR 0x6 + +/* BUD constants */ +#define BUD_MAX_RETRIES 3 +#define BUD_MAX_LOOPCNT 6 +#define BUD_TIMEOUT 3000 + +/* Initialization constants */ +#define INIT_MAX_RETRIES 3 /* Maximum three retries. */ +#define INIT_MAX_LOOPCNT 22 /* Maximum loop counts. */ + +/* RING STATUS field values (high/low) */ +#define SIGNAL_LOSS 0x0080 /* Loss of signal on the ring + * detected. + */ +#define HARD_ERROR 0x0040 /* Transmitting or receiving beacon + * frames. + */ +#define SOFT_ERROR 0x0020 /* Report error MAC frame + * transmitted. + */ +#define TRANSMIT_BEACON 0x0010 /* Transmitting beacon frames on the + * ring. + */ +#define LOBE_WIRE_FAULT 0x0008 /* Open or short circuit in the + * cable to concentrator; adapter + * closed. + */ +#define AUTO_REMOVAL_ERROR 0x0004 /* Lobe wrap test failed, deinserted; + * adapter closed. + */ +#define REMOVE_RECEIVED 0x0001 /* Received a remove ring station MAC + * MAC frame request; adapter closed. + */ +#define COUNTER_OVERFLOW 0x8000 /* Overflow of one of the adapters + * error counters; READ.ERROR.LOG. + */ +#define SINGLE_STATION 0x4000 /* Adapter is the only station on the + * ring. + */ +#define RING_RECOVERY 0x2000 /* Claim token MAC frames on the ring; + * reset after ring purge frame. + */ + +#define ADAPTER_CLOSED (LOBE_WIRE_FAULT | AUTO_REMOVAL_ERROR |\ + REMOVE_RECEIVED) + +/* Adapter_check_block.Status field bit assignments: */ +#define DIO_PARITY 0x8000 /* Adapter detects bad parity + * through direct I/O access. + */ +#define DMA_READ_ABORT 0x4000 /* Aborting DMA read operation + * from system Parm[0]: 0=timeout, + * 1=parity error, 2=bus error; + * Parm[1]: 32 bit pointer to host + * system address at failure. + */ +#define DMA_WRITE_ABORT 0x2000 /* Aborting DMA write operation + * to system. (parameters analogous to + * DMA_READ_ABORT) + */ +#define ILLEGAL_OP_CODE 0x1000 /* Illegal operation code in the + * the adapters firmware Parm[0]-2: + * communications processor registers + * R13-R15. + */ +#define PARITY_ERRORS 0x0800 /* Adapter detects internal bus + * parity error. + */ +#define RAM_DATA_ERROR 0x0080 /* Valid only during RAM testing; + * RAM data error Parm[0-1]: 32 bit + * pointer to RAM location. + */ +#define RAM_PARITY_ERROR 0x0040 /* Valid only during RAM testing; + * RAM parity error Parm[0-1]: 32 bit + * pointer to RAM location. + */ +#define RING_UNDERRUN 0x0020 /* Internal DMA underrun when + * transmitting onto ring. + */ +#define INVALID_IRQ 0x0008 /* Unrecognized interrupt generated + * internal to adapter Parm[0-2]: + * adapter register R13-R15. + */ +#define INVALID_ERROR_IRQ 0x0004 /* Unrecognized error interrupt + * generated Parm[0-2]: adapter register + * R13-R15. + */ +#define INVALID_XOP 0x0002 /* Unrecognized XOP request in + * communication processor Parm[0-2]: + * adapter register R13-R15. + */ +#define CHECKADDR 0x05E0 /* Adapter check status information + * address offset. + */ +#define ROM_PAGE_0 0x0000 /* Adapter ROM page 0. */ + +/* + * RECEIVE.STATUS interrupt result SSB values: (high-low) + * (RECEIVE_COMPLETE field bit definitions in SSB.Parm[0]) + */ +#define RX_COMPLETE 0x0080 /* SSB.Parm[0]; SSB.Parm[1]: 32 + * bit pointer to last RPL. + */ +#define RX_SUSPENDED 0x0040 /* SSB.Parm[0]; SSB.Parm[1]: 32 + * bit pointer to RPL with odd + * forward pointer. + */ + +/* Valid receive CSTAT: */ +#define RX_FRAME_CONTROL_BITS (RX_VALID | RX_START_FRAME | RX_END_FRAME | \ + RX_FRAME_COMPLETE) +#define VALID_SINGLE_BUFFER_FRAME (RX_START_FRAME | RX_END_FRAME | \ + RX_FRAME_COMPLETE) + +typedef enum SKB_STAT SKB_STAT; +enum SKB_STAT { + SKB_UNAVAILABLE, + SKB_DMA_DIRECT, + SKB_DATA_COPY +}; + +/* Receive Parameter List (RPL) The length of the RPLs has to be initialized + * in the OPL. (OPEN parameter list) + */ +#define RPL_NUM 3 + +#define RX_FRAG_NUM 1 /* Maximal number of used fragments in one RPL. + * (up to firmware v2.24: 3, now: up to 9) + */ + +#pragma pack(1) +typedef struct s_RPL RPL; +struct s_RPL { /* Receive Parameter List */ + __be32 NextRPLAddr; /* Pointer to next RPL in chain + * (normalized = physical 32 bit + * address) if pointer is odd: this + * is last RPL. Pointing to itself can + * cause problems! + */ + volatile u_int16_t Status; /* Set by creation of Receive Parameter + * List RECEIVE_CSTAT_COMPLETE set by + * adapter in lists that start or end + * a frame. + */ + volatile __be16 FrameSize; /* Number of bytes received as a + * frame including AC/FC, Destination, + * Source, Routing field not including + * CRC, FS (Frame Status), End Delimiter + * (valid only if START_FRAME bit in + * CSTAT nonzero) must not be zero in + * any list; maximum value: (BUFFER_SIZE + * - 8) * TX_BUF_MAX sum of DataCount + * values in FragmentList must equal + * Frame_Size value in START_FRAME TPL! + * frame data fragment list + */ + + /* TPL/RPL size in OPEN parameter list depending on maximal numbers + * of fragments used in one parameter list. + */ + Fragment FragList[RX_FRAG_NUM]; /* Maximum: nine frame fragments in + * one TPL. Actual version of firmware: + * 9 fragments possible. + */ +#pragma pack() + + /* Special proprietary data and precalculations. */ + RPL *NextRPLPtr; /* Logical pointer to next RPL in chain. */ + unsigned char *MData; + struct sk_buff *Skb; + SKB_STAT SkbStat; + int RPLIndex; + dma_addr_t DMABuff; /* DMA IO bus address from dma_map */ +}; + +/* Information that need to be kept for each board. */ +typedef struct net_local { +#pragma pack(1) + IPB ipb; /* Initialization Parameter Block. */ + SCB scb; /* System Command Block: system to adapter + * communication. + */ + SSB ssb; /* System Status Block: adapter to system + * communication. + */ + OPB ocpl; /* Open Options Parameter Block. */ + + ERRORTAB errorlogtable; /* Adapter statistic error counters. + * (read from adapter memory) + */ + unsigned char ProductID[PROD_ID_SIZE + 1]; /* Product ID */ +#pragma pack() + + TPL Tpl[TPL_NUM]; + TPL *TplFree; + TPL *TplBusy; + unsigned char LocalTxBuffers[TPL_NUM][DEFAULT_PACKET_SIZE]; + + RPL Rpl[RPL_NUM]; + RPL *RplHead; + RPL *RplTail; + unsigned char LocalRxBuffers[RPL_NUM][DEFAULT_PACKET_SIZE]; + + struct device *pdev; + int DataRate; + unsigned char ScbInUse; + unsigned short CMDqueue; + + unsigned long AdapterOpenFlag:1; + unsigned long AdapterVirtOpenFlag:1; + unsigned long OpenCommandIssued:1; + unsigned long TransmitCommandActive:1; + unsigned long TransmitHaltScheduled:1; + unsigned long HaltInProgress:1; + unsigned long LobeWireFaultLogged:1; + unsigned long ReOpenInProgress:1; + unsigned long Sleeping:1; + + unsigned long LastOpenStatus; + unsigned short CurrentRingStatus; + unsigned long MaxPacketSize; + + unsigned long StartTime; + unsigned long LastSendTime; + + struct tr_statistics MacStat; /* MAC statistics structure */ + + unsigned long dmalimit; /* the max DMA address (ie, ISA) */ + dma_addr_t dmabuffer; /* the DMA bus address corresponding to + priv. Might be different from virt_to_bus() + for architectures with IO MMU (Alpha) */ + + struct timer_list timer; + + wait_queue_head_t wait_for_tok_int; + + INTPTRS intptrs; /* Internal adapter pointer. Must be read + * before OPEN command. + */ + unsigned short (*setnselout)(struct net_device *); + unsigned short (*sifreadb)(struct net_device *, unsigned short); + void (*sifwriteb)(struct net_device *, unsigned short, unsigned short); + unsigned short (*sifreadw)(struct net_device *, unsigned short); + void (*sifwritew)(struct net_device *, unsigned short, unsigned short); + + spinlock_t lock; /* SMP protection */ + void *tmspriv; +} NET_LOCAL; + +#endif /* __KERNEL__ */ +#endif /* __LINUX_TMS380TR_H */ diff --git a/trunk/drivers/net/tokenring/tmspci.c b/trunk/drivers/net/tokenring/tmspci.c new file mode 100644 index 000000000000..90f3fa44a151 --- /dev/null +++ b/trunk/drivers/net/tokenring/tmspci.c @@ -0,0 +1,236 @@ +/* + * tmspci.c: A generic network driver for TMS380-based PCI token ring cards. + * + * Written 1999 by Adam Fritzler + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * This driver module supports the following cards: + * - SysKonnect TR4/16(+) PCI (SK-4590) + * - SysKonnect TR4/16 PCI (SK-4591) + * - Compaq TR 4/16 PCI + * - Thomas-Conrad TC4048 4/16 PCI + * - 3Com 3C339 Token Link Velocity + * + * Maintainer(s): + * AF Adam Fritzler + * + * Modification History: + * 30-Dec-99 AF Split off from the tms380tr driver. + * 22-Jan-00 AF Updated to use indirect read/writes + * 23-Nov-00 JG New PCI API, cleanups + * + * TODO: + * 1. See if we can use MMIO instead of port accesses + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "tms380tr.h" + +static char version[] __devinitdata = +"tmspci.c: v1.02 23/11/2000 by Adam Fritzler\n"; + +#define TMS_PCI_IO_EXTENT 32 + +struct card_info { + unsigned char nselout[2]; /* NSELOUT vals for 4mb([0]) and 16mb([1]) */ + char *name; +}; + +static struct card_info card_info_table[] = { + { {0x03, 0x01}, "Compaq 4/16 TR PCI"}, + { {0x03, 0x01}, "SK NET TR 4/16 PCI"}, + { {0x03, 0x01}, "Thomas-Conrad TC4048 PCI 4/16"}, + { {0x03, 0x01}, "3Com Token Link Velocity"}, +}; + +static DEFINE_PCI_DEVICE_TABLE(tmspci_pci_tbl) = { + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TOKENRING, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_TR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, + { PCI_VENDOR_ID_TCONRAD, PCI_DEVICE_ID_TCONRAD_TOKENRING, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, + { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C339, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(pci, tmspci_pci_tbl); + +MODULE_LICENSE("GPL"); + +static void tms_pci_read_eeprom(struct net_device *dev); +static unsigned short tms_pci_setnselout_pins(struct net_device *dev); + +static unsigned short tms_pci_sifreadb(struct net_device *dev, unsigned short reg) +{ + return inb(dev->base_addr + reg); +} + +static unsigned short tms_pci_sifreadw(struct net_device *dev, unsigned short reg) +{ + return inw(dev->base_addr + reg); +} + +static void tms_pci_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg) +{ + outb(val, dev->base_addr + reg); +} + +static void tms_pci_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg) +{ + outw(val, dev->base_addr + reg); +} + +static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + static int versionprinted; + struct net_device *dev; + struct net_local *tp; + int ret; + unsigned int pci_irq_line; + unsigned long pci_ioaddr; + struct card_info *cardinfo = &card_info_table[ent->driver_data]; + + if (versionprinted++ == 0) + printk("%s", version); + + if (pci_enable_device(pdev)) + return -EIO; + + /* Remove I/O space marker in bit 0. */ + pci_irq_line = pdev->irq; + pci_ioaddr = pci_resource_start (pdev, 0); + + /* At this point we have found a valid card. */ + dev = alloc_trdev(sizeof(struct net_local)); + if (!dev) + return -ENOMEM; + + if (!request_region(pci_ioaddr, TMS_PCI_IO_EXTENT, dev->name)) { + ret = -EBUSY; + goto err_out_trdev; + } + + dev->base_addr = pci_ioaddr; + dev->irq = pci_irq_line; + dev->dma = 0; + + dev_info(&pdev->dev, "%s\n", cardinfo->name); + dev_info(&pdev->dev, " IO: %#4lx IRQ: %d\n", dev->base_addr, dev->irq); + + tms_pci_read_eeprom(dev); + + dev_info(&pdev->dev, " Ring Station Address: %pM\n", dev->dev_addr); + + ret = tmsdev_init(dev, &pdev->dev); + if (ret) { + dev_info(&pdev->dev, "unable to get memory for dev->priv.\n"); + goto err_out_region; + } + + tp = netdev_priv(dev); + tp->setnselout = tms_pci_setnselout_pins; + + tp->sifreadb = tms_pci_sifreadb; + tp->sifreadw = tms_pci_sifreadw; + tp->sifwriteb = tms_pci_sifwriteb; + tp->sifwritew = tms_pci_sifwritew; + + memcpy(tp->ProductID, cardinfo->name, PROD_ID_SIZE + 1); + + tp->tmspriv = cardinfo; + + dev->netdev_ops = &tms380tr_netdev_ops; + + ret = request_irq(pdev->irq, tms380tr_interrupt, IRQF_SHARED, + dev->name, dev); + if (ret) + goto err_out_tmsdev; + + pci_set_drvdata(pdev, dev); + SET_NETDEV_DEV(dev, &pdev->dev); + + ret = register_netdev(dev); + if (ret) + goto err_out_irq; + + return 0; + +err_out_irq: + free_irq(pdev->irq, dev); +err_out_tmsdev: + pci_set_drvdata(pdev, NULL); + tmsdev_term(dev); +err_out_region: + release_region(pci_ioaddr, TMS_PCI_IO_EXTENT); +err_out_trdev: + free_netdev(dev); + return ret; +} + +/* + * Reads MAC address from adapter RAM, which should've read it from + * the onboard ROM. + * + * Calling this on a board that does not support it can be a very + * dangerous thing. The Madge board, for instance, will lock your + * machine hard when this is called. Luckily, its supported in a + * separate driver. --ASF + */ +static void tms_pci_read_eeprom(struct net_device *dev) +{ + int i; + + /* Address: 0000:0000 */ + tms_pci_sifwritew(dev, 0, SIFADX); + tms_pci_sifwritew(dev, 0, SIFADR); + + /* Read six byte MAC address data */ + dev->addr_len = 6; + for(i = 0; i < 6; i++) + dev->dev_addr[i] = tms_pci_sifreadw(dev, SIFINC) >> 8; +} + +static unsigned short tms_pci_setnselout_pins(struct net_device *dev) +{ + unsigned short val = 0; + struct net_local *tp = netdev_priv(dev); + struct card_info *cardinfo = tp->tmspriv; + + if(tp->DataRate == SPEED_4) + val |= cardinfo->nselout[0]; /* Set 4Mbps */ + else + val |= cardinfo->nselout[1]; /* Set 16Mbps */ + return val; +} + +static void __devexit tms_pci_detach (struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + + BUG_ON(!dev); + unregister_netdev(dev); + release_region(dev->base_addr, TMS_PCI_IO_EXTENT); + free_irq(dev->irq, dev); + tmsdev_term(dev); + free_netdev(dev); + pci_set_drvdata(pdev, NULL); +} + +static struct pci_driver tms_pci_driver = { + .name = "tmspci", + .id_table = tmspci_pci_tbl, + .probe = tms_pci_attach, + .remove = __devexit_p(tms_pci_detach), +}; + +module_pci_driver(tms_pci_driver); diff --git a/trunk/drivers/net/tun.c b/trunk/drivers/net/tun.c index 987aeefbc774..bb8c72c79c6f 100644 --- a/trunk/drivers/net/tun.c +++ b/trunk/drivers/net/tun.c @@ -313,7 +313,7 @@ static int run_filter(struct tap_filter *filter, const struct sk_buff *skb) /* Exact match */ for (i = 0; i < filter->count; i++) - if (ether_addr_equal(eh->h_dest, filter->addr[i])) + if (!compare_ether_addr(eh->h_dest, filter->addr[i])) return 1; /* Inexact match (multicast only) */ diff --git a/trunk/drivers/net/usb/cdc_ether.c b/trunk/drivers/net/usb/cdc_ether.c index fffee6aee8bb..00880edba048 100644 --- a/trunk/drivers/net/usb/cdc_ether.c +++ b/trunk/drivers/net/usb/cdc_ether.c @@ -485,8 +485,6 @@ static const struct driver_info wwan_info = { /*-------------------------------------------------------------------------*/ #define HUAWEI_VENDOR_ID 0x12D1 -#define NOVATEL_VENDOR_ID 0x1410 -#define ZTE_VENDOR_ID 0x19D2 static const struct usb_device_id products [] = { /* @@ -604,76 +602,6 @@ static const struct usb_device_id products [] = { * because of bugs/quirks in a given product (like Zaurus, above). */ { - /* Novatel USB551L */ - /* This match must come *before* the generic CDC-ETHER match so that - * we get FLAG_WWAN set on the device, since it's descriptors are - * generic CDC-ETHER. - */ - .match_flags = USB_DEVICE_ID_MATCH_VENDOR - | USB_DEVICE_ID_MATCH_PRODUCT - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = NOVATEL_VENDOR_ID, - .idProduct = 0xB001, - .bInterfaceClass = USB_CLASS_COMM, - .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, - .bInterfaceProtocol = USB_CDC_PROTO_NONE, - .driver_info = (unsigned long)&wwan_info, -}, { - /* ZTE (Vodafone) K3805-Z */ - .match_flags = USB_DEVICE_ID_MATCH_VENDOR - | USB_DEVICE_ID_MATCH_PRODUCT - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = ZTE_VENDOR_ID, - .idProduct = 0x1003, - .bInterfaceClass = USB_CLASS_COMM, - .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, - .bInterfaceProtocol = USB_CDC_PROTO_NONE, - .driver_info = (unsigned long)&wwan_info, -}, { - /* ZTE (Vodafone) K3806-Z */ - .match_flags = USB_DEVICE_ID_MATCH_VENDOR - | USB_DEVICE_ID_MATCH_PRODUCT - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = ZTE_VENDOR_ID, - .idProduct = 0x1015, - .bInterfaceClass = USB_CLASS_COMM, - .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, - .bInterfaceProtocol = USB_CDC_PROTO_NONE, - .driver_info = (unsigned long)&wwan_info, -}, { - /* ZTE (Vodafone) K4510-Z */ - .match_flags = USB_DEVICE_ID_MATCH_VENDOR - | USB_DEVICE_ID_MATCH_PRODUCT - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = ZTE_VENDOR_ID, - .idProduct = 0x1173, - .bInterfaceClass = USB_CLASS_COMM, - .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, - .bInterfaceProtocol = USB_CDC_PROTO_NONE, - .driver_info = (unsigned long)&wwan_info, -}, { - /* ZTE (Vodafone) K3770-Z */ - .match_flags = USB_DEVICE_ID_MATCH_VENDOR - | USB_DEVICE_ID_MATCH_PRODUCT - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = ZTE_VENDOR_ID, - .idProduct = 0x1177, - .bInterfaceClass = USB_CLASS_COMM, - .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, - .bInterfaceProtocol = USB_CDC_PROTO_NONE, - .driver_info = (unsigned long)&wwan_info, -}, { - /* ZTE (Vodafone) K3772-Z */ - .match_flags = USB_DEVICE_ID_MATCH_VENDOR - | USB_DEVICE_ID_MATCH_PRODUCT - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = ZTE_VENDOR_ID, - .idProduct = 0x1181, - .bInterfaceClass = USB_CLASS_COMM, - .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, - .bInterfaceProtocol = USB_CDC_PROTO_NONE, - .driver_info = (unsigned long)&wwan_info, -}, { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), .driver_info = (unsigned long) &cdc_info, diff --git a/trunk/drivers/net/usb/qmi_wwan.c b/trunk/drivers/net/usb/qmi_wwan.c index 63cfd0b2c31a..d316503b35d4 100644 --- a/trunk/drivers/net/usb/qmi_wwan.c +++ b/trunk/drivers/net/usb/qmi_wwan.c @@ -356,19 +356,10 @@ static const struct driver_info qmi_wwan_gobi = { }; /* ZTE suck at making USB descriptors */ -static const struct driver_info qmi_wwan_force_int1 = { - .description = "Qualcomm WWAN/QMI device", - .flags = FLAG_WWAN, - .bind = qmi_wwan_bind_shared, - .unbind = qmi_wwan_unbind_shared, - .manage_power = qmi_wwan_manage_power, - .data = BIT(1), /* interface whitelist bitmap */ -}; - static const struct driver_info qmi_wwan_force_int4 = { - .description = "Qualcomm WWAN/QMI device", + .description = "Qualcomm Gobi wwan/QMI device", .flags = FLAG_WWAN, - .bind = qmi_wwan_bind_shared, + .bind = qmi_wwan_bind_gobi, .unbind = qmi_wwan_unbind_shared, .manage_power = qmi_wwan_manage_power, .data = BIT(4), /* interface whitelist bitmap */ @@ -410,14 +401,6 @@ static const struct usb_device_id products[] = { .bInterfaceProtocol = 8, /* NOTE: This is the *slave* interface of the CDC Union! */ .driver_info = (unsigned long)&qmi_wwan_info, }, - { /* Vodafone/Huawei K5005 (12d1:14c8) and similar modems */ - .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = HUAWEI_VENDOR_ID, - .bInterfaceClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 56, /* NOTE: This is the *slave* interface of the CDC Union! */ - .driver_info = (unsigned long)&qmi_wwan_info, - }, { /* Huawei E392, E398 and possibly others in "Windows mode" * using a combined control and data interface without any CDC * functional descriptors @@ -447,15 +430,6 @@ static const struct usb_device_id products[] = { .bInterfaceProtocol = 0xff, .driver_info = (unsigned long)&qmi_wwan_force_int4, }, - { /* ZTE (Vodafone) K3520-Z */ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x19d2, - .idProduct = 0x0055, - .bInterfaceClass = 0xff, - .bInterfaceSubClass = 0xff, - .bInterfaceProtocol = 0xff, - .driver_info = (unsigned long)&qmi_wwan_force_int1, - }, { /* ZTE (Vodafone) K3565-Z */ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, .idVendor = 0x19d2, @@ -483,15 +457,6 @@ static const struct usb_device_id products[] = { .bInterfaceProtocol = 0xff, .driver_info = (unsigned long)&qmi_wwan_force_int4, }, - { /* ZTE (Vodafone) K3765-Z */ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x19d2, - .idProduct = 0x2002, - .bInterfaceClass = 0xff, - .bInterfaceSubClass = 0xff, - .bInterfaceProtocol = 0xff, - .driver_info = (unsigned long)&qmi_wwan_force_int4, - }, { /* ZTE (Vodafone) K4505-Z */ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, .idVendor = 0x19d2, diff --git a/trunk/drivers/net/usb/rndis_host.c b/trunk/drivers/net/usb/rndis_host.c index 0d746b3fdef1..c8f1b5b3aff3 100644 --- a/trunk/drivers/net/usb/rndis_host.c +++ b/trunk/drivers/net/usb/rndis_host.c @@ -77,9 +77,7 @@ static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg, if (dev->driver_info->indication) { dev->driver_info->indication(dev, msg, buflen); } else { - u32 status = le32_to_cpu(msg->status); - - switch (status) { + switch (msg->status) { case RNDIS_STATUS_MEDIA_CONNECT: dev_info(udev, "rndis media connect\n"); break; @@ -87,7 +85,8 @@ static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg, dev_info(udev, "rndis media disconnect\n"); break; default: - dev_info(udev, "rndis indication: 0x%08x\n", status); + dev_info(udev, "rndis indication: 0x%08x\n", + le32_to_cpu(msg->status)); } } } @@ -110,17 +109,16 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen) int retval; int partial; unsigned count; - u32 xid = 0, msg_len, request_id, msg_type, rsp, - status; + __le32 rsp; + u32 xid = 0, msg_len, request_id; /* REVISIT when this gets called from contexts other than probe() or * disconnect(): either serialize, or dispatch responses on xid */ - msg_type = le32_to_cpu(buf->msg_type); - /* Issue the request; xid is unique, don't bother byteswapping it */ - if (likely(msg_type != RNDIS_MSG_HALT && msg_type != RNDIS_MSG_RESET)) { + if (likely(buf->msg_type != RNDIS_MSG_HALT && + buf->msg_type != RNDIS_MSG_RESET)) { xid = dev->xid++; if (!xid) xid = dev->xid++; @@ -151,7 +149,7 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen) } /* Poll the control channel; the request probably completed immediately */ - rsp = le32_to_cpu(buf->msg_type) | RNDIS_MSG_COMPLETION; + rsp = buf->msg_type | RNDIS_MSG_COMPLETION; for (count = 0; count < 10; count++) { memset(buf, 0, CONTROL_BUFFER_SIZE); retval = usb_control_msg(dev->udev, @@ -162,36 +160,35 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen) buf, buflen, RNDIS_CONTROL_TIMEOUT_MS); if (likely(retval >= 8)) { - msg_type = le32_to_cpu(buf->msg_type); msg_len = le32_to_cpu(buf->msg_len); - status = le32_to_cpu(buf->status); request_id = (__force u32) buf->request_id; - if (likely(msg_type == rsp)) { + if (likely(buf->msg_type == rsp)) { if (likely(request_id == xid)) { if (unlikely(rsp == RNDIS_MSG_RESET_C)) return 0; - if (likely(RNDIS_STATUS_SUCCESS == - status)) + if (likely(RNDIS_STATUS_SUCCESS + == buf->status)) return 0; dev_dbg(&info->control->dev, "rndis reply status %08x\n", - status); + le32_to_cpu(buf->status)); return -EL3RST; } dev_dbg(&info->control->dev, "rndis reply id %d expected %d\n", request_id, xid); /* then likely retry */ - } else switch (msg_type) { - case RNDIS_MSG_INDICATE: /* fault/event */ + } else switch (buf->msg_type) { + case RNDIS_MSG_INDICATE: /* fault/event */ rndis_msg_indicate(dev, (void *)buf, buflen); + break; - case RNDIS_MSG_KEEPALIVE: { /* ping */ + case RNDIS_MSG_KEEPALIVE: { /* ping */ struct rndis_keepalive_c *msg = (void *)buf; - msg->msg_type = cpu_to_le32(RNDIS_MSG_KEEPALIVE_C); + msg->msg_type = RNDIS_MSG_KEEPALIVE_C; msg->msg_len = cpu_to_le32(sizeof *msg); - msg->status = cpu_to_le32(RNDIS_STATUS_SUCCESS); + msg->status = RNDIS_STATUS_SUCCESS; retval = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), USB_CDC_SEND_ENCAPSULATED_COMMAND, @@ -239,7 +236,7 @@ EXPORT_SYMBOL_GPL(rndis_command); * ActiveSync 4.1 Windows driver. */ static int rndis_query(struct usbnet *dev, struct usb_interface *intf, - void *buf, u32 oid, u32 in_len, + void *buf, __le32 oid, u32 in_len, void **reply, int *reply_len) { int retval; @@ -254,9 +251,9 @@ static int rndis_query(struct usbnet *dev, struct usb_interface *intf, u.buf = buf; memset(u.get, 0, sizeof *u.get + in_len); - u.get->msg_type = cpu_to_le32(RNDIS_MSG_QUERY); + u.get->msg_type = RNDIS_MSG_QUERY; u.get->msg_len = cpu_to_le32(sizeof *u.get + in_len); - u.get->oid = cpu_to_le32(oid); + u.get->oid = oid; u.get->len = cpu_to_le32(in_len); u.get->offset = cpu_to_le32(20); @@ -327,7 +324,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) if (retval < 0) goto fail; - u.init->msg_type = cpu_to_le32(RNDIS_MSG_INIT); + u.init->msg_type = RNDIS_MSG_INIT; u.init->msg_len = cpu_to_le32(sizeof *u.init); u.init->major_version = cpu_to_le32(1); u.init->minor_version = cpu_to_le32(0); @@ -398,23 +395,22 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) /* Check physical medium */ phym = NULL; reply_len = sizeof *phym; - retval = rndis_query(dev, intf, u.buf, - RNDIS_OID_GEN_PHYSICAL_MEDIUM, - 0, (void **) &phym, &reply_len); + retval = rndis_query(dev, intf, u.buf, OID_GEN_PHYSICAL_MEDIUM, + 0, (void **) &phym, &reply_len); if (retval != 0 || !phym) { /* OID is optional so don't fail here. */ - phym_unspec = cpu_to_le32(RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED); + phym_unspec = RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED; phym = &phym_unspec; } if ((flags & FLAG_RNDIS_PHYM_WIRELESS) && - le32_to_cpup(phym) != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { + *phym != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { netif_dbg(dev, probe, dev->net, "driver requires wireless physical medium, but device is not\n"); retval = -ENODEV; goto halt_fail_and_release; } if ((flags & FLAG_RNDIS_PHYM_NOT_WIRELESS) && - le32_to_cpup(phym) == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { + *phym == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { netif_dbg(dev, probe, dev->net, "driver requires non-wireless physical medium, but device is wireless.\n"); retval = -ENODEV; @@ -423,9 +419,8 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) /* Get designated host ethernet address */ reply_len = ETH_ALEN; - retval = rndis_query(dev, intf, u.buf, - RNDIS_OID_802_3_PERMANENT_ADDRESS, - 48, (void **) &bp, &reply_len); + retval = rndis_query(dev, intf, u.buf, OID_802_3_PERMANENT_ADDRESS, + 48, (void **) &bp, &reply_len); if (unlikely(retval< 0)) { dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval); goto halt_fail_and_release; @@ -435,12 +430,12 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) /* set a nonzero filter to enable data transfers */ memset(u.set, 0, sizeof *u.set); - u.set->msg_type = cpu_to_le32(RNDIS_MSG_SET); + u.set->msg_type = RNDIS_MSG_SET; u.set->msg_len = cpu_to_le32(4 + sizeof *u.set); - u.set->oid = cpu_to_le32(RNDIS_OID_GEN_CURRENT_PACKET_FILTER); + u.set->oid = OID_GEN_CURRENT_PACKET_FILTER; u.set->len = cpu_to_le32(4); u.set->offset = cpu_to_le32((sizeof *u.set) - 8); - *(__le32 *)(u.buf + sizeof *u.set) = cpu_to_le32(RNDIS_DEFAULT_FILTER); + *(__le32 *)(u.buf + sizeof *u.set) = RNDIS_DEFAULT_FILTER; retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE); if (unlikely(retval < 0)) { @@ -455,7 +450,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) halt_fail_and_release: memset(u.halt, 0, sizeof *u.halt); - u.halt->msg_type = cpu_to_le32(RNDIS_MSG_HALT); + u.halt->msg_type = RNDIS_MSG_HALT; u.halt->msg_len = cpu_to_le32(sizeof *u.halt); (void) rndis_command(dev, (void *)u.halt, CONTROL_BUFFER_SIZE); fail_and_release: @@ -480,7 +475,7 @@ void rndis_unbind(struct usbnet *dev, struct usb_interface *intf) /* try to clear any rndis state/activity (no i/o from stack!) */ halt = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL); if (halt) { - halt->msg_type = cpu_to_le32(RNDIS_MSG_HALT); + halt->msg_type = RNDIS_MSG_HALT; halt->msg_len = cpu_to_le32(sizeof *halt); (void) rndis_command(dev, (void *)halt, CONTROL_BUFFER_SIZE); kfree(halt); @@ -499,16 +494,16 @@ int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb) while (likely(skb->len)) { struct rndis_data_hdr *hdr = (void *)skb->data; struct sk_buff *skb2; - u32 msg_type, msg_len, data_offset, data_len; + u32 msg_len, data_offset, data_len; - msg_type = le32_to_cpu(hdr->msg_type); msg_len = le32_to_cpu(hdr->msg_len); data_offset = le32_to_cpu(hdr->data_offset); data_len = le32_to_cpu(hdr->data_len); /* don't choke if we see oob, per-packet data, etc */ - if (unlikely(msg_type != RNDIS_MSG_PACKET || skb->len < msg_len - || (data_offset + data_len + 8) > msg_len)) { + if (unlikely(hdr->msg_type != RNDIS_MSG_PACKET || + skb->len < msg_len || + (data_offset + data_len + 8) > msg_len)) { dev->net->stats.rx_frame_errors++; netdev_dbg(dev->net, "bad rndis message %d/%d/%d/%d, len %d\n", le32_to_cpu(hdr->msg_type), @@ -574,7 +569,7 @@ rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) fill: hdr = (void *) __skb_push(skb, sizeof *hdr); memset(hdr, 0, sizeof *hdr); - hdr->msg_type = cpu_to_le32(RNDIS_MSG_PACKET); + hdr->msg_type = RNDIS_MSG_PACKET; hdr->msg_len = cpu_to_le32(skb->len); hdr->data_offset = cpu_to_le32(sizeof(*hdr) - 8); hdr->data_len = cpu_to_le32(len); diff --git a/trunk/drivers/net/usb/usbnet.c b/trunk/drivers/net/usb/usbnet.c index 9f58330f1312..80b837c88f0d 100644 --- a/trunk/drivers/net/usb/usbnet.c +++ b/trunk/drivers/net/usb/usbnet.c @@ -282,32 +282,17 @@ int usbnet_change_mtu (struct net_device *net, int new_mtu) } EXPORT_SYMBOL_GPL(usbnet_change_mtu); -/* The caller must hold list->lock */ -static void __usbnet_queue_skb(struct sk_buff_head *list, - struct sk_buff *newsk, enum skb_state state) -{ - struct skb_data *entry = (struct skb_data *) newsk->cb; - - __skb_queue_tail(list, newsk); - entry->state = state; -} - /*-------------------------------------------------------------------------*/ /* some LK 2.4 HCDs oopsed if we freed or resubmitted urbs from * completion callbacks. 2.5 should have fixed those bugs... */ -static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb, - struct sk_buff_head *list, enum skb_state state) +static void defer_bh(struct usbnet *dev, struct sk_buff *skb, struct sk_buff_head *list) { unsigned long flags; - enum skb_state old_state; - struct skb_data *entry = (struct skb_data *) skb->cb; spin_lock_irqsave(&list->lock, flags); - old_state = entry->state; - entry->state = state; __skb_unlink(skb, list); spin_unlock(&list->lock); spin_lock(&dev->done.lock); @@ -315,7 +300,6 @@ static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb, if (dev->done.qlen == 1) tasklet_schedule(&dev->bh); spin_unlock_irqrestore(&dev->done.lock, flags); - return old_state; } /* some work can't be done in tasklets, so we use keventd @@ -356,6 +340,7 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) entry = (struct skb_data *) skb->cb; entry->urb = urb; entry->dev = dev; + entry->state = rx_start; entry->length = 0; usb_fill_bulk_urb (urb, dev->udev, dev->in, @@ -387,7 +372,7 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) tasklet_schedule (&dev->bh); break; case 0: - __usbnet_queue_skb(&dev->rxq, skb, rx_start); + __skb_queue_tail (&dev->rxq, skb); } } else { netif_dbg(dev, ifdown, dev->net, "rx: stopped\n"); @@ -438,17 +423,16 @@ static void rx_complete (struct urb *urb) struct skb_data *entry = (struct skb_data *) skb->cb; struct usbnet *dev = entry->dev; int urb_status = urb->status; - enum skb_state state; skb_put (skb, urb->actual_length); - state = rx_done; + entry->state = rx_done; entry->urb = NULL; switch (urb_status) { /* success */ case 0: if (skb->len < dev->net->hard_header_len) { - state = rx_cleanup; + entry->state = rx_cleanup; dev->net->stats.rx_errors++; dev->net->stats.rx_length_errors++; netif_dbg(dev, rx_err, dev->net, @@ -487,7 +471,7 @@ static void rx_complete (struct urb *urb) "rx throttle %d\n", urb_status); } block: - state = rx_cleanup; + entry->state = rx_cleanup; entry->urb = urb; urb = NULL; break; @@ -498,18 +482,17 @@ static void rx_complete (struct urb *urb) // FALLTHROUGH default: - state = rx_cleanup; + entry->state = rx_cleanup; dev->net->stats.rx_errors++; netif_dbg(dev, rx_err, dev->net, "rx status %d\n", urb_status); break; } - state = defer_bh(dev, skb, &dev->rxq, state); + defer_bh(dev, skb, &dev->rxq); if (urb) { if (netif_running (dev->net) && - !test_bit (EVENT_RX_HALT, &dev->flags) && - state != unlink_start) { + !test_bit (EVENT_RX_HALT, &dev->flags)) { rx_submit (dev, urb, GFP_ATOMIC); usb_mark_last_busy(dev->udev); return; @@ -596,23 +579,16 @@ EXPORT_SYMBOL_GPL(usbnet_purge_paused_rxq); static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q) { unsigned long flags; - struct sk_buff *skb; + struct sk_buff *skb, *skbnext; int count = 0; spin_lock_irqsave (&q->lock, flags); - while (!skb_queue_empty(q)) { + skb_queue_walk_safe(q, skb, skbnext) { struct skb_data *entry; struct urb *urb; int retval; - skb_queue_walk(q, skb) { - entry = (struct skb_data *) skb->cb; - if (entry->state != unlink_start) - goto found; - } - break; -found: - entry->state = unlink_start; + entry = (struct skb_data *) skb->cb; urb = entry->urb; /* @@ -1064,7 +1040,8 @@ static void tx_complete (struct urb *urb) } usb_autopm_put_interface_async(dev->intf); - (void) defer_bh(dev, skb, &dev->txq, tx_done); + entry->state = tx_done; + defer_bh(dev, skb, &dev->txq); } /*-------------------------------------------------------------------------*/ @@ -1120,6 +1097,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, entry = (struct skb_data *) skb->cb; entry->urb = urb; entry->dev = dev; + entry->state = tx_start; entry->length = length; usb_fill_bulk_urb (urb, dev->udev, dev->out, @@ -1178,7 +1156,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, break; case 0: net->trans_start = jiffies; - __usbnet_queue_skb(&dev->txq, skb, tx_start); + __skb_queue_tail (&dev->txq, skb); if (dev->txq.qlen >= TX_QLEN (dev)) netif_stop_queue (net); } diff --git a/trunk/drivers/net/virtio_net.c b/trunk/drivers/net/virtio_net.c index 9ce6995e8d08..fa58c7869954 100644 --- a/trunk/drivers/net/virtio_net.c +++ b/trunk/drivers/net/virtio_net.c @@ -501,9 +501,7 @@ static void virtnet_napi_enable(struct virtnet_info *vi) * We synchronize against interrupts via NAPI_STATE_SCHED */ if (napi_schedule_prep(&vi->napi)) { virtqueue_disable_cb(vi->rvq); - local_bh_disable(); __napi_schedule(&vi->napi); - local_bh_enable(); } } diff --git a/trunk/drivers/net/wireless/at76c50x-usb.c b/trunk/drivers/net/wireless/at76c50x-usb.c index 3df0146b797e..3036c0bab056 100644 --- a/trunk/drivers/net/wireless/at76c50x-usb.c +++ b/trunk/drivers/net/wireless/at76c50x-usb.c @@ -1751,7 +1751,7 @@ static void at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * following workaround is necessary. If the TX frame is an * authentication frame extract the bssid and send the CMD_JOIN. */ if (mgmt->frame_control & cpu_to_le16(IEEE80211_STYPE_AUTH)) { - if (!ether_addr_equal(priv->bssid, mgmt->bssid)) { + if (compare_ether_addr(priv->bssid, mgmt->bssid)) { memcpy(priv->bssid, mgmt->bssid, ETH_ALEN); ieee80211_queue_work(hw, &priv->work_join_bssid); dev_kfree_skb_any(skb); diff --git a/trunk/drivers/net/wireless/ath/ath5k/base.c b/trunk/drivers/net/wireless/ath/ath5k/base.c index 0ba81a66061f..49e3b19cf781 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/base.c +++ b/trunk/drivers/net/wireless/ath/ath5k/base.c @@ -462,7 +462,7 @@ void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) } if (iter_data->need_set_hw_addr && iter_data->hw_macaddr) - if (ether_addr_equal(iter_data->hw_macaddr, mac)) + if (compare_ether_addr(iter_data->hw_macaddr, mac) == 0) iter_data->need_set_hw_addr = false; if (!iter_data->any_assoc) { @@ -1170,7 +1170,7 @@ ath5k_check_ibss_tsf(struct ath5k_hw *ah, struct sk_buff *skb, if (ieee80211_is_beacon(mgmt->frame_control) && le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && - ether_addr_equal(mgmt->bssid, common->curbssid)) { + compare_ether_addr(mgmt->bssid, common->curbssid) == 0) { /* * Received an IBSS beacon with the same BSSID. Hardware *must* * have updated the local TSF. We have to work around various @@ -1234,7 +1234,7 @@ ath5k_update_beacon_rssi(struct ath5k_hw *ah, struct sk_buff *skb, int rssi) /* only beacons from our BSSID */ if (!ieee80211_is_beacon(mgmt->frame_control) || - !ether_addr_equal(mgmt->bssid, common->curbssid)) + compare_ether_addr(mgmt->bssid, common->curbssid) != 0) return; ewma_add(&ah->ah_beacon_rssi_avg, rssi); diff --git a/trunk/drivers/net/wireless/ath/ath9k/recv.c b/trunk/drivers/net/wireless/ath/ath9k/recv.c index e1fcc68124dc..544e5490ca2e 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/recv.c +++ b/trunk/drivers/net/wireless/ath/ath9k/recv.c @@ -1833,7 +1833,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) if (ieee80211_is_beacon(hdr->frame_control)) { RX_STAT_INC(rx_beacons); if (!is_zero_ether_addr(common->curbssid) && - ether_addr_equal(hdr->addr3, common->curbssid)) + !compare_ether_addr(hdr->addr3, common->curbssid)) rs.is_mybeacon = true; else rs.is_mybeacon = false; diff --git a/trunk/drivers/net/wireless/ath/carl9170/rx.c b/trunk/drivers/net/wireless/ath/carl9170/rx.c index 84b22eec7abd..dc99030ea8b6 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/rx.c +++ b/trunk/drivers/net/wireless/ath/carl9170/rx.c @@ -538,7 +538,7 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len) return; /* and only beacons from the associated BSSID, please */ - if (!ether_addr_equal(hdr->addr3, ar->common.curbssid) || + if (compare_ether_addr(hdr->addr3, ar->common.curbssid) || !ar->common.curaid) return; diff --git a/trunk/drivers/net/wireless/ipw2x00/libipw_rx.c b/trunk/drivers/net/wireless/ipw2x00/libipw_rx.c index 02e057923236..c4955d25a19a 100644 --- a/trunk/drivers/net/wireless/ipw2x00/libipw_rx.c +++ b/trunk/drivers/net/wireless/ipw2x00/libipw_rx.c @@ -77,8 +77,8 @@ static struct libipw_frag_entry *libipw_frag_cache_find(struct if (entry->skb != NULL && entry->seq == seq && (entry->last_frag + 1 == frag || frag == -1) && - ether_addr_equal(entry->src_addr, src) && - ether_addr_equal(entry->dst_addr, dst)) + !compare_ether_addr(entry->src_addr, src) && + !compare_ether_addr(entry->dst_addr, dst)) return entry; } @@ -245,12 +245,12 @@ static int libipw_is_eapol_frame(struct libipw_device *ieee, /* check that the frame is unicast frame to us */ if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_TODS && - ether_addr_equal(hdr->addr1, dev->dev_addr) && - ether_addr_equal(hdr->addr3, dev->dev_addr)) { + !compare_ether_addr(hdr->addr1, dev->dev_addr) && + !compare_ether_addr(hdr->addr3, dev->dev_addr)) { /* ToDS frame with own addr BSSID and DA */ } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS && - ether_addr_equal(hdr->addr1, dev->dev_addr)) { + !compare_ether_addr(hdr->addr1, dev->dev_addr)) { /* FromDS frame with own addr as DA */ } else return 0; @@ -523,8 +523,8 @@ int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb, if (ieee->iw_mode == IW_MODE_MASTER && !wds && (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == - IEEE80211_FCTL_FROMDS && ieee->stadev && - ether_addr_equal(hdr->addr2, ieee->assoc_ap_addr)) { + IEEE80211_FCTL_FROMDS && ieee->stadev + && !compare_ether_addr(hdr->addr2, ieee->assoc_ap_addr)) { /* Frame from BSSID of the AP for which we are a client */ skb->dev = dev = ieee->stadev; stats = hostap_get_stats(dev); @@ -1468,7 +1468,7 @@ static inline int is_same_network(struct libipw_network *src, * as one network */ return ((src->ssid_len == dst->ssid_len) && (src->channel == dst->channel) && - ether_addr_equal(src->bssid, dst->bssid) && + !compare_ether_addr(src->bssid, dst->bssid) && !memcmp(src->ssid, dst->ssid, src->ssid_len)); } diff --git a/trunk/drivers/net/wireless/iwlegacy/3945.c b/trunk/drivers/net/wireless/iwlegacy/3945.c index 87e539894330..b25c01be0d90 100644 --- a/trunk/drivers/net/wireless/iwlegacy/3945.c +++ b/trunk/drivers/net/wireless/iwlegacy/3945.c @@ -453,10 +453,10 @@ il3945_is_network_packet(struct il_priv *il, struct ieee80211_hdr *header) switch (il->iw_mode) { case NL80211_IFTYPE_ADHOC: /* Header: Dest. | Source | BSSID */ /* packets to our IBSS update information */ - return ether_addr_equal(header->addr3, il->bssid); + return !compare_ether_addr(header->addr3, il->bssid); case NL80211_IFTYPE_STATION: /* Header: Dest. | AP{BSSID} | Source */ /* packets to our IBSS update information */ - return ether_addr_equal(header->addr2, il->bssid); + return !compare_ether_addr(header->addr2, il->bssid); default: return 1; } diff --git a/trunk/drivers/net/wireless/iwlegacy/4965-mac.c b/trunk/drivers/net/wireless/iwlegacy/4965-mac.c index 509301a5e7e2..f2baf94f069c 100644 --- a/trunk/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/trunk/drivers/net/wireless/iwlegacy/4965-mac.c @@ -2565,7 +2565,7 @@ il4965_find_station(struct il_priv *il, const u8 *addr) spin_lock_irqsave(&il->sta_lock, flags); for (i = start; i < il->hw_params.max_stations; i++) if (il->stations[i].used && - ether_addr_equal(il->stations[i].sta.sta.addr, addr)) { + (!compare_ether_addr(il->stations[i].sta.sta.addr, addr))) { ret = i; goto out; } diff --git a/trunk/drivers/net/wireless/iwlegacy/common.c b/trunk/drivers/net/wireless/iwlegacy/common.c index cbf2dc18341f..eaf249452e51 100644 --- a/trunk/drivers/net/wireless/iwlegacy/common.c +++ b/trunk/drivers/net/wireless/iwlegacy/common.c @@ -1896,8 +1896,8 @@ il_prep_station(struct il_priv *il, const u8 *addr, bool is_ap, sta_id = il->hw_params.bcast_id; else for (i = IL_STA_ID; i < il->hw_params.max_stations; i++) { - if (ether_addr_equal(il->stations[i].sta.sta.addr, - addr)) { + if (!compare_ether_addr + (il->stations[i].sta.sta.addr, addr)) { sta_id = i; break; } @@ -1926,7 +1926,7 @@ il_prep_station(struct il_priv *il, const u8 *addr, bool is_ap, if ((il->stations[sta_id].used & IL_STA_DRIVER_ACTIVE) && (il->stations[sta_id].used & IL_STA_UCODE_ACTIVE) && - ether_addr_equal(il->stations[sta_id].sta.sta.addr, addr)) { + !compare_ether_addr(il->stations[sta_id].sta.sta.addr, addr)) { D_ASSOC("STA %d (%pM) already added, not adding again.\n", sta_id, addr); return sta_id; @@ -3744,10 +3744,10 @@ il_full_rxon_required(struct il_priv *il) /* These items are only settable from the full RXON command */ CHK(!il_is_associated(il)); - CHK(!ether_addr_equal(staging->bssid_addr, active->bssid_addr)); - CHK(!ether_addr_equal(staging->node_addr, active->node_addr)); - CHK(!ether_addr_equal(staging->wlap_bssid_addr, - active->wlap_bssid_addr)); + CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr)); + CHK(compare_ether_addr(staging->node_addr, active->node_addr)); + CHK(compare_ether_addr + (staging->wlap_bssid_addr, active->wlap_bssid_addr)); CHK_NEQ(staging->dev_type, active->dev_type); CHK_NEQ(staging->channel, active->channel); CHK_NEQ(staging->air_propagation, active->air_propagation); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 403de96f9747..5b80467a5bb1 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -759,12 +759,7 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, IWL_ERR(priv, "alloc_skb failed\n"); return; } - /* If frame is small enough to fit in skb->head, pull it completely. - * If not, only pull ieee80211_hdr so that splice() or TCP coalesce - * are more efficient. - */ - hdrlen = (len <= skb_tailroom(skb)) ? len : sizeof(*hdr); - + hdrlen = min_t(unsigned int, len, skb_tailroom(skb)); memcpy(skb_put(skb, hdrlen), hdr, hdrlen); fraglen = len - hdrlen; @@ -785,8 +780,8 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, */ if (unlikely(ieee80211_is_beacon(fc) && priv->passive_no_rx)) { for_each_context(priv, ctx) { - if (!ether_addr_equal(hdr->addr3, - ctx->active.bssid_addr)) + if (compare_ether_addr(hdr->addr3, + ctx->active.bssid_addr)) continue; iwlagn_lift_passive_no_rx(priv); } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 74fbee627306..0f7c444f2440 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -881,10 +881,10 @@ int iwl_full_rxon_required(struct iwl_priv *priv, /* These items are only settable from the full RXON command */ CHK(!iwl_is_associated_ctx(ctx)); - CHK(!ether_addr_equal(staging->bssid_addr, active->bssid_addr)); - CHK(!ether_addr_equal(staging->node_addr, active->node_addr)); - CHK(!ether_addr_equal(staging->wlap_bssid_addr, - active->wlap_bssid_addr)); + CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr)); + CHK(compare_ether_addr(staging->node_addr, active->node_addr)); + CHK(compare_ether_addr(staging->wlap_bssid_addr, + active->wlap_bssid_addr)); CHK_NEQ(staging->dev_type, active->dev_type); CHK_NEQ(staging->channel, active->channel); CHK_NEQ(staging->air_propagation, active->air_propagation); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index b31584e87bc7..67e6f1d2a08b 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -322,8 +322,8 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, sta_id = ctx->bcast_sta_id; else for (i = IWL_STA_ID; i < IWLAGN_STATION_COUNT; i++) { - if (ether_addr_equal(priv->stations[i].sta.sta.addr, - addr)) { + if (!compare_ether_addr(priv->stations[i].sta.sta.addr, + addr)) { sta_id = i; break; } @@ -353,7 +353,7 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) && (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) && - ether_addr_equal(priv->stations[sta_id].sta.sta.addr, addr)) { + !compare_ether_addr(priv->stations[sta_id].sta.sta.addr, addr)) { IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not " "adding again.\n", sta_id, addr); return sta_id; diff --git a/trunk/drivers/net/wireless/mac80211_hwsim.c b/trunk/drivers/net/wireless/mac80211_hwsim.c index 03c0c6b1372c..fb787df01666 100644 --- a/trunk/drivers/net/wireless/mac80211_hwsim.c +++ b/trunk/drivers/net/wireless/mac80211_hwsim.c @@ -746,6 +746,11 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) hwsim_check_sta_magic(txi->control.sta); ieee80211_tx_info_clear_status(txi); + + /* frame was transmitted at most favorable rate at first attempt */ + txi->control.rates[0].count = 1; + txi->control.rates[1].idx = -1; + if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK) && ack) txi->flags |= IEEE80211_TX_STAT_ACK; ieee80211_tx_status_irqsafe(hw, skb); diff --git a/trunk/drivers/net/wireless/mwl8k.c b/trunk/drivers/net/wireless/mwl8k.c index cf7bdc66f822..e30cc32f8279 100644 --- a/trunk/drivers/net/wireless/mwl8k.c +++ b/trunk/drivers/net/wireless/mwl8k.c @@ -1235,7 +1235,7 @@ mwl8k_capture_bssid(struct mwl8k_priv *priv, struct ieee80211_hdr *wh) { return priv->capture_beacon && ieee80211_is_beacon(wh->frame_control) && - ether_addr_equal(wh->addr3, priv->capture_bssid); + !compare_ether_addr(wh->addr3, priv->capture_bssid); } static inline void mwl8k_save_beacon(struct ieee80211_hw *hw, diff --git a/trunk/drivers/net/wireless/p54/txrx.c b/trunk/drivers/net/wireless/p54/txrx.c index 82a1cac920bd..7c8f118c2b09 100644 --- a/trunk/drivers/net/wireless/p54/txrx.c +++ b/trunk/drivers/net/wireless/p54/txrx.c @@ -308,7 +308,7 @@ static void p54_pspoll_workaround(struct p54_common *priv, struct sk_buff *skb) return; /* only consider beacons from the associated BSSID */ - if (!ether_addr_equal(hdr->addr3, priv->bssid)) + if (compare_ether_addr(hdr->addr3, priv->bssid)) return; tim = p54_find_ie(skb, WLAN_EID_TIM); diff --git a/trunk/drivers/net/wireless/rndis_wlan.c b/trunk/drivers/net/wireless/rndis_wlan.c index b91d1bb30b41..d66e2980bc27 100644 --- a/trunk/drivers/net/wireless/rndis_wlan.c +++ b/trunk/drivers/net/wireless/rndis_wlan.c @@ -88,6 +88,49 @@ module_param_named(workaround_interval, modparam_workaround_interval, MODULE_PARM_DESC(workaround_interval, "set stall workaround interval in msecs (0=disabled) (default: 0)"); + +/* various RNDIS OID defs */ +#define OID_GEN_LINK_SPEED cpu_to_le32(0x00010107) +#define OID_GEN_RNDIS_CONFIG_PARAMETER cpu_to_le32(0x0001021b) + +#define OID_GEN_XMIT_OK cpu_to_le32(0x00020101) +#define OID_GEN_RCV_OK cpu_to_le32(0x00020102) +#define OID_GEN_XMIT_ERROR cpu_to_le32(0x00020103) +#define OID_GEN_RCV_ERROR cpu_to_le32(0x00020104) +#define OID_GEN_RCV_NO_BUFFER cpu_to_le32(0x00020105) + +#define OID_802_3_CURRENT_ADDRESS cpu_to_le32(0x01010102) +#define OID_802_3_MULTICAST_LIST cpu_to_le32(0x01010103) +#define OID_802_3_MAXIMUM_LIST_SIZE cpu_to_le32(0x01010104) + +#define OID_802_11_BSSID cpu_to_le32(0x0d010101) +#define OID_802_11_SSID cpu_to_le32(0x0d010102) +#define OID_802_11_INFRASTRUCTURE_MODE cpu_to_le32(0x0d010108) +#define OID_802_11_ADD_WEP cpu_to_le32(0x0d010113) +#define OID_802_11_REMOVE_WEP cpu_to_le32(0x0d010114) +#define OID_802_11_DISASSOCIATE cpu_to_le32(0x0d010115) +#define OID_802_11_AUTHENTICATION_MODE cpu_to_le32(0x0d010118) +#define OID_802_11_PRIVACY_FILTER cpu_to_le32(0x0d010119) +#define OID_802_11_BSSID_LIST_SCAN cpu_to_le32(0x0d01011a) +#define OID_802_11_ENCRYPTION_STATUS cpu_to_le32(0x0d01011b) +#define OID_802_11_ADD_KEY cpu_to_le32(0x0d01011d) +#define OID_802_11_REMOVE_KEY cpu_to_le32(0x0d01011e) +#define OID_802_11_ASSOCIATION_INFORMATION cpu_to_le32(0x0d01011f) +#define OID_802_11_CAPABILITY cpu_to_le32(0x0d010122) +#define OID_802_11_PMKID cpu_to_le32(0x0d010123) +#define OID_802_11_NETWORK_TYPES_SUPPORTED cpu_to_le32(0x0d010203) +#define OID_802_11_NETWORK_TYPE_IN_USE cpu_to_le32(0x0d010204) +#define OID_802_11_TX_POWER_LEVEL cpu_to_le32(0x0d010205) +#define OID_802_11_RSSI cpu_to_le32(0x0d010206) +#define OID_802_11_RSSI_TRIGGER cpu_to_le32(0x0d010207) +#define OID_802_11_FRAGMENTATION_THRESHOLD cpu_to_le32(0x0d010209) +#define OID_802_11_RTS_THRESHOLD cpu_to_le32(0x0d01020a) +#define OID_802_11_SUPPORTED_RATES cpu_to_le32(0x0d01020e) +#define OID_802_11_CONFIGURATION cpu_to_le32(0x0d010211) +#define OID_802_11_POWER_MODE cpu_to_le32(0x0d010216) +#define OID_802_11_BSSID_LIST cpu_to_le32(0x0d010217) + + /* Typical noise/maximum signal level values taken from ndiswrapper iw_ndis.h */ #define WL_NOISE -96 /* typical noise level in dBm */ #define WL_SIGMAX -32 /* typical maximum signal level in dBm */ @@ -106,6 +149,12 @@ MODULE_PARM_DESC(workaround_interval, #define BCM4320_DEFAULT_TXPOWER_DBM_50 10 #define BCM4320_DEFAULT_TXPOWER_DBM_25 7 + +/* codes for "status" field of completion messages */ +#define RNDIS_STATUS_ADAPTER_NOT_READY cpu_to_le32(0xc0010011) +#define RNDIS_STATUS_ADAPTER_NOT_OPEN cpu_to_le32(0xc0010012) + + /* Known device types */ #define RNDIS_UNKNOWN 0 #define RNDIS_BCM4320A 1 @@ -466,7 +515,7 @@ struct rndis_wlan_private { int infra_mode; bool connected; u8 bssid[ETH_ALEN]; - u32 current_command_oid; + __le32 current_command_oid; /* encryption stuff */ u8 encr_tx_key_index; @@ -621,63 +670,63 @@ static int rndis_akm_suite_to_key_mgmt(u32 akm_suite) } #ifdef DEBUG -static const char *oid_to_string(u32 oid) +static const char *oid_to_string(__le32 oid) { switch (oid) { #define OID_STR(oid) case oid: return(#oid) /* from rndis_host.h */ - OID_STR(RNDIS_OID_802_3_PERMANENT_ADDRESS); - OID_STR(RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE); - OID_STR(RNDIS_OID_GEN_CURRENT_PACKET_FILTER); - OID_STR(RNDIS_OID_GEN_PHYSICAL_MEDIUM); + OID_STR(OID_802_3_PERMANENT_ADDRESS); + OID_STR(OID_GEN_MAXIMUM_FRAME_SIZE); + OID_STR(OID_GEN_CURRENT_PACKET_FILTER); + OID_STR(OID_GEN_PHYSICAL_MEDIUM); /* from rndis_wlan.c */ - OID_STR(RNDIS_OID_GEN_LINK_SPEED); - OID_STR(RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER); - - OID_STR(RNDIS_OID_GEN_XMIT_OK); - OID_STR(RNDIS_OID_GEN_RCV_OK); - OID_STR(RNDIS_OID_GEN_XMIT_ERROR); - OID_STR(RNDIS_OID_GEN_RCV_ERROR); - OID_STR(RNDIS_OID_GEN_RCV_NO_BUFFER); - - OID_STR(RNDIS_OID_802_3_CURRENT_ADDRESS); - OID_STR(RNDIS_OID_802_3_MULTICAST_LIST); - OID_STR(RNDIS_OID_802_3_MAXIMUM_LIST_SIZE); - - OID_STR(RNDIS_OID_802_11_BSSID); - OID_STR(RNDIS_OID_802_11_SSID); - OID_STR(RNDIS_OID_802_11_INFRASTRUCTURE_MODE); - OID_STR(RNDIS_OID_802_11_ADD_WEP); - OID_STR(RNDIS_OID_802_11_REMOVE_WEP); - OID_STR(RNDIS_OID_802_11_DISASSOCIATE); - OID_STR(RNDIS_OID_802_11_AUTHENTICATION_MODE); - OID_STR(RNDIS_OID_802_11_PRIVACY_FILTER); - OID_STR(RNDIS_OID_802_11_BSSID_LIST_SCAN); - OID_STR(RNDIS_OID_802_11_ENCRYPTION_STATUS); - OID_STR(RNDIS_OID_802_11_ADD_KEY); - OID_STR(RNDIS_OID_802_11_REMOVE_KEY); - OID_STR(RNDIS_OID_802_11_ASSOCIATION_INFORMATION); - OID_STR(RNDIS_OID_802_11_CAPABILITY); - OID_STR(RNDIS_OID_802_11_PMKID); - OID_STR(RNDIS_OID_802_11_NETWORK_TYPES_SUPPORTED); - OID_STR(RNDIS_OID_802_11_NETWORK_TYPE_IN_USE); - OID_STR(RNDIS_OID_802_11_TX_POWER_LEVEL); - OID_STR(RNDIS_OID_802_11_RSSI); - OID_STR(RNDIS_OID_802_11_RSSI_TRIGGER); - OID_STR(RNDIS_OID_802_11_FRAGMENTATION_THRESHOLD); - OID_STR(RNDIS_OID_802_11_RTS_THRESHOLD); - OID_STR(RNDIS_OID_802_11_SUPPORTED_RATES); - OID_STR(RNDIS_OID_802_11_CONFIGURATION); - OID_STR(RNDIS_OID_802_11_POWER_MODE); - OID_STR(RNDIS_OID_802_11_BSSID_LIST); + OID_STR(OID_GEN_LINK_SPEED); + OID_STR(OID_GEN_RNDIS_CONFIG_PARAMETER); + + OID_STR(OID_GEN_XMIT_OK); + OID_STR(OID_GEN_RCV_OK); + OID_STR(OID_GEN_XMIT_ERROR); + OID_STR(OID_GEN_RCV_ERROR); + OID_STR(OID_GEN_RCV_NO_BUFFER); + + OID_STR(OID_802_3_CURRENT_ADDRESS); + OID_STR(OID_802_3_MULTICAST_LIST); + OID_STR(OID_802_3_MAXIMUM_LIST_SIZE); + + OID_STR(OID_802_11_BSSID); + OID_STR(OID_802_11_SSID); + OID_STR(OID_802_11_INFRASTRUCTURE_MODE); + OID_STR(OID_802_11_ADD_WEP); + OID_STR(OID_802_11_REMOVE_WEP); + OID_STR(OID_802_11_DISASSOCIATE); + OID_STR(OID_802_11_AUTHENTICATION_MODE); + OID_STR(OID_802_11_PRIVACY_FILTER); + OID_STR(OID_802_11_BSSID_LIST_SCAN); + OID_STR(OID_802_11_ENCRYPTION_STATUS); + OID_STR(OID_802_11_ADD_KEY); + OID_STR(OID_802_11_REMOVE_KEY); + OID_STR(OID_802_11_ASSOCIATION_INFORMATION); + OID_STR(OID_802_11_CAPABILITY); + OID_STR(OID_802_11_PMKID); + OID_STR(OID_802_11_NETWORK_TYPES_SUPPORTED); + OID_STR(OID_802_11_NETWORK_TYPE_IN_USE); + OID_STR(OID_802_11_TX_POWER_LEVEL); + OID_STR(OID_802_11_RSSI); + OID_STR(OID_802_11_RSSI_TRIGGER); + OID_STR(OID_802_11_FRAGMENTATION_THRESHOLD); + OID_STR(OID_802_11_RTS_THRESHOLD); + OID_STR(OID_802_11_SUPPORTED_RATES); + OID_STR(OID_802_11_CONFIGURATION); + OID_STR(OID_802_11_POWER_MODE); + OID_STR(OID_802_11_BSSID_LIST); #undef OID_STR } return "?"; } #else -static const char *oid_to_string(u32 oid) +static const char *oid_to_string(__le32 oid) { return "?"; } @@ -687,7 +736,7 @@ static const char *oid_to_string(u32 oid) static int rndis_error_status(__le32 rndis_status) { int ret = -EINVAL; - switch (le32_to_cpu(rndis_status)) { + switch (rndis_status) { case RNDIS_STATUS_SUCCESS: ret = 0; break; @@ -706,7 +755,7 @@ static int rndis_error_status(__le32 rndis_status) return ret; } -static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len) +static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev); union { @@ -733,9 +782,9 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len) mutex_lock(&priv->command_lock); memset(u.get, 0, sizeof *u.get); - u.get->msg_type = cpu_to_le32(RNDIS_MSG_QUERY); + u.get->msg_type = RNDIS_MSG_QUERY; u.get->msg_len = cpu_to_le32(sizeof *u.get); - u.get->oid = cpu_to_le32(oid); + u.get->oid = oid; priv->current_command_oid = oid; ret = rndis_command(dev, u.header, buflen); @@ -790,7 +839,7 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len) return ret; } -static int rndis_set_oid(struct usbnet *dev, u32 oid, const void *data, +static int rndis_set_oid(struct usbnet *dev, __le32 oid, const void *data, int len) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev); @@ -817,9 +866,9 @@ static int rndis_set_oid(struct usbnet *dev, u32 oid, const void *data, mutex_lock(&priv->command_lock); memset(u.set, 0, sizeof *u.set); - u.set->msg_type = cpu_to_le32(RNDIS_MSG_SET); + u.set->msg_type = RNDIS_MSG_SET; u.set->msg_len = cpu_to_le32(sizeof(*u.set) + len); - u.set->oid = cpu_to_le32(oid); + u.set->oid = oid; u.set->len = cpu_to_le32(len); u.set->offset = cpu_to_le32(sizeof(*u.set) - 8); u.set->handle = cpu_to_le32(0); @@ -859,7 +908,7 @@ static int rndis_reset(struct usbnet *usbdev) reset = (void *)priv->command_buffer; memset(reset, 0, sizeof(*reset)); - reset->msg_type = cpu_to_le32(RNDIS_MSG_RESET); + reset->msg_type = RNDIS_MSG_RESET; reset->msg_len = cpu_to_le32(sizeof(*reset)); priv->current_command_oid = 0; ret = rndis_command(usbdev, (void *)reset, CONTROL_BUFFER_SIZE); @@ -945,7 +994,7 @@ static int rndis_set_config_parameter(struct usbnet *dev, char *param, } #endif - ret = rndis_set_oid(dev, RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER, + ret = rndis_set_oid(dev, OID_GEN_RNDIS_CONFIG_PARAMETER, infobuf, info_len); if (ret != 0) netdev_dbg(dev->net, "setting rndis config parameter failed, %d\n", @@ -982,9 +1031,9 @@ static int rndis_start_bssid_list_scan(struct usbnet *usbdev) { __le32 tmp; - /* Note: RNDIS_OID_802_11_BSSID_LIST_SCAN clears internal BSS list. */ + /* Note: OID_802_11_BSSID_LIST_SCAN clears internal BSS list. */ tmp = cpu_to_le32(1); - return rndis_set_oid(usbdev, RNDIS_OID_802_11_BSSID_LIST_SCAN, &tmp, + return rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp, sizeof(tmp)); } @@ -993,8 +1042,7 @@ static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); int ret; - ret = rndis_set_oid(usbdev, RNDIS_OID_802_11_SSID, - ssid, sizeof(*ssid)); + ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid)); if (ret < 0) { netdev_warn(usbdev->net, "setting SSID failed (%08X)\n", ret); return ret; @@ -1011,8 +1059,7 @@ static int set_bssid(struct usbnet *usbdev, const u8 *bssid) { int ret; - ret = rndis_set_oid(usbdev, RNDIS_OID_802_11_BSSID, - bssid, ETH_ALEN); + ret = rndis_set_oid(usbdev, OID_802_11_BSSID, bssid, ETH_ALEN); if (ret < 0) { netdev_warn(usbdev->net, "setting BSSID[%pM] failed (%08X)\n", bssid, ret); @@ -1036,8 +1083,7 @@ static int get_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN]) int ret, len; len = ETH_ALEN; - ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_BSSID, - bssid, &len); + ret = rndis_query_oid(usbdev, OID_802_11_BSSID, bssid, &len); if (ret != 0) memset(bssid, 0, ETH_ALEN); @@ -1048,9 +1094,8 @@ static int get_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN]) static int get_association_info(struct usbnet *usbdev, struct ndis_80211_assoc_info *info, int len) { - return rndis_query_oid(usbdev, - RNDIS_OID_802_11_ASSOCIATION_INFORMATION, - info, &len); + return rndis_query_oid(usbdev, OID_802_11_ASSOCIATION_INFORMATION, + info, &len); } static bool is_associated(struct usbnet *usbdev) @@ -1074,9 +1119,7 @@ static int disassociate(struct usbnet *usbdev, bool reset_ssid) int i, ret = 0; if (priv->radio_on) { - ret = rndis_set_oid(usbdev, - RNDIS_OID_802_11_DISASSOCIATE, - NULL, 0); + ret = rndis_set_oid(usbdev, OID_802_11_DISASSOCIATE, NULL, 0); if (ret == 0) { priv->radio_on = false; netdev_dbg(usbdev->net, "%s(): radio_on = false\n", @@ -1138,9 +1181,8 @@ static int set_auth_mode(struct usbnet *usbdev, u32 wpa_version, return -ENOTSUPP; tmp = cpu_to_le32(auth_mode); - ret = rndis_set_oid(usbdev, - RNDIS_OID_802_11_AUTHENTICATION_MODE, - &tmp, sizeof(tmp)); + ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp, + sizeof(tmp)); if (ret != 0) { netdev_warn(usbdev->net, "setting auth mode failed (%08X)\n", ret); @@ -1166,9 +1208,8 @@ static int set_priv_filter(struct usbnet *usbdev) else tmp = cpu_to_le32(NDIS_80211_PRIV_ACCEPT_ALL); - return rndis_set_oid(usbdev, - RNDIS_OID_802_11_PRIVACY_FILTER, &tmp, - sizeof(tmp)); + return rndis_set_oid(usbdev, OID_802_11_PRIVACY_FILTER, &tmp, + sizeof(tmp)); } static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) @@ -1193,9 +1234,8 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) encr_mode = NDIS_80211_ENCR_DISABLED; tmp = cpu_to_le32(encr_mode); - ret = rndis_set_oid(usbdev, - RNDIS_OID_802_11_ENCRYPTION_STATUS, &tmp, - sizeof(tmp)); + ret = rndis_set_oid(usbdev, OID_802_11_ENCRYPTION_STATUS, &tmp, + sizeof(tmp)); if (ret != 0) { netdev_warn(usbdev->net, "setting encr mode failed (%08X)\n", ret); @@ -1215,9 +1255,8 @@ static int set_infra_mode(struct usbnet *usbdev, int mode) __func__, priv->infra_mode); tmp = cpu_to_le32(mode); - ret = rndis_set_oid(usbdev, - RNDIS_OID_802_11_INFRASTRUCTURE_MODE, - &tmp, sizeof(tmp)); + ret = rndis_set_oid(usbdev, OID_802_11_INFRASTRUCTURE_MODE, &tmp, + sizeof(tmp)); if (ret != 0) { netdev_warn(usbdev->net, "setting infra mode failed (%08X)\n", ret); @@ -1243,9 +1282,8 @@ static int set_rts_threshold(struct usbnet *usbdev, u32 rts_threshold) rts_threshold = 2347; tmp = cpu_to_le32(rts_threshold); - return rndis_set_oid(usbdev, - RNDIS_OID_802_11_RTS_THRESHOLD, - &tmp, sizeof(tmp)); + return rndis_set_oid(usbdev, OID_802_11_RTS_THRESHOLD, &tmp, + sizeof(tmp)); } static int set_frag_threshold(struct usbnet *usbdev, u32 frag_threshold) @@ -1258,9 +1296,8 @@ static int set_frag_threshold(struct usbnet *usbdev, u32 frag_threshold) frag_threshold = 2346; tmp = cpu_to_le32(frag_threshold); - return rndis_set_oid(usbdev, - RNDIS_OID_802_11_FRAGMENTATION_THRESHOLD, - &tmp, sizeof(tmp)); + return rndis_set_oid(usbdev, OID_802_11_FRAGMENTATION_THRESHOLD, &tmp, + sizeof(tmp)); } static void set_default_iw_params(struct usbnet *usbdev) @@ -1296,9 +1333,7 @@ static int set_channel(struct usbnet *usbdev, int channel) dsconfig = ieee80211_dsss_chan_to_freq(channel) * 1000; len = sizeof(config); - ret = rndis_query_oid(usbdev, - RNDIS_OID_802_11_CONFIGURATION, - &config, &len); + ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len); if (ret < 0) { netdev_dbg(usbdev->net, "%s(): querying configuration failed\n", __func__); @@ -1306,9 +1341,8 @@ static int set_channel(struct usbnet *usbdev, int channel) } config.ds_config = cpu_to_le32(dsconfig); - ret = rndis_set_oid(usbdev, - RNDIS_OID_802_11_CONFIGURATION, - &config, sizeof(config)); + ret = rndis_set_oid(usbdev, OID_802_11_CONFIGURATION, &config, + sizeof(config)); netdev_dbg(usbdev->net, "%s(): %d -> %d\n", __func__, channel, ret); @@ -1325,10 +1359,8 @@ static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev, /* Get channel and beacon interval */ len = sizeof(config); - ret = rndis_query_oid(usbdev, - RNDIS_OID_802_11_CONFIGURATION, - &config, &len); - netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_CONFIGURATION -> %d\n", + ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len); + netdev_dbg(usbdev->net, "%s(): OID_802_11_CONFIGURATION -> %d\n", __func__, ret); if (ret < 0) return NULL; @@ -1381,9 +1413,8 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len, ret); } - ret = rndis_set_oid(usbdev, - RNDIS_OID_802_11_ADD_WEP, &ndis_key, - sizeof(ndis_key)); + ret = rndis_set_oid(usbdev, OID_802_11_ADD_WEP, &ndis_key, + sizeof(ndis_key)); if (ret != 0) { netdev_warn(usbdev->net, "adding encryption key %d failed (%08X)\n", index + 1, ret); @@ -1473,10 +1504,9 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, get_bssid(usbdev, ndis_key.bssid); } - ret = rndis_set_oid(usbdev, - RNDIS_OID_802_11_ADD_KEY, &ndis_key, - le32_to_cpu(ndis_key.size)); - netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_ADD_KEY -> %08X\n", + ret = rndis_set_oid(usbdev, OID_802_11_ADD_KEY, &ndis_key, + le32_to_cpu(ndis_key.size)); + netdev_dbg(usbdev->net, "%s(): OID_802_11_ADD_KEY -> %08X\n", __func__, ret); if (ret != 0) return ret; @@ -1564,16 +1594,14 @@ static int remove_key(struct usbnet *usbdev, u8 index, const u8 *bssid) memset(remove_key.bssid, 0xff, sizeof(remove_key.bssid)); - ret = rndis_set_oid(usbdev, - RNDIS_OID_802_11_REMOVE_KEY, - &remove_key, sizeof(remove_key)); + ret = rndis_set_oid(usbdev, OID_802_11_REMOVE_KEY, &remove_key, + sizeof(remove_key)); if (ret != 0) return ret; } else { keyindex = cpu_to_le32(index); - ret = rndis_set_oid(usbdev, - RNDIS_OID_802_11_REMOVE_WEP, - &keyindex, sizeof(keyindex)); + ret = rndis_set_oid(usbdev, OID_802_11_REMOVE_WEP, &keyindex, + sizeof(keyindex)); if (ret != 0) { netdev_warn(usbdev->net, "removing encryption key %d failed (%08X)\n", @@ -1598,14 +1626,14 @@ static void set_multicast_list(struct usbnet *usbdev) char *mc_addrs = NULL; int mc_count; - basefilter = filter = cpu_to_le32(RNDIS_PACKET_TYPE_DIRECTED | - RNDIS_PACKET_TYPE_BROADCAST); + basefilter = filter = RNDIS_PACKET_TYPE_DIRECTED | + RNDIS_PACKET_TYPE_BROADCAST; if (usbdev->net->flags & IFF_PROMISC) { - filter |= cpu_to_le32(RNDIS_PACKET_TYPE_PROMISCUOUS | - RNDIS_PACKET_TYPE_ALL_LOCAL); + filter |= RNDIS_PACKET_TYPE_PROMISCUOUS | + RNDIS_PACKET_TYPE_ALL_LOCAL; } else if (usbdev->net->flags & IFF_ALLMULTI) { - filter |= cpu_to_le32(RNDIS_PACKET_TYPE_ALL_MULTICAST); + filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; } if (filter != basefilter) @@ -1618,7 +1646,7 @@ static void set_multicast_list(struct usbnet *usbdev) netif_addr_lock_bh(usbdev->net); mc_count = netdev_mc_count(usbdev->net); if (mc_count > priv->multicast_size) { - filter |= cpu_to_le32(RNDIS_PACKET_TYPE_ALL_MULTICAST); + filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; } else if (mc_count) { int i = 0; @@ -1641,28 +1669,27 @@ static void set_multicast_list(struct usbnet *usbdev) goto set_filter; if (mc_count) { - ret = rndis_set_oid(usbdev, - RNDIS_OID_802_3_MULTICAST_LIST, - mc_addrs, mc_count * ETH_ALEN); + ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, mc_addrs, + mc_count * ETH_ALEN); kfree(mc_addrs); if (ret == 0) - filter |= cpu_to_le32(RNDIS_PACKET_TYPE_MULTICAST); + filter |= RNDIS_PACKET_TYPE_MULTICAST; else - filter |= cpu_to_le32(RNDIS_PACKET_TYPE_ALL_MULTICAST); + filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; - netdev_dbg(usbdev->net, "RNDIS_OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d\n", + netdev_dbg(usbdev->net, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d\n", mc_count, priv->multicast_size, ret); } set_filter: - ret = rndis_set_oid(usbdev, RNDIS_OID_GEN_CURRENT_PACKET_FILTER, &filter, + ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter, sizeof(filter)); if (ret < 0) { netdev_warn(usbdev->net, "couldn't set packet filter: %08x\n", le32_to_cpu(filter)); } - netdev_dbg(usbdev->net, "RNDIS_OID_GEN_CURRENT_PACKET_FILTER(%08x) -> %d\n", + netdev_dbg(usbdev->net, "OID_GEN_CURRENT_PACKET_FILTER(%08x) -> %d\n", le32_to_cpu(filter), ret); } @@ -1721,10 +1748,9 @@ static struct ndis_80211_pmkid *get_device_pmkids(struct usbnet *usbdev) pmkids->length = cpu_to_le32(len); pmkids->bssid_info_count = cpu_to_le32(max_pmkids); - ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_PMKID, - pmkids, &len); + ret = rndis_query_oid(usbdev, OID_802_11_PMKID, pmkids, &len); if (ret < 0) { - netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_PMKID(%d, %d)" + netdev_dbg(usbdev->net, "%s(): OID_802_11_PMKID(%d, %d)" " -> %d\n", __func__, len, max_pmkids, ret); kfree(pmkids); @@ -1750,10 +1776,10 @@ static int set_device_pmkids(struct usbnet *usbdev, debug_print_pmkids(usbdev, pmkids, __func__); - ret = rndis_set_oid(usbdev, RNDIS_OID_802_11_PMKID, pmkids, - le32_to_cpu(pmkids->length)); + ret = rndis_set_oid(usbdev, OID_802_11_PMKID, pmkids, + le32_to_cpu(pmkids->length)); if (ret < 0) { - netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_PMKID(%d, %d) -> %d" + netdev_dbg(usbdev->net, "%s(): OID_802_11_PMKID(%d, %d) -> %d" "\n", __func__, len, num_pmkids, ret); } @@ -1775,8 +1801,8 @@ static struct ndis_80211_pmkid *remove_pmkid(struct usbnet *usbdev, count = max_pmkids; for (i = 0; i < count; i++) - if (ether_addr_equal(pmkids->bssid_info[i].bssid, - pmksa->bssid)) + if (!compare_ether_addr(pmkids->bssid_info[i].bssid, + pmksa->bssid)) break; /* pmkid not found */ @@ -1817,8 +1843,8 @@ static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev, /* update with new pmkid */ for (i = 0; i < count; i++) { - if (!ether_addr_equal(pmkids->bssid_info[i].bssid, - pmksa->bssid)) + if (compare_ether_addr(pmkids->bssid_info[i].bssid, + pmksa->bssid)) continue; memcpy(pmkids->bssid_info[i].pmkid, pmksa->pmkid, @@ -2087,8 +2113,7 @@ static int rndis_check_bssid_list(struct usbnet *usbdev, u8 *match_bssid, * resizing until it won't get any bigger. */ new_len = len; - ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_BSSID_LIST, - buf, &new_len); + ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &new_len); if (ret != 0 || new_len < sizeof(struct ndis_80211_bssid_list_ex)) goto out; @@ -2114,7 +2139,7 @@ static int rndis_check_bssid_list(struct usbnet *usbdev, u8 *match_bssid, while (check_bssid_list_item(bssid, bssid_len, buf, len)) { if (rndis_bss_info_update(usbdev, bssid) && match_bssid && matched) { - if (!ether_addr_equal(bssid->mac, match_bssid)) + if (compare_ether_addr(bssid->mac, match_bssid)) *matched = true; } @@ -2486,15 +2511,14 @@ static void rndis_fill_station_info(struct usbnet *usbdev, memset(sinfo, 0, sizeof(*sinfo)); len = sizeof(linkspeed); - ret = rndis_query_oid(usbdev, RNDIS_OID_GEN_LINK_SPEED, &linkspeed, &len); + ret = rndis_query_oid(usbdev, OID_GEN_LINK_SPEED, &linkspeed, &len); if (ret == 0) { sinfo->txrate.legacy = le32_to_cpu(linkspeed) / 1000; sinfo->filled |= STATION_INFO_TX_BITRATE; } len = sizeof(rssi); - ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_RSSI, - &rssi, &len); + ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len); if (ret == 0) { sinfo->signal = level_to_qual(le32_to_cpu(rssi)); sinfo->filled |= STATION_INFO_SIGNAL; @@ -2507,7 +2531,7 @@ static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev, struct rndis_wlan_private *priv = wiphy_priv(wiphy); struct usbnet *usbdev = priv->usbdev; - if (!ether_addr_equal(priv->bssid, mac)) + if (compare_ether_addr(priv->bssid, mac)) return -ENOENT; rndis_fill_station_info(usbdev, sinfo); @@ -2600,8 +2624,7 @@ static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) pmkid.length = cpu_to_le32(sizeof(pmkid)); pmkid.bssid_info_count = cpu_to_le32(0); - return rndis_set_oid(usbdev, RNDIS_OID_802_11_PMKID, - &pmkid, sizeof(pmkid)); + return rndis_set_oid(usbdev, OID_802_11_PMKID, &pmkid, sizeof(pmkid)); } static int rndis_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, @@ -2631,10 +2654,9 @@ static int rndis_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, priv->power_mode = power_mode; mode = cpu_to_le32(power_mode); - ret = rndis_set_oid(usbdev, RNDIS_OID_802_11_POWER_MODE, - &mode, sizeof(mode)); + ret = rndis_set_oid(usbdev, OID_802_11_POWER_MODE, &mode, sizeof(mode)); - netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_POWER_MODE -> %d\n", + netdev_dbg(usbdev->net, "%s(): OID_802_11_POWER_MODE -> %d\n", __func__, ret); return ret; @@ -2671,11 +2693,10 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, /* Get signal quality, in case of error use rssi=0 and ignore error. */ len = sizeof(rssi); rssi = 0; - ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_RSSI, - &rssi, &len); + ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len); signal = level_to_qual(le32_to_cpu(rssi)); - netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_RSSI -> %d, " + netdev_dbg(usbdev->net, "%s(): OID_802_11_RSSI -> %d, " "rssi:%d, qual: %d\n", __func__, ret, le32_to_cpu(rssi), level_to_qual(le32_to_cpu(rssi))); @@ -2699,9 +2720,8 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, /* Get SSID, in case of error, use zero length SSID and ignore error. */ len = sizeof(ssid); memset(&ssid, 0, sizeof(ssid)); - ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_SSID, - &ssid, &len); - netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_SSID -> %d, len: %d, ssid: " + ret = rndis_query_oid(usbdev, OID_802_11_SSID, &ssid, &len); + netdev_dbg(usbdev->net, "%s(): OID_802_11_SSID -> %d, len: %d, ssid: " "'%.32s'\n", __func__, ret, le32_to_cpu(ssid.length), ssid.essid); @@ -2823,7 +2843,7 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) * NDIS spec says: "If the device is associated, but the associated * BSSID is not in its BSSID scan list, then the driver must add an * entry for the BSSID at the end of the data that it returns in - * response to query of RNDIS_OID_802_11_BSSID_LIST." + * response to query of OID_802_11_BSSID_LIST." * * NOTE: Seems to be true for BCM4320b variant, but not BCM4320a. */ @@ -3075,15 +3095,15 @@ static void rndis_wlan_indication(struct usbnet *usbdev, void *ind, int buflen) struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); struct rndis_indicate *msg = ind; - switch (le32_to_cpu(msg->status)) { + switch (msg->status) { case RNDIS_STATUS_MEDIA_CONNECT: - if (priv->current_command_oid == RNDIS_OID_802_11_ADD_KEY) { - /* RNDIS_OID_802_11_ADD_KEY causes sometimes extra + if (priv->current_command_oid == OID_802_11_ADD_KEY) { + /* OID_802_11_ADD_KEY causes sometimes extra * "media connect" indications which confuses driver * and userspace to think that device is * roaming/reassociating when it isn't. */ - netdev_dbg(usbdev->net, "ignored RNDIS_OID_802_11_ADD_KEY triggered 'media connect'\n"); + netdev_dbg(usbdev->net, "ignored OID_802_11_ADD_KEY triggered 'media connect'\n"); return; } @@ -3128,9 +3148,8 @@ static int rndis_wlan_get_caps(struct usbnet *usbdev, struct wiphy *wiphy) /* determine supported modes */ len = sizeof(networks_supported); - retval = rndis_query_oid(usbdev, - RNDIS_OID_802_11_NETWORK_TYPES_SUPPORTED, - &networks_supported, &len); + retval = rndis_query_oid(usbdev, OID_802_11_NETWORK_TYPES_SUPPORTED, + &networks_supported, &len); if (retval >= 0) { n = le32_to_cpu(networks_supported.num_items); if (n > 8) @@ -3154,11 +3173,9 @@ static int rndis_wlan_get_caps(struct usbnet *usbdev, struct wiphy *wiphy) /* get device 802.11 capabilities, number of PMKIDs */ caps = (struct ndis_80211_capability *)caps_buf; len = sizeof(caps_buf); - retval = rndis_query_oid(usbdev, - RNDIS_OID_802_11_CAPABILITY, - caps, &len); + retval = rndis_query_oid(usbdev, OID_802_11_CAPABILITY, caps, &len); if (retval >= 0) { - netdev_dbg(usbdev->net, "RNDIS_OID_802_11_CAPABILITY -> len %d, " + netdev_dbg(usbdev->net, "OID_802_11_CAPABILITY -> len %d, " "ver %d, pmkids %d, auth-encr-pairs %d\n", le32_to_cpu(caps->length), le32_to_cpu(caps->version), @@ -3230,14 +3247,13 @@ static void rndis_device_poller(struct work_struct *work) } len = sizeof(rssi); - ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_RSSI, - &rssi, &len); + ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len); if (ret == 0) { priv->last_qual = level_to_qual(le32_to_cpu(rssi)); rndis_do_cqm(usbdev, le32_to_cpu(rssi)); } - netdev_dbg(usbdev->net, "dev-poller: RNDIS_OID_802_11_RSSI -> %d, rssi:%d, qual: %d\n", + netdev_dbg(usbdev->net, "dev-poller: OID_802_11_RSSI -> %d, rssi:%d, qual: %d\n", ret, le32_to_cpu(rssi), level_to_qual(le32_to_cpu(rssi))); /* Workaround transfer stalls on poor quality links. @@ -3259,18 +3275,15 @@ static void rndis_device_poller(struct work_struct *work) * working. */ tmp = cpu_to_le32(1); - rndis_set_oid(usbdev, - RNDIS_OID_802_11_BSSID_LIST_SCAN, - &tmp, sizeof(tmp)); + rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp, + sizeof(tmp)); len = CONTROL_BUFFER_SIZE; buf = kmalloc(len, GFP_KERNEL); if (!buf) goto end; - rndis_query_oid(usbdev, - RNDIS_OID_802_11_BSSID_LIST, - buf, &len); + rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len); kfree(buf); } @@ -3452,15 +3465,13 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) */ usbdev->net->netdev_ops = &rndis_wlan_netdev_ops; - tmp = cpu_to_le32(RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST); - retval = rndis_set_oid(usbdev, - RNDIS_OID_GEN_CURRENT_PACKET_FILTER, - &tmp, sizeof(tmp)); + tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST; + retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp, + sizeof(tmp)); len = sizeof(tmp); - retval = rndis_query_oid(usbdev, - RNDIS_OID_802_3_MAXIMUM_LIST_SIZE, - &tmp, &len); + retval = rndis_query_oid(usbdev, OID_802_3_MAXIMUM_LIST_SIZE, &tmp, + &len); priv->multicast_size = le32_to_cpu(tmp); if (retval < 0 || priv->multicast_size < 0) priv->multicast_size = 0; @@ -3590,7 +3601,7 @@ static int rndis_wlan_stop(struct usbnet *usbdev) /* Set current packet filter zero to block receiving data packets from device. */ filter = 0; - rndis_set_oid(usbdev, RNDIS_OID_GEN_CURRENT_PACKET_FILTER, &filter, + rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter, sizeof(filter)); return retval; diff --git a/trunk/drivers/net/wireless/rtlwifi/base.c b/trunk/drivers/net/wireless/rtlwifi/base.c index f4c852c6749b..e54488db0e10 100644 --- a/trunk/drivers/net/wireless/rtlwifi/base.c +++ b/trunk/drivers/net/wireless/rtlwifi/base.c @@ -1460,7 +1460,7 @@ void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len) return; /* and only beacons from the associated BSSID, please */ - if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid)) + if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid)) return; if (rtl_find_221_ie(hw, data, len)) diff --git a/trunk/drivers/net/wireless/rtlwifi/pci.c b/trunk/drivers/net/wireless/rtlwifi/pci.c index 2062ea1d7c80..f7868c0d79ed 100644 --- a/trunk/drivers/net/wireless/rtlwifi/pci.c +++ b/trunk/drivers/net/wireless/rtlwifi/pci.c @@ -1853,6 +1853,14 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, /*like read eeprom and so on */ rtlpriv->cfg->ops->read_eeprom_info(hw); + if (rtlpriv->cfg->ops->init_sw_vars(hw)) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n"); + err = -ENODEV; + goto fail3; + } + + rtlpriv->cfg->ops->init_sw_leds(hw); + /*aspm */ rtl_pci_init_aspm(hw); @@ -1871,14 +1879,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, goto fail3; } - if (rtlpriv->cfg->ops->init_sw_vars(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n"); - err = -ENODEV; - goto fail3; - } - - rtlpriv->cfg->ops->init_sw_leds(hw); - err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, diff --git a/trunk/drivers/net/wireless/rtlwifi/ps.c b/trunk/drivers/net/wireless/rtlwifi/ps.c index 5ae26647f340..5b9c3b5e8c92 100644 --- a/trunk/drivers/net/wireless/rtlwifi/ps.c +++ b/trunk/drivers/net/wireless/rtlwifi/ps.c @@ -480,7 +480,7 @@ void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len) return; /* and only beacons from the associated BSSID, please */ - if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid)) + if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid)) return; rtlpriv->psc.last_beacon = jiffies; diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 3af874e69595..37b13636a778 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -508,14 +508,14 @@ static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw, packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && - ether_addr_equal(mac->bssid, - (c_fc & IEEE80211_FCTL_TODS) ? hdr->addr1 : - (c_fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : - hdr->addr3) && + (!compare_ether_addr(mac->bssid, + (c_fc & IEEE80211_FCTL_TODS) ? + hdr->addr1 : (c_fc & IEEE80211_FCTL_FROMDS) ? + hdr->addr2 : hdr->addr3)) && (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv)); packet_toself = packet_matchbssid && - ether_addr_equal(praddr, rtlefuse->dev_addr); + (!compare_ether_addr(praddr, rtlefuse->dev_addr)); if (ieee80211_is_beacon(fc)) packet_beacon = true; diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 7e91c76582ec..025bdc2eba44 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -1099,14 +1099,14 @@ void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw, praddr = hdr->addr1; packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && - ether_addr_equal(mac->bssid, - (cpu_fc & IEEE80211_FCTL_TODS) ? hdr->addr1 : - (cpu_fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : - hdr->addr3) && + (!compare_ether_addr(mac->bssid, + (cpu_fc & IEEE80211_FCTL_TODS) ? + hdr->addr1 : (cpu_fc & IEEE80211_FCTL_FROMDS) ? + hdr->addr2 : hdr->addr3)) && (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv)); packet_toself = packet_matchbssid && - ether_addr_equal(praddr, rtlefuse->dev_addr); + (!compare_ether_addr(praddr, rtlefuse->dev_addr)); if (ieee80211_is_beacon(fc)) packet_beacon = true; _rtl92c_query_rxphystatus(hw, pstats, pdesc, p_drvinfo, diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index 1666ef7fd87b..a7f6126e2f86 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/trx.c @@ -466,13 +466,12 @@ static void _rtl92de_translate_rx_signal_stuff(struct ieee80211_hw *hw, type = WLAN_FC_GET_TYPE(fc); praddr = hdr->addr1; packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && - ether_addr_equal(mac->bssid, - (cfc & IEEE80211_FCTL_TODS) ? hdr->addr1 : - (cfc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : - hdr->addr3) && - (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv)); + (!compare_ether_addr(mac->bssid, (cfc & IEEE80211_FCTL_TODS) ? + hdr->addr1 : (cfc & IEEE80211_FCTL_FROMDS) ? + hdr->addr2 : hdr->addr3)) && (!pstats->hwerror) && + (!pstats->crc) && (!pstats->icv)); packet_toself = packet_matchbssid && - ether_addr_equal(praddr, rtlefuse->dev_addr); + (!compare_ether_addr(praddr, rtlefuse->dev_addr)); if (ieee80211_is_beacon(fc)) packet_beacon = true; _rtl92de_query_rxphystatus(hw, pstats, pdesc, p_drvinfo, diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index 812b5858f14a..2fd3d13b7ced 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -492,14 +492,13 @@ static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw, praddr = hdr->addr1; packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && - ether_addr_equal(mac->bssid, - (cfc & IEEE80211_FCTL_TODS) ? hdr->addr1 : - (cfc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : - hdr->addr3) && - (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv)); + (!compare_ether_addr(mac->bssid, (cfc & IEEE80211_FCTL_TODS) ? + hdr->addr1 : (cfc & IEEE80211_FCTL_FROMDS) ? + hdr->addr2 : hdr->addr3)) && (!pstats->hwerror) && + (!pstats->crc) && (!pstats->icv)); packet_toself = packet_matchbssid && - ether_addr_equal(praddr, rtlefuse->dev_addr); + (!compare_ether_addr(praddr, rtlefuse->dev_addr)); if (ieee80211_is_beacon(fc)) packet_beacon = true; diff --git a/trunk/drivers/net/wireless/rtlwifi/usb.c b/trunk/drivers/net/wireless/rtlwifi/usb.c index a6049d7d51b3..d04dbda13f5a 100644 --- a/trunk/drivers/net/wireless/rtlwifi/usb.c +++ b/trunk/drivers/net/wireless/rtlwifi/usb.c @@ -971,6 +971,11 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, rtlpriv->cfg->ops->read_chip_version(hw); /*like read eeprom and so on */ rtlpriv->cfg->ops->read_eeprom_info(hw); + if (rtlpriv->cfg->ops->init_sw_vars(hw)) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n"); + goto error_out; + } + rtlpriv->cfg->ops->init_sw_leds(hw); err = _rtl_usb_init(hw); if (err) goto error_out; @@ -982,11 +987,6 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, "Can't allocate sw for mac80211\n"); goto error_out; } - if (rtlpriv->cfg->ops->init_sw_vars(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n"); - goto error_out; - } - rtlpriv->cfg->ops->init_sw_leds(hw); return 0; error_out: diff --git a/trunk/drivers/of/base.c b/trunk/drivers/of/base.c index d9bfd49b1935..580644986945 100644 --- a/trunk/drivers/of/base.c +++ b/trunk/drivers/of/base.c @@ -1260,44 +1260,3 @@ int of_alias_get_id(struct device_node *np, const char *stem) return id; } EXPORT_SYMBOL_GPL(of_alias_get_id); - -const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, - u32 *pu) -{ - const void *curv = cur; - - if (!prop) - return NULL; - - if (!cur) { - curv = prop->value; - goto out_val; - } - - curv += sizeof(*cur); - if (curv >= prop->value + prop->length) - return NULL; - -out_val: - *pu = be32_to_cpup(curv); - return curv; -} -EXPORT_SYMBOL_GPL(of_prop_next_u32); - -const char *of_prop_next_string(struct property *prop, const char *cur) -{ - const void *curv = cur; - - if (!prop) - return NULL; - - if (!cur) - return prop->value; - - curv += strlen(cur) + 1; - if (curv >= prop->value + prop->length) - return NULL; - - return curv; -} -EXPORT_SYMBOL_GPL(of_prop_next_string); diff --git a/trunk/drivers/parisc/sba_iommu.c b/trunk/drivers/parisc/sba_iommu.c index 42cfcd9eb9aa..8644d5372e7f 100644 --- a/trunk/drivers/parisc/sba_iommu.c +++ b/trunk/drivers/parisc/sba_iommu.c @@ -44,7 +44,6 @@ #include #include /* for proc_mckinley_root */ #include /* for proc_runway_root */ -#include /* for PAGE0 */ #include /* for PDC_MODEL_* */ #include /* for is_pdc_pat() */ #include diff --git a/trunk/drivers/pci/Makefile b/trunk/drivers/pci/Makefile index 01c001f3b766..165274c064bc 100644 --- a/trunk/drivers/pci/Makefile +++ b/trunk/drivers/pci/Makefile @@ -2,7 +2,7 @@ # Makefile for the PCI bus specific drivers. # -obj-y += access.o bus.o probe.o host-bridge.o remove.o pci.o \ +obj-y += access.o bus.o probe.o remove.o pci.o \ pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \ irq.o vpd.o obj-$(CONFIG_PROC_FS) += proc.o diff --git a/trunk/drivers/pci/host-bridge.c b/trunk/drivers/pci/host-bridge.c deleted file mode 100644 index a68dc613a5be..000000000000 --- a/trunk/drivers/pci/host-bridge.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * host bridge related code - */ - -#include -#include -#include -#include - -#include "pci.h" - -static struct pci_bus *find_pci_root_bus(struct pci_dev *dev) -{ - struct pci_bus *bus; - - bus = dev->bus; - while (bus->parent) - bus = bus->parent; - - return bus; -} - -static struct pci_host_bridge *find_pci_host_bridge(struct pci_dev *dev) -{ - struct pci_bus *bus = find_pci_root_bus(dev); - - return to_pci_host_bridge(bus->bridge); -} - -void pci_set_host_bridge_release(struct pci_host_bridge *bridge, - void (*release_fn)(struct pci_host_bridge *), - void *release_data) -{ - bridge->release_fn = release_fn; - bridge->release_data = release_data; -} - -static bool resource_contains(struct resource *res1, struct resource *res2) -{ - return res1->start <= res2->start && res1->end >= res2->end; -} - -void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res) -{ - struct pci_host_bridge *bridge = find_pci_host_bridge(dev); - struct pci_host_bridge_window *window; - resource_size_t offset = 0; - - list_for_each_entry(window, &bridge->windows, list) { - if (resource_type(res) != resource_type(window->res)) - continue; - - if (resource_contains(window->res, res)) { - offset = window->offset; - break; - } - } - - region->start = res->start - offset; - region->end = res->end - offset; -} -EXPORT_SYMBOL(pcibios_resource_to_bus); - -static bool region_contains(struct pci_bus_region *region1, - struct pci_bus_region *region2) -{ - return region1->start <= region2->start && region1->end >= region2->end; -} - -void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region) -{ - struct pci_host_bridge *bridge = find_pci_host_bridge(dev); - struct pci_host_bridge_window *window; - resource_size_t offset = 0; - - list_for_each_entry(window, &bridge->windows, list) { - struct pci_bus_region bus_region; - - if (resource_type(res) != resource_type(window->res)) - continue; - - bus_region.start = window->res->start - window->offset; - bus_region.end = window->res->end - window->offset; - - if (region_contains(&bus_region, region)) { - offset = window->offset; - break; - } - } - - res->start = region->start + offset; - res->end = region->end + offset; -} -EXPORT_SYMBOL(pcibios_bus_to_resource); diff --git a/trunk/drivers/pci/pci-acpi.c b/trunk/drivers/pci/pci-acpi.c index 61e2fefeedab..0f150f271c2a 100644 --- a/trunk/drivers/pci/pci-acpi.c +++ b/trunk/drivers/pci/pci-acpi.c @@ -200,7 +200,7 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev) return PCI_D1; case ACPI_STATE_D2: return PCI_D2; - case ACPI_STATE_D3_HOT: + case ACPI_STATE_D3: return PCI_D3hot; case ACPI_STATE_D3_COLD: return PCI_D3cold; diff --git a/trunk/drivers/pci/pci-driver.c b/trunk/drivers/pci/pci-driver.c index bf0cee629b60..6b54b23b990b 100644 --- a/trunk/drivers/pci/pci-driver.c +++ b/trunk/drivers/pci/pci-driver.c @@ -420,12 +420,6 @@ static void pci_device_shutdown(struct device *dev) pci_msi_shutdown(pci_dev); pci_msix_shutdown(pci_dev); - /* - * Turn off Bus Master bit on the device to tell it to not - * continue to do DMA - */ - pci_disable_device(pci_dev); - /* * Devices may be enabled to wake up by runtime PM, but they need not * be supposed to wake up the system from its "power off" state (e.g. diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index 8f169002dc7e..111569ccab43 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include "pci.h" @@ -3165,12 +3164,18 @@ static int pci_parent_bus_reset(struct pci_dev *dev, int probe) return 0; } -static int __pci_dev_reset(struct pci_dev *dev, int probe) +static int pci_dev_reset(struct pci_dev *dev, int probe) { int rc; might_sleep(); + if (!probe) { + pci_cfg_access_lock(dev); + /* block PM suspend, driver probe, etc. */ + device_lock(&dev->dev); + } + rc = pci_dev_specific_reset(dev, probe); if (rc != -ENOTTY) goto done; @@ -3189,27 +3194,14 @@ static int __pci_dev_reset(struct pci_dev *dev, int probe) rc = pci_parent_bus_reset(dev, probe); done: - return rc; -} - -static int pci_dev_reset(struct pci_dev *dev, int probe) -{ - int rc; - - if (!probe) { - pci_cfg_access_lock(dev); - /* block PM suspend, driver probe, etc. */ - device_lock(&dev->dev); - } - - rc = __pci_dev_reset(dev, probe); - if (!probe) { device_unlock(&dev->dev); pci_cfg_access_unlock(dev); } + return rc; } + /** * __pci_reset_function - reset a PCI device function * @dev: PCI device to reset @@ -3254,7 +3246,7 @@ EXPORT_SYMBOL_GPL(__pci_reset_function); */ int __pci_reset_function_locked(struct pci_dev *dev) { - return __pci_dev_reset(dev, 0); + return pci_dev_reset(dev, 1); } EXPORT_SYMBOL_GPL(__pci_reset_function_locked); @@ -3901,8 +3893,6 @@ static int __init pci_setup(char *str) pcie_bus_config = PCIE_BUS_PERFORMANCE; } else if (!strncmp(str, "pcie_bus_peer2peer", 18)) { pcie_bus_config = PCIE_BUS_PEER2PEER; - } else if (!strncmp(str, "pcie_scan_all", 13)) { - pci_add_flags(PCI_SCAN_ALL_PCIE_DEVS); } else { printk(KERN_ERR "PCI: Unknown option `%s'\n", str); diff --git a/trunk/drivers/pci/pcie/portdrv_core.c b/trunk/drivers/pci/pcie/portdrv_core.c index 75915b30ad19..2f589a54f9bd 100644 --- a/trunk/drivers/pci/pcie/portdrv_core.c +++ b/trunk/drivers/pci/pcie/portdrv_core.c @@ -249,7 +249,7 @@ static int get_port_device_capability(struct pci_dev *dev) int services = 0, pos; u16 reg16; u32 reg32; - int cap_mask = 0; + int cap_mask; int err; if (pcie_ports_disabled) diff --git a/trunk/drivers/pci/probe.c b/trunk/drivers/pci/probe.c index 658ac977cb56..5e1ca3c58a7d 100644 --- a/trunk/drivers/pci/probe.c +++ b/trunk/drivers/pci/probe.c @@ -10,16 +10,18 @@ #include #include #include -#include #include "pci.h" #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ #define CARDBUS_RESERVE_BUSNR 3 +static LIST_HEAD(pci_host_bridges); + /* Ugh. Need to stop exporting this to modules. */ LIST_HEAD(pci_root_buses); EXPORT_SYMBOL(pci_root_buses); + static int find_anything(struct device *dev, void *data) { return 1; @@ -42,6 +44,82 @@ int no_pci_devices(void) } EXPORT_SYMBOL(no_pci_devices); +static struct pci_host_bridge *pci_host_bridge(struct pci_dev *dev) +{ + struct pci_bus *bus; + struct pci_host_bridge *bridge; + + bus = dev->bus; + while (bus->parent) + bus = bus->parent; + + list_for_each_entry(bridge, &pci_host_bridges, list) { + if (bridge->bus == bus) + return bridge; + } + + return NULL; +} + +static bool resource_contains(struct resource *res1, struct resource *res2) +{ + return res1->start <= res2->start && res1->end >= res2->end; +} + +void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, + struct resource *res) +{ + struct pci_host_bridge *bridge = pci_host_bridge(dev); + struct pci_host_bridge_window *window; + resource_size_t offset = 0; + + list_for_each_entry(window, &bridge->windows, list) { + if (resource_type(res) != resource_type(window->res)) + continue; + + if (resource_contains(window->res, res)) { + offset = window->offset; + break; + } + } + + region->start = res->start - offset; + region->end = res->end - offset; +} +EXPORT_SYMBOL(pcibios_resource_to_bus); + +static bool region_contains(struct pci_bus_region *region1, + struct pci_bus_region *region2) +{ + return region1->start <= region2->start && region1->end >= region2->end; +} + +void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, + struct pci_bus_region *region) +{ + struct pci_host_bridge *bridge = pci_host_bridge(dev); + struct pci_host_bridge_window *window; + struct pci_bus_region bus_region; + resource_size_t offset = 0; + + list_for_each_entry(window, &bridge->windows, list) { + if (resource_type(res) != resource_type(window->res)) + continue; + + bus_region.start = window->res->start - window->offset; + bus_region.end = window->res->end - window->offset; + + if (region_contains(&bus_region, region)) { + offset = window->offset; + break; + } + } + + res->start = region->start + offset; + res->end = region->end + offset; +} +EXPORT_SYMBOL(pcibios_bus_to_resource); + /* * PCI Bus Class */ @@ -423,19 +501,6 @@ static struct pci_bus * pci_alloc_bus(void) return b; } -static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b) -{ - struct pci_host_bridge *bridge; - - bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); - if (bridge) { - INIT_LIST_HEAD(&bridge->windows); - bridge->bus = b; - } - - return bridge; -} - static unsigned char pcix_bus_speed[] = { PCI_SPEED_UNKNOWN, /* 0 */ PCI_SPEED_66MHz_PCIX, /* 1 */ @@ -1136,14 +1201,7 @@ int pci_cfg_space_size(struct pci_dev *dev) static void pci_release_bus_bridge_dev(struct device *dev) { - struct pci_host_bridge *bridge = to_pci_host_bridge(dev); - - if (bridge->release_fn) - bridge->release_fn(bridge); - - pci_free_resource_list(&bridge->windows); - - kfree(bridge); + kfree(dev); } struct pci_dev *alloc_pci_dev(void) @@ -1337,13 +1395,10 @@ static unsigned no_next_fn(struct pci_dev *dev, unsigned fn) static int only_one_child(struct pci_bus *bus) { struct pci_dev *parent = bus->self; - if (!parent || !pci_is_pcie(parent)) return 0; - if (parent->pcie_type == PCI_EXP_TYPE_ROOT_PORT) - return 1; - if (parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM && - !pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS)) + if (parent->pcie_type == PCI_EXP_TYPE_ROOT_PORT || + parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) return 1; return 0; } @@ -1595,19 +1650,28 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, int error; struct pci_host_bridge *bridge; struct pci_bus *b, *b2; + struct device *dev; struct pci_host_bridge_window *window, *n; struct resource *res; resource_size_t offset; char bus_addr[64]; char *fmt; + bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); + if (!bridge) + return NULL; b = pci_alloc_bus(); if (!b) - return NULL; + goto err_bus; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + goto err_dev; b->sysdata = sysdata; b->ops = ops; + b2 = pci_find_bus(pci_domain_nr(b), bus); if (b2) { /* If we already got to this bus through a different bridge, ignore it */ @@ -1615,17 +1679,13 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, goto err_out; } - bridge = pci_alloc_host_bridge(b); - if (!bridge) - goto err_out; - - bridge->dev.parent = parent; - bridge->dev.release = pci_release_bus_bridge_dev; - dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus); - error = device_register(&bridge->dev); + dev->parent = parent; + dev->release = pci_release_bus_bridge_dev; + dev_set_name(dev, "pci%04x:%02x", pci_domain_nr(b), bus); + error = device_register(dev); if (error) - goto bridge_dev_reg_err; - b->bridge = get_device(&bridge->dev); + goto dev_reg_err; + b->bridge = get_device(dev); device_enable_async_suspend(b->bridge); pci_set_bus_of_node(b); @@ -1644,6 +1704,9 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, b->number = b->secondary = bus; + bridge->bus = b; + INIT_LIST_HEAD(&bridge->windows); + if (parent) dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev)); else @@ -1669,18 +1732,25 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, } down_write(&pci_bus_sem); + list_add_tail(&bridge->list, &pci_host_bridges); list_add_tail(&b->node, &pci_root_buses); up_write(&pci_bus_sem); return b; class_dev_reg_err: - put_device(&bridge->dev); - device_unregister(&bridge->dev); -bridge_dev_reg_err: - kfree(bridge); + device_unregister(dev); +dev_reg_err: + down_write(&pci_bus_sem); + list_del(&bridge->list); + list_del(&b->node); + up_write(&pci_bus_sem); err_out: + kfree(dev); +err_dev: kfree(b); +err_bus: + kfree(bridge); return NULL; } diff --git a/trunk/drivers/pci/quirks.c b/trunk/drivers/pci/quirks.c index 2a7521677541..953ec3f08470 100644 --- a/trunk/drivers/pci/quirks.c +++ b/trunk/drivers/pci/quirks.c @@ -3097,74 +3097,16 @@ static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe) return 0; } -#include "../gpu/drm/i915/i915_reg.h" -#define MSG_CTL 0x45010 -#define NSDE_PWR_STATE 0xd0100 -#define IGD_OPERATION_TIMEOUT 10000 /* set timeout 10 seconds */ - -static int reset_ivb_igd(struct pci_dev *dev, int probe) -{ - void __iomem *mmio_base; - unsigned long timeout; - u32 val; - - if (probe) - return 0; - - mmio_base = pci_iomap(dev, 0, 0); - if (!mmio_base) - return -ENOMEM; - - iowrite32(0x00000002, mmio_base + MSG_CTL); - - /* - * Clobbering SOUTH_CHICKEN2 register is fine only if the next - * driver loaded sets the right bits. However, this's a reset and - * the bits have been set by i915 previously, so we clobber - * SOUTH_CHICKEN2 register directly here. - */ - iowrite32(0x00000005, mmio_base + SOUTH_CHICKEN2); - - val = ioread32(mmio_base + PCH_PP_CONTROL) & 0xfffffffe; - iowrite32(val, mmio_base + PCH_PP_CONTROL); - - timeout = jiffies + msecs_to_jiffies(IGD_OPERATION_TIMEOUT); - do { - val = ioread32(mmio_base + PCH_PP_STATUS); - if ((val & 0xb0000000) == 0) - goto reset_complete; - msleep(10); - } while (time_before(jiffies, timeout)); - dev_warn(&dev->dev, "timeout during reset\n"); - -reset_complete: - iowrite32(0x00000002, mmio_base + NSDE_PWR_STATE); - - pci_iounmap(dev, mmio_base); - return 0; -} - #define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed -#define PCI_DEVICE_ID_INTEL_IVB_M_VGA 0x0156 -#define PCI_DEVICE_ID_INTEL_IVB_M2_VGA 0x0166 static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF, reset_intel_82599_sfp_virtfn }, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_M_VGA, - reset_ivb_igd }, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_M2_VGA, - reset_ivb_igd }, { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, reset_intel_generic_dev }, { 0 } }; -/* - * These device-specific reset methods are here rather than in a driver - * because when a host assigns a device to a guest VM, the host may need - * to reset the device but probably doesn't have a driver for it. - */ int pci_dev_specific_reset(struct pci_dev *dev, int probe) { const struct pci_dev_reset_methods *i; diff --git a/trunk/drivers/pinctrl/Kconfig b/trunk/drivers/pinctrl/Kconfig index 91c1f64102f0..abfb96408779 100644 --- a/trunk/drivers/pinctrl/Kconfig +++ b/trunk/drivers/pinctrl/Kconfig @@ -4,6 +4,7 @@ config PINCTRL bool + depends on EXPERIMENTAL if PINCTRL @@ -26,35 +27,6 @@ config DEBUG_PINCTRL help Say Y here to add some extra checks and diagnostics to PINCTRL calls. -config PINCTRL_IMX - bool - select PINMUX - select PINCONF - -config PINCTRL_IMX51 - bool "IMX51 pinctrl driver" - depends on OF - depends on SOC_IMX51 - select PINCTRL_IMX - help - Say Y here to enable the imx51 pinctrl driver - -config PINCTRL_IMX53 - bool "IMX53 pinctrl driver" - depends on OF - depends on SOC_IMX53 - select PINCTRL_IMX - help - Say Y here to enable the imx53 pinctrl driver - -config PINCTRL_IMX6Q - bool "IMX6Q pinctrl driver" - depends on OF - depends on SOC_IMX6Q - select PINCTRL_IMX - help - Say Y here to enable the imx6q pinctrl driver - config PINCTRL_PXA3xx bool select PINMUX @@ -65,21 +37,6 @@ config PINCTRL_MMP2 select PINCTRL_PXA3xx select PINCONF -config PINCTRL_MXS - bool - -config PINCTRL_IMX23 - bool - select PINMUX - select PINCONF - select PINCTRL_MXS - -config PINCTRL_IMX28 - bool - select PINMUX - select PINCONF - select PINCTRL_MXS - config PINCTRL_PXA168 bool "PXA168 pin controller driver" depends on ARCH_MMP diff --git a/trunk/drivers/pinctrl/Makefile b/trunk/drivers/pinctrl/Makefile index 515e32ff1597..6d4150b4eced 100644 --- a/trunk/drivers/pinctrl/Makefile +++ b/trunk/drivers/pinctrl/Makefile @@ -5,19 +5,9 @@ ccflags-$(CONFIG_DEBUG_PINCTRL) += -DDEBUG obj-$(CONFIG_PINCTRL) += core.o obj-$(CONFIG_PINMUX) += pinmux.o obj-$(CONFIG_PINCONF) += pinconf.o -ifeq ($(CONFIG_OF),y) -obj-$(CONFIG_PINCTRL) += devicetree.o -endif obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o -obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o -obj-$(CONFIG_PINCTRL_IMX51) += pinctrl-imx51.o -obj-$(CONFIG_PINCTRL_IMX53) += pinctrl-imx53.o -obj-$(CONFIG_PINCTRL_IMX6Q) += pinctrl-imx6q.o obj-$(CONFIG_PINCTRL_PXA3xx) += pinctrl-pxa3xx.o obj-$(CONFIG_PINCTRL_MMP2) += pinctrl-mmp2.o -obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o -obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o -obj-$(CONFIG_PINCTRL_IMX28) += pinctrl-imx28.o obj-$(CONFIG_PINCTRL_PXA168) += pinctrl-pxa168.o obj-$(CONFIG_PINCTRL_PXA910) += pinctrl-pxa910.o obj-$(CONFIG_PINCTRL_SIRF) += pinctrl-sirf.o diff --git a/trunk/drivers/pinctrl/core.c b/trunk/drivers/pinctrl/core.c index c3b331b74fa0..df6296c5f47b 100644 --- a/trunk/drivers/pinctrl/core.c +++ b/trunk/drivers/pinctrl/core.c @@ -23,11 +23,9 @@ #include #include #include -#include #include #include #include "core.h" -#include "devicetree.h" #include "pinmux.h" #include "pinconf.h" @@ -43,13 +41,11 @@ struct pinctrl_maps { unsigned num_maps; }; -static bool pinctrl_dummy_state; - /* Mutex taken by all entry points */ DEFINE_MUTEX(pinctrl_mutex); /* Global list of pin control devices (struct pinctrl_dev) */ -LIST_HEAD(pinctrldev_list); +static LIST_HEAD(pinctrldev_list); /* List of pin controller handles (struct pinctrl) */ static LIST_HEAD(pinctrl_list); @@ -63,19 +59,6 @@ static LIST_HEAD(pinctrl_maps); _i_ < _maps_node_->num_maps; \ i++, _map_ = &_maps_node_->maps[_i_]) -/** - * pinctrl_provide_dummies() - indicate if pinctrl provides dummy state support - * - * Usually this function is called by platforms without pinctrl driver support - * but run with some shared drivers using pinctrl APIs. - * After calling this function, the pinctrl core will return successfully - * with creating a dummy state for the driver to keep going smoothly. - */ -void pinctrl_provide_dummies(void) -{ - pinctrl_dummy_state = true; -} - const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev) { /* We're not allowed to register devices without name */ @@ -140,25 +123,6 @@ int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name) return -EINVAL; } -/** - * pin_get_name_from_id() - look up a pin name from a pin id - * @pctldev: the pin control device to lookup the pin on - * @name: the name of the pin to look up - */ -const char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned pin) -{ - const struct pin_desc *desc; - - desc = pin_desc_get(pctldev, pin); - if (desc == NULL) { - dev_err(pctldev->dev, "failed to get pin(%d) name\n", - pin); - return NULL; - } - - return desc->name; -} - /** * pin_is_valid() - check if pin exists on controller * @pctldev: the pin control device to check the pin on @@ -291,8 +255,7 @@ pinctrl_match_gpio_range(struct pinctrl_dev *pctldev, unsigned gpio) * * Find the pin controller handling a certain GPIO pin from the pinspace of * the GPIO subsystem, return the device and the matching GPIO range. Returns - * -EPROBE_DEFER if the GPIO range could not be found in any device since it - * may still have not been registered. + * negative if the GPIO range could not be found in any device. */ static int pinctrl_get_device_gpio_range(unsigned gpio, struct pinctrl_dev **outdev, @@ -312,7 +275,7 @@ static int pinctrl_get_device_gpio_range(unsigned gpio, } } - return -EPROBE_DEFER; + return -EINVAL; } /** @@ -355,10 +318,9 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pctldev, const char *pin_group) { const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; - unsigned ngroups = pctlops->get_groups_count(pctldev); unsigned group_selector = 0; - while (group_selector < ngroups) { + while (pctlops->list_groups(pctldev, group_selector) >= 0) { const char *gname = pctlops->get_group_name(pctldev, group_selector); if (!strcmp(gname, pin_group)) { @@ -398,7 +360,7 @@ int pinctrl_request_gpio(unsigned gpio) ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); if (ret) { mutex_unlock(&pinctrl_mutex); - return ret; + return -EINVAL; } /* Convert to the pin controllers number space */ @@ -554,14 +516,11 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map) setting->pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); if (setting->pctldev == NULL) { - dev_info(p->dev, "unknown pinctrl device %s in map entry, deferring probe", + dev_err(p->dev, "unknown pinctrl device %s in map entry", map->ctrl_dev_name); kfree(setting); - /* - * OK let us guess that the driver is not there yet, and - * let's defer obtaining this pinctrl handle to later... - */ - return -EPROBE_DEFER; + /* Eventually, this should trigger deferred probe */ + return -ENODEV; } switch (map->type) { @@ -620,13 +579,6 @@ static struct pinctrl *create_pinctrl(struct device *dev) } p->dev = dev; INIT_LIST_HEAD(&p->states); - INIT_LIST_HEAD(&p->dt_maps); - - ret = pinctrl_dt_to_map(p); - if (ret < 0) { - kfree(p); - return ERR_PTR(ret); - } devname = dev_name(dev); @@ -710,8 +662,6 @@ static void pinctrl_put_locked(struct pinctrl *p, bool inlist) kfree(state); } - pinctrl_dt_free_maps(p); - if (inlist) list_del(&p->node); kfree(p); @@ -735,18 +685,8 @@ static struct pinctrl_state *pinctrl_lookup_state_locked(struct pinctrl *p, struct pinctrl_state *state; state = find_state(p, name); - if (!state) { - if (pinctrl_dummy_state) { - /* create dummy state */ - dev_dbg(p->dev, "using pinctrl dummy state (%s)\n", - name); - state = create_state(p, name); - if (IS_ERR(state)) - return state; - } else { - return ERR_PTR(-ENODEV); - } - } + if (!state) + return ERR_PTR(-ENODEV); return state; } @@ -847,63 +787,15 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state) } EXPORT_SYMBOL_GPL(pinctrl_select_state); -static void devm_pinctrl_release(struct device *dev, void *res) -{ - pinctrl_put(*(struct pinctrl **)res); -} - -/** - * struct devm_pinctrl_get() - Resource managed pinctrl_get() - * @dev: the device to obtain the handle for - * - * If there is a need to explicitly destroy the returned struct pinctrl, - * devm_pinctrl_put() should be used, rather than plain pinctrl_put(). - */ -struct pinctrl *devm_pinctrl_get(struct device *dev) -{ - struct pinctrl **ptr, *p; - - ptr = devres_alloc(devm_pinctrl_release, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return ERR_PTR(-ENOMEM); - - p = pinctrl_get(dev); - if (!IS_ERR(p)) { - *ptr = p; - devres_add(dev, ptr); - } else { - devres_free(ptr); - } - - return p; -} -EXPORT_SYMBOL_GPL(devm_pinctrl_get); - -static int devm_pinctrl_match(struct device *dev, void *res, void *data) -{ - struct pinctrl **p = res; - - return *p == data; -} - /** - * devm_pinctrl_put() - Resource managed pinctrl_put() - * @p: the pinctrl handle to release - * - * Deallocate a struct pinctrl obtained via devm_pinctrl_get(). Normally - * this function will not need to be called and the resource management - * code will ensure that the resource is freed. + * pinctrl_register_mappings() - register a set of pin controller mappings + * @maps: the pincontrol mappings table to register. This should probably be + * marked with __initdata so it can be discarded after boot. This + * function will perform a shallow copy for the mapping entries. + * @num_maps: the number of maps in the mapping table */ -void devm_pinctrl_put(struct pinctrl *p) -{ - WARN_ON(devres_destroy(p->dev, devm_pinctrl_release, - devm_pinctrl_match, p)); - pinctrl_put(p); -} -EXPORT_SYMBOL_GPL(devm_pinctrl_put); - -int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, - bool dup, bool locked) +int pinctrl_register_mappings(struct pinctrl_map const *maps, + unsigned num_maps) { int i, ret; struct pinctrl_maps *maps_node; @@ -937,13 +829,13 @@ int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, case PIN_MAP_TYPE_MUX_GROUP: ret = pinmux_validate_map(&maps[i], i); if (ret < 0) - return ret; + return 0; break; case PIN_MAP_TYPE_CONFIGS_PIN: case PIN_MAP_TYPE_CONFIGS_GROUP: ret = pinconf_validate_map(&maps[i], i); if (ret < 0) - return ret; + return 0; break; default: pr_err("failed to register map %s (%d): invalid type given\n", @@ -959,52 +851,20 @@ int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, } maps_node->num_maps = num_maps; - if (dup) { - maps_node->maps = kmemdup(maps, sizeof(*maps) * num_maps, - GFP_KERNEL); - if (!maps_node->maps) { - pr_err("failed to duplicate mapping table\n"); - kfree(maps_node); - return -ENOMEM; - } - } else { - maps_node->maps = maps; + maps_node->maps = kmemdup(maps, sizeof(*maps) * num_maps, GFP_KERNEL); + if (!maps_node->maps) { + pr_err("failed to duplicate mapping table\n"); + kfree(maps_node); + return -ENOMEM; } - if (!locked) - mutex_lock(&pinctrl_mutex); + mutex_lock(&pinctrl_mutex); list_add_tail(&maps_node->node, &pinctrl_maps); - if (!locked) - mutex_unlock(&pinctrl_mutex); + mutex_unlock(&pinctrl_mutex); return 0; } -/** - * pinctrl_register_mappings() - register a set of pin controller mappings - * @maps: the pincontrol mappings table to register. This should probably be - * marked with __initdata so it can be discarded after boot. This - * function will perform a shallow copy for the mapping entries. - * @num_maps: the number of maps in the mapping table - */ -int pinctrl_register_mappings(struct pinctrl_map const *maps, - unsigned num_maps) -{ - return pinctrl_register_map(maps, num_maps, true, false); -} - -void pinctrl_unregister_map(struct pinctrl_map const *map) -{ - struct pinctrl_maps *maps_node; - - list_for_each_entry(maps_node, &pinctrl_maps, node) { - if (maps_node->maps == map) { - list_del(&maps_node->node); - return; - } - } -} - #ifdef CONFIG_DEBUG_FS static int pinctrl_pins_show(struct seq_file *s, void *what) @@ -1046,17 +906,15 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) { struct pinctrl_dev *pctldev = s->private; const struct pinctrl_ops *ops = pctldev->desc->pctlops; - unsigned ngroups, selector = 0; + unsigned selector = 0; - ngroups = ops->get_groups_count(pctldev); mutex_lock(&pinctrl_mutex); seq_puts(s, "registered pin groups:\n"); - while (selector < ngroups) { + while (ops->list_groups(pctldev, selector) >= 0) { const unsigned *pins; unsigned num_pins; const char *gname = ops->get_group_name(pctldev, selector); - const char *pname; int ret; int i; @@ -1066,14 +924,10 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) seq_printf(s, "%s [ERROR GETTING PINS]\n", gname); else { - seq_printf(s, "group: %s\n", gname); - for (i = 0; i < num_pins; i++) { - pname = pin_get_name(pctldev, pins[i]); - if (WARN_ON(!pname)) - return -EINVAL; - seq_printf(s, "pin %d (%s)\n", pins[i], pname); - } - seq_puts(s, "\n"); + seq_printf(s, "group: %s, pins = [ ", gname); + for (i = 0; i < num_pins; i++) + seq_printf(s, "%d ", pins[i]); + seq_puts(s, "]\n"); } selector++; } @@ -1372,14 +1226,11 @@ static int pinctrl_check_ops(struct pinctrl_dev *pctldev) const struct pinctrl_ops *ops = pctldev->desc->pctlops; if (!ops || - !ops->get_groups_count || + !ops->list_groups || !ops->get_group_name || !ops->get_group_pins) return -EINVAL; - if (ops->dt_node_to_map && !ops->dt_free_map) - return -EINVAL; - return 0; } @@ -1417,29 +1268,37 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, /* check core ops for sanity */ ret = pinctrl_check_ops(pctldev); if (ret) { - dev_err(dev, "pinctrl ops lacks necessary functions\n"); + pr_err("%s pinctrl ops lacks necessary functions\n", + pctldesc->name); goto out_err; } /* If we're implementing pinmuxing, check the ops for sanity */ if (pctldesc->pmxops) { ret = pinmux_check_ops(pctldev); - if (ret) + if (ret) { + pr_err("%s pinmux ops lacks necessary functions\n", + pctldesc->name); goto out_err; + } } /* If we're implementing pinconfig, check the ops for sanity */ if (pctldesc->confops) { ret = pinconf_check_ops(pctldev); - if (ret) + if (ret) { + pr_err("%s pin config ops lacks necessary functions\n", + pctldesc->name); goto out_err; + } } /* Register all the pins */ - dev_dbg(dev, "try to register %d pins ...\n", pctldesc->npins); + pr_debug("try to register %d pins on %s...\n", + pctldesc->npins, pctldesc->name); ret = pinctrl_register_pins(pctldev, pctldesc->pins, pctldesc->npins); if (ret) { - dev_err(dev, "error during pin registration\n"); + pr_err("error during pin registration\n"); pinctrl_free_pindescs(pctldev, pctldesc->pins, pctldesc->npins); goto out_err; @@ -1454,15 +1313,8 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, struct pinctrl_state *s = pinctrl_lookup_state_locked(pctldev->p, PINCTRL_STATE_DEFAULT); - if (IS_ERR(s)) { - dev_dbg(dev, "failed to lookup the default state\n"); - } else { - ret = pinctrl_select_state_locked(pctldev->p, s); - if (ret) { - dev_err(dev, - "failed to select default state\n"); - } - } + if (!IS_ERR(s)) + pinctrl_select_state_locked(pctldev->p, s); } mutex_unlock(&pinctrl_mutex); diff --git a/trunk/drivers/pinctrl/core.h b/trunk/drivers/pinctrl/core.h index 1f40ff68a8c4..17ecf651b123 100644 --- a/trunk/drivers/pinctrl/core.h +++ b/trunk/drivers/pinctrl/core.h @@ -52,15 +52,12 @@ struct pinctrl_dev { * @dev: the device using this pin control handle * @states: a list of states for this device * @state: the current state - * @dt_maps: the mapping table chunks dynamically parsed from device tree for - * this device, if any */ struct pinctrl { struct list_head node; struct device *dev; struct list_head states; struct pinctrl_state *state; - struct list_head dt_maps; }; /** @@ -103,8 +100,7 @@ struct pinctrl_setting_configs { * struct pinctrl_setting - an individual mux or config setting * @node: list node for struct pinctrl_settings's @settings field * @type: the type of setting - * @pctldev: pin control device handling to be programmed. Not used for - * PIN_MAP_TYPE_DUMMY_STATE. + * @pctldev: pin control device handling to be programmed * @data: Data specific to the setting type */ struct pinctrl_setting { @@ -148,7 +144,6 @@ struct pin_desc { struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *dev_name); int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name); -const char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned pin); int pinctrl_get_group_selector(struct pinctrl_dev *pctldev, const char *pin_group); @@ -158,9 +153,4 @@ static inline struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, return radix_tree_lookup(&pctldev->pin_desc_tree, pin); } -int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, - bool dup, bool locked); -void pinctrl_unregister_map(struct pinctrl_map const *map); - extern struct mutex pinctrl_mutex; -extern struct list_head pinctrldev_list; diff --git a/trunk/drivers/pinctrl/devicetree.c b/trunk/drivers/pinctrl/devicetree.c deleted file mode 100644 index fcb1de45473c..000000000000 --- a/trunk/drivers/pinctrl/devicetree.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Device tree integration for the pin control subsystem - * - * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include - -#include "core.h" -#include "devicetree.h" - -/** - * struct pinctrl_dt_map - mapping table chunk parsed from device tree - * @node: list node for struct pinctrl's @dt_maps field - * @pctldev: the pin controller that allocated this struct, and will free it - * @maps: the mapping table entries - */ -struct pinctrl_dt_map { - struct list_head node; - struct pinctrl_dev *pctldev; - struct pinctrl_map *map; - unsigned num_maps; -}; - -static void dt_free_map(struct pinctrl_dev *pctldev, - struct pinctrl_map *map, unsigned num_maps) -{ - if (pctldev) { - struct pinctrl_ops *ops = pctldev->desc->pctlops; - ops->dt_free_map(pctldev, map, num_maps); - } else { - /* There is no pctldev for PIN_MAP_TYPE_DUMMY_STATE */ - kfree(map); - } -} - -void pinctrl_dt_free_maps(struct pinctrl *p) -{ - struct pinctrl_dt_map *dt_map, *n1; - - list_for_each_entry_safe(dt_map, n1, &p->dt_maps, node) { - pinctrl_unregister_map(dt_map->map); - list_del(&dt_map->node); - dt_free_map(dt_map->pctldev, dt_map->map, - dt_map->num_maps); - kfree(dt_map); - } - - of_node_put(p->dev->of_node); -} - -static int dt_remember_or_free_map(struct pinctrl *p, const char *statename, - struct pinctrl_dev *pctldev, - struct pinctrl_map *map, unsigned num_maps) -{ - int i; - struct pinctrl_dt_map *dt_map; - - /* Initialize common mapping table entry fields */ - for (i = 0; i < num_maps; i++) { - map[i].dev_name = dev_name(p->dev); - map[i].name = statename; - if (pctldev) - map[i].ctrl_dev_name = dev_name(pctldev->dev); - } - - /* Remember the converted mapping table entries */ - dt_map = kzalloc(sizeof(*dt_map), GFP_KERNEL); - if (!dt_map) { - dev_err(p->dev, "failed to alloc struct pinctrl_dt_map\n"); - dt_free_map(pctldev, map, num_maps); - return -ENOMEM; - } - - dt_map->pctldev = pctldev; - dt_map->map = map; - dt_map->num_maps = num_maps; - list_add_tail(&dt_map->node, &p->dt_maps); - - return pinctrl_register_map(map, num_maps, false, true); -} - -static struct pinctrl_dev *find_pinctrl_by_of_node(struct device_node *np) -{ - struct pinctrl_dev *pctldev; - - list_for_each_entry(pctldev, &pinctrldev_list, node) - if (pctldev->dev->of_node == np) - return pctldev; - - return NULL; -} - -static int dt_to_map_one_config(struct pinctrl *p, const char *statename, - struct device_node *np_config) -{ - struct device_node *np_pctldev; - struct pinctrl_dev *pctldev; - struct pinctrl_ops *ops; - int ret; - struct pinctrl_map *map; - unsigned num_maps; - - /* Find the pin controller containing np_config */ - np_pctldev = of_node_get(np_config); - for (;;) { - np_pctldev = of_get_next_parent(np_pctldev); - if (!np_pctldev || of_node_is_root(np_pctldev)) { - dev_info(p->dev, "could not find pctldev for node %s, deferring probe\n", - np_config->full_name); - of_node_put(np_pctldev); - /* OK let's just assume this will appear later then */ - return -EPROBE_DEFER; - } - pctldev = find_pinctrl_by_of_node(np_pctldev); - if (pctldev) - break; - } - of_node_put(np_pctldev); - - /* - * Call pinctrl driver to parse device tree node, and - * generate mapping table entries - */ - ops = pctldev->desc->pctlops; - if (!ops->dt_node_to_map) { - dev_err(p->dev, "pctldev %s doesn't support DT\n", - dev_name(pctldev->dev)); - return -ENODEV; - } - ret = ops->dt_node_to_map(pctldev, np_config, &map, &num_maps); - if (ret < 0) - return ret; - - /* Stash the mapping table chunk away for later use */ - return dt_remember_or_free_map(p, statename, pctldev, map, num_maps); -} - -static int dt_remember_dummy_state(struct pinctrl *p, const char *statename) -{ - struct pinctrl_map *map; - - map = kzalloc(sizeof(*map), GFP_KERNEL); - if (!map) { - dev_err(p->dev, "failed to alloc struct pinctrl_map\n"); - return -ENOMEM; - } - - /* There is no pctldev for PIN_MAP_TYPE_DUMMY_STATE */ - map->type = PIN_MAP_TYPE_DUMMY_STATE; - - return dt_remember_or_free_map(p, statename, NULL, map, 1); -} - -int pinctrl_dt_to_map(struct pinctrl *p) -{ - struct device_node *np = p->dev->of_node; - int state, ret; - char *propname; - struct property *prop; - const char *statename; - const __be32 *list; - int size, config; - phandle phandle; - struct device_node *np_config; - - /* CONFIG_OF enabled, p->dev not instantiated from DT */ - if (!np) { - dev_dbg(p->dev, "no of_node; not parsing pinctrl DT\n"); - return 0; - } - - /* We may store pointers to property names within the node */ - of_node_get(np); - - /* For each defined state ID */ - for (state = 0; ; state++) { - /* Retrieve the pinctrl-* property */ - propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state); - prop = of_find_property(np, propname, &size); - kfree(propname); - if (!prop) - break; - list = prop->value; - size /= sizeof(*list); - - /* Determine whether pinctrl-names property names the state */ - ret = of_property_read_string_index(np, "pinctrl-names", - state, &statename); - /* - * If not, statename is just the integer state ID. But rather - * than dynamically allocate it and have to free it later, - * just point part way into the property name for the string. - */ - if (ret < 0) { - /* strlen("pinctrl-") == 8 */ - statename = prop->name + 8; - } - - /* For every referenced pin configuration node in it */ - for (config = 0; config < size; config++) { - phandle = be32_to_cpup(list++); - - /* Look up the pin configuration node */ - np_config = of_find_node_by_phandle(phandle); - if (!np_config) { - dev_err(p->dev, - "prop %s index %i invalid phandle\n", - prop->name, config); - ret = -EINVAL; - goto err; - } - - /* Parse the node */ - ret = dt_to_map_one_config(p, statename, np_config); - of_node_put(np_config); - if (ret < 0) - goto err; - } - - /* No entries in DT? Generate a dummy state table entry */ - if (!size) { - ret = dt_remember_dummy_state(p, statename); - if (ret < 0) - goto err; - } - } - - return 0; - -err: - pinctrl_dt_free_maps(p); - return ret; -} diff --git a/trunk/drivers/pinctrl/devicetree.h b/trunk/drivers/pinctrl/devicetree.h deleted file mode 100644 index 760bc4960f58..000000000000 --- a/trunk/drivers/pinctrl/devicetree.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Internal interface to pinctrl device tree integration - * - * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifdef CONFIG_OF - -void pinctrl_dt_free_maps(struct pinctrl *p); -int pinctrl_dt_to_map(struct pinctrl *p); - -#else - -static inline int pinctrl_dt_to_map(struct pinctrl *p) -{ - return 0; -} - -static inline void pinctrl_dt_free_maps(struct pinctrl *p) -{ -} - -#endif diff --git a/trunk/drivers/pinctrl/pinconf.c b/trunk/drivers/pinctrl/pinconf.c index 43f474cdc110..7321e8601294 100644 --- a/trunk/drivers/pinctrl/pinconf.c +++ b/trunk/drivers/pinctrl/pinconf.c @@ -28,17 +28,11 @@ int pinconf_check_ops(struct pinctrl_dev *pctldev) const struct pinconf_ops *ops = pctldev->desc->confops; /* We must be able to read out pin status */ - if (!ops->pin_config_get && !ops->pin_config_group_get) { - dev_err(pctldev->dev, - "pinconf must be able to read out pin status\n"); + if (!ops->pin_config_get && !ops->pin_config_group_get) return -EINVAL; - } /* We have to be able to config the pins in SOME way */ - if (!ops->pin_config_set && !ops->pin_config_group_set) { - dev_err(pctldev->dev, - "pinconf has to be able to set a pins config\n"); + if (!ops->pin_config_set && !ops->pin_config_group_set) return -EINVAL; - } return 0; } @@ -50,9 +44,9 @@ int pinconf_validate_map(struct pinctrl_map const *map, int i) return -EINVAL; } - if (!map->data.configs.num_configs || + if (map->data.configs.num_configs && !map->data.configs.configs) { - pr_err("failed to register map %s (%d): no configs given\n", + pr_err("failed to register map %s (%d): no configs ptr given\n", map->name, i); return -EINVAL; } @@ -385,16 +379,8 @@ int pinconf_apply_setting(struct pinctrl_setting const *setting) void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map) { - struct pinctrl_dev *pctldev; - const struct pinconf_ops *confops; int i; - pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); - if (pctldev) - confops = pctldev->desc->confops; - else - confops = NULL; - switch (map->type) { case PIN_MAP_TYPE_CONFIGS_PIN: seq_printf(s, "pin "); @@ -408,15 +394,8 @@ void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map) seq_printf(s, "%s\n", map->data.configs.group_or_pin); - for (i = 0; i < map->data.configs.num_configs; i++) { - seq_printf(s, "config "); - if (confops && confops->pin_config_config_dbg_show) - confops->pin_config_config_dbg_show(pctldev, s, - map->data.configs.configs[i]); - else - seq_printf(s, "%08lx", map->data.configs.configs[i]); - seq_printf(s, "\n"); - } + for (i = 0; i < map->data.configs.num_configs; i++) + seq_printf(s, "config %08lx\n", map->data.configs.configs[i]); } void pinconf_show_setting(struct seq_file *s, @@ -424,7 +403,6 @@ void pinconf_show_setting(struct seq_file *s, { struct pinctrl_dev *pctldev = setting->pctldev; const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; - const struct pinconf_ops *confops = pctldev->desc->confops; struct pin_desc *desc; int i; @@ -450,15 +428,8 @@ void pinconf_show_setting(struct seq_file *s, * FIXME: We should really get the pin controler to dump the config * values, so they can be decoded to something meaningful. */ - for (i = 0; i < setting->data.configs.num_configs; i++) { - seq_printf(s, " "); - if (confops && confops->pin_config_config_dbg_show) - confops->pin_config_config_dbg_show(pctldev, s, - setting->data.configs.configs[i]); - else - seq_printf(s, "%08lx", - setting->data.configs.configs[i]); - } + for (i = 0; i < setting->data.configs.num_configs; i++) + seq_printf(s, " %08lx", setting->data.configs.configs[i]); seq_printf(s, "\n"); } @@ -477,14 +448,10 @@ static void pinconf_dump_pin(struct pinctrl_dev *pctldev, static int pinconf_pins_show(struct seq_file *s, void *what) { struct pinctrl_dev *pctldev = s->private; - const struct pinconf_ops *ops = pctldev->desc->confops; unsigned i, pin; - if (!ops || !ops->pin_config_get) - return 0; - seq_puts(s, "Pin config settings per pin\n"); - seq_puts(s, "Format: pin (name): configs\n"); + seq_puts(s, "Format: pin (name): pinmux setting array\n"); mutex_lock(&pinctrl_mutex); @@ -528,18 +495,17 @@ static int pinconf_groups_show(struct seq_file *s, void *what) struct pinctrl_dev *pctldev = s->private; const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; const struct pinconf_ops *ops = pctldev->desc->confops; - unsigned ngroups = pctlops->get_groups_count(pctldev); unsigned selector = 0; if (!ops || !ops->pin_config_group_get) return 0; seq_puts(s, "Pin config settings per pin group\n"); - seq_puts(s, "Format: group (name): configs\n"); + seq_puts(s, "Format: group (name): pinmux setting array\n"); mutex_lock(&pinctrl_mutex); - while (selector < ngroups) { + while (pctlops->list_groups(pctldev, selector) >= 0) { const char *gname = pctlops->get_group_name(pctldev, selector); seq_printf(s, "%u (%s):", selector, gname); diff --git a/trunk/drivers/pinctrl/pinconf.h b/trunk/drivers/pinctrl/pinconf.h index e3ed8cb072a5..54510de5e8c6 100644 --- a/trunk/drivers/pinctrl/pinconf.h +++ b/trunk/drivers/pinctrl/pinconf.h @@ -19,6 +19,11 @@ int pinconf_map_to_setting(struct pinctrl_map const *map, struct pinctrl_setting *setting); void pinconf_free_setting(struct pinctrl_setting const *setting); int pinconf_apply_setting(struct pinctrl_setting const *setting); +void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map); +void pinconf_show_setting(struct seq_file *s, + struct pinctrl_setting const *setting); +void pinconf_init_device_debugfs(struct dentry *devroot, + struct pinctrl_dev *pctldev); /* * You will only be interested in these if you're using PINCONF @@ -56,18 +61,6 @@ static inline int pinconf_apply_setting(struct pinctrl_setting const *setting) return 0; } -#endif - -#if defined(CONFIG_PINCONF) && defined(CONFIG_DEBUG_FS) - -void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map); -void pinconf_show_setting(struct seq_file *s, - struct pinctrl_setting const *setting); -void pinconf_init_device_debugfs(struct dentry *devroot, - struct pinctrl_dev *pctldev); - -#else - static inline void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map) { diff --git a/trunk/drivers/pinctrl/pinctrl-coh901.c b/trunk/drivers/pinctrl/pinctrl-coh901.c index 55697a5d7482..0797eba3e33a 100644 --- a/trunk/drivers/pinctrl/pinctrl-coh901.c +++ b/trunk/drivers/pinctrl/pinctrl-coh901.c @@ -174,7 +174,7 @@ struct u300_gpio_confdata { /* Initial configuration */ -static const struct __initconst u300_gpio_confdata +static const struct __initdata u300_gpio_confdata bs335_gpio_config[BS335_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = { /* Port 0, pins 0-7 */ { @@ -255,7 +255,7 @@ bs335_gpio_config[BS335_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = { } }; -static const struct __initconst u300_gpio_confdata +static const struct __initdata u300_gpio_confdata bs365_gpio_config[BS365_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = { /* Port 0, pins 0-7 */ { diff --git a/trunk/drivers/pinctrl/pinctrl-imx.c b/trunk/drivers/pinctrl/pinctrl-imx.c deleted file mode 100644 index f6e7c670906c..000000000000 --- a/trunk/drivers/pinctrl/pinctrl-imx.c +++ /dev/null @@ -1,620 +0,0 @@ -/* - * Core driver for the imx pin controller - * - * Copyright (C) 2012 Freescale Semiconductor, Inc. - * Copyright (C) 2012 Linaro Ltd. - * - * Author: Dong Aisheng - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "core.h" -#include "pinctrl-imx.h" - -#define IMX_PMX_DUMP(info, p, m, c, n) \ -{ \ - int i, j; \ - printk("Format: Pin Mux Config\n"); \ - for (i = 0; i < n; i++) { \ - j = p[i]; \ - printk("%s %d 0x%lx\n", \ - info->pins[j].name, \ - m[i], c[i]); \ - } \ -} - -/* The bits in CONFIG cell defined in binding doc*/ -#define IMX_NO_PAD_CTL 0x80000000 /* no pin config need */ -#define IMX_PAD_SION 0x40000000 /* set SION */ - -/** - * @dev: a pointer back to containing device - * @base: the offset to the controller in virtual memory - */ -struct imx_pinctrl { - struct device *dev; - struct pinctrl_dev *pctl; - void __iomem *base; - const struct imx_pinctrl_soc_info *info; -}; - -static const struct imx_pin_reg *imx_find_pin_reg( - const struct imx_pinctrl_soc_info *info, - unsigned pin, bool is_mux, unsigned mux) -{ - const struct imx_pin_reg *pin_reg = NULL; - int i; - - for (i = 0; i < info->npin_regs; i++) { - pin_reg = &info->pin_regs[i]; - if (pin_reg->pid != pin) - continue; - if (!is_mux) - break; - else if (pin_reg->mux_mode == (mux & IMX_MUX_MASK)) - break; - } - - if (!pin_reg) { - dev_err(info->dev, "Pin(%s): unable to find pin reg map\n", - info->pins[pin].name); - return NULL; - } - - return pin_reg; -} - -static const inline struct imx_pin_group *imx_pinctrl_find_group_by_name( - const struct imx_pinctrl_soc_info *info, - const char *name) -{ - const struct imx_pin_group *grp = NULL; - int i; - - for (i = 0; i < info->ngroups; i++) { - if (!strcmp(info->groups[i].name, name)) { - grp = &info->groups[i]; - break; - } - } - - return grp; -} - -static int imx_get_groups_count(struct pinctrl_dev *pctldev) -{ - struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); - const struct imx_pinctrl_soc_info *info = ipctl->info; - - return info->ngroups; -} - -static const char *imx_get_group_name(struct pinctrl_dev *pctldev, - unsigned selector) -{ - struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); - const struct imx_pinctrl_soc_info *info = ipctl->info; - - return info->groups[selector].name; -} - -static int imx_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, - const unsigned **pins, - unsigned *npins) -{ - struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); - const struct imx_pinctrl_soc_info *info = ipctl->info; - - if (selector >= info->ngroups) - return -EINVAL; - - *pins = info->groups[selector].pins; - *npins = info->groups[selector].npins; - - return 0; -} - -static void imx_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, - unsigned offset) -{ - seq_printf(s, "%s", dev_name(pctldev->dev)); -} - -static int imx_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *np, - struct pinctrl_map **map, unsigned *num_maps) -{ - struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); - const struct imx_pinctrl_soc_info *info = ipctl->info; - const struct imx_pin_group *grp; - struct pinctrl_map *new_map; - struct device_node *parent; - int map_num = 1; - int i; - - /* - * first find the group of this node and check if we need create - * config maps for pins - */ - grp = imx_pinctrl_find_group_by_name(info, np->name); - if (!grp) { - dev_err(info->dev, "unable to find group for node %s\n", - np->name); - return -EINVAL; - } - - for (i = 0; i < grp->npins; i++) { - if (!(grp->configs[i] & IMX_NO_PAD_CTL)) - map_num++; - } - - new_map = kmalloc(sizeof(struct pinctrl_map) * map_num, GFP_KERNEL); - if (!new_map) - return -ENOMEM; - - *map = new_map; - *num_maps = map_num; - - /* create mux map */ - parent = of_get_parent(np); - if (!parent) - return -EINVAL; - new_map[0].type = PIN_MAP_TYPE_MUX_GROUP; - new_map[0].data.mux.function = parent->name; - new_map[0].data.mux.group = np->name; - of_node_put(parent); - - /* create config map */ - new_map++; - for (i = 0; i < grp->npins; i++) { - if (!(grp->configs[i] & IMX_NO_PAD_CTL)) { - new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN; - new_map[i].data.configs.group_or_pin = - pin_get_name(pctldev, grp->pins[i]); - new_map[i].data.configs.configs = &grp->configs[i]; - new_map[i].data.configs.num_configs = 1; - } - } - - dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n", - new_map->data.mux.function, new_map->data.mux.group, map_num); - - return 0; -} - -static void imx_dt_free_map(struct pinctrl_dev *pctldev, - struct pinctrl_map *map, unsigned num_maps) -{ - int i; - - for (i = 0; i < num_maps; i++) - kfree(map); -} - -static struct pinctrl_ops imx_pctrl_ops = { - .get_groups_count = imx_get_groups_count, - .get_group_name = imx_get_group_name, - .get_group_pins = imx_get_group_pins, - .pin_dbg_show = imx_pin_dbg_show, - .dt_node_to_map = imx_dt_node_to_map, - .dt_free_map = imx_dt_free_map, - -}; - -static int imx_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, - unsigned group) -{ - struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); - const struct imx_pinctrl_soc_info *info = ipctl->info; - const struct imx_pin_reg *pin_reg; - const unsigned *pins, *mux; - unsigned int npins, pin_id; - int i; - - /* - * Configure the mux mode for each pin in the group for a specific - * function. - */ - pins = info->groups[group].pins; - npins = info->groups[group].npins; - mux = info->groups[group].mux_mode; - - WARN_ON(!pins || !npins || !mux); - - dev_dbg(ipctl->dev, "enable function %s group %s\n", - info->functions[selector].name, info->groups[group].name); - - for (i = 0; i < npins; i++) { - pin_id = pins[i]; - - pin_reg = imx_find_pin_reg(info, pin_id, 1, mux[i]); - if (!pin_reg) - return -EINVAL; - - if (!pin_reg->mux_reg) { - dev_err(ipctl->dev, "Pin(%s) does not support mux function\n", - info->pins[pin_id].name); - return -EINVAL; - } - - writel(mux[i], ipctl->base + pin_reg->mux_reg); - dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n", - pin_reg->mux_reg, mux[i]); - - /* some pins also need select input setting, set it if found */ - if (pin_reg->input_reg) { - writel(pin_reg->input_val, ipctl->base + pin_reg->input_reg); - dev_dbg(ipctl->dev, - "==>select_input: offset 0x%x val 0x%x\n", - pin_reg->input_reg, pin_reg->input_val); - } - } - - return 0; -} - -static int imx_pmx_get_funcs_count(struct pinctrl_dev *pctldev) -{ - struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); - const struct imx_pinctrl_soc_info *info = ipctl->info; - - return info->nfunctions; -} - -static const char *imx_pmx_get_func_name(struct pinctrl_dev *pctldev, - unsigned selector) -{ - struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); - const struct imx_pinctrl_soc_info *info = ipctl->info; - - return info->functions[selector].name; -} - -static int imx_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector, - const char * const **groups, - unsigned * const num_groups) -{ - struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); - const struct imx_pinctrl_soc_info *info = ipctl->info; - - *groups = info->functions[selector].groups; - *num_groups = info->functions[selector].num_groups; - - return 0; -} - -static struct pinmux_ops imx_pmx_ops = { - .get_functions_count = imx_pmx_get_funcs_count, - .get_function_name = imx_pmx_get_func_name, - .get_function_groups = imx_pmx_get_groups, - .enable = imx_pmx_enable, -}; - -static int imx_pinconf_get(struct pinctrl_dev *pctldev, - unsigned pin_id, unsigned long *config) -{ - struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); - const struct imx_pinctrl_soc_info *info = ipctl->info; - const struct imx_pin_reg *pin_reg; - - pin_reg = imx_find_pin_reg(info, pin_id, 0, 0); - if (!pin_reg) - return -EINVAL; - - if (!pin_reg->conf_reg) { - dev_err(info->dev, "Pin(%s) does not support config function\n", - info->pins[pin_id].name); - return -EINVAL; - } - - *config = readl(ipctl->base + pin_reg->conf_reg); - - return 0; -} - -static int imx_pinconf_set(struct pinctrl_dev *pctldev, - unsigned pin_id, unsigned long config) -{ - struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); - const struct imx_pinctrl_soc_info *info = ipctl->info; - const struct imx_pin_reg *pin_reg; - - pin_reg = imx_find_pin_reg(info, pin_id, 0, 0); - if (!pin_reg) - return -EINVAL; - - if (!pin_reg->conf_reg) { - dev_err(info->dev, "Pin(%s) does not support config function\n", - info->pins[pin_id].name); - return -EINVAL; - } - - dev_dbg(ipctl->dev, "pinconf set pin %s\n", - info->pins[pin_id].name); - - writel(config, ipctl->base + pin_reg->conf_reg); - dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n", - pin_reg->conf_reg, config); - - return 0; -} - -static void imx_pinconf_dbg_show(struct pinctrl_dev *pctldev, - struct seq_file *s, unsigned pin_id) -{ - struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); - const struct imx_pinctrl_soc_info *info = ipctl->info; - const struct imx_pin_reg *pin_reg; - unsigned long config; - - pin_reg = imx_find_pin_reg(info, pin_id, 0, 0); - if (!pin_reg || !pin_reg->conf_reg) { - seq_printf(s, "N/A"); - return; - } - - config = readl(ipctl->base + pin_reg->conf_reg); - seq_printf(s, "0x%lx", config); -} - -static void imx_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, - struct seq_file *s, unsigned group) -{ - struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); - const struct imx_pinctrl_soc_info *info = ipctl->info; - struct imx_pin_group *grp; - unsigned long config; - const char *name; - int i, ret; - - if (group > info->ngroups) - return; - - seq_printf(s, "\n"); - grp = &info->groups[group]; - for (i = 0; i < grp->npins; i++) { - name = pin_get_name(pctldev, grp->pins[i]); - ret = imx_pinconf_get(pctldev, grp->pins[i], &config); - if (ret) - return; - seq_printf(s, "%s: 0x%lx", name, config); - } -} - -struct pinconf_ops imx_pinconf_ops = { - .pin_config_get = imx_pinconf_get, - .pin_config_set = imx_pinconf_set, - .pin_config_dbg_show = imx_pinconf_dbg_show, - .pin_config_group_dbg_show = imx_pinconf_group_dbg_show, -}; - -static struct pinctrl_desc imx_pinctrl_desc = { - .pctlops = &imx_pctrl_ops, - .pmxops = &imx_pmx_ops, - .confops = &imx_pinconf_ops, - .owner = THIS_MODULE, -}; - -/* decode pin id and mux from pin function id got from device tree*/ -static int imx_pinctrl_get_pin_id_and_mux(const struct imx_pinctrl_soc_info *info, - unsigned int pin_func_id, unsigned int *pin_id, - unsigned int *mux) -{ - if (pin_func_id > info->npin_regs) - return -EINVAL; - - *pin_id = info->pin_regs[pin_func_id].pid; - *mux = info->pin_regs[pin_func_id].mux_mode; - - return 0; -} - -static int __devinit imx_pinctrl_parse_groups(struct device_node *np, - struct imx_pin_group *grp, - struct imx_pinctrl_soc_info *info, - u32 index) -{ - unsigned int pin_func_id; - int ret, size; - const const __be32 *list; - int i, j; - u32 config; - - dev_dbg(info->dev, "group(%d): %s\n", index, np->name); - - /* Initialise group */ - grp->name = np->name; - - /* - * the binding format is fsl,pins = , - * do sanity check and calculate pins number - */ - list = of_get_property(np, "fsl,pins", &size); - /* we do not check return since it's safe node passed down */ - size /= sizeof(*list); - if (!size || size % 2) { - dev_err(info->dev, "wrong pins number or pins and configs should be pairs\n"); - return -EINVAL; - } - - grp->npins = size / 2; - grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int), - GFP_KERNEL); - grp->mux_mode = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int), - GFP_KERNEL); - grp->configs = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned long), - GFP_KERNEL); - for (i = 0, j = 0; i < size; i += 2, j++) { - pin_func_id = be32_to_cpu(*list++); - ret = imx_pinctrl_get_pin_id_and_mux(info, pin_func_id, - &grp->pins[j], &grp->mux_mode[j]); - if (ret) { - dev_err(info->dev, "get invalid pin function id\n"); - return -EINVAL; - } - /* SION bit is in mux register */ - config = be32_to_cpu(*list++); - if (config & IMX_PAD_SION) - grp->mux_mode[j] |= IOMUXC_CONFIG_SION; - grp->configs[j] = config & ~IMX_PAD_SION; - } - -#ifdef DEBUG - IMX_PMX_DUMP(info, grp->pins, grp->mux_mode, grp->configs, grp->npins); -#endif - return 0; -} - -static int __devinit imx_pinctrl_parse_functions(struct device_node *np, - struct imx_pinctrl_soc_info *info, u32 index) -{ - struct device_node *child; - struct imx_pmx_func *func; - struct imx_pin_group *grp; - int ret; - static u32 grp_index; - u32 i = 0; - - dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name); - - func = &info->functions[index]; - - /* Initialise function */ - func->name = np->name; - func->num_groups = of_get_child_count(np); - if (func->num_groups <= 0) { - dev_err(info->dev, "no groups defined\n"); - return -EINVAL; - } - func->groups = devm_kzalloc(info->dev, - func->num_groups * sizeof(char *), GFP_KERNEL); - - for_each_child_of_node(np, child) { - func->groups[i] = child->name; - grp = &info->groups[grp_index++]; - ret = imx_pinctrl_parse_groups(child, grp, info, i++); - if (ret) - return ret; - } - - return 0; -} - -static int __devinit imx_pinctrl_probe_dt(struct platform_device *pdev, - struct imx_pinctrl_soc_info *info) -{ - struct device_node *np = pdev->dev.of_node; - struct device_node *child; - int ret; - u32 nfuncs = 0; - u32 i = 0; - - if (!np) - return -ENODEV; - - nfuncs = of_get_child_count(np); - if (nfuncs <= 0) { - dev_err(&pdev->dev, "no functions defined\n"); - return -EINVAL; - } - - info->nfunctions = nfuncs; - info->functions = devm_kzalloc(&pdev->dev, nfuncs * sizeof(struct imx_pmx_func), - GFP_KERNEL); - if (!info->functions) - return -ENOMEM; - - info->ngroups = 0; - for_each_child_of_node(np, child) - info->ngroups += of_get_child_count(child); - info->groups = devm_kzalloc(&pdev->dev, info->ngroups * sizeof(struct imx_pin_group), - GFP_KERNEL); - if (!info->groups) - return -ENOMEM; - - for_each_child_of_node(np, child) { - ret = imx_pinctrl_parse_functions(child, info, i++); - if (ret) { - dev_err(&pdev->dev, "failed to parse function\n"); - return ret; - } - } - - return 0; -} - -int __devinit imx_pinctrl_probe(struct platform_device *pdev, - struct imx_pinctrl_soc_info *info) -{ - struct imx_pinctrl *ipctl; - struct resource *res; - int ret; - - if (!info || !info->pins || !info->npins - || !info->pin_regs || !info->npin_regs) { - dev_err(&pdev->dev, "wrong pinctrl info\n"); - return -EINVAL; - } - info->dev = &pdev->dev; - - /* Create state holders etc for this driver */ - ipctl = devm_kzalloc(&pdev->dev, sizeof(*ipctl), GFP_KERNEL); - if (!ipctl) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENOENT; - - ipctl->base = devm_request_and_ioremap(&pdev->dev, res); - if (!ipctl->base) - return -EBUSY; - - imx_pinctrl_desc.name = dev_name(&pdev->dev); - imx_pinctrl_desc.pins = info->pins; - imx_pinctrl_desc.npins = info->npins; - - ret = imx_pinctrl_probe_dt(pdev, info); - if (ret) { - dev_err(&pdev->dev, "fail to probe dt properties\n"); - return ret; - } - - ipctl->info = info; - ipctl->dev = info->dev; - platform_set_drvdata(pdev, ipctl); - ipctl->pctl = pinctrl_register(&imx_pinctrl_desc, &pdev->dev, ipctl); - if (!ipctl->pctl) { - dev_err(&pdev->dev, "could not register IMX pinctrl driver\n"); - return -EINVAL; - } - - dev_info(&pdev->dev, "initialized IMX pinctrl driver\n"); - - return 0; -} - -int __devexit imx_pinctrl_remove(struct platform_device *pdev) -{ - struct imx_pinctrl *ipctl = platform_get_drvdata(pdev); - - pinctrl_unregister(ipctl->pctl); - - return 0; -} diff --git a/trunk/drivers/pinctrl/pinctrl-imx.h b/trunk/drivers/pinctrl/pinctrl-imx.h deleted file mode 100644 index 9b65e7828f1d..000000000000 --- a/trunk/drivers/pinctrl/pinctrl-imx.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * IMX pinmux core definitions - * - * Copyright (C) 2012 Freescale Semiconductor, Inc. - * Copyright (C) 2012 Linaro Ltd. - * - * Author: Dong Aisheng - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef __DRIVERS_PINCTRL_IMX_H -#define __DRIVERS_PINCTRL_IMX_H - -struct platform_device; - -/** - * struct imx_pin_group - describes an IMX pin group - * @name: the name of this specific pin group - * @pins: an array of discrete physical pins used in this group, taken - * from the driver-local pin enumeration space - * @npins: the number of pins in this group array, i.e. the number of - * elements in .pins so we can iterate over that array - * @mux_mode: the mux mode for each pin in this group. The size of this - * array is the same as pins. - * @configs: the config for each pin in this group. The size of this - * array is the same as pins. - */ -struct imx_pin_group { - const char *name; - unsigned int *pins; - unsigned npins; - unsigned int *mux_mode; - unsigned long *configs; -}; - -/** - * struct imx_pmx_func - describes IMX pinmux functions - * @name: the name of this specific function - * @groups: corresponding pin groups - * @num_groups: the number of groups - */ -struct imx_pmx_func { - const char *name; - const char **groups; - unsigned num_groups; -}; - -/** - * struct imx_pin_reg - describe a pin reg map - * The last 3 members are used for select input setting - * @pid: pin id - * @mux_reg: mux register offset - * @conf_reg: config register offset - * @mux_mode: mux mode - * @input_reg: select input register offset for this mux if any - * 0 if no select input setting needed. - * @input_val: the value set to select input register - */ -struct imx_pin_reg { - u16 pid; - u16 mux_reg; - u16 conf_reg; - u8 mux_mode; - u16 input_reg; - u8 input_val; -}; - -struct imx_pinctrl_soc_info { - struct device *dev; - const struct pinctrl_pin_desc *pins; - unsigned int npins; - const struct imx_pin_reg *pin_regs; - unsigned int npin_regs; - struct imx_pin_group *groups; - unsigned int ngroups; - struct imx_pmx_func *functions; - unsigned int nfunctions; -}; - -#define NO_MUX 0x0 -#define NO_PAD 0x0 - -#define IMX_PIN_REG(id, conf, mux, mode, input, val) \ - { \ - .pid = id, \ - .conf_reg = conf, \ - .mux_reg = mux, \ - .mux_mode = mode, \ - .input_reg = input, \ - .input_val = val, \ - } - -#define IMX_PINCTRL_PIN(pin) PINCTRL_PIN(pin, #pin) - -#define PAD_CTL_MASK(len) ((1 << len) - 1) -#define IMX_MUX_MASK 0x7 -#define IOMUXC_CONFIG_SION (0x1 << 4) - -int imx_pinctrl_probe(struct platform_device *pdev, - struct imx_pinctrl_soc_info *info); -int imx_pinctrl_remove(struct platform_device *pdev); -#endif /* __DRIVERS_PINCTRL_IMX_H */ diff --git a/trunk/drivers/pinctrl/pinctrl-imx23.c b/trunk/drivers/pinctrl/pinctrl-imx23.c deleted file mode 100644 index 75d3eff94296..000000000000 --- a/trunk/drivers/pinctrl/pinctrl-imx23.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Copyright 2012 Freescale Semiconductor, Inc. - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include -#include -#include -#include -#include "pinctrl-mxs.h" - -enum imx23_pin_enum { - GPMI_D00 = PINID(0, 0), - GPMI_D01 = PINID(0, 1), - GPMI_D02 = PINID(0, 2), - GPMI_D03 = PINID(0, 3), - GPMI_D04 = PINID(0, 4), - GPMI_D05 = PINID(0, 5), - GPMI_D06 = PINID(0, 6), - GPMI_D07 = PINID(0, 7), - GPMI_D08 = PINID(0, 8), - GPMI_D09 = PINID(0, 9), - GPMI_D10 = PINID(0, 10), - GPMI_D11 = PINID(0, 11), - GPMI_D12 = PINID(0, 12), - GPMI_D13 = PINID(0, 13), - GPMI_D14 = PINID(0, 14), - GPMI_D15 = PINID(0, 15), - GPMI_CLE = PINID(0, 16), - GPMI_ALE = PINID(0, 17), - GPMI_CE2N = PINID(0, 18), - GPMI_RDY0 = PINID(0, 19), - GPMI_RDY1 = PINID(0, 20), - GPMI_RDY2 = PINID(0, 21), - GPMI_RDY3 = PINID(0, 22), - GPMI_WPN = PINID(0, 23), - GPMI_WRN = PINID(0, 24), - GPMI_RDN = PINID(0, 25), - AUART1_CTS = PINID(0, 26), - AUART1_RTS = PINID(0, 27), - AUART1_RX = PINID(0, 28), - AUART1_TX = PINID(0, 29), - I2C_SCL = PINID(0, 30), - I2C_SDA = PINID(0, 31), - LCD_D00 = PINID(1, 0), - LCD_D01 = PINID(1, 1), - LCD_D02 = PINID(1, 2), - LCD_D03 = PINID(1, 3), - LCD_D04 = PINID(1, 4), - LCD_D05 = PINID(1, 5), - LCD_D06 = PINID(1, 6), - LCD_D07 = PINID(1, 7), - LCD_D08 = PINID(1, 8), - LCD_D09 = PINID(1, 9), - LCD_D10 = PINID(1, 10), - LCD_D11 = PINID(1, 11), - LCD_D12 = PINID(1, 12), - LCD_D13 = PINID(1, 13), - LCD_D14 = PINID(1, 14), - LCD_D15 = PINID(1, 15), - LCD_D16 = PINID(1, 16), - LCD_D17 = PINID(1, 17), - LCD_RESET = PINID(1, 18), - LCD_RS = PINID(1, 19), - LCD_WR = PINID(1, 20), - LCD_CS = PINID(1, 21), - LCD_DOTCK = PINID(1, 22), - LCD_ENABLE = PINID(1, 23), - LCD_HSYNC = PINID(1, 24), - LCD_VSYNC = PINID(1, 25), - PWM0 = PINID(1, 26), - PWM1 = PINID(1, 27), - PWM2 = PINID(1, 28), - PWM3 = PINID(1, 29), - PWM4 = PINID(1, 30), - SSP1_CMD = PINID(2, 0), - SSP1_DETECT = PINID(2, 1), - SSP1_DATA0 = PINID(2, 2), - SSP1_DATA1 = PINID(2, 3), - SSP1_DATA2 = PINID(2, 4), - SSP1_DATA3 = PINID(2, 5), - SSP1_SCK = PINID(2, 6), - ROTARYA = PINID(2, 7), - ROTARYB = PINID(2, 8), - EMI_A00 = PINID(2, 9), - EMI_A01 = PINID(2, 10), - EMI_A02 = PINID(2, 11), - EMI_A03 = PINID(2, 12), - EMI_A04 = PINID(2, 13), - EMI_A05 = PINID(2, 14), - EMI_A06 = PINID(2, 15), - EMI_A07 = PINID(2, 16), - EMI_A08 = PINID(2, 17), - EMI_A09 = PINID(2, 18), - EMI_A10 = PINID(2, 19), - EMI_A11 = PINID(2, 20), - EMI_A12 = PINID(2, 21), - EMI_BA0 = PINID(2, 22), - EMI_BA1 = PINID(2, 23), - EMI_CASN = PINID(2, 24), - EMI_CE0N = PINID(2, 25), - EMI_CE1N = PINID(2, 26), - GPMI_CE1N = PINID(2, 27), - GPMI_CE0N = PINID(2, 28), - EMI_CKE = PINID(2, 29), - EMI_RASN = PINID(2, 30), - EMI_WEN = PINID(2, 31), - EMI_D00 = PINID(3, 0), - EMI_D01 = PINID(3, 1), - EMI_D02 = PINID(3, 2), - EMI_D03 = PINID(3, 3), - EMI_D04 = PINID(3, 4), - EMI_D05 = PINID(3, 5), - EMI_D06 = PINID(3, 6), - EMI_D07 = PINID(3, 7), - EMI_D08 = PINID(3, 8), - EMI_D09 = PINID(3, 9), - EMI_D10 = PINID(3, 10), - EMI_D11 = PINID(3, 11), - EMI_D12 = PINID(3, 12), - EMI_D13 = PINID(3, 13), - EMI_D14 = PINID(3, 14), - EMI_D15 = PINID(3, 15), - EMI_DQM0 = PINID(3, 16), - EMI_DQM1 = PINID(3, 17), - EMI_DQS0 = PINID(3, 18), - EMI_DQS1 = PINID(3, 19), - EMI_CLK = PINID(3, 20), - EMI_CLKN = PINID(3, 21), -}; - -static const struct pinctrl_pin_desc imx23_pins[] = { - MXS_PINCTRL_PIN(GPMI_D00), - MXS_PINCTRL_PIN(GPMI_D01), - MXS_PINCTRL_PIN(GPMI_D02), - MXS_PINCTRL_PIN(GPMI_D03), - MXS_PINCTRL_PIN(GPMI_D04), - MXS_PINCTRL_PIN(GPMI_D05), - MXS_PINCTRL_PIN(GPMI_D06), - MXS_PINCTRL_PIN(GPMI_D07), - MXS_PINCTRL_PIN(GPMI_D08), - MXS_PINCTRL_PIN(GPMI_D09), - MXS_PINCTRL_PIN(GPMI_D10), - MXS_PINCTRL_PIN(GPMI_D11), - MXS_PINCTRL_PIN(GPMI_D12), - MXS_PINCTRL_PIN(GPMI_D13), - MXS_PINCTRL_PIN(GPMI_D14), - MXS_PINCTRL_PIN(GPMI_D15), - MXS_PINCTRL_PIN(GPMI_CLE), - MXS_PINCTRL_PIN(GPMI_ALE), - MXS_PINCTRL_PIN(GPMI_CE2N), - MXS_PINCTRL_PIN(GPMI_RDY0), - MXS_PINCTRL_PIN(GPMI_RDY1), - MXS_PINCTRL_PIN(GPMI_RDY2), - MXS_PINCTRL_PIN(GPMI_RDY3), - MXS_PINCTRL_PIN(GPMI_WPN), - MXS_PINCTRL_PIN(GPMI_WRN), - MXS_PINCTRL_PIN(GPMI_RDN), - MXS_PINCTRL_PIN(AUART1_CTS), - MXS_PINCTRL_PIN(AUART1_RTS), - MXS_PINCTRL_PIN(AUART1_RX), - MXS_PINCTRL_PIN(AUART1_TX), - MXS_PINCTRL_PIN(I2C_SCL), - MXS_PINCTRL_PIN(I2C_SDA), - MXS_PINCTRL_PIN(LCD_D00), - MXS_PINCTRL_PIN(LCD_D01), - MXS_PINCTRL_PIN(LCD_D02), - MXS_PINCTRL_PIN(LCD_D03), - MXS_PINCTRL_PIN(LCD_D04), - MXS_PINCTRL_PIN(LCD_D05), - MXS_PINCTRL_PIN(LCD_D06), - MXS_PINCTRL_PIN(LCD_D07), - MXS_PINCTRL_PIN(LCD_D08), - MXS_PINCTRL_PIN(LCD_D09), - MXS_PINCTRL_PIN(LCD_D10), - MXS_PINCTRL_PIN(LCD_D11), - MXS_PINCTRL_PIN(LCD_D12), - MXS_PINCTRL_PIN(LCD_D13), - MXS_PINCTRL_PIN(LCD_D14), - MXS_PINCTRL_PIN(LCD_D15), - MXS_PINCTRL_PIN(LCD_D16), - MXS_PINCTRL_PIN(LCD_D17), - MXS_PINCTRL_PIN(LCD_RESET), - MXS_PINCTRL_PIN(LCD_RS), - MXS_PINCTRL_PIN(LCD_WR), - MXS_PINCTRL_PIN(LCD_CS), - MXS_PINCTRL_PIN(LCD_DOTCK), - MXS_PINCTRL_PIN(LCD_ENABLE), - MXS_PINCTRL_PIN(LCD_HSYNC), - MXS_PINCTRL_PIN(LCD_VSYNC), - MXS_PINCTRL_PIN(PWM0), - MXS_PINCTRL_PIN(PWM1), - MXS_PINCTRL_PIN(PWM2), - MXS_PINCTRL_PIN(PWM3), - MXS_PINCTRL_PIN(PWM4), - MXS_PINCTRL_PIN(SSP1_CMD), - MXS_PINCTRL_PIN(SSP1_DETECT), - MXS_PINCTRL_PIN(SSP1_DATA0), - MXS_PINCTRL_PIN(SSP1_DATA1), - MXS_PINCTRL_PIN(SSP1_DATA2), - MXS_PINCTRL_PIN(SSP1_DATA3), - MXS_PINCTRL_PIN(SSP1_SCK), - MXS_PINCTRL_PIN(ROTARYA), - MXS_PINCTRL_PIN(ROTARYB), - MXS_PINCTRL_PIN(EMI_A00), - MXS_PINCTRL_PIN(EMI_A01), - MXS_PINCTRL_PIN(EMI_A02), - MXS_PINCTRL_PIN(EMI_A03), - MXS_PINCTRL_PIN(EMI_A04), - MXS_PINCTRL_PIN(EMI_A05), - MXS_PINCTRL_PIN(EMI_A06), - MXS_PINCTRL_PIN(EMI_A07), - MXS_PINCTRL_PIN(EMI_A08), - MXS_PINCTRL_PIN(EMI_A09), - MXS_PINCTRL_PIN(EMI_A10), - MXS_PINCTRL_PIN(EMI_A11), - MXS_PINCTRL_PIN(EMI_A12), - MXS_PINCTRL_PIN(EMI_BA0), - MXS_PINCTRL_PIN(EMI_BA1), - MXS_PINCTRL_PIN(EMI_CASN), - MXS_PINCTRL_PIN(EMI_CE0N), - MXS_PINCTRL_PIN(EMI_CE1N), - MXS_PINCTRL_PIN(GPMI_CE1N), - MXS_PINCTRL_PIN(GPMI_CE0N), - MXS_PINCTRL_PIN(EMI_CKE), - MXS_PINCTRL_PIN(EMI_RASN), - MXS_PINCTRL_PIN(EMI_WEN), - MXS_PINCTRL_PIN(EMI_D00), - MXS_PINCTRL_PIN(EMI_D01), - MXS_PINCTRL_PIN(EMI_D02), - MXS_PINCTRL_PIN(EMI_D03), - MXS_PINCTRL_PIN(EMI_D04), - MXS_PINCTRL_PIN(EMI_D05), - MXS_PINCTRL_PIN(EMI_D06), - MXS_PINCTRL_PIN(EMI_D07), - MXS_PINCTRL_PIN(EMI_D08), - MXS_PINCTRL_PIN(EMI_D09), - MXS_PINCTRL_PIN(EMI_D10), - MXS_PINCTRL_PIN(EMI_D11), - MXS_PINCTRL_PIN(EMI_D12), - MXS_PINCTRL_PIN(EMI_D13), - MXS_PINCTRL_PIN(EMI_D14), - MXS_PINCTRL_PIN(EMI_D15), - MXS_PINCTRL_PIN(EMI_DQM0), - MXS_PINCTRL_PIN(EMI_DQM1), - MXS_PINCTRL_PIN(EMI_DQS0), - MXS_PINCTRL_PIN(EMI_DQS1), - MXS_PINCTRL_PIN(EMI_CLK), - MXS_PINCTRL_PIN(EMI_CLKN), -}; - -static struct mxs_regs imx23_regs = { - .muxsel = 0x100, - .drive = 0x200, - .pull = 0x400, -}; - -static struct mxs_pinctrl_soc_data imx23_pinctrl_data = { - .regs = &imx23_regs, - .pins = imx23_pins, - .npins = ARRAY_SIZE(imx23_pins), -}; - -static int __devinit imx23_pinctrl_probe(struct platform_device *pdev) -{ - return mxs_pinctrl_probe(pdev, &imx23_pinctrl_data); -} - -static struct of_device_id imx23_pinctrl_of_match[] __devinitdata = { - { .compatible = "fsl,imx23-pinctrl", }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, imx23_pinctrl_of_match); - -static struct platform_driver imx23_pinctrl_driver = { - .driver = { - .name = "imx23-pinctrl", - .owner = THIS_MODULE, - .of_match_table = imx23_pinctrl_of_match, - }, - .probe = imx23_pinctrl_probe, - .remove = __devexit_p(mxs_pinctrl_remove), -}; - -static int __init imx23_pinctrl_init(void) -{ - return platform_driver_register(&imx23_pinctrl_driver); -} -arch_initcall(imx23_pinctrl_init); - -static void __exit imx23_pinctrl_exit(void) -{ - platform_driver_unregister(&imx23_pinctrl_driver); -} -module_exit(imx23_pinctrl_exit); - -MODULE_AUTHOR("Shawn Guo "); -MODULE_DESCRIPTION("Freescale i.MX23 pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/pinctrl/pinctrl-imx28.c b/trunk/drivers/pinctrl/pinctrl-imx28.c deleted file mode 100644 index b973026811a2..000000000000 --- a/trunk/drivers/pinctrl/pinctrl-imx28.c +++ /dev/null @@ -1,421 +0,0 @@ -/* - * Copyright 2012 Freescale Semiconductor, Inc. - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include -#include -#include -#include -#include "pinctrl-mxs.h" - -enum imx28_pin_enum { - GPMI_D00 = PINID(0, 0), - GPMI_D01 = PINID(0, 1), - GPMI_D02 = PINID(0, 2), - GPMI_D03 = PINID(0, 3), - GPMI_D04 = PINID(0, 4), - GPMI_D05 = PINID(0, 5), - GPMI_D06 = PINID(0, 6), - GPMI_D07 = PINID(0, 7), - GPMI_CE0N = PINID(0, 16), - GPMI_CE1N = PINID(0, 17), - GPMI_CE2N = PINID(0, 18), - GPMI_CE3N = PINID(0, 19), - GPMI_RDY0 = PINID(0, 20), - GPMI_RDY1 = PINID(0, 21), - GPMI_RDY2 = PINID(0, 22), - GPMI_RDY3 = PINID(0, 23), - GPMI_RDN = PINID(0, 24), - GPMI_WRN = PINID(0, 25), - GPMI_ALE = PINID(0, 26), - GPMI_CLE = PINID(0, 27), - GPMI_RESETN = PINID(0, 28), - LCD_D00 = PINID(1, 0), - LCD_D01 = PINID(1, 1), - LCD_D02 = PINID(1, 2), - LCD_D03 = PINID(1, 3), - LCD_D04 = PINID(1, 4), - LCD_D05 = PINID(1, 5), - LCD_D06 = PINID(1, 6), - LCD_D07 = PINID(1, 7), - LCD_D08 = PINID(1, 8), - LCD_D09 = PINID(1, 9), - LCD_D10 = PINID(1, 10), - LCD_D11 = PINID(1, 11), - LCD_D12 = PINID(1, 12), - LCD_D13 = PINID(1, 13), - LCD_D14 = PINID(1, 14), - LCD_D15 = PINID(1, 15), - LCD_D16 = PINID(1, 16), - LCD_D17 = PINID(1, 17), - LCD_D18 = PINID(1, 18), - LCD_D19 = PINID(1, 19), - LCD_D20 = PINID(1, 20), - LCD_D21 = PINID(1, 21), - LCD_D22 = PINID(1, 22), - LCD_D23 = PINID(1, 23), - LCD_RD_E = PINID(1, 24), - LCD_WR_RWN = PINID(1, 25), - LCD_RS = PINID(1, 26), - LCD_CS = PINID(1, 27), - LCD_VSYNC = PINID(1, 28), - LCD_HSYNC = PINID(1, 29), - LCD_DOTCLK = PINID(1, 30), - LCD_ENABLE = PINID(1, 31), - SSP0_DATA0 = PINID(2, 0), - SSP0_DATA1 = PINID(2, 1), - SSP0_DATA2 = PINID(2, 2), - SSP0_DATA3 = PINID(2, 3), - SSP0_DATA4 = PINID(2, 4), - SSP0_DATA5 = PINID(2, 5), - SSP0_DATA6 = PINID(2, 6), - SSP0_DATA7 = PINID(2, 7), - SSP0_CMD = PINID(2, 8), - SSP0_DETECT = PINID(2, 9), - SSP0_SCK = PINID(2, 10), - SSP1_SCK = PINID(2, 12), - SSP1_CMD = PINID(2, 13), - SSP1_DATA0 = PINID(2, 14), - SSP1_DATA3 = PINID(2, 15), - SSP2_SCK = PINID(2, 16), - SSP2_MOSI = PINID(2, 17), - SSP2_MISO = PINID(2, 18), - SSP2_SS0 = PINID(2, 19), - SSP2_SS1 = PINID(2, 20), - SSP2_SS2 = PINID(2, 21), - SSP3_SCK = PINID(2, 24), - SSP3_MOSI = PINID(2, 25), - SSP3_MISO = PINID(2, 26), - SSP3_SS0 = PINID(2, 27), - AUART0_RX = PINID(3, 0), - AUART0_TX = PINID(3, 1), - AUART0_CTS = PINID(3, 2), - AUART0_RTS = PINID(3, 3), - AUART1_RX = PINID(3, 4), - AUART1_TX = PINID(3, 5), - AUART1_CTS = PINID(3, 6), - AUART1_RTS = PINID(3, 7), - AUART2_RX = PINID(3, 8), - AUART2_TX = PINID(3, 9), - AUART2_CTS = PINID(3, 10), - AUART2_RTS = PINID(3, 11), - AUART3_RX = PINID(3, 12), - AUART3_TX = PINID(3, 13), - AUART3_CTS = PINID(3, 14), - AUART3_RTS = PINID(3, 15), - PWM0 = PINID(3, 16), - PWM1 = PINID(3, 17), - PWM2 = PINID(3, 18), - SAIF0_MCLK = PINID(3, 20), - SAIF0_LRCLK = PINID(3, 21), - SAIF0_BITCLK = PINID(3, 22), - SAIF0_SDATA0 = PINID(3, 23), - I2C0_SCL = PINID(3, 24), - I2C0_SDA = PINID(3, 25), - SAIF1_SDATA0 = PINID(3, 26), - SPDIF = PINID(3, 27), - PWM3 = PINID(3, 28), - PWM4 = PINID(3, 29), - LCD_RESET = PINID(3, 30), - ENET0_MDC = PINID(4, 0), - ENET0_MDIO = PINID(4, 1), - ENET0_RX_EN = PINID(4, 2), - ENET0_RXD0 = PINID(4, 3), - ENET0_RXD1 = PINID(4, 4), - ENET0_TX_CLK = PINID(4, 5), - ENET0_TX_EN = PINID(4, 6), - ENET0_TXD0 = PINID(4, 7), - ENET0_TXD1 = PINID(4, 8), - ENET0_RXD2 = PINID(4, 9), - ENET0_RXD3 = PINID(4, 10), - ENET0_TXD2 = PINID(4, 11), - ENET0_TXD3 = PINID(4, 12), - ENET0_RX_CLK = PINID(4, 13), - ENET0_COL = PINID(4, 14), - ENET0_CRS = PINID(4, 15), - ENET_CLK = PINID(4, 16), - JTAG_RTCK = PINID(4, 20), - EMI_D00 = PINID(5, 0), - EMI_D01 = PINID(5, 1), - EMI_D02 = PINID(5, 2), - EMI_D03 = PINID(5, 3), - EMI_D04 = PINID(5, 4), - EMI_D05 = PINID(5, 5), - EMI_D06 = PINID(5, 6), - EMI_D07 = PINID(5, 7), - EMI_D08 = PINID(5, 8), - EMI_D09 = PINID(5, 9), - EMI_D10 = PINID(5, 10), - EMI_D11 = PINID(5, 11), - EMI_D12 = PINID(5, 12), - EMI_D13 = PINID(5, 13), - EMI_D14 = PINID(5, 14), - EMI_D15 = PINID(5, 15), - EMI_ODT0 = PINID(5, 16), - EMI_DQM0 = PINID(5, 17), - EMI_ODT1 = PINID(5, 18), - EMI_DQM1 = PINID(5, 19), - EMI_DDR_OPEN_FB = PINID(5, 20), - EMI_CLK = PINID(5, 21), - EMI_DQS0 = PINID(5, 22), - EMI_DQS1 = PINID(5, 23), - EMI_DDR_OPEN = PINID(5, 26), - EMI_A00 = PINID(6, 0), - EMI_A01 = PINID(6, 1), - EMI_A02 = PINID(6, 2), - EMI_A03 = PINID(6, 3), - EMI_A04 = PINID(6, 4), - EMI_A05 = PINID(6, 5), - EMI_A06 = PINID(6, 6), - EMI_A07 = PINID(6, 7), - EMI_A08 = PINID(6, 8), - EMI_A09 = PINID(6, 9), - EMI_A10 = PINID(6, 10), - EMI_A11 = PINID(6, 11), - EMI_A12 = PINID(6, 12), - EMI_A13 = PINID(6, 13), - EMI_A14 = PINID(6, 14), - EMI_BA0 = PINID(6, 16), - EMI_BA1 = PINID(6, 17), - EMI_BA2 = PINID(6, 18), - EMI_CASN = PINID(6, 19), - EMI_RASN = PINID(6, 20), - EMI_WEN = PINID(6, 21), - EMI_CE0N = PINID(6, 22), - EMI_CE1N = PINID(6, 23), - EMI_CKE = PINID(6, 24), -}; - -static const struct pinctrl_pin_desc imx28_pins[] = { - MXS_PINCTRL_PIN(GPMI_D00), - MXS_PINCTRL_PIN(GPMI_D01), - MXS_PINCTRL_PIN(GPMI_D02), - MXS_PINCTRL_PIN(GPMI_D03), - MXS_PINCTRL_PIN(GPMI_D04), - MXS_PINCTRL_PIN(GPMI_D05), - MXS_PINCTRL_PIN(GPMI_D06), - MXS_PINCTRL_PIN(GPMI_D07), - MXS_PINCTRL_PIN(GPMI_CE0N), - MXS_PINCTRL_PIN(GPMI_CE1N), - MXS_PINCTRL_PIN(GPMI_CE2N), - MXS_PINCTRL_PIN(GPMI_CE3N), - MXS_PINCTRL_PIN(GPMI_RDY0), - MXS_PINCTRL_PIN(GPMI_RDY1), - MXS_PINCTRL_PIN(GPMI_RDY2), - MXS_PINCTRL_PIN(GPMI_RDY3), - MXS_PINCTRL_PIN(GPMI_RDN), - MXS_PINCTRL_PIN(GPMI_WRN), - MXS_PINCTRL_PIN(GPMI_ALE), - MXS_PINCTRL_PIN(GPMI_CLE), - MXS_PINCTRL_PIN(GPMI_RESETN), - MXS_PINCTRL_PIN(LCD_D00), - MXS_PINCTRL_PIN(LCD_D01), - MXS_PINCTRL_PIN(LCD_D02), - MXS_PINCTRL_PIN(LCD_D03), - MXS_PINCTRL_PIN(LCD_D04), - MXS_PINCTRL_PIN(LCD_D05), - MXS_PINCTRL_PIN(LCD_D06), - MXS_PINCTRL_PIN(LCD_D07), - MXS_PINCTRL_PIN(LCD_D08), - MXS_PINCTRL_PIN(LCD_D09), - MXS_PINCTRL_PIN(LCD_D10), - MXS_PINCTRL_PIN(LCD_D11), - MXS_PINCTRL_PIN(LCD_D12), - MXS_PINCTRL_PIN(LCD_D13), - MXS_PINCTRL_PIN(LCD_D14), - MXS_PINCTRL_PIN(LCD_D15), - MXS_PINCTRL_PIN(LCD_D16), - MXS_PINCTRL_PIN(LCD_D17), - MXS_PINCTRL_PIN(LCD_D18), - MXS_PINCTRL_PIN(LCD_D19), - MXS_PINCTRL_PIN(LCD_D20), - MXS_PINCTRL_PIN(LCD_D21), - MXS_PINCTRL_PIN(LCD_D22), - MXS_PINCTRL_PIN(LCD_D23), - MXS_PINCTRL_PIN(LCD_RD_E), - MXS_PINCTRL_PIN(LCD_WR_RWN), - MXS_PINCTRL_PIN(LCD_RS), - MXS_PINCTRL_PIN(LCD_CS), - MXS_PINCTRL_PIN(LCD_VSYNC), - MXS_PINCTRL_PIN(LCD_HSYNC), - MXS_PINCTRL_PIN(LCD_DOTCLK), - MXS_PINCTRL_PIN(LCD_ENABLE), - MXS_PINCTRL_PIN(SSP0_DATA0), - MXS_PINCTRL_PIN(SSP0_DATA1), - MXS_PINCTRL_PIN(SSP0_DATA2), - MXS_PINCTRL_PIN(SSP0_DATA3), - MXS_PINCTRL_PIN(SSP0_DATA4), - MXS_PINCTRL_PIN(SSP0_DATA5), - MXS_PINCTRL_PIN(SSP0_DATA6), - MXS_PINCTRL_PIN(SSP0_DATA7), - MXS_PINCTRL_PIN(SSP0_CMD), - MXS_PINCTRL_PIN(SSP0_DETECT), - MXS_PINCTRL_PIN(SSP0_SCK), - MXS_PINCTRL_PIN(SSP1_SCK), - MXS_PINCTRL_PIN(SSP1_CMD), - MXS_PINCTRL_PIN(SSP1_DATA0), - MXS_PINCTRL_PIN(SSP1_DATA3), - MXS_PINCTRL_PIN(SSP2_SCK), - MXS_PINCTRL_PIN(SSP2_MOSI), - MXS_PINCTRL_PIN(SSP2_MISO), - MXS_PINCTRL_PIN(SSP2_SS0), - MXS_PINCTRL_PIN(SSP2_SS1), - MXS_PINCTRL_PIN(SSP2_SS2), - MXS_PINCTRL_PIN(SSP3_SCK), - MXS_PINCTRL_PIN(SSP3_MOSI), - MXS_PINCTRL_PIN(SSP3_MISO), - MXS_PINCTRL_PIN(SSP3_SS0), - MXS_PINCTRL_PIN(AUART0_RX), - MXS_PINCTRL_PIN(AUART0_TX), - MXS_PINCTRL_PIN(AUART0_CTS), - MXS_PINCTRL_PIN(AUART0_RTS), - MXS_PINCTRL_PIN(AUART1_RX), - MXS_PINCTRL_PIN(AUART1_TX), - MXS_PINCTRL_PIN(AUART1_CTS), - MXS_PINCTRL_PIN(AUART1_RTS), - MXS_PINCTRL_PIN(AUART2_RX), - MXS_PINCTRL_PIN(AUART2_TX), - MXS_PINCTRL_PIN(AUART2_CTS), - MXS_PINCTRL_PIN(AUART2_RTS), - MXS_PINCTRL_PIN(AUART3_RX), - MXS_PINCTRL_PIN(AUART3_TX), - MXS_PINCTRL_PIN(AUART3_CTS), - MXS_PINCTRL_PIN(AUART3_RTS), - MXS_PINCTRL_PIN(PWM0), - MXS_PINCTRL_PIN(PWM1), - MXS_PINCTRL_PIN(PWM2), - MXS_PINCTRL_PIN(SAIF0_MCLK), - MXS_PINCTRL_PIN(SAIF0_LRCLK), - MXS_PINCTRL_PIN(SAIF0_BITCLK), - MXS_PINCTRL_PIN(SAIF0_SDATA0), - MXS_PINCTRL_PIN(I2C0_SCL), - MXS_PINCTRL_PIN(I2C0_SDA), - MXS_PINCTRL_PIN(SAIF1_SDATA0), - MXS_PINCTRL_PIN(SPDIF), - MXS_PINCTRL_PIN(PWM3), - MXS_PINCTRL_PIN(PWM4), - MXS_PINCTRL_PIN(LCD_RESET), - MXS_PINCTRL_PIN(ENET0_MDC), - MXS_PINCTRL_PIN(ENET0_MDIO), - MXS_PINCTRL_PIN(ENET0_RX_EN), - MXS_PINCTRL_PIN(ENET0_RXD0), - MXS_PINCTRL_PIN(ENET0_RXD1), - MXS_PINCTRL_PIN(ENET0_TX_CLK), - MXS_PINCTRL_PIN(ENET0_TX_EN), - MXS_PINCTRL_PIN(ENET0_TXD0), - MXS_PINCTRL_PIN(ENET0_TXD1), - MXS_PINCTRL_PIN(ENET0_RXD2), - MXS_PINCTRL_PIN(ENET0_RXD3), - MXS_PINCTRL_PIN(ENET0_TXD2), - MXS_PINCTRL_PIN(ENET0_TXD3), - MXS_PINCTRL_PIN(ENET0_RX_CLK), - MXS_PINCTRL_PIN(ENET0_COL), - MXS_PINCTRL_PIN(ENET0_CRS), - MXS_PINCTRL_PIN(ENET_CLK), - MXS_PINCTRL_PIN(JTAG_RTCK), - MXS_PINCTRL_PIN(EMI_D00), - MXS_PINCTRL_PIN(EMI_D01), - MXS_PINCTRL_PIN(EMI_D02), - MXS_PINCTRL_PIN(EMI_D03), - MXS_PINCTRL_PIN(EMI_D04), - MXS_PINCTRL_PIN(EMI_D05), - MXS_PINCTRL_PIN(EMI_D06), - MXS_PINCTRL_PIN(EMI_D07), - MXS_PINCTRL_PIN(EMI_D08), - MXS_PINCTRL_PIN(EMI_D09), - MXS_PINCTRL_PIN(EMI_D10), - MXS_PINCTRL_PIN(EMI_D11), - MXS_PINCTRL_PIN(EMI_D12), - MXS_PINCTRL_PIN(EMI_D13), - MXS_PINCTRL_PIN(EMI_D14), - MXS_PINCTRL_PIN(EMI_D15), - MXS_PINCTRL_PIN(EMI_ODT0), - MXS_PINCTRL_PIN(EMI_DQM0), - MXS_PINCTRL_PIN(EMI_ODT1), - MXS_PINCTRL_PIN(EMI_DQM1), - MXS_PINCTRL_PIN(EMI_DDR_OPEN_FB), - MXS_PINCTRL_PIN(EMI_CLK), - MXS_PINCTRL_PIN(EMI_DQS0), - MXS_PINCTRL_PIN(EMI_DQS1), - MXS_PINCTRL_PIN(EMI_DDR_OPEN), - MXS_PINCTRL_PIN(EMI_A00), - MXS_PINCTRL_PIN(EMI_A01), - MXS_PINCTRL_PIN(EMI_A02), - MXS_PINCTRL_PIN(EMI_A03), - MXS_PINCTRL_PIN(EMI_A04), - MXS_PINCTRL_PIN(EMI_A05), - MXS_PINCTRL_PIN(EMI_A06), - MXS_PINCTRL_PIN(EMI_A07), - MXS_PINCTRL_PIN(EMI_A08), - MXS_PINCTRL_PIN(EMI_A09), - MXS_PINCTRL_PIN(EMI_A10), - MXS_PINCTRL_PIN(EMI_A11), - MXS_PINCTRL_PIN(EMI_A12), - MXS_PINCTRL_PIN(EMI_A13), - MXS_PINCTRL_PIN(EMI_A14), - MXS_PINCTRL_PIN(EMI_BA0), - MXS_PINCTRL_PIN(EMI_BA1), - MXS_PINCTRL_PIN(EMI_BA2), - MXS_PINCTRL_PIN(EMI_CASN), - MXS_PINCTRL_PIN(EMI_RASN), - MXS_PINCTRL_PIN(EMI_WEN), - MXS_PINCTRL_PIN(EMI_CE0N), - MXS_PINCTRL_PIN(EMI_CE1N), - MXS_PINCTRL_PIN(EMI_CKE), -}; - -static struct mxs_regs imx28_regs = { - .muxsel = 0x100, - .drive = 0x300, - .pull = 0x600, -}; - -static struct mxs_pinctrl_soc_data imx28_pinctrl_data = { - .regs = &imx28_regs, - .pins = imx28_pins, - .npins = ARRAY_SIZE(imx28_pins), -}; - -static int __devinit imx28_pinctrl_probe(struct platform_device *pdev) -{ - return mxs_pinctrl_probe(pdev, &imx28_pinctrl_data); -} - -static struct of_device_id imx28_pinctrl_of_match[] __devinitdata = { - { .compatible = "fsl,imx28-pinctrl", }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, imx28_pinctrl_of_match); - -static struct platform_driver imx28_pinctrl_driver = { - .driver = { - .name = "imx28-pinctrl", - .owner = THIS_MODULE, - .of_match_table = imx28_pinctrl_of_match, - }, - .probe = imx28_pinctrl_probe, - .remove = __devexit_p(mxs_pinctrl_remove), -}; - -static int __init imx28_pinctrl_init(void) -{ - return platform_driver_register(&imx28_pinctrl_driver); -} -arch_initcall(imx28_pinctrl_init); - -static void __exit imx28_pinctrl_exit(void) -{ - platform_driver_unregister(&imx28_pinctrl_driver); -} -module_exit(imx28_pinctrl_exit); - -MODULE_AUTHOR("Shawn Guo "); -MODULE_DESCRIPTION("Freescale i.MX28 pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/pinctrl/pinctrl-imx51.c b/trunk/drivers/pinctrl/pinctrl-imx51.c deleted file mode 100644 index 689b3c88dd2e..000000000000 --- a/trunk/drivers/pinctrl/pinctrl-imx51.c +++ /dev/null @@ -1,1322 +0,0 @@ -/* - * imx51 pinctrl driver based on imx pinmux core - * - * Copyright (C) 2012 Freescale Semiconductor, Inc. - * Copyright (C) 2012 Linaro, Inc. - * - * Author: Dong Aisheng - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "pinctrl-imx.h" - -enum imx51_pads { - MX51_PAD_EIM_D16 = 1, - MX51_PAD_EIM_D17 = 2, - MX51_PAD_EIM_D18 = 3, - MX51_PAD_EIM_D19 = 4, - MX51_PAD_EIM_D20 = 5, - MX51_PAD_EIM_D21 = 6, - MX51_PAD_EIM_D22 = 7, - MX51_PAD_EIM_D23 = 8, - MX51_PAD_EIM_D24 = 9, - MX51_PAD_EIM_D25 = 10, - MX51_PAD_EIM_D26 = 11, - MX51_PAD_EIM_D27 = 12, - MX51_PAD_EIM_D28 = 13, - MX51_PAD_EIM_D29 = 14, - MX51_PAD_EIM_D30 = 15, - MX51_PAD_EIM_D31 = 16, - MX51_PAD_EIM_A16 = 17, - MX51_PAD_EIM_A17 = 18, - MX51_PAD_EIM_A18 = 19, - MX51_PAD_EIM_A19 = 20, - MX51_PAD_EIM_A20 = 21, - MX51_PAD_EIM_A21 = 22, - MX51_PAD_EIM_A22 = 23, - MX51_PAD_EIM_A23 = 24, - MX51_PAD_EIM_A24 = 25, - MX51_PAD_EIM_A25 = 26, - MX51_PAD_EIM_A26 = 27, - MX51_PAD_EIM_A27 = 28, - MX51_PAD_EIM_EB0 = 29, - MX51_PAD_EIM_EB1 = 30, - MX51_PAD_EIM_EB2 = 31, - MX51_PAD_EIM_EB3 = 32, - MX51_PAD_EIM_OE = 33, - MX51_PAD_EIM_CS0 = 34, - MX51_PAD_EIM_CS1 = 35, - MX51_PAD_EIM_CS2 = 36, - MX51_PAD_EIM_CS3 = 37, - MX51_PAD_EIM_CS4 = 38, - MX51_PAD_EIM_CS5 = 39, - MX51_PAD_EIM_DTACK = 40, - MX51_PAD_EIM_LBA = 41, - MX51_PAD_EIM_CRE = 42, - MX51_PAD_DRAM_CS1 = 43, - MX51_PAD_NANDF_WE_B = 44, - MX51_PAD_NANDF_RE_B = 45, - MX51_PAD_NANDF_ALE = 46, - MX51_PAD_NANDF_CLE = 47, - MX51_PAD_NANDF_WP_B = 48, - MX51_PAD_NANDF_RB0 = 49, - MX51_PAD_NANDF_RB1 = 50, - MX51_PAD_NANDF_RB2 = 51, - MX51_PAD_NANDF_RB3 = 52, - MX51_PAD_GPIO_NAND = 53, - MX51_PAD_NANDF_CS0 = 54, - MX51_PAD_NANDF_CS1 = 55, - MX51_PAD_NANDF_CS2 = 56, - MX51_PAD_NANDF_CS3 = 57, - MX51_PAD_NANDF_CS4 = 58, - MX51_PAD_NANDF_CS5 = 59, - MX51_PAD_NANDF_CS6 = 60, - MX51_PAD_NANDF_CS7 = 61, - MX51_PAD_NANDF_RDY_INT = 62, - MX51_PAD_NANDF_D15 = 63, - MX51_PAD_NANDF_D14 = 64, - MX51_PAD_NANDF_D13 = 65, - MX51_PAD_NANDF_D12 = 66, - MX51_PAD_NANDF_D11 = 67, - MX51_PAD_NANDF_D10 = 68, - MX51_PAD_NANDF_D9 = 69, - MX51_PAD_NANDF_D8 = 70, - MX51_PAD_NANDF_D7 = 71, - MX51_PAD_NANDF_D6 = 72, - MX51_PAD_NANDF_D5 = 73, - MX51_PAD_NANDF_D4 = 74, - MX51_PAD_NANDF_D3 = 75, - MX51_PAD_NANDF_D2 = 76, - MX51_PAD_NANDF_D1 = 77, - MX51_PAD_NANDF_D0 = 78, - MX51_PAD_CSI1_D8 = 79, - MX51_PAD_CSI1_D9 = 80, - MX51_PAD_CSI1_D10 = 81, - MX51_PAD_CSI1_D11 = 82, - MX51_PAD_CSI1_D12 = 83, - MX51_PAD_CSI1_D13 = 84, - MX51_PAD_CSI1_D14 = 85, - MX51_PAD_CSI1_D15 = 86, - MX51_PAD_CSI1_D16 = 87, - MX51_PAD_CSI1_D17 = 88, - MX51_PAD_CSI1_D18 = 89, - MX51_PAD_CSI1_D19 = 90, - MX51_PAD_CSI1_VSYNC = 91, - MX51_PAD_CSI1_HSYNC = 92, - MX51_PAD_CSI1_PIXCLK = 93, - MX51_PAD_CSI1_MCLK = 94, - MX51_PAD_CSI2_D12 = 95, - MX51_PAD_CSI2_D13 = 96, - MX51_PAD_CSI2_D14 = 97, - MX51_PAD_CSI2_D15 = 98, - MX51_PAD_CSI2_D16 = 99, - MX51_PAD_CSI2_D17 = 100, - MX51_PAD_CSI2_D18 = 101, - MX51_PAD_CSI2_D19 = 102, - MX51_PAD_CSI2_VSYNC = 103, - MX51_PAD_CSI2_HSYNC = 104, - MX51_PAD_CSI2_PIXCLK = 105, - MX51_PAD_I2C1_CLK = 106, - MX51_PAD_I2C1_DAT = 107, - MX51_PAD_AUD3_BB_TXD = 108, - MX51_PAD_AUD3_BB_RXD = 109, - MX51_PAD_AUD3_BB_CK = 110, - MX51_PAD_AUD3_BB_FS = 111, - MX51_PAD_CSPI1_MOSI = 112, - MX51_PAD_CSPI1_MISO = 113, - MX51_PAD_CSPI1_SS0 = 114, - MX51_PAD_CSPI1_SS1 = 115, - MX51_PAD_CSPI1_RDY = 116, - MX51_PAD_CSPI1_SCLK = 117, - MX51_PAD_UART1_RXD = 118, - MX51_PAD_UART1_TXD = 119, - MX51_PAD_UART1_RTS = 120, - MX51_PAD_UART1_CTS = 121, - MX51_PAD_UART2_RXD = 122, - MX51_PAD_UART2_TXD = 123, - MX51_PAD_UART3_RXD = 124, - MX51_PAD_UART3_TXD = 125, - MX51_PAD_OWIRE_LINE = 126, - MX51_PAD_KEY_ROW0 = 127, - MX51_PAD_KEY_ROW1 = 128, - MX51_PAD_KEY_ROW2 = 129, - MX51_PAD_KEY_ROW3 = 130, - MX51_PAD_KEY_COL0 = 131, - MX51_PAD_KEY_COL1 = 132, - MX51_PAD_KEY_COL2 = 133, - MX51_PAD_KEY_COL3 = 134, - MX51_PAD_KEY_COL4 = 135, - MX51_PAD_KEY_COL5 = 136, - MX51_PAD_USBH1_CLK = 137, - MX51_PAD_USBH1_DIR = 138, - MX51_PAD_USBH1_STP = 139, - MX51_PAD_USBH1_NXT = 140, - MX51_PAD_USBH1_DATA0 = 141, - MX51_PAD_USBH1_DATA1 = 142, - MX51_PAD_USBH1_DATA2 = 143, - MX51_PAD_USBH1_DATA3 = 144, - MX51_PAD_USBH1_DATA4 = 145, - MX51_PAD_USBH1_DATA5 = 146, - MX51_PAD_USBH1_DATA6 = 147, - MX51_PAD_USBH1_DATA7 = 148, - MX51_PAD_DI1_PIN11 = 149, - MX51_PAD_DI1_PIN12 = 150, - MX51_PAD_DI1_PIN13 = 151, - MX51_PAD_DI1_D0_CS = 152, - MX51_PAD_DI1_D1_CS = 153, - MX51_PAD_DISPB2_SER_DIN = 154, - MX51_PAD_DISPB2_SER_DIO = 155, - MX51_PAD_DISPB2_SER_CLK = 156, - MX51_PAD_DISPB2_SER_RS = 157, - MX51_PAD_DISP1_DAT0 = 158, - MX51_PAD_DISP1_DAT1 = 159, - MX51_PAD_DISP1_DAT2 = 160, - MX51_PAD_DISP1_DAT3 = 161, - MX51_PAD_DISP1_DAT4 = 162, - MX51_PAD_DISP1_DAT5 = 163, - MX51_PAD_DISP1_DAT6 = 164, - MX51_PAD_DISP1_DAT7 = 165, - MX51_PAD_DISP1_DAT8 = 166, - MX51_PAD_DISP1_DAT9 = 167, - MX51_PAD_DISP1_DAT10 = 168, - MX51_PAD_DISP1_DAT11 = 169, - MX51_PAD_DISP1_DAT12 = 170, - MX51_PAD_DISP1_DAT13 = 171, - MX51_PAD_DISP1_DAT14 = 172, - MX51_PAD_DISP1_DAT15 = 173, - MX51_PAD_DISP1_DAT16 = 174, - MX51_PAD_DISP1_DAT17 = 175, - MX51_PAD_DISP1_DAT18 = 176, - MX51_PAD_DISP1_DAT19 = 177, - MX51_PAD_DISP1_DAT20 = 178, - MX51_PAD_DISP1_DAT21 = 179, - MX51_PAD_DISP1_DAT22 = 180, - MX51_PAD_DISP1_DAT23 = 181, - MX51_PAD_DI1_PIN3 = 182, - MX51_PAD_DI1_PIN2 = 183, - MX51_PAD_DI_GP2 = 184, - MX51_PAD_DI_GP3 = 185, - MX51_PAD_DI2_PIN4 = 186, - MX51_PAD_DI2_PIN2 = 187, - MX51_PAD_DI2_PIN3 = 188, - MX51_PAD_DI2_DISP_CLK = 189, - MX51_PAD_DI_GP4 = 190, - MX51_PAD_DISP2_DAT0 = 191, - MX51_PAD_DISP2_DAT1 = 192, - MX51_PAD_DISP2_DAT2 = 193, - MX51_PAD_DISP2_DAT3 = 194, - MX51_PAD_DISP2_DAT4 = 195, - MX51_PAD_DISP2_DAT5 = 196, - MX51_PAD_DISP2_DAT6 = 197, - MX51_PAD_DISP2_DAT7 = 198, - MX51_PAD_DISP2_DAT8 = 199, - MX51_PAD_DISP2_DAT9 = 200, - MX51_PAD_DISP2_DAT10 = 201, - MX51_PAD_DISP2_DAT11 = 202, - MX51_PAD_DISP2_DAT12 = 203, - MX51_PAD_DISP2_DAT13 = 204, - MX51_PAD_DISP2_DAT14 = 205, - MX51_PAD_DISP2_DAT15 = 206, - MX51_PAD_SD1_CMD = 207, - MX51_PAD_SD1_CLK = 208, - MX51_PAD_SD1_DATA0 = 209, - MX51_PAD_EIM_DA0 = 210, - MX51_PAD_EIM_DA1 = 211, - MX51_PAD_EIM_DA2 = 212, - MX51_PAD_EIM_DA3 = 213, - MX51_PAD_SD1_DATA1 = 214, - MX51_PAD_EIM_DA4 = 215, - MX51_PAD_EIM_DA5 = 216, - MX51_PAD_EIM_DA6 = 217, - MX51_PAD_EIM_DA7 = 218, - MX51_PAD_SD1_DATA2 = 219, - MX51_PAD_EIM_DA10 = 220, - MX51_PAD_EIM_DA11 = 221, - MX51_PAD_EIM_DA8 = 222, - MX51_PAD_EIM_DA9 = 223, - MX51_PAD_SD1_DATA3 = 224, - MX51_PAD_GPIO1_0 = 225, - MX51_PAD_GPIO1_1 = 226, - MX51_PAD_EIM_DA12 = 227, - MX51_PAD_EIM_DA13 = 228, - MX51_PAD_EIM_DA14 = 229, - MX51_PAD_EIM_DA15 = 230, - MX51_PAD_SD2_CMD = 231, - MX51_PAD_SD2_CLK = 232, - MX51_PAD_SD2_DATA0 = 233, - MX51_PAD_SD2_DATA1 = 234, - MX51_PAD_SD2_DATA2 = 235, - MX51_PAD_SD2_DATA3 = 236, - MX51_PAD_GPIO1_2 = 237, - MX51_PAD_GPIO1_3 = 238, - MX51_PAD_PMIC_INT_REQ = 239, - MX51_PAD_GPIO1_4 = 240, - MX51_PAD_GPIO1_5 = 241, - MX51_PAD_GPIO1_6 = 242, - MX51_PAD_GPIO1_7 = 243, - MX51_PAD_GPIO1_8 = 244, - MX51_PAD_GPIO1_9 = 245, -}; - -/* imx51 register maps */ -static struct imx_pin_reg imx51_pin_regs[] = { - IMX_PIN_REG(MX51_PAD_EIM_D16, 0x3f0, 0x05c, 5, 0x000, 0), /* MX51_PAD_EIM_D16__AUD4_RXFS */ - IMX_PIN_REG(MX51_PAD_EIM_D16, 0x3f0, 0x05c, 7, 0x8d8, 0), /* MX51_PAD_EIM_D16__AUD5_TXD */ - IMX_PIN_REG(MX51_PAD_EIM_D16, 0x3f0, 0x05c, 0, 0x000, 0), /* MX51_PAD_EIM_D16__EIM_D16 */ - IMX_PIN_REG(MX51_PAD_EIM_D16, 0x3f0, 0x05c, 1, 0x000, 0), /* MX51_PAD_EIM_D16__GPIO2_0 */ - IMX_PIN_REG(MX51_PAD_EIM_D16, 0x3f0, 0x05c, 4, 0x9b4, 0), /* MX51_PAD_EIM_D16__I2C1_SDA */ - IMX_PIN_REG(MX51_PAD_EIM_D16, 0x3f0, 0x05c, 3, 0x000, 0), /* MX51_PAD_EIM_D16__UART2_CTS */ - IMX_PIN_REG(MX51_PAD_EIM_D16, 0x3f0, 0x05c, 2, 0x000, 0), /* MX51_PAD_EIM_D16__USBH2_DATA0 */ - IMX_PIN_REG(MX51_PAD_EIM_D17, 0x3f4, 0x060, 7, 0x8d4, 0), /* MX51_PAD_EIM_D17__AUD5_RXD */ - IMX_PIN_REG(MX51_PAD_EIM_D17, 0x3f4, 0x060, 0, 0x000, 0), /* MX51_PAD_EIM_D17__EIM_D17 */ - IMX_PIN_REG(MX51_PAD_EIM_D17, 0x3f4, 0x060, 1, 0x000, 0), /* MX51_PAD_EIM_D17__GPIO2_1 */ - IMX_PIN_REG(MX51_PAD_EIM_D17, 0x3f4, 0x060, 3, 0x9ec, 0), /* MX51_PAD_EIM_D17__UART2_RXD */ - IMX_PIN_REG(MX51_PAD_EIM_D17, 0x3f4, 0x060, 4, 0x000, 0), /* MX51_PAD_EIM_D17__UART3_CTS */ - IMX_PIN_REG(MX51_PAD_EIM_D17, 0x3f4, 0x060, 2, 0x000, 0), /* MX51_PAD_EIM_D17__USBH2_DATA1 */ - IMX_PIN_REG(MX51_PAD_EIM_D18, 0x3f8, 0x064, 7, 0x8e4, 0), /* MX51_PAD_EIM_D18__AUD5_TXC */ - IMX_PIN_REG(MX51_PAD_EIM_D18, 0x3f8, 0x064, 0, 0x000, 0), /* MX51_PAD_EIM_D18__EIM_D18 */ - IMX_PIN_REG(MX51_PAD_EIM_D18, 0x3f8, 0x064, 1, 0x000, 0), /* MX51_PAD_EIM_D18__GPIO2_2 */ - IMX_PIN_REG(MX51_PAD_EIM_D18, 0x3f8, 0x064, 3, 0x000, 0), /* MX51_PAD_EIM_D18__UART2_TXD */ - IMX_PIN_REG(MX51_PAD_EIM_D18, 0x3f8, 0x064, 4, 0x9f0, 1), /* MX51_PAD_EIM_D18__UART3_RTS */ - IMX_PIN_REG(MX51_PAD_EIM_D18, 0x3f8, 0x064, 2, 0x000, 0), /* MX51_PAD_EIM_D18__USBH2_DATA2 */ - IMX_PIN_REG(MX51_PAD_EIM_D19, 0x3fc, 0x068, 5, 0x000, 0), /* MX51_PAD_EIM_D19__AUD4_RXC */ - IMX_PIN_REG(MX51_PAD_EIM_D19, 0x3fc, 0x068, 7, 0x8e8, 0), /* MX51_PAD_EIM_D19__AUD5_TXFS */ - IMX_PIN_REG(MX51_PAD_EIM_D19, 0x3fc, 0x068, 0, 0x000, 0), /* MX51_PAD_EIM_D19__EIM_D19 */ - IMX_PIN_REG(MX51_PAD_EIM_D19, 0x3fc, 0x068, 1, 0x000, 0), /* MX51_PAD_EIM_D19__GPIO2_3 */ - IMX_PIN_REG(MX51_PAD_EIM_D19, 0x3fc, 0x068, 4, 0x9b0, 0), /* MX51_PAD_EIM_D19__I2C1_SCL */ - IMX_PIN_REG(MX51_PAD_EIM_D19, 0x3fc, 0x068, 3, 0x9e8, 1), /* MX51_PAD_EIM_D19__UART2_RTS */ - IMX_PIN_REG(MX51_PAD_EIM_D19, 0x3fc, 0x068, 2, 0x000, 0), /* MX51_PAD_EIM_D19__USBH2_DATA3 */ - IMX_PIN_REG(MX51_PAD_EIM_D20, 0x400, 0x06c, 5, 0x8c8, 0), /* MX51_PAD_EIM_D20__AUD4_TXD */ - IMX_PIN_REG(MX51_PAD_EIM_D20, 0x400, 0x06c, 0, 0x000, 0), /* MX51_PAD_EIM_D20__EIM_D20 */ - IMX_PIN_REG(MX51_PAD_EIM_D20, 0x400, 0x06c, 1, 0x000, 0), /* MX51_PAD_EIM_D20__GPIO2_4 */ - IMX_PIN_REG(MX51_PAD_EIM_D20, 0x400, 0x06c, 4, 0x000, 0), /* MX51_PAD_EIM_D20__SRTC_ALARM_DEB */ - IMX_PIN_REG(MX51_PAD_EIM_D20, 0x400, 0x06c, 2, 0x000, 0), /* MX51_PAD_EIM_D20__USBH2_DATA4 */ - IMX_PIN_REG(MX51_PAD_EIM_D21, 0x404, 0x070, 5, 0x8c4, 0), /* MX51_PAD_EIM_D21__AUD4_RXD */ - IMX_PIN_REG(MX51_PAD_EIM_D21, 0x404, 0x070, 0, 0x000, 0), /* MX51_PAD_EIM_D21__EIM_D21 */ - IMX_PIN_REG(MX51_PAD_EIM_D21, 0x404, 0x070, 1, 0x000, 0), /* MX51_PAD_EIM_D21__GPIO2_5 */ - IMX_PIN_REG(MX51_PAD_EIM_D21, 0x404, 0x070, 3, 0x000, 0), /* MX51_PAD_EIM_D21__SRTC_ALARM_DEB */ - IMX_PIN_REG(MX51_PAD_EIM_D21, 0x404, 0x070, 2, 0x000, 0), /* MX51_PAD_EIM_D21__USBH2_DATA5 */ - IMX_PIN_REG(MX51_PAD_EIM_D22, 0x408, 0x074, 5, 0x8cc, 0), /* MX51_PAD_EIM_D22__AUD4_TXC */ - IMX_PIN_REG(MX51_PAD_EIM_D22, 0x408, 0x074, 0, 0x000, 0), /* MX51_PAD_EIM_D22__EIM_D22 */ - IMX_PIN_REG(MX51_PAD_EIM_D22, 0x408, 0x074, 1, 0x000, 0), /* MX51_PAD_EIM_D22__GPIO2_6 */ - IMX_PIN_REG(MX51_PAD_EIM_D22, 0x408, 0x074, 2, 0x000, 0), /* MX51_PAD_EIM_D22__USBH2_DATA6 */ - IMX_PIN_REG(MX51_PAD_EIM_D23, 0x40c, 0x078, 5, 0x8d0, 0), /* MX51_PAD_EIM_D23__AUD4_TXFS */ - IMX_PIN_REG(MX51_PAD_EIM_D23, 0x40c, 0x078, 0, 0x000, 0), /* MX51_PAD_EIM_D23__EIM_D23 */ - IMX_PIN_REG(MX51_PAD_EIM_D23, 0x40c, 0x078, 1, 0x000, 0), /* MX51_PAD_EIM_D23__GPIO2_7 */ - IMX_PIN_REG(MX51_PAD_EIM_D23, 0x40c, 0x078, 4, 0x000, 0), /* MX51_PAD_EIM_D23__SPDIF_OUT1 */ - IMX_PIN_REG(MX51_PAD_EIM_D23, 0x40c, 0x078, 2, 0x000, 0), /* MX51_PAD_EIM_D23__USBH2_DATA7 */ - IMX_PIN_REG(MX51_PAD_EIM_D24, 0x410, 0x07c, 5, 0x8f8, 0), /* MX51_PAD_EIM_D24__AUD6_RXFS */ - IMX_PIN_REG(MX51_PAD_EIM_D24, 0x410, 0x07c, 0, 0x000, 0), /* MX51_PAD_EIM_D24__EIM_D24 */ - IMX_PIN_REG(MX51_PAD_EIM_D24, 0x410, 0x07c, 1, 0x000, 0), /* MX51_PAD_EIM_D24__GPIO2_8 */ - IMX_PIN_REG(MX51_PAD_EIM_D24, 0x410, 0x07c, 4, 0x9bc, 0), /* MX51_PAD_EIM_D24__I2C2_SDA */ - IMX_PIN_REG(MX51_PAD_EIM_D24, 0x410, 0x07c, 3, 0x000, 0), /* MX51_PAD_EIM_D24__UART3_CTS */ - IMX_PIN_REG(MX51_PAD_EIM_D24, 0x410, 0x07c, 2, 0x000, 0), /* MX51_PAD_EIM_D24__USBOTG_DATA0 */ - IMX_PIN_REG(MX51_PAD_EIM_D25, 0x414, 0x080, 0, 0x000, 0), /* MX51_PAD_EIM_D25__EIM_D25 */ - IMX_PIN_REG(MX51_PAD_EIM_D25, 0x414, 0x080, 1, 0x9c8, 0), /* MX51_PAD_EIM_D25__KEY_COL6 */ - IMX_PIN_REG(MX51_PAD_EIM_D25, 0x414, 0x080, 4, 0x000, 0), /* MX51_PAD_EIM_D25__UART2_CTS */ - IMX_PIN_REG(MX51_PAD_EIM_D25, 0x414, 0x080, 3, 0x9f4, 0), /* MX51_PAD_EIM_D25__UART3_RXD */ - IMX_PIN_REG(MX51_PAD_EIM_D25, 0x414, 0x080, 2, 0x000, 0), /* MX51_PAD_EIM_D25__USBOTG_DATA1 */ - IMX_PIN_REG(MX51_PAD_EIM_D26, 0x418, 0x084, 0, 0x000, 0), /* MX51_PAD_EIM_D26__EIM_D26 */ - IMX_PIN_REG(MX51_PAD_EIM_D26, 0x418, 0x084, 1, 0x9cc, 0), /* MX51_PAD_EIM_D26__KEY_COL7 */ - IMX_PIN_REG(MX51_PAD_EIM_D26, 0x418, 0x084, 4, 0x9e8, 3), /* MX51_PAD_EIM_D26__UART2_RTS */ - IMX_PIN_REG(MX51_PAD_EIM_D26, 0x418, 0x084, 3, 0x000, 0), /* MX51_PAD_EIM_D26__UART3_TXD */ - IMX_PIN_REG(MX51_PAD_EIM_D26, 0x418, 0x084, 2, 0x000, 0), /* MX51_PAD_EIM_D26__USBOTG_DATA2 */ - IMX_PIN_REG(MX51_PAD_EIM_D27, 0x41c, 0x088, 5, 0x8f4, 0), /* MX51_PAD_EIM_D27__AUD6_RXC */ - IMX_PIN_REG(MX51_PAD_EIM_D27, 0x41c, 0x088, 0, 0x000, 0), /* MX51_PAD_EIM_D27__EIM_D27 */ - IMX_PIN_REG(MX51_PAD_EIM_D27, 0x41c, 0x088, 1, 0x000, 0), /* MX51_PAD_EIM_D27__GPIO2_9 */ - IMX_PIN_REG(MX51_PAD_EIM_D27, 0x41c, 0x088, 4, 0x9b8, 0), /* MX51_PAD_EIM_D27__I2C2_SCL */ - IMX_PIN_REG(MX51_PAD_EIM_D27, 0x41c, 0x088, 3, 0x9f0, 3), /* MX51_PAD_EIM_D27__UART3_RTS */ - IMX_PIN_REG(MX51_PAD_EIM_D27, 0x41c, 0x088, 2, 0x000, 0), /* MX51_PAD_EIM_D27__USBOTG_DATA3 */ - IMX_PIN_REG(MX51_PAD_EIM_D28, 0x420, 0x08c, 5, 0x8f0, 0), /* MX51_PAD_EIM_D28__AUD6_TXD */ - IMX_PIN_REG(MX51_PAD_EIM_D28, 0x420, 0x08c, 0, 0x000, 0), /* MX51_PAD_EIM_D28__EIM_D28 */ - IMX_PIN_REG(MX51_PAD_EIM_D28, 0x420, 0x08c, 1, 0x9d0, 0), /* MX51_PAD_EIM_D28__KEY_ROW4 */ - IMX_PIN_REG(MX51_PAD_EIM_D28, 0x420, 0x08c, 2, 0x000, 0), /* MX51_PAD_EIM_D28__USBOTG_DATA4 */ - IMX_PIN_REG(MX51_PAD_EIM_D29, 0x424, 0x090, 5, 0x8ec, 0), /* MX51_PAD_EIM_D29__AUD6_RXD */ - IMX_PIN_REG(MX51_PAD_EIM_D29, 0x424, 0x090, 0, 0x000, 0), /* MX51_PAD_EIM_D29__EIM_D29 */ - IMX_PIN_REG(MX51_PAD_EIM_D29, 0x424, 0x090, 1, 0x9d4, 0), /* MX51_PAD_EIM_D29__KEY_ROW5 */ - IMX_PIN_REG(MX51_PAD_EIM_D29, 0x424, 0x090, 2, 0x000, 0), /* MX51_PAD_EIM_D29__USBOTG_DATA5 */ - IMX_PIN_REG(MX51_PAD_EIM_D30, 0x428, 0x094, 5, 0x8fc, 0), /* MX51_PAD_EIM_D30__AUD6_TXC */ - IMX_PIN_REG(MX51_PAD_EIM_D30, 0x428, 0x094, 0, 0x000, 0), /* MX51_PAD_EIM_D30__EIM_D30 */ - IMX_PIN_REG(MX51_PAD_EIM_D30, 0x428, 0x094, 1, 0x9d8, 0), /* MX51_PAD_EIM_D30__KEY_ROW6 */ - IMX_PIN_REG(MX51_PAD_EIM_D30, 0x428, 0x094, 2, 0x000, 0), /* MX51_PAD_EIM_D30__USBOTG_DATA6 */ - IMX_PIN_REG(MX51_PAD_EIM_D31, 0x42c, 0x098, 5, 0x900, 0), /* MX51_PAD_EIM_D31__AUD6_TXFS */ - IMX_PIN_REG(MX51_PAD_EIM_D31, 0x42c, 0x098, 0, 0x000, 0), /* MX51_PAD_EIM_D31__EIM_D31 */ - IMX_PIN_REG(MX51_PAD_EIM_D31, 0x42c, 0x098, 1, 0x9dc, 0), /* MX51_PAD_EIM_D31__KEY_ROW7 */ - IMX_PIN_REG(MX51_PAD_EIM_D31, 0x42c, 0x098, 2, 0x000, 0), /* MX51_PAD_EIM_D31__USBOTG_DATA7 */ - IMX_PIN_REG(MX51_PAD_EIM_A16, 0x430, 0x09c, 0, 0x000, 0), /* MX51_PAD_EIM_A16__EIM_A16 */ - IMX_PIN_REG(MX51_PAD_EIM_A16, 0x430, 0x09c, 1, 0x000, 0), /* MX51_PAD_EIM_A16__GPIO2_10 */ - IMX_PIN_REG(MX51_PAD_EIM_A16, 0x430, 0x09c, 7, 0x000, 0), /* MX51_PAD_EIM_A16__OSC_FREQ_SEL0 */ - IMX_PIN_REG(MX51_PAD_EIM_A17, 0x434, 0x0a0, 0, 0x000, 0), /* MX51_PAD_EIM_A17__EIM_A17 */ - IMX_PIN_REG(MX51_PAD_EIM_A17, 0x434, 0x0a0, 1, 0x000, 0), /* MX51_PAD_EIM_A17__GPIO2_11 */ - IMX_PIN_REG(MX51_PAD_EIM_A17, 0x434, 0x0a0, 7, 0x000, 0), /* MX51_PAD_EIM_A17__OSC_FREQ_SEL1 */ - IMX_PIN_REG(MX51_PAD_EIM_A18, 0x438, 0x0a4, 7, 0x000, 0), /* MX51_PAD_EIM_A18__BOOT_LPB0 */ - IMX_PIN_REG(MX51_PAD_EIM_A18, 0x438, 0x0a4, 0, 0x000, 0), /* MX51_PAD_EIM_A18__EIM_A18 */ - IMX_PIN_REG(MX51_PAD_EIM_A18, 0x438, 0x0a4, 1, 0x000, 0), /* MX51_PAD_EIM_A18__GPIO2_12 */ - IMX_PIN_REG(MX51_PAD_EIM_A19, 0x43c, 0x0a8, 7, 0x000, 0), /* MX51_PAD_EIM_A19__BOOT_LPB1 */ - IMX_PIN_REG(MX51_PAD_EIM_A19, 0x43c, 0x0a8, 0, 0x000, 0), /* MX51_PAD_EIM_A19__EIM_A19 */ - IMX_PIN_REG(MX51_PAD_EIM_A19, 0x43c, 0x0a8, 1, 0x000, 0), /* MX51_PAD_EIM_A19__GPIO2_13 */ - IMX_PIN_REG(MX51_PAD_EIM_A20, 0x440, 0x0ac, 7, 0x000, 0), /* MX51_PAD_EIM_A20__BOOT_UART_SRC0 */ - IMX_PIN_REG(MX51_PAD_EIM_A20, 0x440, 0x0ac, 0, 0x000, 0), /* MX51_PAD_EIM_A20__EIM_A20 */ - IMX_PIN_REG(MX51_PAD_EIM_A20, 0x440, 0x0ac, 1, 0x000, 0), /* MX51_PAD_EIM_A20__GPIO2_14 */ - IMX_PIN_REG(MX51_PAD_EIM_A21, 0x444, 0x0b0, 7, 0x000, 0), /* MX51_PAD_EIM_A21__BOOT_UART_SRC1 */ - IMX_PIN_REG(MX51_PAD_EIM_A21, 0x444, 0x0b0, 0, 0x000, 0), /* MX51_PAD_EIM_A21__EIM_A21 */ - IMX_PIN_REG(MX51_PAD_EIM_A21, 0x444, 0x0b0, 1, 0x000, 0), /* MX51_PAD_EIM_A21__GPIO2_15 */ - IMX_PIN_REG(MX51_PAD_EIM_A22, 0x448, 0x0b4, 0, 0x000, 0), /* MX51_PAD_EIM_A22__EIM_A22 */ - IMX_PIN_REG(MX51_PAD_EIM_A22, 0x448, 0x0b4, 1, 0x000, 0), /* MX51_PAD_EIM_A22__GPIO2_16 */ - IMX_PIN_REG(MX51_PAD_EIM_A23, 0x44c, 0x0b8, 7, 0x000, 0), /* MX51_PAD_EIM_A23__BOOT_HPN_EN */ - IMX_PIN_REG(MX51_PAD_EIM_A23, 0x44c, 0x0b8, 0, 0x000, 0), /* MX51_PAD_EIM_A23__EIM_A23 */ - IMX_PIN_REG(MX51_PAD_EIM_A23, 0x44c, 0x0b8, 1, 0x000, 0), /* MX51_PAD_EIM_A23__GPIO2_17 */ - IMX_PIN_REG(MX51_PAD_EIM_A24, 0x450, 0x0bc, 0, 0x000, 0), /* MX51_PAD_EIM_A24__EIM_A24 */ - IMX_PIN_REG(MX51_PAD_EIM_A24, 0x450, 0x0bc, 1, 0x000, 0), /* MX51_PAD_EIM_A24__GPIO2_18 */ - IMX_PIN_REG(MX51_PAD_EIM_A24, 0x450, 0x0bc, 2, 0x000, 0), /* MX51_PAD_EIM_A24__USBH2_CLK */ - IMX_PIN_REG(MX51_PAD_EIM_A25, 0x454, 0x0c0, 6, 0x000, 0), /* MX51_PAD_EIM_A25__DISP1_PIN4 */ - IMX_PIN_REG(MX51_PAD_EIM_A25, 0x454, 0x0c0, 0, 0x000, 0), /* MX51_PAD_EIM_A25__EIM_A25 */ - IMX_PIN_REG(MX51_PAD_EIM_A25, 0x454, 0x0c0, 1, 0x000, 0), /* MX51_PAD_EIM_A25__GPIO2_19 */ - IMX_PIN_REG(MX51_PAD_EIM_A25, 0x454, 0x0c0, 2, 0x000, 0), /* MX51_PAD_EIM_A25__USBH2_DIR */ - IMX_PIN_REG(MX51_PAD_EIM_A26, 0x458, 0x0c4, 5, 0x9a0, 0), /* MX51_PAD_EIM_A26__CSI1_DATA_EN */ - IMX_PIN_REG(MX51_PAD_EIM_A26, 0x458, 0x0c4, 6, 0x908, 0), /* MX51_PAD_EIM_A26__DISP2_EXT_CLK */ - IMX_PIN_REG(MX51_PAD_EIM_A26, 0x458, 0x0c4, 0, 0x000, 0), /* MX51_PAD_EIM_A26__EIM_A26 */ - IMX_PIN_REG(MX51_PAD_EIM_A26, 0x458, 0x0c4, 1, 0x000, 0), /* MX51_PAD_EIM_A26__GPIO2_20 */ - IMX_PIN_REG(MX51_PAD_EIM_A26, 0x458, 0x0c4, 2, 0x000, 0), /* MX51_PAD_EIM_A26__USBH2_STP */ - IMX_PIN_REG(MX51_PAD_EIM_A27, 0x45c, 0x0c8, 5, 0x99c, 0), /* MX51_PAD_EIM_A27__CSI2_DATA_EN */ - IMX_PIN_REG(MX51_PAD_EIM_A27, 0x45c, 0x0c8, 6, 0x9a4, 0), /* MX51_PAD_EIM_A27__DISP1_PIN1 */ - IMX_PIN_REG(MX51_PAD_EIM_A27, 0x45c, 0x0c8, 0, 0x000, 0), /* MX51_PAD_EIM_A27__EIM_A27 */ - IMX_PIN_REG(MX51_PAD_EIM_A27, 0x45c, 0x0c8, 1, 0x000, 0), /* MX51_PAD_EIM_A27__GPIO2_21 */ - IMX_PIN_REG(MX51_PAD_EIM_A27, 0x45c, 0x0c8, 2, 0x000, 0), /* MX51_PAD_EIM_A27__USBH2_NXT */ - IMX_PIN_REG(MX51_PAD_EIM_EB0, 0x460, 0x0cc, 0, 0x000, 0), /* MX51_PAD_EIM_EB0__EIM_EB0 */ - IMX_PIN_REG(MX51_PAD_EIM_EB1, 0x464, 0x0d0, 0, 0x000, 0), /* MX51_PAD_EIM_EB1__EIM_EB1 */ - IMX_PIN_REG(MX51_PAD_EIM_EB2, 0x468, 0x0d4, 6, 0x8e0, 0), /* MX51_PAD_EIM_EB2__AUD5_RXFS */ - IMX_PIN_REG(MX51_PAD_EIM_EB2, 0x468, 0x0d4, 5, 0x000, 0), /* MX51_PAD_EIM_EB2__CSI1_D2 */ - IMX_PIN_REG(MX51_PAD_EIM_EB2, 0x468, 0x0d4, 0, 0x000, 0), /* MX51_PAD_EIM_EB2__EIM_EB2 */ - IMX_PIN_REG(MX51_PAD_EIM_EB2, 0x468, 0x0d4, 3, 0x954, 0), /* MX51_PAD_EIM_EB2__FEC_MDIO */ - IMX_PIN_REG(MX51_PAD_EIM_EB2, 0x468, 0x0d4, 1, 0x000, 0), /* MX51_PAD_EIM_EB2__GPIO2_22 */ - IMX_PIN_REG(MX51_PAD_EIM_EB2, 0x468, 0x0d4, 7, 0x000, 0), /* MX51_PAD_EIM_EB2__GPT_CMPOUT1 */ - IMX_PIN_REG(MX51_PAD_EIM_EB3, 0x46c, 0x0d8, 6, 0x8dc, 0), /* MX51_PAD_EIM_EB3__AUD5_RXC */ - IMX_PIN_REG(MX51_PAD_EIM_EB3, 0x46c, 0x0d8, 5, 0x000, 0), /* MX51_PAD_EIM_EB3__CSI1_D3 */ - IMX_PIN_REG(MX51_PAD_EIM_EB3, 0x46c, 0x0d8, 0, 0x000, 0), /* MX51_PAD_EIM_EB3__EIM_EB3 */ - IMX_PIN_REG(MX51_PAD_EIM_EB3, 0x46c, 0x0d8, 3, 0x95c, 0), /* MX51_PAD_EIM_EB3__FEC_RDATA1 */ - IMX_PIN_REG(MX51_PAD_EIM_EB3, 0x46c, 0x0d8, 1, 0x000, 0), /* MX51_PAD_EIM_EB3__GPIO2_23 */ - IMX_PIN_REG(MX51_PAD_EIM_EB3, 0x46c, 0x0d8, 7, 0x000, 0), /* MX51_PAD_EIM_EB3__GPT_CMPOUT2 */ - IMX_PIN_REG(MX51_PAD_EIM_OE, 0x470, 0x0dc, 0, 0x000, 0), /* MX51_PAD_EIM_OE__EIM_OE */ - IMX_PIN_REG(MX51_PAD_EIM_OE, 0x470, 0x0dc, 1, 0x000, 0), /* MX51_PAD_EIM_OE__GPIO2_24 */ - IMX_PIN_REG(MX51_PAD_EIM_CS0, 0x474, 0x0e0, 0, 0x000, 0), /* MX51_PAD_EIM_CS0__EIM_CS0 */ - IMX_PIN_REG(MX51_PAD_EIM_CS0, 0x474, 0x0e0, 1, 0x000, 0), /* MX51_PAD_EIM_CS0__GPIO2_25 */ - IMX_PIN_REG(MX51_PAD_EIM_CS1, 0x478, 0x0e4, 0, 0x000, 0), /* MX51_PAD_EIM_CS1__EIM_CS1 */ - IMX_PIN_REG(MX51_PAD_EIM_CS1, 0x478, 0x0e4, 1, 0x000, 0), /* MX51_PAD_EIM_CS1__GPIO2_26 */ - IMX_PIN_REG(MX51_PAD_EIM_CS2, 0x47c, 0x0e8, 6, 0x8d8, 1), /* MX51_PAD_EIM_CS2__AUD5_TXD */ - IMX_PIN_REG(MX51_PAD_EIM_CS2, 0x47c, 0x0e8, 5, 0x000, 0), /* MX51_PAD_EIM_CS2__CSI1_D4 */ - IMX_PIN_REG(MX51_PAD_EIM_CS2, 0x47c, 0x0e8, 0, 0x000, 0), /* MX51_PAD_EIM_CS2__EIM_CS2 */ - IMX_PIN_REG(MX51_PAD_EIM_CS2, 0x47c, 0x0e8, 3, 0x960, 0), /* MX51_PAD_EIM_CS2__FEC_RDATA2 */ - IMX_PIN_REG(MX51_PAD_EIM_CS2, 0x47c, 0x0e8, 1, 0x000, 0), /* MX51_PAD_EIM_CS2__GPIO2_27 */ - IMX_PIN_REG(MX51_PAD_EIM_CS2, 0x47c, 0x0e8, 2, 0x000, 0), /* MX51_PAD_EIM_CS2__USBOTG_STP */ - IMX_PIN_REG(MX51_PAD_EIM_CS3, 0x480, 0x0ec, 6, 0x8d4, 1), /* MX51_PAD_EIM_CS3__AUD5_RXD */ - IMX_PIN_REG(MX51_PAD_EIM_CS3, 0x480, 0x0ec, 5, 0x000, 0), /* MX51_PAD_EIM_CS3__CSI1_D5 */ - IMX_PIN_REG(MX51_PAD_EIM_CS3, 0x480, 0x0ec, 0, 0x000, 0), /* MX51_PAD_EIM_CS3__EIM_CS3 */ - IMX_PIN_REG(MX51_PAD_EIM_CS3, 0x480, 0x0ec, 3, 0x964, 0), /* MX51_PAD_EIM_CS3__FEC_RDATA3 */ - IMX_PIN_REG(MX51_PAD_EIM_CS3, 0x480, 0x0ec, 1, 0x000, 0), /* MX51_PAD_EIM_CS3__GPIO2_28 */ - IMX_PIN_REG(MX51_PAD_EIM_CS3, 0x480, 0x0ec, 2, 0x000, 0), /* MX51_PAD_EIM_CS3__USBOTG_NXT */ - IMX_PIN_REG(MX51_PAD_EIM_CS4, 0x484, 0x0f0, 6, 0x8e4, 1), /* MX51_PAD_EIM_CS4__AUD5_TXC */ - IMX_PIN_REG(MX51_PAD_EIM_CS4, 0x484, 0x0f0, 5, 0x000, 0), /* MX51_PAD_EIM_CS4__CSI1_D6 */ - IMX_PIN_REG(MX51_PAD_EIM_CS4, 0x484, 0x0f0, 0, 0x000, 0), /* MX51_PAD_EIM_CS4__EIM_CS4 */ - IMX_PIN_REG(MX51_PAD_EIM_CS4, 0x484, 0x0f0, 3, 0x970, 0), /* MX51_PAD_EIM_CS4__FEC_RX_ER */ - IMX_PIN_REG(MX51_PAD_EIM_CS4, 0x484, 0x0f0, 1, 0x000, 0), /* MX51_PAD_EIM_CS4__GPIO2_29 */ - IMX_PIN_REG(MX51_PAD_EIM_CS4, 0x484, 0x0f0, 2, 0x000, 0), /* MX51_PAD_EIM_CS4__USBOTG_CLK */ - IMX_PIN_REG(MX51_PAD_EIM_CS5, 0x488, 0x0f4, 6, 0x8e8, 1), /* MX51_PAD_EIM_CS5__AUD5_TXFS */ - IMX_PIN_REG(MX51_PAD_EIM_CS5, 0x488, 0x0f4, 5, 0x000, 0), /* MX51_PAD_EIM_CS5__CSI1_D7 */ - IMX_PIN_REG(MX51_PAD_EIM_CS5, 0x488, 0x0f4, 4, 0x904, 0), /* MX51_PAD_EIM_CS5__DISP1_EXT_CLK */ - IMX_PIN_REG(MX51_PAD_EIM_CS5, 0x488, 0x0f4, 0, 0x000, 0), /* MX51_PAD_EIM_CS5__EIM_CS5 */ - IMX_PIN_REG(MX51_PAD_EIM_CS5, 0x488, 0x0f4, 3, 0x950, 0), /* MX51_PAD_EIM_CS5__FEC_CRS */ - IMX_PIN_REG(MX51_PAD_EIM_CS5, 0x488, 0x0f4, 1, 0x000, 0), /* MX51_PAD_EIM_CS5__GPIO2_30 */ - IMX_PIN_REG(MX51_PAD_EIM_CS5, 0x488, 0x0f4, 2, 0x000, 0), /* MX51_PAD_EIM_CS5__USBOTG_DIR */ - IMX_PIN_REG(MX51_PAD_EIM_DTACK, 0x48c, 0x0f8, 0, 0x000, 0), /* MX51_PAD_EIM_DTACK__EIM_DTACK */ - IMX_PIN_REG(MX51_PAD_EIM_DTACK, 0x48c, 0x0f8, 1, 0x000, 0), /* MX51_PAD_EIM_DTACK__GPIO2_31 */ - IMX_PIN_REG(MX51_PAD_EIM_LBA, 0x494, 0x0fc, 0, 0x000, 0), /* MX51_PAD_EIM_LBA__EIM_LBA */ - IMX_PIN_REG(MX51_PAD_EIM_LBA, 0x494, 0x0fc, 1, 0x978, 0), /* MX51_PAD_EIM_LBA__GPIO3_1 */ - IMX_PIN_REG(MX51_PAD_EIM_CRE, 0x4a0, 0x100, 0, 0x000, 0), /* MX51_PAD_EIM_CRE__EIM_CRE */ - IMX_PIN_REG(MX51_PAD_EIM_CRE, 0x4a0, 0x100, 1, 0x97c, 0), /* MX51_PAD_EIM_CRE__GPIO3_2 */ - IMX_PIN_REG(MX51_PAD_DRAM_CS1, 0x4d0, 0x104, 0, 0x000, 0), /* MX51_PAD_DRAM_CS1__DRAM_CS1 */ - IMX_PIN_REG(MX51_PAD_NANDF_WE_B, 0x4e4, 0x108, 3, 0x980, 0), /* MX51_PAD_NANDF_WE_B__GPIO3_3 */ - IMX_PIN_REG(MX51_PAD_NANDF_WE_B, 0x4e4, 0x108, 0, 0x000, 0), /* MX51_PAD_NANDF_WE_B__NANDF_WE_B */ - IMX_PIN_REG(MX51_PAD_NANDF_WE_B, 0x4e4, 0x108, 1, 0x000, 0), /* MX51_PAD_NANDF_WE_B__PATA_DIOW */ - IMX_PIN_REG(MX51_PAD_NANDF_WE_B, 0x4e4, 0x108, 2, 0x93c, 0), /* MX51_PAD_NANDF_WE_B__SD3_DATA0 */ - IMX_PIN_REG(MX51_PAD_NANDF_RE_B, 0x4e8, 0x10c, 3, 0x984, 0), /* MX51_PAD_NANDF_RE_B__GPIO3_4 */ - IMX_PIN_REG(MX51_PAD_NANDF_RE_B, 0x4e8, 0x10c, 0, 0x000, 0), /* MX51_PAD_NANDF_RE_B__NANDF_RE_B */ - IMX_PIN_REG(MX51_PAD_NANDF_RE_B, 0x4e8, 0x10c, 1, 0x000, 0), /* MX51_PAD_NANDF_RE_B__PATA_DIOR */ - IMX_PIN_REG(MX51_PAD_NANDF_RE_B, 0x4e8, 0x10c, 2, 0x940, 0), /* MX51_PAD_NANDF_RE_B__SD3_DATA1 */ - IMX_PIN_REG(MX51_PAD_NANDF_ALE, 0x4ec, 0x110, 3, 0x988, 0), /* MX51_PAD_NANDF_ALE__GPIO3_5 */ - IMX_PIN_REG(MX51_PAD_NANDF_ALE, 0x4ec, 0x110, 0, 0x000, 0), /* MX51_PAD_NANDF_ALE__NANDF_ALE */ - IMX_PIN_REG(MX51_PAD_NANDF_ALE, 0x4ec, 0x110, 1, 0x000, 0), /* MX51_PAD_NANDF_ALE__PATA_BUFFER_EN */ - IMX_PIN_REG(MX51_PAD_NANDF_CLE, 0x4f0, 0x114, 3, 0x98c, 0), /* MX51_PAD_NANDF_CLE__GPIO3_6 */ - IMX_PIN_REG(MX51_PAD_NANDF_CLE, 0x4f0, 0x114, 0, 0x000, 0), /* MX51_PAD_NANDF_CLE__NANDF_CLE */ - IMX_PIN_REG(MX51_PAD_NANDF_CLE, 0x4f0, 0x114, 1, 0x000, 0), /* MX51_PAD_NANDF_CLE__PATA_RESET_B */ - IMX_PIN_REG(MX51_PAD_NANDF_WP_B, 0x4f4, 0x118, 3, 0x990, 0), /* MX51_PAD_NANDF_WP_B__GPIO3_7 */ - IMX_PIN_REG(MX51_PAD_NANDF_WP_B, 0x4f4, 0x118, 0, 0x000, 0), /* MX51_PAD_NANDF_WP_B__NANDF_WP_B */ - IMX_PIN_REG(MX51_PAD_NANDF_WP_B, 0x4f4, 0x118, 1, 0x000, 0), /* MX51_PAD_NANDF_WP_B__PATA_DMACK */ - IMX_PIN_REG(MX51_PAD_NANDF_WP_B, 0x4f4, 0x118, 2, 0x944, 0), /* MX51_PAD_NANDF_WP_B__SD3_DATA2 */ - IMX_PIN_REG(MX51_PAD_NANDF_RB0, 0x4f8, 0x11c, 5, 0x930, 0), /* MX51_PAD_NANDF_RB0__ECSPI2_SS1 */ - IMX_PIN_REG(MX51_PAD_NANDF_RB0, 0x4f8, 0x11c, 3, 0x994, 0), /* MX51_PAD_NANDF_RB0__GPIO3_8 */ - IMX_PIN_REG(MX51_PAD_NANDF_RB0, 0x4f8, 0x11c, 0, 0x000, 0), /* MX51_PAD_NANDF_RB0__NANDF_RB0 */ - IMX_PIN_REG(MX51_PAD_NANDF_RB0, 0x4f8, 0x11c, 1, 0x000, 0), /* MX51_PAD_NANDF_RB0__PATA_DMARQ */ - IMX_PIN_REG(MX51_PAD_NANDF_RB0, 0x4f8, 0x11c, 2, 0x948, 0), /* MX51_PAD_NANDF_RB0__SD3_DATA3 */ - IMX_PIN_REG(MX51_PAD_NANDF_RB1, 0x4fc, 0x120, 6, 0x91c, 0), /* MX51_PAD_NANDF_RB1__CSPI_MOSI */ - IMX_PIN_REG(MX51_PAD_NANDF_RB1, 0x4fc, 0x120, 2, 0x000, 0), /* MX51_PAD_NANDF_RB1__ECSPI2_RDY */ - IMX_PIN_REG(MX51_PAD_NANDF_RB1, 0x4fc, 0x120, 3, 0x000, 0), /* MX51_PAD_NANDF_RB1__GPIO3_9 */ - IMX_PIN_REG(MX51_PAD_NANDF_RB1, 0x4fc, 0x120, 0, 0x000, 0), /* MX51_PAD_NANDF_RB1__NANDF_RB1 */ - IMX_PIN_REG(MX51_PAD_NANDF_RB1, 0x4fc, 0x120, 1, 0x000, 0), /* MX51_PAD_NANDF_RB1__PATA_IORDY */ - IMX_PIN_REG(MX51_PAD_NANDF_RB1, 0x4fc, 0x120, 5, 0x000, 0), /* MX51_PAD_NANDF_RB1__SD4_CMD */ - IMX_PIN_REG(MX51_PAD_NANDF_RB2, 0x500, 0x124, 5, 0x9a8, 0), /* MX51_PAD_NANDF_RB2__DISP2_WAIT */ - IMX_PIN_REG(MX51_PAD_NANDF_RB2, 0x500, 0x124, 2, 0x000, 0), /* MX51_PAD_NANDF_RB2__ECSPI2_SCLK */ - IMX_PIN_REG(MX51_PAD_NANDF_RB2, 0x500, 0x124, 1, 0x94c, 0), /* MX51_PAD_NANDF_RB2__FEC_COL */ - IMX_PIN_REG(MX51_PAD_NANDF_RB2, 0x500, 0x124, 3, 0x000, 0), /* MX51_PAD_NANDF_RB2__GPIO3_10 */ - IMX_PIN_REG(MX51_PAD_NANDF_RB2, 0x500, 0x124, 0, 0x000, 0), /* MX51_PAD_NANDF_RB2__NANDF_RB2 */ - IMX_PIN_REG(MX51_PAD_NANDF_RB2, 0x500, 0x124, 7, 0x000, 0), /* MX51_PAD_NANDF_RB2__USBH3_H3_DP */ - IMX_PIN_REG(MX51_PAD_NANDF_RB2, 0x500, 0x124, 6, 0xa20, 0), /* MX51_PAD_NANDF_RB2__USBH3_NXT */ - IMX_PIN_REG(MX51_PAD_NANDF_RB3, 0x504, 0x128, 5, 0x000, 0), /* MX51_PAD_NANDF_RB3__DISP1_WAIT */ - IMX_PIN_REG(MX51_PAD_NANDF_RB3, 0x504, 0x128, 2, 0x000, 0), /* MX51_PAD_NANDF_RB3__ECSPI2_MISO */ - IMX_PIN_REG(MX51_PAD_NANDF_RB3, 0x504, 0x128, 1, 0x968, 0), /* MX51_PAD_NANDF_RB3__FEC_RX_CLK */ - IMX_PIN_REG(MX51_PAD_NANDF_RB3, 0x504, 0x128, 3, 0x000, 0), /* MX51_PAD_NANDF_RB3__GPIO3_11 */ - IMX_PIN_REG(MX51_PAD_NANDF_RB3, 0x504, 0x128, 0, 0x000, 0), /* MX51_PAD_NANDF_RB3__NANDF_RB3 */ - IMX_PIN_REG(MX51_PAD_NANDF_RB3, 0x504, 0x128, 6, 0x9f8, 0), /* MX51_PAD_NANDF_RB3__USBH3_CLK */ - IMX_PIN_REG(MX51_PAD_NANDF_RB3, 0x504, 0x128, 7, 0x000, 0), /* MX51_PAD_NANDF_RB3__USBH3_H3_DM */ - IMX_PIN_REG(MX51_PAD_GPIO_NAND, 0x514, 0x12c, 0, 0x998, 0), /* MX51_PAD_GPIO_NAND__GPIO_NAND */ - IMX_PIN_REG(MX51_PAD_GPIO_NAND, 0x514, 0x12c, 1, 0x000, 0), /* MX51_PAD_GPIO_NAND__PATA_INTRQ */ - IMX_PIN_REG(MX51_PAD_NANDF_CS0, 0x518, 0x130, 3, 0x000, 0), /* MX51_PAD_NANDF_CS0__GPIO3_16 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS0, 0x518, 0x130, 0, 0x000, 0), /* MX51_PAD_NANDF_CS0__NANDF_CS0 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS1, 0x51c, 0x134, 3, 0x000, 0), /* MX51_PAD_NANDF_CS1__GPIO3_17 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS1, 0x51c, 0x134, 0, 0x000, 0), /* MX51_PAD_NANDF_CS1__NANDF_CS1 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS2, 0x520, 0x138, 6, 0x914, 0), /* MX51_PAD_NANDF_CS2__CSPI_SCLK */ - IMX_PIN_REG(MX51_PAD_NANDF_CS2, 0x520, 0x138, 2, 0x000, 0), /* MX51_PAD_NANDF_CS2__FEC_TX_ER */ - IMX_PIN_REG(MX51_PAD_NANDF_CS2, 0x520, 0x138, 3, 0x000, 0), /* MX51_PAD_NANDF_CS2__GPIO3_18 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS2, 0x520, 0x138, 0, 0x000, 0), /* MX51_PAD_NANDF_CS2__NANDF_CS2 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS2, 0x520, 0x138, 1, 0x000, 0), /* MX51_PAD_NANDF_CS2__PATA_CS_0 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS2, 0x520, 0x138, 5, 0x000, 0), /* MX51_PAD_NANDF_CS2__SD4_CLK */ - IMX_PIN_REG(MX51_PAD_NANDF_CS2, 0x520, 0x138, 7, 0x000, 0), /* MX51_PAD_NANDF_CS2__USBH3_H1_DP */ - IMX_PIN_REG(MX51_PAD_NANDF_CS3, 0x524, 0x13c, 2, 0x000, 0), /* MX51_PAD_NANDF_CS3__FEC_MDC */ - IMX_PIN_REG(MX51_PAD_NANDF_CS3, 0x524, 0x13c, 3, 0x000, 0), /* MX51_PAD_NANDF_CS3__GPIO3_19 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS3, 0x524, 0x13c, 0, 0x000, 0), /* MX51_PAD_NANDF_CS3__NANDF_CS3 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS3, 0x524, 0x13c, 1, 0x000, 0), /* MX51_PAD_NANDF_CS3__PATA_CS_1 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS3, 0x524, 0x13c, 5, 0x000, 0), /* MX51_PAD_NANDF_CS3__SD4_DAT0 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS3, 0x524, 0x13c, 7, 0x000, 0), /* MX51_PAD_NANDF_CS3__USBH3_H1_DM */ - IMX_PIN_REG(MX51_PAD_NANDF_CS4, 0x528, 0x140, 2, 0x000, 0), /* MX51_PAD_NANDF_CS4__FEC_TDATA1 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS4, 0x528, 0x140, 3, 0x000, 0), /* MX51_PAD_NANDF_CS4__GPIO3_20 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS4, 0x528, 0x140, 0, 0x000, 0), /* MX51_PAD_NANDF_CS4__NANDF_CS4 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS4, 0x528, 0x140, 1, 0x000, 0), /* MX51_PAD_NANDF_CS4__PATA_DA_0 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS4, 0x528, 0x140, 5, 0x000, 0), /* MX51_PAD_NANDF_CS4__SD4_DAT1 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS4, 0x528, 0x140, 7, 0xa24, 0), /* MX51_PAD_NANDF_CS4__USBH3_STP */ - IMX_PIN_REG(MX51_PAD_NANDF_CS5, 0x52c, 0x144, 2, 0x000, 0), /* MX51_PAD_NANDF_CS5__FEC_TDATA2 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS5, 0x52c, 0x144, 3, 0x000, 0), /* MX51_PAD_NANDF_CS5__GPIO3_21 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS5, 0x52c, 0x144, 0, 0x000, 0), /* MX51_PAD_NANDF_CS5__NANDF_CS5 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS5, 0x52c, 0x144, 1, 0x000, 0), /* MX51_PAD_NANDF_CS5__PATA_DA_1 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS5, 0x52c, 0x144, 5, 0x000, 0), /* MX51_PAD_NANDF_CS5__SD4_DAT2 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS5, 0x52c, 0x144, 7, 0xa1c, 0), /* MX51_PAD_NANDF_CS5__USBH3_DIR */ - IMX_PIN_REG(MX51_PAD_NANDF_CS6, 0x530, 0x148, 7, 0x928, 0), /* MX51_PAD_NANDF_CS6__CSPI_SS3 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS6, 0x530, 0x148, 2, 0x000, 0), /* MX51_PAD_NANDF_CS6__FEC_TDATA3 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS6, 0x530, 0x148, 3, 0x000, 0), /* MX51_PAD_NANDF_CS6__GPIO3_22 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS6, 0x530, 0x148, 0, 0x000, 0), /* MX51_PAD_NANDF_CS6__NANDF_CS6 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS6, 0x530, 0x148, 1, 0x000, 0), /* MX51_PAD_NANDF_CS6__PATA_DA_2 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS6, 0x530, 0x148, 5, 0x000, 0), /* MX51_PAD_NANDF_CS6__SD4_DAT3 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS7, 0x534, 0x14c, 1, 0x000, 0), /* MX51_PAD_NANDF_CS7__FEC_TX_EN */ - IMX_PIN_REG(MX51_PAD_NANDF_CS7, 0x534, 0x14c, 3, 0x000, 0), /* MX51_PAD_NANDF_CS7__GPIO3_23 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS7, 0x534, 0x14c, 0, 0x000, 0), /* MX51_PAD_NANDF_CS7__NANDF_CS7 */ - IMX_PIN_REG(MX51_PAD_NANDF_CS7, 0x534, 0x14c, 5, 0x000, 0), /* MX51_PAD_NANDF_CS7__SD3_CLK */ - IMX_PIN_REG(MX51_PAD_NANDF_RDY_INT, 0x538, 0x150, 2, 0x000, 0), /* MX51_PAD_NANDF_RDY_INT__ECSPI2_SS0 */ - IMX_PIN_REG(MX51_PAD_NANDF_RDY_INT, 0x538, 0x150, 1, 0x974, 0), /* MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK */ - IMX_PIN_REG(MX51_PAD_NANDF_RDY_INT, 0x538, 0x150, 3, 0x000, 0), /* MX51_PAD_NANDF_RDY_INT__GPIO3_24 */ - IMX_PIN_REG(MX51_PAD_NANDF_RDY_INT, 0x538, 0x150, 0, 0x938, 0), /* MX51_PAD_NANDF_RDY_INT__NANDF_RDY_INT */ - IMX_PIN_REG(MX51_PAD_NANDF_RDY_INT, 0x538, 0x150, 5, 0x000, 0), /* MX51_PAD_NANDF_RDY_INT__SD3_CMD */ - IMX_PIN_REG(MX51_PAD_NANDF_D15, 0x53c, 0x154, 2, 0x000, 0), /* MX51_PAD_NANDF_D15__ECSPI2_MOSI */ - IMX_PIN_REG(MX51_PAD_NANDF_D15, 0x53c, 0x154, 3, 0x000, 0), /* MX51_PAD_NANDF_D15__GPIO3_25 */ - IMX_PIN_REG(MX51_PAD_NANDF_D15, 0x53c, 0x154, 0, 0x000, 0), /* MX51_PAD_NANDF_D15__NANDF_D15 */ - IMX_PIN_REG(MX51_PAD_NANDF_D15, 0x53c, 0x154, 1, 0x000, 0), /* MX51_PAD_NANDF_D15__PATA_DATA15 */ - IMX_PIN_REG(MX51_PAD_NANDF_D15, 0x53c, 0x154, 5, 0x000, 0), /* MX51_PAD_NANDF_D15__SD3_DAT7 */ - IMX_PIN_REG(MX51_PAD_NANDF_D14, 0x540, 0x158, 2, 0x934, 0), /* MX51_PAD_NANDF_D14__ECSPI2_SS3 */ - IMX_PIN_REG(MX51_PAD_NANDF_D14, 0x540, 0x158, 3, 0x000, 0), /* MX51_PAD_NANDF_D14__GPIO3_26 */ - IMX_PIN_REG(MX51_PAD_NANDF_D14, 0x540, 0x158, 0, 0x000, 0), /* MX51_PAD_NANDF_D14__NANDF_D14 */ - IMX_PIN_REG(MX51_PAD_NANDF_D14, 0x540, 0x158, 1, 0x000, 0), /* MX51_PAD_NANDF_D14__PATA_DATA14 */ - IMX_PIN_REG(MX51_PAD_NANDF_D14, 0x540, 0x158, 5, 0x000, 0), /* MX51_PAD_NANDF_D14__SD3_DAT6 */ - IMX_PIN_REG(MX51_PAD_NANDF_D13, 0x544, 0x15c, 2, 0x000, 0), /* MX51_PAD_NANDF_D13__ECSPI2_SS2 */ - IMX_PIN_REG(MX51_PAD_NANDF_D13, 0x544, 0x15c, 3, 0x000, 0), /* MX51_PAD_NANDF_D13__GPIO3_27 */ - IMX_PIN_REG(MX51_PAD_NANDF_D13, 0x544, 0x15c, 0, 0x000, 0), /* MX51_PAD_NANDF_D13__NANDF_D13 */ - IMX_PIN_REG(MX51_PAD_NANDF_D13, 0x544, 0x15c, 1, 0x000, 0), /* MX51_PAD_NANDF_D13__PATA_DATA13 */ - IMX_PIN_REG(MX51_PAD_NANDF_D13, 0x544, 0x15c, 5, 0x000, 0), /* MX51_PAD_NANDF_D13__SD3_DAT5 */ - IMX_PIN_REG(MX51_PAD_NANDF_D12, 0x548, 0x160, 2, 0x930, 1), /* MX51_PAD_NANDF_D12__ECSPI2_SS1 */ - IMX_PIN_REG(MX51_PAD_NANDF_D12, 0x548, 0x160, 3, 0x000, 0), /* MX51_PAD_NANDF_D12__GPIO3_28 */ - IMX_PIN_REG(MX51_PAD_NANDF_D12, 0x548, 0x160, 0, 0x000, 0), /* MX51_PAD_NANDF_D12__NANDF_D12 */ - IMX_PIN_REG(MX51_PAD_NANDF_D12, 0x548, 0x160, 1, 0x000, 0), /* MX51_PAD_NANDF_D12__PATA_DATA12 */ - IMX_PIN_REG(MX51_PAD_NANDF_D12, 0x548, 0x160, 5, 0x000, 0), /* MX51_PAD_NANDF_D12__SD3_DAT4 */ - IMX_PIN_REG(MX51_PAD_NANDF_D11, 0x54c, 0x164, 2, 0x96c, 0), /* MX51_PAD_NANDF_D11__FEC_RX_DV */ - IMX_PIN_REG(MX51_PAD_NANDF_D11, 0x54c, 0x164, 3, 0x000, 0), /* MX51_PAD_NANDF_D11__GPIO3_29 */ - IMX_PIN_REG(MX51_PAD_NANDF_D11, 0x54c, 0x164, 0, 0x000, 0), /* MX51_PAD_NANDF_D11__NANDF_D11 */ - IMX_PIN_REG(MX51_PAD_NANDF_D11, 0x54c, 0x164, 1, 0x000, 0), /* MX51_PAD_NANDF_D11__PATA_DATA11 */ - IMX_PIN_REG(MX51_PAD_NANDF_D11, 0x54c, 0x164, 5, 0x948, 1), /* MX51_PAD_NANDF_D11__SD3_DATA3 */ - IMX_PIN_REG(MX51_PAD_NANDF_D10, 0x550, 0x168, 3, 0x000, 0), /* MX51_PAD_NANDF_D10__GPIO3_30 */ - IMX_PIN_REG(MX51_PAD_NANDF_D10, 0x550, 0x168, 0, 0x000, 0), /* MX51_PAD_NANDF_D10__NANDF_D10 */ - IMX_PIN_REG(MX51_PAD_NANDF_D10, 0x550, 0x168, 1, 0x000, 0), /* MX51_PAD_NANDF_D10__PATA_DATA10 */ - IMX_PIN_REG(MX51_PAD_NANDF_D10, 0x550, 0x168, 5, 0x944, 1), /* MX51_PAD_NANDF_D10__SD3_DATA2 */ - IMX_PIN_REG(MX51_PAD_NANDF_D9, 0x554, 0x16c, 2, 0x958, 0), /* MX51_PAD_NANDF_D9__FEC_RDATA0 */ - IMX_PIN_REG(MX51_PAD_NANDF_D9, 0x554, 0x16c, 3, 0x000, 0), /* MX51_PAD_NANDF_D9__GPIO3_31 */ - IMX_PIN_REG(MX51_PAD_NANDF_D9, 0x554, 0x16c, 0, 0x000, 0), /* MX51_PAD_NANDF_D9__NANDF_D9 */ - IMX_PIN_REG(MX51_PAD_NANDF_D9, 0x554, 0x16c, 1, 0x000, 0), /* MX51_PAD_NANDF_D9__PATA_DATA9 */ - IMX_PIN_REG(MX51_PAD_NANDF_D9, 0x554, 0x16c, 5, 0x940, 1), /* MX51_PAD_NANDF_D9__SD3_DATA1 */ - IMX_PIN_REG(MX51_PAD_NANDF_D8, 0x558, 0x170, 2, 0x000, 0), /* MX51_PAD_NANDF_D8__FEC_TDATA0 */ - IMX_PIN_REG(MX51_PAD_NANDF_D8, 0x558, 0x170, 3, 0x000, 0), /* MX51_PAD_NANDF_D8__GPIO4_0 */ - IMX_PIN_REG(MX51_PAD_NANDF_D8, 0x558, 0x170, 0, 0x000, 0), /* MX51_PAD_NANDF_D8__NANDF_D8 */ - IMX_PIN_REG(MX51_PAD_NANDF_D8, 0x558, 0x170, 1, 0x000, 0), /* MX51_PAD_NANDF_D8__PATA_DATA8 */ - IMX_PIN_REG(MX51_PAD_NANDF_D8, 0x558, 0x170, 5, 0x93c, 1), /* MX51_PAD_NANDF_D8__SD3_DATA0 */ - IMX_PIN_REG(MX51_PAD_NANDF_D7, 0x55c, 0x174, 3, 0x000, 0), /* MX51_PAD_NANDF_D7__GPIO4_1 */ - IMX_PIN_REG(MX51_PAD_NANDF_D7, 0x55c, 0x174, 0, 0x000, 0), /* MX51_PAD_NANDF_D7__NANDF_D7 */ - IMX_PIN_REG(MX51_PAD_NANDF_D7, 0x55c, 0x174, 1, 0x000, 0), /* MX51_PAD_NANDF_D7__PATA_DATA7 */ - IMX_PIN_REG(MX51_PAD_NANDF_D7, 0x55c, 0x174, 5, 0x9fc, 0), /* MX51_PAD_NANDF_D7__USBH3_DATA0 */ - IMX_PIN_REG(MX51_PAD_NANDF_D6, 0x560, 0x178, 3, 0x000, 0), /* MX51_PAD_NANDF_D6__GPIO4_2 */ - IMX_PIN_REG(MX51_PAD_NANDF_D6, 0x560, 0x178, 0, 0x000, 0), /* MX51_PAD_NANDF_D6__NANDF_D6 */ - IMX_PIN_REG(MX51_PAD_NANDF_D6, 0x560, 0x178, 1, 0x000, 0), /* MX51_PAD_NANDF_D6__PATA_DATA6 */ - IMX_PIN_REG(MX51_PAD_NANDF_D6, 0x560, 0x178, 2, 0x000, 0), /* MX51_PAD_NANDF_D6__SD4_LCTL */ - IMX_PIN_REG(MX51_PAD_NANDF_D6, 0x560, 0x178, 5, 0xa00, 0), /* MX51_PAD_NANDF_D6__USBH3_DATA1 */ - IMX_PIN_REG(MX51_PAD_NANDF_D5, 0x564, 0x17c, 3, 0x000, 0), /* MX51_PAD_NANDF_D5__GPIO4_3 */ - IMX_PIN_REG(MX51_PAD_NANDF_D5, 0x564, 0x17c, 0, 0x000, 0), /* MX51_PAD_NANDF_D5__NANDF_D5 */ - IMX_PIN_REG(MX51_PAD_NANDF_D5, 0x564, 0x17c, 1, 0x000, 0), /* MX51_PAD_NANDF_D5__PATA_DATA5 */ - IMX_PIN_REG(MX51_PAD_NANDF_D5, 0x564, 0x17c, 2, 0x000, 0), /* MX51_PAD_NANDF_D5__SD4_WP */ - IMX_PIN_REG(MX51_PAD_NANDF_D5, 0x564, 0x17c, 5, 0xa04, 0), /* MX51_PAD_NANDF_D5__USBH3_DATA2 */ - IMX_PIN_REG(MX51_PAD_NANDF_D4, 0x568, 0x180, 3, 0x000, 0), /* MX51_PAD_NANDF_D4__GPIO4_4 */ - IMX_PIN_REG(MX51_PAD_NANDF_D4, 0x568, 0x180, 0, 0x000, 0), /* MX51_PAD_NANDF_D4__NANDF_D4 */ - IMX_PIN_REG(MX51_PAD_NANDF_D4, 0x568, 0x180, 1, 0x000, 0), /* MX51_PAD_NANDF_D4__PATA_DATA4 */ - IMX_PIN_REG(MX51_PAD_NANDF_D4, 0x568, 0x180, 2, 0x000, 0), /* MX51_PAD_NANDF_D4__SD4_CD */ - IMX_PIN_REG(MX51_PAD_NANDF_D4, 0x568, 0x180, 5, 0xa08, 0), /* MX51_PAD_NANDF_D4__USBH3_DATA3 */ - IMX_PIN_REG(MX51_PAD_NANDF_D3, 0x56c, 0x184, 3, 0x000, 0), /* MX51_PAD_NANDF_D3__GPIO4_5 */ - IMX_PIN_REG(MX51_PAD_NANDF_D3, 0x56c, 0x184, 0, 0x000, 0), /* MX51_PAD_NANDF_D3__NANDF_D3 */ - IMX_PIN_REG(MX51_PAD_NANDF_D3, 0x56c, 0x184, 1, 0x000, 0), /* MX51_PAD_NANDF_D3__PATA_DATA3 */ - IMX_PIN_REG(MX51_PAD_NANDF_D3, 0x56c, 0x184, 2, 0x000, 0), /* MX51_PAD_NANDF_D3__SD4_DAT4 */ - IMX_PIN_REG(MX51_PAD_NANDF_D3, 0x56c, 0x184, 5, 0xa0c, 0), /* MX51_PAD_NANDF_D3__USBH3_DATA4 */ - IMX_PIN_REG(MX51_PAD_NANDF_D2, 0x570, 0x188, 3, 0x000, 0), /* MX51_PAD_NANDF_D2__GPIO4_6 */ - IMX_PIN_REG(MX51_PAD_NANDF_D2, 0x570, 0x188, 0, 0x000, 0), /* MX51_PAD_NANDF_D2__NANDF_D2 */ - IMX_PIN_REG(MX51_PAD_NANDF_D2, 0x570, 0x188, 1, 0x000, 0), /* MX51_PAD_NANDF_D2__PATA_DATA2 */ - IMX_PIN_REG(MX51_PAD_NANDF_D2, 0x570, 0x188, 2, 0x000, 0), /* MX51_PAD_NANDF_D2__SD4_DAT5 */ - IMX_PIN_REG(MX51_PAD_NANDF_D2, 0x570, 0x188, 5, 0xa10, 0), /* MX51_PAD_NANDF_D2__USBH3_DATA5 */ - IMX_PIN_REG(MX51_PAD_NANDF_D1, 0x574, 0x18c, 3, 0x000, 0), /* MX51_PAD_NANDF_D1__GPIO4_7 */ - IMX_PIN_REG(MX51_PAD_NANDF_D1, 0x574, 0x18c, 0, 0x000, 0), /* MX51_PAD_NANDF_D1__NANDF_D1 */ - IMX_PIN_REG(MX51_PAD_NANDF_D1, 0x574, 0x18c, 1, 0x000, 0), /* MX51_PAD_NANDF_D1__PATA_DATA1 */ - IMX_PIN_REG(MX51_PAD_NANDF_D1, 0x574, 0x18c, 2, 0x000, 0), /* MX51_PAD_NANDF_D1__SD4_DAT6 */ - IMX_PIN_REG(MX51_PAD_NANDF_D1, 0x574, 0x18c, 5, 0xa14, 0), /* MX51_PAD_NANDF_D1__USBH3_DATA6 */ - IMX_PIN_REG(MX51_PAD_NANDF_D0, 0x578, 0x190, 3, 0x000, 0), /* MX51_PAD_NANDF_D0__GPIO4_8 */ - IMX_PIN_REG(MX51_PAD_NANDF_D0, 0x578, 0x190, 0, 0x000, 0), /* MX51_PAD_NANDF_D0__NANDF_D0 */ - IMX_PIN_REG(MX51_PAD_NANDF_D0, 0x578, 0x190, 1, 0x000, 0), /* MX51_PAD_NANDF_D0__PATA_DATA0 */ - IMX_PIN_REG(MX51_PAD_NANDF_D0, 0x578, 0x190, 2, 0x000, 0), /* MX51_PAD_NANDF_D0__SD4_DAT7 */ - IMX_PIN_REG(MX51_PAD_NANDF_D0, 0x578, 0x190, 5, 0xa18, 0), /* MX51_PAD_NANDF_D0__USBH3_DATA7 */ - IMX_PIN_REG(MX51_PAD_CSI1_D8, 0x57c, 0x194, 0, 0x000, 0), /* MX51_PAD_CSI1_D8__CSI1_D8 */ - IMX_PIN_REG(MX51_PAD_CSI1_D8, 0x57c, 0x194, 3, 0x998, 1), /* MX51_PAD_CSI1_D8__GPIO3_12 */ - IMX_PIN_REG(MX51_PAD_CSI1_D9, 0x580, 0x198, 0, 0x000, 0), /* MX51_PAD_CSI1_D9__CSI1_D9 */ - IMX_PIN_REG(MX51_PAD_CSI1_D9, 0x580, 0x198, 3, 0x000, 0), /* MX51_PAD_CSI1_D9__GPIO3_13 */ - IMX_PIN_REG(MX51_PAD_CSI1_D10, 0x584, 0x19c, 0, 0x000, 0), /* MX51_PAD_CSI1_D10__CSI1_D10 */ - IMX_PIN_REG(MX51_PAD_CSI1_D11, 0x588, 0x1a0, 0, 0x000, 0), /* MX51_PAD_CSI1_D11__CSI1_D11 */ - IMX_PIN_REG(MX51_PAD_CSI1_D12, 0x58c, 0x1a4, 0, 0x000, 0), /* MX51_PAD_CSI1_D12__CSI1_D12 */ - IMX_PIN_REG(MX51_PAD_CSI1_D13, 0x590, 0x1a8, 0, 0x000, 0), /* MX51_PAD_CSI1_D13__CSI1_D13 */ - IMX_PIN_REG(MX51_PAD_CSI1_D14, 0x594, 0x1ac, 0, 0x000, 0), /* MX51_PAD_CSI1_D14__CSI1_D14 */ - IMX_PIN_REG(MX51_PAD_CSI1_D15, 0x598, 0x1b0, 0, 0x000, 0), /* MX51_PAD_CSI1_D15__CSI1_D15 */ - IMX_PIN_REG(MX51_PAD_CSI1_D16, 0x59c, 0x1b4, 0, 0x000, 0), /* MX51_PAD_CSI1_D16__CSI1_D16 */ - IMX_PIN_REG(MX51_PAD_CSI1_D17, 0x5a0, 0x1b8, 0, 0x000, 0), /* MX51_PAD_CSI1_D17__CSI1_D17 */ - IMX_PIN_REG(MX51_PAD_CSI1_D18, 0x5a4, 0x1bc, 0, 0x000, 0), /* MX51_PAD_CSI1_D18__CSI1_D18 */ - IMX_PIN_REG(MX51_PAD_CSI1_D19, 0x5a8, 0x1c0, 0, 0x000, 0), /* MX51_PAD_CSI1_D19__CSI1_D19 */ - IMX_PIN_REG(MX51_PAD_CSI1_VSYNC, 0x5ac, 0x1c4, 0, 0x000, 0), /* MX51_PAD_CSI1_VSYNC__CSI1_VSYNC */ - IMX_PIN_REG(MX51_PAD_CSI1_VSYNC, 0x5ac, 0x1c4, 3, 0x000, 0), /* MX51_PAD_CSI1_VSYNC__GPIO3_14 */ - IMX_PIN_REG(MX51_PAD_CSI1_HSYNC, 0x5b0, 0x1c8, 0, 0x000, 0), /* MX51_PAD_CSI1_HSYNC__CSI1_HSYNC */ - IMX_PIN_REG(MX51_PAD_CSI1_HSYNC, 0x5b0, 0x1c8, 3, 0x000, 0), /* MX51_PAD_CSI1_HSYNC__GPIO3_15 */ - IMX_PIN_REG(MX51_PAD_CSI1_PIXCLK, 0x5b4, NO_MUX, 0, 0x000, 0), /* MX51_PAD_CSI1_PIXCLK__CSI1_PIXCLK */ - IMX_PIN_REG(MX51_PAD_CSI1_MCLK, 0x5b8, NO_MUX, 0, 0x000, 0), /* MX51_PAD_CSI1_MCLK__CSI1_MCLK */ - IMX_PIN_REG(MX51_PAD_CSI2_D12, 0x5bc, 0x1cc, 0, 0x000, 0), /* MX51_PAD_CSI2_D12__CSI2_D12 */ - IMX_PIN_REG(MX51_PAD_CSI2_D12, 0x5bc, 0x1cc, 3, 0x000, 0), /* MX51_PAD_CSI2_D12__GPIO4_9 */ - IMX_PIN_REG(MX51_PAD_CSI2_D13, 0x5c0, 0x1d0, 0, 0x000, 0), /* MX51_PAD_CSI2_D13__CSI2_D13 */ - IMX_PIN_REG(MX51_PAD_CSI2_D13, 0x5c0, 0x1d0, 3, 0x000, 0), /* MX51_PAD_CSI2_D13__GPIO4_10 */ - IMX_PIN_REG(MX51_PAD_CSI2_D14, 0x5c4, 0x1d4, 0, 0x000, 0), /* MX51_PAD_CSI2_D14__CSI2_D14 */ - IMX_PIN_REG(MX51_PAD_CSI2_D15, 0x5c8, 0x1d8, 0, 0x000, 0), /* MX51_PAD_CSI2_D15__CSI2_D15 */ - IMX_PIN_REG(MX51_PAD_CSI2_D16, 0x5cc, 0x1dc, 0, 0x000, 0), /* MX51_PAD_CSI2_D16__CSI2_D16 */ - IMX_PIN_REG(MX51_PAD_CSI2_D17, 0x5d0, 0x1e0, 0, 0x000, 0), /* MX51_PAD_CSI2_D17__CSI2_D17 */ - IMX_PIN_REG(MX51_PAD_CSI2_D18, 0x5d4, 0x1e4, 0, 0x000, 0), /* MX51_PAD_CSI2_D18__CSI2_D18 */ - IMX_PIN_REG(MX51_PAD_CSI2_D18, 0x5d4, 0x1e4, 3, 0x000, 0), /* MX51_PAD_CSI2_D18__GPIO4_11 */ - IMX_PIN_REG(MX51_PAD_CSI2_D19, 0x5d8, 0x1e8, 0, 0x000, 0), /* MX51_PAD_CSI2_D19__CSI2_D19 */ - IMX_PIN_REG(MX51_PAD_CSI2_D19, 0x5d8, 0x1e8, 3, 0x000, 0), /* MX51_PAD_CSI2_D19__GPIO4_12 */ - IMX_PIN_REG(MX51_PAD_CSI2_VSYNC, 0x5dc, 0x1ec, 0, 0x000, 0), /* MX51_PAD_CSI2_VSYNC__CSI2_VSYNC */ - IMX_PIN_REG(MX51_PAD_CSI2_VSYNC, 0x5dc, 0x1ec, 3, 0x000, 0), /* MX51_PAD_CSI2_VSYNC__GPIO4_13 */ - IMX_PIN_REG(MX51_PAD_CSI2_HSYNC, 0x5e0, 0x1f0, 0, 0x000, 0), /* MX51_PAD_CSI2_HSYNC__CSI2_HSYNC */ - IMX_PIN_REG(MX51_PAD_CSI2_HSYNC, 0x5e0, 0x1f0, 3, 0x000, 0), /* MX51_PAD_CSI2_HSYNC__GPIO4_14 */ - IMX_PIN_REG(MX51_PAD_CSI2_PIXCLK, 0x5e4, 0x1f4, 0, 0x000, 0), /* MX51_PAD_CSI2_PIXCLK__CSI2_PIXCLK */ - IMX_PIN_REG(MX51_PAD_CSI2_PIXCLK, 0x5e4, 0x1f4, 3, 0x000, 0), /* MX51_PAD_CSI2_PIXCLK__GPIO4_15 */ - IMX_PIN_REG(MX51_PAD_I2C1_CLK, 0x5e8, 0x1f8, 3, 0x000, 0), /* MX51_PAD_I2C1_CLK__GPIO4_16 */ - IMX_PIN_REG(MX51_PAD_I2C1_CLK, 0x5e8, 0x1f8, 0, 0x000, 0), /* MX51_PAD_I2C1_CLK__I2C1_CLK */ - IMX_PIN_REG(MX51_PAD_I2C1_DAT, 0x5ec, 0x1fc, 3, 0x000, 0), /* MX51_PAD_I2C1_DAT__GPIO4_17 */ - IMX_PIN_REG(MX51_PAD_I2C1_DAT, 0x5ec, 0x1fc, 0, 0x000, 0), /* MX51_PAD_I2C1_DAT__I2C1_DAT */ - IMX_PIN_REG(MX51_PAD_AUD3_BB_TXD, 0x5f0, 0x200, 0, 0x000, 0), /* MX51_PAD_AUD3_BB_TXD__AUD3_TXD */ - IMX_PIN_REG(MX51_PAD_AUD3_BB_TXD, 0x5f0, 0x200, 3, 0x000, 0), /* MX51_PAD_AUD3_BB_TXD__GPIO4_18 */ - IMX_PIN_REG(MX51_PAD_AUD3_BB_RXD, 0x5f4, 0x204, 0, 0x000, 0), /* MX51_PAD_AUD3_BB_RXD__AUD3_RXD */ - IMX_PIN_REG(MX51_PAD_AUD3_BB_RXD, 0x5f4, 0x204, 3, 0x000, 0), /* MX51_PAD_AUD3_BB_RXD__GPIO4_19 */ - IMX_PIN_REG(MX51_PAD_AUD3_BB_RXD, 0x5f4, 0x204, 1, 0x9f4, 2), /* MX51_PAD_AUD3_BB_RXD__UART3_RXD */ - IMX_PIN_REG(MX51_PAD_AUD3_BB_CK, 0x5f8, 0x208, 0, 0x000, 0), /* MX51_PAD_AUD3_BB_CK__AUD3_TXC */ - IMX_PIN_REG(MX51_PAD_AUD3_BB_CK, 0x5f8, 0x208, 3, 0x000, 0), /* MX51_PAD_AUD3_BB_CK__GPIO4_20 */ - IMX_PIN_REG(MX51_PAD_AUD3_BB_FS, 0x5fc, 0x20c, 0, 0x000, 0), /* MX51_PAD_AUD3_BB_FS__AUD3_TXFS */ - IMX_PIN_REG(MX51_PAD_AUD3_BB_FS, 0x5fc, 0x20c, 3, 0x000, 0), /* MX51_PAD_AUD3_BB_FS__GPIO4_21 */ - IMX_PIN_REG(MX51_PAD_AUD3_BB_FS, 0x5fc, 0x20c, 1, 0x000, 0), /* MX51_PAD_AUD3_BB_FS__UART3_TXD */ - IMX_PIN_REG(MX51_PAD_CSPI1_MOSI, 0x600, 0x210, 0, 0x000, 0), /* MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI */ - IMX_PIN_REG(MX51_PAD_CSPI1_MOSI, 0x600, 0x210, 3, 0x000, 0), /* MX51_PAD_CSPI1_MOSI__GPIO4_22 */ - IMX_PIN_REG(MX51_PAD_CSPI1_MOSI, 0x600, 0x210, 1, 0x9b4, 1), /* MX51_PAD_CSPI1_MOSI__I2C1_SDA */ - IMX_PIN_REG(MX51_PAD_CSPI1_MISO, 0x604, 0x214, 1, 0x8c4, 1), /* MX51_PAD_CSPI1_MISO__AUD4_RXD */ - IMX_PIN_REG(MX51_PAD_CSPI1_MISO, 0x604, 0x214, 0, 0x000, 0), /* MX51_PAD_CSPI1_MISO__ECSPI1_MISO */ - IMX_PIN_REG(MX51_PAD_CSPI1_MISO, 0x604, 0x214, 3, 0x000, 0), /* MX51_PAD_CSPI1_MISO__GPIO4_23 */ - IMX_PIN_REG(MX51_PAD_CSPI1_SS0, 0x608, 0x218, 1, 0x8cc, 1), /* MX51_PAD_CSPI1_SS0__AUD4_TXC */ - IMX_PIN_REG(MX51_PAD_CSPI1_SS0, 0x608, 0x218, 0, 0x000, 0), /* MX51_PAD_CSPI1_SS0__ECSPI1_SS0 */ - IMX_PIN_REG(MX51_PAD_CSPI1_SS0, 0x608, 0x218, 3, 0x000, 0), /* MX51_PAD_CSPI1_SS0__GPIO4_24 */ - IMX_PIN_REG(MX51_PAD_CSPI1_SS1, 0x60c, 0x21c, 1, 0x8c8, 1), /* MX51_PAD_CSPI1_SS1__AUD4_TXD */ - IMX_PIN_REG(MX51_PAD_CSPI1_SS1, 0x60c, 0x21c, 0, 0x000, 0), /* MX51_PAD_CSPI1_SS1__ECSPI1_SS1 */ - IMX_PIN_REG(MX51_PAD_CSPI1_SS1, 0x60c, 0x21c, 3, 0x000, 0), /* MX51_PAD_CSPI1_SS1__GPIO4_25 */ - IMX_PIN_REG(MX51_PAD_CSPI1_RDY, 0x610, 0x220, 1, 0x8d0, 1), /* MX51_PAD_CSPI1_RDY__AUD4_TXFS */ - IMX_PIN_REG(MX51_PAD_CSPI1_RDY, 0x610, 0x220, 0, 0x000, 0), /* MX51_PAD_CSPI1_RDY__ECSPI1_RDY */ - IMX_PIN_REG(MX51_PAD_CSPI1_RDY, 0x610, 0x220, 3, 0x000, 0), /* MX51_PAD_CSPI1_RDY__GPIO4_26 */ - IMX_PIN_REG(MX51_PAD_CSPI1_SCLK, 0x614, 0x224, 0, 0x000, 0), /* MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK */ - IMX_PIN_REG(MX51_PAD_CSPI1_SCLK, 0x614, 0x224, 3, 0x000, 0), /* MX51_PAD_CSPI1_SCLK__GPIO4_27 */ - IMX_PIN_REG(MX51_PAD_CSPI1_SCLK, 0x614, 0x224, 1, 0x9b0, 1), /* MX51_PAD_CSPI1_SCLK__I2C1_SCL */ - IMX_PIN_REG(MX51_PAD_UART1_RXD, 0x618, 0x228, 3, 0x000, 0), /* MX51_PAD_UART1_RXD__GPIO4_28 */ - IMX_PIN_REG(MX51_PAD_UART1_RXD, 0x618, 0x228, 0, 0x9e4, 0), /* MX51_PAD_UART1_RXD__UART1_RXD */ - IMX_PIN_REG(MX51_PAD_UART1_TXD, 0x61c, 0x22c, 3, 0x000, 0), /* MX51_PAD_UART1_TXD__GPIO4_29 */ - IMX_PIN_REG(MX51_PAD_UART1_TXD, 0x61c, 0x22c, 1, 0x000, 0), /* MX51_PAD_UART1_TXD__PWM2_PWMO */ - IMX_PIN_REG(MX51_PAD_UART1_TXD, 0x61c, 0x22c, 0, 0x000, 0), /* MX51_PAD_UART1_TXD__UART1_TXD */ - IMX_PIN_REG(MX51_PAD_UART1_RTS, 0x620, 0x230, 3, 0x000, 0), /* MX51_PAD_UART1_RTS__GPIO4_30 */ - IMX_PIN_REG(MX51_PAD_UART1_RTS, 0x620, 0x230, 0, 0x9e0, 0), /* MX51_PAD_UART1_RTS__UART1_RTS */ - IMX_PIN_REG(MX51_PAD_UART1_CTS, 0x624, 0x234, 3, 0x000, 0), /* MX51_PAD_UART1_CTS__GPIO4_31 */ - IMX_PIN_REG(MX51_PAD_UART1_CTS, 0x624, 0x234, 0, 0x000, 0), /* MX51_PAD_UART1_CTS__UART1_CTS */ - IMX_PIN_REG(MX51_PAD_UART2_RXD, 0x628, 0x238, 1, 0x000, 0), /* MX51_PAD_UART2_RXD__FIRI_TXD */ - IMX_PIN_REG(MX51_PAD_UART2_RXD, 0x628, 0x238, 3, 0x000, 0), /* MX51_PAD_UART2_RXD__GPIO1_20 */ - IMX_PIN_REG(MX51_PAD_UART2_RXD, 0x628, 0x238, 0, 0x9ec, 2), /* MX51_PAD_UART2_RXD__UART2_RXD */ - IMX_PIN_REG(MX51_PAD_UART2_TXD, 0x62c, 0x23c, 1, 0x000, 0), /* MX51_PAD_UART2_TXD__FIRI_RXD */ - IMX_PIN_REG(MX51_PAD_UART2_TXD, 0x62c, 0x23c, 3, 0x000, 0), /* MX51_PAD_UART2_TXD__GPIO1_21 */ - IMX_PIN_REG(MX51_PAD_UART2_TXD, 0x62c, 0x23c, 0, 0x000, 0), /* MX51_PAD_UART2_TXD__UART2_TXD */ - IMX_PIN_REG(MX51_PAD_UART3_RXD, 0x630, 0x240, 2, 0x000, 0), /* MX51_PAD_UART3_RXD__CSI1_D0 */ - IMX_PIN_REG(MX51_PAD_UART3_RXD, 0x630, 0x240, 3, 0x000, 0), /* MX51_PAD_UART3_RXD__GPIO1_22 */ - IMX_PIN_REG(MX51_PAD_UART3_RXD, 0x630, 0x240, 0, 0x000, 0), /* MX51_PAD_UART3_RXD__UART1_DTR */ - IMX_PIN_REG(MX51_PAD_UART3_RXD, 0x630, 0x240, 1, 0x9f4, 4), /* MX51_PAD_UART3_RXD__UART3_RXD */ - IMX_PIN_REG(MX51_PAD_UART3_TXD, 0x634, 0x244, 2, 0x000, 0), /* MX51_PAD_UART3_TXD__CSI1_D1 */ - IMX_PIN_REG(MX51_PAD_UART3_TXD, 0x634, 0x244, 3, 0x000, 0), /* MX51_PAD_UART3_TXD__GPIO1_23 */ - IMX_PIN_REG(MX51_PAD_UART3_TXD, 0x634, 0x244, 0, 0x000, 0), /* MX51_PAD_UART3_TXD__UART1_DSR */ - IMX_PIN_REG(MX51_PAD_UART3_TXD, 0x634, 0x244, 1, 0x000, 0), /* MX51_PAD_UART3_TXD__UART3_TXD */ - IMX_PIN_REG(MX51_PAD_OWIRE_LINE, 0x638, 0x248, 3, 0x000, 0), /* MX51_PAD_OWIRE_LINE__GPIO1_24 */ - IMX_PIN_REG(MX51_PAD_OWIRE_LINE, 0x638, 0x248, 0, 0x000, 0), /* MX51_PAD_OWIRE_LINE__OWIRE_LINE */ - IMX_PIN_REG(MX51_PAD_OWIRE_LINE, 0x638, 0x248, 6, 0x000, 0), /* MX51_PAD_OWIRE_LINE__SPDIF_OUT */ - IMX_PIN_REG(MX51_PAD_KEY_ROW0, 0x63c, 0x24c, 0, 0x000, 0), /* MX51_PAD_KEY_ROW0__KEY_ROW0 */ - IMX_PIN_REG(MX51_PAD_KEY_ROW1, 0x640, 0x250, 0, 0x000, 0), /* MX51_PAD_KEY_ROW1__KEY_ROW1 */ - IMX_PIN_REG(MX51_PAD_KEY_ROW2, 0x644, 0x254, 0, 0x000, 0), /* MX51_PAD_KEY_ROW2__KEY_ROW2 */ - IMX_PIN_REG(MX51_PAD_KEY_ROW3, 0x648, 0x258, 0, 0x000, 0), /* MX51_PAD_KEY_ROW3__KEY_ROW3 */ - IMX_PIN_REG(MX51_PAD_KEY_COL0, 0x64c, 0x25c, 0, 0x000, 0), /* MX51_PAD_KEY_COL0__KEY_COL0 */ - IMX_PIN_REG(MX51_PAD_KEY_COL0, 0x64c, 0x25c, 7, 0x90c, 0), /* MX51_PAD_KEY_COL0__PLL1_BYP */ - IMX_PIN_REG(MX51_PAD_KEY_COL1, 0x650, 0x260, 0, 0x000, 0), /* MX51_PAD_KEY_COL1__KEY_COL1 */ - IMX_PIN_REG(MX51_PAD_KEY_COL1, 0x650, 0x260, 7, 0x910, 0), /* MX51_PAD_KEY_COL1__PLL2_BYP */ - IMX_PIN_REG(MX51_PAD_KEY_COL2, 0x654, 0x264, 0, 0x000, 0), /* MX51_PAD_KEY_COL2__KEY_COL2 */ - IMX_PIN_REG(MX51_PAD_KEY_COL2, 0x654, 0x264, 7, 0x000, 0), /* MX51_PAD_KEY_COL2__PLL3_BYP */ - IMX_PIN_REG(MX51_PAD_KEY_COL3, 0x658, 0x268, 0, 0x000, 0), /* MX51_PAD_KEY_COL3__KEY_COL3 */ - IMX_PIN_REG(MX51_PAD_KEY_COL4, 0x65c, 0x26c, 3, 0x9b8, 1), /* MX51_PAD_KEY_COL4__I2C2_SCL */ - IMX_PIN_REG(MX51_PAD_KEY_COL4, 0x65c, 0x26c, 0, 0x000, 0), /* MX51_PAD_KEY_COL4__KEY_COL4 */ - IMX_PIN_REG(MX51_PAD_KEY_COL4, 0x65c, 0x26c, 6, 0x000, 0), /* MX51_PAD_KEY_COL4__SPDIF_OUT1 */ - IMX_PIN_REG(MX51_PAD_KEY_COL4, 0x65c, 0x26c, 1, 0x000, 0), /* MX51_PAD_KEY_COL4__UART1_RI */ - IMX_PIN_REG(MX51_PAD_KEY_COL4, 0x65c, 0x26c, 2, 0x9f0, 4), /* MX51_PAD_KEY_COL4__UART3_RTS */ - IMX_PIN_REG(MX51_PAD_KEY_COL5, 0x660, 0x270, 3, 0x9bc, 1), /* MX51_PAD_KEY_COL5__I2C2_SDA */ - IMX_PIN_REG(MX51_PAD_KEY_COL5, 0x660, 0x270, 0, 0x000, 0), /* MX51_PAD_KEY_COL5__KEY_COL5 */ - IMX_PIN_REG(MX51_PAD_KEY_COL5, 0x660, 0x270, 1, 0x000, 0), /* MX51_PAD_KEY_COL5__UART1_DCD */ - IMX_PIN_REG(MX51_PAD_KEY_COL5, 0x660, 0x270, 2, 0x000, 0), /* MX51_PAD_KEY_COL5__UART3_CTS */ - IMX_PIN_REG(MX51_PAD_USBH1_CLK, 0x678, 0x278, 1, 0x914, 1), /* MX51_PAD_USBH1_CLK__CSPI_SCLK */ - IMX_PIN_REG(MX51_PAD_USBH1_CLK, 0x678, 0x278, 2, 0x000, 0), /* MX51_PAD_USBH1_CLK__GPIO1_25 */ - IMX_PIN_REG(MX51_PAD_USBH1_CLK, 0x678, 0x278, 5, 0x9b8, 2), /* MX51_PAD_USBH1_CLK__I2C2_SCL */ - IMX_PIN_REG(MX51_PAD_USBH1_CLK, 0x678, 0x278, 0, 0x000, 0), /* MX51_PAD_USBH1_CLK__USBH1_CLK */ - IMX_PIN_REG(MX51_PAD_USBH1_DIR, 0x67c, 0x27c, 1, 0x91c, 1), /* MX51_PAD_USBH1_DIR__CSPI_MOSI */ - IMX_PIN_REG(MX51_PAD_USBH1_DIR, 0x67c, 0x27c, 2, 0x000, 0), /* MX51_PAD_USBH1_DIR__GPIO1_26 */ - IMX_PIN_REG(MX51_PAD_USBH1_DIR, 0x67c, 0x27c, 5, 0x9bc, 2), /* MX51_PAD_USBH1_DIR__I2C2_SDA */ - IMX_PIN_REG(MX51_PAD_USBH1_DIR, 0x67c, 0x27c, 0, 0x000, 0), /* MX51_PAD_USBH1_DIR__USBH1_DIR */ - IMX_PIN_REG(MX51_PAD_USBH1_STP, 0x680, 0x280, 1, 0x000, 0), /* MX51_PAD_USBH1_STP__CSPI_RDY */ - IMX_PIN_REG(MX51_PAD_USBH1_STP, 0x680, 0x280, 2, 0x000, 0), /* MX51_PAD_USBH1_STP__GPIO1_27 */ - IMX_PIN_REG(MX51_PAD_USBH1_STP, 0x680, 0x280, 5, 0x9f4, 6), /* MX51_PAD_USBH1_STP__UART3_RXD */ - IMX_PIN_REG(MX51_PAD_USBH1_STP, 0x680, 0x280, 0, 0x000, 0), /* MX51_PAD_USBH1_STP__USBH1_STP */ - IMX_PIN_REG(MX51_PAD_USBH1_NXT, 0x684, 0x284, 1, 0x918, 0), /* MX51_PAD_USBH1_NXT__CSPI_MISO */ - IMX_PIN_REG(MX51_PAD_USBH1_NXT, 0x684, 0x284, 2, 0x000, 0), /* MX51_PAD_USBH1_NXT__GPIO1_28 */ - IMX_PIN_REG(MX51_PAD_USBH1_NXT, 0x684, 0x284, 5, 0x000, 0), /* MX51_PAD_USBH1_NXT__UART3_TXD */ - IMX_PIN_REG(MX51_PAD_USBH1_NXT, 0x684, 0x284, 0, 0x000, 0), /* MX51_PAD_USBH1_NXT__USBH1_NXT */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA0, 0x688, 0x288, 2, 0x000, 0), /* MX51_PAD_USBH1_DATA0__GPIO1_11 */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA0, 0x688, 0x288, 1, 0x000, 0), /* MX51_PAD_USBH1_DATA0__UART2_CTS */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA0, 0x688, 0x288, 0, 0x000, 0), /* MX51_PAD_USBH1_DATA0__USBH1_DATA0 */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA1, 0x68c, 0x28c, 2, 0x000, 0), /* MX51_PAD_USBH1_DATA1__GPIO1_12 */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA1, 0x68c, 0x28c, 1, 0x9ec, 4), /* MX51_PAD_USBH1_DATA1__UART2_RXD */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA1, 0x68c, 0x28c, 0, 0x000, 0), /* MX51_PAD_USBH1_DATA1__USBH1_DATA1 */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA2, 0x690, 0x290, 2, 0x000, 0), /* MX51_PAD_USBH1_DATA2__GPIO1_13 */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA2, 0x690, 0x290, 1, 0x000, 0), /* MX51_PAD_USBH1_DATA2__UART2_TXD */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA2, 0x690, 0x290, 0, 0x000, 0), /* MX51_PAD_USBH1_DATA2__USBH1_DATA2 */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA3, 0x694, 0x294, 2, 0x000, 0), /* MX51_PAD_USBH1_DATA3__GPIO1_14 */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA3, 0x694, 0x294, 1, 0x9e8, 5), /* MX51_PAD_USBH1_DATA3__UART2_RTS */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA3, 0x694, 0x294, 0, 0x000, 0), /* MX51_PAD_USBH1_DATA3__USBH1_DATA3 */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA4, 0x698, 0x298, 1, 0x000, 0), /* MX51_PAD_USBH1_DATA4__CSPI_SS0 */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA4, 0x698, 0x298, 2, 0x000, 0), /* MX51_PAD_USBH1_DATA4__GPIO1_15 */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA4, 0x698, 0x298, 0, 0x000, 0), /* MX51_PAD_USBH1_DATA4__USBH1_DATA4 */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA5, 0x69c, 0x29c, 1, 0x920, 0), /* MX51_PAD_USBH1_DATA5__CSPI_SS1 */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA5, 0x69c, 0x29c, 2, 0x000, 0), /* MX51_PAD_USBH1_DATA5__GPIO1_16 */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA5, 0x69c, 0x29c, 0, 0x000, 0), /* MX51_PAD_USBH1_DATA5__USBH1_DATA5 */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA6, 0x6a0, 0x2a0, 1, 0x928, 1), /* MX51_PAD_USBH1_DATA6__CSPI_SS3 */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA6, 0x6a0, 0x2a0, 2, 0x000, 0), /* MX51_PAD_USBH1_DATA6__GPIO1_17 */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA6, 0x6a0, 0x2a0, 0, 0x000, 0), /* MX51_PAD_USBH1_DATA6__USBH1_DATA6 */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA7, 0x6a4, 0x2a4, 1, 0x000, 0), /* MX51_PAD_USBH1_DATA7__ECSPI1_SS3 */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA7, 0x6a4, 0x2a4, 5, 0x934, 1), /* MX51_PAD_USBH1_DATA7__ECSPI2_SS3 */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA7, 0x6a4, 0x2a4, 2, 0x000, 0), /* MX51_PAD_USBH1_DATA7__GPIO1_18 */ - IMX_PIN_REG(MX51_PAD_USBH1_DATA7, 0x6a4, 0x2a4, 0, 0x000, 0), /* MX51_PAD_USBH1_DATA7__USBH1_DATA7 */ - IMX_PIN_REG(MX51_PAD_DI1_PIN11, 0x6a8, 0x2a8, 0, 0x000, 0), /* MX51_PAD_DI1_PIN11__DI1_PIN11 */ - IMX_PIN_REG(MX51_PAD_DI1_PIN11, 0x6a8, 0x2a8, 7, 0x000, 0), /* MX51_PAD_DI1_PIN11__ECSPI1_SS2 */ - IMX_PIN_REG(MX51_PAD_DI1_PIN11, 0x6a8, 0x2a8, 4, 0x000, 0), /* MX51_PAD_DI1_PIN11__GPIO3_0 */ - IMX_PIN_REG(MX51_PAD_DI1_PIN12, 0x6ac, 0x2ac, 0, 0x000, 0), /* MX51_PAD_DI1_PIN12__DI1_PIN12 */ - IMX_PIN_REG(MX51_PAD_DI1_PIN12, 0x6ac, 0x2ac, 4, 0x978, 1), /* MX51_PAD_DI1_PIN12__GPIO3_1 */ - IMX_PIN_REG(MX51_PAD_DI1_PIN13, 0x6b0, 0x2b0, 0, 0x000, 0), /* MX51_PAD_DI1_PIN13__DI1_PIN13 */ - IMX_PIN_REG(MX51_PAD_DI1_PIN13, 0x6b0, 0x2b0, 4, 0x97c, 1), /* MX51_PAD_DI1_PIN13__GPIO3_2 */ - IMX_PIN_REG(MX51_PAD_DI1_D0_CS, 0x6b4, 0x2b4, 0, 0x000, 0), /* MX51_PAD_DI1_D0_CS__DI1_D0_CS */ - IMX_PIN_REG(MX51_PAD_DI1_D0_CS, 0x6b4, 0x2b4, 4, 0x980, 1), /* MX51_PAD_DI1_D0_CS__GPIO3_3 */ - IMX_PIN_REG(MX51_PAD_DI1_D1_CS, 0x6b8, 0x2b8, 0, 0x000, 0), /* MX51_PAD_DI1_D1_CS__DI1_D1_CS */ - IMX_PIN_REG(MX51_PAD_DI1_D1_CS, 0x6b8, 0x2b8, 2, 0x000, 0), /* MX51_PAD_DI1_D1_CS__DISP1_PIN14 */ - IMX_PIN_REG(MX51_PAD_DI1_D1_CS, 0x6b8, 0x2b8, 3, 0x000, 0), /* MX51_PAD_DI1_D1_CS__DISP1_PIN5 */ - IMX_PIN_REG(MX51_PAD_DI1_D1_CS, 0x6b8, 0x2b8, 4, 0x984, 1), /* MX51_PAD_DI1_D1_CS__GPIO3_4 */ - IMX_PIN_REG(MX51_PAD_DISPB2_SER_DIN, 0x6bc, 0x2bc, 2, 0x9a4, 1), /* MX51_PAD_DISPB2_SER_DIN__DISP1_PIN1 */ - IMX_PIN_REG(MX51_PAD_DISPB2_SER_DIN, 0x6bc, 0x2bc, 0, 0x9c4, 0), /* MX51_PAD_DISPB2_SER_DIN__DISPB2_SER_DIN */ - IMX_PIN_REG(MX51_PAD_DISPB2_SER_DIN, 0x6bc, 0x2bc, 4, 0x988, 1), /* MX51_PAD_DISPB2_SER_DIN__GPIO3_5 */ - IMX_PIN_REG(MX51_PAD_DISPB2_SER_DIO, 0x6c0, 0x2c0, 3, 0x000, 0), /* MX51_PAD_DISPB2_SER_DIO__DISP1_PIN6 */ - IMX_PIN_REG(MX51_PAD_DISPB2_SER_DIO, 0x6c0, 0x2c0, 0, 0x9c4, 1), /* MX51_PAD_DISPB2_SER_DIO__DISPB2_SER_DIO */ - IMX_PIN_REG(MX51_PAD_DISPB2_SER_DIO, 0x6c0, 0x2c0, 4, 0x98c, 1), /* MX51_PAD_DISPB2_SER_DIO__GPIO3_6 */ - IMX_PIN_REG(MX51_PAD_DISPB2_SER_CLK, 0x6c4, 0x2c4, 2, 0x000, 0), /* MX51_PAD_DISPB2_SER_CLK__DISP1_PIN17 */ - IMX_PIN_REG(MX51_PAD_DISPB2_SER_CLK, 0x6c4, 0x2c4, 3, 0x000, 0), /* MX51_PAD_DISPB2_SER_CLK__DISP1_PIN7 */ - IMX_PIN_REG(MX51_PAD_DISPB2_SER_CLK, 0x6c4, 0x2c4, 0, 0x000, 0), /* MX51_PAD_DISPB2_SER_CLK__DISPB2_SER_CLK */ - IMX_PIN_REG(MX51_PAD_DISPB2_SER_CLK, 0x6c4, 0x2c4, 4, 0x990, 1), /* MX51_PAD_DISPB2_SER_CLK__GPIO3_7 */ - IMX_PIN_REG(MX51_PAD_DISPB2_SER_RS, 0x6c8, 0x2c8, 2, 0x000, 0), /* MX51_PAD_DISPB2_SER_RS__DISP1_EXT_CLK */ - IMX_PIN_REG(MX51_PAD_DISPB2_SER_RS, 0x6c8, 0x2c8, 2, 0x000, 0), /* MX51_PAD_DISPB2_SER_RS__DISP1_PIN16 */ - IMX_PIN_REG(MX51_PAD_DISPB2_SER_RS, 0x6c8, 0x2c8, 3, 0x000, 0), /* MX51_PAD_DISPB2_SER_RS__DISP1_PIN8 */ - IMX_PIN_REG(MX51_PAD_DISPB2_SER_RS, 0x6c8, 0x2c8, 0, 0x000, 0), /* MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS */ - IMX_PIN_REG(MX51_PAD_DISPB2_SER_RS, 0x6c8, 0x2c8, 0, 0x000, 0), /* MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS */ - IMX_PIN_REG(MX51_PAD_DISPB2_SER_RS, 0x6c8, 0x2c8, 4, 0x994, 1), /* MX51_PAD_DISPB2_SER_RS__GPIO3_8 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT0, 0x6cc, 0x2cc, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT0__DISP1_DAT0 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT1, 0x6d0, 0x2d0, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT1__DISP1_DAT1 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT2, 0x6d4, 0x2d4, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT2__DISP1_DAT2 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT3, 0x6d8, 0x2d8, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT3__DISP1_DAT3 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT4, 0x6dc, 0x2dc, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT4__DISP1_DAT4 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT5, 0x6e0, 0x2e0, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT5__DISP1_DAT5 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT6, 0x6e4, 0x2e4, 7, 0x000, 0), /* MX51_PAD_DISP1_DAT6__BOOT_USB_SRC */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT6, 0x6e4, 0x2e4, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT6__DISP1_DAT6 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT7, 0x6e8, 0x2e8, 7, 0x000, 0), /* MX51_PAD_DISP1_DAT7__BOOT_EEPROM_CFG */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT7, 0x6e8, 0x2e8, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT7__DISP1_DAT7 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT8, 0x6ec, 0x2ec, 7, 0x000, 0), /* MX51_PAD_DISP1_DAT8__BOOT_SRC0 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT8, 0x6ec, 0x2ec, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT8__DISP1_DAT8 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT9, 0x6f0, 0x2f0, 7, 0x000, 0), /* MX51_PAD_DISP1_DAT9__BOOT_SRC1 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT9, 0x6f0, 0x2f0, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT9__DISP1_DAT9 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT10, 0x6f4, 0x2f4, 7, 0x000, 0), /* MX51_PAD_DISP1_DAT10__BOOT_SPARE_SIZE */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT10, 0x6f4, 0x2f4, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT10__DISP1_DAT10 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT11, 0x6f8, 0x2f8, 7, 0x000, 0), /* MX51_PAD_DISP1_DAT11__BOOT_LPB_FREQ2 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT11, 0x6f8, 0x2f8, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT11__DISP1_DAT11 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT12, 0x6fc, 0x2fc, 7, 0x000, 0), /* MX51_PAD_DISP1_DAT12__BOOT_MLC_SEL */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT12, 0x6fc, 0x2fc, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT12__DISP1_DAT12 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT13, 0x700, 0x300, 7, 0x000, 0), /* MX51_PAD_DISP1_DAT13__BOOT_MEM_CTL0 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT13, 0x700, 0x300, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT13__DISP1_DAT13 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT14, 0x704, 0x304, 7, 0x000, 0), /* MX51_PAD_DISP1_DAT14__BOOT_MEM_CTL1 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT14, 0x704, 0x304, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT14__DISP1_DAT14 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT15, 0x708, 0x308, 7, 0x000, 0), /* MX51_PAD_DISP1_DAT15__BOOT_BUS_WIDTH */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT15, 0x708, 0x308, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT15__DISP1_DAT15 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT16, 0x70c, 0x30c, 7, 0x000, 0), /* MX51_PAD_DISP1_DAT16__BOOT_PAGE_SIZE0 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT16, 0x70c, 0x30c, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT16__DISP1_DAT16 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT17, 0x710, 0x310, 7, 0x000, 0), /* MX51_PAD_DISP1_DAT17__BOOT_PAGE_SIZE1 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT17, 0x710, 0x310, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT17__DISP1_DAT17 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT18, 0x714, 0x314, 7, 0x000, 0), /* MX51_PAD_DISP1_DAT18__BOOT_WEIM_MUXED0 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT18, 0x714, 0x314, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT18__DISP1_DAT18 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT18, 0x714, 0x314, 5, 0x000, 0), /* MX51_PAD_DISP1_DAT18__DISP2_PIN11 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT18, 0x714, 0x314, 4, 0x000, 0), /* MX51_PAD_DISP1_DAT18__DISP2_PIN5 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT19, 0x718, 0x318, 7, 0x000, 0), /* MX51_PAD_DISP1_DAT19__BOOT_WEIM_MUXED1 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT19, 0x718, 0x318, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT19__DISP1_DAT19 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT19, 0x718, 0x318, 5, 0x000, 0), /* MX51_PAD_DISP1_DAT19__DISP2_PIN12 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT19, 0x718, 0x318, 4, 0x000, 0), /* MX51_PAD_DISP1_DAT19__DISP2_PIN6 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT20, 0x71c, 0x31c, 7, 0x000, 0), /* MX51_PAD_DISP1_DAT20__BOOT_MEM_TYPE0 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT20, 0x71c, 0x31c, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT20__DISP1_DAT20 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT20, 0x71c, 0x31c, 5, 0x000, 0), /* MX51_PAD_DISP1_DAT20__DISP2_PIN13 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT20, 0x71c, 0x31c, 4, 0x000, 0), /* MX51_PAD_DISP1_DAT20__DISP2_PIN7 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT21, 0x720, 0x320, 7, 0x000, 0), /* MX51_PAD_DISP1_DAT21__BOOT_MEM_TYPE1 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT21, 0x720, 0x320, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT21__DISP1_DAT21 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT21, 0x720, 0x320, 5, 0x000, 0), /* MX51_PAD_DISP1_DAT21__DISP2_PIN14 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT21, 0x720, 0x320, 4, 0x000, 0), /* MX51_PAD_DISP1_DAT21__DISP2_PIN8 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT22, 0x724, 0x324, 7, 0x000, 0), /* MX51_PAD_DISP1_DAT22__BOOT_LPB_FREQ0 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT22, 0x724, 0x324, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT22__DISP1_DAT22 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT22, 0x724, 0x324, 6, 0x000, 0), /* MX51_PAD_DISP1_DAT22__DISP2_D0_CS */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT22, 0x724, 0x324, 5, 0x000, 0), /* MX51_PAD_DISP1_DAT22__DISP2_DAT16 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT23, 0x728, 0x328, 7, 0x000, 0), /* MX51_PAD_DISP1_DAT23__BOOT_LPB_FREQ1 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT23, 0x728, 0x328, 0, 0x000, 0), /* MX51_PAD_DISP1_DAT23__DISP1_DAT23 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT23, 0x728, 0x328, 6, 0x000, 0), /* MX51_PAD_DISP1_DAT23__DISP2_D1_CS */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT23, 0x728, 0x328, 5, 0x000, 0), /* MX51_PAD_DISP1_DAT23__DISP2_DAT17 */ - IMX_PIN_REG(MX51_PAD_DISP1_DAT23, 0x728, 0x328, 4, 0x000, 0), /* MX51_PAD_DISP1_DAT23__DISP2_SER_CS */ - IMX_PIN_REG(MX51_PAD_DI1_PIN3, 0x72c, 0x32c, 0, 0x000, 0), /* MX51_PAD_DI1_PIN3__DI1_PIN3 */ - IMX_PIN_REG(MX51_PAD_DI1_PIN2, 0x734, 0x330, 0, 0x000, 0), /* MX51_PAD_DI1_PIN2__DI1_PIN2 */ - IMX_PIN_REG(MX51_PAD_DI_GP2, 0x740, 0x338, 0, 0x000, 0), /* MX51_PAD_DI_GP2__DISP1_SER_CLK */ - IMX_PIN_REG(MX51_PAD_DI_GP2, 0x740, 0x338, 2, 0x9a8, 1), /* MX51_PAD_DI_GP2__DISP2_WAIT */ - IMX_PIN_REG(MX51_PAD_DI_GP3, 0x744, 0x33c, 3, 0x9a0, 1), /* MX51_PAD_DI_GP3__CSI1_DATA_EN */ - IMX_PIN_REG(MX51_PAD_DI_GP3, 0x744, 0x33c, 0, 0x9c0, 0), /* MX51_PAD_DI_GP3__DISP1_SER_DIO */ - IMX_PIN_REG(MX51_PAD_DI_GP3, 0x744, 0x33c, 2, 0x000, 0), /* MX51_PAD_DI_GP3__FEC_TX_ER */ - IMX_PIN_REG(MX51_PAD_DI2_PIN4, 0x748, 0x340, 3, 0x99c, 1), /* MX51_PAD_DI2_PIN4__CSI2_DATA_EN */ - IMX_PIN_REG(MX51_PAD_DI2_PIN4, 0x748, 0x340, 0, 0x000, 0), /* MX51_PAD_DI2_PIN4__DI2_PIN4 */ - IMX_PIN_REG(MX51_PAD_DI2_PIN4, 0x748, 0x340, 2, 0x950, 1), /* MX51_PAD_DI2_PIN4__FEC_CRS */ - IMX_PIN_REG(MX51_PAD_DI2_PIN2, 0x74c, 0x344, 0, 0x000, 0), /* MX51_PAD_DI2_PIN2__DI2_PIN2 */ - IMX_PIN_REG(MX51_PAD_DI2_PIN2, 0x74c, 0x344, 2, 0x000, 0), /* MX51_PAD_DI2_PIN2__FEC_MDC */ - IMX_PIN_REG(MX51_PAD_DI2_PIN3, 0x750, 0x348, 0, 0x000, 0), /* MX51_PAD_DI2_PIN3__DI2_PIN3 */ - IMX_PIN_REG(MX51_PAD_DI2_PIN3, 0x750, 0x348, 2, 0x954, 1), /* MX51_PAD_DI2_PIN3__FEC_MDIO */ - IMX_PIN_REG(MX51_PAD_DI2_DISP_CLK, 0x754, 0x34c, 0, 0x000, 0), /* MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK */ - IMX_PIN_REG(MX51_PAD_DI2_DISP_CLK, 0x754, 0x34c, 2, 0x95c, 1), /* MX51_PAD_DI2_DISP_CLK__FEC_RDATA1 */ - IMX_PIN_REG(MX51_PAD_DI_GP4, 0x758, 0x350, 4, 0x000, 0), /* MX51_PAD_DI_GP4__DI2_PIN15 */ - IMX_PIN_REG(MX51_PAD_DI_GP4, 0x758, 0x350, 0, 0x9c0, 1), /* MX51_PAD_DI_GP4__DISP1_SER_DIN */ - IMX_PIN_REG(MX51_PAD_DI_GP4, 0x758, 0x350, 3, 0x000, 0), /* MX51_PAD_DI_GP4__DISP2_PIN1 */ - IMX_PIN_REG(MX51_PAD_DI_GP4, 0x758, 0x350, 2, 0x960, 1), /* MX51_PAD_DI_GP4__FEC_RDATA2 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT0, 0x75c, 0x354, 0, 0x000, 0), /* MX51_PAD_DISP2_DAT0__DISP2_DAT0 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT0, 0x75c, 0x354, 2, 0x964, 1), /* MX51_PAD_DISP2_DAT0__FEC_RDATA3 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT0, 0x75c, 0x354, 4, 0x9c8, 1), /* MX51_PAD_DISP2_DAT0__KEY_COL6 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT0, 0x75c, 0x354, 5, 0x9f4, 8), /* MX51_PAD_DISP2_DAT0__UART3_RXD */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT0, 0x75c, 0x354, 3, 0x9f8, 1), /* MX51_PAD_DISP2_DAT0__USBH3_CLK */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT1, 0x760, 0x358, 0, 0x000, 0), /* MX51_PAD_DISP2_DAT1__DISP2_DAT1 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT1, 0x760, 0x358, 2, 0x970, 1), /* MX51_PAD_DISP2_DAT1__FEC_RX_ER */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT1, 0x760, 0x358, 4, 0x9cc, 1), /* MX51_PAD_DISP2_DAT1__KEY_COL7 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT1, 0x760, 0x358, 5, 0x000, 0), /* MX51_PAD_DISP2_DAT1__UART3_TXD */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT1, 0x760, 0x358, 3, 0xa1c, 1), /* MX51_PAD_DISP2_DAT1__USBH3_DIR */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT2, 0x764, 0x35c, 0, 0x000, 0), /* MX51_PAD_DISP2_DAT2__DISP2_DAT2 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT3, 0x768, 0x360, 0, 0x000, 0), /* MX51_PAD_DISP2_DAT3__DISP2_DAT3 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT4, 0x76c, 0x364, 0, 0x000, 0), /* MX51_PAD_DISP2_DAT4__DISP2_DAT4 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT5, 0x770, 0x368, 0, 0x000, 0), /* MX51_PAD_DISP2_DAT5__DISP2_DAT5 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT6, 0x774, 0x36c, 0, 0x000, 0), /* MX51_PAD_DISP2_DAT6__DISP2_DAT6 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT6, 0x774, 0x36c, 2, 0x000, 0), /* MX51_PAD_DISP2_DAT6__FEC_TDATA1 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT6, 0x774, 0x36c, 5, 0x000, 0), /* MX51_PAD_DISP2_DAT6__GPIO1_19 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT6, 0x774, 0x36c, 4, 0x9d0, 1), /* MX51_PAD_DISP2_DAT6__KEY_ROW4 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT6, 0x774, 0x36c, 3, 0xa24, 1), /* MX51_PAD_DISP2_DAT6__USBH3_STP */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT7, 0x778, 0x370, 0, 0x000, 0), /* MX51_PAD_DISP2_DAT7__DISP2_DAT7 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT7, 0x778, 0x370, 2, 0x000, 0), /* MX51_PAD_DISP2_DAT7__FEC_TDATA2 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT7, 0x778, 0x370, 5, 0x000, 0), /* MX51_PAD_DISP2_DAT7__GPIO1_29 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT7, 0x778, 0x370, 4, 0x9d4, 1), /* MX51_PAD_DISP2_DAT7__KEY_ROW5 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT7, 0x778, 0x370, 3, 0xa20, 1), /* MX51_PAD_DISP2_DAT7__USBH3_NXT */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT8, 0x77c, 0x374, 0, 0x000, 0), /* MX51_PAD_DISP2_DAT8__DISP2_DAT8 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT8, 0x77c, 0x374, 2, 0x000, 0), /* MX51_PAD_DISP2_DAT8__FEC_TDATA3 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT8, 0x77c, 0x374, 5, 0x000, 0), /* MX51_PAD_DISP2_DAT8__GPIO1_30 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT8, 0x77c, 0x374, 4, 0x9d8, 1), /* MX51_PAD_DISP2_DAT8__KEY_ROW6 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT8, 0x77c, 0x374, 3, 0x9fc, 1), /* MX51_PAD_DISP2_DAT8__USBH3_DATA0 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT9, 0x780, 0x378, 4, 0x8f4, 1), /* MX51_PAD_DISP2_DAT9__AUD6_RXC */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT9, 0x780, 0x378, 0, 0x000, 0), /* MX51_PAD_DISP2_DAT9__DISP2_DAT9 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT9, 0x780, 0x378, 2, 0x000, 0), /* MX51_PAD_DISP2_DAT9__FEC_TX_EN */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT9, 0x780, 0x378, 5, 0x000, 0), /* MX51_PAD_DISP2_DAT9__GPIO1_31 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT9, 0x780, 0x378, 3, 0xa00, 1), /* MX51_PAD_DISP2_DAT9__USBH3_DATA1 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT10, 0x784, 0x37c, 0, 0x000, 0), /* MX51_PAD_DISP2_DAT10__DISP2_DAT10 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT10, 0x784, 0x37c, 5, 0x000, 0), /* MX51_PAD_DISP2_DAT10__DISP2_SER_CS */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT10, 0x784, 0x37c, 2, 0x94c, 1), /* MX51_PAD_DISP2_DAT10__FEC_COL */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT10, 0x784, 0x37c, 4, 0x9dc, 1), /* MX51_PAD_DISP2_DAT10__KEY_ROW7 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT10, 0x784, 0x37c, 3, 0xa04, 1), /* MX51_PAD_DISP2_DAT10__USBH3_DATA2 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT11, 0x788, 0x380, 4, 0x8f0, 1), /* MX51_PAD_DISP2_DAT11__AUD6_TXD */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT11, 0x788, 0x380, 0, 0x000, 0), /* MX51_PAD_DISP2_DAT11__DISP2_DAT11 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT11, 0x788, 0x380, 2, 0x968, 1), /* MX51_PAD_DISP2_DAT11__FEC_RX_CLK */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT11, 0x788, 0x380, 7, 0x000, 0), /* MX51_PAD_DISP2_DAT11__GPIO1_10 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT11, 0x788, 0x380, 3, 0xa08, 1), /* MX51_PAD_DISP2_DAT11__USBH3_DATA3 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT12, 0x78c, 0x384, 4, 0x8ec, 1), /* MX51_PAD_DISP2_DAT12__AUD6_RXD */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT12, 0x78c, 0x384, 0, 0x000, 0), /* MX51_PAD_DISP2_DAT12__DISP2_DAT12 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT12, 0x78c, 0x384, 2, 0x96c, 1), /* MX51_PAD_DISP2_DAT12__FEC_RX_DV */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT12, 0x78c, 0x384, 3, 0xa0c, 1), /* MX51_PAD_DISP2_DAT12__USBH3_DATA4 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT13, 0x790, 0x388, 4, 0x8fc, 1), /* MX51_PAD_DISP2_DAT13__AUD6_TXC */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT13, 0x790, 0x388, 0, 0x000, 0), /* MX51_PAD_DISP2_DAT13__DISP2_DAT13 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT13, 0x790, 0x388, 2, 0x974, 1), /* MX51_PAD_DISP2_DAT13__FEC_TX_CLK */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT13, 0x790, 0x388, 3, 0xa10, 1), /* MX51_PAD_DISP2_DAT13__USBH3_DATA5 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT14, 0x794, 0x38c, 4, 0x900, 1), /* MX51_PAD_DISP2_DAT14__AUD6_TXFS */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT14, 0x794, 0x38c, 0, 0x000, 0), /* MX51_PAD_DISP2_DAT14__DISP2_DAT14 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT14, 0x794, 0x38c, 2, 0x958, 1), /* MX51_PAD_DISP2_DAT14__FEC_RDATA0 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT14, 0x794, 0x38c, 3, 0xa14, 1), /* MX51_PAD_DISP2_DAT14__USBH3_DATA6 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT15, 0x798, 0x390, 4, 0x8f8, 1), /* MX51_PAD_DISP2_DAT15__AUD6_RXFS */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT15, 0x798, 0x390, 5, 0x000, 0), /* MX51_PAD_DISP2_DAT15__DISP1_SER_CS */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT15, 0x798, 0x390, 0, 0x000, 0), /* MX51_PAD_DISP2_DAT15__DISP2_DAT15 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT15, 0x798, 0x390, 2, 0x000, 0), /* MX51_PAD_DISP2_DAT15__FEC_TDATA0 */ - IMX_PIN_REG(MX51_PAD_DISP2_DAT15, 0x798, 0x390, 3, 0xa18, 1), /* MX51_PAD_DISP2_DAT15__USBH3_DATA7 */ - IMX_PIN_REG(MX51_PAD_SD1_CMD, 0x79c, 0x394, 1, 0x8e0, 1), /* MX51_PAD_SD1_CMD__AUD5_RXFS */ - IMX_PIN_REG(MX51_PAD_SD1_CMD, 0x79c, 0x394, 2, 0x91c, 2), /* MX51_PAD_SD1_CMD__CSPI_MOSI */ - IMX_PIN_REG(MX51_PAD_SD1_CMD, 0x79c, 0x394, 0, 0x000, 0), /* MX51_PAD_SD1_CMD__SD1_CMD */ - IMX_PIN_REG(MX51_PAD_SD1_CLK, 0x7a0, 0x398, 1, 0x8dc, 1), /* MX51_PAD_SD1_CLK__AUD5_RXC */ - IMX_PIN_REG(MX51_PAD_SD1_CLK, 0x7a0, 0x398, 2, 0x914, 2), /* MX51_PAD_SD1_CLK__CSPI_SCLK */ - IMX_PIN_REG(MX51_PAD_SD1_CLK, 0x7a0, 0x398, 0, 0x000, 0), /* MX51_PAD_SD1_CLK__SD1_CLK */ - IMX_PIN_REG(MX51_PAD_SD1_DATA0, 0x7a4, 0x39c, 1, 0x8d8, 2), /* MX51_PAD_SD1_DATA0__AUD5_TXD */ - IMX_PIN_REG(MX51_PAD_SD1_DATA0, 0x7a4, 0x39c, 2, 0x918, 1), /* MX51_PAD_SD1_DATA0__CSPI_MISO */ - IMX_PIN_REG(MX51_PAD_SD1_DATA0, 0x7a4, 0x39c, 0, 0x000, 0), /* MX51_PAD_SD1_DATA0__SD1_DATA0 */ - IMX_PIN_REG(MX51_PAD_EIM_DA0, NO_PAD, 0x01c, 0, 0x000, 0), /* MX51_PAD_EIM_DA0__EIM_DA0 */ - IMX_PIN_REG(MX51_PAD_EIM_DA1, NO_PAD, 0x020, 0, 0x000, 0), /* MX51_PAD_EIM_DA1__EIM_DA1 */ - IMX_PIN_REG(MX51_PAD_EIM_DA2, NO_PAD, 0x024, 0, 0x000, 0), /* MX51_PAD_EIM_DA2__EIM_DA2 */ - IMX_PIN_REG(MX51_PAD_EIM_DA3, NO_PAD, 0x028, 0, 0x000, 0), /* MX51_PAD_EIM_DA3__EIM_DA3 */ - IMX_PIN_REG(MX51_PAD_SD1_DATA1, 0x7a8, 0x3a0, 1, 0x8d4, 2), /* MX51_PAD_SD1_DATA1__AUD5_RXD */ - IMX_PIN_REG(MX51_PAD_SD1_DATA1, 0x7a8, 0x3a0, 0, 0x000, 0), /* MX51_PAD_SD1_DATA1__SD1_DATA1 */ - IMX_PIN_REG(MX51_PAD_EIM_DA4, NO_PAD, 0x02c, 0, 0x000, 0), /* MX51_PAD_EIM_DA4__EIM_DA4 */ - IMX_PIN_REG(MX51_PAD_EIM_DA5, NO_PAD, 0x030, 0, 0x000, 0), /* MX51_PAD_EIM_DA5__EIM_DA5 */ - IMX_PIN_REG(MX51_PAD_EIM_DA6, NO_PAD, 0x034, 0, 0x000, 0), /* MX51_PAD_EIM_DA6__EIM_DA6 */ - IMX_PIN_REG(MX51_PAD_EIM_DA7, NO_PAD, 0x038, 0, 0x000, 0), /* MX51_PAD_EIM_DA7__EIM_DA7 */ - IMX_PIN_REG(MX51_PAD_SD1_DATA2, 0x7ac, 0x3a4, 1, 0x8e4, 2), /* MX51_PAD_SD1_DATA2__AUD5_TXC */ - IMX_PIN_REG(MX51_PAD_SD1_DATA2, 0x7ac, 0x3a4, 0, 0x000, 0), /* MX51_PAD_SD1_DATA2__SD1_DATA2 */ - IMX_PIN_REG(MX51_PAD_EIM_DA10, NO_PAD, 0x044, 0, 0x000, 0), /* MX51_PAD_EIM_DA10__EIM_DA10 */ - IMX_PIN_REG(MX51_PAD_EIM_DA11, NO_PAD, 0x048, 0, 0x000, 0), /* MX51_PAD_EIM_DA11__EIM_DA11 */ - IMX_PIN_REG(MX51_PAD_EIM_DA8, NO_PAD, 0x03c, 0, 0x000, 0), /* MX51_PAD_EIM_DA8__EIM_DA8 */ - IMX_PIN_REG(MX51_PAD_EIM_DA9, NO_PAD, 0x040, 0, 0x000, 0), /* MX51_PAD_EIM_DA9__EIM_DA9 */ - IMX_PIN_REG(MX51_PAD_SD1_DATA3, 0x7b0, 0x3a8, 1, 0x8e8, 2), /* MX51_PAD_SD1_DATA3__AUD5_TXFS */ - IMX_PIN_REG(MX51_PAD_SD1_DATA3, 0x7b0, 0x3a8, 2, 0x920, 1), /* MX51_PAD_SD1_DATA3__CSPI_SS1 */ - IMX_PIN_REG(MX51_PAD_SD1_DATA3, 0x7b0, 0x3a8, 0, 0x000, 0), /* MX51_PAD_SD1_DATA3__SD1_DATA3 */ - IMX_PIN_REG(MX51_PAD_GPIO1_0, 0x7b4, 0x3ac, 2, 0x924, 0), /* MX51_PAD_GPIO1_0__CSPI_SS2 */ - IMX_PIN_REG(MX51_PAD_GPIO1_0, 0x7b4, 0x3ac, 1, 0x000, 0), /* MX51_PAD_GPIO1_0__GPIO1_0 */ - IMX_PIN_REG(MX51_PAD_GPIO1_0, 0x7b4, 0x3ac, 0, 0x000, 0), /* MX51_PAD_GPIO1_0__SD1_CD */ - IMX_PIN_REG(MX51_PAD_GPIO1_1, 0x7b8, 0x3b0, 2, 0x918, 2), /* MX51_PAD_GPIO1_1__CSPI_MISO */ - IMX_PIN_REG(MX51_PAD_GPIO1_1, 0x7b8, 0x3b0, 1, 0x000, 0), /* MX51_PAD_GPIO1_1__GPIO1_1 */ - IMX_PIN_REG(MX51_PAD_GPIO1_1, 0x7b8, 0x3b0, 0, 0x000, 0), /* MX51_PAD_GPIO1_1__SD1_WP */ - IMX_PIN_REG(MX51_PAD_EIM_DA12, NO_PAD, 0x04c, 0, 0x000, 0), /* MX51_PAD_EIM_DA12__EIM_DA12 */ - IMX_PIN_REG(MX51_PAD_EIM_DA13, NO_PAD, 0x050, 0, 0x000, 0), /* MX51_PAD_EIM_DA13__EIM_DA13 */ - IMX_PIN_REG(MX51_PAD_EIM_DA14, NO_PAD, 0x054, 0, 0x000, 0), /* MX51_PAD_EIM_DA14__EIM_DA14 */ - IMX_PIN_REG(MX51_PAD_EIM_DA15, NO_PAD, 0x058, 0, 0x000, 0), /* MX51_PAD_EIM_DA15__EIM_DA15 */ - IMX_PIN_REG(MX51_PAD_SD2_CMD, NO_PAD, 0x3b4, 2, 0x91c, 3), /* MX51_PAD_SD2_CMD__CSPI_MOSI */ - IMX_PIN_REG(MX51_PAD_SD2_CMD, 0x7bc, 0x3b4, 1, 0x9b0, 2), /* MX51_PAD_SD2_CMD__I2C1_SCL */ - IMX_PIN_REG(MX51_PAD_SD2_CMD, 0x7bc, 0x3b4, 0, 0x000, 0), /* MX51_PAD_SD2_CMD__SD2_CMD */ - IMX_PIN_REG(MX51_PAD_SD2_CLK, 0x7c0, 0x3b8, 2, 0x914, 3), /* MX51_PAD_SD2_CLK__CSPI_SCLK */ - IMX_PIN_REG(MX51_PAD_SD2_CLK, 0x7c0, 0x3b8, 1, 0x9b4, 2), /* MX51_PAD_SD2_CLK__I2C1_SDA */ - IMX_PIN_REG(MX51_PAD_SD2_CLK, 0x7c0, 0x3b8, 0, 0x000, 0), /* MX51_PAD_SD2_CLK__SD2_CLK */ - IMX_PIN_REG(MX51_PAD_SD2_DATA0, 0x7c4, 0x3bc, 2, 0x918, 3), /* MX51_PAD_SD2_DATA0__CSPI_MISO */ - IMX_PIN_REG(MX51_PAD_SD2_DATA0, 0x7c4, 0x3bc, 1, 0x000, 0), /* MX51_PAD_SD2_DATA0__SD1_DAT4 */ - IMX_PIN_REG(MX51_PAD_SD2_DATA0, 0x7c4, 0x3bc, 0, 0x000, 0), /* MX51_PAD_SD2_DATA0__SD2_DATA0 */ - IMX_PIN_REG(MX51_PAD_SD2_DATA1, 0x7c8, 0x3c0, 1, 0x000, 0), /* MX51_PAD_SD2_DATA1__SD1_DAT5 */ - IMX_PIN_REG(MX51_PAD_SD2_DATA1, 0x7c8, 0x3c0, 0, 0x000, 0), /* MX51_PAD_SD2_DATA1__SD2_DATA1 */ - IMX_PIN_REG(MX51_PAD_SD2_DATA1, 0x7c8, 0x3c0, 2, 0x000, 0), /* MX51_PAD_SD2_DATA1__USBH3_H2_DP */ - IMX_PIN_REG(MX51_PAD_SD2_DATA2, 0x7cc, 0x3c4, 1, 0x000, 0), /* MX51_PAD_SD2_DATA2__SD1_DAT6 */ - IMX_PIN_REG(MX51_PAD_SD2_DATA2, 0x7cc, 0x3c4, 0, 0x000, 0), /* MX51_PAD_SD2_DATA2__SD2_DATA2 */ - IMX_PIN_REG(MX51_PAD_SD2_DATA2, 0x7cc, 0x3c4, 2, 0x000, 0), /* MX51_PAD_SD2_DATA2__USBH3_H2_DM */ - IMX_PIN_REG(MX51_PAD_SD2_DATA3, 0x7d0, 0x3c8, 2, 0x924, 1), /* MX51_PAD_SD2_DATA3__CSPI_SS2 */ - IMX_PIN_REG(MX51_PAD_SD2_DATA3, 0x7d0, 0x3c8, 1, 0x000, 0), /* MX51_PAD_SD2_DATA3__SD1_DAT7 */ - IMX_PIN_REG(MX51_PAD_SD2_DATA3, 0x7d0, 0x3c8, 0, 0x000, 0), /* MX51_PAD_SD2_DATA3__SD2_DATA3 */ - IMX_PIN_REG(MX51_PAD_GPIO1_2, 0x7d4, 0x3cc, 5, 0x000, 0), /* MX51_PAD_GPIO1_2__CCM_OUT_2 */ - IMX_PIN_REG(MX51_PAD_GPIO1_2, 0x7d4, 0x3cc, 0, 0x000, 0), /* MX51_PAD_GPIO1_2__GPIO1_2 */ - IMX_PIN_REG(MX51_PAD_GPIO1_2, 0x7d4, 0x3cc, 2, 0x9b8, 3), /* MX51_PAD_GPIO1_2__I2C2_SCL */ - IMX_PIN_REG(MX51_PAD_GPIO1_2, 0x7d4, 0x3cc, 7, 0x90c, 1), /* MX51_PAD_GPIO1_2__PLL1_BYP */ - IMX_PIN_REG(MX51_PAD_GPIO1_2, 0x7d4, 0x3cc, 1, 0x000, 0), /* MX51_PAD_GPIO1_2__PWM1_PWMO */ - IMX_PIN_REG(MX51_PAD_GPIO1_3, 0x7d8, 0x3d0, 0, 0x000, 0), /* MX51_PAD_GPIO1_3__GPIO1_3 */ - IMX_PIN_REG(MX51_PAD_GPIO1_3, 0x7d8, 0x3d0, 2, 0x9bc, 3), /* MX51_PAD_GPIO1_3__I2C2_SDA */ - IMX_PIN_REG(MX51_PAD_GPIO1_3, 0x7d8, 0x3d0, 7, 0x910, 1), /* MX51_PAD_GPIO1_3__PLL2_BYP */ - IMX_PIN_REG(MX51_PAD_GPIO1_3, 0x7d8, 0x3d0, 1, 0x000, 0), /* MX51_PAD_GPIO1_3__PWM2_PWMO */ - IMX_PIN_REG(MX51_PAD_PMIC_INT_REQ, 0x7fc, 0x3d4, 0, 0x000, 0), /* MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ */ - IMX_PIN_REG(MX51_PAD_PMIC_INT_REQ, 0x7fc, 0x3d4, 1, 0x000, 0), /* MX51_PAD_PMIC_INT_REQ__PMIC_PMU_IRQ_B */ - IMX_PIN_REG(MX51_PAD_GPIO1_4, 0x804, 0x3d8, 4, 0x908, 1), /* MX51_PAD_GPIO1_4__DISP2_EXT_CLK */ - IMX_PIN_REG(MX51_PAD_GPIO1_4, 0x804, 0x3d8, 3, 0x938, 1), /* MX51_PAD_GPIO1_4__EIM_RDY */ - IMX_PIN_REG(MX51_PAD_GPIO1_4, 0x804, 0x3d8, 0, 0x000, 0), /* MX51_PAD_GPIO1_4__GPIO1_4 */ - IMX_PIN_REG(MX51_PAD_GPIO1_4, 0x804, 0x3d8, 2, 0x000, 0), /* MX51_PAD_GPIO1_4__WDOG1_WDOG_B */ - IMX_PIN_REG(MX51_PAD_GPIO1_5, 0x808, 0x3dc, 6, 0x000, 0), /* MX51_PAD_GPIO1_5__CSI2_MCLK */ - IMX_PIN_REG(MX51_PAD_GPIO1_5, 0x808, 0x3dc, 3, 0x000, 0), /* MX51_PAD_GPIO1_5__DISP2_PIN16 */ - IMX_PIN_REG(MX51_PAD_GPIO1_5, 0x808, 0x3dc, 0, 0x000, 0), /* MX51_PAD_GPIO1_5__GPIO1_5 */ - IMX_PIN_REG(MX51_PAD_GPIO1_5, 0x808, 0x3dc, 2, 0x000, 0), /* MX51_PAD_GPIO1_5__WDOG2_WDOG_B */ - IMX_PIN_REG(MX51_PAD_GPIO1_6, 0x80c, 0x3e0, 4, 0x000, 0), /* MX51_PAD_GPIO1_6__DISP2_PIN17 */ - IMX_PIN_REG(MX51_PAD_GPIO1_6, 0x80c, 0x3e0, 0, 0x000, 0), /* MX51_PAD_GPIO1_6__GPIO1_6 */ - IMX_PIN_REG(MX51_PAD_GPIO1_6, 0x80c, 0x3e0, 3, 0x000, 0), /* MX51_PAD_GPIO1_6__REF_EN_B */ - IMX_PIN_REG(MX51_PAD_GPIO1_7, 0x810, 0x3e4, 3, 0x000, 0), /* MX51_PAD_GPIO1_7__CCM_OUT_0 */ - IMX_PIN_REG(MX51_PAD_GPIO1_7, 0x810, 0x3e4, 0, 0x000, 0), /* MX51_PAD_GPIO1_7__GPIO1_7 */ - IMX_PIN_REG(MX51_PAD_GPIO1_7, 0x810, 0x3e4, 6, 0x000, 0), /* MX51_PAD_GPIO1_7__SD2_WP */ - IMX_PIN_REG(MX51_PAD_GPIO1_7, 0x810, 0x3e4, 2, 0x000, 0), /* MX51_PAD_GPIO1_7__SPDIF_OUT1 */ - IMX_PIN_REG(MX51_PAD_GPIO1_8, 0x814, 0x3e8, 2, 0x99c, 2), /* MX51_PAD_GPIO1_8__CSI2_DATA_EN */ - IMX_PIN_REG(MX51_PAD_GPIO1_8, 0x814, 0x3e8, 0, 0x000, 0), /* MX51_PAD_GPIO1_8__GPIO1_8 */ - IMX_PIN_REG(MX51_PAD_GPIO1_8, 0x814, 0x3e8, 6, 0x000, 0), /* MX51_PAD_GPIO1_8__SD2_CD */ - IMX_PIN_REG(MX51_PAD_GPIO1_8, 0x814, 0x3e8, 1, 0x000, 0), /* MX51_PAD_GPIO1_8__USBH3_PWR */ - IMX_PIN_REG(MX51_PAD_GPIO1_9, 0x818, 0x3ec, 3, 0x000, 0), /* MX51_PAD_GPIO1_9__CCM_OUT_1 */ - IMX_PIN_REG(MX51_PAD_GPIO1_9, 0x818, 0x3ec, 2, 0x000, 0), /* MX51_PAD_GPIO1_9__DISP2_D1_CS */ - IMX_PIN_REG(MX51_PAD_GPIO1_9, 0x818, 0x3ec, 7, 0x000, 0), /* MX51_PAD_GPIO1_9__DISP2_SER_CS */ - IMX_PIN_REG(MX51_PAD_GPIO1_9, 0x818, 0x3ec, 0, 0x000, 0), /* MX51_PAD_GPIO1_9__GPIO1_9 */ - IMX_PIN_REG(MX51_PAD_GPIO1_9, 0x818, 0x3ec, 6, 0x000, 0), /* MX51_PAD_GPIO1_9__SD2_LCTL */ - IMX_PIN_REG(MX51_PAD_GPIO1_9, 0x818, 0x3ec, 1, 0x000, 0), /* MX51_PAD_GPIO1_9__USBH3_OC */ -}; - -/* Pad names for the pinmux subsystem */ -static const struct pinctrl_pin_desc imx51_pinctrl_pads[] = { - IMX_PINCTRL_PIN(MX51_PAD_EIM_D16), - IMX_PINCTRL_PIN(MX51_PAD_EIM_D17), - IMX_PINCTRL_PIN(MX51_PAD_EIM_D18), - IMX_PINCTRL_PIN(MX51_PAD_EIM_D19), - IMX_PINCTRL_PIN(MX51_PAD_EIM_D20), - IMX_PINCTRL_PIN(MX51_PAD_EIM_D21), - IMX_PINCTRL_PIN(MX51_PAD_EIM_D22), - IMX_PINCTRL_PIN(MX51_PAD_EIM_D23), - IMX_PINCTRL_PIN(MX51_PAD_EIM_D24), - IMX_PINCTRL_PIN(MX51_PAD_EIM_D25), - IMX_PINCTRL_PIN(MX51_PAD_EIM_D26), - IMX_PINCTRL_PIN(MX51_PAD_EIM_D27), - IMX_PINCTRL_PIN(MX51_PAD_EIM_D28), - IMX_PINCTRL_PIN(MX51_PAD_EIM_D29), - IMX_PINCTRL_PIN(MX51_PAD_EIM_D30), - IMX_PINCTRL_PIN(MX51_PAD_EIM_D31), - IMX_PINCTRL_PIN(MX51_PAD_EIM_A16), - IMX_PINCTRL_PIN(MX51_PAD_EIM_A17), - IMX_PINCTRL_PIN(MX51_PAD_EIM_A18), - IMX_PINCTRL_PIN(MX51_PAD_EIM_A19), - IMX_PINCTRL_PIN(MX51_PAD_EIM_A20), - IMX_PINCTRL_PIN(MX51_PAD_EIM_A21), - IMX_PINCTRL_PIN(MX51_PAD_EIM_A22), - IMX_PINCTRL_PIN(MX51_PAD_EIM_A23), - IMX_PINCTRL_PIN(MX51_PAD_EIM_A24), - IMX_PINCTRL_PIN(MX51_PAD_EIM_A25), - IMX_PINCTRL_PIN(MX51_PAD_EIM_A26), - IMX_PINCTRL_PIN(MX51_PAD_EIM_A27), - IMX_PINCTRL_PIN(MX51_PAD_EIM_EB0), - IMX_PINCTRL_PIN(MX51_PAD_EIM_EB1), - IMX_PINCTRL_PIN(MX51_PAD_EIM_EB2), - IMX_PINCTRL_PIN(MX51_PAD_EIM_EB3), - IMX_PINCTRL_PIN(MX51_PAD_EIM_OE), - IMX_PINCTRL_PIN(MX51_PAD_EIM_CS0), - IMX_PINCTRL_PIN(MX51_PAD_EIM_CS1), - IMX_PINCTRL_PIN(MX51_PAD_EIM_CS2), - IMX_PINCTRL_PIN(MX51_PAD_EIM_CS3), - IMX_PINCTRL_PIN(MX51_PAD_EIM_CS4), - IMX_PINCTRL_PIN(MX51_PAD_EIM_CS5), - IMX_PINCTRL_PIN(MX51_PAD_EIM_DTACK), - IMX_PINCTRL_PIN(MX51_PAD_EIM_LBA), - IMX_PINCTRL_PIN(MX51_PAD_EIM_CRE), - IMX_PINCTRL_PIN(MX51_PAD_DRAM_CS1), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_WE_B), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_RE_B), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_ALE), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_CLE), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_WP_B), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_RB0), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_RB1), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_RB2), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_RB3), - IMX_PINCTRL_PIN(MX51_PAD_GPIO_NAND), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_CS0), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_CS1), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_CS2), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_CS3), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_CS4), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_CS5), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_CS6), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_CS7), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_RDY_INT), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_D15), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_D14), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_D13), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_D12), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_D11), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_D10), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_D9), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_D8), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_D7), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_D6), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_D5), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_D4), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_D3), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_D2), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_D1), - IMX_PINCTRL_PIN(MX51_PAD_NANDF_D0), - IMX_PINCTRL_PIN(MX51_PAD_CSI1_D8), - IMX_PINCTRL_PIN(MX51_PAD_CSI1_D9), - IMX_PINCTRL_PIN(MX51_PAD_CSI1_D10), - IMX_PINCTRL_PIN(MX51_PAD_CSI1_D11), - IMX_PINCTRL_PIN(MX51_PAD_CSI1_D12), - IMX_PINCTRL_PIN(MX51_PAD_CSI1_D13), - IMX_PINCTRL_PIN(MX51_PAD_CSI1_D14), - IMX_PINCTRL_PIN(MX51_PAD_CSI1_D15), - IMX_PINCTRL_PIN(MX51_PAD_CSI1_D16), - IMX_PINCTRL_PIN(MX51_PAD_CSI1_D17), - IMX_PINCTRL_PIN(MX51_PAD_CSI1_D18), - IMX_PINCTRL_PIN(MX51_PAD_CSI1_D19), - IMX_PINCTRL_PIN(MX51_PAD_CSI1_VSYNC), - IMX_PINCTRL_PIN(MX51_PAD_CSI1_HSYNC), - IMX_PINCTRL_PIN(MX51_PAD_CSI1_PIXCLK), - IMX_PINCTRL_PIN(MX51_PAD_CSI1_MCLK), - IMX_PINCTRL_PIN(MX51_PAD_CSI2_D12), - IMX_PINCTRL_PIN(MX51_PAD_CSI2_D13), - IMX_PINCTRL_PIN(MX51_PAD_CSI2_D14), - IMX_PINCTRL_PIN(MX51_PAD_CSI2_D15), - IMX_PINCTRL_PIN(MX51_PAD_CSI2_D16), - IMX_PINCTRL_PIN(MX51_PAD_CSI2_D17), - IMX_PINCTRL_PIN(MX51_PAD_CSI2_D18), - IMX_PINCTRL_PIN(MX51_PAD_CSI2_D19), - IMX_PINCTRL_PIN(MX51_PAD_CSI2_VSYNC), - IMX_PINCTRL_PIN(MX51_PAD_CSI2_HSYNC), - IMX_PINCTRL_PIN(MX51_PAD_CSI2_PIXCLK), - IMX_PINCTRL_PIN(MX51_PAD_I2C1_CLK), - IMX_PINCTRL_PIN(MX51_PAD_I2C1_DAT), - IMX_PINCTRL_PIN(MX51_PAD_AUD3_BB_TXD), - IMX_PINCTRL_PIN(MX51_PAD_AUD3_BB_RXD), - IMX_PINCTRL_PIN(MX51_PAD_AUD3_BB_CK), - IMX_PINCTRL_PIN(MX51_PAD_AUD3_BB_FS), - IMX_PINCTRL_PIN(MX51_PAD_CSPI1_MOSI), - IMX_PINCTRL_PIN(MX51_PAD_CSPI1_MISO), - IMX_PINCTRL_PIN(MX51_PAD_CSPI1_SS0), - IMX_PINCTRL_PIN(MX51_PAD_CSPI1_SS1), - IMX_PINCTRL_PIN(MX51_PAD_CSPI1_RDY), - IMX_PINCTRL_PIN(MX51_PAD_CSPI1_SCLK), - IMX_PINCTRL_PIN(MX51_PAD_UART1_RXD), - IMX_PINCTRL_PIN(MX51_PAD_UART1_TXD), - IMX_PINCTRL_PIN(MX51_PAD_UART1_RTS), - IMX_PINCTRL_PIN(MX51_PAD_UART1_CTS), - IMX_PINCTRL_PIN(MX51_PAD_UART2_RXD), - IMX_PINCTRL_PIN(MX51_PAD_UART2_TXD), - IMX_PINCTRL_PIN(MX51_PAD_UART3_RXD), - IMX_PINCTRL_PIN(MX51_PAD_UART3_TXD), - IMX_PINCTRL_PIN(MX51_PAD_OWIRE_LINE), - IMX_PINCTRL_PIN(MX51_PAD_KEY_ROW0), - IMX_PINCTRL_PIN(MX51_PAD_KEY_ROW1), - IMX_PINCTRL_PIN(MX51_PAD_KEY_ROW2), - IMX_PINCTRL_PIN(MX51_PAD_KEY_ROW3), - IMX_PINCTRL_PIN(MX51_PAD_KEY_COL0), - IMX_PINCTRL_PIN(MX51_PAD_KEY_COL1), - IMX_PINCTRL_PIN(MX51_PAD_KEY_COL2), - IMX_PINCTRL_PIN(MX51_PAD_KEY_COL3), - IMX_PINCTRL_PIN(MX51_PAD_KEY_COL4), - IMX_PINCTRL_PIN(MX51_PAD_KEY_COL5), - IMX_PINCTRL_PIN(MX51_PAD_USBH1_CLK), - IMX_PINCTRL_PIN(MX51_PAD_USBH1_DIR), - IMX_PINCTRL_PIN(MX51_PAD_USBH1_STP), - IMX_PINCTRL_PIN(MX51_PAD_USBH1_NXT), - IMX_PINCTRL_PIN(MX51_PAD_USBH1_DATA0), - IMX_PINCTRL_PIN(MX51_PAD_USBH1_DATA1), - IMX_PINCTRL_PIN(MX51_PAD_USBH1_DATA2), - IMX_PINCTRL_PIN(MX51_PAD_USBH1_DATA3), - IMX_PINCTRL_PIN(MX51_PAD_USBH1_DATA4), - IMX_PINCTRL_PIN(MX51_PAD_USBH1_DATA5), - IMX_PINCTRL_PIN(MX51_PAD_USBH1_DATA6), - IMX_PINCTRL_PIN(MX51_PAD_USBH1_DATA7), - IMX_PINCTRL_PIN(MX51_PAD_DI1_PIN11), - IMX_PINCTRL_PIN(MX51_PAD_DI1_PIN12), - IMX_PINCTRL_PIN(MX51_PAD_DI1_PIN13), - IMX_PINCTRL_PIN(MX51_PAD_DI1_D0_CS), - IMX_PINCTRL_PIN(MX51_PAD_DI1_D1_CS), - IMX_PINCTRL_PIN(MX51_PAD_DISPB2_SER_DIN), - IMX_PINCTRL_PIN(MX51_PAD_DISPB2_SER_DIO), - IMX_PINCTRL_PIN(MX51_PAD_DISPB2_SER_CLK), - IMX_PINCTRL_PIN(MX51_PAD_DISPB2_SER_RS), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT0), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT1), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT2), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT3), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT4), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT5), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT6), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT7), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT8), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT9), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT10), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT11), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT12), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT13), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT14), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT15), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT16), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT17), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT18), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT19), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT20), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT21), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT22), - IMX_PINCTRL_PIN(MX51_PAD_DISP1_DAT23), - IMX_PINCTRL_PIN(MX51_PAD_DI1_PIN3), - IMX_PINCTRL_PIN(MX51_PAD_DI1_PIN2), - IMX_PINCTRL_PIN(MX51_PAD_DI_GP2), - IMX_PINCTRL_PIN(MX51_PAD_DI_GP3), - IMX_PINCTRL_PIN(MX51_PAD_DI2_PIN4), - IMX_PINCTRL_PIN(MX51_PAD_DI2_PIN2), - IMX_PINCTRL_PIN(MX51_PAD_DI2_PIN3), - IMX_PINCTRL_PIN(MX51_PAD_DI2_DISP_CLK), - IMX_PINCTRL_PIN(MX51_PAD_DI_GP4), - IMX_PINCTRL_PIN(MX51_PAD_DISP2_DAT0), - IMX_PINCTRL_PIN(MX51_PAD_DISP2_DAT1), - IMX_PINCTRL_PIN(MX51_PAD_DISP2_DAT2), - IMX_PINCTRL_PIN(MX51_PAD_DISP2_DAT3), - IMX_PINCTRL_PIN(MX51_PAD_DISP2_DAT4), - IMX_PINCTRL_PIN(MX51_PAD_DISP2_DAT5), - IMX_PINCTRL_PIN(MX51_PAD_DISP2_DAT6), - IMX_PINCTRL_PIN(MX51_PAD_DISP2_DAT7), - IMX_PINCTRL_PIN(MX51_PAD_DISP2_DAT8), - IMX_PINCTRL_PIN(MX51_PAD_DISP2_DAT9), - IMX_PINCTRL_PIN(MX51_PAD_DISP2_DAT10), - IMX_PINCTRL_PIN(MX51_PAD_DISP2_DAT11), - IMX_PINCTRL_PIN(MX51_PAD_DISP2_DAT12), - IMX_PINCTRL_PIN(MX51_PAD_DISP2_DAT13), - IMX_PINCTRL_PIN(MX51_PAD_DISP2_DAT14), - IMX_PINCTRL_PIN(MX51_PAD_DISP2_DAT15), - IMX_PINCTRL_PIN(MX51_PAD_SD1_CMD), - IMX_PINCTRL_PIN(MX51_PAD_SD1_CLK), - IMX_PINCTRL_PIN(MX51_PAD_SD1_DATA0), - IMX_PINCTRL_PIN(MX51_PAD_EIM_DA0), - IMX_PINCTRL_PIN(MX51_PAD_EIM_DA1), - IMX_PINCTRL_PIN(MX51_PAD_EIM_DA2), - IMX_PINCTRL_PIN(MX51_PAD_EIM_DA3), - IMX_PINCTRL_PIN(MX51_PAD_SD1_DATA1), - IMX_PINCTRL_PIN(MX51_PAD_EIM_DA4), - IMX_PINCTRL_PIN(MX51_PAD_EIM_DA5), - IMX_PINCTRL_PIN(MX51_PAD_EIM_DA6), - IMX_PINCTRL_PIN(MX51_PAD_EIM_DA7), - IMX_PINCTRL_PIN(MX51_PAD_SD1_DATA2), - IMX_PINCTRL_PIN(MX51_PAD_EIM_DA10), - IMX_PINCTRL_PIN(MX51_PAD_EIM_DA11), - IMX_PINCTRL_PIN(MX51_PAD_EIM_DA8), - IMX_PINCTRL_PIN(MX51_PAD_EIM_DA9), - IMX_PINCTRL_PIN(MX51_PAD_SD1_DATA3), - IMX_PINCTRL_PIN(MX51_PAD_GPIO1_0), - IMX_PINCTRL_PIN(MX51_PAD_GPIO1_1), - IMX_PINCTRL_PIN(MX51_PAD_EIM_DA12), - IMX_PINCTRL_PIN(MX51_PAD_EIM_DA13), - IMX_PINCTRL_PIN(MX51_PAD_EIM_DA14), - IMX_PINCTRL_PIN(MX51_PAD_EIM_DA15), - IMX_PINCTRL_PIN(MX51_PAD_SD2_CMD), - IMX_PINCTRL_PIN(MX51_PAD_SD2_CLK), - IMX_PINCTRL_PIN(MX51_PAD_SD2_DATA0), - IMX_PINCTRL_PIN(MX51_PAD_SD2_DATA1), - IMX_PINCTRL_PIN(MX51_PAD_SD2_DATA2), - IMX_PINCTRL_PIN(MX51_PAD_SD2_DATA3), - IMX_PINCTRL_PIN(MX51_PAD_GPIO1_2), - IMX_PINCTRL_PIN(MX51_PAD_GPIO1_3), - IMX_PINCTRL_PIN(MX51_PAD_PMIC_INT_REQ), - IMX_PINCTRL_PIN(MX51_PAD_GPIO1_4), - IMX_PINCTRL_PIN(MX51_PAD_GPIO1_5), - IMX_PINCTRL_PIN(MX51_PAD_GPIO1_6), - IMX_PINCTRL_PIN(MX51_PAD_GPIO1_7), - IMX_PINCTRL_PIN(MX51_PAD_GPIO1_8), - IMX_PINCTRL_PIN(MX51_PAD_GPIO1_9), -}; - -static struct imx_pinctrl_soc_info imx51_pinctrl_info = { - .pins = imx51_pinctrl_pads, - .npins = ARRAY_SIZE(imx51_pinctrl_pads), - .pin_regs = imx51_pin_regs, - .npin_regs = ARRAY_SIZE(imx51_pin_regs), -}; - -static struct of_device_id imx51_pinctrl_of_match[] __devinitdata = { - { .compatible = "fsl,imx51-iomuxc", }, - { /* sentinel */ } -}; - -static int __devinit imx51_pinctrl_probe(struct platform_device *pdev) -{ - return imx_pinctrl_probe(pdev, &imx51_pinctrl_info); -} - -static struct platform_driver imx51_pinctrl_driver = { - .driver = { - .name = "imx51-pinctrl", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(imx51_pinctrl_of_match), - }, - .probe = imx51_pinctrl_probe, - .remove = __devexit_p(imx_pinctrl_remove), -}; - -static int __init imx51_pinctrl_init(void) -{ - return platform_driver_register(&imx51_pinctrl_driver); -} -arch_initcall(imx51_pinctrl_init); - -static void __exit imx51_pinctrl_exit(void) -{ - platform_driver_unregister(&imx51_pinctrl_driver); -} -module_exit(imx51_pinctrl_exit); -MODULE_AUTHOR("Dong Aisheng "); -MODULE_DESCRIPTION("Freescale IMX51 pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/pinctrl/pinctrl-imx53.c b/trunk/drivers/pinctrl/pinctrl-imx53.c deleted file mode 100644 index 1f49e16a9bcd..000000000000 --- a/trunk/drivers/pinctrl/pinctrl-imx53.c +++ /dev/null @@ -1,1649 +0,0 @@ -/* - * imx53 pinctrl driver based on imx pinmux core - * - * Copyright (C) 2012 Freescale Semiconductor, Inc. - * Copyright (C) 2012 Linaro, Inc. - * - * Author: Dong Aisheng - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "pinctrl-imx.h" - -enum imx53_pads { - MX53_PAD_GPIO_19 = 1, - MX53_PAD_KEY_COL0 = 2, - MX53_PAD_KEY_ROW0 = 3, - MX53_PAD_KEY_COL1 = 4, - MX53_PAD_KEY_ROW1 = 5, - MX53_PAD_KEY_COL2 = 6, - MX53_PAD_KEY_ROW2 = 7, - MX53_PAD_KEY_COL3 = 8, - MX53_PAD_KEY_ROW3 = 9, - MX53_PAD_KEY_COL4 = 10, - MX53_PAD_KEY_ROW4 = 11, - MX53_PAD_DI0_DISP_CLK = 12, - MX53_PAD_DI0_PIN15 = 13, - MX53_PAD_DI0_PIN2 = 14, - MX53_PAD_DI0_PIN3 = 15, - MX53_PAD_DI0_PIN4 = 16, - MX53_PAD_DISP0_DAT0 = 17, - MX53_PAD_DISP0_DAT1 = 18, - MX53_PAD_DISP0_DAT2 = 19, - MX53_PAD_DISP0_DAT3 = 20, - MX53_PAD_DISP0_DAT4 = 21, - MX53_PAD_DISP0_DAT5 = 22, - MX53_PAD_DISP0_DAT6 = 23, - MX53_PAD_DISP0_DAT7 = 24, - MX53_PAD_DISP0_DAT8 = 25, - MX53_PAD_DISP0_DAT9 = 26, - MX53_PAD_DISP0_DAT10 = 27, - MX53_PAD_DISP0_DAT11 = 28, - MX53_PAD_DISP0_DAT12 = 29, - MX53_PAD_DISP0_DAT13 = 30, - MX53_PAD_DISP0_DAT14 = 31, - MX53_PAD_DISP0_DAT15 = 32, - MX53_PAD_DISP0_DAT16 = 33, - MX53_PAD_DISP0_DAT17 = 34, - MX53_PAD_DISP0_DAT18 = 35, - MX53_PAD_DISP0_DAT19 = 36, - MX53_PAD_DISP0_DAT20 = 37, - MX53_PAD_DISP0_DAT21 = 38, - MX53_PAD_DISP0_DAT22 = 39, - MX53_PAD_DISP0_DAT23 = 40, - MX53_PAD_CSI0_PIXCLK = 41, - MX53_PAD_CSI0_MCLK = 42, - MX53_PAD_CSI0_DATA_EN = 43, - MX53_PAD_CSI0_VSYNC = 44, - MX53_PAD_CSI0_DAT4 = 45, - MX53_PAD_CSI0_DAT5 = 46, - MX53_PAD_CSI0_DAT6 = 47, - MX53_PAD_CSI0_DAT7 = 48, - MX53_PAD_CSI0_DAT8 = 49, - MX53_PAD_CSI0_DAT9 = 50, - MX53_PAD_CSI0_DAT10 = 51, - MX53_PAD_CSI0_DAT11 = 52, - MX53_PAD_CSI0_DAT12 = 53, - MX53_PAD_CSI0_DAT13 = 54, - MX53_PAD_CSI0_DAT14 = 55, - MX53_PAD_CSI0_DAT15 = 56, - MX53_PAD_CSI0_DAT16 = 57, - MX53_PAD_CSI0_DAT17 = 58, - MX53_PAD_CSI0_DAT18 = 59, - MX53_PAD_CSI0_DAT19 = 60, - MX53_PAD_EIM_A25 = 61, - MX53_PAD_EIM_EB2 = 62, - MX53_PAD_EIM_D16 = 63, - MX53_PAD_EIM_D17 = 64, - MX53_PAD_EIM_D18 = 65, - MX53_PAD_EIM_D19 = 66, - MX53_PAD_EIM_D20 = 67, - MX53_PAD_EIM_D21 = 68, - MX53_PAD_EIM_D22 = 69, - MX53_PAD_EIM_D23 = 70, - MX53_PAD_EIM_EB3 = 71, - MX53_PAD_EIM_D24 = 72, - MX53_PAD_EIM_D25 = 73, - MX53_PAD_EIM_D26 = 74, - MX53_PAD_EIM_D27 = 75, - MX53_PAD_EIM_D28 = 76, - MX53_PAD_EIM_D29 = 77, - MX53_PAD_EIM_D30 = 78, - MX53_PAD_EIM_D31 = 79, - MX53_PAD_EIM_A24 = 80, - MX53_PAD_EIM_A23 = 81, - MX53_PAD_EIM_A22 = 82, - MX53_PAD_EIM_A21 = 83, - MX53_PAD_EIM_A20 = 84, - MX53_PAD_EIM_A19 = 85, - MX53_PAD_EIM_A18 = 86, - MX53_PAD_EIM_A17 = 87, - MX53_PAD_EIM_A16 = 88, - MX53_PAD_EIM_CS0 = 89, - MX53_PAD_EIM_CS1 = 90, - MX53_PAD_EIM_OE = 91, - MX53_PAD_EIM_RW = 92, - MX53_PAD_EIM_LBA = 93, - MX53_PAD_EIM_EB0 = 94, - MX53_PAD_EIM_EB1 = 95, - MX53_PAD_EIM_DA0 = 96, - MX53_PAD_EIM_DA1 = 97, - MX53_PAD_EIM_DA2 = 98, - MX53_PAD_EIM_DA3 = 99, - MX53_PAD_EIM_DA4 = 100, - MX53_PAD_EIM_DA5 = 101, - MX53_PAD_EIM_DA6 = 102, - MX53_PAD_EIM_DA7 = 103, - MX53_PAD_EIM_DA8 = 104, - MX53_PAD_EIM_DA9 = 105, - MX53_PAD_EIM_DA10 = 106, - MX53_PAD_EIM_DA11 = 107, - MX53_PAD_EIM_DA12 = 108, - MX53_PAD_EIM_DA13 = 109, - MX53_PAD_EIM_DA14 = 110, - MX53_PAD_EIM_DA15 = 111, - MX53_PAD_NANDF_WE_B = 112, - MX53_PAD_NANDF_RE_B = 113, - MX53_PAD_EIM_WAIT = 114, - MX53_PAD_LVDS1_TX3_P = 115, - MX53_PAD_LVDS1_TX2_P = 116, - MX53_PAD_LVDS1_CLK_P = 117, - MX53_PAD_LVDS1_TX1_P = 118, - MX53_PAD_LVDS1_TX0_P = 119, - MX53_PAD_LVDS0_TX3_P = 120, - MX53_PAD_LVDS0_CLK_P = 121, - MX53_PAD_LVDS0_TX2_P = 122, - MX53_PAD_LVDS0_TX1_P = 123, - MX53_PAD_LVDS0_TX0_P = 124, - MX53_PAD_GPIO_10 = 125, - MX53_PAD_GPIO_11 = 126, - MX53_PAD_GPIO_12 = 127, - MX53_PAD_GPIO_13 = 128, - MX53_PAD_GPIO_14 = 129, - MX53_PAD_NANDF_CLE = 130, - MX53_PAD_NANDF_ALE = 131, - MX53_PAD_NANDF_WP_B = 132, - MX53_PAD_NANDF_RB0 = 133, - MX53_PAD_NANDF_CS0 = 134, - MX53_PAD_NANDF_CS1 = 135, - MX53_PAD_NANDF_CS2 = 136, - MX53_PAD_NANDF_CS3 = 137, - MX53_PAD_FEC_MDIO = 138, - MX53_PAD_FEC_REF_CLK = 139, - MX53_PAD_FEC_RX_ER = 140, - MX53_PAD_FEC_CRS_DV = 141, - MX53_PAD_FEC_RXD1 = 142, - MX53_PAD_FEC_RXD0 = 143, - MX53_PAD_FEC_TX_EN = 144, - MX53_PAD_FEC_TXD1 = 145, - MX53_PAD_FEC_TXD0 = 146, - MX53_PAD_FEC_MDC = 147, - MX53_PAD_PATA_DIOW = 148, - MX53_PAD_PATA_DMACK = 149, - MX53_PAD_PATA_DMARQ = 150, - MX53_PAD_PATA_BUFFER_EN = 151, - MX53_PAD_PATA_INTRQ = 152, - MX53_PAD_PATA_DIOR = 153, - MX53_PAD_PATA_RESET_B = 154, - MX53_PAD_PATA_IORDY = 155, - MX53_PAD_PATA_DA_0 = 156, - MX53_PAD_PATA_DA_1 = 157, - MX53_PAD_PATA_DA_2 = 158, - MX53_PAD_PATA_CS_0 = 159, - MX53_PAD_PATA_CS_1 = 160, - MX53_PAD_PATA_DATA0 = 161, - MX53_PAD_PATA_DATA1 = 162, - MX53_PAD_PATA_DATA2 = 163, - MX53_PAD_PATA_DATA3 = 164, - MX53_PAD_PATA_DATA4 = 165, - MX53_PAD_PATA_DATA5 = 166, - MX53_PAD_PATA_DATA6 = 167, - MX53_PAD_PATA_DATA7 = 168, - MX53_PAD_PATA_DATA8 = 169, - MX53_PAD_PATA_DATA9 = 170, - MX53_PAD_PATA_DATA10 = 171, - MX53_PAD_PATA_DATA11 = 172, - MX53_PAD_PATA_DATA12 = 173, - MX53_PAD_PATA_DATA13 = 174, - MX53_PAD_PATA_DATA14 = 175, - MX53_PAD_PATA_DATA15 = 176, - MX53_PAD_SD1_DATA0 = 177, - MX53_PAD_SD1_DATA1 = 178, - MX53_PAD_SD1_CMD = 179, - MX53_PAD_SD1_DATA2 = 180, - MX53_PAD_SD1_CLK = 181, - MX53_PAD_SD1_DATA3 = 182, - MX53_PAD_SD2_CLK = 183, - MX53_PAD_SD2_CMD = 184, - MX53_PAD_SD2_DATA3 = 185, - MX53_PAD_SD2_DATA2 = 186, - MX53_PAD_SD2_DATA1 = 187, - MX53_PAD_SD2_DATA0 = 188, - MX53_PAD_GPIO_0 = 189, - MX53_PAD_GPIO_1 = 190, - MX53_PAD_GPIO_9 = 191, - MX53_PAD_GPIO_3 = 192, - MX53_PAD_GPIO_6 = 193, - MX53_PAD_GPIO_2 = 194, - MX53_PAD_GPIO_4 = 195, - MX53_PAD_GPIO_5 = 196, - MX53_PAD_GPIO_7 = 197, - MX53_PAD_GPIO_8 = 198, - MX53_PAD_GPIO_16 = 199, - MX53_PAD_GPIO_17 = 200, - MX53_PAD_GPIO_18 = 201, -}; - -/* imx53 register maps */ -static struct imx_pin_reg imx53_pin_regs[] = { - IMX_PIN_REG(MX53_PAD_GPIO_19, 0x348, 0x020, 0, 0x840, 0), /* MX53_PAD_GPIO_19__KPP_COL_5 */ - IMX_PIN_REG(MX53_PAD_GPIO_19, 0x348, 0x020, 1, 0x000, 0), /* MX53_PAD_GPIO_19__GPIO4_5 */ - IMX_PIN_REG(MX53_PAD_GPIO_19, 0x348, 0x020, 2, 0x000, 0), /* MX53_PAD_GPIO_19__CCM_CLKO */ - IMX_PIN_REG(MX53_PAD_GPIO_19, 0x348, 0x020, 3, 0x000, 0), /* MX53_PAD_GPIO_19__SPDIF_OUT1 */ - IMX_PIN_REG(MX53_PAD_GPIO_19, 0x348, 0x020, 4, 0x000, 0), /* MX53_PAD_GPIO_19__RTC_CE_RTC_EXT_TRIG2 */ - IMX_PIN_REG(MX53_PAD_GPIO_19, 0x348, 0x020, 5, 0x000, 0), /* MX53_PAD_GPIO_19__ECSPI1_RDY */ - IMX_PIN_REG(MX53_PAD_GPIO_19, 0x348, 0x020, 6, 0x000, 0), /* MX53_PAD_GPIO_19__FEC_TDATA_3 */ - IMX_PIN_REG(MX53_PAD_GPIO_19, 0x348, 0x020, 7, 0x000, 0), /* MX53_PAD_GPIO_19__SRC_INT_BOOT */ - IMX_PIN_REG(MX53_PAD_KEY_COL0, 0x34C, 0x024, 0, 0x000, 0), /* MX53_PAD_KEY_COL0__KPP_COL_0 */ - IMX_PIN_REG(MX53_PAD_KEY_COL0, 0x34C, 0x024, 1, 0x000, 0), /* MX53_PAD_KEY_COL0__GPIO4_6 */ - IMX_PIN_REG(MX53_PAD_KEY_COL0, 0x34C, 0x024, 2, 0x758, 0), /* MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC */ - IMX_PIN_REG(MX53_PAD_KEY_COL0, 0x34C, 0x024, 4, 0x000, 0), /* MX53_PAD_KEY_COL0__UART4_TXD_MUX */ - IMX_PIN_REG(MX53_PAD_KEY_COL0, 0x34C, 0x024, 5, 0x79C, 0), /* MX53_PAD_KEY_COL0__ECSPI1_SCLK */ - IMX_PIN_REG(MX53_PAD_KEY_COL0, 0x34C, 0x024, 6, 0x000, 0), /* MX53_PAD_KEY_COL0__FEC_RDATA_3 */ - IMX_PIN_REG(MX53_PAD_KEY_COL0, 0x34C, 0x024, 7, 0x000, 0), /* MX53_PAD_KEY_COL0__SRC_ANY_PU_RST */ - IMX_PIN_REG(MX53_PAD_KEY_ROW0, 0x350, 0x028, 0, 0x000, 0), /* MX53_PAD_KEY_ROW0__KPP_ROW_0 */ - IMX_PIN_REG(MX53_PAD_KEY_ROW0, 0x350, 0x028, 1, 0x000, 0), /* MX53_PAD_KEY_ROW0__GPIO4_7 */ - IMX_PIN_REG(MX53_PAD_KEY_ROW0, 0x350, 0x028, 2, 0x74C, 0), /* MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD */ - IMX_PIN_REG(MX53_PAD_KEY_ROW0, 0x350, 0x028, 4, 0x890, 1), /* MX53_PAD_KEY_ROW0__UART4_RXD_MUX */ - IMX_PIN_REG(MX53_PAD_KEY_ROW0, 0x350, 0x028, 5, 0x7A4, 0), /* MX53_PAD_KEY_ROW0__ECSPI1_MOSI */ - IMX_PIN_REG(MX53_PAD_KEY_ROW0, 0x350, 0x028, 6, 0x000, 0), /* MX53_PAD_KEY_ROW0__FEC_TX_ER */ - IMX_PIN_REG(MX53_PAD_KEY_COL1, 0x354, 0x02C, 0, 0x000, 0), /* MX53_PAD_KEY_COL1__KPP_COL_1 */ - IMX_PIN_REG(MX53_PAD_KEY_COL1, 0x354, 0x02C, 1, 0x000, 0), /* MX53_PAD_KEY_COL1__GPIO4_8 */ - IMX_PIN_REG(MX53_PAD_KEY_COL1, 0x354, 0x02C, 2, 0x75C, 0), /* MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS */ - IMX_PIN_REG(MX53_PAD_KEY_COL1, 0x354, 0x02C, 4, 0x000, 0), /* MX53_PAD_KEY_COL1__UART5_TXD_MUX */ - IMX_PIN_REG(MX53_PAD_KEY_COL1, 0x354, 0x02C, 5, 0x7A0, 0), /* MX53_PAD_KEY_COL1__ECSPI1_MISO */ - IMX_PIN_REG(MX53_PAD_KEY_COL1, 0x354, 0x02C, 6, 0x808, 0), /* MX53_PAD_KEY_COL1__FEC_RX_CLK */ - IMX_PIN_REG(MX53_PAD_KEY_COL1, 0x354, 0x02C, 7, 0x000, 0), /* MX53_PAD_KEY_COL1__USBPHY1_TXREADY */ - IMX_PIN_REG(MX53_PAD_KEY_ROW1, 0x358, 0x030, 0, 0x000, 0), /* MX53_PAD_KEY_ROW1__KPP_ROW_1 */ - IMX_PIN_REG(MX53_PAD_KEY_ROW1, 0x358, 0x030, 1, 0x000, 0), /* MX53_PAD_KEY_ROW1__GPIO4_9 */ - IMX_PIN_REG(MX53_PAD_KEY_ROW1, 0x358, 0x030, 2, 0x748, 0), /* MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD */ - IMX_PIN_REG(MX53_PAD_KEY_ROW1, 0x358, 0x030, 4, 0x898, 1), /* MX53_PAD_KEY_ROW1__UART5_RXD_MUX */ - IMX_PIN_REG(MX53_PAD_KEY_ROW1, 0x358, 0x030, 5, 0x7A8, 0), /* MX53_PAD_KEY_ROW1__ECSPI1_SS0 */ - IMX_PIN_REG(MX53_PAD_KEY_ROW1, 0x358, 0x030, 6, 0x800, 0), /* MX53_PAD_KEY_ROW1__FEC_COL */ - IMX_PIN_REG(MX53_PAD_KEY_ROW1, 0x358, 0x030, 7, 0x000, 0), /* MX53_PAD_KEY_ROW1__USBPHY1_RXVALID */ - IMX_PIN_REG(MX53_PAD_KEY_COL2, 0x35C, 0x034, 0, 0x000, 0), /* MX53_PAD_KEY_COL2__KPP_COL_2 */ - IMX_PIN_REG(MX53_PAD_KEY_COL2, 0x35C, 0x034, 1, 0x000, 0), /* MX53_PAD_KEY_COL2__GPIO4_10 */ - IMX_PIN_REG(MX53_PAD_KEY_COL2, 0x35C, 0x034, 2, 0x000, 0), /* MX53_PAD_KEY_COL2__CAN1_TXCAN */ - IMX_PIN_REG(MX53_PAD_KEY_COL2, 0x35C, 0x034, 4, 0x804, 0), /* MX53_PAD_KEY_COL2__FEC_MDIO */ - IMX_PIN_REG(MX53_PAD_KEY_COL2, 0x35C, 0x034, 5, 0x7AC, 0), /* MX53_PAD_KEY_COL2__ECSPI1_SS1 */ - IMX_PIN_REG(MX53_PAD_KEY_COL2, 0x35C, 0x034, 6, 0x000, 0), /* MX53_PAD_KEY_COL2__FEC_RDATA_2 */ - IMX_PIN_REG(MX53_PAD_KEY_COL2, 0x35C, 0x034, 7, 0x000, 0), /* MX53_PAD_KEY_COL2__USBPHY1_RXACTIVE */ - IMX_PIN_REG(MX53_PAD_KEY_ROW2, 0x360, 0x038, 0, 0x000, 0), /* MX53_PAD_KEY_ROW2__KPP_ROW_2 */ - IMX_PIN_REG(MX53_PAD_KEY_ROW2, 0x360, 0x038, 1, 0x000, 0), /* MX53_PAD_KEY_ROW2__GPIO4_11 */ - IMX_PIN_REG(MX53_PAD_KEY_ROW2, 0x360, 0x038, 2, 0x760, 0), /* MX53_PAD_KEY_ROW2__CAN1_RXCAN */ - IMX_PIN_REG(MX53_PAD_KEY_ROW2, 0x360, 0x038, 4, 0x000, 0), /* MX53_PAD_KEY_ROW2__FEC_MDC */ - IMX_PIN_REG(MX53_PAD_KEY_ROW2, 0x360, 0x038, 5, 0x7B0, 0), /* MX53_PAD_KEY_ROW2__ECSPI1_SS2 */ - IMX_PIN_REG(MX53_PAD_KEY_ROW2, 0x360, 0x038, 6, 0x000, 0), /* MX53_PAD_KEY_ROW2__FEC_TDATA_2 */ - IMX_PIN_REG(MX53_PAD_KEY_ROW2, 0x360, 0x038, 7, 0x000, 0), /* MX53_PAD_KEY_ROW2__USBPHY1_RXERROR */ - IMX_PIN_REG(MX53_PAD_KEY_COL3, 0x364, 0x03C, 0, 0x000, 0), /* MX53_PAD_KEY_COL3__KPP_COL_3 */ - IMX_PIN_REG(MX53_PAD_KEY_COL3, 0x364, 0x03C, 1, 0x000, 0), /* MX53_PAD_KEY_COL3__GPIO4_12 */ - IMX_PIN_REG(MX53_PAD_KEY_COL3, 0x364, 0x03C, 2, 0x000, 0), /* MX53_PAD_KEY_COL3__USBOH3_H2_DP */ - IMX_PIN_REG(MX53_PAD_KEY_COL3, 0x364, 0x03C, 3, 0x870, 0), /* MX53_PAD_KEY_COL3__SPDIF_IN1 */ - IMX_PIN_REG(MX53_PAD_KEY_COL3, 0x364, 0x03C, 4, 0x81C, 0), /* MX53_PAD_KEY_COL3__I2C2_SCL */ - IMX_PIN_REG(MX53_PAD_KEY_COL3, 0x364, 0x03C, 5, 0x7B4, 0), /* MX53_PAD_KEY_COL3__ECSPI1_SS3 */ - IMX_PIN_REG(MX53_PAD_KEY_COL3, 0x364, 0x03C, 6, 0x000, 0), /* MX53_PAD_KEY_COL3__FEC_CRS */ - IMX_PIN_REG(MX53_PAD_KEY_COL3, 0x364, 0x03C, 7, 0x000, 0), /* MX53_PAD_KEY_COL3__USBPHY1_SIECLOCK */ - IMX_PIN_REG(MX53_PAD_KEY_ROW3, 0x368, 0x040, 0, 0x000, 0), /* MX53_PAD_KEY_ROW3__KPP_ROW_3 */ - IMX_PIN_REG(MX53_PAD_KEY_ROW3, 0x368, 0x040, 1, 0x000, 0), /* MX53_PAD_KEY_ROW3__GPIO4_13 */ - IMX_PIN_REG(MX53_PAD_KEY_ROW3, 0x368, 0x040, 2, 0x000, 0), /* MX53_PAD_KEY_ROW3__USBOH3_H2_DM */ - IMX_PIN_REG(MX53_PAD_KEY_ROW3, 0x368, 0x040, 3, 0x768, 0), /* MX53_PAD_KEY_ROW3__CCM_ASRC_EXT_CLK */ - IMX_PIN_REG(MX53_PAD_KEY_ROW3, 0x368, 0x040, 4, 0x820, 0), /* MX53_PAD_KEY_ROW3__I2C2_SDA */ - IMX_PIN_REG(MX53_PAD_KEY_ROW3, 0x368, 0x040, 5, 0x000, 0), /* MX53_PAD_KEY_ROW3__OSC32K_32K_OUT */ - IMX_PIN_REG(MX53_PAD_KEY_ROW3, 0x368, 0x040, 6, 0x77C, 0), /* MX53_PAD_KEY_ROW3__CCM_PLL4_BYP */ - IMX_PIN_REG(MX53_PAD_KEY_ROW3, 0x368, 0x040, 7, 0x000, 0), /* MX53_PAD_KEY_ROW3__USBPHY1_LINESTATE_0 */ - IMX_PIN_REG(MX53_PAD_KEY_COL4, 0x36C, 0x044, 0, 0x000, 0), /* MX53_PAD_KEY_COL4__KPP_COL_4 */ - IMX_PIN_REG(MX53_PAD_KEY_COL4, 0x36C, 0x044, 1, 0x000, 0), /* MX53_PAD_KEY_COL4__GPIO4_14 */ - IMX_PIN_REG(MX53_PAD_KEY_COL4, 0x36C, 0x044, 2, 0x000, 0), /* MX53_PAD_KEY_COL4__CAN2_TXCAN */ - IMX_PIN_REG(MX53_PAD_KEY_COL4, 0x36C, 0x044, 3, 0x000, 0), /* MX53_PAD_KEY_COL4__IPU_SISG_4 */ - IMX_PIN_REG(MX53_PAD_KEY_COL4, 0x36C, 0x044, 4, 0x894, 0), /* MX53_PAD_KEY_COL4__UART5_RTS */ - IMX_PIN_REG(MX53_PAD_KEY_COL4, 0x36C, 0x044, 5, 0x89C, 0), /* MX53_PAD_KEY_COL4__USBOH3_USBOTG_OC */ - IMX_PIN_REG(MX53_PAD_KEY_COL4, 0x36C, 0x044, 7, 0x000, 0), /* MX53_PAD_KEY_COL4__USBPHY1_LINESTATE_1 */ - IMX_PIN_REG(MX53_PAD_KEY_ROW4, 0x370, 0x048, 0, 0x000, 0), /* MX53_PAD_KEY_ROW4__KPP_ROW_4 */ - IMX_PIN_REG(MX53_PAD_KEY_ROW4, 0x370, 0x048, 1, 0x000, 0), /* MX53_PAD_KEY_ROW4__GPIO4_15 */ - IMX_PIN_REG(MX53_PAD_KEY_ROW4, 0x370, 0x048, 2, 0x764, 0), /* MX53_PAD_KEY_ROW4__CAN2_RXCAN */ - IMX_PIN_REG(MX53_PAD_KEY_ROW4, 0x370, 0x048, 3, 0x000, 0), /* MX53_PAD_KEY_ROW4__IPU_SISG_5 */ - IMX_PIN_REG(MX53_PAD_KEY_ROW4, 0x370, 0x048, 4, 0x000, 0), /* MX53_PAD_KEY_ROW4__UART5_CTS */ - IMX_PIN_REG(MX53_PAD_KEY_ROW4, 0x370, 0x048, 5, 0x000, 0), /* MX53_PAD_KEY_ROW4__USBOH3_USBOTG_PWR */ - IMX_PIN_REG(MX53_PAD_KEY_ROW4, 0x370, 0x048, 7, 0x000, 0), /* MX53_PAD_KEY_ROW4__USBPHY1_VBUSVALID */ - IMX_PIN_REG(MX53_PAD_DI0_DISP_CLK, 0x378, 0x04C, 0, 0x000, 0), /* MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK */ - IMX_PIN_REG(MX53_PAD_DI0_DISP_CLK, 0x378, 0x04C, 1, 0x000, 0), /* MX53_PAD_DI0_DISP_CLK__GPIO4_16 */ - IMX_PIN_REG(MX53_PAD_DI0_DISP_CLK, 0x378, 0x04C, 2, 0x000, 0), /* MX53_PAD_DI0_DISP_CLK__USBOH3_USBH2_DIR */ - IMX_PIN_REG(MX53_PAD_DI0_DISP_CLK, 0x378, 0x04C, 5, 0x000, 0), /* MX53_PAD_DI0_DISP_CLK__SDMA_DEBUG_CORE_STATE_0 */ - IMX_PIN_REG(MX53_PAD_DI0_DISP_CLK, 0x378, 0x04C, 6, 0x000, 0), /* MX53_PAD_DI0_DISP_CLK__EMI_EMI_DEBUG_0 */ - IMX_PIN_REG(MX53_PAD_DI0_DISP_CLK, 0x378, 0x04C, 7, 0x000, 0), /* MX53_PAD_DI0_DISP_CLK__USBPHY1_AVALID */ - IMX_PIN_REG(MX53_PAD_DI0_PIN15, 0x37C, 0x050, 0, 0x000, 0), /* MX53_PAD_DI0_PIN15__IPU_DI0_PIN15 */ - IMX_PIN_REG(MX53_PAD_DI0_PIN15, 0x37C, 0x050, 1, 0x000, 0), /* MX53_PAD_DI0_PIN15__GPIO4_17 */ - IMX_PIN_REG(MX53_PAD_DI0_PIN15, 0x37C, 0x050, 2, 0x000, 0), /* MX53_PAD_DI0_PIN15__AUDMUX_AUD6_TXC */ - IMX_PIN_REG(MX53_PAD_DI0_PIN15, 0x37C, 0x050, 5, 0x000, 0), /* MX53_PAD_DI0_PIN15__SDMA_DEBUG_CORE_STATE_1 */ - IMX_PIN_REG(MX53_PAD_DI0_PIN15, 0x37C, 0x050, 6, 0x000, 0), /* MX53_PAD_DI0_PIN15__EMI_EMI_DEBUG_1 */ - IMX_PIN_REG(MX53_PAD_DI0_PIN15, 0x37C, 0x050, 7, 0x000, 0), /* MX53_PAD_DI0_PIN15__USBPHY1_BVALID */ - IMX_PIN_REG(MX53_PAD_DI0_PIN2, 0x380, 0x054, 0, 0x000, 0), /* MX53_PAD_DI0_PIN2__IPU_DI0_PIN2 */ - IMX_PIN_REG(MX53_PAD_DI0_PIN2, 0x380, 0x054, 1, 0x000, 0), /* MX53_PAD_DI0_PIN2__GPIO4_18 */ - IMX_PIN_REG(MX53_PAD_DI0_PIN2, 0x380, 0x054, 2, 0x000, 0), /* MX53_PAD_DI0_PIN2__AUDMUX_AUD6_TXD */ - IMX_PIN_REG(MX53_PAD_DI0_PIN2, 0x380, 0x054, 5, 0x000, 0), /* MX53_PAD_DI0_PIN2__SDMA_DEBUG_CORE_STATE_2 */ - IMX_PIN_REG(MX53_PAD_DI0_PIN2, 0x380, 0x054, 6, 0x000, 0), /* MX53_PAD_DI0_PIN2__EMI_EMI_DEBUG_2 */ - IMX_PIN_REG(MX53_PAD_DI0_PIN2, 0x380, 0x054, 7, 0x000, 0), /* MX53_PAD_DI0_PIN2__USBPHY1_ENDSESSION */ - IMX_PIN_REG(MX53_PAD_DI0_PIN3, 0x384, 0x058, 0, 0x000, 0), /* MX53_PAD_DI0_PIN3__IPU_DI0_PIN3 */ - IMX_PIN_REG(MX53_PAD_DI0_PIN3, 0x384, 0x058, 1, 0x000, 0), /* MX53_PAD_DI0_PIN3__GPIO4_19 */ - IMX_PIN_REG(MX53_PAD_DI0_PIN3, 0x384, 0x058, 2, 0x000, 0), /* MX53_PAD_DI0_PIN3__AUDMUX_AUD6_TXFS */ - IMX_PIN_REG(MX53_PAD_DI0_PIN3, 0x384, 0x058, 5, 0x000, 0), /* MX53_PAD_DI0_PIN3__SDMA_DEBUG_CORE_STATE_3 */ - IMX_PIN_REG(MX53_PAD_DI0_PIN3, 0x384, 0x058, 6, 0x000, 0), /* MX53_PAD_DI0_PIN3__EMI_EMI_DEBUG_3 */ - IMX_PIN_REG(MX53_PAD_DI0_PIN3, 0x384, 0x058, 7, 0x000, 0), /* MX53_PAD_DI0_PIN3__USBPHY1_IDDIG */ - IMX_PIN_REG(MX53_PAD_DI0_PIN4, 0x388, 0x05C, 0, 0x000, 0), /* MX53_PAD_DI0_PIN4__IPU_DI0_PIN4 */ - IMX_PIN_REG(MX53_PAD_DI0_PIN4, 0x388, 0x05C, 1, 0x000, 0), /* MX53_PAD_DI0_PIN4__GPIO4_20 */ - IMX_PIN_REG(MX53_PAD_DI0_PIN4, 0x388, 0x05C, 2, 0x000, 0), /* MX53_PAD_DI0_PIN4__AUDMUX_AUD6_RXD */ - IMX_PIN_REG(MX53_PAD_DI0_PIN4, 0x388, 0x05C, 3, 0x7FC, 0), /* MX53_PAD_DI0_PIN4__ESDHC1_WP */ - IMX_PIN_REG(MX53_PAD_DI0_PIN4, 0x388, 0x05C, 5, 0x000, 0), /* MX53_PAD_DI0_PIN4__SDMA_DEBUG_YIELD */ - IMX_PIN_REG(MX53_PAD_DI0_PIN4, 0x388, 0x05C, 6, 0x000, 0), /* MX53_PAD_DI0_PIN4__EMI_EMI_DEBUG_4 */ - IMX_PIN_REG(MX53_PAD_DI0_PIN4, 0x388, 0x05C, 7, 0x000, 0), /* MX53_PAD_DI0_PIN4__USBPHY1_HOSTDISCONNECT */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT0, 0x38C, 0x060, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT0, 0x38C, 0x060, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT0__GPIO4_21 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT0, 0x38C, 0x060, 2, 0x780, 0), /* MX53_PAD_DISP0_DAT0__CSPI_SCLK */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT0, 0x38C, 0x060, 3, 0x000, 0), /* MX53_PAD_DISP0_DAT0__USBOH3_USBH2_DATA_0 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT0, 0x38C, 0x060, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT0__SDMA_DEBUG_CORE_RUN */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT0, 0x38C, 0x060, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT0__EMI_EMI_DEBUG_5 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT0, 0x38C, 0x060, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT0__USBPHY2_TXREADY */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT1, 0x390, 0x064, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT1, 0x390, 0x064, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT1__GPIO4_22 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT1, 0x390, 0x064, 2, 0x788, 0), /* MX53_PAD_DISP0_DAT1__CSPI_MOSI */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT1, 0x390, 0x064, 3, 0x000, 0), /* MX53_PAD_DISP0_DAT1__USBOH3_USBH2_DATA_1 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT1, 0x390, 0x064, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT1__SDMA_DEBUG_EVENT_CHANNEL_SEL */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT1, 0x390, 0x064, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT1__EMI_EMI_DEBUG_6 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT1, 0x390, 0x064, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT1__USBPHY2_RXVALID */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT2, 0x394, 0x068, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT2, 0x394, 0x068, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT2__GPIO4_23 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT2, 0x394, 0x068, 2, 0x784, 0), /* MX53_PAD_DISP0_DAT2__CSPI_MISO */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT2, 0x394, 0x068, 3, 0x000, 0), /* MX53_PAD_DISP0_DAT2__USBOH3_USBH2_DATA_2 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT2, 0x394, 0x068, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT2__SDMA_DEBUG_MODE */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT2, 0x394, 0x068, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT2__EMI_EMI_DEBUG_7 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT2, 0x394, 0x068, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT2__USBPHY2_RXACTIVE */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT3, 0x398, 0x06C, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT3, 0x398, 0x06C, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT3__GPIO4_24 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT3, 0x398, 0x06C, 2, 0x78C, 0), /* MX53_PAD_DISP0_DAT3__CSPI_SS0 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT3, 0x398, 0x06C, 3, 0x000, 0), /* MX53_PAD_DISP0_DAT3__USBOH3_USBH2_DATA_3 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT3, 0x398, 0x06C, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT3__SDMA_DEBUG_BUS_ERROR */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT3, 0x398, 0x06C, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT3__EMI_EMI_DEBUG_8 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT3, 0x398, 0x06C, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT3__USBPHY2_RXERROR */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT4, 0x39C, 0x070, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT4, 0x39C, 0x070, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT4__GPIO4_25 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT4, 0x39C, 0x070, 2, 0x790, 0), /* MX53_PAD_DISP0_DAT4__CSPI_SS1 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT4, 0x39C, 0x070, 3, 0x000, 0), /* MX53_PAD_DISP0_DAT4__USBOH3_USBH2_DATA_4 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT4, 0x39C, 0x070, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT4__SDMA_DEBUG_BUS_RWB */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT4, 0x39C, 0x070, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT4__EMI_EMI_DEBUG_9 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT4, 0x39C, 0x070, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT4__USBPHY2_SIECLOCK */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT5, 0x3A0, 0x074, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT5, 0x3A0, 0x074, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT5__GPIO4_26 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT5, 0x3A0, 0x074, 2, 0x794, 0), /* MX53_PAD_DISP0_DAT5__CSPI_SS2 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT5, 0x3A0, 0x074, 3, 0x000, 0), /* MX53_PAD_DISP0_DAT5__USBOH3_USBH2_DATA_5 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT5, 0x3A0, 0x074, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT5__SDMA_DEBUG_MATCHED_DMBUS */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT5, 0x3A0, 0x074, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT5__EMI_EMI_DEBUG_10 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT5, 0x3A0, 0x074, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT5__USBPHY2_LINESTATE_0 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT6, 0x3A4, 0x078, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT6, 0x3A4, 0x078, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT6__GPIO4_27 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT6, 0x3A4, 0x078, 2, 0x798, 0), /* MX53_PAD_DISP0_DAT6__CSPI_SS3 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT6, 0x3A4, 0x078, 3, 0x000, 0), /* MX53_PAD_DISP0_DAT6__USBOH3_USBH2_DATA_6 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT6, 0x3A4, 0x078, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT6__SDMA_DEBUG_RTBUFFER_WRITE */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT6, 0x3A4, 0x078, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT6__EMI_EMI_DEBUG_11 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT6, 0x3A4, 0x078, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT6__USBPHY2_LINESTATE_1 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT7, 0x3A8, 0x07C, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT7, 0x3A8, 0x07C, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT7__GPIO4_28 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT7, 0x3A8, 0x07C, 2, 0x000, 0), /* MX53_PAD_DISP0_DAT7__CSPI_RDY */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT7, 0x3A8, 0x07C, 3, 0x000, 0), /* MX53_PAD_DISP0_DAT7__USBOH3_USBH2_DATA_7 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT7, 0x3A8, 0x07C, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT7__SDMA_DEBUG_EVENT_CHANNEL_0 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT7, 0x3A8, 0x07C, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT7__EMI_EMI_DEBUG_12 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT7, 0x3A8, 0x07C, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT7__USBPHY2_VBUSVALID */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT8, 0x3AC, 0x080, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT8, 0x3AC, 0x080, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT8__GPIO4_29 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT8, 0x3AC, 0x080, 2, 0x000, 0), /* MX53_PAD_DISP0_DAT8__PWM1_PWMO */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT8, 0x3AC, 0x080, 3, 0x000, 0), /* MX53_PAD_DISP0_DAT8__WDOG1_WDOG_B */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT8, 0x3AC, 0x080, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT8__SDMA_DEBUG_EVENT_CHANNEL_1 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT8, 0x3AC, 0x080, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT8__EMI_EMI_DEBUG_13 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT8, 0x3AC, 0x080, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT8__USBPHY2_AVALID */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT9, 0x3B0, 0x084, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT9, 0x3B0, 0x084, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT9__GPIO4_30 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT9, 0x3B0, 0x084, 2, 0x000, 0), /* MX53_PAD_DISP0_DAT9__PWM2_PWMO */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT9, 0x3B0, 0x084, 3, 0x000, 0), /* MX53_PAD_DISP0_DAT9__WDOG2_WDOG_B */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT9, 0x3B0, 0x084, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT9__SDMA_DEBUG_EVENT_CHANNEL_2 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT9, 0x3B0, 0x084, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT9__EMI_EMI_DEBUG_14 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT9, 0x3B0, 0x084, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT9__USBPHY2_VSTATUS_0 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT10, 0x3B4, 0x088, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT10, 0x3B4, 0x088, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT10__GPIO4_31 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT10, 0x3B4, 0x088, 2, 0x000, 0), /* MX53_PAD_DISP0_DAT10__USBOH3_USBH2_STP */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT10, 0x3B4, 0x088, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT10__SDMA_DEBUG_EVENT_CHANNEL_3 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT10, 0x3B4, 0x088, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT10__EMI_EMI_DEBUG_15 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT10, 0x3B4, 0x088, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT10__USBPHY2_VSTATUS_1 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT11, 0x3B8, 0x08C, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT11, 0x3B8, 0x08C, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT11__GPIO5_5 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT11, 0x3B8, 0x08C, 2, 0x000, 0), /* MX53_PAD_DISP0_DAT11__USBOH3_USBH2_NXT */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT11, 0x3B8, 0x08C, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT11__SDMA_DEBUG_EVENT_CHANNEL_4 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT11, 0x3B8, 0x08C, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT11__EMI_EMI_DEBUG_16 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT11, 0x3B8, 0x08C, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT11__USBPHY2_VSTATUS_2 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT12, 0x3BC, 0x090, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT12, 0x3BC, 0x090, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT12__GPIO5_6 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT12, 0x3BC, 0x090, 2, 0x000, 0), /* MX53_PAD_DISP0_DAT12__USBOH3_USBH2_CLK */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT12, 0x3BC, 0x090, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT12__SDMA_DEBUG_EVENT_CHANNEL_5 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT12, 0x3BC, 0x090, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT12__EMI_EMI_DEBUG_17 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT12, 0x3BC, 0x090, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT12__USBPHY2_VSTATUS_3 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT13, 0x3C0, 0x094, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT13, 0x3C0, 0x094, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT13__GPIO5_7 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT13, 0x3C0, 0x094, 3, 0x754, 0), /* MX53_PAD_DISP0_DAT13__AUDMUX_AUD5_RXFS */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT13, 0x3C0, 0x094, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT13__SDMA_DEBUG_EVT_CHN_LINES_0 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT13, 0x3C0, 0x094, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT13__EMI_EMI_DEBUG_18 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT13, 0x3C0, 0x094, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT13__USBPHY2_VSTATUS_4 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT14, 0x3C4, 0x098, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT14, 0x3C4, 0x098, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT14__GPIO5_8 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT14, 0x3C4, 0x098, 3, 0x750, 0), /* MX53_PAD_DISP0_DAT14__AUDMUX_AUD5_RXC */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT14, 0x3C4, 0x098, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT14__SDMA_DEBUG_EVT_CHN_LINES_1 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT14, 0x3C4, 0x098, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT14__EMI_EMI_DEBUG_19 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT14, 0x3C4, 0x098, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT14__USBPHY2_VSTATUS_5 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT15, 0x3C8, 0x09C, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT15, 0x3C8, 0x09C, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT15__GPIO5_9 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT15, 0x3C8, 0x09C, 2, 0x7AC, 1), /* MX53_PAD_DISP0_DAT15__ECSPI1_SS1 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT15, 0x3C8, 0x09C, 3, 0x7C8, 0), /* MX53_PAD_DISP0_DAT15__ECSPI2_SS1 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT15, 0x3C8, 0x09C, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT15__SDMA_DEBUG_EVT_CHN_LINES_2 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT15, 0x3C8, 0x09C, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT15__EMI_EMI_DEBUG_20 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT15, 0x3C8, 0x09C, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT15__USBPHY2_VSTATUS_6 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT16, 0x3CC, 0x0A0, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT16, 0x3CC, 0x0A0, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT16__GPIO5_10 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT16, 0x3CC, 0x0A0, 2, 0x7C0, 0), /* MX53_PAD_DISP0_DAT16__ECSPI2_MOSI */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT16, 0x3CC, 0x0A0, 3, 0x758, 1), /* MX53_PAD_DISP0_DAT16__AUDMUX_AUD5_TXC */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT16, 0x3CC, 0x0A0, 4, 0x868, 0), /* MX53_PAD_DISP0_DAT16__SDMA_EXT_EVENT_0 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT16, 0x3CC, 0x0A0, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT16__SDMA_DEBUG_EVT_CHN_LINES_3 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT16, 0x3CC, 0x0A0, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT16__EMI_EMI_DEBUG_21 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT16, 0x3CC, 0x0A0, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT16__USBPHY2_VSTATUS_7 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT17, 0x3D0, 0x0A4, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT17, 0x3D0, 0x0A4, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT17__GPIO5_11 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT17, 0x3D0, 0x0A4, 2, 0x7BC, 0), /* MX53_PAD_DISP0_DAT17__ECSPI2_MISO */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT17, 0x3D0, 0x0A4, 3, 0x74C, 1), /* MX53_PAD_DISP0_DAT17__AUDMUX_AUD5_TXD */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT17, 0x3D0, 0x0A4, 4, 0x86C, 0), /* MX53_PAD_DISP0_DAT17__SDMA_EXT_EVENT_1 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT17, 0x3D0, 0x0A4, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT17__SDMA_DEBUG_EVT_CHN_LINES_4 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT17, 0x3D0, 0x0A4, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT17__EMI_EMI_DEBUG_22 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT18, 0x3D4, 0x0A8, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT18, 0x3D4, 0x0A8, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT18__GPIO5_12 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT18, 0x3D4, 0x0A8, 2, 0x7C4, 0), /* MX53_PAD_DISP0_DAT18__ECSPI2_SS0 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT18, 0x3D4, 0x0A8, 3, 0x75C, 1), /* MX53_PAD_DISP0_DAT18__AUDMUX_AUD5_TXFS */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT18, 0x3D4, 0x0A8, 4, 0x73C, 0), /* MX53_PAD_DISP0_DAT18__AUDMUX_AUD4_RXFS */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT18, 0x3D4, 0x0A8, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT18__SDMA_DEBUG_EVT_CHN_LINES_5 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT18, 0x3D4, 0x0A8, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT18__EMI_EMI_DEBUG_23 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT18, 0x3D4, 0x0A8, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT18__EMI_WEIM_CS_2 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT19, 0x3D8, 0x0AC, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT19, 0x3D8, 0x0AC, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT19__GPIO5_13 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT19, 0x3D8, 0x0AC, 2, 0x7B8, 0), /* MX53_PAD_DISP0_DAT19__ECSPI2_SCLK */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT19, 0x3D8, 0x0AC, 3, 0x748, 1), /* MX53_PAD_DISP0_DAT19__AUDMUX_AUD5_RXD */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT19, 0x3D8, 0x0AC, 4, 0x738, 0), /* MX53_PAD_DISP0_DAT19__AUDMUX_AUD4_RXC */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT19, 0x3D8, 0x0AC, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT19__SDMA_DEBUG_EVT_CHN_LINES_6 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT19, 0x3D8, 0x0AC, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT19__EMI_EMI_DEBUG_24 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT19, 0x3D8, 0x0AC, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT19__EMI_WEIM_CS_3 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT20, 0x3DC, 0x0B0, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT20, 0x3DC, 0x0B0, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT20__GPIO5_14 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT20, 0x3DC, 0x0B0, 2, 0x79C, 1), /* MX53_PAD_DISP0_DAT20__ECSPI1_SCLK */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT20, 0x3DC, 0x0B0, 3, 0x740, 0), /* MX53_PAD_DISP0_DAT20__AUDMUX_AUD4_TXC */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT20, 0x3DC, 0x0B0, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT20__SDMA_DEBUG_EVT_CHN_LINES_7 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT20, 0x3DC, 0x0B0, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT20__EMI_EMI_DEBUG_25 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT20, 0x3DC, 0x0B0, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT20__SATA_PHY_TDI */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT21, 0x3E0, 0x0B4, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT21, 0x3E0, 0x0B4, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT21__GPIO5_15 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT21, 0x3E0, 0x0B4, 2, 0x7A4, 1), /* MX53_PAD_DISP0_DAT21__ECSPI1_MOSI */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT21, 0x3E0, 0x0B4, 3, 0x734, 0), /* MX53_PAD_DISP0_DAT21__AUDMUX_AUD4_TXD */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT21, 0x3E0, 0x0B4, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT21__SDMA_DEBUG_BUS_DEVICE_0 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT21, 0x3E0, 0x0B4, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT21__EMI_EMI_DEBUG_26 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT21, 0x3E0, 0x0B4, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT21__SATA_PHY_TDO */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT22, 0x3E4, 0x0B8, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT22, 0x3E4, 0x0B8, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT22__GPIO5_16 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT22, 0x3E4, 0x0B8, 2, 0x7A0, 1), /* MX53_PAD_DISP0_DAT22__ECSPI1_MISO */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT22, 0x3E4, 0x0B8, 3, 0x744, 0), /* MX53_PAD_DISP0_DAT22__AUDMUX_AUD4_TXFS */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT22, 0x3E4, 0x0B8, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT22__SDMA_DEBUG_BUS_DEVICE_1 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT22, 0x3E4, 0x0B8, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT22__EMI_EMI_DEBUG_27 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT22, 0x3E4, 0x0B8, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT22__SATA_PHY_TCK */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT23, 0x3E8, 0x0BC, 0, 0x000, 0), /* MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT23, 0x3E8, 0x0BC, 1, 0x000, 0), /* MX53_PAD_DISP0_DAT23__GPIO5_17 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT23, 0x3E8, 0x0BC, 2, 0x7A8, 1), /* MX53_PAD_DISP0_DAT23__ECSPI1_SS0 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT23, 0x3E8, 0x0BC, 3, 0x730, 0), /* MX53_PAD_DISP0_DAT23__AUDMUX_AUD4_RXD */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT23, 0x3E8, 0x0BC, 5, 0x000, 0), /* MX53_PAD_DISP0_DAT23__SDMA_DEBUG_BUS_DEVICE_2 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT23, 0x3E8, 0x0BC, 6, 0x000, 0), /* MX53_PAD_DISP0_DAT23__EMI_EMI_DEBUG_28 */ - IMX_PIN_REG(MX53_PAD_DISP0_DAT23, 0x3E8, 0x0BC, 7, 0x000, 0), /* MX53_PAD_DISP0_DAT23__SATA_PHY_TMS */ - IMX_PIN_REG(MX53_PAD_CSI0_PIXCLK, 0x3EC, 0x0C0, 0, 0x000, 0), /* MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK */ - IMX_PIN_REG(MX53_PAD_CSI0_PIXCLK, 0x3EC, 0x0C0, 1, 0x000, 0), /* MX53_PAD_CSI0_PIXCLK__GPIO5_18 */ - IMX_PIN_REG(MX53_PAD_CSI0_PIXCLK, 0x3EC, 0x0C0, 5, 0x000, 0), /* MX53_PAD_CSI0_PIXCLK__SDMA_DEBUG_PC_0 */ - IMX_PIN_REG(MX53_PAD_CSI0_PIXCLK, 0x3EC, 0x0C0, 6, 0x000, 0), /* MX53_PAD_CSI0_PIXCLK__EMI_EMI_DEBUG_29 */ - IMX_PIN_REG(MX53_PAD_CSI0_MCLK, 0x3F0, 0x0C4, 0, 0x000, 0), /* MX53_PAD_CSI0_MCLK__IPU_CSI0_HSYNC */ - IMX_PIN_REG(MX53_PAD_CSI0_MCLK, 0x3F0, 0x0C4, 1, 0x000, 0), /* MX53_PAD_CSI0_MCLK__GPIO5_19 */ - IMX_PIN_REG(MX53_PAD_CSI0_MCLK, 0x3F0, 0x0C4, 2, 0x000, 0), /* MX53_PAD_CSI0_MCLK__CCM_CSI0_MCLK */ - IMX_PIN_REG(MX53_PAD_CSI0_MCLK, 0x3F0, 0x0C4, 5, 0x000, 0), /* MX53_PAD_CSI0_MCLK__SDMA_DEBUG_PC_1 */ - IMX_PIN_REG(MX53_PAD_CSI0_MCLK, 0x3F0, 0x0C4, 6, 0x000, 0), /* MX53_PAD_CSI0_MCLK__EMI_EMI_DEBUG_30 */ - IMX_PIN_REG(MX53_PAD_CSI0_MCLK, 0x3F0, 0x0C4, 7, 0x000, 0), /* MX53_PAD_CSI0_MCLK__TPIU_TRCTL */ - IMX_PIN_REG(MX53_PAD_CSI0_DATA_EN, 0x3F4, 0x0C8, 0, 0x000, 0), /* MX53_PAD_CSI0_DATA_EN__IPU_CSI0_DATA_EN */ - IMX_PIN_REG(MX53_PAD_CSI0_DATA_EN, 0x3F4, 0x0C8, 1, 0x000, 0), /* MX53_PAD_CSI0_DATA_EN__GPIO5_20 */ - IMX_PIN_REG(MX53_PAD_CSI0_DATA_EN, 0x3F4, 0x0C8, 5, 0x000, 0), /* MX53_PAD_CSI0_DATA_EN__SDMA_DEBUG_PC_2 */ - IMX_PIN_REG(MX53_PAD_CSI0_DATA_EN, 0x3F4, 0x0C8, 6, 0x000, 0), /* MX53_PAD_CSI0_DATA_EN__EMI_EMI_DEBUG_31 */ - IMX_PIN_REG(MX53_PAD_CSI0_DATA_EN, 0x3F4, 0x0C8, 7, 0x000, 0), /* MX53_PAD_CSI0_DATA_EN__TPIU_TRCLK */ - IMX_PIN_REG(MX53_PAD_CSI0_VSYNC, 0x3F8, 0x0CC, 0, 0x000, 0), /* MX53_PAD_CSI0_VSYNC__IPU_CSI0_VSYNC */ - IMX_PIN_REG(MX53_PAD_CSI0_VSYNC, 0x3F8, 0x0CC, 1, 0x000, 0), /* MX53_PAD_CSI0_VSYNC__GPIO5_21 */ - IMX_PIN_REG(MX53_PAD_CSI0_VSYNC, 0x3F8, 0x0CC, 5, 0x000, 0), /* MX53_PAD_CSI0_VSYNC__SDMA_DEBUG_PC_3 */ - IMX_PIN_REG(MX53_PAD_CSI0_VSYNC, 0x3F8, 0x0CC, 6, 0x000, 0), /* MX53_PAD_CSI0_VSYNC__EMI_EMI_DEBUG_32 */ - IMX_PIN_REG(MX53_PAD_CSI0_VSYNC, 0x3F8, 0x0CC, 7, 0x000, 0), /* MX53_PAD_CSI0_VSYNC__TPIU_TRACE_0 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT4, 0x3FC, 0x0D0, 0, 0x000, 0), /* MX53_PAD_CSI0_DAT4__IPU_CSI0_D_4 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT4, 0x3FC, 0x0D0, 1, 0x000, 0), /* MX53_PAD_CSI0_DAT4__GPIO5_22 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT4, 0x3FC, 0x0D0, 2, 0x840, 1), /* MX53_PAD_CSI0_DAT4__KPP_COL_5 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT4, 0x3FC, 0x0D0, 3, 0x79C, 2), /* MX53_PAD_CSI0_DAT4__ECSPI1_SCLK */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT4, 0x3FC, 0x0D0, 4, 0x000, 0), /* MX53_PAD_CSI0_DAT4__USBOH3_USBH3_STP */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT4, 0x3FC, 0x0D0, 5, 0x000, 0), /* MX53_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT4, 0x3FC, 0x0D0, 6, 0x000, 0), /* MX53_PAD_CSI0_DAT4__EMI_EMI_DEBUG_33 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT4, 0x3FC, 0x0D0, 7, 0x000, 0), /* MX53_PAD_CSI0_DAT4__TPIU_TRACE_1 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT5, 0x400, 0x0D4, 0, 0x000, 0), /* MX53_PAD_CSI0_DAT5__IPU_CSI0_D_5 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT5, 0x400, 0x0D4, 1, 0x000, 0), /* MX53_PAD_CSI0_DAT5__GPIO5_23 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT5, 0x400, 0x0D4, 2, 0x84C, 0), /* MX53_PAD_CSI0_DAT5__KPP_ROW_5 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT5, 0x400, 0x0D4, 3, 0x7A4, 2), /* MX53_PAD_CSI0_DAT5__ECSPI1_MOSI */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT5, 0x400, 0x0D4, 4, 0x000, 0), /* MX53_PAD_CSI0_DAT5__USBOH3_USBH3_NXT */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT5, 0x400, 0x0D4, 5, 0x000, 0), /* MX53_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT5, 0x400, 0x0D4, 6, 0x000, 0), /* MX53_PAD_CSI0_DAT5__EMI_EMI_DEBUG_34 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT5, 0x400, 0x0D4, 7, 0x000, 0), /* MX53_PAD_CSI0_DAT5__TPIU_TRACE_2 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT6, 0x404, 0x0D8, 0, 0x000, 0), /* MX53_PAD_CSI0_DAT6__IPU_CSI0_D_6 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT6, 0x404, 0x0D8, 1, 0x000, 0), /* MX53_PAD_CSI0_DAT6__GPIO5_24 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT6, 0x404, 0x0D8, 2, 0x844, 0), /* MX53_PAD_CSI0_DAT6__KPP_COL_6 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT6, 0x404, 0x0D8, 3, 0x7A0, 2), /* MX53_PAD_CSI0_DAT6__ECSPI1_MISO */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT6, 0x404, 0x0D8, 4, 0x000, 0), /* MX53_PAD_CSI0_DAT6__USBOH3_USBH3_CLK */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT6, 0x404, 0x0D8, 5, 0x000, 0), /* MX53_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT6, 0x404, 0x0D8, 6, 0x000, 0), /* MX53_PAD_CSI0_DAT6__EMI_EMI_DEBUG_35 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT6, 0x404, 0x0D8, 7, 0x000, 0), /* MX53_PAD_CSI0_DAT6__TPIU_TRACE_3 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT7, 0x408, 0x0DC, 0, 0x000, 0), /* MX53_PAD_CSI0_DAT7__IPU_CSI0_D_7 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT7, 0x408, 0x0DC, 1, 0x000, 0), /* MX53_PAD_CSI0_DAT7__GPIO5_25 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT7, 0x408, 0x0DC, 2, 0x850, 0), /* MX53_PAD_CSI0_DAT7__KPP_ROW_6 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT7, 0x408, 0x0DC, 3, 0x7A8, 2), /* MX53_PAD_CSI0_DAT7__ECSPI1_SS0 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT7, 0x408, 0x0DC, 4, 0x000, 0), /* MX53_PAD_CSI0_DAT7__USBOH3_USBH3_DIR */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT7, 0x408, 0x0DC, 5, 0x000, 0), /* MX53_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT7, 0x408, 0x0DC, 6, 0x000, 0), /* MX53_PAD_CSI0_DAT7__EMI_EMI_DEBUG_36 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT7, 0x408, 0x0DC, 7, 0x000, 0), /* MX53_PAD_CSI0_DAT7__TPIU_TRACE_4 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT8, 0x40C, 0x0E0, 0, 0x000, 0), /* MX53_PAD_CSI0_DAT8__IPU_CSI0_D_8 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT8, 0x40C, 0x0E0, 1, 0x000, 0), /* MX53_PAD_CSI0_DAT8__GPIO5_26 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT8, 0x40C, 0x0E0, 2, 0x848, 0), /* MX53_PAD_CSI0_DAT8__KPP_COL_7 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT8, 0x40C, 0x0E0, 3, 0x7B8, 1), /* MX53_PAD_CSI0_DAT8__ECSPI2_SCLK */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT8, 0x40C, 0x0E0, 4, 0x000, 0), /* MX53_PAD_CSI0_DAT8__USBOH3_USBH3_OC */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT8, 0x40C, 0x0E0, 5, 0x818, 0), /* MX53_PAD_CSI0_DAT8__I2C1_SDA */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT8, 0x40C, 0x0E0, 6, 0x000, 0), /* MX53_PAD_CSI0_DAT8__EMI_EMI_DEBUG_37 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT8, 0x40C, 0x0E0, 7, 0x000, 0), /* MX53_PAD_CSI0_DAT8__TPIU_TRACE_5 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT9, 0x410, 0x0E4, 0, 0x000, 0), /* MX53_PAD_CSI0_DAT9__IPU_CSI0_D_9 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT9, 0x410, 0x0E4, 1, 0x000, 0), /* MX53_PAD_CSI0_DAT9__GPIO5_27 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT9, 0x410, 0x0E4, 2, 0x854, 0), /* MX53_PAD_CSI0_DAT9__KPP_ROW_7 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT9, 0x410, 0x0E4, 3, 0x7C0, 1), /* MX53_PAD_CSI0_DAT9__ECSPI2_MOSI */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT9, 0x410, 0x0E4, 4, 0x000, 0), /* MX53_PAD_CSI0_DAT9__USBOH3_USBH3_PWR */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT9, 0x410, 0x0E4, 5, 0x814, 0), /* MX53_PAD_CSI0_DAT9__I2C1_SCL */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT9, 0x410, 0x0E4, 6, 0x000, 0), /* MX53_PAD_CSI0_DAT9__EMI_EMI_DEBUG_38 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT9, 0x410, 0x0E4, 7, 0x000, 0), /* MX53_PAD_CSI0_DAT9__TPIU_TRACE_6 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT10, 0x414, 0x0E8, 0, 0x000, 0), /* MX53_PAD_CSI0_DAT10__IPU_CSI0_D_10 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT10, 0x414, 0x0E8, 1, 0x000, 0), /* MX53_PAD_CSI0_DAT10__GPIO5_28 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT10, 0x414, 0x0E8, 2, 0x000, 0), /* MX53_PAD_CSI0_DAT10__UART1_TXD_MUX */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT10, 0x414, 0x0E8, 3, 0x7BC, 1), /* MX53_PAD_CSI0_DAT10__ECSPI2_MISO */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT10, 0x414, 0x0E8, 4, 0x000, 0), /* MX53_PAD_CSI0_DAT10__AUDMUX_AUD3_RXC */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT10, 0x414, 0x0E8, 5, 0x000, 0), /* MX53_PAD_CSI0_DAT10__SDMA_DEBUG_PC_4 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT10, 0x414, 0x0E8, 6, 0x000, 0), /* MX53_PAD_CSI0_DAT10__EMI_EMI_DEBUG_39 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT10, 0x414, 0x0E8, 7, 0x000, 0), /* MX53_PAD_CSI0_DAT10__TPIU_TRACE_7 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT11, 0x418, 0x0EC, 0, 0x000, 0), /* MX53_PAD_CSI0_DAT11__IPU_CSI0_D_11 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT11, 0x418, 0x0EC, 1, 0x000, 0), /* MX53_PAD_CSI0_DAT11__GPIO5_29 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT11, 0x418, 0x0EC, 2, 0x878, 1), /* MX53_PAD_CSI0_DAT11__UART1_RXD_MUX */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT11, 0x418, 0x0EC, 3, 0x7C4, 1), /* MX53_PAD_CSI0_DAT11__ECSPI2_SS0 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT11, 0x418, 0x0EC, 4, 0x000, 0), /* MX53_PAD_CSI0_DAT11__AUDMUX_AUD3_RXFS */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT11, 0x418, 0x0EC, 5, 0x000, 0), /* MX53_PAD_CSI0_DAT11__SDMA_DEBUG_PC_5 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT11, 0x418, 0x0EC, 6, 0x000, 0), /* MX53_PAD_CSI0_DAT11__EMI_EMI_DEBUG_40 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT11, 0x418, 0x0EC, 7, 0x000, 0), /* MX53_PAD_CSI0_DAT11__TPIU_TRACE_8 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT12, 0x41C, 0x0F0, 0, 0x000, 0), /* MX53_PAD_CSI0_DAT12__IPU_CSI0_D_12 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT12, 0x41C, 0x0F0, 1, 0x000, 0), /* MX53_PAD_CSI0_DAT12__GPIO5_30 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT12, 0x41C, 0x0F0, 2, 0x000, 0), /* MX53_PAD_CSI0_DAT12__UART4_TXD_MUX */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT12, 0x41C, 0x0F0, 4, 0x000, 0), /* MX53_PAD_CSI0_DAT12__USBOH3_USBH3_DATA_0 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT12, 0x41C, 0x0F0, 5, 0x000, 0), /* MX53_PAD_CSI0_DAT12__SDMA_DEBUG_PC_6 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT12, 0x41C, 0x0F0, 6, 0x000, 0), /* MX53_PAD_CSI0_DAT12__EMI_EMI_DEBUG_41 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT12, 0x41C, 0x0F0, 7, 0x000, 0), /* MX53_PAD_CSI0_DAT12__TPIU_TRACE_9 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT13, 0x420, 0x0F4, 0, 0x000, 0), /* MX53_PAD_CSI0_DAT13__IPU_CSI0_D_13 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT13, 0x420, 0x0F4, 1, 0x000, 0), /* MX53_PAD_CSI0_DAT13__GPIO5_31 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT13, 0x420, 0x0F4, 2, 0x890, 3), /* MX53_PAD_CSI0_DAT13__UART4_RXD_MUX */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT13, 0x420, 0x0F4, 4, 0x000, 0), /* MX53_PAD_CSI0_DAT13__USBOH3_USBH3_DATA_1 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT13, 0x420, 0x0F4, 5, 0x000, 0), /* MX53_PAD_CSI0_DAT13__SDMA_DEBUG_PC_7 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT13, 0x420, 0x0F4, 6, 0x000, 0), /* MX53_PAD_CSI0_DAT13__EMI_EMI_DEBUG_42 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT13, 0x420, 0x0F4, 7, 0x000, 0), /* MX53_PAD_CSI0_DAT13__TPIU_TRACE_10 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT14, 0x424, 0x0F8, 0, 0x000, 0), /* MX53_PAD_CSI0_DAT14__IPU_CSI0_D_14 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT14, 0x424, 0x0F8, 1, 0x000, 0), /* MX53_PAD_CSI0_DAT14__GPIO6_0 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT14, 0x424, 0x0F8, 2, 0x000, 0), /* MX53_PAD_CSI0_DAT14__UART5_TXD_MUX */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT14, 0x424, 0x0F8, 4, 0x000, 0), /* MX53_PAD_CSI0_DAT14__USBOH3_USBH3_DATA_2 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT14, 0x424, 0x0F8, 5, 0x000, 0), /* MX53_PAD_CSI0_DAT14__SDMA_DEBUG_PC_8 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT14, 0x424, 0x0F8, 6, 0x000, 0), /* MX53_PAD_CSI0_DAT14__EMI_EMI_DEBUG_43 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT14, 0x424, 0x0F8, 7, 0x000, 0), /* MX53_PAD_CSI0_DAT14__TPIU_TRACE_11 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT15, 0x428, 0x0FC, 0, 0x000, 0), /* MX53_PAD_CSI0_DAT15__IPU_CSI0_D_15 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT15, 0x428, 0x0FC, 1, 0x000, 0), /* MX53_PAD_CSI0_DAT15__GPIO6_1 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT15, 0x428, 0x0FC, 2, 0x898, 3), /* MX53_PAD_CSI0_DAT15__UART5_RXD_MUX */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT15, 0x428, 0x0FC, 4, 0x000, 0), /* MX53_PAD_CSI0_DAT15__USBOH3_USBH3_DATA_3 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT15, 0x428, 0x0FC, 5, 0x000, 0), /* MX53_PAD_CSI0_DAT15__SDMA_DEBUG_PC_9 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT15, 0x428, 0x0FC, 6, 0x000, 0), /* MX53_PAD_CSI0_DAT15__EMI_EMI_DEBUG_44 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT15, 0x428, 0x0FC, 7, 0x000, 0), /* MX53_PAD_CSI0_DAT15__TPIU_TRACE_12 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT16, 0x42C, 0x100, 0, 0x000, 0), /* MX53_PAD_CSI0_DAT16__IPU_CSI0_D_16 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT16, 0x42C, 0x100, 1, 0x000, 0), /* MX53_PAD_CSI0_DAT16__GPIO6_2 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT16, 0x42C, 0x100, 2, 0x88C, 0), /* MX53_PAD_CSI0_DAT16__UART4_RTS */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT16, 0x42C, 0x100, 4, 0x000, 0), /* MX53_PAD_CSI0_DAT16__USBOH3_USBH3_DATA_4 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT16, 0x42C, 0x100, 5, 0x000, 0), /* MX53_PAD_CSI0_DAT16__SDMA_DEBUG_PC_10 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT16, 0x42C, 0x100, 6, 0x000, 0), /* MX53_PAD_CSI0_DAT16__EMI_EMI_DEBUG_45 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT16, 0x42C, 0x100, 7, 0x000, 0), /* MX53_PAD_CSI0_DAT16__TPIU_TRACE_13 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT17, 0x430, 0x104, 0, 0x000, 0), /* MX53_PAD_CSI0_DAT17__IPU_CSI0_D_17 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT17, 0x430, 0x104, 1, 0x000, 0), /* MX53_PAD_CSI0_DAT17__GPIO6_3 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT17, 0x430, 0x104, 2, 0x000, 0), /* MX53_PAD_CSI0_DAT17__UART4_CTS */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT17, 0x430, 0x104, 4, 0x000, 0), /* MX53_PAD_CSI0_DAT17__USBOH3_USBH3_DATA_5 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT17, 0x430, 0x104, 5, 0x000, 0), /* MX53_PAD_CSI0_DAT17__SDMA_DEBUG_PC_11 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT17, 0x430, 0x104, 6, 0x000, 0), /* MX53_PAD_CSI0_DAT17__EMI_EMI_DEBUG_46 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT17, 0x430, 0x104, 7, 0x000, 0), /* MX53_PAD_CSI0_DAT17__TPIU_TRACE_14 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT18, 0x434, 0x108, 0, 0x000, 0), /* MX53_PAD_CSI0_DAT18__IPU_CSI0_D_18 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT18, 0x434, 0x108, 1, 0x000, 0), /* MX53_PAD_CSI0_DAT18__GPIO6_4 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT18, 0x434, 0x108, 2, 0x894, 2), /* MX53_PAD_CSI0_DAT18__UART5_RTS */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT18, 0x434, 0x108, 4, 0x000, 0), /* MX53_PAD_CSI0_DAT18__USBOH3_USBH3_DATA_6 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT18, 0x434, 0x108, 5, 0x000, 0), /* MX53_PAD_CSI0_DAT18__SDMA_DEBUG_PC_12 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT18, 0x434, 0x108, 6, 0x000, 0), /* MX53_PAD_CSI0_DAT18__EMI_EMI_DEBUG_47 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT18, 0x434, 0x108, 7, 0x000, 0), /* MX53_PAD_CSI0_DAT18__TPIU_TRACE_15 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT19, 0x438, 0x10C, 0, 0x000, 0), /* MX53_PAD_CSI0_DAT19__IPU_CSI0_D_19 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT19, 0x438, 0x10C, 1, 0x000, 0), /* MX53_PAD_CSI0_DAT19__GPIO6_5 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT19, 0x438, 0x10C, 2, 0x000, 0), /* MX53_PAD_CSI0_DAT19__UART5_CTS */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT19, 0x438, 0x10C, 4, 0x000, 0), /* MX53_PAD_CSI0_DAT19__USBOH3_USBH3_DATA_7 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT19, 0x438, 0x10C, 5, 0x000, 0), /* MX53_PAD_CSI0_DAT19__SDMA_DEBUG_PC_13 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT19, 0x438, 0x10C, 6, 0x000, 0), /* MX53_PAD_CSI0_DAT19__EMI_EMI_DEBUG_48 */ - IMX_PIN_REG(MX53_PAD_CSI0_DAT19, 0x438, 0x10C, 7, 0x000, 0), /* MX53_PAD_CSI0_DAT19__USBPHY2_BISTOK */ - IMX_PIN_REG(MX53_PAD_EIM_A25, 0x458, 0x110, 0, 0x000, 0), /* MX53_PAD_EIM_A25__EMI_WEIM_A_25 */ - IMX_PIN_REG(MX53_PAD_EIM_A25, 0x458, 0x110, 1, 0x000, 0), /* MX53_PAD_EIM_A25__GPIO5_2 */ - IMX_PIN_REG(MX53_PAD_EIM_A25, 0x458, 0x110, 2, 0x000, 0), /* MX53_PAD_EIM_A25__ECSPI2_RDY */ - IMX_PIN_REG(MX53_PAD_EIM_A25, 0x458, 0x110, 3, 0x000, 0), /* MX53_PAD_EIM_A25__IPU_DI1_PIN12 */ - IMX_PIN_REG(MX53_PAD_EIM_A25, 0x458, 0x110, 4, 0x790, 1), /* MX53_PAD_EIM_A25__CSPI_SS1 */ - IMX_PIN_REG(MX53_PAD_EIM_A25, 0x458, 0x110, 6, 0x000, 0), /* MX53_PAD_EIM_A25__IPU_DI0_D1_CS */ - IMX_PIN_REG(MX53_PAD_EIM_A25, 0x458, 0x110, 7, 0x000, 0), /* MX53_PAD_EIM_A25__USBPHY1_BISTOK */ - IMX_PIN_REG(MX53_PAD_EIM_EB2, 0x45C, 0x114, 0, 0x000, 0), /* MX53_PAD_EIM_EB2__EMI_WEIM_EB_2 */ - IMX_PIN_REG(MX53_PAD_EIM_EB2, 0x45C, 0x114, 1, 0x000, 0), /* MX53_PAD_EIM_EB2__GPIO2_30 */ - IMX_PIN_REG(MX53_PAD_EIM_EB2, 0x45C, 0x114, 2, 0x76C, 0), /* MX53_PAD_EIM_EB2__CCM_DI1_EXT_CLK */ - IMX_PIN_REG(MX53_PAD_EIM_EB2, 0x45C, 0x114, 3, 0x000, 0), /* MX53_PAD_EIM_EB2__IPU_SER_DISP1_CS */ - IMX_PIN_REG(MX53_PAD_EIM_EB2, 0x45C, 0x114, 4, 0x7A8, 3), /* MX53_PAD_EIM_EB2__ECSPI1_SS0 */ - IMX_PIN_REG(MX53_PAD_EIM_EB2, 0x45C, 0x114, 5, 0x81C, 1), /* MX53_PAD_EIM_EB2__I2C2_SCL */ - IMX_PIN_REG(MX53_PAD_EIM_D16, 0x460, 0x118, 0, 0x000, 0), /* MX53_PAD_EIM_D16__EMI_WEIM_D_16 */ - IMX_PIN_REG(MX53_PAD_EIM_D16, 0x460, 0x118, 1, 0x000, 0), /* MX53_PAD_EIM_D16__GPIO3_16 */ - IMX_PIN_REG(MX53_PAD_EIM_D16, 0x460, 0x118, 2, 0x000, 0), /* MX53_PAD_EIM_D16__IPU_DI0_PIN5 */ - IMX_PIN_REG(MX53_PAD_EIM_D16, 0x460, 0x118, 3, 0x000, 0), /* MX53_PAD_EIM_D16__IPU_DISPB1_SER_CLK */ - IMX_PIN_REG(MX53_PAD_EIM_D16, 0x460, 0x118, 4, 0x79C, 3), /* MX53_PAD_EIM_D16__ECSPI1_SCLK */ - IMX_PIN_REG(MX53_PAD_EIM_D16, 0x460, 0x118, 5, 0x820, 1), /* MX53_PAD_EIM_D16__I2C2_SDA */ - IMX_PIN_REG(MX53_PAD_EIM_D17, 0x464, 0x11C, 0, 0x000, 0), /* MX53_PAD_EIM_D17__EMI_WEIM_D_17 */ - IMX_PIN_REG(MX53_PAD_EIM_D17, 0x464, 0x11C, 1, 0x000, 0), /* MX53_PAD_EIM_D17__GPIO3_17 */ - IMX_PIN_REG(MX53_PAD_EIM_D17, 0x464, 0x11C, 2, 0x000, 0), /* MX53_PAD_EIM_D17__IPU_DI0_PIN6 */ - IMX_PIN_REG(MX53_PAD_EIM_D17, 0x464, 0x11C, 3, 0x830, 0), /* MX53_PAD_EIM_D17__IPU_DISPB1_SER_DIN */ - IMX_PIN_REG(MX53_PAD_EIM_D17, 0x464, 0x11C, 4, 0x7A0, 3), /* MX53_PAD_EIM_D17__ECSPI1_MISO */ - IMX_PIN_REG(MX53_PAD_EIM_D17, 0x464, 0x11C, 5, 0x824, 0), /* MX53_PAD_EIM_D17__I2C3_SCL */ - IMX_PIN_REG(MX53_PAD_EIM_D18, 0x468, 0x120, 0, 0x000, 0), /* MX53_PAD_EIM_D18__EMI_WEIM_D_18 */ - IMX_PIN_REG(MX53_PAD_EIM_D18, 0x468, 0x120, 1, 0x000, 0), /* MX53_PAD_EIM_D18__GPIO3_18 */ - IMX_PIN_REG(MX53_PAD_EIM_D18, 0x468, 0x120, 2, 0x000, 0), /* MX53_PAD_EIM_D18__IPU_DI0_PIN7 */ - IMX_PIN_REG(MX53_PAD_EIM_D18, 0x468, 0x120, 3, 0x830, 1), /* MX53_PAD_EIM_D18__IPU_DISPB1_SER_DIO */ - IMX_PIN_REG(MX53_PAD_EIM_D18, 0x468, 0x120, 4, 0x7A4, 3), /* MX53_PAD_EIM_D18__ECSPI1_MOSI */ - IMX_PIN_REG(MX53_PAD_EIM_D18, 0x468, 0x120, 5, 0x828, 0), /* MX53_PAD_EIM_D18__I2C3_SDA */ - IMX_PIN_REG(MX53_PAD_EIM_D18, 0x468, 0x120, 6, 0x000, 0), /* MX53_PAD_EIM_D18__IPU_DI1_D0_CS */ - IMX_PIN_REG(MX53_PAD_EIM_D19, 0x46C, 0x124, 0, 0x000, 0), /* MX53_PAD_EIM_D19__EMI_WEIM_D_19 */ - IMX_PIN_REG(MX53_PAD_EIM_D19, 0x46C, 0x124, 1, 0x000, 0), /* MX53_PAD_EIM_D19__GPIO3_19 */ - IMX_PIN_REG(MX53_PAD_EIM_D19, 0x46C, 0x124, 2, 0x000, 0), /* MX53_PAD_EIM_D19__IPU_DI0_PIN8 */ - IMX_PIN_REG(MX53_PAD_EIM_D19, 0x46C, 0x124, 3, 0x000, 0), /* MX53_PAD_EIM_D19__IPU_DISPB1_SER_RS */ - IMX_PIN_REG(MX53_PAD_EIM_D19, 0x46C, 0x124, 4, 0x7AC, 2), /* MX53_PAD_EIM_D19__ECSPI1_SS1 */ - IMX_PIN_REG(MX53_PAD_EIM_D19, 0x46C, 0x124, 5, 0x000, 0), /* MX53_PAD_EIM_D19__EPIT1_EPITO */ - IMX_PIN_REG(MX53_PAD_EIM_D19, 0x46C, 0x124, 6, 0x000, 0), /* MX53_PAD_EIM_D19__UART1_CTS */ - IMX_PIN_REG(MX53_PAD_EIM_D19, 0x46C, 0x124, 7, 0x8A4, 0), /* MX53_PAD_EIM_D19__USBOH3_USBH2_OC */ - IMX_PIN_REG(MX53_PAD_EIM_D20, 0x470, 0x128, 0, 0x000, 0), /* MX53_PAD_EIM_D20__EMI_WEIM_D_20 */ - IMX_PIN_REG(MX53_PAD_EIM_D20, 0x470, 0x128, 1, 0x000, 0), /* MX53_PAD_EIM_D20__GPIO3_20 */ - IMX_PIN_REG(MX53_PAD_EIM_D20, 0x470, 0x128, 2, 0x000, 0), /* MX53_PAD_EIM_D20__IPU_DI0_PIN16 */ - IMX_PIN_REG(MX53_PAD_EIM_D20, 0x470, 0x128, 3, 0x000, 0), /* MX53_PAD_EIM_D20__IPU_SER_DISP0_CS */ - IMX_PIN_REG(MX53_PAD_EIM_D20, 0x470, 0x128, 4, 0x78C, 1), /* MX53_PAD_EIM_D20__CSPI_SS0 */ - IMX_PIN_REG(MX53_PAD_EIM_D20, 0x470, 0x128, 5, 0x000, 0), /* MX53_PAD_EIM_D20__EPIT2_EPITO */ - IMX_PIN_REG(MX53_PAD_EIM_D20, 0x470, 0x128, 6, 0x874, 1), /* MX53_PAD_EIM_D20__UART1_RTS */ - IMX_PIN_REG(MX53_PAD_EIM_D20, 0x470, 0x128, 7, 0x000, 0), /* MX53_PAD_EIM_D20__USBOH3_USBH2_PWR */ - IMX_PIN_REG(MX53_PAD_EIM_D21, 0x474, 0x12C, 0, 0x000, 0), /* MX53_PAD_EIM_D21__EMI_WEIM_D_21 */ - IMX_PIN_REG(MX53_PAD_EIM_D21, 0x474, 0x12C, 1, 0x000, 0), /* MX53_PAD_EIM_D21__GPIO3_21 */ - IMX_PIN_REG(MX53_PAD_EIM_D21, 0x474, 0x12C, 2, 0x000, 0), /* MX53_PAD_EIM_D21__IPU_DI0_PIN17 */ - IMX_PIN_REG(MX53_PAD_EIM_D21, 0x474, 0x12C, 3, 0x000, 0), /* MX53_PAD_EIM_D21__IPU_DISPB0_SER_CLK */ - IMX_PIN_REG(MX53_PAD_EIM_D21, 0x474, 0x12C, 4, 0x780, 1), /* MX53_PAD_EIM_D21__CSPI_SCLK */ - IMX_PIN_REG(MX53_PAD_EIM_D21, 0x474, 0x12C, 5, 0x814, 1), /* MX53_PAD_EIM_D21__I2C1_SCL */ - IMX_PIN_REG(MX53_PAD_EIM_D21, 0x474, 0x12C, 6, 0x89C, 1), /* MX53_PAD_EIM_D21__USBOH3_USBOTG_OC */ - IMX_PIN_REG(MX53_PAD_EIM_D22, 0x478, 0x130, 0, 0x000, 0), /* MX53_PAD_EIM_D22__EMI_WEIM_D_22 */ - IMX_PIN_REG(MX53_PAD_EIM_D22, 0x478, 0x130, 1, 0x000, 0), /* MX53_PAD_EIM_D22__GPIO3_22 */ - IMX_PIN_REG(MX53_PAD_EIM_D22, 0x478, 0x130, 2, 0x000, 0), /* MX53_PAD_EIM_D22__IPU_DI0_PIN1 */ - IMX_PIN_REG(MX53_PAD_EIM_D22, 0x478, 0x130, 3, 0x82C, 0), /* MX53_PAD_EIM_D22__IPU_DISPB0_SER_DIN */ - IMX_PIN_REG(MX53_PAD_EIM_D22, 0x478, 0x130, 4, 0x784, 1), /* MX53_PAD_EIM_D22__CSPI_MISO */ - IMX_PIN_REG(MX53_PAD_EIM_D22, 0x478, 0x130, 6, 0x000, 0), /* MX53_PAD_EIM_D22__USBOH3_USBOTG_PWR */ - IMX_PIN_REG(MX53_PAD_EIM_D23, 0x47C, 0x134, 0, 0x000, 0), /* MX53_PAD_EIM_D23__EMI_WEIM_D_23 */ - IMX_PIN_REG(MX53_PAD_EIM_D23, 0x47C, 0x134, 1, 0x000, 0), /* MX53_PAD_EIM_D23__GPIO3_23 */ - IMX_PIN_REG(MX53_PAD_EIM_D23, 0x47C, 0x134, 2, 0x000, 0), /* MX53_PAD_EIM_D23__UART3_CTS */ - IMX_PIN_REG(MX53_PAD_EIM_D23, 0x47C, 0x134, 3, 0x000, 0), /* MX53_PAD_EIM_D23__UART1_DCD */ - IMX_PIN_REG(MX53_PAD_EIM_D23, 0x47C, 0x134, 4, 0x000, 0), /* MX53_PAD_EIM_D23__IPU_DI0_D0_CS */ - IMX_PIN_REG(MX53_PAD_EIM_D23, 0x47C, 0x134, 5, 0x000, 0), /* MX53_PAD_EIM_D23__IPU_DI1_PIN2 */ - IMX_PIN_REG(MX53_PAD_EIM_D23, 0x47C, 0x134, 6, 0x834, 0), /* MX53_PAD_EIM_D23__IPU_CSI1_DATA_EN */ - IMX_PIN_REG(MX53_PAD_EIM_D23, 0x47C, 0x134, 7, 0x000, 0), /* MX53_PAD_EIM_D23__IPU_DI1_PIN14 */ - IMX_PIN_REG(MX53_PAD_EIM_EB3, 0x480, 0x138, 0, 0x000, 0), /* MX53_PAD_EIM_EB3__EMI_WEIM_EB_3 */ - IMX_PIN_REG(MX53_PAD_EIM_EB3, 0x480, 0x138, 1, 0x000, 0), /* MX53_PAD_EIM_EB3__GPIO2_31 */ - IMX_PIN_REG(MX53_PAD_EIM_EB3, 0x480, 0x138, 2, 0x884, 1), /* MX53_PAD_EIM_EB3__UART3_RTS */ - IMX_PIN_REG(MX53_PAD_EIM_EB3, 0x480, 0x138, 3, 0x000, 0), /* MX53_PAD_EIM_EB3__UART1_RI */ - IMX_PIN_REG(MX53_PAD_EIM_EB3, 0x480, 0x138, 5, 0x000, 0), /* MX53_PAD_EIM_EB3__IPU_DI1_PIN3 */ - IMX_PIN_REG(MX53_PAD_EIM_EB3, 0x480, 0x138, 6, 0x838, 0), /* MX53_PAD_EIM_EB3__IPU_CSI1_HSYNC */ - IMX_PIN_REG(MX53_PAD_EIM_EB3, 0x480, 0x138, 7, 0x000, 0), /* MX53_PAD_EIM_EB3__IPU_DI1_PIN16 */ - IMX_PIN_REG(MX53_PAD_EIM_D24, 0x484, 0x13C, 0, 0x000, 0), /* MX53_PAD_EIM_D24__EMI_WEIM_D_24 */ - IMX_PIN_REG(MX53_PAD_EIM_D24, 0x484, 0x13C, 1, 0x000, 0), /* MX53_PAD_EIM_D24__GPIO3_24 */ - IMX_PIN_REG(MX53_PAD_EIM_D24, 0x484, 0x13C, 2, 0x000, 0), /* MX53_PAD_EIM_D24__UART3_TXD_MUX */ - IMX_PIN_REG(MX53_PAD_EIM_D24, 0x484, 0x13C, 3, 0x7B0, 1), /* MX53_PAD_EIM_D24__ECSPI1_SS2 */ - IMX_PIN_REG(MX53_PAD_EIM_D24, 0x484, 0x13C, 4, 0x794, 1), /* MX53_PAD_EIM_D24__CSPI_SS2 */ - IMX_PIN_REG(MX53_PAD_EIM_D24, 0x484, 0x13C, 5, 0x754, 1), /* MX53_PAD_EIM_D24__AUDMUX_AUD5_RXFS */ - IMX_PIN_REG(MX53_PAD_EIM_D24, 0x484, 0x13C, 6, 0x000, 0), /* MX53_PAD_EIM_D24__ECSPI2_SS2 */ - IMX_PIN_REG(MX53_PAD_EIM_D24, 0x484, 0x13C, 7, 0x000, 0), /* MX53_PAD_EIM_D24__UART1_DTR */ - IMX_PIN_REG(MX53_PAD_EIM_D25, 0x488, 0x140, 0, 0x000, 0), /* MX53_PAD_EIM_D25__EMI_WEIM_D_25 */ - IMX_PIN_REG(MX53_PAD_EIM_D25, 0x488, 0x140, 1, 0x000, 0), /* MX53_PAD_EIM_D25__GPIO3_25 */ - IMX_PIN_REG(MX53_PAD_EIM_D25, 0x488, 0x140, 2, 0x888, 1), /* MX53_PAD_EIM_D25__UART3_RXD_MUX */ - IMX_PIN_REG(MX53_PAD_EIM_D25, 0x488, 0x140, 3, 0x7B4, 1), /* MX53_PAD_EIM_D25__ECSPI1_SS3 */ - IMX_PIN_REG(MX53_PAD_EIM_D25, 0x488, 0x140, 4, 0x798, 1), /* MX53_PAD_EIM_D25__CSPI_SS3 */ - IMX_PIN_REG(MX53_PAD_EIM_D25, 0x488, 0x140, 5, 0x750, 1), /* MX53_PAD_EIM_D25__AUDMUX_AUD5_RXC */ - IMX_PIN_REG(MX53_PAD_EIM_D25, 0x488, 0x140, 6, 0x000, 0), /* MX53_PAD_EIM_D25__ECSPI2_SS3 */ - IMX_PIN_REG(MX53_PAD_EIM_D25, 0x488, 0x140, 7, 0x000, 0), /* MX53_PAD_EIM_D25__UART1_DSR */ - IMX_PIN_REG(MX53_PAD_EIM_D26, 0x48C, 0x144, 0, 0x000, 0), /* MX53_PAD_EIM_D26__EMI_WEIM_D_26 */ - IMX_PIN_REG(MX53_PAD_EIM_D26, 0x48C, 0x144, 1, 0x000, 0), /* MX53_PAD_EIM_D26__GPIO3_26 */ - IMX_PIN_REG(MX53_PAD_EIM_D26, 0x48C, 0x144, 2, 0x000, 0), /* MX53_PAD_EIM_D26__UART2_TXD_MUX */ - IMX_PIN_REG(MX53_PAD_EIM_D26, 0x48C, 0x144, 3, 0x80C, 0), /* MX53_PAD_EIM_D26__FIRI_RXD */ - IMX_PIN_REG(MX53_PAD_EIM_D26, 0x48C, 0x144, 4, 0x000, 0), /* MX53_PAD_EIM_D26__IPU_CSI0_D_1 */ - IMX_PIN_REG(MX53_PAD_EIM_D26, 0x48C, 0x144, 5, 0x000, 0), /* MX53_PAD_EIM_D26__IPU_DI1_PIN11 */ - IMX_PIN_REG(MX53_PAD_EIM_D26, 0x48C, 0x144, 6, 0x000, 0), /* MX53_PAD_EIM_D26__IPU_SISG_2 */ - IMX_PIN_REG(MX53_PAD_EIM_D26, 0x48C, 0x144, 7, 0x000, 0), /* MX53_PAD_EIM_D26__IPU_DISP1_DAT_22 */ - IMX_PIN_REG(MX53_PAD_EIM_D27, 0x490, 0x148, 0, 0x000, 0), /* MX53_PAD_EIM_D27__EMI_WEIM_D_27 */ - IMX_PIN_REG(MX53_PAD_EIM_D27, 0x490, 0x148, 1, 0x000, 0), /* MX53_PAD_EIM_D27__GPIO3_27 */ - IMX_PIN_REG(MX53_PAD_EIM_D27, 0x490, 0x148, 2, 0x880, 1), /* MX53_PAD_EIM_D27__UART2_RXD_MUX */ - IMX_PIN_REG(MX53_PAD_EIM_D27, 0x490, 0x148, 3, 0x000, 0), /* MX53_PAD_EIM_D27__FIRI_TXD */ - IMX_PIN_REG(MX53_PAD_EIM_D27, 0x490, 0x148, 4, 0x000, 0), /* MX53_PAD_EIM_D27__IPU_CSI0_D_0 */ - IMX_PIN_REG(MX53_PAD_EIM_D27, 0x490, 0x148, 5, 0x000, 0), /* MX53_PAD_EIM_D27__IPU_DI1_PIN13 */ - IMX_PIN_REG(MX53_PAD_EIM_D27, 0x490, 0x148, 6, 0x000, 0), /* MX53_PAD_EIM_D27__IPU_SISG_3 */ - IMX_PIN_REG(MX53_PAD_EIM_D27, 0x490, 0x148, 7, 0x000, 0), /* MX53_PAD_EIM_D27__IPU_DISP1_DAT_23 */ - IMX_PIN_REG(MX53_PAD_EIM_D28, 0x494, 0x14C, 0, 0x000, 0), /* MX53_PAD_EIM_D28__EMI_WEIM_D_28 */ - IMX_PIN_REG(MX53_PAD_EIM_D28, 0x494, 0x14C, 1, 0x000, 0), /* MX53_PAD_EIM_D28__GPIO3_28 */ - IMX_PIN_REG(MX53_PAD_EIM_D28, 0x494, 0x14C, 2, 0x000, 0), /* MX53_PAD_EIM_D28__UART2_CTS */ - IMX_PIN_REG(MX53_PAD_EIM_D28, 0x494, 0x14C, 3, 0x82C, 1), /* MX53_PAD_EIM_D28__IPU_DISPB0_SER_DIO */ - IMX_PIN_REG(MX53_PAD_EIM_D28, 0x494, 0x14C, 4, 0x788, 1), /* MX53_PAD_EIM_D28__CSPI_MOSI */ - IMX_PIN_REG(MX53_PAD_EIM_D28, 0x494, 0x14C, 5, 0x818, 1), /* MX53_PAD_EIM_D28__I2C1_SDA */ - IMX_PIN_REG(MX53_PAD_EIM_D28, 0x494, 0x14C, 6, 0x000, 0), /* MX53_PAD_EIM_D28__IPU_EXT_TRIG */ - IMX_PIN_REG(MX53_PAD_EIM_D28, 0x494, 0x14C, 7, 0x000, 0), /* MX53_PAD_EIM_D28__IPU_DI0_PIN13 */ - IMX_PIN_REG(MX53_PAD_EIM_D29, 0x498, 0x150, 0, 0x000, 0), /* MX53_PAD_EIM_D29__EMI_WEIM_D_29 */ - IMX_PIN_REG(MX53_PAD_EIM_D29, 0x498, 0x150, 1, 0x000, 0), /* MX53_PAD_EIM_D29__GPIO3_29 */ - IMX_PIN_REG(MX53_PAD_EIM_D29, 0x498, 0x150, 2, 0x87C, 1), /* MX53_PAD_EIM_D29__UART2_RTS */ - IMX_PIN_REG(MX53_PAD_EIM_D29, 0x498, 0x150, 3, 0x000, 0), /* MX53_PAD_EIM_D29__IPU_DISPB0_SER_RS */ - IMX_PIN_REG(MX53_PAD_EIM_D29, 0x498, 0x150, 4, 0x78C, 2), /* MX53_PAD_EIM_D29__CSPI_SS0 */ - IMX_PIN_REG(MX53_PAD_EIM_D29, 0x498, 0x150, 5, 0x000, 0), /* MX53_PAD_EIM_D29__IPU_DI1_PIN15 */ - IMX_PIN_REG(MX53_PAD_EIM_D29, 0x498, 0x150, 6, 0x83C, 0), /* MX53_PAD_EIM_D29__IPU_CSI1_VSYNC */ - IMX_PIN_REG(MX53_PAD_EIM_D29, 0x498, 0x150, 7, 0x000, 0), /* MX53_PAD_EIM_D29__IPU_DI0_PIN14 */ - IMX_PIN_REG(MX53_PAD_EIM_D30, 0x49C, 0x154, 0, 0x000, 0), /* MX53_PAD_EIM_D30__EMI_WEIM_D_30 */ - IMX_PIN_REG(MX53_PAD_EIM_D30, 0x49C, 0x154, 1, 0x000, 0), /* MX53_PAD_EIM_D30__GPIO3_30 */ - IMX_PIN_REG(MX53_PAD_EIM_D30, 0x49C, 0x154, 2, 0x000, 0), /* MX53_PAD_EIM_D30__UART3_CTS */ - IMX_PIN_REG(MX53_PAD_EIM_D30, 0x49C, 0x154, 3, 0x000, 0), /* MX53_PAD_EIM_D30__IPU_CSI0_D_3 */ - IMX_PIN_REG(MX53_PAD_EIM_D30, 0x49C, 0x154, 4, 0x000, 0), /* MX53_PAD_EIM_D30__IPU_DI0_PIN11 */ - IMX_PIN_REG(MX53_PAD_EIM_D30, 0x49C, 0x154, 5, 0x000, 0), /* MX53_PAD_EIM_D30__IPU_DISP1_DAT_21 */ - IMX_PIN_REG(MX53_PAD_EIM_D30, 0x49C, 0x154, 6, 0x8A0, 0), /* MX53_PAD_EIM_D30__USBOH3_USBH1_OC */ - IMX_PIN_REG(MX53_PAD_EIM_D30, 0x49C, 0x154, 7, 0x8A4, 1), /* MX53_PAD_EIM_D30__USBOH3_USBH2_OC */ - IMX_PIN_REG(MX53_PAD_EIM_D31, 0x4A0, 0x158, 0, 0x000, 0), /* MX53_PAD_EIM_D31__EMI_WEIM_D_31 */ - IMX_PIN_REG(MX53_PAD_EIM_D31, 0x4A0, 0x158, 1, 0x000, 0), /* MX53_PAD_EIM_D31__GPIO3_31 */ - IMX_PIN_REG(MX53_PAD_EIM_D31, 0x4A0, 0x158, 2, 0x884, 3), /* MX53_PAD_EIM_D31__UART3_RTS */ - IMX_PIN_REG(MX53_PAD_EIM_D31, 0x4A0, 0x158, 3, 0x000, 0), /* MX53_PAD_EIM_D31__IPU_CSI0_D_2 */ - IMX_PIN_REG(MX53_PAD_EIM_D31, 0x4A0, 0x158, 4, 0x000, 0), /* MX53_PAD_EIM_D31__IPU_DI0_PIN12 */ - IMX_PIN_REG(MX53_PAD_EIM_D31, 0x4A0, 0x158, 5, 0x000, 0), /* MX53_PAD_EIM_D31__IPU_DISP1_DAT_20 */ - IMX_PIN_REG(MX53_PAD_EIM_D31, 0x4A0, 0x158, 6, 0x000, 0), /* MX53_PAD_EIM_D31__USBOH3_USBH1_PWR */ - IMX_PIN_REG(MX53_PAD_EIM_D31, 0x4A0, 0x158, 7, 0x000, 0), /* MX53_PAD_EIM_D31__USBOH3_USBH2_PWR */ - IMX_PIN_REG(MX53_PAD_EIM_A24, 0x4A8, 0x15C, 0, 0x000, 0), /* MX53_PAD_EIM_A24__EMI_WEIM_A_24 */ - IMX_PIN_REG(MX53_PAD_EIM_A24, 0x4A8, 0x15C, 1, 0x000, 0), /* MX53_PAD_EIM_A24__GPIO5_4 */ - IMX_PIN_REG(MX53_PAD_EIM_A24, 0x4A8, 0x15C, 2, 0x000, 0), /* MX53_PAD_EIM_A24__IPU_DISP1_DAT_19 */ - IMX_PIN_REG(MX53_PAD_EIM_A24, 0x4A8, 0x15C, 3, 0x000, 0), /* MX53_PAD_EIM_A24__IPU_CSI1_D_19 */ - IMX_PIN_REG(MX53_PAD_EIM_A24, 0x4A8, 0x15C, 6, 0x000, 0), /* MX53_PAD_EIM_A24__IPU_SISG_2 */ - IMX_PIN_REG(MX53_PAD_EIM_A24, 0x4A8, 0x15C, 7, 0x000, 0), /* MX53_PAD_EIM_A24__USBPHY2_BVALID */ - IMX_PIN_REG(MX53_PAD_EIM_A23, 0x4AC, 0x160, 0, 0x000, 0), /* MX53_PAD_EIM_A23__EMI_WEIM_A_23 */ - IMX_PIN_REG(MX53_PAD_EIM_A23, 0x4AC, 0x160, 1, 0x000, 0), /* MX53_PAD_EIM_A23__GPIO6_6 */ - IMX_PIN_REG(MX53_PAD_EIM_A23, 0x4AC, 0x160, 2, 0x000, 0), /* MX53_PAD_EIM_A23__IPU_DISP1_DAT_18 */ - IMX_PIN_REG(MX53_PAD_EIM_A23, 0x4AC, 0x160, 3, 0x000, 0), /* MX53_PAD_EIM_A23__IPU_CSI1_D_18 */ - IMX_PIN_REG(MX53_PAD_EIM_A23, 0x4AC, 0x160, 6, 0x000, 0), /* MX53_PAD_EIM_A23__IPU_SISG_3 */ - IMX_PIN_REG(MX53_PAD_EIM_A23, 0x4AC, 0x160, 7, 0x000, 0), /* MX53_PAD_EIM_A23__USBPHY2_ENDSESSION */ - IMX_PIN_REG(MX53_PAD_EIM_A22, 0x4B0, 0x164, 0, 0x000, 0), /* MX53_PAD_EIM_A22__EMI_WEIM_A_22 */ - IMX_PIN_REG(MX53_PAD_EIM_A22, 0x4B0, 0x164, 1, 0x000, 0), /* MX53_PAD_EIM_A22__GPIO2_16 */ - IMX_PIN_REG(MX53_PAD_EIM_A22, 0x4B0, 0x164, 2, 0x000, 0), /* MX53_PAD_EIM_A22__IPU_DISP1_DAT_17 */ - IMX_PIN_REG(MX53_PAD_EIM_A22, 0x4B0, 0x164, 3, 0x000, 0), /* MX53_PAD_EIM_A22__IPU_CSI1_D_17 */ - IMX_PIN_REG(MX53_PAD_EIM_A22, 0x4B0, 0x164, 7, 0x000, 0), /* MX53_PAD_EIM_A22__SRC_BT_CFG1_7 */ - IMX_PIN_REG(MX53_PAD_EIM_A21, 0x4B4, 0x168, 0, 0x000, 0), /* MX53_PAD_EIM_A21__EMI_WEIM_A_21 */ - IMX_PIN_REG(MX53_PAD_EIM_A21, 0x4B4, 0x168, 1, 0x000, 0), /* MX53_PAD_EIM_A21__GPIO2_17 */ - IMX_PIN_REG(MX53_PAD_EIM_A21, 0x4B4, 0x168, 2, 0x000, 0), /* MX53_PAD_EIM_A21__IPU_DISP1_DAT_16 */ - IMX_PIN_REG(MX53_PAD_EIM_A21, 0x4B4, 0x168, 3, 0x000, 0), /* MX53_PAD_EIM_A21__IPU_CSI1_D_16 */ - IMX_PIN_REG(MX53_PAD_EIM_A21, 0x4B4, 0x168, 7, 0x000, 0), /* MX53_PAD_EIM_A21__SRC_BT_CFG1_6 */ - IMX_PIN_REG(MX53_PAD_EIM_A20, 0x4B8, 0x16C, 0, 0x000, 0), /* MX53_PAD_EIM_A20__EMI_WEIM_A_20 */ - IMX_PIN_REG(MX53_PAD_EIM_A20, 0x4B8, 0x16C, 1, 0x000, 0), /* MX53_PAD_EIM_A20__GPIO2_18 */ - IMX_PIN_REG(MX53_PAD_EIM_A20, 0x4B8, 0x16C, 2, 0x000, 0), /* MX53_PAD_EIM_A20__IPU_DISP1_DAT_15 */ - IMX_PIN_REG(MX53_PAD_EIM_A20, 0x4B8, 0x16C, 3, 0x000, 0), /* MX53_PAD_EIM_A20__IPU_CSI1_D_15 */ - IMX_PIN_REG(MX53_PAD_EIM_A20, 0x4B8, 0x16C, 7, 0x000, 0), /* MX53_PAD_EIM_A20__SRC_BT_CFG1_5 */ - IMX_PIN_REG(MX53_PAD_EIM_A19, 0x4BC, 0x170, 0, 0x000, 0), /* MX53_PAD_EIM_A19__EMI_WEIM_A_19 */ - IMX_PIN_REG(MX53_PAD_EIM_A19, 0x4BC, 0x170, 1, 0x000, 0), /* MX53_PAD_EIM_A19__GPIO2_19 */ - IMX_PIN_REG(MX53_PAD_EIM_A19, 0x4BC, 0x170, 2, 0x000, 0), /* MX53_PAD_EIM_A19__IPU_DISP1_DAT_14 */ - IMX_PIN_REG(MX53_PAD_EIM_A19, 0x4BC, 0x170, 3, 0x000, 0), /* MX53_PAD_EIM_A19__IPU_CSI1_D_14 */ - IMX_PIN_REG(MX53_PAD_EIM_A19, 0x4BC, 0x170, 7, 0x000, 0), /* MX53_PAD_EIM_A19__SRC_BT_CFG1_4 */ - IMX_PIN_REG(MX53_PAD_EIM_A18, 0x4C0, 0x174, 0, 0x000, 0), /* MX53_PAD_EIM_A18__EMI_WEIM_A_18 */ - IMX_PIN_REG(MX53_PAD_EIM_A18, 0x4C0, 0x174, 1, 0x000, 0), /* MX53_PAD_EIM_A18__GPIO2_20 */ - IMX_PIN_REG(MX53_PAD_EIM_A18, 0x4C0, 0x174, 2, 0x000, 0), /* MX53_PAD_EIM_A18__IPU_DISP1_DAT_13 */ - IMX_PIN_REG(MX53_PAD_EIM_A18, 0x4C0, 0x174, 3, 0x000, 0), /* MX53_PAD_EIM_A18__IPU_CSI1_D_13 */ - IMX_PIN_REG(MX53_PAD_EIM_A18, 0x4C0, 0x174, 7, 0x000, 0), /* MX53_PAD_EIM_A18__SRC_BT_CFG1_3 */ - IMX_PIN_REG(MX53_PAD_EIM_A17, 0x4C4, 0x178, 0, 0x000, 0), /* MX53_PAD_EIM_A17__EMI_WEIM_A_17 */ - IMX_PIN_REG(MX53_PAD_EIM_A17, 0x4C4, 0x178, 1, 0x000, 0), /* MX53_PAD_EIM_A17__GPIO2_21 */ - IMX_PIN_REG(MX53_PAD_EIM_A17, 0x4C4, 0x178, 2, 0x000, 0), /* MX53_PAD_EIM_A17__IPU_DISP1_DAT_12 */ - IMX_PIN_REG(MX53_PAD_EIM_A17, 0x4C4, 0x178, 3, 0x000, 0), /* MX53_PAD_EIM_A17__IPU_CSI1_D_12 */ - IMX_PIN_REG(MX53_PAD_EIM_A17, 0x4C4, 0x178, 7, 0x000, 0), /* MX53_PAD_EIM_A17__SRC_BT_CFG1_2 */ - IMX_PIN_REG(MX53_PAD_EIM_A16, 0x4C8, 0x17C, 0, 0x000, 0), /* MX53_PAD_EIM_A16__EMI_WEIM_A_16 */ - IMX_PIN_REG(MX53_PAD_EIM_A16, 0x4C8, 0x17C, 1, 0x000, 0), /* MX53_PAD_EIM_A16__GPIO2_22 */ - IMX_PIN_REG(MX53_PAD_EIM_A16, 0x4C8, 0x17C, 2, 0x000, 0), /* MX53_PAD_EIM_A16__IPU_DI1_DISP_CLK */ - IMX_PIN_REG(MX53_PAD_EIM_A16, 0x4C8, 0x17C, 3, 0x000, 0), /* MX53_PAD_EIM_A16__IPU_CSI1_PIXCLK */ - IMX_PIN_REG(MX53_PAD_EIM_A16, 0x4C8, 0x17C, 7, 0x000, 0), /* MX53_PAD_EIM_A16__SRC_BT_CFG1_1 */ - IMX_PIN_REG(MX53_PAD_EIM_CS0, 0x4CC, 0x180, 0, 0x000, 0), /* MX53_PAD_EIM_CS0__EMI_WEIM_CS_0 */ - IMX_PIN_REG(MX53_PAD_EIM_CS0, 0x4CC, 0x180, 1, 0x000, 0), /* MX53_PAD_EIM_CS0__GPIO2_23 */ - IMX_PIN_REG(MX53_PAD_EIM_CS0, 0x4CC, 0x180, 2, 0x7B8, 2), /* MX53_PAD_EIM_CS0__ECSPI2_SCLK */ - IMX_PIN_REG(MX53_PAD_EIM_CS0, 0x4CC, 0x180, 3, 0x000, 0), /* MX53_PAD_EIM_CS0__IPU_DI1_PIN5 */ - IMX_PIN_REG(MX53_PAD_EIM_CS1, 0x4D0, 0x184, 0, 0x000, 0), /* MX53_PAD_EIM_CS1__EMI_WEIM_CS_1 */ - IMX_PIN_REG(MX53_PAD_EIM_CS1, 0x4D0, 0x184, 1, 0x000, 0), /* MX53_PAD_EIM_CS1__GPIO2_24 */ - IMX_PIN_REG(MX53_PAD_EIM_CS1, 0x4D0, 0x184, 2, 0x7C0, 2), /* MX53_PAD_EIM_CS1__ECSPI2_MOSI */ - IMX_PIN_REG(MX53_PAD_EIM_CS1, 0x4D0, 0x184, 3, 0x000, 0), /* MX53_PAD_EIM_CS1__IPU_DI1_PIN6 */ - IMX_PIN_REG(MX53_PAD_EIM_OE, 0x4D4, 0x188, 0, 0x000, 0), /* MX53_PAD_EIM_OE__EMI_WEIM_OE */ - IMX_PIN_REG(MX53_PAD_EIM_OE, 0x4D4, 0x188, 1, 0x000, 0), /* MX53_PAD_EIM_OE__GPIO2_25 */ - IMX_PIN_REG(MX53_PAD_EIM_OE, 0x4D4, 0x188, 2, 0x7BC, 2), /* MX53_PAD_EIM_OE__ECSPI2_MISO */ - IMX_PIN_REG(MX53_PAD_EIM_OE, 0x4D4, 0x188, 3, 0x000, 0), /* MX53_PAD_EIM_OE__IPU_DI1_PIN7 */ - IMX_PIN_REG(MX53_PAD_EIM_OE, 0x4D4, 0x188, 7, 0x000, 0), /* MX53_PAD_EIM_OE__USBPHY2_IDDIG */ - IMX_PIN_REG(MX53_PAD_EIM_RW, 0x4D8, 0x18C, 0, 0x000, 0), /* MX53_PAD_EIM_RW__EMI_WEIM_RW */ - IMX_PIN_REG(MX53_PAD_EIM_RW, 0x4D8, 0x18C, 1, 0x000, 0), /* MX53_PAD_EIM_RW__GPIO2_26 */ - IMX_PIN_REG(MX53_PAD_EIM_RW, 0x4D8, 0x18C, 2, 0x7C4, 2), /* MX53_PAD_EIM_RW__ECSPI2_SS0 */ - IMX_PIN_REG(MX53_PAD_EIM_RW, 0x4D8, 0x18C, 3, 0x000, 0), /* MX53_PAD_EIM_RW__IPU_DI1_PIN8 */ - IMX_PIN_REG(MX53_PAD_EIM_RW, 0x4D8, 0x18C, 7, 0x000, 0), /* MX53_PAD_EIM_RW__USBPHY2_HOSTDISCONNECT */ - IMX_PIN_REG(MX53_PAD_EIM_LBA, 0x4DC, 0x190, 0, 0x000, 0), /* MX53_PAD_EIM_LBA__EMI_WEIM_LBA */ - IMX_PIN_REG(MX53_PAD_EIM_LBA, 0x4DC, 0x190, 1, 0x000, 0), /* MX53_PAD_EIM_LBA__GPIO2_27 */ - IMX_PIN_REG(MX53_PAD_EIM_LBA, 0x4DC, 0x190, 2, 0x7C8, 1), /* MX53_PAD_EIM_LBA__ECSPI2_SS1 */ - IMX_PIN_REG(MX53_PAD_EIM_LBA, 0x4DC, 0x190, 3, 0x000, 0), /* MX53_PAD_EIM_LBA__IPU_DI1_PIN17 */ - IMX_PIN_REG(MX53_PAD_EIM_LBA, 0x4DC, 0x190, 7, 0x000, 0), /* MX53_PAD_EIM_LBA__SRC_BT_CFG1_0 */ - IMX_PIN_REG(MX53_PAD_EIM_EB0, 0x4E4, 0x194, 0, 0x000, 0), /* MX53_PAD_EIM_EB0__EMI_WEIM_EB_0 */ - IMX_PIN_REG(MX53_PAD_EIM_EB0, 0x4E4, 0x194, 1, 0x000, 0), /* MX53_PAD_EIM_EB0__GPIO2_28 */ - IMX_PIN_REG(MX53_PAD_EIM_EB0, 0x4E4, 0x194, 3, 0x000, 0), /* MX53_PAD_EIM_EB0__IPU_DISP1_DAT_11 */ - IMX_PIN_REG(MX53_PAD_EIM_EB0, 0x4E4, 0x194, 4, 0x000, 0), /* MX53_PAD_EIM_EB0__IPU_CSI1_D_11 */ - IMX_PIN_REG(MX53_PAD_EIM_EB0, 0x4E4, 0x194, 5, 0x810, 0), /* MX53_PAD_EIM_EB0__GPC_PMIC_RDY */ - IMX_PIN_REG(MX53_PAD_EIM_EB0, 0x4E4, 0x194, 7, 0x000, 0), /* MX53_PAD_EIM_EB0__SRC_BT_CFG2_7 */ - IMX_PIN_REG(MX53_PAD_EIM_EB1, 0x4E8, 0x198, 0, 0x000, 0), /* MX53_PAD_EIM_EB1__EMI_WEIM_EB_1 */ - IMX_PIN_REG(MX53_PAD_EIM_EB1, 0x4E8, 0x198, 1, 0x000, 0), /* MX53_PAD_EIM_EB1__GPIO2_29 */ - IMX_PIN_REG(MX53_PAD_EIM_EB1, 0x4E8, 0x198, 3, 0x000, 0), /* MX53_PAD_EIM_EB1__IPU_DISP1_DAT_10 */ - IMX_PIN_REG(MX53_PAD_EIM_EB1, 0x4E8, 0x198, 4, 0x000, 0), /* MX53_PAD_EIM_EB1__IPU_CSI1_D_10 */ - IMX_PIN_REG(MX53_PAD_EIM_EB1, 0x4E8, 0x198, 7, 0x000, 0), /* MX53_PAD_EIM_EB1__SRC_BT_CFG2_6 */ - IMX_PIN_REG(MX53_PAD_EIM_DA0, 0x4EC, 0x19C, 0, 0x000, 0), /* MX53_PAD_EIM_DA0__EMI_NAND_WEIM_DA_0 */ - IMX_PIN_REG(MX53_PAD_EIM_DA0, 0x4EC, 0x19C, 1, 0x000, 0), /* MX53_PAD_EIM_DA0__GPIO3_0 */ - IMX_PIN_REG(MX53_PAD_EIM_DA0, 0x4EC, 0x19C, 3, 0x000, 0), /* MX53_PAD_EIM_DA0__IPU_DISP1_DAT_9 */ - IMX_PIN_REG(MX53_PAD_EIM_DA0, 0x4EC, 0x19C, 4, 0x000, 0), /* MX53_PAD_EIM_DA0__IPU_CSI1_D_9 */ - IMX_PIN_REG(MX53_PAD_EIM_DA0, 0x4EC, 0x19C, 7, 0x000, 0), /* MX53_PAD_EIM_DA0__SRC_BT_CFG2_5 */ - IMX_PIN_REG(MX53_PAD_EIM_DA1, 0x4F0, 0x1A0, 0, 0x000, 0), /* MX53_PAD_EIM_DA1__EMI_NAND_WEIM_DA_1 */ - IMX_PIN_REG(MX53_PAD_EIM_DA1, 0x4F0, 0x1A0, 1, 0x000, 0), /* MX53_PAD_EIM_DA1__GPIO3_1 */ - IMX_PIN_REG(MX53_PAD_EIM_DA1, 0x4F0, 0x1A0, 3, 0x000, 0), /* MX53_PAD_EIM_DA1__IPU_DISP1_DAT_8 */ - IMX_PIN_REG(MX53_PAD_EIM_DA1, 0x4F0, 0x1A0, 4, 0x000, 0), /* MX53_PAD_EIM_DA1__IPU_CSI1_D_8 */ - IMX_PIN_REG(MX53_PAD_EIM_DA1, 0x4F0, 0x1A0, 7, 0x000, 0), /* MX53_PAD_EIM_DA1__SRC_BT_CFG2_4 */ - IMX_PIN_REG(MX53_PAD_EIM_DA2, 0x4F4, 0x1A4, 0, 0x000, 0), /* MX53_PAD_EIM_DA2__EMI_NAND_WEIM_DA_2 */ - IMX_PIN_REG(MX53_PAD_EIM_DA2, 0x4F4, 0x1A4, 1, 0x000, 0), /* MX53_PAD_EIM_DA2__GPIO3_2 */ - IMX_PIN_REG(MX53_PAD_EIM_DA2, 0x4F4, 0x1A4, 3, 0x000, 0), /* MX53_PAD_EIM_DA2__IPU_DISP1_DAT_7 */ - IMX_PIN_REG(MX53_PAD_EIM_DA2, 0x4F4, 0x1A4, 4, 0x000, 0), /* MX53_PAD_EIM_DA2__IPU_CSI1_D_7 */ - IMX_PIN_REG(MX53_PAD_EIM_DA2, 0x4F4, 0x1A4, 7, 0x000, 0), /* MX53_PAD_EIM_DA2__SRC_BT_CFG2_3 */ - IMX_PIN_REG(MX53_PAD_EIM_DA3, 0x4F8, 0x1A8, 0, 0x000, 0), /* MX53_PAD_EIM_DA3__EMI_NAND_WEIM_DA_3 */ - IMX_PIN_REG(MX53_PAD_EIM_DA3, 0x4F8, 0x1A8, 1, 0x000, 0), /* MX53_PAD_EIM_DA3__GPIO3_3 */ - IMX_PIN_REG(MX53_PAD_EIM_DA3, 0x4F8, 0x1A8, 3, 0x000, 0), /* MX53_PAD_EIM_DA3__IPU_DISP1_DAT_6 */ - IMX_PIN_REG(MX53_PAD_EIM_DA3, 0x4F8, 0x1A8, 4, 0x000, 0), /* MX53_PAD_EIM_DA3__IPU_CSI1_D_6 */ - IMX_PIN_REG(MX53_PAD_EIM_DA3, 0x4F8, 0x1A8, 7, 0x000, 0), /* MX53_PAD_EIM_DA3__SRC_BT_CFG2_2 */ - IMX_PIN_REG(MX53_PAD_EIM_DA4, 0x4FC, 0x1AC, 0, 0x000, 0), /* MX53_PAD_EIM_DA4__EMI_NAND_WEIM_DA_4 */ - IMX_PIN_REG(MX53_PAD_EIM_DA4, 0x4FC, 0x1AC, 1, 0x000, 0), /* MX53_PAD_EIM_DA4__GPIO3_4 */ - IMX_PIN_REG(MX53_PAD_EIM_DA4, 0x4FC, 0x1AC, 3, 0x000, 0), /* MX53_PAD_EIM_DA4__IPU_DISP1_DAT_5 */ - IMX_PIN_REG(MX53_PAD_EIM_DA4, 0x4FC, 0x1AC, 4, 0x000, 0), /* MX53_PAD_EIM_DA4__IPU_CSI1_D_5 */ - IMX_PIN_REG(MX53_PAD_EIM_DA4, 0x4FC, 0x1AC, 7, 0x000, 0), /* MX53_PAD_EIM_DA4__SRC_BT_CFG3_7 */ - IMX_PIN_REG(MX53_PAD_EIM_DA5, 0x500, 0x1B0, 0, 0x000, 0), /* MX53_PAD_EIM_DA5__EMI_NAND_WEIM_DA_5 */ - IMX_PIN_REG(MX53_PAD_EIM_DA5, 0x500, 0x1B0, 1, 0x000, 0), /* MX53_PAD_EIM_DA5__GPIO3_5 */ - IMX_PIN_REG(MX53_PAD_EIM_DA5, 0x500, 0x1B0, 3, 0x000, 0), /* MX53_PAD_EIM_DA5__IPU_DISP1_DAT_4 */ - IMX_PIN_REG(MX53_PAD_EIM_DA5, 0x500, 0x1B0, 4, 0x000, 0), /* MX53_PAD_EIM_DA5__IPU_CSI1_D_4 */ - IMX_PIN_REG(MX53_PAD_EIM_DA5, 0x500, 0x1B0, 7, 0x000, 0), /* MX53_PAD_EIM_DA5__SRC_BT_CFG3_6 */ - IMX_PIN_REG(MX53_PAD_EIM_DA6, 0x504, 0x1B4, 0, 0x000, 0), /* MX53_PAD_EIM_DA6__EMI_NAND_WEIM_DA_6 */ - IMX_PIN_REG(MX53_PAD_EIM_DA6, 0x504, 0x1B4, 1, 0x000, 0), /* MX53_PAD_EIM_DA6__GPIO3_6 */ - IMX_PIN_REG(MX53_PAD_EIM_DA6, 0x504, 0x1B4, 3, 0x000, 0), /* MX53_PAD_EIM_DA6__IPU_DISP1_DAT_3 */ - IMX_PIN_REG(MX53_PAD_EIM_DA6, 0x504, 0x1B4, 4, 0x000, 0), /* MX53_PAD_EIM_DA6__IPU_CSI1_D_3 */ - IMX_PIN_REG(MX53_PAD_EIM_DA6, 0x504, 0x1B4, 7, 0x000, 0), /* MX53_PAD_EIM_DA6__SRC_BT_CFG3_5 */ - IMX_PIN_REG(MX53_PAD_EIM_DA7, 0x508, 0x1B8, 0, 0x000, 0), /* MX53_PAD_EIM_DA7__EMI_NAND_WEIM_DA_7 */ - IMX_PIN_REG(MX53_PAD_EIM_DA7, 0x508, 0x1B8, 1, 0x000, 0), /* MX53_PAD_EIM_DA7__GPIO3_7 */ - IMX_PIN_REG(MX53_PAD_EIM_DA7, 0x508, 0x1B8, 3, 0x000, 0), /* MX53_PAD_EIM_DA7__IPU_DISP1_DAT_2 */ - IMX_PIN_REG(MX53_PAD_EIM_DA7, 0x508, 0x1B8, 4, 0x000, 0), /* MX53_PAD_EIM_DA7__IPU_CSI1_D_2 */ - IMX_PIN_REG(MX53_PAD_EIM_DA7, 0x508, 0x1B8, 7, 0x000, 0), /* MX53_PAD_EIM_DA7__SRC_BT_CFG3_4 */ - IMX_PIN_REG(MX53_PAD_EIM_DA8, 0x50C, 0x1BC, 0, 0x000, 0), /* MX53_PAD_EIM_DA8__EMI_NAND_WEIM_DA_8 */ - IMX_PIN_REG(MX53_PAD_EIM_DA8, 0x50C, 0x1BC, 1, 0x000, 0), /* MX53_PAD_EIM_DA8__GPIO3_8 */ - IMX_PIN_REG(MX53_PAD_EIM_DA8, 0x50C, 0x1BC, 3, 0x000, 0), /* MX53_PAD_EIM_DA8__IPU_DISP1_DAT_1 */ - IMX_PIN_REG(MX53_PAD_EIM_DA8, 0x50C, 0x1BC, 4, 0x000, 0), /* MX53_PAD_EIM_DA8__IPU_CSI1_D_1 */ - IMX_PIN_REG(MX53_PAD_EIM_DA8, 0x50C, 0x1BC, 7, 0x000, 0), /* MX53_PAD_EIM_DA8__SRC_BT_CFG3_3 */ - IMX_PIN_REG(MX53_PAD_EIM_DA9, 0x510, 0x1C0, 0, 0x000, 0), /* MX53_PAD_EIM_DA9__EMI_NAND_WEIM_DA_9 */ - IMX_PIN_REG(MX53_PAD_EIM_DA9, 0x510, 0x1C0, 1, 0x000, 0), /* MX53_PAD_EIM_DA9__GPIO3_9 */ - IMX_PIN_REG(MX53_PAD_EIM_DA9, 0x510, 0x1C0, 3, 0x000, 0), /* MX53_PAD_EIM_DA9__IPU_DISP1_DAT_0 */ - IMX_PIN_REG(MX53_PAD_EIM_DA9, 0x510, 0x1C0, 4, 0x000, 0), /* MX53_PAD_EIM_DA9__IPU_CSI1_D_0 */ - IMX_PIN_REG(MX53_PAD_EIM_DA9, 0x510, 0x1C0, 7, 0x000, 0), /* MX53_PAD_EIM_DA9__SRC_BT_CFG3_2 */ - IMX_PIN_REG(MX53_PAD_EIM_DA10, 0x514, 0x1C4, 0, 0x000, 0), /* MX53_PAD_EIM_DA10__EMI_NAND_WEIM_DA_10 */ - IMX_PIN_REG(MX53_PAD_EIM_DA10, 0x514, 0x1C4, 1, 0x000, 0), /* MX53_PAD_EIM_DA10__GPIO3_10 */ - IMX_PIN_REG(MX53_PAD_EIM_DA10, 0x514, 0x1C4, 3, 0x000, 0), /* MX53_PAD_EIM_DA10__IPU_DI1_PIN15 */ - IMX_PIN_REG(MX53_PAD_EIM_DA10, 0x514, 0x1C4, 4, 0x834, 1), /* MX53_PAD_EIM_DA10__IPU_CSI1_DATA_EN */ - IMX_PIN_REG(MX53_PAD_EIM_DA10, 0x514, 0x1C4, 7, 0x000, 0), /* MX53_PAD_EIM_DA10__SRC_BT_CFG3_1 */ - IMX_PIN_REG(MX53_PAD_EIM_DA11, 0x518, 0x1C8, 0, 0x000, 0), /* MX53_PAD_EIM_DA11__EMI_NAND_WEIM_DA_11 */ - IMX_PIN_REG(MX53_PAD_EIM_DA11, 0x518, 0x1C8, 1, 0x000, 0), /* MX53_PAD_EIM_DA11__GPIO3_11 */ - IMX_PIN_REG(MX53_PAD_EIM_DA11, 0x518, 0x1C8, 3, 0x000, 0), /* MX53_PAD_EIM_DA11__IPU_DI1_PIN2 */ - IMX_PIN_REG(MX53_PAD_EIM_DA11, 0x518, 0x1C8, 4, 0x838, 1), /* MX53_PAD_EIM_DA11__IPU_CSI1_HSYNC */ - IMX_PIN_REG(MX53_PAD_EIM_DA12, 0x51C, 0x1CC, 0, 0x000, 0), /* MX53_PAD_EIM_DA12__EMI_NAND_WEIM_DA_12 */ - IMX_PIN_REG(MX53_PAD_EIM_DA12, 0x51C, 0x1CC, 1, 0x000, 0), /* MX53_PAD_EIM_DA12__GPIO3_12 */ - IMX_PIN_REG(MX53_PAD_EIM_DA12, 0x51C, 0x1CC, 3, 0x000, 0), /* MX53_PAD_EIM_DA12__IPU_DI1_PIN3 */ - IMX_PIN_REG(MX53_PAD_EIM_DA12, 0x51C, 0x1CC, 4, 0x83C, 1), /* MX53_PAD_EIM_DA12__IPU_CSI1_VSYNC */ - IMX_PIN_REG(MX53_PAD_EIM_DA13, 0x520, 0x1D0, 0, 0x000, 0), /* MX53_PAD_EIM_DA13__EMI_NAND_WEIM_DA_13 */ - IMX_PIN_REG(MX53_PAD_EIM_DA13, 0x520, 0x1D0, 1, 0x000, 0), /* MX53_PAD_EIM_DA13__GPIO3_13 */ - IMX_PIN_REG(MX53_PAD_EIM_DA13, 0x520, 0x1D0, 3, 0x000, 0), /* MX53_PAD_EIM_DA13__IPU_DI1_D0_CS */ - IMX_PIN_REG(MX53_PAD_EIM_DA13, 0x520, 0x1D0, 4, 0x76C, 1), /* MX53_PAD_EIM_DA13__CCM_DI1_EXT_CLK */ - IMX_PIN_REG(MX53_PAD_EIM_DA14, 0x524, 0x1D4, 0, 0x000, 0), /* MX53_PAD_EIM_DA14__EMI_NAND_WEIM_DA_14 */ - IMX_PIN_REG(MX53_PAD_EIM_DA14, 0x524, 0x1D4, 1, 0x000, 0), /* MX53_PAD_EIM_DA14__GPIO3_14 */ - IMX_PIN_REG(MX53_PAD_EIM_DA14, 0x524, 0x1D4, 3, 0x000, 0), /* MX53_PAD_EIM_DA14__IPU_DI1_D1_CS */ - IMX_PIN_REG(MX53_PAD_EIM_DA14, 0x524, 0x1D4, 4, 0x000, 0), /* MX53_PAD_EIM_DA14__CCM_DI0_EXT_CLK */ - IMX_PIN_REG(MX53_PAD_EIM_DA15, 0x528, 0x1D8, 0, 0x000, 0), /* MX53_PAD_EIM_DA15__EMI_NAND_WEIM_DA_15 */ - IMX_PIN_REG(MX53_PAD_EIM_DA15, 0x528, 0x1D8, 1, 0x000, 0), /* MX53_PAD_EIM_DA15__GPIO3_15 */ - IMX_PIN_REG(MX53_PAD_EIM_DA15, 0x528, 0x1D8, 3, 0x000, 0), /* MX53_PAD_EIM_DA15__IPU_DI1_PIN1 */ - IMX_PIN_REG(MX53_PAD_EIM_DA15, 0x528, 0x1D8, 4, 0x000, 0), /* MX53_PAD_EIM_DA15__IPU_DI1_PIN4 */ - IMX_PIN_REG(MX53_PAD_NANDF_WE_B, 0x52C, 0x1DC, 0, 0x000, 0), /* MX53_PAD_NANDF_WE_B__EMI_NANDF_WE_B */ - IMX_PIN_REG(MX53_PAD_NANDF_WE_B, 0x52C, 0x1DC, 1, 0x000, 0), /* MX53_PAD_NANDF_WE_B__GPIO6_12 */ - IMX_PIN_REG(MX53_PAD_NANDF_RE_B, 0x530, 0x1E0, 0, 0x000, 0), /* MX53_PAD_NANDF_RE_B__EMI_NANDF_RE_B */ - IMX_PIN_REG(MX53_PAD_NANDF_RE_B, 0x530, 0x1E0, 1, 0x000, 0), /* MX53_PAD_NANDF_RE_B__GPIO6_13 */ - IMX_PIN_REG(MX53_PAD_EIM_WAIT, 0x534, 0x1E4, 0, 0x000, 0), /* MX53_PAD_EIM_WAIT__EMI_WEIM_WAIT */ - IMX_PIN_REG(MX53_PAD_EIM_WAIT, 0x534, 0x1E4, 1, 0x000, 0), /* MX53_PAD_EIM_WAIT__GPIO5_0 */ - IMX_PIN_REG(MX53_PAD_EIM_WAIT, 0x534, 0x1E4, 2, 0x000, 0), /* MX53_PAD_EIM_WAIT__EMI_WEIM_DTACK_B */ - IMX_PIN_REG(MX53_PAD_LVDS1_TX3_P, NO_PAD, 0x1EC, 0, 0x000, 0), /* MX53_PAD_LVDS1_TX3_P__GPIO6_22 */ - IMX_PIN_REG(MX53_PAD_LVDS1_TX3_P, NO_PAD, 0x1EC, 1, 0x000, 0), /* MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3 */ - IMX_PIN_REG(MX53_PAD_LVDS1_TX2_P, NO_PAD, 0x1F0, 0, 0x000, 0), /* MX53_PAD_LVDS1_TX2_P__GPIO6_24 */ - IMX_PIN_REG(MX53_PAD_LVDS1_TX2_P, NO_PAD, 0x1F0, 1, 0x000, 0), /* MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2 */ - IMX_PIN_REG(MX53_PAD_LVDS1_CLK_P, NO_PAD, 0x1F4, 0, 0x000, 0), /* MX53_PAD_LVDS1_CLK_P__GPIO6_26 */ - IMX_PIN_REG(MX53_PAD_LVDS1_CLK_P, NO_PAD, 0x1F4, 1, 0x000, 0), /* MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK */ - IMX_PIN_REG(MX53_PAD_LVDS1_TX1_P, NO_PAD, 0x1F8, 0, 0x000, 0), /* MX53_PAD_LVDS1_TX1_P__GPIO6_28 */ - IMX_PIN_REG(MX53_PAD_LVDS1_TX1_P, NO_PAD, 0x1F8, 1, 0x000, 0), /* MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1 */ - IMX_PIN_REG(MX53_PAD_LVDS1_TX0_P, NO_PAD, 0x1FC, 0, 0x000, 0), /* MX53_PAD_LVDS1_TX0_P__GPIO6_30 */ - IMX_PIN_REG(MX53_PAD_LVDS1_TX0_P, NO_PAD, 0x1FC, 1, 0x000, 0), /* MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0 */ - IMX_PIN_REG(MX53_PAD_LVDS0_TX3_P, NO_PAD, 0x200, 0, 0x000, 0), /* MX53_PAD_LVDS0_TX3_P__GPIO7_22 */ - IMX_PIN_REG(MX53_PAD_LVDS0_TX3_P, NO_PAD, 0x200, 1, 0x000, 0), /* MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3 */ - IMX_PIN_REG(MX53_PAD_LVDS0_CLK_P, NO_PAD, 0x204, 0, 0x000, 0), /* MX53_PAD_LVDS0_CLK_P__GPIO7_24 */ - IMX_PIN_REG(MX53_PAD_LVDS0_CLK_P, NO_PAD, 0x204, 1, 0x000, 0), /* MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK */ - IMX_PIN_REG(MX53_PAD_LVDS0_TX2_P, NO_PAD, 0x208, 0, 0x000, 0), /* MX53_PAD_LVDS0_TX2_P__GPIO7_26 */ - IMX_PIN_REG(MX53_PAD_LVDS0_TX2_P, NO_PAD, 0x208, 1, 0x000, 0), /* MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2 */ - IMX_PIN_REG(MX53_PAD_LVDS0_TX1_P, NO_PAD, 0x20C, 0, 0x000, 0), /* MX53_PAD_LVDS0_TX1_P__GPIO7_28 */ - IMX_PIN_REG(MX53_PAD_LVDS0_TX1_P, NO_PAD, 0x20C, 1, 0x000, 0), /* MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1 */ - IMX_PIN_REG(MX53_PAD_LVDS0_TX0_P, NO_PAD, 0x210, 0, 0x000, 0), /* MX53_PAD_LVDS0_TX0_P__GPIO7_30 */ - IMX_PIN_REG(MX53_PAD_LVDS0_TX0_P, NO_PAD, 0x210, 1, 0x000, 0), /* MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0 */ - IMX_PIN_REG(MX53_PAD_GPIO_10, 0x540, 0x214, 0, 0x000, 0), /* MX53_PAD_GPIO_10__GPIO4_0 */ - IMX_PIN_REG(MX53_PAD_GPIO_10, 0x540, 0x214, 1, 0x000, 0), /* MX53_PAD_GPIO_10__OSC32k_32K_OUT */ - IMX_PIN_REG(MX53_PAD_GPIO_11, 0x544, 0x218, 0, 0x000, 0), /* MX53_PAD_GPIO_11__GPIO4_1 */ - IMX_PIN_REG(MX53_PAD_GPIO_12, 0x548, 0x21C, 0, 0x000, 0), /* MX53_PAD_GPIO_12__GPIO4_2 */ - IMX_PIN_REG(MX53_PAD_GPIO_13, 0x54C, 0x220, 0, 0x000, 0), /* MX53_PAD_GPIO_13__GPIO4_3 */ - IMX_PIN_REG(MX53_PAD_GPIO_14, 0x550, 0x224, 0, 0x000, 0), /* MX53_PAD_GPIO_14__GPIO4_4 */ - IMX_PIN_REG(MX53_PAD_NANDF_CLE, 0x5A0, 0x228, 0, 0x000, 0), /* MX53_PAD_NANDF_CLE__EMI_NANDF_CLE */ - IMX_PIN_REG(MX53_PAD_NANDF_CLE, 0x5A0, 0x228, 1, 0x000, 0), /* MX53_PAD_NANDF_CLE__GPIO6_7 */ - IMX_PIN_REG(MX53_PAD_NANDF_CLE, 0x5A0, 0x228, 7, 0x000, 0), /* MX53_PAD_NANDF_CLE__USBPHY1_VSTATUS_0 */ - IMX_PIN_REG(MX53_PAD_NANDF_ALE, 0x5A4, 0x22C, 0, 0x000, 0), /* MX53_PAD_NANDF_ALE__EMI_NANDF_ALE */ - IMX_PIN_REG(MX53_PAD_NANDF_ALE, 0x5A4, 0x22C, 1, 0x000, 0), /* MX53_PAD_NANDF_ALE__GPIO6_8 */ - IMX_PIN_REG(MX53_PAD_NANDF_ALE, 0x5A4, 0x22C, 7, 0x000, 0), /* MX53_PAD_NANDF_ALE__USBPHY1_VSTATUS_1 */ - IMX_PIN_REG(MX53_PAD_NANDF_WP_B, 0x5A8, 0x230, 0, 0x000, 0), /* MX53_PAD_NANDF_WP_B__EMI_NANDF_WP_B */ - IMX_PIN_REG(MX53_PAD_NANDF_WP_B, 0x5A8, 0x230, 1, 0x000, 0), /* MX53_PAD_NANDF_WP_B__GPIO6_9 */ - IMX_PIN_REG(MX53_PAD_NANDF_WP_B, 0x5A8, 0x230, 7, 0x000, 0), /* MX53_PAD_NANDF_WP_B__USBPHY1_VSTATUS_2 */ - IMX_PIN_REG(MX53_PAD_NANDF_RB0, 0x5AC, 0x234, 0, 0x000, 0), /* MX53_PAD_NANDF_RB0__EMI_NANDF_RB_0 */ - IMX_PIN_REG(MX53_PAD_NANDF_RB0, 0x5AC, 0x234, 1, 0x000, 0), /* MX53_PAD_NANDF_RB0__GPIO6_10 */ - IMX_PIN_REG(MX53_PAD_NANDF_RB0, 0x5AC, 0x234, 7, 0x000, 0), /* MX53_PAD_NANDF_RB0__USBPHY1_VSTATUS_3 */ - IMX_PIN_REG(MX53_PAD_NANDF_CS0, 0x5B0, 0x238, 0, 0x000, 0), /* MX53_PAD_NANDF_CS0__EMI_NANDF_CS_0 */ - IMX_PIN_REG(MX53_PAD_NANDF_CS0, 0x5B0, 0x238, 1, 0x000, 0), /* MX53_PAD_NANDF_CS0__GPIO6_11 */ - IMX_PIN_REG(MX53_PAD_NANDF_CS0, 0x5B0, 0x238, 7, 0x000, 0), /* MX53_PAD_NANDF_CS0__USBPHY1_VSTATUS_4 */ - IMX_PIN_REG(MX53_PAD_NANDF_CS1, 0x5B4, 0x23C, 0, 0x000, 0), /* MX53_PAD_NANDF_CS1__EMI_NANDF_CS_1 */ - IMX_PIN_REG(MX53_PAD_NANDF_CS1, 0x5B4, 0x23C, 1, 0x000, 0), /* MX53_PAD_NANDF_CS1__GPIO6_14 */ - IMX_PIN_REG(MX53_PAD_NANDF_CS1, 0x5B4, 0x23C, 6, 0x858, 0), /* MX53_PAD_NANDF_CS1__MLB_MLBCLK */ - IMX_PIN_REG(MX53_PAD_NANDF_CS1, 0x5B4, 0x23C, 7, 0x000, 0), /* MX53_PAD_NANDF_CS1__USBPHY1_VSTATUS_5 */ - IMX_PIN_REG(MX53_PAD_NANDF_CS2, 0x5B8, 0x240, 0, 0x000, 0), /* MX53_PAD_NANDF_CS2__EMI_NANDF_CS_2 */ - IMX_PIN_REG(MX53_PAD_NANDF_CS2, 0x5B8, 0x240, 1, 0x000, 0), /* MX53_PAD_NANDF_CS2__GPIO6_15 */ - IMX_PIN_REG(MX53_PAD_NANDF_CS2, 0x5B8, 0x240, 2, 0x000, 0), /* MX53_PAD_NANDF_CS2__IPU_SISG_0 */ - IMX_PIN_REG(MX53_PAD_NANDF_CS2, 0x5B8, 0x240, 3, 0x7E4, 0), /* MX53_PAD_NANDF_CS2__ESAI1_TX0 */ - IMX_PIN_REG(MX53_PAD_NANDF_CS2, 0x5B8, 0x240, 4, 0x000, 0), /* MX53_PAD_NANDF_CS2__EMI_WEIM_CRE */ - IMX_PIN_REG(MX53_PAD_NANDF_CS2, 0x5B8, 0x240, 5, 0x000, 0), /* MX53_PAD_NANDF_CS2__CCM_CSI0_MCLK */ - IMX_PIN_REG(MX53_PAD_NANDF_CS2, 0x5B8, 0x240, 6, 0x860, 0), /* MX53_PAD_NANDF_CS2__MLB_MLBSIG */ - IMX_PIN_REG(MX53_PAD_NANDF_CS2, 0x5B8, 0x240, 7, 0x000, 0), /* MX53_PAD_NANDF_CS2__USBPHY1_VSTATUS_6 */ - IMX_PIN_REG(MX53_PAD_NANDF_CS3, 0x5BC, 0x244, 0, 0x000, 0), /* MX53_PAD_NANDF_CS3__EMI_NANDF_CS_3 */ - IMX_PIN_REG(MX53_PAD_NANDF_CS3, 0x5BC, 0x244, 1, 0x000, 0), /* MX53_PAD_NANDF_CS3__GPIO6_16 */ - IMX_PIN_REG(MX53_PAD_NANDF_CS3, 0x5BC, 0x244, 2, 0x000, 0), /* MX53_PAD_NANDF_CS3__IPU_SISG_1 */ - IMX_PIN_REG(MX53_PAD_NANDF_CS3, 0x5BC, 0x244, 3, 0x7E8, 0), /* MX53_PAD_NANDF_CS3__ESAI1_TX1 */ - IMX_PIN_REG(MX53_PAD_NANDF_CS3, 0x5BC, 0x244, 4, 0x000, 0), /* MX53_PAD_NANDF_CS3__EMI_WEIM_A_26 */ - IMX_PIN_REG(MX53_PAD_NANDF_CS3, 0x5BC, 0x244, 6, 0x85C, 0), /* MX53_PAD_NANDF_CS3__MLB_MLBDAT */ - IMX_PIN_REG(MX53_PAD_NANDF_CS3, 0x5BC, 0x244, 7, 0x000, 0), /* MX53_PAD_NANDF_CS3__USBPHY1_VSTATUS_7 */ - IMX_PIN_REG(MX53_PAD_FEC_MDIO, 0x5C4, 0x248, 0, 0x804, 1), /* MX53_PAD_FEC_MDIO__FEC_MDIO */ - IMX_PIN_REG(MX53_PAD_FEC_MDIO, 0x5C4, 0x248, 1, 0x000, 0), /* MX53_PAD_FEC_MDIO__GPIO1_22 */ - IMX_PIN_REG(MX53_PAD_FEC_MDIO, 0x5C4, 0x248, 2, 0x7DC, 0), /* MX53_PAD_FEC_MDIO__ESAI1_SCKR */ - IMX_PIN_REG(MX53_PAD_FEC_MDIO, 0x5C4, 0x248, 3, 0x800, 1), /* MX53_PAD_FEC_MDIO__FEC_COL */ - IMX_PIN_REG(MX53_PAD_FEC_MDIO, 0x5C4, 0x248, 4, 0x000, 0), /* MX53_PAD_FEC_MDIO__RTC_CE_RTC_PS2 */ - IMX_PIN_REG(MX53_PAD_FEC_MDIO, 0x5C4, 0x248, 5, 0x000, 0), /* MX53_PAD_FEC_MDIO__SDMA_DEBUG_BUS_DEVICE_3 */ - IMX_PIN_REG(MX53_PAD_FEC_MDIO, 0x5C4, 0x248, 6, 0x000, 0), /* MX53_PAD_FEC_MDIO__EMI_EMI_DEBUG_49 */ - IMX_PIN_REG(MX53_PAD_FEC_REF_CLK, 0x5C8, 0x24C, 0, 0x000, 0), /* MX53_PAD_FEC_REF_CLK__FEC_TX_CLK */ - IMX_PIN_REG(MX53_PAD_FEC_REF_CLK, 0x5C8, 0x24C, 1, 0x000, 0), /* MX53_PAD_FEC_REF_CLK__GPIO1_23 */ - IMX_PIN_REG(MX53_PAD_FEC_REF_CLK, 0x5C8, 0x24C, 2, 0x7CC, 0), /* MX53_PAD_FEC_REF_CLK__ESAI1_FSR */ - IMX_PIN_REG(MX53_PAD_FEC_REF_CLK, 0x5C8, 0x24C, 5, 0x000, 0), /* MX53_PAD_FEC_REF_CLK__SDMA_DEBUG_BUS_DEVICE_4 */ - IMX_PIN_REG(MX53_PAD_FEC_REF_CLK, 0x5C8, 0x24C, 6, 0x000, 0), /* MX53_PAD_FEC_REF_CLK__EMI_EMI_DEBUG_50 */ - IMX_PIN_REG(MX53_PAD_FEC_RX_ER, 0x5CC, 0x250, 0, 0x000, 0), /* MX53_PAD_FEC_RX_ER__FEC_RX_ER */ - IMX_PIN_REG(MX53_PAD_FEC_RX_ER, 0x5CC, 0x250, 1, 0x000, 0), /* MX53_PAD_FEC_RX_ER__GPIO1_24 */ - IMX_PIN_REG(MX53_PAD_FEC_RX_ER, 0x5CC, 0x250, 2, 0x7D4, 0), /* MX53_PAD_FEC_RX_ER__ESAI1_HCKR */ - IMX_PIN_REG(MX53_PAD_FEC_RX_ER, 0x5CC, 0x250, 3, 0x808, 1), /* MX53_PAD_FEC_RX_ER__FEC_RX_CLK */ - IMX_PIN_REG(MX53_PAD_FEC_RX_ER, 0x5CC, 0x250, 4, 0x000, 0), /* MX53_PAD_FEC_RX_ER__RTC_CE_RTC_PS3 */ - IMX_PIN_REG(MX53_PAD_FEC_CRS_DV, 0x5D0, 0x254, 0, 0x000, 0), /* MX53_PAD_FEC_CRS_DV__FEC_RX_DV */ - IMX_PIN_REG(MX53_PAD_FEC_CRS_DV, 0x5D0, 0x254, 1, 0x000, 0), /* MX53_PAD_FEC_CRS_DV__GPIO1_25 */ - IMX_PIN_REG(MX53_PAD_FEC_CRS_DV, 0x5D0, 0x254, 2, 0x7E0, 0), /* MX53_PAD_FEC_CRS_DV__ESAI1_SCKT */ - IMX_PIN_REG(MX53_PAD_FEC_RXD1, 0x5D4, 0x258, 0, 0x000, 0), /* MX53_PAD_FEC_RXD1__FEC_RDATA_1 */ - IMX_PIN_REG(MX53_PAD_FEC_RXD1, 0x5D4, 0x258, 1, 0x000, 0), /* MX53_PAD_FEC_RXD1__GPIO1_26 */ - IMX_PIN_REG(MX53_PAD_FEC_RXD1, 0x5D4, 0x258, 2, 0x7D0, 0), /* MX53_PAD_FEC_RXD1__ESAI1_FST */ - IMX_PIN_REG(MX53_PAD_FEC_RXD1, 0x5D4, 0x258, 3, 0x860, 1), /* MX53_PAD_FEC_RXD1__MLB_MLBSIG */ - IMX_PIN_REG(MX53_PAD_FEC_RXD1, 0x5D4, 0x258, 4, 0x000, 0), /* MX53_PAD_FEC_RXD1__RTC_CE_RTC_PS1 */ - IMX_PIN_REG(MX53_PAD_FEC_RXD0, 0x5D8, 0x25C, 0, 0x000, 0), /* MX53_PAD_FEC_RXD0__FEC_RDATA_0 */ - IMX_PIN_REG(MX53_PAD_FEC_RXD0, 0x5D8, 0x25C, 1, 0x000, 0), /* MX53_PAD_FEC_RXD0__GPIO1_27 */ - IMX_PIN_REG(MX53_PAD_FEC_RXD0, 0x5D8, 0x25C, 2, 0x7D8, 0), /* MX53_PAD_FEC_RXD0__ESAI1_HCKT */ - IMX_PIN_REG(MX53_PAD_FEC_RXD0, 0x5D8, 0x25C, 3, 0x000, 0), /* MX53_PAD_FEC_RXD0__OSC32k_32K_OUT */ - IMX_PIN_REG(MX53_PAD_FEC_TX_EN, 0x5DC, 0x260, 0, 0x000, 0), /* MX53_PAD_FEC_TX_EN__FEC_TX_EN */ - IMX_PIN_REG(MX53_PAD_FEC_TX_EN, 0x5DC, 0x260, 1, 0x000, 0), /* MX53_PAD_FEC_TX_EN__GPIO1_28 */ - IMX_PIN_REG(MX53_PAD_FEC_TX_EN, 0x5DC, 0x260, 2, 0x7F0, 0), /* MX53_PAD_FEC_TX_EN__ESAI1_TX3_RX2 */ - IMX_PIN_REG(MX53_PAD_FEC_TXD1, 0x5E0, 0x264, 0, 0x000, 0), /* MX53_PAD_FEC_TXD1__FEC_TDATA_1 */ - IMX_PIN_REG(MX53_PAD_FEC_TXD1, 0x5E0, 0x264, 1, 0x000, 0), /* MX53_PAD_FEC_TXD1__GPIO1_29 */ - IMX_PIN_REG(MX53_PAD_FEC_TXD1, 0x5E0, 0x264, 2, 0x7EC, 0), /* MX53_PAD_FEC_TXD1__ESAI1_TX2_RX3 */ - IMX_PIN_REG(MX53_PAD_FEC_TXD1, 0x5E0, 0x264, 3, 0x858, 1), /* MX53_PAD_FEC_TXD1__MLB_MLBCLK */ - IMX_PIN_REG(MX53_PAD_FEC_TXD1, 0x5E0, 0x264, 4, 0x000, 0), /* MX53_PAD_FEC_TXD1__RTC_CE_RTC_PRSC_CLK */ - IMX_PIN_REG(MX53_PAD_FEC_TXD0, 0x5E4, 0x268, 0, 0x000, 0), /* MX53_PAD_FEC_TXD0__FEC_TDATA_0 */ - IMX_PIN_REG(MX53_PAD_FEC_TXD0, 0x5E4, 0x268, 1, 0x000, 0), /* MX53_PAD_FEC_TXD0__GPIO1_30 */ - IMX_PIN_REG(MX53_PAD_FEC_TXD0, 0x5E4, 0x268, 2, 0x7F4, 0), /* MX53_PAD_FEC_TXD0__ESAI1_TX4_RX1 */ - IMX_PIN_REG(MX53_PAD_FEC_TXD0, 0x5E4, 0x268, 7, 0x000, 0), /* MX53_PAD_FEC_TXD0__USBPHY2_DATAOUT_0 */ - IMX_PIN_REG(MX53_PAD_FEC_MDC, 0x5E8, 0x26C, 0, 0x000, 0), /* MX53_PAD_FEC_MDC__FEC_MDC */ - IMX_PIN_REG(MX53_PAD_FEC_MDC, 0x5E8, 0x26C, 1, 0x000, 0), /* MX53_PAD_FEC_MDC__GPIO1_31 */ - IMX_PIN_REG(MX53_PAD_FEC_MDC, 0x5E8, 0x26C, 2, 0x7F8, 0), /* MX53_PAD_FEC_MDC__ESAI1_TX5_RX0 */ - IMX_PIN_REG(MX53_PAD_FEC_MDC, 0x5E8, 0x26C, 3, 0x85C, 1), /* MX53_PAD_FEC_MDC__MLB_MLBDAT */ - IMX_PIN_REG(MX53_PAD_FEC_MDC, 0x5E8, 0x26C, 4, 0x000, 0), /* MX53_PAD_FEC_MDC__RTC_CE_RTC_ALARM1_TRIG */ - IMX_PIN_REG(MX53_PAD_FEC_MDC, 0x5E8, 0x26C, 7, 0x000, 0), /* MX53_PAD_FEC_MDC__USBPHY2_DATAOUT_1 */ - IMX_PIN_REG(MX53_PAD_PATA_DIOW, 0x5F0, 0x270, 0, 0x000, 0), /* MX53_PAD_PATA_DIOW__PATA_DIOW */ - IMX_PIN_REG(MX53_PAD_PATA_DIOW, 0x5F0, 0x270, 1, 0x000, 0), /* MX53_PAD_PATA_DIOW__GPIO6_17 */ - IMX_PIN_REG(MX53_PAD_PATA_DIOW, 0x5F0, 0x270, 3, 0x000, 0), /* MX53_PAD_PATA_DIOW__UART1_TXD_MUX */ - IMX_PIN_REG(MX53_PAD_PATA_DIOW, 0x5F0, 0x270, 7, 0x000, 0), /* MX53_PAD_PATA_DIOW__USBPHY2_DATAOUT_2 */ - IMX_PIN_REG(MX53_PAD_PATA_DMACK, 0x5F4, 0x274, 0, 0x000, 0), /* MX53_PAD_PATA_DMACK__PATA_DMACK */ - IMX_PIN_REG(MX53_PAD_PATA_DMACK, 0x5F4, 0x274, 1, 0x000, 0), /* MX53_PAD_PATA_DMACK__GPIO6_18 */ - IMX_PIN_REG(MX53_PAD_PATA_DMACK, 0x5F4, 0x274, 3, 0x878, 3), /* MX53_PAD_PATA_DMACK__UART1_RXD_MUX */ - IMX_PIN_REG(MX53_PAD_PATA_DMACK, 0x5F4, 0x274, 7, 0x000, 0), /* MX53_PAD_PATA_DMACK__USBPHY2_DATAOUT_3 */ - IMX_PIN_REG(MX53_PAD_PATA_DMARQ, 0x5F8, 0x278, 0, 0x000, 0), /* MX53_PAD_PATA_DMARQ__PATA_DMARQ */ - IMX_PIN_REG(MX53_PAD_PATA_DMARQ, 0x5F8, 0x278, 1, 0x000, 0), /* MX53_PAD_PATA_DMARQ__GPIO7_0 */ - IMX_PIN_REG(MX53_PAD_PATA_DMARQ, 0x5F8, 0x278, 3, 0x000, 0), /* MX53_PAD_PATA_DMARQ__UART2_TXD_MUX */ - IMX_PIN_REG(MX53_PAD_PATA_DMARQ, 0x5F8, 0x278, 5, 0x000, 0), /* MX53_PAD_PATA_DMARQ__CCM_CCM_OUT_0 */ - IMX_PIN_REG(MX53_PAD_PATA_DMARQ, 0x5F8, 0x278, 7, 0x000, 0), /* MX53_PAD_PATA_DMARQ__USBPHY2_DATAOUT_4 */ - IMX_PIN_REG(MX53_PAD_PATA_BUFFER_EN, 0x5FC, 0x27C, 0, 0x000, 0), /* MX53_PAD_PATA_BUFFER_EN__PATA_BUFFER_EN */ - IMX_PIN_REG(MX53_PAD_PATA_BUFFER_EN, 0x5FC, 0x27C, 1, 0x000, 0), /* MX53_PAD_PATA_BUFFER_EN__GPIO7_1 */ - IMX_PIN_REG(MX53_PAD_PATA_BUFFER_EN, 0x5FC, 0x27C, 3, 0x880, 3), /* MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX */ - IMX_PIN_REG(MX53_PAD_PATA_BUFFER_EN, 0x5FC, 0x27C, 5, 0x000, 0), /* MX53_PAD_PATA_BUFFER_EN__CCM_CCM_OUT_1 */ - IMX_PIN_REG(MX53_PAD_PATA_BUFFER_EN, 0x5FC, 0x27C, 7, 0x000, 0), /* MX53_PAD_PATA_BUFFER_EN__USBPHY2_DATAOUT_5 */ - IMX_PIN_REG(MX53_PAD_PATA_INTRQ, 0x600, 0x280, 0, 0x000, 0), /* MX53_PAD_PATA_INTRQ__PATA_INTRQ */ - IMX_PIN_REG(MX53_PAD_PATA_INTRQ, 0x600, 0x280, 1, 0x000, 0), /* MX53_PAD_PATA_INTRQ__GPIO7_2 */ - IMX_PIN_REG(MX53_PAD_PATA_INTRQ, 0x600, 0x280, 3, 0x000, 0), /* MX53_PAD_PATA_INTRQ__UART2_CTS */ - IMX_PIN_REG(MX53_PAD_PATA_INTRQ, 0x600, 0x280, 4, 0x000, 0), /* MX53_PAD_PATA_INTRQ__CAN1_TXCAN */ - IMX_PIN_REG(MX53_PAD_PATA_INTRQ, 0x600, 0x280, 5, 0x000, 0), /* MX53_PAD_PATA_INTRQ__CCM_CCM_OUT_2 */ - IMX_PIN_REG(MX53_PAD_PATA_INTRQ, 0x600, 0x280, 7, 0x000, 0), /* MX53_PAD_PATA_INTRQ__USBPHY2_DATAOUT_6 */ - IMX_PIN_REG(MX53_PAD_PATA_DIOR, 0x604, 0x284, 0, 0x000, 0), /* MX53_PAD_PATA_DIOR__PATA_DIOR */ - IMX_PIN_REG(MX53_PAD_PATA_DIOR, 0x604, 0x284, 1, 0x000, 0), /* MX53_PAD_PATA_DIOR__GPIO7_3 */ - IMX_PIN_REG(MX53_PAD_PATA_DIOR, 0x604, 0x284, 3, 0x87C, 3), /* MX53_PAD_PATA_DIOR__UART2_RTS */ - IMX_PIN_REG(MX53_PAD_PATA_DIOR, 0x604, 0x284, 4, 0x760, 1), /* MX53_PAD_PATA_DIOR__CAN1_RXCAN */ - IMX_PIN_REG(MX53_PAD_PATA_DIOR, 0x604, 0x284, 7, 0x000, 0), /* MX53_PAD_PATA_DIOR__USBPHY2_DATAOUT_7 */ - IMX_PIN_REG(MX53_PAD_PATA_RESET_B, 0x608, 0x288, 0, 0x000, 0), /* MX53_PAD_PATA_RESET_B__PATA_PATA_RESET_B */ - IMX_PIN_REG(MX53_PAD_PATA_RESET_B, 0x608, 0x288, 1, 0x000, 0), /* MX53_PAD_PATA_RESET_B__GPIO7_4 */ - IMX_PIN_REG(MX53_PAD_PATA_RESET_B, 0x608, 0x288, 2, 0x000, 0), /* MX53_PAD_PATA_RESET_B__ESDHC3_CMD */ - IMX_PIN_REG(MX53_PAD_PATA_RESET_B, 0x608, 0x288, 3, 0x000, 0), /* MX53_PAD_PATA_RESET_B__UART1_CTS */ - IMX_PIN_REG(MX53_PAD_PATA_RESET_B, 0x608, 0x288, 4, 0x000, 0), /* MX53_PAD_PATA_RESET_B__CAN2_TXCAN */ - IMX_PIN_REG(MX53_PAD_PATA_RESET_B, 0x608, 0x288, 7, 0x000, 0), /* MX53_PAD_PATA_RESET_B__USBPHY1_DATAOUT_0 */ - IMX_PIN_REG(MX53_PAD_PATA_IORDY, 0x60C, 0x28C, 0, 0x000, 0), /* MX53_PAD_PATA_IORDY__PATA_IORDY */ - IMX_PIN_REG(MX53_PAD_PATA_IORDY, 0x60C, 0x28C, 1, 0x000, 0), /* MX53_PAD_PATA_IORDY__GPIO7_5 */ - IMX_PIN_REG(MX53_PAD_PATA_IORDY, 0x60C, 0x28C, 2, 0x000, 0), /* MX53_PAD_PATA_IORDY__ESDHC3_CLK */ - IMX_PIN_REG(MX53_PAD_PATA_IORDY, 0x60C, 0x28C, 3, 0x874, 3), /* MX53_PAD_PATA_IORDY__UART1_RTS */ - IMX_PIN_REG(MX53_PAD_PATA_IORDY, 0x60C, 0x28C, 4, 0x764, 1), /* MX53_PAD_PATA_IORDY__CAN2_RXCAN */ - IMX_PIN_REG(MX53_PAD_PATA_IORDY, 0x60C, 0x28C, 7, 0x000, 0), /* MX53_PAD_PATA_IORDY__USBPHY1_DATAOUT_1 */ - IMX_PIN_REG(MX53_PAD_PATA_DA_0, 0x610, 0x290, 0, 0x000, 0), /* MX53_PAD_PATA_DA_0__PATA_DA_0 */ - IMX_PIN_REG(MX53_PAD_PATA_DA_0, 0x610, 0x290, 1, 0x000, 0), /* MX53_PAD_PATA_DA_0__GPIO7_6 */ - IMX_PIN_REG(MX53_PAD_PATA_DA_0, 0x610, 0x290, 2, 0x000, 0), /* MX53_PAD_PATA_DA_0__ESDHC3_RST */ - IMX_PIN_REG(MX53_PAD_PATA_DA_0, 0x610, 0x290, 4, 0x864, 0), /* MX53_PAD_PATA_DA_0__OWIRE_LINE */ - IMX_PIN_REG(MX53_PAD_PATA_DA_0, 0x610, 0x290, 7, 0x000, 0), /* MX53_PAD_PATA_DA_0__USBPHY1_DATAOUT_2 */ - IMX_PIN_REG(MX53_PAD_PATA_DA_1, 0x614, 0x294, 0, 0x000, 0), /* MX53_PAD_PATA_DA_1__PATA_DA_1 */ - IMX_PIN_REG(MX53_PAD_PATA_DA_1, 0x614, 0x294, 1, 0x000, 0), /* MX53_PAD_PATA_DA_1__GPIO7_7 */ - IMX_PIN_REG(MX53_PAD_PATA_DA_1, 0x614, 0x294, 2, 0x000, 0), /* MX53_PAD_PATA_DA_1__ESDHC4_CMD */ - IMX_PIN_REG(MX53_PAD_PATA_DA_1, 0x614, 0x294, 4, 0x000, 0), /* MX53_PAD_PATA_DA_1__UART3_CTS */ - IMX_PIN_REG(MX53_PAD_PATA_DA_1, 0x614, 0x294, 7, 0x000, 0), /* MX53_PAD_PATA_DA_1__USBPHY1_DATAOUT_3 */ - IMX_PIN_REG(MX53_PAD_PATA_DA_2, 0x618, 0x298, 0, 0x000, 0), /* MX53_PAD_PATA_DA_2__PATA_DA_2 */ - IMX_PIN_REG(MX53_PAD_PATA_DA_2, 0x618, 0x298, 1, 0x000, 0), /* MX53_PAD_PATA_DA_2__GPIO7_8 */ - IMX_PIN_REG(MX53_PAD_PATA_DA_2, 0x618, 0x298, 2, 0x000, 0), /* MX53_PAD_PATA_DA_2__ESDHC4_CLK */ - IMX_PIN_REG(MX53_PAD_PATA_DA_2, 0x618, 0x298, 4, 0x884, 5), /* MX53_PAD_PATA_DA_2__UART3_RTS */ - IMX_PIN_REG(MX53_PAD_PATA_DA_2, 0x618, 0x298, 7, 0x000, 0), /* MX53_PAD_PATA_DA_2__USBPHY1_DATAOUT_4 */ - IMX_PIN_REG(MX53_PAD_PATA_CS_0, 0x61C, 0x29C, 0, 0x000, 0), /* MX53_PAD_PATA_CS_0__PATA_CS_0 */ - IMX_PIN_REG(MX53_PAD_PATA_CS_0, 0x61C, 0x29C, 1, 0x000, 0), /* MX53_PAD_PATA_CS_0__GPIO7_9 */ - IMX_PIN_REG(MX53_PAD_PATA_CS_0, 0x61C, 0x29C, 4, 0x000, 0), /* MX53_PAD_PATA_CS_0__UART3_TXD_MUX */ - IMX_PIN_REG(MX53_PAD_PATA_CS_0, 0x61C, 0x29C, 7, 0x000, 0), /* MX53_PAD_PATA_CS_0__USBPHY1_DATAOUT_5 */ - IMX_PIN_REG(MX53_PAD_PATA_CS_1, 0x620, 0x2A0, 0, 0x000, 0), /* MX53_PAD_PATA_CS_1__PATA_CS_1 */ - IMX_PIN_REG(MX53_PAD_PATA_CS_1, 0x620, 0x2A0, 1, 0x000, 0), /* MX53_PAD_PATA_CS_1__GPIO7_10 */ - IMX_PIN_REG(MX53_PAD_PATA_CS_1, 0x620, 0x2A0, 4, 0x888, 3), /* MX53_PAD_PATA_CS_1__UART3_RXD_MUX */ - IMX_PIN_REG(MX53_PAD_PATA_CS_1, 0x620, 0x2A0, 7, 0x000, 0), /* MX53_PAD_PATA_CS_1__USBPHY1_DATAOUT_6 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA0, 0x628, 0x2A4, 0, 0x000, 0), /* MX53_PAD_PATA_DATA0__PATA_DATA_0 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA0, 0x628, 0x2A4, 1, 0x000, 0), /* MX53_PAD_PATA_DATA0__GPIO2_0 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA0, 0x628, 0x2A4, 3, 0x000, 0), /* MX53_PAD_PATA_DATA0__EMI_NANDF_D_0 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA0, 0x628, 0x2A4, 4, 0x000, 0), /* MX53_PAD_PATA_DATA0__ESDHC3_DAT4 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA0, 0x628, 0x2A4, 5, 0x000, 0), /* MX53_PAD_PATA_DATA0__GPU3d_GPU_DEBUG_OUT_0 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA0, 0x628, 0x2A4, 6, 0x000, 0), /* MX53_PAD_PATA_DATA0__IPU_DIAG_BUS_0 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA0, 0x628, 0x2A4, 7, 0x000, 0), /* MX53_PAD_PATA_DATA0__USBPHY1_DATAOUT_7 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA1, 0x62C, 0x2A8, 0, 0x000, 0), /* MX53_PAD_PATA_DATA1__PATA_DATA_1 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA1, 0x62C, 0x2A8, 1, 0x000, 0), /* MX53_PAD_PATA_DATA1__GPIO2_1 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA1, 0x62C, 0x2A8, 3, 0x000, 0), /* MX53_PAD_PATA_DATA1__EMI_NANDF_D_1 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA1, 0x62C, 0x2A8, 4, 0x000, 0), /* MX53_PAD_PATA_DATA1__ESDHC3_DAT5 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA1, 0x62C, 0x2A8, 5, 0x000, 0), /* MX53_PAD_PATA_DATA1__GPU3d_GPU_DEBUG_OUT_1 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA1, 0x62C, 0x2A8, 6, 0x000, 0), /* MX53_PAD_PATA_DATA1__IPU_DIAG_BUS_1 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA2, 0x630, 0x2AC, 0, 0x000, 0), /* MX53_PAD_PATA_DATA2__PATA_DATA_2 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA2, 0x630, 0x2AC, 1, 0x000, 0), /* MX53_PAD_PATA_DATA2__GPIO2_2 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA2, 0x630, 0x2AC, 3, 0x000, 0), /* MX53_PAD_PATA_DATA2__EMI_NANDF_D_2 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA2, 0x630, 0x2AC, 4, 0x000, 0), /* MX53_PAD_PATA_DATA2__ESDHC3_DAT6 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA2, 0x630, 0x2AC, 5, 0x000, 0), /* MX53_PAD_PATA_DATA2__GPU3d_GPU_DEBUG_OUT_2 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA2, 0x630, 0x2AC, 6, 0x000, 0), /* MX53_PAD_PATA_DATA2__IPU_DIAG_BUS_2 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA3, 0x634, 0x2B0, 0, 0x000, 0), /* MX53_PAD_PATA_DATA3__PATA_DATA_3 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA3, 0x634, 0x2B0, 1, 0x000, 0), /* MX53_PAD_PATA_DATA3__GPIO2_3 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA3, 0x634, 0x2B0, 3, 0x000, 0), /* MX53_PAD_PATA_DATA3__EMI_NANDF_D_3 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA3, 0x634, 0x2B0, 4, 0x000, 0), /* MX53_PAD_PATA_DATA3__ESDHC3_DAT7 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA3, 0x634, 0x2B0, 5, 0x000, 0), /* MX53_PAD_PATA_DATA3__GPU3d_GPU_DEBUG_OUT_3 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA3, 0x634, 0x2B0, 6, 0x000, 0), /* MX53_PAD_PATA_DATA3__IPU_DIAG_BUS_3 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA4, 0x638, 0x2B4, 0, 0x000, 0), /* MX53_PAD_PATA_DATA4__PATA_DATA_4 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA4, 0x638, 0x2B4, 1, 0x000, 0), /* MX53_PAD_PATA_DATA4__GPIO2_4 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA4, 0x638, 0x2B4, 3, 0x000, 0), /* MX53_PAD_PATA_DATA4__EMI_NANDF_D_4 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA4, 0x638, 0x2B4, 4, 0x000, 0), /* MX53_PAD_PATA_DATA4__ESDHC4_DAT4 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA4, 0x638, 0x2B4, 5, 0x000, 0), /* MX53_PAD_PATA_DATA4__GPU3d_GPU_DEBUG_OUT_4 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA4, 0x638, 0x2B4, 6, 0x000, 0), /* MX53_PAD_PATA_DATA4__IPU_DIAG_BUS_4 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA5, 0x63C, 0x2B8, 0, 0x000, 0), /* MX53_PAD_PATA_DATA5__PATA_DATA_5 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA5, 0x63C, 0x2B8, 1, 0x000, 0), /* MX53_PAD_PATA_DATA5__GPIO2_5 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA5, 0x63C, 0x2B8, 3, 0x000, 0), /* MX53_PAD_PATA_DATA5__EMI_NANDF_D_5 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA5, 0x63C, 0x2B8, 4, 0x000, 0), /* MX53_PAD_PATA_DATA5__ESDHC4_DAT5 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA5, 0x63C, 0x2B8, 5, 0x000, 0), /* MX53_PAD_PATA_DATA5__GPU3d_GPU_DEBUG_OUT_5 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA5, 0x63C, 0x2B8, 6, 0x000, 0), /* MX53_PAD_PATA_DATA5__IPU_DIAG_BUS_5 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA6, 0x640, 0x2BC, 0, 0x000, 0), /* MX53_PAD_PATA_DATA6__PATA_DATA_6 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA6, 0x640, 0x2BC, 1, 0x000, 0), /* MX53_PAD_PATA_DATA6__GPIO2_6 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA6, 0x640, 0x2BC, 3, 0x000, 0), /* MX53_PAD_PATA_DATA6__EMI_NANDF_D_6 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA6, 0x640, 0x2BC, 4, 0x000, 0), /* MX53_PAD_PATA_DATA6__ESDHC4_DAT6 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA6, 0x640, 0x2BC, 5, 0x000, 0), /* MX53_PAD_PATA_DATA6__GPU3d_GPU_DEBUG_OUT_6 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA6, 0x640, 0x2BC, 6, 0x000, 0), /* MX53_PAD_PATA_DATA6__IPU_DIAG_BUS_6 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA7, 0x644, 0x2C0, 0, 0x000, 0), /* MX53_PAD_PATA_DATA7__PATA_DATA_7 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA7, 0x644, 0x2C0, 1, 0x000, 0), /* MX53_PAD_PATA_DATA7__GPIO2_7 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA7, 0x644, 0x2C0, 3, 0x000, 0), /* MX53_PAD_PATA_DATA7__EMI_NANDF_D_7 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA7, 0x644, 0x2C0, 4, 0x000, 0), /* MX53_PAD_PATA_DATA7__ESDHC4_DAT7 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA7, 0x644, 0x2C0, 5, 0x000, 0), /* MX53_PAD_PATA_DATA7__GPU3d_GPU_DEBUG_OUT_7 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA7, 0x644, 0x2C0, 6, 0x000, 0), /* MX53_PAD_PATA_DATA7__IPU_DIAG_BUS_7 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA8, 0x648, 0x2C4, 0, 0x000, 0), /* MX53_PAD_PATA_DATA8__PATA_DATA_8 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA8, 0x648, 0x2C4, 1, 0x000, 0), /* MX53_PAD_PATA_DATA8__GPIO2_8 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA8, 0x648, 0x2C4, 2, 0x000, 0), /* MX53_PAD_PATA_DATA8__ESDHC1_DAT4 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA8, 0x648, 0x2C4, 3, 0x000, 0), /* MX53_PAD_PATA_DATA8__EMI_NANDF_D_8 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA8, 0x648, 0x2C4, 4, 0x000, 0), /* MX53_PAD_PATA_DATA8__ESDHC3_DAT0 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA8, 0x648, 0x2C4, 5, 0x000, 0), /* MX53_PAD_PATA_DATA8__GPU3d_GPU_DEBUG_OUT_8 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA8, 0x648, 0x2C4, 6, 0x000, 0), /* MX53_PAD_PATA_DATA8__IPU_DIAG_BUS_8 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA9, 0x64C, 0x2C8, 0, 0x000, 0), /* MX53_PAD_PATA_DATA9__PATA_DATA_9 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA9, 0x64C, 0x2C8, 1, 0x000, 0), /* MX53_PAD_PATA_DATA9__GPIO2_9 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA9, 0x64C, 0x2C8, 2, 0x000, 0), /* MX53_PAD_PATA_DATA9__ESDHC1_DAT5 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA9, 0x64C, 0x2C8, 3, 0x000, 0), /* MX53_PAD_PATA_DATA9__EMI_NANDF_D_9 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA9, 0x64C, 0x2C8, 4, 0x000, 0), /* MX53_PAD_PATA_DATA9__ESDHC3_DAT1 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA9, 0x64C, 0x2C8, 5, 0x000, 0), /* MX53_PAD_PATA_DATA9__GPU3d_GPU_DEBUG_OUT_9 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA9, 0x64C, 0x2C8, 6, 0x000, 0), /* MX53_PAD_PATA_DATA9__IPU_DIAG_BUS_9 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA10, 0x650, 0x2CC, 0, 0x000, 0), /* MX53_PAD_PATA_DATA10__PATA_DATA_10 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA10, 0x650, 0x2CC, 1, 0x000, 0), /* MX53_PAD_PATA_DATA10__GPIO2_10 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA10, 0x650, 0x2CC, 2, 0x000, 0), /* MX53_PAD_PATA_DATA10__ESDHC1_DAT6 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA10, 0x650, 0x2CC, 3, 0x000, 0), /* MX53_PAD_PATA_DATA10__EMI_NANDF_D_10 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA10, 0x650, 0x2CC, 4, 0x000, 0), /* MX53_PAD_PATA_DATA10__ESDHC3_DAT2 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA10, 0x650, 0x2CC, 5, 0x000, 0), /* MX53_PAD_PATA_DATA10__GPU3d_GPU_DEBUG_OUT_10 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA10, 0x650, 0x2CC, 6, 0x000, 0), /* MX53_PAD_PATA_DATA10__IPU_DIAG_BUS_10 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA11, 0x654, 0x2D0, 0, 0x000, 0), /* MX53_PAD_PATA_DATA11__PATA_DATA_11 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA11, 0x654, 0x2D0, 1, 0x000, 0), /* MX53_PAD_PATA_DATA11__GPIO2_11 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA11, 0x654, 0x2D0, 2, 0x000, 0), /* MX53_PAD_PATA_DATA11__ESDHC1_DAT7 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA11, 0x654, 0x2D0, 3, 0x000, 0), /* MX53_PAD_PATA_DATA11__EMI_NANDF_D_11 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA11, 0x654, 0x2D0, 4, 0x000, 0), /* MX53_PAD_PATA_DATA11__ESDHC3_DAT3 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA11, 0x654, 0x2D0, 5, 0x000, 0), /* MX53_PAD_PATA_DATA11__GPU3d_GPU_DEBUG_OUT_11 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA11, 0x654, 0x2D0, 6, 0x000, 0), /* MX53_PAD_PATA_DATA11__IPU_DIAG_BUS_11 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA12, 0x658, 0x2D4, 0, 0x000, 0), /* MX53_PAD_PATA_DATA12__PATA_DATA_12 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA12, 0x658, 0x2D4, 1, 0x000, 0), /* MX53_PAD_PATA_DATA12__GPIO2_12 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA12, 0x658, 0x2D4, 2, 0x000, 0), /* MX53_PAD_PATA_DATA12__ESDHC2_DAT4 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA12, 0x658, 0x2D4, 3, 0x000, 0), /* MX53_PAD_PATA_DATA12__EMI_NANDF_D_12 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA12, 0x658, 0x2D4, 4, 0x000, 0), /* MX53_PAD_PATA_DATA12__ESDHC4_DAT0 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA12, 0x658, 0x2D4, 5, 0x000, 0), /* MX53_PAD_PATA_DATA12__GPU3d_GPU_DEBUG_OUT_12 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA12, 0x658, 0x2D4, 6, 0x000, 0), /* MX53_PAD_PATA_DATA12__IPU_DIAG_BUS_12 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA13, 0x65C, 0x2D8, 0, 0x000, 0), /* MX53_PAD_PATA_DATA13__PATA_DATA_13 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA13, 0x65C, 0x2D8, 1, 0x000, 0), /* MX53_PAD_PATA_DATA13__GPIO2_13 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA13, 0x65C, 0x2D8, 2, 0x000, 0), /* MX53_PAD_PATA_DATA13__ESDHC2_DAT5 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA13, 0x65C, 0x2D8, 3, 0x000, 0), /* MX53_PAD_PATA_DATA13__EMI_NANDF_D_13 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA13, 0x65C, 0x2D8, 4, 0x000, 0), /* MX53_PAD_PATA_DATA13__ESDHC4_DAT1 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA13, 0x65C, 0x2D8, 5, 0x000, 0), /* MX53_PAD_PATA_DATA13__GPU3d_GPU_DEBUG_OUT_13 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA13, 0x65C, 0x2D8, 6, 0x000, 0), /* MX53_PAD_PATA_DATA13__IPU_DIAG_BUS_13 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA14, 0x660, 0x2DC, 0, 0x000, 0), /* MX53_PAD_PATA_DATA14__PATA_DATA_14 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA14, 0x660, 0x2DC, 1, 0x000, 0), /* MX53_PAD_PATA_DATA14__GPIO2_14 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA14, 0x660, 0x2DC, 2, 0x000, 0), /* MX53_PAD_PATA_DATA14__ESDHC2_DAT6 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA14, 0x660, 0x2DC, 3, 0x000, 0), /* MX53_PAD_PATA_DATA14__EMI_NANDF_D_14 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA14, 0x660, 0x2DC, 4, 0x000, 0), /* MX53_PAD_PATA_DATA14__ESDHC4_DAT2 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA14, 0x660, 0x2DC, 5, 0x000, 0), /* MX53_PAD_PATA_DATA14__GPU3d_GPU_DEBUG_OUT_14 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA14, 0x660, 0x2DC, 6, 0x000, 0), /* MX53_PAD_PATA_DATA14__IPU_DIAG_BUS_14 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA15, 0x664, 0x2E0, 0, 0x000, 0), /* MX53_PAD_PATA_DATA15__PATA_DATA_15 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA15, 0x664, 0x2E0, 1, 0x000, 0), /* MX53_PAD_PATA_DATA15__GPIO2_15 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA15, 0x664, 0x2E0, 2, 0x000, 0), /* MX53_PAD_PATA_DATA15__ESDHC2_DAT7 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA15, 0x664, 0x2E0, 3, 0x000, 0), /* MX53_PAD_PATA_DATA15__EMI_NANDF_D_15 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA15, 0x664, 0x2E0, 4, 0x000, 0), /* MX53_PAD_PATA_DATA15__ESDHC4_DAT3 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA15, 0x664, 0x2E0, 5, 0x000, 0), /* MX53_PAD_PATA_DATA15__GPU3d_GPU_DEBUG_OUT_15 */ - IMX_PIN_REG(MX53_PAD_PATA_DATA15, 0x664, 0x2E0, 6, 0x000, 0), /* MX53_PAD_PATA_DATA15__IPU_DIAG_BUS_15 */ - IMX_PIN_REG(MX53_PAD_SD1_DATA0, 0x66C, 0x2E4, 0, 0x000, 0), /* MX53_PAD_SD1_DATA0__ESDHC1_DAT0 */ - IMX_PIN_REG(MX53_PAD_SD1_DATA0, 0x66C, 0x2E4, 1, 0x000, 0), /* MX53_PAD_SD1_DATA0__GPIO1_16 */ - IMX_PIN_REG(MX53_PAD_SD1_DATA0, 0x66C, 0x2E4, 3, 0x000, 0), /* MX53_PAD_SD1_DATA0__GPT_CAPIN1 */ - IMX_PIN_REG(MX53_PAD_SD1_DATA0, 0x66C, 0x2E4, 5, 0x784, 2), /* MX53_PAD_SD1_DATA0__CSPI_MISO */ - IMX_PIN_REG(MX53_PAD_SD1_DATA0, 0x66C, 0x2E4, 7, 0x778, 0), /* MX53_PAD_SD1_DATA0__CCM_PLL3_BYP */ - IMX_PIN_REG(MX53_PAD_SD1_DATA1, 0x670, 0x2E8, 0, 0x000, 0), /* MX53_PAD_SD1_DATA1__ESDHC1_DAT1 */ - IMX_PIN_REG(MX53_PAD_SD1_DATA1, 0x670, 0x2E8, 1, 0x000, 0), /* MX53_PAD_SD1_DATA1__GPIO1_17 */ - IMX_PIN_REG(MX53_PAD_SD1_DATA1, 0x670, 0x2E8, 3, 0x000, 0), /* MX53_PAD_SD1_DATA1__GPT_CAPIN2 */ - IMX_PIN_REG(MX53_PAD_SD1_DATA1, 0x670, 0x2E8, 5, 0x78C, 3), /* MX53_PAD_SD1_DATA1__CSPI_SS0 */ - IMX_PIN_REG(MX53_PAD_SD1_DATA1, 0x670, 0x2E8, 7, 0x77C, 1), /* MX53_PAD_SD1_DATA1__CCM_PLL4_BYP */ - IMX_PIN_REG(MX53_PAD_SD1_CMD, 0x674, 0x2EC, 0, 0x000, 0), /* MX53_PAD_SD1_CMD__ESDHC1_CMD */ - IMX_PIN_REG(MX53_PAD_SD1_CMD, 0x674, 0x2EC, 1, 0x000, 0), /* MX53_PAD_SD1_CMD__GPIO1_18 */ - IMX_PIN_REG(MX53_PAD_SD1_CMD, 0x674, 0x2EC, 3, 0x000, 0), /* MX53_PAD_SD1_CMD__GPT_CMPOUT1 */ - IMX_PIN_REG(MX53_PAD_SD1_CMD, 0x674, 0x2EC, 5, 0x788, 2), /* MX53_PAD_SD1_CMD__CSPI_MOSI */ - IMX_PIN_REG(MX53_PAD_SD1_CMD, 0x674, 0x2EC, 7, 0x770, 0), /* MX53_PAD_SD1_CMD__CCM_PLL1_BYP */ - IMX_PIN_REG(MX53_PAD_SD1_DATA2, 0x678, 0x2F0, 0, 0x000, 0), /* MX53_PAD_SD1_DATA2__ESDHC1_DAT2 */ - IMX_PIN_REG(MX53_PAD_SD1_DATA2, 0x678, 0x2F0, 1, 0x000, 0), /* MX53_PAD_SD1_DATA2__GPIO1_19 */ - IMX_PIN_REG(MX53_PAD_SD1_DATA2, 0x678, 0x2F0, 2, 0x000, 0), /* MX53_PAD_SD1_DATA2__GPT_CMPOUT2 */ - IMX_PIN_REG(MX53_PAD_SD1_DATA2, 0x678, 0x2F0, 3, 0x000, 0), /* MX53_PAD_SD1_DATA2__PWM2_PWMO */ - IMX_PIN_REG(MX53_PAD_SD1_DATA2, 0x678, 0x2F0, 4, 0x000, 0), /* MX53_PAD_SD1_DATA2__WDOG1_WDOG_B */ - IMX_PIN_REG(MX53_PAD_SD1_DATA2, 0x678, 0x2F0, 5, 0x790, 2), /* MX53_PAD_SD1_DATA2__CSPI_SS1 */ - IMX_PIN_REG(MX53_PAD_SD1_DATA2, 0x678, 0x2F0, 6, 0x000, 0), /* MX53_PAD_SD1_DATA2__WDOG1_WDOG_RST_B_DEB */ - IMX_PIN_REG(MX53_PAD_SD1_DATA2, 0x678, 0x2F0, 7, 0x774, 0), /* MX53_PAD_SD1_DATA2__CCM_PLL2_BYP */ - IMX_PIN_REG(MX53_PAD_SD1_CLK, 0x67C, 0x2F4, 0, 0x000, 0), /* MX53_PAD_SD1_CLK__ESDHC1_CLK */ - IMX_PIN_REG(MX53_PAD_SD1_CLK, 0x67C, 0x2F4, 1, 0x000, 0), /* MX53_PAD_SD1_CLK__GPIO1_20 */ - IMX_PIN_REG(MX53_PAD_SD1_CLK, 0x67C, 0x2F4, 2, 0x000, 0), /* MX53_PAD_SD1_CLK__OSC32k_32K_OUT */ - IMX_PIN_REG(MX53_PAD_SD1_CLK, 0x67C, 0x2F4, 3, 0x000, 0), /* MX53_PAD_SD1_CLK__GPT_CLKIN */ - IMX_PIN_REG(MX53_PAD_SD1_CLK, 0x67C, 0x2F4, 5, 0x780, 2), /* MX53_PAD_SD1_CLK__CSPI_SCLK */ - IMX_PIN_REG(MX53_PAD_SD1_CLK, 0x67C, 0x2F4, 7, 0x000, 0), /* MX53_PAD_SD1_CLK__SATA_PHY_DTB_0 */ - IMX_PIN_REG(MX53_PAD_SD1_DATA3, 0x680, 0x2F8, 0, 0x000, 0), /* MX53_PAD_SD1_DATA3__ESDHC1_DAT3 */ - IMX_PIN_REG(MX53_PAD_SD1_DATA3, 0x680, 0x2F8, 1, 0x000, 0), /* MX53_PAD_SD1_DATA3__GPIO1_21 */ - IMX_PIN_REG(MX53_PAD_SD1_DATA3, 0x680, 0x2F8, 2, 0x000, 0), /* MX53_PAD_SD1_DATA3__GPT_CMPOUT3 */ - IMX_PIN_REG(MX53_PAD_SD1_DATA3, 0x680, 0x2F8, 3, 0x000, 0), /* MX53_PAD_SD1_DATA3__PWM1_PWMO */ - IMX_PIN_REG(MX53_PAD_SD1_DATA3, 0x680, 0x2F8, 4, 0x000, 0), /* MX53_PAD_SD1_DATA3__WDOG2_WDOG_B */ - IMX_PIN_REG(MX53_PAD_SD1_DATA3, 0x680, 0x2F8, 5, 0x794, 2), /* MX53_PAD_SD1_DATA3__CSPI_SS2 */ - IMX_PIN_REG(MX53_PAD_SD1_DATA3, 0x680, 0x2F8, 6, 0x000, 0), /* MX53_PAD_SD1_DATA3__WDOG2_WDOG_RST_B_DEB */ - IMX_PIN_REG(MX53_PAD_SD1_DATA3, 0x680, 0x2F8, 7, 0x000, 0), /* MX53_PAD_SD1_DATA3__SATA_PHY_DTB_1 */ - IMX_PIN_REG(MX53_PAD_SD2_CLK, 0x688, 0x2FC, 0, 0x000, 0), /* MX53_PAD_SD2_CLK__ESDHC2_CLK */ - IMX_PIN_REG(MX53_PAD_SD2_CLK, 0x688, 0x2FC, 1, 0x000, 0), /* MX53_PAD_SD2_CLK__GPIO1_10 */ - IMX_PIN_REG(MX53_PAD_SD2_CLK, 0x688, 0x2FC, 2, 0x840, 2), /* MX53_PAD_SD2_CLK__KPP_COL_5 */ - IMX_PIN_REG(MX53_PAD_SD2_CLK, 0x688, 0x2FC, 3, 0x73C, 1), /* MX53_PAD_SD2_CLK__AUDMUX_AUD4_RXFS */ - IMX_PIN_REG(MX53_PAD_SD2_CLK, 0x688, 0x2FC, 5, 0x780, 3), /* MX53_PAD_SD2_CLK__CSPI_SCLK */ - IMX_PIN_REG(MX53_PAD_SD2_CLK, 0x688, 0x2FC, 7, 0x000, 0), /* MX53_PAD_SD2_CLK__SCC_RANDOM_V */ - IMX_PIN_REG(MX53_PAD_SD2_CMD, 0x68C, 0x300, 0, 0x000, 0), /* MX53_PAD_SD2_CMD__ESDHC2_CMD */ - IMX_PIN_REG(MX53_PAD_SD2_CMD, 0x68C, 0x300, 1, 0x000, 0), /* MX53_PAD_SD2_CMD__GPIO1_11 */ - IMX_PIN_REG(MX53_PAD_SD2_CMD, 0x68C, 0x300, 2, 0x84C, 1), /* MX53_PAD_SD2_CMD__KPP_ROW_5 */ - IMX_PIN_REG(MX53_PAD_SD2_CMD, 0x68C, 0x300, 3, 0x738, 1), /* MX53_PAD_SD2_CMD__AUDMUX_AUD4_RXC */ - IMX_PIN_REG(MX53_PAD_SD2_CMD, 0x68C, 0x300, 5, 0x788, 3), /* MX53_PAD_SD2_CMD__CSPI_MOSI */ - IMX_PIN_REG(MX53_PAD_SD2_CMD, 0x68C, 0x300, 7, 0x000, 0), /* MX53_PAD_SD2_CMD__SCC_RANDOM */ - IMX_PIN_REG(MX53_PAD_SD2_DATA3, 0x690, 0x304, 0, 0x000, 0), /* MX53_PAD_SD2_DATA3__ESDHC2_DAT3 */ - IMX_PIN_REG(MX53_PAD_SD2_DATA3, 0x690, 0x304, 1, 0x000, 0), /* MX53_PAD_SD2_DATA3__GPIO1_12 */ - IMX_PIN_REG(MX53_PAD_SD2_DATA3, 0x690, 0x304, 2, 0x844, 1), /* MX53_PAD_SD2_DATA3__KPP_COL_6 */ - IMX_PIN_REG(MX53_PAD_SD2_DATA3, 0x690, 0x304, 3, 0x740, 1), /* MX53_PAD_SD2_DATA3__AUDMUX_AUD4_TXC */ - IMX_PIN_REG(MX53_PAD_SD2_DATA3, 0x690, 0x304, 5, 0x794, 3), /* MX53_PAD_SD2_DATA3__CSPI_SS2 */ - IMX_PIN_REG(MX53_PAD_SD2_DATA3, 0x690, 0x304, 7, 0x000, 0), /* MX53_PAD_SD2_DATA3__SJC_DONE */ - IMX_PIN_REG(MX53_PAD_SD2_DATA2, 0x694, 0x308, 0, 0x000, 0), /* MX53_PAD_SD2_DATA2__ESDHC2_DAT2 */ - IMX_PIN_REG(MX53_PAD_SD2_DATA2, 0x694, 0x308, 1, 0x000, 0), /* MX53_PAD_SD2_DATA2__GPIO1_13 */ - IMX_PIN_REG(MX53_PAD_SD2_DATA2, 0x694, 0x308, 2, 0x850, 1), /* MX53_PAD_SD2_DATA2__KPP_ROW_6 */ - IMX_PIN_REG(MX53_PAD_SD2_DATA2, 0x694, 0x308, 3, 0x734, 1), /* MX53_PAD_SD2_DATA2__AUDMUX_AUD4_TXD */ - IMX_PIN_REG(MX53_PAD_SD2_DATA2, 0x694, 0x308, 5, 0x790, 3), /* MX53_PAD_SD2_DATA2__CSPI_SS1 */ - IMX_PIN_REG(MX53_PAD_SD2_DATA2, 0x694, 0x308, 7, 0x000, 0), /* MX53_PAD_SD2_DATA2__SJC_FAIL */ - IMX_PIN_REG(MX53_PAD_SD2_DATA1, 0x698, 0x30C, 0, 0x000, 0), /* MX53_PAD_SD2_DATA1__ESDHC2_DAT1 */ - IMX_PIN_REG(MX53_PAD_SD2_DATA1, 0x698, 0x30C, 1, 0x000, 0), /* MX53_PAD_SD2_DATA1__GPIO1_14 */ - IMX_PIN_REG(MX53_PAD_SD2_DATA1, 0x698, 0x30C, 2, 0x848, 1), /* MX53_PAD_SD2_DATA1__KPP_COL_7 */ - IMX_PIN_REG(MX53_PAD_SD2_DATA1, 0x698, 0x30C, 3, 0x744, 0), /* MX53_PAD_SD2_DATA1__AUDMUX_AUD4_TXFS */ - IMX_PIN_REG(MX53_PAD_SD2_DATA1, 0x698, 0x30C, 5, 0x78C, 4), /* MX53_PAD_SD2_DATA1__CSPI_SS0 */ - IMX_PIN_REG(MX53_PAD_SD2_DATA1, 0x698, 0x30C, 7, 0x000, 0), /* MX53_PAD_SD2_DATA1__RTIC_SEC_VIO */ - IMX_PIN_REG(MX53_PAD_SD2_DATA0, 0x69C, 0x310, 0, 0x000, 0), /* MX53_PAD_SD2_DATA0__ESDHC2_DAT0 */ - IMX_PIN_REG(MX53_PAD_SD2_DATA0, 0x69C, 0x310, 1, 0x000, 0), /* MX53_PAD_SD2_DATA0__GPIO1_15 */ - IMX_PIN_REG(MX53_PAD_SD2_DATA0, 0x69C, 0x310, 2, 0x854, 1), /* MX53_PAD_SD2_DATA0__KPP_ROW_7 */ - IMX_PIN_REG(MX53_PAD_SD2_DATA0, 0x69C, 0x310, 3, 0x730, 1), /* MX53_PAD_SD2_DATA0__AUDMUX_AUD4_RXD */ - IMX_PIN_REG(MX53_PAD_SD2_DATA0, 0x69C, 0x310, 5, 0x784, 3), /* MX53_PAD_SD2_DATA0__CSPI_MISO */ - IMX_PIN_REG(MX53_PAD_SD2_DATA0, 0x69C, 0x310, 7, 0x000, 0), /* MX53_PAD_SD2_DATA0__RTIC_DONE_INT */ - IMX_PIN_REG(MX53_PAD_GPIO_0, 0x6A4, 0x314, 0, 0x000, 0), /* MX53_PAD_GPIO_0__CCM_CLKO */ - IMX_PIN_REG(MX53_PAD_GPIO_0, 0x6A4, 0x314, 1, 0x000, 0), /* MX53_PAD_GPIO_0__GPIO1_0 */ - IMX_PIN_REG(MX53_PAD_GPIO_0, 0x6A4, 0x314, 2, 0x840, 3), /* MX53_PAD_GPIO_0__KPP_COL_5 */ - IMX_PIN_REG(MX53_PAD_GPIO_0, 0x6A4, 0x314, 3, 0x000, 0), /* MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK */ - IMX_PIN_REG(MX53_PAD_GPIO_0, 0x6A4, 0x314, 4, 0x000, 0), /* MX53_PAD_GPIO_0__EPIT1_EPITO */ - IMX_PIN_REG(MX53_PAD_GPIO_0, 0x6A4, 0x314, 5, 0x000, 0), /* MX53_PAD_GPIO_0__SRTC_ALARM_DEB */ - IMX_PIN_REG(MX53_PAD_GPIO_0, 0x6A4, 0x314, 6, 0x000, 0), /* MX53_PAD_GPIO_0__USBOH3_USBH1_PWR */ - IMX_PIN_REG(MX53_PAD_GPIO_0, 0x6A4, 0x314, 7, 0x000, 0), /* MX53_PAD_GPIO_0__CSU_TD */ - IMX_PIN_REG(MX53_PAD_GPIO_1, 0x6A8, 0x318, 0, 0x7DC, 1), /* MX53_PAD_GPIO_1__ESAI1_SCKR */ - IMX_PIN_REG(MX53_PAD_GPIO_1, 0x6A8, 0x318, 1, 0x000, 0), /* MX53_PAD_GPIO_1__GPIO1_1 */ - IMX_PIN_REG(MX53_PAD_GPIO_1, 0x6A8, 0x318, 2, 0x84C, 2), /* MX53_PAD_GPIO_1__KPP_ROW_5 */ - IMX_PIN_REG(MX53_PAD_GPIO_1, 0x6A8, 0x318, 3, 0x000, 0), /* MX53_PAD_GPIO_1__CCM_SSI_EXT2_CLK */ - IMX_PIN_REG(MX53_PAD_GPIO_1, 0x6A8, 0x318, 4, 0x000, 0), /* MX53_PAD_GPIO_1__PWM2_PWMO */ - IMX_PIN_REG(MX53_PAD_GPIO_1, 0x6A8, 0x318, 5, 0x000, 0), /* MX53_PAD_GPIO_1__WDOG2_WDOG_B */ - IMX_PIN_REG(MX53_PAD_GPIO_1, 0x6A8, 0x318, 6, 0x000, 0), /* MX53_PAD_GPIO_1__ESDHC1_CD */ - IMX_PIN_REG(MX53_PAD_GPIO_1, 0x6A8, 0x318, 7, 0x000, 0), /* MX53_PAD_GPIO_1__SRC_TESTER_ACK */ - IMX_PIN_REG(MX53_PAD_GPIO_9, 0x6AC, 0x31C, 0, 0x7CC, 1), /* MX53_PAD_GPIO_9__ESAI1_FSR */ - IMX_PIN_REG(MX53_PAD_GPIO_9, 0x6AC, 0x31C, 1, 0x000, 0), /* MX53_PAD_GPIO_9__GPIO1_9 */ - IMX_PIN_REG(MX53_PAD_GPIO_9, 0x6AC, 0x31C, 2, 0x844, 2), /* MX53_PAD_GPIO_9__KPP_COL_6 */ - IMX_PIN_REG(MX53_PAD_GPIO_9, 0x6AC, 0x31C, 3, 0x000, 0), /* MX53_PAD_GPIO_9__CCM_REF_EN_B */ - IMX_PIN_REG(MX53_PAD_GPIO_9, 0x6AC, 0x31C, 4, 0x000, 0), /* MX53_PAD_GPIO_9__PWM1_PWMO */ - IMX_PIN_REG(MX53_PAD_GPIO_9, 0x6AC, 0x31C, 5, 0x000, 0), /* MX53_PAD_GPIO_9__WDOG1_WDOG_B */ - IMX_PIN_REG(MX53_PAD_GPIO_9, 0x6AC, 0x31C, 6, 0x7FC, 1), /* MX53_PAD_GPIO_9__ESDHC1_WP */ - IMX_PIN_REG(MX53_PAD_GPIO_9, 0x6AC, 0x31C, 7, 0x000, 0), /* MX53_PAD_GPIO_9__SCC_FAIL_STATE */ - IMX_PIN_REG(MX53_PAD_GPIO_3, 0x6B0, 0x320, 0, 0x7D4, 1), /* MX53_PAD_GPIO_3__ESAI1_HCKR */ - IMX_PIN_REG(MX53_PAD_GPIO_3, 0x6B0, 0x320, 1, 0x000, 0), /* MX53_PAD_GPIO_3__GPIO1_3 */ - IMX_PIN_REG(MX53_PAD_GPIO_3, 0x6B0, 0x320, 2, 0x824, 1), /* MX53_PAD_GPIO_3__I2C3_SCL */ - IMX_PIN_REG(MX53_PAD_GPIO_3, 0x6B0, 0x320, 3, 0x000, 0), /* MX53_PAD_GPIO_3__DPLLIP1_TOG_EN */ - IMX_PIN_REG(MX53_PAD_GPIO_3, 0x6B0, 0x320, 4, 0x000, 0), /* MX53_PAD_GPIO_3__CCM_CLKO2 */ - IMX_PIN_REG(MX53_PAD_GPIO_3, 0x6B0, 0x320, 5, 0x000, 0), /* MX53_PAD_GPIO_3__OBSERVE_MUX_OBSRV_INT_OUT0 */ - IMX_PIN_REG(MX53_PAD_GPIO_3, 0x6B0, 0x320, 6, 0x8A0, 1), /* MX53_PAD_GPIO_3__USBOH3_USBH1_OC */ - IMX_PIN_REG(MX53_PAD_GPIO_3, 0x6B0, 0x320, 7, 0x858, 2), /* MX53_PAD_GPIO_3__MLB_MLBCLK */ - IMX_PIN_REG(MX53_PAD_GPIO_6, 0x6B4, 0x324, 0, 0x7E0, 1), /* MX53_PAD_GPIO_6__ESAI1_SCKT */ - IMX_PIN_REG(MX53_PAD_GPIO_6, 0x6B4, 0x324, 1, 0x000, 0), /* MX53_PAD_GPIO_6__GPIO1_6 */ - IMX_PIN_REG(MX53_PAD_GPIO_6, 0x6B4, 0x324, 2, 0x828, 1), /* MX53_PAD_GPIO_6__I2C3_SDA */ - IMX_PIN_REG(MX53_PAD_GPIO_6, 0x6B4, 0x324, 3, 0x000, 0), /* MX53_PAD_GPIO_6__CCM_CCM_OUT_0 */ - IMX_PIN_REG(MX53_PAD_GPIO_6, 0x6B4, 0x324, 4, 0x000, 0), /* MX53_PAD_GPIO_6__CSU_CSU_INT_DEB */ - IMX_PIN_REG(MX53_PAD_GPIO_6, 0x6B4, 0x324, 5, 0x000, 0), /* MX53_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 */ - IMX_PIN_REG(MX53_PAD_GPIO_6, 0x6B4, 0x324, 6, 0x000, 0), /* MX53_PAD_GPIO_6__ESDHC2_LCTL */ - IMX_PIN_REG(MX53_PAD_GPIO_6, 0x6B4, 0x324, 7, 0x860, 2), /* MX53_PAD_GPIO_6__MLB_MLBSIG */ - IMX_PIN_REG(MX53_PAD_GPIO_2, 0x6B8, 0x328, 0, 0x7D0, 1), /* MX53_PAD_GPIO_2__ESAI1_FST */ - IMX_PIN_REG(MX53_PAD_GPIO_2, 0x6B8, 0x328, 1, 0x000, 0), /* MX53_PAD_GPIO_2__GPIO1_2 */ - IMX_PIN_REG(MX53_PAD_GPIO_2, 0x6B8, 0x328, 2, 0x850, 2), /* MX53_PAD_GPIO_2__KPP_ROW_6 */ - IMX_PIN_REG(MX53_PAD_GPIO_2, 0x6B8, 0x328, 3, 0x000, 0), /* MX53_PAD_GPIO_2__CCM_CCM_OUT_1 */ - IMX_PIN_REG(MX53_PAD_GPIO_2, 0x6B8, 0x328, 4, 0x000, 0), /* MX53_PAD_GPIO_2__CSU_CSU_ALARM_AUT_0 */ - IMX_PIN_REG(MX53_PAD_GPIO_2, 0x6B8, 0x328, 5, 0x000, 0), /* MX53_PAD_GPIO_2__OBSERVE_MUX_OBSRV_INT_OUT2 */ - IMX_PIN_REG(MX53_PAD_GPIO_2, 0x6B8, 0x328, 6, 0x000, 0), /* MX53_PAD_GPIO_2__ESDHC2_WP */ - IMX_PIN_REG(MX53_PAD_GPIO_2, 0x6B8, 0x328, 7, 0x85C, 2), /* MX53_PAD_GPIO_2__MLB_MLBDAT */ - IMX_PIN_REG(MX53_PAD_GPIO_4, 0x6BC, 0x32C, 0, 0x7D8, 1), /* MX53_PAD_GPIO_4__ESAI1_HCKT */ - IMX_PIN_REG(MX53_PAD_GPIO_4, 0x6BC, 0x32C, 1, 0x000, 0), /* MX53_PAD_GPIO_4__GPIO1_4 */ - IMX_PIN_REG(MX53_PAD_GPIO_4, 0x6BC, 0x32C, 2, 0x848, 2), /* MX53_PAD_GPIO_4__KPP_COL_7 */ - IMX_PIN_REG(MX53_PAD_GPIO_4, 0x6BC, 0x32C, 3, 0x000, 0), /* MX53_PAD_GPIO_4__CCM_CCM_OUT_2 */ - IMX_PIN_REG(MX53_PAD_GPIO_4, 0x6BC, 0x32C, 4, 0x000, 0), /* MX53_PAD_GPIO_4__CSU_CSU_ALARM_AUT_1 */ - IMX_PIN_REG(MX53_PAD_GPIO_4, 0x6BC, 0x32C, 5, 0x000, 0), /* MX53_PAD_GPIO_4__OBSERVE_MUX_OBSRV_INT_OUT3 */ - IMX_PIN_REG(MX53_PAD_GPIO_4, 0x6BC, 0x32C, 6, 0x000, 0), /* MX53_PAD_GPIO_4__ESDHC2_CD */ - IMX_PIN_REG(MX53_PAD_GPIO_4, 0x6BC, 0x32C, 7, 0x000, 0), /* MX53_PAD_GPIO_4__SCC_SEC_STATE */ - IMX_PIN_REG(MX53_PAD_GPIO_5, 0x6C0, 0x330, 0, 0x7EC, 1), /* MX53_PAD_GPIO_5__ESAI1_TX2_RX3 */ - IMX_PIN_REG(MX53_PAD_GPIO_5, 0x6C0, 0x330, 1, 0x000, 0), /* MX53_PAD_GPIO_5__GPIO1_5 */ - IMX_PIN_REG(MX53_PAD_GPIO_5, 0x6C0, 0x330, 2, 0x854, 2), /* MX53_PAD_GPIO_5__KPP_ROW_7 */ - IMX_PIN_REG(MX53_PAD_GPIO_5, 0x6C0, 0x330, 3, 0x000, 0), /* MX53_PAD_GPIO_5__CCM_CLKO */ - IMX_PIN_REG(MX53_PAD_GPIO_5, 0x6C0, 0x330, 4, 0x000, 0), /* MX53_PAD_GPIO_5__CSU_CSU_ALARM_AUT_2 */ - IMX_PIN_REG(MX53_PAD_GPIO_5, 0x6C0, 0x330, 5, 0x000, 0), /* MX53_PAD_GPIO_5__OBSERVE_MUX_OBSRV_INT_OUT4 */ - IMX_PIN_REG(MX53_PAD_GPIO_5, 0x6C0, 0x330, 6, 0x824, 2), /* MX53_PAD_GPIO_5__I2C3_SCL */ - IMX_PIN_REG(MX53_PAD_GPIO_5, 0x6C0, 0x330, 7, 0x770, 1), /* MX53_PAD_GPIO_5__CCM_PLL1_BYP */ - IMX_PIN_REG(MX53_PAD_GPIO_7, 0x6C4, 0x334, 0, 0x7F4, 1), /* MX53_PAD_GPIO_7__ESAI1_TX4_RX1 */ - IMX_PIN_REG(MX53_PAD_GPIO_7, 0x6C4, 0x334, 1, 0x000, 0), /* MX53_PAD_GPIO_7__GPIO1_7 */ - IMX_PIN_REG(MX53_PAD_GPIO_7, 0x6C4, 0x334, 2, 0x000, 0), /* MX53_PAD_GPIO_7__EPIT1_EPITO */ - IMX_PIN_REG(MX53_PAD_GPIO_7, 0x6C4, 0x334, 3, 0x000, 0), /* MX53_PAD_GPIO_7__CAN1_TXCAN */ - IMX_PIN_REG(MX53_PAD_GPIO_7, 0x6C4, 0x334, 4, 0x000, 0), /* MX53_PAD_GPIO_7__UART2_TXD_MUX */ - IMX_PIN_REG(MX53_PAD_GPIO_7, 0x6C4, 0x334, 5, 0x80C, 1), /* MX53_PAD_GPIO_7__FIRI_RXD */ - IMX_PIN_REG(MX53_PAD_GPIO_7, 0x6C4, 0x334, 6, 0x000, 0), /* MX53_PAD_GPIO_7__SPDIF_PLOCK */ - IMX_PIN_REG(MX53_PAD_GPIO_7, 0x6C4, 0x334, 7, 0x774, 1), /* MX53_PAD_GPIO_7__CCM_PLL2_BYP */ - IMX_PIN_REG(MX53_PAD_GPIO_8, 0x6C8, 0x338, 0, 0x7F8, 1), /* MX53_PAD_GPIO_8__ESAI1_TX5_RX0 */ - IMX_PIN_REG(MX53_PAD_GPIO_8, 0x6C8, 0x338, 1, 0x000, 0), /* MX53_PAD_GPIO_8__GPIO1_8 */ - IMX_PIN_REG(MX53_PAD_GPIO_8, 0x6C8, 0x338, 2, 0x000, 0), /* MX53_PAD_GPIO_8__EPIT2_EPITO */ - IMX_PIN_REG(MX53_PAD_GPIO_8, 0x6C8, 0x338, 3, 0x760, 3), /* MX53_PAD_GPIO_8__CAN1_RXCAN */ - IMX_PIN_REG(MX53_PAD_GPIO_8, 0x6C8, 0x338, 4, 0x880, 5), /* MX53_PAD_GPIO_8__UART2_RXD_MUX */ - IMX_PIN_REG(MX53_PAD_GPIO_8, 0x6C8, 0x338, 5, 0x000, 0), /* MX53_PAD_GPIO_8__FIRI_TXD */ - IMX_PIN_REG(MX53_PAD_GPIO_8, 0x6C8, 0x338, 6, 0x000, 0), /* MX53_PAD_GPIO_8__SPDIF_SRCLK */ - IMX_PIN_REG(MX53_PAD_GPIO_8, 0x6C8, 0x338, 7, 0x778, 1), /* MX53_PAD_GPIO_8__CCM_PLL3_BYP */ - IMX_PIN_REG(MX53_PAD_GPIO_16, 0x6CC, 0x33C, 0, 0x7F0, 1), /* MX53_PAD_GPIO_16__ESAI1_TX3_RX2 */ - IMX_PIN_REG(MX53_PAD_GPIO_16, 0x6CC, 0x33C, 1, 0x000, 0), /* MX53_PAD_GPIO_16__GPIO7_11 */ - IMX_PIN_REG(MX53_PAD_GPIO_16, 0x6CC, 0x33C, 2, 0x000, 0), /* MX53_PAD_GPIO_16__TZIC_PWRFAIL_INT */ - IMX_PIN_REG(MX53_PAD_GPIO_16, 0x6CC, 0x33C, 4, 0x000, 0), /* MX53_PAD_GPIO_16__RTC_CE_RTC_EXT_TRIG1 */ - IMX_PIN_REG(MX53_PAD_GPIO_16, 0x6CC, 0x33C, 5, 0x870, 1), /* MX53_PAD_GPIO_16__SPDIF_IN1 */ - IMX_PIN_REG(MX53_PAD_GPIO_16, 0x6CC, 0x33C, 6, 0x828, 2), /* MX53_PAD_GPIO_16__I2C3_SDA */ - IMX_PIN_REG(MX53_PAD_GPIO_16, 0x6CC, 0x33C, 7, 0x000, 0), /* MX53_PAD_GPIO_16__SJC_DE_B */ - IMX_PIN_REG(MX53_PAD_GPIO_17, 0x6D0, 0x340, 0, 0x7E4, 1), /* MX53_PAD_GPIO_17__ESAI1_TX0 */ - IMX_PIN_REG(MX53_PAD_GPIO_17, 0x6D0, 0x340, 1, 0x000, 0), /* MX53_PAD_GPIO_17__GPIO7_12 */ - IMX_PIN_REG(MX53_PAD_GPIO_17, 0x6D0, 0x340, 2, 0x868, 1), /* MX53_PAD_GPIO_17__SDMA_EXT_EVENT_0 */ - IMX_PIN_REG(MX53_PAD_GPIO_17, 0x6D0, 0x340, 3, 0x810, 1), /* MX53_PAD_GPIO_17__GPC_PMIC_RDY */ - IMX_PIN_REG(MX53_PAD_GPIO_17, 0x6D0, 0x340, 4, 0x000, 0), /* MX53_PAD_GPIO_17__RTC_CE_RTC_FSV_TRIG */ - IMX_PIN_REG(MX53_PAD_GPIO_17, 0x6D0, 0x340, 5, 0x000, 0), /* MX53_PAD_GPIO_17__SPDIF_OUT1 */ - IMX_PIN_REG(MX53_PAD_GPIO_17, 0x6D0, 0x340, 6, 0x000, 0), /* MX53_PAD_GPIO_17__IPU_SNOOP2 */ - IMX_PIN_REG(MX53_PAD_GPIO_17, 0x6D0, 0x340, 7, 0x000, 0), /* MX53_PAD_GPIO_17__SJC_JTAG_ACT */ - IMX_PIN_REG(MX53_PAD_GPIO_18, 0x6D4, 0x344, 0, 0x7E8, 1), /* MX53_PAD_GPIO_18__ESAI1_TX1 */ - IMX_PIN_REG(MX53_PAD_GPIO_18, 0x6D4, 0x344, 1, 0x000, 0), /* MX53_PAD_GPIO_18__GPIO7_13 */ - IMX_PIN_REG(MX53_PAD_GPIO_18, 0x6D4, 0x344, 2, 0x86C, 1), /* MX53_PAD_GPIO_18__SDMA_EXT_EVENT_1 */ - IMX_PIN_REG(MX53_PAD_GPIO_18, 0x6D4, 0x344, 3, 0x864, 1), /* MX53_PAD_GPIO_18__OWIRE_LINE */ - IMX_PIN_REG(MX53_PAD_GPIO_18, 0x6D4, 0x344, 4, 0x000, 0), /* MX53_PAD_GPIO_18__RTC_CE_RTC_ALARM2_TRIG */ - IMX_PIN_REG(MX53_PAD_GPIO_18, 0x6D4, 0x344, 5, 0x768, 1), /* MX53_PAD_GPIO_18__CCM_ASRC_EXT_CLK */ - IMX_PIN_REG(MX53_PAD_GPIO_18, 0x6D4, 0x344, 6, 0x000, 0), /* MX53_PAD_GPIO_18__ESDHC1_LCTL */ - IMX_PIN_REG(MX53_PAD_GPIO_18, 0x6D4, 0x344, 7, 0x000, 0), /* MX53_PAD_GPIO_18__SRC_SYSTEM_RST */ -}; - -/* Pad names for the pinmux subsystem */ -static const struct pinctrl_pin_desc imx53_pinctrl_pads[] = { - IMX_PINCTRL_PIN(MX53_PAD_GPIO_19), - IMX_PINCTRL_PIN(MX53_PAD_KEY_COL0), - IMX_PINCTRL_PIN(MX53_PAD_KEY_ROW0), - IMX_PINCTRL_PIN(MX53_PAD_KEY_COL1), - IMX_PINCTRL_PIN(MX53_PAD_KEY_ROW1), - IMX_PINCTRL_PIN(MX53_PAD_KEY_COL2), - IMX_PINCTRL_PIN(MX53_PAD_KEY_ROW2), - IMX_PINCTRL_PIN(MX53_PAD_KEY_COL3), - IMX_PINCTRL_PIN(MX53_PAD_KEY_ROW3), - IMX_PINCTRL_PIN(MX53_PAD_KEY_COL4), - IMX_PINCTRL_PIN(MX53_PAD_KEY_ROW4), - IMX_PINCTRL_PIN(MX53_PAD_DI0_DISP_CLK), - IMX_PINCTRL_PIN(MX53_PAD_DI0_PIN15), - IMX_PINCTRL_PIN(MX53_PAD_DI0_PIN2), - IMX_PINCTRL_PIN(MX53_PAD_DI0_PIN3), - IMX_PINCTRL_PIN(MX53_PAD_DI0_PIN4), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT0), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT1), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT2), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT3), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT4), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT5), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT6), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT7), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT8), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT9), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT10), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT11), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT12), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT13), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT14), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT15), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT16), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT17), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT18), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT19), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT20), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT21), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT22), - IMX_PINCTRL_PIN(MX53_PAD_DISP0_DAT23), - IMX_PINCTRL_PIN(MX53_PAD_CSI0_PIXCLK), - IMX_PINCTRL_PIN(MX53_PAD_CSI0_MCLK), - IMX_PINCTRL_PIN(MX53_PAD_CSI0_DATA_EN), - IMX_PINCTRL_PIN(MX53_PAD_CSI0_VSYNC), - IMX_PINCTRL_PIN(MX53_PAD_CSI0_DAT4), - IMX_PINCTRL_PIN(MX53_PAD_CSI0_DAT5), - IMX_PINCTRL_PIN(MX53_PAD_CSI0_DAT6), - IMX_PINCTRL_PIN(MX53_PAD_CSI0_DAT7), - IMX_PINCTRL_PIN(MX53_PAD_CSI0_DAT8), - IMX_PINCTRL_PIN(MX53_PAD_CSI0_DAT9), - IMX_PINCTRL_PIN(MX53_PAD_CSI0_DAT10), - IMX_PINCTRL_PIN(MX53_PAD_CSI0_DAT11), - IMX_PINCTRL_PIN(MX53_PAD_CSI0_DAT12), - IMX_PINCTRL_PIN(MX53_PAD_CSI0_DAT13), - IMX_PINCTRL_PIN(MX53_PAD_CSI0_DAT14), - IMX_PINCTRL_PIN(MX53_PAD_CSI0_DAT15), - IMX_PINCTRL_PIN(MX53_PAD_CSI0_DAT16), - IMX_PINCTRL_PIN(MX53_PAD_CSI0_DAT17), - IMX_PINCTRL_PIN(MX53_PAD_CSI0_DAT18), - IMX_PINCTRL_PIN(MX53_PAD_CSI0_DAT19), - IMX_PINCTRL_PIN(MX53_PAD_EIM_A25), - IMX_PINCTRL_PIN(MX53_PAD_EIM_EB2), - IMX_PINCTRL_PIN(MX53_PAD_EIM_D16), - IMX_PINCTRL_PIN(MX53_PAD_EIM_D17), - IMX_PINCTRL_PIN(MX53_PAD_EIM_D18), - IMX_PINCTRL_PIN(MX53_PAD_EIM_D19), - IMX_PINCTRL_PIN(MX53_PAD_EIM_D20), - IMX_PINCTRL_PIN(MX53_PAD_EIM_D21), - IMX_PINCTRL_PIN(MX53_PAD_EIM_D22), - IMX_PINCTRL_PIN(MX53_PAD_EIM_D23), - IMX_PINCTRL_PIN(MX53_PAD_EIM_EB3), - IMX_PINCTRL_PIN(MX53_PAD_EIM_D24), - IMX_PINCTRL_PIN(MX53_PAD_EIM_D25), - IMX_PINCTRL_PIN(MX53_PAD_EIM_D26), - IMX_PINCTRL_PIN(MX53_PAD_EIM_D27), - IMX_PINCTRL_PIN(MX53_PAD_EIM_D28), - IMX_PINCTRL_PIN(MX53_PAD_EIM_D29), - IMX_PINCTRL_PIN(MX53_PAD_EIM_D30), - IMX_PINCTRL_PIN(MX53_PAD_EIM_D31), - IMX_PINCTRL_PIN(MX53_PAD_EIM_A24), - IMX_PINCTRL_PIN(MX53_PAD_EIM_A23), - IMX_PINCTRL_PIN(MX53_PAD_EIM_A22), - IMX_PINCTRL_PIN(MX53_PAD_EIM_A21), - IMX_PINCTRL_PIN(MX53_PAD_EIM_A20), - IMX_PINCTRL_PIN(MX53_PAD_EIM_A19), - IMX_PINCTRL_PIN(MX53_PAD_EIM_A18), - IMX_PINCTRL_PIN(MX53_PAD_EIM_A17), - IMX_PINCTRL_PIN(MX53_PAD_EIM_A16), - IMX_PINCTRL_PIN(MX53_PAD_EIM_CS0), - IMX_PINCTRL_PIN(MX53_PAD_EIM_CS1), - IMX_PINCTRL_PIN(MX53_PAD_EIM_OE), - IMX_PINCTRL_PIN(MX53_PAD_EIM_RW), - IMX_PINCTRL_PIN(MX53_PAD_EIM_LBA), - IMX_PINCTRL_PIN(MX53_PAD_EIM_EB0), - IMX_PINCTRL_PIN(MX53_PAD_EIM_EB1), - IMX_PINCTRL_PIN(MX53_PAD_EIM_DA0), - IMX_PINCTRL_PIN(MX53_PAD_EIM_DA1), - IMX_PINCTRL_PIN(MX53_PAD_EIM_DA2), - IMX_PINCTRL_PIN(MX53_PAD_EIM_DA3), - IMX_PINCTRL_PIN(MX53_PAD_EIM_DA4), - IMX_PINCTRL_PIN(MX53_PAD_EIM_DA5), - IMX_PINCTRL_PIN(MX53_PAD_EIM_DA6), - IMX_PINCTRL_PIN(MX53_PAD_EIM_DA7), - IMX_PINCTRL_PIN(MX53_PAD_EIM_DA8), - IMX_PINCTRL_PIN(MX53_PAD_EIM_DA9), - IMX_PINCTRL_PIN(MX53_PAD_EIM_DA10), - IMX_PINCTRL_PIN(MX53_PAD_EIM_DA11), - IMX_PINCTRL_PIN(MX53_PAD_EIM_DA12), - IMX_PINCTRL_PIN(MX53_PAD_EIM_DA13), - IMX_PINCTRL_PIN(MX53_PAD_EIM_DA14), - IMX_PINCTRL_PIN(MX53_PAD_EIM_DA15), - IMX_PINCTRL_PIN(MX53_PAD_NANDF_WE_B), - IMX_PINCTRL_PIN(MX53_PAD_NANDF_RE_B), - IMX_PINCTRL_PIN(MX53_PAD_EIM_WAIT), - IMX_PINCTRL_PIN(MX53_PAD_LVDS1_TX3_P), - IMX_PINCTRL_PIN(MX53_PAD_LVDS1_TX2_P), - IMX_PINCTRL_PIN(MX53_PAD_LVDS1_CLK_P), - IMX_PINCTRL_PIN(MX53_PAD_LVDS1_TX1_P), - IMX_PINCTRL_PIN(MX53_PAD_LVDS1_TX0_P), - IMX_PINCTRL_PIN(MX53_PAD_LVDS0_TX3_P), - IMX_PINCTRL_PIN(MX53_PAD_LVDS0_CLK_P), - IMX_PINCTRL_PIN(MX53_PAD_LVDS0_TX2_P), - IMX_PINCTRL_PIN(MX53_PAD_LVDS0_TX1_P), - IMX_PINCTRL_PIN(MX53_PAD_LVDS0_TX0_P), - IMX_PINCTRL_PIN(MX53_PAD_GPIO_10), - IMX_PINCTRL_PIN(MX53_PAD_GPIO_11), - IMX_PINCTRL_PIN(MX53_PAD_GPIO_12), - IMX_PINCTRL_PIN(MX53_PAD_GPIO_13), - IMX_PINCTRL_PIN(MX53_PAD_GPIO_14), - IMX_PINCTRL_PIN(MX53_PAD_NANDF_CLE), - IMX_PINCTRL_PIN(MX53_PAD_NANDF_ALE), - IMX_PINCTRL_PIN(MX53_PAD_NANDF_WP_B), - IMX_PINCTRL_PIN(MX53_PAD_NANDF_RB0), - IMX_PINCTRL_PIN(MX53_PAD_NANDF_CS0), - IMX_PINCTRL_PIN(MX53_PAD_NANDF_CS1), - IMX_PINCTRL_PIN(MX53_PAD_NANDF_CS2), - IMX_PINCTRL_PIN(MX53_PAD_NANDF_CS3), - IMX_PINCTRL_PIN(MX53_PAD_FEC_MDIO), - IMX_PINCTRL_PIN(MX53_PAD_FEC_REF_CLK), - IMX_PINCTRL_PIN(MX53_PAD_FEC_RX_ER), - IMX_PINCTRL_PIN(MX53_PAD_FEC_CRS_DV), - IMX_PINCTRL_PIN(MX53_PAD_FEC_RXD1), - IMX_PINCTRL_PIN(MX53_PAD_FEC_RXD0), - IMX_PINCTRL_PIN(MX53_PAD_FEC_TX_EN), - IMX_PINCTRL_PIN(MX53_PAD_FEC_TXD1), - IMX_PINCTRL_PIN(MX53_PAD_FEC_TXD0), - IMX_PINCTRL_PIN(MX53_PAD_FEC_MDC), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DIOW), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DMACK), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DMARQ), - IMX_PINCTRL_PIN(MX53_PAD_PATA_BUFFER_EN), - IMX_PINCTRL_PIN(MX53_PAD_PATA_INTRQ), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DIOR), - IMX_PINCTRL_PIN(MX53_PAD_PATA_RESET_B), - IMX_PINCTRL_PIN(MX53_PAD_PATA_IORDY), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DA_0), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DA_1), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DA_2), - IMX_PINCTRL_PIN(MX53_PAD_PATA_CS_0), - IMX_PINCTRL_PIN(MX53_PAD_PATA_CS_1), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DATA0), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DATA1), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DATA2), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DATA3), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DATA4), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DATA5), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DATA6), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DATA7), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DATA8), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DATA9), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DATA10), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DATA11), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DATA12), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DATA13), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DATA14), - IMX_PINCTRL_PIN(MX53_PAD_PATA_DATA15), - IMX_PINCTRL_PIN(MX53_PAD_SD1_DATA0), - IMX_PINCTRL_PIN(MX53_PAD_SD1_DATA1), - IMX_PINCTRL_PIN(MX53_PAD_SD1_CMD), - IMX_PINCTRL_PIN(MX53_PAD_SD1_DATA2), - IMX_PINCTRL_PIN(MX53_PAD_SD1_CLK), - IMX_PINCTRL_PIN(MX53_PAD_SD1_DATA3), - IMX_PINCTRL_PIN(MX53_PAD_SD2_CLK), - IMX_PINCTRL_PIN(MX53_PAD_SD2_CMD), - IMX_PINCTRL_PIN(MX53_PAD_SD2_DATA3), - IMX_PINCTRL_PIN(MX53_PAD_SD2_DATA2), - IMX_PINCTRL_PIN(MX53_PAD_SD2_DATA1), - IMX_PINCTRL_PIN(MX53_PAD_SD2_DATA0), - IMX_PINCTRL_PIN(MX53_PAD_GPIO_0), - IMX_PINCTRL_PIN(MX53_PAD_GPIO_1), - IMX_PINCTRL_PIN(MX53_PAD_GPIO_9), - IMX_PINCTRL_PIN(MX53_PAD_GPIO_3), - IMX_PINCTRL_PIN(MX53_PAD_GPIO_6), - IMX_PINCTRL_PIN(MX53_PAD_GPIO_2), - IMX_PINCTRL_PIN(MX53_PAD_GPIO_4), - IMX_PINCTRL_PIN(MX53_PAD_GPIO_5), - IMX_PINCTRL_PIN(MX53_PAD_GPIO_7), - IMX_PINCTRL_PIN(MX53_PAD_GPIO_8), - IMX_PINCTRL_PIN(MX53_PAD_GPIO_16), - IMX_PINCTRL_PIN(MX53_PAD_GPIO_17), - IMX_PINCTRL_PIN(MX53_PAD_GPIO_18), -}; - -static struct imx_pinctrl_soc_info imx53_pinctrl_info = { - .pins = imx53_pinctrl_pads, - .npins = ARRAY_SIZE(imx53_pinctrl_pads), - .pin_regs = imx53_pin_regs, - .npin_regs = ARRAY_SIZE(imx53_pin_regs), -}; - -static struct of_device_id imx53_pinctrl_of_match[] __devinitdata = { - { .compatible = "fsl,imx53-iomuxc", }, - { /* sentinel */ } -}; - -static int __devinit imx53_pinctrl_probe(struct platform_device *pdev) -{ - return imx_pinctrl_probe(pdev, &imx53_pinctrl_info); -} - -static struct platform_driver imx53_pinctrl_driver = { - .driver = { - .name = "imx53-pinctrl", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(imx53_pinctrl_of_match), - }, - .probe = imx53_pinctrl_probe, - .remove = __devexit_p(imx_pinctrl_remove), -}; - -static int __init imx53_pinctrl_init(void) -{ - return platform_driver_register(&imx53_pinctrl_driver); -} -arch_initcall(imx53_pinctrl_init); - -static void __exit imx53_pinctrl_exit(void) -{ - platform_driver_unregister(&imx53_pinctrl_driver); -} -module_exit(imx53_pinctrl_exit); -MODULE_AUTHOR("Dong Aisheng "); -MODULE_DESCRIPTION("Freescale IMX53 pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/pinctrl/pinctrl-imx6q.c b/trunk/drivers/pinctrl/pinctrl-imx6q.c deleted file mode 100644 index 7737d4d71a3c..000000000000 --- a/trunk/drivers/pinctrl/pinctrl-imx6q.c +++ /dev/null @@ -1,2331 +0,0 @@ -/* - * imx6q pinctrl driver based on imx pinmux core - * - * Copyright (C) 2012 Freescale Semiconductor, Inc. - * Copyright (C) 2012 Linaro, Inc. - * - * Author: Dong Aisheng - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "pinctrl-imx.h" - -enum imx6q_pads { - MX6Q_PAD_SD2_DAT1 = 0, - MX6Q_PAD_SD2_DAT2 = 1, - MX6Q_PAD_SD2_DAT0 = 2, - MX6Q_PAD_RGMII_TXC = 3, - MX6Q_PAD_RGMII_TD0 = 4, - MX6Q_PAD_RGMII_TD1 = 5, - MX6Q_PAD_RGMII_TD2 = 6, - MX6Q_PAD_RGMII_TD3 = 7, - MX6Q_PAD_RGMII_RX_CTL = 8, - MX6Q_PAD_RGMII_RD0 = 9, - MX6Q_PAD_RGMII_TX_CTL = 10, - MX6Q_PAD_RGMII_RD1 = 11, - MX6Q_PAD_RGMII_RD2 = 12, - MX6Q_PAD_RGMII_RD3 = 13, - MX6Q_PAD_RGMII_RXC = 14, - MX6Q_PAD_EIM_A25 = 15, - MX6Q_PAD_EIM_EB2 = 16, - MX6Q_PAD_EIM_D16 = 17, - MX6Q_PAD_EIM_D17 = 18, - MX6Q_PAD_EIM_D18 = 19, - MX6Q_PAD_EIM_D19 = 20, - MX6Q_PAD_EIM_D20 = 21, - MX6Q_PAD_EIM_D21 = 22, - MX6Q_PAD_EIM_D22 = 23, - MX6Q_PAD_EIM_D23 = 24, - MX6Q_PAD_EIM_EB3 = 25, - MX6Q_PAD_EIM_D24 = 26, - MX6Q_PAD_EIM_D25 = 27, - MX6Q_PAD_EIM_D26 = 28, - MX6Q_PAD_EIM_D27 = 29, - MX6Q_PAD_EIM_D28 = 30, - MX6Q_PAD_EIM_D29 = 31, - MX6Q_PAD_EIM_D30 = 32, - MX6Q_PAD_EIM_D31 = 33, - MX6Q_PAD_EIM_A24 = 34, - MX6Q_PAD_EIM_A23 = 35, - MX6Q_PAD_EIM_A22 = 36, - MX6Q_PAD_EIM_A21 = 37, - MX6Q_PAD_EIM_A20 = 38, - MX6Q_PAD_EIM_A19 = 39, - MX6Q_PAD_EIM_A18 = 40, - MX6Q_PAD_EIM_A17 = 41, - MX6Q_PAD_EIM_A16 = 42, - MX6Q_PAD_EIM_CS0 = 43, - MX6Q_PAD_EIM_CS1 = 44, - MX6Q_PAD_EIM_OE = 45, - MX6Q_PAD_EIM_RW = 46, - MX6Q_PAD_EIM_LBA = 47, - MX6Q_PAD_EIM_EB0 = 48, - MX6Q_PAD_EIM_EB1 = 49, - MX6Q_PAD_EIM_DA0 = 50, - MX6Q_PAD_EIM_DA1 = 51, - MX6Q_PAD_EIM_DA2 = 52, - MX6Q_PAD_EIM_DA3 = 53, - MX6Q_PAD_EIM_DA4 = 54, - MX6Q_PAD_EIM_DA5 = 55, - MX6Q_PAD_EIM_DA6 = 56, - MX6Q_PAD_EIM_DA7 = 57, - MX6Q_PAD_EIM_DA8 = 58, - MX6Q_PAD_EIM_DA9 = 59, - MX6Q_PAD_EIM_DA10 = 60, - MX6Q_PAD_EIM_DA11 = 61, - MX6Q_PAD_EIM_DA12 = 62, - MX6Q_PAD_EIM_DA13 = 63, - MX6Q_PAD_EIM_DA14 = 64, - MX6Q_PAD_EIM_DA15 = 65, - MX6Q_PAD_EIM_WAIT = 66, - MX6Q_PAD_EIM_BCLK = 67, - MX6Q_PAD_DI0_DISP_CLK = 68, - MX6Q_PAD_DI0_PIN15 = 69, - MX6Q_PAD_DI0_PIN2 = 70, - MX6Q_PAD_DI0_PIN3 = 71, - MX6Q_PAD_DI0_PIN4 = 72, - MX6Q_PAD_DISP0_DAT0 = 73, - MX6Q_PAD_DISP0_DAT1 = 74, - MX6Q_PAD_DISP0_DAT2 = 75, - MX6Q_PAD_DISP0_DAT3 = 76, - MX6Q_PAD_DISP0_DAT4 = 77, - MX6Q_PAD_DISP0_DAT5 = 78, - MX6Q_PAD_DISP0_DAT6 = 79, - MX6Q_PAD_DISP0_DAT7 = 80, - MX6Q_PAD_DISP0_DAT8 = 81, - MX6Q_PAD_DISP0_DAT9 = 82, - MX6Q_PAD_DISP0_DAT10 = 83, - MX6Q_PAD_DISP0_DAT11 = 84, - MX6Q_PAD_DISP0_DAT12 = 85, - MX6Q_PAD_DISP0_DAT13 = 86, - MX6Q_PAD_DISP0_DAT14 = 87, - MX6Q_PAD_DISP0_DAT15 = 88, - MX6Q_PAD_DISP0_DAT16 = 89, - MX6Q_PAD_DISP0_DAT17 = 90, - MX6Q_PAD_DISP0_DAT18 = 91, - MX6Q_PAD_DISP0_DAT19 = 92, - MX6Q_PAD_DISP0_DAT20 = 93, - MX6Q_PAD_DISP0_DAT21 = 94, - MX6Q_PAD_DISP0_DAT22 = 95, - MX6Q_PAD_DISP0_DAT23 = 96, - MX6Q_PAD_ENET_MDIO = 97, - MX6Q_PAD_ENET_REF_CLK = 98, - MX6Q_PAD_ENET_RX_ER = 99, - MX6Q_PAD_ENET_CRS_DV = 100, - MX6Q_PAD_ENET_RXD1 = 101, - MX6Q_PAD_ENET_RXD0 = 102, - MX6Q_PAD_ENET_TX_EN = 103, - MX6Q_PAD_ENET_TXD1 = 104, - MX6Q_PAD_ENET_TXD0 = 105, - MX6Q_PAD_ENET_MDC = 106, - MX6Q_PAD_DRAM_D40 = 107, - MX6Q_PAD_DRAM_D41 = 108, - MX6Q_PAD_DRAM_D42 = 109, - MX6Q_PAD_DRAM_D43 = 110, - MX6Q_PAD_DRAM_D44 = 111, - MX6Q_PAD_DRAM_D45 = 112, - MX6Q_PAD_DRAM_D46 = 113, - MX6Q_PAD_DRAM_D47 = 114, - MX6Q_PAD_DRAM_SDQS5 = 115, - MX6Q_PAD_DRAM_DQM5 = 116, - MX6Q_PAD_DRAM_D32 = 117, - MX6Q_PAD_DRAM_D33 = 118, - MX6Q_PAD_DRAM_D34 = 119, - MX6Q_PAD_DRAM_D35 = 120, - MX6Q_PAD_DRAM_D36 = 121, - MX6Q_PAD_DRAM_D37 = 122, - MX6Q_PAD_DRAM_D38 = 123, - MX6Q_PAD_DRAM_D39 = 124, - MX6Q_PAD_DRAM_DQM4 = 125, - MX6Q_PAD_DRAM_SDQS4 = 126, - MX6Q_PAD_DRAM_D24 = 127, - MX6Q_PAD_DRAM_D25 = 128, - MX6Q_PAD_DRAM_D26 = 129, - MX6Q_PAD_DRAM_D27 = 130, - MX6Q_PAD_DRAM_D28 = 131, - MX6Q_PAD_DRAM_D29 = 132, - MX6Q_PAD_DRAM_SDQS3 = 133, - MX6Q_PAD_DRAM_D30 = 134, - MX6Q_PAD_DRAM_D31 = 135, - MX6Q_PAD_DRAM_DQM3 = 136, - MX6Q_PAD_DRAM_D16 = 137, - MX6Q_PAD_DRAM_D17 = 138, - MX6Q_PAD_DRAM_D18 = 139, - MX6Q_PAD_DRAM_D19 = 140, - MX6Q_PAD_DRAM_D20 = 141, - MX6Q_PAD_DRAM_D21 = 142, - MX6Q_PAD_DRAM_D22 = 143, - MX6Q_PAD_DRAM_SDQS2 = 144, - MX6Q_PAD_DRAM_D23 = 145, - MX6Q_PAD_DRAM_DQM2 = 146, - MX6Q_PAD_DRAM_A0 = 147, - MX6Q_PAD_DRAM_A1 = 148, - MX6Q_PAD_DRAM_A2 = 149, - MX6Q_PAD_DRAM_A3 = 150, - MX6Q_PAD_DRAM_A4 = 151, - MX6Q_PAD_DRAM_A5 = 152, - MX6Q_PAD_DRAM_A6 = 153, - MX6Q_PAD_DRAM_A7 = 154, - MX6Q_PAD_DRAM_A8 = 155, - MX6Q_PAD_DRAM_A9 = 156, - MX6Q_PAD_DRAM_A10 = 157, - MX6Q_PAD_DRAM_A11 = 158, - MX6Q_PAD_DRAM_A12 = 159, - MX6Q_PAD_DRAM_A13 = 160, - MX6Q_PAD_DRAM_A14 = 161, - MX6Q_PAD_DRAM_A15 = 162, - MX6Q_PAD_DRAM_CAS = 163, - MX6Q_PAD_DRAM_CS0 = 164, - MX6Q_PAD_DRAM_CS1 = 165, - MX6Q_PAD_DRAM_RAS = 166, - MX6Q_PAD_DRAM_RESET = 167, - MX6Q_PAD_DRAM_SDBA0 = 168, - MX6Q_PAD_DRAM_SDBA1 = 169, - MX6Q_PAD_DRAM_SDCLK_0 = 170, - MX6Q_PAD_DRAM_SDBA2 = 171, - MX6Q_PAD_DRAM_SDCKE0 = 172, - MX6Q_PAD_DRAM_SDCLK_1 = 173, - MX6Q_PAD_DRAM_SDCKE1 = 174, - MX6Q_PAD_DRAM_SDODT0 = 175, - MX6Q_PAD_DRAM_SDODT1 = 176, - MX6Q_PAD_DRAM_SDWE = 177, - MX6Q_PAD_DRAM_D0 = 178, - MX6Q_PAD_DRAM_D1 = 179, - MX6Q_PAD_DRAM_D2 = 180, - MX6Q_PAD_DRAM_D3 = 181, - MX6Q_PAD_DRAM_D4 = 182, - MX6Q_PAD_DRAM_D5 = 183, - MX6Q_PAD_DRAM_SDQS0 = 184, - MX6Q_PAD_DRAM_D6 = 185, - MX6Q_PAD_DRAM_D7 = 186, - MX6Q_PAD_DRAM_DQM0 = 187, - MX6Q_PAD_DRAM_D8 = 188, - MX6Q_PAD_DRAM_D9 = 189, - MX6Q_PAD_DRAM_D10 = 190, - MX6Q_PAD_DRAM_D11 = 191, - MX6Q_PAD_DRAM_D12 = 192, - MX6Q_PAD_DRAM_D13 = 193, - MX6Q_PAD_DRAM_D14 = 194, - MX6Q_PAD_DRAM_SDQS1 = 195, - MX6Q_PAD_DRAM_D15 = 196, - MX6Q_PAD_DRAM_DQM1 = 197, - MX6Q_PAD_DRAM_D48 = 198, - MX6Q_PAD_DRAM_D49 = 199, - MX6Q_PAD_DRAM_D50 = 200, - MX6Q_PAD_DRAM_D51 = 201, - MX6Q_PAD_DRAM_D52 = 202, - MX6Q_PAD_DRAM_D53 = 203, - MX6Q_PAD_DRAM_D54 = 204, - MX6Q_PAD_DRAM_D55 = 205, - MX6Q_PAD_DRAM_SDQS6 = 206, - MX6Q_PAD_DRAM_DQM6 = 207, - MX6Q_PAD_DRAM_D56 = 208, - MX6Q_PAD_DRAM_SDQS7 = 209, - MX6Q_PAD_DRAM_D57 = 210, - MX6Q_PAD_DRAM_D58 = 211, - MX6Q_PAD_DRAM_D59 = 212, - MX6Q_PAD_DRAM_D60 = 213, - MX6Q_PAD_DRAM_DQM7 = 214, - MX6Q_PAD_DRAM_D61 = 215, - MX6Q_PAD_DRAM_D62 = 216, - MX6Q_PAD_DRAM_D63 = 217, - MX6Q_PAD_KEY_COL0 = 218, - MX6Q_PAD_KEY_ROW0 = 219, - MX6Q_PAD_KEY_COL1 = 220, - MX6Q_PAD_KEY_ROW1 = 221, - MX6Q_PAD_KEY_COL2 = 222, - MX6Q_PAD_KEY_ROW2 = 223, - MX6Q_PAD_KEY_COL3 = 224, - MX6Q_PAD_KEY_ROW3 = 225, - MX6Q_PAD_KEY_COL4 = 226, - MX6Q_PAD_KEY_ROW4 = 227, - MX6Q_PAD_GPIO_0 = 228, - MX6Q_PAD_GPIO_1 = 229, - MX6Q_PAD_GPIO_9 = 230, - MX6Q_PAD_GPIO_3 = 231, - MX6Q_PAD_GPIO_6 = 232, - MX6Q_PAD_GPIO_2 = 233, - MX6Q_PAD_GPIO_4 = 234, - MX6Q_PAD_GPIO_5 = 235, - MX6Q_PAD_GPIO_7 = 236, - MX6Q_PAD_GPIO_8 = 237, - MX6Q_PAD_GPIO_16 = 238, - MX6Q_PAD_GPIO_17 = 239, - MX6Q_PAD_GPIO_18 = 240, - MX6Q_PAD_GPIO_19 = 241, - MX6Q_PAD_CSI0_PIXCLK = 242, - MX6Q_PAD_CSI0_MCLK = 243, - MX6Q_PAD_CSI0_DATA_EN = 244, - MX6Q_PAD_CSI0_VSYNC = 245, - MX6Q_PAD_CSI0_DAT4 = 246, - MX6Q_PAD_CSI0_DAT5 = 247, - MX6Q_PAD_CSI0_DAT6 = 248, - MX6Q_PAD_CSI0_DAT7 = 249, - MX6Q_PAD_CSI0_DAT8 = 250, - MX6Q_PAD_CSI0_DAT9 = 251, - MX6Q_PAD_CSI0_DAT10 = 252, - MX6Q_PAD_CSI0_DAT11 = 253, - MX6Q_PAD_CSI0_DAT12 = 254, - MX6Q_PAD_CSI0_DAT13 = 255, - MX6Q_PAD_CSI0_DAT14 = 256, - MX6Q_PAD_CSI0_DAT15 = 257, - MX6Q_PAD_CSI0_DAT16 = 258, - MX6Q_PAD_CSI0_DAT17 = 259, - MX6Q_PAD_CSI0_DAT18 = 260, - MX6Q_PAD_CSI0_DAT19 = 261, - MX6Q_PAD_JTAG_TMS = 262, - MX6Q_PAD_JTAG_MOD = 263, - MX6Q_PAD_JTAG_TRSTB = 264, - MX6Q_PAD_JTAG_TDI = 265, - MX6Q_PAD_JTAG_TCK = 266, - MX6Q_PAD_JTAG_TDO = 267, - MX6Q_PAD_LVDS1_TX3_P = 268, - MX6Q_PAD_LVDS1_TX2_P = 269, - MX6Q_PAD_LVDS1_CLK_P = 270, - MX6Q_PAD_LVDS1_TX1_P = 271, - MX6Q_PAD_LVDS1_TX0_P = 272, - MX6Q_PAD_LVDS0_TX3_P = 273, - MX6Q_PAD_LVDS0_CLK_P = 274, - MX6Q_PAD_LVDS0_TX2_P = 275, - MX6Q_PAD_LVDS0_TX1_P = 276, - MX6Q_PAD_LVDS0_TX0_P = 277, - MX6Q_PAD_TAMPER = 278, - MX6Q_PAD_PMIC_ON_REQ = 279, - MX6Q_PAD_PMIC_STBY_REQ = 280, - MX6Q_PAD_POR_B = 281, - MX6Q_PAD_BOOT_MODE1 = 282, - MX6Q_PAD_RESET_IN_B = 283, - MX6Q_PAD_BOOT_MODE0 = 284, - MX6Q_PAD_TEST_MODE = 285, - MX6Q_PAD_SD3_DAT7 = 286, - MX6Q_PAD_SD3_DAT6 = 287, - MX6Q_PAD_SD3_DAT5 = 288, - MX6Q_PAD_SD3_DAT4 = 289, - MX6Q_PAD_SD3_CMD = 290, - MX6Q_PAD_SD3_CLK = 291, - MX6Q_PAD_SD3_DAT0 = 292, - MX6Q_PAD_SD3_DAT1 = 293, - MX6Q_PAD_SD3_DAT2 = 294, - MX6Q_PAD_SD3_DAT3 = 295, - MX6Q_PAD_SD3_RST = 296, - MX6Q_PAD_NANDF_CLE = 297, - MX6Q_PAD_NANDF_ALE = 298, - MX6Q_PAD_NANDF_WP_B = 299, - MX6Q_PAD_NANDF_RB0 = 300, - MX6Q_PAD_NANDF_CS0 = 301, - MX6Q_PAD_NANDF_CS1 = 302, - MX6Q_PAD_NANDF_CS2 = 303, - MX6Q_PAD_NANDF_CS3 = 304, - MX6Q_PAD_SD4_CMD = 305, - MX6Q_PAD_SD4_CLK = 306, - MX6Q_PAD_NANDF_D0 = 307, - MX6Q_PAD_NANDF_D1 = 308, - MX6Q_PAD_NANDF_D2 = 309, - MX6Q_PAD_NANDF_D3 = 310, - MX6Q_PAD_NANDF_D4 = 311, - MX6Q_PAD_NANDF_D5 = 312, - MX6Q_PAD_NANDF_D6 = 313, - MX6Q_PAD_NANDF_D7 = 314, - MX6Q_PAD_SD4_DAT0 = 315, - MX6Q_PAD_SD4_DAT1 = 316, - MX6Q_PAD_SD4_DAT2 = 317, - MX6Q_PAD_SD4_DAT3 = 318, - MX6Q_PAD_SD4_DAT4 = 319, - MX6Q_PAD_SD4_DAT5 = 320, - MX6Q_PAD_SD4_DAT6 = 321, - MX6Q_PAD_SD4_DAT7 = 322, - MX6Q_PAD_SD1_DAT1 = 323, - MX6Q_PAD_SD1_DAT0 = 324, - MX6Q_PAD_SD1_DAT3 = 325, - MX6Q_PAD_SD1_CMD = 326, - MX6Q_PAD_SD1_DAT2 = 327, - MX6Q_PAD_SD1_CLK = 328, - MX6Q_PAD_SD2_CLK = 329, - MX6Q_PAD_SD2_CMD = 330, - MX6Q_PAD_SD2_DAT3 = 331, -}; - -/* imx6q register maps */ -static struct imx_pin_reg imx6q_pin_regs[] = { - IMX_PIN_REG(MX6Q_PAD_SD2_DAT1, 0x0360, 0x004C, 0, 0x0000, 0), /* MX6Q_PAD_SD2_DAT1__USDHC2_DAT1 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT1, 0x0360, 0x004C, 1, 0x0834, 0), /* MX6Q_PAD_SD2_DAT1__ECSPI5_SS0 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT1, 0x0360, 0x004C, 2, 0x0000, 0), /* MX6Q_PAD_SD2_DAT1__WEIM_WEIM_CS_2 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT1, 0x0360, 0x004C, 3, 0x07C8, 0), /* MX6Q_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT1, 0x0360, 0x004C, 4, 0x08F0, 0), /* MX6Q_PAD_SD2_DAT1__KPP_COL_7 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT1, 0x0360, 0x004C, 5, 0x0000, 0), /* MX6Q_PAD_SD2_DAT1__GPIO_1_14 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT1, 0x0360, 0x004C, 6, 0x0000, 0), /* MX6Q_PAD_SD2_DAT1__CCM_WAIT */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT1, 0x0360, 0x004C, 7, 0x0000, 0), /* MX6Q_PAD_SD2_DAT1__ANATOP_TESTO_0 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT2, 0x0364, 0x0050, 0, 0x0000, 0), /* MX6Q_PAD_SD2_DAT2__USDHC2_DAT2 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT2, 0x0364, 0x0050, 1, 0x0838, 0), /* MX6Q_PAD_SD2_DAT2__ECSPI5_SS1 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT2, 0x0364, 0x0050, 2, 0x0000, 0), /* MX6Q_PAD_SD2_DAT2__WEIM_WEIM_CS_3 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT2, 0x0364, 0x0050, 3, 0x07B8, 0), /* MX6Q_PAD_SD2_DAT2__AUDMUX_AUD4_TXD */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT2, 0x0364, 0x0050, 4, 0x08F8, 0), /* MX6Q_PAD_SD2_DAT2__KPP_ROW_6 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT2, 0x0364, 0x0050, 5, 0x0000, 0), /* MX6Q_PAD_SD2_DAT2__GPIO_1_13 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT2, 0x0364, 0x0050, 6, 0x0000, 0), /* MX6Q_PAD_SD2_DAT2__CCM_STOP */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT2, 0x0364, 0x0050, 7, 0x0000, 0), /* MX6Q_PAD_SD2_DAT2__ANATOP_TESTO_1 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT0, 0x0368, 0x0054, 0, 0x0000, 0), /* MX6Q_PAD_SD2_DAT0__USDHC2_DAT0 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT0, 0x0368, 0x0054, 1, 0x082C, 0), /* MX6Q_PAD_SD2_DAT0__ECSPI5_MISO */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT0, 0x0368, 0x0054, 3, 0x07B4, 0), /* MX6Q_PAD_SD2_DAT0__AUDMUX_AUD4_RXD */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT0, 0x0368, 0x0054, 4, 0x08FC, 0), /* MX6Q_PAD_SD2_DAT0__KPP_ROW_7 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT0, 0x0368, 0x0054, 5, 0x0000, 0), /* MX6Q_PAD_SD2_DAT0__GPIO_1_15 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT0, 0x0368, 0x0054, 6, 0x0000, 0), /* MX6Q_PAD_SD2_DAT0__DCIC2_DCIC_OUT */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT0, 0x0368, 0x0054, 7, 0x0000, 0), /* MX6Q_PAD_SD2_DAT0__TESTO_2 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TXC, 0x036C, 0x0058, 0, 0x0000, 0), /* MX6Q_PAD_RGMII_TXC__USBOH3_H2_DATA */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TXC, 0x036C, 0x0058, 1, 0x0000, 0), /* MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TXC, 0x036C, 0x0058, 2, 0x0918, 0), /* MX6Q_PAD_RGMII_TXC__SPDIF_SPDIF_EXTCLK */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TXC, 0x036C, 0x0058, 5, 0x0000, 0), /* MX6Q_PAD_RGMII_TXC__GPIO_6_19 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TXC, 0x036C, 0x0058, 6, 0x0000, 0), /* MX6Q_PAD_RGMII_TXC__MIPI_CORE_DPHY_IN_0 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TXC, 0x036C, 0x0058, 7, 0x0000, 0), /* MX6Q_PAD_RGMII_TXC__ANATOP_24M_OUT */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TD0, 0x0370, 0x005C, 0, 0x0000, 0), /* MX6Q_PAD_RGMII_TD0__MIPI_HSI_CRL_TX_RDY */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TD0, 0x0370, 0x005C, 1, 0x0000, 0), /* MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TD0, 0x0370, 0x005C, 5, 0x0000, 0), /* MX6Q_PAD_RGMII_TD0__GPIO_6_20 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TD0, 0x0370, 0x005C, 6, 0x0000, 0), /* MX6Q_PAD_RGMII_TD0__MIPI_CORE_DPHY_IN_1 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TD1, 0x0374, 0x0060, 0, 0x0000, 0), /* MX6Q_PAD_RGMII_TD1__MIPI_HSI_CRL_RX_FLG */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TD1, 0x0374, 0x0060, 1, 0x0000, 0), /* MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TD1, 0x0374, 0x0060, 5, 0x0000, 0), /* MX6Q_PAD_RGMII_TD1__GPIO_6_21 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TD1, 0x0374, 0x0060, 6, 0x0000, 0), /* MX6Q_PAD_RGMII_TD1__MIPI_CORE_DPHY_IN_2 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TD1, 0x0374, 0x0060, 7, 0x0000, 0), /* MX6Q_PAD_RGMII_TD1__CCM_PLL3_BYP */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TD2, 0x0378, 0x0064, 0, 0x0000, 0), /* MX6Q_PAD_RGMII_TD2__MIPI_HSI_CRL_RX_DTA */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TD2, 0x0378, 0x0064, 1, 0x0000, 0), /* MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TD2, 0x0378, 0x0064, 5, 0x0000, 0), /* MX6Q_PAD_RGMII_TD2__GPIO_6_22 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TD2, 0x0378, 0x0064, 6, 0x0000, 0), /* MX6Q_PAD_RGMII_TD2__MIPI_CORE_DPHY_IN_3 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TD2, 0x0378, 0x0064, 7, 0x0000, 0), /* MX6Q_PAD_RGMII_TD2__CCM_PLL2_BYP */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TD3, 0x037C, 0x0068, 0, 0x0000, 0), /* MX6Q_PAD_RGMII_TD3__MIPI_HSI_CRL_RX_WAK */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TD3, 0x037C, 0x0068, 1, 0x0000, 0), /* MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TD3, 0x037C, 0x0068, 5, 0x0000, 0), /* MX6Q_PAD_RGMII_TD3__GPIO_6_23 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TD3, 0x037C, 0x0068, 6, 0x0000, 0), /* MX6Q_PAD_RGMII_TD3__MIPI_CORE_DPHY_IN_4 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RX_CTL, 0x0380, 0x006C, 0, 0x0000, 0), /* MX6Q_PAD_RGMII_RX_CTL__USBOH3_H3_DATA */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RX_CTL, 0x0380, 0x006C, 1, 0x0858, 0), /* MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RX_CTL, 0x0380, 0x006C, 5, 0x0000, 0), /* MX6Q_PAD_RGMII_RX_CTL__GPIO_6_24 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RX_CTL, 0x0380, 0x006C, 6, 0x0000, 0), /* MX6Q_PAD_RGMII_RX_CTL__MIPI_DPHY_IN_5 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RD0, 0x0384, 0x0070, 0, 0x0000, 0), /* MX6Q_PAD_RGMII_RD0__MIPI_HSI_CRL_RX_RDY */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RD0, 0x0384, 0x0070, 1, 0x0848, 0), /* MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RD0, 0x0384, 0x0070, 5, 0x0000, 0), /* MX6Q_PAD_RGMII_RD0__GPIO_6_25 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RD0, 0x0384, 0x0070, 6, 0x0000, 0), /* MX6Q_PAD_RGMII_RD0__MIPI_CORE_DPHY_IN_6 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TX_CTL, 0x0388, 0x0074, 0, 0x0000, 0), /* MX6Q_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TX_CTL, 0x0388, 0x0074, 1, 0x0000, 0), /* MX6Q_PAD_RGMII_TX_CTL__RGMII_TX_CTL */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TX_CTL, 0x0388, 0x0074, 5, 0x0000, 0), /* MX6Q_PAD_RGMII_TX_CTL__GPIO_6_26 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TX_CTL, 0x0388, 0x0074, 6, 0x0000, 0), /* MX6Q_PAD_RGMII_TX_CTL__CORE_DPHY_IN_7 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_TX_CTL, 0x0388, 0x0074, 7, 0x083C, 0), /* MX6Q_PAD_RGMII_TX_CTL__ANATOP_REF_OUT */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RD1, 0x038C, 0x0078, 0, 0x0000, 0), /* MX6Q_PAD_RGMII_RD1__MIPI_HSI_CTRL_TX_FL */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RD1, 0x038C, 0x0078, 1, 0x084C, 0), /* MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RD1, 0x038C, 0x0078, 5, 0x0000, 0), /* MX6Q_PAD_RGMII_RD1__GPIO_6_27 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RD1, 0x038C, 0x0078, 6, 0x0000, 0), /* MX6Q_PAD_RGMII_RD1__CORE_DPHY_TEST_IN_8 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RD1, 0x038C, 0x0078, 7, 0x0000, 0), /* MX6Q_PAD_RGMII_RD1__SJC_FAIL */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RD2, 0x0390, 0x007C, 0, 0x0000, 0), /* MX6Q_PAD_RGMII_RD2__MIPI_HSI_CRL_TX_DTA */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RD2, 0x0390, 0x007C, 1, 0x0850, 0), /* MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RD2, 0x0390, 0x007C, 5, 0x0000, 0), /* MX6Q_PAD_RGMII_RD2__GPIO_6_28 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RD2, 0x0390, 0x007C, 6, 0x0000, 0), /* MX6Q_PAD_RGMII_RD2__MIPI_CORE_DPHY_IN_9 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RD3, 0x0394, 0x0080, 0, 0x0000, 0), /* MX6Q_PAD_RGMII_RD3__MIPI_HSI_CRL_TX_WAK */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RD3, 0x0394, 0x0080, 1, 0x0854, 0), /* MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RD3, 0x0394, 0x0080, 5, 0x0000, 0), /* MX6Q_PAD_RGMII_RD3__GPIO_6_29 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RD3, 0x0394, 0x0080, 6, 0x0000, 0), /* MX6Q_PAD_RGMII_RD3__MIPI_CORE_DPHY_IN10 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RXC, 0x0398, 0x0084, 0, 0x0000, 0), /* MX6Q_PAD_RGMII_RXC__USBOH3_H3_STROBE */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RXC, 0x0398, 0x0084, 1, 0x0844, 0), /* MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RXC, 0x0398, 0x0084, 5, 0x0000, 0), /* MX6Q_PAD_RGMII_RXC__GPIO_6_30 */ - IMX_PIN_REG(MX6Q_PAD_RGMII_RXC, 0x0398, 0x0084, 6, 0x0000, 0), /* MX6Q_PAD_RGMII_RXC__MIPI_CORE_DPHY_IN11 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A25, 0x039C, 0x0088, 0, 0x0000, 0), /* MX6Q_PAD_EIM_A25__WEIM_WEIM_A_25 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A25, 0x039C, 0x0088, 1, 0x0000, 0), /* MX6Q_PAD_EIM_A25__ECSPI4_SS1 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A25, 0x039C, 0x0088, 2, 0x0000, 0), /* MX6Q_PAD_EIM_A25__ECSPI2_RDY */ - IMX_PIN_REG(MX6Q_PAD_EIM_A25, 0x039C, 0x0088, 3, 0x0000, 0), /* MX6Q_PAD_EIM_A25__IPU1_DI1_PIN12 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A25, 0x039C, 0x0088, 4, 0x0000, 0), /* MX6Q_PAD_EIM_A25__IPU1_DI0_D1_CS */ - IMX_PIN_REG(MX6Q_PAD_EIM_A25, 0x039C, 0x0088, 5, 0x0000, 0), /* MX6Q_PAD_EIM_A25__GPIO_5_2 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A25, 0x039C, 0x0088, 6, 0x088C, 0), /* MX6Q_PAD_EIM_A25__HDMI_TX_CEC_LINE */ - IMX_PIN_REG(MX6Q_PAD_EIM_A25, 0x039C, 0x0088, 7, 0x0000, 0), /* MX6Q_PAD_EIM_A25__PL301_PER1_HBURST_0 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB2, 0x03A0, 0x008C, 0, 0x0000, 0), /* MX6Q_PAD_EIM_EB2__WEIM_WEIM_EB_2 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB2, 0x03A0, 0x008C, 1, 0x0800, 0), /* MX6Q_PAD_EIM_EB2__ECSPI1_SS0 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB2, 0x03A0, 0x008C, 2, 0x07EC, 0), /* MX6Q_PAD_EIM_EB2__CCM_DI1_EXT_CLK */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB2, 0x03A0, 0x008C, 3, 0x08D4, 0), /* MX6Q_PAD_EIM_EB2__IPU2_CSI1_D_19 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB2, 0x03A0, 0x008C, 4, 0x0890, 0), /* MX6Q_PAD_EIM_EB2__HDMI_TX_DDC_SCL */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB2, 0x03A0, 0x008C, 5, 0x0000, 0), /* MX6Q_PAD_EIM_EB2__GPIO_2_30 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB2, 0x03A0, 0x008C, 6, 0x08A0, 0), /* MX6Q_PAD_EIM_EB2__I2C2_SCL */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB2, 0x03A0, 0x008C, 7, 0x0000, 0), /* MX6Q_PAD_EIM_EB2__SRC_BT_CFG_30 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D16, 0x03A4, 0x0090, 0, 0x0000, 0), /* MX6Q_PAD_EIM_D16__WEIM_WEIM_D_16 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D16, 0x03A4, 0x0090, 1, 0x07F4, 0), /* MX6Q_PAD_EIM_D16__ECSPI1_SCLK */ - IMX_PIN_REG(MX6Q_PAD_EIM_D16, 0x03A4, 0x0090, 2, 0x0000, 0), /* MX6Q_PAD_EIM_D16__IPU1_DI0_PIN5 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D16, 0x03A4, 0x0090, 3, 0x08D0, 0), /* MX6Q_PAD_EIM_D16__IPU2_CSI1_D_18 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D16, 0x03A4, 0x0090, 4, 0x0894, 0), /* MX6Q_PAD_EIM_D16__HDMI_TX_DDC_SDA */ - IMX_PIN_REG(MX6Q_PAD_EIM_D16, 0x03A4, 0x0090, 5, 0x0000, 0), /* MX6Q_PAD_EIM_D16__GPIO_3_16 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D16, 0x03A4, 0x0090, 6, 0x08A4, 0), /* MX6Q_PAD_EIM_D16__I2C2_SDA */ - IMX_PIN_REG(MX6Q_PAD_EIM_D17, 0x03A8, 0x0094, 0, 0x0000, 0), /* MX6Q_PAD_EIM_D17__WEIM_WEIM_D_17 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D17, 0x03A8, 0x0094, 1, 0x07F8, 0), /* MX6Q_PAD_EIM_D17__ECSPI1_MISO */ - IMX_PIN_REG(MX6Q_PAD_EIM_D17, 0x03A8, 0x0094, 2, 0x0000, 0), /* MX6Q_PAD_EIM_D17__IPU1_DI0_PIN6 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D17, 0x03A8, 0x0094, 3, 0x08E0, 0), /* MX6Q_PAD_EIM_D17__IPU2_CSI1_PIXCLK */ - IMX_PIN_REG(MX6Q_PAD_EIM_D17, 0x03A8, 0x0094, 4, 0x0000, 0), /* MX6Q_PAD_EIM_D17__DCIC1_DCIC_OUT */ - IMX_PIN_REG(MX6Q_PAD_EIM_D17, 0x03A8, 0x0094, 5, 0x0000, 0), /* MX6Q_PAD_EIM_D17__GPIO_3_17 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D17, 0x03A8, 0x0094, 6, 0x08A8, 0), /* MX6Q_PAD_EIM_D17__I2C3_SCL */ - IMX_PIN_REG(MX6Q_PAD_EIM_D17, 0x03A8, 0x0094, 7, 0x0000, 0), /* MX6Q_PAD_EIM_D17__PL301_PER1_HBURST_1 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D18, 0x03AC, 0x0098, 0, 0x0000, 0), /* MX6Q_PAD_EIM_D18__WEIM_WEIM_D_18 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D18, 0x03AC, 0x0098, 1, 0x07FC, 0), /* MX6Q_PAD_EIM_D18__ECSPI1_MOSI */ - IMX_PIN_REG(MX6Q_PAD_EIM_D18, 0x03AC, 0x0098, 2, 0x0000, 0), /* MX6Q_PAD_EIM_D18__IPU1_DI0_PIN7 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D18, 0x03AC, 0x0098, 3, 0x08CC, 0), /* MX6Q_PAD_EIM_D18__IPU2_CSI1_D_17 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D18, 0x03AC, 0x0098, 4, 0x0000, 0), /* MX6Q_PAD_EIM_D18__IPU1_DI1_D0_CS */ - IMX_PIN_REG(MX6Q_PAD_EIM_D18, 0x03AC, 0x0098, 5, 0x0000, 0), /* MX6Q_PAD_EIM_D18__GPIO_3_18 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D18, 0x03AC, 0x0098, 6, 0x08AC, 0), /* MX6Q_PAD_EIM_D18__I2C3_SDA */ - IMX_PIN_REG(MX6Q_PAD_EIM_D18, 0x03AC, 0x0098, 7, 0x0000, 0), /* MX6Q_PAD_EIM_D18__PL301_PER1_HBURST_2 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D19, 0x03B0, 0x009C, 0, 0x0000, 0), /* MX6Q_PAD_EIM_D19__WEIM_WEIM_D_19 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D19, 0x03B0, 0x009C, 1, 0x0804, 0), /* MX6Q_PAD_EIM_D19__ECSPI1_SS1 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D19, 0x03B0, 0x009C, 2, 0x0000, 0), /* MX6Q_PAD_EIM_D19__IPU1_DI0_PIN8 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D19, 0x03B0, 0x009C, 3, 0x08C8, 0), /* MX6Q_PAD_EIM_D19__IPU2_CSI1_D_16 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D19, 0x03B0, 0x009C, 4, 0x091C, 0), /* MX6Q_PAD_EIM_D19__UART1_CTS */ - IMX_PIN_REG(MX6Q_PAD_EIM_D19, 0x03B0, 0x009C, 5, 0x0000, 0), /* MX6Q_PAD_EIM_D19__GPIO_3_19 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D19, 0x03B0, 0x009C, 6, 0x0000, 0), /* MX6Q_PAD_EIM_D19__EPIT1_EPITO */ - IMX_PIN_REG(MX6Q_PAD_EIM_D19, 0x03B0, 0x009C, 7, 0x0000, 0), /* MX6Q_PAD_EIM_D19__PL301_PER1_HRESP */ - IMX_PIN_REG(MX6Q_PAD_EIM_D20, 0x03B4, 0x00A0, 0, 0x0000, 0), /* MX6Q_PAD_EIM_D20__WEIM_WEIM_D_20 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D20, 0x03B4, 0x00A0, 1, 0x0824, 0), /* MX6Q_PAD_EIM_D20__ECSPI4_SS0 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D20, 0x03B4, 0x00A0, 2, 0x0000, 0), /* MX6Q_PAD_EIM_D20__IPU1_DI0_PIN16 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D20, 0x03B4, 0x00A0, 3, 0x08C4, 0), /* MX6Q_PAD_EIM_D20__IPU2_CSI1_D_15 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D20, 0x03B4, 0x00A0, 4, 0x091C, 1), /* MX6Q_PAD_EIM_D20__UART1_RTS */ - IMX_PIN_REG(MX6Q_PAD_EIM_D20, 0x03B4, 0x00A0, 5, 0x0000, 0), /* MX6Q_PAD_EIM_D20__GPIO_3_20 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D20, 0x03B4, 0x00A0, 6, 0x0000, 0), /* MX6Q_PAD_EIM_D20__EPIT2_EPITO */ - IMX_PIN_REG(MX6Q_PAD_EIM_D21, 0x03B8, 0x00A4, 0, 0x0000, 0), /* MX6Q_PAD_EIM_D21__WEIM_WEIM_D_21 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D21, 0x03B8, 0x00A4, 1, 0x0000, 0), /* MX6Q_PAD_EIM_D21__ECSPI4_SCLK */ - IMX_PIN_REG(MX6Q_PAD_EIM_D21, 0x03B8, 0x00A4, 2, 0x0000, 0), /* MX6Q_PAD_EIM_D21__IPU1_DI0_PIN17 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D21, 0x03B8, 0x00A4, 3, 0x08B4, 0), /* MX6Q_PAD_EIM_D21__IPU2_CSI1_D_11 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D21, 0x03B8, 0x00A4, 4, 0x0944, 0), /* MX6Q_PAD_EIM_D21__USBOH3_USBOTG_OC */ - IMX_PIN_REG(MX6Q_PAD_EIM_D21, 0x03B8, 0x00A4, 5, 0x0000, 0), /* MX6Q_PAD_EIM_D21__GPIO_3_21 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D21, 0x03B8, 0x00A4, 6, 0x0898, 0), /* MX6Q_PAD_EIM_D21__I2C1_SCL */ - IMX_PIN_REG(MX6Q_PAD_EIM_D21, 0x03B8, 0x00A4, 7, 0x0914, 0), /* MX6Q_PAD_EIM_D21__SPDIF_IN1 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D22, 0x03BC, 0x00A8, 0, 0x0000, 0), /* MX6Q_PAD_EIM_D22__WEIM_WEIM_D_22 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D22, 0x03BC, 0x00A8, 1, 0x0000, 0), /* MX6Q_PAD_EIM_D22__ECSPI4_MISO */ - IMX_PIN_REG(MX6Q_PAD_EIM_D22, 0x03BC, 0x00A8, 2, 0x0000, 0), /* MX6Q_PAD_EIM_D22__IPU1_DI0_PIN1 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D22, 0x03BC, 0x00A8, 3, 0x08B0, 0), /* MX6Q_PAD_EIM_D22__IPU2_CSI1_D_10 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D22, 0x03BC, 0x00A8, 4, 0x0000, 0), /* MX6Q_PAD_EIM_D22__USBOH3_USBOTG_PWR */ - IMX_PIN_REG(MX6Q_PAD_EIM_D22, 0x03BC, 0x00A8, 5, 0x0000, 0), /* MX6Q_PAD_EIM_D22__GPIO_3_22 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D22, 0x03BC, 0x00A8, 6, 0x0000, 0), /* MX6Q_PAD_EIM_D22__SPDIF_OUT1 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D22, 0x03BC, 0x00A8, 7, 0x0000, 0), /* MX6Q_PAD_EIM_D22__PL301_PER1_HWRITE */ - IMX_PIN_REG(MX6Q_PAD_EIM_D23, 0x03C0, 0x00AC, 0, 0x0000, 0), /* MX6Q_PAD_EIM_D23__WEIM_WEIM_D_23 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D23, 0x03C0, 0x00AC, 1, 0x0000, 0), /* MX6Q_PAD_EIM_D23__IPU1_DI0_D0_CS */ - IMX_PIN_REG(MX6Q_PAD_EIM_D23, 0x03C0, 0x00AC, 2, 0x092C, 0), /* MX6Q_PAD_EIM_D23__UART3_CTS */ - IMX_PIN_REG(MX6Q_PAD_EIM_D23, 0x03C0, 0x00AC, 3, 0x0000, 0), /* MX6Q_PAD_EIM_D23__UART1_DCD */ - IMX_PIN_REG(MX6Q_PAD_EIM_D23, 0x03C0, 0x00AC, 4, 0x08D8, 0), /* MX6Q_PAD_EIM_D23__IPU2_CSI1_DATA_EN */ - IMX_PIN_REG(MX6Q_PAD_EIM_D23, 0x03C0, 0x00AC, 5, 0x0000, 0), /* MX6Q_PAD_EIM_D23__GPIO_3_23 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D23, 0x03C0, 0x00AC, 6, 0x0000, 0), /* MX6Q_PAD_EIM_D23__IPU1_DI1_PIN2 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D23, 0x03C0, 0x00AC, 7, 0x0000, 0), /* MX6Q_PAD_EIM_D23__IPU1_DI1_PIN14 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB3, 0x03C4, 0x00B0, 0, 0x0000, 0), /* MX6Q_PAD_EIM_EB3__WEIM_WEIM_EB_3 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB3, 0x03C4, 0x00B0, 1, 0x0000, 0), /* MX6Q_PAD_EIM_EB3__ECSPI4_RDY */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB3, 0x03C4, 0x00B0, 2, 0x092C, 1), /* MX6Q_PAD_EIM_EB3__UART3_RTS */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB3, 0x03C4, 0x00B0, 3, 0x0000, 0), /* MX6Q_PAD_EIM_EB3__UART1_RI */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB3, 0x03C4, 0x00B0, 4, 0x08DC, 0), /* MX6Q_PAD_EIM_EB3__IPU2_CSI1_HSYNC */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB3, 0x03C4, 0x00B0, 5, 0x0000, 0), /* MX6Q_PAD_EIM_EB3__GPIO_2_31 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB3, 0x03C4, 0x00B0, 6, 0x0000, 0), /* MX6Q_PAD_EIM_EB3__IPU1_DI1_PIN3 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB3, 0x03C4, 0x00B0, 7, 0x0000, 0), /* MX6Q_PAD_EIM_EB3__SRC_BT_CFG_31 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D24, 0x03C8, 0x00B4, 0, 0x0000, 0), /* MX6Q_PAD_EIM_D24__WEIM_WEIM_D_24 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D24, 0x03C8, 0x00B4, 1, 0x0000, 0), /* MX6Q_PAD_EIM_D24__ECSPI4_SS2 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D24, 0x03C8, 0x00B4, 2, 0x0000, 0), /* MX6Q_PAD_EIM_D24__UART3_TXD */ - IMX_PIN_REG(MX6Q_PAD_EIM_D24, 0x03C8, 0x00B4, 3, 0x0808, 0), /* MX6Q_PAD_EIM_D24__ECSPI1_SS2 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D24, 0x03C8, 0x00B4, 4, 0x0000, 0), /* MX6Q_PAD_EIM_D24__ECSPI2_SS2 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D24, 0x03C8, 0x00B4, 5, 0x0000, 0), /* MX6Q_PAD_EIM_D24__GPIO_3_24 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D24, 0x03C8, 0x00B4, 6, 0x07D8, 0), /* MX6Q_PAD_EIM_D24__AUDMUX_AUD5_RXFS */ - IMX_PIN_REG(MX6Q_PAD_EIM_D24, 0x03C8, 0x00B4, 7, 0x0000, 0), /* MX6Q_PAD_EIM_D24__UART1_DTR */ - IMX_PIN_REG(MX6Q_PAD_EIM_D25, 0x03CC, 0x00B8, 0, 0x0000, 0), /* MX6Q_PAD_EIM_D25__WEIM_WEIM_D_25 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D25, 0x03CC, 0x00B8, 1, 0x0000, 0), /* MX6Q_PAD_EIM_D25__ECSPI4_SS3 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D25, 0x03CC, 0x00B8, 2, 0x0930, 1), /* MX6Q_PAD_EIM_D25__UART3_RXD */ - IMX_PIN_REG(MX6Q_PAD_EIM_D25, 0x03CC, 0x00B8, 3, 0x080C, 0), /* MX6Q_PAD_EIM_D25__ECSPI1_SS3 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D25, 0x03CC, 0x00B8, 4, 0x0000, 0), /* MX6Q_PAD_EIM_D25__ECSPI2_SS3 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D25, 0x03CC, 0x00B8, 5, 0x0000, 0), /* MX6Q_PAD_EIM_D25__GPIO_3_25 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D25, 0x03CC, 0x00B8, 6, 0x07D4, 0), /* MX6Q_PAD_EIM_D25__AUDMUX_AUD5_RXC */ - IMX_PIN_REG(MX6Q_PAD_EIM_D25, 0x03CC, 0x00B8, 7, 0x0000, 0), /* MX6Q_PAD_EIM_D25__UART1_DSR */ - IMX_PIN_REG(MX6Q_PAD_EIM_D26, 0x03D0, 0x00BC, 0, 0x0000, 0), /* MX6Q_PAD_EIM_D26__WEIM_WEIM_D_26 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D26, 0x03D0, 0x00BC, 1, 0x0000, 0), /* MX6Q_PAD_EIM_D26__IPU1_DI1_PIN11 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D26, 0x03D0, 0x00BC, 2, 0x0000, 0), /* MX6Q_PAD_EIM_D26__IPU1_CSI0_D_1 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D26, 0x03D0, 0x00BC, 3, 0x08C0, 0), /* MX6Q_PAD_EIM_D26__IPU2_CSI1_D_14 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D26, 0x03D0, 0x00BC, 4, 0x0000, 0), /* MX6Q_PAD_EIM_D26__UART2_TXD */ - IMX_PIN_REG(MX6Q_PAD_EIM_D26, 0x03D0, 0x00BC, 5, 0x0000, 0), /* MX6Q_PAD_EIM_D26__GPIO_3_26 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D26, 0x03D0, 0x00BC, 6, 0x0000, 0), /* MX6Q_PAD_EIM_D26__IPU1_SISG_2 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D26, 0x03D0, 0x00BC, 7, 0x0000, 0), /* MX6Q_PAD_EIM_D26__IPU1_DISP1_DAT_22 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D27, 0x03D4, 0x00C0, 0, 0x0000, 0), /* MX6Q_PAD_EIM_D27__WEIM_WEIM_D_27 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D27, 0x03D4, 0x00C0, 1, 0x0000, 0), /* MX6Q_PAD_EIM_D27__IPU1_DI1_PIN13 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D27, 0x03D4, 0x00C0, 2, 0x0000, 0), /* MX6Q_PAD_EIM_D27__IPU1_CSI0_D_0 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D27, 0x03D4, 0x00C0, 3, 0x08BC, 0), /* MX6Q_PAD_EIM_D27__IPU2_CSI1_D_13 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D27, 0x03D4, 0x00C0, 4, 0x0928, 1), /* MX6Q_PAD_EIM_D27__UART2_RXD */ - IMX_PIN_REG(MX6Q_PAD_EIM_D27, 0x03D4, 0x00C0, 5, 0x0000, 0), /* MX6Q_PAD_EIM_D27__GPIO_3_27 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D27, 0x03D4, 0x00C0, 6, 0x0000, 0), /* MX6Q_PAD_EIM_D27__IPU1_SISG_3 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D27, 0x03D4, 0x00C0, 7, 0x0000, 0), /* MX6Q_PAD_EIM_D27__IPU1_DISP1_DAT_23 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D28, 0x03D8, 0x00C4, 0, 0x0000, 0), /* MX6Q_PAD_EIM_D28__WEIM_WEIM_D_28 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D28, 0x03D8, 0x00C4, 1, 0x089C, 0), /* MX6Q_PAD_EIM_D28__I2C1_SDA */ - IMX_PIN_REG(MX6Q_PAD_EIM_D28, 0x03D8, 0x00C4, 2, 0x0000, 0), /* MX6Q_PAD_EIM_D28__ECSPI4_MOSI */ - IMX_PIN_REG(MX6Q_PAD_EIM_D28, 0x03D8, 0x00C4, 3, 0x08B8, 0), /* MX6Q_PAD_EIM_D28__IPU2_CSI1_D_12 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D28, 0x03D8, 0x00C4, 4, 0x0924, 0), /* MX6Q_PAD_EIM_D28__UART2_CTS */ - IMX_PIN_REG(MX6Q_PAD_EIM_D28, 0x03D8, 0x00C4, 5, 0x0000, 0), /* MX6Q_PAD_EIM_D28__GPIO_3_28 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D28, 0x03D8, 0x00C4, 6, 0x0000, 0), /* MX6Q_PAD_EIM_D28__IPU1_EXT_TRIG */ - IMX_PIN_REG(MX6Q_PAD_EIM_D28, 0x03D8, 0x00C4, 7, 0x0000, 0), /* MX6Q_PAD_EIM_D28__IPU1_DI0_PIN13 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D29, 0x03DC, 0x00C8, 0, 0x0000, 0), /* MX6Q_PAD_EIM_D29__WEIM_WEIM_D_29 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D29, 0x03DC, 0x00C8, 1, 0x0000, 0), /* MX6Q_PAD_EIM_D29__IPU1_DI1_PIN15 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D29, 0x03DC, 0x00C8, 2, 0x0824, 1), /* MX6Q_PAD_EIM_D29__ECSPI4_SS0 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D29, 0x03DC, 0x00C8, 4, 0x0924, 1), /* MX6Q_PAD_EIM_D29__UART2_RTS */ - IMX_PIN_REG(MX6Q_PAD_EIM_D29, 0x03DC, 0x00C8, 5, 0x0000, 0), /* MX6Q_PAD_EIM_D29__GPIO_3_29 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D29, 0x03DC, 0x00C8, 6, 0x08E4, 0), /* MX6Q_PAD_EIM_D29__IPU2_CSI1_VSYNC */ - IMX_PIN_REG(MX6Q_PAD_EIM_D29, 0x03DC, 0x00C8, 7, 0x0000, 0), /* MX6Q_PAD_EIM_D29__IPU1_DI0_PIN14 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D30, 0x03E0, 0x00CC, 0, 0x0000, 0), /* MX6Q_PAD_EIM_D30__WEIM_WEIM_D_30 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D30, 0x03E0, 0x00CC, 1, 0x0000, 0), /* MX6Q_PAD_EIM_D30__IPU1_DISP1_DAT_21 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D30, 0x03E0, 0x00CC, 2, 0x0000, 0), /* MX6Q_PAD_EIM_D30__IPU1_DI0_PIN11 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D30, 0x03E0, 0x00CC, 3, 0x0000, 0), /* MX6Q_PAD_EIM_D30__IPU1_CSI0_D_3 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D30, 0x03E0, 0x00CC, 4, 0x092C, 2), /* MX6Q_PAD_EIM_D30__UART3_CTS */ - IMX_PIN_REG(MX6Q_PAD_EIM_D30, 0x03E0, 0x00CC, 5, 0x0000, 0), /* MX6Q_PAD_EIM_D30__GPIO_3_30 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D30, 0x03E0, 0x00CC, 6, 0x0948, 0), /* MX6Q_PAD_EIM_D30__USBOH3_USBH1_OC */ - IMX_PIN_REG(MX6Q_PAD_EIM_D30, 0x03E0, 0x00CC, 7, 0x0000, 0), /* MX6Q_PAD_EIM_D30__PL301_PER1_HPROT_0 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D31, 0x03E4, 0x00D0, 0, 0x0000, 0), /* MX6Q_PAD_EIM_D31__WEIM_WEIM_D_31 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D31, 0x03E4, 0x00D0, 1, 0x0000, 0), /* MX6Q_PAD_EIM_D31__IPU1_DISP1_DAT_20 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D31, 0x03E4, 0x00D0, 2, 0x0000, 0), /* MX6Q_PAD_EIM_D31__IPU1_DI0_PIN12 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D31, 0x03E4, 0x00D0, 3, 0x0000, 0), /* MX6Q_PAD_EIM_D31__IPU1_CSI0_D_2 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D31, 0x03E4, 0x00D0, 4, 0x092C, 3), /* MX6Q_PAD_EIM_D31__UART3_RTS */ - IMX_PIN_REG(MX6Q_PAD_EIM_D31, 0x03E4, 0x00D0, 5, 0x0000, 0), /* MX6Q_PAD_EIM_D31__GPIO_3_31 */ - IMX_PIN_REG(MX6Q_PAD_EIM_D31, 0x03E4, 0x00D0, 6, 0x0000, 0), /* MX6Q_PAD_EIM_D31__USBOH3_USBH1_PWR */ - IMX_PIN_REG(MX6Q_PAD_EIM_D31, 0x03E4, 0x00D0, 7, 0x0000, 0), /* MX6Q_PAD_EIM_D31__PL301_PER1_HPROT_1 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A24, 0x03E8, 0x00D4, 0, 0x0000, 0), /* MX6Q_PAD_EIM_A24__WEIM_WEIM_A_24 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A24, 0x03E8, 0x00D4, 1, 0x0000, 0), /* MX6Q_PAD_EIM_A24__IPU1_DISP1_DAT_19 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A24, 0x03E8, 0x00D4, 2, 0x08D4, 1), /* MX6Q_PAD_EIM_A24__IPU2_CSI1_D_19 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A24, 0x03E8, 0x00D4, 3, 0x0000, 0), /* MX6Q_PAD_EIM_A24__IPU2_SISG_2 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A24, 0x03E8, 0x00D4, 4, 0x0000, 0), /* MX6Q_PAD_EIM_A24__IPU1_SISG_2 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A24, 0x03E8, 0x00D4, 5, 0x0000, 0), /* MX6Q_PAD_EIM_A24__GPIO_5_4 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A24, 0x03E8, 0x00D4, 6, 0x0000, 0), /* MX6Q_PAD_EIM_A24__PL301_PER1_HPROT_2 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A24, 0x03E8, 0x00D4, 7, 0x0000, 0), /* MX6Q_PAD_EIM_A24__SRC_BT_CFG_24 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A23, 0x03EC, 0x00D8, 0, 0x0000, 0), /* MX6Q_PAD_EIM_A23__WEIM_WEIM_A_23 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A23, 0x03EC, 0x00D8, 1, 0x0000, 0), /* MX6Q_PAD_EIM_A23__IPU1_DISP1_DAT_18 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A23, 0x03EC, 0x00D8, 2, 0x08D0, 1), /* MX6Q_PAD_EIM_A23__IPU2_CSI1_D_18 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A23, 0x03EC, 0x00D8, 3, 0x0000, 0), /* MX6Q_PAD_EIM_A23__IPU2_SISG_3 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A23, 0x03EC, 0x00D8, 4, 0x0000, 0), /* MX6Q_PAD_EIM_A23__IPU1_SISG_3 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A23, 0x03EC, 0x00D8, 5, 0x0000, 0), /* MX6Q_PAD_EIM_A23__GPIO_6_6 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A23, 0x03EC, 0x00D8, 6, 0x0000, 0), /* MX6Q_PAD_EIM_A23__PL301_PER1_HPROT_3 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A23, 0x03EC, 0x00D8, 7, 0x0000, 0), /* MX6Q_PAD_EIM_A23__SRC_BT_CFG_23 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A22, 0x03F0, 0x00DC, 0, 0x0000, 0), /* MX6Q_PAD_EIM_A22__WEIM_WEIM_A_22 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A22, 0x03F0, 0x00DC, 1, 0x0000, 0), /* MX6Q_PAD_EIM_A22__IPU1_DISP1_DAT_17 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A22, 0x03F0, 0x00DC, 2, 0x08CC, 1), /* MX6Q_PAD_EIM_A22__IPU2_CSI1_D_17 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A22, 0x03F0, 0x00DC, 5, 0x0000, 0), /* MX6Q_PAD_EIM_A22__GPIO_2_16 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A22, 0x03F0, 0x00DC, 6, 0x0000, 0), /* MX6Q_PAD_EIM_A22__TPSMP_HDATA_0 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A22, 0x03F0, 0x00DC, 7, 0x0000, 0), /* MX6Q_PAD_EIM_A22__SRC_BT_CFG_22 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A21, 0x03F4, 0x00E0, 0, 0x0000, 0), /* MX6Q_PAD_EIM_A21__WEIM_WEIM_A_21 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A21, 0x03F4, 0x00E0, 1, 0x0000, 0), /* MX6Q_PAD_EIM_A21__IPU1_DISP1_DAT_16 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A21, 0x03F4, 0x00E0, 2, 0x08C8, 1), /* MX6Q_PAD_EIM_A21__IPU2_CSI1_D_16 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A21, 0x03F4, 0x00E0, 3, 0x0000, 0), /* MX6Q_PAD_EIM_A21__RESERVED_RESERVED */ - IMX_PIN_REG(MX6Q_PAD_EIM_A21, 0x03F4, 0x00E0, 4, 0x0000, 0), /* MX6Q_PAD_EIM_A21__MIPI_CORE_DPHY_OUT_18 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A21, 0x03F4, 0x00E0, 5, 0x0000, 0), /* MX6Q_PAD_EIM_A21__GPIO_2_17 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A21, 0x03F4, 0x00E0, 6, 0x0000, 0), /* MX6Q_PAD_EIM_A21__TPSMP_HDATA_1 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A21, 0x03F4, 0x00E0, 7, 0x0000, 0), /* MX6Q_PAD_EIM_A21__SRC_BT_CFG_21 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A20, 0x03F8, 0x00E4, 0, 0x0000, 0), /* MX6Q_PAD_EIM_A20__WEIM_WEIM_A_20 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A20, 0x03F8, 0x00E4, 1, 0x0000, 0), /* MX6Q_PAD_EIM_A20__IPU1_DISP1_DAT_15 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A20, 0x03F8, 0x00E4, 2, 0x08C4, 1), /* MX6Q_PAD_EIM_A20__IPU2_CSI1_D_15 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A20, 0x03F8, 0x00E4, 3, 0x0000, 0), /* MX6Q_PAD_EIM_A20__RESERVED_RESERVED */ - IMX_PIN_REG(MX6Q_PAD_EIM_A20, 0x03F8, 0x00E4, 4, 0x0000, 0), /* MX6Q_PAD_EIM_A20__MIPI_CORE_DPHY_OUT_19 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A20, 0x03F8, 0x00E4, 5, 0x0000, 0), /* MX6Q_PAD_EIM_A20__GPIO_2_18 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A20, 0x03F8, 0x00E4, 6, 0x0000, 0), /* MX6Q_PAD_EIM_A20__TPSMP_HDATA_2 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A20, 0x03F8, 0x00E4, 7, 0x0000, 0), /* MX6Q_PAD_EIM_A20__SRC_BT_CFG_20 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A19, 0x03FC, 0x00E8, 0, 0x0000, 0), /* MX6Q_PAD_EIM_A19__WEIM_WEIM_A_19 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A19, 0x03FC, 0x00E8, 1, 0x0000, 0), /* MX6Q_PAD_EIM_A19__IPU1_DISP1_DAT_14 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A19, 0x03FC, 0x00E8, 2, 0x08C0, 1), /* MX6Q_PAD_EIM_A19__IPU2_CSI1_D_14 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A19, 0x03FC, 0x00E8, 3, 0x0000, 0), /* MX6Q_PAD_EIM_A19__RESERVED_RESERVED */ - IMX_PIN_REG(MX6Q_PAD_EIM_A19, 0x03FC, 0x00E8, 4, 0x0000, 0), /* MX6Q_PAD_EIM_A19__MIPI_CORE_DPHY_OUT_20 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A19, 0x03FC, 0x00E8, 5, 0x0000, 0), /* MX6Q_PAD_EIM_A19__GPIO_2_19 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A19, 0x03FC, 0x00E8, 6, 0x0000, 0), /* MX6Q_PAD_EIM_A19__TPSMP_HDATA_3 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A19, 0x03FC, 0x00E8, 7, 0x0000, 0), /* MX6Q_PAD_EIM_A19__SRC_BT_CFG_19 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A18, 0x0400, 0x00EC, 0, 0x0000, 0), /* MX6Q_PAD_EIM_A18__WEIM_WEIM_A_18 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A18, 0x0400, 0x00EC, 1, 0x0000, 0), /* MX6Q_PAD_EIM_A18__IPU1_DISP1_DAT_13 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A18, 0x0400, 0x00EC, 2, 0x08BC, 1), /* MX6Q_PAD_EIM_A18__IPU2_CSI1_D_13 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A18, 0x0400, 0x00EC, 3, 0x0000, 0), /* MX6Q_PAD_EIM_A18__RESERVED_RESERVED */ - IMX_PIN_REG(MX6Q_PAD_EIM_A18, 0x0400, 0x00EC, 4, 0x0000, 0), /* MX6Q_PAD_EIM_A18__MIPI_CORE_DPHY_OUT_21 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A18, 0x0400, 0x00EC, 5, 0x0000, 0), /* MX6Q_PAD_EIM_A18__GPIO_2_20 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A18, 0x0400, 0x00EC, 6, 0x0000, 0), /* MX6Q_PAD_EIM_A18__TPSMP_HDATA_4 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A18, 0x0400, 0x00EC, 7, 0x0000, 0), /* MX6Q_PAD_EIM_A18__SRC_BT_CFG_18 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A17, 0x0404, 0x00F0, 0, 0x0000, 0), /* MX6Q_PAD_EIM_A17__WEIM_WEIM_A_17 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A17, 0x0404, 0x00F0, 1, 0x0000, 0), /* MX6Q_PAD_EIM_A17__IPU1_DISP1_DAT_12 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A17, 0x0404, 0x00F0, 2, 0x08B8, 1), /* MX6Q_PAD_EIM_A17__IPU2_CSI1_D_12 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A17, 0x0404, 0x00F0, 3, 0x0000, 0), /* MX6Q_PAD_EIM_A17__RESERVED_RESERVED */ - IMX_PIN_REG(MX6Q_PAD_EIM_A17, 0x0404, 0x00F0, 4, 0x0000, 0), /* MX6Q_PAD_EIM_A17__MIPI_CORE_DPHY_OUT_22 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A17, 0x0404, 0x00F0, 5, 0x0000, 0), /* MX6Q_PAD_EIM_A17__GPIO_2_21 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A17, 0x0404, 0x00F0, 6, 0x0000, 0), /* MX6Q_PAD_EIM_A17__TPSMP_HDATA_5 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A17, 0x0404, 0x00F0, 7, 0x0000, 0), /* MX6Q_PAD_EIM_A17__SRC_BT_CFG_17 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A16, 0x0408, 0x00F4, 0, 0x0000, 0), /* MX6Q_PAD_EIM_A16__WEIM_WEIM_A_16 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A16, 0x0408, 0x00F4, 1, 0x0000, 0), /* MX6Q_PAD_EIM_A16__IPU1_DI1_DISP_CLK */ - IMX_PIN_REG(MX6Q_PAD_EIM_A16, 0x0408, 0x00F4, 2, 0x08E0, 1), /* MX6Q_PAD_EIM_A16__IPU2_CSI1_PIXCLK */ - IMX_PIN_REG(MX6Q_PAD_EIM_A16, 0x0408, 0x00F4, 4, 0x0000, 0), /* MX6Q_PAD_EIM_A16__MIPI_CORE_DPHY_OUT_23 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A16, 0x0408, 0x00F4, 5, 0x0000, 0), /* MX6Q_PAD_EIM_A16__GPIO_2_22 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A16, 0x0408, 0x00F4, 6, 0x0000, 0), /* MX6Q_PAD_EIM_A16__TPSMP_HDATA_6 */ - IMX_PIN_REG(MX6Q_PAD_EIM_A16, 0x0408, 0x00F4, 7, 0x0000, 0), /* MX6Q_PAD_EIM_A16__SRC_BT_CFG_16 */ - IMX_PIN_REG(MX6Q_PAD_EIM_CS0, 0x040C, 0x00F8, 0, 0x0000, 0), /* MX6Q_PAD_EIM_CS0__WEIM_WEIM_CS_0 */ - IMX_PIN_REG(MX6Q_PAD_EIM_CS0, 0x040C, 0x00F8, 1, 0x0000, 0), /* MX6Q_PAD_EIM_CS0__IPU1_DI1_PIN5 */ - IMX_PIN_REG(MX6Q_PAD_EIM_CS0, 0x040C, 0x00F8, 2, 0x0810, 0), /* MX6Q_PAD_EIM_CS0__ECSPI2_SCLK */ - IMX_PIN_REG(MX6Q_PAD_EIM_CS0, 0x040C, 0x00F8, 4, 0x0000, 0), /* MX6Q_PAD_EIM_CS0__MIPI_CORE_DPHY_OUT_24 */ - IMX_PIN_REG(MX6Q_PAD_EIM_CS0, 0x040C, 0x00F8, 5, 0x0000, 0), /* MX6Q_PAD_EIM_CS0__GPIO_2_23 */ - IMX_PIN_REG(MX6Q_PAD_EIM_CS0, 0x040C, 0x00F8, 6, 0x0000, 0), /* MX6Q_PAD_EIM_CS0__TPSMP_HDATA_7 */ - IMX_PIN_REG(MX6Q_PAD_EIM_CS1, 0x0410, 0x00FC, 0, 0x0000, 0), /* MX6Q_PAD_EIM_CS1__WEIM_WEIM_CS_1 */ - IMX_PIN_REG(MX6Q_PAD_EIM_CS1, 0x0410, 0x00FC, 1, 0x0000, 0), /* MX6Q_PAD_EIM_CS1__IPU1_DI1_PIN6 */ - IMX_PIN_REG(MX6Q_PAD_EIM_CS1, 0x0410, 0x00FC, 2, 0x0818, 0), /* MX6Q_PAD_EIM_CS1__ECSPI2_MOSI */ - IMX_PIN_REG(MX6Q_PAD_EIM_CS1, 0x0410, 0x00FC, 4, 0x0000, 0), /* MX6Q_PAD_EIM_CS1__MIPI_CORE_DPHY_OUT_25 */ - IMX_PIN_REG(MX6Q_PAD_EIM_CS1, 0x0410, 0x00FC, 5, 0x0000, 0), /* MX6Q_PAD_EIM_CS1__GPIO_2_24 */ - IMX_PIN_REG(MX6Q_PAD_EIM_CS1, 0x0410, 0x00FC, 6, 0x0000, 0), /* MX6Q_PAD_EIM_CS1__TPSMP_HDATA_8 */ - IMX_PIN_REG(MX6Q_PAD_EIM_OE, 0x0414, 0x0100, 0, 0x0000, 0), /* MX6Q_PAD_EIM_OE__WEIM_WEIM_OE */ - IMX_PIN_REG(MX6Q_PAD_EIM_OE, 0x0414, 0x0100, 1, 0x0000, 0), /* MX6Q_PAD_EIM_OE__IPU1_DI1_PIN7 */ - IMX_PIN_REG(MX6Q_PAD_EIM_OE, 0x0414, 0x0100, 2, 0x0814, 0), /* MX6Q_PAD_EIM_OE__ECSPI2_MISO */ - IMX_PIN_REG(MX6Q_PAD_EIM_OE, 0x0414, 0x0100, 4, 0x0000, 0), /* MX6Q_PAD_EIM_OE__MIPI_CORE_DPHY_OUT_26 */ - IMX_PIN_REG(MX6Q_PAD_EIM_OE, 0x0414, 0x0100, 5, 0x0000, 0), /* MX6Q_PAD_EIM_OE__GPIO_2_25 */ - IMX_PIN_REG(MX6Q_PAD_EIM_OE, 0x0414, 0x0100, 6, 0x0000, 0), /* MX6Q_PAD_EIM_OE__TPSMP_HDATA_9 */ - IMX_PIN_REG(MX6Q_PAD_EIM_RW, 0x0418, 0x0104, 0, 0x0000, 0), /* MX6Q_PAD_EIM_RW__WEIM_WEIM_RW */ - IMX_PIN_REG(MX6Q_PAD_EIM_RW, 0x0418, 0x0104, 1, 0x0000, 0), /* MX6Q_PAD_EIM_RW__IPU1_DI1_PIN8 */ - IMX_PIN_REG(MX6Q_PAD_EIM_RW, 0x0418, 0x0104, 2, 0x081C, 0), /* MX6Q_PAD_EIM_RW__ECSPI2_SS0 */ - IMX_PIN_REG(MX6Q_PAD_EIM_RW, 0x0418, 0x0104, 4, 0x0000, 0), /* MX6Q_PAD_EIM_RW__MIPI_CORE_DPHY_OUT_27 */ - IMX_PIN_REG(MX6Q_PAD_EIM_RW, 0x0418, 0x0104, 5, 0x0000, 0), /* MX6Q_PAD_EIM_RW__GPIO_2_26 */ - IMX_PIN_REG(MX6Q_PAD_EIM_RW, 0x0418, 0x0104, 6, 0x0000, 0), /* MX6Q_PAD_EIM_RW__TPSMP_HDATA_10 */ - IMX_PIN_REG(MX6Q_PAD_EIM_RW, 0x0418, 0x0104, 7, 0x0000, 0), /* MX6Q_PAD_EIM_RW__SRC_BT_CFG_29 */ - IMX_PIN_REG(MX6Q_PAD_EIM_LBA, 0x041C, 0x0108, 0, 0x0000, 0), /* MX6Q_PAD_EIM_LBA__WEIM_WEIM_LBA */ - IMX_PIN_REG(MX6Q_PAD_EIM_LBA, 0x041C, 0x0108, 1, 0x0000, 0), /* MX6Q_PAD_EIM_LBA__IPU1_DI1_PIN17 */ - IMX_PIN_REG(MX6Q_PAD_EIM_LBA, 0x041C, 0x0108, 2, 0x0820, 0), /* MX6Q_PAD_EIM_LBA__ECSPI2_SS1 */ - IMX_PIN_REG(MX6Q_PAD_EIM_LBA, 0x041C, 0x0108, 5, 0x0000, 0), /* MX6Q_PAD_EIM_LBA__GPIO_2_27 */ - IMX_PIN_REG(MX6Q_PAD_EIM_LBA, 0x041C, 0x0108, 6, 0x0000, 0), /* MX6Q_PAD_EIM_LBA__TPSMP_HDATA_11 */ - IMX_PIN_REG(MX6Q_PAD_EIM_LBA, 0x041C, 0x0108, 7, 0x0000, 0), /* MX6Q_PAD_EIM_LBA__SRC_BT_CFG_26 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB0, 0x0420, 0x010C, 0, 0x0000, 0), /* MX6Q_PAD_EIM_EB0__WEIM_WEIM_EB_0 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB0, 0x0420, 0x010C, 1, 0x0000, 0), /* MX6Q_PAD_EIM_EB0__IPU1_DISP1_DAT_11 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB0, 0x0420, 0x010C, 2, 0x08B4, 1), /* MX6Q_PAD_EIM_EB0__IPU2_CSI1_D_11 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB0, 0x0420, 0x010C, 3, 0x0000, 0), /* MX6Q_PAD_EIM_EB0__MIPI_CORE_DPHY_OUT_0 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB0, 0x0420, 0x010C, 4, 0x07F0, 0), /* MX6Q_PAD_EIM_EB0__CCM_PMIC_RDY */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB0, 0x0420, 0x010C, 5, 0x0000, 0), /* MX6Q_PAD_EIM_EB0__GPIO_2_28 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB0, 0x0420, 0x010C, 6, 0x0000, 0), /* MX6Q_PAD_EIM_EB0__TPSMP_HDATA_12 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB0, 0x0420, 0x010C, 7, 0x0000, 0), /* MX6Q_PAD_EIM_EB0__SRC_BT_CFG_27 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB1, 0x0424, 0x0110, 0, 0x0000, 0), /* MX6Q_PAD_EIM_EB1__WEIM_WEIM_EB_1 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB1, 0x0424, 0x0110, 1, 0x0000, 0), /* MX6Q_PAD_EIM_EB1__IPU1_DISP1_DAT_10 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB1, 0x0424, 0x0110, 2, 0x08B0, 1), /* MX6Q_PAD_EIM_EB1__IPU2_CSI1_D_10 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB1, 0x0424, 0x0110, 3, 0x0000, 0), /* MX6Q_PAD_EIM_EB1__MIPI_CORE_DPHY__OUT_1 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB1, 0x0424, 0x0110, 5, 0x0000, 0), /* MX6Q_PAD_EIM_EB1__GPIO_2_29 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB1, 0x0424, 0x0110, 6, 0x0000, 0), /* MX6Q_PAD_EIM_EB1__TPSMP_HDATA_13 */ - IMX_PIN_REG(MX6Q_PAD_EIM_EB1, 0x0424, 0x0110, 7, 0x0000, 0), /* MX6Q_PAD_EIM_EB1__SRC_BT_CFG_28 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA0, 0x0428, 0x0114, 0, 0x0000, 0), /* MX6Q_PAD_EIM_DA0__WEIM_WEIM_DA_A_0 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA0, 0x0428, 0x0114, 1, 0x0000, 0), /* MX6Q_PAD_EIM_DA0__IPU1_DISP1_DAT_9 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA0, 0x0428, 0x0114, 2, 0x0000, 0), /* MX6Q_PAD_EIM_DA0__IPU2_CSI1_D_9 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA0, 0x0428, 0x0114, 3, 0x0000, 0), /* MX6Q_PAD_EIM_DA0__MIPI_CORE_DPHY__OUT_2 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA0, 0x0428, 0x0114, 5, 0x0000, 0), /* MX6Q_PAD_EIM_DA0__GPIO_3_0 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA0, 0x0428, 0x0114, 6, 0x0000, 0), /* MX6Q_PAD_EIM_DA0__TPSMP_HDATA_14 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA0, 0x0428, 0x0114, 7, 0x0000, 0), /* MX6Q_PAD_EIM_DA0__SRC_BT_CFG_0 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA1, 0x042C, 0x0118, 0, 0x0000, 0), /* MX6Q_PAD_EIM_DA1__WEIM_WEIM_DA_A_1 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA1, 0x042C, 0x0118, 1, 0x0000, 0), /* MX6Q_PAD_EIM_DA1__IPU1_DISP1_DAT_8 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA1, 0x042C, 0x0118, 2, 0x0000, 0), /* MX6Q_PAD_EIM_DA1__IPU2_CSI1_D_8 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA1, 0x042C, 0x0118, 3, 0x0000, 0), /* MX6Q_PAD_EIM_DA1__MIPI_CORE_DPHY_OUT_3 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA1, 0x042C, 0x0118, 4, 0x0000, 0), /* MX6Q_PAD_EIM_DA1__USBPHY1_TX_LS_MODE */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA1, 0x042C, 0x0118, 5, 0x0000, 0), /* MX6Q_PAD_EIM_DA1__GPIO_3_1 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA1, 0x042C, 0x0118, 6, 0x0000, 0), /* MX6Q_PAD_EIM_DA1__TPSMP_HDATA_15 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA1, 0x042C, 0x0118, 7, 0x0000, 0), /* MX6Q_PAD_EIM_DA1__SRC_BT_CFG_1 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA2, 0x0430, 0x011C, 0, 0x0000, 0), /* MX6Q_PAD_EIM_DA2__WEIM_WEIM_DA_A_2 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA2, 0x0430, 0x011C, 1, 0x0000, 0), /* MX6Q_PAD_EIM_DA2__IPU1_DISP1_DAT_7 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA2, 0x0430, 0x011C, 2, 0x0000, 0), /* MX6Q_PAD_EIM_DA2__IPU2_CSI1_D_7 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA2, 0x0430, 0x011C, 3, 0x0000, 0), /* MX6Q_PAD_EIM_DA2__MIPI_CORE_DPHY_OUT_4 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA2, 0x0430, 0x011C, 4, 0x0000, 0), /* MX6Q_PAD_EIM_DA2__USBPHY1_TX_HS_MODE */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA2, 0x0430, 0x011C, 5, 0x0000, 0), /* MX6Q_PAD_EIM_DA2__GPIO_3_2 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA2, 0x0430, 0x011C, 6, 0x0000, 0), /* MX6Q_PAD_EIM_DA2__TPSMP_HDATA_16 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA2, 0x0430, 0x011C, 7, 0x0000, 0), /* MX6Q_PAD_EIM_DA2__SRC_BT_CFG_2 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA3, 0x0434, 0x0120, 0, 0x0000, 0), /* MX6Q_PAD_EIM_DA3__WEIM_WEIM_DA_A_3 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA3, 0x0434, 0x0120, 1, 0x0000, 0), /* MX6Q_PAD_EIM_DA3__IPU1_DISP1_DAT_6 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA3, 0x0434, 0x0120, 2, 0x0000, 0), /* MX6Q_PAD_EIM_DA3__IPU2_CSI1_D_6 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA3, 0x0434, 0x0120, 3, 0x0000, 0), /* MX6Q_PAD_EIM_DA3__MIPI_CORE_DPHY_OUT_5 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA3, 0x0434, 0x0120, 4, 0x0000, 0), /* MX6Q_PAD_EIM_DA3__USBPHY1_TX_HIZ */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA3, 0x0434, 0x0120, 5, 0x0000, 0), /* MX6Q_PAD_EIM_DA3__GPIO_3_3 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA3, 0x0434, 0x0120, 6, 0x0000, 0), /* MX6Q_PAD_EIM_DA3__TPSMP_HDATA_17 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA3, 0x0434, 0x0120, 7, 0x0000, 0), /* MX6Q_PAD_EIM_DA3__SRC_BT_CFG_3 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA4, 0x0438, 0x0124, 0, 0x0000, 0), /* MX6Q_PAD_EIM_DA4__WEIM_WEIM_DA_A_4 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA4, 0x0438, 0x0124, 1, 0x0000, 0), /* MX6Q_PAD_EIM_DA4__IPU1_DISP1_DAT_5 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA4, 0x0438, 0x0124, 2, 0x0000, 0), /* MX6Q_PAD_EIM_DA4__IPU2_CSI1_D_5 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA4, 0x0438, 0x0124, 3, 0x0000, 0), /* MX6Q_PAD_EIM_DA4__MIPI_CORE_DPHY_OUT_6 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA4, 0x0438, 0x0124, 4, 0x0000, 0), /* MX6Q_PAD_EIM_DA4__ANATOP_USBPHY1_TX_EN */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA4, 0x0438, 0x0124, 5, 0x0000, 0), /* MX6Q_PAD_EIM_DA4__GPIO_3_4 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA4, 0x0438, 0x0124, 6, 0x0000, 0), /* MX6Q_PAD_EIM_DA4__TPSMP_HDATA_18 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA4, 0x0438, 0x0124, 7, 0x0000, 0), /* MX6Q_PAD_EIM_DA4__SRC_BT_CFG_4 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA5, 0x043C, 0x0128, 0, 0x0000, 0), /* MX6Q_PAD_EIM_DA5__WEIM_WEIM_DA_A_5 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA5, 0x043C, 0x0128, 1, 0x0000, 0), /* MX6Q_PAD_EIM_DA5__IPU1_DISP1_DAT_4 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA5, 0x043C, 0x0128, 2, 0x0000, 0), /* MX6Q_PAD_EIM_DA5__IPU2_CSI1_D_4 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA5, 0x043C, 0x0128, 3, 0x0000, 0), /* MX6Q_PAD_EIM_DA5__MIPI_CORE_DPHY_OUT_7 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA5, 0x043C, 0x0128, 4, 0x0000, 0), /* MX6Q_PAD_EIM_DA5__ANATOP_USBPHY1_TX_DP */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA5, 0x043C, 0x0128, 5, 0x0000, 0), /* MX6Q_PAD_EIM_DA5__GPIO_3_5 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA5, 0x043C, 0x0128, 6, 0x0000, 0), /* MX6Q_PAD_EIM_DA5__TPSMP_HDATA_19 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA5, 0x043C, 0x0128, 7, 0x0000, 0), /* MX6Q_PAD_EIM_DA5__SRC_BT_CFG_5 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA6, 0x0440, 0x012C, 0, 0x0000, 0), /* MX6Q_PAD_EIM_DA6__WEIM_WEIM_DA_A_6 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA6, 0x0440, 0x012C, 1, 0x0000, 0), /* MX6Q_PAD_EIM_DA6__IPU1_DISP1_DAT_3 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA6, 0x0440, 0x012C, 2, 0x0000, 0), /* MX6Q_PAD_EIM_DA6__IPU2_CSI1_D_3 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA6, 0x0440, 0x012C, 3, 0x0000, 0), /* MX6Q_PAD_EIM_DA6__MIPI_CORE_DPHY_OUT_8 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA6, 0x0440, 0x012C, 4, 0x0000, 0), /* MX6Q_PAD_EIM_DA6__ANATOP_USBPHY1_TX_DN */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA6, 0x0440, 0x012C, 5, 0x0000, 0), /* MX6Q_PAD_EIM_DA6__GPIO_3_6 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA6, 0x0440, 0x012C, 6, 0x0000, 0), /* MX6Q_PAD_EIM_DA6__TPSMP_HDATA_20 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA6, 0x0440, 0x012C, 7, 0x0000, 0), /* MX6Q_PAD_EIM_DA6__SRC_BT_CFG_6 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA7, 0x0444, 0x0130, 0, 0x0000, 0), /* MX6Q_PAD_EIM_DA7__WEIM_WEIM_DA_A_7 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA7, 0x0444, 0x0130, 1, 0x0000, 0), /* MX6Q_PAD_EIM_DA7__IPU1_DISP1_DAT_2 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA7, 0x0444, 0x0130, 2, 0x0000, 0), /* MX6Q_PAD_EIM_DA7__IPU2_CSI1_D_2 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA7, 0x0444, 0x0130, 3, 0x0000, 0), /* MX6Q_PAD_EIM_DA7__MIPI_CORE_DPHY_OUT_9 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA7, 0x0444, 0x0130, 5, 0x0000, 0), /* MX6Q_PAD_EIM_DA7__GPIO_3_7 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA7, 0x0444, 0x0130, 6, 0x0000, 0), /* MX6Q_PAD_EIM_DA7__TPSMP_HDATA_21 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA7, 0x0444, 0x0130, 7, 0x0000, 0), /* MX6Q_PAD_EIM_DA7__SRC_BT_CFG_7 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA8, 0x0448, 0x0134, 0, 0x0000, 0), /* MX6Q_PAD_EIM_DA8__WEIM_WEIM_DA_A_8 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA8, 0x0448, 0x0134, 1, 0x0000, 0), /* MX6Q_PAD_EIM_DA8__IPU1_DISP1_DAT_1 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA8, 0x0448, 0x0134, 2, 0x0000, 0), /* MX6Q_PAD_EIM_DA8__IPU2_CSI1_D_1 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA8, 0x0448, 0x0134, 3, 0x0000, 0), /* MX6Q_PAD_EIM_DA8__MIPI_CORE_DPHY_OUT_10 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA8, 0x0448, 0x0134, 5, 0x0000, 0), /* MX6Q_PAD_EIM_DA8__GPIO_3_8 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA8, 0x0448, 0x0134, 6, 0x0000, 0), /* MX6Q_PAD_EIM_DA8__TPSMP_HDATA_22 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA8, 0x0448, 0x0134, 7, 0x0000, 0), /* MX6Q_PAD_EIM_DA8__SRC_BT_CFG_8 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA9, 0x044C, 0x0138, 0, 0x0000, 0), /* MX6Q_PAD_EIM_DA9__WEIM_WEIM_DA_A_9 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA9, 0x044C, 0x0138, 1, 0x0000, 0), /* MX6Q_PAD_EIM_DA9__IPU1_DISP1_DAT_0 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA9, 0x044C, 0x0138, 2, 0x0000, 0), /* MX6Q_PAD_EIM_DA9__IPU2_CSI1_D_0 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA9, 0x044C, 0x0138, 3, 0x0000, 0), /* MX6Q_PAD_EIM_DA9__MIPI_CORE_DPHY_OUT_11 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA9, 0x044C, 0x0138, 5, 0x0000, 0), /* MX6Q_PAD_EIM_DA9__GPIO_3_9 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA9, 0x044C, 0x0138, 6, 0x0000, 0), /* MX6Q_PAD_EIM_DA9__TPSMP_HDATA_23 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA9, 0x044C, 0x0138, 7, 0x0000, 0), /* MX6Q_PAD_EIM_DA9__SRC_BT_CFG_9 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA10, 0x0450, 0x013C, 0, 0x0000, 0), /* MX6Q_PAD_EIM_DA10__WEIM_WEIM_DA_A_10 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA10, 0x0450, 0x013C, 1, 0x0000, 0), /* MX6Q_PAD_EIM_DA10__IPU1_DI1_PIN15 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA10, 0x0450, 0x013C, 2, 0x08D8, 1), /* MX6Q_PAD_EIM_DA10__IPU2_CSI1_DATA_EN */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA10, 0x0450, 0x013C, 3, 0x0000, 0), /* MX6Q_PAD_EIM_DA10__MIPI_CORE_DPHY_OUT12 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA10, 0x0450, 0x013C, 5, 0x0000, 0), /* MX6Q_PAD_EIM_DA10__GPIO_3_10 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA10, 0x0450, 0x013C, 6, 0x0000, 0), /* MX6Q_PAD_EIM_DA10__TPSMP_HDATA_24 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA10, 0x0450, 0x013C, 7, 0x0000, 0), /* MX6Q_PAD_EIM_DA10__SRC_BT_CFG_10 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA11, 0x0454, 0x0140, 0, 0x0000, 0), /* MX6Q_PAD_EIM_DA11__WEIM_WEIM_DA_A_11 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA11, 0x0454, 0x0140, 1, 0x0000, 0), /* MX6Q_PAD_EIM_DA11__IPU1_DI1_PIN2 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA11, 0x0454, 0x0140, 2, 0x08DC, 1), /* MX6Q_PAD_EIM_DA11__IPU2_CSI1_HSYNC */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA11, 0x0454, 0x0140, 3, 0x0000, 0), /* MX6Q_PAD_EIM_DA11__MIPI_CORE_DPHY_OUT13 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA11, 0x0454, 0x0140, 4, 0x0000, 0), /* MX6Q_PAD_EIM_DA11__SDMA_DBG_EVT_CHN_6 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA11, 0x0454, 0x0140, 5, 0x0000, 0), /* MX6Q_PAD_EIM_DA11__GPIO_3_11 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA11, 0x0454, 0x0140, 6, 0x0000, 0), /* MX6Q_PAD_EIM_DA11__TPSMP_HDATA_25 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA11, 0x0454, 0x0140, 7, 0x0000, 0), /* MX6Q_PAD_EIM_DA11__SRC_BT_CFG_11 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA12, 0x0458, 0x0144, 0, 0x0000, 0), /* MX6Q_PAD_EIM_DA12__WEIM_WEIM_DA_A_12 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA12, 0x0458, 0x0144, 1, 0x0000, 0), /* MX6Q_PAD_EIM_DA12__IPU1_DI1_PIN3 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA12, 0x0458, 0x0144, 2, 0x08E4, 1), /* MX6Q_PAD_EIM_DA12__IPU2_CSI1_VSYNC */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA12, 0x0458, 0x0144, 3, 0x0000, 0), /* MX6Q_PAD_EIM_DA12__MIPI_CORE_DPHY_OUT14 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA12, 0x0458, 0x0144, 4, 0x0000, 0), /* MX6Q_PAD_EIM_DA12__SDMA_DEBUG_EVT_CHN_3 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA12, 0x0458, 0x0144, 5, 0x0000, 0), /* MX6Q_PAD_EIM_DA12__GPIO_3_12 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA12, 0x0458, 0x0144, 6, 0x0000, 0), /* MX6Q_PAD_EIM_DA12__TPSMP_HDATA_26 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA12, 0x0458, 0x0144, 7, 0x0000, 0), /* MX6Q_PAD_EIM_DA12__SRC_BT_CFG_12 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA13, 0x045C, 0x0148, 0, 0x0000, 0), /* MX6Q_PAD_EIM_DA13__WEIM_WEIM_DA_A_13 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA13, 0x045C, 0x0148, 1, 0x0000, 0), /* MX6Q_PAD_EIM_DA13__IPU1_DI1_D0_CS */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA13, 0x045C, 0x0148, 2, 0x07EC, 1), /* MX6Q_PAD_EIM_DA13__CCM_DI1_EXT_CLK */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA13, 0x045C, 0x0148, 3, 0x0000, 0), /* MX6Q_PAD_EIM_DA13__MIPI_CORE_DPHY_OUT15 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA13, 0x045C, 0x0148, 4, 0x0000, 0), /* MX6Q_PAD_EIM_DA13__SDMA_DEBUG_EVT_CHN_4 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA13, 0x045C, 0x0148, 5, 0x0000, 0), /* MX6Q_PAD_EIM_DA13__GPIO_3_13 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA13, 0x045C, 0x0148, 6, 0x0000, 0), /* MX6Q_PAD_EIM_DA13__TPSMP_HDATA_27 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA13, 0x045C, 0x0148, 7, 0x0000, 0), /* MX6Q_PAD_EIM_DA13__SRC_BT_CFG_13 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA14, 0x0460, 0x014C, 0, 0x0000, 0), /* MX6Q_PAD_EIM_DA14__WEIM_WEIM_DA_A_14 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA14, 0x0460, 0x014C, 1, 0x0000, 0), /* MX6Q_PAD_EIM_DA14__IPU1_DI1_D1_CS */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA14, 0x0460, 0x014C, 2, 0x0000, 0), /* MX6Q_PAD_EIM_DA14__CCM_DI0_EXT_CLK */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA14, 0x0460, 0x014C, 3, 0x0000, 0), /* MX6Q_PAD_EIM_DA14__MIPI_CORE_DPHY_OUT16 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA14, 0x0460, 0x014C, 4, 0x0000, 0), /* MX6Q_PAD_EIM_DA14__SDMA_DEBUG_EVT_CHN_5 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA14, 0x0460, 0x014C, 5, 0x0000, 0), /* MX6Q_PAD_EIM_DA14__GPIO_3_14 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA14, 0x0460, 0x014C, 6, 0x0000, 0), /* MX6Q_PAD_EIM_DA14__TPSMP_HDATA_28 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA14, 0x0460, 0x014C, 7, 0x0000, 0), /* MX6Q_PAD_EIM_DA14__SRC_BT_CFG_14 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA15, 0x0464, 0x0150, 0, 0x0000, 0), /* MX6Q_PAD_EIM_DA15__WEIM_WEIM_DA_A_15 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA15, 0x0464, 0x0150, 1, 0x0000, 0), /* MX6Q_PAD_EIM_DA15__IPU1_DI1_PIN1 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA15, 0x0464, 0x0150, 2, 0x0000, 0), /* MX6Q_PAD_EIM_DA15__IPU1_DI1_PIN4 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA15, 0x0464, 0x0150, 3, 0x0000, 0), /* MX6Q_PAD_EIM_DA15__MIPI_CORE_DPHY_OUT17 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA15, 0x0464, 0x0150, 5, 0x0000, 0), /* MX6Q_PAD_EIM_DA15__GPIO_3_15 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA15, 0x0464, 0x0150, 6, 0x0000, 0), /* MX6Q_PAD_EIM_DA15__TPSMP_HDATA_29 */ - IMX_PIN_REG(MX6Q_PAD_EIM_DA15, 0x0464, 0x0150, 7, 0x0000, 0), /* MX6Q_PAD_EIM_DA15__SRC_BT_CFG_15 */ - IMX_PIN_REG(MX6Q_PAD_EIM_WAIT, 0x0468, 0x0154, 0, 0x0000, 0), /* MX6Q_PAD_EIM_WAIT__WEIM_WEIM_WAIT */ - IMX_PIN_REG(MX6Q_PAD_EIM_WAIT, 0x0468, 0x0154, 1, 0x0000, 0), /* MX6Q_PAD_EIM_WAIT__WEIM_WEIM_DTACK_B */ - IMX_PIN_REG(MX6Q_PAD_EIM_WAIT, 0x0468, 0x0154, 5, 0x0000, 0), /* MX6Q_PAD_EIM_WAIT__GPIO_5_0 */ - IMX_PIN_REG(MX6Q_PAD_EIM_WAIT, 0x0468, 0x0154, 6, 0x0000, 0), /* MX6Q_PAD_EIM_WAIT__TPSMP_HDATA_30 */ - IMX_PIN_REG(MX6Q_PAD_EIM_WAIT, 0x0468, 0x0154, 7, 0x0000, 0), /* MX6Q_PAD_EIM_WAIT__SRC_BT_CFG_25 */ - IMX_PIN_REG(MX6Q_PAD_EIM_BCLK, 0x046C, 0x0158, 0, 0x0000, 0), /* MX6Q_PAD_EIM_BCLK__WEIM_WEIM_BCLK */ - IMX_PIN_REG(MX6Q_PAD_EIM_BCLK, 0x046C, 0x0158, 1, 0x0000, 0), /* MX6Q_PAD_EIM_BCLK__IPU1_DI1_PIN16 */ - IMX_PIN_REG(MX6Q_PAD_EIM_BCLK, 0x046C, 0x0158, 5, 0x0000, 0), /* MX6Q_PAD_EIM_BCLK__GPIO_6_31 */ - IMX_PIN_REG(MX6Q_PAD_EIM_BCLK, 0x046C, 0x0158, 6, 0x0000, 0), /* MX6Q_PAD_EIM_BCLK__TPSMP_HDATA_31 */ - IMX_PIN_REG(MX6Q_PAD_DI0_DISP_CLK, 0x0470, 0x015C, 0, 0x0000, 0), /* MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DSP_CLK */ - IMX_PIN_REG(MX6Q_PAD_DI0_DISP_CLK, 0x0470, 0x015C, 1, 0x0000, 0), /* MX6Q_PAD_DI0_DISP_CLK__IPU2_DI0_DSP_CLK */ - IMX_PIN_REG(MX6Q_PAD_DI0_DISP_CLK, 0x0470, 0x015C, 3, 0x0000, 0), /* MX6Q_PAD_DI0_DISP_CLK__MIPI_CR_DPY_OT28 */ - IMX_PIN_REG(MX6Q_PAD_DI0_DISP_CLK, 0x0470, 0x015C, 4, 0x0000, 0), /* MX6Q_PAD_DI0_DISP_CLK__SDMA_DBG_CR_STA0 */ - IMX_PIN_REG(MX6Q_PAD_DI0_DISP_CLK, 0x0470, 0x015C, 5, 0x0000, 0), /* MX6Q_PAD_DI0_DISP_CLK__GPIO_4_16 */ - IMX_PIN_REG(MX6Q_PAD_DI0_DISP_CLK, 0x0470, 0x015C, 6, 0x0000, 0), /* MX6Q_PAD_DI0_DISP_CLK__MMDC_DEBUG_0 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN15, 0x0474, 0x0160, 0, 0x0000, 0), /* MX6Q_PAD_DI0_PIN15__IPU1_DI0_PIN15 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN15, 0x0474, 0x0160, 1, 0x0000, 0), /* MX6Q_PAD_DI0_PIN15__IPU2_DI0_PIN15 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN15, 0x0474, 0x0160, 2, 0x0000, 0), /* MX6Q_PAD_DI0_PIN15__AUDMUX_AUD6_TXC */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN15, 0x0474, 0x0160, 3, 0x0000, 0), /* MX6Q_PAD_DI0_PIN15__MIPI_CR_DPHY_OUT_29 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN15, 0x0474, 0x0160, 4, 0x0000, 0), /* MX6Q_PAD_DI0_PIN15__SDMA_DBG_CORE_STA_1 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN15, 0x0474, 0x0160, 5, 0x0000, 0), /* MX6Q_PAD_DI0_PIN15__GPIO_4_17 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN15, 0x0474, 0x0160, 6, 0x0000, 0), /* MX6Q_PAD_DI0_PIN15__MMDC_MMDC_DEBUG_1 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN2, 0x0478, 0x0164, 0, 0x0000, 0), /* MX6Q_PAD_DI0_PIN2__IPU1_DI0_PIN2 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN2, 0x0478, 0x0164, 1, 0x0000, 0), /* MX6Q_PAD_DI0_PIN2__IPU2_DI0_PIN2 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN2, 0x0478, 0x0164, 2, 0x0000, 0), /* MX6Q_PAD_DI0_PIN2__AUDMUX_AUD6_TXD */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN2, 0x0478, 0x0164, 3, 0x0000, 0), /* MX6Q_PAD_DI0_PIN2__MIPI_CR_DPHY_OUT_30 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN2, 0x0478, 0x0164, 4, 0x0000, 0), /* MX6Q_PAD_DI0_PIN2__SDMA_DBG_CORE_STA_2 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN2, 0x0478, 0x0164, 5, 0x0000, 0), /* MX6Q_PAD_DI0_PIN2__GPIO_4_18 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN2, 0x0478, 0x0164, 6, 0x0000, 0), /* MX6Q_PAD_DI0_PIN2__MMDC_DEBUG_2 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN2, 0x0478, 0x0164, 7, 0x0000, 0), /* MX6Q_PAD_DI0_PIN2__PL301_PER1_HADDR_9 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN3, 0x047C, 0x0168, 0, 0x0000, 0), /* MX6Q_PAD_DI0_PIN3__IPU1_DI0_PIN3 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN3, 0x047C, 0x0168, 1, 0x0000, 0), /* MX6Q_PAD_DI0_PIN3__IPU2_DI0_PIN3 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN3, 0x047C, 0x0168, 2, 0x0000, 0), /* MX6Q_PAD_DI0_PIN3__AUDMUX_AUD6_TXFS */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN3, 0x047C, 0x0168, 3, 0x0000, 0), /* MX6Q_PAD_DI0_PIN3__MIPI_CORE_DPHY_OUT31 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN3, 0x047C, 0x0168, 4, 0x0000, 0), /* MX6Q_PAD_DI0_PIN3__SDMA_DBG_CORE_STA_3 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN3, 0x047C, 0x0168, 5, 0x0000, 0), /* MX6Q_PAD_DI0_PIN3__GPIO_4_19 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN3, 0x047C, 0x0168, 6, 0x0000, 0), /* MX6Q_PAD_DI0_PIN3__MMDC_MMDC_DEBUG_3 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN3, 0x047C, 0x0168, 7, 0x0000, 0), /* MX6Q_PAD_DI0_PIN3__PL301_PER1_HADDR_10 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN4, 0x0480, 0x016C, 0, 0x0000, 0), /* MX6Q_PAD_DI0_PIN4__IPU1_DI0_PIN4 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN4, 0x0480, 0x016C, 1, 0x0000, 0), /* MX6Q_PAD_DI0_PIN4__IPU2_DI0_PIN4 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN4, 0x0480, 0x016C, 2, 0x0000, 0), /* MX6Q_PAD_DI0_PIN4__AUDMUX_AUD6_RXD */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN4, 0x0480, 0x016C, 3, 0x094C, 0), /* MX6Q_PAD_DI0_PIN4__USDHC1_WP */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN4, 0x0480, 0x016C, 4, 0x0000, 0), /* MX6Q_PAD_DI0_PIN4__SDMA_DEBUG_YIELD */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN4, 0x0480, 0x016C, 5, 0x0000, 0), /* MX6Q_PAD_DI0_PIN4__GPIO_4_20 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN4, 0x0480, 0x016C, 6, 0x0000, 0), /* MX6Q_PAD_DI0_PIN4__MMDC_MMDC_DEBUG_4 */ - IMX_PIN_REG(MX6Q_PAD_DI0_PIN4, 0x0480, 0x016C, 7, 0x0000, 0), /* MX6Q_PAD_DI0_PIN4__PL301_PER1_HADDR_11 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT0, 0x0484, 0x0170, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT0, 0x0484, 0x0170, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT0__IPU2_DISP0_DAT_0 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT0, 0x0484, 0x0170, 2, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT0__ECSPI3_SCLK */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT0, 0x0484, 0x0170, 3, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT0__USDHC1_USDHC_DBG_0 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT0, 0x0484, 0x0170, 4, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT0__SDMA_DBG_CORE_RUN */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT0, 0x0484, 0x0170, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT0__GPIO_4_21 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT0, 0x0484, 0x0170, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT0__MMDC_MMDC_DEBUG_5 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT1, 0x0488, 0x0174, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT1, 0x0488, 0x0174, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT1__IPU2_DISP0_DAT_1 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT1, 0x0488, 0x0174, 2, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT1__ECSPI3_MOSI */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT1, 0x0488, 0x0174, 3, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT1__USDHC1_USDHC_DBG_1 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT1, 0x0488, 0x0174, 4, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT1__SDMA_DBG_EVT_CHNSL */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT1, 0x0488, 0x0174, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT1__GPIO_4_22 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT1, 0x0488, 0x0174, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT1__MMDC_DEBUG_6 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT1, 0x0488, 0x0174, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT1__PL301_PER1_HADR_12 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT2, 0x048C, 0x0178, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT2, 0x048C, 0x0178, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT2__IPU2_DISP0_DAT_2 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT2, 0x048C, 0x0178, 2, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT2__ECSPI3_MISO */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT2, 0x048C, 0x0178, 3, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT2__USDHC1_USDHC_DBG_2 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT2, 0x048C, 0x0178, 4, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT2__SDMA_DEBUG_MODE */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT2, 0x048C, 0x0178, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT2__GPIO_4_23 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT2, 0x048C, 0x0178, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT2__MMDC_DEBUG_7 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT2, 0x048C, 0x0178, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT2__PL301_PER1_HADR_13 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT3, 0x0490, 0x017C, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT3, 0x0490, 0x017C, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT3__IPU2_DISP0_DAT_3 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT3, 0x0490, 0x017C, 2, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT3__ECSPI3_SS0 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT3, 0x0490, 0x017C, 3, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT3__USDHC1_USDHC_DBG_3 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT3, 0x0490, 0x017C, 4, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT3__SDMA_DBG_BUS_ERROR */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT3, 0x0490, 0x017C, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT3__GPIO_4_24 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT3, 0x0490, 0x017C, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT3__MMDC_MMDC_DBG_8 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT3, 0x0490, 0x017C, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT3__PL301_PER1_HADR_14 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT4, 0x0494, 0x0180, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT4, 0x0494, 0x0180, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT4__IPU2_DISP0_DAT_4 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT4, 0x0494, 0x0180, 2, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT4__ECSPI3_SS1 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT4, 0x0494, 0x0180, 3, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT4__USDHC1_USDHC_DBG_4 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT4, 0x0494, 0x0180, 4, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT4__SDMA_DEBUG_BUS_RWB */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT4, 0x0494, 0x0180, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT4__GPIO_4_25 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT4, 0x0494, 0x0180, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT4__MMDC_MMDC_DEBUG_9 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT4, 0x0494, 0x0180, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT4__PL301_PER1_HADR_15 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT5, 0x0498, 0x0184, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT5, 0x0498, 0x0184, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT5__IPU2_DISP0_DAT_5 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT5, 0x0498, 0x0184, 2, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT5__ECSPI3_SS2 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT5, 0x0498, 0x0184, 3, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT5__AUDMUX_AUD6_RXFS */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT5, 0x0498, 0x0184, 4, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT5__SDMA_DBG_MCH_DMBUS */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT5, 0x0498, 0x0184, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT5__GPIO_4_26 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT5, 0x0498, 0x0184, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT5__MMDC_DEBUG_10 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT5, 0x0498, 0x0184, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT5__PL301_PER1_HADR_16 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT6, 0x049C, 0x0188, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT6, 0x049C, 0x0188, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT6__IPU2_DISP0_DAT_6 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT6, 0x049C, 0x0188, 2, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT6__ECSPI3_SS3 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT6, 0x049C, 0x0188, 3, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT6__AUDMUX_AUD6_RXC */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT6, 0x049C, 0x0188, 4, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT6__SDMA_DBG_RTBUF_WRT */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT6, 0x049C, 0x0188, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT6__GPIO_4_27 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT6, 0x049C, 0x0188, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT6__MMDC_DEBUG_11 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT6, 0x049C, 0x0188, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT6__PL301_PER1_HADR_17 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT7, 0x04A0, 0x018C, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT7, 0x04A0, 0x018C, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT7__IPU2_DISP0_DAT_7 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT7, 0x04A0, 0x018C, 2, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT7__ECSPI3_RDY */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT7, 0x04A0, 0x018C, 3, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT7__USDHC1_USDHC_DBG_5 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT7, 0x04A0, 0x018C, 4, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT7__SDMA_DBG_EVT_CHN_0 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT7, 0x04A0, 0x018C, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT7__GPIO_4_28 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT7, 0x04A0, 0x018C, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT7__MMDC_DEBUG_12 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT7, 0x04A0, 0x018C, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT7__PL301_PER1_HADR_18 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT8, 0x04A4, 0x0190, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT8, 0x04A4, 0x0190, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT8__IPU2_DISP0_DAT_8 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT8, 0x04A4, 0x0190, 2, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT8__PWM1_PWMO */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT8, 0x04A4, 0x0190, 3, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT8__WDOG1_WDOG_B */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT8, 0x04A4, 0x0190, 4, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT8__SDMA_DBG_EVT_CHN_1 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT8, 0x04A4, 0x0190, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT8__GPIO_4_29 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT8, 0x04A4, 0x0190, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT8__MMDC_DEBUG_13 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT8, 0x04A4, 0x0190, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT8__PL301_PER1_HADR_19 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT9, 0x04A8, 0x0194, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT9, 0x04A8, 0x0194, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT9__IPU2_DISP0_DAT_9 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT9, 0x04A8, 0x0194, 2, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT9__PWM2_PWMO */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT9, 0x04A8, 0x0194, 3, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT9__WDOG2_WDOG_B */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT9, 0x04A8, 0x0194, 4, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT9__SDMA_DBG_EVT_CHN_2 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT9, 0x04A8, 0x0194, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT9__GPIO_4_30 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT9, 0x04A8, 0x0194, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT9__MMDC_DEBUG_14 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT9, 0x04A8, 0x0194, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT9__PL301_PER1_HADR_20 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT10, 0x04AC, 0x0198, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT10, 0x04AC, 0x0198, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT10__IPU2_DISP0_DAT_10 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT10, 0x04AC, 0x0198, 3, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT10__USDHC1_DBG_6 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT10, 0x04AC, 0x0198, 4, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT10__SDMA_DBG_EVT_CHN3 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT10, 0x04AC, 0x0198, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT10__GPIO_4_31 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT10, 0x04AC, 0x0198, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT10__MMDC_DEBUG_15 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT10, 0x04AC, 0x0198, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT10__PL301_PER1_HADR21 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT11, 0x04B0, 0x019C, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT11, 0x04B0, 0x019C, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT11__IPU2_DISP0_DAT_11 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT11, 0x04B0, 0x019C, 3, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT11__USDHC1_USDHC_DBG7 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT11, 0x04B0, 0x019C, 4, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT11__SDMA_DBG_EVT_CHN4 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT11, 0x04B0, 0x019C, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT11__GPIO_5_5 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT11, 0x04B0, 0x019C, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT11__MMDC_DEBUG_16 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT11, 0x04B0, 0x019C, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT11__PL301_PER1_HADR22 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT12, 0x04B4, 0x01A0, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT12, 0x04B4, 0x01A0, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT12__IPU2_DISP0_DAT_12 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT12, 0x04B4, 0x01A0, 3, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT12__RESERVED_RESERVED */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT12, 0x04B4, 0x01A0, 4, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT12__SDMA_DBG_EVT_CHN5 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT12, 0x04B4, 0x01A0, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT12__GPIO_5_6 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT12, 0x04B4, 0x01A0, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT12__MMDC_DEBUG_17 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT12, 0x04B4, 0x01A0, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT12__PL301_PER1_HADR23 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT13, 0x04B8, 0x01A4, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT13, 0x04B8, 0x01A4, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT13__IPU2_DISP0_DAT_13 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT13, 0x04B8, 0x01A4, 3, 0x07D8, 1), /* MX6Q_PAD_DISP0_DAT13__AUDMUX_AUD5_RXFS */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT13, 0x04B8, 0x01A4, 4, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT13__SDMA_DBG_EVT_CHN0 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT13, 0x04B8, 0x01A4, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT13__GPIO_5_7 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT13, 0x04B8, 0x01A4, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT13__MMDC_DEBUG_18 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT13, 0x04B8, 0x01A4, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT13__PL301_PER1_HADR24 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT14, 0x04BC, 0x01A8, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT14, 0x04BC, 0x01A8, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT14__IPU2_DISP0_DAT_14 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT14, 0x04BC, 0x01A8, 3, 0x07D4, 1), /* MX6Q_PAD_DISP0_DAT14__AUDMUX_AUD5_RXC */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT14, 0x04BC, 0x01A8, 4, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT14__SDMA_DBG_EVT_CHN1 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT14, 0x04BC, 0x01A8, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT14__GPIO_5_8 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT14, 0x04BC, 0x01A8, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT14__MMDC_DEBUG_19 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT15, 0x04C0, 0x01AC, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT15, 0x04C0, 0x01AC, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT15__IPU2_DISP0_DAT_15 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT15, 0x04C0, 0x01AC, 2, 0x0804, 1), /* MX6Q_PAD_DISP0_DAT15__ECSPI1_SS1 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT15, 0x04C0, 0x01AC, 3, 0x0820, 1), /* MX6Q_PAD_DISP0_DAT15__ECSPI2_SS1 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT15, 0x04C0, 0x01AC, 4, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT15__SDMA_DBG_EVT_CHN2 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT15, 0x04C0, 0x01AC, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT15__GPIO_5_9 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT15, 0x04C0, 0x01AC, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT15__MMDC_DEBUG_20 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT15, 0x04C0, 0x01AC, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT15__PL301_PER1_HADR25 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT16, 0x04C4, 0x01B0, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT16, 0x04C4, 0x01B0, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT16__IPU2_DISP0_DAT_16 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT16, 0x04C4, 0x01B0, 2, 0x0818, 1), /* MX6Q_PAD_DISP0_DAT16__ECSPI2_MOSI */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT16, 0x04C4, 0x01B0, 3, 0x07DC, 0), /* MX6Q_PAD_DISP0_DAT16__AUDMUX_AUD5_TXC */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT16, 0x04C4, 0x01B0, 4, 0x090C, 0), /* MX6Q_PAD_DISP0_DAT16__SDMA_EXT_EVENT_0 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT16, 0x04C4, 0x01B0, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT16__GPIO_5_10 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT16, 0x04C4, 0x01B0, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT16__MMDC_DEBUG_21 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT16, 0x04C4, 0x01B0, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT16__PL301_PER1_HADR26 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT17, 0x04C8, 0x01B4, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT17, 0x04C8, 0x01B4, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT17__IPU2_DISP0_DAT_17 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT17, 0x04C8, 0x01B4, 2, 0x0814, 1), /* MX6Q_PAD_DISP0_DAT17__ECSPI2_MISO */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT17, 0x04C8, 0x01B4, 3, 0x07D0, 0), /* MX6Q_PAD_DISP0_DAT17__AUDMUX_AUD5_TXD */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT17, 0x04C8, 0x01B4, 4, 0x0910, 0), /* MX6Q_PAD_DISP0_DAT17__SDMA_EXT_EVENT_1 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT17, 0x04C8, 0x01B4, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT17__GPIO_5_11 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT17, 0x04C8, 0x01B4, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT17__MMDC_DEBUG_22 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT17, 0x04C8, 0x01B4, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT17__PL301_PER1_HADR27 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT18, 0x04CC, 0x01B8, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT18, 0x04CC, 0x01B8, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT18__IPU2_DISP0_DAT_18 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT18, 0x04CC, 0x01B8, 2, 0x081C, 1), /* MX6Q_PAD_DISP0_DAT18__ECSPI2_SS0 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT18, 0x04CC, 0x01B8, 3, 0x07E0, 0), /* MX6Q_PAD_DISP0_DAT18__AUDMUX_AUD5_TXFS */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT18, 0x04CC, 0x01B8, 4, 0x07C0, 0), /* MX6Q_PAD_DISP0_DAT18__AUDMUX_AUD4_RXFS */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT18, 0x04CC, 0x01B8, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT18__GPIO_5_12 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT18, 0x04CC, 0x01B8, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT18__MMDC_DEBUG_23 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT18, 0x04CC, 0x01B8, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT18__WEIM_WEIM_CS_2 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT19, 0x04D0, 0x01BC, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT19, 0x04D0, 0x01BC, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT19__IPU2_DISP0_DAT_19 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT19, 0x04D0, 0x01BC, 2, 0x0810, 1), /* MX6Q_PAD_DISP0_DAT19__ECSPI2_SCLK */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT19, 0x04D0, 0x01BC, 3, 0x07CC, 0), /* MX6Q_PAD_DISP0_DAT19__AUDMUX_AUD5_RXD */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT19, 0x04D0, 0x01BC, 4, 0x07BC, 0), /* MX6Q_PAD_DISP0_DAT19__AUDMUX_AUD4_RXC */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT19, 0x04D0, 0x01BC, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT19__GPIO_5_13 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT19, 0x04D0, 0x01BC, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT19__MMDC_DEBUG_24 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT19, 0x04D0, 0x01BC, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT19__WEIM_WEIM_CS_3 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT20, 0x04D4, 0x01C0, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT20, 0x04D4, 0x01C0, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT20__IPU2_DISP0_DAT_20 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT20, 0x04D4, 0x01C0, 2, 0x07F4, 1), /* MX6Q_PAD_DISP0_DAT20__ECSPI1_SCLK */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT20, 0x04D4, 0x01C0, 3, 0x07C4, 0), /* MX6Q_PAD_DISP0_DAT20__AUDMUX_AUD4_TXC */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT20, 0x04D4, 0x01C0, 4, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT20__SDMA_DBG_EVT_CHN7 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT20, 0x04D4, 0x01C0, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT20__GPIO_5_14 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT20, 0x04D4, 0x01C0, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT20__MMDC_DEBUG_25 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT20, 0x04D4, 0x01C0, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT20__PL301_PER1_HADR28 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT21, 0x04D8, 0x01C4, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT21, 0x04D8, 0x01C4, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT21__IPU2_DISP0_DAT_21 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT21, 0x04D8, 0x01C4, 2, 0x07FC, 1), /* MX6Q_PAD_DISP0_DAT21__ECSPI1_MOSI */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT21, 0x04D8, 0x01C4, 3, 0x07B8, 1), /* MX6Q_PAD_DISP0_DAT21__AUDMUX_AUD4_TXD */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT21, 0x04D8, 0x01C4, 4, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT21__SDMA_DBG_BUS_DEV0 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT21, 0x04D8, 0x01C4, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT21__GPIO_5_15 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT21, 0x04D8, 0x01C4, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT21__MMDC_DEBUG_26 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT21, 0x04D8, 0x01C4, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT21__PL301_PER1_HADR29 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT22, 0x04DC, 0x01C8, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT22, 0x04DC, 0x01C8, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT22__IPU2_DISP0_DAT_22 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT22, 0x04DC, 0x01C8, 2, 0x07F8, 1), /* MX6Q_PAD_DISP0_DAT22__ECSPI1_MISO */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT22, 0x04DC, 0x01C8, 3, 0x07C8, 1), /* MX6Q_PAD_DISP0_DAT22__AUDMUX_AUD4_TXFS */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT22, 0x04DC, 0x01C8, 4, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT22__SDMA_DBG_BUS_DEV1 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT22, 0x04DC, 0x01C8, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT22__GPIO_5_16 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT22, 0x04DC, 0x01C8, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT22__MMDC_DEBUG_27 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT22, 0x04DC, 0x01C8, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT22__PL301_PER1_HADR30 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT23, 0x04E0, 0x01CC, 0, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT23, 0x04E0, 0x01CC, 1, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT23__IPU2_DISP0_DAT_23 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT23, 0x04E0, 0x01CC, 2, 0x0800, 1), /* MX6Q_PAD_DISP0_DAT23__ECSPI1_SS0 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT23, 0x04E0, 0x01CC, 3, 0x07B4, 1), /* MX6Q_PAD_DISP0_DAT23__AUDMUX_AUD4_RXD */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT23, 0x04E0, 0x01CC, 4, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT23__SDMA_DBG_BUS_DEV2 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT23, 0x04E0, 0x01CC, 5, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT23__GPIO_5_17 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT23, 0x04E0, 0x01CC, 6, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT23__MMDC_DEBUG_28 */ - IMX_PIN_REG(MX6Q_PAD_DISP0_DAT23, 0x04E0, 0x01CC, 7, 0x0000, 0), /* MX6Q_PAD_DISP0_DAT23__PL301_PER1_HADR31 */ - IMX_PIN_REG(MX6Q_PAD_ENET_MDIO, 0x04E4, 0x01D0, 0, 0x0000, 0), /* MX6Q_PAD_ENET_MDIO__RESERVED_RESERVED */ - IMX_PIN_REG(MX6Q_PAD_ENET_MDIO, 0x04E4, 0x01D0, 1, 0x0840, 0), /* MX6Q_PAD_ENET_MDIO__ENET_MDIO */ - IMX_PIN_REG(MX6Q_PAD_ENET_MDIO, 0x04E4, 0x01D0, 2, 0x086C, 0), /* MX6Q_PAD_ENET_MDIO__ESAI1_SCKR */ - IMX_PIN_REG(MX6Q_PAD_ENET_MDIO, 0x04E4, 0x01D0, 3, 0x0000, 0), /* MX6Q_PAD_ENET_MDIO__SDMA_DEBUG_BUS_DEV3 */ - IMX_PIN_REG(MX6Q_PAD_ENET_MDIO, 0x04E4, 0x01D0, 4, 0x0000, 0), /* MX6Q_PAD_ENET_MDIO__ENET_1588_EVT1_OUT */ - IMX_PIN_REG(MX6Q_PAD_ENET_MDIO, 0x04E4, 0x01D0, 5, 0x0000, 0), /* MX6Q_PAD_ENET_MDIO__GPIO_1_22 */ - IMX_PIN_REG(MX6Q_PAD_ENET_MDIO, 0x04E4, 0x01D0, 6, 0x0000, 0), /* MX6Q_PAD_ENET_MDIO__SPDIF_PLOCK */ - IMX_PIN_REG(MX6Q_PAD_ENET_REF_CLK, 0x04E8, 0x01D4, 0, 0x0000, 0), /* MX6Q_PAD_ENET_REF_CLK__RESERVED_RSRVED */ - IMX_PIN_REG(MX6Q_PAD_ENET_REF_CLK, 0x04E8, 0x01D4, 1, 0x0000, 0), /* MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK */ - IMX_PIN_REG(MX6Q_PAD_ENET_REF_CLK, 0x04E8, 0x01D4, 2, 0x085C, 0), /* MX6Q_PAD_ENET_REF_CLK__ESAI1_FSR */ - IMX_PIN_REG(MX6Q_PAD_ENET_REF_CLK, 0x04E8, 0x01D4, 3, 0x0000, 0), /* MX6Q_PAD_ENET_REF_CLK__SDMA_DBGBUS_DEV4 */ - IMX_PIN_REG(MX6Q_PAD_ENET_REF_CLK, 0x04E8, 0x01D4, 5, 0x0000, 0), /* MX6Q_PAD_ENET_REF_CLK__GPIO_1_23 */ - IMX_PIN_REG(MX6Q_PAD_ENET_REF_CLK, 0x04E8, 0x01D4, 6, 0x0000, 0), /* MX6Q_PAD_ENET_REF_CLK__SPDIF_SRCLK */ - IMX_PIN_REG(MX6Q_PAD_ENET_REF_CLK, 0x04E8, 0x01D4, 7, 0x0000, 0), /* MX6Q_PAD_ENET_REF_CLK__USBPHY1_RX_SQH */ - IMX_PIN_REG(MX6Q_PAD_ENET_RX_ER, 0x04EC, 0x01D8, 1, 0x0000, 0), /* MX6Q_PAD_ENET_RX_ER__ENET_RX_ER */ - IMX_PIN_REG(MX6Q_PAD_ENET_RX_ER, 0x04EC, 0x01D8, 2, 0x0864, 0), /* MX6Q_PAD_ENET_RX_ER__ESAI1_HCKR */ - IMX_PIN_REG(MX6Q_PAD_ENET_RX_ER, 0x04EC, 0x01D8, 3, 0x0914, 1), /* MX6Q_PAD_ENET_RX_ER__SPDIF_IN1 */ - IMX_PIN_REG(MX6Q_PAD_ENET_RX_ER, 0x04EC, 0x01D8, 4, 0x0000, 0), /* MX6Q_PAD_ENET_RX_ER__ENET_1588_EVT2_OUT */ - IMX_PIN_REG(MX6Q_PAD_ENET_RX_ER, 0x04EC, 0x01D8, 5, 0x0000, 0), /* MX6Q_PAD_ENET_RX_ER__GPIO_1_24 */ - IMX_PIN_REG(MX6Q_PAD_ENET_RX_ER, 0x04EC, 0x01D8, 6, 0x0000, 0), /* MX6Q_PAD_ENET_RX_ER__PHY_TDI */ - IMX_PIN_REG(MX6Q_PAD_ENET_RX_ER, 0x04EC, 0x01D8, 7, 0x0000, 0), /* MX6Q_PAD_ENET_RX_ER__USBPHY1_RX_HS_RXD */ - IMX_PIN_REG(MX6Q_PAD_ENET_CRS_DV, 0x04F0, 0x01DC, 0, 0x0000, 0), /* MX6Q_PAD_ENET_CRS_DV__RESERVED_RSRVED */ - IMX_PIN_REG(MX6Q_PAD_ENET_CRS_DV, 0x04F0, 0x01DC, 1, 0x0858, 1), /* MX6Q_PAD_ENET_CRS_DV__ENET_RX_EN */ - IMX_PIN_REG(MX6Q_PAD_ENET_CRS_DV, 0x04F0, 0x01DC, 2, 0x0870, 0), /* MX6Q_PAD_ENET_CRS_DV__ESAI1_SCKT */ - IMX_PIN_REG(MX6Q_PAD_ENET_CRS_DV, 0x04F0, 0x01DC, 3, 0x0918, 1), /* MX6Q_PAD_ENET_CRS_DV__SPDIF_EXTCLK */ - IMX_PIN_REG(MX6Q_PAD_ENET_CRS_DV, 0x04F0, 0x01DC, 5, 0x0000, 0), /* MX6Q_PAD_ENET_CRS_DV__GPIO_1_25 */ - IMX_PIN_REG(MX6Q_PAD_ENET_CRS_DV, 0x04F0, 0x01DC, 6, 0x0000, 0), /* MX6Q_PAD_ENET_CRS_DV__PHY_TDO */ - IMX_PIN_REG(MX6Q_PAD_ENET_CRS_DV, 0x04F0, 0x01DC, 7, 0x0000, 0), /* MX6Q_PAD_ENET_CRS_DV__USBPHY1_RX_FS_RXD */ - IMX_PIN_REG(MX6Q_PAD_ENET_RXD1, 0x04F4, 0x01E0, 0, 0x0908, 0), /* MX6Q_PAD_ENET_RXD1__MLB_MLBSIG */ - IMX_PIN_REG(MX6Q_PAD_ENET_RXD1, 0x04F4, 0x01E0, 1, 0x084C, 1), /* MX6Q_PAD_ENET_RXD1__ENET_RDATA_1 */ - IMX_PIN_REG(MX6Q_PAD_ENET_RXD1, 0x04F4, 0x01E0, 2, 0x0860, 0), /* MX6Q_PAD_ENET_RXD1__ESAI1_FST */ - IMX_PIN_REG(MX6Q_PAD_ENET_RXD1, 0x04F4, 0x01E0, 4, 0x0000, 0), /* MX6Q_PAD_ENET_RXD1__ENET_1588_EVT3_OUT */ - IMX_PIN_REG(MX6Q_PAD_ENET_RXD1, 0x04F4, 0x01E0, 5, 0x0000, 0), /* MX6Q_PAD_ENET_RXD1__GPIO_1_26 */ - IMX_PIN_REG(MX6Q_PAD_ENET_RXD1, 0x04F4, 0x01E0, 6, 0x0000, 0), /* MX6Q_PAD_ENET_RXD1__PHY_TCK */ - IMX_PIN_REG(MX6Q_PAD_ENET_RXD1, 0x04F4, 0x01E0, 7, 0x0000, 0), /* MX6Q_PAD_ENET_RXD1__USBPHY1_RX_DISCON */ - IMX_PIN_REG(MX6Q_PAD_ENET_RXD0, 0x04F8, 0x01E4, 0, 0x0000, 0), /* MX6Q_PAD_ENET_RXD0__OSC32K_32K_OUT */ - IMX_PIN_REG(MX6Q_PAD_ENET_RXD0, 0x04F8, 0x01E4, 1, 0x0848, 1), /* MX6Q_PAD_ENET_RXD0__ENET_RDATA_0 */ - IMX_PIN_REG(MX6Q_PAD_ENET_RXD0, 0x04F8, 0x01E4, 2, 0x0868, 0), /* MX6Q_PAD_ENET_RXD0__ESAI1_HCKT */ - IMX_PIN_REG(MX6Q_PAD_ENET_RXD0, 0x04F8, 0x01E4, 3, 0x0000, 0), /* MX6Q_PAD_ENET_RXD0__SPDIF_OUT1 */ - IMX_PIN_REG(MX6Q_PAD_ENET_RXD0, 0x04F8, 0x01E4, 5, 0x0000, 0), /* MX6Q_PAD_ENET_RXD0__GPIO_1_27 */ - IMX_PIN_REG(MX6Q_PAD_ENET_RXD0, 0x04F8, 0x01E4, 6, 0x0000, 0), /* MX6Q_PAD_ENET_RXD0__PHY_TMS */ - IMX_PIN_REG(MX6Q_PAD_ENET_RXD0, 0x04F8, 0x01E4, 7, 0x0000, 0), /* MX6Q_PAD_ENET_RXD0__USBPHY1_PLL_CK20DIV */ - IMX_PIN_REG(MX6Q_PAD_ENET_TX_EN, 0x04FC, 0x01E8, 0, 0x0000, 0), /* MX6Q_PAD_ENET_TX_EN__RESERVED_RSRVED */ - IMX_PIN_REG(MX6Q_PAD_ENET_TX_EN, 0x04FC, 0x01E8, 1, 0x0000, 0), /* MX6Q_PAD_ENET_TX_EN__ENET_TX_EN */ - IMX_PIN_REG(MX6Q_PAD_ENET_TX_EN, 0x04FC, 0x01E8, 2, 0x0880, 0), /* MX6Q_PAD_ENET_TX_EN__ESAI1_TX3_RX2 */ - IMX_PIN_REG(MX6Q_PAD_ENET_TX_EN, 0x04FC, 0x01E8, 5, 0x0000, 0), /* MX6Q_PAD_ENET_TX_EN__GPIO_1_28 */ - IMX_PIN_REG(MX6Q_PAD_ENET_TX_EN, 0x04FC, 0x01E8, 6, 0x0000, 0), /* MX6Q_PAD_ENET_TX_EN__SATA_PHY_TDI */ - IMX_PIN_REG(MX6Q_PAD_ENET_TX_EN, 0x04FC, 0x01E8, 7, 0x0000, 0), /* MX6Q_PAD_ENET_TX_EN__USBPHY2_RX_SQH */ - IMX_PIN_REG(MX6Q_PAD_ENET_TXD1, 0x0500, 0x01EC, 0, 0x0900, 0), /* MX6Q_PAD_ENET_TXD1__MLB_MLBCLK */ - IMX_PIN_REG(MX6Q_PAD_ENET_TXD1, 0x0500, 0x01EC, 1, 0x0000, 0), /* MX6Q_PAD_ENET_TXD1__ENET_TDATA_1 */ - IMX_PIN_REG(MX6Q_PAD_ENET_TXD1, 0x0500, 0x01EC, 2, 0x087C, 0), /* MX6Q_PAD_ENET_TXD1__ESAI1_TX2_RX3 */ - IMX_PIN_REG(MX6Q_PAD_ENET_TXD1, 0x0500, 0x01EC, 4, 0x0000, 0), /* MX6Q_PAD_ENET_TXD1__ENET_1588_EVENT0_IN */ - IMX_PIN_REG(MX6Q_PAD_ENET_TXD1, 0x0500, 0x01EC, 5, 0x0000, 0), /* MX6Q_PAD_ENET_TXD1__GPIO_1_29 */ - IMX_PIN_REG(MX6Q_PAD_ENET_TXD1, 0x0500, 0x01EC, 6, 0x0000, 0), /* MX6Q_PAD_ENET_TXD1__SATA_PHY_TDO */ - IMX_PIN_REG(MX6Q_PAD_ENET_TXD1, 0x0500, 0x01EC, 7, 0x0000, 0), /* MX6Q_PAD_ENET_TXD1__USBPHY2_RX_HS_RXD */ - IMX_PIN_REG(MX6Q_PAD_ENET_TXD0, 0x0504, 0x01F0, 0, 0x0000, 0), /* MX6Q_PAD_ENET_TXD0__RESERVED_RSRVED */ - IMX_PIN_REG(MX6Q_PAD_ENET_TXD0, 0x0504, 0x01F0, 1, 0x0000, 0), /* MX6Q_PAD_ENET_TXD0__ENET_TDATA_0 */ - IMX_PIN_REG(MX6Q_PAD_ENET_TXD0, 0x0504, 0x01F0, 2, 0x0884, 0), /* MX6Q_PAD_ENET_TXD0__ESAI1_TX4_RX1 */ - IMX_PIN_REG(MX6Q_PAD_ENET_TXD0, 0x0504, 0x01F0, 5, 0x0000, 0), /* MX6Q_PAD_ENET_TXD0__GPIO_1_30 */ - IMX_PIN_REG(MX6Q_PAD_ENET_TXD0, 0x0504, 0x01F0, 6, 0x0000, 0), /* MX6Q_PAD_ENET_TXD0__SATA_PHY_TCK */ - IMX_PIN_REG(MX6Q_PAD_ENET_TXD0, 0x0504, 0x01F0, 7, 0x0000, 0), /* MX6Q_PAD_ENET_TXD0__USBPHY2_RX_FS_RXD */ - IMX_PIN_REG(MX6Q_PAD_ENET_MDC, 0x0508, 0x01F4, 0, 0x0904, 0), /* MX6Q_PAD_ENET_MDC__MLB_MLBDAT */ - IMX_PIN_REG(MX6Q_PAD_ENET_MDC, 0x0508, 0x01F4, 1, 0x0000, 0), /* MX6Q_PAD_ENET_MDC__ENET_MDC */ - IMX_PIN_REG(MX6Q_PAD_ENET_MDC, 0x0508, 0x01F4, 2, 0x0888, 0), /* MX6Q_PAD_ENET_MDC__ESAI1_TX5_RX0 */ - IMX_PIN_REG(MX6Q_PAD_ENET_MDC, 0x0508, 0x01F4, 4, 0x0000, 0), /* MX6Q_PAD_ENET_MDC__ENET_1588_EVENT1_IN */ - IMX_PIN_REG(MX6Q_PAD_ENET_MDC, 0x0508, 0x01F4, 5, 0x0000, 0), /* MX6Q_PAD_ENET_MDC__GPIO_1_31 */ - IMX_PIN_REG(MX6Q_PAD_ENET_MDC, 0x0508, 0x01F4, 6, 0x0000, 0), /* MX6Q_PAD_ENET_MDC__SATA_PHY_TMS */ - IMX_PIN_REG(MX6Q_PAD_ENET_MDC, 0x0508, 0x01F4, 7, 0x0000, 0), /* MX6Q_PAD_ENET_MDC__USBPHY2_RX_DISCON */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D40, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D40__MMDC_DRAM_D_40 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D41, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D41__MMDC_DRAM_D_41 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D42, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D42__MMDC_DRAM_D_42 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D43, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D43__MMDC_DRAM_D_43 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D44, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D44__MMDC_DRAM_D_44 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D45, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D45__MMDC_DRAM_D_45 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D46, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D46__MMDC_DRAM_D_46 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D47, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D47__MMDC_DRAM_D_47 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_SDQS5, 0x050C, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_SDQS5__MMDC_DRAM_SDQS_5 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_DQM5, 0x0510, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_DQM5__MMDC_DRAM_DQM_5 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D32, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D32__MMDC_DRAM_D_32 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D33, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D33__MMDC_DRAM_D_33 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D34, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D34__MMDC_DRAM_D_34 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D35, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D35__MMDC_DRAM_D_35 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D36, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D36__MMDC_DRAM_D_36 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D37, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D37__MMDC_DRAM_D_37 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D38, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D38__MMDC_DRAM_D_38 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D39, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D39__MMDC_DRAM_D_39 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_DQM4, 0x0514, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_DQM4__MMDC_DRAM_DQM_4 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_SDQS4, 0x0518, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_SDQS4__MMDC_DRAM_SDQS_4 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D24, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D24__MMDC_DRAM_D_24 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D25, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D25__MMDC_DRAM_D_25 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D26, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D26__MMDC_DRAM_D_26 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D27, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D27__MMDC_DRAM_D_27 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D28, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D28__MMDC_DRAM_D_28 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D29, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D29__MMDC_DRAM_D_29 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_SDQS3, 0x051C, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_SDQS3__MMDC_DRAM_SDQS_3 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D30, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D30__MMDC_DRAM_D_30 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D31, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D31__MMDC_DRAM_D_31 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_DQM3, 0x0520, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_DQM3__MMDC_DRAM_DQM_3 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D16, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D16__MMDC_DRAM_D_16 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D17, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D17__MMDC_DRAM_D_17 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D18, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D18__MMDC_DRAM_D_18 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D19, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D19__MMDC_DRAM_D_19 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D20, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D20__MMDC_DRAM_D_20 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D21, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D21__MMDC_DRAM_D_21 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D22, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D22__MMDC_DRAM_D_22 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_SDQS2, 0x0524, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_SDQS2__MMDC_DRAM_SDQS_2 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D23, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D23__MMDC_DRAM_D_23 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_DQM2, 0x0528, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_DQM2__MMDC_DRAM_DQM_2 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_A0, 0x052C, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_A0__MMDC_DRAM_A_0 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_A1, 0x0530, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_A1__MMDC_DRAM_A_1 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_A2, 0x0534, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_A2__MMDC_DRAM_A_2 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_A3, 0x0538, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_A3__MMDC_DRAM_A_3 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_A4, 0x053C, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_A4__MMDC_DRAM_A_4 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_A5, 0x0540, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_A5__MMDC_DRAM_A_5 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_A6, 0x0544, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_A6__MMDC_DRAM_A_6 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_A7, 0x0548, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_A7__MMDC_DRAM_A_7 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_A8, 0x054C, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_A8__MMDC_DRAM_A_8 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_A9, 0x0550, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_A9__MMDC_DRAM_A_9 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_A10, 0x0554, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_A10__MMDC_DRAM_A_10 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_A11, 0x0558, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_A11__MMDC_DRAM_A_11 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_A12, 0x055C, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_A12__MMDC_DRAM_A_12 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_A13, 0x0560, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_A13__MMDC_DRAM_A_13 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_A14, 0x0564, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_A14__MMDC_DRAM_A_14 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_A15, 0x0568, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_A15__MMDC_DRAM_A_15 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_CAS, 0x056C, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_CAS__MMDC_DRAM_CAS */ - IMX_PIN_REG(MX6Q_PAD_DRAM_CS0, 0x0570, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_CS0__MMDC_DRAM_CS_0 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_CS1, 0x0574, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_CS1__MMDC_DRAM_CS_1 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_RAS, 0x0578, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_RAS__MMDC_DRAM_RAS */ - IMX_PIN_REG(MX6Q_PAD_DRAM_RESET, 0x057C, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_RESET__MMDC_DRAM_RESET */ - IMX_PIN_REG(MX6Q_PAD_DRAM_SDBA0, 0x0580, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_SDBA0__MMDC_DRAM_SDBA_0 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_SDBA1, 0x0584, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_SDBA1__MMDC_DRAM_SDBA_1 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_SDCLK_0, 0x0588, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_SDCLK_0__MMDC_DRAM_SDCLK0 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_SDBA2, 0x058C, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_SDBA2__MMDC_DRAM_SDBA_2 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_SDCKE0, 0x0590, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_SDCKE0__MMDC_DRAM_SDCKE_0 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_SDCLK_1, 0x0594, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_SDCLK_1__MMDC_DRAM_SDCLK1 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_SDCKE1, 0x0598, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_SDCKE1__MMDC_DRAM_SDCKE_1 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_SDODT0, 0x059C, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_SDODT0__MMDC_DRAM_ODT_0 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_SDODT1, 0x05A0, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_SDODT1__MMDC_DRAM_ODT_1 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_SDWE, 0x05A4, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_SDWE__MMDC_DRAM_SDWE */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D0, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D0__MMDC_DRAM_D_0 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D1, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D1__MMDC_DRAM_D_1 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D2, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D2__MMDC_DRAM_D_2 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D3, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D3__MMDC_DRAM_D_3 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D4, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D4__MMDC_DRAM_D_4 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D5, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D5__MMDC_DRAM_D_5 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_SDQS0, 0x05A8, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_SDQS0__MMDC_DRAM_SDQS_0 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D6, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D6__MMDC_DRAM_D_6 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D7, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D7__MMDC_DRAM_D_7 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_DQM0, 0x05AC, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_DQM0__MMDC_DRAM_DQM_0 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D8, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D8__MMDC_DRAM_D_8 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D9, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D9__MMDC_DRAM_D_9 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D10, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D10__MMDC_DRAM_D_10 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D11, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D11__MMDC_DRAM_D_11 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D12, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D12__MMDC_DRAM_D_12 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D13, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D13__MMDC_DRAM_D_13 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D14, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D14__MMDC_DRAM_D_14 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_SDQS1, 0x05B0, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_SDQS1__MMDC_DRAM_SDQS_1 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D15, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D15__MMDC_DRAM_D_15 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_DQM1, 0x05B4, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_DQM1__MMDC_DRAM_DQM_1 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D48, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D48__MMDC_DRAM_D_48 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D49, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D49__MMDC_DRAM_D_49 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D50, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D50__MMDC_DRAM_D_50 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D51, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D51__MMDC_DRAM_D_51 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D52, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D52__MMDC_DRAM_D_52 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D53, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D53__MMDC_DRAM_D_53 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D54, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D54__MMDC_DRAM_D_54 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D55, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D55__MMDC_DRAM_D_55 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_SDQS6, 0x05B8, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_SDQS6__MMDC_DRAM_SDQS_6 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_DQM6, 0x05BC, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_DQM6__MMDC_DRAM_DQM_6 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D56, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D56__MMDC_DRAM_D_56 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_SDQS7, 0x05C0, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_SDQS7__MMDC_DRAM_SDQS_7 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D57, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D57__MMDC_DRAM_D_57 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D58, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D58__MMDC_DRAM_D_58 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D59, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D59__MMDC_DRAM_D_59 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D60, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D60__MMDC_DRAM_D_60 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_DQM7, 0x05C4, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_DQM7__MMDC_DRAM_DQM_7 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D61, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D61__MMDC_DRAM_D_61 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D62, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D62__MMDC_DRAM_D_62 */ - IMX_PIN_REG(MX6Q_PAD_DRAM_D63, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_DRAM_D63__MMDC_DRAM_D_63 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL0, 0x05C8, 0x01F8, 0, 0x07F4, 2), /* MX6Q_PAD_KEY_COL0__ECSPI1_SCLK */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL0, 0x05C8, 0x01F8, 1, 0x0854, 1), /* MX6Q_PAD_KEY_COL0__ENET_RDATA_3 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL0, 0x05C8, 0x01F8, 2, 0x07DC, 1), /* MX6Q_PAD_KEY_COL0__AUDMUX_AUD5_TXC */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL0, 0x05C8, 0x01F8, 3, 0x0000, 0), /* MX6Q_PAD_KEY_COL0__KPP_COL_0 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL0, 0x05C8, 0x01F8, 4, 0x0000, 0), /* MX6Q_PAD_KEY_COL0__UART4_TXD */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL0, 0x05C8, 0x01F8, 5, 0x0000, 0), /* MX6Q_PAD_KEY_COL0__GPIO_4_6 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL0, 0x05C8, 0x01F8, 6, 0x0000, 0), /* MX6Q_PAD_KEY_COL0__DCIC1_DCIC_OUT */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL0, 0x05C8, 0x01F8, 7, 0x0000, 0), /* MX6Q_PAD_KEY_COL0__SRC_ANY_PU_RST */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW0, 0x05CC, 0x01FC, 0, 0x07FC, 2), /* MX6Q_PAD_KEY_ROW0__ECSPI1_MOSI */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW0, 0x05CC, 0x01FC, 1, 0x0000, 0), /* MX6Q_PAD_KEY_ROW0__ENET_TDATA_3 */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW0, 0x05CC, 0x01FC, 2, 0x07D0, 1), /* MX6Q_PAD_KEY_ROW0__AUDMUX_AUD5_TXD */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW0, 0x05CC, 0x01FC, 3, 0x0000, 0), /* MX6Q_PAD_KEY_ROW0__KPP_ROW_0 */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW0, 0x05CC, 0x01FC, 4, 0x0938, 1), /* MX6Q_PAD_KEY_ROW0__UART4_RXD */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW0, 0x05CC, 0x01FC, 5, 0x0000, 0), /* MX6Q_PAD_KEY_ROW0__GPIO_4_7 */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW0, 0x05CC, 0x01FC, 6, 0x0000, 0), /* MX6Q_PAD_KEY_ROW0__DCIC2_DCIC_OUT */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW0, 0x05CC, 0x01FC, 7, 0x0000, 0), /* MX6Q_PAD_KEY_ROW0__PL301_PER1_HADR_0 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL1, 0x05D0, 0x0200, 0, 0x07F8, 2), /* MX6Q_PAD_KEY_COL1__ECSPI1_MISO */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL1, 0x05D0, 0x0200, 1, 0x0840, 1), /* MX6Q_PAD_KEY_COL1__ENET_MDIO */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL1, 0x05D0, 0x0200, 2, 0x07E0, 1), /* MX6Q_PAD_KEY_COL1__AUDMUX_AUD5_TXFS */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL1, 0x05D0, 0x0200, 3, 0x0000, 0), /* MX6Q_PAD_KEY_COL1__KPP_COL_1 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL1, 0x05D0, 0x0200, 4, 0x0000, 0), /* MX6Q_PAD_KEY_COL1__UART5_TXD */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL1, 0x05D0, 0x0200, 5, 0x0000, 0), /* MX6Q_PAD_KEY_COL1__GPIO_4_8 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL1, 0x05D0, 0x0200, 6, 0x0000, 0), /* MX6Q_PAD_KEY_COL1__USDHC1_VSELECT */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL1, 0x05D0, 0x0200, 7, 0x0000, 0), /* MX6Q_PAD_KEY_COL1__PL301MX_PER1_HADR_1 */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW1, 0x05D4, 0x0204, 0, 0x0800, 2), /* MX6Q_PAD_KEY_ROW1__ECSPI1_SS0 */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW1, 0x05D4, 0x0204, 1, 0x0000, 0), /* MX6Q_PAD_KEY_ROW1__ENET_COL */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW1, 0x05D4, 0x0204, 2, 0x07CC, 1), /* MX6Q_PAD_KEY_ROW1__AUDMUX_AUD5_RXD */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW1, 0x05D4, 0x0204, 3, 0x0000, 0), /* MX6Q_PAD_KEY_ROW1__KPP_ROW_1 */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW1, 0x05D4, 0x0204, 4, 0x0940, 1), /* MX6Q_PAD_KEY_ROW1__UART5_RXD */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW1, 0x05D4, 0x0204, 5, 0x0000, 0), /* MX6Q_PAD_KEY_ROW1__GPIO_4_9 */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW1, 0x05D4, 0x0204, 6, 0x0000, 0), /* MX6Q_PAD_KEY_ROW1__USDHC2_VSELECT */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW1, 0x05D4, 0x0204, 7, 0x0000, 0), /* MX6Q_PAD_KEY_ROW1__PL301_PER1_HADDR_2 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL2, 0x05D8, 0x0208, 0, 0x0804, 2), /* MX6Q_PAD_KEY_COL2__ECSPI1_SS1 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL2, 0x05D8, 0x0208, 1, 0x0850, 1), /* MX6Q_PAD_KEY_COL2__ENET_RDATA_2 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL2, 0x05D8, 0x0208, 2, 0x0000, 0), /* MX6Q_PAD_KEY_COL2__CAN1_TXCAN */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL2, 0x05D8, 0x0208, 3, 0x0000, 0), /* MX6Q_PAD_KEY_COL2__KPP_COL_2 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL2, 0x05D8, 0x0208, 4, 0x0000, 0), /* MX6Q_PAD_KEY_COL2__ENET_MDC */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL2, 0x05D8, 0x0208, 5, 0x0000, 0), /* MX6Q_PAD_KEY_COL2__GPIO_4_10 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL2, 0x05D8, 0x0208, 6, 0x0000, 0), /* MX6Q_PAD_KEY_COL2__USBOH3_H1_PWRCTL_WKP */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL2, 0x05D8, 0x0208, 7, 0x0000, 0), /* MX6Q_PAD_KEY_COL2__PL301_PER1_HADDR_3 */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW2, 0x05DC, 0x020C, 0, 0x0808, 1), /* MX6Q_PAD_KEY_ROW2__ECSPI1_SS2 */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW2, 0x05DC, 0x020C, 1, 0x0000, 0), /* MX6Q_PAD_KEY_ROW2__ENET_TDATA_2 */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW2, 0x05DC, 0x020C, 2, 0x07E4, 0), /* MX6Q_PAD_KEY_ROW2__CAN1_RXCAN */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW2, 0x05DC, 0x020C, 3, 0x0000, 0), /* MX6Q_PAD_KEY_ROW2__KPP_ROW_2 */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW2, 0x05DC, 0x020C, 4, 0x0000, 0), /* MX6Q_PAD_KEY_ROW2__USDHC2_VSELECT */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW2, 0x05DC, 0x020C, 5, 0x0000, 0), /* MX6Q_PAD_KEY_ROW2__GPIO_4_11 */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW2, 0x05DC, 0x020C, 6, 0x088C, 1), /* MX6Q_PAD_KEY_ROW2__HDMI_TX_CEC_LINE */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW2, 0x05DC, 0x020C, 7, 0x0000, 0), /* MX6Q_PAD_KEY_ROW2__PL301_PER1_HADR_4 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL3, 0x05E0, 0x0210, 0, 0x080C, 1), /* MX6Q_PAD_KEY_COL3__ECSPI1_SS3 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL3, 0x05E0, 0x0210, 1, 0x0000, 0), /* MX6Q_PAD_KEY_COL3__ENET_CRS */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL3, 0x05E0, 0x0210, 2, 0x0890, 1), /* MX6Q_PAD_KEY_COL3__HDMI_TX_DDC_SCL */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL3, 0x05E0, 0x0210, 3, 0x0000, 0), /* MX6Q_PAD_KEY_COL3__KPP_COL_3 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL3, 0x05E0, 0x0210, 4, 0x08A0, 1), /* MX6Q_PAD_KEY_COL3__I2C2_SCL */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL3, 0x05E0, 0x0210, 5, 0x0000, 0), /* MX6Q_PAD_KEY_COL3__GPIO_4_12 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL3, 0x05E0, 0x0210, 6, 0x0914, 2), /* MX6Q_PAD_KEY_COL3__SPDIF_IN1 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL3, 0x05E0, 0x0210, 7, 0x0000, 0), /* MX6Q_PAD_KEY_COL3__PL301_PER1_HADR_5 */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW3, 0x05E4, 0x0214, 0, 0x0000, 0), /* MX6Q_PAD_KEY_ROW3__OSC32K_32K_OUT */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW3, 0x05E4, 0x0214, 1, 0x07B0, 0), /* MX6Q_PAD_KEY_ROW3__ASRC_ASRC_EXT_CLK */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW3, 0x05E4, 0x0214, 2, 0x0894, 1), /* MX6Q_PAD_KEY_ROW3__HDMI_TX_DDC_SDA */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW3, 0x05E4, 0x0214, 3, 0x0000, 0), /* MX6Q_PAD_KEY_ROW3__KPP_ROW_3 */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW3, 0x05E4, 0x0214, 4, 0x08A4, 1), /* MX6Q_PAD_KEY_ROW3__I2C2_SDA */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW3, 0x05E4, 0x0214, 5, 0x0000, 0), /* MX6Q_PAD_KEY_ROW3__GPIO_4_13 */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW3, 0x05E4, 0x0214, 6, 0x0000, 0), /* MX6Q_PAD_KEY_ROW3__USDHC1_VSELECT */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW3, 0x05E4, 0x0214, 7, 0x0000, 0), /* MX6Q_PAD_KEY_ROW3__PL301_PER1_HADR_6 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL4, 0x05E8, 0x0218, 0, 0x0000, 0), /* MX6Q_PAD_KEY_COL4__CAN2_TXCAN */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL4, 0x05E8, 0x0218, 1, 0x0000, 0), /* MX6Q_PAD_KEY_COL4__IPU1_SISG_4 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL4, 0x05E8, 0x0218, 2, 0x0944, 1), /* MX6Q_PAD_KEY_COL4__USBOH3_USBOTG_OC */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL4, 0x05E8, 0x0218, 3, 0x0000, 0), /* MX6Q_PAD_KEY_COL4__KPP_COL_4 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL4, 0x05E8, 0x0218, 4, 0x093C, 0), /* MX6Q_PAD_KEY_COL4__UART5_RTS */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL4, 0x05E8, 0x0218, 5, 0x0000, 0), /* MX6Q_PAD_KEY_COL4__GPIO_4_14 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL4, 0x05E8, 0x0218, 6, 0x0000, 0), /* MX6Q_PAD_KEY_COL4__MMDC_DEBUG_49 */ - IMX_PIN_REG(MX6Q_PAD_KEY_COL4, 0x05E8, 0x0218, 7, 0x0000, 0), /* MX6Q_PAD_KEY_COL4__PL301_PER1_HADDR_7 */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW4, 0x05EC, 0x021C, 0, 0x07E8, 0), /* MX6Q_PAD_KEY_ROW4__CAN2_RXCAN */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW4, 0x05EC, 0x021C, 1, 0x0000, 0), /* MX6Q_PAD_KEY_ROW4__IPU1_SISG_5 */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW4, 0x05EC, 0x021C, 2, 0x0000, 0), /* MX6Q_PAD_KEY_ROW4__USBOH3_USBOTG_PWR */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW4, 0x05EC, 0x021C, 3, 0x0000, 0), /* MX6Q_PAD_KEY_ROW4__KPP_ROW_4 */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW4, 0x05EC, 0x021C, 4, 0x093C, 1), /* MX6Q_PAD_KEY_ROW4__UART5_CTS */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW4, 0x05EC, 0x021C, 5, 0x0000, 0), /* MX6Q_PAD_KEY_ROW4__GPIO_4_15 */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW4, 0x05EC, 0x021C, 6, 0x0000, 0), /* MX6Q_PAD_KEY_ROW4__MMDC_DEBUG_50 */ - IMX_PIN_REG(MX6Q_PAD_KEY_ROW4, 0x05EC, 0x021C, 7, 0x0000, 0), /* MX6Q_PAD_KEY_ROW4__PL301_PER1_HADR_8 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_0, 0x05F0, 0x0220, 0, 0x0000, 0), /* MX6Q_PAD_GPIO_0__CCM_CLKO */ - IMX_PIN_REG(MX6Q_PAD_GPIO_0, 0x05F0, 0x0220, 2, 0x08E8, 0), /* MX6Q_PAD_GPIO_0__KPP_COL_5 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_0, 0x05F0, 0x0220, 3, 0x07B0, 1), /* MX6Q_PAD_GPIO_0__ASRC_ASRC_EXT_CLK */ - IMX_PIN_REG(MX6Q_PAD_GPIO_0, 0x05F0, 0x0220, 4, 0x0000, 0), /* MX6Q_PAD_GPIO_0__EPIT1_EPITO */ - IMX_PIN_REG(MX6Q_PAD_GPIO_0, 0x05F0, 0x0220, 5, 0x0000, 0), /* MX6Q_PAD_GPIO_0__GPIO_1_0 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_0, 0x05F0, 0x0220, 6, 0x0000, 0), /* MX6Q_PAD_GPIO_0__USBOH3_USBH1_PWR */ - IMX_PIN_REG(MX6Q_PAD_GPIO_0, 0x05F0, 0x0220, 7, 0x0000, 0), /* MX6Q_PAD_GPIO_0__SNVS_HP_WRAP_SNVS_VIO5 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_1, 0x05F4, 0x0224, 0, 0x086C, 1), /* MX6Q_PAD_GPIO_1__ESAI1_SCKR */ - IMX_PIN_REG(MX6Q_PAD_GPIO_1, 0x05F4, 0x0224, 1, 0x0000, 0), /* MX6Q_PAD_GPIO_1__WDOG2_WDOG_B */ - IMX_PIN_REG(MX6Q_PAD_GPIO_1, 0x05F4, 0x0224, 2, 0x08F4, 0), /* MX6Q_PAD_GPIO_1__KPP_ROW_5 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_1, 0x05F4, 0x0224, 4, 0x0000, 0), /* MX6Q_PAD_GPIO_1__PWM2_PWMO */ - IMX_PIN_REG(MX6Q_PAD_GPIO_1, 0x05F4, 0x0224, 5, 0x0000, 0), /* MX6Q_PAD_GPIO_1__GPIO_1_1 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_1, 0x05F4, 0x0224, 6, 0x0000, 0), /* MX6Q_PAD_GPIO_1__USDHC1_CD */ - IMX_PIN_REG(MX6Q_PAD_GPIO_1, 0x05F4, 0x0224, 7, 0x0000, 0), /* MX6Q_PAD_GPIO_1__SRC_TESTER_ACK */ - IMX_PIN_REG(MX6Q_PAD_GPIO_9, 0x05F8, 0x0228, 0, 0x085C, 1), /* MX6Q_PAD_GPIO_9__ESAI1_FSR */ - IMX_PIN_REG(MX6Q_PAD_GPIO_9, 0x05F8, 0x0228, 1, 0x0000, 0), /* MX6Q_PAD_GPIO_9__WDOG1_WDOG_B */ - IMX_PIN_REG(MX6Q_PAD_GPIO_9, 0x05F8, 0x0228, 2, 0x08EC, 0), /* MX6Q_PAD_GPIO_9__KPP_COL_6 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_9, 0x05F8, 0x0228, 3, 0x0000, 0), /* MX6Q_PAD_GPIO_9__CCM_REF_EN_B */ - IMX_PIN_REG(MX6Q_PAD_GPIO_9, 0x05F8, 0x0228, 4, 0x0000, 0), /* MX6Q_PAD_GPIO_9__PWM1_PWMO */ - IMX_PIN_REG(MX6Q_PAD_GPIO_9, 0x05F8, 0x0228, 5, 0x0000, 0), /* MX6Q_PAD_GPIO_9__GPIO_1_9 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_9, 0x05F8, 0x0228, 6, 0x094C, 1), /* MX6Q_PAD_GPIO_9__USDHC1_WP */ - IMX_PIN_REG(MX6Q_PAD_GPIO_9, 0x05F8, 0x0228, 7, 0x0000, 0), /* MX6Q_PAD_GPIO_9__SRC_EARLY_RST */ - IMX_PIN_REG(MX6Q_PAD_GPIO_3, 0x05FC, 0x022C, 0, 0x0864, 1), /* MX6Q_PAD_GPIO_3__ESAI1_HCKR */ - IMX_PIN_REG(MX6Q_PAD_GPIO_3, 0x05FC, 0x022C, 1, 0x0000, 0), /* MX6Q_PAD_GPIO_3__OBSERVE_MUX_INT_OUT0 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_3, 0x05FC, 0x022C, 2, 0x08A8, 1), /* MX6Q_PAD_GPIO_3__I2C3_SCL */ - IMX_PIN_REG(MX6Q_PAD_GPIO_3, 0x05FC, 0x022C, 3, 0x0000, 0), /* MX6Q_PAD_GPIO_3__ANATOP_24M_OUT */ - IMX_PIN_REG(MX6Q_PAD_GPIO_3, 0x05FC, 0x022C, 4, 0x0000, 0), /* MX6Q_PAD_GPIO_3__CCM_CLKO2 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_3, 0x05FC, 0x022C, 5, 0x0000, 0), /* MX6Q_PAD_GPIO_3__GPIO_1_3 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_3, 0x05FC, 0x022C, 6, 0x0948, 1), /* MX6Q_PAD_GPIO_3__USBOH3_USBH1_OC */ - IMX_PIN_REG(MX6Q_PAD_GPIO_3, 0x05FC, 0x022C, 7, 0x0900, 1), /* MX6Q_PAD_GPIO_3__MLB_MLBCLK */ - IMX_PIN_REG(MX6Q_PAD_GPIO_6, 0x0600, 0x0230, 0, 0x0870, 1), /* MX6Q_PAD_GPIO_6__ESAI1_SCKT */ - IMX_PIN_REG(MX6Q_PAD_GPIO_6, 0x0600, 0x0230, 1, 0x0000, 0), /* MX6Q_PAD_GPIO_6__OBSERVE_MUX_INT_OUT1 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_6, 0x0600, 0x0230, 2, 0x08AC, 1), /* MX6Q_PAD_GPIO_6__I2C3_SDA */ - IMX_PIN_REG(MX6Q_PAD_GPIO_6, 0x0600, 0x0230, 3, 0x0000, 0), /* MX6Q_PAD_GPIO_6__CCM_CCM_OUT_0 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_6, 0x0600, 0x0230, 4, 0x0000, 0), /* MX6Q_PAD_GPIO_6__CSU_CSU_INT_DEB */ - IMX_PIN_REG(MX6Q_PAD_GPIO_6, 0x0600, 0x0230, 5, 0x0000, 0), /* MX6Q_PAD_GPIO_6__GPIO_1_6 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_6, 0x0600, 0x0230, 6, 0x0000, 0), /* MX6Q_PAD_GPIO_6__USDHC2_LCTL */ - IMX_PIN_REG(MX6Q_PAD_GPIO_6, 0x0600, 0x0230, 7, 0x0908, 1), /* MX6Q_PAD_GPIO_6__MLB_MLBSIG */ - IMX_PIN_REG(MX6Q_PAD_GPIO_2, 0x0604, 0x0234, 0, 0x0860, 1), /* MX6Q_PAD_GPIO_2__ESAI1_FST */ - IMX_PIN_REG(MX6Q_PAD_GPIO_2, 0x0604, 0x0234, 1, 0x0000, 0), /* MX6Q_PAD_GPIO_2__OBSERVE_MUX_INT_OUT2 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_2, 0x0604, 0x0234, 2, 0x08F8, 1), /* MX6Q_PAD_GPIO_2__KPP_ROW_6 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_2, 0x0604, 0x0234, 3, 0x0000, 0), /* MX6Q_PAD_GPIO_2__CCM_CCM_OUT_1 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_2, 0x0604, 0x0234, 4, 0x0000, 0), /* MX6Q_PAD_GPIO_2__CSU_CSU_ALARM_AUT_0 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_2, 0x0604, 0x0234, 5, 0x0000, 0), /* MX6Q_PAD_GPIO_2__GPIO_1_2 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_2, 0x0604, 0x0234, 6, 0x0000, 0), /* MX6Q_PAD_GPIO_2__USDHC2_WP */ - IMX_PIN_REG(MX6Q_PAD_GPIO_2, 0x0604, 0x0234, 7, 0x0904, 1), /* MX6Q_PAD_GPIO_2__MLB_MLBDAT */ - IMX_PIN_REG(MX6Q_PAD_GPIO_4, 0x0608, 0x0238, 0, 0x0868, 1), /* MX6Q_PAD_GPIO_4__ESAI1_HCKT */ - IMX_PIN_REG(MX6Q_PAD_GPIO_4, 0x0608, 0x0238, 1, 0x0000, 0), /* MX6Q_PAD_GPIO_4__OBSERVE_MUX_INT_OUT3 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_4, 0x0608, 0x0238, 2, 0x08F0, 1), /* MX6Q_PAD_GPIO_4__KPP_COL_7 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_4, 0x0608, 0x0238, 3, 0x0000, 0), /* MX6Q_PAD_GPIO_4__CCM_CCM_OUT_2 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_4, 0x0608, 0x0238, 4, 0x0000, 0), /* MX6Q_PAD_GPIO_4__CSU_CSU_ALARM_AUT_1 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_4, 0x0608, 0x0238, 5, 0x0000, 0), /* MX6Q_PAD_GPIO_4__GPIO_1_4 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_4, 0x0608, 0x0238, 6, 0x0000, 0), /* MX6Q_PAD_GPIO_4__USDHC2_CD */ - IMX_PIN_REG(MX6Q_PAD_GPIO_4, 0x0608, 0x0238, 7, 0x0000, 0), /* MX6Q_PAD_GPIO_4__OCOTP_CRL_WRAR_FUSE_LA */ - IMX_PIN_REG(MX6Q_PAD_GPIO_5, 0x060C, 0x023C, 0, 0x087C, 1), /* MX6Q_PAD_GPIO_5__ESAI1_TX2_RX3 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_5, 0x060C, 0x023C, 1, 0x0000, 0), /* MX6Q_PAD_GPIO_5__OBSERVE_MUX_INT_OUT4 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_5, 0x060C, 0x023C, 2, 0x08FC, 1), /* MX6Q_PAD_GPIO_5__KPP_ROW_7 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_5, 0x060C, 0x023C, 3, 0x0000, 0), /* MX6Q_PAD_GPIO_5__CCM_CLKO */ - IMX_PIN_REG(MX6Q_PAD_GPIO_5, 0x060C, 0x023C, 4, 0x0000, 0), /* MX6Q_PAD_GPIO_5__CSU_CSU_ALARM_AUT_2 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_5, 0x060C, 0x023C, 5, 0x0000, 0), /* MX6Q_PAD_GPIO_5__GPIO_1_5 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_5, 0x060C, 0x023C, 6, 0x08A8, 2), /* MX6Q_PAD_GPIO_5__I2C3_SCL */ - IMX_PIN_REG(MX6Q_PAD_GPIO_5, 0x060C, 0x023C, 7, 0x0000, 0), /* MX6Q_PAD_GPIO_5__CHEETAH_EVENTI */ - IMX_PIN_REG(MX6Q_PAD_GPIO_7, 0x0610, 0x0240, 0, 0x0884, 1), /* MX6Q_PAD_GPIO_7__ESAI1_TX4_RX1 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_7, 0x0610, 0x0240, 1, 0x0000, 0), /* MX6Q_PAD_GPIO_7__ECSPI5_RDY */ - IMX_PIN_REG(MX6Q_PAD_GPIO_7, 0x0610, 0x0240, 2, 0x0000, 0), /* MX6Q_PAD_GPIO_7__EPIT1_EPITO */ - IMX_PIN_REG(MX6Q_PAD_GPIO_7, 0x0610, 0x0240, 3, 0x0000, 0), /* MX6Q_PAD_GPIO_7__CAN1_TXCAN */ - IMX_PIN_REG(MX6Q_PAD_GPIO_7, 0x0610, 0x0240, 4, 0x0000, 0), /* MX6Q_PAD_GPIO_7__UART2_TXD */ - IMX_PIN_REG(MX6Q_PAD_GPIO_7, 0x0610, 0x0240, 5, 0x0000, 0), /* MX6Q_PAD_GPIO_7__GPIO_1_7 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_7, 0x0610, 0x0240, 6, 0x0000, 0), /* MX6Q_PAD_GPIO_7__SPDIF_PLOCK */ - IMX_PIN_REG(MX6Q_PAD_GPIO_7, 0x0610, 0x0240, 7, 0x0000, 0), /* MX6Q_PAD_GPIO_7__USBOH3_OTGUSB_HST_MODE */ - IMX_PIN_REG(MX6Q_PAD_GPIO_8, 0x0614, 0x0244, 0, 0x0888, 1), /* MX6Q_PAD_GPIO_8__ESAI1_TX5_RX0 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_8, 0x0614, 0x0244, 1, 0x0000, 0), /* MX6Q_PAD_GPIO_8__ANATOP_ANATOP_32K_OUT */ - IMX_PIN_REG(MX6Q_PAD_GPIO_8, 0x0614, 0x0244, 2, 0x0000, 0), /* MX6Q_PAD_GPIO_8__EPIT2_EPITO */ - IMX_PIN_REG(MX6Q_PAD_GPIO_8, 0x0614, 0x0244, 3, 0x07E4, 1), /* MX6Q_PAD_GPIO_8__CAN1_RXCAN */ - IMX_PIN_REG(MX6Q_PAD_GPIO_8, 0x0614, 0x0244, 4, 0x0928, 3), /* MX6Q_PAD_GPIO_8__UART2_RXD */ - IMX_PIN_REG(MX6Q_PAD_GPIO_8, 0x0614, 0x0244, 5, 0x0000, 0), /* MX6Q_PAD_GPIO_8__GPIO_1_8 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_8, 0x0614, 0x0244, 6, 0x0000, 0), /* MX6Q_PAD_GPIO_8__SPDIF_SRCLK */ - IMX_PIN_REG(MX6Q_PAD_GPIO_8, 0x0614, 0x0244, 7, 0x0000, 0), /* MX6Q_PAD_GPIO_8__USBOH3_OTG_PWRCTL_WAK */ - IMX_PIN_REG(MX6Q_PAD_GPIO_16, 0x0618, 0x0248, 0, 0x0880, 1), /* MX6Q_PAD_GPIO_16__ESAI1_TX3_RX2 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_16, 0x0618, 0x0248, 1, 0x0000, 0), /* MX6Q_PAD_GPIO_16__ENET_1588_EVENT2_IN */ - IMX_PIN_REG(MX6Q_PAD_GPIO_16, 0x0618, 0x0248, 2, 0x083C, 1), /* MX6Q_PAD_GPIO_16__ENET_ETHERNET_REF_OUT */ - IMX_PIN_REG(MX6Q_PAD_GPIO_16, 0x0618, 0x0248, 3, 0x0000, 0), /* MX6Q_PAD_GPIO_16__USDHC1_LCTL */ - IMX_PIN_REG(MX6Q_PAD_GPIO_16, 0x0618, 0x0248, 4, 0x0914, 3), /* MX6Q_PAD_GPIO_16__SPDIF_IN1 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_16, 0x0618, 0x0248, 5, 0x0000, 0), /* MX6Q_PAD_GPIO_16__GPIO_7_11 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_16, 0x0618, 0x0248, 6, 0x08AC, 2), /* MX6Q_PAD_GPIO_16__I2C3_SDA */ - IMX_PIN_REG(MX6Q_PAD_GPIO_16, 0x0618, 0x0248, 7, 0x0000, 0), /* MX6Q_PAD_GPIO_16__SJC_DE_B */ - IMX_PIN_REG(MX6Q_PAD_GPIO_17, 0x061C, 0x024C, 0, 0x0874, 0), /* MX6Q_PAD_GPIO_17__ESAI1_TX0 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_17, 0x061C, 0x024C, 1, 0x0000, 0), /* MX6Q_PAD_GPIO_17__ENET_1588_EVENT3_IN */ - IMX_PIN_REG(MX6Q_PAD_GPIO_17, 0x061C, 0x024C, 2, 0x07F0, 1), /* MX6Q_PAD_GPIO_17__CCM_PMIC_RDY */ - IMX_PIN_REG(MX6Q_PAD_GPIO_17, 0x061C, 0x024C, 3, 0x090C, 1), /* MX6Q_PAD_GPIO_17__SDMA_SDMA_EXT_EVENT_0 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_17, 0x061C, 0x024C, 4, 0x0000, 0), /* MX6Q_PAD_GPIO_17__SPDIF_OUT1 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_17, 0x061C, 0x024C, 5, 0x0000, 0), /* MX6Q_PAD_GPIO_17__GPIO_7_12 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_17, 0x061C, 0x024C, 7, 0x0000, 0), /* MX6Q_PAD_GPIO_17__SJC_JTAG_ACT */ - IMX_PIN_REG(MX6Q_PAD_GPIO_18, 0x0620, 0x0250, 0, 0x0878, 0), /* MX6Q_PAD_GPIO_18__ESAI1_TX1 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_18, 0x0620, 0x0250, 1, 0x0844, 1), /* MX6Q_PAD_GPIO_18__ENET_RX_CLK */ - IMX_PIN_REG(MX6Q_PAD_GPIO_18, 0x0620, 0x0250, 2, 0x0000, 0), /* MX6Q_PAD_GPIO_18__USDHC3_VSELECT */ - IMX_PIN_REG(MX6Q_PAD_GPIO_18, 0x0620, 0x0250, 3, 0x0910, 1), /* MX6Q_PAD_GPIO_18__SDMA_SDMA_EXT_EVENT_1 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_18, 0x0620, 0x0250, 4, 0x07B0, 2), /* MX6Q_PAD_GPIO_18__ASRC_ASRC_EXT_CLK */ - IMX_PIN_REG(MX6Q_PAD_GPIO_18, 0x0620, 0x0250, 5, 0x0000, 0), /* MX6Q_PAD_GPIO_18__GPIO_7_13 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_18, 0x0620, 0x0250, 6, 0x0000, 0), /* MX6Q_PAD_GPIO_18__SNVS_HP_WRA_SNVS_VIO5 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_18, 0x0620, 0x0250, 7, 0x0000, 0), /* MX6Q_PAD_GPIO_18__SRC_SYSTEM_RST */ - IMX_PIN_REG(MX6Q_PAD_GPIO_19, 0x0624, 0x0254, 0, 0x08E8, 1), /* MX6Q_PAD_GPIO_19__KPP_COL_5 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_19, 0x0624, 0x0254, 1, 0x0000, 0), /* MX6Q_PAD_GPIO_19__ENET_1588_EVENT0_OUT */ - IMX_PIN_REG(MX6Q_PAD_GPIO_19, 0x0624, 0x0254, 2, 0x0000, 0), /* MX6Q_PAD_GPIO_19__SPDIF_OUT1 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_19, 0x0624, 0x0254, 3, 0x0000, 0), /* MX6Q_PAD_GPIO_19__CCM_CLKO */ - IMX_PIN_REG(MX6Q_PAD_GPIO_19, 0x0624, 0x0254, 4, 0x0000, 0), /* MX6Q_PAD_GPIO_19__ECSPI1_RDY */ - IMX_PIN_REG(MX6Q_PAD_GPIO_19, 0x0624, 0x0254, 5, 0x0000, 0), /* MX6Q_PAD_GPIO_19__GPIO_4_5 */ - IMX_PIN_REG(MX6Q_PAD_GPIO_19, 0x0624, 0x0254, 6, 0x0000, 0), /* MX6Q_PAD_GPIO_19__ENET_TX_ER */ - IMX_PIN_REG(MX6Q_PAD_GPIO_19, 0x0624, 0x0254, 7, 0x0000, 0), /* MX6Q_PAD_GPIO_19__SRC_INT_BOOT */ - IMX_PIN_REG(MX6Q_PAD_CSI0_PIXCLK, 0x0628, 0x0258, 0, 0x0000, 0), /* MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK */ - IMX_PIN_REG(MX6Q_PAD_CSI0_PIXCLK, 0x0628, 0x0258, 2, 0x0000, 0), /* MX6Q_PAD_CSI0_PIXCLK__PCIE_CTRL_MUX_12 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_PIXCLK, 0x0628, 0x0258, 4, 0x0000, 0), /* MX6Q_PAD_CSI0_PIXCLK__SDMA_DEBUG_PC_0 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_PIXCLK, 0x0628, 0x0258, 5, 0x0000, 0), /* MX6Q_PAD_CSI0_PIXCLK__GPIO_5_18 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_PIXCLK, 0x0628, 0x0258, 6, 0x0000, 0), /* MX6Q_PAD_CSI0_PIXCLK___MMDC_DEBUG_29 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_PIXCLK, 0x0628, 0x0258, 7, 0x0000, 0), /* MX6Q_PAD_CSI0_PIXCLK__CHEETAH_EVENTO */ - IMX_PIN_REG(MX6Q_PAD_CSI0_MCLK, 0x062C, 0x025C, 0, 0x0000, 0), /* MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC */ - IMX_PIN_REG(MX6Q_PAD_CSI0_MCLK, 0x062C, 0x025C, 2, 0x0000, 0), /* MX6Q_PAD_CSI0_MCLK__PCIE_CTRL_MUX_13 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_MCLK, 0x062C, 0x025C, 3, 0x0000, 0), /* MX6Q_PAD_CSI0_MCLK__CCM_CLKO */ - IMX_PIN_REG(MX6Q_PAD_CSI0_MCLK, 0x062C, 0x025C, 4, 0x0000, 0), /* MX6Q_PAD_CSI0_MCLK__SDMA_DEBUG_PC_1 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_MCLK, 0x062C, 0x025C, 5, 0x0000, 0), /* MX6Q_PAD_CSI0_MCLK__GPIO_5_19 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_MCLK, 0x062C, 0x025C, 6, 0x0000, 0), /* MX6Q_PAD_CSI0_MCLK__MMDC_MMDC_DEBUG_30 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_MCLK, 0x062C, 0x025C, 7, 0x0000, 0), /* MX6Q_PAD_CSI0_MCLK__CHEETAH_TRCTL */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DATA_EN, 0x0630, 0x0260, 0, 0x0000, 0), /* MX6Q_PAD_CSI0_DATA_EN__IPU1_CSI0_DA_EN */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DATA_EN, 0x0630, 0x0260, 1, 0x0000, 0), /* MX6Q_PAD_CSI0_DATA_EN__WEIM_WEIM_D_0 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DATA_EN, 0x0630, 0x0260, 2, 0x0000, 0), /* MX6Q_PAD_CSI0_DATA_EN__PCIE_CTRL_MUX_14 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DATA_EN, 0x0630, 0x0260, 4, 0x0000, 0), /* MX6Q_PAD_CSI0_DATA_EN__SDMA_DEBUG_PC_2 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DATA_EN, 0x0630, 0x0260, 5, 0x0000, 0), /* MX6Q_PAD_CSI0_DATA_EN__GPIO_5_20 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DATA_EN, 0x0630, 0x0260, 6, 0x0000, 0), /* MX6Q_PAD_CSI0_DATA_EN__MMDC_DEBUG_31 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DATA_EN, 0x0630, 0x0260, 7, 0x0000, 0), /* MX6Q_PAD_CSI0_DATA_EN__CHEETAH_TRCLK */ - IMX_PIN_REG(MX6Q_PAD_CSI0_VSYNC, 0x0634, 0x0264, 0, 0x0000, 0), /* MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC */ - IMX_PIN_REG(MX6Q_PAD_CSI0_VSYNC, 0x0634, 0x0264, 1, 0x0000, 0), /* MX6Q_PAD_CSI0_VSYNC__WEIM_WEIM_D_1 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_VSYNC, 0x0634, 0x0264, 2, 0x0000, 0), /* MX6Q_PAD_CSI0_VSYNC__PCIE_CTRL_MUX_15 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_VSYNC, 0x0634, 0x0264, 4, 0x0000, 0), /* MX6Q_PAD_CSI0_VSYNC__SDMA_DEBUG_PC_3 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_VSYNC, 0x0634, 0x0264, 5, 0x0000, 0), /* MX6Q_PAD_CSI0_VSYNC__GPIO_5_21 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_VSYNC, 0x0634, 0x0264, 6, 0x0000, 0), /* MX6Q_PAD_CSI0_VSYNC__MMDC_DEBUG_32 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_VSYNC, 0x0634, 0x0264, 7, 0x0000, 0), /* MX6Q_PAD_CSI0_VSYNC__CHEETAH_TRACE_0 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT4, 0x0638, 0x0268, 0, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT4__IPU1_CSI0_D_4 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT4, 0x0638, 0x0268, 1, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT4__WEIM_WEIM_D_2 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT4, 0x0638, 0x0268, 2, 0x07F4, 3), /* MX6Q_PAD_CSI0_DAT4__ECSPI1_SCLK */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT4, 0x0638, 0x0268, 3, 0x08E8, 2), /* MX6Q_PAD_CSI0_DAT4__KPP_COL_5 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT4, 0x0638, 0x0268, 4, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT4, 0x0638, 0x0268, 5, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT4__GPIO_5_22 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT4, 0x0638, 0x0268, 6, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT4__MMDC_DEBUG_43 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT4, 0x0638, 0x0268, 7, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT4__CHEETAH_TRACE_1 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT5, 0x063C, 0x026C, 0, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT5__IPU1_CSI0_D_5 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT5, 0x063C, 0x026C, 1, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT5__WEIM_WEIM_D_3 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT5, 0x063C, 0x026C, 2, 0x07FC, 3), /* MX6Q_PAD_CSI0_DAT5__ECSPI1_MOSI */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT5, 0x063C, 0x026C, 3, 0x08F4, 1), /* MX6Q_PAD_CSI0_DAT5__KPP_ROW_5 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT5, 0x063C, 0x026C, 4, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT5, 0x063C, 0x026C, 5, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT5__GPIO_5_23 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT5, 0x063C, 0x026C, 6, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT5__MMDC_MMDC_DEBUG_44 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT5, 0x063C, 0x026C, 7, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT5__CHEETAH_TRACE_2 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT6, 0x0640, 0x0270, 0, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT6__IPU1_CSI0_D_6 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT6, 0x0640, 0x0270, 1, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT6__WEIM_WEIM_D_4 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT6, 0x0640, 0x0270, 2, 0x07F8, 3), /* MX6Q_PAD_CSI0_DAT6__ECSPI1_MISO */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT6, 0x0640, 0x0270, 3, 0x08EC, 1), /* MX6Q_PAD_CSI0_DAT6__KPP_COL_6 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT6, 0x0640, 0x0270, 4, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT6, 0x0640, 0x0270, 5, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT6__GPIO_5_24 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT6, 0x0640, 0x0270, 6, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT6__MMDC_MMDC_DEBUG_45 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT6, 0x0640, 0x0270, 7, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT6__CHEETAH_TRACE_3 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT7, 0x0644, 0x0274, 0, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT7__IPU1_CSI0_D_7 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT7, 0x0644, 0x0274, 1, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT7__WEIM_WEIM_D_5 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT7, 0x0644, 0x0274, 2, 0x0800, 3), /* MX6Q_PAD_CSI0_DAT7__ECSPI1_SS0 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT7, 0x0644, 0x0274, 3, 0x08F8, 2), /* MX6Q_PAD_CSI0_DAT7__KPP_ROW_6 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT7, 0x0644, 0x0274, 4, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT7, 0x0644, 0x0274, 5, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT7__GPIO_5_25 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT7, 0x0644, 0x0274, 6, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT7__MMDC_MMDC_DEBUG_46 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT7, 0x0644, 0x0274, 7, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT7__CHEETAH_TRACE_4 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT8, 0x0648, 0x0278, 0, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT8__IPU1_CSI0_D_8 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT8, 0x0648, 0x0278, 1, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT8__WEIM_WEIM_D_6 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT8, 0x0648, 0x0278, 2, 0x0810, 2), /* MX6Q_PAD_CSI0_DAT8__ECSPI2_SCLK */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT8, 0x0648, 0x0278, 3, 0x08F0, 2), /* MX6Q_PAD_CSI0_DAT8__KPP_COL_7 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT8, 0x0648, 0x0278, 4, 0x089C, 1), /* MX6Q_PAD_CSI0_DAT8__I2C1_SDA */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT8, 0x0648, 0x0278, 5, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT8__GPIO_5_26 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT8, 0x0648, 0x0278, 6, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT8__MMDC_MMDC_DEBUG_47 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT8, 0x0648, 0x0278, 7, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT8__CHEETAH_TRACE_5 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT9, 0x064C, 0x027C, 0, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT9__IPU1_CSI0_D_9 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT9, 0x064C, 0x027C, 1, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT9__WEIM_WEIM_D_7 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT9, 0x064C, 0x027C, 2, 0x0818, 2), /* MX6Q_PAD_CSI0_DAT9__ECSPI2_MOSI */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT9, 0x064C, 0x027C, 3, 0x08FC, 2), /* MX6Q_PAD_CSI0_DAT9__KPP_ROW_7 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT9, 0x064C, 0x027C, 4, 0x0898, 1), /* MX6Q_PAD_CSI0_DAT9__I2C1_SCL */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT9, 0x064C, 0x027C, 5, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT9__GPIO_5_27 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT9, 0x064C, 0x027C, 6, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT9__MMDC_MMDC_DEBUG_48 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT9, 0x064C, 0x027C, 7, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT9__CHEETAH_TRACE_6 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT10, 0x0650, 0x0280, 0, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT10__IPU1_CSI0_D_10 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT10, 0x0650, 0x0280, 1, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT10__AUDMUX_AUD3_RXC */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT10, 0x0650, 0x0280, 2, 0x0814, 2), /* MX6Q_PAD_CSI0_DAT10__ECSPI2_MISO */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT10, 0x0650, 0x0280, 3, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT10__UART1_TXD */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT10, 0x0650, 0x0280, 4, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT10__SDMA_DEBUG_PC_4 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT10, 0x0650, 0x0280, 5, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT10__GPIO_5_28 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT10, 0x0650, 0x0280, 6, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT10__MMDC_MMDC_DEBUG_33 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT10, 0x0650, 0x0280, 7, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT10__CHEETAH_TRACE_7 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT11, 0x0654, 0x0284, 0, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT11__IPU1_CSI0_D_11 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT11, 0x0654, 0x0284, 1, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT11__AUDMUX_AUD3_RXFS */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT11, 0x0654, 0x0284, 2, 0x081C, 2), /* MX6Q_PAD_CSI0_DAT11__ECSPI2_SS0 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT11, 0x0654, 0x0284, 3, 0x0920, 1), /* MX6Q_PAD_CSI0_DAT11__UART1_RXD */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT11, 0x0654, 0x0284, 4, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT11__SDMA_DEBUG_PC_5 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT11, 0x0654, 0x0284, 5, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT11__GPIO_5_29 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT11, 0x0654, 0x0284, 6, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT11__MMDC_MMDC_DEBUG_34 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT11, 0x0654, 0x0284, 7, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT11__CHEETAH_TRACE_8 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT12, 0x0658, 0x0288, 0, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT12, 0x0658, 0x0288, 1, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT12__WEIM_WEIM_D_8 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT12, 0x0658, 0x0288, 2, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT12__PCIE_CTRL_MUX_16 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT12, 0x0658, 0x0288, 3, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT12__UART4_TXD */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT12, 0x0658, 0x0288, 4, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT12__SDMA_DEBUG_PC_6 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT12, 0x0658, 0x0288, 5, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT12__GPIO_5_30 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT12, 0x0658, 0x0288, 6, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT12__MMDC_MMDC_DEBUG_35 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT12, 0x0658, 0x0288, 7, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT12__CHEETAH_TRACE_9 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT13, 0x065C, 0x028C, 0, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT13, 0x065C, 0x028C, 1, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT13__WEIM_WEIM_D_9 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT13, 0x065C, 0x028C, 2, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT13__PCIE_CTRL_MUX_17 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT13, 0x065C, 0x028C, 3, 0x0938, 3), /* MX6Q_PAD_CSI0_DAT13__UART4_RXD */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT13, 0x065C, 0x028C, 4, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT13__SDMA_DEBUG_PC_7 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT13, 0x065C, 0x028C, 5, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT13__GPIO_5_31 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT13, 0x065C, 0x028C, 6, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT13__MMDC_MMDC_DEBUG_36 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT13, 0x065C, 0x028C, 7, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT13__CHEETAH_TRACE_10 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT14, 0x0660, 0x0290, 0, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT14, 0x0660, 0x0290, 1, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT14__WEIM_WEIM_D_10 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT14, 0x0660, 0x0290, 2, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT14__PCIE_CTRL_MUX_18 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT14, 0x0660, 0x0290, 3, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT14__UART5_TXD */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT14, 0x0660, 0x0290, 4, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT14__SDMA_DEBUG_PC_8 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT14, 0x0660, 0x0290, 5, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT14__GPIO_6_0 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT14, 0x0660, 0x0290, 6, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT14__MMDC_MMDC_DEBUG_37 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT14, 0x0660, 0x0290, 7, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT14__CHEETAH_TRACE_11 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT15, 0x0664, 0x0294, 0, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT15, 0x0664, 0x0294, 1, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT15__WEIM_WEIM_D_11 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT15, 0x0664, 0x0294, 2, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT15__PCIE_CTRL_MUX_19 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT15, 0x0664, 0x0294, 3, 0x0940, 3), /* MX6Q_PAD_CSI0_DAT15__UART5_RXD */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT15, 0x0664, 0x0294, 4, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT15__SDMA_DEBUG_PC_9 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT15, 0x0664, 0x0294, 5, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT15__GPIO_6_1 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT15, 0x0664, 0x0294, 6, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT15__MMDC_MMDC_DEBUG_38 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT15, 0x0664, 0x0294, 7, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT15__CHEETAH_TRACE_12 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT16, 0x0668, 0x0298, 0, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT16, 0x0668, 0x0298, 1, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT16__WEIM_WEIM_D_12 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT16, 0x0668, 0x0298, 2, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT16__PCIE_CTRL_MUX_20 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT16, 0x0668, 0x0298, 3, 0x0934, 0), /* MX6Q_PAD_CSI0_DAT16__UART4_RTS */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT16, 0x0668, 0x0298, 4, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT16__SDMA_DEBUG_PC_10 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT16, 0x0668, 0x0298, 5, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT16__GPIO_6_2 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT16, 0x0668, 0x0298, 6, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT16__MMDC_MMDC_DEBUG_39 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT16, 0x0668, 0x0298, 7, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT16__CHEETAH_TRACE_13 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT17, 0x066C, 0x029C, 0, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT17, 0x066C, 0x029C, 1, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT17__WEIM_WEIM_D_13 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT17, 0x066C, 0x029C, 2, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT17__PCIE_CTRL_MUX_21 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT17, 0x066C, 0x029C, 3, 0x0934, 1), /* MX6Q_PAD_CSI0_DAT17__UART4_CTS */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT17, 0x066C, 0x029C, 4, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT17__SDMA_DEBUG_PC_11 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT17, 0x066C, 0x029C, 5, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT17__GPIO_6_3 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT17, 0x066C, 0x029C, 6, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT17__MMDC_MMDC_DEBUG_40 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT17, 0x066C, 0x029C, 7, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT17__CHEETAH_TRACE_14 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT18, 0x0670, 0x02A0, 0, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT18, 0x0670, 0x02A0, 1, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT18__WEIM_WEIM_D_14 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT18, 0x0670, 0x02A0, 2, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT18__PCIE_CTRL_MUX_22 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT18, 0x0670, 0x02A0, 3, 0x093C, 2), /* MX6Q_PAD_CSI0_DAT18__UART5_RTS */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT18, 0x0670, 0x02A0, 4, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT18__SDMA_DEBUG_PC_12 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT18, 0x0670, 0x02A0, 5, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT18__GPIO_6_4 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT18, 0x0670, 0x02A0, 6, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT18__MMDC_MMDC_DEBUG_41 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT18, 0x0670, 0x02A0, 7, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT18__CHEETAH_TRACE_15 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT19, 0x0674, 0x02A4, 0, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT19, 0x0674, 0x02A4, 1, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT19__WEIM_WEIM_D_15 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT19, 0x0674, 0x02A4, 2, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT19__PCIE_CTRL_MUX_23 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT19, 0x0674, 0x02A4, 3, 0x093C, 3), /* MX6Q_PAD_CSI0_DAT19__UART5_CTS */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT19, 0x0674, 0x02A4, 4, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT19__SDMA_DEBUG_PC_13 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT19, 0x0674, 0x02A4, 5, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT19__GPIO_6_5 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT19, 0x0674, 0x02A4, 6, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT19__MMDC_MMDC_DEBUG_42 */ - IMX_PIN_REG(MX6Q_PAD_CSI0_DAT19, 0x0674, 0x02A4, 7, 0x0000, 0), /* MX6Q_PAD_CSI0_DAT19__ANATOP_TESTO_9 */ - IMX_PIN_REG(MX6Q_PAD_JTAG_TMS, 0x0678, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_JTAG_TMS__SJC_TMS */ - IMX_PIN_REG(MX6Q_PAD_JTAG_MOD, 0x067C, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_JTAG_MOD__SJC_MOD */ - IMX_PIN_REG(MX6Q_PAD_JTAG_TRSTB, 0x0680, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_JTAG_TRSTB__SJC_TRSTB */ - IMX_PIN_REG(MX6Q_PAD_JTAG_TDI, 0x0684, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_JTAG_TDI__SJC_TDI */ - IMX_PIN_REG(MX6Q_PAD_JTAG_TCK, 0x0688, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_JTAG_TCK__SJC_TCK */ - IMX_PIN_REG(MX6Q_PAD_JTAG_TDO, 0x068C, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_JTAG_TDO__SJC_TDO */ - IMX_PIN_REG(MX6Q_PAD_LVDS1_TX3_P, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3 */ - IMX_PIN_REG(MX6Q_PAD_LVDS1_TX2_P, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2 */ - IMX_PIN_REG(MX6Q_PAD_LVDS1_CLK_P, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK */ - IMX_PIN_REG(MX6Q_PAD_LVDS1_TX1_P, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1 */ - IMX_PIN_REG(MX6Q_PAD_LVDS1_TX0_P, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0 */ - IMX_PIN_REG(MX6Q_PAD_LVDS0_TX3_P, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3 */ - IMX_PIN_REG(MX6Q_PAD_LVDS0_CLK_P, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK */ - IMX_PIN_REG(MX6Q_PAD_LVDS0_TX2_P, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2 */ - IMX_PIN_REG(MX6Q_PAD_LVDS0_TX1_P, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1 */ - IMX_PIN_REG(MX6Q_PAD_LVDS0_TX0_P, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0 */ - IMX_PIN_REG(MX6Q_PAD_TAMPER, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_TAMPER__SNVS_LP_WRAP_SNVS_TD1 */ - IMX_PIN_REG(MX6Q_PAD_PMIC_ON_REQ, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_PMIC_ON_REQ__SNVS_LPWRAP_WKALM */ - IMX_PIN_REG(MX6Q_PAD_PMIC_STBY_REQ, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_PMIC_STBY_REQ__CCM_PMIC_STBYRQ */ - IMX_PIN_REG(MX6Q_PAD_POR_B, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_POR_B__SRC_POR_B */ - IMX_PIN_REG(MX6Q_PAD_BOOT_MODE1, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_BOOT_MODE1__SRC_BOOT_MODE_1 */ - IMX_PIN_REG(MX6Q_PAD_RESET_IN_B, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_RESET_IN_B__SRC_RESET_B */ - IMX_PIN_REG(MX6Q_PAD_BOOT_MODE0, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_BOOT_MODE0__SRC_BOOT_MODE_0 */ - IMX_PIN_REG(MX6Q_PAD_TEST_MODE, NO_PAD, NO_MUX, 0, 0x0000, 0), /* MX6Q_PAD_TEST_MODE__TCU_TEST_MODE */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT7, 0x0690, 0x02A8, 0, 0x0000, 0), /* MX6Q_PAD_SD3_DAT7__USDHC3_DAT7 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT7, 0x0690, 0x02A8, 1, 0x0000, 0), /* MX6Q_PAD_SD3_DAT7__UART1_TXD */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT7, 0x0690, 0x02A8, 2, 0x0000, 0), /* MX6Q_PAD_SD3_DAT7__PCIE_CTRL_MUX_24 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT7, 0x0690, 0x02A8, 3, 0x0000, 0), /* MX6Q_PAD_SD3_DAT7__USBOH3_UH3_DFD_OUT_0 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT7, 0x0690, 0x02A8, 4, 0x0000, 0), /* MX6Q_PAD_SD3_DAT7__USBOH3_UH2_DFD_OUT_0 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT7, 0x0690, 0x02A8, 5, 0x0000, 0), /* MX6Q_PAD_SD3_DAT7__GPIO_6_17 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT7, 0x0690, 0x02A8, 6, 0x0000, 0), /* MX6Q_PAD_SD3_DAT7__MIPI_CORE_DPHY_IN_12 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT7, 0x0690, 0x02A8, 7, 0x0000, 0), /* MX6Q_PAD_SD3_DAT7__USBPHY2_CLK20DIV */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT6, 0x0694, 0x02AC, 0, 0x0000, 0), /* MX6Q_PAD_SD3_DAT6__USDHC3_DAT6 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT6, 0x0694, 0x02AC, 1, 0x0920, 3), /* MX6Q_PAD_SD3_DAT6__UART1_RXD */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT6, 0x0694, 0x02AC, 2, 0x0000, 0), /* MX6Q_PAD_SD3_DAT6__PCIE_CTRL_MUX_25 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT6, 0x0694, 0x02AC, 3, 0x0000, 0), /* MX6Q_PAD_SD3_DAT6__USBOH3_UH3_DFD_OUT_1 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT6, 0x0694, 0x02AC, 4, 0x0000, 0), /* MX6Q_PAD_SD3_DAT6__USBOH3_UH2_DFD_OUT_1 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT6, 0x0694, 0x02AC, 5, 0x0000, 0), /* MX6Q_PAD_SD3_DAT6__GPIO_6_18 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT6, 0x0694, 0x02AC, 6, 0x0000, 0), /* MX6Q_PAD_SD3_DAT6__MIPI_CORE_DPHY_IN_13 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT6, 0x0694, 0x02AC, 7, 0x0000, 0), /* MX6Q_PAD_SD3_DAT6__ANATOP_TESTO_10 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT5, 0x0698, 0x02B0, 0, 0x0000, 0), /* MX6Q_PAD_SD3_DAT5__USDHC3_DAT5 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT5, 0x0698, 0x02B0, 1, 0x0000, 0), /* MX6Q_PAD_SD3_DAT5__UART2_TXD */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT5, 0x0698, 0x02B0, 2, 0x0000, 0), /* MX6Q_PAD_SD3_DAT5__PCIE_CTRL_MUX_26 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT5, 0x0698, 0x02B0, 3, 0x0000, 0), /* MX6Q_PAD_SD3_DAT5__USBOH3_UH3_DFD_OUT_2 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT5, 0x0698, 0x02B0, 4, 0x0000, 0), /* MX6Q_PAD_SD3_DAT5__USBOH3_UH2_DFD_OUT_2 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT5, 0x0698, 0x02B0, 5, 0x0000, 0), /* MX6Q_PAD_SD3_DAT5__GPIO_7_0 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT5, 0x0698, 0x02B0, 6, 0x0000, 0), /* MX6Q_PAD_SD3_DAT5__MIPI_CORE_DPHY_IN_14 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT5, 0x0698, 0x02B0, 7, 0x0000, 0), /* MX6Q_PAD_SD3_DAT5__ANATOP_TESTO_11 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT4, 0x069C, 0x02B4, 0, 0x0000, 0), /* MX6Q_PAD_SD3_DAT4__USDHC3_DAT4 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT4, 0x069C, 0x02B4, 1, 0x0928, 5), /* MX6Q_PAD_SD3_DAT4__UART2_RXD */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT4, 0x069C, 0x02B4, 2, 0x0000, 0), /* MX6Q_PAD_SD3_DAT4__PCIE_CTRL_MUX_27 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT4, 0x069C, 0x02B4, 3, 0x0000, 0), /* MX6Q_PAD_SD3_DAT4__USBOH3_UH3_DFD_OUT_3 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT4, 0x069C, 0x02B4, 4, 0x0000, 0), /* MX6Q_PAD_SD3_DAT4__USBOH3_UH2_DFD_OUT_3 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT4, 0x069C, 0x02B4, 5, 0x0000, 0), /* MX6Q_PAD_SD3_DAT4__GPIO_7_1 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT4, 0x069C, 0x02B4, 6, 0x0000, 0), /* MX6Q_PAD_SD3_DAT4__MIPI_CORE_DPHY_IN_15 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT4, 0x069C, 0x02B4, 7, 0x0000, 0), /* MX6Q_PAD_SD3_DAT4__ANATOP_TESTO_12 */ - IMX_PIN_REG(MX6Q_PAD_SD3_CMD, 0x06A0, 0x02B8, 0, 0x0000, 0), /* MX6Q_PAD_SD3_CMD__USDHC3_CMD */ - IMX_PIN_REG(MX6Q_PAD_SD3_CMD, 0x06A0, 0x02B8, 1, 0x0924, 2), /* MX6Q_PAD_SD3_CMD__UART2_CTS */ - IMX_PIN_REG(MX6Q_PAD_SD3_CMD, 0x06A0, 0x02B8, 2, 0x0000, 0), /* MX6Q_PAD_SD3_CMD__CAN1_TXCAN */ - IMX_PIN_REG(MX6Q_PAD_SD3_CMD, 0x06A0, 0x02B8, 3, 0x0000, 0), /* MX6Q_PAD_SD3_CMD__USBOH3_UH3_DFD_OUT_4 */ - IMX_PIN_REG(MX6Q_PAD_SD3_CMD, 0x06A0, 0x02B8, 4, 0x0000, 0), /* MX6Q_PAD_SD3_CMD__USBOH3_UH2_DFD_OUT_4 */ - IMX_PIN_REG(MX6Q_PAD_SD3_CMD, 0x06A0, 0x02B8, 5, 0x0000, 0), /* MX6Q_PAD_SD3_CMD__GPIO_7_2 */ - IMX_PIN_REG(MX6Q_PAD_SD3_CMD, 0x06A0, 0x02B8, 6, 0x0000, 0), /* MX6Q_PAD_SD3_CMD__MIPI_CORE_DPHY_IN_16 */ - IMX_PIN_REG(MX6Q_PAD_SD3_CMD, 0x06A0, 0x02B8, 7, 0x0000, 0), /* MX6Q_PAD_SD3_CMD__ANATOP_TESTO_13 */ - IMX_PIN_REG(MX6Q_PAD_SD3_CLK, 0x06A4, 0x02BC, 0, 0x0000, 0), /* MX6Q_PAD_SD3_CLK__USDHC3_CLK */ - IMX_PIN_REG(MX6Q_PAD_SD3_CLK, 0x06A4, 0x02BC, 1, 0x0924, 3), /* MX6Q_PAD_SD3_CLK__UART2_RTS */ - IMX_PIN_REG(MX6Q_PAD_SD3_CLK, 0x06A4, 0x02BC, 2, 0x07E4, 2), /* MX6Q_PAD_SD3_CLK__CAN1_RXCAN */ - IMX_PIN_REG(MX6Q_PAD_SD3_CLK, 0x06A4, 0x02BC, 3, 0x0000, 0), /* MX6Q_PAD_SD3_CLK__USBOH3_UH3_DFD_OUT_5 */ - IMX_PIN_REG(MX6Q_PAD_SD3_CLK, 0x06A4, 0x02BC, 4, 0x0000, 0), /* MX6Q_PAD_SD3_CLK__USBOH3_UH2_DFD_OUT_5 */ - IMX_PIN_REG(MX6Q_PAD_SD3_CLK, 0x06A4, 0x02BC, 5, 0x0000, 0), /* MX6Q_PAD_SD3_CLK__GPIO_7_3 */ - IMX_PIN_REG(MX6Q_PAD_SD3_CLK, 0x06A4, 0x02BC, 6, 0x0000, 0), /* MX6Q_PAD_SD3_CLK__MIPI_CORE_DPHY_IN_17 */ - IMX_PIN_REG(MX6Q_PAD_SD3_CLK, 0x06A4, 0x02BC, 7, 0x0000, 0), /* MX6Q_PAD_SD3_CLK__ANATOP_TESTO_14 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT0, 0x06A8, 0x02C0, 0, 0x0000, 0), /* MX6Q_PAD_SD3_DAT0__USDHC3_DAT0 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT0, 0x06A8, 0x02C0, 1, 0x091C, 2), /* MX6Q_PAD_SD3_DAT0__UART1_CTS */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT0, 0x06A8, 0x02C0, 2, 0x0000, 0), /* MX6Q_PAD_SD3_DAT0__CAN2_TXCAN */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT0, 0x06A8, 0x02C0, 3, 0x0000, 0), /* MX6Q_PAD_SD3_DAT0__USBOH3_UH3_DFD_OUT_6 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT0, 0x06A8, 0x02C0, 4, 0x0000, 0), /* MX6Q_PAD_SD3_DAT0__USBOH3_UH2_DFD_OUT_6 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT0, 0x06A8, 0x02C0, 5, 0x0000, 0), /* MX6Q_PAD_SD3_DAT0__GPIO_7_4 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT0, 0x06A8, 0x02C0, 6, 0x0000, 0), /* MX6Q_PAD_SD3_DAT0__MIPI_CORE_DPHY_IN_18 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT0, 0x06A8, 0x02C0, 7, 0x0000, 0), /* MX6Q_PAD_SD3_DAT0__ANATOP_TESTO_15 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT1, 0x06AC, 0x02C4, 0, 0x0000, 0), /* MX6Q_PAD_SD3_DAT1__USDHC3_DAT1 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT1, 0x06AC, 0x02C4, 1, 0x091C, 3), /* MX6Q_PAD_SD3_DAT1__UART1_RTS */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT1, 0x06AC, 0x02C4, 2, 0x07E8, 1), /* MX6Q_PAD_SD3_DAT1__CAN2_RXCAN */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT1, 0x06AC, 0x02C4, 3, 0x0000, 0), /* MX6Q_PAD_SD3_DAT1__USBOH3_UH3_DFD_OUT_7 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT1, 0x06AC, 0x02C4, 4, 0x0000, 0), /* MX6Q_PAD_SD3_DAT1__USBOH3_UH2_DFD_OUT_7 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT1, 0x06AC, 0x02C4, 5, 0x0000, 0), /* MX6Q_PAD_SD3_DAT1__GPIO_7_5 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT1, 0x06AC, 0x02C4, 6, 0x0000, 0), /* MX6Q_PAD_SD3_DAT1__MIPI_CORE_DPHY_IN_19 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT1, 0x06AC, 0x02C4, 7, 0x0000, 0), /* MX6Q_PAD_SD3_DAT1__ANATOP_TESTI_0 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT2, 0x06B0, 0x02C8, 0, 0x0000, 0), /* MX6Q_PAD_SD3_DAT2__USDHC3_DAT2 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT2, 0x06B0, 0x02C8, 2, 0x0000, 0), /* MX6Q_PAD_SD3_DAT2__PCIE_CTRL_MUX_28 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT2, 0x06B0, 0x02C8, 3, 0x0000, 0), /* MX6Q_PAD_SD3_DAT2__USBOH3_UH3_DFD_OUT_8 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT2, 0x06B0, 0x02C8, 4, 0x0000, 0), /* MX6Q_PAD_SD3_DAT2__USBOH3_UH2_DFD_OUT_8 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT2, 0x06B0, 0x02C8, 5, 0x0000, 0), /* MX6Q_PAD_SD3_DAT2__GPIO_7_6 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT2, 0x06B0, 0x02C8, 6, 0x0000, 0), /* MX6Q_PAD_SD3_DAT2__MIPI_CORE_DPHY_IN_20 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT2, 0x06B0, 0x02C8, 7, 0x0000, 0), /* MX6Q_PAD_SD3_DAT2__ANATOP_TESTI_1 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT3, 0x06B4, 0x02CC, 0, 0x0000, 0), /* MX6Q_PAD_SD3_DAT3__USDHC3_DAT3 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT3, 0x06B4, 0x02CC, 1, 0x092C, 4), /* MX6Q_PAD_SD3_DAT3__UART3_CTS */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT3, 0x06B4, 0x02CC, 2, 0x0000, 0), /* MX6Q_PAD_SD3_DAT3__PCIE_CTRL_MUX_29 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT3, 0x06B4, 0x02CC, 3, 0x0000, 0), /* MX6Q_PAD_SD3_DAT3__USBOH3_UH3_DFD_OUT_9 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT3, 0x06B4, 0x02CC, 4, 0x0000, 0), /* MX6Q_PAD_SD3_DAT3__USBOH3_UH2_DFD_OUT_9 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT3, 0x06B4, 0x02CC, 5, 0x0000, 0), /* MX6Q_PAD_SD3_DAT3__GPIO_7_7 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT3, 0x06B4, 0x02CC, 6, 0x0000, 0), /* MX6Q_PAD_SD3_DAT3__MIPI_CORE_DPHY_IN_21 */ - IMX_PIN_REG(MX6Q_PAD_SD3_DAT3, 0x06B4, 0x02CC, 7, 0x0000, 0), /* MX6Q_PAD_SD3_DAT3__ANATOP_TESTI_2 */ - IMX_PIN_REG(MX6Q_PAD_SD3_RST, 0x06B8, 0x02D0, 0, 0x0000, 0), /* MX6Q_PAD_SD3_RST__USDHC3_RST */ - IMX_PIN_REG(MX6Q_PAD_SD3_RST, 0x06B8, 0x02D0, 1, 0x092C, 5), /* MX6Q_PAD_SD3_RST__UART3_RTS */ - IMX_PIN_REG(MX6Q_PAD_SD3_RST, 0x06B8, 0x02D0, 2, 0x0000, 0), /* MX6Q_PAD_SD3_RST__PCIE_CTRL_MUX_30 */ - IMX_PIN_REG(MX6Q_PAD_SD3_RST, 0x06B8, 0x02D0, 3, 0x0000, 0), /* MX6Q_PAD_SD3_RST__USBOH3_UH3_DFD_OUT_10 */ - IMX_PIN_REG(MX6Q_PAD_SD3_RST, 0x06B8, 0x02D0, 4, 0x0000, 0), /* MX6Q_PAD_SD3_RST__USBOH3_UH2_DFD_OUT_10 */ - IMX_PIN_REG(MX6Q_PAD_SD3_RST, 0x06B8, 0x02D0, 5, 0x0000, 0), /* MX6Q_PAD_SD3_RST__GPIO_7_8 */ - IMX_PIN_REG(MX6Q_PAD_SD3_RST, 0x06B8, 0x02D0, 6, 0x0000, 0), /* MX6Q_PAD_SD3_RST__MIPI_CORE_DPHY_IN_22 */ - IMX_PIN_REG(MX6Q_PAD_SD3_RST, 0x06B8, 0x02D0, 7, 0x0000, 0), /* MX6Q_PAD_SD3_RST__ANATOP_ANATOP_TESTI_3 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CLE, 0x06BC, 0x02D4, 0, 0x0000, 0), /* MX6Q_PAD_NANDF_CLE__RAWNAND_CLE */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CLE, 0x06BC, 0x02D4, 1, 0x0000, 0), /* MX6Q_PAD_NANDF_CLE__IPU2_SISG_4 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CLE, 0x06BC, 0x02D4, 2, 0x0000, 0), /* MX6Q_PAD_NANDF_CLE__PCIE_CTRL_MUX_31 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CLE, 0x06BC, 0x02D4, 3, 0x0000, 0), /* MX6Q_PAD_NANDF_CLE__USBOH3_UH3_DFD_OT11 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CLE, 0x06BC, 0x02D4, 4, 0x0000, 0), /* MX6Q_PAD_NANDF_CLE__USBOH3_UH2_DFD_OT11 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CLE, 0x06BC, 0x02D4, 5, 0x0000, 0), /* MX6Q_PAD_NANDF_CLE__GPIO_6_7 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CLE, 0x06BC, 0x02D4, 6, 0x0000, 0), /* MX6Q_PAD_NANDF_CLE__MIPI_CORE_DPHY_IN23 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CLE, 0x06BC, 0x02D4, 7, 0x0000, 0), /* MX6Q_PAD_NANDF_CLE__TPSMP_HTRANS_0 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_ALE, 0x06C0, 0x02D8, 0, 0x0000, 0), /* MX6Q_PAD_NANDF_ALE__RAWNAND_ALE */ - IMX_PIN_REG(MX6Q_PAD_NANDF_ALE, 0x06C0, 0x02D8, 1, 0x0000, 0), /* MX6Q_PAD_NANDF_ALE__USDHC4_RST */ - IMX_PIN_REG(MX6Q_PAD_NANDF_ALE, 0x06C0, 0x02D8, 2, 0x0000, 0), /* MX6Q_PAD_NANDF_ALE__PCIE_CTRL_MUX_0 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_ALE, 0x06C0, 0x02D8, 3, 0x0000, 0), /* MX6Q_PAD_NANDF_ALE__USBOH3_UH3_DFD_OT12 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_ALE, 0x06C0, 0x02D8, 4, 0x0000, 0), /* MX6Q_PAD_NANDF_ALE__USBOH3_UH2_DFD_OT12 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_ALE, 0x06C0, 0x02D8, 5, 0x0000, 0), /* MX6Q_PAD_NANDF_ALE__GPIO_6_8 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_ALE, 0x06C0, 0x02D8, 6, 0x0000, 0), /* MX6Q_PAD_NANDF_ALE__MIPI_CR_DPHY_IN_24 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_ALE, 0x06C0, 0x02D8, 7, 0x0000, 0), /* MX6Q_PAD_NANDF_ALE__TPSMP_HTRANS_1 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_WP_B, 0x06C4, 0x02DC, 0, 0x0000, 0), /* MX6Q_PAD_NANDF_WP_B__RAWNAND_RESETN */ - IMX_PIN_REG(MX6Q_PAD_NANDF_WP_B, 0x06C4, 0x02DC, 1, 0x0000, 0), /* MX6Q_PAD_NANDF_WP_B__IPU2_SISG_5 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_WP_B, 0x06C4, 0x02DC, 2, 0x0000, 0), /* MX6Q_PAD_NANDF_WP_B__PCIE_CTRL__MUX_1 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_WP_B, 0x06C4, 0x02DC, 3, 0x0000, 0), /* MX6Q_PAD_NANDF_WP_B__USBOH3_UH3_DFDOT13 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_WP_B, 0x06C4, 0x02DC, 4, 0x0000, 0), /* MX6Q_PAD_NANDF_WP_B__USBOH3_UH2_DFDOT13 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_WP_B, 0x06C4, 0x02DC, 5, 0x0000, 0), /* MX6Q_PAD_NANDF_WP_B__GPIO_6_9 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_WP_B, 0x06C4, 0x02DC, 6, 0x0000, 0), /* MX6Q_PAD_NANDF_WP_B__MIPI_CR_DPHY_OUT32 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_WP_B, 0x06C4, 0x02DC, 7, 0x0000, 0), /* MX6Q_PAD_NANDF_WP_B__PL301_PER1_HSIZE_0 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_RB0, 0x06C8, 0x02E0, 0, 0x0000, 0), /* MX6Q_PAD_NANDF_RB0__RAWNAND_READY0 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_RB0, 0x06C8, 0x02E0, 1, 0x0000, 0), /* MX6Q_PAD_NANDF_RB0__IPU2_DI0_PIN1 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_RB0, 0x06C8, 0x02E0, 2, 0x0000, 0), /* MX6Q_PAD_NANDF_RB0__PCIE_CTRL_MUX_2 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_RB0, 0x06C8, 0x02E0, 3, 0x0000, 0), /* MX6Q_PAD_NANDF_RB0__USBOH3_UH3_DFD_OT14 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_RB0, 0x06C8, 0x02E0, 4, 0x0000, 0), /* MX6Q_PAD_NANDF_RB0__USBOH3_UH2_DFD_OT14 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_RB0, 0x06C8, 0x02E0, 5, 0x0000, 0), /* MX6Q_PAD_NANDF_RB0__GPIO_6_10 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_RB0, 0x06C8, 0x02E0, 6, 0x0000, 0), /* MX6Q_PAD_NANDF_RB0__MIPI_CR_DPHY_OUT_33 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_RB0, 0x06C8, 0x02E0, 7, 0x0000, 0), /* MX6Q_PAD_NANDF_RB0__PL301_PER1_HSIZE_1 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS0, 0x06CC, 0x02E4, 0, 0x0000, 0), /* MX6Q_PAD_NANDF_CS0__RAWNAND_CE0N */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS0, 0x06CC, 0x02E4, 3, 0x0000, 0), /* MX6Q_PAD_NANDF_CS0__USBOH3_UH3_DFD_OT15 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS0, 0x06CC, 0x02E4, 4, 0x0000, 0), /* MX6Q_PAD_NANDF_CS0__USBOH3_UH2_DFD_OT15 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS0, 0x06CC, 0x02E4, 5, 0x0000, 0), /* MX6Q_PAD_NANDF_CS0__GPIO_6_11 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS0, 0x06CC, 0x02E4, 7, 0x0000, 0), /* MX6Q_PAD_NANDF_CS0__PL301_PER1_HSIZE_2 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS1, 0x06D0, 0x02E8, 0, 0x0000, 0), /* MX6Q_PAD_NANDF_CS1__RAWNAND_CE1N */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS1, 0x06D0, 0x02E8, 1, 0x0000, 0), /* MX6Q_PAD_NANDF_CS1__USDHC4_VSELECT */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS1, 0x06D0, 0x02E8, 2, 0x0000, 0), /* MX6Q_PAD_NANDF_CS1__USDHC3_VSELECT */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS1, 0x06D0, 0x02E8, 4, 0x0000, 0), /* MX6Q_PAD_NANDF_CS1__PCIE_CTRL_MUX_3 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS1, 0x06D0, 0x02E8, 5, 0x0000, 0), /* MX6Q_PAD_NANDF_CS1__GPIO_6_14 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS1, 0x06D0, 0x02E8, 7, 0x0000, 0), /* MX6Q_PAD_NANDF_CS1__PL301_PER1_HRDYOUT */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS2, 0x06D4, 0x02EC, 0, 0x0000, 0), /* MX6Q_PAD_NANDF_CS2__RAWNAND_CE2N */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS2, 0x06D4, 0x02EC, 1, 0x0000, 0), /* MX6Q_PAD_NANDF_CS2__IPU1_SISG_0 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS2, 0x06D4, 0x02EC, 2, 0x0874, 1), /* MX6Q_PAD_NANDF_CS2__ESAI1_TX0 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS2, 0x06D4, 0x02EC, 3, 0x0000, 0), /* MX6Q_PAD_NANDF_CS2__WEIM_WEIM_CRE */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS2, 0x06D4, 0x02EC, 4, 0x0000, 0), /* MX6Q_PAD_NANDF_CS2__CCM_CLKO2 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS2, 0x06D4, 0x02EC, 5, 0x0000, 0), /* MX6Q_PAD_NANDF_CS2__GPIO_6_15 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS2, 0x06D4, 0x02EC, 6, 0x0000, 0), /* MX6Q_PAD_NANDF_CS2__IPU2_SISG_0 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS3, 0x06D8, 0x02F0, 0, 0x0000, 0), /* MX6Q_PAD_NANDF_CS3__RAWNAND_CE3N */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS3, 0x06D8, 0x02F0, 1, 0x0000, 0), /* MX6Q_PAD_NANDF_CS3__IPU1_SISG_1 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS3, 0x06D8, 0x02F0, 2, 0x0878, 1), /* MX6Q_PAD_NANDF_CS3__ESAI1_TX1 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS3, 0x06D8, 0x02F0, 3, 0x0000, 0), /* MX6Q_PAD_NANDF_CS3__WEIM_WEIM_A_26 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS3, 0x06D8, 0x02F0, 4, 0x0000, 0), /* MX6Q_PAD_NANDF_CS3__PCIE_CTRL_MUX_4 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS3, 0x06D8, 0x02F0, 5, 0x0000, 0), /* MX6Q_PAD_NANDF_CS3__GPIO_6_16 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS3, 0x06D8, 0x02F0, 6, 0x0000, 0), /* MX6Q_PAD_NANDF_CS3__IPU2_SISG_1 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_CS3, 0x06D8, 0x02F0, 7, 0x0000, 0), /* MX6Q_PAD_NANDF_CS3__TPSMP_CLK */ - IMX_PIN_REG(MX6Q_PAD_SD4_CMD, 0x06DC, 0x02F4, 0, 0x0000, 0), /* MX6Q_PAD_SD4_CMD__USDHC4_CMD */ - IMX_PIN_REG(MX6Q_PAD_SD4_CMD, 0x06DC, 0x02F4, 1, 0x0000, 0), /* MX6Q_PAD_SD4_CMD__RAWNAND_RDN */ - IMX_PIN_REG(MX6Q_PAD_SD4_CMD, 0x06DC, 0x02F4, 2, 0x0000, 0), /* MX6Q_PAD_SD4_CMD__UART3_TXD */ - IMX_PIN_REG(MX6Q_PAD_SD4_CMD, 0x06DC, 0x02F4, 4, 0x0000, 0), /* MX6Q_PAD_SD4_CMD__PCIE_CTRL_MUX_5 */ - IMX_PIN_REG(MX6Q_PAD_SD4_CMD, 0x06DC, 0x02F4, 5, 0x0000, 0), /* MX6Q_PAD_SD4_CMD__GPIO_7_9 */ - IMX_PIN_REG(MX6Q_PAD_SD4_CMD, 0x06DC, 0x02F4, 7, 0x0000, 0), /* MX6Q_PAD_SD4_CMD__TPSMP_HDATA_DIR */ - IMX_PIN_REG(MX6Q_PAD_SD4_CLK, 0x06E0, 0x02F8, 0, 0x0000, 0), /* MX6Q_PAD_SD4_CLK__USDHC4_CLK */ - IMX_PIN_REG(MX6Q_PAD_SD4_CLK, 0x06E0, 0x02F8, 1, 0x0000, 0), /* MX6Q_PAD_SD4_CLK__RAWNAND_WRN */ - IMX_PIN_REG(MX6Q_PAD_SD4_CLK, 0x06E0, 0x02F8, 2, 0x0930, 3), /* MX6Q_PAD_SD4_CLK__UART3_RXD */ - IMX_PIN_REG(MX6Q_PAD_SD4_CLK, 0x06E0, 0x02F8, 4, 0x0000, 0), /* MX6Q_PAD_SD4_CLK__PCIE_CTRL_MUX_6 */ - IMX_PIN_REG(MX6Q_PAD_SD4_CLK, 0x06E0, 0x02F8, 5, 0x0000, 0), /* MX6Q_PAD_SD4_CLK__GPIO_7_10 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D0, 0x06E4, 0x02FC, 0, 0x0000, 0), /* MX6Q_PAD_NANDF_D0__RAWNAND_D0 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D0, 0x06E4, 0x02FC, 1, 0x0000, 0), /* MX6Q_PAD_NANDF_D0__USDHC1_DAT4 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D0, 0x06E4, 0x02FC, 2, 0x0000, 0), /* MX6Q_PAD_NANDF_D0__GPU3D_GPU_DBG_OUT_0 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D0, 0x06E4, 0x02FC, 3, 0x0000, 0), /* MX6Q_PAD_NANDF_D0__USBOH3_UH2_DFD_OUT16 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D0, 0x06E4, 0x02FC, 4, 0x0000, 0), /* MX6Q_PAD_NANDF_D0__USBOH3_UH3_DFD_OUT16 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D0, 0x06E4, 0x02FC, 5, 0x0000, 0), /* MX6Q_PAD_NANDF_D0__GPIO_2_0 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D0, 0x06E4, 0x02FC, 6, 0x0000, 0), /* MX6Q_PAD_NANDF_D0__IPU1_IPU_DIAG_BUS_0 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D0, 0x06E4, 0x02FC, 7, 0x0000, 0), /* MX6Q_PAD_NANDF_D0__IPU2_IPU_DIAG_BUS_0 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D1, 0x06E8, 0x0300, 0, 0x0000, 0), /* MX6Q_PAD_NANDF_D1__RAWNAND_D1 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D1, 0x06E8, 0x0300, 1, 0x0000, 0), /* MX6Q_PAD_NANDF_D1__USDHC1_DAT5 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D1, 0x06E8, 0x0300, 2, 0x0000, 0), /* MX6Q_PAD_NANDF_D1__GPU3D_GPU_DEBUG_OUT1 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D1, 0x06E8, 0x0300, 3, 0x0000, 0), /* MX6Q_PAD_NANDF_D1__USBOH3_UH2_DFD_OUT17 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D1, 0x06E8, 0x0300, 4, 0x0000, 0), /* MX6Q_PAD_NANDF_D1__USBOH3_UH3_DFD_OUT17 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D1, 0x06E8, 0x0300, 5, 0x0000, 0), /* MX6Q_PAD_NANDF_D1__GPIO_2_1 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D1, 0x06E8, 0x0300, 6, 0x0000, 0), /* MX6Q_PAD_NANDF_D1__IPU1_IPU_DIAG_BUS_1 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D1, 0x06E8, 0x0300, 7, 0x0000, 0), /* MX6Q_PAD_NANDF_D1__IPU2_IPU_DIAG_BUS_1 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D2, 0x06EC, 0x0304, 0, 0x0000, 0), /* MX6Q_PAD_NANDF_D2__RAWNAND_D2 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D2, 0x06EC, 0x0304, 1, 0x0000, 0), /* MX6Q_PAD_NANDF_D2__USDHC1_DAT6 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D2, 0x06EC, 0x0304, 2, 0x0000, 0), /* MX6Q_PAD_NANDF_D2__GPU3D_GPU_DBG_OUT_2 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D2, 0x06EC, 0x0304, 3, 0x0000, 0), /* MX6Q_PAD_NANDF_D2__USBOH3_UH2_DFD_OUT18 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D2, 0x06EC, 0x0304, 4, 0x0000, 0), /* MX6Q_PAD_NANDF_D2__USBOH3_UH3_DFD_OUT18 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D2, 0x06EC, 0x0304, 5, 0x0000, 0), /* MX6Q_PAD_NANDF_D2__GPIO_2_2 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D2, 0x06EC, 0x0304, 6, 0x0000, 0), /* MX6Q_PAD_NANDF_D2__IPU1_IPU_DIAG_BUS_2 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D2, 0x06EC, 0x0304, 7, 0x0000, 0), /* MX6Q_PAD_NANDF_D2__IPU2_IPU_DIAG_BUS_2 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D3, 0x06F0, 0x0308, 0, 0x0000, 0), /* MX6Q_PAD_NANDF_D3__RAWNAND_D3 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D3, 0x06F0, 0x0308, 1, 0x0000, 0), /* MX6Q_PAD_NANDF_D3__USDHC1_DAT7 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D3, 0x06F0, 0x0308, 2, 0x0000, 0), /* MX6Q_PAD_NANDF_D3__GPU3D_GPU_DBG_OUT_3 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D3, 0x06F0, 0x0308, 3, 0x0000, 0), /* MX6Q_PAD_NANDF_D3__USBOH3_UH2_DFD_OUT19 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D3, 0x06F0, 0x0308, 4, 0x0000, 0), /* MX6Q_PAD_NANDF_D3__USBOH3_UH3_DFD_OUT19 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D3, 0x06F0, 0x0308, 5, 0x0000, 0), /* MX6Q_PAD_NANDF_D3__GPIO_2_3 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D3, 0x06F0, 0x0308, 6, 0x0000, 0), /* MX6Q_PAD_NANDF_D3__IPU1_IPU_DIAG_BUS_3 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D3, 0x06F0, 0x0308, 7, 0x0000, 0), /* MX6Q_PAD_NANDF_D3__IPU2_IPU_DIAG_BUS_3 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D4, 0x06F4, 0x030C, 0, 0x0000, 0), /* MX6Q_PAD_NANDF_D4__RAWNAND_D4 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D4, 0x06F4, 0x030C, 1, 0x0000, 0), /* MX6Q_PAD_NANDF_D4__USDHC2_DAT4 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D4, 0x06F4, 0x030C, 2, 0x0000, 0), /* MX6Q_PAD_NANDF_D4__GPU3D_GPU_DBG_OUT_4 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D4, 0x06F4, 0x030C, 3, 0x0000, 0), /* MX6Q_PAD_NANDF_D4__USBOH3_UH2_DFD_OUT20 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D4, 0x06F4, 0x030C, 4, 0x0000, 0), /* MX6Q_PAD_NANDF_D4__USBOH3_UH3_DFD_OUT20 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D4, 0x06F4, 0x030C, 5, 0x0000, 0), /* MX6Q_PAD_NANDF_D4__GPIO_2_4 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D4, 0x06F4, 0x030C, 6, 0x0000, 0), /* MX6Q_PAD_NANDF_D4__IPU1_IPU_DIAG_BUS_4 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D4, 0x06F4, 0x030C, 7, 0x0000, 0), /* MX6Q_PAD_NANDF_D4__IPU2_IPU_DIAG_BUS_4 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D5, 0x06F8, 0x0310, 0, 0x0000, 0), /* MX6Q_PAD_NANDF_D5__RAWNAND_D5 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D5, 0x06F8, 0x0310, 1, 0x0000, 0), /* MX6Q_PAD_NANDF_D5__USDHC2_DAT5 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D5, 0x06F8, 0x0310, 2, 0x0000, 0), /* MX6Q_PAD_NANDF_D5__GPU3D_GPU_DBG_OUT_5 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D5, 0x06F8, 0x0310, 3, 0x0000, 0), /* MX6Q_PAD_NANDF_D5__USBOH3_UH2_DFD_OUT21 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D5, 0x06F8, 0x0310, 4, 0x0000, 0), /* MX6Q_PAD_NANDF_D5__USBOH3_UH3_DFD_OUT21 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D5, 0x06F8, 0x0310, 5, 0x0000, 0), /* MX6Q_PAD_NANDF_D5__GPIO_2_5 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D5, 0x06F8, 0x0310, 6, 0x0000, 0), /* MX6Q_PAD_NANDF_D5__IPU1_IPU_DIAG_BUS_5 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D5, 0x06F8, 0x0310, 7, 0x0000, 0), /* MX6Q_PAD_NANDF_D5__IPU2_IPU_DIAG_BUS_5 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D6, 0x06FC, 0x0314, 0, 0x0000, 0), /* MX6Q_PAD_NANDF_D6__RAWNAND_D6 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D6, 0x06FC, 0x0314, 1, 0x0000, 0), /* MX6Q_PAD_NANDF_D6__USDHC2_DAT6 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D6, 0x06FC, 0x0314, 2, 0x0000, 0), /* MX6Q_PAD_NANDF_D6__GPU3D_GPU_DBG_OUT_6 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D6, 0x06FC, 0x0314, 3, 0x0000, 0), /* MX6Q_PAD_NANDF_D6__USBOH3_UH2_DFD_OUT22 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D6, 0x06FC, 0x0314, 4, 0x0000, 0), /* MX6Q_PAD_NANDF_D6__USBOH3_UH3_DFD_OUT22 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D6, 0x06FC, 0x0314, 5, 0x0000, 0), /* MX6Q_PAD_NANDF_D6__GPIO_2_6 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D6, 0x06FC, 0x0314, 6, 0x0000, 0), /* MX6Q_PAD_NANDF_D6__IPU1_IPU_DIAG_BUS_6 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D6, 0x06FC, 0x0314, 7, 0x0000, 0), /* MX6Q_PAD_NANDF_D6__IPU2_IPU_DIAG_BUS_6 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D7, 0x0700, 0x0318, 0, 0x0000, 0), /* MX6Q_PAD_NANDF_D7__RAWNAND_D7 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D7, 0x0700, 0x0318, 1, 0x0000, 0), /* MX6Q_PAD_NANDF_D7__USDHC2_DAT7 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D7, 0x0700, 0x0318, 2, 0x0000, 0), /* MX6Q_PAD_NANDF_D7__GPU3D_GPU_DBG_OUT_7 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D7, 0x0700, 0x0318, 3, 0x0000, 0), /* MX6Q_PAD_NANDF_D7__USBOH3_UH2_DFD_OUT23 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D7, 0x0700, 0x0318, 4, 0x0000, 0), /* MX6Q_PAD_NANDF_D7__USBOH3_UH3_DFD_OUT23 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D7, 0x0700, 0x0318, 5, 0x0000, 0), /* MX6Q_PAD_NANDF_D7__GPIO_2_7 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D7, 0x0700, 0x0318, 6, 0x0000, 0), /* MX6Q_PAD_NANDF_D7__IPU1_IPU_DIAG_BUS_7 */ - IMX_PIN_REG(MX6Q_PAD_NANDF_D7, 0x0700, 0x0318, 7, 0x0000, 0), /* MX6Q_PAD_NANDF_D7__IPU2_IPU_DIAG_BUS_7 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT0, 0x0704, 0x031C, 0, 0x0000, 0), /* MX6Q_PAD_SD4_DAT0__RAWNAND_D8 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT0, 0x0704, 0x031C, 1, 0x0000, 0), /* MX6Q_PAD_SD4_DAT0__USDHC4_DAT0 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT0, 0x0704, 0x031C, 2, 0x0000, 0), /* MX6Q_PAD_SD4_DAT0__RAWNAND_DQS */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT0, 0x0704, 0x031C, 3, 0x0000, 0), /* MX6Q_PAD_SD4_DAT0__USBOH3_UH2_DFD_OUT24 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT0, 0x0704, 0x031C, 4, 0x0000, 0), /* MX6Q_PAD_SD4_DAT0__USBOH3_UH3_DFD_OUT24 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT0, 0x0704, 0x031C, 5, 0x0000, 0), /* MX6Q_PAD_SD4_DAT0__GPIO_2_8 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT0, 0x0704, 0x031C, 6, 0x0000, 0), /* MX6Q_PAD_SD4_DAT0__IPU1_IPU_DIAG_BUS_8 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT0, 0x0704, 0x031C, 7, 0x0000, 0), /* MX6Q_PAD_SD4_DAT0__IPU2_IPU_DIAG_BUS_8 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT1, 0x0708, 0x0320, 0, 0x0000, 0), /* MX6Q_PAD_SD4_DAT1__RAWNAND_D9 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT1, 0x0708, 0x0320, 1, 0x0000, 0), /* MX6Q_PAD_SD4_DAT1__USDHC4_DAT1 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT1, 0x0708, 0x0320, 2, 0x0000, 0), /* MX6Q_PAD_SD4_DAT1__PWM3_PWMO */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT1, 0x0708, 0x0320, 3, 0x0000, 0), /* MX6Q_PAD_SD4_DAT1__USBOH3_UH2_DFD_OUT25 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT1, 0x0708, 0x0320, 4, 0x0000, 0), /* MX6Q_PAD_SD4_DAT1__USBOH3_UH3_DFD_OUT25 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT1, 0x0708, 0x0320, 5, 0x0000, 0), /* MX6Q_PAD_SD4_DAT1__GPIO_2_9 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT1, 0x0708, 0x0320, 6, 0x0000, 0), /* MX6Q_PAD_SD4_DAT1__IPU1_IPU_DIAG_BUS_9 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT1, 0x0708, 0x0320, 7, 0x0000, 0), /* MX6Q_PAD_SD4_DAT1__IPU2_IPU_DIAG_BUS_9 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT2, 0x070C, 0x0324, 0, 0x0000, 0), /* MX6Q_PAD_SD4_DAT2__RAWNAND_D10 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT2, 0x070C, 0x0324, 1, 0x0000, 0), /* MX6Q_PAD_SD4_DAT2__USDHC4_DAT2 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT2, 0x070C, 0x0324, 2, 0x0000, 0), /* MX6Q_PAD_SD4_DAT2__PWM4_PWMO */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT2, 0x070C, 0x0324, 3, 0x0000, 0), /* MX6Q_PAD_SD4_DAT2__USBOH3_UH2_DFD_OUT26 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT2, 0x070C, 0x0324, 4, 0x0000, 0), /* MX6Q_PAD_SD4_DAT2__USBOH3_UH3_DFD_OUT26 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT2, 0x070C, 0x0324, 5, 0x0000, 0), /* MX6Q_PAD_SD4_DAT2__GPIO_2_10 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT2, 0x070C, 0x0324, 6, 0x0000, 0), /* MX6Q_PAD_SD4_DAT2__IPU1_IPU_DIAG_BUS_10 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT2, 0x070C, 0x0324, 7, 0x0000, 0), /* MX6Q_PAD_SD4_DAT2__IPU2_IPU_DIAG_BUS_10 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT3, 0x0710, 0x0328, 0, 0x0000, 0), /* MX6Q_PAD_SD4_DAT3__RAWNAND_D11 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT3, 0x0710, 0x0328, 1, 0x0000, 0), /* MX6Q_PAD_SD4_DAT3__USDHC4_DAT3 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT3, 0x0710, 0x0328, 3, 0x0000, 0), /* MX6Q_PAD_SD4_DAT3__USBOH3_UH2_DFD_OUT27 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT3, 0x0710, 0x0328, 4, 0x0000, 0), /* MX6Q_PAD_SD4_DAT3__USBOH3_UH3_DFD_OUT27 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT3, 0x0710, 0x0328, 5, 0x0000, 0), /* MX6Q_PAD_SD4_DAT3__GPIO_2_11 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT3, 0x0710, 0x0328, 6, 0x0000, 0), /* MX6Q_PAD_SD4_DAT3__IPU1_IPU_DIAG_BUS_11 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT3, 0x0710, 0x0328, 7, 0x0000, 0), /* MX6Q_PAD_SD4_DAT3__IPU2_IPU_DIAG_BUS_11 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT4, 0x0714, 0x032C, 0, 0x0000, 0), /* MX6Q_PAD_SD4_DAT4__RAWNAND_D12 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT4, 0x0714, 0x032C, 1, 0x0000, 0), /* MX6Q_PAD_SD4_DAT4__USDHC4_DAT4 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT4, 0x0714, 0x032C, 2, 0x0928, 6), /* MX6Q_PAD_SD4_DAT4__UART2_RXD */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT4, 0x0714, 0x032C, 3, 0x0000, 0), /* MX6Q_PAD_SD4_DAT4__USBOH3_UH2_DFD_OUT28 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT4, 0x0714, 0x032C, 4, 0x0000, 0), /* MX6Q_PAD_SD4_DAT4__USBOH3_UH3_DFD_OUT28 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT4, 0x0714, 0x032C, 5, 0x0000, 0), /* MX6Q_PAD_SD4_DAT4__GPIO_2_12 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT4, 0x0714, 0x032C, 6, 0x0000, 0), /* MX6Q_PAD_SD4_DAT4__IPU1_IPU_DIAG_BUS_12 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT4, 0x0714, 0x032C, 7, 0x0000, 0), /* MX6Q_PAD_SD4_DAT4__IPU2_IPU_DIAG_BUS_12 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT5, 0x0718, 0x0330, 0, 0x0000, 0), /* MX6Q_PAD_SD4_DAT5__RAWNAND_D13 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT5, 0x0718, 0x0330, 1, 0x0000, 0), /* MX6Q_PAD_SD4_DAT5__USDHC4_DAT5 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT5, 0x0718, 0x0330, 2, 0x0924, 4), /* MX6Q_PAD_SD4_DAT5__UART2_RTS */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT5, 0x0718, 0x0330, 3, 0x0000, 0), /* MX6Q_PAD_SD4_DAT5__USBOH3_UH2_DFD_OUT29 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT5, 0x0718, 0x0330, 4, 0x0000, 0), /* MX6Q_PAD_SD4_DAT5__USBOH3_UH3_DFD_OUT29 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT5, 0x0718, 0x0330, 5, 0x0000, 0), /* MX6Q_PAD_SD4_DAT5__GPIO_2_13 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT5, 0x0718, 0x0330, 6, 0x0000, 0), /* MX6Q_PAD_SD4_DAT5__IPU1_IPU_DIAG_BUS_13 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT5, 0x0718, 0x0330, 7, 0x0000, 0), /* MX6Q_PAD_SD4_DAT5__IPU2_IPU_DIAG_BUS_13 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT6, 0x071C, 0x0334, 0, 0x0000, 0), /* MX6Q_PAD_SD4_DAT6__RAWNAND_D14 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT6, 0x071C, 0x0334, 1, 0x0000, 0), /* MX6Q_PAD_SD4_DAT6__USDHC4_DAT6 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT6, 0x071C, 0x0334, 2, 0x0924, 5), /* MX6Q_PAD_SD4_DAT6__UART2_CTS */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT6, 0x071C, 0x0334, 3, 0x0000, 0), /* MX6Q_PAD_SD4_DAT6__USBOH3_UH2_DFD_OUT30 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT6, 0x071C, 0x0334, 4, 0x0000, 0), /* MX6Q_PAD_SD4_DAT6__USBOH3_UH3_DFD_OUT30 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT6, 0x071C, 0x0334, 5, 0x0000, 0), /* MX6Q_PAD_SD4_DAT6__GPIO_2_14 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT6, 0x071C, 0x0334, 6, 0x0000, 0), /* MX6Q_PAD_SD4_DAT6__IPU1_IPU_DIAG_BUS_14 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT6, 0x071C, 0x0334, 7, 0x0000, 0), /* MX6Q_PAD_SD4_DAT6__IPU2_IPU_DIAG_BUS_14 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT7, 0x0720, 0x0338, 0, 0x0000, 0), /* MX6Q_PAD_SD4_DAT7__RAWNAND_D15 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT7, 0x0720, 0x0338, 1, 0x0000, 0), /* MX6Q_PAD_SD4_DAT7__USDHC4_DAT7 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT7, 0x0720, 0x0338, 2, 0x0000, 0), /* MX6Q_PAD_SD4_DAT7__UART2_TXD */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT7, 0x0720, 0x0338, 3, 0x0000, 0), /* MX6Q_PAD_SD4_DAT7__USBOH3_UH2_DFD_OUT31 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT7, 0x0720, 0x0338, 4, 0x0000, 0), /* MX6Q_PAD_SD4_DAT7__USBOH3_UH3_DFD_OUT31 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT7, 0x0720, 0x0338, 5, 0x0000, 0), /* MX6Q_PAD_SD4_DAT7__GPIO_2_15 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT7, 0x0720, 0x0338, 6, 0x0000, 0), /* MX6Q_PAD_SD4_DAT7__IPU1_IPU_DIAG_BUS_15 */ - IMX_PIN_REG(MX6Q_PAD_SD4_DAT7, 0x0720, 0x0338, 7, 0x0000, 0), /* MX6Q_PAD_SD4_DAT7__IPU2_IPU_DIAG_BUS_15 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT1, 0x0724, 0x033C, 0, 0x0000, 0), /* MX6Q_PAD_SD1_DAT1__USDHC1_DAT1 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT1, 0x0724, 0x033C, 1, 0x0834, 1), /* MX6Q_PAD_SD1_DAT1__ECSPI5_SS0 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT1, 0x0724, 0x033C, 2, 0x0000, 0), /* MX6Q_PAD_SD1_DAT1__PWM3_PWMO */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT1, 0x0724, 0x033C, 3, 0x0000, 0), /* MX6Q_PAD_SD1_DAT1__GPT_CAPIN2 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT1, 0x0724, 0x033C, 4, 0x0000, 0), /* MX6Q_PAD_SD1_DAT1__PCIE_CTRL_MUX_7 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT1, 0x0724, 0x033C, 5, 0x0000, 0), /* MX6Q_PAD_SD1_DAT1__GPIO_1_17 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT1, 0x0724, 0x033C, 6, 0x0000, 0), /* MX6Q_PAD_SD1_DAT1__HDMI_TX_OPHYDTB_0 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT1, 0x0724, 0x033C, 7, 0x0000, 0), /* MX6Q_PAD_SD1_DAT1__ANATOP_TESTO_8 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT0, 0x0728, 0x0340, 0, 0x0000, 0), /* MX6Q_PAD_SD1_DAT0__USDHC1_DAT0 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT0, 0x0728, 0x0340, 1, 0x082C, 1), /* MX6Q_PAD_SD1_DAT0__ECSPI5_MISO */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT0, 0x0728, 0x0340, 2, 0x0000, 0), /* MX6Q_PAD_SD1_DAT0__CAAM_WRAP_RNG_OSCOBS */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT0, 0x0728, 0x0340, 3, 0x0000, 0), /* MX6Q_PAD_SD1_DAT0__GPT_CAPIN1 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT0, 0x0728, 0x0340, 4, 0x0000, 0), /* MX6Q_PAD_SD1_DAT0__PCIE_CTRL_MUX_8 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT0, 0x0728, 0x0340, 5, 0x0000, 0), /* MX6Q_PAD_SD1_DAT0__GPIO_1_16 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT0, 0x0728, 0x0340, 6, 0x0000, 0), /* MX6Q_PAD_SD1_DAT0__HDMI_TX_OPHYDTB_1 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT0, 0x0728, 0x0340, 7, 0x0000, 0), /* MX6Q_PAD_SD1_DAT0__ANATOP_TESTO_7 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT3, 0x072C, 0x0344, 0, 0x0000, 0), /* MX6Q_PAD_SD1_DAT3__USDHC1_DAT3 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT3, 0x072C, 0x0344, 1, 0x0000, 0), /* MX6Q_PAD_SD1_DAT3__ECSPI5_SS2 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT3, 0x072C, 0x0344, 2, 0x0000, 0), /* MX6Q_PAD_SD1_DAT3__GPT_CMPOUT3 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT3, 0x072C, 0x0344, 3, 0x0000, 0), /* MX6Q_PAD_SD1_DAT3__PWM1_PWMO */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT3, 0x072C, 0x0344, 4, 0x0000, 0), /* MX6Q_PAD_SD1_DAT3__WDOG2_WDOG_B */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT3, 0x072C, 0x0344, 5, 0x0000, 0), /* MX6Q_PAD_SD1_DAT3__GPIO_1_21 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT3, 0x072C, 0x0344, 6, 0x0000, 0), /* MX6Q_PAD_SD1_DAT3__WDOG2_WDOG_RST_B_DEB */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT3, 0x072C, 0x0344, 7, 0x0000, 0), /* MX6Q_PAD_SD1_DAT3__ANATOP_TESTO_6 */ - IMX_PIN_REG(MX6Q_PAD_SD1_CMD, 0x0730, 0x0348, 0, 0x0000, 0), /* MX6Q_PAD_SD1_CMD__USDHC1_CMD */ - IMX_PIN_REG(MX6Q_PAD_SD1_CMD, 0x0730, 0x0348, 1, 0x0830, 0), /* MX6Q_PAD_SD1_CMD__ECSPI5_MOSI */ - IMX_PIN_REG(MX6Q_PAD_SD1_CMD, 0x0730, 0x0348, 2, 0x0000, 0), /* MX6Q_PAD_SD1_CMD__PWM4_PWMO */ - IMX_PIN_REG(MX6Q_PAD_SD1_CMD, 0x0730, 0x0348, 3, 0x0000, 0), /* MX6Q_PAD_SD1_CMD__GPT_CMPOUT1 */ - IMX_PIN_REG(MX6Q_PAD_SD1_CMD, 0x0730, 0x0348, 5, 0x0000, 0), /* MX6Q_PAD_SD1_CMD__GPIO_1_18 */ - IMX_PIN_REG(MX6Q_PAD_SD1_CMD, 0x0730, 0x0348, 7, 0x0000, 0), /* MX6Q_PAD_SD1_CMD__ANATOP_TESTO_5 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT2, 0x0734, 0x034C, 0, 0x0000, 0), /* MX6Q_PAD_SD1_DAT2__USDHC1_DAT2 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT2, 0x0734, 0x034C, 1, 0x0838, 1), /* MX6Q_PAD_SD1_DAT2__ECSPI5_SS1 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT2, 0x0734, 0x034C, 2, 0x0000, 0), /* MX6Q_PAD_SD1_DAT2__GPT_CMPOUT2 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT2, 0x0734, 0x034C, 3, 0x0000, 0), /* MX6Q_PAD_SD1_DAT2__PWM2_PWMO */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT2, 0x0734, 0x034C, 4, 0x0000, 0), /* MX6Q_PAD_SD1_DAT2__WDOG1_WDOG_B */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT2, 0x0734, 0x034C, 5, 0x0000, 0), /* MX6Q_PAD_SD1_DAT2__GPIO_1_19 */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT2, 0x0734, 0x034C, 6, 0x0000, 0), /* MX6Q_PAD_SD1_DAT2__WDOG1_WDOG_RST_B_DEB */ - IMX_PIN_REG(MX6Q_PAD_SD1_DAT2, 0x0734, 0x034C, 7, 0x0000, 0), /* MX6Q_PAD_SD1_DAT2__ANATOP_TESTO_4 */ - IMX_PIN_REG(MX6Q_PAD_SD1_CLK, 0x0738, 0x0350, 0, 0x0000, 0), /* MX6Q_PAD_SD1_CLK__USDHC1_CLK */ - IMX_PIN_REG(MX6Q_PAD_SD1_CLK, 0x0738, 0x0350, 1, 0x0828, 0), /* MX6Q_PAD_SD1_CLK__ECSPI5_SCLK */ - IMX_PIN_REG(MX6Q_PAD_SD1_CLK, 0x0738, 0x0350, 2, 0x0000, 0), /* MX6Q_PAD_SD1_CLK__OSC32K_32K_OUT */ - IMX_PIN_REG(MX6Q_PAD_SD1_CLK, 0x0738, 0x0350, 3, 0x0000, 0), /* MX6Q_PAD_SD1_CLK__GPT_CLKIN */ - IMX_PIN_REG(MX6Q_PAD_SD1_CLK, 0x0738, 0x0350, 5, 0x0000, 0), /* MX6Q_PAD_SD1_CLK__GPIO_1_20 */ - IMX_PIN_REG(MX6Q_PAD_SD1_CLK, 0x0738, 0x0350, 6, 0x0000, 0), /* MX6Q_PAD_SD1_CLK__PHY_DTB_0 */ - IMX_PIN_REG(MX6Q_PAD_SD1_CLK, 0x0738, 0x0350, 7, 0x0000, 0), /* MX6Q_PAD_SD1_CLK__SATA_PHY_DTB_0 */ - IMX_PIN_REG(MX6Q_PAD_SD2_CLK, 0x073C, 0x0354, 0, 0x0000, 0), /* MX6Q_PAD_SD2_CLK__USDHC2_CLK */ - IMX_PIN_REG(MX6Q_PAD_SD2_CLK, 0x073C, 0x0354, 1, 0x0828, 1), /* MX6Q_PAD_SD2_CLK__ECSPI5_SCLK */ - IMX_PIN_REG(MX6Q_PAD_SD2_CLK, 0x073C, 0x0354, 2, 0x08E8, 3), /* MX6Q_PAD_SD2_CLK__KPP_COL_5 */ - IMX_PIN_REG(MX6Q_PAD_SD2_CLK, 0x073C, 0x0354, 3, 0x07C0, 1), /* MX6Q_PAD_SD2_CLK__AUDMUX_AUD4_RXFS */ - IMX_PIN_REG(MX6Q_PAD_SD2_CLK, 0x073C, 0x0354, 4, 0x0000, 0), /* MX6Q_PAD_SD2_CLK__PCIE_CTRL_MUX_9 */ - IMX_PIN_REG(MX6Q_PAD_SD2_CLK, 0x073C, 0x0354, 5, 0x0000, 0), /* MX6Q_PAD_SD2_CLK__GPIO_1_10 */ - IMX_PIN_REG(MX6Q_PAD_SD2_CLK, 0x073C, 0x0354, 6, 0x0000, 0), /* MX6Q_PAD_SD2_CLK__PHY_DTB_1 */ - IMX_PIN_REG(MX6Q_PAD_SD2_CLK, 0x073C, 0x0354, 7, 0x0000, 0), /* MX6Q_PAD_SD2_CLK__SATA_PHY_DTB_1 */ - IMX_PIN_REG(MX6Q_PAD_SD2_CMD, 0x0740, 0x0358, 0, 0x0000, 0), /* MX6Q_PAD_SD2_CMD__USDHC2_CMD */ - IMX_PIN_REG(MX6Q_PAD_SD2_CMD, 0x0740, 0x0358, 1, 0x0830, 1), /* MX6Q_PAD_SD2_CMD__ECSPI5_MOSI */ - IMX_PIN_REG(MX6Q_PAD_SD2_CMD, 0x0740, 0x0358, 2, 0x08F4, 2), /* MX6Q_PAD_SD2_CMD__KPP_ROW_5 */ - IMX_PIN_REG(MX6Q_PAD_SD2_CMD, 0x0740, 0x0358, 3, 0x07BC, 1), /* MX6Q_PAD_SD2_CMD__AUDMUX_AUD4_RXC */ - IMX_PIN_REG(MX6Q_PAD_SD2_CMD, 0x0740, 0x0358, 4, 0x0000, 0), /* MX6Q_PAD_SD2_CMD__PCIE_CTRL_MUX_10 */ - IMX_PIN_REG(MX6Q_PAD_SD2_CMD, 0x0740, 0x0358, 5, 0x0000, 0), /* MX6Q_PAD_SD2_CMD__GPIO_1_11 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT3, 0x0744, 0x035C, 0, 0x0000, 0), /* MX6Q_PAD_SD2_DAT3__USDHC2_DAT3 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT3, 0x0744, 0x035C, 1, 0x0000, 0), /* MX6Q_PAD_SD2_DAT3__ECSPI5_SS3 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT3, 0x0744, 0x035C, 2, 0x08EC, 2), /* MX6Q_PAD_SD2_DAT3__KPP_COL_6 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT3, 0x0744, 0x035C, 3, 0x07C4, 1), /* MX6Q_PAD_SD2_DAT3__AUDMUX_AUD4_TXC */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT3, 0x0744, 0x035C, 4, 0x0000, 0), /* MX6Q_PAD_SD2_DAT3__PCIE_CTRL_MUX_11 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT3, 0x0744, 0x035C, 5, 0x0000, 0), /* MX6Q_PAD_SD2_DAT3__GPIO_1_12 */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT3, 0x0744, 0x035C, 6, 0x0000, 0), /* MX6Q_PAD_SD2_DAT3__SJC_DONE */ - IMX_PIN_REG(MX6Q_PAD_SD2_DAT3, 0x0744, 0x035C, 7, 0x0000, 0), /* MX6Q_PAD_SD2_DAT3__ANATOP_TESTO_3 */ -}; - -/* Pad names for the pinmux subsystem */ -static const struct pinctrl_pin_desc imx6q_pinctrl_pads[] = { - IMX_PINCTRL_PIN(MX6Q_PAD_SD2_DAT1), - IMX_PINCTRL_PIN(MX6Q_PAD_SD2_DAT2), - IMX_PINCTRL_PIN(MX6Q_PAD_SD2_DAT0), - IMX_PINCTRL_PIN(MX6Q_PAD_RGMII_TXC), - IMX_PINCTRL_PIN(MX6Q_PAD_RGMII_TD0), - IMX_PINCTRL_PIN(MX6Q_PAD_RGMII_TD1), - IMX_PINCTRL_PIN(MX6Q_PAD_RGMII_TD2), - IMX_PINCTRL_PIN(MX6Q_PAD_RGMII_TD3), - IMX_PINCTRL_PIN(MX6Q_PAD_RGMII_RX_CTL), - IMX_PINCTRL_PIN(MX6Q_PAD_RGMII_RD0), - IMX_PINCTRL_PIN(MX6Q_PAD_RGMII_TX_CTL), - IMX_PINCTRL_PIN(MX6Q_PAD_RGMII_RD1), - IMX_PINCTRL_PIN(MX6Q_PAD_RGMII_RD2), - IMX_PINCTRL_PIN(MX6Q_PAD_RGMII_RD3), - IMX_PINCTRL_PIN(MX6Q_PAD_RGMII_RXC), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_A25), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_EB2), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_D16), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_D17), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_D18), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_D19), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_D20), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_D21), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_D22), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_D23), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_EB3), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_D24), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_D25), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_D26), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_D27), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_D28), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_D29), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_D30), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_D31), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_A24), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_A23), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_A22), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_A21), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_A20), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_A19), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_A18), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_A17), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_A16), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_CS0), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_CS1), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_OE), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_RW), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_LBA), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_EB0), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_EB1), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_DA0), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_DA1), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_DA2), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_DA3), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_DA4), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_DA5), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_DA6), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_DA7), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_DA8), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_DA9), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_DA10), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_DA11), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_DA12), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_DA13), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_DA14), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_DA15), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_WAIT), - IMX_PINCTRL_PIN(MX6Q_PAD_EIM_BCLK), - IMX_PINCTRL_PIN(MX6Q_PAD_DI0_DISP_CLK), - IMX_PINCTRL_PIN(MX6Q_PAD_DI0_PIN15), - IMX_PINCTRL_PIN(MX6Q_PAD_DI0_PIN2), - IMX_PINCTRL_PIN(MX6Q_PAD_DI0_PIN3), - IMX_PINCTRL_PIN(MX6Q_PAD_DI0_PIN4), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT0), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT1), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT2), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT3), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT4), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT5), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT6), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT7), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT8), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT9), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT10), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT11), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT12), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT13), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT14), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT15), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT16), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT17), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT18), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT19), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT20), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT21), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT22), - IMX_PINCTRL_PIN(MX6Q_PAD_DISP0_DAT23), - IMX_PINCTRL_PIN(MX6Q_PAD_ENET_MDIO), - IMX_PINCTRL_PIN(MX6Q_PAD_ENET_REF_CLK), - IMX_PINCTRL_PIN(MX6Q_PAD_ENET_RX_ER), - IMX_PINCTRL_PIN(MX6Q_PAD_ENET_CRS_DV), - IMX_PINCTRL_PIN(MX6Q_PAD_ENET_RXD1), - IMX_PINCTRL_PIN(MX6Q_PAD_ENET_RXD0), - IMX_PINCTRL_PIN(MX6Q_PAD_ENET_TX_EN), - IMX_PINCTRL_PIN(MX6Q_PAD_ENET_TXD1), - IMX_PINCTRL_PIN(MX6Q_PAD_ENET_TXD0), - IMX_PINCTRL_PIN(MX6Q_PAD_ENET_MDC), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D40), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D41), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D42), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D43), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D44), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D45), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D46), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D47), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_SDQS5), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_DQM5), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D32), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D33), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D34), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D35), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D36), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D37), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D38), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D39), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_DQM4), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_SDQS4), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D24), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D25), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D26), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D27), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D28), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D29), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_SDQS3), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D30), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D31), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_DQM3), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D16), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D17), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D18), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D19), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D20), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D21), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D22), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_SDQS2), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D23), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_DQM2), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_A0), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_A1), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_A2), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_A3), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_A4), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_A5), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_A6), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_A7), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_A8), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_A9), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_A10), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_A11), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_A12), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_A13), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_A14), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_A15), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_CAS), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_CS0), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_CS1), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_RAS), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_RESET), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_SDBA0), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_SDBA1), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_SDCLK_0), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_SDBA2), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_SDCKE0), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_SDCLK_1), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_SDCKE1), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_SDODT0), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_SDODT1), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_SDWE), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D0), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D1), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D2), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D3), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D4), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D5), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_SDQS0), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D6), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D7), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_DQM0), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D8), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D9), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D10), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D11), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D12), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D13), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D14), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_SDQS1), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D15), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_DQM1), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D48), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D49), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D50), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D51), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D52), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D53), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D54), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D55), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_SDQS6), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_DQM6), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D56), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_SDQS7), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D57), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D58), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D59), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D60), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_DQM7), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D61), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D62), - IMX_PINCTRL_PIN(MX6Q_PAD_DRAM_D63), - IMX_PINCTRL_PIN(MX6Q_PAD_KEY_COL0), - IMX_PINCTRL_PIN(MX6Q_PAD_KEY_ROW0), - IMX_PINCTRL_PIN(MX6Q_PAD_KEY_COL1), - IMX_PINCTRL_PIN(MX6Q_PAD_KEY_ROW1), - IMX_PINCTRL_PIN(MX6Q_PAD_KEY_COL2), - IMX_PINCTRL_PIN(MX6Q_PAD_KEY_ROW2), - IMX_PINCTRL_PIN(MX6Q_PAD_KEY_COL3), - IMX_PINCTRL_PIN(MX6Q_PAD_KEY_ROW3), - IMX_PINCTRL_PIN(MX6Q_PAD_KEY_COL4), - IMX_PINCTRL_PIN(MX6Q_PAD_KEY_ROW4), - IMX_PINCTRL_PIN(MX6Q_PAD_GPIO_0), - IMX_PINCTRL_PIN(MX6Q_PAD_GPIO_1), - IMX_PINCTRL_PIN(MX6Q_PAD_GPIO_9), - IMX_PINCTRL_PIN(MX6Q_PAD_GPIO_3), - IMX_PINCTRL_PIN(MX6Q_PAD_GPIO_6), - IMX_PINCTRL_PIN(MX6Q_PAD_GPIO_2), - IMX_PINCTRL_PIN(MX6Q_PAD_GPIO_4), - IMX_PINCTRL_PIN(MX6Q_PAD_GPIO_5), - IMX_PINCTRL_PIN(MX6Q_PAD_GPIO_7), - IMX_PINCTRL_PIN(MX6Q_PAD_GPIO_8), - IMX_PINCTRL_PIN(MX6Q_PAD_GPIO_16), - IMX_PINCTRL_PIN(MX6Q_PAD_GPIO_17), - IMX_PINCTRL_PIN(MX6Q_PAD_GPIO_18), - IMX_PINCTRL_PIN(MX6Q_PAD_GPIO_19), - IMX_PINCTRL_PIN(MX6Q_PAD_CSI0_PIXCLK), - IMX_PINCTRL_PIN(MX6Q_PAD_CSI0_MCLK), - IMX_PINCTRL_PIN(MX6Q_PAD_CSI0_DATA_EN), - IMX_PINCTRL_PIN(MX6Q_PAD_CSI0_VSYNC), - IMX_PINCTRL_PIN(MX6Q_PAD_CSI0_DAT4), - IMX_PINCTRL_PIN(MX6Q_PAD_CSI0_DAT5), - IMX_PINCTRL_PIN(MX6Q_PAD_CSI0_DAT6), - IMX_PINCTRL_PIN(MX6Q_PAD_CSI0_DAT7), - IMX_PINCTRL_PIN(MX6Q_PAD_CSI0_DAT8), - IMX_PINCTRL_PIN(MX6Q_PAD_CSI0_DAT9), - IMX_PINCTRL_PIN(MX6Q_PAD_CSI0_DAT10), - IMX_PINCTRL_PIN(MX6Q_PAD_CSI0_DAT11), - IMX_PINCTRL_PIN(MX6Q_PAD_CSI0_DAT12), - IMX_PINCTRL_PIN(MX6Q_PAD_CSI0_DAT13), - IMX_PINCTRL_PIN(MX6Q_PAD_CSI0_DAT14), - IMX_PINCTRL_PIN(MX6Q_PAD_CSI0_DAT15), - IMX_PINCTRL_PIN(MX6Q_PAD_CSI0_DAT16), - IMX_PINCTRL_PIN(MX6Q_PAD_CSI0_DAT17), - IMX_PINCTRL_PIN(MX6Q_PAD_CSI0_DAT18), - IMX_PINCTRL_PIN(MX6Q_PAD_CSI0_DAT19), - IMX_PINCTRL_PIN(MX6Q_PAD_JTAG_TMS), - IMX_PINCTRL_PIN(MX6Q_PAD_JTAG_MOD), - IMX_PINCTRL_PIN(MX6Q_PAD_JTAG_TRSTB), - IMX_PINCTRL_PIN(MX6Q_PAD_JTAG_TDI), - IMX_PINCTRL_PIN(MX6Q_PAD_JTAG_TCK), - IMX_PINCTRL_PIN(MX6Q_PAD_JTAG_TDO), - IMX_PINCTRL_PIN(MX6Q_PAD_LVDS1_TX3_P), - IMX_PINCTRL_PIN(MX6Q_PAD_LVDS1_TX2_P), - IMX_PINCTRL_PIN(MX6Q_PAD_LVDS1_CLK_P), - IMX_PINCTRL_PIN(MX6Q_PAD_LVDS1_TX1_P), - IMX_PINCTRL_PIN(MX6Q_PAD_LVDS1_TX0_P), - IMX_PINCTRL_PIN(MX6Q_PAD_LVDS0_TX3_P), - IMX_PINCTRL_PIN(MX6Q_PAD_LVDS0_CLK_P), - IMX_PINCTRL_PIN(MX6Q_PAD_LVDS0_TX2_P), - IMX_PINCTRL_PIN(MX6Q_PAD_LVDS0_TX1_P), - IMX_PINCTRL_PIN(MX6Q_PAD_LVDS0_TX0_P), - IMX_PINCTRL_PIN(MX6Q_PAD_TAMPER), - IMX_PINCTRL_PIN(MX6Q_PAD_PMIC_ON_REQ), - IMX_PINCTRL_PIN(MX6Q_PAD_PMIC_STBY_REQ), - IMX_PINCTRL_PIN(MX6Q_PAD_POR_B), - IMX_PINCTRL_PIN(MX6Q_PAD_BOOT_MODE1), - IMX_PINCTRL_PIN(MX6Q_PAD_RESET_IN_B), - IMX_PINCTRL_PIN(MX6Q_PAD_BOOT_MODE0), - IMX_PINCTRL_PIN(MX6Q_PAD_TEST_MODE), - IMX_PINCTRL_PIN(MX6Q_PAD_SD3_DAT7), - IMX_PINCTRL_PIN(MX6Q_PAD_SD3_DAT6), - IMX_PINCTRL_PIN(MX6Q_PAD_SD3_DAT5), - IMX_PINCTRL_PIN(MX6Q_PAD_SD3_DAT4), - IMX_PINCTRL_PIN(MX6Q_PAD_SD3_CMD), - IMX_PINCTRL_PIN(MX6Q_PAD_SD3_CLK), - IMX_PINCTRL_PIN(MX6Q_PAD_SD3_DAT0), - IMX_PINCTRL_PIN(MX6Q_PAD_SD3_DAT1), - IMX_PINCTRL_PIN(MX6Q_PAD_SD3_DAT2), - IMX_PINCTRL_PIN(MX6Q_PAD_SD3_DAT3), - IMX_PINCTRL_PIN(MX6Q_PAD_SD3_RST), - IMX_PINCTRL_PIN(MX6Q_PAD_NANDF_CLE), - IMX_PINCTRL_PIN(MX6Q_PAD_NANDF_ALE), - IMX_PINCTRL_PIN(MX6Q_PAD_NANDF_WP_B), - IMX_PINCTRL_PIN(MX6Q_PAD_NANDF_RB0), - IMX_PINCTRL_PIN(MX6Q_PAD_NANDF_CS0), - IMX_PINCTRL_PIN(MX6Q_PAD_NANDF_CS1), - IMX_PINCTRL_PIN(MX6Q_PAD_NANDF_CS2), - IMX_PINCTRL_PIN(MX6Q_PAD_NANDF_CS3), - IMX_PINCTRL_PIN(MX6Q_PAD_SD4_CMD), - IMX_PINCTRL_PIN(MX6Q_PAD_SD4_CLK), - IMX_PINCTRL_PIN(MX6Q_PAD_NANDF_D0), - IMX_PINCTRL_PIN(MX6Q_PAD_NANDF_D1), - IMX_PINCTRL_PIN(MX6Q_PAD_NANDF_D2), - IMX_PINCTRL_PIN(MX6Q_PAD_NANDF_D3), - IMX_PINCTRL_PIN(MX6Q_PAD_NANDF_D4), - IMX_PINCTRL_PIN(MX6Q_PAD_NANDF_D5), - IMX_PINCTRL_PIN(MX6Q_PAD_NANDF_D6), - IMX_PINCTRL_PIN(MX6Q_PAD_NANDF_D7), - IMX_PINCTRL_PIN(MX6Q_PAD_SD4_DAT0), - IMX_PINCTRL_PIN(MX6Q_PAD_SD4_DAT1), - IMX_PINCTRL_PIN(MX6Q_PAD_SD4_DAT2), - IMX_PINCTRL_PIN(MX6Q_PAD_SD4_DAT3), - IMX_PINCTRL_PIN(MX6Q_PAD_SD4_DAT4), - IMX_PINCTRL_PIN(MX6Q_PAD_SD4_DAT5), - IMX_PINCTRL_PIN(MX6Q_PAD_SD4_DAT6), - IMX_PINCTRL_PIN(MX6Q_PAD_SD4_DAT7), - IMX_PINCTRL_PIN(MX6Q_PAD_SD1_DAT1), - IMX_PINCTRL_PIN(MX6Q_PAD_SD1_DAT0), - IMX_PINCTRL_PIN(MX6Q_PAD_SD1_DAT3), - IMX_PINCTRL_PIN(MX6Q_PAD_SD1_CMD), - IMX_PINCTRL_PIN(MX6Q_PAD_SD1_DAT2), - IMX_PINCTRL_PIN(MX6Q_PAD_SD1_CLK), - IMX_PINCTRL_PIN(MX6Q_PAD_SD2_CLK), - IMX_PINCTRL_PIN(MX6Q_PAD_SD2_CMD), - IMX_PINCTRL_PIN(MX6Q_PAD_SD2_DAT3), -}; - -static struct imx_pinctrl_soc_info imx6q_pinctrl_info = { - .pins = imx6q_pinctrl_pads, - .npins = ARRAY_SIZE(imx6q_pinctrl_pads), - .pin_regs = imx6q_pin_regs, - .npin_regs = ARRAY_SIZE(imx6q_pin_regs), -}; - -static struct of_device_id imx6q_pinctrl_of_match[] __devinitdata = { - { .compatible = "fsl,imx6q-iomuxc", }, - { /* sentinel */ } -}; - -static int __devinit imx6q_pinctrl_probe(struct platform_device *pdev) -{ - return imx_pinctrl_probe(pdev, &imx6q_pinctrl_info); -} - -static struct platform_driver imx6q_pinctrl_driver = { - .driver = { - .name = "imx6q-pinctrl", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(imx6q_pinctrl_of_match), - }, - .probe = imx6q_pinctrl_probe, - .remove = __devexit_p(imx_pinctrl_remove), -}; - -static int __init imx6q_pinctrl_init(void) -{ - return platform_driver_register(&imx6q_pinctrl_driver); -} -arch_initcall(imx6q_pinctrl_init); - -static void __exit imx6q_pinctrl_exit(void) -{ - platform_driver_unregister(&imx6q_pinctrl_driver); -} -module_exit(imx6q_pinctrl_exit); -MODULE_AUTHOR("Dong Aisheng "); -MODULE_DESCRIPTION("Freescale IMX6Q pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/pinctrl/pinctrl-mxs.c b/trunk/drivers/pinctrl/pinctrl-mxs.c deleted file mode 100644 index 556e45a213eb..000000000000 --- a/trunk/drivers/pinctrl/pinctrl-mxs.c +++ /dev/null @@ -1,528 +0,0 @@ -/* - * Copyright 2012 Freescale Semiconductor, Inc. - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "core.h" -#include "pinctrl-mxs.h" - -#define SUFFIX_LEN 4 - -struct mxs_pinctrl_data { - struct device *dev; - struct pinctrl_dev *pctl; - void __iomem *base; - struct mxs_pinctrl_soc_data *soc; -}; - -static int mxs_get_groups_count(struct pinctrl_dev *pctldev) -{ - struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev); - - return d->soc->ngroups; -} - -static const char *mxs_get_group_name(struct pinctrl_dev *pctldev, - unsigned group) -{ - struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev); - - return d->soc->groups[group].name; -} - -static int mxs_get_group_pins(struct pinctrl_dev *pctldev, unsigned group, - const unsigned **pins, unsigned *num_pins) -{ - struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev); - - *pins = d->soc->groups[group].pins; - *num_pins = d->soc->groups[group].npins; - - return 0; -} - -static void mxs_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, - unsigned offset) -{ - seq_printf(s, " %s", dev_name(pctldev->dev)); -} - -static int mxs_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *np, - struct pinctrl_map **map, unsigned *num_maps) -{ - struct pinctrl_map *new_map; - char *group = NULL; - unsigned new_num = 1; - unsigned long config = 0; - unsigned long *pconfig; - int length = strlen(np->name) + SUFFIX_LEN; - bool purecfg = false; - u32 val, reg; - int ret, i = 0; - - /* Check for pin config node which has no 'reg' property */ - if (of_property_read_u32(np, "reg", ®)) - purecfg = true; - - ret = of_property_read_u32(np, "fsl,drive-strength", &val); - if (!ret) - config = val | MA_PRESENT; - ret = of_property_read_u32(np, "fsl,voltage", &val); - if (!ret) - config |= val << VOL_SHIFT | VOL_PRESENT; - ret = of_property_read_u32(np, "fsl,pull-up", &val); - if (!ret) - config |= val << PULL_SHIFT | PULL_PRESENT; - - /* Check for group node which has both mux and config settings */ - if (!purecfg && config) - new_num = 2; - - new_map = kzalloc(sizeof(*new_map) * new_num, GFP_KERNEL); - if (!new_map) - return -ENOMEM; - - if (!purecfg) { - new_map[i].type = PIN_MAP_TYPE_MUX_GROUP; - new_map[i].data.mux.function = np->name; - - /* Compose group name */ - group = kzalloc(length, GFP_KERNEL); - if (!group) - return -ENOMEM; - snprintf(group, length, "%s.%d", np->name, reg); - new_map[i].data.mux.group = group; - i++; - } - - if (config) { - pconfig = kmemdup(&config, sizeof(config), GFP_KERNEL); - if (!pconfig) { - ret = -ENOMEM; - goto free; - } - - new_map[i].type = PIN_MAP_TYPE_CONFIGS_GROUP; - new_map[i].data.configs.group_or_pin = purecfg ? np->name : - group; - new_map[i].data.configs.configs = pconfig; - new_map[i].data.configs.num_configs = 1; - } - - *map = new_map; - *num_maps = new_num; - - return 0; - -free: - kfree(new_map); - return ret; -} - -static void mxs_dt_free_map(struct pinctrl_dev *pctldev, - struct pinctrl_map *map, unsigned num_maps) -{ - int i; - - for (i = 0; i < num_maps; i++) { - if (map[i].type == PIN_MAP_TYPE_MUX_GROUP) - kfree(map[i].data.mux.group); - if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP) - kfree(map[i].data.configs.configs); - } - - kfree(map); -} - -static struct pinctrl_ops mxs_pinctrl_ops = { - .get_groups_count = mxs_get_groups_count, - .get_group_name = mxs_get_group_name, - .get_group_pins = mxs_get_group_pins, - .pin_dbg_show = mxs_pin_dbg_show, - .dt_node_to_map = mxs_dt_node_to_map, - .dt_free_map = mxs_dt_free_map, -}; - -static int mxs_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev) -{ - struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev); - - return d->soc->nfunctions; -} - -static const char *mxs_pinctrl_get_func_name(struct pinctrl_dev *pctldev, - unsigned function) -{ - struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev); - - return d->soc->functions[function].name; -} - -static int mxs_pinctrl_get_func_groups(struct pinctrl_dev *pctldev, - unsigned group, - const char * const **groups, - unsigned * const num_groups) -{ - struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev); - - *groups = d->soc->functions[group].groups; - *num_groups = d->soc->functions[group].ngroups; - - return 0; -} - -static int mxs_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned selector, - unsigned group) -{ - struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev); - struct mxs_group *g = &d->soc->groups[group]; - void __iomem *reg; - u8 bank, shift; - u16 pin; - int i; - - for (i = 0; i < g->npins; i++) { - bank = PINID_TO_BANK(g->pins[i]); - pin = PINID_TO_PIN(g->pins[i]); - reg = d->base + d->soc->regs->muxsel; - reg += bank * 0x20 + pin / 16 * 0x10; - shift = pin % 16 * 2; - - writel(0x3 << shift, reg + CLR); - writel(g->muxsel[i] << shift, reg + SET); - } - - return 0; -} - -static struct pinmux_ops mxs_pinmux_ops = { - .get_functions_count = mxs_pinctrl_get_funcs_count, - .get_function_name = mxs_pinctrl_get_func_name, - .get_function_groups = mxs_pinctrl_get_func_groups, - .enable = mxs_pinctrl_enable, -}; - -static int mxs_pinconf_get(struct pinctrl_dev *pctldev, - unsigned pin, unsigned long *config) -{ - return -ENOTSUPP; -} - -static int mxs_pinconf_set(struct pinctrl_dev *pctldev, - unsigned pin, unsigned long config) -{ - return -ENOTSUPP; -} - -static int mxs_pinconf_group_get(struct pinctrl_dev *pctldev, - unsigned group, unsigned long *config) -{ - struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev); - - *config = d->soc->groups[group].config; - - return 0; -} - -static int mxs_pinconf_group_set(struct pinctrl_dev *pctldev, - unsigned group, unsigned long config) -{ - struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev); - struct mxs_group *g = &d->soc->groups[group]; - void __iomem *reg; - u8 ma, vol, pull, bank, shift; - u16 pin; - int i; - - ma = CONFIG_TO_MA(config); - vol = CONFIG_TO_VOL(config); - pull = CONFIG_TO_PULL(config); - - for (i = 0; i < g->npins; i++) { - bank = PINID_TO_BANK(g->pins[i]); - pin = PINID_TO_PIN(g->pins[i]); - - /* drive */ - reg = d->base + d->soc->regs->drive; - reg += bank * 0x40 + pin / 8 * 0x10; - - /* mA */ - if (config & MA_PRESENT) { - shift = pin % 8 * 4; - writel(0x3 << shift, reg + CLR); - writel(ma << shift, reg + SET); - } - - /* vol */ - if (config & VOL_PRESENT) { - shift = pin % 8 * 4 + 2; - if (vol) - writel(1 << shift, reg + SET); - else - writel(1 << shift, reg + CLR); - } - - /* pull */ - if (config & PULL_PRESENT) { - reg = d->base + d->soc->regs->pull; - reg += bank * 0x10; - shift = pin; - if (pull) - writel(1 << shift, reg + SET); - else - writel(1 << shift, reg + CLR); - } - } - - /* cache the config value for mxs_pinconf_group_get() */ - g->config = config; - - return 0; -} - -static void mxs_pinconf_dbg_show(struct pinctrl_dev *pctldev, - struct seq_file *s, unsigned pin) -{ - /* Not support */ -} - -static void mxs_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, - struct seq_file *s, unsigned group) -{ - unsigned long config; - - if (!mxs_pinconf_group_get(pctldev, group, &config)) - seq_printf(s, "0x%lx", config); -} - -struct pinconf_ops mxs_pinconf_ops = { - .pin_config_get = mxs_pinconf_get, - .pin_config_set = mxs_pinconf_set, - .pin_config_group_get = mxs_pinconf_group_get, - .pin_config_group_set = mxs_pinconf_group_set, - .pin_config_dbg_show = mxs_pinconf_dbg_show, - .pin_config_group_dbg_show = mxs_pinconf_group_dbg_show, -}; - -static struct pinctrl_desc mxs_pinctrl_desc = { - .pctlops = &mxs_pinctrl_ops, - .pmxops = &mxs_pinmux_ops, - .confops = &mxs_pinconf_ops, - .owner = THIS_MODULE, -}; - -static int __devinit mxs_pinctrl_parse_group(struct platform_device *pdev, - struct device_node *np, int idx, - const char **out_name) -{ - struct mxs_pinctrl_data *d = platform_get_drvdata(pdev); - struct mxs_group *g = &d->soc->groups[idx]; - struct property *prop; - const char *propname = "fsl,pinmux-ids"; - char *group; - int length = strlen(np->name) + SUFFIX_LEN; - int i; - u32 val; - - group = devm_kzalloc(&pdev->dev, length, GFP_KERNEL); - if (!group) - return -ENOMEM; - if (of_property_read_u32(np, "reg", &val)) - snprintf(group, length, "%s", np->name); - else - snprintf(group, length, "%s.%d", np->name, val); - g->name = group; - - prop = of_find_property(np, propname, &length); - if (!prop) - return -EINVAL; - g->npins = length / sizeof(u32); - - g->pins = devm_kzalloc(&pdev->dev, g->npins * sizeof(*g->pins), - GFP_KERNEL); - if (!g->pins) - return -ENOMEM; - - g->muxsel = devm_kzalloc(&pdev->dev, g->npins * sizeof(*g->muxsel), - GFP_KERNEL); - if (!g->muxsel) - return -ENOMEM; - - of_property_read_u32_array(np, propname, g->pins, g->npins); - for (i = 0; i < g->npins; i++) { - g->muxsel[i] = MUXID_TO_MUXSEL(g->pins[i]); - g->pins[i] = MUXID_TO_PINID(g->pins[i]); - } - - if (out_name) - *out_name = g->name; - - return 0; -} - -static int __devinit mxs_pinctrl_probe_dt(struct platform_device *pdev, - struct mxs_pinctrl_data *d) -{ - struct mxs_pinctrl_soc_data *soc = d->soc; - struct device_node *np = pdev->dev.of_node; - struct device_node *child; - struct mxs_function *f; - const char *gpio_compat = "fsl,mxs-gpio"; - const char *fn, *fnull = ""; - int i = 0, idxf = 0, idxg = 0; - int ret; - u32 val; - - child = of_get_next_child(np, NULL); - if (!child) { - dev_err(&pdev->dev, "no group is defined\n"); - return -ENOENT; - } - - /* Count total functions and groups */ - fn = fnull; - for_each_child_of_node(np, child) { - if (of_device_is_compatible(child, gpio_compat)) - continue; - soc->ngroups++; - /* Skip pure pinconf node */ - if (of_property_read_u32(child, "reg", &val)) - continue; - if (strcmp(fn, child->name)) { - fn = child->name; - soc->nfunctions++; - } - } - - soc->functions = devm_kzalloc(&pdev->dev, soc->nfunctions * - sizeof(*soc->functions), GFP_KERNEL); - if (!soc->functions) - return -ENOMEM; - - soc->groups = devm_kzalloc(&pdev->dev, soc->ngroups * - sizeof(*soc->groups), GFP_KERNEL); - if (!soc->groups) - return -ENOMEM; - - /* Count groups for each function */ - fn = fnull; - f = &soc->functions[idxf]; - for_each_child_of_node(np, child) { - if (of_device_is_compatible(child, gpio_compat)) - continue; - if (of_property_read_u32(child, "reg", &val)) - continue; - if (strcmp(fn, child->name)) { - f = &soc->functions[idxf++]; - f->name = fn = child->name; - } - f->ngroups++; - }; - - /* Get groups for each function */ - idxf = 0; - fn = fnull; - for_each_child_of_node(np, child) { - if (of_device_is_compatible(child, gpio_compat)) - continue; - if (of_property_read_u32(child, "reg", &val)) { - ret = mxs_pinctrl_parse_group(pdev, child, - idxg++, NULL); - if (ret) - return ret; - continue; - } - - if (strcmp(fn, child->name)) { - f = &soc->functions[idxf++]; - f->groups = devm_kzalloc(&pdev->dev, f->ngroups * - sizeof(*f->groups), - GFP_KERNEL); - if (!f->groups) - return -ENOMEM; - fn = child->name; - i = 0; - } - ret = mxs_pinctrl_parse_group(pdev, child, idxg++, - &f->groups[i++]); - if (ret) - return ret; - } - - return 0; -} - -int __devinit mxs_pinctrl_probe(struct platform_device *pdev, - struct mxs_pinctrl_soc_data *soc) -{ - struct device_node *np = pdev->dev.of_node; - struct mxs_pinctrl_data *d; - int ret; - - d = devm_kzalloc(&pdev->dev, sizeof(*d), GFP_KERNEL); - if (!d) - return -ENOMEM; - - d->dev = &pdev->dev; - d->soc = soc; - - d->base = of_iomap(np, 0); - if (!d->base) - return -EADDRNOTAVAIL; - - mxs_pinctrl_desc.pins = d->soc->pins; - mxs_pinctrl_desc.npins = d->soc->npins; - mxs_pinctrl_desc.name = dev_name(&pdev->dev); - - platform_set_drvdata(pdev, d); - - ret = mxs_pinctrl_probe_dt(pdev, d); - if (ret) { - dev_err(&pdev->dev, "dt probe failed: %d\n", ret); - goto err; - } - - d->pctl = pinctrl_register(&mxs_pinctrl_desc, &pdev->dev, d); - if (!d->pctl) { - dev_err(&pdev->dev, "Couldn't register MXS pinctrl driver\n"); - ret = -EINVAL; - goto err; - } - - return 0; - -err: - iounmap(d->base); - return ret; -} -EXPORT_SYMBOL_GPL(mxs_pinctrl_probe); - -int __devexit mxs_pinctrl_remove(struct platform_device *pdev) -{ - struct mxs_pinctrl_data *d = platform_get_drvdata(pdev); - - pinctrl_unregister(d->pctl); - iounmap(d->base); - - return 0; -} -EXPORT_SYMBOL_GPL(mxs_pinctrl_remove); diff --git a/trunk/drivers/pinctrl/pinctrl-mxs.h b/trunk/drivers/pinctrl/pinctrl-mxs.h deleted file mode 100644 index fdd88d0bae22..000000000000 --- a/trunk/drivers/pinctrl/pinctrl-mxs.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2012 Freescale Semiconductor, Inc. - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#ifndef __PINCTRL_MXS_H -#define __PINCTRL_MXS_H - -#include -#include - -#define SET 0x4 -#define CLR 0x8 -#define TOG 0xc - -#define MXS_PINCTRL_PIN(pin) PINCTRL_PIN(pin, #pin) -#define PINID(bank, pin) ((bank) * 32 + (pin)) - -/* - * pinmux-id bit field definitions - * - * bank: 15..12 (4) - * pin: 11..4 (8) - * muxsel: 3..0 (4) - */ -#define MUXID_TO_PINID(m) PINID((m) >> 12 & 0xf, (m) >> 4 & 0xff) -#define MUXID_TO_MUXSEL(m) ((m) & 0xf) - -#define PINID_TO_BANK(p) ((p) >> 5) -#define PINID_TO_PIN(p) ((p) % 32) - -/* - * pin config bit field definitions - * - * pull-up: 6..5 (2) - * voltage: 4..3 (2) - * mA: 2..0 (3) - * - * MSB of each field is presence bit for the config. - */ -#define PULL_PRESENT (1 << 6) -#define PULL_SHIFT 5 -#define VOL_PRESENT (1 << 4) -#define VOL_SHIFT 3 -#define MA_PRESENT (1 << 2) -#define MA_SHIFT 0 -#define CONFIG_TO_PULL(c) ((c) >> PULL_SHIFT & 0x1) -#define CONFIG_TO_VOL(c) ((c) >> VOL_SHIFT & 0x1) -#define CONFIG_TO_MA(c) ((c) >> MA_SHIFT & 0x3) - -struct mxs_function { - const char *name; - const char **groups; - unsigned ngroups; -}; - -struct mxs_group { - const char *name; - unsigned int *pins; - unsigned npins; - u8 *muxsel; - u8 config; -}; - -struct mxs_regs { - u16 muxsel; - u16 drive; - u16 pull; -}; - -struct mxs_pinctrl_soc_data { - const struct mxs_regs *regs; - const struct pinctrl_pin_desc *pins; - unsigned npins; - struct mxs_function *functions; - unsigned nfunctions; - struct mxs_group *groups; - unsigned ngroups; -}; - -int mxs_pinctrl_probe(struct platform_device *pdev, - struct mxs_pinctrl_soc_data *soc); -int mxs_pinctrl_remove(struct platform_device *pdev); - -#endif /* __PINCTRL_MXS_H */ diff --git a/trunk/drivers/pinctrl/pinctrl-pxa3xx.c b/trunk/drivers/pinctrl/pinctrl-pxa3xx.c index f14cd6ba4c0b..079dce0e93e9 100644 --- a/trunk/drivers/pinctrl/pinctrl-pxa3xx.c +++ b/trunk/drivers/pinctrl/pinctrl-pxa3xx.c @@ -25,18 +25,20 @@ static struct pinctrl_gpio_range pxa3xx_pinctrl_gpio_range = { .pin_base = 0, }; -static int pxa3xx_get_groups_count(struct pinctrl_dev *pctrldev) +static int pxa3xx_list_groups(struct pinctrl_dev *pctrldev, unsigned selector) { struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); - - return info->num_grps; + if (selector >= info->num_grps) + return -EINVAL; + return 0; } static const char *pxa3xx_get_group_name(struct pinctrl_dev *pctrldev, unsigned selector) { struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); - + if (selector >= info->num_grps) + return NULL; return info->grps[selector].name; } @@ -46,23 +48,25 @@ static int pxa3xx_get_group_pins(struct pinctrl_dev *pctrldev, unsigned *num_pins) { struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); - + if (selector >= info->num_grps) + return -EINVAL; *pins = info->grps[selector].pins; *num_pins = info->grps[selector].npins; return 0; } static struct pinctrl_ops pxa3xx_pctrl_ops = { - .get_groups_count = pxa3xx_get_groups_count, + .list_groups = pxa3xx_list_groups, .get_group_name = pxa3xx_get_group_name, .get_group_pins = pxa3xx_get_group_pins, }; -static int pxa3xx_pmx_get_funcs_count(struct pinctrl_dev *pctrldev) +static int pxa3xx_pmx_list_func(struct pinctrl_dev *pctrldev, unsigned func) { struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); - - return info->num_funcs; + if (func >= info->num_funcs) + return -EINVAL; + return 0; } static const char *pxa3xx_pmx_get_func_name(struct pinctrl_dev *pctrldev, @@ -138,6 +142,11 @@ static int pxa3xx_pmx_enable(struct pinctrl_dev *pctrldev, unsigned func, return 0; } +static void pxa3xx_pmx_disable(struct pinctrl_dev *pctrldev, unsigned func, + unsigned group) +{ +} + static int pxa3xx_pmx_request_gpio(struct pinctrl_dev *pctrldev, struct pinctrl_gpio_range *range, unsigned pin) @@ -161,10 +170,11 @@ static int pxa3xx_pmx_request_gpio(struct pinctrl_dev *pctrldev, } static struct pinmux_ops pxa3xx_pmx_ops = { - .get_functions_count = pxa3xx_pmx_get_funcs_count, + .list_functions = pxa3xx_pmx_list_func, .get_function_name = pxa3xx_pmx_get_func_name, .get_function_groups = pxa3xx_pmx_get_groups, .enable = pxa3xx_pmx_enable, + .disable = pxa3xx_pmx_disable, .gpio_request_enable = pxa3xx_pmx_request_gpio, }; diff --git a/trunk/drivers/pinctrl/pinctrl-sirf.c b/trunk/drivers/pinctrl/pinctrl-sirf.c index ba15b1a29e52..6b3534cc051a 100644 --- a/trunk/drivers/pinctrl/pinctrl-sirf.c +++ b/trunk/drivers/pinctrl/pinctrl-sirf.c @@ -853,14 +853,18 @@ static const struct sirfsoc_pin_group sirfsoc_pin_groups[] = { SIRFSOC_PIN_GROUP("gpsgrp", gps_pins), }; -static int sirfsoc_get_groups_count(struct pinctrl_dev *pctldev) +static int sirfsoc_list_groups(struct pinctrl_dev *pctldev, unsigned selector) { - return ARRAY_SIZE(sirfsoc_pin_groups); + if (selector >= ARRAY_SIZE(sirfsoc_pin_groups)) + return -EINVAL; + return 0; } static const char *sirfsoc_get_group_name(struct pinctrl_dev *pctldev, unsigned selector) { + if (selector >= ARRAY_SIZE(sirfsoc_pin_groups)) + return NULL; return sirfsoc_pin_groups[selector].name; } @@ -868,6 +872,8 @@ static int sirfsoc_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector const unsigned **pins, unsigned *num_pins) { + if (selector >= ARRAY_SIZE(sirfsoc_pin_groups)) + return -EINVAL; *pins = sirfsoc_pin_groups[selector].pins; *num_pins = sirfsoc_pin_groups[selector].num_pins; return 0; @@ -880,7 +886,7 @@ static void sirfsoc_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s } static struct pinctrl_ops sirfsoc_pctrl_ops = { - .get_groups_count = sirfsoc_get_groups_count, + .list_groups = sirfsoc_list_groups, .get_group_name = sirfsoc_get_group_name, .get_group_pins = sirfsoc_get_group_pins, .pin_dbg_show = sirfsoc_pin_dbg_show, @@ -1027,9 +1033,11 @@ static void sirfsoc_pinmux_disable(struct pinctrl_dev *pmxdev, unsigned selector sirfsoc_pinmux_endisable(spmx, selector, false); } -static int sirfsoc_pinmux_get_funcs_count(struct pinctrl_dev *pmxdev) +static int sirfsoc_pinmux_list_funcs(struct pinctrl_dev *pmxdev, unsigned selector) { - return ARRAY_SIZE(sirfsoc_pmx_functions); + if (selector >= ARRAY_SIZE(sirfsoc_pmx_functions)) + return -EINVAL; + return 0; } static const char *sirfsoc_pinmux_get_func_name(struct pinctrl_dev *pctldev, @@ -1066,9 +1074,9 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev, } static struct pinmux_ops sirfsoc_pinmux_ops = { + .list_functions = sirfsoc_pinmux_list_funcs, .enable = sirfsoc_pinmux_enable, .disable = sirfsoc_pinmux_disable, - .get_functions_count = sirfsoc_pinmux_get_funcs_count, .get_function_name = sirfsoc_pinmux_get_func_name, .get_function_groups = sirfsoc_pinmux_get_groups, .gpio_request_enable = sirfsoc_pinmux_request_gpio, diff --git a/trunk/drivers/pinctrl/pinctrl-tegra.c b/trunk/drivers/pinctrl/pinctrl-tegra.c index 2c98fba01ca5..9b329688120c 100644 --- a/trunk/drivers/pinctrl/pinctrl-tegra.c +++ b/trunk/drivers/pinctrl/pinctrl-tegra.c @@ -23,11 +23,9 @@ #include #include #include -#include #include #include #include -#include #include @@ -55,11 +53,15 @@ static inline void pmx_writel(struct tegra_pmx *pmx, u32 val, u32 bank, u32 reg) writel(val, pmx->regs[bank] + reg); } -static int tegra_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) +static int tegra_pinctrl_list_groups(struct pinctrl_dev *pctldev, + unsigned group) { struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - return pmx->soc->ngroups; + if (group >= pmx->soc->ngroups) + return -EINVAL; + + return 0; } static const char *tegra_pinctrl_get_group_name(struct pinctrl_dev *pctldev, @@ -67,6 +69,9 @@ static const char *tegra_pinctrl_get_group_name(struct pinctrl_dev *pctldev, { struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); + if (group >= pmx->soc->ngroups) + return NULL; + return pmx->soc->groups[group].name; } @@ -77,6 +82,9 @@ static int tegra_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, { struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); + if (group >= pmx->soc->ngroups) + return -EINVAL; + *pins = pmx->soc->groups[group].pins; *num_pins = pmx->soc->groups[group].npins; @@ -90,221 +98,22 @@ static void tegra_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev, seq_printf(s, " " DRIVER_NAME); } -static int reserve_map(struct pinctrl_map **map, unsigned *reserved_maps, - unsigned *num_maps, unsigned reserve) -{ - unsigned old_num = *reserved_maps; - unsigned new_num = *num_maps + reserve; - struct pinctrl_map *new_map; - - if (old_num >= new_num) - return 0; - - new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL); - if (!new_map) - return -ENOMEM; - - memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map)); - - *map = new_map; - *reserved_maps = new_num; - - return 0; -} - -static int add_map_mux(struct pinctrl_map **map, unsigned *reserved_maps, - unsigned *num_maps, const char *group, - const char *function) -{ - if (*num_maps == *reserved_maps) - return -ENOSPC; - - (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP; - (*map)[*num_maps].data.mux.group = group; - (*map)[*num_maps].data.mux.function = function; - (*num_maps)++; - - return 0; -} - -static int add_map_configs(struct pinctrl_map **map, unsigned *reserved_maps, - unsigned *num_maps, const char *group, - unsigned long *configs, unsigned num_configs) -{ - unsigned long *dup_configs; - - if (*num_maps == *reserved_maps) - return -ENOSPC; - - dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs), - GFP_KERNEL); - if (!dup_configs) - return -ENOMEM; - - (*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_GROUP; - (*map)[*num_maps].data.configs.group_or_pin = group; - (*map)[*num_maps].data.configs.configs = dup_configs; - (*map)[*num_maps].data.configs.num_configs = num_configs; - (*num_maps)++; - - return 0; -} - -static int add_config(unsigned long **configs, unsigned *num_configs, - unsigned long config) -{ - unsigned old_num = *num_configs; - unsigned new_num = old_num + 1; - unsigned long *new_configs; - - new_configs = krealloc(*configs, sizeof(*new_configs) * new_num, - GFP_KERNEL); - if (!new_configs) - return -ENOMEM; - - new_configs[old_num] = config; - - *configs = new_configs; - *num_configs = new_num; - - return 0; -} - -void tegra_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, - struct pinctrl_map *map, unsigned num_maps) -{ - int i; - - for (i = 0; i < num_maps; i++) - if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP) - kfree(map[i].data.configs.configs); - - kfree(map); -} - -static const struct cfg_param { - const char *property; - enum tegra_pinconf_param param; -} cfg_params[] = { - {"nvidia,pull", TEGRA_PINCONF_PARAM_PULL}, - {"nvidia,tristate", TEGRA_PINCONF_PARAM_TRISTATE}, - {"nvidia,enable-input", TEGRA_PINCONF_PARAM_ENABLE_INPUT}, - {"nvidia,open-drain", TEGRA_PINCONF_PARAM_OPEN_DRAIN}, - {"nvidia,lock", TEGRA_PINCONF_PARAM_LOCK}, - {"nvidia,io-reset", TEGRA_PINCONF_PARAM_IORESET}, - {"nvidia,high-speed-mode", TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE}, - {"nvidia,schmitt", TEGRA_PINCONF_PARAM_SCHMITT}, - {"nvidia,low-power-mode", TEGRA_PINCONF_PARAM_LOW_POWER_MODE}, - {"nvidia,pull-down-strength", TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH}, - {"nvidia,pull-up-strength", TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH}, - {"nvidia,slew-rate-falling", TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING}, - {"nvidia,slew-rate-rising", TEGRA_PINCONF_PARAM_SLEW_RATE_RISING}, -}; - -int tegra_pinctrl_dt_subnode_to_map(struct device_node *np, - struct pinctrl_map **map, - unsigned *reserved_maps, - unsigned *num_maps) -{ - int ret, i; - const char *function; - u32 val; - unsigned long config; - unsigned long *configs = NULL; - unsigned num_configs = 0; - unsigned reserve; - struct property *prop; - const char *group; - - ret = of_property_read_string(np, "nvidia,function", &function); - if (ret < 0) - function = NULL; - - for (i = 0; i < ARRAY_SIZE(cfg_params); i++) { - ret = of_property_read_u32(np, cfg_params[i].property, &val); - if (!ret) { - config = TEGRA_PINCONF_PACK(cfg_params[i].param, val); - ret = add_config(&configs, &num_configs, config); - if (ret < 0) - goto exit; - } - } - - reserve = 0; - if (function != NULL) - reserve++; - if (num_configs) - reserve++; - ret = of_property_count_strings(np, "nvidia,pins"); - if (ret < 0) - goto exit; - reserve *= ret; - - ret = reserve_map(map, reserved_maps, num_maps, reserve); - if (ret < 0) - goto exit; - - of_property_for_each_string(np, "nvidia,pins", prop, group) { - if (function) { - ret = add_map_mux(map, reserved_maps, num_maps, - group, function); - if (ret < 0) - goto exit; - } - - if (num_configs) { - ret = add_map_configs(map, reserved_maps, num_maps, - group, configs, num_configs); - if (ret < 0) - goto exit; - } - } - - ret = 0; - -exit: - kfree(configs); - return ret; -} - -int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *np_config, - struct pinctrl_map **map, unsigned *num_maps) -{ - unsigned reserved_maps; - struct device_node *np; - int ret; - - reserved_maps = 0; - *map = NULL; - *num_maps = 0; - - for_each_child_of_node(np_config, np) { - ret = tegra_pinctrl_dt_subnode_to_map(np, map, &reserved_maps, - num_maps); - if (ret < 0) { - tegra_pinctrl_dt_free_map(pctldev, *map, *num_maps); - return ret; - } - } - - return 0; -} - static struct pinctrl_ops tegra_pinctrl_ops = { - .get_groups_count = tegra_pinctrl_get_groups_count, + .list_groups = tegra_pinctrl_list_groups, .get_group_name = tegra_pinctrl_get_group_name, .get_group_pins = tegra_pinctrl_get_group_pins, .pin_dbg_show = tegra_pinctrl_pin_dbg_show, - .dt_node_to_map = tegra_pinctrl_dt_node_to_map, - .dt_free_map = tegra_pinctrl_dt_free_map, }; -static int tegra_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev) +static int tegra_pinctrl_list_funcs(struct pinctrl_dev *pctldev, + unsigned function) { struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - return pmx->soc->nfunctions; + if (function >= pmx->soc->nfunctions) + return -EINVAL; + + return 0; } static const char *tegra_pinctrl_get_func_name(struct pinctrl_dev *pctldev, @@ -312,6 +121,9 @@ static const char *tegra_pinctrl_get_func_name(struct pinctrl_dev *pctldev, { struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); + if (function >= pmx->soc->nfunctions) + return NULL; + return pmx->soc->functions[function].name; } @@ -322,6 +134,9 @@ static int tegra_pinctrl_get_func_groups(struct pinctrl_dev *pctldev, { struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); + if (function >= pmx->soc->nfunctions) + return -EINVAL; + *groups = pmx->soc->functions[function].groups; *num_groups = pmx->soc->functions[function].ngroups; @@ -336,6 +151,8 @@ static int tegra_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function, int i; u32 val; + if (group >= pmx->soc->ngroups) + return -EINVAL; g = &pmx->soc->groups[group]; if (g->mux_reg < 0) @@ -363,6 +180,8 @@ static void tegra_pinctrl_disable(struct pinctrl_dev *pctldev, const struct tegra_pingroup *g; u32 val; + if (group >= pmx->soc->ngroups) + return; g = &pmx->soc->groups[group]; if (g->mux_reg < 0) @@ -375,7 +194,7 @@ static void tegra_pinctrl_disable(struct pinctrl_dev *pctldev, } static struct pinmux_ops tegra_pinmux_ops = { - .get_functions_count = tegra_pinctrl_get_funcs_count, + .list_functions = tegra_pinctrl_list_funcs, .get_function_name = tegra_pinctrl_get_func_name, .get_function_groups = tegra_pinctrl_get_func_groups, .enable = tegra_pinctrl_enable, @@ -505,6 +324,8 @@ static int tegra_pinconf_group_get(struct pinctrl_dev *pctldev, s16 reg; u32 val, mask; + if (group >= pmx->soc->ngroups) + return -EINVAL; g = &pmx->soc->groups[group]; ret = tegra_pinconf_reg(pmx, g, param, &bank, ®, &bit, &width); @@ -532,6 +353,8 @@ static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev, s16 reg; u32 val, mask; + if (group >= pmx->soc->ngroups) + return -EINVAL; g = &pmx->soc->groups[group]; ret = tegra_pinconf_reg(pmx, g, param, &bank, ®, &bit, &width); diff --git a/trunk/drivers/pinctrl/pinctrl-u300.c b/trunk/drivers/pinctrl/pinctrl-u300.c index 05d029911be6..26eb8ccd72d5 100644 --- a/trunk/drivers/pinctrl/pinctrl-u300.c +++ b/trunk/drivers/pinctrl/pinctrl-u300.c @@ -836,14 +836,18 @@ static const struct u300_pin_group u300_pin_groups[] = { }, }; -static int u300_get_groups_count(struct pinctrl_dev *pctldev) +static int u300_list_groups(struct pinctrl_dev *pctldev, unsigned selector) { - return ARRAY_SIZE(u300_pin_groups); + if (selector >= ARRAY_SIZE(u300_pin_groups)) + return -EINVAL; + return 0; } static const char *u300_get_group_name(struct pinctrl_dev *pctldev, unsigned selector) { + if (selector >= ARRAY_SIZE(u300_pin_groups)) + return NULL; return u300_pin_groups[selector].name; } @@ -851,6 +855,8 @@ static int u300_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, const unsigned **pins, unsigned *num_pins) { + if (selector >= ARRAY_SIZE(u300_pin_groups)) + return -EINVAL; *pins = u300_pin_groups[selector].pins; *num_pins = u300_pin_groups[selector].num_pins; return 0; @@ -863,7 +869,7 @@ static void u300_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, } static struct pinctrl_ops u300_pctrl_ops = { - .get_groups_count = u300_get_groups_count, + .list_groups = u300_list_groups, .get_group_name = u300_get_group_name, .get_group_pins = u300_get_group_pins, .pin_dbg_show = u300_pin_dbg_show, @@ -985,9 +991,11 @@ static void u300_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector, u300_pmx_endisable(upmx, selector, false); } -static int u300_pmx_get_funcs_count(struct pinctrl_dev *pctldev) +static int u300_pmx_list_funcs(struct pinctrl_dev *pctldev, unsigned selector) { - return ARRAY_SIZE(u300_pmx_functions); + if (selector >= ARRAY_SIZE(u300_pmx_functions)) + return -EINVAL; + return 0; } static const char *u300_pmx_get_func_name(struct pinctrl_dev *pctldev, @@ -1006,7 +1014,7 @@ static int u300_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector, } static struct pinmux_ops u300_pmx_ops = { - .get_functions_count = u300_pmx_get_funcs_count, + .list_functions = u300_pmx_list_funcs, .get_function_name = u300_pmx_get_func_name, .get_function_groups = u300_pmx_get_groups, .enable = u300_pmx_enable, diff --git a/trunk/drivers/pinctrl/pinmux.c b/trunk/drivers/pinctrl/pinmux.c index 3d5ac73bd5a7..4e62783a573a 100644 --- a/trunk/drivers/pinctrl/pinmux.c +++ b/trunk/drivers/pinctrl/pinmux.c @@ -33,25 +33,22 @@ int pinmux_check_ops(struct pinctrl_dev *pctldev) { const struct pinmux_ops *ops = pctldev->desc->pmxops; - unsigned nfuncs; unsigned selector = 0; /* Check that we implement required operations */ - if (!ops || - !ops->get_functions_count || + if (!ops->list_functions || !ops->get_function_name || !ops->get_function_groups || - !ops->enable) { - dev_err(pctldev->dev, "pinmux ops lacks necessary functions\n"); + !ops->enable || + !ops->disable) return -EINVAL; - } + /* Check that all functions registered have names */ - nfuncs = ops->get_functions_count(pctldev); - while (selector < nfuncs) { + while (ops->list_functions(pctldev, selector) >= 0) { const char *fname = ops->get_function_name(pctldev, selector); if (!fname) { - dev_err(pctldev->dev, "pinmux ops has no name for function%u\n", + pr_err("pinmux ops has no name for function%u\n", selector); return -EINVAL; } @@ -88,23 +85,20 @@ static int pin_request(struct pinctrl_dev *pctldev, const struct pinmux_ops *ops = pctldev->desc->pmxops; int status = -EINVAL; + dev_dbg(pctldev->dev, "request pin %d for %s\n", pin, owner); + desc = pin_desc_get(pctldev, pin); if (desc == NULL) { dev_err(pctldev->dev, - "pin %d is not registered so it cannot be requested\n", - pin); + "pin is not registered so it cannot be requested\n"); goto out; } - dev_dbg(pctldev->dev, "request pin %d (%s) for %s\n", - pin, desc->name, owner); - if (gpio_range) { /* There's no need to support multiple GPIO requests */ if (desc->gpio_owner) { dev_err(pctldev->dev, - "pin %s already requested by %s; cannot claim for %s\n", - desc->name, desc->gpio_owner, owner); + "pin already requested\n"); goto out; } @@ -112,8 +106,7 @@ static int pin_request(struct pinctrl_dev *pctldev, } else { if (desc->mux_usecount && strcmp(desc->mux_owner, owner)) { dev_err(pctldev->dev, - "pin %s already requested by %s; cannot claim for %s\n", - desc->name, desc->mux_owner, owner); + "pin already requested\n"); goto out; } @@ -146,7 +139,8 @@ static int pin_request(struct pinctrl_dev *pctldev, status = 0; if (status) { - dev_err(pctldev->dev, "request() failed for pin %d\n", pin); + dev_err(pctldev->dev, "->request on device %s failed for pin %d\n", + pctldev->desc->name, pin); module_put(pctldev->owner); } @@ -163,7 +157,7 @@ static int pin_request(struct pinctrl_dev *pctldev, out: if (status) dev_err(pctldev->dev, "pin-%d (%s) status %d\n", - pin, owner, status); + pin, owner, status); return status; } @@ -293,11 +287,10 @@ static int pinmux_func_name_to_selector(struct pinctrl_dev *pctldev, const char *function) { const struct pinmux_ops *ops = pctldev->desc->pmxops; - unsigned nfuncs = ops->get_functions_count(pctldev); unsigned selector = 0; /* See if this pctldev has this function */ - while (selector < nfuncs) { + while (ops->list_functions(pctldev, selector) >= 0) { const char *fname = ops->get_function_name(pctldev, selector); @@ -326,32 +319,18 @@ int pinmux_map_to_setting(struct pinctrl_map const *map, const unsigned *pins; unsigned num_pins; - if (!pmxops) { - dev_err(pctldev->dev, "does not support mux function\n"); - return -EINVAL; - } - - ret = pinmux_func_name_to_selector(pctldev, map->data.mux.function); - if (ret < 0) { - dev_err(pctldev->dev, "invalid function %s in map table\n", - map->data.mux.function); - return ret; - } - setting->data.mux.func = ret; + setting->data.mux.func = + pinmux_func_name_to_selector(pctldev, map->data.mux.function); + if (setting->data.mux.func < 0) + return setting->data.mux.func; ret = pmxops->get_function_groups(pctldev, setting->data.mux.func, &groups, &num_groups); - if (ret < 0) { - dev_err(pctldev->dev, "can't query groups for function %s\n", - map->data.mux.function); + if (ret < 0) return ret; - } - if (!num_groups) { - dev_err(pctldev->dev, - "function %s can't be selected on any group\n", - map->data.mux.function); + if (!num_groups) return -EINVAL; - } + if (map->data.mux.group) { bool found = false; group = map->data.mux.group; @@ -361,23 +340,15 @@ int pinmux_map_to_setting(struct pinctrl_map const *map, break; } } - if (!found) { - dev_err(pctldev->dev, - "invalid group \"%s\" for function \"%s\"\n", - group, map->data.mux.function); + if (!found) return -EINVAL; - } } else { group = groups[0]; } - ret = pinctrl_get_group_selector(pctldev, group); - if (ret < 0) { - dev_err(pctldev->dev, "invalid group %s in map table\n", - map->data.mux.group); - return ret; - } - setting->data.mux.group = ret; + setting->data.mux.group = pinctrl_get_group_selector(pctldev, group); + if (setting->data.mux.group < 0) + return setting->data.mux.group; ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, &pins, &num_pins); @@ -393,7 +364,7 @@ int pinmux_map_to_setting(struct pinctrl_map const *map, ret = pin_request(pctldev, pins[i], map->dev_name, NULL); if (ret) { dev_err(pctldev->dev, - "could not request pin %d on device %s\n", + "could not get request pin %d on device %s\n", pins[i], pinctrl_dev_get_name(pctldev)); /* On error release all taken pins */ i--; /* this pin just failed */ @@ -496,8 +467,7 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting) desc->mux_setting = NULL; } - if (ops->disable) - ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group); + ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group); } #ifdef CONFIG_DEBUG_FS @@ -507,15 +477,11 @@ static int pinmux_functions_show(struct seq_file *s, void *what) { struct pinctrl_dev *pctldev = s->private; const struct pinmux_ops *pmxops = pctldev->desc->pmxops; - unsigned nfuncs; unsigned func_selector = 0; - if (!pmxops) - return 0; - mutex_lock(&pinctrl_mutex); - nfuncs = pmxops->get_functions_count(pctldev); - while (func_selector < nfuncs) { + + while (pmxops->list_functions(pctldev, func_selector) >= 0) { const char *func = pmxops->get_function_name(pctldev, func_selector); const char * const *groups; @@ -549,9 +515,6 @@ static int pinmux_pins_show(struct seq_file *s, void *what) const struct pinmux_ops *pmxops = pctldev->desc->pmxops; unsigned i, pin; - if (!pmxops) - return 0; - seq_puts(s, "Pinmux settings per pin\n"); seq_puts(s, "Format: pin (name): mux_owner gpio_owner hog?\n"); diff --git a/trunk/drivers/pinctrl/pinmux.h b/trunk/drivers/pinctrl/pinmux.h index d1a98b1c9fce..6fc47003e95d 100644 --- a/trunk/drivers/pinctrl/pinmux.h +++ b/trunk/drivers/pinctrl/pinmux.h @@ -31,6 +31,12 @@ void pinmux_free_setting(struct pinctrl_setting const *setting); int pinmux_enable_setting(struct pinctrl_setting const *setting); void pinmux_disable_setting(struct pinctrl_setting const *setting); +void pinmux_show_map(struct seq_file *s, struct pinctrl_map const *map); +void pinmux_show_setting(struct seq_file *s, + struct pinctrl_setting const *setting); +void pinmux_init_device_debugfs(struct dentry *devroot, + struct pinctrl_dev *pctldev); + #else static inline int pinmux_check_ops(struct pinctrl_dev *pctldev) @@ -83,18 +89,6 @@ static inline void pinmux_disable_setting( { } -#endif - -#if defined(CONFIG_PINMUX) && defined(CONFIG_DEBUG_FS) - -void pinmux_show_map(struct seq_file *s, struct pinctrl_map const *map); -void pinmux_show_setting(struct seq_file *s, - struct pinctrl_setting const *setting); -void pinmux_init_device_debugfs(struct dentry *devroot, - struct pinctrl_dev *pctldev); - -#else - static inline void pinmux_show_map(struct seq_file *s, struct pinctrl_map const *map) { diff --git a/trunk/drivers/platform/x86/intel_mid_powerbtn.c b/trunk/drivers/platform/x86/intel_mid_powerbtn.c index bcbad8452a6f..0a3594c7e912 100644 --- a/trunk/drivers/platform/x86/intel_mid_powerbtn.c +++ b/trunk/drivers/platform/x86/intel_mid_powerbtn.c @@ -78,7 +78,7 @@ static int __devinit mfld_pb_probe(struct platform_device *pdev) input_set_capability(input, EV_KEY, KEY_POWER); - error = request_threaded_irq(irq, NULL, mfld_pb_isr, IRQF_NO_SUSPEND, + error = request_threaded_irq(irq, NULL, mfld_pb_isr, 0, DRIVER_NAME, input); if (error) { dev_err(&pdev->dev, "Unable to request irq %d for mfld power" diff --git a/trunk/drivers/ptp/ptp_pch.c b/trunk/drivers/ptp/ptp_pch.c index 3a9c17eced10..08c331130d88 100644 --- a/trunk/drivers/ptp/ptp_pch.c +++ b/trunk/drivers/ptp/ptp_pch.c @@ -30,7 +30,6 @@ #include #include #include -#include #define STATION_ADDR_LEN 20 #define PCI_DEVICE_ID_PCH_1588 0x8819 diff --git a/trunk/drivers/regulator/88pm8607.c b/trunk/drivers/regulator/88pm8607.c index c3482b954cb7..28b81ae4cf7f 100644 --- a/trunk/drivers/regulator/88pm8607.c +++ b/trunk/drivers/regulator/88pm8607.c @@ -27,8 +27,13 @@ struct pm8607_regulator_info { unsigned int *vol_table; unsigned int *vol_suspend; + int vol_reg; + int vol_shift; + int vol_nbits; int update_reg; int update_bit; + int enable_reg; + int enable_bit; int slope_double; }; @@ -211,7 +216,7 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); int ret = -EINVAL; - if (info->vol_table && (index < rdev->desc->n_voltages)) { + if (info->vol_table && (index < (1 << info->vol_nbits))) { ret = info->vol_table[index]; if (info->slope_double) ret <<= 1; @@ -219,16 +224,51 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) return ret; } -static int pm8607_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) +static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) { struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); - uint8_t val; + int i, ret = -ENOENT; + + if (info->slope_double) { + min_uV = min_uV >> 1; + max_uV = max_uV >> 1; + } + if (info->vol_table) { + for (i = 0; i < (1 << info->vol_nbits); i++) { + if (!info->vol_table[i]) + break; + if ((min_uV <= info->vol_table[i]) + && (max_uV >= info->vol_table[i])) { + ret = i; + break; + } + } + } + if (ret < 0) + pr_err("invalid voltage range (%d %d) uV\n", min_uV, max_uV); + return ret; +} + +static int pm8607_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned *selector) +{ + struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); + uint8_t val, mask; int ret; - val = (uint8_t)(selector << (ffs(rdev->desc->vsel_mask) - 1)); + if (min_uV > max_uV) { + pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV); + return -EINVAL; + } - ret = pm860x_set_bits(info->i2c, rdev->desc->vsel_reg, - rdev->desc->vsel_mask, val); + ret = choose_voltage(rdev, min_uV, max_uV); + if (ret < 0) + return -EINVAL; + *selector = ret; + val = (uint8_t)(ret << info->vol_shift); + mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; + + ret = pm860x_set_bits(info->i2c, info->vol_reg, mask, val); if (ret) return ret; switch (info->desc.id) { @@ -242,16 +282,60 @@ static int pm8607_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) return ret; } +static int pm8607_get_voltage(struct regulator_dev *rdev) +{ + struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); + uint8_t val, mask; + int ret; + + ret = pm860x_reg_read(info->i2c, info->vol_reg); + if (ret < 0) + return ret; + + mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; + val = ((unsigned char)ret & mask) >> info->vol_shift; + + return pm8607_list_voltage(rdev, val); +} + +static int pm8607_enable(struct regulator_dev *rdev) +{ + struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); + + return pm860x_set_bits(info->i2c, info->enable_reg, + 1 << info->enable_bit, + 1 << info->enable_bit); +} + +static int pm8607_disable(struct regulator_dev *rdev) +{ + struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); + + return pm860x_set_bits(info->i2c, info->enable_reg, + 1 << info->enable_bit, 0); +} + +static int pm8607_is_enabled(struct regulator_dev *rdev) +{ + struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); + int ret; + + ret = pm860x_reg_read(info->i2c, info->enable_reg); + if (ret < 0) + return ret; + + return !!((unsigned char)ret & (1 << info->enable_bit)); +} + static struct regulator_ops pm8607_regulator_ops = { - .list_voltage = pm8607_list_voltage, - .set_voltage_sel = pm8607_set_voltage_sel, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, + .set_voltage = pm8607_set_voltage, + .get_voltage = pm8607_get_voltage, + .enable = pm8607_enable, + .disable = pm8607_disable, + .is_enabled = pm8607_is_enabled, }; -#define PM8607_DVC(vreg, ureg, ubit, ereg, ebit) \ +#define PM8607_DVC(vreg, nbits, ureg, ubit, ereg, ebit) \ { \ .desc = { \ .name = #vreg, \ @@ -259,20 +343,20 @@ static struct regulator_ops pm8607_regulator_ops = { .type = REGULATOR_VOLTAGE, \ .id = PM8607_ID_##vreg, \ .owner = THIS_MODULE, \ - .n_voltages = ARRAY_SIZE(vreg##_table), \ - .vsel_reg = PM8607_##vreg, \ - .vsel_mask = ARRAY_SIZE(vreg##_table) - 1, \ - .enable_reg = PM8607_##ereg, \ - .enable_mask = 1 << (ebit), \ }, \ + .vol_reg = PM8607_##vreg, \ + .vol_shift = (0), \ + .vol_nbits = (nbits), \ .update_reg = PM8607_##ureg, \ .update_bit = (ubit), \ + .enable_reg = PM8607_##ereg, \ + .enable_bit = (ebit), \ .slope_double = (0), \ .vol_table = (unsigned int *)&vreg##_table, \ .vol_suspend = (unsigned int *)&vreg##_suspend_table, \ } -#define PM8607_LDO(_id, vreg, shift, ereg, ebit) \ +#define PM8607_LDO(_id, vreg, shift, nbits, ereg, ebit) \ { \ .desc = { \ .name = "LDO" #_id, \ @@ -280,35 +364,35 @@ static struct regulator_ops pm8607_regulator_ops = { .type = REGULATOR_VOLTAGE, \ .id = PM8607_ID_LDO##_id, \ .owner = THIS_MODULE, \ - .n_voltages = ARRAY_SIZE(LDO##_id##_table), \ - .vsel_reg = PM8607_##vreg, \ - .vsel_mask = (ARRAY_SIZE(LDO##_id##_table) - 1) << (shift), \ - .enable_reg = PM8607_##ereg, \ - .enable_mask = 1 << (ebit), \ }, \ + .vol_reg = PM8607_##vreg, \ + .vol_shift = (shift), \ + .vol_nbits = (nbits), \ + .enable_reg = PM8607_##ereg, \ + .enable_bit = (ebit), \ .slope_double = (0), \ .vol_table = (unsigned int *)&LDO##_id##_table, \ .vol_suspend = (unsigned int *)&LDO##_id##_suspend_table, \ } static struct pm8607_regulator_info pm8607_regulator_info[] = { - PM8607_DVC(BUCK1, GO, 0, SUPPLIES_EN11, 0), - PM8607_DVC(BUCK2, GO, 1, SUPPLIES_EN11, 1), - PM8607_DVC(BUCK3, GO, 2, SUPPLIES_EN11, 2), - - PM8607_LDO(1, LDO1, 0, SUPPLIES_EN11, 3), - PM8607_LDO(2, LDO2, 0, SUPPLIES_EN11, 4), - PM8607_LDO(3, LDO3, 0, SUPPLIES_EN11, 5), - PM8607_LDO(4, LDO4, 0, SUPPLIES_EN11, 6), - PM8607_LDO(5, LDO5, 0, SUPPLIES_EN11, 7), - PM8607_LDO(6, LDO6, 0, SUPPLIES_EN12, 0), - PM8607_LDO(7, LDO7, 0, SUPPLIES_EN12, 1), - PM8607_LDO(8, LDO8, 0, SUPPLIES_EN12, 2), - PM8607_LDO(9, LDO9, 0, SUPPLIES_EN12, 3), - PM8607_LDO(10, LDO10, 0, SUPPLIES_EN12, 4), - PM8607_LDO(12, LDO12, 0, SUPPLIES_EN12, 5), - PM8607_LDO(13, VIBRATOR_SET, 1, VIBRATOR_SET, 0), - PM8607_LDO(14, LDO14, 0, SUPPLIES_EN12, 6), + PM8607_DVC(BUCK1, 6, GO, 0, SUPPLIES_EN11, 0), + PM8607_DVC(BUCK2, 6, GO, 1, SUPPLIES_EN11, 1), + PM8607_DVC(BUCK3, 6, GO, 2, SUPPLIES_EN11, 2), + + PM8607_LDO( 1, LDO1, 0, 2, SUPPLIES_EN11, 3), + PM8607_LDO( 2, LDO2, 0, 3, SUPPLIES_EN11, 4), + PM8607_LDO( 3, LDO3, 0, 3, SUPPLIES_EN11, 5), + PM8607_LDO( 4, LDO4, 0, 3, SUPPLIES_EN11, 6), + PM8607_LDO( 5, LDO5, 0, 2, SUPPLIES_EN11, 7), + PM8607_LDO( 6, LDO6, 0, 3, SUPPLIES_EN12, 0), + PM8607_LDO( 7, LDO7, 0, 3, SUPPLIES_EN12, 1), + PM8607_LDO( 8, LDO8, 0, 3, SUPPLIES_EN12, 2), + PM8607_LDO( 9, LDO9, 0, 3, SUPPLIES_EN12, 3), + PM8607_LDO(10, LDO10, 0, 4, SUPPLIES_EN12, 4), + PM8607_LDO(12, LDO12, 0, 4, SUPPLIES_EN12, 5), + PM8607_LDO(13, VIBRATOR_SET, 1, 3, VIBRATOR_SET, 0), + PM8607_LDO(14, LDO14, 0, 3, SUPPLIES_EN12, 6), }; static int __devinit pm8607_regulator_probe(struct platform_device *pdev) @@ -316,7 +400,6 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev) struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); struct pm8607_regulator_info *info = NULL; struct regulator_init_data *pdata = pdev->dev.platform_data; - struct regulator_config config = { }; struct resource *res; int i; @@ -342,17 +425,9 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev) if ((i == PM8607_ID_BUCK3) && info->chip->buck3_double) info->slope_double = 1; - config.dev = &pdev->dev; - config.init_data = pdata; - config.driver_data = info; - - if (chip->id == CHIP_PM8607) - config.regmap = chip->regmap; - else - config.regmap = chip->regmap_companion; - /* replace driver_data with info */ - info->regulator = regulator_register(&info->desc, &config); + info->regulator = regulator_register(&info->desc, &pdev->dev, + pdata, info, NULL); if (IS_ERR(info->regulator)) { dev_err(&pdev->dev, "failed to register regulator %s\n", info->desc.name); diff --git a/trunk/drivers/regulator/Kconfig b/trunk/drivers/regulator/Kconfig index c86b8864e411..36db5a441eba 100644 --- a/trunk/drivers/regulator/Kconfig +++ b/trunk/drivers/regulator/Kconfig @@ -223,16 +223,6 @@ config REGULATOR_PCF50633 Say Y here to support the voltage regulators and convertors on PCF50633 -config REGULATOR_RC5T583 - tristate "RICOH RC5T583 Power regulators" - depends on MFD_RC5T583 - help - Select this option to enable the power regulator of RICOH - PMIC RC5T583. - This driver supports the control of different power rails of device - through regulator interface. The device supports multiple DCDC/LDO - outputs which can be controlled by i2c communication. - config REGULATOR_S5M8767 tristate "Samsung S5M8767A voltage regulator" depends on MFD_S5M_CORE @@ -268,18 +258,6 @@ config REGULATOR_DB8500_PRCMU This driver supports the voltage domain regulators controlled by the DB8500 PRCMU -config REGULATOR_PALMAS - tristate "TI Palmas PMIC Regulators" - depends on MFD_PALMAS - help - If you wish to control the regulators on the Palmas series of - chips say Y here. This will enable support for all the software - controllable SMPS/LDO regulators. - - The regulators available on Palmas series chips vary depending - on the muxing. This is handled automatically in the driver by - reading the mux info from OTP. - config REGULATOR_TPS6105X tristate "TI TPS6105X Power regulators" depends on TPS6105X @@ -290,11 +268,11 @@ config REGULATOR_TPS6105X audio amplifiers. config REGULATOR_TPS62360 - tristate "TI TPS6236x Power Regulator" + tristate "TI TPS62360 Power Regulator" depends on I2C select REGMAP_I2C help - This driver supports TPS6236x voltage regulator chip. This + This driver supports TPS62360 voltage regulator chip. This regulator is meant for processor core supply. This chip is high-frequency synchronous step down dc-dc converter optimized for battery-powered portable applications. @@ -316,13 +294,6 @@ config REGULATOR_TPS6507X three step-down converters and two general-purpose LDO voltage regulators. It supports TI's software based Class-2 SmartReflex implementation. -config REGULATOR_TPS65090 - tristate "TI TPS65090 Power regulator" - depends on MFD_TPS65090 - help - This driver provides support for the voltage regulators on the - TI TPS65090 PMIC. - config REGULATOR_TPS65217 tristate "TI TPS65217 Power regulators" depends on MFD_TPS65217 diff --git a/trunk/drivers/regulator/Makefile b/trunk/drivers/regulator/Makefile index 977fd46909ab..94b52745e957 100644 --- a/trunk/drivers/regulator/Makefile +++ b/trunk/drivers/regulator/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o +obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o @@ -19,7 +20,6 @@ obj-$(CONFIG_REGULATOR_DA903X) += da903x.o obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o -obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o @@ -33,16 +33,13 @@ obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o -obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o -obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o -obj-$(CONFIG_REGULATOR_TPS65090) += tps65090-regulator.o obj-$(CONFIG_REGULATOR_TPS65217) += tps65217-regulator.o obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o diff --git a/trunk/drivers/regulator/aat2870-regulator.c b/trunk/drivers/regulator/aat2870-regulator.c index 06776ca945f2..9ed5c5d84e12 100644 --- a/trunk/drivers/regulator/aat2870-regulator.c +++ b/trunk/drivers/regulator/aat2870-regulator.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -177,7 +178,6 @@ static struct aat2870_regulator *aat2870_get_regulator(int id) static int aat2870_regulator_probe(struct platform_device *pdev) { struct aat2870_regulator *ri; - struct regulator_config config = { 0 }; struct regulator_dev *rdev; ri = aat2870_get_regulator(pdev->id); @@ -187,11 +187,8 @@ static int aat2870_regulator_probe(struct platform_device *pdev) } ri->aat2870 = dev_get_drvdata(pdev->dev.parent); - config.dev = &pdev->dev; - config.driver_data = ri; - config.init_data = pdev->dev.platform_data; - - rdev = regulator_register(&ri->desc, &config); + rdev = regulator_register(&ri->desc, &pdev->dev, + pdev->dev.platform_data, ri, NULL); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "Failed to register regulator %s\n", ri->desc.name); @@ -234,4 +231,3 @@ module_exit(aat2870_regulator_exit); MODULE_DESCRIPTION("AnalogicTech AAT2870 Regulator"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jin Park "); -MODULE_ALIAS("platform:aat2870-regulator"); diff --git a/trunk/drivers/regulator/ab3100.c b/trunk/drivers/regulator/ab3100.c index 03f4d9c604ec..042271aace6a 100644 --- a/trunk/drivers/regulator/ab3100.c +++ b/trunk/drivers/regulator/ab3100.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -304,12 +305,53 @@ static int ab3100_get_voltage_regulator(struct regulator_dev *reg) return abreg->typ_voltages[regval]; } -static int ab3100_set_voltage_regulator_sel(struct regulator_dev *reg, - unsigned selector) +static int ab3100_get_best_voltage_index(struct regulator_dev *reg, + int min_uV, int max_uV) +{ + struct ab3100_regulator *abreg = reg->reg_data; + int i; + int bestmatch; + int bestindex; + + /* + * Locate the minimum voltage fitting the criteria on + * this regulator. The switchable voltages are not + * in strict falling order so we need to check them + * all for the best match. + */ + bestmatch = INT_MAX; + bestindex = -1; + for (i = 0; i < abreg->voltages_len; i++) { + if (abreg->typ_voltages[i] <= max_uV && + abreg->typ_voltages[i] >= min_uV && + abreg->typ_voltages[i] < bestmatch) { + bestmatch = abreg->typ_voltages[i]; + bestindex = i; + } + } + + if (bestindex < 0) { + dev_warn(®->dev, "requested %d<=x<=%d uV, out of range!\n", + min_uV, max_uV); + return -EINVAL; + } + return bestindex; +} + +static int ab3100_set_voltage_regulator(struct regulator_dev *reg, + int min_uV, int max_uV, + unsigned *selector) { struct ab3100_regulator *abreg = reg->reg_data; u8 regval; int err; + int bestindex; + + bestindex = ab3100_get_best_voltage_index(reg, min_uV, max_uV); + if (bestindex < 0) + return bestindex; + + *selector = bestindex; err = abx500_get_register_interruptible(abreg->dev, 0, abreg->regreg, ®val); @@ -322,7 +364,7 @@ static int ab3100_set_voltage_regulator_sel(struct regulator_dev *reg, /* The highest three bits control the variable regulators */ regval &= ~0xE0; - regval |= (selector << 5); + regval |= (bestindex << 5); err = abx500_set_register_interruptible(abreg->dev, 0, abreg->regreg, regval); @@ -350,7 +392,7 @@ static int ab3100_set_suspend_voltage_regulator(struct regulator_dev *reg, return -EINVAL; /* LDO E and BUCK have special suspend voltages you can set */ - bestindex = regulator_map_voltage_iterate(reg, uV, uV); + bestindex = ab3100_get_best_voltage_index(reg, uV, uV); err = abx500_get_register_interruptible(abreg->dev, 0, targetreg, ®val); @@ -422,7 +464,7 @@ static struct regulator_ops regulator_ops_variable = { .disable = ab3100_disable_regulator, .is_enabled = ab3100_is_enabled_regulator, .get_voltage = ab3100_get_voltage_regulator, - .set_voltage_sel = ab3100_set_voltage_regulator_sel, + .set_voltage = ab3100_set_voltage_regulator, .list_voltage = ab3100_list_voltage_regulator, .enable_time = ab3100_enable_time_regulator, }; @@ -432,7 +474,7 @@ static struct regulator_ops regulator_ops_variable_sleepable = { .disable = ab3100_disable_regulator, .is_enabled = ab3100_is_enabled_regulator, .get_voltage = ab3100_get_voltage_regulator, - .set_voltage_sel = ab3100_set_voltage_regulator_sel, + .set_voltage = ab3100_set_voltage_regulator, .set_suspend_voltage = ab3100_set_suspend_voltage_regulator, .list_voltage = ab3100_list_voltage_regulator, .enable_time = ab3100_enable_time_regulator, @@ -540,7 +582,6 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { static int __devinit ab3100_regulators_probe(struct platform_device *pdev) { struct ab3100_platform_data *plfdata = pdev->dev.platform_data; - struct regulator_config config = { }; int err = 0; u8 data; int i; @@ -586,15 +627,15 @@ static int __devinit ab3100_regulators_probe(struct platform_device *pdev) reg->dev = &pdev->dev; reg->plfdata = plfdata; - config.dev = &pdev->dev; - config.driver_data = reg; - config.init_data = &plfdata->reg_constraints[i]; - /* * Register the regulator, pass around * the ab3100_regulator struct */ - rdev = regulator_register(&ab3100_regulator_desc[i], &config); + rdev = regulator_register(&ab3100_regulator_desc[i], + &pdev->dev, + &plfdata->reg_constraints[i], + reg, NULL); + if (IS_ERR(rdev)) { err = PTR_ERR(rdev); dev_err(&pdev->dev, diff --git a/trunk/drivers/regulator/ab8500.c b/trunk/drivers/regulator/ab8500.c index e1b8c54ace5a..c7ee4c15d6f5 100644 --- a/trunk/drivers/regulator/ab8500.c +++ b/trunk/drivers/regulator/ab8500.c @@ -18,12 +18,9 @@ #include #include #include -#include -#include #include #include #include -#include /** * struct ab8500_regulator_info - ab8500 regulator information @@ -237,8 +234,25 @@ static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev) return val; } -static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev, - unsigned selector) +static int ab8500_get_best_voltage_index(struct regulator_dev *rdev, + int min_uV, int max_uV) +{ + struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); + int i; + + /* check the supported voltage */ + for (i = 0; i < info->voltages_len; i++) { + if ((info->voltages[i] >= min_uV) && + (info->voltages[i] <= max_uV)) + return i; + } + + return -EINVAL; +} + +static int ab8500_regulator_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, + unsigned *selector) { int ret; struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); @@ -249,8 +263,18 @@ static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev, return -EINVAL; } + /* get the appropriate voltages within the range */ + ret = ab8500_get_best_voltage_index(rdev, min_uV, max_uV); + if (ret < 0) { + dev_err(rdev_get_dev(rdev), + "couldn't get best voltage for regulator\n"); + return ret; + } + + *selector = ret; + /* set the registers for the request */ - regval = (u8)selector; + regval = (u8)ret; ret = abx500_mask_and_set_register_interruptible(info->dev, info->voltage_bank, info->voltage_reg, info->voltage_mask, regval); @@ -295,7 +319,7 @@ static struct regulator_ops ab8500_regulator_ops = { .disable = ab8500_regulator_disable, .is_enabled = ab8500_regulator_is_enabled, .get_voltage_sel = ab8500_regulator_get_voltage_sel, - .set_voltage_sel = ab8500_regulator_set_voltage_sel, + .set_voltage = ab8500_regulator_set_voltage, .list_voltage = ab8500_list_voltage, .enable_time = ab8500_regulator_enable_time, .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel, @@ -711,139 +735,12 @@ static struct ab8500_reg_init ab8500_reg_init[] = { REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16), }; -static __devinit int -ab8500_regulator_init_registers(struct platform_device *pdev, int id, int value) -{ - int err; - - if (value & ~ab8500_reg_init[id].mask) { - dev_err(&pdev->dev, - "Configuration error: value outside mask.\n"); - return -EINVAL; - } - - err = abx500_mask_and_set_register_interruptible( - &pdev->dev, - ab8500_reg_init[id].bank, - ab8500_reg_init[id].addr, - ab8500_reg_init[id].mask, - value); - if (err < 0) { - dev_err(&pdev->dev, - "Failed to initialize 0x%02x, 0x%02x.\n", - ab8500_reg_init[id].bank, - ab8500_reg_init[id].addr); - return err; - } - - dev_vdbg(&pdev->dev, - "init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", - ab8500_reg_init[id].bank, - ab8500_reg_init[id].addr, - ab8500_reg_init[id].mask, - value); - - return 0; -} - -static __devinit int ab8500_regulator_register(struct platform_device *pdev, - struct regulator_init_data *init_data, - int id, - struct device_node *np) -{ - struct ab8500_regulator_info *info = NULL; - struct regulator_config config = { }; - int err; - - /* assign per-regulator data */ - info = &ab8500_regulator_info[id]; - info->dev = &pdev->dev; - - config.dev = &pdev->dev; - config.init_data = init_data; - config.driver_data = info; - config.of_node = np; - - /* fix for hardware before ab8500v2.0 */ - if (abx500_get_chip_id(info->dev) < 0x20) { - if (info->desc.id == AB8500_LDO_AUX3) { - info->desc.n_voltages = - ARRAY_SIZE(ldo_vauxn_voltages); - info->voltages = ldo_vauxn_voltages; - info->voltages_len = - ARRAY_SIZE(ldo_vauxn_voltages); - info->voltage_mask = 0xf; - } - } - - /* register regulator with framework */ - info->regulator = regulator_register(&info->desc, &config); - if (IS_ERR(info->regulator)) { - err = PTR_ERR(info->regulator); - dev_err(&pdev->dev, "failed to register regulator %s\n", - info->desc.name); - /* when we fail, un-register all earlier regulators */ - while (--id >= 0) { - info = &ab8500_regulator_info[id]; - regulator_unregister(info->regulator); - } - return err; - } - - return 0; -} - -static struct of_regulator_match ab8500_regulator_matches[] = { - { .name = "LDO-AUX1", .driver_data = (void *) AB8500_LDO_AUX1, }, - { .name = "LDO-AUX2", .driver_data = (void *) AB8500_LDO_AUX2, }, - { .name = "LDO-AUX3", .driver_data = (void *) AB8500_LDO_AUX3, }, - { .name = "LDO-INTCORE", .driver_data = (void *) AB8500_LDO_INTCORE, }, - { .name = "LDO-TVOUT", .driver_data = (void *) AB8500_LDO_TVOUT, }, - { .name = "LDO-USB", .driver_data = (void *) AB8500_LDO_USB, }, - { .name = "LDO-AUDIO", .driver_data = (void *) AB8500_LDO_AUDIO, }, - { .name = "LDO-ANAMIC1", .driver_data = (void *) AB8500_LDO_ANAMIC1, }, - { .name = "LDO-ANAMIC2", .driver_data = (void *) AB8500_LDO_ANAMIC2, }, - { .name = "LDO-DMIC", .driver_data = (void *) AB8500_LDO_DMIC, }, - { .name = "LDO-ANA", .driver_data = (void *) AB8500_LDO_ANA, }, -}; - -static __devinit int -ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np) -{ - int err, i; - - for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { - err = ab8500_regulator_register( - pdev, ab8500_regulator_matches[i].init_data, - i, ab8500_regulator_matches[i].of_node); - if (err) - return err; - } - - return 0; -} - static __devinit int ab8500_regulator_probe(struct platform_device *pdev) { struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); struct ab8500_platform_data *pdata; - struct device_node *np = pdev->dev.of_node; int i, err; - if (np) { - err = of_regulator_match(&pdev->dev, np, - ab8500_regulator_matches, - ARRAY_SIZE(ab8500_regulator_matches)); - if (err < 0) { - dev_err(&pdev->dev, - "Error parsing regulator init data: %d\n", err); - return err; - } - - err = ab8500_regulator_of_probe(pdev, np); - return err; - } - if (!ab8500) { dev_err(&pdev->dev, "null mfd parent\n"); return -EINVAL; @@ -862,7 +759,8 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev) /* initialize registers */ for (i = 0; i < pdata->num_regulator_reg_init; i++) { - int id, value; + int id; + u8 value; id = pdata->regulator_reg_init[i].id; value = pdata->regulator_reg_init[i].value; @@ -873,17 +771,70 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev) "Configuration error: id outside range.\n"); return -EINVAL; } + if (value & ~ab8500_reg_init[id].mask) { + dev_err(&pdev->dev, + "Configuration error: value outside mask.\n"); + return -EINVAL; + } - err = ab8500_regulator_init_registers(pdev, id, value); - if (err < 0) + /* initialize register */ + err = abx500_mask_and_set_register_interruptible(&pdev->dev, + ab8500_reg_init[id].bank, + ab8500_reg_init[id].addr, + ab8500_reg_init[id].mask, + value); + if (err < 0) { + dev_err(&pdev->dev, + "Failed to initialize 0x%02x, 0x%02x.\n", + ab8500_reg_init[id].bank, + ab8500_reg_init[id].addr); return err; + } + dev_vdbg(&pdev->dev, + " init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", + ab8500_reg_init[id].bank, + ab8500_reg_init[id].addr, + ab8500_reg_init[id].mask, + value); } /* register all regulators */ for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { - err = ab8500_regulator_register(pdev, &pdata->regulator[i], i, NULL); - if (err < 0) + struct ab8500_regulator_info *info = NULL; + + /* assign per-regulator data */ + info = &ab8500_regulator_info[i]; + info->dev = &pdev->dev; + + /* fix for hardware before ab8500v2.0 */ + if (abx500_get_chip_id(info->dev) < 0x20) { + if (info->desc.id == AB8500_LDO_AUX3) { + info->desc.n_voltages = + ARRAY_SIZE(ldo_vauxn_voltages); + info->voltages = ldo_vauxn_voltages; + info->voltages_len = + ARRAY_SIZE(ldo_vauxn_voltages); + info->voltage_mask = 0xf; + } + } + + /* register regulator with framework */ + info->regulator = regulator_register(&info->desc, &pdev->dev, + &pdata->regulator[i], info, NULL); + if (IS_ERR(info->regulator)) { + err = PTR_ERR(info->regulator); + dev_err(&pdev->dev, "failed to register regulator %s\n", + info->desc.name); + /* when we fail, un-register all earlier regulators */ + while (--i >= 0) { + info = &ab8500_regulator_info[i]; + regulator_unregister(info->regulator); + } return err; + } + + dev_vdbg(rdev_get_dev(info->regulator), + "%s-probed\n", info->desc.name); } return 0; @@ -906,18 +857,12 @@ static __devexit int ab8500_regulator_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id ab8500_regulator_match[] = { - { .compatible = "stericsson,ab8500-regulator", }, - {} -}; - static struct platform_driver ab8500_regulator_driver = { .probe = ab8500_regulator_probe, .remove = __devexit_p(ab8500_regulator_remove), .driver = { .name = "ab8500-regulator", .owner = THIS_MODULE, - .of_match_table = ab8500_regulator_match, }, }; diff --git a/trunk/drivers/regulator/ad5398.c b/trunk/drivers/regulator/ad5398.c index 46d05f38baf8..26d23adfc66f 100644 --- a/trunk/drivers/regulator/ad5398.c +++ b/trunk/drivers/regulator/ad5398.c @@ -99,8 +99,8 @@ static int ad5398_set_current_limit(struct regulator_dev *rdev, int min_uA, int if (ad5398_calc_current(chip, selector) > max_uA) return -EINVAL; - dev_dbg(&client->dev, "changing current %duA\n", - ad5398_calc_current(chip, selector)); + dev_dbg(&client->dev, "changing current %dmA\n", + ad5398_calc_current(chip, selector) / 1000); /* read chip enable bit */ ret = ad5398_read_reg(client, &data); @@ -184,7 +184,7 @@ static struct regulator_ops ad5398_ops = { .is_enabled = ad5398_is_enabled, }; -static const struct regulator_desc ad5398_reg = { +static struct regulator_desc ad5398_reg = { .name = "isink", .id = 0, .ops = &ad5398_ops, @@ -212,7 +212,6 @@ static int __devinit ad5398_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct regulator_init_data *init_data = client->dev.platform_data; - struct regulator_config config = { }; struct ad5398_chip_info *chip; const struct ad5398_current_data_format *df = (struct ad5398_current_data_format *)id->driver_data; @@ -221,14 +220,10 @@ static int __devinit ad5398_probe(struct i2c_client *client, if (!init_data) return -EINVAL; - chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (!chip) return -ENOMEM; - config.dev = &client->dev; - config.init_data = init_data; - config.driver_data = chip; - chip->client = client; chip->min_uA = df->min_uA; @@ -237,7 +232,8 @@ static int __devinit ad5398_probe(struct i2c_client *client, chip->current_offset = df->current_offset; chip->current_mask = (chip->current_level - 1) << chip->current_offset; - chip->rdev = regulator_register(&ad5398_reg, &config); + chip->rdev = regulator_register(&ad5398_reg, &client->dev, + init_data, chip, NULL); if (IS_ERR(chip->rdev)) { ret = PTR_ERR(chip->rdev); dev_err(&client->dev, "failed to register %s %s\n", @@ -250,6 +246,7 @@ static int __devinit ad5398_probe(struct i2c_client *client, return 0; err: + kfree(chip); return ret; } @@ -258,6 +255,8 @@ static int __devexit ad5398_remove(struct i2c_client *client) struct ad5398_chip_info *chip = i2c_get_clientdata(client); regulator_unregister(chip->rdev); + kfree(chip); + return 0; } diff --git a/trunk/drivers/regulator/anatop-regulator.c b/trunk/drivers/regulator/anatop-regulator.c index 49b2112b0486..81fd606e47bc 100644 --- a/trunk/drivers/regulator/anatop-regulator.c +++ b/trunk/drivers/regulator/anatop-regulator.c @@ -122,7 +122,6 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev) struct anatop_regulator *sreg; struct regulator_init_data *initdata; struct anatop *anatopmfd = dev_get_drvdata(pdev->dev.parent); - struct regulator_config config = { }; int ret = 0; initdata = of_get_regulator_init_data(dev, np); @@ -179,13 +178,9 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev) rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage) / 25000 + 1; - config.dev = &pdev->dev; - config.init_data = initdata; - config.driver_data = sreg; - config.of_node = pdev->dev.of_node; - /* register regulator */ - rdev = regulator_register(rdesc, &config); + rdev = regulator_register(rdesc, dev, + initdata, sreg, pdev->dev.of_node); if (IS_ERR(rdev)) { dev_err(dev, "failed to register %s\n", rdesc->name); diff --git a/trunk/drivers/regulator/core.c b/trunk/drivers/regulator/core.c index 7584a74eec8a..e70dd382a009 100644 --- a/trunk/drivers/regulator/core.c +++ b/trunk/drivers/regulator/core.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -75,7 +74,6 @@ struct regulator_map { struct regulator { struct device *dev; struct list_head list; - unsigned int always_on:1; int uA_load; int min_uV; int max_uV; @@ -157,17 +155,6 @@ static struct device_node *of_get_regulator(struct device *dev, const char *supp return regnode; } -static int _regulator_can_change_status(struct regulator_dev *rdev) -{ - if (!rdev->constraints) - return 0; - - if (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_STATUS) - return 1; - else - return 0; -} - /* Platform voltage constraint check */ static int regulator_check_voltage(struct regulator_dev *rdev, int *min_uV, int *max_uV) @@ -662,7 +649,7 @@ static void drms_uA_update(struct regulator_dev *rdev) /* get input voltage */ input_uV = 0; if (rdev->supply) - input_uV = regulator_get_voltage(rdev->supply); + input_uV = _regulator_get_voltage(rdev); if (input_uV <= 0) input_uV = rdev->constraints->input_uV; if (input_uV <= 0) @@ -686,14 +673,17 @@ static int suspend_set_state(struct regulator_dev *rdev, struct regulator_state *rstate) { int ret = 0; + bool can_set_state; + + can_set_state = rdev->desc->ops->set_suspend_enable && + rdev->desc->ops->set_suspend_disable; /* If we have no suspend mode configration don't set anything; - * only warn if the driver implements set_suspend_voltage or - * set_suspend_mode callback. + * only warn if the driver actually makes the suspend mode + * configurable. */ if (!rstate->enabled && !rstate->disabled) { - if (rdev->desc->ops->set_suspend_voltage || - rdev->desc->ops->set_suspend_mode) + if (can_set_state) rdev_warn(rdev, "No configuration\n"); return 0; } @@ -703,13 +693,15 @@ static int suspend_set_state(struct regulator_dev *rdev, return -EINVAL; } - if (rstate->enabled && rdev->desc->ops->set_suspend_enable) + if (!can_set_state) { + rdev_err(rdev, "no way to set suspend state\n"); + return -EINVAL; + } + + if (rstate->enabled) ret = rdev->desc->ops->set_suspend_enable(rdev); - else if (rstate->disabled && rdev->desc->ops->set_suspend_disable) + else ret = rdev->desc->ops->set_suspend_disable(rdev); - else /* OK if set_suspend_enable or set_suspend_disable is NULL */ - ret = 0; - if (ret < 0) { rdev_err(rdev, "failed to enabled/disable\n"); return ret; @@ -1154,15 +1146,6 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, ®ulator->max_uV); } - /* - * Check now if the regulator is an always on regulator - if - * it is then we don't need to do nearly so much work for - * enable/disable calls. - */ - if (!_regulator_can_change_status(rdev) && - _regulator_is_enabled(rdev)) - regulator->always_on = true; - mutex_unlock(&rdev->mutex); return regulator; link_name_err: @@ -1186,52 +1169,26 @@ static int _regulator_get_enable_time(struct regulator_dev *rdev) } static struct regulator_dev *regulator_dev_lookup(struct device *dev, - const char *supply, - int *ret) + const char *supply) { struct regulator_dev *r; struct device_node *node; - struct regulator_map *map; - const char *devname = NULL; /* first do a dt based lookup */ if (dev && dev->of_node) { node = of_get_regulator(dev, supply); - if (node) { + if (node) list_for_each_entry(r, ®ulator_list, list) if (r->dev.parent && node == r->dev.of_node) return r; - } else { - /* - * If we couldn't even get the node then it's - * not just that the device didn't register - * yet, there's no node and we'll never - * succeed. - */ - *ret = -ENODEV; - } } /* if not found, try doing it non-dt way */ - if (dev) - devname = dev_name(dev); - list_for_each_entry(r, ®ulator_list, list) if (strcmp(rdev_get_name(r), supply) == 0) return r; - list_for_each_entry(map, ®ulator_map_list, list) { - /* If the mapping has a device set up it must match */ - if (map->dev_name && - (!devname || strcmp(map->dev_name, devname))) - continue; - - if (strcmp(map->supply, supply) == 0) - return map->regulator; - } - - return NULL; } @@ -1240,6 +1197,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, int exclusive) { struct regulator_dev *rdev; + struct regulator_map *map; struct regulator *regulator = ERR_PTR(-EPROBE_DEFER); const char *devname = NULL; int ret; @@ -1254,10 +1212,22 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, mutex_lock(®ulator_list_mutex); - rdev = regulator_dev_lookup(dev, id, &ret); + rdev = regulator_dev_lookup(dev, id); if (rdev) goto found; + list_for_each_entry(map, ®ulator_map_list, list) { + /* If the mapping has a device set up it must match */ + if (map->dev_name && + (!devname || strcmp(map->dev_name, devname))) + continue; + + if (strcmp(map->supply, id) == 0) { + rdev = map->regulator; + goto found; + } + } + if (board_wants_dummy_regulator) { rdev = dummy_regulator_rdev; goto found; @@ -1461,13 +1431,21 @@ void devm_regulator_put(struct regulator *regulator) rc = devres_destroy(regulator->dev, devm_regulator_release, devm_regulator_match, regulator); - if (rc == 0) - regulator_put(regulator); - else - WARN_ON(rc); + WARN_ON(rc); } EXPORT_SYMBOL_GPL(devm_regulator_put); +static int _regulator_can_change_status(struct regulator_dev *rdev) +{ + if (!rdev->constraints) + return 0; + + if (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_STATUS) + return 1; + else + return 0; +} + /* locks held by regulator_enable() */ static int _regulator_enable(struct regulator_dev *rdev) { @@ -1547,9 +1525,6 @@ int regulator_enable(struct regulator *regulator) struct regulator_dev *rdev = regulator->rdev; int ret = 0; - if (regulator->always_on) - return 0; - if (rdev->supply) { ret = regulator_enable(rdev->supply); if (ret != 0) @@ -1628,9 +1603,6 @@ int regulator_disable(struct regulator *regulator) struct regulator_dev *rdev = regulator->rdev; int ret = 0; - if (regulator->always_on) - return 0; - mutex_lock(&rdev->mutex); ret = _regulator_disable(rdev); mutex_unlock(&rdev->mutex); @@ -1739,9 +1711,6 @@ int regulator_disable_deferred(struct regulator *regulator, int ms) struct regulator_dev *rdev = regulator->rdev; int ret; - if (regulator->always_on) - return 0; - mutex_lock(&rdev->mutex); rdev->deferred_disables++; mutex_unlock(&rdev->mutex); @@ -1755,61 +1724,6 @@ int regulator_disable_deferred(struct regulator *regulator, int ms) } EXPORT_SYMBOL_GPL(regulator_disable_deferred); -/** - * regulator_is_enabled_regmap - standard is_enabled() for regmap users - * - * @rdev: regulator to operate on - * - * Regulators that use regmap for their register I/O can set the - * enable_reg and enable_mask fields in their descriptor and then use - * this as their is_enabled operation, saving some code. - */ -int regulator_is_enabled_regmap(struct regulator_dev *rdev) -{ - unsigned int val; - int ret; - - ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); - if (ret != 0) - return ret; - - return (val & rdev->desc->enable_mask) != 0; -} -EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap); - -/** - * regulator_enable_regmap - standard enable() for regmap users - * - * @rdev: regulator to operate on - * - * Regulators that use regmap for their register I/O can set the - * enable_reg and enable_mask fields in their descriptor and then use - * this as their enable() operation, saving some code. - */ -int regulator_enable_regmap(struct regulator_dev *rdev) -{ - return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, - rdev->desc->enable_mask, - rdev->desc->enable_mask); -} -EXPORT_SYMBOL_GPL(regulator_enable_regmap); - -/** - * regulator_disable_regmap - standard disable() for regmap users - * - * @rdev: regulator to operate on - * - * Regulators that use regmap for their register I/O can set the - * enable_reg and enable_mask fields in their descriptor and then use - * this as their disable() operation, saving some code. - */ -int regulator_disable_regmap(struct regulator_dev *rdev) -{ - return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, - rdev->desc->enable_mask, 0); -} -EXPORT_SYMBOL_GPL(regulator_disable_regmap); - static int _regulator_is_enabled(struct regulator_dev *rdev) { /* If we don't know then assume that the regulator is always on */ @@ -1835,9 +1749,6 @@ int regulator_is_enabled(struct regulator *regulator) { int ret; - if (regulator->always_on) - return 1; - mutex_lock(®ulator->rdev->mutex); ret = _regulator_is_enabled(regulator->rdev); mutex_unlock(®ulator->rdev->mutex); @@ -1862,26 +1773,6 @@ int regulator_count_voltages(struct regulator *regulator) } EXPORT_SYMBOL_GPL(regulator_count_voltages); -/** - * regulator_list_voltage_linear - List voltages with simple calculation - * - * @rdev: Regulator device - * @selector: Selector to convert into a voltage - * - * Regulators with a simple linear mapping between voltages and - * selectors can set min_uV and uV_step in the regulator descriptor - * and then use this function as their list_voltage() operation, - */ -int regulator_list_voltage_linear(struct regulator_dev *rdev, - unsigned int selector) -{ - if (selector >= rdev->desc->n_voltages) - return -EINVAL; - - return rdev->desc->min_uV + (rdev->desc->uV_step * selector); -} -EXPORT_SYMBOL_GPL(regulator_list_voltage_linear); - /** * regulator_list_voltage - enumerate supported voltages * @regulator: regulator source @@ -1946,183 +1837,75 @@ int regulator_is_supported_voltage(struct regulator *regulator, } EXPORT_SYMBOL_GPL(regulator_is_supported_voltage); -/** - * regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users - * - * @rdev: regulator to operate on - * - * Regulators that use regmap for their register I/O can set the - * vsel_reg and vsel_mask fields in their descriptor and then use this - * as their get_voltage_vsel operation, saving some code. - */ -int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev) -{ - unsigned int val; - int ret; - - ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val); - if (ret != 0) - return ret; - - val &= rdev->desc->vsel_mask; - val >>= ffs(rdev->desc->vsel_mask) - 1; - - return val; -} -EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap); - -/** - * regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users - * - * @rdev: regulator to operate on - * @sel: Selector to set - * - * Regulators that use regmap for their register I/O can set the - * vsel_reg and vsel_mask fields in their descriptor and then use this - * as their set_voltage_vsel operation, saving some code. - */ -int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel) -{ - sel <<= ffs(rdev->desc->vsel_mask) - 1; - - return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg, - rdev->desc->vsel_mask, sel); -} -EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap); - -/** - * regulator_map_voltage_iterate - map_voltage() based on list_voltage() - * - * @rdev: Regulator to operate on - * @min_uV: Lower bound for voltage - * @max_uV: Upper bound for voltage - * - * Drivers implementing set_voltage_sel() and list_voltage() can use - * this as their map_voltage() operation. It will find a suitable - * voltage by calling list_voltage() until it gets something in bounds - * for the requested voltages. - */ -int regulator_map_voltage_iterate(struct regulator_dev *rdev, - int min_uV, int max_uV) -{ - int best_val = INT_MAX; - int selector = 0; - int i, ret; - - /* Find the smallest voltage that falls within the specified - * range. - */ - for (i = 0; i < rdev->desc->n_voltages; i++) { - ret = rdev->desc->ops->list_voltage(rdev, i); - if (ret < 0) - continue; - - if (ret < best_val && ret >= min_uV && ret <= max_uV) { - best_val = ret; - selector = i; - } - } - - if (best_val != INT_MAX) - return selector; - else - return -EINVAL; -} -EXPORT_SYMBOL_GPL(regulator_map_voltage_iterate); - -/** - * regulator_map_voltage_linear - map_voltage() for simple linear mappings - * - * @rdev: Regulator to operate on - * @min_uV: Lower bound for voltage - * @max_uV: Upper bound for voltage - * - * Drivers providing min_uV and uV_step in their regulator_desc can - * use this as their map_voltage() operation. - */ -int regulator_map_voltage_linear(struct regulator_dev *rdev, - int min_uV, int max_uV) -{ - int ret, voltage; - - if (!rdev->desc->uV_step) { - BUG_ON(!rdev->desc->uV_step); - return -EINVAL; - } - - ret = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step); - if (ret < 0) - return ret; - - /* Map back into a voltage to verify we're still in bounds */ - voltage = rdev->desc->ops->list_voltage(rdev, ret); - if (voltage < min_uV || voltage > max_uV) - return -EINVAL; - - return ret; -} -EXPORT_SYMBOL_GPL(regulator_map_voltage_linear); - static int _regulator_do_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) { int ret; int delay = 0; - int best_val; unsigned int selector; - int old_selector = -1; trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV); min_uV += rdev->constraints->uV_offset; max_uV += rdev->constraints->uV_offset; - /* - * If we can't obtain the old selector there is not enough - * info to call set_voltage_time_sel(). - */ - if (rdev->desc->ops->set_voltage_time_sel && - rdev->desc->ops->get_voltage_sel) { - old_selector = rdev->desc->ops->get_voltage_sel(rdev); - if (old_selector < 0) - return old_selector; - } - if (rdev->desc->ops->set_voltage) { ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV, &selector); - } else if (rdev->desc->ops->set_voltage_sel) { - if (rdev->desc->ops->map_voltage) - ret = rdev->desc->ops->map_voltage(rdev, min_uV, - max_uV); + + if (rdev->desc->ops->list_voltage) + selector = rdev->desc->ops->list_voltage(rdev, + selector); else - ret = regulator_map_voltage_iterate(rdev, min_uV, - max_uV); + selector = -1; + } else if (rdev->desc->ops->set_voltage_sel) { + int best_val = INT_MAX; + int i; - if (ret >= 0) { - selector = ret; - ret = rdev->desc->ops->set_voltage_sel(rdev, ret); - } - } else { - ret = -EINVAL; - } + selector = 0; - if (rdev->desc->ops->list_voltage) - best_val = rdev->desc->ops->list_voltage(rdev, selector); - else - best_val = -1; + /* Find the smallest voltage that falls within the specified + * range. + */ + for (i = 0; i < rdev->desc->n_voltages; i++) { + ret = rdev->desc->ops->list_voltage(rdev, i); + if (ret < 0) + continue; + + if (ret < best_val && ret >= min_uV && ret <= max_uV) { + best_val = ret; + selector = i; + } + } - /* Call set_voltage_time_sel if successfully obtained old_selector */ - if (ret == 0 && old_selector >= 0 && - rdev->desc->ops->set_voltage_time_sel) { + /* + * If we can't obtain the old selector there is not enough + * info to call set_voltage_time_sel(). + */ + if (rdev->desc->ops->set_voltage_time_sel && + rdev->desc->ops->get_voltage_sel) { + unsigned int old_selector = 0; - delay = rdev->desc->ops->set_voltage_time_sel(rdev, + ret = rdev->desc->ops->get_voltage_sel(rdev); + if (ret < 0) + return ret; + old_selector = ret; + ret = rdev->desc->ops->set_voltage_time_sel(rdev, old_selector, selector); - if (delay < 0) { - rdev_warn(rdev, "set_voltage_time_sel() failed: %d\n", - delay); - delay = 0; + if (ret < 0) + rdev_warn(rdev, "set_voltage_time_sel() failed: %d\n", ret); + else + delay = ret; } + + if (best_val != INT_MAX) { + ret = rdev->desc->ops->set_voltage_sel(rdev, selector); + selector = best_val; + } else { + ret = -EINVAL; + } + } else { + ret = -EINVAL; } /* Insert any necessary delays */ @@ -2137,7 +1920,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, NULL); - trace_regulator_set_voltage_complete(rdev_get_name(rdev), best_val); + trace_regulator_set_voltage_complete(rdev_get_name(rdev), selector); return ret; } @@ -2541,9 +2324,6 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) */ ret = -EINVAL; - if (!rdev->desc->ops->set_mode) - goto out; - /* get output voltage */ output_uV = _regulator_get_voltage(rdev); if (output_uV <= 0) { @@ -2745,13 +2525,9 @@ int regulator_bulk_enable(int num_consumers, int i; int ret = 0; - for (i = 0; i < num_consumers; i++) { - if (consumers[i].consumer->always_on) - consumers[i].ret = 0; - else - async_schedule_domain(regulator_bulk_enable_async, - &consumers[i], &async_domain); - } + for (i = 0; i < num_consumers; i++) + async_schedule_domain(regulator_bulk_enable_async, + &consumers[i], &async_domain); async_synchronize_full_domain(&async_domain); @@ -2790,7 +2566,7 @@ int regulator_bulk_disable(int num_consumers, struct regulator_bulk_data *consumers) { int i; - int ret, r; + int ret; for (i = num_consumers - 1; i >= 0; --i) { ret = regulator_disable(consumers[i].consumer); @@ -2802,12 +2578,8 @@ int regulator_bulk_disable(int num_consumers, err: pr_err("Failed to disable %s: %d\n", consumers[i].supply, ret); - for (++i; i < num_consumers; ++i) { - r = regulator_enable(consumers[i].consumer); - if (r != 0) - pr_err("Failed to reename %s: %d\n", - consumers[i].supply, r); - } + for (++i; i < num_consumers; ++i) + regulator_enable(consumers[i].consumer); return ret; } @@ -2984,6 +2756,10 @@ static int add_regulator_attributes(struct regulator_dev *rdev) return status; } + /* suspend mode constraints need multiple supporting methods */ + if (!(ops->set_suspend_enable && ops->set_suspend_disable)) + return status; + status = device_create_file(dev, &dev_attr_suspend_standby_state); if (status < 0) return status; @@ -3044,29 +2820,28 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) /** * regulator_register - register regulator * @regulator_desc: regulator to register - * @config: runtime configuration for regulator + * @dev: struct device for the regulator + * @init_data: platform provided init data, passed through by driver + * @driver_data: private regulator data + * @of_node: OpenFirmware node to parse for device tree bindings (may be + * NULL). * * Called by regulator drivers to register a regulator. * Returns 0 on success. */ -struct regulator_dev * -regulator_register(const struct regulator_desc *regulator_desc, - const struct regulator_config *config) +struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, + struct device *dev, const struct regulator_init_data *init_data, + void *driver_data, struct device_node *of_node) { const struct regulation_constraints *constraints = NULL; - const struct regulator_init_data *init_data; static atomic_t regulator_no = ATOMIC_INIT(0); struct regulator_dev *rdev; - struct device *dev; int ret, i; const char *supply = NULL; - if (regulator_desc == NULL || config == NULL) + if (regulator_desc == NULL) return ERR_PTR(-EINVAL); - dev = config->dev; - WARN_ON(!dev); - if (regulator_desc->name == NULL || regulator_desc->ops == NULL) return ERR_PTR(-EINVAL); @@ -3090,8 +2865,6 @@ regulator_register(const struct regulator_desc *regulator_desc, return ERR_PTR(-EINVAL); } - init_data = config->init_data; - rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL); if (rdev == NULL) return ERR_PTR(-ENOMEM); @@ -3099,10 +2872,9 @@ regulator_register(const struct regulator_desc *regulator_desc, mutex_lock(®ulator_list_mutex); mutex_init(&rdev->mutex); - rdev->reg_data = config->driver_data; + rdev->reg_data = driver_data; rdev->owner = regulator_desc->owner; rdev->desc = regulator_desc; - rdev->regmap = config->regmap; INIT_LIST_HEAD(&rdev->consumer_list); INIT_LIST_HEAD(&rdev->list); BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier); @@ -3117,7 +2889,7 @@ regulator_register(const struct regulator_desc *regulator_desc, /* register with sysfs */ rdev->dev.class = ®ulator_class; - rdev->dev.of_node = config->of_node; + rdev->dev.of_node = of_node; rdev->dev.parent = dev; dev_set_name(&rdev->dev, "regulator.%d", atomic_inc_return(®ulator_no) - 1); @@ -3150,7 +2922,7 @@ regulator_register(const struct regulator_desc *regulator_desc, if (supply) { struct regulator_dev *r; - r = regulator_dev_lookup(dev, supply, &ret); + r = regulator_dev_lookup(dev, supply); if (!r) { dev_err(dev, "Failed to find supply %s\n", supply); @@ -3163,7 +2935,8 @@ regulator_register(const struct regulator_desc *regulator_desc, goto scrub; /* Enable supply if rail is enabled */ - if (_regulator_is_enabled(rdev)) { + if (rdev->desc->ops->is_enabled && + rdev->desc->ops->is_enabled(rdev)) { ret = regulator_enable(rdev->supply); if (ret < 0) goto scrub; @@ -3195,8 +2968,6 @@ regulator_register(const struct regulator_desc *regulator_desc, unset_regulator_supplies(rdev); scrub: - if (rdev->supply) - regulator_put(rdev->supply); kfree(rdev->constraints); device_unregister(&rdev->dev); /* device core frees rdev */ @@ -3295,7 +3066,7 @@ int regulator_suspend_finish(void) goto unlock; if (!ops->disable) goto unlock; - if (!_regulator_is_enabled(rdev)) + if (ops->is_enabled && !ops->is_enabled(rdev)) goto unlock; error = ops->disable(rdev); diff --git a/trunk/drivers/regulator/da903x.c b/trunk/drivers/regulator/da903x.c index 1005f5f7e603..1851f0929ef0 100644 --- a/trunk/drivers/regulator/da903x.c +++ b/trunk/drivers/regulator/da903x.c @@ -76,7 +76,9 @@ struct da903x_regulator_info { struct regulator_desc desc; + int min_uV; int max_uV; + int step_uV; int vol_reg; int vol_shift; int vol_nbits; @@ -86,6 +88,10 @@ struct da903x_regulator_info { int enable_bit; }; +static int da9034_ldo12_data[] = { 1700, 1750, 1800, 1850, 1900, 1950, + 2000, 2050, 2700, 2750, 2800, 2850, + 2900, 2950, 3000, 3050 }; + static inline struct device *to_da903x_dev(struct regulator_dev *rdev) { return rdev_get_dev(rdev)->parent->parent; @@ -94,26 +100,34 @@ static inline struct device *to_da903x_dev(struct regulator_dev *rdev) static inline int check_range(struct da903x_regulator_info *info, int min_uV, int max_uV) { - if (min_uV < info->desc.min_uV || min_uV > info->max_uV) + if (min_uV < info->min_uV || min_uV > info->max_uV) return -EINVAL; return 0; } /* DA9030/DA9034 common operations */ -static int da903x_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) +static int da903x_set_ldo_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned *selector) { struct da903x_regulator_info *info = rdev_get_drvdata(rdev); struct device *da9034_dev = to_da903x_dev(rdev); uint8_t val, mask; - val = selector << info->vol_shift; + if (check_range(info, min_uV, max_uV)) { + pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV); + return -EINVAL; + } + + val = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV); + *selector = val; + val <<= info->vol_shift; mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; return da903x_update(da9034_dev, info->vol_reg, val, mask); } -static int da903x_get_voltage_sel(struct regulator_dev *rdev) +static int da903x_get_voltage(struct regulator_dev *rdev) { struct da903x_regulator_info *info = rdev_get_drvdata(rdev); struct device *da9034_dev = to_da903x_dev(rdev); @@ -127,7 +141,7 @@ static int da903x_get_voltage_sel(struct regulator_dev *rdev) mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; val = (val & mask) >> info->vol_shift; - return val; + return info->min_uV + info->step_uV * val; } static int da903x_enable(struct regulator_dev *rdev) @@ -162,16 +176,35 @@ static int da903x_is_enabled(struct regulator_dev *rdev) return !!(reg_val & (1 << info->enable_bit)); } +static int da903x_list_voltage(struct regulator_dev *rdev, unsigned selector) +{ + struct da903x_regulator_info *info = rdev_get_drvdata(rdev); + int ret; + + ret = info->min_uV + info->step_uV * selector; + if (ret > info->max_uV) + return -EINVAL; + return ret; +} + /* DA9030 specific operations */ -static int da9030_set_ldo1_15_voltage_sel(struct regulator_dev *rdev, - unsigned selector) +static int da9030_set_ldo1_15_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, + unsigned *selector) { struct da903x_regulator_info *info = rdev_get_drvdata(rdev); struct device *da903x_dev = to_da903x_dev(rdev); uint8_t val, mask; int ret; - val = selector << info->vol_shift; + if (check_range(info, min_uV, max_uV)) { + pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV); + return -EINVAL; + } + + val = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV); + *selector = val; + val <<= info->vol_shift; mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; val |= DA9030_LDO_UNLOCK; /* have to set UNLOCK bits */ mask |= DA9030_LDO_UNLOCK_MASK; @@ -184,57 +217,73 @@ static int da9030_set_ldo1_15_voltage_sel(struct regulator_dev *rdev, return da903x_update(da903x_dev, info->vol_reg, val, mask); } -static int da9030_map_ldo14_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) +static int da9030_set_ldo14_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, + unsigned *selector) { struct da903x_regulator_info *info = rdev_get_drvdata(rdev); - int thresh, sel; + struct device *da903x_dev = to_da903x_dev(rdev); + uint8_t val, mask; + int thresh; if (check_range(info, min_uV, max_uV)) { pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV); return -EINVAL; } - thresh = (info->max_uV + info->desc.min_uV) / 2; + thresh = (info->max_uV + info->min_uV) / 2; if (min_uV < thresh) { - sel = DIV_ROUND_UP(thresh - min_uV, info->desc.uV_step); - sel |= 0x4; + val = DIV_ROUND_UP(thresh - min_uV, info->step_uV); + val |= 0x4; } else { - sel = DIV_ROUND_UP(min_uV - thresh, info->desc.uV_step); + val = DIV_ROUND_UP(min_uV - thresh, info->step_uV); } - return sel; + *selector = val; + val <<= info->vol_shift; + mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; + + return da903x_update(da903x_dev, info->vol_reg, val, mask); } -static int da9030_list_ldo14_voltage(struct regulator_dev *rdev, - unsigned selector) +static int da9030_get_ldo14_voltage(struct regulator_dev *rdev) { struct da903x_regulator_info *info = rdev_get_drvdata(rdev); - int volt; + struct device *da903x_dev = to_da903x_dev(rdev); + uint8_t val, mask; + int ret; - if (selector & 0x4) - volt = rdev->desc->min_uV + - rdev->desc->uV_step * (3 - (selector & ~0x4)); - else - volt = (info->max_uV + rdev->desc->min_uV) / 2 + - rdev->desc->uV_step * (selector & ~0x4); + ret = da903x_read(da903x_dev, info->vol_reg, &val); + if (ret) + return ret; - if (volt > info->max_uV) - return -EINVAL; + mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; + val = (val & mask) >> info->vol_shift; - return volt; + if (val & 0x4) + return info->min_uV + info->step_uV * (3 - (val & ~0x4)); + else + return (info->max_uV + info->min_uV) / 2 + + info->step_uV * (val & ~0x4); } /* DA9034 specific operations */ -static int da9034_set_dvc_voltage_sel(struct regulator_dev *rdev, - unsigned selector) +static int da9034_set_dvc_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned *selector) { struct da903x_regulator_info *info = rdev_get_drvdata(rdev); struct device *da9034_dev = to_da903x_dev(rdev); uint8_t val, mask; int ret; - val = selector << info->vol_shift; + if (check_range(info, min_uV, max_uV)) { + pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV); + return -EINVAL; + } + + val = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV); + *selector = val; + val <<= info->vol_shift; mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; ret = da903x_update(da9034_dev, info->vol_reg, val, mask); @@ -246,45 +295,59 @@ static int da9034_set_dvc_voltage_sel(struct regulator_dev *rdev, return ret; } -static int da9034_map_ldo12_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) +static int da9034_set_ldo12_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned *selector) { struct da903x_regulator_info *info = rdev_get_drvdata(rdev); - int sel; + struct device *da9034_dev = to_da903x_dev(rdev); + uint8_t val, mask; if (check_range(info, min_uV, max_uV)) { pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV); return -EINVAL; } - sel = DIV_ROUND_UP(min_uV - info->desc.min_uV, info->desc.uV_step); - sel = (sel >= 20) ? sel - 12 : ((sel > 7) ? 8 : sel); + val = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV); + val = (val >= 20) ? val - 12 : ((val > 7) ? 8 : val); + *selector = val; + val <<= info->vol_shift; + mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; - return sel; + return da903x_update(da9034_dev, info->vol_reg, val, mask); } -static int da9034_list_ldo12_voltage(struct regulator_dev *rdev, - unsigned selector) +static int da9034_get_ldo12_voltage(struct regulator_dev *rdev) { struct da903x_regulator_info *info = rdev_get_drvdata(rdev); - int volt; + struct device *da9034_dev = to_da903x_dev(rdev); + uint8_t val, mask; + int ret; - if (selector >= 8) - volt = 2700000 + rdev->desc->uV_step * (selector - 8); - else - volt = rdev->desc->min_uV + rdev->desc->uV_step * selector; + ret = da903x_read(da9034_dev, info->vol_reg, &val); + if (ret) + return ret; - if (volt > info->max_uV) - return -EINVAL; + mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; + val = (val & mask) >> info->vol_shift; - return volt; + if (val >= 8) + return 2700000 + info->step_uV * (val - 8); + + return info->min_uV + info->step_uV * val; +} + +static int da9034_list_ldo12_voltage(struct regulator_dev *rdev, + unsigned selector) +{ + if (selector >= ARRAY_SIZE(da9034_ldo12_data)) + return -EINVAL; + return da9034_ldo12_data[selector] * 1000; } static struct regulator_ops da903x_regulator_ldo_ops = { - .set_voltage_sel = da903x_set_voltage_sel, - .get_voltage_sel = da903x_get_voltage_sel, - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, + .set_voltage = da903x_set_ldo_voltage, + .get_voltage = da903x_get_voltage, + .list_voltage = da903x_list_voltage, .enable = da903x_enable, .disable = da903x_disable, .is_enabled = da903x_is_enabled, @@ -292,10 +355,9 @@ static struct regulator_ops da903x_regulator_ldo_ops = { /* NOTE: this is dedicated for the insane DA9030 LDO14 */ static struct regulator_ops da9030_regulator_ldo14_ops = { - .set_voltage_sel = da903x_set_voltage_sel, - .get_voltage_sel = da903x_get_voltage_sel, - .list_voltage = da9030_list_ldo14_voltage, - .map_voltage = da9030_map_ldo14_voltage, + .set_voltage = da9030_set_ldo14_voltage, + .get_voltage = da9030_get_ldo14_voltage, + .list_voltage = da903x_list_voltage, .enable = da903x_enable, .disable = da903x_disable, .is_enabled = da903x_is_enabled, @@ -303,20 +365,18 @@ static struct regulator_ops da9030_regulator_ldo14_ops = { /* NOTE: this is dedicated for the DA9030 LDO1 and LDO15 that have locks */ static struct regulator_ops da9030_regulator_ldo1_15_ops = { - .set_voltage_sel = da9030_set_ldo1_15_voltage_sel, - .get_voltage_sel = da903x_get_voltage_sel, - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, + .set_voltage = da9030_set_ldo1_15_voltage, + .get_voltage = da903x_get_voltage, + .list_voltage = da903x_list_voltage, .enable = da903x_enable, .disable = da903x_disable, .is_enabled = da903x_is_enabled, }; static struct regulator_ops da9034_regulator_dvc_ops = { - .set_voltage_sel = da9034_set_dvc_voltage_sel, - .get_voltage_sel = da903x_get_voltage_sel, - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, + .set_voltage = da9034_set_dvc_voltage, + .get_voltage = da903x_get_voltage, + .list_voltage = da903x_list_voltage, .enable = da903x_enable, .disable = da903x_disable, .is_enabled = da903x_is_enabled, @@ -324,10 +384,9 @@ static struct regulator_ops da9034_regulator_dvc_ops = { /* NOTE: this is dedicated for the insane LDO12 */ static struct regulator_ops da9034_regulator_ldo12_ops = { - .set_voltage_sel = da903x_set_voltage_sel, - .get_voltage_sel = da903x_get_voltage_sel, + .set_voltage = da9034_set_ldo12_voltage, + .get_voltage = da9034_get_ldo12_voltage, .list_voltage = da9034_list_ldo12_voltage, - .map_voltage = da9034_map_ldo12_voltage, .enable = da903x_enable, .disable = da903x_disable, .is_enabled = da903x_is_enabled, @@ -342,10 +401,10 @@ static struct regulator_ops da9034_regulator_ldo12_ops = { .id = _pmic##_ID_LDO##_id, \ .n_voltages = (step) ? ((max - min) / step + 1) : 1, \ .owner = THIS_MODULE, \ - .min_uV = (min) * 1000, \ - .uV_step = (step) * 1000, \ }, \ + .min_uV = (min) * 1000, \ .max_uV = (max) * 1000, \ + .step_uV = (step) * 1000, \ .vol_reg = _pmic##_##vreg, \ .vol_shift = (shift), \ .vol_nbits = (nbits), \ @@ -362,10 +421,10 @@ static struct regulator_ops da9034_regulator_ldo12_ops = { .id = _pmic##_ID_##_id, \ .n_voltages = (step) ? ((max - min) / step + 1) : 1, \ .owner = THIS_MODULE, \ - .min_uV = (min) * 1000, \ - .uV_step = (step) * 1000, \ }, \ + .min_uV = (min) * 1000, \ .max_uV = (max) * 1000, \ + .step_uV = (step) * 1000, \ .vol_reg = _pmic##_##vreg, \ .vol_shift = (0), \ .vol_nbits = (nbits), \ @@ -458,7 +517,6 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev) { struct da903x_regulator_info *ri = NULL; struct regulator_dev *rdev; - struct regulator_config config = { }; ri = find_regulator_info(pdev->id); if (ri == NULL) { @@ -469,7 +527,7 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev) /* Workaround for the weird LDO12 voltage setting */ if (ri->desc.id == DA9034_ID_LDO12) { ri->desc.ops = &da9034_regulator_ldo12_ops; - ri->desc.n_voltages = 16; + ri->desc.n_voltages = ARRAY_SIZE(da9034_ldo12_data); } if (ri->desc.id == DA9030_ID_LDO14) @@ -478,11 +536,8 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev) if (ri->desc.id == DA9030_ID_LDO1 || ri->desc.id == DA9030_ID_LDO15) ri->desc.ops = &da9030_regulator_ldo1_15_ops; - config.dev = &pdev->dev; - config.init_data = pdev->dev.platform_data; - config.driver_data = ri; - - rdev = regulator_register(&ri->desc, &config); + rdev = regulator_register(&ri->desc, &pdev->dev, + pdev->dev.platform_data, ri, NULL); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register regulator %s\n", ri->desc.name); diff --git a/trunk/drivers/regulator/da9052-regulator.c b/trunk/drivers/regulator/da9052-regulator.c index 88976d8d44ed..09915e89705d 100644 --- a/trunk/drivers/regulator/da9052-regulator.c +++ b/trunk/drivers/regulator/da9052-regulator.c @@ -19,10 +19,6 @@ #include #include #include -#ifdef CONFIG_OF -#include -#include -#endif #include #include @@ -41,22 +37,6 @@ #define DA9052_BUCK_ILIM_MASK_EVEN 0x0c #define DA9052_BUCK_ILIM_MASK_ODD 0xc0 -/* DA9052 REGULATOR IDs */ -#define DA9052_ID_BUCK1 0 -#define DA9052_ID_BUCK2 1 -#define DA9052_ID_BUCK3 2 -#define DA9052_ID_BUCK4 3 -#define DA9052_ID_LDO1 4 -#define DA9052_ID_LDO2 5 -#define DA9052_ID_LDO3 6 -#define DA9052_ID_LDO4 7 -#define DA9052_ID_LDO5 8 -#define DA9052_ID_LDO6 9 -#define DA9052_ID_LDO7 10 -#define DA9052_ID_LDO8 11 -#define DA9052_ID_LDO9 12 -#define DA9052_ID_LDO10 13 - static const u32 da9052_current_limits[3][4] = { {700000, 800000, 1000000, 1200000}, /* DA9052-BC BUCKs */ {1600000, 2000000, 2400000, 3000000}, /* DA9053-AA/Bx BUCK-CORE */ @@ -70,6 +50,8 @@ struct da9052_regulator_info { int step_uV; int min_uV; int max_uV; + unsigned char volt_shift; + unsigned char en_bit; unsigned char activate_bit; }; @@ -88,6 +70,42 @@ static int verify_range(struct da9052_regulator_info *info, return 0; } +static int da9052_regulator_enable(struct regulator_dev *rdev) +{ + struct da9052_regulator *regulator = rdev_get_drvdata(rdev); + struct da9052_regulator_info *info = regulator->info; + int offset = rdev_get_id(rdev); + + return da9052_reg_update(regulator->da9052, + DA9052_BUCKCORE_REG + offset, + 1 << info->en_bit, 1 << info->en_bit); +} + +static int da9052_regulator_disable(struct regulator_dev *rdev) +{ + struct da9052_regulator *regulator = rdev_get_drvdata(rdev); + struct da9052_regulator_info *info = regulator->info; + int offset = rdev_get_id(rdev); + + return da9052_reg_update(regulator->da9052, + DA9052_BUCKCORE_REG + offset, + 1 << info->en_bit, 0); +} + +static int da9052_regulator_is_enabled(struct regulator_dev *rdev) +{ + struct da9052_regulator *regulator = rdev_get_drvdata(rdev); + struct da9052_regulator_info *info = regulator->info; + int offset = rdev_get_id(rdev); + int ret; + + ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset); + if (ret < 0) + return ret; + + return ret & (1 << info->en_bit); +} + static int da9052_dcdc_get_current_limit(struct regulator_dev *rdev) { struct da9052_regulator *regulator = rdev_get_drvdata(rdev); @@ -155,23 +173,21 @@ static int da9052_dcdc_set_current_limit(struct regulator_dev *rdev, int min_uA, reg_val << 6); } -static int da9052_list_voltage(struct regulator_dev *rdev, - unsigned int selector) +static int da9052_list_buckperi_voltage(struct regulator_dev *rdev, + unsigned int selector) { struct da9052_regulator *regulator = rdev_get_drvdata(rdev); struct da9052_regulator_info *info = regulator->info; - int id = rdev_get_id(rdev); int volt_uV; - if ((id == DA9052_ID_BUCK4) && (regulator->da9052->chip_id == DA9052) - && (selector >= DA9052_BUCK_PERI_REG_MAP_UPTO_3uV)) { + if ((regulator->da9052->chip_id == DA9052) && + (selector >= DA9052_BUCK_PERI_REG_MAP_UPTO_3uV)) { volt_uV = ((DA9052_BUCK_PERI_REG_MAP_UPTO_3uV * info->step_uV) - + info->min_uV); + + info->min_uV); volt_uV += (selector - DA9052_BUCK_PERI_REG_MAP_UPTO_3uV) - * (DA9052_BUCK_PERI_3uV_STEP); - } else { - volt_uV = (selector * info->step_uV) + info->min_uV; - } + * (DA9052_BUCK_PERI_3uV_STEP); + } else + volt_uV = (selector * info->step_uV) + info->min_uV; if (volt_uV > info->max_uV) return -EINVAL; @@ -179,13 +195,29 @@ static int da9052_list_voltage(struct regulator_dev *rdev, return volt_uV; } -static int da9052_map_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) +static int da9052_list_voltage(struct regulator_dev *rdev, + unsigned int selector) { struct da9052_regulator *regulator = rdev_get_drvdata(rdev); struct da9052_regulator_info *info = regulator->info; - int id = rdev_get_id(rdev); - int ret, sel; + int volt_uV; + + volt_uV = info->min_uV + info->step_uV * selector; + + if (volt_uV > info->max_uV) + return -EINVAL; + + return volt_uV; +} + +static int da9052_regulator_set_voltage_int(struct regulator_dev *rdev, + int min_uV, int max_uV, + unsigned int *selector) +{ + struct da9052_regulator *regulator = rdev_get_drvdata(rdev); + struct da9052_regulator_info *info = regulator->info; + int offset = rdev_get_id(rdev); + int ret; ret = verify_range(info, min_uV, max_uV); if (ret < 0) @@ -194,147 +226,281 @@ static int da9052_map_voltage(struct regulator_dev *rdev, if (min_uV < info->min_uV) min_uV = info->min_uV; - if ((id == DA9052_ID_BUCK4) && (regulator->da9052->chip_id == DA9052) - && (min_uV >= DA9052_CONST_3uV)) { - sel = DA9052_BUCK_PERI_REG_MAP_UPTO_3uV + - DIV_ROUND_UP(min_uV - DA9052_CONST_3uV, - DA9052_BUCK_PERI_3uV_STEP); - } else { - sel = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV); - } + *selector = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV); - ret = da9052_list_voltage(rdev, sel); + ret = da9052_list_voltage(rdev, *selector); if (ret < 0) return ret; - return sel; + return da9052_reg_update(regulator->da9052, + DA9052_BUCKCORE_REG + offset, + (1 << info->volt_shift) - 1, *selector); } -static int da9052_regulator_set_voltage_sel(struct regulator_dev *rdev, - unsigned int selector) +static int da9052_set_ldo_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, + unsigned int *selector) +{ + return da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector); +} + +static int da9052_set_ldo5_6_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, + unsigned int *selector) { struct da9052_regulator *regulator = rdev_get_drvdata(rdev); struct da9052_regulator_info *info = regulator->info; - int id = rdev_get_id(rdev); int ret; - ret = da9052_reg_update(regulator->da9052, rdev->desc->vsel_reg, - rdev->desc->vsel_mask, selector); + ret = da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector); if (ret < 0) return ret; - /* Some LDOs and DCDCs are DVC controlled which requires enabling of - * the activate bit to implment the changes on the output. - */ - switch (id) { - case DA9052_ID_BUCK1: - case DA9052_ID_BUCK2: - case DA9052_ID_BUCK3: - case DA9052_ID_LDO2: - case DA9052_ID_LDO3: - ret = da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG, - info->activate_bit, info->activate_bit); - break; - } + /* Some LDOs are DVC controlled which requires enabling of + * the LDO activate bit to implment the changes on the + * LDO output. + */ + return da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG, + info->activate_bit, info->activate_bit); +} + +static int da9052_set_dcdc_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, + unsigned int *selector) +{ + struct da9052_regulator *regulator = rdev_get_drvdata(rdev); + struct da9052_regulator_info *info = regulator->info; + int ret; + + ret = da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector); + if (ret < 0) + return ret; + + /* Some DCDCs are DVC controlled which requires enabling of + * the DCDC activate bit to implment the changes on the + * DCDC output. + */ + return da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG, + info->activate_bit, info->activate_bit); +} + +static int da9052_get_regulator_voltage_sel(struct regulator_dev *rdev) +{ + struct da9052_regulator *regulator = rdev_get_drvdata(rdev); + struct da9052_regulator_info *info = regulator->info; + int offset = rdev_get_id(rdev); + int ret; + + ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset); + if (ret < 0) + return ret; + + ret &= ((1 << info->volt_shift) - 1); + + return ret; +} + +static int da9052_set_buckperi_voltage(struct regulator_dev *rdev, int min_uV, + int max_uV, unsigned int *selector) +{ + struct da9052_regulator *regulator = rdev_get_drvdata(rdev); + struct da9052_regulator_info *info = regulator->info; + int offset = rdev_get_id(rdev); + int ret; + + ret = verify_range(info, min_uV, max_uV); + if (ret < 0) + return ret; + + if (min_uV < info->min_uV) + min_uV = info->min_uV; + + if ((regulator->da9052->chip_id == DA9052) && + (min_uV >= DA9052_CONST_3uV)) + *selector = DA9052_BUCK_PERI_REG_MAP_UPTO_3uV + + DIV_ROUND_UP(min_uV - DA9052_CONST_3uV, + DA9052_BUCK_PERI_3uV_STEP); + else + *selector = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV); + + ret = da9052_list_buckperi_voltage(rdev, *selector); + if (ret < 0) + return ret; + + return da9052_reg_update(regulator->da9052, + DA9052_BUCKCORE_REG + offset, + (1 << info->volt_shift) - 1, *selector); +} + +static int da9052_get_buckperi_voltage_sel(struct regulator_dev *rdev) +{ + struct da9052_regulator *regulator = rdev_get_drvdata(rdev); + struct da9052_regulator_info *info = regulator->info; + int offset = rdev_get_id(rdev); + int ret; + + ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset); + if (ret < 0) + return ret; + + ret &= ((1 << info->volt_shift) - 1); return ret; } +static struct regulator_ops da9052_buckperi_ops = { + .list_voltage = da9052_list_buckperi_voltage, + .get_voltage_sel = da9052_get_buckperi_voltage_sel, + .set_voltage = da9052_set_buckperi_voltage, + + .get_current_limit = da9052_dcdc_get_current_limit, + .set_current_limit = da9052_dcdc_set_current_limit, + + .is_enabled = da9052_regulator_is_enabled, + .enable = da9052_regulator_enable, + .disable = da9052_regulator_disable, +}; + static struct regulator_ops da9052_dcdc_ops = { + .set_voltage = da9052_set_dcdc_voltage, .get_current_limit = da9052_dcdc_get_current_limit, .set_current_limit = da9052_dcdc_set_current_limit, .list_voltage = da9052_list_voltage, - .map_voltage = da9052_map_voltage, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_sel = da9052_regulator_set_voltage_sel, - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, + .get_voltage_sel = da9052_get_regulator_voltage_sel, + .is_enabled = da9052_regulator_is_enabled, + .enable = da9052_regulator_enable, + .disable = da9052_regulator_disable, +}; + +static struct regulator_ops da9052_ldo5_6_ops = { + .set_voltage = da9052_set_ldo5_6_voltage, + + .list_voltage = da9052_list_voltage, + .get_voltage_sel = da9052_get_regulator_voltage_sel, + .is_enabled = da9052_regulator_is_enabled, + .enable = da9052_regulator_enable, + .disable = da9052_regulator_disable, }; static struct regulator_ops da9052_ldo_ops = { + .set_voltage = da9052_set_ldo_voltage, + .list_voltage = da9052_list_voltage, - .map_voltage = da9052_map_voltage, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_sel = da9052_regulator_set_voltage_sel, - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, + .get_voltage_sel = da9052_get_regulator_voltage_sel, + .is_enabled = da9052_regulator_is_enabled, + .enable = da9052_regulator_enable, + .disable = da9052_regulator_disable, }; +#define DA9052_LDO5_6(_id, step, min, max, sbits, ebits, abits) \ +{\ + .reg_desc = {\ + .name = "LDO" #_id,\ + .ops = &da9052_ldo5_6_ops,\ + .type = REGULATOR_VOLTAGE,\ + .id = _id,\ + .n_voltages = (max - min) / step + 1, \ + .owner = THIS_MODULE,\ + },\ + .min_uV = (min) * 1000,\ + .max_uV = (max) * 1000,\ + .step_uV = (step) * 1000,\ + .volt_shift = (sbits),\ + .en_bit = (ebits),\ + .activate_bit = (abits),\ +} + #define DA9052_LDO(_id, step, min, max, sbits, ebits, abits) \ {\ .reg_desc = {\ - .name = #_id,\ + .name = "LDO" #_id,\ .ops = &da9052_ldo_ops,\ .type = REGULATOR_VOLTAGE,\ - .id = DA9052_ID_##_id,\ + .id = _id,\ .n_voltages = (max - min) / step + 1, \ .owner = THIS_MODULE,\ - .vsel_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \ - .vsel_mask = (1 << (sbits)) - 1,\ - .enable_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \ - .enable_mask = 1 << (ebits),\ },\ .min_uV = (min) * 1000,\ .max_uV = (max) * 1000,\ .step_uV = (step) * 1000,\ + .volt_shift = (sbits),\ + .en_bit = (ebits),\ .activate_bit = (abits),\ } #define DA9052_DCDC(_id, step, min, max, sbits, ebits, abits) \ {\ .reg_desc = {\ - .name = #_id,\ + .name = "BUCK" #_id,\ .ops = &da9052_dcdc_ops,\ .type = REGULATOR_VOLTAGE,\ - .id = DA9052_ID_##_id,\ + .id = _id,\ .n_voltages = (max - min) / step + 1, \ .owner = THIS_MODULE,\ - .vsel_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \ - .vsel_mask = (1 << (sbits)) - 1,\ - .enable_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \ - .enable_mask = 1 << (ebits),\ },\ .min_uV = (min) * 1000,\ .max_uV = (max) * 1000,\ .step_uV = (step) * 1000,\ + .volt_shift = (sbits),\ + .en_bit = (ebits),\ + .activate_bit = (abits),\ +} + +#define DA9052_BUCKPERI(_id, step, min, max, sbits, ebits, abits) \ +{\ + .reg_desc = {\ + .name = "BUCK" #_id,\ + .ops = &da9052_buckperi_ops,\ + .type = REGULATOR_VOLTAGE,\ + .id = _id,\ + .n_voltages = (max - min) / step + 1, \ + .owner = THIS_MODULE,\ + },\ + .min_uV = (min) * 1000,\ + .max_uV = (max) * 1000,\ + .step_uV = (step) * 1000,\ + .volt_shift = (sbits),\ + .en_bit = (ebits),\ .activate_bit = (abits),\ } static struct da9052_regulator_info da9052_regulator_info[] = { - DA9052_DCDC(BUCK1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO), - DA9052_DCDC(BUCK2, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO), - DA9052_DCDC(BUCK3, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO), - DA9052_DCDC(BUCK4, 50, 1800, 3600, 5, 6, 0), - DA9052_LDO(LDO1, 50, 600, 1800, 5, 6, 0), - DA9052_LDO(LDO2, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO), - DA9052_LDO(LDO3, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO), - DA9052_LDO(LDO4, 25, 1725, 3300, 6, 6, 0), - DA9052_LDO(LDO5, 50, 1200, 3600, 6, 6, 0), - DA9052_LDO(LDO6, 50, 1200, 3600, 6, 6, 0), - DA9052_LDO(LDO7, 50, 1200, 3600, 6, 6, 0), - DA9052_LDO(LDO8, 50, 1200, 3600, 6, 6, 0), - DA9052_LDO(LDO9, 50, 1250, 3650, 6, 6, 0), - DA9052_LDO(LDO10, 50, 1200, 3600, 6, 6, 0), + /* Buck1 - 4 */ + DA9052_DCDC(0, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO), + DA9052_DCDC(1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO), + DA9052_DCDC(2, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO), + DA9052_BUCKPERI(3, 50, 1800, 3600, 5, 6, 0), + /* LD01 - LDO10 */ + DA9052_LDO(4, 50, 600, 1800, 5, 6, 0), + DA9052_LDO5_6(5, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO), + DA9052_LDO5_6(6, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO), + DA9052_LDO(7, 25, 1725, 3300, 6, 6, 0), + DA9052_LDO(8, 50, 1200, 3600, 6, 6, 0), + DA9052_LDO(9, 50, 1200, 3600, 6, 6, 0), + DA9052_LDO(10, 50, 1200, 3600, 6, 6, 0), + DA9052_LDO(11, 50, 1200, 3600, 6, 6, 0), + DA9052_LDO(12, 50, 1250, 3650, 6, 6, 0), + DA9052_LDO(13, 50, 1200, 3600, 6, 6, 0), }; static struct da9052_regulator_info da9053_regulator_info[] = { - DA9052_DCDC(BUCK1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO), - DA9052_DCDC(BUCK2, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO), - DA9052_DCDC(BUCK3, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO), - DA9052_DCDC(BUCK4, 25, 925, 2500, 6, 6, 0), - DA9052_LDO(LDO1, 50, 600, 1800, 5, 6, 0), - DA9052_LDO(LDO2, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO), - DA9052_LDO(LDO3, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO), - DA9052_LDO(LDO4, 25, 1725, 3300, 6, 6, 0), - DA9052_LDO(LDO5, 50, 1200, 3600, 6, 6, 0), - DA9052_LDO(LDO6, 50, 1200, 3600, 6, 6, 0), - DA9052_LDO(LDO7, 50, 1200, 3600, 6, 6, 0), - DA9052_LDO(LDO8, 50, 1200, 3600, 6, 6, 0), - DA9052_LDO(LDO9, 50, 1250, 3650, 6, 6, 0), - DA9052_LDO(LDO10, 50, 1200, 3600, 6, 6, 0), + /* Buck1 - 4 */ + DA9052_DCDC(0, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO), + DA9052_DCDC(1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO), + DA9052_DCDC(2, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO), + DA9052_BUCKPERI(3, 25, 925, 2500, 6, 6, 0), + /* LD01 - LDO10 */ + DA9052_LDO(4, 50, 600, 1800, 5, 6, 0), + DA9052_LDO5_6(5, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO), + DA9052_LDO5_6(6, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO), + DA9052_LDO(7, 25, 1725, 3300, 6, 6, 0), + DA9052_LDO(8, 50, 1200, 3600, 6, 6, 0), + DA9052_LDO(9, 50, 1200, 3600, 6, 6, 0), + DA9052_LDO(10, 50, 1200, 3600, 6, 6, 0), + DA9052_LDO(11, 50, 1200, 3600, 6, 6, 0), + DA9052_LDO(12, 50, 1250, 3650, 6, 6, 0), + DA9052_LDO(13, 50, 1200, 3600, 6, 6, 0), }; static inline struct da9052_regulator_info *find_regulator_info(u8 chip_id, @@ -367,10 +533,10 @@ static inline struct da9052_regulator_info *find_regulator_info(u8 chip_id, static int __devinit da9052_regulator_probe(struct platform_device *pdev) { - struct regulator_config config = { }; struct da9052_regulator *regulator; struct da9052 *da9052; struct da9052_pdata *pdata; + int ret; regulator = devm_kzalloc(&pdev->dev, sizeof(struct da9052_regulator), GFP_KERNEL); @@ -385,49 +551,26 @@ static int __devinit da9052_regulator_probe(struct platform_device *pdev) pdev->id); if (regulator->info == NULL) { dev_err(&pdev->dev, "invalid regulator ID specified\n"); - return -EINVAL; + ret = -EINVAL; + goto err; } - - config.dev = &pdev->dev; - config.driver_data = regulator; - config.regmap = da9052->regmap; - if (pdata && pdata->regulators) { - config.init_data = pdata->regulators[pdev->id]; - } else { -#ifdef CONFIG_OF - struct device_node *nproot = da9052->dev->of_node; - struct device_node *np; - - if (!nproot) - return -ENODEV; - - nproot = of_find_node_by_name(nproot, "regulators"); - if (!nproot) - return -ENODEV; - - for (np = of_get_next_child(nproot, NULL); np; - np = of_get_next_child(nproot, np)) { - if (!of_node_cmp(np->name, - regulator->info->reg_desc.name)) { - config.init_data = of_get_regulator_init_data( - &pdev->dev, np); - break; - } - } -#endif - } - regulator->rdev = regulator_register(®ulator->info->reg_desc, - &config); + &pdev->dev, + pdata->regulators[pdev->id], + regulator, NULL); if (IS_ERR(regulator->rdev)) { dev_err(&pdev->dev, "failed to register regulator %s\n", regulator->info->reg_desc.name); - return PTR_ERR(regulator->rdev); + ret = PTR_ERR(regulator->rdev); + goto err; } platform_set_drvdata(pdev, regulator); return 0; +err: + devm_kfree(&pdev->dev, regulator); + return ret; } static int __devexit da9052_regulator_remove(struct platform_device *pdev) @@ -435,6 +578,8 @@ static int __devexit da9052_regulator_remove(struct platform_device *pdev) struct da9052_regulator *regulator = platform_get_drvdata(pdev); regulator_unregister(regulator->rdev); + devm_kfree(&pdev->dev, regulator); + return 0; } diff --git a/trunk/drivers/regulator/db8500-prcmu.c b/trunk/drivers/regulator/db8500-prcmu.c index 968f97f3cb3d..4bd25e75efa0 100644 --- a/trunk/drivers/regulator/db8500-prcmu.c +++ b/trunk/drivers/regulator/db8500-prcmu.c @@ -17,8 +17,6 @@ #include #include #include -#include -#include #include #include "dbx500-prcmu.h" @@ -412,120 +410,45 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { }, }; -static __devinit int db8500_regulator_register(struct platform_device *pdev, - struct regulator_init_data *init_data, - int id, - struct device_node *np) -{ - struct dbx500_regulator_info *info; - struct regulator_config config = { }; - int err; - - /* assign per-regulator data */ - info = &dbx500_regulator_info[id]; - info->dev = &pdev->dev; - - config.dev = &pdev->dev; - config.init_data = init_data; - config.driver_data = info; - config.of_node = np; - - /* register with the regulator framework */ - info->rdev = regulator_register(&info->desc, &config); - if (IS_ERR(info->rdev)) { - err = PTR_ERR(info->rdev); - dev_err(&pdev->dev, "failed to register %s: err %i\n", - info->desc.name, err); - - /* if failing, unregister all earlier regulators */ - while (--id >= 0) { - info = &dbx500_regulator_info[id]; - regulator_unregister(info->rdev); - } - return err; - } - - dev_dbg(rdev_get_dev(info->rdev), - "regulator-%s-probed\n", info->desc.name); - - return 0; -} - -static struct of_regulator_match db8500_regulator_matches[] = { - { .name = "db8500-vape", .driver_data = (void *) DB8500_REGULATOR_VAPE, }, - { .name = "db8500-varm", .driver_data = (void *) DB8500_REGULATOR_VARM, }, - { .name = "db8500-vmodem", .driver_data = (void *) DB8500_REGULATOR_VMODEM, }, - { .name = "db8500-vpll", .driver_data = (void *) DB8500_REGULATOR_VPLL, }, - { .name = "db8500-vsmps1", .driver_data = (void *) DB8500_REGULATOR_VSMPS1, }, - { .name = "db8500-vsmps2", .driver_data = (void *) DB8500_REGULATOR_VSMPS2, }, - { .name = "db8500-vsmps3", .driver_data = (void *) DB8500_REGULATOR_VSMPS3, }, - { .name = "db8500-vrf1", .driver_data = (void *) DB8500_REGULATOR_VRF1, }, - { .name = "db8500-sva-mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSP, }, - { .name = "db8500-sva-mmdsp-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSPRET, }, - { .name = "db8500-sva-pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAPIPE, }, - { .name = "db8500-sia-mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSP, }, - { .name = "db8500-sia-mmdsp-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSPRET, }, - { .name = "db8500-sia-pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAPIPE, }, - { .name = "db8500-sga", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SGA, }, - { .name = "db8500-b2r2-mcde", .driver_data = (void *) DB8500_REGULATOR_SWITCH_B2R2_MCDE, }, - { .name = "db8500-esram12", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12, }, - { .name = "db8500-esram12-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12RET, }, - { .name = "db8500-esram34", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34, }, - { .name = "db8500-esram34-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, }, -}; - -static __devinit int -db8500_regulator_of_probe(struct platform_device *pdev, - struct device_node *np) -{ - int i, err; - - for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { - err = db8500_regulator_register( - pdev, db8500_regulator_matches[i].init_data, - i, db8500_regulator_matches[i].of_node); - if (err) - return err; - } - - return 0; -} - static int __devinit db8500_regulator_probe(struct platform_device *pdev) { struct regulator_init_data *db8500_init_data = dev_get_platdata(&pdev->dev); - struct device_node *np = pdev->dev.of_node; int i, err; /* register all regulators */ - if (np) { - err = of_regulator_match(&pdev->dev, np, - db8500_regulator_matches, - ARRAY_SIZE(db8500_regulator_matches)); - if (err < 0) { - dev_err(&pdev->dev, - "Error parsing regulator init data: %d\n", err); - return err; - } + for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { + struct dbx500_regulator_info *info; + struct regulator_init_data *init_data = &db8500_init_data[i]; - err = db8500_regulator_of_probe(pdev, np); - if (err) + /* assign per-regulator data */ + info = &dbx500_regulator_info[i]; + info->dev = &pdev->dev; + + /* register with the regulator framework */ + info->rdev = regulator_register(&info->desc, &pdev->dev, + init_data, info, NULL); + if (IS_ERR(info->rdev)) { + err = PTR_ERR(info->rdev); + dev_err(&pdev->dev, "failed to register %s: err %i\n", + info->desc.name, err); + + /* if failing, unregister all earlier regulators */ + while (--i >= 0) { + info = &dbx500_regulator_info[i]; + regulator_unregister(info->rdev); + } return err; - } else { - for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { - err = db8500_regulator_register(pdev, - &db8500_init_data[i], - i, NULL); - if (err) - return err; } - } + dev_dbg(rdev_get_dev(info->rdev), + "regulator-%s-probed\n", info->desc.name); + } err = ux500_regulator_debug_init(pdev, dbx500_regulator_info, ARRAY_SIZE(dbx500_regulator_info)); - return 0; + + return err; } static int __exit db8500_regulator_remove(struct platform_device *pdev) @@ -547,16 +470,10 @@ static int __exit db8500_regulator_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id db8500_prcmu_regulator_match[] = { - { .compatible = "stericsson,db8500-prcmu-regulator", }, - {} -}; - static struct platform_driver db8500_regulator_driver = { .driver = { .name = "db8500-prcmu-regulators", .owner = THIS_MODULE, - .of_match_table = db8500_prcmu_regulator_match, }, .probe = db8500_regulator_probe, .remove = __exit_p(db8500_regulator_remove), diff --git a/trunk/drivers/regulator/dummy.c b/trunk/drivers/regulator/dummy.c index 86f655c7f7a1..0ee00de4be72 100644 --- a/trunk/drivers/regulator/dummy.c +++ b/trunk/drivers/regulator/dummy.c @@ -39,13 +39,10 @@ static struct regulator_desc dummy_desc = { static int __devinit dummy_regulator_probe(struct platform_device *pdev) { - struct regulator_config config = { }; int ret; - config.dev = &pdev->dev; - config.init_data = &dummy_initdata; - - dummy_regulator_rdev = regulator_register(&dummy_desc, &config); + dummy_regulator_rdev = regulator_register(&dummy_desc, NULL, + &dummy_initdata, NULL, NULL); if (IS_ERR(dummy_regulator_rdev)) { ret = PTR_ERR(dummy_regulator_rdev); pr_err("Failed to register regulator: %d\n", ret); diff --git a/trunk/drivers/regulator/fixed.c b/trunk/drivers/regulator/fixed.c index f09fe7b20e82..40f38030b394 100644 --- a/trunk/drivers/regulator/fixed.c +++ b/trunk/drivers/regulator/fixed.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -90,9 +91,6 @@ of_get_fixed_voltage_config(struct device *dev) if (of_find_property(np, "enable-active-high", NULL)) config->enable_high = true; - if (of_find_property(np, "gpio-open-drain", NULL)) - config->gpio_is_open_drain = true; - return config; } @@ -107,8 +105,10 @@ static int fixed_voltage_enable(struct regulator_dev *dev) { struct fixed_voltage_data *data = rdev_get_drvdata(dev); - gpio_set_value_cansleep(data->gpio, data->enable_high); - data->is_enabled = true; + if (gpio_is_valid(data->gpio)) { + gpio_set_value_cansleep(data->gpio, data->enable_high); + data->is_enabled = true; + } return 0; } @@ -117,8 +117,10 @@ static int fixed_voltage_disable(struct regulator_dev *dev) { struct fixed_voltage_data *data = rdev_get_drvdata(dev); - gpio_set_value_cansleep(data->gpio, !data->enable_high); - data->is_enabled = false; + if (gpio_is_valid(data->gpio)) { + gpio_set_value_cansleep(data->gpio, !data->enable_high); + data->is_enabled = false; + } return 0; } @@ -151,7 +153,7 @@ static int fixed_voltage_list_voltage(struct regulator_dev *dev, return data->microvolts; } -static struct regulator_ops fixed_voltage_gpio_ops = { +static struct regulator_ops fixed_voltage_ops = { .is_enabled = fixed_voltage_is_enabled, .enable = fixed_voltage_enable, .disable = fixed_voltage_disable, @@ -160,16 +162,10 @@ static struct regulator_ops fixed_voltage_gpio_ops = { .list_voltage = fixed_voltage_list_voltage, }; -static struct regulator_ops fixed_voltage_ops = { - .get_voltage = fixed_voltage_get_voltage, - .list_voltage = fixed_voltage_list_voltage, -}; - static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev) { struct fixed_voltage_config *config; struct fixed_voltage_data *drvdata; - struct regulator_config cfg = { }; int ret; if (pdev->dev.of_node) @@ -180,8 +176,7 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev) if (!config) return -ENOMEM; - drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data), - GFP_KERNEL); + drvdata = kzalloc(sizeof(struct fixed_voltage_data), GFP_KERNEL); if (drvdata == NULL) { dev_err(&pdev->dev, "Failed to allocate device data\n"); ret = -ENOMEM; @@ -196,6 +191,7 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev) } drvdata->desc.type = REGULATOR_VOLTAGE; drvdata->desc.owner = THIS_MODULE; + drvdata->desc.ops = &fixed_voltage_ops; if (config->microvolts) drvdata->desc.n_voltages = 1; @@ -205,7 +201,6 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev) drvdata->startup_delay = config->startup_delay; if (gpio_is_valid(config->gpio)) { - int gpio_flag; drvdata->enable_high = config->enable_high; /* FIXME: Remove below print warning @@ -223,39 +218,39 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev) dev_warn(&pdev->dev, "using GPIO 0 for regulator enable control\n"); - /* - * set output direction without changing state + ret = gpio_request(config->gpio, config->supply_name); + if (ret) { + dev_err(&pdev->dev, + "Could not obtain regulator enable GPIO %d: %d\n", + config->gpio, ret); + goto err_name; + } + + /* set output direction without changing state * to prevent glitch */ drvdata->is_enabled = config->enabled_at_boot; ret = drvdata->is_enabled ? config->enable_high : !config->enable_high; - gpio_flag = ret ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; - - if (config->gpio_is_open_drain) - gpio_flag |= GPIOF_OPEN_DRAIN; - ret = gpio_request_one(config->gpio, gpio_flag, - config->supply_name); + ret = gpio_direction_output(config->gpio, ret); if (ret) { dev_err(&pdev->dev, - "Could not obtain regulator enable GPIO %d: %d\n", + "Could not configure regulator enable GPIO %d direction: %d\n", config->gpio, ret); - goto err_name; + goto err_gpio; } - drvdata->desc.ops = &fixed_voltage_gpio_ops; - } else { - drvdata->desc.ops = &fixed_voltage_ops; + /* Regulator without GPIO control is considered + * always enabled + */ + drvdata->is_enabled = true; } - cfg.dev = &pdev->dev; - cfg.init_data = config->init_data; - cfg.driver_data = drvdata; - cfg.of_node = pdev->dev.of_node; - - drvdata->dev = regulator_register(&drvdata->desc, &cfg); + drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev, + config->init_data, drvdata, + pdev->dev.of_node); if (IS_ERR(drvdata->dev)) { ret = PTR_ERR(drvdata->dev); dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret); @@ -275,6 +270,7 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev) err_name: kfree(drvdata->desc.name); err: + kfree(drvdata); return ret; } @@ -286,6 +282,7 @@ static int __devexit reg_fixed_voltage_remove(struct platform_device *pdev) if (gpio_is_valid(drvdata->gpio)) gpio_free(drvdata->gpio); kfree(drvdata->desc.name); + kfree(drvdata); return 0; } diff --git a/trunk/drivers/regulator/gpio-regulator.c b/trunk/drivers/regulator/gpio-regulator.c index 9997d7aaca84..42e1cb1835e5 100644 --- a/trunk/drivers/regulator/gpio-regulator.c +++ b/trunk/drivers/regulator/gpio-regulator.c @@ -30,6 +30,7 @@ #include #include #include +#include #include struct gpio_regulator_data { @@ -104,15 +105,15 @@ static int gpio_regulator_set_value(struct regulator_dev *dev, int min, int max) { struct gpio_regulator_data *data = rdev_get_drvdata(dev); - int ptr, target, state, best_val = INT_MAX; + int ptr, target, state; + target = -1; for (ptr = 0; ptr < data->nr_states; ptr++) - if (data->states[ptr].value < best_val && - data->states[ptr].value >= min && + if (data->states[ptr].value >= min && data->states[ptr].value <= max) target = data->states[ptr].gpios; - if (best_val == INT_MAX) + if (target < 0) return -EINVAL; for (ptr = 0; ptr < data->nr_gpios; ptr++) { @@ -171,11 +172,9 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev) { struct gpio_regulator_config *config = pdev->dev.platform_data; struct gpio_regulator_data *drvdata; - struct regulator_config cfg = { }; int ptr, ret, state; - drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data), - GFP_KERNEL); + drvdata = kzalloc(sizeof(struct gpio_regulator_data), GFP_KERNEL); if (drvdata == NULL) { dev_err(&pdev->dev, "Failed to allocate device data\n"); return -ENOMEM; @@ -284,11 +283,8 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev) } drvdata->state = state; - cfg.dev = &pdev->dev; - cfg.init_data = config->init_data; - cfg.driver_data = &drvdata; - - drvdata->dev = regulator_register(&drvdata->desc, &cfg); + drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev, + config->init_data, drvdata, NULL); if (IS_ERR(drvdata->dev)) { ret = PTR_ERR(drvdata->dev); dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret); @@ -311,6 +307,7 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev) err_name: kfree(drvdata->desc.name); err: + kfree(drvdata); return ret; } @@ -329,6 +326,7 @@ static int __devexit gpio_regulator_remove(struct platform_device *pdev) gpio_free(drvdata->enable_gpio); kfree(drvdata->desc.name); + kfree(drvdata); return 0; } diff --git a/trunk/drivers/regulator/isl6271a-regulator.c b/trunk/drivers/regulator/isl6271a-regulator.c index 56d273f25603..775f5fd208c3 100644 --- a/trunk/drivers/regulator/isl6271a-regulator.c +++ b/trunk/drivers/regulator/isl6271a-regulator.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #define ISL6271A_VOLTAGE_MIN 850000 @@ -35,30 +36,47 @@ struct isl_pmic { struct mutex mtx; }; -static int isl6271a_get_voltage_sel(struct regulator_dev *dev) +static int isl6271a_get_voltage(struct regulator_dev *dev) { struct isl_pmic *pmic = rdev_get_drvdata(dev); - int idx; + int idx, data; mutex_lock(&pmic->mtx); idx = i2c_smbus_read_byte(pmic->client); - if (idx < 0) + if (idx < 0) { dev_err(&pmic->client->dev, "Error getting voltage\n"); + data = idx; + goto out; + } + + /* Convert the data from chip to microvolts */ + data = ISL6271A_VOLTAGE_MIN + (ISL6271A_VOLTAGE_STEP * (idx & 0xf)); +out: mutex_unlock(&pmic->mtx); - return idx; + return data; } -static int isl6271a_set_voltage_sel(struct regulator_dev *dev, - unsigned selector) +static int isl6271a_set_voltage(struct regulator_dev *dev, + int minuV, int maxuV, + unsigned *selector) { struct isl_pmic *pmic = rdev_get_drvdata(dev); - int err; + int err, data; + + if (minuV < ISL6271A_VOLTAGE_MIN || minuV > ISL6271A_VOLTAGE_MAX) + return -EINVAL; + if (maxuV < ISL6271A_VOLTAGE_MIN || maxuV > ISL6271A_VOLTAGE_MAX) + return -EINVAL; + + data = DIV_ROUND_UP(minuV - ISL6271A_VOLTAGE_MIN, + ISL6271A_VOLTAGE_STEP); + *selector = data; mutex_lock(&pmic->mtx); - err = i2c_smbus_write_byte(pmic->client, selector); + err = i2c_smbus_write_byte(pmic->client, data); if (err < 0) dev_err(&pmic->client->dev, "Error setting voltage\n"); @@ -66,11 +84,15 @@ static int isl6271a_set_voltage_sel(struct regulator_dev *dev, return err; } +static int isl6271a_list_voltage(struct regulator_dev *dev, unsigned selector) +{ + return ISL6271A_VOLTAGE_MIN + (ISL6271A_VOLTAGE_STEP * selector); +} + static struct regulator_ops isl_core_ops = { - .get_voltage_sel = isl6271a_get_voltage_sel, - .set_voltage_sel = isl6271a_set_voltage_sel, - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, + .get_voltage = isl6271a_get_voltage, + .set_voltage = isl6271a_set_voltage, + .list_voltage = isl6271a_list_voltage, }; static int isl6271a_get_fixed_voltage(struct regulator_dev *dev) @@ -90,7 +112,7 @@ static struct regulator_ops isl_fixed_ops = { .list_voltage = isl6271a_list_fixed_voltage, }; -static const struct regulator_desc isl_rd[] = { +static struct regulator_desc isl_rd[] = { { .name = "Core Buck", .id = 0, @@ -98,8 +120,6 @@ static const struct regulator_desc isl_rd[] = { .ops = &isl_core_ops, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, - .min_uV = ISL6271A_VOLTAGE_MIN, - .uV_step = ISL6271A_VOLTAGE_STEP, }, { .name = "LDO1", .id = 1, @@ -120,7 +140,6 @@ static const struct regulator_desc isl_rd[] = { static int __devinit isl6271a_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { - struct regulator_config config = { }; struct regulator_init_data *init_data = i2c->dev.platform_data; struct isl_pmic *pmic; int err, i; @@ -128,7 +147,12 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c, if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; - pmic = devm_kzalloc(&i2c->dev, sizeof(struct isl_pmic), GFP_KERNEL); + if (!init_data) { + dev_err(&i2c->dev, "no platform data supplied\n"); + return -EIO; + } + + pmic = kzalloc(sizeof(struct isl_pmic), GFP_KERNEL); if (!pmic) return -ENOMEM; @@ -137,14 +161,8 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c, mutex_init(&pmic->mtx); for (i = 0; i < 3; i++) { - config.dev = &i2c->dev; - if (i == 0) - config.init_data = init_data; - else - config.init_data = 0; - config.driver_data = pmic; - - pmic->rdev[i] = regulator_register(&isl_rd[i], &config); + pmic->rdev[i] = regulator_register(&isl_rd[i], &i2c->dev, + init_data, pmic, NULL); if (IS_ERR(pmic->rdev[i])) { dev_err(&i2c->dev, "failed to register %s\n", id->name); err = PTR_ERR(pmic->rdev[i]); @@ -159,6 +177,8 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c, error: while (--i >= 0) regulator_unregister(pmic->rdev[i]); + + kfree(pmic); return err; } @@ -169,6 +189,9 @@ static int __devexit isl6271a_remove(struct i2c_client *i2c) for (i = 0; i < 3; i++) regulator_unregister(pmic->rdev[i]); + + kfree(pmic); + return 0; } diff --git a/trunk/drivers/regulator/lp3971.c b/trunk/drivers/regulator/lp3971.c index 981bea9cb9d7..0cfabd318a59 100644 --- a/trunk/drivers/regulator/lp3971.c +++ b/trunk/drivers/regulator/lp3971.c @@ -124,10 +124,6 @@ static const int *ldo_voltage_map[] = { static int lp3971_ldo_list_voltage(struct regulator_dev *dev, unsigned index) { int ldo = rdev_get_id(dev) - LP3971_LDO1; - - if (index > LDO_VOL_MAX_IDX) - return -EINVAL; - return 1000 * LDO_VOL_VALUE_MAP(ldo)[index]; } @@ -172,15 +168,32 @@ static int lp3971_ldo_get_voltage(struct regulator_dev *dev) return 1000 * LDO_VOL_VALUE_MAP(ldo)[val]; } -static int lp3971_ldo_set_voltage_sel(struct regulator_dev *dev, - unsigned int selector) +static int lp3971_ldo_set_voltage(struct regulator_dev *dev, + int min_uV, int max_uV, + unsigned int *selector) { struct lp3971 *lp3971 = rdev_get_drvdata(dev); int ldo = rdev_get_id(dev) - LP3971_LDO1; + int min_vol = min_uV / 1000, max_vol = max_uV / 1000; + const int *vol_map = LDO_VOL_VALUE_MAP(ldo); + u16 val; + + if (min_vol < vol_map[LDO_VOL_MIN_IDX] || + min_vol > vol_map[LDO_VOL_MAX_IDX]) + return -EINVAL; + + for (val = LDO_VOL_MIN_IDX; val <= LDO_VOL_MAX_IDX; val++) + if (vol_map[val] >= min_vol) + break; + + if (val > LDO_VOL_MAX_IDX || vol_map[val] > max_vol) + return -EINVAL; + + *selector = val; return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo), LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo), - selector << LDO_VOL_CONTR_SHIFT(ldo)); + val << LDO_VOL_CONTR_SHIFT(ldo)); } static struct regulator_ops lp3971_ldo_ops = { @@ -189,14 +202,11 @@ static struct regulator_ops lp3971_ldo_ops = { .enable = lp3971_ldo_enable, .disable = lp3971_ldo_disable, .get_voltage = lp3971_ldo_get_voltage, - .set_voltage_sel = lp3971_ldo_set_voltage_sel, + .set_voltage = lp3971_ldo_set_voltage, }; static int lp3971_dcdc_list_voltage(struct regulator_dev *dev, unsigned index) { - if (index < BUCK_TARGET_VOL_MIN_IDX || index > BUCK_TARGET_VOL_MAX_IDX) - return -EINVAL; - return 1000 * buck_voltage_map[index]; } @@ -249,15 +259,33 @@ static int lp3971_dcdc_get_voltage(struct regulator_dev *dev) return val; } -static int lp3971_dcdc_set_voltage_sel(struct regulator_dev *dev, - unsigned int selector) +static int lp3971_dcdc_set_voltage(struct regulator_dev *dev, + int min_uV, int max_uV, + unsigned int *selector) { struct lp3971 *lp3971 = rdev_get_drvdata(dev); int buck = rdev_get_id(dev) - LP3971_DCDC1; + int min_vol = min_uV / 1000, max_vol = max_uV / 1000; + const int *vol_map = buck_voltage_map; + u16 val; int ret; + if (min_vol < vol_map[BUCK_TARGET_VOL_MIN_IDX] || + min_vol > vol_map[BUCK_TARGET_VOL_MAX_IDX]) + return -EINVAL; + + for (val = BUCK_TARGET_VOL_MIN_IDX; val <= BUCK_TARGET_VOL_MAX_IDX; + val++) + if (vol_map[val] >= min_vol) + break; + + if (val > BUCK_TARGET_VOL_MAX_IDX || vol_map[val] > max_vol) + return -EINVAL; + + *selector = val; + ret = lp3971_set_bits(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck), - BUCK_TARGET_VOL_MASK, selector); + BUCK_TARGET_VOL_MASK, val); if (ret) return ret; @@ -278,10 +306,10 @@ static struct regulator_ops lp3971_dcdc_ops = { .enable = lp3971_dcdc_enable, .disable = lp3971_dcdc_disable, .get_voltage = lp3971_dcdc_get_voltage, - .set_voltage_sel = lp3971_dcdc_set_voltage_sel, + .set_voltage = lp3971_dcdc_set_voltage, }; -static const struct regulator_desc regulators[] = { +static struct regulator_desc regulators[] = { { .name = "LDO1", .id = LP3971_LDO1, @@ -421,15 +449,10 @@ static int __devinit setup_regulators(struct lp3971 *lp3971, /* Instantiate the regulators */ for (i = 0; i < pdata->num_regulators; i++) { - struct regulator_config config = { }; struct lp3971_regulator_subdev *reg = &pdata->regulators[i]; - - config.dev = lp3971->dev; - config.init_data = reg->initdata; - config.driver_data = lp3971; - lp3971->rdev[i] = regulator_register(®ulators[reg->id], - &config); + lp3971->dev, reg->initdata, lp3971, NULL); + if (IS_ERR(lp3971->rdev[i])) { err = PTR_ERR(lp3971->rdev[i]); dev_err(lp3971->dev, "regulator init failed: %d\n", @@ -522,7 +545,23 @@ static struct i2c_driver lp3971_i2c_driver = { .id_table = lp3971_i2c_id, }; -module_i2c_driver(lp3971_i2c_driver); +static int __init lp3971_module_init(void) +{ + int ret; + + ret = i2c_add_driver(&lp3971_i2c_driver); + if (ret != 0) + pr_err("Failed to register I2C driver: %d\n", ret); + + return ret; +} +module_init(lp3971_module_init); + +static void __exit lp3971_module_exit(void) +{ + i2c_del_driver(&lp3971_i2c_driver); +} +module_exit(lp3971_module_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Marek Szyprowski "); diff --git a/trunk/drivers/regulator/lp3972.c b/trunk/drivers/regulator/lp3972.c index de073df7d344..49a15eefe5fe 100644 --- a/trunk/drivers/regulator/lp3972.c +++ b/trunk/drivers/regulator/lp3972.c @@ -245,11 +245,6 @@ static int lp3972_set_bits(struct lp3972 *lp3972, u8 reg, u16 mask, u16 val) static int lp3972_ldo_list_voltage(struct regulator_dev *dev, unsigned index) { int ldo = rdev_get_id(dev) - LP3972_LDO1; - - if (index < LP3972_LDO_VOL_MIN_IDX(ldo) || - index > LP3972_LDO_VOL_MAX_IDX(ldo)) - return -EINVAL; - return 1000 * LP3972_LDO_VOL_VALUE_MAP(ldo)[index]; } @@ -297,16 +292,34 @@ static int lp3972_ldo_get_voltage(struct regulator_dev *dev) return 1000 * LP3972_LDO_VOL_VALUE_MAP(ldo)[val]; } -static int lp3972_ldo_set_voltage_sel(struct regulator_dev *dev, - unsigned int selector) +static int lp3972_ldo_set_voltage(struct regulator_dev *dev, + int min_uV, int max_uV, + unsigned int *selector) { struct lp3972 *lp3972 = rdev_get_drvdata(dev); int ldo = rdev_get_id(dev) - LP3972_LDO1; + int min_vol = min_uV / 1000, max_vol = max_uV / 1000; + const int *vol_map = LP3972_LDO_VOL_VALUE_MAP(ldo); + u16 val; int shift, ret; + if (min_vol < vol_map[LP3972_LDO_VOL_MIN_IDX(ldo)] || + min_vol > vol_map[LP3972_LDO_VOL_MAX_IDX(ldo)]) + return -EINVAL; + + for (val = LP3972_LDO_VOL_MIN_IDX(ldo); + val <= LP3972_LDO_VOL_MAX_IDX(ldo); val++) + if (vol_map[val] >= min_vol) + break; + + if (val > LP3972_LDO_VOL_MAX_IDX(ldo) || vol_map[val] > max_vol) + return -EINVAL; + + *selector = val; + shift = LP3972_LDO_VOL_CONTR_SHIFT(ldo); ret = lp3972_set_bits(lp3972, LP3972_LDO_VOL_CONTR_REG(ldo), - LP3972_LDO_VOL_MASK(ldo) << shift, selector << shift); + LP3972_LDO_VOL_MASK(ldo) << shift, val << shift); if (ret) return ret; @@ -342,17 +355,12 @@ static struct regulator_ops lp3972_ldo_ops = { .enable = lp3972_ldo_enable, .disable = lp3972_ldo_disable, .get_voltage = lp3972_ldo_get_voltage, - .set_voltage_sel = lp3972_ldo_set_voltage_sel, + .set_voltage = lp3972_ldo_set_voltage, }; static int lp3972_dcdc_list_voltage(struct regulator_dev *dev, unsigned index) { int buck = rdev_get_id(dev) - LP3972_DCDC1; - - if (index < LP3972_BUCK_VOL_MIN_IDX(buck) || - index > LP3972_BUCK_VOL_MAX_IDX(buck)) - return -EINVAL; - return 1000 * buck_voltage_map[buck][index]; } @@ -411,15 +419,34 @@ static int lp3972_dcdc_get_voltage(struct regulator_dev *dev) return val; } -static int lp3972_dcdc_set_voltage_sel(struct regulator_dev *dev, - unsigned int selector) +static int lp3972_dcdc_set_voltage(struct regulator_dev *dev, + int min_uV, int max_uV, + unsigned int *selector) { struct lp3972 *lp3972 = rdev_get_drvdata(dev); int buck = rdev_get_id(dev) - LP3972_DCDC1; + int min_vol = min_uV / 1000, max_vol = max_uV / 1000; + const int *vol_map = buck_voltage_map[buck]; + u16 val; int ret; + if (min_vol < vol_map[LP3972_BUCK_VOL_MIN_IDX(buck)] || + min_vol > vol_map[LP3972_BUCK_VOL_MAX_IDX(buck)]) + return -EINVAL; + + for (val = LP3972_BUCK_VOL_MIN_IDX(buck); + val <= LP3972_BUCK_VOL_MAX_IDX(buck); val++) + if (vol_map[val] >= min_vol) + break; + + if (val > LP3972_BUCK_VOL_MAX_IDX(buck) || + vol_map[val] > max_vol) + return -EINVAL; + + *selector = val; + ret = lp3972_set_bits(lp3972, LP3972_BUCK_VOL1_REG(buck), - LP3972_BUCK_VOL_MASK, selector); + LP3972_BUCK_VOL_MASK, val); if (ret) return ret; @@ -441,10 +468,10 @@ static struct regulator_ops lp3972_dcdc_ops = { .enable = lp3972_dcdc_enable, .disable = lp3972_dcdc_disable, .get_voltage = lp3972_dcdc_get_voltage, - .set_voltage_sel = lp3972_dcdc_set_voltage_sel, + .set_voltage = lp3972_dcdc_set_voltage, }; -static const struct regulator_desc regulators[] = { +static struct regulator_desc regulators[] = { { .name = "LDO1", .id = LP3972_LDO1, @@ -527,14 +554,9 @@ static int __devinit setup_regulators(struct lp3972 *lp3972, /* Instantiate the regulators */ for (i = 0; i < pdata->num_regulators; i++) { struct lp3972_regulator_subdev *reg = &pdata->regulators[i]; - struct regulator_config config = { }; - - config.dev = lp3972->dev; - config.init_data = reg->initdata; - config.driver_data = lp3972; - lp3972->rdev[i] = regulator_register(®ulators[reg->id], - &config); + lp3972->dev, reg->initdata, lp3972, NULL); + if (IS_ERR(lp3972->rdev[i])) { err = PTR_ERR(lp3972->rdev[i]); dev_err(lp3972->dev, "regulator init failed: %d\n", diff --git a/trunk/drivers/regulator/max1586.c b/trunk/drivers/regulator/max1586.c index b9444ee08da9..282d2ee0604e 100644 --- a/trunk/drivers/regulator/max1586.c +++ b/trunk/drivers/regulator/max1586.c @@ -161,7 +161,7 @@ static struct regulator_ops max1586_v6_ops = { .list_voltage = max1586_v6_list, }; -static const struct regulator_desc max1586_reg[] = { +static struct regulator_desc max1586_reg[] = { { .name = "Output_V3", .id = MAX1586_V3, @@ -185,21 +185,21 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client, { struct regulator_dev **rdev; struct max1586_platform_data *pdata = client->dev.platform_data; - struct regulator_config config = { }; struct max1586_data *max1586; int i, id, ret = -ENOMEM; - max1586 = devm_kzalloc(&client->dev, sizeof(struct max1586_data) + + max1586 = kzalloc(sizeof(struct max1586_data) + sizeof(struct regulator_dev *) * (MAX1586_V6 + 1), GFP_KERNEL); if (!max1586) - return -ENOMEM; + goto out; max1586->client = client; - if (!pdata->v3_gain) - return -EINVAL; - + if (!pdata->v3_gain) { + ret = -EINVAL; + goto out_unmap; + } max1586->min_uV = MAX1586_V3_MIN_UV / 1000 * pdata->v3_gain / 1000; max1586->max_uV = MAX1586_V3_MAX_UV / 1000 * pdata->v3_gain / 1000; @@ -212,12 +212,9 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client, dev_err(&client->dev, "invalid regulator id %d\n", id); goto err; } - - config.dev = &client->dev; - config.init_data = pdata->subdevs[i].platform_data; - config.driver_data = max1586; - - rdev[i] = regulator_register(&max1586_reg[id], &config); + rdev[i] = regulator_register(&max1586_reg[id], &client->dev, + pdata->subdevs[i].platform_data, + max1586, NULL); if (IS_ERR(rdev[i])) { ret = PTR_ERR(rdev[i]); dev_err(&client->dev, "failed to register %s\n", @@ -233,6 +230,9 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client, err: while (--i >= 0) regulator_unregister(rdev[i]); +out_unmap: + kfree(max1586); +out: return ret; } @@ -244,6 +244,8 @@ static int __devexit max1586_pmic_remove(struct i2c_client *client) for (i = 0; i <= MAX1586_V6; i++) if (max1586->rdev[i]) regulator_unregister(max1586->rdev[i]); + kfree(max1586); + return 0; } diff --git a/trunk/drivers/regulator/max8649.c b/trunk/drivers/regulator/max8649.c index 1f4bb80457b3..824c650436ed 100644 --- a/trunk/drivers/regulator/max8649.c +++ b/trunk/drivers/regulator/max8649.c @@ -53,6 +53,7 @@ struct max8649_regulator_info { struct device *dev; struct regmap *regmap; + int vol_reg; unsigned mode:2; /* bit[1:0] = VID1, VID0 */ unsigned extclk_freq:2; unsigned extclk:1; @@ -60,6 +61,53 @@ struct max8649_regulator_info { unsigned ramp_down:1; }; +/* I2C operations */ + +static inline int check_range(int min_uV, int max_uV) +{ + if ((min_uV < MAX8649_DCDC_VMIN) || (max_uV > MAX8649_DCDC_VMAX) + || (min_uV > max_uV)) + return -EINVAL; + return 0; +} + +static int max8649_list_voltage(struct regulator_dev *rdev, unsigned index) +{ + return (MAX8649_DCDC_VMIN + index * MAX8649_DCDC_STEP); +} + +static int max8649_get_voltage(struct regulator_dev *rdev) +{ + struct max8649_regulator_info *info = rdev_get_drvdata(rdev); + unsigned int val; + unsigned char data; + int ret; + + ret = regmap_read(info->regmap, info->vol_reg, &val); + if (ret != 0) + return ret; + data = (unsigned char)val & MAX8649_VOL_MASK; + return max8649_list_voltage(rdev, data); +} + +static int max8649_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned *selector) +{ + struct max8649_regulator_info *info = rdev_get_drvdata(rdev); + unsigned char data, mask; + + if (check_range(min_uV, max_uV)) { + dev_err(info->dev, "invalid voltage range (%d, %d) uV\n", + min_uV, max_uV); + return -EINVAL; + } + data = DIV_ROUND_UP(min_uV - MAX8649_DCDC_VMIN, MAX8649_DCDC_STEP); + mask = MAX8649_VOL_MASK; + *selector = data & mask; + + return regmap_update_bits(info->regmap, info->vol_reg, mask, data); +} + /* EN_PD means pulldown on EN input */ static int max8649_enable(struct regulator_dev *rdev) { @@ -97,11 +145,11 @@ static int max8649_enable_time(struct regulator_dev *rdev) unsigned int val; /* get voltage */ - ret = regmap_read(info->regmap, rdev->desc->vsel_reg, &val); + ret = regmap_read(info->regmap, info->vol_reg, &val); if (ret != 0) return ret; val &= MAX8649_VOL_MASK; - voltage = regulator_list_voltage_linear(rdev, (unsigned char)val); + voltage = max8649_list_voltage(rdev, (unsigned char)val); /* uV */ /* get rate */ ret = regmap_read(info->regmap, MAX8649_RAMP, &val); @@ -119,11 +167,11 @@ static int max8649_set_mode(struct regulator_dev *rdev, unsigned int mode) switch (mode) { case REGULATOR_MODE_FAST: - regmap_update_bits(info->regmap, rdev->desc->vsel_reg, - MAX8649_FORCE_PWM, MAX8649_FORCE_PWM); + regmap_update_bits(info->regmap, info->vol_reg, MAX8649_FORCE_PWM, + MAX8649_FORCE_PWM); break; case REGULATOR_MODE_NORMAL: - regmap_update_bits(info->regmap, rdev->desc->vsel_reg, + regmap_update_bits(info->regmap, info->vol_reg, MAX8649_FORCE_PWM, 0); break; default: @@ -138,7 +186,7 @@ static unsigned int max8649_get_mode(struct regulator_dev *rdev) unsigned int val; int ret; - ret = regmap_read(info->regmap, rdev->desc->vsel_reg, &val); + ret = regmap_read(info->regmap, info->vol_reg, &val); if (ret != 0) return ret; if (val & MAX8649_FORCE_PWM) @@ -147,10 +195,9 @@ static unsigned int max8649_get_mode(struct regulator_dev *rdev) } static struct regulator_ops max8649_dcdc_ops = { - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, + .set_voltage = max8649_set_voltage, + .get_voltage = max8649_get_voltage, + .list_voltage = max8649_list_voltage, .enable = max8649_enable, .disable = max8649_disable, .is_enabled = max8649_is_enabled, @@ -166,9 +213,6 @@ static struct regulator_desc dcdc_desc = { .type = REGULATOR_VOLTAGE, .n_voltages = 1 << 6, .owner = THIS_MODULE, - .vsel_mask = MAX8649_VOL_MASK, - .min_uV = MAX8649_DCDC_VMIN, - .uV_step = MAX8649_DCDC_STEP, }; static struct regmap_config max8649_regmap_config = { @@ -181,23 +225,21 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, { struct max8649_platform_data *pdata = client->dev.platform_data; struct max8649_regulator_info *info = NULL; - struct regulator_config config = { }; unsigned int val; unsigned char data; int ret; - info = devm_kzalloc(&client->dev, sizeof(struct max8649_regulator_info), - GFP_KERNEL); + info = kzalloc(sizeof(struct max8649_regulator_info), GFP_KERNEL); if (!info) { dev_err(&client->dev, "No enough memory\n"); return -ENOMEM; } - info->regmap = devm_regmap_init_i2c(client, &max8649_regmap_config); + info->regmap = regmap_init_i2c(client, &max8649_regmap_config); if (IS_ERR(info->regmap)) { ret = PTR_ERR(info->regmap); dev_err(&client->dev, "Failed to allocate register map: %d\n", ret); - return ret; + goto fail; } info->dev = &client->dev; @@ -206,16 +248,16 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, info->mode = pdata->mode; switch (info->mode) { case 0: - dcdc_desc.vsel_reg = MAX8649_MODE0; + info->vol_reg = MAX8649_MODE0; break; case 1: - dcdc_desc.vsel_reg = MAX8649_MODE1; + info->vol_reg = MAX8649_MODE1; break; case 2: - dcdc_desc.vsel_reg = MAX8649_MODE2; + info->vol_reg = MAX8649_MODE2; break; case 3: - dcdc_desc.vsel_reg = MAX8649_MODE3; + info->vol_reg = MAX8649_MODE3; break; default: break; @@ -225,7 +267,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, if (ret != 0) { dev_err(info->dev, "Failed to detect ID of MAX8649:%d\n", ret); - return ret; + goto out; } dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", val); @@ -235,8 +277,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, /* enable/disable external clock synchronization */ info->extclk = pdata->extclk; data = (info->extclk) ? MAX8649_SYNC_EXTCLK : 0; - regmap_update_bits(info->regmap, dcdc_desc.vsel_reg, - MAX8649_SYNC_EXTCLK, data); + regmap_update_bits(info->regmap, info->vol_reg, MAX8649_SYNC_EXTCLK, data); if (info->extclk) { /* set external clock frequency */ info->extclk_freq = pdata->extclk_freq; @@ -256,18 +297,22 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, MAX8649_RAMP_DOWN); } - config.dev = &client->dev; - config.init_data = pdata->regulator; - config.driver_data = info; - - info->regulator = regulator_register(&dcdc_desc, &config); + info->regulator = regulator_register(&dcdc_desc, &client->dev, + pdata->regulator, info, NULL); if (IS_ERR(info->regulator)) { dev_err(info->dev, "failed to register regulator %s\n", dcdc_desc.name); - return PTR_ERR(info->regulator); + ret = PTR_ERR(info->regulator); + goto out; } + dev_info(info->dev, "Max8649 regulator device is detected.\n"); return 0; +out: + regmap_exit(info->regmap); +fail: + kfree(info); + return ret; } static int __devexit max8649_regulator_remove(struct i2c_client *client) @@ -277,6 +322,8 @@ static int __devexit max8649_regulator_remove(struct i2c_client *client) if (info) { if (info->regulator) regulator_unregister(info->regulator); + regmap_exit(info->regmap); + kfree(info); } return 0; @@ -313,3 +360,4 @@ module_exit(max8649_exit); MODULE_DESCRIPTION("MAXIM 8649 voltage regulator driver"); MODULE_AUTHOR("Haojian Zhuang "); MODULE_LICENSE("GPL"); + diff --git a/trunk/drivers/regulator/max8660.c b/trunk/drivers/regulator/max8660.c index 8d531742f593..4c5b05311f47 100644 --- a/trunk/drivers/regulator/max8660.c +++ b/trunk/drivers/regulator/max8660.c @@ -126,22 +126,42 @@ static int max8660_dcdc_disable(struct regulator_dev *rdev) return max8660_write(max8660, MAX8660_OVER1, mask, 0); } -static int max8660_dcdc_get_voltage_sel(struct regulator_dev *rdev) +static int max8660_dcdc_list(struct regulator_dev *rdev, unsigned selector) { - struct max8660 *max8660 = rdev_get_drvdata(rdev); + if (selector > MAX8660_DCDC_MAX_SEL) + return -EINVAL; + return MAX8660_DCDC_MIN_UV + selector * MAX8660_DCDC_STEP; +} +static int max8660_dcdc_get(struct regulator_dev *rdev) +{ + struct max8660 *max8660 = rdev_get_drvdata(rdev); u8 reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2; u8 selector = max8660->shadow_regs[reg]; - return selector; + return MAX8660_DCDC_MIN_UV + selector * MAX8660_DCDC_STEP; } -static int max8660_dcdc_set_voltage_sel(struct regulator_dev *rdev, - unsigned int selector) +static int max8660_dcdc_set(struct regulator_dev *rdev, int min_uV, int max_uV, + unsigned int *s) { struct max8660 *max8660 = rdev_get_drvdata(rdev); - u8 reg, bits; + u8 reg, selector, bits; int ret; + if (min_uV < MAX8660_DCDC_MIN_UV || min_uV > MAX8660_DCDC_MAX_UV) + return -EINVAL; + if (max_uV < MAX8660_DCDC_MIN_UV || max_uV > MAX8660_DCDC_MAX_UV) + return -EINVAL; + + selector = DIV_ROUND_UP(min_uV - MAX8660_DCDC_MIN_UV, + MAX8660_DCDC_STEP); + + ret = max8660_dcdc_list(rdev, selector); + if (ret < 0 || ret > max_uV) + return -EINVAL; + + *s = selector; + reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2; ret = max8660_write(max8660, reg, 0, selector); if (ret) @@ -154,10 +174,9 @@ static int max8660_dcdc_set_voltage_sel(struct regulator_dev *rdev, static struct regulator_ops max8660_dcdc_ops = { .is_enabled = max8660_dcdc_is_enabled, - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, - .set_voltage_sel = max8660_dcdc_set_voltage_sel, - .get_voltage_sel = max8660_dcdc_get_voltage_sel, + .list_voltage = max8660_dcdc_list, + .set_voltage = max8660_dcdc_set, + .get_voltage = max8660_dcdc_get, }; @@ -165,20 +184,42 @@ static struct regulator_ops max8660_dcdc_ops = { * LDO5 functions */ -static int max8660_ldo5_get_voltage_sel(struct regulator_dev *rdev) +static int max8660_ldo5_list(struct regulator_dev *rdev, unsigned selector) { - struct max8660 *max8660 = rdev_get_drvdata(rdev); + if (selector > MAX8660_LDO5_MAX_SEL) + return -EINVAL; + return MAX8660_LDO5_MIN_UV + selector * MAX8660_LDO5_STEP; +} +static int max8660_ldo5_get(struct regulator_dev *rdev) +{ + struct max8660 *max8660 = rdev_get_drvdata(rdev); u8 selector = max8660->shadow_regs[MAX8660_MDTV2]; - return selector; + + return MAX8660_LDO5_MIN_UV + selector * MAX8660_LDO5_STEP; } -static int max8660_ldo5_set_voltage_sel(struct regulator_dev *rdev, - unsigned int selector) +static int max8660_ldo5_set(struct regulator_dev *rdev, int min_uV, int max_uV, + unsigned int *s) { struct max8660 *max8660 = rdev_get_drvdata(rdev); + u8 selector; int ret; + if (min_uV < MAX8660_LDO5_MIN_UV || min_uV > MAX8660_LDO5_MAX_UV) + return -EINVAL; + if (max_uV < MAX8660_LDO5_MIN_UV || max_uV > MAX8660_LDO5_MAX_UV) + return -EINVAL; + + selector = DIV_ROUND_UP(min_uV - MAX8660_LDO5_MIN_UV, + MAX8660_LDO5_STEP); + + ret = max8660_ldo5_list(rdev, selector); + if (ret < 0 || ret > max_uV) + return -EINVAL; + + *s = selector; + ret = max8660_write(max8660, MAX8660_MDTV2, 0, selector); if (ret) return ret; @@ -188,10 +229,9 @@ static int max8660_ldo5_set_voltage_sel(struct regulator_dev *rdev, } static struct regulator_ops max8660_ldo5_ops = { - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, - .set_voltage_sel = max8660_ldo5_set_voltage_sel, - .get_voltage_sel = max8660_ldo5_get_voltage_sel, + .list_voltage = max8660_ldo5_list, + .set_voltage = max8660_ldo5_set, + .get_voltage = max8660_ldo5_get, }; @@ -221,38 +261,59 @@ static int max8660_ldo67_disable(struct regulator_dev *rdev) return max8660_write(max8660, MAX8660_OVER2, mask, 0); } -static int max8660_ldo67_get_voltage_sel(struct regulator_dev *rdev) +static int max8660_ldo67_list(struct regulator_dev *rdev, unsigned selector) { - struct max8660 *max8660 = rdev_get_drvdata(rdev); + if (selector > MAX8660_LDO67_MAX_SEL) + return -EINVAL; + return MAX8660_LDO67_MIN_UV + selector * MAX8660_LDO67_STEP; +} +static int max8660_ldo67_get(struct regulator_dev *rdev) +{ + struct max8660 *max8660 = rdev_get_drvdata(rdev); u8 shift = (rdev_get_id(rdev) == MAX8660_V6) ? 0 : 4; u8 selector = (max8660->shadow_regs[MAX8660_L12VCR] >> shift) & 0xf; - return selector; + + return MAX8660_LDO67_MIN_UV + selector * MAX8660_LDO67_STEP; } -static int max8660_ldo67_set_voltage_sel(struct regulator_dev *rdev, - unsigned int selector) +static int max8660_ldo67_set(struct regulator_dev *rdev, int min_uV, + int max_uV, unsigned int *s) { struct max8660 *max8660 = rdev_get_drvdata(rdev); + u8 selector; + int ret; + + if (min_uV < MAX8660_LDO67_MIN_UV || min_uV > MAX8660_LDO67_MAX_UV) + return -EINVAL; + if (max_uV < MAX8660_LDO67_MIN_UV || max_uV > MAX8660_LDO67_MAX_UV) + return -EINVAL; + + selector = DIV_ROUND_UP(min_uV - MAX8660_LDO67_MIN_UV, + MAX8660_LDO67_STEP); + + ret = max8660_ldo67_list(rdev, selector); + if (ret < 0 || ret > max_uV) + return -EINVAL; + + *s = selector; if (rdev_get_id(rdev) == MAX8660_V6) return max8660_write(max8660, MAX8660_L12VCR, 0xf0, selector); else - return max8660_write(max8660, MAX8660_L12VCR, 0x0f, - selector << 4); + return max8660_write(max8660, MAX8660_L12VCR, 0x0f, selector << 4); } static struct regulator_ops max8660_ldo67_ops = { .is_enabled = max8660_ldo67_is_enabled, .enable = max8660_ldo67_enable, .disable = max8660_ldo67_disable, - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, - .get_voltage_sel = max8660_ldo67_get_voltage_sel, - .set_voltage_sel = max8660_ldo67_set_voltage_sel, + .list_voltage = max8660_ldo67_list, + .get_voltage = max8660_ldo67_get, + .set_voltage = max8660_ldo67_set, }; -static const struct regulator_desc max8660_reg[] = { +static struct regulator_desc max8660_reg[] = { { .name = "V3(DCDC)", .id = MAX8660_V3, @@ -260,8 +321,6 @@ static const struct regulator_desc max8660_reg[] = { .type = REGULATOR_VOLTAGE, .n_voltages = MAX8660_DCDC_MAX_SEL + 1, .owner = THIS_MODULE, - .min_uV = MAX8660_DCDC_MIN_UV, - .uV_step = MAX8660_DCDC_STEP, }, { .name = "V4(DCDC)", @@ -270,8 +329,6 @@ static const struct regulator_desc max8660_reg[] = { .type = REGULATOR_VOLTAGE, .n_voltages = MAX8660_DCDC_MAX_SEL + 1, .owner = THIS_MODULE, - .min_uV = MAX8660_DCDC_MIN_UV, - .uV_step = MAX8660_DCDC_STEP, }, { .name = "V5(LDO)", @@ -280,8 +337,6 @@ static const struct regulator_desc max8660_reg[] = { .type = REGULATOR_VOLTAGE, .n_voltages = MAX8660_LDO5_MAX_SEL + 1, .owner = THIS_MODULE, - .min_uV = MAX8660_LDO5_MIN_UV, - .uV_step = MAX8660_LDO5_STEP, }, { .name = "V6(LDO)", @@ -290,8 +345,6 @@ static const struct regulator_desc max8660_reg[] = { .type = REGULATOR_VOLTAGE, .n_voltages = MAX8660_LDO67_MAX_SEL + 1, .owner = THIS_MODULE, - .min_uV = MAX8660_LDO67_MIN_UV, - .uV_step = MAX8660_LDO67_STEP, }, { .name = "V7(LDO)", @@ -300,8 +353,6 @@ static const struct regulator_desc max8660_reg[] = { .type = REGULATOR_VOLTAGE, .n_voltages = MAX8660_LDO67_MAX_SEL + 1, .owner = THIS_MODULE, - .min_uV = MAX8660_LDO67_MIN_UV, - .uV_step = MAX8660_LDO67_STEP, }, }; @@ -310,20 +361,21 @@ static int __devinit max8660_probe(struct i2c_client *client, { struct regulator_dev **rdev; struct max8660_platform_data *pdata = client->dev.platform_data; - struct regulator_config config = { }; struct max8660 *max8660; int boot_on, i, id, ret = -EINVAL; if (pdata->num_subdevs > MAX8660_V_END) { dev_err(&client->dev, "Too many regulators found!\n"); - return -EINVAL; + goto out; } - max8660 = devm_kzalloc(&client->dev, sizeof(struct max8660) + + max8660 = kzalloc(sizeof(struct max8660) + sizeof(struct regulator_dev *) * MAX8660_V_END, GFP_KERNEL); - if (!max8660) - return -ENOMEM; + if (!max8660) { + ret = -ENOMEM; + goto out; + } max8660->client = client; rdev = max8660->rdev; @@ -352,7 +404,7 @@ static int __devinit max8660_probe(struct i2c_client *client, for (i = 0; i < pdata->num_subdevs; i++) { if (!pdata->subdevs[i].platform_data) - goto err_out; + goto err_free; boot_on = pdata->subdevs[i].platform_data->constraints.boot_on; @@ -378,7 +430,7 @@ static int __devinit max8660_probe(struct i2c_client *client, case MAX8660_V7: if (!strcmp(i2c_id->name, "max8661")) { dev_err(&client->dev, "Regulator not on this chip!\n"); - goto err_out; + goto err_free; } if (boot_on) @@ -388,7 +440,7 @@ static int __devinit max8660_probe(struct i2c_client *client, default: dev_err(&client->dev, "invalid regulator %s\n", pdata->subdevs[i].name); - goto err_out; + goto err_free; } } @@ -397,11 +449,9 @@ static int __devinit max8660_probe(struct i2c_client *client, id = pdata->subdevs[i].id; - config.dev = &client->dev; - config.init_data = pdata->subdevs[i].platform_data; - config.driver_data = max8660; - - rdev[i] = regulator_register(&max8660_reg[id], &config); + rdev[i] = regulator_register(&max8660_reg[id], &client->dev, + pdata->subdevs[i].platform_data, + max8660, NULL); if (IS_ERR(rdev[i])) { ret = PTR_ERR(rdev[i]); dev_err(&client->dev, "failed to register %s\n", @@ -411,12 +461,15 @@ static int __devinit max8660_probe(struct i2c_client *client, } i2c_set_clientdata(client, max8660); + dev_info(&client->dev, "Maxim 8660/8661 regulator driver loaded\n"); return 0; err_unregister: while (--i >= 0) regulator_unregister(rdev[i]); -err_out: +err_free: + kfree(max8660); +out: return ret; } @@ -428,6 +481,8 @@ static int __devexit max8660_remove(struct i2c_client *client) for (i = 0; i < MAX8660_V_END; i++) if (max8660->rdev[i]) regulator_unregister(max8660->rdev[i]); + kfree(max8660); + return 0; } diff --git a/trunk/drivers/regulator/max8925-regulator.c b/trunk/drivers/regulator/max8925-regulator.c index 43dc97ec3932..2f242f43096e 100644 --- a/trunk/drivers/regulator/max8925-regulator.c +++ b/trunk/drivers/regulator/max8925-regulator.c @@ -38,20 +38,50 @@ struct max8925_regulator_info { struct i2c_client *i2c; struct max8925_chip *chip; + int min_uV; + int max_uV; + int step_uV; int vol_reg; + int vol_shift; + int vol_nbits; int enable_reg; }; -static int max8925_set_voltage_sel(struct regulator_dev *rdev, - unsigned int selector) +static inline int check_range(struct max8925_regulator_info *info, + int min_uV, int max_uV) +{ + if (min_uV < info->min_uV || min_uV > info->max_uV) + return -EINVAL; + + return 0; +} + +static int max8925_list_voltage(struct regulator_dev *rdev, unsigned index) +{ + struct max8925_regulator_info *info = rdev_get_drvdata(rdev); + return info->min_uV + index * info->step_uV; +} + +static int max8925_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned int *selector) { struct max8925_regulator_info *info = rdev_get_drvdata(rdev); - unsigned char mask = rdev->desc->n_voltages - 1; + unsigned char data, mask; + + if (check_range(info, min_uV, max_uV)) { + dev_err(info->chip->dev, "invalid voltage range (%d, %d) uV\n", + min_uV, max_uV); + return -EINVAL; + } + data = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV); + *selector = data; + data <<= info->vol_shift; + mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; - return max8925_set_bits(info->i2c, info->vol_reg, mask, selector); + return max8925_set_bits(info->i2c, info->vol_reg, mask, data); } -static int max8925_get_voltage_sel(struct regulator_dev *rdev) +static int max8925_get_voltage(struct regulator_dev *rdev) { struct max8925_regulator_info *info = rdev_get_drvdata(rdev); unsigned char data, mask; @@ -60,10 +90,10 @@ static int max8925_get_voltage_sel(struct regulator_dev *rdev) ret = max8925_reg_read(info->i2c, info->vol_reg); if (ret < 0) return ret; - mask = rdev->desc->n_voltages - 1; - data = ret & mask; + mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; + data = (ret & mask) >> info->vol_shift; - return data; + return max8925_list_voltage(rdev, data); } static int max8925_enable(struct regulator_dev *rdev) @@ -133,10 +163,8 @@ static int max8925_set_dvm_disable(struct regulator_dev *rdev) } static struct regulator_ops max8925_regulator_sdv_ops = { - .map_voltage = regulator_map_voltage_linear, - .list_voltage = regulator_list_voltage_linear, - .set_voltage_sel = max8925_set_voltage_sel, - .get_voltage_sel = max8925_get_voltage_sel, + .set_voltage = max8925_set_voltage, + .get_voltage = max8925_get_voltage, .enable = max8925_enable, .disable = max8925_disable, .is_enabled = max8925_is_enabled, @@ -146,10 +174,8 @@ static struct regulator_ops max8925_regulator_sdv_ops = { }; static struct regulator_ops max8925_regulator_ldo_ops = { - .map_voltage = regulator_map_voltage_linear, - .list_voltage = regulator_list_voltage_linear, - .set_voltage_sel = max8925_set_voltage_sel, - .get_voltage_sel = max8925_get_voltage_sel, + .set_voltage = max8925_set_voltage, + .get_voltage = max8925_get_voltage, .enable = max8925_enable, .disable = max8925_disable, .is_enabled = max8925_is_enabled, @@ -163,11 +189,13 @@ static struct regulator_ops max8925_regulator_ldo_ops = { .type = REGULATOR_VOLTAGE, \ .id = MAX8925_ID_SD##_id, \ .owner = THIS_MODULE, \ - .n_voltages = 64, \ - .min_uV = min * 1000, \ - .uV_step = step * 1000, \ }, \ + .min_uV = min * 1000, \ + .max_uV = max * 1000, \ + .step_uV = step * 1000, \ .vol_reg = MAX8925_SDV##_id, \ + .vol_shift = 0, \ + .vol_nbits = 6, \ .enable_reg = MAX8925_SDCTL##_id, \ } @@ -179,11 +207,13 @@ static struct regulator_ops max8925_regulator_ldo_ops = { .type = REGULATOR_VOLTAGE, \ .id = MAX8925_ID_LDO##_id, \ .owner = THIS_MODULE, \ - .n_voltages = 64, \ - .min_uV = min * 1000, \ - .uV_step = step * 1000, \ }, \ + .min_uV = min * 1000, \ + .max_uV = max * 1000, \ + .step_uV = step * 1000, \ .vol_reg = MAX8925_LDOVOUT##_id, \ + .vol_shift = 0, \ + .vol_nbits = 6, \ .enable_reg = MAX8925_LDOCTL##_id, \ } @@ -231,7 +261,6 @@ static int __devinit max8925_regulator_probe(struct platform_device *pdev) { struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); struct max8925_platform_data *pdata = chip->dev->platform_data; - struct regulator_config config = { }; struct max8925_regulator_info *ri; struct regulator_dev *rdev; @@ -243,11 +272,8 @@ static int __devinit max8925_regulator_probe(struct platform_device *pdev) ri->i2c = chip->i2c; ri->chip = chip; - config.dev = &pdev->dev; - config.init_data = pdata->regulator[pdev->id]; - config.driver_data = ri; - - rdev = regulator_register(&ri->desc, &config); + rdev = regulator_register(&ri->desc, &pdev->dev, + pdata->regulator[pdev->id], ri, NULL); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register regulator %s\n", ri->desc.name); @@ -293,3 +319,4 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Haojian Zhuang "); MODULE_DESCRIPTION("Regulator Driver for Maxim 8925 PMIC"); MODULE_ALIAS("platform:max8925-regulator"); + diff --git a/trunk/drivers/regulator/max8952.c b/trunk/drivers/regulator/max8952.c index 910c9b26d499..75d89400c123 100644 --- a/trunk/drivers/regulator/max8952.c +++ b/trunk/drivers/regulator/max8952.c @@ -69,6 +69,11 @@ static int max8952_write_reg(struct max8952_data *max8952, return i2c_smbus_write_byte_data(max8952->client, reg, value); } +static int max8952_voltage(struct max8952_data *max8952, u8 mode) +{ + return (max8952->pdata->dvs_mode[mode] * 10 + 770) * 1000; +} + static int max8952_list_voltage(struct regulator_dev *rdev, unsigned int selector) { @@ -77,7 +82,7 @@ static int max8952_list_voltage(struct regulator_dev *rdev, if (rdev_get_id(rdev) != 0) return -EINVAL; - return (max8952->pdata->dvs_mode[selector] * 10 + 770) * 1000; + return max8952_voltage(max8952, selector); } static int max8952_is_enabled(struct regulator_dev *rdev) @@ -112,7 +117,7 @@ static int max8952_disable(struct regulator_dev *rdev) return 0; } -static int max8952_get_voltage_sel(struct regulator_dev *rdev) +static int max8952_get_voltage(struct regulator_dev *rdev) { struct max8952_data *max8952 = rdev_get_drvdata(rdev); u8 vid = 0; @@ -122,13 +127,14 @@ static int max8952_get_voltage_sel(struct regulator_dev *rdev) if (max8952->vid1) vid += 2; - return vid; + return max8952_voltage(max8952, vid); } -static int max8952_set_voltage_sel(struct regulator_dev *rdev, - unsigned selector) +static int max8952_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned *selector) { struct max8952_data *max8952 = rdev_get_drvdata(rdev); + s8 vid = -1, i; if (!gpio_is_valid(max8952->pdata->gpio_vid0) || !gpio_is_valid(max8952->pdata->gpio_vid1)) { @@ -136,10 +142,23 @@ static int max8952_set_voltage_sel(struct regulator_dev *rdev, return -EPERM; } - max8952->vid0 = selector & 0x1; - max8952->vid1 = (selector >> 1) & 0x1; - gpio_set_value(max8952->pdata->gpio_vid0, max8952->vid0); - gpio_set_value(max8952->pdata->gpio_vid1, max8952->vid1); + for (i = 0; i < MAX8952_NUM_DVS_MODE; i++) { + int volt = max8952_voltage(max8952, i); + + /* Set the voltage as low as possible within the range */ + if (volt <= max_uV && volt >= min_uV) + if (vid == -1 || max8952_voltage(max8952, vid) > volt) + vid = i; + } + + if (vid >= 0 && vid < MAX8952_NUM_DVS_MODE) { + max8952->vid0 = (vid % 2 == 1); + max8952->vid1 = (((vid >> 1) % 2) == 1); + *selector = vid; + gpio_set_value(max8952->pdata->gpio_vid0, max8952->vid0); + gpio_set_value(max8952->pdata->gpio_vid1, max8952->vid1); + } else + return -EINVAL; return 0; } @@ -149,12 +168,12 @@ static struct regulator_ops max8952_ops = { .is_enabled = max8952_is_enabled, .enable = max8952_enable, .disable = max8952_disable, - .get_voltage_sel = max8952_get_voltage_sel, - .set_voltage_sel = max8952_set_voltage_sel, + .get_voltage = max8952_get_voltage, + .set_voltage = max8952_set_voltage, .set_suspend_disable = max8952_disable, }; -static const struct regulator_desc regulator = { +static struct regulator_desc regulator = { .name = "MAX8952_VOUT", .id = 0, .n_voltages = MAX8952_NUM_DVS_MODE, @@ -168,7 +187,6 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client, { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct max8952_platform_data *pdata = client->dev.platform_data; - struct regulator_config config = { }; struct max8952_data *max8952; int ret = 0, err = 0; @@ -181,8 +199,7 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client, if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) return -EIO; - max8952 = devm_kzalloc(&client->dev, sizeof(struct max8952_data), - GFP_KERNEL); + max8952 = kzalloc(sizeof(struct max8952_data), GFP_KERNEL); if (!max8952) return -ENOMEM; @@ -190,21 +207,18 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client, max8952->dev = &client->dev; max8952->pdata = pdata; - config.dev = max8952->dev; - config.init_data = &pdata->reg_data; - config.driver_data = max8952; - - max8952->rdev = regulator_register(®ulator, &config); + max8952->rdev = regulator_register(®ulator, max8952->dev, + &pdata->reg_data, max8952, NULL); if (IS_ERR(max8952->rdev)) { ret = PTR_ERR(max8952->rdev); dev_err(max8952->dev, "regulator init failed (%d)\n", ret); - return ret; + goto err_reg; } max8952->en = !!(pdata->reg_data.constraints.boot_on); - max8952->vid0 = pdata->default_mode & 0x1; - max8952->vid1 = (pdata->default_mode >> 1) & 0x1; + max8952->vid0 = (pdata->default_mode % 2) == 1; + max8952->vid1 = ((pdata->default_mode >> 1) % 2) == 1; if (gpio_is_valid(pdata->gpio_en)) { if (!gpio_request(pdata->gpio_en, "MAX8952 EN")) @@ -227,13 +241,13 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client, gpio_is_valid(pdata->gpio_vid1)) { if (!gpio_request(pdata->gpio_vid0, "MAX8952 VID0")) gpio_direction_output(pdata->gpio_vid0, - (pdata->default_mode) & 0x1); + (pdata->default_mode) % 2); else err = 1; if (!gpio_request(pdata->gpio_vid1, "MAX8952 VID1")) gpio_direction_output(pdata->gpio_vid1, - (pdata->default_mode >> 1) & 0x1); + (pdata->default_mode >> 1) % 2); else { if (!err) gpio_free(pdata->gpio_vid0); @@ -296,6 +310,10 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client, i2c_set_clientdata(client, max8952); return 0; + +err_reg: + kfree(max8952); + return ret; } static int __devexit max8952_pmic_remove(struct i2c_client *client) @@ -309,6 +327,8 @@ static int __devexit max8952_pmic_remove(struct i2c_client *client) gpio_free(pdata->gpio_vid0); gpio_free(pdata->gpio_vid1); gpio_free(pdata->gpio_en); + + kfree(max8952); return 0; } diff --git a/trunk/drivers/regulator/max8997.c b/trunk/drivers/regulator/max8997.c index 704cd49ef375..96579296f04d 100644 --- a/trunk/drivers/regulator/max8997.c +++ b/trunk/drivers/regulator/max8997.c @@ -22,6 +22,7 @@ */ #include +#include #include #include #include @@ -67,28 +68,29 @@ struct voltage_map_desc { int min; int max; int step; + unsigned int n_bits; }; /* Voltage maps in mV */ static const struct voltage_map_desc ldo_voltage_map_desc = { - .min = 800, .max = 3950, .step = 50, + .min = 800, .max = 3950, .step = 50, .n_bits = 6, }; /* LDO1 ~ 18, 21 all */ static const struct voltage_map_desc buck1245_voltage_map_desc = { - .min = 650, .max = 2225, .step = 25, + .min = 650, .max = 2225, .step = 25, .n_bits = 6, }; /* Buck1, 2, 4, 5 */ static const struct voltage_map_desc buck37_voltage_map_desc = { - .min = 750, .max = 3900, .step = 50, + .min = 750, .max = 3900, .step = 50, .n_bits = 6, }; /* Buck3, 7 */ /* current map in mA */ static const struct voltage_map_desc charger_current_map_desc = { - .min = 200, .max = 950, .step = 50, + .min = 200, .max = 950, .step = 50, .n_bits = 4, }; static const struct voltage_map_desc topoff_current_map_desc = { - .min = 50, .max = 200, .step = 10, + .min = 50, .max = 200, .step = 10, .n_bits = 4, }; static const struct voltage_map_desc *reg_voltage_map[] = { @@ -277,7 +279,9 @@ static int max8997_reg_is_enabled(struct regulator_dev *rdev) u8 val; ret = max8997_get_enable_register(rdev, ®, &mask, &pattern); - if (ret) + if (ret == -EINVAL) + return 1; /* "not controllable" */ + else if (ret) return ret; ret = max8997_read_reg(i2c, reg, &val); @@ -316,7 +320,6 @@ static int max8997_reg_disable(struct regulator_dev *rdev) static int max8997_get_voltage_register(struct regulator_dev *rdev, int *_reg, int *_shift, int *_mask) { - struct max8997_data *max8997 = rdev_get_drvdata(rdev); int rid = rdev_get_id(rdev); int reg, shift = 0, mask = 0x3f; @@ -326,13 +329,9 @@ static int max8997_get_voltage_register(struct regulator_dev *rdev, break; case MAX8997_BUCK1: reg = MAX8997_REG_BUCK1DVS1; - if (max8997->buck1_gpiodvs) - reg += max8997->buck125_gpioindex; break; case MAX8997_BUCK2: reg = MAX8997_REG_BUCK2DVS1; - if (max8997->buck2_gpiodvs) - reg += max8997->buck125_gpioindex; break; case MAX8997_BUCK3: reg = MAX8997_REG_BUCK3DVS; @@ -342,8 +341,6 @@ static int max8997_get_voltage_register(struct regulator_dev *rdev, break; case MAX8997_BUCK5: reg = MAX8997_REG_BUCK5DVS1; - if (max8997->buck5_gpiodvs) - reg += max8997->buck125_gpioindex; break; case MAX8997_BUCK7: reg = MAX8997_REG_BUCK7DVS; @@ -379,17 +376,23 @@ static int max8997_get_voltage_register(struct regulator_dev *rdev, return 0; } -static int max8997_get_voltage_sel(struct regulator_dev *rdev) +static int max8997_get_voltage(struct regulator_dev *rdev) { struct max8997_data *max8997 = rdev_get_drvdata(rdev); struct i2c_client *i2c = max8997->iodev->i2c; int reg, shift, mask, ret; + int rid = rdev_get_id(rdev); u8 val; ret = max8997_get_voltage_register(rdev, ®, &shift, &mask); if (ret) return ret; + if ((rid == MAX8997_BUCK1 && max8997->buck1_gpiodvs) || + (rid == MAX8997_BUCK2 && max8997->buck2_gpiodvs) || + (rid == MAX8997_BUCK5 && max8997->buck5_gpiodvs)) + reg += max8997->buck125_gpioindex; + ret = max8997_read_reg(i2c, reg, &val); if (ret) return ret; @@ -397,14 +400,22 @@ static int max8997_get_voltage_sel(struct regulator_dev *rdev) val >>= shift; val &= mask; - return val; + if (rdev->desc && rdev->desc->ops && rdev->desc->ops->list_voltage) + return rdev->desc->ops->list_voltage(rdev, val); + + /* + * max8997_list_voltage returns value for any rdev with voltage_map, + * which works for "CHARGER" and "CHARGER TOPOFF" that do not have + * list_voltage ops (they are current regulators). + */ + return max8997_list_voltage(rdev, val); } static inline int max8997_get_voltage_proper_val( const struct voltage_map_desc *desc, int min_vol, int max_vol) { - int i; + int i = 0; if (desc == NULL) return -EINVAL; @@ -412,14 +423,16 @@ static inline int max8997_get_voltage_proper_val( if (max_vol < desc->min || min_vol > desc->max) return -EINVAL; - if (min_vol < desc->min) - min_vol = desc->min; - - i = DIV_ROUND_UP(min_vol - desc->min, desc->step); + while (desc->min + desc->step * i < min_vol && + desc->min + desc->step * i < desc->max) + i++; if (desc->min + desc->step * i > max_vol) return -EINVAL; + if (i >= (1 << desc->n_bits)) + return -EINVAL; + return i; } @@ -486,7 +499,9 @@ static int max8997_set_voltage_ldobuck(struct regulator_dev *rdev, int min_vol = min_uV / 1000, max_vol = max_uV / 1000; const struct voltage_map_desc *desc; int rid = rdev_get_id(rdev); - int i, reg, shift, mask, ret; + int reg, shift = 0, mask, ret; + int i; + u8 org; switch (rid) { case MAX8997_LDO1 ... MAX8997_LDO21: @@ -515,50 +530,21 @@ static int max8997_set_voltage_ldobuck(struct regulator_dev *rdev, if (ret) return ret; + max8997_read_reg(i2c, reg, &org); + org = (org & mask) >> shift; + ret = max8997_update_reg(i2c, reg, i << shift, mask << shift); *selector = i; - return ret; -} - -static int max8997_set_voltage_ldobuck_time_sel(struct regulator_dev *rdev, - unsigned int old_selector, - unsigned int new_selector) -{ - struct max8997_data *max8997 = rdev_get_drvdata(rdev); - int rid = rdev_get_id(rdev); - const struct voltage_map_desc *desc = reg_voltage_map[rid]; - - /* Delay is required only if the voltage is increasing */ - if (old_selector >= new_selector) - return 0; - - /* No need to delay if gpio_dvs_mode */ - switch (rid) { - case MAX8997_BUCK1: - if (max8997->buck1_gpiodvs) - return 0; - break; - case MAX8997_BUCK2: - if (max8997->buck2_gpiodvs) - return 0; - break; - case MAX8997_BUCK5: - if (max8997->buck5_gpiodvs) - return 0; - break; + if (rid == MAX8997_BUCK1 || rid == MAX8997_BUCK2 || + rid == MAX8997_BUCK4 || rid == MAX8997_BUCK5) { + /* If the voltage is increasing */ + if (org < i) + udelay(DIV_ROUND_UP(desc->step * (i - org), + max8997->ramp_delay)); } - switch (rid) { - case MAX8997_BUCK1: - case MAX8997_BUCK2: - case MAX8997_BUCK4: - case MAX8997_BUCK5: - return DIV_ROUND_UP(desc->step * (new_selector - old_selector), - max8997->ramp_delay); - } - - return 0; + return ret; } /* @@ -698,7 +684,7 @@ static int max8997_set_voltage_buck(struct regulator_dev *rdev, } new_val++; - } while (desc->min + desc->step * new_val <= desc->max); + } while (desc->min + desc->step + new_val <= desc->max); new_idx = tmp_idx; new_val = tmp_val; @@ -765,6 +751,11 @@ static int max8997_set_voltage_safeout(struct regulator_dev *rdev, return ret; } +static int max8997_reg_enable_suspend(struct regulator_dev *rdev) +{ + return 0; +} + static int max8997_reg_disable_suspend(struct regulator_dev *rdev) { struct max8997_data *max8997 = rdev_get_drvdata(rdev); @@ -797,9 +788,9 @@ static struct regulator_ops max8997_ldo_ops = { .is_enabled = max8997_reg_is_enabled, .enable = max8997_reg_enable, .disable = max8997_reg_disable, - .get_voltage_sel = max8997_get_voltage_sel, + .get_voltage = max8997_get_voltage, .set_voltage = max8997_set_voltage_ldobuck, - .set_voltage_time_sel = max8997_set_voltage_ldobuck_time_sel, + .set_suspend_enable = max8997_reg_enable_suspend, .set_suspend_disable = max8997_reg_disable_suspend, }; @@ -808,9 +799,9 @@ static struct regulator_ops max8997_buck_ops = { .is_enabled = max8997_reg_is_enabled, .enable = max8997_reg_enable, .disable = max8997_reg_disable, - .get_voltage_sel = max8997_get_voltage_sel, + .get_voltage = max8997_get_voltage, .set_voltage = max8997_set_voltage_buck, - .set_voltage_time_sel = max8997_set_voltage_ldobuck_time_sel, + .set_suspend_enable = max8997_reg_enable_suspend, .set_suspend_disable = max8997_reg_disable_suspend, }; @@ -819,6 +810,7 @@ static struct regulator_ops max8997_fixedvolt_ops = { .is_enabled = max8997_reg_is_enabled, .enable = max8997_reg_enable, .disable = max8997_reg_disable, + .set_suspend_enable = max8997_reg_enable_suspend, .set_suspend_disable = max8997_reg_disable_suspend, }; @@ -827,117 +819,144 @@ static struct regulator_ops max8997_safeout_ops = { .is_enabled = max8997_reg_is_enabled, .enable = max8997_reg_enable, .disable = max8997_reg_disable, - .get_voltage_sel = max8997_get_voltage_sel, + .get_voltage = max8997_get_voltage, .set_voltage = max8997_set_voltage_safeout, + .set_suspend_enable = max8997_reg_enable_suspend, .set_suspend_disable = max8997_reg_disable_suspend, }; static struct regulator_ops max8997_fixedstate_ops = { .list_voltage = max8997_list_voltage_charger_cv, - .get_voltage_sel = max8997_get_voltage_sel, + .get_voltage = max8997_get_voltage, .set_voltage = max8997_set_voltage_charger_cv, }; -static int max8997_set_current_limit(struct regulator_dev *rdev, - int min_uA, int max_uA) +static int max8997_set_voltage_ldobuck_wrap(struct regulator_dev *rdev, + int min_uV, int max_uV) { unsigned dummy; - int rid = rdev_get_id(rdev); - - if (rid != MAX8997_CHARGER && rid != MAX8997_CHARGER_TOPOFF) - return -EINVAL; - /* Reuse max8997_set_voltage_ldobuck to set current_limit. */ - return max8997_set_voltage_ldobuck(rdev, min_uA, max_uA, &dummy); + return max8997_set_voltage_ldobuck(rdev, min_uV, max_uV, &dummy); } -static int max8997_get_current_limit(struct regulator_dev *rdev) -{ - int sel, rid = rdev_get_id(rdev); - - if (rid != MAX8997_CHARGER && rid != MAX8997_CHARGER_TOPOFF) - return -EINVAL; - - sel = max8997_get_voltage_sel(rdev); - if (sel < 0) - return sel; - - /* Reuse max8997_list_voltage to get current_limit. */ - return max8997_list_voltage(rdev, sel); -} static struct regulator_ops max8997_charger_ops = { .is_enabled = max8997_reg_is_enabled, .enable = max8997_reg_enable, .disable = max8997_reg_disable, - .get_current_limit = max8997_get_current_limit, - .set_current_limit = max8997_set_current_limit, + .get_current_limit = max8997_get_voltage, + .set_current_limit = max8997_set_voltage_ldobuck_wrap, }; static struct regulator_ops max8997_charger_fixedstate_ops = { - .get_current_limit = max8997_get_current_limit, - .set_current_limit = max8997_set_current_limit, + .is_enabled = max8997_reg_is_enabled, + .get_current_limit = max8997_get_voltage, + .set_current_limit = max8997_set_voltage_ldobuck_wrap, }; -#define MAX8997_VOLTAGE_REGULATOR(_name, _ops) {\ - .name = #_name, \ - .id = MAX8997_##_name, \ - .ops = &_ops, \ +#define regulator_desc_ldo(num) { \ + .name = "LDO"#num, \ + .id = MAX8997_LDO##num, \ + .ops = &max8997_ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ } - -#define MAX8997_CURRENT_REGULATOR(_name, _ops) {\ - .name = #_name, \ - .id = MAX8997_##_name, \ - .ops = &_ops, \ - .type = REGULATOR_CURRENT, \ +#define regulator_desc_buck(num) { \ + .name = "BUCK"#num, \ + .id = MAX8997_BUCK##num, \ + .ops = &max8997_buck_ops, \ + .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ } static struct regulator_desc regulators[] = { - MAX8997_VOLTAGE_REGULATOR(LDO1, max8997_ldo_ops), - MAX8997_VOLTAGE_REGULATOR(LDO2, max8997_ldo_ops), - MAX8997_VOLTAGE_REGULATOR(LDO3, max8997_ldo_ops), - MAX8997_VOLTAGE_REGULATOR(LDO4, max8997_ldo_ops), - MAX8997_VOLTAGE_REGULATOR(LDO5, max8997_ldo_ops), - MAX8997_VOLTAGE_REGULATOR(LDO6, max8997_ldo_ops), - MAX8997_VOLTAGE_REGULATOR(LDO7, max8997_ldo_ops), - MAX8997_VOLTAGE_REGULATOR(LDO8, max8997_ldo_ops), - MAX8997_VOLTAGE_REGULATOR(LDO9, max8997_ldo_ops), - MAX8997_VOLTAGE_REGULATOR(LDO10, max8997_ldo_ops), - MAX8997_VOLTAGE_REGULATOR(LDO11, max8997_ldo_ops), - MAX8997_VOLTAGE_REGULATOR(LDO12, max8997_ldo_ops), - MAX8997_VOLTAGE_REGULATOR(LDO13, max8997_ldo_ops), - MAX8997_VOLTAGE_REGULATOR(LDO14, max8997_ldo_ops), - MAX8997_VOLTAGE_REGULATOR(LDO15, max8997_ldo_ops), - MAX8997_VOLTAGE_REGULATOR(LDO16, max8997_ldo_ops), - MAX8997_VOLTAGE_REGULATOR(LDO17, max8997_ldo_ops), - MAX8997_VOLTAGE_REGULATOR(LDO18, max8997_ldo_ops), - MAX8997_VOLTAGE_REGULATOR(LDO21, max8997_ldo_ops), - MAX8997_VOLTAGE_REGULATOR(BUCK1, max8997_buck_ops), - MAX8997_VOLTAGE_REGULATOR(BUCK2, max8997_buck_ops), - MAX8997_VOLTAGE_REGULATOR(BUCK3, max8997_buck_ops), - MAX8997_VOLTAGE_REGULATOR(BUCK4, max8997_buck_ops), - MAX8997_VOLTAGE_REGULATOR(BUCK5, max8997_buck_ops), - MAX8997_VOLTAGE_REGULATOR(BUCK6, max8997_fixedvolt_ops), - MAX8997_VOLTAGE_REGULATOR(BUCK7, max8997_buck_ops), - MAX8997_VOLTAGE_REGULATOR(EN32KHZ_AP, max8997_fixedvolt_ops), - MAX8997_VOLTAGE_REGULATOR(EN32KHZ_CP, max8997_fixedvolt_ops), - MAX8997_VOLTAGE_REGULATOR(ENVICHG, max8997_fixedvolt_ops), - MAX8997_VOLTAGE_REGULATOR(ESAFEOUT1, max8997_safeout_ops), - MAX8997_VOLTAGE_REGULATOR(ESAFEOUT2, max8997_safeout_ops), - MAX8997_VOLTAGE_REGULATOR(CHARGER_CV, max8997_fixedstate_ops), - MAX8997_CURRENT_REGULATOR(CHARGER, max8997_charger_ops), - MAX8997_CURRENT_REGULATOR(CHARGER_TOPOFF, - max8997_charger_fixedstate_ops), + regulator_desc_ldo(1), + regulator_desc_ldo(2), + regulator_desc_ldo(3), + regulator_desc_ldo(4), + regulator_desc_ldo(5), + regulator_desc_ldo(6), + regulator_desc_ldo(7), + regulator_desc_ldo(8), + regulator_desc_ldo(9), + regulator_desc_ldo(10), + regulator_desc_ldo(11), + regulator_desc_ldo(12), + regulator_desc_ldo(13), + regulator_desc_ldo(14), + regulator_desc_ldo(15), + regulator_desc_ldo(16), + regulator_desc_ldo(17), + regulator_desc_ldo(18), + regulator_desc_ldo(21), + regulator_desc_buck(1), + regulator_desc_buck(2), + regulator_desc_buck(3), + regulator_desc_buck(4), + regulator_desc_buck(5), + { + .name = "BUCK6", + .id = MAX8997_BUCK6, + .ops = &max8997_fixedvolt_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + regulator_desc_buck(7), + { + .name = "EN32KHz_AP", + .id = MAX8997_EN32KHZ_AP, + .ops = &max8997_fixedvolt_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, { + .name = "EN32KHz_CP", + .id = MAX8997_EN32KHZ_CP, + .ops = &max8997_fixedvolt_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, { + .name = "ENVICHG", + .id = MAX8997_ENVICHG, + .ops = &max8997_fixedvolt_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, { + .name = "ESAFEOUT1", + .id = MAX8997_ESAFEOUT1, + .ops = &max8997_safeout_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, { + .name = "ESAFEOUT2", + .id = MAX8997_ESAFEOUT2, + .ops = &max8997_safeout_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, { + .name = "CHARGER_CV", + .id = MAX8997_CHARGER_CV, + .ops = &max8997_fixedstate_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, { + .name = "CHARGER", + .id = MAX8997_CHARGER, + .ops = &max8997_charger_ops, + .type = REGULATOR_CURRENT, + .owner = THIS_MODULE, + }, { + .name = "CHARGER_TOPOFF", + .id = MAX8997_CHARGER_TOPOFF, + .ops = &max8997_charger_fixedstate_ops, + .type = REGULATOR_CURRENT, + .owner = THIS_MODULE, + }, }; static __devinit int max8997_pmic_probe(struct platform_device *pdev) { struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev); - struct regulator_config config = { }; struct regulator_dev **rdev; struct max8997_data *max8997; struct i2c_client *i2c; @@ -949,15 +968,16 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) return -ENODEV; } - max8997 = devm_kzalloc(&pdev->dev, sizeof(struct max8997_data), - GFP_KERNEL); + max8997 = kzalloc(sizeof(struct max8997_data), GFP_KERNEL); if (!max8997) return -ENOMEM; size = sizeof(struct regulator_dev *) * pdata->num_regulators; - max8997->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); - if (!max8997->rdev) + max8997->rdev = kzalloc(size, GFP_KERNEL); + if (!max8997->rdev) { + kfree(max8997); return -ENOMEM; + } rdev = max8997->rdev; max8997->dev = &pdev->dev; @@ -981,7 +1001,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) pdata->buck1_voltage[i] / 1000 + buck1245_voltage_map_desc.step); if (ret < 0) - goto err_out; + goto err_alloc; max8997->buck2_vol[i] = ret = max8997_get_voltage_proper_val( @@ -990,7 +1010,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) pdata->buck2_voltage[i] / 1000 + buck1245_voltage_map_desc.step); if (ret < 0) - goto err_out; + goto err_alloc; max8997->buck5_vol[i] = ret = max8997_get_voltage_proper_val( @@ -999,7 +1019,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) pdata->buck5_voltage[i] / 1000 + buck1245_voltage_map_desc.step); if (ret < 0) - goto err_out; + goto err_alloc; if (max_buck1 < max8997->buck1_vol[i]) max_buck1 = max8997->buck1_vol[i]; @@ -1032,7 +1052,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) !gpio_is_valid(pdata->buck125_gpios[2])) { dev_err(&pdev->dev, "GPIO NOT VALID\n"); ret = -EINVAL; - goto err_out; + goto err_alloc; } ret = gpio_request(pdata->buck125_gpios[0], @@ -1041,7 +1061,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) dev_warn(&pdev->dev, "Duplicated gpio request" " on SET1\n"); else if (ret) - goto err_out; + goto err_alloc; else gpio1set = true; @@ -1053,7 +1073,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) else if (ret) { if (gpio1set) gpio_free(pdata->buck125_gpios[0]); - goto err_out; + goto err_alloc; } else gpio2set = true; @@ -1067,7 +1087,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) gpio_free(pdata->buck125_gpios[0]); if (gpio2set) gpio_free(pdata->buck125_gpios[1]); - goto err_out; + goto err_alloc; } gpio_direction_output(pdata->buck125_gpios[0], @@ -1120,11 +1140,8 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) else if (id == MAX8997_CHARGER_CV) regulators[id].n_voltages = 16; - config.dev = max8997->dev; - config.init_data = pdata->regulators[i].initdata; - config.driver_data = max8997; - - rdev[i] = regulator_register(®ulators[id], &config); + rdev[i] = regulator_register(®ulators[id], max8997->dev, + pdata->regulators[i].initdata, max8997, NULL); if (IS_ERR(rdev[i])) { ret = PTR_ERR(rdev[i]); dev_err(max8997->dev, "regulator init failed for %d\n", @@ -1136,9 +1153,13 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) return 0; err: - while (--i >= 0) - regulator_unregister(rdev[i]); -err_out: + for (i = 0; i < max8997->num_regulators; i++) + if (rdev[i]) + regulator_unregister(rdev[i]); +err_alloc: + kfree(max8997->rdev); + kfree(max8997); + return ret; } @@ -1149,7 +1170,12 @@ static int __devexit max8997_pmic_remove(struct platform_device *pdev) int i; for (i = 0; i < max8997->num_regulators; i++) - regulator_unregister(rdev[i]); + if (rdev[i]) + regulator_unregister(rdev[i]); + + kfree(max8997->rdev); + kfree(max8997); + return 0; } diff --git a/trunk/drivers/regulator/max8998.c b/trunk/drivers/regulator/max8998.c index 18bb58b9b96e..5890265eeacc 100644 --- a/trunk/drivers/regulator/max8998.c +++ b/trunk/drivers/regulator/max8998.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -276,7 +277,7 @@ static int max8998_get_voltage_register(struct regulator_dev *rdev, return 0; } -static int max8998_get_voltage_sel(struct regulator_dev *rdev) +static int max8998_get_voltage(struct regulator_dev *rdev) { struct max8998_data *max8998 = rdev_get_drvdata(rdev); struct i2c_client *i2c = max8998->iodev->i2c; @@ -294,7 +295,7 @@ static int max8998_get_voltage_sel(struct regulator_dev *rdev) val >>= shift; val &= mask; - return val; + return max8998_list_voltage(rdev, val); } static int max8998_set_voltage_ldo(struct regulator_dev *rdev, @@ -305,7 +306,8 @@ static int max8998_set_voltage_ldo(struct regulator_dev *rdev, int min_vol = min_uV / 1000, max_vol = max_uV / 1000; const struct voltage_map_desc *desc; int ldo = rdev_get_id(rdev); - int reg, shift = 0, mask, ret, i; + int reg, shift = 0, mask, ret; + int i = 0; if (ldo >= ARRAY_SIZE(ldo_voltage_map)) return -EINVAL; @@ -317,10 +319,9 @@ static int max8998_set_voltage_ldo(struct regulator_dev *rdev, if (max_vol < desc->min || min_vol > desc->max) return -EINVAL; - if (min_vol < desc->min) - min_vol = desc->min; - - i = DIV_ROUND_UP(min_vol - desc->min, desc->step); + while (desc->min + desc->step*i < min_vol && + desc->min + desc->step*i < desc->max) + i++; if (desc->min + desc->step*i > max_vol) return -EINVAL; @@ -358,7 +359,8 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev, const struct voltage_map_desc *desc; int buck = rdev_get_id(rdev); int reg, shift = 0, mask, ret; - int i, j, previous_sel; + int difference = 0, i = 0, j = 0, previous_vol = 0; + u8 val = 0; static u8 buck1_last_val; if (buck >= ARRAY_SIZE(ldo_voltage_map)) @@ -372,10 +374,9 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev, if (max_vol < desc->min || min_vol > desc->max) return -EINVAL; - if (min_vol < desc->min) - min_vol = desc->min; - - i = DIV_ROUND_UP(min_vol - desc->min, desc->step); + while (desc->min + desc->step*i < min_vol && + desc->min + desc->step*i < desc->max) + i++; if (desc->min + desc->step*i > max_vol) return -EINVAL; @@ -386,14 +387,13 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev, if (ret) return ret; - previous_sel = max8998_get_voltage_sel(rdev); + previous_vol = max8998_get_voltage(rdev); /* Check if voltage needs to be changed */ /* if previous_voltage equal new voltage, return */ - if (previous_sel == i) { + if (previous_vol == max8998_list_voltage(rdev, i)) { dev_dbg(max8998->dev, "No voltage change, old:%d, new:%d\n", - max8998_list_voltage(rdev, previous_sel), - max8998_list_voltage(rdev, i)); + previous_vol, max8998_list_voltage(rdev, i)); return ret; } @@ -482,40 +482,19 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev, break; } - return ret; -} - -static int max8998_set_voltage_buck_time_sel(struct regulator_dev *rdev, - unsigned int old_selector, - unsigned int new_selector) -{ - struct max8998_data *max8998 = rdev_get_drvdata(rdev); - struct i2c_client *i2c = max8998->iodev->i2c; - const struct voltage_map_desc *desc; - int buck = rdev_get_id(rdev); - u8 val = 0; - int difference, ret; - - if (buck < MAX8998_BUCK1 || buck > MAX8998_BUCK4) - return -EINVAL; - - desc = ldo_voltage_map[buck]; - /* Voltage stabilization */ - ret = max8998_read_reg(i2c, MAX8998_REG_ONOFF4, &val); - if (ret) - return ret; + max8998_read_reg(i2c, MAX8998_REG_ONOFF4, &val); /* lp3974 hasn't got ENRAMP bit - ramp is assumed as true */ /* MAX8998 has ENRAMP bit implemented, so test it*/ if (max8998->iodev->type == TYPE_MAX8998 && !(val & MAX8998_ENRAMP)) - return 0; + return ret; - difference = (new_selector - old_selector) * desc->step; + difference = desc->min + desc->step*i - previous_vol/1000; if (difference > 0) - return difference / ((val & 0x0f) + 1); + udelay(difference / ((val & 0x0f) + 1)); - return 0; + return ret; } static struct regulator_ops max8998_ldo_ops = { @@ -523,7 +502,7 @@ static struct regulator_ops max8998_ldo_ops = { .is_enabled = max8998_ldo_is_enabled, .enable = max8998_ldo_enable, .disable = max8998_ldo_disable, - .get_voltage_sel = max8998_get_voltage_sel, + .get_voltage = max8998_get_voltage, .set_voltage = max8998_set_voltage_ldo, .set_suspend_enable = max8998_ldo_enable, .set_suspend_disable = max8998_ldo_disable, @@ -534,9 +513,8 @@ static struct regulator_ops max8998_buck_ops = { .is_enabled = max8998_ldo_is_enabled, .enable = max8998_ldo_enable, .disable = max8998_ldo_disable, - .get_voltage_sel = max8998_get_voltage_sel, + .get_voltage = max8998_get_voltage, .set_voltage = max8998_set_voltage_buck, - .set_voltage_time_sel = max8998_set_voltage_buck_time_sel, .set_suspend_enable = max8998_ldo_enable, .set_suspend_disable = max8998_ldo_disable, }; @@ -707,7 +685,6 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) { struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev); - struct regulator_config config = { }; struct regulator_dev **rdev; struct max8998_data *max8998; struct i2c_client *i2c; @@ -718,15 +695,16 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) return -ENODEV; } - max8998 = devm_kzalloc(&pdev->dev, sizeof(struct max8998_data), - GFP_KERNEL); + max8998 = kzalloc(sizeof(struct max8998_data), GFP_KERNEL); if (!max8998) return -ENOMEM; size = sizeof(struct regulator_dev *) * pdata->num_regulators; - max8998->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); - if (!max8998->rdev) + max8998->rdev = kzalloc(size, GFP_KERNEL); + if (!max8998->rdev) { + kfree(max8998); return -ENOMEM; + } rdev = max8998->rdev; max8998->dev = &pdev->dev; @@ -750,14 +728,14 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) printk(KERN_ERR "MAX8998 SET1 GPIO defined as 0 !\n"); WARN_ON(!pdata->buck1_set1); ret = -EIO; - goto err_out; + goto err_free_mem; } /* Check if SET2 is not equal to 0 */ if (!pdata->buck1_set2) { printk(KERN_ERR "MAX8998 SET2 GPIO defined as 0 !\n"); WARN_ON(!pdata->buck1_set2); ret = -EIO; - goto err_out; + goto err_free_mem; } gpio_request(pdata->buck1_set1, "MAX8998 BUCK1_SET1"); @@ -777,7 +755,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) max8998->buck1_vol[0] = i; ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i); if (ret) - goto err_out; + goto err_free_mem; /* Set predefined value for BUCK1 register 2 */ i = 0; @@ -789,7 +767,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) max8998->buck1_vol[1] = i; ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE2, i); if (ret) - goto err_out; + goto err_free_mem; /* Set predefined value for BUCK1 register 3 */ i = 0; @@ -801,7 +779,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) max8998->buck1_vol[2] = i; ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE3, i); if (ret) - goto err_out; + goto err_free_mem; /* Set predefined value for BUCK1 register 4 */ i = 0; @@ -813,7 +791,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) max8998->buck1_vol[3] = i; ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE4, i); if (ret) - goto err_out; + goto err_free_mem; } @@ -823,7 +801,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) printk(KERN_ERR "MAX8998 SET3 GPIO defined as 0 !\n"); WARN_ON(!pdata->buck2_set3); ret = -EIO; - goto err_out; + goto err_free_mem; } gpio_request(pdata->buck2_set3, "MAX8998 BUCK2_SET3"); gpio_direction_output(pdata->buck2_set3, @@ -838,7 +816,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) max8998->buck2_vol[0] = i; ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i); if (ret) - goto err_out; + goto err_free_mem; /* BUCK2 register 2 */ i = 0; @@ -849,7 +827,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) max8998->buck2_vol[1] = i; ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, i); if (ret) - goto err_out; + goto err_free_mem; } for (i = 0; i < pdata->num_regulators; i++) { @@ -862,12 +840,8 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) int count = (desc->max - desc->min) / desc->step + 1; regulators[index].n_voltages = count; } - - config.dev = max8998->dev; - config.init_data = pdata->regulators[i].initdata; - config.driver_data = max8998; - - rdev[i] = regulator_register(®ulators[index], &config); + rdev[i] = regulator_register(®ulators[index], max8998->dev, + pdata->regulators[i].initdata, max8998, NULL); if (IS_ERR(rdev[i])) { ret = PTR_ERR(rdev[i]); dev_err(max8998->dev, "regulator init failed\n"); @@ -879,9 +853,14 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) return 0; err: - while (--i >= 0) - regulator_unregister(rdev[i]); -err_out: + for (i = 0; i < max8998->num_regulators; i++) + if (rdev[i]) + regulator_unregister(rdev[i]); + +err_free_mem: + kfree(max8998->rdev); + kfree(max8998); + return ret; } @@ -892,7 +871,12 @@ static int __devexit max8998_pmic_remove(struct platform_device *pdev) int i; for (i = 0; i < max8998->num_regulators; i++) - regulator_unregister(rdev[i]); + if (rdev[i]) + regulator_unregister(rdev[i]); + + kfree(max8998->rdev); + kfree(max8998); + return 0; } diff --git a/trunk/drivers/regulator/mc13783-regulator.c b/trunk/drivers/regulator/mc13783-regulator.c index 7dcdfa283e93..6c0face87ffe 100644 --- a/trunk/drivers/regulator/mc13783-regulator.c +++ b/trunk/drivers/regulator/mc13783-regulator.c @@ -340,7 +340,6 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev) struct mc13xxx_regulator_platform_data *pdata = dev_get_platdata(&pdev->dev); struct mc13xxx_regulator_init_data *init_data; - struct regulator_config config = { }; int i, ret; dev_dbg(&pdev->dev, "%s id %d\n", __func__, pdev->id); @@ -358,16 +357,11 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev) priv->mc13xxx = mc13783; for (i = 0; i < pdata->num_regulators; i++) { - struct regulator_desc *desc; - init_data = &pdata->regulators[i]; - desc = &mc13783_regulators[init_data->id].desc; - - config.dev = &pdev->dev; - config.init_data = init_data->init_data; - config.driver_data = priv; + priv->regulators[i] = regulator_register( + &mc13783_regulators[init_data->id].desc, + &pdev->dev, init_data->init_data, priv, NULL); - priv->regulators[i] = regulator_register(desc, &config); if (IS_ERR(priv->regulators[i])) { dev_err(&pdev->dev, "failed to register regulator %s\n", mc13783_regulators[i].desc.name); diff --git a/trunk/drivers/regulator/mc13892-regulator.c b/trunk/drivers/regulator/mc13892-regulator.c index 970a233dbe46..845aa2263b8a 100644 --- a/trunk/drivers/regulator/mc13892-regulator.c +++ b/trunk/drivers/regulator/mc13892-regulator.c @@ -428,15 +428,24 @@ static int mc13892_sw_regulator_get_voltage(struct regulator_dev *rdev) return val; } -static int mc13892_sw_regulator_set_voltage_sel(struct regulator_dev *rdev, - unsigned selector) +static int mc13892_sw_regulator_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned *selector) { struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); int hi, value, mask, id = rdev_get_id(rdev); u32 valread; int ret; - value = mc13892_regulators[id].voltages[selector]; + dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", + __func__, id, min_uV, max_uV); + + /* Find the best index */ + value = mc13xxx_get_best_voltage_index(rdev, min_uV, max_uV); + dev_dbg(rdev_get_dev(rdev), "%s best value: %d\n", __func__, value); + if (value < 0) + return value; + + value = mc13892_regulators[id].voltages[value]; mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_read(priv->mc13xxx, @@ -471,7 +480,7 @@ static int mc13892_sw_regulator_set_voltage_sel(struct regulator_dev *rdev, static struct regulator_ops mc13892_sw_regulator_ops = { .is_enabled = mc13xxx_sw_regulator_is_enabled, .list_voltage = mc13xxx_regulator_list_voltage, - .set_voltage_sel = mc13892_sw_regulator_set_voltage_sel, + .set_voltage = mc13892_sw_regulator_set_voltage, .get_voltage = mc13892_sw_regulator_get_voltage, }; @@ -519,7 +528,6 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev) struct mc13xxx_regulator_platform_data *pdata = dev_get_platdata(&pdev->dev); struct mc13xxx_regulator_init_data *mc13xxx_data; - struct regulator_config config = { }; int i, ret; int num_regulators = 0; u32 val; @@ -589,12 +597,9 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev) } desc = &mc13892_regulators[id].desc; - config.dev = &pdev->dev; - config.init_data = init_data; - config.driver_data = priv; - config.of_node = node; + priv->regulators[i] = regulator_register( + desc, &pdev->dev, init_data, priv, node); - priv->regulators[i] = regulator_register(desc, &config); if (IS_ERR(priv->regulators[i])) { dev_err(&pdev->dev, "failed to register regulator %s\n", mc13892_regulators[i].desc.name); diff --git a/trunk/drivers/regulator/mc13xxx-regulator-core.c b/trunk/drivers/regulator/mc13xxx-regulator-core.c index 4fa9704739bc..62dcd0a432bb 100644 --- a/trunk/drivers/regulator/mc13xxx-regulator-core.c +++ b/trunk/drivers/regulator/mc13xxx-regulator-core.c @@ -94,18 +94,62 @@ int mc13xxx_regulator_list_voltage(struct regulator_dev *rdev, } EXPORT_SYMBOL_GPL(mc13xxx_regulator_list_voltage); -static int mc13xxx_regulator_set_voltage_sel(struct regulator_dev *rdev, - unsigned selector) +int mc13xxx_get_best_voltage_index(struct regulator_dev *rdev, + int min_uV, int max_uV) { struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; - int id = rdev_get_id(rdev); + int reg_id = rdev_get_id(rdev); + int i; + int bestmatch; + int bestindex; + + /* + * Locate the minimum voltage fitting the criteria on + * this regulator. The switchable voltages are not + * in strict falling order so we need to check them + * all for the best match. + */ + bestmatch = INT_MAX; + bestindex = -1; + for (i = 0; i < mc13xxx_regulators[reg_id].desc.n_voltages; i++) { + if (mc13xxx_regulators[reg_id].voltages[i] >= min_uV && + mc13xxx_regulators[reg_id].voltages[i] < bestmatch) { + bestmatch = mc13xxx_regulators[reg_id].voltages[i]; + bestindex = i; + } + } + + if (bestindex < 0 || bestmatch > max_uV) { + dev_warn(&rdev->dev, "no possible value for %d<=x<=%d uV\n", + min_uV, max_uV); + return -EINVAL; + } + return bestindex; +} +EXPORT_SYMBOL_GPL(mc13xxx_get_best_voltage_index); + +static int mc13xxx_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, + int max_uV, unsigned *selector) +{ + struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); + struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; + int value, id = rdev_get_id(rdev); int ret; + dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", + __func__, id, min_uV, max_uV); + + /* Find the best index */ + value = mc13xxx_get_best_voltage_index(rdev, min_uV, max_uV); + dev_dbg(rdev_get_dev(rdev), "%s best value: %d\n", __func__, value); + if (value < 0) + return value; + mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].vsel_reg, mc13xxx_regulators[id].vsel_mask, - selector << mc13xxx_regulators[id].vsel_shift); + value << mc13xxx_regulators[id].vsel_shift); mc13xxx_unlock(priv->mc13xxx); return ret; @@ -143,7 +187,7 @@ struct regulator_ops mc13xxx_regulator_ops = { .disable = mc13xxx_regulator_disable, .is_enabled = mc13xxx_regulator_is_enabled, .list_voltage = mc13xxx_regulator_list_voltage, - .set_voltage_sel = mc13xxx_regulator_set_voltage_sel, + .set_voltage = mc13xxx_regulator_set_voltage, .get_voltage = mc13xxx_regulator_get_voltage, }; EXPORT_SYMBOL_GPL(mc13xxx_regulator_ops); diff --git a/trunk/drivers/regulator/mc13xxx.h b/trunk/drivers/regulator/mc13xxx.h index 044aba4d28ec..b3961c658b05 100644 --- a/trunk/drivers/regulator/mc13xxx.h +++ b/trunk/drivers/regulator/mc13xxx.h @@ -35,6 +35,8 @@ struct mc13xxx_regulator_priv { extern int mc13xxx_sw_regulator(struct regulator_dev *rdev); extern int mc13xxx_sw_regulator_is_enabled(struct regulator_dev *rdev); +extern int mc13xxx_get_best_voltage_index(struct regulator_dev *rdev, + int min_uV, int max_uV); extern int mc13xxx_regulator_list_voltage(struct regulator_dev *rdev, unsigned selector); extern int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev, diff --git a/trunk/drivers/regulator/of_regulator.c b/trunk/drivers/regulator/of_regulator.c index 56593b75168a..679734d26a16 100644 --- a/trunk/drivers/regulator/of_regulator.c +++ b/trunk/drivers/regulator/of_regulator.c @@ -14,7 +14,6 @@ #include #include #include -#include static void of_get_regulation_constraints(struct device_node *np, struct regulator_init_data **init_data) @@ -86,49 +85,3 @@ struct regulator_init_data *of_get_regulator_init_data(struct device *dev, return init_data; } EXPORT_SYMBOL_GPL(of_get_regulator_init_data); - -/** - * of_regulator_match - extract regulator init data - * @dev: device requesting the data - * @node: parent device node of the regulators - * @matches: match table for the regulators - * @num_matches: number of entries in match table - * - * This function uses a match table specified by the regulator driver and - * looks up the corresponding init data in the device tree. Note that the - * match table is modified in place. - * - * Returns the number of matches found or a negative error code on failure. - */ -int of_regulator_match(struct device *dev, struct device_node *node, - struct of_regulator_match *matches, - unsigned int num_matches) -{ - unsigned int count = 0; - unsigned int i; - - if (!dev || !node) - return -EINVAL; - - for (i = 0; i < num_matches; i++) { - struct of_regulator_match *match = &matches[i]; - struct device_node *child; - - child = of_find_node_by_name(node, match->name); - if (!child) - continue; - - match->init_data = of_get_regulator_init_data(dev, child); - if (!match->init_data) { - dev_err(dev, "failed to parse DT for regulator %s\n", - child->name); - return -EINVAL; - } - - match->of_node = child; - count++; - } - - return count; -} -EXPORT_SYMBOL_GPL(of_regulator_match); diff --git a/trunk/drivers/regulator/palmas-regulator.c b/trunk/drivers/regulator/palmas-regulator.c deleted file mode 100644 index c4435f608df7..000000000000 --- a/trunk/drivers/regulator/palmas-regulator.c +++ /dev/null @@ -1,822 +0,0 @@ -/* - * Driver for Regulator part of Palmas PMIC Chips - * - * Copyright 2011-2012 Texas Instruments Inc. - * - * Author: Graeme Gregory - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct regs_info { - char *name; - u8 vsel_addr; - u8 ctrl_addr; - u8 tstep_addr; -}; - -static const struct regs_info palmas_regs_info[] = { - { - .name = "SMPS12", - .vsel_addr = PALMAS_SMPS12_VOLTAGE, - .ctrl_addr = PALMAS_SMPS12_CTRL, - .tstep_addr = PALMAS_SMPS12_TSTEP, - }, - { - .name = "SMPS123", - .vsel_addr = PALMAS_SMPS12_VOLTAGE, - .ctrl_addr = PALMAS_SMPS12_CTRL, - .tstep_addr = PALMAS_SMPS12_TSTEP, - }, - { - .name = "SMPS3", - .vsel_addr = PALMAS_SMPS3_VOLTAGE, - .ctrl_addr = PALMAS_SMPS3_CTRL, - }, - { - .name = "SMPS45", - .vsel_addr = PALMAS_SMPS45_VOLTAGE, - .ctrl_addr = PALMAS_SMPS45_CTRL, - .tstep_addr = PALMAS_SMPS45_TSTEP, - }, - { - .name = "SMPS457", - .vsel_addr = PALMAS_SMPS45_VOLTAGE, - .ctrl_addr = PALMAS_SMPS45_CTRL, - .tstep_addr = PALMAS_SMPS45_TSTEP, - }, - { - .name = "SMPS6", - .vsel_addr = PALMAS_SMPS6_VOLTAGE, - .ctrl_addr = PALMAS_SMPS6_CTRL, - .tstep_addr = PALMAS_SMPS6_TSTEP, - }, - { - .name = "SMPS7", - .vsel_addr = PALMAS_SMPS7_VOLTAGE, - .ctrl_addr = PALMAS_SMPS7_CTRL, - }, - { - .name = "SMPS8", - .vsel_addr = PALMAS_SMPS8_VOLTAGE, - .ctrl_addr = PALMAS_SMPS8_CTRL, - .tstep_addr = PALMAS_SMPS8_TSTEP, - }, - { - .name = "SMPS9", - .vsel_addr = PALMAS_SMPS9_VOLTAGE, - .ctrl_addr = PALMAS_SMPS9_CTRL, - }, - { - .name = "SMPS10", - }, - { - .name = "LDO1", - .vsel_addr = PALMAS_LDO1_VOLTAGE, - .ctrl_addr = PALMAS_LDO1_CTRL, - }, - { - .name = "LDO2", - .vsel_addr = PALMAS_LDO2_VOLTAGE, - .ctrl_addr = PALMAS_LDO2_CTRL, - }, - { - .name = "LDO3", - .vsel_addr = PALMAS_LDO3_VOLTAGE, - .ctrl_addr = PALMAS_LDO3_CTRL, - }, - { - .name = "LDO4", - .vsel_addr = PALMAS_LDO4_VOLTAGE, - .ctrl_addr = PALMAS_LDO4_CTRL, - }, - { - .name = "LDO5", - .vsel_addr = PALMAS_LDO5_VOLTAGE, - .ctrl_addr = PALMAS_LDO5_CTRL, - }, - { - .name = "LDO6", - .vsel_addr = PALMAS_LDO6_VOLTAGE, - .ctrl_addr = PALMAS_LDO6_CTRL, - }, - { - .name = "LDO7", - .vsel_addr = PALMAS_LDO7_VOLTAGE, - .ctrl_addr = PALMAS_LDO7_CTRL, - }, - { - .name = "LDO8", - .vsel_addr = PALMAS_LDO8_VOLTAGE, - .ctrl_addr = PALMAS_LDO8_CTRL, - }, - { - .name = "LDO9", - .vsel_addr = PALMAS_LDO9_VOLTAGE, - .ctrl_addr = PALMAS_LDO9_CTRL, - }, - { - .name = "LDOLN", - .vsel_addr = PALMAS_LDOLN_VOLTAGE, - .ctrl_addr = PALMAS_LDOLN_CTRL, - }, - { - .name = "LDOUSB", - .vsel_addr = PALMAS_LDOUSB_VOLTAGE, - .ctrl_addr = PALMAS_LDOUSB_CTRL, - }, -}; - -#define SMPS_CTRL_MODE_OFF 0x00 -#define SMPS_CTRL_MODE_ON 0x01 -#define SMPS_CTRL_MODE_ECO 0x02 -#define SMPS_CTRL_MODE_PWM 0x03 - -/* These values are derived from the data sheet. And are the number of steps - * where there is a voltage change, the ranges at beginning and end of register - * max/min values where there are no change are ommitted. - * - * So they are basically (maxV-minV)/stepV - */ -#define PALMAS_SMPS_NUM_VOLTAGES 116 -#define PALMAS_SMPS10_NUM_VOLTAGES 2 -#define PALMAS_LDO_NUM_VOLTAGES 50 - -#define SMPS10_VSEL (1<<3) -#define SMPS10_BOOST_EN (1<<2) -#define SMPS10_BYPASS_EN (1<<1) -#define SMPS10_SWITCH_EN (1<<0) - -#define REGULATOR_SLAVE 0 - -static int palmas_smps_read(struct palmas *palmas, unsigned int reg, - unsigned int *dest) -{ - unsigned int addr; - - addr = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, reg); - - return regmap_read(palmas->regmap[REGULATOR_SLAVE], addr, dest); -} - -static int palmas_smps_write(struct palmas *palmas, unsigned int reg, - unsigned int value) -{ - unsigned int addr; - - addr = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, reg); - - return regmap_write(palmas->regmap[REGULATOR_SLAVE], addr, value); -} - -static int palmas_ldo_read(struct palmas *palmas, unsigned int reg, - unsigned int *dest) -{ - unsigned int addr; - - addr = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, reg); - - return regmap_read(palmas->regmap[REGULATOR_SLAVE], addr, dest); -} - -static int palmas_ldo_write(struct palmas *palmas, unsigned int reg, - unsigned int value) -{ - unsigned int addr; - - addr = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, reg); - - return regmap_write(palmas->regmap[REGULATOR_SLAVE], addr, value); -} - -static int palmas_is_enabled_smps(struct regulator_dev *dev) -{ - struct palmas_pmic *pmic = rdev_get_drvdata(dev); - int id = rdev_get_id(dev); - unsigned int reg; - - palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, ®); - - reg &= PALMAS_SMPS12_CTRL_STATUS_MASK; - reg >>= PALMAS_SMPS12_CTRL_STATUS_SHIFT; - - return !!(reg); -} - -static int palmas_enable_smps(struct regulator_dev *dev) -{ - struct palmas_pmic *pmic = rdev_get_drvdata(dev); - int id = rdev_get_id(dev); - unsigned int reg; - - palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, ®); - - reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; - reg |= SMPS_CTRL_MODE_ON; - - palmas_smps_write(pmic->palmas, palmas_regs_info[id].ctrl_addr, reg); - - return 0; -} - -static int palmas_disable_smps(struct regulator_dev *dev) -{ - struct palmas_pmic *pmic = rdev_get_drvdata(dev); - int id = rdev_get_id(dev); - unsigned int reg; - - palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, ®); - - reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; - - palmas_smps_write(pmic->palmas, palmas_regs_info[id].ctrl_addr, reg); - - return 0; -} - - -static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode) -{ - struct palmas_pmic *pmic = rdev_get_drvdata(dev); - int id = rdev_get_id(dev); - unsigned int reg; - - palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, ®); - reg &= ~PALMAS_SMPS12_CTRL_STATUS_MASK; - reg >>= PALMAS_SMPS12_CTRL_STATUS_SHIFT; - - switch (mode) { - case REGULATOR_MODE_NORMAL: - reg |= SMPS_CTRL_MODE_ON; - break; - case REGULATOR_MODE_IDLE: - reg |= SMPS_CTRL_MODE_ECO; - break; - case REGULATOR_MODE_FAST: - reg |= SMPS_CTRL_MODE_PWM; - break; - default: - return -EINVAL; - } - palmas_smps_write(pmic->palmas, palmas_regs_info[id].ctrl_addr, reg); - - return 0; -} - -static unsigned int palmas_get_mode_smps(struct regulator_dev *dev) -{ - struct palmas_pmic *pmic = rdev_get_drvdata(dev); - int id = rdev_get_id(dev); - unsigned int reg; - - palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, ®); - reg &= PALMAS_SMPS12_CTRL_STATUS_MASK; - reg >>= PALMAS_SMPS12_CTRL_STATUS_SHIFT; - - switch (reg) { - case SMPS_CTRL_MODE_ON: - return REGULATOR_MODE_NORMAL; - case SMPS_CTRL_MODE_ECO: - return REGULATOR_MODE_IDLE; - case SMPS_CTRL_MODE_PWM: - return REGULATOR_MODE_FAST; - } - - return 0; -} - -static int palmas_list_voltage_smps(struct regulator_dev *dev, - unsigned selector) -{ - struct palmas_pmic *pmic = rdev_get_drvdata(dev); - int id = rdev_get_id(dev); - int mult = 1; - - if (!selector) - return 0; - - /* Read the multiplier set in VSEL register to return - * the correct voltage. - */ - if (pmic->range[id]) - mult = 2; - - /* Voltage is (0.49V + (selector * 0.01V)) * RANGE - * as defined in data sheet. RANGE is either x1 or x2 - */ - return (490000 + (selector * 10000)) * mult; -} - -static int palmas_get_voltage_smps_sel(struct regulator_dev *dev) -{ - struct palmas_pmic *pmic = rdev_get_drvdata(dev); - int id = rdev_get_id(dev); - int selector; - unsigned int reg; - unsigned int addr; - - addr = palmas_regs_info[id].vsel_addr; - - palmas_smps_read(pmic->palmas, addr, ®); - - selector = reg & PALMAS_SMPS12_VOLTAGE_VSEL_MASK; - - /* Adjust selector to match list_voltage ranges */ - if ((selector > 0) && (selector < 6)) - selector = 6; - if (!selector) - selector = 5; - if (selector > 121) - selector = 121; - selector -= 5; - - return selector; -} - -static int palmas_set_voltage_smps_sel(struct regulator_dev *dev, - unsigned selector) -{ - struct palmas_pmic *pmic = rdev_get_drvdata(dev); - int id = rdev_get_id(dev); - unsigned int reg = 0; - unsigned int addr; - - addr = palmas_regs_info[id].vsel_addr; - - /* Make sure we don't change the value of RANGE */ - if (pmic->range[id]) - reg |= PALMAS_SMPS12_VOLTAGE_RANGE; - - /* Adjust the linux selector into range used in VSEL register */ - if (selector) - reg |= selector + 5; - - palmas_smps_write(pmic->palmas, addr, reg); - - return 0; -} - -static int palmas_map_voltage_smps(struct regulator_dev *rdev, - int min_uV, int max_uV) -{ - int ret, voltage; - - ret = ((min_uV - 500000) / 10000) + 1; - if (ret < 0) - return ret; - - /* Map back into a voltage to verify we're still in bounds */ - voltage = palmas_list_voltage_smps(rdev, ret); - if (voltage < min_uV || voltage > max_uV) - return -EINVAL; - - return ret; -} - -static struct regulator_ops palmas_ops_smps = { - .is_enabled = palmas_is_enabled_smps, - .enable = palmas_enable_smps, - .disable = palmas_disable_smps, - .set_mode = palmas_set_mode_smps, - .get_mode = palmas_get_mode_smps, - .get_voltage_sel = palmas_get_voltage_smps_sel, - .set_voltage_sel = palmas_set_voltage_smps_sel, - .list_voltage = palmas_list_voltage_smps, - .map_voltage = palmas_map_voltage_smps, -}; - -static int palmas_list_voltage_smps10(struct regulator_dev *dev, - unsigned selector) -{ - return 3750000 + (selector * 1250000); -} - -static struct regulator_ops palmas_ops_smps10 = { - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .list_voltage = palmas_list_voltage_smps10, -}; - -static int palmas_is_enabled_ldo(struct regulator_dev *dev) -{ - struct palmas_pmic *pmic = rdev_get_drvdata(dev); - int id = rdev_get_id(dev); - unsigned int reg; - - palmas_ldo_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, ®); - - reg &= PALMAS_LDO1_CTRL_STATUS; - - return !!(reg); -} - -static int palmas_list_voltage_ldo(struct regulator_dev *dev, - unsigned selector) -{ - if (!selector) - return 0; - - /* voltage is 0.85V + (selector * 0.05v) */ - return 850000 + (selector * 50000); -} - -static int palmas_get_voltage_ldo_sel(struct regulator_dev *dev) -{ - struct palmas_pmic *pmic = rdev_get_drvdata(dev); - int id = rdev_get_id(dev); - int selector; - unsigned int reg; - unsigned int addr; - - addr = palmas_regs_info[id].vsel_addr; - - palmas_ldo_read(pmic->palmas, addr, ®); - - selector = reg & PALMAS_LDO1_VOLTAGE_VSEL_MASK; - - /* Adjust selector to match list_voltage ranges */ - if (selector > 49) - selector = 49; - - return selector; -} - -static int palmas_set_voltage_ldo_sel(struct regulator_dev *dev, - unsigned selector) -{ - struct palmas_pmic *pmic = rdev_get_drvdata(dev); - int id = rdev_get_id(dev); - unsigned int reg = 0; - unsigned int addr; - - addr = palmas_regs_info[id].vsel_addr; - - reg = selector; - - palmas_ldo_write(pmic->palmas, addr, reg); - - return 0; -} - -static int palmas_map_voltage_ldo(struct regulator_dev *rdev, - int min_uV, int max_uV) -{ - int ret, voltage; - - ret = ((min_uV - 900000) / 50000) + 1; - if (ret < 0) - return ret; - - /* Map back into a voltage to verify we're still in bounds */ - voltage = palmas_list_voltage_ldo(rdev, ret); - if (voltage < min_uV || voltage > max_uV) - return -EINVAL; - - return ret; -} - -static struct regulator_ops palmas_ops_ldo = { - .is_enabled = palmas_is_enabled_ldo, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .get_voltage_sel = palmas_get_voltage_ldo_sel, - .set_voltage_sel = palmas_set_voltage_ldo_sel, - .list_voltage = palmas_list_voltage_ldo, - .map_voltage = palmas_map_voltage_ldo, -}; - -/* - * setup the hardware based sleep configuration of the SMPS/LDO regulators - * from the platform data. This is different to the software based control - * supported by the regulator framework as it is controlled by toggling - * pins on the PMIC such as PREQ, SYSEN, ... - */ -static int palmas_smps_init(struct palmas *palmas, int id, - struct palmas_reg_init *reg_init) -{ - unsigned int reg; - unsigned int addr; - int ret; - - addr = palmas_regs_info[id].ctrl_addr; - - ret = palmas_smps_read(palmas, addr, ®); - if (ret) - return ret; - - if (id != PALMAS_REG_SMPS10) { - if (reg_init->warm_reset) - reg |= PALMAS_SMPS12_CTRL_WR_S; - - if (reg_init->roof_floor) - reg |= PALMAS_SMPS12_CTRL_ROOF_FLOOR_EN; - - if (reg_init->mode_sleep) { - reg &= ~PALMAS_SMPS12_CTRL_MODE_SLEEP_MASK; - reg |= reg_init->mode_sleep << - PALMAS_SMPS12_CTRL_MODE_SLEEP_SHIFT; - } - } else { - if (reg_init->mode_sleep) { - reg &= ~PALMAS_SMPS10_CTRL_MODE_SLEEP_MASK; - reg |= reg_init->mode_sleep << - PALMAS_SMPS10_CTRL_MODE_SLEEP_SHIFT; - } - - } - ret = palmas_smps_write(palmas, addr, reg); - if (ret) - return ret; - - if (palmas_regs_info[id].tstep_addr && reg_init->tstep) { - addr = palmas_regs_info[id].tstep_addr; - - reg = reg_init->tstep & PALMAS_SMPS12_TSTEP_TSTEP_MASK; - - ret = palmas_smps_write(palmas, addr, reg); - if (ret) - return ret; - } - - if (palmas_regs_info[id].vsel_addr && reg_init->vsel) { - addr = palmas_regs_info[id].vsel_addr; - - reg = reg_init->vsel; - - ret = palmas_smps_write(palmas, addr, reg); - if (ret) - return ret; - } - - - return 0; -} - -static int palmas_ldo_init(struct palmas *palmas, int id, - struct palmas_reg_init *reg_init) -{ - unsigned int reg; - unsigned int addr; - int ret; - - addr = palmas_regs_info[id].ctrl_addr; - - ret = palmas_smps_read(palmas, addr, ®); - if (ret) - return ret; - - if (reg_init->warm_reset) - reg |= PALMAS_LDO1_CTRL_WR_S; - - if (reg_init->mode_sleep) - reg |= PALMAS_LDO1_CTRL_MODE_SLEEP; - - ret = palmas_smps_write(palmas, addr, reg); - if (ret) - return ret; - - return 0; -} - -static __devinit int palmas_probe(struct platform_device *pdev) -{ - struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); - struct palmas_pmic_platform_data *pdata = pdev->dev.platform_data; - struct regulator_dev *rdev; - struct regulator_config config = { }; - struct palmas_pmic *pmic; - struct palmas_reg_init *reg_init; - int id = 0, ret; - unsigned int addr, reg; - - if (!pdata) - return -EINVAL; - if (!pdata->reg_data) - return -EINVAL; - - pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); - if (!pmic) - return -ENOMEM; - - pmic->dev = &pdev->dev; - pmic->palmas = palmas; - palmas->pmic = pmic; - platform_set_drvdata(pdev, pmic); - - ret = palmas_smps_read(palmas, PALMAS_SMPS_CTRL, ®); - if (ret) - goto err_unregister_regulator; - - if (reg & PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN) - pmic->smps123 = 1; - - if (reg & PALMAS_SMPS_CTRL_SMPS45_SMPS457_EN) - pmic->smps457 = 1; - - config.regmap = palmas->regmap[REGULATOR_SLAVE]; - config.dev = &pdev->dev; - config.driver_data = pmic; - - for (id = 0; id < PALMAS_REG_LDO1; id++) { - - /* - * Miss out regulators which are not available due - * to slaving configurations. - */ - switch (id) { - case PALMAS_REG_SMPS12: - case PALMAS_REG_SMPS3: - if (pmic->smps123) - continue; - break; - case PALMAS_REG_SMPS123: - if (!pmic->smps123) - continue; - break; - case PALMAS_REG_SMPS45: - case PALMAS_REG_SMPS7: - if (pmic->smps457) - continue; - break; - case PALMAS_REG_SMPS457: - if (!pmic->smps457) - continue; - } - - /* Register the regulators */ - pmic->desc[id].name = palmas_regs_info[id].name; - pmic->desc[id].id = id; - - if (id != PALMAS_REG_SMPS10) { - pmic->desc[id].ops = &palmas_ops_smps; - pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES; - } else { - pmic->desc[id].n_voltages = PALMAS_SMPS10_NUM_VOLTAGES; - pmic->desc[id].ops = &palmas_ops_smps10; - pmic->desc[id].vsel_reg = PALMAS_SMPS10_CTRL; - pmic->desc[id].vsel_mask = SMPS10_VSEL; - pmic->desc[id].enable_reg = PALMAS_SMPS10_STATUS; - pmic->desc[id].enable_mask = SMPS10_BOOST_EN; - } - - pmic->desc[id].type = REGULATOR_VOLTAGE; - pmic->desc[id].owner = THIS_MODULE; - - /* Initialise sleep/init values from platform data */ - if (pdata && pdata->reg_init) { - reg_init = pdata->reg_init[id]; - if (reg_init) { - ret = palmas_smps_init(palmas, id, reg_init); - if (ret) - goto err_unregister_regulator; - } - } - - /* - * read and store the RANGE bit for later use - * This must be done before regulator is probed otherwise - * we error in probe with unsuportable ranges. - */ - if (id != PALMAS_REG_SMPS10) { - addr = palmas_regs_info[id].vsel_addr; - - ret = palmas_smps_read(pmic->palmas, addr, ®); - if (ret) - goto err_unregister_regulator; - if (reg & PALMAS_SMPS12_VOLTAGE_RANGE) - pmic->range[id] = 1; - } - - if (pdata && pdata->reg_data) - config.init_data = pdata->reg_data[id]; - else - config.init_data = NULL; - - rdev = regulator_register(&pmic->desc[id], &config); - if (IS_ERR(rdev)) { - dev_err(&pdev->dev, - "failed to register %s regulator\n", - pdev->name); - ret = PTR_ERR(rdev); - goto err_unregister_regulator; - } - - /* Save regulator for cleanup */ - pmic->rdev[id] = rdev; - } - - /* Start this loop from the id left from previous loop */ - for (; id < PALMAS_NUM_REGS; id++) { - - /* Miss out regulators which are not available due - * to alternate functions. - */ - - /* Register the regulators */ - pmic->desc[id].name = palmas_regs_info[id].name; - pmic->desc[id].id = id; - pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES; - - pmic->desc[id].ops = &palmas_ops_ldo; - - pmic->desc[id].type = REGULATOR_VOLTAGE; - pmic->desc[id].owner = THIS_MODULE; - pmic->desc[id].enable_reg = palmas_regs_info[id].ctrl_addr; - pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE; - - if (pdata && pdata->reg_data) - config.init_data = pdata->reg_data[id]; - else - config.init_data = NULL; - - rdev = regulator_register(&pmic->desc[id], &config); - if (IS_ERR(rdev)) { - dev_err(&pdev->dev, - "failed to register %s regulator\n", - pdev->name); - ret = PTR_ERR(rdev); - goto err_unregister_regulator; - } - - /* Save regulator for cleanup */ - pmic->rdev[id] = rdev; - - /* Initialise sleep/init values from platform data */ - if (pdata->reg_init) { - reg_init = pdata->reg_init[id]; - if (reg_init) { - ret = palmas_ldo_init(palmas, id, reg_init); - if (ret) - goto err_unregister_regulator; - } - } - } - - return 0; - -err_unregister_regulator: - while (--id >= 0) - regulator_unregister(pmic->rdev[id]); - kfree(pmic->rdev); - kfree(pmic->desc); - kfree(pmic); - return ret; -} - -static int __devexit palmas_remove(struct platform_device *pdev) -{ - struct palmas_pmic *pmic = platform_get_drvdata(pdev); - int id; - - for (id = 0; id < PALMAS_NUM_REGS; id++) - regulator_unregister(pmic->rdev[id]); - - kfree(pmic->rdev); - kfree(pmic->desc); - kfree(pmic); - return 0; -} - -static struct platform_driver palmas_driver = { - .driver = { - .name = "palmas-pmic", - .owner = THIS_MODULE, - }, - .probe = palmas_probe, - .remove = __devexit_p(palmas_remove), -}; - -static int __init palmas_init(void) -{ - return platform_driver_register(&palmas_driver); -} -subsys_initcall(palmas_init); - -static void __exit palmas_exit(void) -{ - platform_driver_unregister(&palmas_driver); -} -module_exit(palmas_exit); - -MODULE_AUTHOR("Graeme Gregory "); -MODULE_DESCRIPTION("Palmas voltage regulator driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:palmas-pmic"); diff --git a/trunk/drivers/regulator/pcap-regulator.c b/trunk/drivers/regulator/pcap-regulator.c index 8211101121f0..a5aab1b08bcf 100644 --- a/trunk/drivers/regulator/pcap-regulator.c +++ b/trunk/drivers/regulator/pcap-regulator.c @@ -150,33 +150,57 @@ static struct pcap_regulator vreg_table[] = { VREG_INFO(SW2S, PCAP_REG_LOWPWR, NA, 20, NA, NA), */ }; -static int pcap_regulator_set_voltage_sel(struct regulator_dev *rdev, - unsigned selector) +static int pcap_regulator_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, + unsigned *selector) { struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)]; void *pcap = rdev_get_drvdata(rdev); + int uV; + u8 i; /* the regulator doesn't support voltage switching */ if (vreg->n_voltages == 1) return -EINVAL; - return ezx_pcap_set_bits(pcap, vreg->reg, - (vreg->n_voltages - 1) << vreg->index, - selector << vreg->index); + for (i = 0; i < vreg->n_voltages; i++) { + /* For V1 the first is not the best match */ + if (i == 0 && rdev_get_id(rdev) == V1) + i = 1; + else if (i + 1 == vreg->n_voltages && rdev_get_id(rdev) == V1) + i = 0; + + uV = vreg->voltage_table[i] * 1000; + if (min_uV <= uV && uV <= max_uV) { + *selector = i; + return ezx_pcap_set_bits(pcap, vreg->reg, + (vreg->n_voltages - 1) << vreg->index, + i << vreg->index); + } + + if (i == 0 && rdev_get_id(rdev) == V1) + i = vreg->n_voltages - 1; + } + + /* the requested voltage range is not supported by this regulator */ + return -EINVAL; } -static int pcap_regulator_get_voltage_sel(struct regulator_dev *rdev) +static int pcap_regulator_get_voltage(struct regulator_dev *rdev) { struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)]; void *pcap = rdev_get_drvdata(rdev); u32 tmp; + int mV; if (vreg->n_voltages == 1) - return 0; + return vreg->voltage_table[0] * 1000; ezx_pcap_read(pcap, vreg->reg, &tmp); tmp = ((tmp >> vreg->index) & (vreg->n_voltages - 1)); - return tmp; + mV = vreg->voltage_table[tmp]; + + return mV * 1000; } static int pcap_regulator_enable(struct regulator_dev *rdev) @@ -224,8 +248,8 @@ static int pcap_regulator_list_voltage(struct regulator_dev *rdev, static struct regulator_ops pcap_regulator_ops = { .list_voltage = pcap_regulator_list_voltage, - .set_voltage_sel = pcap_regulator_set_voltage_sel, - .get_voltage_sel = pcap_regulator_get_voltage_sel, + .set_voltage = pcap_regulator_set_voltage, + .get_voltage = pcap_regulator_get_voltage, .enable = pcap_regulator_enable, .disable = pcap_regulator_disable, .is_enabled = pcap_regulator_is_enabled, @@ -241,7 +265,7 @@ static struct regulator_ops pcap_regulator_ops = { .owner = THIS_MODULE, \ } -static const struct regulator_desc pcap_regulators[] = { +static struct regulator_desc pcap_regulators[] = { VREG(V1), VREG(V2), VREG(V3), VREG(V4), VREG(V5), VREG(V6), VREG(V7), VREG(V8), VREG(V9), VREG(V10), VREG(VAUX1), VREG(VAUX2), VREG(VAUX3), VREG(VAUX4), VREG(VSIM), VREG(VSIM2), VREG(VVIB), VREG(SW1), VREG(SW2), @@ -251,13 +275,9 @@ static int __devinit pcap_regulator_probe(struct platform_device *pdev) { struct regulator_dev *rdev; void *pcap = dev_get_drvdata(pdev->dev.parent); - struct regulator_config config = { }; - - config.dev = &pdev->dev; - config.init_data = pdev->dev.platform_data; - config.driver_data = pcap; - rdev = regulator_register(&pcap_regulators[pdev->id], &config); + rdev = regulator_register(&pcap_regulators[pdev->id], &pdev->dev, + pdev->dev.platform_data, pcap, NULL); if (IS_ERR(rdev)) return PTR_ERR(rdev); diff --git a/trunk/drivers/regulator/pcf50633-regulator.c b/trunk/drivers/regulator/pcf50633-regulator.c index 3c9d14c0017b..6db46c632f13 100644 --- a/trunk/drivers/regulator/pcf50633-regulator.c +++ b/trunk/drivers/regulator/pcf50633-regulator.c @@ -24,25 +24,35 @@ #include #include -#define PCF50633_REGULATOR(_name, _id, _n) \ - { \ - .name = _name, \ - .id = PCF50633_REGULATOR_##_id, \ - .ops = &pcf50633_regulator_ops, \ - .n_voltages = _n, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .vsel_reg = PCF50633_REG_##_id##OUT, \ - .vsel_mask = 0xff, \ - .enable_reg = PCF50633_REG_##_id##OUT + 1, \ - .enable_mask = PCF50633_REGULATOR_ON, \ +#define PCF50633_REGULATOR(_name, _id, _n) \ + { \ + .name = _name, \ + .id = _id, \ + .ops = &pcf50633_regulator_ops, \ + .n_voltages = _n, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ } +static const u8 pcf50633_regulator_registers[PCF50633_NUM_REGULATORS] = { + [PCF50633_REGULATOR_AUTO] = PCF50633_REG_AUTOOUT, + [PCF50633_REGULATOR_DOWN1] = PCF50633_REG_DOWN1OUT, + [PCF50633_REGULATOR_DOWN2] = PCF50633_REG_DOWN2OUT, + [PCF50633_REGULATOR_MEMLDO] = PCF50633_REG_MEMLDOOUT, + [PCF50633_REGULATOR_LDO1] = PCF50633_REG_LDO1OUT, + [PCF50633_REGULATOR_LDO2] = PCF50633_REG_LDO2OUT, + [PCF50633_REGULATOR_LDO3] = PCF50633_REG_LDO3OUT, + [PCF50633_REGULATOR_LDO4] = PCF50633_REG_LDO4OUT, + [PCF50633_REGULATOR_LDO5] = PCF50633_REG_LDO5OUT, + [PCF50633_REGULATOR_LDO6] = PCF50633_REG_LDO6OUT, + [PCF50633_REGULATOR_HCLDO] = PCF50633_REG_HCLDOOUT, +}; + /* Bits from voltage value */ static u8 auto_voltage_bits(unsigned int millivolts) { if (millivolts < 1800) - return 0x2f; + return 0; if (millivolts > 3800) return 0xff; @@ -77,9 +87,6 @@ static u8 ldo_voltage_bits(unsigned int millivolts) /* Obtain voltage value from bits */ static unsigned int auto_voltage_value(u8 bits) { - /* AUTOOUT: 00000000 to 00101110 are reserved. - * Return 0 for bits in reserved range, which means this selector code - * can't be used on this system */ if (bits < 0x2f) return 0; @@ -116,7 +123,7 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev, millivolts = min_uV / 1000; - regnr = rdev->desc->vsel_reg; + regnr = pcf50633_regulator_registers[regulator_id]; switch (regulator_id) { case PCF50633_REGULATOR_AUTO: @@ -147,22 +154,20 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev, return pcf50633_reg_write(pcf, regnr, volt_bits); } -static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev, - unsigned int index) +static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id, + u8 bits) { - int regulator_id = rdev_get_id(rdev); - int millivolts; - switch (regulator_id) { + switch (id) { case PCF50633_REGULATOR_AUTO: - millivolts = auto_voltage_value(index); + millivolts = auto_voltage_value(bits); break; case PCF50633_REGULATOR_DOWN1: - millivolts = down_voltage_value(index); + millivolts = down_voltage_value(bits); break; case PCF50633_REGULATOR_DOWN2: - millivolts = down_voltage_value(index); + millivolts = down_voltage_value(bits); break; case PCF50633_REGULATOR_LDO1: case PCF50633_REGULATOR_LDO2: @@ -172,7 +177,7 @@ static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev, case PCF50633_REGULATOR_LDO6: case PCF50633_REGULATOR_HCLDO: case PCF50633_REGULATOR_MEMLDO: - millivolts = ldo_voltage_value(index); + millivolts = ldo_voltage_value(bits); break; default: return -EINVAL; @@ -181,44 +186,140 @@ static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev, return millivolts * 1000; } +static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev) +{ + struct pcf50633 *pcf; + int regulator_id; + u8 volt_bits, regnr; + + pcf = rdev_get_drvdata(rdev); + + regulator_id = rdev_get_id(rdev); + if (regulator_id >= PCF50633_NUM_REGULATORS) + return -EINVAL; + + regnr = pcf50633_regulator_registers[regulator_id]; + + volt_bits = pcf50633_reg_read(pcf, regnr); + + return pcf50633_regulator_voltage_value(regulator_id, volt_bits); +} + +static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev, + unsigned int index) +{ + struct pcf50633 *pcf; + int regulator_id; + + pcf = rdev_get_drvdata(rdev); + + regulator_id = rdev_get_id(rdev); + + switch (regulator_id) { + case PCF50633_REGULATOR_AUTO: + index += 0x2f; + break; + default: + break; + } + + return pcf50633_regulator_voltage_value(regulator_id, index); +} + +static int pcf50633_regulator_enable(struct regulator_dev *rdev) +{ + struct pcf50633 *pcf = rdev_get_drvdata(rdev); + int regulator_id; + u8 regnr; + + regulator_id = rdev_get_id(rdev); + if (regulator_id >= PCF50633_NUM_REGULATORS) + return -EINVAL; + + /* The *ENA register is always one after the *OUT register */ + regnr = pcf50633_regulator_registers[regulator_id] + 1; + + return pcf50633_reg_set_bit_mask(pcf, regnr, PCF50633_REGULATOR_ON, + PCF50633_REGULATOR_ON); +} + +static int pcf50633_regulator_disable(struct regulator_dev *rdev) +{ + struct pcf50633 *pcf = rdev_get_drvdata(rdev); + int regulator_id; + u8 regnr; + + regulator_id = rdev_get_id(rdev); + if (regulator_id >= PCF50633_NUM_REGULATORS) + return -EINVAL; + + /* the *ENA register is always one after the *OUT register */ + regnr = pcf50633_regulator_registers[regulator_id] + 1; + + return pcf50633_reg_set_bit_mask(pcf, regnr, + PCF50633_REGULATOR_ON, 0); +} + +static int pcf50633_regulator_is_enabled(struct regulator_dev *rdev) +{ + struct pcf50633 *pcf = rdev_get_drvdata(rdev); + int regulator_id = rdev_get_id(rdev); + u8 regnr; + + regulator_id = rdev_get_id(rdev); + if (regulator_id >= PCF50633_NUM_REGULATORS) + return -EINVAL; + + /* the *ENA register is always one after the *OUT register */ + regnr = pcf50633_regulator_registers[regulator_id] + 1; + + return pcf50633_reg_read(pcf, regnr) & PCF50633_REGULATOR_ON; +} + static struct regulator_ops pcf50633_regulator_ops = { .set_voltage = pcf50633_regulator_set_voltage, - .get_voltage_sel = regulator_get_voltage_sel_regmap, + .get_voltage = pcf50633_regulator_get_voltage, .list_voltage = pcf50633_regulator_list_voltage, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, + .enable = pcf50633_regulator_enable, + .disable = pcf50633_regulator_disable, + .is_enabled = pcf50633_regulator_is_enabled, }; -static const struct regulator_desc regulators[] = { - [PCF50633_REGULATOR_AUTO] = PCF50633_REGULATOR("auto", AUTO, 128), - [PCF50633_REGULATOR_DOWN1] = PCF50633_REGULATOR("down1", DOWN1, 96), - [PCF50633_REGULATOR_DOWN2] = PCF50633_REGULATOR("down2", DOWN2, 96), - [PCF50633_REGULATOR_LDO1] = PCF50633_REGULATOR("ldo1", LDO1, 28), - [PCF50633_REGULATOR_LDO2] = PCF50633_REGULATOR("ldo2", LDO2, 28), - [PCF50633_REGULATOR_LDO3] = PCF50633_REGULATOR("ldo3", LDO3, 28), - [PCF50633_REGULATOR_LDO4] = PCF50633_REGULATOR("ldo4", LDO4, 28), - [PCF50633_REGULATOR_LDO5] = PCF50633_REGULATOR("ldo5", LDO5, 28), - [PCF50633_REGULATOR_LDO6] = PCF50633_REGULATOR("ldo6", LDO6, 28), - [PCF50633_REGULATOR_HCLDO] = PCF50633_REGULATOR("hcldo", HCLDO, 28), - [PCF50633_REGULATOR_MEMLDO] = PCF50633_REGULATOR("memldo", MEMLDO, 28), +static struct regulator_desc regulators[] = { + [PCF50633_REGULATOR_AUTO] = + PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO, 81), + [PCF50633_REGULATOR_DOWN1] = + PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1, 96), + [PCF50633_REGULATOR_DOWN2] = + PCF50633_REGULATOR("down2", PCF50633_REGULATOR_DOWN2, 96), + [PCF50633_REGULATOR_LDO1] = + PCF50633_REGULATOR("ldo1", PCF50633_REGULATOR_LDO1, 28), + [PCF50633_REGULATOR_LDO2] = + PCF50633_REGULATOR("ldo2", PCF50633_REGULATOR_LDO2, 28), + [PCF50633_REGULATOR_LDO3] = + PCF50633_REGULATOR("ldo3", PCF50633_REGULATOR_LDO3, 28), + [PCF50633_REGULATOR_LDO4] = + PCF50633_REGULATOR("ldo4", PCF50633_REGULATOR_LDO4, 28), + [PCF50633_REGULATOR_LDO5] = + PCF50633_REGULATOR("ldo5", PCF50633_REGULATOR_LDO5, 28), + [PCF50633_REGULATOR_LDO6] = + PCF50633_REGULATOR("ldo6", PCF50633_REGULATOR_LDO6, 28), + [PCF50633_REGULATOR_HCLDO] = + PCF50633_REGULATOR("hcldo", PCF50633_REGULATOR_HCLDO, 28), + [PCF50633_REGULATOR_MEMLDO] = + PCF50633_REGULATOR("memldo", PCF50633_REGULATOR_MEMLDO, 28), }; static int __devinit pcf50633_regulator_probe(struct platform_device *pdev) { struct regulator_dev *rdev; struct pcf50633 *pcf; - struct regulator_config config = { }; /* Already set by core driver */ pcf = dev_to_pcf50633(pdev->dev.parent); - config.dev = &pdev->dev; - config.init_data = pdev->dev.platform_data; - config.driver_data = pcf; - config.regmap = pcf->regmap; - - rdev = regulator_register(®ulators[pdev->id], &config); + rdev = regulator_register(®ulators[pdev->id], &pdev->dev, + pdev->dev.platform_data, pcf, NULL); if (IS_ERR(rdev)) return PTR_ERR(rdev); diff --git a/trunk/drivers/regulator/rc5t583-regulator.c b/trunk/drivers/regulator/rc5t583-regulator.c deleted file mode 100644 index 1d34e64a1307..000000000000 --- a/trunk/drivers/regulator/rc5t583-regulator.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Regulator driver for RICOH RC5T583 power management chip. - * - * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved. - * Author: Laxman dewangan - * - * based on code - * Copyright (C) 2011 RICOH COMPANY,LTD - * - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct rc5t583_regulator_info { - int deepsleep_id; - - /* Regulator register address.*/ - uint8_t reg_disc_reg; - uint8_t disc_bit; - uint8_t deepsleep_reg; - - /* Regulator specific turn-on delay and voltage settling time*/ - int enable_uv_per_us; - int change_uv_per_us; - - /* Used by regulator core */ - struct regulator_desc desc; -}; - -struct rc5t583_regulator { - struct rc5t583_regulator_info *reg_info; - - /* Devices */ - struct device *dev; - struct rc5t583 *mfd; - struct regulator_dev *rdev; -}; - -static int rc5t583_regulator_enable_time(struct regulator_dev *rdev) -{ - struct rc5t583_regulator *reg = rdev_get_drvdata(rdev); - int vsel = regulator_get_voltage_sel_regmap(rdev); - int curr_uV = regulator_list_voltage_linear(rdev, vsel); - - return DIV_ROUND_UP(curr_uV, reg->reg_info->enable_uv_per_us); -} - -static int rc5t583_set_voltage_time_sel(struct regulator_dev *rdev, - unsigned int old_selector, unsigned int new_selector) -{ - struct rc5t583_regulator *reg = rdev_get_drvdata(rdev); - int old_uV, new_uV; - old_uV = regulator_list_voltage_linear(rdev, old_selector); - - if (old_uV < 0) - return old_uV; - - new_uV = regulator_list_voltage_linear(rdev, new_selector); - if (new_uV < 0) - return new_uV; - - return DIV_ROUND_UP(abs(old_uV - new_uV), - reg->reg_info->change_uv_per_us); -} - - -static struct regulator_ops rc5t583_ops = { - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .enable_time = rc5t583_regulator_enable_time, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, - .set_voltage_time_sel = rc5t583_set_voltage_time_sel, -}; - -#define RC5T583_REG(_id, _en_reg, _en_bit, _disc_reg, _disc_bit, \ - _vout_mask, _min_mv, _max_mv, _step_uV, _enable_mv) \ -{ \ - .reg_disc_reg = RC5T583_REG_##_disc_reg, \ - .disc_bit = _disc_bit, \ - .deepsleep_reg = RC5T583_REG_##_id##DAC_DS, \ - .enable_uv_per_us = _enable_mv * 1000, \ - .change_uv_per_us = 40 * 1000, \ - .deepsleep_id = RC5T583_DS_##_id, \ - .desc = { \ - .name = "rc5t583-regulator-"#_id, \ - .id = RC5T583_REGULATOR_##_id, \ - .n_voltages = (_max_mv - _min_mv) * 1000 / _step_uV + 1, \ - .ops = &rc5t583_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .vsel_reg = RC5T583_REG_##_id##DAC, \ - .vsel_mask = _vout_mask, \ - .enable_reg = RC5T583_REG_##_en_reg, \ - .enable_mask = BIT(_en_bit), \ - .min_uV = _min_mv * 1000, \ - .uV_step = _step_uV, \ - }, \ -} - -static struct rc5t583_regulator_info rc5t583_reg_info[RC5T583_REGULATOR_MAX] = { - RC5T583_REG(DC0, DC0CTL, 0, DC0CTL, 1, 0x7F, 700, 1500, 12500, 4), - RC5T583_REG(DC1, DC1CTL, 0, DC1CTL, 1, 0x7F, 700, 1500, 12500, 14), - RC5T583_REG(DC2, DC2CTL, 0, DC2CTL, 1, 0x7F, 900, 2400, 12500, 14), - RC5T583_REG(DC3, DC3CTL, 0, DC3CTL, 1, 0x7F, 900, 2400, 12500, 14), - RC5T583_REG(LDO0, LDOEN2, 0, LDODIS2, 0, 0x7F, 900, 3400, 25000, 160), - RC5T583_REG(LDO1, LDOEN2, 1, LDODIS2, 1, 0x7F, 900, 3400, 25000, 160), - RC5T583_REG(LDO2, LDOEN2, 2, LDODIS2, 2, 0x7F, 900, 3400, 25000, 160), - RC5T583_REG(LDO3, LDOEN2, 3, LDODIS2, 3, 0x7F, 900, 3400, 25000, 160), - RC5T583_REG(LDO4, LDOEN2, 4, LDODIS2, 4, 0x3F, 750, 1500, 12500, 133), - RC5T583_REG(LDO5, LDOEN2, 5, LDODIS2, 5, 0x7F, 900, 3400, 25000, 267), - RC5T583_REG(LDO6, LDOEN2, 6, LDODIS2, 6, 0x7F, 900, 3400, 25000, 133), - RC5T583_REG(LDO7, LDOEN2, 7, LDODIS2, 7, 0x7F, 900, 3400, 25000, 233), - RC5T583_REG(LDO8, LDOEN1, 0, LDODIS1, 0, 0x7F, 900, 3400, 25000, 233), - RC5T583_REG(LDO9, LDOEN1, 1, LDODIS1, 1, 0x7F, 900, 3400, 25000, 133), -}; - -static int __devinit rc5t583_regulator_probe(struct platform_device *pdev) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent); - struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev); - struct regulator_init_data *reg_data; - struct regulator_config config = { }; - struct rc5t583_regulator *reg = NULL; - struct rc5t583_regulator *regs; - struct regulator_dev *rdev; - struct rc5t583_regulator_info *ri; - int ret; - int id; - - if (!pdata) { - dev_err(&pdev->dev, "No platform data, exiting...\n"); - return -ENODEV; - } - - regs = devm_kzalloc(&pdev->dev, RC5T583_REGULATOR_MAX * - sizeof(struct rc5t583_regulator), GFP_KERNEL); - if (!regs) { - dev_err(&pdev->dev, "Memory allocation failed exiting..\n"); - return -ENOMEM; - } - - - for (id = 0; id < RC5T583_REGULATOR_MAX; ++id) { - reg_data = pdata->reg_init_data[id]; - - /* No need to register if there is no regulator data */ - if (!reg_data) - continue; - - reg = ®s[id]; - ri = &rc5t583_reg_info[id]; - reg->reg_info = ri; - reg->mfd = rc5t583; - reg->dev = &pdev->dev; - - if (ri->deepsleep_id == RC5T583_DS_NONE) - goto skip_ext_pwr_config; - - ret = rc5t583_ext_power_req_config(rc5t583->dev, - ri->deepsleep_id, - pdata->regulator_ext_pwr_control[id], - pdata->regulator_deepsleep_slot[id]); - /* - * Configuring external control is not a major issue, - * just give warning. - */ - if (ret < 0) - dev_warn(&pdev->dev, - "Failed to configure ext control %d\n", id); - -skip_ext_pwr_config: - config.dev = &pdev->dev; - config.init_data = reg_data; - config.driver_data = reg; - config.regmap = rc5t583->regmap; - - rdev = regulator_register(&ri->desc, &config); - if (IS_ERR(rdev)) { - dev_err(&pdev->dev, "Failed to register regulator %s\n", - ri->desc.name); - ret = PTR_ERR(rdev); - goto clean_exit; - } - reg->rdev = rdev; - } - platform_set_drvdata(pdev, regs); - return 0; - -clean_exit: - while (--id >= 0) - regulator_unregister(regs[id].rdev); - - return ret; -} - -static int __devexit rc5t583_regulator_remove(struct platform_device *pdev) -{ - struct rc5t583_regulator *regs = platform_get_drvdata(pdev); - int id; - - for (id = 0; id < RC5T583_REGULATOR_MAX; ++id) - regulator_unregister(regs[id].rdev); - return 0; -} - -static struct platform_driver rc5t583_regulator_driver = { - .driver = { - .name = "rc5t583-regulator", - .owner = THIS_MODULE, - }, - .probe = rc5t583_regulator_probe, - .remove = __devexit_p(rc5t583_regulator_remove), -}; - -static int __init rc5t583_regulator_init(void) -{ - return platform_driver_register(&rc5t583_regulator_driver); -} -subsys_initcall(rc5t583_regulator_init); - -static void __exit rc5t583_regulator_exit(void) -{ - platform_driver_unregister(&rc5t583_regulator_driver); -} -module_exit(rc5t583_regulator_exit); - -MODULE_AUTHOR("Laxman Dewangan "); -MODULE_DESCRIPTION("RC5T583 regulator driver"); -MODULE_ALIAS("platform:rc5t583-regulator"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/regulator/s5m8767.c b/trunk/drivers/regulator/s5m8767.c index 290d6fc01029..4ca2db059004 100644 --- a/trunk/drivers/regulator/s5m8767.c +++ b/trunk/drivers/regulator/s5m8767.c @@ -12,6 +12,7 @@ */ #include +#include #include #include #include @@ -27,7 +28,6 @@ struct s5m8767_info { struct s5m87xx_dev *iodev; int num_regulators; struct regulator_dev **rdev; - struct s5m_opmode_data *opmode; int ramp_delay; bool buck2_ramp; @@ -141,56 +141,9 @@ static int s5m8767_list_voltage(struct regulator_dev *rdev, return val; } -static unsigned int s5m8767_opmode_reg[][4] = { - /* {OFF, ON, LOWPOWER, SUSPEND} */ - /* LDO1 ... LDO28 */ - {0x0, 0x3, 0x2, 0x1}, /* LDO1 */ - {0x0, 0x3, 0x2, 0x1}, - {0x0, 0x3, 0x2, 0x1}, - {0x0, 0x0, 0x0, 0x0}, - {0x0, 0x3, 0x2, 0x1}, /* LDO5 */ - {0x0, 0x3, 0x2, 0x1}, - {0x0, 0x3, 0x2, 0x1}, - {0x0, 0x3, 0x2, 0x1}, - {0x0, 0x3, 0x2, 0x1}, - {0x0, 0x3, 0x2, 0x1}, /* LDO10 */ - {0x0, 0x3, 0x2, 0x1}, - {0x0, 0x3, 0x2, 0x1}, - {0x0, 0x3, 0x2, 0x1}, - {0x0, 0x3, 0x2, 0x1}, - {0x0, 0x3, 0x2, 0x1}, /* LDO15 */ - {0x0, 0x3, 0x2, 0x1}, - {0x0, 0x3, 0x2, 0x1}, - {0x0, 0x0, 0x0, 0x0}, - {0x0, 0x3, 0x2, 0x1}, - {0x0, 0x3, 0x2, 0x1}, /* LDO20 */ - {0x0, 0x3, 0x2, 0x1}, - {0x0, 0x3, 0x2, 0x1}, - {0x0, 0x0, 0x0, 0x0}, - {0x0, 0x3, 0x2, 0x1}, - {0x0, 0x3, 0x2, 0x1}, /* LDO25 */ - {0x0, 0x3, 0x2, 0x1}, - {0x0, 0x3, 0x2, 0x1}, - {0x0, 0x3, 0x2, 0x1}, /* LDO28 */ - - /* BUCK1 ... BUCK9 */ - {0x0, 0x3, 0x1, 0x1}, /* BUCK1 */ - {0x0, 0x3, 0x1, 0x1}, - {0x0, 0x3, 0x1, 0x1}, - {0x0, 0x3, 0x1, 0x1}, - {0x0, 0x3, 0x2, 0x1}, /* BUCK5 */ - {0x0, 0x3, 0x1, 0x1}, - {0x0, 0x3, 0x1, 0x1}, - {0x0, 0x3, 0x1, 0x1}, - {0x0, 0x3, 0x1, 0x1}, /* BUCK9 */ -}; - -static int s5m8767_get_register(struct regulator_dev *rdev, int *reg, - int *enable_ctrl) +static int s5m8767_get_register(struct regulator_dev *rdev, int *reg) { int reg_id = rdev_get_id(rdev); - unsigned int mode; - struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); switch (reg_id) { case S5M8767_LDO1 ... S5M8767_LDO2: @@ -215,8 +168,6 @@ static int s5m8767_get_register(struct regulator_dev *rdev, int *reg, return -EINVAL; } - mode = s5m8767->opmode[reg_id].mode; - *enable_ctrl = s5m8767_opmode_reg[reg_id][mode] << S5M8767_ENCTRL_SHIFT; return 0; } @@ -224,10 +175,10 @@ static int s5m8767_reg_is_enabled(struct regulator_dev *rdev) { struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); int ret, reg; - int mask = 0xc0, enable_ctrl; + int mask = 0xc0, pattern = 0xc0; u8 val; - ret = s5m8767_get_register(rdev, ®, &enable_ctrl); + ret = s5m8767_get_register(rdev, ®); if (ret == -EINVAL) return 1; else if (ret) @@ -237,33 +188,33 @@ static int s5m8767_reg_is_enabled(struct regulator_dev *rdev) if (ret) return ret; - return (val & mask) == enable_ctrl; + return (val & mask) == pattern; } static int s5m8767_reg_enable(struct regulator_dev *rdev) { struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); int ret, reg; - int mask = 0xc0, enable_ctrl; + int mask = 0xc0, pattern = 0xc0; - ret = s5m8767_get_register(rdev, ®, &enable_ctrl); + ret = s5m8767_get_register(rdev, ®); if (ret) return ret; - return s5m_reg_update(s5m8767->iodev, reg, enable_ctrl, mask); + return s5m_reg_update(s5m8767->iodev, reg, pattern, mask); } static int s5m8767_reg_disable(struct regulator_dev *rdev) { struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); int ret, reg; - int mask = 0xc0, enable_ctrl; + int mask = 0xc0, pattern = 0xc0; - ret = s5m8767_get_register(rdev, ®, &enable_ctrl); + ret = s5m8767_get_register(rdev, ®); if (ret) return ret; - return s5m_reg_update(s5m8767->iodev, reg, ~mask, mask); + return s5m_reg_update(s5m8767->iodev, reg, ~pattern, mask); } static int s5m8767_get_voltage_register(struct regulator_dev *rdev, int *_reg) @@ -346,10 +297,7 @@ static int s5m8767_convert_voltage_to_sel( if (max_vol < desc->min || min_vol > desc->max) return -EINVAL; - if (min_vol < desc->min) - min_vol = desc->min; - - selector = DIV_ROUND_UP(min_vol - desc->min, desc->step); + selector = (min_vol - desc->min) / desc->step; if (desc->min + desc->step * selector > max_vol) return -EINVAL; @@ -357,33 +305,14 @@ static int s5m8767_convert_voltage_to_sel( return selector; } -static inline void s5m8767_set_high(struct s5m8767_info *s5m8767) -{ - int temp_index = s5m8767->buck_gpioindex; - - gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1); - gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1); - gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1); -} - -static inline void s5m8767_set_low(struct s5m8767_info *s5m8767) -{ - int temp_index = s5m8767->buck_gpioindex; - - gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1); - gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1); - gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1); -} - static int s5m8767_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned *selector) { struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); const struct s5m_voltage_desc *desc; int reg_id = rdev_get_id(rdev); - int sel, reg, mask, ret = 0, old_index, index = 0; + int sel, reg, mask, ret; u8 val; - u8 *buck234_vol = NULL; switch (reg_id) { case S5M8767_LDO1 ... S5M8767_LDO28: @@ -391,12 +320,6 @@ static int s5m8767_set_voltage(struct regulator_dev *rdev, break; case S5M8767_BUCK1 ... S5M8767_BUCK6: mask = 0xff; - if (reg_id == S5M8767_BUCK2 && s5m8767->buck2_gpiodvs) - buck234_vol = &s5m8767->buck2_vol[0]; - else if (reg_id == S5M8767_BUCK3 && s5m8767->buck3_gpiodvs) - buck234_vol = &s5m8767->buck3_vol[0]; - else if (reg_id == S5M8767_BUCK4 && s5m8767->buck4_gpiodvs) - buck234_vol = &s5m8767->buck4_vol[0]; break; case S5M8767_BUCK7 ... S5M8767_BUCK8: return -EINVAL; @@ -413,34 +336,104 @@ static int s5m8767_set_voltage(struct regulator_dev *rdev, if (sel < 0) return sel; - /* buck234_vol != NULL means to control buck234 voltage via DVS GPIO */ - if (buck234_vol) { - while (*buck234_vol != sel) { - buck234_vol++; - index++; - } - old_index = s5m8767->buck_gpioindex; - s5m8767->buck_gpioindex = index; - - if (index > old_index) - s5m8767_set_high(s5m8767); - else - s5m8767_set_low(s5m8767); - } else { - ret = s5m8767_get_voltage_register(rdev, ®); - if (ret) - return ret; - - s5m_reg_read(s5m8767->iodev, reg, &val); - val = (val & ~mask) | sel; + ret = s5m8767_get_voltage_register(rdev, ®); + if (ret) + return ret; - ret = s5m_reg_write(s5m8767->iodev, reg, val); - } + s5m_reg_read(s5m8767->iodev, reg, &val); + val &= ~mask; + val |= sel; + ret = s5m_reg_write(s5m8767->iodev, reg, val); *selector = sel; + return ret; } +static inline void s5m8767_set_high(struct s5m8767_info *s5m8767) +{ + int temp_index = s5m8767->buck_gpioindex; + + gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1); + gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1); + gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1); +} + +static inline void s5m8767_set_low(struct s5m8767_info *s5m8767) +{ + int temp_index = s5m8767->buck_gpioindex; + + gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1); + gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1); + gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1); +} + +static int s5m8767_set_voltage_buck(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned *selector) +{ + struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); + int reg_id = rdev_get_id(rdev); + const struct s5m_voltage_desc *desc; + int new_val, old_val, i = 0; + + if (reg_id < S5M8767_BUCK1 || reg_id > S5M8767_BUCK6) + return -EINVAL; + + switch (reg_id) { + case S5M8767_BUCK1: + return s5m8767_set_voltage(rdev, min_uV, max_uV, selector); + case S5M8767_BUCK2 ... S5M8767_BUCK4: + break; + case S5M8767_BUCK5 ... S5M8767_BUCK6: + return s5m8767_set_voltage(rdev, min_uV, max_uV, selector); + case S5M8767_BUCK9: + return s5m8767_set_voltage(rdev, min_uV, max_uV, selector); + } + + desc = reg_voltage_map[reg_id]; + new_val = s5m8767_convert_voltage_to_sel(desc, min_uV, max_uV); + if (new_val < 0) + return new_val; + + switch (reg_id) { + case S5M8767_BUCK2: + if (s5m8767->buck2_gpiodvs) { + while (s5m8767->buck2_vol[i] != new_val) + i++; + } else + return s5m8767_set_voltage(rdev, min_uV, + max_uV, selector); + break; + case S5M8767_BUCK3: + if (s5m8767->buck3_gpiodvs) { + while (s5m8767->buck3_vol[i] != new_val) + i++; + } else + return s5m8767_set_voltage(rdev, min_uV, + max_uV, selector); + break; + case S5M8767_BUCK4: + if (s5m8767->buck3_gpiodvs) { + while (s5m8767->buck4_vol[i] != new_val) + i++; + } else + return s5m8767_set_voltage(rdev, min_uV, + max_uV, selector); + break; + } + + old_val = s5m8767->buck_gpioindex; + s5m8767->buck_gpioindex = i; + + if (i > old_val) + s5m8767_set_high(s5m8767); + else + s5m8767_set_low(s5m8767); + + *selector = new_val; + return 0; +} + static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, unsigned int old_sel, unsigned int new_sel) @@ -457,7 +450,7 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, return 0; } -static struct regulator_ops s5m8767_ops = { +static struct regulator_ops s5m8767_ldo_ops = { .list_voltage = s5m8767_list_voltage, .is_enabled = s5m8767_reg_is_enabled, .enable = s5m8767_reg_enable, @@ -467,59 +460,75 @@ static struct regulator_ops s5m8767_ops = { .set_voltage_time_sel = s5m8767_set_voltage_time_sel, }; -#define s5m8767_regulator_desc(_name) { \ - .name = #_name, \ - .id = S5M8767_##_name, \ - .ops = &s5m8767_ops, \ +static struct regulator_ops s5m8767_buck_ops = { + .list_voltage = s5m8767_list_voltage, + .is_enabled = s5m8767_reg_is_enabled, + .enable = s5m8767_reg_enable, + .disable = s5m8767_reg_disable, + .get_voltage_sel = s5m8767_get_voltage_sel, + .set_voltage = s5m8767_set_voltage_buck, + .set_voltage_time_sel = s5m8767_set_voltage_time_sel, +}; + +#define regulator_desc_ldo(num) { \ + .name = "LDO"#num, \ + .id = S5M8767_LDO##num, \ + .ops = &s5m8767_ldo_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ +} +#define regulator_desc_buck(num) { \ + .name = "BUCK"#num, \ + .id = S5M8767_BUCK##num, \ + .ops = &s5m8767_buck_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ } static struct regulator_desc regulators[] = { - s5m8767_regulator_desc(LDO1), - s5m8767_regulator_desc(LDO2), - s5m8767_regulator_desc(LDO3), - s5m8767_regulator_desc(LDO4), - s5m8767_regulator_desc(LDO5), - s5m8767_regulator_desc(LDO6), - s5m8767_regulator_desc(LDO7), - s5m8767_regulator_desc(LDO8), - s5m8767_regulator_desc(LDO9), - s5m8767_regulator_desc(LDO10), - s5m8767_regulator_desc(LDO11), - s5m8767_regulator_desc(LDO12), - s5m8767_regulator_desc(LDO13), - s5m8767_regulator_desc(LDO14), - s5m8767_regulator_desc(LDO15), - s5m8767_regulator_desc(LDO16), - s5m8767_regulator_desc(LDO17), - s5m8767_regulator_desc(LDO18), - s5m8767_regulator_desc(LDO19), - s5m8767_regulator_desc(LDO20), - s5m8767_regulator_desc(LDO21), - s5m8767_regulator_desc(LDO22), - s5m8767_regulator_desc(LDO23), - s5m8767_regulator_desc(LDO24), - s5m8767_regulator_desc(LDO25), - s5m8767_regulator_desc(LDO26), - s5m8767_regulator_desc(LDO27), - s5m8767_regulator_desc(LDO28), - s5m8767_regulator_desc(BUCK1), - s5m8767_regulator_desc(BUCK2), - s5m8767_regulator_desc(BUCK3), - s5m8767_regulator_desc(BUCK4), - s5m8767_regulator_desc(BUCK5), - s5m8767_regulator_desc(BUCK6), - s5m8767_regulator_desc(BUCK7), - s5m8767_regulator_desc(BUCK8), - s5m8767_regulator_desc(BUCK9), + regulator_desc_ldo(1), + regulator_desc_ldo(2), + regulator_desc_ldo(3), + regulator_desc_ldo(4), + regulator_desc_ldo(5), + regulator_desc_ldo(6), + regulator_desc_ldo(7), + regulator_desc_ldo(8), + regulator_desc_ldo(9), + regulator_desc_ldo(10), + regulator_desc_ldo(11), + regulator_desc_ldo(12), + regulator_desc_ldo(13), + regulator_desc_ldo(14), + regulator_desc_ldo(15), + regulator_desc_ldo(16), + regulator_desc_ldo(17), + regulator_desc_ldo(18), + regulator_desc_ldo(19), + regulator_desc_ldo(20), + regulator_desc_ldo(21), + regulator_desc_ldo(22), + regulator_desc_ldo(23), + regulator_desc_ldo(24), + regulator_desc_ldo(25), + regulator_desc_ldo(26), + regulator_desc_ldo(27), + regulator_desc_ldo(28), + regulator_desc_buck(1), + regulator_desc_buck(2), + regulator_desc_buck(3), + regulator_desc_buck(4), + regulator_desc_buck(5), + regulator_desc_buck(6), + regulator_desc_buck(7), + regulator_desc_buck(8), + regulator_desc_buck(9), }; static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) { struct s5m87xx_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct s5m_platform_data *pdata = dev_get_platdata(iodev->dev); - struct regulator_config config = { }; struct regulator_dev **rdev; struct s5m8767_info *s5m8767; int i, ret, size; @@ -577,7 +586,6 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) s5m8767->buck2_ramp = pdata->buck2_ramp_enable; s5m8767->buck3_ramp = pdata->buck3_ramp_enable; s5m8767->buck4_ramp = pdata->buck4_ramp_enable; - s5m8767->opmode = pdata->opmode; for (i = 0; i < 8; i++) { if (s5m8767->buck2_gpiodvs) { @@ -715,11 +723,8 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) regulators[id].n_voltages = (desc->max - desc->min) / desc->step + 1; - config.dev = s5m8767->dev; - config.init_data = pdata->regulators[i].initdata; - config.driver_data = s5m8767; - - rdev[i] = regulator_register(®ulators[id], &config); + rdev[i] = regulator_register(®ulators[id], s5m8767->dev, + pdata->regulators[i].initdata, s5m8767, NULL); if (IS_ERR(rdev[i])) { ret = PTR_ERR(rdev[i]); dev_err(s5m8767->dev, "regulator init failed for %d\n", diff --git a/trunk/drivers/regulator/tps6105x-regulator.c b/trunk/drivers/regulator/tps6105x-regulator.c index d840d8440a91..d9278da18a9e 100644 --- a/trunk/drivers/regulator/tps6105x-regulator.c +++ b/trunk/drivers/regulator/tps6105x-regulator.c @@ -123,7 +123,7 @@ static struct regulator_ops tps6105x_regulator_ops = { .list_voltage = tps6105x_regulator_list_voltage, }; -static const struct regulator_desc tps6105x_regulator_desc = { +static struct regulator_desc tps6105x_regulator_desc = { .name = "tps6105x-boost", .ops = &tps6105x_regulator_ops, .type = REGULATOR_VOLTAGE, @@ -139,7 +139,6 @@ static int __devinit tps6105x_regulator_probe(struct platform_device *pdev) { struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev); struct tps6105x_platform_data *pdata = tps6105x->pdata; - struct regulator_config config = { }; int ret; /* This instance is not set for regulator mode so bail out */ @@ -149,13 +148,11 @@ static int __devinit tps6105x_regulator_probe(struct platform_device *pdev) return 0; } - config.dev = &tps6105x->client->dev; - config.init_data = pdata->regulator_data; - config.driver_data = tps6105x; - /* Register regulator with framework */ tps6105x->regulator = regulator_register(&tps6105x_regulator_desc, - &config); + &tps6105x->client->dev, + pdata->regulator_data, tps6105x, + NULL); if (IS_ERR(tps6105x->regulator)) { ret = PTR_ERR(tps6105x->regulator); dev_err(&tps6105x->client->dev, diff --git a/trunk/drivers/regulator/tps62360-regulator.c b/trunk/drivers/regulator/tps62360-regulator.c index e534269ed44a..e2ec73068ee2 100644 --- a/trunk/drivers/regulator/tps62360-regulator.c +++ b/trunk/drivers/regulator/tps62360-regulator.c @@ -1,7 +1,7 @@ /* * tps62360.c -- TI tps62360 * - * Driver for processor core supply tps62360, tps62361B, tps62362 and tps62363. + * Driver for processor core supply tps62360 and tps62361B * * Copyright (c) 2012, NVIDIA Corporation. * @@ -26,16 +26,13 @@ #include #include #include -#include -#include -#include -#include #include #include #include #include #include #include +#include #include #include @@ -49,20 +46,20 @@ #define REG_RAMPCTRL 6 #define REG_CHIPID 8 -#define FORCE_PWM_ENABLE BIT(7) +enum chips {TPS62360, TPS62361}; -enum chips {TPS62360, TPS62361, TPS62362, TPS62363}; - -#define TPS62360_BASE_VOLTAGE 770000 +#define TPS62360_BASE_VOLTAGE 770 #define TPS62360_N_VOLTAGES 64 -#define TPS62361_BASE_VOLTAGE 500000 +#define TPS62361_BASE_VOLTAGE 500 #define TPS62361_N_VOLTAGES 128 /* tps 62360 chip information */ struct tps62360_chip { + const char *name; struct device *dev; struct regulator_desc desc; + struct i2c_client *client; struct regulator_dev *rdev; struct regmap *regmap; int chip_id; @@ -71,12 +68,12 @@ struct tps62360_chip { int voltage_base; u8 voltage_reg_mask; bool en_internal_pulldn; + bool en_force_pwm; bool en_discharge; bool valid_gpios; int lru_index[4]; int curr_vset_vsel[4]; int curr_vset_id; - int change_uv_per_us; }; /* @@ -102,7 +99,6 @@ static bool find_voltage_set_register(struct tps62360_chip *tps, bool found = false; int new_vset_reg = tps->lru_index[3]; int found_index = 3; - for (i = 0; i < 4; ++i) { if (tps->curr_vset_vsel[tps->lru_index[i]] == req_vsel) { new_vset_reg = tps->lru_index[i]; @@ -121,7 +117,7 @@ static bool find_voltage_set_register(struct tps62360_chip *tps, return found; } -static int tps62360_dcdc_get_voltage_sel(struct regulator_dev *dev) +static int tps62360_dcdc_get_voltage(struct regulator_dev *dev) { struct tps62360_chip *tps = rdev_get_drvdata(dev); int vsel; @@ -130,312 +126,196 @@ static int tps62360_dcdc_get_voltage_sel(struct regulator_dev *dev) ret = regmap_read(tps->regmap, REG_VSET0 + tps->curr_vset_id, &data); if (ret < 0) { - dev_err(tps->dev, "%s(): register %d read failed with err %d\n", - __func__, REG_VSET0 + tps->curr_vset_id, ret); + dev_err(tps->dev, "%s: Error in reading register %d\n", + __func__, REG_VSET0 + tps->curr_vset_id); return ret; } vsel = (int)data & tps->voltage_reg_mask; - return vsel; + return (tps->voltage_base + vsel * 10) * 1000; } -static int tps62360_dcdc_set_voltage_sel(struct regulator_dev *dev, - unsigned selector) +static int tps62360_dcdc_set_voltage(struct regulator_dev *dev, + int min_uV, int max_uV, unsigned *selector) { struct tps62360_chip *tps = rdev_get_drvdata(dev); + int vsel; int ret; bool found = false; int new_vset_id = tps->curr_vset_id; + if (max_uV < min_uV) + return -EINVAL; + + if (min_uV > + ((tps->voltage_base + (tps->desc.n_voltages - 1) * 10) * 1000)) + return -EINVAL; + + if (max_uV < tps->voltage_base * 1000) + return -EINVAL; + + vsel = DIV_ROUND_UP(min_uV - (tps->voltage_base * 1000), 10000); + if (selector) + *selector = (vsel & tps->voltage_reg_mask); + /* * If gpios are available to select the VSET register then least * recently used register for new configuration. */ if (tps->valid_gpios) - found = find_voltage_set_register(tps, selector, &new_vset_id); + found = find_voltage_set_register(tps, vsel, &new_vset_id); if (!found) { ret = regmap_update_bits(tps->regmap, REG_VSET0 + new_vset_id, - tps->voltage_reg_mask, selector); + tps->voltage_reg_mask, vsel); if (ret < 0) { - dev_err(tps->dev, - "%s(): register %d update failed with err %d\n", - __func__, REG_VSET0 + new_vset_id, ret); + dev_err(tps->dev, "%s: Error in updating register %d\n", + __func__, REG_VSET0 + new_vset_id); return ret; } tps->curr_vset_id = new_vset_id; - tps->curr_vset_vsel[new_vset_id] = selector; + tps->curr_vset_vsel[new_vset_id] = vsel; } /* Select proper VSET register vio gpios */ if (tps->valid_gpios) { - gpio_set_value_cansleep(tps->vsel0_gpio, new_vset_id & 0x1); + gpio_set_value_cansleep(tps->vsel0_gpio, + new_vset_id & 0x1); gpio_set_value_cansleep(tps->vsel1_gpio, (new_vset_id >> 1) & 0x1); } return 0; } -static int tps62360_set_voltage_time_sel(struct regulator_dev *rdev, - unsigned int old_selector, unsigned int new_selector) +static int tps62360_dcdc_list_voltage(struct regulator_dev *dev, + unsigned selector) { - struct tps62360_chip *tps = rdev_get_drvdata(rdev); - int old_uV, new_uV; - - old_uV = regulator_list_voltage_linear(rdev, old_selector); - if (old_uV < 0) - return old_uV; - - new_uV = regulator_list_voltage_linear(rdev, new_selector); - if (new_uV < 0) - return new_uV; - - return DIV_ROUND_UP(abs(old_uV - new_uV), tps->change_uv_per_us); -} - -static int tps62360_set_mode(struct regulator_dev *rdev, unsigned int mode) -{ - struct tps62360_chip *tps = rdev_get_drvdata(rdev); - int i; - int val; - int ret; - - /* Enable force PWM mode in FAST mode only. */ - switch (mode) { - case REGULATOR_MODE_FAST: - val = FORCE_PWM_ENABLE; - break; - - case REGULATOR_MODE_NORMAL: - val = 0; - break; + struct tps62360_chip *tps = rdev_get_drvdata(dev); - default: + if (selector >= tps->desc.n_voltages) return -EINVAL; - } - - if (!tps->valid_gpios) { - ret = regmap_update_bits(tps->regmap, - REG_VSET0 + tps->curr_vset_id, FORCE_PWM_ENABLE, val); - if (ret < 0) - dev_err(tps->dev, - "%s(): register %d update failed with err %d\n", - __func__, REG_VSET0 + tps->curr_vset_id, ret); - return ret; - } - - /* If gpios are valid then all register set need to be control */ - for (i = 0; i < 4; ++i) { - ret = regmap_update_bits(tps->regmap, - REG_VSET0 + i, FORCE_PWM_ENABLE, val); - if (ret < 0) { - dev_err(tps->dev, - "%s(): register %d update failed with err %d\n", - __func__, REG_VSET0 + i, ret); - return ret; - } - } - return ret; + return (tps->voltage_base + selector * 10) * 1000; } -static unsigned int tps62360_get_mode(struct regulator_dev *rdev) +static struct regulator_ops tps62360_dcdc_ops = { + .get_voltage = tps62360_dcdc_get_voltage, + .set_voltage = tps62360_dcdc_set_voltage, + .list_voltage = tps62360_dcdc_list_voltage, +}; + +static int tps62360_init_force_pwm(struct tps62360_chip *tps, + struct tps62360_regulator_platform_data *pdata, + int vset_id) { - struct tps62360_chip *tps = rdev_get_drvdata(rdev); unsigned int data; int ret; - - ret = regmap_read(tps->regmap, REG_VSET0 + tps->curr_vset_id, &data); + ret = regmap_read(tps->regmap, REG_VSET0 + vset_id, &data); if (ret < 0) { - dev_err(tps->dev, "%s(): register %d read failed with err %d\n", - __func__, REG_VSET0 + tps->curr_vset_id, ret); + dev_err(tps->dev, "%s() fails in writing reg %d\n", + __func__, REG_VSET0 + vset_id); return ret; } - return (data & FORCE_PWM_ENABLE) ? - REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL; + tps->curr_vset_vsel[vset_id] = data & tps->voltage_reg_mask; + if (pdata->en_force_pwm) + data |= BIT(7); + else + data &= ~BIT(7); + ret = regmap_write(tps->regmap, REG_VSET0 + vset_id, data); + if (ret < 0) + dev_err(tps->dev, "%s() fails in writing reg %d\n", + __func__, REG_VSET0 + vset_id); + return ret; } -static struct regulator_ops tps62360_dcdc_ops = { - .get_voltage_sel = tps62360_dcdc_get_voltage_sel, - .set_voltage_sel = tps62360_dcdc_set_voltage_sel, - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, - .set_voltage_time_sel = tps62360_set_voltage_time_sel, - .set_mode = tps62360_set_mode, - .get_mode = tps62360_get_mode, -}; - -static int __devinit tps62360_init_dcdc(struct tps62360_chip *tps, +static int tps62360_init_dcdc(struct tps62360_chip *tps, struct tps62360_regulator_platform_data *pdata) { int ret; - unsigned int ramp_ctrl; + int i; - /* Initialize internal pull up/down control */ + /* Initailize internal pull up/down control */ if (tps->en_internal_pulldn) ret = regmap_write(tps->regmap, REG_CONTROL, 0xE0); else ret = regmap_write(tps->regmap, REG_CONTROL, 0x0); if (ret < 0) { - dev_err(tps->dev, - "%s(): register %d write failed with err %d\n", - __func__, REG_CONTROL, ret); - return ret; - } - - /* Reset output discharge path to reduce power consumption */ - ret = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), 0); - if (ret < 0) { - dev_err(tps->dev, - "%s(): register %d update failed with err %d\n", - __func__, REG_RAMPCTRL, ret); + dev_err(tps->dev, "%s() fails in writing reg %d\n", + __func__, REG_CONTROL); return ret; } - /* Get ramp value from ramp control register */ - ret = regmap_read(tps->regmap, REG_RAMPCTRL, &ramp_ctrl); - if (ret < 0) { - dev_err(tps->dev, - "%s(): register %d read failed with err %d\n", - __func__, REG_RAMPCTRL, ret); - return ret; + /* Initailize force PWM mode */ + if (tps->valid_gpios) { + for (i = 0; i < 4; ++i) { + ret = tps62360_init_force_pwm(tps, pdata, i); + if (ret < 0) + return ret; + } + } else { + ret = tps62360_init_force_pwm(tps, pdata, tps->curr_vset_id); + if (ret < 0) + return ret; } - ramp_ctrl = (ramp_ctrl >> 4) & 0x7; - /* ramp mV/us = 32/(2^ramp_ctrl) */ - tps->change_uv_per_us = DIV_ROUND_UP(32000, BIT(ramp_ctrl)); + /* Reset output discharge path to reduce power consumption */ + ret = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), 0); + if (ret < 0) + dev_err(tps->dev, "%s() fails in updating reg %d\n", + __func__, REG_RAMPCTRL); return ret; } static const struct regmap_config tps62360_regmap_config = { - .reg_bits = 8, - .val_bits = 8, - .max_register = REG_CHIPID, - .cache_type = REGCACHE_RBTREE, + .reg_bits = 8, + .val_bits = 8, }; -static struct tps62360_regulator_platform_data * - of_get_tps62360_platform_data(struct device *dev) -{ - struct tps62360_regulator_platform_data *pdata; - struct device_node *np = dev->of_node; - - pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) { - dev_err(dev, "Memory alloc failed for platform data\n"); - return NULL; - } - - pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node); - if (!pdata->reg_init_data) { - dev_err(dev, "Not able to get OF regulator init data\n"); - return NULL; - } - - pdata->vsel0_gpio = of_get_named_gpio(np, "vsel0-gpio", 0); - pdata->vsel1_gpio = of_get_named_gpio(np, "vsel1-gpio", 0); - - if (of_find_property(np, "ti,vsel0-state-high", NULL)) - pdata->vsel0_def_state = 1; - - if (of_find_property(np, "ti,vsel1-state-high", NULL)) - pdata->vsel1_def_state = 1; - - if (of_find_property(np, "ti,enable-pull-down", NULL)) - pdata->en_internal_pulldn = true; - - if (of_find_property(np, "ti,enable-vout-discharge", NULL)) - pdata->en_discharge = true; - - return pdata; -} - -#if defined(CONFIG_OF) -static const struct of_device_id tps62360_of_match[] = { - { .compatible = "ti,tps62360", .data = (void *)TPS62360}, - { .compatible = "ti,tps62361", .data = (void *)TPS62361}, - { .compatible = "ti,tps62362", .data = (void *)TPS62362}, - { .compatible = "ti,tps62363", .data = (void *)TPS62363}, - {}, -}; -MODULE_DEVICE_TABLE(of, tps62360_of_match); -#endif - static int __devinit tps62360_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct regulator_config config = { }; struct tps62360_regulator_platform_data *pdata; struct regulator_dev *rdev; struct tps62360_chip *tps; int ret; int i; - int chip_id; pdata = client->dev.platform_data; - chip_id = id->driver_data; - - if (client->dev.of_node) { - const struct of_device_id *match; - match = of_match_device(of_match_ptr(tps62360_of_match), - &client->dev); - if (!match) { - dev_err(&client->dev, "Error: No device match found\n"); - return -ENODEV; - } - chip_id = (int)match->data; - if (!pdata) - pdata = of_get_tps62360_platform_data(&client->dev); - } - if (!pdata) { - dev_err(&client->dev, "%s(): Platform data not found\n", + dev_err(&client->dev, "%s() Err: Platform data not found\n", __func__); return -EIO; } tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); if (!tps) { - dev_err(&client->dev, "%s(): Memory allocation failed\n", + dev_err(&client->dev, "%s() Err: Memory allocation fails\n", __func__); return -ENOMEM; } + tps->en_force_pwm = pdata->en_force_pwm; tps->en_discharge = pdata->en_discharge; tps->en_internal_pulldn = pdata->en_internal_pulldn; tps->vsel0_gpio = pdata->vsel0_gpio; tps->vsel1_gpio = pdata->vsel1_gpio; + tps->client = client; tps->dev = &client->dev; - - switch (chip_id) { - case TPS62360: - case TPS62362: - tps->voltage_base = TPS62360_BASE_VOLTAGE; - tps->voltage_reg_mask = 0x3F; - tps->desc.n_voltages = TPS62360_N_VOLTAGES; - break; - case TPS62361: - case TPS62363: - tps->voltage_base = TPS62361_BASE_VOLTAGE; - tps->voltage_reg_mask = 0x7F; - tps->desc.n_voltages = TPS62361_N_VOLTAGES; - break; - default: - return -ENODEV; - } + tps->name = id->name; + tps->voltage_base = (id->driver_data == TPS62360) ? + TPS62360_BASE_VOLTAGE : TPS62361_BASE_VOLTAGE; + tps->voltage_reg_mask = (id->driver_data == TPS62360) ? 0x3F : 0x7F; tps->desc.name = id->name; tps->desc.id = 0; + tps->desc.n_voltages = (id->driver_data == TPS62360) ? + TPS62360_N_VOLTAGES : TPS62361_N_VOLTAGES; tps->desc.ops = &tps62360_dcdc_ops; tps->desc.type = REGULATOR_VOLTAGE; tps->desc.owner = THIS_MODULE; - tps->desc.min_uV = tps->voltage_base; - tps->desc.uV_step = 10000; - - tps->regmap = devm_regmap_init_i2c(client, &tps62360_regmap_config); + tps->regmap = regmap_init_i2c(client, &tps62360_regmap_config); if (IS_ERR(tps->regmap)) { ret = PTR_ERR(tps->regmap); - dev_err(&client->dev, - "%s(): regmap allocation failed with err %d\n", - __func__, ret); + dev_err(&client->dev, "%s() Err: Failed to allocate register" + "map: %d\n", __func__, ret); return ret; } i2c_set_clientdata(client, tps); @@ -446,26 +326,35 @@ static int __devinit tps62360_probe(struct i2c_client *client, tps->valid_gpios = false; if (gpio_is_valid(tps->vsel0_gpio) && gpio_is_valid(tps->vsel1_gpio)) { - int gpio_flags; - gpio_flags = (pdata->vsel0_def_state) ? - GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; - ret = gpio_request_one(tps->vsel0_gpio, - gpio_flags, "tps62360-vsel0"); + ret = gpio_request(tps->vsel0_gpio, "tps62360-vsel0"); if (ret) { dev_err(&client->dev, - "%s(): Could not obtain vsel0 GPIO %d: %d\n", - __func__, tps->vsel0_gpio, ret); + "Err: Could not obtain vsel0 GPIO %d: %d\n", + tps->vsel0_gpio, ret); + goto err_gpio0; + } + ret = gpio_direction_output(tps->vsel0_gpio, + pdata->vsel0_def_state); + if (ret) { + dev_err(&client->dev, "Err: Could not set direction of" + "vsel0 GPIO %d: %d\n", tps->vsel0_gpio, ret); + gpio_free(tps->vsel0_gpio); goto err_gpio0; } - gpio_flags = (pdata->vsel1_def_state) ? - GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; - ret = gpio_request_one(tps->vsel1_gpio, - gpio_flags, "tps62360-vsel1"); + ret = gpio_request(tps->vsel1_gpio, "tps62360-vsel1"); if (ret) { dev_err(&client->dev, - "%s(): Could not obtain vsel1 GPIO %d: %d\n", - __func__, tps->vsel1_gpio, ret); + "Err: Could not obtain vsel1 GPIO %d: %d\n", + tps->vsel1_gpio, ret); + goto err_gpio1; + } + ret = gpio_direction_output(tps->vsel1_gpio, + pdata->vsel1_def_state); + if (ret) { + dev_err(&client->dev, "Err: Could not set direction of" + "vsel1 GPIO %d: %d\n", tps->vsel1_gpio, ret); + gpio_free(tps->vsel1_gpio); goto err_gpio1; } tps->valid_gpios = true; @@ -482,22 +371,17 @@ static int __devinit tps62360_probe(struct i2c_client *client, ret = tps62360_init_dcdc(tps, pdata); if (ret < 0) { - dev_err(tps->dev, "%s(): Init failed with err = %d\n", + dev_err(tps->dev, "%s() Err: Init fails with = %d\n", __func__, ret); goto err_init; } - config.dev = &client->dev; - config.init_data = pdata->reg_init_data; - config.driver_data = tps; - config.of_node = client->dev.of_node; - /* Register the regulators */ - rdev = regulator_register(&tps->desc, &config); + rdev = regulator_register(&tps->desc, &client->dev, + &pdata->reg_init_data, tps, NULL); if (IS_ERR(rdev)) { - dev_err(tps->dev, - "%s(): regulator register failed with err %s\n", - __func__, id->name); + dev_err(tps->dev, "%s() Err: Failed to register %s\n", + __func__, id->name); ret = PTR_ERR(rdev); goto err_init; } @@ -512,6 +396,7 @@ static int __devinit tps62360_probe(struct i2c_client *client, if (gpio_is_valid(tps->vsel0_gpio)) gpio_free(tps->vsel0_gpio); err_gpio0: + regmap_exit(tps->regmap); return ret; } @@ -532,6 +417,7 @@ static int __devexit tps62360_remove(struct i2c_client *client) gpio_free(tps->vsel0_gpio); regulator_unregister(tps->rdev); + regmap_exit(tps->regmap); return 0; } @@ -546,16 +432,13 @@ static void tps62360_shutdown(struct i2c_client *client) /* Configure the output discharge path */ st = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), BIT(2)); if (st < 0) - dev_err(tps->dev, - "%s(): register %d update failed with err %d\n", - __func__, REG_RAMPCTRL, st); + dev_err(tps->dev, "%s() fails in updating reg %d\n", + __func__, REG_RAMPCTRL); } static const struct i2c_device_id tps62360_id[] = { {.name = "tps62360", .driver_data = TPS62360}, {.name = "tps62361", .driver_data = TPS62361}, - {.name = "tps62362", .driver_data = TPS62362}, - {.name = "tps62363", .driver_data = TPS62363}, {}, }; @@ -565,7 +448,6 @@ static struct i2c_driver tps62360_i2c_driver = { .driver = { .name = "tps62360", .owner = THIS_MODULE, - .of_match_table = of_match_ptr(tps62360_of_match), }, .probe = tps62360_probe, .remove = __devexit_p(tps62360_remove), @@ -586,5 +468,5 @@ static void __exit tps62360_cleanup(void) module_exit(tps62360_cleanup); MODULE_AUTHOR("Laxman Dewangan "); -MODULE_DESCRIPTION("TPS6236x voltage regulator driver"); +MODULE_DESCRIPTION("TPS62360 voltage regulator driver"); MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/regulator/tps65023-regulator.c b/trunk/drivers/regulator/tps65023-regulator.c index f841bd0db6aa..43e4902d7af8 100644 --- a/trunk/drivers/regulator/tps65023-regulator.c +++ b/trunk/drivers/regulator/tps65023-regulator.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -71,7 +72,7 @@ /* LDO_CTRL bitfields */ #define TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_id) ((ldo_id)*4) -#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id) (0x0F << ((ldo_id)*4)) +#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id) (0xF0 >> ((ldo_id)*4)) /* Number of step-down converters available */ #define TPS65023_NUM_DCDC 3 @@ -138,6 +139,7 @@ struct tps_info { /* PMIC details */ struct tps_pmic { struct regulator_desc desc[TPS65023_NUM_REGULATOR]; + struct i2c_client *client; struct regulator_dev *rdev[TPS65023_NUM_REGULATOR]; const struct tps_info *info[TPS65023_NUM_REGULATOR]; struct regmap *regmap; @@ -150,6 +152,96 @@ struct tps_driver_data { u8 core_regulator; }; +static int tps65023_dcdc_is_enabled(struct regulator_dev *dev) +{ + struct tps_pmic *tps = rdev_get_drvdata(dev); + int data, dcdc = rdev_get_id(dev); + int ret; + u8 shift; + + if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3) + return -EINVAL; + + shift = TPS65023_NUM_REGULATOR - dcdc; + ret = regmap_read(tps->regmap, TPS65023_REG_REG_CTRL, &data); + + if (ret != 0) + return ret; + else + return (data & 1< TPS65023_LDO_2) + return -EINVAL; + + shift = (ldo == TPS65023_LDO_1 ? 1 : 2); + ret = regmap_read(tps->regmap, TPS65023_REG_REG_CTRL, &data); + + if (ret != 0) + return ret; + else + return (data & 1< TPS65023_DCDC_3) + return -EINVAL; + + shift = TPS65023_NUM_REGULATOR - dcdc; + return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 1 << shift); +} + +static int tps65023_dcdc_disable(struct regulator_dev *dev) +{ + struct tps_pmic *tps = rdev_get_drvdata(dev); + int dcdc = rdev_get_id(dev); + u8 shift; + + if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3) + return -EINVAL; + + shift = TPS65023_NUM_REGULATOR - dcdc; + return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 0); +} + +static int tps65023_ldo_enable(struct regulator_dev *dev) +{ + struct tps_pmic *tps = rdev_get_drvdata(dev); + int ldo = rdev_get_id(dev); + u8 shift; + + if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2) + return -EINVAL; + + shift = (ldo == TPS65023_LDO_1 ? 1 : 2); + return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 1 << shift); +} + +static int tps65023_ldo_disable(struct regulator_dev *dev) +{ + struct tps_pmic *tps = rdev_get_drvdata(dev); + int ldo = rdev_get_id(dev); + u8 shift; + + if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2) + return -EINVAL; + + shift = (ldo == TPS65023_LDO_1 ? 1 : 2); + return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 0); +} + static int tps65023_dcdc_get_voltage(struct regulator_dev *dev) { struct tps_pmic *tps = rdev_get_drvdata(dev); @@ -169,28 +261,50 @@ static int tps65023_dcdc_get_voltage(struct regulator_dev *dev) return tps->info[dcdc]->min_uV; } -static int tps65023_dcdc_set_voltage_sel(struct regulator_dev *dev, - unsigned selector) +static int tps65023_dcdc_set_voltage(struct regulator_dev *dev, + int min_uV, int max_uV, + unsigned *selector) { struct tps_pmic *tps = rdev_get_drvdata(dev); int dcdc = rdev_get_id(dev); + int vsel; int ret; if (dcdc != tps->core_regulator) return -EINVAL; + if (min_uV < tps->info[dcdc]->min_uV + || min_uV > tps->info[dcdc]->max_uV) + return -EINVAL; + if (max_uV < tps->info[dcdc]->min_uV + || max_uV > tps->info[dcdc]->max_uV) + return -EINVAL; + + for (vsel = 0; vsel < tps->info[dcdc]->table_len; vsel++) { + int mV = tps->info[dcdc]->table[vsel]; + int uV = mV * 1000; + + /* Break at the first in-range value */ + if (min_uV <= uV && uV <= max_uV) + break; + } - ret = regmap_write(tps->regmap, TPS65023_REG_DEF_CORE, selector); - if (ret) - goto out; + *selector = vsel; + + if (vsel == tps->info[dcdc]->table_len) + goto failed; + + ret = regmap_write(tps->regmap, TPS65023_REG_DEF_CORE, vsel); /* Tell the chip that we have changed the value in DEFCORE * and its time to update the core voltage */ - ret = regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2, - TPS65023_REG_CTRL2_GO, TPS65023_REG_CTRL2_GO); + regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2, + TPS65023_REG_CTRL2_GO, TPS65023_REG_CTRL2_GO); -out: return ret; + +failed: + return -EINVAL; } static int tps65023_ldo_get_voltage(struct regulator_dev *dev) @@ -211,15 +325,42 @@ static int tps65023_ldo_get_voltage(struct regulator_dev *dev) return tps->info[ldo]->table[data] * 1000; } -static int tps65023_ldo_set_voltage_sel(struct regulator_dev *dev, - unsigned selector) +static int tps65023_ldo_set_voltage(struct regulator_dev *dev, + int min_uV, int max_uV, unsigned *selector) { struct tps_pmic *tps = rdev_get_drvdata(dev); - int ldo_index = rdev_get_id(dev) - TPS65023_LDO_1; + int data, vsel, ldo = rdev_get_id(dev); + int ret; + + if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2) + return -EINVAL; - return regmap_update_bits(tps->regmap, TPS65023_REG_LDO_CTRL, - TPS65023_LDO_CTRL_LDOx_MASK(ldo_index), - selector << TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_index)); + if (min_uV < tps->info[ldo]->min_uV || min_uV > tps->info[ldo]->max_uV) + return -EINVAL; + if (max_uV < tps->info[ldo]->min_uV || max_uV > tps->info[ldo]->max_uV) + return -EINVAL; + + for (vsel = 0; vsel < tps->info[ldo]->table_len; vsel++) { + int mV = tps->info[ldo]->table[vsel]; + int uV = mV * 1000; + + /* Break at the first in-range value */ + if (min_uV <= uV && uV <= max_uV) + break; + } + + if (vsel == tps->info[ldo]->table_len) + return -EINVAL; + + *selector = vsel; + + ret = regmap_read(tps->regmap, TPS65023_REG_LDO_CTRL, &data); + if (ret != 0) + return ret; + + data &= TPS65023_LDO_CTRL_LDOx_MASK(ldo - TPS65023_LDO_1); + data |= (vsel << (TPS65023_LDO_CTRL_LDOx_SHIFT(ldo - TPS65023_LDO_1))); + return regmap_write(tps->regmap, TPS65023_REG_LDO_CTRL, data); } static int tps65023_dcdc_list_voltage(struct regulator_dev *dev, @@ -257,21 +398,21 @@ static int tps65023_ldo_list_voltage(struct regulator_dev *dev, /* Operations permitted on VDCDCx */ static struct regulator_ops tps65023_dcdc_ops = { - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, + .is_enabled = tps65023_dcdc_is_enabled, + .enable = tps65023_dcdc_enable, + .disable = tps65023_dcdc_disable, .get_voltage = tps65023_dcdc_get_voltage, - .set_voltage_sel = tps65023_dcdc_set_voltage_sel, + .set_voltage = tps65023_dcdc_set_voltage, .list_voltage = tps65023_dcdc_list_voltage, }; /* Operations permitted on LDOx */ static struct regulator_ops tps65023_ldo_ops = { - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, + .is_enabled = tps65023_ldo_is_enabled, + .enable = tps65023_ldo_enable, + .disable = tps65023_ldo_disable, .get_voltage = tps65023_ldo_get_voltage, - .set_voltage_sel = tps65023_ldo_set_voltage_sel, + .set_voltage = tps65023_ldo_set_voltage, .list_voltage = tps65023_ldo_list_voltage, }; @@ -285,7 +426,6 @@ static int __devinit tps_65023_probe(struct i2c_client *client, { const struct tps_driver_data *drv_data = (void *)id->driver_data; const struct tps_info *info = drv_data->info; - struct regulator_config config = { }; struct regulator_init_data *init_data; struct regulator_dev *rdev; struct tps_pmic *tps; @@ -303,19 +443,20 @@ static int __devinit tps_65023_probe(struct i2c_client *client, if (!init_data) return -EIO; - tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); + tps = kzalloc(sizeof(*tps), GFP_KERNEL); if (!tps) return -ENOMEM; - tps->regmap = devm_regmap_init_i2c(client, &tps65023_regmap_config); + tps->regmap = regmap_init_i2c(client, &tps65023_regmap_config); if (IS_ERR(tps->regmap)) { error = PTR_ERR(tps->regmap); dev_err(&client->dev, "Failed to allocate register map: %d\n", error); - return error; + goto fail_alloc; } /* common for all regulators */ + tps->client = client; tps->core_regulator = drv_data->core_regulator; for (i = 0; i < TPS65023_NUM_REGULATOR; i++, info++, init_data++) { @@ -330,22 +471,9 @@ static int __devinit tps_65023_probe(struct i2c_client *client, tps->desc[i].type = REGULATOR_VOLTAGE; tps->desc[i].owner = THIS_MODULE; - tps->desc[i].enable_reg = TPS65023_REG_REG_CTRL; - if (i == TPS65023_LDO_1) - tps->desc[i].enable_mask = 1 << 1; - else if (i == TPS65023_LDO_2) - tps->desc[i].enable_mask = 1 << 2; - else /* DCDCx */ - tps->desc[i].enable_mask = - 1 << (TPS65023_NUM_REGULATOR - i); - - config.dev = &client->dev; - config.init_data = init_data; - config.driver_data = tps; - config.regmap = tps->regmap; - /* Register the regulators */ - rdev = regulator_register(&tps->desc[i], &config); + rdev = regulator_register(&tps->desc[i], &client->dev, + init_data, tps, NULL); if (IS_ERR(rdev)) { dev_err(&client->dev, "failed to register %s\n", id->name); @@ -368,9 +496,19 @@ static int __devinit tps_65023_probe(struct i2c_client *client, fail: while (--i >= 0) regulator_unregister(tps->rdev[i]); + + regmap_exit(tps->regmap); + fail_alloc: + kfree(tps); return error; } +/** + * tps_65023_remove - TPS65023 driver i2c remove handler + * @client: i2c driver client device structure + * + * Unregister TPS driver as an i2c client device driver + */ static int __devexit tps_65023_remove(struct i2c_client *client) { struct tps_pmic *tps = i2c_get_clientdata(client); @@ -378,6 +516,10 @@ static int __devexit tps_65023_remove(struct i2c_client *client) for (i = 0; i < TPS65023_NUM_REGULATOR; i++) regulator_unregister(tps->rdev[i]); + + regmap_exit(tps->regmap); + kfree(tps); + return 0; } @@ -496,13 +638,13 @@ static struct tps_driver_data tps65020_drv_data = { }; static struct tps_driver_data tps65021_drv_data = { - .info = tps65021_regs, - .core_regulator = TPS65023_DCDC_3, + .info = tps65021_regs, + .core_regulator = TPS65023_DCDC_3, }; static struct tps_driver_data tps65023_drv_data = { - .info = tps65023_regs, - .core_regulator = TPS65023_DCDC_1, + .info = tps65023_regs, + .core_regulator = TPS65023_DCDC_1, }; static const struct i2c_device_id tps_65023_id[] = { @@ -527,12 +669,22 @@ static struct i2c_driver tps_65023_i2c_driver = { .id_table = tps_65023_id, }; +/** + * tps_65023_init + * + * Module init function + */ static int __init tps_65023_init(void) { return i2c_add_driver(&tps_65023_i2c_driver); } subsys_initcall(tps_65023_init); +/** + * tps_65023_cleanup + * + * Module exit function + */ static void __exit tps_65023_cleanup(void) { i2c_del_driver(&tps_65023_i2c_driver); diff --git a/trunk/drivers/regulator/tps6507x-regulator.c b/trunk/drivers/regulator/tps6507x-regulator.c index da38be1016aa..832833fe8aad 100644 --- a/trunk/drivers/regulator/tps6507x-regulator.c +++ b/trunk/drivers/regulator/tps6507x-regulator.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -282,7 +283,7 @@ static int tps6507x_pmic_disable(struct regulator_dev *dev) 1 << shift); } -static int tps6507x_pmic_get_voltage_sel(struct regulator_dev *dev) +static int tps6507x_pmic_get_voltage(struct regulator_dev *dev) { struct tps6507x_pmic *tps = rdev_get_drvdata(dev); int data, rid = rdev_get_id(dev); @@ -324,7 +325,7 @@ static int tps6507x_pmic_get_voltage_sel(struct regulator_dev *dev) return data; data &= mask; - return data; + return tps->info[rid]->table[data] * 1000; } static int tps6507x_pmic_set_voltage_sel(struct regulator_dev *dev, @@ -394,7 +395,7 @@ static struct regulator_ops tps6507x_pmic_ops = { .is_enabled = tps6507x_pmic_is_enabled, .enable = tps6507x_pmic_enable, .disable = tps6507x_pmic_disable, - .get_voltage_sel = tps6507x_pmic_get_voltage_sel, + .get_voltage = tps6507x_pmic_get_voltage, .set_voltage_sel = tps6507x_pmic_set_voltage_sel, .list_voltage = tps6507x_pmic_list_voltage, }; @@ -403,7 +404,6 @@ static __devinit int tps6507x_pmic_probe(struct platform_device *pdev) { struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); struct tps_info *info = &tps6507x_pmic_regs[0]; - struct regulator_config config = { }; struct regulator_init_data *init_data; struct regulator_dev *rdev; struct tps6507x_pmic *tps; @@ -428,7 +428,7 @@ static __devinit int tps6507x_pmic_probe(struct platform_device *pdev) if (!init_data) return -EINVAL; - tps = devm_kzalloc(&pdev->dev, sizeof(*tps), GFP_KERNEL); + tps = kzalloc(sizeof(*tps), GFP_KERNEL); if (!tps) return -ENOMEM; @@ -453,11 +453,8 @@ static __devinit int tps6507x_pmic_probe(struct platform_device *pdev) tps->desc[i].type = REGULATOR_VOLTAGE; tps->desc[i].owner = THIS_MODULE; - config.dev = tps6507x_dev->dev; - config.init_data = init_data; - config.driver_data = tps; - - rdev = regulator_register(&tps->desc[i], &config); + rdev = regulator_register(&tps->desc[i], + tps6507x_dev->dev, init_data, tps, NULL); if (IS_ERR(rdev)) { dev_err(tps6507x_dev->dev, "failed to register %s regulator\n", @@ -478,6 +475,8 @@ static __devinit int tps6507x_pmic_probe(struct platform_device *pdev) fail: while (--i >= 0) regulator_unregister(tps->rdev[i]); + + kfree(tps); return error; } @@ -489,6 +488,9 @@ static int __devexit tps6507x_pmic_remove(struct platform_device *pdev) for (i = 0; i < TPS6507X_NUM_REGULATOR; i++) regulator_unregister(tps->rdev[i]); + + kfree(tps); + return 0; } diff --git a/trunk/drivers/regulator/tps65090-regulator.c b/trunk/drivers/regulator/tps65090-regulator.c deleted file mode 100644 index 001ad554ac62..000000000000 --- a/trunk/drivers/regulator/tps65090-regulator.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Regulator driver for tps65090 power management chip. - * - * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. - - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct tps65090_regulator { - int id; - /* used by regulator core */ - struct regulator_desc desc; - - /* Device */ - struct device *dev; -}; - -static struct regulator_ops tps65090_ops = { - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, -}; - -#define tps65090_REG(_id) \ -{ \ - .id = TPS65090_ID_##_id, \ - .desc = { \ - .name = tps65090_rails(_id), \ - .id = TPS65090_ID_##_id, \ - .ops = &tps65090_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .enable_reg = (TPS65090_ID_##_id) + 12, \ - .enable_mask = BIT(0), \ - }, \ -} - -static struct tps65090_regulator TPS65090_regulator[] = { - tps65090_REG(DCDC1), - tps65090_REG(DCDC2), - tps65090_REG(DCDC3), - tps65090_REG(FET1), - tps65090_REG(FET2), - tps65090_REG(FET3), - tps65090_REG(FET4), - tps65090_REG(FET5), - tps65090_REG(FET6), - tps65090_REG(FET7), -}; - -static inline struct tps65090_regulator *find_regulator_info(int id) -{ - struct tps65090_regulator *ri; - int i; - - for (i = 0; i < ARRAY_SIZE(TPS65090_regulator); i++) { - ri = &TPS65090_regulator[i]; - if (ri->desc.id == id) - return ri; - } - return NULL; -} - -static int __devinit tps65090_regulator_probe(struct platform_device *pdev) -{ - struct tps65090 *tps65090_mfd = dev_get_drvdata(pdev->dev.parent); - struct tps65090_regulator *ri = NULL; - struct regulator_config config = { }; - struct regulator_dev *rdev; - struct tps65090_regulator_platform_data *tps_pdata; - int id = pdev->id; - - dev_dbg(&pdev->dev, "Probing regulator %d\n", id); - - ri = find_regulator_info(id); - if (ri == NULL) { - dev_err(&pdev->dev, "invalid regulator ID specified\n"); - return -EINVAL; - } - tps_pdata = pdev->dev.platform_data; - ri->dev = &pdev->dev; - - config.dev = &pdev->dev; - config.init_data = &tps_pdata->regulator; - config.driver_data = ri; - config.regmap = tps65090_mfd->rmap; - - rdev = regulator_register(&ri->desc, &config); - if (IS_ERR(rdev)) { - dev_err(&pdev->dev, "failed to register regulator %s\n", - ri->desc.name); - return PTR_ERR(rdev); - } - - platform_set_drvdata(pdev, rdev); - return 0; -} - -static int __devexit tps65090_regulator_remove(struct platform_device *pdev) -{ - struct regulator_dev *rdev = platform_get_drvdata(pdev); - - regulator_unregister(rdev); - return 0; -} - -static struct platform_driver tps65090_regulator_driver = { - .driver = { - .name = "tps65090-regulator", - .owner = THIS_MODULE, - }, - .probe = tps65090_regulator_probe, - .remove = __devexit_p(tps65090_regulator_remove), -}; - -static int __init tps65090_regulator_init(void) -{ - return platform_driver_register(&tps65090_regulator_driver); -} -subsys_initcall(tps65090_regulator_init); - -static void __exit tps65090_regulator_exit(void) -{ - platform_driver_unregister(&tps65090_regulator_driver); -} -module_exit(tps65090_regulator_exit); - -MODULE_DESCRIPTION("tps65090 regulator driver"); -MODULE_AUTHOR("Venu Byravarasu "); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/regulator/tps65217-regulator.c b/trunk/drivers/regulator/tps65217-regulator.c index 9d371d2cbcae..e39521b42772 100644 --- a/trunk/drivers/regulator/tps65217-regulator.c +++ b/trunk/drivers/regulator/tps65217-regulator.c @@ -213,56 +213,65 @@ static int tps65217_pmic_get_voltage_sel(struct regulator_dev *dev) return selector; } -static int tps65217_pmic_set_voltage_sel(struct regulator_dev *dev, - unsigned selector) +static int tps65217_pmic_ldo1_set_voltage_sel(struct regulator_dev *dev, + unsigned selector) { - int ret; struct tps65217 *tps = rdev_get_drvdata(dev); - unsigned int rid = rdev_get_id(dev); + int ldo = rdev_get_id(dev); - /* Set the voltage based on vsel value and write protect level is 2 */ - ret = tps65217_set_bits(tps, tps->info[rid]->set_vout_reg, - tps->info[rid]->set_vout_mask, - selector, TPS65217_PROTECT_L2); + if (ldo != TPS65217_LDO_1) + return -EINVAL; - /* Set GO bit for DCDCx to initiate voltage transistion */ - switch (rid) { - case TPS65217_DCDC_1 ... TPS65217_DCDC_3: - ret = tps65217_set_bits(tps, TPS65217_REG_DEFSLEW, - TPS65217_DEFSLEW_GO, TPS65217_DEFSLEW_GO, - TPS65217_PROTECT_L2); - break; - } + if (selector >= tps->info[ldo]->table_len) + return -EINVAL; - return ret; + /* Set the voltage based on vsel value and write protect level is 2 */ + return tps65217_set_bits(tps, tps->info[ldo]->set_vout_reg, + tps->info[ldo]->set_vout_mask, + selector, TPS65217_PROTECT_L2); } -static int tps65217_pmic_map_voltage(struct regulator_dev *dev, - int min_uV, int max_uV) +static int tps65217_pmic_set_voltage(struct regulator_dev *dev, + int min_uV, int max_uV, unsigned *selector) { - - struct tps65217 *tps = rdev_get_drvdata(dev); - unsigned int sel, rid = rdev_get_id(dev); int ret; + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int rid = rdev_get_id(dev); - /* LDO1 uses regulator_map_voltage_iterate() */ + /* LDO1 implements set_voltage_sel callback */ if (rid == TPS65217_LDO_1) return -EINVAL; if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) return -EINVAL; - if (min_uV < tps->info[rid]->min_uV || min_uV > tps->info[rid]->max_uV) + if (min_uV < tps->info[rid]->min_uV + || min_uV > tps->info[rid]->max_uV) return -EINVAL; - if (max_uV < tps->info[rid]->min_uV || max_uV > tps->info[rid]->max_uV) + if (max_uV < tps->info[rid]->min_uV + || max_uV > tps->info[rid]->max_uV) return -EINVAL; - ret = tps->info[rid]->uv_to_vsel(min_uV, &sel); + ret = tps->info[rid]->uv_to_vsel(min_uV, selector); if (ret) return ret; - return sel; + /* Set the voltage based on vsel value and write protect level is 2 */ + ret = tps65217_set_bits(tps, tps->info[rid]->set_vout_reg, + tps->info[rid]->set_vout_mask, + *selector, TPS65217_PROTECT_L2); + + /* Set GO bit for DCDCx to initiate voltage transistion */ + switch (rid) { + case TPS65217_DCDC_1 ... TPS65217_DCDC_3: + ret = tps65217_set_bits(tps, TPS65217_REG_DEFSLEW, + TPS65217_DEFSLEW_GO, TPS65217_DEFSLEW_GO, + TPS65217_PROTECT_L2); + break; + } + + return ret; } static int tps65217_pmic_list_voltage(struct regulator_dev *dev, @@ -289,9 +298,8 @@ static struct regulator_ops tps65217_pmic_ops = { .enable = tps65217_pmic_enable, .disable = tps65217_pmic_disable, .get_voltage_sel = tps65217_pmic_get_voltage_sel, - .set_voltage_sel = tps65217_pmic_set_voltage_sel, + .set_voltage = tps65217_pmic_set_voltage, .list_voltage = tps65217_pmic_list_voltage, - .map_voltage = tps65217_pmic_map_voltage, }; /* Operations permitted on LDO1 */ @@ -300,11 +308,11 @@ static struct regulator_ops tps65217_pmic_ldo1_ops = { .enable = tps65217_pmic_enable, .disable = tps65217_pmic_disable, .get_voltage_sel = tps65217_pmic_get_voltage_sel, - .set_voltage_sel = tps65217_pmic_set_voltage_sel, + .set_voltage_sel = tps65217_pmic_ldo1_set_voltage_sel, .list_voltage = tps65217_pmic_list_voltage, }; -static const struct regulator_desc regulators[] = { +static struct regulator_desc regulators[] = { TPS65217_REGULATOR("DCDC1", TPS65217_DCDC_1, tps65217_pmic_ops, 64), TPS65217_REGULATOR("DCDC2", TPS65217_DCDC_2, tps65217_pmic_ops, 64), TPS65217_REGULATOR("DCDC3", TPS65217_DCDC_3, tps65217_pmic_ops, 64), @@ -319,17 +327,13 @@ static int __devinit tps65217_regulator_probe(struct platform_device *pdev) struct regulator_dev *rdev; struct tps65217 *tps; struct tps_info *info = &tps65217_pmic_regs[pdev->id]; - struct regulator_config config = { }; /* Already set by core driver */ tps = dev_to_tps65217(pdev->dev.parent); tps->info[pdev->id] = info; - config.dev = &pdev->dev; - config.init_data = pdev->dev.platform_data; - config.driver_data = tps; - - rdev = regulator_register(®ulators[pdev->id], &config); + rdev = regulator_register(®ulators[pdev->id], &pdev->dev, + pdev->dev.platform_data, tps, NULL); if (IS_ERR(rdev)) return PTR_ERR(rdev); diff --git a/trunk/drivers/regulator/tps6524x-regulator.c b/trunk/drivers/regulator/tps6524x-regulator.c index b88b3df82381..4a421be6d4f2 100644 --- a/trunk/drivers/regulator/tps6524x-regulator.c +++ b/trunk/drivers/regulator/tps6524x-regulator.c @@ -458,10 +458,12 @@ static int list_voltage(struct regulator_dev *rdev, unsigned selector) info->voltages[selector] : -EINVAL); } -static int set_voltage_sel(struct regulator_dev *rdev, unsigned selector) +static int set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, + unsigned *selector) { const struct supply_info *info; struct tps6524x *hw; + unsigned i; hw = rdev_get_drvdata(rdev); info = &supply_info[rdev_get_id(rdev)]; @@ -469,10 +471,20 @@ static int set_voltage_sel(struct regulator_dev *rdev, unsigned selector) if (info->flags & FIXED_VOLTAGE) return -EINVAL; - return write_field(hw, &info->voltage, selector); + for (i = 0; i < info->n_voltages; i++) + if (min_uV <= info->voltages[i] && + max_uV >= info->voltages[i]) + break; + + if (i >= info->n_voltages) + i = info->n_voltages - 1; + + *selector = i; + + return write_field(hw, &info->voltage, i); } -static int get_voltage_sel(struct regulator_dev *rdev) +static int get_voltage(struct regulator_dev *rdev) { const struct supply_info *info; struct tps6524x *hw; @@ -490,7 +502,7 @@ static int get_voltage_sel(struct regulator_dev *rdev) if (WARN_ON(ret >= info->n_voltages)) return -EIO; - return ret; + return info->voltages[ret]; } static int set_current_limit(struct regulator_dev *rdev, int min_uA, @@ -575,8 +587,8 @@ static struct regulator_ops regulator_ops = { .is_enabled = is_supply_enabled, .enable = enable_supply, .disable = disable_supply, - .get_voltage_sel = get_voltage_sel, - .set_voltage_sel = set_voltage_sel, + .get_voltage = get_voltage, + .set_voltage = set_voltage, .list_voltage = list_voltage, .set_current_limit = set_current_limit, .get_current_limit = get_current_limit, @@ -595,6 +607,7 @@ static int pmic_remove(struct spi_device *spi) hw->rdev[i] = NULL; } spi_set_drvdata(spi, NULL); + kfree(hw); return 0; } @@ -604,7 +617,6 @@ static int __devinit pmic_probe(struct spi_device *spi) struct device *dev = &spi->dev; const struct supply_info *info = supply_info; struct regulator_init_data *init_data; - struct regulator_config config = { }; int ret = 0, i; init_data = dev->platform_data; @@ -613,7 +625,7 @@ static int __devinit pmic_probe(struct spi_device *spi) return -EINVAL; } - hw = devm_kzalloc(&spi->dev, sizeof(struct tps6524x), GFP_KERNEL); + hw = kzalloc(sizeof(struct tps6524x), GFP_KERNEL); if (!hw) { dev_err(dev, "cannot allocate regulator private data\n"); return -ENOMEM; @@ -636,11 +648,8 @@ static int __devinit pmic_probe(struct spi_device *spi) if (info->flags & FIXED_VOLTAGE) hw->desc[i].n_voltages = 1; - config.dev = dev; - config.init_data = init_data; - config.driver_data = hw; - - hw->rdev[i] = regulator_register(&hw->desc[i], &config); + hw->rdev[i] = regulator_register(&hw->desc[i], dev, + init_data, hw, NULL); if (IS_ERR(hw->rdev[i])) { ret = PTR_ERR(hw->rdev[i]); hw->rdev[i] = NULL; @@ -664,7 +673,17 @@ static struct spi_driver pmic_driver = { }, }; -module_spi_driver(pmic_driver); +static int __init pmic_driver_init(void) +{ + return spi_register_driver(&pmic_driver); +} +module_init(pmic_driver_init); + +static void __exit pmic_driver_exit(void) +{ + spi_unregister_driver(&pmic_driver); +} +module_exit(pmic_driver_exit); MODULE_DESCRIPTION("TPS6524X PMIC Driver"); MODULE_AUTHOR("Cyril Chemparathy"); diff --git a/trunk/drivers/regulator/tps6586x-regulator.c b/trunk/drivers/regulator/tps6586x-regulator.c index c0a214575380..cfc1f16f7771 100644 --- a/trunk/drivers/regulator/tps6586x-regulator.c +++ b/trunk/drivers/regulator/tps6586x-regulator.c @@ -75,7 +75,8 @@ static inline struct device *to_tps6586x_dev(struct regulator_dev *rdev) return rdev_get_dev(rdev)->parent->parent; } -static int tps6586x_list_voltage(struct regulator_dev *rdev, unsigned selector) +static int tps6586x_ldo_list_voltage(struct regulator_dev *rdev, + unsigned selector) { struct tps6586x_regulator *info = rdev_get_drvdata(rdev); int rid = rdev_get_id(rdev); @@ -88,34 +89,47 @@ static int tps6586x_list_voltage(struct regulator_dev *rdev, unsigned selector) } -static int tps6586x_set_voltage_sel(struct regulator_dev *rdev, - unsigned selector) +static int __tps6586x_ldo_set_voltage(struct device *parent, + struct tps6586x_regulator *ri, + int min_uV, int max_uV, + unsigned *selector) { - struct tps6586x_regulator *ri = rdev_get_drvdata(rdev); - struct device *parent = to_tps6586x_dev(rdev); - int ret, val, rid = rdev_get_id(rdev); + int val, uV; uint8_t mask; - val = selector << ri->volt_shift; - mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift; + for (val = 0; val < ri->desc.n_voltages; val++) { + uV = ri->voltages[val] * 1000; - ret = tps6586x_update(parent, ri->volt_reg, val, mask); - if (ret) - return ret; + /* LDO0 has minimal voltage 1.2 rather than 1.25 */ + if (ri->desc.id == TPS6586X_ID_LDO_0 && val == 0) + uV -= 50 * 1000; - /* Update go bit for DVM regulators */ - switch (rid) { - case TPS6586X_ID_LDO_2: - case TPS6586X_ID_LDO_4: - case TPS6586X_ID_SM_0: - case TPS6586X_ID_SM_1: - ret = tps6586x_set_bits(parent, ri->go_reg, 1 << ri->go_bit); - break; + /* use the first in-range value */ + if (min_uV <= uV && uV <= max_uV) { + + *selector = val; + + val <<= ri->volt_shift; + mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift; + + return tps6586x_update(parent, ri->volt_reg, val, mask); + } } - return ret; + + return -EINVAL; +} + +static int tps6586x_ldo_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned *selector) +{ + struct tps6586x_regulator *ri = rdev_get_drvdata(rdev); + struct device *parent = to_tps6586x_dev(rdev); + + return __tps6586x_ldo_set_voltage(parent, ri, min_uV, max_uV, + selector); } -static int tps6586x_get_voltage_sel(struct regulator_dev *rdev) +static int tps6586x_ldo_get_voltage(struct regulator_dev *rdev) { struct tps6586x_regulator *ri = rdev_get_drvdata(rdev); struct device *parent = to_tps6586x_dev(rdev); @@ -132,7 +146,22 @@ static int tps6586x_get_voltage_sel(struct regulator_dev *rdev) if (val >= ri->desc.n_voltages) BUG(); - return val; + return ri->voltages[val] * 1000; +} + +static int tps6586x_dvm_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned *selector) +{ + struct tps6586x_regulator *ri = rdev_get_drvdata(rdev); + struct device *parent = to_tps6586x_dev(rdev); + int ret; + + ret = __tps6586x_ldo_set_voltage(parent, ri, min_uV, max_uV, + selector); + if (ret) + return ret; + + return tps6586x_set_bits(parent, ri->go_reg, 1 << ri->go_bit); } static int tps6586x_regulator_enable(struct regulator_dev *rdev) @@ -167,10 +196,20 @@ static int tps6586x_regulator_is_enabled(struct regulator_dev *rdev) return !!(reg_val & (1 << ri->enable_bit[0])); } -static struct regulator_ops tps6586x_regulator_ops = { - .list_voltage = tps6586x_list_voltage, - .get_voltage_sel = tps6586x_get_voltage_sel, - .set_voltage_sel = tps6586x_set_voltage_sel, +static struct regulator_ops tps6586x_regulator_ldo_ops = { + .list_voltage = tps6586x_ldo_list_voltage, + .get_voltage = tps6586x_ldo_get_voltage, + .set_voltage = tps6586x_ldo_set_voltage, + + .is_enabled = tps6586x_regulator_is_enabled, + .enable = tps6586x_regulator_enable, + .disable = tps6586x_regulator_disable, +}; + +static struct regulator_ops tps6586x_regulator_dvm_ops = { + .list_voltage = tps6586x_ldo_list_voltage, + .get_voltage = tps6586x_ldo_get_voltage, + .set_voltage = tps6586x_dvm_set_voltage, .is_enabled = tps6586x_regulator_is_enabled, .enable = tps6586x_regulator_enable, @@ -202,11 +241,11 @@ static int tps6586x_dvm_voltages[] = { 1325, 1350, 1375, 1400, 1425, 1450, 1475, 1500, }; -#define TPS6586X_REGULATOR(_id, vdata, vreg, shift, nbits, \ +#define TPS6586X_REGULATOR(_id, vdata, _ops, vreg, shift, nbits, \ ereg0, ebit0, ereg1, ebit1) \ .desc = { \ .name = "REG-" #_id, \ - .ops = &tps6586x_regulator_ops, \ + .ops = &tps6586x_regulator_##_ops, \ .type = REGULATOR_VOLTAGE, \ .id = TPS6586X_ID_##_id, \ .n_voltages = ARRAY_SIZE(tps6586x_##vdata##_voltages), \ @@ -228,14 +267,14 @@ static int tps6586x_dvm_voltages[] = { #define TPS6586X_LDO(_id, vdata, vreg, shift, nbits, \ ereg0, ebit0, ereg1, ebit1) \ { \ - TPS6586X_REGULATOR(_id, vdata, vreg, shift, nbits, \ + TPS6586X_REGULATOR(_id, vdata, ldo_ops, vreg, shift, nbits, \ ereg0, ebit0, ereg1, ebit1) \ } #define TPS6586X_DVM(_id, vdata, vreg, shift, nbits, \ ereg0, ebit0, ereg1, ebit1, goreg, gobit) \ { \ - TPS6586X_REGULATOR(_id, vdata, vreg, shift, nbits, \ + TPS6586X_REGULATOR(_id, vdata, dvm_ops, vreg, shift, nbits, \ ereg0, ebit0, ereg1, ebit1) \ TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \ } @@ -345,7 +384,6 @@ static inline struct tps6586x_regulator *find_regulator_info(int id) static int __devinit tps6586x_regulator_probe(struct platform_device *pdev) { struct tps6586x_regulator *ri = NULL; - struct regulator_config config = { }; struct regulator_dev *rdev; int id = pdev->id; int err; @@ -362,12 +400,8 @@ static int __devinit tps6586x_regulator_probe(struct platform_device *pdev) if (err) return err; - config.dev = &pdev->dev; - config.of_node = pdev->dev.of_node; - config.init_data = pdev->dev.platform_data; - config.driver_data = ri; - - rdev = regulator_register(&ri->desc, &config); + rdev = regulator_register(&ri->desc, &pdev->dev, + pdev->dev.platform_data, ri, NULL); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register regulator %s\n", ri->desc.name); diff --git a/trunk/drivers/regulator/tps65910-regulator.c b/trunk/drivers/regulator/tps65910-regulator.c index 8dc3d9392bfa..4a37c2b6367f 100644 --- a/trunk/drivers/regulator/tps65910-regulator.c +++ b/trunk/drivers/regulator/tps65910-regulator.c @@ -20,10 +20,10 @@ #include #include #include +#include #include #include #include -#include #define TPS65910_SUPPLY_STATE_ENABLED 0x1 #define EXT_SLEEP_CONTROL (TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 | \ @@ -94,11 +94,11 @@ struct tps_info { static struct tps_info tps65910_regs[] = { { - .name = "vrtc", + .name = "VRTC", .enable_time_us = 2200, }, { - .name = "vio", + .name = "VIO", .min_uV = 1500000, .max_uV = 3300000, .n_voltages = ARRAY_SIZE(VIO_VSEL_table), @@ -106,19 +106,19 @@ static struct tps_info tps65910_regs[] = { .enable_time_us = 350, }, { - .name = "vdd1", + .name = "VDD1", .min_uV = 600000, .max_uV = 4500000, .enable_time_us = 350, }, { - .name = "vdd2", + .name = "VDD2", .min_uV = 600000, .max_uV = 4500000, .enable_time_us = 350, }, { - .name = "vdd3", + .name = "VDD3", .min_uV = 5000000, .max_uV = 5000000, .n_voltages = ARRAY_SIZE(VDD3_VSEL_table), @@ -126,7 +126,7 @@ static struct tps_info tps65910_regs[] = { .enable_time_us = 200, }, { - .name = "vdig1", + .name = "VDIG1", .min_uV = 1200000, .max_uV = 2700000, .n_voltages = ARRAY_SIZE(VDIG1_VSEL_table), @@ -134,7 +134,7 @@ static struct tps_info tps65910_regs[] = { .enable_time_us = 100, }, { - .name = "vdig2", + .name = "VDIG2", .min_uV = 1000000, .max_uV = 1800000, .n_voltages = ARRAY_SIZE(VDIG2_VSEL_table), @@ -142,7 +142,7 @@ static struct tps_info tps65910_regs[] = { .enable_time_us = 100, }, { - .name = "vpll", + .name = "VPLL", .min_uV = 1000000, .max_uV = 2500000, .n_voltages = ARRAY_SIZE(VPLL_VSEL_table), @@ -150,7 +150,7 @@ static struct tps_info tps65910_regs[] = { .enable_time_us = 100, }, { - .name = "vdac", + .name = "VDAC", .min_uV = 1800000, .max_uV = 2850000, .n_voltages = ARRAY_SIZE(VDAC_VSEL_table), @@ -158,7 +158,7 @@ static struct tps_info tps65910_regs[] = { .enable_time_us = 100, }, { - .name = "vaux1", + .name = "VAUX1", .min_uV = 1800000, .max_uV = 2850000, .n_voltages = ARRAY_SIZE(VAUX1_VSEL_table), @@ -166,7 +166,7 @@ static struct tps_info tps65910_regs[] = { .enable_time_us = 100, }, { - .name = "vaux2", + .name = "VAUX2", .min_uV = 1800000, .max_uV = 3300000, .n_voltages = ARRAY_SIZE(VAUX2_VSEL_table), @@ -174,7 +174,7 @@ static struct tps_info tps65910_regs[] = { .enable_time_us = 100, }, { - .name = "vaux33", + .name = "VAUX33", .min_uV = 1800000, .max_uV = 3300000, .n_voltages = ARRAY_SIZE(VAUX33_VSEL_table), @@ -182,7 +182,7 @@ static struct tps_info tps65910_regs[] = { .enable_time_us = 100, }, { - .name = "vmmc", + .name = "VMMC", .min_uV = 1800000, .max_uV = 3300000, .n_voltages = ARRAY_SIZE(VMMC_VSEL_table), @@ -193,11 +193,11 @@ static struct tps_info tps65910_regs[] = { static struct tps_info tps65911_regs[] = { { - .name = "vrtc", + .name = "VRTC", .enable_time_us = 2200, }, { - .name = "vio", + .name = "VIO", .min_uV = 1500000, .max_uV = 3300000, .n_voltages = ARRAY_SIZE(VIO_VSEL_table), @@ -205,77 +205,77 @@ static struct tps_info tps65911_regs[] = { .enable_time_us = 350, }, { - .name = "vdd1", + .name = "VDD1", .min_uV = 600000, .max_uV = 4500000, .n_voltages = 73, .enable_time_us = 350, }, { - .name = "vdd2", + .name = "VDD2", .min_uV = 600000, .max_uV = 4500000, .n_voltages = 73, .enable_time_us = 350, }, { - .name = "vddctrl", + .name = "VDDCTRL", .min_uV = 600000, .max_uV = 1400000, .n_voltages = 65, .enable_time_us = 900, }, { - .name = "ldo1", + .name = "LDO1", .min_uV = 1000000, .max_uV = 3300000, .n_voltages = 47, .enable_time_us = 420, }, { - .name = "ldo2", + .name = "LDO2", .min_uV = 1000000, .max_uV = 3300000, .n_voltages = 47, .enable_time_us = 420, }, { - .name = "ldo3", + .name = "LDO3", .min_uV = 1000000, .max_uV = 3300000, .n_voltages = 24, .enable_time_us = 230, }, { - .name = "ldo4", + .name = "LDO4", .min_uV = 1000000, .max_uV = 3300000, .n_voltages = 47, .enable_time_us = 230, }, { - .name = "ldo5", + .name = "LDO5", .min_uV = 1000000, .max_uV = 3300000, .n_voltages = 24, .enable_time_us = 230, }, { - .name = "ldo6", + .name = "LDO6", .min_uV = 1000000, .max_uV = 3300000, .n_voltages = 24, .enable_time_us = 230, }, { - .name = "ldo7", + .name = "LDO7", .min_uV = 1000000, .max_uV = 3300000, .n_voltages = 24, .enable_time_us = 230, }, { - .name = "ldo8", + .name = "LDO8", .min_uV = 1000000, .max_uV = 3300000, .n_voltages = 24, @@ -467,6 +467,48 @@ static int tps65911_get_ctrl_register(int id) } } +static int tps65910_is_enabled(struct regulator_dev *dev) +{ + struct tps65910_reg *pmic = rdev_get_drvdata(dev); + int reg, value, id = rdev_get_id(dev); + + reg = pmic->get_ctrl_reg(id); + if (reg < 0) + return reg; + + value = tps65910_reg_read(pmic, reg); + if (value < 0) + return value; + + return value & TPS65910_SUPPLY_STATE_ENABLED; +} + +static int tps65910_enable(struct regulator_dev *dev) +{ + struct tps65910_reg *pmic = rdev_get_drvdata(dev); + struct tps65910 *mfd = pmic->mfd; + int reg, id = rdev_get_id(dev); + + reg = pmic->get_ctrl_reg(id); + if (reg < 0) + return reg; + + return tps65910_set_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED); +} + +static int tps65910_disable(struct regulator_dev *dev) +{ + struct tps65910_reg *pmic = rdev_get_drvdata(dev); + struct tps65910 *mfd = pmic->mfd; + int reg, id = rdev_get_id(dev); + + reg = pmic->get_ctrl_reg(id); + if (reg < 0) + return reg; + + return tps65910_clear_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED); +} + static int tps65910_enable_time(struct regulator_dev *dev) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); @@ -579,10 +621,10 @@ static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev) return -EINVAL; } -static int tps65910_get_voltage_sel(struct regulator_dev *dev) +static int tps65910_get_voltage(struct regulator_dev *dev) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); - int reg, value, id = rdev_get_id(dev); + int reg, value, id = rdev_get_id(dev), voltage = 0; reg = pmic->get_ctrl_reg(id); if (reg < 0) @@ -609,7 +651,9 @@ static int tps65910_get_voltage_sel(struct regulator_dev *dev) return -EINVAL; } - return value; + voltage = pmic->info[id]->voltage_table[value] * 1000; + + return voltage; } static int tps65910_get_voltage_vdd3(struct regulator_dev *dev) @@ -617,10 +661,10 @@ static int tps65910_get_voltage_vdd3(struct regulator_dev *dev) return 5 * 1000 * 1000; } -static int tps65911_get_voltage_sel(struct regulator_dev *dev) +static int tps65911_get_voltage(struct regulator_dev *dev) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); - int id = rdev_get_id(dev); + int step_mv, id = rdev_get_id(dev); u8 value, reg; reg = pmic->get_ctrl_reg(id); @@ -633,6 +677,13 @@ static int tps65911_get_voltage_sel(struct regulator_dev *dev) case TPS65911_REG_LDO4: value &= LDO1_SEL_MASK; value >>= LDO_SEL_SHIFT; + /* The first 5 values of the selector correspond to 1V */ + if (value < 5) + value = 0; + else + value -= 4; + + step_mv = 50; break; case TPS65911_REG_LDO3: case TPS65911_REG_LDO5: @@ -641,16 +692,23 @@ static int tps65911_get_voltage_sel(struct regulator_dev *dev) case TPS65911_REG_LDO8: value &= LDO3_SEL_MASK; value >>= LDO_SEL_SHIFT; + /* The first 3 values of the selector correspond to 1V */ + if (value < 3) + value = 0; + else + value -= 2; + + step_mv = 100; break; case TPS65910_REG_VIO: value &= LDO_SEL_MASK; value >>= LDO_SEL_SHIFT; - break; + return pmic->info[id]->voltage_table[value] * 1000; default: return -EINVAL; } - return value; + return (LDO_MIN_VOLT + value * step_mv) * 1000; } static int tps65910_set_voltage_dcdc_sel(struct regulator_dev *dev, @@ -856,9 +914,9 @@ static int tps65910_set_voltage_dcdc_time_sel(struct regulator_dev *dev, /* Regulator ops (except VRTC) */ static struct regulator_ops tps65910_ops_dcdc = { - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, + .is_enabled = tps65910_is_enabled, + .enable = tps65910_enable, + .disable = tps65910_disable, .enable_time = tps65910_enable_time, .set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, @@ -869,9 +927,9 @@ static struct regulator_ops tps65910_ops_dcdc = { }; static struct regulator_ops tps65910_ops_vdd3 = { - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, + .is_enabled = tps65910_is_enabled, + .enable = tps65910_enable, + .disable = tps65910_disable, .enable_time = tps65910_enable_time, .set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, @@ -880,25 +938,25 @@ static struct regulator_ops tps65910_ops_vdd3 = { }; static struct regulator_ops tps65910_ops = { - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, + .is_enabled = tps65910_is_enabled, + .enable = tps65910_enable, + .disable = tps65910_disable, .enable_time = tps65910_enable_time, .set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, - .get_voltage_sel = tps65910_get_voltage_sel, + .get_voltage = tps65910_get_voltage, .set_voltage_sel = tps65910_set_voltage_sel, .list_voltage = tps65910_list_voltage, }; static struct regulator_ops tps65911_ops = { - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, + .is_enabled = tps65910_is_enabled, + .enable = tps65910_enable, + .disable = tps65910_disable, .enable_time = tps65910_enable_time, .set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, - .get_voltage_sel = tps65911_get_voltage_sel, + .get_voltage = tps65911_get_voltage, .set_voltage_sel = tps65911_set_voltage_sel, .list_voltage = tps65911_list_voltage, }; @@ -1036,141 +1094,23 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic, return ret; } -#ifdef CONFIG_OF - -static struct of_regulator_match tps65910_matches[] = { - { .name = "vrtc", .driver_data = (void *) &tps65910_regs[0] }, - { .name = "vio", .driver_data = (void *) &tps65910_regs[1] }, - { .name = "vdd1", .driver_data = (void *) &tps65910_regs[2] }, - { .name = "vdd2", .driver_data = (void *) &tps65910_regs[3] }, - { .name = "vdd3", .driver_data = (void *) &tps65910_regs[4] }, - { .name = "vdig1", .driver_data = (void *) &tps65910_regs[5] }, - { .name = "vdig2", .driver_data = (void *) &tps65910_regs[6] }, - { .name = "vpll", .driver_data = (void *) &tps65910_regs[7] }, - { .name = "vdac", .driver_data = (void *) &tps65910_regs[8] }, - { .name = "vaux1", .driver_data = (void *) &tps65910_regs[9] }, - { .name = "vaux2", .driver_data = (void *) &tps65910_regs[10] }, - { .name = "vaux33", .driver_data = (void *) &tps65910_regs[11] }, - { .name = "vmmc", .driver_data = (void *) &tps65910_regs[12] }, -}; - -static struct of_regulator_match tps65911_matches[] = { - { .name = "vrtc", .driver_data = (void *) &tps65911_regs[0] }, - { .name = "vio", .driver_data = (void *) &tps65911_regs[1] }, - { .name = "vdd1", .driver_data = (void *) &tps65911_regs[2] }, - { .name = "vdd2", .driver_data = (void *) &tps65911_regs[3] }, - { .name = "vddctrl", .driver_data = (void *) &tps65911_regs[4] }, - { .name = "ldo1", .driver_data = (void *) &tps65911_regs[5] }, - { .name = "ldo2", .driver_data = (void *) &tps65911_regs[6] }, - { .name = "ldo3", .driver_data = (void *) &tps65911_regs[7] }, - { .name = "ldo4", .driver_data = (void *) &tps65911_regs[8] }, - { .name = "ldo5", .driver_data = (void *) &tps65911_regs[9] }, - { .name = "ldo6", .driver_data = (void *) &tps65911_regs[10] }, - { .name = "ldo7", .driver_data = (void *) &tps65911_regs[11] }, - { .name = "ldo8", .driver_data = (void *) &tps65911_regs[12] }, -}; - -static struct tps65910_board *tps65910_parse_dt_reg_data( - struct platform_device *pdev, - struct of_regulator_match **tps65910_reg_matches) -{ - struct tps65910_board *pmic_plat_data; - struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); - struct device_node *np = pdev->dev.parent->of_node; - struct device_node *regulators; - struct of_regulator_match *matches; - unsigned int prop; - int idx = 0, ret, count; - - pmic_plat_data = devm_kzalloc(&pdev->dev, sizeof(*pmic_plat_data), - GFP_KERNEL); - - if (!pmic_plat_data) { - dev_err(&pdev->dev, "Failure to alloc pdata for regulators.\n"); - return NULL; - } - - regulators = of_find_node_by_name(np, "regulators"); - if (!regulators) { - dev_err(&pdev->dev, "regulator node not found\n"); - return NULL; - } - - switch (tps65910_chip_id(tps65910)) { - case TPS65910: - count = ARRAY_SIZE(tps65910_matches); - matches = tps65910_matches; - break; - case TPS65911: - count = ARRAY_SIZE(tps65911_matches); - matches = tps65911_matches; - break; - default: - dev_err(&pdev->dev, "Invalid tps chip version\n"); - return NULL; - } - - ret = of_regulator_match(pdev->dev.parent, regulators, matches, count); - if (ret < 0) { - dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", - ret); - return NULL; - } - - *tps65910_reg_matches = matches; - - for (idx = 0; idx < count; idx++) { - if (!matches[idx].init_data || !matches[idx].of_node) - continue; - - pmic_plat_data->tps65910_pmic_init_data[idx] = - matches[idx].init_data; - - ret = of_property_read_u32(matches[idx].of_node, - "ti,regulator-ext-sleep-control", &prop); - if (!ret) - pmic_plat_data->regulator_ext_sleep_control[idx] = prop; - } - - return pmic_plat_data; -} -#else -static inline struct tps65910_board *tps65910_parse_dt_reg_data( - struct platform_device *pdev, - struct of_regulator_match **tps65910_reg_matches) -{ - *tps65910_reg_matches = NULL; - return 0; -} -#endif - static __devinit int tps65910_probe(struct platform_device *pdev) { struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); - struct regulator_config config = { }; struct tps_info *info; struct regulator_init_data *reg_data; struct regulator_dev *rdev; struct tps65910_reg *pmic; struct tps65910_board *pmic_plat_data; - struct of_regulator_match *tps65910_reg_matches = NULL; int i, err; pmic_plat_data = dev_get_platdata(tps65910->dev); - if (!pmic_plat_data && tps65910->dev->of_node) - pmic_plat_data = tps65910_parse_dt_reg_data(pdev, - &tps65910_reg_matches); - - if (!pmic_plat_data) { - dev_err(&pdev->dev, "Platform data not found\n"); + if (!pmic_plat_data) return -EINVAL; - } - pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); - if (!pmic) { - dev_err(&pdev->dev, "Memory allocation failed for pmic\n"); + pmic = kzalloc(sizeof(*pmic), GFP_KERNEL); + if (!pmic) return -ENOMEM; - } mutex_init(&pmic->mutex); pmic->mfd = tps65910; @@ -1194,29 +1134,30 @@ static __devinit int tps65910_probe(struct platform_device *pdev) info = tps65911_regs; break; default: - dev_err(&pdev->dev, "Invalid tps chip version\n"); + pr_err("Invalid tps chip version\n"); + kfree(pmic); return -ENODEV; } - pmic->desc = devm_kzalloc(&pdev->dev, pmic->num_regulators * + pmic->desc = kcalloc(pmic->num_regulators, sizeof(struct regulator_desc), GFP_KERNEL); if (!pmic->desc) { - dev_err(&pdev->dev, "Memory alloc fails for desc\n"); - return -ENOMEM; + err = -ENOMEM; + goto err_free_pmic; } - pmic->info = devm_kzalloc(&pdev->dev, pmic->num_regulators * + pmic->info = kcalloc(pmic->num_regulators, sizeof(struct tps_info *), GFP_KERNEL); if (!pmic->info) { - dev_err(&pdev->dev, "Memory alloc fails for info\n"); - return -ENOMEM; + err = -ENOMEM; + goto err_free_desc; } - pmic->rdev = devm_kzalloc(&pdev->dev, pmic->num_regulators * + pmic->rdev = kcalloc(pmic->num_regulators, sizeof(struct regulator_dev *), GFP_KERNEL); if (!pmic->rdev) { - dev_err(&pdev->dev, "Memory alloc fails for rdev\n"); - return -ENOMEM; + err = -ENOMEM; + goto err_free_info; } for (i = 0; i < pmic->num_regulators && i < TPS65910_NUM_REGS; @@ -1264,18 +1205,9 @@ static __devinit int tps65910_probe(struct platform_device *pdev) pmic->desc[i].type = REGULATOR_VOLTAGE; pmic->desc[i].owner = THIS_MODULE; - pmic->desc[i].enable_reg = pmic->get_ctrl_reg(i); - pmic->desc[i].enable_mask = TPS65910_SUPPLY_STATE_ENABLED; - - config.dev = tps65910->dev; - config.init_data = reg_data; - config.driver_data = pmic; - config.regmap = tps65910->regmap; - - if (tps65910_reg_matches) - config.of_node = tps65910_reg_matches[i].of_node; - rdev = regulator_register(&pmic->desc[i], &config); + rdev = regulator_register(&pmic->desc[i], + tps65910->dev, reg_data, pmic, NULL); if (IS_ERR(rdev)) { dev_err(tps65910->dev, "failed to register %s regulator\n", @@ -1292,6 +1224,13 @@ static __devinit int tps65910_probe(struct platform_device *pdev) err_unregister_regulator: while (--i >= 0) regulator_unregister(pmic->rdev[i]); + kfree(pmic->rdev); +err_free_info: + kfree(pmic->info); +err_free_desc: + kfree(pmic->desc); +err_free_pmic: + kfree(pmic); return err; } @@ -1303,6 +1242,10 @@ static int __devexit tps65910_remove(struct platform_device *pdev) for (i = 0; i < pmic->num_regulators; i++) regulator_unregister(pmic->rdev[i]); + kfree(pmic->rdev); + kfree(pmic->info); + kfree(pmic->desc); + kfree(pmic); return 0; } diff --git a/trunk/drivers/regulator/tps65912-regulator.c b/trunk/drivers/regulator/tps65912-regulator.c index 18b2a1dcb4b5..b36799b1f530 100644 --- a/trunk/drivers/regulator/tps65912-regulator.c +++ b/trunk/drivers/regulator/tps65912-regulator.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -371,14 +372,12 @@ static unsigned int tps65912_get_mode(struct regulator_dev *dev) return mode; } -static int tps65912_list_voltage(struct regulator_dev *dev, unsigned selector) +static int tps65912_list_voltage_dcdc(struct regulator_dev *dev, + unsigned selector) { struct tps65912_reg *pmic = rdev_get_drvdata(dev); int range, voltage = 0, id = rdev_get_id(dev); - if (id >= TPS65912_REG_LDO1 && id <= TPS65912_REG_LDO10) - return tps65912_vsel_to_uv_ldo(selector); - if (id > TPS65912_REG_DCDC4) return -EINVAL; @@ -405,7 +404,7 @@ static int tps65912_list_voltage(struct regulator_dev *dev, unsigned selector) return voltage; } -static int tps65912_get_voltage_sel(struct regulator_dev *dev) +static int tps65912_get_voltage_dcdc(struct regulator_dev *dev) { struct tps65912_reg *pmic = rdev_get_drvdata(dev); struct tps65912 *mfd = pmic->mfd; @@ -419,7 +418,7 @@ static int tps65912_get_voltage_sel(struct regulator_dev *dev) vsel = tps65912_reg_read(mfd, reg); vsel &= 0x3F; - return vsel; + return tps65912_list_voltage_dcdc(dev, vsel); } static int tps65912_set_voltage_sel(struct regulator_dev *dev, @@ -437,6 +436,32 @@ static int tps65912_set_voltage_sel(struct regulator_dev *dev, return tps65912_reg_write(mfd, reg, selector | value); } +static int tps65912_get_voltage_ldo(struct regulator_dev *dev) +{ + struct tps65912_reg *pmic = rdev_get_drvdata(dev); + struct tps65912 *mfd = pmic->mfd; + int id = rdev_get_id(dev); + int vsel = 0; + u8 reg; + + reg = tps65912_get_sel_register(pmic, id); + vsel = tps65912_reg_read(mfd, reg); + vsel &= 0x3F; + + return tps65912_vsel_to_uv_ldo(vsel); +} + +static int tps65912_list_voltage_ldo(struct regulator_dev *dev, + unsigned selector) +{ + int ldo = rdev_get_id(dev); + + if (ldo < TPS65912_REG_LDO1 || ldo > TPS65912_REG_LDO10) + return -EINVAL; + + return tps65912_vsel_to_uv_ldo(selector); +} + /* Operations permitted on DCDCx */ static struct regulator_ops tps65912_ops_dcdc = { .is_enabled = tps65912_reg_is_enabled, @@ -444,9 +469,9 @@ static struct regulator_ops tps65912_ops_dcdc = { .disable = tps65912_reg_disable, .set_mode = tps65912_set_mode, .get_mode = tps65912_get_mode, - .get_voltage_sel = tps65912_get_voltage_sel, + .get_voltage = tps65912_get_voltage_dcdc, .set_voltage_sel = tps65912_set_voltage_sel, - .list_voltage = tps65912_list_voltage, + .list_voltage = tps65912_list_voltage_dcdc, }; /* Operations permitted on LDOx */ @@ -454,15 +479,14 @@ static struct regulator_ops tps65912_ops_ldo = { .is_enabled = tps65912_reg_is_enabled, .enable = tps65912_reg_enable, .disable = tps65912_reg_disable, - .get_voltage_sel = tps65912_get_voltage_sel, + .get_voltage = tps65912_get_voltage_ldo, .set_voltage_sel = tps65912_set_voltage_sel, - .list_voltage = tps65912_list_voltage, + .list_voltage = tps65912_list_voltage_ldo, }; static __devinit int tps65912_probe(struct platform_device *pdev) { struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent); - struct regulator_config config = { }; struct tps_info *info; struct regulator_init_data *reg_data; struct regulator_dev *rdev; @@ -476,7 +500,7 @@ static __devinit int tps65912_probe(struct platform_device *pdev) reg_data = pmic_plat_data->tps65912_pmic_init_data; - pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); + pmic = kzalloc(sizeof(*pmic), GFP_KERNEL); if (!pmic) return -ENOMEM; @@ -500,12 +524,8 @@ static __devinit int tps65912_probe(struct platform_device *pdev) pmic->desc[i].type = REGULATOR_VOLTAGE; pmic->desc[i].owner = THIS_MODULE; range = tps65912_get_range(pmic, i); - - config.dev = tps65912->dev; - config.init_data = reg_data; - config.driver_data = pmic; - - rdev = regulator_register(&pmic->desc[i], &config); + rdev = regulator_register(&pmic->desc[i], + tps65912->dev, reg_data, pmic, NULL); if (IS_ERR(rdev)) { dev_err(tps65912->dev, "failed to register %s regulator\n", @@ -522,6 +542,8 @@ static __devinit int tps65912_probe(struct platform_device *pdev) err: while (--i >= 0) regulator_unregister(pmic->rdev[i]); + + kfree(pmic); return err; } @@ -532,6 +554,8 @@ static int __devexit tps65912_remove(struct platform_device *pdev) for (i = 0; i < TPS65912_NUM_REGULATOR; i++) regulator_unregister(tps65912_reg->rdev[i]); + + kfree(tps65912_reg); return 0; } diff --git a/trunk/drivers/regulator/twl-regulator.c b/trunk/drivers/regulator/twl-regulator.c index c7390711d954..9cdfc389ca26 100644 --- a/trunk/drivers/regulator/twl-regulator.c +++ b/trunk/drivers/regulator/twl-regulator.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -174,14 +175,15 @@ static int twl6030reg_is_enabled(struct regulator_dev *rdev) struct twlreg_info *info = rdev_get_drvdata(rdev); int grp = 0, val; - if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) { - grp = twlreg_grp(rdev); - if (grp < 0) - return grp; + if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) + grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); + if (grp < 0) + return grp; + + if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) grp &= P1_GRP_6030; - } else { + else grp = 1; - } val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE); val = TWL6030_CFG_STATE_APP(val); @@ -195,7 +197,7 @@ static int twl4030reg_enable(struct regulator_dev *rdev) int grp; int ret; - grp = twlreg_grp(rdev); + grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); if (grp < 0) return grp; @@ -203,6 +205,8 @@ static int twl4030reg_enable(struct regulator_dev *rdev) ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); + udelay(info->delay); + return ret; } @@ -213,28 +217,17 @@ static int twl6030reg_enable(struct regulator_dev *rdev) int ret; if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) - grp = twlreg_grp(rdev); + grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); if (grp < 0) return grp; ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, grp << TWL6030_CFG_STATE_GRP_SHIFT | TWL6030_CFG_STATE_ON); - return ret; -} - -static int twl4030reg_enable_time(struct regulator_dev *rdev) -{ - struct twlreg_info *info = rdev_get_drvdata(rdev); - return info->delay; -} + udelay(info->delay); -static int twl6030reg_enable_time(struct regulator_dev *rdev) -{ - struct twlreg_info *info = rdev_get_drvdata(rdev); - - return info->delay; + return ret; } static int twl4030reg_disable(struct regulator_dev *rdev) @@ -243,7 +236,7 @@ static int twl4030reg_disable(struct regulator_dev *rdev) int grp; int ret; - grp = twlreg_grp(rdev); + grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); if (grp < 0) return grp; @@ -355,7 +348,7 @@ static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode) int val; if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) - grp = twlreg_grp(rdev); + grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); if (grp < 0) return grp; @@ -395,12 +388,14 @@ static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode) * VAUX3 at 3V is incorrectly listed in some TI manuals as unsupported. * TI are revising the twl5030/tps659x0 specs to support that 3.0V setting. */ +#ifdef CONFIG_TWL4030_ALLOW_UNSUPPORTED +#define UNSUP_MASK 0x0000 +#else #define UNSUP_MASK 0x8000 +#endif #define UNSUP(x) (UNSUP_MASK | (x)) -#define IS_UNSUP(info, x) \ - ((UNSUP_MASK & (x)) && \ - !((info)->features & TWL4030_ALLOW_UNSUPPORTED)) +#define IS_UNSUP(x) (UNSUP_MASK & (x)) #define LDO_MV(x) (~UNSUP_MASK & (x)) @@ -474,16 +469,35 @@ static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) struct twlreg_info *info = rdev_get_drvdata(rdev); int mV = info->table[index]; - return IS_UNSUP(info, mV) ? 0 : (LDO_MV(mV) * 1000); + return IS_UNSUP(mV) ? 0 : (LDO_MV(mV) * 1000); } static int -twl4030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) +twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, + unsigned *selector) { struct twlreg_info *info = rdev_get_drvdata(rdev); + int vsel; - return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE, - selector); + for (vsel = 0; vsel < info->table_len; vsel++) { + int mV = info->table[vsel]; + int uV; + + if (IS_UNSUP(mV)) + continue; + uV = LDO_MV(mV) * 1000; + + /* REVISIT for VAUX2, first match may not be best/lowest */ + + /* use the first in-range value */ + if (min_uV <= uV && uV <= max_uV) { + *selector = vsel; + return twlreg_write(info, TWL_MODULE_PM_RECEIVER, + VREG_VOLTAGE, vsel); + } + } + + return -EDOM; } static int twl4030ldo_get_voltage(struct regulator_dev *rdev) @@ -502,13 +516,12 @@ static int twl4030ldo_get_voltage(struct regulator_dev *rdev) static struct regulator_ops twl4030ldo_ops = { .list_voltage = twl4030ldo_list_voltage, - .set_voltage_sel = twl4030ldo_set_voltage_sel, + .set_voltage = twl4030ldo_set_voltage, .get_voltage = twl4030ldo_get_voltage, .enable = twl4030reg_enable, .disable = twl4030reg_disable, .is_enabled = twl4030reg_is_enabled, - .enable_time = twl4030reg_enable_time, .set_mode = twl4030reg_set_mode, @@ -629,7 +642,6 @@ static struct regulator_ops twl6030ldo_ops = { .enable = twl6030reg_enable, .disable = twl6030reg_disable, .is_enabled = twl6030reg_is_enabled, - .enable_time = twl6030reg_enable_time, .set_mode = twl6030reg_set_mode, @@ -663,7 +675,6 @@ static struct regulator_ops twl4030fixed_ops = { .enable = twl4030reg_enable, .disable = twl4030reg_disable, .is_enabled = twl4030reg_is_enabled, - .enable_time = twl4030reg_enable_time, .set_mode = twl4030reg_set_mode, @@ -678,7 +689,6 @@ static struct regulator_ops twl6030fixed_ops = { .enable = twl6030reg_enable, .disable = twl6030reg_disable, .is_enabled = twl6030reg_is_enabled, - .enable_time = twl6030reg_enable_time, .set_mode = twl6030reg_set_mode, @@ -689,7 +699,6 @@ static struct regulator_ops twl6030_fixed_resource = { .enable = twl6030reg_enable, .disable = twl6030reg_disable, .is_enabled = twl6030reg_is_enabled, - .enable_time = twl6030reg_enable_time, .get_status = twl6030reg_get_status, }; @@ -797,7 +806,10 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, vsel = 0; else if ((min_uV >= 600000) && (min_uV <= 1300000)) { int calc_uV; - vsel = DIV_ROUND_UP(min_uV - 600000, 12500); + vsel = (min_uV - 600000) / 125; + if (vsel % 100) + vsel += 100; + vsel /= 100; vsel++; calc_uV = twl6030smps_list_voltage(rdev, vsel); if (calc_uV > max_uV) @@ -824,7 +836,10 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, vsel = 0; else if ((min_uV >= 700000) && (min_uV <= 1420000)) { int calc_uV; - vsel = DIV_ROUND_UP(min_uV - 700000, 12500); + vsel = (min_uV - 700000) / 125; + if (vsel % 100) + vsel += 100; + vsel /= 100; vsel++; calc_uV = twl6030smps_list_voltage(rdev, vsel); if (calc_uV > max_uV) @@ -847,18 +862,24 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, return -EINVAL; break; case SMPS_EXTENDED_EN: - if (min_uV == 0) { + if (min_uV == 0) vsel = 0; - } else if ((min_uV >= 1852000) && (max_uV <= 4013600)) { - vsel = DIV_ROUND_UP(min_uV - 1852000, 38600); + else if ((min_uV >= 1852000) && (max_uV <= 4013600)) { + vsel = (min_uV - 1852000) / 386; + if (vsel % 100) + vsel += 100; + vsel /= 100; vsel++; } break; case SMPS_OFFSET_EN|SMPS_EXTENDED_EN: - if (min_uV == 0) { + if (min_uV == 0) vsel = 0; - } else if ((min_uV >= 2161000) && (max_uV <= 4321000)) { - vsel = DIV_ROUND_UP(min_uV - 2161000, 38600); + else if ((min_uV >= 2161000) && (max_uV <= 4321000)) { + vsel = (min_uV - 2161000) / 386; + if (vsel % 100) + vsel += 100; + vsel /= 100; vsel++; } break; @@ -886,7 +907,6 @@ static struct regulator_ops twlsmps_ops = { .enable = twl6030reg_enable, .disable = twl6030reg_disable, .is_enabled = twl6030reg_is_enabled, - .enable_time = twl6030reg_enable_time, .set_mode = twl6030reg_set_mode, @@ -1174,7 +1194,6 @@ static int __devinit twlreg_probe(struct platform_device *pdev) struct regulator_dev *rdev; struct twl_regulator_driver_data *drvdata; const struct of_device_id *match; - struct regulator_config config = { }; match = of_match_device(twl_of_match, &pdev->dev); if (match) { @@ -1188,12 +1207,10 @@ static int __devinit twlreg_probe(struct platform_device *pdev) initdata = pdev->dev.platform_data; for (i = 0, info = NULL; i < ARRAY_SIZE(twl_of_match); i++) { info = twl_of_match[i].data; - if (info && info->desc.id == id) - break; + if (!info || info->desc.id != id) + continue; + break; } - if (i == ARRAY_SIZE(twl_of_match)) - return -ENODEV; - drvdata = initdata->driver_data; if (!drvdata) return -EINVAL; @@ -1256,12 +1273,8 @@ static int __devinit twlreg_probe(struct platform_device *pdev) break; } - config.dev = &pdev->dev; - config.init_data = initdata; - config.driver_data = info; - config.of_node = pdev->dev.of_node; - - rdev = regulator_register(&info->desc, &config); + rdev = regulator_register(&info->desc, &pdev->dev, initdata, info, + pdev->dev.of_node); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "can't register %s, %ld\n", info->desc.name, PTR_ERR(rdev)); diff --git a/trunk/drivers/regulator/userspace-consumer.c b/trunk/drivers/regulator/userspace-consumer.c index a7c8deb5f28f..518667ef9a0d 100644 --- a/trunk/drivers/regulator/userspace-consumer.c +++ b/trunk/drivers/regulator/userspace-consumer.c @@ -115,9 +115,7 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev) if (!pdata) return -EINVAL; - drvdata = devm_kzalloc(&pdev->dev, - sizeof(struct userspace_consumer_data), - GFP_KERNEL); + drvdata = kzalloc(sizeof(struct userspace_consumer_data), GFP_KERNEL); if (drvdata == NULL) return -ENOMEM; @@ -127,16 +125,16 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev) mutex_init(&drvdata->lock); - ret = devm_regulator_bulk_get(&pdev->dev, drvdata->num_supplies, - drvdata->supplies); + ret = regulator_bulk_get(&pdev->dev, drvdata->num_supplies, + drvdata->supplies); if (ret) { dev_err(&pdev->dev, "Failed to get supplies: %d\n", ret); - return ret; + goto err_alloc_supplies; } ret = sysfs_create_group(&pdev->dev.kobj, &attr_group); if (ret != 0) - return ret; + goto err_create_attrs; if (pdata->init_on) { ret = regulator_bulk_enable(drvdata->num_supplies, @@ -156,6 +154,11 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev) err_enable: sysfs_remove_group(&pdev->dev.kobj, &attr_group); +err_create_attrs: + regulator_bulk_free(drvdata->num_supplies, drvdata->supplies); + +err_alloc_supplies: + kfree(drvdata); return ret; } @@ -168,6 +171,9 @@ static int regulator_userspace_consumer_remove(struct platform_device *pdev) if (data->enabled) regulator_bulk_disable(data->num_supplies, data->supplies); + regulator_bulk_free(data->num_supplies, data->supplies); + kfree(data); + return 0; } diff --git a/trunk/drivers/regulator/virtual.c b/trunk/drivers/regulator/virtual.c index c038e7422538..ee0b161c998f 100644 --- a/trunk/drivers/regulator/virtual.c +++ b/trunk/drivers/regulator/virtual.c @@ -121,7 +121,7 @@ static ssize_t set_min_uV(struct device *dev, struct device_attribute *attr, struct virtual_consumer_data *data = dev_get_drvdata(dev); long val; - if (kstrtol(buf, 10, &val) != 0) + if (strict_strtol(buf, 10, &val) != 0) return count; mutex_lock(&data->lock); @@ -147,7 +147,7 @@ static ssize_t set_max_uV(struct device *dev, struct device_attribute *attr, struct virtual_consumer_data *data = dev_get_drvdata(dev); long val; - if (kstrtol(buf, 10, &val) != 0) + if (strict_strtol(buf, 10, &val) != 0) return count; mutex_lock(&data->lock); @@ -173,7 +173,7 @@ static ssize_t set_min_uA(struct device *dev, struct device_attribute *attr, struct virtual_consumer_data *data = dev_get_drvdata(dev); long val; - if (kstrtol(buf, 10, &val) != 0) + if (strict_strtol(buf, 10, &val) != 0) return count; mutex_lock(&data->lock); @@ -199,7 +199,7 @@ static ssize_t set_max_uA(struct device *dev, struct device_attribute *attr, struct virtual_consumer_data *data = dev_get_drvdata(dev); long val; - if (kstrtol(buf, 10, &val) != 0) + if (strict_strtol(buf, 10, &val) != 0) return count; mutex_lock(&data->lock); @@ -291,19 +291,18 @@ static int __devinit regulator_virtual_probe(struct platform_device *pdev) struct virtual_consumer_data *drvdata; int ret; - drvdata = devm_kzalloc(&pdev->dev, sizeof(struct virtual_consumer_data), - GFP_KERNEL); + drvdata = kzalloc(sizeof(struct virtual_consumer_data), GFP_KERNEL); if (drvdata == NULL) return -ENOMEM; mutex_init(&drvdata->lock); - drvdata->regulator = devm_regulator_get(&pdev->dev, reg_id); + drvdata->regulator = regulator_get(&pdev->dev, reg_id); if (IS_ERR(drvdata->regulator)) { ret = PTR_ERR(drvdata->regulator); dev_err(&pdev->dev, "Failed to obtain supply '%s': %d\n", reg_id, ret); - return ret; + goto err; } ret = sysfs_create_group(&pdev->dev.kobj, @@ -311,7 +310,7 @@ static int __devinit regulator_virtual_probe(struct platform_device *pdev) if (ret != 0) { dev_err(&pdev->dev, "Failed to create attribute group: %d\n", ret); - return ret; + goto err_regulator; } drvdata->mode = regulator_get_mode(drvdata->regulator); @@ -319,6 +318,12 @@ static int __devinit regulator_virtual_probe(struct platform_device *pdev) platform_set_drvdata(pdev, drvdata); return 0; + +err_regulator: + regulator_put(drvdata->regulator); +err: + kfree(drvdata); + return ret; } static int __devexit regulator_virtual_remove(struct platform_device *pdev) @@ -329,6 +334,9 @@ static int __devexit regulator_virtual_remove(struct platform_device *pdev) if (drvdata->enabled) regulator_disable(drvdata->regulator); + regulator_put(drvdata->regulator); + + kfree(drvdata); platform_set_drvdata(pdev, NULL); diff --git a/trunk/drivers/regulator/wm831x-dcdc.c b/trunk/drivers/regulator/wm831x-dcdc.c index a885911bb5fc..ff810e787eac 100644 --- a/trunk/drivers/regulator/wm831x-dcdc.c +++ b/trunk/drivers/regulator/wm831x-dcdc.c @@ -35,7 +35,7 @@ #define WM831X_DCDC_MODE_IDLE 2 #define WM831X_DCDC_MODE_STANDBY 3 -#define WM831X_DCDC_MAX_NAME 9 +#define WM831X_DCDC_MAX_NAME 6 /* Register offsets in control block */ #define WM831X_DCDC_CONTROL_1 0 @@ -50,7 +50,6 @@ struct wm831x_dcdc { char name[WM831X_DCDC_MAX_NAME]; - char supply_name[WM831X_DCDC_MAX_NAME]; struct regulator_desc desc; int base; struct wm831x *wm831x; @@ -61,6 +60,41 @@ struct wm831x_dcdc { int dvs_vsel; }; +static int wm831x_dcdc_is_enabled(struct regulator_dev *rdev) +{ + struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); + struct wm831x *wm831x = dcdc->wm831x; + int mask = 1 << rdev_get_id(rdev); + int reg; + + reg = wm831x_reg_read(wm831x, WM831X_DCDC_ENABLE); + if (reg < 0) + return reg; + + if (reg & mask) + return 1; + else + return 0; +} + +static int wm831x_dcdc_enable(struct regulator_dev *rdev) +{ + struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); + struct wm831x *wm831x = dcdc->wm831x; + int mask = 1 << rdev_get_id(rdev); + + return wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, mask, mask); +} + +static int wm831x_dcdc_disable(struct regulator_dev *rdev) +{ + struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); + struct wm831x *wm831x = dcdc->wm831x; + int mask = 1 << rdev_get_id(rdev); + + return wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, mask, 0); +} + static unsigned int wm831x_dcdc_get_mode(struct regulator_dev *rdev) { @@ -380,9 +414,9 @@ static struct regulator_ops wm831x_buckv_ops = { .set_current_limit = wm831x_buckv_set_current_limit, .get_current_limit = wm831x_buckv_get_current_limit, - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, + .is_enabled = wm831x_dcdc_is_enabled, + .enable = wm831x_dcdc_enable, + .disable = wm831x_dcdc_disable, .get_status = wm831x_dcdc_get_status, .get_mode = wm831x_dcdc_get_mode, .set_mode = wm831x_dcdc_set_mode, @@ -403,17 +437,23 @@ static __devinit void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc, if (!pdata || !pdata->dvs_gpio) return; + ret = gpio_request(pdata->dvs_gpio, "DCDC DVS"); + if (ret < 0) { + dev_err(wm831x->dev, "Failed to get %s DVS GPIO: %d\n", + dcdc->name, ret); + return; + } + /* gpiolib won't let us read the GPIO status so pick the higher * of the two existing voltages so we take it as platform data. */ dcdc->dvs_gpio_state = pdata->dvs_init_state; - ret = gpio_request_one(pdata->dvs_gpio, - dcdc->dvs_gpio_state ? GPIOF_INIT_HIGH : 0, - "DCDC DVS"); + ret = gpio_direction_output(pdata->dvs_gpio, dcdc->dvs_gpio_state); if (ret < 0) { - dev_err(wm831x->dev, "Failed to get %s DVS GPIO: %d\n", + dev_err(wm831x->dev, "Failed to enable %s DVS GPIO: %d\n", dcdc->name, ret); + gpio_free(pdata->dvs_gpio); return; } @@ -458,7 +498,6 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_pdata *pdata = wm831x->dev->platform_data; - struct regulator_config config = { }; int id; struct wm831x_dcdc *dcdc; struct resource *res; @@ -472,6 +511,9 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1); + if (pdata == NULL || pdata->dcdc[id] == NULL) + return -ENODEV; + dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc), GFP_KERNEL); if (dcdc == NULL) { @@ -491,18 +533,11 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) snprintf(dcdc->name, sizeof(dcdc->name), "DCDC%d", id + 1); dcdc->desc.name = dcdc->name; - - snprintf(dcdc->supply_name, sizeof(dcdc->supply_name), - "DC%dVDD", id + 1); - dcdc->desc.supply_name = dcdc->supply_name; - dcdc->desc.id = id; dcdc->desc.type = REGULATOR_VOLTAGE; dcdc->desc.n_voltages = WM831X_BUCKV_MAX_SELECTOR + 1; dcdc->desc.ops = &wm831x_buckv_ops; dcdc->desc.owner = THIS_MODULE; - dcdc->desc.enable_reg = WM831X_DCDC_ENABLE; - dcdc->desc.enable_mask = 1 << id; ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_ON_CONFIG); if (ret < 0) { @@ -518,16 +553,11 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) } dcdc->dvs_vsel = ret & WM831X_DC1_DVS_VSEL_MASK; - if (pdata && pdata->dcdc[id]) + if (pdata->dcdc[id]) wm831x_buckv_dvs_init(dcdc, pdata->dcdc[id]->driver_data); - config.dev = pdev->dev.parent; - if (pdata) - config.init_data = pdata->dcdc[id]; - config.driver_data = dcdc; - config.regmap = wm831x->regmap; - - dcdc->regulator = regulator_register(&dcdc->desc, &config); + dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev, + pdata->dcdc[id], dcdc, NULL); if (IS_ERR(dcdc->regulator)) { ret = PTR_ERR(dcdc->regulator); dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n", @@ -645,15 +675,29 @@ static int wm831x_buckp_set_suspend_voltage(struct regulator_dev *rdev, return wm831x_buckp_set_voltage_int(rdev, reg, uV, uV, &selector); } +static int wm831x_buckp_get_voltage_sel(struct regulator_dev *rdev) +{ + struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); + struct wm831x *wm831x = dcdc->wm831x; + u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG; + int val; + + val = wm831x_reg_read(wm831x, reg); + if (val < 0) + return val; + + return val & WM831X_DC3_ON_VSEL_MASK; +} + static struct regulator_ops wm831x_buckp_ops = { .set_voltage = wm831x_buckp_set_voltage, - .get_voltage_sel = regulator_get_voltage_sel_regmap, + .get_voltage_sel = wm831x_buckp_get_voltage_sel, .list_voltage = wm831x_buckp_list_voltage, .set_suspend_voltage = wm831x_buckp_set_suspend_voltage, - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, + .is_enabled = wm831x_dcdc_is_enabled, + .enable = wm831x_dcdc_enable, + .disable = wm831x_dcdc_disable, .get_status = wm831x_dcdc_get_status, .get_mode = wm831x_dcdc_get_mode, .set_mode = wm831x_dcdc_set_mode, @@ -664,7 +708,6 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_pdata *pdata = wm831x->dev->platform_data; - struct regulator_config config = { }; int id; struct wm831x_dcdc *dcdc; struct resource *res; @@ -678,6 +721,9 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1); + if (pdata == NULL || pdata->dcdc[id] == NULL) + return -ENODEV; + dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc), GFP_KERNEL); if (dcdc == NULL) { @@ -697,28 +743,14 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev) snprintf(dcdc->name, sizeof(dcdc->name), "DCDC%d", id + 1); dcdc->desc.name = dcdc->name; - - snprintf(dcdc->supply_name, sizeof(dcdc->supply_name), - "DC%dVDD", id + 1); - dcdc->desc.supply_name = dcdc->supply_name; - dcdc->desc.id = id; dcdc->desc.type = REGULATOR_VOLTAGE; dcdc->desc.n_voltages = WM831X_BUCKP_MAX_SELECTOR + 1; dcdc->desc.ops = &wm831x_buckp_ops; dcdc->desc.owner = THIS_MODULE; - dcdc->desc.vsel_reg = dcdc->base + WM831X_DCDC_ON_CONFIG; - dcdc->desc.vsel_mask = WM831X_DC3_ON_VSEL_MASK; - dcdc->desc.enable_reg = WM831X_DCDC_ENABLE; - dcdc->desc.enable_mask = 1 << id; - - config.dev = pdev->dev.parent; - if (pdata) - config.init_data = pdata->dcdc[id]; - config.driver_data = dcdc; - config.regmap = wm831x->regmap; - - dcdc->regulator = regulator_register(&dcdc->desc, &config); + + dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev, + pdata->dcdc[id], dcdc, NULL); if (IS_ERR(dcdc->regulator)) { ret = PTR_ERR(dcdc->regulator); dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n", @@ -800,16 +832,15 @@ static int wm831x_boostp_get_status(struct regulator_dev *rdev) static struct regulator_ops wm831x_boostp_ops = { .get_status = wm831x_boostp_get_status, - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, + .is_enabled = wm831x_dcdc_is_enabled, + .enable = wm831x_dcdc_enable, + .disable = wm831x_dcdc_disable, }; static __devinit int wm831x_boostp_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_pdata *pdata = wm831x->dev->platform_data; - struct regulator_config config = { }; int id = pdev->id % ARRAY_SIZE(pdata->dcdc); struct wm831x_dcdc *dcdc; struct resource *res; @@ -820,7 +851,7 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev) if (pdata == NULL || pdata->dcdc[id] == NULL) return -ENODEV; - dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc), GFP_KERNEL); + dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL); if (dcdc == NULL) { dev_err(&pdev->dev, "Unable to allocate private data\n"); return -ENOMEM; @@ -842,16 +873,9 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev) dcdc->desc.type = REGULATOR_VOLTAGE; dcdc->desc.ops = &wm831x_boostp_ops; dcdc->desc.owner = THIS_MODULE; - dcdc->desc.enable_reg = WM831X_DCDC_ENABLE; - dcdc->desc.enable_mask = 1 << id; - config.dev = pdev->dev.parent; - if (pdata) - config.init_data = pdata->dcdc[id]; - config.driver_data = dcdc; - config.regmap = wm831x->regmap; - - dcdc->regulator = regulator_register(&dcdc->desc, &config); + dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev, + pdata->dcdc[id], dcdc, NULL); if (IS_ERR(dcdc->regulator)) { ret = PTR_ERR(dcdc->regulator); dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n", @@ -876,6 +900,7 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev) err_regulator: regulator_unregister(dcdc->regulator); err: + kfree(dcdc); return ret; } @@ -887,6 +912,7 @@ static __devexit int wm831x_boostp_remove(struct platform_device *pdev) free_irq(platform_get_irq_byname(pdev, "UV"), dcdc); regulator_unregister(dcdc->regulator); + kfree(dcdc); return 0; } @@ -910,9 +936,9 @@ static struct platform_driver wm831x_boostp_driver = { #define WM831X_EPE_BASE 6 static struct regulator_ops wm831x_epe_ops = { - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, + .is_enabled = wm831x_dcdc_is_enabled, + .enable = wm831x_dcdc_enable, + .disable = wm831x_dcdc_disable, .get_status = wm831x_dcdc_get_status, }; @@ -920,14 +946,16 @@ static __devinit int wm831x_epe_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_pdata *pdata = wm831x->dev->platform_data; - struct regulator_config config = { }; int id = pdev->id % ARRAY_SIZE(pdata->epe); struct wm831x_dcdc *dcdc; int ret; dev_dbg(&pdev->dev, "Probing EPE%d\n", id + 1); - dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc), GFP_KERNEL); + if (pdata == NULL || pdata->epe[id] == NULL) + return -ENODEV; + + dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL); if (dcdc == NULL) { dev_err(&pdev->dev, "Unable to allocate private data\n"); return -ENOMEM; @@ -944,16 +972,9 @@ static __devinit int wm831x_epe_probe(struct platform_device *pdev) dcdc->desc.ops = &wm831x_epe_ops; dcdc->desc.type = REGULATOR_VOLTAGE; dcdc->desc.owner = THIS_MODULE; - dcdc->desc.enable_reg = WM831X_DCDC_ENABLE; - dcdc->desc.enable_mask = 1 << dcdc->desc.id; - - config.dev = pdev->dev.parent; - if (pdata) - config.init_data = pdata->epe[id]; - config.driver_data = dcdc; - config.regmap = wm831x->regmap; - dcdc->regulator = regulator_register(&dcdc->desc, &config); + dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev, + pdata->epe[id], dcdc, NULL); if (IS_ERR(dcdc->regulator)) { ret = PTR_ERR(dcdc->regulator); dev_err(wm831x->dev, "Failed to register EPE%d: %d\n", @@ -966,6 +987,7 @@ static __devinit int wm831x_epe_probe(struct platform_device *pdev) return 0; err: + kfree(dcdc); return ret; } @@ -974,7 +996,9 @@ static __devexit int wm831x_epe_remove(struct platform_device *pdev) struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev); platform_set_drvdata(pdev, NULL); + regulator_unregister(dcdc->regulator); + kfree(dcdc); return 0; } diff --git a/trunk/drivers/regulator/wm831x-isink.c b/trunk/drivers/regulator/wm831x-isink.c index b50ab778b098..b414e09c5620 100644 --- a/trunk/drivers/regulator/wm831x-isink.c +++ b/trunk/drivers/regulator/wm831x-isink.c @@ -154,7 +154,6 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev) struct wm831x_pdata *pdata = wm831x->dev->platform_data; struct wm831x_isink *isink; int id = pdev->id % ARRAY_SIZE(pdata->isink); - struct regulator_config config = { }; struct resource *res; int ret, irq; @@ -190,11 +189,8 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev) isink->desc.type = REGULATOR_CURRENT; isink->desc.owner = THIS_MODULE; - config.dev = pdev->dev.parent; - config.init_data = pdata->isink[id]; - config.driver_data = isink; - - isink->regulator = regulator_register(&isink->desc, &config); + isink->regulator = regulator_register(&isink->desc, &pdev->dev, + pdata->isink[id], isink, NULL); if (IS_ERR(isink->regulator)) { ret = PTR_ERR(isink->regulator); dev_err(wm831x->dev, "Failed to register ISINK%d: %d\n", diff --git a/trunk/drivers/regulator/wm831x-ldo.c b/trunk/drivers/regulator/wm831x-ldo.c index aa1f8b3fbe16..641e9f6499d1 100644 --- a/trunk/drivers/regulator/wm831x-ldo.c +++ b/trunk/drivers/regulator/wm831x-ldo.c @@ -25,7 +25,7 @@ #include #include -#define WM831X_LDO_MAX_NAME 9 +#define WM831X_LDO_MAX_NAME 6 #define WM831X_LDO_CONTROL 0 #define WM831X_LDO_ON_CONTROL 1 @@ -36,7 +36,6 @@ struct wm831x_ldo { char name[WM831X_LDO_MAX_NAME]; - char supply_name[WM831X_LDO_MAX_NAME]; struct regulator_desc desc; int base; struct wm831x *wm831x; @@ -47,6 +46,41 @@ struct wm831x_ldo { * Shared */ +static int wm831x_ldo_is_enabled(struct regulator_dev *rdev) +{ + struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); + struct wm831x *wm831x = ldo->wm831x; + int mask = 1 << rdev_get_id(rdev); + int reg; + + reg = wm831x_reg_read(wm831x, WM831X_LDO_ENABLE); + if (reg < 0) + return reg; + + if (reg & mask) + return 1; + else + return 0; +} + +static int wm831x_ldo_enable(struct regulator_dev *rdev) +{ + struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); + struct wm831x *wm831x = ldo->wm831x; + int mask = 1 << rdev_get_id(rdev); + + return wm831x_set_bits(wm831x, WM831X_LDO_ENABLE, mask, mask); +} + +static int wm831x_ldo_disable(struct regulator_dev *rdev) +{ + struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); + struct wm831x *wm831x = ldo->wm831x; + int mask = 1 << rdev_get_id(rdev); + + return wm831x_set_bits(wm831x, WM831X_LDO_ENABLE, mask, 0); +} + static irqreturn_t wm831x_ldo_uv_irq(int irq, void *data) { struct wm831x_ldo *ldo = data; @@ -71,7 +105,7 @@ static int wm831x_gp_ldo_list_voltage(struct regulator_dev *rdev, /* 0.9-1.6V in 50mV steps */ if (selector <= WM831X_GP_LDO_SELECTOR_LOW) return 900000 + (selector * 50000); - /* 1.7-3.3V in 100mV steps */ + /* 1.7-3.3V in 50mV steps */ if (selector <= WM831X_GP_LDO_MAX_SELECTOR) return 1600000 + ((selector - WM831X_GP_LDO_SELECTOR_LOW) * 100000); @@ -126,6 +160,22 @@ static int wm831x_gp_ldo_set_suspend_voltage(struct regulator_dev *rdev, return wm831x_gp_ldo_set_voltage_int(rdev, reg, uV, uV, &selector); } +static int wm831x_gp_ldo_get_voltage_sel(struct regulator_dev *rdev) +{ + struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); + struct wm831x *wm831x = ldo->wm831x; + int reg = ldo->base + WM831X_LDO_ON_CONTROL; + int ret; + + ret = wm831x_reg_read(wm831x, reg); + if (ret < 0) + return ret; + + ret &= WM831X_LDO1_ON_VSEL_MASK; + + return ret; +} + static unsigned int wm831x_gp_ldo_get_mode(struct regulator_dev *rdev) { struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); @@ -243,7 +293,7 @@ static unsigned int wm831x_gp_ldo_get_optimum_mode(struct regulator_dev *rdev, static struct regulator_ops wm831x_gp_ldo_ops = { .list_voltage = wm831x_gp_ldo_list_voltage, - .get_voltage_sel = regulator_get_voltage_sel_regmap, + .get_voltage_sel = wm831x_gp_ldo_get_voltage_sel, .set_voltage = wm831x_gp_ldo_set_voltage, .set_suspend_voltage = wm831x_gp_ldo_set_suspend_voltage, .get_mode = wm831x_gp_ldo_get_mode, @@ -251,16 +301,15 @@ static struct regulator_ops wm831x_gp_ldo_ops = { .get_status = wm831x_gp_ldo_get_status, .get_optimum_mode = wm831x_gp_ldo_get_optimum_mode, - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, + .is_enabled = wm831x_ldo_is_enabled, + .enable = wm831x_ldo_enable, + .disable = wm831x_ldo_disable, }; static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_pdata *pdata = wm831x->dev->platform_data; - struct regulator_config config = { }; int id; struct wm831x_ldo *ldo; struct resource *res; @@ -274,6 +323,9 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); + if (pdata == NULL || pdata->ldo[id] == NULL) + return -ENODEV; + ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL); if (ldo == NULL) { dev_err(&pdev->dev, "Unable to allocate private data\n"); @@ -292,28 +344,14 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev) snprintf(ldo->name, sizeof(ldo->name), "LDO%d", id + 1); ldo->desc.name = ldo->name; - - snprintf(ldo->supply_name, sizeof(ldo->supply_name), - "LDO%dVDD", id + 1); - ldo->desc.supply_name = ldo->supply_name; - ldo->desc.id = id; ldo->desc.type = REGULATOR_VOLTAGE; ldo->desc.n_voltages = WM831X_GP_LDO_MAX_SELECTOR + 1; ldo->desc.ops = &wm831x_gp_ldo_ops; ldo->desc.owner = THIS_MODULE; - ldo->desc.vsel_reg = ldo->base + WM831X_LDO_ON_CONTROL; - ldo->desc.vsel_mask = WM831X_LDO1_ON_VSEL_MASK; - ldo->desc.enable_reg = WM831X_LDO_ENABLE; - ldo->desc.enable_mask = 1 << id; - - config.dev = pdev->dev.parent; - if (pdata) - config.init_data = pdata->ldo[id]; - config.driver_data = ldo; - config.regmap = wm831x->regmap; - - ldo->regulator = regulator_register(&ldo->desc, &config); + + ldo->regulator = regulator_register(&ldo->desc, &pdev->dev, + pdata->ldo[id], ldo, NULL); if (IS_ERR(ldo->regulator)) { ret = PTR_ERR(ldo->regulator); dev_err(wm831x->dev, "Failed to register LDO%d: %d\n", @@ -376,7 +414,7 @@ static int wm831x_aldo_list_voltage(struct regulator_dev *rdev, /* 1-1.6V in 50mV steps */ if (selector <= WM831X_ALDO_SELECTOR_LOW) return 1000000 + (selector * 50000); - /* 1.7-3.5V in 100mV steps */ + /* 1.7-3.5V in 50mV steps */ if (selector <= WM831X_ALDO_MAX_SELECTOR) return 1600000 + ((selector - WM831X_ALDO_SELECTOR_LOW) * 100000); @@ -430,6 +468,22 @@ static int wm831x_aldo_set_suspend_voltage(struct regulator_dev *rdev, return wm831x_aldo_set_voltage_int(rdev, reg, uV, uV, &selector); } +static int wm831x_aldo_get_voltage_sel(struct regulator_dev *rdev) +{ + struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); + struct wm831x *wm831x = ldo->wm831x; + int reg = ldo->base + WM831X_LDO_ON_CONTROL; + int ret; + + ret = wm831x_reg_read(wm831x, reg); + if (ret < 0) + return ret; + + ret &= WM831X_LDO7_ON_VSEL_MASK; + + return ret; +} + static unsigned int wm831x_aldo_get_mode(struct regulator_dev *rdev) { struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); @@ -505,23 +559,22 @@ static int wm831x_aldo_get_status(struct regulator_dev *rdev) static struct regulator_ops wm831x_aldo_ops = { .list_voltage = wm831x_aldo_list_voltage, - .get_voltage_sel = regulator_get_voltage_sel_regmap, + .get_voltage_sel = wm831x_aldo_get_voltage_sel, .set_voltage = wm831x_aldo_set_voltage, .set_suspend_voltage = wm831x_aldo_set_suspend_voltage, .get_mode = wm831x_aldo_get_mode, .set_mode = wm831x_aldo_set_mode, .get_status = wm831x_aldo_get_status, - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, + .is_enabled = wm831x_ldo_is_enabled, + .enable = wm831x_ldo_enable, + .disable = wm831x_ldo_disable, }; static __devinit int wm831x_aldo_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_pdata *pdata = wm831x->dev->platform_data; - struct regulator_config config = { }; int id; struct wm831x_ldo *ldo; struct resource *res; @@ -535,6 +588,9 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); + if (pdata == NULL || pdata->ldo[id] == NULL) + return -ENODEV; + ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL); if (ldo == NULL) { dev_err(&pdev->dev, "Unable to allocate private data\n"); @@ -553,28 +609,14 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev) snprintf(ldo->name, sizeof(ldo->name), "LDO%d", id + 1); ldo->desc.name = ldo->name; - - snprintf(ldo->supply_name, sizeof(ldo->supply_name), - "LDO%dVDD", id + 1); - ldo->desc.supply_name = ldo->supply_name; - ldo->desc.id = id; ldo->desc.type = REGULATOR_VOLTAGE; ldo->desc.n_voltages = WM831X_ALDO_MAX_SELECTOR + 1; ldo->desc.ops = &wm831x_aldo_ops; ldo->desc.owner = THIS_MODULE; - ldo->desc.vsel_reg = ldo->base + WM831X_LDO_ON_CONTROL; - ldo->desc.vsel_mask = WM831X_LDO7_ON_VSEL_MASK; - ldo->desc.enable_reg = WM831X_LDO_ENABLE; - ldo->desc.enable_mask = 1 << id; - - config.dev = pdev->dev.parent; - if (pdata) - config.init_data = pdata->ldo[id]; - config.driver_data = ldo; - config.regmap = wm831x->regmap; - - ldo->regulator = regulator_register(&ldo->desc, &config); + + ldo->regulator = regulator_register(&ldo->desc, &pdev->dev, + pdata->ldo[id], ldo, NULL); if (IS_ERR(ldo->regulator)) { ret = PTR_ERR(ldo->regulator); dev_err(wm831x->dev, "Failed to register LDO%d: %d\n", @@ -626,6 +668,15 @@ static struct platform_driver wm831x_aldo_driver = { #define WM831X_ALIVE_LDO_MAX_SELECTOR 0xf +static int wm831x_alive_ldo_list_voltage(struct regulator_dev *rdev, + unsigned int selector) +{ + /* 0.8-1.55V in 50mV steps */ + if (selector <= WM831X_ALIVE_LDO_MAX_SELECTOR) + return 800000 + (selector * 50000); + return -EINVAL; +} + static int wm831x_alive_ldo_set_voltage_int(struct regulator_dev *rdev, int reg, int min_uV, int max_uV, @@ -637,7 +688,7 @@ static int wm831x_alive_ldo_set_voltage_int(struct regulator_dev *rdev, vsel = (min_uV - 800000) / 50000; - ret = regulator_list_voltage_linear(rdev, vsel); + ret = wm831x_alive_ldo_list_voltage(rdev, vsel); if (ret < 0) return ret; if (ret < min_uV || ret > max_uV) @@ -669,6 +720,22 @@ static int wm831x_alive_ldo_set_suspend_voltage(struct regulator_dev *rdev, return wm831x_alive_ldo_set_voltage_int(rdev, reg, uV, uV, &selector); } +static int wm831x_alive_ldo_get_voltage_sel(struct regulator_dev *rdev) +{ + struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); + struct wm831x *wm831x = ldo->wm831x; + int reg = ldo->base + WM831X_ALIVE_LDO_ON_CONTROL; + int ret; + + ret = wm831x_reg_read(wm831x, reg); + if (ret < 0) + return ret; + + ret &= WM831X_LDO11_ON_VSEL_MASK; + + return ret; +} + static int wm831x_alive_ldo_get_status(struct regulator_dev *rdev) { struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); @@ -687,22 +754,21 @@ static int wm831x_alive_ldo_get_status(struct regulator_dev *rdev) } static struct regulator_ops wm831x_alive_ldo_ops = { - .list_voltage = regulator_list_voltage_linear, - .get_voltage_sel = regulator_get_voltage_sel_regmap, + .list_voltage = wm831x_alive_ldo_list_voltage, + .get_voltage_sel = wm831x_alive_ldo_get_voltage_sel, .set_voltage = wm831x_alive_ldo_set_voltage, .set_suspend_voltage = wm831x_alive_ldo_set_suspend_voltage, .get_status = wm831x_alive_ldo_get_status, - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, + .is_enabled = wm831x_ldo_is_enabled, + .enable = wm831x_ldo_enable, + .disable = wm831x_ldo_disable, }; static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_pdata *pdata = wm831x->dev->platform_data; - struct regulator_config config = { }; int id; struct wm831x_ldo *ldo; struct resource *res; @@ -717,6 +783,9 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); + if (pdata == NULL || pdata->ldo[id] == NULL) + return -ENODEV; + ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL); if (ldo == NULL) { dev_err(&pdev->dev, "Unable to allocate private data\n"); @@ -735,30 +804,14 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev) snprintf(ldo->name, sizeof(ldo->name), "LDO%d", id + 1); ldo->desc.name = ldo->name; - - snprintf(ldo->supply_name, sizeof(ldo->supply_name), - "LDO%dVDD", id + 1); - ldo->desc.supply_name = ldo->supply_name; - ldo->desc.id = id; ldo->desc.type = REGULATOR_VOLTAGE; ldo->desc.n_voltages = WM831X_ALIVE_LDO_MAX_SELECTOR + 1; ldo->desc.ops = &wm831x_alive_ldo_ops; ldo->desc.owner = THIS_MODULE; - ldo->desc.vsel_reg = ldo->base + WM831X_ALIVE_LDO_ON_CONTROL; - ldo->desc.vsel_mask = WM831X_LDO11_ON_VSEL_MASK; - ldo->desc.enable_reg = WM831X_LDO_ENABLE; - ldo->desc.enable_mask = 1 << id; - ldo->desc.min_uV = 800000; - ldo->desc.uV_step = 50000; - - config.dev = pdev->dev.parent; - if (pdata) - config.init_data = pdata->ldo[id]; - config.driver_data = ldo; - config.regmap = wm831x->regmap; - - ldo->regulator = regulator_register(&ldo->desc, &config); + + ldo->regulator = regulator_register(&ldo->desc, &pdev->dev, + pdata->ldo[id], ldo, NULL); if (IS_ERR(ldo->regulator)) { ret = PTR_ERR(ldo->regulator); dev_err(wm831x->dev, "Failed to register LDO%d: %d\n", diff --git a/trunk/drivers/regulator/wm8350-regulator.c b/trunk/drivers/regulator/wm8350-regulator.c index 94e550dc70b6..05ecfb872319 100644 --- a/trunk/drivers/regulator/wm8350-regulator.c +++ b/trunk/drivers/regulator/wm8350-regulator.c @@ -1269,7 +1269,7 @@ static struct regulator_ops wm8350_isink_ops = { .enable_time = wm8350_isink_enable_time, }; -static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { +static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { { .name = "DCDC1", .id = WM8350_DCDC_1, @@ -1398,7 +1398,6 @@ static irqreturn_t pmic_uv_handler(int irq, void *data) static int wm8350_regulator_probe(struct platform_device *pdev) { struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev); - struct regulator_config config = { }; struct regulator_dev *rdev; int ret; u16 val; @@ -1426,12 +1425,10 @@ static int wm8350_regulator_probe(struct platform_device *pdev) break; } - config.dev = &pdev->dev; - config.init_data = pdev->dev.platform_data; - config.driver_data = dev_get_drvdata(&pdev->dev); - /* register regulator */ - rdev = regulator_register(&wm8350_reg[pdev->id], &config); + rdev = regulator_register(&wm8350_reg[pdev->id], &pdev->dev, + pdev->dev.platform_data, + dev_get_drvdata(&pdev->dev), NULL); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register %s\n", wm8350_reg[pdev->id].name); diff --git a/trunk/drivers/regulator/wm8400-regulator.c b/trunk/drivers/regulator/wm8400-regulator.c index 69a2b7ce5e4a..8477153780b6 100644 --- a/trunk/drivers/regulator/wm8400-regulator.c +++ b/trunk/drivers/regulator/wm8400-regulator.c @@ -19,6 +19,31 @@ #include #include +static int wm8400_ldo_is_enabled(struct regulator_dev *dev) +{ + struct wm8400 *wm8400 = rdev_get_drvdata(dev); + u16 val; + + val = wm8400_reg_read(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev)); + return (val & WM8400_LDO1_ENA) != 0; +} + +static int wm8400_ldo_enable(struct regulator_dev *dev) +{ + struct wm8400 *wm8400 = rdev_get_drvdata(dev); + + return wm8400_set_bits(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev), + WM8400_LDO1_ENA, WM8400_LDO1_ENA); +} + +static int wm8400_ldo_disable(struct regulator_dev *dev) +{ + struct wm8400 *wm8400 = rdev_get_drvdata(dev); + + return wm8400_set_bits(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev), + WM8400_LDO1_ENA, 0); +} + static int wm8400_ldo_list_voltage(struct regulator_dev *dev, unsigned selector) { @@ -31,9 +56,21 @@ static int wm8400_ldo_list_voltage(struct regulator_dev *dev, return 1600000 + ((selector - 14) * 100000); } -static int wm8400_ldo_map_voltage(struct regulator_dev *dev, - int min_uV, int max_uV) +static int wm8400_ldo_get_voltage_sel(struct regulator_dev *dev) { + struct wm8400 *wm8400 = rdev_get_drvdata(dev); + u16 val; + + val = wm8400_reg_read(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev)); + val &= WM8400_LDO1_VSEL_MASK; + + return val; +} + +static int wm8400_ldo_set_voltage(struct regulator_dev *dev, + int min_uV, int max_uV, unsigned *selector) +{ + struct wm8400 *wm8400 = rdev_get_drvdata(dev); u16 val; if (min_uV < 900000 || min_uV > 3300000) @@ -57,19 +94,92 @@ static int wm8400_ldo_map_voltage(struct regulator_dev *dev, val += 0xf; } - return val; + *selector = val; + + return wm8400_set_bits(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev), + WM8400_LDO1_VSEL_MASK, val); } static struct regulator_ops wm8400_ldo_ops = { - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, + .is_enabled = wm8400_ldo_is_enabled, + .enable = wm8400_ldo_enable, + .disable = wm8400_ldo_disable, .list_voltage = wm8400_ldo_list_voltage, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .map_voltage = wm8400_ldo_map_voltage, + .get_voltage_sel = wm8400_ldo_get_voltage_sel, + .set_voltage = wm8400_ldo_set_voltage, }; +static int wm8400_dcdc_is_enabled(struct regulator_dev *dev) +{ + struct wm8400 *wm8400 = rdev_get_drvdata(dev); + int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; + u16 val; + + val = wm8400_reg_read(wm8400, WM8400_DCDC1_CONTROL_1 + offset); + return (val & WM8400_DC1_ENA) != 0; +} + +static int wm8400_dcdc_enable(struct regulator_dev *dev) +{ + struct wm8400 *wm8400 = rdev_get_drvdata(dev); + int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; + + return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, + WM8400_DC1_ENA, WM8400_DC1_ENA); +} + +static int wm8400_dcdc_disable(struct regulator_dev *dev) +{ + struct wm8400 *wm8400 = rdev_get_drvdata(dev); + int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; + + return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, + WM8400_DC1_ENA, 0); +} + +static int wm8400_dcdc_list_voltage(struct regulator_dev *dev, + unsigned selector) +{ + if (selector > WM8400_DC1_VSEL_MASK) + return -EINVAL; + + return 850000 + (selector * 25000); +} + +static int wm8400_dcdc_get_voltage_sel(struct regulator_dev *dev) +{ + struct wm8400 *wm8400 = rdev_get_drvdata(dev); + u16 val; + int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; + + val = wm8400_reg_read(wm8400, WM8400_DCDC1_CONTROL_1 + offset); + val &= WM8400_DC1_VSEL_MASK; + + return val; +} + +static int wm8400_dcdc_set_voltage(struct regulator_dev *dev, + int min_uV, int max_uV, unsigned *selector) +{ + struct wm8400 *wm8400 = rdev_get_drvdata(dev); + u16 val; + int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; + + if (min_uV < 850000) + return -EINVAL; + + val = DIV_ROUND_UP(min_uV - 850000, 25000); + + if (850000 + (25000 * val) > max_uV) + return -EINVAL; + BUG_ON(850000 + (25000 * val) < min_uV); + + *selector = val; + + return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, + WM8400_DC1_VSEL_MASK, val); +} + static unsigned int wm8400_dcdc_get_mode(struct regulator_dev *dev) { struct wm8400 *wm8400 = rdev_get_drvdata(dev); @@ -148,12 +258,12 @@ static unsigned int wm8400_dcdc_get_optimum_mode(struct regulator_dev *dev, } static struct regulator_ops wm8400_dcdc_ops = { - .is_enabled = regulator_is_enabled_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .list_voltage = regulator_list_voltage_linear, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_sel = regulator_set_voltage_sel_regmap, + .is_enabled = wm8400_dcdc_is_enabled, + .enable = wm8400_dcdc_enable, + .disable = wm8400_dcdc_disable, + .list_voltage = wm8400_dcdc_list_voltage, + .get_voltage_sel = wm8400_dcdc_get_voltage_sel, + .set_voltage = wm8400_dcdc_set_voltage, .get_mode = wm8400_dcdc_get_mode, .set_mode = wm8400_dcdc_set_mode, .get_optimum_mode = wm8400_dcdc_get_optimum_mode, @@ -164,11 +274,7 @@ static struct regulator_desc regulators[] = { .name = "LDO1", .id = WM8400_LDO1, .ops = &wm8400_ldo_ops, - .enable_reg = WM8400_LDO1_CONTROL, - .enable_mask = WM8400_LDO1_ENA, .n_voltages = WM8400_LDO1_VSEL_MASK + 1, - .vsel_reg = WM8400_LDO1_CONTROL, - .vsel_mask = WM8400_LDO1_VSEL_MASK, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -176,23 +282,15 @@ static struct regulator_desc regulators[] = { .name = "LDO2", .id = WM8400_LDO2, .ops = &wm8400_ldo_ops, - .enable_reg = WM8400_LDO2_CONTROL, - .enable_mask = WM8400_LDO2_ENA, .n_voltages = WM8400_LDO2_VSEL_MASK + 1, .type = REGULATOR_VOLTAGE, - .vsel_reg = WM8400_LDO2_CONTROL, - .vsel_mask = WM8400_LDO2_VSEL_MASK, .owner = THIS_MODULE, }, { .name = "LDO3", .id = WM8400_LDO3, .ops = &wm8400_ldo_ops, - .enable_reg = WM8400_LDO3_CONTROL, - .enable_mask = WM8400_LDO3_ENA, .n_voltages = WM8400_LDO3_VSEL_MASK + 1, - .vsel_reg = WM8400_LDO3_CONTROL, - .vsel_mask = WM8400_LDO3_VSEL_MASK, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -200,11 +298,7 @@ static struct regulator_desc regulators[] = { .name = "LDO4", .id = WM8400_LDO4, .ops = &wm8400_ldo_ops, - .enable_reg = WM8400_LDO4_CONTROL, - .enable_mask = WM8400_LDO4_ENA, .n_voltages = WM8400_LDO4_VSEL_MASK + 1, - .vsel_reg = WM8400_LDO4_CONTROL, - .vsel_mask = WM8400_LDO4_VSEL_MASK, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -212,13 +306,7 @@ static struct regulator_desc regulators[] = { .name = "DCDC1", .id = WM8400_DCDC1, .ops = &wm8400_dcdc_ops, - .enable_reg = WM8400_DCDC1_CONTROL_1, - .enable_mask = WM8400_DC1_ENA_MASK, .n_voltages = WM8400_DC1_VSEL_MASK + 1, - .vsel_reg = WM8400_DCDC1_CONTROL_1, - .vsel_mask = WM8400_DC1_VSEL_MASK, - .min_uV = 850000, - .uV_step = 25000, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -226,13 +314,7 @@ static struct regulator_desc regulators[] = { .name = "DCDC2", .id = WM8400_DCDC2, .ops = &wm8400_dcdc_ops, - .enable_reg = WM8400_DCDC2_CONTROL_1, - .enable_mask = WM8400_DC1_ENA_MASK, .n_voltages = WM8400_DC2_VSEL_MASK + 1, - .vsel_reg = WM8400_DCDC2_CONTROL_1, - .vsel_mask = WM8400_DC2_VSEL_MASK, - .min_uV = 850000, - .uV_step = 25000, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, @@ -241,15 +323,11 @@ static struct regulator_desc regulators[] = { static int __devinit wm8400_regulator_probe(struct platform_device *pdev) { struct wm8400 *wm8400 = container_of(pdev, struct wm8400, regulators[pdev->id]); - struct regulator_config config = { }; struct regulator_dev *rdev; - config.dev = &pdev->dev; - config.init_data = pdev->dev.platform_data; - config.driver_data = wm8400; - config.regmap = wm8400->regmap; + rdev = regulator_register(®ulators[pdev->id], &pdev->dev, + pdev->dev.platform_data, wm8400, NULL); - rdev = regulator_register(®ulators[pdev->id], &config); if (IS_ERR(rdev)) return PTR_ERR(rdev); diff --git a/trunk/drivers/regulator/wm8994-regulator.c b/trunk/drivers/regulator/wm8994-regulator.c index 9a994316e63c..75ed402d9f43 100644 --- a/trunk/drivers/regulator/wm8994-regulator.c +++ b/trunk/drivers/regulator/wm8994-regulator.c @@ -86,6 +86,36 @@ static int wm8994_ldo1_list_voltage(struct regulator_dev *rdev, return (selector * 100000) + 2400000; } +static int wm8994_ldo1_get_voltage_sel(struct regulator_dev *rdev) +{ + struct wm8994_ldo *ldo = rdev_get_drvdata(rdev); + int val; + + val = wm8994_reg_read(ldo->wm8994, WM8994_LDO_1); + if (val < 0) + return val; + + return (val & WM8994_LDO1_VSEL_MASK) >> WM8994_LDO1_VSEL_SHIFT; +} + +static int wm8994_ldo1_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned *s) +{ + struct wm8994_ldo *ldo = rdev_get_drvdata(rdev); + int selector, v; + + selector = (min_uV - 2400000) / 100000; + v = wm8994_ldo1_list_voltage(rdev, selector); + if (v < 0 || v > max_uV) + return -EINVAL; + + *s = selector; + selector <<= WM8994_LDO1_VSEL_SHIFT; + + return wm8994_set_bits(ldo->wm8994, WM8994_LDO_1, + WM8994_LDO1_VSEL_MASK, selector); +} + static struct regulator_ops wm8994_ldo1_ops = { .enable = wm8994_ldo_enable, .disable = wm8994_ldo_disable, @@ -93,8 +123,8 @@ static struct regulator_ops wm8994_ldo1_ops = { .enable_time = wm8994_ldo_enable_time, .list_voltage = wm8994_ldo1_list_voltage, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = wm8994_ldo1_get_voltage_sel, + .set_voltage = wm8994_ldo1_set_voltage, }; static int wm8994_ldo2_list_voltage(struct regulator_dev *rdev, @@ -123,6 +153,51 @@ static int wm8994_ldo2_list_voltage(struct regulator_dev *rdev, } } +static int wm8994_ldo2_get_voltage_sel(struct regulator_dev *rdev) +{ + struct wm8994_ldo *ldo = rdev_get_drvdata(rdev); + int val; + + val = wm8994_reg_read(ldo->wm8994, WM8994_LDO_2); + if (val < 0) + return val; + + return (val & WM8994_LDO2_VSEL_MASK) >> WM8994_LDO2_VSEL_SHIFT; +} + +static int wm8994_ldo2_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned *s) +{ + struct wm8994_ldo *ldo = rdev_get_drvdata(rdev); + int selector, v; + + switch (ldo->wm8994->type) { + case WM8994: + selector = (min_uV - 900000) / 100000; + break; + case WM8958: + selector = (min_uV - 1000000) / 100000; + break; + case WM1811: + selector = (min_uV - 950000) / 100000; + if (selector == 0) + selector = 1; + break; + default: + return -EINVAL; + } + + v = wm8994_ldo2_list_voltage(rdev, selector); + if (v < 0 || v > max_uV) + return -EINVAL; + + *s = selector; + selector <<= WM8994_LDO2_VSEL_SHIFT; + + return wm8994_set_bits(ldo->wm8994, WM8994_LDO_2, + WM8994_LDO2_VSEL_MASK, selector); +} + static struct regulator_ops wm8994_ldo2_ops = { .enable = wm8994_ldo_enable, .disable = wm8994_ldo_disable, @@ -130,18 +205,16 @@ static struct regulator_ops wm8994_ldo2_ops = { .enable_time = wm8994_ldo_enable_time, .list_voltage = wm8994_ldo2_list_voltage, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = wm8994_ldo2_get_voltage_sel, + .set_voltage = wm8994_ldo2_set_voltage, }; -static const struct regulator_desc wm8994_ldo_desc[] = { +static struct regulator_desc wm8994_ldo_desc[] = { { .name = "LDO1", .id = 1, .type = REGULATOR_VOLTAGE, .n_voltages = WM8994_LDO1_MAX_SELECTOR + 1, - .vsel_reg = WM8994_LDO_1, - .vsel_mask = WM8994_LDO1_VSEL_MASK, .ops = &wm8994_ldo1_ops, .owner = THIS_MODULE, }, @@ -150,8 +223,6 @@ static const struct regulator_desc wm8994_ldo_desc[] = { .id = 2, .type = REGULATOR_VOLTAGE, .n_voltages = WM8994_LDO2_MAX_SELECTOR + 1, - .vsel_reg = WM8994_LDO_2, - .vsel_mask = WM8994_LDO2_VSEL_MASK, .ops = &wm8994_ldo2_ops, .owner = THIS_MODULE, }, @@ -162,12 +233,14 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev) struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent); struct wm8994_pdata *pdata = wm8994->dev->platform_data; int id = pdev->id % ARRAY_SIZE(pdata->ldo); - struct regulator_config config = { }; struct wm8994_ldo *ldo; int ret; dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1); + if (!pdata) + return -ENODEV; + ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm8994_ldo), GFP_KERNEL); if (ldo == NULL) { dev_err(&pdev->dev, "Unable to allocate private data\n"); @@ -179,22 +252,24 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev) if (pdata->ldo[id].enable && gpio_is_valid(pdata->ldo[id].enable)) { ldo->enable = pdata->ldo[id].enable; - ret = gpio_request_one(ldo->enable, 0, "WM8994 LDO enable"); + ret = gpio_request(ldo->enable, "WM8994 LDO enable"); if (ret < 0) { dev_err(&pdev->dev, "Failed to get enable GPIO: %d\n", ret); goto err; } + + ret = gpio_direction_output(ldo->enable, ldo->is_enabled); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to set GPIO up: %d\n", + ret); + goto err_gpio; + } } else ldo->is_enabled = true; - config.dev = wm8994->dev; - config.driver_data = ldo; - config.regmap = wm8994->regmap; - if (pdata) - config.init_data = pdata->ldo[id].init_data; - - ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &config); + ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &pdev->dev, + pdata->ldo[id].init_data, ldo, NULL); if (IS_ERR(ldo->regulator)) { ret = PTR_ERR(ldo->regulator); dev_err(wm8994->dev, "Failed to register LDO%d: %d\n", diff --git a/trunk/drivers/remoteproc/remoteproc_core.c b/trunk/drivers/remoteproc/remoteproc_core.c index e756a0df3664..ee15c68fb519 100644 --- a/trunk/drivers/remoteproc/remoteproc_core.c +++ b/trunk/drivers/remoteproc/remoteproc_core.c @@ -354,7 +354,7 @@ static void __rproc_free_vrings(struct rproc_vdev *rvdev, int i) { struct rproc *rproc = rvdev->rproc; - for (i--; i >= 0; i--) { + for (i--; i > 0; i--) { struct rproc_vring *rvring = &rvdev->vring[i]; int size = PAGE_ALIGN(vring_size(rvring->len, rvring->align)); diff --git a/trunk/drivers/rtc/rtc-mpc5121.c b/trunk/drivers/rtc/rtc-mpc5121.c index 029e421baaed..42f5f829b3ee 100644 --- a/trunk/drivers/rtc/rtc-mpc5121.c +++ b/trunk/drivers/rtc/rtc-mpc5121.c @@ -360,11 +360,12 @@ static int __devinit mpc5121_rtc_probe(struct platform_device *op) &mpc5200_rtc_ops, THIS_MODULE); } + rtc->rtc->uie_unsupported = 1; + if (IS_ERR(rtc->rtc)) { err = PTR_ERR(rtc->rtc); goto out_free_irq; } - rtc->rtc->uie_unsupported = 1; return 0; diff --git a/trunk/drivers/rtc/rtc-pl031.c b/trunk/drivers/rtc/rtc-pl031.c index f027c063fb20..684ef4bbfce4 100644 --- a/trunk/drivers/rtc/rtc-pl031.c +++ b/trunk/drivers/rtc/rtc-pl031.c @@ -312,7 +312,6 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) int ret; struct pl031_local *ldata; struct rtc_class_ops *ops = id->data; - unsigned long time; ret = amba_request_regions(adev, NULL); if (ret) @@ -344,23 +343,6 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN, ldata->base + RTC_CR); - /* - * On ST PL031 variants, the RTC reset value does not provide correct - * weekday for 2000-01-01. Correct the erroneous sunday to saturday. - */ - if (ldata->hw_designer == AMBA_VENDOR_ST) { - if (readl(ldata->base + RTC_YDR) == 0x2000) { - time = readl(ldata->base + RTC_DR); - if ((time & - (RTC_MON_MASK | RTC_MDAY_MASK | RTC_WDAY_MASK)) - == 0x02120000) { - time = time | (0x7 << RTC_WDAY_SHIFT); - writel(0x2000, ldata->base + RTC_YLR); - writel(time, ldata->base + RTC_LR); - } - } - } - ldata->rtc = rtc_device_register("pl031", &adev->dev, ops, THIS_MODULE); if (IS_ERR(ldata->rtc)) { diff --git a/trunk/drivers/s390/char/sclp_cmd.c b/trunk/drivers/s390/char/sclp_cmd.c index 36506366158d..231a1d85127b 100644 --- a/trunk/drivers/s390/char/sclp_cmd.c +++ b/trunk/drivers/s390/char/sclp_cmd.c @@ -352,17 +352,7 @@ static int do_assign_storage(sclp_cmdw_t cmd, u16 rn) static int sclp_assign_storage(u16 rn) { - unsigned long long start, address; - int rc; - - rc = do_assign_storage(0x000d0001, rn); - if (rc) - goto out; - start = address = rn2addr(rn); - for (; address < start + rzm; address += PAGE_SIZE) - page_set_storage_key(address, PAGE_DEFAULT_KEY, 0); -out: - return rc; + return do_assign_storage(0x000d0001, rn); } static int sclp_unassign_storage(u16 rn) diff --git a/trunk/drivers/s390/char/tape.h b/trunk/drivers/s390/char/tape.h index bc6c7cfd36b6..267b54e8ff5a 100644 --- a/trunk/drivers/s390/char/tape.h +++ b/trunk/drivers/s390/char/tape.h @@ -154,6 +154,12 @@ struct tape_discipline { struct tape_request *(*read_block)(struct tape_device *, size_t); struct tape_request *(*write_block)(struct tape_device *, size_t); void (*process_eov)(struct tape_device*); +#ifdef CONFIG_S390_TAPE_BLOCK + /* Block device stuff. */ + struct tape_request *(*bread)(struct tape_device *, struct request *); + void (*check_locate)(struct tape_device *, struct tape_request *); + void (*free_bread)(struct tape_request *); +#endif /* ioctl function for additional ioctls. */ int (*ioctl_fn)(struct tape_device *, unsigned int, unsigned long); /* Array of tape commands with TAPE_NR_MTOPS entries */ @@ -176,6 +182,26 @@ struct tape_char_data { int block_size; /* of size block_size. */ }; +#ifdef CONFIG_S390_TAPE_BLOCK +/* Block Frontend Data */ +struct tape_blk_data +{ + struct tape_device * device; + /* Block device request queue. */ + struct request_queue * request_queue; + spinlock_t request_queue_lock; + + /* Task to move entries from block request to CCS request queue. */ + struct work_struct requeue_task; + atomic_t requeue_scheduled; + + /* Current position on the tape. */ + long block_position; + int medium_changed; + struct gendisk * disk; +}; +#endif + /* Tape Info */ struct tape_device { /* entry in tape_device_list */ @@ -222,6 +248,10 @@ struct tape_device { /* Character device frontend data */ struct tape_char_data char_data; +#ifdef CONFIG_S390_TAPE_BLOCK + /* Block dev frontend data */ + struct tape_blk_data blk_data; +#endif /* Function to start or stop the next request later. */ struct delayed_work tape_dnr; @@ -283,6 +313,19 @@ extern void tapechar_exit(void); extern int tapechar_setup_device(struct tape_device *); extern void tapechar_cleanup_device(struct tape_device *); +/* Externals from tape_block.c */ +#ifdef CONFIG_S390_TAPE_BLOCK +extern int tapeblock_init (void); +extern void tapeblock_exit(void); +extern int tapeblock_setup_device(struct tape_device *); +extern void tapeblock_cleanup_device(struct tape_device *); +#else +static inline int tapeblock_init (void) {return 0;} +static inline void tapeblock_exit (void) {;} +static inline int tapeblock_setup_device(struct tape_device *t) {return 0;} +static inline void tapeblock_cleanup_device (struct tape_device *t) {;} +#endif + /* tape initialisation functions */ #ifdef CONFIG_PROC_FS extern void tape_proc_init (void); diff --git a/trunk/drivers/s390/char/tape_34xx.c b/trunk/drivers/s390/char/tape_34xx.c index b28de80b7ca4..934ef33eb9a4 100644 --- a/trunk/drivers/s390/char/tape_34xx.c +++ b/trunk/drivers/s390/char/tape_34xx.c @@ -323,6 +323,20 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request, inhibit_cu_recovery = (*device->modeset_byte & 0x80) ? 1 : 0; sense = irb->ecw; +#ifdef CONFIG_S390_TAPE_BLOCK + if (request->op == TO_BLOCK) { + /* + * Recovery for block device requests. Set the block_position + * to something invalid and retry. + */ + device->blk_data.block_position = -1; + if (request->retries-- <= 0) + return tape_34xx_erp_failed(request, -EIO); + else + return tape_34xx_erp_retry(request); + } +#endif + if ( sense[0] & SENSE_COMMAND_REJECT && sense[1] & SENSE_WRITE_PROTECT @@ -1115,6 +1129,123 @@ tape_34xx_mtseek(struct tape_device *device, int mt_count) return tape_do_io_free(device, request); } +#ifdef CONFIG_S390_TAPE_BLOCK +/* + * Tape block read for 34xx. + */ +static struct tape_request * +tape_34xx_bread(struct tape_device *device, struct request *req) +{ + struct tape_request *request; + struct ccw1 *ccw; + int count = 0; + unsigned off; + char *dst; + struct bio_vec *bv; + struct req_iterator iter; + struct tape_34xx_block_id * start_block; + + DBF_EVENT(6, "xBREDid:"); + + /* Count the number of blocks for the request. */ + rq_for_each_segment(bv, req, iter) + count += bv->bv_len >> (TAPEBLOCK_HSEC_S2B + 9); + + /* Allocate the ccw request. */ + request = tape_alloc_request(3+count+1, 8); + if (IS_ERR(request)) + return request; + + /* Setup ccws. */ + request->op = TO_BLOCK; + start_block = (struct tape_34xx_block_id *) request->cpdata; + start_block->block = blk_rq_pos(req) >> TAPEBLOCK_HSEC_S2B; + DBF_EVENT(6, "start_block = %i\n", start_block->block); + + ccw = request->cpaddr; + ccw = tape_ccw_cc(ccw, MODE_SET_DB, 1, device->modeset_byte); + + /* + * We always setup a nop after the mode set ccw. This slot is + * used in tape_std_check_locate to insert a locate ccw if the + * current tape position doesn't match the start block to be read. + * The second nop will be filled with a read block id which is in + * turn used by tape_34xx_free_bread to populate the segment bid + * table. + */ + ccw = tape_ccw_cc(ccw, NOP, 0, NULL); + ccw = tape_ccw_cc(ccw, NOP, 0, NULL); + + rq_for_each_segment(bv, req, iter) { + dst = kmap(bv->bv_page) + bv->bv_offset; + for (off = 0; off < bv->bv_len; off += TAPEBLOCK_HSEC_SIZE) { + ccw->flags = CCW_FLAG_CC; + ccw->cmd_code = READ_FORWARD; + ccw->count = TAPEBLOCK_HSEC_SIZE; + set_normalized_cda(ccw, (void*) __pa(dst)); + ccw++; + dst += TAPEBLOCK_HSEC_SIZE; + } + } + + ccw = tape_ccw_end(ccw, NOP, 0, NULL); + DBF_EVENT(6, "xBREDccwg\n"); + return request; +} + +static void +tape_34xx_free_bread (struct tape_request *request) +{ + struct ccw1* ccw; + + ccw = request->cpaddr; + if ((ccw + 2)->cmd_code == READ_BLOCK_ID) { + struct { + struct tape_34xx_block_id cbid; + struct tape_34xx_block_id dbid; + } __attribute__ ((packed)) *rbi_data; + + rbi_data = request->cpdata; + + if (request->device) + tape_34xx_add_sbid(request->device, rbi_data->cbid); + } + + /* Last ccw is a nop and doesn't need clear_normalized_cda */ + for (; ccw->flags & CCW_FLAG_CC; ccw++) + if (ccw->cmd_code == READ_FORWARD) + clear_normalized_cda(ccw); + tape_free_request(request); +} + +/* + * check_locate is called just before the tape request is passed to + * the common io layer for execution. It has to check the current + * tape position and insert a locate ccw if it doesn't match the + * start block for the request. + */ +static void +tape_34xx_check_locate(struct tape_device *device, struct tape_request *request) +{ + struct tape_34xx_block_id * start_block; + + start_block = (struct tape_34xx_block_id *) request->cpdata; + if (start_block->block == device->blk_data.block_position) + return; + + DBF_LH(4, "Block seek(%06d+%06d)\n", start_block->block, device->bof); + start_block->wrap = 0; + start_block->segment = 1; + start_block->format = (*device->modeset_byte & 0x08) ? + TAPE34XX_FMT_3480_XF : + TAPE34XX_FMT_3480; + start_block->block = start_block->block + device->bof; + tape_34xx_merge_sbid(device, start_block); + tape_ccw_cc(request->cpaddr + 1, LOCATE, 4, request->cpdata); + tape_ccw_cc(request->cpaddr + 2, READ_BLOCK_ID, 8, request->cpdata); +} +#endif + /* * List of 3480/3490 magnetic tape commands. */ @@ -1164,6 +1295,11 @@ static struct tape_discipline tape_discipline_34xx = { .irq = tape_34xx_irq, .read_block = tape_std_read_block, .write_block = tape_std_write_block, +#ifdef CONFIG_S390_TAPE_BLOCK + .bread = tape_34xx_bread, + .free_bread = tape_34xx_free_bread, + .check_locate = tape_34xx_check_locate, +#endif .ioctl_fn = tape_34xx_ioctl, .mtop_array = tape_34xx_mtop }; diff --git a/trunk/drivers/s390/char/tape_3590.c b/trunk/drivers/s390/char/tape_3590.c index a5c6614b0db2..49c6aab7ad78 100644 --- a/trunk/drivers/s390/char/tape_3590.c +++ b/trunk/drivers/s390/char/tape_3590.c @@ -670,6 +670,92 @@ tape_3590_schedule_work(struct tape_device *device, enum tape_op op) return 0; } +#ifdef CONFIG_S390_TAPE_BLOCK +/* + * Tape Block READ + */ +static struct tape_request * +tape_3590_bread(struct tape_device *device, struct request *req) +{ + struct tape_request *request; + struct ccw1 *ccw; + int count = 0, start_block; + unsigned off; + char *dst; + struct bio_vec *bv; + struct req_iterator iter; + + DBF_EVENT(6, "xBREDid:"); + start_block = blk_rq_pos(req) >> TAPEBLOCK_HSEC_S2B; + DBF_EVENT(6, "start_block = %i\n", start_block); + + rq_for_each_segment(bv, req, iter) + count += bv->bv_len >> (TAPEBLOCK_HSEC_S2B + 9); + + request = tape_alloc_request(2 + count + 1, 4); + if (IS_ERR(request)) + return request; + request->op = TO_BLOCK; + *(__u32 *) request->cpdata = start_block; + ccw = request->cpaddr; + ccw = tape_ccw_cc(ccw, MODE_SET_DB, 1, device->modeset_byte); + + /* + * We always setup a nop after the mode set ccw. This slot is + * used in tape_std_check_locate to insert a locate ccw if the + * current tape position doesn't match the start block to be read. + */ + ccw = tape_ccw_cc(ccw, NOP, 0, NULL); + + rq_for_each_segment(bv, req, iter) { + dst = page_address(bv->bv_page) + bv->bv_offset; + for (off = 0; off < bv->bv_len; off += TAPEBLOCK_HSEC_SIZE) { + ccw->flags = CCW_FLAG_CC; + ccw->cmd_code = READ_FORWARD; + ccw->count = TAPEBLOCK_HSEC_SIZE; + set_normalized_cda(ccw, (void *) __pa(dst)); + ccw++; + dst += TAPEBLOCK_HSEC_SIZE; + } + BUG_ON(off > bv->bv_len); + } + ccw = tape_ccw_end(ccw, NOP, 0, NULL); + DBF_EVENT(6, "xBREDccwg\n"); + return request; +} + +static void +tape_3590_free_bread(struct tape_request *request) +{ + struct ccw1 *ccw; + + /* Last ccw is a nop and doesn't need clear_normalized_cda */ + for (ccw = request->cpaddr; ccw->flags & CCW_FLAG_CC; ccw++) + if (ccw->cmd_code == READ_FORWARD) + clear_normalized_cda(ccw); + tape_free_request(request); +} + +/* + * check_locate is called just before the tape request is passed to + * the common io layer for execution. It has to check the current + * tape position and insert a locate ccw if it doesn't match the + * start block for the request. + */ +static void +tape_3590_check_locate(struct tape_device *device, struct tape_request *request) +{ + __u32 *start_block; + + start_block = (__u32 *) request->cpdata; + if (*start_block != device->blk_data.block_position) { + /* Add the start offset of the file to get the real block. */ + *start_block += device->bof; + tape_ccw_cc(request->cpaddr + 1, LOCATE, 4, request->cpdata); + } +} +#endif + static void tape_3590_med_state_set(struct tape_device *device, struct tape_3590_med_sense *sense) { @@ -1337,6 +1423,20 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request, { struct tape_3590_sense *sense; +#ifdef CONFIG_S390_TAPE_BLOCK + if (request->op == TO_BLOCK) { + /* + * Recovery for block device requests. Set the block_position + * to something invalid and retry. + */ + device->blk_data.block_position = -1; + if (request->retries-- <= 0) + return tape_3590_erp_failed(device, request, irb, -EIO); + else + return tape_3590_erp_retry(device, request, irb); + } +#endif + sense = (struct tape_3590_sense *) irb->ecw; DBF_EVENT(6, "Unit Check: RQC = %x\n", sense->rc_rqc); @@ -1629,6 +1729,11 @@ static struct tape_discipline tape_discipline_3590 = { .irq = tape_3590_irq, .read_block = tape_std_read_block, .write_block = tape_std_write_block, +#ifdef CONFIG_S390_TAPE_BLOCK + .bread = tape_3590_bread, + .free_bread = tape_3590_free_bread, + .check_locate = tape_3590_check_locate, +#endif .ioctl_fn = tape_3590_ioctl, .mtop_array = tape_3590_mtop }; diff --git a/trunk/drivers/s390/char/tape_char.c b/trunk/drivers/s390/char/tape_char.c index 46886a7578c6..87cd0ab242de 100644 --- a/trunk/drivers/s390/char/tape_char.c +++ b/trunk/drivers/s390/char/tape_char.c @@ -161,6 +161,11 @@ tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos) if (rc) return rc; +#ifdef CONFIG_S390_TAPE_BLOCK + /* Changes position. */ + device->blk_data.medium_changed = 1; +#endif + DBF_EVENT(6, "TCHAR:nbytes: %lx\n", block_size); /* Let the discipline build the ccw chain. */ request = device->discipline->read_block(device, block_size); @@ -213,6 +218,11 @@ tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t if (rc) return rc; +#ifdef CONFIG_S390_TAPE_BLOCK + /* Changes position. */ + device->blk_data.medium_changed = 1; +#endif + DBF_EVENT(6,"TCHAR:nbytes: %lx\n", block_size); DBF_EVENT(6, "TCHAR:nblocks: %x\n", nblocks); /* Let the discipline build the ccw chain. */ @@ -369,6 +379,9 @@ __tapechar_ioctl(struct tape_device *device, case MTBSFM: case MTFSFM: case MTSEEK: +#ifdef CONFIG_S390_TAPE_BLOCK + device->blk_data.medium_changed = 1; +#endif if (device->required_tapemarks) tape_std_terminate_write(device); default: diff --git a/trunk/drivers/s390/char/tape_core.c b/trunk/drivers/s390/char/tape_core.c index 585618663ba4..b3a3e8e8656e 100644 --- a/trunk/drivers/s390/char/tape_core.c +++ b/trunk/drivers/s390/char/tape_core.c @@ -401,6 +401,9 @@ tape_generic_online(struct tape_device *device, rc = tapechar_setup_device(device); if (rc) goto out_minor; + rc = tapeblock_setup_device(device); + if (rc) + goto out_char; tape_state_set(device, TS_UNUSED); @@ -408,6 +411,8 @@ tape_generic_online(struct tape_device *device, return 0; +out_char: + tapechar_cleanup_device(device); out_minor: tape_remove_minor(device); out_discipline: @@ -421,6 +426,7 @@ tape_generic_online(struct tape_device *device, static void tape_cleanup_device(struct tape_device *device) { + tapeblock_cleanup_device(device); tapechar_cleanup_device(device); device->discipline->cleanup_device(device); module_put(device->discipline->owner); @@ -779,6 +785,10 @@ __tape_start_io(struct tape_device *device, struct tape_request *request) { int rc; +#ifdef CONFIG_S390_TAPE_BLOCK + if (request->op == TO_BLOCK) + device->discipline->check_locate(device, request); +#endif rc = ccw_device_start( device->cdev, request->cpaddr, @@ -1243,7 +1253,7 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) } /* - * Tape device open function used by tape_char frontend. + * Tape device open function used by tape_char & tape_block frontends. */ int tape_open(struct tape_device *device) @@ -1273,7 +1283,7 @@ tape_open(struct tape_device *device) } /* - * Tape device release function used by tape_char frontend. + * Tape device release function used by tape_char & tape_block frontends. */ int tape_release(struct tape_device *device) @@ -1334,6 +1344,7 @@ tape_init (void) DBF_EVENT(3, "tape init\n"); tape_proc_init(); tapechar_init (); + tapeblock_init (); return 0; } @@ -1347,6 +1358,7 @@ tape_exit(void) /* Get rid of the frontends */ tapechar_exit(); + tapeblock_exit(); tape_proc_cleanup(); debug_unregister (TAPE_DBF_AREA); } diff --git a/trunk/drivers/s390/cio/ccwgroup.c b/trunk/drivers/s390/cio/ccwgroup.c index 731470e68493..5f1dc6fb5708 100644 --- a/trunk/drivers/s390/cio/ccwgroup.c +++ b/trunk/drivers/s390/cio/ccwgroup.c @@ -1,7 +1,7 @@ /* * bus driver for ccwgroup * - * Copyright IBM Corp. 2002, 2012 + * Copyright IBM Corp. 2002, 2009 * * Author(s): Arnd Bergmann (arndb@de.ibm.com) * Cornelia Huck (cornelia.huck@de.ibm.com) @@ -15,13 +15,10 @@ #include #include -#include #include #include -#include "device.h" - -#define CCW_BUS_ID_SIZE 10 +#define CCW_BUS_ID_SIZE 20 /* In Linux 2.4, we had a channel device layer called "chandev" * that did all sorts of obscure stuff for networking devices. @@ -30,6 +27,19 @@ * to devices that use multiple subchannels. */ +/* a device matches a driver if all its slave devices match the same + * entry of the driver */ +static int ccwgroup_bus_match(struct device *dev, struct device_driver * drv) +{ + struct ccwgroup_device *gdev = to_ccwgroupdev(dev); + struct ccwgroup_driver *gdrv = to_ccwgroupdrv(drv); + + if (gdev->creator_id == gdrv->driver_id) + return 1; + + return 0; +} + static struct bus_type ccwgroup_bus_type; static void __ccwgroup_remove_symlinks(struct ccwgroup_device *gdev) @@ -244,10 +254,9 @@ static int __ccwgroup_create_symlinks(struct ccwgroup_device *gdev) return 0; } -static int __get_next_id(const char **buf, struct ccw_dev_id *id) +static int __get_next_bus_id(const char **buf, char *bus_id) { - unsigned int cssid, ssid, devno; - int ret = 0, len; + int rc, len; char *start, *end; start = (char *)*buf; @@ -262,40 +271,49 @@ static int __get_next_id(const char **buf, struct ccw_dev_id *id) len = end - start + 1; end++; } - if (len <= CCW_BUS_ID_SIZE) { - if (sscanf(start, "%2x.%1x.%04x", &cssid, &ssid, &devno) != 3) - ret = -EINVAL; + if (len < CCW_BUS_ID_SIZE) { + strlcpy(bus_id, start, len); + rc = 0; } else - ret = -EINVAL; - - if (!ret) { - id->ssid = ssid; - id->devno = devno; - } + rc = -EINVAL; *buf = end; - return ret; + return rc; +} + +static int __is_valid_bus_id(char bus_id[CCW_BUS_ID_SIZE]) +{ + int cssid, ssid, devno; + + /* Must be of form %x.%x.%04x */ + if (sscanf(bus_id, "%x.%1x.%04x", &cssid, &ssid, &devno) != 3) + return 0; + return 1; } /** - * ccwgroup_create_dev() - create and register a ccw group device - * @parent: parent device for the new device - * @gdrv: driver for the new group device + * ccwgroup_create_from_string() - create and register a ccw group device + * @root: parent device for the new device + * @creator_id: identifier of creating driver + * @cdrv: ccw driver of slave devices * @num_devices: number of slave devices * @buf: buffer containing comma separated bus ids of slave devices * - * Create and register a new ccw group device as a child of @parent. Slave - * devices are obtained from the list of bus ids given in @buf. + * Create and register a new ccw group device as a child of @root. Slave + * devices are obtained from the list of bus ids given in @buf and must all + * belong to @cdrv. * Returns: * %0 on success and an error code on failure. * Context: * non-atomic */ -int ccwgroup_create_dev(struct device *parent, struct ccwgroup_driver *gdrv, - int num_devices, const char *buf) +int ccwgroup_create_from_string(struct device *root, unsigned int creator_id, + struct ccw_driver *cdrv, int num_devices, + const char *buf) { struct ccwgroup_device *gdev; - struct ccw_dev_id dev_id; int rc, i; + char tmp_bus_id[CCW_BUS_ID_SIZE]; + const char *curr_buf; gdev = kzalloc(sizeof(*gdev) + num_devices * sizeof(gdev->cdev[0]), GFP_KERNEL); @@ -305,24 +323,29 @@ int ccwgroup_create_dev(struct device *parent, struct ccwgroup_driver *gdrv, atomic_set(&gdev->onoff, 0); mutex_init(&gdev->reg_mutex); mutex_lock(&gdev->reg_mutex); + gdev->creator_id = creator_id; gdev->count = num_devices; gdev->dev.bus = &ccwgroup_bus_type; - gdev->dev.parent = parent; + gdev->dev.parent = root; gdev->dev.release = ccwgroup_release; device_initialize(&gdev->dev); - for (i = 0; i < num_devices && buf; i++) { - rc = __get_next_id(&buf, &dev_id); + curr_buf = buf; + for (i = 0; i < num_devices && curr_buf; i++) { + rc = __get_next_bus_id(&curr_buf, tmp_bus_id); if (rc != 0) goto error; - gdev->cdev[i] = get_ccwdev_by_dev_id(&dev_id); + if (!__is_valid_bus_id(tmp_bus_id)) { + rc = -EINVAL; + goto error; + } + gdev->cdev[i] = get_ccwdev_by_busid(cdrv, tmp_bus_id); /* * All devices have to be of the same type in * order to be grouped. */ - if (!gdev->cdev[i] || !gdev->cdev[i]->drv || - gdev->cdev[i]->drv != gdev->cdev[0]->drv || - gdev->cdev[i]->id.driver_info != + if (!gdev->cdev[i] + || gdev->cdev[i]->id.driver_info != gdev->cdev[0]->id.driver_info) { rc = -EINVAL; goto error; @@ -338,25 +361,18 @@ int ccwgroup_create_dev(struct device *parent, struct ccwgroup_driver *gdrv, spin_unlock_irq(gdev->cdev[i]->ccwlock); } /* Check for sufficient number of bus ids. */ - if (i < num_devices) { + if (i < num_devices && !curr_buf) { rc = -EINVAL; goto error; } /* Check for trailing stuff. */ - if (i == num_devices && strlen(buf) > 0) { + if (i == num_devices && strlen(curr_buf) > 0) { rc = -EINVAL; goto error; } dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev)); gdev->dev.groups = ccwgroup_attr_groups; - - if (gdrv) { - gdev->dev.driver = &gdrv->driver; - rc = gdrv->setup ? gdrv->setup(gdev) : 0; - if (rc) - goto error; - } rc = device_add(&gdev->dev); if (rc) goto error; @@ -381,7 +397,7 @@ int ccwgroup_create_dev(struct device *parent, struct ccwgroup_driver *gdrv, put_device(&gdev->dev); return rc; } -EXPORT_SYMBOL(ccwgroup_create_dev); +EXPORT_SYMBOL(ccwgroup_create_from_string); static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action, void *data) @@ -424,6 +440,14 @@ module_exit(cleanup_ccwgroup); /************************** driver stuff ******************************/ +static int ccwgroup_probe(struct device *dev) +{ + struct ccwgroup_device *gdev = to_ccwgroupdev(dev); + struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver); + + return gdrv->probe ? gdrv->probe(gdev) : -ENODEV; +} + static int ccwgroup_remove(struct device *dev) { struct ccwgroup_device *gdev = to_ccwgroupdev(dev); @@ -518,6 +542,8 @@ static const struct dev_pm_ops ccwgroup_pm_ops = { static struct bus_type ccwgroup_bus_type = { .name = "ccwgroup", + .match = ccwgroup_bus_match, + .probe = ccwgroup_probe, .remove = ccwgroup_remove, .shutdown = ccwgroup_shutdown, .pm = &ccwgroup_pm_ops, diff --git a/trunk/drivers/s390/cio/cio.c b/trunk/drivers/s390/cio/cio.c index a6ddaed8793d..a49c46c91983 100644 --- a/trunk/drivers/s390/cio/cio.c +++ b/trunk/drivers/s390/cio/cio.c @@ -656,34 +656,51 @@ static struct io_subchannel_private console_priv; static int console_subchannel_in_use; /* - * Use cio_tsch to update the subchannel status and call the interrupt handler - * if status had been pending. Called with the console_subchannel lock. + * Use cio_tpi to get a pending interrupt and call the interrupt handler. + * Return non-zero if an interrupt was processed, zero otherwise. */ -static void cio_tsch(struct subchannel *sch) +static int cio_tpi(void) { + struct tpi_info *tpi_info; + struct subchannel *sch; struct irb *irb; int irq_context; + tpi_info = (struct tpi_info *)&S390_lowcore.subchannel_id; + if (tpi(NULL) != 1) + return 0; + kstat_cpu(smp_processor_id()).irqs[IO_INTERRUPT]++; + if (tpi_info->adapter_IO) { + do_adapter_IO(tpi_info->isc); + return 1; + } irb = (struct irb *)&S390_lowcore.irb; /* Store interrupt response block to lowcore. */ - if (tsch(sch->schid, irb) != 0) + if (tsch(tpi_info->schid, irb) != 0) { /* Not status pending or not operational. */ - return; - memcpy(&sch->schib.scsw, &irb->scsw, sizeof(union scsw)); - /* Call interrupt handler with updated status. */ + kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; + return 1; + } + sch = (struct subchannel *)(unsigned long)tpi_info->intparm; + if (!sch) { + kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; + return 1; + } irq_context = in_interrupt(); - if (!irq_context) { + if (!irq_context) local_bh_disable(); - irq_enter(); - } + irq_enter(); + spin_lock(sch->lock); + memcpy(&sch->schib.scsw, &irb->scsw, sizeof(union scsw)); if (sch->driver && sch->driver->irq) sch->driver->irq(sch); else kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++; - if (!irq_context) { - irq_exit(); + spin_unlock(sch->lock); + irq_exit(); + if (!irq_context) _local_bh_enable(); - } + return 1; } void *cio_get_console_priv(void) @@ -695,16 +712,34 @@ void *cio_get_console_priv(void) * busy wait for the next interrupt on the console */ void wait_cons_dev(void) + __releases(console_subchannel.lock) + __acquires(console_subchannel.lock) { + unsigned long cr6 __attribute__ ((aligned (8))); + unsigned long save_cr6 __attribute__ ((aligned (8))); + + /* + * before entering the spinlock we may already have + * processed the interrupt on a different CPU... + */ if (!console_subchannel_in_use) return; - while (1) { - cio_tsch(&console_subchannel); - if (console_subchannel.schib.scsw.cmd.actl == 0) - break; - udelay_simple(100); - } + /* disable all but the console isc */ + __ctl_store (save_cr6, 6, 6); + cr6 = 1UL << (31 - CONSOLE_ISC); + __ctl_load (cr6, 6, 6); + + do { + spin_unlock(console_subchannel.lock); + if (!cio_tpi()) + cpu_relax(); + spin_lock(console_subchannel.lock); + } while (console_subchannel.schib.scsw.cmd.actl != 0); + /* + * restore previous isc value + */ + __ctl_load (save_cr6, 6, 6); } static int diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index f8f952d52045..02d015259461 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -695,17 +695,7 @@ static int match_dev_id(struct device *dev, void *data) return ccw_dev_id_is_equal(&cdev->private->dev_id, dev_id); } -/** - * get_ccwdev_by_dev_id() - obtain device from a ccw device id - * @dev_id: id of the device to be searched - * - * This function searches all devices attached to the ccw bus for a device - * matching @dev_id. - * Returns: - * If a device is found its reference count is increased and returned; - * else %NULL is returned. - */ -struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id) +static struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id) { struct device *dev; @@ -713,7 +703,6 @@ struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id) return dev ? to_ccwdev(dev) : NULL; } -EXPORT_SYMBOL_GPL(get_ccwdev_by_dev_id); static void ccw_device_do_unbind_bind(struct ccw_device *cdev) { diff --git a/trunk/drivers/s390/cio/device.h b/trunk/drivers/s390/cio/device.h index 6bace6942396..179824b3082f 100644 --- a/trunk/drivers/s390/cio/device.h +++ b/trunk/drivers/s390/cio/device.h @@ -101,7 +101,6 @@ int ccw_device_test_sense_data(struct ccw_device *); void ccw_device_schedule_sch_unregister(struct ccw_device *); int ccw_purge_blacklisted(void); void ccw_device_sched_todo(struct ccw_device *cdev, enum cdev_todo todo); -struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id); /* Function prototypes for device status and basic sense stuff. */ void ccw_device_accumulate_irb(struct ccw_device *, struct irb *); diff --git a/trunk/drivers/s390/cio/qdio_main.c b/trunk/drivers/s390/cio/qdio_main.c index 7493efafa0d5..35c685c374e9 100644 --- a/trunk/drivers/s390/cio/qdio_main.c +++ b/trunk/drivers/s390/cio/qdio_main.c @@ -63,7 +63,7 @@ static inline int do_siga_input(unsigned long schid, unsigned int mask, " ipm %0\n" " srl %0,28\n" : "=d" (cc) - : "d" (__fc), "d" (__schid), "d" (__mask) : "cc"); + : "d" (__fc), "d" (__schid), "d" (__mask) : "cc", "memory"); return cc; } @@ -74,7 +74,7 @@ static inline int do_siga_input(unsigned long schid, unsigned int mask, * @bb: busy bit indicator, set only if SIGA-w/wt could not access a buffer * @fc: function code to perform * - * Returns condition code. + * Returns cc or QDIO_ERROR_SIGA_ACCESS_EXCEPTION. * Note: For IQDC unicast queues only the highest priority queue is processed. */ static inline int do_siga_output(unsigned long schid, unsigned long mask, @@ -85,16 +85,18 @@ static inline int do_siga_output(unsigned long schid, unsigned long mask, register unsigned long __schid asm("1") = schid; register unsigned long __mask asm("2") = mask; register unsigned long __aob asm("3") = aob; - int cc; + int cc = QDIO_ERROR_SIGA_ACCESS_EXCEPTION; asm volatile( " siga 0\n" - " ipm %0\n" + "0: ipm %0\n" " srl %0,28\n" - : "=d" (cc), "+d" (__fc), "+d" (__aob) - : "d" (__schid), "d" (__mask) - : "cc"); - *bb = __fc >> 31; + "1:\n" + EX_TABLE(0b, 1b) + : "+d" (cc), "+d" (__fc), "+d" (__schid), "+d" (__mask), + "+d" (__aob) + : : "cc", "memory"); + *bb = ((unsigned int) __fc) >> 31; return cc; } @@ -165,7 +167,7 @@ static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state, DBF_ERROR("%4x EQBS ERROR", SCH_NO(q)); DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); - q->handler(q->irq_ptr->cdev, QDIO_ERROR_GET_BUF_STATE, + q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, q->nr, q->first_to_kick, count, q->irq_ptr->int_parm); return 0; } @@ -213,7 +215,7 @@ static int qdio_do_sqbs(struct qdio_q *q, unsigned char state, int start, DBF_ERROR("%4x SQBS ERROR", SCH_NO(q)); DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); - q->handler(q->irq_ptr->cdev, QDIO_ERROR_SET_BUF_STATE, + q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, q->nr, q->first_to_kick, count, q->irq_ptr->int_parm); return 0; } @@ -311,7 +313,7 @@ static inline int qdio_siga_sync(struct qdio_q *q, unsigned int output, cc = do_siga_sync(schid, output, input, fc); if (unlikely(cc)) DBF_ERROR("%4x SIGA-S:%2d", SCH_NO(q), cc); - return (cc) ? -EIO : 0; + return cc; } static inline int qdio_siga_sync_q(struct qdio_q *q) @@ -382,7 +384,7 @@ static inline int qdio_siga_input(struct qdio_q *q) cc = do_siga_input(schid, q->mask, fc); if (unlikely(cc)) DBF_ERROR("%4x SIGA-R:%2d", SCH_NO(q), cc); - return (cc) ? -EIO : 0; + return cc; } #define qdio_siga_sync_out(q) qdio_siga_sync(q, ~0U, 0) @@ -441,7 +443,7 @@ static void process_buffer_error(struct qdio_q *q, int count) unsigned char state = (q->is_input_q) ? SLSB_P_INPUT_NOT_INIT : SLSB_P_OUTPUT_NOT_INIT; - q->qdio_error = QDIO_ERROR_SLSB_STATE; + q->qdio_error |= QDIO_ERROR_SLSB_STATE; /* special handling for no target buffer empty */ if ((!q->is_input_q && @@ -517,7 +519,7 @@ static int get_inbound_buffer_frontier(struct qdio_q *q) int count, stop; unsigned char state = 0; - q->timestamp = get_clock(); + q->timestamp = get_clock_fast(); /* * Don't check 128 buffers, as otherwise qdio_inbound_q_moved @@ -573,7 +575,7 @@ static int qdio_inbound_q_moved(struct qdio_q *q) bufnr = get_inbound_buffer_frontier(q); - if (bufnr != q->last_move) { + if ((bufnr != q->last_move) || q->qdio_error) { q->last_move = bufnr; if (!is_thinint_irq(q->irq_ptr) && MACHINE_IS_LPAR) q->u.in.timestamp = get_clock(); @@ -788,7 +790,7 @@ static int get_outbound_buffer_frontier(struct qdio_q *q) int count, stop; unsigned char state = 0; - q->timestamp = get_clock(); + q->timestamp = get_clock_fast(); if (need_siga_sync(q)) if (((queue_type(q) != QDIO_IQDIO_QFMT) && @@ -861,7 +863,7 @@ static inline int qdio_outbound_q_moved(struct qdio_q *q) bufnr = get_outbound_buffer_frontier(q); - if (bufnr != q->last_move) { + if ((bufnr != q->last_move) || q->qdio_error) { q->last_move = bufnr; DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr); return 1; @@ -892,16 +894,13 @@ static int qdio_kick_outbound_q(struct qdio_q *q, unsigned long aob) goto retry; } DBF_ERROR("%4x cc2 BBC:%1d", SCH_NO(q), q->nr); - cc = -EBUSY; - } else { + cc |= QDIO_ERROR_SIGA_BUSY; + } else DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d", q->nr); - cc = -ENOBUFS; - } break; case 1: case 3: DBF_ERROR("%4x SIGA-W:%1d", SCH_NO(q), cc); - cc = -EIO; break; } if (retries) { @@ -1091,7 +1090,7 @@ static void qdio_handle_activate_check(struct ccw_device *cdev, } count = sub_buf(q->first_to_check, q->first_to_kick); - q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE, + q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, q->nr, q->first_to_kick, count, irq_ptr->int_parm); no_handler: qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED); @@ -1692,7 +1691,7 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags, "do%02x b:%02x c:%02x", callflags, bufnr, count); if (irq_ptr->state != QDIO_IRQ_STATE_ACTIVE) - return -EIO; + return -EBUSY; if (!count) return 0; if (callflags & QDIO_FLAG_SYNC_INPUT) diff --git a/trunk/drivers/s390/crypto/ap_bus.c b/trunk/drivers/s390/crypto/ap_bus.c index b987d4619586..7e9a72eb2fe0 100644 --- a/trunk/drivers/s390/crypto/ap_bus.c +++ b/trunk/drivers/s390/crypto/ap_bus.c @@ -215,7 +215,7 @@ ap_queue_interruption_control(ap_qid_t qid, void *ind) register struct ap_queue_status reg1_out asm ("1"); register void *reg2 asm ("2") = ind; asm volatile( - ".long 0xb2af0000" /* PQAP(AQIC) */ + ".long 0xb2af0000" /* PQAP(RAPQ) */ : "+d" (reg0), "+d" (reg1_in), "=d" (reg1_out), "+d" (reg2) : : "cc" ); @@ -232,7 +232,7 @@ __ap_query_functions(ap_qid_t qid, unsigned int *functions) register unsigned long reg2 asm ("2"); asm volatile( - ".long 0xb2af0000\n" /* PQAP(TAPQ) */ + ".long 0xb2af0000\n" "0:\n" EX_TABLE(0b, 0b) : "+d" (reg0), "+d" (reg1), "=d" (reg2) @@ -391,7 +391,7 @@ __ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length, reg0 |= 0x400000UL; asm volatile ( - "0: .long 0xb2ad0042\n" /* NQAP */ + "0: .long 0xb2ad0042\n" /* DQAP */ " brc 2,0b" : "+d" (reg0), "=d" (reg1), "+d" (reg2), "+d" (reg3) : "d" (reg4), "d" (reg5), "m" (*(msgblock *) msg) @@ -450,7 +450,7 @@ __ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length) asm volatile( - "0: .long 0xb2ae0064\n" /* DQAP */ + "0: .long 0xb2ae0064\n" " brc 6,0b\n" : "+d" (reg0), "=d" (reg1), "+d" (reg2), "+d" (reg4), "+d" (reg5), "+d" (reg6), "+d" (reg7), @@ -836,12 +836,12 @@ static void __ap_flush_queue(struct ap_device *ap_dev) list_for_each_entry_safe(ap_msg, next, &ap_dev->pendingq, list) { list_del_init(&ap_msg->list); ap_dev->pendingq_count--; - ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); + ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); } list_for_each_entry_safe(ap_msg, next, &ap_dev->requestq, list) { list_del_init(&ap_msg->list); ap_dev->requestq_count--; - ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); + ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); } } @@ -1329,7 +1329,7 @@ static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags) continue; list_del_init(&ap_msg->list); ap_dev->pendingq_count--; - ap_msg->receive(ap_dev, ap_msg, ap_dev->reply); + ap_dev->drv->receive(ap_dev, ap_msg, ap_dev->reply); break; } if (ap_dev->queue_count > 0) @@ -1450,10 +1450,10 @@ static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_ms return -EBUSY; case AP_RESPONSE_REQ_FAC_NOT_INST: case AP_RESPONSE_MESSAGE_TOO_BIG: - ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL)); + ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL)); return -EINVAL; default: /* Device is gone. */ - ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); + ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); return -ENODEV; } } else { @@ -1471,10 +1471,6 @@ void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg) unsigned long flags; int rc; - /* For asynchronous message handling a valid receive-callback - * is required. */ - BUG_ON(!ap_msg->receive); - spin_lock_bh(&ap_dev->lock); if (!ap_dev->unregistered) { /* Make room on the queue by polling for finished requests. */ @@ -1486,7 +1482,7 @@ void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg) if (rc == -ENODEV) ap_dev->unregistered = 1; } else { - ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); + ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); rc = -ENODEV; } spin_unlock_bh(&ap_dev->lock); diff --git a/trunk/drivers/s390/crypto/ap_bus.h b/trunk/drivers/s390/crypto/ap_bus.h index 726fc65809d8..d960a6309eec 100644 --- a/trunk/drivers/s390/crypto/ap_bus.h +++ b/trunk/drivers/s390/crypto/ap_bus.h @@ -136,6 +136,9 @@ struct ap_driver { int (*probe)(struct ap_device *); void (*remove)(struct ap_device *); + /* receive is called from tasklet context */ + void (*receive)(struct ap_device *, struct ap_message *, + struct ap_message *); int request_timeout; /* request timeout in jiffies */ }; @@ -180,9 +183,6 @@ struct ap_message { void *private; /* ap driver private pointer. */ unsigned int special:1; /* Used for special commands. */ - /* receive is called from tasklet context */ - void (*receive)(struct ap_device *, struct ap_message *, - struct ap_message *); }; #define AP_DEVICE(dt) \ @@ -199,7 +199,6 @@ static inline void ap_init_message(struct ap_message *ap_msg) ap_msg->psmid = 0; ap_msg->length = 0; ap_msg->special = 0; - ap_msg->receive = NULL; } /* diff --git a/trunk/drivers/s390/crypto/zcrypt_cex2a.c b/trunk/drivers/s390/crypto/zcrypt_cex2a.c index 46812440425a..084286728166 100644 --- a/trunk/drivers/s390/crypto/zcrypt_cex2a.c +++ b/trunk/drivers/s390/crypto/zcrypt_cex2a.c @@ -77,6 +77,7 @@ static void zcrypt_cex2a_receive(struct ap_device *, struct ap_message *, static struct ap_driver zcrypt_cex2a_driver = { .probe = zcrypt_cex2a_probe, .remove = zcrypt_cex2a_remove, + .receive = zcrypt_cex2a_receive, .ids = zcrypt_cex2a_ids, .request_timeout = CEX2A_CLEANUP_TIME, }; @@ -348,7 +349,6 @@ static long zcrypt_cex2a_modexpo(struct zcrypt_device *zdev, ap_msg.message = kmalloc(CEX3A_MAX_MESSAGE_SIZE, GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; - ap_msg.receive = zcrypt_cex2a_receive; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); ap_msg.private = &work; @@ -390,7 +390,6 @@ static long zcrypt_cex2a_modexpo_crt(struct zcrypt_device *zdev, ap_msg.message = kmalloc(CEX3A_MAX_MESSAGE_SIZE, GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; - ap_msg.receive = zcrypt_cex2a_receive; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); ap_msg.private = &work; diff --git a/trunk/drivers/s390/crypto/zcrypt_pcica.c b/trunk/drivers/s390/crypto/zcrypt_pcica.c index ad7951c21b79..0effca925451 100644 --- a/trunk/drivers/s390/crypto/zcrypt_pcica.c +++ b/trunk/drivers/s390/crypto/zcrypt_pcica.c @@ -67,6 +67,7 @@ static void zcrypt_pcica_receive(struct ap_device *, struct ap_message *, static struct ap_driver zcrypt_pcica_driver = { .probe = zcrypt_pcica_probe, .remove = zcrypt_pcica_remove, + .receive = zcrypt_pcica_receive, .ids = zcrypt_pcica_ids, .request_timeout = PCICA_CLEANUP_TIME, }; @@ -283,7 +284,6 @@ static long zcrypt_pcica_modexpo(struct zcrypt_device *zdev, ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; - ap_msg.receive = zcrypt_pcica_receive; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); ap_msg.private = &work; @@ -322,7 +322,6 @@ static long zcrypt_pcica_modexpo_crt(struct zcrypt_device *zdev, ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; - ap_msg.receive = zcrypt_pcica_receive; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); ap_msg.private = &work; diff --git a/trunk/drivers/s390/crypto/zcrypt_pcicc.c b/trunk/drivers/s390/crypto/zcrypt_pcicc.c index e5dd335fda53..f9523c0cc8d2 100644 --- a/trunk/drivers/s390/crypto/zcrypt_pcicc.c +++ b/trunk/drivers/s390/crypto/zcrypt_pcicc.c @@ -79,6 +79,7 @@ static void zcrypt_pcicc_receive(struct ap_device *, struct ap_message *, static struct ap_driver zcrypt_pcicc_driver = { .probe = zcrypt_pcicc_probe, .remove = zcrypt_pcicc_remove, + .receive = zcrypt_pcicc_receive, .ids = zcrypt_pcicc_ids, .request_timeout = PCICC_CLEANUP_TIME, }; @@ -487,7 +488,6 @@ static long zcrypt_pcicc_modexpo(struct zcrypt_device *zdev, ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; - ap_msg.receive = zcrypt_pcicc_receive; ap_msg.length = PAGE_SIZE; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); @@ -527,7 +527,6 @@ static long zcrypt_pcicc_modexpo_crt(struct zcrypt_device *zdev, ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; - ap_msg.receive = zcrypt_pcicc_receive; ap_msg.length = PAGE_SIZE; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); diff --git a/trunk/drivers/s390/crypto/zcrypt_pcixcc.c b/trunk/drivers/s390/crypto/zcrypt_pcixcc.c index f7cc43401816..cf1cbd4747f4 100644 --- a/trunk/drivers/s390/crypto/zcrypt_pcixcc.c +++ b/trunk/drivers/s390/crypto/zcrypt_pcixcc.c @@ -89,6 +89,7 @@ static void zcrypt_pcixcc_receive(struct ap_device *, struct ap_message *, static struct ap_driver zcrypt_pcixcc_driver = { .probe = zcrypt_pcixcc_probe, .remove = zcrypt_pcixcc_remove, + .receive = zcrypt_pcixcc_receive, .ids = zcrypt_pcixcc_ids, .request_timeout = PCIXCC_CLEANUP_TIME, }; @@ -697,7 +698,6 @@ static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev, ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; - ap_msg.receive = zcrypt_pcixcc_receive; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); ap_msg.private = &resp_type; @@ -738,7 +738,6 @@ static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev, ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; - ap_msg.receive = zcrypt_pcixcc_receive; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); ap_msg.private = &resp_type; @@ -779,7 +778,6 @@ static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev, ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; - ap_msg.receive = zcrypt_pcixcc_receive; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); ap_msg.private = &resp_type; @@ -820,7 +818,6 @@ static long zcrypt_pcixcc_rng(struct zcrypt_device *zdev, ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; - ap_msg.receive = zcrypt_pcixcc_receive; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); ap_msg.private = &resp_type; diff --git a/trunk/drivers/s390/net/Kconfig b/trunk/drivers/s390/net/Kconfig index dfda748c4000..9b66d2d1809b 100644 --- a/trunk/drivers/s390/net/Kconfig +++ b/trunk/drivers/s390/net/Kconfig @@ -4,10 +4,11 @@ menu "S/390 network device drivers" config LCS def_tristate m prompt "Lan Channel Station Interface" - depends on CCW && NETDEVICES && (ETHERNET || FDDI) + depends on CCW && NETDEVICES && (ETHERNET || TR || FDDI) help Select this option if you want to use LCS networking on IBM System z. - This device driver supports FDDI (IEEE 802.7) and Ethernet. + This device driver supports Token Ring (IEEE 802.5), + FDDI (IEEE 802.7) and Ethernet. To compile as a module, choose M. The module name is lcs. If you do not know what it is, it's safe to choose Y. diff --git a/trunk/drivers/s390/net/claw.c b/trunk/drivers/s390/net/claw.c index 6b1ff90d2f00..b41fae37d3af 100644 --- a/trunk/drivers/s390/net/claw.c +++ b/trunk/drivers/s390/net/claw.c @@ -136,6 +136,7 @@ static inline void claw_set_busy(struct net_device *dev) { ((struct claw_privbk *)dev->ml_priv)->tbusy = 1; + eieio(); } static inline void @@ -143,11 +144,13 @@ claw_clear_busy(struct net_device *dev) { clear_bit(0, &(((struct claw_privbk *) dev->ml_priv)->tbusy)); netif_wake_queue(dev); + eieio(); } static inline int claw_check_busy(struct net_device *dev) { + eieio(); return ((struct claw_privbk *) dev->ml_priv)->tbusy; } @@ -230,6 +233,8 @@ static ssize_t claw_rbuff_show(struct device *dev, static ssize_t claw_rbuff_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +static int claw_add_files(struct device *dev); +static void claw_remove_files(struct device *dev); /* Functions for System Validate */ static int claw_process_control( struct net_device *dev, struct ccwbk * p_ccw); @@ -262,10 +267,12 @@ static struct ccwgroup_driver claw_group_driver = { .owner = THIS_MODULE, .name = "claw", }, - .setup = claw_probe, - .remove = claw_remove_device, - .set_online = claw_new_device, - .set_offline = claw_shutdown_device, + .max_slaves = 2, + .driver_id = 0xC3D3C1E6, + .probe = claw_probe, + .remove = claw_remove_device, + .set_online = claw_new_device, + .set_offline = claw_shutdown_device, .prepare = claw_pm_prepare, }; @@ -286,24 +293,30 @@ static struct ccw_driver claw_ccw_driver = { .int_class = IOINT_CLW, }; -static ssize_t claw_driver_group_store(struct device_driver *ddrv, - const char *buf, size_t count) +static ssize_t +claw_driver_group_store(struct device_driver *ddrv, const char *buf, + size_t count) { int err; - err = ccwgroup_create_dev(claw_root_dev, &claw_group_driver, 2, buf); + err = ccwgroup_create_from_string(claw_root_dev, + claw_group_driver.driver_id, + &claw_ccw_driver, 2, buf); return err ? err : count; } + static DRIVER_ATTR(group, 0200, NULL, claw_driver_group_store); -static struct attribute *claw_drv_attrs[] = { +static struct attribute *claw_group_attrs[] = { &driver_attr_group.attr, NULL, }; -static struct attribute_group claw_drv_attr_group = { - .attrs = claw_drv_attrs, + +static struct attribute_group claw_group_attr_group = { + .attrs = claw_group_attrs, }; -static const struct attribute_group *claw_drv_attr_groups[] = { - &claw_drv_attr_group, + +static const struct attribute_group *claw_group_attr_groups[] = { + &claw_group_attr_group, NULL, }; @@ -311,6 +324,60 @@ static const struct attribute_group *claw_drv_attr_groups[] = { * Key functions */ +/*----------------------------------------------------------------* + * claw_probe * + * this function is called for each CLAW device. * + *----------------------------------------------------------------*/ +static int +claw_probe(struct ccwgroup_device *cgdev) +{ + int rc; + struct claw_privbk *privptr=NULL; + + CLAW_DBF_TEXT(2, setup, "probe"); + if (!get_device(&cgdev->dev)) + return -ENODEV; + privptr = kzalloc(sizeof(struct claw_privbk), GFP_KERNEL); + dev_set_drvdata(&cgdev->dev, privptr); + if (privptr == NULL) { + probe_error(cgdev); + put_device(&cgdev->dev); + CLAW_DBF_TEXT_(2, setup, "probex%d", -ENOMEM); + return -ENOMEM; + } + privptr->p_mtc_envelope= kzalloc( MAX_ENVELOPE_SIZE, GFP_KERNEL); + privptr->p_env = kzalloc(sizeof(struct claw_env), GFP_KERNEL); + if ((privptr->p_mtc_envelope==NULL) || (privptr->p_env==NULL)) { + probe_error(cgdev); + put_device(&cgdev->dev); + CLAW_DBF_TEXT_(2, setup, "probex%d", -ENOMEM); + return -ENOMEM; + } + memcpy(privptr->p_env->adapter_name,WS_NAME_NOT_DEF,8); + memcpy(privptr->p_env->host_name,WS_NAME_NOT_DEF,8); + memcpy(privptr->p_env->api_type,WS_NAME_NOT_DEF,8); + privptr->p_env->packing = 0; + privptr->p_env->write_buffers = 5; + privptr->p_env->read_buffers = 5; + privptr->p_env->read_size = CLAW_FRAME_SIZE; + privptr->p_env->write_size = CLAW_FRAME_SIZE; + rc = claw_add_files(&cgdev->dev); + if (rc) { + probe_error(cgdev); + put_device(&cgdev->dev); + dev_err(&cgdev->dev, "Creating the /proc files for a new" + " CLAW device failed\n"); + CLAW_DBF_TEXT_(2, setup, "probex%d", rc); + return rc; + } + privptr->p_env->p_priv = privptr; + cgdev->cdev[0]->handler = claw_irq_handler; + cgdev->cdev[1]->handler = claw_irq_handler; + CLAW_DBF_TEXT(2, setup, "prbext 0"); + + return 0; +} /* end of claw_probe */ + /*-------------------------------------------------------------------* * claw_tx * *-------------------------------------------------------------------*/ @@ -3026,6 +3093,7 @@ claw_remove_device(struct ccwgroup_device *cgdev) dev_info(&cgdev->dev, " will be removed.\n"); if (cgdev->state == CCWGROUP_ONLINE) claw_shutdown_device(cgdev); + claw_remove_files(&cgdev->dev); kfree(priv->p_mtc_envelope); priv->p_mtc_envelope=NULL; kfree(priv->p_env); @@ -3253,6 +3321,7 @@ claw_rbuff_write(struct device *dev, struct device_attribute *attr, CLAW_DBF_TEXT_(2, setup, "RB=%d", p_env->read_buffers); return count; } + static DEVICE_ATTR(read_buffer, 0644, claw_rbuff_show, claw_rbuff_write); static struct attribute *claw_attr[] = { @@ -3263,73 +3332,40 @@ static struct attribute *claw_attr[] = { &dev_attr_host_name.attr, NULL, }; + static struct attribute_group claw_attr_group = { .attrs = claw_attr, }; -static const struct attribute_group *claw_attr_groups[] = { - &claw_attr_group, - NULL, -}; -static const struct device_type claw_devtype = { - .name = "claw", - .groups = claw_attr_groups, -}; -/*----------------------------------------------------------------* - * claw_probe * - * this function is called for each CLAW device. * - *----------------------------------------------------------------*/ -static int claw_probe(struct ccwgroup_device *cgdev) +static int +claw_add_files(struct device *dev) { - struct claw_privbk *privptr = NULL; - - CLAW_DBF_TEXT(2, setup, "probe"); - if (!get_device(&cgdev->dev)) - return -ENODEV; - privptr = kzalloc(sizeof(struct claw_privbk), GFP_KERNEL); - dev_set_drvdata(&cgdev->dev, privptr); - if (privptr == NULL) { - probe_error(cgdev); - put_device(&cgdev->dev); - CLAW_DBF_TEXT_(2, setup, "probex%d", -ENOMEM); - return -ENOMEM; - } - privptr->p_mtc_envelope = kzalloc(MAX_ENVELOPE_SIZE, GFP_KERNEL); - privptr->p_env = kzalloc(sizeof(struct claw_env), GFP_KERNEL); - if ((privptr->p_mtc_envelope == NULL) || (privptr->p_env == NULL)) { - probe_error(cgdev); - put_device(&cgdev->dev); - CLAW_DBF_TEXT_(2, setup, "probex%d", -ENOMEM); - return -ENOMEM; - } - memcpy(privptr->p_env->adapter_name, WS_NAME_NOT_DEF, 8); - memcpy(privptr->p_env->host_name, WS_NAME_NOT_DEF, 8); - memcpy(privptr->p_env->api_type, WS_NAME_NOT_DEF, 8); - privptr->p_env->packing = 0; - privptr->p_env->write_buffers = 5; - privptr->p_env->read_buffers = 5; - privptr->p_env->read_size = CLAW_FRAME_SIZE; - privptr->p_env->write_size = CLAW_FRAME_SIZE; - privptr->p_env->p_priv = privptr; - cgdev->cdev[0]->handler = claw_irq_handler; - cgdev->cdev[1]->handler = claw_irq_handler; - cgdev->dev.type = &claw_devtype; - CLAW_DBF_TEXT(2, setup, "prbext 0"); + CLAW_DBF_TEXT(2, setup, "add_file"); + return sysfs_create_group(&dev->kobj, &claw_attr_group); +} - return 0; -} /* end of claw_probe */ +static void +claw_remove_files(struct device *dev) +{ + CLAW_DBF_TEXT(2, setup, "rem_file"); + sysfs_remove_group(&dev->kobj, &claw_attr_group); +} /*--------------------------------------------------------------------* * claw_init and cleanup * *---------------------------------------------------------------------*/ -static void __exit claw_cleanup(void) +static void __exit +claw_cleanup(void) { + driver_remove_file(&claw_group_driver.driver, + &driver_attr_group); ccwgroup_driver_unregister(&claw_group_driver); ccw_driver_unregister(&claw_ccw_driver); root_device_unregister(claw_root_dev); claw_unregister_debug_facility(); pr_info("Driver unloaded\n"); + } /** @@ -3338,7 +3374,8 @@ static void __exit claw_cleanup(void) * * @return 0 on success, !0 on error. */ -static int __init claw_init(void) +static int __init +claw_init(void) { int ret = 0; @@ -3357,7 +3394,7 @@ static int __init claw_init(void) ret = ccw_driver_register(&claw_ccw_driver); if (ret) goto ccw_err; - claw_group_driver.driver.groups = claw_drv_attr_groups; + claw_group_driver.driver.groups = claw_group_attr_groups; ret = ccwgroup_driver_register(&claw_group_driver); if (ret) goto ccwgroup_err; diff --git a/trunk/drivers/s390/net/ctcm_main.c b/trunk/drivers/s390/net/ctcm_main.c index 3cd25544a27a..11f3b071f305 100644 --- a/trunk/drivers/s390/net/ctcm_main.c +++ b/trunk/drivers/s390/net/ctcm_main.c @@ -1296,11 +1296,6 @@ static void ctcm_irq_handler(struct ccw_device *cdev, } -static const struct device_type ctcm_devtype = { - .name = "ctcm", - .groups = ctcm_attr_groups, -}; - /** * Add ctcm specific attributes. * Add ctcm private data. @@ -1312,6 +1307,7 @@ static const struct device_type ctcm_devtype = { static int ctcm_probe_device(struct ccwgroup_device *cgdev) { struct ctcm_priv *priv; + int rc; CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, "%s %p", @@ -1328,11 +1324,17 @@ static int ctcm_probe_device(struct ccwgroup_device *cgdev) put_device(&cgdev->dev); return -ENOMEM; } + + rc = ctcm_add_files(&cgdev->dev); + if (rc) { + kfree(priv); + put_device(&cgdev->dev); + return rc; + } priv->buffer_size = CTCM_BUFSIZE_DEFAULT; cgdev->cdev[0]->handler = ctcm_irq_handler; cgdev->cdev[1]->handler = ctcm_irq_handler; dev_set_drvdata(&cgdev->dev, priv); - cgdev->dev.type = &ctcm_devtype; return 0; } @@ -1609,6 +1611,11 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev) goto out_dev; } + if (ctcm_add_attributes(&cgdev->dev)) { + result = -ENODEV; + goto out_unregister; + } + strlcpy(priv->fsm->name, dev->name, sizeof(priv->fsm->name)); dev_info(&dev->dev, @@ -1622,6 +1629,8 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev) priv->channel[CTCM_WRITE]->id, priv->protocol); return 0; +out_unregister: + unregister_netdev(dev); out_dev: ctcm_free_netdevice(dev); out_ccw2: @@ -1660,6 +1669,7 @@ static int ctcm_shutdown_device(struct ccwgroup_device *cgdev) /* Close the device */ ctcm_close(dev); dev->flags &= ~IFF_RUNNING; + ctcm_remove_attributes(&cgdev->dev); channel_free(priv->channel[CTCM_READ]); } else dev = NULL; @@ -1701,6 +1711,7 @@ static void ctcm_remove_device(struct ccwgroup_device *cgdev) if (cgdev->state == CCWGROUP_ONLINE) ctcm_shutdown_device(cgdev); + ctcm_remove_files(&cgdev->dev); dev_set_drvdata(&cgdev->dev, NULL); kfree(priv); put_device(&cgdev->dev); @@ -1767,7 +1778,9 @@ static struct ccwgroup_driver ctcm_group_driver = { .owner = THIS_MODULE, .name = CTC_DRIVER_NAME, }, - .setup = ctcm_probe_device, + .max_slaves = 2, + .driver_id = 0xC3E3C3D4, /* CTCM */ + .probe = ctcm_probe_device, .remove = ctcm_remove_device, .set_online = ctcm_new_device, .set_offline = ctcm_shutdown_device, @@ -1776,25 +1789,31 @@ static struct ccwgroup_driver ctcm_group_driver = { .restore = ctcm_pm_resume, }; -static ssize_t ctcm_driver_group_store(struct device_driver *ddrv, - const char *buf, size_t count) +static ssize_t +ctcm_driver_group_store(struct device_driver *ddrv, const char *buf, + size_t count) { int err; - err = ccwgroup_create_dev(ctcm_root_dev, &ctcm_group_driver, 2, buf); + err = ccwgroup_create_from_string(ctcm_root_dev, + ctcm_group_driver.driver_id, + &ctcm_ccw_driver, 2, buf); return err ? err : count; } + static DRIVER_ATTR(group, 0200, NULL, ctcm_driver_group_store); -static struct attribute *ctcm_drv_attrs[] = { +static struct attribute *ctcm_group_attrs[] = { &driver_attr_group.attr, NULL, }; -static struct attribute_group ctcm_drv_attr_group = { - .attrs = ctcm_drv_attrs, + +static struct attribute_group ctcm_group_attr_group = { + .attrs = ctcm_group_attrs, }; -static const struct attribute_group *ctcm_drv_attr_groups[] = { - &ctcm_drv_attr_group, + +static const struct attribute_group *ctcm_group_attr_groups[] = { + &ctcm_group_attr_group, NULL, }; @@ -1810,6 +1829,7 @@ static const struct attribute_group *ctcm_drv_attr_groups[] = { */ static void __exit ctcm_exit(void) { + driver_remove_file(&ctcm_group_driver.driver, &driver_attr_group); ccwgroup_driver_unregister(&ctcm_group_driver); ccw_driver_unregister(&ctcm_ccw_driver); root_device_unregister(ctcm_root_dev); @@ -1847,7 +1867,7 @@ static int __init ctcm_init(void) ret = ccw_driver_register(&ctcm_ccw_driver); if (ret) goto ccw_err; - ctcm_group_driver.driver.groups = ctcm_drv_attr_groups; + ctcm_group_driver.driver.groups = ctcm_group_attr_groups; ret = ccwgroup_driver_register(&ctcm_group_driver); if (ret) goto ccwgroup_err; diff --git a/trunk/drivers/s390/net/ctcm_main.h b/trunk/drivers/s390/net/ctcm_main.h index b9056a55d995..24d5215eb0c4 100644 --- a/trunk/drivers/s390/net/ctcm_main.h +++ b/trunk/drivers/s390/net/ctcm_main.h @@ -225,7 +225,13 @@ struct ctcm_priv { int ctcm_open(struct net_device *dev); int ctcm_close(struct net_device *dev); -extern const struct attribute_group *ctcm_attr_groups[]; +/* + * prototypes for non-static sysfs functions + */ +int ctcm_add_attributes(struct device *dev); +void ctcm_remove_attributes(struct device *dev); +int ctcm_add_files(struct device *dev); +void ctcm_remove_files(struct device *dev); /* * Compatibility macros for busy handling diff --git a/trunk/drivers/s390/net/ctcm_sysfs.c b/trunk/drivers/s390/net/ctcm_sysfs.c index 0c27ae726475..650aec1839e9 100644 --- a/trunk/drivers/s390/net/ctcm_sysfs.c +++ b/trunk/drivers/s390/net/ctcm_sysfs.c @@ -13,7 +13,6 @@ #define KMSG_COMPONENT "ctcm" #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt -#include #include #include #include "ctcm_main.h" @@ -109,12 +108,10 @@ static void ctcm_print_statistics(struct ctcm_priv *priv) } static ssize_t stats_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, char *buf) { - struct ccwgroup_device *gdev = to_ccwgroupdev(dev); struct ctcm_priv *priv = dev_get_drvdata(dev); - - if (!priv || gdev->state != CCWGROUP_ONLINE) + if (!priv) return -ENODEV; ctcm_print_statistics(priv); return sprintf(buf, "0\n"); @@ -193,14 +190,34 @@ static struct attribute *ctcm_attr[] = { &dev_attr_protocol.attr, &dev_attr_type.attr, &dev_attr_buffer.attr, - &dev_attr_stats.attr, NULL, }; static struct attribute_group ctcm_attr_group = { .attrs = ctcm_attr, }; -const struct attribute_group *ctcm_attr_groups[] = { - &ctcm_attr_group, - NULL, -}; + +int ctcm_add_attributes(struct device *dev) +{ + int rc; + + rc = device_create_file(dev, &dev_attr_stats); + + return rc; +} + +void ctcm_remove_attributes(struct device *dev) +{ + device_remove_file(dev, &dev_attr_stats); +} + +int ctcm_add_files(struct device *dev) +{ + return sysfs_create_group(&dev->kobj, &ctcm_attr_group); +} + +void ctcm_remove_files(struct device *dev) +{ + sysfs_remove_group(&dev->kobj, &ctcm_attr_group); +} + diff --git a/trunk/drivers/s390/net/lcs.c b/trunk/drivers/s390/net/lcs.c index a3adf4b1c60d..687efe4d589a 100644 --- a/trunk/drivers/s390/net/lcs.c +++ b/trunk/drivers/s390/net/lcs.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -49,7 +50,8 @@ #include "lcs.h" -#if !defined(CONFIG_ETHERNET) && !defined(CONFIG_FDDI) +#if !defined(CONFIG_ETHERNET) && \ + !defined(CONFIG_TR) && !defined(CONFIG_FDDI) #error Cannot compile lcs.c without some net devices switched on. #endif @@ -1164,7 +1166,10 @@ static void lcs_get_mac_for_ipm(__be32 ipm, char *mac, struct net_device *dev) { LCS_DBF_TEXT(4,trace, "getmac"); - ip_eth_mc_map(ipm, mac); + if (dev->type == ARPHRD_IEEE802_TR) + ip_tr_mc_map(ipm, mac); + else + ip_eth_mc_map(ipm, mac); } /** @@ -1636,6 +1641,12 @@ lcs_startlan_auto(struct lcs_card *card) return 0; #endif +#ifdef CONFIG_TR + card->lan_type = LCS_FRAME_TYPE_TR; + rc = lcs_send_startlan(card, LCS_INITIATOR_TCPIP); + if (rc == 0) + return 0; +#endif #ifdef CONFIG_FDDI card->lan_type = LCS_FRAME_TYPE_FDDI; rc = lcs_send_startlan(card, LCS_INITIATOR_TCPIP); @@ -2040,17 +2051,10 @@ static struct attribute * lcs_attrs[] = { &dev_attr_recover.attr, NULL, }; + static struct attribute_group lcs_attr_group = { .attrs = lcs_attrs, }; -static const struct attribute_group *lcs_attr_groups[] = { - &lcs_attr_group, - NULL, -}; -static const struct device_type lcs_devtype = { - .name = "lcs", - .groups = lcs_attr_groups, -}; /** * lcs_probe_device is called on establishing a new ccwgroup_device. @@ -2059,6 +2063,7 @@ static int lcs_probe_device(struct ccwgroup_device *ccwgdev) { struct lcs_card *card; + int ret; if (!get_device(&ccwgdev->dev)) return -ENODEV; @@ -2070,6 +2075,12 @@ lcs_probe_device(struct ccwgroup_device *ccwgdev) put_device(&ccwgdev->dev); return -ENOMEM; } + ret = sysfs_create_group(&ccwgdev->dev.kobj, &lcs_attr_group); + if (ret) { + lcs_free_card(card); + put_device(&ccwgdev->dev); + return ret; + } dev_set_drvdata(&ccwgdev->dev, card); ccwgdev->cdev[0]->handler = lcs_irq; ccwgdev->cdev[1]->handler = lcs_irq; @@ -2078,9 +2089,7 @@ lcs_probe_device(struct ccwgroup_device *ccwgdev) card->thread_start_mask = 0; card->thread_allowed_mask = 0; card->thread_running_mask = 0; - ccwgdev->dev.type = &lcs_devtype; - - return 0; + return 0; } static int @@ -2163,6 +2172,12 @@ lcs_new_device(struct ccwgroup_device *ccwgdev) dev = alloc_etherdev(0); break; #endif +#ifdef CONFIG_TR + case LCS_FRAME_TYPE_TR: + card->lan_type_trans = tr_type_trans; + dev = alloc_trdev(0); + break; +#endif #ifdef CONFIG_FDDI case LCS_FRAME_TYPE_FDDI: card->lan_type_trans = fddi_type_trans; @@ -2308,9 +2323,9 @@ lcs_remove_device(struct ccwgroup_device *ccwgdev) } if (card->dev) unregister_netdev(card->dev); + sysfs_remove_group(&ccwgdev->dev.kobj, &lcs_attr_group); lcs_cleanup_card(card); lcs_free_card(card); - dev_set_drvdata(&ccwgdev->dev, NULL); put_device(&ccwgdev->dev); } @@ -2395,7 +2410,9 @@ static struct ccwgroup_driver lcs_group_driver = { .owner = THIS_MODULE, .name = "lcs", }, - .setup = lcs_probe_device, + .max_slaves = 2, + .driver_id = 0xD3C3E2, + .probe = lcs_probe_device, .remove = lcs_remove_device, .set_online = lcs_new_device, .set_offline = lcs_shutdown_device, @@ -2406,24 +2423,30 @@ static struct ccwgroup_driver lcs_group_driver = { .restore = lcs_restore, }; -static ssize_t lcs_driver_group_store(struct device_driver *ddrv, - const char *buf, size_t count) +static ssize_t +lcs_driver_group_store(struct device_driver *ddrv, const char *buf, + size_t count) { int err; - err = ccwgroup_create_dev(lcs_root_dev, &lcs_group_driver, 2, buf); + err = ccwgroup_create_from_string(lcs_root_dev, + lcs_group_driver.driver_id, + &lcs_ccw_driver, 2, buf); return err ? err : count; } + static DRIVER_ATTR(group, 0200, NULL, lcs_driver_group_store); -static struct attribute *lcs_drv_attrs[] = { +static struct attribute *lcs_group_attrs[] = { &driver_attr_group.attr, NULL, }; -static struct attribute_group lcs_drv_attr_group = { - .attrs = lcs_drv_attrs, + +static struct attribute_group lcs_group_attr_group = { + .attrs = lcs_group_attrs, }; -static const struct attribute_group *lcs_drv_attr_groups[] = { - &lcs_drv_attr_group, + +static const struct attribute_group *lcs_group_attr_groups[] = { + &lcs_group_attr_group, NULL, }; @@ -2447,7 +2470,7 @@ __init lcs_init_module(void) rc = ccw_driver_register(&lcs_ccw_driver); if (rc) goto ccw_err; - lcs_group_driver.driver.groups = lcs_drv_attr_groups; + lcs_group_driver.driver.groups = lcs_group_attr_groups; rc = ccwgroup_driver_register(&lcs_group_driver); if (rc) goto ccwgroup_err; @@ -2473,6 +2496,8 @@ __exit lcs_cleanup_module(void) { pr_info("Terminating lcs module.\n"); LCS_DBF_TEXT(0, trace, "cleanup"); + driver_remove_file(&lcs_group_driver.driver, + &driver_attr_group); ccwgroup_driver_unregister(&lcs_group_driver); ccw_driver_unregister(&lcs_ccw_driver); root_device_unregister(lcs_root_dev); diff --git a/trunk/drivers/s390/net/qeth_core.h b/trunk/drivers/s390/net/qeth_core.h index 06e8f31ff3dc..ec7921b5138e 100644 --- a/trunk/drivers/s390/net/qeth_core.h +++ b/trunk/drivers/s390/net/qeth_core.h @@ -13,6 +13,8 @@ #include #include +#include +#include #include #include #include @@ -674,6 +676,8 @@ struct qeth_card_options { struct qeth_ipa_info adp; /*Adapter parameters*/ struct qeth_routing_info route6; struct qeth_ipa_info ipa6; + int broadcast_mode; + int macaddr_mode; int fake_broadcast; int add_hhlen; int layer2; @@ -707,16 +711,7 @@ struct qeth_discipline { qdio_handler_t *input_handler; qdio_handler_t *output_handler; int (*recover)(void *ptr); - int (*setup) (struct ccwgroup_device *); - void (*remove) (struct ccwgroup_device *); - int (*set_online) (struct ccwgroup_device *); - int (*set_offline) (struct ccwgroup_device *); - void (*shutdown)(struct ccwgroup_device *); - int (*prepare) (struct ccwgroup_device *); - void (*complete) (struct ccwgroup_device *); - int (*freeze)(struct ccwgroup_device *); - int (*thaw) (struct ccwgroup_device *); - int (*restore)(struct ccwgroup_device *); + struct ccwgroup_driver *ccwgdriver; }; struct qeth_vlan_vid { @@ -780,7 +775,7 @@ struct qeth_card { struct qeth_perf_stats perf_stats; int read_or_write_problem; struct qeth_osn_info osn_info; - struct qeth_discipline *discipline; + struct qeth_discipline discipline; atomic_t force_alloc_skb; struct service_level qeth_service_level; struct qdio_ssqd_desc ssqd; @@ -846,15 +841,16 @@ static inline int qeth_is_diagass_supported(struct qeth_card *card, return card->info.diagass_support & (__u32)cmd; } -extern struct qeth_discipline qeth_l2_discipline; -extern struct qeth_discipline qeth_l3_discipline; -extern const struct attribute_group *qeth_generic_attr_groups[]; -extern const struct attribute_group *qeth_osn_attr_groups[]; - +extern struct ccwgroup_driver qeth_l2_ccwgroup_driver; +extern struct ccwgroup_driver qeth_l3_ccwgroup_driver; const char *qeth_get_cardname_short(struct qeth_card *); int qeth_realloc_buffer_pool(struct qeth_card *, int); int qeth_core_load_discipline(struct qeth_card *, enum qeth_discipline_id); void qeth_core_free_discipline(struct qeth_card *); +int qeth_core_create_device_attributes(struct device *); +void qeth_core_remove_device_attributes(struct device *); +int qeth_core_create_osn_attributes(struct device *); +void qeth_core_remove_osn_attributes(struct device *); void qeth_buffer_reclaim_work(struct work_struct *); /* exports for qeth discipline device drivers */ diff --git a/trunk/drivers/s390/net/qeth_core_main.c b/trunk/drivers/s390/net/qeth_core_main.c index e118e1e1e1c1..8334dadc681d 100644 --- a/trunk/drivers/s390/net/qeth_core_main.c +++ b/trunk/drivers/s390/net/qeth_core_main.c @@ -1329,6 +1329,8 @@ static void qeth_set_intial_options(struct qeth_card *card) { card->options.route4.type = NO_ROUTER; card->options.route6.type = NO_ROUTER; + card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS; + card->options.macaddr_mode = QETH_TR_MACADDR_NONCANONICAL; card->options.fake_broadcast = 0; card->options.add_hhlen = DEFAULT_ADD_HHLEN; card->options.performance_stats = 0; @@ -1363,7 +1365,7 @@ static void qeth_start_kernel_thread(struct work_struct *work) card->write.state != CH_STATE_UP) return; if (qeth_do_start_thread(card, QETH_RECOVER_THREAD)) { - ts = kthread_run(card->discipline->recover, (void *)card, + ts = kthread_run(card->discipline.recover, (void *)card, "qeth_recover"); if (IS_ERR(ts)) { qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); @@ -3337,7 +3339,7 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index, if (rc) { queue->card->stats.tx_errors += count; /* ignore temporary SIGA errors without busy condition */ - if (rc == -ENOBUFS) + if (rc == QDIO_ERROR_SIGA_TARGET) return; QETH_CARD_TEXT(queue->card, 2, "flushbuf"); QETH_CARD_TEXT_(queue->card, 2, " q%d", queue->queue_no); @@ -3531,7 +3533,7 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev, int i; QETH_CARD_TEXT(card, 6, "qdouhdl"); - if (qdio_error & QDIO_ERROR_FATAL) { + if (qdio_error & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) { QETH_CARD_TEXT(card, 2, "achkcond"); netif_stop_queue(card->dev); qeth_schedule_recovery(card); @@ -4627,7 +4629,7 @@ static int qeth_qdio_establish(struct qeth_card *card) goto out_free_in_sbals; } for (i = 0; i < card->qdio.no_in_queues; ++i) - queue_start_poll[i] = card->discipline->start_poll; + queue_start_poll[i] = card->discipline.start_poll; qeth_qdio_establish_cq(card, in_sbal_ptrs, queue_start_poll); @@ -4651,8 +4653,8 @@ static int qeth_qdio_establish(struct qeth_card *card) init_data.qib_param_field = qib_param_field; init_data.no_input_qs = card->qdio.no_in_queues; init_data.no_output_qs = card->qdio.no_out_queues; - init_data.input_handler = card->discipline->input_handler; - init_data.output_handler = card->discipline->output_handler; + init_data.input_handler = card->discipline.input_handler; + init_data.output_handler = card->discipline.output_handler; init_data.queue_start_poll_array = queue_start_poll; init_data.int_parm = (unsigned long) card; init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; @@ -4737,6 +4739,13 @@ static struct ccw_driver qeth_ccw_driver = { .remove = ccwgroup_remove_ccwdev, }; +static int qeth_core_driver_group(const char *buf, struct device *root_dev, + unsigned long driver_id) +{ + return ccwgroup_create_from_string(root_dev, driver_id, + &qeth_ccw_driver, 3, buf); +} + int qeth_core_hardsetup_card(struct qeth_card *card) { int retries = 0; @@ -4902,7 +4911,11 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card, break; case QETH_HEADER_TYPE_LAYER3: skb_len = (*hdr)->hdr.l3.length; - headroom = ETH_HLEN; + if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) || + (card->info.link_type == QETH_LINK_TYPE_HSTR)) + headroom = TR_HLEN; + else + headroom = ETH_HLEN; break; case QETH_HEADER_TYPE_OSN: skb_len = (*hdr)->hdr.osn.pdu_length; @@ -5033,15 +5046,17 @@ int qeth_core_load_discipline(struct qeth_card *card, mutex_lock(&qeth_mod_mutex); switch (discipline) { case QETH_DISCIPLINE_LAYER3: - card->discipline = try_then_request_module( - symbol_get(qeth_l3_discipline), "qeth_l3"); + card->discipline.ccwgdriver = try_then_request_module( + symbol_get(qeth_l3_ccwgroup_driver), + "qeth_l3"); break; case QETH_DISCIPLINE_LAYER2: - card->discipline = try_then_request_module( - symbol_get(qeth_l2_discipline), "qeth_l2"); + card->discipline.ccwgdriver = try_then_request_module( + symbol_get(qeth_l2_ccwgroup_driver), + "qeth_l2"); break; } - if (!card->discipline) { + if (!card->discipline.ccwgdriver) { dev_err(&card->gdev->dev, "There is no kernel module to " "support discipline %d\n", discipline); rc = -EINVAL; @@ -5053,21 +5068,12 @@ int qeth_core_load_discipline(struct qeth_card *card, void qeth_core_free_discipline(struct qeth_card *card) { if (card->options.layer2) - symbol_put(qeth_l2_discipline); + symbol_put(qeth_l2_ccwgroup_driver); else - symbol_put(qeth_l3_discipline); - card->discipline = NULL; + symbol_put(qeth_l3_ccwgroup_driver); + card->discipline.ccwgdriver = NULL; } -static const struct device_type qeth_generic_devtype = { - .name = "qeth_generic", - .groups = qeth_generic_attr_groups, -}; -static const struct device_type qeth_osn_devtype = { - .name = "qeth_osn", - .groups = qeth_osn_attr_groups, -}; - static int qeth_core_probe_device(struct ccwgroup_device *gdev) { struct qeth_card *card; @@ -5122,17 +5128,18 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) } if (card->info.type == QETH_CARD_TYPE_OSN) - gdev->dev.type = &qeth_osn_devtype; + rc = qeth_core_create_osn_attributes(dev); else - gdev->dev.type = &qeth_generic_devtype; - + rc = qeth_core_create_device_attributes(dev); + if (rc) + goto err_dbf; switch (card->info.type) { case QETH_CARD_TYPE_OSN: case QETH_CARD_TYPE_OSM: rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2); if (rc) - goto err_dbf; - rc = card->discipline->setup(card->gdev); + goto err_attr; + rc = card->discipline.ccwgdriver->probe(card->gdev); if (rc) goto err_disc; case QETH_CARD_TYPE_OSD: @@ -5150,6 +5157,11 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) err_disc: qeth_core_free_discipline(card); +err_attr: + if (card->info.type == QETH_CARD_TYPE_OSN) + qeth_core_remove_osn_attributes(dev); + else + qeth_core_remove_device_attributes(dev); err_dbf: debug_unregister(card->debug); err_card: @@ -5166,8 +5178,14 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev) QETH_DBF_TEXT(SETUP, 2, "removedv"); - if (card->discipline) { - card->discipline->remove(gdev); + if (card->info.type == QETH_CARD_TYPE_OSN) { + qeth_core_remove_osn_attributes(&gdev->dev); + } else { + qeth_core_remove_device_attributes(&gdev->dev); + } + + if (card->discipline.ccwgdriver) { + card->discipline.ccwgdriver->remove(gdev); qeth_core_free_discipline(card); } @@ -5187,7 +5205,7 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev) int rc = 0; int def_discipline; - if (!card->discipline) { + if (!card->discipline.ccwgdriver) { if (card->info.type == QETH_CARD_TYPE_IQD) def_discipline = QETH_DISCIPLINE_LAYER3; else @@ -5195,11 +5213,11 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev) rc = qeth_core_load_discipline(card, def_discipline); if (rc) goto err; - rc = card->discipline->setup(card->gdev); + rc = card->discipline.ccwgdriver->probe(card->gdev); if (rc) goto err; } - rc = card->discipline->set_online(gdev); + rc = card->discipline.ccwgdriver->set_online(gdev); err: return rc; } @@ -5207,52 +5225,58 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev) static int qeth_core_set_offline(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - return card->discipline->set_offline(gdev); + return card->discipline.ccwgdriver->set_offline(gdev); } static void qeth_core_shutdown(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - if (card->discipline && card->discipline->shutdown) - card->discipline->shutdown(gdev); + if (card->discipline.ccwgdriver && + card->discipline.ccwgdriver->shutdown) + card->discipline.ccwgdriver->shutdown(gdev); } static int qeth_core_prepare(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - if (card->discipline && card->discipline->prepare) - return card->discipline->prepare(gdev); + if (card->discipline.ccwgdriver && + card->discipline.ccwgdriver->prepare) + return card->discipline.ccwgdriver->prepare(gdev); return 0; } static void qeth_core_complete(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - if (card->discipline && card->discipline->complete) - card->discipline->complete(gdev); + if (card->discipline.ccwgdriver && + card->discipline.ccwgdriver->complete) + card->discipline.ccwgdriver->complete(gdev); } static int qeth_core_freeze(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - if (card->discipline && card->discipline->freeze) - return card->discipline->freeze(gdev); + if (card->discipline.ccwgdriver && + card->discipline.ccwgdriver->freeze) + return card->discipline.ccwgdriver->freeze(gdev); return 0; } static int qeth_core_thaw(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - if (card->discipline && card->discipline->thaw) - return card->discipline->thaw(gdev); + if (card->discipline.ccwgdriver && + card->discipline.ccwgdriver->thaw) + return card->discipline.ccwgdriver->thaw(gdev); return 0; } static int qeth_core_restore(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - if (card->discipline && card->discipline->restore) - return card->discipline->restore(gdev); + if (card->discipline.ccwgdriver && + card->discipline.ccwgdriver->restore) + return card->discipline.ccwgdriver->restore(gdev); return 0; } @@ -5261,7 +5285,8 @@ static struct ccwgroup_driver qeth_core_ccwgroup_driver = { .owner = THIS_MODULE, .name = "qeth", }, - .setup = qeth_core_probe_device, + .driver_id = 0xD8C5E3C8, + .probe = qeth_core_probe_device, .remove = qeth_core_remove_device, .set_online = qeth_core_set_online, .set_offline = qeth_core_set_offline, @@ -5273,29 +5298,20 @@ static struct ccwgroup_driver qeth_core_ccwgroup_driver = { .restore = qeth_core_restore, }; -static ssize_t qeth_core_driver_group_store(struct device_driver *ddrv, - const char *buf, size_t count) +static ssize_t +qeth_core_driver_group_store(struct device_driver *ddrv, const char *buf, + size_t count) { int err; - - err = ccwgroup_create_dev(qeth_core_root_dev, - &qeth_core_ccwgroup_driver, 3, buf); - - return err ? err : count; + err = qeth_core_driver_group(buf, qeth_core_root_dev, + qeth_core_ccwgroup_driver.driver_id); + if (err) + return err; + else + return count; } -static DRIVER_ATTR(group, 0200, NULL, qeth_core_driver_group_store); -static struct attribute *qeth_drv_attrs[] = { - &driver_attr_group.attr, - NULL, -}; -static struct attribute_group qeth_drv_attr_group = { - .attrs = qeth_drv_attrs, -}; -static const struct attribute_group *qeth_drv_attr_groups[] = { - &qeth_drv_attr_group, - NULL, -}; +static DRIVER_ATTR(group, 0200, NULL, qeth_core_driver_group_store); static struct { const char str[ETH_GSTRING_LEN]; @@ -5534,41 +5550,49 @@ static int __init qeth_core_init(void) rc = qeth_register_dbf_views(); if (rc) goto out_err; + rc = ccw_driver_register(&qeth_ccw_driver); + if (rc) + goto ccw_err; + rc = ccwgroup_driver_register(&qeth_core_ccwgroup_driver); + if (rc) + goto ccwgroup_err; + rc = driver_create_file(&qeth_core_ccwgroup_driver.driver, + &driver_attr_group); + if (rc) + goto driver_err; qeth_core_root_dev = root_device_register("qeth"); rc = IS_ERR(qeth_core_root_dev) ? PTR_ERR(qeth_core_root_dev) : 0; if (rc) goto register_err; + qeth_core_header_cache = kmem_cache_create("qeth_hdr", sizeof(struct qeth_hdr) + ETH_HLEN, 64, 0, NULL); if (!qeth_core_header_cache) { rc = -ENOMEM; goto slab_err; } + qeth_qdio_outbuf_cache = kmem_cache_create("qeth_buf", sizeof(struct qeth_qdio_out_buffer), 0, 0, NULL); if (!qeth_qdio_outbuf_cache) { rc = -ENOMEM; goto cqslab_err; } - rc = ccw_driver_register(&qeth_ccw_driver); - if (rc) - goto ccw_err; - qeth_core_ccwgroup_driver.driver.groups = qeth_drv_attr_groups; - rc = ccwgroup_driver_register(&qeth_core_ccwgroup_driver); - if (rc) - goto ccwgroup_err; return 0; - -ccwgroup_err: - ccw_driver_unregister(&qeth_ccw_driver); -ccw_err: - kmem_cache_destroy(qeth_qdio_outbuf_cache); cqslab_err: kmem_cache_destroy(qeth_core_header_cache); slab_err: root_device_unregister(qeth_core_root_dev); register_err: + driver_remove_file(&qeth_core_ccwgroup_driver.driver, + &driver_attr_group); +driver_err: + ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver); +ccwgroup_err: + ccw_driver_unregister(&qeth_ccw_driver); +ccw_err: + QETH_DBF_MESSAGE(2, "Initialization failed with code %d\n", rc); qeth_unregister_dbf_views(); out_err: pr_err("Initializing the qeth device driver failed\n"); @@ -5577,11 +5601,13 @@ static int __init qeth_core_init(void) static void __exit qeth_core_exit(void) { + root_device_unregister(qeth_core_root_dev); + driver_remove_file(&qeth_core_ccwgroup_driver.driver, + &driver_attr_group); ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver); ccw_driver_unregister(&qeth_ccw_driver); kmem_cache_destroy(qeth_qdio_outbuf_cache); kmem_cache_destroy(qeth_core_header_cache); - root_device_unregister(qeth_core_root_dev); qeth_unregister_dbf_views(); pr_info("core functions removed\n"); } diff --git a/trunk/drivers/s390/net/qeth_core_mpc.h b/trunk/drivers/s390/net/qeth_core_mpc.h index a11b30c38423..ff41e42004ac 100644 --- a/trunk/drivers/s390/net/qeth_core_mpc.h +++ b/trunk/drivers/s390/net/qeth_core_mpc.h @@ -70,6 +70,16 @@ enum qeth_link_types { QETH_LINK_TYPE_ATM_NATIVE = 0x90, }; +enum qeth_tr_macaddr_modes { + QETH_TR_MACADDR_NONCANONICAL = 0, + QETH_TR_MACADDR_CANONICAL = 1, +}; + +enum qeth_tr_broadcast_modes { + QETH_TR_BROADCAST_ALLRINGS = 0, + QETH_TR_BROADCAST_LOCAL = 1, +}; + /* * Routing stuff */ diff --git a/trunk/drivers/s390/net/qeth_core_sys.c b/trunk/drivers/s390/net/qeth_core_sys.c index f163af575c48..0a8e86c1b0ea 100644 --- a/trunk/drivers/s390/net/qeth_core_sys.c +++ b/trunk/drivers/s390/net/qeth_core_sys.c @@ -434,8 +434,8 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, goto out; else { card->info.mac_bits = 0; - if (card->discipline) { - card->discipline->remove(card->gdev); + if (card->discipline.ccwgdriver) { + card->discipline.ccwgdriver->remove(card->gdev); qeth_core_free_discipline(card); } } @@ -444,7 +444,7 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, if (rc) goto out; - rc = card->discipline->setup(card->gdev); + rc = card->discipline.ccwgdriver->probe(card->gdev); out: mutex_unlock(&card->discipline_mutex); return rc ? rc : count; @@ -693,6 +693,7 @@ static struct attribute *qeth_blkt_device_attrs[] = { &dev_attr_inter_jumbo.attr, NULL, }; + static struct attribute_group qeth_device_blkt_group = { .name = "blkt", .attrs = qeth_blkt_device_attrs, @@ -715,16 +716,11 @@ static struct attribute *qeth_device_attrs[] = { &dev_attr_hw_trap.attr, NULL, }; + static struct attribute_group qeth_device_attr_group = { .attrs = qeth_device_attrs, }; -const struct attribute_group *qeth_generic_attr_groups[] = { - &qeth_device_attr_group, - &qeth_device_blkt_group, - NULL, -}; - static struct attribute *qeth_osn_device_attrs[] = { &dev_attr_state.attr, &dev_attr_chpid.attr, @@ -734,10 +730,37 @@ static struct attribute *qeth_osn_device_attrs[] = { &dev_attr_recover.attr, NULL, }; + static struct attribute_group qeth_osn_device_attr_group = { .attrs = qeth_osn_device_attrs, }; -const struct attribute_group *qeth_osn_attr_groups[] = { - &qeth_osn_device_attr_group, - NULL, -}; + +int qeth_core_create_device_attributes(struct device *dev) +{ + int ret; + ret = sysfs_create_group(&dev->kobj, &qeth_device_attr_group); + if (ret) + return ret; + ret = sysfs_create_group(&dev->kobj, &qeth_device_blkt_group); + if (ret) + sysfs_remove_group(&dev->kobj, &qeth_device_attr_group); + + return 0; +} + +void qeth_core_remove_device_attributes(struct device *dev) +{ + sysfs_remove_group(&dev->kobj, &qeth_device_attr_group); + sysfs_remove_group(&dev->kobj, &qeth_device_blkt_group); +} + +int qeth_core_create_osn_attributes(struct device *dev) +{ + return sysfs_create_group(&dev->kobj, &qeth_osn_device_attr_group); +} + +void qeth_core_remove_osn_attributes(struct device *dev) +{ + sysfs_remove_group(&dev->kobj, &qeth_osn_device_attr_group); + return; +} diff --git a/trunk/drivers/s390/net/qeth_l2_main.c b/trunk/drivers/s390/net/qeth_l2_main.c index 426986518e96..0e7c29d1d7ef 100644 --- a/trunk/drivers/s390/net/qeth_l2_main.c +++ b/trunk/drivers/s390/net/qeth_l2_main.c @@ -882,6 +882,12 @@ static int qeth_l2_probe_device(struct ccwgroup_device *gdev) INIT_LIST_HEAD(&card->mc_list); card->options.layer2 = 1; card->info.hwtrap = 0; + card->discipline.start_poll = qeth_qdio_start_poll; + card->discipline.input_handler = (qdio_handler_t *) + qeth_qdio_input_handler; + card->discipline.output_handler = (qdio_handler_t *) + qeth_qdio_output_handler; + card->discipline.recover = qeth_l2_recover; return 0; } @@ -1221,12 +1227,8 @@ static int qeth_l2_pm_resume(struct ccwgroup_device *gdev) return rc; } -struct qeth_discipline qeth_l2_discipline = { - .start_poll = qeth_qdio_start_poll, - .input_handler = (qdio_handler_t *) qeth_qdio_input_handler, - .output_handler = (qdio_handler_t *) qeth_qdio_output_handler, - .recover = qeth_l2_recover, - .setup = qeth_l2_probe_device, +struct ccwgroup_driver qeth_l2_ccwgroup_driver = { + .probe = qeth_l2_probe_device, .remove = qeth_l2_remove_device, .set_online = qeth_l2_set_online, .set_offline = qeth_l2_set_offline, @@ -1235,7 +1237,7 @@ struct qeth_discipline qeth_l2_discipline = { .thaw = qeth_l2_pm_resume, .restore = qeth_l2_pm_resume, }; -EXPORT_SYMBOL_GPL(qeth_l2_discipline); +EXPORT_SYMBOL_GPL(qeth_l2_ccwgroup_driver); static int qeth_osn_send_control_data(struct qeth_card *card, int len, struct qeth_cmd_buffer *iob) diff --git a/trunk/drivers/s390/net/qeth_l3_main.c b/trunk/drivers/s390/net/qeth_l3_main.c index 7be5e9775691..f85921607686 100644 --- a/trunk/drivers/s390/net/qeth_l3_main.c +++ b/trunk/drivers/s390/net/qeth_l3_main.c @@ -976,6 +976,57 @@ static inline u8 qeth_l3_get_qeth_hdr_flags6(int cast_type) return ct | QETH_CAST_UNICAST; } +static int qeth_l3_send_setadp_mode(struct qeth_card *card, __u32 command, + __u32 mode) +{ + int rc; + struct qeth_cmd_buffer *iob; + struct qeth_ipa_cmd *cmd; + + QETH_CARD_TEXT(card, 4, "adpmode"); + + iob = qeth_get_adapter_cmd(card, command, + sizeof(struct qeth_ipacmd_setadpparms)); + cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); + cmd->data.setadapterparms.data.mode = mode; + rc = qeth_send_ipa_cmd(card, iob, qeth_default_setadapterparms_cb, + NULL); + return rc; +} + +static int qeth_l3_setadapter_hstr(struct qeth_card *card) +{ + int rc; + + QETH_CARD_TEXT(card, 4, "adphstr"); + + if (qeth_adp_supported(card, IPA_SETADP_SET_BROADCAST_MODE)) { + rc = qeth_l3_send_setadp_mode(card, + IPA_SETADP_SET_BROADCAST_MODE, + card->options.broadcast_mode); + if (rc) + QETH_DBF_MESSAGE(2, "couldn't set broadcast mode on " + "device %s: x%x\n", + CARD_BUS_ID(card), rc); + rc = qeth_l3_send_setadp_mode(card, + IPA_SETADP_ALTER_MAC_ADDRESS, + card->options.macaddr_mode); + if (rc) + QETH_DBF_MESSAGE(2, "couldn't set macaddr mode on " + "device %s: x%x\n", CARD_BUS_ID(card), rc); + return rc; + } + if (card->options.broadcast_mode == QETH_TR_BROADCAST_LOCAL) + QETH_DBF_MESSAGE(2, "set adapter parameters not available " + "to set broadcast mode, using ALLRINGS " + "on device %s:\n", CARD_BUS_ID(card)); + if (card->options.macaddr_mode == QETH_TR_MACADDR_CANONICAL) + QETH_DBF_MESSAGE(2, "set adapter parameters not available " + "to set macaddr mode, using NONCANONICAL " + "on device %s:\n", CARD_BUS_ID(card)); + return 0; +} + static int qeth_l3_setadapter_parms(struct qeth_card *card) { int rc; @@ -1001,6 +1052,10 @@ static int qeth_l3_setadapter_parms(struct qeth_card *card) " address failed\n"); } + if ((card->info.link_type == QETH_LINK_TYPE_HSTR) || + (card->info.link_type == QETH_LINK_TYPE_LANE_TR)) + rc = qeth_l3_setadapter_hstr(card); + return rc; } @@ -1616,7 +1671,10 @@ qeth_diags_trace(struct qeth_card *card, enum qeth_diags_trace_cmds diags_cmd) static void qeth_l3_get_mac_for_ipm(__u32 ipm, char *mac, struct net_device *dev) { - ip_eth_mc_map(ipm, mac); + if (dev->type == ARPHRD_IEEE802_TR) + ip_tr_mc_map(ipm, mac); + else + ip_eth_mc_map(ipm, mac); } static void qeth_l3_add_mc(struct qeth_card *card, struct in_device *in4_dev) @@ -1864,6 +1922,8 @@ static inline int qeth_l3_rebuild_skb(struct qeth_card *card, #endif case __constant_htons(ETH_P_IP): ip_hdr = (struct iphdr *)skb->data; + (card->dev->type == ARPHRD_IEEE802_TR) ? + ip_tr_mc_map(ip_hdr->daddr, tg_addr): ip_eth_mc_map(ip_hdr->daddr, tg_addr); break; default: @@ -1899,7 +1959,12 @@ static inline int qeth_l3_rebuild_skb(struct qeth_card *card, tg_addr, "FAKELL", card->dev->addr_len); } - skb->protocol = eth_type_trans(skb, card->dev); +#ifdef CONFIG_TR + if (card->dev->type == ARPHRD_IEEE802_TR) + skb->protocol = tr_type_trans(skb, card->dev); + else +#endif + skb->protocol = eth_type_trans(skb, card->dev); if (hdr->hdr.l3.ext_flags & (QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) { @@ -2073,7 +2138,7 @@ static int qeth_l3_verify_vlan_dev(struct net_device *dev, struct net_device *netdev; rcu_read_lock(); - netdev = __vlan_find_dev_deep(card->dev, vid); + netdev = __vlan_find_dev_deep(dev, vid); rcu_read_unlock(); if (netdev == dev) { rc = QETH_VLAN_CARD; @@ -2818,7 +2883,13 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU; memcpy(hdr->hdr.l3.dest_addr, pkey, 16); } else { - if (!memcmp(skb->data + sizeof(struct qeth_hdr), + /* passthrough */ + if ((skb->dev->type == ARPHRD_IEEE802_TR) && + !memcmp(skb->data + sizeof(struct qeth_hdr) + + sizeof(__u16), skb->dev->broadcast, 6)) { + hdr->hdr.l3.flags = QETH_CAST_BROADCAST | + QETH_HDR_PASSTHRU; + } else if (!memcmp(skb->data + sizeof(struct qeth_hdr), skb->dev->broadcast, 6)) { /* broadcast? */ hdr->hdr.l3.flags = QETH_CAST_BROADCAST | @@ -2960,7 +3031,10 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) skb_pull(new_skb, ETH_HLEN); } else { if (ipv == 4) { - skb_pull(new_skb, ETH_HLEN); + if (card->dev->type == ARPHRD_IEEE802_TR) + skb_pull(new_skb, TR_HLEN); + else + skb_pull(new_skb, ETH_HLEN); } if (ipv != 4 && vlan_tx_tag_present(new_skb)) { @@ -3244,8 +3318,12 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) card->info.type == QETH_CARD_TYPE_OSX) { if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) || (card->info.link_type == QETH_LINK_TYPE_HSTR)) { - pr_info("qeth_l3: ignoring TR device\n"); - return -ENODEV; +#ifdef CONFIG_TR + card->dev = alloc_trdev(0); +#endif + if (!card->dev) + return -ENODEV; + card->dev->netdev_ops = &qeth_l3_netdev_ops; } else { card->dev = alloc_etherdev(0); if (!card->dev) @@ -3298,6 +3376,12 @@ static int qeth_l3_probe_device(struct ccwgroup_device *gdev) qeth_l3_create_device_attributes(&gdev->dev); card->options.layer2 = 0; card->info.hwtrap = 0; + card->discipline.start_poll = qeth_qdio_start_poll; + card->discipline.input_handler = (qdio_handler_t *) + qeth_qdio_input_handler; + card->discipline.output_handler = (qdio_handler_t *) + qeth_qdio_output_handler; + card->discipline.recover = qeth_l3_recover; return 0; } @@ -3572,12 +3656,8 @@ static int qeth_l3_pm_resume(struct ccwgroup_device *gdev) return rc; } -struct qeth_discipline qeth_l3_discipline = { - .start_poll = qeth_qdio_start_poll, - .input_handler = (qdio_handler_t *) qeth_qdio_input_handler, - .output_handler = (qdio_handler_t *) qeth_qdio_output_handler, - .recover = qeth_l3_recover, - .setup = qeth_l3_probe_device, +struct ccwgroup_driver qeth_l3_ccwgroup_driver = { + .probe = qeth_l3_probe_device, .remove = qeth_l3_remove_device, .set_online = qeth_l3_set_online, .set_offline = qeth_l3_set_offline, @@ -3586,7 +3666,7 @@ struct qeth_discipline qeth_l3_discipline = { .thaw = qeth_l3_pm_resume, .restore = qeth_l3_pm_resume, }; -EXPORT_SYMBOL_GPL(qeth_l3_discipline); +EXPORT_SYMBOL_GPL(qeth_l3_ccwgroup_driver); static int qeth_l3_ip_event(struct notifier_block *this, unsigned long event, void *ptr) @@ -3600,9 +3680,9 @@ static int qeth_l3_ip_event(struct notifier_block *this, return NOTIFY_DONE; card = qeth_l3_get_card_from_dev(dev); + QETH_CARD_TEXT(card, 3, "ipevent"); if (!card) return NOTIFY_DONE; - QETH_CARD_TEXT(card, 3, "ipevent"); addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV4); if (addr != NULL) { diff --git a/trunk/drivers/s390/net/qeth_l3_sys.c b/trunk/drivers/s390/net/qeth_l3_sys.c index 4cafedf950ad..d979bb26522f 100644 --- a/trunk/drivers/s390/net/qeth_l3_sys.c +++ b/trunk/drivers/s390/net/qeth_l3_sys.c @@ -175,6 +175,116 @@ static ssize_t qeth_l3_dev_fake_broadcast_store(struct device *dev, static DEVICE_ATTR(fake_broadcast, 0644, qeth_l3_dev_fake_broadcast_show, qeth_l3_dev_fake_broadcast_store); +static ssize_t qeth_l3_dev_broadcast_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct qeth_card *card = dev_get_drvdata(dev); + + if (!card) + return -EINVAL; + + if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || + (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) + return sprintf(buf, "n/a\n"); + + return sprintf(buf, "%s\n", (card->options.broadcast_mode == + QETH_TR_BROADCAST_ALLRINGS)? + "all rings":"local"); +} + +static ssize_t qeth_l3_dev_broadcast_mode_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct qeth_card *card = dev_get_drvdata(dev); + char *tmp; + int rc = 0; + + if (!card) + return -EINVAL; + + mutex_lock(&card->conf_mutex); + if ((card->state != CARD_STATE_DOWN) && + (card->state != CARD_STATE_RECOVER)) { + rc = -EPERM; + goto out; + } + + if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || + (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) { + rc = -EINVAL; + goto out; + } + + tmp = strsep((char **) &buf, "\n"); + + if (!strcmp(tmp, "local")) + card->options.broadcast_mode = QETH_TR_BROADCAST_LOCAL; + else if (!strcmp(tmp, "all_rings")) + card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS; + else + rc = -EINVAL; +out: + mutex_unlock(&card->conf_mutex); + return rc ? rc : count; +} + +static DEVICE_ATTR(broadcast_mode, 0644, qeth_l3_dev_broadcast_mode_show, + qeth_l3_dev_broadcast_mode_store); + +static ssize_t qeth_l3_dev_canonical_macaddr_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct qeth_card *card = dev_get_drvdata(dev); + + if (!card) + return -EINVAL; + + if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || + (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) + return sprintf(buf, "n/a\n"); + + return sprintf(buf, "%i\n", (card->options.macaddr_mode == + QETH_TR_MACADDR_CANONICAL)? 1:0); +} + +static ssize_t qeth_l3_dev_canonical_macaddr_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct qeth_card *card = dev_get_drvdata(dev); + char *tmp; + int i, rc = 0; + + if (!card) + return -EINVAL; + + mutex_lock(&card->conf_mutex); + if ((card->state != CARD_STATE_DOWN) && + (card->state != CARD_STATE_RECOVER)) { + rc = -EPERM; + goto out; + } + + if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || + (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) { + rc = -EINVAL; + goto out; + } + + i = simple_strtoul(buf, &tmp, 16); + if ((i == 0) || (i == 1)) + card->options.macaddr_mode = i? + QETH_TR_MACADDR_CANONICAL : + QETH_TR_MACADDR_NONCANONICAL; + else + rc = -EINVAL; +out: + mutex_unlock(&card->conf_mutex); + return rc ? rc : count; +} + +static DEVICE_ATTR(canonical_macaddr, 0644, qeth_l3_dev_canonical_macaddr_show, + qeth_l3_dev_canonical_macaddr_store); + static ssize_t qeth_l3_dev_sniffer_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -348,6 +458,8 @@ static struct attribute *qeth_l3_device_attrs[] = { &dev_attr_route4.attr, &dev_attr_route6.attr, &dev_attr_fake_broadcast.attr, + &dev_attr_broadcast_mode.attr, + &dev_attr_canonical_macaddr.attr, &dev_attr_sniffer.attr, &dev_attr_hsuid.attr, NULL, diff --git a/trunk/drivers/scsi/Kconfig b/trunk/drivers/scsi/Kconfig index bea04e5d3b51..29684c8142b0 100644 --- a/trunk/drivers/scsi/Kconfig +++ b/trunk/drivers/scsi/Kconfig @@ -408,7 +408,6 @@ config BLK_DEV_3W_XXXX_RAID config SCSI_HPSA tristate "HP Smart Array SCSI driver" depends on PCI && SCSI - select CHECK_SIGNATURE help This driver supports HP Smart Array Controllers (circa 2009). It is a SCSI alternative to the cciss driver, which is a block diff --git a/trunk/drivers/scsi/aacraid/src.c b/trunk/drivers/scsi/aacraid/src.c index 762820636304..2bee51506a91 100644 --- a/trunk/drivers/scsi/aacraid/src.c +++ b/trunk/drivers/scsi/aacraid/src.c @@ -424,8 +424,6 @@ static int aac_src_deliver_message(struct fib *fib) static int aac_src_ioremap(struct aac_dev *dev, u32 size) { if (!size) { - iounmap(dev->regs.src.bar1); - dev->regs.src.bar1 = NULL; iounmap(dev->regs.src.bar0); dev->base = dev->regs.src.bar0 = NULL; return 0; diff --git a/trunk/drivers/scsi/atari_scsi.c b/trunk/drivers/scsi/atari_scsi.c index df740cbbaef4..04a154f87e3e 100644 --- a/trunk/drivers/scsi/atari_scsi.c +++ b/trunk/drivers/scsi/atari_scsi.c @@ -572,7 +572,7 @@ static void falcon_get_lock(void) } -static int __init atari_scsi_detect(struct scsi_host_template *host) +int __init atari_scsi_detect(struct scsi_host_template *host) { static int called = 0; struct Scsi_Host *instance; @@ -724,7 +724,7 @@ static int __init atari_scsi_detect(struct scsi_host_template *host) return 1; } -static int atari_scsi_release(struct Scsi_Host *sh) +int atari_scsi_release(struct Scsi_Host *sh) { if (IS_A_TT()) free_irq(IRQ_TT_MFP_SCSI, sh); @@ -734,21 +734,17 @@ static int atari_scsi_release(struct Scsi_Host *sh) return 1; } -#ifndef MODULE -static int __init atari_scsi_setup(char *str) +void __init atari_scsi_setup(char *str, int *ints) { /* Format of atascsi parameter is: * atascsi=,,,, * Defaults depend on TT or Falcon, hostid determined at run time. * Negative values mean don't change. */ - int ints[6]; - - get_options(str, ARRAY_SIZE(ints), ints); if (ints[0] < 1) { printk("atari_scsi_setup: no arguments!\n"); - return 0; + return; } if (ints[0] >= 1) { @@ -781,14 +777,9 @@ static int __init atari_scsi_setup(char *str) setup_use_tagged_queuing = !!ints[5]; } #endif - - return 1; } -__setup("atascsi=", atari_scsi_setup); -#endif /* !MODULE */ - -static int atari_scsi_bus_reset(Scsi_Cmnd *cmd) +int atari_scsi_bus_reset(Scsi_Cmnd *cmd) { int rv; struct NCR5380_hostdata *hostdata = @@ -861,7 +852,7 @@ static void __init atari_scsi_reset_boot(void) #endif -static const char *atari_scsi_info(struct Scsi_Host *host) +const char *atari_scsi_info(struct Scsi_Host *host) { /* atari_scsi_detect() is verbose enough... */ static const char string[] = "Atari native SCSI"; @@ -871,9 +862,8 @@ static const char *atari_scsi_info(struct Scsi_Host *host) #if defined(REAL_DMA) -static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance, - void *data, unsigned long count, - int dir) +unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance, void *data, + unsigned long count, int dir) { unsigned long addr = virt_to_phys(data); diff --git a/trunk/drivers/scsi/atari_scsi.h b/trunk/drivers/scsi/atari_scsi.h index bd52df78b209..efadb8d567c2 100644 --- a/trunk/drivers/scsi/atari_scsi.h +++ b/trunk/drivers/scsi/atari_scsi.h @@ -18,6 +18,11 @@ /* (I_HAVE_OVERRUNS stuff removed) */ #ifndef ASM +int atari_scsi_detect (struct scsi_host_template *); +const char *atari_scsi_info (struct Scsi_Host *); +int atari_scsi_reset (Scsi_Cmnd *, unsigned int); +int atari_scsi_release (struct Scsi_Host *); + /* The values for CMD_PER_LUN and CAN_QUEUE are somehow arbitrary. Higher * values should work, too; try it! (but cmd_per_lun costs memory!) */ diff --git a/trunk/drivers/scsi/be2iscsi/be.h b/trunk/drivers/scsi/be2iscsi/be.h index a50b6a9030e8..1d7b976c850f 100644 --- a/trunk/drivers/scsi/be2iscsi/be.h +++ b/trunk/drivers/scsi/be2iscsi/be.h @@ -132,6 +132,10 @@ struct be_ctrl_info { ((u32)((((size_t)(_address) & (PAGE_SIZE_4K - 1)) + \ (size) + (PAGE_SIZE_4K - 1)) >> PAGE_SHIFT_4K)) +/* Byte offset into the page corresponding to given address */ +#define OFFSET_IN_PAGE(addr) \ + ((size_t)(addr) & (PAGE_SIZE_4K-1)) + /* Returns bit offset within a DWORD of a bitfield */ #define AMAP_BIT_OFFSET(_struct, field) \ (((size_t)&(((_struct *)0)->field))%32) diff --git a/trunk/drivers/scsi/be2iscsi/be_cmds.c b/trunk/drivers/scsi/be2iscsi/be_cmds.c index d2e9e933f7a3..cdb15364bc69 100644 --- a/trunk/drivers/scsi/be2iscsi/be_cmds.c +++ b/trunk/drivers/scsi/be2iscsi/be_cmds.c @@ -15,8 +15,6 @@ * Costa Mesa, CA 92626 */ -#include - #include "be.h" #include "be_mgmt.h" #include "be_main.h" diff --git a/trunk/drivers/scsi/be2iscsi/be_cmds.h b/trunk/drivers/scsi/be2iscsi/be_cmds.h index b0b36c6a145f..8b40a5b4366c 100644 --- a/trunk/drivers/scsi/be2iscsi/be_cmds.h +++ b/trunk/drivers/scsi/be2iscsi/be_cmds.h @@ -23,7 +23,7 @@ * firmware in the BE. These requests are communicated to the processor * using Work Request Blocks (WRBs) submitted to the MCC-WRB ring or via one * WRB inside a MAILBOX. - * The commands are serviced by the ARM processor in the OneConnect's MPU. + * The commands are serviced by the ARM processor in the BladeEngine's MPU. */ struct be_sge { u32 pa_lo; @@ -163,8 +163,7 @@ struct be_mcc_mailbox { #define OPCODE_COMMON_ISCSI_CFG_REMOVE_SGL_PAGES 3 #define OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG 7 #define OPCODE_COMMON_ISCSI_NTWK_SET_VLAN 14 -#define OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR 17 -#define OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR 18 +#define OPCODE_COMMON_ISCSI_NTWK_CONFIGURE_STATELESS_IP_ADDR 17 #define OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR 21 #define OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY 22 #define OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY 23 @@ -275,15 +274,15 @@ struct mgmt_conn_login_options { struct mgmt_auth_method_format auth_data; } __packed; -struct ip_addr_format { +struct ip_address_format { u16 size_of_structure; u8 reserved; u8 ip_type; - u8 addr[16]; + u8 ip_address[16]; u32 rsvd0; } __packed; -struct mgmt_conn_info { +struct mgmt_conn_info { u32 connection_handle; u32 connection_status; u16 src_port; @@ -291,9 +290,9 @@ struct mgmt_conn_info { u16 dest_port_redirected; u16 cid; u32 estimated_throughput; - struct ip_addr_format src_ipaddr; - struct ip_addr_format dest_ipaddr; - struct ip_addr_format dest_ipaddr_redirected; + struct ip_address_format src_ipaddr; + struct ip_address_format dest_ipaddr; + struct ip_address_format dest_ipaddr_redirected; struct mgmt_conn_login_options negotiated_login_options; } __packed; @@ -323,115 +322,43 @@ struct mgmt_session_info { struct mgmt_conn_info conn_list[1]; } __packed; -struct be_cmd_get_session_req { +struct be_cmd_req_get_session { struct be_cmd_req_hdr hdr; u32 session_handle; } __packed; -struct be_cmd_get_session_resp { +struct be_cmd_resp_get_session { struct be_cmd_resp_hdr hdr; struct mgmt_session_info session_info; } __packed; struct mac_addr { - u16 size_of_structure; + u16 size_of_struct; u8 addr[ETH_ALEN]; } __packed; -struct be_cmd_get_boot_target_req { +struct be_cmd_req_get_boot_target { struct be_cmd_req_hdr hdr; } __packed; -struct be_cmd_get_boot_target_resp { +struct be_cmd_resp_get_boot_target { struct be_cmd_resp_hdr hdr; u32 boot_session_count; int boot_session_handle; }; -struct be_cmd_mac_query_req { +struct be_cmd_req_mac_query { struct be_cmd_req_hdr hdr; u8 type; u8 permanent; u16 if_id; } __packed; -struct be_cmd_get_mac_resp { +struct be_cmd_resp_mac_query { struct be_cmd_resp_hdr hdr; struct mac_addr mac; }; -struct be_ip_addr_subnet_format { - u16 size_of_structure; - u8 ip_type; - u8 ipv6_prefix_length; - u8 addr[16]; - u8 subnet_mask[16]; - u32 rsvd0; -} __packed; - -struct be_cmd_get_if_info_req { - struct be_cmd_req_hdr hdr; - u32 interface_hndl; - u32 ip_type; -} __packed; - -struct be_cmd_get_if_info_resp { - struct be_cmd_req_hdr hdr; - u32 interface_hndl; - u32 vlan_priority; - u32 ip_addr_count; - u32 dhcp_state; - struct be_ip_addr_subnet_format ip_addr; -} __packed; - -struct be_ip_addr_record { - u32 action; - u32 interface_hndl; - struct be_ip_addr_subnet_format ip_addr; - u32 status; -} __packed; - -struct be_ip_addr_record_params { - u32 record_entry_count; - struct be_ip_addr_record ip_record; -} __packed; - -struct be_cmd_set_ip_addr_req { - struct be_cmd_req_hdr hdr; - struct be_ip_addr_record_params ip_params; -} __packed; - - -struct be_cmd_set_dhcp_req { - struct be_cmd_req_hdr hdr; - u32 interface_hndl; - u32 ip_type; - u32 flags; - u32 retry_count; -} __packed; - -struct be_cmd_rel_dhcp_req { - struct be_cmd_req_hdr hdr; - u32 interface_hndl; - u32 ip_type; -} __packed; - -struct be_cmd_set_def_gateway_req { - struct be_cmd_req_hdr hdr; - u32 action; - struct ip_addr_format ip_addr; -} __packed; - -struct be_cmd_get_def_gateway_req { - struct be_cmd_req_hdr hdr; - u32 ip_type; -} __packed; - -struct be_cmd_get_def_gateway_resp { - struct be_cmd_req_hdr hdr; - struct ip_addr_format ip_addr; -} __packed; - /******************** Create CQ ***************************/ /** * Pseudo amap definition in which each bit of the actual structure is defined @@ -562,7 +489,7 @@ struct be_cmd_req_modify_eq_delay { #define ETH_ALEN 6 -struct be_cmd_get_nic_conf_req { +struct be_cmd_req_get_mac_addr { struct be_cmd_req_hdr hdr; u32 nic_port_count; u32 speed; @@ -574,7 +501,7 @@ struct be_cmd_get_nic_conf_req { u32 rsvd[23]; }; -struct be_cmd_get_nic_conf_resp { +struct be_cmd_resp_get_mac_addr { struct be_cmd_resp_hdr hdr; u32 nic_port_count; u32 speed; @@ -586,39 +513,6 @@ struct be_cmd_get_nic_conf_resp { u32 rsvd[23]; }; -#define BEISCSI_ALIAS_LEN 32 - -struct be_cmd_hba_name { - struct be_cmd_req_hdr hdr; - u16 flags; - u16 rsvd0; - u8 initiator_name[ISCSI_NAME_LEN]; - u8 initiator_alias[BEISCSI_ALIAS_LEN]; -} __packed; - -struct be_cmd_ntwk_link_status_req { - struct be_cmd_req_hdr hdr; - u32 rsvd0; -} __packed; - -/*** Port Speed Values ***/ -#define BE2ISCSI_LINK_SPEED_ZERO 0x00 -#define BE2ISCSI_LINK_SPEED_10MBPS 0x01 -#define BE2ISCSI_LINK_SPEED_100MBPS 0x02 -#define BE2ISCSI_LINK_SPEED_1GBPS 0x03 -#define BE2ISCSI_LINK_SPEED_10GBPS 0x04 -struct be_cmd_ntwk_link_status_resp { - struct be_cmd_resp_hdr hdr; - u8 phys_port; - u8 mac_duplex; - u8 mac_speed; - u8 mac_fault; - u8 mgmt_mac_duplex; - u8 mgmt_mac_speed; - u16 qos_link_speed; - u32 logical_link_speed; -} __packed; - int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl, struct be_queue_info *eq, int eq_delay); @@ -636,8 +530,11 @@ int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba, int be_poll_mcc(struct be_ctrl_info *ctrl); int mgmt_check_supported_fw(struct be_ctrl_info *ctrl, struct beiscsi_hba *phba); -unsigned int be_cmd_get_initname(struct beiscsi_hba *phba); -unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba); +unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba); +unsigned int beiscsi_get_boot_target(struct beiscsi_hba *phba); +unsigned int beiscsi_get_session_info(struct beiscsi_hba *phba, + u32 boot_session_handle, + struct be_dma_mem *nonemb_cmd); void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag); /*ISCSI Functuions */ @@ -818,7 +715,7 @@ struct be_eq_delay_params_in { struct tcp_connect_and_offload_in { struct be_cmd_req_hdr hdr; - struct ip_addr_format ip_address; + struct ip_address_format ip_address; u16 tcp_port; u16 cid; u16 cq_id; @@ -895,14 +792,13 @@ struct be_fw_cfg { u32 function_caps; } __packed; -struct be_cmd_get_all_if_id_req { +struct be_all_if_id { struct be_cmd_req_hdr hdr; u32 if_count; u32 if_hndl_list[1]; } __packed; #define ISCSI_OPCODE_SCSI_DATA_OUT 5 -#define OPCODE_COMMON_NTWK_LINK_STATUS_QUERY 5 #define OPCODE_COMMON_MODIFY_EQ_DELAY 41 #define OPCODE_COMMON_ISCSI_CLEANUP 59 #define OPCODE_COMMON_TCP_UPLOAD 56 @@ -914,8 +810,6 @@ struct be_cmd_get_all_if_id_req { #define OPCODE_ISCSI_INI_DRIVER_OFFLOAD_SESSION 41 #define OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION 42 #define OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET 52 -#define OPCODE_COMMON_WRITE_FLASH 96 -#define OPCODE_COMMON_READ_FLASH 97 /* --- CMD_ISCSI_INVALIDATE_CONNECTION_TYPE --- */ #define CMD_ISCSI_COMMAND_INVALIDATE 1 diff --git a/trunk/drivers/scsi/be2iscsi/be_iscsi.c b/trunk/drivers/scsi/be2iscsi/be_iscsi.c index 43f35034585d..33c8f09c7ac1 100644 --- a/trunk/drivers/scsi/be2iscsi/be_iscsi.c +++ b/trunk/drivers/scsi/be2iscsi/be_iscsi.c @@ -23,8 +23,6 @@ #include #include #include -#include -#include #include #include "be_iscsi.h" @@ -209,301 +207,6 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session, return beiscsi_bindconn_cid(phba, beiscsi_conn, beiscsi_ep->ep_cid); } -static int beiscsi_create_ipv4_iface(struct beiscsi_hba *phba) -{ - if (phba->ipv4_iface) - return 0; - - phba->ipv4_iface = iscsi_create_iface(phba->shost, - &beiscsi_iscsi_transport, - ISCSI_IFACE_TYPE_IPV4, - 0, 0); - if (!phba->ipv4_iface) { - shost_printk(KERN_ERR, phba->shost, "Could not " - "create default IPv4 address.\n"); - return -ENODEV; - } - - return 0; -} - -static int beiscsi_create_ipv6_iface(struct beiscsi_hba *phba) -{ - if (phba->ipv6_iface) - return 0; - - phba->ipv6_iface = iscsi_create_iface(phba->shost, - &beiscsi_iscsi_transport, - ISCSI_IFACE_TYPE_IPV6, - 0, 0); - if (!phba->ipv6_iface) { - shost_printk(KERN_ERR, phba->shost, "Could not " - "create default IPv6 address.\n"); - return -ENODEV; - } - - return 0; -} - -void beiscsi_create_def_ifaces(struct beiscsi_hba *phba) -{ - struct be_cmd_get_if_info_resp if_info; - - if (!mgmt_get_if_info(phba, BE2_IPV4, &if_info)) - beiscsi_create_ipv4_iface(phba); - - if (!mgmt_get_if_info(phba, BE2_IPV6, &if_info)) - beiscsi_create_ipv6_iface(phba); -} - -void beiscsi_destroy_def_ifaces(struct beiscsi_hba *phba) -{ - if (phba->ipv6_iface) - iscsi_destroy_iface(phba->ipv6_iface); - if (phba->ipv4_iface) - iscsi_destroy_iface(phba->ipv4_iface); -} - -static int -beiscsi_set_static_ip(struct Scsi_Host *shost, - struct iscsi_iface_param_info *iface_param, - void *data, uint32_t dt_len) -{ - struct beiscsi_hba *phba = iscsi_host_priv(shost); - struct iscsi_iface_param_info *iface_ip = NULL; - struct iscsi_iface_param_info *iface_subnet = NULL; - struct nlattr *nla; - int ret; - - - switch (iface_param->param) { - case ISCSI_NET_PARAM_IPV4_BOOTPROTO: - nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_ADDR); - if (nla) - iface_ip = nla_data(nla); - - nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_SUBNET); - if (nla) - iface_subnet = nla_data(nla); - break; - case ISCSI_NET_PARAM_IPV4_ADDR: - iface_ip = iface_param; - nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_SUBNET); - if (nla) - iface_subnet = nla_data(nla); - break; - case ISCSI_NET_PARAM_IPV4_SUBNET: - iface_subnet = iface_param; - nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_ADDR); - if (nla) - iface_ip = nla_data(nla); - break; - default: - shost_printk(KERN_ERR, shost, "Unsupported param %d\n", - iface_param->param); - } - - if (!iface_ip || !iface_subnet) { - shost_printk(KERN_ERR, shost, "IP and Subnet Mask required\n"); - return -EINVAL; - } - - ret = mgmt_set_ip(phba, iface_ip, iface_subnet, - ISCSI_BOOTPROTO_STATIC); - - return ret; -} - -static int -beiscsi_set_ipv4(struct Scsi_Host *shost, - struct iscsi_iface_param_info *iface_param, - void *data, uint32_t dt_len) -{ - struct beiscsi_hba *phba = iscsi_host_priv(shost); - int ret = 0; - - /* Check the param */ - switch (iface_param->param) { - case ISCSI_NET_PARAM_IPV4_GW: - ret = mgmt_set_gateway(phba, iface_param); - break; - case ISCSI_NET_PARAM_IPV4_BOOTPROTO: - if (iface_param->value[0] == ISCSI_BOOTPROTO_DHCP) - ret = mgmt_set_ip(phba, iface_param, - NULL, ISCSI_BOOTPROTO_DHCP); - else if (iface_param->value[0] == ISCSI_BOOTPROTO_STATIC) - ret = beiscsi_set_static_ip(shost, iface_param, - data, dt_len); - else - shost_printk(KERN_ERR, shost, "Invalid BOOTPROTO: %d\n", - iface_param->value[0]); - break; - case ISCSI_NET_PARAM_IFACE_ENABLE: - if (iface_param->value[0] == ISCSI_IFACE_ENABLE) - ret = beiscsi_create_ipv4_iface(phba); - else - iscsi_destroy_iface(phba->ipv4_iface); - break; - case ISCSI_NET_PARAM_IPV4_SUBNET: - case ISCSI_NET_PARAM_IPV4_ADDR: - ret = beiscsi_set_static_ip(shost, iface_param, - data, dt_len); - break; - default: - shost_printk(KERN_ERR, shost, "Param %d not supported\n", - iface_param->param); - } - - return ret; -} - -static int -beiscsi_set_ipv6(struct Scsi_Host *shost, - struct iscsi_iface_param_info *iface_param, - void *data, uint32_t dt_len) -{ - struct beiscsi_hba *phba = iscsi_host_priv(shost); - int ret = 0; - - switch (iface_param->param) { - case ISCSI_NET_PARAM_IFACE_ENABLE: - if (iface_param->value[0] == ISCSI_IFACE_ENABLE) - ret = beiscsi_create_ipv6_iface(phba); - else { - iscsi_destroy_iface(phba->ipv6_iface); - ret = 0; - } - break; - case ISCSI_NET_PARAM_IPV6_ADDR: - ret = mgmt_set_ip(phba, iface_param, NULL, - ISCSI_BOOTPROTO_STATIC); - break; - default: - shost_printk(KERN_ERR, shost, "Param %d not supported\n", - iface_param->param); - } - - return ret; -} - -int be2iscsi_iface_set_param(struct Scsi_Host *shost, - void *data, uint32_t dt_len) -{ - struct iscsi_iface_param_info *iface_param = NULL; - struct nlattr *attrib; - uint32_t rm_len = dt_len; - int ret = 0 ; - - nla_for_each_attr(attrib, data, dt_len, rm_len) { - iface_param = nla_data(attrib); - - if (iface_param->param_type != ISCSI_NET_PARAM) - continue; - - /* - * BE2ISCSI only supports 1 interface - */ - if (iface_param->iface_num) { - shost_printk(KERN_ERR, shost, "Invalid iface_num %d." - "Only iface_num 0 is supported.\n", - iface_param->iface_num); - return -EINVAL; - } - - switch (iface_param->iface_type) { - case ISCSI_IFACE_TYPE_IPV4: - ret = beiscsi_set_ipv4(shost, iface_param, - data, dt_len); - break; - case ISCSI_IFACE_TYPE_IPV6: - ret = beiscsi_set_ipv6(shost, iface_param, - data, dt_len); - break; - default: - shost_printk(KERN_ERR, shost, - "Invalid iface type :%d passed\n", - iface_param->iface_type); - break; - } - - if (ret) - return ret; - } - - return ret; -} - -static int be2iscsi_get_if_param(struct beiscsi_hba *phba, - struct iscsi_iface *iface, int param, - char *buf) -{ - struct be_cmd_get_if_info_resp if_info; - int len, ip_type = BE2_IPV4; - - memset(&if_info, 0, sizeof(if_info)); - - if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6) - ip_type = BE2_IPV6; - - len = mgmt_get_if_info(phba, ip_type, &if_info); - if (len) - return len; - - switch (param) { - case ISCSI_NET_PARAM_IPV4_ADDR: - len = sprintf(buf, "%pI4\n", &if_info.ip_addr.addr); - break; - case ISCSI_NET_PARAM_IPV6_ADDR: - len = sprintf(buf, "%pI6\n", &if_info.ip_addr.addr); - break; - case ISCSI_NET_PARAM_IPV4_BOOTPROTO: - if (!if_info.dhcp_state) - len = sprintf(buf, "static"); - else - len = sprintf(buf, "dhcp"); - break; - case ISCSI_NET_PARAM_IPV4_SUBNET: - len = sprintf(buf, "%pI4\n", &if_info.ip_addr.subnet_mask); - break; - default: - WARN_ON(1); - } - - return len; -} - -int be2iscsi_iface_get_param(struct iscsi_iface *iface, - enum iscsi_param_type param_type, - int param, char *buf) -{ - struct Scsi_Host *shost = iscsi_iface_to_shost(iface); - struct beiscsi_hba *phba = iscsi_host_priv(shost); - struct be_cmd_get_def_gateway_resp gateway; - int len = -ENOSYS; - - switch (param) { - case ISCSI_NET_PARAM_IPV4_ADDR: - case ISCSI_NET_PARAM_IPV4_SUBNET: - case ISCSI_NET_PARAM_IPV4_BOOTPROTO: - case ISCSI_NET_PARAM_IPV6_ADDR: - len = be2iscsi_get_if_param(phba, iface, param, buf); - break; - case ISCSI_NET_PARAM_IFACE_ENABLE: - len = sprintf(buf, "enabled"); - break; - case ISCSI_NET_PARAM_IPV4_GW: - memset(&gateway, 0, sizeof(gateway)); - len = mgmt_get_gateway(phba, BE2_IPV4, &gateway); - if (!len) - len = sprintf(buf, "%pI4\n", &gateway.ip_addr.addr); - break; - default: - len = -ENOSYS; - } - - return len; -} - /** * beiscsi_ep_get_param - get the iscsi parameter * @ep: pointer to iscsi ep @@ -518,7 +221,7 @@ int beiscsi_ep_get_param(struct iscsi_endpoint *ep, struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; int len = 0; - SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_get_param, param= %d\n", param); + SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_get_param, param= %d\n", param); switch (param) { case ISCSI_PARAM_CONN_PORT: @@ -575,121 +278,6 @@ int beiscsi_set_param(struct iscsi_cls_conn *cls_conn, return 0; } -/** - * beiscsi_get_initname - Read Initiator Name from flash - * @buf: buffer bointer - * @phba: The device priv structure instance - * - * returns number of bytes - */ -static int beiscsi_get_initname(char *buf, struct beiscsi_hba *phba) -{ - int rc; - unsigned int tag, wrb_num; - unsigned short status, extd_status; - struct be_mcc_wrb *wrb; - struct be_cmd_hba_name *resp; - struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; - - tag = be_cmd_get_initname(phba); - if (!tag) { - SE_DEBUG(DBG_LVL_1, "Getting Initiator Name Failed\n"); - return -EBUSY; - } else - wait_event_interruptible(phba->ctrl.mcc_wait[tag], - phba->ctrl.mcc_numtag[tag]); - - wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; - extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; - status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; - - if (status || extd_status) { - SE_DEBUG(DBG_LVL_1, "MailBox Command Failed with " - "status = %d extd_status = %d\n", - status, extd_status); - free_mcc_tag(&phba->ctrl, tag); - return -EAGAIN; - } - wrb = queue_get_wrb(mccq, wrb_num); - free_mcc_tag(&phba->ctrl, tag); - resp = embedded_payload(wrb); - rc = sprintf(buf, "%s\n", resp->initiator_name); - return rc; -} - -/** - * beiscsi_get_port_state - Get the Port State - * @shost : pointer to scsi_host structure - * - * returns number of bytes - */ -static void beiscsi_get_port_state(struct Scsi_Host *shost) -{ - struct beiscsi_hba *phba = iscsi_host_priv(shost); - struct iscsi_cls_host *ihost = shost->shost_data; - - ihost->port_state = (phba->state == BE_ADAPTER_UP) ? - ISCSI_PORT_STATE_UP : ISCSI_PORT_STATE_DOWN; -} - -/** - * beiscsi_get_port_speed - Get the Port Speed from Adapter - * @shost : pointer to scsi_host structure - * - * returns Success/Failure - */ -static int beiscsi_get_port_speed(struct Scsi_Host *shost) -{ - unsigned int tag, wrb_num; - unsigned short status, extd_status; - struct be_mcc_wrb *wrb; - struct be_cmd_ntwk_link_status_resp *resp; - struct beiscsi_hba *phba = iscsi_host_priv(shost); - struct iscsi_cls_host *ihost = shost->shost_data; - struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; - - tag = be_cmd_get_port_speed(phba); - if (!tag) { - SE_DEBUG(DBG_LVL_1, "Getting Port Speed Failed\n"); - return -EBUSY; - } else - wait_event_interruptible(phba->ctrl.mcc_wait[tag], - phba->ctrl.mcc_numtag[tag]); - - wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; - extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; - status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; - - if (status || extd_status) { - SE_DEBUG(DBG_LVL_1, "MailBox Command Failed with " - "status = %d extd_status = %d\n", - status, extd_status); - free_mcc_tag(&phba->ctrl, tag); - return -EAGAIN; - } - wrb = queue_get_wrb(mccq, wrb_num); - free_mcc_tag(&phba->ctrl, tag); - resp = embedded_payload(wrb); - - switch (resp->mac_speed) { - case BE2ISCSI_LINK_SPEED_10MBPS: - ihost->port_speed = ISCSI_PORT_SPEED_10MBPS; - break; - case BE2ISCSI_LINK_SPEED_100MBPS: - ihost->port_speed = BE2ISCSI_LINK_SPEED_100MBPS; - break; - case BE2ISCSI_LINK_SPEED_1GBPS: - ihost->port_speed = ISCSI_PORT_SPEED_1GBPS; - break; - case BE2ISCSI_LINK_SPEED_10GBPS: - ihost->port_speed = ISCSI_PORT_SPEED_10GBPS; - break; - default: - ihost->port_speed = ISCSI_PORT_SPEED_UNKNOWN; - } - return 0; -} - /** * beiscsi_get_host_param - get the iscsi parameter * @shost: pointer to scsi_host structure @@ -713,27 +301,6 @@ int beiscsi_get_host_param(struct Scsi_Host *shost, return status; } break; - case ISCSI_HOST_PARAM_INITIATOR_NAME: - status = beiscsi_get_initname(buf, phba); - if (status < 0) { - SE_DEBUG(DBG_LVL_1, - "Retreiving Initiator Name Failed\n"); - return status; - } - break; - case ISCSI_HOST_PARAM_PORT_STATE: - beiscsi_get_port_state(shost); - status = sprintf(buf, "%s\n", iscsi_get_port_state_name(shost)); - break; - case ISCSI_HOST_PARAM_PORT_SPEED: - status = beiscsi_get_port_speed(shost); - if (status) { - SE_DEBUG(DBG_LVL_1, - "Retreiving Port Speed Failed\n"); - return status; - } - status = sprintf(buf, "%s\n", iscsi_get_port_speed_name(shost)); - break; default: return iscsi_host_get_param(shost, param, buf); } @@ -742,21 +309,46 @@ int beiscsi_get_host_param(struct Scsi_Host *shost, int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba) { - struct be_cmd_get_nic_conf_resp resp; + struct be_cmd_resp_get_mac_addr *resp; + struct be_mcc_wrb *wrb; + unsigned int tag, wrb_num; + unsigned short status, extd_status; + struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; int rc; - if (strlen(phba->mac_address)) - return strlcpy(buf, phba->mac_address, PAGE_SIZE); + if (phba->read_mac_address) + return sysfs_format_mac(buf, phba->mac_address, + ETH_ALEN); - memset(&resp, 0, sizeof(resp)); - rc = mgmt_get_nic_conf(phba, &resp); - if (rc) - return rc; + tag = be_cmd_get_mac_addr(phba); + if (!tag) { + SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n"); + return -EBUSY; + } else + wait_event_interruptible(phba->ctrl.mcc_wait[tag], + phba->ctrl.mcc_numtag[tag]); - memcpy(phba->mac_address, resp.mac_address, ETH_ALEN); - return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); + wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; + extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; + status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; + if (status || extd_status) { + SE_DEBUG(DBG_LVL_1, "Failed to get be_cmd_get_mac_addr" + " status = %d extd_status = %d\n", + status, extd_status); + free_mcc_tag(&phba->ctrl, tag); + return -EAGAIN; + } + wrb = queue_get_wrb(mccq, wrb_num); + free_mcc_tag(&phba->ctrl, tag); + resp = embedded_payload(wrb); + memcpy(phba->mac_address, resp->mac_address, ETH_ALEN); + rc = sysfs_format_mac(buf, phba->mac_address, + ETH_ALEN); + phba->read_mac_address = 1; + return rc; } + /** * beiscsi_conn_get_stats - get the iscsi stats * @cls_conn: pointer to iscsi cls conn @@ -1144,24 +736,11 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) umode_t be2iscsi_attr_is_visible(int param_type, int param) { switch (param_type) { - case ISCSI_NET_PARAM: - switch (param) { - case ISCSI_NET_PARAM_IFACE_ENABLE: - case ISCSI_NET_PARAM_IPV4_ADDR: - case ISCSI_NET_PARAM_IPV4_SUBNET: - case ISCSI_NET_PARAM_IPV4_BOOTPROTO: - case ISCSI_NET_PARAM_IPV4_GW: - case ISCSI_NET_PARAM_IPV6_ADDR: - return S_IRUGO; - default: - return 0; - } case ISCSI_HOST_PARAM: switch (param) { case ISCSI_HOST_PARAM_HWADDRESS: + case ISCSI_HOST_PARAM_IPADDRESS: case ISCSI_HOST_PARAM_INITIATOR_NAME: - case ISCSI_HOST_PARAM_PORT_STATE: - case ISCSI_HOST_PARAM_PORT_SPEED: return S_IRUGO; default: return 0; diff --git a/trunk/drivers/scsi/be2iscsi/be_iscsi.h b/trunk/drivers/scsi/be2iscsi/be_iscsi.h index 8b826fc06bcc..5c45be134501 100644 --- a/trunk/drivers/scsi/be2iscsi/be_iscsi.h +++ b/trunk/drivers/scsi/be2iscsi/be_iscsi.h @@ -25,21 +25,6 @@ #define BE2_IPV4 0x1 #define BE2_IPV6 0x10 -#define BE2_DHCP_V4 0x05 - -#define NON_BLOCKING 0x0 -#define BLOCKING 0x1 - -void beiscsi_create_def_ifaces(struct beiscsi_hba *phba); - -void beiscsi_destroy_def_ifaces(struct beiscsi_hba *phba); - -int be2iscsi_iface_get_param(struct iscsi_iface *iface, - enum iscsi_param_type param_type, - int param, char *buf); - -int be2iscsi_iface_set_param(struct Scsi_Host *shost, - void *data, uint32_t count); umode_t be2iscsi_attr_is_visible(int param_type, int param); diff --git a/trunk/drivers/scsi/be2iscsi/be_main.c b/trunk/drivers/scsi/be2iscsi/be_main.c index 0b1d99c99fd2..375756fa95cf 100644 --- a/trunk/drivers/scsi/be2iscsi/be_main.c +++ b/trunk/drivers/scsi/be2iscsi/be_main.c @@ -28,11 +28,8 @@ #include #include #include -#include #include -#include -#include #include #include #include @@ -51,8 +48,7 @@ static unsigned int num_hba = 0; MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR); -MODULE_VERSION(BUILD_STR); -MODULE_AUTHOR("Emulex Corporation"); +MODULE_AUTHOR("ServerEngines Corporation"); MODULE_LICENSE("GPL"); module_param(be_iopoll_budget, int, 0); module_param(enable_msix, int, 0); @@ -151,15 +147,15 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc) struct invalidate_command_table *inv_tbl; struct be_dma_mem nonemb_cmd; unsigned int cid, tag, i, num_invalidate; + int rc = FAILED; /* invalidate iocbs */ cls_session = starget_to_session(scsi_target(sc->device)); session = cls_session->dd_data; spin_lock_bh(&session->lock); - if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN) { - spin_unlock_bh(&session->lock); - return FAILED; - } + if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN) + goto unlock; + conn = session->leadconn; beiscsi_conn = conn->dd_data; phba = beiscsi_conn->phba; @@ -212,6 +208,9 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc) pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, nonemb_cmd.va, nonemb_cmd.dma); return iscsi_eh_device_reset(sc); +unlock: + spin_unlock_bh(&session->lock); + return rc; } static ssize_t beiscsi_show_boot_tgt_info(void *data, int type, char *buf) @@ -231,10 +230,10 @@ static ssize_t beiscsi_show_boot_tgt_info(void *data, int type, char *buf) case ISCSI_BOOT_TGT_IP_ADDR: if (boot_conn->dest_ipaddr.ip_type == 0x1) rc = sprintf(buf, "%pI4\n", - (char *)&boot_conn->dest_ipaddr.addr); + (char *)&boot_conn->dest_ipaddr.ip_address); else rc = sprintf(str, "%pI6\n", - (char *)&boot_conn->dest_ipaddr.addr); + (char *)&boot_conn->dest_ipaddr.ip_address); break; case ISCSI_BOOT_TGT_PORT: rc = sprintf(str, "%d\n", boot_conn->dest_port); @@ -312,8 +311,12 @@ static ssize_t beiscsi_show_boot_eth_info(void *data, int type, char *buf) rc = sprintf(str, "0\n"); break; case ISCSI_BOOT_ETH_MAC: - rc = beiscsi_get_macaddr(str, phba); - break; + rc = beiscsi_get_macaddr(buf, phba); + if (rc < 0) { + SE_DEBUG(DBG_LVL_1, "beiscsi_get_macaddr Failed\n"); + return rc; + } + break; default: rc = -ENOSYS; break; @@ -391,7 +394,7 @@ MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); static struct scsi_host_template beiscsi_sht = { .module = THIS_MODULE, - .name = "Emulex 10Gbe open-iscsi Initiator Driver", + .name = "ServerEngines 10Gbe open-iscsi Initiator Driver", .proc_name = DRV_NAME, .queuecommand = iscsi_queuecommand, .change_queue_depth = iscsi_change_queue_depth, @@ -406,8 +409,6 @@ static struct scsi_host_template beiscsi_sht = { .max_sectors = BEISCSI_MAX_SECTORS, .cmd_per_lun = BEISCSI_CMD_PER_LUN, .use_clustering = ENABLE_CLUSTERING, - .vendor_id = SCSI_NL_VID_TYPE_PCI | BE_VENDOR_ID, - }; static struct scsi_transport_template *beiscsi_scsi_transport; @@ -434,7 +435,6 @@ static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev) phba->shost = shost; phba->pcidev = pci_dev_get(pcidev); pci_set_drvdata(pcidev, phba); - phba->interface_handle = 0xFFFFFFFF; if (iscsi_host_add(shost, &phba->pcidev->dev)) goto free_devices; @@ -544,7 +544,8 @@ static int be_ctrl_init(struct beiscsi_hba *phba, struct pci_dev *pdev) &mbox_mem_alloc->dma); if (!mbox_mem_alloc->va) { beiscsi_unmap_pci_function(phba); - return -ENOMEM; + status = -ENOMEM; + return status; } mbox_mem_align->size = sizeof(struct be_mcc_mailbox); @@ -1251,9 +1252,9 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn, task = pwrb_handle->pio_handle; io_task = task->dd_data; - spin_lock_bh(&phba->mgmt_sgl_lock); + spin_lock(&phba->mgmt_sgl_lock); free_mgmt_sgl_handle(phba, io_task->psgl_handle); - spin_unlock_bh(&phba->mgmt_sgl_lock); + spin_unlock(&phba->mgmt_sgl_lock); spin_lock_bh(&session->lock); free_wrb_handle(phba, pwrb_context, pwrb_handle); spin_unlock_bh(&session->lock); @@ -1369,6 +1370,8 @@ hwi_get_async_handle(struct beiscsi_hba *phba, struct be_bus_address phys_addr; struct list_head *pbusy_list; struct async_pdu_handle *pasync_handle = NULL; + int buffer_len = 0; + unsigned char buffer_index = -1; unsigned char is_header = 0; phys_addr.u.a32.address_lo = @@ -1389,11 +1392,22 @@ hwi_get_async_handle(struct beiscsi_hba *phba, pbusy_list = hwi_get_async_busy_list(pasync_ctx, 1, (pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe, index) / 32] & PDUCQE_INDEX_MASK)); + + buffer_len = (unsigned int)(phys_addr.u.a64.address - + pasync_ctx->async_header.pa_base.u.a64.address); + + buffer_index = buffer_len / + pasync_ctx->async_header.buffer_size; + break; case UNSOL_DATA_NOTIFY: pbusy_list = hwi_get_async_busy_list(pasync_ctx, 0, (pdpdu_cqe-> dw[offsetof(struct amap_i_t_dpdu_cqe, index) / 32] & PDUCQE_INDEX_MASK)); + buffer_len = (unsigned long)(phys_addr.u.a64.address - + pasync_ctx->async_data.pa_base.u. + a64.address); + buffer_index = buffer_len / pasync_ctx->async_data.buffer_size; break; default: pbusy_list = NULL; @@ -1404,9 +1418,11 @@ hwi_get_async_handle(struct beiscsi_hba *phba, return NULL; } + WARN_ON(!(buffer_index <= pasync_ctx->async_data.num_entries)); WARN_ON(list_empty(pbusy_list)); list_for_each_entry(pasync_handle, pbusy_list, link) { - if (pasync_handle->pa.u.a64.address == phys_addr.u.a64.address) + WARN_ON(pasync_handle->consumed); + if (pasync_handle->index == buffer_index) break; } @@ -1433,13 +1449,15 @@ hwi_update_async_writables(struct hwi_async_pdu_context *pasync_ctx, unsigned int num_entries, writables = 0; unsigned int *pep_read_ptr, *pwritables; - num_entries = pasync_ctx->num_entries; + if (is_header) { pep_read_ptr = &pasync_ctx->async_header.ep_read_ptr; pwritables = &pasync_ctx->async_header.writables; + num_entries = pasync_ctx->async_header.num_entries; } else { pep_read_ptr = &pasync_ctx->async_data.ep_read_ptr; pwritables = &pasync_ctx->async_data.writables; + num_entries = pasync_ctx->async_data.num_entries; } while ((*pep_read_ptr) != cq_index) { @@ -1473,13 +1491,14 @@ hwi_update_async_writables(struct hwi_async_pdu_context *pasync_ctx, return 0; } -static void hwi_free_async_msg(struct beiscsi_hba *phba, +static unsigned int hwi_free_async_msg(struct beiscsi_hba *phba, unsigned int cri) { struct hwi_controller *phwi_ctrlr; struct hwi_async_pdu_context *pasync_ctx; struct async_pdu_handle *pasync_handle, *tmp_handle; struct list_head *plist; + unsigned int i = 0; phwi_ctrlr = phba->phwi_ctrlr; pasync_ctx = HWI_GET_ASYNC_PDU_CTX(phwi_ctrlr); @@ -1489,20 +1508,23 @@ static void hwi_free_async_msg(struct beiscsi_hba *phba, list_for_each_entry_safe(pasync_handle, tmp_handle, plist, link) { list_del(&pasync_handle->link); - if (pasync_handle->is_header) { + if (i == 0) { list_add_tail(&pasync_handle->link, &pasync_ctx->async_header.free_list); pasync_ctx->async_header.free_entries++; + i++; } else { list_add_tail(&pasync_handle->link, &pasync_ctx->async_data.free_list); pasync_ctx->async_data.free_entries++; + i++; } } INIT_LIST_HEAD(&pasync_ctx->async_entry[cri].wait_queue.list); pasync_ctx->async_entry[cri].wait_queue.hdr_received = 0; pasync_ctx->async_entry[cri].wait_queue.bytes_received = 0; + return 0; } static struct phys_addr * @@ -1535,15 +1557,16 @@ static void hwi_post_async_buffers(struct beiscsi_hba *phba, phwi_ctrlr = phba->phwi_ctrlr; pasync_ctx = HWI_GET_ASYNC_PDU_CTX(phwi_ctrlr); - num_entries = pasync_ctx->num_entries; if (is_header) { + num_entries = pasync_ctx->async_header.num_entries; writables = min(pasync_ctx->async_header.writables, pasync_ctx->async_header.free_entries); pfree_link = pasync_ctx->async_header.free_list.next; host_write_num = pasync_ctx->async_header.host_write_ptr; ring_id = phwi_ctrlr->default_pdu_hdr.id; } else { + num_entries = pasync_ctx->async_data.num_entries; writables = min(pasync_ctx->async_data.writables, pasync_ctx->async_data.free_entries); pfree_link = pasync_ctx->async_data.free_list.next; @@ -1650,7 +1673,7 @@ hwi_fwd_async_msg(struct beiscsi_conn *beiscsi_conn, } memcpy(pfirst_buffer + offset, pasync_handle->pbuffer, buf_len); - offset += buf_len; + offset = buf_len; } index++; } @@ -1659,9 +1682,10 @@ hwi_fwd_async_msg(struct beiscsi_conn *beiscsi_conn, (beiscsi_conn->beiscsi_conn_cid - phba->fw_config.iscsi_cid_start), phdr, hdr_len, pfirst_buffer, - offset); + buf_len); - hwi_free_async_msg(phba, cri); + if (status == 0) + hwi_free_async_msg(phba, cri); return 0; } @@ -2205,7 +2229,7 @@ static int beiscsi_alloc_mem(struct beiscsi_hba *phba) struct mem_array *mem_arr, *mem_arr_orig; unsigned int i, j, alloc_size, curr_alloc_size; - phba->phwi_ctrlr = kzalloc(phba->params.hwi_ws_sz, GFP_KERNEL); + phba->phwi_ctrlr = kmalloc(phba->params.hwi_ws_sz, GFP_KERNEL); if (!phba->phwi_ctrlr) return -ENOMEM; @@ -2325,21 +2349,27 @@ static void iscsi_init_global_templates(struct beiscsi_hba *phba) AMAP_SET_BITS(struct amap_pdu_nop_out, i_bit, pnop_out, 0); } -static int beiscsi_init_wrb_handle(struct beiscsi_hba *phba) +static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba) { struct be_mem_descriptor *mem_descr_wrbh, *mem_descr_wrb; - struct wrb_handle *pwrb_handle = NULL; + struct wrb_handle *pwrb_handle; struct hwi_controller *phwi_ctrlr; struct hwi_wrb_context *pwrb_context; - struct iscsi_wrb *pwrb = NULL; - unsigned int num_cxn_wrbh = 0; - unsigned int num_cxn_wrb = 0, j, idx = 0, index; + struct iscsi_wrb *pwrb; + unsigned int num_cxn_wrbh; + unsigned int num_cxn_wrb, j, idx, index; mem_descr_wrbh = phba->init_mem; mem_descr_wrbh += HWI_MEM_WRBH; mem_descr_wrb = phba->init_mem; mem_descr_wrb += HWI_MEM_WRB; + + idx = 0; + pwrb_handle = mem_descr_wrbh->mem_array[idx].virtual_address; + num_cxn_wrbh = ((mem_descr_wrbh->mem_array[idx].size) / + ((sizeof(struct wrb_handle)) * + phba->params.wrbs_per_cxn)); phwi_ctrlr = phba->phwi_ctrlr; for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) { @@ -2347,32 +2377,12 @@ static int beiscsi_init_wrb_handle(struct beiscsi_hba *phba) pwrb_context->pwrb_handle_base = kzalloc(sizeof(struct wrb_handle *) * phba->params.wrbs_per_cxn, GFP_KERNEL); - if (!pwrb_context->pwrb_handle_base) { - shost_printk(KERN_ERR, phba->shost, - "Mem Alloc Failed. Failing to load\n"); - goto init_wrb_hndl_failed; - } pwrb_context->pwrb_handle_basestd = kzalloc(sizeof(struct wrb_handle *) * phba->params.wrbs_per_cxn, GFP_KERNEL); - if (!pwrb_context->pwrb_handle_basestd) { - shost_printk(KERN_ERR, phba->shost, - "Mem Alloc Failed. Failing to load\n"); - goto init_wrb_hndl_failed; - } - if (!num_cxn_wrbh) { - pwrb_handle = - mem_descr_wrbh->mem_array[idx].virtual_address; - num_cxn_wrbh = ((mem_descr_wrbh->mem_array[idx].size) / - ((sizeof(struct wrb_handle)) * - phba->params.wrbs_per_cxn)); - idx++; - } - pwrb_context->alloc_index = 0; - pwrb_context->wrb_handles_available = 0; - pwrb_context->free_index = 0; - if (num_cxn_wrbh) { + pwrb_context->alloc_index = 0; + pwrb_context->wrb_handles_available = 0; for (j = 0; j < phba->params.wrbs_per_cxn; j++) { pwrb_context->pwrb_handle_base[j] = pwrb_handle; pwrb_context->pwrb_handle_basestd[j] = @@ -2381,21 +2391,49 @@ static int beiscsi_init_wrb_handle(struct beiscsi_hba *phba) pwrb_handle->wrb_index = j; pwrb_handle++; } + pwrb_context->free_index = 0; + num_cxn_wrbh--; + } else { + idx++; + pwrb_handle = + mem_descr_wrbh->mem_array[idx].virtual_address; + num_cxn_wrbh = + ((mem_descr_wrbh->mem_array[idx].size) / + ((sizeof(struct wrb_handle)) * + phba->params.wrbs_per_cxn)); + pwrb_context->alloc_index = 0; + for (j = 0; j < phba->params.wrbs_per_cxn; j++) { + pwrb_context->pwrb_handle_base[j] = pwrb_handle; + pwrb_context->pwrb_handle_basestd[j] = + pwrb_handle; + pwrb_context->wrb_handles_available++; + pwrb_handle->wrb_index = j; + pwrb_handle++; + } + pwrb_context->free_index = 0; num_cxn_wrbh--; } } idx = 0; + pwrb = mem_descr_wrb->mem_array[idx].virtual_address; + num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) / + ((sizeof(struct iscsi_wrb) * + phba->params.wrbs_per_cxn)); for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) { pwrb_context = &phwi_ctrlr->wrb_context[index]; - if (!num_cxn_wrb) { + if (num_cxn_wrb) { + for (j = 0; j < phba->params.wrbs_per_cxn; j++) { + pwrb_handle = pwrb_context->pwrb_handle_base[j]; + pwrb_handle->pwrb = pwrb; + pwrb++; + } + num_cxn_wrb--; + } else { + idx++; pwrb = mem_descr_wrb->mem_array[idx].virtual_address; num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) / - ((sizeof(struct iscsi_wrb) * - phba->params.wrbs_per_cxn)); - idx++; - } - - if (num_cxn_wrb) { + ((sizeof(struct iscsi_wrb) * + phba->params.wrbs_per_cxn)); for (j = 0; j < phba->params.wrbs_per_cxn; j++) { pwrb_handle = pwrb_context->pwrb_handle_base[j]; pwrb_handle->pwrb = pwrb; @@ -2404,14 +2442,6 @@ static int beiscsi_init_wrb_handle(struct beiscsi_hba *phba) num_cxn_wrb--; } } - return 0; -init_wrb_hndl_failed: - for (j = index; j > 0; j--) { - pwrb_context = &phwi_ctrlr->wrb_context[j]; - kfree(pwrb_context->pwrb_handle_base); - kfree(pwrb_context->pwrb_handle_basestd); - } - return -ENOMEM; } static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) @@ -2420,7 +2450,7 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) struct hba_parameters *p = &phba->params; struct hwi_async_pdu_context *pasync_ctx; struct async_pdu_handle *pasync_header_h, *pasync_data_h; - unsigned int index, idx, num_per_mem, num_async_data; + unsigned int index; struct be_mem_descriptor *mem_descr; mem_descr = (struct be_mem_descriptor *)phba->init_mem; @@ -2432,8 +2462,10 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) pasync_ctx = phwi_ctrlr->phwi_ctxt->pasync_ctx; memset(pasync_ctx, 0, sizeof(*pasync_ctx)); - pasync_ctx->num_entries = p->asyncpdus_per_ctrl; - pasync_ctx->buffer_size = p->defpdu_hdr_sz; + pasync_ctx->async_header.num_entries = p->asyncpdus_per_ctrl; + pasync_ctx->async_header.buffer_size = p->defpdu_hdr_sz; + pasync_ctx->async_data.buffer_size = p->defpdu_data_sz; + pasync_ctx->async_data.num_entries = p->asyncpdus_per_ctrl; mem_descr = (struct be_mem_descriptor *)phba->init_mem; mem_descr += HWI_MEM_ASYNC_HEADER_BUF; @@ -2478,6 +2510,19 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) pasync_ctx->async_header.writables = 0; INIT_LIST_HEAD(&pasync_ctx->async_header.free_list); + mem_descr = (struct be_mem_descriptor *)phba->init_mem; + mem_descr += HWI_MEM_ASYNC_DATA_BUF; + if (mem_descr->mem_array[0].virtual_address) { + SE_DEBUG(DBG_LVL_8, + "hwi_init_async_pdu_ctx HWI_MEM_ASYNC_DATA_BUF" + "va=%p\n", mem_descr->mem_array[0].virtual_address); + } else + shost_printk(KERN_WARNING, phba->shost, + "No Virtual address\n"); + pasync_ctx->async_data.va_base = + mem_descr->mem_array[0].virtual_address; + pasync_ctx->async_data.pa_base.u.a64.address = + mem_descr->mem_array[0].bus_address.u.a64.address; mem_descr = (struct be_mem_descriptor *)phba->init_mem; mem_descr += HWI_MEM_ASYNC_DATA_RING; @@ -2508,25 +2553,6 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) pasync_data_h = (struct async_pdu_handle *)pasync_ctx->async_data.handle_base; - mem_descr = (struct be_mem_descriptor *)phba->init_mem; - mem_descr += HWI_MEM_ASYNC_DATA_BUF; - if (mem_descr->mem_array[0].virtual_address) { - SE_DEBUG(DBG_LVL_8, - "hwi_init_async_pdu_ctx HWI_MEM_ASYNC_DATA_BUF" - "va=%p\n", mem_descr->mem_array[0].virtual_address); - } else - shost_printk(KERN_WARNING, phba->shost, - "No Virtual address\n"); - idx = 0; - pasync_ctx->async_data.va_base = - mem_descr->mem_array[idx].virtual_address; - pasync_ctx->async_data.pa_base.u.a64.address = - mem_descr->mem_array[idx].bus_address.u.a64.address; - - num_async_data = ((mem_descr->mem_array[idx].size) / - phba->params.defpdu_data_sz); - num_per_mem = 0; - for (index = 0; index < p->asyncpdus_per_ctrl; index++) { pasync_header_h->cri = -1; pasync_header_h->index = (char)index; @@ -2552,29 +2578,14 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) pasync_data_h->cri = -1; pasync_data_h->index = (char)index; INIT_LIST_HEAD(&pasync_data_h->link); - - if (!num_async_data) { - num_per_mem = 0; - idx++; - pasync_ctx->async_data.va_base = - mem_descr->mem_array[idx].virtual_address; - pasync_ctx->async_data.pa_base.u.a64.address = - mem_descr->mem_array[idx]. - bus_address.u.a64.address; - - num_async_data = ((mem_descr->mem_array[idx].size) / - phba->params.defpdu_data_sz); - } pasync_data_h->pbuffer = (void *)((unsigned long) (pasync_ctx->async_data.va_base) + - (p->defpdu_data_sz * num_per_mem)); + (p->defpdu_data_sz * index)); pasync_data_h->pa.u.a64.address = pasync_ctx->async_data.pa_base.u.a64.address + - (p->defpdu_data_sz * num_per_mem); - num_per_mem++; - num_async_data--; + (p->defpdu_data_sz * index); list_add_tail(&pasync_data_h->link, &pasync_ctx->async_data.free_list); @@ -2902,11 +2913,9 @@ beiscsi_post_pages(struct beiscsi_hba *phba) static void be_queue_free(struct beiscsi_hba *phba, struct be_queue_info *q) { struct be_dma_mem *mem = &q->dma_mem; - if (mem->va) { + if (mem->va) pci_free_consistent(phba->pcidev, mem->size, mem->va, mem->dma); - mem->va = NULL; - } } static int be_queue_alloc(struct beiscsi_hba *phba, struct be_queue_info *q, @@ -3206,7 +3215,7 @@ static int hwi_init_port(struct beiscsi_hba *phba) error: shost_printk(KERN_ERR, phba->shost, "hwi_init_port failed"); hwi_cleanup(phba); - return status; + return -ENOMEM; } static int hwi_init_controller(struct beiscsi_hba *phba) @@ -3227,9 +3236,7 @@ static int hwi_init_controller(struct beiscsi_hba *phba) } iscsi_init_global_templates(phba); - if (beiscsi_init_wrb_handle(phba)) - return -ENOMEM; - + beiscsi_init_wrb_handle(phba); hwi_init_async_pdu_ctx(phba); if (hwi_init_port(phba) != 0) { shost_printk(KERN_ERR, phba->shost, @@ -3281,7 +3288,7 @@ static int beiscsi_init_controller(struct beiscsi_hba *phba) free_init: beiscsi_free_mem(phba); - return ret; + return -ENOMEM; } static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba) @@ -3468,8 +3475,8 @@ static void hwi_disable_intr(struct beiscsi_hba *phba) static int beiscsi_get_boot_info(struct beiscsi_hba *phba) { - struct be_cmd_get_boot_target_resp *boot_resp; - struct be_cmd_get_session_resp *session_resp; + struct be_cmd_resp_get_boot_target *boot_resp; + struct be_cmd_resp_get_session *session_resp; struct be_mcc_wrb *wrb; struct be_dma_mem nonemb_cmd; unsigned int tag, wrb_num; @@ -3477,9 +3484,9 @@ static int beiscsi_get_boot_info(struct beiscsi_hba *phba) struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; int ret = -ENOMEM; - tag = mgmt_get_boot_target(phba); + tag = beiscsi_get_boot_target(phba); if (!tag) { - SE_DEBUG(DBG_LVL_1, "beiscsi_get_boot_info Failed\n"); + SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n"); return -EAGAIN; } else wait_event_interruptible(phba->ctrl.mcc_wait[tag], @@ -3489,7 +3496,7 @@ static int beiscsi_get_boot_info(struct beiscsi_hba *phba) extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; if (status || extd_status) { - SE_DEBUG(DBG_LVL_1, "beiscsi_get_boot_info Failed" + SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed" " status = %d extd_status = %d\n", status, extd_status); free_mcc_tag(&phba->ctrl, tag); @@ -3515,8 +3522,8 @@ static int beiscsi_get_boot_info(struct beiscsi_hba *phba) } memset(nonemb_cmd.va, 0, sizeof(*session_resp)); - tag = mgmt_get_session_info(phba, boot_resp->boot_session_handle, - &nonemb_cmd); + tag = beiscsi_get_session_info(phba, + boot_resp->boot_session_handle, &nonemb_cmd); if (!tag) { SE_DEBUG(DBG_LVL_1, "beiscsi_get_session_info" " Failed\n"); @@ -3689,57 +3696,6 @@ static void beiscsi_clean_port(struct beiscsi_hba *phba) kfree(phba->ep_array); } -static void beiscsi_cleanup_task(struct iscsi_task *task) -{ - struct beiscsi_io_task *io_task = task->dd_data; - struct iscsi_conn *conn = task->conn; - struct beiscsi_conn *beiscsi_conn = conn->dd_data; - struct beiscsi_hba *phba = beiscsi_conn->phba; - struct beiscsi_session *beiscsi_sess = beiscsi_conn->beiscsi_sess; - struct hwi_wrb_context *pwrb_context; - struct hwi_controller *phwi_ctrlr; - - phwi_ctrlr = phba->phwi_ctrlr; - pwrb_context = &phwi_ctrlr->wrb_context[beiscsi_conn->beiscsi_conn_cid - - phba->fw_config.iscsi_cid_start]; - - if (io_task->cmd_bhs) { - pci_pool_free(beiscsi_sess->bhs_pool, io_task->cmd_bhs, - io_task->bhs_pa.u.a64.address); - io_task->cmd_bhs = NULL; - } - - if (task->sc) { - if (io_task->pwrb_handle) { - free_wrb_handle(phba, pwrb_context, - io_task->pwrb_handle); - io_task->pwrb_handle = NULL; - } - - if (io_task->psgl_handle) { - spin_lock(&phba->io_sgl_lock); - free_io_sgl_handle(phba, io_task->psgl_handle); - spin_unlock(&phba->io_sgl_lock); - io_task->psgl_handle = NULL; - } - } else { - if (!beiscsi_conn->login_in_progress) { - if (io_task->pwrb_handle) { - free_wrb_handle(phba, pwrb_context, - io_task->pwrb_handle); - io_task->pwrb_handle = NULL; - } - if (io_task->psgl_handle) { - spin_lock(&phba->mgmt_sgl_lock); - free_mgmt_sgl_handle(phba, - io_task->psgl_handle); - spin_unlock(&phba->mgmt_sgl_lock); - io_task->psgl_handle = NULL; - } - } - } -} - void beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn, struct beiscsi_offload_params *params) @@ -3748,19 +3704,12 @@ beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn, struct iscsi_target_context_update_wrb *pwrb = NULL; struct be_mem_descriptor *mem_descr; struct beiscsi_hba *phba = beiscsi_conn->phba; - struct iscsi_task *task = beiscsi_conn->task; - struct iscsi_session *session = task->conn->session; u32 doorbell = 0; /* * We can always use 0 here because it is reserved by libiscsi for * login/startup related tasks. */ - beiscsi_conn->login_in_progress = 0; - spin_lock_bh(&session->lock); - beiscsi_cleanup_task(task); - spin_unlock_bh(&session->lock); - pwrb_handle = alloc_wrb_handle(phba, (beiscsi_conn->beiscsi_conn_cid - phba->fw_config.iscsi_cid_start)); pwrb = (struct iscsi_target_context_update_wrb *)pwrb_handle->pwrb; @@ -3874,7 +3823,7 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) task->hdr = (struct iscsi_hdr *)&io_task->cmd_bhs->iscsi_hdr; task->hdr_max = sizeof(struct be_cmd_bhs); io_task->psgl_handle = NULL; - io_task->pwrb_handle = NULL; + io_task->psgl_handle = NULL; if (task->sc) { spin_lock(&phba->io_sgl_lock); @@ -3916,7 +3865,6 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) io_task->pwrb_handle = beiscsi_conn->plogin_wrb_handle; } - beiscsi_conn->task = task; } else { spin_lock(&phba->mgmt_sgl_lock); io_task->psgl_handle = alloc_mgmt_sgl_handle(phba); @@ -3959,11 +3907,53 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) io_task->pwrb_handle = NULL; pci_pool_free(beiscsi_sess->bhs_pool, io_task->cmd_bhs, io_task->bhs_pa.u.a64.address); - io_task->cmd_bhs = NULL; SE_DEBUG(DBG_LVL_1, "Alloc of SGL_ICD Failed\n"); return -ENOMEM; } +static void beiscsi_cleanup_task(struct iscsi_task *task) +{ + struct beiscsi_io_task *io_task = task->dd_data; + struct iscsi_conn *conn = task->conn; + struct beiscsi_conn *beiscsi_conn = conn->dd_data; + struct beiscsi_hba *phba = beiscsi_conn->phba; + struct beiscsi_session *beiscsi_sess = beiscsi_conn->beiscsi_sess; + struct hwi_wrb_context *pwrb_context; + struct hwi_controller *phwi_ctrlr; + + phwi_ctrlr = phba->phwi_ctrlr; + pwrb_context = &phwi_ctrlr->wrb_context[beiscsi_conn->beiscsi_conn_cid + - phba->fw_config.iscsi_cid_start]; + if (io_task->pwrb_handle) { + free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle); + io_task->pwrb_handle = NULL; + } + + if (io_task->cmd_bhs) { + pci_pool_free(beiscsi_sess->bhs_pool, io_task->cmd_bhs, + io_task->bhs_pa.u.a64.address); + } + + if (task->sc) { + if (io_task->psgl_handle) { + spin_lock(&phba->io_sgl_lock); + free_io_sgl_handle(phba, io_task->psgl_handle); + spin_unlock(&phba->io_sgl_lock); + io_task->psgl_handle = NULL; + } + } else { + if (task->hdr && + ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN)) + return; + if (io_task->psgl_handle) { + spin_lock(&phba->mgmt_sgl_lock); + free_mgmt_sgl_handle(phba, io_task->psgl_handle); + spin_unlock(&phba->mgmt_sgl_lock); + io_task->psgl_handle = NULL; + } + } +} + static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg, unsigned int num_sg, unsigned int xferlen, unsigned int writedir) @@ -4003,8 +3993,7 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg, &io_task->cmd_bhs->iscsi_hdr.lun, sizeof(struct scsi_lun)); AMAP_SET_BITS(struct amap_iscsi_wrb, lun, pwrb, - cpu_to_be16(*(unsigned short *) - &io_task->cmd_bhs->iscsi_hdr.lun)); + cpu_to_be16(*(unsigned short *)&io_task->cmd_bhs->iscsi_hdr.lun)); AMAP_SET_BITS(struct amap_iscsi_wrb, r2t_exp_dtl, pwrb, xferlen); AMAP_SET_BITS(struct amap_iscsi_wrb, wrb_idx, pwrb, io_task->pwrb_handle->wrb_index); @@ -4137,76 +4126,6 @@ static int beiscsi_task_xmit(struct iscsi_task *task) return beiscsi_iotask(task, sg, num_sg, xferlen, writedir); } -/** - * beiscsi_bsg_request - handle bsg request from ISCSI transport - * @job: job to handle - */ -static int beiscsi_bsg_request(struct bsg_job *job) -{ - struct Scsi_Host *shost; - struct beiscsi_hba *phba; - struct iscsi_bsg_request *bsg_req = job->request; - int rc = -EINVAL; - unsigned int tag; - struct be_dma_mem nonemb_cmd; - struct be_cmd_resp_hdr *resp; - struct iscsi_bsg_reply *bsg_reply = job->reply; - unsigned short status, extd_status; - - shost = iscsi_job_to_shost(job); - phba = iscsi_host_priv(shost); - - switch (bsg_req->msgcode) { - case ISCSI_BSG_HST_VENDOR: - nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev, - job->request_payload.payload_len, - &nonemb_cmd.dma); - if (nonemb_cmd.va == NULL) { - SE_DEBUG(DBG_LVL_1, "Failed to allocate memory for " - "beiscsi_bsg_request\n"); - return -EIO; - } - tag = mgmt_vendor_specific_fw_cmd(&phba->ctrl, phba, job, - &nonemb_cmd); - if (!tag) { - SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n"); - pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, - nonemb_cmd.va, nonemb_cmd.dma); - return -EAGAIN; - } else - wait_event_interruptible(phba->ctrl.mcc_wait[tag], - phba->ctrl.mcc_numtag[tag]); - extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; - status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; - free_mcc_tag(&phba->ctrl, tag); - resp = (struct be_cmd_resp_hdr *)nonemb_cmd.va; - sg_copy_from_buffer(job->reply_payload.sg_list, - job->reply_payload.sg_cnt, - nonemb_cmd.va, (resp->response_length - + sizeof(*resp))); - bsg_reply->reply_payload_rcv_len = resp->response_length; - bsg_reply->result = status; - bsg_job_done(job, bsg_reply->result, - bsg_reply->reply_payload_rcv_len); - pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, - nonemb_cmd.va, nonemb_cmd.dma); - if (status || extd_status) { - SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed" - " status = %d extd_status = %d\n", - status, extd_status); - return -EIO; - } - break; - - default: - SE_DEBUG(DBG_LVL_1, "Unsupported bsg command: 0x%x\n", - bsg_req->msgcode); - break; - } - - return rc; -} - static void beiscsi_quiesce(struct beiscsi_hba *phba) { struct hwi_controller *phwi_ctrlr; @@ -4264,7 +4183,6 @@ static void beiscsi_remove(struct pci_dev *pcidev) return; } - beiscsi_destroy_def_ifaces(phba); beiscsi_quiesce(phba); iscsi_boot_destroy_kset(phba->boot_kset); iscsi_host_remove(phba->shost); @@ -4349,11 +4267,8 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, phba->num_cpus = num_cpus; SE_DEBUG(DBG_LVL_8, "num_cpus = %d\n", phba->num_cpus); - if (enable_msix) { + if (enable_msix) beiscsi_msix_enable(phba); - if (!phba->msix_enabled) - phba->num_cpus = 1; - } ret = be_ctrl_init(phba, pcidev); if (ret) { shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-" @@ -4451,9 +4366,8 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, * iscsi boot. */ shost_printk(KERN_ERR, phba->shost, "Could not set up " - "iSCSI boot info.\n"); + "iSCSI boot info."); - beiscsi_create_def_ifaces(phba); SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED\n\n\n"); return 0; @@ -4504,8 +4418,6 @@ struct iscsi_transport beiscsi_iscsi_transport = { .bind_conn = beiscsi_conn_bind, .destroy_conn = iscsi_conn_teardown, .attr_is_visible = be2iscsi_attr_is_visible, - .set_iface_param = be2iscsi_iface_set_param, - .get_iface_param = be2iscsi_iface_get_param, .set_param = beiscsi_set_param, .get_conn_param = iscsi_conn_get_param, .get_session_param = iscsi_session_get_param, @@ -4523,7 +4435,6 @@ struct iscsi_transport beiscsi_iscsi_transport = { .ep_poll = beiscsi_ep_poll, .ep_disconnect = beiscsi_ep_disconnect, .session_recovery_timedout = iscsi_session_recovery_timedout, - .bsg_request = beiscsi_bsg_request, }; static struct pci_driver beiscsi_pci_driver = { diff --git a/trunk/drivers/scsi/be2iscsi/be_main.h b/trunk/drivers/scsi/be2iscsi/be_main.h index 40fea6ec879c..b4a06d5e5f9e 100644 --- a/trunk/drivers/scsi/be2iscsi/be_main.h +++ b/trunk/drivers/scsi/be2iscsi/be_main.h @@ -34,9 +34,9 @@ #include "be.h" #define DRV_NAME "be2iscsi" -#define BUILD_STR "4.2.162.0" -#define BE_NAME "Emulex OneConnect" \ - "Open-iSCSI Driver version" BUILD_STR +#define BUILD_STR "4.1.239.0" +#define BE_NAME "ServerEngines BladeEngine2" \ + "Linux iSCSI Driver version" BUILD_STR #define DRV_DESC BE_NAME " " "Driver" #define BE_VENDOR_ID 0x19A2 @@ -316,8 +316,6 @@ struct beiscsi_hba { struct iscsi_endpoint **ep_array; struct iscsi_boot_kset *boot_kset; struct Scsi_Host *shost; - struct iscsi_iface *ipv4_iface; - struct iscsi_iface *ipv6_iface; struct { /** * group together since they are used most frequently @@ -347,7 +345,7 @@ struct beiscsi_hba { struct work_struct work_cqs; /* The work being queued */ struct be_ctrl_info ctrl; unsigned int generation; - unsigned int interface_handle; + unsigned int read_mac_address; struct mgmt_session_info boot_sess; struct invalidate_command_table inv_tbl[128]; @@ -527,6 +525,8 @@ struct hwi_async_pdu_context { unsigned int free_entries; unsigned int busy_entries; + unsigned int buffer_size; + unsigned int num_entries; struct list_head free_list; } async_header; @@ -543,12 +543,11 @@ struct hwi_async_pdu_context { unsigned int free_entries; unsigned int busy_entries; + unsigned int buffer_size; struct list_head free_list; + unsigned int num_entries; } async_data; - unsigned int buffer_size; - unsigned int num_entries; - /** * This is a varying size list! Do not add anything * after this entry!! diff --git a/trunk/drivers/scsi/be2iscsi/be_mgmt.c b/trunk/drivers/scsi/be2iscsi/be_mgmt.c index 01bb04cd9e75..44762cfa3e12 100644 --- a/trunk/drivers/scsi/be2iscsi/be_mgmt.c +++ b/trunk/drivers/scsi/be2iscsi/be_mgmt.c @@ -17,17 +17,15 @@ * Costa Mesa, CA 92626 */ -#include -#include -#include #include "be_mgmt.h" #include "be_iscsi.h" +#include -unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba) +unsigned int beiscsi_get_boot_target(struct beiscsi_hba *phba) { struct be_ctrl_info *ctrl = &phba->ctrl; struct be_mcc_wrb *wrb; - struct be_cmd_get_boot_target_req *req; + struct be_cmd_req_get_mac_addr *req; unsigned int tag = 0; SE_DEBUG(DBG_LVL_8, "In bescsi_get_boot_target\n"); @@ -44,22 +42,22 @@ unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba) be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET, - sizeof(struct be_cmd_get_boot_target_resp)); + sizeof(*req)); be_mcc_notify(phba); spin_unlock(&ctrl->mbox_lock); return tag; } -unsigned int mgmt_get_session_info(struct beiscsi_hba *phba, - u32 boot_session_handle, - struct be_dma_mem *nonemb_cmd) +unsigned int beiscsi_get_session_info(struct beiscsi_hba *phba, + u32 boot_session_handle, + struct be_dma_mem *nonemb_cmd) { struct be_ctrl_info *ctrl = &phba->ctrl; struct be_mcc_wrb *wrb; unsigned int tag = 0; - struct be_cmd_get_session_req *req; - struct be_cmd_get_session_resp *resp; + struct be_cmd_req_get_session *req; + struct be_cmd_resp_get_session *resp; struct be_sge *sge; SE_DEBUG(DBG_LVL_8, "In beiscsi_get_session_info\n"); @@ -189,72 +187,6 @@ int mgmt_check_supported_fw(struct be_ctrl_info *ctrl, return status; } -unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl, - struct beiscsi_hba *phba, - struct bsg_job *job, - struct be_dma_mem *nonemb_cmd) -{ - struct be_cmd_resp_hdr *resp; - struct be_mcc_wrb *wrb = wrb_from_mccq(phba); - struct be_sge *mcc_sge = nonembedded_sgl(wrb); - unsigned int tag = 0; - struct iscsi_bsg_request *bsg_req = job->request; - struct be_bsg_vendor_cmd *req = nonemb_cmd->va; - unsigned short region, sector_size, sector, offset; - - nonemb_cmd->size = job->request_payload.payload_len; - memset(nonemb_cmd->va, 0, nonemb_cmd->size); - resp = nonemb_cmd->va; - region = bsg_req->rqst_data.h_vendor.vendor_cmd[1]; - sector_size = bsg_req->rqst_data.h_vendor.vendor_cmd[2]; - sector = bsg_req->rqst_data.h_vendor.vendor_cmd[3]; - offset = bsg_req->rqst_data.h_vendor.vendor_cmd[4]; - req->region = region; - req->sector = sector; - req->offset = offset; - spin_lock(&ctrl->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); - - switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) { - case BEISCSI_WRITE_FLASH: - offset = sector * sector_size + offset; - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, - OPCODE_COMMON_WRITE_FLASH, sizeof(*req)); - sg_copy_to_buffer(job->request_payload.sg_list, - job->request_payload.sg_cnt, - nonemb_cmd->va + offset, job->request_len); - break; - case BEISCSI_READ_FLASH: - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, - OPCODE_COMMON_READ_FLASH, sizeof(*req)); - break; - default: - shost_printk(KERN_WARNING, phba->shost, - "Unsupported cmd = 0x%x\n\n", bsg_req->rqst_data. - h_vendor.vendor_cmd[0]); - spin_unlock(&ctrl->mbox_lock); - return -ENOSYS; - } - - tag = alloc_mcc_tag(phba); - if (!tag) { - spin_unlock(&ctrl->mbox_lock); - return tag; - } - - be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, - job->request_payload.sg_cnt); - mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); - mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); - mcc_sge->len = cpu_to_le32(nonemb_cmd->size); - wrb->tag0 |= tag; - - be_mcc_notify(phba); - - spin_unlock(&ctrl->mbox_lock); - return tag; -} - int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute) { struct be_ctrl_info *ctrl = &phba->ctrl; @@ -396,6 +328,7 @@ int mgmt_open_connection(struct beiscsi_hba *phba, struct sockaddr *dst_addr, struct beiscsi_endpoint *beiscsi_ep, struct be_dma_mem *nonemb_cmd) + { struct hwi_controller *phwi_ctrlr; struct hwi_context_memory *phwi_context; @@ -441,17 +374,17 @@ int mgmt_open_connection(struct beiscsi_hba *phba, if (dst_addr->sa_family == PF_INET) { __be32 s_addr = daddr_in->sin_addr.s_addr; req->ip_address.ip_type = BE2_IPV4; - req->ip_address.addr[0] = s_addr & 0x000000ff; - req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8; - req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16; - req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24; + req->ip_address.ip_address[0] = s_addr & 0x000000ff; + req->ip_address.ip_address[1] = (s_addr & 0x0000ff00) >> 8; + req->ip_address.ip_address[2] = (s_addr & 0x00ff0000) >> 16; + req->ip_address.ip_address[3] = (s_addr & 0xff000000) >> 24; req->tcp_port = ntohs(daddr_in->sin_port); beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr; beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port); beiscsi_ep->ip_type = BE2_IPV4; } else if (dst_addr->sa_family == PF_INET6) { req->ip_address.ip_type = BE2_IPV6; - memcpy(&req->ip_address.addr, + memcpy(&req->ip_address.ip_address, &daddr_in6->sin6_addr.in6_u.u6_addr8, 16); req->tcp_port = ntohs(daddr_in6->sin6_port); beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port); @@ -486,426 +419,14 @@ int mgmt_open_connection(struct beiscsi_hba *phba, return tag; } -unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba) -{ - struct be_ctrl_info *ctrl = &phba->ctrl; - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_cmd_get_all_if_id_req *req = embedded_payload(wrb); - struct be_cmd_get_all_if_id_req *pbe_allid = req; - int status = 0; - - memset(wrb, 0, sizeof(*wrb)); - - spin_lock(&ctrl->mbox_lock); - - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, - OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID, - sizeof(*req)); - status = be_mbox_notify(ctrl); - if (!status) - phba->interface_handle = pbe_allid->if_hndl_list[0]; - else { - shost_printk(KERN_WARNING, phba->shost, - "Failed in mgmt_get_all_if_id\n"); - } - spin_unlock(&ctrl->mbox_lock); - - return status; -} - -static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba, - struct be_dma_mem *nonemb_cmd, void *resp_buf, - int resp_buf_len) +unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba) { struct be_ctrl_info *ctrl = &phba->ctrl; - struct be_mcc_wrb *wrb = wrb_from_mccq(phba); - unsigned short status, extd_status; - struct be_sge *sge; - unsigned int tag; - int rc = 0; - - spin_lock(&ctrl->mbox_lock); - tag = alloc_mcc_tag(phba); - if (!tag) { - spin_unlock(&ctrl->mbox_lock); - rc = -ENOMEM; - goto free_cmd; - } - memset(wrb, 0, sizeof(*wrb)); - wrb->tag0 |= tag; - sge = nonembedded_sgl(wrb); - - be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1); - sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); - sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); - sge->len = cpu_to_le32(nonemb_cmd->size); - - be_mcc_notify(phba); - spin_unlock(&ctrl->mbox_lock); - - wait_event_interruptible(phba->ctrl.mcc_wait[tag], - phba->ctrl.mcc_numtag[tag]); - - extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; - status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; - if (status || extd_status) { - SE_DEBUG(DBG_LVL_1, - "mgmt_exec_nonemb_cmd Failed status = %d" - "extd_status = %d\n", status, extd_status); - rc = -EIO; - goto free_tag; - } - - if (resp_buf) - memcpy(resp_buf, nonemb_cmd->va, resp_buf_len); - -free_tag: - free_mcc_tag(&phba->ctrl, tag); -free_cmd: - pci_free_consistent(ctrl->pdev, nonemb_cmd->size, - nonemb_cmd->va, nonemb_cmd->dma); - return rc; -} - -static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd, - int iscsi_cmd, int size) -{ - cmd->va = pci_alloc_consistent(phba->ctrl.pdev, sizeof(size), - &cmd->dma); - if (!cmd->va) { - SE_DEBUG(DBG_LVL_1, "Failed to allocate memory for if info\n"); - return -ENOMEM; - } - memset(cmd->va, 0, sizeof(size)); - cmd->size = size; - be_cmd_hdr_prepare(cmd->va, CMD_SUBSYSTEM_ISCSI, iscsi_cmd, size); - return 0; -} - -static int -mgmt_static_ip_modify(struct beiscsi_hba *phba, - struct be_cmd_get_if_info_resp *if_info, - struct iscsi_iface_param_info *ip_param, - struct iscsi_iface_param_info *subnet_param, - uint32_t ip_action) -{ - struct be_cmd_set_ip_addr_req *req; - struct be_dma_mem nonemb_cmd; - uint32_t ip_type; - int rc; - - rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, - OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR, - sizeof(*req)); - if (rc) - return rc; - - ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ? - BE2_IPV6 : BE2_IPV4 ; - - req = nonemb_cmd.va; - req->ip_params.record_entry_count = 1; - req->ip_params.ip_record.action = ip_action; - req->ip_params.ip_record.interface_hndl = - phba->interface_handle; - req->ip_params.ip_record.ip_addr.size_of_structure = - sizeof(struct be_ip_addr_subnet_format); - req->ip_params.ip_record.ip_addr.ip_type = ip_type; - - if (ip_action == IP_ACTION_ADD) { - memcpy(req->ip_params.ip_record.ip_addr.addr, ip_param->value, - ip_param->len); - - if (subnet_param) - memcpy(req->ip_params.ip_record.ip_addr.subnet_mask, - subnet_param->value, subnet_param->len); - } else { - memcpy(req->ip_params.ip_record.ip_addr.addr, - if_info->ip_addr.addr, ip_param->len); - - memcpy(req->ip_params.ip_record.ip_addr.subnet_mask, - if_info->ip_addr.subnet_mask, ip_param->len); - } - - rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0); - if (rc < 0) - shost_printk(KERN_WARNING, phba->shost, - "Failed to Modify existing IP Address\n"); - return rc; -} - -static int mgmt_modify_gateway(struct beiscsi_hba *phba, uint8_t *gt_addr, - uint32_t gtway_action, uint32_t param_len) -{ - struct be_cmd_set_def_gateway_req *req; - struct be_dma_mem nonemb_cmd; - int rt_val; - - - rt_val = mgmt_alloc_cmd_data(phba, &nonemb_cmd, - OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY, - sizeof(*req)); - if (rt_val) - return rt_val; - - req = nonemb_cmd.va; - req->action = gtway_action; - req->ip_addr.ip_type = BE2_IPV4; - - memcpy(req->ip_addr.addr, gt_addr, param_len); - - return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0); -} - -int mgmt_set_ip(struct beiscsi_hba *phba, - struct iscsi_iface_param_info *ip_param, - struct iscsi_iface_param_info *subnet_param, - uint32_t boot_proto) -{ - struct be_cmd_get_def_gateway_resp gtway_addr_set; - struct be_cmd_get_if_info_resp if_info; - struct be_cmd_set_dhcp_req *dhcpreq; - struct be_cmd_rel_dhcp_req *reldhcp; - struct be_dma_mem nonemb_cmd; - uint8_t *gtway_addr; - uint32_t ip_type; - int rc; - - if (mgmt_get_all_if_id(phba)) - return -EIO; - - memset(&if_info, 0, sizeof(if_info)); - ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ? - BE2_IPV6 : BE2_IPV4 ; - - rc = mgmt_get_if_info(phba, ip_type, &if_info); - if (rc) - return rc; - - if (boot_proto == ISCSI_BOOTPROTO_DHCP) { - if (if_info.dhcp_state) { - shost_printk(KERN_WARNING, phba->shost, - "DHCP Already Enabled\n"); - return 0; - } - /* The ip_param->len is 1 in DHCP case. Setting - proper IP len as this it is used while - freeing the Static IP. - */ - ip_param->len = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ? - IP_V6_LEN : IP_V4_LEN; - - } else { - if (if_info.dhcp_state) { - - memset(&if_info, 0, sizeof(if_info)); - rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, - OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR, - sizeof(*reldhcp)); - - if (rc) - return rc; - - reldhcp = nonemb_cmd.va; - reldhcp->interface_hndl = phba->interface_handle; - reldhcp->ip_type = ip_type; - - rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0); - if (rc < 0) { - shost_printk(KERN_WARNING, phba->shost, - "Failed to Delete existing dhcp\n"); - return rc; - } - } - } - - /* Delete the Static IP Set */ - if (if_info.ip_addr.addr[0]) { - rc = mgmt_static_ip_modify(phba, &if_info, ip_param, NULL, - IP_ACTION_DEL); - if (rc) - return rc; - } - - /* Delete the Gateway settings if mode change is to DHCP */ - if (boot_proto == ISCSI_BOOTPROTO_DHCP) { - memset(>way_addr_set, 0, sizeof(gtway_addr_set)); - rc = mgmt_get_gateway(phba, BE2_IPV4, >way_addr_set); - if (rc) { - shost_printk(KERN_WARNING, phba->shost, - "Failed to Get Gateway Addr\n"); - return rc; - } - - if (gtway_addr_set.ip_addr.addr[0]) { - gtway_addr = (uint8_t *)>way_addr_set.ip_addr.addr; - rc = mgmt_modify_gateway(phba, gtway_addr, - IP_ACTION_DEL, IP_V4_LEN); - - if (rc) { - shost_printk(KERN_WARNING, phba->shost, - "Failed to clear Gateway Addr Set\n"); - return rc; - } - } - } - - /* Set Adapter to DHCP/Static Mode */ - if (boot_proto == ISCSI_BOOTPROTO_DHCP) { - rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, - OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR, - sizeof(*dhcpreq)); - if (rc) - return rc; - - dhcpreq = nonemb_cmd.va; - dhcpreq->flags = BLOCKING; - dhcpreq->retry_count = 1; - dhcpreq->interface_hndl = phba->interface_handle; - dhcpreq->ip_type = BE2_DHCP_V4; - - return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0); - } else { - return mgmt_static_ip_modify(phba, &if_info, ip_param, - subnet_param, IP_ACTION_ADD); - } - - return rc; -} - -int mgmt_set_gateway(struct beiscsi_hba *phba, - struct iscsi_iface_param_info *gateway_param) -{ - struct be_cmd_get_def_gateway_resp gtway_addr_set; - uint8_t *gtway_addr; - int rt_val; - - memset(>way_addr_set, 0, sizeof(gtway_addr_set)); - rt_val = mgmt_get_gateway(phba, BE2_IPV4, >way_addr_set); - if (rt_val) { - shost_printk(KERN_WARNING, phba->shost, - "Failed to Get Gateway Addr\n"); - return rt_val; - } - - if (gtway_addr_set.ip_addr.addr[0]) { - gtway_addr = (uint8_t *)>way_addr_set.ip_addr.addr; - rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_DEL, - gateway_param->len); - if (rt_val) { - shost_printk(KERN_WARNING, phba->shost, - "Failed to clear Gateway Addr Set\n"); - return rt_val; - } - } - - gtway_addr = (uint8_t *)&gateway_param->value; - rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_ADD, - gateway_param->len); - - if (rt_val) - shost_printk(KERN_WARNING, phba->shost, - "Failed to Set Gateway Addr\n"); - - return rt_val; -} - -int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type, - struct be_cmd_get_def_gateway_resp *gateway) -{ - struct be_cmd_get_def_gateway_req *req; - struct be_dma_mem nonemb_cmd; - int rc; - - rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, - OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY, - sizeof(*gateway)); - if (rc) - return rc; - - req = nonemb_cmd.va; - req->ip_type = ip_type; - - return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, gateway, - sizeof(*gateway)); -} - -int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type, - struct be_cmd_get_if_info_resp *if_info) -{ - struct be_cmd_get_if_info_req *req; - struct be_dma_mem nonemb_cmd; - int rc; - - if (mgmt_get_all_if_id(phba)) - return -EIO; - - rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, - OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO, - sizeof(*if_info)); - if (rc) - return rc; - - req = nonemb_cmd.va; - req->interface_hndl = phba->interface_handle; - req->ip_type = ip_type; - - return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, if_info, - sizeof(*if_info)); -} - -int mgmt_get_nic_conf(struct beiscsi_hba *phba, - struct be_cmd_get_nic_conf_resp *nic) -{ - struct be_dma_mem nonemb_cmd; - int rc; - - rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, - OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG, - sizeof(*nic)); - if (rc) - return rc; - - return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, nic, sizeof(*nic)); -} - - - -unsigned int be_cmd_get_initname(struct beiscsi_hba *phba) -{ - unsigned int tag = 0; struct be_mcc_wrb *wrb; - struct be_cmd_hba_name *req; - struct be_ctrl_info *ctrl = &phba->ctrl; - - spin_lock(&ctrl->mbox_lock); - tag = alloc_mcc_tag(phba); - if (!tag) { - spin_unlock(&ctrl->mbox_lock); - return tag; - } - - wrb = wrb_from_mccq(phba); - req = embedded_payload(wrb); - wrb->tag0 |= tag; - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, - OPCODE_ISCSI_INI_CFG_GET_HBA_NAME, - sizeof(*req)); - - be_mcc_notify(phba); - spin_unlock(&ctrl->mbox_lock); - return tag; -} - -unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba) -{ + struct be_cmd_req_get_mac_addr *req; unsigned int tag = 0; - struct be_mcc_wrb *wrb; - struct be_cmd_ntwk_link_status_req *req; - struct be_ctrl_info *ctrl = &phba->ctrl; + SE_DEBUG(DBG_LVL_8, "In be_cmd_get_mac_addr\n"); spin_lock(&ctrl->mbox_lock); tag = alloc_mcc_tag(phba); if (!tag) { @@ -917,11 +438,12 @@ unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba) req = embedded_payload(wrb); wrb->tag0 |= tag; be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, - sizeof(*req)); + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, + OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG, + sizeof(*req)); be_mcc_notify(phba); spin_unlock(&ctrl->mbox_lock); return tag; } + diff --git a/trunk/drivers/scsi/be2iscsi/be_mgmt.h b/trunk/drivers/scsi/be2iscsi/be_mgmt.h index 5c2e37693ca8..08428824ace2 100644 --- a/trunk/drivers/scsi/be2iscsi/be_mgmt.h +++ b/trunk/drivers/scsi/be2iscsi/be_mgmt.h @@ -20,16 +20,11 @@ #ifndef _BEISCSI_MGMT_ #define _BEISCSI_MGMT_ -#include +#include +#include #include "be_iscsi.h" #include "be_main.h" -#define IP_ACTION_ADD 0x01 -#define IP_ACTION_DEL 0x02 - -#define IP_V6_LEN 16 -#define IP_V4_LEN 4 - /** * Pseudo amap definition in which each bit of the actual structure is defined * as a byte: used to calculate offset/shift/mask of each field @@ -103,10 +98,6 @@ unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba, struct invalidate_command_table *inv_tbl, unsigned int num_invalidate, unsigned int cid, struct be_dma_mem *nonemb_cmd); -unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl, - struct beiscsi_hba *phba, - struct bsg_job *job, - struct be_dma_mem *nonemb_cmd); struct iscsi_invalidate_connection_params_in { struct be_cmd_req_hdr hdr; @@ -213,13 +204,6 @@ struct be_mgmt_controller_attributes_resp { struct mgmt_controller_attributes params; } __packed; -struct be_bsg_vendor_cmd { - struct be_cmd_req_hdr hdr; - unsigned short region; - unsigned short offset; - unsigned short sector; -} __packed; - /* configuration management */ #define GET_MGMT_CONTROLLER_WS(phba) (phba->pmgmt_ws) @@ -235,15 +219,12 @@ struct be_bsg_vendor_cmd { /* the CMD_RESPONSE_HEADER */ #define ISCSI_GET_PDU_TEMPLATE_ADDRESS(pc, pa) {\ - pa->lo = phba->init_mem[ISCSI_MEM_GLOBAL_HEADER].mem_array[0].\ + pa->lo = phba->init_mem[ISCSI_MEM_GLOBAL_HEADER].mem_array[0].\ bus_address.u.a32.address_lo; \ - pa->hi = phba->init_mem[ISCSI_MEM_GLOBAL_HEADER].mem_array[0].\ + pa->hi = phba->init_mem[ISCSI_MEM_GLOBAL_HEADER].mem_array[0].\ bus_address.u.a32.address_hi; \ } -#define BEISCSI_WRITE_FLASH 0 -#define BEISCSI_READ_FLASH 1 - struct beiscsi_endpoint { struct beiscsi_hba *phba; struct beiscsi_sess *sess; @@ -267,27 +248,4 @@ unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba, unsigned short issue_reset, unsigned short savecfg_flag); -int mgmt_set_ip(struct beiscsi_hba *phba, - struct iscsi_iface_param_info *ip_param, - struct iscsi_iface_param_info *subnet_param, - uint32_t boot_proto); - -unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba); - -unsigned int mgmt_get_session_info(struct beiscsi_hba *phba, - u32 boot_session_handle, - struct be_dma_mem *nonemb_cmd); - -int mgmt_get_nic_conf(struct beiscsi_hba *phba, - struct be_cmd_get_nic_conf_resp *mac); - -int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type, - struct be_cmd_get_if_info_resp *if_info); - -int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type, - struct be_cmd_get_def_gateway_resp *gateway); - -int mgmt_set_gateway(struct beiscsi_hba *phba, - struct iscsi_iface_param_info *gateway_param); - #endif diff --git a/trunk/drivers/scsi/bfa/bfa_fcs.h b/trunk/drivers/scsi/bfa/bfa_fcs.h index 51c9e1345719..e75e07d25915 100644 --- a/trunk/drivers/scsi/bfa/bfa_fcs.h +++ b/trunk/drivers/scsi/bfa/bfa_fcs.h @@ -799,6 +799,9 @@ struct bfad_port_s *bfa_fcb_lport_new(struct bfad_s *bfad, enum bfa_lport_role roles, struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv); +void bfa_fcb_lport_delete(struct bfad_s *bfad, enum bfa_lport_role roles, + struct bfad_vf_s *vf_drv, + struct bfad_vport_s *vp_drv); /* * vport callbacks diff --git a/trunk/drivers/scsi/bfa/bfa_fcs_lport.c b/trunk/drivers/scsi/bfa/bfa_fcs_lport.c index 937000db62a8..5d2a1307e5ce 100644 --- a/trunk/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/trunk/drivers/scsi/bfa/bfa_fcs_lport.c @@ -616,7 +616,7 @@ bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port) __port_action[port->fabric->fab_type].online(port); wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); - BFA_LOG(KERN_WARNING, bfad, bfa_log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Logical port online: WWN = %s Role = %s\n", lpwwn_buf, "Initiator"); bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_ONLINE); @@ -639,12 +639,12 @@ bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port) wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); if (bfa_sm_cmp_state(port->fabric, bfa_fcs_fabric_sm_online) == BFA_TRUE) { - BFA_LOG(KERN_WARNING, bfad, bfa_log_level, + BFA_LOG(KERN_ERR, bfad, bfa_log_level, "Logical port lost fabric connectivity: WWN = %s Role = %s\n", lpwwn_buf, "Initiator"); bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DISCONNECT); } else { - BFA_LOG(KERN_WARNING, bfad, bfa_log_level, + BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Logical port taken offline: WWN = %s Role = %s\n", lpwwn_buf, "Initiator"); bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_OFFLINE); @@ -709,10 +709,14 @@ bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port) bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DELETE); /* Base port will be deleted by the OS driver */ - if (port->vport) + if (port->vport) { + bfa_fcb_lport_delete(port->fcs->bfad, port->port_cfg.roles, + port->fabric->vf_drv, + port->vport ? port->vport->vport_drv : NULL); bfa_fcs_vport_delete_comp(port->vport); - else + } else { bfa_wc_down(&port->fabric->wc); + } } @@ -5710,23 +5714,17 @@ bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport) (struct bfad_vport_s *)vport->vport_drv; bfa_fcs_fabric_delvport(__vport_fabric(vport), vport); - bfa_lps_delete(vport->lps); - if (vport_drv->comp_del) { + if (vport_drv->comp_del) complete(vport_drv->comp_del); - return; - } + else + kfree(vport_drv); - /* - * We queue the vport delete work to the IM work_q from here. - * The memory for the bfad_vport_s is freed from the FC function - * template vport_delete entry point. - */ - if (vport_drv) - bfad_im_port_delete(vport_drv->drv_port.bfad, - &vport_drv->drv_port); + bfa_lps_delete(vport->lps); } + + /* * fcs_vport_public FCS virtual port public interfaces */ diff --git a/trunk/drivers/scsi/bfa/bfad.c b/trunk/drivers/scsi/bfa/bfad.c index 2e4b0be14a20..404fd10ddb21 100644 --- a/trunk/drivers/scsi/bfa/bfad.c +++ b/trunk/drivers/scsi/bfa/bfad.c @@ -456,6 +456,23 @@ bfa_fcb_lport_new(struct bfad_s *bfad, struct bfa_fcs_lport_s *port, return port_drv; } +void +bfa_fcb_lport_delete(struct bfad_s *bfad, enum bfa_lport_role roles, + struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv) +{ + struct bfad_port_s *port_drv; + + /* this will be only called from rmmod context */ + if (vp_drv && !vp_drv->comp_del) { + port_drv = (vp_drv) ? (&(vp_drv)->drv_port) : + ((vf_drv) ? (&(vf_drv)->base_port) : + (&(bfad)->pport)); + bfa_trc(bfad, roles); + if (roles & BFA_LPORT_ROLE_FCP_IM) + bfad_im_port_delete(bfad, port_drv); + } +} + /* * FCS RPORT alloc callback, after successful PLOGI by FCS */ diff --git a/trunk/drivers/scsi/bfa/bfad_attr.c b/trunk/drivers/scsi/bfa/bfad_attr.c index 8b6c6bf7837e..7b1ecd2b3ffe 100644 --- a/trunk/drivers/scsi/bfa/bfad_attr.c +++ b/trunk/drivers/scsi/bfa/bfad_attr.c @@ -497,7 +497,6 @@ bfad_im_vport_delete(struct fc_vport *fc_vport) if (im_port->flags & BFAD_PORT_DELETE) { bfad_scsi_host_free(bfad, im_port); list_del(&vport->list_entry); - kfree(vport); return 0; } @@ -759,10 +758,25 @@ bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr, else if (!strcmp(model, "Brocade-804")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, "Brocade 8Gbps FC HBA for HP Bladesystem C-class"); - else if (!strcmp(model, "Brocade-1741")) + else if (!strcmp(model, "Brocade-902") || + !strcmp(model, "Brocade-1741")) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, "Brocade 10Gbps CNA for Dell M-Series Blade Servers"); - else if (strstr(model, "Brocade-1860")) { + else if (strstr(model, "Brocade-1560")) { + if (nports == 1) + snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, + "Brocade 16Gbps PCIe single port FC HBA"); + else + snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, + "Brocade 16Gbps PCIe dual port FC HBA"); + } else if (strstr(model, "Brocade-1710")) { + if (nports == 1) + snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, + "Brocade 10Gbps single port CNA"); + else + snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, + "Brocade 10Gbps dual port CNA"); + } else if (strstr(model, "Brocade-1860")) { if (nports == 1 && bfa_ioc_is_cna(&bfad->bfa.ioc)) snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, "Brocade 10Gbps single port CNA"); diff --git a/trunk/drivers/scsi/bnx2i/57xx_iscsi_constants.h b/trunk/drivers/scsi/bnx2i/57xx_iscsi_constants.h index 25093a04123b..495a841645f9 100644 --- a/trunk/drivers/scsi/bnx2i/57xx_iscsi_constants.h +++ b/trunk/drivers/scsi/bnx2i/57xx_iscsi_constants.h @@ -1,6 +1,6 @@ /* 57xx_iscsi_constants.h: Broadcom NetXtreme II iSCSI HSI * - * Copyright (c) 2006 - 2012 Broadcom Corporation + * Copyright (c) 2006 - 2011 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/trunk/drivers/scsi/bnx2i/57xx_iscsi_hsi.h b/trunk/drivers/scsi/bnx2i/57xx_iscsi_hsi.h index dc0a08e69c82..72118db89a20 100644 --- a/trunk/drivers/scsi/bnx2i/57xx_iscsi_hsi.h +++ b/trunk/drivers/scsi/bnx2i/57xx_iscsi_hsi.h @@ -1,6 +1,6 @@ /* 57xx_iscsi_hsi.h: Broadcom NetXtreme II iSCSI HSI. * - * Copyright (c) 2006 - 2012 Broadcom Corporation + * Copyright (c) 2006 - 2011 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/trunk/drivers/scsi/bnx2i/bnx2i.h b/trunk/drivers/scsi/bnx2i/bnx2i.h index 0c53c28dc3d3..0bd70e80efe4 100644 --- a/trunk/drivers/scsi/bnx2i/bnx2i.h +++ b/trunk/drivers/scsi/bnx2i/bnx2i.h @@ -1,6 +1,6 @@ /* bnx2i.h: Broadcom NetXtreme II iSCSI driver. * - * Copyright (c) 2006 - 2012 Broadcom Corporation + * Copyright (c) 2006 - 2011 Broadcom Corporation * Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved. * Copyright (c) 2007, 2008 Mike Christie * diff --git a/trunk/drivers/scsi/bnx2i/bnx2i_hwi.c b/trunk/drivers/scsi/bnx2i/bnx2i_hwi.c index ece47e502282..f9d6f4129093 100644 --- a/trunk/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/trunk/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -1,6 +1,6 @@ /* bnx2i_hwi.c: Broadcom NetXtreme II iSCSI driver. * - * Copyright (c) 2006 - 2012 Broadcom Corporation + * Copyright (c) 2006 - 2011 Broadcom Corporation * Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved. * Copyright (c) 2007, 2008 Mike Christie * diff --git a/trunk/drivers/scsi/bnx2i/bnx2i_init.c b/trunk/drivers/scsi/bnx2i/bnx2i_init.c index 8b6816706ee5..4927cca733d3 100644 --- a/trunk/drivers/scsi/bnx2i/bnx2i_init.c +++ b/trunk/drivers/scsi/bnx2i/bnx2i_init.c @@ -1,6 +1,6 @@ /* bnx2i.c: Broadcom NetXtreme II iSCSI driver. * - * Copyright (c) 2006 - 2012 Broadcom Corporation + * Copyright (c) 2006 - 2011 Broadcom Corporation * Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved. * Copyright (c) 2007, 2008 Mike Christie * @@ -18,8 +18,8 @@ static struct list_head adapter_list = LIST_HEAD_INIT(adapter_list); static u32 adapter_count; #define DRV_MODULE_NAME "bnx2i" -#define DRV_MODULE_VERSION "2.7.2.2" -#define DRV_MODULE_RELDATE "Apr 25, 2012" +#define DRV_MODULE_VERSION "2.7.0.3" +#define DRV_MODULE_RELDATE "Jun 15, 2011" static char version[] __devinitdata = "Broadcom NetXtreme II iSCSI Driver " DRV_MODULE_NAME \ diff --git a/trunk/drivers/scsi/bnx2i/bnx2i_iscsi.c b/trunk/drivers/scsi/bnx2i/bnx2i_iscsi.c index f8d516b53161..1a44b45e7bef 100644 --- a/trunk/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/trunk/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -1,7 +1,7 @@ /* * bnx2i_iscsi.c: Broadcom NetXtreme II iSCSI driver. * - * Copyright (c) 2006 - 2012 Broadcom Corporation + * Copyright (c) 2006 - 2011 Broadcom Corporation * Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved. * Copyright (c) 2007, 2008 Mike Christie * @@ -2244,7 +2244,6 @@ static struct scsi_host_template bnx2i_host_template = { .eh_device_reset_handler = iscsi_eh_device_reset, .eh_target_reset_handler = iscsi_eh_recover_target, .change_queue_depth = iscsi_change_queue_depth, - .target_alloc = iscsi_target_alloc, .can_queue = 2048, .max_sectors = 127, .cmd_per_lun = 128, diff --git a/trunk/drivers/scsi/bnx2i/bnx2i_sysfs.c b/trunk/drivers/scsi/bnx2i/bnx2i_sysfs.c index c61cf7a43658..83a77f7244d2 100644 --- a/trunk/drivers/scsi/bnx2i/bnx2i_sysfs.c +++ b/trunk/drivers/scsi/bnx2i/bnx2i_sysfs.c @@ -1,6 +1,6 @@ /* bnx2i_sysfs.c: Broadcom NetXtreme II iSCSI driver. * - * Copyright (c) 2004 - 2012 Broadcom Corporation + * Copyright (c) 2004 - 2011 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/trunk/drivers/scsi/device_handler/scsi_dh_alua.c b/trunk/drivers/scsi/device_handler/scsi_dh_alua.c index fda9cdea0e60..04c5cea47a22 100644 --- a/trunk/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/trunk/drivers/scsi/device_handler/scsi_dh_alua.c @@ -55,16 +55,11 @@ #define ALUA_FAILOVER_TIMEOUT (60 * HZ) #define ALUA_FAILOVER_RETRIES 5 -/* flags passed from user level */ -#define ALUA_OPTIMIZE_STPG 1 - struct alua_dh_data { int group_id; int rel_port; int tpgs; int state; - int pref; - unsigned flags; /* used for optimizing STPG */ unsigned char inq[ALUA_INQUIRY_SIZE]; unsigned char *buff; int bufflen; @@ -559,16 +554,14 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) for (k = 4, ucp = h->buff + 4; k < len; k += off, ucp += off) { if (h->group_id == (ucp[2] << 8) + ucp[3]) { h->state = ucp[0] & 0x0f; - h->pref = ucp[0] >> 7; valid_states = ucp[1]; } off = 8 + (ucp[7] * 4); } sdev_printk(KERN_INFO, sdev, - "%s: port group %02x state %c %s supports %c%c%c%c%c%c%c\n", + "%s: port group %02x state %c supports %c%c%c%c%c%c%c\n", ALUA_DH_NAME, h->group_id, print_alua_state(h->state), - h->pref ? "preferred" : "non-preferred", valid_states&TPGS_SUPPORT_TRANSITION?'T':'t', valid_states&TPGS_SUPPORT_OFFLINE?'O':'o', valid_states&TPGS_SUPPORT_LBA_DEPENDENT?'L':'l', @@ -628,37 +621,6 @@ static int alua_initialize(struct scsi_device *sdev, struct alua_dh_data *h) out: return err; } -/* - * alua_set_params - set/unset the optimize flag - * @sdev: device on the path to be activated - * params - parameters in the following format - * "no_of_params\0param1\0param2\0param3\0...\0" - * For example, to set the flag pass the following parameters - * from multipath.conf - * hardware_handler "2 alua 1" - */ -static int alua_set_params(struct scsi_device *sdev, const char *params) -{ - struct alua_dh_data *h = get_alua_data(sdev); - unsigned int optimize = 0, argc; - const char *p = params; - int result = SCSI_DH_OK; - - if ((sscanf(params, "%u", &argc) != 1) || (argc != 1)) - return -EINVAL; - - while (*p++) - ; - if ((sscanf(p, "%u", &optimize) != 1) || (optimize > 1)) - return -EINVAL; - - if (optimize) - h->flags |= ALUA_OPTIMIZE_STPG; - else - h->flags &= ~ALUA_OPTIMIZE_STPG; - - return result; -} /* * alua_activate - activate a path @@ -675,37 +637,14 @@ static int alua_activate(struct scsi_device *sdev, { struct alua_dh_data *h = get_alua_data(sdev); int err = SCSI_DH_OK; - int stpg = 0; err = alua_rtpg(sdev, h); if (err != SCSI_DH_OK) goto out; - if (h->tpgs & TPGS_MODE_EXPLICIT) { - switch (h->state) { - case TPGS_STATE_NONOPTIMIZED: - stpg = 1; - if ((h->flags & ALUA_OPTIMIZE_STPG) && - (!h->pref) && - (h->tpgs & TPGS_MODE_IMPLICIT)) - stpg = 0; - break; - case TPGS_STATE_STANDBY: - stpg = 1; - break; - case TPGS_STATE_UNAVAILABLE: - case TPGS_STATE_OFFLINE: - err = SCSI_DH_IO; - break; - case TPGS_STATE_TRANSITIONING: - err = SCSI_DH_RETRY; - break; - default: - break; - } - } - - if (stpg) { + if (h->tpgs & TPGS_MODE_EXPLICIT && + h->state != TPGS_STATE_OPTIMIZED && + h->state != TPGS_STATE_LBA_DEPENDENT) { h->callback_fn = fn; h->callback_data = data; err = submit_stpg(h); @@ -759,7 +698,6 @@ static struct scsi_device_handler alua_dh = { .prep_fn = alua_prep_fn, .check_sense = alua_check_sense, .activate = alua_activate, - .set_params = alua_set_params, .match = alua_match, }; diff --git a/trunk/drivers/scsi/fcoe/fcoe.c b/trunk/drivers/scsi/fcoe/fcoe.c index 76e3d0b5bfa6..335e85192807 100644 --- a/trunk/drivers/scsi/fcoe/fcoe.c +++ b/trunk/drivers/scsi/fcoe/fcoe.c @@ -411,18 +411,20 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev, } /** - * fcoe_interface_remove() - remove FCoE interface from netdev + * fcoe_interface_cleanup() - Clean up a FCoE interface * @fcoe: The FCoE interface to be cleaned up * * Caller must be holding the RTNL mutex */ -static void fcoe_interface_remove(struct fcoe_interface *fcoe) +static void fcoe_interface_cleanup(struct fcoe_interface *fcoe) { struct net_device *netdev = fcoe->netdev; struct fcoe_ctlr *fip = &fcoe->ctlr; u8 flogi_maddr[ETH_ALEN]; const struct net_device_ops *ops; + rtnl_lock(); + /* * Don't listen for Ethernet packets anymore. * synchronize_net() ensures that the packet handlers are not running @@ -451,28 +453,12 @@ static void fcoe_interface_remove(struct fcoe_interface *fcoe) FCOE_NETDEV_DBG(netdev, "Failed to disable FCoE" " specific feature for LLD.\n"); } - fcoe->removed = 1; -} - - -/** - * fcoe_interface_cleanup() - Clean up a FCoE interface - * @fcoe: The FCoE interface to be cleaned up - */ -static void fcoe_interface_cleanup(struct fcoe_interface *fcoe) -{ - struct net_device *netdev = fcoe->netdev; - struct fcoe_ctlr *fip = &fcoe->ctlr; - rtnl_lock(); - if (!fcoe->removed) - fcoe_interface_remove(fcoe); rtnl_unlock(); /* Release the self-reference taken during fcoe_interface_create() */ /* tear-down the FCoE controller */ fcoe_ctlr_destroy(fip); - scsi_host_put(fcoe->ctlr.lp->host); kfree(fcoe); dev_put(netdev); module_put(THIS_MODULE); @@ -536,11 +522,13 @@ static void fcoe_update_src_mac(struct fc_lport *lport, u8 *addr) struct fcoe_port *port = lport_priv(lport); struct fcoe_interface *fcoe = port->priv; + rtnl_lock(); if (!is_zero_ether_addr(port->data_src_addr)) dev_uc_del(fcoe->netdev, port->data_src_addr); if (!is_zero_ether_addr(addr)) dev_uc_add(fcoe->netdev, addr); memcpy(port->data_src_addr, addr, ETH_ALEN); + rtnl_unlock(); } /** @@ -953,10 +941,6 @@ static void fcoe_if_destroy(struct fc_lport *lport) rtnl_lock(); if (!is_zero_ether_addr(port->data_src_addr)) dev_uc_del(netdev, port->data_src_addr); - if (lport->vport) - synchronize_net(); - else - fcoe_interface_remove(fcoe); rtnl_unlock(); /* Free queued packets for the per-CPU receive threads */ @@ -975,12 +959,8 @@ static void fcoe_if_destroy(struct fc_lport *lport) /* Free memory used by statistical counters */ fc_lport_free_stats(lport); - /* - * Release the Scsi_Host for vport but hold on to - * master lport until it fcoe interface fully cleaned-up. - */ - if (lport->vport) - scsi_host_put(lport->host); + /* Release the Scsi_Host */ + scsi_host_put(lport->host); } /** @@ -2294,9 +2274,10 @@ static void fcoe_percpu_clean(struct fc_lport *lport) continue; skb = dev_alloc_skb(0); - if (!skb) + if (!skb) { + spin_unlock_bh(&pp->fcoe_rx_list.lock); continue; - + } skb->destructor = fcoe_percpu_flush_done; spin_lock_bh(&pp->fcoe_rx_list.lock); diff --git a/trunk/drivers/scsi/fcoe/fcoe.h b/trunk/drivers/scsi/fcoe/fcoe.h index 96ac938d39cc..3c2733a12aa1 100644 --- a/trunk/drivers/scsi/fcoe/fcoe.h +++ b/trunk/drivers/scsi/fcoe/fcoe.h @@ -71,8 +71,7 @@ do { \ * @ctlr: The FCoE controller (for FIP) * @oem: The offload exchange manager for all local port * instances associated with this port - * @removed: Indicates fcoe interface removed from net device - * This structure is 1:1 with a net device. + * This structure is 1:1 with a net devive. */ struct fcoe_interface { struct list_head list; @@ -82,7 +81,6 @@ struct fcoe_interface { struct packet_type fip_packet_type; struct fcoe_ctlr ctlr; struct fc_exch_mgr *oem; - u8 removed; }; #define fcoe_from_ctlr(fip) container_of(fip, struct fcoe_interface, ctlr) diff --git a/trunk/drivers/scsi/fcoe/fcoe_ctlr.c b/trunk/drivers/scsi/fcoe/fcoe_ctlr.c index 5a4c7250aa77..249a106888d9 100644 --- a/trunk/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/trunk/drivers/scsi/fcoe/fcoe_ctlr.c @@ -1883,13 +1883,7 @@ static void fcoe_ctlr_vn_send(struct fcoe_ctlr *fip, frame = (struct fip_frame *)skb->data; memset(frame, 0, len); memcpy(frame->eth.h_dest, dest, ETH_ALEN); - - if (sub == FIP_SC_VN_BEACON) { - hton24(frame->eth.h_source, FIP_VN_FC_MAP); - hton24(frame->eth.h_source + 3, fip->port_id); - } else { - memcpy(frame->eth.h_source, fip->ctl_src_addr, ETH_ALEN); - } + memcpy(frame->eth.h_source, fip->ctl_src_addr, ETH_ALEN); frame->eth.h_proto = htons(ETH_P_FIP); frame->fip.fip_ver = FIP_VER_ENCAPS(FIP_VER); diff --git a/trunk/drivers/scsi/hosts.c b/trunk/drivers/scsi/hosts.c index a3a056a9db67..351dc0b86fab 100644 --- a/trunk/drivers/scsi/hosts.c +++ b/trunk/drivers/scsi/hosts.c @@ -218,9 +218,6 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, if (!shost->shost_gendev.parent) shost->shost_gendev.parent = dev ? dev : &platform_bus; - if (!dma_dev) - dma_dev = shost->shost_gendev.parent; - shost->dma_dev = dma_dev; error = device_add(&shost->shost_gendev); diff --git a/trunk/drivers/scsi/hpsa.c b/trunk/drivers/scsi/hpsa.c index 796482badf13..500e20dd56ec 100644 --- a/trunk/drivers/scsi/hpsa.c +++ b/trunk/drivers/scsi/hpsa.c @@ -159,7 +159,6 @@ static int hpsa_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason); static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd); -static int hpsa_eh_abort_handler(struct scsi_cmnd *scsicmd); static int hpsa_slave_alloc(struct scsi_device *sdev); static void hpsa_slave_destroy(struct scsi_device *sdev); @@ -172,7 +171,7 @@ static void check_ioctl_unit_attention(struct ctlr_info *h, static void calc_bucket_map(int *bucket, int num_buckets, int nsgs, int *bucket_map); static __devinit void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h); -static inline u32 next_command(struct ctlr_info *h, u8 q); +static inline u32 next_command(struct ctlr_info *h); static int __devinit hpsa_find_cfg_addrs(struct pci_dev *pdev, void __iomem *vaddr, u32 *cfg_base_addr, u64 *cfg_base_addr_index, u64 *cfg_offset); @@ -181,7 +180,6 @@ static int __devinit hpsa_pci_find_memory_BAR(struct pci_dev *pdev, static int __devinit hpsa_lookup_board_id(struct pci_dev *pdev, u32 *board_id); static int __devinit hpsa_wait_for_board_state(struct pci_dev *pdev, void __iomem *vaddr, int wait_for_ready); -static inline void finish_cmd(struct CommandList *c); #define BOARD_NOT_READY 0 #define BOARD_READY 1 @@ -236,16 +234,6 @@ static int check_for_unit_attention(struct ctlr_info *h, return 1; } -static int check_for_busy(struct ctlr_info *h, struct CommandList *c) -{ - if (c->err_info->CommandStatus != CMD_TARGET_STATUS || - (c->err_info->ScsiStatus != SAM_STAT_BUSY && - c->err_info->ScsiStatus != SAM_STAT_TASK_SET_FULL)) - return 0; - dev_warn(&h->pdev->dev, HPSA "device busy"); - return 1; -} - static ssize_t host_store_rescan(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -380,7 +368,7 @@ static inline int is_logical_dev_addr_mode(unsigned char scsi3addr[]) } static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", - "1(ADM)", "UNKNOWN" + "UNKNOWN" }; #define RAID_UNKNOWN (ARRAY_SIZE(raid_label) - 1) @@ -509,7 +497,6 @@ static struct scsi_host_template hpsa_driver_template = { .change_queue_depth = hpsa_change_queue_depth, .this_id = -1, .use_clustering = ENABLE_CLUSTERING, - .eh_abort_handler = hpsa_eh_abort_handler, .eh_device_reset_handler = hpsa_eh_device_reset_handler, .ioctl = hpsa_ioctl, .slave_alloc = hpsa_slave_alloc, @@ -529,28 +516,24 @@ static inline void addQ(struct list_head *list, struct CommandList *c) list_add_tail(&c->list, list); } -static inline u32 next_command(struct ctlr_info *h, u8 q) +static inline u32 next_command(struct ctlr_info *h) { u32 a; - struct reply_pool *rq = &h->reply_queue[q]; - unsigned long flags; if (unlikely(!(h->transMethod & CFGTBL_Trans_Performant))) - return h->access.command_completed(h, q); + return h->access.command_completed(h); - if ((rq->head[rq->current_entry] & 1) == rq->wraparound) { - a = rq->head[rq->current_entry]; - rq->current_entry++; - spin_lock_irqsave(&h->lock, flags); + if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) { + a = *(h->reply_pool_head); /* Next cmd in ring buffer */ + (h->reply_pool_head)++; h->commands_outstanding--; - spin_unlock_irqrestore(&h->lock, flags); } else { a = FIFO_EMPTY; } /* Check for wraparound */ - if (rq->current_entry == h->max_commands) { - rq->current_entry = 0; - rq->wraparound ^= 1; + if (h->reply_pool_head == (h->reply_pool + h->max_commands)) { + h->reply_pool_head = h->reply_pool; + h->reply_pool_wraparound ^= 1; } return a; } @@ -561,41 +544,8 @@ static inline u32 next_command(struct ctlr_info *h, u8 q) */ static void set_performant_mode(struct ctlr_info *h, struct CommandList *c) { - if (likely(h->transMethod & CFGTBL_Trans_Performant)) { + if (likely(h->transMethod & CFGTBL_Trans_Performant)) c->busaddr |= 1 | (h->blockFetchTable[c->Header.SGList] << 1); - if (likely(h->msix_vector)) - c->Header.ReplyQueue = - smp_processor_id() % h->nreply_queues; - } -} - -static int is_firmware_flash_cmd(u8 *cdb) -{ - return cdb[0] == BMIC_WRITE && cdb[6] == BMIC_FLASH_FIRMWARE; -} - -/* - * During firmware flash, the heartbeat register may not update as frequently - * as it should. So we dial down lockup detection during firmware flash. and - * dial it back up when firmware flash completes. - */ -#define HEARTBEAT_SAMPLE_INTERVAL_DURING_FLASH (240 * HZ) -#define HEARTBEAT_SAMPLE_INTERVAL (30 * HZ) -static void dial_down_lockup_detection_during_fw_flash(struct ctlr_info *h, - struct CommandList *c) -{ - if (!is_firmware_flash_cmd(c->Request.CDB)) - return; - atomic_inc(&h->firmware_flash_in_progress); - h->heartbeat_sample_interval = HEARTBEAT_SAMPLE_INTERVAL_DURING_FLASH; -} - -static void dial_up_lockup_detection_on_fw_flash_complete(struct ctlr_info *h, - struct CommandList *c) -{ - if (is_firmware_flash_cmd(c->Request.CDB) && - atomic_dec_and_test(&h->firmware_flash_in_progress)) - h->heartbeat_sample_interval = HEARTBEAT_SAMPLE_INTERVAL; } static void enqueue_cmd_and_start_io(struct ctlr_info *h, @@ -604,12 +554,11 @@ static void enqueue_cmd_and_start_io(struct ctlr_info *h, unsigned long flags; set_performant_mode(h, c); - dial_down_lockup_detection_during_fw_flash(h, c); spin_lock_irqsave(&h->lock, flags); addQ(&h->reqQ, c); h->Qdepth++; - spin_unlock_irqrestore(&h->lock, flags); start_io(h); + spin_unlock_irqrestore(&h->lock, flags); } static inline void removeQ(struct CommandList *c) @@ -1244,7 +1193,7 @@ static void complete_scsi_command(struct CommandList *cp) break; } /* Must be some other type of check condition */ - dev_dbg(&h->pdev->dev, "cp %p has check condition: " + dev_warn(&h->pdev->dev, "cp %p has check condition: " "unknown type: " "Sense: 0x%x, ASC: 0x%x, ASCQ: 0x%x, " "Returning result: 0x%x, " @@ -1421,24 +1370,16 @@ static void hpsa_scsi_do_simple_cmd_core_if_no_lockup(struct ctlr_info *h, } } -#define MAX_DRIVER_CMD_RETRIES 25 static void hpsa_scsi_do_simple_cmd_with_retry(struct ctlr_info *h, struct CommandList *c, int data_direction) { - int backoff_time = 10, retry_count = 0; + int retry_count = 0; do { memset(c->err_info, 0, sizeof(*c->err_info)); hpsa_scsi_do_simple_cmd_core(h, c); retry_count++; - if (retry_count > 3) { - msleep(backoff_time); - if (backoff_time < 1000) - backoff_time *= 2; - } - } while ((check_for_unit_attention(h, c) || - check_for_busy(h, c)) && - retry_count <= MAX_DRIVER_CMD_RETRIES); + } while (check_for_unit_attention(h, c) && retry_count <= 3); hpsa_pci_unmap(h->pdev, c, 1, data_direction); } @@ -2124,8 +2065,9 @@ static int hpsa_scsi_queue_command_lck(struct scsi_cmnd *cmd, done(cmd); return 0; } - spin_unlock_irqrestore(&h->lock, flags); + /* Need a lock as this is being allocated from the pool */ c = cmd_alloc(h); + spin_unlock_irqrestore(&h->lock, flags); if (c == NULL) { /* trouble... */ dev_err(&h->pdev->dev, "cmd_alloc returned NULL!\n"); return SCSI_MLQUEUE_HOST_BUSY; @@ -2392,261 +2334,6 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd) return FAILED; } -static void swizzle_abort_tag(u8 *tag) -{ - u8 original_tag[8]; - - memcpy(original_tag, tag, 8); - tag[0] = original_tag[3]; - tag[1] = original_tag[2]; - tag[2] = original_tag[1]; - tag[3] = original_tag[0]; - tag[4] = original_tag[7]; - tag[5] = original_tag[6]; - tag[6] = original_tag[5]; - tag[7] = original_tag[4]; -} - -static int hpsa_send_abort(struct ctlr_info *h, unsigned char *scsi3addr, - struct CommandList *abort, int swizzle) -{ - int rc = IO_OK; - struct CommandList *c; - struct ErrorInfo *ei; - - c = cmd_special_alloc(h); - if (c == NULL) { /* trouble... */ - dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n"); - return -ENOMEM; - } - - fill_cmd(c, HPSA_ABORT_MSG, h, abort, 0, 0, scsi3addr, TYPE_MSG); - if (swizzle) - swizzle_abort_tag(&c->Request.CDB[4]); - hpsa_scsi_do_simple_cmd_core(h, c); - dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: do_simple_cmd_core completed.\n", - __func__, abort->Header.Tag.upper, abort->Header.Tag.lower); - /* no unmap needed here because no data xfer. */ - - ei = c->err_info; - switch (ei->CommandStatus) { - case CMD_SUCCESS: - break; - case CMD_UNABORTABLE: /* Very common, don't make noise. */ - rc = -1; - break; - default: - dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: interpreting error.\n", - __func__, abort->Header.Tag.upper, - abort->Header.Tag.lower); - hpsa_scsi_interpret_error(c); - rc = -1; - break; - } - cmd_special_free(h, c); - dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: Finished.\n", __func__, - abort->Header.Tag.upper, abort->Header.Tag.lower); - return rc; -} - -/* - * hpsa_find_cmd_in_queue - * - * Used to determine whether a command (find) is still present - * in queue_head. Optionally excludes the last element of queue_head. - * - * This is used to avoid unnecessary aborts. Commands in h->reqQ have - * not yet been submitted, and so can be aborted by the driver without - * sending an abort to the hardware. - * - * Returns pointer to command if found in queue, NULL otherwise. - */ -static struct CommandList *hpsa_find_cmd_in_queue(struct ctlr_info *h, - struct scsi_cmnd *find, struct list_head *queue_head) -{ - unsigned long flags; - struct CommandList *c = NULL; /* ptr into cmpQ */ - - if (!find) - return 0; - spin_lock_irqsave(&h->lock, flags); - list_for_each_entry(c, queue_head, list) { - if (c->scsi_cmd == NULL) /* e.g.: passthru ioctl */ - continue; - if (c->scsi_cmd == find) { - spin_unlock_irqrestore(&h->lock, flags); - return c; - } - } - spin_unlock_irqrestore(&h->lock, flags); - return NULL; -} - -static struct CommandList *hpsa_find_cmd_in_queue_by_tag(struct ctlr_info *h, - u8 *tag, struct list_head *queue_head) -{ - unsigned long flags; - struct CommandList *c; - - spin_lock_irqsave(&h->lock, flags); - list_for_each_entry(c, queue_head, list) { - if (memcmp(&c->Header.Tag, tag, 8) != 0) - continue; - spin_unlock_irqrestore(&h->lock, flags); - return c; - } - spin_unlock_irqrestore(&h->lock, flags); - return NULL; -} - -/* Some Smart Arrays need the abort tag swizzled, and some don't. It's hard to - * tell which kind we're dealing with, so we send the abort both ways. There - * shouldn't be any collisions between swizzled and unswizzled tags due to the - * way we construct our tags but we check anyway in case the assumptions which - * make this true someday become false. - */ -static int hpsa_send_abort_both_ways(struct ctlr_info *h, - unsigned char *scsi3addr, struct CommandList *abort) -{ - u8 swizzled_tag[8]; - struct CommandList *c; - int rc = 0, rc2 = 0; - - /* we do not expect to find the swizzled tag in our queue, but - * check anyway just to be sure the assumptions which make this - * the case haven't become wrong. - */ - memcpy(swizzled_tag, &abort->Request.CDB[4], 8); - swizzle_abort_tag(swizzled_tag); - c = hpsa_find_cmd_in_queue_by_tag(h, swizzled_tag, &h->cmpQ); - if (c != NULL) { - dev_warn(&h->pdev->dev, "Unexpectedly found byte-swapped tag in completion queue.\n"); - return hpsa_send_abort(h, scsi3addr, abort, 0); - } - rc = hpsa_send_abort(h, scsi3addr, abort, 0); - - /* if the command is still in our queue, we can't conclude that it was - * aborted (it might have just completed normally) but in any case - * we don't need to try to abort it another way. - */ - c = hpsa_find_cmd_in_queue(h, abort->scsi_cmd, &h->cmpQ); - if (c) - rc2 = hpsa_send_abort(h, scsi3addr, abort, 1); - return rc && rc2; -} - -/* Send an abort for the specified command. - * If the device and controller support it, - * send a task abort request. - */ -static int hpsa_eh_abort_handler(struct scsi_cmnd *sc) -{ - - int i, rc; - struct ctlr_info *h; - struct hpsa_scsi_dev_t *dev; - struct CommandList *abort; /* pointer to command to be aborted */ - struct CommandList *found; - struct scsi_cmnd *as; /* ptr to scsi cmd inside aborted command. */ - char msg[256]; /* For debug messaging. */ - int ml = 0; - - /* Find the controller of the command to be aborted */ - h = sdev_to_hba(sc->device); - if (WARN(h == NULL, - "ABORT REQUEST FAILED, Controller lookup failed.\n")) - return FAILED; - - /* Check that controller supports some kind of task abort */ - if (!(HPSATMF_PHYS_TASK_ABORT & h->TMFSupportFlags) && - !(HPSATMF_LOG_TASK_ABORT & h->TMFSupportFlags)) - return FAILED; - - memset(msg, 0, sizeof(msg)); - ml += sprintf(msg+ml, "ABORT REQUEST on C%d:B%d:T%d:L%d ", - h->scsi_host->host_no, sc->device->channel, - sc->device->id, sc->device->lun); - - /* Find the device of the command to be aborted */ - dev = sc->device->hostdata; - if (!dev) { - dev_err(&h->pdev->dev, "%s FAILED, Device lookup failed.\n", - msg); - return FAILED; - } - - /* Get SCSI command to be aborted */ - abort = (struct CommandList *) sc->host_scribble; - if (abort == NULL) { - dev_err(&h->pdev->dev, "%s FAILED, Command to abort is NULL.\n", - msg); - return FAILED; - } - - ml += sprintf(msg+ml, "Tag:0x%08x:%08x ", - abort->Header.Tag.upper, abort->Header.Tag.lower); - as = (struct scsi_cmnd *) abort->scsi_cmd; - if (as != NULL) - ml += sprintf(msg+ml, "Command:0x%x SN:0x%lx ", - as->cmnd[0], as->serial_number); - dev_dbg(&h->pdev->dev, "%s\n", msg); - dev_warn(&h->pdev->dev, "Abort request on C%d:B%d:T%d:L%d\n", - h->scsi_host->host_no, dev->bus, dev->target, dev->lun); - - /* Search reqQ to See if command is queued but not submitted, - * if so, complete the command with aborted status and remove - * it from the reqQ. - */ - found = hpsa_find_cmd_in_queue(h, sc, &h->reqQ); - if (found) { - found->err_info->CommandStatus = CMD_ABORTED; - finish_cmd(found); - dev_info(&h->pdev->dev, "%s Request SUCCEEDED (driver queue).\n", - msg); - return SUCCESS; - } - - /* not in reqQ, if also not in cmpQ, must have already completed */ - found = hpsa_find_cmd_in_queue(h, sc, &h->cmpQ); - if (!found) { - dev_dbg(&h->pdev->dev, "%s Request FAILED (not known to driver).\n", - msg); - return SUCCESS; - } - - /* - * Command is in flight, or possibly already completed - * by the firmware (but not to the scsi mid layer) but we can't - * distinguish which. Send the abort down. - */ - rc = hpsa_send_abort_both_ways(h, dev->scsi3addr, abort); - if (rc != 0) { - dev_dbg(&h->pdev->dev, "%s Request FAILED.\n", msg); - dev_warn(&h->pdev->dev, "FAILED abort on device C%d:B%d:T%d:L%d\n", - h->scsi_host->host_no, - dev->bus, dev->target, dev->lun); - return FAILED; - } - dev_info(&h->pdev->dev, "%s REQUEST SUCCEEDED.\n", msg); - - /* If the abort(s) above completed and actually aborted the - * command, then the command to be aborted should already be - * completed. If not, wait around a bit more to see if they - * manage to complete normally. - */ -#define ABORT_COMPLETE_WAIT_SECS 30 - for (i = 0; i < ABORT_COMPLETE_WAIT_SECS * 10; i++) { - found = hpsa_find_cmd_in_queue(h, sc, &h->cmpQ); - if (!found) - return SUCCESS; - msleep(100); - } - dev_warn(&h->pdev->dev, "%s FAILED. Aborted command has not completed after %d seconds.\n", - msg, ABORT_COMPLETE_WAIT_SECS); - return FAILED; -} - - /* * For operations that cannot sleep, a command block is allocated at init, * and managed by cmd_alloc() and cmd_free() using a simple bitmap to track @@ -2659,21 +2346,14 @@ static struct CommandList *cmd_alloc(struct ctlr_info *h) int i; union u64bit temp64; dma_addr_t cmd_dma_handle, err_dma_handle; - unsigned long flags; - spin_lock_irqsave(&h->lock, flags); do { i = find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds); - if (i == h->nr_cmds) { - spin_unlock_irqrestore(&h->lock, flags); + if (i == h->nr_cmds) return NULL; - } } while (test_and_set_bit (i & (BITS_PER_LONG - 1), h->cmd_pool_bits + (i / BITS_PER_LONG)) != 0); - h->nr_allocs++; - spin_unlock_irqrestore(&h->lock, flags); - c = h->cmd_pool + i; memset(c, 0, sizeof(*c)); cmd_dma_handle = h->cmd_pool_dhandle @@ -2682,6 +2362,7 @@ static struct CommandList *cmd_alloc(struct ctlr_info *h) memset(c->err_info, 0, sizeof(*c->err_info)); err_dma_handle = h->errinfo_pool_dhandle + i * sizeof(*c->err_info); + h->nr_allocs++; c->cmdindex = i; @@ -2737,14 +2418,11 @@ static struct CommandList *cmd_special_alloc(struct ctlr_info *h) static void cmd_free(struct ctlr_info *h, struct CommandList *c) { int i; - unsigned long flags; i = c - h->cmd_pool; - spin_lock_irqsave(&h->lock, flags); clear_bit(i & (BITS_PER_LONG - 1), h->cmd_pool_bits + (i / BITS_PER_LONG)); h->nr_frees++; - spin_unlock_irqrestore(&h->lock, flags); } static void cmd_special_free(struct ctlr_info *h, struct CommandList *c) @@ -3188,7 +2866,6 @@ static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h, int cmd_type) { int pci_dir = XFER_NONE; - struct CommandList *a; /* for commands to be aborted */ c->cmd_type = CMD_IOCTL_PEND; c->Header.ReplyQueue = 0; @@ -3272,35 +2949,8 @@ static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h, c->Request.CDB[5] = 0x00; c->Request.CDB[6] = 0x00; c->Request.CDB[7] = 0x00; - break; - case HPSA_ABORT_MSG: - a = buff; /* point to command to be aborted */ - dev_dbg(&h->pdev->dev, "Abort Tag:0x%08x:%08x using request Tag:0x%08x:%08x\n", - a->Header.Tag.upper, a->Header.Tag.lower, - c->Header.Tag.upper, c->Header.Tag.lower); - c->Request.CDBLen = 16; - c->Request.Type.Type = TYPE_MSG; - c->Request.Type.Attribute = ATTR_SIMPLE; - c->Request.Type.Direction = XFER_WRITE; - c->Request.Timeout = 0; /* Don't time out */ - c->Request.CDB[0] = HPSA_TASK_MANAGEMENT; - c->Request.CDB[1] = HPSA_TMF_ABORT_TASK; - c->Request.CDB[2] = 0x00; /* reserved */ - c->Request.CDB[3] = 0x00; /* reserved */ - /* Tag to abort goes in CDB[4]-CDB[11] */ - c->Request.CDB[4] = a->Header.Tag.lower & 0xFF; - c->Request.CDB[5] = (a->Header.Tag.lower >> 8) & 0xFF; - c->Request.CDB[6] = (a->Header.Tag.lower >> 16) & 0xFF; - c->Request.CDB[7] = (a->Header.Tag.lower >> 24) & 0xFF; - c->Request.CDB[8] = a->Header.Tag.upper & 0xFF; - c->Request.CDB[9] = (a->Header.Tag.upper >> 8) & 0xFF; - c->Request.CDB[10] = (a->Header.Tag.upper >> 16) & 0xFF; - c->Request.CDB[11] = (a->Header.Tag.upper >> 24) & 0xFF; - c->Request.CDB[12] = 0x00; /* reserved */ - c->Request.CDB[13] = 0x00; /* reserved */ - c->Request.CDB[14] = 0x00; /* reserved */ - c->Request.CDB[15] = 0x00; /* reserved */ break; + default: dev_warn(&h->pdev->dev, "unknown message type %d\n", cmd); @@ -3348,9 +2998,7 @@ static void __iomem *remap_pci_mem(ulong base, ulong size) static void start_io(struct ctlr_info *h) { struct CommandList *c; - unsigned long flags; - spin_lock_irqsave(&h->lock, flags); while (!list_empty(&h->reqQ)) { c = list_entry(h->reqQ.next, struct CommandList, list); /* can't do anything if fifo is full */ @@ -3363,28 +3011,17 @@ static void start_io(struct ctlr_info *h) removeQ(c); h->Qdepth--; - /* Put job onto the completed Q */ - addQ(&h->cmpQ, c); - - /* Must increment commands_outstanding before unlocking - * and submitting to avoid race checking for fifo full - * condition. - */ - h->commands_outstanding++; - if (h->commands_outstanding > h->max_outstanding) - h->max_outstanding = h->commands_outstanding; - /* Tell the controller execute command */ - spin_unlock_irqrestore(&h->lock, flags); h->access.submit_command(h, c); - spin_lock_irqsave(&h->lock, flags); + + /* Put job onto the completed Q */ + addQ(&h->cmpQ, c); } - spin_unlock_irqrestore(&h->lock, flags); } -static inline unsigned long get_next_completion(struct ctlr_info *h, u8 q) +static inline unsigned long get_next_completion(struct ctlr_info *h) { - return h->access.command_completed(h, q); + return h->access.command_completed(h); } static inline bool interrupt_pending(struct ctlr_info *h) @@ -3408,14 +3045,9 @@ static inline int bad_tag(struct ctlr_info *h, u32 tag_index, return 0; } -static inline void finish_cmd(struct CommandList *c) +static inline void finish_cmd(struct CommandList *c, u32 raw_tag) { - unsigned long flags; - - spin_lock_irqsave(&c->h->lock, flags); removeQ(c); - spin_unlock_irqrestore(&c->h->lock, flags); - dial_up_lockup_detection_on_fw_flash_complete(c->h, c); if (likely(c->cmd_type == CMD_SCSI)) complete_scsi_command(c); else if (c->cmd_type == CMD_IOCTL_PEND) @@ -3443,38 +3075,36 @@ static inline u32 hpsa_tag_discard_error_bits(struct ctlr_info *h, u32 tag) } /* process completion of an indexed ("direct lookup") command */ -static inline void process_indexed_cmd(struct ctlr_info *h, +static inline u32 process_indexed_cmd(struct ctlr_info *h, u32 raw_tag) { u32 tag_index; struct CommandList *c; tag_index = hpsa_tag_to_index(raw_tag); - if (!bad_tag(h, tag_index, raw_tag)) { - c = h->cmd_pool + tag_index; - finish_cmd(c); - } + if (bad_tag(h, tag_index, raw_tag)) + return next_command(h); + c = h->cmd_pool + tag_index; + finish_cmd(c, raw_tag); + return next_command(h); } /* process completion of a non-indexed command */ -static inline void process_nonindexed_cmd(struct ctlr_info *h, +static inline u32 process_nonindexed_cmd(struct ctlr_info *h, u32 raw_tag) { u32 tag; struct CommandList *c = NULL; - unsigned long flags; tag = hpsa_tag_discard_error_bits(h, raw_tag); - spin_lock_irqsave(&h->lock, flags); list_for_each_entry(c, &h->cmpQ, list) { if ((c->busaddr & 0xFFFFFFE0) == (tag & 0xFFFFFFE0)) { - spin_unlock_irqrestore(&h->lock, flags); - finish_cmd(c); - return; + finish_cmd(c, raw_tag); + return next_command(h); } } - spin_unlock_irqrestore(&h->lock, flags); bad_tag(h, h->nr_cmds + 1, raw_tag); + return next_command(h); } /* Some controllers, like p400, will give us one interrupt @@ -3496,20 +3126,10 @@ static int ignore_bogus_interrupt(struct ctlr_info *h) return 1; } -/* - * Convert &h->q[x] (passed to interrupt handlers) back to h. - * Relies on (h-q[x] == x) being true for x such that - * 0 <= x < MAX_REPLY_QUEUES. - */ -static struct ctlr_info *queue_to_hba(u8 *queue) -{ - return container_of((queue - *queue), struct ctlr_info, q[0]); -} - -static irqreturn_t hpsa_intx_discard_completions(int irq, void *queue) +static irqreturn_t hpsa_intx_discard_completions(int irq, void *dev_id) { - struct ctlr_info *h = queue_to_hba(queue); - u8 q = *(u8 *) queue; + struct ctlr_info *h = dev_id; + unsigned long flags; u32 raw_tag; if (ignore_bogus_interrupt(h)) @@ -3517,68 +3137,74 @@ static irqreturn_t hpsa_intx_discard_completions(int irq, void *queue) if (interrupt_not_for_us(h)) return IRQ_NONE; + spin_lock_irqsave(&h->lock, flags); h->last_intr_timestamp = get_jiffies_64(); while (interrupt_pending(h)) { - raw_tag = get_next_completion(h, q); + raw_tag = get_next_completion(h); while (raw_tag != FIFO_EMPTY) - raw_tag = next_command(h, q); + raw_tag = next_command(h); } + spin_unlock_irqrestore(&h->lock, flags); return IRQ_HANDLED; } -static irqreturn_t hpsa_msix_discard_completions(int irq, void *queue) +static irqreturn_t hpsa_msix_discard_completions(int irq, void *dev_id) { - struct ctlr_info *h = queue_to_hba(queue); + struct ctlr_info *h = dev_id; + unsigned long flags; u32 raw_tag; - u8 q = *(u8 *) queue; if (ignore_bogus_interrupt(h)) return IRQ_NONE; + spin_lock_irqsave(&h->lock, flags); h->last_intr_timestamp = get_jiffies_64(); - raw_tag = get_next_completion(h, q); + raw_tag = get_next_completion(h); while (raw_tag != FIFO_EMPTY) - raw_tag = next_command(h, q); + raw_tag = next_command(h); + spin_unlock_irqrestore(&h->lock, flags); return IRQ_HANDLED; } -static irqreturn_t do_hpsa_intr_intx(int irq, void *queue) +static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id) { - struct ctlr_info *h = queue_to_hba((u8 *) queue); + struct ctlr_info *h = dev_id; + unsigned long flags; u32 raw_tag; - u8 q = *(u8 *) queue; if (interrupt_not_for_us(h)) return IRQ_NONE; + spin_lock_irqsave(&h->lock, flags); h->last_intr_timestamp = get_jiffies_64(); while (interrupt_pending(h)) { - raw_tag = get_next_completion(h, q); + raw_tag = get_next_completion(h); while (raw_tag != FIFO_EMPTY) { - if (likely(hpsa_tag_contains_index(raw_tag))) - process_indexed_cmd(h, raw_tag); + if (hpsa_tag_contains_index(raw_tag)) + raw_tag = process_indexed_cmd(h, raw_tag); else - process_nonindexed_cmd(h, raw_tag); - raw_tag = next_command(h, q); + raw_tag = process_nonindexed_cmd(h, raw_tag); } } + spin_unlock_irqrestore(&h->lock, flags); return IRQ_HANDLED; } -static irqreturn_t do_hpsa_intr_msi(int irq, void *queue) +static irqreturn_t do_hpsa_intr_msi(int irq, void *dev_id) { - struct ctlr_info *h = queue_to_hba(queue); + struct ctlr_info *h = dev_id; + unsigned long flags; u32 raw_tag; - u8 q = *(u8 *) queue; + spin_lock_irqsave(&h->lock, flags); h->last_intr_timestamp = get_jiffies_64(); - raw_tag = get_next_completion(h, q); + raw_tag = get_next_completion(h); while (raw_tag != FIFO_EMPTY) { - if (likely(hpsa_tag_contains_index(raw_tag))) - process_indexed_cmd(h, raw_tag); + if (hpsa_tag_contains_index(raw_tag)) + raw_tag = process_indexed_cmd(h, raw_tag); else - process_nonindexed_cmd(h, raw_tag); - raw_tag = next_command(h, q); + raw_tag = process_nonindexed_cmd(h, raw_tag); } + spin_unlock_irqrestore(&h->lock, flags); return IRQ_HANDLED; } @@ -4012,13 +3638,10 @@ static int find_PCI_BAR_index(struct pci_dev *pdev, unsigned long pci_bar_addr) static void __devinit hpsa_interrupt_mode(struct ctlr_info *h) { #ifdef CONFIG_PCI_MSI - int err, i; - struct msix_entry hpsa_msix_entries[MAX_REPLY_QUEUES]; - - for (i = 0; i < MAX_REPLY_QUEUES; i++) { - hpsa_msix_entries[i].vector = 0; - hpsa_msix_entries[i].entry = i; - } + int err; + struct msix_entry hpsa_msix_entries[4] = { {0, 0}, {0, 1}, + {0, 2}, {0, 3} + }; /* Some boards advertise MSI but don't really support it */ if ((h->board_id == 0x40700E11) || (h->board_id == 0x40800E11) || @@ -4026,11 +3649,12 @@ static void __devinit hpsa_interrupt_mode(struct ctlr_info *h) goto default_int_mode; if (pci_find_capability(h->pdev, PCI_CAP_ID_MSIX)) { dev_info(&h->pdev->dev, "MSIX\n"); - err = pci_enable_msix(h->pdev, hpsa_msix_entries, - MAX_REPLY_QUEUES); + err = pci_enable_msix(h->pdev, hpsa_msix_entries, 4); if (!err) { - for (i = 0; i < MAX_REPLY_QUEUES; i++) - h->intr[i] = hpsa_msix_entries[i].vector; + h->intr[0] = hpsa_msix_entries[0].vector; + h->intr[1] = hpsa_msix_entries[1].vector; + h->intr[2] = hpsa_msix_entries[2].vector; + h->intr[3] = hpsa_msix_entries[3].vector; h->msix_vector = 1; return; } @@ -4081,6 +3705,14 @@ static int __devinit hpsa_lookup_board_id(struct pci_dev *pdev, u32 *board_id) return ARRAY_SIZE(products) - 1; /* generic unknown smart array */ } +static inline bool hpsa_board_disabled(struct pci_dev *pdev) +{ + u16 command; + + (void) pci_read_config_word(pdev, PCI_COMMAND, &command); + return ((command & PCI_COMMAND_MEMORY) == 0); +} + static int __devinit hpsa_pci_find_memory_BAR(struct pci_dev *pdev, unsigned long *memory_bar) { @@ -4206,14 +3838,14 @@ static void __devinit hpsa_find_board_params(struct ctlr_info *h) h->maxsgentries = 31; /* default to traditional values */ h->chainsize = 0; } - - /* Find out what task management functions are supported and cache */ - h->TMFSupportFlags = readl(&(h->cfgtable->TMFSupportFlags)); } static inline bool hpsa_CISS_signature_present(struct ctlr_info *h) { - if (!check_signature(h->cfgtable->Signature, "CISS", 4)) { + if ((readb(&h->cfgtable->Signature[0]) != 'C') || + (readb(&h->cfgtable->Signature[1]) != 'I') || + (readb(&h->cfgtable->Signature[2]) != 'S') || + (readb(&h->cfgtable->Signature[3]) != 'S')) { dev_warn(&h->pdev->dev, "not a valid CISS config table\n"); return false; } @@ -4300,6 +3932,11 @@ static int __devinit hpsa_pci_init(struct ctlr_info *h) h->product_name = products[prod_index].product_name; h->access = *(products[prod_index].access); + if (hpsa_board_disabled(h->pdev)) { + dev_warn(&h->pdev->dev, "controller appears to be disabled\n"); + return -ENODEV; + } + pci_disable_link_state(h->pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM); @@ -4309,9 +3946,6 @@ static int __devinit hpsa_pci_init(struct ctlr_info *h) return err; } - /* Enable bus mastering (pci_disable_device may disable this) */ - pci_set_master(h->pdev); - err = pci_request_regions(h->pdev, HPSA); if (err) { dev_err(&h->pdev->dev, @@ -4353,7 +3987,10 @@ static int __devinit hpsa_pci_init(struct ctlr_info *h) iounmap(h->cfgtable); if (h->vaddr) iounmap(h->vaddr); - pci_disable_device(h->pdev); + /* + * Deliberately omit pci_disable_device(): it does something nasty to + * Smart Array controllers that pci_enable_device does not undo + */ pci_release_regions(h->pdev); return err; } @@ -4444,33 +4081,14 @@ static int hpsa_request_irq(struct ctlr_info *h, irqreturn_t (*msixhandler)(int, void *), irqreturn_t (*intxhandler)(int, void *)) { - int rc, i; + int rc; - /* - * initialize h->q[x] = x so that interrupt handlers know which - * queue to process. - */ - for (i = 0; i < MAX_REPLY_QUEUES; i++) - h->q[i] = (u8) i; - - if (h->intr_mode == PERF_MODE_INT && h->msix_vector) { - /* If performant mode and MSI-X, use multiple reply queues */ - for (i = 0; i < MAX_REPLY_QUEUES; i++) - rc = request_irq(h->intr[i], msixhandler, - 0, h->devname, - &h->q[i]); - } else { - /* Use single reply pool */ - if (h->msix_vector || h->msi_vector) { - rc = request_irq(h->intr[h->intr_mode], - msixhandler, 0, h->devname, - &h->q[h->intr_mode]); - } else { - rc = request_irq(h->intr[h->intr_mode], - intxhandler, IRQF_SHARED, h->devname, - &h->q[h->intr_mode]); - } - } + if (h->msix_vector || h->msi_vector) + rc = request_irq(h->intr[h->intr_mode], msixhandler, + 0, h->devname, h); + else + rc = request_irq(h->intr[h->intr_mode], intxhandler, + IRQF_SHARED, h->devname, h); if (rc) { dev_err(&h->pdev->dev, "unable to get irq %d for %s\n", h->intr[h->intr_mode], h->devname); @@ -4503,38 +4121,15 @@ static int __devinit hpsa_kdump_soft_reset(struct ctlr_info *h) return 0; } -static void free_irqs(struct ctlr_info *h) -{ - int i; - - if (!h->msix_vector || h->intr_mode != PERF_MODE_INT) { - /* Single reply queue, only one irq to free */ - i = h->intr_mode; - free_irq(h->intr[i], &h->q[i]); - return; - } - - for (i = 0; i < MAX_REPLY_QUEUES; i++) - free_irq(h->intr[i], &h->q[i]); -} - -static void hpsa_free_irqs_and_disable_msix(struct ctlr_info *h) +static void hpsa_undo_allocations_after_kdump_soft_reset(struct ctlr_info *h) { - free_irqs(h); + free_irq(h->intr[h->intr_mode], h); #ifdef CONFIG_PCI_MSI - if (h->msix_vector) { - if (h->pdev->msix_enabled) - pci_disable_msix(h->pdev); - } else if (h->msi_vector) { - if (h->pdev->msi_enabled) - pci_disable_msi(h->pdev); - } + if (h->msix_vector) + pci_disable_msix(h->pdev); + else if (h->msi_vector) + pci_disable_msi(h->pdev); #endif /* CONFIG_PCI_MSI */ -} - -static void hpsa_undo_allocations_after_kdump_soft_reset(struct ctlr_info *h) -{ - hpsa_free_irqs_and_disable_msix(h); hpsa_free_sg_chain_blocks(h); hpsa_free_cmd_pool(h); kfree(h->blockFetchTable); @@ -4570,7 +4165,7 @@ static void fail_all_cmds_on_list(struct ctlr_info *h, struct list_head *list) while (!list_empty(list)) { c = list_entry(list->next, struct CommandList, list); c->err_info->CommandStatus = CMD_HARDWARE_ERR; - finish_cmd(c); + finish_cmd(c, c->Header.Tag.lower); } } @@ -4593,6 +4188,9 @@ static void controller_lockup_detected(struct ctlr_info *h) spin_unlock_irqrestore(&h->lock, flags); } +#define HEARTBEAT_SAMPLE_INTERVAL (10 * HZ) +#define HEARTBEAT_CHECK_MINIMUM_INTERVAL (HEARTBEAT_SAMPLE_INTERVAL / 2) + static void detect_controller_lockup(struct ctlr_info *h) { u64 now; @@ -4603,7 +4201,7 @@ static void detect_controller_lockup(struct ctlr_info *h) now = get_jiffies_64(); /* If we've received an interrupt recently, we're ok. */ if (time_after64(h->last_intr_timestamp + - (h->heartbeat_sample_interval), now)) + (HEARTBEAT_CHECK_MINIMUM_INTERVAL), now)) return; /* @@ -4612,7 +4210,7 @@ static void detect_controller_lockup(struct ctlr_info *h) * otherwise don't care about signals in this thread. */ if (time_after64(h->last_heartbeat_timestamp + - (h->heartbeat_sample_interval), now)) + (HEARTBEAT_CHECK_MINIMUM_INTERVAL), now)) return; /* If heartbeat has not changed since we last looked, we're not ok. */ @@ -4654,7 +4252,6 @@ static void add_ctlr_to_lockup_detector_list(struct ctlr_info *h) { unsigned long flags; - h->heartbeat_sample_interval = HEARTBEAT_SAMPLE_INTERVAL; spin_lock_irqsave(&lockup_detector_lock, flags); list_add_tail(&h->lockup_list, &hpsa_ctlr_list); spin_unlock_irqrestore(&lockup_detector_lock, flags); @@ -4794,7 +4391,7 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev, spin_lock_irqsave(&h->lock, flags); h->access.set_intr_mask(h, HPSA_INTR_OFF); spin_unlock_irqrestore(&h->lock, flags); - free_irqs(h); + free_irq(h->intr[h->intr_mode], h); rc = hpsa_request_irq(h, hpsa_msix_discard_completions, hpsa_intx_discard_completions); if (rc) { @@ -4844,7 +4441,7 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev, clean4: hpsa_free_sg_chain_blocks(h); hpsa_free_cmd_pool(h); - free_irqs(h); + free_irq(h->intr[h->intr_mode], h); clean2: clean1: kfree(h); @@ -4887,7 +4484,13 @@ static void hpsa_shutdown(struct pci_dev *pdev) */ hpsa_flush_cache(h); h->access.set_intr_mask(h, HPSA_INTR_OFF); - hpsa_free_irqs_and_disable_msix(h); + free_irq(h->intr[h->intr_mode], h); +#ifdef CONFIG_PCI_MSI + if (h->msix_vector) + pci_disable_msix(h->pdev); + else if (h->msi_vector) + pci_disable_msi(h->pdev); +#endif /* CONFIG_PCI_MSI */ } static void __devexit hpsa_free_device_info(struct ctlr_info *h) @@ -4926,7 +4529,10 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev) kfree(h->cmd_pool_bits); kfree(h->blockFetchTable); kfree(h->hba_inquiry_data); - pci_disable_device(pdev); + /* + * Deliberately omit pci_disable_device(): it does something nasty to + * Smart Array controllers that pci_enable_device does not undo + */ pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); kfree(h); @@ -5021,8 +4627,11 @@ static __devinit void hpsa_enter_performant_mode(struct ctlr_info *h, * 10 = 6 s/g entry or 24k */ + h->reply_pool_wraparound = 1; /* spec: init to 1 */ + /* Controller spec: zero out this buffer. */ memset(h->reply_pool, 0, h->reply_pool_size); + h->reply_pool_head = h->reply_pool; bft[7] = SG_ENTRIES_IN_CMD + 4; calc_bucket_map(bft, ARRAY_SIZE(bft), @@ -5032,19 +4641,12 @@ static __devinit void hpsa_enter_performant_mode(struct ctlr_info *h, /* size of controller ring buffer */ writel(h->max_commands, &h->transtable->RepQSize); - writel(h->nreply_queues, &h->transtable->RepQCount); + writel(1, &h->transtable->RepQCount); writel(0, &h->transtable->RepQCtrAddrLow32); writel(0, &h->transtable->RepQCtrAddrHigh32); - - for (i = 0; i < h->nreply_queues; i++) { - writel(0, &h->transtable->RepQAddr[i].upper); - writel(h->reply_pool_dhandle + - (h->max_commands * sizeof(u64) * i), - &h->transtable->RepQAddr[i].lower); - } - - writel(CFGTBL_Trans_Performant | use_short_tags | - CFGTBL_Trans_enable_directed_msix, + writel(h->reply_pool_dhandle, &h->transtable->RepQAddr0Low32); + writel(0, &h->transtable->RepQAddr0High32); + writel(CFGTBL_Trans_Performant | use_short_tags, &(h->cfgtable->HostWrite.TransportRequest)); writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); hpsa_wait_for_mode_change_ack(h); @@ -5062,7 +4664,6 @@ static __devinit void hpsa_enter_performant_mode(struct ctlr_info *h, static __devinit void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h) { u32 trans_support; - int i; if (hpsa_simple_mode) return; @@ -5071,20 +4672,12 @@ static __devinit void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h) if (!(trans_support & PERFORMANT_MODE)) return; - h->nreply_queues = h->msix_vector ? MAX_REPLY_QUEUES : 1; hpsa_get_max_perf_mode_cmds(h); /* Performant mode ring buffer and supporting data structures */ - h->reply_pool_size = h->max_commands * sizeof(u64) * h->nreply_queues; + h->reply_pool_size = h->max_commands * sizeof(u64); h->reply_pool = pci_alloc_consistent(h->pdev, h->reply_pool_size, &(h->reply_pool_dhandle)); - for (i = 0; i < h->nreply_queues; i++) { - h->reply_queue[i].head = &h->reply_pool[h->max_commands * i]; - h->reply_queue[i].size = h->max_commands; - h->reply_queue[i].wraparound = 1; /* spec: init to 1 */ - h->reply_queue[i].current_entry = 0; - } - /* Need a block fetch table for performant mode */ h->blockFetchTable = kmalloc(((SG_ENTRIES_IN_CMD + 1) * sizeof(u32)), GFP_KERNEL); diff --git a/trunk/drivers/scsi/hpsa.h b/trunk/drivers/scsi/hpsa.h index 981647989bfd..7b28d54fa878 100644 --- a/trunk/drivers/scsi/hpsa.h +++ b/trunk/drivers/scsi/hpsa.h @@ -34,7 +34,7 @@ struct access_method { void (*set_intr_mask)(struct ctlr_info *h, unsigned long val); unsigned long (*fifo_full)(struct ctlr_info *h); bool (*intr_pending)(struct ctlr_info *h); - unsigned long (*command_completed)(struct ctlr_info *h, u8 q); + unsigned long (*command_completed)(struct ctlr_info *h); }; struct hpsa_scsi_dev_t { @@ -48,13 +48,6 @@ struct hpsa_scsi_dev_t { unsigned char raid_level; /* from inquiry page 0xC1 */ }; -struct reply_pool { - u64 *head; - size_t size; - u8 wraparound; - u32 current_entry; -}; - struct ctlr_info { int ctlr; char devname[8]; @@ -75,7 +68,7 @@ struct ctlr_info { # define DOORBELL_INT 1 # define SIMPLE_MODE_INT 2 # define MEMQ_MODE_INT 3 - unsigned int intr[MAX_REPLY_QUEUES]; + unsigned int intr[4]; unsigned int msix_vector; unsigned int msi_vector; int intr_mode; /* either PERF_MODE_INT or SIMPLE_MODE_INT */ @@ -85,6 +78,7 @@ struct ctlr_info { struct list_head reqQ; struct list_head cmpQ; unsigned int Qdepth; + unsigned int maxQsinceinit; unsigned int maxSG; spinlock_t lock; int maxsgentries; @@ -117,45 +111,20 @@ struct ctlr_info { unsigned long transMethod; /* - * Performant mode completion buffers + * Performant mode completion buffer */ u64 *reply_pool; - size_t reply_pool_size; - struct reply_pool reply_queue[MAX_REPLY_QUEUES]; - u8 nreply_queues; dma_addr_t reply_pool_dhandle; + u64 *reply_pool_head; + size_t reply_pool_size; + unsigned char reply_pool_wraparound; u32 *blockFetchTable; unsigned char *hba_inquiry_data; u64 last_intr_timestamp; u32 last_heartbeat; u64 last_heartbeat_timestamp; - u32 heartbeat_sample_interval; - atomic_t firmware_flash_in_progress; u32 lockup_detected; struct list_head lockup_list; - /* Address of h->q[x] is passed to intr handler to know which queue */ - u8 q[MAX_REPLY_QUEUES]; - u32 TMFSupportFlags; /* cache what task mgmt funcs are supported. */ -#define HPSATMF_BITS_SUPPORTED (1 << 0) -#define HPSATMF_PHYS_LUN_RESET (1 << 1) -#define HPSATMF_PHYS_NEX_RESET (1 << 2) -#define HPSATMF_PHYS_TASK_ABORT (1 << 3) -#define HPSATMF_PHYS_TSET_ABORT (1 << 4) -#define HPSATMF_PHYS_CLEAR_ACA (1 << 5) -#define HPSATMF_PHYS_CLEAR_TSET (1 << 6) -#define HPSATMF_PHYS_QRY_TASK (1 << 7) -#define HPSATMF_PHYS_QRY_TSET (1 << 8) -#define HPSATMF_PHYS_QRY_ASYNC (1 << 9) -#define HPSATMF_MASK_SUPPORTED (1 << 16) -#define HPSATMF_LOG_LUN_RESET (1 << 17) -#define HPSATMF_LOG_NEX_RESET (1 << 18) -#define HPSATMF_LOG_TASK_ABORT (1 << 19) -#define HPSATMF_LOG_TSET_ABORT (1 << 20) -#define HPSATMF_LOG_CLEAR_ACA (1 << 21) -#define HPSATMF_LOG_CLEAR_TSET (1 << 22) -#define HPSATMF_LOG_QRY_TASK (1 << 23) -#define HPSATMF_LOG_QRY_TSET (1 << 24) -#define HPSATMF_LOG_QRY_ASYNC (1 << 25) }; #define HPSA_ABORT_MSG 0 #define HPSA_DEVICE_RESET_MSG 1 @@ -247,6 +216,9 @@ static void SA5_submit_command(struct ctlr_info *h, c->Header.Tag.lower); writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); (void) readl(h->vaddr + SA5_SCRATCHPAD_OFFSET); + h->commands_outstanding++; + if (h->commands_outstanding > h->max_outstanding) + h->max_outstanding = h->commands_outstanding; } /* @@ -282,17 +254,16 @@ static void SA5_performant_intr_mask(struct ctlr_info *h, unsigned long val) } } -static unsigned long SA5_performant_completed(struct ctlr_info *h, u8 q) +static unsigned long SA5_performant_completed(struct ctlr_info *h) { - struct reply_pool *rq = &h->reply_queue[q]; - unsigned long flags, register_value = FIFO_EMPTY; + unsigned long register_value = FIFO_EMPTY; + /* flush the controller write of the reply queue by reading + * outbound doorbell status register. + */ + register_value = readl(h->vaddr + SA5_OUTDB_STATUS); /* msi auto clears the interrupt pending bit. */ if (!(h->msi_vector || h->msix_vector)) { - /* flush the controller write of the reply queue by reading - * outbound doorbell status register. - */ - register_value = readl(h->vaddr + SA5_OUTDB_STATUS); writel(SA5_OUTDB_CLEAR_PERF_BIT, h->vaddr + SA5_OUTDB_CLEAR); /* Do a read in order to flush the write to the controller * (as per spec.) @@ -300,20 +271,19 @@ static unsigned long SA5_performant_completed(struct ctlr_info *h, u8 q) register_value = readl(h->vaddr + SA5_OUTDB_STATUS); } - if ((rq->head[rq->current_entry] & 1) == rq->wraparound) { - register_value = rq->head[rq->current_entry]; - rq->current_entry++; - spin_lock_irqsave(&h->lock, flags); + if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) { + register_value = *(h->reply_pool_head); + (h->reply_pool_head)++; h->commands_outstanding--; - spin_unlock_irqrestore(&h->lock, flags); } else { register_value = FIFO_EMPTY; } /* Check for wraparound */ - if (rq->current_entry == h->max_commands) { - rq->current_entry = 0; - rq->wraparound ^= 1; + if (h->reply_pool_head == (h->reply_pool + h->max_commands)) { + h->reply_pool_head = h->reply_pool; + h->reply_pool_wraparound ^= 1; } + return register_value; } @@ -333,18 +303,13 @@ static unsigned long SA5_fifo_full(struct ctlr_info *h) * returns value read from hardware. * returns FIFO_EMPTY if there is nothing to read */ -static unsigned long SA5_completed(struct ctlr_info *h, - __attribute__((unused)) u8 q) +static unsigned long SA5_completed(struct ctlr_info *h) { unsigned long register_value = readl(h->vaddr + SA5_REPLY_PORT_OFFSET); - unsigned long flags; - if (register_value != FIFO_EMPTY) { - spin_lock_irqsave(&h->lock, flags); + if (register_value != FIFO_EMPTY) h->commands_outstanding--; - spin_unlock_irqrestore(&h->lock, flags); - } #ifdef HPSA_DEBUG if (register_value != FIFO_EMPTY) diff --git a/trunk/drivers/scsi/hpsa_cmd.h b/trunk/drivers/scsi/hpsa_cmd.h index a894f2eca7ac..8049815d8c1e 100644 --- a/trunk/drivers/scsi/hpsa_cmd.h +++ b/trunk/drivers/scsi/hpsa_cmd.h @@ -82,29 +82,6 @@ #define TYPE_CMD 0x00 #define TYPE_MSG 0x01 -/* Message Types */ -#define HPSA_TASK_MANAGEMENT 0x00 -#define HPSA_RESET 0x01 -#define HPSA_SCAN 0x02 -#define HPSA_NOOP 0x03 - -#define HPSA_CTLR_RESET_TYPE 0x00 -#define HPSA_BUS_RESET_TYPE 0x01 -#define HPSA_TARGET_RESET_TYPE 0x03 -#define HPSA_LUN_RESET_TYPE 0x04 -#define HPSA_NEXUS_RESET_TYPE 0x05 - -/* Task Management Functions */ -#define HPSA_TMF_ABORT_TASK 0x00 -#define HPSA_TMF_ABORT_TASK_SET 0x01 -#define HPSA_TMF_CLEAR_ACA 0x02 -#define HPSA_TMF_CLEAR_TASK_SET 0x03 -#define HPSA_TMF_QUERY_TASK 0x04 -#define HPSA_TMF_QUERY_TASK_SET 0x05 -#define HPSA_TMF_QUERY_ASYNCEVENT 0x06 - - - /* config space register offsets */ #define CFG_VENDORID 0x00 #define CFG_DEVICEID 0x02 @@ -129,7 +106,6 @@ #define CFGTBL_Trans_Simple 0x00000002l #define CFGTBL_Trans_Performant 0x00000004l #define CFGTBL_Trans_use_short_tags 0x20000000l -#define CFGTBL_Trans_enable_directed_msix (1 << 30) #define CFGTBL_BusType_Ultra2 0x00000001l #define CFGTBL_BusType_Ultra3 0x00000002l @@ -186,7 +162,6 @@ struct SenseSubsystem_info { #define BMIC_WRITE 0x27 #define BMIC_CACHE_FLUSH 0xc2 #define HPSA_CACHE_FLUSH 0x01 /* C2 was already being used by HPSA */ -#define BMIC_FLASH_FIRMWARE 0xF7 /* Command List Structure */ union SCSI3Addr { @@ -362,17 +337,11 @@ struct CfgTable { u32 MaxPhysicalDevices; u32 MaxPhysicalDrivesPerLogicalUnit; u32 MaxPerformantModeCommands; - u32 MaxBlockFetch; - u32 PowerConservationSupport; - u32 PowerConservationEnable; - u32 TMFSupportFlags; - u8 TMFTagMask[8]; - u8 reserved[0x78 - 0x70]; + u8 reserved[0x78 - 0x58]; u32 misc_fw_support; /* offset 0x78 */ #define MISC_FW_DOORBELL_RESET (0x02) #define MISC_FW_DOORBELL_RESET2 (0x010) u8 driver_version[32]; - }; #define NUM_BLOCKFETCH_ENTRIES 8 @@ -382,8 +351,8 @@ struct TransTable_struct { u32 RepQCount; u32 RepQCtrAddrLow32; u32 RepQCtrAddrHigh32; -#define MAX_REPLY_QUEUES 8 - struct vals32 RepQAddr[MAX_REPLY_QUEUES]; + u32 RepQAddr0Low32; + u32 RepQAddr0High32; }; struct hpsa_pci_info { diff --git a/trunk/drivers/scsi/isci/host.c b/trunk/drivers/scsi/isci/host.c index 45385f531649..d4bf9c12ecd4 100644 --- a/trunk/drivers/scsi/isci/host.c +++ b/trunk/drivers/scsi/isci/host.c @@ -192,27 +192,22 @@ static bool sci_controller_completion_queue_has_entries(struct isci_host *ihost) static bool sci_controller_isr(struct isci_host *ihost) { - if (sci_controller_completion_queue_has_entries(ihost)) + if (sci_controller_completion_queue_has_entries(ihost)) { return true; + } else { + /* + * we have a spurious interrupt it could be that we have already + * emptied the completion queue from a previous interrupt */ + writel(SMU_ISR_COMPLETION, &ihost->smu_registers->interrupt_status); - /* we have a spurious interrupt it could be that we have already - * emptied the completion queue from a previous interrupt - * FIXME: really!? - */ - writel(SMU_ISR_COMPLETION, &ihost->smu_registers->interrupt_status); - - /* There is a race in the hardware that could cause us not to be - * notified of an interrupt completion if we do not take this - * step. We will mask then unmask the interrupts so if there is - * another interrupt pending the clearing of the interrupt - * source we get the next interrupt message. - */ - spin_lock(&ihost->scic_lock); - if (test_bit(IHOST_IRQ_ENABLED, &ihost->flags)) { + /* + * There is a race in the hardware that could cause us not to be notified + * of an interrupt completion if we do not take this step. We will mask + * then unmask the interrupts so if there is another interrupt pending + * the clearing of the interrupt source we get the next interrupt message. */ writel(0xFF000000, &ihost->smu_registers->interrupt_mask); writel(0, &ihost->smu_registers->interrupt_mask); } - spin_unlock(&ihost->scic_lock); return false; } @@ -647,6 +642,7 @@ static void isci_host_start_complete(struct isci_host *ihost, enum sci_status co if (completion_status != SCI_SUCCESS) dev_info(&ihost->pdev->dev, "controller start timed out, continuing...\n"); + isci_host_change_state(ihost, isci_ready); clear_bit(IHOST_START_PENDING, &ihost->flags); wake_up(&ihost->eventq); } @@ -661,7 +657,12 @@ int isci_host_scan_finished(struct Scsi_Host *shost, unsigned long time) sas_drain_work(ha); + dev_dbg(&ihost->pdev->dev, + "%s: ihost->status = %d, time = %ld\n", + __func__, isci_host_get_state(ihost), time); + return 1; + } /** @@ -703,15 +704,14 @@ static u32 sci_controller_get_suggested_start_timeout(struct isci_host *ihost) static void sci_controller_enable_interrupts(struct isci_host *ihost) { - set_bit(IHOST_IRQ_ENABLED, &ihost->flags); + BUG_ON(ihost->smu_registers == NULL); writel(0, &ihost->smu_registers->interrupt_mask); } void sci_controller_disable_interrupts(struct isci_host *ihost) { - clear_bit(IHOST_IRQ_ENABLED, &ihost->flags); + BUG_ON(ihost->smu_registers == NULL); writel(0xffffffff, &ihost->smu_registers->interrupt_mask); - readl(&ihost->smu_registers->interrupt_mask); /* flush */ } static void sci_controller_enable_port_task_scheduler(struct isci_host *ihost) @@ -822,7 +822,7 @@ static void sci_controller_initialize_unsolicited_frame_queue(struct isci_host * &ihost->scu_registers->sdma.unsolicited_frame_put_pointer); } -void sci_controller_transition_to_ready(struct isci_host *ihost, enum sci_status status) +static void sci_controller_transition_to_ready(struct isci_host *ihost, enum sci_status status) { if (ihost->sm.current_state_id == SCIC_STARTING) { /* @@ -849,7 +849,6 @@ static bool is_phy_starting(struct isci_phy *iphy) case SCI_PHY_SUB_AWAIT_SATA_POWER: case SCI_PHY_SUB_AWAIT_SATA_PHY_EN: case SCI_PHY_SUB_AWAIT_SATA_SPEED_EN: - case SCI_PHY_SUB_AWAIT_OSSP_EN: case SCI_PHY_SUB_AWAIT_SIG_FIS_UF: case SCI_PHY_SUB_FINAL: return true; @@ -858,39 +857,6 @@ static bool is_phy_starting(struct isci_phy *iphy) } } -bool is_controller_start_complete(struct isci_host *ihost) -{ - int i; - - for (i = 0; i < SCI_MAX_PHYS; i++) { - struct isci_phy *iphy = &ihost->phys[i]; - u32 state = iphy->sm.current_state_id; - - /* in apc mode we need to check every phy, in - * mpc mode we only need to check phys that have - * been configured into a port - */ - if (is_port_config_apc(ihost)) - /* pass */; - else if (!phy_get_non_dummy_port(iphy)) - continue; - - /* The controller start operation is complete iff: - * - all links have been given an opportunity to start - * - have no indication of a connected device - * - have an indication of a connected device and it has - * finished the link training process. - */ - if ((iphy->is_in_link_training == false && state == SCI_PHY_INITIAL) || - (iphy->is_in_link_training == false && state == SCI_PHY_STOPPED) || - (iphy->is_in_link_training == true && is_phy_starting(iphy)) || - (ihost->port_agent.phy_ready_mask != ihost->port_agent.phy_configured_mask)) - return false; - } - - return true; -} - /** * sci_controller_start_next_phy - start phy * @scic: controller @@ -911,7 +877,36 @@ static enum sci_status sci_controller_start_next_phy(struct isci_host *ihost) return status; if (ihost->next_phy_to_start >= SCI_MAX_PHYS) { - if (is_controller_start_complete(ihost)) { + bool is_controller_start_complete = true; + u32 state; + u8 index; + + for (index = 0; index < SCI_MAX_PHYS; index++) { + iphy = &ihost->phys[index]; + state = iphy->sm.current_state_id; + + if (!phy_get_non_dummy_port(iphy)) + continue; + + /* The controller start operation is complete iff: + * - all links have been given an opportunity to start + * - have no indication of a connected device + * - have an indication of a connected device and it has + * finished the link training process. + */ + if ((iphy->is_in_link_training == false && state == SCI_PHY_INITIAL) || + (iphy->is_in_link_training == false && state == SCI_PHY_STOPPED) || + (iphy->is_in_link_training == true && is_phy_starting(iphy)) || + (ihost->port_agent.phy_ready_mask != ihost->port_agent.phy_configured_mask)) { + is_controller_start_complete = false; + break; + } + } + + /* + * The controller has successfully finished the start process. + * Inform the SCI Core user and transition to the READY state. */ + if (is_controller_start_complete == true) { sci_controller_transition_to_ready(ihost, SCI_SUCCESS); sci_del_timer(&ihost->phy_timer); ihost->phy_startup_timer_pending = false; @@ -992,8 +987,9 @@ static enum sci_status sci_controller_start(struct isci_host *ihost, u16 index; if (ihost->sm.current_state_id != SCIC_INITIALIZED) { - dev_warn(&ihost->pdev->dev, "%s invalid state: %d\n", - __func__, ihost->sm.current_state_id); + dev_warn(&ihost->pdev->dev, + "SCIC Controller start operation requested in " + "invalid state\n"); return SCI_FAILURE_INVALID_STATE; } @@ -1057,8 +1053,9 @@ void isci_host_scan_start(struct Scsi_Host *shost) spin_unlock_irq(&ihost->scic_lock); } -static void isci_host_stop_complete(struct isci_host *ihost) +static void isci_host_stop_complete(struct isci_host *ihost, enum sci_status completion_status) { + isci_host_change_state(ihost, isci_stopped); sci_controller_disable_interrupts(ihost); clear_bit(IHOST_STOP_PENDING, &ihost->flags); wake_up(&ihost->eventq); @@ -1077,32 +1074,6 @@ static void sci_controller_completion_handler(struct isci_host *ihost) writel(0, &ihost->smu_registers->interrupt_mask); } -void ireq_done(struct isci_host *ihost, struct isci_request *ireq, struct sas_task *task) -{ - task->lldd_task = NULL; - if (!test_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags) && - !(task->task_state_flags & SAS_TASK_STATE_ABORTED)) { - if (test_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags)) { - /* Normal notification (task_done) */ - dev_dbg(&ihost->pdev->dev, - "%s: Normal - ireq/task = %p/%p\n", - __func__, ireq, task); - - task->task_done(task); - } else { - dev_dbg(&ihost->pdev->dev, - "%s: Error - ireq/task = %p/%p\n", - __func__, ireq, task); - - sas_task_abort(task); - } - } - if (test_and_clear_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags)) - wake_up_all(&ihost->eventq); - - if (!test_bit(IREQ_NO_AUTO_FREE_TAG, &ireq->flags)) - isci_free_tag(ihost, ireq->io_tag); -} /** * isci_host_completion_routine() - This function is the delayed service * routine that calls the sci core library's completion handler. It's @@ -1111,15 +1082,107 @@ void ireq_done(struct isci_host *ihost, struct isci_request *ireq, struct sas_ta * @data: This parameter specifies the ISCI host object * */ -void isci_host_completion_routine(unsigned long data) +static void isci_host_completion_routine(unsigned long data) { struct isci_host *ihost = (struct isci_host *)data; + struct list_head completed_request_list; + struct list_head errored_request_list; + struct list_head *current_position; + struct list_head *next_position; + struct isci_request *request; + struct isci_request *next_request; + struct sas_task *task; u16 active; + INIT_LIST_HEAD(&completed_request_list); + INIT_LIST_HEAD(&errored_request_list); + spin_lock_irq(&ihost->scic_lock); + sci_controller_completion_handler(ihost); + + /* Take the lists of completed I/Os from the host. */ + + list_splice_init(&ihost->requests_to_complete, + &completed_request_list); + + /* Take the list of errored I/Os from the host. */ + list_splice_init(&ihost->requests_to_errorback, + &errored_request_list); + spin_unlock_irq(&ihost->scic_lock); + /* Process any completions in the lists. */ + list_for_each_safe(current_position, next_position, + &completed_request_list) { + + request = list_entry(current_position, struct isci_request, + completed_node); + task = isci_request_access_task(request); + + /* Normal notification (task_done) */ + dev_dbg(&ihost->pdev->dev, + "%s: Normal - request/task = %p/%p\n", + __func__, + request, + task); + + /* Return the task to libsas */ + if (task != NULL) { + + task->lldd_task = NULL; + if (!(task->task_state_flags & SAS_TASK_STATE_ABORTED)) { + + /* If the task is already in the abort path, + * the task_done callback cannot be called. + */ + task->task_done(task); + } + } + + spin_lock_irq(&ihost->scic_lock); + isci_free_tag(ihost, request->io_tag); + spin_unlock_irq(&ihost->scic_lock); + } + list_for_each_entry_safe(request, next_request, &errored_request_list, + completed_node) { + + task = isci_request_access_task(request); + + /* Use sas_task_abort */ + dev_warn(&ihost->pdev->dev, + "%s: Error - request/task = %p/%p\n", + __func__, + request, + task); + + if (task != NULL) { + + /* Put the task into the abort path if it's not there + * already. + */ + if (!(task->task_state_flags & SAS_TASK_STATE_ABORTED)) + sas_task_abort(task); + + } else { + /* This is a case where the request has completed with a + * status such that it needed further target servicing, + * but the sas_task reference has already been removed + * from the request. Since it was errored, it was not + * being aborted, so there is nothing to do except free + * it. + */ + + spin_lock_irq(&ihost->scic_lock); + /* Remove the request from the remote device's list + * of pending requests. + */ + list_del_init(&request->dev_node); + isci_free_tag(ihost, request->io_tag); + spin_unlock_irq(&ihost->scic_lock); + } + } + /* the coalesence timeout doubles at each encoding step, so * update it based on the ilog2 value of the outstanding requests */ @@ -1150,8 +1213,9 @@ void isci_host_completion_routine(unsigned long data) static enum sci_status sci_controller_stop(struct isci_host *ihost, u32 timeout) { if (ihost->sm.current_state_id != SCIC_READY) { - dev_warn(&ihost->pdev->dev, "%s invalid state: %d\n", - __func__, ihost->sm.current_state_id); + dev_warn(&ihost->pdev->dev, + "SCIC Controller stop operation requested in " + "invalid state\n"); return SCI_FAILURE_INVALID_STATE; } @@ -1177,7 +1241,7 @@ static enum sci_status sci_controller_reset(struct isci_host *ihost) switch (ihost->sm.current_state_id) { case SCIC_RESET: case SCIC_READY: - case SCIC_STOPPING: + case SCIC_STOPPED: case SCIC_FAILED: /* * The reset operation is not a graceful cleanup, just @@ -1186,50 +1250,13 @@ static enum sci_status sci_controller_reset(struct isci_host *ihost) sci_change_state(&ihost->sm, SCIC_RESETTING); return SCI_SUCCESS; default: - dev_warn(&ihost->pdev->dev, "%s invalid state: %d\n", - __func__, ihost->sm.current_state_id); + dev_warn(&ihost->pdev->dev, + "SCIC Controller reset operation requested in " + "invalid state\n"); return SCI_FAILURE_INVALID_STATE; } } -static enum sci_status sci_controller_stop_phys(struct isci_host *ihost) -{ - u32 index; - enum sci_status status; - enum sci_status phy_status; - - status = SCI_SUCCESS; - - for (index = 0; index < SCI_MAX_PHYS; index++) { - phy_status = sci_phy_stop(&ihost->phys[index]); - - if (phy_status != SCI_SUCCESS && - phy_status != SCI_FAILURE_INVALID_STATE) { - status = SCI_FAILURE; - - dev_warn(&ihost->pdev->dev, - "%s: Controller stop operation failed to stop " - "phy %d because of status %d.\n", - __func__, - ihost->phys[index].phy_index, phy_status); - } - } - - return status; -} - - -/** - * isci_host_deinit - shutdown frame reception and dma - * @ihost: host to take down - * - * This is called in either the driver shutdown or the suspend path. In - * the shutdown case libsas went through port teardown and normal device - * removal (i.e. physical links stayed up to service scsi_device removal - * commands). In the suspend case we disable the hardware without - * notifying libsas of the link down events since we want libsas to - * remember the domain across the suspend/resume cycle - */ void isci_host_deinit(struct isci_host *ihost) { int i; @@ -1238,6 +1265,17 @@ void isci_host_deinit(struct isci_host *ihost) for (i = 0; i < isci_gpio_count(ihost); i++) writel(SGPIO_HW_CONTROL, &ihost->scu_registers->peg0.sgpio.output_data_select[i]); + isci_host_change_state(ihost, isci_stopping); + for (i = 0; i < SCI_MAX_PORTS; i++) { + struct isci_port *iport = &ihost->ports[i]; + struct isci_remote_device *idev, *d; + + list_for_each_entry_safe(idev, d, &iport->remote_dev_list, node) { + if (test_bit(IDEV_ALLOCATED, &idev->flags)) + isci_remote_device_stop(ihost, idev); + } + } + set_bit(IHOST_STOP_PENDING, &ihost->flags); spin_lock_irq(&ihost->scic_lock); @@ -1246,21 +1284,12 @@ void isci_host_deinit(struct isci_host *ihost) wait_for_stop(ihost); - /* phy stop is after controller stop to allow port and device to - * go idle before shutting down the phys, but the expectation is - * that i/o has been shut off well before we reach this - * function. - */ - sci_controller_stop_phys(ihost); - /* disable sgpio: where the above wait should give time for the * enclosure to sample the gpios going inactive */ writel(0, &ihost->scu_registers->peg0.sgpio.interface_control); - spin_lock_irq(&ihost->scic_lock); sci_controller_reset(ihost); - spin_unlock_irq(&ihost->scic_lock); /* Cancel any/all outstanding port timers */ for (i = 0; i < ihost->logical_port_entries; i++) { @@ -1299,6 +1328,29 @@ static void __iomem *smu_base(struct isci_host *isci_host) return pcim_iomap_table(pdev)[SCI_SMU_BAR * 2] + SCI_SMU_BAR_SIZE * id; } +static void isci_user_parameters_get(struct sci_user_parameters *u) +{ + int i; + + for (i = 0; i < SCI_MAX_PHYS; i++) { + struct sci_phy_user_params *u_phy = &u->phys[i]; + + u_phy->max_speed_generation = phy_gen; + + /* we are not exporting these for now */ + u_phy->align_insertion_frequency = 0x7f; + u_phy->in_connection_align_insertion_frequency = 0xff; + u_phy->notify_enable_spin_up_insertion_frequency = 0x33; + } + + u->stp_inactivity_timeout = stp_inactive_to; + u->ssp_inactivity_timeout = ssp_inactive_to; + u->stp_max_occupancy_timeout = stp_max_occ_to; + u->ssp_max_occupancy_timeout = ssp_max_occ_to; + u->no_outbound_task_timeout = no_outbound_task_to; + u->max_concurr_spinup = max_concurr_spinup; +} + static void sci_controller_initial_state_enter(struct sci_base_state_machine *sm) { struct isci_host *ihost = container_of(sm, typeof(*ihost), sm); @@ -1458,6 +1510,32 @@ static void sci_controller_ready_state_exit(struct sci_base_state_machine *sm) sci_controller_set_interrupt_coalescence(ihost, 0, 0); } +static enum sci_status sci_controller_stop_phys(struct isci_host *ihost) +{ + u32 index; + enum sci_status status; + enum sci_status phy_status; + + status = SCI_SUCCESS; + + for (index = 0; index < SCI_MAX_PHYS; index++) { + phy_status = sci_phy_stop(&ihost->phys[index]); + + if (phy_status != SCI_SUCCESS && + phy_status != SCI_FAILURE_INVALID_STATE) { + status = SCI_FAILURE; + + dev_warn(&ihost->pdev->dev, + "%s: Controller stop operation failed to stop " + "phy %d because of status %d.\n", + __func__, + ihost->phys[index].phy_index, phy_status); + } + } + + return status; +} + static enum sci_status sci_controller_stop_ports(struct isci_host *ihost) { u32 index; @@ -1517,11 +1595,10 @@ static void sci_controller_stopping_state_enter(struct sci_base_state_machine *s { struct isci_host *ihost = container_of(sm, typeof(*ihost), sm); - sci_controller_stop_devices(ihost); + /* Stop all of the components for this controller */ + sci_controller_stop_phys(ihost); sci_controller_stop_ports(ihost); - - if (!sci_controller_has_remote_devices_stopping(ihost)) - isci_host_stop_complete(ihost); + sci_controller_stop_devices(ihost); } static void sci_controller_stopping_state_exit(struct sci_base_state_machine *sm) @@ -1547,9 +1624,6 @@ static void sci_controller_reset_hardware(struct isci_host *ihost) /* The write to the UFQGP clears the UFQPR */ writel(0, &ihost->scu_registers->sdma.unsolicited_frame_get_pointer); - - /* clear all interrupts */ - writel(~SMU_INTERRUPT_STATUS_RESERVED_MASK, &ihost->smu_registers->interrupt_status); } static void sci_controller_resetting_state_enter(struct sci_base_state_machine *sm) @@ -1581,9 +1655,59 @@ static const struct sci_base_state sci_controller_state_table[] = { .enter_state = sci_controller_stopping_state_enter, .exit_state = sci_controller_stopping_state_exit, }, + [SCIC_STOPPED] = {}, [SCIC_FAILED] = {} }; +static void sci_controller_set_default_config_parameters(struct isci_host *ihost) +{ + /* these defaults are overridden by the platform / firmware */ + u16 index; + + /* Default to APC mode. */ + ihost->oem_parameters.controller.mode_type = SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE; + + /* Default to APC mode. */ + ihost->oem_parameters.controller.max_concurr_spin_up = 1; + + /* Default to no SSC operation. */ + ihost->oem_parameters.controller.do_enable_ssc = false; + + /* Default to short cables on all phys. */ + ihost->oem_parameters.controller.cable_selection_mask = 0; + + /* Initialize all of the port parameter information to narrow ports. */ + for (index = 0; index < SCI_MAX_PORTS; index++) { + ihost->oem_parameters.ports[index].phy_mask = 0; + } + + /* Initialize all of the phy parameter information. */ + for (index = 0; index < SCI_MAX_PHYS; index++) { + /* Default to 3G (i.e. Gen 2). */ + ihost->user_parameters.phys[index].max_speed_generation = + SCIC_SDS_PARM_GEN2_SPEED; + + /* the frequencies cannot be 0 */ + ihost->user_parameters.phys[index].align_insertion_frequency = 0x7f; + ihost->user_parameters.phys[index].in_connection_align_insertion_frequency = 0xff; + ihost->user_parameters.phys[index].notify_enable_spin_up_insertion_frequency = 0x33; + + /* + * Previous Vitesse based expanders had a arbitration issue that + * is worked around by having the upper 32-bits of SAS address + * with a value greater then the Vitesse company identifier. + * Hence, usage of 0x5FCFFFFF. */ + ihost->oem_parameters.phys[index].sas_address.low = 0x1 + ihost->id; + ihost->oem_parameters.phys[index].sas_address.high = 0x5FCFFFFF; + } + + ihost->user_parameters.stp_inactivity_timeout = 5; + ihost->user_parameters.ssp_inactivity_timeout = 5; + ihost->user_parameters.stp_max_occupancy_timeout = 5; + ihost->user_parameters.ssp_max_occupancy_timeout = 20; + ihost->user_parameters.no_outbound_task_timeout = 2; +} + static void controller_timeout(unsigned long data) { struct sci_timer *tmr = (struct sci_timer *)data; @@ -1600,7 +1724,7 @@ static void controller_timeout(unsigned long data) sci_controller_transition_to_ready(ihost, SCI_FAILURE_TIMEOUT); else if (sm->current_state_id == SCIC_STOPPING) { sci_change_state(sm, SCIC_FAILED); - isci_host_stop_complete(ihost); + isci_host_stop_complete(ihost, SCI_FAILURE_TIMEOUT); } else /* / @todo Now what do we want to do in this case? */ dev_err(&ihost->pdev->dev, "%s: Controller timer fired when controller was not " @@ -1640,6 +1764,9 @@ static enum sci_status sci_controller_construct(struct isci_host *ihost, sci_init_timer(&ihost->timer, controller_timeout); + /* Initialize the User and OEM parameters to default values. */ + sci_controller_set_default_config_parameters(ihost); + return sci_controller_reset(ihost); } @@ -1719,6 +1846,27 @@ int sci_oem_parameters_validate(struct sci_oem_params *oem, u8 version) return 0; } +static enum sci_status sci_oem_parameters_set(struct isci_host *ihost) +{ + u32 state = ihost->sm.current_state_id; + struct isci_pci_info *pci_info = to_pci_info(ihost->pdev); + + if (state == SCIC_RESET || + state == SCIC_INITIALIZING || + state == SCIC_INITIALIZED) { + u8 oem_version = pci_info->orom ? pci_info->orom->hdr.version : + ISCI_ROM_VER_1_0; + + if (sci_oem_parameters_validate(&ihost->oem_parameters, + oem_version)) + return SCI_FAILURE_INVALID_PARAMETER_VALUE; + + return SCI_SUCCESS; + } + + return SCI_FAILURE_INVALID_STATE; +} + static u8 max_spin_up(struct isci_host *ihost) { if (ihost->user_parameters.max_concurr_spinup) @@ -1766,7 +1914,7 @@ static void power_control_timeout(unsigned long data) ihost->power_control.phys_granted_power++; sci_phy_consume_power_handler(iphy); - if (iphy->protocol == SAS_PROTOCOL_SSP) { + if (iphy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) { u8 j; for (j = 0; j < SCI_MAX_PHYS; j++) { @@ -1840,7 +1988,7 @@ void sci_controller_power_control_queue_insert(struct isci_host *ihost, sizeof(current_phy->frame_rcvd.iaf.sas_addr)); if (current_phy->sm.current_state_id == SCI_PHY_READY && - current_phy->protocol == SAS_PROTOCOL_SSP && + current_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS && other == 0) { sci_phy_consume_power_handler(iphy); break; @@ -2131,8 +2279,9 @@ static enum sci_status sci_controller_initialize(struct isci_host *ihost) unsigned long i, state, val; if (ihost->sm.current_state_id != SCIC_RESET) { - dev_warn(&ihost->pdev->dev, "%s invalid state: %d\n", - __func__, ihost->sm.current_state_id); + dev_warn(&ihost->pdev->dev, + "SCIC Controller initialize operation requested " + "in invalid state\n"); return SCI_FAILURE_INVALID_STATE; } @@ -2235,76 +2384,96 @@ static enum sci_status sci_controller_initialize(struct isci_host *ihost) return result; } -static int sci_controller_dma_alloc(struct isci_host *ihost) +static enum sci_status sci_user_parameters_set(struct isci_host *ihost, + struct sci_user_parameters *sci_parms) +{ + u32 state = ihost->sm.current_state_id; + + if (state == SCIC_RESET || + state == SCIC_INITIALIZING || + state == SCIC_INITIALIZED) { + u16 index; + + /* + * Validate the user parameters. If they are not legal, then + * return a failure. + */ + for (index = 0; index < SCI_MAX_PHYS; index++) { + struct sci_phy_user_params *user_phy; + + user_phy = &sci_parms->phys[index]; + + if (!((user_phy->max_speed_generation <= + SCIC_SDS_PARM_MAX_SPEED) && + (user_phy->max_speed_generation > + SCIC_SDS_PARM_NO_SPEED))) + return SCI_FAILURE_INVALID_PARAMETER_VALUE; + + if (user_phy->in_connection_align_insertion_frequency < + 3) + return SCI_FAILURE_INVALID_PARAMETER_VALUE; + + if ((user_phy->in_connection_align_insertion_frequency < + 3) || + (user_phy->align_insertion_frequency == 0) || + (user_phy-> + notify_enable_spin_up_insertion_frequency == + 0)) + return SCI_FAILURE_INVALID_PARAMETER_VALUE; + } + + if ((sci_parms->stp_inactivity_timeout == 0) || + (sci_parms->ssp_inactivity_timeout == 0) || + (sci_parms->stp_max_occupancy_timeout == 0) || + (sci_parms->ssp_max_occupancy_timeout == 0) || + (sci_parms->no_outbound_task_timeout == 0)) + return SCI_FAILURE_INVALID_PARAMETER_VALUE; + + memcpy(&ihost->user_parameters, sci_parms, sizeof(*sci_parms)); + + return SCI_SUCCESS; + } + + return SCI_FAILURE_INVALID_STATE; +} + +static int sci_controller_mem_init(struct isci_host *ihost) { struct device *dev = &ihost->pdev->dev; + dma_addr_t dma; size_t size; - int i; - - /* detect re-initialization */ - if (ihost->completion_queue) - return 0; + int err; size = SCU_MAX_COMPLETION_QUEUE_ENTRIES * sizeof(u32); - ihost->completion_queue = dmam_alloc_coherent(dev, size, &ihost->cq_dma, - GFP_KERNEL); + ihost->completion_queue = dmam_alloc_coherent(dev, size, &dma, GFP_KERNEL); if (!ihost->completion_queue) return -ENOMEM; + writel(lower_32_bits(dma), &ihost->smu_registers->completion_queue_lower); + writel(upper_32_bits(dma), &ihost->smu_registers->completion_queue_upper); + size = ihost->remote_node_entries * sizeof(union scu_remote_node_context); - ihost->remote_node_context_table = dmam_alloc_coherent(dev, size, &ihost->rnc_dma, + ihost->remote_node_context_table = dmam_alloc_coherent(dev, size, &dma, GFP_KERNEL); - if (!ihost->remote_node_context_table) return -ENOMEM; + writel(lower_32_bits(dma), &ihost->smu_registers->remote_node_context_lower); + writel(upper_32_bits(dma), &ihost->smu_registers->remote_node_context_upper); + size = ihost->task_context_entries * sizeof(struct scu_task_context), - ihost->task_context_table = dmam_alloc_coherent(dev, size, &ihost->tc_dma, - GFP_KERNEL); + ihost->task_context_table = dmam_alloc_coherent(dev, size, &dma, GFP_KERNEL); if (!ihost->task_context_table) return -ENOMEM; - size = SCI_UFI_TOTAL_SIZE; - ihost->ufi_buf = dmam_alloc_coherent(dev, size, &ihost->ufi_dma, GFP_KERNEL); - if (!ihost->ufi_buf) - return -ENOMEM; - - for (i = 0; i < SCI_MAX_IO_REQUESTS; i++) { - struct isci_request *ireq; - dma_addr_t dma; - - ireq = dmam_alloc_coherent(dev, sizeof(*ireq), &dma, GFP_KERNEL); - if (!ireq) - return -ENOMEM; - - ireq->tc = &ihost->task_context_table[i]; - ireq->owning_controller = ihost; - ireq->request_daddr = dma; - ireq->isci_host = ihost; - ihost->reqs[i] = ireq; - } - - return 0; -} - -static int sci_controller_mem_init(struct isci_host *ihost) -{ - int err = sci_controller_dma_alloc(ihost); + ihost->task_context_dma = dma; + writel(lower_32_bits(dma), &ihost->smu_registers->host_task_table_lower); + writel(upper_32_bits(dma), &ihost->smu_registers->host_task_table_upper); + err = sci_unsolicited_frame_control_construct(ihost); if (err) return err; - writel(lower_32_bits(ihost->cq_dma), &ihost->smu_registers->completion_queue_lower); - writel(upper_32_bits(ihost->cq_dma), &ihost->smu_registers->completion_queue_upper); - - writel(lower_32_bits(ihost->rnc_dma), &ihost->smu_registers->remote_node_context_lower); - writel(upper_32_bits(ihost->rnc_dma), &ihost->smu_registers->remote_node_context_upper); - - writel(lower_32_bits(ihost->tc_dma), &ihost->smu_registers->host_task_table_lower); - writel(upper_32_bits(ihost->tc_dma), &ihost->smu_registers->host_task_table_upper); - - sci_unsolicited_frame_control_construct(ihost); - /* * Inform the silicon as to the location of the UF headers and * address table. @@ -2322,22 +2491,22 @@ static int sci_controller_mem_init(struct isci_host *ihost) return 0; } -/** - * isci_host_init - (re-)initialize hardware and internal (private) state - * @ihost: host to init - * - * Any public facing objects (like asd_sas_port, and asd_sas_phys), or - * one-time initialization objects like locks and waitqueues, are - * not touched (they are initialized in isci_host_alloc) - */ int isci_host_init(struct isci_host *ihost) { - int i, err; + int err = 0, i; enum sci_status status; + struct sci_user_parameters sci_user_params; + struct isci_pci_info *pci_info = to_pci_info(ihost->pdev); + + spin_lock_init(&ihost->state_lock); + spin_lock_init(&ihost->scic_lock); + init_waitqueue_head(&ihost->eventq); + + isci_host_change_state(ihost, isci_starting); + + status = sci_controller_construct(ihost, scu_base(ihost), + smu_base(ihost)); - spin_lock_irq(&ihost->scic_lock); - status = sci_controller_construct(ihost, scu_base(ihost), smu_base(ihost)); - spin_unlock_irq(&ihost->scic_lock); if (status != SCI_SUCCESS) { dev_err(&ihost->pdev->dev, "%s: sci_controller_construct failed - status = %x\n", @@ -2346,6 +2515,48 @@ int isci_host_init(struct isci_host *ihost) return -ENODEV; } + ihost->sas_ha.dev = &ihost->pdev->dev; + ihost->sas_ha.lldd_ha = ihost; + + /* + * grab initial values stored in the controller object for OEM and USER + * parameters + */ + isci_user_parameters_get(&sci_user_params); + status = sci_user_parameters_set(ihost, &sci_user_params); + if (status != SCI_SUCCESS) { + dev_warn(&ihost->pdev->dev, + "%s: sci_user_parameters_set failed\n", + __func__); + return -ENODEV; + } + + /* grab any OEM parameters specified in orom */ + if (pci_info->orom) { + status = isci_parse_oem_parameters(&ihost->oem_parameters, + pci_info->orom, + ihost->id); + if (status != SCI_SUCCESS) { + dev_warn(&ihost->pdev->dev, + "parsing firmware oem parameters failed\n"); + return -EINVAL; + } + } + + status = sci_oem_parameters_set(ihost); + if (status != SCI_SUCCESS) { + dev_warn(&ihost->pdev->dev, + "%s: sci_oem_parameters_set failed\n", + __func__); + return -ENODEV; + } + + tasklet_init(&ihost->completion_tasklet, + isci_host_completion_routine, (unsigned long)ihost); + + INIT_LIST_HEAD(&ihost->requests_to_complete); + INIT_LIST_HEAD(&ihost->requests_to_errorback); + spin_lock_irq(&ihost->scic_lock); status = sci_controller_initialize(ihost); spin_unlock_irq(&ihost->scic_lock); @@ -2361,12 +2572,43 @@ int isci_host_init(struct isci_host *ihost) if (err) return err; + for (i = 0; i < SCI_MAX_PORTS; i++) + isci_port_init(&ihost->ports[i], ihost, i); + + for (i = 0; i < SCI_MAX_PHYS; i++) + isci_phy_init(&ihost->phys[i], ihost, i); + /* enable sgpio */ writel(1, &ihost->scu_registers->peg0.sgpio.interface_control); for (i = 0; i < isci_gpio_count(ihost); i++) writel(SGPIO_HW_CONTROL, &ihost->scu_registers->peg0.sgpio.output_data_select[i]); writel(0, &ihost->scu_registers->peg0.sgpio.vendor_specific_code); + for (i = 0; i < SCI_MAX_REMOTE_DEVICES; i++) { + struct isci_remote_device *idev = &ihost->devices[i]; + + INIT_LIST_HEAD(&idev->reqs_in_process); + INIT_LIST_HEAD(&idev->node); + } + + for (i = 0; i < SCI_MAX_IO_REQUESTS; i++) { + struct isci_request *ireq; + dma_addr_t dma; + + ireq = dmam_alloc_coherent(&ihost->pdev->dev, + sizeof(struct isci_request), &dma, + GFP_KERNEL); + if (!ireq) + return -ENOMEM; + + ireq->tc = &ihost->task_context_table[i]; + ireq->owning_controller = ihost; + spin_lock_init(&ireq->state_lock); + ireq->request_daddr = dma; + ireq->isci_host = ihost; + ihost->reqs[i] = ireq; + } + return 0; } @@ -2412,7 +2654,7 @@ void sci_controller_link_down(struct isci_host *ihost, struct isci_port *iport, } } -bool sci_controller_has_remote_devices_stopping(struct isci_host *ihost) +static bool sci_controller_has_remote_devices_stopping(struct isci_host *ihost) { u32 index; @@ -2438,7 +2680,7 @@ void sci_controller_remote_device_stopped(struct isci_host *ihost, } if (!sci_controller_has_remote_devices_stopping(ihost)) - isci_host_stop_complete(ihost); + sci_change_state(&ihost->sm, SCIC_STOPPED); } void sci_controller_post_request(struct isci_host *ihost, u32 request) @@ -2600,8 +2842,7 @@ enum sci_status sci_controller_start_io(struct isci_host *ihost, enum sci_status status; if (ihost->sm.current_state_id != SCIC_READY) { - dev_warn(&ihost->pdev->dev, "%s invalid state: %d\n", - __func__, ihost->sm.current_state_id); + dev_warn(&ihost->pdev->dev, "invalid state to start I/O"); return SCI_FAILURE_INVALID_STATE; } @@ -2625,26 +2866,22 @@ enum sci_status sci_controller_terminate_request(struct isci_host *ihost, enum sci_status status; if (ihost->sm.current_state_id != SCIC_READY) { - dev_warn(&ihost->pdev->dev, "%s invalid state: %d\n", - __func__, ihost->sm.current_state_id); + dev_warn(&ihost->pdev->dev, + "invalid state to terminate request\n"); return SCI_FAILURE_INVALID_STATE; } - status = sci_io_request_terminate(ireq); - dev_dbg(&ihost->pdev->dev, "%s: status=%d; ireq=%p; flags=%lx\n", - __func__, status, ireq, ireq->flags); + status = sci_io_request_terminate(ireq); + if (status != SCI_SUCCESS) + return status; - if ((status == SCI_SUCCESS) && - !test_bit(IREQ_PENDING_ABORT, &ireq->flags) && - !test_and_set_bit(IREQ_TC_ABORT_POSTED, &ireq->flags)) { - /* Utilize the original post context command and or in the - * POST_TC_ABORT request sub-type. - */ - sci_controller_post_request( - ihost, ireq->post_context | - SCU_CONTEXT_COMMAND_REQUEST_POST_TC_ABORT); - } - return status; + /* + * Utilize the original post context command and or in the POST_TC_ABORT + * request sub-type. + */ + sci_controller_post_request(ihost, + ireq->post_context | SCU_CONTEXT_COMMAND_REQUEST_POST_TC_ABORT); + return SCI_SUCCESS; } /** @@ -2678,8 +2915,7 @@ enum sci_status sci_controller_complete_io(struct isci_host *ihost, clear_bit(IREQ_ACTIVE, &ireq->flags); return SCI_SUCCESS; default: - dev_warn(&ihost->pdev->dev, "%s invalid state: %d\n", - __func__, ihost->sm.current_state_id); + dev_warn(&ihost->pdev->dev, "invalid state to complete I/O"); return SCI_FAILURE_INVALID_STATE; } @@ -2690,8 +2926,7 @@ enum sci_status sci_controller_continue_io(struct isci_request *ireq) struct isci_host *ihost = ireq->owning_controller; if (ihost->sm.current_state_id != SCIC_READY) { - dev_warn(&ihost->pdev->dev, "%s invalid state: %d\n", - __func__, ihost->sm.current_state_id); + dev_warn(&ihost->pdev->dev, "invalid state to continue I/O"); return SCI_FAILURE_INVALID_STATE; } diff --git a/trunk/drivers/scsi/isci/host.h b/trunk/drivers/scsi/isci/host.h index 9ab58e0540e7..adbad69d1069 100644 --- a/trunk/drivers/scsi/isci/host.h +++ b/trunk/drivers/scsi/isci/host.h @@ -55,7 +55,6 @@ #ifndef _SCI_HOST_H_ #define _SCI_HOST_H_ -#include #include "remote_device.h" #include "phy.h" #include "isci.h" @@ -109,8 +108,6 @@ struct sci_port_configuration_agent; typedef void (*port_config_fn)(struct isci_host *, struct sci_port_configuration_agent *, struct isci_port *, struct isci_phy *); -bool is_port_config_apc(struct isci_host *ihost); -bool is_controller_start_complete(struct isci_host *ihost); struct sci_port_configuration_agent { u16 phy_configured_mask; @@ -160,17 +157,13 @@ struct isci_host { struct sci_power_control power_control; u8 io_request_sequence[SCI_MAX_IO_REQUESTS]; struct scu_task_context *task_context_table; - dma_addr_t tc_dma; + dma_addr_t task_context_dma; union scu_remote_node_context *remote_node_context_table; - dma_addr_t rnc_dma; u32 *completion_queue; - dma_addr_t cq_dma; u32 completion_queue_get; u32 logical_port_entries; u32 remote_node_entries; u32 task_context_entries; - void *ufi_buf; - dma_addr_t ufi_dma; struct sci_unsolicited_frame_control uf_control; /* phy startup */ @@ -197,13 +190,17 @@ struct isci_host { struct asd_sas_port sas_ports[SCI_MAX_PORTS]; struct sas_ha_struct sas_ha; + spinlock_t state_lock; struct pci_dev *pdev; + enum isci_status status; #define IHOST_START_PENDING 0 #define IHOST_STOP_PENDING 1 - #define IHOST_IRQ_ENABLED 2 unsigned long flags; wait_queue_head_t eventq; + struct Scsi_Host *shost; struct tasklet_struct completion_tasklet; + struct list_head requests_to_complete; + struct list_head requests_to_errorback; spinlock_t scic_lock; struct isci_request *reqs[SCI_MAX_IO_REQUESTS]; struct isci_remote_device devices[SCI_MAX_REMOTE_DEVICES]; @@ -276,6 +273,13 @@ enum sci_controller_states { */ SCIC_STOPPING, + /** + * This state indicates that the controller has successfully been stopped. + * In this state no new IO operations are permitted. + * This state is entered from the STOPPING state. + */ + SCIC_STOPPED, + /** * This state indicates that the controller could not successfully be * initialized. In this state no new IO operations are permitted. @@ -305,16 +309,32 @@ static inline struct isci_pci_info *to_pci_info(struct pci_dev *pdev) return pci_get_drvdata(pdev); } -static inline struct Scsi_Host *to_shost(struct isci_host *ihost) -{ - return ihost->sas_ha.core.shost; -} - #define for_each_isci_host(id, ihost, pdev) \ for (id = 0, ihost = to_pci_info(pdev)->hosts[id]; \ id < ARRAY_SIZE(to_pci_info(pdev)->hosts) && ihost; \ ihost = to_pci_info(pdev)->hosts[++id]) +static inline enum isci_status isci_host_get_state(struct isci_host *isci_host) +{ + return isci_host->status; +} + +static inline void isci_host_change_state(struct isci_host *isci_host, + enum isci_status status) +{ + unsigned long flags; + + dev_dbg(&isci_host->pdev->dev, + "%s: isci_host = %p, state = 0x%x", + __func__, + isci_host, + status); + spin_lock_irqsave(&isci_host->state_lock, flags); + isci_host->status = status; + spin_unlock_irqrestore(&isci_host->state_lock, flags); + +} + static inline void wait_for_start(struct isci_host *ihost) { wait_event(ihost->eventq, !test_bit(IHOST_START_PENDING, &ihost->flags)); @@ -340,11 +360,6 @@ static inline struct isci_host *dev_to_ihost(struct domain_device *dev) return dev->port->ha->lldd_ha; } -static inline struct isci_host *idev_to_ihost(struct isci_remote_device *idev) -{ - return dev_to_ihost(idev->domain_dev); -} - /* we always use protocol engine group zero */ #define ISCI_PEG 0 @@ -363,7 +378,8 @@ static inline int sci_remote_device_node_count(struct isci_remote_device *idev) { struct domain_device *dev = idev->domain_dev; - if (dev_is_sata(dev) && dev->parent) + if ((dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) && + !idev->is_direct_attached) return SCU_STP_REMOTE_NODE_COUNT; return SCU_SSP_REMOTE_NODE_COUNT; } @@ -459,17 +475,36 @@ void sci_controller_free_remote_node_context( struct isci_remote_device *idev, u16 node_id); -struct isci_request *sci_request_by_tag(struct isci_host *ihost, u16 io_tag); -void sci_controller_power_control_queue_insert(struct isci_host *ihost, - struct isci_phy *iphy); -void sci_controller_power_control_queue_remove(struct isci_host *ihost, - struct isci_phy *iphy); -void sci_controller_link_up(struct isci_host *ihost, struct isci_port *iport, - struct isci_phy *iphy); -void sci_controller_link_down(struct isci_host *ihost, struct isci_port *iport, - struct isci_phy *iphy); -void sci_controller_remote_device_stopped(struct isci_host *ihost, - struct isci_remote_device *idev); +struct isci_request *sci_request_by_tag(struct isci_host *ihost, + u16 io_tag); + +void sci_controller_power_control_queue_insert( + struct isci_host *ihost, + struct isci_phy *iphy); + +void sci_controller_power_control_queue_remove( + struct isci_host *ihost, + struct isci_phy *iphy); + +void sci_controller_link_up( + struct isci_host *ihost, + struct isci_port *iport, + struct isci_phy *iphy); + +void sci_controller_link_down( + struct isci_host *ihost, + struct isci_port *iport, + struct isci_phy *iphy); + +void sci_controller_remote_device_stopped( + struct isci_host *ihost, + struct isci_remote_device *idev); + +void sci_controller_copy_task_context( + struct isci_host *ihost, + struct isci_request *ireq); + +void sci_controller_register_setup(struct isci_host *ihost); enum sci_status sci_controller_continue_io(struct isci_request *ireq); int isci_host_scan_finished(struct Scsi_Host *, unsigned long); @@ -477,14 +512,29 @@ void isci_host_scan_start(struct Scsi_Host *); u16 isci_alloc_tag(struct isci_host *ihost); enum sci_status isci_free_tag(struct isci_host *ihost, u16 io_tag); void isci_tci_free(struct isci_host *ihost, u16 tci); -void ireq_done(struct isci_host *ihost, struct isci_request *ireq, struct sas_task *task); int isci_host_init(struct isci_host *); -void isci_host_completion_routine(unsigned long data); -void isci_host_deinit(struct isci_host *); -void sci_controller_disable_interrupts(struct isci_host *ihost); -bool sci_controller_has_remote_devices_stopping(struct isci_host *ihost); -void sci_controller_transition_to_ready(struct isci_host *ihost, enum sci_status status); + +void isci_host_init_controller_names( + struct isci_host *isci_host, + unsigned int controller_idx); + +void isci_host_deinit( + struct isci_host *); + +void isci_host_port_link_up( + struct isci_host *, + struct isci_port *, + struct isci_phy *); +int isci_host_dev_found(struct domain_device *); + +void isci_host_remote_device_start_complete( + struct isci_host *, + struct isci_remote_device *, + enum sci_status); + +void sci_controller_disable_interrupts( + struct isci_host *ihost); enum sci_status sci_controller_start_io( struct isci_host *ihost, diff --git a/trunk/drivers/scsi/isci/init.c b/trunk/drivers/scsi/isci/init.c index 47e28b555029..5137db5a5d85 100644 --- a/trunk/drivers/scsi/isci/init.c +++ b/trunk/drivers/scsi/isci/init.c @@ -271,12 +271,13 @@ static void isci_unregister(struct isci_host *isci_host) if (!isci_host) return; + shost = isci_host->shost; + sas_unregister_ha(&isci_host->sas_ha); - shost = to_shost(isci_host); - sas_remove_host(shost); - scsi_remove_host(shost); - scsi_host_put(shost); + sas_remove_host(isci_host->shost); + scsi_remove_host(isci_host->shost); + scsi_host_put(isci_host->shost); } static int __devinit isci_pci_init(struct pci_dev *pdev) @@ -396,199 +397,38 @@ static int isci_setup_interrupts(struct pci_dev *pdev) return err; } -static void isci_user_parameters_get(struct sci_user_parameters *u) -{ - int i; - - for (i = 0; i < SCI_MAX_PHYS; i++) { - struct sci_phy_user_params *u_phy = &u->phys[i]; - - u_phy->max_speed_generation = phy_gen; - - /* we are not exporting these for now */ - u_phy->align_insertion_frequency = 0x7f; - u_phy->in_connection_align_insertion_frequency = 0xff; - u_phy->notify_enable_spin_up_insertion_frequency = 0x33; - } - - u->stp_inactivity_timeout = stp_inactive_to; - u->ssp_inactivity_timeout = ssp_inactive_to; - u->stp_max_occupancy_timeout = stp_max_occ_to; - u->ssp_max_occupancy_timeout = ssp_max_occ_to; - u->no_outbound_task_timeout = no_outbound_task_to; - u->max_concurr_spinup = max_concurr_spinup; -} - -static enum sci_status sci_user_parameters_set(struct isci_host *ihost, - struct sci_user_parameters *sci_parms) -{ - u16 index; - - /* - * Validate the user parameters. If they are not legal, then - * return a failure. - */ - for (index = 0; index < SCI_MAX_PHYS; index++) { - struct sci_phy_user_params *u; - - u = &sci_parms->phys[index]; - - if (!((u->max_speed_generation <= SCIC_SDS_PARM_MAX_SPEED) && - (u->max_speed_generation > SCIC_SDS_PARM_NO_SPEED))) - return SCI_FAILURE_INVALID_PARAMETER_VALUE; - - if (u->in_connection_align_insertion_frequency < 3) - return SCI_FAILURE_INVALID_PARAMETER_VALUE; - - if ((u->in_connection_align_insertion_frequency < 3) || - (u->align_insertion_frequency == 0) || - (u->notify_enable_spin_up_insertion_frequency == 0)) - return SCI_FAILURE_INVALID_PARAMETER_VALUE; - } - - if ((sci_parms->stp_inactivity_timeout == 0) || - (sci_parms->ssp_inactivity_timeout == 0) || - (sci_parms->stp_max_occupancy_timeout == 0) || - (sci_parms->ssp_max_occupancy_timeout == 0) || - (sci_parms->no_outbound_task_timeout == 0)) - return SCI_FAILURE_INVALID_PARAMETER_VALUE; - - memcpy(&ihost->user_parameters, sci_parms, sizeof(*sci_parms)); - - return SCI_SUCCESS; -} - -static void sci_oem_defaults(struct isci_host *ihost) -{ - /* these defaults are overridden by the platform / firmware */ - struct sci_user_parameters *user = &ihost->user_parameters; - struct sci_oem_params *oem = &ihost->oem_parameters; - int i; - - /* Default to APC mode. */ - oem->controller.mode_type = SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE; - - /* Default to APC mode. */ - oem->controller.max_concurr_spin_up = 1; - - /* Default to no SSC operation. */ - oem->controller.do_enable_ssc = false; - - /* Default to short cables on all phys. */ - oem->controller.cable_selection_mask = 0; - - /* Initialize all of the port parameter information to narrow ports. */ - for (i = 0; i < SCI_MAX_PORTS; i++) - oem->ports[i].phy_mask = 0; - - /* Initialize all of the phy parameter information. */ - for (i = 0; i < SCI_MAX_PHYS; i++) { - /* Default to 3G (i.e. Gen 2). */ - user->phys[i].max_speed_generation = SCIC_SDS_PARM_GEN2_SPEED; - - /* the frequencies cannot be 0 */ - user->phys[i].align_insertion_frequency = 0x7f; - user->phys[i].in_connection_align_insertion_frequency = 0xff; - user->phys[i].notify_enable_spin_up_insertion_frequency = 0x33; - - /* Previous Vitesse based expanders had a arbitration issue that - * is worked around by having the upper 32-bits of SAS address - * with a value greater then the Vitesse company identifier. - * Hence, usage of 0x5FCFFFFF. - */ - oem->phys[i].sas_address.low = 0x1 + ihost->id; - oem->phys[i].sas_address.high = 0x5FCFFFFF; - } - - user->stp_inactivity_timeout = 5; - user->ssp_inactivity_timeout = 5; - user->stp_max_occupancy_timeout = 5; - user->ssp_max_occupancy_timeout = 20; - user->no_outbound_task_timeout = 2; -} - static struct isci_host *isci_host_alloc(struct pci_dev *pdev, int id) { - struct isci_orom *orom = to_pci_info(pdev)->orom; - struct sci_user_parameters sci_user_params; - u8 oem_version = ISCI_ROM_VER_1_0; - struct isci_host *ihost; + struct isci_host *isci_host; struct Scsi_Host *shost; - int err, i; - - ihost = devm_kzalloc(&pdev->dev, sizeof(*ihost), GFP_KERNEL); - if (!ihost) - return NULL; + int err; - ihost->pdev = pdev; - ihost->id = id; - spin_lock_init(&ihost->scic_lock); - init_waitqueue_head(&ihost->eventq); - ihost->sas_ha.dev = &ihost->pdev->dev; - ihost->sas_ha.lldd_ha = ihost; - tasklet_init(&ihost->completion_tasklet, - isci_host_completion_routine, (unsigned long)ihost); - - /* validate module parameters */ - /* TODO: kill struct sci_user_parameters and reference directly */ - sci_oem_defaults(ihost); - isci_user_parameters_get(&sci_user_params); - if (sci_user_parameters_set(ihost, &sci_user_params)) { - dev_warn(&pdev->dev, - "%s: sci_user_parameters_set failed\n", __func__); + isci_host = devm_kzalloc(&pdev->dev, sizeof(*isci_host), GFP_KERNEL); + if (!isci_host) return NULL; - } - - /* sanity check platform (or 'firmware') oem parameters */ - if (orom) { - if (id < 0 || id >= SCI_MAX_CONTROLLERS || id > orom->hdr.num_elements) { - dev_warn(&pdev->dev, "parsing firmware oem parameters failed\n"); - return NULL; - } - ihost->oem_parameters = orom->ctrl[id]; - oem_version = orom->hdr.version; - } - /* validate oem parameters (platform, firmware, or built-in defaults) */ - if (sci_oem_parameters_validate(&ihost->oem_parameters, oem_version)) { - dev_warn(&pdev->dev, "oem parameter validation failed\n"); - return NULL; - } - - for (i = 0; i < SCI_MAX_PORTS; i++) { - struct isci_port *iport = &ihost->ports[i]; - - INIT_LIST_HEAD(&iport->remote_dev_list); - iport->isci_host = ihost; - } - - for (i = 0; i < SCI_MAX_PHYS; i++) - isci_phy_init(&ihost->phys[i], ihost, i); - - for (i = 0; i < SCI_MAX_REMOTE_DEVICES; i++) { - struct isci_remote_device *idev = &ihost->devices[i]; - - INIT_LIST_HEAD(&idev->node); - } + isci_host->pdev = pdev; + isci_host->id = id; shost = scsi_host_alloc(&isci_sht, sizeof(void *)); if (!shost) return NULL; + isci_host->shost = shost; dev_info(&pdev->dev, "%sSCU controller %d: phy 3-0 cables: " "{%s, %s, %s, %s}\n", - (is_cable_select_overridden() ? "* " : ""), ihost->id, - lookup_cable_names(decode_cable_selection(ihost, 3)), - lookup_cable_names(decode_cable_selection(ihost, 2)), - lookup_cable_names(decode_cable_selection(ihost, 1)), - lookup_cable_names(decode_cable_selection(ihost, 0))); + (is_cable_select_overridden() ? "* " : ""), isci_host->id, + lookup_cable_names(decode_cable_selection(isci_host, 3)), + lookup_cable_names(decode_cable_selection(isci_host, 2)), + lookup_cable_names(decode_cable_selection(isci_host, 1)), + lookup_cable_names(decode_cable_selection(isci_host, 0))); - err = isci_host_init(ihost); + err = isci_host_init(isci_host); if (err) goto err_shost; - SHOST_TO_SAS_HA(shost) = &ihost->sas_ha; - ihost->sas_ha.core.shost = shost; + SHOST_TO_SAS_HA(shost) = &isci_host->sas_ha; + isci_host->sas_ha.core.shost = shost; shost->transportt = isci_transport_template; shost->max_id = ~0; @@ -599,11 +439,11 @@ static struct isci_host *isci_host_alloc(struct pci_dev *pdev, int id) if (err) goto err_shost; - err = isci_register_sas_ha(ihost); + err = isci_register_sas_ha(isci_host); if (err) goto err_shost_remove; - return ihost; + return isci_host; err_shost_remove: scsi_remove_host(shost); @@ -636,7 +476,7 @@ static int __devinit isci_pci_probe(struct pci_dev *pdev, const struct pci_devic if (!orom) orom = isci_request_oprom(pdev); - for (i = 0; orom && i < num_controllers(pdev); i++) { + for (i = 0; orom && i < ARRAY_SIZE(orom->ctrl); i++) { if (sci_oem_parameters_validate(&orom->ctrl[i], orom->hdr.version)) { dev_warn(&pdev->dev, @@ -685,11 +525,11 @@ static int __devinit isci_pci_probe(struct pci_dev *pdev, const struct pci_devic pci_info->hosts[i] = h; /* turn on DIF support */ - scsi_host_set_prot(to_shost(h), + scsi_host_set_prot(h->shost, SHOST_DIF_TYPE1_PROTECTION | SHOST_DIF_TYPE2_PROTECTION | SHOST_DIF_TYPE3_PROTECTION); - scsi_host_set_guard(to_shost(h), SHOST_DIX_GUARD_CRC); + scsi_host_set_guard(h->shost, SHOST_DIX_GUARD_CRC); } err = isci_setup_interrupts(pdev); @@ -697,7 +537,7 @@ static int __devinit isci_pci_probe(struct pci_dev *pdev, const struct pci_devic goto err_host_alloc; for_each_isci_host(i, isci_host, pdev) - scsi_scan_host(to_shost(isci_host)); + scsi_scan_host(isci_host->shost); return 0; diff --git a/trunk/drivers/scsi/isci/phy.c b/trunk/drivers/scsi/isci/phy.c index 18f43d4c30ba..fab3586840b5 100644 --- a/trunk/drivers/scsi/isci/phy.c +++ b/trunk/drivers/scsi/isci/phy.c @@ -580,7 +580,7 @@ static void sci_phy_start_sas_link_training(struct isci_phy *iphy) sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SAS_SPEED_EN); - iphy->protocol = SAS_PROTOCOL_SSP; + iphy->protocol = SCIC_SDS_PHY_PROTOCOL_SAS; } static void sci_phy_start_sata_link_training(struct isci_phy *iphy) @@ -591,7 +591,7 @@ static void sci_phy_start_sata_link_training(struct isci_phy *iphy) */ sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SATA_POWER); - iphy->protocol = SAS_PROTOCOL_SATA; + iphy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA; } /** @@ -668,19 +668,6 @@ static const char *phy_event_name(u32 event_code) phy_to_host(iphy)->id, iphy->phy_index, \ phy_state_name(state), phy_event_name(code), code) - -void scu_link_layer_set_txcomsas_timeout(struct isci_phy *iphy, u32 timeout) -{ - u32 val; - - /* Extend timeout */ - val = readl(&iphy->link_layer_registers->transmit_comsas_signal); - val &= ~SCU_SAS_LLTXCOMSAS_GEN_VAL(NEGTIME, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_MASK); - val |= SCU_SAS_LLTXCOMSAS_GEN_VAL(NEGTIME, timeout); - - writel(val, &iphy->link_layer_registers->transmit_comsas_signal); -} - enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) { enum sci_phy_states state = iphy->sm.current_state_id; @@ -696,13 +683,6 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) sci_phy_start_sata_link_training(iphy); iphy->is_in_link_training = true; break; - case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT: - /* Extend timeout value */ - scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_EXTENDED); - - /* Start the oob/sn state machine over again */ - sci_change_state(&iphy->sm, SCI_PHY_STARTING); - break; default: phy_event_dbg(iphy, state, event_code); return SCI_FAILURE; @@ -737,19 +717,9 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) sci_phy_start_sata_link_training(iphy); break; case SCU_EVENT_LINK_FAILURE: - /* Change the timeout value to default */ - scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_DEFAULT); - /* Link failure change state back to the starting state */ sci_change_state(&iphy->sm, SCI_PHY_STARTING); break; - case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT: - /* Extend the timeout value */ - scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_EXTENDED); - - /* Start the oob/sn state machine over again */ - sci_change_state(&iphy->sm, SCI_PHY_STARTING); - break; default: phy_event_warn(iphy, state, event_code); return SCI_FAILURE; @@ -770,14 +740,7 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) sci_phy_start_sata_link_training(iphy); break; case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT: - /* Extend the timeout value */ - scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_EXTENDED); - - /* Start the oob/sn state machine over again */ - sci_change_state(&iphy->sm, SCI_PHY_STARTING); - break; case SCU_EVENT_LINK_FAILURE: - scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_DEFAULT); case SCU_EVENT_HARD_RESET_RECEIVED: /* Start the oob/sn state machine over again */ sci_change_state(&iphy->sm, SCI_PHY_STARTING); @@ -790,9 +753,6 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) case SCI_PHY_SUB_AWAIT_SAS_POWER: switch (scu_get_event_code(event_code)) { case SCU_EVENT_LINK_FAILURE: - /* Change the timeout value to default */ - scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_DEFAULT); - /* Link failure change state back to the starting state */ sci_change_state(&iphy->sm, SCI_PHY_STARTING); break; @@ -804,9 +764,6 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) case SCI_PHY_SUB_AWAIT_SATA_POWER: switch (scu_get_event_code(event_code)) { case SCU_EVENT_LINK_FAILURE: - /* Change the timeout value to default */ - scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_DEFAULT); - /* Link failure change state back to the starting state */ sci_change_state(&iphy->sm, SCI_PHY_STARTING); break; @@ -831,9 +788,6 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) case SCI_PHY_SUB_AWAIT_SATA_PHY_EN: switch (scu_get_event_code(event_code)) { case SCU_EVENT_LINK_FAILURE: - /* Change the timeout value to default */ - scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_DEFAULT); - /* Link failure change state back to the starting state */ sci_change_state(&iphy->sm, SCI_PHY_STARTING); break; @@ -843,7 +797,7 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) */ break; case SCU_EVENT_SATA_PHY_DETECTED: - iphy->protocol = SAS_PROTOCOL_SATA; + iphy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA; /* We have received the SATA PHY notification change state */ sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SATA_SPEED_EN); @@ -882,9 +836,6 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) SCI_PHY_SUB_AWAIT_SIG_FIS_UF); break; case SCU_EVENT_LINK_FAILURE: - /* Change the timeout value to default */ - scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_DEFAULT); - /* Link failure change state back to the starting state */ sci_change_state(&iphy->sm, SCI_PHY_STARTING); break; @@ -908,9 +859,6 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) break; case SCU_EVENT_LINK_FAILURE: - /* Change the timeout value to default */ - scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_DEFAULT); - /* Link failure change state back to the starting state */ sci_change_state(&iphy->sm, SCI_PHY_STARTING); break; @@ -923,26 +871,16 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) case SCI_PHY_READY: switch (scu_get_event_code(event_code)) { case SCU_EVENT_LINK_FAILURE: - /* Set default timeout */ - scu_link_layer_set_txcomsas_timeout(iphy, SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_DEFAULT); - /* Link failure change state back to the starting state */ sci_change_state(&iphy->sm, SCI_PHY_STARTING); break; case SCU_EVENT_BROADCAST_CHANGE: - case SCU_EVENT_BROADCAST_SES: - case SCU_EVENT_BROADCAST_RESERVED0: - case SCU_EVENT_BROADCAST_RESERVED1: - case SCU_EVENT_BROADCAST_EXPANDER: - case SCU_EVENT_BROADCAST_AEN: /* Broadcast change received. Notify the port. */ if (phy_get_non_dummy_port(iphy) != NULL) sci_port_broadcast_change_received(iphy->owning_port, iphy); else iphy->bcn_received_while_port_unassigned = true; break; - case SCU_EVENT_BROADCAST_RESERVED3: - case SCU_EVENT_BROADCAST_RESERVED4: default: phy_event_warn(iphy, state, event_code); return SCI_FAILURE_INVALID_STATE; @@ -1277,7 +1215,7 @@ static void sci_phy_starting_state_enter(struct sci_base_state_machine *sm) scu_link_layer_start_oob(iphy); /* We don't know what kind of phy we are going to be just yet */ - iphy->protocol = SAS_PROTOCOL_NONE; + iphy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN; iphy->bcn_received_while_port_unassigned = false; if (iphy->sm.previous_state_id == SCI_PHY_READY) @@ -1312,7 +1250,7 @@ static void sci_phy_resetting_state_enter(struct sci_base_state_machine *sm) */ sci_port_deactivate_phy(iphy->owning_port, iphy, false); - if (iphy->protocol == SAS_PROTOCOL_SSP) { + if (iphy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) { scu_link_layer_tx_hard_reset(iphy); } else { /* The SCU does not need to have a discrete reset state so @@ -1378,7 +1316,7 @@ void sci_phy_construct(struct isci_phy *iphy, iphy->owning_port = iport; iphy->phy_index = phy_index; iphy->bcn_received_while_port_unassigned = false; - iphy->protocol = SAS_PROTOCOL_NONE; + iphy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN; iphy->link_layer_registers = NULL; iphy->max_negotiated_speed = SAS_LINK_RATE_UNKNOWN; @@ -1442,14 +1380,12 @@ int isci_phy_control(struct asd_sas_phy *sas_phy, switch (func) { case PHY_FUNC_DISABLE: spin_lock_irqsave(&ihost->scic_lock, flags); - scu_link_layer_start_oob(iphy); sci_phy_stop(iphy); spin_unlock_irqrestore(&ihost->scic_lock, flags); break; case PHY_FUNC_LINK_RESET: spin_lock_irqsave(&ihost->scic_lock, flags); - scu_link_layer_start_oob(iphy); sci_phy_stop(iphy); sci_phy_start(iphy); spin_unlock_irqrestore(&ihost->scic_lock, flags); diff --git a/trunk/drivers/scsi/isci/phy.h b/trunk/drivers/scsi/isci/phy.h index 45fecfa36a98..0e45833ba06d 100644 --- a/trunk/drivers/scsi/isci/phy.h +++ b/trunk/drivers/scsi/isci/phy.h @@ -76,6 +76,13 @@ */ #define SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT 250 +enum sci_phy_protocol { + SCIC_SDS_PHY_PROTOCOL_UNKNOWN, + SCIC_SDS_PHY_PROTOCOL_SAS, + SCIC_SDS_PHY_PROTOCOL_SATA, + SCIC_SDS_MAX_PHY_PROTOCOLS +}; + /** * isci_phy - hba local phy infrastructure * @sm: @@ -88,7 +95,7 @@ struct isci_phy { struct sci_base_state_machine sm; struct isci_port *owning_port; enum sas_linkrate max_negotiated_speed; - enum sas_protocol protocol; + enum sci_phy_protocol protocol; u8 phy_index; bool bcn_received_while_port_unassigned; bool is_in_link_training; diff --git a/trunk/drivers/scsi/isci/port.c b/trunk/drivers/scsi/isci/port.c index 2fb85bf75449..5fada73b71ff 100644 --- a/trunk/drivers/scsi/isci/port.c +++ b/trunk/drivers/scsi/isci/port.c @@ -184,7 +184,7 @@ static void isci_port_link_up(struct isci_host *isci_host, sci_port_get_properties(iport, &properties); - if (iphy->protocol == SAS_PROTOCOL_SATA) { + if (iphy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) { u64 attached_sas_address; iphy->sas_phy.oob_mode = SATA_OOB_MODE; @@ -204,7 +204,7 @@ static void isci_port_link_up(struct isci_host *isci_host, memcpy(&iphy->sas_phy.attached_sas_addr, &attached_sas_address, sizeof(attached_sas_address)); - } else if (iphy->protocol == SAS_PROTOCOL_SSP) { + } else if (iphy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) { iphy->sas_phy.oob_mode = SAS_OOB_MODE; iphy->sas_phy.frame_rcvd_size = sizeof(struct sas_identify_frame); @@ -251,10 +251,10 @@ static void isci_port_link_down(struct isci_host *isci_host, if (isci_phy->sas_phy.port && isci_phy->sas_phy.port->num_phys == 1) { /* change the state for all devices on this port. The - * next task sent to this device will be returned as - * SAS_TASK_UNDELIVERED, and the scsi mid layer will - * remove the target - */ + * next task sent to this device will be returned as + * SAS_TASK_UNDELIVERED, and the scsi mid layer will + * remove the target + */ list_for_each_entry(isci_device, &isci_port->remote_dev_list, node) { @@ -517,7 +517,7 @@ void sci_port_get_attached_sas_address(struct isci_port *iport, struct sci_sas_a */ iphy = sci_port_get_a_connected_phy(iport); if (iphy) { - if (iphy->protocol != SAS_PROTOCOL_SATA) { + if (iphy->protocol != SCIC_SDS_PHY_PROTOCOL_SATA) { sci_phy_get_attached_sas_address(iphy, sas); } else { sci_phy_get_sas_address(iphy, sas); @@ -624,7 +624,7 @@ static void sci_port_activate_phy(struct isci_port *iport, { struct isci_host *ihost = iport->owning_controller; - if (iphy->protocol != SAS_PROTOCOL_SATA && (flags & PF_RESUME)) + if (iphy->protocol != SCIC_SDS_PHY_PROTOCOL_SATA && (flags & PF_RESUME)) sci_phy_resume(iphy); iport->active_phy_mask |= 1 << iphy->phy_index; @@ -751,10 +751,12 @@ static bool sci_port_is_wide(struct isci_port *iport) * wide ports and direct attached phys. Since there are no wide ported SATA * devices this could become an invalid port configuration. */ -bool sci_port_link_detected(struct isci_port *iport, struct isci_phy *iphy) +bool sci_port_link_detected( + struct isci_port *iport, + struct isci_phy *iphy) { if ((iport->logical_port_index != SCIC_SDS_DUMMY_PORT) && - (iphy->protocol == SAS_PROTOCOL_SATA)) { + (iphy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA)) { if (sci_port_is_wide(iport)) { sci_port_invalid_link_up(iport, iphy); return false; @@ -1199,8 +1201,6 @@ enum sci_status sci_port_add_phy(struct isci_port *iport, enum sci_status status; enum sci_port_states state; - sci_port_bcn_enable(iport); - state = iport->sm.current_state_id; switch (state) { case SCI_PORT_STOPPED: { @@ -1548,29 +1548,6 @@ static void sci_port_failed_state_enter(struct sci_base_state_machine *sm) isci_port_hard_reset_complete(iport, SCI_FAILURE_TIMEOUT); } -void sci_port_set_hang_detection_timeout(struct isci_port *iport, u32 timeout) -{ - int phy_index; - u32 phy_mask = iport->active_phy_mask; - - if (timeout) - ++iport->hang_detect_users; - else if (iport->hang_detect_users > 1) - --iport->hang_detect_users; - else - iport->hang_detect_users = 0; - - if (timeout || (iport->hang_detect_users == 0)) { - for (phy_index = 0; phy_index < SCI_MAX_PHYS; phy_index++) { - if ((phy_mask >> phy_index) & 1) { - writel(timeout, - &iport->phy_table[phy_index] - ->link_layer_registers - ->link_layer_hang_detection_timeout); - } - } - } -} /* --------------------------------------------------------------------------- */ static const struct sci_base_state sci_port_state_table[] = { @@ -1619,7 +1596,6 @@ void sci_port_construct(struct isci_port *iport, u8 index, iport->started_request_count = 0; iport->assigned_device_count = 0; - iport->hang_detect_users = 0; iport->reserved_rni = SCU_DUMMY_INDEX; iport->reserved_tag = SCI_CONTROLLER_INVALID_IO_TAG; @@ -1632,6 +1608,13 @@ void sci_port_construct(struct isci_port *iport, u8 index, iport->phy_table[index] = NULL; } +void isci_port_init(struct isci_port *iport, struct isci_host *ihost, int index) +{ + INIT_LIST_HEAD(&iport->remote_dev_list); + INIT_LIST_HEAD(&iport->domain_dev_list); + iport->isci_host = ihost; +} + void sci_port_broadcast_change_received(struct isci_port *iport, struct isci_phy *iphy) { struct isci_host *ihost = iport->owning_controller; @@ -1688,6 +1671,17 @@ int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *ipor __func__, iport, status); } + + /* If the hard reset for the port has failed, consider this + * the same as link failures on all phys in the port. + */ + if (ret != TMF_RESP_FUNC_COMPLETE) { + + dev_err(&ihost->pdev->dev, + "%s: iport = %p; hard reset failed " + "(0x%x) - driving explicit link fail for all phys\n", + __func__, iport, iport->hard_reset_status); + } return ret; } @@ -1746,7 +1740,7 @@ void isci_port_formed(struct asd_sas_phy *phy) struct isci_host *ihost = phy->ha->lldd_ha; struct isci_phy *iphy = to_iphy(phy); struct asd_sas_port *port = phy->port; - struct isci_port *iport = NULL; + struct isci_port *iport; unsigned long flags; int i; diff --git a/trunk/drivers/scsi/isci/port.h b/trunk/drivers/scsi/isci/port.h index 861e8f72811b..6b56240c2051 100644 --- a/trunk/drivers/scsi/isci/port.h +++ b/trunk/drivers/scsi/isci/port.h @@ -97,6 +97,7 @@ enum isci_status { struct isci_port { struct isci_host *isci_host; struct list_head remote_dev_list; + struct list_head domain_dev_list; #define IPORT_RESET_PENDING 0 unsigned long state; enum sci_status hard_reset_status; @@ -111,7 +112,6 @@ struct isci_port { u16 reserved_tag; u32 started_request_count; u32 assigned_device_count; - u32 hang_detect_users; u32 not_ready_reason; struct isci_phy *phy_table[SCI_MAX_PHYS]; struct isci_host *owning_controller; @@ -270,13 +270,14 @@ void sci_port_get_attached_sas_address( struct isci_port *iport, struct sci_sas_address *sas_address); -void sci_port_set_hang_detection_timeout( - struct isci_port *isci_port, - u32 timeout); - void isci_port_formed(struct asd_sas_phy *); void isci_port_deformed(struct asd_sas_phy *); +void isci_port_init( + struct isci_port *port, + struct isci_host *host, + int index); + int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *iport, struct isci_phy *iphy); int isci_ata_check_ready(struct domain_device *dev); diff --git a/trunk/drivers/scsi/isci/port_config.c b/trunk/drivers/scsi/isci/port_config.c index cd962da4a57a..6d1e9544cbe5 100644 --- a/trunk/drivers/scsi/isci/port_config.c +++ b/trunk/drivers/scsi/isci/port_config.c @@ -57,7 +57,7 @@ #define SCIC_SDS_MPC_RECONFIGURATION_TIMEOUT (10) #define SCIC_SDS_APC_RECONFIGURATION_TIMEOUT (10) -#define SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION (1000) +#define SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION (250) enum SCIC_SDS_APC_ACTIVITY { SCIC_SDS_APC_SKIP_PHY, @@ -472,9 +472,13 @@ sci_apc_agent_validate_phy_configuration(struct isci_host *ihost, * down event or a link up event where we can not yet tell to which a phy * belongs. */ -static void sci_apc_agent_start_timer(struct sci_port_configuration_agent *port_agent, - u32 timeout) +static void sci_apc_agent_start_timer( + struct sci_port_configuration_agent *port_agent, + u32 timeout) { + if (port_agent->timer_pending) + sci_del_timer(&port_agent->timer); + port_agent->timer_pending = true; sci_mod_timer(&port_agent->timer, timeout); } @@ -693,9 +697,6 @@ static void apc_agent_timeout(unsigned long data) &ihost->phys[index], false); } - if (is_controller_start_complete(ihost)) - sci_controller_transition_to_ready(ihost, SCI_SUCCESS); - done: spin_unlock_irqrestore(&ihost->scic_lock, flags); } @@ -731,11 +732,6 @@ void sci_port_configuration_agent_construct( } } -bool is_port_config_apc(struct isci_host *ihost) -{ - return ihost->port_agent.link_up_handler == sci_apc_agent_link_up; -} - enum sci_status sci_port_configuration_agent_initialize( struct isci_host *ihost, struct sci_port_configuration_agent *port_agent) diff --git a/trunk/drivers/scsi/isci/probe_roms.c b/trunk/drivers/scsi/isci/probe_roms.c index 4d95654c3fd4..9b8117b9d756 100644 --- a/trunk/drivers/scsi/isci/probe_roms.c +++ b/trunk/drivers/scsi/isci/probe_roms.c @@ -112,6 +112,18 @@ struct isci_orom *isci_request_oprom(struct pci_dev *pdev) return rom; } +enum sci_status isci_parse_oem_parameters(struct sci_oem_params *oem, + struct isci_orom *orom, int scu_index) +{ + /* check for valid inputs */ + if (scu_index < 0 || scu_index >= SCI_MAX_CONTROLLERS || + scu_index > orom->hdr.num_elements || !oem) + return -EINVAL; + + *oem = orom->ctrl[scu_index]; + return 0; +} + struct isci_orom *isci_request_firmware(struct pci_dev *pdev, const struct firmware *fw) { struct isci_orom *orom = NULL, *data; diff --git a/trunk/drivers/scsi/isci/probe_roms.h b/trunk/drivers/scsi/isci/probe_roms.h index e08b578241f8..bb0e9d4d97c9 100644 --- a/trunk/drivers/scsi/isci/probe_roms.h +++ b/trunk/drivers/scsi/isci/probe_roms.h @@ -156,6 +156,8 @@ int sci_oem_parameters_validate(struct sci_oem_params *oem, u8 version); struct isci_orom; struct isci_orom *isci_request_oprom(struct pci_dev *pdev); +enum sci_status isci_parse_oem_parameters(struct sci_oem_params *oem, + struct isci_orom *orom, int scu_index); struct isci_orom *isci_request_firmware(struct pci_dev *pdev, const struct firmware *fw); struct isci_orom *isci_get_efi_var(struct pci_dev *pdev); diff --git a/trunk/drivers/scsi/isci/registers.h b/trunk/drivers/scsi/isci/registers.h index 97f3ceb8d724..7eb0ccd45fe6 100644 --- a/trunk/drivers/scsi/isci/registers.h +++ b/trunk/drivers/scsi/isci/registers.h @@ -1239,14 +1239,6 @@ struct scu_transport_layer_registers { #define SCU_SAS_LLCTL_GEN_BIT(name) \ SCU_GEN_BIT(SCU_SAS_LINK_LAYER_CONTROL_ ## name) -#define SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_DEFAULT (0xF0) -#define SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_EXTENDED (0x1FF) -#define SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_SHIFT (0) -#define SCU_SAS_LINK_LAYER_TXCOMSAS_NEGTIME_MASK (0x3FF) - -#define SCU_SAS_LLTXCOMSAS_GEN_VAL(name, value) \ - SCU_GEN_VALUE(SCU_SAS_LINK_LAYER_TXCOMSAS_ ## name, value) - /* #define SCU_FRXHECR_DCNT_OFFSET 0x00B0 */ #define SCU_PSZGCR_OFFSET 0x00E4 diff --git a/trunk/drivers/scsi/isci/remote_device.c b/trunk/drivers/scsi/isci/remote_device.c index c3aa6c5457b9..8f501b0a81d6 100644 --- a/trunk/drivers/scsi/isci/remote_device.c +++ b/trunk/drivers/scsi/isci/remote_device.c @@ -72,11 +72,46 @@ const char *dev_state_name(enum sci_remote_device_states state) } #undef C -enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev, - enum sci_remote_node_suspension_reasons reason) +/** + * isci_remote_device_not_ready() - This function is called by the ihost when + * the remote device is not ready. We mark the isci device as ready (not + * "ready_for_io") and signal the waiting proccess. + * @isci_host: This parameter specifies the isci host object. + * @isci_device: This parameter specifies the remote device + * + * sci_lock is held on entrance to this function. + */ +static void isci_remote_device_not_ready(struct isci_host *ihost, + struct isci_remote_device *idev, u32 reason) { - return sci_remote_node_context_suspend(&idev->rnc, reason, - SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT); + struct isci_request *ireq; + + dev_dbg(&ihost->pdev->dev, + "%s: isci_device = %p\n", __func__, idev); + + switch (reason) { + case SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED: + set_bit(IDEV_GONE, &idev->flags); + break; + case SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED: + set_bit(IDEV_IO_NCQERROR, &idev->flags); + + /* Kill all outstanding requests for the device. */ + list_for_each_entry(ireq, &idev->reqs_in_process, dev_node) { + + dev_dbg(&ihost->pdev->dev, + "%s: isci_device = %p request = %p\n", + __func__, idev, ireq); + + sci_controller_terminate_request(ihost, + idev, + ireq); + } + /* Fall through into the default case... */ + default: + clear_bit(IDEV_IO_READY, &idev->flags); + break; + } } /** @@ -98,29 +133,18 @@ static void isci_remote_device_ready(struct isci_host *ihost, struct isci_remote wake_up(&ihost->eventq); } -static enum sci_status sci_remote_device_terminate_req( - struct isci_host *ihost, - struct isci_remote_device *idev, - int check_abort, - struct isci_request *ireq) +/* called once the remote node context is ready to be freed. + * The remote device can now report that its stop operation is complete. none + */ +static void rnc_destruct_done(void *_dev) { - if (!test_bit(IREQ_ACTIVE, &ireq->flags) || - (ireq->target_device != idev) || - (check_abort && !test_bit(IREQ_PENDING_ABORT, &ireq->flags))) - return SCI_SUCCESS; - - dev_dbg(&ihost->pdev->dev, - "%s: idev=%p; flags=%lx; req=%p; req target=%p\n", - __func__, idev, idev->flags, ireq, ireq->target_device); - - set_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags); + struct isci_remote_device *idev = _dev; - return sci_controller_terminate_request(ihost, idev, ireq); + BUG_ON(idev->started_request_count != 0); + sci_change_state(&idev->sm, SCI_DEV_STOPPED); } -static enum sci_status sci_remote_device_terminate_reqs_checkabort( - struct isci_remote_device *idev, - int chk) +static enum sci_status sci_remote_device_terminate_requests(struct isci_remote_device *idev) { struct isci_host *ihost = idev->owning_port->owning_controller; enum sci_status status = SCI_SUCCESS; @@ -130,210 +154,18 @@ static enum sci_status sci_remote_device_terminate_reqs_checkabort( struct isci_request *ireq = ihost->reqs[i]; enum sci_status s; - s = sci_remote_device_terminate_req(ihost, idev, chk, ireq); + if (!test_bit(IREQ_ACTIVE, &ireq->flags) || + ireq->target_device != idev) + continue; + + s = sci_controller_terminate_request(ihost, idev, ireq); if (s != SCI_SUCCESS) status = s; } - return status; -} - -static bool isci_compare_suspendcount( - struct isci_remote_device *idev, - u32 localcount) -{ - smp_rmb(); - - /* Check for a change in the suspend count, or the RNC - * being destroyed. - */ - return (localcount != idev->rnc.suspend_count) - || sci_remote_node_context_is_being_destroyed(&idev->rnc); -} - -static bool isci_check_reqterm( - struct isci_host *ihost, - struct isci_remote_device *idev, - struct isci_request *ireq, - u32 localcount) -{ - unsigned long flags; - bool res; - spin_lock_irqsave(&ihost->scic_lock, flags); - res = isci_compare_suspendcount(idev, localcount) - && !test_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags); - spin_unlock_irqrestore(&ihost->scic_lock, flags); - - return res; -} - -static bool isci_check_devempty( - struct isci_host *ihost, - struct isci_remote_device *idev, - u32 localcount) -{ - unsigned long flags; - bool res; - - spin_lock_irqsave(&ihost->scic_lock, flags); - res = isci_compare_suspendcount(idev, localcount) - && idev->started_request_count == 0; - spin_unlock_irqrestore(&ihost->scic_lock, flags); - - return res; -} - -enum sci_status isci_remote_device_terminate_requests( - struct isci_host *ihost, - struct isci_remote_device *idev, - struct isci_request *ireq) -{ - enum sci_status status = SCI_SUCCESS; - unsigned long flags; - u32 rnc_suspend_count; - - spin_lock_irqsave(&ihost->scic_lock, flags); - - if (isci_get_device(idev) == NULL) { - dev_dbg(&ihost->pdev->dev, "%s: failed isci_get_device(idev=%p)\n", - __func__, idev); - spin_unlock_irqrestore(&ihost->scic_lock, flags); - status = SCI_FAILURE; - } else { - /* If already suspended, don't wait for another suspension. */ - smp_rmb(); - rnc_suspend_count - = sci_remote_node_context_is_suspended(&idev->rnc) - ? 0 : idev->rnc.suspend_count; - - dev_dbg(&ihost->pdev->dev, - "%s: idev=%p, ireq=%p; started_request_count=%d, " - "rnc_suspend_count=%d, rnc.suspend_count=%d" - "about to wait\n", - __func__, idev, ireq, idev->started_request_count, - rnc_suspend_count, idev->rnc.suspend_count); - - #define MAX_SUSPEND_MSECS 10000 - if (ireq) { - /* Terminate a specific TC. */ - set_bit(IREQ_NO_AUTO_FREE_TAG, &ireq->flags); - sci_remote_device_terminate_req(ihost, idev, 0, ireq); - spin_unlock_irqrestore(&ihost->scic_lock, flags); - if (!wait_event_timeout(ihost->eventq, - isci_check_reqterm(ihost, idev, ireq, - rnc_suspend_count), - msecs_to_jiffies(MAX_SUSPEND_MSECS))) { - - dev_warn(&ihost->pdev->dev, "%s host%d timeout single\n", - __func__, ihost->id); - dev_dbg(&ihost->pdev->dev, - "%s: ******* Timeout waiting for " - "suspend; idev=%p, current state %s; " - "started_request_count=%d, flags=%lx\n\t" - "rnc_suspend_count=%d, rnc.suspend_count=%d " - "RNC: current state %s, current " - "suspend_type %x dest state %d;\n" - "ireq=%p, ireq->flags = %lx\n", - __func__, idev, - dev_state_name(idev->sm.current_state_id), - idev->started_request_count, idev->flags, - rnc_suspend_count, idev->rnc.suspend_count, - rnc_state_name(idev->rnc.sm.current_state_id), - idev->rnc.suspend_type, - idev->rnc.destination_state, - ireq, ireq->flags); - } - spin_lock_irqsave(&ihost->scic_lock, flags); - clear_bit(IREQ_NO_AUTO_FREE_TAG, &ireq->flags); - if (!test_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags)) - isci_free_tag(ihost, ireq->io_tag); - spin_unlock_irqrestore(&ihost->scic_lock, flags); - } else { - /* Terminate all TCs. */ - sci_remote_device_terminate_requests(idev); - spin_unlock_irqrestore(&ihost->scic_lock, flags); - if (!wait_event_timeout(ihost->eventq, - isci_check_devempty(ihost, idev, - rnc_suspend_count), - msecs_to_jiffies(MAX_SUSPEND_MSECS))) { - - dev_warn(&ihost->pdev->dev, "%s host%d timeout all\n", - __func__, ihost->id); - dev_dbg(&ihost->pdev->dev, - "%s: ******* Timeout waiting for " - "suspend; idev=%p, current state %s; " - "started_request_count=%d, flags=%lx\n\t" - "rnc_suspend_count=%d, " - "RNC: current state %s, " - "rnc.suspend_count=%d, current " - "suspend_type %x dest state %d\n", - __func__, idev, - dev_state_name(idev->sm.current_state_id), - idev->started_request_count, idev->flags, - rnc_suspend_count, - rnc_state_name(idev->rnc.sm.current_state_id), - idev->rnc.suspend_count, - idev->rnc.suspend_type, - idev->rnc.destination_state); - } - } - dev_dbg(&ihost->pdev->dev, "%s: idev=%p, wait done\n", - __func__, idev); - isci_put_device(idev); - } return status; } -/** -* isci_remote_device_not_ready() - This function is called by the ihost when -* the remote device is not ready. We mark the isci device as ready (not -* "ready_for_io") and signal the waiting proccess. -* @isci_host: This parameter specifies the isci host object. -* @isci_device: This parameter specifies the remote device -* -* sci_lock is held on entrance to this function. -*/ -static void isci_remote_device_not_ready(struct isci_host *ihost, - struct isci_remote_device *idev, - u32 reason) -{ - dev_dbg(&ihost->pdev->dev, - "%s: isci_device = %p; reason = %d\n", __func__, idev, reason); - - switch (reason) { - case SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED: - set_bit(IDEV_IO_NCQERROR, &idev->flags); - - /* Suspend the remote device so the I/O can be terminated. */ - sci_remote_device_suspend(idev, SCI_SW_SUSPEND_NORMAL); - - /* Kill all outstanding requests for the device. */ - sci_remote_device_terminate_requests(idev); - - /* Fall through into the default case... */ - default: - clear_bit(IDEV_IO_READY, &idev->flags); - break; - } -} - -/* called once the remote node context is ready to be freed. - * The remote device can now report that its stop operation is complete. none - */ -static void rnc_destruct_done(void *_dev) -{ - struct isci_remote_device *idev = _dev; - - BUG_ON(idev->started_request_count != 0); - sci_change_state(&idev->sm, SCI_DEV_STOPPED); -} - -enum sci_status sci_remote_device_terminate_requests( - struct isci_remote_device *idev) -{ - return sci_remote_device_terminate_reqs_checkabort(idev, 0); -} - enum sci_status sci_remote_device_stop(struct isci_remote_device *idev, u32 timeout) { @@ -369,16 +201,13 @@ enum sci_status sci_remote_device_stop(struct isci_remote_device *idev, case SCI_SMP_DEV_IDLE: case SCI_SMP_DEV_CMD: sci_change_state(sm, SCI_DEV_STOPPING); - if (idev->started_request_count == 0) + if (idev->started_request_count == 0) { sci_remote_node_context_destruct(&idev->rnc, - rnc_destruct_done, - idev); - else { - sci_remote_device_suspend( - idev, SCI_SW_SUSPEND_LINKHANG_DETECT); - sci_remote_device_terminate_requests(idev); - } - return SCI_SUCCESS; + rnc_destruct_done, idev); + return SCI_SUCCESS; + } else + return sci_remote_device_terminate_requests(idev); + break; case SCI_DEV_STOPPING: /* All requests should have been terminated, but if there is an * attempt to stop a device already in the stopping state, then @@ -436,6 +265,22 @@ enum sci_status sci_remote_device_reset_complete(struct isci_remote_device *idev return SCI_SUCCESS; } +enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev, + u32 suspend_type) +{ + struct sci_base_state_machine *sm = &idev->sm; + enum sci_remote_device_states state = sm->current_state_id; + + if (state != SCI_STP_DEV_CMD) { + dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %s\n", + __func__, dev_state_name(state)); + return SCI_FAILURE_INVALID_STATE; + } + + return sci_remote_node_context_suspend(&idev->rnc, + suspend_type, NULL, NULL); +} + enum sci_status sci_remote_device_frame_handler(struct isci_remote_device *idev, u32 frame_index) { @@ -567,9 +412,9 @@ static void atapi_remote_device_resume_done(void *_dev) enum sci_status sci_remote_device_event_handler(struct isci_remote_device *idev, u32 event_code) { - enum sci_status status; struct sci_base_state_machine *sm = &idev->sm; enum sci_remote_device_states state = sm->current_state_id; + enum sci_status status; switch (scu_get_event_type(event_code)) { case SCU_EVENT_TYPE_RNC_OPS_MISC: @@ -582,7 +427,9 @@ enum sci_status sci_remote_device_event_handler(struct isci_remote_device *idev, status = SCI_SUCCESS; /* Suspend the associated RNC */ - sci_remote_device_suspend(idev, SCI_SW_SUSPEND_NORMAL); + sci_remote_node_context_suspend(&idev->rnc, + SCI_SOFTWARE_SUSPENSION, + NULL, NULL); dev_dbg(scirdev_to_dev(idev), "%s: device: %p event code: %x: %s\n", @@ -608,10 +455,6 @@ enum sci_status sci_remote_device_event_handler(struct isci_remote_device *idev, if (status != SCI_SUCCESS) return status; - /* Decode device-specific states that may require an RNC resume during - * normal operation. When the abort path is active, these resumes are - * managed when the abort path exits. - */ if (state == SCI_STP_DEV_ATAPI_ERROR) { /* For ATAPI error state resume the RNC right away. */ if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX || @@ -900,6 +743,10 @@ enum sci_status sci_remote_device_start_task(struct isci_host *ihost, if (status != SCI_SUCCESS) return status; + status = sci_remote_node_context_start_task(&idev->rnc, ireq); + if (status != SCI_SUCCESS) + goto out; + status = sci_request_start(ireq); if (status != SCI_SUCCESS) goto out; @@ -918,11 +765,11 @@ enum sci_status sci_remote_device_start_task(struct isci_host *ihost, * the correct action when the remote node context is suspended * and later resumed. */ - sci_remote_device_suspend(idev, - SCI_SW_SUSPEND_LINKHANG_DETECT); - - status = sci_remote_node_context_start_task(&idev->rnc, ireq, - sci_remote_device_continue_request, idev); + sci_remote_node_context_suspend(&idev->rnc, + SCI_SOFTWARE_SUSPENSION, NULL, NULL); + sci_remote_node_context_resume(&idev->rnc, + sci_remote_device_continue_request, + idev); out: sci_remote_device_start_request(idev, ireq, status); @@ -936,9 +783,7 @@ enum sci_status sci_remote_device_start_task(struct isci_host *ihost, if (status != SCI_SUCCESS) return status; - /* Resume the RNC as needed: */ - status = sci_remote_node_context_start_task(&idev->rnc, ireq, - NULL, NULL); + status = sci_remote_node_context_start_task(&idev->rnc, ireq); if (status != SCI_SUCCESS) break; @@ -1047,7 +892,7 @@ static void isci_remote_device_deconstruct(struct isci_host *ihost, struct isci_ * here should go through isci_remote_device_nuke_requests. * If we hit this condition, we will need a way to complete * io requests in process */ - BUG_ON(idev->started_request_count > 0); + BUG_ON(!list_empty(&idev->reqs_in_process)); sci_remote_device_destruct(idev); list_del_init(&idev->node); @@ -1109,21 +954,14 @@ static void sci_remote_device_ready_state_exit(struct sci_base_state_machine *sm static void sci_remote_device_resetting_state_enter(struct sci_base_state_machine *sm) { struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm); - struct isci_host *ihost = idev->owning_port->owning_controller; - dev_dbg(&ihost->pdev->dev, - "%s: isci_device = %p\n", __func__, idev); - - sci_remote_device_suspend(idev, SCI_SW_SUSPEND_LINKHANG_DETECT); + sci_remote_node_context_suspend( + &idev->rnc, SCI_SOFTWARE_SUSPENSION, NULL, NULL); } static void sci_remote_device_resetting_state_exit(struct sci_base_state_machine *sm) { struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm); - struct isci_host *ihost = idev->owning_port->owning_controller; - - dev_dbg(&ihost->pdev->dev, - "%s: isci_device = %p\n", __func__, idev); sci_remote_node_context_resume(&idev->rnc, NULL, NULL); } @@ -1275,20 +1113,33 @@ static enum sci_status sci_remote_device_da_construct(struct isci_port *iport, { enum sci_status status; struct sci_port_properties properties; + struct domain_device *dev = idev->domain_dev; sci_remote_device_construct(iport, idev); + /* + * This information is request to determine how many remote node context + * entries will be needed to store the remote node. + */ + idev->is_direct_attached = true; + sci_port_get_properties(iport, &properties); /* Get accurate port width from port's phy mask for a DA device. */ idev->device_port_width = hweight32(properties.phy_mask); status = sci_controller_allocate_remote_node_context(iport->owning_controller, - idev, - &idev->rnc.remote_node_index); + idev, + &idev->rnc.remote_node_index); if (status != SCI_SUCCESS) return status; + if (dev->dev_type == SAS_END_DEV || dev->dev_type == SATA_DEV || + (dev->tproto & SAS_PROTOCOL_STP) || dev_is_expander(dev)) + /* pass */; + else + return SCI_FAILURE_UNSUPPORTED_PROTOCOL; + idev->connection_rate = sci_port_get_max_allowed_speed(iport); return SCI_SUCCESS; @@ -1320,13 +1171,19 @@ static enum sci_status sci_remote_device_ea_construct(struct isci_port *iport, if (status != SCI_SUCCESS) return status; - /* For SAS-2 the physical link rate is actually a logical link + if (dev->dev_type == SAS_END_DEV || dev->dev_type == SATA_DEV || + (dev->tproto & SAS_PROTOCOL_STP) || dev_is_expander(dev)) + /* pass */; + else + return SCI_FAILURE_UNSUPPORTED_PROTOCOL; + + /* + * For SAS-2 the physical link rate is actually a logical link * rate that incorporates multiplexing. The SCU doesn't * incorporate multiplexing and for the purposes of the * connection the logical link rate is that same as the * physical. Furthermore, the SAS-2 and SAS-1.1 fields overlay - * one another, so this code works for both situations. - */ + * one another, so this code works for both situations. */ idev->connection_rate = min_t(u16, sci_port_get_max_allowed_speed(iport), dev->linkrate); @@ -1336,105 +1193,6 @@ static enum sci_status sci_remote_device_ea_construct(struct isci_port *iport, return SCI_SUCCESS; } -enum sci_status sci_remote_device_resume( - struct isci_remote_device *idev, - scics_sds_remote_node_context_callback cb_fn, - void *cb_p) -{ - enum sci_status status; - - status = sci_remote_node_context_resume(&idev->rnc, cb_fn, cb_p); - if (status != SCI_SUCCESS) - dev_dbg(scirdev_to_dev(idev), "%s: failed to resume: %d\n", - __func__, status); - return status; -} - -static void isci_remote_device_resume_from_abort_complete(void *cbparam) -{ - struct isci_remote_device *idev = cbparam; - struct isci_host *ihost = idev->owning_port->owning_controller; - scics_sds_remote_node_context_callback abort_resume_cb = - idev->abort_resume_cb; - - dev_dbg(scirdev_to_dev(idev), "%s: passing-along resume: %p\n", - __func__, abort_resume_cb); - - if (abort_resume_cb != NULL) { - idev->abort_resume_cb = NULL; - abort_resume_cb(idev->abort_resume_cbparam); - } - clear_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags); - wake_up(&ihost->eventq); -} - -static bool isci_remote_device_test_resume_done( - struct isci_host *ihost, - struct isci_remote_device *idev) -{ - unsigned long flags; - bool done; - - spin_lock_irqsave(&ihost->scic_lock, flags); - done = !test_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags) - || test_bit(IDEV_STOP_PENDING, &idev->flags) - || sci_remote_node_context_is_being_destroyed(&idev->rnc); - spin_unlock_irqrestore(&ihost->scic_lock, flags); - - return done; -} - -void isci_remote_device_wait_for_resume_from_abort( - struct isci_host *ihost, - struct isci_remote_device *idev) -{ - dev_dbg(&ihost->pdev->dev, "%s: starting resume wait: %p\n", - __func__, idev); - - #define MAX_RESUME_MSECS 10000 - if (!wait_event_timeout(ihost->eventq, - isci_remote_device_test_resume_done(ihost, idev), - msecs_to_jiffies(MAX_RESUME_MSECS))) { - - dev_warn(&ihost->pdev->dev, "%s: #### Timeout waiting for " - "resume: %p\n", __func__, idev); - } - clear_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags); - - dev_dbg(&ihost->pdev->dev, "%s: resume wait done: %p\n", - __func__, idev); -} - -enum sci_status isci_remote_device_resume_from_abort( - struct isci_host *ihost, - struct isci_remote_device *idev) -{ - unsigned long flags; - enum sci_status status = SCI_SUCCESS; - int destroyed; - - spin_lock_irqsave(&ihost->scic_lock, flags); - /* Preserve any current resume callbacks, for instance from other - * resumptions. - */ - idev->abort_resume_cb = idev->rnc.user_callback; - idev->abort_resume_cbparam = idev->rnc.user_cookie; - set_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags); - clear_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags); - destroyed = sci_remote_node_context_is_being_destroyed(&idev->rnc); - if (!destroyed) - status = sci_remote_device_resume( - idev, isci_remote_device_resume_from_abort_complete, - idev); - spin_unlock_irqrestore(&ihost->scic_lock, flags); - if (!destroyed && (status == SCI_SUCCESS)) - isci_remote_device_wait_for_resume_from_abort(ihost, idev); - else - clear_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags); - - return status; -} - /** * sci_remote_device_start() - This method will start the supplied remote * device. This method enables normal IO requests to flow through to the @@ -1449,7 +1207,7 @@ enum sci_status isci_remote_device_resume_from_abort( * the device when there have been no phys added to it. */ static enum sci_status sci_remote_device_start(struct isci_remote_device *idev, - u32 timeout) + u32 timeout) { struct sci_base_state_machine *sm = &idev->sm; enum sci_remote_device_states state = sm->current_state_id; @@ -1461,8 +1219,9 @@ static enum sci_status sci_remote_device_start(struct isci_remote_device *idev, return SCI_FAILURE_INVALID_STATE; } - status = sci_remote_device_resume(idev, remote_device_resume_done, - idev); + status = sci_remote_node_context_resume(&idev->rnc, + remote_device_resume_done, + idev); if (status != SCI_SUCCESS) return status; @@ -1500,6 +1259,20 @@ static enum sci_status isci_remote_device_construct(struct isci_port *iport, return status; } +void isci_remote_device_nuke_requests(struct isci_host *ihost, struct isci_remote_device *idev) +{ + DECLARE_COMPLETION_ONSTACK(aborted_task_completion); + + dev_dbg(&ihost->pdev->dev, + "%s: idev = %p\n", __func__, idev); + + /* Cleanup all requests pending for this device. */ + isci_terminate_pending_requests(ihost, idev); + + dev_dbg(&ihost->pdev->dev, + "%s: idev = %p, done\n", __func__, idev); +} + /** * This function builds the isci_remote_device when a libsas dev_found message * is received. @@ -1524,6 +1297,10 @@ isci_remote_device_alloc(struct isci_host *ihost, struct isci_port *iport) dev_warn(&ihost->pdev->dev, "%s: failed\n", __func__); return NULL; } + + if (WARN_ONCE(!list_empty(&idev->reqs_in_process), "found requests in process\n")) + return NULL; + if (WARN_ONCE(!list_empty(&idev->node), "found non-idle remote device\n")) return NULL; @@ -1565,8 +1342,14 @@ enum sci_status isci_remote_device_stop(struct isci_host *ihost, struct isci_rem spin_lock_irqsave(&ihost->scic_lock, flags); idev->domain_dev->lldd_dev = NULL; /* disable new lookups */ set_bit(IDEV_GONE, &idev->flags); + spin_unlock_irqrestore(&ihost->scic_lock, flags); + + /* Kill all outstanding requests. */ + isci_remote_device_nuke_requests(ihost, idev); set_bit(IDEV_STOP_PENDING, &idev->flags); + + spin_lock_irqsave(&ihost->scic_lock, flags); status = sci_remote_device_stop(idev, 50); spin_unlock_irqrestore(&ihost->scic_lock, flags); @@ -1576,9 +1359,6 @@ enum sci_status isci_remote_device_stop(struct isci_host *ihost, struct isci_rem else wait_for_device_stop(ihost, idev); - dev_dbg(&ihost->pdev->dev, - "%s: isci_device = %p, waiting done.\n", __func__, idev); - return status; } @@ -1654,73 +1434,3 @@ int isci_remote_device_found(struct domain_device *dev) return status == SCI_SUCCESS ? 0 : -ENODEV; } - -enum sci_status isci_remote_device_suspend_terminate( - struct isci_host *ihost, - struct isci_remote_device *idev, - struct isci_request *ireq) -{ - unsigned long flags; - enum sci_status status; - - /* Put the device into suspension. */ - spin_lock_irqsave(&ihost->scic_lock, flags); - set_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags); - sci_remote_device_suspend(idev, SCI_SW_SUSPEND_LINKHANG_DETECT); - spin_unlock_irqrestore(&ihost->scic_lock, flags); - - /* Terminate and wait for the completions. */ - status = isci_remote_device_terminate_requests(ihost, idev, ireq); - if (status != SCI_SUCCESS) - dev_dbg(&ihost->pdev->dev, - "%s: isci_remote_device_terminate_requests(%p) " - "returned %d!\n", - __func__, idev, status); - - /* NOTE: RNC resumption is left to the caller! */ - return status; -} - -int isci_remote_device_is_safe_to_abort( - struct isci_remote_device *idev) -{ - return sci_remote_node_context_is_safe_to_abort(&idev->rnc); -} - -enum sci_status sci_remote_device_abort_requests_pending_abort( - struct isci_remote_device *idev) -{ - return sci_remote_device_terminate_reqs_checkabort(idev, 1); -} - -enum sci_status isci_remote_device_reset_complete( - struct isci_host *ihost, - struct isci_remote_device *idev) -{ - unsigned long flags; - enum sci_status status; - - spin_lock_irqsave(&ihost->scic_lock, flags); - status = sci_remote_device_reset_complete(idev); - spin_unlock_irqrestore(&ihost->scic_lock, flags); - - return status; -} - -void isci_dev_set_hang_detection_timeout( - struct isci_remote_device *idev, - u32 timeout) -{ - if (dev_is_sata(idev->domain_dev)) { - if (timeout) { - if (test_and_set_bit(IDEV_RNC_LLHANG_ENABLED, - &idev->flags)) - return; /* Already enabled. */ - } else if (!test_and_clear_bit(IDEV_RNC_LLHANG_ENABLED, - &idev->flags)) - return; /* Not enabled. */ - - sci_port_set_hang_detection_timeout(idev->owning_port, - timeout); - } -} diff --git a/trunk/drivers/scsi/isci/remote_device.h b/trunk/drivers/scsi/isci/remote_device.h index 7674caae1d88..58637ee08f55 100644 --- a/trunk/drivers/scsi/isci/remote_device.h +++ b/trunk/drivers/scsi/isci/remote_device.h @@ -85,38 +85,27 @@ struct isci_remote_device { #define IDEV_GONE 3 #define IDEV_IO_READY 4 #define IDEV_IO_NCQERROR 5 - #define IDEV_RNC_LLHANG_ENABLED 6 - #define IDEV_ABORT_PATH_ACTIVE 7 - #define IDEV_ABORT_PATH_RESUME_PENDING 8 unsigned long flags; struct kref kref; struct isci_port *isci_port; struct domain_device *domain_dev; struct list_head node; + struct list_head reqs_in_process; struct sci_base_state_machine sm; u32 device_port_width; enum sas_linkrate connection_rate; + bool is_direct_attached; struct isci_port *owning_port; struct sci_remote_node_context rnc; /* XXX unify with device reference counting and delete */ u32 started_request_count; struct isci_request *working_request; u32 not_ready_reason; - scics_sds_remote_node_context_callback abort_resume_cb; - void *abort_resume_cbparam; }; #define ISCI_REMOTE_DEVICE_START_TIMEOUT 5000 /* device reference routines must be called under sci_lock */ -static inline struct isci_remote_device *isci_get_device( - struct isci_remote_device *idev) -{ - if (idev) - kref_get(&idev->kref); - return idev; -} - static inline struct isci_remote_device *isci_lookup_device(struct domain_device *dev) { struct isci_remote_device *idev = dev->lldd_dev; @@ -313,8 +302,6 @@ static inline void sci_remote_device_decrement_request_count(struct isci_remote_ idev->started_request_count--; } -void isci_dev_set_hang_detection_timeout(struct isci_remote_device *idev, u32 timeout); - enum sci_status sci_remote_device_frame_handler( struct isci_remote_device *idev, u32 frame_index); @@ -338,50 +325,12 @@ enum sci_status sci_remote_device_complete_io( struct isci_remote_device *idev, struct isci_request *ireq); -void sci_remote_device_post_request( - struct isci_remote_device *idev, - u32 request); - -enum sci_status sci_remote_device_terminate_requests( - struct isci_remote_device *idev); - -int isci_remote_device_is_safe_to_abort( - struct isci_remote_device *idev); - -enum sci_status -sci_remote_device_abort_requests_pending_abort( - struct isci_remote_device *idev); - -enum sci_status isci_remote_device_suspend( - struct isci_host *ihost, - struct isci_remote_device *idev); - -enum sci_status sci_remote_device_resume( +enum sci_status sci_remote_device_suspend( struct isci_remote_device *idev, - scics_sds_remote_node_context_callback cb_fn, - void *cb_p); - -enum sci_status isci_remote_device_resume_from_abort( - struct isci_host *ihost, - struct isci_remote_device *idev); - -enum sci_status isci_remote_device_reset( - struct isci_host *ihost, - struct isci_remote_device *idev); - -enum sci_status isci_remote_device_reset_complete( - struct isci_host *ihost, - struct isci_remote_device *idev); + u32 suspend_type); -enum sci_status isci_remote_device_suspend_terminate( - struct isci_host *ihost, +void sci_remote_device_post_request( struct isci_remote_device *idev, - struct isci_request *ireq); + u32 request); -enum sci_status isci_remote_device_terminate_requests( - struct isci_host *ihost, - struct isci_remote_device *idev, - struct isci_request *ireq); -enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev, - enum sci_remote_node_suspension_reasons reason); #endif /* !defined(_ISCI_REMOTE_DEVICE_H_) */ diff --git a/trunk/drivers/scsi/isci/remote_node_context.c b/trunk/drivers/scsi/isci/remote_node_context.c index 1910100638a2..3a9463481f38 100644 --- a/trunk/drivers/scsi/isci/remote_node_context.c +++ b/trunk/drivers/scsi/isci/remote_node_context.c @@ -52,7 +52,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include + #include "host.h" #include "isci.h" #include "remote_device.h" @@ -90,15 +90,6 @@ bool sci_remote_node_context_is_ready( return false; } -bool sci_remote_node_context_is_suspended(struct sci_remote_node_context *sci_rnc) -{ - u32 current_state = sci_rnc->sm.current_state_id; - - if (current_state == SCI_RNC_TX_RX_SUSPENDED) - return true; - return false; -} - static union scu_remote_node_context *sci_rnc_by_id(struct isci_host *ihost, u16 id) { if (id < ihost->remote_node_entries && @@ -140,7 +131,7 @@ static void sci_remote_node_context_construct_buffer(struct sci_remote_node_cont rnc->ssp.arbitration_wait_time = 0; - if (dev_is_sata(dev)) { + if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) { rnc->ssp.connection_occupancy_timeout = ihost->user_parameters.stp_max_occupancy_timeout; rnc->ssp.connection_inactivity_timeout = @@ -160,6 +151,7 @@ static void sci_remote_node_context_construct_buffer(struct sci_remote_node_cont rnc->ssp.oaf_source_zone_group = 0; rnc->ssp.oaf_more_compatibility_features = 0; } + /** * * @sci_rnc: @@ -173,30 +165,23 @@ static void sci_remote_node_context_construct_buffer(struct sci_remote_node_cont static void sci_remote_node_context_setup_to_resume( struct sci_remote_node_context *sci_rnc, scics_sds_remote_node_context_callback callback, - void *callback_parameter, - enum sci_remote_node_context_destination_state dest_param) + void *callback_parameter) { - if (sci_rnc->destination_state != RNC_DEST_FINAL) { - sci_rnc->destination_state = dest_param; - if (callback != NULL) { - sci_rnc->user_callback = callback; - sci_rnc->user_cookie = callback_parameter; - } + if (sci_rnc->destination_state != SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL) { + sci_rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY; + sci_rnc->user_callback = callback; + sci_rnc->user_cookie = callback_parameter; } } -static void sci_remote_node_context_setup_to_destroy( +static void sci_remote_node_context_setup_to_destory( struct sci_remote_node_context *sci_rnc, scics_sds_remote_node_context_callback callback, void *callback_parameter) { - struct isci_host *ihost = idev_to_ihost(rnc_to_dev(sci_rnc)); - - sci_rnc->destination_state = RNC_DEST_FINAL; + sci_rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL; sci_rnc->user_callback = callback; sci_rnc->user_cookie = callback_parameter; - - wake_up(&ihost->eventq); } /** @@ -218,19 +203,9 @@ static void sci_remote_node_context_notify_user( static void sci_remote_node_context_continue_state_transitions(struct sci_remote_node_context *rnc) { - switch (rnc->destination_state) { - case RNC_DEST_READY: - case RNC_DEST_SUSPENDED_RESUME: - rnc->destination_state = RNC_DEST_READY; - /* Fall through... */ - case RNC_DEST_FINAL: + if (rnc->destination_state == SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY) sci_remote_node_context_resume(rnc, rnc->user_callback, - rnc->user_cookie); - break; - default: - rnc->destination_state = RNC_DEST_UNSPECIFIED; - break; - } + rnc->user_cookie); } static void sci_remote_node_context_validate_context_buffer(struct sci_remote_node_context *sci_rnc) @@ -244,12 +219,13 @@ static void sci_remote_node_context_validate_context_buffer(struct sci_remote_no rnc_buffer->ssp.is_valid = true; - if (dev_is_sata(dev) && dev->parent) { + if (!idev->is_direct_attached && + (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP))) { sci_remote_device_post_request(idev, SCU_CONTEXT_COMMAND_POST_RNC_96); } else { sci_remote_device_post_request(idev, SCU_CONTEXT_COMMAND_POST_RNC_32); - if (!dev->parent) + if (idev->is_direct_attached) sci_port_setup_transports(idev->owning_port, sci_rnc->remote_node_index); } @@ -272,18 +248,13 @@ static void sci_remote_node_context_invalidate_context_buffer(struct sci_remote_ static void sci_remote_node_context_initial_state_enter(struct sci_base_state_machine *sm) { struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm); - struct isci_remote_device *idev = rnc_to_dev(rnc); - struct isci_host *ihost = idev->owning_port->owning_controller; /* Check to see if we have gotten back to the initial state because * someone requested to destroy the remote node context object. */ if (sm->previous_state_id == SCI_RNC_INVALIDATING) { - rnc->destination_state = RNC_DEST_UNSPECIFIED; + rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED; sci_remote_node_context_notify_user(rnc); - - smp_wmb(); - wake_up(&ihost->eventq); } } @@ -298,8 +269,6 @@ static void sci_remote_node_context_invalidating_state_enter(struct sci_base_sta { struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm); - /* Terminate all outstanding requests. */ - sci_remote_device_terminate_requests(rnc_to_dev(rnc)); sci_remote_node_context_invalidate_context_buffer(rnc); } @@ -318,8 +287,10 @@ static void sci_remote_node_context_resuming_state_enter(struct sci_base_state_m * resume because of a target reset we also need to update * the STPTLDARNI register with the RNi of the device */ - if (dev_is_sata(dev) && !dev->parent) - sci_port_setup_transports(idev->owning_port, rnc->remote_node_index); + if ((dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) && + idev->is_direct_attached) + sci_port_setup_transports(idev->owning_port, + rnc->remote_node_index); sci_remote_device_post_request(idev, SCU_CONTEXT_COMMAND_POST_RNC_RESUME); } @@ -327,22 +298,10 @@ static void sci_remote_node_context_resuming_state_enter(struct sci_base_state_m static void sci_remote_node_context_ready_state_enter(struct sci_base_state_machine *sm) { struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm); - enum sci_remote_node_context_destination_state dest_select; - int tell_user = 1; - - dest_select = rnc->destination_state; - rnc->destination_state = RNC_DEST_UNSPECIFIED; - if ((dest_select == RNC_DEST_SUSPENDED) || - (dest_select == RNC_DEST_SUSPENDED_RESUME)) { - sci_remote_node_context_suspend( - rnc, rnc->suspend_reason, - SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT); + rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED; - if (dest_select == RNC_DEST_SUSPENDED_RESUME) - tell_user = 0; /* Wait until ready again. */ - } - if (tell_user) + if (rnc->user_callback) sci_remote_node_context_notify_user(rnc); } @@ -356,34 +315,10 @@ static void sci_remote_node_context_tx_suspended_state_enter(struct sci_base_sta static void sci_remote_node_context_tx_rx_suspended_state_enter(struct sci_base_state_machine *sm) { struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm); - struct isci_remote_device *idev = rnc_to_dev(rnc); - struct isci_host *ihost = idev->owning_port->owning_controller; - u32 new_count = rnc->suspend_count + 1; - - if (new_count == 0) - rnc->suspend_count = 1; - else - rnc->suspend_count = new_count; - smp_wmb(); - /* Terminate outstanding requests pending abort. */ - sci_remote_device_abort_requests_pending_abort(idev); - - wake_up(&ihost->eventq); sci_remote_node_context_continue_state_transitions(rnc); } -static void sci_remote_node_context_await_suspend_state_exit( - struct sci_base_state_machine *sm) -{ - struct sci_remote_node_context *rnc - = container_of(sm, typeof(*rnc), sm); - struct isci_remote_device *idev = rnc_to_dev(rnc); - - if (dev_is_sata(idev->domain_dev)) - isci_dev_set_hang_detection_timeout(idev, 0); -} - static const struct sci_base_state sci_remote_node_context_state_table[] = { [SCI_RNC_INITIAL] = { .enter_state = sci_remote_node_context_initial_state_enter, @@ -406,9 +341,7 @@ static const struct sci_base_state sci_remote_node_context_state_table[] = { [SCI_RNC_TX_RX_SUSPENDED] = { .enter_state = sci_remote_node_context_tx_rx_suspended_state_enter, }, - [SCI_RNC_AWAIT_SUSPENSION] = { - .exit_state = sci_remote_node_context_await_suspend_state_exit, - }, + [SCI_RNC_AWAIT_SUSPENSION] = { }, }; void sci_remote_node_context_construct(struct sci_remote_node_context *rnc, @@ -417,7 +350,7 @@ void sci_remote_node_context_construct(struct sci_remote_node_context *rnc, memset(rnc, 0, sizeof(struct sci_remote_node_context)); rnc->remote_node_index = remote_node_index; - rnc->destination_state = RNC_DEST_UNSPECIFIED; + rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED; sci_init_sm(&rnc->sm, sci_remote_node_context_state_table, SCI_RNC_INITIAL); } @@ -426,7 +359,6 @@ enum sci_status sci_remote_node_context_event_handler(struct sci_remote_node_con u32 event_code) { enum scis_sds_remote_node_context_states state; - u32 next_state; state = sci_rnc->sm.current_state_id; switch (state) { @@ -441,18 +373,18 @@ enum sci_status sci_remote_node_context_event_handler(struct sci_remote_node_con break; case SCI_RNC_INVALIDATING: if (scu_get_event_code(event_code) == SCU_EVENT_POST_RNC_INVALIDATE_COMPLETE) { - if (sci_rnc->destination_state == RNC_DEST_FINAL) - next_state = SCI_RNC_INITIAL; + if (sci_rnc->destination_state == SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL) + state = SCI_RNC_INITIAL; else - next_state = SCI_RNC_POSTING; - sci_change_state(&sci_rnc->sm, next_state); + state = SCI_RNC_POSTING; + sci_change_state(&sci_rnc->sm, state); } else { switch (scu_get_event_type(event_code)) { case SCU_EVENT_TYPE_RNC_SUSPEND_TX: case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX: /* We really dont care if the hardware is going to suspend * the device since it's being invalidated anyway */ - dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), + dev_dbg(scirdev_to_dev(rnc_to_dev(sci_rnc)), "%s: SCIC Remote Node Context 0x%p was " "suspeneded by hardware while being " "invalidated.\n", __func__, sci_rnc); @@ -471,7 +403,7 @@ enum sci_status sci_remote_node_context_event_handler(struct sci_remote_node_con case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX: /* We really dont care if the hardware is going to suspend * the device since it's being resumed anyway */ - dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), + dev_dbg(scirdev_to_dev(rnc_to_dev(sci_rnc)), "%s: SCIC Remote Node Context 0x%p was " "suspeneded by hardware while being resumed.\n", __func__, sci_rnc); @@ -485,11 +417,11 @@ enum sci_status sci_remote_node_context_event_handler(struct sci_remote_node_con switch (scu_get_event_type(event_code)) { case SCU_EVENT_TL_RNC_SUSPEND_TX: sci_change_state(&sci_rnc->sm, SCI_RNC_TX_SUSPENDED); - sci_rnc->suspend_type = scu_get_event_type(event_code); + sci_rnc->suspension_code = scu_get_event_specifier(event_code); break; case SCU_EVENT_TL_RNC_SUSPEND_TX_RX: sci_change_state(&sci_rnc->sm, SCI_RNC_TX_RX_SUSPENDED); - sci_rnc->suspend_type = scu_get_event_type(event_code); + sci_rnc->suspension_code = scu_get_event_specifier(event_code); break; default: goto out; @@ -498,29 +430,27 @@ enum sci_status sci_remote_node_context_event_handler(struct sci_remote_node_con case SCI_RNC_AWAIT_SUSPENSION: switch (scu_get_event_type(event_code)) { case SCU_EVENT_TL_RNC_SUSPEND_TX: - next_state = SCI_RNC_TX_SUSPENDED; + sci_change_state(&sci_rnc->sm, SCI_RNC_TX_SUSPENDED); + sci_rnc->suspension_code = scu_get_event_specifier(event_code); break; case SCU_EVENT_TL_RNC_SUSPEND_TX_RX: - next_state = SCI_RNC_TX_RX_SUSPENDED; + sci_change_state(&sci_rnc->sm, SCI_RNC_TX_RX_SUSPENDED); + sci_rnc->suspension_code = scu_get_event_specifier(event_code); break; default: goto out; } - if (sci_rnc->suspend_type == scu_get_event_type(event_code)) - sci_change_state(&sci_rnc->sm, next_state); break; default: dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), - "%s: invalid state: %s\n", __func__, - rnc_state_name(state)); + "%s: invalid state %d\n", __func__, state); return SCI_FAILURE_INVALID_STATE; } return SCI_SUCCESS; out: dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), - "%s: code: %#x state: %s\n", __func__, event_code, - rnc_state_name(state)); + "%s: code: %#x state: %d\n", __func__, event_code, state); return SCI_FAILURE; } @@ -534,23 +464,20 @@ enum sci_status sci_remote_node_context_destruct(struct sci_remote_node_context state = sci_rnc->sm.current_state_id; switch (state) { case SCI_RNC_INVALIDATING: - sci_remote_node_context_setup_to_destroy(sci_rnc, cb_fn, cb_p); + sci_remote_node_context_setup_to_destory(sci_rnc, cb_fn, cb_p); return SCI_SUCCESS; case SCI_RNC_POSTING: case SCI_RNC_RESUMING: case SCI_RNC_READY: case SCI_RNC_TX_SUSPENDED: case SCI_RNC_TX_RX_SUSPENDED: - sci_remote_node_context_setup_to_destroy(sci_rnc, cb_fn, cb_p); - sci_change_state(&sci_rnc->sm, SCI_RNC_INVALIDATING); - return SCI_SUCCESS; case SCI_RNC_AWAIT_SUSPENSION: - sci_remote_node_context_setup_to_destroy(sci_rnc, cb_fn, cb_p); + sci_remote_node_context_setup_to_destory(sci_rnc, cb_fn, cb_p); + sci_change_state(&sci_rnc->sm, SCI_RNC_INVALIDATING); return SCI_SUCCESS; case SCI_RNC_INITIAL: dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), - "%s: invalid state: %s\n", __func__, - rnc_state_name(state)); + "%s: invalid state %d\n", __func__, state); /* We have decided that the destruct request on the remote node context * can not fail since it is either in the initial/destroyed state or is * can be destroyed. @@ -558,101 +485,35 @@ enum sci_status sci_remote_node_context_destruct(struct sci_remote_node_context return SCI_SUCCESS; default: dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), - "%s: invalid state %s\n", __func__, - rnc_state_name(state)); + "%s: invalid state %d\n", __func__, state); return SCI_FAILURE_INVALID_STATE; } } -enum sci_status sci_remote_node_context_suspend( - struct sci_remote_node_context *sci_rnc, - enum sci_remote_node_suspension_reasons suspend_reason, - u32 suspend_type) +enum sci_status sci_remote_node_context_suspend(struct sci_remote_node_context *sci_rnc, + u32 suspend_type, + scics_sds_remote_node_context_callback cb_fn, + void *cb_p) { - enum scis_sds_remote_node_context_states state - = sci_rnc->sm.current_state_id; - struct isci_remote_device *idev = rnc_to_dev(sci_rnc); - enum sci_status status = SCI_FAILURE_INVALID_STATE; - enum sci_remote_node_context_destination_state dest_param = - RNC_DEST_UNSPECIFIED; - - dev_dbg(scirdev_to_dev(idev), - "%s: current state %s, current suspend_type %x dest state %d," - " arg suspend_reason %d, arg suspend_type %x", - __func__, rnc_state_name(state), sci_rnc->suspend_type, - sci_rnc->destination_state, suspend_reason, - suspend_type); - - /* Disable automatic state continuations if explicitly suspending. */ - if ((suspend_reason == SCI_HW_SUSPEND) || - (sci_rnc->destination_state == RNC_DEST_FINAL)) - dest_param = sci_rnc->destination_state; - - switch (state) { - case SCI_RNC_READY: - break; - case SCI_RNC_INVALIDATING: - if (sci_rnc->destination_state == RNC_DEST_FINAL) { - dev_warn(scirdev_to_dev(idev), - "%s: already destroying %p\n", - __func__, sci_rnc); - return SCI_FAILURE_INVALID_STATE; - } - /* Fall through and handle like SCI_RNC_POSTING */ - case SCI_RNC_RESUMING: - /* Fall through and handle like SCI_RNC_POSTING */ - case SCI_RNC_POSTING: - /* Set the destination state to AWAIT - this signals the - * entry into the SCI_RNC_READY state that a suspension - * needs to be done immediately. - */ - if (sci_rnc->destination_state != RNC_DEST_FINAL) - sci_rnc->destination_state = RNC_DEST_SUSPENDED; - sci_rnc->suspend_type = suspend_type; - sci_rnc->suspend_reason = suspend_reason; - return SCI_SUCCESS; + enum scis_sds_remote_node_context_states state; - case SCI_RNC_TX_SUSPENDED: - if (suspend_type == SCU_EVENT_TL_RNC_SUSPEND_TX) - status = SCI_SUCCESS; - break; - case SCI_RNC_TX_RX_SUSPENDED: - if (suspend_type == SCU_EVENT_TL_RNC_SUSPEND_TX_RX) - status = SCI_SUCCESS; - break; - case SCI_RNC_AWAIT_SUSPENSION: - if ((sci_rnc->suspend_type == SCU_EVENT_TL_RNC_SUSPEND_TX_RX) - || (suspend_type == sci_rnc->suspend_type)) - return SCI_SUCCESS; - break; - default: + state = sci_rnc->sm.current_state_id; + if (state != SCI_RNC_READY) { dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), - "%s: invalid state %s\n", __func__, - rnc_state_name(state)); + "%s: invalid state %d\n", __func__, state); return SCI_FAILURE_INVALID_STATE; } - sci_rnc->destination_state = dest_param; - sci_rnc->suspend_type = suspend_type; - sci_rnc->suspend_reason = suspend_reason; - - if (status == SCI_SUCCESS) { /* Already in the destination state? */ - struct isci_host *ihost = idev->owning_port->owning_controller; - - wake_up_all(&ihost->eventq); /* Let observers look. */ - return SCI_SUCCESS; - } - if ((suspend_reason == SCI_SW_SUSPEND_NORMAL) || - (suspend_reason == SCI_SW_SUSPEND_LINKHANG_DETECT)) { - if (suspend_reason == SCI_SW_SUSPEND_LINKHANG_DETECT) - isci_dev_set_hang_detection_timeout(idev, 0x00000001); + sci_rnc->user_callback = cb_fn; + sci_rnc->user_cookie = cb_p; + sci_rnc->suspension_code = suspend_type; - sci_remote_device_post_request( - idev, SCI_SOFTWARE_SUSPEND_CMD); + if (suspend_type == SCI_SOFTWARE_SUSPENSION) { + sci_remote_device_post_request(rnc_to_dev(sci_rnc), + SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX); } - if (state != SCI_RNC_AWAIT_SUSPENSION) - sci_change_state(&sci_rnc->sm, SCI_RNC_AWAIT_SUSPENSION); + sci_change_state(&sci_rnc->sm, SCI_RNC_AWAIT_SUSPENSION); return SCI_SUCCESS; } @@ -661,86 +522,56 @@ enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *s void *cb_p) { enum scis_sds_remote_node_context_states state; - struct isci_remote_device *idev = rnc_to_dev(sci_rnc); state = sci_rnc->sm.current_state_id; - dev_dbg(scirdev_to_dev(idev), - "%s: state %s, cb_fn = %p, cb_p = %p; dest_state = %d; " - "dev resume path %s\n", - __func__, rnc_state_name(state), cb_fn, cb_p, - sci_rnc->destination_state, - test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags) - ? "" : ""); - switch (state) { case SCI_RNC_INITIAL: if (sci_rnc->remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) return SCI_FAILURE_INVALID_STATE; - sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p, - RNC_DEST_READY); - if (!test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) { - sci_remote_node_context_construct_buffer(sci_rnc); - sci_change_state(&sci_rnc->sm, SCI_RNC_POSTING); - } + sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p); + sci_remote_node_context_construct_buffer(sci_rnc); + sci_change_state(&sci_rnc->sm, SCI_RNC_POSTING); return SCI_SUCCESS; - case SCI_RNC_POSTING: case SCI_RNC_INVALIDATING: case SCI_RNC_RESUMING: - /* We are still waiting to post when a resume was - * requested. - */ - switch (sci_rnc->destination_state) { - case RNC_DEST_SUSPENDED: - case RNC_DEST_SUSPENDED_RESUME: - /* Previously waiting to suspend after posting. - * Now continue onto resumption. - */ - sci_remote_node_context_setup_to_resume( - sci_rnc, cb_fn, cb_p, - RNC_DEST_SUSPENDED_RESUME); - break; - default: - sci_remote_node_context_setup_to_resume( - sci_rnc, cb_fn, cb_p, - RNC_DEST_READY); - break; - } - return SCI_SUCCESS; + if (sci_rnc->destination_state != SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY) + return SCI_FAILURE_INVALID_STATE; - case SCI_RNC_TX_SUSPENDED: - case SCI_RNC_TX_RX_SUSPENDED: - { - struct domain_device *dev = idev->domain_dev; - /* If this is an expander attached SATA device we must - * invalidate and repost the RNC since this is the only - * way to clear the TCi to NCQ tag mapping table for - * the RNi. All other device types we can just resume. - */ - sci_remote_node_context_setup_to_resume( - sci_rnc, cb_fn, cb_p, RNC_DEST_READY); - - if (!test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) { - if ((dev_is_sata(dev) && dev->parent) || - (sci_rnc->destination_state == RNC_DEST_FINAL)) - sci_change_state(&sci_rnc->sm, - SCI_RNC_INVALIDATING); - else - sci_change_state(&sci_rnc->sm, - SCI_RNC_RESUMING); + sci_rnc->user_callback = cb_fn; + sci_rnc->user_cookie = cb_p; + return SCI_SUCCESS; + case SCI_RNC_TX_SUSPENDED: { + struct isci_remote_device *idev = rnc_to_dev(sci_rnc); + struct domain_device *dev = idev->domain_dev; + + sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p); + + /* TODO: consider adding a resume action of NONE, INVALIDATE, WRITE_TLCR */ + if (dev->dev_type == SAS_END_DEV || dev_is_expander(dev)) + sci_change_state(&sci_rnc->sm, SCI_RNC_RESUMING); + else if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) { + if (idev->is_direct_attached) { + /* @todo Fix this since I am being silly in writing to the STPTLDARNI register. */ + sci_change_state(&sci_rnc->sm, SCI_RNC_RESUMING); + } else { + sci_change_state(&sci_rnc->sm, SCI_RNC_INVALIDATING); } - } + } else + return SCI_FAILURE; return SCI_SUCCESS; - + } + case SCI_RNC_TX_RX_SUSPENDED: + sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p); + sci_change_state(&sci_rnc->sm, SCI_RNC_RESUMING); + return SCI_FAILURE_INVALID_STATE; case SCI_RNC_AWAIT_SUSPENSION: - sci_remote_node_context_setup_to_resume( - sci_rnc, cb_fn, cb_p, RNC_DEST_SUSPENDED_RESUME); + sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p); return SCI_SUCCESS; default: dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), - "%s: invalid state %s\n", __func__, - rnc_state_name(state)); + "%s: invalid state %d\n", __func__, state); return SCI_FAILURE_INVALID_STATE; } } @@ -759,51 +590,35 @@ enum sci_status sci_remote_node_context_start_io(struct sci_remote_node_context case SCI_RNC_TX_RX_SUSPENDED: case SCI_RNC_AWAIT_SUSPENSION: dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), - "%s: invalid state %s\n", __func__, - rnc_state_name(state)); + "%s: invalid state %d\n", __func__, state); return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED; default: - dev_dbg(scirdev_to_dev(rnc_to_dev(sci_rnc)), - "%s: invalid state %s\n", __func__, - rnc_state_name(state)); - return SCI_FAILURE_INVALID_STATE; + break; } + dev_dbg(scirdev_to_dev(rnc_to_dev(sci_rnc)), + "%s: requested to start IO while still resuming, %d\n", + __func__, state); + return SCI_FAILURE_INVALID_STATE; } -enum sci_status sci_remote_node_context_start_task( - struct sci_remote_node_context *sci_rnc, - struct isci_request *ireq, - scics_sds_remote_node_context_callback cb_fn, - void *cb_p) -{ - enum sci_status status = sci_remote_node_context_resume(sci_rnc, - cb_fn, cb_p); - if (status != SCI_SUCCESS) - dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), - "%s: resume failed: %d\n", __func__, status); - return status; -} - -int sci_remote_node_context_is_safe_to_abort( - struct sci_remote_node_context *sci_rnc) +enum sci_status sci_remote_node_context_start_task(struct sci_remote_node_context *sci_rnc, + struct isci_request *ireq) { enum scis_sds_remote_node_context_states state; state = sci_rnc->sm.current_state_id; switch (state) { - case SCI_RNC_INVALIDATING: - case SCI_RNC_TX_RX_SUSPENDED: - return 1; - case SCI_RNC_POSTING: case SCI_RNC_RESUMING: case SCI_RNC_READY: - case SCI_RNC_TX_SUSPENDED: case SCI_RNC_AWAIT_SUSPENSION: - case SCI_RNC_INITIAL: - return 0; + return SCI_SUCCESS; + case SCI_RNC_TX_SUSPENDED: + case SCI_RNC_TX_RX_SUSPENDED: + sci_remote_node_context_resume(sci_rnc, NULL, NULL); + return SCI_SUCCESS; default: dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), "%s: invalid state %d\n", __func__, state); - return 0; + return SCI_FAILURE_INVALID_STATE; } } diff --git a/trunk/drivers/scsi/isci/remote_node_context.h b/trunk/drivers/scsi/isci/remote_node_context.h index a703b9ce0c2c..a241e0f4c865 100644 --- a/trunk/drivers/scsi/isci/remote_node_context.h +++ b/trunk/drivers/scsi/isci/remote_node_context.h @@ -75,13 +75,8 @@ */ #define SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX 0x0FFF -enum sci_remote_node_suspension_reasons { - SCI_HW_SUSPEND, - SCI_SW_SUSPEND_NORMAL, - SCI_SW_SUSPEND_LINKHANG_DETECT -}; -#define SCI_SOFTWARE_SUSPEND_CMD SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX_RX -#define SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT SCU_EVENT_TL_RNC_SUSPEND_TX_RX +#define SCU_HARDWARE_SUSPENSION (0) +#define SCI_SOFTWARE_SUSPENSION (1) struct isci_request; struct isci_remote_device; @@ -142,13 +137,9 @@ const char *rnc_state_name(enum scis_sds_remote_node_context_states state); * node context. */ enum sci_remote_node_context_destination_state { - RNC_DEST_UNSPECIFIED, - RNC_DEST_READY, - RNC_DEST_FINAL, - RNC_DEST_SUSPENDED, /* Set when suspend during post/invalidate */ - RNC_DEST_SUSPENDED_RESUME /* Set when a resume was done during posting - * or invalidating and already suspending. - */ + SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED, + SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY, + SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL }; /** @@ -165,12 +156,10 @@ struct sci_remote_node_context { u16 remote_node_index; /** - * This field is the recored suspension type of the remote node + * This field is the recored suspension code or the reason for the remote node * context suspension. */ - u32 suspend_type; - enum sci_remote_node_suspension_reasons suspend_reason; - u32 suspend_count; + u32 suspension_code; /** * This field is true if the remote node context is resuming from its current @@ -204,8 +193,6 @@ void sci_remote_node_context_construct(struct sci_remote_node_context *rnc, bool sci_remote_node_context_is_ready( struct sci_remote_node_context *sci_rnc); -bool sci_remote_node_context_is_suspended(struct sci_remote_node_context *sci_rnc); - enum sci_status sci_remote_node_context_event_handler(struct sci_remote_node_context *sci_rnc, u32 event_code); enum sci_status sci_remote_node_context_destruct(struct sci_remote_node_context *sci_rnc, @@ -213,24 +200,14 @@ enum sci_status sci_remote_node_context_destruct(struct sci_remote_node_context void *callback_parameter); enum sci_status sci_remote_node_context_suspend(struct sci_remote_node_context *sci_rnc, u32 suspend_type, - u32 suspension_code); + scics_sds_remote_node_context_callback cb_fn, + void *cb_p); enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *sci_rnc, scics_sds_remote_node_context_callback cb_fn, void *cb_p); enum sci_status sci_remote_node_context_start_task(struct sci_remote_node_context *sci_rnc, - struct isci_request *ireq, - scics_sds_remote_node_context_callback cb_fn, - void *cb_p); + struct isci_request *ireq); enum sci_status sci_remote_node_context_start_io(struct sci_remote_node_context *sci_rnc, struct isci_request *ireq); -int sci_remote_node_context_is_safe_to_abort( - struct sci_remote_node_context *sci_rnc); -static inline bool sci_remote_node_context_is_being_destroyed( - struct sci_remote_node_context *sci_rnc) -{ - return (sci_rnc->destination_state == RNC_DEST_FINAL) - || ((sci_rnc->sm.current_state_id == SCI_RNC_INITIAL) - && (sci_rnc->destination_state == RNC_DEST_UNSPECIFIED)); -} #endif /* _SCIC_SDS_REMOTE_NODE_CONTEXT_H_ */ diff --git a/trunk/drivers/scsi/isci/request.c b/trunk/drivers/scsi/isci/request.c index 7a0431c73493..2def1e3960f6 100644 --- a/trunk/drivers/scsi/isci/request.c +++ b/trunk/drivers/scsi/isci/request.c @@ -92,11 +92,11 @@ static dma_addr_t to_sgl_element_pair_dma(struct isci_host *ihost, if (idx == 0) { offset = (void *) &ireq->tc->sgl_pair_ab - (void *) &ihost->task_context_table[0]; - return ihost->tc_dma + offset; + return ihost->task_context_dma + offset; } else if (idx == 1) { offset = (void *) &ireq->tc->sgl_pair_cd - (void *) &ihost->task_context_table[0]; - return ihost->tc_dma + offset; + return ihost->task_context_dma + offset; } return sci_io_request_get_dma_addr(ireq, &ireq->sg_table[idx - 2]); @@ -730,7 +730,7 @@ static enum sci_status sci_io_request_construct_basic_ssp(struct isci_request *i { struct sas_task *task = isci_request_access_task(ireq); - ireq->protocol = SAS_PROTOCOL_SSP; + ireq->protocol = SCIC_SSP_PROTOCOL; scu_ssp_io_request_construct_task_context(ireq, task->data_dir, @@ -763,7 +763,7 @@ static enum sci_status sci_io_request_construct_basic_sata(struct isci_request * bool copy = false; struct sas_task *task = isci_request_access_task(ireq); - ireq->protocol = SAS_PROTOCOL_STP; + ireq->protocol = SCIC_STP_PROTOCOL; copy = (task->data_dir == DMA_NONE) ? false : true; @@ -863,8 +863,6 @@ sci_io_request_terminate(struct isci_request *ireq) switch (state) { case SCI_REQ_CONSTRUCTED: - /* Set to make sure no HW terminate posting is done: */ - set_bit(IREQ_TC_ABORT_POSTED, &ireq->flags); ireq->scu_status = SCU_TASK_DONE_TASK_ABORT; ireq->sci_status = SCI_FAILURE_IO_TERMINATED; sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); @@ -885,7 +883,8 @@ sci_io_request_terminate(struct isci_request *ireq) case SCI_REQ_ATAPI_WAIT_PIO_SETUP: case SCI_REQ_ATAPI_WAIT_D2H: case SCI_REQ_ATAPI_WAIT_TC_COMP: - /* Fall through and change state to ABORTING... */ + sci_change_state(&ireq->sm, SCI_REQ_ABORTING); + return SCI_SUCCESS; case SCI_REQ_TASK_WAIT_TC_RESP: /* The task frame was already confirmed to have been * sent by the SCU HW. Since the state machine is @@ -894,21 +893,20 @@ sci_io_request_terminate(struct isci_request *ireq) * and don't wait for the task response. */ sci_change_state(&ireq->sm, SCI_REQ_ABORTING); - /* Fall through and handle like ABORTING... */ + sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); + return SCI_SUCCESS; case SCI_REQ_ABORTING: - if (!isci_remote_device_is_safe_to_abort(ireq->target_device)) - set_bit(IREQ_PENDING_ABORT, &ireq->flags); - else - clear_bit(IREQ_PENDING_ABORT, &ireq->flags); - /* If the request is only waiting on the remote device - * suspension, return SUCCESS so the caller will wait too. + /* If a request has a termination requested twice, return + * a failure indication, since HW confirmation of the first + * abort is still outstanding. */ - return SCI_SUCCESS; case SCI_REQ_COMPLETED: default: dev_warn(&ireq->owning_controller->pdev->dev, "%s: SCIC IO Request requested to abort while in wrong " - "state %d\n", __func__, ireq->sm.current_state_id); + "state %d\n", + __func__, + ireq->sm.current_state_id); break; } @@ -1072,7 +1070,7 @@ request_started_state_tc_event(struct isci_request *ireq, case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_SDBFIS): case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_REG_ERR): case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SDB_ERR): - if (ireq->protocol == SAS_PROTOCOL_STP) { + if (ireq->protocol == SCIC_STP_PROTOCOL) { ireq->scu_status = SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT; ireq->sci_status = SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED; @@ -2119,7 +2117,7 @@ static enum sci_status stp_request_udma_await_tc_event(struct isci_request *ireq */ if (ireq->stp.rsp.fis_type == FIS_REGD2H) { sci_remote_device_suspend(ireq->target_device, - SCI_SW_SUSPEND_NORMAL); + SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code))); ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE; ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID; @@ -2140,6 +2138,13 @@ static enum sci_status stp_request_udma_await_tc_event(struct isci_request *ireq /* TODO We can retry the command for SCU_TASK_DONE_CMD_LL_R_ERR * - this comes only for B0 */ + case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_INV_FIS_LEN): + case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_MAX_PLD_ERR): + case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_R_ERR): + case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CMD_LL_R_ERR): + sci_remote_device_suspend(ireq->target_device, + SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code))); + /* Fall through to the default case */ default: /* All other completion status cause the IO to be complete. */ ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code); @@ -2257,151 +2262,15 @@ static enum sci_status atapi_data_tc_completion_handler(struct isci_request *ire return status; } -static int sci_request_smp_completion_status_is_tx_suspend( - unsigned int completion_status) -{ - switch (completion_status) { - case SCU_TASK_OPEN_REJECT_WRONG_DESTINATION: - case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_1: - case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_2: - case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_3: - case SCU_TASK_OPEN_REJECT_BAD_DESTINATION: - case SCU_TASK_OPEN_REJECT_ZONE_VIOLATION: - return 1; - } - return 0; -} - -static int sci_request_smp_completion_status_is_tx_rx_suspend( - unsigned int completion_status) -{ - return 0; /* There are no Tx/Rx SMP suspend conditions. */ -} - -static int sci_request_ssp_completion_status_is_tx_suspend( - unsigned int completion_status) -{ - switch (completion_status) { - case SCU_TASK_DONE_TX_RAW_CMD_ERR: - case SCU_TASK_DONE_LF_ERR: - case SCU_TASK_OPEN_REJECT_WRONG_DESTINATION: - case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_1: - case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_2: - case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_3: - case SCU_TASK_OPEN_REJECT_BAD_DESTINATION: - case SCU_TASK_OPEN_REJECT_ZONE_VIOLATION: - case SCU_TASK_OPEN_REJECT_STP_RESOURCES_BUSY: - case SCU_TASK_OPEN_REJECT_PROTOCOL_NOT_SUPPORTED: - case SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED: - return 1; - } - return 0; -} - -static int sci_request_ssp_completion_status_is_tx_rx_suspend( - unsigned int completion_status) -{ - return 0; /* There are no Tx/Rx SSP suspend conditions. */ -} - -static int sci_request_stpsata_completion_status_is_tx_suspend( - unsigned int completion_status) -{ - switch (completion_status) { - case SCU_TASK_DONE_TX_RAW_CMD_ERR: - case SCU_TASK_DONE_LL_R_ERR: - case SCU_TASK_DONE_LL_PERR: - case SCU_TASK_DONE_REG_ERR: - case SCU_TASK_DONE_SDB_ERR: - case SCU_TASK_OPEN_REJECT_WRONG_DESTINATION: - case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_1: - case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_2: - case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_3: - case SCU_TASK_OPEN_REJECT_BAD_DESTINATION: - case SCU_TASK_OPEN_REJECT_ZONE_VIOLATION: - case SCU_TASK_OPEN_REJECT_STP_RESOURCES_BUSY: - case SCU_TASK_OPEN_REJECT_PROTOCOL_NOT_SUPPORTED: - case SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED: - return 1; - } - return 0; -} - - -static int sci_request_stpsata_completion_status_is_tx_rx_suspend( - unsigned int completion_status) -{ - switch (completion_status) { - case SCU_TASK_DONE_LF_ERR: - case SCU_TASK_DONE_LL_SY_TERM: - case SCU_TASK_DONE_LL_LF_TERM: - case SCU_TASK_DONE_BREAK_RCVD: - case SCU_TASK_DONE_INV_FIS_LEN: - case SCU_TASK_DONE_UNEXP_FIS: - case SCU_TASK_DONE_UNEXP_SDBFIS: - case SCU_TASK_DONE_MAX_PLD_ERR: - return 1; - } - return 0; -} - -static void sci_request_handle_suspending_completions( - struct isci_request *ireq, - u32 completion_code) -{ - int is_tx = 0; - int is_tx_rx = 0; - - switch (ireq->protocol) { - case SAS_PROTOCOL_SMP: - is_tx = sci_request_smp_completion_status_is_tx_suspend( - completion_code); - is_tx_rx = sci_request_smp_completion_status_is_tx_rx_suspend( - completion_code); - break; - case SAS_PROTOCOL_SSP: - is_tx = sci_request_ssp_completion_status_is_tx_suspend( - completion_code); - is_tx_rx = sci_request_ssp_completion_status_is_tx_rx_suspend( - completion_code); - break; - case SAS_PROTOCOL_STP: - is_tx = sci_request_stpsata_completion_status_is_tx_suspend( - completion_code); - is_tx_rx = - sci_request_stpsata_completion_status_is_tx_rx_suspend( - completion_code); - break; - default: - dev_warn(&ireq->isci_host->pdev->dev, - "%s: request %p has no valid protocol\n", - __func__, ireq); - break; - } - if (is_tx || is_tx_rx) { - BUG_ON(is_tx && is_tx_rx); - - sci_remote_node_context_suspend( - &ireq->target_device->rnc, - SCI_HW_SUSPEND, - (is_tx_rx) ? SCU_EVENT_TL_RNC_SUSPEND_TX_RX - : SCU_EVENT_TL_RNC_SUSPEND_TX); - } -} - enum sci_status sci_io_request_tc_completion(struct isci_request *ireq, - u32 completion_code) + u32 completion_code) { enum sci_base_request_states state; struct isci_host *ihost = ireq->owning_controller; state = ireq->sm.current_state_id; - /* Decode those completions that signal upcoming suspension events. */ - sci_request_handle_suspending_completions( - ireq, SCU_GET_COMPLETION_TL_STATUS(completion_code)); - switch (state) { case SCI_REQ_STARTED: return request_started_state_tc_event(ireq, completion_code); @@ -2493,6 +2362,9 @@ static void isci_request_process_response_iu( * @request: This parameter is the completed isci_request object. * @response_ptr: This parameter specifies the service response for the I/O. * @status_ptr: This parameter specifies the exec status for the I/O. + * @complete_to_host_ptr: This parameter specifies the action to be taken by + * the LLDD with respect to completing this request or forcing an abort + * condition on the I/O. * @open_rej_reason: This parameter specifies the encoded reason for the * abandon-class reject. * @@ -2503,12 +2375,14 @@ static void isci_request_set_open_reject_status( struct sas_task *task, enum service_response *response_ptr, enum exec_status *status_ptr, + enum isci_completion_selection *complete_to_host_ptr, enum sas_open_rej_reason open_rej_reason) { /* Task in the target is done. */ set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); *response_ptr = SAS_TASK_UNDELIVERED; *status_ptr = SAS_OPEN_REJECT; + *complete_to_host_ptr = isci_perform_normal_io_completion; task->task_status.open_rej_reason = open_rej_reason; } @@ -2518,6 +2392,9 @@ static void isci_request_set_open_reject_status( * @request: This parameter is the completed isci_request object. * @response_ptr: This parameter specifies the service response for the I/O. * @status_ptr: This parameter specifies the exec status for the I/O. + * @complete_to_host_ptr: This parameter specifies the action to be taken by + * the LLDD with respect to completing this request or forcing an abort + * condition on the I/O. * * none. */ @@ -2526,7 +2403,8 @@ static void isci_request_handle_controller_specific_errors( struct isci_request *request, struct sas_task *task, enum service_response *response_ptr, - enum exec_status *status_ptr) + enum exec_status *status_ptr, + enum isci_completion_selection *complete_to_host_ptr) { unsigned int cstatus; @@ -2567,6 +2445,9 @@ static void isci_request_handle_controller_specific_errors( *status_ptr = SAS_ABORTED_TASK; set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); + + *complete_to_host_ptr = + isci_perform_normal_io_completion; } else { /* Task in the target is not done. */ *response_ptr = SAS_TASK_UNDELIVERED; @@ -2577,6 +2458,9 @@ static void isci_request_handle_controller_specific_errors( *status_ptr = SAM_STAT_TASK_ABORTED; clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); + + *complete_to_host_ptr = + isci_perform_error_io_completion; } break; @@ -2605,6 +2489,8 @@ static void isci_request_handle_controller_specific_errors( *status_ptr = SAS_ABORTED_TASK; set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); + + *complete_to_host_ptr = isci_perform_normal_io_completion; break; @@ -2615,7 +2501,7 @@ static void isci_request_handle_controller_specific_errors( isci_request_set_open_reject_status( request, task, response_ptr, status_ptr, - SAS_OREJ_WRONG_DEST); + complete_to_host_ptr, SAS_OREJ_WRONG_DEST); break; case SCU_TASK_OPEN_REJECT_ZONE_VIOLATION: @@ -2625,56 +2511,56 @@ static void isci_request_handle_controller_specific_errors( */ isci_request_set_open_reject_status( request, task, response_ptr, status_ptr, - SAS_OREJ_RESV_AB0); + complete_to_host_ptr, SAS_OREJ_RESV_AB0); break; case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_1: isci_request_set_open_reject_status( request, task, response_ptr, status_ptr, - SAS_OREJ_RESV_AB1); + complete_to_host_ptr, SAS_OREJ_RESV_AB1); break; case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_2: isci_request_set_open_reject_status( request, task, response_ptr, status_ptr, - SAS_OREJ_RESV_AB2); + complete_to_host_ptr, SAS_OREJ_RESV_AB2); break; case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_3: isci_request_set_open_reject_status( request, task, response_ptr, status_ptr, - SAS_OREJ_RESV_AB3); + complete_to_host_ptr, SAS_OREJ_RESV_AB3); break; case SCU_TASK_OPEN_REJECT_BAD_DESTINATION: isci_request_set_open_reject_status( request, task, response_ptr, status_ptr, - SAS_OREJ_BAD_DEST); + complete_to_host_ptr, SAS_OREJ_BAD_DEST); break; case SCU_TASK_OPEN_REJECT_STP_RESOURCES_BUSY: isci_request_set_open_reject_status( request, task, response_ptr, status_ptr, - SAS_OREJ_STP_NORES); + complete_to_host_ptr, SAS_OREJ_STP_NORES); break; case SCU_TASK_OPEN_REJECT_PROTOCOL_NOT_SUPPORTED: isci_request_set_open_reject_status( request, task, response_ptr, status_ptr, - SAS_OREJ_EPROTO); + complete_to_host_ptr, SAS_OREJ_EPROTO); break; case SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED: isci_request_set_open_reject_status( request, task, response_ptr, status_ptr, - SAS_OREJ_CONN_RATE); + complete_to_host_ptr, SAS_OREJ_CONN_RATE); break; case SCU_TASK_DONE_LL_R_ERR: @@ -2706,12 +2592,95 @@ static void isci_request_handle_controller_specific_errors( *response_ptr = SAS_TASK_UNDELIVERED; *status_ptr = SAM_STAT_TASK_ABORTED; - if (task->task_proto == SAS_PROTOCOL_SMP) + if (task->task_proto == SAS_PROTOCOL_SMP) { set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); - else + + *complete_to_host_ptr = isci_perform_normal_io_completion; + } else { clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); + + *complete_to_host_ptr = isci_perform_error_io_completion; + } + break; + } +} + +/** + * isci_task_save_for_upper_layer_completion() - This function saves the + * request for later completion to the upper layer driver. + * @host: This parameter is a pointer to the host on which the the request + * should be queued (either as an error or success). + * @request: This parameter is the completed request. + * @response: This parameter is the response code for the completed task. + * @status: This parameter is the status code for the completed task. + * + * none. + */ +static void isci_task_save_for_upper_layer_completion( + struct isci_host *host, + struct isci_request *request, + enum service_response response, + enum exec_status status, + enum isci_completion_selection task_notification_selection) +{ + struct sas_task *task = isci_request_access_task(request); + + task_notification_selection + = isci_task_set_completion_status(task, response, status, + task_notification_selection); + + /* Tasks aborted specifically by a call to the lldd_abort_task + * function should not be completed to the host in the regular path. + */ + switch (task_notification_selection) { + + case isci_perform_normal_io_completion: + /* Normal notification (task_done) */ + + /* Add to the completed list. */ + list_add(&request->completed_node, + &host->requests_to_complete); + + /* Take the request off the device's pending request list. */ + list_del_init(&request->dev_node); + break; + + case isci_perform_aborted_io_completion: + /* No notification to libsas because this request is + * already in the abort path. + */ + /* Wake up whatever process was waiting for this + * request to complete. + */ + WARN_ON(request->io_request_completion == NULL); + + if (request->io_request_completion != NULL) { + + /* Signal whoever is waiting that this + * request is complete. + */ + complete(request->io_request_completion); + } + break; + + case isci_perform_error_io_completion: + /* Use sas_task_abort */ + /* Add to the aborted list. */ + list_add(&request->completed_node, + &host->requests_to_errorback); + break; + + default: + /* Add to the error to libsas list. */ + list_add(&request->completed_node, + &host->requests_to_errorback); break; } + dev_dbg(&host->pdev->dev, + "%s: %d - task = %p, response=%d (%d), status=%d (%d)\n", + __func__, task_notification_selection, task, + (task) ? task->task_status.resp : 0, response, + (task) ? task->task_status.stat : 0, status); } static void isci_process_stp_response(struct sas_task *task, struct dev_to_host_fis *fis) @@ -2746,164 +2715,295 @@ static void isci_request_io_request_complete(struct isci_host *ihost, struct isci_remote_device *idev = request->target_device; enum service_response response = SAS_TASK_UNDELIVERED; enum exec_status status = SAS_ABORTED_TASK; + enum isci_request_status request_status; + enum isci_completion_selection complete_to_host + = isci_perform_normal_io_completion; dev_dbg(&ihost->pdev->dev, - "%s: request = %p, task = %p, " + "%s: request = %p, task = %p,\n" "task->data_dir = %d completion_status = 0x%x\n", - __func__, request, task, task->data_dir, completion_status); - - /* The request is done from an SCU HW perspective. */ - - /* This is an active request being completed from the core. */ - switch (completion_status) { - - case SCI_IO_FAILURE_RESPONSE_VALID: - dev_dbg(&ihost->pdev->dev, - "%s: SCI_IO_FAILURE_RESPONSE_VALID (%p/%p)\n", - __func__, request, task); - - if (sas_protocol_ata(task->task_proto)) { - isci_process_stp_response(task, &request->stp.rsp); - } else if (SAS_PROTOCOL_SSP == task->task_proto) { + __func__, + request, + task, + task->data_dir, + completion_status); - /* crack the iu response buffer. */ - resp_iu = &request->ssp.rsp; - isci_request_process_response_iu(task, resp_iu, - &ihost->pdev->dev); + spin_lock(&request->state_lock); + request_status = request->status; - } else if (SAS_PROTOCOL_SMP == task->task_proto) { + /* Decode the request status. Note that if the request has been + * aborted by a task management function, we don't care + * what the status is. + */ + switch (request_status) { + + case aborted: + /* "aborted" indicates that the request was aborted by a task + * management function, since once a task management request is + * perfomed by the device, the request only completes because + * of the subsequent driver terminate. + * + * Aborted also means an external thread is explicitly managing + * this request, so that we do not complete it up the stack. + * + * The target is still there (since the TMF was successful). + */ + set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); + response = SAS_TASK_COMPLETE; - dev_err(&ihost->pdev->dev, - "%s: SCI_IO_FAILURE_RESPONSE_VALID: " - "SAS_PROTOCOL_SMP protocol\n", - __func__); + /* See if the device has been/is being stopped. Note + * that we ignore the quiesce state, since we are + * concerned about the actual device state. + */ + if (!idev) + status = SAS_DEVICE_UNKNOWN; + else + status = SAS_ABORTED_TASK; - } else - dev_err(&ihost->pdev->dev, - "%s: unknown protocol\n", __func__); + complete_to_host = isci_perform_aborted_io_completion; + /* This was an aborted request. */ - /* use the task status set in the task struct by the - * isci_request_process_response_iu call. - */ - set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); - response = task->task_status.resp; - status = task->task_status.stat; + spin_unlock(&request->state_lock); break; - case SCI_IO_SUCCESS: - case SCI_IO_SUCCESS_IO_DONE_EARLY: - - response = SAS_TASK_COMPLETE; - status = SAM_STAT_GOOD; + case aborting: + /* aborting means that the task management function tried and + * failed to abort the request. We need to note the request + * as SAS_TASK_UNDELIVERED, so that the scsi mid layer marks the + * target as down. + * + * Aborting also means an external thread is explicitly managing + * this request, so that we do not complete it up the stack. + */ set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); + response = SAS_TASK_UNDELIVERED; - if (completion_status == SCI_IO_SUCCESS_IO_DONE_EARLY) { - - /* This was an SSP / STP / SATA transfer. - * There is a possibility that less data than - * the maximum was transferred. - */ - u32 transferred_length = sci_req_tx_bytes(request); - - task->task_status.residual - = task->total_xfer_len - transferred_length; + if (!idev) + /* The device has been /is being stopped. Note that + * we ignore the quiesce state, since we are + * concerned about the actual device state. + */ + status = SAS_DEVICE_UNKNOWN; + else + status = SAS_PHY_DOWN; - /* If there were residual bytes, call this an - * underrun. - */ - if (task->task_status.residual != 0) - status = SAS_DATA_UNDERRUN; + complete_to_host = isci_perform_aborted_io_completion; - dev_dbg(&ihost->pdev->dev, - "%s: SCI_IO_SUCCESS_IO_DONE_EARLY %d\n", - __func__, status); + /* This was an aborted request. */ - } else - dev_dbg(&ihost->pdev->dev, "%s: SCI_IO_SUCCESS\n", - __func__); + spin_unlock(&request->state_lock); break; - case SCI_IO_FAILURE_TERMINATED: - - dev_dbg(&ihost->pdev->dev, - "%s: SCI_IO_FAILURE_TERMINATED (%p/%p)\n", - __func__, request, task); + case terminating: - /* The request was terminated explicitly. */ + /* This was an terminated request. This happens when + * the I/O is being terminated because of an action on + * the device (reset, tear down, etc.), and the I/O needs + * to be completed up the stack. + */ set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); response = SAS_TASK_UNDELIVERED; /* See if the device has been/is being stopped. Note - * that we ignore the quiesce state, since we are - * concerned about the actual device state. - */ + * that we ignore the quiesce state, since we are + * concerned about the actual device state. + */ if (!idev) status = SAS_DEVICE_UNKNOWN; else status = SAS_ABORTED_TASK; - break; - case SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR: + complete_to_host = isci_perform_aborted_io_completion; - isci_request_handle_controller_specific_errors(idev, request, - task, &response, - &status); + /* This was a terminated request. */ + + spin_unlock(&request->state_lock); break; - case SCI_IO_FAILURE_REMOTE_DEVICE_RESET_REQUIRED: - /* This is a special case, in that the I/O completion - * is telling us that the device needs a reset. - * In order for the device reset condition to be - * noticed, the I/O has to be handled in the error - * handler. Set the reset flag and cause the - * SCSI error thread to be scheduled. - */ - spin_lock_irqsave(&task->task_state_lock, task_flags); - task->task_state_flags |= SAS_TASK_NEED_DEV_RESET; - spin_unlock_irqrestore(&task->task_state_lock, task_flags); + case dead: + /* This was a terminated request that timed-out during the + * termination process. There is no task to complete to + * libsas. + */ + complete_to_host = isci_perform_normal_io_completion; + spin_unlock(&request->state_lock); + break; - /* Fail the I/O. */ - response = SAS_TASK_UNDELIVERED; - status = SAM_STAT_TASK_ABORTED; + default: - clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); - break; + /* The request is done from an SCU HW perspective. */ + request->status = completed; - case SCI_FAILURE_RETRY_REQUIRED: + spin_unlock(&request->state_lock); - /* Fail the I/O so it can be retried. */ - response = SAS_TASK_UNDELIVERED; - if (!idev) - status = SAS_DEVICE_UNKNOWN; - else - status = SAS_ABORTED_TASK; + /* This is an active request being completed from the core. */ + switch (completion_status) { - set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); - break; + case SCI_IO_FAILURE_RESPONSE_VALID: + dev_dbg(&ihost->pdev->dev, + "%s: SCI_IO_FAILURE_RESPONSE_VALID (%p/%p)\n", + __func__, + request, + task); + if (sas_protocol_ata(task->task_proto)) { + isci_process_stp_response(task, &request->stp.rsp); + } else if (SAS_PROTOCOL_SSP == task->task_proto) { - default: - /* Catch any otherwise unhandled error codes here. */ - dev_dbg(&ihost->pdev->dev, - "%s: invalid completion code: 0x%x - " - "isci_request = %p\n", - __func__, completion_status, request); + /* crack the iu response buffer. */ + resp_iu = &request->ssp.rsp; + isci_request_process_response_iu(task, resp_iu, + &ihost->pdev->dev); - response = SAS_TASK_UNDELIVERED; + } else if (SAS_PROTOCOL_SMP == task->task_proto) { - /* See if the device has been/is being stopped. Note - * that we ignore the quiesce state, since we are - * concerned about the actual device state. - */ - if (!idev) - status = SAS_DEVICE_UNKNOWN; - else - status = SAS_ABORTED_TASK; + dev_err(&ihost->pdev->dev, + "%s: SCI_IO_FAILURE_RESPONSE_VALID: " + "SAS_PROTOCOL_SMP protocol\n", + __func__); + + } else + dev_err(&ihost->pdev->dev, + "%s: unknown protocol\n", __func__); - if (SAS_PROTOCOL_SMP == task->task_proto) + /* use the task status set in the task struct by the + * isci_request_process_response_iu call. + */ set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); - else + response = task->task_status.resp; + status = task->task_status.stat; + break; + + case SCI_IO_SUCCESS: + case SCI_IO_SUCCESS_IO_DONE_EARLY: + + response = SAS_TASK_COMPLETE; + status = SAM_STAT_GOOD; + set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); + + if (completion_status == SCI_IO_SUCCESS_IO_DONE_EARLY) { + + /* This was an SSP / STP / SATA transfer. + * There is a possibility that less data than + * the maximum was transferred. + */ + u32 transferred_length = sci_req_tx_bytes(request); + + task->task_status.residual + = task->total_xfer_len - transferred_length; + + /* If there were residual bytes, call this an + * underrun. + */ + if (task->task_status.residual != 0) + status = SAS_DATA_UNDERRUN; + + dev_dbg(&ihost->pdev->dev, + "%s: SCI_IO_SUCCESS_IO_DONE_EARLY %d\n", + __func__, + status); + + } else + dev_dbg(&ihost->pdev->dev, + "%s: SCI_IO_SUCCESS\n", + __func__); + + break; + + case SCI_IO_FAILURE_TERMINATED: + dev_dbg(&ihost->pdev->dev, + "%s: SCI_IO_FAILURE_TERMINATED (%p/%p)\n", + __func__, + request, + task); + + /* The request was terminated explicitly. No handling + * is needed in the SCSI error handler path. + */ + set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); + response = SAS_TASK_UNDELIVERED; + + /* See if the device has been/is being stopped. Note + * that we ignore the quiesce state, since we are + * concerned about the actual device state. + */ + if (!idev) + status = SAS_DEVICE_UNKNOWN; + else + status = SAS_ABORTED_TASK; + + complete_to_host = isci_perform_normal_io_completion; + break; + + case SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR: + + isci_request_handle_controller_specific_errors( + idev, request, task, &response, &status, + &complete_to_host); + + break; + + case SCI_IO_FAILURE_REMOTE_DEVICE_RESET_REQUIRED: + /* This is a special case, in that the I/O completion + * is telling us that the device needs a reset. + * In order for the device reset condition to be + * noticed, the I/O has to be handled in the error + * handler. Set the reset flag and cause the + * SCSI error thread to be scheduled. + */ + spin_lock_irqsave(&task->task_state_lock, task_flags); + task->task_state_flags |= SAS_TASK_NEED_DEV_RESET; + spin_unlock_irqrestore(&task->task_state_lock, task_flags); + + /* Fail the I/O. */ + response = SAS_TASK_UNDELIVERED; + status = SAM_STAT_TASK_ABORTED; + + complete_to_host = isci_perform_error_io_completion; clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); + break; + + case SCI_FAILURE_RETRY_REQUIRED: + + /* Fail the I/O so it can be retried. */ + response = SAS_TASK_UNDELIVERED; + if (!idev) + status = SAS_DEVICE_UNKNOWN; + else + status = SAS_ABORTED_TASK; + + complete_to_host = isci_perform_normal_io_completion; + set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); + break; + + + default: + /* Catch any otherwise unhandled error codes here. */ + dev_dbg(&ihost->pdev->dev, + "%s: invalid completion code: 0x%x - " + "isci_request = %p\n", + __func__, completion_status, request); + + response = SAS_TASK_UNDELIVERED; + + /* See if the device has been/is being stopped. Note + * that we ignore the quiesce state, since we are + * concerned about the actual device state. + */ + if (!idev) + status = SAS_DEVICE_UNKNOWN; + else + status = SAS_ABORTED_TASK; + + if (SAS_PROTOCOL_SMP == task->task_proto) { + set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); + complete_to_host = isci_perform_normal_io_completion; + } else { + clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); + complete_to_host = isci_perform_error_io_completion; + } + break; + } break; } @@ -2938,18 +3038,10 @@ static void isci_request_io_request_complete(struct isci_host *ihost, break; } - spin_lock_irqsave(&task->task_state_lock, task_flags); - - task->task_status.resp = response; - task->task_status.stat = status; - - if (test_bit(IREQ_COMPLETE_IN_TARGET, &request->flags)) { - /* Normal notification (task_done) */ - task->task_state_flags |= SAS_TASK_STATE_DONE; - task->task_state_flags &= ~(SAS_TASK_AT_INITIATOR | - SAS_TASK_STATE_PENDING); - } - spin_unlock_irqrestore(&task->task_state_lock, task_flags); + /* Put the completed request on the correct list */ + isci_task_save_for_upper_layer_completion(ihost, request, response, + status, complete_to_host + ); /* complete the io request to the core. */ sci_controller_complete_io(ihost, request->target_device, request); @@ -2959,8 +3051,6 @@ static void isci_request_io_request_complete(struct isci_host *ihost, * task to recognize the already completed case. */ set_bit(IREQ_TERMINATED, &request->flags); - - ireq_done(ihost, request, task); } static void sci_request_started_state_enter(struct sci_base_state_machine *sm) @@ -3079,7 +3169,7 @@ sci_general_request_construct(struct isci_host *ihost, sci_init_sm(&ireq->sm, sci_request_state_table, SCI_REQ_INIT); ireq->target_device = idev; - ireq->protocol = SAS_PROTOCOL_NONE; + ireq->protocol = SCIC_NO_PROTOCOL; ireq->saved_rx_frame_index = SCU_INVALID_FRAME_INDEX; ireq->sci_status = SCI_SUCCESS; @@ -3103,7 +3193,7 @@ sci_io_request_construct(struct isci_host *ihost, if (dev->dev_type == SAS_END_DEV) /* pass */; - else if (dev_is_sata(dev)) + else if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) memset(&ireq->stp.cmd, 0, sizeof(ireq->stp.cmd)); else if (dev_is_expander(dev)) /* pass */; @@ -3125,15 +3215,10 @@ enum sci_status sci_task_request_construct(struct isci_host *ihost, /* Build the common part of the request */ sci_general_request_construct(ihost, idev, ireq); - if (dev->dev_type == SAS_END_DEV || dev_is_sata(dev)) { + if (dev->dev_type == SAS_END_DEV || + dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) { set_bit(IREQ_TMF, &ireq->flags); memset(ireq->tc, 0, sizeof(struct scu_task_context)); - - /* Set the protocol indicator. */ - if (dev_is_sata(dev)) - ireq->protocol = SAS_PROTOCOL_STP; - else - ireq->protocol = SAS_PROTOCOL_SSP; } else status = SCI_FAILURE_UNSUPPORTED_PROTOCOL; @@ -3226,7 +3311,7 @@ sci_io_request_construct_smp(struct device *dev, if (!dma_map_sg(dev, sg, 1, DMA_TO_DEVICE)) return SCI_FAILURE; - ireq->protocol = SAS_PROTOCOL_SMP; + ireq->protocol = SCIC_SMP_PROTOCOL; /* byte swap the smp request. */ @@ -3411,6 +3496,9 @@ static struct isci_request *isci_request_from_tag(struct isci_host *ihost, u16 t ireq->io_request_completion = NULL; ireq->flags = 0; ireq->num_sg_entries = 0; + INIT_LIST_HEAD(&ireq->completed_node); + INIT_LIST_HEAD(&ireq->dev_node); + isci_request_change_state(ireq, allocated); return ireq; } @@ -3494,15 +3582,26 @@ int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *ide spin_unlock_irqrestore(&ihost->scic_lock, flags); return status; } + /* Either I/O started OK, or the core has signaled that * the device needs a target reset. + * + * In either case, hold onto the I/O for later. + * + * Update it's status and add it to the list in the + * remote device object. */ - if (status != SCI_SUCCESS) { + list_add(&ireq->dev_node, &idev->reqs_in_process); + + if (status == SCI_SUCCESS) { + isci_request_change_state(ireq, started); + } else { /* The request did not really start in the * hardware, so clear the request handle * here so no terminations will be done. */ set_bit(IREQ_TERMINATED, &ireq->flags); + isci_request_change_state(ireq, completed); } spin_unlock_irqrestore(&ihost->scic_lock, flags); diff --git a/trunk/drivers/scsi/isci/request.h b/trunk/drivers/scsi/isci/request.h index aff95317fcf4..057f2378452d 100644 --- a/trunk/drivers/scsi/isci/request.h +++ b/trunk/drivers/scsi/isci/request.h @@ -60,6 +60,30 @@ #include "host.h" #include "scu_task_context.h" +/** + * struct isci_request_status - This enum defines the possible states of an I/O + * request. + * + * + */ +enum isci_request_status { + unallocated = 0x00, + allocated = 0x01, + started = 0x02, + completed = 0x03, + aborting = 0x04, + aborted = 0x05, + terminating = 0x06, + dead = 0x07 +}; + +enum sci_request_protocol { + SCIC_NO_PROTOCOL, + SCIC_SMP_PROTOCOL, + SCIC_SSP_PROTOCOL, + SCIC_STP_PROTOCOL +}; /* XXX remove me, use sas_task.{dev|task_proto} instead */; + /** * isci_stp_request - extra request infrastructure to handle pio/atapi protocol * @pio_len - number of bytes requested at PIO setup @@ -80,14 +104,11 @@ struct isci_stp_request { }; struct isci_request { + enum isci_request_status status; #define IREQ_COMPLETE_IN_TARGET 0 #define IREQ_TERMINATED 1 #define IREQ_TMF 2 #define IREQ_ACTIVE 3 - #define IREQ_PENDING_ABORT 4 /* Set == device was not suspended yet */ - #define IREQ_TC_ABORT_POSTED 5 - #define IREQ_ABORT_PATH_ACTIVE 6 - #define IREQ_NO_AUTO_FREE_TAG 7 /* Set when being explicitly managed */ unsigned long flags; /* XXX kill ttype and ttype_ptr, allocate full sas_task */ union ttype_ptr_union { @@ -95,6 +116,11 @@ struct isci_request { struct isci_tmf *tmf_task_ptr; /* When ttype==tmf_task */ } ttype_ptr; struct isci_host *isci_host; + /* For use in the requests_to_{complete|abort} lists: */ + struct list_head completed_node; + /* For use in the reqs_in_process list: */ + struct list_head dev_node; + spinlock_t state_lock; dma_addr_t request_daddr; dma_addr_t zero_scatter_daddr; unsigned int num_sg_entries; @@ -114,7 +140,7 @@ struct isci_request { struct isci_host *owning_controller; struct isci_remote_device *target_device; u16 io_tag; - enum sas_protocol protocol; + enum sci_request_protocol protocol; u32 scu_status; /* hardware result */ u32 sci_status; /* upper layer disposition */ u32 post_context; @@ -283,6 +309,92 @@ sci_io_request_get_dma_addr(struct isci_request *ireq, void *virt_addr) return ireq->request_daddr + (requested_addr - base_addr); } +/** + * isci_request_change_state() - This function sets the status of the request + * object. + * @request: This parameter points to the isci_request object + * @status: This Parameter is the new status of the object + * + */ +static inline enum isci_request_status +isci_request_change_state(struct isci_request *isci_request, + enum isci_request_status status) +{ + enum isci_request_status old_state; + unsigned long flags; + + dev_dbg(&isci_request->isci_host->pdev->dev, + "%s: isci_request = %p, state = 0x%x\n", + __func__, + isci_request, + status); + + BUG_ON(isci_request == NULL); + + spin_lock_irqsave(&isci_request->state_lock, flags); + old_state = isci_request->status; + isci_request->status = status; + spin_unlock_irqrestore(&isci_request->state_lock, flags); + + return old_state; +} + +/** + * isci_request_change_started_to_newstate() - This function sets the status of + * the request object. + * @request: This parameter points to the isci_request object + * @status: This Parameter is the new status of the object + * + * state previous to any change. + */ +static inline enum isci_request_status +isci_request_change_started_to_newstate(struct isci_request *isci_request, + struct completion *completion_ptr, + enum isci_request_status newstate) +{ + enum isci_request_status old_state; + unsigned long flags; + + spin_lock_irqsave(&isci_request->state_lock, flags); + + old_state = isci_request->status; + + if (old_state == started || old_state == aborting) { + BUG_ON(isci_request->io_request_completion != NULL); + + isci_request->io_request_completion = completion_ptr; + isci_request->status = newstate; + } + + spin_unlock_irqrestore(&isci_request->state_lock, flags); + + dev_dbg(&isci_request->isci_host->pdev->dev, + "%s: isci_request = %p, old_state = 0x%x\n", + __func__, + isci_request, + old_state); + + return old_state; +} + +/** + * isci_request_change_started_to_aborted() - This function sets the status of + * the request object. + * @request: This parameter points to the isci_request object + * @completion_ptr: This parameter is saved as the kernel completion structure + * signalled when the old request completes. + * + * state previous to any change. + */ +static inline enum isci_request_status +isci_request_change_started_to_aborted(struct isci_request *isci_request, + struct completion *completion_ptr) +{ + return isci_request_change_started_to_newstate(isci_request, + completion_ptr, + aborted); +} + #define isci_request_access_task(req) ((req)->ttype_ptr.io_task_ptr) #define isci_request_access_tmf(req) ((req)->ttype_ptr.tmf_task_ptr) @@ -292,6 +404,8 @@ struct isci_request *isci_tmf_request_from_tag(struct isci_host *ihost, u16 tag); int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *idev, struct sas_task *task, u16 tag); +void isci_terminate_pending_requests(struct isci_host *ihost, + struct isci_remote_device *idev); enum sci_status sci_task_request_construct(struct isci_host *ihost, struct isci_remote_device *idev, @@ -307,4 +421,5 @@ static inline int isci_task_is_ncq_recovery(struct sas_task *task) task->ata_task.fis.lbal == ATA_LOG_SATA_NCQ); } + #endif /* !defined(_ISCI_REQUEST_H_) */ diff --git a/trunk/drivers/scsi/isci/scu_completion_codes.h b/trunk/drivers/scsi/isci/scu_completion_codes.h index 071cb74a211c..c8b329c695f9 100644 --- a/trunk/drivers/scsi/isci/scu_completion_codes.h +++ b/trunk/drivers/scsi/isci/scu_completion_codes.h @@ -224,7 +224,6 @@ * 32-bit value like we want, each immediate value must be cast to a u32. */ #define SCU_TASK_DONE_GOOD ((u32)0x00) -#define SCU_TASK_DONE_TX_RAW_CMD_ERR ((u32)0x08) #define SCU_TASK_DONE_CRC_ERR ((u32)0x14) #define SCU_TASK_DONE_CHECK_RESPONSE ((u32)0x14) #define SCU_TASK_DONE_GEN_RESPONSE ((u32)0x15) @@ -238,7 +237,6 @@ #define SCU_TASK_DONE_LL_LF_TERM ((u32)0x1A) #define SCU_TASK_DONE_DATA_LEN_ERR ((u32)0x1A) #define SCU_TASK_DONE_LL_CL_TERM ((u32)0x1B) -#define SCU_TASK_DONE_BREAK_RCVD ((u32)0x1B) #define SCU_TASK_DONE_LL_ABORT_ERR ((u32)0x1B) #define SCU_TASK_DONE_SEQ_INV_TYPE ((u32)0x1C) #define SCU_TASK_DONE_UNEXP_XR ((u32)0x1C) diff --git a/trunk/drivers/scsi/isci/task.c b/trunk/drivers/scsi/isci/task.c index 6bc74eb012c9..374254ede9d4 100644 --- a/trunk/drivers/scsi/isci/task.c +++ b/trunk/drivers/scsi/isci/task.c @@ -78,25 +78,54 @@ static void isci_task_refuse(struct isci_host *ihost, struct sas_task *task, enum exec_status status) { - unsigned long flags; - - /* Normal notification (task_done) */ - dev_dbg(&ihost->pdev->dev, "%s: task = %p, response=%d, status=%d\n", - __func__, task, response, status); + enum isci_completion_selection disposition; - spin_lock_irqsave(&task->task_state_lock, flags); + disposition = isci_perform_normal_io_completion; + disposition = isci_task_set_completion_status(task, response, status, + disposition); - task->task_status.resp = response; - task->task_status.stat = status; + /* Tasks aborted specifically by a call to the lldd_abort_task + * function should not be completed to the host in the regular path. + */ + switch (disposition) { + case isci_perform_normal_io_completion: + /* Normal notification (task_done) */ + dev_dbg(&ihost->pdev->dev, + "%s: Normal - task = %p, response=%d, " + "status=%d\n", + __func__, task, response, status); + + task->lldd_task = NULL; + task->task_done(task); + break; + + case isci_perform_aborted_io_completion: + /* + * No notification because this request is already in the + * abort path. + */ + dev_dbg(&ihost->pdev->dev, + "%s: Aborted - task = %p, response=%d, " + "status=%d\n", + __func__, task, response, status); + break; - /* Normal notification (task_done) */ - task->task_state_flags |= SAS_TASK_STATE_DONE; - task->task_state_flags &= ~(SAS_TASK_AT_INITIATOR | - SAS_TASK_STATE_PENDING); - task->lldd_task = NULL; - spin_unlock_irqrestore(&task->task_state_lock, flags); + case isci_perform_error_io_completion: + /* Use sas_task_abort */ + dev_dbg(&ihost->pdev->dev, + "%s: Error - task = %p, response=%d, " + "status=%d\n", + __func__, task, response, status); + sas_task_abort(task); + break; - task->task_done(task); + default: + dev_dbg(&ihost->pdev->dev, + "%s: isci task notification default case!", + __func__); + sas_task_abort(task); + break; + } } #define for_each_sas_task(num, task) \ @@ -260,6 +289,60 @@ static struct isci_request *isci_task_request_build(struct isci_host *ihost, return ireq; } +/** +* isci_request_mark_zombie() - This function must be called with scic_lock held. +*/ +static void isci_request_mark_zombie(struct isci_host *ihost, struct isci_request *ireq) +{ + struct completion *tmf_completion = NULL; + struct completion *req_completion; + + /* Set the request state to "dead". */ + ireq->status = dead; + + req_completion = ireq->io_request_completion; + ireq->io_request_completion = NULL; + + if (test_bit(IREQ_TMF, &ireq->flags)) { + /* Break links with the TMF request. */ + struct isci_tmf *tmf = isci_request_access_tmf(ireq); + + /* In the case where a task request is dying, + * the thread waiting on the complete will sit and + * timeout unless we wake it now. Since the TMF + * has a default error status, complete it here + * to wake the waiting thread. + */ + if (tmf) { + tmf_completion = tmf->complete; + tmf->complete = NULL; + } + ireq->ttype_ptr.tmf_task_ptr = NULL; + dev_dbg(&ihost->pdev->dev, "%s: tmf_code %d, managed tag %#x\n", + __func__, tmf->tmf_code, tmf->io_tag); + } else { + /* Break links with the sas_task - the callback is done + * elsewhere. + */ + struct sas_task *task = isci_request_access_task(ireq); + + if (task) + task->lldd_task = NULL; + + ireq->ttype_ptr.io_task_ptr = NULL; + } + + dev_warn(&ihost->pdev->dev, "task context unrecoverable (tag: %#x)\n", + ireq->io_tag); + + /* Don't force waiting threads to timeout. */ + if (req_completion) + complete(req_completion); + + if (tmf_completion != NULL) + complete(tmf_completion); +} + static int isci_task_execute_tmf(struct isci_host *ihost, struct isci_remote_device *idev, struct isci_tmf *tmf, unsigned long timeout_ms) @@ -317,10 +400,16 @@ static int isci_task_execute_tmf(struct isci_host *ihost, spin_unlock_irqrestore(&ihost->scic_lock, flags); goto err_tci; } - spin_unlock_irqrestore(&ihost->scic_lock, flags); - /* The RNC must be unsuspended before the TMF can get a response. */ - isci_remote_device_resume_from_abort(ihost, idev); + if (tmf->cb_state_func != NULL) + tmf->cb_state_func(isci_tmf_started, tmf, tmf->cb_data); + + isci_request_change_state(ireq, started); + + /* add the request to the remote device request list. */ + list_add(&ireq->dev_node, &idev->reqs_in_process); + + spin_unlock_irqrestore(&ihost->scic_lock, flags); /* Wait for the TMF to complete, or a timeout. */ timeleft = wait_for_completion_timeout(&completion, @@ -330,7 +419,32 @@ static int isci_task_execute_tmf(struct isci_host *ihost, /* The TMF did not complete - this could be because * of an unplug. Terminate the TMF request now. */ - isci_remote_device_suspend_terminate(ihost, idev, ireq); + spin_lock_irqsave(&ihost->scic_lock, flags); + + if (tmf->cb_state_func != NULL) + tmf->cb_state_func(isci_tmf_timed_out, tmf, + tmf->cb_data); + + sci_controller_terminate_request(ihost, idev, ireq); + + spin_unlock_irqrestore(&ihost->scic_lock, flags); + + timeleft = wait_for_completion_timeout( + &completion, + msecs_to_jiffies(ISCI_TERMINATION_TIMEOUT_MSEC)); + + if (!timeleft) { + /* Strange condition - the termination of the TMF + * request timed-out. + */ + spin_lock_irqsave(&ihost->scic_lock, flags); + + /* If the TMF status has not changed, kill it. */ + if (tmf->status == SCI_FAILURE_TIMEOUT) + isci_request_mark_zombie(ihost, ireq); + + spin_unlock_irqrestore(&ihost->scic_lock, flags); + } } isci_print_tmf(ihost, tmf); @@ -362,20 +476,314 @@ static int isci_task_execute_tmf(struct isci_host *ihost, } static void isci_task_build_tmf(struct isci_tmf *tmf, - enum isci_tmf_function_codes code) + enum isci_tmf_function_codes code, + void (*tmf_sent_cb)(enum isci_tmf_cb_state, + struct isci_tmf *, + void *), + void *cb_data) { memset(tmf, 0, sizeof(*tmf)); - tmf->tmf_code = code; + + tmf->tmf_code = code; + tmf->cb_state_func = tmf_sent_cb; + tmf->cb_data = cb_data; } static void isci_task_build_abort_task_tmf(struct isci_tmf *tmf, enum isci_tmf_function_codes code, + void (*tmf_sent_cb)(enum isci_tmf_cb_state, + struct isci_tmf *, + void *), struct isci_request *old_request) { - isci_task_build_tmf(tmf, code); + isci_task_build_tmf(tmf, code, tmf_sent_cb, old_request); tmf->io_tag = old_request->io_tag; } +/** + * isci_task_validate_request_to_abort() - This function checks the given I/O + * against the "started" state. If the request is still "started", it's + * state is changed to aborted. NOTE: isci_host->scic_lock MUST BE HELD + * BEFORE CALLING THIS FUNCTION. + * @isci_request: This parameter specifies the request object to control. + * @isci_host: This parameter specifies the ISCI host object + * @isci_device: This is the device to which the request is pending. + * @aborted_io_completion: This is a completion structure that will be added to + * the request in case it is changed to aborting; this completion is + * triggered when the request is fully completed. + * + * Either "started" on successful change of the task status to "aborted", or + * "unallocated" if the task cannot be controlled. + */ +static enum isci_request_status isci_task_validate_request_to_abort( + struct isci_request *isci_request, + struct isci_host *isci_host, + struct isci_remote_device *isci_device, + struct completion *aborted_io_completion) +{ + enum isci_request_status old_state = unallocated; + + /* Only abort the task if it's in the + * device's request_in_process list + */ + if (isci_request && !list_empty(&isci_request->dev_node)) { + old_state = isci_request_change_started_to_aborted( + isci_request, aborted_io_completion); + + } + + return old_state; +} + +static int isci_request_is_dealloc_managed(enum isci_request_status stat) +{ + switch (stat) { + case aborted: + case aborting: + case terminating: + case completed: + case dead: + return true; + default: + return false; + } +} + +/** + * isci_terminate_request_core() - This function will terminate the given + * request, and wait for it to complete. This function must only be called + * from a thread that can wait. Note that the request is terminated and + * completed (back to the host, if started there). + * @ihost: This SCU. + * @idev: The target. + * @isci_request: The I/O request to be terminated. + * + */ +static void isci_terminate_request_core(struct isci_host *ihost, + struct isci_remote_device *idev, + struct isci_request *isci_request) +{ + enum sci_status status = SCI_SUCCESS; + bool was_terminated = false; + bool needs_cleanup_handling = false; + unsigned long flags; + unsigned long termination_completed = 1; + struct completion *io_request_completion; + + dev_dbg(&ihost->pdev->dev, + "%s: device = %p; request = %p\n", + __func__, idev, isci_request); + + spin_lock_irqsave(&ihost->scic_lock, flags); + + io_request_completion = isci_request->io_request_completion; + + /* Note that we are not going to control + * the target to abort the request. + */ + set_bit(IREQ_COMPLETE_IN_TARGET, &isci_request->flags); + + /* Make sure the request wasn't just sitting around signalling + * device condition (if the request handle is NULL, then the + * request completed but needed additional handling here). + */ + if (!test_bit(IREQ_TERMINATED, &isci_request->flags)) { + was_terminated = true; + needs_cleanup_handling = true; + status = sci_controller_terminate_request(ihost, + idev, + isci_request); + } + spin_unlock_irqrestore(&ihost->scic_lock, flags); + + /* + * The only time the request to terminate will + * fail is when the io request is completed and + * being aborted. + */ + if (status != SCI_SUCCESS) { + dev_dbg(&ihost->pdev->dev, + "%s: sci_controller_terminate_request" + " returned = 0x%x\n", + __func__, status); + + isci_request->io_request_completion = NULL; + + } else { + if (was_terminated) { + dev_dbg(&ihost->pdev->dev, + "%s: before completion wait (%p/%p)\n", + __func__, isci_request, io_request_completion); + + /* Wait here for the request to complete. */ + termination_completed + = wait_for_completion_timeout( + io_request_completion, + msecs_to_jiffies(ISCI_TERMINATION_TIMEOUT_MSEC)); + + if (!termination_completed) { + + /* The request to terminate has timed out. */ + spin_lock_irqsave(&ihost->scic_lock, flags); + + /* Check for state changes. */ + if (!test_bit(IREQ_TERMINATED, + &isci_request->flags)) { + + /* The best we can do is to have the + * request die a silent death if it + * ever really completes. + */ + isci_request_mark_zombie(ihost, + isci_request); + needs_cleanup_handling = true; + } else + termination_completed = 1; + + spin_unlock_irqrestore(&ihost->scic_lock, + flags); + + if (!termination_completed) { + + dev_dbg(&ihost->pdev->dev, + "%s: *** Timeout waiting for " + "termination(%p/%p)\n", + __func__, io_request_completion, + isci_request); + + /* The request can no longer be referenced + * safely since it may go away if the + * termination every really does complete. + */ + isci_request = NULL; + } + } + if (termination_completed) + dev_dbg(&ihost->pdev->dev, + "%s: after completion wait (%p/%p)\n", + __func__, isci_request, io_request_completion); + } + + if (termination_completed) { + + isci_request->io_request_completion = NULL; + + /* Peek at the status of the request. This will tell + * us if there was special handling on the request such that it + * needs to be detached and freed here. + */ + spin_lock_irqsave(&isci_request->state_lock, flags); + + needs_cleanup_handling + = isci_request_is_dealloc_managed( + isci_request->status); + + spin_unlock_irqrestore(&isci_request->state_lock, flags); + + } + if (needs_cleanup_handling) { + + dev_dbg(&ihost->pdev->dev, + "%s: cleanup isci_device=%p, request=%p\n", + __func__, idev, isci_request); + + if (isci_request != NULL) { + spin_lock_irqsave(&ihost->scic_lock, flags); + isci_free_tag(ihost, isci_request->io_tag); + isci_request_change_state(isci_request, unallocated); + list_del_init(&isci_request->dev_node); + spin_unlock_irqrestore(&ihost->scic_lock, flags); + } + } + } +} + +/** + * isci_terminate_pending_requests() - This function will change the all of the + * requests on the given device's state to "aborting", will terminate the + * requests, and wait for them to complete. This function must only be + * called from a thread that can wait. Note that the requests are all + * terminated and completed (back to the host, if started there). + * @isci_host: This parameter specifies SCU. + * @idev: This parameter specifies the target. + * + */ +void isci_terminate_pending_requests(struct isci_host *ihost, + struct isci_remote_device *idev) +{ + struct completion request_completion; + enum isci_request_status old_state; + unsigned long flags; + LIST_HEAD(list); + + spin_lock_irqsave(&ihost->scic_lock, flags); + list_splice_init(&idev->reqs_in_process, &list); + + /* assumes that isci_terminate_request_core deletes from the list */ + while (!list_empty(&list)) { + struct isci_request *ireq = list_entry(list.next, typeof(*ireq), dev_node); + + /* Change state to "terminating" if it is currently + * "started". + */ + old_state = isci_request_change_started_to_newstate(ireq, + &request_completion, + terminating); + switch (old_state) { + case started: + case completed: + case aborting: + break; + default: + /* termination in progress, or otherwise dispositioned. + * We know the request was on 'list' so should be safe + * to move it back to reqs_in_process + */ + list_move(&ireq->dev_node, &idev->reqs_in_process); + ireq = NULL; + break; + } + + if (!ireq) + continue; + spin_unlock_irqrestore(&ihost->scic_lock, flags); + + init_completion(&request_completion); + + dev_dbg(&ihost->pdev->dev, + "%s: idev=%p request=%p; task=%p old_state=%d\n", + __func__, idev, ireq, + (!test_bit(IREQ_TMF, &ireq->flags) + ? isci_request_access_task(ireq) + : NULL), + old_state); + + /* If the old_state is started: + * This request was not already being aborted. If it had been, + * then the aborting I/O (ie. the TMF request) would not be in + * the aborting state, and thus would be terminated here. Note + * that since the TMF completion's call to the kernel function + * "complete()" does not happen until the pending I/O request + * terminate fully completes, we do not have to implement a + * special wait here for already aborting requests - the + * termination of the TMF request will force the request + * to finish it's already started terminate. + * + * If old_state == completed: + * This request completed from the SCU hardware perspective + * and now just needs cleaning up in terms of freeing the + * request and potentially calling up to libsas. + * + * If old_state == aborting: + * This request has already gone through a TMF timeout, but may + * not have been terminated; needs cleaning up at least. + */ + isci_terminate_request_core(ihost, idev, ireq); + spin_lock_irqsave(&ihost->scic_lock, flags); + } + spin_unlock_irqrestore(&ihost->scic_lock, flags); +} + /** * isci_task_send_lu_reset_sas() - This function is called by of the SAS Domain * Template functions. @@ -399,7 +807,7 @@ static int isci_task_send_lu_reset_sas( * value is "TMF_RESP_FUNC_COMPLETE", or the request timed-out (or * was otherwise unable to be executed ("TMF_RESP_FUNC_FAILED"). */ - isci_task_build_tmf(&tmf, isci_tmf_ssp_lun_reset); + isci_task_build_tmf(&tmf, isci_tmf_ssp_lun_reset, NULL, NULL); #define ISCI_LU_RESET_TIMEOUT_MS 2000 /* 2 second timeout. */ ret = isci_task_execute_tmf(isci_host, isci_device, &tmf, ISCI_LU_RESET_TIMEOUT_MS); @@ -418,44 +826,42 @@ static int isci_task_send_lu_reset_sas( int isci_task_lu_reset(struct domain_device *dev, u8 *lun) { - struct isci_host *ihost = dev_to_ihost(dev); - struct isci_remote_device *idev; + struct isci_host *isci_host = dev_to_ihost(dev); + struct isci_remote_device *isci_device; unsigned long flags; - int ret = TMF_RESP_FUNC_COMPLETE; + int ret; - spin_lock_irqsave(&ihost->scic_lock, flags); - idev = isci_get_device(dev->lldd_dev); - spin_unlock_irqrestore(&ihost->scic_lock, flags); + spin_lock_irqsave(&isci_host->scic_lock, flags); + isci_device = isci_lookup_device(dev); + spin_unlock_irqrestore(&isci_host->scic_lock, flags); - dev_dbg(&ihost->pdev->dev, + dev_dbg(&isci_host->pdev->dev, "%s: domain_device=%p, isci_host=%p; isci_device=%p\n", - __func__, dev, ihost, idev); + __func__, dev, isci_host, isci_device); - if (!idev) { - /* If the device is gone, escalate to I_T_Nexus_Reset. */ - dev_dbg(&ihost->pdev->dev, "%s: No dev\n", __func__); + if (!isci_device) { + /* If the device is gone, stop the escalations. */ + dev_dbg(&isci_host->pdev->dev, "%s: No dev\n", __func__); - ret = TMF_RESP_FUNC_FAILED; + ret = TMF_RESP_FUNC_COMPLETE; goto out; } - /* Suspend the RNC, kill all TCs */ - if (isci_remote_device_suspend_terminate(ihost, idev, NULL) - != SCI_SUCCESS) { - /* The suspend/terminate only fails if isci_get_device fails */ - ret = TMF_RESP_FUNC_FAILED; - goto out; - } - /* All pending I/Os have been terminated and cleaned up. */ - if (!test_bit(IDEV_GONE, &idev->flags)) { - if (dev_is_sata(dev)) - sas_ata_schedule_reset(dev); - else - /* Send the task management part of the reset. */ - ret = isci_task_send_lu_reset_sas(ihost, idev, lun); - } + /* Send the task management part of the reset. */ + if (dev_is_sata(dev)) { + sas_ata_schedule_reset(dev); + ret = TMF_RESP_FUNC_COMPLETE; + } else + ret = isci_task_send_lu_reset_sas(isci_host, isci_device, lun); + + /* If the LUN reset worked, all the I/O can now be terminated. */ + if (ret == TMF_RESP_FUNC_COMPLETE) + /* Terminate all I/O now. */ + isci_terminate_pending_requests(isci_host, + isci_device); + out: - isci_put_device(idev); + isci_put_device(isci_device); return ret; } @@ -475,6 +881,63 @@ int isci_task_clear_nexus_ha(struct sas_ha_struct *ha) /* Task Management Functions. Must be called from process context. */ +/** + * isci_abort_task_process_cb() - This is a helper function for the abort task + * TMF command. It manages the request state with respect to the successful + * transmission / completion of the abort task request. + * @cb_state: This parameter specifies when this function was called - after + * the TMF request has been started and after it has timed-out. + * @tmf: This parameter specifies the TMF in progress. + * + * + */ +static void isci_abort_task_process_cb( + enum isci_tmf_cb_state cb_state, + struct isci_tmf *tmf, + void *cb_data) +{ + struct isci_request *old_request; + + old_request = (struct isci_request *)cb_data; + + dev_dbg(&old_request->isci_host->pdev->dev, + "%s: tmf=%p, old_request=%p\n", + __func__, tmf, old_request); + + switch (cb_state) { + + case isci_tmf_started: + /* The TMF has been started. Nothing to do here, since the + * request state was already set to "aborted" by the abort + * task function. + */ + if ((old_request->status != aborted) + && (old_request->status != completed)) + dev_dbg(&old_request->isci_host->pdev->dev, + "%s: Bad request status (%d): tmf=%p, old_request=%p\n", + __func__, old_request->status, tmf, old_request); + break; + + case isci_tmf_timed_out: + + /* Set the task's state to "aborting", since the abort task + * function thread set it to "aborted" (above) in anticipation + * of the task management request working correctly. Since the + * timeout has now fired, the TMF request failed. We set the + * state such that the request completion will indicate the + * device is no longer present. + */ + isci_request_change_state(old_request, aborting); + break; + + default: + dev_dbg(&old_request->isci_host->pdev->dev, + "%s: Bad cb_state (%d): tmf=%p, old_request=%p\n", + __func__, cb_state, tmf, old_request); + break; + } +} + /** * isci_task_abort_task() - This function is one of the SAS Domain Template * functions. This function is called by libsas to abort a specified task. @@ -484,20 +947,22 @@ int isci_task_clear_nexus_ha(struct sas_ha_struct *ha) */ int isci_task_abort_task(struct sas_task *task) { - struct isci_host *ihost = dev_to_ihost(task->dev); + struct isci_host *isci_host = dev_to_ihost(task->dev); DECLARE_COMPLETION_ONSTACK(aborted_io_completion); struct isci_request *old_request = NULL; - struct isci_remote_device *idev = NULL; + enum isci_request_status old_state; + struct isci_remote_device *isci_device = NULL; struct isci_tmf tmf; int ret = TMF_RESP_FUNC_FAILED; unsigned long flags; + int perform_termination = 0; /* Get the isci_request reference from the task. Note that * this check does not depend on the pending request list * in the device, because tasks driving resets may land here * after completion in the core. */ - spin_lock_irqsave(&ihost->scic_lock, flags); + spin_lock_irqsave(&isci_host->scic_lock, flags); spin_lock(&task->task_state_lock); old_request = task->lldd_task; @@ -506,29 +971,20 @@ int isci_task_abort_task(struct sas_task *task) if (!(task->task_state_flags & SAS_TASK_STATE_DONE) && (task->task_state_flags & SAS_TASK_AT_INITIATOR) && old_request) - idev = isci_get_device(task->dev->lldd_dev); + isci_device = isci_lookup_device(task->dev); spin_unlock(&task->task_state_lock); - spin_unlock_irqrestore(&ihost->scic_lock, flags); + spin_unlock_irqrestore(&isci_host->scic_lock, flags); - dev_warn(&ihost->pdev->dev, - "%s: dev = %p (%s%s), task = %p, old_request == %p\n", - __func__, idev, - (dev_is_sata(task->dev) ? "STP/SATA" - : ((dev_is_expander(task->dev)) - ? "SMP" - : "SSP")), - ((idev) ? ((test_bit(IDEV_GONE, &idev->flags)) - ? " IDEV_GONE" - : "") - : " "), - task, old_request); + dev_dbg(&isci_host->pdev->dev, + "%s: dev = %p, task = %p, old_request == %p\n", + __func__, isci_device, task, old_request); /* Device reset conditions signalled in task_state_flags are the * responsbility of libsas to observe at the start of the error * handler thread. */ - if (!idev || !old_request) { + if (!isci_device || !old_request) { /* The request has already completed and there * is nothing to do here other than to set the task * done bit, and indicate that the task abort function @@ -542,72 +998,108 @@ int isci_task_abort_task(struct sas_task *task) ret = TMF_RESP_FUNC_COMPLETE; - dev_warn(&ihost->pdev->dev, - "%s: abort task not needed for %p\n", - __func__, task); + dev_dbg(&isci_host->pdev->dev, + "%s: abort task not needed for %p\n", + __func__, task); goto out; } - /* Suspend the RNC, kill the TC */ - if (isci_remote_device_suspend_terminate(ihost, idev, old_request) - != SCI_SUCCESS) { - dev_warn(&ihost->pdev->dev, - "%s: isci_remote_device_reset_terminate(dev=%p, " - "req=%p, task=%p) failed\n", - __func__, idev, old_request, task); - ret = TMF_RESP_FUNC_FAILED; + + spin_lock_irqsave(&isci_host->scic_lock, flags); + + /* Check the request status and change to "aborted" if currently + * "starting"; if true then set the I/O kernel completion + * struct that will be triggered when the request completes. + */ + old_state = isci_task_validate_request_to_abort( + old_request, isci_host, isci_device, + &aborted_io_completion); + if ((old_state != started) && + (old_state != completed) && + (old_state != aborting)) { + + spin_unlock_irqrestore(&isci_host->scic_lock, flags); + + /* The request was already being handled by someone else (because + * they got to set the state away from started). + */ + dev_dbg(&isci_host->pdev->dev, + "%s: device = %p; old_request %p already being aborted\n", + __func__, + isci_device, old_request); + ret = TMF_RESP_FUNC_COMPLETE; goto out; } - spin_lock_irqsave(&ihost->scic_lock, flags); - if (task->task_proto == SAS_PROTOCOL_SMP || sas_protocol_ata(task->task_proto) || - test_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags) || - test_bit(IDEV_GONE, &idev->flags)) { - - spin_unlock_irqrestore(&ihost->scic_lock, flags); + test_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags)) { - /* No task to send, so explicitly resume the device here */ - isci_remote_device_resume_from_abort(ihost, idev); + spin_unlock_irqrestore(&isci_host->scic_lock, flags); - dev_warn(&ihost->pdev->dev, - "%s: %s request" - " or complete_in_target (%d), " - "or IDEV_GONE (%d), thus no TMF\n", - __func__, - ((task->task_proto == SAS_PROTOCOL_SMP) - ? "SMP" - : (sas_protocol_ata(task->task_proto) - ? "SATA/STP" - : "") - ), - test_bit(IREQ_COMPLETE_IN_TARGET, - &old_request->flags), - test_bit(IDEV_GONE, &idev->flags)); + dev_dbg(&isci_host->pdev->dev, + "%s: %s request" + " or complete_in_target (%d), thus no TMF\n", + __func__, + ((task->task_proto == SAS_PROTOCOL_SMP) + ? "SMP" + : (sas_protocol_ata(task->task_proto) + ? "SATA/STP" + : "") + ), + test_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags)); + + if (test_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags)) { + spin_lock_irqsave(&task->task_state_lock, flags); + task->task_state_flags |= SAS_TASK_STATE_DONE; + task->task_state_flags &= ~(SAS_TASK_AT_INITIATOR | + SAS_TASK_STATE_PENDING); + spin_unlock_irqrestore(&task->task_state_lock, flags); + ret = TMF_RESP_FUNC_COMPLETE; + } else { + spin_lock_irqsave(&task->task_state_lock, flags); + task->task_state_flags &= ~(SAS_TASK_AT_INITIATOR | + SAS_TASK_STATE_PENDING); + spin_unlock_irqrestore(&task->task_state_lock, flags); + } - spin_lock_irqsave(&task->task_state_lock, flags); - task->task_state_flags &= ~(SAS_TASK_AT_INITIATOR | - SAS_TASK_STATE_PENDING); - task->task_state_flags |= SAS_TASK_STATE_DONE; - spin_unlock_irqrestore(&task->task_state_lock, flags); + /* STP and SMP devices are not sent a TMF, but the + * outstanding I/O request is terminated below. This is + * because SATA/STP and SMP discovery path timeouts directly + * call the abort task interface for cleanup. + */ + perform_termination = 1; - ret = TMF_RESP_FUNC_COMPLETE; } else { /* Fill in the tmf stucture */ isci_task_build_abort_task_tmf(&tmf, isci_tmf_ssp_task_abort, + isci_abort_task_process_cb, old_request); - spin_unlock_irqrestore(&ihost->scic_lock, flags); + spin_unlock_irqrestore(&isci_host->scic_lock, flags); - /* Send the task management request. */ #define ISCI_ABORT_TASK_TIMEOUT_MS 500 /* 1/2 second timeout */ - ret = isci_task_execute_tmf(ihost, idev, &tmf, + ret = isci_task_execute_tmf(isci_host, isci_device, &tmf, ISCI_ABORT_TASK_TIMEOUT_MS); + + if (ret == TMF_RESP_FUNC_COMPLETE) + perform_termination = 1; + else + dev_dbg(&isci_host->pdev->dev, + "%s: isci_task_send_tmf failed\n", __func__); } -out: - dev_warn(&ihost->pdev->dev, - "%s: Done; dev = %p, task = %p , old_request == %p\n", - __func__, idev, task, old_request); - isci_put_device(idev); + if (perform_termination) { + set_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags); + + /* Clean up the request on our side, and wait for the aborted + * I/O to complete. + */ + isci_terminate_request_core(isci_host, isci_device, + old_request); + } + + /* Make sure we do not leave a reference to aborted_io_completion */ + old_request->io_request_completion = NULL; + out: + isci_put_device(isci_device); return ret; } @@ -703,11 +1195,14 @@ isci_task_request_complete(struct isci_host *ihost, { struct isci_tmf *tmf = isci_request_access_tmf(ireq); struct completion *tmf_complete = NULL; + struct completion *request_complete = ireq->io_request_completion; dev_dbg(&ihost->pdev->dev, "%s: request = %p, status=%d\n", __func__, ireq, completion_status); + isci_request_change_state(ireq, completed); + set_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags); if (tmf) { @@ -731,11 +1226,20 @@ isci_task_request_complete(struct isci_host *ihost, */ set_bit(IREQ_TERMINATED, &ireq->flags); - if (test_and_clear_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags)) - wake_up_all(&ihost->eventq); - - if (!test_bit(IREQ_NO_AUTO_FREE_TAG, &ireq->flags)) + /* As soon as something is in the terminate path, deallocation is + * managed there. Note that the final non-managed state of a task + * request is "completed". + */ + if ((ireq->status == completed) || + !isci_request_is_dealloc_managed(ireq->status)) { + isci_request_change_state(ireq, unallocated); isci_free_tag(ihost, ireq->io_tag); + list_del_init(&ireq->dev_node); + } + + /* "request_complete" is set if the task was being terminated. */ + if (request_complete) + complete(request_complete); /* The task management part completes last. */ if (tmf_complete) @@ -746,38 +1250,48 @@ static int isci_reset_device(struct isci_host *ihost, struct domain_device *dev, struct isci_remote_device *idev) { - int rc = TMF_RESP_FUNC_COMPLETE, reset_stat = -1; + int rc; + unsigned long flags; + enum sci_status status; struct sas_phy *phy = sas_get_local_phy(dev); struct isci_port *iport = dev->port->lldd_port; dev_dbg(&ihost->pdev->dev, "%s: idev %p\n", __func__, idev); - /* Suspend the RNC, terminate all outstanding TCs. */ - if (isci_remote_device_suspend_terminate(ihost, idev, NULL) - != SCI_SUCCESS) { + spin_lock_irqsave(&ihost->scic_lock, flags); + status = sci_remote_device_reset(idev); + spin_unlock_irqrestore(&ihost->scic_lock, flags); + + if (status != SCI_SUCCESS) { + dev_dbg(&ihost->pdev->dev, + "%s: sci_remote_device_reset(%p) returned %d!\n", + __func__, idev, status); rc = TMF_RESP_FUNC_FAILED; goto out; } - /* Note that since the termination for outstanding requests succeeded, - * this function will return success. This is because the resets will - * only fail if the device has been removed (ie. hotplug), and the - * primary duty of this function is to cleanup tasks, so that is the - * relevant status. - */ - if (!test_bit(IDEV_GONE, &idev->flags)) { - if (scsi_is_sas_phy_local(phy)) { - struct isci_phy *iphy = &ihost->phys[phy->number]; - - reset_stat = isci_port_perform_hard_reset(ihost, iport, - iphy); - } else - reset_stat = sas_phy_reset(phy, !dev_is_sata(dev)); + + if (scsi_is_sas_phy_local(phy)) { + struct isci_phy *iphy = &ihost->phys[phy->number]; + + rc = isci_port_perform_hard_reset(ihost, iport, iphy); + } else + rc = sas_phy_reset(phy, !dev_is_sata(dev)); + + /* Terminate in-progress I/O now. */ + isci_remote_device_nuke_requests(ihost, idev); + + /* Since all pending TCs have been cleaned, resume the RNC. */ + spin_lock_irqsave(&ihost->scic_lock, flags); + status = sci_remote_device_reset_complete(idev); + spin_unlock_irqrestore(&ihost->scic_lock, flags); + + if (status != SCI_SUCCESS) { + dev_dbg(&ihost->pdev->dev, + "%s: sci_remote_device_reset_complete(%p) " + "returned %d!\n", __func__, idev, status); } - /* Explicitly resume the RNC here, since there was no task sent. */ - isci_remote_device_resume_from_abort(ihost, idev); - dev_dbg(&ihost->pdev->dev, "%s: idev %p complete, reset_stat=%d.\n", - __func__, idev, reset_stat); + dev_dbg(&ihost->pdev->dev, "%s: idev %p complete.\n", __func__, idev); out: sas_put_local_phy(phy); return rc; @@ -791,7 +1305,7 @@ int isci_task_I_T_nexus_reset(struct domain_device *dev) int ret; spin_lock_irqsave(&ihost->scic_lock, flags); - idev = isci_get_device(dev->lldd_dev); + idev = isci_lookup_device(dev); spin_unlock_irqrestore(&ihost->scic_lock, flags); if (!idev) { diff --git a/trunk/drivers/scsi/isci/task.h b/trunk/drivers/scsi/isci/task.h index 9c06cbad1d26..7b6d0e32fd9b 100644 --- a/trunk/drivers/scsi/isci/task.h +++ b/trunk/drivers/scsi/isci/task.h @@ -62,6 +62,19 @@ struct isci_request; +/** + * enum isci_tmf_cb_state - This enum defines the possible states in which the + * TMF callback function is invoked during the TMF execution process. + * + * + */ +enum isci_tmf_cb_state { + + isci_tmf_init_state = 0, + isci_tmf_started, + isci_tmf_timed_out +}; + /** * enum isci_tmf_function_codes - This enum defines the possible preparations * of task management requests. @@ -74,7 +87,6 @@ enum isci_tmf_function_codes { isci_tmf_ssp_task_abort = TMF_ABORT_TASK, isci_tmf_ssp_lun_reset = TMF_LU_RESET, }; - /** * struct isci_tmf - This class represents the task management object which * acts as an interface to libsas for processing task management requests @@ -94,6 +106,15 @@ struct isci_tmf { u16 io_tag; enum isci_tmf_function_codes tmf_code; int status; + + /* The optional callback function allows the user process to + * track the TMF transmit / timeout conditions. + */ + void (*cb_state_func)( + enum isci_tmf_cb_state, + struct isci_tmf *, void *); + void *cb_data; + }; static inline void isci_print_tmf(struct isci_host *ihost, struct isci_tmf *tmf) @@ -187,4 +208,113 @@ int isci_queuecommand( struct scsi_cmnd *scsi_cmd, void (*donefunc)(struct scsi_cmnd *)); +/** + * enum isci_completion_selection - This enum defines the possible actions to + * take with respect to a given request's notification back to libsas. + * + * + */ +enum isci_completion_selection { + + isci_perform_normal_io_completion, /* Normal notify (task_done) */ + isci_perform_aborted_io_completion, /* No notification. */ + isci_perform_error_io_completion /* Use sas_task_abort */ +}; + +/** + * isci_task_set_completion_status() - This function sets the completion status + * for the request. + * @task: This parameter is the completed request. + * @response: This parameter is the response code for the completed task. + * @status: This parameter is the status code for the completed task. + * +* @return The new notification mode for the request. +*/ +static inline enum isci_completion_selection +isci_task_set_completion_status( + struct sas_task *task, + enum service_response response, + enum exec_status status, + enum isci_completion_selection task_notification_selection) +{ + unsigned long flags; + + spin_lock_irqsave(&task->task_state_lock, flags); + + /* If a device reset is being indicated, make sure the I/O + * is in the error path. + */ + if (task->task_state_flags & SAS_TASK_NEED_DEV_RESET) { + /* Fail the I/O to make sure it goes into the error path. */ + response = SAS_TASK_UNDELIVERED; + status = SAM_STAT_TASK_ABORTED; + + task_notification_selection = isci_perform_error_io_completion; + } + task->task_status.resp = response; + task->task_status.stat = status; + + switch (task->task_proto) { + + case SAS_PROTOCOL_SATA: + case SAS_PROTOCOL_STP: + case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: + + if (task_notification_selection + == isci_perform_error_io_completion) { + /* SATA/STP I/O has it's own means of scheduling device + * error handling on the normal path. + */ + task_notification_selection + = isci_perform_normal_io_completion; + } + break; + default: + break; + } + + switch (task_notification_selection) { + + case isci_perform_error_io_completion: + + if (task->task_proto == SAS_PROTOCOL_SMP) { + /* There is no error escalation in the SMP case. + * Convert to a normal completion to avoid the + * timeout in the discovery path and to let the + * next action take place quickly. + */ + task_notification_selection + = isci_perform_normal_io_completion; + + /* Fall through to the normal case... */ + } else { + /* Use sas_task_abort */ + /* Leave SAS_TASK_STATE_DONE clear + * Leave SAS_TASK_AT_INITIATOR set. + */ + break; + } + + case isci_perform_aborted_io_completion: + /* This path can occur with task-managed requests as well as + * requests terminated because of LUN or device resets. + */ + /* Fall through to the normal case... */ + case isci_perform_normal_io_completion: + /* Normal notification (task_done) */ + task->task_state_flags |= SAS_TASK_STATE_DONE; + task->task_state_flags &= ~(SAS_TASK_AT_INITIATOR | + SAS_TASK_STATE_PENDING); + break; + default: + WARN_ONCE(1, "unknown task_notification_selection: %d\n", + task_notification_selection); + break; + } + + spin_unlock_irqrestore(&task->task_state_lock, flags); + + return task_notification_selection; + +} #endif /* !defined(_SCI_TASK_H_) */ diff --git a/trunk/drivers/scsi/isci/unsolicited_frame_control.c b/trunk/drivers/scsi/isci/unsolicited_frame_control.c index 04a6d0d59a22..16f88ab939c8 100644 --- a/trunk/drivers/scsi/isci/unsolicited_frame_control.c +++ b/trunk/drivers/scsi/isci/unsolicited_frame_control.c @@ -57,19 +57,31 @@ #include "unsolicited_frame_control.h" #include "registers.h" -void sci_unsolicited_frame_control_construct(struct isci_host *ihost) +int sci_unsolicited_frame_control_construct(struct isci_host *ihost) { struct sci_unsolicited_frame_control *uf_control = &ihost->uf_control; struct sci_unsolicited_frame *uf; - dma_addr_t dma = ihost->ufi_dma; - void *virt = ihost->ufi_buf; - int i; + u32 buf_len, header_len, i; + dma_addr_t dma; + size_t size; + void *virt; + + /* + * Prepare all of the memory sizes for the UF headers, UF address + * table, and UF buffers themselves. + */ + buf_len = SCU_MAX_UNSOLICITED_FRAMES * SCU_UNSOLICITED_FRAME_BUFFER_SIZE; + header_len = SCU_MAX_UNSOLICITED_FRAMES * sizeof(struct scu_unsolicited_frame_header); + size = buf_len + header_len + SCU_MAX_UNSOLICITED_FRAMES * sizeof(uf_control->address_table.array[0]); /* * The Unsolicited Frame buffers are set at the start of the UF * memory descriptor entry. The headers and address table will be * placed after the buffers. */ + virt = dmam_alloc_coherent(&ihost->pdev->dev, size, &dma, GFP_KERNEL); + if (!virt) + return -ENOMEM; /* * Program the location of the UF header table into the SCU. @@ -81,8 +93,8 @@ void sci_unsolicited_frame_control_construct(struct isci_host *ihost) * headers, since we program the UF address table pointers to * NULL. */ - uf_control->headers.physical_address = dma + SCI_UFI_BUF_SIZE; - uf_control->headers.array = virt + SCI_UFI_BUF_SIZE; + uf_control->headers.physical_address = dma + buf_len; + uf_control->headers.array = virt + buf_len; /* * Program the location of the UF address table into the SCU. @@ -91,8 +103,8 @@ void sci_unsolicited_frame_control_construct(struct isci_host *ihost) * byte boundary already due to above programming headers being on a * 64-bit boundary and headers are on a 64-bytes in size. */ - uf_control->address_table.physical_address = dma + SCI_UFI_BUF_SIZE + SCI_UFI_HDR_SIZE; - uf_control->address_table.array = virt + SCI_UFI_BUF_SIZE + SCI_UFI_HDR_SIZE; + uf_control->address_table.physical_address = dma + buf_len + header_len; + uf_control->address_table.array = virt + buf_len + header_len; uf_control->get = 0; /* @@ -123,6 +135,8 @@ void sci_unsolicited_frame_control_construct(struct isci_host *ihost) virt += SCU_UNSOLICITED_FRAME_BUFFER_SIZE; dma += SCU_UNSOLICITED_FRAME_BUFFER_SIZE; } + + return 0; } enum sci_status sci_unsolicited_frame_control_get_header(struct sci_unsolicited_frame_control *uf_control, diff --git a/trunk/drivers/scsi/isci/unsolicited_frame_control.h b/trunk/drivers/scsi/isci/unsolicited_frame_control.h index 1bc551ec611f..75d896686f5a 100644 --- a/trunk/drivers/scsi/isci/unsolicited_frame_control.h +++ b/trunk/drivers/scsi/isci/unsolicited_frame_control.h @@ -257,13 +257,9 @@ struct sci_unsolicited_frame_control { }; -#define SCI_UFI_BUF_SIZE (SCU_MAX_UNSOLICITED_FRAMES * SCU_UNSOLICITED_FRAME_BUFFER_SIZE) -#define SCI_UFI_HDR_SIZE (SCU_MAX_UNSOLICITED_FRAMES * sizeof(struct scu_unsolicited_frame_header)) -#define SCI_UFI_TOTAL_SIZE (SCI_UFI_BUF_SIZE + SCI_UFI_HDR_SIZE + SCU_MAX_UNSOLICITED_FRAMES * sizeof(u64)) - struct isci_host; -void sci_unsolicited_frame_control_construct(struct isci_host *ihost); +int sci_unsolicited_frame_control_construct(struct isci_host *ihost); enum sci_status sci_unsolicited_frame_control_get_header( struct sci_unsolicited_frame_control *uf_control, diff --git a/trunk/drivers/scsi/libfc/fc_lport.c b/trunk/drivers/scsi/libfc/fc_lport.c index c1402fb499ab..cc83b66d45b7 100644 --- a/trunk/drivers/scsi/libfc/fc_lport.c +++ b/trunk/drivers/scsi/libfc/fc_lport.c @@ -648,7 +648,6 @@ int fc_lport_destroy(struct fc_lport *lport) lport->tt.fcp_abort_io(lport); lport->tt.disc_stop_final(lport); lport->tt.exch_mgr_reset(lport, 0, 0); - cancel_delayed_work_sync(&lport->retry_work); fc_fc4_del_lport(lport); return 0; } @@ -1565,6 +1564,7 @@ static void fc_lport_timeout(struct work_struct *work) switch (lport->state) { case LPORT_ST_DISABLED: + WARN_ON(1); break; case LPORT_ST_READY: break; diff --git a/trunk/drivers/scsi/lpfc/lpfc.h b/trunk/drivers/scsi/lpfc/lpfc.h index e5da6da20f8a..3a1ffdd6d831 100644 --- a/trunk/drivers/scsi/lpfc/lpfc.h +++ b/trunk/drivers/scsi/lpfc/lpfc.h @@ -93,9 +93,6 @@ struct lpfc_sli2_slim; /* lpfc wait event data ready flag */ #define LPFC_DATA_READY (1<<0) -/* queue dump line buffer size */ -#define LPFC_LBUF_SZ 128 - enum lpfc_polling_flags { ENABLE_FCP_RING_POLLING = 0x1, DISABLE_FCP_RING_INT = 0x2 @@ -623,7 +620,6 @@ struct lpfc_hba { #define HBA_AER_ENABLED 0x1000 /* AER enabled with HBA */ #define HBA_DEVLOSS_TMO 0x2000 /* HBA in devloss timeout */ #define HBA_RRQ_ACTIVE 0x4000 /* process the rrq active list */ -#define HBA_FCP_IOQ_FLUSH 0x8000 /* FCP I/O queues being flushed */ uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/ struct lpfc_dmabuf slim2p; diff --git a/trunk/drivers/scsi/lpfc/lpfc_bsg.c b/trunk/drivers/scsi/lpfc/lpfc_bsg.c index 253d9a857346..141e4b40bb55 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_bsg.c +++ b/trunk/drivers/scsi/lpfc/lpfc_bsg.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2009-2012 Emulex. All rights reserved. * + * Copyright (C) 2009-2011 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -599,7 +599,6 @@ lpfc_bsg_rport_els(struct fc_bsg_job *job) cmdiocbq->iocb_cmpl = lpfc_bsg_rport_els_cmp; cmdiocbq->context1 = dd_data; - cmdiocbq->context_un.ndlp = ndlp; cmdiocbq->context2 = rspiocbq; dd_data->type = TYPE_IOCB; dd_data->context_un.iocb.cmdiocbq = cmdiocbq; @@ -3979,7 +3978,6 @@ lpfc_bsg_handle_sli_cfg_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, } else if (subsys == SLI_CONFIG_SUBSYS_COMN) { switch (opcode) { case COMN_OPCODE_GET_CNTL_ADDL_ATTRIBUTES: - case COMN_OPCODE_GET_CNTL_ATTRIBUTES: lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, "3106 Handled SLI_CONFIG " "subsys_comn, opcode:x%x\n", diff --git a/trunk/drivers/scsi/lpfc/lpfc_bsg.h b/trunk/drivers/scsi/lpfc/lpfc_bsg.h index 67f7d0a160d1..edfe61fc52b1 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_bsg.h +++ b/trunk/drivers/scsi/lpfc/lpfc_bsg.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2010-2012 Emulex. All rights reserved. * + * Copyright (C) 2010 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -249,7 +249,6 @@ struct lpfc_sli_config_emb1_subsys { #define COMN_OPCODE_READ_OBJECT_LIST 0xAD #define COMN_OPCODE_DELETE_OBJECT 0xAE #define COMN_OPCODE_GET_CNTL_ADDL_ATTRIBUTES 0x79 -#define COMN_OPCODE_GET_CNTL_ATTRIBUTES 0x20 uint32_t timeout; uint32_t request_length; uint32_t word9; diff --git a/trunk/drivers/scsi/lpfc/lpfc_crtn.h b/trunk/drivers/scsi/lpfc/lpfc_crtn.h index 9b2a16f3bc79..330dd7192a7f 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_crtn.h +++ b/trunk/drivers/scsi/lpfc/lpfc_crtn.h @@ -254,7 +254,6 @@ int lpfc_sli_handle_fast_ring_event(struct lpfc_hba *, struct lpfc_sli_ring *, uint32_t); -struct lpfc_iocbq *__lpfc_sli_get_iocbq(struct lpfc_hba *); struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *); void lpfc_sli_release_iocbq(struct lpfc_hba *, struct lpfc_iocbq *); uint16_t lpfc_sli_next_iotag(struct lpfc_hba *, struct lpfc_iocbq *); @@ -461,7 +460,6 @@ int lpfc_hba_init_link_fc_topology(struct lpfc_hba *, uint32_t, uint32_t); int lpfc_issue_reg_vfi(struct lpfc_vport *); int lpfc_issue_unreg_vfi(struct lpfc_vport *); int lpfc_selective_reset(struct lpfc_hba *); -int lpfc_sli4_read_config(struct lpfc_hba *); -void lpfc_sli4_node_prep(struct lpfc_hba *); -int lpfc_sli4_xri_sgl_update(struct lpfc_hba *); -void lpfc_free_sgl_list(struct lpfc_hba *, struct list_head *); +int lpfc_sli4_read_config(struct lpfc_hba *phba); +int lpfc_scsi_buf_update(struct lpfc_hba *phba); +void lpfc_sli4_node_prep(struct lpfc_hba *phba); diff --git a/trunk/drivers/scsi/lpfc/lpfc_debugfs.c b/trunk/drivers/scsi/lpfc/lpfc_debugfs.c index 3217d63ed282..af04b0d6688d 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/trunk/drivers/scsi/lpfc/lpfc_debugfs.c @@ -4466,49 +4466,3 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport) #endif return; } - -/* - * Driver debug utility routines outside of debugfs. The debug utility - * routines implemented here is intended to be used in the instrumented - * debug driver for debugging host or port issues. - */ - -/** - * lpfc_debug_dump_all_queues - dump all the queues with a hba - * @phba: Pointer to HBA context object. - * - * This function dumps entries of all the queues asociated with the @phba. - **/ -void -lpfc_debug_dump_all_queues(struct lpfc_hba *phba) -{ - int fcp_wqidx; - - /* - * Dump Work Queues (WQs) - */ - lpfc_debug_dump_mbx_wq(phba); - lpfc_debug_dump_els_wq(phba); - - for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_wq_count; fcp_wqidx++) - lpfc_debug_dump_fcp_wq(phba, fcp_wqidx); - - lpfc_debug_dump_hdr_rq(phba); - lpfc_debug_dump_dat_rq(phba); - /* - * Dump Complete Queues (CQs) - */ - lpfc_debug_dump_mbx_cq(phba); - lpfc_debug_dump_els_cq(phba); - - for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_wq_count; fcp_wqidx++) - lpfc_debug_dump_fcp_cq(phba, fcp_wqidx); - - /* - * Dump Event Queues (EQs) - */ - lpfc_debug_dump_sp_eq(phba); - - for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_wq_count; fcp_wqidx++) - lpfc_debug_dump_fcp_eq(phba, fcp_wqidx); -} diff --git a/trunk/drivers/scsi/lpfc/lpfc_debugfs.h b/trunk/drivers/scsi/lpfc/lpfc_debugfs.h index 616c400dae14..f83bd944edd8 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_debugfs.h +++ b/trunk/drivers/scsi/lpfc/lpfc_debugfs.h @@ -267,421 +267,3 @@ struct lpfc_idiag { #define LPFC_DISC_TRC_DISCOVERY 0xef /* common mask for general * discovery */ #endif /* H_LPFC_DEBUG_FS */ - - -/* - * Driver debug utility routines outside of debugfs. The debug utility - * routines implemented here is intended to be used in the instrumented - * debug driver for debugging host or port issues. - */ - -/** - * lpfc_debug_dump_qe - dump an specific entry from a queue - * @q: Pointer to the queue descriptor. - * @idx: Index to the entry on the queue. - * - * This function dumps an entry indexed by @idx from a queue specified by the - * queue descriptor @q. - **/ -static inline void -lpfc_debug_dump_qe(struct lpfc_queue *q, uint32_t idx) -{ - char line_buf[LPFC_LBUF_SZ]; - int i, esize, qe_word_cnt, len; - uint32_t *pword; - - /* sanity checks */ - if (!q) - return; - if (idx >= q->entry_count) - return; - - esize = q->entry_size; - qe_word_cnt = esize / sizeof(uint32_t); - pword = q->qe[idx].address; - - len = 0; - len += snprintf(line_buf+len, LPFC_LBUF_SZ-len, "QE[%04d]: ", idx); - if (qe_word_cnt > 8) - printk(KERN_ERR "%s\n", line_buf); - - for (i = 0; i < qe_word_cnt; i++) { - if (!(i % 8)) { - if (i != 0) - printk(KERN_ERR "%s\n", line_buf); - if (qe_word_cnt > 8) { - len = 0; - memset(line_buf, 0, LPFC_LBUF_SZ); - len += snprintf(line_buf+len, LPFC_LBUF_SZ-len, - "%03d: ", i); - } - } - len += snprintf(line_buf+len, LPFC_LBUF_SZ-len, "%08x ", - ((uint32_t)*pword) & 0xffffffff); - pword++; - } - if (qe_word_cnt <= 8 || (i - 1) % 8) - printk(KERN_ERR "%s\n", line_buf); -} - -/** - * lpfc_debug_dump_q - dump all entries from an specific queue - * @q: Pointer to the queue descriptor. - * - * This function dumps all entries from a queue specified by the queue - * descriptor @q. - **/ -static inline void -lpfc_debug_dump_q(struct lpfc_queue *q) -{ - int idx, entry_count; - - /* sanity check */ - if (!q) - return; - - dev_printk(KERN_ERR, &(((q->phba))->pcidev)->dev, - "%d: [qid:%d, type:%d, subtype:%d, " - "qe_size:%d, qe_count:%d, " - "host_index:%d, port_index:%d]\n", - (q->phba)->brd_no, - q->queue_id, q->type, q->subtype, - q->entry_size, q->entry_count, - q->host_index, q->hba_index); - entry_count = q->entry_count; - for (idx = 0; idx < entry_count; idx++) - lpfc_debug_dump_qe(q, idx); - printk(KERN_ERR "\n"); -} - -/** - * lpfc_debug_dump_fcp_wq - dump all entries from a fcp work queue - * @phba: Pointer to HBA context object. - * @fcp_wqidx: Index to a FCP work queue. - * - * This function dumps all entries from a FCP work queue specified by the - * @fcp_wqidx. - **/ -static inline void -lpfc_debug_dump_fcp_wq(struct lpfc_hba *phba, int fcp_wqidx) -{ - /* sanity check */ - if (fcp_wqidx >= phba->cfg_fcp_wq_count) - return; - - printk(KERN_ERR "FCP WQ: WQ[Idx:%d|Qid:%d]\n", - fcp_wqidx, phba->sli4_hba.fcp_wq[fcp_wqidx]->queue_id); - lpfc_debug_dump_q(phba->sli4_hba.fcp_wq[fcp_wqidx]); -} - -/** - * lpfc_debug_dump_fcp_cq - dump all entries from a fcp work queue's cmpl queue - * @phba: Pointer to HBA context object. - * @fcp_wqidx: Index to a FCP work queue. - * - * This function dumps all entries from a FCP complete queue which is - * associated to the FCP work queue specified by the @fcp_wqidx. - **/ -static inline void -lpfc_debug_dump_fcp_cq(struct lpfc_hba *phba, int fcp_wqidx) -{ - int fcp_cqidx, fcp_cqid; - - /* sanity check */ - if (fcp_wqidx >= phba->cfg_fcp_wq_count) - return; - - fcp_cqid = phba->sli4_hba.fcp_wq[fcp_wqidx]->assoc_qid; - for (fcp_cqidx = 0; fcp_cqidx < phba->cfg_fcp_eq_count; fcp_cqidx++) - if (phba->sli4_hba.fcp_cq[fcp_cqidx]->queue_id == fcp_cqid) - break; - if (fcp_cqidx >= phba->cfg_fcp_eq_count) - return; - - printk(KERN_ERR "FCP CQ: WQ[Idx:%d|Qid%d]->CQ[Idx%d|Qid%d]:\n", - fcp_wqidx, phba->sli4_hba.fcp_wq[fcp_wqidx]->queue_id, - fcp_cqidx, fcp_cqid); - lpfc_debug_dump_q(phba->sli4_hba.fcp_cq[fcp_cqidx]); -} - -/** - * lpfc_debug_dump_fcp_eq - dump all entries from a fcp work queue's evt queue - * @phba: Pointer to HBA context object. - * @fcp_wqidx: Index to a FCP work queue. - * - * This function dumps all entries from a FCP event queue which is - * associated to the FCP work queue specified by the @fcp_wqidx. - **/ -static inline void -lpfc_debug_dump_fcp_eq(struct lpfc_hba *phba, int fcp_wqidx) -{ - struct lpfc_queue *qdesc; - int fcp_eqidx, fcp_eqid; - int fcp_cqidx, fcp_cqid; - - /* sanity check */ - if (fcp_wqidx >= phba->cfg_fcp_wq_count) - return; - fcp_cqid = phba->sli4_hba.fcp_wq[fcp_wqidx]->assoc_qid; - for (fcp_cqidx = 0; fcp_cqidx < phba->cfg_fcp_eq_count; fcp_cqidx++) - if (phba->sli4_hba.fcp_cq[fcp_cqidx]->queue_id == fcp_cqid) - break; - if (fcp_cqidx >= phba->cfg_fcp_eq_count) - return; - - if (phba->cfg_fcp_eq_count == 0) { - fcp_eqidx = -1; - fcp_eqid = phba->sli4_hba.sp_eq->queue_id; - qdesc = phba->sli4_hba.sp_eq; - } else { - fcp_eqidx = fcp_cqidx; - fcp_eqid = phba->sli4_hba.fp_eq[fcp_eqidx]->queue_id; - qdesc = phba->sli4_hba.fp_eq[fcp_eqidx]; - } - - printk(KERN_ERR "FCP EQ: WQ[Idx:%d|Qid:%d]->CQ[Idx:%d|Qid:%d]->" - "EQ[Idx:%d|Qid:%d]\n", - fcp_wqidx, phba->sli4_hba.fcp_wq[fcp_wqidx]->queue_id, - fcp_cqidx, fcp_cqid, fcp_eqidx, fcp_eqid); - lpfc_debug_dump_q(qdesc); -} - -/** - * lpfc_debug_dump_els_wq - dump all entries from the els work queue - * @phba: Pointer to HBA context object. - * - * This function dumps all entries from the ELS work queue. - **/ -static inline void -lpfc_debug_dump_els_wq(struct lpfc_hba *phba) -{ - printk(KERN_ERR "ELS WQ: WQ[Qid:%d]:\n", - phba->sli4_hba.els_wq->queue_id); - lpfc_debug_dump_q(phba->sli4_hba.els_wq); -} - -/** - * lpfc_debug_dump_mbx_wq - dump all entries from the mbox work queue - * @phba: Pointer to HBA context object. - * - * This function dumps all entries from the MBOX work queue. - **/ -static inline void -lpfc_debug_dump_mbx_wq(struct lpfc_hba *phba) -{ - printk(KERN_ERR "MBX WQ: WQ[Qid:%d]\n", - phba->sli4_hba.mbx_wq->queue_id); - lpfc_debug_dump_q(phba->sli4_hba.mbx_wq); -} - -/** - * lpfc_debug_dump_dat_rq - dump all entries from the receive data queue - * @phba: Pointer to HBA context object. - * - * This function dumps all entries from the receive data queue. - **/ -static inline void -lpfc_debug_dump_dat_rq(struct lpfc_hba *phba) -{ - printk(KERN_ERR "DAT RQ: RQ[Qid:%d]\n", - phba->sli4_hba.dat_rq->queue_id); - lpfc_debug_dump_q(phba->sli4_hba.dat_rq); -} - -/** - * lpfc_debug_dump_hdr_rq - dump all entries from the receive header queue - * @phba: Pointer to HBA context object. - * - * This function dumps all entries from the receive header queue. - **/ -static inline void -lpfc_debug_dump_hdr_rq(struct lpfc_hba *phba) -{ - printk(KERN_ERR "HDR RQ: RQ[Qid:%d]\n", - phba->sli4_hba.hdr_rq->queue_id); - lpfc_debug_dump_q(phba->sli4_hba.hdr_rq); -} - -/** - * lpfc_debug_dump_els_cq - dump all entries from the els complete queue - * @phba: Pointer to HBA context object. - * - * This function dumps all entries from the els complete queue. - **/ -static inline void -lpfc_debug_dump_els_cq(struct lpfc_hba *phba) -{ - printk(KERN_ERR "ELS CQ: WQ[Qid:%d]->CQ[Qid:%d]\n", - phba->sli4_hba.els_wq->queue_id, - phba->sli4_hba.els_cq->queue_id); - lpfc_debug_dump_q(phba->sli4_hba.els_cq); -} - -/** - * lpfc_debug_dump_mbx_cq - dump all entries from the mbox complete queue - * @phba: Pointer to HBA context object. - * - * This function dumps all entries from the mbox complete queue. - **/ -static inline void -lpfc_debug_dump_mbx_cq(struct lpfc_hba *phba) -{ - printk(KERN_ERR "MBX CQ: WQ[Qid:%d]->CQ[Qid:%d]\n", - phba->sli4_hba.mbx_wq->queue_id, - phba->sli4_hba.mbx_cq->queue_id); - lpfc_debug_dump_q(phba->sli4_hba.mbx_cq); -} - -/** - * lpfc_debug_dump_sp_eq - dump all entries from slow-path event queue - * @phba: Pointer to HBA context object. - * - * This function dumps all entries from the slow-path event queue. - **/ -static inline void -lpfc_debug_dump_sp_eq(struct lpfc_hba *phba) -{ - printk(KERN_ERR "SP EQ: WQ[Qid:%d/Qid:%d]->CQ[Qid:%d/Qid:%d]->" - "EQ[Qid:%d]:\n", - phba->sli4_hba.mbx_wq->queue_id, - phba->sli4_hba.els_wq->queue_id, - phba->sli4_hba.mbx_cq->queue_id, - phba->sli4_hba.els_cq->queue_id, - phba->sli4_hba.sp_eq->queue_id); - lpfc_debug_dump_q(phba->sli4_hba.sp_eq); -} - -/** - * lpfc_debug_dump_wq_by_id - dump all entries from a work queue by queue id - * @phba: Pointer to HBA context object. - * @qid: Work queue identifier. - * - * This function dumps all entries from a work queue identified by the queue - * identifier. - **/ -static inline void -lpfc_debug_dump_wq_by_id(struct lpfc_hba *phba, int qid) -{ - int wq_idx; - - for (wq_idx = 0; wq_idx < phba->cfg_fcp_wq_count; wq_idx++) - if (phba->sli4_hba.fcp_wq[wq_idx]->queue_id == qid) - break; - if (wq_idx < phba->cfg_fcp_wq_count) { - printk(KERN_ERR "FCP WQ[Idx:%d|Qid:%d]\n", wq_idx, qid); - lpfc_debug_dump_q(phba->sli4_hba.fcp_wq[wq_idx]); - return; - } - - if (phba->sli4_hba.els_wq->queue_id == qid) { - printk(KERN_ERR "ELS WQ[Qid:%d]\n", qid); - lpfc_debug_dump_q(phba->sli4_hba.els_wq); - } -} - -/** - * lpfc_debug_dump_mq_by_id - dump all entries from a mbox queue by queue id - * @phba: Pointer to HBA context object. - * @qid: Mbox work queue identifier. - * - * This function dumps all entries from a mbox work queue identified by the - * queue identifier. - **/ -static inline void -lpfc_debug_dump_mq_by_id(struct lpfc_hba *phba, int qid) -{ - if (phba->sli4_hba.mbx_wq->queue_id == qid) { - printk(KERN_ERR "MBX WQ[Qid:%d]\n", qid); - lpfc_debug_dump_q(phba->sli4_hba.mbx_wq); - } -} - -/** - * lpfc_debug_dump_rq_by_id - dump all entries from a receive queue by queue id - * @phba: Pointer to HBA context object. - * @qid: Receive queue identifier. - * - * This function dumps all entries from a receive queue identified by the - * queue identifier. - **/ -static inline void -lpfc_debug_dump_rq_by_id(struct lpfc_hba *phba, int qid) -{ - if (phba->sli4_hba.hdr_rq->queue_id == qid) { - printk(KERN_ERR "HDR RQ[Qid:%d]\n", qid); - lpfc_debug_dump_q(phba->sli4_hba.hdr_rq); - return; - } - if (phba->sli4_hba.dat_rq->queue_id == qid) { - printk(KERN_ERR "DAT RQ[Qid:%d]\n", qid); - lpfc_debug_dump_q(phba->sli4_hba.dat_rq); - } -} - -/** - * lpfc_debug_dump_cq_by_id - dump all entries from a cmpl queue by queue id - * @phba: Pointer to HBA context object. - * @qid: Complete queue identifier. - * - * This function dumps all entries from a complete queue identified by the - * queue identifier. - **/ -static inline void -lpfc_debug_dump_cq_by_id(struct lpfc_hba *phba, int qid) -{ - int cq_idx = 0; - - do { - if (phba->sli4_hba.fcp_cq[cq_idx]->queue_id == qid) - break; - } while (++cq_idx < phba->cfg_fcp_eq_count); - - if (cq_idx < phba->cfg_fcp_eq_count) { - printk(KERN_ERR "FCP CQ[Idx:%d|Qid:%d]\n", cq_idx, qid); - lpfc_debug_dump_q(phba->sli4_hba.fcp_cq[cq_idx]); - return; - } - - if (phba->sli4_hba.els_cq->queue_id == qid) { - printk(KERN_ERR "ELS CQ[Qid:%d]\n", qid); - lpfc_debug_dump_q(phba->sli4_hba.els_cq); - return; - } - - if (phba->sli4_hba.mbx_cq->queue_id == qid) { - printk(KERN_ERR "MBX CQ[Qid:%d]\n", qid); - lpfc_debug_dump_q(phba->sli4_hba.mbx_cq); - } -} - -/** - * lpfc_debug_dump_eq_by_id - dump all entries from an event queue by queue id - * @phba: Pointer to HBA context object. - * @qid: Complete queue identifier. - * - * This function dumps all entries from an event queue identified by the - * queue identifier. - **/ -static inline void -lpfc_debug_dump_eq_by_id(struct lpfc_hba *phba, int qid) -{ - int eq_idx; - - for (eq_idx = 0; eq_idx < phba->cfg_fcp_eq_count; eq_idx++) { - if (phba->sli4_hba.fp_eq[eq_idx]->queue_id == qid) - break; - } - - if (eq_idx < phba->cfg_fcp_eq_count) { - printk(KERN_ERR "FCP EQ[Idx:%d|Qid:%d]\n", eq_idx, qid); - lpfc_debug_dump_q(phba->sli4_hba.fp_eq[eq_idx]); - return; - } - - if (phba->sli4_hba.sp_eq->queue_id == qid) { - printk(KERN_ERR "SP EQ[|Qid:%d]\n", qid); - lpfc_debug_dump_q(phba->sli4_hba.sp_eq); - } -} - -void lpfc_debug_dump_all_queues(struct lpfc_hba *); diff --git a/trunk/drivers/scsi/lpfc/lpfc_els.c b/trunk/drivers/scsi/lpfc/lpfc_els.c index d54ae1999797..3407b39e0a3f 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_els.c +++ b/trunk/drivers/scsi/lpfc/lpfc_els.c @@ -230,43 +230,27 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, INIT_LIST_HEAD(&pbuflist->list); + icmd->un.elsreq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys); + icmd->un.elsreq64.bdl.addrLow = putPaddrLow(pbuflist->phys); + icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64; + icmd->un.elsreq64.remoteID = did; /* DID */ if (expectRsp) { - icmd->un.elsreq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys); - icmd->un.elsreq64.bdl.addrLow = putPaddrLow(pbuflist->phys); - icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64; icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof(struct ulp_bde64)); - - icmd->un.elsreq64.remoteID = did; /* DID */ icmd->ulpCommand = CMD_ELS_REQUEST64_CR; icmd->ulpTimeout = phba->fc_ratov * 2; } else { - icmd->un.xseq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys); - icmd->un.xseq64.bdl.addrLow = putPaddrLow(pbuflist->phys); - icmd->un.xseq64.bdl.bdeFlags = BUFF_TYPE_BLP_64; - icmd->un.xseq64.bdl.bdeSize = sizeof(struct ulp_bde64); - icmd->un.xseq64.xmit_els_remoteID = did; /* DID */ + icmd->un.elsreq64.bdl.bdeSize = sizeof(struct ulp_bde64); icmd->ulpCommand = CMD_XMIT_ELS_RSP64_CX; } icmd->ulpBdeCount = 1; icmd->ulpLe = 1; icmd->ulpClass = CLASS3; - /* - * If we have NPIV enabled, we want to send ELS traffic by VPI. - * For SLI4, since the driver controls VPIs we also want to include - * all ELS pt2pt protocol traffic as well. - */ - if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) || - ((phba->sli_rev == LPFC_SLI_REV4) && - (vport->fc_flag & FC_PT2PT))) { - - if (expectRsp) { - icmd->un.elsreq64.myID = vport->fc_myDID; - - /* For ELS_REQUEST64_CR, use the VPI by default */ - icmd->ulpContext = phba->vpi_ids[vport->vpi]; - } + if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { + icmd->un.elsreq64.myID = vport->fc_myDID; + /* For ELS_REQUEST64_CR, use the VPI by default */ + icmd->ulpContext = phba->vpi_ids[vport->vpi]; icmd->ulpCt_h = 0; /* The CT field must be 0=INVALID_RPI for the ECHO cmd */ if (elscmd == ELS_CMD_ECHO) @@ -454,10 +438,9 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport) int rc = 0; sp = &phba->fc_fabparam; - /* move forward in case of SLI4 FC port loopback test and pt2pt mode */ + /* move forward in case of SLI4 FC port loopback test */ if ((phba->sli_rev == LPFC_SLI_REV4) && - !(phba->link_flag & LS_LOOPBACK_MODE) && - !(vport->fc_flag & FC_PT2PT)) { + !(phba->link_flag & LS_LOOPBACK_MODE)) { ndlp = lpfc_findnode_did(vport, Fabric_DID); if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { rc = -ENODEV; @@ -724,17 +707,14 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, lpfc_sli4_unreg_all_rpis(vport); lpfc_mbx_unreg_vpi(vport); spin_lock_irq(shost->host_lock); + vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; + /* + * If VPI is unreged, driver need to do INIT_VPI + * before re-registering + */ vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; spin_unlock_irq(shost->host_lock); } - - /* - * For SLI3 and SLI4, the VPI needs to be reregistered in - * response to this fabric parameter change event. - */ - spin_lock_irq(shost->host_lock); - vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; - spin_unlock_irq(shost->host_lock); } else if ((phba->sli_rev == LPFC_SLI_REV4) && !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) { /* @@ -837,17 +817,6 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, mempool_free(mbox, phba->mbox_mem_pool); goto fail; } - - /* - * For SLI4, the VFI/VPI are registered AFTER the - * Nport with the higher WWPN sends the PLOGI with - * an assigned NPortId. - */ - - /* not equal */ - if ((phba->sli_rev == LPFC_SLI_REV4) && rc) - lpfc_issue_reg_vfi(vport); - /* Decrement ndlp reference count indicating that ndlp can be * safely released when other references to it are done. */ @@ -3003,7 +2972,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, * ABTS we cannot generate and RRQ. */ lpfc_set_rrq_active(phba, ndlp, - cmdiocb->sli4_lxritag, 0, 0); + cmdiocb->sli4_xritag, 0, 0); } break; case IOSTAT_LOCAL_REJECT: @@ -3834,11 +3803,10 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, /* Xmit ELS ACC response tag */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "0128 Xmit ELS ACC response tag x%x, XRI: x%x, " - "DID: x%x, nlp_flag: x%x nlp_state: x%x RPI: x%x " - "fc_flag x%x\n", + "DID: x%x, nlp_flag: x%x nlp_state: x%x RPI: x%x\n", elsiocb->iotag, elsiocb->iocb.ulpContext, ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, - ndlp->nlp_rpi, vport->fc_flag); + ndlp->nlp_rpi); if (ndlp->nlp_flag & NLP_LOGO_ACC) { spin_lock_irq(shost->host_lock); ndlp->nlp_flag &= ~NLP_LOGO_ACC; @@ -4968,6 +4936,8 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, return 1; } + did = Fabric_DID; + if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 1))) { /* For a FLOGI we accept, then if our portname is greater * then the remote portname we initiate Nport login. @@ -5006,82 +4976,26 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, spin_lock_irq(shost->host_lock); vport->fc_flag |= FC_PT2PT_PLOGI; spin_unlock_irq(shost->host_lock); - - /* If we have the high WWPN we can assign our own - * myDID; otherwise, we have to WAIT for a PLOGI - * from the remote NPort to find out what it - * will be. - */ - vport->fc_myDID = PT2PT_LocalID; } - - /* - * The vport state should go to LPFC_FLOGI only - * AFTER we issue a FLOGI, not receive one. - */ spin_lock_irq(shost->host_lock); vport->fc_flag |= FC_PT2PT; vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); spin_unlock_irq(shost->host_lock); - - /* - * We temporarily set fc_myDID to make it look like we are - * a Fabric. This is done just so we end up with the right - * did / sid on the FLOGI ACC rsp. - */ - did = vport->fc_myDID; - vport->fc_myDID = Fabric_DID; - } else { /* Reject this request because invalid parameters */ stat.un.b.lsRjtRsvd0 = 0; stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; stat.un.b.vendorUnique = 0; - - /* - * We temporarily set fc_myDID to make it look like we are - * a Fabric. This is done just so we end up with the right - * did / sid on the FLOGI LS_RJT rsp. - */ - did = vport->fc_myDID; - vport->fc_myDID = Fabric_DID; - lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL); - - /* Now lets put fc_myDID back to what its supposed to be */ - vport->fc_myDID = did; - return 1; } /* Send back ACC */ lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL); - /* Now lets put fc_myDID back to what its supposed to be */ - vport->fc_myDID = did; - - if (!(vport->fc_flag & FC_PT2PT_PLOGI)) { - - mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - if (!mbox) - goto fail; - - lpfc_config_link(phba, mbox); - - mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - mbox->vport = vport; - rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); - if (rc == MBX_NOT_FINISHED) { - mempool_free(mbox, phba->mbox_mem_pool); - goto fail; - } - } - return 0; -fail: - return 1; } /** @@ -5262,6 +5176,7 @@ lpfc_els_rsp_rls_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) } cmdsize = sizeof(struct RLS_RSP) + sizeof(uint32_t); + mempool_free(pmb, phba->mbox_mem_pool); elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize, lpfc_max_els_tries, ndlp, ndlp->nlp_DID, ELS_CMD_ACC); @@ -5269,10 +5184,8 @@ lpfc_els_rsp_rls_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) /* Decrement the ndlp reference count from previous mbox command */ lpfc_nlp_put(ndlp); - if (!elsiocb) { - mempool_free(pmb, phba->mbox_mem_pool); + if (!elsiocb) return; - } icmd = &elsiocb->iocb; icmd->ulpContext = rxid; @@ -5289,7 +5202,7 @@ lpfc_els_rsp_rls_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) rls_rsp->primSeqErrCnt = cpu_to_be32(mb->un.varRdLnk.primSeqErrCnt); rls_rsp->invalidXmitWord = cpu_to_be32(mb->un.varRdLnk.invalidXmitWord); rls_rsp->crcCnt = cpu_to_be32(mb->un.varRdLnk.crcCnt); - mempool_free(pmb, phba->mbox_mem_pool); + /* Xmit ELS RLS ACC response tag */ lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS, "2874 Xmit ELS RLS ACC response tag x%x xri x%x, " @@ -5673,7 +5586,7 @@ lpfc_issue_els_rrq(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, pcmd += sizeof(uint32_t); els_rrq = (struct RRQ *) pcmd; - bf_set(rrq_oxid, els_rrq, phba->sli4_hba.xri_ids[rrq->xritag]); + bf_set(rrq_oxid, els_rrq, rrq->xritag); bf_set(rrq_rxid, els_rrq, rrq->rxid); bf_set(rrq_did, els_rrq, vport->fc_myDID); els_rrq->rrq = cpu_to_be32(els_rrq->rrq); @@ -7960,9 +7873,7 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba, sglq_entry->state = SGL_FREED; spin_unlock(&phba->sli4_hba.abts_sgl_list_lock); spin_unlock_irqrestore(&phba->hbalock, iflag); - lpfc_set_rrq_active(phba, ndlp, - sglq_entry->sli4_lxritag, - rxid, 1); + lpfc_set_rrq_active(phba, ndlp, xri, rxid, 1); /* Check if TXQ queue needs to be serviced */ if (pring->txq_cnt) diff --git a/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c b/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c index 5bb269e224f6..b507536dc5b5 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -713,7 +713,6 @@ lpfc_do_work(void *p) int rc; set_user_nice(current, -20); - current->flags |= PF_NOFREEZE; phba->data_flags = 0; while (!kthread_should_stop()) { @@ -1095,7 +1094,7 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) /* Start discovery by sending a FLOGI. port_state is identically * LPFC_FLOGI while waiting for FLOGI cmpl */ - if (vport->port_state != LPFC_FLOGI || vport->fc_flag & FC_PT2PT_PLOGI) + if (vport->port_state != LPFC_FLOGI) lpfc_initial_flogi(vport); return; @@ -2882,14 +2881,9 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) } if (vport->port_state == LPFC_FABRIC_CFG_LINK) { - /* - * For private loop or for NPort pt2pt, - * just start discovery and we are done. - */ - if ((vport->fc_flag & FC_PT2PT) || - ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) && - !(vport->fc_flag & FC_PUBLIC_LOOP))) { - + /* For private loop just start discovery and we are done. */ + if ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) && + !(vport->fc_flag & FC_PUBLIC_LOOP)) { /* Use loop map to make discovery list */ lpfc_disc_list_loopmap(vport); /* Start discovery */ @@ -5496,9 +5490,9 @@ lpfc_nlp_release(struct kref *kref) ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type); lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, - "0279 lpfc_nlp_release: ndlp:x%p did %x " + "0279 lpfc_nlp_release: ndlp:x%p " "usgmap:x%x refcnt:%d\n", - (void *)ndlp, ndlp->nlp_DID, ndlp->nlp_usg_map, + (void *)ndlp, ndlp->nlp_usg_map, atomic_read(&ndlp->kref.refcount)); /* remove ndlp from action. */ diff --git a/trunk/drivers/scsi/lpfc/lpfc_hw.h b/trunk/drivers/scsi/lpfc/lpfc_hw.h index 41bb1d2fb625..5f280b5ae3db 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_hw.h +++ b/trunk/drivers/scsi/lpfc/lpfc_hw.h @@ -3374,9 +3374,6 @@ typedef struct { WORD5 w5; /* Header control/status word */ } XMT_SEQ_FIELDS64; -/* This word is remote ports D_ID for XMIT_ELS_RSP64 */ -#define xmit_els_remoteID xrsqRo - /* IOCB Command template for 64 bit RCV_SEQUENCE64 */ typedef struct { struct ulp_bde64 rcvBde; diff --git a/trunk/drivers/scsi/lpfc/lpfc_hw4.h b/trunk/drivers/scsi/lpfc/lpfc_hw4.h index f1946dfda5b4..91f09761bd32 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_hw4.h +++ b/trunk/drivers/scsi/lpfc/lpfc_hw4.h @@ -228,15 +228,19 @@ struct lpfc_sli4_flags { #define lpfc_idx_rsrc_rdy_MASK 0x00000001 #define lpfc_idx_rsrc_rdy_WORD word0 #define LPFC_IDX_RSRC_RDY 1 -#define lpfc_rpi_rsrc_rdy_SHIFT 1 +#define lpfc_xri_rsrc_rdy_SHIFT 1 +#define lpfc_xri_rsrc_rdy_MASK 0x00000001 +#define lpfc_xri_rsrc_rdy_WORD word0 +#define LPFC_XRI_RSRC_RDY 1 +#define lpfc_rpi_rsrc_rdy_SHIFT 2 #define lpfc_rpi_rsrc_rdy_MASK 0x00000001 #define lpfc_rpi_rsrc_rdy_WORD word0 #define LPFC_RPI_RSRC_RDY 1 -#define lpfc_vpi_rsrc_rdy_SHIFT 2 +#define lpfc_vpi_rsrc_rdy_SHIFT 3 #define lpfc_vpi_rsrc_rdy_MASK 0x00000001 #define lpfc_vpi_rsrc_rdy_WORD word0 #define LPFC_VPI_RSRC_RDY 1 -#define lpfc_vfi_rsrc_rdy_SHIFT 3 +#define lpfc_vfi_rsrc_rdy_SHIFT 4 #define lpfc_vfi_rsrc_rdy_MASK 0x00000001 #define lpfc_vfi_rsrc_rdy_WORD word0 #define LPFC_VFI_RSRC_RDY 1 @@ -3295,13 +3299,7 @@ struct els_request64_wqe { struct xmit_els_rsp64_wqe { struct ulp_bde64 bde; uint32_t response_payload_len; - uint32_t word4; -#define els_rsp64_sid_SHIFT 0 -#define els_rsp64_sid_MASK 0x00FFFFFF -#define els_rsp64_sid_WORD word4 -#define els_rsp64_sp_SHIFT 24 -#define els_rsp64_sp_MASK 0x00000001 -#define els_rsp64_sp_WORD word4 + uint32_t rsvd4; struct wqe_did wqe_dest; struct wqe_common wqe_com; /* words 6-11 */ uint32_t word12; diff --git a/trunk/drivers/scsi/lpfc/lpfc_init.c b/trunk/drivers/scsi/lpfc/lpfc_init.c index 411ed48d79da..9598fdcb08ab 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_init.c +++ b/trunk/drivers/scsi/lpfc/lpfc_init.c @@ -64,8 +64,8 @@ static int lpfc_sli4_queue_verify(struct lpfc_hba *); static int lpfc_create_bootstrap_mbox(struct lpfc_hba *); static int lpfc_setup_endian_order(struct lpfc_hba *); static void lpfc_destroy_bootstrap_mbox(struct lpfc_hba *); -static void lpfc_free_els_sgl_list(struct lpfc_hba *); -static void lpfc_init_sgl_list(struct lpfc_hba *); +static void lpfc_free_sgl_list(struct lpfc_hba *); +static int lpfc_init_sgl_list(struct lpfc_hba *); static int lpfc_init_active_sgl_array(struct lpfc_hba *); static void lpfc_free_active_sgl(struct lpfc_hba *); static int lpfc_hba_down_post_s3(struct lpfc_hba *phba); @@ -2766,6 +2766,36 @@ lpfc_offline(struct lpfc_hba *phba) lpfc_destroy_vport_work_array(phba, vports); } +/** + * lpfc_scsi_buf_update - Update the scsi_buffers that are already allocated. + * @phba: pointer to lpfc hba data structure. + * + * This routine goes through all the scsi buffers in the system and updates the + * Physical XRIs assigned to the SCSI buffer because these may change after any + * firmware reset + * + * Return codes + * 0 - successful (for now, it always returns 0) + **/ +int +lpfc_scsi_buf_update(struct lpfc_hba *phba) +{ + struct lpfc_scsi_buf *sb, *sb_next; + + spin_lock_irq(&phba->hbalock); + spin_lock(&phba->scsi_buf_list_lock); + list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list, list) { + sb->cur_iocbq.sli4_xritag = + phba->sli4_hba.xri_ids[sb->cur_iocbq.sli4_lxritag]; + set_bit(sb->cur_iocbq.sli4_lxritag, phba->sli4_hba.xri_bmask); + phba->sli4_hba.max_cfg_param.xri_used++; + phba->sli4_hba.xri_count++; + } + spin_unlock(&phba->scsi_buf_list_lock); + spin_unlock_irq(&phba->hbalock); + return 0; +} + /** * lpfc_scsi_free - Free all the SCSI buffers and IOCBs from driver lists * @phba: pointer to lpfc hba data structure. @@ -2773,8 +2803,11 @@ lpfc_offline(struct lpfc_hba *phba) * This routine is to free all the SCSI buffers and IOCBs from the driver * list back to kernel. It is called from lpfc_pci_remove_one to free * the internal resources before the device is removed from the system. + * + * Return codes + * 0 - successful (for now, it always returns 0) **/ -static void +static int lpfc_scsi_free(struct lpfc_hba *phba) { struct lpfc_scsi_buf *sb, *sb_next; @@ -2800,178 +2833,7 @@ lpfc_scsi_free(struct lpfc_hba *phba) } spin_unlock_irq(&phba->hbalock); -} - -/** - * lpfc_sli4_xri_sgl_update - update xri-sgl sizing and mapping - * @phba: pointer to lpfc hba data structure. - * - * This routine first calculates the sizes of the current els and allocated - * scsi sgl lists, and then goes through all sgls to updates the physical - * XRIs assigned due to port function reset. During port initialization, the - * current els and allocated scsi sgl lists are 0s. - * - * Return codes - * 0 - successful (for now, it always returns 0) - **/ -int -lpfc_sli4_xri_sgl_update(struct lpfc_hba *phba) -{ - struct lpfc_sglq *sglq_entry = NULL, *sglq_entry_next = NULL; - struct lpfc_scsi_buf *psb = NULL, *psb_next = NULL; - uint16_t i, lxri, xri_cnt, els_xri_cnt, scsi_xri_cnt; - LIST_HEAD(els_sgl_list); - LIST_HEAD(scsi_sgl_list); - int rc; - - /* - * update on pci function's els xri-sgl list - */ - els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba); - if (els_xri_cnt > phba->sli4_hba.els_xri_cnt) { - /* els xri-sgl expanded */ - xri_cnt = els_xri_cnt - phba->sli4_hba.els_xri_cnt; - lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "3157 ELS xri-sgl count increased from " - "%d to %d\n", phba->sli4_hba.els_xri_cnt, - els_xri_cnt); - /* allocate the additional els sgls */ - for (i = 0; i < xri_cnt; i++) { - sglq_entry = kzalloc(sizeof(struct lpfc_sglq), - GFP_KERNEL); - if (sglq_entry == NULL) { - lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "2562 Failure to allocate an " - "ELS sgl entry:%d\n", i); - rc = -ENOMEM; - goto out_free_mem; - } - sglq_entry->buff_type = GEN_BUFF_TYPE; - sglq_entry->virt = lpfc_mbuf_alloc(phba, 0, - &sglq_entry->phys); - if (sglq_entry->virt == NULL) { - kfree(sglq_entry); - lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "2563 Failure to allocate an " - "ELS mbuf:%d\n", i); - rc = -ENOMEM; - goto out_free_mem; - } - sglq_entry->sgl = sglq_entry->virt; - memset(sglq_entry->sgl, 0, LPFC_BPL_SIZE); - sglq_entry->state = SGL_FREED; - list_add_tail(&sglq_entry->list, &els_sgl_list); - } - spin_lock(&phba->hbalock); - list_splice_init(&els_sgl_list, &phba->sli4_hba.lpfc_sgl_list); - spin_unlock(&phba->hbalock); - } else if (els_xri_cnt < phba->sli4_hba.els_xri_cnt) { - /* els xri-sgl shrinked */ - xri_cnt = phba->sli4_hba.els_xri_cnt - els_xri_cnt; - lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "3158 ELS xri-sgl count decreased from " - "%d to %d\n", phba->sli4_hba.els_xri_cnt, - els_xri_cnt); - spin_lock_irq(&phba->hbalock); - list_splice_init(&phba->sli4_hba.lpfc_sgl_list, &els_sgl_list); - spin_unlock_irq(&phba->hbalock); - /* release extra els sgls from list */ - for (i = 0; i < xri_cnt; i++) { - list_remove_head(&els_sgl_list, - sglq_entry, struct lpfc_sglq, list); - if (sglq_entry) { - lpfc_mbuf_free(phba, sglq_entry->virt, - sglq_entry->phys); - kfree(sglq_entry); - } - } - spin_lock_irq(&phba->hbalock); - list_splice_init(&els_sgl_list, &phba->sli4_hba.lpfc_sgl_list); - spin_unlock_irq(&phba->hbalock); - } else - lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "3163 ELS xri-sgl count unchanged: %d\n", - els_xri_cnt); - phba->sli4_hba.els_xri_cnt = els_xri_cnt; - - /* update xris to els sgls on the list */ - sglq_entry = NULL; - sglq_entry_next = NULL; - list_for_each_entry_safe(sglq_entry, sglq_entry_next, - &phba->sli4_hba.lpfc_sgl_list, list) { - lxri = lpfc_sli4_next_xritag(phba); - if (lxri == NO_XRI) { - lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "2400 Failed to allocate xri for " - "ELS sgl\n"); - rc = -ENOMEM; - goto out_free_mem; - } - sglq_entry->sli4_lxritag = lxri; - sglq_entry->sli4_xritag = phba->sli4_hba.xri_ids[lxri]; - } - - /* - * update on pci function's allocated scsi xri-sgl list - */ - phba->total_scsi_bufs = 0; - - /* maximum number of xris available for scsi buffers */ - phba->sli4_hba.scsi_xri_max = phba->sli4_hba.max_cfg_param.max_xri - - els_xri_cnt; - - lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "2401 Current allocated SCSI xri-sgl count:%d, " - "maximum SCSI xri count:%d\n", - phba->sli4_hba.scsi_xri_cnt, - phba->sli4_hba.scsi_xri_max); - - spin_lock_irq(&phba->scsi_buf_list_lock); - list_splice_init(&phba->lpfc_scsi_buf_list, &scsi_sgl_list); - spin_unlock_irq(&phba->scsi_buf_list_lock); - - if (phba->sli4_hba.scsi_xri_cnt > phba->sli4_hba.scsi_xri_max) { - /* max scsi xri shrinked below the allocated scsi buffers */ - scsi_xri_cnt = phba->sli4_hba.scsi_xri_cnt - - phba->sli4_hba.scsi_xri_max; - /* release the extra allocated scsi buffers */ - for (i = 0; i < scsi_xri_cnt; i++) { - list_remove_head(&scsi_sgl_list, psb, - struct lpfc_scsi_buf, list); - pci_pool_free(phba->lpfc_scsi_dma_buf_pool, psb->data, - psb->dma_handle); - kfree(psb); - } - spin_lock_irq(&phba->scsi_buf_list_lock); - phba->sli4_hba.scsi_xri_cnt -= scsi_xri_cnt; - spin_unlock_irq(&phba->scsi_buf_list_lock); - } - - /* update xris associated to remaining allocated scsi buffers */ - psb = NULL; - psb_next = NULL; - list_for_each_entry_safe(psb, psb_next, &scsi_sgl_list, list) { - lxri = lpfc_sli4_next_xritag(phba); - if (lxri == NO_XRI) { - lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "2560 Failed to allocate xri for " - "scsi buffer\n"); - rc = -ENOMEM; - goto out_free_mem; - } - psb->cur_iocbq.sli4_lxritag = lxri; - psb->cur_iocbq.sli4_xritag = phba->sli4_hba.xri_ids[lxri]; - } - spin_lock(&phba->scsi_buf_list_lock); - list_splice_init(&scsi_sgl_list, &phba->lpfc_scsi_buf_list); - spin_unlock(&phba->scsi_buf_list_lock); - return 0; - -out_free_mem: - lpfc_free_els_sgl_list(phba); - lpfc_scsi_free(phba); - return rc; } /** @@ -4774,15 +4636,18 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) if (rc) goto out_free_bsmbx; - /* Initialize sgl lists per host */ - lpfc_init_sgl_list(phba); - - /* Allocate and initialize active sgl array */ + /* Initialize and populate the iocb list per host */ + rc = lpfc_init_sgl_list(phba); + if (rc) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "1400 Failed to initialize sgl list.\n"); + goto out_destroy_cq_event_pool; + } rc = lpfc_init_active_sgl_array(phba); if (rc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "1430 Failed to initialize sgl list.\n"); - goto out_destroy_cq_event_pool; + goto out_free_sgl_list; } rc = lpfc_sli4_init_rpi_hdrs(phba); if (rc) { @@ -4857,6 +4722,8 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) lpfc_sli4_remove_rpi_hdrs(phba); out_free_active_sgl: lpfc_free_active_sgl(phba); +out_free_sgl_list: + lpfc_free_sgl_list(phba); out_destroy_cq_event_pool: lpfc_sli4_cq_event_pool_destroy(phba); out_free_bsmbx: @@ -4893,7 +4760,10 @@ lpfc_sli4_driver_resource_unset(struct lpfc_hba *phba) /* Free the ELS sgl list */ lpfc_free_active_sgl(phba); - lpfc_free_els_sgl_list(phba); + lpfc_free_sgl_list(phba); + + /* Free the SCSI sgl management array */ + kfree(phba->sli4_hba.lpfc_scsi_psb_array); /* Free the completion queue EQ event pool */ lpfc_sli4_cq_event_release_all(phba); @@ -5120,42 +4990,29 @@ lpfc_init_iocb_list(struct lpfc_hba *phba, int iocb_count) } /** - * lpfc_free_sgl_list - Free a given sgl list. + * lpfc_free_sgl_list - Free sgl list. * @phba: pointer to lpfc hba data structure. - * @sglq_list: pointer to the head of sgl list. * - * This routine is invoked to free a give sgl list and memory. - **/ -void -lpfc_free_sgl_list(struct lpfc_hba *phba, struct list_head *sglq_list) -{ - struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL; - - list_for_each_entry_safe(sglq_entry, sglq_next, sglq_list, list) { - list_del(&sglq_entry->list); - lpfc_mbuf_free(phba, sglq_entry->virt, sglq_entry->phys); - kfree(sglq_entry); - } -} - -/** - * lpfc_free_els_sgl_list - Free els sgl list. - * @phba: pointer to lpfc hba data structure. - * - * This routine is invoked to free the driver's els sgl list and memory. + * This routine is invoked to free the driver's sgl list and memory. **/ static void -lpfc_free_els_sgl_list(struct lpfc_hba *phba) +lpfc_free_sgl_list(struct lpfc_hba *phba) { + struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL; LIST_HEAD(sglq_list); - /* Retrieve all els sgls from driver list */ spin_lock_irq(&phba->hbalock); list_splice_init(&phba->sli4_hba.lpfc_sgl_list, &sglq_list); spin_unlock_irq(&phba->hbalock); - /* Now free the sgl list */ - lpfc_free_sgl_list(phba, &sglq_list); + list_for_each_entry_safe(sglq_entry, sglq_next, + &sglq_list, list) { + list_del(&sglq_entry->list); + lpfc_mbuf_free(phba, sglq_entry->virt, sglq_entry->phys); + kfree(sglq_entry); + phba->sli4_hba.total_sglq_bufs--; + } + kfree(phba->sli4_hba.lpfc_els_sgl_array); } /** @@ -5200,19 +5057,99 @@ lpfc_free_active_sgl(struct lpfc_hba *phba) * This routine is invoked to allocate and initizlize the driver's sgl * list and set up the sgl xritag tag array accordingly. * + * Return codes + * 0 - successful + * other values - error **/ -static void +static int lpfc_init_sgl_list(struct lpfc_hba *phba) { + struct lpfc_sglq *sglq_entry = NULL; + int i; + int els_xri_cnt; + + els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba); + lpfc_printf_log(phba, KERN_INFO, LOG_SLI, + "2400 ELS XRI count %d.\n", + els_xri_cnt); /* Initialize and populate the sglq list per host/VF. */ INIT_LIST_HEAD(&phba->sli4_hba.lpfc_sgl_list); INIT_LIST_HEAD(&phba->sli4_hba.lpfc_abts_els_sgl_list); - /* els xri-sgl book keeping */ - phba->sli4_hba.els_xri_cnt = 0; + /* Sanity check on XRI management */ + if (phba->sli4_hba.max_cfg_param.max_xri <= els_xri_cnt) { + lpfc_printf_log(phba, KERN_ERR, LOG_SLI, + "2562 No room left for SCSI XRI allocation: " + "max_xri=%d, els_xri=%d\n", + phba->sli4_hba.max_cfg_param.max_xri, + els_xri_cnt); + return -ENOMEM; + } + + /* Allocate memory for the ELS XRI management array */ + phba->sli4_hba.lpfc_els_sgl_array = + kzalloc((sizeof(struct lpfc_sglq *) * els_xri_cnt), + GFP_KERNEL); + + if (!phba->sli4_hba.lpfc_els_sgl_array) { + lpfc_printf_log(phba, KERN_ERR, LOG_SLI, + "2401 Failed to allocate memory for ELS " + "XRI management array of size %d.\n", + els_xri_cnt); + return -ENOMEM; + } - /* scsi xri-buffer book keeping */ + /* Keep the SCSI XRI into the XRI management array */ + phba->sli4_hba.scsi_xri_max = + phba->sli4_hba.max_cfg_param.max_xri - els_xri_cnt; phba->sli4_hba.scsi_xri_cnt = 0; + phba->sli4_hba.lpfc_scsi_psb_array = + kzalloc((sizeof(struct lpfc_scsi_buf *) * + phba->sli4_hba.scsi_xri_max), GFP_KERNEL); + + if (!phba->sli4_hba.lpfc_scsi_psb_array) { + lpfc_printf_log(phba, KERN_ERR, LOG_SLI, + "2563 Failed to allocate memory for SCSI " + "XRI management array of size %d.\n", + phba->sli4_hba.scsi_xri_max); + kfree(phba->sli4_hba.lpfc_els_sgl_array); + return -ENOMEM; + } + + for (i = 0; i < els_xri_cnt; i++) { + sglq_entry = kzalloc(sizeof(struct lpfc_sglq), GFP_KERNEL); + if (sglq_entry == NULL) { + printk(KERN_ERR "%s: only allocated %d sgls of " + "expected %d count. Unloading driver.\n", + __func__, i, els_xri_cnt); + goto out_free_mem; + } + + sglq_entry->buff_type = GEN_BUFF_TYPE; + sglq_entry->virt = lpfc_mbuf_alloc(phba, 0, &sglq_entry->phys); + if (sglq_entry->virt == NULL) { + kfree(sglq_entry); + printk(KERN_ERR "%s: failed to allocate mbuf.\n" + "Unloading driver.\n", __func__); + goto out_free_mem; + } + sglq_entry->sgl = sglq_entry->virt; + memset(sglq_entry->sgl, 0, LPFC_BPL_SIZE); + + /* The list order is used by later block SGL registraton */ + spin_lock_irq(&phba->hbalock); + sglq_entry->state = SGL_FREED; + list_add_tail(&sglq_entry->list, &phba->sli4_hba.lpfc_sgl_list); + phba->sli4_hba.lpfc_els_sgl_array[i] = sglq_entry; + phba->sli4_hba.total_sglq_bufs++; + spin_unlock_irq(&phba->hbalock); + } + return 0; + +out_free_mem: + kfree(phba->sli4_hba.lpfc_scsi_psb_array); + lpfc_free_sgl_list(phba); + return -ENOMEM; } /** @@ -7383,11 +7320,9 @@ lpfc_pci_function_reset(struct lpfc_hba *phba) phba->sli4_hba.u.if_type2.ERR2regaddr); lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "2890 Port error detected during port " - "reset(%d): wait_tmo:%d ms, " - "port status reg 0x%x, " + "reset(%d): port status reg 0x%x, " "error 1=0x%x, error 2=0x%x\n", - num_resets, rdy_chk*10, - reg_data.word0, + num_resets, reg_data.word0, phba->work_status[0], phba->work_status[1]); rc = -ENODEV; @@ -8759,11 +8694,8 @@ lpfc_pci_remove_one_s3(struct pci_dev *pdev) /* Release all the vports against this physical port */ vports = lpfc_create_vport_work_array(phba); if (vports != NULL) - for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { - if (vports[i]->port_type == LPFC_PHYSICAL_PORT) - continue; + for (i = 1; i <= phba->max_vports && vports[i] != NULL; i++) fc_vport_terminate(vports[i]->fc_vport); - } lpfc_destroy_vport_work_array(phba, vports); /* Remove FC host and then SCSI host with the physical port */ @@ -9183,12 +9115,8 @@ lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *phba) return 50; else if (max_xri <= 1024) return 100; - else if (max_xri <= 1536) - return 150; - else if (max_xri <= 2048) - return 200; else - return 250; + return 150; } else return 0; } @@ -9527,11 +9455,8 @@ lpfc_pci_remove_one_s4(struct pci_dev *pdev) /* Release all the vports against this physical port */ vports = lpfc_create_vport_work_array(phba); if (vports != NULL) - for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { - if (vports[i]->port_type == LPFC_PHYSICAL_PORT) - continue; + for (i = 1; i <= phba->max_vports && vports[i] != NULL; i++) fc_vport_terminate(vports[i]->fc_vport); - } lpfc_destroy_vport_work_array(phba, vports); /* Remove FC host and then SCSI host with the physical port */ diff --git a/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c b/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c index 9133a97f045f..15ca2a9a0cdd 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -367,10 +367,8 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, return 1; } - /* Check for Nport to NPort pt2pt protocol */ if ((vport->fc_flag & FC_PT2PT) && !(vport->fc_flag & FC_PT2PT_PLOGI)) { - /* rcv'ed PLOGI decides what our NPortId will be */ vport->fc_myDID = icmd->un.rcvels.parmRo; mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); @@ -384,13 +382,6 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, mempool_free(mbox, phba->mbox_mem_pool); goto out; } - /* - * For SLI4, the VFI/VPI are registered AFTER the - * Nport with the higher WWPN sends us a PLOGI with - * our assigned NPortId. - */ - if (phba->sli_rev == LPFC_SLI_REV4) - lpfc_issue_reg_vfi(vport); lpfc_can_disctmo(vport); } diff --git a/trunk/drivers/scsi/lpfc/lpfc_scsi.c b/trunk/drivers/scsi/lpfc/lpfc_scsi.c index 66e09069f281..88f3a83dbd2e 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_scsi.c +++ b/trunk/drivers/scsi/lpfc/lpfc_scsi.c @@ -399,14 +399,6 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) num_rsrc_err = atomic_read(&phba->num_rsrc_err); num_cmd_success = atomic_read(&phba->num_cmd_success); - /* - * The error and success command counters are global per - * driver instance. If another handler has already - * operated on this error event, just exit. - */ - if (num_rsrc_err == 0) - return; - vports = lpfc_create_vport_work_array(phba); if (vports != NULL) for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { @@ -696,8 +688,7 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba, rrq_empty = list_empty(&phba->active_rrq_list); spin_unlock_irqrestore(&phba->hbalock, iflag); if (ndlp) { - lpfc_set_rrq_active(phba, ndlp, - psb->cur_iocbq.sli4_lxritag, rxid, 1); + lpfc_set_rrq_active(phba, ndlp, xri, rxid, 1); lpfc_sli4_abts_err_handler(phba, ndlp, axri); } lpfc_release_scsi_buf_s4(phba, psb); @@ -727,162 +718,72 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba, } /** - * lpfc_sli4_post_scsi_sgl_list - Psot blocks of scsi buffer sgls from a list + * lpfc_sli4_repost_scsi_sgl_list - Repsot the Scsi buffers sgl pages as block * @phba: pointer to lpfc hba data structure. - * @post_sblist: pointer to the scsi buffer list. * - * This routine walks a list of scsi buffers that was passed in. It attempts - * to construct blocks of scsi buffer sgls which contains contiguous xris and - * uses the non-embedded SGL block post mailbox commands to post to the port. - * For single SCSI buffer sgl with non-contiguous xri, if any, it shall use - * embedded SGL post mailbox command for posting. The @post_sblist passed in - * must be local list, thus no lock is needed when manipulate the list. + * This routine walks the list of scsi buffers that have been allocated and + * repost them to the HBA by using SGL block post. This is needed after a + * pci_function_reset/warm_start or start. The lpfc_hba_down_post_s4 routine + * is responsible for moving all scsi buffers on the lpfc_abts_scsi_sgl_list + * to the lpfc_scsi_buf_list. If the repost fails, reject all scsi buffers. * - * Returns: 0 = failure, non-zero number of successfully posted buffers. + * Returns: 0 = success, non-zero failure. **/ int -lpfc_sli4_post_scsi_sgl_list(struct lpfc_hba *phba, - struct list_head *post_sblist, int sb_count) +lpfc_sli4_repost_scsi_sgl_list(struct lpfc_hba *phba) { - struct lpfc_scsi_buf *psb, *psb_next; - int status; - int post_cnt = 0, block_cnt = 0, num_posting = 0, num_posted = 0; - dma_addr_t pdma_phys_bpl1; - int last_xritag = NO_XRI; - LIST_HEAD(prep_sblist); - LIST_HEAD(blck_sblist); - LIST_HEAD(scsi_sblist); - - /* sanity check */ - if (sb_count <= 0) - return -EINVAL; - - list_for_each_entry_safe(psb, psb_next, post_sblist, list) { - list_del_init(&psb->list); - block_cnt++; - if ((last_xritag != NO_XRI) && - (psb->cur_iocbq.sli4_xritag != last_xritag + 1)) { - /* a hole in xri block, form a sgl posting block */ - list_splice_init(&prep_sblist, &blck_sblist); - post_cnt = block_cnt - 1; - /* prepare list for next posting block */ - list_add_tail(&psb->list, &prep_sblist); - block_cnt = 1; - } else { - /* prepare list for next posting block */ - list_add_tail(&psb->list, &prep_sblist); - /* enough sgls for non-embed sgl mbox command */ - if (block_cnt == LPFC_NEMBED_MBOX_SGL_CNT) { - list_splice_init(&prep_sblist, &blck_sblist); - post_cnt = block_cnt; - block_cnt = 0; - } - } - num_posting++; - last_xritag = psb->cur_iocbq.sli4_xritag; + struct lpfc_scsi_buf *psb; + int index, status, bcnt = 0, rcnt = 0, rc = 0; + LIST_HEAD(sblist); - /* end of repost sgl list condition for SCSI buffers */ - if (num_posting == sb_count) { - if (post_cnt == 0) { - /* last sgl posting block */ - list_splice_init(&prep_sblist, &blck_sblist); - post_cnt = block_cnt; - } else if (block_cnt == 1) { - /* last single sgl with non-contiguous xri */ - if (phba->cfg_sg_dma_buf_size > SGL_PAGE_SIZE) - pdma_phys_bpl1 = psb->dma_phys_bpl + - SGL_PAGE_SIZE; - else - pdma_phys_bpl1 = 0; - status = lpfc_sli4_post_sgl(phba, - psb->dma_phys_bpl, - pdma_phys_bpl1, - psb->cur_iocbq.sli4_xritag); - if (status) { - /* failure, put on abort scsi list */ - psb->exch_busy = 1; - } else { - /* success, put on SCSI buffer list */ - psb->exch_busy = 0; - psb->status = IOSTAT_SUCCESS; - num_posted++; - } - /* success, put on SCSI buffer sgl list */ - list_add_tail(&psb->list, &scsi_sblist); + for (index = 0; index < phba->sli4_hba.scsi_xri_cnt; index++) { + psb = phba->sli4_hba.lpfc_scsi_psb_array[index]; + if (psb) { + /* Remove from SCSI buffer list */ + list_del(&psb->list); + /* Add it to a local SCSI buffer list */ + list_add_tail(&psb->list, &sblist); + if (++rcnt == LPFC_NEMBED_MBOX_SGL_CNT) { + bcnt = rcnt; + rcnt = 0; } - } - - /* continue until a nembed page worth of sgls */ - if (post_cnt == 0) - continue; - - /* post block of SCSI buffer list sgls */ - status = lpfc_sli4_post_scsi_sgl_block(phba, &blck_sblist, - post_cnt); - - /* don't reset xirtag due to hole in xri block */ - if (block_cnt == 0) - last_xritag = NO_XRI; + } else + /* A hole present in the XRI array, need to skip */ + bcnt = rcnt; - /* reset SCSI buffer post count for next round of posting */ - post_cnt = 0; + if (index == phba->sli4_hba.scsi_xri_cnt - 1) + /* End of XRI array for SCSI buffer, complete */ + bcnt = rcnt; - /* put posted SCSI buffer-sgl posted on SCSI buffer sgl list */ - while (!list_empty(&blck_sblist)) { - list_remove_head(&blck_sblist, psb, - struct lpfc_scsi_buf, list); + /* Continue until collect up to a nembed page worth of sgls */ + if (bcnt == 0) + continue; + /* Now, post the SCSI buffer list sgls as a block */ + if (!phba->sli4_hba.extents_in_use) + status = lpfc_sli4_post_scsi_sgl_block(phba, + &sblist, + bcnt); + else + status = lpfc_sli4_post_scsi_sgl_blk_ext(phba, + &sblist, + bcnt); + /* Reset SCSI buffer count for next round of posting */ + bcnt = 0; + while (!list_empty(&sblist)) { + list_remove_head(&sblist, psb, struct lpfc_scsi_buf, + list); if (status) { - /* failure, put on abort scsi list */ + /* Put this back on the abort scsi list */ psb->exch_busy = 1; + rc++; } else { - /* success, put on SCSI buffer list */ psb->exch_busy = 0; psb->status = IOSTAT_SUCCESS; - num_posted++; } - list_add_tail(&psb->list, &scsi_sblist); + /* Put it back into the SCSI buffer list */ + lpfc_release_scsi_buf_s4(phba, psb); } } - /* Push SCSI buffers with sgl posted to the availble list */ - while (!list_empty(&scsi_sblist)) { - list_remove_head(&scsi_sblist, psb, - struct lpfc_scsi_buf, list); - lpfc_release_scsi_buf_s4(phba, psb); - } - return num_posted; -} - -/** - * lpfc_sli4_repost_scsi_sgl_list - Repsot all the allocated scsi buffer sgls - * @phba: pointer to lpfc hba data structure. - * - * This routine walks the list of scsi buffers that have been allocated and - * repost them to the port by using SGL block post. This is needed after a - * pci_function_reset/warm_start or start. The lpfc_hba_down_post_s4 routine - * is responsible for moving all scsi buffers on the lpfc_abts_scsi_sgl_list - * to the lpfc_scsi_buf_list. If the repost fails, reject all scsi buffers. - * - * Returns: 0 = success, non-zero failure. - **/ -int -lpfc_sli4_repost_scsi_sgl_list(struct lpfc_hba *phba) -{ - LIST_HEAD(post_sblist); - int num_posted, rc = 0; - - /* get all SCSI buffers need to repost to a local list */ - spin_lock(&phba->scsi_buf_list_lock); - list_splice_init(&phba->lpfc_scsi_buf_list, &post_sblist); - spin_unlock(&phba->scsi_buf_list_lock); - - /* post the list of scsi buffer sgls to port if available */ - if (!list_empty(&post_sblist)) { - num_posted = lpfc_sli4_post_scsi_sgl_list(phba, &post_sblist, - phba->sli4_hba.scsi_xri_cnt); - /* failed to post any scsi buffer, return error */ - if (num_posted == 0) - rc = -EIO; - } return rc; } @@ -891,13 +792,12 @@ lpfc_sli4_repost_scsi_sgl_list(struct lpfc_hba *phba) * @vport: The virtual port for which this call being executed. * @num_to_allocate: The requested number of buffers to allocate. * - * This routine allocates scsi buffers for device with SLI-4 interface spec, + * This routine allocates a scsi buffer for device with SLI-4 interface spec, * the scsi buffer contains all the necessary information needed to initiate - * a SCSI I/O. After allocating up to @num_to_allocate SCSI buffers and put - * them on a list, it post them to the port by using SGL block post. + * a SCSI I/O. * * Return codes: - * int - number of scsi buffers that were allocated and posted. + * int - number of scsi buffers that were allocated. * 0 = failure, less than num_to_alloc is a partial failure. **/ static int @@ -910,21 +810,22 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc) dma_addr_t pdma_phys_fcp_cmd; dma_addr_t pdma_phys_fcp_rsp; dma_addr_t pdma_phys_bpl, pdma_phys_bpl1; - uint16_t iotag, lxri = 0; - int bcnt, num_posted; - LIST_HEAD(prep_sblist); - LIST_HEAD(post_sblist); - LIST_HEAD(scsi_sblist); + uint16_t iotag, last_xritag = NO_XRI, lxri = 0; + int status = 0, index; + int bcnt; + int non_sequential_xri = 0; + LIST_HEAD(sblist); for (bcnt = 0; bcnt < num_to_alloc; bcnt++) { psb = kzalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL); if (!psb) break; + /* - * Get memory from the pci pool to map the virt space to - * pci bus space for an I/O. The DMA buffer includes space - * for the struct fcp_cmnd, struct fcp_rsp and the number - * of bde's necessary to support the sg_tablesize. + * Get memory from the pci pool to map the virt space to pci bus + * space for an I/O. The DMA buffer includes space for the + * struct fcp_cmnd, struct fcp_rsp and the number of bde's + * necessary to support the sg_tablesize. */ psb->data = pci_pool_alloc(phba->lpfc_scsi_dma_buf_pool, GFP_KERNEL, &psb->dma_handle); @@ -932,6 +833,8 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc) kfree(psb); break; } + + /* Initialize virtual ptrs to dma_buf region. */ memset(psb->data, 0, phba->cfg_sg_dma_buf_size); /* Allocate iotag for psb->cur_iocbq. */ @@ -952,7 +855,16 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc) } psb->cur_iocbq.sli4_lxritag = lxri; psb->cur_iocbq.sli4_xritag = phba->sli4_hba.xri_ids[lxri]; + if (last_xritag != NO_XRI + && psb->cur_iocbq.sli4_xritag != (last_xritag+1)) { + non_sequential_xri = 1; + } else + list_add_tail(&psb->list, &sblist); + last_xritag = psb->cur_iocbq.sli4_xritag; + + index = phba->sli4_hba.scsi_xri_cnt++; psb->cur_iocbq.iocb_flag |= LPFC_IO_FCP; + psb->fcp_bpl = psb->data; psb->fcp_cmnd = (psb->data + phba->cfg_sg_dma_buf_size) - (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp)); @@ -968,9 +880,9 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc) pdma_phys_fcp_rsp = pdma_phys_fcp_cmd + sizeof(struct fcp_cmnd); /* - * The first two bdes are the FCP_CMD and FCP_RSP. - * The balance are sg list bdes. Initialize the - * first two and leave the rest for queuecommand. + * The first two bdes are the FCP_CMD and FCP_RSP. The balance + * are sg list bdes. Initialize the first two and leave the + * rest for queuecommand. */ sgl->addr_hi = cpu_to_le32(putPaddrHigh(pdma_phys_fcp_cmd)); sgl->addr_lo = cpu_to_le32(putPaddrLow(pdma_phys_fcp_cmd)); @@ -1005,31 +917,62 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc) iocb->ulpBdeCount = 1; iocb->ulpLe = 1; iocb->ulpClass = CLASS3; - psb->cur_iocbq.context1 = psb; + psb->cur_iocbq.context1 = psb; if (phba->cfg_sg_dma_buf_size > SGL_PAGE_SIZE) pdma_phys_bpl1 = pdma_phys_bpl + SGL_PAGE_SIZE; else pdma_phys_bpl1 = 0; psb->dma_phys_bpl = pdma_phys_bpl; - - /* add the scsi buffer to a post list */ - list_add_tail(&psb->list, &post_sblist); - spin_lock_irq(&phba->scsi_buf_list_lock); - phba->sli4_hba.scsi_xri_cnt++; - spin_unlock_irq(&phba->scsi_buf_list_lock); + phba->sli4_hba.lpfc_scsi_psb_array[index] = psb; + if (non_sequential_xri) { + status = lpfc_sli4_post_sgl(phba, pdma_phys_bpl, + pdma_phys_bpl1, + psb->cur_iocbq.sli4_xritag); + if (status) { + /* Put this back on the abort scsi list */ + psb->exch_busy = 1; + } else { + psb->exch_busy = 0; + psb->status = IOSTAT_SUCCESS; + } + /* Put it back into the SCSI buffer list */ + lpfc_release_scsi_buf_s4(phba, psb); + break; + } + } + if (bcnt) { + if (!phba->sli4_hba.extents_in_use) + status = lpfc_sli4_post_scsi_sgl_block(phba, + &sblist, + bcnt); + else + status = lpfc_sli4_post_scsi_sgl_blk_ext(phba, + &sblist, + bcnt); + + if (status) { + lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, + "3021 SCSI SGL post error %d\n", + status); + bcnt = 0; + } + /* Reset SCSI buffer count for next round of posting */ + while (!list_empty(&sblist)) { + list_remove_head(&sblist, psb, struct lpfc_scsi_buf, + list); + if (status) { + /* Put this back on the abort scsi list */ + psb->exch_busy = 1; + } else { + psb->exch_busy = 0; + psb->status = IOSTAT_SUCCESS; + } + /* Put it back into the SCSI buffer list */ + lpfc_release_scsi_buf_s4(phba, psb); + } } - lpfc_printf_log(phba, KERN_INFO, LOG_BG, - "3021 Allocate %d out of %d requested new SCSI " - "buffers\n", bcnt, num_to_alloc); - - /* post the list of scsi buffer sgls to port if available */ - if (!list_empty(&post_sblist)) - num_posted = lpfc_sli4_post_scsi_sgl_list(phba, - &post_sblist, bcnt); - else - num_posted = 0; - return num_posted; + return bcnt + non_sequential_xri; } /** @@ -1100,7 +1043,7 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) list_for_each_entry(lpfc_cmd, &phba->lpfc_scsi_buf_list, list) { if (lpfc_test_rrq_active(phba, ndlp, - lpfc_cmd->cur_iocbq.sli4_lxritag)) + lpfc_cmd->cur_iocbq.sli4_xritag)) continue; list_del(&lpfc_cmd->list); found = 1; @@ -1954,9 +1897,7 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc, dma_addr_t physaddr; int i = 0, num_bde = 0, status; int datadir = sc->sc_data_direction; -#ifdef CONFIG_SCSI_LPFC_DEBUG_FS uint32_t rc; -#endif uint32_t checking = 1; uint32_t reftag; unsigned blksize; @@ -2093,9 +2034,7 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, int datadir = sc->sc_data_direction; unsigned char pgdone = 0, alldone = 0; unsigned blksize; -#ifdef CONFIG_SCSI_LPFC_DEBUG_FS uint32_t rc; -#endif uint32_t checking = 1; uint32_t reftag; uint8_t txop, rxop; @@ -2314,9 +2253,7 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, uint32_t reftag; unsigned blksize; uint8_t txop, rxop; -#ifdef CONFIG_SCSI_LPFC_DEBUG_FS uint32_t rc; -#endif uint32_t checking = 1; uint32_t dma_len; uint32_t dma_offset = 0; @@ -2446,9 +2383,7 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, uint32_t reftag; uint8_t txop, rxop; uint32_t dma_len; -#ifdef CONFIG_SCSI_LPFC_DEBUG_FS uint32_t rc; -#endif uint32_t checking = 1; uint32_t dma_offset = 0; int num_sge = 0; @@ -3669,16 +3604,11 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, logit = LOG_FCP | LOG_FCP_UNDER; lpfc_printf_vlog(vport, KERN_WARNING, logit, "9030 FCP cmd x%x failed <%d/%d> " - "status: x%x result: x%x " - "sid: x%x did: x%x oxid: x%x " - "Data: x%x x%x\n", + "status: x%x result: x%x Data: x%x x%x\n", cmd->cmnd[0], cmd->device ? cmd->device->id : 0xffff, cmd->device ? cmd->device->lun : 0xffff, lpfc_cmd->status, lpfc_cmd->result, - vport->fc_myDID, pnode->nlp_DID, - phba->sli_rev == LPFC_SLI_REV4 ? - lpfc_cmd->cur_iocbq.sli4_xritag : 0xffff, pIocbOut->iocb.ulpContext, lpfc_cmd->cur_iocbq.iocb.ulpIoTag); @@ -3759,8 +3689,8 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, * ABTS we cannot generate and RRQ. */ lpfc_set_rrq_active(phba, pnode, - lpfc_cmd->cur_iocbq.sli4_lxritag, - 0, 0); + lpfc_cmd->cur_iocbq.sli4_xritag, + 0, 0); } /* else: fall through */ default: @@ -4418,20 +4348,8 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) ret = fc_block_scsi_eh(cmnd); if (ret) return ret; - - spin_lock_irq(&phba->hbalock); - /* driver queued commands are in process of being flushed */ - if (phba->hba_flag & HBA_FCP_IOQ_FLUSH) { - spin_unlock_irq(&phba->hbalock); - lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, - "3168 SCSI Layer abort requested I/O has been " - "flushed by LLD.\n"); - return FAILED; - } - lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; if (!lpfc_cmd) { - spin_unlock_irq(&phba->hbalock); lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, "2873 SCSI Layer I/O Abort Request IO CMPL Status " "x%x ID %d LUN %d\n", @@ -4439,34 +4357,23 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) return SUCCESS; } - iocb = &lpfc_cmd->cur_iocbq; - /* the command is in process of being cancelled */ - if (!(iocb->iocb_flag & LPFC_IO_ON_TXCMPLQ)) { - spin_unlock_irq(&phba->hbalock); - lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, - "3169 SCSI Layer abort requested I/O has been " - "cancelled by LLD.\n"); - return FAILED; - } /* * If pCmd field of the corresponding lpfc_scsi_buf structure * points to a different SCSI command, then the driver has * already completed this command, but the midlayer did not - * see the completion before the eh fired. Just return SUCCESS. + * see the completion before the eh fired. Just return + * SUCCESS. */ - if (lpfc_cmd->pCmd != cmnd) { - lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, - "3170 SCSI Layer abort requested I/O has been " - "completed by LLD.\n"); - goto out_unlock; - } + iocb = &lpfc_cmd->cur_iocbq; + if (lpfc_cmd->pCmd != cmnd) + goto out; BUG_ON(iocb->context1 != lpfc_cmd); - abtsiocb = __lpfc_sli_get_iocbq(phba); + abtsiocb = lpfc_sli_get_iocbq(phba); if (abtsiocb == NULL) { ret = FAILED; - goto out_unlock; + goto out; } /* @@ -4498,9 +4405,6 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; abtsiocb->vport = vport; - /* no longer need the lock after this point */ - spin_unlock_irq(&phba->hbalock); - if (lpfc_sli_issue_iocb(phba, LPFC_FCP_RING, abtsiocb, 0) == IOCB_ERROR) { lpfc_sli_release_iocbq(phba, abtsiocb); @@ -4517,7 +4421,10 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) wait_event_timeout(waitq, (lpfc_cmd->pCmd != cmnd), (2*vport->cfg_devloss_tmo*HZ)); + + spin_lock_irq(shost->host_lock); lpfc_cmd->waitq = NULL; + spin_unlock_irq(shost->host_lock); if (lpfc_cmd->pCmd == cmnd) { ret = FAILED; @@ -4527,11 +4434,8 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) "LUN %d\n", ret, cmnd->device->id, cmnd->device->lun); } - goto out; -out_unlock: - spin_unlock_irq(&phba->hbalock); -out: + out: lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, "0749 SCSI Layer I/O Abort Request Status x%x ID %d " "LUN %d\n", ret, cmnd->device->id, @@ -4958,43 +4862,6 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) return ret; } -/** - * lpfc_host_reset_handler - scsi_host_template eh_host_reset_handler entry pt - * @cmnd: Pointer to scsi_cmnd data structure. - * - * This routine does host reset to the adaptor port. It brings the HBA - * offline, performs a board restart, and then brings the board back online. - * The lpfc_offline calls lpfc_sli_hba_down which will abort and local - * reject all outstanding SCSI commands to the host and error returned - * back to SCSI mid-level. As this will be SCSI mid-level's last resort - * of error handling, it will only return error if resetting of the adapter - * is not successful; in all other cases, will return success. - * - * Return code : - * 0x2003 - Error - * 0x2002 - Success - **/ -static int -lpfc_host_reset_handler(struct scsi_cmnd *cmnd) -{ - struct Scsi_Host *shost = cmnd->device->host; - struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; - struct lpfc_hba *phba = vport->phba; - int rc, ret = SUCCESS; - - lpfc_offline_prep(phba); - lpfc_offline(phba); - rc = lpfc_sli_brdrestart(phba); - if (rc) - ret = FAILED; - lpfc_online(phba); - lpfc_unblock_mgmt_io(phba); - - lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "3172 SCSI layer issued Host Reset Data: x%x\n", ret); - return ret; -} - /** * lpfc_slave_alloc - scsi_host_template slave_alloc entry point * @sdev: Pointer to scsi_device. @@ -5127,7 +4994,6 @@ struct scsi_host_template lpfc_template = { .eh_device_reset_handler = lpfc_device_reset_handler, .eh_target_reset_handler = lpfc_target_reset_handler, .eh_bus_reset_handler = lpfc_bus_reset_handler, - .eh_host_reset_handler = lpfc_host_reset_handler, .slave_alloc = lpfc_slave_alloc, .slave_configure = lpfc_slave_configure, .slave_destroy = lpfc_slave_destroy, diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli.c b/trunk/drivers/scsi/lpfc/lpfc_sli.c index b4720a109817..dbaf5b963bff 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli.c +++ b/trunk/drivers/scsi/lpfc/lpfc_sli.c @@ -67,8 +67,6 @@ static void lpfc_sli4_send_seq_to_ulp(struct lpfc_vport *, struct hbq_dmabuf *); static int lpfc_sli4_fp_handle_wcqe(struct lpfc_hba *, struct lpfc_queue *, struct lpfc_cqe *); -static int lpfc_sli4_post_els_sgl_list(struct lpfc_hba *, struct list_head *, - int); static IOCB_t * lpfc_get_iocb_from_iocbq(struct lpfc_iocbq *iocbq) @@ -502,7 +500,7 @@ lpfc_resp_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) * allocation is successful, it returns pointer to the newly * allocated iocb object else it returns NULL. **/ -struct lpfc_iocbq * +static struct lpfc_iocbq * __lpfc_sli_get_iocbq(struct lpfc_hba *phba) { struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; @@ -877,9 +875,6 @@ __lpfc_sli_get_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq) } else if ((piocbq->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) && !(piocbq->iocb_flag & LPFC_IO_LIBDFC)) ndlp = piocbq->context_un.ndlp; - else if ((piocbq->iocb.ulpCommand == CMD_ELS_REQUEST64_CR) && - (piocbq->iocb_flag & LPFC_IO_LIBDFC)) - ndlp = piocbq->context_un.ndlp; else ndlp = piocbq->context1; @@ -888,7 +883,7 @@ __lpfc_sli_get_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq) while (!found) { if (!sglq) return NULL; - if (lpfc_test_rrq_active(phba, ndlp, sglq->sli4_lxritag)) { + if (lpfc_test_rrq_active(phba, ndlp, sglq->sli4_xritag)) { /* This xri has an rrq outstanding for this DID. * put it back in the list and get another xri. */ @@ -1262,7 +1257,7 @@ lpfc_sli_ringtxcmpl_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_iocbq *piocb) { list_add_tail(&piocb->list, &pring->txcmplq); - piocb->iocb_flag |= LPFC_IO_ON_TXCMPLQ; + piocb->iocb_flag |= LPFC_IO_ON_Q; pring->txcmplq_cnt++; if (pring->txcmplq_cnt > pring->txcmplq_max) pring->txcmplq_max = pring->txcmplq_cnt; @@ -2561,9 +2556,9 @@ lpfc_sli_iocbq_lookup(struct lpfc_hba *phba, if (iotag != 0 && iotag <= phba->sli.last_iotag) { cmd_iocb = phba->sli.iocbq_lookup[iotag]; list_del_init(&cmd_iocb->list); - if (cmd_iocb->iocb_flag & LPFC_IO_ON_TXCMPLQ) { + if (cmd_iocb->iocb_flag & LPFC_IO_ON_Q) { pring->txcmplq_cnt--; - cmd_iocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ; + cmd_iocb->iocb_flag &= ~LPFC_IO_ON_Q; } return cmd_iocb; } @@ -2596,14 +2591,14 @@ lpfc_sli_iocbq_lookup_by_tag(struct lpfc_hba *phba, if (iotag != 0 && iotag <= phba->sli.last_iotag) { cmd_iocb = phba->sli.iocbq_lookup[iotag]; - if (cmd_iocb->iocb_flag & LPFC_IO_ON_TXCMPLQ) { - /* remove from txcmpl queue list */ - list_del_init(&cmd_iocb->list); - cmd_iocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ; + list_del_init(&cmd_iocb->list); + if (cmd_iocb->iocb_flag & LPFC_IO_ON_Q) { + cmd_iocb->iocb_flag &= ~LPFC_IO_ON_Q; pring->txcmplq_cnt--; - return cmd_iocb; } + return cmd_iocb; } + lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "0372 iotag x%x is out off range: max iotag (x%x)\n", iotag, phba->sli.last_iotag); @@ -3471,9 +3466,6 @@ lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba) /* Retrieve everything on the txcmplq */ list_splice_init(&pring->txcmplq, &txcmplq); pring->txcmplq_cnt = 0; - - /* Indicate the I/O queues are flushed */ - phba->hba_flag |= HBA_FCP_IOQ_FLUSH; spin_unlock_irq(&phba->hbalock); /* Flush the txq */ @@ -3885,7 +3877,6 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba) { struct lpfc_sli *psli = &phba->sli; uint16_t cfg_value; - int rc; /* Reset HBA */ lpfc_printf_log(phba, KERN_INFO, LOG_SLI, @@ -3914,12 +3905,12 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba) /* Perform FCoE PCI function reset */ lpfc_sli4_queue_destroy(phba); - rc = lpfc_pci_function_reset(phba); + lpfc_pci_function_reset(phba); /* Restore PCI cmd register */ pci_write_config_word(phba->pcidev, PCI_COMMAND, cfg_value); - return rc; + return 0; } /** @@ -4011,7 +4002,6 @@ lpfc_sli_brdrestart_s4(struct lpfc_hba *phba) { struct lpfc_sli *psli = &phba->sli; uint32_t hba_aer_enabled; - int rc; /* Restart HBA */ lpfc_printf_log(phba, KERN_INFO, LOG_SLI, @@ -4021,7 +4011,7 @@ lpfc_sli_brdrestart_s4(struct lpfc_hba *phba) /* Take PCIe device Advanced Error Reporting (AER) state */ hba_aer_enabled = phba->hba_flag & HBA_AER_ENABLED; - rc = lpfc_sli4_brdreset(phba); + lpfc_sli4_brdreset(phba); spin_lock_irq(&phba->hbalock); phba->pport->stopped = 0; @@ -4038,7 +4028,7 @@ lpfc_sli_brdrestart_s4(struct lpfc_hba *phba) lpfc_hba_down_post(phba); - return rc; + return 0; } /** @@ -4977,12 +4967,7 @@ lpfc_sli4_get_avail_extnt_rsrc(struct lpfc_hba *phba, uint16_t type, &rsrc_info->u.rsp); *extnt_size = bf_get(lpfc_mbx_get_rsrc_extent_info_size, &rsrc_info->u.rsp); - - lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "3162 Retrieved extents type-%d from port: count:%d, " - "size:%d\n", type, *extnt_count, *extnt_size); - -err_exit: + err_exit: mempool_free(mbox, phba->mbox_mem_pool); return rc; } @@ -5066,7 +5051,7 @@ lpfc_sli4_chk_avail_extnt_rsrc(struct lpfc_hba *phba, uint16_t type) * 0: if successful **/ static int -lpfc_sli4_cfg_post_extnts(struct lpfc_hba *phba, uint16_t extnt_cnt, +lpfc_sli4_cfg_post_extnts(struct lpfc_hba *phba, uint16_t *extnt_cnt, uint16_t type, bool *emb, LPFC_MBOXQ_t *mbox) { int rc = 0; @@ -5075,7 +5060,7 @@ lpfc_sli4_cfg_post_extnts(struct lpfc_hba *phba, uint16_t extnt_cnt, uint32_t alloc_len, mbox_tmo; /* Calculate the total requested length of the dma memory */ - req_len = extnt_cnt * sizeof(uint16_t); + req_len = *extnt_cnt * sizeof(uint16_t); /* * Calculate the size of an embedded mailbox. The uint32_t @@ -5090,7 +5075,7 @@ lpfc_sli4_cfg_post_extnts(struct lpfc_hba *phba, uint16_t extnt_cnt, */ *emb = LPFC_SLI4_MBX_EMBED; if (req_len > emb_len) { - req_len = extnt_cnt * sizeof(uint16_t) + + req_len = *extnt_cnt * sizeof(uint16_t) + sizeof(union lpfc_sli4_cfg_shdr) + sizeof(uint32_t); *emb = LPFC_SLI4_MBX_NEMBED; @@ -5106,7 +5091,7 @@ lpfc_sli4_cfg_post_extnts(struct lpfc_hba *phba, uint16_t extnt_cnt, "size (x%x)\n", alloc_len, req_len); return -ENOMEM; } - rc = lpfc_sli4_mbox_rsrc_extent(phba, mbox, extnt_cnt, type, *emb); + rc = lpfc_sli4_mbox_rsrc_extent(phba, mbox, *extnt_cnt, type, *emb); if (unlikely(rc)) return -EIO; @@ -5164,15 +5149,17 @@ lpfc_sli4_alloc_extent(struct lpfc_hba *phba, uint16_t type) return -ENOMEM; } - lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_INIT | LOG_SLI, - "2903 Post resource extents type-0x%x: " - "count:%d, size %d\n", type, rsrc_cnt, rsrc_size); + lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_INIT, + "2903 Available Resource Extents " + "for resource type 0x%x: Count: 0x%x, " + "Size 0x%x\n", type, rsrc_cnt, + rsrc_size); mbox = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!mbox) return -ENOMEM; - rc = lpfc_sli4_cfg_post_extnts(phba, rsrc_cnt, type, &emb, mbox); + rc = lpfc_sli4_cfg_post_extnts(phba, &rsrc_cnt, type, &emb, mbox); if (unlikely(rc)) { rc = -EIO; goto err_exit; @@ -5263,7 +5250,6 @@ lpfc_sli4_alloc_extent(struct lpfc_hba *phba, uint16_t type) rc = -ENOMEM; goto err_exit; } - phba->sli4_hba.max_cfg_param.xri_used = 0; phba->sli4_hba.xri_ids = kzalloc(rsrc_id_cnt * sizeof(uint16_t), GFP_KERNEL); @@ -5434,6 +5420,7 @@ lpfc_sli4_dealloc_extent(struct lpfc_hba *phba, uint16_t type) case LPFC_RSC_TYPE_FCOE_XRI: kfree(phba->sli4_hba.xri_bmask); kfree(phba->sli4_hba.xri_ids); + bf_set(lpfc_xri_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0); list_for_each_entry_safe(rsrc_blk, rsrc_blk_next, &phba->sli4_hba.lpfc_xri_blk_list, list) { list_del_init(&rsrc_blk->list); @@ -5625,6 +5612,7 @@ lpfc_sli4_alloc_resource_identifiers(struct lpfc_hba *phba) goto free_vpi_ids; } phba->sli4_hba.max_cfg_param.xri_used = 0; + phba->sli4_hba.xri_count = 0; phba->sli4_hba.xri_ids = kzalloc(count * sizeof(uint16_t), GFP_KERNEL); @@ -5706,6 +5694,7 @@ lpfc_sli4_dealloc_resource_identifiers(struct lpfc_hba *phba) bf_set(lpfc_vpi_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0); kfree(phba->sli4_hba.xri_bmask); kfree(phba->sli4_hba.xri_ids); + bf_set(lpfc_xri_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0); kfree(phba->sli4_hba.vfi_bmask); kfree(phba->sli4_hba.vfi_ids); bf_set(lpfc_vfi_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0); @@ -5863,149 +5852,6 @@ lpfc_sli4_get_allocated_extnts(struct lpfc_hba *phba, uint16_t type, return rc; } -/** - * lpfc_sli4_repost_els_sgl_list - Repsot the els buffers sgl pages as block - * @phba: pointer to lpfc hba data structure. - * - * This routine walks the list of els buffers that have been allocated and - * repost them to the port by using SGL block post. This is needed after a - * pci_function_reset/warm_start or start. It attempts to construct blocks - * of els buffer sgls which contains contiguous xris and uses the non-embedded - * SGL block post mailbox commands to post them to the port. For single els - * buffer sgl with non-contiguous xri, if any, it shall use embedded SGL post - * mailbox command for posting. - * - * Returns: 0 = success, non-zero failure. - **/ -static int -lpfc_sli4_repost_els_sgl_list(struct lpfc_hba *phba) -{ - struct lpfc_sglq *sglq_entry = NULL; - struct lpfc_sglq *sglq_entry_next = NULL; - struct lpfc_sglq *sglq_entry_first = NULL; - int status, post_cnt = 0, num_posted = 0, block_cnt = 0; - int last_xritag = NO_XRI; - LIST_HEAD(prep_sgl_list); - LIST_HEAD(blck_sgl_list); - LIST_HEAD(allc_sgl_list); - LIST_HEAD(post_sgl_list); - LIST_HEAD(free_sgl_list); - - spin_lock(&phba->hbalock); - list_splice_init(&phba->sli4_hba.lpfc_sgl_list, &allc_sgl_list); - spin_unlock(&phba->hbalock); - - list_for_each_entry_safe(sglq_entry, sglq_entry_next, - &allc_sgl_list, list) { - list_del_init(&sglq_entry->list); - block_cnt++; - if ((last_xritag != NO_XRI) && - (sglq_entry->sli4_xritag != last_xritag + 1)) { - /* a hole in xri block, form a sgl posting block */ - list_splice_init(&prep_sgl_list, &blck_sgl_list); - post_cnt = block_cnt - 1; - /* prepare list for next posting block */ - list_add_tail(&sglq_entry->list, &prep_sgl_list); - block_cnt = 1; - } else { - /* prepare list for next posting block */ - list_add_tail(&sglq_entry->list, &prep_sgl_list); - /* enough sgls for non-embed sgl mbox command */ - if (block_cnt == LPFC_NEMBED_MBOX_SGL_CNT) { - list_splice_init(&prep_sgl_list, - &blck_sgl_list); - post_cnt = block_cnt; - block_cnt = 0; - } - } - num_posted++; - - /* keep track of last sgl's xritag */ - last_xritag = sglq_entry->sli4_xritag; - - /* end of repost sgl list condition for els buffers */ - if (num_posted == phba->sli4_hba.els_xri_cnt) { - if (post_cnt == 0) { - list_splice_init(&prep_sgl_list, - &blck_sgl_list); - post_cnt = block_cnt; - } else if (block_cnt == 1) { - status = lpfc_sli4_post_sgl(phba, - sglq_entry->phys, 0, - sglq_entry->sli4_xritag); - if (!status) { - /* successful, put sgl to posted list */ - list_add_tail(&sglq_entry->list, - &post_sgl_list); - } else { - /* Failure, put sgl to free list */ - lpfc_printf_log(phba, KERN_WARNING, - LOG_SLI, - "3159 Failed to post els " - "sgl, xritag:x%x\n", - sglq_entry->sli4_xritag); - list_add_tail(&sglq_entry->list, - &free_sgl_list); - spin_lock_irq(&phba->hbalock); - phba->sli4_hba.els_xri_cnt--; - spin_unlock_irq(&phba->hbalock); - } - } - } - - /* continue until a nembed page worth of sgls */ - if (post_cnt == 0) - continue; - - /* post the els buffer list sgls as a block */ - status = lpfc_sli4_post_els_sgl_list(phba, &blck_sgl_list, - post_cnt); - - if (!status) { - /* success, put sgl list to posted sgl list */ - list_splice_init(&blck_sgl_list, &post_sgl_list); - } else { - /* Failure, put sgl list to free sgl list */ - sglq_entry_first = list_first_entry(&blck_sgl_list, - struct lpfc_sglq, - list); - lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, - "3160 Failed to post els sgl-list, " - "xritag:x%x-x%x\n", - sglq_entry_first->sli4_xritag, - (sglq_entry_first->sli4_xritag + - post_cnt - 1)); - list_splice_init(&blck_sgl_list, &free_sgl_list); - spin_lock_irq(&phba->hbalock); - phba->sli4_hba.els_xri_cnt -= post_cnt; - spin_unlock_irq(&phba->hbalock); - } - - /* don't reset xirtag due to hole in xri block */ - if (block_cnt == 0) - last_xritag = NO_XRI; - - /* reset els sgl post count for next round of posting */ - post_cnt = 0; - } - - /* free the els sgls failed to post */ - lpfc_free_sgl_list(phba, &free_sgl_list); - - /* push els sgls posted to the availble list */ - if (!list_empty(&post_sgl_list)) { - spin_lock(&phba->hbalock); - list_splice_init(&post_sgl_list, - &phba->sli4_hba.lpfc_sgl_list); - spin_unlock(&phba->hbalock); - } else { - lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "3161 Failure to post els sgl to port.\n"); - return -EIO; - } - return 0; -} - /** * lpfc_sli4_hba_setup - SLI4 device intialization PCI function * @phba: Pointer to HBA context object. @@ -6077,8 +5923,6 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) else phba->hba_flag &= ~HBA_FIP_SUPPORT; - phba->hba_flag &= ~HBA_FCP_IOQ_FLUSH; - if (phba->sli_rev != LPFC_SLI_REV4) { lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, "0376 READ_REV Error. SLI Level %d " @@ -6219,6 +6063,8 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) "rc = x%x\n", rc); goto out_free_mbox; } + /* update physical xri mappings in the scsi buffers */ + lpfc_scsi_buf_update(phba); /* Read the port's service parameters. */ rc = lpfc_read_sparam(phba, mboxq, vport->vpi); @@ -6259,26 +6105,28 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) fc_host_node_name(shost) = wwn_to_u64(vport->fc_nodename.u.wwn); fc_host_port_name(shost) = wwn_to_u64(vport->fc_portname.u.wwn); - /* update host els and scsi xri-sgl sizes and mappings */ - rc = lpfc_sli4_xri_sgl_update(phba); - if (unlikely(rc)) { - lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, - "1400 Failed to update xri-sgl size and " - "mapping: %d\n", rc); - goto out_free_mbox; - } - - /* register the els sgl pool to the port */ - rc = lpfc_sli4_repost_els_sgl_list(phba); - if (unlikely(rc)) { - lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, - "0582 Error %d during els sgl post " - "operation\n", rc); - rc = -ENODEV; - goto out_free_mbox; + /* Register SGL pool to the device using non-embedded mailbox command */ + if (!phba->sli4_hba.extents_in_use) { + rc = lpfc_sli4_post_els_sgl_list(phba); + if (unlikely(rc)) { + lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, + "0582 Error %d during els sgl post " + "operation\n", rc); + rc = -ENODEV; + goto out_free_mbox; + } + } else { + rc = lpfc_sli4_post_els_sgl_list_ext(phba); + if (unlikely(rc)) { + lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, + "2560 Error %d during els sgl post " + "operation\n", rc); + rc = -ENODEV; + goto out_free_mbox; + } } - /* register the allocated scsi sgl pool to the port */ + /* Register SCSI SGL pool to the device */ rc = lpfc_sli4_repost_scsi_sgl_list(phba); if (unlikely(rc)) { lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, @@ -7212,19 +7060,14 @@ lpfc_sli_issue_mbox_s4(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, if (rc != MBX_SUCCESS) lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_SLI, "(%d):2541 Mailbox command x%x " - "(x%x/x%x) failure: " - "mqe_sta: x%x mcqe_sta: x%x/x%x " - "Data: x%x x%x\n,", + "(x%x/x%x) cannot issue Data: " + "x%x x%x\n", mboxq->vport ? mboxq->vport->vpi : 0, mboxq->u.mb.mbxCommand, lpfc_sli_config_mbox_subsys_get(phba, mboxq), lpfc_sli_config_mbox_opcode_get(phba, mboxq), - bf_get(lpfc_mqe_status, &mboxq->u.mqe), - bf_get(lpfc_mcqe_status, &mboxq->mcqe), - bf_get(lpfc_mcqe_ext_status, - &mboxq->mcqe), psli->sli_flag, flag); return rc; } else if (flag == MBX_POLL) { @@ -7243,22 +7086,18 @@ lpfc_sli_issue_mbox_s4(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, /* Successfully blocked, now issue sync mbox cmd */ rc = lpfc_sli4_post_sync_mbox(phba, mboxq); if (rc != MBX_SUCCESS) - lpfc_printf_log(phba, KERN_WARNING, + lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, - "(%d):2597 Sync Mailbox command " - "x%x (x%x/x%x) failure: " - "mqe_sta: x%x mcqe_sta: x%x/x%x " - "Data: x%x x%x\n,", - mboxq->vport ? mboxq->vport->vpi : 0, + "(%d):2597 Mailbox command " + "x%x (x%x/x%x) cannot issue " + "Data: x%x x%x\n", + mboxq->vport ? + mboxq->vport->vpi : 0, mboxq->u.mb.mbxCommand, lpfc_sli_config_mbox_subsys_get(phba, mboxq), lpfc_sli_config_mbox_opcode_get(phba, mboxq), - bf_get(lpfc_mqe_status, &mboxq->u.mqe), - bf_get(lpfc_mcqe_status, &mboxq->mcqe), - bf_get(lpfc_mcqe_ext_status, - &mboxq->mcqe), psli->sli_flag, flag); /* Unblock the async mailbox posting afterward */ lpfc_sli4_async_mbox_unblock(phba); @@ -7873,10 +7712,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, switch (iocbq->iocb.ulpCommand) { case CMD_ELS_REQUEST64_CR: - if (iocbq->iocb_flag & LPFC_IO_LIBDFC) - ndlp = iocbq->context_un.ndlp; - else - ndlp = (struct lpfc_nodelist *)iocbq->context1; + ndlp = (struct lpfc_nodelist *)iocbq->context1; if (!iocbq->iocb.ulpLe) { lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "2007 Only Limited Edition cmd Format" @@ -7915,13 +7751,9 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, bf_set(els_req64_sp, &wqe->els_req, 1); bf_set(els_req64_sid, &wqe->els_req, iocbq->vport->fc_myDID); - if ((*pcmd == ELS_CMD_FLOGI) && - !(phba->fc_topology == - LPFC_TOPOLOGY_LOOP)) - bf_set(els_req64_sid, &wqe->els_req, 0); bf_set(wqe_ct, &wqe->els_req.wqe_com, 1); bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com, - phba->vpi_ids[iocbq->vport->vpi]); + phba->vpi_ids[phba->pport->vpi]); } else if (pcmd && iocbq->context1) { bf_set(wqe_ct, &wqe->els_req.wqe_com, 0); bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com, @@ -8076,25 +7908,11 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, /* words0-2 BDE memcpy */ /* word3 iocb=iotag32 wqe=response_payload_len */ wqe->xmit_els_rsp.response_payload_len = xmit_len; - /* word4 */ - wqe->xmit_els_rsp.word4 = 0; + /* word4 iocb=did wge=rsvd. */ + wqe->xmit_els_rsp.rsvd4 = 0; /* word5 iocb=rsvd wge=did */ bf_set(wqe_els_did, &wqe->xmit_els_rsp.wqe_dest, - iocbq->iocb.un.xseq64.xmit_els_remoteID); - - if_type = bf_get(lpfc_sli_intf_if_type, - &phba->sli4_hba.sli_intf); - if (if_type == LPFC_SLI_INTF_IF_TYPE_2) { - if (iocbq->vport->fc_flag & FC_PT2PT) { - bf_set(els_rsp64_sp, &wqe->xmit_els_rsp, 1); - bf_set(els_rsp64_sid, &wqe->xmit_els_rsp, - iocbq->vport->fc_myDID); - if (iocbq->vport->fc_myDID == Fabric_DID) { - bf_set(wqe_els_did, - &wqe->xmit_els_rsp.wqe_dest, 0); - } - } - } + iocbq->iocb.un.elsreq64.remoteID); bf_set(wqe_ct, &wqe->xmit_els_rsp.wqe_com, ((iocbq->iocb.ulpCt_h << 1) | iocbq->iocb.ulpCt_l)); bf_set(wqe_pu, &wqe->xmit_els_rsp.wqe_com, iocbq->iocb.ulpPU); @@ -8114,11 +7932,11 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, pcmd = (uint32_t *) (((struct lpfc_dmabuf *) iocbq->context2)->virt); if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) { - bf_set(els_rsp64_sp, &wqe->xmit_els_rsp, 1); - bf_set(els_rsp64_sid, &wqe->xmit_els_rsp, + bf_set(els_req64_sp, &wqe->els_req, 1); + bf_set(els_req64_sid, &wqe->els_req, iocbq->vport->fc_myDID); - bf_set(wqe_ct, &wqe->xmit_els_rsp.wqe_com, 1); - bf_set(wqe_ctxt_tag, &wqe->xmit_els_rsp.wqe_com, + bf_set(wqe_ct, &wqe->els_req.wqe_com, 1); + bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com, phba->vpi_ids[phba->pport->vpi]); } command_type = OTHER_COMMAND; @@ -13262,7 +13080,9 @@ lpfc_sli4_alloc_xri(struct lpfc_hba *phba) } else { set_bit(xri, phba->sli4_hba.xri_bmask); phba->sli4_hba.max_cfg_param.xri_used++; + phba->sli4_hba.xri_count++; } + spin_unlock_irq(&phba->hbalock); return xri; } @@ -13278,6 +13098,7 @@ void __lpfc_sli4_free_xri(struct lpfc_hba *phba, int xri) { if (test_and_clear_bit(xri, phba->sli4_hba.xri_bmask)) { + phba->sli4_hba.xri_count--; phba->sli4_hba.max_cfg_param.xri_used--; } } @@ -13313,45 +13134,46 @@ lpfc_sli4_next_xritag(struct lpfc_hba *phba) uint16_t xri_index; xri_index = lpfc_sli4_alloc_xri(phba); - if (xri_index == NO_XRI) - lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, - "2004 Failed to allocate XRI.last XRITAG is %d" - " Max XRI is %d, Used XRI is %d\n", - xri_index, - phba->sli4_hba.max_cfg_param.max_xri, - phba->sli4_hba.max_cfg_param.xri_used); - return xri_index; + if (xri_index != NO_XRI) + return xri_index; + + lpfc_printf_log(phba, KERN_ERR, LOG_SLI, + "2004 Failed to allocate XRI.last XRITAG is %d" + " Max XRI is %d, Used XRI is %d\n", + xri_index, + phba->sli4_hba.max_cfg_param.max_xri, + phba->sli4_hba.max_cfg_param.xri_used); + return NO_XRI; } /** * lpfc_sli4_post_els_sgl_list - post a block of ELS sgls to the port. * @phba: pointer to lpfc hba data structure. - * @post_sgl_list: pointer to els sgl entry list. - * @count: number of els sgl entries on the list. * * This routine is invoked to post a block of driver's sgl pages to the * HBA using non-embedded mailbox command. No Lock is held. This routine * is only called when the driver is loading and after all IO has been * stopped. **/ -static int -lpfc_sli4_post_els_sgl_list(struct lpfc_hba *phba, - struct list_head *post_sgl_list, - int post_cnt) +int +lpfc_sli4_post_els_sgl_list(struct lpfc_hba *phba) { - struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL; + struct lpfc_sglq *sglq_entry; struct lpfc_mbx_post_uembed_sgl_page1 *sgl; struct sgl_page_pairs *sgl_pg_pairs; void *viraddr; LPFC_MBOXQ_t *mbox; uint32_t reqlen, alloclen, pg_pairs; uint32_t mbox_tmo; - uint16_t xritag_start = 0; - int rc = 0; + uint16_t xritag_start = 0, lxri = 0; + int els_xri_cnt, rc = 0; uint32_t shdr_status, shdr_add_status; union lpfc_sli4_cfg_shdr *shdr; - reqlen = phba->sli4_hba.els_xri_cnt * sizeof(struct sgl_page_pairs) + + /* The number of sgls to be posted */ + els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba); + + reqlen = els_xri_cnt * sizeof(struct sgl_page_pairs) + sizeof(union lpfc_sli4_cfg_shdr) + sizeof(uint32_t); if (reqlen > SLI4_PAGE_SIZE) { lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, @@ -13381,8 +13203,25 @@ lpfc_sli4_post_els_sgl_list(struct lpfc_hba *phba, sgl = (struct lpfc_mbx_post_uembed_sgl_page1 *)viraddr; sgl_pg_pairs = &sgl->sgl_pg_pairs; - pg_pairs = 0; - list_for_each_entry_safe(sglq_entry, sglq_next, post_sgl_list, list) { + for (pg_pairs = 0; pg_pairs < els_xri_cnt; pg_pairs++) { + sglq_entry = phba->sli4_hba.lpfc_els_sgl_array[pg_pairs]; + + /* + * Assign the sglq a physical xri only if the driver has not + * initialized those resources. A port reset only needs + * the sglq's posted. + */ + if (bf_get(lpfc_xri_rsrc_rdy, &phba->sli4_hba.sli4_flags) != + LPFC_XRI_RSRC_RDY) { + lxri = lpfc_sli4_next_xritag(phba); + if (lxri == NO_XRI) { + lpfc_sli4_mbox_cmd_free(phba, mbox); + return -ENOMEM; + } + sglq_entry->sli4_lxritag = lxri; + sglq_entry->sli4_xritag = phba->sli4_hba.xri_ids[lxri]; + } + /* Set up the sge entry */ sgl_pg_pairs->sgl_pg0_addr_lo = cpu_to_le32(putPaddrLow(sglq_entry->phys)); @@ -13397,12 +13236,11 @@ lpfc_sli4_post_els_sgl_list(struct lpfc_hba *phba, if (pg_pairs == 0) xritag_start = sglq_entry->sli4_xritag; sgl_pg_pairs++; - pg_pairs++; } /* Complete initialization and perform endian conversion. */ bf_set(lpfc_post_sgl_pages_xri, sgl, xritag_start); - bf_set(lpfc_post_sgl_pages_xricnt, sgl, phba->sli4_hba.els_xri_cnt); + bf_set(lpfc_post_sgl_pages_xricnt, sgl, els_xri_cnt); sgl->word0 = cpu_to_le32(sgl->word0); if (!phba->sli4_hba.intr_enable) rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); @@ -13422,6 +13260,183 @@ lpfc_sli4_post_els_sgl_list(struct lpfc_hba *phba, shdr_status, shdr_add_status, rc); rc = -ENXIO; } + + if (rc == 0) + bf_set(lpfc_xri_rsrc_rdy, &phba->sli4_hba.sli4_flags, + LPFC_XRI_RSRC_RDY); + return rc; +} + +/** + * lpfc_sli4_post_els_sgl_list_ext - post a block of ELS sgls to the port. + * @phba: pointer to lpfc hba data structure. + * + * This routine is invoked to post a block of driver's sgl pages to the + * HBA using non-embedded mailbox command. No Lock is held. This routine + * is only called when the driver is loading and after all IO has been + * stopped. + **/ +int +lpfc_sli4_post_els_sgl_list_ext(struct lpfc_hba *phba) +{ + struct lpfc_sglq *sglq_entry; + struct lpfc_mbx_post_uembed_sgl_page1 *sgl; + struct sgl_page_pairs *sgl_pg_pairs; + void *viraddr; + LPFC_MBOXQ_t *mbox; + uint32_t reqlen, alloclen, index; + uint32_t mbox_tmo; + uint16_t rsrc_start, rsrc_size, els_xri_cnt, post_els_xri_cnt; + uint16_t xritag_start = 0, lxri = 0; + struct lpfc_rsrc_blks *rsrc_blk; + int cnt, ttl_cnt, rc = 0; + int loop_cnt; + uint32_t shdr_status, shdr_add_status; + union lpfc_sli4_cfg_shdr *shdr; + + /* The number of sgls to be posted */ + els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba); + + reqlen = els_xri_cnt * sizeof(struct sgl_page_pairs) + + sizeof(union lpfc_sli4_cfg_shdr) + sizeof(uint32_t); + if (reqlen > SLI4_PAGE_SIZE) { + lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, + "2989 Block sgl registration required DMA " + "size (%d) great than a page\n", reqlen); + return -ENOMEM; + } + + cnt = 0; + ttl_cnt = 0; + post_els_xri_cnt = els_xri_cnt; + list_for_each_entry(rsrc_blk, &phba->sli4_hba.lpfc_xri_blk_list, + list) { + rsrc_start = rsrc_blk->rsrc_start; + rsrc_size = rsrc_blk->rsrc_size; + + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, + "3014 Working ELS Extent start %d, cnt %d\n", + rsrc_start, rsrc_size); + + loop_cnt = min(post_els_xri_cnt, rsrc_size); + if (loop_cnt < post_els_xri_cnt) { + post_els_xri_cnt -= loop_cnt; + ttl_cnt += loop_cnt; + } else + ttl_cnt += post_els_xri_cnt; + + mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!mbox) + return -ENOMEM; + /* + * Allocate DMA memory and set up the non-embedded mailbox + * command. + */ + alloclen = lpfc_sli4_config(phba, mbox, + LPFC_MBOX_SUBSYSTEM_FCOE, + LPFC_MBOX_OPCODE_FCOE_POST_SGL_PAGES, + reqlen, LPFC_SLI4_MBX_NEMBED); + if (alloclen < reqlen) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "2987 Allocated DMA memory size (%d) " + "is less than the requested DMA memory " + "size (%d)\n", alloclen, reqlen); + lpfc_sli4_mbox_cmd_free(phba, mbox); + return -ENOMEM; + } + + /* Set up the SGL pages in the non-embedded DMA pages */ + viraddr = mbox->sge_array->addr[0]; + sgl = (struct lpfc_mbx_post_uembed_sgl_page1 *)viraddr; + sgl_pg_pairs = &sgl->sgl_pg_pairs; + + /* + * The starting resource may not begin at zero. Control + * the loop variants via the block resource parameters, + * but handle the sge pointers with a zero-based index + * that doesn't get reset per loop pass. + */ + for (index = rsrc_start; + index < rsrc_start + loop_cnt; + index++) { + sglq_entry = phba->sli4_hba.lpfc_els_sgl_array[cnt]; + + /* + * Assign the sglq a physical xri only if the driver + * has not initialized those resources. A port reset + * only needs the sglq's posted. + */ + if (bf_get(lpfc_xri_rsrc_rdy, + &phba->sli4_hba.sli4_flags) != + LPFC_XRI_RSRC_RDY) { + lxri = lpfc_sli4_next_xritag(phba); + if (lxri == NO_XRI) { + lpfc_sli4_mbox_cmd_free(phba, mbox); + rc = -ENOMEM; + goto err_exit; + } + sglq_entry->sli4_lxritag = lxri; + sglq_entry->sli4_xritag = + phba->sli4_hba.xri_ids[lxri]; + } + + /* Set up the sge entry */ + sgl_pg_pairs->sgl_pg0_addr_lo = + cpu_to_le32(putPaddrLow(sglq_entry->phys)); + sgl_pg_pairs->sgl_pg0_addr_hi = + cpu_to_le32(putPaddrHigh(sglq_entry->phys)); + sgl_pg_pairs->sgl_pg1_addr_lo = + cpu_to_le32(putPaddrLow(0)); + sgl_pg_pairs->sgl_pg1_addr_hi = + cpu_to_le32(putPaddrHigh(0)); + + /* Track the starting physical XRI for the mailbox. */ + if (index == rsrc_start) + xritag_start = sglq_entry->sli4_xritag; + sgl_pg_pairs++; + cnt++; + } + + /* Complete initialization and perform endian conversion. */ + rsrc_blk->rsrc_used += loop_cnt; + bf_set(lpfc_post_sgl_pages_xri, sgl, xritag_start); + bf_set(lpfc_post_sgl_pages_xricnt, sgl, loop_cnt); + sgl->word0 = cpu_to_le32(sgl->word0); + + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, + "3015 Post ELS Extent SGL, start %d, " + "cnt %d, used %d\n", + xritag_start, loop_cnt, rsrc_blk->rsrc_used); + if (!phba->sli4_hba.intr_enable) + rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); + else { + mbox_tmo = lpfc_mbox_tmo_val(phba, mbox); + rc = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo); + } + shdr = (union lpfc_sli4_cfg_shdr *) &sgl->cfg_shdr; + shdr_status = bf_get(lpfc_mbox_hdr_status, + &shdr->response); + shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, + &shdr->response); + if (rc != MBX_TIMEOUT) + lpfc_sli4_mbox_cmd_free(phba, mbox); + if (shdr_status || shdr_add_status || rc) { + lpfc_printf_log(phba, KERN_ERR, LOG_SLI, + "2988 POST_SGL_BLOCK mailbox " + "command failed status x%x " + "add_status x%x mbx status x%x\n", + shdr_status, shdr_add_status, rc); + rc = -ENXIO; + goto err_exit; + } + if (ttl_cnt >= els_xri_cnt) + break; + } + + err_exit: + if (rc == 0) + bf_set(lpfc_xri_rsrc_rdy, &phba->sli4_hba.sli4_flags, + LPFC_XRI_RSRC_RDY); return rc; } @@ -13437,9 +13452,8 @@ lpfc_sli4_post_els_sgl_list(struct lpfc_hba *phba, * **/ int -lpfc_sli4_post_scsi_sgl_block(struct lpfc_hba *phba, - struct list_head *sblist, - int count) +lpfc_sli4_post_scsi_sgl_block(struct lpfc_hba *phba, struct list_head *sblist, + int cnt) { struct lpfc_scsi_buf *psb; struct lpfc_mbx_post_uembed_sgl_page1 *sgl; @@ -13455,7 +13469,7 @@ lpfc_sli4_post_scsi_sgl_block(struct lpfc_hba *phba, union lpfc_sli4_cfg_shdr *shdr; /* Calculate the requested length of the dma memory */ - reqlen = count * sizeof(struct sgl_page_pairs) + + reqlen = cnt * sizeof(struct sgl_page_pairs) + sizeof(union lpfc_sli4_cfg_shdr) + sizeof(uint32_t); if (reqlen > SLI4_PAGE_SIZE) { lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, @@ -13538,6 +13552,169 @@ lpfc_sli4_post_scsi_sgl_block(struct lpfc_hba *phba, return rc; } +/** + * lpfc_sli4_post_scsi_sgl_blk_ext - post a block of scsi sgls to the port. + * @phba: pointer to lpfc hba data structure. + * @sblist: pointer to scsi buffer list. + * @count: number of scsi buffers on the list. + * + * This routine is invoked to post a block of @count scsi sgl pages from a + * SCSI buffer list @sblist to the HBA using non-embedded mailbox command. + * No Lock is held. + * + **/ +int +lpfc_sli4_post_scsi_sgl_blk_ext(struct lpfc_hba *phba, struct list_head *sblist, + int cnt) +{ + struct lpfc_scsi_buf *psb = NULL; + struct lpfc_mbx_post_uembed_sgl_page1 *sgl; + struct sgl_page_pairs *sgl_pg_pairs; + void *viraddr; + LPFC_MBOXQ_t *mbox; + uint32_t reqlen, alloclen, pg_pairs; + uint32_t mbox_tmo; + uint16_t xri_start = 0, scsi_xri_start; + uint16_t rsrc_range; + int rc = 0, avail_cnt; + uint32_t shdr_status, shdr_add_status; + dma_addr_t pdma_phys_bpl1; + union lpfc_sli4_cfg_shdr *shdr; + struct lpfc_rsrc_blks *rsrc_blk; + uint32_t xri_cnt = 0; + + /* Calculate the total requested length of the dma memory */ + reqlen = cnt * sizeof(struct sgl_page_pairs) + + sizeof(union lpfc_sli4_cfg_shdr) + sizeof(uint32_t); + if (reqlen > SLI4_PAGE_SIZE) { + lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, + "2932 Block sgl registration required DMA " + "size (%d) great than a page\n", reqlen); + return -ENOMEM; + } + + /* + * The use of extents requires the driver to post the sgl headers + * in multiple postings to meet the contiguous resource assignment. + */ + psb = list_prepare_entry(psb, sblist, list); + scsi_xri_start = phba->sli4_hba.scsi_xri_start; + list_for_each_entry(rsrc_blk, &phba->sli4_hba.lpfc_xri_blk_list, + list) { + rsrc_range = rsrc_blk->rsrc_start + rsrc_blk->rsrc_size; + if (rsrc_range < scsi_xri_start) + continue; + else if (rsrc_blk->rsrc_used >= rsrc_blk->rsrc_size) + continue; + else + avail_cnt = rsrc_blk->rsrc_size - rsrc_blk->rsrc_used; + + reqlen = (avail_cnt * sizeof(struct sgl_page_pairs)) + + sizeof(union lpfc_sli4_cfg_shdr) + sizeof(uint32_t); + /* + * Allocate DMA memory and set up the non-embedded mailbox + * command. The mbox is used to post an SGL page per loop + * but the DMA memory has a use-once semantic so the mailbox + * is used and freed per loop pass. + */ + mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!mbox) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "2933 Failed to allocate mbox cmd " + "memory\n"); + return -ENOMEM; + } + alloclen = lpfc_sli4_config(phba, mbox, + LPFC_MBOX_SUBSYSTEM_FCOE, + LPFC_MBOX_OPCODE_FCOE_POST_SGL_PAGES, + reqlen, + LPFC_SLI4_MBX_NEMBED); + if (alloclen < reqlen) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "2934 Allocated DMA memory size (%d) " + "is less than the requested DMA memory " + "size (%d)\n", alloclen, reqlen); + lpfc_sli4_mbox_cmd_free(phba, mbox); + return -ENOMEM; + } + + /* Get the first SGE entry from the non-embedded DMA memory */ + viraddr = mbox->sge_array->addr[0]; + + /* Set up the SGL pages in the non-embedded DMA pages */ + sgl = (struct lpfc_mbx_post_uembed_sgl_page1 *)viraddr; + sgl_pg_pairs = &sgl->sgl_pg_pairs; + + /* pg_pairs tracks posted SGEs per loop iteration. */ + pg_pairs = 0; + list_for_each_entry_continue(psb, sblist, list) { + /* Set up the sge entry */ + sgl_pg_pairs->sgl_pg0_addr_lo = + cpu_to_le32(putPaddrLow(psb->dma_phys_bpl)); + sgl_pg_pairs->sgl_pg0_addr_hi = + cpu_to_le32(putPaddrHigh(psb->dma_phys_bpl)); + if (phba->cfg_sg_dma_buf_size > SGL_PAGE_SIZE) + pdma_phys_bpl1 = psb->dma_phys_bpl + + SGL_PAGE_SIZE; + else + pdma_phys_bpl1 = 0; + sgl_pg_pairs->sgl_pg1_addr_lo = + cpu_to_le32(putPaddrLow(pdma_phys_bpl1)); + sgl_pg_pairs->sgl_pg1_addr_hi = + cpu_to_le32(putPaddrHigh(pdma_phys_bpl1)); + /* Keep the first xri for this extent. */ + if (pg_pairs == 0) + xri_start = psb->cur_iocbq.sli4_xritag; + sgl_pg_pairs++; + pg_pairs++; + xri_cnt++; + + /* + * Track two exit conditions - the loop has constructed + * all of the caller's SGE pairs or all available + * resource IDs in this extent are consumed. + */ + if ((xri_cnt == cnt) || (pg_pairs >= avail_cnt)) + break; + } + rsrc_blk->rsrc_used += pg_pairs; + bf_set(lpfc_post_sgl_pages_xri, sgl, xri_start); + bf_set(lpfc_post_sgl_pages_xricnt, sgl, pg_pairs); + + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, + "3016 Post SCSI Extent SGL, start %d, cnt %d " + "blk use %d\n", + xri_start, pg_pairs, rsrc_blk->rsrc_used); + /* Perform endian conversion if necessary */ + sgl->word0 = cpu_to_le32(sgl->word0); + if (!phba->sli4_hba.intr_enable) + rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); + else { + mbox_tmo = lpfc_mbox_tmo_val(phba, mbox); + rc = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo); + } + shdr = (union lpfc_sli4_cfg_shdr *) &sgl->cfg_shdr; + shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); + shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, + &shdr->response); + if (rc != MBX_TIMEOUT) + lpfc_sli4_mbox_cmd_free(phba, mbox); + if (shdr_status || shdr_add_status || rc) { + lpfc_printf_log(phba, KERN_ERR, LOG_SLI, + "2935 POST_SGL_BLOCK mailbox command " + "failed status x%x add_status x%x " + "mbx status x%x\n", + shdr_status, shdr_add_status, rc); + return -ENXIO; + } + + /* Post only what is requested. */ + if (xri_cnt >= cnt) + break; + } + return rc; +} + /** * lpfc_fc_frame_check - Check that this frame is a valid frame to handle * @phba: pointer to lpfc_hba struct that the frame was received on @@ -13662,13 +13839,8 @@ lpfc_fc_frame_to_vport(struct lpfc_hba *phba, struct fc_frame_header *fc_hdr, uint32_t did = (fc_hdr->fh_d_id[0] << 16 | fc_hdr->fh_d_id[1] << 8 | fc_hdr->fh_d_id[2]); - if (did == Fabric_DID) return phba->pport; - if ((phba->pport->fc_flag & FC_PT2PT) && - !(phba->link_state == LPFC_HBA_READY)) - return phba->pport; - vports = lpfc_create_vport_work_array(phba); if (vports != NULL) for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { @@ -13961,6 +14133,7 @@ lpfc_sli4_xri_inrange(struct lpfc_hba *phba, return NO_XRI; } + /** * lpfc_sli4_seq_abort_rsp - bls rsp to sequence abort * @phba: Pointer to HBA context object. @@ -13975,7 +14148,7 @@ lpfc_sli4_seq_abort_rsp(struct lpfc_hba *phba, { struct lpfc_iocbq *ctiocb = NULL; struct lpfc_nodelist *ndlp; - uint16_t oxid, rxid, xri, lxri; + uint16_t oxid, rxid; uint32_t sid, fctl; IOCB_t *icmd; int rc; @@ -13994,6 +14167,8 @@ lpfc_sli4_seq_abort_rsp(struct lpfc_hba *phba, "SID:x%x\n", oxid, sid); return; } + if (lpfc_sli4_xri_inrange(phba, rxid)) + lpfc_set_rrq_active(phba, ndlp, rxid, oxid, 0); /* Allocate buffer for rsp iocb */ ctiocb = lpfc_sli_get_iocbq(phba); @@ -14024,24 +14199,13 @@ lpfc_sli4_seq_abort_rsp(struct lpfc_hba *phba, ctiocb->sli4_lxritag = NO_XRI; ctiocb->sli4_xritag = NO_XRI; - if (fctl & FC_FC_EX_CTX) - /* Exchange responder sent the abort so we - * own the oxid. - */ - xri = oxid; - else - xri = rxid; - lxri = lpfc_sli4_xri_inrange(phba, xri); - if (lxri != NO_XRI) - lpfc_set_rrq_active(phba, ndlp, lxri, - (xri == oxid) ? rxid : oxid, 0); /* If the oxid maps to the FCP XRI range or if it is out of range, * send a BLS_RJT. The driver no longer has that exchange. * Override the IOCB for a BA_RJT. */ - if (xri > (phba->sli4_hba.max_cfg_param.max_xri + + if (oxid > (phba->sli4_hba.max_cfg_param.max_xri + phba->sli4_hba.max_cfg_param.xri_base) || - xri > (lpfc_sli4_get_els_iocb_cnt(phba) + + oxid > (lpfc_sli4_get_els_iocb_cnt(phba) + phba->sli4_hba.max_cfg_param.xri_base)) { icmd->un.xseq64.w5.hcsw.Rctl = FC_RCTL_BA_RJT; bf_set(lpfc_vndr_code, &icmd->un.bls_rsp, 0); @@ -14213,15 +14377,7 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) /* Initialize the first IOCB. */ first_iocbq->iocb.unsli3.rcvsli3.acc_len = 0; first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS; - - /* Check FC Header to see what TYPE of frame we are rcv'ing */ - if (sli4_type_from_fc_hdr(fc_hdr) == FC_TYPE_ELS) { - first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_ELS64_CX; - first_iocbq->iocb.un.rcvels.parmRo = - sli4_did_from_fc_hdr(fc_hdr); - first_iocbq->iocb.ulpPU = PARM_NPIV_DID; - } else - first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX; + first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX; first_iocbq->iocb.ulpContext = NO_XRI; first_iocbq->iocb.unsli3.rcvsli3.ox_id = be16_to_cpu(fc_hdr->fh_ox_id); @@ -14351,7 +14507,6 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba, struct fc_frame_header *fc_hdr; struct lpfc_vport *vport; uint32_t fcfi; - uint32_t did; /* Process each received buffer */ fc_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt; @@ -14367,32 +14522,12 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba, else fcfi = bf_get(lpfc_rcqe_fcf_id, &dmabuf->cq_event.cqe.rcqe_cmpl); - vport = lpfc_fc_frame_to_vport(phba, fc_hdr, fcfi); - if (!vport) { + if (!vport || !(vport->vpi_state & LPFC_VPI_REGISTERED)) { /* throw out the frame */ lpfc_in_buf_free(phba, &dmabuf->dbuf); return; } - - /* d_id this frame is directed to */ - did = sli4_did_from_fc_hdr(fc_hdr); - - /* vport is registered unless we rcv a FLOGI directed to Fabric_DID */ - if (!(vport->vpi_state & LPFC_VPI_REGISTERED) && - (did != Fabric_DID)) { - /* - * Throw out the frame if we are not pt2pt. - * The pt2pt protocol allows for discovery frames - * to be received without a registered VPI. - */ - if (!(vport->fc_flag & FC_PT2PT) || - (phba->link_state == LPFC_HBA_READY)) { - lpfc_in_buf_free(phba, &dmabuf->dbuf); - return; - } - } - /* Handle the basic abort sequence (BA_ABTS) event */ if (fc_hdr->fh_r_ctl == FC_RCTL_BA_ABTS) { lpfc_sli4_handle_unsol_abort(vport, dmabuf); diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli.h b/trunk/drivers/scsi/lpfc/lpfc_sli.h index 2626f58c0747..3290b8e7ab65 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli.h +++ b/trunk/drivers/scsi/lpfc/lpfc_sli.h @@ -68,7 +68,7 @@ struct lpfc_iocbq { #define LPFC_EXCHANGE_BUSY 0x40 /* SLI4 hba reported XB in response */ #define LPFC_USE_FCPWQIDX 0x80 /* Submit to specified FCPWQ index */ #define DSS_SECURITY_OP 0x100 /* security IO */ -#define LPFC_IO_ON_TXCMPLQ 0x200 /* The IO is still on the TXCMPLQ */ +#define LPFC_IO_ON_Q 0x200 /* The IO is still on the TXCMPLQ */ #define LPFC_IO_DIF 0x400 /* T10 DIF IO */ #define LPFC_FIP_ELS_ID_MASK 0xc000 /* ELS_ID range 0-3, non-shifted mask */ diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli4.h b/trunk/drivers/scsi/lpfc/lpfc_sli4.h index a4a77080091b..c19d139618b7 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli4.h +++ b/trunk/drivers/scsi/lpfc/lpfc_sli4.h @@ -75,19 +75,11 @@ (fc_hdr)->fh_s_id[1] << 8 | \ (fc_hdr)->fh_s_id[2]) -#define sli4_did_from_fc_hdr(fc_hdr) \ - ((fc_hdr)->fh_d_id[0] << 16 | \ - (fc_hdr)->fh_d_id[1] << 8 | \ - (fc_hdr)->fh_d_id[2]) - #define sli4_fctl_from_fc_hdr(fc_hdr) \ ((fc_hdr)->fh_f_ctl[0] << 16 | \ (fc_hdr)->fh_f_ctl[1] << 8 | \ (fc_hdr)->fh_f_ctl[2]) -#define sli4_type_from_fc_hdr(fc_hdr) \ - ((fc_hdr)->fh_type) - #define LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT 12000 enum lpfc_sli4_queue_type { @@ -501,12 +493,14 @@ struct lpfc_sli4_hba { uint16_t next_rpi; uint16_t scsi_xri_max; uint16_t scsi_xri_cnt; - uint16_t els_xri_cnt; uint16_t scsi_xri_start; struct list_head lpfc_free_sgl_list; struct list_head lpfc_sgl_list; + struct lpfc_sglq **lpfc_els_sgl_array; struct list_head lpfc_abts_els_sgl_list; + struct lpfc_scsi_buf **lpfc_scsi_psb_array; struct list_head lpfc_abts_scsi_buf_list; + uint32_t total_sglq_bufs; struct lpfc_sglq **lpfc_sglq_active_list; struct list_head lpfc_rpi_hdr_list; unsigned long *rpi_bmask; @@ -515,6 +509,7 @@ struct lpfc_sli4_hba { struct list_head lpfc_rpi_blk_list; unsigned long *xri_bmask; uint16_t *xri_ids; + uint16_t xri_count; struct list_head lpfc_xri_blk_list; unsigned long *vfi_bmask; uint16_t *vfi_ids; @@ -619,7 +614,11 @@ int lpfc_sli4_post_sgl(struct lpfc_hba *, dma_addr_t, dma_addr_t, uint16_t); int lpfc_sli4_repost_scsi_sgl_list(struct lpfc_hba *); uint16_t lpfc_sli4_next_xritag(struct lpfc_hba *); int lpfc_sli4_post_async_mbox(struct lpfc_hba *); +int lpfc_sli4_post_els_sgl_list(struct lpfc_hba *phba); +int lpfc_sli4_post_els_sgl_list_ext(struct lpfc_hba *phba); int lpfc_sli4_post_scsi_sgl_block(struct lpfc_hba *, struct list_head *, int); +int lpfc_sli4_post_scsi_sgl_blk_ext(struct lpfc_hba *, struct list_head *, + int); struct lpfc_cq_event *__lpfc_sli4_cq_event_alloc(struct lpfc_hba *); struct lpfc_cq_event *lpfc_sli4_cq_event_alloc(struct lpfc_hba *); void __lpfc_sli4_cq_event_release(struct lpfc_hba *, struct lpfc_cq_event *); diff --git a/trunk/drivers/scsi/lpfc/lpfc_version.h b/trunk/drivers/scsi/lpfc/lpfc_version.h index 59c57a409981..25cefc254b76 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_version.h +++ b/trunk/drivers/scsi/lpfc/lpfc_version.h @@ -18,7 +18,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "8.3.31" +#define LPFC_DRIVER_VERSION "8.3.30" #define LPFC_DRIVER_NAME "lpfc" #define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp" #define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp" diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas.h b/trunk/drivers/scsi/megaraid/megaraid_sas.h index e8f892647681..e5f416f8042d 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas.h +++ b/trunk/drivers/scsi/megaraid/megaraid_sas.h @@ -33,9 +33,9 @@ /* * MegaRAID SAS Driver meta data */ -#define MEGASAS_VERSION "00.00.06.15-rc1" -#define MEGASAS_RELDATE "Mar. 19, 2012" -#define MEGASAS_EXT_VERSION "Mon. Mar. 19 17:00:00 PDT 2012" +#define MEGASAS_VERSION "00.00.06.14-rc1" +#define MEGASAS_RELDATE "Jan. 6, 2012" +#define MEGASAS_EXT_VERSION "Fri. Jan. 6 17:00:00 PDT 2012" /* * Device IDs diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas_base.c b/trunk/drivers/scsi/megaraid/megaraid_sas_base.c index dc27598785e5..8b300be44284 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/trunk/drivers/scsi/megaraid/megaraid_sas_base.c @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * FILE: megaraid_sas_base.c - * Version : v00.00.06.15-rc1 + * Version : v00.00.06.14-rc1 * * Authors: LSI Corporation * Sreenivas Bagalkote diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas_fp.c b/trunk/drivers/scsi/megaraid/megaraid_sas_fp.c index e3d251a2e26a..294abb0defa6 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/trunk/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -362,20 +362,15 @@ MR_BuildRaidContext(struct megasas_instance *instance, /* assume this IO needs the full row - we'll adjust if not true */ regSize = stripSize; - /* Check if we can send this I/O via FastPath */ - if (raid->capability.fpCapable) { - if (isRead) - io_info->fpOkForIo = (raid->capability.fpReadCapable && - ((num_strips == 1) || - raid->capability. - fpReadAcrossStripe)); - else - io_info->fpOkForIo = (raid->capability.fpWriteCapable && - ((num_strips == 1) || - raid->capability. - fpWriteAcrossStripe)); - } else + /* If IO spans more than 1 strip, fp is not possible + FP is not possible for writes on non-0 raid levels + FP is not possible if LD is not capable */ + if (num_strips > 1 || (!isRead && raid->level != 0) || + !raid->capability.fpCapable) { io_info->fpOkForIo = FALSE; + } else { + io_info->fpOkForIo = TRUE; + } if (numRows == 1) { /* single-strip IOs can always lock only the data needed */ diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas_fusion.c b/trunk/drivers/scsi/megaraid/megaraid_sas_fusion.c index a610cf1d4847..bfd87fab39aa 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/trunk/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -634,7 +634,9 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) fusion->reply_frames_desc_phys; IOCInitMessage->SystemRequestFrameBaseAddress = fusion->io_request_frames_phys; - IOCInitMessage->HostMSIxVectors = instance->msix_vectors; + /* Set to 0 for none or 1 MSI-X vectors */ + IOCInitMessage->HostMSIxVectors = (instance->msix_vectors > 0 ? + instance->msix_vectors : 0); init_frame = (struct megasas_init_frame *)cmd->frame; memset(init_frame, 0, MEGAMFI_FRAME_SIZE); diff --git a/trunk/drivers/scsi/mpt2sas/mpi/mpi2.h b/trunk/drivers/scsi/mpt2sas/mpi/mpi2.h index a80f3220c641..a01f0aa66f20 100644 --- a/trunk/drivers/scsi/mpt2sas/mpi/mpi2.h +++ b/trunk/drivers/scsi/mpt2sas/mpi/mpi2.h @@ -8,7 +8,7 @@ * scatter/gather formats. * Creation Date: June 21, 2006 * - * mpi2.h Version: 02.00.23 + * mpi2.h Version: 02.00.22 * * Version History * --------------- @@ -71,7 +71,6 @@ * 03-09-11 02.00.20 Bumped MPI2_HEADER_VERSION_UNIT. * 05-25-11 02.00.21 Bumped MPI2_HEADER_VERSION_UNIT. * 08-24-11 02.00.22 Bumped MPI2_HEADER_VERSION_UNIT. - * 11-18-11 02.00.23 Bumped MPI2_HEADER_VERSION_UNIT. * -------------------------------------------------------------------------- */ @@ -97,7 +96,7 @@ #define MPI2_VERSION_02_00 (0x0200) /* versioning for this MPI header set */ -#define MPI2_HEADER_VERSION_UNIT (0x17) +#define MPI2_HEADER_VERSION_UNIT (0x16) #define MPI2_HEADER_VERSION_DEV (0x00) #define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) #define MPI2_HEADER_VERSION_UNIT_SHIFT (8) @@ -481,7 +480,7 @@ typedef union _MPI2_REPLY_DESCRIPTORS_UNION MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR RAIDAcceleratorSuccess; U64 Words; } MPI2_REPLY_DESCRIPTORS_UNION, MPI2_POINTER PTR_MPI2_REPLY_DESCRIPTORS_UNION, -Mpi2ReplyDescriptorsUnion_t, MPI2_POINTER pMpi2ReplyDescriptorsUnion_t; + Mpi2ReplyDescriptorsUnion_t, MPI2_POINTER pMpi2ReplyDescriptorsUnion_t; diff --git a/trunk/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h b/trunk/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h index 737fa8cfb54a..3a023dad77a1 100644 --- a/trunk/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h +++ b/trunk/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h @@ -6,7 +6,7 @@ * Title: MPI Configuration messages and pages * Creation Date: November 10, 2006 * - * mpi2_cnfg.h Version: 02.00.22 + * mpi2_cnfg.h Version: 02.00.21 * * Version History * --------------- @@ -146,9 +146,7 @@ * Added SpinupFlags field containing a Disable Spin-up * bit to the MPI2_SAS_IOUNIT4_SPINUP_GROUP fields of * SAS IO Unit Page 4. - * 11-18-11 02.00.22 Added define MPI2_IOCPAGE6_CAP_FLAGS_4K_SECTORS_SUPPORT. - * Added UEFIVersion field to BIOS Page 1 and defined new - * BiosOptions bits. + * -------------------------------------------------------------------------- */ @@ -1133,10 +1131,9 @@ typedef struct _MPI2_CONFIG_PAGE_IOC_6 } MPI2_CONFIG_PAGE_IOC_6, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IOC_6, Mpi2IOCPage6_t, MPI2_POINTER pMpi2IOCPage6_t; -#define MPI2_IOCPAGE6_PAGEVERSION (0x05) +#define MPI2_IOCPAGE6_PAGEVERSION (0x04) /* defines for IOC Page 6 CapabilitiesFlags */ -#define MPI2_IOCPAGE6_CAP_FLAGS_4K_SECTORS_SUPPORT (0x00000020) #define MPI2_IOCPAGE6_CAP_FLAGS_RAID10_SUPPORT (0x00000010) #define MPI2_IOCPAGE6_CAP_FLAGS_RAID1_SUPPORT (0x00000008) #define MPI2_IOCPAGE6_CAP_FLAGS_RAID1E_SUPPORT (0x00000004) @@ -1207,29 +1204,24 @@ typedef struct _MPI2_CONFIG_PAGE_IOC_8 typedef struct _MPI2_CONFIG_PAGE_BIOS_1 { - MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */ - U32 BiosOptions; /* 0x04 */ - U32 IOCSettings; /* 0x08 */ - U32 Reserved1; /* 0x0C */ - U32 DeviceSettings; /* 0x10 */ - U16 NumberOfDevices; /* 0x14 */ - U16 UEFIVersion; /* 0x16 */ - U16 IOTimeoutBlockDevicesNonRM; /* 0x18 */ - U16 IOTimeoutSequential; /* 0x1A */ - U16 IOTimeoutOther; /* 0x1C */ - U16 IOTimeoutBlockDevicesRM; /* 0x1E */ + MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */ + U32 BiosOptions; /* 0x04 */ + U32 IOCSettings; /* 0x08 */ + U32 Reserved1; /* 0x0C */ + U32 DeviceSettings; /* 0x10 */ + U16 NumberOfDevices; /* 0x14 */ + U16 Reserved2; /* 0x16 */ + U16 IOTimeoutBlockDevicesNonRM; /* 0x18 */ + U16 IOTimeoutSequential; /* 0x1A */ + U16 IOTimeoutOther; /* 0x1C */ + U16 IOTimeoutBlockDevicesRM; /* 0x1E */ } MPI2_CONFIG_PAGE_BIOS_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_BIOS_1, Mpi2BiosPage1_t, MPI2_POINTER pMpi2BiosPage1_t; -#define MPI2_BIOSPAGE1_PAGEVERSION (0x05) +#define MPI2_BIOSPAGE1_PAGEVERSION (0x04) /* values for BIOS Page 1 BiosOptions field */ -#define MPI2_BIOSPAGE1_OPTIONS_MASK_UEFI_HII_REGISTRATION (0x00000006) -#define MPI2_BIOSPAGE1_OPTIONS_ENABLE_UEFI_HII (0x00000000) -#define MPI2_BIOSPAGE1_OPTIONS_DISABLE_UEFI_HII (0x00000002) -#define MPI2_BIOSPAGE1_OPTIONS_VERSION_CHECK_UEFI_HII (0x00000004) - -#define MPI2_BIOSPAGE1_OPTIONS_DISABLE_BIOS (0x00000001) +#define MPI2_BIOSPAGE1_OPTIONS_DISABLE_BIOS (0x00000001) /* values for BIOS Page 1 IOCSettings field */ #define MPI2_BIOSPAGE1_IOCSET_MASK_BOOT_PREFERENCE (0x00030000) @@ -1256,13 +1248,6 @@ typedef struct _MPI2_CONFIG_PAGE_BIOS_1 #define MPI2_BIOSPAGE1_DEVSET_DISABLE_NON_RM_LUN (0x00000002) #define MPI2_BIOSPAGE1_DEVSET_DISABLE_OTHER_LUN (0x00000001) -/* defines for BIOS Page 1 UEFIVersion field */ -#define MPI2_BIOSPAGE1_UEFI_VER_MAJOR_MASK (0xFF00) -#define MPI2_BIOSPAGE1_UEFI_VER_MAJOR_SHIFT (8) -#define MPI2_BIOSPAGE1_UEFI_VER_MINOR_MASK (0x00FF) -#define MPI2_BIOSPAGE1_UEFI_VER_MINOR_SHIFT (0) - - /* BIOS Page 2 */ @@ -2231,27 +2216,6 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_8 { -/* SAS IO Unit Page 16 */ - -typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT16 { - MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */ - U64 TimeStamp; /* 0x08 */ - U32 Reserved1; /* 0x10 */ - U32 Reserved2; /* 0x14 */ - U32 FastPathPendedRequests; /* 0x18 */ - U32 FastPathUnPendedRequests; /* 0x1C */ - U32 FastPathHostRequestStarts; /* 0x20 */ - U32 FastPathFirmwareRequestStarts; /* 0x24 */ - U32 FastPathHostCompletions; /* 0x28 */ - U32 FastPathFirmwareCompletions; /* 0x2C */ - U32 NonFastPathRequestStarts; /* 0x30 */ - U32 NonFastPathHostCompletions; /* 0x30 */ -} MPI2_CONFIG_PAGE_SASIOUNIT16, -MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT16, -Mpi2SasIOUnitPage16_t, MPI2_POINTER pMpi2SasIOUnitPage16_t; - -#define MPI2_SASIOUNITPAGE16_PAGEVERSION (0x00) - /**************************************************************************** * SAS Expander Config Pages diff --git a/trunk/drivers/scsi/mpt2sas/mpt2sas_base.c b/trunk/drivers/scsi/mpt2sas/mpt2sas_base.c index 6102ef2cb2d8..8a59a772fdf2 100644 --- a/trunk/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/trunk/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -699,11 +699,6 @@ _base_display_reply_info(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u16 ioc_status; mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); - if (unlikely(!mpi_reply)) { - printk(MPT2SAS_ERR_FMT "mpi_reply not valid at %s:%d/%s()!\n", - ioc->name, __FILE__, __LINE__, __func__); - return; - } ioc_status = le16_to_cpu(mpi_reply->IOCStatus); #ifdef CONFIG_SCSI_MPT2SAS_LOGGING if ((ioc_status & MPI2_IOCSTATUS_MASK) && @@ -935,18 +930,16 @@ _base_interrupt(int irq, void *bus_id) else if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_TARGETASSIST_SUCCESS) goto next; - if (smid) { + if (smid) cb_idx = _base_get_cb_idx(ioc, smid); - if ((likely(cb_idx < MPT_MAX_CALLBACKS)) - && (likely(mpt_callbacks[cb_idx] != NULL))) { - rc = mpt_callbacks[cb_idx](ioc, smid, - msix_index, reply); + if (smid && cb_idx != 0xFF) { + rc = mpt_callbacks[cb_idx](ioc, smid, msix_index, + reply); if (reply) - _base_display_reply_info(ioc, smid, - msix_index, reply); + _base_display_reply_info(ioc, smid, msix_index, + reply); if (rc) mpt2sas_base_free_smid(ioc, smid); - } } if (!smid) _base_async_event(ioc, msix_index, reply); @@ -3350,7 +3343,7 @@ _base_get_port_facts(struct MPT2SAS_ADAPTER *ioc, int port, int sleep_flag) } pfacts = &ioc->pfacts[port]; - memset(pfacts, 0, sizeof(struct mpt2sas_port_facts)); + memset(pfacts, 0, sizeof(Mpi2PortFactsReply_t)); pfacts->PortNumber = mpi_reply.PortNumber; pfacts->VP_ID = mpi_reply.VP_ID; pfacts->VF_ID = mpi_reply.VF_ID; @@ -3392,7 +3385,7 @@ _base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) } facts = &ioc->facts; - memset(facts, 0, sizeof(struct mpt2sas_facts)); + memset(facts, 0, sizeof(Mpi2IOCFactsReply_t)); facts->MsgVersion = le16_to_cpu(mpi_reply.MsgVersion); facts->HeaderVersion = le16_to_cpu(mpi_reply.HeaderVersion); facts->VP_ID = mpi_reply.VP_ID; @@ -4160,8 +4153,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) if (ioc->is_driver_loading) { if (ioc->is_warpdrive && ioc->manu_pg10.OEMIdentifier == 0x80) { - hide_flag = (u8) ( - le32_to_cpu(ioc->manu_pg10.OEMSpecificFlags0) & + hide_flag = (u8) (ioc->manu_pg10.OEMSpecificFlags0 & MFG_PAGE10_HIDE_SSDS_MASK); if (hide_flag != MFG_PAGE10_HIDE_SSDS_MASK) ioc->mfg_pg10_hide_flag = hide_flag; @@ -4270,7 +4262,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) goto out_free_resources; ioc->pfacts = kcalloc(ioc->facts.NumberOfPorts, - sizeof(struct mpt2sas_port_facts), GFP_KERNEL); + sizeof(Mpi2PortFactsReply_t), GFP_KERNEL); if (!ioc->pfacts) { r = -ENOMEM; goto out_free_resources; @@ -4287,6 +4279,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) goto out_free_resources; init_waitqueue_head(&ioc->reset_wq); + /* allocate memory pd handle bitmask list */ ioc->pd_handles_sz = (ioc->facts.MaxDevHandle / 8); if (ioc->facts.MaxDevHandle % 8) @@ -4297,12 +4290,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) r = -ENOMEM; goto out_free_resources; } - ioc->blocking_handles = kzalloc(ioc->pd_handles_sz, - GFP_KERNEL); - if (!ioc->blocking_handles) { - r = -ENOMEM; - goto out_free_resources; - } + ioc->fwfault_debug = mpt2sas_fwfault_debug; /* base internal command bits */ @@ -4389,7 +4377,6 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) if (ioc->is_warpdrive) kfree(ioc->reply_post_host_index); kfree(ioc->pd_handles); - kfree(ioc->blocking_handles); kfree(ioc->tm_cmds.reply); kfree(ioc->transport_cmds.reply); kfree(ioc->scsih_cmds.reply); @@ -4431,7 +4418,6 @@ mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc) if (ioc->is_warpdrive) kfree(ioc->reply_post_host_index); kfree(ioc->pd_handles); - kfree(ioc->blocking_handles); kfree(ioc->pfacts); kfree(ioc->ctl_cmds.reply); kfree(ioc->ctl_cmds.sense); diff --git a/trunk/drivers/scsi/mpt2sas/mpt2sas_base.h b/trunk/drivers/scsi/mpt2sas/mpt2sas_base.h index b6dd3a5de7f9..c7459fdc06cc 100644 --- a/trunk/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/trunk/drivers/scsi/mpt2sas/mpt2sas_base.h @@ -69,8 +69,8 @@ #define MPT2SAS_DRIVER_NAME "mpt2sas" #define MPT2SAS_AUTHOR "LSI Corporation " #define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" -#define MPT2SAS_DRIVER_VERSION "13.100.00.00" -#define MPT2SAS_MAJOR_VERSION 13 +#define MPT2SAS_DRIVER_VERSION "12.100.00.00" +#define MPT2SAS_MAJOR_VERSION 12 #define MPT2SAS_MINOR_VERSION 100 #define MPT2SAS_BUILD_VERSION 00 #define MPT2SAS_RELEASE_VERSION 00 @@ -720,7 +720,6 @@ typedef void (*MPT2SAS_FLUSH_RUNNING_CMDS)(struct MPT2SAS_ADAPTER *ioc); * @io_missing_delay: time for IO completed by fw when PDR enabled * @device_missing_delay: time for device missing by fw when PDR enabled * @sas_id : used for setting volume target IDs - * @blocking_handles: bitmask used to identify which devices need blocking * @pd_handles : bitmask for PD handles * @pd_handles_sz : size of pd_handle bitmask * @config_page_sz: config page size @@ -890,7 +889,7 @@ struct MPT2SAS_ADAPTER { u8 io_missing_delay; u16 device_missing_delay; int sas_id; - void *blocking_handles; + void *pd_handles; u16 pd_handles_sz; @@ -1059,8 +1058,7 @@ int mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle); void mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle); void mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address); -void mpt2sas_device_remove_by_sas_address(struct MPT2SAS_ADAPTER *ioc, - u64 sas_address); +void mpt2sas_device_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address); struct _sas_node *mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle); struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAPTER diff --git a/trunk/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/trunk/drivers/scsi/mpt2sas/mpt2sas_ctl.c index 49bdd2dc8452..3b9a28efea82 100644 --- a/trunk/drivers/scsi/mpt2sas/mpt2sas_ctl.c +++ b/trunk/drivers/scsi/mpt2sas/mpt2sas_ctl.c @@ -620,10 +620,11 @@ _ctl_set_task_mid(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command *karg, * @ioc: per adapter object * @karg - (struct mpt2_ioctl_command) * @mf - pointer to mf in user space + * @state - NON_BLOCKING or BLOCKING */ static long -_ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command karg, - void __user *mf) +_ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, + struct mpt2_ioctl_command karg, void __user *mf, enum block_state state) { MPI2RequestHeader_t *mpi_request = NULL, *request; MPI2DefaultReply_t *mpi_reply; @@ -646,6 +647,11 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command karg, issue_reset = 0; + if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex)) + return -EAGAIN; + else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) + return -ERESTARTSYS; + if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) { printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n", ioc->name, __func__); @@ -865,16 +871,8 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command karg, if (smp_request->PassthroughFlags & MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE) data = (u8 *)&smp_request->SGL; - else { - if (unlikely(data_out == NULL)) { - printk(KERN_ERR "failure at %s:%d/%s()!\n", - __FILE__, __LINE__, __func__); - mpt2sas_base_free_smid(ioc, smid); - ret = -EINVAL; - goto out; - } + else data = data_out; - } if (data[1] == 0x91 && (data[10] == 1 || data[10] == 2)) { ioc->ioc_link_reset_in_progress = 1; @@ -987,8 +985,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command karg, ret = -ENODATA; if ((mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST || mpi_request->Function == - MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH || - mpi_request->Function == MPI2_FUNCTION_SATA_PASSTHROUGH)) { + MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { printk(MPT2SAS_INFO_FMT "issue target reset: handle " "= (0x%04x)\n", ioc->name, le16_to_cpu(mpi_request->FunctionDependent1)); @@ -1016,24 +1013,27 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command karg, kfree(mpi_request); ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; + mutex_unlock(&ioc->ctl_cmds.mutex); return ret; } /** * _ctl_getiocinfo - main handler for MPT2IOCINFO opcode - * @ioc: per adapter object * @arg - user space buffer containing ioctl content */ static long -_ctl_getiocinfo(struct MPT2SAS_ADAPTER *ioc, void __user *arg) +_ctl_getiocinfo(void __user *arg) { struct mpt2_ioctl_iocinfo karg; + struct MPT2SAS_ADAPTER *ioc; if (copy_from_user(&karg, arg, sizeof(karg))) { printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); return -EFAULT; } + if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) + return -ENODEV; dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, __func__)); @@ -1069,19 +1069,21 @@ _ctl_getiocinfo(struct MPT2SAS_ADAPTER *ioc, void __user *arg) /** * _ctl_eventquery - main handler for MPT2EVENTQUERY opcode - * @ioc: per adapter object * @arg - user space buffer containing ioctl content */ static long -_ctl_eventquery(struct MPT2SAS_ADAPTER *ioc, void __user *arg) +_ctl_eventquery(void __user *arg) { struct mpt2_ioctl_eventquery karg; + struct MPT2SAS_ADAPTER *ioc; if (copy_from_user(&karg, arg, sizeof(karg))) { printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); return -EFAULT; } + if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) + return -ENODEV; dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, __func__)); @@ -1100,19 +1102,21 @@ _ctl_eventquery(struct MPT2SAS_ADAPTER *ioc, void __user *arg) /** * _ctl_eventenable - main handler for MPT2EVENTENABLE opcode - * @ioc: per adapter object * @arg - user space buffer containing ioctl content */ static long -_ctl_eventenable(struct MPT2SAS_ADAPTER *ioc, void __user *arg) +_ctl_eventenable(void __user *arg) { struct mpt2_ioctl_eventenable karg; + struct MPT2SAS_ADAPTER *ioc; if (copy_from_user(&karg, arg, sizeof(karg))) { printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); return -EFAULT; } + if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) + return -ENODEV; dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, __func__)); @@ -1138,13 +1142,13 @@ _ctl_eventenable(struct MPT2SAS_ADAPTER *ioc, void __user *arg) /** * _ctl_eventreport - main handler for MPT2EVENTREPORT opcode - * @ioc: per adapter object * @arg - user space buffer containing ioctl content */ static long -_ctl_eventreport(struct MPT2SAS_ADAPTER *ioc, void __user *arg) +_ctl_eventreport(void __user *arg) { struct mpt2_ioctl_eventreport karg; + struct MPT2SAS_ADAPTER *ioc; u32 number_bytes, max_events, max; struct mpt2_ioctl_eventreport __user *uarg = arg; @@ -1153,6 +1157,8 @@ _ctl_eventreport(struct MPT2SAS_ADAPTER *ioc, void __user *arg) __FILE__, __LINE__, __func__); return -EFAULT; } + if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) + return -ENODEV; dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, __func__)); @@ -1182,13 +1188,13 @@ _ctl_eventreport(struct MPT2SAS_ADAPTER *ioc, void __user *arg) /** * _ctl_do_reset - main handler for MPT2HARDRESET opcode - * @ioc: per adapter object * @arg - user space buffer containing ioctl content */ static long -_ctl_do_reset(struct MPT2SAS_ADAPTER *ioc, void __user *arg) +_ctl_do_reset(void __user *arg) { struct mpt2_ioctl_diag_reset karg; + struct MPT2SAS_ADAPTER *ioc; int retval; if (copy_from_user(&karg, arg, sizeof(karg))) { @@ -1196,6 +1202,8 @@ _ctl_do_reset(struct MPT2SAS_ADAPTER *ioc, void __user *arg) __FILE__, __LINE__, __func__); return -EFAULT; } + if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) + return -ENODEV; if (ioc->shost_recovery || ioc->pci_error_recovery || ioc->is_driver_loading) @@ -1284,13 +1292,13 @@ _ctl_btdh_search_raid_device(struct MPT2SAS_ADAPTER *ioc, /** * _ctl_btdh_mapping - main handler for MPT2BTDHMAPPING opcode - * @ioc: per adapter object * @arg - user space buffer containing ioctl content */ static long -_ctl_btdh_mapping(struct MPT2SAS_ADAPTER *ioc, void __user *arg) +_ctl_btdh_mapping(void __user *arg) { struct mpt2_ioctl_btdh_mapping karg; + struct MPT2SAS_ADAPTER *ioc; int rc; if (copy_from_user(&karg, arg, sizeof(karg))) { @@ -1298,6 +1306,8 @@ _ctl_btdh_mapping(struct MPT2SAS_ADAPTER *ioc, void __user *arg) __FILE__, __LINE__, __func__); return -EFAULT; } + if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) + return -ENODEV; dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__)); @@ -1566,16 +1576,17 @@ mpt2sas_enable_diag_buffer(struct MPT2SAS_ADAPTER *ioc, u8 bits_to_register) /** * _ctl_diag_register - application register with driver - * @ioc: per adapter object * @arg - user space buffer containing ioctl content + * @state - NON_BLOCKING or BLOCKING * * This will allow the driver to setup any required buffers that will be * needed by firmware to communicate with the driver. */ static long -_ctl_diag_register(struct MPT2SAS_ADAPTER *ioc, void __user *arg) +_ctl_diag_register(void __user *arg, enum block_state state) { struct mpt2_diag_register karg; + struct MPT2SAS_ADAPTER *ioc; long rc; if (copy_from_user(&karg, arg, sizeof(karg))) { @@ -1583,23 +1594,30 @@ _ctl_diag_register(struct MPT2SAS_ADAPTER *ioc, void __user *arg) __FILE__, __LINE__, __func__); return -EFAULT; } + if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) + return -ENODEV; + if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex)) + return -EAGAIN; + else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) + return -ERESTARTSYS; rc = _ctl_diag_register_2(ioc, &karg); + mutex_unlock(&ioc->ctl_cmds.mutex); return rc; } /** * _ctl_diag_unregister - application unregister with driver - * @ioc: per adapter object * @arg - user space buffer containing ioctl content * * This will allow the driver to cleanup any memory allocated for diag * messages and to free up any resources. */ static long -_ctl_diag_unregister(struct MPT2SAS_ADAPTER *ioc, void __user *arg) +_ctl_diag_unregister(void __user *arg) { struct mpt2_diag_unregister karg; + struct MPT2SAS_ADAPTER *ioc; void *request_data; dma_addr_t request_data_dma; u32 request_data_sz; @@ -1610,6 +1628,8 @@ _ctl_diag_unregister(struct MPT2SAS_ADAPTER *ioc, void __user *arg) __FILE__, __LINE__, __func__); return -EFAULT; } + if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) + return -ENODEV; dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__)); @@ -1658,7 +1678,6 @@ _ctl_diag_unregister(struct MPT2SAS_ADAPTER *ioc, void __user *arg) /** * _ctl_diag_query - query relevant info associated with diag buffers - * @ioc: per adapter object * @arg - user space buffer containing ioctl content * * The application will send only buffer_type and unique_id. Driver will @@ -1666,9 +1685,10 @@ _ctl_diag_unregister(struct MPT2SAS_ADAPTER *ioc, void __user *arg) * 0x00, the driver will return info specified by Buffer Type. */ static long -_ctl_diag_query(struct MPT2SAS_ADAPTER *ioc, void __user *arg) +_ctl_diag_query(void __user *arg) { struct mpt2_diag_query karg; + struct MPT2SAS_ADAPTER *ioc; void *request_data; int i; u8 buffer_type; @@ -1678,6 +1698,8 @@ _ctl_diag_query(struct MPT2SAS_ADAPTER *ioc, void __user *arg) __FILE__, __LINE__, __func__); return -EFAULT; } + if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) + return -ENODEV; dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__)); @@ -1844,15 +1866,17 @@ _ctl_send_release(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type, u8 *issue_reset) /** * _ctl_diag_release - request to send Diag Release Message to firmware * @arg - user space buffer containing ioctl content + * @state - NON_BLOCKING or BLOCKING * * This allows ownership of the specified buffer to returned to the driver, * allowing an application to read the buffer without fear that firmware is * overwritting information in the buffer. */ static long -_ctl_diag_release(struct MPT2SAS_ADAPTER *ioc, void __user *arg) +_ctl_diag_release(void __user *arg, enum block_state state) { struct mpt2_diag_release karg; + struct MPT2SAS_ADAPTER *ioc; void *request_data; int rc; u8 buffer_type; @@ -1863,6 +1887,8 @@ _ctl_diag_release(struct MPT2SAS_ADAPTER *ioc, void __user *arg) __FILE__, __LINE__, __func__); return -EFAULT; } + if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) + return -ENODEV; dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__)); @@ -1916,25 +1942,32 @@ _ctl_diag_release(struct MPT2SAS_ADAPTER *ioc, void __user *arg) return 0; } + if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex)) + return -EAGAIN; + else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) + return -ERESTARTSYS; + rc = _ctl_send_release(ioc, buffer_type, &issue_reset); if (issue_reset) mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, FORCE_BIG_HAMMER); + mutex_unlock(&ioc->ctl_cmds.mutex); return rc; } /** * _ctl_diag_read_buffer - request for copy of the diag buffer - * @ioc: per adapter object * @arg - user space buffer containing ioctl content + * @state - NON_BLOCKING or BLOCKING */ static long -_ctl_diag_read_buffer(struct MPT2SAS_ADAPTER *ioc, void __user *arg) +_ctl_diag_read_buffer(void __user *arg, enum block_state state) { struct mpt2_diag_read_buffer karg; struct mpt2_diag_read_buffer __user *uarg = arg; + struct MPT2SAS_ADAPTER *ioc; void *request_data, *diag_data; Mpi2DiagBufferPostRequest_t *mpi_request; Mpi2DiagBufferPostReply_t *mpi_reply; @@ -1950,6 +1983,8 @@ _ctl_diag_read_buffer(struct MPT2SAS_ADAPTER *ioc, void __user *arg) __FILE__, __LINE__, __func__); return -EFAULT; } + if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) + return -ENODEV; dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__)); @@ -2020,6 +2055,10 @@ _ctl_diag_read_buffer(struct MPT2SAS_ADAPTER *ioc, void __user *arg) } /* Get a free request frame and save the message context. */ + if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex)) + return -EAGAIN; + else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) + return -ERESTARTSYS; if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) { printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n", @@ -2100,170 +2139,115 @@ _ctl_diag_read_buffer(struct MPT2SAS_ADAPTER *ioc, void __user *arg) out: ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; + mutex_unlock(&ioc->ctl_cmds.mutex); return rc; } - -#ifdef CONFIG_COMPAT -/** - * _ctl_compat_mpt_command - convert 32bit pointers to 64bit. - * @ioc: per adapter object - * @cmd - ioctl opcode - * @arg - (struct mpt2_ioctl_command32) - * - * MPT2COMMAND32 - Handle 32bit applications running on 64bit os. - */ -static long -_ctl_compat_mpt_command(struct MPT2SAS_ADAPTER *ioc, unsigned cmd, - void __user *arg) -{ - struct mpt2_ioctl_command32 karg32; - struct mpt2_ioctl_command32 __user *uarg; - struct mpt2_ioctl_command karg; - - if (_IOC_SIZE(cmd) != sizeof(struct mpt2_ioctl_command32)) - return -EINVAL; - - uarg = (struct mpt2_ioctl_command32 __user *) arg; - - if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32))) { - printk(KERN_ERR "failure at %s:%d/%s()!\n", - __FILE__, __LINE__, __func__); - return -EFAULT; - } - - memset(&karg, 0, sizeof(struct mpt2_ioctl_command)); - karg.hdr.ioc_number = karg32.hdr.ioc_number; - karg.hdr.port_number = karg32.hdr.port_number; - karg.hdr.max_data_size = karg32.hdr.max_data_size; - karg.timeout = karg32.timeout; - karg.max_reply_bytes = karg32.max_reply_bytes; - karg.data_in_size = karg32.data_in_size; - karg.data_out_size = karg32.data_out_size; - karg.max_sense_bytes = karg32.max_sense_bytes; - karg.data_sge_offset = karg32.data_sge_offset; - karg.reply_frame_buf_ptr = compat_ptr(karg32.reply_frame_buf_ptr); - karg.data_in_buf_ptr = compat_ptr(karg32.data_in_buf_ptr); - karg.data_out_buf_ptr = compat_ptr(karg32.data_out_buf_ptr); - karg.sense_data_ptr = compat_ptr(karg32.sense_data_ptr); - return _ctl_do_mpt_command(ioc, karg, &uarg->mf); -} -#endif - /** * _ctl_ioctl_main - main ioctl entry point * @file - (struct file) * @cmd - ioctl opcode * @arg - - * compat - handles 32 bit applications in 64bit os */ static long -_ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg, - u8 compat) +_ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg) { - struct MPT2SAS_ADAPTER *ioc; - struct mpt2_ioctl_header ioctl_header; enum block_state state; long ret = -EINVAL; - /* get IOCTL header */ - if (copy_from_user(&ioctl_header, (char __user *)arg, - sizeof(struct mpt2_ioctl_header))) { - printk(KERN_ERR "failure at %s:%d/%s()!\n", - __FILE__, __LINE__, __func__); - return -EFAULT; - } - - if (_ctl_verify_adapter(ioctl_header.ioc_number, &ioc) == -1 || !ioc) - return -ENODEV; - if (ioc->shost_recovery || ioc->pci_error_recovery || - ioc->is_driver_loading) - return -EAGAIN; - - state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING; - if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex)) - return -EAGAIN; - else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) - return -ERESTARTSYS; + state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : + BLOCKING; switch (cmd) { case MPT2IOCINFO: if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_iocinfo)) - ret = _ctl_getiocinfo(ioc, arg); + ret = _ctl_getiocinfo(arg); break; -#ifdef CONFIG_COMPAT - case MPT2COMMAND32: -#endif case MPT2COMMAND: { - struct mpt2_ioctl_command __user *uarg; struct mpt2_ioctl_command karg; -#ifdef CONFIG_COMPAT - if (compat) { - ret = _ctl_compat_mpt_command(ioc, cmd, arg); - break; - } -#endif + struct mpt2_ioctl_command __user *uarg; + struct MPT2SAS_ADAPTER *ioc; + if (copy_from_user(&karg, arg, sizeof(karg))) { printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); - ret = -EFAULT; - break; + return -EFAULT; } + if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || + !ioc) + return -ENODEV; + + if (ioc->shost_recovery || ioc->pci_error_recovery || + ioc->is_driver_loading) + return -EAGAIN; + if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_command)) { uarg = arg; - ret = _ctl_do_mpt_command(ioc, karg, &uarg->mf); + ret = _ctl_do_mpt_command(ioc, karg, &uarg->mf, state); } break; } case MPT2EVENTQUERY: if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_eventquery)) - ret = _ctl_eventquery(ioc, arg); + ret = _ctl_eventquery(arg); break; case MPT2EVENTENABLE: if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_eventenable)) - ret = _ctl_eventenable(ioc, arg); + ret = _ctl_eventenable(arg); break; case MPT2EVENTREPORT: - ret = _ctl_eventreport(ioc, arg); + ret = _ctl_eventreport(arg); break; case MPT2HARDRESET: if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_diag_reset)) - ret = _ctl_do_reset(ioc, arg); + ret = _ctl_do_reset(arg); break; case MPT2BTDHMAPPING: if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_btdh_mapping)) - ret = _ctl_btdh_mapping(ioc, arg); + ret = _ctl_btdh_mapping(arg); break; case MPT2DIAGREGISTER: if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_register)) - ret = _ctl_diag_register(ioc, arg); + ret = _ctl_diag_register(arg, state); break; case MPT2DIAGUNREGISTER: if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_unregister)) - ret = _ctl_diag_unregister(ioc, arg); + ret = _ctl_diag_unregister(arg); break; case MPT2DIAGQUERY: if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_query)) - ret = _ctl_diag_query(ioc, arg); + ret = _ctl_diag_query(arg); break; case MPT2DIAGRELEASE: if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_release)) - ret = _ctl_diag_release(ioc, arg); + ret = _ctl_diag_release(arg, state); break; case MPT2DIAGREADBUFFER: if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_read_buffer)) - ret = _ctl_diag_read_buffer(ioc, arg); + ret = _ctl_diag_read_buffer(arg, state); break; default: + { + struct mpt2_ioctl_command karg; + struct MPT2SAS_ADAPTER *ioc; + + if (copy_from_user(&karg, arg, sizeof(karg))) { + printk(KERN_ERR "failure at %s:%d/%s()!\n", + __FILE__, __LINE__, __func__); + return -EFAULT; + } + + if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || + !ioc) + return -ENODEV; dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "unsupported ioctl opcode(0x%08x)\n", ioc->name, cmd)); break; } - - mutex_unlock(&ioc->ctl_cmds.mutex); + } return ret; } @@ -2278,10 +2262,65 @@ _ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { long ret; - ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0); + mutex_lock(&_ctl_mutex); + ret = _ctl_ioctl_main(file, cmd, (void __user *)arg); + mutex_unlock(&_ctl_mutex); return ret; } + #ifdef CONFIG_COMPAT +/** + * _ctl_compat_mpt_command - convert 32bit pointers to 64bit. + * @file - (struct file) + * @cmd - ioctl opcode + * @arg - (struct mpt2_ioctl_command32) + * + * MPT2COMMAND32 - Handle 32bit applications running on 64bit os. + */ +static long +_ctl_compat_mpt_command(struct file *file, unsigned cmd, unsigned long arg) +{ + struct mpt2_ioctl_command32 karg32; + struct mpt2_ioctl_command32 __user *uarg; + struct mpt2_ioctl_command karg; + struct MPT2SAS_ADAPTER *ioc; + enum block_state state; + + if (_IOC_SIZE(cmd) != sizeof(struct mpt2_ioctl_command32)) + return -EINVAL; + + uarg = (struct mpt2_ioctl_command32 __user *) arg; + + if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32))) { + printk(KERN_ERR "failure at %s:%d/%s()!\n", + __FILE__, __LINE__, __func__); + return -EFAULT; + } + if (_ctl_verify_adapter(karg32.hdr.ioc_number, &ioc) == -1 || !ioc) + return -ENODEV; + + if (ioc->shost_recovery || ioc->pci_error_recovery || + ioc->is_driver_loading) + return -EAGAIN; + + memset(&karg, 0, sizeof(struct mpt2_ioctl_command)); + karg.hdr.ioc_number = karg32.hdr.ioc_number; + karg.hdr.port_number = karg32.hdr.port_number; + karg.hdr.max_data_size = karg32.hdr.max_data_size; + karg.timeout = karg32.timeout; + karg.max_reply_bytes = karg32.max_reply_bytes; + karg.data_in_size = karg32.data_in_size; + karg.data_out_size = karg32.data_out_size; + karg.max_sense_bytes = karg32.max_sense_bytes; + karg.data_sge_offset = karg32.data_sge_offset; + karg.reply_frame_buf_ptr = compat_ptr(karg32.reply_frame_buf_ptr); + karg.data_in_buf_ptr = compat_ptr(karg32.data_in_buf_ptr); + karg.data_out_buf_ptr = compat_ptr(karg32.data_out_buf_ptr); + karg.sense_data_ptr = compat_ptr(karg32.sense_data_ptr); + state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING; + return _ctl_do_mpt_command(ioc, karg, &uarg->mf, state); +} + /** * _ctl_ioctl_compat - main ioctl entry point (compat) * @file - @@ -2295,7 +2334,12 @@ _ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg) { long ret; - ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1); + mutex_lock(&_ctl_mutex); + if (cmd == MPT2COMMAND32) + ret = _ctl_compat_mpt_command(file, cmd, arg); + else + ret = _ctl_ioctl_main(file, cmd, (void __user *)arg); + mutex_unlock(&_ctl_mutex); return ret; } #endif @@ -2840,7 +2884,7 @@ _ctl_host_trace_buffer_enable_store(struct device *cdev, struct mpt2_diag_register diag_register; u8 issue_reset = 0; - if (sscanf(buf, "%9s", str) != 1) + if (sscanf(buf, "%s", str) != 1) return -EINVAL; if (!strcmp(str, "post")) { diff --git a/trunk/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/trunk/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 76973e8ca4ba..d953a57e779d 100644 --- a/trunk/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/trunk/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -579,12 +579,14 @@ _scsih_sas_device_remove(struct MPT2SAS_ADAPTER *ioc, return; spin_lock_irqsave(&ioc->sas_device_lock, flags); - list_del(&sas_device->list); - kfree(sas_device); + if (mpt2sas_scsih_sas_device_find_by_sas_address(ioc, + sas_device->sas_address)) { + list_del(&sas_device->list); + kfree(sas_device); + } spin_unlock_irqrestore(&ioc->sas_device_lock, flags); } - /** * _scsih_sas_device_add - insert sas_device to the list. * @ioc: per adapter object @@ -643,8 +645,8 @@ _scsih_sas_device_init_add(struct MPT2SAS_ADAPTER *ioc, spin_lock_irqsave(&ioc->sas_device_lock, flags); list_add_tail(&sas_device->list, &ioc->sas_device_init_list); - _scsih_determine_boot_device(ioc, sas_device, 0); spin_unlock_irqrestore(&ioc->sas_device_lock, flags); + _scsih_determine_boot_device(ioc, sas_device, 0); } /** @@ -753,6 +755,7 @@ _scsih_raid_device_add(struct MPT2SAS_ADAPTER *ioc, * @ioc: per adapter object * @raid_device: raid_device object * + * This is removed from the raid_device_list link list. */ static void _scsih_raid_device_remove(struct MPT2SAS_ADAPTER *ioc, @@ -762,6 +765,7 @@ _scsih_raid_device_remove(struct MPT2SAS_ADAPTER *ioc, spin_lock_irqsave(&ioc->raid_device_lock, flags); list_del(&raid_device->list); + memset(raid_device, 0, sizeof(struct _raid_device)); kfree(raid_device); spin_unlock_irqrestore(&ioc->raid_device_lock, flags); } @@ -1195,10 +1199,10 @@ _scsih_adjust_queue_depth(struct scsi_device *sdev, int qdepth) spin_lock_irqsave(&ioc->sas_device_lock, flags); sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, sas_device_priv_data->sas_target->sas_address); + spin_unlock_irqrestore(&ioc->sas_device_lock, flags); if (sas_device && sas_device->device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) max_depth = MPT2SAS_SATA_QUEUE_DEPTH; - spin_unlock_irqrestore(&ioc->sas_device_lock, flags); not_sata: @@ -1295,8 +1299,7 @@ _scsih_target_alloc(struct scsi_target *starget) sas_target_priv_data->handle = raid_device->handle; sas_target_priv_data->sas_address = raid_device->wwid; sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME; - if (ioc->is_warpdrive) - sas_target_priv_data->raid_device = raid_device; + sas_target_priv_data->raid_device = raid_device; raid_device->starget = starget; } spin_unlock_irqrestore(&ioc->raid_device_lock, flags); @@ -1462,12 +1465,12 @@ _scsih_slave_destroy(struct scsi_device *sdev) /** * _scsih_display_sata_capabilities - sata capabilities * @ioc: per adapter object - * @handle: device handle + * @sas_device: the sas_device object * @sdev: scsi device struct */ static void _scsih_display_sata_capabilities(struct MPT2SAS_ADAPTER *ioc, - u16 handle, struct scsi_device *sdev) + struct _sas_device *sas_device, struct scsi_device *sdev) { Mpi2ConfigReply_t mpi_reply; Mpi2SasDevicePage0_t sas_device_pg0; @@ -1476,7 +1479,7 @@ _scsih_display_sata_capabilities(struct MPT2SAS_ADAPTER *ioc, u32 device_info; if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, - MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { + MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, sas_device->handle))) { printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); return; @@ -1534,40 +1537,27 @@ _scsih_get_resync(struct device *dev) Mpi2RaidVolPage0_t vol_pg0; Mpi2ConfigReply_t mpi_reply; u32 volume_status_flags; - u8 percent_complete; - u16 handle; - - percent_complete = 0; - handle = 0; - if (ioc->is_warpdrive) - goto out; + u8 percent_complete = 0; spin_lock_irqsave(&ioc->raid_device_lock, flags); raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id, sdev->channel); - if (raid_device) { - handle = raid_device->handle; - percent_complete = raid_device->percent_complete; - } spin_unlock_irqrestore(&ioc->raid_device_lock, flags); - if (!handle) + if (!raid_device || ioc->is_warpdrive) goto out; if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0, - MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle, + MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sizeof(Mpi2RaidVolPage0_t))) { printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); - percent_complete = 0; goto out; } volume_status_flags = le32_to_cpu(vol_pg0.VolumeStatusFlags); - if (!(volume_status_flags & - MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS)) - percent_complete = 0; - + if (volume_status_flags & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) + percent_complete = raid_device->percent_complete; out: raid_set_resync(mpt2sas_raid_template, dev, percent_complete); } @@ -1587,20 +1577,17 @@ _scsih_get_state(struct device *dev) Mpi2ConfigReply_t mpi_reply; u32 volstate; enum raid_state state = RAID_STATE_UNKNOWN; - u16 handle = 0; spin_lock_irqsave(&ioc->raid_device_lock, flags); raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id, sdev->channel); - if (raid_device) - handle = raid_device->handle; spin_unlock_irqrestore(&ioc->raid_device_lock, flags); if (!raid_device) goto out; if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0, - MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle, + MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sizeof(Mpi2RaidVolPage0_t))) { printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); @@ -1633,14 +1620,14 @@ _scsih_get_state(struct device *dev) /** * _scsih_set_level - set raid level * @sdev: scsi device struct - * @volume_type: volume type + * @raid_device: raid_device object */ static void -_scsih_set_level(struct scsi_device *sdev, u8 volume_type) +_scsih_set_level(struct scsi_device *sdev, struct _raid_device *raid_device) { enum raid_level level = RAID_LEVEL_UNKNOWN; - switch (volume_type) { + switch (raid_device->volume_type) { case MPI2_RAID_VOL_TYPE_RAID0: level = RAID_LEVEL_0; break; @@ -1735,7 +1722,6 @@ _scsih_disable_ddio(struct MPT2SAS_ADAPTER *ioc) struct _raid_device *raid_device; u16 handle; u16 ioc_status; - unsigned long flags; handle = 0xFFFF; while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply, @@ -1745,11 +1731,9 @@ _scsih_disable_ddio(struct MPT2SAS_ADAPTER *ioc) if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) break; handle = le16_to_cpu(vol_pg1.DevHandle); - spin_lock_irqsave(&ioc->raid_device_lock, flags); raid_device = _scsih_raid_device_find_by_handle(ioc, handle); if (raid_device) raid_device->direct_io_enabled = 0; - spin_unlock_irqrestore(&ioc->raid_device_lock, flags); } return; } @@ -1854,8 +1838,7 @@ _scsih_init_warpdrive_properties(struct MPT2SAS_ADAPTER *ioc, if (mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply, &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM, vol_pg0->PhysDisk[count].PhysDiskNum) || - le16_to_cpu(pd_pg0.DevHandle) == - MPT2SAS_INVALID_DEVICE_HANDLE) { + pd_pg0.DevHandle == MPT2SAS_INVALID_DEVICE_HANDLE) { printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is " "disabled for the drive with handle(0x%04x) member" "handle retrieval failed for member number=%d\n", @@ -1985,21 +1968,19 @@ _scsih_slave_configure(struct scsi_device *sdev) u8 ssp_target = 0; char *ds = ""; char *r_level = ""; - u16 handle, volume_handle = 0; - u64 volume_wwid = 0; qdepth = 1; sas_device_priv_data = sdev->hostdata; sas_device_priv_data->configured_lun = 1; sas_device_priv_data->flags &= ~MPT_DEVICE_FLAGS_INIT; sas_target_priv_data = sas_device_priv_data->sas_target; - handle = sas_target_priv_data->handle; /* raid volume handling */ if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME) { spin_lock_irqsave(&ioc->raid_device_lock, flags); - raid_device = _scsih_raid_device_find_by_handle(ioc, handle); + raid_device = _scsih_raid_device_find_by_handle(ioc, + sas_target_priv_data->handle); spin_unlock_irqrestore(&ioc->raid_device_lock, flags); if (!raid_device) { dfailprintk(ioc, printk(MPT2SAS_WARN_FMT @@ -2008,6 +1989,8 @@ _scsih_slave_configure(struct scsi_device *sdev) return 1; } + _scsih_get_volume_capabilities(ioc, raid_device); + if (_scsih_get_volume_capabilities(ioc, raid_device)) { dfailprintk(ioc, printk(MPT2SAS_WARN_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, @@ -2075,67 +2058,68 @@ _scsih_slave_configure(struct scsi_device *sdev) _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); /* raid transport support */ if (!ioc->is_warpdrive) - _scsih_set_level(sdev, raid_device->volume_type); + _scsih_set_level(sdev, raid_device); return 0; } /* non-raid handling */ - if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT) { - if (mpt2sas_config_get_volume_handle(ioc, handle, - &volume_handle)) { - dfailprintk(ioc, printk(MPT2SAS_WARN_FMT - "failure at %s:%d/%s()!\n", ioc->name, - __FILE__, __LINE__, __func__)); - return 1; - } - if (volume_handle && mpt2sas_config_get_volume_wwid(ioc, - volume_handle, &volume_wwid)) { - dfailprintk(ioc, printk(MPT2SAS_WARN_FMT - "failure at %s:%d/%s()!\n", ioc->name, - __FILE__, __LINE__, __func__)); - return 1; - } - } - spin_lock_irqsave(&ioc->sas_device_lock, flags); sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, sas_device_priv_data->sas_target->sas_address); - if (!sas_device) { - spin_unlock_irqrestore(&ioc->sas_device_lock, flags); + spin_unlock_irqrestore(&ioc->sas_device_lock, flags); + if (sas_device) { + if (sas_target_priv_data->flags & + MPT_TARGET_FLAGS_RAID_COMPONENT) { + if (mpt2sas_config_get_volume_handle(ioc, + sas_device->handle, &sas_device->volume_handle)) { + dfailprintk(ioc, printk(MPT2SAS_WARN_FMT + "failure at %s:%d/%s()!\n", ioc->name, + __FILE__, __LINE__, __func__)); + return 1; + } + if (sas_device->volume_handle && + mpt2sas_config_get_volume_wwid(ioc, + sas_device->volume_handle, + &sas_device->volume_wwid)) { + dfailprintk(ioc, printk(MPT2SAS_WARN_FMT + "failure at %s:%d/%s()!\n", ioc->name, + __FILE__, __LINE__, __func__)); + return 1; + } + } + if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) { + qdepth = MPT2SAS_SAS_QUEUE_DEPTH; + ssp_target = 1; + ds = "SSP"; + } else { + qdepth = MPT2SAS_SATA_QUEUE_DEPTH; + if (sas_device->device_info & + MPI2_SAS_DEVICE_INFO_STP_TARGET) + ds = "STP"; + else if (sas_device->device_info & + MPI2_SAS_DEVICE_INFO_SATA_DEVICE) + ds = "SATA"; + } + + sdev_printk(KERN_INFO, sdev, "%s: handle(0x%04x), " + "sas_addr(0x%016llx), phy(%d), device_name(0x%016llx)\n", + ds, sas_device->handle, + (unsigned long long)sas_device->sas_address, + sas_device->phy, + (unsigned long long)sas_device->device_name); + sdev_printk(KERN_INFO, sdev, "%s: " + "enclosure_logical_id(0x%016llx), slot(%d)\n", ds, + (unsigned long long) sas_device->enclosure_logical_id, + sas_device->slot); + + if (!ssp_target) + _scsih_display_sata_capabilities(ioc, sas_device, sdev); + } else { dfailprintk(ioc, printk(MPT2SAS_WARN_FMT - "failure at %s:%d/%s()!\n", ioc->name, __FILE__, - __LINE__, __func__)); + "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, + __func__)); return 1; } - sas_device->volume_handle = volume_handle; - sas_device->volume_wwid = volume_wwid; - if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) { - qdepth = MPT2SAS_SAS_QUEUE_DEPTH; - ssp_target = 1; - ds = "SSP"; - } else { - qdepth = MPT2SAS_SATA_QUEUE_DEPTH; - if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET) - ds = "STP"; - else if (sas_device->device_info & - MPI2_SAS_DEVICE_INFO_SATA_DEVICE) - ds = "SATA"; - } - sdev_printk(KERN_INFO, sdev, "%s: handle(0x%04x), " - "sas_addr(0x%016llx), phy(%d), device_name(0x%016llx)\n", - ds, sas_device->handle, - (unsigned long long)sas_device->sas_address, - sas_device->phy, - (unsigned long long)sas_device->device_name); - sdev_printk(KERN_INFO, sdev, "%s: " - "enclosure_logical_id(0x%016llx), slot(%d)\n", ds, - (unsigned long long) sas_device->enclosure_logical_id, - sas_device->slot); - - spin_unlock_irqrestore(&ioc->sas_device_lock, flags); - if (!ssp_target) - _scsih_display_sata_capabilities(ioc, handle, sdev); - _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); @@ -2915,7 +2899,7 @@ _scsih_ublock_io_all_device(struct MPT2SAS_ADAPTER *ioc) * During device pull we need to appropiately set the sdev state. */ static void -_scsih_ublock_io_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address) +_scsih_ublock_io_device(struct MPT2SAS_ADAPTER *ioc, u16 handle) { struct MPT2SAS_DEVICE *sas_device_priv_data; struct scsi_device *sdev; @@ -2926,12 +2910,10 @@ _scsih_ublock_io_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address) continue; if (!sas_device_priv_data->block) continue; - if (sas_device_priv_data->sas_target->sas_address == - sas_address) { + if (sas_device_priv_data->sas_target->handle == handle) { dewtprintk(ioc, sdev_printk(KERN_INFO, sdev, MPT2SAS_INFO_FMT "SDEV_RUNNING: " - "sas address(0x%016llx)\n", ioc->name, - (unsigned long long)sas_address)); + "handle(0x%04x)\n", ioc->name, handle)); sas_device_priv_data->block = 0; scsi_internal_device_unblock(sdev); } @@ -3024,10 +3006,10 @@ _scsih_block_io_to_children_attached_to_ex(struct MPT2SAS_ADAPTER *ioc, sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, mpt2sas_port->remote_identify.sas_address); - if (sas_device) - set_bit(sas_device->handle, - ioc->blocking_handles); spin_unlock_irqrestore(&ioc->sas_device_lock, flags); + if (!sas_device) + continue; + _scsih_block_io_device(ioc, sas_device->handle); } } @@ -3038,9 +3020,12 @@ _scsih_block_io_to_children_attached_to_ex(struct MPT2SAS_ADAPTER *ioc, SAS_EDGE_EXPANDER_DEVICE || mpt2sas_port->remote_identify.device_type == SAS_FANOUT_EXPANDER_DEVICE) { + + spin_lock_irqsave(&ioc->sas_node_lock, flags); expander_sibling = mpt2sas_scsih_expander_find_by_sas_address( ioc, mpt2sas_port->remote_identify.sas_address); + spin_unlock_irqrestore(&ioc->sas_node_lock, flags); _scsih_block_io_to_children_attached_to_ex(ioc, expander_sibling); } @@ -3139,7 +3124,7 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle) dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "setting delete flag: " "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, handle, (unsigned long long)sas_address)); - _scsih_ublock_io_device(ioc, sas_address); + _scsih_ublock_io_device(ioc, handle); sas_target_priv_data->handle = MPT2SAS_INVALID_DEVICE_HANDLE; } @@ -3189,19 +3174,16 @@ static u8 _scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) { +#ifdef CONFIG_SCSI_MPT2SAS_LOGGING Mpi2SasIoUnitControlReply_t *mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); - if (likely(mpi_reply)) { - dewtprintk(ioc, printk(MPT2SAS_INFO_FMT - "sc_complete:handle(0x%04x), (open) " - "smid(%d), ioc_status(0x%04x), loginfo(0x%08x)\n", - ioc->name, le16_to_cpu(mpi_reply->DevHandle), smid, - le16_to_cpu(mpi_reply->IOCStatus), - le32_to_cpu(mpi_reply->IOCLogInfo))); - } else { - printk(MPT2SAS_ERR_FMT "mpi_reply not valid at %s:%d/%s()!\n", - ioc->name, __FILE__, __LINE__, __func__); - } +#endif + dewtprintk(ioc, printk(MPT2SAS_INFO_FMT + "sc_complete:handle(0x%04x), (open) " + "smid(%d), ioc_status(0x%04x), loginfo(0x%08x)\n", + ioc->name, le16_to_cpu(mpi_reply->DevHandle), smid, + le16_to_cpu(mpi_reply->IOCStatus), + le32_to_cpu(mpi_reply->IOCLogInfo))); return 1; } @@ -3280,11 +3262,7 @@ _scsih_tm_volume_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, "progress!\n", __func__, ioc->name)); return 1; } - if (unlikely(!mpi_reply)) { - printk(MPT2SAS_ERR_FMT "mpi_reply not valid at %s:%d/%s()!\n", - ioc->name, __FILE__, __LINE__, __func__); - return 1; - } + mpi_request_tm = mpt2sas_base_get_msg_frame(ioc, smid); handle = le16_to_cpu(mpi_request_tm->DevHandle); if (handle != le16_to_cpu(mpi_reply->DevHandle)) { @@ -3347,11 +3325,7 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, "operational\n", __func__, ioc->name)); return 1; } - if (unlikely(!mpi_reply)) { - printk(MPT2SAS_ERR_FMT "mpi_reply not valid at %s:%d/%s()!\n", - ioc->name, __FILE__, __LINE__, __func__); - return 1; - } + mpi_request_tm = mpt2sas_base_get_msg_frame(ioc, smid); handle = le16_to_cpu(mpi_request_tm->DevHandle); if (handle != le16_to_cpu(mpi_reply->DevHandle)) { @@ -3467,20 +3441,14 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc, _scsih_block_io_to_children_attached_directly(ioc, event_data); return; } - if (event_data->ExpStatus == - MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING) { - /* put expander attached devices into blocking state */ + + if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING + || event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING) { spin_lock_irqsave(&ioc->sas_node_lock, flags); sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, expander_handle); - _scsih_block_io_to_children_attached_to_ex(ioc, sas_expander); spin_unlock_irqrestore(&ioc->sas_node_lock, flags); - do { - handle = find_first_bit(ioc->blocking_handles, - ioc->facts.MaxDevHandle); - if (handle < ioc->facts.MaxDevHandle) - _scsih_block_io_device(ioc, handle); - } while (test_and_clear_bit(handle, ioc->blocking_handles)); + _scsih_block_io_to_children_attached_to_ex(ioc, sas_expander); } else if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_RESPONDING) _scsih_block_io_to_children_attached_directly(ioc, event_data); @@ -4478,8 +4446,8 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) != MPI2_IOCSTATUS_SCSI_TASK_TERMINATED)) { spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ioc->scsi_lookup[smid - 1].scmd = scmd; - _scsih_scsi_direct_io_set(ioc, smid, 0); spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); + _scsih_scsi_direct_io_set(ioc, smid, 0); memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len); mpi_request->DevHandle = cpu_to_le16(sas_device_priv_data->sas_target->handle); @@ -5052,11 +5020,13 @@ mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address) spin_lock_irqsave(&ioc->sas_node_lock, flags); sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc, sas_address); - if (sas_expander) - list_del(&sas_expander->list); + if (!sas_expander) { + spin_unlock_irqrestore(&ioc->sas_node_lock, flags); + return; + } + list_del(&sas_expander->list); spin_unlock_irqrestore(&ioc->sas_node_lock, flags); - if (sas_expander) - _scsih_expander_node_remove(ioc, sas_expander); + _scsih_expander_node_remove(ioc, sas_expander); } /** @@ -5136,7 +5106,6 @@ _scsih_check_device(struct MPT2SAS_ADAPTER *ioc, u16 handle) struct MPT2SAS_TARGET *sas_target_priv_data; u32 device_info; - if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) return; @@ -5170,24 +5139,21 @@ _scsih_check_device(struct MPT2SAS_ADAPTER *ioc, u16 handle) sas_target_priv_data->handle = handle; sas_device->handle = handle; } + spin_unlock_irqrestore(&ioc->sas_device_lock, flags); /* check if device is present */ if (!(le16_to_cpu(sas_device_pg0.Flags) & MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) { printk(MPT2SAS_ERR_FMT "device is not present " "handle(0x%04x), flags!!!\n", ioc->name, handle); - spin_unlock_irqrestore(&ioc->sas_device_lock, flags); return; } /* check if there were any issues with discovery */ if (_scsih_check_access_status(ioc, sas_address, handle, - sas_device_pg0.AccessStatus)) { - spin_unlock_irqrestore(&ioc->sas_device_lock, flags); + sas_device_pg0.AccessStatus)) return; - } - spin_unlock_irqrestore(&ioc->sas_device_lock, flags); - _scsih_ublock_io_device(ioc, sas_address); + _scsih_ublock_io_device(ioc, handle); } @@ -5314,71 +5280,54 @@ static void _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, struct _sas_device *sas_device) { + struct _sas_device sas_device_backup; struct MPT2SAS_TARGET *sas_target_priv_data; + if (!sas_device) + return; + + memcpy(&sas_device_backup, sas_device, sizeof(struct _sas_device)); + _scsih_sas_device_remove(ioc, sas_device); + dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: " "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__, - sas_device->handle, (unsigned long long) - sas_device->sas_address)); + sas_device_backup.handle, (unsigned long long) + sas_device_backup.sas_address)); - if (sas_device->starget && sas_device->starget->hostdata) { - sas_target_priv_data = sas_device->starget->hostdata; + if (sas_device_backup.starget && sas_device_backup.starget->hostdata) { + sas_target_priv_data = sas_device_backup.starget->hostdata; sas_target_priv_data->deleted = 1; - _scsih_ublock_io_device(ioc, sas_device->sas_address); + _scsih_ublock_io_device(ioc, sas_device_backup.handle); sas_target_priv_data->handle = MPT2SAS_INVALID_DEVICE_HANDLE; } + _scsih_ublock_io_device(ioc, sas_device_backup.handle); + if (!ioc->hide_drives) mpt2sas_transport_port_remove(ioc, - sas_device->sas_address, - sas_device->sas_address_parent); + sas_device_backup.sas_address, + sas_device_backup.sas_address_parent); printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr" - "(0x%016llx)\n", ioc->name, sas_device->handle, - (unsigned long long) sas_device->sas_address); + "(0x%016llx)\n", ioc->name, sas_device_backup.handle, + (unsigned long long) sas_device_backup.sas_address); dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit: " "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__, - sas_device->handle, (unsigned long long) - sas_device->sas_address)); - kfree(sas_device); -} -/** - * _scsih_device_remove_by_handle - removing device object by handle - * @ioc: per adapter object - * @handle: device handle - * - * Return nothing. - */ -static void -_scsih_device_remove_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle) -{ - struct _sas_device *sas_device; - unsigned long flags; - - if (ioc->shost_recovery) - return; - - spin_lock_irqsave(&ioc->sas_device_lock, flags); - sas_device = _scsih_sas_device_find_by_handle(ioc, handle); - if (sas_device) - list_del(&sas_device->list); - spin_unlock_irqrestore(&ioc->sas_device_lock, flags); - if (sas_device) - _scsih_remove_device(ioc, sas_device); + sas_device_backup.handle, (unsigned long long) + sas_device_backup.sas_address)); } /** - * mpt2sas_device_remove_by_sas_address - removing device object by sas address + * mpt2sas_device_remove - removing device object * @ioc: per adapter object - * @sas_address: device sas_address + * @sas_address: expander sas_address * * Return nothing. */ void -mpt2sas_device_remove_by_sas_address(struct MPT2SAS_ADAPTER *ioc, - u64 sas_address) +mpt2sas_device_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address) { struct _sas_device *sas_device; unsigned long flags; @@ -5389,12 +5338,14 @@ mpt2sas_device_remove_by_sas_address(struct MPT2SAS_ADAPTER *ioc, spin_lock_irqsave(&ioc->sas_device_lock, flags); sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, sas_address); - if (sas_device) - list_del(&sas_device->list); + if (!sas_device) { + spin_unlock_irqrestore(&ioc->sas_device_lock, flags); + return; + } spin_unlock_irqrestore(&ioc->sas_device_lock, flags); - if (sas_device) - _scsih_remove_device(ioc, sas_device); + _scsih_remove_device(ioc, sas_device); } + #ifdef CONFIG_SCSI_MPT2SAS_LOGGING /** * _scsih_sas_topology_change_event_debug - debug for topology event @@ -5491,6 +5442,7 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, u16 reason_code; u8 phy_number, max_phys; struct _sas_node *sas_expander; + struct _sas_device *sas_device; u64 sas_address; unsigned long flags; u8 link_rate, prev_link_rate; @@ -5525,17 +5477,15 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, spin_lock_irqsave(&ioc->sas_node_lock, flags); sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, parent_handle); + spin_unlock_irqrestore(&ioc->sas_node_lock, flags); if (sas_expander) { sas_address = sas_expander->sas_address; max_phys = sas_expander->num_phys; } else if (parent_handle < ioc->sas_hba.num_phys) { sas_address = ioc->sas_hba.sas_address; max_phys = ioc->sas_hba.num_phys; - } else { - spin_unlock_irqrestore(&ioc->sas_node_lock, flags); + } else return; - } - spin_unlock_irqrestore(&ioc->sas_node_lock, flags); /* handle siblings events */ for (i = 0; i < event_data->NumEntries; i++) { @@ -5590,7 +5540,16 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, break; case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: - _scsih_device_remove_by_handle(ioc, handle); + spin_lock_irqsave(&ioc->sas_device_lock, flags); + sas_device = _scsih_sas_device_find_by_handle(ioc, + handle); + if (!sas_device) { + spin_unlock_irqrestore(&ioc->sas_device_lock, + flags); + break; + } + spin_unlock_irqrestore(&ioc->sas_device_lock, flags); + _scsih_remove_device(ioc, sas_device); break; } } @@ -5713,24 +5672,20 @@ _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc, sas_address = le64_to_cpu(event_data->SASAddress); sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, sas_address); + spin_unlock_irqrestore(&ioc->sas_device_lock, flags); - if (!sas_device || !sas_device->starget) { - spin_unlock_irqrestore(&ioc->sas_device_lock, flags); + if (!sas_device || !sas_device->starget) return; - } target_priv_data = sas_device->starget->hostdata; - if (!target_priv_data) { - spin_unlock_irqrestore(&ioc->sas_device_lock, flags); + if (!target_priv_data) return; - } if (event_data->ReasonCode == MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET) target_priv_data->tm_busy = 1; else target_priv_data->tm_busy = 0; - spin_unlock_irqrestore(&ioc->sas_device_lock, flags); } #ifdef CONFIG_SCSI_MPT2SAS_LOGGING @@ -5994,6 +5949,30 @@ _scsih_reprobe_lun(struct scsi_device *sdev, void *no_uld_attach) rc = scsi_device_reprobe(sdev); } +/** + * _scsih_reprobe_target - reprobing target + * @starget: scsi target struct + * @no_uld_attach: sdev->no_uld_attach flag setting + * + * Note: no_uld_attach flag determines whether the disk device is attached + * to block layer. A value of `1` means to not attach. + **/ +static void +_scsih_reprobe_target(struct scsi_target *starget, int no_uld_attach) +{ + struct MPT2SAS_TARGET *sas_target_priv_data; + + if (starget == NULL) + return; + sas_target_priv_data = starget->hostdata; + if (no_uld_attach) + sas_target_priv_data->flags |= MPT_TARGET_FLAGS_RAID_COMPONENT; + else + sas_target_priv_data->flags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT; + + starget_for_each_device(starget, no_uld_attach ? (void *)1 : NULL, + _scsih_reprobe_lun); +} /** * _scsih_sas_volume_add - add new volume * @ioc: per adapter object @@ -6045,11 +6024,8 @@ _scsih_sas_volume_add(struct MPT2SAS_ADAPTER *ioc, raid_device->id, 0); if (rc) _scsih_raid_device_remove(ioc, raid_device); - } else { - spin_lock_irqsave(&ioc->raid_device_lock, flags); + } else _scsih_determine_boot_device(ioc, raid_device, 1); - spin_unlock_irqrestore(&ioc->raid_device_lock, flags); - } } /** @@ -6066,25 +6042,21 @@ _scsih_sas_volume_delete(struct MPT2SAS_ADAPTER *ioc, u16 handle) struct _raid_device *raid_device; unsigned long flags; struct MPT2SAS_TARGET *sas_target_priv_data; - struct scsi_target *starget = NULL; spin_lock_irqsave(&ioc->raid_device_lock, flags); raid_device = _scsih_raid_device_find_by_handle(ioc, handle); - if (raid_device) { - if (raid_device->starget) { - starget = raid_device->starget; - sas_target_priv_data = starget->hostdata; - sas_target_priv_data->deleted = 1; - } - printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), wwid" - "(0x%016llx)\n", ioc->name, raid_device->handle, - (unsigned long long) raid_device->wwid); - list_del(&raid_device->list); - kfree(raid_device); - } spin_unlock_irqrestore(&ioc->raid_device_lock, flags); - if (starget) - scsi_remove_target(&starget->dev); + if (!raid_device) + return; + if (raid_device->starget) { + sas_target_priv_data = raid_device->starget->hostdata; + sas_target_priv_data->deleted = 1; + scsi_remove_target(&raid_device->starget->dev); + } + printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), wwid" + "(0x%016llx)\n", ioc->name, raid_device->handle, + (unsigned long long) raid_device->wwid); + _scsih_raid_device_remove(ioc, raid_device); } /** @@ -6100,31 +6072,20 @@ _scsih_sas_pd_expose(struct MPT2SAS_ADAPTER *ioc, Mpi2EventIrConfigElement_t *element) { struct _sas_device *sas_device; - struct scsi_target *starget = NULL; - struct MPT2SAS_TARGET *sas_target_priv_data; unsigned long flags; u16 handle = le16_to_cpu(element->PhysDiskDevHandle); spin_lock_irqsave(&ioc->sas_device_lock, flags); sas_device = _scsih_sas_device_find_by_handle(ioc, handle); - if (sas_device) { - sas_device->volume_handle = 0; - sas_device->volume_wwid = 0; - clear_bit(handle, ioc->pd_handles); - if (sas_device->starget && sas_device->starget->hostdata) { - starget = sas_device->starget; - sas_target_priv_data = starget->hostdata; - sas_target_priv_data->flags &= - ~MPT_TARGET_FLAGS_RAID_COMPONENT; - } - } spin_unlock_irqrestore(&ioc->sas_device_lock, flags); if (!sas_device) return; /* exposing raid component */ - if (starget) - starget_for_each_device(starget, NULL, _scsih_reprobe_lun); + sas_device->volume_handle = 0; + sas_device->volume_wwid = 0; + clear_bit(handle, ioc->pd_handles); + _scsih_reprobe_target(sas_device->starget, 0); } /** @@ -6140,38 +6101,23 @@ _scsih_sas_pd_hide(struct MPT2SAS_ADAPTER *ioc, Mpi2EventIrConfigElement_t *element) { struct _sas_device *sas_device; - struct scsi_target *starget = NULL; - struct MPT2SAS_TARGET *sas_target_priv_data; unsigned long flags; u16 handle = le16_to_cpu(element->PhysDiskDevHandle); - u16 volume_handle = 0; - u64 volume_wwid = 0; - - mpt2sas_config_get_volume_handle(ioc, handle, &volume_handle); - if (volume_handle) - mpt2sas_config_get_volume_wwid(ioc, volume_handle, - &volume_wwid); spin_lock_irqsave(&ioc->sas_device_lock, flags); sas_device = _scsih_sas_device_find_by_handle(ioc, handle); - if (sas_device) { - set_bit(handle, ioc->pd_handles); - if (sas_device->starget && sas_device->starget->hostdata) { - starget = sas_device->starget; - sas_target_priv_data = starget->hostdata; - sas_target_priv_data->flags |= - MPT_TARGET_FLAGS_RAID_COMPONENT; - sas_device->volume_handle = volume_handle; - sas_device->volume_wwid = volume_wwid; - } - } spin_unlock_irqrestore(&ioc->sas_device_lock, flags); if (!sas_device) return; /* hiding raid component */ - if (starget) - starget_for_each_device(starget, (void *)1, _scsih_reprobe_lun); + mpt2sas_config_get_volume_handle(ioc, handle, + &sas_device->volume_handle); + mpt2sas_config_get_volume_wwid(ioc, sas_device->volume_handle, + &sas_device->volume_wwid); + set_bit(handle, ioc->pd_handles); + _scsih_reprobe_target(sas_device->starget, 1); + } /** @@ -6186,9 +6132,16 @@ static void _scsih_sas_pd_delete(struct MPT2SAS_ADAPTER *ioc, Mpi2EventIrConfigElement_t *element) { + struct _sas_device *sas_device; + unsigned long flags; u16 handle = le16_to_cpu(element->PhysDiskDevHandle); - _scsih_device_remove_by_handle(ioc, handle); + spin_lock_irqsave(&ioc->sas_device_lock, flags); + sas_device = _scsih_sas_device_find_by_handle(ioc, handle); + spin_unlock_irqrestore(&ioc->sas_device_lock, flags); + if (!sas_device) + return; + _scsih_remove_device(ioc, sas_device); } /** @@ -6630,13 +6583,18 @@ _scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc, /* code added for raid transport support */ if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) { - spin_lock_irqsave(&ioc->raid_device_lock, flags); handle = le16_to_cpu(event_data->VolDevHandle); + + spin_lock_irqsave(&ioc->raid_device_lock, flags); raid_device = _scsih_raid_device_find_by_handle(ioc, handle); - if (raid_device) + spin_unlock_irqrestore(&ioc->raid_device_lock, flags); + + if (!raid_device) + return; + + if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) raid_device->percent_complete = event_data->PercentComplete; - spin_unlock_irqrestore(&ioc->raid_device_lock, flags); } } @@ -6803,18 +6761,13 @@ _scsih_mark_responding_raid_device(struct MPT2SAS_ADAPTER *ioc, u64 wwid, * required data for Direct IO */ _scsih_init_warpdrive_properties(ioc, raid_device); - spin_lock_irqsave(&ioc->raid_device_lock, flags); - if (raid_device->handle == handle) { - spin_unlock_irqrestore(&ioc->raid_device_lock, - flags); + if (raid_device->handle == handle) return; - } printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", raid_device->handle); raid_device->handle = handle; if (sas_target_priv_data) sas_target_priv_data->handle = handle; - spin_unlock_irqrestore(&ioc->raid_device_lock, flags); return; } } @@ -6986,56 +6939,58 @@ static void _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc) { struct _sas_device *sas_device, *sas_device_next; - struct _sas_node *sas_expander, *sas_expander_next; + struct _sas_node *sas_expander; struct _raid_device *raid_device, *raid_device_next; - struct list_head tmp_list; - unsigned long flags; printk(MPT2SAS_INFO_FMT "removing unresponding devices: start\n", ioc->name); - /* removing unresponding end devices */ - printk(MPT2SAS_INFO_FMT "removing unresponding devices: end-devices\n", - ioc->name); list_for_each_entry_safe(sas_device, sas_device_next, &ioc->sas_device_list, list) { - if (!sas_device->responding) - mpt2sas_device_remove_by_sas_address(ioc, - sas_device->sas_address); - else + if (sas_device->responding) { sas_device->responding = 0; + continue; + } + if (sas_device->starget) + starget_printk(KERN_INFO, sas_device->starget, + "removing: handle(0x%04x), sas_addr(0x%016llx), " + "enclosure logical id(0x%016llx), slot(%d)\n", + sas_device->handle, + (unsigned long long)sas_device->sas_address, + (unsigned long long) + sas_device->enclosure_logical_id, + sas_device->slot); + _scsih_remove_device(ioc, sas_device); } - /* removing unresponding volumes */ - if (ioc->ir_firmware) { - printk(MPT2SAS_INFO_FMT "removing unresponding devices: " - "volumes\n", ioc->name); - list_for_each_entry_safe(raid_device, raid_device_next, - &ioc->raid_device_list, list) { - if (!raid_device->responding) - _scsih_sas_volume_delete(ioc, - raid_device->handle); - else - raid_device->responding = 0; + if (!ioc->ir_firmware) + goto retry_expander_search; + + list_for_each_entry_safe(raid_device, raid_device_next, + &ioc->raid_device_list, list) { + if (raid_device->responding) { + raid_device->responding = 0; + continue; } + if (raid_device->starget) { + starget_printk(KERN_INFO, raid_device->starget, + "removing: handle(0x%04x), wwid(0x%016llx)\n", + raid_device->handle, + (unsigned long long)raid_device->wwid); + scsi_remove_target(&raid_device->starget->dev); + } + _scsih_raid_device_remove(ioc, raid_device); } - /* removing unresponding expanders */ - printk(MPT2SAS_INFO_FMT "removing unresponding devices: expanders\n", - ioc->name); - spin_lock_irqsave(&ioc->sas_node_lock, flags); - INIT_LIST_HEAD(&tmp_list); - list_for_each_entry_safe(sas_expander, sas_expander_next, - &ioc->sas_expander_list, list) { - if (!sas_expander->responding) - list_move_tail(&sas_expander->list, &tmp_list); - else + + retry_expander_search: + sas_expander = NULL; + list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) { + if (sas_expander->responding) { sas_expander->responding = 0; - } - spin_unlock_irqrestore(&ioc->sas_node_lock, flags); - list_for_each_entry_safe(sas_expander, sas_expander_next, &tmp_list, - list) { - list_del(&sas_expander->list); - _scsih_expander_node_remove(ioc, sas_expander); + continue; + } + mpt2sas_expander_remove(ioc, sas_expander->sas_address); + goto retry_expander_search; } printk(MPT2SAS_INFO_FMT "removing unresponding devices: complete\n", ioc->name); @@ -7088,7 +7043,6 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc) struct _sas_device *sas_device; struct _sas_node *expander_device; static struct _raid_device *raid_device; - unsigned long flags; printk(MPT2SAS_INFO_FMT "scan devices: start\n", ioc->name); @@ -7103,10 +7057,8 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc) if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) break; handle = le16_to_cpu(expander_pg0.DevHandle); - spin_lock_irqsave(&ioc->sas_node_lock, flags); expander_device = mpt2sas_scsih_expander_find_by_sas_address( ioc, le64_to_cpu(expander_pg0.SASAddress)); - spin_unlock_irqrestore(&ioc->sas_node_lock, flags); if (expander_device) _scsih_refresh_expander_links(ioc, expander_device, handle); @@ -7128,9 +7080,7 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc) break; phys_disk_num = pd_pg0.PhysDiskNum; handle = le16_to_cpu(pd_pg0.DevHandle); - spin_lock_irqsave(&ioc->sas_device_lock, flags); sas_device = _scsih_sas_device_find_by_handle(ioc, handle); - spin_unlock_irqrestore(&ioc->sas_device_lock, flags); if (sas_device) continue; if (mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, @@ -7157,10 +7107,8 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc) if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) break; handle = le16_to_cpu(volume_pg1.DevHandle); - spin_lock_irqsave(&ioc->raid_device_lock, flags); raid_device = _scsih_raid_device_find_by_wwid(ioc, le64_to_cpu(volume_pg1.WWID)); - spin_unlock_irqrestore(&ioc->raid_device_lock, flags); if (raid_device) continue; if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, @@ -7192,10 +7140,8 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc) if (!(_scsih_is_end_device( le32_to_cpu(sas_device_pg0.DeviceInfo)))) continue; - spin_lock_irqsave(&ioc->sas_device_lock, flags); sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, le64_to_cpu(sas_device_pg0.SASAddress)); - spin_unlock_irqrestore(&ioc->sas_device_lock, flags); if (sas_device) continue; parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); @@ -7289,7 +7235,7 @@ _firmware_event_work(struct work_struct *work) switch (fw_event->event) { case MPT2SAS_REMOVE_UNRESPONDING_DEVICES: - while (scsi_host_in_recovery(ioc->shost) || ioc->shost_recovery) + while (scsi_host_in_recovery(ioc->shost)) ssleep(1); _scsih_remove_unresponding_sas_devices(ioc); _scsih_scan_for_devices_after_reset(ioc); @@ -7367,13 +7313,6 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, return 1; mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); - - if (unlikely(!mpi_reply)) { - printk(MPT2SAS_ERR_FMT "mpi_reply not valid at %s:%d/%s()!\n", - ioc->name, __FILE__, __LINE__, __func__); - return 1; - } - event = le16_to_cpu(mpi_reply->Event); switch (event) { @@ -7414,14 +7353,14 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, case MPI2_EVENT_LOG_ENTRY_ADDED: { Mpi2EventDataLogEntryAdded_t *log_entry; - __le32 *log_code; + u32 *log_code; if (!ioc->is_warpdrive) break; log_entry = (Mpi2EventDataLogEntryAdded_t *) mpi_reply->EventData; - log_code = (__le32 *)log_entry->LogData; + log_code = (u32 *)log_entry->LogData; if (le16_to_cpu(log_entry->LogEntryQualifier) != MPT2_WARPDRIVE_LOGENTRY) @@ -7548,7 +7487,7 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc, return; if (mpt2sas_port->remote_identify.device_type == SAS_END_DEVICE) - mpt2sas_device_remove_by_sas_address(ioc, + mpt2sas_device_remove(ioc, mpt2sas_port->remote_identify.sas_address); else if (mpt2sas_port->remote_identify.device_type == SAS_EDGE_EXPANDER_DEVICE || @@ -7722,7 +7661,7 @@ _scsih_remove(struct pci_dev *pdev) &ioc->sas_hba.sas_port_list, port_list) { if (mpt2sas_port->remote_identify.device_type == SAS_END_DEVICE) - mpt2sas_device_remove_by_sas_address(ioc, + mpt2sas_device_remove(ioc, mpt2sas_port->remote_identify.sas_address); else if (mpt2sas_port->remote_identify.device_type == SAS_EDGE_EXPANDER_DEVICE || @@ -7794,11 +7733,11 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc) if (rc) _scsih_raid_device_remove(ioc, raid_device); } else { - spin_lock_irqsave(&ioc->sas_device_lock, flags); sas_device = device; handle = sas_device->handle; sas_address_parent = sas_device->sas_address_parent; sas_address = sas_device->sas_address; + spin_lock_irqsave(&ioc->sas_device_lock, flags); list_move_tail(&sas_device->list, &ioc->sas_device_list); spin_unlock_irqrestore(&ioc->sas_device_lock, flags); @@ -8122,8 +8061,8 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) out_thread_fail: list_del(&ioc->list); scsi_remove_host(shost); - out_add_shost_fail: scsi_host_put(shost); + out_add_shost_fail: return -ENODEV; } diff --git a/trunk/drivers/scsi/mpt2sas/mpt2sas_transport.c b/trunk/drivers/scsi/mpt2sas/mpt2sas_transport.c index c6cf20f60720..831047466a5a 100644 --- a/trunk/drivers/scsi/mpt2sas/mpt2sas_transport.c +++ b/trunk/drivers/scsi/mpt2sas/mpt2sas_transport.c @@ -163,15 +163,12 @@ _transport_set_identify(struct MPT2SAS_ADAPTER *ioc, u16 handle, return -EIO; } - memset(identify, 0, sizeof(struct sas_identify)); + memset(identify, 0, sizeof(*identify)); device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); /* sas_address */ identify->sas_address = le64_to_cpu(sas_device_pg0.SASAddress); - /* phy number of the parent device this device is linked to */ - identify->phy_identifier = sas_device_pg0.PhyNum; - /* device_type */ switch (device_info & MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) { case MPI2_SAS_DEVICE_INFO_NO_DEVICE: @@ -487,7 +484,7 @@ _transport_delete_port(struct MPT2SAS_ADAPTER *ioc, ioc->logging_level |= MPT_DEBUG_TRANSPORT; if (device_type == SAS_END_DEVICE) - mpt2sas_device_remove_by_sas_address(ioc, sas_address); + mpt2sas_device_remove(ioc, sas_address); else if (device_type == SAS_EDGE_EXPANDER_DEVICE || device_type == SAS_FANOUT_EXPANDER_DEVICE) mpt2sas_expander_remove(ioc, sas_address); @@ -795,10 +792,9 @@ mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, spin_lock_irqsave(&ioc->sas_node_lock, flags); sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address_parent); - if (!sas_node) { - spin_unlock_irqrestore(&ioc->sas_node_lock, flags); + spin_unlock_irqrestore(&ioc->sas_node_lock, flags); + if (!sas_node) return; - } list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list, port_list) { if (mpt2sas_port->remote_identify.sas_address != sas_address) @@ -808,10 +804,8 @@ mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, goto out; } out: - if (!found) { - spin_unlock_irqrestore(&ioc->sas_node_lock, flags); + if (!found) return; - } for (i = 0; i < sas_node->num_phys; i++) { if (sas_node->phy[i].remote_identify.sas_address == sas_address) @@ -819,7 +813,6 @@ mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, sizeof(struct sas_identify)); } - spin_unlock_irqrestore(&ioc->sas_node_lock, flags); list_for_each_entry_safe(mpt2sas_phy, next_phy, &mpt2sas_port->phy_list, port_siblings) { if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) @@ -993,14 +986,12 @@ mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, spin_lock_irqsave(&ioc->sas_node_lock, flags); sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address); - if (!sas_node) { - spin_unlock_irqrestore(&ioc->sas_node_lock, flags); + spin_unlock_irqrestore(&ioc->sas_node_lock, flags); + if (!sas_node) return; - } mpt2sas_phy = &sas_node->phy[phy_number]; mpt2sas_phy->attached_handle = handle; - spin_unlock_irqrestore(&ioc->sas_node_lock, flags); if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) { _transport_set_identify(ioc, handle, &mpt2sas_phy->remote_identify); @@ -1319,20 +1310,17 @@ _transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier) struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy); struct _sas_device *sas_device; unsigned long flags; - int rc; spin_lock_irqsave(&ioc->sas_device_lock, flags); sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, rphy->identify.sas_address); - if (sas_device) { - *identifier = sas_device->enclosure_logical_id; - rc = 0; - } else { - *identifier = 0; - rc = -ENXIO; - } spin_unlock_irqrestore(&ioc->sas_device_lock, flags); - return rc; + + if (!sas_device) + return -ENXIO; + + *identifier = sas_device->enclosure_logical_id; + return 0; } /** @@ -1347,17 +1335,16 @@ _transport_get_bay_identifier(struct sas_rphy *rphy) struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy); struct _sas_device *sas_device; unsigned long flags; - int rc; spin_lock_irqsave(&ioc->sas_device_lock, flags); sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, rphy->identify.sas_address); - if (sas_device) - rc = sas_device->slot; - else - rc = -ENXIO; spin_unlock_irqrestore(&ioc->sas_device_lock, flags); - return rc; + + if (!sas_device) + return -ENXIO; + + return sas_device->slot; } /* phy control request structure */ @@ -1642,13 +1629,11 @@ _transport_phy_enable(struct sas_phy *phy, int enable) { struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy); Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; - Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; Mpi2ConfigReply_t mpi_reply; u16 ioc_status; u16 sz; int rc = 0; unsigned long flags; - int i, discovery_active; spin_lock_irqsave(&ioc->sas_node_lock, flags); if (_transport_sas_node_find_by_sas_address(ioc, @@ -1666,50 +1651,7 @@ _transport_phy_enable(struct sas_phy *phy, int enable) /* handle hba phys */ - /* read sas_iounit page 0 */ - sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys * - sizeof(Mpi2SasIOUnit0PhyData_t)); - sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL); - if (!sas_iounit_pg0) { - printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", - ioc->name, __FILE__, __LINE__, __func__); - rc = -ENOMEM; - goto out; - } - if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply, - sas_iounit_pg0, sz))) { - printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", - ioc->name, __FILE__, __LINE__, __func__); - rc = -ENXIO; - goto out; - } - ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & - MPI2_IOCSTATUS_MASK; - if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { - printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", - ioc->name, __FILE__, __LINE__, __func__); - rc = -EIO; - goto out; - } - - /* unable to enable/disable phys when when discovery is active */ - for (i = 0, discovery_active = 0; i < ioc->sas_hba.num_phys ; i++) { - if (sas_iounit_pg0->PhyData[i].PortFlags & - MPI2_SASIOUNIT0_PORTFLAGS_DISCOVERY_IN_PROGRESS) { - printk(MPT2SAS_ERR_FMT "discovery is active on " - "port = %d, phy = %d: unable to enable/disable " - "phys, try again later!\n", ioc->name, - sas_iounit_pg0->PhyData[i].Port, i); - discovery_active = 1; - } - } - - if (discovery_active) { - rc = -EAGAIN; - goto out; - } - - /* read sas_iounit page 1 */ + /* sas_iounit page 1 */ sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys * sizeof(Mpi2SasIOUnit1PhyData_t)); sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); @@ -1734,18 +1676,7 @@ _transport_phy_enable(struct sas_phy *phy, int enable) rc = -EIO; goto out; } - /* copy Port/PortFlags/PhyFlags from page 0 */ - for (i = 0; i < ioc->sas_hba.num_phys ; i++) { - sas_iounit_pg1->PhyData[i].Port = - sas_iounit_pg0->PhyData[i].Port; - sas_iounit_pg1->PhyData[i].PortFlags = - (sas_iounit_pg0->PhyData[i].PortFlags & - MPI2_SASIOUNIT0_PORTFLAGS_AUTO_PORT_CONFIG); - sas_iounit_pg1->PhyData[i].PhyFlags = - (sas_iounit_pg0->PhyData[i].PhyFlags & - (MPI2_SASIOUNIT0_PHYFLAGS_ZONING_ENABLED + - MPI2_SASIOUNIT0_PHYFLAGS_PHY_DISABLED)); - } + if (enable) sas_iounit_pg1->PhyData[phy->number].PhyFlags &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE; @@ -1761,7 +1692,6 @@ _transport_phy_enable(struct sas_phy *phy, int enable) out: kfree(sas_iounit_pg1); - kfree(sas_iounit_pg0); return rc; } @@ -1898,7 +1828,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); Mpi2SmpPassthroughRequest_t *mpi_request; Mpi2SmpPassthroughReply_t *mpi_reply; - int rc, i; + int rc; u16 smid; u32 ioc_state; unsigned long timeleft; @@ -1907,20 +1837,24 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, u8 issue_reset = 0; dma_addr_t dma_addr_in = 0; dma_addr_t dma_addr_out = 0; - dma_addr_t pci_dma_in = 0; - dma_addr_t pci_dma_out = 0; - void *pci_addr_in = NULL; - void *pci_addr_out = NULL; u16 wait_state_count; struct request *rsp = req->next_rq; - struct bio_vec *bvec = NULL; if (!rsp) { printk(MPT2SAS_ERR_FMT "%s: the smp response space is " "missing\n", ioc->name, __func__); return -EINVAL; } - if (ioc->shost_recovery || ioc->pci_error_recovery) { + + /* do we need to support multiple segments? */ + if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) { + printk(MPT2SAS_ERR_FMT "%s: multiple segments req %u %u, " + "rsp %u %u\n", ioc->name, __func__, req->bio->bi_vcnt, + blk_rq_bytes(req), rsp->bio->bi_vcnt, blk_rq_bytes(rsp)); + return -EINVAL; + } + + if (ioc->shost_recovery) { printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", __func__, ioc->name); return -EFAULT; @@ -1938,59 +1872,6 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, } ioc->transport_cmds.status = MPT2_CMD_PENDING; - /* Check if the request is split across multiple segments */ - if (req->bio->bi_vcnt > 1) { - u32 offset = 0; - - /* Allocate memory and copy the request */ - pci_addr_out = pci_alloc_consistent(ioc->pdev, - blk_rq_bytes(req), &pci_dma_out); - if (!pci_addr_out) { - printk(MPT2SAS_INFO_FMT "%s(): PCI Addr out = NULL\n", - ioc->name, __func__); - rc = -ENOMEM; - goto out; - } - - bio_for_each_segment(bvec, req->bio, i) { - memcpy(pci_addr_out + offset, - page_address(bvec->bv_page) + bvec->bv_offset, - bvec->bv_len); - offset += bvec->bv_len; - } - } else { - dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio), - blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL); - if (!dma_addr_out) { - printk(MPT2SAS_INFO_FMT "%s(): DMA Addr out = NULL\n", - ioc->name, __func__); - rc = -ENOMEM; - goto free_pci; - } - } - - /* Check if the response needs to be populated across - * multiple segments */ - if (rsp->bio->bi_vcnt > 1) { - pci_addr_in = pci_alloc_consistent(ioc->pdev, blk_rq_bytes(rsp), - &pci_dma_in); - if (!pci_addr_in) { - printk(MPT2SAS_INFO_FMT "%s(): PCI Addr in = NULL\n", - ioc->name, __func__); - rc = -ENOMEM; - goto unmap; - } - } else { - dma_addr_in = pci_map_single(ioc->pdev, bio_data(rsp->bio), - blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL); - if (!dma_addr_in) { - printk(MPT2SAS_INFO_FMT "%s(): DMA Addr in = NULL\n", - ioc->name, __func__); - rc = -ENOMEM; - goto unmap; - } - } - wait_state_count = 0; ioc_state = mpt2sas_base_get_iocstate(ioc, 1); while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { @@ -1999,7 +1880,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, "%s: failed due to ioc not operational\n", ioc->name, __func__); rc = -EFAULT; - goto unmap; + goto out; } ssleep(1); ioc_state = mpt2sas_base_get_iocstate(ioc, 1); @@ -2016,7 +1897,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", ioc->name, __func__); rc = -EAGAIN; - goto unmap; + goto out; } rc = 0; @@ -2038,14 +1919,16 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC); sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; - if (req->bio->bi_vcnt > 1) { - ioc->base_add_sg_single(psge, sgl_flags | - (blk_rq_bytes(req) - 4), pci_dma_out); - } else { - ioc->base_add_sg_single(psge, sgl_flags | - (blk_rq_bytes(req) - 4), dma_addr_out); + dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio), + blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL); + if (!dma_addr_out) { + mpt2sas_base_free_smid(ioc, smid); + goto unmap; } + ioc->base_add_sg_single(psge, sgl_flags | (blk_rq_bytes(req) - 4), + dma_addr_out); + /* incr sgel */ psge += ioc->sge_size; @@ -2054,14 +1937,16 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_END_OF_LIST); sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; - if (rsp->bio->bi_vcnt > 1) { - ioc->base_add_sg_single(psge, sgl_flags | - (blk_rq_bytes(rsp) + 4), pci_dma_in); - } else { - ioc->base_add_sg_single(psge, sgl_flags | - (blk_rq_bytes(rsp) + 4), dma_addr_in); + dma_addr_in = pci_map_single(ioc->pdev, bio_data(rsp->bio), + blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL); + if (!dma_addr_in) { + mpt2sas_base_free_smid(ioc, smid); + goto unmap; } + ioc->base_add_sg_single(psge, sgl_flags | (blk_rq_bytes(rsp) + 4), + dma_addr_in); + dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "%s - " "sending smp request\n", ioc->name, __func__)); @@ -2097,27 +1982,6 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, req->resid_len = 0; rsp->resid_len -= le16_to_cpu(mpi_reply->ResponseDataLength); - /* check if the resp needs to be copied from the allocated - * pci mem */ - if (rsp->bio->bi_vcnt > 1) { - u32 offset = 0; - u32 bytes_to_copy = - le16_to_cpu(mpi_reply->ResponseDataLength); - bio_for_each_segment(bvec, rsp->bio, i) { - if (bytes_to_copy <= bvec->bv_len) { - memcpy(page_address(bvec->bv_page) + - bvec->bv_offset, pci_addr_in + - offset, bytes_to_copy); - break; - } else { - memcpy(page_address(bvec->bv_page) + - bvec->bv_offset, pci_addr_in + - offset, bvec->bv_len); - bytes_to_copy -= bvec->bv_len; - } - offset += bvec->bv_len; - } - } } else { dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "%s - no reply\n", ioc->name, __func__)); @@ -2139,15 +2003,6 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, pci_unmap_single(ioc->pdev, dma_addr_in, blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL); - free_pci: - if (pci_addr_out) - pci_free_consistent(ioc->pdev, blk_rq_bytes(req), pci_addr_out, - pci_dma_out); - - if (pci_addr_in) - pci_free_consistent(ioc->pdev, blk_rq_bytes(rsp), pci_addr_in, - pci_dma_in); - out: ioc->transport_cmds.status = MPT2_CMD_NOT_USED; mutex_unlock(&ioc->transport_cmds.mutex); diff --git a/trunk/drivers/scsi/pm8001/pm8001_defs.h b/trunk/drivers/scsi/pm8001/pm8001_defs.h index c3d20c8d4abe..944afada61ee 100644 --- a/trunk/drivers/scsi/pm8001/pm8001_defs.h +++ b/trunk/drivers/scsi/pm8001/pm8001_defs.h @@ -66,10 +66,9 @@ enum port_type { /* driver compile-time configuration */ #define PM8001_MAX_CCB 512 /* max ccbs supported */ -#define PM8001_MPI_QUEUE 1024 /* maximum mpi queue entries */ #define PM8001_MAX_INB_NUM 1 #define PM8001_MAX_OUTB_NUM 1 -#define PM8001_CAN_QUEUE 508 /* SCSI Queue depth */ +#define PM8001_CAN_QUEUE 128 /* SCSI Queue depth */ /* unchangeable hardware details */ #define PM8001_MAX_PHYS 8 /* max. possible phys */ diff --git a/trunk/drivers/scsi/pm8001/pm8001_hwi.c b/trunk/drivers/scsi/pm8001/pm8001_hwi.c index bf54aafc2d71..9d82ee5c10de 100644 --- a/trunk/drivers/scsi/pm8001/pm8001_hwi.c +++ b/trunk/drivers/scsi/pm8001/pm8001_hwi.c @@ -192,7 +192,7 @@ init_default_table_values(struct pm8001_hba_info *pm8001_ha) pm8001_ha->main_cfg_tbl.fatal_err_interrupt = 0x01; for (i = 0; i < qn; i++) { pm8001_ha->inbnd_q_tbl[i].element_pri_size_cnt = - PM8001_MPI_QUEUE | (64 << 16) | (0x00<<30); + 0x00000100 | (0x00000040 << 16) | (0x00<<30); pm8001_ha->inbnd_q_tbl[i].upper_base_addr = pm8001_ha->memoryMap.region[IB].phys_addr_hi; pm8001_ha->inbnd_q_tbl[i].lower_base_addr = @@ -218,7 +218,7 @@ init_default_table_values(struct pm8001_hba_info *pm8001_ha) } for (i = 0; i < qn; i++) { pm8001_ha->outbnd_q_tbl[i].element_size_cnt = - PM8001_MPI_QUEUE | (64 << 16) | (0x01<<30); + 256 | (64 << 16) | (1<<30); pm8001_ha->outbnd_q_tbl[i].upper_base_addr = pm8001_ha->memoryMap.region[OB].phys_addr_hi; pm8001_ha->outbnd_q_tbl[i].lower_base_addr = @@ -1245,7 +1245,7 @@ static int mpi_msg_free_get(struct inbound_queue_table *circularQ, /* Stores the new consumer index */ consumer_index = pm8001_read_32(circularQ->ci_virt); circularQ->consumer_index = cpu_to_le32(consumer_index); - if (((circularQ->producer_idx + bcCount) % PM8001_MPI_QUEUE) == + if (((circularQ->producer_idx + bcCount) % 256) == le32_to_cpu(circularQ->consumer_index)) { *messagePtr = NULL; return -1; @@ -1253,8 +1253,7 @@ static int mpi_msg_free_get(struct inbound_queue_table *circularQ, /* get memory IOMB buffer address */ offset = circularQ->producer_idx * 64; /* increment to next bcCount element */ - circularQ->producer_idx = (circularQ->producer_idx + bcCount) - % PM8001_MPI_QUEUE; + circularQ->producer_idx = (circularQ->producer_idx + bcCount) % 256; /* Adds that distance to the base of the region virtual address plus the message header size*/ msgHeader = (struct mpi_msg_hdr *)(circularQ->base_virt + offset); @@ -1327,8 +1326,7 @@ static u32 mpi_msg_free_set(struct pm8001_hba_info *pm8001_ha, void *pMsg, return 0; } /* free the circular queue buffer elements associated with the message*/ - circularQ->consumer_idx = (circularQ->consumer_idx + bc) - % PM8001_MPI_QUEUE; + circularQ->consumer_idx = (circularQ->consumer_idx + bc) % 256; /* update the CI of outbound queue */ pm8001_cw32(pm8001_ha, circularQ->ci_pci_bar, circularQ->ci_offset, circularQ->consumer_idx); @@ -1385,8 +1383,7 @@ static u32 mpi_msg_consume(struct pm8001_hba_info *pm8001_ha, circularQ->consumer_idx = (circularQ->consumer_idx + ((le32_to_cpu(msgHeader_tmp) - >> 24) & 0x1f)) - % PM8001_MPI_QUEUE; + >> 24) & 0x1f)) % 256; msgHeader_tmp = 0; pm8001_write_32(msgHeader, 0, 0); /* update the CI of outbound queue */ @@ -1399,7 +1396,7 @@ static u32 mpi_msg_consume(struct pm8001_hba_info *pm8001_ha, circularQ->consumer_idx = (circularQ->consumer_idx + ((le32_to_cpu(msgHeader_tmp) >> 24) & - 0x1f)) % PM8001_MPI_QUEUE; + 0x1f)) % 256; msgHeader_tmp = 0; pm8001_write_32(msgHeader, 0, 0); /* update the CI of outbound queue */ @@ -3360,7 +3357,7 @@ mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) struct fw_control_ex fw_control_context; struct fw_flash_Update_resp *ppayload = (struct fw_flash_Update_resp *)(piomb + 4); - u32 tag = le32_to_cpu(ppayload->tag); + u32 tag = ppayload->tag; struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag]; status = le32_to_cpu(ppayload->status); memcpy(&fw_control_context, @@ -3706,8 +3703,8 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb) */ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb) { - __le32 pHeader = *(__le32 *)piomb; - u8 opc = (u8)((le32_to_cpu(pHeader)) & 0xFFF); + u32 pHeader = (u32)*(u32 *)piomb; + u8 opc = (u8)(pHeader & 0xFFF); PM8001_MSG_DBG(pm8001_ha, pm8001_printk("process_one_iomb:")); diff --git a/trunk/drivers/scsi/pm8001/pm8001_hwi.h b/trunk/drivers/scsi/pm8001/pm8001_hwi.h index d437309cb1e1..1a4611eb0321 100644 --- a/trunk/drivers/scsi/pm8001/pm8001_hwi.h +++ b/trunk/drivers/scsi/pm8001/pm8001_hwi.h @@ -599,7 +599,7 @@ struct fw_flash_Update_req { * */ struct fw_flash_Update_resp { - __le32 tag; + dma_addr_t tag; __le32 status; u32 reserved[13]; } __attribute__((packed, aligned(4))); diff --git a/trunk/drivers/scsi/pm8001/pm8001_init.c b/trunk/drivers/scsi/pm8001/pm8001_init.c index 0267c22f8741..36efaa7c3a54 100644 --- a/trunk/drivers/scsi/pm8001/pm8001_init.c +++ b/trunk/drivers/scsi/pm8001/pm8001_init.c @@ -235,15 +235,15 @@ static int __devinit pm8001_alloc(struct pm8001_hba_info *pm8001_ha) pm8001_ha->memoryMap.region[PI].alignment = 4; /* MPI Memory region 5 inbound queues */ - pm8001_ha->memoryMap.region[IB].num_elements = PM8001_MPI_QUEUE; + pm8001_ha->memoryMap.region[IB].num_elements = 256; pm8001_ha->memoryMap.region[IB].element_size = 64; - pm8001_ha->memoryMap.region[IB].total_len = PM8001_MPI_QUEUE * 64; + pm8001_ha->memoryMap.region[IB].total_len = 256 * 64; pm8001_ha->memoryMap.region[IB].alignment = 64; - /* MPI Memory region 6 outbound queues */ - pm8001_ha->memoryMap.region[OB].num_elements = PM8001_MPI_QUEUE; + /* MPI Memory region 6 inbound queues */ + pm8001_ha->memoryMap.region[OB].num_elements = 256; pm8001_ha->memoryMap.region[OB].element_size = 64; - pm8001_ha->memoryMap.region[OB].total_len = PM8001_MPI_QUEUE * 64; + pm8001_ha->memoryMap.region[OB].total_len = 256 * 64; pm8001_ha->memoryMap.region[OB].alignment = 64; /* Memory region write DMA*/ diff --git a/trunk/drivers/scsi/qla2xxx/qla_bsg.c b/trunk/drivers/scsi/qla2xxx/qla_bsg.c index bc3cc6d91117..f74cc0602f3b 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_bsg.c +++ b/trunk/drivers/scsi/qla2xxx/qla_bsg.c @@ -1367,9 +1367,6 @@ qla2x00_read_optrom(struct fc_bsg_job *bsg_job) struct qla_hw_data *ha = vha->hw; int rval = 0; - if (ha->flags.isp82xx_reset_hdlr_active) - return -EBUSY; - rval = qla2x00_optrom_setup(bsg_job, vha, 0); if (rval) return rval; diff --git a/trunk/drivers/scsi/qla2xxx/qla_dbg.c b/trunk/drivers/scsi/qla2xxx/qla_dbg.c index 62324a1d5573..897731b93df2 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_dbg.c +++ b/trunk/drivers/scsi/qla2xxx/qla_dbg.c @@ -15,7 +15,7 @@ * | Mailbox commands | 0x113e | 0x112c-0x112e | * | | | 0x113a | * | Device Discovery | 0x2086 | 0x2020-0x2022 | - * | Queue Command and IO tracing | 0x3030 | 0x3006,0x3008 | + * | Queue Command and IO tracing | 0x302f | 0x3006,0x3008 | * | | | 0x302d-0x302e | * | DPC Thread | 0x401c | | * | Async Events | 0x505d | 0x502b-0x502f | diff --git a/trunk/drivers/scsi/qla2xxx/qla_isr.c b/trunk/drivers/scsi/qla2xxx/qla_isr.c index ce42288049b5..f79844ce7122 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_isr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_isr.c @@ -1715,24 +1715,13 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) res = DID_ERROR << 16; break; } - } else if (lscsi_status != SAM_STAT_TASK_SET_FULL && - lscsi_status != SAM_STAT_BUSY) { - /* - * scsi status of task set and busy are considered to be - * task not completed. - */ - + } else { ql_dbg(ql_dbg_io, fcport->vha, 0x301f, "Dropped frame(s) detected (0x%x " - "of 0x%x bytes).\n", resid, - scsi_bufflen(cp)); + "of 0x%x bytes).\n", resid, scsi_bufflen(cp)); res = DID_ERROR << 16 | lscsi_status; goto check_scsi_status; - } else { - ql_dbg(ql_dbg_io, fcport->vha, 0x3030, - "scsi_status: 0x%x, lscsi_status: 0x%x\n", - scsi_status, lscsi_status); } res = DID_OK << 16 | lscsi_status; diff --git a/trunk/drivers/scsi/qla2xxx/qla_nx.c b/trunk/drivers/scsi/qla2xxx/qla_nx.c index de722a933438..f0528539bbbc 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_nx.c +++ b/trunk/drivers/scsi/qla2xxx/qla_nx.c @@ -3125,7 +3125,6 @@ qla82xx_need_reset_handler(scsi_qla_host_t *vha) ql_log(ql_log_info, vha, 0x00b7, "HW State: COLD/RE-INIT.\n"); qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_COLD); - qla82xx_set_rst_ready(ha); if (ql2xmdenable) { if (qla82xx_md_collect(vha)) ql_log(ql_log_warn, vha, 0xb02c, diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c index 7db803377c64..a2f999273a5f 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_os.c +++ b/trunk/drivers/scsi/qla2xxx/qla_os.c @@ -3577,25 +3577,9 @@ void qla2x00_relogin(struct scsi_qla_host *vha) continue; /* Attempt a retry. */ status = 1; - } else { + } else status = qla2x00_fabric_login(vha, fcport, &next_loopid); - if (status == QLA_SUCCESS) { - int status2; - uint8_t opts; - - opts = 0; - if (fcport->flags & - FCF_FCP2_DEVICE) - opts |= BIT_1; - status2 = - qla2x00_get_port_database( - vha, fcport, - opts); - if (status2 != QLA_SUCCESS) - status = 1; - } - } } else status = qla2x00_local_device_login(vha, fcport); diff --git a/trunk/drivers/scsi/qla2xxx/qla_sup.c b/trunk/drivers/scsi/qla2xxx/qla_sup.c index a683e766d1ae..3c13c0a6be63 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_sup.c +++ b/trunk/drivers/scsi/qla2xxx/qla_sup.c @@ -1017,9 +1017,6 @@ qla2xxx_flash_npiv_conf(scsi_qla_host_t *vha) !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha)) return; - if (ha->flags.isp82xx_reset_hdlr_active) - return; - ha->isp_ops->read_optrom(vha, (uint8_t *)&hdr, ha->flt_region_npiv_conf << 2, sizeof(struct qla_npiv_header)); if (hdr.version == __constant_cpu_to_le16(0xffff)) diff --git a/trunk/drivers/scsi/qla2xxx/qla_version.h b/trunk/drivers/scsi/qla2xxx/qla_version.h index f5fdb16bec9b..29d780c38040 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_version.h +++ b/trunk/drivers/scsi/qla2xxx/qla_version.h @@ -7,9 +7,9 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.04.00.03-k" +#define QLA2XXX_VERSION "8.03.07.13-k" #define QLA_DRIVER_MAJOR_VER 8 -#define QLA_DRIVER_MINOR_VER 4 -#define QLA_DRIVER_PATCH_VER 0 +#define QLA_DRIVER_MINOR_VER 3 +#define QLA_DRIVER_PATCH_VER 7 #define QLA_DRIVER_BETA_VER 3 diff --git a/trunk/drivers/scsi/scsi.c b/trunk/drivers/scsi/scsi.c index 61c82a345f82..07322ecff90d 100644 --- a/trunk/drivers/scsi/scsi.c +++ b/trunk/drivers/scsi/scsi.c @@ -90,12 +90,6 @@ unsigned int scsi_logging_level; EXPORT_SYMBOL(scsi_logging_level); #endif -#if IS_ENABLED(CONFIG_PM) || IS_ENABLED(CONFIG_BLK_DEV_SD) -/* sd and scsi_pm need to coordinate flushing async actions */ -LIST_HEAD(scsi_sd_probe_domain); -EXPORT_SYMBOL(scsi_sd_probe_domain); -#endif - /* NB: These are exposed through /proc/scsi/scsi and form part of the ABI. * You may not alter any existing entry (although adding new ones is * encouraged once assigned by ANSI/INCITS T10 diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index 62ddfd31d4ce..5dfd7495d1a1 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -2348,14 +2348,10 @@ EXPORT_SYMBOL(scsi_device_quiesce); * * Must be called with user context, may sleep. */ -void scsi_device_resume(struct scsi_device *sdev) +void +scsi_device_resume(struct scsi_device *sdev) { - /* check if the device state was mutated prior to resume, and if - * so assume the state is being managed elsewhere (for example - * device deleted during suspend) - */ - if (sdev->sdev_state != SDEV_QUIESCE || - scsi_device_set_state(sdev, SDEV_RUNNING)) + if(scsi_device_set_state(sdev, SDEV_RUNNING)) return; scsi_run_queue(sdev->request_queue); } diff --git a/trunk/drivers/scsi/scsi_pm.c b/trunk/drivers/scsi/scsi_pm.c index f661a41fa4c6..c4670642d023 100644 --- a/trunk/drivers/scsi/scsi_pm.c +++ b/trunk/drivers/scsi/scsi_pm.c @@ -97,7 +97,7 @@ static int scsi_bus_prepare(struct device *dev) { if (scsi_is_sdev_device(dev)) { /* sd probing uses async_schedule. Wait until it finishes. */ - async_synchronize_full_domain(&scsi_sd_probe_domain); + async_synchronize_full(); } else if (scsi_is_host_device(dev)) { /* Wait until async scanning is finished */ diff --git a/trunk/drivers/scsi/scsi_priv.h b/trunk/drivers/scsi/scsi_priv.h index 07ce3f51701d..be4fa6d179b1 100644 --- a/trunk/drivers/scsi/scsi_priv.h +++ b/trunk/drivers/scsi/scsi_priv.h @@ -163,8 +163,6 @@ static inline int scsi_autopm_get_host(struct Scsi_Host *h) { return 0; } static inline void scsi_autopm_put_host(struct Scsi_Host *h) {} #endif /* CONFIG_PM_RUNTIME */ -extern struct list_head scsi_sd_probe_domain; - /* * internal scsi timeout functions: for use by mid-layer and transport * classes. diff --git a/trunk/drivers/scsi/scsi_transport_fc.c b/trunk/drivers/scsi/scsi_transport_fc.c index 579760420d53..80fbe2ac0b47 100644 --- a/trunk/drivers/scsi/scsi_transport_fc.c +++ b/trunk/drivers/scsi/scsi_transport_fc.c @@ -2808,20 +2808,17 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, FC_RPORT_DEVLOSS_PENDING | FC_RPORT_DEVLOSS_CALLBK_DONE); - spin_unlock_irqrestore(shost->host_lock, flags); - /* if target, initiate a scan */ if (rport->scsi_target_id != -1) { - scsi_target_unblock(&rport->dev); - - spin_lock_irqsave(shost->host_lock, - flags); rport->flags |= FC_RPORT_SCAN_PENDING; scsi_queue_work(shost, &rport->scan_work); spin_unlock_irqrestore(shost->host_lock, flags); - } + scsi_target_unblock(&rport->dev); + } else + spin_unlock_irqrestore(shost->host_lock, + flags); fc_bsg_goose_queue(rport); @@ -2879,17 +2876,16 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, if (fci->f->dd_fcrport_size) memset(rport->dd_data, 0, fci->f->dd_fcrport_size); - spin_unlock_irqrestore(shost->host_lock, flags); - - if (ids->roles & FC_PORT_ROLE_FCP_TARGET) { - scsi_target_unblock(&rport->dev); + if (rport->roles & FC_PORT_ROLE_FCP_TARGET) { /* initiate a scan of the target */ - spin_lock_irqsave(shost->host_lock, flags); rport->flags |= FC_RPORT_SCAN_PENDING; scsi_queue_work(shost, &rport->scan_work); spin_unlock_irqrestore(shost->host_lock, flags); - } + scsi_target_unblock(&rport->dev); + } else + spin_unlock_irqrestore(shost->host_lock, flags); + return rport; } } @@ -3087,12 +3083,12 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) /* ensure any stgt delete functions are done */ fc_flush_work(shost); - scsi_target_unblock(&rport->dev); /* initiate a scan of the target */ spin_lock_irqsave(shost->host_lock, flags); rport->flags |= FC_RPORT_SCAN_PENDING; scsi_queue_work(shost, &rport->scan_work); spin_unlock_irqrestore(shost->host_lock, flags); + scsi_target_unblock(&rport->dev); } } EXPORT_SYMBOL(fc_remote_port_rolechg); diff --git a/trunk/drivers/scsi/scsi_transport_spi.c b/trunk/drivers/scsi/scsi_transport_spi.c index cf08071a9b6e..a2715c31e754 100644 --- a/trunk/drivers/scsi/scsi_transport_spi.c +++ b/trunk/drivers/scsi/scsi_transport_spi.c @@ -1010,10 +1010,10 @@ spi_dv_device(struct scsi_device *sdev) u8 *buffer; const int len = SPI_MAX_ECHO_BUFFER_SIZE*2; - if (unlikely(spi_dv_in_progress(starget))) + if (unlikely(scsi_device_get(sdev))) return; - if (unlikely(scsi_device_get(sdev))) + if (unlikely(spi_dv_in_progress(starget))) return; spi_dv_in_progress(starget) = 1; diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c index 6f0a4c612b3b..5ba5c2a9e8e9 100644 --- a/trunk/drivers/scsi/sd.c +++ b/trunk/drivers/scsi/sd.c @@ -65,7 +65,6 @@ #include #include "sd.h" -#include "scsi_priv.h" #include "scsi_logging.h" MODULE_AUTHOR("Eric Youngdale"); @@ -2723,7 +2722,7 @@ static int sd_probe(struct device *dev) dev_set_drvdata(dev, sdkp); get_device(&sdkp->dev); /* prevent release before async_schedule */ - async_schedule_domain(sd_probe_async, sdkp, &scsi_sd_probe_domain); + async_schedule(sd_probe_async, sdkp); return 0; @@ -2757,7 +2756,7 @@ static int sd_remove(struct device *dev) sdkp = dev_get_drvdata(dev); scsi_autopm_get_device(sdkp->device); - async_synchronize_full_domain(&scsi_sd_probe_domain); + async_synchronize_full(); blk_queue_prep_rq(sdkp->device->request_queue, scsi_prep_fn); blk_queue_unprep_rq(sdkp->device->request_queue, NULL); device_del(&sdkp->dev); diff --git a/trunk/drivers/scsi/sg.c b/trunk/drivers/scsi/sg.c index 9c5c5f2b3962..eacd46bb36b9 100644 --- a/trunk/drivers/scsi/sg.c +++ b/trunk/drivers/scsi/sg.c @@ -104,7 +104,7 @@ static int scatter_elem_sz_prev = SG_SCATTER_SZ; static int sg_add(struct device *, struct class_interface *); static void sg_remove(struct device *, struct class_interface *); -static DEFINE_SPINLOCK(sg_open_exclusive_lock); +static DEFINE_MUTEX(sg_mutex); static DEFINE_IDR(sg_index_idr); static DEFINE_RWLOCK(sg_index_lock); /* Also used to lock @@ -137,15 +137,13 @@ typedef struct sg_request { /* SG_MAX_QUEUE requests outstanding per file */ char res_used; /* 1 -> using reserve buffer, 0 -> not ... */ char orphan; /* 1 -> drop on sight, 0 -> normal */ char sg_io_owned; /* 1 -> packet belongs to SG_IO */ - /* done protected by rq_list_lock */ - char done; /* 0->before bh, 1->before read, 2->read */ + volatile char done; /* 0->before bh, 1->before read, 2->read */ struct request *rq; struct bio *bio; struct execute_work ew; } Sg_request; typedef struct sg_fd { /* holds the state of a file descriptor */ - /* sfd_siblings is protected by sg_index_lock */ struct list_head sfd_siblings; struct sg_device *parentdp; /* owning device */ wait_queue_head_t read_wait; /* queue read until command done */ @@ -159,6 +157,7 @@ typedef struct sg_fd { /* holds the state of a file descriptor */ Sg_request req_arr[SG_MAX_QUEUE]; /* used as singly-linked list */ char low_dma; /* as in parent but possibly overridden to 1 */ char force_packid; /* 1 -> pack_id input to read(), 0 -> ignored */ + volatile char closed; /* 1 -> fd closed but request(s) outstanding */ char cmd_q; /* 1 -> allow command queuing, 0 -> don't */ char next_cmd_len; /* 0 -> automatic (def), >0 -> use on next write() */ char keep_orphan; /* 0 -> drop orphan (def), 1 -> keep for read() */ @@ -172,11 +171,9 @@ typedef struct sg_device { /* holds the state of each scsi generic device */ wait_queue_head_t o_excl_wait; /* queue open() when O_EXCL in use */ int sg_tablesize; /* adapter's max scatter-gather table size */ u32 index; /* device index number */ - /* sfds is protected by sg_index_lock */ struct list_head sfds; volatile char detached; /* 0->attached, 1->detached pending removal */ - /* exclude protected by sg_open_exclusive_lock */ - char exclude; /* opened for exclusive access */ + volatile char exclude; /* opened for exclusive access */ char sgdebug; /* 0->off, 1->sense, 9->dump dev, 10-> all devs */ struct gendisk *disk; struct cdev * cdev; /* char_dev [sysfs: /sys/cdev/major/sg] */ @@ -224,38 +221,6 @@ static int sg_allow_access(struct file *filp, unsigned char *cmd) return blk_verify_command(cmd, filp->f_mode & FMODE_WRITE); } -static int get_exclude(Sg_device *sdp) -{ - unsigned long flags; - int ret; - - spin_lock_irqsave(&sg_open_exclusive_lock, flags); - ret = sdp->exclude; - spin_unlock_irqrestore(&sg_open_exclusive_lock, flags); - return ret; -} - -static int set_exclude(Sg_device *sdp, char val) -{ - unsigned long flags; - - spin_lock_irqsave(&sg_open_exclusive_lock, flags); - sdp->exclude = val; - spin_unlock_irqrestore(&sg_open_exclusive_lock, flags); - return val; -} - -static int sfds_list_empty(Sg_device *sdp) -{ - unsigned long flags; - int ret; - - read_lock_irqsave(&sg_index_lock, flags); - ret = list_empty(&sdp->sfds); - read_unlock_irqrestore(&sg_index_lock, flags); - return ret; -} - static int sg_open(struct inode *inode, struct file *filp) { @@ -267,6 +232,7 @@ sg_open(struct inode *inode, struct file *filp) int res; int retval; + mutex_lock(&sg_mutex); nonseekable_open(inode, filp); SCSI_LOG_TIMEOUT(3, printk("sg_open: dev=%d, flags=0x%x\n", dev, flags)); sdp = sg_get_dev(dev); @@ -298,22 +264,25 @@ sg_open(struct inode *inode, struct file *filp) retval = -EPERM; /* Can't lock it with read only access */ goto error_out; } - if (!sfds_list_empty(sdp) && (flags & O_NONBLOCK)) { + if (!list_empty(&sdp->sfds) && (flags & O_NONBLOCK)) { retval = -EBUSY; goto error_out; } - res = wait_event_interruptible(sdp->o_excl_wait, - ((!sfds_list_empty(sdp) || get_exclude(sdp)) ? 0 : set_exclude(sdp, 1))); + res = 0; + __wait_event_interruptible(sdp->o_excl_wait, + ((!list_empty(&sdp->sfds) || sdp->exclude) ? 0 : (sdp->exclude = 1)), res); if (res) { retval = res; /* -ERESTARTSYS because signal hit process */ goto error_out; } - } else if (get_exclude(sdp)) { /* some other fd has an exclusive lock on dev */ + } else if (sdp->exclude) { /* some other fd has an exclusive lock on dev */ if (flags & O_NONBLOCK) { retval = -EBUSY; goto error_out; } - res = wait_event_interruptible(sdp->o_excl_wait, !get_exclude(sdp)); + res = 0; + __wait_event_interruptible(sdp->o_excl_wait, (!sdp->exclude), + res); if (res) { retval = res; /* -ERESTARTSYS because signal hit process */ goto error_out; @@ -323,7 +292,7 @@ sg_open(struct inode *inode, struct file *filp) retval = -ENODEV; goto error_out; } - if (sfds_list_empty(sdp)) { /* no existing opens on this device */ + if (list_empty(&sdp->sfds)) { /* no existing opens on this device */ sdp->sgdebug = 0; q = sdp->device->request_queue; sdp->sg_tablesize = queue_max_segments(q); @@ -332,7 +301,7 @@ sg_open(struct inode *inode, struct file *filp) filp->private_data = sfp; else { if (flags & O_EXCL) { - set_exclude(sdp, 0); /* undo if error */ + sdp->exclude = 0; /* undo if error */ wake_up_interruptible(&sdp->o_excl_wait); } retval = -ENOMEM; @@ -348,6 +317,7 @@ sg_open(struct inode *inode, struct file *filp) sg_put: if (sdp) sg_put_dev(sdp); + mutex_unlock(&sg_mutex); return retval; } @@ -362,7 +332,9 @@ sg_release(struct inode *inode, struct file *filp) return -ENXIO; SCSI_LOG_TIMEOUT(3, printk("sg_release: %s\n", sdp->disk->disk_name)); - set_exclude(sdp, 0); + sfp->closed = 1; + + sdp->exclude = 0; wake_up_interruptible(&sdp->o_excl_wait); scsi_autopm_put_device(sdp->device); @@ -426,14 +398,19 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos) retval = -EAGAIN; goto free_old_hdr; } - retval = wait_event_interruptible(sfp->read_wait, - (sdp->detached || - (srp = sg_get_rq_mark(sfp, req_pack_id)))); - if (sdp->detached) { - retval = -ENODEV; - goto free_old_hdr; - } - if (retval) { + while (1) { + retval = 0; /* following macro beats race condition */ + __wait_event_interruptible(sfp->read_wait, + (sdp->detached || + (srp = sg_get_rq_mark(sfp, req_pack_id))), + retval); + if (sdp->detached) { + retval = -ENODEV; + goto free_old_hdr; + } + if (0 == retval) + break; + /* -ERESTARTSYS as signal hit process */ goto free_old_hdr; } @@ -794,18 +771,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, return 0; } -static int srp_done(Sg_fd *sfp, Sg_request *srp) -{ - unsigned long flags; - int ret; - - read_lock_irqsave(&sfp->rq_list_lock, flags); - ret = srp->done; - read_unlock_irqrestore(&sfp->rq_list_lock, flags); - return ret; -} - -static long +static int sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) { void __user *p = (void __user *)arg; @@ -825,30 +791,40 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) switch (cmd_in) { case SG_IO: - if (sdp->detached) - return -ENODEV; - if (!scsi_block_when_processing_errors(sdp->device)) - return -ENXIO; - if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR)) - return -EFAULT; - result = sg_new_write(sfp, filp, p, SZ_SG_IO_HDR, - 1, read_only, 1, &srp); - if (result < 0) - return result; - result = wait_event_interruptible(sfp->read_wait, - (srp_done(sfp, srp) || sdp->detached)); - if (sdp->detached) - return -ENODEV; - write_lock_irq(&sfp->rq_list_lock); - if (srp->done) { - srp->done = 2; - write_unlock_irq(&sfp->rq_list_lock); + { + int blocking = 1; /* ignore O_NONBLOCK flag */ + + if (sdp->detached) + return -ENODEV; + if (!scsi_block_when_processing_errors(sdp->device)) + return -ENXIO; + if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR)) + return -EFAULT; + result = + sg_new_write(sfp, filp, p, SZ_SG_IO_HDR, + blocking, read_only, 1, &srp); + if (result < 0) + return result; + while (1) { + result = 0; /* following macro to beat race condition */ + __wait_event_interruptible(sfp->read_wait, + (srp->done || sdp->detached), + result); + if (sdp->detached) + return -ENODEV; + write_lock_irq(&sfp->rq_list_lock); + if (srp->done) { + srp->done = 2; + write_unlock_irq(&sfp->rq_list_lock); + break; + } + srp->orphan = 1; + write_unlock_irq(&sfp->rq_list_lock); + return result; /* -ERESTARTSYS because signal hit process */ + } result = sg_new_read(sfp, p, SZ_SG_IO_HDR, srp); return (result < 0) ? result : 0; } - srp->orphan = 1; - write_unlock_irq(&sfp->rq_list_lock); - return result; /* -ERESTARTSYS because signal hit process */ case SG_SET_TIMEOUT: result = get_user(val, ip); if (result) @@ -1115,6 +1091,18 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) } } +static long +sg_unlocked_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) +{ + int ret; + + mutex_lock(&sg_mutex); + ret = sg_ioctl(filp, cmd_in, arg); + mutex_unlock(&sg_mutex); + + return ret; +} + #ifdef CONFIG_COMPAT static long sg_compat_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) { @@ -1148,11 +1136,8 @@ sg_poll(struct file *filp, poll_table * wait) int count = 0; unsigned long iflags; - sfp = filp->private_data; - if (!sfp) - return POLLERR; - sdp = sfp->parentdp; - if (!sdp) + if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)) + || sfp->closed) return POLLERR; poll_wait(filp, &sfp->read_wait, wait); read_lock_irqsave(&sfp->rq_list_lock, iflags); @@ -1362,7 +1347,7 @@ static const struct file_operations sg_fops = { .read = sg_read, .write = sg_write, .poll = sg_poll, - .unlocked_ioctl = sg_ioctl, + .unlocked_ioctl = sg_unlocked_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = sg_compat_ioctl, #endif @@ -2327,7 +2312,7 @@ struct sg_proc_leaf { const struct file_operations * fops; }; -static const struct sg_proc_leaf sg_proc_leaf_arr[] = { +static struct sg_proc_leaf sg_proc_leaf_arr[] = { {"allow_dio", &adio_fops}, {"debug", &debug_fops}, {"def_reserved_size", &dressz_fops}, @@ -2347,7 +2332,7 @@ sg_proc_init(void) if (!sg_proc_sgp) return 1; for (k = 0; k < num_leaves; ++k) { - const struct sg_proc_leaf *leaf = &sg_proc_leaf_arr[k]; + struct sg_proc_leaf *leaf = &sg_proc_leaf_arr[k]; umode_t mask = leaf->fops->write ? S_IRUGO | S_IWUSR : S_IRUGO; proc_create(leaf->name, mask, sg_proc_sgp, leaf->fops); } @@ -2548,9 +2533,9 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) fp->reserve.bufflen, (int) fp->reserve.k_use_sg, (int) fp->low_dma); - seq_printf(s, " cmd_q=%d f_packid=%d k_orphan=%d closed=0\n", + seq_printf(s, " cmd_q=%d f_packid=%d k_orphan=%d closed=%d\n", (int) fp->cmd_q, (int) fp->force_packid, - (int) fp->keep_orphan); + (int) fp->keep_orphan, (int) fp->closed); for (m = 0, srp = fp->headrp; srp != NULL; ++m, srp = srp->nextrp) { @@ -2627,7 +2612,7 @@ static int sg_proc_seq_show_debug(struct seq_file *s, void *v) scsidp->lun, scsidp->host->hostt->emulated); seq_printf(s, " sg_tablesize=%d excl=%d\n", - sdp->sg_tablesize, get_exclude(sdp)); + sdp->sg_tablesize, sdp->exclude); sg_proc_debug_helper(s, sdp); } read_unlock_irqrestore(&sg_index_lock, iflags); diff --git a/trunk/drivers/scsi/st.h b/trunk/drivers/scsi/st.h index b548923785ed..ea35632b986c 100644 --- a/trunk/drivers/scsi/st.h +++ b/trunk/drivers/scsi/st.h @@ -35,8 +35,8 @@ struct st_request { /* The tape buffer descriptor. */ struct st_buffer { unsigned char dma; /* DMA-able buffer */ + unsigned char do_dio; /* direct i/o set up? */ unsigned char cleared; /* internal buffer cleared after open? */ - unsigned short do_dio; /* direct i/o set up? */ int buffer_size; int buffer_blocks; int buffer_bytes; diff --git a/trunk/drivers/scsi/storvsc_drv.c b/trunk/drivers/scsi/storvsc_drv.c index 528d52beaa1c..83a1972a1999 100644 --- a/trunk/drivers/scsi/storvsc_drv.c +++ b/trunk/drivers/scsi/storvsc_drv.c @@ -785,22 +785,12 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request) /* * If there is an error; offline the device since all * error recovery strategies would have already been - * deployed on the host side. However, if the command - * were a pass-through command deal with it appropriately. + * deployed on the host side. */ - scmnd->result = vm_srb->scsi_status; - - if (vm_srb->srb_status == SRB_STATUS_ERROR) { - switch (scmnd->cmnd[0]) { - case ATA_16: - case ATA_12: - set_host_byte(scmnd, DID_PASSTHROUGH); - break; - default: - set_host_byte(scmnd, DID_TARGET_FAILURE); - } - } - + if (vm_srb->srb_status == SRB_STATUS_ERROR) + scmnd->result = DID_TARGET_FAILURE << 16; + else + scmnd->result = vm_srb->scsi_status; /* * If the LUN is invalid; remove the device. diff --git a/trunk/drivers/scsi/ufs/ufshcd.c b/trunk/drivers/scsi/ufs/ufshcd.c index 4e010b727818..52b96e8bf92e 100644 --- a/trunk/drivers/scsi/ufs/ufshcd.c +++ b/trunk/drivers/scsi/ufs/ufshcd.c @@ -1032,11 +1032,11 @@ static int ufshcd_initialize_hba(struct ufs_hba *hba) return -EIO; /* Configure UTRL and UTMRL base address registers */ - writel(lower_32_bits(hba->utrdl_dma_addr), + writel(hba->utrdl_dma_addr, (hba->mmio_base + REG_UTP_TRANSFER_REQ_LIST_BASE_L)); - writel(upper_32_bits(hba->utrdl_dma_addr), + writel(lower_32_bits(hba->utrdl_dma_addr), (hba->mmio_base + REG_UTP_TRANSFER_REQ_LIST_BASE_H)); - writel(lower_32_bits(hba->utmrdl_dma_addr), + writel(hba->utmrdl_dma_addr, (hba->mmio_base + REG_UTP_TASK_REQ_LIST_BASE_L)); writel(upper_32_bits(hba->utmrdl_dma_addr), (hba->mmio_base + REG_UTP_TASK_REQ_LIST_BASE_H)); @@ -1160,7 +1160,7 @@ static int ufshcd_task_req_compl(struct ufs_hba *hba, u32 index) task_result = be32_to_cpu(task_rsp_upiup->header.dword_1); task_result = ((task_result & MASK_TASK_RESPONSE) >> 8); - if (task_result != UPIU_TASK_MANAGEMENT_FUNC_COMPL && + if (task_result != UPIU_TASK_MANAGEMENT_FUNC_COMPL || task_result != UPIU_TASK_MANAGEMENT_FUNC_SUCCEEDED) task_result = FAILED; } else { diff --git a/trunk/drivers/scsi/virtio_scsi.c b/trunk/drivers/scsi/virtio_scsi.c index 1b3843117268..efccd72c4a3e 100644 --- a/trunk/drivers/scsi/virtio_scsi.c +++ b/trunk/drivers/scsi/virtio_scsi.c @@ -175,8 +175,7 @@ static void virtscsi_complete_free(void *buf) if (cmd->comp) complete_all(cmd->comp); - else - mempool_free(cmd, virtscsi_cmd_pool); + mempool_free(cmd, virtscsi_cmd_pool); } static void virtscsi_ctrl_done(struct virtqueue *vq) @@ -312,22 +311,21 @@ static int virtscsi_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc) static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd) { DECLARE_COMPLETION_ONSTACK(comp); - int ret = FAILED; + int ret; cmd->comp = ∁ - if (virtscsi_kick_cmd(vscsi, vscsi->ctrl_vq, cmd, - sizeof cmd->req.tmf, sizeof cmd->resp.tmf, - GFP_NOIO) < 0) - goto out; + ret = virtscsi_kick_cmd(vscsi, vscsi->ctrl_vq, cmd, + sizeof cmd->req.tmf, sizeof cmd->resp.tmf, + GFP_NOIO); + if (ret < 0) + return FAILED; wait_for_completion(&comp); - if (cmd->resp.tmf.response == VIRTIO_SCSI_S_OK || - cmd->resp.tmf.response == VIRTIO_SCSI_S_FUNCTION_SUCCEEDED) - ret = SUCCESS; + if (cmd->resp.tmf.response != VIRTIO_SCSI_S_OK && + cmd->resp.tmf.response != VIRTIO_SCSI_S_FUNCTION_SUCCEEDED) + return FAILED; -out: - mempool_free(cmd, virtscsi_cmd_pool); - return ret; + return SUCCESS; } static int virtscsi_device_reset(struct scsi_cmnd *sc) diff --git a/trunk/drivers/target/iscsi/iscsi_target.c b/trunk/drivers/target/iscsi/iscsi_target.c index d57d10cb2e47..8b1d5e62ed40 100644 --- a/trunk/drivers/target/iscsi/iscsi_target.c +++ b/trunk/drivers/target/iscsi/iscsi_target.c @@ -27,10 +27,8 @@ #include #include #include -#include #include #include -#include #include "iscsi_target_core.h" #include "iscsi_target_parameters.h" @@ -595,7 +593,7 @@ static void __exit iscsi_target_cleanup_module(void) kfree(iscsit_global); } -static int iscsit_add_reject( +int iscsit_add_reject( u8 reason, int fail_conn, unsigned char *buf, @@ -624,7 +622,7 @@ static int iscsit_add_reject( } spin_lock_bh(&conn->cmd_lock); - list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); + list_add_tail(&cmd->i_list, &conn->conn_cmd_list); spin_unlock_bh(&conn->cmd_lock); cmd->i_state = ISTATE_SEND_REJECT; @@ -671,7 +669,7 @@ int iscsit_add_reject_from_cmd( if (add_to_conn) { spin_lock_bh(&conn->cmd_lock); - list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); + list_add_tail(&cmd->i_list, &conn->conn_cmd_list); spin_unlock_bh(&conn->cmd_lock); } @@ -687,7 +685,9 @@ int iscsit_add_reject_from_cmd( /* * Map some portion of the allocated scatterlist to an iovec, suitable for - * kernel sockets to copy data in/out. + * kernel sockets to copy data in/out. This handles both pages and slab-allocated + * buffers, since we have been tricky and mapped t_mem_sg to the buffer in + * either case (see iscsit_alloc_buffs) */ static int iscsit_map_iovec( struct iscsi_cmd *cmd, @@ -700,9 +700,10 @@ static int iscsit_map_iovec( unsigned int page_off; /* - * We know each entry in t_data_sg contains a page. + * We have a private mapping of the allocated pages in t_mem_sg. + * At this point, we also know each contains a page. */ - sg = &cmd->se_cmd.t_data_sg[data_offset / PAGE_SIZE]; + sg = &cmd->t_mem_sg[data_offset / PAGE_SIZE]; page_off = (data_offset % PAGE_SIZE); cmd->first_data_sg = sg; @@ -743,7 +744,7 @@ static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn) conn->exp_statsn = exp_statsn; spin_lock_bh(&conn->cmd_lock); - list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) { + list_for_each_entry(cmd, &conn->conn_cmd_list, i_list) { spin_lock(&cmd->istate_lock); if ((cmd->i_state == ISTATE_SENT_STATUS) && (cmd->stat_sn < exp_statsn)) { @@ -760,7 +761,8 @@ static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn) static int iscsit_allocate_iovecs(struct iscsi_cmd *cmd) { - u32 iov_count = max(1UL, DIV_ROUND_UP(cmd->se_cmd.data_length, PAGE_SIZE)); + u32 iov_count = (cmd->se_cmd.t_data_nents == 0) ? 1 : + cmd->se_cmd.t_data_nents; iov_count += ISCSI_IOV_DATA_BUFFER; @@ -774,6 +776,64 @@ static int iscsit_allocate_iovecs(struct iscsi_cmd *cmd) return 0; } +static int iscsit_alloc_buffs(struct iscsi_cmd *cmd) +{ + struct scatterlist *sgl; + u32 length = cmd->se_cmd.data_length; + int nents = DIV_ROUND_UP(length, PAGE_SIZE); + int i = 0, j = 0, ret; + /* + * If no SCSI payload is present, allocate the default iovecs used for + * iSCSI PDU Header + */ + if (!length) + return iscsit_allocate_iovecs(cmd); + + sgl = kzalloc(sizeof(*sgl) * nents, GFP_KERNEL); + if (!sgl) + return -ENOMEM; + + sg_init_table(sgl, nents); + + while (length) { + int buf_size = min_t(int, length, PAGE_SIZE); + struct page *page; + + page = alloc_page(GFP_KERNEL | __GFP_ZERO); + if (!page) + goto page_alloc_failed; + + sg_set_page(&sgl[i], page, buf_size, 0); + + length -= buf_size; + i++; + } + + cmd->t_mem_sg = sgl; + cmd->t_mem_sg_nents = nents; + + /* BIDI ops not supported */ + + /* Tell the core about our preallocated memory */ + transport_generic_map_mem_to_cmd(&cmd->se_cmd, sgl, nents, NULL, 0); + /* + * Allocate iovecs for SCSI payload after transport_generic_map_mem_to_cmd + * so that cmd->se_cmd.t_tasks_se_num has been set. + */ + ret = iscsit_allocate_iovecs(cmd); + if (ret < 0) + return -ENOMEM; + + return 0; + +page_alloc_failed: + while (j < i) + __free_page(sg_page(&sgl[j++])); + + kfree(sgl); + return -ENOMEM; +} + static int iscsit_handle_scsi_cmd( struct iscsi_conn *conn, unsigned char *buf) @@ -782,8 +842,6 @@ static int iscsit_handle_scsi_cmd( int dump_immediate_data = 0, send_check_condition = 0, payload_length; struct iscsi_cmd *cmd = NULL; struct iscsi_scsi_req *hdr; - int iscsi_task_attr; - int sam_task_attr; spin_lock_bh(&conn->sess->session_stats_lock); conn->sess->cmd_pdus++; @@ -900,30 +958,15 @@ static int iscsit_handle_scsi_cmd( (hdr->flags & ISCSI_FLAG_CMD_READ) ? DMA_FROM_DEVICE : DMA_NONE; - cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); + cmd = iscsit_allocate_se_cmd(conn, hdr->data_length, data_direction, + (hdr->flags & ISCSI_FLAG_CMD_ATTR_MASK)); if (!cmd) return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, 1, - buf, conn); + buf, conn); - cmd->data_direction = data_direction; - iscsi_task_attr = hdr->flags & ISCSI_FLAG_CMD_ATTR_MASK; - /* - * Figure out the SAM Task Attribute for the incoming SCSI CDB - */ - if ((iscsi_task_attr == ISCSI_ATTR_UNTAGGED) || - (iscsi_task_attr == ISCSI_ATTR_SIMPLE)) - sam_task_attr = MSG_SIMPLE_TAG; - else if (iscsi_task_attr == ISCSI_ATTR_ORDERED) - sam_task_attr = MSG_ORDERED_TAG; - else if (iscsi_task_attr == ISCSI_ATTR_HEAD_OF_QUEUE) - sam_task_attr = MSG_HEAD_TAG; - else if (iscsi_task_attr == ISCSI_ATTR_ACA) - sam_task_attr = MSG_ACA_TAG; - else { - pr_debug("Unknown iSCSI Task Attribute: 0x%02x, using" - " MSG_SIMPLE_TAG\n", iscsi_task_attr); - sam_task_attr = MSG_SIMPLE_TAG; - } + pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x," + " ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt, + hdr->cmdsn, hdr->data_length, payload_length, conn->cid); cmd->iscsi_opcode = ISCSI_OP_SCSI_CMD; cmd->i_state = ISTATE_NEW_CMD; @@ -959,17 +1002,6 @@ static int iscsit_handle_scsi_cmd( iscsit_attach_datain_req(cmd, dr); } - /* - * Initialize struct se_cmd descriptor from target_core_mod infrastructure - */ - transport_init_se_cmd(&cmd->se_cmd, &lio_target_fabric_configfs->tf_ops, - conn->sess->se_sess, hdr->data_length, cmd->data_direction, - sam_task_attr, &cmd->sense_buffer[0]); - - pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x," - " ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt, - hdr->cmdsn, hdr->data_length, payload_length, conn->cid); - /* * The CDB is going to an se_device_t. */ @@ -984,8 +1016,13 @@ static int iscsit_handle_scsi_cmd( send_check_condition = 1; goto attach_cmd; } - - transport_ret = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb); + /* + * The Initiator Node has access to the LUN (the addressing method + * is handled inside of iscsit_get_lun_for_cmd()). Now it's time to + * allocate 1->N transport tasks (depending on sector count and + * maximum request size the physical HBA(s) can handle. + */ + transport_ret = transport_generic_allocate_tasks(&cmd->se_cmd, hdr->cdb); if (transport_ret == -ENOMEM) { return iscsit_add_reject_from_cmd( ISCSI_REASON_BOOKMARK_NO_RESOURCES, @@ -998,7 +1035,9 @@ static int iscsit_handle_scsi_cmd( */ send_check_condition = 1; } else { - if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0) + cmd->data_length = cmd->se_cmd.data_length; + + if (iscsit_decide_list_to_build(cmd, payload_length) < 0) return iscsit_add_reject_from_cmd( ISCSI_REASON_BOOKMARK_NO_RESOURCES, 1, 1, buf, cmd); @@ -1006,15 +1045,18 @@ static int iscsit_handle_scsi_cmd( attach_cmd: spin_lock_bh(&conn->cmd_lock); - list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); + list_add_tail(&cmd->i_list, &conn->conn_cmd_list); spin_unlock_bh(&conn->cmd_lock); /* * Check if we need to delay processing because of ALUA * Active/NonOptimized primary access state.. */ core_alua_check_nonop_delay(&cmd->se_cmd); - - ret = iscsit_allocate_iovecs(cmd); + /* + * Allocate and setup SGL used with transport_generic_map_mem_to_cmd(). + * also call iscsit_allocate_iovecs() + */ + ret = iscsit_alloc_buffs(cmd); if (ret < 0) return iscsit_add_reject_from_cmd( ISCSI_REASON_BOOKMARK_NO_RESOURCES, @@ -1261,10 +1303,10 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) se_cmd = &cmd->se_cmd; iscsit_mod_dataout_timer(cmd); - if ((hdr->offset + payload_length) > cmd->se_cmd.data_length) { + if ((hdr->offset + payload_length) > cmd->data_length) { pr_err("DataOut Offset: %u, Length %u greater than" " iSCSI Command EDTL %u, protocol error.\n", - hdr->offset, payload_length, cmd->se_cmd.data_length); + hdr->offset, payload_length, cmd->data_length); return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, 1, 0, buf, cmd); } @@ -1400,7 +1442,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) return 0; else if (ret == DATAOUT_SEND_R2T) { iscsit_set_dataout_sequence_values(cmd); - iscsit_build_r2ts_for_cmd(cmd, conn, false); + iscsit_build_r2ts_for_cmd(cmd, conn, 0); } else if (ret == DATAOUT_SEND_TO_TRANSPORT) { /* * Handle extra special case for out of order @@ -1575,7 +1617,7 @@ static int iscsit_handle_nop_out( * Initiator is expecting a NopIN ping reply, */ spin_lock_bh(&conn->cmd_lock); - list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); + list_add_tail(&cmd->i_list, &conn->conn_cmd_list); spin_unlock_bh(&conn->cmd_lock); iscsit_ack_from_expstatsn(conn, hdr->exp_statsn); @@ -1681,75 +1723,10 @@ static int iscsit_handle_task_mgt_cmd( (hdr->refcmdsn != ISCSI_RESERVED_TAG)) hdr->refcmdsn = ISCSI_RESERVED_TAG; - cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); + cmd = iscsit_allocate_se_cmd_for_tmr(conn, function); if (!cmd) return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, - 1, buf, conn); - - cmd->data_direction = DMA_NONE; - - cmd->tmr_req = kzalloc(sizeof(struct iscsi_tmr_req), GFP_KERNEL); - if (!cmd->tmr_req) { - pr_err("Unable to allocate memory for" - " Task Management command!\n"); - return iscsit_add_reject_from_cmd( - ISCSI_REASON_BOOKMARK_NO_RESOURCES, - 1, 1, buf, cmd); - } - - /* - * TASK_REASSIGN for ERL=2 / connection stays inside of - * LIO-Target $FABRIC_MOD - */ - if (function != ISCSI_TM_FUNC_TASK_REASSIGN) { - - u8 tcm_function; - int ret; - - transport_init_se_cmd(&cmd->se_cmd, - &lio_target_fabric_configfs->tf_ops, - conn->sess->se_sess, 0, DMA_NONE, - MSG_SIMPLE_TAG, &cmd->sense_buffer[0]); - - switch (function) { - case ISCSI_TM_FUNC_ABORT_TASK: - tcm_function = TMR_ABORT_TASK; - break; - case ISCSI_TM_FUNC_ABORT_TASK_SET: - tcm_function = TMR_ABORT_TASK_SET; - break; - case ISCSI_TM_FUNC_CLEAR_ACA: - tcm_function = TMR_CLEAR_ACA; - break; - case ISCSI_TM_FUNC_CLEAR_TASK_SET: - tcm_function = TMR_CLEAR_TASK_SET; - break; - case ISCSI_TM_FUNC_LOGICAL_UNIT_RESET: - tcm_function = TMR_LUN_RESET; - break; - case ISCSI_TM_FUNC_TARGET_WARM_RESET: - tcm_function = TMR_TARGET_WARM_RESET; - break; - case ISCSI_TM_FUNC_TARGET_COLD_RESET: - tcm_function = TMR_TARGET_COLD_RESET; - break; - default: - pr_err("Unknown iSCSI TMR Function:" - " 0x%02x\n", function); - return iscsit_add_reject_from_cmd( - ISCSI_REASON_BOOKMARK_NO_RESOURCES, - 1, 1, buf, cmd); - } - - ret = core_tmr_alloc_req(&cmd->se_cmd, cmd->tmr_req, - tcm_function, GFP_KERNEL); - if (ret < 0) - return iscsit_add_reject_from_cmd( - ISCSI_REASON_BOOKMARK_NO_RESOURCES, - 1, 1, buf, cmd); - - cmd->tmr_req->se_tmr_req = cmd->se_cmd.se_tmr_req; - } + 1, buf, conn); cmd->iscsi_opcode = ISCSI_OP_SCSI_TMFUNC; cmd->i_state = ISTATE_SEND_TASKMGTRSP; @@ -1827,7 +1804,7 @@ static int iscsit_handle_task_mgt_cmd( se_tmr->call_transport = 1; attach: spin_lock_bh(&conn->cmd_lock); - list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); + list_add_tail(&cmd->i_list, &conn->conn_cmd_list); spin_unlock_bh(&conn->cmd_lock); if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) { @@ -2003,7 +1980,7 @@ static int iscsit_handle_text_cmd( cmd->data_direction = DMA_NONE; spin_lock_bh(&conn->cmd_lock); - list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); + list_add_tail(&cmd->i_list, &conn->conn_cmd_list); spin_unlock_bh(&conn->cmd_lock); iscsit_ack_from_expstatsn(conn, hdr->exp_statsn); @@ -2191,7 +2168,7 @@ static int iscsit_handle_logout_cmd( logout_remove = 1; spin_lock_bh(&conn->cmd_lock); - list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); + list_add_tail(&cmd->i_list, &conn->conn_cmd_list); spin_unlock_bh(&conn->cmd_lock); if (reason_code != ISCSI_LOGOUT_REASON_RECOVERY) @@ -2201,7 +2178,7 @@ static int iscsit_handle_logout_cmd( * Immediate commands are executed, well, immediately. * Non-Immediate Logout Commands are executed in CmdSN order. */ - if (cmd->immediate_cmd) { + if (hdr->opcode & ISCSI_OP_IMMEDIATE) { int ret = iscsit_execute_cmd(cmd, 0); if (ret < 0) @@ -2359,7 +2336,7 @@ static int iscsit_handle_immediate_data( cmd->write_data_done += length; - if (cmd->write_data_done == cmd->se_cmd.data_length) { + if (cmd->write_data_done == cmd->data_length) { spin_lock_bh(&cmd->istate_lock); cmd->cmd_flags |= ICF_GOT_LAST_DATAOUT; cmd->i_state = ISTATE_RECEIVED_LAST_DATAOUT; @@ -2404,7 +2381,7 @@ static void iscsit_build_conn_drop_async_message(struct iscsi_conn *conn) cmd->i_state = ISTATE_SEND_ASYNCMSG; spin_lock_bh(&conn_p->cmd_lock); - list_add_tail(&cmd->i_conn_node, &conn_p->conn_cmd_list); + list_add_tail(&cmd->i_list, &conn_p->conn_cmd_list); spin_unlock_bh(&conn_p->cmd_lock); iscsit_add_cmd_to_response_queue(cmd, conn_p, cmd->i_state); @@ -2457,19 +2434,10 @@ static int iscsit_send_conn_drop_async_message( return 0; } -static void iscsit_tx_thread_wait_for_tcp(struct iscsi_conn *conn) -{ - if ((conn->sock->sk->sk_shutdown & SEND_SHUTDOWN) || - (conn->sock->sk->sk_shutdown & RCV_SHUTDOWN)) { - wait_for_completion_interruptible_timeout( - &conn->tx_half_close_comp, - ISCSI_TX_THREAD_TCP_TIMEOUT * HZ); - } -} - static int iscsit_send_data_in( struct iscsi_cmd *cmd, - struct iscsi_conn *conn) + struct iscsi_conn *conn, + int *eodr) { int iov_ret = 0, set_statsn = 0; u32 iov_count = 0, tx_size = 0; @@ -2477,8 +2445,6 @@ static int iscsit_send_data_in( struct iscsi_datain_req *dr; struct iscsi_data_rsp *hdr; struct kvec *iov; - int eodr = 0; - int ret; memset(&datain, 0, sizeof(struct iscsi_datain)); dr = iscsit_get_datain_values(cmd, &datain); @@ -2491,11 +2457,11 @@ static int iscsit_send_data_in( /* * Be paranoid and double check the logic for now. */ - if ((datain.offset + datain.length) > cmd->se_cmd.data_length) { + if ((datain.offset + datain.length) > cmd->data_length) { pr_err("Command ITT: 0x%08x, datain.offset: %u and" " datain.length: %u exceeds cmd->data_length: %u\n", cmd->init_task_tag, datain.offset, datain.length, - cmd->se_cmd.data_length); + cmd->data_length); return -1; } @@ -2611,26 +2577,13 @@ static int iscsit_send_data_in( cmd->init_task_tag, ntohl(hdr->statsn), ntohl(hdr->datasn), ntohl(hdr->offset), datain.length, conn->cid); - /* sendpage is preferred but can't insert markers */ - if (!conn->conn_ops->IFMarker) - ret = iscsit_fe_sendpage_sg(cmd, conn); - else - ret = iscsit_send_tx_data(cmd, conn, 0); - - iscsit_unmap_iovec(cmd); - - if (ret < 0) { - iscsit_tx_thread_wait_for_tcp(conn); - return ret; - } - if (dr->dr_complete) { - eodr = (cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ? + *eodr = (cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ? 2 : 1; iscsit_free_datain_req(cmd, dr); } - return eodr; + return 0; } static int iscsit_send_logout_response( @@ -2762,7 +2715,6 @@ static int iscsit_send_unsolicited_nopin( { int tx_size = ISCSI_HDR_LEN; struct iscsi_nopin *hdr; - int ret; hdr = (struct iscsi_nopin *) cmd->pdu; memset(hdr, 0, ISCSI_HDR_LEN); @@ -2795,17 +2747,6 @@ static int iscsit_send_unsolicited_nopin( pr_debug("Sending Unsolicited NOPIN TTT: 0x%08x StatSN:" " 0x%08x CID: %hu\n", hdr->ttt, cmd->stat_sn, conn->cid); - ret = iscsit_send_tx_data(cmd, conn, 1); - if (ret < 0) { - iscsit_tx_thread_wait_for_tcp(conn); - return ret; - } - - spin_lock_bh(&cmd->istate_lock); - cmd->i_state = want_response ? - ISTATE_SENT_NOPIN_WANT_RESPONSE : ISTATE_SENT_STATUS; - spin_unlock_bh(&cmd->istate_lock); - return 0; } @@ -2896,14 +2837,13 @@ static int iscsit_send_nopin_response( return 0; } -static int iscsit_send_r2t( +int iscsit_send_r2t( struct iscsi_cmd *cmd, struct iscsi_conn *conn) { int tx_size = 0; struct iscsi_r2t *r2t; struct iscsi_r2t_rsp *hdr; - int ret; r2t = iscsit_get_r2t_from_list(cmd); if (!r2t) @@ -2959,27 +2899,19 @@ static int iscsit_send_r2t( r2t->sent_r2t = 1; spin_unlock_bh(&cmd->r2t_lock); - ret = iscsit_send_tx_data(cmd, conn, 1); - if (ret < 0) { - iscsit_tx_thread_wait_for_tcp(conn); - return ret; - } - - spin_lock_bh(&cmd->dataout_timeout_lock); - iscsit_start_dataout_timer(cmd, conn); - spin_unlock_bh(&cmd->dataout_timeout_lock); - return 0; } /* - * @recovery: If called from iscsi_task_reassign_complete_write() for - * connection recovery. + * type 0: Normal Operation. + * type 1: Called from Storage Transport. + * type 2: Called from iscsi_task_reassign_complete_write() for + * connection recovery. */ int iscsit_build_r2ts_for_cmd( struct iscsi_cmd *cmd, struct iscsi_conn *conn, - bool recovery) + int type) { int first_r2t = 1; u32 offset = 0, xfer_len = 0; @@ -2990,37 +2922,32 @@ int iscsit_build_r2ts_for_cmd( return 0; } - if (conn->sess->sess_ops->DataSequenceInOrder && - !recovery) - cmd->r2t_offset = max(cmd->r2t_offset, cmd->write_data_done); + if (conn->sess->sess_ops->DataSequenceInOrder && (type != 2)) + if (cmd->r2t_offset < cmd->write_data_done) + cmd->r2t_offset = cmd->write_data_done; while (cmd->outstanding_r2ts < conn->sess->sess_ops->MaxOutstandingR2T) { if (conn->sess->sess_ops->DataSequenceInOrder) { offset = cmd->r2t_offset; - if (first_r2t && recovery) { - int new_data_end = offset + - conn->sess->sess_ops->MaxBurstLength - - cmd->next_burst_len; - - if (new_data_end > cmd->se_cmd.data_length) - xfer_len = cmd->se_cmd.data_length - offset; - else - xfer_len = - conn->sess->sess_ops->MaxBurstLength - - cmd->next_burst_len; + if (first_r2t && (type == 2)) { + xfer_len = ((offset + + (conn->sess->sess_ops->MaxBurstLength - + cmd->next_burst_len) > + cmd->data_length) ? + (cmd->data_length - offset) : + (conn->sess->sess_ops->MaxBurstLength - + cmd->next_burst_len)); } else { - int new_data_end = offset + - conn->sess->sess_ops->MaxBurstLength; - - if (new_data_end > cmd->se_cmd.data_length) - xfer_len = cmd->se_cmd.data_length - offset; - else - xfer_len = conn->sess->sess_ops->MaxBurstLength; + xfer_len = ((offset + + conn->sess->sess_ops->MaxBurstLength) > + cmd->data_length) ? + (cmd->data_length - offset) : + conn->sess->sess_ops->MaxBurstLength; } cmd->r2t_offset += xfer_len; - if (cmd->r2t_offset == cmd->se_cmd.data_length) + if (cmd->r2t_offset == cmd->data_length) cmd->cmd_flags |= ICF_SENT_LAST_R2T; } else { struct iscsi_seq *seq; @@ -3252,8 +3179,6 @@ static bool iscsit_check_inaddr_any(struct iscsi_np *np) return ret; } -#define SENDTARGETS_BUF_LIMIT 32768U - static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd) { char *payload = NULL; @@ -3262,10 +3187,12 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd) struct iscsi_tiqn *tiqn; struct iscsi_tpg_np *tpg_np; int buffer_len, end_of_buf = 0, len = 0, payload_len = 0; - unsigned char buf[ISCSI_IQN_LEN+12]; /* iqn + "TargetName=" + \0 */ + unsigned char buf[256]; - buffer_len = max(conn->conn_ops->MaxRecvDataSegmentLength, - SENDTARGETS_BUF_LIMIT); + buffer_len = (conn->conn_ops->MaxRecvDataSegmentLength > 32768) ? + 32768 : conn->conn_ops->MaxRecvDataSegmentLength; + + memset(buf, 0, 256); payload = kzalloc(buffer_len, GFP_KERNEL); if (!payload) { @@ -3481,6 +3408,18 @@ static int iscsit_send_reject( return 0; } +static void iscsit_tx_thread_wait_for_tcp(struct iscsi_conn *conn) +{ + if ((conn->sock->sk->sk_shutdown & SEND_SHUTDOWN) || + (conn->sock->sk->sk_shutdown & RCV_SHUTDOWN)) { + wait_for_completion_interruptible_timeout( + &conn->tx_half_close_comp, + ISCSI_TX_THREAD_TCP_TIMEOUT * HZ); + } +} + +#ifdef CONFIG_SMP + void iscsit_thread_get_cpumask(struct iscsi_conn *conn) { struct iscsi_thread_set *ts = conn->thread_set; @@ -3494,6 +3433,10 @@ void iscsit_thread_get_cpumask(struct iscsi_conn *conn) * execute upon. */ ord = ts->thread_id % cpumask_weight(cpu_online_mask); +#if 0 + pr_debug(">>>>>>>>>>>>>>>>>>>> Generated ord: %d from" + " thread_id: %d\n", ord, ts->thread_id); +#endif for_each_online_cpu(cpu) { if (ord-- == 0) { cpumask_set_cpu(cpu, conn->conn_cpumask); @@ -3533,196 +3476,34 @@ static inline void iscsit_thread_check_cpumask( */ memset(buf, 0, 128); cpumask_scnprintf(buf, 128, conn->conn_cpumask); +#if 0 + pr_debug(">>>>>>>>>>>>>> Calling set_cpus_allowed_ptr():" + " %s for %s\n", buf, p->comm); +#endif set_cpus_allowed_ptr(p, conn->conn_cpumask); } -static int handle_immediate_queue(struct iscsi_conn *conn) -{ - struct iscsi_queue_req *qr; - struct iscsi_cmd *cmd; - u8 state; - int ret; - - while ((qr = iscsit_get_cmd_from_immediate_queue(conn))) { - atomic_set(&conn->check_immediate_queue, 0); - cmd = qr->cmd; - state = qr->state; - kmem_cache_free(lio_qr_cache, qr); - - switch (state) { - case ISTATE_SEND_R2T: - ret = iscsit_send_r2t(cmd, conn); - if (ret < 0) - goto err; - break; - case ISTATE_REMOVE: - if (cmd->data_direction == DMA_TO_DEVICE) - iscsit_stop_dataout_timer(cmd); - - spin_lock_bh(&conn->cmd_lock); - list_del(&cmd->i_conn_node); - spin_unlock_bh(&conn->cmd_lock); - - iscsit_free_cmd(cmd); - continue; - case ISTATE_SEND_NOPIN_WANT_RESPONSE: - iscsit_mod_nopin_response_timer(conn); - ret = iscsit_send_unsolicited_nopin(cmd, - conn, 1); - if (ret < 0) - goto err; - break; - case ISTATE_SEND_NOPIN_NO_RESPONSE: - ret = iscsit_send_unsolicited_nopin(cmd, - conn, 0); - if (ret < 0) - goto err; - break; - default: - pr_err("Unknown Opcode: 0x%02x ITT:" - " 0x%08x, i_state: %d on CID: %hu\n", - cmd->iscsi_opcode, cmd->init_task_tag, state, - conn->cid); - goto err; - } - } - - return 0; +#else -err: - return -1; -} - -static int handle_response_queue(struct iscsi_conn *conn) +void iscsit_thread_get_cpumask(struct iscsi_conn *conn) { - struct iscsi_queue_req *qr; - struct iscsi_cmd *cmd; - u8 state; - int ret; - - while ((qr = iscsit_get_cmd_from_response_queue(conn))) { - cmd = qr->cmd; - state = qr->state; - kmem_cache_free(lio_qr_cache, qr); - -check_rsp_state: - switch (state) { - case ISTATE_SEND_DATAIN: - ret = iscsit_send_data_in(cmd, conn); - if (ret < 0) - goto err; - else if (!ret) - /* more drs */ - goto check_rsp_state; - else if (ret == 1) { - /* all done */ - spin_lock_bh(&cmd->istate_lock); - cmd->i_state = ISTATE_SENT_STATUS; - spin_unlock_bh(&cmd->istate_lock); - continue; - } else if (ret == 2) { - /* Still must send status, - SCF_TRANSPORT_TASK_SENSE was set */ - spin_lock_bh(&cmd->istate_lock); - cmd->i_state = ISTATE_SEND_STATUS; - spin_unlock_bh(&cmd->istate_lock); - state = ISTATE_SEND_STATUS; - goto check_rsp_state; - } - - break; - case ISTATE_SEND_STATUS: - case ISTATE_SEND_STATUS_RECOVERY: - ret = iscsit_send_status(cmd, conn); - break; - case ISTATE_SEND_LOGOUTRSP: - ret = iscsit_send_logout_response(cmd, conn); - break; - case ISTATE_SEND_ASYNCMSG: - ret = iscsit_send_conn_drop_async_message( - cmd, conn); - break; - case ISTATE_SEND_NOPIN: - ret = iscsit_send_nopin_response(cmd, conn); - break; - case ISTATE_SEND_REJECT: - ret = iscsit_send_reject(cmd, conn); - break; - case ISTATE_SEND_TASKMGTRSP: - ret = iscsit_send_task_mgt_rsp(cmd, conn); - if (ret != 0) - break; - ret = iscsit_tmr_post_handler(cmd, conn); - if (ret != 0) - iscsit_fall_back_to_erl0(conn->sess); - break; - case ISTATE_SEND_TEXTRSP: - ret = iscsit_send_text_rsp(cmd, conn); - break; - default: - pr_err("Unknown Opcode: 0x%02x ITT:" - " 0x%08x, i_state: %d on CID: %hu\n", - cmd->iscsi_opcode, cmd->init_task_tag, - state, conn->cid); - goto err; - } - if (ret < 0) - goto err; - - if (iscsit_send_tx_data(cmd, conn, 1) < 0) { - iscsit_tx_thread_wait_for_tcp(conn); - iscsit_unmap_iovec(cmd); - goto err; - } - iscsit_unmap_iovec(cmd); - - switch (state) { - case ISTATE_SEND_LOGOUTRSP: - if (!iscsit_logout_post_handler(cmd, conn)) - goto restart; - /* fall through */ - case ISTATE_SEND_STATUS: - case ISTATE_SEND_ASYNCMSG: - case ISTATE_SEND_NOPIN: - case ISTATE_SEND_STATUS_RECOVERY: - case ISTATE_SEND_TEXTRSP: - case ISTATE_SEND_TASKMGTRSP: - spin_lock_bh(&cmd->istate_lock); - cmd->i_state = ISTATE_SENT_STATUS; - spin_unlock_bh(&cmd->istate_lock); - break; - case ISTATE_SEND_REJECT: - if (cmd->cmd_flags & ICF_REJECT_FAIL_CONN) { - cmd->cmd_flags &= ~ICF_REJECT_FAIL_CONN; - complete(&cmd->reject_comp); - goto err; - } - complete(&cmd->reject_comp); - break; - default: - pr_err("Unknown Opcode: 0x%02x ITT:" - " 0x%08x, i_state: %d on CID: %hu\n", - cmd->iscsi_opcode, cmd->init_task_tag, - cmd->i_state, conn->cid); - goto err; - } - - if (atomic_read(&conn->check_immediate_queue)) - break; - } - - return 0; - -err: - return -1; -restart: - return -EAGAIN; + return; } +#define iscsit_thread_check_cpumask(X, Y, Z) ({}) +#endif /* CONFIG_SMP */ + int iscsi_target_tx_thread(void *arg) { + u8 state; + int eodr = 0; int ret = 0; + int sent_status = 0; + int use_misc = 0; + int map_sg = 0; + struct iscsi_cmd *cmd = NULL; struct iscsi_conn *conn; + struct iscsi_queue_req *qr = NULL; struct iscsi_thread_set *ts = arg; /* * Allow ourselves to be interrupted by SIGINT so that a @@ -3735,7 +3516,7 @@ int iscsi_target_tx_thread(void *arg) if (!conn) goto out; - ret = 0; + eodr = map_sg = ret = sent_status = use_misc = 0; while (!kthread_should_stop()) { /* @@ -3750,15 +3531,251 @@ int iscsi_target_tx_thread(void *arg) signal_pending(current)) goto transport_err; - ret = handle_immediate_queue(conn); - if (ret < 0) - goto transport_err; +get_immediate: + qr = iscsit_get_cmd_from_immediate_queue(conn); + if (qr) { + atomic_set(&conn->check_immediate_queue, 0); + cmd = qr->cmd; + state = qr->state; + kmem_cache_free(lio_qr_cache, qr); - ret = handle_response_queue(conn); - if (ret == -EAGAIN) - goto restart; - else if (ret < 0) - goto transport_err; + spin_lock_bh(&cmd->istate_lock); + switch (state) { + case ISTATE_SEND_R2T: + spin_unlock_bh(&cmd->istate_lock); + ret = iscsit_send_r2t(cmd, conn); + break; + case ISTATE_REMOVE: + spin_unlock_bh(&cmd->istate_lock); + + if (cmd->data_direction == DMA_TO_DEVICE) + iscsit_stop_dataout_timer(cmd); + + spin_lock_bh(&conn->cmd_lock); + list_del(&cmd->i_list); + spin_unlock_bh(&conn->cmd_lock); + + iscsit_free_cmd(cmd); + goto get_immediate; + case ISTATE_SEND_NOPIN_WANT_RESPONSE: + spin_unlock_bh(&cmd->istate_lock); + iscsit_mod_nopin_response_timer(conn); + ret = iscsit_send_unsolicited_nopin(cmd, + conn, 1); + break; + case ISTATE_SEND_NOPIN_NO_RESPONSE: + spin_unlock_bh(&cmd->istate_lock); + ret = iscsit_send_unsolicited_nopin(cmd, + conn, 0); + break; + default: + pr_err("Unknown Opcode: 0x%02x ITT:" + " 0x%08x, i_state: %d on CID: %hu\n", + cmd->iscsi_opcode, cmd->init_task_tag, state, + conn->cid); + spin_unlock_bh(&cmd->istate_lock); + goto transport_err; + } + if (ret < 0) { + conn->tx_immediate_queue = 0; + goto transport_err; + } + + if (iscsit_send_tx_data(cmd, conn, 1) < 0) { + conn->tx_immediate_queue = 0; + iscsit_tx_thread_wait_for_tcp(conn); + goto transport_err; + } + + spin_lock_bh(&cmd->istate_lock); + switch (state) { + case ISTATE_SEND_R2T: + spin_unlock_bh(&cmd->istate_lock); + spin_lock_bh(&cmd->dataout_timeout_lock); + iscsit_start_dataout_timer(cmd, conn); + spin_unlock_bh(&cmd->dataout_timeout_lock); + break; + case ISTATE_SEND_NOPIN_WANT_RESPONSE: + cmd->i_state = ISTATE_SENT_NOPIN_WANT_RESPONSE; + spin_unlock_bh(&cmd->istate_lock); + break; + case ISTATE_SEND_NOPIN_NO_RESPONSE: + cmd->i_state = ISTATE_SENT_STATUS; + spin_unlock_bh(&cmd->istate_lock); + break; + default: + pr_err("Unknown Opcode: 0x%02x ITT:" + " 0x%08x, i_state: %d on CID: %hu\n", + cmd->iscsi_opcode, cmd->init_task_tag, + state, conn->cid); + spin_unlock_bh(&cmd->istate_lock); + goto transport_err; + } + goto get_immediate; + } else + conn->tx_immediate_queue = 0; + +get_response: + qr = iscsit_get_cmd_from_response_queue(conn); + if (qr) { + cmd = qr->cmd; + state = qr->state; + kmem_cache_free(lio_qr_cache, qr); + + spin_lock_bh(&cmd->istate_lock); +check_rsp_state: + switch (state) { + case ISTATE_SEND_DATAIN: + spin_unlock_bh(&cmd->istate_lock); + ret = iscsit_send_data_in(cmd, conn, + &eodr); + map_sg = 1; + break; + case ISTATE_SEND_STATUS: + case ISTATE_SEND_STATUS_RECOVERY: + spin_unlock_bh(&cmd->istate_lock); + use_misc = 1; + ret = iscsit_send_status(cmd, conn); + break; + case ISTATE_SEND_LOGOUTRSP: + spin_unlock_bh(&cmd->istate_lock); + use_misc = 1; + ret = iscsit_send_logout_response(cmd, conn); + break; + case ISTATE_SEND_ASYNCMSG: + spin_unlock_bh(&cmd->istate_lock); + use_misc = 1; + ret = iscsit_send_conn_drop_async_message( + cmd, conn); + break; + case ISTATE_SEND_NOPIN: + spin_unlock_bh(&cmd->istate_lock); + use_misc = 1; + ret = iscsit_send_nopin_response(cmd, conn); + break; + case ISTATE_SEND_REJECT: + spin_unlock_bh(&cmd->istate_lock); + use_misc = 1; + ret = iscsit_send_reject(cmd, conn); + break; + case ISTATE_SEND_TASKMGTRSP: + spin_unlock_bh(&cmd->istate_lock); + use_misc = 1; + ret = iscsit_send_task_mgt_rsp(cmd, conn); + if (ret != 0) + break; + ret = iscsit_tmr_post_handler(cmd, conn); + if (ret != 0) + iscsit_fall_back_to_erl0(conn->sess); + break; + case ISTATE_SEND_TEXTRSP: + spin_unlock_bh(&cmd->istate_lock); + use_misc = 1; + ret = iscsit_send_text_rsp(cmd, conn); + break; + default: + pr_err("Unknown Opcode: 0x%02x ITT:" + " 0x%08x, i_state: %d on CID: %hu\n", + cmd->iscsi_opcode, cmd->init_task_tag, + state, conn->cid); + spin_unlock_bh(&cmd->istate_lock); + goto transport_err; + } + if (ret < 0) { + conn->tx_response_queue = 0; + goto transport_err; + } + + if (map_sg && !conn->conn_ops->IFMarker) { + if (iscsit_fe_sendpage_sg(cmd, conn) < 0) { + conn->tx_response_queue = 0; + iscsit_tx_thread_wait_for_tcp(conn); + iscsit_unmap_iovec(cmd); + goto transport_err; + } + } else { + if (iscsit_send_tx_data(cmd, conn, use_misc) < 0) { + conn->tx_response_queue = 0; + iscsit_tx_thread_wait_for_tcp(conn); + iscsit_unmap_iovec(cmd); + goto transport_err; + } + } + map_sg = 0; + iscsit_unmap_iovec(cmd); + + spin_lock_bh(&cmd->istate_lock); + switch (state) { + case ISTATE_SEND_DATAIN: + if (!eodr) + goto check_rsp_state; + + if (eodr == 1) { + cmd->i_state = ISTATE_SENT_LAST_DATAIN; + sent_status = 1; + eodr = use_misc = 0; + } else if (eodr == 2) { + cmd->i_state = state = + ISTATE_SEND_STATUS; + sent_status = 0; + eodr = use_misc = 0; + goto check_rsp_state; + } + break; + case ISTATE_SEND_STATUS: + use_misc = 0; + sent_status = 1; + break; + case ISTATE_SEND_ASYNCMSG: + case ISTATE_SEND_NOPIN: + case ISTATE_SEND_STATUS_RECOVERY: + case ISTATE_SEND_TEXTRSP: + use_misc = 0; + sent_status = 1; + break; + case ISTATE_SEND_REJECT: + use_misc = 0; + if (cmd->cmd_flags & ICF_REJECT_FAIL_CONN) { + cmd->cmd_flags &= ~ICF_REJECT_FAIL_CONN; + spin_unlock_bh(&cmd->istate_lock); + complete(&cmd->reject_comp); + goto transport_err; + } + complete(&cmd->reject_comp); + break; + case ISTATE_SEND_TASKMGTRSP: + use_misc = 0; + sent_status = 1; + break; + case ISTATE_SEND_LOGOUTRSP: + spin_unlock_bh(&cmd->istate_lock); + if (!iscsit_logout_post_handler(cmd, conn)) + goto restart; + spin_lock_bh(&cmd->istate_lock); + use_misc = 0; + sent_status = 1; + break; + default: + pr_err("Unknown Opcode: 0x%02x ITT:" + " 0x%08x, i_state: %d on CID: %hu\n", + cmd->iscsi_opcode, cmd->init_task_tag, + cmd->i_state, conn->cid); + spin_unlock_bh(&cmd->istate_lock); + goto transport_err; + } + + if (sent_status) { + cmd->i_state = ISTATE_SENT_STATUS; + sent_status = 0; + } + spin_unlock_bh(&cmd->istate_lock); + + if (atomic_read(&conn->check_immediate_queue)) + goto get_immediate; + + goto get_response; + } else + conn->tx_response_queue = 0; } transport_err: @@ -3935,9 +3952,9 @@ static void iscsit_release_commands_from_conn(struct iscsi_conn *conn) * has been reset -> returned sleeping pre-handler state. */ spin_lock_bh(&conn->cmd_lock); - list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_conn_node) { + list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_list) { - list_del(&cmd->i_conn_node); + list_del(&cmd->i_list); spin_unlock_bh(&conn->cmd_lock); iscsit_increment_maxcmdsn(cmd, sess); @@ -3955,7 +3972,7 @@ static void iscsit_stop_timers_for_cmds( struct iscsi_cmd *cmd; spin_lock_bh(&conn->cmd_lock); - list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) { + list_for_each_entry(cmd, &conn->conn_cmd_list, i_list) { if (cmd->data_direction == DMA_TO_DEVICE) iscsit_stop_dataout_timer(cmd); } diff --git a/trunk/drivers/target/iscsi/iscsi_target.h b/trunk/drivers/target/iscsi/iscsi_target.h index 12abb4c9e34e..5db2ddeed5eb 100644 --- a/trunk/drivers/target/iscsi/iscsi_target.h +++ b/trunk/drivers/target/iscsi/iscsi_target.h @@ -18,7 +18,8 @@ extern int iscsit_logout_closesession(struct iscsi_cmd *, struct iscsi_conn *); extern int iscsit_logout_closeconnection(struct iscsi_cmd *, struct iscsi_conn *); extern int iscsit_logout_removeconnforrecovery(struct iscsi_cmd *, struct iscsi_conn *); extern int iscsit_send_async_msg(struct iscsi_conn *, u16, u8, u8); -extern int iscsit_build_r2ts_for_cmd(struct iscsi_cmd *, struct iscsi_conn *, bool recovery); +extern int iscsit_send_r2t(struct iscsi_cmd *, struct iscsi_conn *); +extern int iscsit_build_r2ts_for_cmd(struct iscsi_cmd *, struct iscsi_conn *, int); extern void iscsit_thread_get_cpumask(struct iscsi_conn *); extern int iscsi_target_tx_thread(void *); extern int iscsi_target_rx_thread(void *); diff --git a/trunk/drivers/target/iscsi/iscsi_target_configfs.c b/trunk/drivers/target/iscsi/iscsi_target_configfs.c index 69dc8e35c03a..00c58cc82c85 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_configfs.c +++ b/trunk/drivers/target/iscsi/iscsi_target_configfs.c @@ -1538,7 +1538,7 @@ static int lio_write_pending(struct se_cmd *se_cmd) struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); if (!cmd->immediate_data && !cmd->unsolicited_data) - return iscsit_build_r2ts_for_cmd(cmd, cmd->conn, false); + return iscsit_build_r2ts_for_cmd(cmd, cmd->conn, 1); return 0; } diff --git a/trunk/drivers/target/iscsi/iscsi_target_core.h b/trunk/drivers/target/iscsi/iscsi_target_core.h index 1c70144cdaf1..2aaee7efa683 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_core.h +++ b/trunk/drivers/target/iscsi/iscsi_target_core.h @@ -296,11 +296,12 @@ struct iscsi_datain_req { u32 runlength; u32 data_length; u32 data_offset; + u32 data_offset_end; u32 data_sn; u32 next_burst_len; u32 read_data_done; u32 seq_send_order; - struct list_head cmd_datain_node; + struct list_head dr_list; } ____cacheline_aligned; struct iscsi_ooo_cmdsn { @@ -380,6 +381,8 @@ struct iscsi_cmd { u32 buf_ptr_size; /* Used to store DataDigest */ u32 data_crc; + /* Total size in bytes associated with command */ + u32 data_length; /* Counter for MaxOutstandingR2T */ u32 outstanding_r2ts; /* Next R2T Offset when DataSequenceInOrder=Yes */ @@ -461,13 +464,16 @@ struct iscsi_cmd { /* Session the command is part of, used for connection recovery */ struct iscsi_session *sess; /* list_head for connection list */ - struct list_head i_conn_node; + struct list_head i_list; /* The TCM I/O descriptor that is accessed via container_of() */ struct se_cmd se_cmd; /* Sense buffer that will be mapped into outgoing status */ #define ISCSI_SENSE_BUFFER_LEN (TRANSPORT_SENSE_BUFFER + 2) unsigned char sense_buffer[ISCSI_SENSE_BUFFER_LEN]; + struct scatterlist *t_mem_sg; + u32 t_mem_sg_nents; + u32 padding; u8 pad_bytes[4]; @@ -494,6 +500,8 @@ struct iscsi_conn { u8 network_transport; enum iscsi_timer_flags_table nopin_timer_flags; enum iscsi_timer_flags_table nopin_response_timer_flags; + u8 tx_immediate_queue; + u8 tx_response_queue; /* Used to know what thread encountered a transport failure */ u8 which_thread; /* connection id assigned by the Initiator */ diff --git a/trunk/drivers/target/iscsi/iscsi_target_datain_values.c b/trunk/drivers/target/iscsi/iscsi_target_datain_values.c index 848fee768948..8c0495129513 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_datain_values.c +++ b/trunk/drivers/target/iscsi/iscsi_target_datain_values.c @@ -37,7 +37,7 @@ struct iscsi_datain_req *iscsit_allocate_datain_req(void) " struct iscsi_datain_req\n"); return NULL; } - INIT_LIST_HEAD(&dr->cmd_datain_node); + INIT_LIST_HEAD(&dr->dr_list); return dr; } @@ -45,14 +45,14 @@ struct iscsi_datain_req *iscsit_allocate_datain_req(void) void iscsit_attach_datain_req(struct iscsi_cmd *cmd, struct iscsi_datain_req *dr) { spin_lock(&cmd->datain_lock); - list_add_tail(&dr->cmd_datain_node, &cmd->datain_list); + list_add_tail(&dr->dr_list, &cmd->datain_list); spin_unlock(&cmd->datain_lock); } void iscsit_free_datain_req(struct iscsi_cmd *cmd, struct iscsi_datain_req *dr) { spin_lock(&cmd->datain_lock); - list_del(&dr->cmd_datain_node); + list_del(&dr->dr_list); spin_unlock(&cmd->datain_lock); kmem_cache_free(lio_dr_cache, dr); @@ -63,8 +63,8 @@ void iscsit_free_all_datain_reqs(struct iscsi_cmd *cmd) struct iscsi_datain_req *dr, *dr_tmp; spin_lock(&cmd->datain_lock); - list_for_each_entry_safe(dr, dr_tmp, &cmd->datain_list, cmd_datain_node) { - list_del(&dr->cmd_datain_node); + list_for_each_entry_safe(dr, dr_tmp, &cmd->datain_list, dr_list) { + list_del(&dr->dr_list); kmem_cache_free(lio_dr_cache, dr); } spin_unlock(&cmd->datain_lock); @@ -72,14 +72,17 @@ void iscsit_free_all_datain_reqs(struct iscsi_cmd *cmd) struct iscsi_datain_req *iscsit_get_datain_req(struct iscsi_cmd *cmd) { + struct iscsi_datain_req *dr; + if (list_empty(&cmd->datain_list)) { pr_err("cmd->datain_list is empty for ITT:" " 0x%08x\n", cmd->init_task_tag); return NULL; } + list_for_each_entry(dr, &cmd->datain_list, dr_list) + break; - return list_first_entry(&cmd->datain_list, struct iscsi_datain_req, - cmd_datain_node); + return dr; } /* @@ -110,7 +113,7 @@ static struct iscsi_datain_req *iscsit_set_datain_values_yes_and_yes( read_data_done = (!dr->recovery) ? cmd->read_data_done : dr->read_data_done; - read_data_left = (cmd->se_cmd.data_length - read_data_done); + read_data_left = (cmd->data_length - read_data_done); if (!read_data_left) { pr_err("ITT: 0x%08x read_data_left is zero!\n", cmd->init_task_tag); @@ -209,7 +212,7 @@ static struct iscsi_datain_req *iscsit_set_datain_values_no_and_yes( seq_send_order = (!dr->recovery) ? cmd->seq_send_order : dr->seq_send_order; - read_data_left = (cmd->se_cmd.data_length - read_data_done); + read_data_left = (cmd->data_length - read_data_done); if (!read_data_left) { pr_err("ITT: 0x%08x read_data_left is zero!\n", cmd->init_task_tag); @@ -228,8 +231,8 @@ static struct iscsi_datain_req *iscsit_set_datain_values_no_and_yes( offset = (seq->offset + seq->next_burst_len); if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >= - cmd->se_cmd.data_length) { - datain->length = (cmd->se_cmd.data_length - offset); + cmd->data_length) { + datain->length = (cmd->data_length - offset); datain->offset = offset; datain->flags |= ISCSI_FLAG_CMD_FINAL; @@ -261,7 +264,7 @@ static struct iscsi_datain_req *iscsit_set_datain_values_no_and_yes( } } - if ((read_data_done + datain->length) == cmd->se_cmd.data_length) + if ((read_data_done + datain->length) == cmd->data_length) datain->flags |= ISCSI_FLAG_DATA_STATUS; datain->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++; @@ -330,7 +333,7 @@ static struct iscsi_datain_req *iscsit_set_datain_values_yes_and_no( read_data_done = (!dr->recovery) ? cmd->read_data_done : dr->read_data_done; - read_data_left = (cmd->se_cmd.data_length - read_data_done); + read_data_left = (cmd->data_length - read_data_done); if (!read_data_left) { pr_err("ITT: 0x%08x read_data_left is zero!\n", cmd->init_task_tag); @@ -341,7 +344,7 @@ static struct iscsi_datain_req *iscsit_set_datain_values_yes_and_no( if (!pdu) return dr; - if ((read_data_done + pdu->length) == cmd->se_cmd.data_length) { + if ((read_data_done + pdu->length) == cmd->data_length) { pdu->flags |= (ISCSI_FLAG_CMD_FINAL | ISCSI_FLAG_DATA_STATUS); if (conn->sess->sess_ops->ErrorRecoveryLevel > 0) pdu->flags |= ISCSI_FLAG_DATA_ACK; @@ -430,7 +433,7 @@ static struct iscsi_datain_req *iscsit_set_datain_values_no_and_no( seq_send_order = (!dr->recovery) ? cmd->seq_send_order : dr->seq_send_order; - read_data_left = (cmd->se_cmd.data_length - read_data_done); + read_data_left = (cmd->data_length - read_data_done); if (!read_data_left) { pr_err("ITT: 0x%08x read_data_left is zero!\n", cmd->init_task_tag); @@ -460,7 +463,7 @@ static struct iscsi_datain_req *iscsit_set_datain_values_no_and_no( } else seq->next_burst_len += pdu->length; - if ((read_data_done + pdu->length) == cmd->se_cmd.data_length) + if ((read_data_done + pdu->length) == cmd->data_length) pdu->flags |= ISCSI_FLAG_DATA_STATUS; pdu->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++; diff --git a/trunk/drivers/target/iscsi/iscsi_target_erl0.c b/trunk/drivers/target/iscsi/iscsi_target_erl0.c index 1a02016ecdab..1ab0560b0924 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_erl0.c +++ b/trunk/drivers/target/iscsi/iscsi_target_erl0.c @@ -48,9 +48,9 @@ void iscsit_set_dataout_sequence_values( if (cmd->unsolicited_data) { cmd->seq_start_offset = cmd->write_data_done; cmd->seq_end_offset = (cmd->write_data_done + - (cmd->se_cmd.data_length > + (cmd->data_length > conn->sess->sess_ops->FirstBurstLength) ? - conn->sess->sess_ops->FirstBurstLength : cmd->se_cmd.data_length); + conn->sess->sess_ops->FirstBurstLength : cmd->data_length); return; } @@ -59,15 +59,15 @@ void iscsit_set_dataout_sequence_values( if (!cmd->seq_start_offset && !cmd->seq_end_offset) { cmd->seq_start_offset = cmd->write_data_done; - cmd->seq_end_offset = (cmd->se_cmd.data_length > + cmd->seq_end_offset = (cmd->data_length > conn->sess->sess_ops->MaxBurstLength) ? (cmd->write_data_done + - conn->sess->sess_ops->MaxBurstLength) : cmd->se_cmd.data_length; + conn->sess->sess_ops->MaxBurstLength) : cmd->data_length; } else { cmd->seq_start_offset = cmd->seq_end_offset; cmd->seq_end_offset = ((cmd->seq_end_offset + conn->sess->sess_ops->MaxBurstLength) >= - cmd->se_cmd.data_length) ? cmd->se_cmd.data_length : + cmd->data_length) ? cmd->data_length : (cmd->seq_end_offset + conn->sess->sess_ops->MaxBurstLength); } @@ -182,13 +182,13 @@ static int iscsit_dataout_check_unsolicited_sequence( if (!conn->sess->sess_ops->DataPDUInOrder) goto out; - if ((first_burst_len != cmd->se_cmd.data_length) && + if ((first_burst_len != cmd->data_length) && (first_burst_len != conn->sess->sess_ops->FirstBurstLength)) { pr_err("Unsolicited non-immediate data" " received %u does not equal FirstBurstLength: %u, and" " does not equal ExpXferLen %u.\n", first_burst_len, conn->sess->sess_ops->FirstBurstLength, - cmd->se_cmd.data_length); + cmd->data_length); transport_send_check_condition_and_sense(&cmd->se_cmd, TCM_INCORRECT_AMOUNT_OF_DATA, 0); return DATAOUT_CANNOT_RECOVER; @@ -201,10 +201,10 @@ static int iscsit_dataout_check_unsolicited_sequence( conn->sess->sess_ops->FirstBurstLength); return DATAOUT_CANNOT_RECOVER; } - if (first_burst_len == cmd->se_cmd.data_length) { + if (first_burst_len == cmd->data_length) { pr_err("Command ITT: 0x%08x reached" " ExpXferLen: %u, but ISCSI_FLAG_CMD_FINAL is not set. protocol" - " error.\n", cmd->init_task_tag, cmd->se_cmd.data_length); + " error.\n", cmd->init_task_tag, cmd->data_length); return DATAOUT_CANNOT_RECOVER; } } @@ -294,7 +294,7 @@ static int iscsit_dataout_check_sequence( if ((next_burst_len < conn->sess->sess_ops->MaxBurstLength) && ((cmd->write_data_done + payload_length) < - cmd->se_cmd.data_length)) { + cmd->data_length)) { pr_err("Command ITT: 0x%08x set ISCSI_FLAG_CMD_FINAL" " before end of DataOUT sequence, protocol" " error.\n", cmd->init_task_tag); @@ -319,7 +319,7 @@ static int iscsit_dataout_check_sequence( return DATAOUT_CANNOT_RECOVER; } if ((cmd->write_data_done + payload_length) == - cmd->se_cmd.data_length) { + cmd->data_length) { pr_err("Command ITT: 0x%08x reached" " last DataOUT PDU in sequence but ISCSI_FLAG_" "CMD_FINAL is not set, protocol error.\n", @@ -640,12 +640,9 @@ static int iscsit_dataout_post_crc_passed( cmd->write_data_done += payload_length; - if (cmd->write_data_done == cmd->se_cmd.data_length) - return DATAOUT_SEND_TO_TRANSPORT; - else if (send_r2t) - return DATAOUT_SEND_R2T; - else - return DATAOUT_NORMAL; + return (cmd->write_data_done == cmd->data_length) ? + DATAOUT_SEND_TO_TRANSPORT : (send_r2t) ? + DATAOUT_SEND_R2T : DATAOUT_NORMAL; } static int iscsit_dataout_post_crc_failed( diff --git a/trunk/drivers/target/iscsi/iscsi_target_erl1.c b/trunk/drivers/target/iscsi/iscsi_target_erl1.c index ecdd46deedda..006f605edb08 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_erl1.c +++ b/trunk/drivers/target/iscsi/iscsi_target_erl1.c @@ -279,9 +279,11 @@ int iscsit_create_recovery_datain_values_datasequenceinorder_no( * seq->first_datasn and seq->last_datasn have not been set. */ if (!seq->sent) { +#if 0 pr_err("Ignoring non-sent sequence 0x%08x ->" " 0x%08x\n\n", seq->first_datasn, seq->last_datasn); +#endif continue; } @@ -292,10 +294,11 @@ int iscsit_create_recovery_datain_values_datasequenceinorder_no( */ if ((seq->first_datasn < begrun) && (seq->last_datasn < begrun)) { +#if 0 pr_err("Pre BegRun sequence 0x%08x ->" " 0x%08x\n", seq->first_datasn, seq->last_datasn); - +#endif read_data_done += cmd->seq_list[i].xfer_len; seq->next_burst_len = seq->pdu_send_order = 0; continue; @@ -306,10 +309,11 @@ int iscsit_create_recovery_datain_values_datasequenceinorder_no( */ if ((seq->first_datasn <= begrun) && (seq->last_datasn >= begrun)) { +#if 0 pr_err("Found sequence begrun: 0x%08x in" " 0x%08x -> 0x%08x\n", begrun, seq->first_datasn, seq->last_datasn); - +#endif seq_send_order = seq->seq_send_order; data_sn = seq->first_datasn; seq->next_burst_len = seq->pdu_send_order = 0; @@ -365,9 +369,10 @@ int iscsit_create_recovery_datain_values_datasequenceinorder_no( */ if ((seq->first_datasn > begrun) || (seq->last_datasn > begrun)) { +#if 0 pr_err("Post BegRun sequence 0x%08x -> 0x%08x\n", seq->first_datasn, seq->last_datasn); - +#endif seq->next_burst_len = seq->pdu_send_order = 0; continue; } @@ -521,7 +526,7 @@ int iscsit_handle_status_snack( found_cmd = 0; spin_lock_bh(&conn->cmd_lock); - list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) { + list_for_each_entry(cmd, &conn->conn_cmd_list, i_list) { if (cmd->stat_sn == begrun) { found_cmd = 1; break; @@ -982,7 +987,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo) return 0; iscsit_set_dataout_sequence_values(cmd); - iscsit_build_r2ts_for_cmd(cmd, cmd->conn, false); + iscsit_build_r2ts_for_cmd(cmd, cmd->conn, 0); } return 0; } @@ -1116,8 +1121,8 @@ static int iscsit_set_dataout_timeout_values( if (cmd->unsolicited_data) { *offset = 0; *length = (conn->sess->sess_ops->FirstBurstLength > - cmd->se_cmd.data_length) ? - cmd->se_cmd.data_length : + cmd->data_length) ? + cmd->data_length : conn->sess->sess_ops->FirstBurstLength; return 0; } @@ -1188,8 +1193,8 @@ static void iscsit_handle_dataout_timeout(unsigned long data) if (conn->sess->sess_ops->DataPDUInOrder) { pdu_offset = cmd->write_data_done; if ((pdu_offset + (conn->sess->sess_ops->MaxBurstLength - - cmd->next_burst_len)) > cmd->se_cmd.data_length) - pdu_length = (cmd->se_cmd.data_length - + cmd->next_burst_len)) > cmd->data_length) + pdu_length = (cmd->data_length - cmd->write_data_done); else pdu_length = (conn->sess->sess_ops->MaxBurstLength - diff --git a/trunk/drivers/target/iscsi/iscsi_target_erl2.c b/trunk/drivers/target/iscsi/iscsi_target_erl2.c index 65aac14fd831..1af1f21af21f 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_erl2.c +++ b/trunk/drivers/target/iscsi/iscsi_target_erl2.c @@ -138,9 +138,9 @@ void iscsit_free_connection_recovery_entires(struct iscsi_session *sess) spin_lock(&cr->conn_recovery_cmd_lock); list_for_each_entry_safe(cmd, cmd_tmp, - &cr->conn_recovery_cmd_list, i_conn_node) { + &cr->conn_recovery_cmd_list, i_list) { - list_del(&cmd->i_conn_node); + list_del(&cmd->i_list); cmd->conn = NULL; spin_unlock(&cr->conn_recovery_cmd_lock); iscsit_free_cmd(cmd); @@ -160,9 +160,9 @@ void iscsit_free_connection_recovery_entires(struct iscsi_session *sess) spin_lock(&cr->conn_recovery_cmd_lock); list_for_each_entry_safe(cmd, cmd_tmp, - &cr->conn_recovery_cmd_list, i_conn_node) { + &cr->conn_recovery_cmd_list, i_list) { - list_del(&cmd->i_conn_node); + list_del(&cmd->i_list); cmd->conn = NULL; spin_unlock(&cr->conn_recovery_cmd_lock); iscsit_free_cmd(cmd); @@ -220,7 +220,7 @@ int iscsit_remove_cmd_from_connection_recovery( } cr = cmd->cr; - list_del(&cmd->i_conn_node); + list_del(&cmd->i_list); return --cr->cmd_count; } @@ -234,7 +234,7 @@ void iscsit_discard_cr_cmds_by_expstatsn( spin_lock(&cr->conn_recovery_cmd_lock); list_for_each_entry_safe(cmd, cmd_tmp, - &cr->conn_recovery_cmd_list, i_conn_node) { + &cr->conn_recovery_cmd_list, i_list) { if (((cmd->deferred_i_state != ISTATE_SENT_STATUS) && (cmd->deferred_i_state != ISTATE_REMOVE)) || @@ -297,11 +297,11 @@ int iscsit_discard_unacknowledged_ooo_cmdsns_for_conn(struct iscsi_conn *conn) mutex_unlock(&sess->cmdsn_mutex); spin_lock_bh(&conn->cmd_lock); - list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_conn_node) { + list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_list) { if (!(cmd->cmd_flags & ICF_OOO_CMDSN)) continue; - list_del(&cmd->i_conn_node); + list_del(&cmd->i_list); spin_unlock_bh(&conn->cmd_lock); iscsit_free_cmd(cmd); @@ -339,14 +339,14 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) /* * Only perform connection recovery on ISCSI_OP_SCSI_CMD or * ISCSI_OP_NOOP_OUT opcodes. For all other opcodes call - * list_del(&cmd->i_conn_node); to release the command to the + * list_del(&cmd->i_list); to release the command to the * session pool and remove it from the connection's list. * * Also stop the DataOUT timer, which will be restarted after * sending the TMR response. */ spin_lock_bh(&conn->cmd_lock); - list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_conn_node) { + list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_list) { if ((cmd->iscsi_opcode != ISCSI_OP_SCSI_CMD) && (cmd->iscsi_opcode != ISCSI_OP_NOOP_OUT)) { @@ -355,7 +355,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) " CID: %hu\n", cmd->iscsi_opcode, cmd->init_task_tag, cmd->cmd_sn, conn->cid); - list_del(&cmd->i_conn_node); + list_del(&cmd->i_list); spin_unlock_bh(&conn->cmd_lock); iscsit_free_cmd(cmd); spin_lock_bh(&conn->cmd_lock); @@ -375,7 +375,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) */ if (!(cmd->cmd_flags & ICF_OOO_CMDSN) && !cmd->immediate_cmd && (cmd->cmd_sn >= conn->sess->exp_cmd_sn)) { - list_del(&cmd->i_conn_node); + list_del(&cmd->i_list); spin_unlock_bh(&conn->cmd_lock); iscsit_free_cmd(cmd); spin_lock_bh(&conn->cmd_lock); @@ -397,7 +397,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) cmd->sess = conn->sess; - list_del(&cmd->i_conn_node); + list_del(&cmd->i_list); spin_unlock_bh(&conn->cmd_lock); iscsit_free_all_datain_reqs(cmd); @@ -407,7 +407,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) * Add the struct iscsi_cmd to the connection recovery cmd list */ spin_lock(&cr->conn_recovery_cmd_lock); - list_add_tail(&cmd->i_conn_node, &cr->conn_recovery_cmd_list); + list_add_tail(&cmd->i_list, &cr->conn_recovery_cmd_list); spin_unlock(&cr->conn_recovery_cmd_lock); spin_lock_bh(&conn->cmd_lock); diff --git a/trunk/drivers/target/iscsi/iscsi_target_parameters.c b/trunk/drivers/target/iscsi/iscsi_target_parameters.c index ed5241e7f12a..eb05c9d751ea 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_parameters.c +++ b/trunk/drivers/target/iscsi/iscsi_target_parameters.c @@ -803,6 +803,14 @@ static int iscsi_check_numerical_value(struct iscsi_param *param, char *value_pt value = simple_strtoul(value_ptr, &tmpptr, 0); +/* #warning FIXME: Fix this */ +#if 0 + if (strspn(endptr, WHITE_SPACE) != strlen(endptr)) { + pr_err("Illegal value \"%s\" for \"%s\".\n", + value, param->name); + return -1; + } +#endif if (IS_TYPERANGE_0_TO_2(param)) { if ((value < 0) || (value > 2)) { pr_err("Illegal value for \"%s\", must be" @@ -1037,6 +1045,13 @@ static char *iscsi_check_valuelist_for_support( tmp2 = strchr(acceptor_values, ','); if (tmp2) *tmp2 = '\0'; + if (!acceptor_values || !proposer_values) { + if (tmp1) + *tmp1 = ','; + if (tmp2) + *tmp2 = ','; + return NULL; + } if (!strcmp(acceptor_values, proposer_values)) { if (tmp2) *tmp2 = ','; @@ -1046,6 +1061,8 @@ static char *iscsi_check_valuelist_for_support( *tmp2++ = ','; acceptor_values = tmp2; + if (!acceptor_values) + break; } while (acceptor_values); if (tmp1) *tmp1++ = ','; diff --git a/trunk/drivers/target/iscsi/iscsi_target_seq_pdu_list.c b/trunk/drivers/target/iscsi/iscsi_target_seq_pdu_list.c index 85a306e067ba..fc694082bfc0 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_seq_pdu_list.c +++ b/trunk/drivers/target/iscsi/iscsi_target_seq_pdu_list.c @@ -24,13 +24,11 @@ #include "iscsi_target_core.h" #include "iscsi_target_util.h" -#include "iscsi_target_tpg.h" #include "iscsi_target_seq_pdu_list.h" #define OFFLOAD_BUF_SIZE 32768 -#ifdef DEBUG -static void iscsit_dump_seq_list(struct iscsi_cmd *cmd) +void iscsit_dump_seq_list(struct iscsi_cmd *cmd) { int i; struct iscsi_seq *seq; @@ -48,7 +46,7 @@ static void iscsit_dump_seq_list(struct iscsi_cmd *cmd) } } -static void iscsit_dump_pdu_list(struct iscsi_cmd *cmd) +void iscsit_dump_pdu_list(struct iscsi_cmd *cmd) { int i; struct iscsi_pdu *pdu; @@ -63,10 +61,6 @@ static void iscsit_dump_pdu_list(struct iscsi_cmd *cmd) pdu->length, pdu->pdu_send_order, pdu->seq_no); } } -#else -static void iscsit_dump_seq_list(struct iscsi_cmd *cmd) {} -static void iscsit_dump_pdu_list(struct iscsi_cmd *cmd) {} -#endif static void iscsit_ordered_seq_lists( struct iscsi_cmd *cmd, @@ -141,11 +135,11 @@ static int iscsit_randomize_pdu_lists( seq_count++; continue; } - array = kcalloc(seq_count, sizeof(u32), GFP_KERNEL); + array = kzalloc(seq_count * sizeof(u32), GFP_KERNEL); if (!array) { pr_err("Unable to allocate memory" " for random array.\n"); - return -ENOMEM; + return -1; } iscsit_create_random_array(array, seq_count); @@ -161,11 +155,11 @@ static int iscsit_randomize_pdu_lists( } if (seq_count) { - array = kcalloc(seq_count, sizeof(u32), GFP_KERNEL); + array = kzalloc(seq_count * sizeof(u32), GFP_KERNEL); if (!array) { pr_err("Unable to allocate memory for" " random array.\n"); - return -ENOMEM; + return -1; } iscsit_create_random_array(array, seq_count); @@ -193,10 +187,10 @@ static int iscsit_randomize_seq_lists( if (!seq_count) return 0; - array = kcalloc(seq_count, sizeof(u32), GFP_KERNEL); + array = kzalloc(seq_count * sizeof(u32), GFP_KERNEL); if (!array) { pr_err("Unable to allocate memory for random array.\n"); - return -ENOMEM; + return -1; } iscsit_create_random_array(array, seq_count); @@ -227,10 +221,11 @@ static void iscsit_determine_counts_for_list( if ((bl->type == PDULIST_UNSOLICITED) || (bl->type == PDULIST_IMMEDIATE_AND_UNSOLICITED)) - unsolicited_data_length = min(cmd->se_cmd.data_length, - conn->sess->sess_ops->FirstBurstLength); + unsolicited_data_length = (cmd->data_length > + conn->sess->sess_ops->FirstBurstLength) ? + conn->sess->sess_ops->FirstBurstLength : cmd->data_length; - while (offset < cmd->se_cmd.data_length) { + while (offset < cmd->data_length) { *pdu_count += 1; if (check_immediate) { @@ -244,10 +239,10 @@ static void iscsit_determine_counts_for_list( } if (unsolicited_data_length > 0) { if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) - >= cmd->se_cmd.data_length) { + >= cmd->data_length) { unsolicited_data_length -= - (cmd->se_cmd.data_length - offset); - offset += (cmd->se_cmd.data_length - offset); + (cmd->data_length - offset); + offset += (cmd->data_length - offset); continue; } if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) @@ -268,8 +263,8 @@ static void iscsit_determine_counts_for_list( continue; } if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >= - cmd->se_cmd.data_length) { - offset += (cmd->se_cmd.data_length - offset); + cmd->data_length) { + offset += (cmd->data_length - offset); continue; } if ((burstlength + conn->conn_ops->MaxRecvDataSegmentLength) >= @@ -288,10 +283,10 @@ static void iscsit_determine_counts_for_list( /* - * Builds PDU and/or Sequence list, called while DataSequenceInOrder=No - * or DataPDUInOrder=No. + * Builds PDU and/or Sequence list, called while DataSequenceInOrder=No + * and DataPDUInOrder=No. */ -static int iscsit_do_build_pdu_and_seq_lists( +static int iscsit_build_pdu_and_seq_list( struct iscsi_cmd *cmd, struct iscsi_build_list *bl) { @@ -311,10 +306,11 @@ static int iscsit_do_build_pdu_and_seq_lists( if ((bl->type == PDULIST_UNSOLICITED) || (bl->type == PDULIST_IMMEDIATE_AND_UNSOLICITED)) - unsolicited_data_length = min(cmd->se_cmd.data_length, - conn->sess->sess_ops->FirstBurstLength); + unsolicited_data_length = (cmd->data_length > + conn->sess->sess_ops->FirstBurstLength) ? + conn->sess->sess_ops->FirstBurstLength : cmd->data_length; - while (offset < cmd->se_cmd.data_length) { + while (offset < cmd->data_length) { pdu_count++; if (!datapduinorder) { pdu[i].offset = offset; @@ -350,21 +346,21 @@ static int iscsit_do_build_pdu_and_seq_lists( if (unsolicited_data_length > 0) { if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >= - cmd->se_cmd.data_length) { + cmd->data_length) { if (!datapduinorder) { pdu[i].type = PDUTYPE_UNSOLICITED; pdu[i].length = - (cmd->se_cmd.data_length - offset); + (cmd->data_length - offset); } if (!datasequenceinorder) { seq[seq_no].type = SEQTYPE_UNSOLICITED; seq[seq_no].pdu_count = pdu_count; seq[seq_no].xfer_len = (burstlength + - (cmd->se_cmd.data_length - offset)); + (cmd->data_length - offset)); } unsolicited_data_length -= - (cmd->se_cmd.data_length - offset); - offset += (cmd->se_cmd.data_length - offset); + (cmd->data_length - offset); + offset += (cmd->data_length - offset); continue; } if ((offset + @@ -406,18 +402,18 @@ static int iscsit_do_build_pdu_and_seq_lists( continue; } if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >= - cmd->se_cmd.data_length) { + cmd->data_length) { if (!datapduinorder) { pdu[i].type = PDUTYPE_NORMAL; - pdu[i].length = (cmd->se_cmd.data_length - offset); + pdu[i].length = (cmd->data_length - offset); } if (!datasequenceinorder) { seq[seq_no].type = SEQTYPE_NORMAL; seq[seq_no].pdu_count = pdu_count; seq[seq_no].xfer_len = (burstlength + - (cmd->se_cmd.data_length - offset)); + (cmd->data_length - offset)); } - offset += (cmd->se_cmd.data_length - offset); + offset += (cmd->data_length - offset); continue; } if ((burstlength + conn->conn_ops->MaxRecvDataSegmentLength) >= @@ -468,8 +464,9 @@ static int iscsit_do_build_pdu_and_seq_lists( } else iscsit_ordered_seq_lists(cmd, bl->type); } - +#if 0 iscsit_dump_seq_list(cmd); +#endif } if (!datapduinorder) { if (bl->data_direction & ISCSI_PDU_WRITE) { @@ -487,86 +484,50 @@ static int iscsit_do_build_pdu_and_seq_lists( } else iscsit_ordered_pdu_lists(cmd, bl->type); } - +#if 0 iscsit_dump_pdu_list(cmd); +#endif } return 0; } -int iscsit_build_pdu_and_seq_lists( +/* + * Only called while DataSequenceInOrder=No or DataPDUInOrder=No. + */ +int iscsit_do_build_list( struct iscsi_cmd *cmd, - u32 immediate_data_length) + struct iscsi_build_list *bl) { - struct iscsi_build_list bl; u32 pdu_count = 0, seq_count = 1; struct iscsi_conn *conn = cmd->conn; struct iscsi_pdu *pdu = NULL; struct iscsi_seq *seq = NULL; - struct iscsi_session *sess = conn->sess; - struct iscsi_node_attrib *na; - - /* - * Do nothing if no OOO shenanigans - */ - if (sess->sess_ops->DataSequenceInOrder && - sess->sess_ops->DataPDUInOrder) - return 0; - - if (cmd->data_direction == DMA_NONE) - return 0; - - na = iscsit_tpg_get_node_attrib(sess); - memset(&bl, 0, sizeof(struct iscsi_build_list)); - - if (cmd->data_direction == DMA_FROM_DEVICE) { - bl.data_direction = ISCSI_PDU_READ; - bl.type = PDULIST_NORMAL; - if (na->random_datain_pdu_offsets) - bl.randomize |= RANDOM_DATAIN_PDU_OFFSETS; - if (na->random_datain_seq_offsets) - bl.randomize |= RANDOM_DATAIN_SEQ_OFFSETS; - } else { - bl.data_direction = ISCSI_PDU_WRITE; - bl.immediate_data_length = immediate_data_length; - if (na->random_r2t_offsets) - bl.randomize |= RANDOM_R2T_OFFSETS; - - if (!cmd->immediate_data && !cmd->unsolicited_data) - bl.type = PDULIST_NORMAL; - else if (cmd->immediate_data && !cmd->unsolicited_data) - bl.type = PDULIST_IMMEDIATE; - else if (!cmd->immediate_data && cmd->unsolicited_data) - bl.type = PDULIST_UNSOLICITED; - else if (cmd->immediate_data && cmd->unsolicited_data) - bl.type = PDULIST_IMMEDIATE_AND_UNSOLICITED; - } - - iscsit_determine_counts_for_list(cmd, &bl, &seq_count, &pdu_count); + iscsit_determine_counts_for_list(cmd, bl, &seq_count, &pdu_count); if (!conn->sess->sess_ops->DataSequenceInOrder) { - seq = kcalloc(seq_count, sizeof(struct iscsi_seq), GFP_ATOMIC); + seq = kzalloc(seq_count * sizeof(struct iscsi_seq), GFP_ATOMIC); if (!seq) { pr_err("Unable to allocate struct iscsi_seq list\n"); - return -ENOMEM; + return -1; } cmd->seq_list = seq; cmd->seq_count = seq_count; } if (!conn->sess->sess_ops->DataPDUInOrder) { - pdu = kcalloc(pdu_count, sizeof(struct iscsi_pdu), GFP_ATOMIC); + pdu = kzalloc(pdu_count * sizeof(struct iscsi_pdu), GFP_ATOMIC); if (!pdu) { pr_err("Unable to allocate struct iscsi_pdu list.\n"); kfree(seq); - return -ENOMEM; + return -1; } cmd->pdu_list = pdu; cmd->pdu_count = pdu_count; } - return iscsit_do_build_pdu_and_seq_lists(cmd, &bl); + return iscsit_build_pdu_and_seq_list(cmd, bl); } struct iscsi_pdu *iscsit_get_pdu_holder( @@ -611,12 +572,13 @@ struct iscsi_pdu *iscsit_get_pdu_holder_for_seq( pdu = &cmd->pdu_list[cmd->pdu_start]; for (i = 0; pdu[i].seq_no != cmd->seq_no; i++) { +#if 0 pr_debug("pdu[i].seq_no: %d, pdu[i].pdu" "_send_order: %d, pdu[i].offset: %d," " pdu[i].length: %d\n", pdu[i].seq_no, pdu[i].pdu_send_order, pdu[i].offset, pdu[i].length); - +#endif if (pdu[i].pdu_send_order == cmd->pdu_send_order) { cmd->pdu_send_order++; return &pdu[i]; @@ -639,11 +601,11 @@ struct iscsi_pdu *iscsit_get_pdu_holder_for_seq( pr_err("struct iscsi_seq is NULL!\n"); return NULL; } - +#if 0 pr_debug("seq->pdu_start: %d, seq->pdu_count: %d," " seq->seq_no: %d\n", seq->pdu_start, seq->pdu_count, seq->seq_no); - +#endif pdu = &cmd->pdu_list[seq->pdu_start]; if (seq->pdu_send_order == seq->pdu_count) { @@ -683,11 +645,12 @@ struct iscsi_seq *iscsit_get_seq_holder( } for (i = 0; i < cmd->seq_count; i++) { +#if 0 pr_debug("seq_list[i].orig_offset: %d, seq_list[i]." "xfer_len: %d, seq_list[i].seq_no %u\n", cmd->seq_list[i].orig_offset, cmd->seq_list[i].xfer_len, cmd->seq_list[i].seq_no); - +#endif if ((cmd->seq_list[i].orig_offset + cmd->seq_list[i].xfer_len) >= (offset + length)) diff --git a/trunk/drivers/target/iscsi/iscsi_target_seq_pdu_list.h b/trunk/drivers/target/iscsi/iscsi_target_seq_pdu_list.h index d5b153751a8d..0d52a10e3069 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_seq_pdu_list.h +++ b/trunk/drivers/target/iscsi/iscsi_target_seq_pdu_list.h @@ -78,7 +78,7 @@ struct iscsi_seq { u32 xfer_len; } ____cacheline_aligned; -extern int iscsit_build_pdu_and_seq_lists(struct iscsi_cmd *, u32); +extern int iscsit_do_build_list(struct iscsi_cmd *, struct iscsi_build_list *); extern struct iscsi_pdu *iscsit_get_pdu_holder(struct iscsi_cmd *, u32, u32); extern struct iscsi_pdu *iscsit_get_pdu_holder_for_seq(struct iscsi_cmd *, struct iscsi_seq *); extern struct iscsi_seq *iscsit_get_seq_holder(struct iscsi_cmd *, u32, u32); diff --git a/trunk/drivers/target/iscsi/iscsi_target_tmr.c b/trunk/drivers/target/iscsi/iscsi_target_tmr.c index f4e640b51fd1..e01da9d2b37e 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_tmr.c +++ b/trunk/drivers/target/iscsi/iscsi_target_tmr.c @@ -78,7 +78,10 @@ int iscsit_tmr_task_warm_reset( { struct iscsi_session *sess = conn->sess; struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess); - +#if 0 + struct iscsi_init_task_mgt_cmnd *hdr = + (struct iscsi_init_task_mgt_cmnd *) buf; +#endif if (!na->tmr_warm_reset) { pr_err("TMR Opcode TARGET_WARM_RESET authorization" " failed for Initiator Node: %s\n", @@ -213,7 +216,7 @@ static int iscsit_task_reassign_complete_nop_out( iscsit_task_reassign_remove_cmd(cmd, cr, conn->sess); spin_lock_bh(&conn->cmd_lock); - list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); + list_add_tail(&cmd->i_list, &conn->conn_cmd_list); spin_unlock_bh(&conn->cmd_lock); cmd->i_state = ISTATE_SEND_NOPIN; @@ -269,9 +272,9 @@ static int iscsit_task_reassign_complete_write( offset = cmd->next_burst_len = cmd->write_data_done; if ((conn->sess->sess_ops->FirstBurstLength - offset) >= - cmd->se_cmd.data_length) { + cmd->data_length) { no_build_r2ts = 1; - length = (cmd->se_cmd.data_length - offset); + length = (cmd->data_length - offset); } else length = (conn->sess->sess_ops->FirstBurstLength - offset); @@ -289,7 +292,7 @@ static int iscsit_task_reassign_complete_write( /* * iscsit_build_r2ts_for_cmd() can handle the rest from here. */ - return iscsit_build_r2ts_for_cmd(cmd, conn, true); + return iscsit_build_r2ts_for_cmd(cmd, conn, 2); } static int iscsit_task_reassign_complete_read( @@ -382,7 +385,7 @@ static int iscsit_task_reassign_complete_scsi_cmnd( iscsit_task_reassign_remove_cmd(cmd, cr, conn->sess); spin_lock_bh(&conn->cmd_lock); - list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); + list_add_tail(&cmd->i_list, &conn->conn_cmd_list); spin_unlock_bh(&conn->cmd_lock); if (se_cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) { diff --git a/trunk/drivers/target/iscsi/iscsi_target_util.c b/trunk/drivers/target/iscsi/iscsi_target_util.c index b42cdeb153df..4eba86d2bd82 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_util.c +++ b/trunk/drivers/target/iscsi/iscsi_target_util.c @@ -163,7 +163,7 @@ struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *conn, gfp_t gfp_mask) } cmd->conn = conn; - INIT_LIST_HEAD(&cmd->i_conn_node); + INIT_LIST_HEAD(&cmd->i_list); INIT_LIST_HEAD(&cmd->datain_list); INIT_LIST_HEAD(&cmd->cmd_r2t_list); init_completion(&cmd->reject_comp); @@ -176,6 +176,174 @@ struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *conn, gfp_t gfp_mask) return cmd; } +/* + * Called from iscsi_handle_scsi_cmd() + */ +struct iscsi_cmd *iscsit_allocate_se_cmd( + struct iscsi_conn *conn, + u32 data_length, + int data_direction, + int iscsi_task_attr) +{ + struct iscsi_cmd *cmd; + struct se_cmd *se_cmd; + int sam_task_attr; + + cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); + if (!cmd) + return NULL; + + cmd->data_direction = data_direction; + cmd->data_length = data_length; + /* + * Figure out the SAM Task Attribute for the incoming SCSI CDB + */ + if ((iscsi_task_attr == ISCSI_ATTR_UNTAGGED) || + (iscsi_task_attr == ISCSI_ATTR_SIMPLE)) + sam_task_attr = MSG_SIMPLE_TAG; + else if (iscsi_task_attr == ISCSI_ATTR_ORDERED) + sam_task_attr = MSG_ORDERED_TAG; + else if (iscsi_task_attr == ISCSI_ATTR_HEAD_OF_QUEUE) + sam_task_attr = MSG_HEAD_TAG; + else if (iscsi_task_attr == ISCSI_ATTR_ACA) + sam_task_attr = MSG_ACA_TAG; + else { + pr_debug("Unknown iSCSI Task Attribute: 0x%02x, using" + " MSG_SIMPLE_TAG\n", iscsi_task_attr); + sam_task_attr = MSG_SIMPLE_TAG; + } + + se_cmd = &cmd->se_cmd; + /* + * Initialize struct se_cmd descriptor from target_core_mod infrastructure + */ + transport_init_se_cmd(se_cmd, &lio_target_fabric_configfs->tf_ops, + conn->sess->se_sess, data_length, data_direction, + sam_task_attr, &cmd->sense_buffer[0]); + return cmd; +} + +struct iscsi_cmd *iscsit_allocate_se_cmd_for_tmr( + struct iscsi_conn *conn, + u8 function) +{ + struct iscsi_cmd *cmd; + struct se_cmd *se_cmd; + int rc; + u8 tcm_function; + + cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); + if (!cmd) + return NULL; + + cmd->data_direction = DMA_NONE; + + cmd->tmr_req = kzalloc(sizeof(struct iscsi_tmr_req), GFP_KERNEL); + if (!cmd->tmr_req) { + pr_err("Unable to allocate memory for" + " Task Management command!\n"); + goto out; + } + /* + * TASK_REASSIGN for ERL=2 / connection stays inside of + * LIO-Target $FABRIC_MOD + */ + if (function == ISCSI_TM_FUNC_TASK_REASSIGN) + return cmd; + + se_cmd = &cmd->se_cmd; + /* + * Initialize struct se_cmd descriptor from target_core_mod infrastructure + */ + transport_init_se_cmd(se_cmd, &lio_target_fabric_configfs->tf_ops, + conn->sess->se_sess, 0, DMA_NONE, + MSG_SIMPLE_TAG, &cmd->sense_buffer[0]); + + switch (function) { + case ISCSI_TM_FUNC_ABORT_TASK: + tcm_function = TMR_ABORT_TASK; + break; + case ISCSI_TM_FUNC_ABORT_TASK_SET: + tcm_function = TMR_ABORT_TASK_SET; + break; + case ISCSI_TM_FUNC_CLEAR_ACA: + tcm_function = TMR_CLEAR_ACA; + break; + case ISCSI_TM_FUNC_CLEAR_TASK_SET: + tcm_function = TMR_CLEAR_TASK_SET; + break; + case ISCSI_TM_FUNC_LOGICAL_UNIT_RESET: + tcm_function = TMR_LUN_RESET; + break; + case ISCSI_TM_FUNC_TARGET_WARM_RESET: + tcm_function = TMR_TARGET_WARM_RESET; + break; + case ISCSI_TM_FUNC_TARGET_COLD_RESET: + tcm_function = TMR_TARGET_COLD_RESET; + break; + default: + pr_err("Unknown iSCSI TMR Function:" + " 0x%02x\n", function); + goto out; + } + + rc = core_tmr_alloc_req(se_cmd, cmd->tmr_req, tcm_function, GFP_KERNEL); + if (rc < 0) + goto out; + + cmd->tmr_req->se_tmr_req = se_cmd->se_tmr_req; + + return cmd; +out: + iscsit_release_cmd(cmd); + return NULL; +} + +int iscsit_decide_list_to_build( + struct iscsi_cmd *cmd, + u32 immediate_data_length) +{ + struct iscsi_build_list bl; + struct iscsi_conn *conn = cmd->conn; + struct iscsi_session *sess = conn->sess; + struct iscsi_node_attrib *na; + + if (sess->sess_ops->DataSequenceInOrder && + sess->sess_ops->DataPDUInOrder) + return 0; + + if (cmd->data_direction == DMA_NONE) + return 0; + + na = iscsit_tpg_get_node_attrib(sess); + memset(&bl, 0, sizeof(struct iscsi_build_list)); + + if (cmd->data_direction == DMA_FROM_DEVICE) { + bl.data_direction = ISCSI_PDU_READ; + bl.type = PDULIST_NORMAL; + if (na->random_datain_pdu_offsets) + bl.randomize |= RANDOM_DATAIN_PDU_OFFSETS; + if (na->random_datain_seq_offsets) + bl.randomize |= RANDOM_DATAIN_SEQ_OFFSETS; + } else { + bl.data_direction = ISCSI_PDU_WRITE; + bl.immediate_data_length = immediate_data_length; + if (na->random_r2t_offsets) + bl.randomize |= RANDOM_R2T_OFFSETS; + + if (!cmd->immediate_data && !cmd->unsolicited_data) + bl.type = PDULIST_NORMAL; + else if (cmd->immediate_data && !cmd->unsolicited_data) + bl.type = PDULIST_IMMEDIATE; + else if (!cmd->immediate_data && cmd->unsolicited_data) + bl.type = PDULIST_UNSOLICITED; + else if (cmd->immediate_data && cmd->unsolicited_data) + bl.type = PDULIST_IMMEDIATE_AND_UNSOLICITED; + } + + return iscsit_do_build_list(cmd, &bl); +} + struct iscsi_seq *iscsit_get_seq_holder_for_datain( struct iscsi_cmd *cmd, u32 seq_send_order) @@ -334,14 +502,14 @@ int iscsit_check_unsolicited_dataout(struct iscsi_cmd *cmd, unsigned char *buf) if (!(hdr->flags & ISCSI_FLAG_CMD_FINAL)) return 0; - if (((cmd->first_burst_len + payload_length) != cmd->se_cmd.data_length) && + if (((cmd->first_burst_len + payload_length) != cmd->data_length) && ((cmd->first_burst_len + payload_length) != conn->sess->sess_ops->FirstBurstLength)) { pr_err("Unsolicited non-immediate data received %u" " does not equal FirstBurstLength: %u, and does" " not equal ExpXferLen %u.\n", (cmd->first_burst_len + payload_length), - conn->sess->sess_ops->FirstBurstLength, cmd->se_cmd.data_length); + conn->sess->sess_ops->FirstBurstLength, cmd->data_length); transport_send_check_condition_and_sense(se_cmd, TCM_INCORRECT_AMOUNT_OF_DATA, 0); return -1; @@ -356,7 +524,7 @@ struct iscsi_cmd *iscsit_find_cmd_from_itt( struct iscsi_cmd *cmd; spin_lock_bh(&conn->cmd_lock); - list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) { + list_for_each_entry(cmd, &conn->conn_cmd_list, i_list) { if (cmd->init_task_tag == init_task_tag) { spin_unlock_bh(&conn->cmd_lock); return cmd; @@ -377,7 +545,7 @@ struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump( struct iscsi_cmd *cmd; spin_lock_bh(&conn->cmd_lock); - list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) { + list_for_each_entry(cmd, &conn->conn_cmd_list, i_list) { if (cmd->init_task_tag == init_task_tag) { spin_unlock_bh(&conn->cmd_lock); return cmd; @@ -400,7 +568,7 @@ struct iscsi_cmd *iscsit_find_cmd_from_ttt( struct iscsi_cmd *cmd = NULL; spin_lock_bh(&conn->cmd_lock); - list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) { + list_for_each_entry(cmd, &conn->conn_cmd_list, i_list) { if (cmd->targ_xfer_tag == targ_xfer_tag) { spin_unlock_bh(&conn->cmd_lock); return cmd; @@ -428,7 +596,7 @@ int iscsit_find_cmd_for_recovery( spin_lock(&sess->cr_i_lock); list_for_each_entry(cr, &sess->cr_inactive_list, cr_list) { spin_lock(&cr->conn_recovery_cmd_lock); - list_for_each_entry(cmd, &cr->conn_recovery_cmd_list, i_conn_node) { + list_for_each_entry(cmd, &cr->conn_recovery_cmd_list, i_list) { if (cmd->init_task_tag == init_task_tag) { spin_unlock(&cr->conn_recovery_cmd_lock); spin_unlock(&sess->cr_i_lock); @@ -448,7 +616,7 @@ int iscsit_find_cmd_for_recovery( spin_lock(&sess->cr_a_lock); list_for_each_entry(cr, &sess->cr_active_list, cr_list) { spin_lock(&cr->conn_recovery_cmd_lock); - list_for_each_entry(cmd, &cr->conn_recovery_cmd_list, i_conn_node) { + list_for_each_entry(cmd, &cr->conn_recovery_cmd_list, i_list) { if (cmd->init_task_tag == init_task_tag) { spin_unlock(&cr->conn_recovery_cmd_lock); spin_unlock(&sess->cr_a_lock); @@ -645,6 +813,7 @@ void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn) void iscsit_release_cmd(struct iscsi_cmd *cmd) { struct iscsi_conn *conn = cmd->conn; + int i; iscsit_free_r2ts_from_list(cmd); iscsit_free_all_datain_reqs(cmd); @@ -655,6 +824,11 @@ void iscsit_release_cmd(struct iscsi_cmd *cmd) kfree(cmd->tmr_req); kfree(cmd->iov_data); + for (i = 0; i < cmd->t_mem_sg_nents; i++) + __free_page(sg_page(&cmd->t_mem_sg[i])); + + kfree(cmd->t_mem_sg); + if (conn) { iscsit_remove_cmd_from_immediate_queue(cmd, conn); iscsit_remove_cmd_from_response_queue(cmd, conn); @@ -864,7 +1038,7 @@ static int iscsit_add_nopin(struct iscsi_conn *conn, int want_response) spin_unlock_bh(&conn->sess->ttt_lock); spin_lock_bh(&conn->cmd_lock); - list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); + list_add_tail(&cmd->i_list, &conn->conn_cmd_list); spin_unlock_bh(&conn->cmd_lock); if (want_response) diff --git a/trunk/drivers/target/iscsi/iscsi_target_util.h b/trunk/drivers/target/iscsi/iscsi_target_util.h index e1c729b8a1c5..835bf7de0281 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_util.h +++ b/trunk/drivers/target/iscsi/iscsi_target_util.h @@ -9,6 +9,9 @@ extern struct iscsi_r2t *iscsit_get_r2t_from_list(struct iscsi_cmd *); extern void iscsit_free_r2t(struct iscsi_r2t *, struct iscsi_cmd *); extern void iscsit_free_r2ts_from_list(struct iscsi_cmd *); extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, gfp_t); +extern struct iscsi_cmd *iscsit_allocate_se_cmd(struct iscsi_conn *, u32, int, int); +extern struct iscsi_cmd *iscsit_allocate_se_cmd_for_tmr(struct iscsi_conn *, u8); +extern int iscsit_decide_list_to_build(struct iscsi_cmd *, u32); extern struct iscsi_seq *iscsit_get_seq_holder_for_datain(struct iscsi_cmd *, u32); extern struct iscsi_seq *iscsit_get_seq_holder_for_r2t(struct iscsi_cmd *); extern struct iscsi_r2t *iscsit_get_holder_for_r2tsn(struct iscsi_cmd *, u32); diff --git a/trunk/drivers/target/loopback/tcm_loop.c b/trunk/drivers/target/loopback/tcm_loop.c index 38dfac2b0a1c..a9b4eeefe9fc 100644 --- a/trunk/drivers/target/loopback/tcm_loop.c +++ b/trunk/drivers/target/loopback/tcm_loop.c @@ -213,7 +213,7 @@ static void tcm_loop_submission_work(struct work_struct *work) * associated read buffers, go ahead and do that here for type * SCF_SCSI_CONTROL_SG_IO_CDB. Also note that this is currently * guaranteed to be a single SGL for SCF_SCSI_CONTROL_SG_IO_CDB - * by target core in target_setup_cmd_from_cdb() -> + * by target core in transport_generic_allocate_tasks() -> * transport_generic_cmd_sequencer(). */ if (se_cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB && @@ -227,7 +227,7 @@ static void tcm_loop_submission_work(struct work_struct *work) } } - ret = target_setup_cmd_from_cdb(se_cmd, sc->cmnd); + ret = transport_generic_allocate_tasks(se_cmd, sc->cmnd); if (ret == -ENOMEM) { transport_send_check_condition_and_sense(se_cmd, TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); diff --git a/trunk/drivers/target/target_core_alua.c b/trunk/drivers/target/target_core_alua.c index e624b836469c..c7746a3339d4 100644 --- a/trunk/drivers/target/target_core_alua.c +++ b/trunk/drivers/target/target_core_alua.c @@ -59,31 +59,26 @@ struct t10_alua_lu_gp *default_lu_gp; * * See spc4r17 section 6.27 */ -int target_emulate_report_target_port_groups(struct se_cmd *cmd) +int target_emulate_report_target_port_groups(struct se_task *task) { + struct se_cmd *cmd = task->task_se_cmd; struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev; struct se_port *port; struct t10_alua_tg_pt_gp *tg_pt_gp; struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; unsigned char *buf; - u32 rd_len = 0, off; - int ext_hdr = (cmd->t_task_cdb[1] & 0x20); + u32 rd_len = 0, off = 4; /* Skip over RESERVED area to first + Target port group descriptor */ /* - * Skip over RESERVED area to first Target port group descriptor - * depending on the PARAMETER DATA FORMAT type.. + * Need at least 4 bytes of response data or else we can't + * even fit the return data length. */ - if (ext_hdr != 0) - off = 8; - else - off = 4; - - if (cmd->data_length < off) { - pr_warn("REPORT TARGET PORT GROUPS allocation length %u too" - " small for %s header\n", cmd->data_length, - (ext_hdr) ? "extended" : "normal"); - cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; + if (cmd->data_length < 4) { + pr_warn("REPORT TARGET PORT GROUPS allocation length %u" + " too small\n", cmd->data_length); return -EINVAL; } + buf = transport_kmap_data_sg(cmd); spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); @@ -164,34 +159,15 @@ int target_emulate_report_target_port_groups(struct se_cmd *cmd) /* * Set the RETURN DATA LENGTH set in the header of the DataIN Payload */ - put_unaligned_be32(rd_len, &buf[0]); + buf[0] = ((rd_len >> 24) & 0xff); + buf[1] = ((rd_len >> 16) & 0xff); + buf[2] = ((rd_len >> 8) & 0xff); + buf[3] = (rd_len & 0xff); - /* - * Fill in the Extended header parameter data format if requested - */ - if (ext_hdr != 0) { - buf[4] = 0x10; - /* - * Set the implict transition time (in seconds) for the application - * client to use as a base for it's transition timeout value. - * - * Use the current tg_pt_gp_mem -> tg_pt_gp membership from the LUN - * this CDB was received upon to determine this value individually - * for ALUA target port group. - */ - port = cmd->se_lun->lun_sep; - tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; - if (tg_pt_gp_mem) { - spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); - tg_pt_gp = tg_pt_gp_mem->tg_pt_gp; - if (tg_pt_gp) - buf[5] = tg_pt_gp->tg_pt_gp_implict_trans_secs; - spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); - } - } transport_kunmap_data_sg(cmd); - target_complete_cmd(cmd, GOOD); + task->task_scsi_status = GOOD; + transport_complete_task(task, 1); return 0; } @@ -200,8 +176,9 @@ int target_emulate_report_target_port_groups(struct se_cmd *cmd) * * See spc4r17 section 6.35 */ -int target_emulate_set_target_port_groups(struct se_cmd *cmd) +int target_emulate_set_target_port_groups(struct se_task *task) { + struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; struct se_subsystem_dev *su_dev = dev->se_sub_dev; struct se_port *port, *l_port = cmd->se_lun->lun_sep; @@ -374,7 +351,8 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) out: transport_kunmap_data_sg(cmd); - target_complete_cmd(cmd, GOOD); + task->task_scsi_status = GOOD; + transport_complete_task(task, 1); return 0; } @@ -413,7 +391,7 @@ static inline int core_alua_state_standby( case RECEIVE_DIAGNOSTIC: case SEND_DIAGNOSTIC: case MAINTENANCE_IN: - switch (cdb[1] & 0x1f) { + switch (cdb[1]) { case MI_REPORT_TARGET_PGS: return 0; default: @@ -455,7 +433,7 @@ static inline int core_alua_state_unavailable( case INQUIRY: case REPORT_LUNS: case MAINTENANCE_IN: - switch (cdb[1] & 0x1f) { + switch (cdb[1]) { case MI_REPORT_TARGET_PGS: return 0; default: @@ -495,7 +473,7 @@ static inline int core_alua_state_transition( case INQUIRY: case REPORT_LUNS: case MAINTENANCE_IN: - switch (cdb[1] & 0x1f) { + switch (cdb[1]) { case MI_REPORT_TARGET_PGS: return 0; default: @@ -1381,7 +1359,6 @@ struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp( */ tg_pt_gp->tg_pt_gp_nonop_delay_msecs = ALUA_DEFAULT_NONOP_DELAY_MSECS; tg_pt_gp->tg_pt_gp_trans_delay_msecs = ALUA_DEFAULT_TRANS_DELAY_MSECS; - tg_pt_gp->tg_pt_gp_implict_trans_secs = ALUA_DEFAULT_IMPLICT_TRANS_SECS; if (def_group) { spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); @@ -1878,37 +1855,6 @@ ssize_t core_alua_store_trans_delay_msecs( return count; } -ssize_t core_alua_show_implict_trans_secs( - struct t10_alua_tg_pt_gp *tg_pt_gp, - char *page) -{ - return sprintf(page, "%d\n", tg_pt_gp->tg_pt_gp_implict_trans_secs); -} - -ssize_t core_alua_store_implict_trans_secs( - struct t10_alua_tg_pt_gp *tg_pt_gp, - const char *page, - size_t count) -{ - unsigned long tmp; - int ret; - - ret = strict_strtoul(page, 0, &tmp); - if (ret < 0) { - pr_err("Unable to extract implict_trans_secs\n"); - return -EINVAL; - } - if (tmp > ALUA_MAX_IMPLICT_TRANS_SECS) { - pr_err("Passed implict_trans_secs: %lu, exceeds" - " ALUA_MAX_IMPLICT_TRANS_SECS: %d\n", tmp, - ALUA_MAX_IMPLICT_TRANS_SECS); - return -EINVAL; - } - tg_pt_gp->tg_pt_gp_implict_trans_secs = (int)tmp; - - return count; -} - ssize_t core_alua_show_preferred_bit( struct t10_alua_tg_pt_gp *tg_pt_gp, char *page) diff --git a/trunk/drivers/target/target_core_alua.h b/trunk/drivers/target/target_core_alua.h index f920c170d47b..c5b4ecd3e745 100644 --- a/trunk/drivers/target/target_core_alua.h +++ b/trunk/drivers/target/target_core_alua.h @@ -51,12 +51,6 @@ */ #define ALUA_DEFAULT_TRANS_DELAY_MSECS 0 #define ALUA_MAX_TRANS_DELAY_MSECS 30000 /* 30 seconds */ -/* - * Used for the recommended application client implict transition timeout - * in seconds, returned by the REPORT_TARGET_PORT_GROUPS w/ extended header. - */ -#define ALUA_DEFAULT_IMPLICT_TRANS_SECS 0 -#define ALUA_MAX_IMPLICT_TRANS_SECS 255 /* * Used by core_alua_update_tpg_primary_metadata() and * core_alua_update_tpg_secondary_metadata() @@ -72,8 +66,8 @@ extern struct kmem_cache *t10_alua_lu_gp_mem_cache; extern struct kmem_cache *t10_alua_tg_pt_gp_cache; extern struct kmem_cache *t10_alua_tg_pt_gp_mem_cache; -extern int target_emulate_report_target_port_groups(struct se_cmd *); -extern int target_emulate_set_target_port_groups(struct se_cmd *); +extern int target_emulate_report_target_port_groups(struct se_task *); +extern int target_emulate_set_target_port_groups(struct se_task *); extern int core_alua_check_nonop_delay(struct se_cmd *); extern int core_alua_do_port_transition(struct t10_alua_tg_pt_gp *, struct se_device *, struct se_port *, @@ -113,10 +107,6 @@ extern ssize_t core_alua_show_trans_delay_msecs(struct t10_alua_tg_pt_gp *, char *); extern ssize_t core_alua_store_trans_delay_msecs(struct t10_alua_tg_pt_gp *, const char *, size_t); -extern ssize_t core_alua_show_implict_trans_secs(struct t10_alua_tg_pt_gp *, - char *); -extern ssize_t core_alua_store_implict_trans_secs(struct t10_alua_tg_pt_gp *, - const char *, size_t); extern ssize_t core_alua_show_preferred_bit(struct t10_alua_tg_pt_gp *, char *); extern ssize_t core_alua_store_preferred_bit(struct t10_alua_tg_pt_gp *, diff --git a/trunk/drivers/target/target_core_cdb.c b/trunk/drivers/target/target_core_cdb.c index 9888693a18fe..30a67707036f 100644 --- a/trunk/drivers/target/target_core_cdb.c +++ b/trunk/drivers/target/target_core_cdb.c @@ -432,7 +432,6 @@ static int target_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) { struct se_device *dev = cmd->se_dev; - u32 max_sectors; int have_tp = 0; /* @@ -457,9 +456,7 @@ target_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) /* * Set MAXIMUM TRANSFER LENGTH */ - max_sectors = min(dev->se_sub_dev->se_dev_attrib.fabric_max_sectors, - dev->se_sub_dev->se_dev_attrib.hw_max_sectors); - put_unaligned_be32(max_sectors, &buf[8]); + put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.fabric_max_sectors, &buf[8]); /* * Set OPTIMAL TRANSFER LENGTH @@ -601,8 +598,9 @@ target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) return 0; } -int target_emulate_inquiry(struct se_cmd *cmd) +int target_emulate_inquiry(struct se_task *task) { + struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; struct se_portal_group *tpg = cmd->se_lun->lun_sep->sep_tpg; unsigned char *buf, *map_buf; @@ -666,13 +664,16 @@ int target_emulate_inquiry(struct se_cmd *cmd) } transport_kunmap_data_sg(cmd); - if (!ret) - target_complete_cmd(cmd, GOOD); + if (!ret) { + task->task_scsi_status = GOOD; + transport_complete_task(task, 1); + } return ret; } -int target_emulate_readcapacity(struct se_cmd *cmd) +int target_emulate_readcapacity(struct se_task *task) { + struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; unsigned char *buf; unsigned long long blocks_long = dev->transport->get_blocks(dev); @@ -696,12 +697,14 @@ int target_emulate_readcapacity(struct se_cmd *cmd) transport_kunmap_data_sg(cmd); - target_complete_cmd(cmd, GOOD); + task->task_scsi_status = GOOD; + transport_complete_task(task, 1); return 0; } -int target_emulate_readcapacity_16(struct se_cmd *cmd) +int target_emulate_readcapacity_16(struct se_task *task) { + struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; unsigned char *buf; unsigned long long blocks = dev->transport->get_blocks(dev); @@ -729,7 +732,8 @@ int target_emulate_readcapacity_16(struct se_cmd *cmd) transport_kunmap_data_sg(cmd); - target_complete_cmd(cmd, GOOD); + task->task_scsi_status = GOOD; + transport_complete_task(task, 1); return 0; } @@ -868,8 +872,9 @@ target_modesense_dpofua(unsigned char *buf, int type) } } -int target_emulate_modesense(struct se_cmd *cmd) +int target_emulate_modesense(struct se_task *task) { + struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; char *cdb = cmd->t_task_cdb; unsigned char *rbuf; @@ -942,12 +947,14 @@ int target_emulate_modesense(struct se_cmd *cmd) memcpy(rbuf, buf, offset); transport_kunmap_data_sg(cmd); - target_complete_cmd(cmd, GOOD); + task->task_scsi_status = GOOD; + transport_complete_task(task, 1); return 0; } -int target_emulate_request_sense(struct se_cmd *cmd) +int target_emulate_request_sense(struct se_task *task) { + struct se_cmd *cmd = task->task_se_cmd; unsigned char *cdb = cmd->t_task_cdb; unsigned char *buf; u8 ua_asc = 0, ua_ascq = 0; @@ -1001,7 +1008,8 @@ int target_emulate_request_sense(struct se_cmd *cmd) end: transport_kunmap_data_sg(cmd); - target_complete_cmd(cmd, GOOD); + task->task_scsi_status = GOOD; + transport_complete_task(task, 1); return 0; } @@ -1009,8 +1017,9 @@ int target_emulate_request_sense(struct se_cmd *cmd) * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support. * Note this is not used for TCM/pSCSI passthrough */ -int target_emulate_unmap(struct se_cmd *cmd) +int target_emulate_unmap(struct se_task *task) { + struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; unsigned char *buf, *ptr = NULL; unsigned char *cdb = &cmd->t_task_cdb[0]; @@ -1057,8 +1066,10 @@ int target_emulate_unmap(struct se_cmd *cmd) err: transport_kunmap_data_sg(cmd); - if (!ret) - target_complete_cmd(cmd, GOOD); + if (!ret) { + task->task_scsi_status = GOOD; + transport_complete_task(task, 1); + } return ret; } @@ -1066,8 +1077,9 @@ int target_emulate_unmap(struct se_cmd *cmd) * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support. * Note this is not used for TCM/pSCSI passthrough */ -int target_emulate_write_same(struct se_cmd *cmd) +int target_emulate_write_same(struct se_task *task) { + struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; sector_t range; sector_t lba = cmd->t_task_lba; @@ -1106,25 +1118,79 @@ int target_emulate_write_same(struct se_cmd *cmd) return ret; } - target_complete_cmd(cmd, GOOD); + task->task_scsi_status = GOOD; + transport_complete_task(task, 1); return 0; } -int target_emulate_synchronize_cache(struct se_cmd *cmd) +int target_emulate_synchronize_cache(struct se_task *task) { - if (!cmd->se_dev->transport->do_sync_cache) { + struct se_device *dev = task->task_se_cmd->se_dev; + struct se_cmd *cmd = task->task_se_cmd; + + if (!dev->transport->do_sync_cache) { pr_err("SYNCHRONIZE_CACHE emulation not supported" - " for: %s\n", cmd->se_dev->transport->name); + " for: %s\n", dev->transport->name); cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; return -ENOSYS; } - cmd->se_dev->transport->do_sync_cache(cmd); + dev->transport->do_sync_cache(task); return 0; } -int target_emulate_noop(struct se_cmd *cmd) +int target_emulate_noop(struct se_task *task) { - target_complete_cmd(cmd, GOOD); + task->task_scsi_status = GOOD; + transport_complete_task(task, 1); return 0; } + +/* + * Write a CDB into @cdb that is based on the one the intiator sent us, + * but updated to only cover the sectors that the current task handles. + */ +void target_get_task_cdb(struct se_task *task, unsigned char *cdb) +{ + struct se_cmd *cmd = task->task_se_cmd; + unsigned int cdb_len = scsi_command_size(cmd->t_task_cdb); + + memcpy(cdb, cmd->t_task_cdb, cdb_len); + if (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) { + unsigned long long lba = task->task_lba; + u32 sectors = task->task_sectors; + + switch (cdb_len) { + case 6: + /* 21-bit LBA and 8-bit sectors */ + cdb[1] = (lba >> 16) & 0x1f; + cdb[2] = (lba >> 8) & 0xff; + cdb[3] = lba & 0xff; + cdb[4] = sectors & 0xff; + break; + case 10: + /* 32-bit LBA and 16-bit sectors */ + put_unaligned_be32(lba, &cdb[2]); + put_unaligned_be16(sectors, &cdb[7]); + break; + case 12: + /* 32-bit LBA and 32-bit sectors */ + put_unaligned_be32(lba, &cdb[2]); + put_unaligned_be32(sectors, &cdb[6]); + break; + case 16: + /* 64-bit LBA and 32-bit sectors */ + put_unaligned_be64(lba, &cdb[2]); + put_unaligned_be32(sectors, &cdb[10]); + break; + case 32: + /* 64-bit LBA and 32-bit sectors, extended CDB */ + put_unaligned_be64(lba, &cdb[12]); + put_unaligned_be32(sectors, &cdb[28]); + break; + default: + BUG(); + } + } +} +EXPORT_SYMBOL(target_get_task_cdb); diff --git a/trunk/drivers/target/target_core_configfs.c b/trunk/drivers/target/target_core_configfs.c index 801efa892046..cbb66537d230 100644 --- a/trunk/drivers/target/target_core_configfs.c +++ b/trunk/drivers/target/target_core_configfs.c @@ -683,6 +683,9 @@ SE_DEV_ATTR(block_size, S_IRUGO | S_IWUSR); DEF_DEV_ATTRIB_RO(hw_max_sectors); SE_DEV_ATTR_RO(hw_max_sectors); +DEF_DEV_ATTRIB(max_sectors); +SE_DEV_ATTR(max_sectors, S_IRUGO | S_IWUSR); + DEF_DEV_ATTRIB(fabric_max_sectors); SE_DEV_ATTR(fabric_max_sectors, S_IRUGO | S_IWUSR); @@ -724,6 +727,7 @@ static struct configfs_attribute *target_core_dev_attrib_attrs[] = { &target_core_dev_attrib_hw_block_size.attr, &target_core_dev_attrib_block_size.attr, &target_core_dev_attrib_hw_max_sectors.attr, + &target_core_dev_attrib_max_sectors.attr, &target_core_dev_attrib_fabric_max_sectors.attr, &target_core_dev_attrib_optimal_sectors.attr, &target_core_dev_attrib_hw_queue_depth.attr, @@ -2446,26 +2450,6 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_trans_delay_msecs( SE_DEV_ALUA_TG_PT_ATTR(trans_delay_msecs, S_IRUGO | S_IWUSR); -/* - * implict_trans_secs - */ -static ssize_t target_core_alua_tg_pt_gp_show_attr_implict_trans_secs( - struct t10_alua_tg_pt_gp *tg_pt_gp, - char *page) -{ - return core_alua_show_implict_trans_secs(tg_pt_gp, page); -} - -static ssize_t target_core_alua_tg_pt_gp_store_attr_implict_trans_secs( - struct t10_alua_tg_pt_gp *tg_pt_gp, - const char *page, - size_t count) -{ - return core_alua_store_implict_trans_secs(tg_pt_gp, page, count); -} - -SE_DEV_ALUA_TG_PT_ATTR(implict_trans_secs, S_IRUGO | S_IWUSR); - /* * preferred */ @@ -2590,7 +2574,6 @@ static struct configfs_attribute *target_core_alua_tg_pt_gp_attrs[] = { &target_core_alua_tg_pt_gp_alua_write_metadata.attr, &target_core_alua_tg_pt_gp_nonop_delay_msecs.attr, &target_core_alua_tg_pt_gp_trans_delay_msecs.attr, - &target_core_alua_tg_pt_gp_implict_trans_secs.attr, &target_core_alua_tg_pt_gp_preferred.attr, &target_core_alua_tg_pt_gp_tg_pt_gp_id.attr, &target_core_alua_tg_pt_gp_members.attr, diff --git a/trunk/drivers/target/target_core_device.c b/trunk/drivers/target/target_core_device.c index 5ad972856a8d..aa6267746383 100644 --- a/trunk/drivers/target/target_core_device.c +++ b/trunk/drivers/target/target_core_device.c @@ -643,8 +643,9 @@ void core_dev_unexport( lun->lun_se_dev = NULL; } -int target_report_luns(struct se_cmd *se_cmd) +int target_report_luns(struct se_task *se_task) { + struct se_cmd *se_cmd = se_task->task_se_cmd; struct se_dev_entry *deve; struct se_session *se_sess = se_cmd->se_sess; unsigned char *buf; @@ -695,7 +696,8 @@ int target_report_luns(struct se_cmd *se_cmd) buf[3] = (lun_count & 0xff); transport_kunmap_data_sg(se_cmd); - target_complete_cmd(se_cmd, GOOD); + se_task->task_scsi_status = GOOD; + transport_complete_task(se_task, 1); return 0; } @@ -876,12 +878,15 @@ void se_dev_set_default_attribs( dev->se_sub_dev->se_dev_attrib.hw_block_size = limits->logical_block_size; dev->se_sub_dev->se_dev_attrib.block_size = limits->logical_block_size; /* - * Align max_hw_sectors down to PAGE_SIZE I/O transfers + * max_sectors is based on subsystem plugin dependent requirements. */ - limits->max_hw_sectors = se_dev_align_max_sectors(limits->max_hw_sectors, - limits->logical_block_size); dev->se_sub_dev->se_dev_attrib.hw_max_sectors = limits->max_hw_sectors; - + /* + * Align max_sectors down to PAGE_SIZE to follow transport_allocate_data_tasks() + */ + limits->max_sectors = se_dev_align_max_sectors(limits->max_sectors, + limits->logical_block_size); + dev->se_sub_dev->se_dev_attrib.max_sectors = limits->max_sectors; /* * Set fabric_max_sectors, which is reported in block limits * VPD page (B0h). @@ -1165,6 +1170,64 @@ int se_dev_set_queue_depth(struct se_device *dev, u32 queue_depth) return 0; } +int se_dev_set_max_sectors(struct se_device *dev, u32 max_sectors) +{ + int force = 0; /* Force setting for VDEVS */ + + if (atomic_read(&dev->dev_export_obj.obj_access_count)) { + pr_err("dev[%p]: Unable to change SE Device" + " max_sectors while dev_export_obj: %d count exists\n", + dev, atomic_read(&dev->dev_export_obj.obj_access_count)); + return -EINVAL; + } + if (!max_sectors) { + pr_err("dev[%p]: Illegal ZERO value for" + " max_sectors\n", dev); + return -EINVAL; + } + if (max_sectors < DA_STATUS_MAX_SECTORS_MIN) { + pr_err("dev[%p]: Passed max_sectors: %u less than" + " DA_STATUS_MAX_SECTORS_MIN: %u\n", dev, max_sectors, + DA_STATUS_MAX_SECTORS_MIN); + return -EINVAL; + } + if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { + if (max_sectors > dev->se_sub_dev->se_dev_attrib.hw_max_sectors) { + pr_err("dev[%p]: Passed max_sectors: %u" + " greater than TCM/SE_Device max_sectors:" + " %u\n", dev, max_sectors, + dev->se_sub_dev->se_dev_attrib.hw_max_sectors); + return -EINVAL; + } + } else { + if (!force && (max_sectors > + dev->se_sub_dev->se_dev_attrib.hw_max_sectors)) { + pr_err("dev[%p]: Passed max_sectors: %u" + " greater than TCM/SE_Device max_sectors" + ": %u, use force=1 to override.\n", dev, + max_sectors, dev->se_sub_dev->se_dev_attrib.hw_max_sectors); + return -EINVAL; + } + if (max_sectors > DA_STATUS_MAX_SECTORS_MAX) { + pr_err("dev[%p]: Passed max_sectors: %u" + " greater than DA_STATUS_MAX_SECTORS_MAX:" + " %u\n", dev, max_sectors, + DA_STATUS_MAX_SECTORS_MAX); + return -EINVAL; + } + } + /* + * Align max_sectors down to PAGE_SIZE to follow transport_allocate_data_tasks() + */ + max_sectors = se_dev_align_max_sectors(max_sectors, + dev->se_sub_dev->se_dev_attrib.block_size); + + dev->se_sub_dev->se_dev_attrib.max_sectors = max_sectors; + pr_debug("dev[%p]: SE Device max_sectors changed to %u\n", + dev, max_sectors); + return 0; +} + int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors) { if (atomic_read(&dev->dev_export_obj.obj_access_count)) { @@ -1278,6 +1341,7 @@ struct se_lun *core_dev_add_lun( u32 lun) { struct se_lun *lun_p; + u32 lun_access = 0; int rc; if (atomic_read(&dev->dev_access_obj.obj_access_count) != 0) { @@ -1290,8 +1354,12 @@ struct se_lun *core_dev_add_lun( if (IS_ERR(lun_p)) return lun_p; - rc = core_tpg_post_addlun(tpg, lun_p, - TRANSPORT_LUNFLAGS_READ_WRITE, dev); + if (dev->dev_flags & DF_READ_ONLY) + lun_access = TRANSPORT_LUNFLAGS_READ_ONLY; + else + lun_access = TRANSPORT_LUNFLAGS_READ_WRITE; + + rc = core_tpg_post_addlun(tpg, lun_p, lun_access, dev); if (rc < 0) return ERR_PTR(rc); diff --git a/trunk/drivers/target/target_core_file.c b/trunk/drivers/target/target_core_file.c index 686dba189f8e..7ed58e2df791 100644 --- a/trunk/drivers/target/target_core_file.c +++ b/trunk/drivers/target/target_core_file.c @@ -133,10 +133,15 @@ static struct se_device *fd_create_virtdevice( ret = PTR_ERR(dev_p); goto fail; } - - /* O_DIRECT too? */ +#if 0 + if (di->no_create_file) + flags = O_RDWR | O_LARGEFILE; + else + flags = O_RDWR | O_CREAT | O_LARGEFILE; +#else flags = O_RDWR | O_CREAT | O_LARGEFILE; - +#endif +/* flags |= O_DIRECT; */ /* * If fd_buffered_io=1 has not been set explicitly (the default), * use O_SYNC to force FILEIO writes to disk. @@ -164,7 +169,6 @@ static struct se_device *fd_create_virtdevice( inode = file->f_mapping->host; if (S_ISBLK(inode->i_mode)) { struct request_queue *q; - unsigned long long dev_size; /* * Setup the local scope queue_limits from struct request_queue->limits * to pass into transport_add_device_to_core_hba() as struct se_dev_limits. @@ -179,12 +183,13 @@ static struct se_device *fd_create_virtdevice( * one (1) logical sector from underlying struct block_device */ fd_dev->fd_block_size = bdev_logical_block_size(inode->i_bdev); - dev_size = (i_size_read(file->f_mapping->host) - + fd_dev->fd_dev_size = (i_size_read(file->f_mapping->host) - fd_dev->fd_block_size); pr_debug("FILEIO: Using size: %llu bytes from struct" " block_device blocks: %llu logical_block_size: %d\n", - dev_size, div_u64(dev_size, fd_dev->fd_block_size), + fd_dev->fd_dev_size, + div_u64(fd_dev->fd_dev_size, fd_dev->fd_block_size), fd_dev->fd_block_size); } else { if (!(fd_dev->fbd_flags & FBDF_HAS_SIZE)) { @@ -244,33 +249,53 @@ static void fd_free_device(void *p) kfree(fd_dev); } -static int fd_do_readv(struct se_cmd *cmd, struct scatterlist *sgl, - u32 sgl_nents) +static inline struct fd_request *FILE_REQ(struct se_task *task) { - struct se_device *se_dev = cmd->se_dev; + return container_of(task, struct fd_request, fd_task); +} + + +static struct se_task * +fd_alloc_task(unsigned char *cdb) +{ + struct fd_request *fd_req; + + fd_req = kzalloc(sizeof(struct fd_request), GFP_KERNEL); + if (!fd_req) { + pr_err("Unable to allocate struct fd_request\n"); + return NULL; + } + + return &fd_req->fd_task; +} + +static int fd_do_readv(struct se_task *task) +{ + struct fd_request *req = FILE_REQ(task); + struct se_device *se_dev = req->fd_task.task_se_cmd->se_dev; struct fd_dev *dev = se_dev->dev_ptr; struct file *fd = dev->fd_file; - struct scatterlist *sg; + struct scatterlist *sg = task->task_sg; struct iovec *iov; mm_segment_t old_fs; - loff_t pos = (cmd->t_task_lba * + loff_t pos = (task->task_lba * se_dev->se_sub_dev->se_dev_attrib.block_size); int ret = 0, i; - iov = kzalloc(sizeof(struct iovec) * sgl_nents, GFP_KERNEL); + iov = kzalloc(sizeof(struct iovec) * task->task_sg_nents, GFP_KERNEL); if (!iov) { pr_err("Unable to allocate fd_do_readv iov[]\n"); return -ENOMEM; } - for_each_sg(sgl, sg, sgl_nents, i) { + for_each_sg(task->task_sg, sg, task->task_sg_nents, i) { iov[i].iov_len = sg->length; iov[i].iov_base = sg_virt(sg); } old_fs = get_fs(); set_fs(get_ds()); - ret = vfs_readv(fd, &iov[0], sgl_nents, &pos); + ret = vfs_readv(fd, &iov[0], task->task_sg_nents, &pos); set_fs(old_fs); kfree(iov); @@ -280,10 +305,10 @@ static int fd_do_readv(struct se_cmd *cmd, struct scatterlist *sgl, * block_device. */ if (S_ISBLK(fd->f_dentry->d_inode->i_mode)) { - if (ret < 0 || ret != cmd->data_length) { + if (ret < 0 || ret != task->task_size) { pr_err("vfs_readv() returned %d," " expecting %d for S_ISBLK\n", ret, - (int)cmd->data_length); + (int)task->task_size); return (ret < 0 ? ret : -EINVAL); } } else { @@ -297,38 +322,38 @@ static int fd_do_readv(struct se_cmd *cmd, struct scatterlist *sgl, return 1; } -static int fd_do_writev(struct se_cmd *cmd, struct scatterlist *sgl, - u32 sgl_nents) +static int fd_do_writev(struct se_task *task) { - struct se_device *se_dev = cmd->se_dev; + struct fd_request *req = FILE_REQ(task); + struct se_device *se_dev = req->fd_task.task_se_cmd->se_dev; struct fd_dev *dev = se_dev->dev_ptr; struct file *fd = dev->fd_file; - struct scatterlist *sg; + struct scatterlist *sg = task->task_sg; struct iovec *iov; mm_segment_t old_fs; - loff_t pos = (cmd->t_task_lba * + loff_t pos = (task->task_lba * se_dev->se_sub_dev->se_dev_attrib.block_size); int ret, i = 0; - iov = kzalloc(sizeof(struct iovec) * sgl_nents, GFP_KERNEL); + iov = kzalloc(sizeof(struct iovec) * task->task_sg_nents, GFP_KERNEL); if (!iov) { pr_err("Unable to allocate fd_do_writev iov[]\n"); return -ENOMEM; } - for_each_sg(sgl, sg, sgl_nents, i) { + for_each_sg(task->task_sg, sg, task->task_sg_nents, i) { iov[i].iov_len = sg->length; iov[i].iov_base = sg_virt(sg); } old_fs = get_fs(); set_fs(get_ds()); - ret = vfs_writev(fd, &iov[0], sgl_nents, &pos); + ret = vfs_writev(fd, &iov[0], task->task_sg_nents, &pos); set_fs(old_fs); kfree(iov); - if (ret < 0 || ret != cmd->data_length) { + if (ret < 0 || ret != task->task_size) { pr_err("vfs_writev() returned %d\n", ret); return (ret < 0 ? ret : -EINVAL); } @@ -336,8 +361,9 @@ static int fd_do_writev(struct se_cmd *cmd, struct scatterlist *sgl, return 1; } -static void fd_emulate_sync_cache(struct se_cmd *cmd) +static void fd_emulate_sync_cache(struct se_task *task) { + struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; struct fd_dev *fd_dev = dev->dev_ptr; int immed = (cmd->t_task_cdb[1] & 0x2); @@ -349,7 +375,7 @@ static void fd_emulate_sync_cache(struct se_cmd *cmd) * for this SYNCHRONIZE_CACHE op */ if (immed) - target_complete_cmd(cmd, SAM_STAT_GOOD); + transport_complete_sync_cache(cmd, 1); /* * Determine if we will be flushing the entire device. @@ -369,37 +395,33 @@ static void fd_emulate_sync_cache(struct se_cmd *cmd) if (ret != 0) pr_err("FILEIO: vfs_fsync_range() failed: %d\n", ret); - if (immed) - return; - - if (ret) { - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION); - } else { - target_complete_cmd(cmd, SAM_STAT_GOOD); - } + if (!immed) + transport_complete_sync_cache(cmd, ret == 0); } -static void fd_emulate_write_fua(struct se_cmd *cmd) +/* + * WRITE Force Unit Access (FUA) emulation on a per struct se_task + * LBA range basis.. + */ +static void fd_emulate_write_fua(struct se_cmd *cmd, struct se_task *task) { struct se_device *dev = cmd->se_dev; struct fd_dev *fd_dev = dev->dev_ptr; - loff_t start = cmd->t_task_lba * - dev->se_sub_dev->se_dev_attrib.block_size; - loff_t end = start + cmd->data_length; + loff_t start = task->task_lba * dev->se_sub_dev->se_dev_attrib.block_size; + loff_t end = start + task->task_size; int ret; pr_debug("FILEIO: FUA WRITE LBA: %llu, bytes: %u\n", - cmd->t_task_lba, cmd->data_length); + task->task_lba, task->task_size); ret = vfs_fsync_range(fd_dev->fd_file, start, end, 1); if (ret != 0) pr_err("FILEIO: vfs_fsync_range() failed: %d\n", ret); } -static int fd_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl, - u32 sgl_nents, enum dma_data_direction data_direction) +static int fd_do_task(struct se_task *task) { + struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; int ret = 0; @@ -407,10 +429,10 @@ static int fd_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl, * Call vectorized fileio functions to map struct scatterlist * physical memory addresses to struct iovec virtual memory. */ - if (data_direction == DMA_FROM_DEVICE) { - ret = fd_do_readv(cmd, sgl, sgl_nents); + if (task->task_data_direction == DMA_FROM_DEVICE) { + ret = fd_do_readv(task); } else { - ret = fd_do_writev(cmd, sgl, sgl_nents); + ret = fd_do_writev(task); if (ret > 0 && dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0 && @@ -421,7 +443,7 @@ static int fd_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl, * and return some sense data to let the initiator * know the FUA WRITE cache sync failed..? */ - fd_emulate_write_fua(cmd); + fd_emulate_write_fua(cmd, task); } } @@ -430,11 +452,24 @@ static int fd_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl, cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; return ret; } - if (ret) - target_complete_cmd(cmd, SAM_STAT_GOOD); + if (ret) { + task->task_scsi_status = GOOD; + transport_complete_task(task, 1); + } return 0; } +/* fd_free_task(): (Part of se_subsystem_api_t template) + * + * + */ +static void fd_free_task(struct se_task *task) +{ + struct fd_request *req = FILE_REQ(task); + + kfree(req); +} + enum { Opt_fd_dev_name, Opt_fd_dev_size, Opt_fd_buffered_io, Opt_err }; @@ -570,20 +605,10 @@ static u32 fd_get_device_type(struct se_device *dev) static sector_t fd_get_blocks(struct se_device *dev) { struct fd_dev *fd_dev = dev->dev_ptr; - struct file *f = fd_dev->fd_file; - struct inode *i = f->f_mapping->host; - unsigned long long dev_size; - /* - * When using a file that references an underlying struct block_device, - * ensure dev_size is always based on the current inode size in order - * to handle underlying block_device resize operations. - */ - if (S_ISBLK(i->i_mode)) - dev_size = (i_size_read(i) - fd_dev->fd_block_size); - else - dev_size = fd_dev->fd_dev_size; + unsigned long long blocks_long = div_u64(fd_dev->fd_dev_size, + dev->se_sub_dev->se_dev_attrib.block_size); - return div_u64(dev_size, dev->se_sub_dev->se_dev_attrib.block_size); + return blocks_long; } static struct se_subsystem_api fileio_template = { @@ -597,8 +622,10 @@ static struct se_subsystem_api fileio_template = { .allocate_virtdevice = fd_allocate_virtdevice, .create_virtdevice = fd_create_virtdevice, .free_device = fd_free_device, - .execute_cmd = fd_execute_cmd, + .alloc_task = fd_alloc_task, + .do_task = fd_do_task, .do_sync_cache = fd_emulate_sync_cache, + .free_task = fd_free_task, .check_configfs_dev_params = fd_check_configfs_dev_params, .set_configfs_dev_params = fd_set_configfs_dev_params, .show_configfs_dev_params = fd_show_configfs_dev_params, diff --git a/trunk/drivers/target/target_core_file.h b/trunk/drivers/target/target_core_file.h index fbd59ef7d8be..59e6e73106c2 100644 --- a/trunk/drivers/target/target_core_file.h +++ b/trunk/drivers/target/target_core_file.h @@ -12,6 +12,10 @@ #define RRF_EMULATE_CDB 0x01 #define RRF_GOT_LBA 0x02 +struct fd_request { + struct se_task fd_task; +}; + #define FBDF_HAS_PATH 0x01 #define FBDF_HAS_SIZE 0x02 #define FDBD_USE_BUFFERED_IO 0x04 diff --git a/trunk/drivers/target/target_core_iblock.c b/trunk/drivers/target/target_core_iblock.c index fd47950727b4..2ec299e8a73e 100644 --- a/trunk/drivers/target/target_core_iblock.c +++ b/trunk/drivers/target/target_core_iblock.c @@ -189,6 +189,26 @@ static void iblock_free_device(void *p) kfree(ib_dev); } +static inline struct iblock_req *IBLOCK_REQ(struct se_task *task) +{ + return container_of(task, struct iblock_req, ib_task); +} + +static struct se_task * +iblock_alloc_task(unsigned char *cdb) +{ + struct iblock_req *ib_req; + + ib_req = kzalloc(sizeof(struct iblock_req), GFP_KERNEL); + if (!ib_req) { + pr_err("Unable to allocate memory for struct iblock_req\n"); + return NULL; + } + + atomic_set(&ib_req->pending, 1); + return &ib_req->ib_task; +} + static unsigned long long iblock_emulate_read_cap_with_block_size( struct se_device *dev, struct block_device *bd, @@ -275,16 +295,8 @@ static void iblock_end_io_flush(struct bio *bio, int err) if (err) pr_err("IBLOCK: cache flush failed: %d\n", err); - if (cmd) { - if (err) { - cmd->scsi_sense_reason = - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION); - } else { - target_complete_cmd(cmd, SAM_STAT_GOOD); - } - } - + if (cmd) + transport_complete_sync_cache(cmd, err == 0); bio_put(bio); } @@ -292,8 +304,9 @@ static void iblock_end_io_flush(struct bio *bio, int err) * Implement SYCHRONIZE CACHE. Note that we can't handle lba ranges and must * always flush the whole cache. */ -static void iblock_emulate_sync_cache(struct se_cmd *cmd) +static void iblock_emulate_sync_cache(struct se_task *task) { + struct se_cmd *cmd = task->task_se_cmd; struct iblock_dev *ib_dev = cmd->se_dev->dev_ptr; int immed = (cmd->t_task_cdb[1] & 0x2); struct bio *bio; @@ -303,7 +316,7 @@ static void iblock_emulate_sync_cache(struct se_cmd *cmd) * for this SYNCHRONIZE_CACHE op. */ if (immed) - target_complete_cmd(cmd, SAM_STAT_GOOD); + transport_complete_sync_cache(cmd, 1); bio = bio_alloc(GFP_KERNEL, 0); bio->bi_end_io = iblock_end_io_flush; @@ -322,6 +335,11 @@ static int iblock_do_discard(struct se_device *dev, sector_t lba, u32 range) return blkdev_issue_discard(bd, lba, range, GFP_KERNEL, barrier); } +static void iblock_free_task(struct se_task *task) +{ + kfree(IBLOCK_REQ(task)); +} + enum { Opt_udev_path, Opt_force, Opt_err }; @@ -430,35 +448,19 @@ static ssize_t iblock_show_configfs_dev_params( return bl; } -static void iblock_complete_cmd(struct se_cmd *cmd) -{ - struct iblock_req *ibr = cmd->priv; - u8 status; - - if (!atomic_dec_and_test(&ibr->pending)) - return; - - if (atomic_read(&ibr->ib_bio_err_cnt)) - status = SAM_STAT_CHECK_CONDITION; - else - status = SAM_STAT_GOOD; - - target_complete_cmd(cmd, status); - kfree(ibr); -} - static void iblock_bio_destructor(struct bio *bio) { - struct se_cmd *cmd = bio->bi_private; - struct iblock_dev *ib_dev = cmd->se_dev->dev_ptr; + struct se_task *task = bio->bi_private; + struct iblock_dev *ib_dev = task->task_se_cmd->se_dev->dev_ptr; bio_free(bio, ib_dev->ibd_bio_set); } static struct bio * -iblock_get_bio(struct se_cmd *cmd, sector_t lba, u32 sg_num) +iblock_get_bio(struct se_task *task, sector_t lba, u32 sg_num) { - struct iblock_dev *ib_dev = cmd->se_dev->dev_ptr; + struct iblock_dev *ib_dev = task->task_se_cmd->se_dev->dev_ptr; + struct iblock_req *ib_req = IBLOCK_REQ(task); struct bio *bio; /* @@ -474,11 +476,19 @@ iblock_get_bio(struct se_cmd *cmd, sector_t lba, u32 sg_num) return NULL; } + pr_debug("Allocated bio: %p task_sg_nents: %u using ibd_bio_set:" + " %p\n", bio, task->task_sg_nents, ib_dev->ibd_bio_set); + pr_debug("Allocated bio: %p task_size: %u\n", bio, task->task_size); + bio->bi_bdev = ib_dev->ibd_bd; - bio->bi_private = cmd; + bio->bi_private = task; bio->bi_destructor = iblock_bio_destructor; bio->bi_end_io = &iblock_bio_done; bio->bi_sector = lba; + atomic_inc(&ib_req->pending); + + pr_debug("Set bio->bi_sector: %llu\n", (unsigned long long)bio->bi_sector); + pr_debug("Set ib_req->pending: %d\n", atomic_read(&ib_req->pending)); return bio; } @@ -493,21 +503,20 @@ static void iblock_submit_bios(struct bio_list *list, int rw) blk_finish_plug(&plug); } -static int iblock_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl, - u32 sgl_nents, enum dma_data_direction data_direction) +static int iblock_do_task(struct se_task *task) { + struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; - struct iblock_req *ibr; + struct iblock_req *ibr = IBLOCK_REQ(task); struct bio *bio; struct bio_list list; struct scatterlist *sg; - u32 sg_num = sgl_nents; + u32 i, sg_num = task->task_sg_nents; sector_t block_lba; unsigned bio_cnt; int rw; - int i; - if (data_direction == DMA_TO_DEVICE) { + if (task->task_data_direction == DMA_TO_DEVICE) { /* * Force data to disk if we pretend to not have a volatile * write cache, or the initiator set the Force Unit Access bit. @@ -523,17 +532,17 @@ static int iblock_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl, } /* - * Convert the blocksize advertised to the initiator to the 512 byte - * units unconditionally used by the Linux block layer. + * Do starting conversion up from non 512-byte blocksize with + * struct se_task SCSI blocksize into Linux/Block 512 units for BIO. */ if (dev->se_sub_dev->se_dev_attrib.block_size == 4096) - block_lba = (cmd->t_task_lba << 3); + block_lba = (task->task_lba << 3); else if (dev->se_sub_dev->se_dev_attrib.block_size == 2048) - block_lba = (cmd->t_task_lba << 2); + block_lba = (task->task_lba << 2); else if (dev->se_sub_dev->se_dev_attrib.block_size == 1024) - block_lba = (cmd->t_task_lba << 1); + block_lba = (task->task_lba << 1); else if (dev->se_sub_dev->se_dev_attrib.block_size == 512) - block_lba = cmd->t_task_lba; + block_lba = task->task_lba; else { pr_err("Unsupported SCSI -> BLOCK LBA conversion:" " %u\n", dev->se_sub_dev->se_dev_attrib.block_size); @@ -541,22 +550,17 @@ static int iblock_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl, return -ENOSYS; } - ibr = kzalloc(sizeof(struct iblock_req), GFP_KERNEL); - if (!ibr) - goto fail; - cmd->priv = ibr; - - bio = iblock_get_bio(cmd, block_lba, sgl_nents); - if (!bio) - goto fail_free_ibr; + bio = iblock_get_bio(task, block_lba, sg_num); + if (!bio) { + cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; + return -ENOMEM; + } bio_list_init(&list); bio_list_add(&list, bio); - - atomic_set(&ibr->pending, 2); bio_cnt = 1; - for_each_sg(sgl, sg, sgl_nents, i) { + for_each_sg(task->task_sg, sg, task->task_sg_nents, i) { /* * XXX: if the length the device accepts is shorter than the * length of the S/G list entry this will cause and @@ -569,11 +573,9 @@ static int iblock_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl, bio_cnt = 0; } - bio = iblock_get_bio(cmd, block_lba, sg_num); + bio = iblock_get_bio(task, block_lba, sg_num); if (!bio) - goto fail_put_bios; - - atomic_inc(&ibr->pending); + goto fail; bio_list_add(&list, bio); bio_cnt++; } @@ -584,16 +586,17 @@ static int iblock_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl, } iblock_submit_bios(&list, rw); - iblock_complete_cmd(cmd); + + if (atomic_dec_and_test(&ibr->pending)) { + transport_complete_task(task, + !atomic_read(&ibr->ib_bio_err_cnt)); + } return 0; -fail_put_bios: +fail: while ((bio = bio_list_pop(&list))) bio_put(bio); -fail_free_ibr: - kfree(ibr); cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; -fail: return -ENOMEM; } @@ -618,8 +621,8 @@ static sector_t iblock_get_blocks(struct se_device *dev) static void iblock_bio_done(struct bio *bio, int err) { - struct se_cmd *cmd = bio->bi_private; - struct iblock_req *ibr = cmd->priv; + struct se_task *task = bio->bi_private; + struct iblock_req *ibr = IBLOCK_REQ(task); /* * Set -EIO if !BIO_UPTODATE and the passed is still err=0 @@ -639,7 +642,14 @@ static void iblock_bio_done(struct bio *bio, int err) bio_put(bio); - iblock_complete_cmd(cmd); + if (!atomic_dec_and_test(&ibr->pending)) + return; + + pr_debug("done[%p] bio: %p task_lba: %llu bio_lba: %llu err=%d\n", + task, bio, task->task_lba, + (unsigned long long)bio->bi_sector, err); + + transport_complete_task(task, !atomic_read(&ibr->ib_bio_err_cnt)); } static struct se_subsystem_api iblock_template = { @@ -653,9 +663,11 @@ static struct se_subsystem_api iblock_template = { .allocate_virtdevice = iblock_allocate_virtdevice, .create_virtdevice = iblock_create_virtdevice, .free_device = iblock_free_device, - .execute_cmd = iblock_execute_cmd, + .alloc_task = iblock_alloc_task, + .do_task = iblock_do_task, .do_discard = iblock_do_discard, .do_sync_cache = iblock_emulate_sync_cache, + .free_task = iblock_free_task, .check_configfs_dev_params = iblock_check_configfs_dev_params, .set_configfs_dev_params = iblock_set_configfs_dev_params, .show_configfs_dev_params = iblock_show_configfs_dev_params, diff --git a/trunk/drivers/target/target_core_iblock.h b/trunk/drivers/target/target_core_iblock.h index 66cf7b9e205e..e929370b6fd3 100644 --- a/trunk/drivers/target/target_core_iblock.h +++ b/trunk/drivers/target/target_core_iblock.h @@ -7,6 +7,7 @@ #define IBLOCK_LBA_SHIFT 9 struct iblock_req { + struct se_task ib_task; atomic_t pending; atomic_t ib_bio_err_cnt; } ____cacheline_aligned; diff --git a/trunk/drivers/target/target_core_internal.h b/trunk/drivers/target/target_core_internal.h index 165e82429687..21c05638f158 100644 --- a/trunk/drivers/target/target_core_internal.h +++ b/trunk/drivers/target/target_core_internal.h @@ -5,15 +5,15 @@ extern struct t10_alua_lu_gp *default_lu_gp; /* target_core_cdb.c */ -int target_emulate_inquiry(struct se_cmd *cmd); -int target_emulate_readcapacity(struct se_cmd *cmd); -int target_emulate_readcapacity_16(struct se_cmd *cmd); -int target_emulate_modesense(struct se_cmd *cmd); -int target_emulate_request_sense(struct se_cmd *cmd); -int target_emulate_unmap(struct se_cmd *cmd); -int target_emulate_write_same(struct se_cmd *cmd); -int target_emulate_synchronize_cache(struct se_cmd *cmd); -int target_emulate_noop(struct se_cmd *cmd); +int target_emulate_inquiry(struct se_task *task); +int target_emulate_readcapacity(struct se_task *task); +int target_emulate_readcapacity_16(struct se_task *task); +int target_emulate_modesense(struct se_task *task); +int target_emulate_request_sense(struct se_task *task); +int target_emulate_unmap(struct se_task *task); +int target_emulate_write_same(struct se_task *task); +int target_emulate_synchronize_cache(struct se_task *task); +int target_emulate_noop(struct se_task *task); /* target_core_device.c */ struct se_dev_entry *core_get_se_deve_from_rtpi(struct se_node_acl *, u16); @@ -28,7 +28,7 @@ int core_dev_export(struct se_device *, struct se_portal_group *, struct se_lun *); void core_dev_unexport(struct se_device *, struct se_portal_group *, struct se_lun *); -int target_report_luns(struct se_cmd *); +int target_report_luns(struct se_task *); void se_release_device_for_hba(struct se_device *); void se_release_vpd_for_dev(struct se_device *); int se_free_virtual_device(struct se_device *, struct se_hba *); @@ -104,7 +104,8 @@ void release_se_kmem_caches(void); u32 scsi_get_new_index(scsi_index_t); void transport_subsystem_check_init(void); void transport_cmd_finish_abort(struct se_cmd *, int); -void __target_remove_from_execute_list(struct se_cmd *); +void __transport_remove_task_from_execute_queue(struct se_task *, + struct se_device *); unsigned char *transport_dump_cmd_direction(struct se_cmd *); void transport_dump_dev_state(struct se_device *, char *, int *); void transport_dump_dev_info(struct se_device *, struct se_lun *, @@ -113,7 +114,7 @@ void transport_dump_vpd_proto_id(struct t10_vpd *, unsigned char *, int); int transport_dump_vpd_assoc(struct t10_vpd *, unsigned char *, int); int transport_dump_vpd_ident_type(struct t10_vpd *, unsigned char *, int); int transport_dump_vpd_ident(struct t10_vpd *, unsigned char *, int); -bool target_stop_cmd(struct se_cmd *cmd, unsigned long *flags); +bool target_stop_task(struct se_task *task, unsigned long *flags); int transport_clear_lun_from_sessions(struct se_lun *); void transport_send_task_abort(struct se_cmd *); diff --git a/trunk/drivers/target/target_core_pr.c b/trunk/drivers/target/target_core_pr.c index 85564998500a..86f0c3b5d500 100644 --- a/trunk/drivers/target/target_core_pr.c +++ b/trunk/drivers/target/target_core_pr.c @@ -193,8 +193,9 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd) return 0; } -int target_scsi2_reservation_release(struct se_cmd *cmd) +int target_scsi2_reservation_release(struct se_task *task) { + struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; struct se_session *sess = cmd->se_sess; struct se_portal_group *tpg = sess->se_tpg; @@ -219,9 +220,6 @@ int target_scsi2_reservation_release(struct se_cmd *cmd) if (dev->dev_reserved_node_acl != sess->se_node_acl) goto out_unlock; - if (dev->dev_res_bin_isid != sess->sess_bin_isid) - goto out_unlock; - dev->dev_reserved_node_acl = NULL; dev->dev_flags &= ~DF_SPC2_RESERVATIONS; if (dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID) { @@ -236,13 +234,16 @@ int target_scsi2_reservation_release(struct se_cmd *cmd) out_unlock: spin_unlock(&dev->dev_reservation_lock); out: - if (!ret) - target_complete_cmd(cmd, GOOD); + if (!ret) { + task->task_scsi_status = GOOD; + transport_complete_task(task, 1); + } return ret; } -int target_scsi2_reservation_reserve(struct se_cmd *cmd) +int target_scsi2_reservation_reserve(struct se_task *task) { + struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; struct se_session *sess = cmd->se_sess; struct se_portal_group *tpg = sess->se_tpg; @@ -303,8 +304,10 @@ int target_scsi2_reservation_reserve(struct se_cmd *cmd) out_unlock: spin_unlock(&dev->dev_reservation_lock); out: - if (!ret) - target_complete_cmd(cmd, GOOD); + if (!ret) { + task->task_scsi_status = GOOD; + transport_complete_task(task, 1); + } return ret; } @@ -497,10 +500,11 @@ static int core_scsi3_pr_seq_non_holder( * statement. */ if (!ret && !other_cdb) { +#if 0 pr_debug("Allowing explict CDB: 0x%02x for %s" " reservation holder\n", cdb[0], core_scsi3_pr_dump_type(pr_reg_type)); - +#endif return ret; } /* @@ -528,14 +532,14 @@ static int core_scsi3_pr_seq_non_holder( * as we expect registered non-reservation holding * nexuses to issue CDBs. */ - +#if 0 if (!registered_nexus) { pr_debug("Allowing implict CDB: 0x%02x" " for %s reservation on unregistered" " nexus\n", cdb[0], core_scsi3_pr_dump_type(pr_reg_type)); } - +#endif return 0; } } else if ((reg_only) || (all_reg)) { @@ -544,11 +548,11 @@ static int core_scsi3_pr_seq_non_holder( * For PR_*_REG_ONLY and PR_*_ALL_REG reservations, * allow commands from registered nexuses. */ - +#if 0 pr_debug("Allowing implict CDB: 0x%02x for %s" " reservation\n", cdb[0], core_scsi3_pr_dump_type(pr_reg_type)); - +#endif return 0; } } @@ -1662,12 +1666,12 @@ static int core_scsi3_decode_spec_i_port( ret = -EINVAL; goto out; } - +#if 0 pr_debug("SPC-3 PR SPEC_I_PT: Got %s data_length: %u tpdl: %u" " tid_len: %d for %s + %s\n", dest_tpg->se_tpg_tfo->get_fabric_name(), cmd->data_length, tpdl, tid_len, i_str, iport_ptr); - +#endif if (tid_len > tpdl) { pr_err("SPC-3 PR SPEC_I_PT: Illegal tid_len:" " %u for Transport ID: %s\n", tid_len, ptr); @@ -1710,12 +1714,12 @@ static int core_scsi3_decode_spec_i_port( ret = -EINVAL; goto out; } - +#if 0 pr_debug("SPC-3 PR SPEC_I_PT: Located %s Node: %s" " dest_se_deve mapped_lun: %u\n", dest_tpg->se_tpg_tfo->get_fabric_name(), dest_node_acl->initiatorname, dest_se_deve->mapped_lun); - +#endif /* * Skip any TransportIDs that already have a registration for * this target port. @@ -3469,10 +3473,10 @@ static int core_scsi3_emulate_pro_register_and_move( buf = transport_kmap_data_sg(cmd); proto_ident = (buf[24] & 0x0f); - +#if 0 pr_debug("SPC-3 PR REGISTER_AND_MOVE: Extracted Protocol Identifier:" " 0x%02x\n", proto_ident); - +#endif if (proto_ident != dest_tf_ops->get_fabric_proto_ident(dest_se_tpg)) { pr_err("SPC-3 PR REGISTER_AND_MOVE: Received" " proto_ident: 0x%02x does not match ident: 0x%02x" @@ -3571,11 +3575,11 @@ static int core_scsi3_emulate_pro_register_and_move( ret = -EINVAL; goto out; } - +#if 0 pr_debug("SPC-3 PR REGISTER_AND_MOVE: Found %s dest_node_acl:" " %s from TransportID\n", dest_tf_ops->get_fabric_name(), dest_node_acl->initiatorname); - +#endif /* * Locate the struct se_dev_entry pointer for the matching RELATIVE TARGET * PORT IDENTIFIER. @@ -3599,12 +3603,12 @@ static int core_scsi3_emulate_pro_register_and_move( ret = -EINVAL; goto out; } - +#if 0 pr_debug("SPC-3 PR REGISTER_AND_MOVE: Located %s node %s LUN" " ACL for dest_se_deve->mapped_lun: %u\n", dest_tf_ops->get_fabric_name(), dest_node_acl->initiatorname, dest_se_deve->mapped_lun); - +#endif /* * A persistent reservation needs to already existing in order to * successfully complete the REGISTER_AND_MOVE service action.. @@ -3795,8 +3799,9 @@ static unsigned long long core_scsi3_extract_reservation_key(unsigned char *cdb) /* * See spc4r17 section 6.14 Table 170 */ -int target_scsi3_emulate_pr_out(struct se_cmd *cmd) +int target_scsi3_emulate_pr_out(struct se_task *task) { + struct se_cmd *cmd = task->task_se_cmd; unsigned char *cdb = &cmd->t_task_cdb[0]; unsigned char *buf; u64 res_key, sa_res_key; @@ -3936,8 +3941,10 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd) } out: - if (!ret) - target_complete_cmd(cmd, GOOD); + if (!ret) { + task->task_scsi_status = GOOD; + transport_complete_task(task, 1); + } return ret; } @@ -4292,8 +4299,9 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd) return 0; } -int target_scsi3_emulate_pr_in(struct se_cmd *cmd) +int target_scsi3_emulate_pr_in(struct se_task *task) { + struct se_cmd *cmd = task->task_se_cmd; int ret; /* @@ -4334,8 +4342,10 @@ int target_scsi3_emulate_pr_in(struct se_cmd *cmd) break; } - if (!ret) - target_complete_cmd(cmd, GOOD); + if (!ret) { + task->task_scsi_status = GOOD; + transport_complete_task(task, 1); + } return ret; } diff --git a/trunk/drivers/target/target_core_pr.h b/trunk/drivers/target/target_core_pr.h index af6c460d886d..7a233feb7e99 100644 --- a/trunk/drivers/target/target_core_pr.h +++ b/trunk/drivers/target/target_core_pr.h @@ -47,8 +47,8 @@ extern struct kmem_cache *t10_pr_reg_cache; extern int core_pr_dump_initiator_port(struct t10_pr_registration *, char *, u32); -extern int target_scsi2_reservation_release(struct se_cmd *); -extern int target_scsi2_reservation_reserve(struct se_cmd *); +extern int target_scsi2_reservation_release(struct se_task *task); +extern int target_scsi2_reservation_reserve(struct se_task *task); extern int core_scsi3_alloc_aptpl_registration( struct t10_reservation *, u64, unsigned char *, unsigned char *, u32, @@ -61,8 +61,8 @@ extern void core_scsi3_free_pr_reg_from_nacl(struct se_device *, extern void core_scsi3_free_all_registrations(struct se_device *); extern unsigned char *core_scsi3_pr_dump_type(int); -extern int target_scsi3_emulate_pr_in(struct se_cmd *); -extern int target_scsi3_emulate_pr_out(struct se_cmd *); +extern int target_scsi3_emulate_pr_in(struct se_task *task); +extern int target_scsi3_emulate_pr_out(struct se_task *task); extern int core_setup_reservations(struct se_device *, int); #endif /* TARGET_CORE_PR_H */ diff --git a/trunk/drivers/target/target_core_pscsi.c b/trunk/drivers/target/target_core_pscsi.c index 4ce2cf642fce..94c905fcbceb 100644 --- a/trunk/drivers/target/target_core_pscsi.c +++ b/trunk/drivers/target/target_core_pscsi.c @@ -663,12 +663,22 @@ static void pscsi_free_device(void *p) kfree(pdv); } -static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg) +static inline struct pscsi_plugin_task *PSCSI_TASK(struct se_task *task) { - struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr; + return container_of(task, struct pscsi_plugin_task, pscsi_task); +} + + +/* pscsi_transport_complete(): + * + * + */ +static int pscsi_transport_complete(struct se_task *task) +{ + struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr; struct scsi_device *sd = pdv->pdv_sd; int result; - struct pscsi_plugin_task *pt = cmd->priv; + struct pscsi_plugin_task *pt = PSCSI_TASK(task); unsigned char *cdb = &pt->pscsi_cdb[0]; result = pt->pscsi_result; @@ -678,11 +688,12 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg) */ if (((cdb[0] == MODE_SENSE) || (cdb[0] == MODE_SENSE_10)) && (status_byte(result) << 1) == SAM_STAT_GOOD) { - if (!cmd->se_deve) + if (!task->task_se_cmd->se_deve) goto after_mode_sense; - if (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) { - unsigned char *buf = transport_kmap_data_sg(cmd); + if (task->task_se_cmd->se_deve->lun_flags & + TRANSPORT_LUNFLAGS_READ_ONLY) { + unsigned char *buf = transport_kmap_data_sg(task->task_se_cmd); if (cdb[0] == MODE_SENSE_10) { if (!(buf[3] & 0x80)) @@ -692,7 +703,7 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg) buf[2] |= 0x80; } - transport_kunmap_data_sg(cmd); + transport_kunmap_data_sg(task->task_se_cmd); } } after_mode_sense: @@ -711,6 +722,7 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg) if (((cdb[0] == MODE_SELECT) || (cdb[0] == MODE_SELECT_10)) && (status_byte(result) << 1) == SAM_STAT_GOOD) { unsigned char *buf; + struct scatterlist *sg = task->task_sg; u16 bdl; u32 blocksize; @@ -745,6 +757,35 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg) return 0; } +static struct se_task * +pscsi_alloc_task(unsigned char *cdb) +{ + struct pscsi_plugin_task *pt; + + /* + * Dynamically alloc cdb space, since it may be larger than + * TCM_MAX_COMMAND_SIZE + */ + pt = kzalloc(sizeof(*pt) + scsi_command_size(cdb), GFP_KERNEL); + if (!pt) { + pr_err("Unable to allocate struct pscsi_plugin_task\n"); + return NULL; + } + + return &pt->pscsi_task; +} + +static void pscsi_free_task(struct se_task *task) +{ + struct pscsi_plugin_task *pt = PSCSI_TASK(task); + + /* + * We do not release the bio(s) here associated with this task, as + * this is handled by bio_put() and pscsi_bi_endio(). + */ + kfree(pt); +} + enum { Opt_scsi_host_id, Opt_scsi_channel_id, Opt_scsi_target_id, Opt_scsi_lun_id, Opt_err @@ -917,25 +958,26 @@ static inline struct bio *pscsi_get_bio(int sg_num) return bio; } -static int pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, - u32 sgl_nents, enum dma_data_direction data_direction, +static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg, struct bio **hbio) { - struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr; + struct se_cmd *cmd = task->task_se_cmd; + struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr; + u32 task_sg_num = task->task_sg_nents; struct bio *bio = NULL, *tbio = NULL; struct page *page; struct scatterlist *sg; - u32 data_len = cmd->data_length, i, len, bytes, off; - int nr_pages = (cmd->data_length + sgl[0].offset + + u32 data_len = task->task_size, i, len, bytes, off; + int nr_pages = (task->task_size + task_sg[0].offset + PAGE_SIZE - 1) >> PAGE_SHIFT; int nr_vecs = 0, rc; - int rw = (data_direction == DMA_TO_DEVICE); + int rw = (task->task_data_direction == DMA_TO_DEVICE); *hbio = NULL; pr_debug("PSCSI: nr_pages: %d\n", nr_pages); - for_each_sg(sgl, sg, sgl_nents, i) { + for_each_sg(task_sg, sg, task_sg_num, i) { page = sg_page(sg); off = sg->offset; len = sg->length; @@ -967,7 +1009,7 @@ static int pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, * Set *hbio pointer to handle the case: * nr_pages > BIO_MAX_PAGES, where additional * bios need to be added to complete a given - * command. + * struct se_task */ if (!*hbio) *hbio = tbio = bio; @@ -1007,7 +1049,7 @@ static int pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, } } - return sgl_nents; + return task->task_sg_nents; fail: while (*hbio) { bio = *hbio; @@ -1019,61 +1061,52 @@ static int pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, return -ENOMEM; } -static int pscsi_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl, - u32 sgl_nents, enum dma_data_direction data_direction) +static int pscsi_do_task(struct se_task *task) { - struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr; - struct pscsi_plugin_task *pt; + struct se_cmd *cmd = task->task_se_cmd; + struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr; + struct pscsi_plugin_task *pt = PSCSI_TASK(task); struct request *req; struct bio *hbio; int ret; - /* - * Dynamically alloc cdb space, since it may be larger than - * TCM_MAX_COMMAND_SIZE - */ - pt = kzalloc(sizeof(*pt) + scsi_command_size(cmd->t_task_cdb), GFP_KERNEL); - if (!pt) { - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -ENOMEM; - } - cmd->priv = pt; - - memcpy(pt->pscsi_cdb, cmd->t_task_cdb, - scsi_command_size(cmd->t_task_cdb)); + target_get_task_cdb(task, pt->pscsi_cdb); - if (cmd->se_cmd_flags & SCF_SCSI_NON_DATA_CDB) { + if (task->task_se_cmd->se_cmd_flags & SCF_SCSI_NON_DATA_CDB) { req = blk_get_request(pdv->pdv_sd->request_queue, - (data_direction == DMA_TO_DEVICE), + (task->task_data_direction == DMA_TO_DEVICE), GFP_KERNEL); if (!req || IS_ERR(req)) { pr_err("PSCSI: blk_get_request() failed: %ld\n", req ? IS_ERR(req) : -ENOMEM); cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - goto fail; + return -ENODEV; } } else { - BUG_ON(!cmd->data_length); + BUG_ON(!task->task_size); - ret = pscsi_map_sg(cmd, sgl, sgl_nents, data_direction, &hbio); + /* + * Setup the main struct request for the task->task_sg[] payload + */ + ret = pscsi_map_sg(task, task->task_sg, &hbio); if (ret < 0) { cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - goto fail; + return ret; } req = blk_make_request(pdv->pdv_sd->request_queue, hbio, GFP_KERNEL); if (IS_ERR(req)) { pr_err("pSCSI: blk_make_request() failed\n"); - goto fail_free_bio; + goto fail; } } req->cmd_type = REQ_TYPE_BLOCK_PC; req->end_io = pscsi_req_done; - req->end_io_data = cmd; + req->end_io_data = task; req->cmd_len = scsi_command_size(pt->pscsi_cdb); req->cmd = &pt->pscsi_cdb[0]; req->sense = &pt->pscsi_sense[0]; @@ -1085,12 +1118,12 @@ static int pscsi_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl, req->retries = PS_RETRY; blk_execute_rq_nowait(pdv->pdv_sd->request_queue, NULL, req, - (cmd->sam_task_attr == MSG_HEAD_TAG), + (task->task_se_cmd->sam_task_attr == MSG_HEAD_TAG), pscsi_req_done); return 0; -fail_free_bio: +fail: while (hbio) { struct bio *bio = hbio; hbio = hbio->bi_next; @@ -1098,14 +1131,16 @@ static int pscsi_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl, bio_endio(bio, 0); /* XXX: should be error */ } cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; -fail: - kfree(pt); return -ENOMEM; } -static unsigned char *pscsi_get_sense_buffer(struct se_cmd *cmd) +/* pscsi_get_sense_buffer(): + * + * + */ +static unsigned char *pscsi_get_sense_buffer(struct se_task *task) { - struct pscsi_plugin_task *pt = cmd->priv; + struct pscsi_plugin_task *pt = PSCSI_TASK(task); return pt->pscsi_sense; } @@ -1145,36 +1180,48 @@ static sector_t pscsi_get_blocks(struct se_device *dev) return 0; } -static void pscsi_req_done(struct request *req, int uptodate) +/* pscsi_handle_SAM_STATUS_failures(): + * + * + */ +static inline void pscsi_process_SAM_status( + struct se_task *task, + struct pscsi_plugin_task *pt) { - struct se_cmd *cmd = req->end_io_data; - struct pscsi_plugin_task *pt = cmd->priv; - - pt->pscsi_result = req->errors; - pt->pscsi_resid = req->resid_len; - - cmd->scsi_status = status_byte(pt->pscsi_result) << 1; - if (cmd->scsi_status) { - pr_debug("PSCSI Status Byte exception at cmd: %p CDB:" - " 0x%02x Result: 0x%08x\n", cmd, pt->pscsi_cdb[0], + task->task_scsi_status = status_byte(pt->pscsi_result); + if (task->task_scsi_status) { + task->task_scsi_status <<= 1; + pr_debug("PSCSI Status Byte exception at task: %p CDB:" + " 0x%02x Result: 0x%08x\n", task, pt->pscsi_cdb[0], pt->pscsi_result); } switch (host_byte(pt->pscsi_result)) { case DID_OK: - target_complete_cmd(cmd, cmd->scsi_status); + transport_complete_task(task, (!task->task_scsi_status)); break; default: - pr_debug("PSCSI Host Byte exception at cmd: %p CDB:" - " 0x%02x Result: 0x%08x\n", cmd, pt->pscsi_cdb[0], + pr_debug("PSCSI Host Byte exception at task: %p CDB:" + " 0x%02x Result: 0x%08x\n", task, pt->pscsi_cdb[0], pt->pscsi_result); - cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; - target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION); + task->task_scsi_status = SAM_STAT_CHECK_CONDITION; + task->task_se_cmd->scsi_sense_reason = + TCM_UNSUPPORTED_SCSI_OPCODE; + transport_complete_task(task, 0); break; } +} +static void pscsi_req_done(struct request *req, int uptodate) +{ + struct se_task *task = req->end_io_data; + struct pscsi_plugin_task *pt = PSCSI_TASK(task); + + pt->pscsi_result = req->errors; + pt->pscsi_resid = req->resid_len; + + pscsi_process_SAM_status(task, pt); __blk_put_request(req->q, req); - kfree(pt); } static struct se_subsystem_api pscsi_template = { @@ -1188,7 +1235,9 @@ static struct se_subsystem_api pscsi_template = { .create_virtdevice = pscsi_create_virtdevice, .free_device = pscsi_free_device, .transport_complete = pscsi_transport_complete, - .execute_cmd = pscsi_execute_cmd, + .alloc_task = pscsi_alloc_task, + .do_task = pscsi_do_task, + .free_task = pscsi_free_task, .check_configfs_dev_params = pscsi_check_configfs_dev_params, .set_configfs_dev_params = pscsi_set_configfs_dev_params, .show_configfs_dev_params = pscsi_show_configfs_dev_params, diff --git a/trunk/drivers/target/target_core_pscsi.h b/trunk/drivers/target/target_core_pscsi.h index bc1e5e11eca0..43f1c419e8e5 100644 --- a/trunk/drivers/target/target_core_pscsi.h +++ b/trunk/drivers/target/target_core_pscsi.h @@ -22,6 +22,7 @@ #include struct pscsi_plugin_task { + struct se_task pscsi_task; unsigned char pscsi_sense[SCSI_SENSE_BUFFERSIZE]; int pscsi_direction; int pscsi_result; diff --git a/trunk/drivers/target/target_core_rd.c b/trunk/drivers/target/target_core_rd.c index d0ceb873c0e5..8b68f7b82631 100644 --- a/trunk/drivers/target/target_core_rd.c +++ b/trunk/drivers/target/target_core_rd.c @@ -64,6 +64,9 @@ static int rd_attach_hba(struct se_hba *hba, u32 host_id) pr_debug("CORE_HBA[%d] - TCM Ramdisk HBA Driver %s on" " Generic Target Core Stack %s\n", hba->hba_id, RD_HBA_VERSION, TARGET_CORE_MOD_VERSION); + pr_debug("CORE_HBA[%d] - Attached Ramdisk HBA: %u to Generic" + " MaxSectors: %u\n", hba->hba_id, + rd_host->rd_host_id, RD_MAX_SECTORS); return 0; } @@ -196,7 +199,10 @@ static int rd_build_device_space(struct rd_dev *rd_dev) return 0; } -static void *rd_allocate_virtdevice(struct se_hba *hba, const char *name) +static void *rd_allocate_virtdevice( + struct se_hba *hba, + const char *name, + int rd_direct) { struct rd_dev *rd_dev; struct rd_host *rd_host = hba->hba_ptr; @@ -208,12 +214,25 @@ static void *rd_allocate_virtdevice(struct se_hba *hba, const char *name) } rd_dev->rd_host = rd_host; + rd_dev->rd_direct = rd_direct; return rd_dev; } -static struct se_device *rd_create_virtdevice(struct se_hba *hba, - struct se_subsystem_dev *se_dev, void *p) +static void *rd_MEMCPY_allocate_virtdevice(struct se_hba *hba, const char *name) +{ + return rd_allocate_virtdevice(hba, name, 0); +} + +/* rd_create_virtdevice(): + * + * + */ +static struct se_device *rd_create_virtdevice( + struct se_hba *hba, + struct se_subsystem_dev *se_dev, + void *p, + int rd_direct) { struct se_device *dev; struct se_dev_limits dev_limits; @@ -228,12 +247,13 @@ static struct se_device *rd_create_virtdevice(struct se_hba *hba, if (ret < 0) goto fail; - snprintf(prod, 16, "RAMDISK-MCP"); - snprintf(rev, 4, "%s", RD_MCP_VERSION); + snprintf(prod, 16, "RAMDISK-%s", (rd_dev->rd_direct) ? "DR" : "MCP"); + snprintf(rev, 4, "%s", (rd_dev->rd_direct) ? RD_DR_VERSION : + RD_MCP_VERSION); dev_limits.limits.logical_block_size = RD_BLOCKSIZE; - dev_limits.limits.max_hw_sectors = UINT_MAX; - dev_limits.limits.max_sectors = UINT_MAX; + dev_limits.limits.max_hw_sectors = RD_MAX_SECTORS; + dev_limits.limits.max_sectors = RD_MAX_SECTORS; dev_limits.hw_queue_depth = RD_MAX_DEVICE_QUEUE_DEPTH; dev_limits.queue_depth = RD_DEVICE_QUEUE_DEPTH; @@ -244,10 +264,12 @@ static struct se_device *rd_create_virtdevice(struct se_hba *hba, goto fail; rd_dev->rd_dev_id = rd_host->rd_host_dev_id_count++; + rd_dev->rd_queue_depth = dev->queue_depth; - pr_debug("CORE_RD[%u] - Added TCM MEMCPY Ramdisk Device ID: %u of" + pr_debug("CORE_RD[%u] - Added TCM %s Ramdisk Device ID: %u of" " %u pages in %u tables, %lu total bytes\n", - rd_host->rd_host_id, rd_dev->rd_dev_id, rd_dev->rd_page_count, + rd_host->rd_host_id, (!rd_dev->rd_direct) ? "MEMCPY" : + "DIRECT", rd_dev->rd_dev_id, rd_dev->rd_page_count, rd_dev->sg_table_count, (unsigned long)(rd_dev->rd_page_count * PAGE_SIZE)); @@ -258,6 +280,18 @@ static struct se_device *rd_create_virtdevice(struct se_hba *hba, return ERR_PTR(ret); } +static struct se_device *rd_MEMCPY_create_virtdevice( + struct se_hba *hba, + struct se_subsystem_dev *se_dev, + void *p) +{ + return rd_create_virtdevice(hba, se_dev, p, 0); +} + +/* rd_free_device(): (Part of se_subsystem_api_t template) + * + * + */ static void rd_free_device(void *p) { struct rd_dev *rd_dev = p; @@ -266,6 +300,29 @@ static void rd_free_device(void *p) kfree(rd_dev); } +static inline struct rd_request *RD_REQ(struct se_task *task) +{ + return container_of(task, struct rd_request, rd_task); +} + +static struct se_task * +rd_alloc_task(unsigned char *cdb) +{ + struct rd_request *rd_req; + + rd_req = kzalloc(sizeof(struct rd_request), GFP_KERNEL); + if (!rd_req) { + pr_err("Unable to allocate struct rd_request\n"); + return NULL; + } + + return &rd_req->rd_task; +} + +/* rd_get_sg_table(): + * + * + */ static struct rd_dev_sg_table *rd_get_sg_table(struct rd_dev *rd_dev, u32 page) { u32 i; @@ -284,41 +341,31 @@ static struct rd_dev_sg_table *rd_get_sg_table(struct rd_dev *rd_dev, u32 page) return NULL; } -static int rd_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl, - u32 sgl_nents, enum dma_data_direction data_direction) +static int rd_MEMCPY(struct rd_request *req, u32 read_rd) { - struct se_device *se_dev = cmd->se_dev; - struct rd_dev *dev = se_dev->dev_ptr; + struct se_task *task = &req->rd_task; + struct rd_dev *dev = req->rd_task.task_se_cmd->se_dev->dev_ptr; struct rd_dev_sg_table *table; struct scatterlist *rd_sg; struct sg_mapping_iter m; - u32 rd_offset; - u32 rd_size; - u32 rd_page; + u32 rd_offset = req->rd_offset; u32 src_len; - u64 tmp; - - tmp = cmd->t_task_lba * se_dev->se_sub_dev->se_dev_attrib.block_size; - rd_offset = do_div(tmp, PAGE_SIZE); - rd_page = tmp; - rd_size = cmd->data_length; - table = rd_get_sg_table(dev, rd_page); + table = rd_get_sg_table(dev, req->rd_page); if (!table) return -EINVAL; - rd_sg = &table->sg_table[rd_page - table->page_start_offset]; + rd_sg = &table->sg_table[req->rd_page - table->page_start_offset]; pr_debug("RD[%u]: %s LBA: %llu, Size: %u Page: %u, Offset: %u\n", - dev->rd_dev_id, - data_direction == DMA_FROM_DEVICE ? "Read" : "Write", - cmd->t_task_lba, rd_size, rd_page, rd_offset); + dev->rd_dev_id, read_rd ? "Read" : "Write", + task->task_lba, req->rd_size, req->rd_page, + rd_offset); src_len = PAGE_SIZE - rd_offset; - sg_miter_start(&m, sgl, sgl_nents, - data_direction == DMA_FROM_DEVICE ? - SG_MITER_TO_SG : SG_MITER_FROM_SG); - while (rd_size) { + sg_miter_start(&m, task->task_sg, task->task_sg_nents, + read_rd ? SG_MITER_TO_SG : SG_MITER_FROM_SG); + while (req->rd_size) { u32 len; void *rd_addr; @@ -328,13 +375,13 @@ static int rd_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl, rd_addr = sg_virt(rd_sg) + rd_offset; - if (data_direction == DMA_FROM_DEVICE) + if (read_rd) memcpy(m.addr, rd_addr, len); else memcpy(rd_addr, m.addr, len); - rd_size -= len; - if (!rd_size) + req->rd_size -= len; + if (!req->rd_size) continue; src_len -= len; @@ -344,15 +391,15 @@ static int rd_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl, } /* rd page completed, next one please */ - rd_page++; + req->rd_page++; rd_offset = 0; src_len = PAGE_SIZE; - if (rd_page <= table->page_end_offset) { + if (req->rd_page <= table->page_end_offset) { rd_sg++; continue; } - table = rd_get_sg_table(dev, rd_page); + table = rd_get_sg_table(dev, req->rd_page); if (!table) { sg_miter_stop(&m); return -EINVAL; @@ -362,11 +409,43 @@ static int rd_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl, rd_sg = table->sg_table; } sg_miter_stop(&m); + return 0; +} - target_complete_cmd(cmd, SAM_STAT_GOOD); +/* rd_MEMCPY_do_task(): (Part of se_subsystem_api_t template) + * + * + */ +static int rd_MEMCPY_do_task(struct se_task *task) +{ + struct se_device *dev = task->task_se_cmd->se_dev; + struct rd_request *req = RD_REQ(task); + u64 tmp; + int ret; + + tmp = task->task_lba * dev->se_sub_dev->se_dev_attrib.block_size; + req->rd_offset = do_div(tmp, PAGE_SIZE); + req->rd_page = tmp; + req->rd_size = task->task_size; + + ret = rd_MEMCPY(req, task->task_data_direction == DMA_FROM_DEVICE); + if (ret != 0) + return ret; + + task->task_scsi_status = GOOD; + transport_complete_task(task, 1); return 0; } +/* rd_free_task(): (Part of se_subsystem_api_t template) + * + * + */ +static void rd_free_task(struct se_task *task) +{ + kfree(RD_REQ(task)); +} + enum { Opt_rd_pages, Opt_err }; @@ -433,8 +512,9 @@ static ssize_t rd_show_configfs_dev_params( char *b) { struct rd_dev *rd_dev = se_dev->se_dev_su_ptr; - ssize_t bl = sprintf(b, "TCM RamDisk ID: %u RamDisk Makeup: rd_mcp\n", - rd_dev->rd_dev_id); + ssize_t bl = sprintf(b, "TCM RamDisk ID: %u RamDisk Makeup: %s\n", + rd_dev->rd_dev_id, (rd_dev->rd_direct) ? + "rd_direct" : "rd_mcp"); bl += sprintf(b + bl, " PAGES/PAGE_SIZE: %u*%lu" " SG_table_count: %u\n", rd_dev->rd_page_count, PAGE_SIZE, rd_dev->sg_table_count); @@ -465,10 +545,12 @@ static struct se_subsystem_api rd_mcp_template = { .transport_type = TRANSPORT_PLUGIN_VHBA_VDEV, .attach_hba = rd_attach_hba, .detach_hba = rd_detach_hba, - .allocate_virtdevice = rd_allocate_virtdevice, - .create_virtdevice = rd_create_virtdevice, + .allocate_virtdevice = rd_MEMCPY_allocate_virtdevice, + .create_virtdevice = rd_MEMCPY_create_virtdevice, .free_device = rd_free_device, - .execute_cmd = rd_execute_cmd, + .alloc_task = rd_alloc_task, + .do_task = rd_MEMCPY_do_task, + .free_task = rd_free_task, .check_configfs_dev_params = rd_check_configfs_dev_params, .set_configfs_dev_params = rd_set_configfs_dev_params, .show_configfs_dev_params = rd_show_configfs_dev_params, diff --git a/trunk/drivers/target/target_core_rd.h b/trunk/drivers/target/target_core_rd.h index 21458125fe51..784e56a04100 100644 --- a/trunk/drivers/target/target_core_rd.h +++ b/trunk/drivers/target/target_core_rd.h @@ -2,6 +2,7 @@ #define TARGET_CORE_RD_H #define RD_HBA_VERSION "v4.0" +#define RD_DR_VERSION "4.0" #define RD_MCP_VERSION "4.0" /* Largest piece of memory kmalloc can allocate */ @@ -9,11 +10,28 @@ #define RD_DEVICE_QUEUE_DEPTH 32 #define RD_MAX_DEVICE_QUEUE_DEPTH 128 #define RD_BLOCKSIZE 512 +#define RD_MAX_SECTORS 1024 /* Used in target_core_init_configfs() for virtual LUN 0 access */ int __init rd_module_init(void); void rd_module_exit(void); +#define RRF_EMULATE_CDB 0x01 +#define RRF_GOT_LBA 0x02 + +struct rd_request { + struct se_task rd_task; + + /* Offset from start of page */ + u32 rd_offset; + /* Starting page in Ramdisk for request */ + u32 rd_page; + /* Total number of pages needed for request */ + u32 rd_page_count; + /* Scatterlist count */ + u32 rd_size; +} ____cacheline_aligned; + struct rd_dev_sg_table { u32 page_start_offset; u32 page_end_offset; @@ -24,6 +42,7 @@ struct rd_dev_sg_table { #define RDF_HAS_PAGE_COUNT 0x01 struct rd_dev { + int rd_direct; u32 rd_flags; /* Unique Ramdisk Device ID in Ramdisk HBA */ u32 rd_dev_id; @@ -31,6 +50,7 @@ struct rd_dev { u32 rd_page_count; /* Number of SG tables in sg_table_array */ u32 sg_table_count; + u32 rd_queue_depth; /* Array of rd_dev_sg_table_t containing scatterlists */ struct rd_dev_sg_table *sg_table_array; /* Ramdisk HBA device is connected to */ diff --git a/trunk/drivers/target/target_core_tmr.c b/trunk/drivers/target/target_core_tmr.c index 84caf1bed9a3..f015839aef89 100644 --- a/trunk/drivers/target/target_core_tmr.c +++ b/trunk/drivers/target/target_core_tmr.c @@ -244,7 +244,7 @@ static void core_tmr_drain_tmr_list( } } -static void core_tmr_drain_state_list( +static void core_tmr_drain_task_list( struct se_device *dev, struct se_cmd *prout_cmd, struct se_node_acl *tmr_nacl, @@ -252,13 +252,12 @@ static void core_tmr_drain_state_list( struct list_head *preempt_and_abort_list) { LIST_HEAD(drain_task_list); - struct se_cmd *cmd, *next; + struct se_cmd *cmd; + struct se_task *task, *task_tmp; unsigned long flags; int fe_count; - /* - * Complete outstanding commands with TASK_ABORTED SAM status. - * + * Complete outstanding struct se_task CDBs with TASK_ABORTED SAM status. * This is following sam4r17, section 5.6 Aborting commands, Table 38 * for TMR LUN_RESET: * @@ -279,43 +278,56 @@ static void core_tmr_drain_state_list( * in the Control Mode Page. */ spin_lock_irqsave(&dev->execute_task_lock, flags); - list_for_each_entry_safe(cmd, next, &dev->state_list, state_list) { + list_for_each_entry_safe(task, task_tmp, &dev->state_task_list, + t_state_list) { + if (!task->task_se_cmd) { + pr_err("task->task_se_cmd is NULL!\n"); + continue; + } + cmd = task->task_se_cmd; + /* * For PREEMPT_AND_ABORT usage, only process commands * with a matching reservation key. */ if (target_check_cdb_and_preempt(preempt_and_abort_list, cmd)) continue; - /* * Not aborting PROUT PREEMPT_AND_ABORT CDB.. */ if (prout_cmd == cmd) continue; - list_move_tail(&cmd->state_list, &drain_task_list); - cmd->state_active = false; - - if (!list_empty(&cmd->execute_list)) - __target_remove_from_execute_list(cmd); + list_move_tail(&task->t_state_list, &drain_task_list); + task->t_state_active = false; + /* + * Remove from task execute list before processing drain_task_list + */ + if (!list_empty(&task->t_execute_list)) + __transport_remove_task_from_execute_queue(task, dev); } spin_unlock_irqrestore(&dev->execute_task_lock, flags); while (!list_empty(&drain_task_list)) { - cmd = list_entry(drain_task_list.next, struct se_cmd, state_list); - list_del(&cmd->state_list); + task = list_entry(drain_task_list.next, struct se_task, t_state_list); + list_del(&task->t_state_list); + cmd = task->task_se_cmd; - pr_debug("LUN_RESET: %s cmd: %p" + pr_debug("LUN_RESET: %s cmd: %p task: %p" " ITT/CmdSN: 0x%08x/0x%08x, i_state: %d, t_state: %d" "cdb: 0x%02x\n", - (preempt_and_abort_list) ? "Preempt" : "", cmd, + (preempt_and_abort_list) ? "Preempt" : "", cmd, task, cmd->se_tfo->get_task_tag(cmd), 0, cmd->se_tfo->get_cmd_state(cmd), cmd->t_state, cmd->t_task_cdb[0]); pr_debug("LUN_RESET: ITT[0x%08x] - pr_res_key: 0x%016Lx" - " -- CMD_T_ACTIVE: %d" + " t_task_cdbs: %d t_task_cdbs_left: %d" + " t_task_cdbs_sent: %d -- CMD_T_ACTIVE: %d" " CMD_T_STOP: %d CMD_T_SENT: %d\n", cmd->se_tfo->get_task_tag(cmd), cmd->pr_res_key, + cmd->t_task_list_num, + atomic_read(&cmd->t_task_cdbs_left), + atomic_read(&cmd->t_task_cdbs_sent), (cmd->transport_state & CMD_T_ACTIVE) != 0, (cmd->transport_state & CMD_T_STOP) != 0, (cmd->transport_state & CMD_T_SENT) != 0); @@ -331,13 +343,20 @@ static void core_tmr_drain_state_list( cancel_work_sync(&cmd->work); spin_lock_irqsave(&cmd->t_state_lock, flags); - target_stop_cmd(cmd, &flags); + target_stop_task(task, &flags); + if (!atomic_dec_and_test(&cmd->t_task_cdbs_ex_left)) { + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + pr_debug("LUN_RESET: Skipping task: %p, dev: %p for" + " t_task_cdbs_ex_left: %d\n", task, dev, + atomic_read(&cmd->t_task_cdbs_ex_left)); + continue; + } fe_count = atomic_read(&cmd->t_fe_count); if (!(cmd->transport_state & CMD_T_ACTIVE)) { pr_debug("LUN_RESET: got CMD_T_ACTIVE for" - " cdb: %p, t_fe_count: %d dev: %p\n", cmd, + " task: %p, t_fe_count: %d dev: %p\n", task, fe_count, dev); cmd->transport_state |= CMD_T_ABORTED; spin_unlock_irqrestore(&cmd->t_state_lock, flags); @@ -345,8 +364,8 @@ static void core_tmr_drain_state_list( core_tmr_handle_tas_abort(tmr_nacl, cmd, tas, fe_count); continue; } - pr_debug("LUN_RESET: Got !CMD_T_ACTIVE for cdb: %p," - " t_fe_count: %d dev: %p\n", cmd, fe_count, dev); + pr_debug("LUN_RESET: Got !CMD_T_ACTIVE for task: %p," + " t_fe_count: %d dev: %p\n", task, fe_count, dev); cmd->transport_state |= CMD_T_ABORTED; spin_unlock_irqrestore(&cmd->t_state_lock, flags); @@ -365,11 +384,13 @@ static void core_tmr_drain_cmd_list( struct se_queue_obj *qobj = &dev->dev_queue_obj; struct se_cmd *cmd, *tcmd; unsigned long flags; - /* - * Release all commands remaining in the per-device command queue. + * Release all commands remaining in the struct se_device cmd queue. * - * This follows the same logic as above for the state list. + * This follows the same logic as above for the struct se_device + * struct se_task state list, where commands are returned with + * TASK_ABORTED status, if there is an outstanding $FABRIC_MOD + * reference, otherwise the struct se_cmd is released. */ spin_lock_irqsave(&qobj->cmd_queue_lock, flags); list_for_each_entry_safe(cmd, tcmd, &qobj->qobj_list, se_queue_node) { @@ -445,7 +466,7 @@ int core_tmr_lun_reset( dev->transport->name, tas); core_tmr_drain_tmr_list(dev, tmr, preempt_and_abort_list); - core_tmr_drain_state_list(dev, prout_cmd, tmr_nacl, tas, + core_tmr_drain_task_list(dev, prout_cmd, tmr_nacl, tas, preempt_and_abort_list); core_tmr_drain_cmd_list(dev, prout_cmd, tmr_nacl, tas, preempt_and_abort_list); diff --git a/trunk/drivers/target/target_core_tpg.c b/trunk/drivers/target/target_core_tpg.c index 8bd58e284185..70c3ffb981e7 100644 --- a/trunk/drivers/target/target_core_tpg.c +++ b/trunk/drivers/target/target_core_tpg.c @@ -60,6 +60,7 @@ static void core_clear_initiator_node_from_tpg( int i; struct se_dev_entry *deve; struct se_lun *lun; + struct se_lun_acl *acl, *acl_tmp; spin_lock_irq(&nacl->device_list_lock); for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { @@ -80,7 +81,28 @@ static void core_clear_initiator_node_from_tpg( core_update_device_list_for_node(lun, NULL, deve->mapped_lun, TRANSPORT_LUNFLAGS_NO_ACCESS, nacl, tpg, 0); + spin_lock(&lun->lun_acl_lock); + list_for_each_entry_safe(acl, acl_tmp, + &lun->lun_acl_list, lacl_list) { + if (!strcmp(acl->initiatorname, nacl->initiatorname) && + (acl->mapped_lun == deve->mapped_lun)) + break; + } + + if (!acl) { + pr_err("Unable to locate struct se_lun_acl for %s," + " mapped_lun: %u\n", nacl->initiatorname, + deve->mapped_lun); + spin_unlock(&lun->lun_acl_lock); + spin_lock_irq(&nacl->device_list_lock); + continue; + } + + list_del(&acl->lacl_list); + spin_unlock(&lun->lun_acl_lock); + spin_lock_irq(&nacl->device_list_lock); + kfree(acl); } spin_unlock_irq(&nacl->device_list_lock); } @@ -153,7 +175,10 @@ void core_tpg_add_node_to_devs( * demo_mode_write_protect is ON, or READ_ONLY; */ if (!tpg->se_tpg_tfo->tpg_check_demo_mode_write_protect(tpg)) { - lun_access = TRANSPORT_LUNFLAGS_READ_WRITE; + if (dev->dev_flags & DF_READ_ONLY) + lun_access = TRANSPORT_LUNFLAGS_READ_ONLY; + else + lun_access = TRANSPORT_LUNFLAGS_READ_WRITE; } else { /* * Allow only optical drives to issue R/W in default RO diff --git a/trunk/drivers/target/target_core_transport.c b/trunk/drivers/target/target_core_transport.c index b05fdc0c05d3..443704f84fd5 100644 --- a/trunk/drivers/target/target_core_transport.c +++ b/trunk/drivers/target/target_core_transport.c @@ -72,6 +72,7 @@ static int __transport_execute_tasks(struct se_device *dev, struct se_cmd *); static void transport_complete_task_attr(struct se_cmd *cmd); static void transport_handle_queue_full(struct se_cmd *cmd, struct se_device *dev); +static void transport_free_dev_tasks(struct se_cmd *cmd); static int transport_generic_get_mem(struct se_cmd *cmd); static void transport_put_cmd(struct se_cmd *cmd); static void transport_remove_cmd_from_queue(struct se_cmd *cmd); @@ -330,9 +331,9 @@ void target_get_session(struct se_session *se_sess) } EXPORT_SYMBOL(target_get_session); -void target_put_session(struct se_session *se_sess) +int target_put_session(struct se_session *se_sess) { - kref_put(&se_sess->sess_kref, target_release_session); + return kref_put(&se_sess->sess_kref, target_release_session); } EXPORT_SYMBOL(target_put_session); @@ -443,23 +444,31 @@ EXPORT_SYMBOL(transport_deregister_session); /* * Called with cmd->t_state_lock held. */ -static void target_remove_from_state_list(struct se_cmd *cmd) +static void transport_all_task_dev_remove_state(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; + struct se_task *task; unsigned long flags; if (!dev) return; - if (cmd->transport_state & CMD_T_BUSY) - return; + list_for_each_entry(task, &cmd->t_task_list, t_list) { + if (task->task_flags & TF_ACTIVE) + continue; - spin_lock_irqsave(&dev->execute_task_lock, flags); - if (cmd->state_active) { - list_del(&cmd->state_list); - cmd->state_active = false; + spin_lock_irqsave(&dev->execute_task_lock, flags); + if (task->t_state_active) { + pr_debug("Removed ITT: 0x%08x dev: %p task[%p]\n", + cmd->se_tfo->get_task_tag(cmd), dev, task); + + list_del(&task->t_state_list); + atomic_dec(&cmd->t_task_cdbs_ex_left); + task->t_state_active = false; + } + spin_unlock_irqrestore(&dev->execute_task_lock, flags); } - spin_unlock_irqrestore(&dev->execute_task_lock, flags); + } /* transport_cmd_check_stop(): @@ -488,7 +497,7 @@ static int transport_cmd_check_stop( cmd->transport_state &= ~CMD_T_ACTIVE; if (transport_off == 2) - target_remove_from_state_list(cmd); + transport_all_task_dev_remove_state(cmd); spin_unlock_irqrestore(&cmd->t_state_lock, flags); complete(&cmd->transport_lun_stop_comp); @@ -504,7 +513,7 @@ static int transport_cmd_check_stop( cmd->se_tfo->get_task_tag(cmd)); if (transport_off == 2) - target_remove_from_state_list(cmd); + transport_all_task_dev_remove_state(cmd); /* * Clear struct se_cmd->se_lun before the transport_off == 2 handoff @@ -520,7 +529,7 @@ static int transport_cmd_check_stop( if (transport_off) { cmd->transport_state &= ~CMD_T_ACTIVE; if (transport_off == 2) { - target_remove_from_state_list(cmd); + transport_all_task_dev_remove_state(cmd); /* * Clear struct se_cmd->se_lun before the transport_off == 2 * handoff to fabric module. @@ -568,7 +577,7 @@ static void transport_lun_remove_cmd(struct se_cmd *cmd) spin_lock_irqsave(&cmd->t_state_lock, flags); if (cmd->transport_state & CMD_T_DEV_ACTIVE) { cmd->transport_state &= ~CMD_T_DEV_ACTIVE; - target_remove_from_state_list(cmd); + transport_all_task_dev_remove_state(cmd); } spin_unlock_irqrestore(&cmd->t_state_lock, flags); @@ -660,6 +669,29 @@ static void transport_remove_cmd_from_queue(struct se_cmd *cmd) spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags); } +/* + * Completion function used by TCM subsystem plugins (such as FILEIO) + * for queueing up response from struct se_subsystem_api->do_task() + */ +void transport_complete_sync_cache(struct se_cmd *cmd, int good) +{ + struct se_task *task = list_entry(cmd->t_task_list.next, + struct se_task, t_list); + + if (good) { + cmd->scsi_status = SAM_STAT_GOOD; + task->task_scsi_status = GOOD; + } else { + task->task_scsi_status = SAM_STAT_CHECK_CONDITION; + task->task_se_cmd->scsi_sense_reason = + TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; + + } + + transport_complete_task(task, good); +} +EXPORT_SYMBOL(transport_complete_sync_cache); + static void target_complete_failure_work(struct work_struct *work) { struct se_cmd *cmd = container_of(work, struct se_cmd, work); @@ -667,38 +699,55 @@ static void target_complete_failure_work(struct work_struct *work) transport_generic_request_failure(cmd); } -void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) +/* transport_complete_task(): + * + * Called from interrupt and non interrupt context depending + * on the transport plugin. + */ +void transport_complete_task(struct se_task *task, int success) { + struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; - int success = scsi_status == GOOD; unsigned long flags; - cmd->scsi_status = scsi_status; - - spin_lock_irqsave(&cmd->t_state_lock, flags); - cmd->transport_state &= ~CMD_T_BUSY; + task->task_flags &= ~TF_ACTIVE; + /* + * See if any sense data exists, if so set the TASK_SENSE flag. + * Also check for any other post completion work that needs to be + * done by the plugins. + */ if (dev && dev->transport->transport_complete) { - if (dev->transport->transport_complete(cmd, - cmd->t_data_sg) != 0) { + if (dev->transport->transport_complete(task) != 0) { cmd->se_cmd_flags |= SCF_TRANSPORT_TASK_SENSE; + task->task_flags |= TF_HAS_SENSE; success = 1; } } /* - * See if we are waiting to complete for an exception condition. + * See if we are waiting for outstanding struct se_task + * to complete for an exception condition */ - if (cmd->transport_state & CMD_T_REQUEST_STOP) { + if (task->task_flags & TF_REQUEST_STOP) { spin_unlock_irqrestore(&cmd->t_state_lock, flags); - complete(&cmd->task_stop_comp); + complete(&task->task_stop_comp); return; } if (!success) cmd->transport_state |= CMD_T_FAILED; + /* + * Decrement the outstanding t_task_cdbs_left count. The last + * struct se_task from struct se_cmd will complete itself into the + * device queue depending upon int success. + */ + if (!atomic_dec_and_test(&cmd->t_task_cdbs_left)) { + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + return; + } /* * Check for case where an explict ABORT_TASK has been received * and transport_wait_for_tasks() will be waiting for completion.. @@ -721,77 +770,157 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) queue_work(target_completion_wq, &cmd->work); } -EXPORT_SYMBOL(target_complete_cmd); +EXPORT_SYMBOL(transport_complete_task); -static void target_add_to_state_list(struct se_cmd *cmd) -{ - struct se_device *dev = cmd->se_dev; - unsigned long flags; +/* + * Called by transport_add_tasks_from_cmd() once a struct se_cmd's + * struct se_task list are ready to be added to the active execution list + * struct se_device - spin_lock_irqsave(&dev->execute_task_lock, flags); - if (!cmd->state_active) { - list_add_tail(&cmd->state_list, &dev->state_list); - cmd->state_active = true; + * Called with se_dev_t->execute_task_lock called. + */ +static inline int transport_add_task_check_sam_attr( + struct se_task *task, + struct se_task *task_prev, + struct se_device *dev) +{ + /* + * No SAM Task attribute emulation enabled, add to tail of + * execution queue + */ + if (dev->dev_task_attr_type != SAM_TASK_ATTR_EMULATED) { + list_add_tail(&task->t_execute_list, &dev->execute_task_list); + return 0; } - spin_unlock_irqrestore(&dev->execute_task_lock, flags); + /* + * HEAD_OF_QUEUE attribute for received CDB, which means + * the first task that is associated with a struct se_cmd goes to + * head of the struct se_device->execute_task_list, and task_prev + * after that for each subsequent task + */ + if (task->task_se_cmd->sam_task_attr == MSG_HEAD_TAG) { + list_add(&task->t_execute_list, + (task_prev != NULL) ? + &task_prev->t_execute_list : + &dev->execute_task_list); + + pr_debug("Set HEAD_OF_QUEUE for task CDB: 0x%02x" + " in execution queue\n", + task->task_se_cmd->t_task_cdb[0]); + return 1; + } + /* + * For ORDERED, SIMPLE or UNTAGGED attribute tasks once they have been + * transitioned from Dermant -> Active state, and are added to the end + * of the struct se_device->execute_task_list + */ + list_add_tail(&task->t_execute_list, &dev->execute_task_list); + return 0; } -static void __target_add_to_execute_list(struct se_cmd *cmd) +/* __transport_add_task_to_execute_queue(): + * + * Called with se_dev_t->execute_task_lock called. + */ +static void __transport_add_task_to_execute_queue( + struct se_task *task, + struct se_task *task_prev, + struct se_device *dev) { - struct se_device *dev = cmd->se_dev; - bool head_of_queue = false; - - if (!list_empty(&cmd->execute_list)) - return; + int head_of_queue; - if (dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED && - cmd->sam_task_attr == MSG_HEAD_TAG) - head_of_queue = true; + head_of_queue = transport_add_task_check_sam_attr(task, task_prev, dev); + atomic_inc(&dev->execute_tasks); + if (task->t_state_active) + return; + /* + * Determine if this task needs to go to HEAD_OF_QUEUE for the + * state list as well. Running with SAM Task Attribute emulation + * will always return head_of_queue == 0 here + */ if (head_of_queue) - list_add(&cmd->execute_list, &dev->execute_list); + list_add(&task->t_state_list, (task_prev) ? + &task_prev->t_state_list : + &dev->state_task_list); else - list_add_tail(&cmd->execute_list, &dev->execute_list); + list_add_tail(&task->t_state_list, &dev->state_task_list); - atomic_inc(&dev->execute_tasks); + task->t_state_active = true; - if (cmd->state_active) - return; + pr_debug("Added ITT: 0x%08x task[%p] to dev: %p\n", + task->task_se_cmd->se_tfo->get_task_tag(task->task_se_cmd), + task, dev); +} - if (head_of_queue) - list_add(&cmd->state_list, &dev->state_list); - else - list_add_tail(&cmd->state_list, &dev->state_list); +static void transport_add_tasks_to_state_queue(struct se_cmd *cmd) +{ + struct se_device *dev = cmd->se_dev; + struct se_task *task; + unsigned long flags; + + spin_lock_irqsave(&cmd->t_state_lock, flags); + list_for_each_entry(task, &cmd->t_task_list, t_list) { + spin_lock(&dev->execute_task_lock); + if (!task->t_state_active) { + list_add_tail(&task->t_state_list, + &dev->state_task_list); + task->t_state_active = true; + + pr_debug("Added ITT: 0x%08x task[%p] to dev: %p\n", + task->task_se_cmd->se_tfo->get_task_tag( + task->task_se_cmd), task, dev); + } + spin_unlock(&dev->execute_task_lock); + } + spin_unlock_irqrestore(&cmd->t_state_lock, flags); +} + +static void __transport_add_tasks_from_cmd(struct se_cmd *cmd) +{ + struct se_device *dev = cmd->se_dev; + struct se_task *task, *task_prev = NULL; - cmd->state_active = true; + list_for_each_entry(task, &cmd->t_task_list, t_list) { + if (!list_empty(&task->t_execute_list)) + continue; + /* + * __transport_add_task_to_execute_queue() handles the + * SAM Task Attribute emulation if enabled + */ + __transport_add_task_to_execute_queue(task, task_prev, dev); + task_prev = task; + } } -static void target_add_to_execute_list(struct se_cmd *cmd) +static void transport_add_tasks_from_cmd(struct se_cmd *cmd) { unsigned long flags; struct se_device *dev = cmd->se_dev; spin_lock_irqsave(&dev->execute_task_lock, flags); - __target_add_to_execute_list(cmd); + __transport_add_tasks_from_cmd(cmd); spin_unlock_irqrestore(&dev->execute_task_lock, flags); } -void __target_remove_from_execute_list(struct se_cmd *cmd) +void __transport_remove_task_from_execute_queue(struct se_task *task, + struct se_device *dev) { - list_del_init(&cmd->execute_list); - atomic_dec(&cmd->se_dev->execute_tasks); + list_del_init(&task->t_execute_list); + atomic_dec(&dev->execute_tasks); } -static void target_remove_from_execute_list(struct se_cmd *cmd) +static void transport_remove_task_from_execute_queue( + struct se_task *task, + struct se_device *dev) { - struct se_device *dev = cmd->se_dev; unsigned long flags; - if (WARN_ON(list_empty(&cmd->execute_list))) + if (WARN_ON(list_empty(&task->t_execute_list))) return; spin_lock_irqsave(&dev->execute_task_lock, flags); - __target_remove_from_execute_list(cmd); + __transport_remove_task_from_execute_queue(task, dev); spin_unlock_irqrestore(&dev->execute_task_lock, flags); } @@ -870,9 +999,8 @@ void transport_dump_dev_state( *bl += sprintf(b + *bl, " Execute/Max Queue Depth: %d/%d", atomic_read(&dev->execute_tasks), dev->queue_depth); - *bl += sprintf(b + *bl, " SectorSize: %u HwMaxSectors: %u\n", - dev->se_sub_dev->se_dev_attrib.block_size, - dev->se_sub_dev->se_dev_attrib.hw_max_sectors); + *bl += sprintf(b + *bl, " SectorSize: %u MaxSectors: %u\n", + dev->se_sub_dev->se_dev_attrib.block_size, dev->se_sub_dev->se_dev_attrib.max_sectors); *bl += sprintf(b + *bl, " "); } @@ -1216,9 +1344,9 @@ struct se_device *transport_add_device_to_core_hba( INIT_LIST_HEAD(&dev->dev_list); INIT_LIST_HEAD(&dev->dev_sep_list); INIT_LIST_HEAD(&dev->dev_tmr_list); - INIT_LIST_HEAD(&dev->execute_list); + INIT_LIST_HEAD(&dev->execute_task_list); INIT_LIST_HEAD(&dev->delayed_cmd_list); - INIT_LIST_HEAD(&dev->state_list); + INIT_LIST_HEAD(&dev->state_task_list); INIT_LIST_HEAD(&dev->qf_cmd_list); spin_lock_init(&dev->execute_task_lock); spin_lock_init(&dev->delayed_cmd_lock); @@ -1329,7 +1457,6 @@ static inline void transport_generic_prepare_cdb( case VERIFY_16: /* SBC - VRProtect */ case WRITE_VERIFY: /* SBC - VRProtect */ case WRITE_VERIFY_12: /* SBC - VRProtect */ - case MAINTENANCE_IN: /* SPC - Parameter Data Format for SA RTPG */ break; default: cdb[1] &= 0x1f; /* clear logical unit number */ @@ -1337,6 +1464,29 @@ static inline void transport_generic_prepare_cdb( } } +static struct se_task * +transport_generic_get_task(struct se_cmd *cmd, + enum dma_data_direction data_direction) +{ + struct se_task *task; + struct se_device *dev = cmd->se_dev; + + task = dev->transport->alloc_task(cmd->t_task_cdb); + if (!task) { + pr_err("Unable to allocate struct se_task\n"); + return NULL; + } + + INIT_LIST_HEAD(&task->t_list); + INIT_LIST_HEAD(&task->t_execute_list); + INIT_LIST_HEAD(&task->t_state_list); + init_completion(&task->task_stop_comp); + task->task_se_cmd = cmd; + task->task_data_direction = data_direction; + + return task; +} + static int transport_generic_cmd_sequencer(struct se_cmd *, unsigned char *); /* @@ -1357,13 +1507,11 @@ void transport_init_se_cmd( INIT_LIST_HEAD(&cmd->se_qf_node); INIT_LIST_HEAD(&cmd->se_queue_node); INIT_LIST_HEAD(&cmd->se_cmd_list); - INIT_LIST_HEAD(&cmd->execute_list); - INIT_LIST_HEAD(&cmd->state_list); + INIT_LIST_HEAD(&cmd->t_task_list); init_completion(&cmd->transport_lun_fe_stop_comp); init_completion(&cmd->transport_lun_stop_comp); init_completion(&cmd->t_transport_stop_comp); init_completion(&cmd->cmd_wait_comp); - init_completion(&cmd->task_stop_comp); spin_lock_init(&cmd->t_state_lock); cmd->transport_state = CMD_T_DEV_ACTIVE; @@ -1373,8 +1521,6 @@ void transport_init_se_cmd( cmd->data_direction = data_direction; cmd->sam_task_attr = task_attr; cmd->sense_buffer = sense_buffer; - - cmd->state_active = false; } EXPORT_SYMBOL(transport_init_se_cmd); @@ -1404,11 +1550,11 @@ static int transport_check_alloc_task_attr(struct se_cmd *cmd) return 0; } -/* target_setup_cmd_from_cdb(): +/* transport_generic_allocate_tasks(): * * Called from fabric RX Thread. */ -int target_setup_cmd_from_cdb( +int transport_generic_allocate_tasks( struct se_cmd *cmd, unsigned char *cdb) { @@ -1474,7 +1620,7 @@ int target_setup_cmd_from_cdb( spin_unlock(&cmd->se_lun->lun_sep_lock); return 0; } -EXPORT_SYMBOL(target_setup_cmd_from_cdb); +EXPORT_SYMBOL(transport_generic_allocate_tasks); /* * Used by fabric module frontends to queue tasks directly. @@ -1555,8 +1701,6 @@ void target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, */ transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, data_length, data_dir, task_attr, sense); - if (flags & TARGET_SCF_UNKNOWN_SIZE) - se_cmd->unknown_data_length = 1; /* * Obtain struct se_cmd->cmd_kref reference and add new cmd to * se_sess->sess_cmd_list. A second kref_get here is necessary @@ -1582,18 +1726,11 @@ void target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, * Sanitize CDBs via transport_generic_cmd_sequencer() and * allocate the necessary tasks to complete the received CDB+data */ - rc = target_setup_cmd_from_cdb(se_cmd, cdb); + rc = transport_generic_allocate_tasks(se_cmd, cdb); if (rc != 0) { transport_generic_request_failure(se_cmd); return; } - - /* - * Check if we need to delay processing because of ALUA - * Active/NonOptimized primary access state.. - */ - core_alua_check_nonop_delay(se_cmd); - /* * Dispatch se_cmd descriptor to se_lun->lun_se_dev backend * for immediate execution of READs, otherwise wait for @@ -1735,30 +1872,72 @@ int transport_generic_handle_tmr( EXPORT_SYMBOL(transport_generic_handle_tmr); /* - * If the cmd is active, request it to be stopped and sleep until it + * If the task is active, request it to be stopped and sleep until it * has completed. */ -bool target_stop_cmd(struct se_cmd *cmd, unsigned long *flags) +bool target_stop_task(struct se_task *task, unsigned long *flags) { + struct se_cmd *cmd = task->task_se_cmd; bool was_active = false; - if (cmd->transport_state & CMD_T_BUSY) { - cmd->transport_state |= CMD_T_REQUEST_STOP; + if (task->task_flags & TF_ACTIVE) { + task->task_flags |= TF_REQUEST_STOP; spin_unlock_irqrestore(&cmd->t_state_lock, *flags); - pr_debug("cmd %p waiting to complete\n", cmd); - wait_for_completion(&cmd->task_stop_comp); - pr_debug("cmd %p stopped successfully\n", cmd); + pr_debug("Task %p waiting to complete\n", task); + wait_for_completion(&task->task_stop_comp); + pr_debug("Task %p stopped successfully\n", task); spin_lock_irqsave(&cmd->t_state_lock, *flags); - cmd->transport_state &= ~CMD_T_REQUEST_STOP; - cmd->transport_state &= ~CMD_T_BUSY; + atomic_dec(&cmd->t_task_cdbs_left); + task->task_flags &= ~(TF_ACTIVE | TF_REQUEST_STOP); was_active = true; } return was_active; } +static int transport_stop_tasks_for_cmd(struct se_cmd *cmd) +{ + struct se_task *task, *task_tmp; + unsigned long flags; + int ret = 0; + + pr_debug("ITT[0x%08x] - Stopping tasks\n", + cmd->se_tfo->get_task_tag(cmd)); + + /* + * No tasks remain in the execution queue + */ + spin_lock_irqsave(&cmd->t_state_lock, flags); + list_for_each_entry_safe(task, task_tmp, + &cmd->t_task_list, t_list) { + pr_debug("Processing task %p\n", task); + /* + * If the struct se_task has not been sent and is not active, + * remove the struct se_task from the execution queue. + */ + if (!(task->task_flags & (TF_ACTIVE | TF_SENT))) { + spin_unlock_irqrestore(&cmd->t_state_lock, + flags); + transport_remove_task_from_execute_queue(task, + cmd->se_dev); + + pr_debug("Task %p removed from execute queue\n", task); + spin_lock_irqsave(&cmd->t_state_lock, flags); + continue; + } + + if (!target_stop_task(task, &flags)) { + pr_debug("Task %p - did nothing\n", task); + ret++; + } + } + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + + return ret; +} + /* * Handle SAM-esque emulation for generic transport request failures. */ @@ -1772,7 +1951,13 @@ void transport_generic_request_failure(struct se_cmd *cmd) pr_debug("-----[ i_state: %d t_state: %d scsi_sense_reason: %d\n", cmd->se_tfo->get_cmd_state(cmd), cmd->t_state, cmd->scsi_sense_reason); - pr_debug("-----[ CMD_T_ACTIVE: %d CMD_T_STOP: %d CMD_T_SENT: %d\n", + pr_debug("-----[ t_tasks: %d t_task_cdbs_left: %d" + " t_task_cdbs_sent: %d t_task_cdbs_ex_left: %d --" + " CMD_T_ACTIVE: %d CMD_T_STOP: %d CMD_T_SENT: %d\n", + cmd->t_task_list_num, + atomic_read(&cmd->t_task_cdbs_left), + atomic_read(&cmd->t_task_cdbs_sent), + atomic_read(&cmd->t_task_cdbs_ex_left), (cmd->transport_state & CMD_T_ACTIVE) != 0, (cmd->transport_state & CMD_T_STOP) != 0, (cmd->transport_state & CMD_T_SENT) != 0); @@ -1971,7 +2156,7 @@ static inline int transport_execute_task_attr(struct se_cmd *cmd) * Called from fabric module context in transport_generic_new_cmd() and * transport_generic_process_write() */ -static void transport_execute_tasks(struct se_cmd *cmd) +static int transport_execute_tasks(struct se_cmd *cmd) { int add_tasks; struct se_device *se_dev = cmd->se_dev; @@ -1985,52 +2170,71 @@ static void transport_execute_tasks(struct se_cmd *cmd) * attribute for the tasks of the received struct se_cmd CDB */ add_tasks = transport_execute_task_attr(cmd); - if (add_tasks) { - __transport_execute_tasks(se_dev, cmd); - return; - } + if (!add_tasks) + goto execute_tasks; + /* + * __transport_execute_tasks() -> __transport_add_tasks_from_cmd() + * adds associated se_tasks while holding dev->execute_task_lock + * before I/O dispath to avoid a double spinlock access. + */ + __transport_execute_tasks(se_dev, cmd); + return 0; } + +execute_tasks: __transport_execute_tasks(se_dev, NULL); + return 0; } +/* + * Called to check struct se_device tcq depth window, and once open pull struct se_task + * from struct se_device->execute_task_list and + * + * Called from transport_processing_thread() + */ static int __transport_execute_tasks(struct se_device *dev, struct se_cmd *new_cmd) { int error; struct se_cmd *cmd = NULL; + struct se_task *task = NULL; unsigned long flags; check_depth: spin_lock_irq(&dev->execute_task_lock); if (new_cmd != NULL) - __target_add_to_execute_list(new_cmd); + __transport_add_tasks_from_cmd(new_cmd); - if (list_empty(&dev->execute_list)) { + if (list_empty(&dev->execute_task_list)) { spin_unlock_irq(&dev->execute_task_lock); return 0; } - cmd = list_first_entry(&dev->execute_list, struct se_cmd, execute_list); - __target_remove_from_execute_list(cmd); + task = list_first_entry(&dev->execute_task_list, + struct se_task, t_execute_list); + __transport_remove_task_from_execute_queue(task, dev); spin_unlock_irq(&dev->execute_task_lock); + cmd = task->task_se_cmd; spin_lock_irqsave(&cmd->t_state_lock, flags); - cmd->transport_state |= CMD_T_BUSY; - cmd->transport_state |= CMD_T_SENT; + task->task_flags |= (TF_ACTIVE | TF_SENT); + atomic_inc(&cmd->t_task_cdbs_sent); - spin_unlock_irqrestore(&cmd->t_state_lock, flags); + if (atomic_read(&cmd->t_task_cdbs_sent) == + cmd->t_task_list_num) + cmd->transport_state |= CMD_T_SENT; - if (cmd->execute_cmd) - error = cmd->execute_cmd(cmd); - else { - error = dev->transport->execute_cmd(cmd, cmd->t_data_sg, - cmd->t_data_nents, cmd->data_direction); - } + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + if (cmd->execute_task) + error = cmd->execute_task(task); + else + error = dev->transport->do_task(task); if (error != 0) { spin_lock_irqsave(&cmd->t_state_lock, flags); - cmd->transport_state &= ~CMD_T_BUSY; + task->task_flags &= ~TF_ACTIVE; cmd->transport_state &= ~CMD_T_SENT; spin_unlock_irqrestore(&cmd->t_state_lock, flags); + transport_stop_tasks_for_cmd(cmd); transport_generic_request_failure(cmd); } @@ -2188,12 +2392,12 @@ static inline u32 transport_get_size( } else /* bytes */ return sectors; } - +#if 0 pr_debug("Returning block_size: %u, sectors: %u == %u for" - " %s object\n", dev->se_sub_dev->se_dev_attrib.block_size, - sectors, dev->se_sub_dev->se_dev_attrib.block_size * sectors, - dev->transport->name); - + " %s object\n", dev->se_sub_dev->se_dev_attrib.block_size, sectors, + dev->se_sub_dev->se_dev_attrib.block_size * sectors, + dev->transport->name); +#endif return dev->se_sub_dev->se_dev_attrib.block_size * sectors; } @@ -2258,6 +2462,7 @@ static int transport_get_sense_data(struct se_cmd *cmd) { unsigned char *buffer = cmd->sense_buffer, *sense_buffer = NULL; struct se_device *dev = cmd->se_dev; + struct se_task *task = NULL, *task_tmp; unsigned long flags; u32 offset = 0; @@ -2272,37 +2477,44 @@ static int transport_get_sense_data(struct se_cmd *cmd) return 0; } - if (!(cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE)) - goto out; - - if (!dev->transport->get_sense_buffer) { - pr_err("dev->transport->get_sense_buffer is NULL\n"); - goto out; - } - - sense_buffer = dev->transport->get_sense_buffer(cmd); - if (!sense_buffer) { - pr_err("ITT 0x%08x cmd %p: Unable to locate" - " sense buffer for task with sense\n", - cmd->se_tfo->get_task_tag(cmd), cmd); - goto out; - } - - spin_unlock_irqrestore(&cmd->t_state_lock, flags); - - offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER); + list_for_each_entry_safe(task, task_tmp, + &cmd->t_task_list, t_list) { + if (!(task->task_flags & TF_HAS_SENSE)) + continue; - memcpy(&buffer[offset], sense_buffer, TRANSPORT_SENSE_BUFFER); + if (!dev->transport->get_sense_buffer) { + pr_err("dev->transport->get_sense_buffer" + " is NULL\n"); + continue; + } - /* Automatically padded */ - cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset; + sense_buffer = dev->transport->get_sense_buffer(task); + if (!sense_buffer) { + pr_err("ITT[0x%08x]_TASK[%p]: Unable to locate" + " sense buffer for task with sense\n", + cmd->se_tfo->get_task_tag(cmd), task); + continue; + } + spin_unlock_irqrestore(&cmd->t_state_lock, flags); - pr_debug("HBA_[%u]_PLUG[%s]: Set SAM STATUS: 0x%02x and sense\n", - dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status); - return 0; + offset = cmd->se_tfo->set_fabric_sense_len(cmd, + TRANSPORT_SENSE_BUFFER); -out: + memcpy(&buffer[offset], sense_buffer, + TRANSPORT_SENSE_BUFFER); + cmd->scsi_status = task->task_scsi_status; + /* Automatically padded */ + cmd->scsi_sense_length = + (TRANSPORT_SENSE_BUFFER + offset); + + pr_debug("HBA_[%u]_PLUG[%s]: Set SAM STATUS: 0x%02x" + " and sense\n", + dev->se_hba->hba_id, dev->transport->name, + cmd->scsi_status); + return 0; + } spin_unlock_irqrestore(&cmd->t_state_lock, flags); + return -1; } @@ -2369,7 +2581,7 @@ static int target_check_write_same_discard(unsigned char *flags, struct se_devic * Generic Command Sequencer that should work for most DAS transport * drivers. * - * Called from target_setup_cmd_from_cdb() in the $FABRIC_MOD + * Called from transport_generic_allocate_tasks() in the $FABRIC_MOD * RX Thread. * * FIXME: Need to support other SCSI OPCODES where as well. @@ -2403,10 +2615,11 @@ static int transport_generic_cmd_sequencer( * by the ALUA primary or secondary access state.. */ if (ret > 0) { +#if 0 pr_debug("[%s]: ALUA TG Port not available," " SenseKey: NOT_READY, ASC/ASCQ: 0x04/0x%02x\n", cmd->se_tfo->get_fabric_name(), alua_ascq); - +#endif transport_set_sense_codes(cmd, 0x04, alua_ascq); cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; cmd->scsi_sense_reason = TCM_CHECK_CONDITION_NOT_READY; @@ -2482,7 +2695,6 @@ static int transport_generic_cmd_sequencer( cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; break; case WRITE_10: - case WRITE_VERIFY: sectors = transport_get_sectors_10(cdb, cmd, §or_ret); if (sector_ret) goto out_unsupported_cdb; @@ -2584,7 +2796,7 @@ static int transport_generic_cmd_sequencer( if (target_check_write_same_discard(&cdb[10], dev) < 0) goto out_unsupported_cdb; if (!passthrough) - cmd->execute_cmd = target_emulate_write_same; + cmd->execute_task = target_emulate_write_same; break; default: pr_err("VARIABLE_LENGTH_CMD service action" @@ -2598,9 +2810,9 @@ static int transport_generic_cmd_sequencer( /* * Check for emulated MI_REPORT_TARGET_PGS. */ - if ((cdb[1] & 0x1f) == MI_REPORT_TARGET_PGS && + if (cdb[1] == MI_REPORT_TARGET_PGS && su_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) { - cmd->execute_cmd = + cmd->execute_task = target_emulate_report_target_port_groups; } size = (cdb[6] << 24) | (cdb[7] << 16) | @@ -2623,13 +2835,13 @@ static int transport_generic_cmd_sequencer( size = cdb[4]; cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; if (!passthrough) - cmd->execute_cmd = target_emulate_modesense; + cmd->execute_task = target_emulate_modesense; break; case MODE_SENSE_10: size = (cdb[7] << 8) + cdb[8]; cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; if (!passthrough) - cmd->execute_cmd = target_emulate_modesense; + cmd->execute_task = target_emulate_modesense; break; case GPCMD_READ_BUFFER_CAPACITY: case GPCMD_SEND_OPC: @@ -2651,13 +2863,13 @@ static int transport_generic_cmd_sequencer( break; case PERSISTENT_RESERVE_IN: if (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS) - cmd->execute_cmd = target_scsi3_emulate_pr_in; + cmd->execute_task = target_scsi3_emulate_pr_in; size = (cdb[7] << 8) + cdb[8]; cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; break; case PERSISTENT_RESERVE_OUT: if (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS) - cmd->execute_cmd = target_scsi3_emulate_pr_out; + cmd->execute_task = target_scsi3_emulate_pr_out; size = (cdb[7] << 8) + cdb[8]; cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; break; @@ -2678,7 +2890,7 @@ static int transport_generic_cmd_sequencer( */ if (cdb[1] == MO_SET_TARGET_PGS && su_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) { - cmd->execute_cmd = + cmd->execute_task = target_emulate_set_target_port_groups; } @@ -2700,7 +2912,7 @@ static int transport_generic_cmd_sequencer( cmd->sam_task_attr = MSG_HEAD_TAG; cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; if (!passthrough) - cmd->execute_cmd = target_emulate_inquiry; + cmd->execute_task = target_emulate_inquiry; break; case READ_BUFFER: size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8]; @@ -2710,7 +2922,7 @@ static int transport_generic_cmd_sequencer( size = READ_CAP_LEN; cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; if (!passthrough) - cmd->execute_cmd = target_emulate_readcapacity; + cmd->execute_task = target_emulate_readcapacity; break; case READ_MEDIA_SERIAL_NUMBER: case SECURITY_PROTOCOL_IN: @@ -2722,7 +2934,7 @@ static int transport_generic_cmd_sequencer( switch (cmd->t_task_cdb[1] & 0x1f) { case SAI_READ_CAPACITY_16: if (!passthrough) - cmd->execute_cmd = + cmd->execute_task = target_emulate_readcapacity_16; break; default: @@ -2765,7 +2977,7 @@ static int transport_generic_cmd_sequencer( size = cdb[4]; cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; if (!passthrough) - cmd->execute_cmd = target_emulate_request_sense; + cmd->execute_task = target_emulate_request_sense; break; case READ_ELEMENT_STATUS: size = 65536 * cdb[7] + 256 * cdb[8] + cdb[9]; @@ -2794,7 +3006,7 @@ static int transport_generic_cmd_sequencer( * emulation disabled. */ if (su_dev->t10_pr.res_type != SPC_PASSTHROUGH) - cmd->execute_cmd = target_scsi2_reservation_reserve; + cmd->execute_task = target_scsi2_reservation_reserve; cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB; break; case RELEASE: @@ -2809,7 +3021,7 @@ static int transport_generic_cmd_sequencer( size = cmd->data_length; if (su_dev->t10_pr.res_type != SPC_PASSTHROUGH) - cmd->execute_cmd = target_scsi2_reservation_release; + cmd->execute_task = target_scsi2_reservation_release; cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB; break; case SYNCHRONIZE_CACHE: @@ -2841,13 +3053,13 @@ static int transport_generic_cmd_sequencer( if (transport_cmd_get_valid_sectors(cmd) < 0) goto out_invalid_cdb_field; } - cmd->execute_cmd = target_emulate_synchronize_cache; + cmd->execute_task = target_emulate_synchronize_cache; break; case UNMAP: size = get_unaligned_be16(&cdb[7]); cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; if (!passthrough) - cmd->execute_cmd = target_emulate_unmap; + cmd->execute_task = target_emulate_unmap; break; case WRITE_SAME_16: sectors = transport_get_sectors_16(cdb, cmd, §or_ret); @@ -2867,7 +3079,7 @@ static int transport_generic_cmd_sequencer( if (target_check_write_same_discard(&cdb[1], dev) < 0) goto out_unsupported_cdb; if (!passthrough) - cmd->execute_cmd = target_emulate_write_same; + cmd->execute_task = target_emulate_write_same; break; case WRITE_SAME: sectors = transport_get_sectors_10(cdb, cmd, §or_ret); @@ -2890,7 +3102,7 @@ static int transport_generic_cmd_sequencer( if (target_check_write_same_discard(&cdb[1], dev) < 0) goto out_unsupported_cdb; if (!passthrough) - cmd->execute_cmd = target_emulate_write_same; + cmd->execute_task = target_emulate_write_same; break; case ALLOW_MEDIUM_REMOVAL: case ERASE: @@ -2903,7 +3115,7 @@ static int transport_generic_cmd_sequencer( case WRITE_FILEMARKS: cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB; if (!passthrough) - cmd->execute_cmd = target_emulate_noop; + cmd->execute_task = target_emulate_noop; break; case GPCMD_CLOSE_TRACK: case INITIALIZE_ELEMENT_STATUS: @@ -2913,7 +3125,7 @@ static int transport_generic_cmd_sequencer( cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB; break; case REPORT_LUNS: - cmd->execute_cmd = target_report_luns; + cmd->execute_task = target_report_luns; size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; /* * Do implict HEAD_OF_QUEUE processing for REPORT_LUNS @@ -2923,42 +3135,6 @@ static int transport_generic_cmd_sequencer( cmd->sam_task_attr = MSG_HEAD_TAG; cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; break; - case GET_EVENT_STATUS_NOTIFICATION: - size = (cdb[7] << 8) | cdb[8]; - cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; - break; - case ATA_16: - /* Only support ATA passthrough to pSCSI backends.. */ - if (!passthrough) - goto out_unsupported_cdb; - - /* T_LENGTH */ - switch (cdb[2] & 0x3) { - case 0x0: - sectors = 0; - break; - case 0x1: - sectors = (((cdb[1] & 0x1) ? cdb[3] : 0) << 8) | cdb[4]; - break; - case 0x2: - sectors = (((cdb[1] & 0x1) ? cdb[5] : 0) << 8) | cdb[6]; - break; - case 0x3: - pr_err("T_LENGTH=0x3 not supported for ATA_16\n"); - goto out_invalid_cdb_field; - } - - /* BYTE_BLOCK */ - if (cdb[2] & 0x4) { - /* BLOCK T_TYPE: 512 or sector */ - size = sectors * ((cdb[2] & 0x10) ? - dev->se_sub_dev->se_dev_attrib.block_size : 512); - } else { - /* BYTE */ - size = sectors; - } - cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; - break; default: pr_warn("TARGET_CORE[%s]: Unsupported SCSI Opcode" " 0x%02x, sending CHECK_CONDITION.\n", @@ -2966,9 +3142,6 @@ static int transport_generic_cmd_sequencer( goto out_unsupported_cdb; } - if (cmd->unknown_data_length) - cmd->data_length = size; - if (size != cmd->data_length) { pr_warn("TARGET_CORE[%s]: Expected Transfer Length:" " %u does not match SCSI CDB Length: %u for SAM Opcode:" @@ -3004,25 +3177,15 @@ static int transport_generic_cmd_sequencer( cmd->data_length = size; } - if (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) { - if (sectors > su_dev->se_dev_attrib.fabric_max_sectors) { - printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" - " big sectors %u exceeds fabric_max_sectors:" - " %u\n", cdb[0], sectors, - su_dev->se_dev_attrib.fabric_max_sectors); - goto out_invalid_cdb_field; - } - if (sectors > su_dev->se_dev_attrib.hw_max_sectors) { - printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" - " big sectors %u exceeds backend hw_max_sectors:" - " %u\n", cdb[0], sectors, - su_dev->se_dev_attrib.hw_max_sectors); - goto out_invalid_cdb_field; - } + if (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB && + sectors > dev->se_sub_dev->se_dev_attrib.fabric_max_sectors) { + printk_ratelimited(KERN_ERR "SCSI OP %02xh with too big sectors %u\n", + cdb[0], sectors); + goto out_invalid_cdb_field; } /* reject any command that we don't have a handler for */ - if (!(passthrough || cmd->execute_cmd || + if (!(passthrough || cmd->execute_task || (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB))) goto out_unsupported_cdb; @@ -3087,7 +3250,7 @@ static void transport_complete_task_attr(struct se_cmd *cmd) cmd_p->t_task_cdb[0], cmd_p->sam_task_attr, cmd_p->se_ordered_id); - target_add_to_execute_list(cmd_p); + transport_add_tasks_from_cmd(cmd_p); new_active_tasks++; spin_lock(&dev->delayed_cmd_lock); @@ -3183,6 +3346,10 @@ static void target_complete_ok_work(struct work_struct *work) if (transport_get_sense_data(cmd) < 0) reason = TCM_NON_EXISTENT_LUN; + /* + * Only set when an struct se_task->task_scsi_status returned + * a non GOOD status. + */ if (cmd->scsi_status) { ret = transport_send_check_condition_and_sense( cmd, reason, 1); @@ -3257,6 +3424,33 @@ static void target_complete_ok_work(struct work_struct *work) transport_handle_queue_full(cmd, cmd->se_dev); } +static void transport_free_dev_tasks(struct se_cmd *cmd) +{ + struct se_task *task, *task_tmp; + unsigned long flags; + LIST_HEAD(dispose_list); + + spin_lock_irqsave(&cmd->t_state_lock, flags); + list_for_each_entry_safe(task, task_tmp, + &cmd->t_task_list, t_list) { + if (!(task->task_flags & TF_ACTIVE)) + list_move_tail(&task->t_list, &dispose_list); + } + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + + while (!list_empty(&dispose_list)) { + task = list_first_entry(&dispose_list, struct se_task, t_list); + + if (task->task_sg != cmd->t_data_sg && + task->task_sg != cmd->t_bidi_data_sg) + kfree(task->task_sg); + + list_del(&task->t_list); + + cmd->se_dev->transport->free_task(task); + } +} + static inline void transport_free_sgl(struct scatterlist *sgl, int nents) { struct scatterlist *sg; @@ -3317,6 +3511,7 @@ static void transport_release_cmd(struct se_cmd *cmd) static void transport_put_cmd(struct se_cmd *cmd) { unsigned long flags; + int free_tasks = 0; spin_lock_irqsave(&cmd->t_state_lock, flags); if (atomic_read(&cmd->t_fe_count)) { @@ -3324,12 +3519,21 @@ static void transport_put_cmd(struct se_cmd *cmd) goto out_busy; } + if (atomic_read(&cmd->t_se_count)) { + if (!atomic_dec_and_test(&cmd->t_se_count)) + goto out_busy; + } + if (cmd->transport_state & CMD_T_DEV_ACTIVE) { cmd->transport_state &= ~CMD_T_DEV_ACTIVE; - target_remove_from_state_list(cmd); + transport_all_task_dev_remove_state(cmd); + free_tasks = 1; } spin_unlock_irqrestore(&cmd->t_state_lock, flags); + if (free_tasks != 0) + transport_free_dev_tasks(cmd); + transport_free_pages(cmd); transport_release_cmd(cmd); return; @@ -3479,14 +3683,245 @@ transport_generic_get_mem(struct se_cmd *cmd) return -ENOMEM; } +/* Reduce sectors if they are too long for the device */ +static inline sector_t transport_limit_task_sectors( + struct se_device *dev, + unsigned long long lba, + sector_t sectors) +{ + sectors = min_t(sector_t, sectors, dev->se_sub_dev->se_dev_attrib.max_sectors); + + if (dev->transport->get_device_type(dev) == TYPE_DISK) + if ((lba + sectors) > transport_dev_end_lba(dev)) + sectors = ((transport_dev_end_lba(dev) - lba) + 1); + + return sectors; +} + + +/* + * This function can be used by HW target mode drivers to create a linked + * scatterlist from all contiguously allocated struct se_task->task_sg[]. + * This is intended to be called during the completion path by TCM Core + * when struct target_core_fabric_ops->check_task_sg_chaining is enabled. + */ +void transport_do_task_sg_chain(struct se_cmd *cmd) +{ + struct scatterlist *sg_first = NULL; + struct scatterlist *sg_prev = NULL; + int sg_prev_nents = 0; + struct scatterlist *sg; + struct se_task *task; + u32 chained_nents = 0; + int i; + + BUG_ON(!cmd->se_tfo->task_sg_chaining); + + /* + * Walk the struct se_task list and setup scatterlist chains + * for each contiguously allocated struct se_task->task_sg[]. + */ + list_for_each_entry(task, &cmd->t_task_list, t_list) { + if (!task->task_sg) + continue; + + if (!sg_first) { + sg_first = task->task_sg; + chained_nents = task->task_sg_nents; + } else { + sg_chain(sg_prev, sg_prev_nents, task->task_sg); + chained_nents += task->task_sg_nents; + } + /* + * For the padded tasks, use the extra SGL vector allocated + * in transport_allocate_data_tasks() for the sg_prev_nents + * offset into sg_chain() above. + * + * We do not need the padding for the last task (or a single + * task), but in that case we will never use the sg_prev_nents + * value below which would be incorrect. + */ + sg_prev_nents = (task->task_sg_nents + 1); + sg_prev = task->task_sg; + } + /* + * Setup the starting pointer and total t_tasks_sg_linked_no including + * padding SGs for linking and to mark the end. + */ + cmd->t_tasks_sg_chained = sg_first; + cmd->t_tasks_sg_chained_no = chained_nents; + + pr_debug("Setup cmd: %p cmd->t_tasks_sg_chained: %p and" + " t_tasks_sg_chained_no: %u\n", cmd, cmd->t_tasks_sg_chained, + cmd->t_tasks_sg_chained_no); + + for_each_sg(cmd->t_tasks_sg_chained, sg, + cmd->t_tasks_sg_chained_no, i) { + + pr_debug("SG[%d]: %p page: %p length: %d offset: %d\n", + i, sg, sg_page(sg), sg->length, sg->offset); + if (sg_is_chain(sg)) + pr_debug("SG: %p sg_is_chain=1\n", sg); + if (sg_is_last(sg)) + pr_debug("SG: %p sg_is_last=1\n", sg); + } +} +EXPORT_SYMBOL(transport_do_task_sg_chain); + +/* + * Break up cmd into chunks transport can handle + */ +static int +transport_allocate_data_tasks(struct se_cmd *cmd, + enum dma_data_direction data_direction, + struct scatterlist *cmd_sg, unsigned int sgl_nents) +{ + struct se_device *dev = cmd->se_dev; + int task_count, i; + unsigned long long lba; + sector_t sectors, dev_max_sectors; + u32 sector_size; + + if (transport_cmd_get_valid_sectors(cmd) < 0) + return -EINVAL; + + dev_max_sectors = dev->se_sub_dev->se_dev_attrib.max_sectors; + sector_size = dev->se_sub_dev->se_dev_attrib.block_size; + + WARN_ON(cmd->data_length % sector_size); + + lba = cmd->t_task_lba; + sectors = DIV_ROUND_UP(cmd->data_length, sector_size); + task_count = DIV_ROUND_UP_SECTOR_T(sectors, dev_max_sectors); + + /* + * If we need just a single task reuse the SG list in the command + * and avoid a lot of work. + */ + if (task_count == 1) { + struct se_task *task; + unsigned long flags; + + task = transport_generic_get_task(cmd, data_direction); + if (!task) + return -ENOMEM; + + task->task_sg = cmd_sg; + task->task_sg_nents = sgl_nents; + + task->task_lba = lba; + task->task_sectors = sectors; + task->task_size = task->task_sectors * sector_size; + + spin_lock_irqsave(&cmd->t_state_lock, flags); + list_add_tail(&task->t_list, &cmd->t_task_list); + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + + return task_count; + } + + for (i = 0; i < task_count; i++) { + struct se_task *task; + unsigned int task_size, task_sg_nents_padded; + struct scatterlist *sg; + unsigned long flags; + int count; + + task = transport_generic_get_task(cmd, data_direction); + if (!task) + return -ENOMEM; + + task->task_lba = lba; + task->task_sectors = min(sectors, dev_max_sectors); + task->task_size = task->task_sectors * sector_size; + + /* + * This now assumes that passed sg_ents are in PAGE_SIZE chunks + * in order to calculate the number per task SGL entries + */ + task->task_sg_nents = DIV_ROUND_UP(task->task_size, PAGE_SIZE); + /* + * Check if the fabric module driver is requesting that all + * struct se_task->task_sg[] be chained together.. If so, + * then allocate an extra padding SG entry for linking and + * marking the end of the chained SGL for every task except + * the last one for (task_count > 1) operation, or skipping + * the extra padding for the (task_count == 1) case. + */ + if (cmd->se_tfo->task_sg_chaining && (i < (task_count - 1))) { + task_sg_nents_padded = (task->task_sg_nents + 1); + } else + task_sg_nents_padded = task->task_sg_nents; + + task->task_sg = kmalloc(sizeof(struct scatterlist) * + task_sg_nents_padded, GFP_KERNEL); + if (!task->task_sg) { + cmd->se_dev->transport->free_task(task); + return -ENOMEM; + } + + sg_init_table(task->task_sg, task_sg_nents_padded); + + task_size = task->task_size; + + /* Build new sgl, only up to task_size */ + for_each_sg(task->task_sg, sg, task->task_sg_nents, count) { + if (cmd_sg->length > task_size) + break; + + *sg = *cmd_sg; + task_size -= cmd_sg->length; + cmd_sg = sg_next(cmd_sg); + } + + lba += task->task_sectors; + sectors -= task->task_sectors; + + spin_lock_irqsave(&cmd->t_state_lock, flags); + list_add_tail(&task->t_list, &cmd->t_task_list); + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + } + + return task_count; +} + +static int +transport_allocate_control_task(struct se_cmd *cmd) +{ + struct se_task *task; + unsigned long flags; + + /* Workaround for handling zero-length control CDBs */ + if ((cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB) && + !cmd->data_length) + return 0; + + task = transport_generic_get_task(cmd, cmd->data_direction); + if (!task) + return -ENOMEM; + + task->task_sg = cmd->t_data_sg; + task->task_size = cmd->data_length; + task->task_sg_nents = cmd->t_data_nents; + + spin_lock_irqsave(&cmd->t_state_lock, flags); + list_add_tail(&task->t_list, &cmd->t_task_list); + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + + /* Success! Return number of tasks allocated */ + return 1; +} + /* - * Allocate any required resources to execute the command. For writes we - * might not have the payload yet, so notify the fabric via a call to - * ->write_pending instead. Otherwise place it on the execution queue. + * Allocate any required ressources to execute the command, and either place + * it on the execution queue if possible. For writes we might not have the + * payload yet, thus notify the fabric via a call to ->write_pending instead. */ int transport_generic_new_cmd(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; + int task_cdbs, task_cdbs_bidi = 0; + int set_counts = 1; int ret = 0; /* @@ -3501,9 +3936,35 @@ int transport_generic_new_cmd(struct se_cmd *cmd) goto out_fail; } - /* Workaround for handling zero-length control CDBs */ - if ((cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB) && - !cmd->data_length) { + /* + * For BIDI command set up the read tasks first. + */ + if (cmd->t_bidi_data_sg && + dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) { + BUG_ON(!(cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB)); + + task_cdbs_bidi = transport_allocate_data_tasks(cmd, + DMA_FROM_DEVICE, cmd->t_bidi_data_sg, + cmd->t_bidi_data_nents); + if (task_cdbs_bidi <= 0) + goto out_fail; + + atomic_inc(&cmd->t_fe_count); + atomic_inc(&cmd->t_se_count); + set_counts = 0; + } + + if (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) { + task_cdbs = transport_allocate_data_tasks(cmd, + cmd->data_direction, cmd->t_data_sg, + cmd->t_data_nents); + } else { + task_cdbs = transport_allocate_control_task(cmd); + } + + if (task_cdbs < 0) + goto out_fail; + else if (!task_cdbs && (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB)) { spin_lock_irq(&cmd->t_state_lock); cmd->t_state = TRANSPORT_COMPLETE; cmd->transport_state |= CMD_T_ACTIVE; @@ -3521,31 +3982,29 @@ int transport_generic_new_cmd(struct se_cmd *cmd) return 0; } - if (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) { - struct se_dev_attrib *attr = &dev->se_sub_dev->se_dev_attrib; - - if (transport_cmd_get_valid_sectors(cmd) < 0) - return -EINVAL; - - BUG_ON(cmd->data_length % attr->block_size); - BUG_ON(DIV_ROUND_UP(cmd->data_length, attr->block_size) > - attr->hw_max_sectors); + if (set_counts) { + atomic_inc(&cmd->t_fe_count); + atomic_inc(&cmd->t_se_count); } - atomic_inc(&cmd->t_fe_count); + cmd->t_task_list_num = (task_cdbs + task_cdbs_bidi); + atomic_set(&cmd->t_task_cdbs_left, cmd->t_task_list_num); + atomic_set(&cmd->t_task_cdbs_ex_left, cmd->t_task_list_num); /* - * For WRITEs, let the fabric know its buffer is ready. - * - * The command will be added to the execution queue after its write - * data has arrived. + * For WRITEs, let the fabric know its buffer is ready.. + * This WRITE struct se_cmd (and all of its associated struct se_task's) + * will be added to the struct se_device execution queue after its WRITE + * data has arrived. (ie: It gets handled by the transport processing + * thread a second time) */ if (cmd->data_direction == DMA_TO_DEVICE) { - target_add_to_state_list(cmd); + transport_add_tasks_to_state_queue(cmd); return transport_generic_write_pending(cmd); } /* - * Everything else but a WRITE, add the command to the execution queue. + * Everything else but a WRITE, add the struct se_cmd's struct se_task's + * to the execution queue. */ transport_execute_tasks(cmd); return 0; @@ -3632,6 +4091,8 @@ void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks) if (cmd->se_lun) transport_lun_remove_cmd(cmd); + transport_free_dev_tasks(cmd); + transport_put_cmd(cmd); } } @@ -3772,8 +4233,7 @@ EXPORT_SYMBOL(target_wait_for_sess_cmds); static int transport_lun_wait_for_tasks(struct se_cmd *cmd, struct se_lun *lun) { unsigned long flags; - int ret = 0; - + int ret; /* * If the frontend has already requested this struct se_cmd to * be stopped, we can safely ignore this struct se_cmd. @@ -3793,21 +4253,10 @@ static int transport_lun_wait_for_tasks(struct se_cmd *cmd, struct se_lun *lun) wake_up_interruptible(&cmd->se_dev->dev_queue_obj.thread_wq); - // XXX: audit task_flags checks. - spin_lock_irqsave(&cmd->t_state_lock, flags); - if ((cmd->transport_state & CMD_T_BUSY) && - (cmd->transport_state & CMD_T_SENT)) { - if (!target_stop_cmd(cmd, &flags)) - ret++; - spin_unlock_irqrestore(&cmd->t_state_lock, flags); - } else { - spin_unlock_irqrestore(&cmd->t_state_lock, - flags); - target_remove_from_execute_list(cmd); - } + ret = transport_stop_tasks_for_cmd(cmd); - pr_debug("ConfigFS: cmd: %p stop tasks ret:" - " %d\n", cmd, ret); + pr_debug("ConfigFS: cmd: %p t_tasks: %d stop tasks ret:" + " %d\n", cmd, cmd->t_task_list_num, ret); if (!ret) { pr_debug("ConfigFS: ITT[0x%08x] - stopping cmd....\n", cmd->se_tfo->get_task_tag(cmd)); @@ -3879,9 +4328,10 @@ static void __transport_clear_lun_from_sessions(struct se_lun *lun) goto check_cond; } cmd->transport_state &= ~CMD_T_DEV_ACTIVE; - target_remove_from_state_list(cmd); + transport_all_task_dev_remove_state(cmd); spin_unlock_irqrestore(&cmd->t_state_lock, cmd_flags); + transport_free_dev_tasks(cmd); /* * The Storage engine stopped this struct se_cmd before it was * send to the fabric frontend for delivery back to the @@ -3994,7 +4444,7 @@ bool transport_wait_for_tasks(struct se_cmd *cmd) wait_for_completion(&cmd->transport_lun_fe_stop_comp); spin_lock_irqsave(&cmd->t_state_lock, flags); - target_remove_from_state_list(cmd); + transport_all_task_dev_remove_state(cmd); /* * At this point, the frontend who was the originator of this * struct se_cmd, now owns the structure and can be released through @@ -4260,12 +4710,12 @@ int transport_check_aborted_status(struct se_cmd *cmd, int send_status) if (!send_status || (cmd->se_cmd_flags & SCF_SENT_DELAYED_TAS)) return 1; - +#if 0 pr_debug("Sending delayed SAM_STAT_TASK_ABORTED" " status for CDB: 0x%02x ITT: 0x%08x\n", cmd->t_task_cdb[0], cmd->se_tfo->get_task_tag(cmd)); - +#endif cmd->se_cmd_flags |= SCF_SENT_DELAYED_TAS; cmd->se_tfo->queue_status(cmd); ret = 1; @@ -4298,11 +4748,11 @@ void transport_send_task_abort(struct se_cmd *cmd) } } cmd->scsi_status = SAM_STAT_TASK_ABORTED; - +#if 0 pr_debug("Setting SAM_STAT_TASK_ABORTED status for CDB: 0x%02x," " ITT: 0x%08x\n", cmd->t_task_cdb[0], cmd->se_tfo->get_task_tag(cmd)); - +#endif cmd->se_tfo->queue_status(cmd); } @@ -4415,7 +4865,7 @@ static int transport_processing_thread(void *param) } out: - WARN_ON(!list_empty(&dev->state_list)); + WARN_ON(!list_empty(&dev->state_task_list)); WARN_ON(!list_empty(&dev->dev_queue_obj.qobj_list)); dev->process_thread = NULL; return 0; diff --git a/trunk/drivers/target/tcm_fc/tfc_cmd.c b/trunk/drivers/target/tcm_fc/tfc_cmd.c index f03fb9730f5b..a375f257aabc 100644 --- a/trunk/drivers/target/tcm_fc/tfc_cmd.c +++ b/trunk/drivers/target/tcm_fc/tfc_cmd.c @@ -215,10 +215,20 @@ int ft_write_pending(struct se_cmd *se_cmd) */ if ((ep->xid <= lport->lro_xid) && (fh->fh_r_ctl == FC_RCTL_DD_DATA_DESC)) { - if ((se_cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) && - lport->tt.ddp_target(lport, ep->xid, - se_cmd->t_data_sg, - se_cmd->t_data_nents)) + if (se_cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) { + /* + * cmd may have been broken up into multiple + * tasks. Link their sgs together so we can + * operate on them all at once. + */ + transport_do_task_sg_chain(se_cmd); + cmd->sg = se_cmd->t_tasks_sg_chained; + cmd->sg_cnt = + se_cmd->t_tasks_sg_chained_no; + } + if (cmd->sg && lport->tt.ddp_target(lport, ep->xid, + cmd->sg, + cmd->sg_cnt)) cmd->was_ddp_setup = 1; } } diff --git a/trunk/drivers/target/tcm_fc/tfc_conf.c b/trunk/drivers/target/tcm_fc/tfc_conf.c index 9501844fae2d..2948dc944619 100644 --- a/trunk/drivers/target/tcm_fc/tfc_conf.c +++ b/trunk/drivers/target/tcm_fc/tfc_conf.c @@ -576,6 +576,9 @@ int ft_register_configfs(void) } fabric->tf_ops = ft_fabric_ops; + /* Allowing support for task_sg_chaining */ + fabric->tf_ops.task_sg_chaining = 1; + /* * Setup default attribute lists for various fabric->tf_cit_tmpl */ diff --git a/trunk/drivers/target/tcm_fc/tfc_io.c b/trunk/drivers/target/tcm_fc/tfc_io.c index 071a505f98fc..dc7c0db26e20 100644 --- a/trunk/drivers/target/tcm_fc/tfc_io.c +++ b/trunk/drivers/target/tcm_fc/tfc_io.c @@ -228,7 +228,7 @@ void ft_recv_write_data(struct ft_cmd *cmd, struct fc_frame *fp) "payload, Frame will be dropped if" "'Sequence Initiative' bit in f_ctl is" "not set\n", __func__, ep->xid, f_ctl, - se_cmd->t_data_sg, se_cmd->t_data_nents); + cmd->sg, cmd->sg_cnt); /* * Invalidate HW DDP context if it was setup for respective * command. Invalidation of HW DDP context is requited in both diff --git a/trunk/drivers/tty/vt/keyboard.c b/trunk/drivers/tty/vt/keyboard.c index 3b0c4e32ed7b..29ca20dbd335 100644 --- a/trunk/drivers/tty/vt/keyboard.c +++ b/trunk/drivers/tty/vt/keyboard.c @@ -2044,7 +2044,7 @@ int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm) kbd->default_ledflagstate = ((arg >> 4) & 7); set_leds(); spin_unlock_irqrestore(&kbd_event_lock, flags); - return 0; + break; /* the ioctls below only set the lights, not the functions */ /* for those, see KDGKBLED and KDSKBLED above */ diff --git a/trunk/drivers/usb/gadget/Kconfig b/trunk/drivers/usb/gadget/Kconfig index 569b33e754ba..2633f7595116 100644 --- a/trunk/drivers/usb/gadget/Kconfig +++ b/trunk/drivers/usb/gadget/Kconfig @@ -798,16 +798,6 @@ config USB_MASS_STORAGE Say "y" to link the driver statically, or "m" to build a dynamically linked module called "g_mass_storage". -config USB_GADGET_TARGET - tristate "USB Gadget Target Fabric Module" - depends on TARGET_CORE - help - This fabric is an USB gadget. Two USB protocols are supported that is - BBB or BOT (Bulk Only Transport) and UAS (USB Attached SCSI). BOT is - advertised on alternative interface 0 (primary) and UAS is on - alternative interface 1. Both protocols can work on USB2.0 and USB3.0. - UAS utilizes the USB 3.0 feature called streams support. - config USB_G_SERIAL tristate "Serial Gadget (with CDC ACM and CDC OBEX support)" help diff --git a/trunk/drivers/usb/gadget/Makefile b/trunk/drivers/usb/gadget/Makefile index fc5b83683de5..b7f6eefc3927 100644 --- a/trunk/drivers/usb/gadget/Makefile +++ b/trunk/drivers/usb/gadget/Makefile @@ -52,7 +52,6 @@ g_nokia-y := nokia.o g_webcam-y := webcam.o g_ncm-y := ncm.o g_acm_ms-y := acm_ms.o -g_tcm_usb_gadget-y := tcm_usb_gadget.o obj-$(CONFIG_USB_ZERO) += g_zero.o obj-$(CONFIG_USB_AUDIO) += g_audio.o @@ -72,4 +71,3 @@ obj-$(CONFIG_USB_G_NOKIA) += g_nokia.o obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o obj-$(CONFIG_USB_G_NCM) += g_ncm.o obj-$(CONFIG_USB_G_ACM_MS) += g_acm_ms.o -obj-$(CONFIG_USB_GADGET_TARGET) += tcm_usb_gadget.o diff --git a/trunk/drivers/usb/gadget/f_rndis.c b/trunk/drivers/usb/gadget/f_rndis.c index d4f823f463e9..52343654f5df 100644 --- a/trunk/drivers/usb/gadget/f_rndis.c +++ b/trunk/drivers/usb/gadget/f_rndis.c @@ -637,7 +637,7 @@ static void rndis_open(struct gether *geth) DBG(cdev, "%s\n", __func__); - rndis_set_param_medium(rndis->config, RNDIS_MEDIUM_802_3, + rndis_set_param_medium(rndis->config, NDIS_MEDIUM_802_3, bitrate(cdev->gadget) / 100); rndis_signal_connect(rndis->config); } @@ -648,7 +648,7 @@ static void rndis_close(struct gether *geth) DBG(geth->func.config->cdev, "%s\n", __func__); - rndis_set_param_medium(rndis->config, RNDIS_MEDIUM_802_3, 0); + rndis_set_param_medium(rndis->config, NDIS_MEDIUM_802_3, 0); rndis_signal_disconnect(rndis->config); } @@ -765,7 +765,7 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) goto fail; rndis->config = status; - rndis_set_param_medium(rndis->config, RNDIS_MEDIUM_802_3, 0); + rndis_set_param_medium(rndis->config, NDIS_MEDIUM_802_3, 0); rndis_set_host_mac(rndis->config, rndis->ethaddr); #if 0 diff --git a/trunk/drivers/usb/gadget/ndis.h b/trunk/drivers/usb/gadget/ndis.h index a19f72dec0cd..b0e52fc277b4 100644 --- a/trunk/drivers/usb/gadget/ndis.h +++ b/trunk/drivers/usb/gadget/ndis.h @@ -15,6 +15,11 @@ #ifndef _LINUX_NDIS_H #define _LINUX_NDIS_H + +#define NDIS_STATUS_MULTICAST_FULL 0xC0010009 +#define NDIS_STATUS_MULTICAST_EXISTS 0xC001000A +#define NDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B + enum NDIS_DEVICE_POWER_STATE { NdisDeviceStateUnspecified = 0, NdisDeviceStateD0, @@ -30,6 +35,11 @@ struct NDIS_PM_WAKE_UP_CAPABILITIES { enum NDIS_DEVICE_POWER_STATE MinLinkChangeWakeUp; }; +/* NDIS_PNP_CAPABILITIES.Flags constants */ +#define NDIS_DEVICE_WAKE_UP_ENABLE 0x00000001 +#define NDIS_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002 +#define NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004 + struct NDIS_PNP_CAPABILITIES { __le32 Flags; struct NDIS_PM_WAKE_UP_CAPABILITIES WakeUpCapabilities; @@ -44,4 +54,158 @@ struct NDIS_PM_PACKET_PATTERN { __le32 PatternFlags; }; + +/* Required Object IDs (OIDs) */ +#define OID_GEN_SUPPORTED_LIST 0x00010101 +#define OID_GEN_HARDWARE_STATUS 0x00010102 +#define OID_GEN_MEDIA_SUPPORTED 0x00010103 +#define OID_GEN_MEDIA_IN_USE 0x00010104 +#define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 +#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 +#define OID_GEN_LINK_SPEED 0x00010107 +#define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 +#define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 +#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A +#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B +#define OID_GEN_VENDOR_ID 0x0001010C +#define OID_GEN_VENDOR_DESCRIPTION 0x0001010D +#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E +#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F +#define OID_GEN_DRIVER_VERSION 0x00010110 +#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 +#define OID_GEN_PROTOCOL_OPTIONS 0x00010112 +#define OID_GEN_MAC_OPTIONS 0x00010113 +#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 +#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 +#define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116 +#define OID_GEN_SUPPORTED_GUIDS 0x00010117 +#define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118 +#define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119 +#define OID_GEN_MACHINE_NAME 0x0001021A +#define OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B +#define OID_GEN_VLAN_ID 0x0001021C + +/* Optional OIDs */ +#define OID_GEN_MEDIA_CAPABILITIES 0x00010201 +#define OID_GEN_PHYSICAL_MEDIUM 0x00010202 + +/* Required statistics OIDs */ +#define OID_GEN_XMIT_OK 0x00020101 +#define OID_GEN_RCV_OK 0x00020102 +#define OID_GEN_XMIT_ERROR 0x00020103 +#define OID_GEN_RCV_ERROR 0x00020104 +#define OID_GEN_RCV_NO_BUFFER 0x00020105 + +/* Optional statistics OIDs */ +#define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 +#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 +#define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 +#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 +#define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 +#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 +#define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 +#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 +#define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 +#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A +#define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B +#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C +#define OID_GEN_RCV_CRC_ERROR 0x0002020D +#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E +#define OID_GEN_GET_TIME_CAPS 0x0002020F +#define OID_GEN_GET_NETCARD_TIME 0x00020210 +#define OID_GEN_NETCARD_LOAD 0x00020211 +#define OID_GEN_DEVICE_PROFILE 0x00020212 +#define OID_GEN_INIT_TIME_MS 0x00020213 +#define OID_GEN_RESET_COUNTS 0x00020214 +#define OID_GEN_MEDIA_SENSE_COUNTS 0x00020215 +#define OID_GEN_FRIENDLY_NAME 0x00020216 +#define OID_GEN_MINIPORT_INFO 0x00020217 +#define OID_GEN_RESET_VERIFY_PARAMETERS 0x00020218 + +/* IEEE 802.3 (Ethernet) OIDs */ +#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001 + +#define OID_802_3_PERMANENT_ADDRESS 0x01010101 +#define OID_802_3_CURRENT_ADDRESS 0x01010102 +#define OID_802_3_MULTICAST_LIST 0x01010103 +#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 +#define OID_802_3_MAC_OPTIONS 0x01010105 +#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 +#define OID_802_3_XMIT_ONE_COLLISION 0x01020102 +#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 +#define OID_802_3_XMIT_DEFERRED 0x01020201 +#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 +#define OID_802_3_RCV_OVERRUN 0x01020203 +#define OID_802_3_XMIT_UNDERRUN 0x01020204 +#define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 +#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 +#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 + +/* OID_GEN_MINIPORT_INFO constants */ +#define NDIS_MINIPORT_BUS_MASTER 0x00000001 +#define NDIS_MINIPORT_WDM_DRIVER 0x00000002 +#define NDIS_MINIPORT_SG_LIST 0x00000004 +#define NDIS_MINIPORT_SUPPORTS_MEDIA_QUERY 0x00000008 +#define NDIS_MINIPORT_INDICATES_PACKETS 0x00000010 +#define NDIS_MINIPORT_IGNORE_PACKET_QUEUE 0x00000020 +#define NDIS_MINIPORT_IGNORE_REQUEST_QUEUE 0x00000040 +#define NDIS_MINIPORT_IGNORE_TOKEN_RING_ERRORS 0x00000080 +#define NDIS_MINIPORT_INTERMEDIATE_DRIVER 0x00000100 +#define NDIS_MINIPORT_IS_NDIS_5 0x00000200 +#define NDIS_MINIPORT_IS_CO 0x00000400 +#define NDIS_MINIPORT_DESERIALIZE 0x00000800 +#define NDIS_MINIPORT_REQUIRES_MEDIA_POLLING 0x00001000 +#define NDIS_MINIPORT_SUPPORTS_MEDIA_SENSE 0x00002000 +#define NDIS_MINIPORT_NETBOOT_CARD 0x00004000 +#define NDIS_MINIPORT_PM_SUPPORTED 0x00008000 +#define NDIS_MINIPORT_SUPPORTS_MAC_ADDRESS_OVERWRITE 0x00010000 +#define NDIS_MINIPORT_USES_SAFE_BUFFER_APIS 0x00020000 +#define NDIS_MINIPORT_HIDDEN 0x00040000 +#define NDIS_MINIPORT_SWENUM 0x00080000 +#define NDIS_MINIPORT_SURPRISE_REMOVE_OK 0x00100000 +#define NDIS_MINIPORT_NO_HALT_ON_SUSPEND 0x00200000 +#define NDIS_MINIPORT_HARDWARE_DEVICE 0x00400000 +#define NDIS_MINIPORT_SUPPORTS_CANCEL_SEND_PACKETS 0x00800000 +#define NDIS_MINIPORT_64BITS_DMA 0x01000000 + +#define NDIS_MEDIUM_802_3 0x00000000 +#define NDIS_MEDIUM_802_5 0x00000001 +#define NDIS_MEDIUM_FDDI 0x00000002 +#define NDIS_MEDIUM_WAN 0x00000003 +#define NDIS_MEDIUM_LOCAL_TALK 0x00000004 +#define NDIS_MEDIUM_DIX 0x00000005 +#define NDIS_MEDIUM_ARCENT_RAW 0x00000006 +#define NDIS_MEDIUM_ARCENT_878_2 0x00000007 +#define NDIS_MEDIUM_ATM 0x00000008 +#define NDIS_MEDIUM_WIRELESS_LAN 0x00000009 +#define NDIS_MEDIUM_IRDA 0x0000000A +#define NDIS_MEDIUM_BPC 0x0000000B +#define NDIS_MEDIUM_CO_WAN 0x0000000C +#define NDIS_MEDIUM_1394 0x0000000D + +#define NDIS_PACKET_TYPE_DIRECTED 0x00000001 +#define NDIS_PACKET_TYPE_MULTICAST 0x00000002 +#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004 +#define NDIS_PACKET_TYPE_BROADCAST 0x00000008 +#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010 +#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020 +#define NDIS_PACKET_TYPE_SMT 0x00000040 +#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080 +#define NDIS_PACKET_TYPE_GROUP 0x00000100 +#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00000200 +#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00000400 +#define NDIS_PACKET_TYPE_MAC_FRAME 0x00000800 + +#define NDIS_MEDIA_STATE_CONNECTED 0x00000000 +#define NDIS_MEDIA_STATE_DISCONNECTED 0x00000001 + +#define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001 +#define NDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002 +#define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004 +#define NDIS_MAC_OPTION_NO_LOOPBACK 0x00000008 +#define NDIS_MAC_OPTION_FULL_DUPLEX 0x00000010 +#define NDIS_MAC_OPTION_EOTX_INDICATION 0x00000020 +#define NDIS_MAC_OPTION_8021P_PRIORITY 0x00000040 +#define NDIS_MAC_OPTION_RESERVED 0x80000000 + #endif /* _LINUX_NDIS_H */ diff --git a/trunk/drivers/usb/gadget/rndis.c b/trunk/drivers/usb/gadget/rndis.c index b35babed6fcb..73a934a170d1 100644 --- a/trunk/drivers/usb/gadget/rndis.c +++ b/trunk/drivers/usb/gadget/rndis.c @@ -73,65 +73,65 @@ static rndis_resp_t *rndis_add_response(int configNr, u32 length); static const u32 oid_supported_list[] = { /* the general stuff */ - RNDIS_OID_GEN_SUPPORTED_LIST, - RNDIS_OID_GEN_HARDWARE_STATUS, - RNDIS_OID_GEN_MEDIA_SUPPORTED, - RNDIS_OID_GEN_MEDIA_IN_USE, - RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE, - RNDIS_OID_GEN_LINK_SPEED, - RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE, - RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE, - RNDIS_OID_GEN_VENDOR_ID, - RNDIS_OID_GEN_VENDOR_DESCRIPTION, - RNDIS_OID_GEN_VENDOR_DRIVER_VERSION, - RNDIS_OID_GEN_CURRENT_PACKET_FILTER, - RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE, - RNDIS_OID_GEN_MEDIA_CONNECT_STATUS, - RNDIS_OID_GEN_PHYSICAL_MEDIUM, + OID_GEN_SUPPORTED_LIST, + OID_GEN_HARDWARE_STATUS, + OID_GEN_MEDIA_SUPPORTED, + OID_GEN_MEDIA_IN_USE, + OID_GEN_MAXIMUM_FRAME_SIZE, + OID_GEN_LINK_SPEED, + OID_GEN_TRANSMIT_BLOCK_SIZE, + OID_GEN_RECEIVE_BLOCK_SIZE, + OID_GEN_VENDOR_ID, + OID_GEN_VENDOR_DESCRIPTION, + OID_GEN_VENDOR_DRIVER_VERSION, + OID_GEN_CURRENT_PACKET_FILTER, + OID_GEN_MAXIMUM_TOTAL_SIZE, + OID_GEN_MEDIA_CONNECT_STATUS, + OID_GEN_PHYSICAL_MEDIUM, /* the statistical stuff */ - RNDIS_OID_GEN_XMIT_OK, - RNDIS_OID_GEN_RCV_OK, - RNDIS_OID_GEN_XMIT_ERROR, - RNDIS_OID_GEN_RCV_ERROR, - RNDIS_OID_GEN_RCV_NO_BUFFER, + OID_GEN_XMIT_OK, + OID_GEN_RCV_OK, + OID_GEN_XMIT_ERROR, + OID_GEN_RCV_ERROR, + OID_GEN_RCV_NO_BUFFER, #ifdef RNDIS_OPTIONAL_STATS - RNDIS_OID_GEN_DIRECTED_BYTES_XMIT, - RNDIS_OID_GEN_DIRECTED_FRAMES_XMIT, - RNDIS_OID_GEN_MULTICAST_BYTES_XMIT, - RNDIS_OID_GEN_MULTICAST_FRAMES_XMIT, - RNDIS_OID_GEN_BROADCAST_BYTES_XMIT, - RNDIS_OID_GEN_BROADCAST_FRAMES_XMIT, - RNDIS_OID_GEN_DIRECTED_BYTES_RCV, - RNDIS_OID_GEN_DIRECTED_FRAMES_RCV, - RNDIS_OID_GEN_MULTICAST_BYTES_RCV, - RNDIS_OID_GEN_MULTICAST_FRAMES_RCV, - RNDIS_OID_GEN_BROADCAST_BYTES_RCV, - RNDIS_OID_GEN_BROADCAST_FRAMES_RCV, - RNDIS_OID_GEN_RCV_CRC_ERROR, - RNDIS_OID_GEN_TRANSMIT_QUEUE_LENGTH, + OID_GEN_DIRECTED_BYTES_XMIT, + OID_GEN_DIRECTED_FRAMES_XMIT, + OID_GEN_MULTICAST_BYTES_XMIT, + OID_GEN_MULTICAST_FRAMES_XMIT, + OID_GEN_BROADCAST_BYTES_XMIT, + OID_GEN_BROADCAST_FRAMES_XMIT, + OID_GEN_DIRECTED_BYTES_RCV, + OID_GEN_DIRECTED_FRAMES_RCV, + OID_GEN_MULTICAST_BYTES_RCV, + OID_GEN_MULTICAST_FRAMES_RCV, + OID_GEN_BROADCAST_BYTES_RCV, + OID_GEN_BROADCAST_FRAMES_RCV, + OID_GEN_RCV_CRC_ERROR, + OID_GEN_TRANSMIT_QUEUE_LENGTH, #endif /* RNDIS_OPTIONAL_STATS */ /* mandatory 802.3 */ /* the general stuff */ - RNDIS_OID_802_3_PERMANENT_ADDRESS, - RNDIS_OID_802_3_CURRENT_ADDRESS, - RNDIS_OID_802_3_MULTICAST_LIST, - RNDIS_OID_802_3_MAC_OPTIONS, - RNDIS_OID_802_3_MAXIMUM_LIST_SIZE, + OID_802_3_PERMANENT_ADDRESS, + OID_802_3_CURRENT_ADDRESS, + OID_802_3_MULTICAST_LIST, + OID_802_3_MAC_OPTIONS, + OID_802_3_MAXIMUM_LIST_SIZE, /* the statistical stuff */ - RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT, - RNDIS_OID_802_3_XMIT_ONE_COLLISION, - RNDIS_OID_802_3_XMIT_MORE_COLLISIONS, + OID_802_3_RCV_ERROR_ALIGNMENT, + OID_802_3_XMIT_ONE_COLLISION, + OID_802_3_XMIT_MORE_COLLISIONS, #ifdef RNDIS_OPTIONAL_STATS - RNDIS_OID_802_3_XMIT_DEFERRED, - RNDIS_OID_802_3_XMIT_MAX_COLLISIONS, - RNDIS_OID_802_3_RCV_OVERRUN, - RNDIS_OID_802_3_XMIT_UNDERRUN, - RNDIS_OID_802_3_XMIT_HEARTBEAT_FAILURE, - RNDIS_OID_802_3_XMIT_TIMES_CRS_LOST, - RNDIS_OID_802_3_XMIT_LATE_COLLISIONS, + OID_802_3_XMIT_DEFERRED, + OID_802_3_XMIT_MAX_COLLISIONS, + OID_802_3_RCV_OVERRUN, + OID_802_3_XMIT_UNDERRUN, + OID_802_3_XMIT_HEARTBEAT_FAILURE, + OID_802_3_XMIT_TIMES_CRS_LOST, + OID_802_3_XMIT_LATE_COLLISIONS, #endif /* RNDIS_OPTIONAL_STATS */ #ifdef RNDIS_PM @@ -200,8 +200,8 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, /* general oids (table 4-1) */ /* mandatory */ - case RNDIS_OID_GEN_SUPPORTED_LIST: - pr_debug("%s: RNDIS_OID_GEN_SUPPORTED_LIST\n", __func__); + case OID_GEN_SUPPORTED_LIST: + pr_debug("%s: OID_GEN_SUPPORTED_LIST\n", __func__); length = sizeof(oid_supported_list); count = length / sizeof(u32); for (i = 0; i < count; i++) @@ -210,8 +210,8 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, break; /* mandatory */ - case RNDIS_OID_GEN_HARDWARE_STATUS: - pr_debug("%s: RNDIS_OID_GEN_HARDWARE_STATUS\n", __func__); + case OID_GEN_HARDWARE_STATUS: + pr_debug("%s: OID_GEN_HARDWARE_STATUS\n", __func__); /* Bogus question! * Hardware must be ready to receive high level protocols. * BTW: @@ -223,23 +223,23 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, break; /* mandatory */ - case RNDIS_OID_GEN_MEDIA_SUPPORTED: - pr_debug("%s: RNDIS_OID_GEN_MEDIA_SUPPORTED\n", __func__); + case OID_GEN_MEDIA_SUPPORTED: + pr_debug("%s: OID_GEN_MEDIA_SUPPORTED\n", __func__); *outbuf = cpu_to_le32(rndis_per_dev_params[configNr].medium); retval = 0; break; /* mandatory */ - case RNDIS_OID_GEN_MEDIA_IN_USE: - pr_debug("%s: RNDIS_OID_GEN_MEDIA_IN_USE\n", __func__); + case OID_GEN_MEDIA_IN_USE: + pr_debug("%s: OID_GEN_MEDIA_IN_USE\n", __func__); /* one medium, one transport... (maybe you do it better) */ *outbuf = cpu_to_le32(rndis_per_dev_params[configNr].medium); retval = 0; break; /* mandatory */ - case RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE: - pr_debug("%s: RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__); + case OID_GEN_MAXIMUM_FRAME_SIZE: + pr_debug("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__); if (rndis_per_dev_params[configNr].dev) { *outbuf = cpu_to_le32( rndis_per_dev_params[configNr].dev->mtu); @@ -248,11 +248,11 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, break; /* mandatory */ - case RNDIS_OID_GEN_LINK_SPEED: + case OID_GEN_LINK_SPEED: if (rndis_debug > 1) - pr_debug("%s: RNDIS_OID_GEN_LINK_SPEED\n", __func__); + pr_debug("%s: OID_GEN_LINK_SPEED\n", __func__); if (rndis_per_dev_params[configNr].media_state - == RNDIS_MEDIA_STATE_DISCONNECTED) + == NDIS_MEDIA_STATE_DISCONNECTED) *outbuf = cpu_to_le32(0); else *outbuf = cpu_to_le32( @@ -261,8 +261,8 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, break; /* mandatory */ - case RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE: - pr_debug("%s: RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__); + case OID_GEN_TRANSMIT_BLOCK_SIZE: + pr_debug("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__); if (rndis_per_dev_params[configNr].dev) { *outbuf = cpu_to_le32( rndis_per_dev_params[configNr].dev->mtu); @@ -271,8 +271,8 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, break; /* mandatory */ - case RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE: - pr_debug("%s: RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__); + case OID_GEN_RECEIVE_BLOCK_SIZE: + pr_debug("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__); if (rndis_per_dev_params[configNr].dev) { *outbuf = cpu_to_le32( rndis_per_dev_params[configNr].dev->mtu); @@ -281,16 +281,16 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, break; /* mandatory */ - case RNDIS_OID_GEN_VENDOR_ID: - pr_debug("%s: RNDIS_OID_GEN_VENDOR_ID\n", __func__); + case OID_GEN_VENDOR_ID: + pr_debug("%s: OID_GEN_VENDOR_ID\n", __func__); *outbuf = cpu_to_le32( rndis_per_dev_params[configNr].vendorID); retval = 0; break; /* mandatory */ - case RNDIS_OID_GEN_VENDOR_DESCRIPTION: - pr_debug("%s: RNDIS_OID_GEN_VENDOR_DESCRIPTION\n", __func__); + case OID_GEN_VENDOR_DESCRIPTION: + pr_debug("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__); if (rndis_per_dev_params[configNr].vendorDescr) { length = strlen(rndis_per_dev_params[configNr]. vendorDescr); @@ -303,38 +303,38 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, retval = 0; break; - case RNDIS_OID_GEN_VENDOR_DRIVER_VERSION: - pr_debug("%s: RNDIS_OID_GEN_VENDOR_DRIVER_VERSION\n", __func__); + case OID_GEN_VENDOR_DRIVER_VERSION: + pr_debug("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __func__); /* Created as LE */ *outbuf = rndis_driver_version; retval = 0; break; /* mandatory */ - case RNDIS_OID_GEN_CURRENT_PACKET_FILTER: - pr_debug("%s: RNDIS_OID_GEN_CURRENT_PACKET_FILTER\n", __func__); + case OID_GEN_CURRENT_PACKET_FILTER: + pr_debug("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __func__); *outbuf = cpu_to_le32(*rndis_per_dev_params[configNr].filter); retval = 0; break; /* mandatory */ - case RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE: - pr_debug("%s: RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__); + case OID_GEN_MAXIMUM_TOTAL_SIZE: + pr_debug("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__); *outbuf = cpu_to_le32(RNDIS_MAX_TOTAL_SIZE); retval = 0; break; /* mandatory */ - case RNDIS_OID_GEN_MEDIA_CONNECT_STATUS: + case OID_GEN_MEDIA_CONNECT_STATUS: if (rndis_debug > 1) - pr_debug("%s: RNDIS_OID_GEN_MEDIA_CONNECT_STATUS\n", __func__); + pr_debug("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __func__); *outbuf = cpu_to_le32(rndis_per_dev_params[configNr] .media_state); retval = 0; break; - case RNDIS_OID_GEN_PHYSICAL_MEDIUM: - pr_debug("%s: RNDIS_OID_GEN_PHYSICAL_MEDIUM\n", __func__); + case OID_GEN_PHYSICAL_MEDIUM: + pr_debug("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__); *outbuf = cpu_to_le32(0); retval = 0; break; @@ -343,20 +343,20 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, * of MS-Windows expect OIDs that aren't specified there. Other * versions emit undefined RNDIS messages. DOCUMENT ALL THESE! */ - case RNDIS_OID_GEN_MAC_OPTIONS: /* from WinME */ - pr_debug("%s: RNDIS_OID_GEN_MAC_OPTIONS\n", __func__); + case OID_GEN_MAC_OPTIONS: /* from WinME */ + pr_debug("%s: OID_GEN_MAC_OPTIONS\n", __func__); *outbuf = cpu_to_le32( - RNDIS_MAC_OPTION_RECEIVE_SERIALIZED - | RNDIS_MAC_OPTION_FULL_DUPLEX); + NDIS_MAC_OPTION_RECEIVE_SERIALIZED + | NDIS_MAC_OPTION_FULL_DUPLEX); retval = 0; break; /* statistics OIDs (table 4-2) */ /* mandatory */ - case RNDIS_OID_GEN_XMIT_OK: + case OID_GEN_XMIT_OK: if (rndis_debug > 1) - pr_debug("%s: RNDIS_OID_GEN_XMIT_OK\n", __func__); + pr_debug("%s: OID_GEN_XMIT_OK\n", __func__); if (stats) { *outbuf = cpu_to_le32(stats->tx_packets - stats->tx_errors - stats->tx_dropped); @@ -365,9 +365,9 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, break; /* mandatory */ - case RNDIS_OID_GEN_RCV_OK: + case OID_GEN_RCV_OK: if (rndis_debug > 1) - pr_debug("%s: RNDIS_OID_GEN_RCV_OK\n", __func__); + pr_debug("%s: OID_GEN_RCV_OK\n", __func__); if (stats) { *outbuf = cpu_to_le32(stats->rx_packets - stats->rx_errors - stats->rx_dropped); @@ -376,9 +376,9 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, break; /* mandatory */ - case RNDIS_OID_GEN_XMIT_ERROR: + case OID_GEN_XMIT_ERROR: if (rndis_debug > 1) - pr_debug("%s: RNDIS_OID_GEN_XMIT_ERROR\n", __func__); + pr_debug("%s: OID_GEN_XMIT_ERROR\n", __func__); if (stats) { *outbuf = cpu_to_le32(stats->tx_errors); retval = 0; @@ -386,9 +386,9 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, break; /* mandatory */ - case RNDIS_OID_GEN_RCV_ERROR: + case OID_GEN_RCV_ERROR: if (rndis_debug > 1) - pr_debug("%s: RNDIS_OID_GEN_RCV_ERROR\n", __func__); + pr_debug("%s: OID_GEN_RCV_ERROR\n", __func__); if (stats) { *outbuf = cpu_to_le32(stats->rx_errors); retval = 0; @@ -396,8 +396,8 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, break; /* mandatory */ - case RNDIS_OID_GEN_RCV_NO_BUFFER: - pr_debug("%s: RNDIS_OID_GEN_RCV_NO_BUFFER\n", __func__); + case OID_GEN_RCV_NO_BUFFER: + pr_debug("%s: OID_GEN_RCV_NO_BUFFER\n", __func__); if (stats) { *outbuf = cpu_to_le32(stats->rx_dropped); retval = 0; @@ -407,8 +407,8 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, /* ieee802.3 OIDs (table 4-3) */ /* mandatory */ - case RNDIS_OID_802_3_PERMANENT_ADDRESS: - pr_debug("%s: RNDIS_OID_802_3_PERMANENT_ADDRESS\n", __func__); + case OID_802_3_PERMANENT_ADDRESS: + pr_debug("%s: OID_802_3_PERMANENT_ADDRESS\n", __func__); if (rndis_per_dev_params[configNr].dev) { length = ETH_ALEN; memcpy(outbuf, @@ -419,8 +419,8 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, break; /* mandatory */ - case RNDIS_OID_802_3_CURRENT_ADDRESS: - pr_debug("%s: RNDIS_OID_802_3_CURRENT_ADDRESS\n", __func__); + case OID_802_3_CURRENT_ADDRESS: + pr_debug("%s: OID_802_3_CURRENT_ADDRESS\n", __func__); if (rndis_per_dev_params[configNr].dev) { length = ETH_ALEN; memcpy(outbuf, @@ -431,23 +431,23 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, break; /* mandatory */ - case RNDIS_OID_802_3_MULTICAST_LIST: - pr_debug("%s: RNDIS_OID_802_3_MULTICAST_LIST\n", __func__); + case OID_802_3_MULTICAST_LIST: + pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__); /* Multicast base address only */ *outbuf = cpu_to_le32(0xE0000000); retval = 0; break; /* mandatory */ - case RNDIS_OID_802_3_MAXIMUM_LIST_SIZE: - pr_debug("%s: RNDIS_OID_802_3_MAXIMUM_LIST_SIZE\n", __func__); + case OID_802_3_MAXIMUM_LIST_SIZE: + pr_debug("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__); /* Multicast base address only */ *outbuf = cpu_to_le32(1); retval = 0; break; - case RNDIS_OID_802_3_MAC_OPTIONS: - pr_debug("%s: RNDIS_OID_802_3_MAC_OPTIONS\n", __func__); + case OID_802_3_MAC_OPTIONS: + pr_debug("%s: OID_802_3_MAC_OPTIONS\n", __func__); *outbuf = cpu_to_le32(0); retval = 0; break; @@ -455,8 +455,8 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, /* ieee802.3 statistics OIDs (table 4-4) */ /* mandatory */ - case RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT: - pr_debug("%s: RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__); + case OID_802_3_RCV_ERROR_ALIGNMENT: + pr_debug("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__); if (stats) { *outbuf = cpu_to_le32(stats->rx_frame_errors); retval = 0; @@ -464,15 +464,15 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, break; /* mandatory */ - case RNDIS_OID_802_3_XMIT_ONE_COLLISION: - pr_debug("%s: RNDIS_OID_802_3_XMIT_ONE_COLLISION\n", __func__); + case OID_802_3_XMIT_ONE_COLLISION: + pr_debug("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__); *outbuf = cpu_to_le32(0); retval = 0; break; /* mandatory */ - case RNDIS_OID_802_3_XMIT_MORE_COLLISIONS: - pr_debug("%s: RNDIS_OID_802_3_XMIT_MORE_COLLISIONS\n", __func__); + case OID_802_3_XMIT_MORE_COLLISIONS: + pr_debug("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__); *outbuf = cpu_to_le32(0); retval = 0; break; @@ -516,7 +516,7 @@ static int gen_ndis_set_resp(u8 configNr, u32 OID, u8 *buf, u32 buf_len, params = &rndis_per_dev_params[configNr]; switch (OID) { - case RNDIS_OID_GEN_CURRENT_PACKET_FILTER: + case OID_GEN_CURRENT_PACKET_FILTER: /* these NDIS_PACKET_TYPE_* bitflags are shared with * cdc_filter; it's not RNDIS-specific @@ -525,7 +525,7 @@ static int gen_ndis_set_resp(u8 configNr, u32 OID, u8 *buf, u32 buf_len, * MULTICAST, ALL_MULTICAST, BROADCAST */ *params->filter = (u16)get_unaligned_le32(buf); - pr_debug("%s: RNDIS_OID_GEN_CURRENT_PACKET_FILTER %08x\n", + pr_debug("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n", __func__, *params->filter); /* this call has a significant side effect: it's @@ -545,9 +545,9 @@ static int gen_ndis_set_resp(u8 configNr, u32 OID, u8 *buf, u32 buf_len, } break; - case RNDIS_OID_802_3_MULTICAST_LIST: + case OID_802_3_MULTICAST_LIST: /* I think we can ignore this */ - pr_debug("%s: RNDIS_OID_802_3_MULTICAST_LIST\n", __func__); + pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__); retval = 0; break; @@ -577,7 +577,7 @@ static int rndis_init_response(int configNr, rndis_init_msg_type *buf) return -ENOMEM; resp = (rndis_init_cmplt_type *)r->buf; - resp->MessageType = cpu_to_le32(RNDIS_MSG_INIT_C); + resp->MessageType = cpu_to_le32(REMOTE_NDIS_INITIALIZE_CMPLT); resp->MessageLength = cpu_to_le32(52); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); @@ -621,7 +621,7 @@ static int rndis_query_response(int configNr, rndis_query_msg_type *buf) return -ENOMEM; resp = (rndis_query_cmplt_type *)r->buf; - resp->MessageType = cpu_to_le32(RNDIS_MSG_QUERY_C); + resp->MessageType = cpu_to_le32(REMOTE_NDIS_QUERY_CMPLT); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ if (gen_ndis_query_resp(configNr, le32_to_cpu(buf->OID), @@ -668,7 +668,7 @@ static int rndis_set_response(int configNr, rndis_set_msg_type *buf) pr_debug("\n"); #endif - resp->MessageType = cpu_to_le32(RNDIS_MSG_SET_C); + resp->MessageType = cpu_to_le32(REMOTE_NDIS_SET_CMPLT); resp->MessageLength = cpu_to_le32(16); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ if (gen_ndis_set_resp(configNr, le32_to_cpu(buf->OID), @@ -692,7 +692,7 @@ static int rndis_reset_response(int configNr, rndis_reset_msg_type *buf) return -ENOMEM; resp = (rndis_reset_cmplt_type *)r->buf; - resp->MessageType = cpu_to_le32(RNDIS_MSG_RESET_C); + resp->MessageType = cpu_to_le32(REMOTE_NDIS_RESET_CMPLT); resp->MessageLength = cpu_to_le32(16); resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); /* resent information */ @@ -716,7 +716,8 @@ static int rndis_keepalive_response(int configNr, return -ENOMEM; resp = (rndis_keepalive_cmplt_type *)r->buf; - resp->MessageType = cpu_to_le32(RNDIS_MSG_KEEPALIVE_C); + resp->MessageType = cpu_to_le32( + REMOTE_NDIS_KEEPALIVE_CMPLT); resp->MessageLength = cpu_to_le32(16); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); @@ -744,7 +745,7 @@ static int rndis_indicate_status_msg(int configNr, u32 status) return -ENOMEM; resp = (rndis_indicate_status_msg_type *)r->buf; - resp->MessageType = cpu_to_le32(RNDIS_MSG_INDICATE); + resp->MessageType = cpu_to_le32(REMOTE_NDIS_INDICATE_STATUS_MSG); resp->MessageLength = cpu_to_le32(20); resp->Status = cpu_to_le32(status); resp->StatusBufferLength = cpu_to_le32(0); @@ -757,7 +758,7 @@ static int rndis_indicate_status_msg(int configNr, u32 status) int rndis_signal_connect(int configNr) { rndis_per_dev_params[configNr].media_state - = RNDIS_MEDIA_STATE_CONNECTED; + = NDIS_MEDIA_STATE_CONNECTED; return rndis_indicate_status_msg(configNr, RNDIS_STATUS_MEDIA_CONNECT); } @@ -765,7 +766,7 @@ int rndis_signal_connect(int configNr) int rndis_signal_disconnect(int configNr) { rndis_per_dev_params[configNr].media_state - = RNDIS_MEDIA_STATE_DISCONNECTED; + = NDIS_MEDIA_STATE_DISCONNECTED; return rndis_indicate_status_msg(configNr, RNDIS_STATUS_MEDIA_DISCONNECT); } @@ -816,15 +817,15 @@ int rndis_msg_parser(u8 configNr, u8 *buf) /* For USB: responses may take up to 10 seconds */ switch (MsgType) { - case RNDIS_MSG_INIT: - pr_debug("%s: RNDIS_MSG_INIT\n", + case REMOTE_NDIS_INITIALIZE_MSG: + pr_debug("%s: REMOTE_NDIS_INITIALIZE_MSG\n", __func__); params->state = RNDIS_INITIALIZED; return rndis_init_response(configNr, (rndis_init_msg_type *)buf); - case RNDIS_MSG_HALT: - pr_debug("%s: RNDIS_MSG_HALT\n", + case REMOTE_NDIS_HALT_MSG: + pr_debug("%s: REMOTE_NDIS_HALT_MSG\n", __func__); params->state = RNDIS_UNINITIALIZED; if (params->dev) { @@ -833,24 +834,24 @@ int rndis_msg_parser(u8 configNr, u8 *buf) } return 0; - case RNDIS_MSG_QUERY: + case REMOTE_NDIS_QUERY_MSG: return rndis_query_response(configNr, (rndis_query_msg_type *)buf); - case RNDIS_MSG_SET: + case REMOTE_NDIS_SET_MSG: return rndis_set_response(configNr, (rndis_set_msg_type *)buf); - case RNDIS_MSG_RESET: - pr_debug("%s: RNDIS_MSG_RESET\n", + case REMOTE_NDIS_RESET_MSG: + pr_debug("%s: REMOTE_NDIS_RESET_MSG\n", __func__); return rndis_reset_response(configNr, (rndis_reset_msg_type *)buf); - case RNDIS_MSG_KEEPALIVE: + case REMOTE_NDIS_KEEPALIVE_MSG: /* For USB: host does this every 5 seconds */ if (rndis_debug > 1) - pr_debug("%s: RNDIS_MSG_KEEPALIVE\n", + pr_debug("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", __func__); return rndis_keepalive_response(configNr, (rndis_keepalive_msg_type *) @@ -962,7 +963,7 @@ void rndis_add_hdr(struct sk_buff *skb) return; header = (void *)skb_push(skb, sizeof(*header)); memset(header, 0, sizeof *header); - header->MessageType = cpu_to_le32(RNDIS_MSG_PACKET); + header->MessageType = cpu_to_le32(REMOTE_NDIS_PACKET_MSG); header->MessageLength = cpu_to_le32(skb->len); header->DataOffset = cpu_to_le32(36); header->DataLength = cpu_to_le32(skb->len - sizeof(*header)); @@ -1030,7 +1031,7 @@ int rndis_rm_hdr(struct gether *port, __le32 *tmp = (void *)skb->data; /* MessageType, MessageLength */ - if (cpu_to_le32(RNDIS_MSG_PACKET) + if (cpu_to_le32(REMOTE_NDIS_PACKET_MSG) != get_unaligned(tmp++)) { dev_kfree_skb_any(skb); return -EINVAL; @@ -1172,7 +1173,7 @@ int rndis_init(void) rndis_per_dev_params[i].used = 0; rndis_per_dev_params[i].state = RNDIS_UNINITIALIZED; rndis_per_dev_params[i].media_state - = RNDIS_MEDIA_STATE_DISCONNECTED; + = NDIS_MEDIA_STATE_DISCONNECTED; INIT_LIST_HEAD(&(rndis_per_dev_params[i].resp_queue)); } diff --git a/trunk/drivers/usb/gadget/rndis.h b/trunk/drivers/usb/gadget/rndis.h index 0647f2f34e89..907c33008118 100644 --- a/trunk/drivers/usb/gadget/rndis.h +++ b/trunk/drivers/usb/gadget/rndis.h @@ -15,12 +15,58 @@ #ifndef _LINUX_RNDIS_H #define _LINUX_RNDIS_H -#include #include "ndis.h" #define RNDIS_MAXIMUM_FRAME_SIZE 1518 #define RNDIS_MAX_TOTAL_SIZE 1558 +/* Remote NDIS Versions */ +#define RNDIS_MAJOR_VERSION 1 +#define RNDIS_MINOR_VERSION 0 + +/* Status Values */ +#define RNDIS_STATUS_SUCCESS 0x00000000U /* Success */ +#define RNDIS_STATUS_FAILURE 0xC0000001U /* Unspecified error */ +#define RNDIS_STATUS_INVALID_DATA 0xC0010015U /* Invalid data */ +#define RNDIS_STATUS_NOT_SUPPORTED 0xC00000BBU /* Unsupported request */ +#define RNDIS_STATUS_MEDIA_CONNECT 0x4001000BU /* Device connected */ +#define RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000CU /* Device disconnected */ +/* For all not specified status messages: + * RNDIS_STATUS_Xxx -> NDIS_STATUS_Xxx + */ + +/* Message Set for Connectionless (802.3) Devices */ +#define REMOTE_NDIS_PACKET_MSG 0x00000001U +#define REMOTE_NDIS_INITIALIZE_MSG 0x00000002U /* Initialize device */ +#define REMOTE_NDIS_HALT_MSG 0x00000003U +#define REMOTE_NDIS_QUERY_MSG 0x00000004U +#define REMOTE_NDIS_SET_MSG 0x00000005U +#define REMOTE_NDIS_RESET_MSG 0x00000006U +#define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007U +#define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008U + +/* Message completion */ +#define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002U +#define REMOTE_NDIS_QUERY_CMPLT 0x80000004U +#define REMOTE_NDIS_SET_CMPLT 0x80000005U +#define REMOTE_NDIS_RESET_CMPLT 0x80000006U +#define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008U + +/* Device Flags */ +#define RNDIS_DF_CONNECTIONLESS 0x00000001U +#define RNDIS_DF_CONNECTION_ORIENTED 0x00000002U + +#define RNDIS_MEDIUM_802_3 0x00000000U + +/* from drivers/net/sk98lin/h/skgepnmi.h */ +#define OID_PNP_CAPABILITIES 0xFD010100 +#define OID_PNP_SET_POWER 0xFD010101 +#define OID_PNP_QUERY_POWER 0xFD010102 +#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103 +#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104 +#define OID_PNP_ENABLE_WAKE_UP 0xFD010106 + + typedef struct rndis_init_msg_type { __le32 MessageType; diff --git a/trunk/drivers/usb/gadget/tcm_usb_gadget.c b/trunk/drivers/usb/gadget/tcm_usb_gadget.c deleted file mode 100644 index c46439c8dd74..000000000000 --- a/trunk/drivers/usb/gadget/tcm_usb_gadget.c +++ /dev/null @@ -1,2480 +0,0 @@ -/* Target based USB-Gadget - * - * UAS protocol handling, target callbacks, configfs handling, - * BBB (USB Mass Storage Class Bulk-Only (BBB) and Transport protocol handling. - * - * Author: Sebastian Andrzej Siewior - * License: GPLv2 as published by FSF. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "usbstring.c" -#include "epautoconf.c" -#include "config.c" -#include "composite.c" - -#include "tcm_usb_gadget.h" - -static struct target_fabric_configfs *usbg_fabric_configfs; - -static inline struct f_uas *to_f_uas(struct usb_function *f) -{ - return container_of(f, struct f_uas, function); -} - -static void usbg_cmd_release(struct kref *); - -static inline void usbg_cleanup_cmd(struct usbg_cmd *cmd) -{ - kref_put(&cmd->ref, usbg_cmd_release); -} - -/* Start bot.c code */ - -static int bot_enqueue_cmd_cbw(struct f_uas *fu) -{ - int ret; - - if (fu->flags & USBG_BOT_CMD_PEND) - return 0; - - ret = usb_ep_queue(fu->ep_out, fu->cmd.req, GFP_ATOMIC); - if (!ret) - fu->flags |= USBG_BOT_CMD_PEND; - return ret; -} - -static void bot_status_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct usbg_cmd *cmd = req->context; - struct f_uas *fu = cmd->fu; - - usbg_cleanup_cmd(cmd); - if (req->status < 0) { - pr_err("ERR %s(%d)\n", __func__, __LINE__); - return; - } - - /* CSW completed, wait for next CBW */ - bot_enqueue_cmd_cbw(fu); -} - -static void bot_enqueue_sense_code(struct f_uas *fu, struct usbg_cmd *cmd) -{ - struct bulk_cs_wrap *csw = &fu->bot_status.csw; - int ret; - u8 *sense; - unsigned int csw_stat; - - csw_stat = cmd->csw_code; - - /* - * We can't send SENSE as a response. So we take ASC & ASCQ from our - * sense buffer and queue it and hope the host sends a REQUEST_SENSE - * command where it learns why we failed. - */ - sense = cmd->sense_iu.sense; - - csw->Tag = cmd->bot_tag; - csw->Status = csw_stat; - fu->bot_status.req->context = cmd; - ret = usb_ep_queue(fu->ep_in, fu->bot_status.req, GFP_ATOMIC); - if (ret) - pr_err("%s(%d) ERR: %d\n", __func__, __LINE__, ret); -} - -static void bot_err_compl(struct usb_ep *ep, struct usb_request *req) -{ - struct usbg_cmd *cmd = req->context; - struct f_uas *fu = cmd->fu; - - if (req->status < 0) - pr_err("ERR %s(%d)\n", __func__, __LINE__); - - if (cmd->data_len) { - if (cmd->data_len > ep->maxpacket) { - req->length = ep->maxpacket; - cmd->data_len -= ep->maxpacket; - } else { - req->length = cmd->data_len; - cmd->data_len = 0; - } - - usb_ep_queue(ep, req, GFP_ATOMIC); - return ; - } - bot_enqueue_sense_code(fu, cmd); -} - -static void bot_send_bad_status(struct usbg_cmd *cmd) -{ - struct f_uas *fu = cmd->fu; - struct bulk_cs_wrap *csw = &fu->bot_status.csw; - struct usb_request *req; - struct usb_ep *ep; - - csw->Residue = cpu_to_le32(cmd->data_len); - - if (cmd->data_len) { - if (cmd->is_read) { - ep = fu->ep_in; - req = fu->bot_req_in; - } else { - ep = fu->ep_out; - req = fu->bot_req_out; - } - - if (cmd->data_len > fu->ep_in->maxpacket) { - req->length = ep->maxpacket; - cmd->data_len -= ep->maxpacket; - } else { - req->length = cmd->data_len; - cmd->data_len = 0; - } - req->complete = bot_err_compl; - req->context = cmd; - req->buf = fu->cmd.buf; - usb_ep_queue(ep, req, GFP_KERNEL); - } else { - bot_enqueue_sense_code(fu, cmd); - } -} - -static int bot_send_status(struct usbg_cmd *cmd, bool moved_data) -{ - struct f_uas *fu = cmd->fu; - struct bulk_cs_wrap *csw = &fu->bot_status.csw; - int ret; - - if (cmd->se_cmd.scsi_status == SAM_STAT_GOOD) { - if (!moved_data && cmd->data_len) { - /* - * the host wants to move data, we don't. Fill / empty - * the pipe and then send the csw with reside set. - */ - cmd->csw_code = US_BULK_STAT_OK; - bot_send_bad_status(cmd); - return 0; - } - - csw->Tag = cmd->bot_tag; - csw->Residue = cpu_to_le32(0); - csw->Status = US_BULK_STAT_OK; - fu->bot_status.req->context = cmd; - - ret = usb_ep_queue(fu->ep_in, fu->bot_status.req, GFP_KERNEL); - if (ret) - pr_err("%s(%d) ERR: %d\n", __func__, __LINE__, ret); - } else { - cmd->csw_code = US_BULK_STAT_FAIL; - bot_send_bad_status(cmd); - } - return 0; -} - -/* - * Called after command (no data transfer) or after the write (to device) - * operation is completed - */ -static int bot_send_status_response(struct usbg_cmd *cmd) -{ - bool moved_data = false; - - if (!cmd->is_read) - moved_data = true; - return bot_send_status(cmd, moved_data); -} - -/* Read request completed, now we have to send the CSW */ -static void bot_read_compl(struct usb_ep *ep, struct usb_request *req) -{ - struct usbg_cmd *cmd = req->context; - - if (req->status < 0) - pr_err("ERR %s(%d)\n", __func__, __LINE__); - - bot_send_status(cmd, true); -} - -static int bot_send_read_response(struct usbg_cmd *cmd) -{ - struct f_uas *fu = cmd->fu; - struct se_cmd *se_cmd = &cmd->se_cmd; - struct usb_gadget *gadget = fuas_to_gadget(fu); - int ret; - - if (!cmd->data_len) { - cmd->csw_code = US_BULK_STAT_PHASE; - bot_send_bad_status(cmd); - return 0; - } - - if (!gadget->sg_supported) { - cmd->data_buf = kmalloc(se_cmd->data_length, GFP_ATOMIC); - if (!cmd->data_buf) - return -ENOMEM; - - sg_copy_to_buffer(se_cmd->t_data_sg, - se_cmd->t_data_nents, - cmd->data_buf, - se_cmd->data_length); - - fu->bot_req_in->buf = cmd->data_buf; - } else { - fu->bot_req_in->buf = NULL; - fu->bot_req_in->num_sgs = se_cmd->t_data_nents; - fu->bot_req_in->sg = se_cmd->t_data_sg; - } - - fu->bot_req_in->complete = bot_read_compl; - fu->bot_req_in->length = se_cmd->data_length; - fu->bot_req_in->context = cmd; - ret = usb_ep_queue(fu->ep_in, fu->bot_req_in, GFP_ATOMIC); - if (ret) - pr_err("%s(%d)\n", __func__, __LINE__); - return 0; -} - -static void usbg_data_write_cmpl(struct usb_ep *, struct usb_request *); -static int usbg_prepare_w_request(struct usbg_cmd *, struct usb_request *); - -static int bot_send_write_request(struct usbg_cmd *cmd) -{ - struct f_uas *fu = cmd->fu; - struct se_cmd *se_cmd = &cmd->se_cmd; - struct usb_gadget *gadget = fuas_to_gadget(fu); - int ret; - - init_completion(&cmd->write_complete); - cmd->fu = fu; - - if (!cmd->data_len) { - cmd->csw_code = US_BULK_STAT_PHASE; - return -EINVAL; - } - - if (!gadget->sg_supported) { - cmd->data_buf = kmalloc(se_cmd->data_length, GFP_KERNEL); - if (!cmd->data_buf) - return -ENOMEM; - - fu->bot_req_out->buf = cmd->data_buf; - } else { - fu->bot_req_out->buf = NULL; - fu->bot_req_out->num_sgs = se_cmd->t_data_nents; - fu->bot_req_out->sg = se_cmd->t_data_sg; - } - - fu->bot_req_out->complete = usbg_data_write_cmpl; - fu->bot_req_out->length = se_cmd->data_length; - fu->bot_req_out->context = cmd; - - ret = usbg_prepare_w_request(cmd, fu->bot_req_out); - if (ret) - goto cleanup; - ret = usb_ep_queue(fu->ep_out, fu->bot_req_out, GFP_KERNEL); - if (ret) - pr_err("%s(%d)\n", __func__, __LINE__); - - wait_for_completion(&cmd->write_complete); - transport_generic_process_write(se_cmd); -cleanup: - return ret; -} - -static int bot_submit_command(struct f_uas *, void *, unsigned int); - -static void bot_cmd_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct f_uas *fu = req->context; - int ret; - - fu->flags &= ~USBG_BOT_CMD_PEND; - - if (req->status < 0) - return; - - ret = bot_submit_command(fu, req->buf, req->actual); - if (ret) - pr_err("%s(%d): %d\n", __func__, __LINE__, ret); -} - -static int bot_prepare_reqs(struct f_uas *fu) -{ - int ret; - - fu->bot_req_in = usb_ep_alloc_request(fu->ep_in, GFP_KERNEL); - if (!fu->bot_req_in) - goto err; - - fu->bot_req_out = usb_ep_alloc_request(fu->ep_out, GFP_KERNEL); - if (!fu->bot_req_out) - goto err_out; - - fu->cmd.req = usb_ep_alloc_request(fu->ep_out, GFP_KERNEL); - if (!fu->cmd.req) - goto err_cmd; - - fu->bot_status.req = usb_ep_alloc_request(fu->ep_in, GFP_KERNEL); - if (!fu->bot_status.req) - goto err_sts; - - fu->bot_status.req->buf = &fu->bot_status.csw; - fu->bot_status.req->length = US_BULK_CS_WRAP_LEN; - fu->bot_status.req->complete = bot_status_complete; - fu->bot_status.csw.Signature = cpu_to_le32(US_BULK_CS_SIGN); - - fu->cmd.buf = kmalloc(fu->ep_out->maxpacket, GFP_KERNEL); - if (!fu->cmd.buf) - goto err_buf; - - fu->cmd.req->complete = bot_cmd_complete; - fu->cmd.req->buf = fu->cmd.buf; - fu->cmd.req->length = fu->ep_out->maxpacket; - fu->cmd.req->context = fu; - - ret = bot_enqueue_cmd_cbw(fu); - if (ret) - goto err_queue; - return 0; -err_queue: - kfree(fu->cmd.buf); - fu->cmd.buf = NULL; -err_buf: - usb_ep_free_request(fu->ep_in, fu->bot_status.req); -err_sts: - usb_ep_free_request(fu->ep_out, fu->cmd.req); - fu->cmd.req = NULL; -err_cmd: - usb_ep_free_request(fu->ep_out, fu->bot_req_out); - fu->bot_req_out = NULL; -err_out: - usb_ep_free_request(fu->ep_in, fu->bot_req_in); - fu->bot_req_in = NULL; -err: - pr_err("BOT: endpoint setup failed\n"); - return -ENOMEM; -} - -void bot_cleanup_old_alt(struct f_uas *fu) -{ - if (!(fu->flags & USBG_ENABLED)) - return; - - usb_ep_disable(fu->ep_in); - usb_ep_disable(fu->ep_out); - - if (!fu->bot_req_in) - return; - - usb_ep_free_request(fu->ep_in, fu->bot_req_in); - usb_ep_free_request(fu->ep_out, fu->bot_req_out); - usb_ep_free_request(fu->ep_out, fu->cmd.req); - usb_ep_free_request(fu->ep_out, fu->bot_status.req); - - kfree(fu->cmd.buf); - - fu->bot_req_in = NULL; - fu->bot_req_out = NULL; - fu->cmd.req = NULL; - fu->bot_status.req = NULL; - fu->cmd.buf = NULL; -} - -static void bot_set_alt(struct f_uas *fu) -{ - struct usb_function *f = &fu->function; - struct usb_gadget *gadget = f->config->cdev->gadget; - int ret; - - fu->flags = USBG_IS_BOT; - - config_ep_by_speed(gadget, f, fu->ep_in); - ret = usb_ep_enable(fu->ep_in); - if (ret) - goto err_b_in; - - config_ep_by_speed(gadget, f, fu->ep_out); - ret = usb_ep_enable(fu->ep_out); - if (ret) - goto err_b_out; - - ret = bot_prepare_reqs(fu); - if (ret) - goto err_wq; - fu->flags |= USBG_ENABLED; - pr_info("Using the BOT protocol\n"); - return; -err_wq: - usb_ep_disable(fu->ep_out); -err_b_out: - usb_ep_disable(fu->ep_in); -err_b_in: - fu->flags = USBG_IS_BOT; -} - -static int usbg_bot_setup(struct usb_function *f, - const struct usb_ctrlrequest *ctrl) -{ - struct f_uas *fu = to_f_uas(f); - struct usb_composite_dev *cdev = f->config->cdev; - u16 w_value = le16_to_cpu(ctrl->wValue); - u16 w_length = le16_to_cpu(ctrl->wLength); - int luns; - u8 *ret_lun; - - switch (ctrl->bRequest) { - case US_BULK_GET_MAX_LUN: - if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_CLASS | - USB_RECIP_INTERFACE)) - return -ENOTSUPP; - - if (w_length < 1) - return -EINVAL; - if (w_value != 0) - return -EINVAL; - luns = atomic_read(&fu->tpg->tpg_port_count); - if (!luns) { - pr_err("No LUNs configured?\n"); - return -EINVAL; - } - /* - * If 4 LUNs are present we return 3 i.e. LUN 0..3 can be - * accessed. The upper limit is 0xf - */ - luns--; - if (luns > 0xf) { - pr_info_once("Limiting the number of luns to 16\n"); - luns = 0xf; - } - ret_lun = cdev->req->buf; - *ret_lun = luns; - cdev->req->length = 1; - return usb_ep_queue(cdev->gadget->ep0, cdev->req, GFP_ATOMIC); - break; - - case US_BULK_RESET_REQUEST: - /* XXX maybe we should remove previous requests for IN + OUT */ - bot_enqueue_cmd_cbw(fu); - return 0; - break; - }; - return -ENOTSUPP; -} - -/* Start uas.c code */ - -static void uasp_cleanup_one_stream(struct f_uas *fu, struct uas_stream *stream) -{ - /* We have either all three allocated or none */ - if (!stream->req_in) - return; - - usb_ep_free_request(fu->ep_in, stream->req_in); - usb_ep_free_request(fu->ep_out, stream->req_out); - usb_ep_free_request(fu->ep_status, stream->req_status); - - stream->req_in = NULL; - stream->req_out = NULL; - stream->req_status = NULL; -} - -static void uasp_free_cmdreq(struct f_uas *fu) -{ - usb_ep_free_request(fu->ep_cmd, fu->cmd.req); - kfree(fu->cmd.buf); - fu->cmd.req = NULL; - fu->cmd.buf = NULL; -} - -static void uasp_cleanup_old_alt(struct f_uas *fu) -{ - int i; - - if (!(fu->flags & USBG_ENABLED)) - return; - - usb_ep_disable(fu->ep_in); - usb_ep_disable(fu->ep_out); - usb_ep_disable(fu->ep_status); - usb_ep_disable(fu->ep_cmd); - - for (i = 0; i < UASP_SS_EP_COMP_NUM_STREAMS; i++) - uasp_cleanup_one_stream(fu, &fu->stream[i]); - uasp_free_cmdreq(fu); -} - -static void uasp_status_data_cmpl(struct usb_ep *ep, struct usb_request *req); - -static int uasp_prepare_r_request(struct usbg_cmd *cmd) -{ - struct se_cmd *se_cmd = &cmd->se_cmd; - struct f_uas *fu = cmd->fu; - struct usb_gadget *gadget = fuas_to_gadget(fu); - struct uas_stream *stream = cmd->stream; - - if (!gadget->sg_supported) { - cmd->data_buf = kmalloc(se_cmd->data_length, GFP_ATOMIC); - if (!cmd->data_buf) - return -ENOMEM; - - sg_copy_to_buffer(se_cmd->t_data_sg, - se_cmd->t_data_nents, - cmd->data_buf, - se_cmd->data_length); - - stream->req_in->buf = cmd->data_buf; - } else { - stream->req_in->buf = NULL; - stream->req_in->num_sgs = se_cmd->t_data_nents; - stream->req_in->sg = se_cmd->t_data_sg; - } - - stream->req_in->complete = uasp_status_data_cmpl; - stream->req_in->length = se_cmd->data_length; - stream->req_in->context = cmd; - - cmd->state = UASP_SEND_STATUS; - return 0; -} - -static void uasp_prepare_status(struct usbg_cmd *cmd) -{ - struct se_cmd *se_cmd = &cmd->se_cmd; - struct sense_iu *iu = &cmd->sense_iu; - struct uas_stream *stream = cmd->stream; - - cmd->state = UASP_QUEUE_COMMAND; - iu->iu_id = IU_ID_STATUS; - iu->tag = cpu_to_be16(cmd->tag); - - /* - * iu->status_qual = cpu_to_be16(STATUS QUALIFIER SAM-4. Where R U?); - */ - iu->len = cpu_to_be16(se_cmd->scsi_sense_length); - iu->status = se_cmd->scsi_status; - stream->req_status->context = cmd; - stream->req_status->length = se_cmd->scsi_sense_length + 16; - stream->req_status->buf = iu; - stream->req_status->complete = uasp_status_data_cmpl; -} - -static void uasp_status_data_cmpl(struct usb_ep *ep, struct usb_request *req) -{ - struct usbg_cmd *cmd = req->context; - struct uas_stream *stream = cmd->stream; - struct f_uas *fu = cmd->fu; - int ret; - - if (req->status < 0) - goto cleanup; - - switch (cmd->state) { - case UASP_SEND_DATA: - ret = uasp_prepare_r_request(cmd); - if (ret) - goto cleanup; - ret = usb_ep_queue(fu->ep_in, stream->req_in, GFP_ATOMIC); - if (ret) - pr_err("%s(%d) => %d\n", __func__, __LINE__, ret); - break; - - case UASP_RECEIVE_DATA: - ret = usbg_prepare_w_request(cmd, stream->req_out); - if (ret) - goto cleanup; - ret = usb_ep_queue(fu->ep_out, stream->req_out, GFP_ATOMIC); - if (ret) - pr_err("%s(%d) => %d\n", __func__, __LINE__, ret); - break; - - case UASP_SEND_STATUS: - uasp_prepare_status(cmd); - ret = usb_ep_queue(fu->ep_status, stream->req_status, - GFP_ATOMIC); - if (ret) - pr_err("%s(%d) => %d\n", __func__, __LINE__, ret); - break; - - case UASP_QUEUE_COMMAND: - usbg_cleanup_cmd(cmd); - usb_ep_queue(fu->ep_cmd, fu->cmd.req, GFP_ATOMIC); - break; - - default: - BUG(); - }; - return; - -cleanup: - usbg_cleanup_cmd(cmd); -} - -static int uasp_send_status_response(struct usbg_cmd *cmd) -{ - struct f_uas *fu = cmd->fu; - struct uas_stream *stream = cmd->stream; - struct sense_iu *iu = &cmd->sense_iu; - - iu->tag = cpu_to_be16(cmd->tag); - stream->req_status->complete = uasp_status_data_cmpl; - stream->req_status->context = cmd; - cmd->fu = fu; - uasp_prepare_status(cmd); - return usb_ep_queue(fu->ep_status, stream->req_status, GFP_ATOMIC); -} - -static int uasp_send_read_response(struct usbg_cmd *cmd) -{ - struct f_uas *fu = cmd->fu; - struct uas_stream *stream = cmd->stream; - struct sense_iu *iu = &cmd->sense_iu; - int ret; - - cmd->fu = fu; - - iu->tag = cpu_to_be16(cmd->tag); - if (fu->flags & USBG_USE_STREAMS) { - - ret = uasp_prepare_r_request(cmd); - if (ret) - goto out; - ret = usb_ep_queue(fu->ep_in, stream->req_in, GFP_ATOMIC); - if (ret) { - pr_err("%s(%d) => %d\n", __func__, __LINE__, ret); - kfree(cmd->data_buf); - cmd->data_buf = NULL; - } - - } else { - - iu->iu_id = IU_ID_READ_READY; - iu->tag = cpu_to_be16(cmd->tag); - - stream->req_status->complete = uasp_status_data_cmpl; - stream->req_status->context = cmd; - - cmd->state = UASP_SEND_DATA; - stream->req_status->buf = iu; - stream->req_status->length = sizeof(struct iu); - - ret = usb_ep_queue(fu->ep_status, stream->req_status, - GFP_ATOMIC); - if (ret) - pr_err("%s(%d) => %d\n", __func__, __LINE__, ret); - } -out: - return ret; -} - -static int uasp_send_write_request(struct usbg_cmd *cmd) -{ - struct f_uas *fu = cmd->fu; - struct se_cmd *se_cmd = &cmd->se_cmd; - struct uas_stream *stream = cmd->stream; - struct sense_iu *iu = &cmd->sense_iu; - int ret; - - init_completion(&cmd->write_complete); - cmd->fu = fu; - - iu->tag = cpu_to_be16(cmd->tag); - - if (fu->flags & USBG_USE_STREAMS) { - - ret = usbg_prepare_w_request(cmd, stream->req_out); - if (ret) - goto cleanup; - ret = usb_ep_queue(fu->ep_out, stream->req_out, GFP_ATOMIC); - if (ret) - pr_err("%s(%d)\n", __func__, __LINE__); - - } else { - - iu->iu_id = IU_ID_WRITE_READY; - iu->tag = cpu_to_be16(cmd->tag); - - stream->req_status->complete = uasp_status_data_cmpl; - stream->req_status->context = cmd; - - cmd->state = UASP_RECEIVE_DATA; - stream->req_status->buf = iu; - stream->req_status->length = sizeof(struct iu); - - ret = usb_ep_queue(fu->ep_status, stream->req_status, - GFP_ATOMIC); - if (ret) - pr_err("%s(%d)\n", __func__, __LINE__); - } - - wait_for_completion(&cmd->write_complete); - transport_generic_process_write(se_cmd); -cleanup: - return ret; -} - -static int usbg_submit_command(struct f_uas *, void *, unsigned int); - -static void uasp_cmd_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct f_uas *fu = req->context; - int ret; - - if (req->status < 0) - return; - - ret = usbg_submit_command(fu, req->buf, req->actual); - /* - * Once we tune for performance enqueue the command req here again so - * we can receive a second command while we processing this one. Pay - * attention to properly sync STAUS endpoint with DATA IN + OUT so you - * don't break HS. - */ - if (!ret) - return; - usb_ep_queue(fu->ep_cmd, fu->cmd.req, GFP_ATOMIC); -} - -static int uasp_alloc_stream_res(struct f_uas *fu, struct uas_stream *stream) -{ - stream->req_in = usb_ep_alloc_request(fu->ep_in, GFP_KERNEL); - if (!stream->req_in) - goto out; - - stream->req_out = usb_ep_alloc_request(fu->ep_out, GFP_KERNEL); - if (!stream->req_out) - goto err_out; - - stream->req_status = usb_ep_alloc_request(fu->ep_status, GFP_KERNEL); - if (!stream->req_status) - goto err_sts; - - return 0; -err_sts: - usb_ep_free_request(fu->ep_status, stream->req_status); - stream->req_status = NULL; -err_out: - usb_ep_free_request(fu->ep_out, stream->req_out); - stream->req_out = NULL; -out: - return -ENOMEM; -} - -static int uasp_alloc_cmd(struct f_uas *fu) -{ - fu->cmd.req = usb_ep_alloc_request(fu->ep_cmd, GFP_KERNEL); - if (!fu->cmd.req) - goto err; - - fu->cmd.buf = kmalloc(fu->ep_cmd->maxpacket, GFP_KERNEL); - if (!fu->cmd.buf) - goto err_buf; - - fu->cmd.req->complete = uasp_cmd_complete; - fu->cmd.req->buf = fu->cmd.buf; - fu->cmd.req->length = fu->ep_cmd->maxpacket; - fu->cmd.req->context = fu; - return 0; - -err_buf: - usb_ep_free_request(fu->ep_cmd, fu->cmd.req); -err: - return -ENOMEM; -} - -static void uasp_setup_stream_res(struct f_uas *fu, int max_streams) -{ - int i; - - for (i = 0; i < max_streams; i++) { - struct uas_stream *s = &fu->stream[i]; - - s->req_in->stream_id = i + 1; - s->req_out->stream_id = i + 1; - s->req_status->stream_id = i + 1; - } -} - -static int uasp_prepare_reqs(struct f_uas *fu) -{ - int ret; - int i; - int max_streams; - - if (fu->flags & USBG_USE_STREAMS) - max_streams = UASP_SS_EP_COMP_NUM_STREAMS; - else - max_streams = 1; - - for (i = 0; i < max_streams; i++) { - ret = uasp_alloc_stream_res(fu, &fu->stream[i]); - if (ret) - goto err_cleanup; - } - - ret = uasp_alloc_cmd(fu); - if (ret) - goto err_free_stream; - uasp_setup_stream_res(fu, max_streams); - - ret = usb_ep_queue(fu->ep_cmd, fu->cmd.req, GFP_ATOMIC); - if (ret) - goto err_free_stream; - - return 0; - -err_free_stream: - uasp_free_cmdreq(fu); - -err_cleanup: - if (i) { - do { - uasp_cleanup_one_stream(fu, &fu->stream[i - 1]); - i--; - } while (i); - } - pr_err("UASP: endpoint setup failed\n"); - return ret; -} - -static void uasp_set_alt(struct f_uas *fu) -{ - struct usb_function *f = &fu->function; - struct usb_gadget *gadget = f->config->cdev->gadget; - int ret; - - fu->flags = USBG_IS_UAS; - - if (gadget->speed == USB_SPEED_SUPER) - fu->flags |= USBG_USE_STREAMS; - - config_ep_by_speed(gadget, f, fu->ep_in); - ret = usb_ep_enable(fu->ep_in); - if (ret) - goto err_b_in; - - config_ep_by_speed(gadget, f, fu->ep_out); - ret = usb_ep_enable(fu->ep_out); - if (ret) - goto err_b_out; - - config_ep_by_speed(gadget, f, fu->ep_cmd); - ret = usb_ep_enable(fu->ep_cmd); - if (ret) - goto err_cmd; - config_ep_by_speed(gadget, f, fu->ep_status); - ret = usb_ep_enable(fu->ep_status); - if (ret) - goto err_status; - - ret = uasp_prepare_reqs(fu); - if (ret) - goto err_wq; - fu->flags |= USBG_ENABLED; - - pr_info("Using the UAS protocol\n"); - return; -err_wq: - usb_ep_disable(fu->ep_status); -err_status: - usb_ep_disable(fu->ep_cmd); -err_cmd: - usb_ep_disable(fu->ep_out); -err_b_out: - usb_ep_disable(fu->ep_in); -err_b_in: - fu->flags = 0; -} - -static int get_cmd_dir(const unsigned char *cdb) -{ - int ret; - - switch (cdb[0]) { - case READ_6: - case READ_10: - case READ_12: - case READ_16: - case INQUIRY: - case MODE_SENSE: - case MODE_SENSE_10: - case SERVICE_ACTION_IN: - case MAINTENANCE_IN: - case PERSISTENT_RESERVE_IN: - case SECURITY_PROTOCOL_IN: - case ACCESS_CONTROL_IN: - case REPORT_LUNS: - case READ_BLOCK_LIMITS: - case READ_POSITION: - case READ_CAPACITY: - case READ_TOC: - case READ_FORMAT_CAPACITIES: - case REQUEST_SENSE: - ret = DMA_FROM_DEVICE; - break; - - case WRITE_6: - case WRITE_10: - case WRITE_12: - case WRITE_16: - case MODE_SELECT: - case MODE_SELECT_10: - case WRITE_VERIFY: - case WRITE_VERIFY_12: - case PERSISTENT_RESERVE_OUT: - case MAINTENANCE_OUT: - case SECURITY_PROTOCOL_OUT: - case ACCESS_CONTROL_OUT: - ret = DMA_TO_DEVICE; - break; - case ALLOW_MEDIUM_REMOVAL: - case TEST_UNIT_READY: - case SYNCHRONIZE_CACHE: - case START_STOP: - case ERASE: - case REZERO_UNIT: - case SEEK_10: - case SPACE: - case VERIFY: - case WRITE_FILEMARKS: - ret = DMA_NONE; - break; - default: - pr_warn("target: Unknown data direction for SCSI Opcode " - "0x%02x\n", cdb[0]); - ret = -EINVAL; - } - return ret; -} - -static void usbg_data_write_cmpl(struct usb_ep *ep, struct usb_request *req) -{ - struct usbg_cmd *cmd = req->context; - struct se_cmd *se_cmd = &cmd->se_cmd; - - if (req->status < 0) { - pr_err("%s() state %d transfer failed\n", __func__, cmd->state); - goto cleanup; - } - - if (req->num_sgs == 0) { - sg_copy_from_buffer(se_cmd->t_data_sg, - se_cmd->t_data_nents, - cmd->data_buf, - se_cmd->data_length); - } - - complete(&cmd->write_complete); - return; - -cleanup: - usbg_cleanup_cmd(cmd); -} - -static int usbg_prepare_w_request(struct usbg_cmd *cmd, struct usb_request *req) -{ - struct se_cmd *se_cmd = &cmd->se_cmd; - struct f_uas *fu = cmd->fu; - struct usb_gadget *gadget = fuas_to_gadget(fu); - - if (!gadget->sg_supported) { - cmd->data_buf = kmalloc(se_cmd->data_length, GFP_ATOMIC); - if (!cmd->data_buf) - return -ENOMEM; - - req->buf = cmd->data_buf; - } else { - req->buf = NULL; - req->num_sgs = se_cmd->t_data_nents; - req->sg = se_cmd->t_data_sg; - } - - req->complete = usbg_data_write_cmpl; - req->length = se_cmd->data_length; - req->context = cmd; - return 0; -} - -static int usbg_send_status_response(struct se_cmd *se_cmd) -{ - struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd, - se_cmd); - struct f_uas *fu = cmd->fu; - - if (fu->flags & USBG_IS_BOT) - return bot_send_status_response(cmd); - else - return uasp_send_status_response(cmd); -} - -static int usbg_send_write_request(struct se_cmd *se_cmd) -{ - struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd, - se_cmd); - struct f_uas *fu = cmd->fu; - - if (fu->flags & USBG_IS_BOT) - return bot_send_write_request(cmd); - else - return uasp_send_write_request(cmd); -} - -static int usbg_send_read_response(struct se_cmd *se_cmd) -{ - struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd, - se_cmd); - struct f_uas *fu = cmd->fu; - - if (fu->flags & USBG_IS_BOT) - return bot_send_read_response(cmd); - else - return uasp_send_read_response(cmd); -} - -static void usbg_cmd_work(struct work_struct *work) -{ - struct usbg_cmd *cmd = container_of(work, struct usbg_cmd, work); - struct se_cmd *se_cmd; - struct tcm_usbg_nexus *tv_nexus; - struct usbg_tpg *tpg; - int dir; - - se_cmd = &cmd->se_cmd; - tpg = cmd->fu->tpg; - tv_nexus = tpg->tpg_nexus; - dir = get_cmd_dir(cmd->cmd_buf); - if (dir < 0) { - transport_init_se_cmd(se_cmd, - tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo, - tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE, - cmd->prio_attr, cmd->sense_iu.sense); - - transport_send_check_condition_and_sense(se_cmd, - TCM_UNSUPPORTED_SCSI_OPCODE, 1); - usbg_cleanup_cmd(cmd); - return; - } - - target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess, - cmd->cmd_buf, cmd->sense_iu.sense, cmd->unpacked_lun, - 0, cmd->prio_attr, dir, TARGET_SCF_UNKNOWN_SIZE); -} - -static int usbg_submit_command(struct f_uas *fu, - void *cmdbuf, unsigned int len) -{ - struct command_iu *cmd_iu = cmdbuf; - struct usbg_cmd *cmd; - struct usbg_tpg *tpg; - struct se_cmd *se_cmd; - struct tcm_usbg_nexus *tv_nexus; - u32 cmd_len; - int ret; - - if (cmd_iu->iu_id != IU_ID_COMMAND) { - pr_err("Unsupported type %d\n", cmd_iu->iu_id); - return -EINVAL; - } - - cmd = kzalloc(sizeof *cmd, GFP_ATOMIC); - if (!cmd) - return -ENOMEM; - - cmd->fu = fu; - - /* XXX until I figure out why I can't free in on complete */ - kref_init(&cmd->ref); - kref_get(&cmd->ref); - - tpg = fu->tpg; - cmd_len = (cmd_iu->len & ~0x3) + 16; - if (cmd_len > USBG_MAX_CMD) - goto err; - - memcpy(cmd->cmd_buf, cmd_iu->cdb, cmd_len); - - cmd->tag = be16_to_cpup(&cmd_iu->tag); - if (fu->flags & USBG_USE_STREAMS) { - if (cmd->tag > UASP_SS_EP_COMP_NUM_STREAMS) - goto err; - if (!cmd->tag) - cmd->stream = &fu->stream[0]; - else - cmd->stream = &fu->stream[cmd->tag - 1]; - } else { - cmd->stream = &fu->stream[0]; - } - - tv_nexus = tpg->tpg_nexus; - if (!tv_nexus) { - pr_err("Missing nexus, ignoring command\n"); - goto err; - } - - switch (cmd_iu->prio_attr & 0x7) { - case UAS_HEAD_TAG: - cmd->prio_attr = MSG_HEAD_TAG; - break; - case UAS_ORDERED_TAG: - cmd->prio_attr = MSG_ORDERED_TAG; - break; - case UAS_ACA: - cmd->prio_attr = MSG_ACA_TAG; - break; - default: - pr_debug_once("Unsupported prio_attr: %02x.\n", - cmd_iu->prio_attr); - case UAS_SIMPLE_TAG: - cmd->prio_attr = MSG_SIMPLE_TAG; - break; - } - - se_cmd = &cmd->se_cmd; - cmd->unpacked_lun = scsilun_to_int(&cmd_iu->lun); - - INIT_WORK(&cmd->work, usbg_cmd_work); - ret = queue_work(tpg->workqueue, &cmd->work); - if (ret < 0) - goto err; - - return 0; -err: - kfree(cmd); - return -EINVAL; -} - -static void bot_cmd_work(struct work_struct *work) -{ - struct usbg_cmd *cmd = container_of(work, struct usbg_cmd, work); - struct se_cmd *se_cmd; - struct tcm_usbg_nexus *tv_nexus; - struct usbg_tpg *tpg; - int dir; - - se_cmd = &cmd->se_cmd; - tpg = cmd->fu->tpg; - tv_nexus = tpg->tpg_nexus; - dir = get_cmd_dir(cmd->cmd_buf); - if (dir < 0) { - transport_init_se_cmd(se_cmd, - tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo, - tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE, - cmd->prio_attr, cmd->sense_iu.sense); - - transport_send_check_condition_and_sense(se_cmd, - TCM_UNSUPPORTED_SCSI_OPCODE, 1); - usbg_cleanup_cmd(cmd); - return; - } - - target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess, - cmd->cmd_buf, cmd->sense_iu.sense, cmd->unpacked_lun, - cmd->data_len, cmd->prio_attr, dir, 0); -} - -static int bot_submit_command(struct f_uas *fu, - void *cmdbuf, unsigned int len) -{ - struct bulk_cb_wrap *cbw = cmdbuf; - struct usbg_cmd *cmd; - struct usbg_tpg *tpg; - struct se_cmd *se_cmd; - struct tcm_usbg_nexus *tv_nexus; - u32 cmd_len; - int ret; - - if (cbw->Signature != cpu_to_le32(US_BULK_CB_SIGN)) { - pr_err("Wrong signature on CBW\n"); - return -EINVAL; - } - if (len != 31) { - pr_err("Wrong length for CBW\n"); - return -EINVAL; - } - - cmd_len = cbw->Length; - if (cmd_len < 1 || cmd_len > 16) - return -EINVAL; - - cmd = kzalloc(sizeof *cmd, GFP_ATOMIC); - if (!cmd) - return -ENOMEM; - - cmd->fu = fu; - - /* XXX until I figure out why I can't free in on complete */ - kref_init(&cmd->ref); - kref_get(&cmd->ref); - - tpg = fu->tpg; - - memcpy(cmd->cmd_buf, cbw->CDB, cmd_len); - - cmd->bot_tag = cbw->Tag; - - tv_nexus = tpg->tpg_nexus; - if (!tv_nexus) { - pr_err("Missing nexus, ignoring command\n"); - goto err; - } - - cmd->prio_attr = MSG_SIMPLE_TAG; - se_cmd = &cmd->se_cmd; - cmd->unpacked_lun = cbw->Lun; - cmd->is_read = cbw->Flags & US_BULK_FLAG_IN ? 1 : 0; - cmd->data_len = le32_to_cpu(cbw->DataTransferLength); - - INIT_WORK(&cmd->work, bot_cmd_work); - ret = queue_work(tpg->workqueue, &cmd->work); - if (ret < 0) - goto err; - - return 0; -err: - kfree(cmd); - return -EINVAL; -} - -/* Start fabric.c code */ - -static int usbg_check_true(struct se_portal_group *se_tpg) -{ - return 1; -} - -static int usbg_check_false(struct se_portal_group *se_tpg) -{ - return 0; -} - -static char *usbg_get_fabric_name(void) -{ - return "usb_gadget"; -} - -static u8 usbg_get_fabric_proto_ident(struct se_portal_group *se_tpg) -{ - struct usbg_tpg *tpg = container_of(se_tpg, - struct usbg_tpg, se_tpg); - struct usbg_tport *tport = tpg->tport; - u8 proto_id; - - switch (tport->tport_proto_id) { - case SCSI_PROTOCOL_SAS: - default: - proto_id = sas_get_fabric_proto_ident(se_tpg); - break; - } - - return proto_id; -} - -static char *usbg_get_fabric_wwn(struct se_portal_group *se_tpg) -{ - struct usbg_tpg *tpg = container_of(se_tpg, - struct usbg_tpg, se_tpg); - struct usbg_tport *tport = tpg->tport; - - return &tport->tport_name[0]; -} - -static u16 usbg_get_tag(struct se_portal_group *se_tpg) -{ - struct usbg_tpg *tpg = container_of(se_tpg, - struct usbg_tpg, se_tpg); - return tpg->tport_tpgt; -} - -static u32 usbg_get_default_depth(struct se_portal_group *se_tpg) -{ - return 1; -} - -static u32 usbg_get_pr_transport_id( - struct se_portal_group *se_tpg, - struct se_node_acl *se_nacl, - struct t10_pr_registration *pr_reg, - int *format_code, - unsigned char *buf) -{ - struct usbg_tpg *tpg = container_of(se_tpg, - struct usbg_tpg, se_tpg); - struct usbg_tport *tport = tpg->tport; - int ret = 0; - - switch (tport->tport_proto_id) { - case SCSI_PROTOCOL_SAS: - default: - ret = sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg, - format_code, buf); - break; - } - - return ret; -} - -static u32 usbg_get_pr_transport_id_len( - struct se_portal_group *se_tpg, - struct se_node_acl *se_nacl, - struct t10_pr_registration *pr_reg, - int *format_code) -{ - struct usbg_tpg *tpg = container_of(se_tpg, - struct usbg_tpg, se_tpg); - struct usbg_tport *tport = tpg->tport; - int ret = 0; - - switch (tport->tport_proto_id) { - case SCSI_PROTOCOL_SAS: - default: - ret = sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg, - format_code); - break; - } - - return ret; -} - -static char *usbg_parse_pr_out_transport_id( - struct se_portal_group *se_tpg, - const char *buf, - u32 *out_tid_len, - char **port_nexus_ptr) -{ - struct usbg_tpg *tpg = container_of(se_tpg, - struct usbg_tpg, se_tpg); - struct usbg_tport *tport = tpg->tport; - char *tid = NULL; - - switch (tport->tport_proto_id) { - case SCSI_PROTOCOL_SAS: - default: - tid = sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len, - port_nexus_ptr); - } - - return tid; -} - -static struct se_node_acl *usbg_alloc_fabric_acl(struct se_portal_group *se_tpg) -{ - struct usbg_nacl *nacl; - - nacl = kzalloc(sizeof(struct usbg_nacl), GFP_KERNEL); - if (!nacl) { - printk(KERN_ERR "Unable to alocate struct usbg_nacl\n"); - return NULL; - } - - return &nacl->se_node_acl; -} - -static void usbg_release_fabric_acl( - struct se_portal_group *se_tpg, - struct se_node_acl *se_nacl) -{ - struct usbg_nacl *nacl = container_of(se_nacl, - struct usbg_nacl, se_node_acl); - kfree(nacl); -} - -static u32 usbg_tpg_get_inst_index(struct se_portal_group *se_tpg) -{ - return 1; -} - -static int usbg_new_cmd(struct se_cmd *se_cmd) -{ - struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd, - se_cmd); - int ret; - - ret = target_setup_cmd_from_cdb(se_cmd, cmd->cmd_buf); - if (ret) - return ret; - - return transport_generic_map_mem_to_cmd(se_cmd, NULL, 0, NULL, 0); -} - -static void usbg_cmd_release(struct kref *ref) -{ - struct usbg_cmd *cmd = container_of(ref, struct usbg_cmd, - ref); - - transport_generic_free_cmd(&cmd->se_cmd, 0); -} - -static void usbg_release_cmd(struct se_cmd *se_cmd) -{ - struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd, - se_cmd); - kfree(cmd->data_buf); - kfree(cmd); - return; -} - -static int usbg_shutdown_session(struct se_session *se_sess) -{ - return 0; -} - -static void usbg_close_session(struct se_session *se_sess) -{ - return; -} - -static u32 usbg_sess_get_index(struct se_session *se_sess) -{ - return 0; -} - -/* - * XXX Error recovery: return != 0 if we expect writes. Dunno when that could be - */ -static int usbg_write_pending_status(struct se_cmd *se_cmd) -{ - return 0; -} - -static void usbg_set_default_node_attrs(struct se_node_acl *nacl) -{ - return; -} - -static u32 usbg_get_task_tag(struct se_cmd *se_cmd) -{ - struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd, - se_cmd); - struct f_uas *fu = cmd->fu; - - if (fu->flags & USBG_IS_BOT) - return le32_to_cpu(cmd->bot_tag); - else - return cmd->tag; -} - -static int usbg_get_cmd_state(struct se_cmd *se_cmd) -{ - return 0; -} - -static int usbg_queue_tm_rsp(struct se_cmd *se_cmd) -{ - return 0; -} - -static u16 usbg_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length) -{ - return 0; -} - -static u16 usbg_get_fabric_sense_len(void) -{ - return 0; -} - -static const char *usbg_check_wwn(const char *name) -{ - const char *n; - unsigned int len; - - n = strstr(name, "naa."); - if (!n) - return NULL; - n += 4; - len = strlen(n); - if (len == 0 || len > USBG_NAMELEN - 1) - return NULL; - return n; -} - -static struct se_node_acl *usbg_make_nodeacl( - struct se_portal_group *se_tpg, - struct config_group *group, - const char *name) -{ - struct se_node_acl *se_nacl, *se_nacl_new; - struct usbg_nacl *nacl; - u64 wwpn = 0; - u32 nexus_depth; - const char *wnn_name; - - wnn_name = usbg_check_wwn(name); - if (!wnn_name) - return ERR_PTR(-EINVAL); - se_nacl_new = usbg_alloc_fabric_acl(se_tpg); - if (!(se_nacl_new)) - return ERR_PTR(-ENOMEM); - - nexus_depth = 1; - /* - * se_nacl_new may be released by core_tpg_add_initiator_node_acl() - * when converting a NodeACL from demo mode -> explict - */ - se_nacl = core_tpg_add_initiator_node_acl(se_tpg, se_nacl_new, - name, nexus_depth); - if (IS_ERR(se_nacl)) { - usbg_release_fabric_acl(se_tpg, se_nacl_new); - return se_nacl; - } - /* - * Locate our struct usbg_nacl and set the FC Nport WWPN - */ - nacl = container_of(se_nacl, struct usbg_nacl, se_node_acl); - nacl->iport_wwpn = wwpn; - snprintf(nacl->iport_name, sizeof(nacl->iport_name), "%s", name); - return se_nacl; -} - -static void usbg_drop_nodeacl(struct se_node_acl *se_acl) -{ - struct usbg_nacl *nacl = container_of(se_acl, - struct usbg_nacl, se_node_acl); - core_tpg_del_initiator_node_acl(se_acl->se_tpg, se_acl, 1); - kfree(nacl); -} - -struct usbg_tpg *the_only_tpg_I_currently_have; - -static struct se_portal_group *usbg_make_tpg( - struct se_wwn *wwn, - struct config_group *group, - const char *name) -{ - struct usbg_tport *tport = container_of(wwn, struct usbg_tport, - tport_wwn); - struct usbg_tpg *tpg; - unsigned long tpgt; - int ret; - - if (strstr(name, "tpgt_") != name) - return ERR_PTR(-EINVAL); - if (kstrtoul(name + 5, 0, &tpgt) || tpgt > UINT_MAX) - return ERR_PTR(-EINVAL); - if (the_only_tpg_I_currently_have) { - pr_err("Until the gadget framework can't handle multiple\n"); - pr_err("gadgets, you can't do this here.\n"); - return ERR_PTR(-EBUSY); - } - - tpg = kzalloc(sizeof(struct usbg_tpg), GFP_KERNEL); - if (!tpg) { - printk(KERN_ERR "Unable to allocate struct usbg_tpg"); - return ERR_PTR(-ENOMEM); - } - mutex_init(&tpg->tpg_mutex); - atomic_set(&tpg->tpg_port_count, 0); - tpg->workqueue = alloc_workqueue("tcm_usb_gadget", 0, 1); - if (!tpg->workqueue) { - kfree(tpg); - return NULL; - } - - tpg->tport = tport; - tpg->tport_tpgt = tpgt; - - ret = core_tpg_register(&usbg_fabric_configfs->tf_ops, wwn, - &tpg->se_tpg, tpg, - TRANSPORT_TPG_TYPE_NORMAL); - if (ret < 0) { - destroy_workqueue(tpg->workqueue); - kfree(tpg); - return NULL; - } - the_only_tpg_I_currently_have = tpg; - return &tpg->se_tpg; -} - -static void usbg_drop_tpg(struct se_portal_group *se_tpg) -{ - struct usbg_tpg *tpg = container_of(se_tpg, - struct usbg_tpg, se_tpg); - - core_tpg_deregister(se_tpg); - destroy_workqueue(tpg->workqueue); - kfree(tpg); - the_only_tpg_I_currently_have = NULL; -} - -static struct se_wwn *usbg_make_tport( - struct target_fabric_configfs *tf, - struct config_group *group, - const char *name) -{ - struct usbg_tport *tport; - const char *wnn_name; - u64 wwpn = 0; - - wnn_name = usbg_check_wwn(name); - if (!wnn_name) - return ERR_PTR(-EINVAL); - - tport = kzalloc(sizeof(struct usbg_tport), GFP_KERNEL); - if (!(tport)) { - printk(KERN_ERR "Unable to allocate struct usbg_tport"); - return ERR_PTR(-ENOMEM); - } - tport->tport_wwpn = wwpn; - snprintf(tport->tport_name, sizeof(tport->tport_name), wnn_name); - return &tport->tport_wwn; -} - -static void usbg_drop_tport(struct se_wwn *wwn) -{ - struct usbg_tport *tport = container_of(wwn, - struct usbg_tport, tport_wwn); - kfree(tport); -} - -/* - * If somebody feels like dropping the version property, go ahead. - */ -static ssize_t usbg_wwn_show_attr_version( - struct target_fabric_configfs *tf, - char *page) -{ - return sprintf(page, "usb-gadget fabric module\n"); -} -TF_WWN_ATTR_RO(usbg, version); - -static struct configfs_attribute *usbg_wwn_attrs[] = { - &usbg_wwn_version.attr, - NULL, -}; - -static ssize_t tcm_usbg_tpg_show_enable( - struct se_portal_group *se_tpg, - char *page) -{ - struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg); - - return snprintf(page, PAGE_SIZE, "%u\n", tpg->gadget_connect); -} - -static int usbg_attach(struct usbg_tpg *); -static void usbg_detach(struct usbg_tpg *); - -static ssize_t tcm_usbg_tpg_store_enable( - struct se_portal_group *se_tpg, - const char *page, - size_t count) -{ - struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg); - unsigned long op; - ssize_t ret; - - ret = kstrtoul(page, 0, &op); - if (ret < 0) - return -EINVAL; - if (op > 1) - return -EINVAL; - - if (op && tpg->gadget_connect) - goto out; - if (!op && !tpg->gadget_connect) - goto out; - - if (op) { - ret = usbg_attach(tpg); - if (ret) - goto out; - } else { - usbg_detach(tpg); - } - tpg->gadget_connect = op; -out: - return count; -} -TF_TPG_BASE_ATTR(tcm_usbg, enable, S_IRUGO | S_IWUSR); - -static ssize_t tcm_usbg_tpg_show_nexus( - struct se_portal_group *se_tpg, - char *page) -{ - struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg); - struct tcm_usbg_nexus *tv_nexus; - ssize_t ret; - - mutex_lock(&tpg->tpg_mutex); - tv_nexus = tpg->tpg_nexus; - if (!tv_nexus) { - ret = -ENODEV; - goto out; - } - ret = snprintf(page, PAGE_SIZE, "%s\n", - tv_nexus->tvn_se_sess->se_node_acl->initiatorname); -out: - mutex_unlock(&tpg->tpg_mutex); - return ret; -} - -static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name) -{ - struct se_portal_group *se_tpg; - struct tcm_usbg_nexus *tv_nexus; - int ret; - - mutex_lock(&tpg->tpg_mutex); - if (tpg->tpg_nexus) { - ret = -EEXIST; - pr_debug("tpg->tpg_nexus already exists\n"); - goto err_unlock; - } - se_tpg = &tpg->se_tpg; - - ret = -ENOMEM; - tv_nexus = kzalloc(sizeof(*tv_nexus), GFP_KERNEL); - if (!tv_nexus) { - pr_err("Unable to allocate struct tcm_vhost_nexus\n"); - goto err_unlock; - } - tv_nexus->tvn_se_sess = transport_init_session(); - if (IS_ERR(tv_nexus->tvn_se_sess)) - goto err_free; - - /* - * Since we are running in 'demo mode' this call with generate a - * struct se_node_acl for the tcm_vhost struct se_portal_group with - * the SCSI Initiator port name of the passed configfs group 'name'. - */ - tv_nexus->tvn_se_sess->se_node_acl = core_tpg_check_initiator_node_acl( - se_tpg, name); - if (!tv_nexus->tvn_se_sess->se_node_acl) { - pr_debug("core_tpg_check_initiator_node_acl() failed" - " for %s\n", name); - goto err_session; - } - /* - * Now register the TCM vHost virtual I_T Nexus as active with the - * call to __transport_register_session() - */ - __transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl, - tv_nexus->tvn_se_sess, tv_nexus); - tpg->tpg_nexus = tv_nexus; - mutex_unlock(&tpg->tpg_mutex); - return 0; - -err_session: - transport_free_session(tv_nexus->tvn_se_sess); -err_free: - kfree(tv_nexus); -err_unlock: - mutex_unlock(&tpg->tpg_mutex); - return ret; -} - -static int tcm_usbg_drop_nexus(struct usbg_tpg *tpg) -{ - struct se_session *se_sess; - struct tcm_usbg_nexus *tv_nexus; - int ret = -ENODEV; - - mutex_lock(&tpg->tpg_mutex); - tv_nexus = tpg->tpg_nexus; - if (!tv_nexus) - goto out; - - se_sess = tv_nexus->tvn_se_sess; - if (!se_sess) - goto out; - - if (atomic_read(&tpg->tpg_port_count)) { - ret = -EPERM; - pr_err("Unable to remove Host I_T Nexus with" - " active TPG port count: %d\n", - atomic_read(&tpg->tpg_port_count)); - goto out; - } - - pr_debug("Removing I_T Nexus to Initiator Port: %s\n", - tv_nexus->tvn_se_sess->se_node_acl->initiatorname); - /* - * Release the SCSI I_T Nexus to the emulated vHost Target Port - */ - transport_deregister_session(tv_nexus->tvn_se_sess); - tpg->tpg_nexus = NULL; - - kfree(tv_nexus); -out: - mutex_unlock(&tpg->tpg_mutex); - return 0; -} - -static ssize_t tcm_usbg_tpg_store_nexus( - struct se_portal_group *se_tpg, - const char *page, - size_t count) -{ - struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg); - unsigned char i_port[USBG_NAMELEN], *ptr; - int ret; - - if (!strncmp(page, "NULL", 4)) { - ret = tcm_usbg_drop_nexus(tpg); - return (!ret) ? count : ret; - } - if (strlen(page) > USBG_NAMELEN) { - pr_err("Emulated NAA Sas Address: %s, exceeds" - " max: %d\n", page, USBG_NAMELEN); - return -EINVAL; - } - snprintf(i_port, USBG_NAMELEN, "%s", page); - - ptr = strstr(i_port, "naa."); - if (!ptr) { - pr_err("Missing 'naa.' prefix\n"); - return -EINVAL; - } - - if (i_port[strlen(i_port) - 1] == '\n') - i_port[strlen(i_port) - 1] = '\0'; - - ret = tcm_usbg_make_nexus(tpg, &i_port[4]); - if (ret < 0) - return ret; - return count; -} -TF_TPG_BASE_ATTR(tcm_usbg, nexus, S_IRUGO | S_IWUSR); - -static struct configfs_attribute *usbg_base_attrs[] = { - &tcm_usbg_tpg_enable.attr, - &tcm_usbg_tpg_nexus.attr, - NULL, -}; - -static int usbg_port_link(struct se_portal_group *se_tpg, struct se_lun *lun) -{ - struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg); - - atomic_inc(&tpg->tpg_port_count); - smp_mb__after_atomic_inc(); - return 0; -} - -static void usbg_port_unlink(struct se_portal_group *se_tpg, - struct se_lun *se_lun) -{ - struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg); - - atomic_dec(&tpg->tpg_port_count); - smp_mb__after_atomic_dec(); -} - -static int usbg_check_stop_free(struct se_cmd *se_cmd) -{ - struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd, - se_cmd); - - kref_put(&cmd->ref, usbg_cmd_release); - return 1; -} - -static struct target_core_fabric_ops usbg_ops = { - .get_fabric_name = usbg_get_fabric_name, - .get_fabric_proto_ident = usbg_get_fabric_proto_ident, - .tpg_get_wwn = usbg_get_fabric_wwn, - .tpg_get_tag = usbg_get_tag, - .tpg_get_default_depth = usbg_get_default_depth, - .tpg_get_pr_transport_id = usbg_get_pr_transport_id, - .tpg_get_pr_transport_id_len = usbg_get_pr_transport_id_len, - .tpg_parse_pr_out_transport_id = usbg_parse_pr_out_transport_id, - .tpg_check_demo_mode = usbg_check_true, - .tpg_check_demo_mode_cache = usbg_check_false, - .tpg_check_demo_mode_write_protect = usbg_check_false, - .tpg_check_prod_mode_write_protect = usbg_check_false, - .tpg_alloc_fabric_acl = usbg_alloc_fabric_acl, - .tpg_release_fabric_acl = usbg_release_fabric_acl, - .tpg_get_inst_index = usbg_tpg_get_inst_index, - .new_cmd_map = usbg_new_cmd, - .release_cmd = usbg_release_cmd, - .shutdown_session = usbg_shutdown_session, - .close_session = usbg_close_session, - .sess_get_index = usbg_sess_get_index, - .sess_get_initiator_sid = NULL, - .write_pending = usbg_send_write_request, - .write_pending_status = usbg_write_pending_status, - .set_default_node_attributes = usbg_set_default_node_attrs, - .get_task_tag = usbg_get_task_tag, - .get_cmd_state = usbg_get_cmd_state, - .queue_data_in = usbg_send_read_response, - .queue_status = usbg_send_status_response, - .queue_tm_rsp = usbg_queue_tm_rsp, - .get_fabric_sense_len = usbg_get_fabric_sense_len, - .set_fabric_sense_len = usbg_set_fabric_sense_len, - .check_stop_free = usbg_check_stop_free, - - .fabric_make_wwn = usbg_make_tport, - .fabric_drop_wwn = usbg_drop_tport, - .fabric_make_tpg = usbg_make_tpg, - .fabric_drop_tpg = usbg_drop_tpg, - .fabric_post_link = usbg_port_link, - .fabric_pre_unlink = usbg_port_unlink, - .fabric_make_np = NULL, - .fabric_drop_np = NULL, - .fabric_make_nodeacl = usbg_make_nodeacl, - .fabric_drop_nodeacl = usbg_drop_nodeacl, -}; - -static int usbg_register_configfs(void) -{ - struct target_fabric_configfs *fabric; - int ret; - - fabric = target_fabric_configfs_init(THIS_MODULE, "usb_gadget"); - if (IS_ERR(fabric)) { - printk(KERN_ERR "target_fabric_configfs_init() failed\n"); - return PTR_ERR(fabric); - } - - fabric->tf_ops = usbg_ops; - TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = usbg_wwn_attrs; - TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = usbg_base_attrs; - TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = NULL; - TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = NULL; - TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL; - TF_CIT_TMPL(fabric)->tfc_tpg_nacl_base_cit.ct_attrs = NULL; - TF_CIT_TMPL(fabric)->tfc_tpg_nacl_attrib_cit.ct_attrs = NULL; - TF_CIT_TMPL(fabric)->tfc_tpg_nacl_auth_cit.ct_attrs = NULL; - TF_CIT_TMPL(fabric)->tfc_tpg_nacl_param_cit.ct_attrs = NULL; - ret = target_fabric_configfs_register(fabric); - if (ret < 0) { - printk(KERN_ERR "target_fabric_configfs_register() failed" - " for usb-gadget\n"); - return ret; - } - usbg_fabric_configfs = fabric; - return 0; -}; - -static void usbg_deregister_configfs(void) -{ - if (!(usbg_fabric_configfs)) - return; - - target_fabric_configfs_deregister(usbg_fabric_configfs); - usbg_fabric_configfs = NULL; -}; - -/* Start gadget.c code */ - -static struct usb_interface_descriptor bot_intf_desc = { - .bLength = sizeof(bot_intf_desc), - .bDescriptorType = USB_DT_INTERFACE, - .bAlternateSetting = 0, - .bNumEndpoints = 2, - .bAlternateSetting = USB_G_ALT_INT_BBB, - .bInterfaceClass = USB_CLASS_MASS_STORAGE, - .bInterfaceSubClass = USB_SC_SCSI, - .bInterfaceProtocol = USB_PR_BULK, - .iInterface = USB_G_STR_INT_UAS, -}; - -static struct usb_interface_descriptor uasp_intf_desc = { - .bLength = sizeof(uasp_intf_desc), - .bDescriptorType = USB_DT_INTERFACE, - .bNumEndpoints = 4, - .bAlternateSetting = USB_G_ALT_INT_UAS, - .bInterfaceClass = USB_CLASS_MASS_STORAGE, - .bInterfaceSubClass = USB_SC_SCSI, - .bInterfaceProtocol = USB_PR_UAS, - .iInterface = USB_G_STR_INT_BBB, -}; - -static struct usb_endpoint_descriptor uasp_bi_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor uasp_fs_bi_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_pipe_usage_descriptor uasp_bi_pipe_desc = { - .bLength = sizeof(uasp_bi_pipe_desc), - .bDescriptorType = USB_DT_PIPE_USAGE, - .bPipeID = DATA_IN_PIPE_ID, -}; - -static struct usb_endpoint_descriptor uasp_ss_bi_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(1024), -}; - -static struct usb_ss_ep_comp_descriptor uasp_bi_ep_comp_desc = { - .bLength = sizeof(uasp_bi_ep_comp_desc), - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, - .bMaxBurst = 0, - .bmAttributes = UASP_SS_EP_COMP_LOG_STREAMS, - .wBytesPerInterval = 0, -}; - -static struct usb_ss_ep_comp_descriptor bot_bi_ep_comp_desc = { - .bLength = sizeof(bot_bi_ep_comp_desc), - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, - .bMaxBurst = 0, -}; - -static struct usb_endpoint_descriptor uasp_bo_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor uasp_fs_bo_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_pipe_usage_descriptor uasp_bo_pipe_desc = { - .bLength = sizeof(uasp_bo_pipe_desc), - .bDescriptorType = USB_DT_PIPE_USAGE, - .bPipeID = DATA_OUT_PIPE_ID, -}; - -static struct usb_endpoint_descriptor uasp_ss_bo_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(0x400), -}; - -static struct usb_ss_ep_comp_descriptor uasp_bo_ep_comp_desc = { - .bLength = sizeof(uasp_bo_ep_comp_desc), - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, - .bmAttributes = UASP_SS_EP_COMP_LOG_STREAMS, -}; - -static struct usb_ss_ep_comp_descriptor bot_bo_ep_comp_desc = { - .bLength = sizeof(bot_bo_ep_comp_desc), - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, -}; - -static struct usb_endpoint_descriptor uasp_status_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor uasp_fs_status_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_pipe_usage_descriptor uasp_status_pipe_desc = { - .bLength = sizeof(uasp_status_pipe_desc), - .bDescriptorType = USB_DT_PIPE_USAGE, - .bPipeID = STATUS_PIPE_ID, -}; - -static struct usb_endpoint_descriptor uasp_ss_status_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(1024), -}; - -static struct usb_ss_ep_comp_descriptor uasp_status_in_ep_comp_desc = { - .bLength = sizeof(uasp_status_in_ep_comp_desc), - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, - .bmAttributes = UASP_SS_EP_COMP_LOG_STREAMS, -}; - -static struct usb_endpoint_descriptor uasp_cmd_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor uasp_fs_cmd_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, -}; - -static struct usb_pipe_usage_descriptor uasp_cmd_pipe_desc = { - .bLength = sizeof(uasp_cmd_pipe_desc), - .bDescriptorType = USB_DT_PIPE_USAGE, - .bPipeID = CMD_PIPE_ID, -}; - -static struct usb_endpoint_descriptor uasp_ss_cmd_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(1024), -}; - -static struct usb_ss_ep_comp_descriptor uasp_cmd_comp_desc = { - .bLength = sizeof(uasp_cmd_comp_desc), - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, -}; - -static struct usb_descriptor_header *uasp_fs_function_desc[] = { - (struct usb_descriptor_header *) &bot_intf_desc, - (struct usb_descriptor_header *) &uasp_fs_bi_desc, - (struct usb_descriptor_header *) &uasp_fs_bo_desc, - - (struct usb_descriptor_header *) &uasp_intf_desc, - (struct usb_descriptor_header *) &uasp_fs_bi_desc, - (struct usb_descriptor_header *) &uasp_bi_pipe_desc, - (struct usb_descriptor_header *) &uasp_fs_bo_desc, - (struct usb_descriptor_header *) &uasp_bo_pipe_desc, - (struct usb_descriptor_header *) &uasp_fs_status_desc, - (struct usb_descriptor_header *) &uasp_status_pipe_desc, - (struct usb_descriptor_header *) &uasp_fs_cmd_desc, - (struct usb_descriptor_header *) &uasp_cmd_pipe_desc, -}; - -static struct usb_descriptor_header *uasp_hs_function_desc[] = { - (struct usb_descriptor_header *) &bot_intf_desc, - (struct usb_descriptor_header *) &uasp_bi_desc, - (struct usb_descriptor_header *) &uasp_bo_desc, - - (struct usb_descriptor_header *) &uasp_intf_desc, - (struct usb_descriptor_header *) &uasp_bi_desc, - (struct usb_descriptor_header *) &uasp_bi_pipe_desc, - (struct usb_descriptor_header *) &uasp_bo_desc, - (struct usb_descriptor_header *) &uasp_bo_pipe_desc, - (struct usb_descriptor_header *) &uasp_status_desc, - (struct usb_descriptor_header *) &uasp_status_pipe_desc, - (struct usb_descriptor_header *) &uasp_cmd_desc, - (struct usb_descriptor_header *) &uasp_cmd_pipe_desc, - NULL, -}; - -static struct usb_descriptor_header *uasp_ss_function_desc[] = { - (struct usb_descriptor_header *) &bot_intf_desc, - (struct usb_descriptor_header *) &uasp_ss_bi_desc, - (struct usb_descriptor_header *) &bot_bi_ep_comp_desc, - (struct usb_descriptor_header *) &uasp_ss_bo_desc, - (struct usb_descriptor_header *) &bot_bo_ep_comp_desc, - - (struct usb_descriptor_header *) &uasp_intf_desc, - (struct usb_descriptor_header *) &uasp_ss_bi_desc, - (struct usb_descriptor_header *) &uasp_bi_ep_comp_desc, - (struct usb_descriptor_header *) &uasp_bi_pipe_desc, - (struct usb_descriptor_header *) &uasp_ss_bo_desc, - (struct usb_descriptor_header *) &uasp_bo_ep_comp_desc, - (struct usb_descriptor_header *) &uasp_bo_pipe_desc, - (struct usb_descriptor_header *) &uasp_ss_status_desc, - (struct usb_descriptor_header *) &uasp_status_in_ep_comp_desc, - (struct usb_descriptor_header *) &uasp_status_pipe_desc, - (struct usb_descriptor_header *) &uasp_ss_cmd_desc, - (struct usb_descriptor_header *) &uasp_cmd_comp_desc, - (struct usb_descriptor_header *) &uasp_cmd_pipe_desc, - NULL, -}; - -#define UAS_VENDOR_ID 0x0525 /* NetChip */ -#define UAS_PRODUCT_ID 0xa4a5 /* Linux-USB File-backed Storage Gadget */ - -static struct usb_device_descriptor usbg_device_desc = { - .bLength = sizeof(usbg_device_desc), - .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = cpu_to_le16(0x0200), - .bDeviceClass = USB_CLASS_PER_INTERFACE, - .idVendor = cpu_to_le16(UAS_VENDOR_ID), - .idProduct = cpu_to_le16(UAS_PRODUCT_ID), - .iManufacturer = USB_G_STR_MANUFACTOR, - .iProduct = USB_G_STR_PRODUCT, - .iSerialNumber = USB_G_STR_SERIAL, - - .bNumConfigurations = 1, -}; - -static struct usb_string usbg_us_strings[] = { - { USB_G_STR_MANUFACTOR, "Target Manufactor"}, - { USB_G_STR_PRODUCT, "Target Product"}, - { USB_G_STR_SERIAL, "000000000001"}, - { USB_G_STR_CONFIG, "default config"}, - { USB_G_STR_INT_UAS, "USB Attached SCSI"}, - { USB_G_STR_INT_BBB, "Bulk Only Transport"}, - { }, -}; - -static struct usb_gadget_strings usbg_stringtab = { - .language = 0x0409, - .strings = usbg_us_strings, -}; - -static struct usb_gadget_strings *usbg_strings[] = { - &usbg_stringtab, - NULL, -}; - -static int guas_unbind(struct usb_composite_dev *cdev) -{ - return 0; -} - -static struct usb_configuration usbg_config_driver = { - .label = "Linux Target", - .bConfigurationValue = 1, - .iConfiguration = USB_G_STR_CONFIG, - .bmAttributes = USB_CONFIG_ATT_SELFPOWER, -}; - -static void give_back_ep(struct usb_ep **pep) -{ - struct usb_ep *ep = *pep; - if (!ep) - return; - ep->driver_data = NULL; -} - -static int usbg_bind(struct usb_configuration *c, struct usb_function *f) -{ - struct f_uas *fu = to_f_uas(f); - struct usb_gadget *gadget = c->cdev->gadget; - struct usb_ep *ep; - int iface; - - iface = usb_interface_id(c, f); - if (iface < 0) - return iface; - - bot_intf_desc.bInterfaceNumber = iface; - uasp_intf_desc.bInterfaceNumber = iface; - fu->iface = iface; - ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bi_desc, - &uasp_bi_ep_comp_desc); - if (!ep) - goto ep_fail; - - ep->driver_data = fu; - fu->ep_in = ep; - - ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bo_desc, - &uasp_bo_ep_comp_desc); - if (!ep) - goto ep_fail; - ep->driver_data = fu; - fu->ep_out = ep; - - ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_status_desc, - &uasp_status_in_ep_comp_desc); - if (!ep) - goto ep_fail; - ep->driver_data = fu; - fu->ep_status = ep; - - ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_cmd_desc, - &uasp_cmd_comp_desc); - if (!ep) - goto ep_fail; - ep->driver_data = fu; - fu->ep_cmd = ep; - - /* Assume endpoint addresses are the same for both speeds */ - uasp_bi_desc.bEndpointAddress = uasp_ss_bi_desc.bEndpointAddress; - uasp_bo_desc.bEndpointAddress = uasp_ss_bo_desc.bEndpointAddress; - uasp_status_desc.bEndpointAddress = - uasp_ss_status_desc.bEndpointAddress; - uasp_cmd_desc.bEndpointAddress = uasp_ss_cmd_desc.bEndpointAddress; - - uasp_fs_bi_desc.bEndpointAddress = uasp_ss_bi_desc.bEndpointAddress; - uasp_fs_bo_desc.bEndpointAddress = uasp_ss_bo_desc.bEndpointAddress; - uasp_fs_status_desc.bEndpointAddress = - uasp_ss_status_desc.bEndpointAddress; - uasp_fs_cmd_desc.bEndpointAddress = uasp_ss_cmd_desc.bEndpointAddress; - - return 0; -ep_fail: - pr_err("Can't claim all required eps\n"); - - give_back_ep(&fu->ep_in); - give_back_ep(&fu->ep_out); - give_back_ep(&fu->ep_status); - give_back_ep(&fu->ep_cmd); - return -ENOTSUPP; -} - -static void usbg_unbind(struct usb_configuration *c, struct usb_function *f) -{ - struct f_uas *fu = to_f_uas(f); - - kfree(fu); -} - -struct guas_setup_wq { - struct work_struct work; - struct f_uas *fu; - unsigned int alt; -}; - -static void usbg_delayed_set_alt(struct work_struct *wq) -{ - struct guas_setup_wq *work = container_of(wq, struct guas_setup_wq, - work); - struct f_uas *fu = work->fu; - int alt = work->alt; - - kfree(work); - - if (fu->flags & USBG_IS_BOT) - bot_cleanup_old_alt(fu); - if (fu->flags & USBG_IS_UAS) - uasp_cleanup_old_alt(fu); - - if (alt == USB_G_ALT_INT_BBB) - bot_set_alt(fu); - else if (alt == USB_G_ALT_INT_UAS) - uasp_set_alt(fu); - usb_composite_setup_continue(fu->function.config->cdev); -} - -static int usbg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) -{ - struct f_uas *fu = to_f_uas(f); - - if ((alt == USB_G_ALT_INT_BBB) || (alt == USB_G_ALT_INT_UAS)) { - struct guas_setup_wq *work; - - work = kmalloc(sizeof(*work), GFP_ATOMIC); - if (!work) - return -ENOMEM; - INIT_WORK(&work->work, usbg_delayed_set_alt); - work->fu = fu; - work->alt = alt; - schedule_work(&work->work); - return USB_GADGET_DELAYED_STATUS; - } - return -EOPNOTSUPP; -} - -static void usbg_disable(struct usb_function *f) -{ - struct f_uas *fu = to_f_uas(f); - - if (fu->flags & USBG_IS_UAS) - uasp_cleanup_old_alt(fu); - else if (fu->flags & USBG_IS_BOT) - bot_cleanup_old_alt(fu); - fu->flags = 0; -} - -static int usbg_setup(struct usb_function *f, - const struct usb_ctrlrequest *ctrl) -{ - struct f_uas *fu = to_f_uas(f); - - if (!(fu->flags & USBG_IS_BOT)) - return -EOPNOTSUPP; - - return usbg_bot_setup(f, ctrl); -} - -static int usbg_cfg_bind(struct usb_configuration *c) -{ - struct f_uas *fu; - int ret; - - fu = kzalloc(sizeof(*fu), GFP_KERNEL); - if (!fu) - return -ENOMEM; - fu->function.name = "Target Function"; - fu->function.descriptors = uasp_fs_function_desc; - fu->function.hs_descriptors = uasp_hs_function_desc; - fu->function.ss_descriptors = uasp_ss_function_desc; - fu->function.bind = usbg_bind; - fu->function.unbind = usbg_unbind; - fu->function.set_alt = usbg_set_alt; - fu->function.setup = usbg_setup; - fu->function.disable = usbg_disable; - fu->tpg = the_only_tpg_I_currently_have; - - ret = usb_add_function(c, &fu->function); - if (ret) - goto err; - - return 0; -err: - kfree(fu); - return ret; -} - -static int usb_target_bind(struct usb_composite_dev *cdev) -{ - int ret; - - ret = usb_add_config(cdev, &usbg_config_driver, - usbg_cfg_bind); - return 0; -} - -static struct usb_composite_driver usbg_driver = { - .name = "g_target", - .dev = &usbg_device_desc, - .strings = usbg_strings, - .max_speed = USB_SPEED_SUPER, - .unbind = guas_unbind, -}; - -static int usbg_attach(struct usbg_tpg *tpg) -{ - return usb_composite_probe(&usbg_driver, usb_target_bind); -} - -static void usbg_detach(struct usbg_tpg *tpg) -{ - usb_composite_unregister(&usbg_driver); -} - -static int __init usb_target_gadget_init(void) -{ - int ret; - - ret = usbg_register_configfs(); - return ret; -} -module_init(usb_target_gadget_init); - -static void __exit usb_target_gadget_exit(void) -{ - usbg_deregister_configfs(); -} -module_exit(usb_target_gadget_exit); - -MODULE_AUTHOR("Sebastian Andrzej Siewior "); -MODULE_DESCRIPTION("usb-gadget fabric"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/usb/gadget/tcm_usb_gadget.h b/trunk/drivers/usb/gadget/tcm_usb_gadget.h deleted file mode 100644 index bb18999a9a8d..000000000000 --- a/trunk/drivers/usb/gadget/tcm_usb_gadget.h +++ /dev/null @@ -1,146 +0,0 @@ -#ifndef __TARGET_USB_GADGET_H__ -#define __TARGET_USB_GADGET_H__ - -#include -/* #include */ -#include -#include -#include -#include -#include -#include - -#define USBG_NAMELEN 32 - -#define fuas_to_gadget(f) (f->function.config->cdev->gadget) -#define UASP_SS_EP_COMP_LOG_STREAMS 4 -#define UASP_SS_EP_COMP_NUM_STREAMS (1 << UASP_SS_EP_COMP_LOG_STREAMS) - -#define USB_G_STR_MANUFACTOR 1 -#define USB_G_STR_PRODUCT 2 -#define USB_G_STR_SERIAL 3 -#define USB_G_STR_CONFIG 4 -#define USB_G_STR_INT_UAS 5 -#define USB_G_STR_INT_BBB 6 - -#define USB_G_ALT_INT_BBB 0 -#define USB_G_ALT_INT_UAS 1 - -struct usbg_nacl { - /* Binary World Wide unique Port Name for SAS Initiator port */ - u64 iport_wwpn; - /* ASCII formatted WWPN for Sas Initiator port */ - char iport_name[USBG_NAMELEN]; - /* Returned by usbg_make_nodeacl() */ - struct se_node_acl se_node_acl; -}; - -struct tcm_usbg_nexus { - struct se_session *tvn_se_sess; -}; - -struct usbg_tpg { - struct mutex tpg_mutex; - /* SAS port target portal group tag for TCM */ - u16 tport_tpgt; - /* Pointer back to usbg_tport */ - struct usbg_tport *tport; - struct workqueue_struct *workqueue; - /* Returned by usbg_make_tpg() */ - struct se_portal_group se_tpg; - u32 gadget_connect; - struct tcm_usbg_nexus *tpg_nexus; - atomic_t tpg_port_count; -}; - -struct usbg_tport { - /* SCSI protocol the tport is providing */ - u8 tport_proto_id; - /* Binary World Wide unique Port Name for SAS Target port */ - u64 tport_wwpn; - /* ASCII formatted WWPN for SAS Target port */ - char tport_name[USBG_NAMELEN]; - /* Returned by usbg_make_tport() */ - struct se_wwn tport_wwn; -}; - -enum uas_state { - UASP_SEND_DATA, - UASP_RECEIVE_DATA, - UASP_SEND_STATUS, - UASP_QUEUE_COMMAND, -}; - -#define USBG_MAX_CMD 64 -struct usbg_cmd { - /* common */ - u8 cmd_buf[USBG_MAX_CMD]; - u32 data_len; - struct work_struct work; - int unpacked_lun; - struct se_cmd se_cmd; - void *data_buf; /* used if no sg support available */ - struct f_uas *fu; - struct completion write_complete; - struct kref ref; - - /* UAS only */ - u16 tag; - u16 prio_attr; - struct sense_iu sense_iu; - enum uas_state state; - struct uas_stream *stream; - - /* BOT only */ - __le32 bot_tag; - unsigned int csw_code; - unsigned is_read:1; - -}; - -struct uas_stream { - struct usb_request *req_in; - struct usb_request *req_out; - struct usb_request *req_status; -}; - -struct usbg_cdb { - struct usb_request *req; - void *buf; -}; - -struct bot_status { - struct usb_request *req; - struct bulk_cs_wrap csw; -}; - -struct f_uas { - struct usbg_tpg *tpg; - struct usb_function function; - u16 iface; - - u32 flags; -#define USBG_ENABLED (1 << 0) -#define USBG_IS_UAS (1 << 1) -#define USBG_USE_STREAMS (1 << 2) -#define USBG_IS_BOT (1 << 3) -#define USBG_BOT_CMD_PEND (1 << 4) - - struct usbg_cdb cmd; - struct usb_ep *ep_in; - struct usb_ep *ep_out; - - /* UAS */ - struct usb_ep *ep_status; - struct usb_ep *ep_cmd; - struct uas_stream stream[UASP_SS_EP_COMP_NUM_STREAMS]; - - /* BOT */ - struct bot_status bot_status; - struct usb_request *bot_req_in; - struct usb_request *bot_req_out; -}; - -extern struct usbg_tpg *the_only_tpg_I_currently_have; - -#endif diff --git a/trunk/drivers/usb/musb/musb_io.h b/trunk/drivers/usb/musb/musb_io.h index f7c1c8e2dc3f..1d5eda26fbd1 100644 --- a/trunk/drivers/usb/musb/musb_io.h +++ b/trunk/drivers/usb/musb/musb_io.h @@ -40,7 +40,7 @@ #if !defined(CONFIG_ARM) && !defined(CONFIG_SUPERH) \ && !defined(CONFIG_AVR32) && !defined(CONFIG_PPC32) \ && !defined(CONFIG_PPC64) && !defined(CONFIG_BLACKFIN) \ - && !defined(CONFIG_MIPS) && !defined(CONFIG_M68K) + && !defined(CONFIG_MIPS) static inline void readsl(const void __iomem *addr, void *buf, int len) { insl((unsigned long)addr, buf, len); } static inline void readsw(const void __iomem *addr, void *buf, int len) diff --git a/trunk/drivers/vhost/net.c b/trunk/drivers/vhost/net.c index f82a7394756e..853db7a08a26 100644 --- a/trunk/drivers/vhost/net.c +++ b/trunk/drivers/vhost/net.c @@ -24,7 +24,6 @@ #include #include #include -#include #include @@ -287,12 +286,8 @@ static int peek_head_len(struct sock *sk) spin_lock_irqsave(&sk->sk_receive_queue.lock, flags); head = skb_peek(&sk->sk_receive_queue); - if (likely(head)) { + if (likely(head)) len = head->len; - if (vlan_tx_tag_present(head)) - len += VLAN_HLEN; - } - spin_unlock_irqrestore(&sk->sk_receive_queue.lock, flags); return len; } diff --git a/trunk/drivers/video/console/sticore.c b/trunk/drivers/video/console/sticore.c index 39571f9e0162..6468a297e341 100644 --- a/trunk/drivers/video/console/sticore.c +++ b/trunk/drivers/video/console/sticore.c @@ -22,9 +22,7 @@ #include #include -#include #include -#include #include #include diff --git a/trunk/drivers/video/sh_mobile_lcdcfb.c b/trunk/drivers/video/sh_mobile_lcdcfb.c index e672698bd820..7a0b301587f6 100644 --- a/trunk/drivers/video/sh_mobile_lcdcfb.c +++ b/trunk/drivers/video/sh_mobile_lcdcfb.c @@ -758,7 +758,7 @@ static void __sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) } lcdc_write_chan(ch, LDDFR, tmp); - lcdc_write_chan(ch, LDMLSR, ch->line_size); + lcdc_write_chan(ch, LDMLSR, ch->pitch); lcdc_write_chan(ch, LDSA1R, ch->base_addr_y); if (ch->format->yuv) lcdc_write_chan(ch, LDSA2R, ch->base_addr_c); @@ -847,7 +847,6 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) ch->base_addr_y = ch->dma_handle; ch->base_addr_c = ch->base_addr_y + ch->xres * ch->yres_virtual; - ch->line_size = ch->pitch; /* Enable MERAM if possible. */ if (mdev == NULL || mdev->ops == NULL || @@ -883,7 +882,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) meram = mdev->ops->meram_register(mdev, ch->cfg->meram_cfg, ch->pitch, ch->yres, pixelformat, - &ch->line_size); + &ch->pitch); if (!IS_ERR(meram)) { mdev->ops->meram_update(mdev, meram, ch->base_addr_y, ch->base_addr_c, diff --git a/trunk/drivers/video/sh_mobile_lcdcfb.h b/trunk/drivers/video/sh_mobile_lcdcfb.h index 5c3bddd2cb72..da1c26e78a57 100644 --- a/trunk/drivers/video/sh_mobile_lcdcfb.h +++ b/trunk/drivers/video/sh_mobile_lcdcfb.h @@ -84,7 +84,6 @@ struct sh_mobile_lcdc_chan { unsigned long base_addr_y; unsigned long base_addr_c; - unsigned int line_size; int (*notify)(struct sh_mobile_lcdc_chan *ch, enum sh_mobile_lcdc_entity_event event, diff --git a/trunk/drivers/video/uvesafb.c b/trunk/drivers/video/uvesafb.c index b0e2a4261afe..26e83d7fdd6f 100644 --- a/trunk/drivers/video/uvesafb.c +++ b/trunk/drivers/video/uvesafb.c @@ -73,7 +73,7 @@ static void uvesafb_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *ns struct uvesafb_task *utask; struct uvesafb_ktask *task; - if (!capable(CAP_SYS_ADMIN)) + if (!cap_raised(current_cap(), CAP_SYS_ADMIN)) return; if (msg->seq >= UVESAFB_TASKS_MAX) diff --git a/trunk/drivers/video/xen-fbfront.c b/trunk/drivers/video/xen-fbfront.c index b7f5173ff9e9..cb4529c40d74 100644 --- a/trunk/drivers/video/xen-fbfront.c +++ b/trunk/drivers/video/xen-fbfront.c @@ -365,7 +365,7 @@ static int __devinit xenfb_probe(struct xenbus_device *dev, struct fb_info *fb_info; int fb_size; int val; - int ret = 0; + int ret; info = kzalloc(sizeof(*info), GFP_KERNEL); if (info == NULL) { @@ -458,31 +458,26 @@ static int __devinit xenfb_probe(struct xenbus_device *dev, xenfb_init_shared_page(info, fb_info); ret = xenfb_connect_backend(dev, info); - if (ret < 0) { - xenbus_dev_fatal(dev, ret, "xenfb_connect_backend"); - goto error_fb; - } + if (ret < 0) + goto error; ret = register_framebuffer(fb_info); if (ret) { + fb_deferred_io_cleanup(fb_info); + fb_dealloc_cmap(&fb_info->cmap); + framebuffer_release(fb_info); xenbus_dev_fatal(dev, ret, "register_framebuffer"); - goto error_fb; + goto error; } info->fb_info = fb_info; xenfb_make_preferred_console(); return 0; -error_fb: - fb_deferred_io_cleanup(fb_info); - fb_dealloc_cmap(&fb_info->cmap); - framebuffer_release(fb_info); -error_nomem: - if (!ret) { - ret = -ENOMEM; - xenbus_dev_fatal(dev, ret, "allocating device memory"); - } -error: + error_nomem: + ret = -ENOMEM; + xenbus_dev_fatal(dev, ret, "allocating device memory"); + error: xenfb_remove(dev); return ret; } diff --git a/trunk/drivers/virtio/Kconfig b/trunk/drivers/virtio/Kconfig index f38b17a86c35..1a61939b85fc 100644 --- a/trunk/drivers/virtio/Kconfig +++ b/trunk/drivers/virtio/Kconfig @@ -46,15 +46,4 @@ config VIRTIO_BALLOON If unsure, say N. -config VIRTIO_MMIO_CMDLINE_DEVICES - bool "Memory mapped virtio devices parameter parsing" - depends on VIRTIO_MMIO - ---help--- - Allow virtio-mmio devices instantiation via the kernel command line - or module parameters. Be aware that using incorrect parameters (base - address in particular) can crash your system - you have been warned. - See Documentation/kernel-parameters.txt for details. - - If unsure, say 'N'. - endmenu diff --git a/trunk/drivers/virtio/virtio.c b/trunk/drivers/virtio/virtio.c index f3558070e375..984c501c258f 100644 --- a/trunk/drivers/virtio/virtio.c +++ b/trunk/drivers/virtio/virtio.c @@ -2,10 +2,9 @@ #include #include #include -#include /* Unique numbering for virtio devices. */ -static DEFINE_IDA(virtio_index_ida); +static unsigned int dev_index; static ssize_t device_show(struct device *_d, struct device_attribute *attr, char *buf) @@ -194,11 +193,7 @@ int register_virtio_device(struct virtio_device *dev) dev->dev.bus = &virtio_bus; /* Assign a unique device index and hence name. */ - err = ida_simple_get(&virtio_index_ida, 0, 0, GFP_KERNEL); - if (err < 0) - goto out; - - dev->index = err; + dev->index = dev_index++; dev_set_name(&dev->dev, "virtio%u", dev->index); /* We always start by resetting the device, in case a previous @@ -213,7 +208,6 @@ int register_virtio_device(struct virtio_device *dev) /* device_register() causes the bus infrastructure to look for a * matching driver. */ err = device_register(&dev->dev); -out: if (err) add_status(dev, VIRTIO_CONFIG_S_FAILED); return err; @@ -223,7 +217,6 @@ EXPORT_SYMBOL_GPL(register_virtio_device); void unregister_virtio_device(struct virtio_device *dev) { device_unregister(&dev->dev); - ida_simple_remove(&virtio_index_ida, dev->index); } EXPORT_SYMBOL_GPL(unregister_virtio_device); diff --git a/trunk/drivers/virtio/virtio_balloon.c b/trunk/drivers/virtio/virtio_balloon.c index bfbc15ca38dd..c2d05a8279fd 100644 --- a/trunk/drivers/virtio/virtio_balloon.c +++ b/trunk/drivers/virtio/virtio_balloon.c @@ -381,25 +381,20 @@ static int virtballoon_probe(struct virtio_device *vdev) return err; } -static void remove_common(struct virtio_balloon *vb) +static void __devexit virtballoon_remove(struct virtio_device *vdev) { + struct virtio_balloon *vb = vdev->priv; + + kthread_stop(vb->thread); + /* There might be pages left in the balloon: free them. */ while (vb->num_pages) leak_balloon(vb, vb->num_pages); - update_balloon_size(vb); /* Now we reset the device so we can clean up the queues. */ - vb->vdev->config->reset(vb->vdev); - - vb->vdev->config->del_vqs(vb->vdev); -} - -static void __devexit virtballoon_remove(struct virtio_device *vdev) -{ - struct virtio_balloon *vb = vdev->priv; + vdev->config->reset(vdev); - kthread_stop(vb->thread); - remove_common(vb); + vdev->config->del_vqs(vdev); kfree(vb); } @@ -413,11 +408,17 @@ static int virtballoon_freeze(struct virtio_device *vdev) * function is called. */ - remove_common(vb); + while (vb->num_pages) + leak_balloon(vb, vb->num_pages); + update_balloon_size(vb); + + /* Ensure we don't get any more requests from the host */ + vdev->config->reset(vdev); + vdev->config->del_vqs(vdev); return 0; } -static int virtballoon_restore(struct virtio_device *vdev) +static int restore_common(struct virtio_device *vdev) { struct virtio_balloon *vb = vdev->priv; int ret; @@ -430,6 +431,11 @@ static int virtballoon_restore(struct virtio_device *vdev) update_balloon_size(vb); return 0; } + +static int virtballoon_restore(struct virtio_device *vdev) +{ + return restore_common(vdev); +} #endif static unsigned int features[] = { diff --git a/trunk/drivers/virtio/virtio_mmio.c b/trunk/drivers/virtio/virtio_mmio.c index 453db0c403d8..01d6dc250d5c 100644 --- a/trunk/drivers/virtio/virtio_mmio.c +++ b/trunk/drivers/virtio/virtio_mmio.c @@ -6,50 +6,6 @@ * This module allows virtio devices to be used over a virtual, memory mapped * platform device. * - * The guest device(s) may be instantiated in one of three equivalent ways: - * - * 1. Static platform device in board's code, eg.: - * - * static struct platform_device v2m_virtio_device = { - * .name = "virtio-mmio", - * .id = -1, - * .num_resources = 2, - * .resource = (struct resource []) { - * { - * .start = 0x1001e000, - * .end = 0x1001e0ff, - * .flags = IORESOURCE_MEM, - * }, { - * .start = 42 + 32, - * .end = 42 + 32, - * .flags = IORESOURCE_IRQ, - * }, - * } - * }; - * - * 2. Device Tree node, eg.: - * - * virtio_block@1e000 { - * compatible = "virtio,mmio"; - * reg = <0x1e000 0x100>; - * interrupts = <42>; - * } - * - * 3. Kernel module (or command line) parameter. Can be used more than once - - * one device will be created for each one. Syntax: - * - * [virtio_mmio.]device=@:[:] - * where: - * := size (can use standard suffixes like K, M or G) - * := physical base address - * := interrupt number (as passed to request_irq()) - * := (optional) platform device id - * eg.: - * virtio_mmio.device=0x100@0x100b0000:48 \ - * virtio_mmio.device=1K@0x1001e000:74 - * - * - * * Registers layout (all 32-bit wide): * * offset d. name description @@ -86,8 +42,6 @@ * See the COPYING file in the top-level directory. */ -#define pr_fmt(fmt) "virtio-mmio: " fmt - #include #include #include @@ -495,122 +449,6 @@ static int __devexit virtio_mmio_remove(struct platform_device *pdev) -/* Devices list parameter */ - -#if defined(CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES) - -static struct device vm_cmdline_parent = { - .init_name = "virtio-mmio-cmdline", -}; - -static int vm_cmdline_parent_registered; -static int vm_cmdline_id; - -static int vm_cmdline_set(const char *device, - const struct kernel_param *kp) -{ - int err; - struct resource resources[2] = {}; - char *str; - long long int base; - int processed, consumed = 0; - struct platform_device *pdev; - - resources[0].flags = IORESOURCE_MEM; - resources[1].flags = IORESOURCE_IRQ; - - resources[0].end = memparse(device, &str) - 1; - - processed = sscanf(str, "@%lli:%u%n:%d%n", - &base, &resources[1].start, &consumed, - &vm_cmdline_id, &consumed); - - if (processed < 2 || processed > 3 || str[consumed]) - return -EINVAL; - - resources[0].start = base; - resources[0].end += base; - resources[1].end = resources[1].start; - - if (!vm_cmdline_parent_registered) { - err = device_register(&vm_cmdline_parent); - if (err) { - pr_err("Failed to register parent device!\n"); - return err; - } - vm_cmdline_parent_registered = 1; - } - - pr_info("Registering device virtio-mmio.%d at 0x%llx-0x%llx, IRQ %d.\n", - vm_cmdline_id, - (unsigned long long)resources[0].start, - (unsigned long long)resources[0].end, - (int)resources[1].start); - - pdev = platform_device_register_resndata(&vm_cmdline_parent, - "virtio-mmio", vm_cmdline_id++, - resources, ARRAY_SIZE(resources), NULL, 0); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - - return 0; -} - -static int vm_cmdline_get_device(struct device *dev, void *data) -{ - char *buffer = data; - unsigned int len = strlen(buffer); - struct platform_device *pdev = to_platform_device(dev); - - snprintf(buffer + len, PAGE_SIZE - len, "0x%llx@0x%llx:%llu:%d\n", - pdev->resource[0].end - pdev->resource[0].start + 1ULL, - (unsigned long long)pdev->resource[0].start, - (unsigned long long)pdev->resource[1].start, - pdev->id); - return 0; -} - -static int vm_cmdline_get(char *buffer, const struct kernel_param *kp) -{ - buffer[0] = '\0'; - device_for_each_child(&vm_cmdline_parent, buffer, - vm_cmdline_get_device); - return strlen(buffer) + 1; -} - -static struct kernel_param_ops vm_cmdline_param_ops = { - .set = vm_cmdline_set, - .get = vm_cmdline_get, -}; - -device_param_cb(device, &vm_cmdline_param_ops, NULL, S_IRUSR); - -static int vm_unregister_cmdline_device(struct device *dev, - void *data) -{ - platform_device_unregister(to_platform_device(dev)); - - return 0; -} - -static void vm_unregister_cmdline_devices(void) -{ - if (vm_cmdline_parent_registered) { - device_for_each_child(&vm_cmdline_parent, NULL, - vm_unregister_cmdline_device); - device_unregister(&vm_cmdline_parent); - vm_cmdline_parent_registered = 0; - } -} - -#else - -static void vm_unregister_cmdline_devices(void) -{ -} - -#endif - /* Platform driver */ static struct of_device_id virtio_mmio_match[] = { @@ -637,7 +475,6 @@ static int __init virtio_mmio_init(void) static void __exit virtio_mmio_exit(void) { platform_driver_unregister(&virtio_mmio_driver); - vm_unregister_cmdline_devices(); } module_init(virtio_mmio_init); diff --git a/trunk/drivers/watchdog/hpwdt.c b/trunk/drivers/watchdog/hpwdt.c index 23885f2d56a0..9f13b897fd64 100644 --- a/trunk/drivers/watchdog/hpwdt.c +++ b/trunk/drivers/watchdog/hpwdt.c @@ -147,6 +147,7 @@ struct cmn_registers { static unsigned int hpwdt_nmi_decoding; static unsigned int allow_kdump; +static unsigned int priority; /* hpwdt at end of die_notify list */ static unsigned int is_icru; static DEFINE_SPINLOCK(rom_lock); static void *cru_rom_addr; @@ -722,35 +723,28 @@ static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev) } /* - * Only one function can register for NMI_UNKNOWN + * If the priority is set to 1, then we will be put first on the + * die notify list to handle a critical NMI. The default is to + * be last so other users of the NMI signal can function. */ - retval = register_nmi_handler(NMI_UNKNOWN, hpwdt_pretimeout, 0, "hpwdt"); - if (retval) - goto error; - retval = register_nmi_handler(NMI_SERR, hpwdt_pretimeout, 0, "hpwdt"); - if (retval) - goto error1; - retval = register_nmi_handler(NMI_IO_CHECK, hpwdt_pretimeout, 0, "hpwdt"); - if (retval) - goto error2; + retval = register_nmi_handler(NMI_UNKNOWN, hpwdt_pretimeout, + (priority) ? NMI_FLAG_FIRST : 0, + "hpwdt"); + if (retval != 0) { + dev_warn(&dev->dev, + "Unable to register a die notifier (err=%d).\n", + retval); + if (cru_rom_addr) + iounmap(cru_rom_addr); + } dev_info(&dev->dev, "HP Watchdog Timer Driver: NMI decoding initialized" - ", allow kernel dump: %s (default = 0/OFF)\n", - (allow_kdump == 0) ? "OFF" : "ON"); + ", allow kernel dump: %s (default = 0/OFF)" + ", priority: %s (default = 0/LAST).\n", + (allow_kdump == 0) ? "OFF" : "ON", + (priority == 0) ? "LAST" : "FIRST"); return 0; - -error2: - unregister_nmi_handler(NMI_SERR, "hpwdt"); -error1: - unregister_nmi_handler(NMI_UNKNOWN, "hpwdt"); -error: - dev_warn(&dev->dev, - "Unable to register a die notifier (err=%d).\n", - retval); - if (cru_rom_addr) - iounmap(cru_rom_addr); - return retval; } static void hpwdt_exit_nmi_decoding(void) @@ -887,6 +881,10 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" #ifdef CONFIG_HPWDT_NMI_DECODING module_param(allow_kdump, int, 0); MODULE_PARM_DESC(allow_kdump, "Start a kernel dump after NMI occurs"); + +module_param(priority, int, 0); +MODULE_PARM_DESC(priority, "The hpwdt driver handles NMIs first or last" + " (default = 0/Last)\n"); #endif /* !CONFIG_HPWDT_NMI_DECODING */ module_init(hpwdt_init); diff --git a/trunk/drivers/xen/Kconfig b/trunk/drivers/xen/Kconfig index ea20c51d24c7..94243136f6bf 100644 --- a/trunk/drivers/xen/Kconfig +++ b/trunk/drivers/xen/Kconfig @@ -183,17 +183,15 @@ config XEN_ACPI_PROCESSOR depends on XEN && X86 && ACPI_PROCESSOR && CPU_FREQ default m help - This ACPI processor uploads Power Management information to the Xen - hypervisor. - - To do that the driver parses the Power Management data and uploads - said information to the Xen hypervisor. Then the Xen hypervisor can - select the proper Cx and Pxx states. It also registers itslef as the - SMM so that other drivers (such as ACPI cpufreq scaling driver) will - not load. - - To compile this driver as a module, choose M here: the module will be - called xen_acpi_processor If you do not know what to choose, select - M here. If the CPUFREQ drivers are built in, select Y here. + This ACPI processor uploads Power Management information to the Xen hypervisor. + + To do that the driver parses the Power Management data and uploads said + information to the Xen hypervisor. Then the Xen hypervisor can select the + proper Cx and Pxx states. It also registers itslef as the SMM so that + other drivers (such as ACPI cpufreq scaling driver) will not load. + + To compile this driver as a module, choose M here: the + module will be called xen_acpi_processor If you do not know what to choose, + select M here. If the CPUFREQ drivers are built in, select Y here. endmenu diff --git a/trunk/firmware/3com/3C359.bin.ihex b/trunk/firmware/3com/3C359.bin.ihex new file mode 100644 index 000000000000..781bac3b2a02 --- /dev/null +++ b/trunk/firmware/3com/3C359.bin.ihex @@ -0,0 +1,1573 @@ +:10000000FE3A0000000000000000000000000000B8 +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000000000000000000000000000000C0 +:1000400000000000000030332F30322F39392031CA +:10005000373A3133000000000000000000000000CB +:1000600030313233343536373839414243444546EE +:10007000000007FF0200FE9F0600007C48000070A1 +:100080008200FFFF8600FFFF8800FFFF9A00FFFF4E +:10009000FFFF1100C000FFFFFFFF11223344556630 +:1000A00033434F4D20424142451140C000FFFFFF06 +:1000B000FF1122334455665374617274206F6620B9 +:1000C0004C4C43206672616D652E2020546F746124 +:1000D0006C20646174612073697A6520697320788B +:1000E000787820202042414245E8D201833EF7340F +:1000F000007521E84100833EF734007517E882005F +:10010000833EF73400750DE8BF00833EF734007579 +:1001100003E84102C31EB800F08ED833F6B9008060 +:1001200033DBAD03D8E2FB1FB8000083FB00740390 +:10013000B82200A3F734C3FABA5600B0FFEE33C0BA +:100140008EC033F6B9FF7F833EFF340074088D3EC6 +:100150003061D1EF2BCF268B1C26C704FFFF2683EF +:100160003CFF751726C704000026833C00750C264B +:10017000891C4646E2E0B80000EB03B82400A3F770 +:1001800034C3FAB4D79E733A753879367B349FB14D +:1001900005D2EC732DB040D0E071277925D0E07303 +:1001A000217B1F32C0751B32E49E721674147812C4 +:1001B0007A109FD2EC720BD0E470077505B800007E +:1001C000EB03B82600A3F734C3FABA5A0033C0EFE2 +:1001D000EFEFEFB000E656B000E654BA5200B801B7 +:1001E00001EFE8CA003C01757FE88300BA5200B80D +:1001F0000202EFE8B9003C02756EE87A00BA5200DC +:10020000B80404EFE8A8003C04755DE87100BA5238 +:1002100000B80808EFE897003C08754CE86800BA99 +:100220005200B81010EFE886003C10753BE85F0004 +:10023000BA5200B82020EFE875003C20752AE85635 +:1002400000BA5200B84040EFE864003C407519E83D +:100250004D00BA5200B88080EFE853003C8075082A +:10026000E84400B80000EB03B82800A3F734C3BA91 +:100270005A00B80080EFC3BA5A00B80180EFC3BA81 +:100280005A00B80280EFC3BA5A00B80380EFC3BA6D +:100290005A00B80480EFC3BA5A00B80580EFC3BA59 +:1002A0005A00B80680EFC3BA5A00B80780EFC3B946 +:1002B000FFFFE458E4543C0075034975F7C3FA3274 +:1002C000C0E656E4563C007403E98200B0FFE656EF +:1002D000E4563CFF7578BA5200B8FFFFEFED3CFFE3 +:1002E000756CB800FFEFED3C007563B0FFE654E4B9 +:1002F000543CFF755932C0E654E4543C00754FB08D +:100300000FE650E450240F3C0F7543B000E650E474 +:1003100050240F3C0075378CC88EC0BE7000268BF1 +:1003200014268B5C02B80000EFED23C33D0000757E +:100330001DB8FFFF23C3EF8BC8ED23C33BC1750E70 +:1003400083C60426833CFF75D5B80000EB03B82AAA +:1003500000A3F734C3FA33C0BF0020B91700F3ABD2 +:10036000BF0030B91700F3ABBF0022B94000F3ABB8 +:10037000BF0032B94000F3ABFC1E8CC88ED833C02E +:100380008EC0BE9200BF0020B91700F3A4BEA90022 +:10039000BF0022B94000F3A41FC706FB346400BAB3 +:1003A0000800B80F00EFE88201E89B01720DC70654 +:1003B000F7342C00C706F9340400C3BA0A0033C06E +:1003C000EFE89801E8B501B81700BA9C00EFB80053 +:1003D00010BA9A00EFB81700A90100740140BA8C56 +:1003E00000EFB80018BA8600EFB80C00BA8200EF30 +:1003F000BA0200ED25F9FF0D0200EFBA060033C086 +:10040000EFBA0400B86000EFBA0000B81800EFBA05 +:100410008000B9FFFFEDA901007504E2F8EB3EBAD8 +:100420000A00EDA900407435A90020743033C0EFF4 +:1004300051B9C800E2FE591E061F268B0E023083FA +:10044000F91775184949BE0220BF0630F3A61F23CD +:10045000C9750AFF0EFB347412E94DFF1FB82C005A +:10046000BB0000A3F734891EF934C3C706FB34640C +:1004700000E8D300720DC706F7342C00C706F93424 +:100480000400C3E8D600E8F300B80300BA8200EF26 +:10049000B84080BA9800EFB80011BA9600EFB840A3 +:1004A00000A90100740140BA9200EFB80019BA8E99 +:1004B00000EFBA0200ED25F9FF0D0600EFBA0600C5 +:1004C00033C0EFBA0000B81800EFBA8000B9FFFFE0 +:1004D000EDA920007504E2F8EB43BA0A00EDA9008B +:1004E00040743AA90020743533C0EF51B9C800E216 +:1004F000FE591E061F268B0E023283F940751D49D8 +:1005000049BE0222BF0632F3A61F23C9750FFF0E94 +:10051000FB347403E95AFFB80000EB0B1FB82C0042 +:10052000BB0200891EF934A3F734C3BA0200B80035 +:100530009CEFBA0000B80084EF33C0EFBA0A00EFB6 +:10054000BA0E0033C0EFC3BA0A00B9FFFFED2500B1 +:10055000603D00607404E2F5F8C3F9C3B000E656EC +:10056000B800FFBA5200EFB9FFFFBA5800ED25EF0F +:10057000007408BA5A0033C0EFE2EFC3BA8000ED4E +:10058000BA8400EFBA8000EDC30000000000000054 +:10059000C606EC341533C08ED88EC01E8CC8BE4043 +:1005A00054BF60FE8ED8B91000F3A41FC706803672 +:1005B0001035C7068C3630358D063835A33035A357 +:1005C0003235053301A33435C70636355001C70629 +:1005D000843680FEC7068836C0FEC606C2FEFFC649 +:1005E00006933680C606923600C60680FE80C70691 +:1005F00082FE5450C70684FE2B4DE5CEA90200753D +:1006000008C60681FE23E90500C60681FE22A1F781 +:1006100034A386FEB8483486E0A388FE8D064E34A7 +:1006200086E0A38AFEB8583486E0A38CFEB89C34DA +:1006300086E0A38EFE8D06200386E0A390FE33C0E5 +:10064000BA7200EF33C0BA7400EFBA7600EFB88028 +:10065000FE86E0BA7200EFE8BF07BA0C01B840406E +:10066000EFEDBA6A00B80300C1E0080D0300EFB96E +:100670000A00E89400BA6A00B80300C1E008EFA1DC +:100680003234A3A233C706A63304008D06A033C1BB +:10069000E804CD39C7069036FFFFE9E300630D6635 +:1006A0000D660D8A0DE60E75122E0F030F500F60AA +:1006B0000D600D600DED0FE912600D600D600D60B5 +:1006C0000D600D2210600D600D600D600DFE10605C +:1006D0000D600D600D600D600D600DAF0F321037B5 +:1006E0000D600D600D600D600D600D600D600D60A2 +:1006F0000D600D600D600D600D600D600D600D6092 +:100700000D640E000F9509600A49BBFFFFBA6A002D +:10071000EDA900207438803E80FE127531E84A0051 +:10072000A13234A3A233C706A63304008D06A0333A +:10073000C1E804CD39E82200C706F3344600C706F5 +:10074000F534FFFFC7069036FFFF58E932004B83B0 +:10075000FB0075B983F90075B0C352BA6A00B803DB +:1007600000C1E0080D0300EF5AC352BA6A00B80393 +:1007700000C1E008EF5AC3000000000000000000C4 +:10078000688007A19036CD358B3624022EFFA43524 +:100790000AFA8A2694368826E834C606943600FB80 +:1007A00022E47501C3F6C420747DF6C40874058084 +:1007B0000E9236048026E834D7C41E8436268B3742 +:1007C00081E6FF0083FE207605B001E9280053068C +:1007D000D1E62EFF949D06075B268847023CFF74F6 +:1007E000073CFE7511E93B00F6069236087534F6B3 +:1007F00006923604742D80269236F3803E9536009C +:10080000752126803F057513C60695360026807F24 +:1008100006007407268B4704A29536BA0C01B8402F +:1008200040EFED8A26E834F6C4107503E95B00F664 +:10083000C4047405800E9236018026E834EBC43E71 +:100840008836268B3583E67F83FE12720826C645DE +:100850000201E9240083C620D1E62EFF949D06C440 +:100860003E8836268845023CFF750EF60692360114 +:100870007414F606923602750D80269236FCBA0C78 +:1008800001B82020EFED8A26E834F6C408742280EF +:1008900026E834F7800E923604F606923608741174 +:1008A00080269236F3BA0C01B84040EFED8A26E874 +:1008B00034F6C40474228026E834FB800E9236019C +:1008C000F606923602751180269236FEBA0C01B8F1 +:1008D0002020EFED8A26E834F6C40174678026E80C +:1008E00034FE803EE8FF007439803EE8FF04743235 +:1008F000803EE8FF017521E580A90007740ABA9ED1 +:1009000000B80002EFE9EFFFC606E8FF03BA0C01EA +:10091000B80808EFEDE92800803EE8FF037406E917 +:100920001E00E90000BA1001B80202EFEDE5000D6B +:100930001800E700E5820D0200E782C606E8FF0422 +:100940008A26E834F6C402740D8026E834FD802639 +:100950009236BFE84F0BFAA0E83408069436C60674 +:10096000E83400FBC3E8E70FC41E84362EFF1601EF +:100970000726884702E97EFEE82D10C41E84362E25 +:10098000FF16030726884702E96BFE8E0626022E15 +:10099000FF160707C3C3833EF53400740FFF0EF341 +:1009A000347509E8C4FDC706F5340000F606933631 +:1009B000207430A1C2343B06E934A3E934742480A6 +:1009C0003E953600751DF706E63420007412A92006 +:1009D00000740D8326C234DF8326E934DFE9030087 +:1009E000E8DD09BA0601ED8BD081E200C0C1EA0E54 +:1009F00003167434C1E002110672347304FF0674E6 +:100A000034BA0201ED8BD081E200C0C1EA0E0316B8 +:100A10007034C1E00211066E347304FF067034C7EF +:100A200006A6330400C706AA3300008D06A033C112 +:100A3000E804CD39C39509950965097809950995A3 +:100A4000099107950996098B0995099509950995C5 +:100A500009950995098BC08BC08BC08BC08BC0904A +:100A6000F6069336207503E9CC008CC0408EC02674 +:100A70008B0E060086E926890E06008CC2C1E204B0 +:100A8000BE0E0026A10400D0E024C08AE0C0EC0421 +:100A90000AC426A2050026A10800A900C07403E923 +:100AA0009E0026F6061000807503E90A0026A016AF +:100AB00000241F32E403F0803EEC3406725C803E7A +:100AC00095360075668BFA33DB8EC326891D268822 +:100AD0005D045150C41E8C36B90F0033C0E82109A3 +:100AE00058590BDB7434FE0EE63A26C6078126C63B +:100AF00047010026C64702FF26C747040000268993 +:100B00004F0A86F2268957062689770826C647099E +:100B10000026C6470C02E88C09C3FF06EC338CC0E4 +:100B2000488EC0FAE89710FBE9EBFF8CC0488EC0F6 +:100B3000FAE88A10FBC38CC08EC0FAE88010FBC3B1 +:100B4000803E9536007503E9C200BF080026F60610 +:100B5000100080750503FEE90C0026A01600241F76 +:100B600032E403F003FEA095363C007503E99C00D7 +:100B70003C01740B3C0274143C03741DE98D00C6E7 +:100B800006963601E83C017227E98000C6069636D3 +:100B900002E88300721AE97300C606963601E8225D +:100BA00001720DC606963602E86C007203E95C001D +:100BB000530650C41E8C36B90B0033C0E8420858A7 +:100BC00026C6078226C64702FF8D06E0FE86C4269B +:100BD000894706A0963626884708E8C808075B8339 +:100BE00026AD36FEA1AD36E704BA1001B88080EF1D +:100BF000EDBA1001B80202EFED52BAE000B84110B0 +:100C0000EF5AB89C03CD39C6069536008CC0488E85 +:100C1000C0FAE8A90FFBC31E061F0633C08EC08BA7 +:100C2000F08D3E20F351B10A26837D0C01752A57C1 +:100C300026837D0E007406E82F00E90300E86607AE +:100C40005F731633C08ED8268B4D128D75208D3E66 +:100C5000E0FEF3A459071FF9C3FEC9740781C7203A +:100C600001E9C4FF59071FF8C35150535652573377 +:100C7000DB268A5D0E268B4D128D7D205A87D72666 +:100C80008A451487D74232FF80FF087508FECB22C1 +:100C9000DB75EA33DB23DB7406FEC7D0C8730C5068 +:100CA000268A053804587403E90A0049464723C9CF +:100CB000740AE9D3FF5A5E5B5859F8C35A5E5B5811 +:100CC00059F9C31E061F0633C08EC086CD2BCE8BAE +:100CD000F78BC133C9803CFF741680F90673093263 +:100CE000C94648742EE9EDFF3D6000730CE923000E +:100CF000FEC14648741DE9DCFFB810008D3E183473 +:100D000032EDB106F3A67403E908004823C0740766 +:100D1000E9E9FF071FF8C38D36183433C08ED88D2C +:100D20003EE0FEB81000B9060056F3A45E483D0050 +:100D30000075F3071FF9C3FF06E433C606EB340062 +:100D4000268B450686E0C1E80448068EC0FE06E60E +:100D50003AFAE8690EFB07B0FFC30000000000008C +:100D6000B001C3B000C3F6069336207503B004C3C8 +:100D70008B0E973681E18030268B4704257FCF0B81 +:100D8000C1A39736A3E634B000C3F60693362074A9 +:100D900003B003C3268B4708A39736A3E634268AFD +:100DA0004720A2FD343C017506C706A13600002687 +:100DB0008A4721A2FE34268B470AA31834A358344D +:100DC000268B470CA31A34A35A34268B470EA31C38 +:100DD00034A35C34C6062A34C0268B4714257FFF13 +:100DE00009062C34268B471625FFFE25FFFC090635 +:100DF0002E34C6060034C0268B4710A30234268B3F +:100E00004712A304340653E8840A5B073D000075CB +:100E100007800E923608B0FEC3B90001A1AC33338F +:100E2000D2F7F9A3AE33914933D2F7E905003BA3DA +:100E30004634BF003B893E4434BA6800B8E0E0EF76 +:100E4000A1AE33E762A1AE33BA0801EFA14434E7A3 +:100E500064A14434BA0A01EFB800012D04000D006A +:100E600010E792C33D0000740A26894707E8833AD9 +:100E7000B007C3A1AE332689472BA1443426894746 +:100E80002DA146342689472F800E933620A188361F +:100E900086E026894708A1843686E02689470AA18C +:100EA000803686E02689470CB860FE86E0268947B2 +:100EB0000EA0A136268847108B36883626C64402F7 +:100EC000FFE59EA90008740CBA8400ED0D0800EF40 +:100ED000BA8E00EFE50225F9FFE702BA1001B80269 +:100EE00002EFEDB000C3F6069336207503B001C3E0 +:100EF000802693369FE88D0A800E923608B0FEC396 +:100F0000B000C3F6069336207503B004C3C6062AA4 +:100F100034C0268B4706257FFFA32C34268B470839 +:100F200025FFFE25FFFCA32E34CD52B000C3F606EC +:100F30009336207503B004C3C6060034C0268B4721 +:100F400006A30234268B4708A30434CD52B000C355 +:100F5000F6069336207503B004C3578D7F0651B94A +:100F6000070033C0F3AB598D7F06A17A34030639ED +:100F700037268805A1953726884502A180340306C7 +:100F8000763426884507A1C63426884509A1D8337A +:100F90002688450A33C0A37A34A33937A39537A3EB +:100FA0008034A37634A3C634A3D8335FB000C3F62D +:100FB000069336207503B004C3268B4F0483F906CD +:100FC000741283F904740D83F900740883F90274B0 +:100FD00003B001C3890EE83A8326AB36F9090EAB9C +:100FE00036E50225F9FF0BC1E702B000C3F6069310 +:100FF00036207503B004C3268B4F0480F9FF7408B4 +:1010000080F9007410B001C3830EAD3602A1AD3675 +:10101000E704E90A008326AD36FDA1AD36E704B04A +:1010200000C3F6069336207503B004C3E8D504B0B8 +:1010300000C3F6069336807503B001C326837F068E +:10104000057503E99D00268B5704268B47082681EA +:101050007F0600807508ED2689470AE99D002683F2 +:101060007F06017504EFE9920026817F06018075F5 +:1010700009EFED2689470AE9810026837F0602757C +:101080000726214704E9730026817F060280750C3C +:1010900026214704ED2689470AE95F0026837F065B +:1010A00003750726094704E9510026817F0603805E +:1010B000750C26094704ED2689470AE93D00268379 +:1010C0007F0604750726314704E92F0026817F0635 +:1010D0000480750C26314704ED2689470AE91B0078 +:1010E000B001C3FA53268B4F080BC9740C8D1EE058 +:1010F000FEE852FF83C308E2F85BFBB000C3F606CC +:10110000933680750AF6069336207503B001C38DB9 +:101110003EE0FEE500268905E50226894502A1ADEF +:101120003626894504E50626894506E508268945CB +:1011300008E50A2689450AE50E2689450CE5482674 +:1011400089450EE54A26894510E54C26894512A1B8 +:10115000B73626894514E55026894516E552268975 +:101160004518E5542689451AE5562689451CE55853 +:101170002689451EE56226894520E56426894522A3 +:10118000E56626894524E56826894526E56A268997 +:101190004528E56C2689452AE5702689452CE572A7 +:1011A0002689452EE57426894530E576268945321F +:1011B000E57C26894534E57E26894536E580268905 +:1011C0004538E5822689453AE5862689453CE58805 +:1011D0002689453EE59A26894540E59E2689454271 +:1011E000E5CC26894544E5CE26894546E5D02689C5 +:1011F0004548E5D22689454ABA0001ED1106663414 +:101200007304FF0668342689454CBA0201EDC1E03B +:101210000211066E347304FF0670342689454EBAF7 +:101220000401ED11066A347304FF066C3426894507 +:1012300050BA0601EDC1E002110672347304FF06D4 +:10124000743426894552BA0801ED26894554BA0AF4 +:1012500001ED26894556BA0C01ED26894558BA0E8E +:1012600001ED01067A342689455EBA1001ED268922 +:10127000455CB000C3F6069336807407F6069336D5 +:10128000207503B001C326807F06007530803E952F +:1012900036007452C6069536008326AD36FEA1ADE3 +:1012A00036E704BA1001B88080EFEDBA1001B80239 +:1012B00002EFEDBAE000B80010EFB000C3268B4794 +:1012C000043D000074203D0300771BBA1001B802F2 +:1012D00000EFBAE000B80110EF830EAD3601A1AD0A +:1012E00036E704B000C3B006C3F606933680750334 +:1012F000B001C326837F0401740A26837F0402742D +:1013000019B006C326837F060C77F626837F0A6012 +:1013100077EFE81000720BB046C3E84E007203B0DE +:1013200046C3B000C351B10A8B3E20F326837D0C27 +:10133000027503E90E00FEC9740781C72001E9EBBD +:10134000FF59F8C3578D7D0E8D7706B91200F3A4AF +:101350008D7D208D36E0FE268B4D12F3A4FF060115 +:10136000355F26C7450C010059F9C351B10A8D3EBE +:1013700020F38D36E0FE26837D0C01751B57E82592 +:10138000005F731433C0B92001F3AA26C7450C02CD +:1013900000FF0E013559F9C3FEC9740781C720014A +:1013A000E9D3FF59F8C351268B4D128D7D20F3A64A +:1013B000740359F8C359F9C300000000000000008D +:1013C000803EEC34067233FF06F03350C41E8C3678 +:1013D000B90F0033C0E82900588126C234DF7F816D +:1013E00026E934DF7F0BDB741126C6078426C64747 +:1013F00002FF26894706E8AC00C3FF06EA33E9F599 +:10140000FF57268B3F03F9263B7F027416263B7F4E +:10141000047C2A3D000075138D7F0803F9263B7F6D +:10142000027C14FF06DE3333DB5FC3268B7F02268C +:10143000893F03F9E9060026893F26290F26C705BB +:10144000FFFF26873F26890D8D5D02508BFB83E9C8 +:101450000233C0F3AA58FE0EEC345FC38B7C023B10 +:101460003C742F833DFF750B8D7C08897C02833D86 +:10147000FF741E8A45023C81750C803EEB3400747B +:101480000533C0E90B008B0D014C028D750283E919 +:1014900002C3803EEC3406720533C0E9F3FFFF0659 +:1014A000EE33E9BEFFF6069236407401C35756513B +:1014B000528B368C36E8A4FF7503E91A00E91C004C +:1014C000FE06EC34C43E8036F3A4800E923640BA59 +:1014D0000C01B88080EFED5A595E5FC3FF06E03320 +:1014E000803C81750CFF06E233C606EB3401E9CF80 +:1014F000FF803C847507FF06E633E9C3FFFF06E87B +:1015000033E9BCFF8D3EE0FEA17234C706723400A1 +:10151000008905A17434C70674340000894502BAF5 +:101520000401ED894504C745060000A16E34C706D5 +:101530006E340000894508A17034C706703400007D +:1015400089450ABA0001ED89450CC7450E000032F5 +:10155000E4BA0E01EC894510A17E34C7067E340042 +:1015600000894512A18C34C7068C340000894514CB +:10157000A18A34C7068A340000894516A17C34C785 +:10158000067C340000894518A18834C706883400D9 +:101590000089451AA1CA33C706CA33000089451C11 +:1015A000A17834C7067834000089451EA1C634C727 +:1015B00006C6340000894520C3000000000000007A +:1015C000FA33C08ED88EC0B8A001C1E8048ED08D89 +:1015D000268000E80001E810EB8B1EF7348B16F92B +:1015E000348B36FF3433C0B9EFFF8D3E14002BCF60 +:1015F0002BCED1E9F3AB891EF7348916F93483FE7B +:1016000000740CB9EFFFBF80FE2BCFD1E9F3ABB96B +:10161000FFFF81E9003B83FE007403E91B00511EBC +:10162000B800E08ED833F68D3E00D8B9000CF3A593 +:101630001F59BEFFFF81EE00D82BCE81E100FF894C +:101640000EAC338D062002C1E804A332348ED036AE +:10165000C7061E00801836C7062200FF7F36C70661 +:101660000A00FFFF36C7061C0080008D06A002C1DD +:10167000E804A330348ED036C7061E00502836C783 +:10168000060A00FFFF36C7061C008000B8A001C193 +:10169000E804A33434A3F2338ED08D268000B80042 +:1016A00090E7028D3E70018BC7C1E804B903008941 +:1016B000450E894502C705FFFF83C710050100E2FB +:1016C000EEE85B01E5CEA3B536E82100E84501A1CF +:1016D00032348CCBCD370E58A900F0740733F6891D +:1016E00036FF34C38D3630618936FF34C333C08B47 +:1016F000D08BF2B968002E80BCAC17807501EF83E7 +:10170000C20246E2F1B80200E750B95A0033FFC7FF +:101710000565188C4D0283C704E2F433C08EC08C7B +:10172000C88ED88D3E80008D369C17B90800E837EA +:10173000008D3620218D3EC000B90D00E829008DB6 +:101740003E4001B90A00E81F00E84B0E33C08ED8B6 +:10175000C7064E376F17E748E74CB8409CE74AE5A5 +:101760004890B80070E748C3A583C702E2FAC3E512 +:101770004CC35051565752061E33C08ED8E558D12F +:10178000E073118BF0D1E633C08ED88BB480008328 +:10179000C60BFFE61F075A5F5E5958CF581CE41C62 +:1017A0006C1C8E1AC01F401A441C6518808080FF74 +:1017B00080030280FFFFFFFFFFFFFFFFFFFFFFFF30 +:1017C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 +:1017D0008003034380800280420302FF0301030170 +:1017E00001030203FFFFFFFFFFFFFFFF02030103EF +:1017F00003FF0101FF01FF0101030303FFFFFFFFDF +:10180000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 +:10181000FFFFFF02B80F00E784B80FF8E782C3B9F3 +:101820000800890EE63A8D0620038BD0C1E804A398 +:1018300090018BC28BD8C1E8048EC005610026A33D +:101840000000A1303426A3020083C314D1EB268903 +:101850001E080081C21006E2D926C7060000FFFF5D +:101860008C069201C35051565752061E33C08ED873 +:10187000E75AFF06BE33BAD200EDCF0000000000E9 +:101880008CCBA13034CD37E906EDB83200C3E88CFB +:1018900001FE06E234E8210175F0E8530E810EAF37 +:1018A0003600C0C706AD366000F706E63480007526 +:1018B0001AF706E63400087409C706AB360B00E9D0 +:1018C0000F00C706AB360300E90600C706AB3611AA +:1018D0009CC706A9361800F706E6348000750DF798 +:1018E00006B53602007405830EA93620A1A936E795 +:1018F00000A1AB36E702F706E6348000742EE8F26A +:101900002F33C00D4100E756A1B1360D0010E70896 +:10191000A1B336E70AA1AF36E706B84000E74E3379 +:10192000C0E70EC70626020000E92300C7064E37AF +:101930003F208E06303426F7060A00008074072602 +:10194000810E08000080C606E03401B80000C3FE26 +:1019500006E134C606E03400A126020BC07401C3C0 +:10196000E80400B80000C3A1A936E7008B1EAB361F +:1019700083E306E50225F9FF0BC30D1000E702A182 +:10198000AD36E704C3B80A00E784FE06E534C606B0 +:10199000E334018E06303426F7060A00004074074F +:1019A00026810E08000040C3C7064E376F17FE069B +:1019B000E434C606E33400C3C3F606183480750D5C +:1019C000A118340B061A340B061C347501C3A12E62 +:1019D0003425FFFE8B16E73681E200010BC2A32EF1 +:1019E000348D161000BF0000B908008B850034EF5D +:1019F00083C2108B850234EF83C2108B850434EFD1 +:101A000083C2E283C7064975E2B800008EC0BE00FB +:101A100034BFB936B91800F3A5B80000C333C08E7F +:101A2000C08D3EB033B90800F3AB8D3E3E34B903F0 +:101A300000F3ABC300000000000000000000000045 +:101A40005051565752061E33C08ED8E75AFF06BA79 +:101A500033E5560D2000E756BA7A00ED0826943695 +:101A600033C0B10832ED068EC08D3EE0FFF3AA8E82 +:101A700006323426810E0800000207E55625DFFFF6 +:101A8000E756E9F8FC00BD1B101BD91AF31A505198 +:101A9000565752061E33C08ED8E75AFF06B6335348 +:101AA0000651E580A3B4338BD88BC8251000A3ED75 +:101AB000340BC07414FF068034803EFE340074037F +:101AC000E90600B88000E89D0483E303D1E32EFF1C +:101AD00097861A59075BE9A4FCBA20008E063C34AD +:101AE000833E3C34007503E9F000C7063C34000037 +:101AF000E92A00BA10008E063A34833E3A34007563 +:101B000003E9D5FFC7063A340000E81000E9C9FF31 +:101B1000BA10008E063A34C7063A34000026A114E3 +:101B20000026A30C0026A1160026A30E0026C6063A +:101B30000A0000C1EA0223D1741CBA200026C7069D +:101B40000E00EA05260B160C002689160C00FF066F +:101B50008634FF06DC3326A10C00A9003774162654 +:101B6000C6060A0002A900307404FF067A34FF0694 +:101B7000DA33E94900C0EC0783168A340024073CB5 +:101B8000077504FF068C34FF067E34A130348CC305 +:101B90008EC08EDB26830E0800408CD82687061662 +:101BA0000026833E1400FF740A8EC0268C1E00009F +:101BB000E90500268C1E140033C08ED8C3C38CC028 +:101BC000870692013DFFFF740D8ED88C060000330E +:101BD000C08ED8E904008C069001E80100C306839A +:101BE0003E9001FF7429833E3A34007511BA860095 +:101BF000E81E008C063A34833E9001FF7411833E48 +:101C00003C3400750ABA8800E806008C063C3407AC +:101C1000C3A190018EC026A10800EF26A1000026D6 +:101C2000C7060000FFFFA390013DFFFF7503A392CD +:101C300001833EED3400740BB81000E784C706ED55 +:101C4000340000C35051565752061E33C08ED8E799 +:101C50005AFF06BC33E925FB5051565752061E3336 +:101C6000C08ED8E75AFF06B033E911FB50515657E2 +:101C700052061E33C08ED8E75AFF06B43306FF065D +:101C80007634803EFE3400740407E9F0FAB8800030 +:101C9000E8D30207E9E6FA000000000000000000B7 +:101CA000C61D081D911E5D1E731E891E911EA81D56 +:101CB000911E911EAF1EAF1E151D151D911E991F61 +:101CC000000000000000000000040000000200000E +:101CD00000010010000100400000000000010000B1 +:101CE00007E999FA5051565752061E33C08ED8E76D +:101CF0005AFF06B2330668F61CE506A3B2338BF032 +:101D000083E61E2EFFA4A01CE50CA980007406E843 +:101D1000A401E506C353E50C8BD8A9010074148314 +:101D20003EE03A00740D8E063834E8BF06C706E080 +:101D30003A0000E5000D1800E700E5020D1100E78C +:101D4000028BC35BA901007401C38BD0B80008E704 +:101D5000848BC28E06383426A30C008BD0C1E003DE +:101D60008316883400FF067C3426833E06000A75FD +:101D7000218BC22540183D4000740C3D00107512A7 +:101D800026FE0E0A00740BF706EF3420007503E9F7 +:101D90005A068CC0268E06020026830E08002026D6 +:101DA000A3120026A31000C3FF06C433E50CA9014B +:101DB000007501C3A9F0077401C3FF06D433E50021 +:101DC0000D1800E700C3FF06CA33803EA036087531 +:101DD000148E06303426F7060A00000874072681A0 +:101DE0000E08000008E58225FDFFE782E50C50E5BE +:101DF00080250007A3E43AE58C250080A3E23A5849 +:101E0000A902007525833EE23A00751E833EE43A3E +:101E1000007517E5080D000425FF04E708E86A01CE +:101E2000E5820D0200E782E92100E81A06803EE81B +:101E3000FF00740A803EE8FF047403E90D00C60643 +:101E4000E8FF01BA0C01B80808EFED803E9F3606A6 +:101E50007505830E993640B80001E90901FF06CCEB +:101E6000338126AF36FFF7A1AF36E706FF06C6344B +:101E7000E91E00FF06CE33FF0695378126AF36FFF9 +:101E8000EFA1AF36E706E90800FF06D033FF067A78 +:101E900034FF06D233D1E68E0630342E8B84C01C3C +:101EA00026090608002E8B84C21C09066637C3E586 +:101EB0000CA98000745650E8F00058A9000175077D +:101EC000FF06C633E90800FF067834FF06C833E58D +:101ED0008225FDFFE782E86E05BA1001ED803EE83D +:101EE000FF00740A803EE8FF047403E91D00C60683 +:101EF000E8FF01BA0C01B80808EFEDE90D00C606CD +:101F0000E8FF03BA0C01B80808EFEDC3A90100749B +:101F10001CE82C00833EE03A00740F068E0638342D +:101F2000E8C904C706E03A000007E95D008BD08EDF +:101F300006383426A30C00E8060068691DE94A004B +:101F4000A90004740AB80004FF06D833E91700A9F1 +:101F50000001740AFF063937B80001E90800A9102A +:101F600000B81000741D090666378CC08E06303428 +:101F700026F7060A000001740726810E08000001FA +:101F80008EC0C3FF06C233E9F8FFE5000D1800E775 +:101F900000E5020D1100E702C358E943FDE5080D15 +:101FA000000425FF04E708E9E0FFE50EA900087535 +:101FB00001C3E9F5FF000000000000000000000080 +:101FC0005051565752061E33C08ED8E75AFF06B8F6 +:101FD00033E548065357FF164E375F5B833E80015B +:101FE000FF74588E06800126FF0E0800754D26A14D +:101FF0000000A3800126C7060000FFFF8CC0268ECC +:1020000006020026810E080080008BD02687061A63 +:102010000026833E1800FF740A8EC0268916000031 +:10202000E905002689161800833E8001FF740C8E96 +:1020300006800126833E08000074B307E93EF7E5F9 +:102040004C90E502A90020740D25FFDF0D0100E78B +:10205000020D0020E702E50A8BD8A3F43325C3570D +:102060000D0010E70AF7069B3600807437F7C300AF +:10207000807406F7C30008745D8126C2347FFFC7F1 +:102080000635370500B88003CD3981269B36FF7FA2 +:10209000C7060F370400F7069B3640007506C706D3 +:1020A0000F370300F7069B360020742AF7C3000899 +:1020B0007424803E9D36067C1DFF069434830E6694 +:1020C00037208E06303426F7060A000001740726F2 +:1020D000810E08000001F7C30020753BF7069A3710 +:1020E0008000740BFF06893733C0E70EE90400FF58 +:1020F000063B37F7069B360020741C80269E36FF71 +:1021000075158E06303426F7060A00000874072677 +:10211000810E08000008C3C300000000000000009A +:1021200002230223022302230323DD220223FD21B3 +:102130000223A424F32402238D227A23022397244A +:102140001B247524022302238E25FB8E067E01FBB1 +:1021500026833E0000FF74F2268E060000FA268BCE +:102160001E080026231E0A0074E58CC08ED0268B24 +:102170002602008C16F23322FF756A26A11C008A03 +:10218000E38ADC22D8750DD0E824F80AC075F2B0D5 +:1021900080E9EDFFD0E824F80AC07502B08032E48F +:1021A00026A31C00F7C3080075472E8A9FC5252E5D +:1021B0008BBFC52680C310268E1D268C1E06008B65 +:1021C000160000C7060000FFFF26891583FAFF7579 +:1021D0000A2E8B97CD26262116080033C08ED826CE +:1021E000891E0400C38ADFB7002E8A9FC525E9E057 +:1021F000FF2683260800F783C310E9DEFF60061E72 +:102200006887256A001F8E06F2338B0E3434390E30 +:10221000F233740E26810E0A00000226810E080099 +:1022200000022689260200A3F2338ED08D2680007C +:10223000368926020036891E200036C706080000AF +:1022400000B90400BE00002E8BBCC52636C705FFB2 +:10225000FF36C74502FFFF83C602E2EB8E067E0112 +:10226000368B0E22008CC026833E0000FF268E0691 +:1022700000007407263B0E22007DEA368C06000023 +:102280008EC0268C160000FB36FF2E1E00061E6830 +:102290008B256A001F2609360800F7C600FF740167 +:1022A000C356522E8BB4C52581E6FF002E8BB4C5D4 +:1022B000268CC28EC026C7060000FFFF8EC2268372 +:1022C0003CFF740F8BD0268754028EC226A30000D9 +:1022D000E90700268944022689045A5EC3061E685F +:1022E0008B256A001F8E06F23326A30A0026892654 +:1022F0000200A134348ED08D2680008C16F233E992 +:102300004DFECF501E525333C08ED826833E04005C +:10231000FF26C706040000007403E91A00833EE6A6 +:102320003A027613FF06D6338CC08E063234BE4096 +:1023300000683A23E95EFFE884F85B5A1F58CFE84B +:10234000E10026C606180010268A1E2900881E1BDA +:102350003726C7060C00FF7F26A10E00E79C26A1AA +:102360000800E79AE50080FB0874090D18ACE70047 +:10237000071F58CF0D1800E9F4FF501E0633C08E1A +:10238000D8833EA1360075B7268B3606002EFF9403 +:10239000DC23071F58CFE88A00E5000D1800E7008E +:1023A000E84900C353F706EF342000752DE58C256E +:1023B00000708BD8E58C2500703BC374058BD8E981 +:1023C000F2FF3D00307510E50225EFFFE702C7067A +:1023D000E03AFFFFE90300E812005BC3A323962362 +:1023E000A423A4239623A4239623962326A029007E +:1023F000A21B3726C7060C00FF7F26A10E00E79C14 +:1024000026A10800E79AE50025FF53268B36060033 +:1024100083E60E2E0B84AD25E700C3061E688B25D0 +:102420006A001F830EEF3420830E9B3608E50025DB +:10243000EFFF0D0800E700E500A910007501C3E5F6 +:1024400000A9100075F9C350535156061E33C08EB3 +:10245000D8B80500E784E5080D000425FF04E70867 +:10246000E5000D1800E700E5020D1100E7021F0767 +:102470005E595B58C3501E33C08ED8C706EF340078 +:102480000083269B36F7E5000D1800E700E5020DF6 +:102490001100E7021F58CF60061E6887256A001FDB +:1024A000E816F5C3061E688B256A001F8EC02683BA +:1024B0003E0A00007403E8430026C7060A00FFFF37 +:1024C000268B1606008E1E8E018CD88BCA833E008A +:1024D00000FF8E1E0000740A2B16080073EB290EF5 +:1024E000080026890E0800268C1E00008ED88C0657 +:1024F0000000C360061E6887256A001F8EC08BC857 +:102500008E1E8E0126C7060A0000008CD8833E006E +:1025100000FF74253B0E00008E1E000075ED8ED866 +:1025200026A10000A300003DFFFF74568ED826A10F +:10253000080001060800E94900268E1E0200BE18A8 +:1025400000833CFF743C390C74198E1CBE00008360 +:102550003E0000FF742C390E000074078E1E000030 +:10256000E9ECFF26A10000890433C98ED93DFFFFA5 +:10257000751083FE18750B268E1E0200812608003A +:102580007FFF33C08ED8C31F0761CF1F07CF600600 +:102590001E6887256A001FE506251E003D1E007582 +:1025A000F6B90800E558E75A23C0E0F8C300000078 +:1025B000000000000000AC000000A8008C02040035 +:1025C0000008102000FF0E0C0C0A0A0A0A0808086E +:1025D0000808080808060606060606060606060691 +:1025E00006060606060404040404040404040404A1 +:1025F000040404040404040404040404040404049B +:1026000004040404040202020202020202020202A0 +:10261000020202020202020202020202020202029A +:10262000020202020202020202020202020202028A +:10263000020202020202020202020202020202027A +:102640000202020202000000000000000000000080 +:10265000000000000000000000000000000000007A +:10266000000000000000000000000000000000006A +:10267000000000000000000000000000000000005A +:10268000000000000000000000000000000000004A +:10269000000000000000000000000000000000003A +:1026A000000000000000000000000000000000002A +:1026B000000000000000000000000000000000001A +:1026C00000000000001800140010000C00FF7FFF45 +:1026D000BFFFDFFFEFFFF7FFFBFFFDFFFE7FFFBF49 +:1026E000FFDFFFEFFFF7FFFBFFFDFFFEFF00000036 +:1026F000803EE234017603E9A500B80000E74EB958 +:102700002800E2FEC606453702BF3F282E8B45084B +:10271000E74EB92800E2FE2E8B1DC706B3364011E6 +:10272000C706B1362700C70646370200C706483736 +:102730006400F706B5360200751C2E0B5D0281267B +:10274000B336FFFEC706B1369C00C7064637080001 +:10275000C70648379001891EB736891EFE33BE2052 +:10276000008BC3E74EB92800E2FE2E8B4504E74EEE +:10277000B92800E2FEE54E8BCB2E2345062E234DD5 +:10278000063AC174364E75D9803E453700740BC683 +:1027900006453700BF2F28E972FFC606453701F707 +:1027A00006B53602007414E5CE25FDFFE7CEE843FA +:1027B00000E5CE0D0200E7CEE83900803EE23401AC +:1027C0007601C3B8EA05E78CFAE812F4FB8D06D06F +:1027D000398BD8C1E804A338348EC0A1303426A385 +:1027E000020026C7060000FFFF83C318D1EB26892D +:1027F0001E0800C3E5020D0040E702E5000D0400DD +:10280000E700B80000E70AE50AA900807514E508AA +:102810000D0010E708E50A0D0008B90500E70AE217 +:10282000FCC3E5080D0010B90500E708E2FCC3048D +:102830000C2000010C7EFF000C0200100040000C78 +:10284000C6010000C0F7FF00C002001000400000F9 +:1028500033C08ED88D3E72498D36B037B914008B97 +:102860001E3034895C022E8B45028944062E8B056E +:1028700089440483C70483C610E2E8C6069E360E68 +:10288000E8FD26688328A1AA02CD35833EA1360043 +:102890007403E93B2733FF8E06A6028B36A4022E73 +:1028A000FFA42E30830E993604C70637370100C6C1 +:1028B00006CA3401E97D19803EA0360874E68026F8 +:1028C0009E36FF751AF7069B3600207412F7069B9A +:1028D000360300750A830E663710C606A03608E96F +:1028E000FB01803E9E360275CEC606A03606E9EC98 +:1028F00001C3E9E80126C7060A00000026FF2604F6 +:1029000000A1D1362639061A007522A1D336263900 +:10291000061C007518A1D5362639061E00750E2630 +:10292000F7060C0040007405830E663740810EAF39 +:10293000360010A1AF36E706803E9D36027506CD03 +:1029400034E9A21AC3F7069B361000755426F60622 +:102950000A00FF754C26A0190024C03C4075118068 +:102960003E953600743B26C7060400FFFFE93100A0 +:10297000E8F104F7069B360300742F8BD8B87D036B +:10298000CD3A8BC3C606A03606F7069B3602007505 +:1029900005C606A03604810E9B36800083269B3632 +:1029A000FCE92301E8871DE933015026A10C00252D +:1029B00007003D07007503E984003D05007503E944 +:1029C0007C00833EE83A047475833EE83A02746EF4 +:1029D000F706E63418807503E96A00F706E6340066 +:1029E00080743526803E290002752D5156578D364C +:1029F0003E348D3E2000B90600F3A65F5E59744553 +:102A000026A12000A33E3426A12200A3403426A103 +:102A10002400A34234E92600F706E6340800740BCC +:102A200026803E1900007403E91300F706E634100F +:102A300000741226A02800C0E80422C0740726C72C +:102A4000060400FFFF5823C07403E957FF81269B4B +:102A500036FFFE83FE067F2426A120003B06D136EA +:102A6000751A26A122003B06D336751026A1240034 +:102A70003B06D5367506810E9B36000126A1200047 +:102A8000257FFFA3B83426A12200A3BA3426A124AF +:102A900000A3BC348BC686C4A3C034D1E680FC0935 +:102AA0007403E8AA1C8BC62EFFA4304926A10C0093 +:102AB0003DFF7F740F26FF2604008E063834E8366B +:102AC00006CD50C3E91600CD34E91100CD34893666 +:102AD0003D37A19D36A33F37C606A0360CE88E00D1 +:102AE000A19F3622E47532F7064C370100752AF6AD +:102AF000069D3680740788269E36E931003A069D89 +:102B000036A39D3674288BF02EFFA40D2B4429EE9E +:102B1000421944CD442F455A453A269E367501C385 +:102B200032C086C48BF0A29E362EFFA420498B2E85 +:102B3000993623ED7501C3BF0100BE000085FD7508 +:102B40001A46D1E7E9F6FF2A0029002800270025C8 +:102B50000005000700260006002000F7D7213E9957 +:102B600036D1E62E8BB4472BE94FFFE956FF80267E +:102B70009E36FF7517F7064C370100750FF6069D58 +:102B800036807408F7066637FFFF7507C706663795 +:102B90000000C3F70641370100750BB87F03CD393C +:102BA000C7064137010033F6B80040850666377422 +:102BB0002180BC5437FF7404FE84543780BC9634A3 +:102BC000FF7404FE84963431066637833E66370010 +:102BD000740546D1E873D4C3A1F433A90088740BFB +:102BE000A9001075098B1E4337FFE3E9D700C7061C +:102BF00035370500C70643371E2CF706F4330008A7 +:102C00007406C7064337102CB88003CD39E9CDFED2 +:102C1000A9000874D9FF0E353775EDE96600A900E3 +:102C20000875CBFF0E353775DF810EC234C000F654 +:102C3000069D36807448810E9B360080F7069B36D1 +:102C40000100741EB87D03CD3A810E9B368000834F +:102C5000269B36FEC7060F370200C606A03604E9DB +:102C60007BFE803EA036047507833E0F3701750555 +:102C7000C606A03606C7060F370200E95FFEBE0291 +:102C800000E94AFE80269E36FF753AF6069D36809C +:102C9000742DF7069B360020752BC606A03606FF5E +:102CA000069434830E6637208E06303426F7060AE3 +:102CB000000001740726810E08000001E90600BE2D +:102CC0000400E909FE810EAF360008A1AF36E70621 +:102CD000E50AA90080740E8126AF36FFF7A1AF3652 +:102CE000E706E909FFE9F5FDC70641370000830E55 +:102CF000993602E9E7FD80269E36FF751DF7069B93 +:102D00003600407505830E993608830E993620816A +:102D1000269B36FFBFB88503CD39E9C0FD803E9EB6 +:102D200036067407803E9E360A7534F6069D368058 +:102D30007506BE0700E996FDC606A03604833E0F61 +:102D40003702741BC7060F370400803E9E36067597 +:102D50000EF7069B3640007506C7060F370300E9DD +:102D60007BFD803E9D36047512810EC2340040FF0B +:102D7000069234C606A03606E962FDBE0500E94D9E +:102D8000FDF6069D36807519830EC23404BE06001A +:102D9000E93BFD80269E36FF75C5FF063137E90009 +:102DA000008326C234BFC606A03606E92FFDE50A19 +:102DB0005025C3BFE70A5880269E36FF750DA9002F +:102DC000407508C606A03606E912FDB88303CD3962 +:102DD000C3B87C03CD39F706F43300107509C70674 +:102DE00033370200E9F6FCFF0E33377403E9EDFCDC +:102DF000FF068E34E8F719830EC23408BE0300E9DB +:102E0000CCFC0000000000000000000400040405E9 +:102E1000040404000300030300000000000000009D +:102E20000004000808050808080003000303000068 +:102E3000020404040400000800000A1400001A0040 +:102E40001C001E2000000441060B08C2FFE704031B +:102E500006040405040604870403060404854EA240 +:102E600004CF04CDC706A2370000C706A63700006E +:102E700026A12000257FFFA3F53626A12200A3F777 +:102E80003626A12400A3F936E83B198BF0268B0ED9 +:102E90000E002BC883E90EB8018083F9047C51260B +:102EA0008A542888161C3740268B6C2686CD3BCD4D +:102EB00086CD890EA43775384032FF268A5C29807A +:102EC000FB15772580FB0A742080FB01741BB80476 +:102ED000802E3A97022E74072E3A97182E751133CA +:102EE000C080FB09754F8BF3C326C7060400FFFFA4 +:102EF0005052A1A43786C4263B0626007C32268188 +:102F00003E260000047E298D742A268B1422D2745A +:102F10001F80E6BF80FE097517C706A23701008033 +:102F2000FA04750C268B4402A3033786C4A3D0345D +:102F30005A58E9B1FFBD72372E8A872E2E22C074EF +:102F40001605442E8BF82E8B053E89460083C5025C +:102F500083C70222E47DEF8D742A83E9047503E9B7 +:102F6000A100268B1422D27503E97C00C706A63780 +:102F70000100BF72378B0583C70280E6BF80E43F44 +:102F800080FE09752280FA04755EC706A23701002B +:102F9000268B4402A3033786C4A3D03486C4C70655 +:102FA000A6370000E947003BFD7E15268B04A840AC +:102FB0007406B80780E938FF32C0268B04E92E007A +:102FC0003AF475B1C745FE000080FE22750D3AD077 +:102FD0007716C706A6370000E913003AD07509C76F +:102FE00006A6370000E90600B80580E902FF32F6C0 +:102FF00003F22BCAB8058023C97603E964FF740382 +:10300000E9EDFE33C0BF72378B1547473BFD7F1B91 +:10301000F6C6807416F706A63701007406B8088055 +:10302000E9C3FEF6C64074E0B80780E9B8FE7D4209 +:10303000A34544294429B728E228EE2BF228F52895 +:103040000129AC2A4429442944294429442900005F +:10305000733600000336C535833545350735D23420 +:1030600045340000000000000000000000000000E7 +:103070000000A6380000E03800000000000000005A +:103080000000000000000000000000000000000040 +:10309000F2330000A6336033FD32BC3277323C326B +:1030A000FB316A310A31E0E0101010E0E0E0E000AE +:1030B0000000000000000000000000000000000010 +:1030C000000000000000E000E0E0E0E0E0E0E0E020 +:1030D000E033FF26F6061A0080741B2680261A00AD +:1030E0007F268B3E260083E71F740B26800E200070 +:1030F0008026013E0E00C3602E8B84A63026A318C6 +:1031000000D1E62EFF94503061C326C7060400C4E8 +:103110002A26C7060E00160026C706060006002649 +:10312000C606190000E8BF05E8980526C706260070 +:10313000000826C60628004026C60629002ABF2AFF +:103140000026C6050426C645012AA1933733DBA90C +:1031500040007502B301A900107402B788A90008E5 +:10316000740380CF4426895D02C3830EC2342026B7 +:10317000C70604006B2B26C7060E00300026C706C4 +:1031800006000A0026C7060A00040026C606190023 +:1031900000E86905E82C0526C7062600002226C699 +:1031A0000628006026C606290029BF2A0026C60573 +:1031B0000826C645012D8D7D02BE5437B90300F3A4 +:1031C000A526C6050826C645012E8D7D02BE5A37A6 +:1031D000B90300F3A5E8D405E86405B90600BE54B8 +:1031E000378D2E2C00268B4600290483C60283C50A +:1031F0000283F90475024545E2EBC326C7060400C5 +:10320000C42A26C7060E00240026C70606000600AC +:1032100026C606190000E8E404E8A70426C7062627 +:1032200000001626C60628006026C606290028BF0C +:103230002A00E85B06E87405E80405C326C706040F +:1032400000C42A26C7060E001A0026C70606000676 +:103250000026C606190000E8A304E8660426C7068F +:103260002600000C26C60628006026C60629002770 +:10327000BF2A00E82105C326C7060400C42A26C7C2 +:10328000060E00200026C70606000A0026C7060A0A +:1032900000040026C606190000E84B04E8240426B2 +:1032A000C7062600001226C60628004026C60629A4 +:1032B0000026BF2A00E8F404E88404C326C70604F5 +:1032C00000C42A26C7060E00340026C706060006DC +:1032D0000026C606190000E80D04E8E60326C70626 +:1032E0002600002626C60628004026C606290025F8 +:1032F000BF2A00E8B604E84604E8FA04C326C70675 +:103300000400C42A26C7060E003800A1A237500BBD +:10331000C0750726C7060E00340026C7060600063D +:103320000026C606190000E89903E8A4FD26C74553 +:1033300026002A580BC0750626C745260026A11C64 +:1033400037C1E0042688452826C645292483C72A94 +:10335000E82904E8A004E82205E8F803E80904C322 +:1033600026C7060400C42A26C7060E00320026C758 +:10337000060600060026C606190000E84503E850C8 +:10338000FD26C745260024A11C37C1E00426884538 +:103390002826C645292383C72AE8E003E86C04E809 +:1033A0008A04E89C04C326C7060400C42A26C7066C +:1033B0000E00340026C7060600060026C6061900C1 +:1033C00000E8FF02E80AFD26C745260026A11C37B3 +:1033D000C1E0042688452826C645292283C72AE855 +:1033E0009A03E8C703E85703E8F803E87804E88A93 +:1033F00004C326C7060400744526C7060E003E0017 +:1034000026C7060600060026C7060A00040026C6D0 +:1034100006190000E8FC02E8A902833E8D37037517 +:10342000019026C7062600003026C6062800502632 +:10343000C606290020BF2A00E8D003E80103E8B54A +:1034400003E89F03C326C70604006143B9F0008365 +:10345000E90226890E0E0026C7060600020026C6CF +:103460000619000026C7061A00000026C7061C0021 +:10347000000026C7061E000000E8470283E90E860A +:10348000CD26890E260086CD26C60628000026C633 +:1034900006290008BF2A0083E90426890D26C645AF +:1034A00001268D7D0283E902BB0100B830304B75E7 +:1034B00017BB0A008AC4268805B03180C40180FC8D +:1034C0003A750AB461E90500268805040147497583 +:1034D000DDC326C7060400044526C7060E001200F9 +:1034E00026C7060600060026C606190001E8E50103 +:1034F000E8D00126C7062600000426C606280000DC +:1035000026C606290007C326C7060400C42A26C704 +:10351000060E00200026C7060600060026C606196D +:103520000006E80402E89B0126C7062600001226D2 +:10353000C60628000026C606290006BF2A00E86B3A +:1035400002E8FB01C326C7060400C42A26C7060EEC +:1035500000200026C7060600060026C6061900053C +:10356000E8C601E85D0126C7062600001226C60649 +:1035700028000026C606290005BF2A00E82D02E81B +:10358000BD01C3FF06823426C70604003D4126C79D +:10359000060E00200026C70606000E0026C60619E5 +:1035A0000004E88401E81B0126C706260000122655 +:1035B000C60628000026C606290004BF2A00E8EB3C +:1035C00001E87B01C326C7060400674226C7060E32 +:1035D00000200026C7060600080026C606190003BC +:1035E000E84601E8DD0026C7062600001226C606CA +:1035F00028000026C606290003BF2A00E8AD01E81E +:103600003D01C3FF06843426C7060400674226C76F +:10361000060E00240026C7060600080026C6061966 +:103620000002E80401E89B0026C7062600001626D3 +:10363000C60628000026C606290002BF2A0026C6A4 +:10364000050426C6450101A10F3786E0F6066F374F +:1036500001750F3906CC3474098BD8B88903CD397C +:103660008BC3A3CC34268945028D7D04E83D01E857 +:10367000CD00C326C7060400C42A26C7060E001CB8 +:1036800000A1A237500BC0750726C7060E00180010 +:1036900026C7060600060026C606190000E8230015 +:1036A000E82EFA26C74526000E580BC0750626C719 +:1036B0004526000A26C645290083C72AE8BD00E83A +:1036C000FF00C3565751B90300BED136BF2000F3E7 +:1036D000A5595F5EC3565751B90300BED136BF1A14 +:1036E00000F3A5595F5EC326C7061A00C00026C7AF +:1036F000061C00000026C7061E000010C326C706D1 +:103700001A00C00026C7061C00000026C7061E00BF +:103710000008C326C7061A00C00026C7061C000002 +:103720000026C7061E000002C326C7061A00C000F6 +:1037300026C7061C00FFFF26C7061E00FFFFC32684 +:10374000C6050826C64501028D7D02BE0537B903B0 +:1037500000F3A5C326C6050426C6450106A10D37FC +:10376000268945028D7D04C326C6050426C645016B +:1037700007A10B372689450283C704C3A1A2370BD3 +:10378000C0741326C6050426C6450109A1033726C1 +:1037900089450283C704C326C6050826C64501021B +:1037A0008D7D02BE0537B90300F3A5C326C6050605 +:1037B00026C645010B8D7D02BEEF36B90200F3A58A +:1037C000C326C6050626C6450120A16837268945B9 +:1037D00002A16A3726886505C1E00426884504836E +:1037E000C706C326C6050426C645012126C74502CD +:1037F000000083C704C326C6051426C64501228DD2 +:103800007D02BE1F37B90900F3A5C326C6050C26E5 +:10381000C64501238D7D021E0E1F8D364054B9030F +:1038200000F3A533C0B90200F3AB1FC326C60508D9 +:1038300026C64501288D7D02BED136B90300F3A509 +:10384000C326C6050826C6450129A1C23486E0263E +:10385000894502A19B362689450426884506268887 +:1038600045078D7D08C326C6050626C645012B8D56 +:103870007D02BEBB36B90200F3A5C326C6050626E7 +:10388000C645012C8D7D02BEE536B90200F3A5C305 +:1038900026C6050426C6450130A1373786E02689AD +:1038A00045028D7D04C326C7060E001E0026C706EE +:1038B0000600020026C606190000E86CFEE803FEBA +:1038C00026C7062600001026C60628003026C60693 +:1038D000290011BF2A00E83500E84500E85500C37B +:1038E00026C7060E00120026C7060600020026C6DE +:1038F00006190000E832FEE8C9FD26C706260000CA +:103900000426C60628003026C606290013C326C68C +:10391000050426C645010C26C74502000183C704DD +:10392000C326C6050426C645010E26C74502000269 +:1039300083C704C326C6050426C645012126C745FC +:1039400002000083C704C300000000000000000064 +:10395000B339C939833AB339B339B3391C3A1C3A4C +:10396000A3B634A1E936A31137A3D234A1EB36A311 +:103970001337A3D434A1ED36A31537A3D634A10150 +:1039800037A3CE34A1F736A31737A3DC34A1F93619 +:10399000A31937A3DE34F7069B360200750C33C03B +:1039A000A09E368BF02EFFA45039E90F01BE070010 +:1039B000E919F1F6069D368074F3C606A03602C6F4 +:1039C000066E3708C606703702B88803CD39F6068A +:1039D0006F3701754AA1D1363A06E93675413A2664 +:1039E000EA36753BA1D3363A06EB3675323A26EC09 +:1039F00036752CA1D5363A06ED3675233A26EE36C5 +:103A0000751DC606703702FE0E6E37750FB8880337 +:103A1000CD3A830E9B3612C606A0360CE9A8F0A15B +:103A20000537263B0620007540A10737263B0622B6 +:103A3000007536A10937263B062400752CA09E365A +:103A40003C02750826F6061800087547C6066E374C +:103A500008FE0E7037751CC606703702E5020D01B0 +:103A60000425EFFFE702E95EF0C606703702C606DE +:103A70006E3708E50225FFFB0D010025EFFFE70289 +:103A8000E944F0F7069B360001742526F606180077 +:103A90000875ED81269B367FFFB88903CD3AB8843F +:103AA00003CD3AC606A036068326C234AFE917F026 +:103AB000A101373A260F377FC7E9F7FE83269B36E9 +:103AC000ECE82A0D810E9B368000BBFF7FCD53C6EC +:103AD00006A03602E9F0EF830E9B3611C606A0362B +:103AE0000CE9F9EF443B2C3BC72A6B3B443BC72A0C +:103AF000C72AC72AA3B634810EC2340020F7064174 +:103B0000370100741B8CC3C70641370000B87F0320 +:103B1000CD3A33C08EC0BF5437B90600F3AB8EC365 +:103B200033C0A09E368BF02EFFA4E43AF7069B36F6 +:103B3000000175218326C234BFA1A936E700A19BED +:103B400036E90900A19B3681269B36FFDFA90020BC +:103B50007506E96E00E96FEF830E993604C70637E4 +:103B6000370100C606CA3401E95800830E9B36406F +:103B7000E85800A105373B06E9367537A107373B02 +:103B800006EB36752EA109373B06ED367525FE0E80 +:103B90007137751CB88703CD3A830E993610A15042 +:103BA00037C7065037000009069936C606A0360802 +:103BB000E914EF830E993604C70637370300C606AB +:103BC000CA3403C606A0360AE9FCEEA1D136263B6C +:103BD0000620007515A1D336263B0622007512A1DA +:103BE000D536263B062400750FC38D362000E90B21 +:103BF000008D362200E904008D36240083C402F7CC +:103C000006E63401007415263A047708720E263A47 +:103C100064017208C606A03606E9ABEEE87C0A8CA1 +:103C2000C03DFFFF741B26C60618001026C70604F9 +:103C300000493C26C70606000C00CD50B94E00E2F4 +:103C4000FEC606A0360AE994EEE97BEE8F3C063DFF +:103C5000063D063DD23CEA3C063D063DA3B6348116 +:103C600026C234AFDFC7064C370000B88A03CD3A0E +:103C7000803E9D3604750C803E9E36067405C60651 +:103C80009F360633C0A09E368BF02EFFA44C3CF727 +:103C9000069B360020750E81269B36FFBFB88B032E +:103CA000CD3AE95400F7069B3600017403E917EE9C +:103CB000C70637370200C606CA3402830E99360497 +:103CC000830E503704F6069D3680752AE81F0BE9EF +:103CD0002700F7069B36000175D3C7063737020069 +:103CE000C606CA3402830E993604C606A03600F60C +:103CF000069D36807403E8DE0A81269B367CFFBB76 +:103D0000FFFFCD53CD54E9BEEDA3B634E8AD01B805 +:103D10008603CD39C7064C3700008126C234AFDF99 +:103D2000F6069D36807434F7069B3600207456F7ED +:103D3000069B3600017427E83501721CBE004085E1 +:103D400036C23475080936C234FF069234E88B0156 +:103D50007306810E99368000E96CEDE9B500C7065F +:103D600037370200C606CA3402830E993604830E22 +:103D7000503704803E9E36087403E85A0AE8EF0084 +:103D800072D6E9C8FF803E9E360A7512C606A03676 +:103D900000F7069B3608007402CD54E8390A8126E4 +:103DA0009B36FFBFE8C80072AFB88B03CD39E99CE2 +:103DB000FFF6069E36FF7558A3B634E8FE0081264E +:103DC000C234FFBFF6069D36807448F7069B360066 +:103DD000207422F7069B3600407508E89100723087 +:103DE000E9220026A10C00A960007524810E663727 +:103DF0000008E9D2ECC7064C370000E871007210E9 +:103E0000B88B03CD39E8D3007306810E9936800054 +:103E1000E9B4EC803E9D3604750C803E9E360674F7 +:103E200046C6069F3606F7069B360001740C803E98 +:103E30009D36087505C6069F360AE8320072D1E83D +:103E40009900803E9D36087513810E99368000F7E3 +:103E5000069B3600207508B88B03CD39E968ECC69F +:103E6000069F360AE960ECB88603CD3AE958EC269D +:103E7000A10C00A9600074088126C234FFBFF9C3F9 +:103E8000F7069B3600407413810E66370008E84A37 +:103E9000007306810E99368000F9C3810E9B3600AF +:103EA0004080266F37FE81269B367FFFC606A036F0 +:103EB00000F8C3810E99360001E921EC26A120000B +:103EC000A3FB36A3AA3426A12200A3FD36A3AC345B +:103ED00026A12400A3FF36A3AE34C3A10537263B99 +:103EE0000620007519A10737263B062200750FA191 +:103EF0000937263B0624007505E80200F8C3511E69 +:103F0000068BC78D362000BF0537B903001E061F7C +:103F100007F3A58BF88D362000BFA034B90300F35A +:103F2000A5071F598BF8A10737A3A634A10937A30A +:103F3000A834F9C3C606B63401E98BEBE887088BD1 +:103F4000F00512002629060E00268B442A263A0682 +:103F50000E00755B26832E0E000280FC277550260E +:103F60008B442CA9FFFF75478BFE33C026F6453CDA +:103F7000807406268A453A241F03F826807D450969 +:103F8000752D8CC28E0638348EDA8B0E0E00268983 +:103F90000E0E008D742CBF1800F3A433C08ED826EB +:103FA000C7060400B53F26C70606000600CD50B878 +:103FB0000680E9EFE926A10C00A39337830E99361A +:103FC00001E900EB26803E1C00FF752F26803E1E77 +:103FD00000FF752726F7060C004000751BA1D1369F +:103FE00026A31A00A1D33626A31C00A1D53626A3EA +:103FF0001E00B80A80E83607E9E2EAFF069034BE00 +:104000000A00C606B63401F6069D36807505830E95 +:10401000C23401E9B6EA803E9D360A750F26A10C2E +:10402000002507003D04007503E87900A1F33686FA +:10403000E0E71EA3E33681260B37000381260D3708 +:104040007B7F830E0D3748E81E0026A10C00250754 +:10405000003D0400740926F7060C0020007506B820 +:104060000100E93FE9E95FEAC70641370000B87F90 +:1040700003CD3AA11D37A3C43486E0687F031FA394 +:10408000060033C08ED8A10B37A3B234A10D37A3DD +:10409000B434A1F336A3C834A1EF36A39C34A1F104 +:1040A00036A39E34C3800E9D3680BE0000E8B40760 +:1040B000B87B03CD3AB87C03CD39C706333702004D +:1040C000A1E536E72EA1E736E73EB88203CD3AF701 +:1040D000069B3600207503E8FD06A1D336A3EF3614 +:1040E000A39C34A1D536A3F136A39E34C3F6069D16 +:1040F00036807431BE2200E91700F6069D368074C2 +:1041000024BE2300E90A00F6069D36807417BE24FB +:104110000056E8A8058CC03DFFFF5E7405E8D7EFA8 +:10412000CD50E91FE8E99FE9000000000000000011 +:10413000B88403CD3AB88A03CD39E9F700803EA0B0 +:104140003608752EA9D007752CA1B1360D0004E7ED +:1041500008E50025FF73E700B88A03CD3AE8C306F7 +:1041600033C0E70EE50A25C317E70ACD54C606A0FB +:104170003600E968E9BE0400E93FE983269B36BFC3 +:10418000C606713703B88603CD3AB88803CD3AB86E +:104190008303CD3AB88703CD39810EC2340020E9BC +:1041A0009200E84906B88703CD39BBFF7FCD53B8ED +:1041B0008403CD3AB88803CD3AB88B03CD3AB8839F +:1041C00003CD3AB88603CD3AB88503CD3AC3E500AE +:1041D00025FF53E700830EC234408326C234EFE844 +:1041E0000C06BBFF7FCD53B88A03CD3AB88503CD0B +:1041F0003AB88603CD3AB88303CD3AB88703CD3AAF +:10420000B88B03CD3AB88403CD3AB88903CD3AC30D +:10421000830EC23450E81804E8D305F6066F370160 +:104220007512B88903CD39833E0F37007506C7066E +:104230000F370400A19D3680FC087405B88403CDB7 +:1042400039E5020D010825EFFFE702A19D3686E062 +:1042500032E48BF0D1EE33C00D20000906AD36A15B +:10426000AD36E704E953E8E95AE833C0A01B37D17B +:10427000E03A06A0367503E9BAFFE960E8C70641EF +:10428000370000E8C1E1E86A0633C00D4100E75697 +:10429000A1B1360D0010E708E50225F9FF0D030076 +:1042A000E702A1B336E70AA1AF36E706A1AD36E7CC +:1042B00004E87C03E89F03C7061D3700C8C7060B48 +:1042C000370003C7060D377B7F33C0A39936A39B06 +:1042D00036A39D36A39F36A34C37A3F336A3EF3600 +:1042E000A3F136E882FDC6069F3602E9EFE7E50254 +:1042F0000D018825EFFF0D00400D0004E702E8F2F4 +:1043000005E50A0D4000E70A33C0A38137A38537CE +:10431000A38337A38737A38937E5000D0084E7001F +:10432000B88C03CD39B88000CD35C706AA02FFFF8F +:10433000E50025FF7BE700810E9A378000B87E03F9 +:10434000CD3933C0E70EBE08008E063834E8A7ED3D +:104350008326EF34DFFF068137CD50830EEF342004 +:10436000C3F7069A378000743DA9D0077410A900DE +:1043700004741233C0E70EFF068737E9D2FFFF0649 +:104380008537E9CBFFFF068337E9C4FF83269A37D9 +:104390007FA18937030687373D05007F01C3BBFF37 +:1043A0007FCD53E90000E50225FFFB25EFFF0D015E +:1043B00000E702A183373B0646377F2AA185373BBA +:1043C0000648377C21A18937030687373D05007FE2 +:1043D00015C6069F3604E50225FFF70D010025EFFF +:1043E000FFE702E9F7E6BE0100F7069B360300741B +:1043F0000A83269B36FC830EC23404E9D0E6B87BE0 +:1044000003CD39E5020D016025EFFFE702C706F194 +:10441000342003B88E03CD39C38126C2347FFF8098 +:104420000E6F3701F7069B36030074D2B87B03CDBD +:104430003AB87D03CD3983269B36EF33C0B08AA2CC +:104440009F36A29D36C7064C370100C7060F3704BA +:1044500000F7069B3640007506C7060F370300B805 +:104460008D03CD39E800D5E5020D014025EFFF8B26 +:10447000D8B87C03CD39C706333702008BC30D0093 +:104480002025F9FF0B06E83AE702C3FF0EF1347569 +:1044900001C3E54EA901007512E500A900047505E8 +:1044A0000D0004E700B88E03CD39C3E500A9000470 +:1044B00074F325FFFBE700E9EBFFC606A036048393 +:1044C000269B36FC810E9B368000E910E6B88E03F1 +:1044D000CD3ACD54810EAF360018A1AF36E706B8FD +:1044E0007B03CD39A1D336A38F37A1D536A391371E +:1044F000C7068B370200C7068D370200830E993638 +:1045000040E9D9E5803E9F36067515A9D00775ECC0 +:10451000250018750EFF0E8B3775E1C6069F36080D +:10452000E9BAE5FF0E8D3775D3BE0800E99FE5B8FF +:104530007B03CD39F7069B3600207408C6069F36EC +:104540000AE90D00F7069B360040740BB88B03CDCB +:1045500039810E99368000E983E5B87B03CD39C7F0 +:10456000068B370400C7068D370400810E9936008C +:1045700002E969E5F6069D3680751BA9D00775EB43 +:10458000A90018750CFF0E8D3775E0E817FBE94C94 +:10459000E5B88203CD39C3FF0E8B3775CEBE090057 +:1045A000E92BE5C7063D370000C7069B360000E84B +:1045B0003C028126AF36FFE7A1AF36E70681269B96 +:1045C00036FF7FE5020D010025EFFF25FFDFE70243 +:1045D000BBFF7FCD5333C0A39D36A39F36E8500069 +:1045E000E87300B88103CD39C3F7069B3603007426 +:1045F0000DC6069F3602C606A03600E9DFE4830E2C +:104600009B3610C70699360000E8E702E5560D0212 +:1046100000E756C706A80200008B363D37E8440283 +:10462000C606A0360EE9B5E4000000000000000058 +:1046300006B88A03CD3AB88503CD3AB88603CD3A99 +:10464000B88303CD3AB88703CD3AB88B03CD3AB8D7 +:104650008803CD3A07C306B88803CD3AB87B03CDAB +:104660003AB88203CD3AB87F03CD3AB87C03CD3A4D +:10467000B87E03CD3AB88003CD3AB88103CD3AB8BD +:104680008403CD3AB88903CD3AB87D03CD3AB88DCD +:1046900003CD3AC7064137000007C3068E063834FB +:1046A0001F8B0E0E0026890E0E00BE1800BF1800CC +:1046B000F3A4061E07CD340733C08ED8C326F606F2 +:1046C000200080744433C026A02600241F8BF026CF +:1046D0008B5C28891E6A37068E0638341FC0E304B7 +:1046E00026885C288BC6B90600BE2000BF1A00F3DE +:1046F000A48BC883C706F3A426812626001F802624 +:10470000813626000080E9A9FF268B1E2800891E1D +:104710006A37068E0638341FC0E30426881E280038 +:10472000B90600BE2000BF1A00F3A4E984FF86C4C6 +:10473000A36837E887FFF7066A370F007410803EDA +:104740009E36007509BE0000E8ACE9CD50C3C350E9 +:10475000560633C026F606200080740626A02600E2 +:10476000241F8BF0268B5C2686FB83EB04744F831F +:10477000C62A8CC08ED8B9070033C08EC0BF72372E +:10478000F3AB33C98A0C80F9007503E930003BD9DB +:104790007303E929002BD98A4401253F0074193D90 +:1047A0000B007D14D1E08BF82E8BBD5C498D74021B +:1047B00083E902F3A4E9020003F123DB75C433C0EB +:1047C0008ED8075E58C333C026F6062000807406D4 +:1047D00026A02600241FC3E50A25C3BFE70AB88622 +:1047E00003CD39B88303CD3981269B367CDFB8856C +:1047F00003CD3AE50225FFF30D010025EFFFE702A7 +:10480000E50025FF53E700A1E73625FFFEA3E736C5 +:10481000E73E83269936CF810EAF360010A1AF3622 +:10482000E706C3E5020D010C25EFFFE702A1E7361D +:104830000D0001E73EA3E736810E9B360020830E74 +:1048400099362081269B367CBF810EAF360010A1A1 +:10485000AF36E706B88603CD39B88503CD39B883BE +:1048600003CD3AC30BF67549068E063234803EE01E +:104870003401751B26893606008E06323426F7066B +:104880000A000020740726810E0800002007C3805C +:104890003EE33401751926893606008E0632342629 +:1048A000F7060A000010740726810E0800001007A2 +:1048B000C3E9B4FF50515733C0B906008EC0BFD111 +:1048C00036F3AE5F740C26F6060000C07504F85986 +:1048D00058C3F9E9F9FF8B050B45020B4504C35298 +:1048E00050E506251E003D1E0075F6B80180E75A0A +:1048F000585AC3E8E9FF50E50225FF7F0D01002566 +:10490000EFFFE7020D0080E702A1AD36E704A1AF9B +:1049100036E70658C3000000000000000000000059 +:104920002E2BCE4110427B413041A241AF4544295C +:10493000C72AC72A6039F43A5C3C093DB13D343F8F +:10494000C72A3C3FC72AC43F16401640ED40FA40F4 +:104950000741C72AC72AC72AC72AD65200000137EB +:10496000E936F336EF361D370D370B379C370337F3 +:10497000FB36622D4006D12DF401BA4440068C432B +:104980006400E82CC800D82B0500E9455000974585 +:10499000FA00AE2D04016A420200F62CBC02932DEF +:1049A000DC051D2D6400A12D1400D73A0807812DC8 +:1049B0006400B33E020030436400C52CF4018B4414 +:1049C00002000000000000000000000000000000E5 +:1049D000803EFD3402740CE82005C706A1360000B5 +:1049E000E99AF8FF06C033E810058B363D37E873C7 +:1049F000FEC3CD34E9E805C706A3360000C706416B +:104A0000370000E8EDFE33C00D4100E756A1B13696 +:104A10000D0010E708A1B336E70AA1AF36E706A1FB +:104A2000AD36E704E82B09C7061D3700C8C7060BDB +:104A3000370003C7060D377B7F33C0A39B36A39D8A +:104A400036C7064C370100C6069E36FFC706053737 +:104A50000000C70607370000C70609370000A3F3A8 +:104A600036A3EF36A3F136E8FEF5E50225F9FF0D92 +:104A700003000D008825EFFF0D00400D0004E70244 +:104A8000B88F03CD39B88000CD35C706AA02FFFF25 +:104A9000A1A936A3A7360D00A40D0008E700A3A91D +:104AA00036C706A3360100C706A5360C00833EA50F +:104AB00036007509C7063D370500E913FFFF0EA54F +:104AC00036BE1100E82205B89003CD39C3833EA35A +:104AD000360174D9C3B89003CD3A26A02B00268B9B +:104AE0001E2C00CD34833EA336017403E9F0043C50 +:104AF0000F751E81FB0002751826A12000A3053743 +:104B000026A12200A3073726A12400A30937E9091B +:104B100000C7063D370100E9B6FEC706A33602000E +:104B2000C6069E36FFE8CBFDE81CD933C0A3853707 +:104B3000A38337A38737A38937B89103CD39B880CA +:104B400000CD35C706AA02FFFFE50025FF53E700A9 +:104B5000810E9A378000B89203CD3933C0E70EBE7C +:104B600008008E063834E88EE526C70604007D4B23 +:104B70008326EF34DFCD50830EEF3420C3F7069A3F +:104B80003780007432A9D007740CA90004740E3366 +:104B9000C0E70EE9DAFFFF068537E9D3FFFF06839A +:104BA00037E9CCFFC7063D370100E936FE83269A78 +:104BB000377FBBFF7FCD53E5000D00ACE700E5027A +:104BC00025FFFB25EFFF25FFF70D0100E702A1837D +:104BD000373B0646377FCDA185373B0648377CC437 +:104BE000C706A3360300BE1300E8FD03B89303CD48 +:104BF00039B89403CD39B89603CD39B89503CD397A +:104C0000BE0600E8E303E9D603833EA3360374013E +:104C1000C3BE1300E8D203B89403CD39C3B89403DC +:104C2000CD3A26A02B00268B1E2C00CD34833EA32C +:104C300036037403E9A8033C0D753E83FB00753908 +:104C4000E5020D0020E702B89303CD3AC706A3366C +:104C50000400BE0000E80CFCC6069D3680C6069E19 +:104C60003600C70633370200B89A03CD39E8FC0096 +:104C7000C7064C370000E96603C7063D370800E960 +:104C800061FD833EA336037509C7063D370500E97C +:104C900051FDE94A03833EA336047412833EA336D2 +:104CA00005740BCD34C7063D370700E935FDC7064F +:104CB000A3360600C6069E36FFB89A03CD3AB899C9 +:104CC00003CD3AB89603CD3AB89703CD39B89803D7 +:104CD000CD39B89B03CD39E918FDCD34833EA336D9 +:104CE000047718833EA336037508F7069B36000148 +:104CF0007509C7063D370100E9E8FCE9E102CD345A +:104D0000833EA336027709C7063D370100E9D3FC8D +:104D1000833EA336047705B89603CD39E9C00283F4 +:104D20003EA33603751026A10C00250700503D0454 +:104D3000007503E83600A1F33686E0E71EA3E336EC +:104D400081260B37000381260D377B7F830E0D37BD +:104D500048E814F3583D0400740926F7060C0020B7 +:104D6000007506B80100E97A02E986FCA1E536E79C +:104D70002EA1E736E73EA1D336A39C34A1D536A3B6 +:104D80009E34C326803E1C00FF752F26803E1E00E9 +:104D9000FF752726F7060C004000751BA1D13626AB +:104DA000A31A00A1D33626A31C00A1D53626A31E24 +:104DB00000B80A80E92C02E938FCFF069034BE0AEC +:104DC00000C606B63401F6069D36807505830EC210 +:104DD0003401CD34E90CFC833EA336037509C706C4 +:104DE0003D370500E9FCFBE5020D03000D00880DD1 +:104DF00000400D0004E702C706A3360500C6069E64 +:104E000036FFBE0200E8E101B88903CD3AB89A0343 +:104E1000CD3AB89903CD39B89703CD39B89803CDB9 +:104E200039E9BB01833EA33603740A833EA33604EB +:104E30007403E9AA01BE0600E8AE01B89503CD39B6 +:104E4000E99C01833EA336057403E99201BE02008A +:104E5000E89601B89903CD39E98401C7060F3705F3 +:104E600000E97B01E50225FFDFE702C706A336075D +:104E700000C7060F370500E96501E8D504C6069DA1 +:104E80003600C7069B360000C7060F370500C70669 +:104E9000A8020000C7064C370100E50225F9FF0D06 +:104EA00003000D008825EFFF0D00400D0004E70210 +:104EB000E967FCB89A03CD39F706F4330010750999 +:104EC000C70633370200E91601FF0E33377403E9D2 +:104ED0000D01FF068E34830EC23408C7063D37032A +:104EE00000E9FFFAC35250BAE000B80010EF585A78 +:104EF000C3C7063D370000E9E9FAFAE85404B88070 +:104F0000038EC026C7060400D82BB87F038EC026A8 +:104F1000C7060400E82C33C08EC0A1A736A3A9366B +:104F2000A1A936E700A1AB36E702C70605370000A6 +:104F3000C70607370000C70609370000C6069D36BA +:104F400000C6069E36FFC7069B360000C706A3367E +:104F50000000C7060F370000C706A8020000C706FA +:104F60004C3701008126AF36FFE7A1AF36E706BB1D +:104F7000FF7FCD53E87CF9E5560D0200E756FBC3F1 +:104F80008D3EC0538D36F038B90E008B1E303489FB +:104F90005C022E8B45028944062E8B0589440483CE +:104FA000C70483C610E2E8B880038EC026C7060493 +:104FB00000E251B87F038EC026C7060400B2523308 +:104FC000C08EC0C706A1360100C7060F370500C353 +:104FD00033FF8E06A6028B36A4022EFFA4A053E850 +:104FE0008CDBC3E848F7E9F6FF8E063834E807E1C2 +:104FF00026C7060400DF4FCD50C326C7060A0000AF +:105000000026FF260400CD34E9D4FFA1D13626398D +:10501000061A007522A1D3362639061C007518A180 +:10502000D5362639061E00750E26F7060C00400000 +:105030007405830E663740810EAF360010A1AF367F +:10504000E706833EA336027505CD34E956FB833E61 +:10505000A3360074B1833EA3360577AA26F6060A66 +:1050600000FF75A2E8FDDD50F6069336207503E9D2 +:105070008C0026A10C002507003D07007503E9768A +:10508000003D05007503E96E00F706E634188075EB +:1050900003E96A00F706E6340080743526803E296D +:1050A0000002752D5156578D363E348D3E2000B985 +:1050B0000600F3A65F5E59754526A12000A33E3485 +:1050C00026A12200A3403426A12400A34234E926CD +:1050D00000F706E6340800740B26803E19000074C1 +:1050E00003E91300F706E6341000741226A0280026 +:1050F000C0E80422C0740726C7060400FFFF582337 +:10510000C07403E9DDFE81269B36FFFE26A1200048 +:105110003B06D136751A26A122003B06D336751000 +:1051200026A124003B06D5367506810E9B3600016C +:1051300026A12000257FFFA3B83426A12200A3BA10 +:105140003426A12400A3BC348BC686C4A3C034D1AA +:10515000E680FC097403E8F6F5A105370B0607376E +:105160000B060937743E26A120003B06053775174C +:1051700026A122003B060737750D26A124003B0619 +:1051800009377503E91D0026A02800240F3C03748D +:105190001B3C00750F833EA336047410F7069B3644 +:1051A000000174082EFF94F853E933FECD34C7068E +:1051B0003D370100E92CF8833EA336057410833E89 +:1051C000A336017E0983EE162EFF942454C3CD34FA +:1051D000C326A10C003DFF7F740526FF260400E9CD +:1051E000FDFDA1F433A90088740BA9001075098B8B +:1051F0001E4337FFE3E99700C70635370500C706AA +:1052000043372852F706F43300087406C7064337BD +:105210001A52B88003CD39E9C5FDA9000874D9FF39 +:105220000E353775EDE93000A9000875CBFF0E3556 +:105230003775DF810EC234C000F6069D3680740FCC +:10524000810E9B360080C7060F370200E990FDC72C +:10525000063D370200E98BF780269E36FF7530F653 +:10526000069D36807420FF069434830E6637208EA8 +:1052700006303426F7060A000001740726810E085E +:10528000000001E90900C7063D370400E954F78131 +:105290000EAF360008A1AF36E706E50AA900807414 +:1052A0000E8126AF36FFF7A1AF36E706E949FFE9E1 +:1052B0002DFDC70641370000BE2900E82BFDE91E81 +:1052C000FDCD34833EA336047709C7063D37010080 +:1052D000E910F7E909FDCD34C3C7069B360000E8A5 +:1052E0000CF58126AF36FFE7A1AF36E70681269B96 +:1052F00036FF7FE5020D010025EFFF25FFDFE70206 +:10530000BBFF7FCD5333C0A39D36A39F36E820F368 +:10531000E843F3830E9B3610C70699360000E8D2A7 +:10532000F5E5560D0200E756C706A8020000BE00CC +:1053300000E830F5C606A0360EB89C03CD39B8801B +:1053400000CD35C706AA02FFFFC706A1360100E956 +:10535000A5F606B88F03CD3AB89003CD3AB89103BD +:10536000CD3AB89203CD3AB89303CD3AB89403CD71 +:105370003AB89503CD3AB89603CD3AB89703CD3AEB +:10538000B89803CD3AB89903CD3AB89A03CD3AB854 +:105390009B03CD3AB87F03CD3AB88003CD3A07C31B +:1053A000F749F14EDF4FDF4FDF4FDF4FF851DF4F4F +:1053B000FA4F0B50D151DF4FDF4FDF4FDF4FDF4F41 +:1053C000E44E0600CD4A0400E44E1900AD4BFA004D +:1053D000824C0807094C1400244E6400D74DF40198 +:1053E000644EBC027A4EE803434E0200B34EF40111 +:1053F0005B4EF401E54E140006500650954CC15228 +:10540000C152FE4CDA4C0650065006500650B751B9 +:10541000B751B751B751B751B7510650D54A065099 +:105420001D4C0650834D1F4D1F4DED40FA40074166 +:1054300037372E3737202079792F79792F797920CE +:1054400030312E3930202030322F31372F3939206A +:10545000000000000000000000000000000000004C +:10546000000000000000000000000000000000003C +:10547000000000000000000000000000000000002C +:10548000000000000000000000000000000000001C +:10549000000000000000000000000000000000000C +:1054A00000000000000000000000000000000000FC +:1054B00000000000000000000000000000000000EC +:1054C00000000000000000000000000000000000DC +:1054D00000000000000000000000000000000000CC +:1054E00000000000000000000000000000000000BC +:1054F00000000000000000000000000000000000AC +:10550000000000000000000000000000000000009B +:10551000000000000000000000000000000000008B +:10552000000000000000000000000000000000007B +:10553000000000000000000000000000000000006B +:10554000000000000000000000000000000000005B +:10555000000000000000000000000000000000004B +:10556000000000000000000000000000000000003B +:10557000000000000000000000000000000000002B +:10558000000000000000000000000000000000001B +:10559000000000000000000000000000000000000B +:1055A00000000000000000000000000000000000FB +:1055B00000000000000000000000000000000000EB +:1055C00000000000000000000000000000000000DB +:1055D00000000000000000000000000000000000CB +:1055E00000000000000000000000000000000000BB +:1055F00000000000000000000000000000000000AB +:10560000000000000000000000000000000000009A +:10561000000000000000000000000000000000008A +:10562000000000000000000000000000000000007A +:10563000000000000000000000000000000000006A +:10564000000000000000000000000000000000005A +:10565000000000000000000000000000000000004A +:10566000000000000000000000000000000000003A +:10567000000000000000000000000000000000002A +:10568000000000000000000000000000000000001A +:10569000000000000000000000000000000000000A +:1056A00000000000000000000000000000000000FA +:1056B00000000000000000000000000000000000EA +:1056C00000000000000000000000000000000000DA +:1056D00000000000000000000000000000000000CA +:1056E00000000000000000000000000000000000BA +:1056F00000000000000000000000000000000000AA +:105700000000000000000000000000000000000099 +:105710000000000000000000000000000000000089 +:105720000000000000000000000000000000000079 +:105730000000000000000000000000000000000069 +:105740000000000000000000000000000000000059 +:105750000000000000000000000000000000000049 +:105760000000000000000000000000000000000039 +:105770000000000000000000000000000000000029 +:105780000000000000000000000000000000000019 +:105790000000000000000000000000000000000009 +:1057A00000000000000000000000000000000000F9 +:1057B00000000000000000000000000000000000E9 +:1057C00000000000000000000000000000000000D9 +:1057D00000000000000000000000000000000000C9 +:1057E00000000000000000000000000000000000B9 +:1057F00000000000000000000000000000000000A9 +:105800000000000000000000000000000000000098 +:105810000000000000000000000000000000000088 +:105820000000000000000000000000000000000078 +:105830000000000000000000000000000000000068 +:105840000000000000000000000000000000000058 +:105850000000000000000000000000000000000048 +:105860000000000000000000000000000000000038 +:105870000000000000000000000000000000000028 +:105880000000000000000000000000000000000018 +:105890000000000000000000000000000000000008 +:1058A00000000000000000000000000000000000F8 +:1058B00000000000000000000000000000000000E8 +:1058C00000000000000000000000000000000000D8 +:1058D00000000000000000000000000000000000C8 +:1058E00000000000000000000000000000000000B8 +:1058F00000000000000000000000000000000000A8 +:105900000000000000000000000000000000000097 +:105910000000000000000000000000000000000087 +:105920000000000000000000000000000000000077 +:105930000000000000000000000000000000000067 +:105940000000000000000000000000000000000057 +:105950000000000000000000000000000000000047 +:105960000000000000000000000000000000000037 +:105970000000000000000000000000000000000027 +:105980000000000000000000000000000000000017 +:105990000000000000000000000000000000000007 +:1059A00000000000000000000000000000000000F7 +:1059B00000000000000000000000000000000000E7 +:1059C00000000000000000000000000000000000D7 +:1059D00000000000000000000000000000000000C7 +:1059E00000000000000000000000000000000000B7 +:1059F00000000000000000000000000000000000A7 +:105A00000000000000000000000000000000000096 +:105A10000000000000000000000000000000000086 +:105A20000000000000000000000000000000000076 +:105A30000000000000000000000000000000000066 +:105A40000000000000000000000000000000000056 +:105A50000000000000000000000000000000000046 +:105A60000000000000000000000000000000000036 +:105A70000000000000000000000000000000000026 +:105A80000000000000000000000000000000000016 +:105A90000000000000000000000000000000000006 +:105AA00000000000000000000000000000000000F6 +:105AB00000000000000000000000000000000000E6 +:105AC00000000000000000000000000000000000D6 +:105AD00000000000000000000000000000000000C6 +:105AE00000000000000000000000000000000000B6 +:105AF00000000000000000000000000000000000A6 +:105B00000000000000000000000000000000000095 +:105B10000000000000000000000000000000000085 +:105B20000000000000000000000000000000000075 +:105B30000000000000000000000000000000000065 +:105B40000000000000000000000000000000000055 +:105B50000000000000000000000000000000000045 +:105B60000000000000000000000000000000000035 +:105B70000000000000000000000000000000000025 +:105B80000000000000000000000000000000000015 +:105B90000000000000000000000000000000000005 +:105BA00000000000000000000000000000000000F5 +:105BB00000000000000000000000000000000000E5 +:105BC00000000000000000000000000000000000D5 +:105BD00000000000000000000000000000000000C5 +:105BE00000000000000000000000000000000000B5 +:105BF00000000000000000000000000000000000A5 +:105C00000000000000000000000000000000000094 +:105C10000000000000000000000000000000000084 +:105C20000000000000000000000000000000000074 +:105C30000000000000000000000000000000000064 +:105C40000000000000000000000000000000000054 +:105C50000000000000000000000000000000000044 +:105C60000000000000000000000000000000000034 +:105C70000000000000000000000000000000000024 +:105C80000000000000000000000000000000000014 +:105C90000000000000000000000000000000000004 +:105CA00000000000000000000000000000000000F4 +:105CB00000000000000000000000000000000000E4 +:105CC00000000000000000000000000000000000D4 +:105CD00000000000000000000000000000000000C4 +:105CE00000000000000000000000000000000000B4 +:105CF00000000000000000000000000000000000A4 +:105D00000000000000000000000000000000000093 +:105D10000000000000000000000000000000000083 +:105D20000000000000000000000000000000000073 +:105D30000000000000000000000000000000000063 +:105D40000000000000000000000000000000000053 +:105D50000000000000000000000000000000000043 +:105D60000000000000000000000000000000000033 +:105D70000000000000000000000000000000000023 +:105D80000000000000000000000000000000000013 +:105D90000000000000000000000000000000000003 +:105DA00000000000000000000000000000000000F3 +:105DB00000000000000000000000000000000000E3 +:105DC00000000000000000000000000000000000D3 +:105DD00000000000000000000000000000000000C3 +:105DE00000000000000000000000000000000000B3 +:105DF00000000000000000000000000000000000A3 +:105E00000000000000000000000000000000000092 +:105E10000000000000000000000000000000000082 +:105E20000000000000000000000000000000000072 +:105E30000000000000000000000000000000000062 +:105E40000000000000000000000000000000000052 +:105E50000000000000000000000000000000000042 +:105E60000000000000000000000000000000000032 +:105E70000000000000000000000000000000000022 +:105E80000000000000000000000000000000000012 +:105E90000000000000000000000000000000000002 +:105EA00000000000000000000000000000000000F2 +:105EB00000000000000000000000000000000000E2 +:105EC00000000000000000000000000000000000D2 +:105ED00000000000000000000000000000000000C2 +:105EE00000000000000000000000000000000000B2 +:105EF00000000000000000000000000000000000A2 +:105F00000000000000000000000000000000000091 +:105F10000000000000000000000000000000000081 +:105F20000000000000000000000000000000000071 +:105F30000000000000000000000000000000000061 +:105F40000000000000000000000000000000000051 +:105F50000000000000000000000000000000000041 +:105F60000000000000000000000000000000000031 +:105F70000000000000000000000000000000000021 +:105F80000000000000000000000000000000000011 +:105F90000000000000000000000000000000000001 +:105FA00000000000000000000000000000000000F1 +:105FB00000000000000000000000000000000000E1 +:105FC00000000000000000000000000000000000D1 +:105FD00000000000000000000000000000000000C1 +:105FE00000000000000000000000000000000000B1 +:105FF00000000000000000000000000000000000A1 +:106000000000000000000000000000000000000090 +:106010000000000000000000000000000000000080 +:106020000000000000000000000000000000000070 +:106030000000000000000000000000000000000060 +:106040000000000000000000000000000000000050 +:106050000000000000000000000000000000000040 +:106060000000000000000000000000000000000030 +:106070000000000000000000000000000000000020 +:106080000000000000000000000000000000000010 +:106090000000000000000000000000000000000000 +:1060A00000000000000000000000000000000000F0 +:1060B00000000000000000000000000000000000E0 +:1060C00000000000000000000000000000000000D0 +:1060D00000000000000000000000000000000000C0 +:1060E00000000000000000000000000000000000B0 +:1060F00000000000000000000000000000000000A0 +:10610000000000000000000000000000000000008F +:10611000000000000000000000000000000000007F +:1061200090EAC01500000000000000000000130607 +:00000001FF +/* + * The firmware this driver downloads into the tokenring card is a + * separate program and is not GPL'd source code, even though the Linux + * side driver and the routine that loads this data into the card are. + * + * This firmware is licensed to you strictly for use in conjunction + * with the use of 3Com 3C359 TokenRing adapters. There is no + * waranty expressed or implied about its fitness for any purpose. + */ + +/* 3c359_microcode.mac: 3Com 3C359 Tokenring microcode. + * + * Notes: + * - Loaded from xl_init upon adapter initialization. + * + * Available from 3Com as part of their standard 3C359 driver. + */ diff --git a/trunk/firmware/Makefile b/trunk/firmware/Makefile index 344713b11669..0d15a3d113a2 100644 --- a/trunk/firmware/Makefile +++ b/trunk/firmware/Makefile @@ -26,6 +26,7 @@ fw-shipped- += acenic/tg1.bin else acenic-objs := acenic/tg1.bin acenic/tg2.bin endif +fw-shipped-$(CONFIG_3C359) += 3com/3C359.bin fw-shipped-$(CONFIG_ACENIC) += $(acenic-objs) fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \ adaptec/starfire_tx.bin @@ -85,6 +86,7 @@ fw-shipped-$(CONFIG_SCSI_QLOGIC_1280) += qlogic/1040.bin qlogic/1280.bin \ qlogic/12160.bin fw-shipped-$(CONFIG_SCSI_QLOGICPTI) += qlogic/isp1000.bin fw-shipped-$(CONFIG_INFINIBAND_QIB) += qlogic/sd7220.fw +fw-shipped-$(CONFIG_SMCTR) += tr_smctr.bin fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \ ess/maestro3_assp_minisrc.fw diff --git a/trunk/firmware/WHENCE b/trunk/firmware/WHENCE index 8388f02de2bd..182ecb6c275e 100644 --- a/trunk/firmware/WHENCE +++ b/trunk/firmware/WHENCE @@ -88,6 +88,18 @@ Licence: Allegedly GPLv2+, but no source visible. Marked: QLogic ISP1280/ device driver for Linux 2.2.x and 2.4.x Copyright (C) 2001 Qlogic Corporation (www.qlogic.com) +-------------------------------------------------------------------------- +Driver: smctr -- SMC ISA/MCA Token Ring adapter + +File: tr_smctr.bin +Info: MCT.BIN v6.3C1 03/01/95 + +Original licence info: + + * This firmware is licensed to you strictly for use in conjunction + * with the use of SMC TokenRing adapters. There is no waranty + * expressed or implied about its fitness for any purpose. + -------------------------------------------------------------------------- Driver: kaweth -- USB KLSI KL5USB101-based Ethernet device @@ -555,6 +567,32 @@ Found in hex form in kernel source. -------------------------------------------------------------------------- +Driver: 3C359 - 3Com 3C359 Token Link Velocity XL adapter + +File: 3com/3C359.bin + +Licence: +/* + * The firmware this driver downloads into the tokenring card is a + * separate program and is not GPL'd source code, even though the Linux + * side driver and the routine that loads this data into the card are. + * + * This firmware is licensed to you strictly for use in conjunction + * with the use of 3Com 3C359 TokenRing adapters. There is no + * waranty expressed or implied about its fitness for any purpose. + */ +/* 3c359_microcode.mac: 3Com 3C359 Tokenring microcode. + * + * Notes: + * - Loaded from xl_init upon adapter initialization. + * + * Available from 3Com as part of their standard 3C359 driver. + */ + +Found in hex form in kernel source. + +-------------------------------------------------------------------------- + Driver: PCMCIA_PCNET - NE2000 compatible PCMCIA adapter File: cis/LA-PCM.cis diff --git a/trunk/firmware/tr_smctr.bin.ihex b/trunk/firmware/tr_smctr.bin.ihex new file mode 100644 index 000000000000..6797451ffa9c --- /dev/null +++ b/trunk/firmware/tr_smctr.bin.ihex @@ -0,0 +1,477 @@ +:10000000BC1D123B63B4E900001F000101000205A2 +:10001000010006030100040901000A070100080BA2 +:1000200001000C000000000F0100100D01000E1374 +:10003000010014110100120000050015010016193D +:1000400001001A1701001800000E00000001000056 +:100050000004001B01001C0000070000000F00004E +:10006000000B001D01001E0000080000000200003F +:10007000000C000000060000000D0000000300005E +:10008000000A00000009000478C6BC0194049380B3 +:10009000C84062E9DA1C2C1555555555555555582B +:1000A0000BE9E5D595C19D77CEBBA06E1C05F67713 +:1000B000C602FA9670E81DC0170E02FA587DC05F9E +:1000C00072CEECA4C384907A30CD8D7919E76C247C +:1000D000279C08390738A84A4CEA4D989B244CC005 +:1000E00026D3E7545A4DF24C0C13234990326EA498 +:1000F000DF9371137726E126F8260C4C12260809A7 +:10010000828260A9307936B0B2A8A772648F9B331F +:1001100033F9B839D51173AA75265D2651932A494A +:1001200094C99589BC4DC89B809BA099064C862696 +:10013000589BA49B9937626C679B3330BF366661CE +:10014000BF36ECC5BD66825A5031D59D9818293C02 +:1001500098864C17263E2CB8693B492EB408431AA2 +:10016000A4F9B351F110F343CD086F6379B3330EA3 +:100170001398499804DA7CE05279310C982E4DACF2 +:100180002C8414EE4CFE675EE49A7529D7A9353AA3 +:10019000945BD59B58B4AF7566AF14A9EF40952515 +:1001A00008B9AD42FCD8D98C330E1398661E45AC05 +:1001B000B00C42D3CCA61262DEB4B180497DA2DE7F +:1001C000B418C02484E654F5834601681A630CC64B +:1001D0001264FA4C351C2C0EAAAAAAAAAAAAAAAA88 +:1001E000AAAAAAAAAAADD70270E04CF3A1C1D5C0B1 +:1001F0003CB96939604E58770267933C99E4CF382F +:100200001C972E401B903146A35E0E88346A35E061 +:10021000E8AA351AA9F51546A3EA7D4AA351AA9F73 +:100220007054A6572EB4CDC8A30CC1DAC6E1CB7A60 +:10023000D41C68FFCF55A8C02D851117442A300B58 +:100240004A88C24DB520D5260169516952195260BC +:100250001695168296549805A545F3DD6AF9281877 +:10026000EF003030514E445D12D143E6126F9EBA1A +:10027000CCDF25031DE006060A30CCA9EB2D008655 +:10028000A612654F56D665495F3DE837C940C77825 +:100290000181828C33184980AE40C518059C6D18C9 +:1002A000660EF3A0C61262DEF504B4AC6BC61991FB +:1002B0007305482E72948073A1C8473666642F3642 +:1002C0006664079902918E72D10F9D063173A0C3A7 +:1002D000516A1A20BF3A0C2C7387435E600223FCDC +:1002E000E0D635EF9EF5EF92818EF0030305186698 +:1002F00045CC0B482E700A4039D0E4239B3332178B +:100300009B333203CC8548C73814A5CE297ED280D2 +:10031000A1A8B448882FCE830B1CE1D0D7980488BD +:1003200087CE963173A58FF38358D7BE7B82AF9269 +:10033000818EF0030305186645CC1520B9C8290045 +:10034000E743908E6CCCC85E6CCCC80F3205231C82 +:10035000E450D45A17882FCE8310F9D023173A04CB +:1003600035E600221639C3A3FCE0D635E0BFF41809 +:10037000F22D4D43516E5A221F30D417E74191732D +:1003800005482E776900E743908E6CCCC85E6CCC34 +:10039000C80F3205231CEF4C4E0604C99E0BFF41CB +:1003A0008F22D4D43516E5A221F35A82FCE8322EEE +:1003B00060A905CE1348073A1C8473666642F3664B +:1003C000664079902918E70A989C0A9EB5125C7CD1 +:1003D000C3318B982A7CD3ED38E9D34E74ED499E16 +:1003E0000BFF418F22D4D43516E5A22DEB45338F78 +:1003F000FCF7A05F25031DE40E060A30CC0CF3EBDE +:1004000040DE61A870920A00E1241E00E1241E0073 +:10041000E1241E00E1241E00E1241E010F982A0B96 +:10042000F3A0C8B9A2A4173A6900E743908E7548B3 +:100430005E706901E6005231CC1814A5CC09829493 +:10044000730CA091F525CC070684849F30A2A47D6F +:100450005075A665014A8EB4CCC435547566A49710 +:100460007A895053138019E3495C6DCEA940350653 +:1004700078D25706F1B32A8D972362925D69991C51 +:100480006A36E6CD46126F9EE1ABE4A30CC0DEAC4B +:10049000D40D281BD012A500F84BAD332806A0DEE2 +:1004A00014973A895DC00DE30690925D699866B92C +:1004B0001995E4A8CF9D331849BE7B86AF928C3343 +:1004C00024140CF4832421C270BFF418F22D4D4380 +:1004D000516E5A221F32A82FCE8322E605A4173A66 +:1004E0006900E743908E75485E706901E642A46337 +:1004F0009802294B9A2978E9405313818132678207 +:10050000FFD063C8B5350D45AE50087CE0D05F9D87 +:100510000645CC01A4173A6900E743908E75485E02 +:10052000706901E659A463981C52973B30528E7D46 +:100530002A091F51EBA4A40AB99487AEC531380229 +:10054000FFD063C8B5350D45AE50087CEA20BF3AF0 +:100550000C8B9A16905CE9A4039D0E4239D5217943 +:1005600095480F300A918E60EB297300095404CA34 +:1005700082655265E4CA226572650932E099724C5F +:10058000C4E00BFF418F22D4D43516B94021F38A41 +:1005900082FCE8322E60A905CE9A4039D0E4239D32 +:1005A00052179954619901E640A4639804B1849864 +:1005B00018EF2D0305313802FFD063C8B5350D455E +:1005C000B968887CE0505F9D0645CC81482E713427 +:1005D0008F48014815210521E90A5203CE5A4639B0 +:1005E000CF478E60AB1AF35343EB3524B81B30076B +:1005F000098A742F7E41741E1D0D874649D595D1F9 +:10060000D5D5BBA94E829D053A0A7414E829D0427B +:10061000745BCE50C40745BCE20C40745BCE8304CF +:10062000F9954D13635E6F313BA08BA2C5398D7870 +:100630003A22A0006BC1D1546016D991A2E7438C35 +:1006400024DC1CE05117396B3BCC4B422E6B50BF66 +:100650003636654F7A185525789823E7503EF38152 +:100660004C026D3E7153AF78A9D4A629B1BCD9997B +:10067000B28E628F222E7516B0B2AB23281654525A +:1006800031BCD999B28E6619022E7516502CA9C8A4 +:10069000C6F520D3E47F4F9C0AD6167F90EE4CEB34 +:1006A000CFE288BA2F4286AEBDE5A7529F93637909 +:1006B000EB3308F9945247CD99256F3A0C13E65560 +:1006C000344C5A4DB52395A548115A0A4395AC2C84 +:1006D000BA240549B1BCCAA7726C6BC5BDE83169C3 +:1006E000525D0612653EB1504C7D4FAC0A300B3660 +:1006F0006411738A838E75129F7BD29958EE822E75 +:1007000077A0E39D5D4FBC2A532953DE9324BAB3EF +:1007100036AA4AC679D4B9DE625A11735050BF372F +:10072000366F1323BA0C24CEBDE2A752B28E6B6093 +:10073000622E751330ACA059CA646379B333651C5B +:10074000CC32045CEA2CA059DF231BD4835247DD52 +:100750007996D49EB3524BA25A1A8D5D7B82A752D2 +:10076000B28E6619022E7516502C8C321D7B8EA708 +:1007700052B1BCD9999804DA7CE2ACFE6619022E1B +:100780006550BF336664FE7418864C1726D6165221 +:100790003918DE7ACCC23E651491F36649086E833F +:1007A0000933AF31ED0D9D0612622A318D6DE7419F +:1007B000827CCAA68987092E29B1AF1039D66497E1 +:1007C000301D42759344028C24D27AB350F68905C9 +:1007D000435E6198C02C92253C8B2489490549E7EA +:1007E0000CB98498B7AD3344AE5A5186609F38A98E +:1007F000A26C6BC48EF45E49461262DEB4CD215CFD +:10080000B4A30CC13E7229A26C6BC6126247F0E819 +:10081000C33204354092A4828810927CCBD42FA49A +:1008200002118498B7AD3344AE5A5186609F38A9FF +:10083000A26C6BC48EF45E494408493E65EA17D247 +:100840000108C24C5BD699A42B9694619827CE459B +:10085000344D8D78810927CCBD12286C58AFB6F382 +:10086000A0C13E655344D8D7928E7D4BC2FA612613 +:10087000063AB36B030549E70CB96F5A66955CB449 +:10088000A30CC13E7029A26EA4DF9371137726E1F9 +:1008900026F826C6BC9473F92F0BE9849818EACC85 +:1008A000EC0C15279C32FF3D56AF928B7AD335D591 +:1008B000CB4A30CC13E7029A26C6BC947341979179 +:1008C000F483CE0420628B0516498C24C0C7569051 +:1008D000C0C15279C32E5BD5A672D294FAAD58C866 +:1008E000FA9F54B3324BB954A651866B79D0609FAE +:1008F0003205344D8D7A4D1E7AB35100A93D59A869 +:100900007B4482A1AF4A8D52A95241494F3A2E40B1 +:10091000A49950BE90085279C32E61262DEB4CD07D +:1009200015CB4A30CC13E7029A26C6BC48FE1D25DB +:1009300046A954A920A4A79D1720524CA85F48049B +:100940002309316F5A6680AE5A5186609F3814D1A0 +:100950003635E4A79D1720524CA2450D8B15F49116 +:10096000DE8BC928C24C5BD699A95CB4A30CD6F324 +:10097000A0C13E640A689B1AF16D4CAA92E03694BD +:10098000709B297813AEB3AA85D44375093AC9EB95 +:100990003524B81B328E13487E4EFD40FD40FD408D +:1009A000FD40FD40FC13F421F917458A300B335FFD +:1009B00083A22A300B335F83A2A8C02DB32070928C +:1009C000139ADE741827CCAA689B1AF70745518042 +:1009D0005B66470738A823E751113FE0E8854601E9 +:1009E0006D990612654F7A2024BAB33215257BAD76 +:1009F0003378AE0E73D047CEA730CC44FF83A2A885 +:100A0000C02CD991C1D11518059B3208BA2C518040 +:100A100059B3207092E29889FDBCEE1890FC8BA22D +:100A2000C52B0D783A22A561AF074551805B66441E +:100A30009EB3524B83ADC709BE1F9F74655D0A17F5 +:100A40007CABA0C24C3849122E384907A30CC13EDA +:100A5000655344D8D7ADE700324B9B33344A03008B +:100A60009D25CE8324B819998C02124BA199D8C028 +:100A7000274973CFF93CF47CE79804E92E7F39E3EA +:100A80004F4653C06013A4B9E53C03DE8F9CF300CE +:100A90009C6FCF3E85F9A336021E6038923E631AE2 +:100AA000109FCF181092BCD0A40CDCC00F9C9734C0 +:100AB00062B6E7F3F3A5CF1842341CC2CAFA8E68B7 +:100AC0005206AF3CA30DBF9E50E1D173CAE03AFC81 +:100AD000C1091A1E6A5C5B8E634E7773CC6167DD59 +:100AE000E66C48D1F31B24695108D4421BF467D14A +:100AF000804E2FD08CD83009C21E801C46013A4748 +:100B0000D031A106013A7F4630211804E95E8429DC +:100B100000C027CDD0007C9804F92E84628C027D21 +:100B2000BA3E7E4C027D2E8C61083009F41D0165B1 +:100B300073009F51D085201804FABD194618C027AC +:100B4000DFD194384C027D174657013009F5FA0180 +:100B50000906013E87A14B88C027DC740D39D300FC +:100B60009F73D030B39804FBBD06C483009F47D069 +:100B70003648CC0271BF3F9A17E63F0821E692A49F +:100B80008F9A1031A7F310B184AF3AACDCF773F24F +:100B90005CC62ADB9E7E7E97310863D0737B43A8B8 +:100BA000E63D34EAF3E315BF9F185F45CFE89F5F4A +:100BB0009A5B03D0F3D3CE371CD00FBB9E68783B33 +:100BC000BCCA31E8F9A20212A27351086FD1F346F0 +:100BD0000138BF40FC23009C21E84951804E91F42C +:100BE000210319804E9FD0216306013A568C02746E +:100BF000FE75495E63D34A54423513A7D1804E95A2 +:100C0000E81E9A4C027CDD1BB9E6013E4BA062A3B4 +:100C1000009F6E8CFCF3009F4BA04218CC027D0716 +:100C200043DA13009F51D03D349804FABD1C628C06 +:100C3000027DFD1C6173009F45D1F44E6013EBF4FF +:100C400025B033009F43D1A79C1804FB8E8403E991 +:100C5000804FB9E843C13009F77A0A319804FA3E67 +:100C6000844041804E82E7418709230423009D058B +:100C7000CE961C248C108C0274173A043849182123 +:100C80001804E82E7450E12460846013A0B9D411D4 +:100C9000C248C108C0274173A82384918211804EA5 +:100CA00082E7528E12460846013A0B9D401C248C66 +:100CB000108C0274173A090E12460846013A0B9836 +:100CC0006A1C24B0E11804E82E6B50E1258708C0A7 +:100CD000274173054384961C23009D05CCAA1C2440 +:100CE000B0E11804E82E70687092C3846013E54484 +:100CF000F9409D05CE5A1C24B0E11804F9D13E708C +:100D000027CF13E5442CA042CB89F2213A0B9C0A51 +:100D10001C24B0E11804F9D10B3810B3C4213936C2 +:100D20005C42C8842B79D061C2741524BAD331E5F2 +:100D300059082908E066634295128100290BC151C8 +:100D400024B81999902290B418A0914101414141D1 +:100D50005283CA4028682908BA16109C990B5694E9 +:100D600090521574C0271A2AD29025D3009D28AB23 +:100D70004A42174C0270D4842E9804E12A42174C40 +:100D8000027082904BA60138514842E9804E15A46A +:100D90002174C0270FA412E9804E82AC80ACA0ACB5 +:100DA000A959E5644565CAC84ACE0ACE4ACE95918E +:100DB000959495932925C0CCCC88A4975636647217 +:100DC00090548A9C4508B9B766129309C9B2748ECB +:100DD000BA6013E5348EBA6013E4748EBA6013E51A +:100DE000691D74C027CA291D74C027CED225D3001F +:100DF0009F38A44BA6013E5E912E9804F915225D02 +:100E00003009F3E912E9804F905225D3009DC5487F +:100E100025D3009C45CECD09C9B21A44BA6013E768 +:100E2000348974C0271C27B79C80C2D776599B93FE +:100E30000C64C31D1BF4454BC7C63A37E8814BC74A +:100E4000C63A37E8914BC7C632618EB3BCC34A225B +:100E5000E6B5249771C987B431AE73A2CF39D25D9C +:100E6000044442C0D6DE710616BBDBCE830C64C3DD +:100E70001D311304F9954D133293635E6614CC292A +:100E80002A5330A6614CC299853A72CCC299850624 +:100E90001BB30A661414249985330A08B186614C81 +:100EA000C2842168733B30A661414EA5985330AC93 +:100EB0005976614CC2B08DD6614CC2B02CF6614CF3 +:100EC000C2B18CA5985330AC0F24CC2998560F286A +:100ED0006615921A1985330ACA850CC2998565C3AD +:100EE000D985330ACE7086614CC2B397710C993B99 +:100EF000CC83580BEA779D064ABE047460E0D14E5D +:100F0000384C3EEE3EEE3EEE3EEE30BBCAE11F7781 +:100F10001F771F771F7727708FBB800E11F771F730 +:100F20007C6F3CB33602FB8DE655707F2D246955EE +:100F30004F58A9231F54F78A95252B750CCCAC5616 +:100F400051CC51E445CEA21239C0A0AF566A497FB8 +:100F5000028C09F80BEBAF56766752B28E69A71177 +:100F600073A8B1BCCAA0A936502C98E70AF566A4AC +:100F700097E25A3027BAF7834EA5330A66158DE6F5 +:100F80005539D2A7AC546016701B728E628F222E18 +:100F9000751602FB8DE60A953D62A300B701B553B5 +:100FA000DE2A5494ADD43332B15947314791173AC0 +:100FB0008848E702B017DC679D4B8DE752AA7BD4C7 +:100FC000AA92BDD699BC5602FB8CF36666C6F36640 +:100FD0006662992AF8186870B08A0D5555555552B1 +:100FE00032E1405C380BEA9B87017DC05F7017DC03 +:100FF00005F5DC9B017D614D80BEA77982A21F5063 +:10100000152A8F8B1CE5A5138458E702915405021D +:101010004BBD221A947F9C1AC05F421A21D180597D +:10102000C06D1C2C0A83555555555555555555556C +:1010300055541CB85C6E179C2F385E70E7B85E7014 +:10104000BCE179C2F385E70BCE179C299C299C292A +:101050009C230F5814EE357726219305C9B017D27B +:101060001D188A219305C9B017D187AC0A740FAE39 +:10107000F55A82A3E43A3114BBD7599974A21930B6 +:101080005C9B017D187AC0A740F843D4638925D0C2 +:1010900010D61C6A10F5558925D151661F51F5915E +:1010A000492E8915986AA3E08A9465640E1317384F +:1010B000A8864C1726C05F461EB028631F087A8C8E +:1010C0007124BA021AD00D421EAAB124BA2A2D31B7 +:1010D000F51F587492E8875A6352DEF451694A3E0C +:1010E00009694650F0E131730545BD598D8B4A7C45 +:1010F000D3ED38E9D34E74ED443260B93602FA5B71 +:10110000DE8A2D29D0E121F5A39221F219305C9BD2 +:10111000017D21F5A0C6016701B445CEA51239D4E1 +:101120001C05F440A1C2C3506AAAAAAAAAAAAAAAE4 +:10113000AAAAAAAAAAAA81AF869F191BE781F3656A +:10114000F280BE7017DFDF380BEB0DC380BEA70F38 +:10115000954F5A94C02CD8B1A7CE5A1173A83AC251 +:10116000CCB63017DC6F35A9804DA7CE2A1879C5CB +:1011700049DE61A822E75033F9986408B99542FC2A +:10118000CCD9953D62A248D448E70288B9C1A0E312 +:101190009D4E62E6CCC66BCE8310C982E4DAC2C82B +:1011A0001EC3B93602FAA9EB4E3030FA0DF0A9EBA6 +:1011B00040B90FAA7AD2C2C8FAA7AD410A47D53DB5 +:1011C00068ACF1F54F5A97547D4FA8AA551F11737B +:1011D0005AB017DE5D59A925D0552A46BCB822AEB3 +:1011E00045293E14FAE19994CA4ABE3DD699925DCA +:1011F0001517C8D7DC15178A401F0A9EACC9654968 +:101200005C1D10684A3E5BDE83169580BE91745863 +:10121000A4007C38E7563017DF75A6649745209DFB +:10122000035F70545E291DF0A9EACC865495C1D1A4 +:1012300006830FAA7BD0654945BDE962D291DF04E0 +:101240005D16291C7D4FAC1A471AA9F5676653280D +:10125000B7BD2C5A523BE3DD59A925D1A8AC086B88 +:10126000EE08ABC5202F854F566675495C1C181DCE +:1012700081C26405F080BE355CD017C255F0957C04 +:10128000255F080BE1017C7BAB3524BA1055931A1E +:10129000FB822AF148D7C2A7AB31B2A4AC639D4A06 +:1012A0008D7C7BAB3524BA1054308D7DC11578AC64 +:1012B0006F5A94601AE379D4AA4F854F5666D54980 +:1012C00058C73A9549F045D1629486BC1D13D29017 +:1012D000FFCF7A83F25031DE006060A11735A85F3E +:1012E0009B1B3707441A300B380DBC1CE0D047CE8F +:1012F000A0AA7AA1986A92953D6831805B80DAA9AC +:10130000EF41952516F7A58B4AC679B333602FAA0E +:101310009EB15180599ECAA7AC0A300B67B2ADD5B9 +:10132000DA925D17A300B32D956E08A958A1173A5C +:101330008B017D54F78E9525081CE05602FBC1D128 +:10134000151805926B3C1D1228C02CA56C11701746 +:10135000B2384D80BEE02FB4EC4AEDB39E02FB8064 +:10136000BEE02FB139933E6DE710609F32A9A26CA9 +:1013700005F440E60A953D6A2300B380DAA7D62A31 +:10138000030D7017D22E76294FBC54A6516F7A5890 +:10139000B4AC05F48BA2F40E350D492EB4CC18A5CF +:1013A000C8F84A9723E1052E47C28A5C8F85697287 +:1013B0003E1F4AC3551F5643328CA35E60A845CEDC +:1013C0000D602FA3849DD8F017D22E0E1B2384D836 +:1013D0000BEB89F380BEE02FBB3985DF2203E701E9 +:1013E0007DC05F7017D11738145BD6A2740D4B7A8D +:1013F000B33196946BCC3523D749481573290F5DCB +:101400008AC05F4D79843580BE881CC3529F59685D +:10141000C02CE036AA7BCD4A92BEF3814A7D5B594F +:1014200094CA1C24EEC780BE881CC3529F5968C052 +:101430002CE036AA7BCD4A92BEF38143849C7B3854 +:101440000BEBAF70D4EA53009B4F9C5430F38A945B +:10145000FAB6B3299422E61A85F9B05993F9D2C4A1 +:101460003260B936B0B390D977261C2722E896B4FB +:1014700023EA9EB511805965862073968D79AD5803 +:101480000BE917448A4A07D77A82A190FAEF0154F0 +:10149000BA50D4591E2CE9F38A99856B0B23159702 +:1014A00072611730D42C738748AA028125DE910D12 +:1014B0004AC05F7ED280A53EB2D0C86B80BE881C79 +:1014C000EA0917441A371A917458A371AF074454A4 +:1014D0006E35E0E8AA640F90FAD06300B380DA2C8E +:1014E000738748AA028125DE910D4AC05F48BA275A +:1014F000A300B701B74F9CB46BCC3516F566632DCE +:10150000291EBA4A40AB99487AEC508B9C0822FCC1 +:10151000F9B2553D62A92351239C0A3C730D445CEA +:10152000E15071CEA11FE7156B0B25ED0B93602FDA +:10153000AA9EAC3665495F7A2050087FEF3914497E +:10154000011181046040CC59C0AD23EB41B081F260 +:101550003A41AA5043E4D48654A087C152CA9301A9 +:1015600032549D2402000052AF1646A7916708B47A +:101570000451F16519B46E2DC0AD490092571B742A +:10158000455F2351B7440A1006A36E8B6B081F19E1 +:10159000D1E680828054042A4591A9E459C22D01E4 +:1015A000140450D3FC558461D980512FE21F465F4B +:1015B00040E020154ABC591A9E459C22D01148CBC8 +:1015C000E81408015415E2C8D4F22CE116808A46CA +:1015D0005F527CD9A8F888D05A3CD25C5B80DAA7ED +:1015E000D65A0886A45D17A0C3522E88A8221F537E +:1015F000EADACCA650E127763C05F54FAB6B329981 +:1016000043849C7B380BE927ACD492E00EDA384D4A +:1016100080BEE67D50BA51AE66EFBCDC7B871E0211 +:10162000FA93E6CD47C443CD0F349DA300B05501D6 +:10163000AE038404CE01D0E17002800E89E9221F3E +:10164000E0E896B011F4C2CE036A442DC06D48059F +:10165000B80DA300B776D5DEB150DC7D77BC54BAA7 +:10166000527F5814340F9AF381580BEAEF581460E4 +:1016700016A56C2EF7814BA56F7D5DEEB52E95807E +:10168000BEF073BD047CEAFEEB4CDE2953DD6A54E8 +:1016900094A9EA0A8C02D64C3C05F400EACD56AF78 +:1016A000C047D29C8D29CAE02FAEBD75999D4AF9DD +:1016B000EF517C940C77801818292AF8E0E8AA30BA +:1016C0000B2A987C1D1151805954C351F51B3324AA +:1016D000BB82A5195C1D1028C02C9AC7C1D1228CD1 +:1016E00002C994645C0CD68E13602FB80BEA30E309 +:1016F000C05F48DC780BE800E3C05F6C38D52E355E +:101700004F5A8A61AA9F561B32994642C8010C451E +:10171000CEA517E6C6CEA9EB151646A24738144348 +:101720002622E73D602FAA9EB512E07F017DE3E708 +:101730000293F995445CE5A0E39D4A7F9C54A9EB94 +:10174000510546B9FCC01B222E64542FCD46CCA7B0 +:10175000D586CCA65055C645CE5A0E39D4A7F9C564 +:101760004A9EB5118059C06DCFE600D9117322A1F0 +:101770007E6A36653EAC366532B017DD3E72D27990 +:10178000310C982E4C20732A8FF38AADE741827C6E +:10179000CAA689B5859FB0F017D51F5454251AA83D +:1017A000FF2A946511D74944D5CCA055D8AE0E88F0 +:1017B0001460164D6322E07286384D80BEE02FB86B +:1017C0000BEE02FB8138F017D7D71E02FAFAE3C0FE +:1017D0005F4C85900218C85B80DA300B701B4C227E +:1017E000D34C33038C2E4C4326D0F56366D095A79B +:1017F000CE45330AD61642386EE4CEBD592CD2AB54 +:10180000BA949DE61AB017D54F5A8B091A88B9C5F4 +:10181000424730D43216728865BD599925A5602F8C +:10182000B860F308B74A1A8FAB0D994651AF38A884 +:101830008E9065135218A054B1422E61A848E72D2E +:1018400016F7A805A5602FA475D251357328157613 +:101850002B83A20518059358C8B806286384D80BB3 +:10186000EE02FB80BEE02FA043A7017D4CE3C05FEA +:101870007017DC05F4642DC06D1805B80DA5BD6AA0 +:101880002386AA9EB511A46AA3EA8A8D23E117389C +:101890003469719845A6986A3EAC36651946BCE233 +:1018A000A23A41944D48628152C516F7A88B4A541A +:1018B000F5A88C02DC06D1039CB4A9EE0A95252A72 +:1018C0007AAD46016701B5D7AC0A300B6C4935E6F5 +:1018D000B567F3006C88B99150BF311B32A7B86867 +:1018E00095257BAD3378A7CD3ED38E9D34E74ED47E +:1018F00022E706848E60A8FF38AB839C2A08F9D4BF +:101900002063BC1A060AC05F4642DC06D1805B80B9 +:10191000DA22E61A848E72D16F5A80871AAA7AD494 +:1019200048C8D547D5152323E11738348CBA4B7BEB +:10193000D402D28C22DC06D51F561B328CA35E71DA +:10194000511D20CA26A43140A962B017DF9EF4B70A +:10195000C940C778018182B83839491C26C05F70F8 +:1019600017D4ABE12AF84ABE12AF8F974FCBA7012D +:101970007DDA80AA91647F4A81D522C8FE828025C3 +:1019800048B23EBBDC352E9407E88A9C03E24BA5A7 +:1019900077ABB332E94BBD598684977A04BA53E1E9 +:1019A00032EF50D4E63553EB029CC7D77AB330D22E +:1019B0005DEA02E9445D1628C02CE0369174455971 +:1019C00018D54FAC0AC435308B38692BBD5998698E +:1019D0002EF512E958674AEF50D58E3E1CA4B0CEC2 +:1019E00093216E1A481FA22AC30D577AB30D092EF0 +:1019F000F4435D288B832092384D80BEE02FAC17D6 +:101A000049B3A582E93EE93674E02FA6CE9C05F4E1 +:101A1000C22C8C52577AD48D48FAEF50D5AE35533C +:101A2000EB028621AAEF56661A4BBD44BA50C4E9B0 +:101A300053EB028681F5DEA1A8621F5DFEA25D293F +:101A400077A86A618D40FD11530C6AA7D60530C78F +:101A5000D77FA9574A5DEB481B0C7C8B9D8A53EFBF +:101A60006694CA54F5A0C6016E036A9F5676653225 +:101A70008B7BD2C5A5602FAA7D65A300B701B4C832 +:101A80005A078FED01D527916701B48B9C541C73C5 +:101A9000A8845CC150BF365660AB8C8B9C541C73C1 +:101AA000A8845CC150BF36566C05F553D6A2300BE6 +:101AB000295B19FCF69445CF150BF33CB32A7AC584 +:101AC0004601648A31239C0A5DEA34332E95C7CEE1 +:101AD0002A4FE65020B9310C9BEF391445CE45070B +:101AE0001CEA4687AB1B3684A75EAC966752B017DC +:101AF000DCFE7B4A22E78A85F99E59977A8D0CCBCA +:101B0000A527F3A0443260B937DE72288B9C8A0E79 +:101B100039D48C05F7E7B82AF92818EF0030305788 +:101B200007440A508FF07391411F3A9045C0BB188B +:101B3000E13602FBFB9E02FAEEE7F5CF017D105C79 +:101B4000F017D105CF017D53EB2D1805B80DA64236 +:101B5000DC06D31735A88B9C0A0E39D40CFE7B4AC1 +:101B600022E6550BF331B3602FBC7CE2A4FE655135 +:101B70001738141C73A819FCF69445CCAA17E66311 +:101B8000660AB8CC85A158F6A23548487F4A89959F +:101B90002121FD0502549E45910E3C05F507405557 +:101BA00048523E86A07548523EB5004A9C006BC71D +:101BB000CE4527F32A843735DEA0AB231AAEF58352 +:101BC0005918D743DE2AD094EBDE053A959FCCC353 +:101BD0002045CCAA17E666CC43264FE741222E705B +:101BE0006838E753E02FABBC12D2E9580BEAA7AD37 +:101BF00045A11FC05F7839C8A08F9D481C24EEC73F +:101C000080BEBAF56D6649770D4EA53009B4F9C5A9 +:101C1000430F38A93F9D02FBCE4511739141C73A4E +:101C2000919FCF69445CF150BF33CB32A7AC549045 +:101C30008D448E702977A8D0CCBA56B0B29D8C86D0 +:101C40004C172677261C271C249E2361BE8E124F1C +:101C500011871CEA5C05F5D7B86A752977AB0D9931 +:101C600074A54F72A0AA4AC6F36666C63982AF75DC +:101C7000A66F146BCE05707396823E7528E13AA765 +:101C8000AD44601652B61D7AB6B324BB86A75298EF +:101C900004DA7CE2A1879C55F79CB5AC2C9533B94E +:101CA0003105D953D6A2300B295B022E615A17E6B3 +:101CB0009CB32A7AC54021A891CE0527F3A5886454 +:101CC000C172654F58140C8D7EF381445CEF41C79F +:101CD0003ABE02FAA9EACECCA92953D6A24647DDDC +:101CE0007AC0A30086E29B29788B810998709B2992 +:101CF000795DD972ED94BCB976133B2A5DB29795A4 +:101D00002ED94BCA7D5B5994CA1C24EEC794BCC023 +:101D100026D3E7150C3CE2ACFE7B4A22E78A85F924 +:101D20009E59977A8D0CCBA527F3A0417262193783 +:101D3000DE70288B9C8A0E39D48D0F56366D094E75 +:101D4000BD592CCEA56B0B22D99DC9B297BEF3818C +:101D50004A7D65A300938F672978C24DC1D1068261 +:101D600031AF07383411F3A82A9EA8661AA4A54FEC +:101D70005A0C118FAA7BD0654945BDE962D2B19E4C +:101D80006CCCC6198709C38E75411F3AA513D5556A +:101D900055555555555555555555555555555555F3 +:101DA00055555555555555555555555555555555E3 +:0E1DB00055555555555555555555555ACC90C8 +:00000001FF diff --git a/trunk/fs/Kconfig.binfmt b/trunk/fs/Kconfig.binfmt index 022574202749..e95d1b64082c 100644 --- a/trunk/fs/Kconfig.binfmt +++ b/trunk/fs/Kconfig.binfmt @@ -33,7 +33,7 @@ config ARCH_BINFMT_ELF_RANDOMIZE_PIE config BINFMT_ELF_FDPIC bool "Kernel support for FDPIC ELF binaries" default y - depends on (FRV || BLACKFIN || (SUPERH32 && !MMU) || C6X) + depends on (FRV || BLACKFIN || (SUPERH32 && !MMU)) help ELF FDPIC binaries are based on ELF, but allow the individual load segments of a binary to be located in memory independently of each diff --git a/trunk/fs/aio.c b/trunk/fs/aio.c index e7f2fad7b4ce..67a6db3e1b6f 100644 --- a/trunk/fs/aio.c +++ b/trunk/fs/aio.c @@ -1456,10 +1456,6 @@ static ssize_t aio_setup_vectored_rw(int type, struct kiocb *kiocb, bool compat) if (ret < 0) goto out; - ret = rw_verify_area(type, kiocb->ki_filp, &kiocb->ki_pos, ret); - if (ret < 0) - goto out; - kiocb->ki_nr_segs = kiocb->ki_nbytes; kiocb->ki_cur_seg = 0; /* ki_nbytes/left now reflect bytes instead of segs */ @@ -1471,17 +1467,11 @@ static ssize_t aio_setup_vectored_rw(int type, struct kiocb *kiocb, bool compat) return ret; } -static ssize_t aio_setup_single_vector(int type, struct file * file, struct kiocb *kiocb) +static ssize_t aio_setup_single_vector(struct kiocb *kiocb) { - int bytes; - - bytes = rw_verify_area(type, file, &kiocb->ki_pos, kiocb->ki_left); - if (bytes < 0) - return bytes; - kiocb->ki_iovec = &kiocb->ki_inline_vec; kiocb->ki_iovec->iov_base = kiocb->ki_buf; - kiocb->ki_iovec->iov_len = bytes; + kiocb->ki_iovec->iov_len = kiocb->ki_left; kiocb->ki_nr_segs = 1; kiocb->ki_cur_seg = 0; return 0; @@ -1506,7 +1496,10 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat) if (unlikely(!access_ok(VERIFY_WRITE, kiocb->ki_buf, kiocb->ki_left))) break; - ret = aio_setup_single_vector(READ, file, kiocb); + ret = security_file_permission(file, MAY_READ); + if (unlikely(ret)) + break; + ret = aio_setup_single_vector(kiocb); if (ret) break; ret = -EINVAL; @@ -1521,7 +1514,10 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat) if (unlikely(!access_ok(VERIFY_READ, kiocb->ki_buf, kiocb->ki_left))) break; - ret = aio_setup_single_vector(WRITE, file, kiocb); + ret = security_file_permission(file, MAY_WRITE); + if (unlikely(ret)) + break; + ret = aio_setup_single_vector(kiocb); if (ret) break; ret = -EINVAL; @@ -1532,6 +1528,9 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat) ret = -EBADF; if (unlikely(!(file->f_mode & FMODE_READ))) break; + ret = security_file_permission(file, MAY_READ); + if (unlikely(ret)) + break; ret = aio_setup_vectored_rw(READ, kiocb, compat); if (ret) break; @@ -1543,6 +1542,9 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat) ret = -EBADF; if (unlikely(!(file->f_mode & FMODE_WRITE))) break; + ret = security_file_permission(file, MAY_WRITE); + if (unlikely(ret)) + break; ret = aio_setup_vectored_rw(WRITE, kiocb, compat); if (ret) break; diff --git a/trunk/fs/bio.c b/trunk/fs/bio.c index 84da88539046..e453924036e9 100644 --- a/trunk/fs/bio.c +++ b/trunk/fs/bio.c @@ -505,14 +505,9 @@ EXPORT_SYMBOL(bio_clone); int bio_get_nr_vecs(struct block_device *bdev) { struct request_queue *q = bdev_get_queue(bdev); - int nr_pages; - - nr_pages = min_t(unsigned, + return min_t(unsigned, queue_max_segments(q), queue_max_sectors(q) / (PAGE_SIZE >> 9) + 1); - - return min_t(unsigned, nr_pages, BIO_MAX_PAGES); - } EXPORT_SYMBOL(bio_get_nr_vecs); diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index ba11c30f302d..e08f6a20a5bb 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -70,7 +70,7 @@ static void bdev_inode_switch_bdi(struct inode *inode, spin_unlock(&dst->wb.list_lock); } -sector_t blkdev_max_block(struct block_device *bdev) +static sector_t max_block(struct block_device *bdev) { sector_t retval = ~((sector_t)0); loff_t sz = i_size_read(bdev->bd_inode); @@ -163,7 +163,7 @@ static int blkdev_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh, int create) { - if (iblock >= blkdev_max_block(I_BDEV(inode))) { + if (iblock >= max_block(I_BDEV(inode))) { if (create) return -EIO; @@ -185,7 +185,7 @@ static int blkdev_get_blocks(struct inode *inode, sector_t iblock, struct buffer_head *bh, int create) { - sector_t end_block = blkdev_max_block(I_BDEV(inode)); + sector_t end_block = max_block(I_BDEV(inode)); unsigned long max_blocks = bh->b_size >> inode->i_blkbits; if ((iblock + max_blocks) > end_block) { diff --git a/trunk/fs/btrfs/ctree.c b/trunk/fs/btrfs/ctree.c index 4106264fbc65..e801f226d7e0 100644 --- a/trunk/fs/btrfs/ctree.c +++ b/trunk/fs/btrfs/ctree.c @@ -220,12 +220,10 @@ struct extent_buffer *btrfs_read_lock_root_node(struct btrfs_root *root) */ static void add_root_to_dirty_list(struct btrfs_root *root) { - spin_lock(&root->fs_info->trans_lock); if (root->track_dirty && list_empty(&root->dirty_list)) { list_add(&root->dirty_list, &root->fs_info->dirty_cowonly_roots); } - spin_unlock(&root->fs_info->trans_lock); } /* @@ -725,7 +723,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, cur = btrfs_find_tree_block(root, blocknr, blocksize); if (cur) - uptodate = btrfs_buffer_uptodate(cur, gen, 0); + uptodate = btrfs_buffer_uptodate(cur, gen); else uptodate = 0; if (!cur || !uptodate) { @@ -1360,12 +1358,7 @@ static noinline int reada_for_balance(struct btrfs_root *root, block1 = btrfs_node_blockptr(parent, slot - 1); gen = btrfs_node_ptr_generation(parent, slot - 1); eb = btrfs_find_tree_block(root, block1, blocksize); - /* - * if we get -eagain from btrfs_buffer_uptodate, we - * don't want to return eagain here. That will loop - * forever - */ - if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0) + if (eb && btrfs_buffer_uptodate(eb, gen)) block1 = 0; free_extent_buffer(eb); } @@ -1373,7 +1366,7 @@ static noinline int reada_for_balance(struct btrfs_root *root, block2 = btrfs_node_blockptr(parent, slot + 1); gen = btrfs_node_ptr_generation(parent, slot + 1); eb = btrfs_find_tree_block(root, block2, blocksize); - if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0) + if (eb && btrfs_buffer_uptodate(eb, gen)) block2 = 0; free_extent_buffer(eb); } @@ -1511,9 +1504,8 @@ read_block_for_search(struct btrfs_trans_handle *trans, tmp = btrfs_find_tree_block(root, blocknr, blocksize); if (tmp) { - /* first we do an atomic uptodate check */ - if (btrfs_buffer_uptodate(tmp, 0, 1) > 0) { - if (btrfs_buffer_uptodate(tmp, gen, 1) > 0) { + if (btrfs_buffer_uptodate(tmp, 0)) { + if (btrfs_buffer_uptodate(tmp, gen)) { /* * we found an up to date block without * sleeping, return @@ -1531,9 +1523,8 @@ read_block_for_search(struct btrfs_trans_handle *trans, free_extent_buffer(tmp); btrfs_set_path_blocking(p); - /* now we're allowed to do a blocking uptodate check */ tmp = read_tree_block(root, blocknr, blocksize, gen); - if (tmp && btrfs_buffer_uptodate(tmp, gen, 0) > 0) { + if (tmp && btrfs_buffer_uptodate(tmp, gen)) { *eb_ret = tmp; return 0; } @@ -1568,7 +1559,7 @@ read_block_for_search(struct btrfs_trans_handle *trans, * and give up so that our caller doesn't loop forever * on our EAGAINs. */ - if (!btrfs_buffer_uptodate(tmp, 0, 0)) + if (!btrfs_buffer_uptodate(tmp, 0)) ret = -EIO; free_extent_buffer(tmp); } @@ -4052,7 +4043,7 @@ int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, tmp = btrfs_find_tree_block(root, blockptr, btrfs_level_size(root, level - 1)); - if (tmp && btrfs_buffer_uptodate(tmp, gen, 1) > 0) { + if (tmp && btrfs_buffer_uptodate(tmp, gen)) { free_extent_buffer(tmp); break; } @@ -4175,8 +4166,7 @@ int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path, struct extent_buffer *cur; cur = btrfs_find_tree_block(root, blockptr, btrfs_level_size(root, level - 1)); - if (!cur || - btrfs_buffer_uptodate(cur, gen, 1) <= 0) { + if (!cur || !btrfs_buffer_uptodate(cur, gen)) { slot++; if (cur) free_extent_buffer(cur); diff --git a/trunk/fs/btrfs/disk-io.c b/trunk/fs/btrfs/disk-io.c index a7ffc88a7dbe..d0c969beaad4 100644 --- a/trunk/fs/btrfs/disk-io.c +++ b/trunk/fs/btrfs/disk-io.c @@ -323,8 +323,7 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf, * in the wrong place. */ static int verify_parent_transid(struct extent_io_tree *io_tree, - struct extent_buffer *eb, u64 parent_transid, - int atomic) + struct extent_buffer *eb, u64 parent_transid) { struct extent_state *cached_state = NULL; int ret; @@ -332,9 +331,6 @@ static int verify_parent_transid(struct extent_io_tree *io_tree, if (!parent_transid || btrfs_header_generation(eb) == parent_transid) return 0; - if (atomic) - return -EAGAIN; - lock_extent_bits(io_tree, eb->start, eb->start + eb->len - 1, 0, &cached_state); if (extent_buffer_uptodate(eb) && @@ -376,8 +372,7 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root, ret = read_extent_buffer_pages(io_tree, eb, start, WAIT_COMPLETE, btree_get_extent, mirror_num); - if (!ret && !verify_parent_transid(io_tree, eb, - parent_transid, 0)) + if (!ret && !verify_parent_transid(io_tree, eb, parent_transid)) break; /* @@ -1207,7 +1202,7 @@ static int __must_check find_and_setup_root(struct btrfs_root *tree_root, root->commit_root = NULL; root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), blocksize, generation); - if (!root->node || !btrfs_buffer_uptodate(root->node, generation, 0)) { + if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) { free_extent_buffer(root->node); root->node = NULL; return -EIO; @@ -3148,8 +3143,7 @@ int close_ctree(struct btrfs_root *root) return 0; } -int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid, - int atomic) +int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid) { int ret; struct inode *btree_inode = buf->pages[0]->mapping->host; @@ -3159,9 +3153,7 @@ int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid, return ret; ret = verify_parent_transid(&BTRFS_I(btree_inode)->io_tree, buf, - parent_transid, atomic); - if (ret == -EAGAIN) - return ret; + parent_transid); return !ret; } diff --git a/trunk/fs/btrfs/disk-io.h b/trunk/fs/btrfs/disk-io.h index ab1830aaf0ed..a7ace1a2dd12 100644 --- a/trunk/fs/btrfs/disk-io.h +++ b/trunk/fs/btrfs/disk-io.h @@ -66,8 +66,7 @@ void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr); void __btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr); void btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root); void btrfs_mark_buffer_dirty(struct extent_buffer *buf); -int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid, - int atomic); +int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid); int btrfs_set_buffer_uptodate(struct extent_buffer *buf); int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid); u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len); diff --git a/trunk/fs/btrfs/extent-tree.c b/trunk/fs/btrfs/extent-tree.c index 49fd7b66d57b..6fc2e6f5aab8 100644 --- a/trunk/fs/btrfs/extent-tree.c +++ b/trunk/fs/btrfs/extent-tree.c @@ -6568,7 +6568,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, goto skip; } - if (!btrfs_buffer_uptodate(next, generation, 0)) { + if (!btrfs_buffer_uptodate(next, generation)) { btrfs_tree_unlock(next); free_extent_buffer(next); next = NULL; diff --git a/trunk/fs/btrfs/extent_io.c b/trunk/fs/btrfs/extent_io.c index c9018a05036e..198c2ba2fa40 100644 --- a/trunk/fs/btrfs/extent_io.c +++ b/trunk/fs/btrfs/extent_io.c @@ -4120,7 +4120,6 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, if (atomic_inc_not_zero(&exists->refs)) { spin_unlock(&mapping->private_lock); unlock_page(p); - page_cache_release(p); mark_extent_buffer_accessed(exists); goto free_eb; } @@ -4200,7 +4199,8 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, unlock_page(eb->pages[i]); } - WARN_ON(!atomic_dec_and_test(&eb->refs)); + if (!atomic_dec_and_test(&eb->refs)) + return exists; btrfs_release_extent_buffer(eb); return exists; } diff --git a/trunk/fs/btrfs/ioctl.h b/trunk/fs/btrfs/ioctl.h index 086e6bdae1c4..4f69028a68c4 100644 --- a/trunk/fs/btrfs/ioctl.h +++ b/trunk/fs/btrfs/ioctl.h @@ -252,7 +252,7 @@ struct btrfs_data_container { struct btrfs_ioctl_ino_path_args { __u64 inum; /* in */ - __u64 size; /* in */ + __u32 size; /* in */ __u64 reserved[4]; /* struct btrfs_data_container *fspath; out */ __u64 fspath; /* out */ @@ -260,7 +260,7 @@ struct btrfs_ioctl_ino_path_args { struct btrfs_ioctl_logical_ino_args { __u64 logical; /* in */ - __u64 size; /* in */ + __u32 size; /* in */ __u64 reserved[4]; /* struct btrfs_data_container *inodes; out */ __u64 inodes; diff --git a/trunk/fs/btrfs/scrub.c b/trunk/fs/btrfs/scrub.c index 2f3d6f917fb3..4f76fc3f8e89 100644 --- a/trunk/fs/btrfs/scrub.c +++ b/trunk/fs/btrfs/scrub.c @@ -998,7 +998,6 @@ static int scrub_setup_recheck_block(struct scrub_dev *sdev, page = sblock->pagev + page_index; page->logical = logical; page->physical = bbio->stripes[mirror_index].physical; - /* for missing devices, bdev is NULL */ page->bdev = bbio->stripes[mirror_index].dev->bdev; page->mirror_num = mirror_index + 1; page->page = alloc_page(GFP_NOFS); @@ -1043,12 +1042,6 @@ static int scrub_recheck_block(struct btrfs_fs_info *fs_info, struct scrub_page *page = sblock->pagev + page_num; DECLARE_COMPLETION_ONSTACK(complete); - if (page->bdev == NULL) { - page->io_error = 1; - sblock->no_io_error_seen = 0; - continue; - } - BUG_ON(!page->page); bio = bio_alloc(GFP_NOFS, 1); if (!bio) diff --git a/trunk/fs/btrfs/tree-log.c b/trunk/fs/btrfs/tree-log.c index eb1ae908582c..d017283ae6f5 100644 --- a/trunk/fs/btrfs/tree-log.c +++ b/trunk/fs/btrfs/tree-log.c @@ -279,7 +279,7 @@ static int process_one_buffer(struct btrfs_root *log, log->fs_info->extent_root, eb->start, eb->len); - if (btrfs_buffer_uptodate(eb, gen, 0)) { + if (btrfs_buffer_uptodate(eb, gen)) { if (wc->write) btrfs_write_tree_block(eb); if (wc->wait) diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c index ad5938ca357c..351e18ea2e53 100644 --- a/trunk/fs/buffer.c +++ b/trunk/fs/buffer.c @@ -921,7 +921,6 @@ init_page_buffers(struct page *page, struct block_device *bdev, struct buffer_head *head = page_buffers(page); struct buffer_head *bh = head; int uptodate = PageUptodate(page); - sector_t end_block = blkdev_max_block(I_BDEV(bdev->bd_inode)); do { if (!buffer_mapped(bh)) { @@ -930,8 +929,7 @@ init_page_buffers(struct page *page, struct block_device *bdev, bh->b_blocknr = block; if (uptodate) set_buffer_uptodate(bh); - if (block < end_block) - set_buffer_mapped(bh); + set_buffer_mapped(bh); } block++; bh = bh->b_this_page; diff --git a/trunk/fs/cifs/cifsfs.c b/trunk/fs/cifs/cifsfs.c index 541ef81f6ae8..811245b1ff2e 100644 --- a/trunk/fs/cifs/cifsfs.c +++ b/trunk/fs/cifs/cifsfs.c @@ -442,7 +442,7 @@ cifs_show_options(struct seq_file *s, struct dentry *root) seq_printf(s, ",rsize=%u", cifs_sb->rsize); seq_printf(s, ",wsize=%u", cifs_sb->wsize); /* convert actimeo and display it in seconds */ - seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); + seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); return 0; } @@ -699,7 +699,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin) * origin == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate * the cached file length */ - if (origin != SEEK_SET && origin != SEEK_CUR) { + if (origin != SEEK_SET || origin != SEEK_CUR) { int rc; struct inode *inode = file->f_path.dentry->d_inode; diff --git a/trunk/fs/cifs/cifsfs.h b/trunk/fs/cifs/cifsfs.h index 65365358c976..d1389bb33ceb 100644 --- a/trunk/fs/cifs/cifsfs.h +++ b/trunk/fs/cifs/cifsfs.h @@ -125,5 +125,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); extern const struct export_operations cifs_export_ops; #endif /* CONFIG_CIFS_NFSD_EXPORT */ -#define CIFS_VERSION "1.78" +#define CIFS_VERSION "1.77" #endif /* _CIFSFS_H */ diff --git a/trunk/fs/cifs/cifssmb.c b/trunk/fs/cifs/cifssmb.c index da2f5446fa7a..f52c5ab78f9d 100644 --- a/trunk/fs/cifs/cifssmb.c +++ b/trunk/fs/cifs/cifssmb.c @@ -4844,12 +4844,8 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr, max_len = data_end - temp; node->node_name = cifs_strndup_from_utf16(temp, max_len, is_unicode, nls_codepage); - if (!node->node_name) { + if (!node->node_name) rc = -ENOMEM; - goto parse_DFS_referrals_exit; - } - - ref++; } parse_DFS_referrals_exit: diff --git a/trunk/fs/cifs/connect.c b/trunk/fs/cifs/connect.c index e0b56d7a19c5..f4d381e331ce 100644 --- a/trunk/fs/cifs/connect.c +++ b/trunk/fs/cifs/connect.c @@ -164,8 +164,7 @@ static const match_table_t cifs_mount_option_tokens = { { Opt_sign, "sign" }, { Opt_seal, "seal" }, { Opt_direct, "direct" }, - { Opt_direct, "directio" }, - { Opt_direct, "forcedirectio" }, + { Opt_direct, "forceddirectio" }, { Opt_strictcache, "strictcache" }, { Opt_noac, "noac" }, { Opt_fsc, "fsc" }, @@ -216,8 +215,6 @@ static const match_table_t cifs_mount_option_tokens = { { Opt_ignore, "cred" }, { Opt_ignore, "credentials" }, - { Opt_ignore, "cred=%s" }, - { Opt_ignore, "credentials=%s" }, { Opt_ignore, "guest" }, { Opt_ignore, "rw" }, { Opt_ignore, "ro" }, @@ -2186,7 +2183,6 @@ cifs_get_tcp_session(struct smb_vol *volume_info) tcp_ses->session_estab = false; tcp_ses->sequence_number = 0; tcp_ses->lstrp = jiffies; - spin_lock_init(&tcp_ses->req_lock); INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); INIT_LIST_HEAD(&tcp_ses->smb_ses_list); INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request); @@ -3618,6 +3614,22 @@ cifs_get_volume_info(char *mount_data, const char *devname) return volume_info; } +/* make sure ra_pages is a multiple of rsize */ +static inline unsigned int +cifs_ra_pages(struct cifs_sb_info *cifs_sb) +{ + unsigned int reads; + unsigned int rsize_pages = cifs_sb->rsize / PAGE_CACHE_SIZE; + + if (rsize_pages >= default_backing_dev_info.ra_pages) + return default_backing_dev_info.ra_pages; + else if (rsize_pages == 0) + return rsize_pages; + + reads = default_backing_dev_info.ra_pages / rsize_pages; + return reads * rsize_pages; +} + int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) { @@ -3705,7 +3717,7 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) cifs_sb->rsize = cifs_negotiate_rsize(tcon, volume_info); /* tune readahead according to rsize */ - cifs_sb->bdi.ra_pages = cifs_sb->rsize / PAGE_CACHE_SIZE; + cifs_sb->bdi.ra_pages = cifs_ra_pages(cifs_sb); remote_path_check: #ifdef CONFIG_CIFS_DFS_UPCALL diff --git a/trunk/fs/cifs/dir.c b/trunk/fs/cifs/dir.c index ec4e9a2a12f8..d172c8ed9017 100644 --- a/trunk/fs/cifs/dir.c +++ b/trunk/fs/cifs/dir.c @@ -668,19 +668,12 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) return 0; else { /* - * If the inode wasn't known to be a dfs entry when - * the dentry was instantiated, such as when created - * via ->readdir(), it needs to be set now since the - * attributes will have been updated by - * cifs_revalidate_dentry(). + * Forcibly invalidate automounting directory inodes + * (remote DFS directories) so to have them + * instantiated again for automount */ - if (IS_AUTOMOUNT(direntry->d_inode) && - !(direntry->d_flags & DCACHE_NEED_AUTOMOUNT)) { - spin_lock(&direntry->d_lock); - direntry->d_flags |= DCACHE_NEED_AUTOMOUNT; - spin_unlock(&direntry->d_lock); - } - + if (IS_AUTOMOUNT(direntry->d_inode)) + return 0; return 1; } } diff --git a/trunk/fs/dcache.c b/trunk/fs/dcache.c index 8c1ab8fb5012..b60ddc41d783 100644 --- a/trunk/fs/dcache.c +++ b/trunk/fs/dcache.c @@ -141,25 +141,18 @@ int proc_nr_dentry(ctl_table *table, int write, void __user *buffer, * Compare 2 name strings, return 0 if they match, otherwise non-zero. * The strings are both count bytes long, and count is non-zero. */ -#ifdef CONFIG_DCACHE_WORD_ACCESS - -#include -/* - * NOTE! 'cs' and 'scount' come from a dentry, so it has a - * aligned allocation for this particular component. We don't - * strictly need the load_unaligned_zeropad() safety, but it - * doesn't hurt either. - * - * In contrast, 'ct' and 'tcount' can be from a pathname, and do - * need the careful unaligned handling. - */ -static inline int dentry_string_cmp(const unsigned char *cs, const unsigned char *ct, unsigned tcount) +static inline int dentry_cmp(const unsigned char *cs, size_t scount, + const unsigned char *ct, size_t tcount) { +#ifdef CONFIG_DCACHE_WORD_ACCESS unsigned long a,b,mask; + if (unlikely(scount != tcount)) + return 1; + for (;;) { a = *(unsigned long *)cs; - b = load_unaligned_zeropad(ct); + b = *(unsigned long *)ct; if (tcount < sizeof(unsigned long)) break; if (unlikely(a != b)) @@ -172,12 +165,10 @@ static inline int dentry_string_cmp(const unsigned char *cs, const unsigned char } mask = ~(~0ul << tcount*8); return unlikely(!!((a ^ b) & mask)); -} - #else + if (scount != tcount) + return 1; -static inline int dentry_string_cmp(const unsigned char *cs, const unsigned char *ct, unsigned tcount) -{ do { if (*cs != *ct) return 1; @@ -186,32 +177,7 @@ static inline int dentry_string_cmp(const unsigned char *cs, const unsigned char tcount--; } while (tcount); return 0; -} - #endif - -static inline int dentry_cmp(const struct dentry *dentry, const unsigned char *ct, unsigned tcount) -{ - const unsigned char *cs; - /* - * Be careful about RCU walk racing with rename: - * use ACCESS_ONCE to fetch the name pointer. - * - * NOTE! Even if a rename will mean that the length - * was not loaded atomically, we don't care. The - * RCU walk will check the sequence count eventually, - * and catch it. And we won't overrun the buffer, - * because we're reading the name pointer atomically, - * and a dentry name is guaranteed to be properly - * terminated with a NUL byte. - * - * End result: even if 'len' is wrong, we'll exit - * early because the data cannot match (there can - * be no NUL in the ct/tcount data) - */ - cs = ACCESS_ONCE(dentry->d_name.name); - smp_read_barrier_depends(); - return dentry_string_cmp(cs, ct, tcount); } static void __d_free(struct rcu_head *head) @@ -1274,13 +1240,6 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) if (!dentry) return NULL; - /* - * We guarantee that the inline name is always NUL-terminated. - * This way the memcpy() done by the name switching in rename - * will still always have a NUL at the end, even if we might - * be overwriting an internal NUL character - */ - dentry->d_iname[DNAME_INLINE_LEN-1] = 0; if (name->len > DNAME_INLINE_LEN-1) { dname = kmalloc(name->len + 1, GFP_KERNEL); if (!dname) { @@ -1290,16 +1249,13 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) } else { dname = dentry->d_iname; } + dentry->d_name.name = dname; dentry->d_name.len = name->len; dentry->d_name.hash = name->hash; memcpy(dname, name->name, name->len); dname[name->len] = 0; - /* Make sure we always see the terminating NUL character */ - smp_wmb(); - dentry->d_name.name = dname; - dentry->d_count = 1; dentry->d_flags = 0; spin_lock_init(&dentry->d_lock); @@ -1465,18 +1421,18 @@ static struct dentry *__d_instantiate_unique(struct dentry *entry, } list_for_each_entry(alias, &inode->i_dentry, d_alias) { + struct qstr *qstr = &alias->d_name; + /* * Don't need alias->d_lock here, because aliases with * d_parent == entry->d_parent are not subject to name or * parent changes, because the parent inode i_mutex is held. */ - if (alias->d_name.hash != hash) + if (qstr->hash != hash) continue; if (alias->d_parent != entry->d_parent) continue; - if (alias->d_name.len != len) - continue; - if (dentry_cmp(alias, name, len)) + if (dentry_cmp(qstr->name, qstr->len, name, len)) continue; __dget(alias); return alias; @@ -1515,7 +1471,7 @@ struct dentry *d_make_root(struct inode *root_inode) struct dentry *res = NULL; if (root_inode) { - static const struct qstr name = QSTR_INIT("/", 1); + static const struct qstr name = { .name = "/", .len = 1 }; res = __d_alloc(root_inode->i_sb, &name); if (res) @@ -1753,48 +1709,6 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode, } EXPORT_SYMBOL(d_add_ci); -/* - * Do the slow-case of the dentry name compare. - * - * Unlike the dentry_cmp() function, we need to atomically - * load the name, length and inode information, so that the - * filesystem can rely on them, and can use the 'name' and - * 'len' information without worrying about walking off the - * end of memory etc. - * - * Thus the read_seqcount_retry() and the "duplicate" info - * in arguments (the low-level filesystem should not look - * at the dentry inode or name contents directly, since - * rename can change them while we're in RCU mode). - */ -enum slow_d_compare { - D_COMP_OK, - D_COMP_NOMATCH, - D_COMP_SEQRETRY, -}; - -static noinline enum slow_d_compare slow_dentry_cmp( - const struct dentry *parent, - struct inode *inode, - struct dentry *dentry, - unsigned int seq, - const struct qstr *name) -{ - int tlen = dentry->d_name.len; - const char *tname = dentry->d_name.name; - struct inode *i = dentry->d_inode; - - if (read_seqcount_retry(&dentry->d_seq, seq)) { - cpu_relax(); - return D_COMP_SEQRETRY; - } - if (parent->d_op->d_compare(parent, inode, - dentry, i, - tlen, tname, name)) - return D_COMP_NOMATCH; - return D_COMP_OK; -} - /** * __d_lookup_rcu - search for a dentry (racy, store-free) * @parent: parent dentry @@ -1821,17 +1735,15 @@ static noinline enum slow_d_compare slow_dentry_cmp( * the returned dentry, so long as its parent's seqlock is checked after the * child is looked up. Thus, an interlocking stepping of sequence lock checks * is formed, giving integrity down the path walk. - * - * NOTE! The caller *has* to check the resulting dentry against the sequence - * number we've returned before using any of the resulting dentry state! */ struct dentry *__d_lookup_rcu(const struct dentry *parent, const struct qstr *name, - unsigned *seqp, struct inode *inode) + unsigned *seqp, struct inode **inode) { - u64 hashlen = name->hash_len; + unsigned int len = name->len; + unsigned int hash = name->hash; const unsigned char *str = name->name; - struct hlist_bl_head *b = d_hash(parent, hashlen_hash(hashlen)); + struct hlist_bl_head *b = d_hash(parent, hash); struct hlist_bl_node *node; struct dentry *dentry; @@ -1857,47 +1769,49 @@ struct dentry *__d_lookup_rcu(const struct dentry *parent, */ hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) { unsigned seq; + struct inode *i; + const char *tname; + int tlen; + + if (dentry->d_name.hash != hash) + continue; seqretry: - /* - * The dentry sequence count protects us from concurrent - * renames, and thus protects inode, parent and name fields. - * - * The caller must perform a seqcount check in order - * to do anything useful with the returned dentry, - * including using the 'd_inode' pointer. - * - * NOTE! We do a "raw" seqcount_begin here. That means that - * we don't wait for the sequence count to stabilize if it - * is in the middle of a sequence change. If we do the slow - * dentry compare, we will do seqretries until it is stable, - * and if we end up with a successful lookup, we actually - * want to exit RCU lookup anyway. - */ - seq = raw_seqcount_begin(&dentry->d_seq); + seq = read_seqcount_begin(&dentry->d_seq); if (dentry->d_parent != parent) continue; if (d_unhashed(dentry)) continue; - *seqp = seq; - + tlen = dentry->d_name.len; + tname = dentry->d_name.name; + i = dentry->d_inode; + prefetch(tname); + /* + * This seqcount check is required to ensure name and + * len are loaded atomically, so as not to walk off the + * edge of memory when walking. If we could load this + * atomically some other way, we could drop this check. + */ + if (read_seqcount_retry(&dentry->d_seq, seq)) + goto seqretry; if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) { - if (dentry->d_name.hash != hashlen_hash(hashlen)) + if (parent->d_op->d_compare(parent, *inode, + dentry, i, + tlen, tname, name)) continue; - switch (slow_dentry_cmp(parent, inode, dentry, seq, name)) { - case D_COMP_OK: - return dentry; - case D_COMP_NOMATCH: + } else { + if (dentry_cmp(tname, tlen, str, len)) continue; - default: - goto seqretry; - } } - - if (dentry->d_name.hash_len != hashlen) - continue; - if (!dentry_cmp(dentry, str, hashlen_len(hashlen))) - return dentry; + /* + * No extra seqcount check is required after the name + * compare. The caller must perform a seqcount check in + * order to do anything useful with the returned dentry + * anyway. + */ + *seqp = seq; + *inode = i; + return dentry; } return NULL; } @@ -1976,6 +1890,8 @@ struct dentry *__d_lookup(struct dentry *parent, struct qstr *name) rcu_read_lock(); hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) { + const char *tname; + int tlen; if (dentry->d_name.hash != hash) continue; @@ -1990,17 +1906,15 @@ struct dentry *__d_lookup(struct dentry *parent, struct qstr *name) * It is safe to compare names since d_move() cannot * change the qstr (protected by d_lock). */ + tlen = dentry->d_name.len; + tname = dentry->d_name.name; if (parent->d_flags & DCACHE_OP_COMPARE) { - int tlen = dentry->d_name.len; - const char *tname = dentry->d_name.name; if (parent->d_op->d_compare(parent, parent->d_inode, dentry, dentry->d_inode, tlen, tname, name)) goto next; } else { - if (dentry->d_name.len != len) - goto next; - if (dentry_cmp(dentry, str, len)) + if (dentry_cmp(tname, tlen, str, len)) goto next; } diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index d038968b54b4..b1fd2025e59a 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -1245,13 +1245,6 @@ static int check_unsafe_exec(struct linux_binprm *bprm) bprm->unsafe |= LSM_UNSAFE_PTRACE; } - /* - * This isn't strictly necessary, but it makes it harder for LSMs to - * mess up. - */ - if (current->no_new_privs) - bprm->unsafe |= LSM_UNSAFE_NO_NEW_PRIVS; - n_fs = 1; spin_lock(&p->fs->lock); rcu_read_lock(); @@ -1295,8 +1288,7 @@ int prepare_binprm(struct linux_binprm *bprm) bprm->cred->euid = current_euid(); bprm->cred->egid = current_egid(); - if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) && - !current->no_new_privs) { + if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)) { /* Set-uid? */ if (mode & S_ISUID) { bprm->per_clear |= PER_CLEAR_ON_SETID; diff --git a/trunk/fs/ext2/namei.c b/trunk/fs/ext2/namei.c index f663a67d7bf0..dffb86536285 100644 --- a/trunk/fs/ext2/namei.c +++ b/trunk/fs/ext2/namei.c @@ -79,7 +79,7 @@ static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, str struct dentry *ext2_get_parent(struct dentry *child) { - struct qstr dotdot = QSTR_INIT("..", 2); + struct qstr dotdot = {.name = "..", .len = 2}; unsigned long ino = ext2_inode_by_name(child->d_inode, &dotdot); if (!ino) return ERR_PTR(-ENOENT); diff --git a/trunk/fs/ext3/namei.c b/trunk/fs/ext3/namei.c index eeb63dfc5d20..d7940b24cf68 100644 --- a/trunk/fs/ext3/namei.c +++ b/trunk/fs/ext3/namei.c @@ -1045,7 +1045,7 @@ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, str struct dentry *ext3_get_parent(struct dentry *child) { unsigned long ino; - struct qstr dotdot = QSTR_INIT("..", 2); + struct qstr dotdot = {.name = "..", .len = 2}; struct ext3_dir_entry_2 * de; struct buffer_head *bh; diff --git a/trunk/fs/ext4/namei.c b/trunk/fs/ext4/namei.c index e2a3f4b0ff78..349d7b3671c8 100644 --- a/trunk/fs/ext4/namei.c +++ b/trunk/fs/ext4/namei.c @@ -1052,7 +1052,10 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, stru struct dentry *ext4_get_parent(struct dentry *child) { __u32 ino; - static const struct qstr dotdot = QSTR_INIT("..", 2); + static const struct qstr dotdot = { + .name = "..", + .len = 2, + }; struct ext4_dir_entry_2 * de; struct buffer_head *bh; diff --git a/trunk/fs/gfs2/acl.c b/trunk/fs/gfs2/acl.c index bd4a5892c93c..230eb0f005b6 100644 --- a/trunk/fs/gfs2/acl.c +++ b/trunk/fs/gfs2/acl.c @@ -73,8 +73,12 @@ static int gfs2_set_mode(struct inode *inode, umode_t mode) int error = 0; if (mode != inode->i_mode) { - inode->i_mode = mode; - mark_inode_dirty(inode); + struct iattr iattr; + + iattr.ia_valid = ATTR_MODE; + iattr.ia_mode = mode; + + error = gfs2_setattr_simple(inode, &iattr); } return error; @@ -122,7 +126,9 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode) return PTR_ERR(acl); if (!acl) { mode &= ~current_umask(); - return gfs2_set_mode(inode, mode); + if (mode != inode->i_mode) + error = gfs2_set_mode(inode, mode); + return error; } if (S_ISDIR(inode->i_mode)) { diff --git a/trunk/fs/gfs2/aops.c b/trunk/fs/gfs2/aops.c index e80a464850c8..9b2ff0e851b1 100644 --- a/trunk/fs/gfs2/aops.c +++ b/trunk/fs/gfs2/aops.c @@ -36,8 +36,8 @@ #include "glops.h" -static void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page, - unsigned int from, unsigned int to) +void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page, + unsigned int from, unsigned int to) { struct buffer_head *head = page_buffers(page); unsigned int bsize = head->b_size; @@ -517,14 +517,15 @@ static int gfs2_readpage(struct file *file, struct page *page) /** * gfs2_internal_read - read an internal file * @ip: The gfs2 inode + * @ra_state: The readahead state (or NULL for no readahead) * @buf: The buffer to fill * @pos: The file position * @size: The amount to read * */ -int gfs2_internal_read(struct gfs2_inode *ip, char *buf, loff_t *pos, - unsigned size) +int gfs2_internal_read(struct gfs2_inode *ip, struct file_ra_state *ra_state, + char *buf, loff_t *pos, unsigned size) { struct address_space *mapping = ip->i_inode.i_mapping; unsigned long index = *pos / PAGE_CACHE_SIZE; @@ -942,8 +943,8 @@ static void gfs2_discard(struct gfs2_sbd *sdp, struct buffer_head *bh) clear_buffer_dirty(bh); bd = bh->b_private; if (bd) { - if (!list_empty(&bd->bd_list) && !buffer_pinned(bh)) - list_del_init(&bd->bd_list); + if (!list_empty(&bd->bd_le.le_list) && !buffer_pinned(bh)) + list_del_init(&bd->bd_le.le_list); else gfs2_remove_from_journal(bh, current->journal_info, 0); } @@ -1083,9 +1084,10 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask) bd = bh->b_private; if (bd) { gfs2_assert_warn(sdp, bd->bd_bh == bh); - if (!list_empty(&bd->bd_list)) { + gfs2_assert_warn(sdp, list_empty(&bd->bd_list_tr)); + if (!list_empty(&bd->bd_le.le_list)) { if (!buffer_pinned(bh)) - list_del_init(&bd->bd_list); + list_del_init(&bd->bd_le.le_list); else bd = NULL; } diff --git a/trunk/fs/gfs2/bmap.c b/trunk/fs/gfs2/bmap.c index dab54099dd98..03c04febe26f 100644 --- a/trunk/fs/gfs2/bmap.c +++ b/trunk/fs/gfs2/bmap.c @@ -324,7 +324,7 @@ static int lookup_metapath(struct gfs2_inode *ip, struct metapath *mp) if (!dblock) return x + 1; - ret = gfs2_meta_indirect_buffer(ip, x+1, dblock, &mp->mp_bh[x+1]); + ret = gfs2_meta_indirect_buffer(ip, x+1, dblock, 0, &mp->mp_bh[x+1]); if (ret) return ret; } @@ -882,7 +882,7 @@ static int recursive_scan(struct gfs2_inode *ip, struct buffer_head *dibh, top = (__be64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + mp->mp_list[0]; bottom = (__be64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + sdp->sd_diptrs; } else { - error = gfs2_meta_indirect_buffer(ip, height, block, &bh); + error = gfs2_meta_indirect_buffer(ip, height, block, 0, &bh); if (error) return error; @@ -1169,7 +1169,6 @@ static int do_grow(struct inode *inode, u64 size) struct buffer_head *dibh; struct gfs2_qadata *qa = NULL; int error; - int unstuff = 0; if (gfs2_is_stuffed(ip) && (size > (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)))) { @@ -1184,14 +1183,13 @@ static int do_grow(struct inode *inode, u64 size) error = gfs2_inplace_reserve(ip, 1); if (error) goto do_grow_qunlock; - unstuff = 1; } error = gfs2_trans_begin(sdp, RES_DINODE + RES_STATFS + RES_RG_BIT, 0); if (error) goto do_grow_release; - if (unstuff) { + if (qa) { error = gfs2_unstuff_dinode(ip, NULL); if (error) goto do_end_trans; @@ -1210,7 +1208,7 @@ static int do_grow(struct inode *inode, u64 size) do_end_trans: gfs2_trans_end(sdp); do_grow_release: - if (unstuff) { + if (qa) { gfs2_inplace_release(ip); do_grow_qunlock: gfs2_quota_unlock(ip); diff --git a/trunk/fs/gfs2/dir.c b/trunk/fs/gfs2/dir.c index 8aaeb07a07b5..a836056343f0 100644 --- a/trunk/fs/gfs2/dir.c +++ b/trunk/fs/gfs2/dir.c @@ -821,7 +821,7 @@ static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh, struct buffer_head *bh; struct gfs2_leaf *leaf; struct gfs2_dirent *dent; - struct qstr name = { .name = "" }; + struct qstr name = { .name = "", .len = 0, .hash = 0 }; error = gfs2_alloc_blocks(ip, &bn, &n, 0, NULL); if (error) diff --git a/trunk/fs/gfs2/file.c b/trunk/fs/gfs2/file.c index 31b199f6efc1..a3d2c9ee8d66 100644 --- a/trunk/fs/gfs2/file.c +++ b/trunk/fs/gfs2/file.c @@ -558,14 +558,14 @@ static int gfs2_open(struct inode *inode, struct file *file) } /** - * gfs2_release - called to close a struct file + * gfs2_close - called to close a struct file * @inode: the inode the struct file belongs to * @file: the struct file being closed * * Returns: errno */ -static int gfs2_release(struct inode *inode, struct file *file) +static int gfs2_close(struct inode *inode, struct file *file) { struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; struct gfs2_file *fp; @@ -1005,7 +1005,7 @@ const struct file_operations gfs2_file_fops = { .unlocked_ioctl = gfs2_ioctl, .mmap = gfs2_mmap, .open = gfs2_open, - .release = gfs2_release, + .release = gfs2_close, .fsync = gfs2_fsync, .lock = gfs2_lock, .flock = gfs2_flock, @@ -1019,7 +1019,7 @@ const struct file_operations gfs2_dir_fops = { .readdir = gfs2_readdir, .unlocked_ioctl = gfs2_ioctl, .open = gfs2_open, - .release = gfs2_release, + .release = gfs2_close, .fsync = gfs2_fsync, .lock = gfs2_lock, .flock = gfs2_flock, @@ -1037,7 +1037,7 @@ const struct file_operations gfs2_file_fops_nolock = { .unlocked_ioctl = gfs2_ioctl, .mmap = gfs2_mmap, .open = gfs2_open, - .release = gfs2_release, + .release = gfs2_close, .fsync = gfs2_fsync, .splice_read = generic_file_splice_read, .splice_write = generic_file_splice_write, @@ -1049,7 +1049,7 @@ const struct file_operations gfs2_dir_fops_nolock = { .readdir = gfs2_readdir, .unlocked_ioctl = gfs2_ioctl, .open = gfs2_open, - .release = gfs2_release, + .release = gfs2_close, .fsync = gfs2_fsync, .llseek = default_llseek, }; diff --git a/trunk/fs/gfs2/glops.c b/trunk/fs/gfs2/glops.c index 4bdcf3784187..1656df7aacd2 100644 --- a/trunk/fs/gfs2/glops.c +++ b/trunk/fs/gfs2/glops.c @@ -94,6 +94,7 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl) /* A shortened, inline version of gfs2_trans_begin() */ tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64)); tr.tr_ip = (unsigned long)__builtin_return_address(0); + INIT_LIST_HEAD(&tr.tr_list_buf); gfs2_log_reserve(sdp, tr.tr_reserved); BUG_ON(current->journal_info); current->journal_info = &tr; @@ -378,6 +379,11 @@ int gfs2_inode_refresh(struct gfs2_inode *ip) if (error) return error; + if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), dibh, GFS2_METATYPE_DI)) { + brelse(dibh); + return -EIO; + } + error = gfs2_dinode_in(ip, dibh->b_data); brelse(dibh); clear_bit(GIF_INVALID, &ip->i_flags); diff --git a/trunk/fs/gfs2/incore.h b/trunk/fs/gfs2/incore.h index aa9949e5de26..47d0bda5ac2b 100644 --- a/trunk/fs/gfs2/incore.h +++ b/trunk/fs/gfs2/incore.h @@ -26,7 +26,7 @@ #define DIO_METADATA 0x00000020 struct gfs2_log_operations; -struct gfs2_bufdata; +struct gfs2_log_element; struct gfs2_holder; struct gfs2_glock; struct gfs2_quota_data; @@ -52,7 +52,7 @@ struct gfs2_log_header_host { */ struct gfs2_log_operations { - void (*lo_add) (struct gfs2_sbd *sdp, struct gfs2_bufdata *bd); + void (*lo_add) (struct gfs2_sbd *sdp, struct gfs2_log_element *le); void (*lo_before_commit) (struct gfs2_sbd *sdp); void (*lo_after_commit) (struct gfs2_sbd *sdp, struct gfs2_ail *ai); void (*lo_before_scan) (struct gfs2_jdesc *jd, @@ -64,6 +64,11 @@ struct gfs2_log_operations { const char *lo_name; }; +struct gfs2_log_element { + struct list_head le_list; + const struct gfs2_log_operations *le_ops; +}; + #define GBF_FULL 1 struct gfs2_bitmap { @@ -113,10 +118,15 @@ TAS_BUFFER_FNS(Zeronew, zeronew) struct gfs2_bufdata { struct buffer_head *bd_bh; struct gfs2_glock *bd_gl; - u64 bd_blkno; - struct list_head bd_list; - const struct gfs2_log_operations *bd_ops; + union { + struct list_head list_tr; + u64 blkno; + } u; +#define bd_list_tr u.list_tr +#define bd_blkno u.blkno + + struct gfs2_log_element bd_le; struct gfs2_ail *bd_ail; struct list_head bd_ail_st_list; @@ -401,10 +411,13 @@ struct gfs2_trans { int tr_touched; + unsigned int tr_num_buf; unsigned int tr_num_buf_new; unsigned int tr_num_databuf_new; unsigned int tr_num_buf_rm; unsigned int tr_num_databuf_rm; + struct list_head tr_list_buf; + unsigned int tr_num_revoke; unsigned int tr_num_revoke_rm; }; @@ -686,6 +699,7 @@ struct gfs2_sbd { struct list_head sd_log_le_buf; struct list_head sd_log_le_revoke; + struct list_head sd_log_le_rg; struct list_head sd_log_le_databuf; struct list_head sd_log_le_ordered; @@ -702,9 +716,7 @@ struct gfs2_sbd { struct rw_semaphore sd_log_flush_lock; atomic_t sd_log_in_flight; - struct bio *sd_log_bio; wait_queue_head_t sd_log_flush_wait; - int sd_log_error; unsigned int sd_log_flush_head; u64 sd_log_flush_wrapped; diff --git a/trunk/fs/gfs2/inode.h b/trunk/fs/gfs2/inode.h index c53c7477f6da..276e7b52b658 100644 --- a/trunk/fs/gfs2/inode.h +++ b/trunk/fs/gfs2/inode.h @@ -17,7 +17,10 @@ extern int gfs2_releasepage(struct page *page, gfp_t gfp_mask); extern int gfs2_internal_read(struct gfs2_inode *ip, + struct file_ra_state *ra_state, char *buf, loff_t *pos, unsigned size); +extern void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page, + unsigned int from, unsigned int to); extern void gfs2_set_aops(struct inode *inode); static inline int gfs2_is_stuffed(const struct gfs2_inode *ip) diff --git a/trunk/fs/gfs2/log.c b/trunk/fs/gfs2/log.c index f4beeb9c81c1..4752eadc7f6e 100644 --- a/trunk/fs/gfs2/log.c +++ b/trunk/fs/gfs2/log.c @@ -32,6 +32,8 @@ #include "dir.h" #include "trace_gfs2.h" +#define PULL 1 + /** * gfs2_struct2blk - compute stuff * @sdp: the filesystem @@ -357,6 +359,18 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) return 0; } +u64 gfs2_log_bmap(struct gfs2_sbd *sdp, unsigned int lbn) +{ + struct gfs2_journal_extent *je; + + list_for_each_entry(je, &sdp->sd_jdesc->extent_list, extent_list) { + if (lbn >= je->lblock && lbn < je->lblock + je->blocks) + return je->dblock + lbn - je->lblock; + } + + return -1; +} + /** * log_distance - Compute distance between two journal blocks * @sdp: The GFS2 superblock @@ -452,6 +466,17 @@ static unsigned int current_tail(struct gfs2_sbd *sdp) return tail; } +void gfs2_log_incr_head(struct gfs2_sbd *sdp) +{ + BUG_ON((sdp->sd_log_flush_head == sdp->sd_log_tail) && + (sdp->sd_log_flush_head != sdp->sd_log_head)); + + if (++sdp->sd_log_flush_head == sdp->sd_jdesc->jd_blocks) { + sdp->sd_log_flush_head = 0; + sdp->sd_log_flush_wrapped = 1; + } +} + static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail) { unsigned int dist = log_distance(sdp, new_tail, sdp->sd_log_tail); @@ -486,8 +511,8 @@ static int bd_cmp(void *priv, struct list_head *a, struct list_head *b) { struct gfs2_bufdata *bda, *bdb; - bda = list_entry(a, struct gfs2_bufdata, bd_list); - bdb = list_entry(b, struct gfs2_bufdata, bd_list); + bda = list_entry(a, struct gfs2_bufdata, bd_le.le_list); + bdb = list_entry(b, struct gfs2_bufdata, bd_le.le_list); if (bda->bd_bh->b_blocknr < bdb->bd_bh->b_blocknr) return -1; @@ -505,8 +530,8 @@ static void gfs2_ordered_write(struct gfs2_sbd *sdp) gfs2_log_lock(sdp); list_sort(NULL, &sdp->sd_log_le_ordered, &bd_cmp); while (!list_empty(&sdp->sd_log_le_ordered)) { - bd = list_entry(sdp->sd_log_le_ordered.next, struct gfs2_bufdata, bd_list); - list_move(&bd->bd_list, &written); + bd = list_entry(sdp->sd_log_le_ordered.next, struct gfs2_bufdata, bd_le.le_list); + list_move(&bd->bd_le.le_list, &written); bh = bd->bd_bh; if (!buffer_dirty(bh)) continue; @@ -533,7 +558,7 @@ static void gfs2_ordered_wait(struct gfs2_sbd *sdp) gfs2_log_lock(sdp); while (!list_empty(&sdp->sd_log_le_ordered)) { - bd = list_entry(sdp->sd_log_le_ordered.prev, struct gfs2_bufdata, bd_list); + bd = list_entry(sdp->sd_log_le_ordered.prev, struct gfs2_bufdata, bd_le.le_list); bh = bd->bd_bh; if (buffer_locked(bh)) { get_bh(bh); @@ -543,7 +568,7 @@ static void gfs2_ordered_wait(struct gfs2_sbd *sdp) gfs2_log_lock(sdp); continue; } - list_del_init(&bd->bd_list); + list_del_init(&bd->bd_le.le_list); } gfs2_log_unlock(sdp); } @@ -555,19 +580,25 @@ static void gfs2_ordered_wait(struct gfs2_sbd *sdp) * Returns: the initialized log buffer descriptor */ -static void log_write_header(struct gfs2_sbd *sdp, u32 flags) +static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull) { + u64 blkno = gfs2_log_bmap(sdp, sdp->sd_log_flush_head); + struct buffer_head *bh; struct gfs2_log_header *lh; unsigned int tail; u32 hash; - int rw = WRITE_FLUSH_FUA | REQ_META; - struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO); - lh = page_address(page); - clear_page(lh); + + bh = sb_getblk(sdp->sd_vfs, blkno); + lock_buffer(bh); + memset(bh->b_data, 0, bh->b_size); + set_buffer_uptodate(bh); + clear_buffer_dirty(bh); gfs2_ail1_empty(sdp); tail = current_tail(sdp); + lh = (struct gfs2_log_header *)bh->b_data; + memset(lh, 0, sizeof(struct gfs2_log_header)); lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC); lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH); lh->lh_header.__pad0 = cpu_to_be64(0); @@ -577,22 +608,31 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags) lh->lh_flags = cpu_to_be32(flags); lh->lh_tail = cpu_to_be32(tail); lh->lh_blkno = cpu_to_be32(sdp->sd_log_flush_head); - hash = gfs2_disk_hash(page_address(page), sizeof(struct gfs2_log_header)); + hash = gfs2_disk_hash(bh->b_data, sizeof(struct gfs2_log_header)); lh->lh_hash = cpu_to_be32(hash); + bh->b_end_io = end_buffer_write_sync; + get_bh(bh); if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags)) { gfs2_ordered_wait(sdp); log_flush_wait(sdp); - rw = WRITE_SYNC | REQ_META | REQ_PRIO; + submit_bh(WRITE_SYNC | REQ_META | REQ_PRIO, bh); + } else { + submit_bh(WRITE_FLUSH_FUA | REQ_META, bh); } + wait_on_buffer(bh); - sdp->sd_log_idle = (tail == sdp->sd_log_flush_head); - gfs2_log_write_page(sdp, page); - gfs2_log_flush_bio(sdp, rw); - log_flush_wait(sdp); + if (!buffer_uptodate(bh)) + gfs2_io_error_bh(sdp, bh); + brelse(bh); if (sdp->sd_log_tail != tail) log_pull_tail(sdp, tail); + else + gfs2_assert_withdraw(sdp, !pull); + + sdp->sd_log_idle = (tail == sdp->sd_log_flush_head); + gfs2_log_incr_head(sdp); } /** @@ -638,14 +678,15 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) gfs2_ordered_write(sdp); lops_before_commit(sdp); - gfs2_log_flush_bio(sdp, WRITE); if (sdp->sd_log_head != sdp->sd_log_flush_head) { - log_write_header(sdp, 0); + log_write_header(sdp, 0, 0); } else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){ + gfs2_log_lock(sdp); atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */ trace_gfs2_log_blocks(sdp, -1); - log_write_header(sdp, 0); + gfs2_log_unlock(sdp); + log_write_header(sdp, 0, PULL); } lops_after_commit(sdp, ai); @@ -694,6 +735,21 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) gfs2_log_unlock(sdp); } +static void buf_lo_incore_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) +{ + struct list_head *head = &tr->tr_list_buf; + struct gfs2_bufdata *bd; + + gfs2_log_lock(sdp); + while (!list_empty(head)) { + bd = list_entry(head->next, struct gfs2_bufdata, bd_list_tr); + list_del_init(&bd->bd_list_tr); + tr->tr_num_buf--; + } + gfs2_log_unlock(sdp); + gfs2_assert_warn(sdp, !tr->tr_num_buf); +} + /** * gfs2_log_commit - Commit a transaction to the log * @sdp: the filesystem @@ -712,6 +768,8 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) { log_refund(sdp, tr); + buf_lo_incore_commit(sdp, tr); + up_read(&sdp->sd_log_flush_lock); if (atomic_read(&sdp->sd_log_pinned) > atomic_read(&sdp->sd_log_thresh1) || @@ -740,7 +798,8 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp) sdp->sd_log_flush_head = sdp->sd_log_head; sdp->sd_log_flush_wrapped = 0; - log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT); + log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT, + (sdp->sd_log_tail == current_tail(sdp)) ? 0 : PULL); gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_blks_free) == sdp->sd_jdesc->jd_blocks); gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail); @@ -795,9 +854,11 @@ int gfs2_logd(void *data) struct gfs2_sbd *sdp = data; unsigned long t = 1; DEFINE_WAIT(wait); + unsigned preflush; while (!kthread_should_stop()) { + preflush = atomic_read(&sdp->sd_log_pinned); if (gfs2_jrnl_flush_reqd(sdp) || t == 0) { gfs2_ail1_empty(sdp); gfs2_log_flush(sdp, NULL); diff --git a/trunk/fs/gfs2/log.h b/trunk/fs/gfs2/log.h index 3fd5215ea25f..ff07454b582c 100644 --- a/trunk/fs/gfs2/log.h +++ b/trunk/fs/gfs2/log.h @@ -52,6 +52,8 @@ extern unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, unsigned int ssize); extern int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks); +extern void gfs2_log_incr_head(struct gfs2_sbd *sdp); +extern u64 gfs2_log_bmap(struct gfs2_sbd *sdp, unsigned int lbn); extern void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl); extern void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); extern void gfs2_remove_from_ail(struct gfs2_bufdata *bd); diff --git a/trunk/fs/gfs2/lops.c b/trunk/fs/gfs2/lops.c index 852c1be1dd3b..6b1efb594d90 100644 --- a/trunk/fs/gfs2/lops.c +++ b/trunk/fs/gfs2/lops.c @@ -127,277 +127,146 @@ static void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh, atomic_dec(&sdp->sd_log_pinned); } -static void gfs2_log_incr_head(struct gfs2_sbd *sdp) -{ - BUG_ON((sdp->sd_log_flush_head == sdp->sd_log_tail) && - (sdp->sd_log_flush_head != sdp->sd_log_head)); - if (++sdp->sd_log_flush_head == sdp->sd_jdesc->jd_blocks) { - sdp->sd_log_flush_head = 0; - sdp->sd_log_flush_wrapped = 1; - } +static inline struct gfs2_log_descriptor *bh_log_desc(struct buffer_head *bh) +{ + return (struct gfs2_log_descriptor *)bh->b_data; } -static u64 gfs2_log_bmap(struct gfs2_sbd *sdp) +static inline __be64 *bh_log_ptr(struct buffer_head *bh) { - unsigned int lbn = sdp->sd_log_flush_head; - struct gfs2_journal_extent *je; - u64 block; - - list_for_each_entry(je, &sdp->sd_jdesc->extent_list, extent_list) { - if (lbn >= je->lblock && lbn < je->lblock + je->blocks) { - block = je->dblock + lbn - je->lblock; - gfs2_log_incr_head(sdp); - return block; - } - } - - return -1; + struct gfs2_log_descriptor *ld = bh_log_desc(bh); + return (__force __be64 *)(ld + 1); } -/** - * gfs2_end_log_write_bh - end log write of pagecache data with buffers - * @sdp: The superblock - * @bvec: The bio_vec - * @error: The i/o status - * - * This finds the relavent buffers and unlocks then and sets the - * error flag according to the status of the i/o request. This is - * used when the log is writing data which has an in-place version - * that is pinned in the pagecache. - */ - -static void gfs2_end_log_write_bh(struct gfs2_sbd *sdp, struct bio_vec *bvec, - int error) +static inline __be64 *bh_ptr_end(struct buffer_head *bh) { - struct buffer_head *bh, *next; - struct page *page = bvec->bv_page; - unsigned size; - - bh = page_buffers(page); - size = bvec->bv_len; - while (bh_offset(bh) < bvec->bv_offset) - bh = bh->b_this_page; - do { - if (error) - set_buffer_write_io_error(bh); - unlock_buffer(bh); - next = bh->b_this_page; - size -= bh->b_size; - brelse(bh); - bh = next; - } while(bh && size); + return (__force __be64 *)(bh->b_data + bh->b_size); } /** - * gfs2_end_log_write - end of i/o to the log - * @bio: The bio - * @error: Status of i/o request - * - * Each bio_vec contains either data from the pagecache or data - * relating to the log itself. Here we iterate over the bio_vec - * array, processing both kinds of data. + * gfs2_log_write_endio - End of I/O for a log buffer + * @bh: The buffer head + * @uptodate: I/O Status * */ -static void gfs2_end_log_write(struct bio *bio, int error) +static void gfs2_log_write_endio(struct buffer_head *bh, int uptodate) { - struct gfs2_sbd *sdp = bio->bi_private; - struct bio_vec *bvec; - struct page *page; - int i; + struct gfs2_sbd *sdp = bh->b_private; + bh->b_private = NULL; - if (error) { - sdp->sd_log_error = error; - fs_err(sdp, "Error %d writing to log\n", error); - } - - bio_for_each_segment(bvec, bio, i) { - page = bvec->bv_page; - if (page_has_buffers(page)) - gfs2_end_log_write_bh(sdp, bvec, error); - else - mempool_free(page, gfs2_page_pool); - } - - bio_put(bio); + end_buffer_write_sync(bh, uptodate); if (atomic_dec_and_test(&sdp->sd_log_in_flight)) wake_up(&sdp->sd_log_flush_wait); } /** - * gfs2_log_flush_bio - Submit any pending log bio - * @sdp: The superblock - * @rw: The rw flags - * - * Submit any pending part-built or full bio to the block device. If - * there is no pending bio, then this is a no-op. - */ - -void gfs2_log_flush_bio(struct gfs2_sbd *sdp, int rw) -{ - if (sdp->sd_log_bio) { - atomic_inc(&sdp->sd_log_in_flight); - submit_bio(rw, sdp->sd_log_bio); - sdp->sd_log_bio = NULL; - } -} - -/** - * gfs2_log_alloc_bio - Allocate a new bio for log writing - * @sdp: The superblock - * @blkno: The next device block number we want to write to - * - * This should never be called when there is a cached bio in the - * super block. When it returns, there will be a cached bio in the - * super block which will have as many bio_vecs as the device is - * happy to handle. + * gfs2_log_get_buf - Get and initialize a buffer to use for log control data + * @sdp: The GFS2 superblock * - * Returns: Newly allocated bio + * tReturns: the buffer_head */ -static struct bio *gfs2_log_alloc_bio(struct gfs2_sbd *sdp, u64 blkno) +static struct buffer_head *gfs2_log_get_buf(struct gfs2_sbd *sdp) { - struct super_block *sb = sdp->sd_vfs; - unsigned nrvecs = bio_get_nr_vecs(sb->s_bdev); - struct bio *bio; - - BUG_ON(sdp->sd_log_bio); - - while (1) { - bio = bio_alloc(GFP_NOIO, nrvecs); - if (likely(bio)) - break; - nrvecs = max(nrvecs/2, 1U); - } - - bio->bi_sector = blkno * (sb->s_blocksize >> 9); - bio->bi_bdev = sb->s_bdev; - bio->bi_end_io = gfs2_end_log_write; - bio->bi_private = sdp; + u64 blkno = gfs2_log_bmap(sdp, sdp->sd_log_flush_head); + struct buffer_head *bh; - sdp->sd_log_bio = bio; + bh = sb_getblk(sdp->sd_vfs, blkno); + lock_buffer(bh); + memset(bh->b_data, 0, bh->b_size); + set_buffer_uptodate(bh); + clear_buffer_dirty(bh); + gfs2_log_incr_head(sdp); + atomic_inc(&sdp->sd_log_in_flight); + bh->b_private = sdp; + bh->b_end_io = gfs2_log_write_endio; - return bio; + return bh; } /** - * gfs2_log_get_bio - Get cached log bio, or allocate a new one - * @sdp: The superblock - * @blkno: The device block number we want to write to - * - * If there is a cached bio, then if the next block number is sequential - * with the previous one, return it, otherwise flush the bio to the - * device. If there is not a cached bio, or we just flushed it, then - * allocate a new one. + * gfs2_fake_write_endio - + * @bh: The buffer head + * @uptodate: The I/O Status * - * Returns: The bio to use for log writes */ -static struct bio *gfs2_log_get_bio(struct gfs2_sbd *sdp, u64 blkno) +static void gfs2_fake_write_endio(struct buffer_head *bh, int uptodate) { - struct bio *bio = sdp->sd_log_bio; - u64 nblk; - - if (bio) { - nblk = bio->bi_sector + bio_sectors(bio); - nblk >>= sdp->sd_fsb2bb_shift; - if (blkno == nblk) - return bio; - gfs2_log_flush_bio(sdp, WRITE); - } + struct buffer_head *real_bh = bh->b_private; + struct gfs2_bufdata *bd = real_bh->b_private; + struct gfs2_sbd *sdp = bd->bd_gl->gl_sbd; - return gfs2_log_alloc_bio(sdp, blkno); + end_buffer_write_sync(bh, uptodate); + mempool_free(bh, gfs2_bh_pool); + unlock_buffer(real_bh); + brelse(real_bh); + if (atomic_dec_and_test(&sdp->sd_log_in_flight)) + wake_up(&sdp->sd_log_flush_wait); } - /** - * gfs2_log_write - write to log + * gfs2_log_fake_buf - Build a fake buffer head to write metadata buffer to log * @sdp: the filesystem - * @page: the page to write - * @size: the size of the data to write - * @offset: the offset within the page + * @data: the data the buffer_head should point to * - * Try and add the page segment to the current bio. If that fails, - * submit the current bio to the device and create a new one, and - * then add the page segment to that. + * Returns: the log buffer descriptor */ -static void gfs2_log_write(struct gfs2_sbd *sdp, struct page *page, - unsigned size, unsigned offset) +static struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp, + struct buffer_head *real) { - u64 blkno = gfs2_log_bmap(sdp); - struct bio *bio; - int ret; - - bio = gfs2_log_get_bio(sdp, blkno); - ret = bio_add_page(bio, page, size, offset); - if (ret == 0) { - gfs2_log_flush_bio(sdp, WRITE); - bio = gfs2_log_alloc_bio(sdp, blkno); - ret = bio_add_page(bio, page, size, offset); - WARN_ON(ret == 0); - } -} - -/** - * gfs2_log_write_bh - write a buffer's content to the log - * @sdp: The super block - * @bh: The buffer pointing to the in-place location - * - * This writes the content of the buffer to the next available location - * in the log. The buffer will be unlocked once the i/o to the log has - * completed. - */ + u64 blkno = gfs2_log_bmap(sdp, sdp->sd_log_flush_head); + struct buffer_head *bh; -static void gfs2_log_write_bh(struct gfs2_sbd *sdp, struct buffer_head *bh) -{ - gfs2_log_write(sdp, bh->b_page, bh->b_size, bh_offset(bh)); -} + bh = mempool_alloc(gfs2_bh_pool, GFP_NOFS); + atomic_set(&bh->b_count, 1); + bh->b_state = (1 << BH_Mapped) | (1 << BH_Uptodate) | (1 << BH_Lock); + set_bh_page(bh, real->b_page, bh_offset(real)); + bh->b_blocknr = blkno; + bh->b_size = sdp->sd_sb.sb_bsize; + bh->b_bdev = sdp->sd_vfs->s_bdev; + bh->b_private = real; + bh->b_end_io = gfs2_fake_write_endio; -/** - * gfs2_log_write_page - write one block stored in a page, into the log - * @sdp: The superblock - * @page: The struct page - * - * This writes the first block-sized part of the page into the log. Note - * that the page must have been allocated from the gfs2_page_pool mempool - * and that after this has been called, ownership has been transferred and - * the page may be freed at any time. - */ + gfs2_log_incr_head(sdp); + atomic_inc(&sdp->sd_log_in_flight); -void gfs2_log_write_page(struct gfs2_sbd *sdp, struct page *page) -{ - struct super_block *sb = sdp->sd_vfs; - gfs2_log_write(sdp, page, sb->s_blocksize, 0); + return bh; } -static struct page *gfs2_get_log_desc(struct gfs2_sbd *sdp, u32 ld_type, - u32 ld_length, u32 ld_data1) +static struct buffer_head *gfs2_get_log_desc(struct gfs2_sbd *sdp, u32 ld_type) { - struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO); - struct gfs2_log_descriptor *ld = page_address(page); - clear_page(ld); + struct buffer_head *bh = gfs2_log_get_buf(sdp); + struct gfs2_log_descriptor *ld = bh_log_desc(bh); ld->ld_header.mh_magic = cpu_to_be32(GFS2_MAGIC); ld->ld_header.mh_type = cpu_to_be32(GFS2_METATYPE_LD); ld->ld_header.mh_format = cpu_to_be32(GFS2_FORMAT_LD); ld->ld_type = cpu_to_be32(ld_type); - ld->ld_length = cpu_to_be32(ld_length); - ld->ld_data1 = cpu_to_be32(ld_data1); + ld->ld_length = 0; + ld->ld_data1 = 0; ld->ld_data2 = 0; - return page; + memset(ld->ld_reserved, 0, sizeof(ld->ld_reserved)); + return bh; } -static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) +static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) { + struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le); struct gfs2_meta_header *mh; struct gfs2_trans *tr; lock_buffer(bd->bd_bh); gfs2_log_lock(sdp); + if (!list_empty(&bd->bd_list_tr)) + goto out; tr = current->journal_info; tr->tr_touched = 1; - if (!list_empty(&bd->bd_list)) + tr->tr_num_buf++; + list_add(&bd->bd_list_tr, &tr->tr_list_buf); + if (!list_empty(&le->le_list)) goto out; set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); @@ -407,86 +276,62 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) mh->__pad0 = cpu_to_be64(0); mh->mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid); sdp->sd_log_num_buf++; - list_add(&bd->bd_list, &sdp->sd_log_le_buf); + list_add(&le->le_list, &sdp->sd_log_le_buf); tr->tr_num_buf_new++; out: gfs2_log_unlock(sdp); unlock_buffer(bd->bd_bh); } -static void gfs2_check_magic(struct buffer_head *bh) -{ - void *kaddr; - __be32 *ptr; - - clear_buffer_escaped(bh); - kaddr = kmap_atomic(bh->b_page); - ptr = kaddr + bh_offset(bh); - if (*ptr == cpu_to_be32(GFS2_MAGIC)) - set_buffer_escaped(bh); - kunmap_atomic(kaddr); -} - -static void gfs2_before_commit(struct gfs2_sbd *sdp, unsigned int limit, - unsigned int total, struct list_head *blist, - bool is_databuf) +static void buf_lo_before_commit(struct gfs2_sbd *sdp) { + struct buffer_head *bh; struct gfs2_log_descriptor *ld; struct gfs2_bufdata *bd1 = NULL, *bd2; - struct page *page; + unsigned int total; + unsigned int limit; unsigned int num; unsigned n; __be64 *ptr; + limit = buf_limit(sdp); + /* for 4k blocks, limit = 503 */ + gfs2_log_lock(sdp); - bd1 = bd2 = list_prepare_entry(bd1, blist, bd_list); + total = sdp->sd_log_num_buf; + bd1 = bd2 = list_prepare_entry(bd1, &sdp->sd_log_le_buf, bd_le.le_list); while(total) { num = total; if (total > limit) num = limit; gfs2_log_unlock(sdp); - page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_METADATA, num + 1, num); - ld = page_address(page); + bh = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_METADATA); gfs2_log_lock(sdp); - ptr = (__be64 *)(ld + 1); + ld = bh_log_desc(bh); + ptr = bh_log_ptr(bh); + ld->ld_length = cpu_to_be32(num + 1); + ld->ld_data1 = cpu_to_be32(num); n = 0; - list_for_each_entry_continue(bd1, blist, bd_list) { + list_for_each_entry_continue(bd1, &sdp->sd_log_le_buf, + bd_le.le_list) { *ptr++ = cpu_to_be64(bd1->bd_bh->b_blocknr); - if (is_databuf) { - gfs2_check_magic(bd1->bd_bh); - *ptr++ = cpu_to_be64(buffer_escaped(bd1->bd_bh) ? 1 : 0); - } if (++n >= num) break; } gfs2_log_unlock(sdp); - gfs2_log_write_page(sdp, page); + submit_bh(WRITE_SYNC, bh); gfs2_log_lock(sdp); n = 0; - list_for_each_entry_continue(bd2, blist, bd_list) { + list_for_each_entry_continue(bd2, &sdp->sd_log_le_buf, + bd_le.le_list) { get_bh(bd2->bd_bh); gfs2_log_unlock(sdp); lock_buffer(bd2->bd_bh); - - if (buffer_escaped(bd2->bd_bh)) { - void *kaddr; - page = mempool_alloc(gfs2_page_pool, GFP_NOIO); - ptr = page_address(page); - kaddr = kmap_atomic(bd2->bd_bh->b_page); - memcpy(ptr, kaddr + bh_offset(bd2->bd_bh), - bd2->bd_bh->b_size); - kunmap_atomic(kaddr); - *(__be32 *)ptr = 0; - clear_buffer_escaped(bd2->bd_bh); - unlock_buffer(bd2->bd_bh); - brelse(bd2->bd_bh); - gfs2_log_write_page(sdp, page); - } else { - gfs2_log_write_bh(sdp, bd2->bd_bh); - } + bh = gfs2_log_fake_buf(sdp, bd2->bd_bh); + submit_bh(WRITE_SYNC, bh); gfs2_log_lock(sdp); if (++n >= num) break; @@ -498,22 +343,14 @@ static void gfs2_before_commit(struct gfs2_sbd *sdp, unsigned int limit, gfs2_log_unlock(sdp); } -static void buf_lo_before_commit(struct gfs2_sbd *sdp) -{ - unsigned int limit = buf_limit(sdp); /* 503 for 4k blocks */ - - gfs2_before_commit(sdp, limit, sdp->sd_log_num_buf, - &sdp->sd_log_le_buf, 0); -} - static void buf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) { struct list_head *head = &sdp->sd_log_le_buf; struct gfs2_bufdata *bd; while (!list_empty(head)) { - bd = list_entry(head->next, struct gfs2_bufdata, bd_list); - list_del_init(&bd->bd_list); + bd = list_entry(head->next, struct gfs2_bufdata, bd_le.le_list); + list_del_init(&bd->bd_le.le_list); sdp->sd_log_num_buf--; gfs2_unpin(sdp, bd->bd_bh, ai); @@ -600,8 +437,9 @@ static void buf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass) jd->jd_jid, sdp->sd_replayed_blocks, sdp->sd_found_blocks); } -static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) +static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) { + struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le); struct gfs2_glock *gl = bd->bd_gl; struct gfs2_trans *tr; @@ -611,48 +449,48 @@ static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) sdp->sd_log_num_revoke++; atomic_inc(&gl->gl_revokes); set_bit(GLF_LFLUSH, &gl->gl_flags); - list_add(&bd->bd_list, &sdp->sd_log_le_revoke); + list_add(&le->le_list, &sdp->sd_log_le_revoke); } static void revoke_lo_before_commit(struct gfs2_sbd *sdp) { struct gfs2_log_descriptor *ld; struct gfs2_meta_header *mh; + struct buffer_head *bh; unsigned int offset; struct list_head *head = &sdp->sd_log_le_revoke; struct gfs2_bufdata *bd; - struct page *page; - unsigned int length; if (!sdp->sd_log_num_revoke) return; - length = gfs2_struct2blk(sdp, sdp->sd_log_num_revoke, sizeof(u64)); - page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_REVOKE, length, sdp->sd_log_num_revoke); - ld = page_address(page); + bh = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_REVOKE); + ld = bh_log_desc(bh); + ld->ld_length = cpu_to_be32(gfs2_struct2blk(sdp, sdp->sd_log_num_revoke, + sizeof(u64))); + ld->ld_data1 = cpu_to_be32(sdp->sd_log_num_revoke); offset = sizeof(struct gfs2_log_descriptor); - list_for_each_entry(bd, head, bd_list) { + list_for_each_entry(bd, head, bd_le.le_list) { sdp->sd_log_num_revoke--; if (offset + sizeof(u64) > sdp->sd_sb.sb_bsize) { + submit_bh(WRITE_SYNC, bh); - gfs2_log_write_page(sdp, page); - page = mempool_alloc(gfs2_page_pool, GFP_NOIO); - mh = page_address(page); - clear_page(mh); + bh = gfs2_log_get_buf(sdp); + mh = (struct gfs2_meta_header *)bh->b_data; mh->mh_magic = cpu_to_be32(GFS2_MAGIC); mh->mh_type = cpu_to_be32(GFS2_METATYPE_LB); mh->mh_format = cpu_to_be32(GFS2_FORMAT_LB); offset = sizeof(struct gfs2_meta_header); } - *(__be64 *)(page_address(page) + offset) = cpu_to_be64(bd->bd_blkno); + *(__be64 *)(bh->b_data + offset) = cpu_to_be64(bd->bd_blkno); offset += sizeof(u64); } gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); - gfs2_log_write_page(sdp, page); + submit_bh(WRITE_SYNC, bh); } static void revoke_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) @@ -662,8 +500,8 @@ static void revoke_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) struct gfs2_glock *gl; while (!list_empty(head)) { - bd = list_entry(head->next, struct gfs2_bufdata, bd_list); - list_del_init(&bd->bd_list); + bd = list_entry(head->next, struct gfs2_bufdata, bd_le.le_list); + list_del_init(&bd->bd_le.le_list); gl = bd->bd_gl; atomic_dec(&gl->gl_revokes); clear_bit(GLF_LFLUSH, &gl->gl_flags); @@ -766,33 +604,108 @@ static void revoke_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass) * blocks, which isn't an enormous overhead but twice as much as * for normal metadata blocks. */ -static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) +static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) { + struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le); struct gfs2_trans *tr = current->journal_info; struct address_space *mapping = bd->bd_bh->b_page->mapping; struct gfs2_inode *ip = GFS2_I(mapping->host); lock_buffer(bd->bd_bh); gfs2_log_lock(sdp); - if (tr) + if (tr) { + if (!list_empty(&bd->bd_list_tr)) + goto out; tr->tr_touched = 1; - if (!list_empty(&bd->bd_list)) + if (gfs2_is_jdata(ip)) { + tr->tr_num_buf++; + list_add(&bd->bd_list_tr, &tr->tr_list_buf); + } + } + if (!list_empty(&le->le_list)) goto out; + set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); if (gfs2_is_jdata(ip)) { gfs2_pin(sdp, bd->bd_bh); tr->tr_num_databuf_new++; sdp->sd_log_num_databuf++; - list_add_tail(&bd->bd_list, &sdp->sd_log_le_databuf); + list_add_tail(&le->le_list, &sdp->sd_log_le_databuf); } else { - list_add_tail(&bd->bd_list, &sdp->sd_log_le_ordered); + list_add_tail(&le->le_list, &sdp->sd_log_le_ordered); } out: gfs2_log_unlock(sdp); unlock_buffer(bd->bd_bh); } +static void gfs2_check_magic(struct buffer_head *bh) +{ + void *kaddr; + __be32 *ptr; + + clear_buffer_escaped(bh); + kaddr = kmap_atomic(bh->b_page); + ptr = kaddr + bh_offset(bh); + if (*ptr == cpu_to_be32(GFS2_MAGIC)) + set_buffer_escaped(bh); + kunmap_atomic(kaddr); +} + +static void gfs2_write_blocks(struct gfs2_sbd *sdp, struct buffer_head *bh, + struct list_head *list, struct list_head *done, + unsigned int n) +{ + struct buffer_head *bh1; + struct gfs2_log_descriptor *ld; + struct gfs2_bufdata *bd; + __be64 *ptr; + + if (!bh) + return; + + ld = bh_log_desc(bh); + ld->ld_length = cpu_to_be32(n + 1); + ld->ld_data1 = cpu_to_be32(n); + + ptr = bh_log_ptr(bh); + + get_bh(bh); + submit_bh(WRITE_SYNC, bh); + gfs2_log_lock(sdp); + while(!list_empty(list)) { + bd = list_entry(list->next, struct gfs2_bufdata, bd_le.le_list); + list_move_tail(&bd->bd_le.le_list, done); + get_bh(bd->bd_bh); + while (be64_to_cpu(*ptr) != bd->bd_bh->b_blocknr) { + gfs2_log_incr_head(sdp); + ptr += 2; + } + gfs2_log_unlock(sdp); + lock_buffer(bd->bd_bh); + if (buffer_escaped(bd->bd_bh)) { + void *kaddr; + bh1 = gfs2_log_get_buf(sdp); + kaddr = kmap_atomic(bd->bd_bh->b_page); + memcpy(bh1->b_data, kaddr + bh_offset(bd->bd_bh), + bh1->b_size); + kunmap_atomic(kaddr); + *(__be32 *)bh1->b_data = 0; + clear_buffer_escaped(bd->bd_bh); + unlock_buffer(bd->bd_bh); + brelse(bd->bd_bh); + } else { + bh1 = gfs2_log_fake_buf(sdp, bd->bd_bh); + } + submit_bh(WRITE_SYNC, bh1); + gfs2_log_lock(sdp); + ptr += 2; + } + gfs2_log_unlock(sdp); + brelse(bh); +} + /** * databuf_lo_before_commit - Scan the data buffers, writing as we go * @@ -800,10 +713,37 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) static void databuf_lo_before_commit(struct gfs2_sbd *sdp) { - unsigned int limit = buf_limit(sdp) / 2; + struct gfs2_bufdata *bd = NULL; + struct buffer_head *bh = NULL; + unsigned int n = 0; + __be64 *ptr = NULL, *end = NULL; + LIST_HEAD(processed); + LIST_HEAD(in_progress); - gfs2_before_commit(sdp, limit, sdp->sd_log_num_databuf, - &sdp->sd_log_le_databuf, 1); + gfs2_log_lock(sdp); + while (!list_empty(&sdp->sd_log_le_databuf)) { + if (ptr == end) { + gfs2_log_unlock(sdp); + gfs2_write_blocks(sdp, bh, &in_progress, &processed, n); + n = 0; + bh = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_JDATA); + ptr = bh_log_ptr(bh); + end = bh_ptr_end(bh) - 1; + gfs2_log_lock(sdp); + continue; + } + bd = list_entry(sdp->sd_log_le_databuf.next, struct gfs2_bufdata, bd_le.le_list); + list_move_tail(&bd->bd_le.le_list, &in_progress); + gfs2_check_magic(bd->bd_bh); + *ptr++ = cpu_to_be64(bd->bd_bh->b_blocknr); + *ptr++ = cpu_to_be64(buffer_escaped(bh) ? 1 : 0); + n++; + } + gfs2_log_unlock(sdp); + gfs2_write_blocks(sdp, bh, &in_progress, &processed, n); + gfs2_log_lock(sdp); + list_splice(&processed, &sdp->sd_log_le_databuf); + gfs2_log_unlock(sdp); } static int databuf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start, @@ -882,8 +822,8 @@ static void databuf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) struct gfs2_bufdata *bd; while (!list_empty(head)) { - bd = list_entry(head->next, struct gfs2_bufdata, bd_list); - list_del_init(&bd->bd_list); + bd = list_entry(head->next, struct gfs2_bufdata, bd_le.le_list); + list_del_init(&bd->bd_le.le_list); sdp->sd_log_num_databuf--; gfs2_unpin(sdp, bd->bd_bh, ai); } diff --git a/trunk/fs/gfs2/lops.h b/trunk/fs/gfs2/lops.h index 954a330585f4..3c0b2737658a 100644 --- a/trunk/fs/gfs2/lops.h +++ b/trunk/fs/gfs2/lops.h @@ -27,8 +27,6 @@ extern const struct gfs2_log_operations gfs2_rg_lops; extern const struct gfs2_log_operations gfs2_databuf_lops; extern const struct gfs2_log_operations *gfs2_log_ops[]; -extern void gfs2_log_write_page(struct gfs2_sbd *sdp, struct page *page); -extern void gfs2_log_flush_bio(struct gfs2_sbd *sdp, int rw); static inline unsigned int buf_limit(struct gfs2_sbd *sdp) { @@ -46,17 +44,17 @@ static inline unsigned int databuf_limit(struct gfs2_sbd *sdp) return limit; } -static inline void lops_init_le(struct gfs2_bufdata *bd, +static inline void lops_init_le(struct gfs2_log_element *le, const struct gfs2_log_operations *lops) { - INIT_LIST_HEAD(&bd->bd_list); - bd->bd_ops = lops; + INIT_LIST_HEAD(&le->le_list); + le->le_ops = lops; } -static inline void lops_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) +static inline void lops_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) { - if (bd->bd_ops->lo_add) - bd->bd_ops->lo_add(sdp, bd); + if (le->le_ops->lo_add) + le->le_ops->lo_add(sdp, le); } static inline void lops_before_commit(struct gfs2_sbd *sdp) diff --git a/trunk/fs/gfs2/main.c b/trunk/fs/gfs2/main.c index 6cdb0f2a1b09..754426b1e52c 100644 --- a/trunk/fs/gfs2/main.c +++ b/trunk/fs/gfs2/main.c @@ -70,6 +70,16 @@ static void gfs2_init_gl_aspace_once(void *foo) address_space_init_once(mapping); } +static void *gfs2_bh_alloc(gfp_t mask, void *data) +{ + return alloc_buffer_head(mask); +} + +static void gfs2_bh_free(void *ptr, void *data) +{ + return free_buffer_head(ptr); +} + /** * init_gfs2_fs - Register GFS2 as a filesystem * @@ -133,12 +143,6 @@ static int __init init_gfs2_fs(void) if (!gfs2_quotad_cachep) goto fail; - gfs2_rsrv_cachep = kmem_cache_create("gfs2_mblk", - sizeof(struct gfs2_blkreserv), - 0, 0, NULL); - if (!gfs2_rsrv_cachep) - goto fail; - register_shrinker(&qd_shrinker); error = register_filesystem(&gfs2_fs_type); @@ -160,8 +164,8 @@ static int __init init_gfs2_fs(void) if (!gfs2_control_wq) goto fail_recovery; - gfs2_page_pool = mempool_create_page_pool(64, 0); - if (!gfs2_page_pool) + gfs2_bh_pool = mempool_create(1024, gfs2_bh_alloc, gfs2_bh_free, NULL); + if (!gfs2_bh_pool) goto fail_control; gfs2_register_debugfs(); @@ -182,9 +186,6 @@ static int __init init_gfs2_fs(void) unregister_shrinker(&qd_shrinker); gfs2_glock_exit(); - if (gfs2_rsrv_cachep) - kmem_cache_destroy(gfs2_rsrv_cachep); - if (gfs2_quotad_cachep) kmem_cache_destroy(gfs2_quotad_cachep); @@ -224,8 +225,7 @@ static void __exit exit_gfs2_fs(void) rcu_barrier(); - mempool_destroy(gfs2_page_pool); - kmem_cache_destroy(gfs2_rsrv_cachep); + mempool_destroy(gfs2_bh_pool); kmem_cache_destroy(gfs2_quotad_cachep); kmem_cache_destroy(gfs2_rgrpd_cachep); kmem_cache_destroy(gfs2_bufdata_cachep); diff --git a/trunk/fs/gfs2/meta_io.c b/trunk/fs/gfs2/meta_io.c index 6c1e5d1c404a..181586e673f9 100644 --- a/trunk/fs/gfs2/meta_io.c +++ b/trunk/fs/gfs2/meta_io.c @@ -293,10 +293,11 @@ void gfs2_attach_bufdata(struct gfs2_glock *gl, struct buffer_head *bh, bd->bd_bh = bh; bd->bd_gl = gl; + INIT_LIST_HEAD(&bd->bd_list_tr); if (meta) - lops_init_le(bd, &gfs2_buf_lops); + lops_init_le(&bd->bd_le, &gfs2_buf_lops); else - lops_init_le(bd, &gfs2_databuf_lops); + lops_init_le(&bd->bd_le, &gfs2_databuf_lops); bh->b_private = bd; if (meta) @@ -312,7 +313,7 @@ void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr, int if (test_clear_buffer_pinned(bh)) { trace_gfs2_pin(bd, 0); atomic_dec(&sdp->sd_log_pinned); - list_del_init(&bd->bd_list); + list_del_init(&bd->bd_le.le_list); if (meta) { gfs2_assert_warn(sdp, sdp->sd_log_num_buf); sdp->sd_log_num_buf--; @@ -374,24 +375,33 @@ void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen) * @ip: The GFS2 inode * @height: The level of this buf in the metadata (indir addr) tree (if any) * @num: The block number (device relative) of the buffer + * @new: Non-zero if we may create a new buffer * @bhp: the buffer is returned here * * Returns: errno */ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, - struct buffer_head **bhp) + int new, struct buffer_head **bhp) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_glock *gl = ip->i_gl; struct buffer_head *bh; int ret = 0; - u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI; - ret = gfs2_meta_read(gl, num, DIO_WAIT, &bh); - if (ret == 0 && gfs2_metatype_check(sdp, bh, mtype)) { - brelse(bh); - ret = -EIO; + if (new) { + BUG_ON(height == 0); + bh = gfs2_meta_new(gl, num); + gfs2_trans_add_bh(ip->i_gl, bh, 1); + gfs2_metatype_set(bh, GFS2_METATYPE_IN, GFS2_FORMAT_IN); + gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header)); + } else { + u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI; + ret = gfs2_meta_read(gl, num, DIO_WAIT, &bh); + if (ret == 0 && gfs2_metatype_check(sdp, bh, mtype)) { + brelse(bh); + ret = -EIO; + } } *bhp = bh; return ret; diff --git a/trunk/fs/gfs2/meta_io.h b/trunk/fs/gfs2/meta_io.h index c30973b07a7c..22c526593131 100644 --- a/trunk/fs/gfs2/meta_io.h +++ b/trunk/fs/gfs2/meta_io.h @@ -65,12 +65,12 @@ void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr, void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen); int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, - struct buffer_head **bhp); + int new, struct buffer_head **bhp); static inline int gfs2_meta_inode_buffer(struct gfs2_inode *ip, struct buffer_head **bhp) { - return gfs2_meta_indirect_buffer(ip, 0, ip->i_no_addr, bhp); + return gfs2_meta_indirect_buffer(ip, 0, ip->i_no_addr, 0, bhp); } struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen); diff --git a/trunk/fs/gfs2/ops_fstype.c b/trunk/fs/gfs2/ops_fstype.c index c5871ae40561..6f3a18f9e176 100644 --- a/trunk/fs/gfs2/ops_fstype.c +++ b/trunk/fs/gfs2/ops_fstype.c @@ -99,6 +99,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) atomic_set(&sdp->sd_log_pinned, 0); INIT_LIST_HEAD(&sdp->sd_log_le_buf); INIT_LIST_HEAD(&sdp->sd_log_le_revoke); + INIT_LIST_HEAD(&sdp->sd_log_le_rg); INIT_LIST_HEAD(&sdp->sd_log_le_databuf); INIT_LIST_HEAD(&sdp->sd_log_le_ordered); diff --git a/trunk/fs/gfs2/quota.c b/trunk/fs/gfs2/quota.c index b97178e7d397..6019da3dcaed 100644 --- a/trunk/fs/gfs2/quota.c +++ b/trunk/fs/gfs2/quota.c @@ -652,7 +652,7 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc, } memset(&q, 0, sizeof(struct gfs2_quota)); - err = gfs2_internal_read(ip, (char *)&q, &loc, sizeof(q)); + err = gfs2_internal_read(ip, NULL, (char *)&q, &loc, sizeof(q)); if (err < 0) return err; @@ -744,7 +744,7 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc, i_size_write(inode, size); inode->i_mtime = inode->i_atime = CURRENT_TIME; mark_inode_dirty(inode); - return 0; + return err; unlock_out: unlock_page(page); @@ -852,7 +852,7 @@ static int update_qd(struct gfs2_sbd *sdp, struct gfs2_quota_data *qd) memset(&q, 0, sizeof(struct gfs2_quota)); pos = qd2offset(qd); - error = gfs2_internal_read(ip, (char *)&q, &pos, sizeof(q)); + error = gfs2_internal_read(ip, NULL, (char *)&q, &pos, sizeof(q)); if (error < 0) return error; diff --git a/trunk/fs/gfs2/rgrp.c b/trunk/fs/gfs2/rgrp.c index f74fb9bd1973..3df65c9ab73b 100644 --- a/trunk/fs/gfs2/rgrp.c +++ b/trunk/fs/gfs2/rgrp.c @@ -70,15 +70,15 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, /** * gfs2_setbit - Set a bit in the bitmaps - * @rgd: the resource group descriptor - * @buf2: the clone buffer that holds the bitmaps - * @bi: the bitmap structure + * @buffer: the buffer that holds the bitmaps + * @buflen: the length (in bytes) of the buffer * @block: the block to set * @new_state: the new state of the block * */ -static inline void gfs2_setbit(struct gfs2_rgrpd *rgd, unsigned char *buf2, +static inline void gfs2_setbit(struct gfs2_rgrpd *rgd, unsigned char *buf1, + unsigned char *buf2, unsigned int offset, struct gfs2_bitmap *bi, u32 block, unsigned char new_state) { @@ -86,8 +86,8 @@ static inline void gfs2_setbit(struct gfs2_rgrpd *rgd, unsigned char *buf2, unsigned int buflen = bi->bi_len; const unsigned int bit = (block % GFS2_NBBY) * GFS2_BIT_SIZE; - byte1 = bi->bi_bh->b_data + bi->bi_offset + (block / GFS2_NBBY); - end = bi->bi_bh->b_data + bi->bi_offset + buflen; + byte1 = buf1 + offset + (block / GFS2_NBBY); + end = buf1 + offset + buflen; BUG_ON(byte1 >= end); @@ -110,7 +110,7 @@ static inline void gfs2_setbit(struct gfs2_rgrpd *rgd, unsigned char *buf2, *byte1 ^= (cur_state ^ new_state) << bit; if (buf2) { - byte2 = buf2 + bi->bi_offset + (block / GFS2_NBBY); + byte2 = buf2 + offset + (block / GFS2_NBBY); cur_state = (*byte2 >> bit) & GFS2_BIT_MASK; *byte2 ^= (cur_state ^ new_state) << bit; } @@ -118,7 +118,6 @@ static inline void gfs2_setbit(struct gfs2_rgrpd *rgd, unsigned char *buf2, /** * gfs2_testbit - test a bit in the bitmaps - * @rgd: the resource group descriptor * @buffer: the buffer that holds the bitmaps * @buflen: the length (in bytes) of the buffer * @block: the block to read @@ -180,7 +179,7 @@ static inline u64 gfs2_bit_search(const __le64 *ptr, u64 mask, u8 state) /** * gfs2_bitfit - Search an rgrp's bitmap buffer to find a bit-pair representing * a block in a given allocation state. - * @buf: the buffer that holds the bitmaps + * @buffer: the buffer that holds the bitmaps * @len: the length (in bytes) of the buffer * @goal: start search at this block's bit-pair (within @buffer) * @state: GFS2_BLKST_XXX the state of the block we're looking for. @@ -232,7 +231,6 @@ static u32 gfs2_bitfit(const u8 *buf, const unsigned int len, /** * gfs2_bitcount - count the number of bits in a certain state - * @rgd: the resource group descriptor * @buffer: the buffer that holds the bitmaps * @buflen: the length (in bytes) of the buffer * @state: the state of the block we're looking for @@ -266,6 +264,7 @@ static u32 gfs2_bitcount(struct gfs2_rgrpd *rgd, const u8 *buffer, /** * gfs2_rgrp_verify - Verify that a resource group is consistent + * @sdp: the filesystem * @rgd: the rgrp * */ @@ -323,8 +322,7 @@ static inline int rgrp_contains_block(struct gfs2_rgrpd *rgd, u64 block) /** * gfs2_blk2rgrpd - Find resource group for a given data/meta block number * @sdp: The GFS2 superblock - * @blk: The data block number - * @exact: True if this needs to be an exact match + * @n: The data block number * * Returns: The resource group, or NULL if not found */ @@ -382,7 +380,7 @@ struct gfs2_rgrpd *gfs2_rgrpd_get_first(struct gfs2_sbd *sdp) /** * gfs2_rgrpd_get_next - get the next RG - * @rgd: the resource group descriptor + * @rgd: A RG * * Returns: The next rgrp */ @@ -531,7 +529,6 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd) /** * gfs2_ri_total - Total up the file system space, according to the rindex. - * @sdp: the filesystem * */ u64 gfs2_ri_total(struct gfs2_sbd *sdp) @@ -540,14 +537,16 @@ u64 gfs2_ri_total(struct gfs2_sbd *sdp) struct inode *inode = sdp->sd_rindex; struct gfs2_inode *ip = GFS2_I(inode); char buf[sizeof(struct gfs2_rindex)]; + struct file_ra_state ra_state; int error, rgrps; + file_ra_state_init(&ra_state, inode->i_mapping); for (rgrps = 0;; rgrps++) { loff_t pos = rgrps * sizeof(struct gfs2_rindex); if (pos + sizeof(struct gfs2_rindex) > i_size_read(inode)) break; - error = gfs2_internal_read(ip, buf, &pos, + error = gfs2_internal_read(ip, &ra_state, buf, &pos, sizeof(struct gfs2_rindex)); if (error != sizeof(struct gfs2_rindex)) break; @@ -583,12 +582,13 @@ static int rgd_insert(struct gfs2_rgrpd *rgd) /** * read_rindex_entry - Pull in a new resource index entry from the disk - * @ip: Pointer to the rindex inode + * @gl: The glock covering the rindex inode * * Returns: 0 on success, > 0 on EOF, error code otherwise */ -static int read_rindex_entry(struct gfs2_inode *ip) +static int read_rindex_entry(struct gfs2_inode *ip, + struct file_ra_state *ra_state) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex); @@ -599,7 +599,7 @@ static int read_rindex_entry(struct gfs2_inode *ip) if (pos >= i_size_read(&ip->i_inode)) return 1; - error = gfs2_internal_read(ip, (char *)&buf, &pos, + error = gfs2_internal_read(ip, ra_state, (char *)&buf, &pos, sizeof(struct gfs2_rindex)); if (error != sizeof(struct gfs2_rindex)) @@ -655,10 +655,13 @@ static int read_rindex_entry(struct gfs2_inode *ip) static int gfs2_ri_update(struct gfs2_inode *ip) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); + struct inode *inode = &ip->i_inode; + struct file_ra_state ra_state; int error; + file_ra_state_init(&ra_state, inode->i_mapping); do { - error = read_rindex_entry(ip); + error = read_rindex_entry(ip, &ra_state); } while (error == 0); if (error < 0) @@ -738,7 +741,7 @@ static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf) /** * gfs2_rgrp_go_lock - Read in a RG's header and bitmaps - * @gh: The glock holder for the resource group + * @rgd: the struct gfs2_rgrpd describing the RG to read in * * Read in all of a Resource Group's header and bitmap blocks. * Caller must eventually call gfs2_rgrp_relse() to free the bitmaps. @@ -798,7 +801,7 @@ int gfs2_rgrp_go_lock(struct gfs2_holder *gh) /** * gfs2_rgrp_go_unlock - Release RG bitmaps read in with gfs2_rgrp_bh_get() - * @gh: The glock holder for the resource group + * @rgd: the struct gfs2_rgrpd describing the RG to read in * */ @@ -999,13 +1002,11 @@ struct gfs2_qadata *gfs2_qadata_get(struct gfs2_inode *ip) * Returns: the struct gfs2_qadata */ -static int gfs2_blkrsv_get(struct gfs2_inode *ip) +static struct gfs2_blkreserv *gfs2_blkrsv_get(struct gfs2_inode *ip) { BUG_ON(ip->i_res != NULL); - ip->i_res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS); - if (!ip->i_res) - return -ENOMEM; - return 0; + ip->i_res = kzalloc(sizeof(struct gfs2_blkreserv), GFP_NOFS); + return ip->i_res; } /** @@ -1037,8 +1038,6 @@ static inline u32 gfs2_bi2rgd_blk(struct gfs2_bitmap *bi, u32 blk) /** * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes * @rgd: The rgrp - * @last_unlinked: block address of the last dinode we unlinked - * @skip: block address we should explicitly not unlink * * Returns: 0 if no error * The inode, if one has been found, in inode. @@ -1103,7 +1102,7 @@ static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip /** * get_local_rgrp - Choose and lock a rgrp for allocation * @ip: the inode to reserve space for - * @last_unlinked: the last unlinked block + * @rgp: the chosen and locked rgrp * * Try to acquire rgrp in way which avoids contending with others. * @@ -1165,14 +1164,13 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) static void gfs2_blkrsv_put(struct gfs2_inode *ip) { BUG_ON(ip->i_res == NULL); - kmem_cache_free(gfs2_rsrv_cachep, ip->i_res); + kfree(ip->i_res); ip->i_res = NULL; } /** * gfs2_inplace_reserve - Reserve space in the filesystem * @ip: the inode to reserve space for - * @requested: the number of blocks to be reserved * * Returns: errno */ @@ -1181,15 +1179,14 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_blkreserv *rs; - int error; + int error = 0; u64 last_unlinked = NO_BLOCK; int tries = 0; - error = gfs2_blkrsv_get(ip); - if (error) - return error; + rs = gfs2_blkrsv_get(ip); + if (!rs) + return -ENOMEM; - rs = ip->i_res; rs->rs_requested = requested; if (gfs2_assert_warn(sdp, requested)) { error = -EINVAL; @@ -1271,6 +1268,7 @@ static unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block) * @rgd: the resource group descriptor * @goal: the goal block within the RG (start here to search for avail block) * @state: GFS2_BLKST_XXX the before-allocation state to find + * @dinode: TRUE if the first block we allocate is for a dinode * @rbi: address of the pointer to the bitmap containing the block found * * Walk rgrp's bitmap to find bits that represent a block in @state. @@ -1284,12 +1282,13 @@ static unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block) * Returns: the block number found relative to the bitmap rbi */ -static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, unsigned char state, +static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, + unsigned char state, struct gfs2_bitmap **rbi) { struct gfs2_bitmap *bi = NULL; const u32 length = rgd->rd_length; - u32 biblk = BFITNOENT; + u32 blk = BFITNOENT; unsigned int buf, x; const u8 *buffer = NULL; @@ -1326,8 +1325,8 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, unsigned char state, if (state != GFS2_BLKST_UNLINKED && bi->bi_clone) buffer = bi->bi_clone + bi->bi_offset; - biblk = gfs2_bitfit(buffer, bi->bi_len, goal, state); - if (biblk != BFITNOENT) + blk = gfs2_bitfit(buffer, bi->bi_len, goal, state); + if (blk != BFITNOENT) break; if ((goal == 0) && (state == GFS2_BLKST_FREE)) @@ -1340,10 +1339,10 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, unsigned char state, goal = 0; } - if (biblk != BFITNOENT) + if (blk != BFITNOENT) *rbi = bi; - return biblk; + return blk; } /** @@ -1368,8 +1367,8 @@ static u64 gfs2_alloc_extent(struct gfs2_rgrpd *rgd, struct gfs2_bitmap *bi, *n = 0; buffer = bi->bi_bh->b_data + bi->bi_offset; gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); - gfs2_setbit(rgd, bi->bi_clone, bi, blk, - dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED); + gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset, + bi, blk, dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED); (*n)++; goal = blk; while (*n < elen) { @@ -1379,7 +1378,8 @@ static u64 gfs2_alloc_extent(struct gfs2_rgrpd *rgd, struct gfs2_bitmap *bi, if (gfs2_testbit(rgd, buffer, bi->bi_len, goal) != GFS2_BLKST_FREE) break; - gfs2_setbit(rgd, bi->bi_clone, bi, goal, GFS2_BLKST_USED); + gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset, + bi, goal, GFS2_BLKST_USED); (*n)++; } blk = gfs2_bi2rgd_blk(bi, blk); @@ -1436,7 +1436,8 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart, bi->bi_len); } gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); - gfs2_setbit(rgd, NULL, bi, buf_blk, new_state); + gfs2_setbit(rgd, bi->bi_bh->b_data, NULL, bi->bi_offset, + bi, buf_blk, new_state); } return rgd; @@ -1556,7 +1557,7 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks, ip->i_inode.i_gid); rgd->rd_free_clone -= *nblocks; - trace_gfs2_block_alloc(ip, rgd, block, *nblocks, + trace_gfs2_block_alloc(ip, block, *nblocks, dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED); *bn = block; return 0; @@ -1583,7 +1584,7 @@ void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta) rgd = rgblk_free(sdp, bstart, blen, GFS2_BLKST_FREE); if (!rgd) return; - trace_gfs2_block_alloc(ip, rgd, bstart, blen, GFS2_BLKST_FREE); + trace_gfs2_block_alloc(ip, bstart, blen, GFS2_BLKST_FREE); rgd->rd_free += blen; rgd->rd_flags &= ~GFS2_RGF_TRIMMED; gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); @@ -1621,7 +1622,7 @@ void gfs2_unlink_di(struct inode *inode) rgd = rgblk_free(sdp, blkno, 1, GFS2_BLKST_UNLINKED); if (!rgd) return; - trace_gfs2_block_alloc(ip, rgd, blkno, 1, GFS2_BLKST_UNLINKED); + trace_gfs2_block_alloc(ip, blkno, 1, GFS2_BLKST_UNLINKED); gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); } @@ -1651,7 +1652,7 @@ static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno) void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) { gfs2_free_uninit_di(rgd, ip->i_no_addr); - trace_gfs2_block_alloc(ip, rgd, ip->i_no_addr, 1, GFS2_BLKST_FREE); + trace_gfs2_block_alloc(ip, ip->i_no_addr, 1, GFS2_BLKST_FREE); gfs2_quota_change(ip, -1, ip->i_inode.i_uid, ip->i_inode.i_gid); gfs2_meta_wipe(ip, ip->i_no_addr, 1); } @@ -1751,6 +1752,7 @@ void gfs2_rlist_add(struct gfs2_inode *ip, struct gfs2_rgrp_list *rlist, * and initialize an array of glock holders for them * @rlist: the list of resource groups * @state: the lock state to acquire the RG lock in + * @flags: the modifier flags for the holder structures * * FIXME: Don't use NOFAIL * diff --git a/trunk/fs/gfs2/trace_gfs2.h b/trunk/fs/gfs2/trace_gfs2.h index 1b8b81588199..dfa89cd75534 100644 --- a/trunk/fs/gfs2/trace_gfs2.h +++ b/trunk/fs/gfs2/trace_gfs2.h @@ -457,10 +457,10 @@ TRACE_EVENT(gfs2_bmap, /* Keep track of blocks as they are allocated/freed */ TRACE_EVENT(gfs2_block_alloc, - TP_PROTO(const struct gfs2_inode *ip, struct gfs2_rgrpd *rgd, - u64 block, unsigned len, u8 block_state), + TP_PROTO(const struct gfs2_inode *ip, u64 block, unsigned len, + u8 block_state), - TP_ARGS(ip, rgd, block, len, block_state), + TP_ARGS(ip, block, len, block_state), TP_STRUCT__entry( __field( dev_t, dev ) @@ -468,8 +468,6 @@ TRACE_EVENT(gfs2_block_alloc, __field( u64, inum ) __field( u32, len ) __field( u8, block_state ) - __field( u64, rd_addr ) - __field( u32, rd_free_clone ) ), TP_fast_assign( @@ -478,18 +476,14 @@ TRACE_EVENT(gfs2_block_alloc, __entry->inum = ip->i_no_addr; __entry->len = len; __entry->block_state = block_state; - __entry->rd_addr = rgd->rd_addr; - __entry->rd_free_clone = rgd->rd_free_clone; ), - TP_printk("%u,%u bmap %llu alloc %llu/%lu %s rg:%llu rf:%u", + TP_printk("%u,%u bmap %llu alloc %llu/%lu %s", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long long)__entry->inum, (unsigned long long)__entry->start, (unsigned long)__entry->len, - block_state_name(__entry->block_state), - (unsigned long long)__entry->rd_addr, - __entry->rd_free_clone) + block_state_name(__entry->block_state)) ); #endif /* _TRACE_GFS2_H */ diff --git a/trunk/fs/gfs2/trans.c b/trunk/fs/gfs2/trans.c index ad3e2fb763d7..86ac75d99d31 100644 --- a/trunk/fs/gfs2/trans.c +++ b/trunk/fs/gfs2/trans.c @@ -50,6 +50,8 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks, if (revokes) tr->tr_reserved += gfs2_struct2blk(sdp, revokes, sizeof(u64)); + INIT_LIST_HEAD(&tr->tr_list_buf); + gfs2_holder_init(sdp->sd_trans_gl, LM_ST_SHARED, 0, &tr->tr_t_gh); error = gfs2_glock_nq(&tr->tr_t_gh); @@ -91,21 +93,10 @@ static void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks) up_read(&sdp->sd_log_flush_lock); } -static void gfs2_print_trans(const struct gfs2_trans *tr) -{ - print_symbol(KERN_WARNING "GFS2: Transaction created at: %s\n", tr->tr_ip); - printk(KERN_WARNING "GFS2: blocks=%u revokes=%u reserved=%u touched=%d\n", - tr->tr_blocks, tr->tr_revokes, tr->tr_reserved, tr->tr_touched); - printk(KERN_WARNING "GFS2: Buf %u/%u Databuf %u/%u Revoke %u/%u\n", - tr->tr_num_buf_new, tr->tr_num_buf_rm, - tr->tr_num_databuf_new, tr->tr_num_databuf_rm, - tr->tr_num_revoke, tr->tr_num_revoke_rm); -} - void gfs2_trans_end(struct gfs2_sbd *sdp) { struct gfs2_trans *tr = current->journal_info; - s64 nbuf; + BUG_ON(!tr); current->journal_info = NULL; @@ -119,13 +110,16 @@ void gfs2_trans_end(struct gfs2_sbd *sdp) return; } - nbuf = tr->tr_num_buf_new + tr->tr_num_databuf_new; - nbuf -= tr->tr_num_buf_rm; - nbuf -= tr->tr_num_databuf_rm; - - if (gfs2_assert_withdraw(sdp, (nbuf <= tr->tr_blocks) && - (tr->tr_num_revoke <= tr->tr_revokes))) - gfs2_print_trans(tr); + if (gfs2_assert_withdraw(sdp, tr->tr_num_buf <= tr->tr_blocks)) { + fs_err(sdp, "tr_num_buf = %u, tr_blocks = %u ", + tr->tr_num_buf, tr->tr_blocks); + print_symbol(KERN_WARNING "GFS2: Transaction created at: %s\n", tr->tr_ip); + } + if (gfs2_assert_withdraw(sdp, tr->tr_num_revoke <= tr->tr_revokes)) { + fs_err(sdp, "tr_num_revoke = %u, tr_revokes = %u ", + tr->tr_num_revoke, tr->tr_revokes); + print_symbol(KERN_WARNING "GFS2: Transaction created at: %s\n", tr->tr_ip); + } gfs2_log_commit(sdp, tr); if (tr->tr_t_gh.gh_gl) { @@ -158,16 +152,16 @@ void gfs2_trans_add_bh(struct gfs2_glock *gl, struct buffer_head *bh, int meta) gfs2_attach_bufdata(gl, bh, meta); bd = bh->b_private; } - lops_add(sdp, bd); + lops_add(sdp, &bd->bd_le); } void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) { - BUG_ON(!list_empty(&bd->bd_list)); + BUG_ON(!list_empty(&bd->bd_le.le_list)); BUG_ON(!list_empty(&bd->bd_ail_st_list)); BUG_ON(!list_empty(&bd->bd_ail_gl_list)); - lops_init_le(bd, &gfs2_revoke_lops); - lops_add(sdp, bd); + lops_init_le(&bd->bd_le, &gfs2_revoke_lops); + lops_add(sdp, &bd->bd_le); } void gfs2_trans_add_unrevoke(struct gfs2_sbd *sdp, u64 blkno, unsigned int len) @@ -177,9 +171,9 @@ void gfs2_trans_add_unrevoke(struct gfs2_sbd *sdp, u64 blkno, unsigned int len) unsigned int n = len; gfs2_log_lock(sdp); - list_for_each_entry_safe(bd, tmp, &sdp->sd_log_le_revoke, bd_list) { + list_for_each_entry_safe(bd, tmp, &sdp->sd_log_le_revoke, bd_le.le_list) { if ((bd->bd_blkno >= blkno) && (bd->bd_blkno < (blkno + len))) { - list_del_init(&bd->bd_list); + list_del_init(&bd->bd_le.le_list); gfs2_assert_withdraw(sdp, sdp->sd_log_num_revoke); sdp->sd_log_num_revoke--; kmem_cache_free(gfs2_bufdata_cachep, bd); diff --git a/trunk/fs/gfs2/util.c b/trunk/fs/gfs2/util.c index f00d7c5744f6..9e7765e8e7b0 100644 --- a/trunk/fs/gfs2/util.c +++ b/trunk/fs/gfs2/util.c @@ -25,8 +25,7 @@ struct kmem_cache *gfs2_inode_cachep __read_mostly; struct kmem_cache *gfs2_bufdata_cachep __read_mostly; struct kmem_cache *gfs2_rgrpd_cachep __read_mostly; struct kmem_cache *gfs2_quotad_cachep __read_mostly; -struct kmem_cache *gfs2_rsrv_cachep __read_mostly; -mempool_t *gfs2_page_pool __read_mostly; +mempool_t *gfs2_bh_pool __read_mostly; void gfs2_assert_i(struct gfs2_sbd *sdp) { diff --git a/trunk/fs/gfs2/util.h b/trunk/fs/gfs2/util.h index 3586b0dd6aa7..a4ce76c67dbb 100644 --- a/trunk/fs/gfs2/util.h +++ b/trunk/fs/gfs2/util.h @@ -152,8 +152,7 @@ extern struct kmem_cache *gfs2_inode_cachep; extern struct kmem_cache *gfs2_bufdata_cachep; extern struct kmem_cache *gfs2_rgrpd_cachep; extern struct kmem_cache *gfs2_quotad_cachep; -extern struct kmem_cache *gfs2_rsrv_cachep; -extern mempool_t *gfs2_page_pool; +extern mempool_t *gfs2_bh_pool; static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt, unsigned int *p) diff --git a/trunk/fs/hfsplus/catalog.c b/trunk/fs/hfsplus/catalog.c index ec2a9c23f0c9..4dfbfec357e8 100644 --- a/trunk/fs/hfsplus/catalog.c +++ b/trunk/fs/hfsplus/catalog.c @@ -366,10 +366,6 @@ int hfsplus_rename_cat(u32 cnid, err = hfs_brec_find(&src_fd); if (err) goto out; - if (src_fd.entrylength > sizeof(entry) || src_fd.entrylength < 0) { - err = -EIO; - goto out; - } hfs_bnode_read(src_fd.bnode, &entry, src_fd.entryoffset, src_fd.entrylength); diff --git a/trunk/fs/hfsplus/dir.c b/trunk/fs/hfsplus/dir.c index 26b53fb09f68..88e155f895c6 100644 --- a/trunk/fs/hfsplus/dir.c +++ b/trunk/fs/hfsplus/dir.c @@ -150,11 +150,6 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) filp->f_pos++; /* fall through */ case 1: - if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) { - err = -EIO; - goto out; - } - hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); if (be16_to_cpu(entry.type) != HFSPLUS_FOLDER_THREAD) { @@ -186,12 +181,6 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) err = -EIO; goto out; } - - if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) { - err = -EIO; - goto out; - } - hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); type = be16_to_cpu(entry.type); diff --git a/trunk/fs/jffs2/gc.c b/trunk/fs/jffs2/gc.c index 5a2dec2b064c..ad271c70aa25 100644 --- a/trunk/fs/jffs2/gc.c +++ b/trunk/fs/jffs2/gc.c @@ -234,8 +234,8 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) return 0; jffs2_dbg(1, "No progress from erasing block; doing GC anyway\n"); - mutex_lock(&c->alloc_sem); spin_lock(&c->erase_completion_lock); + mutex_lock(&c->alloc_sem); } /* First, work out which block we're garbage-collecting */ diff --git a/trunk/fs/libfs.c b/trunk/fs/libfs.c index f86ec27a4230..18d08f5db53a 100644 --- a/trunk/fs/libfs.c +++ b/trunk/fs/libfs.c @@ -68,7 +68,7 @@ struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, struct na int dcache_dir_open(struct inode *inode, struct file *file) { - static struct qstr cursor_name = QSTR_INIT(".", 1); + static struct qstr cursor_name = {.len = 1, .name = "."}; file->private_data = d_alloc(file->f_path.dentry, &cursor_name); @@ -225,7 +225,7 @@ struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name, struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL); struct dentry *dentry; struct inode *root; - struct qstr d_name = QSTR_INIT(name, strlen(name)); + struct qstr d_name = {.name = name, .len = strlen(name)}; if (IS_ERR(s)) return ERR_CAST(s); diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index f9e883c1b856..0062dd17eb55 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -116,37 +116,47 @@ * POSIX.1 2.4: an empty pathname is invalid (ENOENT). * PATH_MAX includes the nul terminator --RR. */ +static int do_getname(const char __user *filename, char *page) +{ + int retval; + unsigned long len = PATH_MAX; + + if (!segment_eq(get_fs(), KERNEL_DS)) { + if ((unsigned long) filename >= TASK_SIZE) + return -EFAULT; + if (TASK_SIZE - (unsigned long) filename < PATH_MAX) + len = TASK_SIZE - (unsigned long) filename; + } + + retval = strncpy_from_user(page, filename, len); + if (retval > 0) { + if (retval < len) + return 0; + return -ENAMETOOLONG; + } else if (!retval) + retval = -ENOENT; + return retval; +} + static char *getname_flags(const char __user *filename, int flags, int *empty) { - char *result = __getname(), *err; - int len; + char *result = __getname(); + int retval; - if (unlikely(!result)) + if (!result) return ERR_PTR(-ENOMEM); - len = strncpy_from_user(result, filename, PATH_MAX); - err = ERR_PTR(len); - if (unlikely(len < 0)) - goto error; - - /* The empty path is special. */ - if (unlikely(!len)) { - if (empty) + retval = do_getname(filename, result); + if (retval < 0) { + if (retval == -ENOENT && empty) *empty = 1; - err = ERR_PTR(-ENOENT); - if (!(flags & LOOKUP_EMPTY)) - goto error; - } - - err = ERR_PTR(-ENAMETOOLONG); - if (likely(len < PATH_MAX)) { - audit_getname(result); - return result; + if (retval != -ENOENT || !(flags & LOOKUP_EMPTY)) { + __putname(result); + return ERR_PTR(retval); + } } - -error: - __putname(result); - return err; + audit_getname(result); + return result; } char *getname(const char __user * filename) @@ -1144,25 +1154,12 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, */ if (nd->flags & LOOKUP_RCU) { unsigned seq; - dentry = __d_lookup_rcu(parent, name, &seq, nd->inode); + *inode = nd->inode; + dentry = __d_lookup_rcu(parent, name, &seq, inode); if (!dentry) goto unlazy; - /* - * This sequence count validates that the inode matches - * the dentry name information from lookup. - */ - *inode = dentry->d_inode; - if (read_seqcount_retry(&dentry->d_seq, seq)) - return -ECHILD; - - /* - * This sequence count validates that the parent had no - * changes while we did the lookup of the dentry above. - * - * The memory barrier in read_seqcount_begin of child is - * enough, we can use __read_seqcount_retry here. - */ + /* Memory barrier in read_seqcount_begin of child is enough */ if (__read_seqcount_retry(&parent->d_seq, nd->seq)) return -ECHILD; nd->seq = seq; @@ -1432,7 +1429,7 @@ unsigned int full_name_hash(const unsigned char *name, unsigned int len) unsigned long hash = 0; for (;;) { - a = load_unaligned_zeropad(name); + a = *(unsigned long *)name; if (len < sizeof(unsigned long)) break; hash += a; @@ -1462,7 +1459,7 @@ static inline unsigned long hash_name(const char *name, unsigned int *hashp) do { hash = (hash + a) * 9; len += sizeof(unsigned long); - a = load_unaligned_zeropad(name+len); + a = *(unsigned long *)(name+len); /* Do we have any NUL or '/' bytes in this word? */ mask = has_zero(a) | has_zero(a ^ REPEAT_BYTE('/')); } while (!mask); diff --git a/trunk/fs/nfs/dir.c b/trunk/fs/nfs/dir.c index eedd24d0ad2e..8789210c6905 100644 --- a/trunk/fs/nfs/dir.c +++ b/trunk/fs/nfs/dir.c @@ -477,7 +477,10 @@ int nfs_same_file(struct dentry *dentry, struct nfs_entry *entry) static void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) { - struct qstr filename = QSTR_INIT(entry->name, entry->len); + struct qstr filename = { + .len = entry->len, + .name = entry->name, + }; struct dentry *dentry; struct dentry *alias; struct inode *dir = parent->d_inode; diff --git a/trunk/fs/nfs/nfs3proc.c b/trunk/fs/nfs/nfs3proc.c index 75c68299358e..5242eae6711a 100644 --- a/trunk/fs/nfs/nfs3proc.c +++ b/trunk/fs/nfs/nfs3proc.c @@ -398,7 +398,8 @@ nfs3_proc_remove(struct inode *dir, struct qstr *name) { struct nfs_removeargs arg = { .fh = NFS_FH(dir), - .name = *name, + .name.len = name->len, + .name.name = name->name, }; struct nfs_removeres res; struct rpc_message msg = { diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c index ab985f6f0da8..99650aaf8937 100644 --- a/trunk/fs/nfs/nfs4proc.c +++ b/trunk/fs/nfs/nfs4proc.c @@ -2782,7 +2782,8 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name) struct nfs_server *server = NFS_SERVER(dir); struct nfs_removeargs args = { .fh = NFS_FH(dir), - .name = *name, + .name.len = name->len, + .name.name = name->name, .bitmask = server->attr_bitmask, }; struct nfs_removeres res = { diff --git a/trunk/fs/nfs/proc.c b/trunk/fs/nfs/proc.c index d6408b6437de..b63b6f4d14fb 100644 --- a/trunk/fs/nfs/proc.c +++ b/trunk/fs/nfs/proc.c @@ -335,7 +335,8 @@ nfs_proc_remove(struct inode *dir, struct qstr *name) { struct nfs_removeargs arg = { .fh = NFS_FH(dir), - .name = *name, + .name.len = name->len, + .name.name = name->name, }; struct rpc_message msg = { .rpc_proc = &nfs_procedures[NFSPROC_REMOVE], diff --git a/trunk/fs/nilfs2/namei.c b/trunk/fs/nilfs2/namei.c index 0bb2c2010b95..fce2bbee66d4 100644 --- a/trunk/fs/nilfs2/namei.c +++ b/trunk/fs/nilfs2/namei.c @@ -441,7 +441,7 @@ static struct dentry *nilfs_get_parent(struct dentry *child) { unsigned long ino; struct inode *inode; - struct qstr dotdot = QSTR_INIT("..", 2); + struct qstr dotdot = {.name = "..", .len = 2}; struct nilfs_root *root; ino = nilfs_inode_by_name(child->d_inode, &dotdot); diff --git a/trunk/fs/open.c b/trunk/fs/open.c index 5eccdcea2d1b..5720854156db 100644 --- a/trunk/fs/open.c +++ b/trunk/fs/open.c @@ -681,7 +681,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, f->f_op = fops_get(inode->i_fop); - error = security_file_open(f, cred); + error = security_dentry_open(f, cred); if (error) goto cleanup_all; diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index 57b8159f26f3..1c8b280146d7 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -1799,15 +1799,10 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) if (task) { files = get_files_struct(task); if (files) { - struct file *file; rcu_read_lock(); - file = fcheck_files(files, fd); - if (file) { - unsigned i_mode, f_mode = file->f_mode; - + if (fcheck_files(files, fd)) { rcu_read_unlock(); put_files_struct(files); - if (task_dumpable(task)) { rcu_read_lock(); cred = __task_cred(task); @@ -1818,14 +1813,7 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) inode->i_uid = 0; inode->i_gid = 0; } - - i_mode = S_IFLNK; - if (f_mode & FMODE_READ) - i_mode |= S_IRUSR | S_IXUSR; - if (f_mode & FMODE_WRITE) - i_mode |= S_IWUSR | S_IXUSR; - inode->i_mode = i_mode; - + inode->i_mode &= ~(S_ISUID | S_ISGID); security_task_to_inode(task, inode); put_task_struct(task); return 1; @@ -1849,6 +1837,8 @@ static struct dentry *proc_fd_instantiate(struct inode *dir, struct dentry *dentry, struct task_struct *task, const void *ptr) { unsigned fd = *(const unsigned *)ptr; + struct file *file; + struct files_struct *files; struct inode *inode; struct proc_inode *ei; struct dentry *error = ERR_PTR(-ENOENT); @@ -1858,6 +1848,25 @@ static struct dentry *proc_fd_instantiate(struct inode *dir, goto out; ei = PROC_I(inode); ei->fd = fd; + files = get_files_struct(task); + if (!files) + goto out_iput; + inode->i_mode = S_IFLNK; + + /* + * We are not taking a ref to the file structure, so we must + * hold ->file_lock. + */ + spin_lock(&files->file_lock); + file = fcheck_files(files, fd); + if (!file) + goto out_unlock; + if (file->f_mode & FMODE_READ) + inode->i_mode |= S_IRUSR | S_IXUSR; + if (file->f_mode & FMODE_WRITE) + inode->i_mode |= S_IWUSR | S_IXUSR; + spin_unlock(&files->file_lock); + put_files_struct(files); inode->i_op = &proc_pid_link_inode_operations; inode->i_size = 64; @@ -1870,6 +1879,12 @@ static struct dentry *proc_fd_instantiate(struct inode *dir, out: return error; +out_unlock: + spin_unlock(&files->file_lock); + put_files_struct(files); +out_iput: + iput(inode); + goto out; } static struct dentry *proc_lookupfd_common(struct inode *dir, @@ -2162,16 +2177,16 @@ static struct dentry *proc_map_files_lookup(struct inode *dir, goto out; result = ERR_PTR(-EACCES); - if (!ptrace_may_access(task, PTRACE_MODE_READ)) + if (lock_trace(task)) goto out_put_task; result = ERR_PTR(-ENOENT); if (dname_to_vma_addr(dentry, &vm_start, &vm_end)) - goto out_put_task; + goto out_unlock; mm = get_task_mm(task); if (!mm) - goto out_put_task; + goto out_unlock; down_read(&mm->mmap_sem); vma = find_exact_vma(mm, vm_start, vm_end); @@ -2183,6 +2198,8 @@ static struct dentry *proc_map_files_lookup(struct inode *dir, out_no_vma: up_read(&mm->mmap_sem); mmput(mm); +out_unlock: + unlock_trace(task); out_put_task: put_task_struct(task); out: @@ -2216,7 +2233,7 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir) goto out; ret = -EACCES; - if (!ptrace_may_access(task, PTRACE_MODE_READ)) + if (lock_trace(task)) goto out_put_task; ret = 0; @@ -2224,12 +2241,12 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir) case 0: ino = inode->i_ino; if (filldir(dirent, ".", 1, 0, ino, DT_DIR) < 0) - goto out_put_task; + goto out_unlock; filp->f_pos++; case 1: ino = parent_ino(dentry); if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0) - goto out_put_task; + goto out_unlock; filp->f_pos++; default: { @@ -2240,7 +2257,7 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir) mm = get_task_mm(task); if (!mm) - goto out_put_task; + goto out_unlock; down_read(&mm->mmap_sem); nr_files = 0; @@ -2270,7 +2287,7 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir) flex_array_free(fa); up_read(&mm->mmap_sem); mmput(mm); - goto out_put_task; + goto out_unlock; } for (i = 0, vma = mm->mmap, pos = 2; vma; vma = vma->vm_next) { @@ -2315,6 +2332,8 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir) } } +out_unlock: + unlock_trace(task); out_put_task: put_task_struct(task); out: diff --git a/trunk/fs/proc/task_mmu.c b/trunk/fs/proc/task_mmu.c index 1030a716d155..2d60492d6df8 100644 --- a/trunk/fs/proc/task_mmu.c +++ b/trunk/fs/proc/task_mmu.c @@ -747,8 +747,6 @@ static void pte_to_pagemap_entry(pagemap_entry_t *pme, pte_t pte) else if (pte_present(pte)) *pme = make_pme(PM_PFRAME(pte_pfn(pte)) | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT); - else - *pme = make_pme(PM_NOT_PRESENT); } #ifdef CONFIG_TRANSPARENT_HUGEPAGE @@ -763,8 +761,6 @@ static void thp_pmd_to_pagemap_entry(pagemap_entry_t *pme, if (pmd_present(pmd)) *pme = make_pme(PM_PFRAME(pmd_pfn(pmd) + offset) | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT); - else - *pme = make_pme(PM_NOT_PRESENT); } #else static inline void thp_pmd_to_pagemap_entry(pagemap_entry_t *pme, @@ -805,10 +801,8 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, /* check to see if we've left 'vma' behind * and need a new, higher one */ - if (vma && (addr >= vma->vm_end)) { + if (vma && (addr >= vma->vm_end)) vma = find_vma(walk->mm, addr); - pme = make_pme(PM_NOT_PRESENT); - } /* check that 'vma' actually covers this address, * and that it isn't a huge page vma */ @@ -836,8 +830,6 @@ static void huge_pte_to_pagemap_entry(pagemap_entry_t *pme, if (pte_present(pte)) *pme = make_pme(PM_PFRAME(pte_pfn(pte) + offset) | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT); - else - *pme = make_pme(PM_NOT_PRESENT); } /* This function walks within one hugetlb entry in the single call */ @@ -847,7 +839,7 @@ static int pagemap_hugetlb_range(pte_t *pte, unsigned long hmask, { struct pagemapread *pm = walk->private; int err = 0; - pagemap_entry_t pme; + pagemap_entry_t pme = make_pme(PM_NOT_PRESENT); for (; addr != end; addr += PAGE_SIZE) { int offset = (addr & ~hmask) >> PAGE_SHIFT; diff --git a/trunk/fs/stat.c b/trunk/fs/stat.c index 0cef3366a919..c733dc5753ae 100644 --- a/trunk/fs/stat.c +++ b/trunk/fs/stat.c @@ -57,13 +57,12 @@ EXPORT_SYMBOL(vfs_getattr); int vfs_fstat(unsigned int fd, struct kstat *stat) { - int fput_needed; - struct file *f = fget_light(fd, &fput_needed); + struct file *f = fget(fd); int error = -EBADF; if (f) { error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, stat); - fput_light(f, fput_needed); + fput(f); } return error; } @@ -191,32 +190,24 @@ SYSCALL_DEFINE2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, stat #endif /* __ARCH_WANT_OLD_STAT */ -#if BITS_PER_LONG == 32 -# define choose_32_64(a,b) a -#else -# define choose_32_64(a,b) b -#endif - -#define valid_dev(x) choose_32_64(old_valid_dev,new_valid_dev)(x) -#define encode_dev(x) choose_32_64(old_encode_dev,new_encode_dev)(x) - -#ifndef INIT_STRUCT_STAT_PADDING -# define INIT_STRUCT_STAT_PADDING(st) memset(&st, 0, sizeof(st)) -#endif - static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf) { struct stat tmp; - if (!valid_dev(stat->dev) || !valid_dev(stat->rdev)) - return -EOVERFLOW; #if BITS_PER_LONG == 32 - if (stat->size > MAX_NON_LFS) + if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev)) + return -EOVERFLOW; +#else + if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev)) return -EOVERFLOW; #endif - INIT_STRUCT_STAT_PADDING(tmp); - tmp.st_dev = encode_dev(stat->dev); + memset(&tmp, 0, sizeof(tmp)); +#if BITS_PER_LONG == 32 + tmp.st_dev = old_encode_dev(stat->dev); +#else + tmp.st_dev = new_encode_dev(stat->dev); +#endif tmp.st_ino = stat->ino; if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino) return -EOVERFLOW; @@ -226,7 +217,15 @@ static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf) return -EOVERFLOW; SET_UID(tmp.st_uid, stat->uid); SET_GID(tmp.st_gid, stat->gid); - tmp.st_rdev = encode_dev(stat->rdev); +#if BITS_PER_LONG == 32 + tmp.st_rdev = old_encode_dev(stat->rdev); +#else + tmp.st_rdev = new_encode_dev(stat->rdev); +#endif +#if BITS_PER_LONG == 32 + if (stat->size > MAX_NON_LFS) + return -EOVERFLOW; +#endif tmp.st_size = stat->size; tmp.st_atime = stat->atime.tv_sec; tmp.st_mtime = stat->mtime.tv_sec; @@ -328,15 +327,11 @@ SYSCALL_DEFINE3(readlink, const char __user *, path, char __user *, buf, /* ---------- LFS-64 ----------- */ #ifdef __ARCH_WANT_STAT64 -#ifndef INIT_STRUCT_STAT64_PADDING -# define INIT_STRUCT_STAT64_PADDING(st) memset(&st, 0, sizeof(st)) -#endif - static long cp_new_stat64(struct kstat *stat, struct stat64 __user *statbuf) { struct stat64 tmp; - INIT_STRUCT_STAT64_PADDING(tmp); + memset(&tmp, 0, sizeof(struct stat64)); #ifdef CONFIG_MIPS /* mips has weird padding, so we don't get 64 bits there */ if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev)) diff --git a/trunk/fs/ubifs/tnc.c b/trunk/fs/ubifs/tnc.c index abd51331345e..16ad84d8402f 100644 --- a/trunk/fs/ubifs/tnc.c +++ b/trunk/fs/ubifs/tnc.c @@ -2361,7 +2361,7 @@ int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, * by passing 'ubifs_tnc_remove_nm()' the same key but * an unmatchable name. */ - struct qstr noname = { .name = "" }; + struct qstr noname = { .len = 0, .name = "" }; err = dbg_check_tnc(c, 0); mutex_unlock(&c->tnc_mutex); diff --git a/trunk/fs/ubifs/xattr.c b/trunk/fs/ubifs/xattr.c index 7a8bafa19c9f..85b272268754 100644 --- a/trunk/fs/ubifs/xattr.c +++ b/trunk/fs/ubifs/xattr.c @@ -298,7 +298,7 @@ int ubifs_setxattr(struct dentry *dentry, const char *name, { struct inode *inode, *host = dentry->d_inode; struct ubifs_info *c = host->i_sb->s_fs_info; - struct qstr nm = QSTR_INIT(name, strlen(name)); + struct qstr nm = { .name = name, .len = strlen(name) }; struct ubifs_dent_node *xent; union ubifs_key key; int err, type; @@ -361,7 +361,7 @@ ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf, { struct inode *inode, *host = dentry->d_inode; struct ubifs_info *c = host->i_sb->s_fs_info; - struct qstr nm = QSTR_INIT(name, strlen(name)); + struct qstr nm = { .name = name, .len = strlen(name) }; struct ubifs_inode *ui; struct ubifs_dent_node *xent; union ubifs_key key; @@ -524,7 +524,7 @@ int ubifs_removexattr(struct dentry *dentry, const char *name) { struct inode *inode, *host = dentry->d_inode; struct ubifs_info *c = host->i_sb->s_fs_info; - struct qstr nm = QSTR_INIT(name, strlen(name)); + struct qstr nm = { .name = name, .len = strlen(name) }; struct ubifs_dent_node *xent; union ubifs_key key; int err; diff --git a/trunk/fs/udf/namei.c b/trunk/fs/udf/namei.c index a165c66e3eef..38de8f234b94 100644 --- a/trunk/fs/udf/namei.c +++ b/trunk/fs/udf/namei.c @@ -1193,7 +1193,7 @@ static struct dentry *udf_get_parent(struct dentry *child) { struct kernel_lb_addr tloc; struct inode *inode = NULL; - struct qstr dotdot = QSTR_INIT("..", 2); + struct qstr dotdot = {.name = "..", .len = 2}; struct fileIdentDesc cfi; struct udf_fileident_bh fibh; diff --git a/trunk/fs/ufs/super.c b/trunk/fs/ufs/super.c index 302f340d0071..ac8e279eccc6 100644 --- a/trunk/fs/ufs/super.c +++ b/trunk/fs/ufs/super.c @@ -146,7 +146,10 @@ static struct dentry *ufs_fh_to_parent(struct super_block *sb, struct fid *fid, static struct dentry *ufs_get_parent(struct dentry *child) { - struct qstr dot_dot = QSTR_INIT("..", 2); + struct qstr dot_dot = { + .name = "..", + .len = 2, + }; ino_t ino; ino = ufs_inode_by_name(child->d_inode, &dot_dot); diff --git a/trunk/include/acpi/actypes.h b/trunk/include/acpi/actypes.h index e8bcc4742e0e..eba66043cf1b 100644 --- a/trunk/include/acpi/actypes.h +++ b/trunk/include/acpi/actypes.h @@ -499,10 +499,9 @@ typedef u64 acpi_integer; #define ACPI_STATE_D0 (u8) 0 #define ACPI_STATE_D1 (u8) 1 #define ACPI_STATE_D2 (u8) 2 -#define ACPI_STATE_D3_HOT (u8) 3 -#define ACPI_STATE_D3 (u8) 4 -#define ACPI_STATE_D3_COLD ACPI_STATE_D3 -#define ACPI_D_STATES_MAX ACPI_STATE_D3 +#define ACPI_STATE_D3 (u8) 3 +#define ACPI_STATE_D3_COLD (u8) 4 +#define ACPI_D_STATES_MAX ACPI_STATE_D3_COLD #define ACPI_D_STATE_COUNT 5 #define ACPI_STATE_C0 (u8) 0 diff --git a/trunk/include/asm-generic/pci-bridge.h b/trunk/include/asm-generic/pci-bridge.h index 20db2e5a0a69..a5b5d5a89a4f 100644 --- a/trunk/include/asm-generic/pci-bridge.h +++ b/trunk/include/asm-generic/pci-bridge.h @@ -30,12 +30,6 @@ enum { PCI_ENABLE_PROC_DOMAINS = 0x00000010, /* ... except for domain 0 */ PCI_COMPAT_DOMAIN_0 = 0x00000020, - - /* PCIe downstream ports are bridges that normally lead to only a - * device 0, but if this is set, we scan all possible devices, not - * just device 0. - */ - PCI_SCAN_ALL_PCIE_DEVS = 0x00000040, }; #ifdef CONFIG_PCI diff --git a/trunk/include/asm-generic/siginfo.h b/trunk/include/asm-generic/siginfo.h index 8ed67779fc09..5e5e3865f1ed 100644 --- a/trunk/include/asm-generic/siginfo.h +++ b/trunk/include/asm-generic/siginfo.h @@ -98,18 +98,9 @@ typedef struct siginfo { __ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */ int _fd; } _sigpoll; - - /* SIGSYS */ - struct { - void __user *_call_addr; /* calling user insn */ - int _syscall; /* triggering system call number */ - unsigned int _arch; /* AUDIT_ARCH_* of syscall */ - } _sigsys; } _sifields; } __ARCH_SI_ATTRIBUTES siginfo_t; -/* If the arch shares siginfo, then it has SIGSYS. */ -#define __ARCH_SIGSYS #endif /* @@ -133,11 +124,6 @@ typedef struct siginfo { #define si_addr_lsb _sifields._sigfault._addr_lsb #define si_band _sifields._sigpoll._band #define si_fd _sifields._sigpoll._fd -#ifdef __ARCH_SIGSYS -#define si_call_addr _sifields._sigsys._call_addr -#define si_syscall _sifields._sigsys._syscall -#define si_arch _sifields._sigsys._arch -#endif #ifdef __KERNEL__ #define __SI_MASK 0xffff0000u @@ -148,7 +134,6 @@ typedef struct siginfo { #define __SI_CHLD (4 << 16) #define __SI_RT (5 << 16) #define __SI_MESGQ (6 << 16) -#define __SI_SYS (7 << 16) #define __SI_CODE(T,N) ((T) | ((N) & 0xffff)) #else #define __SI_KILL 0 @@ -158,7 +143,6 @@ typedef struct siginfo { #define __SI_CHLD 0 #define __SI_RT 0 #define __SI_MESGQ 0 -#define __SI_SYS 0 #define __SI_CODE(T,N) (N) #endif @@ -255,12 +239,6 @@ typedef struct siginfo { #define POLL_HUP (__SI_POLL|6) /* device disconnected */ #define NSIGPOLL 6 -/* - * SIGSYS si_codes - */ -#define SYS_SECCOMP (__SI_SYS|1) /* seccomp triggered */ -#define NSIGSYS 1 - /* * sigevent definitions * diff --git a/trunk/include/asm-generic/statfs.h b/trunk/include/asm-generic/statfs.h index c749af9c0983..0fd28e028de1 100644 --- a/trunk/include/asm-generic/statfs.h +++ b/trunk/include/asm-generic/statfs.h @@ -15,7 +15,7 @@ typedef __kernel_fsid_t fsid_t; * with a 10' pole. */ #ifndef __statfs_word -#if __BITS_PER_LONG == 64 +#if BITS_PER_LONG == 64 #define __statfs_word long #else #define __statfs_word __u32 diff --git a/trunk/include/asm-generic/syscall.h b/trunk/include/asm-generic/syscall.h index 5b09392db673..5c122ae6bfa6 100644 --- a/trunk/include/asm-generic/syscall.h +++ b/trunk/include/asm-generic/syscall.h @@ -142,18 +142,4 @@ void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs, unsigned int i, unsigned int n, const unsigned long *args); -/** - * syscall_get_arch - return the AUDIT_ARCH for the current system call - * @task: task of interest, must be in system call entry tracing - * @regs: task_pt_regs() of @task - * - * Returns the AUDIT_ARCH_* based on the system call convention in use. - * - * It's only valid to call this when @task is stopped on entry to a system - * call, due to %TIF_SYSCALL_TRACE, %TIF_SYSCALL_AUDIT, or %TIF_SECCOMP. - * - * Architectures which permit CONFIG_HAVE_ARCH_SECCOMP_FILTER must - * provide an implementation of this. - */ -int syscall_get_arch(struct task_struct *task, struct pt_regs *regs); #endif /* _ASM_SYSCALL_H */ diff --git a/trunk/include/keys/keyring-type.h b/trunk/include/keys/keyring-type.h index cf49159b0e3a..843f872a4b63 100644 --- a/trunk/include/keys/keyring-type.h +++ b/trunk/include/keys/keyring-type.h @@ -24,7 +24,7 @@ struct keyring_list { unsigned short maxkeys; /* max keys this list can hold */ unsigned short nkeys; /* number of keys currently held */ unsigned short delkey; /* key to be unlinked by RCU */ - struct key __rcu *keys[0]; + struct key *keys[0]; }; diff --git a/trunk/include/linux/Kbuild b/trunk/include/linux/Kbuild index 0237b84ba541..3c9b616c834a 100644 --- a/trunk/include/linux/Kbuild +++ b/trunk/include/linux/Kbuild @@ -167,6 +167,7 @@ header-y += if_arp.h header-y += if_bonding.h header-y += if_bridge.h header-y += if_cablemodem.h +header-y += if_ec.h header-y += if_eql.h header-y += if_ether.h header-y += if_fc.h @@ -185,6 +186,7 @@ header-y += if_pppox.h header-y += if_slip.h header-y += if_strip.h header-y += if_team.h +header-y += if_tr.h header-y += if_tun.h header-y += if_tunnel.h header-y += if_vlan.h @@ -330,7 +332,6 @@ header-y += scc.h header-y += sched.h header-y += screen_info.h header-y += sdla.h -header-y += seccomp.h header-y += securebits.h header-y += selinux_netlink.h header-y += sem.h diff --git a/trunk/include/linux/amba/bus.h b/trunk/include/linux/amba/bus.h index d36417158d8f..8d54f79457ba 100644 --- a/trunk/include/linux/amba/bus.h +++ b/trunk/include/linux/amba/bus.h @@ -63,14 +63,6 @@ struct amba_device *amba_device_alloc(const char *, resource_size_t, size_t); void amba_device_put(struct amba_device *); int amba_device_add(struct amba_device *, struct resource *); int amba_device_register(struct amba_device *, struct resource *); -struct amba_device *amba_apb_device_add(struct device *parent, const char *name, - resource_size_t base, size_t size, - int irq1, int irq2, void *pdata, - unsigned int periphid); -struct amba_device *amba_ahb_device_add(struct device *parent, const char *name, - resource_size_t base, size_t size, - int irq1, int irq2, void *pdata, - unsigned int periphid); void amba_device_unregister(struct amba_device *); struct amba_device *amba_find_device(const char *, struct device *, unsigned int, unsigned int); int amba_request_regions(struct amba_device *, const char *); diff --git a/trunk/include/linux/atmlec.h b/trunk/include/linux/atmlec.h index 302791e3ab2b..39c917fd1b96 100644 --- a/trunk/include/linux/atmlec.h +++ b/trunk/include/linux/atmlec.h @@ -21,6 +21,13 @@ /* Maximum number of LEC interfaces (tweakable) */ #define MAX_LEC_ITF 48 +/* + * From the total of MAX_LEC_ITF, last NUM_TR_DEVS are reserved for Token Ring. + * E.g. if MAX_LEC_ITF = 48 and NUM_TR_DEVS = 8, then lec0-lec39 are for + * Ethernet ELANs and lec40-lec47 are for Token Ring ELANS. + */ +#define NUM_TR_DEVS 8 + typedef enum { l_set_mac_addr, l_del_mac_addr, diff --git a/trunk/include/linux/audit.h b/trunk/include/linux/audit.h index 22f292a917a3..ed3ef1972496 100644 --- a/trunk/include/linux/audit.h +++ b/trunk/include/linux/audit.h @@ -463,7 +463,7 @@ extern void audit_putname(const char *name); extern void __audit_inode(const char *name, const struct dentry *dentry); extern void __audit_inode_child(const struct dentry *dentry, const struct inode *parent); -extern void __audit_seccomp(unsigned long syscall, long signr, int code); +extern void __audit_seccomp(unsigned long syscall); extern void __audit_ptrace(struct task_struct *t); static inline int audit_dummy_context(void) @@ -508,10 +508,10 @@ static inline void audit_inode_child(const struct dentry *dentry, } void audit_core_dumps(long signr); -static inline void audit_seccomp(unsigned long syscall, long signr, int code) +static inline void audit_seccomp(unsigned long syscall) { if (unlikely(!audit_dummy_context())) - __audit_seccomp(syscall, signr, code); + __audit_seccomp(syscall); } static inline void audit_ptrace(struct task_struct *t) @@ -634,7 +634,7 @@ extern int audit_signals; #define audit_inode(n,d) do { (void)(d); } while (0) #define audit_inode_child(i,p) do { ; } while (0) #define audit_core_dumps(i) do { ; } while (0) -#define audit_seccomp(i,s,c) do { ; } while (0) +#define audit_seccomp(i) do { ; } while (0) #define auditsc_get_stamp(c,t,s) (0) #define audit_get_loginuid(t) (-1) #define audit_get_sessionid(t) (-1) diff --git a/trunk/include/linux/blkdev.h b/trunk/include/linux/blkdev.h index 4d4ac24a263e..2aa24664a5b5 100644 --- a/trunk/include/linux/blkdev.h +++ b/trunk/include/linux/blkdev.h @@ -1,10 +1,9 @@ #ifndef _LINUX_BLKDEV_H #define _LINUX_BLKDEV_H -#include - #ifdef CONFIG_BLOCK +#include #include #include #include diff --git a/trunk/include/linux/clk.h b/trunk/include/linux/clk.h index 70cf722ac3af..b0252726df61 100644 --- a/trunk/include/linux/clk.h +++ b/trunk/include/linux/clk.h @@ -100,26 +100,6 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb); */ struct clk *clk_get(struct device *dev, const char *id); -/** - * devm_clk_get - lookup and obtain a managed reference to a clock producer. - * @dev: device for clock "consumer" - * @id: clock comsumer ID - * - * Returns a struct clk corresponding to the clock producer, or - * valid IS_ERR() condition containing errno. The implementation - * uses @dev and @id to determine the clock consumer, and thereby - * the clock producer. (IOW, @id may be identical strings, but - * clk_get may return different clock producers depending on @dev.) - * - * Drivers must assume that the clock source is not enabled. - * - * devm_clk_get should not be called from within interrupt context. - * - * The clock will automatically be freed when the device is unbound - * from the bus. - */ -struct clk *devm_clk_get(struct device *dev, const char *id); - /** * clk_prepare - prepare a clock source * @clk: clock source @@ -226,18 +206,6 @@ unsigned long clk_get_rate(struct clk *clk); */ void clk_put(struct clk *clk); -/** - * devm_clk_put - "free" a managed clock source - * @dev: device used to acuqire the clock - * @clk: clock source acquired with devm_clk_get() - * - * Note: drivers must ensure that all clk_enable calls made on this - * clock source are balanced by clk_disable calls prior to calling - * this function. - * - * clk_put should not be called from within interrupt context. - */ -void devm_clk_put(struct device *dev, struct clk *clk); /* * The remaining APIs are optional for machine class support. diff --git a/trunk/include/linux/clkdev.h b/trunk/include/linux/clkdev.h index a6a6f603103b..d9a4fd028c9d 100644 --- a/trunk/include/linux/clkdev.h +++ b/trunk/include/linux/clkdev.h @@ -40,7 +40,4 @@ void clkdev_drop(struct clk_lookup *cl); void clkdev_add_table(struct clk_lookup *, size_t); int clk_add_alias(const char *, const char *, char *, struct device *); -int clk_register_clkdev(struct clk *, const char *, const char *, ...); -int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t); - #endif diff --git a/trunk/include/linux/dcache.h b/trunk/include/linux/dcache.h index 094789ff3e9f..7e11f1418203 100644 --- a/trunk/include/linux/dcache.h +++ b/trunk/include/linux/dcache.h @@ -25,13 +25,6 @@ struct vfsmount; #define IS_ROOT(x) ((x) == (x)->d_parent) -/* The hash is always the low bits of hash_len */ -#ifdef __LITTLE_ENDIAN - #define HASH_LEN_DECLARE u32 hash; u32 len; -#else - #define HASH_LEN_DECLARE u32 len; u32 hash; -#endif - /* * "quick string" -- eases parameter passing, but more importantly * saves "metadata" about the string (ie length and the hash). @@ -40,19 +33,11 @@ struct vfsmount; * dentry. */ struct qstr { - union { - struct { - HASH_LEN_DECLARE; - }; - u64 hash_len; - }; + unsigned int hash; + unsigned int len; const unsigned char *name; }; -#define QSTR_INIT(n,l) { { { .len = l } }, .name = n } -#define hashlen_hash(hashlen) ((u32) (hashlen)) -#define hashlen_len(hashlen) ((u32)((hashlen) >> 32)) - struct dentry_stat_t { int nr_dentry; int nr_unused; @@ -297,7 +282,7 @@ extern struct dentry *d_hash_and_lookup(struct dentry *, struct qstr *); extern struct dentry *__d_lookup(struct dentry *, struct qstr *); extern struct dentry *__d_lookup_rcu(const struct dentry *parent, const struct qstr *name, - unsigned *seq, struct inode *inode); + unsigned *seq, struct inode **inode); /** * __d_rcu_to_refcount - take a refcount on dentry if sequence check is ok diff --git a/trunk/include/linux/dmar.h b/trunk/include/linux/dmar.h index b029d1aa2d12..731a60975101 100644 --- a/trunk/include/linux/dmar.h +++ b/trunk/include/linux/dmar.h @@ -114,6 +114,91 @@ struct irte { }; }; +#ifdef CONFIG_IRQ_REMAP +extern int intr_remapping_enabled; +extern int intr_remapping_supported(void); +extern int enable_intr_remapping(void); +extern void disable_intr_remapping(void); +extern int reenable_intr_remapping(int); + +extern int get_irte(int irq, struct irte *entry); +extern int modify_irte(int irq, struct irte *irte_modified); +extern int alloc_irte(struct intel_iommu *iommu, int irq, u16 count); +extern int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, + u16 sub_handle); +extern int map_irq_to_irte_handle(int irq, u16 *sub_handle); +extern int free_irte(int irq); + +extern struct intel_iommu *map_dev_to_ir(struct pci_dev *dev); +extern struct intel_iommu *map_ioapic_to_ir(int apic); +extern struct intel_iommu *map_hpet_to_ir(u8 id); +extern int set_ioapic_sid(struct irte *irte, int apic); +extern int set_hpet_sid(struct irte *irte, u8 id); +extern int set_msi_sid(struct irte *irte, struct pci_dev *dev); +#else +static inline int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) +{ + return -1; +} +static inline int modify_irte(int irq, struct irte *irte_modified) +{ + return -1; +} +static inline int free_irte(int irq) +{ + return -1; +} +static inline int map_irq_to_irte_handle(int irq, u16 *sub_handle) +{ + return -1; +} +static inline int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, + u16 sub_handle) +{ + return -1; +} +static inline struct intel_iommu *map_dev_to_ir(struct pci_dev *dev) +{ + return NULL; +} +static inline struct intel_iommu *map_ioapic_to_ir(int apic) +{ + return NULL; +} +static inline struct intel_iommu *map_hpet_to_ir(unsigned int hpet_id) +{ + return NULL; +} +static inline int set_ioapic_sid(struct irte *irte, int apic) +{ + return 0; +} +static inline int set_hpet_sid(struct irte *irte, u8 id) +{ + return -1; +} +static inline int set_msi_sid(struct irte *irte, struct pci_dev *dev) +{ + return 0; +} + +#define intr_remapping_enabled (0) + +static inline int enable_intr_remapping(void) +{ + return -1; +} + +static inline void disable_intr_remapping(void) +{ +} + +static inline int reenable_intr_remapping(int eim) +{ + return 0; +} +#endif + enum { IRQ_REMAP_XAPIC_MODE, IRQ_REMAP_X2APIC_MODE, diff --git a/trunk/include/linux/etherdevice.h b/trunk/include/linux/etherdevice.h index 3d406e0ede6d..c47631fac229 100644 --- a/trunk/include/linux/etherdevice.h +++ b/trunk/include/linux/etherdevice.h @@ -18,6 +18,8 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * + * WARNING: This move may well be temporary. This file will get merged with others RSN. + * */ #ifndef _LINUX_ETHERDEVICE_H #define _LINUX_ETHERDEVICE_H @@ -157,7 +159,7 @@ static inline void eth_hw_addr_random(struct net_device *dev) * @addr1: Pointer to a six-byte array containing the Ethernet address * @addr2: Pointer other six-byte array containing the Ethernet address * - * Compare two Ethernet addresses, returns 0 if equal, non-zero otherwise. + * Compare two ethernet addresses, returns 0 if equal, non-zero otherwise. * Unlike memcmp(), it doesn't return a value suitable for sorting. */ static inline unsigned compare_ether_addr(const u8 *addr1, const u8 *addr2) @@ -169,18 +171,6 @@ static inline unsigned compare_ether_addr(const u8 *addr1, const u8 *addr2) return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0; } -/** - * ether_addr_equal - Compare two Ethernet addresses - * @addr1: Pointer to a six-byte array containing the Ethernet address - * @addr2: Pointer other six-byte array containing the Ethernet address - * - * Compare two Ethernet addresses, returns true if equal - */ -static inline bool ether_addr_equal(const u8 *addr1, const u8 *addr2) -{ - return !compare_ether_addr(addr1, addr2); -} - static inline unsigned long zap_last_2bytes(unsigned long value) { #ifdef __BIG_ENDIAN @@ -191,34 +181,34 @@ static inline unsigned long zap_last_2bytes(unsigned long value) } /** - * ether_addr_equal_64bits - Compare two Ethernet addresses + * compare_ether_addr_64bits - Compare two Ethernet addresses * @addr1: Pointer to an array of 8 bytes * @addr2: Pointer to an other array of 8 bytes * - * Compare two Ethernet addresses, returns true if equal, false otherwise. - * + * Compare two ethernet addresses, returns 0 if equal, non-zero otherwise. + * Unlike memcmp(), it doesn't return a value suitable for sorting. * The function doesn't need any conditional branches and possibly uses * word memory accesses on CPU allowing cheap unaligned memory reads. - * arrays = { byte1, byte2, byte3, byte4, byte5, byte6, pad1, pad2 } + * arrays = { byte1, byte2, byte3, byte4, byte6, byte7, pad1, pad2} * - * Please note that alignment of addr1 & addr2 are only guaranteed to be 16 bits. + * Please note that alignment of addr1 & addr2 is only guaranted to be 16 bits. */ -static inline bool ether_addr_equal_64bits(const u8 addr1[6+2], - const u8 addr2[6+2]) +static inline unsigned compare_ether_addr_64bits(const u8 addr1[6+2], + const u8 addr2[6+2]) { #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS unsigned long fold = ((*(unsigned long *)addr1) ^ (*(unsigned long *)addr2)); if (sizeof(fold) == 8) - return zap_last_2bytes(fold) == 0; + return zap_last_2bytes(fold) != 0; fold |= zap_last_2bytes((*(unsigned long *)(addr1 + 4)) ^ (*(unsigned long *)(addr2 + 4))); - return fold == 0; + return fold != 0; #else - return ether_addr_equal(addr1, addr2); + return compare_ether_addr(addr1, addr2); #endif } @@ -230,23 +220,23 @@ static inline bool ether_addr_equal_64bits(const u8 addr1[6+2], * Compare passed address with all addresses of the device. Return true if the * address if one of the device addresses. * - * Note that this function calls ether_addr_equal_64bits() so take care of + * Note that this function calls compare_ether_addr_64bits() so take care of * the right padding. */ static inline bool is_etherdev_addr(const struct net_device *dev, const u8 addr[6 + 2]) { struct netdev_hw_addr *ha; - bool res = false; + int res = 1; rcu_read_lock(); for_each_dev_addr(dev, ha) { - res = ether_addr_equal_64bits(addr, ha->addr); - if (res) + res = compare_ether_addr_64bits(addr, ha->addr); + if (!res) break; } rcu_read_unlock(); - return res; + return !res; } #endif /* __KERNEL__ */ @@ -255,7 +245,7 @@ static inline bool is_etherdev_addr(const struct net_device *dev, * @a: Pointer to Ethernet header * @b: Pointer to Ethernet header * - * Compare two Ethernet headers, returns 0 if equal. + * Compare two ethernet headers, returns 0 if equal. * This assumes that the network header (i.e., IP header) is 4-byte * aligned OR the platform can handle unaligned access. This is the * case for all packets coming into netif_receive_skb or similar diff --git a/trunk/include/linux/ethtool.h b/trunk/include/linux/ethtool.h index e17fa7140588..89d68d837b6e 100644 --- a/trunk/include/linux/ethtool.h +++ b/trunk/include/linux/ethtool.h @@ -136,23 +136,6 @@ struct ethtool_eeprom { __u8 data[0]; }; -/** - * struct ethtool_modinfo - plugin module eeprom information - * @cmd: %ETHTOOL_GMODULEINFO - * @type: Standard the module information conforms to %ETH_MODULE_SFF_xxxx - * @eeprom_len: Length of the eeprom - * - * This structure is used to return the information to - * properly size memory for a subsequent call to %ETHTOOL_GMODULEEEPROM. - * The type code indicates the eeprom data format - */ -struct ethtool_modinfo { - __u32 cmd; - __u32 type; - __u32 eeprom_len; - __u32 reserved[8]; -}; - /** * struct ethtool_coalesce - coalescing parameters for IRQs and stats updates * @cmd: ETHTOOL_{G,S}COALESCE @@ -678,17 +661,12 @@ struct ethtool_flash { * %ETHTOOL_SET_DUMP * @version: FW version of the dump, filled in by driver * @flag: driver dependent flag for dump setting, filled in by driver during - * get and filled in by ethtool for set operation. - * flag must be initialized by macro ETH_FW_DUMP_DISABLE value when - * firmware dump is disabled. + * get and filled in by ethtool for set operation * @len: length of dump data, used as the length of the user buffer on entry to * %ETHTOOL_GET_DUMP_DATA and this is returned as dump length by driver * for %ETHTOOL_GET_DUMP_FLAG command * @data: data collected for get dump data operation */ - -#define ETH_FW_DUMP_DISABLE 0 - struct ethtool_dump { __u32 cmd; __u32 version; @@ -942,9 +920,6 @@ static inline u32 ethtool_rxfh_indir_default(u32 index, u32 n_rx_rings) * @get_ts_info: Get the time stamping and PTP hardware clock capabilities. * Drivers supporting transmit time stamps in software should set this to * ethtool_op_get_ts_info(). - * @get_module_info: Get the size and type of the eeprom contained within - * a plug-in module. - * @get_module_eeprom: Get the eeprom information from the plug-in module * * All operations are optional (i.e. the function pointer may be set * to %NULL) and callers must take this into account. Callers must @@ -1007,11 +982,6 @@ struct ethtool_ops { struct ethtool_dump *, void *); int (*set_dump)(struct net_device *, struct ethtool_dump *); int (*get_ts_info)(struct net_device *, struct ethtool_ts_info *); - int (*get_module_info)(struct net_device *, - struct ethtool_modinfo *); - int (*get_module_eeprom)(struct net_device *, - struct ethtool_eeprom *, u8 *); - }; #endif /* __KERNEL__ */ @@ -1087,8 +1057,6 @@ struct ethtool_ops { #define ETHTOOL_GET_DUMP_FLAG 0x0000003f /* Get dump settings */ #define ETHTOOL_GET_DUMP_DATA 0x00000040 /* Get dump data */ #define ETHTOOL_GET_TS_INFO 0x00000041 /* Get time stamping and PHC info */ -#define ETHTOOL_GMODULEINFO 0x00000042 /* Get plug-in module information */ -#define ETHTOOL_GMODULEEEPROM 0x00000043 /* Get plug-in module eeprom */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET @@ -1238,12 +1206,6 @@ struct ethtool_ops { #define RX_CLS_LOC_FIRST 0xfffffffe #define RX_CLS_LOC_LAST 0xfffffffd -/* EEPROM Standards for plug in modules */ -#define ETH_MODULE_SFF_8079 0x1 -#define ETH_MODULE_SFF_8079_LEN 256 -#define ETH_MODULE_SFF_8472 0x2 -#define ETH_MODULE_SFF_8472_LEN 512 - /* Reset flags */ /* The reset() operation must clear the flags for the components which * were actually reset. On successful return, the flags indicate the diff --git a/trunk/include/linux/filter.h b/trunk/include/linux/filter.h index 82b01357af8b..72090994d789 100644 --- a/trunk/include/linux/filter.h +++ b/trunk/include/linux/filter.h @@ -10,7 +10,6 @@ #ifdef __KERNEL__ #include -#include #endif /* @@ -134,16 +133,6 @@ struct sock_fprog { /* Required for SO_ATTACH_FILTER. */ #ifdef __KERNEL__ -#ifdef CONFIG_COMPAT -/* - * A struct sock_filter is architecture independent. - */ -struct compat_sock_fprog { - u16 len; - compat_uptr_t filter; /* struct sock_filter * */ -}; -#endif - struct sk_buff; struct sock; @@ -244,7 +233,6 @@ enum { BPF_S_ANC_RXHASH, BPF_S_ANC_CPU, BPF_S_ANC_ALU_XOR_X, - BPF_S_ANC_SECCOMP_LD_W, }; #endif /* __KERNEL__ */ diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index 25c40b9f848a..8de675523e46 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -2051,7 +2051,6 @@ extern void unregister_blkdev(unsigned int, const char *); extern struct block_device *bdget(dev_t); extern struct block_device *bdgrab(struct block_device *bdev); extern void bd_set_size(struct block_device *, loff_t size); -extern sector_t blkdev_max_block(struct block_device *bdev); extern void bd_forget(struct inode *inode); extern void bdput(struct block_device *); extern void invalidate_bdev(struct block_device *); diff --git a/trunk/include/linux/ftrace_event.h b/trunk/include/linux/ftrace_event.h index 176a939d1547..5f3f3be5af09 100644 --- a/trunk/include/linux/ftrace_event.h +++ b/trunk/include/linux/ftrace_event.h @@ -179,7 +179,6 @@ enum { TRACE_EVENT_FL_RECORDED_CMD_BIT, TRACE_EVENT_FL_CAP_ANY_BIT, TRACE_EVENT_FL_NO_SET_FILTER_BIT, - TRACE_EVENT_FL_IGNORE_ENABLE_BIT, }; enum { @@ -188,7 +187,6 @@ enum { TRACE_EVENT_FL_RECORDED_CMD = (1 << TRACE_EVENT_FL_RECORDED_CMD_BIT), TRACE_EVENT_FL_CAP_ANY = (1 << TRACE_EVENT_FL_CAP_ANY_BIT), TRACE_EVENT_FL_NO_SET_FILTER = (1 << TRACE_EVENT_FL_NO_SET_FILTER_BIT), - TRACE_EVENT_FL_IGNORE_ENABLE = (1 << TRACE_EVENT_FL_IGNORE_ENABLE_BIT), }; struct ftrace_event_call { diff --git a/trunk/include/linux/genhd.h b/trunk/include/linux/genhd.h index 017a7fb5a1fc..e61d3192448e 100644 --- a/trunk/include/linux/genhd.h +++ b/trunk/include/linux/genhd.h @@ -222,6 +222,12 @@ static inline void part_pack_uuid(const u8 *uuid_str, u8 *to) } } +static inline char *part_unpack_uuid(const u8 *uuid, char *out) +{ + sprintf(out, "%pU", uuid); + return out; +} + static inline int disk_max_parts(struct gendisk *disk) { if (disk->flags & GENHD_FL_EXT_DEVT) diff --git a/trunk/include/linux/i2c/twl.h b/trunk/include/linux/i2c/twl.h index 3993477103a5..1f90de0cfdbe 100644 --- a/trunk/include/linux/i2c/twl.h +++ b/trunk/include/linux/i2c/twl.h @@ -171,6 +171,8 @@ static inline int twl_class_is_ ##class(void) \ TWL_CLASS_IS(4030, TWL4030_CLASS_ID) TWL_CLASS_IS(6030, TWL6030_CLASS_ID) +#define TWL6025_SUBCLASS BIT(4) /* TWL6025 has changed registers */ + /* * Read and write single 8-bit registers */ @@ -744,17 +746,6 @@ struct twl_regulator_driver_data { void *data; unsigned long features; }; -/* chip-specific feature flags, for twl_regulator_driver_data.features */ -#define TWL4030_VAUX2 BIT(0) /* pre-5030 voltage ranges */ -#define TPS_SUBSET BIT(1) /* tps659[23]0 have fewer LDOs */ -#define TWL5031 BIT(2) /* twl5031 has different registers */ -#define TWL6030_CLASS BIT(3) /* TWL6030 class */ -#define TWL6025_SUBCLASS BIT(4) /* TWL6025 has changed registers */ -#define TWL4030_ALLOW_UNSUPPORTED BIT(5) /* Some voltages are possible - * but not officially supported. - * This flag is necessary to - * enable them. - */ /*----------------------------------------------------------------------*/ diff --git a/trunk/include/linux/ibmtr.h b/trunk/include/linux/ibmtr.h new file mode 100644 index 000000000000..06695b74d405 --- /dev/null +++ b/trunk/include/linux/ibmtr.h @@ -0,0 +1,373 @@ +#ifndef __LINUX_IBMTR_H__ +#define __LINUX_IBMTR_H__ + +/* Definitions for an IBM Token Ring card. */ +/* This file is distributed under the GNU GPL */ + +/* ported to the Alpha architecture 02/20/96 (just used the HZ macro) */ + +#define TR_RETRY_INTERVAL (30*HZ) /* 500 on PC = 5 s */ +#define TR_RST_TIME (msecs_to_jiffies(50)) /* 5 on PC = 50 ms */ +#define TR_BUSY_INTERVAL (msecs_to_jiffies(200)) /* 5 on PC = 200 ms */ +#define TR_SPIN_INTERVAL (3*HZ) /* 3 seconds before init timeout */ + +#define TR_ISA 1 +#define TR_MCA 2 +#define TR_ISAPNP 3 +#define NOTOK 0 + +#define IBMTR_SHARED_RAM_SIZE 0x10000 +#define IBMTR_IO_EXTENT 4 +#define IBMTR_MAX_ADAPTERS 4 + +#define CHANNEL_ID 0X1F30 +#define AIP 0X1F00 +#define AIPADAPTYPE 0X1FA0 +#define AIPDATARATE 0X1FA2 +#define AIPEARLYTOKEN 0X1FA4 +#define AIPAVAILSHRAM 0X1FA6 +#define AIPSHRAMPAGE 0X1FA8 +#define AIP4MBDHB 0X1FAA +#define AIP16MBDHB 0X1FAC +#define AIPFID 0X1FBA + +#define ADAPTRESET 0x1 /* Control Adapter reset (add to base) */ +#define ADAPTRESETREL 0x2 /* Release Adapter from reset ( """) */ +#define ADAPTINTREL 0x3 /* Adapter interrupt release */ + +#define GLOBAL_INT_ENABLE 0x02f0 + +/* MMIO bits 0-4 select register */ +#define RRR_EVEN 0x00 /* Shared RAM relocation registers - even and odd */ +/* Used to set the starting address of shared RAM */ +/* Bits 1 through 7 of this register map to bits 13 through 19 of the shared + RAM address.*/ +/* ie: 0x02 sets RAM address to ...ato! issy su wazzoo !! GODZILLA!!! */ +#define RRR_ODD 0x01 +/* Bits 2 and 3 of this register can be read to determine shared RAM size */ +/* 00 for 8k, 01 for 16k, 10 for 32k, 11 for 64k */ +#define WRBR_EVEN 0x02 /* Write region base registers - even and odd */ +#define WRBR_ODD 0x03 +#define WWOR_EVEN 0x04 /* Write window open registers - even and odd */ +#define WWOR_ODD 0x05 +#define WWCR_EVEN 0x06 /* Write window close registers - even and odd */ +#define WWCR_ODD 0x07 + +/* Interrupt status registers - PC system - even and odd */ +#define ISRP_EVEN 0x08 + +#define TCR_INT 0x10 /* Bit 4 - Timer interrupt. The TVR_EVEN timer has + expired. */ +#define ERR_INT 0x08 /* Bit 3 - Error interrupt. The adapter has had an + internal error. */ +#define ACCESS_INT 0x04 /* Bit 2 - Access interrupt. You have attempted to + write to an invalid area of shared RAM + or an invalid register within the MMIO. */ +/* In addition, the following bits within ISRP_EVEN can be turned on or off */ +/* by you to control the interrupt processing: */ +#define INT_ENABLE 0x40 /* Bit 6 - Interrupt enable. If 0, no interrupts will + occur. If 1, interrupts will occur normally. + Normally set to 1. */ +/* Bit 0 - Primary or alternate adapter. Set to zero if this adapter is the + primary adapter, 1 if this adapter is the alternate adapter. */ + + +#define ISRP_ODD 0x09 + +#define ADAP_CHK_INT 0x40 /* Bit 6 - Adapter check. the adapter has + encountered a serious problem and has closed + itself. Whoa. */ +#define SRB_RESP_INT 0x20 /* Bit 5 - SRB response. The adapter has accepted + an SRB request and set the return code within + the SRB. */ +#define ASB_FREE_INT 0x10 /* Bit 4 - ASB free. The adapter has read the ASB + and this area can be safely reused. This interrupt + is only used if your application has set the ASB + free request bit in ISRA_ODD or if an error was + detected in your response. */ +#define ARB_CMD_INT 0x08 /* Bit 3 - ARB command. The adapter has given you a + command for action. The command is located in the + ARB area of shared memory. */ +#define SSB_RESP_INT 0x04 /* Bit 2 - SSB response. The adapter has posted a + response to your SRB (the response is located in + the SSB area of shared memory). */ +/* Bit 1 - Bridge frame forward complete. */ + + + +#define ISRA_EVEN 0x0A /*Interrupt status registers - adapter - even and odd */ +/* Bit 7 - Internal parity error (on adapter's internal bus) */ +/* Bit 6 - Timer interrupt pending */ +/* Bit 5 - Access interrupt (attempt by adapter to access illegal address) */ +/* Bit 4 - Adapter microcode problem (microcode dead-man timer expired) */ +/* Bit 3 - Adapter processor check status */ +/* Bit 2 - Reserved */ +/* Bit 1 - Adapter hardware interrupt mask (prevents internal interrupts) */ +/* Bit 0 - Adapter software interrupt mask (prevents internal software ints) */ + +#define ISRA_ODD 0x0B +#define CMD_IN_SRB 0x20 /* Bit 5 - Indicates that you have placed a new + command in the SRB and are ready for the adapter to + process the command. */ +#define RESP_IN_ASB 0x10 /* Bit 4 - Indicates that you have placed a response + (an ASB) in the shared RAM which is available for + the adapter's use. */ +/* Bit 3 - Indicates that you are ready to put an SRB in the shared RAM, but + that a previous command is still pending. The adapter will then + interrupt you when the previous command is completed */ +/* Bit 2 - Indicates that you are ready to put an ASB in the shared RAM, but + that a previous ASB is still pending. The adapter will then interrupt + you when the previous ASB is copied. */ +#define ARB_FREE 0x2 +#define SSB_FREE 0x1 + +#define TCR_EVEN 0x0C /* Timer control registers - even and odd */ +#define TCR_ODD 0x0D +#define TVR_EVEN 0x0E /* Timer value registers - even and odd */ +#define TVR_ODD 0x0F +#define SRPR_EVEN 0x18 /* Shared RAM paging registers - even and odd */ +#define SRPR_ENABLE_PAGING 0xc0 +#define SRPR_ODD 0x19 /* Not used. */ +#define TOKREAD 0x60 +#define TOKOR 0x40 +#define TOKAND 0x20 +#define TOKWRITE 0x00 + +/* MMIO bits 5-6 select operation */ +/* 00 is used to write to a register */ +/* 01 is used to bitwise AND a byte with a register */ +/* 10 is used to bitwise OR a byte with a register */ +/* 11 is used to read from a register */ + +/* MMIO bits 7-8 select area of interest.. see below */ +/* 00 selects attachment control area. */ +/* 01 is reserved. */ +/* 10 selects adapter identification area A containing the adapter encoded + address. */ +/* 11 selects the adapter identification area B containing test patterns. */ + +#define PCCHANNELID 5049434F3631313039393020 +#define MCCHANNELID 4D4152533633583435313820 + +#define ACA_OFFSET 0x1e00 +#define ACA_SET 0x40 +#define ACA_RESET 0x20 +#define ACA_RW 0x00 + +#ifdef ENABLE_PAGING +#define SET_PAGE(x) (writeb((x), ti->mmio + ACA_OFFSET+ ACA_RW + SRPR_EVEN)) +#else +#define SET_PAGE(x) +#endif + +/* do_tok_int possible values */ +#define FIRST_INT 1 +#define NOT_FIRST 2 + +typedef enum { CLOSED, OPEN } open_state; +//staic const char *printstate[] = { "CLOSED","OPEN"}; + +struct tok_info { + unsigned char irq; + void __iomem *mmio; + unsigned char hw_address[32]; + unsigned char adapter_type; + unsigned char data_rate; + unsigned char token_release; + unsigned char avail_shared_ram; + unsigned char shared_ram_paging; + unsigned char turbo; + unsigned short dhb_size4mb; + unsigned short rbuf_len4; + unsigned short rbuf_cnt4; + unsigned short maxmtu4; + unsigned short dhb_size16mb; + unsigned short rbuf_len16; + unsigned short rbuf_cnt16; + unsigned short maxmtu16; + /* Additions by David Morris */ + unsigned char do_tok_int; + wait_queue_head_t wait_for_reset; + unsigned char sram_base; + /* Additions by Peter De Schrijver */ + unsigned char page_mask; /* mask to select RAM page to Map*/ + unsigned char mapped_ram_size; /* size of RAM page */ + __u32 sram_phys; /* Shared memory base address */ + void __iomem *sram_virt; /* Shared memory base address */ + void __iomem *init_srb; /* Initial System Request Block address */ + void __iomem *srb; /* System Request Block address */ + void __iomem *ssb; /* System Status Block address */ + void __iomem *arb; /* Adapter Request Block address */ + void __iomem *asb; /* Adapter Status Block address */ + __u8 init_srb_page; + __u8 srb_page; + __u8 ssb_page; + __u8 arb_page; + __u8 asb_page; + unsigned short exsap_station_id; + unsigned short global_int_enable; + struct sk_buff *current_skb; + + unsigned char auto_speedsave; + open_state open_status, sap_status; + enum {MANUAL, AUTOMATIC} open_mode; + enum {FAIL, RESTART, REOPEN} open_action; + enum {NO, YES} open_failure; + unsigned char readlog_pending; + unsigned short adapter_int_enable; /* Adapter-specific int enable */ + struct timer_list tr_timer; + unsigned char ring_speed; + spinlock_t lock; /* SMP protection */ +}; + +/* token ring adapter commands */ +#define DIR_INTERRUPT 0x00 /* struct srb_interrupt */ +#define DIR_MOD_OPEN_PARAMS 0x01 +#define DIR_OPEN_ADAPTER 0x03 /* struct dir_open_adapter */ +#define DIR_CLOSE_ADAPTER 0x04 +#define DIR_SET_GRP_ADDR 0x06 +#define DIR_SET_FUNC_ADDR 0x07 /* struct srb_set_funct_addr */ +#define DIR_READ_LOG 0x08 /* struct srb_read_log */ +#define DLC_OPEN_SAP 0x15 /* struct dlc_open_sap */ +#define DLC_CLOSE_SAP 0x16 +#define DATA_LOST 0x20 /* struct asb_rec */ +#define REC_DATA 0x81 /* struct arb_rec_req */ +#define XMIT_DATA_REQ 0x82 /* struct arb_xmit_req */ +#define DLC_STATUS 0x83 /* struct arb_dlc_status */ +#define RING_STAT_CHANGE 0x84 /* struct dlc_open_sap ??? */ + +/* DIR_OPEN_ADAPTER options */ +#define OPEN_PASS_BCON_MAC 0x0100 +#define NUM_RCV_BUF 2 +#define RCV_BUF_LEN 1024 +#define DHB_LENGTH 2048 +#define NUM_DHB 2 +#define DLC_MAX_SAP 2 +#define DLC_MAX_STA 1 + +/* DLC_OPEN_SAP options */ +#define MAX_I_FIELD 0x0088 +#define SAP_OPEN_IND_SAP 0x04 +#define SAP_OPEN_PRIORITY 0x20 +#define SAP_OPEN_STATION_CNT 0x1 +#define XMIT_DIR_FRAME 0x0A +#define XMIT_UI_FRAME 0x0d +#define XMIT_XID_CMD 0x0e +#define XMIT_TEST_CMD 0x11 + +/* srb close return code */ +#define SIGNAL_LOSS 0x8000 +#define HARD_ERROR 0x4000 +#define XMIT_BEACON 0x1000 +#define LOBE_FAULT 0x0800 +#define AUTO_REMOVAL 0x0400 +#define REMOVE_RECV 0x0100 +#define LOG_OVERFLOW 0x0080 +#define RING_RECOVER 0x0020 + +struct srb_init_response { + unsigned char command; + unsigned char init_status; + unsigned char init_status_2; + unsigned char reserved[3]; + __u16 bring_up_code; + __u16 encoded_address; + __u16 level_address; + __u16 adapter_address; + __u16 parms_address; + __u16 mac_address; +}; + +struct dir_open_adapter { + unsigned char command; + char reserved[7]; + __u16 open_options; + unsigned char node_address[6]; + unsigned char group_address[4]; + unsigned char funct_address[4]; + __u16 num_rcv_buf; + __u16 rcv_buf_len; + __u16 dhb_length; + unsigned char num_dhb; + char reserved2; + unsigned char dlc_max_sap; + unsigned char dlc_max_sta; + unsigned char dlc_max_gsap; + unsigned char dlc_max_gmem; + unsigned char dlc_t1_tick_1; + unsigned char dlc_t2_tick_1; + unsigned char dlc_ti_tick_1; + unsigned char dlc_t1_tick_2; + unsigned char dlc_t2_tick_2; + unsigned char dlc_ti_tick_2; + unsigned char product_id[18]; +}; + +struct dlc_open_sap { + unsigned char command; + unsigned char reserved1; + unsigned char ret_code; + unsigned char reserved2; + __u16 station_id; + unsigned char timer_t1; + unsigned char timer_t2; + unsigned char timer_ti; + unsigned char maxout; + unsigned char maxin; + unsigned char maxout_incr; + unsigned char max_retry_count; + unsigned char gsap_max_mem; + __u16 max_i_field; + unsigned char sap_value; + unsigned char sap_options; + unsigned char station_count; + unsigned char sap_gsap_mem; + unsigned char gsap[0]; +}; + +struct srb_xmit { + unsigned char command; + unsigned char cmd_corr; + unsigned char ret_code; + unsigned char reserved1; + __u16 station_id; +}; + +struct arb_rec_req { + unsigned char command; + unsigned char reserved1[3]; + __u16 station_id; + __u16 rec_buf_addr; + unsigned char lan_hdr_len; + unsigned char dlc_hdr_len; + __u16 frame_len; + unsigned char msg_type; +}; + +struct asb_rec { + unsigned char command; + unsigned char reserved1; + unsigned char ret_code; + unsigned char reserved2; + __u16 station_id; + __u16 rec_buf_addr; +}; + +struct rec_buf { + unsigned char reserved1[2]; + __u16 buf_ptr; + unsigned char reserved2; + unsigned char receive_fs; + __u16 buf_len; + unsigned char data[0]; +}; + +struct srb_set_funct_addr { + unsigned char command; + unsigned char reserved1; + unsigned char ret_code; + unsigned char reserved2[3]; + unsigned char funct_address[4]; +}; + +#endif diff --git a/trunk/include/linux/if_arp.h b/trunk/include/linux/if_arp.h index 26cb3c2c5c71..6d722f41ee7c 100644 --- a/trunk/include/linux/if_arp.h +++ b/trunk/include/linux/if_arp.h @@ -82,12 +82,11 @@ #define ARPHRD_FCPL 786 /* Fibrechannel public loop */ #define ARPHRD_FCFABRIC 787 /* Fibrechannel fabric */ /* 787->799 reserved for fibrechannel media types */ -/* 800 used to be used for token ring */ +#define ARPHRD_IEEE802_TR 800 /* Magic type ident for TR */ #define ARPHRD_IEEE80211 801 /* IEEE 802.11 */ #define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header */ #define ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header */ #define ARPHRD_IEEE802154 804 -#define ARPHRD_IEEE802154_MONITOR 805 /* IEEE 802.15.4 network monitor */ #define ARPHRD_PHONET 820 /* PhoNet media type */ #define ARPHRD_PHONET_PIPE 821 /* PhoNet pipe header */ diff --git a/trunk/include/linux/if_ec.h b/trunk/include/linux/if_ec.h new file mode 100644 index 000000000000..d85f9f48129f --- /dev/null +++ b/trunk/include/linux/if_ec.h @@ -0,0 +1,68 @@ +/* Definitions for Econet sockets. */ + +#ifndef __LINUX_IF_EC +#define __LINUX_IF_EC + +/* User visible stuff. Glibc provides its own but libc5 folk will use these */ + +struct ec_addr { + unsigned char station; /* Station number. */ + unsigned char net; /* Network number. */ +}; + +struct sockaddr_ec { + unsigned short sec_family; + unsigned char port; /* Port number. */ + unsigned char cb; /* Control/flag byte. */ + unsigned char type; /* Type of message. */ + struct ec_addr addr; + unsigned long cookie; +}; + +#define ECTYPE_PACKET_RECEIVED 0 /* Packet received */ +#define ECTYPE_TRANSMIT_STATUS 0x10 /* Transmit completed, + low nibble holds status */ + +#define ECTYPE_TRANSMIT_OK 1 +#define ECTYPE_TRANSMIT_NOT_LISTENING 2 +#define ECTYPE_TRANSMIT_NET_ERROR 3 +#define ECTYPE_TRANSMIT_NO_CLOCK 4 +#define ECTYPE_TRANSMIT_LINE_JAMMED 5 +#define ECTYPE_TRANSMIT_NOT_PRESENT 6 + +#ifdef __KERNEL__ + +#define EC_HLEN 6 + +/* This is what an Econet frame looks like on the wire. */ +struct ec_framehdr { + unsigned char dst_stn; + unsigned char dst_net; + unsigned char src_stn; + unsigned char src_net; + unsigned char cb; + unsigned char port; +}; + +struct econet_sock { + /* struct sock has to be the first member of econet_sock */ + struct sock sk; + unsigned char cb; + unsigned char port; + unsigned char station; + unsigned char net; + unsigned short num; +}; + +static inline struct econet_sock *ec_sk(const struct sock *sk) +{ + return (struct econet_sock *)sk; +} + +struct ec_device { + unsigned char station, net; /* Econet protocol address */ +}; + +#endif + +#endif diff --git a/trunk/include/linux/if_tr.h b/trunk/include/linux/if_tr.h new file mode 100644 index 000000000000..fc23aeb0f201 --- /dev/null +++ b/trunk/include/linux/if_tr.h @@ -0,0 +1,103 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Global definitions for the Token-Ring IEEE 802.5 interface. + * + * Version: @(#)if_tr.h 0.0 07/11/94 + * + * Author: Fred N. van Kempen, + * Donald Becker, + * Peter De Schrijver, + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _LINUX_IF_TR_H +#define _LINUX_IF_TR_H + +#include +#include /* For __be16 */ + +/* IEEE 802.5 Token-Ring magic constants. The frame sizes omit the preamble + and FCS/CRC (frame check sequence). */ +#define TR_ALEN 6 /* Octets in one token-ring addr */ +#define TR_HLEN (sizeof(struct trh_hdr)+sizeof(struct trllc)) +#define AC 0x10 +#define LLC_FRAME 0x40 + +/* LLC and SNAP constants */ +#define EXTENDED_SAP 0xAA +#define UI_CMD 0x03 + +/* This is an Token-Ring frame header. */ +struct trh_hdr { + __u8 ac; /* access control field */ + __u8 fc; /* frame control field */ + __u8 daddr[TR_ALEN]; /* destination address */ + __u8 saddr[TR_ALEN]; /* source address */ + __be16 rcf; /* route control field */ + __be16 rseg[8]; /* routing registers */ +}; + +#ifdef __KERNEL__ +#include + +static inline struct trh_hdr *tr_hdr(const struct sk_buff *skb) +{ + return (struct trh_hdr *)skb_mac_header(skb); +} +#endif + +/* This is an Token-Ring LLC structure */ +struct trllc { + __u8 dsap; /* destination SAP */ + __u8 ssap; /* source SAP */ + __u8 llc; /* LLC control field */ + __u8 protid[3]; /* protocol id */ + __be16 ethertype; /* ether type field */ +}; + +/* Token-Ring statistics collection data. */ +struct tr_statistics { + unsigned long rx_packets; /* total packets received */ + unsigned long tx_packets; /* total packets transmitted */ + unsigned long rx_bytes; /* total bytes received */ + unsigned long tx_bytes; /* total bytes transmitted */ + unsigned long rx_errors; /* bad packets received */ + unsigned long tx_errors; /* packet transmit problems */ + unsigned long rx_dropped; /* no space in linux buffers */ + unsigned long tx_dropped; /* no space available in linux */ + unsigned long multicast; /* multicast packets received */ + unsigned long transmit_collision; + + /* detailed Token-Ring errors. See IBM Token-Ring Network + Architecture for more info */ + + unsigned long line_errors; + unsigned long internal_errors; + unsigned long burst_errors; + unsigned long A_C_errors; + unsigned long abort_delimiters; + unsigned long lost_frames; + unsigned long recv_congest_count; + unsigned long frame_copied_errors; + unsigned long frequency_errors; + unsigned long token_errors; + unsigned long dummy1; +}; + +/* source routing stuff */ +#define TR_RII 0x80 +#define TR_RCF_DIR_BIT 0x80 +#define TR_RCF_LEN_MASK 0x1f00 +#define TR_RCF_BROADCAST 0x8000 /* all-routes broadcast */ +#define TR_RCF_LIMITED_BROADCAST 0xC000 /* single-route broadcast */ +#define TR_RCF_FRAME2K 0x20 +#define TR_RCF_BROADCAST_MASK 0xC000 +#define TR_MAXRIFLEN 18 + +#endif /* _LINUX_IF_TR_H */ diff --git a/trunk/include/linux/in6.h b/trunk/include/linux/in6.h index cba469ba11a4..5c83d9e3eb8f 100644 --- a/trunk/include/linux/in6.h +++ b/trunk/include/linux/in6.h @@ -142,7 +142,7 @@ struct in6_flowlabel_req { /* * IPv6 TLV options. */ -#define IPV6_TLV_PAD1 0 +#define IPV6_TLV_PAD0 0 #define IPV6_TLV_PADN 1 #define IPV6_TLV_ROUTERALERT 5 #define IPV6_TLV_JUMBO 194 diff --git a/trunk/include/linux/interrupt.h b/trunk/include/linux/interrupt.h index c91171599cb6..2aea5d22db07 100644 --- a/trunk/include/linux/interrupt.h +++ b/trunk/include/linux/interrupt.h @@ -93,27 +93,27 @@ typedef irqreturn_t (*irq_handler_t)(int, void *); /** * struct irqaction - per interrupt action descriptor * @handler: interrupt handler function + * @flags: flags (see IRQF_* above) * @name: name of the device * @dev_id: cookie to identify the device * @percpu_dev_id: cookie to identify the device * @next: pointer to the next irqaction for shared interrupts * @irq: interrupt number - * @flags: flags (see IRQF_* above) + * @dir: pointer to the proc/irq/NN/name entry * @thread_fn: interrupt handler function for threaded interrupts * @thread: thread pointer for threaded interrupts * @thread_flags: flags related to @thread * @thread_mask: bitmask for keeping track of @thread activity - * @dir: pointer to the proc/irq/NN/name entry */ struct irqaction { irq_handler_t handler; + unsigned long flags; void *dev_id; void __percpu *percpu_dev_id; struct irqaction *next; + int irq; irq_handler_t thread_fn; struct task_struct *thread; - unsigned int irq; - unsigned int flags; unsigned long thread_flags; unsigned long thread_mask; const char *name; diff --git a/trunk/include/linux/ioport.h b/trunk/include/linux/ioport.h index 589e0e75efae..e885ba23de70 100644 --- a/trunk/include/linux/ioport.h +++ b/trunk/include/linux/ioport.h @@ -223,12 +223,5 @@ extern int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages, void *arg, int (*func)(unsigned long, unsigned long, void *)); -/* True if any part of r1 overlaps r2 */ -static inline bool resource_overlaps(struct resource *r1, struct resource *r2) -{ - return (r1->start <= r2->end && r1->end >= r2->start); -} - - #endif /* __ASSEMBLY__ */ #endif /* _LINUX_IOPORT_H */ diff --git a/trunk/include/linux/ipx.h b/trunk/include/linux/ipx.h index 8f0243982eb6..3d48014cdd71 100644 --- a/trunk/include/linux/ipx.h +++ b/trunk/include/linux/ipx.h @@ -38,7 +38,7 @@ struct ipx_interface_definition { #define IPX_FRAME_8022 2 #define IPX_FRAME_ETHERII 3 #define IPX_FRAME_8023 4 -/* obsolete token ring was 5 */ +#define IPX_FRAME_TR_8022 5 /* obsolete */ unsigned char ipx_special; #define IPX_SPECIAL_NONE 0 #define IPX_PRIMARY 1 diff --git a/trunk/include/linux/key.h b/trunk/include/linux/key.h index 5231800770e1..96933b1e5d24 100644 --- a/trunk/include/linux/key.h +++ b/trunk/include/linux/key.h @@ -124,10 +124,7 @@ static inline unsigned long is_key_possessed(const key_ref_t key_ref) struct key { atomic_t usage; /* number of references */ key_serial_t serial; /* key serial number */ - union { - struct list_head graveyard_link; - struct rb_node serial_node; - }; + struct rb_node serial_node; struct key_type *type; /* type of key */ struct rw_semaphore sem; /* change vs change sem */ struct key_user *user; /* owner of this key */ @@ -136,7 +133,6 @@ struct key { time_t expiry; /* time at which key expires (or 0) */ time_t revoked_at; /* time at which key was revoked */ }; - time_t last_used_at; /* last time used for LRU keyring discard */ uid_t uid; gid_t gid; key_perm_t perm; /* access permissions */ @@ -160,7 +156,6 @@ struct key { #define KEY_FLAG_USER_CONSTRUCT 4 /* set if key is being constructed in userspace */ #define KEY_FLAG_NEGATIVE 5 /* set if key is negative */ #define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */ -#define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */ /* the description string * - this is used to match a key against search criteria @@ -204,7 +199,6 @@ extern struct key *key_alloc(struct key_type *type, #define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */ extern void key_revoke(struct key *key); -extern void key_invalidate(struct key *key); extern void key_put(struct key *key); static inline struct key *key_get(struct key *key) @@ -242,7 +236,7 @@ extern struct key *request_key_async_with_auxdata(struct key_type *type, extern int wait_for_key_construction(struct key *key, bool intr); -extern int key_validate(const struct key *key); +extern int key_validate(struct key *key); extern key_ref_t key_create_or_update(key_ref_t keyring, const char *type, @@ -325,7 +319,6 @@ extern void key_init(void); #define key_serial(k) 0 #define key_get(k) ({ NULL; }) #define key_revoke(k) do { } while(0) -#define key_invalidate(k) do { } while(0) #define key_put(k) do { } while(0) #define key_ref_put(k) do { } while(0) #define make_key_ref(k, p) NULL diff --git a/trunk/include/linux/keyctl.h b/trunk/include/linux/keyctl.h index c9b7f4faf97a..9b0b865ce622 100644 --- a/trunk/include/linux/keyctl.h +++ b/trunk/include/linux/keyctl.h @@ -55,6 +55,5 @@ #define KEYCTL_SESSION_TO_PARENT 18 /* apply session keyring to parent process */ #define KEYCTL_REJECT 19 /* reject a partially constructed key */ #define KEYCTL_INSTANTIATE_IOV 20 /* instantiate a partially constructed key */ -#define KEYCTL_INVALIDATE 21 /* invalidate a key */ #endif /* _LINUX_KEYCTL_H */ diff --git a/trunk/include/linux/lsm_audit.h b/trunk/include/linux/lsm_audit.h index 1cc89e9df480..fad48aab893b 100644 --- a/trunk/include/linux/lsm_audit.h +++ b/trunk/include/linux/lsm_audit.h @@ -53,6 +53,7 @@ struct common_audit_data { #define LSM_AUDIT_DATA_KMOD 8 #define LSM_AUDIT_DATA_INODE 9 #define LSM_AUDIT_DATA_DENTRY 10 + struct task_struct *tsk; union { struct path path; struct dentry *dentry; @@ -92,6 +93,11 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb, int ipv6_skb_to_auditdata(struct sk_buff *skb, struct common_audit_data *ad, u8 *proto); +/* Initialize an LSM audit data structure. */ +#define COMMON_AUDIT_DATA_INIT(_d, _t) \ + { memset((_d), 0, sizeof(struct common_audit_data)); \ + (_d)->type = LSM_AUDIT_DATA_##_t; } + void common_lsm_audit(struct common_audit_data *a, void (*pre_audit)(struct audit_buffer *, void *), void (*post_audit)(struct audit_buffer *, void *)); diff --git a/trunk/include/linux/mISDNhw.h b/trunk/include/linux/mISDNhw.h index d0752eca9b44..de165b54237b 100644 --- a/trunk/include/linux/mISDNhw.h +++ b/trunk/include/linux/mISDNhw.h @@ -72,9 +72,7 @@ #define FLG_LL_OK 24 #define FLG_LL_CONN 25 #define FLG_DTMFSEND 26 -#define FLG_TX_EMPTY 27 -/* stop sending received data upstream */ -#define FLG_RX_OFF 28 + /* workq events */ #define FLG_RECVQUEUE 30 #define FLG_PHCHANGE 31 @@ -144,7 +142,6 @@ extern int create_l1(struct dchannel *, dchannel_l1callback *); struct layer1; extern int l1_event(struct layer1 *, u_int); -#define MISDN_BCH_FILL_SIZE 4 struct bchannel { struct mISDNchannel ch; @@ -156,14 +153,8 @@ struct bchannel { int slot; /* multiport card channel slot */ struct timer_list timer; /* receive data */ - u8 fill[MISDN_BCH_FILL_SIZE]; struct sk_buff *rx_skb; - unsigned short maxlen; - unsigned short init_maxlen; /* initial value */ - unsigned short next_maxlen; /* pending value */ - unsigned short minlen; /* for transparent data */ - unsigned short init_minlen; /* initial value */ - unsigned short next_minlen; /* pending value */ + int maxlen; /* send data */ struct sk_buff *next_skb; struct sk_buff *tx_skb; @@ -175,26 +166,23 @@ struct bchannel { int err_crc; int err_tx; int err_rx; - int dropcnt; }; extern int mISDN_initdchannel(struct dchannel *, int, void *); -extern int mISDN_initbchannel(struct bchannel *, unsigned short, - unsigned short); +extern int mISDN_initbchannel(struct bchannel *, int); extern int mISDN_freedchannel(struct dchannel *); extern void mISDN_clear_bchannel(struct bchannel *); extern int mISDN_freebchannel(struct bchannel *); -extern int mISDN_ctrl_bchannel(struct bchannel *, struct mISDN_ctrl_req *); extern void queue_ch_frame(struct mISDNchannel *, u_int, int, struct sk_buff *); extern int dchannel_senddata(struct dchannel *, struct sk_buff *); extern int bchannel_senddata(struct bchannel *, struct sk_buff *); -extern int bchannel_get_rxbuf(struct bchannel *, int); extern void recv_Dchannel(struct dchannel *); extern void recv_Echannel(struct dchannel *, struct dchannel *); -extern void recv_Bchannel(struct bchannel *, unsigned int, bool); +extern void recv_Bchannel(struct bchannel *, unsigned int id); extern void recv_Dchannel_skb(struct dchannel *, struct sk_buff *); extern void recv_Bchannel_skb(struct bchannel *, struct sk_buff *); +extern void confirm_Bsend(struct bchannel *bch); extern int get_next_bframe(struct bchannel *); extern int get_next_dframe(struct dchannel *); diff --git a/trunk/include/linux/mISDNif.h b/trunk/include/linux/mISDNif.h index 246a3529ecf6..ce6e613dff4c 100644 --- a/trunk/include/linux/mISDNif.h +++ b/trunk/include/linux/mISDNif.h @@ -37,7 +37,7 @@ */ #define MISDN_MAJOR_VERSION 1 #define MISDN_MINOR_VERSION 1 -#define MISDN_RELEASE 29 +#define MISDN_RELEASE 28 /* primitives for information exchange * generell format @@ -365,7 +365,6 @@ clear_channelmap(u_int nr, u_char *map) #define MISDN_CTRL_LOOP 0x0001 #define MISDN_CTRL_CONNECT 0x0002 #define MISDN_CTRL_DISCONNECT 0x0004 -#define MISDN_CTRL_RX_BUFFER 0x0008 #define MISDN_CTRL_PCMCONNECT 0x0010 #define MISDN_CTRL_PCMDISCONNECT 0x0020 #define MISDN_CTRL_SETPEER 0x0040 @@ -388,12 +387,6 @@ clear_channelmap(u_int nr, u_char *map) #define MISDN_CTRL_HFC_WD_INIT 0x4009 #define MISDN_CTRL_HFC_WD_RESET 0x400A -/* special RX buffer value for MISDN_CTRL_RX_BUFFER request.p1 is the minimum - * buffer size request.p2 the maximum. Using MISDN_CTRL_RX_SIZE_IGNORE will - * not change the value, but still read back the actual stetting. - */ -#define MISDN_CTRL_RX_SIZE_IGNORE -1 - /* socket options */ #define MISDN_TIME_STAMP 0x0001 diff --git a/trunk/include/linux/mfd/da9052/da9052.h b/trunk/include/linux/mfd/da9052/da9052.h index 8313cd9658e3..7ffbd6e9e7fc 100644 --- a/trunk/include/linux/mfd/da9052/da9052.h +++ b/trunk/include/linux/mfd/da9052/da9052.h @@ -80,7 +80,6 @@ struct da9052 { struct regmap *regmap; int irq_base; - struct regmap_irq_chip_data *irq_data; u8 chip_id; int chip_irq; diff --git a/trunk/include/linux/mfd/palmas.h b/trunk/include/linux/mfd/palmas.h deleted file mode 100644 index 9cbc642d40ad..000000000000 --- a/trunk/include/linux/mfd/palmas.h +++ /dev/null @@ -1,2620 +0,0 @@ -/* - * TI Palmas - * - * Copyright 2011 Texas Instruments Inc. - * - * Author: Graeme Gregory - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#ifndef __LINUX_MFD_PALMAS_H -#define __LINUX_MFD_PALMAS_H - -#include -#include -#include -#include - -#define PALMAS_NUM_CLIENTS 3 - -struct palmas_pmic; - -struct palmas { - struct device *dev; - - struct i2c_client *i2c_clients[PALMAS_NUM_CLIENTS]; - struct regmap *regmap[PALMAS_NUM_CLIENTS]; - - /* Stored chip id */ - int id; - - /* IRQ Data */ - int irq; - u32 irq_mask; - struct mutex irq_lock; - struct regmap_irq_chip_data *irq_data; - - /* Child Devices */ - struct palmas_pmic *pmic; - - /* GPIO MUXing */ - u8 gpio_muxed; - u8 led_muxed; - u8 pwm_muxed; -}; - -struct palmas_reg_init { - /* warm_rest controls the voltage levels after a warm reset - * - * 0: reload default values from OTP on warm reset - * 1: maintain voltage from VSEL on warm reset - */ - int warm_reset; - - /* roof_floor controls whether the regulator uses the i2c style - * of DVS or uses the method where a GPIO or other control method is - * attached to the NSLEEP/ENABLE1/ENABLE2 pins - * - * For SMPS - * - * 0: i2c selection of voltage - * 1: pin selection of voltage. - * - * For LDO unused - */ - int roof_floor; - - /* sleep_mode is the mode loaded to MODE_SLEEP bits as defined in - * the data sheet. - * - * For SMPS - * - * 0: Off - * 1: AUTO - * 2: ECO - * 3: Forced PWM - * - * For LDO - * - * 0: Off - * 1: On - */ - int mode_sleep; - - /* tstep is the timestep loaded to the TSTEP register - * - * For SMPS - * - * 0: Jump (no slope control) - * 1: 10mV/us - * 2: 5mV/us - * 3: 2.5mV/us - * - * For LDO unused - */ - int tstep; - - /* voltage_sel is the bitfield loaded onto the SMPSX_VOLTAGE - * register. Set this is the default voltage set in OTP needs - * to be overridden. - */ - u8 vsel; - -}; - -struct palmas_pmic_platform_data { - /* An array of pointers to regulator init data indexed by regulator - * ID - */ - struct regulator_init_data **reg_data; - - /* An array of pointers to structures containing sleep mode and DVS - * configuration for regulators indexed by ID - */ - struct palmas_reg_init **reg_init; - - /* use LDO6 for vibrator control */ - int ldo6_vibrator; - - -}; - -struct palmas_platform_data { - int gpio_base; - - /* bit value to be loaded to the POWER_CTRL register */ - u8 power_ctrl; - - /* - * boolean to select if we want to configure muxing here - * then the two value to load into the registers if true - */ - int mux_from_pdata; - u8 pad1, pad2; - - struct palmas_pmic_platform_data *pmic_pdata; -}; - -/* Define the palmas IRQ numbers */ -enum palmas_irqs { - /* INT1 registers */ - PALMAS_CHARG_DET_N_VBUS_OVV_IRQ, - PALMAS_PWRON_IRQ, - PALMAS_LONG_PRESS_KEY_IRQ, - PALMAS_RPWRON_IRQ, - PALMAS_PWRDOWN_IRQ, - PALMAS_HOTDIE_IRQ, - PALMAS_VSYS_MON_IRQ, - PALMAS_VBAT_MON_IRQ, - /* INT2 registers */ - PALMAS_RTC_ALARM_IRQ, - PALMAS_RTC_TIMER_IRQ, - PALMAS_WDT_IRQ, - PALMAS_BATREMOVAL_IRQ, - PALMAS_RESET_IN_IRQ, - PALMAS_FBI_BB_IRQ, - PALMAS_SHORT_IRQ, - PALMAS_VAC_ACOK_IRQ, - /* INT3 registers */ - PALMAS_GPADC_AUTO_0_IRQ, - PALMAS_GPADC_AUTO_1_IRQ, - PALMAS_GPADC_EOC_SW_IRQ, - PALMAS_GPADC_EOC_RT_IRQ, - PALMAS_ID_OTG_IRQ, - PALMAS_ID_IRQ, - PALMAS_VBUS_OTG_IRQ, - PALMAS_VBUS_IRQ, - /* INT4 registers */ - PALMAS_GPIO_0_IRQ, - PALMAS_GPIO_1_IRQ, - PALMAS_GPIO_2_IRQ, - PALMAS_GPIO_3_IRQ, - PALMAS_GPIO_4_IRQ, - PALMAS_GPIO_5_IRQ, - PALMAS_GPIO_6_IRQ, - PALMAS_GPIO_7_IRQ, - /* Total Number IRQs */ - PALMAS_NUM_IRQ, -}; - -enum palmas_regulators { - /* SMPS regulators */ - PALMAS_REG_SMPS12, - PALMAS_REG_SMPS123, - PALMAS_REG_SMPS3, - PALMAS_REG_SMPS45, - PALMAS_REG_SMPS457, - PALMAS_REG_SMPS6, - PALMAS_REG_SMPS7, - PALMAS_REG_SMPS8, - PALMAS_REG_SMPS9, - PALMAS_REG_SMPS10, - /* LDO regulators */ - PALMAS_REG_LDO1, - PALMAS_REG_LDO2, - PALMAS_REG_LDO3, - PALMAS_REG_LDO4, - PALMAS_REG_LDO5, - PALMAS_REG_LDO6, - PALMAS_REG_LDO7, - PALMAS_REG_LDO8, - PALMAS_REG_LDO9, - PALMAS_REG_LDOLN, - PALMAS_REG_LDOUSB, - /* Total number of regulators */ - PALMAS_NUM_REGS, -}; - -struct palmas_pmic { - struct palmas *palmas; - struct device *dev; - struct regulator_desc desc[PALMAS_NUM_REGS]; - struct regulator_dev *rdev[PALMAS_NUM_REGS]; - struct mutex mutex; - - int smps123; - int smps457; - - int range[PALMAS_REG_SMPS10]; -}; - -/* defines so we can store the mux settings */ -#define PALMAS_GPIO_0_MUXED (1 << 0) -#define PALMAS_GPIO_1_MUXED (1 << 1) -#define PALMAS_GPIO_2_MUXED (1 << 2) -#define PALMAS_GPIO_3_MUXED (1 << 3) -#define PALMAS_GPIO_4_MUXED (1 << 4) -#define PALMAS_GPIO_5_MUXED (1 << 5) -#define PALMAS_GPIO_6_MUXED (1 << 6) -#define PALMAS_GPIO_7_MUXED (1 << 7) - -#define PALMAS_LED1_MUXED (1 << 0) -#define PALMAS_LED2_MUXED (1 << 1) - -#define PALMAS_PWM1_MUXED (1 << 0) -#define PALMAS_PWM2_MUXED (1 << 1) - -/* helper macro to get correct slave number */ -#define PALMAS_BASE_TO_SLAVE(x) ((x >> 8) - 1) -#define PALMAS_BASE_TO_REG(x, y) ((x & 0xff) + y) - -/* Base addresses of IP blocks in Palmas */ -#define PALMAS_SMPS_DVS_BASE 0x20 -#define PALMAS_RTC_BASE 0x100 -#define PALMAS_VALIDITY_BASE 0x118 -#define PALMAS_SMPS_BASE 0x120 -#define PALMAS_LDO_BASE 0x150 -#define PALMAS_DVFS_BASE 0x180 -#define PALMAS_PMU_CONTROL_BASE 0x1A0 -#define PALMAS_RESOURCE_BASE 0x1D4 -#define PALMAS_PU_PD_OD_BASE 0x1F4 -#define PALMAS_LED_BASE 0x200 -#define PALMAS_INTERRUPT_BASE 0x210 -#define PALMAS_USB_OTG_BASE 0x250 -#define PALMAS_VIBRATOR_BASE 0x270 -#define PALMAS_GPIO_BASE 0x280 -#define PALMAS_USB_BASE 0x290 -#define PALMAS_GPADC_BASE 0x2C0 -#define PALMAS_TRIM_GPADC_BASE 0x3CD - -/* Registers for function RTC */ -#define PALMAS_SECONDS_REG 0x0 -#define PALMAS_MINUTES_REG 0x1 -#define PALMAS_HOURS_REG 0x2 -#define PALMAS_DAYS_REG 0x3 -#define PALMAS_MONTHS_REG 0x4 -#define PALMAS_YEARS_REG 0x5 -#define PALMAS_WEEKS_REG 0x6 -#define PALMAS_ALARM_SECONDS_REG 0x8 -#define PALMAS_ALARM_MINUTES_REG 0x9 -#define PALMAS_ALARM_HOURS_REG 0xA -#define PALMAS_ALARM_DAYS_REG 0xB -#define PALMAS_ALARM_MONTHS_REG 0xC -#define PALMAS_ALARM_YEARS_REG 0xD -#define PALMAS_RTC_CTRL_REG 0x10 -#define PALMAS_RTC_STATUS_REG 0x11 -#define PALMAS_RTC_INTERRUPTS_REG 0x12 -#define PALMAS_RTC_COMP_LSB_REG 0x13 -#define PALMAS_RTC_COMP_MSB_REG 0x14 -#define PALMAS_RTC_RES_PROG_REG 0x15 -#define PALMAS_RTC_RESET_STATUS_REG 0x16 - -/* Bit definitions for SECONDS_REG */ -#define PALMAS_SECONDS_REG_SEC1_MASK 0x70 -#define PALMAS_SECONDS_REG_SEC1_SHIFT 4 -#define PALMAS_SECONDS_REG_SEC0_MASK 0x0f -#define PALMAS_SECONDS_REG_SEC0_SHIFT 0 - -/* Bit definitions for MINUTES_REG */ -#define PALMAS_MINUTES_REG_MIN1_MASK 0x70 -#define PALMAS_MINUTES_REG_MIN1_SHIFT 4 -#define PALMAS_MINUTES_REG_MIN0_MASK 0x0f -#define PALMAS_MINUTES_REG_MIN0_SHIFT 0 - -/* Bit definitions for HOURS_REG */ -#define PALMAS_HOURS_REG_PM_NAM 0x80 -#define PALMAS_HOURS_REG_PM_NAM_SHIFT 7 -#define PALMAS_HOURS_REG_HOUR1_MASK 0x30 -#define PALMAS_HOURS_REG_HOUR1_SHIFT 4 -#define PALMAS_HOURS_REG_HOUR0_MASK 0x0f -#define PALMAS_HOURS_REG_HOUR0_SHIFT 0 - -/* Bit definitions for DAYS_REG */ -#define PALMAS_DAYS_REG_DAY1_MASK 0x30 -#define PALMAS_DAYS_REG_DAY1_SHIFT 4 -#define PALMAS_DAYS_REG_DAY0_MASK 0x0f -#define PALMAS_DAYS_REG_DAY0_SHIFT 0 - -/* Bit definitions for MONTHS_REG */ -#define PALMAS_MONTHS_REG_MONTH1 0x10 -#define PALMAS_MONTHS_REG_MONTH1_SHIFT 4 -#define PALMAS_MONTHS_REG_MONTH0_MASK 0x0f -#define PALMAS_MONTHS_REG_MONTH0_SHIFT 0 - -/* Bit definitions for YEARS_REG */ -#define PALMAS_YEARS_REG_YEAR1_MASK 0xf0 -#define PALMAS_YEARS_REG_YEAR1_SHIFT 4 -#define PALMAS_YEARS_REG_YEAR0_MASK 0x0f -#define PALMAS_YEARS_REG_YEAR0_SHIFT 0 - -/* Bit definitions for WEEKS_REG */ -#define PALMAS_WEEKS_REG_WEEK_MASK 0x07 -#define PALMAS_WEEKS_REG_WEEK_SHIFT 0 - -/* Bit definitions for ALARM_SECONDS_REG */ -#define PALMAS_ALARM_SECONDS_REG_ALARM_SEC1_MASK 0x70 -#define PALMAS_ALARM_SECONDS_REG_ALARM_SEC1_SHIFT 4 -#define PALMAS_ALARM_SECONDS_REG_ALARM_SEC0_MASK 0x0f -#define PALMAS_ALARM_SECONDS_REG_ALARM_SEC0_SHIFT 0 - -/* Bit definitions for ALARM_MINUTES_REG */ -#define PALMAS_ALARM_MINUTES_REG_ALARM_MIN1_MASK 0x70 -#define PALMAS_ALARM_MINUTES_REG_ALARM_MIN1_SHIFT 4 -#define PALMAS_ALARM_MINUTES_REG_ALARM_MIN0_MASK 0x0f -#define PALMAS_ALARM_MINUTES_REG_ALARM_MIN0_SHIFT 0 - -/* Bit definitions for ALARM_HOURS_REG */ -#define PALMAS_ALARM_HOURS_REG_ALARM_PM_NAM 0x80 -#define PALMAS_ALARM_HOURS_REG_ALARM_PM_NAM_SHIFT 7 -#define PALMAS_ALARM_HOURS_REG_ALARM_HOUR1_MASK 0x30 -#define PALMAS_ALARM_HOURS_REG_ALARM_HOUR1_SHIFT 4 -#define PALMAS_ALARM_HOURS_REG_ALARM_HOUR0_MASK 0x0f -#define PALMAS_ALARM_HOURS_REG_ALARM_HOUR0_SHIFT 0 - -/* Bit definitions for ALARM_DAYS_REG */ -#define PALMAS_ALARM_DAYS_REG_ALARM_DAY1_MASK 0x30 -#define PALMAS_ALARM_DAYS_REG_ALARM_DAY1_SHIFT 4 -#define PALMAS_ALARM_DAYS_REG_ALARM_DAY0_MASK 0x0f -#define PALMAS_ALARM_DAYS_REG_ALARM_DAY0_SHIFT 0 - -/* Bit definitions for ALARM_MONTHS_REG */ -#define PALMAS_ALARM_MONTHS_REG_ALARM_MONTH1 0x10 -#define PALMAS_ALARM_MONTHS_REG_ALARM_MONTH1_SHIFT 4 -#define PALMAS_ALARM_MONTHS_REG_ALARM_MONTH0_MASK 0x0f -#define PALMAS_ALARM_MONTHS_REG_ALARM_MONTH0_SHIFT 0 - -/* Bit definitions for ALARM_YEARS_REG */ -#define PALMAS_ALARM_YEARS_REG_ALARM_YEAR1_MASK 0xf0 -#define PALMAS_ALARM_YEARS_REG_ALARM_YEAR1_SHIFT 4 -#define PALMAS_ALARM_YEARS_REG_ALARM_YEAR0_MASK 0x0f -#define PALMAS_ALARM_YEARS_REG_ALARM_YEAR0_SHIFT 0 - -/* Bit definitions for RTC_CTRL_REG */ -#define PALMAS_RTC_CTRL_REG_RTC_V_OPT 0x80 -#define PALMAS_RTC_CTRL_REG_RTC_V_OPT_SHIFT 7 -#define PALMAS_RTC_CTRL_REG_GET_TIME 0x40 -#define PALMAS_RTC_CTRL_REG_GET_TIME_SHIFT 6 -#define PALMAS_RTC_CTRL_REG_SET_32_COUNTER 0x20 -#define PALMAS_RTC_CTRL_REG_SET_32_COUNTER_SHIFT 5 -#define PALMAS_RTC_CTRL_REG_TEST_MODE 0x10 -#define PALMAS_RTC_CTRL_REG_TEST_MODE_SHIFT 4 -#define PALMAS_RTC_CTRL_REG_MODE_12_24 0x08 -#define PALMAS_RTC_CTRL_REG_MODE_12_24_SHIFT 3 -#define PALMAS_RTC_CTRL_REG_AUTO_COMP 0x04 -#define PALMAS_RTC_CTRL_REG_AUTO_COMP_SHIFT 2 -#define PALMAS_RTC_CTRL_REG_ROUND_30S 0x02 -#define PALMAS_RTC_CTRL_REG_ROUND_30S_SHIFT 1 -#define PALMAS_RTC_CTRL_REG_STOP_RTC 0x01 -#define PALMAS_RTC_CTRL_REG_STOP_RTC_SHIFT 0 - -/* Bit definitions for RTC_STATUS_REG */ -#define PALMAS_RTC_STATUS_REG_POWER_UP 0x80 -#define PALMAS_RTC_STATUS_REG_POWER_UP_SHIFT 7 -#define PALMAS_RTC_STATUS_REG_ALARM 0x40 -#define PALMAS_RTC_STATUS_REG_ALARM_SHIFT 6 -#define PALMAS_RTC_STATUS_REG_EVENT_1D 0x20 -#define PALMAS_RTC_STATUS_REG_EVENT_1D_SHIFT 5 -#define PALMAS_RTC_STATUS_REG_EVENT_1H 0x10 -#define PALMAS_RTC_STATUS_REG_EVENT_1H_SHIFT 4 -#define PALMAS_RTC_STATUS_REG_EVENT_1M 0x08 -#define PALMAS_RTC_STATUS_REG_EVENT_1M_SHIFT 3 -#define PALMAS_RTC_STATUS_REG_EVENT_1S 0x04 -#define PALMAS_RTC_STATUS_REG_EVENT_1S_SHIFT 2 -#define PALMAS_RTC_STATUS_REG_RUN 0x02 -#define PALMAS_RTC_STATUS_REG_RUN_SHIFT 1 - -/* Bit definitions for RTC_INTERRUPTS_REG */ -#define PALMAS_RTC_INTERRUPTS_REG_IT_SLEEP_MASK_EN 0x10 -#define PALMAS_RTC_INTERRUPTS_REG_IT_SLEEP_MASK_EN_SHIFT 4 -#define PALMAS_RTC_INTERRUPTS_REG_IT_ALARM 0x08 -#define PALMAS_RTC_INTERRUPTS_REG_IT_ALARM_SHIFT 3 -#define PALMAS_RTC_INTERRUPTS_REG_IT_TIMER 0x04 -#define PALMAS_RTC_INTERRUPTS_REG_IT_TIMER_SHIFT 2 -#define PALMAS_RTC_INTERRUPTS_REG_EVERY_MASK 0x03 -#define PALMAS_RTC_INTERRUPTS_REG_EVERY_SHIFT 0 - -/* Bit definitions for RTC_COMP_LSB_REG */ -#define PALMAS_RTC_COMP_LSB_REG_RTC_COMP_LSB_MASK 0xff -#define PALMAS_RTC_COMP_LSB_REG_RTC_COMP_LSB_SHIFT 0 - -/* Bit definitions for RTC_COMP_MSB_REG */ -#define PALMAS_RTC_COMP_MSB_REG_RTC_COMP_MSB_MASK 0xff -#define PALMAS_RTC_COMP_MSB_REG_RTC_COMP_MSB_SHIFT 0 - -/* Bit definitions for RTC_RES_PROG_REG */ -#define PALMAS_RTC_RES_PROG_REG_SW_RES_PROG_MASK 0x3f -#define PALMAS_RTC_RES_PROG_REG_SW_RES_PROG_SHIFT 0 - -/* Bit definitions for RTC_RESET_STATUS_REG */ -#define PALMAS_RTC_RESET_STATUS_REG_RESET_STATUS 0x01 -#define PALMAS_RTC_RESET_STATUS_REG_RESET_STATUS_SHIFT 0 - -/* Registers for function BACKUP */ -#define PALMAS_BACKUP0 0x0 -#define PALMAS_BACKUP1 0x1 -#define PALMAS_BACKUP2 0x2 -#define PALMAS_BACKUP3 0x3 -#define PALMAS_BACKUP4 0x4 -#define PALMAS_BACKUP5 0x5 -#define PALMAS_BACKUP6 0x6 -#define PALMAS_BACKUP7 0x7 - -/* Bit definitions for BACKUP0 */ -#define PALMAS_BACKUP0_BACKUP_MASK 0xff -#define PALMAS_BACKUP0_BACKUP_SHIFT 0 - -/* Bit definitions for BACKUP1 */ -#define PALMAS_BACKUP1_BACKUP_MASK 0xff -#define PALMAS_BACKUP1_BACKUP_SHIFT 0 - -/* Bit definitions for BACKUP2 */ -#define PALMAS_BACKUP2_BACKUP_MASK 0xff -#define PALMAS_BACKUP2_BACKUP_SHIFT 0 - -/* Bit definitions for BACKUP3 */ -#define PALMAS_BACKUP3_BACKUP_MASK 0xff -#define PALMAS_BACKUP3_BACKUP_SHIFT 0 - -/* Bit definitions for BACKUP4 */ -#define PALMAS_BACKUP4_BACKUP_MASK 0xff -#define PALMAS_BACKUP4_BACKUP_SHIFT 0 - -/* Bit definitions for BACKUP5 */ -#define PALMAS_BACKUP5_BACKUP_MASK 0xff -#define PALMAS_BACKUP5_BACKUP_SHIFT 0 - -/* Bit definitions for BACKUP6 */ -#define PALMAS_BACKUP6_BACKUP_MASK 0xff -#define PALMAS_BACKUP6_BACKUP_SHIFT 0 - -/* Bit definitions for BACKUP7 */ -#define PALMAS_BACKUP7_BACKUP_MASK 0xff -#define PALMAS_BACKUP7_BACKUP_SHIFT 0 - -/* Registers for function SMPS */ -#define PALMAS_SMPS12_CTRL 0x0 -#define PALMAS_SMPS12_TSTEP 0x1 -#define PALMAS_SMPS12_FORCE 0x2 -#define PALMAS_SMPS12_VOLTAGE 0x3 -#define PALMAS_SMPS3_CTRL 0x4 -#define PALMAS_SMPS3_VOLTAGE 0x7 -#define PALMAS_SMPS45_CTRL 0x8 -#define PALMAS_SMPS45_TSTEP 0x9 -#define PALMAS_SMPS45_FORCE 0xA -#define PALMAS_SMPS45_VOLTAGE 0xB -#define PALMAS_SMPS6_CTRL 0xC -#define PALMAS_SMPS6_TSTEP 0xD -#define PALMAS_SMPS6_FORCE 0xE -#define PALMAS_SMPS6_VOLTAGE 0xF -#define PALMAS_SMPS7_CTRL 0x10 -#define PALMAS_SMPS7_VOLTAGE 0x13 -#define PALMAS_SMPS8_CTRL 0x14 -#define PALMAS_SMPS8_TSTEP 0x15 -#define PALMAS_SMPS8_FORCE 0x16 -#define PALMAS_SMPS8_VOLTAGE 0x17 -#define PALMAS_SMPS9_CTRL 0x18 -#define PALMAS_SMPS9_VOLTAGE 0x1B -#define PALMAS_SMPS10_CTRL 0x1C -#define PALMAS_SMPS10_STATUS 0x1F -#define PALMAS_SMPS_CTRL 0x24 -#define PALMAS_SMPS_PD_CTRL 0x25 -#define PALMAS_SMPS_DITHER_EN 0x26 -#define PALMAS_SMPS_THERMAL_EN 0x27 -#define PALMAS_SMPS_THERMAL_STATUS 0x28 -#define PALMAS_SMPS_SHORT_STATUS 0x29 -#define PALMAS_SMPS_NEGATIVE_CURRENT_LIMIT_EN 0x2A -#define PALMAS_SMPS_POWERGOOD_MASK1 0x2B -#define PALMAS_SMPS_POWERGOOD_MASK2 0x2C - -/* Bit definitions for SMPS12_CTRL */ -#define PALMAS_SMPS12_CTRL_WR_S 0x80 -#define PALMAS_SMPS12_CTRL_WR_S_SHIFT 7 -#define PALMAS_SMPS12_CTRL_ROOF_FLOOR_EN 0x40 -#define PALMAS_SMPS12_CTRL_ROOF_FLOOR_EN_SHIFT 6 -#define PALMAS_SMPS12_CTRL_STATUS_MASK 0x30 -#define PALMAS_SMPS12_CTRL_STATUS_SHIFT 4 -#define PALMAS_SMPS12_CTRL_MODE_SLEEP_MASK 0x0c -#define PALMAS_SMPS12_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK 0x03 -#define PALMAS_SMPS12_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for SMPS12_TSTEP */ -#define PALMAS_SMPS12_TSTEP_TSTEP_MASK 0x03 -#define PALMAS_SMPS12_TSTEP_TSTEP_SHIFT 0 - -/* Bit definitions for SMPS12_FORCE */ -#define PALMAS_SMPS12_FORCE_CMD 0x80 -#define PALMAS_SMPS12_FORCE_CMD_SHIFT 7 -#define PALMAS_SMPS12_FORCE_VSEL_MASK 0x7f -#define PALMAS_SMPS12_FORCE_VSEL_SHIFT 0 - -/* Bit definitions for SMPS12_VOLTAGE */ -#define PALMAS_SMPS12_VOLTAGE_RANGE 0x80 -#define PALMAS_SMPS12_VOLTAGE_RANGE_SHIFT 7 -#define PALMAS_SMPS12_VOLTAGE_VSEL_MASK 0x7f -#define PALMAS_SMPS12_VOLTAGE_VSEL_SHIFT 0 - -/* Bit definitions for SMPS3_CTRL */ -#define PALMAS_SMPS3_CTRL_WR_S 0x80 -#define PALMAS_SMPS3_CTRL_WR_S_SHIFT 7 -#define PALMAS_SMPS3_CTRL_STATUS_MASK 0x30 -#define PALMAS_SMPS3_CTRL_STATUS_SHIFT 4 -#define PALMAS_SMPS3_CTRL_MODE_SLEEP_MASK 0x0c -#define PALMAS_SMPS3_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_SMPS3_CTRL_MODE_ACTIVE_MASK 0x03 -#define PALMAS_SMPS3_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for SMPS3_VOLTAGE */ -#define PALMAS_SMPS3_VOLTAGE_RANGE 0x80 -#define PALMAS_SMPS3_VOLTAGE_RANGE_SHIFT 7 -#define PALMAS_SMPS3_VOLTAGE_VSEL_MASK 0x7f -#define PALMAS_SMPS3_VOLTAGE_VSEL_SHIFT 0 - -/* Bit definitions for SMPS45_CTRL */ -#define PALMAS_SMPS45_CTRL_WR_S 0x80 -#define PALMAS_SMPS45_CTRL_WR_S_SHIFT 7 -#define PALMAS_SMPS45_CTRL_ROOF_FLOOR_EN 0x40 -#define PALMAS_SMPS45_CTRL_ROOF_FLOOR_EN_SHIFT 6 -#define PALMAS_SMPS45_CTRL_STATUS_MASK 0x30 -#define PALMAS_SMPS45_CTRL_STATUS_SHIFT 4 -#define PALMAS_SMPS45_CTRL_MODE_SLEEP_MASK 0x0c -#define PALMAS_SMPS45_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_SMPS45_CTRL_MODE_ACTIVE_MASK 0x03 -#define PALMAS_SMPS45_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for SMPS45_TSTEP */ -#define PALMAS_SMPS45_TSTEP_TSTEP_MASK 0x03 -#define PALMAS_SMPS45_TSTEP_TSTEP_SHIFT 0 - -/* Bit definitions for SMPS45_FORCE */ -#define PALMAS_SMPS45_FORCE_CMD 0x80 -#define PALMAS_SMPS45_FORCE_CMD_SHIFT 7 -#define PALMAS_SMPS45_FORCE_VSEL_MASK 0x7f -#define PALMAS_SMPS45_FORCE_VSEL_SHIFT 0 - -/* Bit definitions for SMPS45_VOLTAGE */ -#define PALMAS_SMPS45_VOLTAGE_RANGE 0x80 -#define PALMAS_SMPS45_VOLTAGE_RANGE_SHIFT 7 -#define PALMAS_SMPS45_VOLTAGE_VSEL_MASK 0x7f -#define PALMAS_SMPS45_VOLTAGE_VSEL_SHIFT 0 - -/* Bit definitions for SMPS6_CTRL */ -#define PALMAS_SMPS6_CTRL_WR_S 0x80 -#define PALMAS_SMPS6_CTRL_WR_S_SHIFT 7 -#define PALMAS_SMPS6_CTRL_ROOF_FLOOR_EN 0x40 -#define PALMAS_SMPS6_CTRL_ROOF_FLOOR_EN_SHIFT 6 -#define PALMAS_SMPS6_CTRL_STATUS_MASK 0x30 -#define PALMAS_SMPS6_CTRL_STATUS_SHIFT 4 -#define PALMAS_SMPS6_CTRL_MODE_SLEEP_MASK 0x0c -#define PALMAS_SMPS6_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_SMPS6_CTRL_MODE_ACTIVE_MASK 0x03 -#define PALMAS_SMPS6_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for SMPS6_TSTEP */ -#define PALMAS_SMPS6_TSTEP_TSTEP_MASK 0x03 -#define PALMAS_SMPS6_TSTEP_TSTEP_SHIFT 0 - -/* Bit definitions for SMPS6_FORCE */ -#define PALMAS_SMPS6_FORCE_CMD 0x80 -#define PALMAS_SMPS6_FORCE_CMD_SHIFT 7 -#define PALMAS_SMPS6_FORCE_VSEL_MASK 0x7f -#define PALMAS_SMPS6_FORCE_VSEL_SHIFT 0 - -/* Bit definitions for SMPS6_VOLTAGE */ -#define PALMAS_SMPS6_VOLTAGE_RANGE 0x80 -#define PALMAS_SMPS6_VOLTAGE_RANGE_SHIFT 7 -#define PALMAS_SMPS6_VOLTAGE_VSEL_MASK 0x7f -#define PALMAS_SMPS6_VOLTAGE_VSEL_SHIFT 0 - -/* Bit definitions for SMPS7_CTRL */ -#define PALMAS_SMPS7_CTRL_WR_S 0x80 -#define PALMAS_SMPS7_CTRL_WR_S_SHIFT 7 -#define PALMAS_SMPS7_CTRL_STATUS_MASK 0x30 -#define PALMAS_SMPS7_CTRL_STATUS_SHIFT 4 -#define PALMAS_SMPS7_CTRL_MODE_SLEEP_MASK 0x0c -#define PALMAS_SMPS7_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_SMPS7_CTRL_MODE_ACTIVE_MASK 0x03 -#define PALMAS_SMPS7_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for SMPS7_VOLTAGE */ -#define PALMAS_SMPS7_VOLTAGE_RANGE 0x80 -#define PALMAS_SMPS7_VOLTAGE_RANGE_SHIFT 7 -#define PALMAS_SMPS7_VOLTAGE_VSEL_MASK 0x7f -#define PALMAS_SMPS7_VOLTAGE_VSEL_SHIFT 0 - -/* Bit definitions for SMPS8_CTRL */ -#define PALMAS_SMPS8_CTRL_WR_S 0x80 -#define PALMAS_SMPS8_CTRL_WR_S_SHIFT 7 -#define PALMAS_SMPS8_CTRL_ROOF_FLOOR_EN 0x40 -#define PALMAS_SMPS8_CTRL_ROOF_FLOOR_EN_SHIFT 6 -#define PALMAS_SMPS8_CTRL_STATUS_MASK 0x30 -#define PALMAS_SMPS8_CTRL_STATUS_SHIFT 4 -#define PALMAS_SMPS8_CTRL_MODE_SLEEP_MASK 0x0c -#define PALMAS_SMPS8_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_SMPS8_CTRL_MODE_ACTIVE_MASK 0x03 -#define PALMAS_SMPS8_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for SMPS8_TSTEP */ -#define PALMAS_SMPS8_TSTEP_TSTEP_MASK 0x03 -#define PALMAS_SMPS8_TSTEP_TSTEP_SHIFT 0 - -/* Bit definitions for SMPS8_FORCE */ -#define PALMAS_SMPS8_FORCE_CMD 0x80 -#define PALMAS_SMPS8_FORCE_CMD_SHIFT 7 -#define PALMAS_SMPS8_FORCE_VSEL_MASK 0x7f -#define PALMAS_SMPS8_FORCE_VSEL_SHIFT 0 - -/* Bit definitions for SMPS8_VOLTAGE */ -#define PALMAS_SMPS8_VOLTAGE_RANGE 0x80 -#define PALMAS_SMPS8_VOLTAGE_RANGE_SHIFT 7 -#define PALMAS_SMPS8_VOLTAGE_VSEL_MASK 0x7f -#define PALMAS_SMPS8_VOLTAGE_VSEL_SHIFT 0 - -/* Bit definitions for SMPS9_CTRL */ -#define PALMAS_SMPS9_CTRL_WR_S 0x80 -#define PALMAS_SMPS9_CTRL_WR_S_SHIFT 7 -#define PALMAS_SMPS9_CTRL_STATUS_MASK 0x30 -#define PALMAS_SMPS9_CTRL_STATUS_SHIFT 4 -#define PALMAS_SMPS9_CTRL_MODE_SLEEP_MASK 0x0c -#define PALMAS_SMPS9_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_SMPS9_CTRL_MODE_ACTIVE_MASK 0x03 -#define PALMAS_SMPS9_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for SMPS9_VOLTAGE */ -#define PALMAS_SMPS9_VOLTAGE_RANGE 0x80 -#define PALMAS_SMPS9_VOLTAGE_RANGE_SHIFT 7 -#define PALMAS_SMPS9_VOLTAGE_VSEL_MASK 0x7f -#define PALMAS_SMPS9_VOLTAGE_VSEL_SHIFT 0 - -/* Bit definitions for SMPS10_CTRL */ -#define PALMAS_SMPS10_CTRL_MODE_SLEEP_MASK 0xf0 -#define PALMAS_SMPS10_CTRL_MODE_SLEEP_SHIFT 4 -#define PALMAS_SMPS10_CTRL_MODE_ACTIVE_MASK 0x0f -#define PALMAS_SMPS10_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for SMPS10_STATUS */ -#define PALMAS_SMPS10_STATUS_STATUS_MASK 0x0f -#define PALMAS_SMPS10_STATUS_STATUS_SHIFT 0 - -/* Bit definitions for SMPS_CTRL */ -#define PALMAS_SMPS_CTRL_SMPS45_SMPS457_EN 0x20 -#define PALMAS_SMPS_CTRL_SMPS45_SMPS457_EN_SHIFT 5 -#define PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN 0x10 -#define PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN_SHIFT 4 -#define PALMAS_SMPS_CTRL_SMPS45_PHASE_CTRL_MASK 0x0c -#define PALMAS_SMPS_CTRL_SMPS45_PHASE_CTRL_SHIFT 2 -#define PALMAS_SMPS_CTRL_SMPS123_PHASE_CTRL_MASK 0x03 -#define PALMAS_SMPS_CTRL_SMPS123_PHASE_CTRL_SHIFT 0 - -/* Bit definitions for SMPS_PD_CTRL */ -#define PALMAS_SMPS_PD_CTRL_SMPS9 0x40 -#define PALMAS_SMPS_PD_CTRL_SMPS9_SHIFT 6 -#define PALMAS_SMPS_PD_CTRL_SMPS8 0x20 -#define PALMAS_SMPS_PD_CTRL_SMPS8_SHIFT 5 -#define PALMAS_SMPS_PD_CTRL_SMPS7 0x10 -#define PALMAS_SMPS_PD_CTRL_SMPS7_SHIFT 4 -#define PALMAS_SMPS_PD_CTRL_SMPS6 0x08 -#define PALMAS_SMPS_PD_CTRL_SMPS6_SHIFT 3 -#define PALMAS_SMPS_PD_CTRL_SMPS45 0x04 -#define PALMAS_SMPS_PD_CTRL_SMPS45_SHIFT 2 -#define PALMAS_SMPS_PD_CTRL_SMPS3 0x02 -#define PALMAS_SMPS_PD_CTRL_SMPS3_SHIFT 1 -#define PALMAS_SMPS_PD_CTRL_SMPS12 0x01 -#define PALMAS_SMPS_PD_CTRL_SMPS12_SHIFT 0 - -/* Bit definitions for SMPS_THERMAL_EN */ -#define PALMAS_SMPS_THERMAL_EN_SMPS9 0x40 -#define PALMAS_SMPS_THERMAL_EN_SMPS9_SHIFT 6 -#define PALMAS_SMPS_THERMAL_EN_SMPS8 0x20 -#define PALMAS_SMPS_THERMAL_EN_SMPS8_SHIFT 5 -#define PALMAS_SMPS_THERMAL_EN_SMPS6 0x08 -#define PALMAS_SMPS_THERMAL_EN_SMPS6_SHIFT 3 -#define PALMAS_SMPS_THERMAL_EN_SMPS457 0x04 -#define PALMAS_SMPS_THERMAL_EN_SMPS457_SHIFT 2 -#define PALMAS_SMPS_THERMAL_EN_SMPS123 0x01 -#define PALMAS_SMPS_THERMAL_EN_SMPS123_SHIFT 0 - -/* Bit definitions for SMPS_THERMAL_STATUS */ -#define PALMAS_SMPS_THERMAL_STATUS_SMPS9 0x40 -#define PALMAS_SMPS_THERMAL_STATUS_SMPS9_SHIFT 6 -#define PALMAS_SMPS_THERMAL_STATUS_SMPS8 0x20 -#define PALMAS_SMPS_THERMAL_STATUS_SMPS8_SHIFT 5 -#define PALMAS_SMPS_THERMAL_STATUS_SMPS6 0x08 -#define PALMAS_SMPS_THERMAL_STATUS_SMPS6_SHIFT 3 -#define PALMAS_SMPS_THERMAL_STATUS_SMPS457 0x04 -#define PALMAS_SMPS_THERMAL_STATUS_SMPS457_SHIFT 2 -#define PALMAS_SMPS_THERMAL_STATUS_SMPS123 0x01 -#define PALMAS_SMPS_THERMAL_STATUS_SMPS123_SHIFT 0 - -/* Bit definitions for SMPS_SHORT_STATUS */ -#define PALMAS_SMPS_SHORT_STATUS_SMPS10 0x80 -#define PALMAS_SMPS_SHORT_STATUS_SMPS10_SHIFT 7 -#define PALMAS_SMPS_SHORT_STATUS_SMPS9 0x40 -#define PALMAS_SMPS_SHORT_STATUS_SMPS9_SHIFT 6 -#define PALMAS_SMPS_SHORT_STATUS_SMPS8 0x20 -#define PALMAS_SMPS_SHORT_STATUS_SMPS8_SHIFT 5 -#define PALMAS_SMPS_SHORT_STATUS_SMPS7 0x10 -#define PALMAS_SMPS_SHORT_STATUS_SMPS7_SHIFT 4 -#define PALMAS_SMPS_SHORT_STATUS_SMPS6 0x08 -#define PALMAS_SMPS_SHORT_STATUS_SMPS6_SHIFT 3 -#define PALMAS_SMPS_SHORT_STATUS_SMPS45 0x04 -#define PALMAS_SMPS_SHORT_STATUS_SMPS45_SHIFT 2 -#define PALMAS_SMPS_SHORT_STATUS_SMPS3 0x02 -#define PALMAS_SMPS_SHORT_STATUS_SMPS3_SHIFT 1 -#define PALMAS_SMPS_SHORT_STATUS_SMPS12 0x01 -#define PALMAS_SMPS_SHORT_STATUS_SMPS12_SHIFT 0 - -/* Bit definitions for SMPS_NEGATIVE_CURRENT_LIMIT_EN */ -#define PALMAS_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS9 0x40 -#define PALMAS_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS9_SHIFT 6 -#define PALMAS_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS8 0x20 -#define PALMAS_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS8_SHIFT 5 -#define PALMAS_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS7 0x10 -#define PALMAS_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS7_SHIFT 4 -#define PALMAS_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS6 0x08 -#define PALMAS_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS6_SHIFT 3 -#define PALMAS_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS45 0x04 -#define PALMAS_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS45_SHIFT 2 -#define PALMAS_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS3 0x02 -#define PALMAS_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS3_SHIFT 1 -#define PALMAS_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS12 0x01 -#define PALMAS_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS12_SHIFT 0 - -/* Bit definitions for SMPS_POWERGOOD_MASK1 */ -#define PALMAS_SMPS_POWERGOOD_MASK1_SMPS10 0x80 -#define PALMAS_SMPS_POWERGOOD_MASK1_SMPS10_SHIFT 7 -#define PALMAS_SMPS_POWERGOOD_MASK1_SMPS9 0x40 -#define PALMAS_SMPS_POWERGOOD_MASK1_SMPS9_SHIFT 6 -#define PALMAS_SMPS_POWERGOOD_MASK1_SMPS8 0x20 -#define PALMAS_SMPS_POWERGOOD_MASK1_SMPS8_SHIFT 5 -#define PALMAS_SMPS_POWERGOOD_MASK1_SMPS7 0x10 -#define PALMAS_SMPS_POWERGOOD_MASK1_SMPS7_SHIFT 4 -#define PALMAS_SMPS_POWERGOOD_MASK1_SMPS6 0x08 -#define PALMAS_SMPS_POWERGOOD_MASK1_SMPS6_SHIFT 3 -#define PALMAS_SMPS_POWERGOOD_MASK1_SMPS45 0x04 -#define PALMAS_SMPS_POWERGOOD_MASK1_SMPS45_SHIFT 2 -#define PALMAS_SMPS_POWERGOOD_MASK1_SMPS3 0x02 -#define PALMAS_SMPS_POWERGOOD_MASK1_SMPS3_SHIFT 1 -#define PALMAS_SMPS_POWERGOOD_MASK1_SMPS12 0x01 -#define PALMAS_SMPS_POWERGOOD_MASK1_SMPS12_SHIFT 0 - -/* Bit definitions for SMPS_POWERGOOD_MASK2 */ -#define PALMAS_SMPS_POWERGOOD_MASK2_POWERGOOD_TYPE_SELECT 0x80 -#define PALMAS_SMPS_POWERGOOD_MASK2_POWERGOOD_TYPE_SELECT_SHIFT 7 -#define PALMAS_SMPS_POWERGOOD_MASK2_GPIO_7 0x04 -#define PALMAS_SMPS_POWERGOOD_MASK2_GPIO_7_SHIFT 2 -#define PALMAS_SMPS_POWERGOOD_MASK2_VBUS 0x02 -#define PALMAS_SMPS_POWERGOOD_MASK2_VBUS_SHIFT 1 -#define PALMAS_SMPS_POWERGOOD_MASK2_ACOK 0x01 -#define PALMAS_SMPS_POWERGOOD_MASK2_ACOK_SHIFT 0 - -/* Registers for function LDO */ -#define PALMAS_LDO1_CTRL 0x0 -#define PALMAS_LDO1_VOLTAGE 0x1 -#define PALMAS_LDO2_CTRL 0x2 -#define PALMAS_LDO2_VOLTAGE 0x3 -#define PALMAS_LDO3_CTRL 0x4 -#define PALMAS_LDO3_VOLTAGE 0x5 -#define PALMAS_LDO4_CTRL 0x6 -#define PALMAS_LDO4_VOLTAGE 0x7 -#define PALMAS_LDO5_CTRL 0x8 -#define PALMAS_LDO5_VOLTAGE 0x9 -#define PALMAS_LDO6_CTRL 0xA -#define PALMAS_LDO6_VOLTAGE 0xB -#define PALMAS_LDO7_CTRL 0xC -#define PALMAS_LDO7_VOLTAGE 0xD -#define PALMAS_LDO8_CTRL 0xE -#define PALMAS_LDO8_VOLTAGE 0xF -#define PALMAS_LDO9_CTRL 0x10 -#define PALMAS_LDO9_VOLTAGE 0x11 -#define PALMAS_LDOLN_CTRL 0x12 -#define PALMAS_LDOLN_VOLTAGE 0x13 -#define PALMAS_LDOUSB_CTRL 0x14 -#define PALMAS_LDOUSB_VOLTAGE 0x15 -#define PALMAS_LDO_CTRL 0x1A -#define PALMAS_LDO_PD_CTRL1 0x1B -#define PALMAS_LDO_PD_CTRL2 0x1C -#define PALMAS_LDO_SHORT_STATUS1 0x1D -#define PALMAS_LDO_SHORT_STATUS2 0x1E - -/* Bit definitions for LDO1_CTRL */ -#define PALMAS_LDO1_CTRL_WR_S 0x80 -#define PALMAS_LDO1_CTRL_WR_S_SHIFT 7 -#define PALMAS_LDO1_CTRL_STATUS 0x10 -#define PALMAS_LDO1_CTRL_STATUS_SHIFT 4 -#define PALMAS_LDO1_CTRL_MODE_SLEEP 0x04 -#define PALMAS_LDO1_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_LDO1_CTRL_MODE_ACTIVE 0x01 -#define PALMAS_LDO1_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for LDO1_VOLTAGE */ -#define PALMAS_LDO1_VOLTAGE_VSEL_MASK 0x3f -#define PALMAS_LDO1_VOLTAGE_VSEL_SHIFT 0 - -/* Bit definitions for LDO2_CTRL */ -#define PALMAS_LDO2_CTRL_WR_S 0x80 -#define PALMAS_LDO2_CTRL_WR_S_SHIFT 7 -#define PALMAS_LDO2_CTRL_STATUS 0x10 -#define PALMAS_LDO2_CTRL_STATUS_SHIFT 4 -#define PALMAS_LDO2_CTRL_MODE_SLEEP 0x04 -#define PALMAS_LDO2_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_LDO2_CTRL_MODE_ACTIVE 0x01 -#define PALMAS_LDO2_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for LDO2_VOLTAGE */ -#define PALMAS_LDO2_VOLTAGE_VSEL_MASK 0x3f -#define PALMAS_LDO2_VOLTAGE_VSEL_SHIFT 0 - -/* Bit definitions for LDO3_CTRL */ -#define PALMAS_LDO3_CTRL_WR_S 0x80 -#define PALMAS_LDO3_CTRL_WR_S_SHIFT 7 -#define PALMAS_LDO3_CTRL_STATUS 0x10 -#define PALMAS_LDO3_CTRL_STATUS_SHIFT 4 -#define PALMAS_LDO3_CTRL_MODE_SLEEP 0x04 -#define PALMAS_LDO3_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_LDO3_CTRL_MODE_ACTIVE 0x01 -#define PALMAS_LDO3_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for LDO3_VOLTAGE */ -#define PALMAS_LDO3_VOLTAGE_VSEL_MASK 0x3f -#define PALMAS_LDO3_VOLTAGE_VSEL_SHIFT 0 - -/* Bit definitions for LDO4_CTRL */ -#define PALMAS_LDO4_CTRL_WR_S 0x80 -#define PALMAS_LDO4_CTRL_WR_S_SHIFT 7 -#define PALMAS_LDO4_CTRL_STATUS 0x10 -#define PALMAS_LDO4_CTRL_STATUS_SHIFT 4 -#define PALMAS_LDO4_CTRL_MODE_SLEEP 0x04 -#define PALMAS_LDO4_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_LDO4_CTRL_MODE_ACTIVE 0x01 -#define PALMAS_LDO4_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for LDO4_VOLTAGE */ -#define PALMAS_LDO4_VOLTAGE_VSEL_MASK 0x3f -#define PALMAS_LDO4_VOLTAGE_VSEL_SHIFT 0 - -/* Bit definitions for LDO5_CTRL */ -#define PALMAS_LDO5_CTRL_WR_S 0x80 -#define PALMAS_LDO5_CTRL_WR_S_SHIFT 7 -#define PALMAS_LDO5_CTRL_STATUS 0x10 -#define PALMAS_LDO5_CTRL_STATUS_SHIFT 4 -#define PALMAS_LDO5_CTRL_MODE_SLEEP 0x04 -#define PALMAS_LDO5_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_LDO5_CTRL_MODE_ACTIVE 0x01 -#define PALMAS_LDO5_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for LDO5_VOLTAGE */ -#define PALMAS_LDO5_VOLTAGE_VSEL_MASK 0x3f -#define PALMAS_LDO5_VOLTAGE_VSEL_SHIFT 0 - -/* Bit definitions for LDO6_CTRL */ -#define PALMAS_LDO6_CTRL_WR_S 0x80 -#define PALMAS_LDO6_CTRL_WR_S_SHIFT 7 -#define PALMAS_LDO6_CTRL_LDO_VIB_EN 0x40 -#define PALMAS_LDO6_CTRL_LDO_VIB_EN_SHIFT 6 -#define PALMAS_LDO6_CTRL_STATUS 0x10 -#define PALMAS_LDO6_CTRL_STATUS_SHIFT 4 -#define PALMAS_LDO6_CTRL_MODE_SLEEP 0x04 -#define PALMAS_LDO6_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_LDO6_CTRL_MODE_ACTIVE 0x01 -#define PALMAS_LDO6_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for LDO6_VOLTAGE */ -#define PALMAS_LDO6_VOLTAGE_VSEL_MASK 0x3f -#define PALMAS_LDO6_VOLTAGE_VSEL_SHIFT 0 - -/* Bit definitions for LDO7_CTRL */ -#define PALMAS_LDO7_CTRL_WR_S 0x80 -#define PALMAS_LDO7_CTRL_WR_S_SHIFT 7 -#define PALMAS_LDO7_CTRL_STATUS 0x10 -#define PALMAS_LDO7_CTRL_STATUS_SHIFT 4 -#define PALMAS_LDO7_CTRL_MODE_SLEEP 0x04 -#define PALMAS_LDO7_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_LDO7_CTRL_MODE_ACTIVE 0x01 -#define PALMAS_LDO7_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for LDO7_VOLTAGE */ -#define PALMAS_LDO7_VOLTAGE_VSEL_MASK 0x3f -#define PALMAS_LDO7_VOLTAGE_VSEL_SHIFT 0 - -/* Bit definitions for LDO8_CTRL */ -#define PALMAS_LDO8_CTRL_WR_S 0x80 -#define PALMAS_LDO8_CTRL_WR_S_SHIFT 7 -#define PALMAS_LDO8_CTRL_LDO_TRACKING_EN 0x40 -#define PALMAS_LDO8_CTRL_LDO_TRACKING_EN_SHIFT 6 -#define PALMAS_LDO8_CTRL_STATUS 0x10 -#define PALMAS_LDO8_CTRL_STATUS_SHIFT 4 -#define PALMAS_LDO8_CTRL_MODE_SLEEP 0x04 -#define PALMAS_LDO8_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_LDO8_CTRL_MODE_ACTIVE 0x01 -#define PALMAS_LDO8_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for LDO8_VOLTAGE */ -#define PALMAS_LDO8_VOLTAGE_VSEL_MASK 0x3f -#define PALMAS_LDO8_VOLTAGE_VSEL_SHIFT 0 - -/* Bit definitions for LDO9_CTRL */ -#define PALMAS_LDO9_CTRL_WR_S 0x80 -#define PALMAS_LDO9_CTRL_WR_S_SHIFT 7 -#define PALMAS_LDO9_CTRL_LDO_BYPASS_EN 0x40 -#define PALMAS_LDO9_CTRL_LDO_BYPASS_EN_SHIFT 6 -#define PALMAS_LDO9_CTRL_STATUS 0x10 -#define PALMAS_LDO9_CTRL_STATUS_SHIFT 4 -#define PALMAS_LDO9_CTRL_MODE_SLEEP 0x04 -#define PALMAS_LDO9_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_LDO9_CTRL_MODE_ACTIVE 0x01 -#define PALMAS_LDO9_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for LDO9_VOLTAGE */ -#define PALMAS_LDO9_VOLTAGE_VSEL_MASK 0x3f -#define PALMAS_LDO9_VOLTAGE_VSEL_SHIFT 0 - -/* Bit definitions for LDOLN_CTRL */ -#define PALMAS_LDOLN_CTRL_WR_S 0x80 -#define PALMAS_LDOLN_CTRL_WR_S_SHIFT 7 -#define PALMAS_LDOLN_CTRL_STATUS 0x10 -#define PALMAS_LDOLN_CTRL_STATUS_SHIFT 4 -#define PALMAS_LDOLN_CTRL_MODE_SLEEP 0x04 -#define PALMAS_LDOLN_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_LDOLN_CTRL_MODE_ACTIVE 0x01 -#define PALMAS_LDOLN_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for LDOLN_VOLTAGE */ -#define PALMAS_LDOLN_VOLTAGE_VSEL_MASK 0x3f -#define PALMAS_LDOLN_VOLTAGE_VSEL_SHIFT 0 - -/* Bit definitions for LDOUSB_CTRL */ -#define PALMAS_LDOUSB_CTRL_WR_S 0x80 -#define PALMAS_LDOUSB_CTRL_WR_S_SHIFT 7 -#define PALMAS_LDOUSB_CTRL_STATUS 0x10 -#define PALMAS_LDOUSB_CTRL_STATUS_SHIFT 4 -#define PALMAS_LDOUSB_CTRL_MODE_SLEEP 0x04 -#define PALMAS_LDOUSB_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_LDOUSB_CTRL_MODE_ACTIVE 0x01 -#define PALMAS_LDOUSB_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for LDOUSB_VOLTAGE */ -#define PALMAS_LDOUSB_VOLTAGE_VSEL_MASK 0x3f -#define PALMAS_LDOUSB_VOLTAGE_VSEL_SHIFT 0 - -/* Bit definitions for LDO_CTRL */ -#define PALMAS_LDO_CTRL_LDOUSB_ON_VBUS_VSYS 0x01 -#define PALMAS_LDO_CTRL_LDOUSB_ON_VBUS_VSYS_SHIFT 0 - -/* Bit definitions for LDO_PD_CTRL1 */ -#define PALMAS_LDO_PD_CTRL1_LDO8 0x80 -#define PALMAS_LDO_PD_CTRL1_LDO8_SHIFT 7 -#define PALMAS_LDO_PD_CTRL1_LDO7 0x40 -#define PALMAS_LDO_PD_CTRL1_LDO7_SHIFT 6 -#define PALMAS_LDO_PD_CTRL1_LDO6 0x20 -#define PALMAS_LDO_PD_CTRL1_LDO6_SHIFT 5 -#define PALMAS_LDO_PD_CTRL1_LDO5 0x10 -#define PALMAS_LDO_PD_CTRL1_LDO5_SHIFT 4 -#define PALMAS_LDO_PD_CTRL1_LDO4 0x08 -#define PALMAS_LDO_PD_CTRL1_LDO4_SHIFT 3 -#define PALMAS_LDO_PD_CTRL1_LDO3 0x04 -#define PALMAS_LDO_PD_CTRL1_LDO3_SHIFT 2 -#define PALMAS_LDO_PD_CTRL1_LDO2 0x02 -#define PALMAS_LDO_PD_CTRL1_LDO2_SHIFT 1 -#define PALMAS_LDO_PD_CTRL1_LDO1 0x01 -#define PALMAS_LDO_PD_CTRL1_LDO1_SHIFT 0 - -/* Bit definitions for LDO_PD_CTRL2 */ -#define PALMAS_LDO_PD_CTRL2_LDOUSB 0x04 -#define PALMAS_LDO_PD_CTRL2_LDOUSB_SHIFT 2 -#define PALMAS_LDO_PD_CTRL2_LDOLN 0x02 -#define PALMAS_LDO_PD_CTRL2_LDOLN_SHIFT 1 -#define PALMAS_LDO_PD_CTRL2_LDO9 0x01 -#define PALMAS_LDO_PD_CTRL2_LDO9_SHIFT 0 - -/* Bit definitions for LDO_SHORT_STATUS1 */ -#define PALMAS_LDO_SHORT_STATUS1_LDO8 0x80 -#define PALMAS_LDO_SHORT_STATUS1_LDO8_SHIFT 7 -#define PALMAS_LDO_SHORT_STATUS1_LDO7 0x40 -#define PALMAS_LDO_SHORT_STATUS1_LDO7_SHIFT 6 -#define PALMAS_LDO_SHORT_STATUS1_LDO6 0x20 -#define PALMAS_LDO_SHORT_STATUS1_LDO6_SHIFT 5 -#define PALMAS_LDO_SHORT_STATUS1_LDO5 0x10 -#define PALMAS_LDO_SHORT_STATUS1_LDO5_SHIFT 4 -#define PALMAS_LDO_SHORT_STATUS1_LDO4 0x08 -#define PALMAS_LDO_SHORT_STATUS1_LDO4_SHIFT 3 -#define PALMAS_LDO_SHORT_STATUS1_LDO3 0x04 -#define PALMAS_LDO_SHORT_STATUS1_LDO3_SHIFT 2 -#define PALMAS_LDO_SHORT_STATUS1_LDO2 0x02 -#define PALMAS_LDO_SHORT_STATUS1_LDO2_SHIFT 1 -#define PALMAS_LDO_SHORT_STATUS1_LDO1 0x01 -#define PALMAS_LDO_SHORT_STATUS1_LDO1_SHIFT 0 - -/* Bit definitions for LDO_SHORT_STATUS2 */ -#define PALMAS_LDO_SHORT_STATUS2_LDOVANA 0x08 -#define PALMAS_LDO_SHORT_STATUS2_LDOVANA_SHIFT 3 -#define PALMAS_LDO_SHORT_STATUS2_LDOUSB 0x04 -#define PALMAS_LDO_SHORT_STATUS2_LDOUSB_SHIFT 2 -#define PALMAS_LDO_SHORT_STATUS2_LDOLN 0x02 -#define PALMAS_LDO_SHORT_STATUS2_LDOLN_SHIFT 1 -#define PALMAS_LDO_SHORT_STATUS2_LDO9 0x01 -#define PALMAS_LDO_SHORT_STATUS2_LDO9_SHIFT 0 - -/* Registers for function PMU_CONTROL */ -#define PALMAS_DEV_CTRL 0x0 -#define PALMAS_POWER_CTRL 0x1 -#define PALMAS_VSYS_LO 0x2 -#define PALMAS_VSYS_MON 0x3 -#define PALMAS_VBAT_MON 0x4 -#define PALMAS_WATCHDOG 0x5 -#define PALMAS_BOOT_STATUS 0x6 -#define PALMAS_BATTERY_BOUNCE 0x7 -#define PALMAS_BACKUP_BATTERY_CTRL 0x8 -#define PALMAS_LONG_PRESS_KEY 0x9 -#define PALMAS_OSC_THERM_CTRL 0xA -#define PALMAS_BATDEBOUNCING 0xB -#define PALMAS_SWOFF_HWRST 0xF -#define PALMAS_SWOFF_COLDRST 0x10 -#define PALMAS_SWOFF_STATUS 0x11 -#define PALMAS_PMU_CONFIG 0x12 -#define PALMAS_SPARE 0x14 -#define PALMAS_PMU_SECONDARY_INT 0x15 -#define PALMAS_SW_REVISION 0x17 -#define PALMAS_EXT_CHRG_CTRL 0x18 -#define PALMAS_PMU_SECONDARY_INT2 0x19 - -/* Bit definitions for DEV_CTRL */ -#define PALMAS_DEV_CTRL_DEV_STATUS_MASK 0x0c -#define PALMAS_DEV_CTRL_DEV_STATUS_SHIFT 2 -#define PALMAS_DEV_CTRL_SW_RST 0x02 -#define PALMAS_DEV_CTRL_SW_RST_SHIFT 1 -#define PALMAS_DEV_CTRL_DEV_ON 0x01 -#define PALMAS_DEV_CTRL_DEV_ON_SHIFT 0 - -/* Bit definitions for POWER_CTRL */ -#define PALMAS_POWER_CTRL_ENABLE2_MASK 0x04 -#define PALMAS_POWER_CTRL_ENABLE2_MASK_SHIFT 2 -#define PALMAS_POWER_CTRL_ENABLE1_MASK 0x02 -#define PALMAS_POWER_CTRL_ENABLE1_MASK_SHIFT 1 -#define PALMAS_POWER_CTRL_NSLEEP_MASK 0x01 -#define PALMAS_POWER_CTRL_NSLEEP_MASK_SHIFT 0 - -/* Bit definitions for VSYS_LO */ -#define PALMAS_VSYS_LO_THRESHOLD_MASK 0x1f -#define PALMAS_VSYS_LO_THRESHOLD_SHIFT 0 - -/* Bit definitions for VSYS_MON */ -#define PALMAS_VSYS_MON_ENABLE 0x80 -#define PALMAS_VSYS_MON_ENABLE_SHIFT 7 -#define PALMAS_VSYS_MON_THRESHOLD_MASK 0x3f -#define PALMAS_VSYS_MON_THRESHOLD_SHIFT 0 - -/* Bit definitions for VBAT_MON */ -#define PALMAS_VBAT_MON_ENABLE 0x80 -#define PALMAS_VBAT_MON_ENABLE_SHIFT 7 -#define PALMAS_VBAT_MON_THRESHOLD_MASK 0x3f -#define PALMAS_VBAT_MON_THRESHOLD_SHIFT 0 - -/* Bit definitions for WATCHDOG */ -#define PALMAS_WATCHDOG_LOCK 0x20 -#define PALMAS_WATCHDOG_LOCK_SHIFT 5 -#define PALMAS_WATCHDOG_ENABLE 0x10 -#define PALMAS_WATCHDOG_ENABLE_SHIFT 4 -#define PALMAS_WATCHDOG_MODE 0x08 -#define PALMAS_WATCHDOG_MODE_SHIFT 3 -#define PALMAS_WATCHDOG_TIMER_MASK 0x07 -#define PALMAS_WATCHDOG_TIMER_SHIFT 0 - -/* Bit definitions for BOOT_STATUS */ -#define PALMAS_BOOT_STATUS_BOOT1 0x02 -#define PALMAS_BOOT_STATUS_BOOT1_SHIFT 1 -#define PALMAS_BOOT_STATUS_BOOT0 0x01 -#define PALMAS_BOOT_STATUS_BOOT0_SHIFT 0 - -/* Bit definitions for BATTERY_BOUNCE */ -#define PALMAS_BATTERY_BOUNCE_BB_DELAY_MASK 0x3f -#define PALMAS_BATTERY_BOUNCE_BB_DELAY_SHIFT 0 - -/* Bit definitions for BACKUP_BATTERY_CTRL */ -#define PALMAS_BACKUP_BATTERY_CTRL_VRTC_18_15 0x80 -#define PALMAS_BACKUP_BATTERY_CTRL_VRTC_18_15_SHIFT 7 -#define PALMAS_BACKUP_BATTERY_CTRL_VRTC_EN_SLP 0x40 -#define PALMAS_BACKUP_BATTERY_CTRL_VRTC_EN_SLP_SHIFT 6 -#define PALMAS_BACKUP_BATTERY_CTRL_VRTC_EN_OFF 0x20 -#define PALMAS_BACKUP_BATTERY_CTRL_VRTC_EN_OFF_SHIFT 5 -#define PALMAS_BACKUP_BATTERY_CTRL_VRTC_PWEN 0x10 -#define PALMAS_BACKUP_BATTERY_CTRL_VRTC_PWEN_SHIFT 4 -#define PALMAS_BACKUP_BATTERY_CTRL_BBS_BBC_LOW_ICHRG 0x08 -#define PALMAS_BACKUP_BATTERY_CTRL_BBS_BBC_LOW_ICHRG_SHIFT 3 -#define PALMAS_BACKUP_BATTERY_CTRL_BB_SEL_MASK 0x06 -#define PALMAS_BACKUP_BATTERY_CTRL_BB_SEL_SHIFT 1 -#define PALMAS_BACKUP_BATTERY_CTRL_BB_CHG_EN 0x01 -#define PALMAS_BACKUP_BATTERY_CTRL_BB_CHG_EN_SHIFT 0 - -/* Bit definitions for LONG_PRESS_KEY */ -#define PALMAS_LONG_PRESS_KEY_LPK_LOCK 0x80 -#define PALMAS_LONG_PRESS_KEY_LPK_LOCK_SHIFT 7 -#define PALMAS_LONG_PRESS_KEY_LPK_INT_CLR 0x10 -#define PALMAS_LONG_PRESS_KEY_LPK_INT_CLR_SHIFT 4 -#define PALMAS_LONG_PRESS_KEY_LPK_TIME_MASK 0x0c -#define PALMAS_LONG_PRESS_KEY_LPK_TIME_SHIFT 2 -#define PALMAS_LONG_PRESS_KEY_PWRON_DEBOUNCE_MASK 0x03 -#define PALMAS_LONG_PRESS_KEY_PWRON_DEBOUNCE_SHIFT 0 - -/* Bit definitions for OSC_THERM_CTRL */ -#define PALMAS_OSC_THERM_CTRL_VANA_ON_IN_SLEEP 0x80 -#define PALMAS_OSC_THERM_CTRL_VANA_ON_IN_SLEEP_SHIFT 7 -#define PALMAS_OSC_THERM_CTRL_INT_MASK_IN_SLEEP 0x40 -#define PALMAS_OSC_THERM_CTRL_INT_MASK_IN_SLEEP_SHIFT 6 -#define PALMAS_OSC_THERM_CTRL_RC15MHZ_ON_IN_SLEEP 0x20 -#define PALMAS_OSC_THERM_CTRL_RC15MHZ_ON_IN_SLEEP_SHIFT 5 -#define PALMAS_OSC_THERM_CTRL_THERM_OFF_IN_SLEEP 0x10 -#define PALMAS_OSC_THERM_CTRL_THERM_OFF_IN_SLEEP_SHIFT 4 -#define PALMAS_OSC_THERM_CTRL_THERM_HD_SEL_MASK 0x0c -#define PALMAS_OSC_THERM_CTRL_THERM_HD_SEL_SHIFT 2 -#define PALMAS_OSC_THERM_CTRL_OSC_BYPASS 0x02 -#define PALMAS_OSC_THERM_CTRL_OSC_BYPASS_SHIFT 1 -#define PALMAS_OSC_THERM_CTRL_OSC_HPMODE 0x01 -#define PALMAS_OSC_THERM_CTRL_OSC_HPMODE_SHIFT 0 - -/* Bit definitions for BATDEBOUNCING */ -#define PALMAS_BATDEBOUNCING_BAT_DEB_BYPASS 0x80 -#define PALMAS_BATDEBOUNCING_BAT_DEB_BYPASS_SHIFT 7 -#define PALMAS_BATDEBOUNCING_BINS_DEB_MASK 0x78 -#define PALMAS_BATDEBOUNCING_BINS_DEB_SHIFT 3 -#define PALMAS_BATDEBOUNCING_BEXT_DEB_MASK 0x07 -#define PALMAS_BATDEBOUNCING_BEXT_DEB_SHIFT 0 - -/* Bit definitions for SWOFF_HWRST */ -#define PALMAS_SWOFF_HWRST_PWRON_LPK 0x80 -#define PALMAS_SWOFF_HWRST_PWRON_LPK_SHIFT 7 -#define PALMAS_SWOFF_HWRST_PWRDOWN 0x40 -#define PALMAS_SWOFF_HWRST_PWRDOWN_SHIFT 6 -#define PALMAS_SWOFF_HWRST_WTD 0x20 -#define PALMAS_SWOFF_HWRST_WTD_SHIFT 5 -#define PALMAS_SWOFF_HWRST_TSHUT 0x10 -#define PALMAS_SWOFF_HWRST_TSHUT_SHIFT 4 -#define PALMAS_SWOFF_HWRST_RESET_IN 0x08 -#define PALMAS_SWOFF_HWRST_RESET_IN_SHIFT 3 -#define PALMAS_SWOFF_HWRST_SW_RST 0x04 -#define PALMAS_SWOFF_HWRST_SW_RST_SHIFT 2 -#define PALMAS_SWOFF_HWRST_VSYS_LO 0x02 -#define PALMAS_SWOFF_HWRST_VSYS_LO_SHIFT 1 -#define PALMAS_SWOFF_HWRST_GPADC_SHUTDOWN 0x01 -#define PALMAS_SWOFF_HWRST_GPADC_SHUTDOWN_SHIFT 0 - -/* Bit definitions for SWOFF_COLDRST */ -#define PALMAS_SWOFF_COLDRST_PWRON_LPK 0x80 -#define PALMAS_SWOFF_COLDRST_PWRON_LPK_SHIFT 7 -#define PALMAS_SWOFF_COLDRST_PWRDOWN 0x40 -#define PALMAS_SWOFF_COLDRST_PWRDOWN_SHIFT 6 -#define PALMAS_SWOFF_COLDRST_WTD 0x20 -#define PALMAS_SWOFF_COLDRST_WTD_SHIFT 5 -#define PALMAS_SWOFF_COLDRST_TSHUT 0x10 -#define PALMAS_SWOFF_COLDRST_TSHUT_SHIFT 4 -#define PALMAS_SWOFF_COLDRST_RESET_IN 0x08 -#define PALMAS_SWOFF_COLDRST_RESET_IN_SHIFT 3 -#define PALMAS_SWOFF_COLDRST_SW_RST 0x04 -#define PALMAS_SWOFF_COLDRST_SW_RST_SHIFT 2 -#define PALMAS_SWOFF_COLDRST_VSYS_LO 0x02 -#define PALMAS_SWOFF_COLDRST_VSYS_LO_SHIFT 1 -#define PALMAS_SWOFF_COLDRST_GPADC_SHUTDOWN 0x01 -#define PALMAS_SWOFF_COLDRST_GPADC_SHUTDOWN_SHIFT 0 - -/* Bit definitions for SWOFF_STATUS */ -#define PALMAS_SWOFF_STATUS_PWRON_LPK 0x80 -#define PALMAS_SWOFF_STATUS_PWRON_LPK_SHIFT 7 -#define PALMAS_SWOFF_STATUS_PWRDOWN 0x40 -#define PALMAS_SWOFF_STATUS_PWRDOWN_SHIFT 6 -#define PALMAS_SWOFF_STATUS_WTD 0x20 -#define PALMAS_SWOFF_STATUS_WTD_SHIFT 5 -#define PALMAS_SWOFF_STATUS_TSHUT 0x10 -#define PALMAS_SWOFF_STATUS_TSHUT_SHIFT 4 -#define PALMAS_SWOFF_STATUS_RESET_IN 0x08 -#define PALMAS_SWOFF_STATUS_RESET_IN_SHIFT 3 -#define PALMAS_SWOFF_STATUS_SW_RST 0x04 -#define PALMAS_SWOFF_STATUS_SW_RST_SHIFT 2 -#define PALMAS_SWOFF_STATUS_VSYS_LO 0x02 -#define PALMAS_SWOFF_STATUS_VSYS_LO_SHIFT 1 -#define PALMAS_SWOFF_STATUS_GPADC_SHUTDOWN 0x01 -#define PALMAS_SWOFF_STATUS_GPADC_SHUTDOWN_SHIFT 0 - -/* Bit definitions for PMU_CONFIG */ -#define PALMAS_PMU_CONFIG_MULTI_CELL_EN 0x40 -#define PALMAS_PMU_CONFIG_MULTI_CELL_EN_SHIFT 6 -#define PALMAS_PMU_CONFIG_SPARE_MASK 0x30 -#define PALMAS_PMU_CONFIG_SPARE_SHIFT 4 -#define PALMAS_PMU_CONFIG_SWOFF_DLY_MASK 0x0c -#define PALMAS_PMU_CONFIG_SWOFF_DLY_SHIFT 2 -#define PALMAS_PMU_CONFIG_GATE_RESET_OUT 0x02 -#define PALMAS_PMU_CONFIG_GATE_RESET_OUT_SHIFT 1 -#define PALMAS_PMU_CONFIG_AUTODEVON 0x01 -#define PALMAS_PMU_CONFIG_AUTODEVON_SHIFT 0 - -/* Bit definitions for SPARE */ -#define PALMAS_SPARE_SPARE_MASK 0xf8 -#define PALMAS_SPARE_SPARE_SHIFT 3 -#define PALMAS_SPARE_REGEN3_OD 0x04 -#define PALMAS_SPARE_REGEN3_OD_SHIFT 2 -#define PALMAS_SPARE_REGEN2_OD 0x02 -#define PALMAS_SPARE_REGEN2_OD_SHIFT 1 -#define PALMAS_SPARE_REGEN1_OD 0x01 -#define PALMAS_SPARE_REGEN1_OD_SHIFT 0 - -/* Bit definitions for PMU_SECONDARY_INT */ -#define PALMAS_PMU_SECONDARY_INT_VBUS_OVV_INT_SRC 0x80 -#define PALMAS_PMU_SECONDARY_INT_VBUS_OVV_INT_SRC_SHIFT 7 -#define PALMAS_PMU_SECONDARY_INT_CHARG_DET_N_INT_SRC 0x40 -#define PALMAS_PMU_SECONDARY_INT_CHARG_DET_N_INT_SRC_SHIFT 6 -#define PALMAS_PMU_SECONDARY_INT_BB_INT_SRC 0x20 -#define PALMAS_PMU_SECONDARY_INT_BB_INT_SRC_SHIFT 5 -#define PALMAS_PMU_SECONDARY_INT_FBI_INT_SRC 0x10 -#define PALMAS_PMU_SECONDARY_INT_FBI_INT_SRC_SHIFT 4 -#define PALMAS_PMU_SECONDARY_INT_VBUS_OVV_MASK 0x08 -#define PALMAS_PMU_SECONDARY_INT_VBUS_OVV_MASK_SHIFT 3 -#define PALMAS_PMU_SECONDARY_INT_CHARG_DET_N_MASK 0x04 -#define PALMAS_PMU_SECONDARY_INT_CHARG_DET_N_MASK_SHIFT 2 -#define PALMAS_PMU_SECONDARY_INT_BB_MASK 0x02 -#define PALMAS_PMU_SECONDARY_INT_BB_MASK_SHIFT 1 -#define PALMAS_PMU_SECONDARY_INT_FBI_MASK 0x01 -#define PALMAS_PMU_SECONDARY_INT_FBI_MASK_SHIFT 0 - -/* Bit definitions for SW_REVISION */ -#define PALMAS_SW_REVISION_SW_REVISION_MASK 0xff -#define PALMAS_SW_REVISION_SW_REVISION_SHIFT 0 - -/* Bit definitions for EXT_CHRG_CTRL */ -#define PALMAS_EXT_CHRG_CTRL_VBUS_OVV_STATUS 0x80 -#define PALMAS_EXT_CHRG_CTRL_VBUS_OVV_STATUS_SHIFT 7 -#define PALMAS_EXT_CHRG_CTRL_CHARG_DET_N_STATUS 0x40 -#define PALMAS_EXT_CHRG_CTRL_CHARG_DET_N_STATUS_SHIFT 6 -#define PALMAS_EXT_CHRG_CTRL_VSYS_DEBOUNCE_DELAY 0x08 -#define PALMAS_EXT_CHRG_CTRL_VSYS_DEBOUNCE_DELAY_SHIFT 3 -#define PALMAS_EXT_CHRG_CTRL_CHRG_DET_N 0x04 -#define PALMAS_EXT_CHRG_CTRL_CHRG_DET_N_SHIFT 2 -#define PALMAS_EXT_CHRG_CTRL_AUTO_ACA_EN 0x02 -#define PALMAS_EXT_CHRG_CTRL_AUTO_ACA_EN_SHIFT 1 -#define PALMAS_EXT_CHRG_CTRL_AUTO_LDOUSB_EN 0x01 -#define PALMAS_EXT_CHRG_CTRL_AUTO_LDOUSB_EN_SHIFT 0 - -/* Bit definitions for PMU_SECONDARY_INT2 */ -#define PALMAS_PMU_SECONDARY_INT2_DVFS2_INT_SRC 0x20 -#define PALMAS_PMU_SECONDARY_INT2_DVFS2_INT_SRC_SHIFT 5 -#define PALMAS_PMU_SECONDARY_INT2_DVFS1_INT_SRC 0x10 -#define PALMAS_PMU_SECONDARY_INT2_DVFS1_INT_SRC_SHIFT 4 -#define PALMAS_PMU_SECONDARY_INT2_DVFS2_MASK 0x02 -#define PALMAS_PMU_SECONDARY_INT2_DVFS2_MASK_SHIFT 1 -#define PALMAS_PMU_SECONDARY_INT2_DVFS1_MASK 0x01 -#define PALMAS_PMU_SECONDARY_INT2_DVFS1_MASK_SHIFT 0 - -/* Registers for function RESOURCE */ -#define PALMAS_CLK32KG_CTRL 0x0 -#define PALMAS_CLK32KGAUDIO_CTRL 0x1 -#define PALMAS_REGEN1_CTRL 0x2 -#define PALMAS_REGEN2_CTRL 0x3 -#define PALMAS_SYSEN1_CTRL 0x4 -#define PALMAS_SYSEN2_CTRL 0x5 -#define PALMAS_NSLEEP_RES_ASSIGN 0x6 -#define PALMAS_NSLEEP_SMPS_ASSIGN 0x7 -#define PALMAS_NSLEEP_LDO_ASSIGN1 0x8 -#define PALMAS_NSLEEP_LDO_ASSIGN2 0x9 -#define PALMAS_ENABLE1_RES_ASSIGN 0xA -#define PALMAS_ENABLE1_SMPS_ASSIGN 0xB -#define PALMAS_ENABLE1_LDO_ASSIGN1 0xC -#define PALMAS_ENABLE1_LDO_ASSIGN2 0xD -#define PALMAS_ENABLE2_RES_ASSIGN 0xE -#define PALMAS_ENABLE2_SMPS_ASSIGN 0xF -#define PALMAS_ENABLE2_LDO_ASSIGN1 0x10 -#define PALMAS_ENABLE2_LDO_ASSIGN2 0x11 -#define PALMAS_REGEN3_CTRL 0x12 - -/* Bit definitions for CLK32KG_CTRL */ -#define PALMAS_CLK32KG_CTRL_STATUS 0x10 -#define PALMAS_CLK32KG_CTRL_STATUS_SHIFT 4 -#define PALMAS_CLK32KG_CTRL_MODE_SLEEP 0x04 -#define PALMAS_CLK32KG_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_CLK32KG_CTRL_MODE_ACTIVE 0x01 -#define PALMAS_CLK32KG_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for CLK32KGAUDIO_CTRL */ -#define PALMAS_CLK32KGAUDIO_CTRL_STATUS 0x10 -#define PALMAS_CLK32KGAUDIO_CTRL_STATUS_SHIFT 4 -#define PALMAS_CLK32KGAUDIO_CTRL_RESERVED3 0x08 -#define PALMAS_CLK32KGAUDIO_CTRL_RESERVED3_SHIFT 3 -#define PALMAS_CLK32KGAUDIO_CTRL_MODE_SLEEP 0x04 -#define PALMAS_CLK32KGAUDIO_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_CLK32KGAUDIO_CTRL_MODE_ACTIVE 0x01 -#define PALMAS_CLK32KGAUDIO_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for REGEN1_CTRL */ -#define PALMAS_REGEN1_CTRL_STATUS 0x10 -#define PALMAS_REGEN1_CTRL_STATUS_SHIFT 4 -#define PALMAS_REGEN1_CTRL_MODE_SLEEP 0x04 -#define PALMAS_REGEN1_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_REGEN1_CTRL_MODE_ACTIVE 0x01 -#define PALMAS_REGEN1_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for REGEN2_CTRL */ -#define PALMAS_REGEN2_CTRL_STATUS 0x10 -#define PALMAS_REGEN2_CTRL_STATUS_SHIFT 4 -#define PALMAS_REGEN2_CTRL_MODE_SLEEP 0x04 -#define PALMAS_REGEN2_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_REGEN2_CTRL_MODE_ACTIVE 0x01 -#define PALMAS_REGEN2_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for SYSEN1_CTRL */ -#define PALMAS_SYSEN1_CTRL_STATUS 0x10 -#define PALMAS_SYSEN1_CTRL_STATUS_SHIFT 4 -#define PALMAS_SYSEN1_CTRL_MODE_SLEEP 0x04 -#define PALMAS_SYSEN1_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_SYSEN1_CTRL_MODE_ACTIVE 0x01 -#define PALMAS_SYSEN1_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for SYSEN2_CTRL */ -#define PALMAS_SYSEN2_CTRL_STATUS 0x10 -#define PALMAS_SYSEN2_CTRL_STATUS_SHIFT 4 -#define PALMAS_SYSEN2_CTRL_MODE_SLEEP 0x04 -#define PALMAS_SYSEN2_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_SYSEN2_CTRL_MODE_ACTIVE 0x01 -#define PALMAS_SYSEN2_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Bit definitions for NSLEEP_RES_ASSIGN */ -#define PALMAS_NSLEEP_RES_ASSIGN_REGEN3 0x40 -#define PALMAS_NSLEEP_RES_ASSIGN_REGEN3_SHIFT 6 -#define PALMAS_NSLEEP_RES_ASSIGN_CLK32KGAUDIO 0x20 -#define PALMAS_NSLEEP_RES_ASSIGN_CLK32KGAUDIO_SHIFT 5 -#define PALMAS_NSLEEP_RES_ASSIGN_CLK32KG 0x10 -#define PALMAS_NSLEEP_RES_ASSIGN_CLK32KG_SHIFT 4 -#define PALMAS_NSLEEP_RES_ASSIGN_SYSEN2 0x08 -#define PALMAS_NSLEEP_RES_ASSIGN_SYSEN2_SHIFT 3 -#define PALMAS_NSLEEP_RES_ASSIGN_SYSEN1 0x04 -#define PALMAS_NSLEEP_RES_ASSIGN_SYSEN1_SHIFT 2 -#define PALMAS_NSLEEP_RES_ASSIGN_REGEN2 0x02 -#define PALMAS_NSLEEP_RES_ASSIGN_REGEN2_SHIFT 1 -#define PALMAS_NSLEEP_RES_ASSIGN_REGEN1 0x01 -#define PALMAS_NSLEEP_RES_ASSIGN_REGEN1_SHIFT 0 - -/* Bit definitions for NSLEEP_SMPS_ASSIGN */ -#define PALMAS_NSLEEP_SMPS_ASSIGN_SMPS10 0x80 -#define PALMAS_NSLEEP_SMPS_ASSIGN_SMPS10_SHIFT 7 -#define PALMAS_NSLEEP_SMPS_ASSIGN_SMPS9 0x40 -#define PALMAS_NSLEEP_SMPS_ASSIGN_SMPS9_SHIFT 6 -#define PALMAS_NSLEEP_SMPS_ASSIGN_SMPS8 0x20 -#define PALMAS_NSLEEP_SMPS_ASSIGN_SMPS8_SHIFT 5 -#define PALMAS_NSLEEP_SMPS_ASSIGN_SMPS7 0x10 -#define PALMAS_NSLEEP_SMPS_ASSIGN_SMPS7_SHIFT 4 -#define PALMAS_NSLEEP_SMPS_ASSIGN_SMPS6 0x08 -#define PALMAS_NSLEEP_SMPS_ASSIGN_SMPS6_SHIFT 3 -#define PALMAS_NSLEEP_SMPS_ASSIGN_SMPS45 0x04 -#define PALMAS_NSLEEP_SMPS_ASSIGN_SMPS45_SHIFT 2 -#define PALMAS_NSLEEP_SMPS_ASSIGN_SMPS3 0x02 -#define PALMAS_NSLEEP_SMPS_ASSIGN_SMPS3_SHIFT 1 -#define PALMAS_NSLEEP_SMPS_ASSIGN_SMPS12 0x01 -#define PALMAS_NSLEEP_SMPS_ASSIGN_SMPS12_SHIFT 0 - -/* Bit definitions for NSLEEP_LDO_ASSIGN1 */ -#define PALMAS_NSLEEP_LDO_ASSIGN1_LDO8 0x80 -#define PALMAS_NSLEEP_LDO_ASSIGN1_LDO8_SHIFT 7 -#define PALMAS_NSLEEP_LDO_ASSIGN1_LDO7 0x40 -#define PALMAS_NSLEEP_LDO_ASSIGN1_LDO7_SHIFT 6 -#define PALMAS_NSLEEP_LDO_ASSIGN1_LDO6 0x20 -#define PALMAS_NSLEEP_LDO_ASSIGN1_LDO6_SHIFT 5 -#define PALMAS_NSLEEP_LDO_ASSIGN1_LDO5 0x10 -#define PALMAS_NSLEEP_LDO_ASSIGN1_LDO5_SHIFT 4 -#define PALMAS_NSLEEP_LDO_ASSIGN1_LDO4 0x08 -#define PALMAS_NSLEEP_LDO_ASSIGN1_LDO4_SHIFT 3 -#define PALMAS_NSLEEP_LDO_ASSIGN1_LDO3 0x04 -#define PALMAS_NSLEEP_LDO_ASSIGN1_LDO3_SHIFT 2 -#define PALMAS_NSLEEP_LDO_ASSIGN1_LDO2 0x02 -#define PALMAS_NSLEEP_LDO_ASSIGN1_LDO2_SHIFT 1 -#define PALMAS_NSLEEP_LDO_ASSIGN1_LDO1 0x01 -#define PALMAS_NSLEEP_LDO_ASSIGN1_LDO1_SHIFT 0 - -/* Bit definitions for NSLEEP_LDO_ASSIGN2 */ -#define PALMAS_NSLEEP_LDO_ASSIGN2_LDOUSB 0x04 -#define PALMAS_NSLEEP_LDO_ASSIGN2_LDOUSB_SHIFT 2 -#define PALMAS_NSLEEP_LDO_ASSIGN2_LDOLN 0x02 -#define PALMAS_NSLEEP_LDO_ASSIGN2_LDOLN_SHIFT 1 -#define PALMAS_NSLEEP_LDO_ASSIGN2_LDO9 0x01 -#define PALMAS_NSLEEP_LDO_ASSIGN2_LDO9_SHIFT 0 - -/* Bit definitions for ENABLE1_RES_ASSIGN */ -#define PALMAS_ENABLE1_RES_ASSIGN_REGEN3 0x40 -#define PALMAS_ENABLE1_RES_ASSIGN_REGEN3_SHIFT 6 -#define PALMAS_ENABLE1_RES_ASSIGN_CLK32KGAUDIO 0x20 -#define PALMAS_ENABLE1_RES_ASSIGN_CLK32KGAUDIO_SHIFT 5 -#define PALMAS_ENABLE1_RES_ASSIGN_CLK32KG 0x10 -#define PALMAS_ENABLE1_RES_ASSIGN_CLK32KG_SHIFT 4 -#define PALMAS_ENABLE1_RES_ASSIGN_SYSEN2 0x08 -#define PALMAS_ENABLE1_RES_ASSIGN_SYSEN2_SHIFT 3 -#define PALMAS_ENABLE1_RES_ASSIGN_SYSEN1 0x04 -#define PALMAS_ENABLE1_RES_ASSIGN_SYSEN1_SHIFT 2 -#define PALMAS_ENABLE1_RES_ASSIGN_REGEN2 0x02 -#define PALMAS_ENABLE1_RES_ASSIGN_REGEN2_SHIFT 1 -#define PALMAS_ENABLE1_RES_ASSIGN_REGEN1 0x01 -#define PALMAS_ENABLE1_RES_ASSIGN_REGEN1_SHIFT 0 - -/* Bit definitions for ENABLE1_SMPS_ASSIGN */ -#define PALMAS_ENABLE1_SMPS_ASSIGN_SMPS10 0x80 -#define PALMAS_ENABLE1_SMPS_ASSIGN_SMPS10_SHIFT 7 -#define PALMAS_ENABLE1_SMPS_ASSIGN_SMPS9 0x40 -#define PALMAS_ENABLE1_SMPS_ASSIGN_SMPS9_SHIFT 6 -#define PALMAS_ENABLE1_SMPS_ASSIGN_SMPS8 0x20 -#define PALMAS_ENABLE1_SMPS_ASSIGN_SMPS8_SHIFT 5 -#define PALMAS_ENABLE1_SMPS_ASSIGN_SMPS7 0x10 -#define PALMAS_ENABLE1_SMPS_ASSIGN_SMPS7_SHIFT 4 -#define PALMAS_ENABLE1_SMPS_ASSIGN_SMPS6 0x08 -#define PALMAS_ENABLE1_SMPS_ASSIGN_SMPS6_SHIFT 3 -#define PALMAS_ENABLE1_SMPS_ASSIGN_SMPS45 0x04 -#define PALMAS_ENABLE1_SMPS_ASSIGN_SMPS45_SHIFT 2 -#define PALMAS_ENABLE1_SMPS_ASSIGN_SMPS3 0x02 -#define PALMAS_ENABLE1_SMPS_ASSIGN_SMPS3_SHIFT 1 -#define PALMAS_ENABLE1_SMPS_ASSIGN_SMPS12 0x01 -#define PALMAS_ENABLE1_SMPS_ASSIGN_SMPS12_SHIFT 0 - -/* Bit definitions for ENABLE1_LDO_ASSIGN1 */ -#define PALMAS_ENABLE1_LDO_ASSIGN1_LDO8 0x80 -#define PALMAS_ENABLE1_LDO_ASSIGN1_LDO8_SHIFT 7 -#define PALMAS_ENABLE1_LDO_ASSIGN1_LDO7 0x40 -#define PALMAS_ENABLE1_LDO_ASSIGN1_LDO7_SHIFT 6 -#define PALMAS_ENABLE1_LDO_ASSIGN1_LDO6 0x20 -#define PALMAS_ENABLE1_LDO_ASSIGN1_LDO6_SHIFT 5 -#define PALMAS_ENABLE1_LDO_ASSIGN1_LDO5 0x10 -#define PALMAS_ENABLE1_LDO_ASSIGN1_LDO5_SHIFT 4 -#define PALMAS_ENABLE1_LDO_ASSIGN1_LDO4 0x08 -#define PALMAS_ENABLE1_LDO_ASSIGN1_LDO4_SHIFT 3 -#define PALMAS_ENABLE1_LDO_ASSIGN1_LDO3 0x04 -#define PALMAS_ENABLE1_LDO_ASSIGN1_LDO3_SHIFT 2 -#define PALMAS_ENABLE1_LDO_ASSIGN1_LDO2 0x02 -#define PALMAS_ENABLE1_LDO_ASSIGN1_LDO2_SHIFT 1 -#define PALMAS_ENABLE1_LDO_ASSIGN1_LDO1 0x01 -#define PALMAS_ENABLE1_LDO_ASSIGN1_LDO1_SHIFT 0 - -/* Bit definitions for ENABLE1_LDO_ASSIGN2 */ -#define PALMAS_ENABLE1_LDO_ASSIGN2_LDOUSB 0x04 -#define PALMAS_ENABLE1_LDO_ASSIGN2_LDOUSB_SHIFT 2 -#define PALMAS_ENABLE1_LDO_ASSIGN2_LDOLN 0x02 -#define PALMAS_ENABLE1_LDO_ASSIGN2_LDOLN_SHIFT 1 -#define PALMAS_ENABLE1_LDO_ASSIGN2_LDO9 0x01 -#define PALMAS_ENABLE1_LDO_ASSIGN2_LDO9_SHIFT 0 - -/* Bit definitions for ENABLE2_RES_ASSIGN */ -#define PALMAS_ENABLE2_RES_ASSIGN_REGEN3 0x40 -#define PALMAS_ENABLE2_RES_ASSIGN_REGEN3_SHIFT 6 -#define PALMAS_ENABLE2_RES_ASSIGN_CLK32KGAUDIO 0x20 -#define PALMAS_ENABLE2_RES_ASSIGN_CLK32KGAUDIO_SHIFT 5 -#define PALMAS_ENABLE2_RES_ASSIGN_CLK32KG 0x10 -#define PALMAS_ENABLE2_RES_ASSIGN_CLK32KG_SHIFT 4 -#define PALMAS_ENABLE2_RES_ASSIGN_SYSEN2 0x08 -#define PALMAS_ENABLE2_RES_ASSIGN_SYSEN2_SHIFT 3 -#define PALMAS_ENABLE2_RES_ASSIGN_SYSEN1 0x04 -#define PALMAS_ENABLE2_RES_ASSIGN_SYSEN1_SHIFT 2 -#define PALMAS_ENABLE2_RES_ASSIGN_REGEN2 0x02 -#define PALMAS_ENABLE2_RES_ASSIGN_REGEN2_SHIFT 1 -#define PALMAS_ENABLE2_RES_ASSIGN_REGEN1 0x01 -#define PALMAS_ENABLE2_RES_ASSIGN_REGEN1_SHIFT 0 - -/* Bit definitions for ENABLE2_SMPS_ASSIGN */ -#define PALMAS_ENABLE2_SMPS_ASSIGN_SMPS10 0x80 -#define PALMAS_ENABLE2_SMPS_ASSIGN_SMPS10_SHIFT 7 -#define PALMAS_ENABLE2_SMPS_ASSIGN_SMPS9 0x40 -#define PALMAS_ENABLE2_SMPS_ASSIGN_SMPS9_SHIFT 6 -#define PALMAS_ENABLE2_SMPS_ASSIGN_SMPS8 0x20 -#define PALMAS_ENABLE2_SMPS_ASSIGN_SMPS8_SHIFT 5 -#define PALMAS_ENABLE2_SMPS_ASSIGN_SMPS7 0x10 -#define PALMAS_ENABLE2_SMPS_ASSIGN_SMPS7_SHIFT 4 -#define PALMAS_ENABLE2_SMPS_ASSIGN_SMPS6 0x08 -#define PALMAS_ENABLE2_SMPS_ASSIGN_SMPS6_SHIFT 3 -#define PALMAS_ENABLE2_SMPS_ASSIGN_SMPS45 0x04 -#define PALMAS_ENABLE2_SMPS_ASSIGN_SMPS45_SHIFT 2 -#define PALMAS_ENABLE2_SMPS_ASSIGN_SMPS3 0x02 -#define PALMAS_ENABLE2_SMPS_ASSIGN_SMPS3_SHIFT 1 -#define PALMAS_ENABLE2_SMPS_ASSIGN_SMPS12 0x01 -#define PALMAS_ENABLE2_SMPS_ASSIGN_SMPS12_SHIFT 0 - -/* Bit definitions for ENABLE2_LDO_ASSIGN1 */ -#define PALMAS_ENABLE2_LDO_ASSIGN1_LDO8 0x80 -#define PALMAS_ENABLE2_LDO_ASSIGN1_LDO8_SHIFT 7 -#define PALMAS_ENABLE2_LDO_ASSIGN1_LDO7 0x40 -#define PALMAS_ENABLE2_LDO_ASSIGN1_LDO7_SHIFT 6 -#define PALMAS_ENABLE2_LDO_ASSIGN1_LDO6 0x20 -#define PALMAS_ENABLE2_LDO_ASSIGN1_LDO6_SHIFT 5 -#define PALMAS_ENABLE2_LDO_ASSIGN1_LDO5 0x10 -#define PALMAS_ENABLE2_LDO_ASSIGN1_LDO5_SHIFT 4 -#define PALMAS_ENABLE2_LDO_ASSIGN1_LDO4 0x08 -#define PALMAS_ENABLE2_LDO_ASSIGN1_LDO4_SHIFT 3 -#define PALMAS_ENABLE2_LDO_ASSIGN1_LDO3 0x04 -#define PALMAS_ENABLE2_LDO_ASSIGN1_LDO3_SHIFT 2 -#define PALMAS_ENABLE2_LDO_ASSIGN1_LDO2 0x02 -#define PALMAS_ENABLE2_LDO_ASSIGN1_LDO2_SHIFT 1 -#define PALMAS_ENABLE2_LDO_ASSIGN1_LDO1 0x01 -#define PALMAS_ENABLE2_LDO_ASSIGN1_LDO1_SHIFT 0 - -/* Bit definitions for ENABLE2_LDO_ASSIGN2 */ -#define PALMAS_ENABLE2_LDO_ASSIGN2_LDOUSB 0x04 -#define PALMAS_ENABLE2_LDO_ASSIGN2_LDOUSB_SHIFT 2 -#define PALMAS_ENABLE2_LDO_ASSIGN2_LDOLN 0x02 -#define PALMAS_ENABLE2_LDO_ASSIGN2_LDOLN_SHIFT 1 -#define PALMAS_ENABLE2_LDO_ASSIGN2_LDO9 0x01 -#define PALMAS_ENABLE2_LDO_ASSIGN2_LDO9_SHIFT 0 - -/* Bit definitions for REGEN3_CTRL */ -#define PALMAS_REGEN3_CTRL_STATUS 0x10 -#define PALMAS_REGEN3_CTRL_STATUS_SHIFT 4 -#define PALMAS_REGEN3_CTRL_MODE_SLEEP 0x04 -#define PALMAS_REGEN3_CTRL_MODE_SLEEP_SHIFT 2 -#define PALMAS_REGEN3_CTRL_MODE_ACTIVE 0x01 -#define PALMAS_REGEN3_CTRL_MODE_ACTIVE_SHIFT 0 - -/* Registers for function PAD_CONTROL */ -#define PALMAS_PU_PD_INPUT_CTRL1 0x0 -#define PALMAS_PU_PD_INPUT_CTRL2 0x1 -#define PALMAS_PU_PD_INPUT_CTRL3 0x2 -#define PALMAS_OD_OUTPUT_CTRL 0x4 -#define PALMAS_POLARITY_CTRL 0x5 -#define PALMAS_PRIMARY_SECONDARY_PAD1 0x6 -#define PALMAS_PRIMARY_SECONDARY_PAD2 0x7 -#define PALMAS_I2C_SPI 0x8 -#define PALMAS_PU_PD_INPUT_CTRL4 0x9 -#define PALMAS_PRIMARY_SECONDARY_PAD3 0xA - -/* Bit definitions for PU_PD_INPUT_CTRL1 */ -#define PALMAS_PU_PD_INPUT_CTRL1_RESET_IN_PD 0x40 -#define PALMAS_PU_PD_INPUT_CTRL1_RESET_IN_PD_SHIFT 6 -#define PALMAS_PU_PD_INPUT_CTRL1_GPADC_START_PU 0x20 -#define PALMAS_PU_PD_INPUT_CTRL1_GPADC_START_PU_SHIFT 5 -#define PALMAS_PU_PD_INPUT_CTRL1_GPADC_START_PD 0x10 -#define PALMAS_PU_PD_INPUT_CTRL1_GPADC_START_PD_SHIFT 4 -#define PALMAS_PU_PD_INPUT_CTRL1_PWRDOWN_PD 0x04 -#define PALMAS_PU_PD_INPUT_CTRL1_PWRDOWN_PD_SHIFT 2 -#define PALMAS_PU_PD_INPUT_CTRL1_NRESWARM_PU 0x02 -#define PALMAS_PU_PD_INPUT_CTRL1_NRESWARM_PU_SHIFT 1 - -/* Bit definitions for PU_PD_INPUT_CTRL2 */ -#define PALMAS_PU_PD_INPUT_CTRL2_ENABLE2_PU 0x20 -#define PALMAS_PU_PD_INPUT_CTRL2_ENABLE2_PU_SHIFT 5 -#define PALMAS_PU_PD_INPUT_CTRL2_ENABLE2_PD 0x10 -#define PALMAS_PU_PD_INPUT_CTRL2_ENABLE2_PD_SHIFT 4 -#define PALMAS_PU_PD_INPUT_CTRL2_ENABLE1_PU 0x08 -#define PALMAS_PU_PD_INPUT_CTRL2_ENABLE1_PU_SHIFT 3 -#define PALMAS_PU_PD_INPUT_CTRL2_ENABLE1_PD 0x04 -#define PALMAS_PU_PD_INPUT_CTRL2_ENABLE1_PD_SHIFT 2 -#define PALMAS_PU_PD_INPUT_CTRL2_NSLEEP_PU 0x02 -#define PALMAS_PU_PD_INPUT_CTRL2_NSLEEP_PU_SHIFT 1 -#define PALMAS_PU_PD_INPUT_CTRL2_NSLEEP_PD 0x01 -#define PALMAS_PU_PD_INPUT_CTRL2_NSLEEP_PD_SHIFT 0 - -/* Bit definitions for PU_PD_INPUT_CTRL3 */ -#define PALMAS_PU_PD_INPUT_CTRL3_ACOK_PD 0x40 -#define PALMAS_PU_PD_INPUT_CTRL3_ACOK_PD_SHIFT 6 -#define PALMAS_PU_PD_INPUT_CTRL3_CHRG_DET_N_PD 0x10 -#define PALMAS_PU_PD_INPUT_CTRL3_CHRG_DET_N_PD_SHIFT 4 -#define PALMAS_PU_PD_INPUT_CTRL3_POWERHOLD_PD 0x04 -#define PALMAS_PU_PD_INPUT_CTRL3_POWERHOLD_PD_SHIFT 2 -#define PALMAS_PU_PD_INPUT_CTRL3_MSECURE_PD 0x01 -#define PALMAS_PU_PD_INPUT_CTRL3_MSECURE_PD_SHIFT 0 - -/* Bit definitions for OD_OUTPUT_CTRL */ -#define PALMAS_OD_OUTPUT_CTRL_PWM_2_OD 0x80 -#define PALMAS_OD_OUTPUT_CTRL_PWM_2_OD_SHIFT 7 -#define PALMAS_OD_OUTPUT_CTRL_VBUSDET_OD 0x40 -#define PALMAS_OD_OUTPUT_CTRL_VBUSDET_OD_SHIFT 6 -#define PALMAS_OD_OUTPUT_CTRL_PWM_1_OD 0x20 -#define PALMAS_OD_OUTPUT_CTRL_PWM_1_OD_SHIFT 5 -#define PALMAS_OD_OUTPUT_CTRL_INT_OD 0x08 -#define PALMAS_OD_OUTPUT_CTRL_INT_OD_SHIFT 3 - -/* Bit definitions for POLARITY_CTRL */ -#define PALMAS_POLARITY_CTRL_INT_POLARITY 0x80 -#define PALMAS_POLARITY_CTRL_INT_POLARITY_SHIFT 7 -#define PALMAS_POLARITY_CTRL_ENABLE2_POLARITY 0x40 -#define PALMAS_POLARITY_CTRL_ENABLE2_POLARITY_SHIFT 6 -#define PALMAS_POLARITY_CTRL_ENABLE1_POLARITY 0x20 -#define PALMAS_POLARITY_CTRL_ENABLE1_POLARITY_SHIFT 5 -#define PALMAS_POLARITY_CTRL_NSLEEP_POLARITY 0x10 -#define PALMAS_POLARITY_CTRL_NSLEEP_POLARITY_SHIFT 4 -#define PALMAS_POLARITY_CTRL_RESET_IN_POLARITY 0x08 -#define PALMAS_POLARITY_CTRL_RESET_IN_POLARITY_SHIFT 3 -#define PALMAS_POLARITY_CTRL_GPIO_3_CHRG_DET_N_POLARITY 0x04 -#define PALMAS_POLARITY_CTRL_GPIO_3_CHRG_DET_N_POLARITY_SHIFT 2 -#define PALMAS_POLARITY_CTRL_POWERGOOD_USB_PSEL_POLARITY 0x02 -#define PALMAS_POLARITY_CTRL_POWERGOOD_USB_PSEL_POLARITY_SHIFT 1 -#define PALMAS_POLARITY_CTRL_PWRDOWN_POLARITY 0x01 -#define PALMAS_POLARITY_CTRL_PWRDOWN_POLARITY_SHIFT 0 - -/* Bit definitions for PRIMARY_SECONDARY_PAD1 */ -#define PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_3 0x80 -#define PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_3_SHIFT 7 -#define PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK 0x60 -#define PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_SHIFT 5 -#define PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK 0x18 -#define PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT 3 -#define PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_0 0x04 -#define PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_0_SHIFT 2 -#define PALMAS_PRIMARY_SECONDARY_PAD1_VAC 0x02 -#define PALMAS_PRIMARY_SECONDARY_PAD1_VAC_SHIFT 1 -#define PALMAS_PRIMARY_SECONDARY_PAD1_POWERGOOD 0x01 -#define PALMAS_PRIMARY_SECONDARY_PAD1_POWERGOOD_SHIFT 0 - -/* Bit definitions for PRIMARY_SECONDARY_PAD2 */ -#define PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_7_MASK 0x30 -#define PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_7_SHIFT 4 -#define PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_6 0x08 -#define PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_6_SHIFT 3 -#define PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_5_MASK 0x06 -#define PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_5_SHIFT 1 -#define PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_4 0x01 -#define PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_4_SHIFT 0 - -/* Bit definitions for I2C_SPI */ -#define PALMAS_I2C_SPI_I2C2OTP_EN 0x80 -#define PALMAS_I2C_SPI_I2C2OTP_EN_SHIFT 7 -#define PALMAS_I2C_SPI_I2C2OTP_PAGESEL 0x40 -#define PALMAS_I2C_SPI_I2C2OTP_PAGESEL_SHIFT 6 -#define PALMAS_I2C_SPI_ID_I2C2 0x20 -#define PALMAS_I2C_SPI_ID_I2C2_SHIFT 5 -#define PALMAS_I2C_SPI_I2C_SPI 0x10 -#define PALMAS_I2C_SPI_I2C_SPI_SHIFT 4 -#define PALMAS_I2C_SPI_ID_I2C1_MASK 0x0f -#define PALMAS_I2C_SPI_ID_I2C1_SHIFT 0 - -/* Bit definitions for PU_PD_INPUT_CTRL4 */ -#define PALMAS_PU_PD_INPUT_CTRL4_DVFS2_DAT_PD 0x40 -#define PALMAS_PU_PD_INPUT_CTRL4_DVFS2_DAT_PD_SHIFT 6 -#define PALMAS_PU_PD_INPUT_CTRL4_DVFS2_CLK_PD 0x10 -#define PALMAS_PU_PD_INPUT_CTRL4_DVFS2_CLK_PD_SHIFT 4 -#define PALMAS_PU_PD_INPUT_CTRL4_DVFS1_DAT_PD 0x04 -#define PALMAS_PU_PD_INPUT_CTRL4_DVFS1_DAT_PD_SHIFT 2 -#define PALMAS_PU_PD_INPUT_CTRL4_DVFS1_CLK_PD 0x01 -#define PALMAS_PU_PD_INPUT_CTRL4_DVFS1_CLK_PD_SHIFT 0 - -/* Bit definitions for PRIMARY_SECONDARY_PAD3 */ -#define PALMAS_PRIMARY_SECONDARY_PAD3_DVFS2 0x02 -#define PALMAS_PRIMARY_SECONDARY_PAD3_DVFS2_SHIFT 1 -#define PALMAS_PRIMARY_SECONDARY_PAD3_DVFS1 0x01 -#define PALMAS_PRIMARY_SECONDARY_PAD3_DVFS1_SHIFT 0 - -/* Registers for function LED_PWM */ -#define PALMAS_LED_PERIOD_CTRL 0x0 -#define PALMAS_LED_CTRL 0x1 -#define PALMAS_PWM_CTRL1 0x2 -#define PALMAS_PWM_CTRL2 0x3 - -/* Bit definitions for LED_PERIOD_CTRL */ -#define PALMAS_LED_PERIOD_CTRL_LED_2_PERIOD_MASK 0x38 -#define PALMAS_LED_PERIOD_CTRL_LED_2_PERIOD_SHIFT 3 -#define PALMAS_LED_PERIOD_CTRL_LED_1_PERIOD_MASK 0x07 -#define PALMAS_LED_PERIOD_CTRL_LED_1_PERIOD_SHIFT 0 - -/* Bit definitions for LED_CTRL */ -#define PALMAS_LED_CTRL_LED_2_SEQ 0x20 -#define PALMAS_LED_CTRL_LED_2_SEQ_SHIFT 5 -#define PALMAS_LED_CTRL_LED_1_SEQ 0x10 -#define PALMAS_LED_CTRL_LED_1_SEQ_SHIFT 4 -#define PALMAS_LED_CTRL_LED_2_ON_TIME_MASK 0x0c -#define PALMAS_LED_CTRL_LED_2_ON_TIME_SHIFT 2 -#define PALMAS_LED_CTRL_LED_1_ON_TIME_MASK 0x03 -#define PALMAS_LED_CTRL_LED_1_ON_TIME_SHIFT 0 - -/* Bit definitions for PWM_CTRL1 */ -#define PALMAS_PWM_CTRL1_PWM_FREQ_EN 0x02 -#define PALMAS_PWM_CTRL1_PWM_FREQ_EN_SHIFT 1 -#define PALMAS_PWM_CTRL1_PWM_FREQ_SEL 0x01 -#define PALMAS_PWM_CTRL1_PWM_FREQ_SEL_SHIFT 0 - -/* Bit definitions for PWM_CTRL2 */ -#define PALMAS_PWM_CTRL2_PWM_DUTY_SEL_MASK 0xff -#define PALMAS_PWM_CTRL2_PWM_DUTY_SEL_SHIFT 0 - -/* Registers for function INTERRUPT */ -#define PALMAS_INT1_STATUS 0x0 -#define PALMAS_INT1_MASK 0x1 -#define PALMAS_INT1_LINE_STATE 0x2 -#define PALMAS_INT1_EDGE_DETECT1_RESERVED 0x3 -#define PALMAS_INT1_EDGE_DETECT2_RESERVED 0x4 -#define PALMAS_INT2_STATUS 0x5 -#define PALMAS_INT2_MASK 0x6 -#define PALMAS_INT2_LINE_STATE 0x7 -#define PALMAS_INT2_EDGE_DETECT1_RESERVED 0x8 -#define PALMAS_INT2_EDGE_DETECT2_RESERVED 0x9 -#define PALMAS_INT3_STATUS 0xA -#define PALMAS_INT3_MASK 0xB -#define PALMAS_INT3_LINE_STATE 0xC -#define PALMAS_INT3_EDGE_DETECT1_RESERVED 0xD -#define PALMAS_INT3_EDGE_DETECT2_RESERVED 0xE -#define PALMAS_INT4_STATUS 0xF -#define PALMAS_INT4_MASK 0x10 -#define PALMAS_INT4_LINE_STATE 0x11 -#define PALMAS_INT4_EDGE_DETECT1 0x12 -#define PALMAS_INT4_EDGE_DETECT2 0x13 -#define PALMAS_INT_CTRL 0x14 - -/* Bit definitions for INT1_STATUS */ -#define PALMAS_INT1_STATUS_VBAT_MON 0x80 -#define PALMAS_INT1_STATUS_VBAT_MON_SHIFT 7 -#define PALMAS_INT1_STATUS_VSYS_MON 0x40 -#define PALMAS_INT1_STATUS_VSYS_MON_SHIFT 6 -#define PALMAS_INT1_STATUS_HOTDIE 0x20 -#define PALMAS_INT1_STATUS_HOTDIE_SHIFT 5 -#define PALMAS_INT1_STATUS_PWRDOWN 0x10 -#define PALMAS_INT1_STATUS_PWRDOWN_SHIFT 4 -#define PALMAS_INT1_STATUS_RPWRON 0x08 -#define PALMAS_INT1_STATUS_RPWRON_SHIFT 3 -#define PALMAS_INT1_STATUS_LONG_PRESS_KEY 0x04 -#define PALMAS_INT1_STATUS_LONG_PRESS_KEY_SHIFT 2 -#define PALMAS_INT1_STATUS_PWRON 0x02 -#define PALMAS_INT1_STATUS_PWRON_SHIFT 1 -#define PALMAS_INT1_STATUS_CHARG_DET_N_VBUS_OVV 0x01 -#define PALMAS_INT1_STATUS_CHARG_DET_N_VBUS_OVV_SHIFT 0 - -/* Bit definitions for INT1_MASK */ -#define PALMAS_INT1_MASK_VBAT_MON 0x80 -#define PALMAS_INT1_MASK_VBAT_MON_SHIFT 7 -#define PALMAS_INT1_MASK_VSYS_MON 0x40 -#define PALMAS_INT1_MASK_VSYS_MON_SHIFT 6 -#define PALMAS_INT1_MASK_HOTDIE 0x20 -#define PALMAS_INT1_MASK_HOTDIE_SHIFT 5 -#define PALMAS_INT1_MASK_PWRDOWN 0x10 -#define PALMAS_INT1_MASK_PWRDOWN_SHIFT 4 -#define PALMAS_INT1_MASK_RPWRON 0x08 -#define PALMAS_INT1_MASK_RPWRON_SHIFT 3 -#define PALMAS_INT1_MASK_LONG_PRESS_KEY 0x04 -#define PALMAS_INT1_MASK_LONG_PRESS_KEY_SHIFT 2 -#define PALMAS_INT1_MASK_PWRON 0x02 -#define PALMAS_INT1_MASK_PWRON_SHIFT 1 -#define PALMAS_INT1_MASK_CHARG_DET_N_VBUS_OVV 0x01 -#define PALMAS_INT1_MASK_CHARG_DET_N_VBUS_OVV_SHIFT 0 - -/* Bit definitions for INT1_LINE_STATE */ -#define PALMAS_INT1_LINE_STATE_VBAT_MON 0x80 -#define PALMAS_INT1_LINE_STATE_VBAT_MON_SHIFT 7 -#define PALMAS_INT1_LINE_STATE_VSYS_MON 0x40 -#define PALMAS_INT1_LINE_STATE_VSYS_MON_SHIFT 6 -#define PALMAS_INT1_LINE_STATE_HOTDIE 0x20 -#define PALMAS_INT1_LINE_STATE_HOTDIE_SHIFT 5 -#define PALMAS_INT1_LINE_STATE_PWRDOWN 0x10 -#define PALMAS_INT1_LINE_STATE_PWRDOWN_SHIFT 4 -#define PALMAS_INT1_LINE_STATE_RPWRON 0x08 -#define PALMAS_INT1_LINE_STATE_RPWRON_SHIFT 3 -#define PALMAS_INT1_LINE_STATE_LONG_PRESS_KEY 0x04 -#define PALMAS_INT1_LINE_STATE_LONG_PRESS_KEY_SHIFT 2 -#define PALMAS_INT1_LINE_STATE_PWRON 0x02 -#define PALMAS_INT1_LINE_STATE_PWRON_SHIFT 1 -#define PALMAS_INT1_LINE_STATE_CHARG_DET_N_VBUS_OVV 0x01 -#define PALMAS_INT1_LINE_STATE_CHARG_DET_N_VBUS_OVV_SHIFT 0 - -/* Bit definitions for INT2_STATUS */ -#define PALMAS_INT2_STATUS_VAC_ACOK 0x80 -#define PALMAS_INT2_STATUS_VAC_ACOK_SHIFT 7 -#define PALMAS_INT2_STATUS_SHORT 0x40 -#define PALMAS_INT2_STATUS_SHORT_SHIFT 6 -#define PALMAS_INT2_STATUS_FBI_BB 0x20 -#define PALMAS_INT2_STATUS_FBI_BB_SHIFT 5 -#define PALMAS_INT2_STATUS_RESET_IN 0x10 -#define PALMAS_INT2_STATUS_RESET_IN_SHIFT 4 -#define PALMAS_INT2_STATUS_BATREMOVAL 0x08 -#define PALMAS_INT2_STATUS_BATREMOVAL_SHIFT 3 -#define PALMAS_INT2_STATUS_WDT 0x04 -#define PALMAS_INT2_STATUS_WDT_SHIFT 2 -#define PALMAS_INT2_STATUS_RTC_TIMER 0x02 -#define PALMAS_INT2_STATUS_RTC_TIMER_SHIFT 1 -#define PALMAS_INT2_STATUS_RTC_ALARM 0x01 -#define PALMAS_INT2_STATUS_RTC_ALARM_SHIFT 0 - -/* Bit definitions for INT2_MASK */ -#define PALMAS_INT2_MASK_VAC_ACOK 0x80 -#define PALMAS_INT2_MASK_VAC_ACOK_SHIFT 7 -#define PALMAS_INT2_MASK_SHORT 0x40 -#define PALMAS_INT2_MASK_SHORT_SHIFT 6 -#define PALMAS_INT2_MASK_FBI_BB 0x20 -#define PALMAS_INT2_MASK_FBI_BB_SHIFT 5 -#define PALMAS_INT2_MASK_RESET_IN 0x10 -#define PALMAS_INT2_MASK_RESET_IN_SHIFT 4 -#define PALMAS_INT2_MASK_BATREMOVAL 0x08 -#define PALMAS_INT2_MASK_BATREMOVAL_SHIFT 3 -#define PALMAS_INT2_MASK_WDT 0x04 -#define PALMAS_INT2_MASK_WDT_SHIFT 2 -#define PALMAS_INT2_MASK_RTC_TIMER 0x02 -#define PALMAS_INT2_MASK_RTC_TIMER_SHIFT 1 -#define PALMAS_INT2_MASK_RTC_ALARM 0x01 -#define PALMAS_INT2_MASK_RTC_ALARM_SHIFT 0 - -/* Bit definitions for INT2_LINE_STATE */ -#define PALMAS_INT2_LINE_STATE_VAC_ACOK 0x80 -#define PALMAS_INT2_LINE_STATE_VAC_ACOK_SHIFT 7 -#define PALMAS_INT2_LINE_STATE_SHORT 0x40 -#define PALMAS_INT2_LINE_STATE_SHORT_SHIFT 6 -#define PALMAS_INT2_LINE_STATE_FBI_BB 0x20 -#define PALMAS_INT2_LINE_STATE_FBI_BB_SHIFT 5 -#define PALMAS_INT2_LINE_STATE_RESET_IN 0x10 -#define PALMAS_INT2_LINE_STATE_RESET_IN_SHIFT 4 -#define PALMAS_INT2_LINE_STATE_BATREMOVAL 0x08 -#define PALMAS_INT2_LINE_STATE_BATREMOVAL_SHIFT 3 -#define PALMAS_INT2_LINE_STATE_WDT 0x04 -#define PALMAS_INT2_LINE_STATE_WDT_SHIFT 2 -#define PALMAS_INT2_LINE_STATE_RTC_TIMER 0x02 -#define PALMAS_INT2_LINE_STATE_RTC_TIMER_SHIFT 1 -#define PALMAS_INT2_LINE_STATE_RTC_ALARM 0x01 -#define PALMAS_INT2_LINE_STATE_RTC_ALARM_SHIFT 0 - -/* Bit definitions for INT3_STATUS */ -#define PALMAS_INT3_STATUS_VBUS 0x80 -#define PALMAS_INT3_STATUS_VBUS_SHIFT 7 -#define PALMAS_INT3_STATUS_VBUS_OTG 0x40 -#define PALMAS_INT3_STATUS_VBUS_OTG_SHIFT 6 -#define PALMAS_INT3_STATUS_ID 0x20 -#define PALMAS_INT3_STATUS_ID_SHIFT 5 -#define PALMAS_INT3_STATUS_ID_OTG 0x10 -#define PALMAS_INT3_STATUS_ID_OTG_SHIFT 4 -#define PALMAS_INT3_STATUS_GPADC_EOC_RT 0x08 -#define PALMAS_INT3_STATUS_GPADC_EOC_RT_SHIFT 3 -#define PALMAS_INT3_STATUS_GPADC_EOC_SW 0x04 -#define PALMAS_INT3_STATUS_GPADC_EOC_SW_SHIFT 2 -#define PALMAS_INT3_STATUS_GPADC_AUTO_1 0x02 -#define PALMAS_INT3_STATUS_GPADC_AUTO_1_SHIFT 1 -#define PALMAS_INT3_STATUS_GPADC_AUTO_0 0x01 -#define PALMAS_INT3_STATUS_GPADC_AUTO_0_SHIFT 0 - -/* Bit definitions for INT3_MASK */ -#define PALMAS_INT3_MASK_VBUS 0x80 -#define PALMAS_INT3_MASK_VBUS_SHIFT 7 -#define PALMAS_INT3_MASK_VBUS_OTG 0x40 -#define PALMAS_INT3_MASK_VBUS_OTG_SHIFT 6 -#define PALMAS_INT3_MASK_ID 0x20 -#define PALMAS_INT3_MASK_ID_SHIFT 5 -#define PALMAS_INT3_MASK_ID_OTG 0x10 -#define PALMAS_INT3_MASK_ID_OTG_SHIFT 4 -#define PALMAS_INT3_MASK_GPADC_EOC_RT 0x08 -#define PALMAS_INT3_MASK_GPADC_EOC_RT_SHIFT 3 -#define PALMAS_INT3_MASK_GPADC_EOC_SW 0x04 -#define PALMAS_INT3_MASK_GPADC_EOC_SW_SHIFT 2 -#define PALMAS_INT3_MASK_GPADC_AUTO_1 0x02 -#define PALMAS_INT3_MASK_GPADC_AUTO_1_SHIFT 1 -#define PALMAS_INT3_MASK_GPADC_AUTO_0 0x01 -#define PALMAS_INT3_MASK_GPADC_AUTO_0_SHIFT 0 - -/* Bit definitions for INT3_LINE_STATE */ -#define PALMAS_INT3_LINE_STATE_VBUS 0x80 -#define PALMAS_INT3_LINE_STATE_VBUS_SHIFT 7 -#define PALMAS_INT3_LINE_STATE_VBUS_OTG 0x40 -#define PALMAS_INT3_LINE_STATE_VBUS_OTG_SHIFT 6 -#define PALMAS_INT3_LINE_STATE_ID 0x20 -#define PALMAS_INT3_LINE_STATE_ID_SHIFT 5 -#define PALMAS_INT3_LINE_STATE_ID_OTG 0x10 -#define PALMAS_INT3_LINE_STATE_ID_OTG_SHIFT 4 -#define PALMAS_INT3_LINE_STATE_GPADC_EOC_RT 0x08 -#define PALMAS_INT3_LINE_STATE_GPADC_EOC_RT_SHIFT 3 -#define PALMAS_INT3_LINE_STATE_GPADC_EOC_SW 0x04 -#define PALMAS_INT3_LINE_STATE_GPADC_EOC_SW_SHIFT 2 -#define PALMAS_INT3_LINE_STATE_GPADC_AUTO_1 0x02 -#define PALMAS_INT3_LINE_STATE_GPADC_AUTO_1_SHIFT 1 -#define PALMAS_INT3_LINE_STATE_GPADC_AUTO_0 0x01 -#define PALMAS_INT3_LINE_STATE_GPADC_AUTO_0_SHIFT 0 - -/* Bit definitions for INT4_STATUS */ -#define PALMAS_INT4_STATUS_GPIO_7 0x80 -#define PALMAS_INT4_STATUS_GPIO_7_SHIFT 7 -#define PALMAS_INT4_STATUS_GPIO_6 0x40 -#define PALMAS_INT4_STATUS_GPIO_6_SHIFT 6 -#define PALMAS_INT4_STATUS_GPIO_5 0x20 -#define PALMAS_INT4_STATUS_GPIO_5_SHIFT 5 -#define PALMAS_INT4_STATUS_GPIO_4 0x10 -#define PALMAS_INT4_STATUS_GPIO_4_SHIFT 4 -#define PALMAS_INT4_STATUS_GPIO_3 0x08 -#define PALMAS_INT4_STATUS_GPIO_3_SHIFT 3 -#define PALMAS_INT4_STATUS_GPIO_2 0x04 -#define PALMAS_INT4_STATUS_GPIO_2_SHIFT 2 -#define PALMAS_INT4_STATUS_GPIO_1 0x02 -#define PALMAS_INT4_STATUS_GPIO_1_SHIFT 1 -#define PALMAS_INT4_STATUS_GPIO_0 0x01 -#define PALMAS_INT4_STATUS_GPIO_0_SHIFT 0 - -/* Bit definitions for INT4_MASK */ -#define PALMAS_INT4_MASK_GPIO_7 0x80 -#define PALMAS_INT4_MASK_GPIO_7_SHIFT 7 -#define PALMAS_INT4_MASK_GPIO_6 0x40 -#define PALMAS_INT4_MASK_GPIO_6_SHIFT 6 -#define PALMAS_INT4_MASK_GPIO_5 0x20 -#define PALMAS_INT4_MASK_GPIO_5_SHIFT 5 -#define PALMAS_INT4_MASK_GPIO_4 0x10 -#define PALMAS_INT4_MASK_GPIO_4_SHIFT 4 -#define PALMAS_INT4_MASK_GPIO_3 0x08 -#define PALMAS_INT4_MASK_GPIO_3_SHIFT 3 -#define PALMAS_INT4_MASK_GPIO_2 0x04 -#define PALMAS_INT4_MASK_GPIO_2_SHIFT 2 -#define PALMAS_INT4_MASK_GPIO_1 0x02 -#define PALMAS_INT4_MASK_GPIO_1_SHIFT 1 -#define PALMAS_INT4_MASK_GPIO_0 0x01 -#define PALMAS_INT4_MASK_GPIO_0_SHIFT 0 - -/* Bit definitions for INT4_LINE_STATE */ -#define PALMAS_INT4_LINE_STATE_GPIO_7 0x80 -#define PALMAS_INT4_LINE_STATE_GPIO_7_SHIFT 7 -#define PALMAS_INT4_LINE_STATE_GPIO_6 0x40 -#define PALMAS_INT4_LINE_STATE_GPIO_6_SHIFT 6 -#define PALMAS_INT4_LINE_STATE_GPIO_5 0x20 -#define PALMAS_INT4_LINE_STATE_GPIO_5_SHIFT 5 -#define PALMAS_INT4_LINE_STATE_GPIO_4 0x10 -#define PALMAS_INT4_LINE_STATE_GPIO_4_SHIFT 4 -#define PALMAS_INT4_LINE_STATE_GPIO_3 0x08 -#define PALMAS_INT4_LINE_STATE_GPIO_3_SHIFT 3 -#define PALMAS_INT4_LINE_STATE_GPIO_2 0x04 -#define PALMAS_INT4_LINE_STATE_GPIO_2_SHIFT 2 -#define PALMAS_INT4_LINE_STATE_GPIO_1 0x02 -#define PALMAS_INT4_LINE_STATE_GPIO_1_SHIFT 1 -#define PALMAS_INT4_LINE_STATE_GPIO_0 0x01 -#define PALMAS_INT4_LINE_STATE_GPIO_0_SHIFT 0 - -/* Bit definitions for INT4_EDGE_DETECT1 */ -#define PALMAS_INT4_EDGE_DETECT1_GPIO_3_RISING 0x80 -#define PALMAS_INT4_EDGE_DETECT1_GPIO_3_RISING_SHIFT 7 -#define PALMAS_INT4_EDGE_DETECT1_GPIO_3_FALLING 0x40 -#define PALMAS_INT4_EDGE_DETECT1_GPIO_3_FALLING_SHIFT 6 -#define PALMAS_INT4_EDGE_DETECT1_GPIO_2_RISING 0x20 -#define PALMAS_INT4_EDGE_DETECT1_GPIO_2_RISING_SHIFT 5 -#define PALMAS_INT4_EDGE_DETECT1_GPIO_2_FALLING 0x10 -#define PALMAS_INT4_EDGE_DETECT1_GPIO_2_FALLING_SHIFT 4 -#define PALMAS_INT4_EDGE_DETECT1_GPIO_1_RISING 0x08 -#define PALMAS_INT4_EDGE_DETECT1_GPIO_1_RISING_SHIFT 3 -#define PALMAS_INT4_EDGE_DETECT1_GPIO_1_FALLING 0x04 -#define PALMAS_INT4_EDGE_DETECT1_GPIO_1_FALLING_SHIFT 2 -#define PALMAS_INT4_EDGE_DETECT1_GPIO_0_RISING 0x02 -#define PALMAS_INT4_EDGE_DETECT1_GPIO_0_RISING_SHIFT 1 -#define PALMAS_INT4_EDGE_DETECT1_GPIO_0_FALLING 0x01 -#define PALMAS_INT4_EDGE_DETECT1_GPIO_0_FALLING_SHIFT 0 - -/* Bit definitions for INT4_EDGE_DETECT2 */ -#define PALMAS_INT4_EDGE_DETECT2_GPIO_7_RISING 0x80 -#define PALMAS_INT4_EDGE_DETECT2_GPIO_7_RISING_SHIFT 7 -#define PALMAS_INT4_EDGE_DETECT2_GPIO_7_FALLING 0x40 -#define PALMAS_INT4_EDGE_DETECT2_GPIO_7_FALLING_SHIFT 6 -#define PALMAS_INT4_EDGE_DETECT2_GPIO_6_RISING 0x20 -#define PALMAS_INT4_EDGE_DETECT2_GPIO_6_RISING_SHIFT 5 -#define PALMAS_INT4_EDGE_DETECT2_GPIO_6_FALLING 0x10 -#define PALMAS_INT4_EDGE_DETECT2_GPIO_6_FALLING_SHIFT 4 -#define PALMAS_INT4_EDGE_DETECT2_GPIO_5_RISING 0x08 -#define PALMAS_INT4_EDGE_DETECT2_GPIO_5_RISING_SHIFT 3 -#define PALMAS_INT4_EDGE_DETECT2_GPIO_5_FALLING 0x04 -#define PALMAS_INT4_EDGE_DETECT2_GPIO_5_FALLING_SHIFT 2 -#define PALMAS_INT4_EDGE_DETECT2_GPIO_4_RISING 0x02 -#define PALMAS_INT4_EDGE_DETECT2_GPIO_4_RISING_SHIFT 1 -#define PALMAS_INT4_EDGE_DETECT2_GPIO_4_FALLING 0x01 -#define PALMAS_INT4_EDGE_DETECT2_GPIO_4_FALLING_SHIFT 0 - -/* Bit definitions for INT_CTRL */ -#define PALMAS_INT_CTRL_INT_PENDING 0x04 -#define PALMAS_INT_CTRL_INT_PENDING_SHIFT 2 -#define PALMAS_INT_CTRL_INT_CLEAR 0x01 -#define PALMAS_INT_CTRL_INT_CLEAR_SHIFT 0 - -/* Registers for function USB_OTG */ -#define PALMAS_USB_WAKEUP 0x3 -#define PALMAS_USB_VBUS_CTRL_SET 0x4 -#define PALMAS_USB_VBUS_CTRL_CLR 0x5 -#define PALMAS_USB_ID_CTRL_SET 0x6 -#define PALMAS_USB_ID_CTRL_CLEAR 0x7 -#define PALMAS_USB_VBUS_INT_SRC 0x8 -#define PALMAS_USB_VBUS_INT_LATCH_SET 0x9 -#define PALMAS_USB_VBUS_INT_LATCH_CLR 0xA -#define PALMAS_USB_VBUS_INT_EN_LO_SET 0xB -#define PALMAS_USB_VBUS_INT_EN_LO_CLR 0xC -#define PALMAS_USB_VBUS_INT_EN_HI_SET 0xD -#define PALMAS_USB_VBUS_INT_EN_HI_CLR 0xE -#define PALMAS_USB_ID_INT_SRC 0xF -#define PALMAS_USB_ID_INT_LATCH_SET 0x10 -#define PALMAS_USB_ID_INT_LATCH_CLR 0x11 -#define PALMAS_USB_ID_INT_EN_LO_SET 0x12 -#define PALMAS_USB_ID_INT_EN_LO_CLR 0x13 -#define PALMAS_USB_ID_INT_EN_HI_SET 0x14 -#define PALMAS_USB_ID_INT_EN_HI_CLR 0x15 -#define PALMAS_USB_OTG_ADP_CTRL 0x16 -#define PALMAS_USB_OTG_ADP_HIGH 0x17 -#define PALMAS_USB_OTG_ADP_LOW 0x18 -#define PALMAS_USB_OTG_ADP_RISE 0x19 -#define PALMAS_USB_OTG_REVISION 0x1A - -/* Bit definitions for USB_WAKEUP */ -#define PALMAS_USB_WAKEUP_ID_WK_UP_COMP 0x01 -#define PALMAS_USB_WAKEUP_ID_WK_UP_COMP_SHIFT 0 - -/* Bit definitions for USB_VBUS_CTRL_SET */ -#define PALMAS_USB_VBUS_CTRL_SET_VBUS_CHRG_VSYS 0x80 -#define PALMAS_USB_VBUS_CTRL_SET_VBUS_CHRG_VSYS_SHIFT 7 -#define PALMAS_USB_VBUS_CTRL_SET_VBUS_DISCHRG 0x20 -#define PALMAS_USB_VBUS_CTRL_SET_VBUS_DISCHRG_SHIFT 5 -#define PALMAS_USB_VBUS_CTRL_SET_VBUS_IADP_SRC 0x10 -#define PALMAS_USB_VBUS_CTRL_SET_VBUS_IADP_SRC_SHIFT 4 -#define PALMAS_USB_VBUS_CTRL_SET_VBUS_IADP_SINK 0x08 -#define PALMAS_USB_VBUS_CTRL_SET_VBUS_IADP_SINK_SHIFT 3 -#define PALMAS_USB_VBUS_CTRL_SET_VBUS_ACT_COMP 0x04 -#define PALMAS_USB_VBUS_CTRL_SET_VBUS_ACT_COMP_SHIFT 2 - -/* Bit definitions for USB_VBUS_CTRL_CLR */ -#define PALMAS_USB_VBUS_CTRL_CLR_VBUS_CHRG_VSYS 0x80 -#define PALMAS_USB_VBUS_CTRL_CLR_VBUS_CHRG_VSYS_SHIFT 7 -#define PALMAS_USB_VBUS_CTRL_CLR_VBUS_DISCHRG 0x20 -#define PALMAS_USB_VBUS_CTRL_CLR_VBUS_DISCHRG_SHIFT 5 -#define PALMAS_USB_VBUS_CTRL_CLR_VBUS_IADP_SRC 0x10 -#define PALMAS_USB_VBUS_CTRL_CLR_VBUS_IADP_SRC_SHIFT 4 -#define PALMAS_USB_VBUS_CTRL_CLR_VBUS_IADP_SINK 0x08 -#define PALMAS_USB_VBUS_CTRL_CLR_VBUS_IADP_SINK_SHIFT 3 -#define PALMAS_USB_VBUS_CTRL_CLR_VBUS_ACT_COMP 0x04 -#define PALMAS_USB_VBUS_CTRL_CLR_VBUS_ACT_COMP_SHIFT 2 - -/* Bit definitions for USB_ID_CTRL_SET */ -#define PALMAS_USB_ID_CTRL_SET_ID_PU_220K 0x80 -#define PALMAS_USB_ID_CTRL_SET_ID_PU_220K_SHIFT 7 -#define PALMAS_USB_ID_CTRL_SET_ID_PU_100K 0x40 -#define PALMAS_USB_ID_CTRL_SET_ID_PU_100K_SHIFT 6 -#define PALMAS_USB_ID_CTRL_SET_ID_GND_DRV 0x20 -#define PALMAS_USB_ID_CTRL_SET_ID_GND_DRV_SHIFT 5 -#define PALMAS_USB_ID_CTRL_SET_ID_SRC_16U 0x10 -#define PALMAS_USB_ID_CTRL_SET_ID_SRC_16U_SHIFT 4 -#define PALMAS_USB_ID_CTRL_SET_ID_SRC_5U 0x08 -#define PALMAS_USB_ID_CTRL_SET_ID_SRC_5U_SHIFT 3 -#define PALMAS_USB_ID_CTRL_SET_ID_ACT_COMP 0x04 -#define PALMAS_USB_ID_CTRL_SET_ID_ACT_COMP_SHIFT 2 - -/* Bit definitions for USB_ID_CTRL_CLEAR */ -#define PALMAS_USB_ID_CTRL_CLEAR_ID_PU_220K 0x80 -#define PALMAS_USB_ID_CTRL_CLEAR_ID_PU_220K_SHIFT 7 -#define PALMAS_USB_ID_CTRL_CLEAR_ID_PU_100K 0x40 -#define PALMAS_USB_ID_CTRL_CLEAR_ID_PU_100K_SHIFT 6 -#define PALMAS_USB_ID_CTRL_CLEAR_ID_GND_DRV 0x20 -#define PALMAS_USB_ID_CTRL_CLEAR_ID_GND_DRV_SHIFT 5 -#define PALMAS_USB_ID_CTRL_CLEAR_ID_SRC_16U 0x10 -#define PALMAS_USB_ID_CTRL_CLEAR_ID_SRC_16U_SHIFT 4 -#define PALMAS_USB_ID_CTRL_CLEAR_ID_SRC_5U 0x08 -#define PALMAS_USB_ID_CTRL_CLEAR_ID_SRC_5U_SHIFT 3 -#define PALMAS_USB_ID_CTRL_CLEAR_ID_ACT_COMP 0x04 -#define PALMAS_USB_ID_CTRL_CLEAR_ID_ACT_COMP_SHIFT 2 - -/* Bit definitions for USB_VBUS_INT_SRC */ -#define PALMAS_USB_VBUS_INT_SRC_VOTG_SESS_VLD 0x80 -#define PALMAS_USB_VBUS_INT_SRC_VOTG_SESS_VLD_SHIFT 7 -#define PALMAS_USB_VBUS_INT_SRC_VADP_PRB 0x40 -#define PALMAS_USB_VBUS_INT_SRC_VADP_PRB_SHIFT 6 -#define PALMAS_USB_VBUS_INT_SRC_VADP_SNS 0x20 -#define PALMAS_USB_VBUS_INT_SRC_VADP_SNS_SHIFT 5 -#define PALMAS_USB_VBUS_INT_SRC_VA_VBUS_VLD 0x08 -#define PALMAS_USB_VBUS_INT_SRC_VA_VBUS_VLD_SHIFT 3 -#define PALMAS_USB_VBUS_INT_SRC_VA_SESS_VLD 0x04 -#define PALMAS_USB_VBUS_INT_SRC_VA_SESS_VLD_SHIFT 2 -#define PALMAS_USB_VBUS_INT_SRC_VB_SESS_VLD 0x02 -#define PALMAS_USB_VBUS_INT_SRC_VB_SESS_VLD_SHIFT 1 -#define PALMAS_USB_VBUS_INT_SRC_VB_SESS_END 0x01 -#define PALMAS_USB_VBUS_INT_SRC_VB_SESS_END_SHIFT 0 - -/* Bit definitions for USB_VBUS_INT_LATCH_SET */ -#define PALMAS_USB_VBUS_INT_LATCH_SET_VOTG_SESS_VLD 0x80 -#define PALMAS_USB_VBUS_INT_LATCH_SET_VOTG_SESS_VLD_SHIFT 7 -#define PALMAS_USB_VBUS_INT_LATCH_SET_VADP_PRB 0x40 -#define PALMAS_USB_VBUS_INT_LATCH_SET_VADP_PRB_SHIFT 6 -#define PALMAS_USB_VBUS_INT_LATCH_SET_VADP_SNS 0x20 -#define PALMAS_USB_VBUS_INT_LATCH_SET_VADP_SNS_SHIFT 5 -#define PALMAS_USB_VBUS_INT_LATCH_SET_ADP 0x10 -#define PALMAS_USB_VBUS_INT_LATCH_SET_ADP_SHIFT 4 -#define PALMAS_USB_VBUS_INT_LATCH_SET_VA_VBUS_VLD 0x08 -#define PALMAS_USB_VBUS_INT_LATCH_SET_VA_VBUS_VLD_SHIFT 3 -#define PALMAS_USB_VBUS_INT_LATCH_SET_VA_SESS_VLD 0x04 -#define PALMAS_USB_VBUS_INT_LATCH_SET_VA_SESS_VLD_SHIFT 2 -#define PALMAS_USB_VBUS_INT_LATCH_SET_VB_SESS_VLD 0x02 -#define PALMAS_USB_VBUS_INT_LATCH_SET_VB_SESS_VLD_SHIFT 1 -#define PALMAS_USB_VBUS_INT_LATCH_SET_VB_SESS_END 0x01 -#define PALMAS_USB_VBUS_INT_LATCH_SET_VB_SESS_END_SHIFT 0 - -/* Bit definitions for USB_VBUS_INT_LATCH_CLR */ -#define PALMAS_USB_VBUS_INT_LATCH_CLR_VOTG_SESS_VLD 0x80 -#define PALMAS_USB_VBUS_INT_LATCH_CLR_VOTG_SESS_VLD_SHIFT 7 -#define PALMAS_USB_VBUS_INT_LATCH_CLR_VADP_PRB 0x40 -#define PALMAS_USB_VBUS_INT_LATCH_CLR_VADP_PRB_SHIFT 6 -#define PALMAS_USB_VBUS_INT_LATCH_CLR_VADP_SNS 0x20 -#define PALMAS_USB_VBUS_INT_LATCH_CLR_VADP_SNS_SHIFT 5 -#define PALMAS_USB_VBUS_INT_LATCH_CLR_ADP 0x10 -#define PALMAS_USB_VBUS_INT_LATCH_CLR_ADP_SHIFT 4 -#define PALMAS_USB_VBUS_INT_LATCH_CLR_VA_VBUS_VLD 0x08 -#define PALMAS_USB_VBUS_INT_LATCH_CLR_VA_VBUS_VLD_SHIFT 3 -#define PALMAS_USB_VBUS_INT_LATCH_CLR_VA_SESS_VLD 0x04 -#define PALMAS_USB_VBUS_INT_LATCH_CLR_VA_SESS_VLD_SHIFT 2 -#define PALMAS_USB_VBUS_INT_LATCH_CLR_VB_SESS_VLD 0x02 -#define PALMAS_USB_VBUS_INT_LATCH_CLR_VB_SESS_VLD_SHIFT 1 -#define PALMAS_USB_VBUS_INT_LATCH_CLR_VB_SESS_END 0x01 -#define PALMAS_USB_VBUS_INT_LATCH_CLR_VB_SESS_END_SHIFT 0 - -/* Bit definitions for USB_VBUS_INT_EN_LO_SET */ -#define PALMAS_USB_VBUS_INT_EN_LO_SET_VOTG_SESS_VLD 0x80 -#define PALMAS_USB_VBUS_INT_EN_LO_SET_VOTG_SESS_VLD_SHIFT 7 -#define PALMAS_USB_VBUS_INT_EN_LO_SET_VADP_PRB 0x40 -#define PALMAS_USB_VBUS_INT_EN_LO_SET_VADP_PRB_SHIFT 6 -#define PALMAS_USB_VBUS_INT_EN_LO_SET_VADP_SNS 0x20 -#define PALMAS_USB_VBUS_INT_EN_LO_SET_VADP_SNS_SHIFT 5 -#define PALMAS_USB_VBUS_INT_EN_LO_SET_VA_VBUS_VLD 0x08 -#define PALMAS_USB_VBUS_INT_EN_LO_SET_VA_VBUS_VLD_SHIFT 3 -#define PALMAS_USB_VBUS_INT_EN_LO_SET_VA_SESS_VLD 0x04 -#define PALMAS_USB_VBUS_INT_EN_LO_SET_VA_SESS_VLD_SHIFT 2 -#define PALMAS_USB_VBUS_INT_EN_LO_SET_VB_SESS_VLD 0x02 -#define PALMAS_USB_VBUS_INT_EN_LO_SET_VB_SESS_VLD_SHIFT 1 -#define PALMAS_USB_VBUS_INT_EN_LO_SET_VB_SESS_END 0x01 -#define PALMAS_USB_VBUS_INT_EN_LO_SET_VB_SESS_END_SHIFT 0 - -/* Bit definitions for USB_VBUS_INT_EN_LO_CLR */ -#define PALMAS_USB_VBUS_INT_EN_LO_CLR_VOTG_SESS_VLD 0x80 -#define PALMAS_USB_VBUS_INT_EN_LO_CLR_VOTG_SESS_VLD_SHIFT 7 -#define PALMAS_USB_VBUS_INT_EN_LO_CLR_VADP_PRB 0x40 -#define PALMAS_USB_VBUS_INT_EN_LO_CLR_VADP_PRB_SHIFT 6 -#define PALMAS_USB_VBUS_INT_EN_LO_CLR_VADP_SNS 0x20 -#define PALMAS_USB_VBUS_INT_EN_LO_CLR_VADP_SNS_SHIFT 5 -#define PALMAS_USB_VBUS_INT_EN_LO_CLR_VA_VBUS_VLD 0x08 -#define PALMAS_USB_VBUS_INT_EN_LO_CLR_VA_VBUS_VLD_SHIFT 3 -#define PALMAS_USB_VBUS_INT_EN_LO_CLR_VA_SESS_VLD 0x04 -#define PALMAS_USB_VBUS_INT_EN_LO_CLR_VA_SESS_VLD_SHIFT 2 -#define PALMAS_USB_VBUS_INT_EN_LO_CLR_VB_SESS_VLD 0x02 -#define PALMAS_USB_VBUS_INT_EN_LO_CLR_VB_SESS_VLD_SHIFT 1 -#define PALMAS_USB_VBUS_INT_EN_LO_CLR_VB_SESS_END 0x01 -#define PALMAS_USB_VBUS_INT_EN_LO_CLR_VB_SESS_END_SHIFT 0 - -/* Bit definitions for USB_VBUS_INT_EN_HI_SET */ -#define PALMAS_USB_VBUS_INT_EN_HI_SET_VOTG_SESS_VLD 0x80 -#define PALMAS_USB_VBUS_INT_EN_HI_SET_VOTG_SESS_VLD_SHIFT 7 -#define PALMAS_USB_VBUS_INT_EN_HI_SET_VADP_PRB 0x40 -#define PALMAS_USB_VBUS_INT_EN_HI_SET_VADP_PRB_SHIFT 6 -#define PALMAS_USB_VBUS_INT_EN_HI_SET_VADP_SNS 0x20 -#define PALMAS_USB_VBUS_INT_EN_HI_SET_VADP_SNS_SHIFT 5 -#define PALMAS_USB_VBUS_INT_EN_HI_SET_ADP 0x10 -#define PALMAS_USB_VBUS_INT_EN_HI_SET_ADP_SHIFT 4 -#define PALMAS_USB_VBUS_INT_EN_HI_SET_VA_VBUS_VLD 0x08 -#define PALMAS_USB_VBUS_INT_EN_HI_SET_VA_VBUS_VLD_SHIFT 3 -#define PALMAS_USB_VBUS_INT_EN_HI_SET_VA_SESS_VLD 0x04 -#define PALMAS_USB_VBUS_INT_EN_HI_SET_VA_SESS_VLD_SHIFT 2 -#define PALMAS_USB_VBUS_INT_EN_HI_SET_VB_SESS_VLD 0x02 -#define PALMAS_USB_VBUS_INT_EN_HI_SET_VB_SESS_VLD_SHIFT 1 -#define PALMAS_USB_VBUS_INT_EN_HI_SET_VB_SESS_END 0x01 -#define PALMAS_USB_VBUS_INT_EN_HI_SET_VB_SESS_END_SHIFT 0 - -/* Bit definitions for USB_VBUS_INT_EN_HI_CLR */ -#define PALMAS_USB_VBUS_INT_EN_HI_CLR_VOTG_SESS_VLD 0x80 -#define PALMAS_USB_VBUS_INT_EN_HI_CLR_VOTG_SESS_VLD_SHIFT 7 -#define PALMAS_USB_VBUS_INT_EN_HI_CLR_VADP_PRB 0x40 -#define PALMAS_USB_VBUS_INT_EN_HI_CLR_VADP_PRB_SHIFT 6 -#define PALMAS_USB_VBUS_INT_EN_HI_CLR_VADP_SNS 0x20 -#define PALMAS_USB_VBUS_INT_EN_HI_CLR_VADP_SNS_SHIFT 5 -#define PALMAS_USB_VBUS_INT_EN_HI_CLR_ADP 0x10 -#define PALMAS_USB_VBUS_INT_EN_HI_CLR_ADP_SHIFT 4 -#define PALMAS_USB_VBUS_INT_EN_HI_CLR_VA_VBUS_VLD 0x08 -#define PALMAS_USB_VBUS_INT_EN_HI_CLR_VA_VBUS_VLD_SHIFT 3 -#define PALMAS_USB_VBUS_INT_EN_HI_CLR_VA_SESS_VLD 0x04 -#define PALMAS_USB_VBUS_INT_EN_HI_CLR_VA_SESS_VLD_SHIFT 2 -#define PALMAS_USB_VBUS_INT_EN_HI_CLR_VB_SESS_VLD 0x02 -#define PALMAS_USB_VBUS_INT_EN_HI_CLR_VB_SESS_VLD_SHIFT 1 -#define PALMAS_USB_VBUS_INT_EN_HI_CLR_VB_SESS_END 0x01 -#define PALMAS_USB_VBUS_INT_EN_HI_CLR_VB_SESS_END_SHIFT 0 - -/* Bit definitions for USB_ID_INT_SRC */ -#define PALMAS_USB_ID_INT_SRC_ID_FLOAT 0x10 -#define PALMAS_USB_ID_INT_SRC_ID_FLOAT_SHIFT 4 -#define PALMAS_USB_ID_INT_SRC_ID_A 0x08 -#define PALMAS_USB_ID_INT_SRC_ID_A_SHIFT 3 -#define PALMAS_USB_ID_INT_SRC_ID_B 0x04 -#define PALMAS_USB_ID_INT_SRC_ID_B_SHIFT 2 -#define PALMAS_USB_ID_INT_SRC_ID_C 0x02 -#define PALMAS_USB_ID_INT_SRC_ID_C_SHIFT 1 -#define PALMAS_USB_ID_INT_SRC_ID_GND 0x01 -#define PALMAS_USB_ID_INT_SRC_ID_GND_SHIFT 0 - -/* Bit definitions for USB_ID_INT_LATCH_SET */ -#define PALMAS_USB_ID_INT_LATCH_SET_ID_FLOAT 0x10 -#define PALMAS_USB_ID_INT_LATCH_SET_ID_FLOAT_SHIFT 4 -#define PALMAS_USB_ID_INT_LATCH_SET_ID_A 0x08 -#define PALMAS_USB_ID_INT_LATCH_SET_ID_A_SHIFT 3 -#define PALMAS_USB_ID_INT_LATCH_SET_ID_B 0x04 -#define PALMAS_USB_ID_INT_LATCH_SET_ID_B_SHIFT 2 -#define PALMAS_USB_ID_INT_LATCH_SET_ID_C 0x02 -#define PALMAS_USB_ID_INT_LATCH_SET_ID_C_SHIFT 1 -#define PALMAS_USB_ID_INT_LATCH_SET_ID_GND 0x01 -#define PALMAS_USB_ID_INT_LATCH_SET_ID_GND_SHIFT 0 - -/* Bit definitions for USB_ID_INT_LATCH_CLR */ -#define PALMAS_USB_ID_INT_LATCH_CLR_ID_FLOAT 0x10 -#define PALMAS_USB_ID_INT_LATCH_CLR_ID_FLOAT_SHIFT 4 -#define PALMAS_USB_ID_INT_LATCH_CLR_ID_A 0x08 -#define PALMAS_USB_ID_INT_LATCH_CLR_ID_A_SHIFT 3 -#define PALMAS_USB_ID_INT_LATCH_CLR_ID_B 0x04 -#define PALMAS_USB_ID_INT_LATCH_CLR_ID_B_SHIFT 2 -#define PALMAS_USB_ID_INT_LATCH_CLR_ID_C 0x02 -#define PALMAS_USB_ID_INT_LATCH_CLR_ID_C_SHIFT 1 -#define PALMAS_USB_ID_INT_LATCH_CLR_ID_GND 0x01 -#define PALMAS_USB_ID_INT_LATCH_CLR_ID_GND_SHIFT 0 - -/* Bit definitions for USB_ID_INT_EN_LO_SET */ -#define PALMAS_USB_ID_INT_EN_LO_SET_ID_FLOAT 0x10 -#define PALMAS_USB_ID_INT_EN_LO_SET_ID_FLOAT_SHIFT 4 -#define PALMAS_USB_ID_INT_EN_LO_SET_ID_A 0x08 -#define PALMAS_USB_ID_INT_EN_LO_SET_ID_A_SHIFT 3 -#define PALMAS_USB_ID_INT_EN_LO_SET_ID_B 0x04 -#define PALMAS_USB_ID_INT_EN_LO_SET_ID_B_SHIFT 2 -#define PALMAS_USB_ID_INT_EN_LO_SET_ID_C 0x02 -#define PALMAS_USB_ID_INT_EN_LO_SET_ID_C_SHIFT 1 -#define PALMAS_USB_ID_INT_EN_LO_SET_ID_GND 0x01 -#define PALMAS_USB_ID_INT_EN_LO_SET_ID_GND_SHIFT 0 - -/* Bit definitions for USB_ID_INT_EN_LO_CLR */ -#define PALMAS_USB_ID_INT_EN_LO_CLR_ID_FLOAT 0x10 -#define PALMAS_USB_ID_INT_EN_LO_CLR_ID_FLOAT_SHIFT 4 -#define PALMAS_USB_ID_INT_EN_LO_CLR_ID_A 0x08 -#define PALMAS_USB_ID_INT_EN_LO_CLR_ID_A_SHIFT 3 -#define PALMAS_USB_ID_INT_EN_LO_CLR_ID_B 0x04 -#define PALMAS_USB_ID_INT_EN_LO_CLR_ID_B_SHIFT 2 -#define PALMAS_USB_ID_INT_EN_LO_CLR_ID_C 0x02 -#define PALMAS_USB_ID_INT_EN_LO_CLR_ID_C_SHIFT 1 -#define PALMAS_USB_ID_INT_EN_LO_CLR_ID_GND 0x01 -#define PALMAS_USB_ID_INT_EN_LO_CLR_ID_GND_SHIFT 0 - -/* Bit definitions for USB_ID_INT_EN_HI_SET */ -#define PALMAS_USB_ID_INT_EN_HI_SET_ID_FLOAT 0x10 -#define PALMAS_USB_ID_INT_EN_HI_SET_ID_FLOAT_SHIFT 4 -#define PALMAS_USB_ID_INT_EN_HI_SET_ID_A 0x08 -#define PALMAS_USB_ID_INT_EN_HI_SET_ID_A_SHIFT 3 -#define PALMAS_USB_ID_INT_EN_HI_SET_ID_B 0x04 -#define PALMAS_USB_ID_INT_EN_HI_SET_ID_B_SHIFT 2 -#define PALMAS_USB_ID_INT_EN_HI_SET_ID_C 0x02 -#define PALMAS_USB_ID_INT_EN_HI_SET_ID_C_SHIFT 1 -#define PALMAS_USB_ID_INT_EN_HI_SET_ID_GND 0x01 -#define PALMAS_USB_ID_INT_EN_HI_SET_ID_GND_SHIFT 0 - -/* Bit definitions for USB_ID_INT_EN_HI_CLR */ -#define PALMAS_USB_ID_INT_EN_HI_CLR_ID_FLOAT 0x10 -#define PALMAS_USB_ID_INT_EN_HI_CLR_ID_FLOAT_SHIFT 4 -#define PALMAS_USB_ID_INT_EN_HI_CLR_ID_A 0x08 -#define PALMAS_USB_ID_INT_EN_HI_CLR_ID_A_SHIFT 3 -#define PALMAS_USB_ID_INT_EN_HI_CLR_ID_B 0x04 -#define PALMAS_USB_ID_INT_EN_HI_CLR_ID_B_SHIFT 2 -#define PALMAS_USB_ID_INT_EN_HI_CLR_ID_C 0x02 -#define PALMAS_USB_ID_INT_EN_HI_CLR_ID_C_SHIFT 1 -#define PALMAS_USB_ID_INT_EN_HI_CLR_ID_GND 0x01 -#define PALMAS_USB_ID_INT_EN_HI_CLR_ID_GND_SHIFT 0 - -/* Bit definitions for USB_OTG_ADP_CTRL */ -#define PALMAS_USB_OTG_ADP_CTRL_ADP_EN 0x04 -#define PALMAS_USB_OTG_ADP_CTRL_ADP_EN_SHIFT 2 -#define PALMAS_USB_OTG_ADP_CTRL_ADP_MODE_MASK 0x03 -#define PALMAS_USB_OTG_ADP_CTRL_ADP_MODE_SHIFT 0 - -/* Bit definitions for USB_OTG_ADP_HIGH */ -#define PALMAS_USB_OTG_ADP_HIGH_T_ADP_HIGH_MASK 0xff -#define PALMAS_USB_OTG_ADP_HIGH_T_ADP_HIGH_SHIFT 0 - -/* Bit definitions for USB_OTG_ADP_LOW */ -#define PALMAS_USB_OTG_ADP_LOW_T_ADP_LOW_MASK 0xff -#define PALMAS_USB_OTG_ADP_LOW_T_ADP_LOW_SHIFT 0 - -/* Bit definitions for USB_OTG_ADP_RISE */ -#define PALMAS_USB_OTG_ADP_RISE_T_ADP_RISE_MASK 0xff -#define PALMAS_USB_OTG_ADP_RISE_T_ADP_RISE_SHIFT 0 - -/* Bit definitions for USB_OTG_REVISION */ -#define PALMAS_USB_OTG_REVISION_OTG_REV 0x01 -#define PALMAS_USB_OTG_REVISION_OTG_REV_SHIFT 0 - -/* Registers for function VIBRATOR */ -#define PALMAS_VIBRA_CTRL 0x0 - -/* Bit definitions for VIBRA_CTRL */ -#define PALMAS_VIBRA_CTRL_PWM_DUTY_SEL_MASK 0x06 -#define PALMAS_VIBRA_CTRL_PWM_DUTY_SEL_SHIFT 1 -#define PALMAS_VIBRA_CTRL_PWM_FREQ_SEL 0x01 -#define PALMAS_VIBRA_CTRL_PWM_FREQ_SEL_SHIFT 0 - -/* Registers for function GPIO */ -#define PALMAS_GPIO_DATA_IN 0x0 -#define PALMAS_GPIO_DATA_DIR 0x1 -#define PALMAS_GPIO_DATA_OUT 0x2 -#define PALMAS_GPIO_DEBOUNCE_EN 0x3 -#define PALMAS_GPIO_CLEAR_DATA_OUT 0x4 -#define PALMAS_GPIO_SET_DATA_OUT 0x5 -#define PALMAS_PU_PD_GPIO_CTRL1 0x6 -#define PALMAS_PU_PD_GPIO_CTRL2 0x7 -#define PALMAS_OD_OUTPUT_GPIO_CTRL 0x8 - -/* Bit definitions for GPIO_DATA_IN */ -#define PALMAS_GPIO_DATA_IN_GPIO_7_IN 0x80 -#define PALMAS_GPIO_DATA_IN_GPIO_7_IN_SHIFT 7 -#define PALMAS_GPIO_DATA_IN_GPIO_6_IN 0x40 -#define PALMAS_GPIO_DATA_IN_GPIO_6_IN_SHIFT 6 -#define PALMAS_GPIO_DATA_IN_GPIO_5_IN 0x20 -#define PALMAS_GPIO_DATA_IN_GPIO_5_IN_SHIFT 5 -#define PALMAS_GPIO_DATA_IN_GPIO_4_IN 0x10 -#define PALMAS_GPIO_DATA_IN_GPIO_4_IN_SHIFT 4 -#define PALMAS_GPIO_DATA_IN_GPIO_3_IN 0x08 -#define PALMAS_GPIO_DATA_IN_GPIO_3_IN_SHIFT 3 -#define PALMAS_GPIO_DATA_IN_GPIO_2_IN 0x04 -#define PALMAS_GPIO_DATA_IN_GPIO_2_IN_SHIFT 2 -#define PALMAS_GPIO_DATA_IN_GPIO_1_IN 0x02 -#define PALMAS_GPIO_DATA_IN_GPIO_1_IN_SHIFT 1 -#define PALMAS_GPIO_DATA_IN_GPIO_0_IN 0x01 -#define PALMAS_GPIO_DATA_IN_GPIO_0_IN_SHIFT 0 - -/* Bit definitions for GPIO_DATA_DIR */ -#define PALMAS_GPIO_DATA_DIR_GPIO_7_DIR 0x80 -#define PALMAS_GPIO_DATA_DIR_GPIO_7_DIR_SHIFT 7 -#define PALMAS_GPIO_DATA_DIR_GPIO_6_DIR 0x40 -#define PALMAS_GPIO_DATA_DIR_GPIO_6_DIR_SHIFT 6 -#define PALMAS_GPIO_DATA_DIR_GPIO_5_DIR 0x20 -#define PALMAS_GPIO_DATA_DIR_GPIO_5_DIR_SHIFT 5 -#define PALMAS_GPIO_DATA_DIR_GPIO_4_DIR 0x10 -#define PALMAS_GPIO_DATA_DIR_GPIO_4_DIR_SHIFT 4 -#define PALMAS_GPIO_DATA_DIR_GPIO_3_DIR 0x08 -#define PALMAS_GPIO_DATA_DIR_GPIO_3_DIR_SHIFT 3 -#define PALMAS_GPIO_DATA_DIR_GPIO_2_DIR 0x04 -#define PALMAS_GPIO_DATA_DIR_GPIO_2_DIR_SHIFT 2 -#define PALMAS_GPIO_DATA_DIR_GPIO_1_DIR 0x02 -#define PALMAS_GPIO_DATA_DIR_GPIO_1_DIR_SHIFT 1 -#define PALMAS_GPIO_DATA_DIR_GPIO_0_DIR 0x01 -#define PALMAS_GPIO_DATA_DIR_GPIO_0_DIR_SHIFT 0 - -/* Bit definitions for GPIO_DATA_OUT */ -#define PALMAS_GPIO_DATA_OUT_GPIO_7_OUT 0x80 -#define PALMAS_GPIO_DATA_OUT_GPIO_7_OUT_SHIFT 7 -#define PALMAS_GPIO_DATA_OUT_GPIO_6_OUT 0x40 -#define PALMAS_GPIO_DATA_OUT_GPIO_6_OUT_SHIFT 6 -#define PALMAS_GPIO_DATA_OUT_GPIO_5_OUT 0x20 -#define PALMAS_GPIO_DATA_OUT_GPIO_5_OUT_SHIFT 5 -#define PALMAS_GPIO_DATA_OUT_GPIO_4_OUT 0x10 -#define PALMAS_GPIO_DATA_OUT_GPIO_4_OUT_SHIFT 4 -#define PALMAS_GPIO_DATA_OUT_GPIO_3_OUT 0x08 -#define PALMAS_GPIO_DATA_OUT_GPIO_3_OUT_SHIFT 3 -#define PALMAS_GPIO_DATA_OUT_GPIO_2_OUT 0x04 -#define PALMAS_GPIO_DATA_OUT_GPIO_2_OUT_SHIFT 2 -#define PALMAS_GPIO_DATA_OUT_GPIO_1_OUT 0x02 -#define PALMAS_GPIO_DATA_OUT_GPIO_1_OUT_SHIFT 1 -#define PALMAS_GPIO_DATA_OUT_GPIO_0_OUT 0x01 -#define PALMAS_GPIO_DATA_OUT_GPIO_0_OUT_SHIFT 0 - -/* Bit definitions for GPIO_DEBOUNCE_EN */ -#define PALMAS_GPIO_DEBOUNCE_EN_GPIO_7_DEBOUNCE_EN 0x80 -#define PALMAS_GPIO_DEBOUNCE_EN_GPIO_7_DEBOUNCE_EN_SHIFT 7 -#define PALMAS_GPIO_DEBOUNCE_EN_GPIO_6_DEBOUNCE_EN 0x40 -#define PALMAS_GPIO_DEBOUNCE_EN_GPIO_6_DEBOUNCE_EN_SHIFT 6 -#define PALMAS_GPIO_DEBOUNCE_EN_GPIO_5_DEBOUNCE_EN 0x20 -#define PALMAS_GPIO_DEBOUNCE_EN_GPIO_5_DEBOUNCE_EN_SHIFT 5 -#define PALMAS_GPIO_DEBOUNCE_EN_GPIO_4_DEBOUNCE_EN 0x10 -#define PALMAS_GPIO_DEBOUNCE_EN_GPIO_4_DEBOUNCE_EN_SHIFT 4 -#define PALMAS_GPIO_DEBOUNCE_EN_GPIO_3_DEBOUNCE_EN 0x08 -#define PALMAS_GPIO_DEBOUNCE_EN_GPIO_3_DEBOUNCE_EN_SHIFT 3 -#define PALMAS_GPIO_DEBOUNCE_EN_GPIO_2_DEBOUNCE_EN 0x04 -#define PALMAS_GPIO_DEBOUNCE_EN_GPIO_2_DEBOUNCE_EN_SHIFT 2 -#define PALMAS_GPIO_DEBOUNCE_EN_GPIO_1_DEBOUNCE_EN 0x02 -#define PALMAS_GPIO_DEBOUNCE_EN_GPIO_1_DEBOUNCE_EN_SHIFT 1 -#define PALMAS_GPIO_DEBOUNCE_EN_GPIO_0_DEBOUNCE_EN 0x01 -#define PALMAS_GPIO_DEBOUNCE_EN_GPIO_0_DEBOUNCE_EN_SHIFT 0 - -/* Bit definitions for GPIO_CLEAR_DATA_OUT */ -#define PALMAS_GPIO_CLEAR_DATA_OUT_GPIO_7_CLEAR_DATA_OUT 0x80 -#define PALMAS_GPIO_CLEAR_DATA_OUT_GPIO_7_CLEAR_DATA_OUT_SHIFT 7 -#define PALMAS_GPIO_CLEAR_DATA_OUT_GPIO_6_CLEAR_DATA_OUT 0x40 -#define PALMAS_GPIO_CLEAR_DATA_OUT_GPIO_6_CLEAR_DATA_OUT_SHIFT 6 -#define PALMAS_GPIO_CLEAR_DATA_OUT_GPIO_5_CLEAR_DATA_OUT 0x20 -#define PALMAS_GPIO_CLEAR_DATA_OUT_GPIO_5_CLEAR_DATA_OUT_SHIFT 5 -#define PALMAS_GPIO_CLEAR_DATA_OUT_GPIO_4_CLEAR_DATA_OUT 0x10 -#define PALMAS_GPIO_CLEAR_DATA_OUT_GPIO_4_CLEAR_DATA_OUT_SHIFT 4 -#define PALMAS_GPIO_CLEAR_DATA_OUT_GPIO_3_CLEAR_DATA_OUT 0x08 -#define PALMAS_GPIO_CLEAR_DATA_OUT_GPIO_3_CLEAR_DATA_OUT_SHIFT 3 -#define PALMAS_GPIO_CLEAR_DATA_OUT_GPIO_2_CLEAR_DATA_OUT 0x04 -#define PALMAS_GPIO_CLEAR_DATA_OUT_GPIO_2_CLEAR_DATA_OUT_SHIFT 2 -#define PALMAS_GPIO_CLEAR_DATA_OUT_GPIO_1_CLEAR_DATA_OUT 0x02 -#define PALMAS_GPIO_CLEAR_DATA_OUT_GPIO_1_CLEAR_DATA_OUT_SHIFT 1 -#define PALMAS_GPIO_CLEAR_DATA_OUT_GPIO_0_CLEAR_DATA_OUT 0x01 -#define PALMAS_GPIO_CLEAR_DATA_OUT_GPIO_0_CLEAR_DATA_OUT_SHIFT 0 - -/* Bit definitions for GPIO_SET_DATA_OUT */ -#define PALMAS_GPIO_SET_DATA_OUT_GPIO_7_SET_DATA_OUT 0x80 -#define PALMAS_GPIO_SET_DATA_OUT_GPIO_7_SET_DATA_OUT_SHIFT 7 -#define PALMAS_GPIO_SET_DATA_OUT_GPIO_6_SET_DATA_OUT 0x40 -#define PALMAS_GPIO_SET_DATA_OUT_GPIO_6_SET_DATA_OUT_SHIFT 6 -#define PALMAS_GPIO_SET_DATA_OUT_GPIO_5_SET_DATA_OUT 0x20 -#define PALMAS_GPIO_SET_DATA_OUT_GPIO_5_SET_DATA_OUT_SHIFT 5 -#define PALMAS_GPIO_SET_DATA_OUT_GPIO_4_SET_DATA_OUT 0x10 -#define PALMAS_GPIO_SET_DATA_OUT_GPIO_4_SET_DATA_OUT_SHIFT 4 -#define PALMAS_GPIO_SET_DATA_OUT_GPIO_3_SET_DATA_OUT 0x08 -#define PALMAS_GPIO_SET_DATA_OUT_GPIO_3_SET_DATA_OUT_SHIFT 3 -#define PALMAS_GPIO_SET_DATA_OUT_GPIO_2_SET_DATA_OUT 0x04 -#define PALMAS_GPIO_SET_DATA_OUT_GPIO_2_SET_DATA_OUT_SHIFT 2 -#define PALMAS_GPIO_SET_DATA_OUT_GPIO_1_SET_DATA_OUT 0x02 -#define PALMAS_GPIO_SET_DATA_OUT_GPIO_1_SET_DATA_OUT_SHIFT 1 -#define PALMAS_GPIO_SET_DATA_OUT_GPIO_0_SET_DATA_OUT 0x01 -#define PALMAS_GPIO_SET_DATA_OUT_GPIO_0_SET_DATA_OUT_SHIFT 0 - -/* Bit definitions for PU_PD_GPIO_CTRL1 */ -#define PALMAS_PU_PD_GPIO_CTRL1_GPIO_3_PD 0x40 -#define PALMAS_PU_PD_GPIO_CTRL1_GPIO_3_PD_SHIFT 6 -#define PALMAS_PU_PD_GPIO_CTRL1_GPIO_2_PU 0x20 -#define PALMAS_PU_PD_GPIO_CTRL1_GPIO_2_PU_SHIFT 5 -#define PALMAS_PU_PD_GPIO_CTRL1_GPIO_2_PD 0x10 -#define PALMAS_PU_PD_GPIO_CTRL1_GPIO_2_PD_SHIFT 4 -#define PALMAS_PU_PD_GPIO_CTRL1_GPIO_1_PU 0x08 -#define PALMAS_PU_PD_GPIO_CTRL1_GPIO_1_PU_SHIFT 3 -#define PALMAS_PU_PD_GPIO_CTRL1_GPIO_1_PD 0x04 -#define PALMAS_PU_PD_GPIO_CTRL1_GPIO_1_PD_SHIFT 2 -#define PALMAS_PU_PD_GPIO_CTRL1_GPIO_0_PD 0x01 -#define PALMAS_PU_PD_GPIO_CTRL1_GPIO_0_PD_SHIFT 0 - -/* Bit definitions for PU_PD_GPIO_CTRL2 */ -#define PALMAS_PU_PD_GPIO_CTRL2_GPIO_7_PD 0x40 -#define PALMAS_PU_PD_GPIO_CTRL2_GPIO_7_PD_SHIFT 6 -#define PALMAS_PU_PD_GPIO_CTRL2_GPIO_6_PU 0x20 -#define PALMAS_PU_PD_GPIO_CTRL2_GPIO_6_PU_SHIFT 5 -#define PALMAS_PU_PD_GPIO_CTRL2_GPIO_6_PD 0x10 -#define PALMAS_PU_PD_GPIO_CTRL2_GPIO_6_PD_SHIFT 4 -#define PALMAS_PU_PD_GPIO_CTRL2_GPIO_5_PU 0x08 -#define PALMAS_PU_PD_GPIO_CTRL2_GPIO_5_PU_SHIFT 3 -#define PALMAS_PU_PD_GPIO_CTRL2_GPIO_5_PD 0x04 -#define PALMAS_PU_PD_GPIO_CTRL2_GPIO_5_PD_SHIFT 2 -#define PALMAS_PU_PD_GPIO_CTRL2_GPIO_4_PU 0x02 -#define PALMAS_PU_PD_GPIO_CTRL2_GPIO_4_PU_SHIFT 1 -#define PALMAS_PU_PD_GPIO_CTRL2_GPIO_4_PD 0x01 -#define PALMAS_PU_PD_GPIO_CTRL2_GPIO_4_PD_SHIFT 0 - -/* Bit definitions for OD_OUTPUT_GPIO_CTRL */ -#define PALMAS_OD_OUTPUT_GPIO_CTRL_GPIO_5_OD 0x20 -#define PALMAS_OD_OUTPUT_GPIO_CTRL_GPIO_5_OD_SHIFT 5 -#define PALMAS_OD_OUTPUT_GPIO_CTRL_GPIO_2_OD 0x04 -#define PALMAS_OD_OUTPUT_GPIO_CTRL_GPIO_2_OD_SHIFT 2 -#define PALMAS_OD_OUTPUT_GPIO_CTRL_GPIO_1_OD 0x02 -#define PALMAS_OD_OUTPUT_GPIO_CTRL_GPIO_1_OD_SHIFT 1 - -/* Registers for function GPADC */ -#define PALMAS_GPADC_CTRL1 0x0 -#define PALMAS_GPADC_CTRL2 0x1 -#define PALMAS_GPADC_RT_CTRL 0x2 -#define PALMAS_GPADC_AUTO_CTRL 0x3 -#define PALMAS_GPADC_STATUS 0x4 -#define PALMAS_GPADC_RT_SELECT 0x5 -#define PALMAS_GPADC_RT_CONV0_LSB 0x6 -#define PALMAS_GPADC_RT_CONV0_MSB 0x7 -#define PALMAS_GPADC_AUTO_SELECT 0x8 -#define PALMAS_GPADC_AUTO_CONV0_LSB 0x9 -#define PALMAS_GPADC_AUTO_CONV0_MSB 0xA -#define PALMAS_GPADC_AUTO_CONV1_LSB 0xB -#define PALMAS_GPADC_AUTO_CONV1_MSB 0xC -#define PALMAS_GPADC_SW_SELECT 0xD -#define PALMAS_GPADC_SW_CONV0_LSB 0xE -#define PALMAS_GPADC_SW_CONV0_MSB 0xF -#define PALMAS_GPADC_THRES_CONV0_LSB 0x10 -#define PALMAS_GPADC_THRES_CONV0_MSB 0x11 -#define PALMAS_GPADC_THRES_CONV1_LSB 0x12 -#define PALMAS_GPADC_THRES_CONV1_MSB 0x13 -#define PALMAS_GPADC_SMPS_ILMONITOR_EN 0x14 -#define PALMAS_GPADC_SMPS_VSEL_MONITORING 0x15 - -/* Bit definitions for GPADC_CTRL1 */ -#define PALMAS_GPADC_CTRL1_RESERVED_MASK 0xc0 -#define PALMAS_GPADC_CTRL1_RESERVED_SHIFT 6 -#define PALMAS_GPADC_CTRL1_CURRENT_SRC_CH3_MASK 0x30 -#define PALMAS_GPADC_CTRL1_CURRENT_SRC_CH3_SHIFT 4 -#define PALMAS_GPADC_CTRL1_CURRENT_SRC_CH0_MASK 0x0c -#define PALMAS_GPADC_CTRL1_CURRENT_SRC_CH0_SHIFT 2 -#define PALMAS_GPADC_CTRL1_BAT_REMOVAL_DET 0x02 -#define PALMAS_GPADC_CTRL1_BAT_REMOVAL_DET_SHIFT 1 -#define PALMAS_GPADC_CTRL1_GPADC_FORCE 0x01 -#define PALMAS_GPADC_CTRL1_GPADC_FORCE_SHIFT 0 - -/* Bit definitions for GPADC_CTRL2 */ -#define PALMAS_GPADC_CTRL2_RESERVED_MASK 0x06 -#define PALMAS_GPADC_CTRL2_RESERVED_SHIFT 1 - -/* Bit definitions for GPADC_RT_CTRL */ -#define PALMAS_GPADC_RT_CTRL_EXTEND_DELAY 0x02 -#define PALMAS_GPADC_RT_CTRL_EXTEND_DELAY_SHIFT 1 -#define PALMAS_GPADC_RT_CTRL_START_POLARITY 0x01 -#define PALMAS_GPADC_RT_CTRL_START_POLARITY_SHIFT 0 - -/* Bit definitions for GPADC_AUTO_CTRL */ -#define PALMAS_GPADC_AUTO_CTRL_SHUTDOWN_CONV1 0x80 -#define PALMAS_GPADC_AUTO_CTRL_SHUTDOWN_CONV1_SHIFT 7 -#define PALMAS_GPADC_AUTO_CTRL_SHUTDOWN_CONV0 0x40 -#define PALMAS_GPADC_AUTO_CTRL_SHUTDOWN_CONV0_SHIFT 6 -#define PALMAS_GPADC_AUTO_CTRL_AUTO_CONV1_EN 0x20 -#define PALMAS_GPADC_AUTO_CTRL_AUTO_CONV1_EN_SHIFT 5 -#define PALMAS_GPADC_AUTO_CTRL_AUTO_CONV0_EN 0x10 -#define PALMAS_GPADC_AUTO_CTRL_AUTO_CONV0_EN_SHIFT 4 -#define PALMAS_GPADC_AUTO_CTRL_COUNTER_CONV_MASK 0x0f -#define PALMAS_GPADC_AUTO_CTRL_COUNTER_CONV_SHIFT 0 - -/* Bit definitions for GPADC_STATUS */ -#define PALMAS_GPADC_STATUS_GPADC_AVAILABLE 0x10 -#define PALMAS_GPADC_STATUS_GPADC_AVAILABLE_SHIFT 4 - -/* Bit definitions for GPADC_RT_SELECT */ -#define PALMAS_GPADC_RT_SELECT_RT_CONV_EN 0x80 -#define PALMAS_GPADC_RT_SELECT_RT_CONV_EN_SHIFT 7 -#define PALMAS_GPADC_RT_SELECT_RT_CONV0_SEL_MASK 0x0f -#define PALMAS_GPADC_RT_SELECT_RT_CONV0_SEL_SHIFT 0 - -/* Bit definitions for GPADC_RT_CONV0_LSB */ -#define PALMAS_GPADC_RT_CONV0_LSB_RT_CONV0_LSB_MASK 0xff -#define PALMAS_GPADC_RT_CONV0_LSB_RT_CONV0_LSB_SHIFT 0 - -/* Bit definitions for GPADC_RT_CONV0_MSB */ -#define PALMAS_GPADC_RT_CONV0_MSB_RT_CONV0_MSB_MASK 0x0f -#define PALMAS_GPADC_RT_CONV0_MSB_RT_CONV0_MSB_SHIFT 0 - -/* Bit definitions for GPADC_AUTO_SELECT */ -#define PALMAS_GPADC_AUTO_SELECT_AUTO_CONV1_SEL_MASK 0xf0 -#define PALMAS_GPADC_AUTO_SELECT_AUTO_CONV1_SEL_SHIFT 4 -#define PALMAS_GPADC_AUTO_SELECT_AUTO_CONV0_SEL_MASK 0x0f -#define PALMAS_GPADC_AUTO_SELECT_AUTO_CONV0_SEL_SHIFT 0 - -/* Bit definitions for GPADC_AUTO_CONV0_LSB */ -#define PALMAS_GPADC_AUTO_CONV0_LSB_AUTO_CONV0_LSB_MASK 0xff -#define PALMAS_GPADC_AUTO_CONV0_LSB_AUTO_CONV0_LSB_SHIFT 0 - -/* Bit definitions for GPADC_AUTO_CONV0_MSB */ -#define PALMAS_GPADC_AUTO_CONV0_MSB_AUTO_CONV0_MSB_MASK 0x0f -#define PALMAS_GPADC_AUTO_CONV0_MSB_AUTO_CONV0_MSB_SHIFT 0 - -/* Bit definitions for GPADC_AUTO_CONV1_LSB */ -#define PALMAS_GPADC_AUTO_CONV1_LSB_AUTO_CONV1_LSB_MASK 0xff -#define PALMAS_GPADC_AUTO_CONV1_LSB_AUTO_CONV1_LSB_SHIFT 0 - -/* Bit definitions for GPADC_AUTO_CONV1_MSB */ -#define PALMAS_GPADC_AUTO_CONV1_MSB_AUTO_CONV1_MSB_MASK 0x0f -#define PALMAS_GPADC_AUTO_CONV1_MSB_AUTO_CONV1_MSB_SHIFT 0 - -/* Bit definitions for GPADC_SW_SELECT */ -#define PALMAS_GPADC_SW_SELECT_SW_CONV_EN 0x80 -#define PALMAS_GPADC_SW_SELECT_SW_CONV_EN_SHIFT 7 -#define PALMAS_GPADC_SW_SELECT_SW_START_CONV0 0x10 -#define PALMAS_GPADC_SW_SELECT_SW_START_CONV0_SHIFT 4 -#define PALMAS_GPADC_SW_SELECT_SW_CONV0_SEL_MASK 0x0f -#define PALMAS_GPADC_SW_SELECT_SW_CONV0_SEL_SHIFT 0 - -/* Bit definitions for GPADC_SW_CONV0_LSB */ -#define PALMAS_GPADC_SW_CONV0_LSB_SW_CONV0_LSB_MASK 0xff -#define PALMAS_GPADC_SW_CONV0_LSB_SW_CONV0_LSB_SHIFT 0 - -/* Bit definitions for GPADC_SW_CONV0_MSB */ -#define PALMAS_GPADC_SW_CONV0_MSB_SW_CONV0_MSB_MASK 0x0f -#define PALMAS_GPADC_SW_CONV0_MSB_SW_CONV0_MSB_SHIFT 0 - -/* Bit definitions for GPADC_THRES_CONV0_LSB */ -#define PALMAS_GPADC_THRES_CONV0_LSB_THRES_CONV0_LSB_MASK 0xff -#define PALMAS_GPADC_THRES_CONV0_LSB_THRES_CONV0_LSB_SHIFT 0 - -/* Bit definitions for GPADC_THRES_CONV0_MSB */ -#define PALMAS_GPADC_THRES_CONV0_MSB_THRES_CONV0_POL 0x80 -#define PALMAS_GPADC_THRES_CONV0_MSB_THRES_CONV0_POL_SHIFT 7 -#define PALMAS_GPADC_THRES_CONV0_MSB_THRES_CONV0_MSB_MASK 0x0f -#define PALMAS_GPADC_THRES_CONV0_MSB_THRES_CONV0_MSB_SHIFT 0 - -/* Bit definitions for GPADC_THRES_CONV1_LSB */ -#define PALMAS_GPADC_THRES_CONV1_LSB_THRES_CONV1_LSB_MASK 0xff -#define PALMAS_GPADC_THRES_CONV1_LSB_THRES_CONV1_LSB_SHIFT 0 - -/* Bit definitions for GPADC_THRES_CONV1_MSB */ -#define PALMAS_GPADC_THRES_CONV1_MSB_THRES_CONV1_POL 0x80 -#define PALMAS_GPADC_THRES_CONV1_MSB_THRES_CONV1_POL_SHIFT 7 -#define PALMAS_GPADC_THRES_CONV1_MSB_THRES_CONV1_MSB_MASK 0x0f -#define PALMAS_GPADC_THRES_CONV1_MSB_THRES_CONV1_MSB_SHIFT 0 - -/* Bit definitions for GPADC_SMPS_ILMONITOR_EN */ -#define PALMAS_GPADC_SMPS_ILMONITOR_EN_SMPS_ILMON_EN 0x20 -#define PALMAS_GPADC_SMPS_ILMONITOR_EN_SMPS_ILMON_EN_SHIFT 5 -#define PALMAS_GPADC_SMPS_ILMONITOR_EN_SMPS_ILMON_REXT 0x10 -#define PALMAS_GPADC_SMPS_ILMONITOR_EN_SMPS_ILMON_REXT_SHIFT 4 -#define PALMAS_GPADC_SMPS_ILMONITOR_EN_SMPS_ILMON_SEL_MASK 0x0f -#define PALMAS_GPADC_SMPS_ILMONITOR_EN_SMPS_ILMON_SEL_SHIFT 0 - -/* Bit definitions for GPADC_SMPS_VSEL_MONITORING */ -#define PALMAS_GPADC_SMPS_VSEL_MONITORING_ACTIVE_PHASE 0x80 -#define PALMAS_GPADC_SMPS_VSEL_MONITORING_ACTIVE_PHASE_SHIFT 7 -#define PALMAS_GPADC_SMPS_VSEL_MONITORING_SMPS_VSEL_MONITORING_MASK 0x7f -#define PALMAS_GPADC_SMPS_VSEL_MONITORING_SMPS_VSEL_MONITORING_SHIFT 0 - -/* Registers for function GPADC */ -#define PALMAS_GPADC_TRIM1 0x0 -#define PALMAS_GPADC_TRIM2 0x1 -#define PALMAS_GPADC_TRIM3 0x2 -#define PALMAS_GPADC_TRIM4 0x3 -#define PALMAS_GPADC_TRIM5 0x4 -#define PALMAS_GPADC_TRIM6 0x5 -#define PALMAS_GPADC_TRIM7 0x6 -#define PALMAS_GPADC_TRIM8 0x7 -#define PALMAS_GPADC_TRIM9 0x8 -#define PALMAS_GPADC_TRIM10 0x9 -#define PALMAS_GPADC_TRIM11 0xA -#define PALMAS_GPADC_TRIM12 0xB -#define PALMAS_GPADC_TRIM13 0xC -#define PALMAS_GPADC_TRIM14 0xD -#define PALMAS_GPADC_TRIM15 0xE -#define PALMAS_GPADC_TRIM16 0xF - -#endif /* __LINUX_MFD_PALMAS_H */ diff --git a/trunk/include/linux/mfd/rc5t583.h b/trunk/include/linux/mfd/rc5t583.h index c42fe92a727d..0b64b19d81ab 100644 --- a/trunk/include/linux/mfd/rc5t583.h +++ b/trunk/include/linux/mfd/rc5t583.h @@ -250,26 +250,6 @@ enum { RC5T583_EXT_PWRREQ2_CONTROL = 0x2, }; -enum { - RC5T583_REGULATOR_DC0, - RC5T583_REGULATOR_DC1, - RC5T583_REGULATOR_DC2, - RC5T583_REGULATOR_DC3, - RC5T583_REGULATOR_LDO0, - RC5T583_REGULATOR_LDO1, - RC5T583_REGULATOR_LDO2, - RC5T583_REGULATOR_LDO3, - RC5T583_REGULATOR_LDO4, - RC5T583_REGULATOR_LDO5, - RC5T583_REGULATOR_LDO6, - RC5T583_REGULATOR_LDO7, - RC5T583_REGULATOR_LDO8, - RC5T583_REGULATOR_LDO9, - - /* Should be last entry */ - RC5T583_REGULATOR_MAX, -}; - struct rc5t583 { struct device *dev; struct regmap *regmap; @@ -293,20 +273,11 @@ struct rc5t583 { * The board specific data is provided through this structure. * @irq_base: Irq base number on which this device registers their interrupts. * @enable_shutdown: Enable shutdown through the input pin "shutdown". - * @regulator_deepsleep_slot: The slot number on which device goes to sleep - * in device sleep mode. - * @regulator_ext_pwr_control: External power request regulator control. The - * regulator output enable/disable is controlled by the external - * power request input state. - * @reg_init_data: Regulator init data. */ struct rc5t583_platform_data { int irq_base; bool enable_shutdown; - int regulator_deepsleep_slot[RC5T583_REGULATOR_MAX]; - unsigned long regulator_ext_pwr_control[RC5T583_REGULATOR_MAX]; - struct regulator_init_data *reg_init_data[RC5T583_REGULATOR_MAX]; }; static inline int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val) diff --git a/trunk/include/linux/mfd/s5m87xx/s5m-core.h b/trunk/include/linux/mfd/s5m87xx/s5m-core.h index 21603b42f22f..a7480b57f92d 100644 --- a/trunk/include/linux/mfd/s5m87xx/s5m-core.h +++ b/trunk/include/linux/mfd/s5m87xx/s5m-core.h @@ -335,7 +335,6 @@ extern int s5m_reg_update(struct s5m87xx_dev *s5m87xx, u8 reg, u8 val, u8 mask); struct s5m_platform_data { struct s5m_regulator_data *regulators; - struct s5m_opmode_data *opmode; int device_type; int num_regulators; diff --git a/trunk/include/linux/mfd/s5m87xx/s5m-pmic.h b/trunk/include/linux/mfd/s5m87xx/s5m-pmic.h index 7c719f20f58a..a72a5d27e62e 100644 --- a/trunk/include/linux/mfd/s5m87xx/s5m-pmic.h +++ b/trunk/include/linux/mfd/s5m87xx/s5m-pmic.h @@ -58,8 +58,6 @@ enum s5m8767_regulators { S5M8767_REG_MAX, }; -#define S5M8767_ENCTRL_SHIFT 6 - /* S5M8763 regulator ids */ enum s5m8763_regulators { S5M8763_LDO1, @@ -99,31 +97,4 @@ struct s5m_regulator_data { struct regulator_init_data *initdata; }; -/* - * s5m_opmode_data - regulator operation mode data - * @id: regulator id - * @mode: regulator operation mode - */ -struct s5m_opmode_data { - int id; - int mode; -}; - -/* - * s5m regulator operation mode - * S5M_OPMODE_OFF Regulator always OFF - * S5M_OPMODE_ON Regulator always ON - * S5M_OPMODE_LOWPOWER Regulator is on in low-power mode - * S5M_OPMODE_SUSPEND Regulator is changed by PWREN pin - * If PWREN is high, regulator is on - * If PWREN is low, regulator is off - */ - -enum s5m_opmode { - S5M_OPMODE_OFF, - S5M_OPMODE_ON, - S5M_OPMODE_LOWPOWER, - S5M_OPMODE_SUSPEND, -}; - #endif /* __LINUX_MFD_S5M_PMIC_H */ diff --git a/trunk/include/linux/mfd/tps65090.h b/trunk/include/linux/mfd/tps65090.h index 6bc31d854626..38e31c55adbb 100644 --- a/trunk/include/linux/mfd/tps65090.h +++ b/trunk/include/linux/mfd/tps65090.h @@ -22,19 +22,6 @@ #ifndef __LINUX_MFD_TPS65090_H #define __LINUX_MFD_TPS65090_H -#include - -struct tps65090 { - struct mutex lock; - struct device *dev; - struct i2c_client *client; - struct regmap *rmap; - struct irq_chip irq_chip; - struct mutex irq_lock; - int irq_base; - unsigned int id; -}; - struct tps65090_subdev_info { int id; const char *name; diff --git a/trunk/include/linux/mfd/tps6586x.h b/trunk/include/linux/mfd/tps6586x.h index f350fd0ba1df..b19176eab44d 100644 --- a/trunk/include/linux/mfd/tps6586x.h +++ b/trunk/include/linux/mfd/tps6586x.h @@ -68,7 +68,6 @@ struct tps6586x_subdev_info { int id; const char *name; void *platform_data; - struct device_node *of_node; }; struct tps6586x_platform_data { diff --git a/trunk/include/linux/mfd/wm8994/core.h b/trunk/include/linux/mfd/wm8994/core.h index 6695c3ec4518..9eff2a351ec5 100644 --- a/trunk/include/linux/mfd/wm8994/core.h +++ b/trunk/include/linux/mfd/wm8994/core.h @@ -17,7 +17,6 @@ #include #include -#include enum wm8994_type { WM8994 = 0, @@ -27,6 +26,7 @@ enum wm8994_type { struct regulator_dev; struct regulator_bulk_data; +struct regmap; #define WM8994_NUM_GPIO_REGS 11 #define WM8994_NUM_LDO_REGS 2 @@ -94,17 +94,17 @@ static inline int wm8994_request_irq(struct wm8994 *wm8994, int irq, irq_handler_t handler, const char *name, void *data) { - if (!wm8994->irq_data) + if (!wm8994->irq_base) return -EINVAL; - return request_threaded_irq(regmap_irq_get_virq(wm8994->irq_data, irq), - NULL, handler, IRQF_TRIGGER_RISING, name, + return request_threaded_irq(wm8994->irq_base + irq, NULL, handler, + IRQF_TRIGGER_RISING, name, data); } static inline void wm8994_free_irq(struct wm8994 *wm8994, int irq, void *data) { - if (!wm8994->irq_data) + if (!wm8994->irq_base) return; - free_irq(regmap_irq_get_virq(wm8994->irq_data, irq), data); + free_irq(wm8994->irq_base + irq, data); } int wm8994_irq_init(struct wm8994 *wm8994); diff --git a/trunk/include/linux/micrel_phy.h b/trunk/include/linux/micrel_phy.h index 61f0905bdc48..dd8da342a991 100644 --- a/trunk/include/linux/micrel_phy.h +++ b/trunk/include/linux/micrel_phy.h @@ -3,7 +3,7 @@ #define MICREL_PHY_ID_MASK 0x00fffff0 -#define PHY_ID_KSZ9021 0x00221610 +#define PHY_ID_KSZ9021 0x00221611 #define PHY_ID_KS8737 0x00221720 #define PHY_ID_KS8041 0x00221510 #define PHY_ID_KS8051 0x00221550 diff --git a/trunk/include/linux/mlx4/device.h b/trunk/include/linux/mlx4/device.h index 6e27fa99e8b9..6d028247f79d 100644 --- a/trunk/include/linux/mlx4/device.h +++ b/trunk/include/linux/mlx4/device.h @@ -98,12 +98,6 @@ enum { MLX4_DEV_CAP_FLAG_SENSE_SUPPORT = 1LL << 55 }; -enum { - MLX4_DEV_CAP_FLAG2_RSS = 1LL << 0, - MLX4_DEV_CAP_FLAG2_RSS_TOP = 1LL << 1, - MLX4_DEV_CAP_FLAG2_RSS_XOR = 1LL << 2 -}; - #define MLX4_ATTR_EXTENDED_PORT_INFO cpu_to_be16(0xff90) enum { @@ -298,13 +292,11 @@ struct mlx4_caps { u32 max_msg_sz; u32 page_size_cap; u64 flags; - u64 flags2; u32 bmme_flags; u32 reserved_lkey; u16 stat_rate_support; u8 port_width_cap[MLX4_MAX_PORTS + 1]; int max_gso_sz; - int max_rss_tbl_sz; int reserved_qps_cnt[MLX4_NUM_QP_REGION]; int reserved_qps; int reserved_qps_base[MLX4_NUM_QP_REGION]; diff --git a/trunk/include/linux/mlx4/qp.h b/trunk/include/linux/mlx4/qp.h index 338388ba260a..96005d75893c 100644 --- a/trunk/include/linux/mlx4/qp.h +++ b/trunk/include/linux/mlx4/qp.h @@ -234,8 +234,7 @@ struct mlx4_wqe_mlx_seg { u8 owner; u8 reserved1[2]; u8 opcode; - __be16 sched_prio; - u8 reserved2; + u8 reserved2[3]; u8 size; /* * [17] VL15 diff --git a/trunk/include/linux/mm.h b/trunk/include/linux/mm.h index 7d5c37f24c63..74aa71bea1e4 100644 --- a/trunk/include/linux/mm.h +++ b/trunk/include/linux/mm.h @@ -896,8 +896,10 @@ int zap_vma_ptes(struct vm_area_struct *vma, unsigned long address, unsigned long size); void zap_page_range(struct vm_area_struct *vma, unsigned long address, unsigned long size, struct zap_details *); -void unmap_vmas(struct mmu_gather *tlb, struct vm_area_struct *start_vma, - unsigned long start, unsigned long end); +void unmap_vmas(struct mmu_gather *tlb, + struct vm_area_struct *start_vma, unsigned long start_addr, + unsigned long end_addr, unsigned long *nr_accounted, + struct zap_details *); /** * mm_walk - callbacks for walk_page_range diff --git a/trunk/include/linux/net.h b/trunk/include/linux/net.h index 2d7510f38934..be60c7f5e145 100644 --- a/trunk/include/linux/net.h +++ b/trunk/include/linux/net.h @@ -250,29 +250,6 @@ extern struct socket *sockfd_lookup(int fd, int *err); #define sockfd_put(sock) fput(sock->file) extern int net_ratelimit(void); -#define net_ratelimited_function(function, ...) \ -do { \ - if (net_ratelimit()) \ - function(__VA_ARGS__); \ -} while (0) - -#define net_emerg_ratelimited(fmt, ...) \ - net_ratelimited_function(pr_emerg, fmt, ##__VA_ARGS__) -#define net_alert_ratelimited(fmt, ...) \ - net_ratelimited_function(pr_alert, fmt, ##__VA_ARGS__) -#define net_crit_ratelimited(fmt, ...) \ - net_ratelimited_function(pr_crit, fmt, ##__VA_ARGS__) -#define net_err_ratelimited(fmt, ...) \ - net_ratelimited_function(pr_err, fmt, ##__VA_ARGS__) -#define net_notice_ratelimited(fmt, ...) \ - net_ratelimited_function(pr_notice, fmt, ##__VA_ARGS__) -#define net_warn_ratelimited(fmt, ...) \ - net_ratelimited_function(pr_warn, fmt, ##__VA_ARGS__) -#define net_info_ratelimited(fmt, ...) \ - net_ratelimited_function(pr_info, fmt, ##__VA_ARGS__) -#define net_dbg_ratelimited(fmt, ...) \ - net_ratelimited_function(pr_debug, fmt, ##__VA_ARGS__) - #define net_random() random32() #define net_srandom(seed) srandom32((__force u32)seed) diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index e7fd468f7126..7f377fb8b527 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -1155,6 +1155,7 @@ struct net_device { struct in_device __rcu *ip_ptr; /* IPv4 specific data */ struct dn_dev __rcu *dn_ptr; /* DECnet specific data */ struct inet6_dev __rcu *ip6_ptr; /* IPv6 specific data */ + void *ec_ptr; /* Econet specific data */ void *ax25_ptr; /* AX.25 specific data */ struct wireless_dev *ieee80211_ptr; /* IEEE 802.11 specific data, assign before registering */ @@ -1425,6 +1426,15 @@ static inline bool netdev_uses_dsa_tags(struct net_device *dev) return 0; } +#ifndef CONFIG_NET_NS +static inline void skb_set_dev(struct sk_buff *skb, struct net_device *dev) +{ + skb->dev = dev; +} +#else /* CONFIG_NET_NS */ +void skb_set_dev(struct sk_buff *skb, struct net_device *dev); +#endif + static inline bool netdev_uses_trailer_tags(struct net_device *dev) { #ifdef CONFIG_NET_DSA_TAG_TRAILER @@ -2142,6 +2152,7 @@ extern struct sk_buff * napi_get_frags(struct napi_struct *napi); extern gro_result_t napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb, gro_result_t ret); +extern struct sk_buff * napi_frags_skb(struct napi_struct *napi); extern gro_result_t napi_gro_frags(struct napi_struct *napi); static inline void napi_free_frags(struct napi_struct *napi) diff --git a/trunk/include/linux/netfilter/ipset/ip_set_ahash.h b/trunk/include/linux/netfilter/ipset/ip_set_ahash.h index b114d35aea5e..289b62d9dd1f 100644 --- a/trunk/include/linux/netfilter/ipset/ip_set_ahash.h +++ b/trunk/include/linux/netfilter/ipset/ip_set_ahash.h @@ -99,22 +99,6 @@ struct ip_set_hash { #endif }; -static size_t -htable_size(u8 hbits) -{ - size_t hsize; - - /* We must fit both into u32 in jhash and size_t */ - if (hbits > 31) - return 0; - hsize = jhash_size(hbits); - if ((((size_t)-1) - sizeof(struct htable))/sizeof(struct hbucket) - < hsize) - return 0; - - return hsize * sizeof(struct hbucket) + sizeof(struct htable); -} - /* Compute htable_bits from the user input parameter hashsize */ static u8 htable_bits(u32 hashsize) diff --git a/trunk/include/linux/netfilter/ipset/ip_set_timeout.h b/trunk/include/linux/netfilter/ipset/ip_set_timeout.h index 41d9cfa08167..47923205a4ad 100644 --- a/trunk/include/linux/netfilter/ipset/ip_set_timeout.h +++ b/trunk/include/linux/netfilter/ipset/ip_set_timeout.h @@ -30,10 +30,6 @@ ip_set_timeout_uget(struct nlattr *tb) { unsigned int timeout = ip_set_get_h32(tb); - /* Normalize to fit into jiffies */ - if (timeout > UINT_MAX/MSEC_PER_SEC) - timeout = UINT_MAX/MSEC_PER_SEC; - /* Userspace supplied TIMEOUT parameter: adjust crazy size */ return timeout == IPSET_NO_TIMEOUT ? IPSET_NO_TIMEOUT - 1 : timeout; } diff --git a/trunk/include/linux/netfilter/xt_HMARK.h b/trunk/include/linux/netfilter/xt_HMARK.h deleted file mode 100644 index abb1650940d2..000000000000 --- a/trunk/include/linux/netfilter/xt_HMARK.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef XT_HMARK_H_ -#define XT_HMARK_H_ - -#include - -enum { - XT_HMARK_SADDR_MASK, - XT_HMARK_DADDR_MASK, - XT_HMARK_SPI, - XT_HMARK_SPI_MASK, - XT_HMARK_SPORT, - XT_HMARK_DPORT, - XT_HMARK_SPORT_MASK, - XT_HMARK_DPORT_MASK, - XT_HMARK_PROTO_MASK, - XT_HMARK_RND, - XT_HMARK_MODULUS, - XT_HMARK_OFFSET, - XT_HMARK_CT, - XT_HMARK_METHOD_L3, - XT_HMARK_METHOD_L3_4, -}; -#define XT_HMARK_FLAG(flag) (1 << flag) - -union hmark_ports { - struct { - __u16 src; - __u16 dst; - } p16; - __u32 v32; -}; - -struct xt_hmark_info { - union nf_inet_addr src_mask; - union nf_inet_addr dst_mask; - union hmark_ports port_mask; - union hmark_ports port_set; - __u32 flags; - __u16 proto_mask; - __u32 hashrnd; - __u32 hmodulus; - __u32 hoffset; /* Mark offset to start from */ -}; - -#endif /* XT_HMARK_H_ */ diff --git a/trunk/include/linux/netfilter/xt_hashlimit.h b/trunk/include/linux/netfilter/xt_hashlimit.h index c42e52f39f8f..b1925b5925e9 100644 --- a/trunk/include/linux/netfilter/xt_hashlimit.h +++ b/trunk/include/linux/netfilter/xt_hashlimit.h @@ -6,11 +6,7 @@ /* timings are in milliseconds. */ #define XT_HASHLIMIT_SCALE 10000 /* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490 - * seconds, or one packet every 59 hours. - */ - -/* packet length accounting is done in 16-byte steps */ -#define XT_HASHLIMIT_BYTE_SHIFT 4 + seconds, or one every 59 hours. */ /* details of this structure hidden by the implementation */ struct xt_hashlimit_htable; @@ -21,13 +17,7 @@ enum { XT_HASHLIMIT_HASH_SIP = 1 << 2, XT_HASHLIMIT_HASH_SPT = 1 << 3, XT_HASHLIMIT_INVERT = 1 << 4, - XT_HASHLIMIT_BYTES = 1 << 5, }; -#ifdef __KERNEL__ -#define XT_HASHLIMIT_ALL (XT_HASHLIMIT_HASH_DIP | XT_HASHLIMIT_HASH_DPT | \ - XT_HASHLIMIT_HASH_SIP | XT_HASHLIMIT_HASH_SPT | \ - XT_HASHLIMIT_INVERT | XT_HASHLIMIT_BYTES) -#endif struct hashlimit_cfg { __u32 mode; /* bitmask of XT_HASHLIMIT_HASH_* */ diff --git a/trunk/include/linux/netfilter_ipv6/ip6_tables.h b/trunk/include/linux/netfilter_ipv6/ip6_tables.h index 08c2cbbaa32b..1bc898b14a80 100644 --- a/trunk/include/linux/netfilter_ipv6/ip6_tables.h +++ b/trunk/include/linux/netfilter_ipv6/ip6_tables.h @@ -298,14 +298,9 @@ ip6t_ext_hdr(u8 nexthdr) (nexthdr == IPPROTO_DSTOPTS); } -enum { - IP6T_FH_F_FRAG = (1 << 0), - IP6T_FH_F_AUTH = (1 << 1), -}; - /* find specified header and get offset to it */ extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, - int target, unsigned short *fragoff, int *fragflg); + int target, unsigned short *fragoff); #ifdef CONFIG_COMPAT #include diff --git a/trunk/include/linux/nl802154.h b/trunk/include/linux/nl802154.h index 5a3db3aa5f17..33d9f5175109 100644 --- a/trunk/include/linux/nl802154.h +++ b/trunk/include/linux/nl802154.h @@ -68,7 +68,6 @@ enum { IEEE802154_ATTR_CHANNEL_PAGE_LIST, IEEE802154_ATTR_PHY_NAME, - IEEE802154_ATTR_DEV_TYPE, __IEEE802154_ATTR_MAX, }; @@ -127,23 +126,4 @@ enum { #define IEEE802154_CMD_MAX (__IEEE802154_CMD_MAX - 1) -enum { - __IEEE802154_DEV_INVALID = -1, - - /* TODO: - * Nowadays three device types supported by this stack at linux-zigbee - * project: WPAN = 0, MONITOR = 1 and SMAC = 2. - * - * Since this stack implementation exists many years, it's definitely - * bad idea to change the assigned values due to they are already used - * by third-party userspace software like: iz-tools, wireshark... - * - * Currently only monitor device is added and initialized by '1' for - * compatibility. - */ - IEEE802154_DEV_MONITOR = 1, - - __IEEE802154_DEV_MAX, -}; - #endif diff --git a/trunk/include/linux/of.h b/trunk/include/linux/of.h index 2ec1083af7ff..fa7fb1d97458 100644 --- a/trunk/include/linux/of.h +++ b/trunk/include/linux/of.h @@ -193,17 +193,6 @@ extern struct device_node *of_get_next_child(const struct device_node *node, for (child = of_get_next_child(parent, NULL); child != NULL; \ child = of_get_next_child(parent, child)) -static inline int of_get_child_count(const struct device_node *np) -{ - struct device_node *child; - int num = 0; - - for_each_child_of_node(np, child) - num++; - - return num; -} - extern struct device_node *of_find_node_with_property( struct device_node *from, const char *prop_name); #define for_each_node_with_property(dn, prop_name) \ @@ -270,37 +259,6 @@ extern void of_detach_node(struct device_node *); #endif #define of_match_ptr(_ptr) (_ptr) - -/* - * struct property *prop; - * const __be32 *p; - * u32 u; - * - * of_property_for_each_u32(np, "propname", prop, p, u) - * printk("U32 value: %x\n", u); - */ -const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, - u32 *pu); -#define of_property_for_each_u32(np, propname, prop, p, u) \ - for (prop = of_find_property(np, propname, NULL), \ - p = of_prop_next_u32(prop, NULL, &u); \ - p; \ - p = of_prop_next_u32(prop, p, &u)) - -/* - * struct property *prop; - * const char *s; - * - * of_property_for_each_string(np, "propname", prop, s) - * printk("String value: %s\n", s); - */ -const char *of_prop_next_string(struct property *prop, const char *cur); -#define of_property_for_each_string(np, propname, prop, s) \ - for (prop = of_find_property(np, propname, NULL), \ - s = of_prop_next_string(prop, NULL); \ - s; \ - s = of_prop_next_string(prop, s)) - #else /* CONFIG_OF */ static inline bool of_have_populated_dt(void) @@ -311,11 +269,6 @@ static inline bool of_have_populated_dt(void) #define for_each_child_of_node(parent, child) \ while (0) -static inline int of_get_child_count(const struct device_node *np) -{ - return 0; -} - static inline int of_device_is_compatible(const struct device_node *device, const char *name) { @@ -396,10 +349,6 @@ static inline int of_machine_is_compatible(const char *compat) #define of_match_ptr(_ptr) NULL #define of_match_node(_matches, _node) NULL -#define of_property_for_each_u32(np, propname, prop, p, u) \ - while (0) -#define of_property_for_each_string(np, propname, prop, s) \ - while (0) #endif /* CONFIG_OF */ /** diff --git a/trunk/include/linux/pci.h b/trunk/include/linux/pci.h index 17b7b5b01b4a..e444f5b49118 100644 --- a/trunk/include/linux/pci.h +++ b/trunk/include/linux/pci.h @@ -375,18 +375,11 @@ struct pci_host_bridge_window { }; struct pci_host_bridge { - struct device dev; + struct list_head list; struct pci_bus *bus; /* root bus */ struct list_head windows; /* pci_host_bridge_windows */ - void (*release_fn)(struct pci_host_bridge *); - void *release_data; }; -#define to_pci_host_bridge(n) container_of(n, struct pci_host_bridge, dev) -void pci_set_host_bridge_release(struct pci_host_bridge *bridge, - void (*release_fn)(struct pci_host_bridge *), - void *release_data); - /* * The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond * to P2P or CardBus bridge windows) go in a table. Additional ones (for diff --git a/trunk/include/linux/phy.h b/trunk/include/linux/phy.h index c291cae8ce32..f092032f1c98 100644 --- a/trunk/include/linux/phy.h +++ b/trunk/include/linux/phy.h @@ -480,6 +480,7 @@ static inline int phy_write(struct phy_device *phydev, u32 regnum, u16 val) return mdiobus_write(phydev->bus, phydev->addr, regnum, val); } +int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id); struct phy_device* get_phy_device(struct mii_bus *bus, int addr); int phy_device_register(struct phy_device *phy); int phy_init_hw(struct phy_device *phydev); diff --git a/trunk/include/linux/pinctrl/consumer.h b/trunk/include/linux/pinctrl/consumer.h index 6dd96fb45482..191e72688481 100644 --- a/trunk/include/linux/pinctrl/consumer.h +++ b/trunk/include/linux/pinctrl/consumer.h @@ -36,9 +36,6 @@ extern struct pinctrl_state * __must_check pinctrl_lookup_state( const char *name); extern int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *s); -extern struct pinctrl * __must_check devm_pinctrl_get(struct device *dev); -extern void devm_pinctrl_put(struct pinctrl *p); - #else /* !CONFIG_PINCTRL */ static inline int pinctrl_request_gpio(unsigned gpio) @@ -82,15 +79,6 @@ static inline int pinctrl_select_state(struct pinctrl *p, return 0; } -static inline struct pinctrl * __must_check devm_pinctrl_get(struct device *dev) -{ - return NULL; -} - -static inline void devm_pinctrl_put(struct pinctrl *p) -{ -} - #endif /* CONFIG_PINCTRL */ static inline struct pinctrl * __must_check pinctrl_get_select( @@ -125,38 +113,6 @@ static inline struct pinctrl * __must_check pinctrl_get_select_default( return pinctrl_get_select(dev, PINCTRL_STATE_DEFAULT); } -static inline struct pinctrl * __must_check devm_pinctrl_get_select( - struct device *dev, const char *name) -{ - struct pinctrl *p; - struct pinctrl_state *s; - int ret; - - p = devm_pinctrl_get(dev); - if (IS_ERR(p)) - return p; - - s = pinctrl_lookup_state(p, name); - if (IS_ERR(s)) { - devm_pinctrl_put(p); - return ERR_PTR(PTR_ERR(s)); - } - - ret = pinctrl_select_state(p, s); - if (ret < 0) { - devm_pinctrl_put(p); - return ERR_PTR(ret); - } - - return p; -} - -static inline struct pinctrl * __must_check devm_pinctrl_get_select_default( - struct device *dev) -{ - return devm_pinctrl_get_select(dev, PINCTRL_STATE_DEFAULT); -} - #ifdef CONFIG_PINCONF extern int pin_config_get(const char *dev_name, const char *name, diff --git a/trunk/include/linux/pinctrl/machine.h b/trunk/include/linux/pinctrl/machine.h index 7d22ab00343f..e4d1de742502 100644 --- a/trunk/include/linux/pinctrl/machine.h +++ b/trunk/include/linux/pinctrl/machine.h @@ -154,7 +154,7 @@ struct pinctrl_map { extern int pinctrl_register_mappings(struct pinctrl_map const *map, unsigned num_maps); -extern void pinctrl_provide_dummies(void); + #else static inline int pinctrl_register_mappings(struct pinctrl_map const *map, @@ -163,8 +163,5 @@ static inline int pinctrl_register_mappings(struct pinctrl_map const *map, return 0; } -static inline void pinctrl_provide_dummies(void) -{ -} -#endif /* !CONFIG_PINCTRL */ +#endif /* !CONFIG_PINMUX */ #endif diff --git a/trunk/include/linux/pinctrl/pinconf.h b/trunk/include/linux/pinctrl/pinconf.h index e7a720104a47..ec431f03362d 100644 --- a/trunk/include/linux/pinctrl/pinconf.h +++ b/trunk/include/linux/pinctrl/pinconf.h @@ -25,6 +25,7 @@ struct seq_file; * @pin_config_get: get the config of a certain pin, if the requested config * is not available on this controller this should return -ENOTSUPP * and if it is available but disabled it should return -EINVAL + * @pin_config_get: get the config of a certain pin * @pin_config_set: configure an individual pin * @pin_config_group_get: get configurations for an entire pin group * @pin_config_group_set: configure all pins in a group @@ -32,8 +33,6 @@ struct seq_file; * per-device info for a certain pin in debugfs * @pin_config_group_dbg_show: optional debugfs display hook that will provide * per-device info for a certain group in debugfs - * @pin_config_config_dbg_show: optional debugfs display hook that will decode - * and display a driver's pin configuration parameter */ struct pinconf_ops { #ifdef CONFIG_GENERIC_PINCONF @@ -57,9 +56,6 @@ struct pinconf_ops { void (*pin_config_group_dbg_show) (struct pinctrl_dev *pctldev, struct seq_file *s, unsigned selector); - void (*pin_config_config_dbg_show) (struct pinctrl_dev *pctldev, - struct seq_file *s, - unsigned long config); }; #endif diff --git a/trunk/include/linux/pinctrl/pinctrl.h b/trunk/include/linux/pinctrl/pinctrl.h index 3b894a668d32..4e9f0788c221 100644 --- a/trunk/include/linux/pinctrl/pinctrl.h +++ b/trunk/include/linux/pinctrl/pinctrl.h @@ -21,11 +21,9 @@ struct device; struct pinctrl_dev; -struct pinctrl_map; struct pinmux_ops; struct pinconf_ops; struct gpio_chip; -struct device_node; /** * struct pinctrl_pin_desc - boards/machines provide information on their @@ -66,24 +64,17 @@ struct pinctrl_gpio_range { /** * struct pinctrl_ops - global pin control operations, to be implemented by * pin controller drivers. - * @get_groups_count: Returns the count of total number of groups registered. + * @list_groups: list the number of selectable named groups available + * in this pinmux driver, the core will begin on 0 and call this + * repeatedly as long as it returns >= 0 to enumerate the groups * @get_group_name: return the group name of the pin group * @get_group_pins: return an array of pins corresponding to a certain * group selector @pins, and the size of the array in @num_pins * @pin_dbg_show: optional debugfs display hook that will provide per-device * info for a certain pin in debugfs - * @dt_node_to_map: parse a device tree "pin configuration node", and create - * mapping table entries for it. These are returned through the @map and - * @num_maps output parameters. This function is optional, and may be - * omitted for pinctrl drivers that do not support device tree. - * @dt_free_map: free mapping table entries created via @dt_node_to_map. The - * top-level @map pointer must be freed, along with any dynamically - * allocated members of the mapping table entries themselves. This - * function is optional, and may be omitted for pinctrl drivers that do - * not support device tree. */ struct pinctrl_ops { - int (*get_groups_count) (struct pinctrl_dev *pctldev); + int (*list_groups) (struct pinctrl_dev *pctldev, unsigned selector); const char *(*get_group_name) (struct pinctrl_dev *pctldev, unsigned selector); int (*get_group_pins) (struct pinctrl_dev *pctldev, @@ -92,11 +83,6 @@ struct pinctrl_ops { unsigned *num_pins); void (*pin_dbg_show) (struct pinctrl_dev *pctldev, struct seq_file *s, unsigned offset); - int (*dt_node_to_map) (struct pinctrl_dev *pctldev, - struct device_node *np_config, - struct pinctrl_map **map, unsigned *num_maps); - void (*dt_free_map) (struct pinctrl_dev *pctldev, - struct pinctrl_map *map, unsigned num_maps); }; /** diff --git a/trunk/include/linux/pinctrl/pinmux.h b/trunk/include/linux/pinctrl/pinmux.h index 1818dcbdd9ab..47e9237edd47 100644 --- a/trunk/include/linux/pinctrl/pinmux.h +++ b/trunk/include/linux/pinctrl/pinmux.h @@ -23,14 +23,15 @@ struct pinctrl_dev; /** * struct pinmux_ops - pinmux operations, to be implemented by pin controller * drivers that support pinmuxing - * @request: called by the core to see if a certain pin can be made + * @request: called by the core to see if a certain pin can be made available * available for muxing. This is called by the core to acquire the pins * before selecting any actual mux setting across a function. The driver * is allowed to answer "no" by returning a negative error code * @free: the reverse function of the request() callback, frees a pin after * being requested - * @get_functions_count: returns number of selectable named functions available - * in this pinmux driver + * @list_functions: list the number of selectable named functions available + * in this pinmux driver, the core will begin on 0 and call this + * repeatedly as long as it returns >= 0 to enumerate mux settings * @get_function_name: return the function name of the muxing selector, * called by the core to figure out which mux setting it shall map a * certain device to @@ -61,7 +62,7 @@ struct pinctrl_dev; struct pinmux_ops { int (*request) (struct pinctrl_dev *pctldev, unsigned offset); int (*free) (struct pinctrl_dev *pctldev, unsigned offset); - int (*get_functions_count) (struct pinctrl_dev *pctldev); + int (*list_functions) (struct pinctrl_dev *pctldev, unsigned selector); const char *(*get_function_name) (struct pinctrl_dev *pctldev, unsigned selector); int (*get_function_groups) (struct pinctrl_dev *pctldev, diff --git a/trunk/include/linux/pkt_sched.h b/trunk/include/linux/pkt_sched.h index 32aef0a439ef..ffe975c3f1d8 100644 --- a/trunk/include/linux/pkt_sched.h +++ b/trunk/include/linux/pkt_sched.h @@ -655,84 +655,4 @@ struct tc_qfq_stats { __u32 lmax; }; -/* CODEL */ - -enum { - TCA_CODEL_UNSPEC, - TCA_CODEL_TARGET, - TCA_CODEL_LIMIT, - TCA_CODEL_INTERVAL, - TCA_CODEL_ECN, - __TCA_CODEL_MAX -}; - -#define TCA_CODEL_MAX (__TCA_CODEL_MAX - 1) - -struct tc_codel_xstats { - __u32 maxpacket; /* largest packet we've seen so far */ - __u32 count; /* how many drops we've done since the last time we - * entered dropping state - */ - __u32 lastcount; /* count at entry to dropping state */ - __u32 ldelay; /* in-queue delay seen by most recently dequeued packet */ - __s32 drop_next; /* time to drop next packet */ - __u32 drop_overlimit; /* number of time max qdisc packet limit was hit */ - __u32 ecn_mark; /* number of packets we ECN marked instead of dropped */ - __u32 dropping; /* are we in dropping state ? */ -}; - -/* FQ_CODEL */ - -enum { - TCA_FQ_CODEL_UNSPEC, - TCA_FQ_CODEL_TARGET, - TCA_FQ_CODEL_LIMIT, - TCA_FQ_CODEL_INTERVAL, - TCA_FQ_CODEL_ECN, - TCA_FQ_CODEL_FLOWS, - TCA_FQ_CODEL_QUANTUM, - __TCA_FQ_CODEL_MAX -}; - -#define TCA_FQ_CODEL_MAX (__TCA_FQ_CODEL_MAX - 1) - -enum { - TCA_FQ_CODEL_XSTATS_QDISC, - TCA_FQ_CODEL_XSTATS_CLASS, -}; - -struct tc_fq_codel_qd_stats { - __u32 maxpacket; /* largest packet we've seen so far */ - __u32 drop_overlimit; /* number of time max qdisc - * packet limit was hit - */ - __u32 ecn_mark; /* number of packets we ECN marked - * instead of being dropped - */ - __u32 new_flow_count; /* number of time packets - * created a 'new flow' - */ - __u32 new_flows_len; /* count of flows in new list */ - __u32 old_flows_len; /* count of flows in old list */ -}; - -struct tc_fq_codel_cl_stats { - __s32 deficit; - __u32 ldelay; /* in-queue delay seen by most recently - * dequeued packet - */ - __u32 count; - __u32 lastcount; - __u32 dropping; - __s32 drop_next; -}; - -struct tc_fq_codel_xstats { - __u32 type; - union { - struct tc_fq_codel_qd_stats qdisc_stats; - struct tc_fq_codel_cl_stats class_stats; - }; -}; - #endif diff --git a/trunk/include/linux/prctl.h b/trunk/include/linux/prctl.h index 78b76e24cc7e..e0cfec2490aa 100644 --- a/trunk/include/linux/prctl.h +++ b/trunk/include/linux/prctl.h @@ -124,19 +124,4 @@ #define PR_SET_CHILD_SUBREAPER 36 #define PR_GET_CHILD_SUBREAPER 37 -/* - * If no_new_privs is set, then operations that grant new privileges (i.e. - * execve) will either fail or not grant them. This affects suid/sgid, - * file capabilities, and LSMs. - * - * Operations that merely manipulate or drop existing privileges (setresuid, - * capset, etc.) will still work. Drop those privileges if you want them gone. - * - * Changing LSM security domain is considered a new privilege. So, for example, - * asking selinux for a specific new context (e.g. with runcon) will result - * in execve returning -EPERM. - */ -#define PR_SET_NO_NEW_PRIVS 38 -#define PR_GET_NO_NEW_PRIVS 39 - #endif /* _LINUX_PRCTL_H */ diff --git a/trunk/include/linux/ptrace.h b/trunk/include/linux/ptrace.h index 597e4fdb97fe..5c719627c2aa 100644 --- a/trunk/include/linux/ptrace.h +++ b/trunk/include/linux/ptrace.h @@ -58,7 +58,6 @@ #define PTRACE_EVENT_EXEC 4 #define PTRACE_EVENT_VFORK_DONE 5 #define PTRACE_EVENT_EXIT 6 -#define PTRACE_EVENT_SECCOMP 7 /* Extended result codes which enabled by means other than options. */ #define PTRACE_EVENT_STOP 128 @@ -70,9 +69,8 @@ #define PTRACE_O_TRACEEXEC (1 << PTRACE_EVENT_EXEC) #define PTRACE_O_TRACEVFORKDONE (1 << PTRACE_EVENT_VFORK_DONE) #define PTRACE_O_TRACEEXIT (1 << PTRACE_EVENT_EXIT) -#define PTRACE_O_TRACESECCOMP (1 << PTRACE_EVENT_SECCOMP) -#define PTRACE_O_MASK 0x000000ff +#define PTRACE_O_MASK 0x0000007f #include @@ -100,7 +98,6 @@ #define PT_TRACE_EXEC PT_EVENT_FLAG(PTRACE_EVENT_EXEC) #define PT_TRACE_VFORK_DONE PT_EVENT_FLAG(PTRACE_EVENT_VFORK_DONE) #define PT_TRACE_EXIT PT_EVENT_FLAG(PTRACE_EVENT_EXIT) -#define PT_TRACE_SECCOMP PT_EVENT_FLAG(PTRACE_EVENT_SECCOMP) /* single stepping state bits (used on ARM and PA-RISC) */ #define PT_SINGLESTEP_BIT 31 diff --git a/trunk/include/linux/rculist.h b/trunk/include/linux/rculist.h index e0f0fab20415..d079290843a9 100644 --- a/trunk/include/linux/rculist.h +++ b/trunk/include/linux/rculist.h @@ -30,7 +30,6 @@ * This is only for internal list manipulation where we know * the prev/next entries already! */ -#ifndef CONFIG_DEBUG_LIST static inline void __list_add_rcu(struct list_head *new, struct list_head *prev, struct list_head *next) { @@ -39,10 +38,6 @@ static inline void __list_add_rcu(struct list_head *new, rcu_assign_pointer(list_next_rcu(prev), new); next->prev = new; } -#else -extern void __list_add_rcu(struct list_head *new, - struct list_head *prev, struct list_head *next); -#endif /** * list_add_rcu - add a new entry to rcu-protected list @@ -113,7 +108,7 @@ static inline void list_add_tail_rcu(struct list_head *new, */ static inline void list_del_rcu(struct list_head *entry) { - __list_del_entry(entry); + __list_del(entry->prev, entry->next); entry->prev = LIST_POISON2; } @@ -233,43 +228,18 @@ static inline void list_splice_init_rcu(struct list_head *list, }) /** - * Where are list_empty_rcu() and list_first_entry_rcu()? - * - * Implementing those functions following their counterparts list_empty() and - * list_first_entry() is not advisable because they lead to subtle race - * conditions as the following snippet shows: - * - * if (!list_empty_rcu(mylist)) { - * struct foo *bar = list_first_entry_rcu(mylist, struct foo, list_member); - * do_something(bar); - * } - * - * The list may not be empty when list_empty_rcu checks it, but it may be when - * list_first_entry_rcu rereads the ->next pointer. - * - * Rereading the ->next pointer is not a problem for list_empty() and - * list_first_entry() because they would be protected by a lock that blocks - * writers. - * - * See list_first_or_null_rcu for an alternative. - */ - -/** - * list_first_or_null_rcu - get the first element from a list + * list_first_entry_rcu - get the first element from a list * @ptr: the list head to take the element from. * @type: the type of the struct this is embedded in. * @member: the name of the list_struct within the struct. * - * Note that if the list is empty, it returns NULL. + * Note, that list is expected to be not empty. * * This primitive may safely run concurrently with the _rcu list-mutation * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock(). */ -#define list_first_or_null_rcu(ptr, type, member) \ - ({struct list_head *__ptr = (ptr); \ - struct list_head __rcu *__next = list_next_rcu(__ptr); \ - likely(__ptr != __next) ? container_of(__next, type, member) : NULL; \ - }) +#define list_first_entry_rcu(ptr, type, member) \ + list_entry_rcu((ptr)->next, type, member) /** * list_for_each_entry_rcu - iterate over rcu list of given type diff --git a/trunk/include/linux/rcupdate.h b/trunk/include/linux/rcupdate.h index 26d1a47591f1..20fb776a1d4a 100644 --- a/trunk/include/linux/rcupdate.h +++ b/trunk/include/linux/rcupdate.h @@ -184,14 +184,12 @@ static inline int rcu_preempt_depth(void) /* Internal to kernel */ extern void rcu_sched_qs(int cpu); extern void rcu_bh_qs(int cpu); -extern void rcu_preempt_note_context_switch(void); extern void rcu_check_callbacks(int cpu, int user); struct notifier_block; extern void rcu_idle_enter(void); extern void rcu_idle_exit(void); extern void rcu_irq_enter(void); extern void rcu_irq_exit(void); -extern void exit_rcu(void); /** * RCU_NONIDLE - Indicate idle-loop code that needs RCU readers @@ -924,21 +922,6 @@ void __kfree_rcu(struct rcu_head *head, unsigned long offset) kfree_call_rcu(head, (rcu_callback)offset); } -/* - * Does the specified offset indicate that the corresponding rcu_head - * structure can be handled by kfree_rcu()? - */ -#define __is_kfree_rcu_offset(offset) ((offset) < 4096) - -/* - * Helper macro for kfree_rcu() to prevent argument-expansion eyestrain. - */ -#define __kfree_rcu(head, offset) \ - do { \ - BUILD_BUG_ON(!__is_kfree_rcu_offset(offset)); \ - call_rcu(head, (void (*)(struct rcu_head *))(unsigned long)(offset)); \ - } while (0) - /** * kfree_rcu() - kfree an object after a grace period. * @ptr: pointer to kfree @@ -961,9 +944,6 @@ void __kfree_rcu(struct rcu_head *head, unsigned long offset) * * Note that the allowable offset might decrease in the future, for example, * to allow something like kmem_cache_free_rcu(). - * - * The BUILD_BUG_ON check must not involve any function calls, hence the - * checks are done in macros here. */ #define kfree_rcu(ptr, rcu_head) \ __kfree_rcu(&((ptr)->rcu_head), offsetof(typeof(*(ptr)), rcu_head)) diff --git a/trunk/include/linux/rcutiny.h b/trunk/include/linux/rcutiny.h index adb5e5a38cae..e93df77176d1 100644 --- a/trunk/include/linux/rcutiny.h +++ b/trunk/include/linux/rcutiny.h @@ -87,6 +87,14 @@ static inline void kfree_call_rcu(struct rcu_head *head, #ifdef CONFIG_TINY_RCU +static inline void rcu_preempt_note_context_switch(void) +{ +} + +static inline void exit_rcu(void) +{ +} + static inline int rcu_needs_cpu(int cpu) { return 0; @@ -94,6 +102,8 @@ static inline int rcu_needs_cpu(int cpu) #else /* #ifdef CONFIG_TINY_RCU */ +void rcu_preempt_note_context_switch(void); +extern void exit_rcu(void); int rcu_preempt_needs_cpu(void); static inline int rcu_needs_cpu(int cpu) @@ -106,6 +116,7 @@ static inline int rcu_needs_cpu(int cpu) static inline void rcu_note_context_switch(int cpu) { rcu_sched_qs(cpu); + rcu_preempt_note_context_switch(); } /* diff --git a/trunk/include/linux/rcutree.h b/trunk/include/linux/rcutree.h index 3c6083cde4fc..e8ee5dd0854c 100644 --- a/trunk/include/linux/rcutree.h +++ b/trunk/include/linux/rcutree.h @@ -45,6 +45,18 @@ static inline void rcu_virt_note_context_switch(int cpu) rcu_note_context_switch(cpu); } +#ifdef CONFIG_TREE_PREEMPT_RCU + +extern void exit_rcu(void); + +#else /* #ifdef CONFIG_TREE_PREEMPT_RCU */ + +static inline void exit_rcu(void) +{ +} + +#endif /* #else #ifdef CONFIG_TREE_PREEMPT_RCU */ + extern void synchronize_rcu_bh(void); extern void synchronize_sched_expedited(void); extern void synchronize_rcu_expedited(void); @@ -86,6 +98,13 @@ extern void rcu_force_quiescent_state(void); extern void rcu_bh_force_quiescent_state(void); extern void rcu_sched_force_quiescent_state(void); +/* A context switch is a grace period for RCU-sched and RCU-bh. */ +static inline int rcu_blocking_is_gp(void) +{ + might_sleep(); /* Check for RCU read-side critical section. */ + return num_online_cpus() == 1; +} + extern void rcu_scheduler_starting(void); extern int rcu_scheduler_active __read_mostly; diff --git a/trunk/include/linux/regmap.h b/trunk/include/linux/regmap.h index 56af22ec9aba..a90abb6bfa64 100644 --- a/trunk/include/linux/regmap.h +++ b/trunk/include/linux/regmap.h @@ -46,13 +46,7 @@ struct reg_default { /** * Configuration for the register map of a device. * - * @name: Optional name of the regmap. Useful when a device has multiple - * register regions. - * * @reg_bits: Number of bits in a register address, mandatory. - * @reg_stride: The register address stride. Valid register addresses are a - * multiple of this value. If set to 0, a value of 1 will be - * used. * @pad_bits: Number of bits of padding between register and value. * @val_bits: Number of bits in a register value, mandatory. * @@ -76,9 +70,6 @@ struct reg_default { * @write_flag_mask: Mask to be set in the top byte of the register when doing * a write. If both read_flag_mask and write_flag_mask are * empty the regmap_bus default masks are used. - * @use_single_rw: If set, converts the bulk read and write operations into - * a series of single read and write operations. This is useful - * for device that does not support bulk read and write. * * @cache_type: The actual cache type. * @reg_defaults_raw: Power on reset values for registers (for use with @@ -86,10 +77,7 @@ struct reg_default { * @num_reg_defaults_raw: Number of elements in reg_defaults_raw. */ struct regmap_config { - const char *name; - int reg_bits; - int reg_stride; int pad_bits; int val_bits; @@ -107,25 +95,20 @@ struct regmap_config { u8 read_flag_mask; u8 write_flag_mask; - - bool use_single_rw; }; -typedef int (*regmap_hw_write)(void *context, const void *data, +typedef int (*regmap_hw_write)(struct device *dev, const void *data, size_t count); -typedef int (*regmap_hw_gather_write)(void *context, +typedef int (*regmap_hw_gather_write)(struct device *dev, const void *reg, size_t reg_len, const void *val, size_t val_len); -typedef int (*regmap_hw_read)(void *context, +typedef int (*regmap_hw_read)(struct device *dev, const void *reg_buf, size_t reg_size, void *val_buf, size_t val_size); -typedef void (*regmap_hw_free_context)(void *context); /** * Description of a hardware bus for the register map infrastructure. * - * @fast_io: Register IO is fast. Use a spinlock instead of a mutex - * to perform locking. * @write: Write operation. * @gather_write: Write operation with split register/value, return -ENOTSUPP * if not implemented on a given device. @@ -135,42 +118,31 @@ typedef void (*regmap_hw_free_context)(void *context); * a read. */ struct regmap_bus { - bool fast_io; regmap_hw_write write; regmap_hw_gather_write gather_write; regmap_hw_read read; - regmap_hw_free_context free_context; u8 read_flag_mask; }; struct regmap *regmap_init(struct device *dev, const struct regmap_bus *bus, - void *bus_context, const struct regmap_config *config); struct regmap *regmap_init_i2c(struct i2c_client *i2c, const struct regmap_config *config); struct regmap *regmap_init_spi(struct spi_device *dev, const struct regmap_config *config); -struct regmap *regmap_init_mmio(struct device *dev, - void __iomem *regs, - const struct regmap_config *config); struct regmap *devm_regmap_init(struct device *dev, const struct regmap_bus *bus, - void *bus_context, const struct regmap_config *config); struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c, const struct regmap_config *config); struct regmap *devm_regmap_init_spi(struct spi_device *dev, const struct regmap_config *config); -struct regmap *devm_regmap_init_mmio(struct device *dev, - void __iomem *regs, - const struct regmap_config *config); void regmap_exit(struct regmap *map); int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config); -struct regmap *dev_get_regmap(struct device *dev, const char *name); int regmap_write(struct regmap *map, unsigned int reg, unsigned int val); int regmap_raw_write(struct regmap *map, unsigned int reg, const void *val, size_t val_len); @@ -219,7 +191,6 @@ struct regmap_irq { * @status_base: Base status register address. * @mask_base: Base mask register address. * @ack_base: Base ack address. If zero then the chip is clear on read. - * @irq_reg_stride: Stride to use for chips where registers are not contiguous. * * @num_regs: Number of registers in each control bank. * @irqs: Descriptors for individual IRQs. Interrupt numbers are @@ -232,7 +203,6 @@ struct regmap_irq_chip { unsigned int status_base; unsigned int mask_base; unsigned int ack_base; - unsigned int irq_reg_stride; int num_regs; @@ -247,7 +217,6 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, struct regmap_irq_chip_data **data); void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *data); int regmap_irq_chip_get_base(struct regmap_irq_chip_data *data); -int regmap_irq_get_virq(struct regmap_irq_chip_data *data, int irq); #else @@ -358,13 +327,6 @@ static inline int regmap_register_patch(struct regmap *map, return -EINVAL; } -static inline struct regmap *dev_get_regmap(struct device *dev, - const char *name) -{ - WARN_ONCE(1, "regmap API is disabled"); - return NULL; -} - #endif #endif diff --git a/trunk/include/linux/regulator/driver.h b/trunk/include/linux/regulator/driver.h index b0432cc2b169..fa8b55b8191c 100644 --- a/trunk/include/linux/regulator/driver.h +++ b/trunk/include/linux/regulator/driver.h @@ -19,7 +19,6 @@ #include #include -struct regmap; struct regulator_dev; struct regulator_init_data; @@ -46,7 +45,6 @@ enum regulator_status { * The driver should select the voltage closest to min_uV. * @set_voltage_sel: Set the voltage for the regulator using the specified * selector. - * @map_voltage: Convert a voltage into a selector * @get_voltage: Return the currently configured voltage for the regulator. * @get_voltage_sel: Return the currently configured voltage selector for the * regulator. @@ -92,7 +90,6 @@ struct regulator_ops { /* get/set regulator voltage */ int (*set_voltage) (struct regulator_dev *, int min_uV, int max_uV, unsigned *selector); - int (*map_voltage)(struct regulator_dev *, int min_uV, int max_uV); int (*set_voltage_sel) (struct regulator_dev *, unsigned selector); int (*get_voltage) (struct regulator_dev *); int (*get_voltage_sel) (struct regulator_dev *); @@ -151,30 +148,19 @@ enum regulator_type { }; /** - * struct regulator_desc - Static regulator descriptor + * struct regulator_desc - Regulator descriptor * - * Each regulator registered with the core is described with a - * structure of this type and a struct regulator_config. This - * structure contains the non-varying parts of the regulator - * description. + * Each regulator registered with the core is described with a structure of + * this type. * * @name: Identifying name for the regulator. * @supply_name: Identifying the regulator supply * @id: Numerical identifier for the regulator. + * @n_voltages: Number of selectors available for ops.list_voltage(). * @ops: Regulator operations table. * @irq: Interrupt number for the regulator. * @type: Indicates if the regulator is a voltage or current regulator. * @owner: Module providing the regulator, used for refcounting. - * - * @n_voltages: Number of selectors available for ops.list_voltage(). - * - * @min_uV: Voltage given by the lowest selector (if linear mapping) - * @uV_step: Voltage increase with each selector (if linear mapping) - * - * @vsel_reg: Register for selector when using regulator_regmap_X_voltage_ - * @vsel_mask: Mask for register bitfield used for selector - * @enable_reg: Register for control when using regmap enable/disable ops - * @enable_mask: Mask for control when using regmap enable/disable ops */ struct regulator_desc { const char *name; @@ -185,36 +171,6 @@ struct regulator_desc { int irq; enum regulator_type type; struct module *owner; - - unsigned int min_uV; - unsigned int uV_step; - - unsigned int vsel_reg; - unsigned int vsel_mask; - unsigned int enable_reg; - unsigned int enable_mask; -}; - -/** - * struct regulator_config - Dynamic regulator descriptor - * - * Each regulator registered with the core is described with a - * structure of this type and a struct regulator_desc. This structure - * contains the runtime variable parts of the regulator description. - * - * @dev: struct device for the regulator - * @init_data: platform provided init data, passed through by driver - * @driver_data: private regulator data - * @of_node: OpenFirmware node to parse for device tree bindings (may be - * NULL). - * @regmap: regmap to use for core regmap helpers - */ -struct regulator_config { - struct device *dev; - const struct regulator_init_data *init_data; - void *driver_data; - struct device_node *of_node; - struct regmap *regmap; }; /* @@ -228,7 +184,7 @@ struct regulator_config { * no other direct access). */ struct regulator_dev { - const struct regulator_desc *desc; + struct regulator_desc *desc; int exclusive; u32 use_count; u32 open_count; @@ -245,7 +201,6 @@ struct regulator_dev { struct device dev; struct regulation_constraints *constraints; struct regulator *supply; /* for tree */ - struct regmap *regmap; struct delayed_work disable_work; int deferred_disables; @@ -255,9 +210,9 @@ struct regulator_dev { struct dentry *debugfs; }; -struct regulator_dev * -regulator_register(const struct regulator_desc *regulator_desc, - const struct regulator_config *config); +struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, + struct device *dev, const struct regulator_init_data *init_data, + void *driver_data, struct device_node *of_node); void regulator_unregister(struct regulator_dev *rdev); int regulator_notifier_call_chain(struct regulator_dev *rdev, @@ -269,18 +224,6 @@ int rdev_get_id(struct regulator_dev *rdev); int regulator_mode_to_status(unsigned int); -int regulator_list_voltage_linear(struct regulator_dev *rdev, - unsigned int selector); -int regulator_map_voltage_linear(struct regulator_dev *rdev, - int min_uV, int max_uV); -int regulator_map_voltage_iterate(struct regulator_dev *rdev, - int min_uV, int max_uV); -int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev); -int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel); -int regulator_is_enabled_regmap(struct regulator_dev *rdev); -int regulator_enable_regmap(struct regulator_dev *rdev); -int regulator_disable_regmap(struct regulator_dev *rdev); - void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data); #endif diff --git a/trunk/include/linux/regulator/fixed.h b/trunk/include/linux/regulator/fixed.h index f83f7440b488..936a7d8c11a9 100644 --- a/trunk/include/linux/regulator/fixed.h +++ b/trunk/include/linux/regulator/fixed.h @@ -26,12 +26,6 @@ struct regulator_init_data; * @gpio: GPIO to use for enable control * set to -EINVAL if not used * @startup_delay: Start-up time in microseconds - * @gpio_is_open_drain: Gpio pin is open drain or normal type. - * If it is open drain type then HIGH will be set - * through PULL-UP with setting gpio as input - * and low will be set as gpio-output with driven - * to low. For non-open-drain case, the gpio will - * will be in output and drive to low/high accordingly. * @enable_high: Polarity of enable GPIO * 1 = Active high, 0 = Active low * @enabled_at_boot: Whether regulator has been enabled at @@ -49,7 +43,6 @@ struct fixed_voltage_config { int microvolts; int gpio; unsigned startup_delay; - unsigned gpio_is_open_drain:1; unsigned enable_high:1; unsigned enabled_at_boot:1; struct regulator_init_data *init_data; diff --git a/trunk/include/linux/regulator/of_regulator.h b/trunk/include/linux/regulator/of_regulator.h index f9217965aaa3..769704f296e5 100644 --- a/trunk/include/linux/regulator/of_regulator.h +++ b/trunk/include/linux/regulator/of_regulator.h @@ -6,20 +6,10 @@ #ifndef __LINUX_OF_REG_H #define __LINUX_OF_REG_H -struct of_regulator_match { - const char *name; - void *driver_data; - struct regulator_init_data *init_data; - struct device_node *of_node; -}; - #if defined(CONFIG_OF) extern struct regulator_init_data *of_get_regulator_init_data(struct device *dev, struct device_node *node); -extern int of_regulator_match(struct device *dev, struct device_node *node, - struct of_regulator_match *matches, - unsigned int num_matches); #else static inline struct regulator_init_data *of_get_regulator_init_data(struct device *dev, @@ -27,14 +17,6 @@ static inline struct regulator_init_data { return NULL; } - -static inline int of_regulator_match(struct device *dev, - struct device_node *node, - struct of_regulator_match *matches, - unsigned int num_matches) -{ - return 0; -} #endif /* CONFIG_OF */ #endif /* __LINUX_OF_REG_H */ diff --git a/trunk/include/linux/regulator/tps62360.h b/trunk/include/linux/regulator/tps62360.h index a4c49394c497..6a5c1b2c751e 100644 --- a/trunk/include/linux/regulator/tps62360.h +++ b/trunk/include/linux/regulator/tps62360.h @@ -26,10 +26,13 @@ #ifndef __LINUX_REGULATOR_TPS62360_H #define __LINUX_REGULATOR_TPS62360_H +#include + /* * struct tps62360_regulator_platform_data - tps62360 regulator platform data. * * @reg_init_data: The regulator init data. + * @en_force_pwm: Enable force pwm or not. * @en_discharge: Enable discharge the output capacitor via internal * register. * @en_internal_pulldn: internal pull down enable or not. @@ -41,7 +44,8 @@ * @vsel1_def_state: Default state of vsel1. 1 if it is high else 0. */ struct tps62360_regulator_platform_data { - struct regulator_init_data *reg_init_data; + struct regulator_init_data reg_init_data; + bool en_force_pwm; bool en_discharge; bool en_internal_pulldn; int vsel0_gpio; diff --git a/trunk/include/linux/regulator/tps65090-regulator.h b/trunk/include/linux/regulator/tps65090-regulator.h deleted file mode 100644 index 0fa04b64db3e..000000000000 --- a/trunk/include/linux/regulator/tps65090-regulator.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Regulator driver interface for TI TPS65090 PMIC family - * - * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. - - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __REGULATOR_TPS65090_H -#define __REGULATOR_TPS65090_H - -#include - -#define tps65090_rails(_name) "tps65090_"#_name - -enum { - TPS65090_ID_DCDC1, - TPS65090_ID_DCDC2, - TPS65090_ID_DCDC3, - TPS65090_ID_FET1, - TPS65090_ID_FET2, - TPS65090_ID_FET3, - TPS65090_ID_FET4, - TPS65090_ID_FET5, - TPS65090_ID_FET6, - TPS65090_ID_FET7, -}; - -/* - * struct tps65090_regulator_platform_data - * - * @regulator: The regulator init data. - * @slew_rate_uV_per_us: Slew rate microvolt per microsec. - */ - -struct tps65090_regulator_platform_data { - struct regulator_init_data regulator; -}; - -#endif /* __REGULATOR_TPS65090_H */ diff --git a/trunk/include/linux/rndis.h b/trunk/include/linux/rndis.h deleted file mode 100644 index 0c8dc7195cdb..000000000000 --- a/trunk/include/linux/rndis.h +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Remote Network Driver Interface Specification (RNDIS) - * definitions of the magic numbers used by this protocol - */ - -/* Remote NDIS Versions */ -#define RNDIS_MAJOR_VERSION 0x00000001 -#define RNDIS_MINOR_VERSION 0x00000000 - -/* Device Flags */ -#define RNDIS_DF_CONNECTIONLESS 0x00000001U -#define RNDIS_DF_CONNECTION_ORIENTED 0x00000002U -#define RNDIS_DF_RAW_DATA 0x00000004U - -/* - * Codes for "msg_type" field of rndis messages; - * only the data channel uses packet messages (maybe batched); - * everything else goes on the control channel. - */ -#define RNDIS_MSG_COMPLETION 0x80000000 -#define RNDIS_MSG_PACKET 0x00000001 /* 1-N packets */ -#define RNDIS_MSG_INIT 0x00000002 -#define RNDIS_MSG_INIT_C (RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION) -#define RNDIS_MSG_HALT 0x00000003 -#define RNDIS_MSG_QUERY 0x00000004 -#define RNDIS_MSG_QUERY_C (RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION) -#define RNDIS_MSG_SET 0x00000005 -#define RNDIS_MSG_SET_C (RNDIS_MSG_SET|RNDIS_MSG_COMPLETION) -#define RNDIS_MSG_RESET 0x00000006 -#define RNDIS_MSG_RESET_C (RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION) -#define RNDIS_MSG_INDICATE 0x00000007 -#define RNDIS_MSG_KEEPALIVE 0x00000008 -#define RNDIS_MSG_KEEPALIVE_C (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION) -/* - * Reserved message type for private communication between lower-layer host - * driver and remote device, if necessary. - */ -#define RNDIS_MSG_BUS 0xff000001 - -/* codes for "status" field of completion messages */ -#define RNDIS_STATUS_SUCCESS 0x00000000 -#define RNDIS_STATUS_PENDING 0x00000103 - -/* Status codes */ -#define RNDIS_STATUS_NOT_RECOGNIZED 0x00010001 -#define RNDIS_STATUS_NOT_COPIED 0x00010002 -#define RNDIS_STATUS_NOT_ACCEPTED 0x00010003 -#define RNDIS_STATUS_CALL_ACTIVE 0x00010007 - -#define RNDIS_STATUS_ONLINE 0x40010003 -#define RNDIS_STATUS_RESET_START 0x40010004 -#define RNDIS_STATUS_RESET_END 0x40010005 -#define RNDIS_STATUS_RING_STATUS 0x40010006 -#define RNDIS_STATUS_CLOSED 0x40010007 -#define RNDIS_STATUS_WAN_LINE_UP 0x40010008 -#define RNDIS_STATUS_WAN_LINE_DOWN 0x40010009 -#define RNDIS_STATUS_WAN_FRAGMENT 0x4001000A -#define RNDIS_STATUS_MEDIA_CONNECT 0x4001000B -#define RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000C -#define RNDIS_STATUS_HARDWARE_LINE_UP 0x4001000D -#define RNDIS_STATUS_HARDWARE_LINE_DOWN 0x4001000E -#define RNDIS_STATUS_INTERFACE_UP 0x4001000F -#define RNDIS_STATUS_INTERFACE_DOWN 0x40010010 -#define RNDIS_STATUS_MEDIA_BUSY 0x40010011 -#define RNDIS_STATUS_MEDIA_SPECIFIC_INDICATION 0x40010012 -#define RNDIS_STATUS_WW_INDICATION RDIA_SPECIFIC_INDICATION -#define RNDIS_STATUS_LINK_SPEED_CHANGE 0x40010013L - -#define RNDIS_STATUS_NOT_RESETTABLE 0x80010001 -#define RNDIS_STATUS_SOFT_ERRORS 0x80010003 -#define RNDIS_STATUS_HARD_ERRORS 0x80010004 -#define RNDIS_STATUS_BUFFER_OVERFLOW 0x80000005 - -#define RNDIS_STATUS_FAILURE 0xC0000001 -#define RNDIS_STATUS_RESOURCES 0xC000009A -#define RNDIS_STATUS_NOT_SUPPORTED 0xc00000BB -#define RNDIS_STATUS_CLOSING 0xC0010002 -#define RNDIS_STATUS_BAD_VERSION 0xC0010004 -#define RNDIS_STATUS_BAD_CHARACTERISTICS 0xC0010005 -#define RNDIS_STATUS_ADAPTER_NOT_FOUND 0xC0010006 -#define RNDIS_STATUS_OPEN_FAILED 0xC0010007 -#define RNDIS_STATUS_DEVICE_FAILED 0xC0010008 -#define RNDIS_STATUS_MULTICAST_FULL 0xC0010009 -#define RNDIS_STATUS_MULTICAST_EXISTS 0xC001000A -#define RNDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B -#define RNDIS_STATUS_REQUEST_ABORTED 0xC001000C -#define RNDIS_STATUS_RESET_IN_PROGRESS 0xC001000D -#define RNDIS_STATUS_CLOSING_INDICATING 0xC001000E -#define RNDIS_STATUS_INVALID_PACKET 0xC001000F -#define RNDIS_STATUS_OPEN_LIST_FULL 0xC0010010 -#define RNDIS_STATUS_ADAPTER_NOT_READY 0xC0010011 -#define RNDIS_STATUS_ADAPTER_NOT_OPEN 0xC0010012 -#define RNDIS_STATUS_NOT_INDICATING 0xC0010013 -#define RNDIS_STATUS_INVALID_LENGTH 0xC0010014 -#define RNDIS_STATUS_INVALID_DATA 0xC0010015 -#define RNDIS_STATUS_BUFFER_TOO_SHORT 0xC0010016 -#define RNDIS_STATUS_INVALID_OID 0xC0010017 -#define RNDIS_STATUS_ADAPTER_REMOVED 0xC0010018 -#define RNDIS_STATUS_UNSUPPORTED_MEDIA 0xC0010019 -#define RNDIS_STATUS_GROUP_ADDRESS_IN_USE 0xC001001A -#define RNDIS_STATUS_FILE_NOT_FOUND 0xC001001B -#define RNDIS_STATUS_ERROR_READING_FILE 0xC001001C -#define RNDIS_STATUS_ALREADY_MAPPED 0xC001001D -#define RNDIS_STATUS_RESOURCE_CONFLICT 0xC001001E -#define RNDIS_STATUS_NO_CABLE 0xC001001F - -#define RNDIS_STATUS_INVALID_SAP 0xC0010020 -#define RNDIS_STATUS_SAP_IN_USE 0xC0010021 -#define RNDIS_STATUS_INVALID_ADDRESS 0xC0010022 -#define RNDIS_STATUS_VC_NOT_ACTIVATED 0xC0010023 -#define RNDIS_STATUS_DEST_OUT_OF_ORDER 0xC0010024 -#define RNDIS_STATUS_VC_NOT_AVAILABLE 0xC0010025 -#define RNDIS_STATUS_CELLRATE_NOT_AVAILABLE 0xC0010026 -#define RNDIS_STATUS_INCOMPATABLE_QOS 0xC0010027 -#define RNDIS_STATUS_AAL_PARAMS_UNSUPPORTED 0xC0010028 -#define RNDIS_STATUS_NO_ROUTE_TO_DESTINATION 0xC0010029 - -#define RNDIS_STATUS_TOKEN_RING_OPEN_ERROR 0xC0011000 - -/* codes for RNDIS_OID_GEN_PHYSICAL_MEDIUM */ -#define RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED 0x00000000 -#define RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN 0x00000001 -#define RNDIS_PHYSICAL_MEDIUM_CABLE_MODEM 0x00000002 -#define RNDIS_PHYSICAL_MEDIUM_PHONE_LINE 0x00000003 -#define RNDIS_PHYSICAL_MEDIUM_POWER_LINE 0x00000004 -#define RNDIS_PHYSICAL_MEDIUM_DSL 0x00000005 -#define RNDIS_PHYSICAL_MEDIUM_FIBRE_CHANNEL 0x00000006 -#define RNDIS_PHYSICAL_MEDIUM_1394 0x00000007 -#define RNDIS_PHYSICAL_MEDIUM_WIRELESS_WAN 0x00000008 -#define RNDIS_PHYSICAL_MEDIUM_MAX 0x00000009 - -/* Remote NDIS medium types. */ -#define RNDIS_MEDIUM_UNSPECIFIED 0x00000000 -#define RNDIS_MEDIUM_802_3 0x00000000 -#define RNDIS_MEDIUM_802_5 0x00000001 -#define RNDIS_MEDIUM_FDDI 0x00000002 -#define RNDIS_MEDIUM_WAN 0x00000003 -#define RNDIS_MEDIUM_LOCAL_TALK 0x00000004 -#define RNDIS_MEDIUM_ARCNET_RAW 0x00000006 -#define RNDIS_MEDIUM_ARCNET_878_2 0x00000007 -#define RNDIS_MEDIUM_ATM 0x00000008 -#define RNDIS_MEDIUM_WIRELESS_LAN 0x00000009 -#define RNDIS_MEDIUM_IRDA 0x0000000A -#define RNDIS_MEDIUM_BPC 0x0000000B -#define RNDIS_MEDIUM_CO_WAN 0x0000000C -#define RNDIS_MEDIUM_1394 0x0000000D -/* Not a real medium, defined as an upper-bound */ -#define RNDIS_MEDIUM_MAX 0x0000000E - -/* Remote NDIS medium connection states. */ -#define RNDIS_MEDIA_STATE_CONNECTED 0x00000000 -#define RNDIS_MEDIA_STATE_DISCONNECTED 0x00000001 - -/* packet filter bits used by RNDIS_OID_GEN_CURRENT_PACKET_FILTER */ -#define RNDIS_PACKET_TYPE_DIRECTED 0x00000001 -#define RNDIS_PACKET_TYPE_MULTICAST 0x00000002 -#define RNDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004 -#define RNDIS_PACKET_TYPE_BROADCAST 0x00000008 -#define RNDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010 -#define RNDIS_PACKET_TYPE_PROMISCUOUS 0x00000020 -#define RNDIS_PACKET_TYPE_SMT 0x00000040 -#define RNDIS_PACKET_TYPE_ALL_LOCAL 0x00000080 -#define RNDIS_PACKET_TYPE_GROUP 0x00001000 -#define RNDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00002000 -#define RNDIS_PACKET_TYPE_FUNCTIONAL 0x00004000 -#define RNDIS_PACKET_TYPE_MAC_FRAME 0x00008000 - -/* RNDIS_OID_GEN_MINIPORT_INFO constants */ -#define RNDIS_MINIPORT_BUS_MASTER 0x00000001 -#define RNDIS_MINIPORT_WDM_DRIVER 0x00000002 -#define RNDIS_MINIPORT_SG_LIST 0x00000004 -#define RNDIS_MINIPORT_SUPPORTS_MEDIA_QUERY 0x00000008 -#define RNDIS_MINIPORT_INDICATES_PACKETS 0x00000010 -#define RNDIS_MINIPORT_IGNORE_PACKET_QUEUE 0x00000020 -#define RNDIS_MINIPORT_IGNORE_REQUEST_QUEUE 0x00000040 -#define RNDIS_MINIPORT_IGNORE_TOKEN_RING_ERRORS 0x00000080 -#define RNDIS_MINIPORT_INTERMEDIATE_DRIVER 0x00000100 -#define RNDIS_MINIPORT_IS_NDIS_5 0x00000200 -#define RNDIS_MINIPORT_IS_CO 0x00000400 -#define RNDIS_MINIPORT_DESERIALIZE 0x00000800 -#define RNDIS_MINIPORT_REQUIRES_MEDIA_POLLING 0x00001000 -#define RNDIS_MINIPORT_SUPPORTS_MEDIA_SENSE 0x00002000 -#define RNDIS_MINIPORT_NETBOOT_CARD 0x00004000 -#define RNDIS_MINIPORT_PM_SUPPORTED 0x00008000 -#define RNDIS_MINIPORT_SUPPORTS_MAC_ADDRESS_OVERWRITE 0x00010000 -#define RNDIS_MINIPORT_USES_SAFE_BUFFER_APIS 0x00020000 -#define RNDIS_MINIPORT_HIDDEN 0x00040000 -#define RNDIS_MINIPORT_SWENUM 0x00080000 -#define RNDIS_MINIPORT_SURPRISE_REMOVE_OK 0x00100000 -#define RNDIS_MINIPORT_NO_HALT_ON_SUSPEND 0x00200000 -#define RNDIS_MINIPORT_HARDWARE_DEVICE 0x00400000 -#define RNDIS_MINIPORT_SUPPORTS_CANCEL_SEND_PACKETS 0x00800000 -#define RNDIS_MINIPORT_64BITS_DMA 0x01000000 - -#define RNDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001 -#define RNDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002 -#define RNDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004 -#define RNDIS_MAC_OPTION_NO_LOOPBACK 0x00000008 -#define RNDIS_MAC_OPTION_FULL_DUPLEX 0x00000010 -#define RNDIS_MAC_OPTION_EOTX_INDICATION 0x00000020 -#define RNDIS_MAC_OPTION_8021P_PRIORITY 0x00000040 -#define RNDIS_MAC_OPTION_RESERVED 0x80000000 - -/* Object Identifiers used by NdisRequest Query/Set Information */ -/* General (Required) Objects */ -#define RNDIS_OID_GEN_SUPPORTED_LIST 0x00010101 -#define RNDIS_OID_GEN_HARDWARE_STATUS 0x00010102 -#define RNDIS_OID_GEN_MEDIA_SUPPORTED 0x00010103 -#define RNDIS_OID_GEN_MEDIA_IN_USE 0x00010104 -#define RNDIS_OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 -#define RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 -#define RNDIS_OID_GEN_LINK_SPEED 0x00010107 -#define RNDIS_OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 -#define RNDIS_OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 -#define RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A -#define RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B -#define RNDIS_OID_GEN_VENDOR_ID 0x0001010C -#define RNDIS_OID_GEN_VENDOR_DESCRIPTION 0x0001010D -#define RNDIS_OID_GEN_CURRENT_PACKET_FILTER 0x0001010E -#define RNDIS_OID_GEN_CURRENT_LOOKAHEAD 0x0001010F -#define RNDIS_OID_GEN_DRIVER_VERSION 0x00010110 -#define RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 -#define RNDIS_OID_GEN_PROTOCOL_OPTIONS 0x00010112 -#define RNDIS_OID_GEN_MAC_OPTIONS 0x00010113 -#define RNDIS_OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 -#define RNDIS_OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 -#define RNDIS_OID_GEN_VENDOR_DRIVER_VERSION 0x00010116 -#define RNDIS_OID_GEN_SUPPORTED_GUIDS 0x00010117 -#define RNDIS_OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118 -#define RNDIS_OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119 -#define RNDIS_OID_GEN_PHYSICAL_MEDIUM 0x00010202 -#define RNDIS_OID_GEN_MACHINE_NAME 0x0001021A -#define RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B -#define RNDIS_OID_GEN_VLAN_ID 0x0001021C - -/* Optional OIDs */ -#define RNDIS_OID_GEN_MEDIA_CAPABILITIES 0x00010201 - -/* Required statistics OIDs */ -#define RNDIS_OID_GEN_XMIT_OK 0x00020101 -#define RNDIS_OID_GEN_RCV_OK 0x00020102 -#define RNDIS_OID_GEN_XMIT_ERROR 0x00020103 -#define RNDIS_OID_GEN_RCV_ERROR 0x00020104 -#define RNDIS_OID_GEN_RCV_NO_BUFFER 0x00020105 - -/* Optional statistics OIDs */ -#define RNDIS_OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 -#define RNDIS_OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 -#define RNDIS_OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 -#define RNDIS_OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 -#define RNDIS_OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 -#define RNDIS_OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 -#define RNDIS_OID_GEN_DIRECTED_BYTES_RCV 0x00020207 -#define RNDIS_OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 -#define RNDIS_OID_GEN_MULTICAST_BYTES_RCV 0x00020209 -#define RNDIS_OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A -#define RNDIS_OID_GEN_BROADCAST_BYTES_RCV 0x0002020B -#define RNDIS_OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C - -#define RNDIS_OID_GEN_RCV_CRC_ERROR 0x0002020D -#define RNDIS_OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E - -#define RNDIS_OID_GEN_GET_TIME_CAPS 0x0002020F -#define RNDIS_OID_GEN_GET_NETCARD_TIME 0x00020210 - -#define RNDIS_OID_GEN_NETCARD_LOAD 0x00020211 -#define RNDIS_OID_GEN_DEVICE_PROFILE 0x00020212 -#define RNDIS_OID_GEN_INIT_TIME_MS 0x00020213 -#define RNDIS_OID_GEN_RESET_COUNTS 0x00020214 -#define RNDIS_OID_GEN_MEDIA_SENSE_COUNTS 0x00020215 -#define RNDIS_OID_GEN_FRIENDLY_NAME 0x00020216 -#define RNDIS_OID_GEN_MINIPORT_INFO 0x00020217 -#define RNDIS_OID_GEN_RESET_VERIFY_PARAMETERS 0x00020218 - -/* These are connection-oriented general OIDs. */ -/* These replace the above OIDs for connection-oriented media. */ -#define RNDIS_OID_GEN_CO_SUPPORTED_LIST 0x00010101 -#define RNDIS_OID_GEN_CO_HARDWARE_STATUS 0x00010102 -#define RNDIS_OID_GEN_CO_MEDIA_SUPPORTED 0x00010103 -#define RNDIS_OID_GEN_CO_MEDIA_IN_USE 0x00010104 -#define RNDIS_OID_GEN_CO_LINK_SPEED 0x00010105 -#define RNDIS_OID_GEN_CO_VENDOR_ID 0x00010106 -#define RNDIS_OID_GEN_CO_VENDOR_DESCRIPTION 0x00010107 -#define RNDIS_OID_GEN_CO_DRIVER_VERSION 0x00010108 -#define RNDIS_OID_GEN_CO_PROTOCOL_OPTIONS 0x00010109 -#define RNDIS_OID_GEN_CO_MAC_OPTIONS 0x0001010A -#define RNDIS_OID_GEN_CO_MEDIA_CONNECT_STATUS 0x0001010B -#define RNDIS_OID_GEN_CO_VENDOR_DRIVER_VERSION 0x0001010C -#define RNDIS_OID_GEN_CO_MINIMUM_LINK_SPEED 0x0001010D - -#define RNDIS_OID_GEN_CO_GET_TIME_CAPS 0x00010201 -#define RNDIS_OID_GEN_CO_GET_NETCARD_TIME 0x00010202 - -/* These are connection-oriented statistics OIDs. */ -#define RNDIS_OID_GEN_CO_XMIT_PDUS_OK 0x00020101 -#define RNDIS_OID_GEN_CO_RCV_PDUS_OK 0x00020102 -#define RNDIS_OID_GEN_CO_XMIT_PDUS_ERROR 0x00020103 -#define RNDIS_OID_GEN_CO_RCV_PDUS_ERROR 0x00020104 -#define RNDIS_OID_GEN_CO_RCV_PDUS_NO_BUFFER 0x00020105 - - -#define RNDIS_OID_GEN_CO_RCV_CRC_ERROR 0x00020201 -#define RNDIS_OID_GEN_CO_TRANSMIT_QUEUE_LENGTH 0x00020202 -#define RNDIS_OID_GEN_CO_BYTES_XMIT 0x00020203 -#define RNDIS_OID_GEN_CO_BYTES_RCV 0x00020204 -#define RNDIS_OID_GEN_CO_BYTES_XMIT_OUTSTANDING 0x00020205 -#define RNDIS_OID_GEN_CO_NETCARD_LOAD 0x00020206 - -/* These are objects for Connection-oriented media call-managers. */ -#define RNDIS_OID_CO_ADD_PVC 0xFF000001 -#define RNDIS_OID_CO_DELETE_PVC 0xFF000002 -#define RNDIS_OID_CO_GET_CALL_INFORMATION 0xFF000003 -#define RNDIS_OID_CO_ADD_ADDRESS 0xFF000004 -#define RNDIS_OID_CO_DELETE_ADDRESS 0xFF000005 -#define RNDIS_OID_CO_GET_ADDRESSES 0xFF000006 -#define RNDIS_OID_CO_ADDRESS_CHANGE 0xFF000007 -#define RNDIS_OID_CO_SIGNALING_ENABLED 0xFF000008 -#define RNDIS_OID_CO_SIGNALING_DISABLED 0xFF000009 - -/* 802.3 Objects (Ethernet) */ -#define RNDIS_OID_802_3_PERMANENT_ADDRESS 0x01010101 -#define RNDIS_OID_802_3_CURRENT_ADDRESS 0x01010102 -#define RNDIS_OID_802_3_MULTICAST_LIST 0x01010103 -#define RNDIS_OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 -#define RNDIS_OID_802_3_MAC_OPTIONS 0x01010105 - -#define RNDIS_802_3_MAC_OPTION_PRIORITY 0x00000001 - -#define RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 -#define RNDIS_OID_802_3_XMIT_ONE_COLLISION 0x01020102 -#define RNDIS_OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 - -#define RNDIS_OID_802_3_XMIT_DEFERRED 0x01020201 -#define RNDIS_OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 -#define RNDIS_OID_802_3_RCV_OVERRUN 0x01020203 -#define RNDIS_OID_802_3_XMIT_UNDERRUN 0x01020204 -#define RNDIS_OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 -#define RNDIS_OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 -#define RNDIS_OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 - -#define RNDIS_OID_802_11_BSSID 0x0d010101 -#define RNDIS_OID_802_11_SSID 0x0d010102 -#define RNDIS_OID_802_11_INFRASTRUCTURE_MODE 0x0d010108 -#define RNDIS_OID_802_11_ADD_WEP 0x0d010113 -#define RNDIS_OID_802_11_REMOVE_WEP 0x0d010114 -#define RNDIS_OID_802_11_DISASSOCIATE 0x0d010115 -#define RNDIS_OID_802_11_AUTHENTICATION_MODE 0x0d010118 -#define RNDIS_OID_802_11_PRIVACY_FILTER 0x0d010119 -#define RNDIS_OID_802_11_BSSID_LIST_SCAN 0x0d01011a -#define RNDIS_OID_802_11_ENCRYPTION_STATUS 0x0d01011b -#define RNDIS_OID_802_11_ADD_KEY 0x0d01011d -#define RNDIS_OID_802_11_REMOVE_KEY 0x0d01011e -#define RNDIS_OID_802_11_ASSOCIATION_INFORMATION 0x0d01011f -#define RNDIS_OID_802_11_CAPABILITY 0x0d010122 -#define RNDIS_OID_802_11_PMKID 0x0d010123 -#define RNDIS_OID_802_11_NETWORK_TYPES_SUPPORTED 0x0d010203 -#define RNDIS_OID_802_11_NETWORK_TYPE_IN_USE 0x0d010204 -#define RNDIS_OID_802_11_TX_POWER_LEVEL 0x0d010205 -#define RNDIS_OID_802_11_RSSI 0x0d010206 -#define RNDIS_OID_802_11_RSSI_TRIGGER 0x0d010207 -#define RNDIS_OID_802_11_FRAGMENTATION_THRESHOLD 0x0d010209 -#define RNDIS_OID_802_11_RTS_THRESHOLD 0x0d01020a -#define RNDIS_OID_802_11_SUPPORTED_RATES 0x0d01020e -#define RNDIS_OID_802_11_CONFIGURATION 0x0d010211 -#define RNDIS_OID_802_11_POWER_MODE 0x0d010216 -#define RNDIS_OID_802_11_BSSID_LIST 0x0d010217 - -/* Plug and Play capabilities */ -#define RNDIS_OID_PNP_CAPABILITIES 0xFD010100 -#define RNDIS_OID_PNP_SET_POWER 0xFD010101 -#define RNDIS_OID_PNP_QUERY_POWER 0xFD010102 -#define RNDIS_OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103 -#define RNDIS_OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104 -#define RNDIS_OID_PNP_ENABLE_WAKE_UP 0xFD010106 - -/* RNDIS_PNP_CAPABILITIES.Flags constants */ -#define RNDIS_DEVICE_WAKE_UP_ENABLE 0x00000001 -#define RNDIS_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002 -#define RNDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004 - -#define REMOTE_CONDIS_MP_CREATE_VC_MSG 0x00008001 -#define REMOTE_CONDIS_MP_DELETE_VC_MSG 0x00008002 -#define REMOTE_CONDIS_MP_ACTIVATE_VC_MSG 0x00008005 -#define REMOTE_CONDIS_MP_DEACTIVATE_VC_MSG 0x00008006 -#define REMOTE_CONDIS_INDICATE_STATUS_MSG 0x00008007 - -#define REMOTE_CONDIS_MP_CREATE_VC_CMPLT 0x80008001 -#define REMOTE_CONDIS_MP_DELETE_VC_CMPLT 0x80008002 -#define REMOTE_CONDIS_MP_ACTIVATE_VC_CMPLT 0x80008005 -#define REMOTE_CONDIS_MP_DEACTIVATE_VC_CMPLT 0x80008006 diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index f774d88cd0aa..81a173c0897d 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -1341,8 +1341,6 @@ struct task_struct { * execve */ unsigned in_iowait:1; - /* task may not gain privileges */ - unsigned no_new_privs:1; /* Revert to default priority/policy when forking */ unsigned sched_reset_on_fork:1; @@ -1452,7 +1450,7 @@ struct task_struct { uid_t loginuid; unsigned int sessionid; #endif - struct seccomp seccomp; + seccomp_t seccomp; /* Thread group tracking */ u32 parent_exec_id; @@ -1907,22 +1905,12 @@ static inline void rcu_copy_process(struct task_struct *p) INIT_LIST_HEAD(&p->rcu_node_entry); } -static inline void rcu_switch_from(struct task_struct *prev) -{ - if (prev->rcu_read_lock_nesting != 0) - rcu_preempt_note_context_switch(); -} - #else static inline void rcu_copy_process(struct task_struct *p) { } -static inline void rcu_switch_from(struct task_struct *prev) -{ -} - #endif #ifdef CONFIG_SMP diff --git a/trunk/include/linux/seccomp.h b/trunk/include/linux/seccomp.h index 84f6320da50f..cc7a4e9cc7ad 100644 --- a/trunk/include/linux/seccomp.h +++ b/trunk/include/linux/seccomp.h @@ -1,90 +1,25 @@ #ifndef _LINUX_SECCOMP_H #define _LINUX_SECCOMP_H -#include -#include - - -/* Valid values for seccomp.mode and prctl(PR_SET_SECCOMP, ) */ -#define SECCOMP_MODE_DISABLED 0 /* seccomp is not in use. */ -#define SECCOMP_MODE_STRICT 1 /* uses hard-coded filter. */ -#define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */ - -/* - * All BPF programs must return a 32-bit value. - * The bottom 16-bits are for optional return data. - * The upper 16-bits are ordered from least permissive values to most. - * - * The ordering ensures that a min_t() over composed return values always - * selects the least permissive choice. - */ -#define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */ -#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */ -#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */ -#define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */ -#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */ - -/* Masks for the return value sections. */ -#define SECCOMP_RET_ACTION 0x7fff0000U -#define SECCOMP_RET_DATA 0x0000ffffU - -/** - * struct seccomp_data - the format the BPF program executes over. - * @nr: the system call number - * @arch: indicates system call convention as an AUDIT_ARCH_* value - * as defined in . - * @instruction_pointer: at the time of the system call. - * @args: up to 6 system call arguments always stored as 64-bit values - * regardless of the architecture. - */ -struct seccomp_data { - int nr; - __u32 arch; - __u64 instruction_pointer; - __u64 args[6]; -}; - -#ifdef __KERNEL__ + #ifdef CONFIG_SECCOMP #include #include -struct seccomp_filter; -/** - * struct seccomp - the state of a seccomp'ed process - * - * @mode: indicates one of the valid values above for controlled - * system calls available to a process. - * @filter: The metadata and ruleset for determining what system calls - * are allowed for a task. - * - * @filter must only be accessed from the context of current as there - * is no locking. - */ -struct seccomp { - int mode; - struct seccomp_filter *filter; -}; - -extern int __secure_computing(int); -static inline int secure_computing(int this_syscall) -{ - if (unlikely(test_thread_flag(TIF_SECCOMP))) - return __secure_computing(this_syscall); - return 0; -} +typedef struct { int mode; } seccomp_t; -/* A wrapper for architectures supporting only SECCOMP_MODE_STRICT. */ -static inline void secure_computing_strict(int this_syscall) +extern void __secure_computing(int); +static inline void secure_computing(int this_syscall) { - BUG_ON(secure_computing(this_syscall) != 0); + if (unlikely(test_thread_flag(TIF_SECCOMP))) + __secure_computing(this_syscall); } extern long prctl_get_seccomp(void); -extern long prctl_set_seccomp(unsigned long, char __user *); +extern long prctl_set_seccomp(unsigned long); -static inline int seccomp_mode(struct seccomp *s) +static inline int seccomp_mode(seccomp_t *s) { return s->mode; } @@ -93,41 +28,25 @@ static inline int seccomp_mode(struct seccomp *s) #include -struct seccomp { }; -struct seccomp_filter { }; +typedef struct { } seccomp_t; -static inline int secure_computing(int this_syscall) { return 0; } -static inline void secure_computing_strict(int this_syscall) { return; } +#define secure_computing(x) do { } while (0) static inline long prctl_get_seccomp(void) { return -EINVAL; } -static inline long prctl_set_seccomp(unsigned long arg2, char __user *arg3) +static inline long prctl_set_seccomp(unsigned long arg2) { return -EINVAL; } -static inline int seccomp_mode(struct seccomp *s) +static inline int seccomp_mode(seccomp_t *s) { return 0; } + #endif /* CONFIG_SECCOMP */ -#ifdef CONFIG_SECCOMP_FILTER -extern void put_seccomp_filter(struct task_struct *tsk); -extern void get_seccomp_filter(struct task_struct *tsk); -extern u32 seccomp_bpf_load(int off); -#else /* CONFIG_SECCOMP_FILTER */ -static inline void put_seccomp_filter(struct task_struct *tsk) -{ - return; -} -static inline void get_seccomp_filter(struct task_struct *tsk) -{ - return; -} -#endif /* CONFIG_SECCOMP_FILTER */ -#endif /* __KERNEL__ */ #endif /* _LINUX_SECCOMP_H */ diff --git a/trunk/include/linux/security.h b/trunk/include/linux/security.h index ab0e091ce5fa..673afbb8238a 100644 --- a/trunk/include/linux/security.h +++ b/trunk/include/linux/security.h @@ -144,7 +144,6 @@ struct request_sock; #define LSM_UNSAFE_SHARE 1 #define LSM_UNSAFE_PTRACE 2 #define LSM_UNSAFE_PTRACE_CAP 4 -#define LSM_UNSAFE_NO_NEW_PRIVS 8 #ifdef CONFIG_MMU extern int mmap_min_addr_handler(struct ctl_table *table, int write, @@ -640,7 +639,10 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * to receive an open file descriptor via socket IPC. * @file contains the file structure being received. * Return 0 if permission is granted. - * @file_open + * + * Security hook for dentry + * + * @dentry_open * Save open-time permission checking state for later use upon * file_permission, and recheck access if anything has changed * since inode_permission. @@ -1495,7 +1497,7 @@ struct security_operations { int (*file_send_sigiotask) (struct task_struct *tsk, struct fown_struct *fown, int sig); int (*file_receive) (struct file *file); - int (*file_open) (struct file *file, const struct cred *cred); + int (*dentry_open) (struct file *file, const struct cred *cred); int (*task_create) (unsigned long clone_flags); void (*task_free) (struct task_struct *task); @@ -1754,7 +1756,7 @@ int security_file_set_fowner(struct file *file); int security_file_send_sigiotask(struct task_struct *tsk, struct fown_struct *fown, int sig); int security_file_receive(struct file *file); -int security_file_open(struct file *file, const struct cred *cred); +int security_dentry_open(struct file *file, const struct cred *cred); int security_task_create(unsigned long clone_flags); void security_task_free(struct task_struct *task); int security_cred_alloc_blank(struct cred *cred, gfp_t gfp); @@ -2225,8 +2227,8 @@ static inline int security_file_receive(struct file *file) return 0; } -static inline int security_file_open(struct file *file, - const struct cred *cred) +static inline int security_dentry_open(struct file *file, + const struct cred *cred) { return 0; } diff --git a/trunk/include/linux/seqlock.h b/trunk/include/linux/seqlock.h index 600060e25ec6..c6db9fb33c44 100644 --- a/trunk/include/linux/seqlock.h +++ b/trunk/include/linux/seqlock.h @@ -141,7 +141,7 @@ static inline unsigned __read_seqcount_begin(const seqcount_t *s) unsigned ret; repeat: - ret = ACCESS_ONCE(s->sequence); + ret = s->sequence; if (unlikely(ret & 1)) { cpu_relax(); goto repeat; @@ -165,27 +165,6 @@ static inline unsigned read_seqcount_begin(const seqcount_t *s) return ret; } -/** - * raw_seqcount_begin - begin a seq-read critical section - * @s: pointer to seqcount_t - * Returns: count to be passed to read_seqcount_retry - * - * raw_seqcount_begin opens a read critical section of the given seqcount. - * Validity of the critical section is tested by checking read_seqcount_retry - * function. - * - * Unlike read_seqcount_begin(), this function will not wait for the count - * to stabilize. If a writer is active when we begin, we will fail the - * read_seqcount_retry() instead of stabilizing at the beginning of the - * critical section. - */ -static inline unsigned raw_seqcount_begin(const seqcount_t *s) -{ - unsigned ret = ACCESS_ONCE(s->sequence); - smp_rmb(); - return ret & ~1; -} - /** * __read_seqcount_retry - end a seq-read critical section (without barrier) * @s: pointer to seqcount_t diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index 0e501714d47f..bb47314c7179 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -562,11 +562,6 @@ extern void kfree_skb(struct sk_buff *skb); extern void consume_skb(struct sk_buff *skb); extern void __kfree_skb(struct sk_buff *skb); extern struct kmem_cache *skbuff_head_cache; - -extern void kfree_skb_partial(struct sk_buff *skb, bool head_stolen); -extern bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, - bool *fragstolen, int *delta_truesize); - extern struct sk_buff *__alloc_skb(unsigned int size, gfp_t priority, int fclone, int node); extern struct sk_buff *build_skb(void *data, unsigned int frag_size); @@ -1685,11 +1680,31 @@ static inline void __skb_queue_purge(struct sk_buff_head *list) kfree_skb(skb); } -extern void *netdev_alloc_frag(unsigned int fragsz); +/** + * __dev_alloc_skb - allocate an skbuff for receiving + * @length: length to allocate + * @gfp_mask: get_free_pages mask, passed to alloc_skb + * + * Allocate a new &sk_buff and assign it a usage count of one. The + * buffer has unspecified headroom built in. Users should allocate + * the headroom they think they need without accounting for the + * built in space. The built in space is used for optimisations. + * + * %NULL is returned if there is no free memory. + */ +static inline struct sk_buff *__dev_alloc_skb(unsigned int length, + gfp_t gfp_mask) +{ + struct sk_buff *skb = alloc_skb(length + NET_SKB_PAD, gfp_mask); + if (likely(skb)) + skb_reserve(skb, NET_SKB_PAD); + return skb; +} + +extern struct sk_buff *dev_alloc_skb(unsigned int length); extern struct sk_buff *__netdev_alloc_skb(struct net_device *dev, - unsigned int length, - gfp_t gfp_mask); + unsigned int length, gfp_t gfp_mask); /** * netdev_alloc_skb - allocate an skbuff for rx on a specific device @@ -1705,25 +1720,11 @@ extern struct sk_buff *__netdev_alloc_skb(struct net_device *dev, * allocates memory it can be called from an interrupt. */ static inline struct sk_buff *netdev_alloc_skb(struct net_device *dev, - unsigned int length) + unsigned int length) { return __netdev_alloc_skb(dev, length, GFP_ATOMIC); } -/* legacy helper around __netdev_alloc_skb() */ -static inline struct sk_buff *__dev_alloc_skb(unsigned int length, - gfp_t gfp_mask) -{ - return __netdev_alloc_skb(NULL, length, gfp_mask); -} - -/* legacy helper around netdev_alloc_skb() */ -static inline struct sk_buff *dev_alloc_skb(unsigned int length) -{ - return netdev_alloc_skb(NULL, length); -} - - static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, unsigned int length, gfp_t gfp) { diff --git a/trunk/include/linux/smp.h b/trunk/include/linux/smp.h index 717fb746c9a8..10530d92c04b 100644 --- a/trunk/include/linux/smp.h +++ b/trunk/include/linux/smp.h @@ -61,7 +61,7 @@ extern void smp_prepare_cpus(unsigned int max_cpus); /* * Bring a CPU up */ -extern int __cpu_up(unsigned int cpunum, struct task_struct *tidle); +extern int __cpu_up(unsigned int cpunum); /* * Final polishing of CPUs @@ -81,8 +81,6 @@ void __smp_call_function_single(int cpuid, struct call_single_data *data, int smp_call_function_any(const struct cpumask *mask, smp_call_func_t func, void *info, int wait); -void kick_all_cpus_sync(void); - /* * Generic and arch helpers */ @@ -194,8 +192,6 @@ smp_call_function_any(const struct cpumask *mask, smp_call_func_t func, return smp_call_function_single(0, func, info, wait); } -static inline void kick_all_cpus_sync(void) { } - #endif /* !SMP */ /* diff --git a/trunk/include/linux/srcu.h b/trunk/include/linux/srcu.h index 55a5c52cbb25..d3d5fa54f25e 100644 --- a/trunk/include/linux/srcu.h +++ b/trunk/include/linux/srcu.h @@ -29,35 +29,26 @@ #include #include -#include struct srcu_struct_array { - unsigned long c[2]; - unsigned long seq[2]; -}; - -struct rcu_batch { - struct rcu_head *head, **tail; + int c[2]; }; struct srcu_struct { - unsigned completed; + int completed; struct srcu_struct_array __percpu *per_cpu_ref; - spinlock_t queue_lock; /* protect ->batch_queue, ->running */ - bool running; - /* callbacks just queued */ - struct rcu_batch batch_queue; - /* callbacks try to do the first check_zero */ - struct rcu_batch batch_check0; - /* callbacks done with the first check_zero and the flip */ - struct rcu_batch batch_check1; - struct rcu_batch batch_done; - struct delayed_work work; + struct mutex mutex; #ifdef CONFIG_DEBUG_LOCK_ALLOC struct lockdep_map dep_map; #endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ }; +#ifndef CONFIG_PREEMPT +#define srcu_barrier() barrier() +#else /* #ifndef CONFIG_PREEMPT */ +#define srcu_barrier() +#endif /* #else #ifndef CONFIG_PREEMPT */ + #ifdef CONFIG_DEBUG_LOCK_ALLOC int __init_srcu_struct(struct srcu_struct *sp, const char *name, @@ -76,33 +67,12 @@ int init_srcu_struct(struct srcu_struct *sp); #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ -/** - * call_srcu() - Queue a callback for invocation after an SRCU grace period - * @sp: srcu_struct in queue the callback - * @head: structure to be used for queueing the SRCU callback. - * @func: function to be invoked after the SRCU grace period - * - * The callback function will be invoked some time after a full SRCU - * grace period elapses, in other words after all pre-existing SRCU - * read-side critical sections have completed. However, the callback - * function might well execute concurrently with other SRCU read-side - * critical sections that started after call_srcu() was invoked. SRCU - * read-side critical sections are delimited by srcu_read_lock() and - * srcu_read_unlock(), and may be nested. - * - * The callback will be invoked from process context, but must nevertheless - * be fast and must not block. - */ -void call_srcu(struct srcu_struct *sp, struct rcu_head *head, - void (*func)(struct rcu_head *head)); - void cleanup_srcu_struct(struct srcu_struct *sp); int __srcu_read_lock(struct srcu_struct *sp) __acquires(sp); void __srcu_read_unlock(struct srcu_struct *sp, int idx) __releases(sp); void synchronize_srcu(struct srcu_struct *sp); void synchronize_srcu_expedited(struct srcu_struct *sp); long srcu_batches_completed(struct srcu_struct *sp); -void srcu_barrier(struct srcu_struct *sp); #ifdef CONFIG_DEBUG_LOCK_ALLOC diff --git a/trunk/include/linux/stmmac.h b/trunk/include/linux/stmmac.h index b69bdb1e08b6..f85c93d6e6da 100644 --- a/trunk/include/linux/stmmac.h +++ b/trunk/include/linux/stmmac.h @@ -86,7 +86,6 @@ struct stmmac_mdio_bus_data { struct stmmac_dma_cfg { int pbl; int fixed_burst; - int mixed_burst; int burst_len; }; diff --git a/trunk/include/linux/thread_info.h b/trunk/include/linux/thread_info.h index db78775eff3b..8d03f079688c 100644 --- a/trunk/include/linux/thread_info.h +++ b/trunk/include/linux/thread_info.h @@ -54,12 +54,6 @@ extern long do_no_restart_syscall(struct restart_block *parm); #ifdef __KERNEL__ -#ifdef CONFIG_DEBUG_STACK_USAGE -# define THREADINFO_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO) -#else -# define THREADINFO_GFP (GFP_KERNEL | __GFP_NOTRACK) -#endif - /* * flag set/clear/test wrappers * - pass TIF_xxxx constants to these functions diff --git a/trunk/include/linux/trdevice.h b/trunk/include/linux/trdevice.h new file mode 100644 index 000000000000..bfc84a7aecc5 --- /dev/null +++ b/trunk/include/linux/trdevice.h @@ -0,0 +1,37 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. NET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Definitions for the Token-ring handlers. + * + * Version: @(#)eth.h 1.0.4 05/13/93 + * + * Authors: Ross Biro + * Fred N. van Kempen, + * + * Relocated to include/linux where it belongs by Alan Cox + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * WARNING: This move may well be temporary. This file will get merged with others RSN. + * + */ +#ifndef _LINUX_TRDEVICE_H +#define _LINUX_TRDEVICE_H + + +#include + +#ifdef __KERNEL__ +extern __be16 tr_type_trans(struct sk_buff *skb, struct net_device *dev); +extern void tr_source_route(struct sk_buff *skb, struct trh_hdr *trh, struct net_device *dev); +extern struct net_device *alloc_trdev(int sizeof_priv); + +#endif + +#endif /* _LINUX_TRDEVICE_H */ diff --git a/trunk/include/linux/usb/rndis_host.h b/trunk/include/linux/usb/rndis_host.h index d44ef85db177..88fceb718c77 100644 --- a/trunk/include/linux/usb/rndis_host.h +++ b/trunk/include/linux/usb/rndis_host.h @@ -20,8 +20,6 @@ #ifndef __LINUX_USB_RNDIS_HOST_H #define __LINUX_USB_RNDIS_HOST_H -#include - /* * CONTROL uses CDC "encapsulated commands" with funky notifications. * - control-out: SEND_ENCAPSULATED @@ -51,6 +49,47 @@ struct rndis_msg_hdr { */ #define RNDIS_CONTROL_TIMEOUT_MS (5 * 1000) +#define RNDIS_MSG_COMPLETION cpu_to_le32(0x80000000) + +/* codes for "msg_type" field of rndis messages; + * only the data channel uses packet messages (maybe batched); + * everything else goes on the control channel. + */ +#define RNDIS_MSG_PACKET cpu_to_le32(0x00000001) /* 1-N packets */ +#define RNDIS_MSG_INIT cpu_to_le32(0x00000002) +#define RNDIS_MSG_INIT_C (RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION) +#define RNDIS_MSG_HALT cpu_to_le32(0x00000003) +#define RNDIS_MSG_QUERY cpu_to_le32(0x00000004) +#define RNDIS_MSG_QUERY_C (RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION) +#define RNDIS_MSG_SET cpu_to_le32(0x00000005) +#define RNDIS_MSG_SET_C (RNDIS_MSG_SET|RNDIS_MSG_COMPLETION) +#define RNDIS_MSG_RESET cpu_to_le32(0x00000006) +#define RNDIS_MSG_RESET_C (RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION) +#define RNDIS_MSG_INDICATE cpu_to_le32(0x00000007) +#define RNDIS_MSG_KEEPALIVE cpu_to_le32(0x00000008) +#define RNDIS_MSG_KEEPALIVE_C (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION) + +/* codes for "status" field of completion messages */ +#define RNDIS_STATUS_SUCCESS cpu_to_le32(0x00000000) +#define RNDIS_STATUS_FAILURE cpu_to_le32(0xc0000001) +#define RNDIS_STATUS_INVALID_DATA cpu_to_le32(0xc0010015) +#define RNDIS_STATUS_NOT_SUPPORTED cpu_to_le32(0xc00000bb) +#define RNDIS_STATUS_MEDIA_CONNECT cpu_to_le32(0x4001000b) +#define RNDIS_STATUS_MEDIA_DISCONNECT cpu_to_le32(0x4001000c) +#define RNDIS_STATUS_MEDIA_SPECIFIC_INDICATION cpu_to_le32(0x40010012) + +/* codes for OID_GEN_PHYSICAL_MEDIUM */ +#define RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED cpu_to_le32(0x00000000) +#define RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN cpu_to_le32(0x00000001) +#define RNDIS_PHYSICAL_MEDIUM_CABLE_MODEM cpu_to_le32(0x00000002) +#define RNDIS_PHYSICAL_MEDIUM_PHONE_LINE cpu_to_le32(0x00000003) +#define RNDIS_PHYSICAL_MEDIUM_POWER_LINE cpu_to_le32(0x00000004) +#define RNDIS_PHYSICAL_MEDIUM_DSL cpu_to_le32(0x00000005) +#define RNDIS_PHYSICAL_MEDIUM_FIBRE_CHANNEL cpu_to_le32(0x00000006) +#define RNDIS_PHYSICAL_MEDIUM_1394 cpu_to_le32(0x00000007) +#define RNDIS_PHYSICAL_MEDIUM_WIRELESS_WAN cpu_to_le32(0x00000008) +#define RNDIS_PHYSICAL_MEDIUM_MAX cpu_to_le32(0x00000009) + struct rndis_data_hdr { __le32 msg_type; /* RNDIS_MSG_PACKET */ __le32 msg_len; /* rndis_data_hdr + data_len + pad */ @@ -183,6 +222,29 @@ struct rndis_keepalive_c { /* IN (optionally OUT) */ __le32 status; } __attribute__ ((packed)); +/* NOTE: about 30 OIDs are "mandatory" for peripherals to support ... and + * there are gobs more that may optionally be supported. We'll avoid as much + * of that mess as possible. + */ +#define OID_802_3_PERMANENT_ADDRESS cpu_to_le32(0x01010101) +#define OID_GEN_MAXIMUM_FRAME_SIZE cpu_to_le32(0x00010106) +#define OID_GEN_CURRENT_PACKET_FILTER cpu_to_le32(0x0001010e) +#define OID_GEN_PHYSICAL_MEDIUM cpu_to_le32(0x00010202) + +/* packet filter bits used by OID_GEN_CURRENT_PACKET_FILTER */ +#define RNDIS_PACKET_TYPE_DIRECTED cpu_to_le32(0x00000001) +#define RNDIS_PACKET_TYPE_MULTICAST cpu_to_le32(0x00000002) +#define RNDIS_PACKET_TYPE_ALL_MULTICAST cpu_to_le32(0x00000004) +#define RNDIS_PACKET_TYPE_BROADCAST cpu_to_le32(0x00000008) +#define RNDIS_PACKET_TYPE_SOURCE_ROUTING cpu_to_le32(0x00000010) +#define RNDIS_PACKET_TYPE_PROMISCUOUS cpu_to_le32(0x00000020) +#define RNDIS_PACKET_TYPE_SMT cpu_to_le32(0x00000040) +#define RNDIS_PACKET_TYPE_ALL_LOCAL cpu_to_le32(0x00000080) +#define RNDIS_PACKET_TYPE_GROUP cpu_to_le32(0x00001000) +#define RNDIS_PACKET_TYPE_ALL_FUNCTIONAL cpu_to_le32(0x00002000) +#define RNDIS_PACKET_TYPE_FUNCTIONAL cpu_to_le32(0x00004000) +#define RNDIS_PACKET_TYPE_MAC_FRAME cpu_to_le32(0x00008000) + /* default filter used with RNDIS devices */ #define RNDIS_DEFAULT_FILTER ( \ RNDIS_PACKET_TYPE_DIRECTED | \ diff --git a/trunk/include/linux/usb/usbnet.h b/trunk/include/linux/usb/usbnet.h index 76f439647c4b..605b0aa8d852 100644 --- a/trunk/include/linux/usb/usbnet.h +++ b/trunk/include/linux/usb/usbnet.h @@ -191,8 +191,7 @@ extern void usbnet_cdc_status(struct usbnet *, struct urb *); enum skb_state { illegal = 0, tx_start, tx_done, - rx_start, rx_done, rx_cleanup, - unlink_start + rx_start, rx_done, rx_cleanup }; struct skb_data { /* skb->cb is one of these */ diff --git a/trunk/include/linux/virtio_config.h b/trunk/include/linux/virtio_config.h index fc457f452f64..7323a3390206 100644 --- a/trunk/include/linux/virtio_config.h +++ b/trunk/include/linux/virtio_config.h @@ -74,6 +74,15 @@ * @set_status: write the status byte * vdev: the virtio_device * status: the new status byte + * @request_vqs: request the specified number of virtqueues + * vdev: the virtio_device + * max_vqs: the max number of virtqueues we want + * If supplied, must call before any virtqueues are instantiated. + * To modify the max number of virtqueues after request_vqs has been + * called, call free_vqs and then request_vqs with a new value. + * @free_vqs: cleanup resources allocated by request_vqs + * vdev: the virtio_device + * If supplied, must call after all virtqueues have been deleted. * @reset: reset the device * vdev: the virtio device * After this, status and feature negotiation must be done again @@ -147,7 +156,7 @@ static inline bool virtio_has_feature(const struct virtio_device *vdev, * @vdev: the virtio device * @fbit: the feature bit * @offset: the type to search for. - * @v: a pointer to the value to fill in. + * @val: a pointer to the value to fill in. * * The return value is -ENOENT if the feature doesn't exist. Otherwise * the config value is copied into whatever is pointed to by v. */ diff --git a/trunk/include/media/soc_camera.h b/trunk/include/media/soc_camera.h index cad374bdcf4b..b5c2b6cb0d81 100644 --- a/trunk/include/media/soc_camera.h +++ b/trunk/include/media/soc_camera.h @@ -59,8 +59,7 @@ struct soc_camera_device { struct soc_camera_host { struct v4l2_device v4l2_dev; struct list_head list; - struct mutex host_lock; /* Protect during probing */ - unsigned char nr; /* Host number */ + unsigned char nr; /* Host number */ void *priv; const char *drv_name; struct soc_camera_host_ops *ops; diff --git a/trunk/include/net/addrconf.h b/trunk/include/net/addrconf.h index f2b801c4b555..27f450ba9514 100644 --- a/trunk/include/net/addrconf.h +++ b/trunk/include/net/addrconf.h @@ -131,9 +131,9 @@ extern int ipv6_sock_mc_join(struct sock *sk, int ifindex, extern int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr); extern void ipv6_sock_mc_close(struct sock *sk); -extern bool inet6_mc_check(struct sock *sk, - const struct in6_addr *mc_addr, - const struct in6_addr *src_addr); +extern int inet6_mc_check(struct sock *sk, + const struct in6_addr *mc_addr, + const struct in6_addr *src_addr); extern int ipv6_dev_mc_inc(struct net_device *dev, const struct in6_addr *addr); extern int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr); @@ -146,10 +146,10 @@ extern void ipv6_mc_init_dev(struct inet6_dev *idev); extern void ipv6_mc_destroy_dev(struct inet6_dev *idev); extern void addrconf_dad_failure(struct inet6_ifaddr *ifp); -extern bool ipv6_chk_mcast_addr(struct net_device *dev, - const struct in6_addr *group, - const struct in6_addr *src_addr); -extern bool ipv6_is_mld(struct sk_buff *skb, int nexthdr); +extern int ipv6_chk_mcast_addr(struct net_device *dev, + const struct in6_addr *group, + const struct in6_addr *src_addr); +extern int ipv6_is_mld(struct sk_buff *skb, int nexthdr); extern void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao); @@ -163,8 +163,8 @@ extern void ipv6_sock_ac_close(struct sock *sk); extern int ipv6_dev_ac_inc(struct net_device *dev, const struct in6_addr *addr); extern int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr); -extern bool ipv6_chk_acast_addr(struct net *net, struct net_device *dev, - const struct in6_addr *addr); +extern int ipv6_chk_acast_addr(struct net *net, struct net_device *dev, + const struct in6_addr *addr); /* Device notifier */ diff --git a/trunk/include/net/bluetooth/bluetooth.h b/trunk/include/net/bluetooth/bluetooth.h index a65910bda381..262ebd1747d4 100644 --- a/trunk/include/net/bluetooth/bluetooth.h +++ b/trunk/include/net/bluetooth/bluetooth.h @@ -191,7 +191,6 @@ struct bt_sock { struct list_head accept_q; struct sock *parent; u32 defer_setup; - bool suspended; }; struct bt_sock_list { diff --git a/trunk/include/net/codel.h b/trunk/include/net/codel.h deleted file mode 100644 index 550debfc2403..000000000000 --- a/trunk/include/net/codel.h +++ /dev/null @@ -1,342 +0,0 @@ -#ifndef __NET_SCHED_CODEL_H -#define __NET_SCHED_CODEL_H - -/* - * Codel - The Controlled-Delay Active Queue Management algorithm - * - * Copyright (C) 2011-2012 Kathleen Nichols - * Copyright (C) 2011-2012 Van Jacobson - * Copyright (C) 2012 Michael D. Taht - * Copyright (C) 2012 Eric Dumazet - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The names of the authors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * Alternatively, provided that this notice is retained in full, this - * software may be distributed under the terms of the GNU General - * Public License ("GPL") version 2, in which case the provisions of the - * GPL apply INSTEAD OF those given above. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - */ - -#include -#include -#include -#include -#include -#include - -/* Controlling Queue Delay (CoDel) algorithm - * ========================================= - * Source : Kathleen Nichols and Van Jacobson - * http://queue.acm.org/detail.cfm?id=2209336 - * - * Implemented on linux by Dave Taht and Eric Dumazet - */ - - -/* CoDel uses a 1024 nsec clock, encoded in u32 - * This gives a range of 2199 seconds, because of signed compares - */ -typedef u32 codel_time_t; -typedef s32 codel_tdiff_t; -#define CODEL_SHIFT 10 -#define MS2TIME(a) ((a * NSEC_PER_MSEC) >> CODEL_SHIFT) - -static inline codel_time_t codel_get_time(void) -{ - u64 ns = ktime_to_ns(ktime_get()); - - return ns >> CODEL_SHIFT; -} - -#define codel_time_after(a, b) ((s32)(a) - (s32)(b) > 0) -#define codel_time_after_eq(a, b) ((s32)(a) - (s32)(b) >= 0) -#define codel_time_before(a, b) ((s32)(a) - (s32)(b) < 0) -#define codel_time_before_eq(a, b) ((s32)(a) - (s32)(b) <= 0) - -/* Qdiscs using codel plugin must use codel_skb_cb in their own cb[] */ -struct codel_skb_cb { - codel_time_t enqueue_time; -}; - -static struct codel_skb_cb *get_codel_cb(const struct sk_buff *skb) -{ - qdisc_cb_private_validate(skb, sizeof(struct codel_skb_cb)); - return (struct codel_skb_cb *)qdisc_skb_cb(skb)->data; -} - -static codel_time_t codel_get_enqueue_time(const struct sk_buff *skb) -{ - return get_codel_cb(skb)->enqueue_time; -} - -static void codel_set_enqueue_time(struct sk_buff *skb) -{ - get_codel_cb(skb)->enqueue_time = codel_get_time(); -} - -static inline u32 codel_time_to_us(codel_time_t val) -{ - u64 valns = ((u64)val << CODEL_SHIFT); - - do_div(valns, NSEC_PER_USEC); - return (u32)valns; -} - -/** - * struct codel_params - contains codel parameters - * @target: target queue size (in time units) - * @interval: width of moving time window - * @ecn: is Explicit Congestion Notification enabled - */ -struct codel_params { - codel_time_t target; - codel_time_t interval; - bool ecn; -}; - -/** - * struct codel_vars - contains codel variables - * @count: how many drops we've done since the last time we - * entered dropping state - * @lastcount: count at entry to dropping state - * @dropping: set to true if in dropping state - * @rec_inv_sqrt: reciprocal value of sqrt(count) >> 1 - * @first_above_time: when we went (or will go) continuously above target - * for interval - * @drop_next: time to drop next packet, or when we dropped last - * @ldelay: sojourn time of last dequeued packet - */ -struct codel_vars { - u32 count; - u32 lastcount; - bool dropping; - u16 rec_inv_sqrt; - codel_time_t first_above_time; - codel_time_t drop_next; - codel_time_t ldelay; -}; - -#define REC_INV_SQRT_BITS (8 * sizeof(u16)) /* or sizeof_in_bits(rec_inv_sqrt) */ -/* needed shift to get a Q0.32 number from rec_inv_sqrt */ -#define REC_INV_SQRT_SHIFT (32 - REC_INV_SQRT_BITS) - -/** - * struct codel_stats - contains codel shared variables and stats - * @maxpacket: largest packet we've seen so far - * @drop_count: temp count of dropped packets in dequeue() - * ecn_mark: number of packets we ECN marked instead of dropping - */ -struct codel_stats { - u32 maxpacket; - u32 drop_count; - u32 ecn_mark; -}; - -static void codel_params_init(struct codel_params *params) -{ - params->interval = MS2TIME(100); - params->target = MS2TIME(5); - params->ecn = false; -} - -static void codel_vars_init(struct codel_vars *vars) -{ - memset(vars, 0, sizeof(*vars)); -} - -static void codel_stats_init(struct codel_stats *stats) -{ - stats->maxpacket = 256; -} - -/* - * http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Iterative_methods_for_reciprocal_square_roots - * new_invsqrt = (invsqrt / 2) * (3 - count * invsqrt^2) - * - * Here, invsqrt is a fixed point number (< 1.0), 32bit mantissa, aka Q0.32 - */ -static void codel_Newton_step(struct codel_vars *vars) -{ - u32 invsqrt = ((u32)vars->rec_inv_sqrt) << REC_INV_SQRT_SHIFT; - u32 invsqrt2 = ((u64)invsqrt * invsqrt) >> 32; - u64 val = (3LL << 32) - ((u64)vars->count * invsqrt2); - - val >>= 2; /* avoid overflow in following multiply */ - val = (val * invsqrt) >> (32 - 2 + 1); - - vars->rec_inv_sqrt = val >> REC_INV_SQRT_SHIFT; -} - -/* - * CoDel control_law is t + interval/sqrt(count) - * We maintain in rec_inv_sqrt the reciprocal value of sqrt(count) to avoid - * both sqrt() and divide operation. - */ -static codel_time_t codel_control_law(codel_time_t t, - codel_time_t interval, - u32 rec_inv_sqrt) -{ - return t + reciprocal_divide(interval, rec_inv_sqrt << REC_INV_SQRT_SHIFT); -} - - -static bool codel_should_drop(const struct sk_buff *skb, - struct Qdisc *sch, - struct codel_vars *vars, - struct codel_params *params, - struct codel_stats *stats, - codel_time_t now) -{ - bool ok_to_drop; - - if (!skb) { - vars->first_above_time = 0; - return false; - } - - vars->ldelay = now - codel_get_enqueue_time(skb); - sch->qstats.backlog -= qdisc_pkt_len(skb); - - if (unlikely(qdisc_pkt_len(skb) > stats->maxpacket)) - stats->maxpacket = qdisc_pkt_len(skb); - - if (codel_time_before(vars->ldelay, params->target) || - sch->qstats.backlog <= stats->maxpacket) { - /* went below - stay below for at least interval */ - vars->first_above_time = 0; - return false; - } - ok_to_drop = false; - if (vars->first_above_time == 0) { - /* just went above from below. If we stay above - * for at least interval we'll say it's ok to drop - */ - vars->first_above_time = now + params->interval; - } else if (codel_time_after(now, vars->first_above_time)) { - ok_to_drop = true; - } - return ok_to_drop; -} - -typedef struct sk_buff * (*codel_skb_dequeue_t)(struct codel_vars *vars, - struct Qdisc *sch); - -static struct sk_buff *codel_dequeue(struct Qdisc *sch, - struct codel_params *params, - struct codel_vars *vars, - struct codel_stats *stats, - codel_skb_dequeue_t dequeue_func) -{ - struct sk_buff *skb = dequeue_func(vars, sch); - codel_time_t now; - bool drop; - - if (!skb) { - vars->dropping = false; - return skb; - } - now = codel_get_time(); - drop = codel_should_drop(skb, sch, vars, params, stats, now); - if (vars->dropping) { - if (!drop) { - /* sojourn time below target - leave dropping state */ - vars->dropping = false; - } else if (codel_time_after_eq(now, vars->drop_next)) { - /* It's time for the next drop. Drop the current - * packet and dequeue the next. The dequeue might - * take us out of dropping state. - * If not, schedule the next drop. - * A large backlog might result in drop rates so high - * that the next drop should happen now, - * hence the while loop. - */ - while (vars->dropping && - codel_time_after_eq(now, vars->drop_next)) { - vars->count++; /* dont care of possible wrap - * since there is no more divide - */ - codel_Newton_step(vars); - if (params->ecn && INET_ECN_set_ce(skb)) { - stats->ecn_mark++; - vars->drop_next = - codel_control_law(vars->drop_next, - params->interval, - vars->rec_inv_sqrt); - goto end; - } - qdisc_drop(skb, sch); - stats->drop_count++; - skb = dequeue_func(vars, sch); - if (!codel_should_drop(skb, sch, - vars, params, stats, now)) { - /* leave dropping state */ - vars->dropping = false; - } else { - /* and schedule the next drop */ - vars->drop_next = - codel_control_law(vars->drop_next, - params->interval, - vars->rec_inv_sqrt); - } - } - } - } else if (drop) { - if (params->ecn && INET_ECN_set_ce(skb)) { - stats->ecn_mark++; - } else { - qdisc_drop(skb, sch); - stats->drop_count++; - - skb = dequeue_func(vars, sch); - drop = codel_should_drop(skb, sch, vars, params, - stats, now); - } - vars->dropping = true; - /* if min went above target close to when we last went below it - * assume that the drop rate that controlled the queue on the - * last cycle is a good starting point to control it now. - */ - if (codel_time_before(now - vars->drop_next, - 16 * params->interval)) { - vars->count = (vars->count - vars->lastcount) | 1; - /* we dont care if rec_inv_sqrt approximation - * is not very precise : - * Next Newton steps will correct it quadratically. - */ - codel_Newton_step(vars); - } else { - vars->count = 1; - vars->rec_inv_sqrt = ~0U >> REC_INV_SQRT_SHIFT; - } - vars->lastcount = vars->count; - vars->drop_next = codel_control_law(now, params->interval, - vars->rec_inv_sqrt); - } -end: - return skb; -} -#endif diff --git a/trunk/include/net/ieee802154_netdev.h b/trunk/include/net/ieee802154_netdev.h index d104c882fc29..57430555487a 100644 --- a/trunk/include/net/ieee802154_netdev.h +++ b/trunk/include/net/ieee802154_netdev.h @@ -1,7 +1,7 @@ /* * An interface between IEEE802.15.4 device and rest of the kernel. * - * Copyright (C) 2007-2012 Siemens AG + * Copyright (C) 2007, 2008, 2009 Siemens AG * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -21,14 +21,11 @@ * Maxim Gorbachyov * Maxim Osipov * Dmitry Eremin-Solenikov - * Alexander Smirnov */ #ifndef IEEE802154_NETDEVICE_H #define IEEE802154_NETDEVICE_H -#include - /* * A control block of skb passed between the ARPHRD_IEEE802154 device * and other stack parts. @@ -113,26 +110,12 @@ struct ieee802154_mlme_ops { u8 (*get_bsn)(const struct net_device *dev); }; -/* The IEEE 802.15.4 standard defines 2 type of the devices: - * - FFD - full functionality device - * - RFD - reduce functionality device - * - * So 2 sets of mlme operations are needed - */ -struct ieee802154_reduced_mlme_ops { - struct wpan_phy *(*get_phy)(const struct net_device *dev); -}; - -static inline struct ieee802154_mlme_ops * -ieee802154_mlme_ops(const struct net_device *dev) -{ - return dev->ml_priv; -} - -static inline struct ieee802154_reduced_mlme_ops * -ieee802154_reduced_mlme_ops(const struct net_device *dev) +static inline struct ieee802154_mlme_ops *ieee802154_mlme_ops( + const struct net_device *dev) { return dev->ml_priv; } #endif + + diff --git a/trunk/include/net/if_inet6.h b/trunk/include/net/if_inet6.h index 93563221d29a..50f325fd0691 100644 --- a/trunk/include/net/if_inet6.h +++ b/trunk/include/net/if_inet6.h @@ -209,6 +209,60 @@ static inline void ipv6_eth_mc_map(const struct in6_addr *addr, char *buf) memcpy(buf + 2, &addr->s6_addr32[3], sizeof(__u32)); } +static inline void ipv6_tr_mc_map(const struct in6_addr *addr, char *buf) +{ + /* All nodes FF01::1, FF02::1, FF02::1:FFxx:xxxx */ + + if (((addr->s6_addr[0] == 0xFF) && + ((addr->s6_addr[1] == 0x01) || (addr->s6_addr[1] == 0x02)) && + (addr->s6_addr16[1] == 0) && + (addr->s6_addr32[1] == 0) && + (addr->s6_addr32[2] == 0) && + (addr->s6_addr16[6] == 0) && + (addr->s6_addr[15] == 1)) || + ((addr->s6_addr[0] == 0xFF) && + (addr->s6_addr[1] == 0x02) && + (addr->s6_addr16[1] == 0) && + (addr->s6_addr32[1] == 0) && + (addr->s6_addr16[4] == 0) && + (addr->s6_addr[10] == 0) && + (addr->s6_addr[11] == 1) && + (addr->s6_addr[12] == 0xff))) + { + buf[0]=0xC0; + buf[1]=0x00; + buf[2]=0x01; + buf[3]=0x00; + buf[4]=0x00; + buf[5]=0x00; + /* All routers FF0x::2 */ + } else if ((addr->s6_addr[0] ==0xff) && + ((addr->s6_addr[1] & 0xF0) == 0) && + (addr->s6_addr16[1] == 0) && + (addr->s6_addr32[1] == 0) && + (addr->s6_addr32[2] == 0) && + (addr->s6_addr16[6] == 0) && + (addr->s6_addr[15] == 2)) + { + buf[0]=0xC0; + buf[1]=0x00; + buf[2]=0x02; + buf[3]=0x00; + buf[4]=0x00; + buf[5]=0x00; + } else { + unsigned char i ; + + i = addr->s6_addr[15] & 7 ; + buf[0]=0xC0; + buf[1]=0x00; + buf[2]=0x00; + buf[3]=0x01 << i ; + buf[4]=0x00; + buf[5]=0x00; + } +} + static inline void ipv6_arcnet_mc_map(const struct in6_addr *addr, char *buf) { buf[0] = 0x00; diff --git a/trunk/include/net/inet_frag.h b/trunk/include/net/inet_frag.h index 2431cf83aeca..16ff29a7bb30 100644 --- a/trunk/include/net/inet_frag.h +++ b/trunk/include/net/inet_frag.h @@ -46,7 +46,8 @@ struct inet_frags { void *arg); void (*destructor)(struct inet_frag_queue *); void (*skb_free)(struct sk_buff *); - bool (*match)(struct inet_frag_queue *q, void *arg); + int (*match)(struct inet_frag_queue *q, + void *arg); void (*frag_expire)(unsigned long data); }; diff --git a/trunk/include/net/ip.h b/trunk/include/net/ip.h index 83e0619f59d0..94ddb69cc0f3 100644 --- a/trunk/include/net/ip.h +++ b/trunk/include/net/ip.h @@ -141,6 +141,23 @@ static inline struct sk_buff *ip_finish_skb(struct sock *sk, struct flowi4 *fl4) extern int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len); +/* + * Map a multicast IP onto multicast MAC for type Token Ring. + * This conforms to RFC1469 Option 2 Multicasting i.e. + * using a functional address to transmit / receive + * multicast packets. + */ + +static inline void ip_tr_mc_map(__be32 addr, char *buf) +{ + buf[0]=0xC0; + buf[1]=0x00; + buf[2]=0x00; + buf[3]=0x04; + buf[4]=0x00; + buf[5]=0x00; +} + struct ip_reply_arg { struct kvec iov[1]; int flags; diff --git a/trunk/include/net/ip6_route.h b/trunk/include/net/ip6_route.h index 37c1a1ed82c1..c062b6773cc7 100644 --- a/trunk/include/net/ip6_route.h +++ b/trunk/include/net/ip6_route.h @@ -175,7 +175,7 @@ static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst, spin_unlock(&sk->sk_dst_lock); } -static inline bool ipv6_unicast_destination(const struct sk_buff *skb) +static inline int ipv6_unicast_destination(struct sk_buff *skb) { struct rt6_info *rt = (struct rt6_info *) skb_dst(skb); diff --git a/trunk/include/net/ipv6.h b/trunk/include/net/ipv6.h index aecf88436abf..4332e9aad853 100644 --- a/trunk/include/net/ipv6.h +++ b/trunk/include/net/ipv6.h @@ -263,7 +263,7 @@ extern struct ipv6_txoptions * ipv6_renew_options(struct sock *sk, struct ipv6_t struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space, struct ipv6_txoptions *opt); -extern bool ipv6_opt_accepted(const struct sock *sk, const struct sk_buff *skb); +extern int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb); int ip6_frag_nqueues(struct net *net); int ip6_frag_mem(struct net *net); @@ -332,8 +332,8 @@ static inline void ipv6_addr_set(struct in6_addr *addr, addr->s6_addr32[3] = w4; } -static inline bool ipv6_addr_equal(const struct in6_addr *a1, - const struct in6_addr *a2) +static inline int ipv6_addr_equal(const struct in6_addr *a1, + const struct in6_addr *a2) { return ((a1->s6_addr32[0] ^ a2->s6_addr32[0]) | (a1->s6_addr32[1] ^ a2->s6_addr32[1]) | @@ -341,27 +341,27 @@ static inline bool ipv6_addr_equal(const struct in6_addr *a1, (a1->s6_addr32[3] ^ a2->s6_addr32[3])) == 0; } -static inline bool __ipv6_prefix_equal(const __be32 *a1, const __be32 *a2, - unsigned int prefixlen) +static inline int __ipv6_prefix_equal(const __be32 *a1, const __be32 *a2, + unsigned int prefixlen) { unsigned int pdw, pbi; /* check complete u32 in prefix */ pdw = prefixlen >> 5; if (pdw && memcmp(a1, a2, pdw << 2)) - return false; + return 0; /* check incomplete u32 in prefix */ pbi = prefixlen & 0x1f; if (pbi && ((a1[pdw] ^ a2[pdw]) & htonl((0xffffffff) << (32 - pbi)))) - return false; + return 0; - return true; + return 1; } -static inline bool ipv6_prefix_equal(const struct in6_addr *a1, - const struct in6_addr *a2, - unsigned int prefixlen) +static inline int ipv6_prefix_equal(const struct in6_addr *a1, + const struct in6_addr *a2, + unsigned int prefixlen) { return __ipv6_prefix_equal(a1->s6_addr32, a2->s6_addr32, prefixlen); @@ -387,21 +387,21 @@ struct ip6_create_arg { }; void ip6_frag_init(struct inet_frag_queue *q, void *a); -bool ip6_frag_match(struct inet_frag_queue *q, void *a); +int ip6_frag_match(struct inet_frag_queue *q, void *a); -static inline bool ipv6_addr_any(const struct in6_addr *a) +static inline int ipv6_addr_any(const struct in6_addr *a) { return (a->s6_addr32[0] | a->s6_addr32[1] | a->s6_addr32[2] | a->s6_addr32[3]) == 0; } -static inline bool ipv6_addr_loopback(const struct in6_addr *a) +static inline int ipv6_addr_loopback(const struct in6_addr *a) { return (a->s6_addr32[0] | a->s6_addr32[1] | a->s6_addr32[2] | (a->s6_addr32[3] ^ htonl(1))) == 0; } -static inline bool ipv6_addr_v4mapped(const struct in6_addr *a) +static inline int ipv6_addr_v4mapped(const struct in6_addr *a) { return (a->s6_addr32[0] | a->s6_addr32[1] | (a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0; @@ -411,7 +411,7 @@ static inline bool ipv6_addr_v4mapped(const struct in6_addr *a) * Check for a RFC 4843 ORCHID address * (Overlay Routable Cryptographic Hash Identifiers) */ -static inline bool ipv6_addr_orchid(const struct in6_addr *a) +static inline int ipv6_addr_orchid(const struct in6_addr *a) { return (a->s6_addr32[0] & htonl(0xfffffff0)) == htonl(0x20010010); } @@ -559,7 +559,7 @@ extern void ipv6_push_frag_opts(struct sk_buff *skb, extern int ipv6_skip_exthdr(const struct sk_buff *, int start, u8 *nexthdrp, __be16 *frag_offp); -extern bool ipv6_ext_hdr(u8 nexthdr); +extern int ipv6_ext_hdr(u8 nexthdr); extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type); diff --git a/trunk/include/net/lapb.h b/trunk/include/net/lapb.h index df892a94f2c6..fd2bf572ee1d 100644 --- a/trunk/include/net/lapb.h +++ b/trunk/include/net/lapb.h @@ -149,10 +149,4 @@ extern int lapb_t1timer_running(struct lapb_cb *lapb); */ #define LAPB_DEBUG 0 -#define lapb_dbg(level, fmt, ...) \ -do { \ - if (level < LAPB_DEBUG) \ - pr_debug(fmt, ##__VA_ARGS__); \ -} while (0) - #endif diff --git a/trunk/include/net/llc_pdu.h b/trunk/include/net/llc_pdu.h index 5a93d13ac95c..f57e7d46a453 100644 --- a/trunk/include/net/llc_pdu.h +++ b/trunk/include/net/llc_pdu.h @@ -13,6 +13,7 @@ */ #include +#include /* Lengths of frame formats */ #define LLC_PDU_LEN_I 4 /* header and 2 control bytes */ @@ -252,6 +253,10 @@ static inline void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa) { if (skb->protocol == htons(ETH_P_802_2)) memcpy(sa, eth_hdr(skb)->h_source, ETH_ALEN); + else if (skb->protocol == htons(ETH_P_TR_802_2)) { + memcpy(sa, tr_hdr(skb)->saddr, ETH_ALEN); + *sa &= 0x7F; + } } /** @@ -265,6 +270,8 @@ static inline void llc_pdu_decode_da(struct sk_buff *skb, u8 *da) { if (skb->protocol == htons(ETH_P_802_2)) memcpy(da, eth_hdr(skb)->h_dest, ETH_ALEN); + else if (skb->protocol == htons(ETH_P_TR_802_2)) + memcpy(da, tr_hdr(skb)->daddr, ETH_ALEN); } /** diff --git a/trunk/include/net/mac802154.h b/trunk/include/net/mac802154.h deleted file mode 100644 index c9f8ab5cc687..000000000000 --- a/trunk/include/net/mac802154.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * IEEE802.15.4-2003 specification - * - * Copyright (C) 2007-2012 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef NET_MAC802154_H -#define NET_MAC802154_H - -#include - -/* The following flags are used to indicate changed address settings from - * the stack to the hardware. - */ - -/* indicates that the Short Address changed */ -#define IEEE802515_AFILT_SADDR_CHANGED 0x00000001 -/* indicates that the IEEE Address changed */ -#define IEEE802515_AFILT_IEEEADDR_CHANGED 0x00000002 -/* indicates that the PAN ID changed */ -#define IEEE802515_AFILT_PANID_CHANGED 0x00000004 -/* indicates that PAN Coordinator status changed */ -#define IEEE802515_AFILT_PANC_CHANGED 0x00000008 - -struct ieee802154_hw_addr_filt { - __le16 pan_id; /* Each independent PAN selects a unique - * identifier. This PAN id allows communication - * between devices within a network using short - * addresses and enables transmissions between - * devices across independent networks. - */ - __le16 short_addr; - u8 ieee_addr[IEEE802154_ADDR_LEN]; - u8 pan_coord; -}; - -struct ieee802154_dev { - /* filled by the driver */ - int extra_tx_headroom; - u32 flags; - struct device *parent; - - /* filled by mac802154 core */ - struct ieee802154_hw_addr_filt hw_filt; - void *priv; - struct wpan_phy *phy; -}; - -/* Checksum is in hardware and is omitted from a packet - * - * These following flags are used to indicate hardware capabilities to - * the stack. Generally, flags here should have their meaning - * done in a way that the simplest hardware doesn't need setting - * any particular flags. There are some exceptions to this rule, - * however, so you are advised to review these flags carefully. - */ - -/* Indicates that receiver omits FCS and xmitter will add FCS on it's own. */ -#define IEEE802154_HW_OMIT_CKSUM 0x00000001 -/* Indicates that receiver will autorespond with ACK frames. */ -#define IEEE802154_HW_AACK 0x00000002 - -/* struct ieee802154_ops - callbacks from mac802154 to the driver - * - * This structure contains various callbacks that the driver may - * handle or, in some cases, must handle, for example to transmit - * a frame. - * - * start: Handler that 802.15.4 module calls for device initialization. - * This function is called before the first interface is attached. - * - * stop: Handler that 802.15.4 module calls for device cleanup. - * This function is called after the last interface is removed. - * - * xmit: Handler that 802.15.4 module calls for each transmitted frame. - * skb cntains the buffer starting from the IEEE 802.15.4 header. - * The low-level driver should send the frame based on available - * configuration. - * This function should return zero or negative errno. Called with - * pib_lock held. - * - * ed: Handler that 802.15.4 module calls for Energy Detection. - * This function should place the value for detected energy - * (usually device-dependant) in the level pointer and return - * either zero or negative errno. Called with pib_lock held. - * - * set_channel: - * Set radio for listening on specific channel. - * Set the device for listening on specified channel. - * Returns either zero, or negative errno. Called with pib_lock held. - * - * set_hw_addr_filt: - * Set radio for listening on specific address. - * Set the device for listening on specified address. - * Returns either zero, or negative errno. - */ -struct ieee802154_ops { - struct module *owner; - int (*start)(struct ieee802154_dev *dev); - void (*stop)(struct ieee802154_dev *dev); - int (*xmit)(struct ieee802154_dev *dev, - struct sk_buff *skb); - int (*ed)(struct ieee802154_dev *dev, u8 *level); - int (*set_channel)(struct ieee802154_dev *dev, - int page, - int channel); - int (*set_hw_addr_filt)(struct ieee802154_dev *dev, - struct ieee802154_hw_addr_filt *filt, - unsigned long changed); - int (*ieee_addr)(struct ieee802154_dev *dev, - u8 addr[IEEE802154_ADDR_LEN]); -}; - -/* Basic interface to register ieee802154 device */ -struct ieee802154_dev * -ieee802154_alloc_device(size_t priv_data_lex, struct ieee802154_ops *ops); -void ieee802154_free_device(struct ieee802154_dev *dev); -int ieee802154_register_device(struct ieee802154_dev *dev); -void ieee802154_unregister_device(struct ieee802154_dev *dev); - -void ieee802154_rx_irqsafe(struct ieee802154_dev *dev, struct sk_buff *skb, - u8 lqi); - -#endif /* NET_MAC802154_H */ diff --git a/trunk/include/net/rawv6.h b/trunk/include/net/rawv6.h index e7ea660e4db6..cf7577234457 100644 --- a/trunk/include/net/rawv6.h +++ b/trunk/include/net/rawv6.h @@ -5,7 +5,7 @@ void raw6_icmp_error(struct sk_buff *, int nexthdr, u8 type, u8 code, int inner_offset, __be32); -bool raw6_local_deliver(struct sk_buff *, int); +int raw6_local_deliver(struct sk_buff *, int); extern int rawv6_rcv(struct sock *sk, struct sk_buff *skb); diff --git a/trunk/include/net/sctp/sctp.h b/trunk/include/net/sctp/sctp.h index a2ef81466b00..6ee44b24864a 100644 --- a/trunk/include/net/sctp/sctp.h +++ b/trunk/include/net/sctp/sctp.h @@ -704,17 +704,4 @@ static inline void sctp_v4_map_v6(union sctp_addr *addr) addr->v6.sin6_addr.s6_addr32[2] = htonl(0x0000ffff); } -/* The cookie is always 0 since this is how it's used in the - * pmtu code. - */ -static inline struct dst_entry *sctp_transport_dst_check(struct sctp_transport *t) -{ - if (t->dst && !dst_check(t->dst, 0)) { - dst_release(t->dst); - t->dst = NULL; - } - - return t->dst; -} - #endif /* __net_sctp_h__ */ diff --git a/trunk/include/net/sock.h b/trunk/include/net/sock.h index da931555e000..e613704e9d1c 100644 --- a/trunk/include/net/sock.h +++ b/trunk/include/net/sock.h @@ -97,7 +97,7 @@ void mem_cgroup_sockets_destroy(struct cgroup *cgrp) #else /* Validate arguments and do nothing */ static inline __printf(2, 3) -void SOCK_DEBUG(const struct sock *sk, const char *msg, ...) +void SOCK_DEBUG(struct sock *sk, const char *msg, ...) { } #endif @@ -372,8 +372,8 @@ struct sock { void (*sk_data_ready)(struct sock *sk, int bytes); void (*sk_write_space)(struct sock *sk); void (*sk_error_report)(struct sock *sk); - int (*sk_backlog_rcv)(struct sock *sk, - struct sk_buff *skb); + int (*sk_backlog_rcv)(struct sock *sk, + struct sk_buff *skb); void (*sk_destruct)(struct sock *sk); }; @@ -454,40 +454,40 @@ static inline struct sock *sk_nulls_next(const struct sock *sk) NULL; } -static inline bool sk_unhashed(const struct sock *sk) +static inline int sk_unhashed(const struct sock *sk) { return hlist_unhashed(&sk->sk_node); } -static inline bool sk_hashed(const struct sock *sk) +static inline int sk_hashed(const struct sock *sk) { return !sk_unhashed(sk); } -static inline void sk_node_init(struct hlist_node *node) +static __inline__ void sk_node_init(struct hlist_node *node) { node->pprev = NULL; } -static inline void sk_nulls_node_init(struct hlist_nulls_node *node) +static __inline__ void sk_nulls_node_init(struct hlist_nulls_node *node) { node->pprev = NULL; } -static inline void __sk_del_node(struct sock *sk) +static __inline__ void __sk_del_node(struct sock *sk) { __hlist_del(&sk->sk_node); } /* NB: equivalent to hlist_del_init_rcu */ -static inline bool __sk_del_node_init(struct sock *sk) +static __inline__ int __sk_del_node_init(struct sock *sk) { if (sk_hashed(sk)) { __sk_del_node(sk); sk_node_init(&sk->sk_node); - return true; + return 1; } - return false; + return 0; } /* Grab socket reference count. This operation is valid only @@ -509,9 +509,9 @@ static inline void __sock_put(struct sock *sk) atomic_dec(&sk->sk_refcnt); } -static inline bool sk_del_node_init(struct sock *sk) +static __inline__ int sk_del_node_init(struct sock *sk) { - bool rc = __sk_del_node_init(sk); + int rc = __sk_del_node_init(sk); if (rc) { /* paranoid for a while -acme */ @@ -522,18 +522,18 @@ static inline bool sk_del_node_init(struct sock *sk) } #define sk_del_node_init_rcu(sk) sk_del_node_init(sk) -static inline bool __sk_nulls_del_node_init_rcu(struct sock *sk) +static __inline__ int __sk_nulls_del_node_init_rcu(struct sock *sk) { if (sk_hashed(sk)) { hlist_nulls_del_init_rcu(&sk->sk_nulls_node); - return true; + return 1; } - return false; + return 0; } -static inline bool sk_nulls_del_node_init_rcu(struct sock *sk) +static __inline__ int sk_nulls_del_node_init_rcu(struct sock *sk) { - bool rc = __sk_nulls_del_node_init_rcu(sk); + int rc = __sk_nulls_del_node_init_rcu(sk); if (rc) { /* paranoid for a while -acme */ @@ -543,40 +543,40 @@ static inline bool sk_nulls_del_node_init_rcu(struct sock *sk) return rc; } -static inline void __sk_add_node(struct sock *sk, struct hlist_head *list) +static __inline__ void __sk_add_node(struct sock *sk, struct hlist_head *list) { hlist_add_head(&sk->sk_node, list); } -static inline void sk_add_node(struct sock *sk, struct hlist_head *list) +static __inline__ void sk_add_node(struct sock *sk, struct hlist_head *list) { sock_hold(sk); __sk_add_node(sk, list); } -static inline void sk_add_node_rcu(struct sock *sk, struct hlist_head *list) +static __inline__ void sk_add_node_rcu(struct sock *sk, struct hlist_head *list) { sock_hold(sk); hlist_add_head_rcu(&sk->sk_node, list); } -static inline void __sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_head *list) +static __inline__ void __sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_head *list) { hlist_nulls_add_head_rcu(&sk->sk_nulls_node, list); } -static inline void sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_head *list) +static __inline__ void sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_head *list) { sock_hold(sk); __sk_nulls_add_node_rcu(sk, list); } -static inline void __sk_del_bind_node(struct sock *sk) +static __inline__ void __sk_del_bind_node(struct sock *sk) { __hlist_del(&sk->sk_bind_node); } -static inline void sk_add_bind_node(struct sock *sk, +static __inline__ void sk_add_bind_node(struct sock *sk, struct hlist_head *list) { hlist_add_head(&sk->sk_bind_node, list); @@ -650,7 +650,7 @@ static inline void sock_reset_flag(struct sock *sk, enum sock_flags flag) __clear_bit(flag, &sk->sk_flags); } -static inline bool sock_flag(const struct sock *sk, enum sock_flags flag) +static inline int sock_flag(struct sock *sk, enum sock_flags flag) { return test_bit(flag, &sk->sk_flags); } @@ -665,7 +665,7 @@ static inline void sk_acceptq_added(struct sock *sk) sk->sk_ack_backlog++; } -static inline bool sk_acceptq_is_full(const struct sock *sk) +static inline int sk_acceptq_is_full(struct sock *sk) { return sk->sk_ack_backlog > sk->sk_max_ack_backlog; } @@ -673,19 +673,19 @@ static inline bool sk_acceptq_is_full(const struct sock *sk) /* * Compute minimal free write space needed to queue new packets. */ -static inline int sk_stream_min_wspace(const struct sock *sk) +static inline int sk_stream_min_wspace(struct sock *sk) { return sk->sk_wmem_queued >> 1; } -static inline int sk_stream_wspace(const struct sock *sk) +static inline int sk_stream_wspace(struct sock *sk) { return sk->sk_sndbuf - sk->sk_wmem_queued; } extern void sk_stream_write_space(struct sock *sk); -static inline bool sk_stream_memory_free(const struct sock *sk) +static inline int sk_stream_memory_free(struct sock *sk) { return sk->sk_wmem_queued < sk->sk_sndbuf; } @@ -809,26 +809,26 @@ struct module; * transport -> network interface is defined by struct inet_proto */ struct proto { - void (*close)(struct sock *sk, + void (*close)(struct sock *sk, long timeout); int (*connect)(struct sock *sk, - struct sockaddr *uaddr, + struct sockaddr *uaddr, int addr_len); int (*disconnect)(struct sock *sk, int flags); - struct sock * (*accept)(struct sock *sk, int flags, int *err); + struct sock * (*accept) (struct sock *sk, int flags, int *err); int (*ioctl)(struct sock *sk, int cmd, unsigned long arg); int (*init)(struct sock *sk); void (*destroy)(struct sock *sk); void (*shutdown)(struct sock *sk, int how); - int (*setsockopt)(struct sock *sk, int level, + int (*setsockopt)(struct sock *sk, int level, int optname, char __user *optval, unsigned int optlen); - int (*getsockopt)(struct sock *sk, int level, - int optname, char __user *optval, - int __user *option); + int (*getsockopt)(struct sock *sk, int level, + int optname, char __user *optval, + int __user *option); #ifdef CONFIG_COMPAT int (*compat_setsockopt)(struct sock *sk, int level, @@ -845,14 +845,14 @@ struct proto { struct msghdr *msg, size_t len); int (*recvmsg)(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, - size_t len, int noblock, int flags, - int *addr_len); + size_t len, int noblock, int flags, + int *addr_len); int (*sendpage)(struct sock *sk, struct page *page, int offset, size_t size, int flags); - int (*bind)(struct sock *sk, + int (*bind)(struct sock *sk, struct sockaddr *uaddr, int addr_len); - int (*backlog_rcv) (struct sock *sk, + int (*backlog_rcv) (struct sock *sk, struct sk_buff *skb); /* Keeping track of sk's, looking them up, and port selection methods. */ @@ -1173,7 +1173,7 @@ proto_memory_pressure(struct proto *prot) extern void sock_prot_inuse_add(struct net *net, struct proto *prot, int inc); extern int sock_prot_inuse_get(struct net *net, struct proto *proto); #else -static inline void sock_prot_inuse_add(struct net *net, struct proto *prot, +static void inline sock_prot_inuse_add(struct net *net, struct proto *prot, int inc) { } @@ -1260,24 +1260,24 @@ static inline int sk_mem_pages(int amt) return (amt + SK_MEM_QUANTUM - 1) >> SK_MEM_QUANTUM_SHIFT; } -static inline bool sk_has_account(struct sock *sk) +static inline int sk_has_account(struct sock *sk) { /* return true if protocol supports memory accounting */ return !!sk->sk_prot->memory_allocated; } -static inline bool sk_wmem_schedule(struct sock *sk, int size) +static inline int sk_wmem_schedule(struct sock *sk, int size) { if (!sk_has_account(sk)) - return true; + return 1; return size <= sk->sk_forward_alloc || __sk_mem_schedule(sk, size, SK_MEM_SEND); } -static inline bool sk_rmem_schedule(struct sock *sk, int size) +static inline int sk_rmem_schedule(struct sock *sk, int size) { if (!sk_has_account(sk)) - return true; + return 1; return size <= sk->sk_forward_alloc || __sk_mem_schedule(sk, size, SK_MEM_RECV); } @@ -1342,7 +1342,7 @@ static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb) * Mark both the sk_lock and the sk_lock.slock as a * per-address-family lock class. */ -#define sock_lock_init_class_and_name(sk, sname, skey, name, key) \ +#define sock_lock_init_class_and_name(sk, sname, skey, name, key) \ do { \ sk->sk_lock.owned = 0; \ init_waitqueue_head(&sk->sk_lock.wq); \ @@ -1350,7 +1350,7 @@ do { \ debug_check_no_locks_freed((void *)&(sk)->sk_lock, \ sizeof((sk)->sk_lock)); \ lockdep_set_class_and_name(&(sk)->sk_lock.slock, \ - (skey), (sname)); \ + (skey), (sname)); \ lockdep_init_map(&(sk)->sk_lock.dep_map, (name), (key), 0); \ } while (0) @@ -1410,13 +1410,13 @@ extern int sock_setsockopt(struct socket *sock, int level, unsigned int optlen); extern int sock_getsockopt(struct socket *sock, int level, - int op, char __user *optval, + int op, char __user *optval, int __user *optlen); -extern struct sk_buff *sock_alloc_send_skb(struct sock *sk, +extern struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, int noblock, int *errcode); -extern struct sk_buff *sock_alloc_send_pskb(struct sock *sk, +extern struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len, unsigned long data_len, int noblock, @@ -1438,7 +1438,7 @@ static inline void sock_update_classid(struct sock *sk) * Functions to fill in entries in struct proto_ops when a protocol * does not implement a particular function. */ -extern int sock_no_bind(struct socket *, +extern int sock_no_bind(struct socket *, struct sockaddr *, int); extern int sock_no_connect(struct socket *, struct sockaddr *, int, int); @@ -1467,7 +1467,7 @@ extern int sock_no_mmap(struct file *file, struct vm_area_struct *vma); extern ssize_t sock_no_sendpage(struct socket *sock, struct page *page, - int offset, size_t size, + int offset, size_t size, int flags); /* @@ -1490,7 +1490,7 @@ extern void sk_common_release(struct sock *sk); /* * Default socket callbacks and setup code */ - + /* Initialise core socket variables */ extern void sock_init_data(struct socket *sock, struct sock *sk); @@ -1690,7 +1690,7 @@ extern struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie); extern struct dst_entry *sk_dst_check(struct sock *sk, u32 cookie); -static inline bool sk_can_gso(const struct sock *sk) +static inline int sk_can_gso(const struct sock *sk) { return net_gso_ok(sk->sk_route_caps, sk->sk_gso_type); } @@ -1807,7 +1807,7 @@ static inline int sk_rmem_alloc_get(const struct sock *sk) * * Returns true if socket has write or read allocations */ -static inline bool sk_has_allocations(const struct sock *sk) +static inline int sk_has_allocations(const struct sock *sk) { return sk_wmem_alloc_get(sk) || sk_rmem_alloc_get(sk); } @@ -1846,7 +1846,9 @@ static inline bool sk_has_allocations(const struct sock *sk) */ static inline bool wq_has_sleeper(struct socket_wq *wq) { - /* We need to be sure we are in sync with the + + /* + * We need to be sure we are in sync with the * add_wait_queue modifications to the wait queue. * * This memory barrier is paired in the sock_poll_wait. @@ -1868,21 +1870,22 @@ static inline void sock_poll_wait(struct file *filp, { if (!poll_does_not_wait(p) && wait_address) { poll_wait(filp, wait_address, p); - /* We need to be sure we are in sync with the + /* + * We need to be sure we are in sync with the * socket flags modification. * * This memory barrier is paired in the wq_has_sleeper. - */ + */ smp_mb(); } } /* - * Queue a received datagram if it will fit. Stream and sequenced + * Queue a received datagram if it will fit. Stream and sequenced * protocols can't normally use this as they need to fit buffers in * and play with them. * - * Inlined as it's very short and called for pretty much every + * Inlined as it's very short and called for pretty much every * packet ever received. */ @@ -1908,10 +1911,10 @@ static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk) sk_mem_charge(sk, skb->truesize); } -extern void sk_reset_timer(struct sock *sk, struct timer_list *timer, +extern void sk_reset_timer(struct sock *sk, struct timer_list* timer, unsigned long expires); -extern void sk_stop_timer(struct sock *sk, struct timer_list *timer); +extern void sk_stop_timer(struct sock *sk, struct timer_list* timer); extern int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); @@ -1920,7 +1923,7 @@ extern int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb); /* * Recover an error report and clear atomically */ - + static inline int sock_error(struct sock *sk) { int err; @@ -1936,7 +1939,7 @@ static inline unsigned long sock_wspace(struct sock *sk) if (!(sk->sk_shutdown & SEND_SHUTDOWN)) { amt = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); - if (amt < 0) + if (amt < 0) amt = 0; } return amt; @@ -1980,7 +1983,7 @@ static inline struct page *sk_stream_alloc_page(struct sock *sk) /* * Default write policy as shown to user space via poll/select/SIGIO */ -static inline bool sock_writeable(const struct sock *sk) +static inline int sock_writeable(const struct sock *sk) { return atomic_read(&sk->sk_wmem_alloc) < (sk->sk_sndbuf >> 1); } @@ -1990,12 +1993,12 @@ static inline gfp_t gfp_any(void) return in_softirq() ? GFP_ATOMIC : GFP_KERNEL; } -static inline long sock_rcvtimeo(const struct sock *sk, bool noblock) +static inline long sock_rcvtimeo(const struct sock *sk, int noblock) { return noblock ? 0 : sk->sk_rcvtimeo; } -static inline long sock_sndtimeo(const struct sock *sk, bool noblock) +static inline long sock_sndtimeo(const struct sock *sk, int noblock) { return noblock ? 0 : sk->sk_sndtimeo; } @@ -2018,7 +2021,7 @@ extern void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, extern void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk, struct sk_buff *skb); -static inline void +static __inline__ void sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) { ktime_t kt = skb->tstamp; @@ -2059,7 +2062,7 @@ static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, (1UL << SOCK_RCVTSTAMP) | \ (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE) | \ (1UL << SOCK_TIMESTAMPING_SOFTWARE) | \ - (1UL << SOCK_TIMESTAMPING_RAW_HARDWARE) | \ + (1UL << SOCK_TIMESTAMPING_RAW_HARDWARE) | \ (1UL << SOCK_TIMESTAMPING_SYS_HARDWARE)) if (sk->sk_flags & FLAGS_TS_OR_DROPS) @@ -2088,7 +2091,7 @@ extern int sock_tx_timestamp(struct sock *sk, __u8 *tx_flags); * locked so that the sk_buff queue operation is ok. */ #ifdef CONFIG_NET_DMA -static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb, bool copied_early) +static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb, int copied_early) { __skb_unlink(skb, &sk->sk_receive_queue); if (!copied_early) @@ -2097,7 +2100,7 @@ static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb, bool copied_ __skb_queue_tail(&sk->sk_async_wait_queue, skb); } #else -static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb, bool copied_early) +static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb, int copied_early) { __skb_unlink(skb, &sk->sk_receive_queue); __kfree_skb(skb); @@ -2144,8 +2147,8 @@ extern void sock_enable_timestamp(struct sock *sk, int flag); extern int sock_get_timestamp(struct sock *, struct timeval __user *); extern int sock_get_timestampns(struct sock *, struct timespec __user *); -/* - * Enable debug/info messages +/* + * Enable debug/info messages */ extern int net_msg_warn; #define NETDEBUG(fmt, args...) \ diff --git a/trunk/include/net/tcp.h b/trunk/include/net/tcp.h index e79aa48d9fc1..92faa6a7ea97 100644 --- a/trunk/include/net/tcp.h +++ b/trunk/include/net/tcp.h @@ -263,14 +263,14 @@ extern int tcp_memory_pressure; * and worry about wraparound (automatic with unsigned arithmetic). */ -static inline bool before(__u32 seq1, __u32 seq2) +static inline int before(__u32 seq1, __u32 seq2) { return (__s32)(seq1-seq2) < 0; } #define after(seq2, seq1) before(seq1, seq2) /* is s2<=s1<=s3 ? */ -static inline bool between(__u32 seq1, __u32 seq2, __u32 seq3) +static inline int between(__u32 seq1, __u32 seq2, __u32 seq3) { return seq3 - seq2 >= seq1 - seq2; } @@ -305,7 +305,7 @@ static inline void tcp_synq_overflow(struct sock *sk) } /* syncookies: no recent synqueue overflow on this listening socket? */ -static inline bool tcp_synq_no_recent_overflow(const struct sock *sk) +static inline int tcp_synq_no_recent_overflow(const struct sock *sk) { unsigned long last_overflow = tcp_sk(sk)->rx_opt.ts_recent_stamp; return time_after(jiffies, last_overflow + TCP_TIMEOUT_FALLBACK); @@ -383,7 +383,7 @@ extern struct sock * tcp_check_req(struct sock *sk,struct sk_buff *skb, struct request_sock **prev); extern int tcp_child_process(struct sock *parent, struct sock *child, struct sk_buff *skb); -extern bool tcp_use_frto(struct sock *sk); +extern int tcp_use_frto(struct sock *sk); extern void tcp_enter_frto(struct sock *sk); extern void tcp_enter_loss(struct sock *sk, int how); extern void tcp_clear_retrans(struct tcp_sock *tp); @@ -432,7 +432,8 @@ extern int tcp_disconnect(struct sock *sk, int flags); void tcp_connect_init(struct sock *sk); void tcp_finish_connect(struct sock *sk, struct sk_buff *skb); -int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size); +int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, + int hdrlen, bool *fragstolen); /* From syncookies.c */ extern __u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS]; @@ -470,7 +471,7 @@ static inline __u32 cookie_v6_init_sequence(struct sock *sk, extern void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss, int nonagle); -extern bool tcp_may_send_now(struct sock *sk); +extern int tcp_may_send_now(struct sock *sk); extern int tcp_retransmit_skb(struct sock *, struct sk_buff *); extern void tcp_retransmit_timer(struct sock *sk); extern void tcp_xmit_retransmit_queue(struct sock *); @@ -484,9 +485,9 @@ extern int tcp_write_wakeup(struct sock *); extern void tcp_send_fin(struct sock *sk); extern void tcp_send_active_reset(struct sock *sk, gfp_t priority); extern int tcp_send_synack(struct sock *); -extern bool tcp_syn_flood_action(struct sock *sk, - const struct sk_buff *skb, - const char *proto); +extern int tcp_syn_flood_action(struct sock *sk, + const struct sk_buff *skb, + const char *proto); extern void tcp_push_one(struct sock *, unsigned int mss_now); extern void tcp_send_ack(struct sock *sk); extern void tcp_send_delayed_ack(struct sock *sk); @@ -794,12 +795,12 @@ static inline int tcp_is_sack(const struct tcp_sock *tp) return tp->rx_opt.sack_ok; } -static inline bool tcp_is_reno(const struct tcp_sock *tp) +static inline int tcp_is_reno(const struct tcp_sock *tp) { return !tcp_is_sack(tp); } -static inline bool tcp_is_fack(const struct tcp_sock *tp) +static inline int tcp_is_fack(const struct tcp_sock *tp) { return tp->rx_opt.sack_ok & TCP_FACK_ENABLED; } @@ -901,7 +902,7 @@ static inline u32 tcp_wnd_end(const struct tcp_sock *tp) { return tp->snd_una + tp->snd_wnd; } -extern bool tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight); +extern int tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight); static inline void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss, const struct sk_buff *skb) @@ -944,7 +945,7 @@ static inline __sum16 __tcp_checksum_complete(struct sk_buff *skb) return __skb_checksum_complete(skb); } -static inline bool tcp_checksum_complete(struct sk_buff *skb) +static inline int tcp_checksum_complete(struct sk_buff *skb) { return !skb_csum_unnecessary(skb) && __tcp_checksum_complete(skb); @@ -974,12 +975,12 @@ static inline void tcp_prequeue_init(struct tcp_sock *tp) * * NOTE: is this not too big to inline? */ -static inline bool tcp_prequeue(struct sock *sk, struct sk_buff *skb) +static inline int tcp_prequeue(struct sock *sk, struct sk_buff *skb) { struct tcp_sock *tp = tcp_sk(sk); if (sysctl_tcp_low_latency || !tp->ucopy.task) - return false; + return 0; __skb_queue_tail(&tp->ucopy.prequeue, skb); tp->ucopy.memory += skb->truesize; @@ -1003,7 +1004,7 @@ static inline bool tcp_prequeue(struct sock *sk, struct sk_buff *skb) (3 * tcp_rto_min(sk)) / 4, TCP_RTO_MAX); } - return true; + return 1; } @@ -1108,28 +1109,28 @@ static inline int tcp_fin_time(const struct sock *sk) return fin_timeout; } -static inline bool tcp_paws_check(const struct tcp_options_received *rx_opt, - int paws_win) +static inline int tcp_paws_check(const struct tcp_options_received *rx_opt, + int paws_win) { if ((s32)(rx_opt->ts_recent - rx_opt->rcv_tsval) <= paws_win) - return true; + return 1; if (unlikely(get_seconds() >= rx_opt->ts_recent_stamp + TCP_PAWS_24DAYS)) - return true; + return 1; /* * Some OSes send SYN and SYNACK messages with tsval=0 tsecr=0, * then following tcp messages have valid values. Ignore 0 value, * or else 'negative' tsval might forbid us to accept their packets. */ if (!rx_opt->ts_recent) - return true; - return false; + return 1; + return 0; } -static inline bool tcp_paws_reject(const struct tcp_options_received *rx_opt, - int rst) +static inline int tcp_paws_reject(const struct tcp_options_received *rx_opt, + int rst) { if (tcp_paws_check(rx_opt, 0)) - return false; + return 0; /* RST segments are not recommended to carry timestamp, and, if they do, it is recommended to ignore PAWS because @@ -1144,8 +1145,8 @@ static inline bool tcp_paws_reject(const struct tcp_options_received *rx_opt, However, we can relax time bounds for RST segments to MSL. */ if (rst && get_seconds() >= rx_opt->ts_recent_stamp + TCP_PAWS_MSL) - return false; - return true; + return 0; + return 1; } static inline void tcp_mib_init(struct net *net) @@ -1383,7 +1384,7 @@ static inline void tcp_unlink_write_queue(struct sk_buff *skb, struct sock *sk) __skb_unlink(skb, &sk->sk_write_queue); } -static inline bool tcp_write_queue_empty(struct sock *sk) +static inline int tcp_write_queue_empty(struct sock *sk) { return skb_queue_empty(&sk->sk_write_queue); } @@ -1440,7 +1441,7 @@ static inline void tcp_highest_sack_combine(struct sock *sk, /* Determines whether this is a thin stream (which may suffer from * increased latency). Used to trigger latency-reducing mechanisms. */ -static inline bool tcp_stream_is_thin(struct tcp_sock *tp) +static inline unsigned int tcp_stream_is_thin(struct tcp_sock *tp) { return tp->packets_out < 4 && !tcp_in_initial_slowstart(tp); } diff --git a/trunk/include/net/wpan-phy.h b/trunk/include/net/wpan-phy.h index b52bda8d13b1..ff27f1b078d1 100644 --- a/trunk/include/net/wpan-phy.h +++ b/trunk/include/net/wpan-phy.h @@ -25,14 +25,6 @@ #include #include -/* According to the IEEE 802.15.4 stadard the upper most significant bits of - * the 32-bit channel bitmaps shall be used as an integer value to specify 32 - * possible channel pages. The lower 27 bits of the channel bit map shall be - * used as a bit mask to specify channel numbers within a channel page. - */ -#define WPAN_NUM_CHANNELS 27 -#define WPAN_NUM_PAGES 32 - struct wpan_phy { struct mutex pib_lock; @@ -51,7 +43,7 @@ struct wpan_phy { int idx; struct net_device *(*add_iface)(struct wpan_phy *phy, - const char *name, int type); + const char *name); void (*del_iface)(struct wpan_phy *phy, struct net_device *dev); char priv[0] __attribute__((__aligned__(NETDEV_ALIGN))); diff --git a/trunk/include/net/xfrm.h b/trunk/include/net/xfrm.h index e0a55df5bde8..1cb32bf107de 100644 --- a/trunk/include/net/xfrm.h +++ b/trunk/include/net/xfrm.h @@ -886,15 +886,15 @@ __be16 xfrm_flowi_dport(const struct flowi *fl, const union flowi_uli *uli) return port; } -extern bool xfrm_selector_match(const struct xfrm_selector *sel, - const struct flowi *fl, - unsigned short family); +extern int xfrm_selector_match(const struct xfrm_selector *sel, + const struct flowi *fl, + unsigned short family); #ifdef CONFIG_SECURITY_NETWORK_XFRM /* If neither has a context --> match * Otherwise, both must have a context and the sids, doi, alg must match */ -static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2) +static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2) { return ((!s1 && !s2) || (s1 && s2 && @@ -903,9 +903,9 @@ static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_c (s1->ctx_alg == s2->ctx_alg))); } #else -static inline bool xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2) +static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2) { - return true; + return 1; } #endif diff --git a/trunk/include/rdma/ib_mad.h b/trunk/include/rdma/ib_mad.h index 3d81b90cc315..b513f57e1725 100644 --- a/trunk/include/rdma/ib_mad.h +++ b/trunk/include/rdma/ib_mad.h @@ -160,7 +160,7 @@ struct ib_rmpp_hdr { typedef u64 __bitwise ib_sa_comp_mask; -#define IB_SA_COMP_MASK(n) ((__force ib_sa_comp_mask) cpu_to_be64(1ull << (n))) +#define IB_SA_COMP_MASK(n) ((__force ib_sa_comp_mask) cpu_to_be64(1ull << n)) /* * ib_sa_hdr and ib_sa_mad structures must be packed because they have diff --git a/trunk/include/rdma/ib_verbs.h b/trunk/include/rdma/ib_verbs.h index 07996af8265a..c3cca5a4dacd 100644 --- a/trunk/include/rdma/ib_verbs.h +++ b/trunk/include/rdma/ib_verbs.h @@ -605,7 +605,7 @@ enum ib_qp_type { IB_QPT_UD, IB_QPT_RAW_IPV6, IB_QPT_RAW_ETHERTYPE, - IB_QPT_RAW_PACKET = 8, + /* Save 8 for RAW_PACKET */ IB_QPT_XRC_INI = 9, IB_QPT_XRC_TGT, IB_QPT_MAX @@ -964,7 +964,7 @@ struct ib_qp { struct ib_srq *srq; struct ib_xrcd *xrcd; /* XRC TGT QPs only */ struct list_head xrcd_list; - atomic_t usecnt; /* count times opened, mcast attaches */ + atomic_t usecnt; /* count times opened */ struct list_head open_list; struct ib_qp *real_qp; struct ib_uobject *uobject; diff --git a/trunk/include/scsi/iscsi_proto.h b/trunk/include/scsi/iscsi_proto.h index c1260d80ef30..988ba06b3ad6 100644 --- a/trunk/include/scsi/iscsi_proto.h +++ b/trunk/include/scsi/iscsi_proto.h @@ -661,8 +661,6 @@ struct iscsi_reject { #define ISCSI_DEF_TIME2WAIT 2 -#define ISCSI_NAME_LEN 224 - /************************* RFC 3720 End *****************************/ #endif /* ISCSI_PROTO_H */ diff --git a/trunk/include/scsi/sas.h b/trunk/include/scsi/sas.h index be3eb0bf1ac0..a577a833603d 100644 --- a/trunk/include/scsi/sas.h +++ b/trunk/include/scsi/sas.h @@ -103,7 +103,6 @@ enum sas_dev_type { }; enum sas_protocol { - SAS_PROTOCOL_NONE = 0, SAS_PROTOCOL_SATA = 0x01, SAS_PROTOCOL_SMP = 0x02, SAS_PROTOCOL_STP = 0x04, diff --git a/trunk/include/target/target_core_backend.h b/trunk/include/target/target_core_backend.h index 2d7db85e93ae..8c9ff1b14396 100644 --- a/trunk/include/target/target_core_backend.h +++ b/trunk/include/target/target_core_backend.h @@ -23,11 +23,12 @@ struct se_subsystem_api { struct se_device *(*create_virtdevice)(struct se_hba *, struct se_subsystem_dev *, void *); void (*free_device)(void *); - int (*transport_complete)(struct se_cmd *cmd, struct scatterlist *); - int (*execute_cmd)(struct se_cmd *, struct scatterlist *, u32, - enum dma_data_direction); + int (*transport_complete)(struct se_task *task); + struct se_task *(*alloc_task)(unsigned char *cdb); + int (*do_task)(struct se_task *); int (*do_discard)(struct se_device *, sector_t, u32); - void (*do_sync_cache)(struct se_cmd *); + void (*do_sync_cache)(struct se_task *); + void (*free_task)(struct se_task *); ssize_t (*check_configfs_dev_params)(struct se_hba *, struct se_subsystem_dev *); ssize_t (*set_configfs_dev_params)(struct se_hba *, @@ -37,7 +38,7 @@ struct se_subsystem_api { u32 (*get_device_rev)(struct se_device *); u32 (*get_device_type)(struct se_device *); sector_t (*get_blocks)(struct se_device *); - unsigned char *(*get_sense_buffer)(struct se_cmd *); + unsigned char *(*get_sense_buffer)(struct se_task *); }; int transport_subsystem_register(struct se_subsystem_api *); @@ -47,7 +48,10 @@ struct se_device *transport_add_device_to_core_hba(struct se_hba *, struct se_subsystem_api *, struct se_subsystem_dev *, u32, void *, struct se_dev_limits *, const char *, const char *); -void target_complete_cmd(struct se_cmd *, u8); +void transport_complete_sync_cache(struct se_cmd *, int); +void transport_complete_task(struct se_task *, int); + +void target_get_task_cdb(struct se_task *, unsigned char *); void transport_set_vpd_proto_id(struct t10_vpd *, unsigned char *); int transport_set_vpd_assoc(struct t10_vpd *, unsigned char *); diff --git a/trunk/include/target/target_core_base.h b/trunk/include/target/target_core_base.h index dc35d8660aa6..aaccc5f5fc9f 100644 --- a/trunk/include/target/target_core_base.h +++ b/trunk/include/target/target_core_base.h @@ -73,8 +73,9 @@ /* * struct se_device->dev_flags */ -#define DF_SPC2_RESERVATIONS 0x00000001 -#define DF_SPC2_RESERVATIONS_WITH_ISID 0x00000002 +#define DF_READ_ONLY 0x00000001 +#define DF_SPC2_RESERVATIONS 0x00000002 +#define DF_SPC2_RESERVATIONS_WITH_ISID 0x00000004 /* struct se_dev_attrib sanity values */ /* Default max_unmap_lba_count */ @@ -140,6 +141,14 @@ enum transport_tpg_type_table { TRANSPORT_TPG_TYPE_DISCOVERY = 1, }; +/* struct se_task->task_flags */ +enum se_task_flags { + TF_ACTIVE = (1 << 0), + TF_SENT = (1 << 1), + TF_REQUEST_STOP = (1 << 2), + TF_HAS_SENSE = (1 << 3), +}; + /* Special transport agnostic struct se_cmd->t_states */ enum transport_state_table { TRANSPORT_NO_STATE = 0, @@ -225,7 +234,6 @@ enum tcm_sense_reason_table { enum target_sc_flags_table { TARGET_SCF_BIDI_OP = 0x01, TARGET_SCF_ACK_KREF = 0x02, - TARGET_SCF_UNKNOWN_SIZE = 0x04, }; /* fabric independent task management function values */ @@ -330,7 +338,6 @@ struct t10_alua_tg_pt_gp { int tg_pt_gp_alua_access_type; int tg_pt_gp_nonop_delay_msecs; int tg_pt_gp_trans_delay_msecs; - int tg_pt_gp_implict_trans_secs; int tg_pt_gp_pref; int tg_pt_gp_write_metadata; /* Used by struct t10_alua_tg_pt_gp->tg_pt_gp_md_buf_len */ @@ -478,6 +485,23 @@ struct se_queue_obj { wait_queue_head_t thread_wq; }; +struct se_task { + unsigned long long task_lba; + u32 task_sectors; + u32 task_size; + struct se_cmd *task_se_cmd; + struct scatterlist *task_sg; + u32 task_sg_nents; + u16 task_flags; + u8 task_scsi_status; + enum dma_data_direction task_data_direction; + struct list_head t_list; + struct list_head t_execute_list; + struct list_head t_state_list; + bool t_state_active; + struct completion task_stop_comp; +}; + struct se_tmr_req { /* Task Management function to be performed */ u8 function; @@ -514,7 +538,6 @@ struct se_cmd { /* Used to signal cmd->se_tfo->check_release_cmd() usage per cmd */ unsigned check_release:1; unsigned cmd_wait_set:1; - unsigned unknown_data_length:1; /* See se_cmd_flags_table */ u32 se_cmd_flags; u32 se_ordered_id; @@ -542,13 +565,18 @@ struct se_cmd { struct completion cmd_wait_comp; struct kref cmd_kref; struct target_core_fabric_ops *se_tfo; - int (*execute_cmd)(struct se_cmd *); + int (*execute_task)(struct se_task *); void (*transport_complete_callback)(struct se_cmd *); unsigned char *t_task_cdb; unsigned char __t_task_cdb[TCM_MAX_COMMAND_SIZE]; unsigned long long t_task_lba; + u32 t_tasks_sg_chained_no; atomic_t t_fe_count; + atomic_t t_se_count; + atomic_t t_task_cdbs_left; + atomic_t t_task_cdbs_ex_left; + atomic_t t_task_cdbs_sent; unsigned int transport_state; #define CMD_T_ABORTED (1 << 0) #define CMD_T_ACTIVE (1 << 1) @@ -560,12 +588,11 @@ struct se_cmd { #define CMD_T_LUN_STOP (1 << 7) #define CMD_T_LUN_FE_STOP (1 << 8) #define CMD_T_DEV_ACTIVE (1 << 9) -#define CMD_T_REQUEST_STOP (1 << 10) -#define CMD_T_BUSY (1 << 11) spinlock_t t_state_lock; struct completion t_transport_stop_comp; struct completion transport_lun_fe_stop_comp; struct completion transport_lun_stop_comp; + struct scatterlist *t_tasks_sg_chained; struct work_struct work; @@ -575,15 +602,10 @@ struct se_cmd { struct scatterlist *t_bidi_data_sg; unsigned int t_bidi_data_nents; - struct list_head execute_list; - struct list_head state_list; - bool state_active; - - /* old task stop completion, consider merging with some of the above */ - struct completion task_stop_comp; + /* Used for BIDI READ */ + struct list_head t_task_list; + u32 t_task_list_num; - /* backend private data */ - void *priv; }; struct se_ua { @@ -709,6 +731,7 @@ struct se_dev_attrib { u32 hw_block_size; u32 block_size; u32 hw_max_sectors; + u32 max_sectors; u32 fabric_max_sectors; u32 optimal_sectors; u32 hw_queue_depth; @@ -806,8 +829,8 @@ struct se_device { struct task_struct *process_thread; struct work_struct qf_work_queue; struct list_head delayed_cmd_list; - struct list_head execute_list; - struct list_head state_list; + struct list_head execute_task_list; + struct list_head state_task_list; struct list_head qf_cmd_list; /* Pointer to associated SE HBA */ struct se_hba *se_hba; diff --git a/trunk/include/target/target_core_fabric.h b/trunk/include/target/target_core_fabric.h index 116959933f46..10c690809601 100644 --- a/trunk/include/target/target_core_fabric.h +++ b/trunk/include/target/target_core_fabric.h @@ -3,6 +3,12 @@ struct target_core_fabric_ops { struct configfs_subsystem *tf_subsys; + /* + * Optional to signal struct se_task->task_sg[] padding entries + * for scatterlist chaining using transport_do_task_sg_link(), + * disabled by default + */ + bool task_sg_chaining; char *(*get_fabric_name)(void); u8 (*get_fabric_proto_ident)(struct se_portal_group *); char *(*tpg_get_wwn)(struct se_portal_group *); @@ -96,7 +102,7 @@ void __transport_register_session(struct se_portal_group *, void transport_register_session(struct se_portal_group *, struct se_node_acl *, struct se_session *, void *); void target_get_session(struct se_session *); -void target_put_session(struct se_session *); +int target_put_session(struct se_session *); void transport_free_session(struct se_session *); void target_put_nacl(struct se_node_acl *); void transport_deregister_session_configfs(struct se_session *); @@ -106,7 +112,7 @@ void transport_deregister_session(struct se_session *); void transport_init_se_cmd(struct se_cmd *, struct target_core_fabric_ops *, struct se_session *, u32, int, int, unsigned char *); int transport_lookup_cmd_lun(struct se_cmd *, u32); -int target_setup_cmd_from_cdb(struct se_cmd *, unsigned char *); +int transport_generic_allocate_tasks(struct se_cmd *, unsigned char *); void target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *, unsigned char *, u32, u32, int, int, int); int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess, @@ -118,6 +124,7 @@ int transport_generic_handle_cdb_map(struct se_cmd *); int transport_generic_handle_data(struct se_cmd *); int transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *, u32, struct scatterlist *, u32); +void transport_do_task_sg_chain(struct se_cmd *); int transport_generic_new_cmd(struct se_cmd *); void transport_generic_process_write(struct se_cmd *); diff --git a/trunk/include/trace/events/rcu.h b/trunk/include/trace/events/rcu.h index 1480900c511c..337099783f37 100644 --- a/trunk/include/trace/events/rcu.h +++ b/trunk/include/trace/events/rcu.h @@ -292,8 +292,6 @@ TRACE_EVENT(rcu_dyntick, * "More callbacks": Still more callbacks, try again to clear them out. * "Callbacks drained": All callbacks processed, off to dyntick idle! * "Timer": Timer fired to cause CPU to continue processing callbacks. - * "Demigrate": Timer fired on wrong CPU, woke up correct CPU. - * "Cleanup after idle": Idle exited, timer canceled. */ TRACE_EVENT(rcu_prep_idle, diff --git a/trunk/include/video/vga.h b/trunk/include/video/vga.h index cac567f22e62..2b8691f7d256 100644 --- a/trunk/include/video/vga.h +++ b/trunk/include/video/vga.h @@ -19,7 +19,29 @@ #include #include +#ifndef CONFIG_AMIGA #include +#else +/* + * FIXME + * Ugh, we don't have PCI space, so map readb() and friends to use Zorro space + * for MMIO accesses. This should make cirrusfb work again on Amiga + */ +#undef inb_p +#undef inw_p +#undef outb_p +#undef outw +#undef readb +#undef writeb +#undef writew +#define inb_p(port) 0 +#define inw_p(port) 0 +#define outb_p(port, val) do { } while (0) +#define outw(port, val) do { } while (0) +#define readb z_readb +#define writeb z_writeb +#define writew z_writew +#endif #include diff --git a/trunk/init/Kconfig b/trunk/init/Kconfig index 6d18ef8071b5..6cfd71d06463 100644 --- a/trunk/init/Kconfig +++ b/trunk/init/Kconfig @@ -458,33 +458,6 @@ config RCU_FANOUT Select a specific number if testing RCU itself. Take the default if unsure. -config RCU_FANOUT_LEAF - int "Tree-based hierarchical RCU leaf-level fanout value" - range 2 RCU_FANOUT if 64BIT - range 2 RCU_FANOUT if !64BIT - depends on TREE_RCU || TREE_PREEMPT_RCU - default 16 - help - This option controls the leaf-level fanout of hierarchical - implementations of RCU, and allows trading off cache misses - against lock contention. Systems that synchronize their - scheduling-clock interrupts for energy-efficiency reasons will - want the default because the smaller leaf-level fanout keeps - lock contention levels acceptably low. Very large systems - (hundreds or thousands of CPUs) will instead want to set this - value to the maximum value possible in order to reduce the - number of cache misses incurred during RCU's grace-period - initialization. These systems tend to run CPU-bound, and thus - are not helped by synchronized interrupts, and thus tend to - skew them, which reduces lock contention enough that large - leaf-level fanouts work well. - - Select a specific number if testing RCU itself. - - Select the maximum permissible value for large systems. - - Take the default if unsure. - config RCU_FANOUT_EXACT bool "Disable tree-based hierarchical RCU auto-balancing" depends on TREE_RCU || TREE_PREEMPT_RCU @@ -542,25 +515,10 @@ config RCU_BOOST_PRIO depends on RCU_BOOST default 1 help - This option specifies the real-time priority to which long-term - preempted RCU readers are to be boosted. If you are working - with a real-time application that has one or more CPU-bound - threads running at a real-time priority level, you should set - RCU_BOOST_PRIO to a priority higher then the highest-priority - real-time CPU-bound thread. The default RCU_BOOST_PRIO value - of 1 is appropriate in the common case, which is real-time - applications that do not have any CPU-bound threads. - - Some real-time applications might not have a single real-time - thread that saturates a given CPU, but instead might have - multiple real-time threads that, taken together, fully utilize - that CPU. In this case, you should set RCU_BOOST_PRIO to - a priority higher than the lowest-priority thread that is - conspiring to prevent the CPU from running any non-real-time - tasks. For example, if one thread at priority 10 and another - thread at priority 5 are between themselves fully consuming - the CPU time on a given CPU, then RCU_BOOST_PRIO should be - set to priority 6 or higher. + This option specifies the real-time priority to which preempted + RCU readers are to be boosted. If you are working with CPU-bound + real-time applications, you should specify a priority higher then + the highest-priority CPU-bound application. Specify the real-time priority, or take the default if unsure. diff --git a/trunk/init/Makefile b/trunk/init/Makefile index 7bc47ee31c36..0bf677aa0872 100644 --- a/trunk/init/Makefile +++ b/trunk/init/Makefile @@ -10,10 +10,6 @@ obj-$(CONFIG_BLK_DEV_INITRD) += initramfs.o endif obj-$(CONFIG_GENERIC_CALIBRATE_DELAY) += calibrate.o -ifneq ($(CONFIG_ARCH_INIT_TASK),y) -obj-y += init_task.o -endif - mounts-y := do_mounts.o mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o diff --git a/trunk/init/do_mounts.c b/trunk/init/do_mounts.c index 42b0707c3481..0e93f92a0345 100644 --- a/trunk/init/do_mounts.c +++ b/trunk/init/do_mounts.c @@ -472,7 +472,7 @@ void __init change_floppy(char *fmt, ...) void __init mount_root(void) { #ifdef CONFIG_ROOT_NFS - if (ROOT_DEV == Root_NFS) { + if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) { if (mount_nfs_root()) return; diff --git a/trunk/init/main.c b/trunk/init/main.c index cb54cd3dbf05..44b2433334c7 100644 --- a/trunk/init/main.c +++ b/trunk/init/main.c @@ -560,6 +560,9 @@ asmlinkage void __init start_kernel(void) early_boot_irqs_disabled = false; local_irq_enable(); + /* Interrupts are enabled now so all GFP allocations are safe. */ + gfp_allowed_mask = __GFP_BITS_MASK; + kmem_cache_init_late(); /* @@ -839,10 +842,6 @@ static int __init kernel_init(void * unused) * Wait until kthreadd is all set-up. */ wait_for_completion(&kthreadd_done); - - /* Now the scheduler is fully set up and can do blocking allocations */ - gfp_allowed_mask = __GFP_BITS_MASK; - /* * init can allocate pages on any node */ diff --git a/trunk/kernel/Makefile b/trunk/kernel/Makefile index 6c07f30fa9b7..cb41b9547c9f 100644 --- a/trunk/kernel/Makefile +++ b/trunk/kernel/Makefile @@ -43,7 +43,6 @@ obj-$(CONFIG_DEBUG_RT_MUTEXES) += rtmutex-debug.o obj-$(CONFIG_RT_MUTEX_TESTER) += rtmutex-tester.o obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_SMP) += smpboot.o ifneq ($(CONFIG_SMP),y) obj-y += up.o endif diff --git a/trunk/kernel/auditsc.c b/trunk/kernel/auditsc.c index 4b96415527b8..af1de0f34eae 100644 --- a/trunk/kernel/auditsc.c +++ b/trunk/kernel/auditsc.c @@ -67,7 +67,6 @@ #include #include #include -#include #include "audit.h" @@ -2711,16 +2710,13 @@ void audit_core_dumps(long signr) audit_log_end(ab); } -void __audit_seccomp(unsigned long syscall, long signr, int code) +void __audit_seccomp(unsigned long syscall) { struct audit_buffer *ab; ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); - audit_log_abend(ab, "seccomp", signr); + audit_log_abend(ab, "seccomp", SIGKILL); audit_log_format(ab, " syscall=%ld", syscall); - audit_log_format(ab, " compat=%d", is_compat_task()); - audit_log_format(ab, " ip=0x%lx", KSTK_EIP(current)); - audit_log_format(ab, " code=0x%x", code); audit_log_end(ab); } diff --git a/trunk/kernel/compat.c b/trunk/kernel/compat.c index d2c67aa49ae6..74ff8498809a 100644 --- a/trunk/kernel/compat.c +++ b/trunk/kernel/compat.c @@ -372,54 +372,25 @@ asmlinkage long compat_sys_sigpending(compat_old_sigset_t __user *set) #ifdef __ARCH_WANT_SYS_SIGPROCMASK -/* - * sys_sigprocmask SIG_SETMASK sets the first (compat) word of the - * blocked set of signals to the supplied signal set - */ -static inline void compat_sig_setmask(sigset_t *blocked, compat_sigset_word set) -{ - memcpy(blocked->sig, &set, sizeof(set)); -} - -asmlinkage long compat_sys_sigprocmask(int how, - compat_old_sigset_t __user *nset, - compat_old_sigset_t __user *oset) +asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *set, + compat_old_sigset_t __user *oset) { - old_sigset_t old_set, new_set; - sigset_t new_blocked; - - old_set = current->blocked.sig[0]; - - if (nset) { - if (get_user(new_set, nset)) - return -EFAULT; - new_set &= ~(sigmask(SIGKILL) | sigmask(SIGSTOP)); - - new_blocked = current->blocked; - - switch (how) { - case SIG_BLOCK: - sigaddsetmask(&new_blocked, new_set); - break; - case SIG_UNBLOCK: - sigdelsetmask(&new_blocked, new_set); - break; - case SIG_SETMASK: - compat_sig_setmask(&new_blocked, new_set); - break; - default: - return -EINVAL; - } - - set_current_blocked(&new_blocked); - } - - if (oset) { - if (put_user(old_set, oset)) - return -EFAULT; - } + old_sigset_t s; + long ret; + mm_segment_t old_fs; - return 0; + if (set && get_user(s, set)) + return -EFAULT; + old_fs = get_fs(); + set_fs(KERNEL_DS); + ret = sys_sigprocmask(how, + set ? (old_sigset_t __user *) &s : NULL, + oset ? (old_sigset_t __user *) &s : NULL); + set_fs(old_fs); + if (ret == 0) + if (oset) + ret = put_user(s, oset); + return ret; } #endif diff --git a/trunk/kernel/cpu.c b/trunk/kernel/cpu.c index 0e6353cf147a..2060c6e57027 100644 --- a/trunk/kernel/cpu.c +++ b/trunk/kernel/cpu.c @@ -17,8 +17,6 @@ #include #include -#include "smpboot.h" - #ifdef CONFIG_SMP /* Serializes the updates to cpu_online_mask, cpu_present_mask */ static DEFINE_MUTEX(cpu_add_remove_lock); @@ -297,19 +295,11 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen) int ret, nr_calls = 0; void *hcpu = (void *)(long)cpu; unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0; - struct task_struct *idle; if (cpu_online(cpu) || !cpu_present(cpu)) return -EINVAL; cpu_hotplug_begin(); - - idle = idle_thread_get(cpu); - if (IS_ERR(idle)) { - ret = PTR_ERR(idle); - goto out; - } - ret = __cpu_notify(CPU_UP_PREPARE | mod, hcpu, -1, &nr_calls); if (ret) { nr_calls--; @@ -319,7 +309,7 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen) } /* Arch-specific enabling code. */ - ret = __cpu_up(cpu, idle); + ret = __cpu_up(cpu); if (ret != 0) goto out_notify; BUG_ON(!cpu_online(cpu)); @@ -330,7 +320,6 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen) out_notify: if (ret != 0) __cpu_notify(CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL); -out: cpu_hotplug_done(); return ret; diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index ad54c833116a..b9372a0bff18 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -48,7 +47,6 @@ #include #include #include -#include #include #include #include @@ -113,67 +111,32 @@ int nr_processes(void) return total; } -#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR +#ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR +# define alloc_task_struct_node(node) \ + kmem_cache_alloc_node(task_struct_cachep, GFP_KERNEL, node) +# define free_task_struct(tsk) \ + kmem_cache_free(task_struct_cachep, (tsk)) static struct kmem_cache *task_struct_cachep; - -static inline struct task_struct *alloc_task_struct_node(int node) -{ - return kmem_cache_alloc_node(task_struct_cachep, GFP_KERNEL, node); -} - -void __weak arch_release_task_struct(struct task_struct *tsk) { } - -static inline void free_task_struct(struct task_struct *tsk) -{ - arch_release_task_struct(tsk); - kmem_cache_free(task_struct_cachep, tsk); -} #endif -#ifndef CONFIG_ARCH_THREAD_INFO_ALLOCATOR -void __weak arch_release_thread_info(struct thread_info *ti) { } - -/* - * Allocate pages if THREAD_SIZE is >= PAGE_SIZE, otherwise use a - * kmemcache based allocator. - */ -# if THREAD_SIZE >= PAGE_SIZE +#ifndef __HAVE_ARCH_THREAD_INFO_ALLOCATOR static struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node) { - struct page *page = alloc_pages_node(node, THREADINFO_GFP, - THREAD_SIZE_ORDER); +#ifdef CONFIG_DEBUG_STACK_USAGE + gfp_t mask = GFP_KERNEL | __GFP_ZERO; +#else + gfp_t mask = GFP_KERNEL; +#endif + struct page *page = alloc_pages_node(node, mask, THREAD_SIZE_ORDER); return page ? page_address(page) : NULL; } static inline void free_thread_info(struct thread_info *ti) { - arch_release_thread_info(ti); free_pages((unsigned long)ti, THREAD_SIZE_ORDER); } -# else -static struct kmem_cache *thread_info_cache; - -static struct thread_info *alloc_thread_info_node(struct task_struct *tsk, - int node) -{ - return kmem_cache_alloc_node(thread_info_cache, THREADINFO_GFP, node); -} - -static void free_thread_info(struct thread_info *ti) -{ - arch_release_thread_info(ti); - kmem_cache_free(thread_info_cache, ti); -} - -void thread_info_cache_init(void) -{ - thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE, - THREAD_SIZE, 0, NULL); - BUG_ON(thread_info_cache == NULL); -} -# endif #endif /* SLAB cache for signal_struct structures (tsk->signal) */ @@ -207,7 +170,6 @@ void free_task(struct task_struct *tsk) free_thread_info(tsk->stack); rt_mutex_debug_task_free(tsk); ftrace_graph_exit_task(tsk); - put_seccomp_filter(tsk); free_task_struct(tsk); } EXPORT_SYMBOL(free_task); @@ -241,11 +203,17 @@ void __put_task_struct(struct task_struct *tsk) } EXPORT_SYMBOL_GPL(__put_task_struct); -void __init __weak arch_task_cache_init(void) { } +/* + * macro override instead of weak attribute alias, to workaround + * gcc 4.1.0 and 4.1.1 bugs with weak attribute and empty functions. + */ +#ifndef arch_task_cache_init +#define arch_task_cache_init() +#endif void __init fork_init(unsigned long mempages) { -#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR +#ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR #ifndef ARCH_MIN_TASKALIGN #define ARCH_MIN_TASKALIGN L1_CACHE_BYTES #endif @@ -1194,7 +1162,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, goto fork_out; ftrace_graph_init_task(p); - get_seccomp_filter(p); rt_mutex_init_task(p); @@ -1497,8 +1464,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, if (p->io_context) exit_io_context(p); bad_fork_cleanup_namespaces: - if (unlikely(clone_flags & CLONE_NEWPID)) - pid_ns_release_proc(p->nsproxy->pid_ns); exit_task_namespaces(p); bad_fork_cleanup_mm: if (p->mm) diff --git a/trunk/kernel/hung_task.c b/trunk/kernel/hung_task.c index 6df614912b9d..c21449f85a2a 100644 --- a/trunk/kernel/hung_task.c +++ b/trunk/kernel/hung_task.c @@ -108,10 +108,8 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout) touch_nmi_watchdog(); - if (sysctl_hung_task_panic) { - trigger_all_cpu_backtrace(); + if (sysctl_hung_task_panic) panic("hung_task: blocked tasks"); - } } /* diff --git a/trunk/kernel/irq/chip.c b/trunk/kernel/irq/chip.c index fc275e4f629b..6080f6bc8c33 100644 --- a/trunk/kernel/irq/chip.c +++ b/trunk/kernel/irq/chip.c @@ -379,10 +379,8 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc) * If its disabled or no action available * keep it masked and get out of here */ - if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) { - desc->istate |= IRQS_PENDING; + if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) goto out_unlock; - } handle_irq_event(desc); @@ -520,7 +518,6 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc) out_unlock: raw_spin_unlock(&desc->lock); } -EXPORT_SYMBOL(handle_edge_irq); #ifdef CONFIG_IRQ_EDGE_EOI_HANDLER /** diff --git a/trunk/kernel/irq/irqdesc.c b/trunk/kernel/irq/irqdesc.c index 192a302d6cfd..d86e254b95eb 100644 --- a/trunk/kernel/irq/irqdesc.c +++ b/trunk/kernel/irq/irqdesc.c @@ -112,7 +112,6 @@ struct irq_desc *irq_to_desc(unsigned int irq) { return radix_tree_lookup(&irq_desc_tree, irq); } -EXPORT_SYMBOL(irq_to_desc); static void delete_irq_desc(unsigned int irq) { diff --git a/trunk/kernel/irq/manage.c b/trunk/kernel/irq/manage.c index 585f6381f8e4..89a3ea82569b 100644 --- a/trunk/kernel/irq/manage.c +++ b/trunk/kernel/irq/manage.c @@ -565,8 +565,8 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, * IRQF_TRIGGER_* but the PIC does not support multiple * flow-types? */ - pr_debug("genirq: No set_type function for IRQ %d (%s)\n", irq, - chip ? (chip->name ? : "unknown") : "unknown"); + pr_debug("No set_type function for IRQ %d (%s)\n", irq, + chip ? (chip->name ? : "unknown") : "unknown"); return 0; } @@ -600,7 +600,7 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, ret = 0; break; default: - pr_err("genirq: Setting trigger mode %lu for irq %u failed (%pF)\n", + pr_err("setting trigger mode %lu for irq %u failed (%pF)\n", flags, irq, chip->irq_set_type); } if (unmask) @@ -837,7 +837,8 @@ void exit_irq_thread(void) action = kthread_data(tsk); - pr_err("genirq: exiting task \"%s\" (%d) is an active IRQ thread (irq %d)\n", + printk(KERN_ERR + "exiting task \"%s\" (%d) is an active IRQ thread (irq %d)\n", tsk->comm ? tsk->comm : "", tsk->pid, action->irq); desc = irq_to_desc(action->irq); @@ -877,6 +878,7 @@ static int __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) { struct irqaction *old, **old_ptr; + const char *old_name = NULL; unsigned long flags, thread_mask = 0; int ret, nested, shared = 0; cpumask_var_t mask; @@ -970,8 +972,10 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) */ if (!((old->flags & new->flags) & IRQF_SHARED) || ((old->flags ^ new->flags) & IRQF_TRIGGER_MASK) || - ((old->flags ^ new->flags) & IRQF_ONESHOT)) + ((old->flags ^ new->flags) & IRQF_ONESHOT)) { + old_name = old->name; goto mismatch; + } /* All handlers must agree on per-cpuness */ if ((old->flags & IRQF_PERCPU) != @@ -1027,27 +1031,6 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) * all existing action->thread_mask bits. */ new->thread_mask = 1 << ffz(thread_mask); - - } else if (new->handler == irq_default_primary_handler) { - /* - * The interrupt was requested with handler = NULL, so - * we use the default primary handler for it. But it - * does not have the oneshot flag set. In combination - * with level interrupts this is deadly, because the - * default primary handler just wakes the thread, then - * the irq lines is reenabled, but the device still - * has the level irq asserted. Rinse and repeat.... - * - * While this works for edge type interrupts, we play - * it safe and reject unconditionally because we can't - * say for sure which type this interrupt really - * has. The type flags are unreliable as the - * underlying chip implementation can override them. - */ - pr_err("genirq: Threaded irq requested with handler=NULL and !ONESHOT for irq %d\n", - irq); - ret = -EINVAL; - goto out_mask; } if (!shared) { @@ -1095,7 +1078,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) if (nmsk != omsk) /* hope the handler works with current trigger mode */ - pr_warning("genirq: irq %d uses trigger mode %u; requested %u\n", + pr_warning("IRQ %d uses trigger mode %u; requested %u\n", irq, nmsk, omsk); } @@ -1132,13 +1115,14 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) return 0; mismatch: - if (!(new->flags & IRQF_PROBE_SHARED)) { - pr_err("genirq: Flags mismatch irq %d. %08x (%s) vs. %08x (%s)\n", - irq, new->flags, new->name, old->flags, old->name); #ifdef CONFIG_DEBUG_SHIRQ + if (!(new->flags & IRQF_PROBE_SHARED)) { + printk(KERN_ERR "IRQ handler type mismatch for IRQ %d\n", irq); + if (old_name) + printk(KERN_ERR "current handler: %s\n", old_name); dump_stack(); -#endif } +#endif ret = -EBUSY; out_mask: diff --git a/trunk/kernel/irq/pm.c b/trunk/kernel/irq/pm.c index cb228bf21760..15e53b1766a6 100644 --- a/trunk/kernel/irq/pm.c +++ b/trunk/kernel/irq/pm.c @@ -103,13 +103,8 @@ int check_wakeup_irqs(void) int irq; for_each_irq_desc(irq, desc) { - /* - * Only interrupts which are marked as wakeup source - * and have not been disabled before the suspend check - * can abort suspend. - */ if (irqd_is_wakeup_set(&desc->irq_data)) { - if (desc->depth == 1 && desc->istate & IRQS_PENDING) + if (desc->istate & IRQS_PENDING) return -EBUSY; continue; } diff --git a/trunk/kernel/irq/resend.c b/trunk/kernel/irq/resend.c index 6454db7b6a4d..14dd5761e8c9 100644 --- a/trunk/kernel/irq/resend.c +++ b/trunk/kernel/irq/resend.c @@ -58,13 +58,10 @@ void check_irq_resend(struct irq_desc *desc, unsigned int irq) /* * We do not resend level type interrupts. Level type * interrupts are resent by hardware when they are still - * active. Clear the pending bit so suspend/resume does not - * get confused. + * active. */ - if (irq_settings_is_level(desc)) { - desc->istate &= ~IRQS_PENDING; + if (irq_settings_is_level(desc)) return; - } if (desc->istate & IRQS_REPLAY) return; if (desc->istate & IRQS_PENDING) { diff --git a/trunk/kernel/rcupdate.c b/trunk/kernel/rcupdate.c index 95cba41ce1e9..a86f1741cc27 100644 --- a/trunk/kernel/rcupdate.c +++ b/trunk/kernel/rcupdate.c @@ -51,34 +51,6 @@ #include "rcu.h" -#ifdef CONFIG_PREEMPT_RCU - -/* - * Check for a task exiting while in a preemptible-RCU read-side - * critical section, clean up if so. No need to issue warnings, - * as debug_check_no_locks_held() already does this if lockdep - * is enabled. - */ -void exit_rcu(void) -{ - struct task_struct *t = current; - - if (likely(list_empty(¤t->rcu_node_entry))) - return; - t->rcu_read_lock_nesting = 1; - barrier(); - t->rcu_read_unlock_special = RCU_READ_UNLOCK_BLOCKED; - __rcu_read_unlock(); -} - -#else /* #ifdef CONFIG_PREEMPT_RCU */ - -void exit_rcu(void) -{ -} - -#endif /* #else #ifdef CONFIG_PREEMPT_RCU */ - #ifdef CONFIG_DEBUG_LOCK_ALLOC static struct lock_class_key rcu_lock_key; struct lockdep_map rcu_lock_map = diff --git a/trunk/kernel/rcutiny_plugin.h b/trunk/kernel/rcutiny_plugin.h index fc31a2d65100..22ecea0dfb62 100644 --- a/trunk/kernel/rcutiny_plugin.h +++ b/trunk/kernel/rcutiny_plugin.h @@ -851,6 +851,22 @@ int rcu_preempt_needs_cpu(void) return rcu_preempt_ctrlblk.rcb.rcucblist != NULL; } +/* + * Check for a task exiting while in a preemptible -RCU read-side + * critical section, clean up if so. No need to issue warnings, + * as debug_check_no_locks_held() already does this if lockdep + * is enabled. + */ +void exit_rcu(void) +{ + struct task_struct *t = current; + + if (t->rcu_read_lock_nesting == 0) + return; + t->rcu_read_lock_nesting = 1; + __rcu_read_unlock(); +} + #else /* #ifdef CONFIG_TINY_PREEMPT_RCU */ #ifdef CONFIG_RCU_TRACE diff --git a/trunk/kernel/rcutorture.c b/trunk/kernel/rcutorture.c index e66b34ab7555..a89b381a8c6e 100644 --- a/trunk/kernel/rcutorture.c +++ b/trunk/kernel/rcutorture.c @@ -64,7 +64,6 @@ static int irqreader = 1; /* RCU readers from irq (timers). */ static int fqs_duration; /* Duration of bursts (us), 0 to disable. */ static int fqs_holdoff; /* Hold time within burst (us). */ static int fqs_stutter = 3; /* Wait time between bursts (s). */ -static int n_barrier_cbs; /* Number of callbacks to test RCU barriers. */ static int onoff_interval; /* Wait time between CPU hotplugs, 0=disable. */ static int onoff_holdoff; /* Seconds after boot before CPU hotplugs. */ static int shutdown_secs; /* Shutdown time (s). <=0 for no shutdown. */ @@ -97,8 +96,6 @@ module_param(fqs_holdoff, int, 0444); MODULE_PARM_DESC(fqs_holdoff, "Holdoff time within fqs bursts (us)"); module_param(fqs_stutter, int, 0444); MODULE_PARM_DESC(fqs_stutter, "Wait time between fqs bursts (s)"); -module_param(n_barrier_cbs, int, 0444); -MODULE_PARM_DESC(n_barrier_cbs, "# of callbacks/kthreads for barrier testing"); module_param(onoff_interval, int, 0444); MODULE_PARM_DESC(onoff_interval, "Time between CPU hotplugs (s), 0=disable"); module_param(onoff_holdoff, int, 0444); @@ -142,8 +139,6 @@ static struct task_struct *shutdown_task; static struct task_struct *onoff_task; #endif /* #ifdef CONFIG_HOTPLUG_CPU */ static struct task_struct *stall_task; -static struct task_struct **barrier_cbs_tasks; -static struct task_struct *barrier_task; #define RCU_TORTURE_PIPE_LEN 10 @@ -169,7 +164,6 @@ static atomic_t n_rcu_torture_alloc_fail; static atomic_t n_rcu_torture_free; static atomic_t n_rcu_torture_mberror; static atomic_t n_rcu_torture_error; -static long n_rcu_torture_barrier_error; static long n_rcu_torture_boost_ktrerror; static long n_rcu_torture_boost_rterror; static long n_rcu_torture_boost_failure; @@ -179,8 +173,6 @@ static long n_offline_attempts; static long n_offline_successes; static long n_online_attempts; static long n_online_successes; -static long n_barrier_attempts; -static long n_barrier_successes; static struct list_head rcu_torture_removed; static cpumask_var_t shuffle_tmp_mask; @@ -205,10 +197,6 @@ static unsigned long shutdown_time; /* jiffies to system shutdown. */ static unsigned long boost_starttime; /* jiffies of next boost test start. */ DEFINE_MUTEX(boost_mutex); /* protect setting boost_starttime */ /* and boost task create/destroy. */ -static atomic_t barrier_cbs_count; /* Barrier callbacks registered. */ -static atomic_t barrier_cbs_invoked; /* Barrier callbacks invoked. */ -static wait_queue_head_t *barrier_cbs_wq; /* Coordinate barrier testing. */ -static DECLARE_WAIT_QUEUE_HEAD(barrier_wq); /* Mediate rmmod and system shutdown. Concurrent rmmod & shutdown illegal! */ @@ -339,7 +327,6 @@ struct rcu_torture_ops { int (*completed)(void); void (*deferred_free)(struct rcu_torture *p); void (*sync)(void); - void (*call)(struct rcu_head *head, void (*func)(struct rcu_head *rcu)); void (*cb_barrier)(void); void (*fqs)(void); int (*stats)(char *page); @@ -430,7 +417,6 @@ static struct rcu_torture_ops rcu_ops = { .completed = rcu_torture_completed, .deferred_free = rcu_torture_deferred_free, .sync = synchronize_rcu, - .call = call_rcu, .cb_barrier = rcu_barrier, .fqs = rcu_force_quiescent_state, .stats = NULL, @@ -474,7 +460,6 @@ static struct rcu_torture_ops rcu_sync_ops = { .completed = rcu_torture_completed, .deferred_free = rcu_sync_torture_deferred_free, .sync = synchronize_rcu, - .call = NULL, .cb_barrier = NULL, .fqs = rcu_force_quiescent_state, .stats = NULL, @@ -492,7 +477,6 @@ static struct rcu_torture_ops rcu_expedited_ops = { .completed = rcu_no_completed, .deferred_free = rcu_sync_torture_deferred_free, .sync = synchronize_rcu_expedited, - .call = NULL, .cb_barrier = NULL, .fqs = rcu_force_quiescent_state, .stats = NULL, @@ -535,7 +519,6 @@ static struct rcu_torture_ops rcu_bh_ops = { .completed = rcu_bh_torture_completed, .deferred_free = rcu_bh_torture_deferred_free, .sync = synchronize_rcu_bh, - .call = call_rcu_bh, .cb_barrier = rcu_barrier_bh, .fqs = rcu_bh_force_quiescent_state, .stats = NULL, @@ -552,7 +535,6 @@ static struct rcu_torture_ops rcu_bh_sync_ops = { .completed = rcu_bh_torture_completed, .deferred_free = rcu_sync_torture_deferred_free, .sync = synchronize_rcu_bh, - .call = NULL, .cb_barrier = NULL, .fqs = rcu_bh_force_quiescent_state, .stats = NULL, @@ -569,7 +551,6 @@ static struct rcu_torture_ops rcu_bh_expedited_ops = { .completed = rcu_bh_torture_completed, .deferred_free = rcu_sync_torture_deferred_free, .sync = synchronize_rcu_bh_expedited, - .call = NULL, .cb_barrier = NULL, .fqs = rcu_bh_force_quiescent_state, .stats = NULL, @@ -625,11 +606,6 @@ static int srcu_torture_completed(void) return srcu_batches_completed(&srcu_ctl); } -static void srcu_torture_deferred_free(struct rcu_torture *rp) -{ - call_srcu(&srcu_ctl, &rp->rtort_rcu, rcu_torture_cb); -} - static void srcu_torture_synchronize(void) { synchronize_srcu(&srcu_ctl); @@ -644,7 +620,7 @@ static int srcu_torture_stats(char *page) cnt += sprintf(&page[cnt], "%s%s per-CPU(idx=%d):", torture_type, TORTURE_FLAG, idx); for_each_possible_cpu(cpu) { - cnt += sprintf(&page[cnt], " %d(%lu,%lu)", cpu, + cnt += sprintf(&page[cnt], " %d(%d,%d)", cpu, per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)->c[!idx], per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)->c[idx]); } @@ -653,21 +629,6 @@ static int srcu_torture_stats(char *page) } static struct rcu_torture_ops srcu_ops = { - .init = srcu_torture_init, - .cleanup = srcu_torture_cleanup, - .readlock = srcu_torture_read_lock, - .read_delay = srcu_read_delay, - .readunlock = srcu_torture_read_unlock, - .completed = srcu_torture_completed, - .deferred_free = srcu_torture_deferred_free, - .sync = srcu_torture_synchronize, - .call = NULL, - .cb_barrier = NULL, - .stats = srcu_torture_stats, - .name = "srcu" -}; - -static struct rcu_torture_ops srcu_sync_ops = { .init = srcu_torture_init, .cleanup = srcu_torture_cleanup, .readlock = srcu_torture_read_lock, @@ -676,10 +637,9 @@ static struct rcu_torture_ops srcu_sync_ops = { .completed = srcu_torture_completed, .deferred_free = rcu_sync_torture_deferred_free, .sync = srcu_torture_synchronize, - .call = NULL, .cb_barrier = NULL, .stats = srcu_torture_stats, - .name = "srcu_sync" + .name = "srcu" }; static int srcu_torture_read_lock_raw(void) __acquires(&srcu_ctl) @@ -693,21 +653,6 @@ static void srcu_torture_read_unlock_raw(int idx) __releases(&srcu_ctl) } static struct rcu_torture_ops srcu_raw_ops = { - .init = srcu_torture_init, - .cleanup = srcu_torture_cleanup, - .readlock = srcu_torture_read_lock_raw, - .read_delay = srcu_read_delay, - .readunlock = srcu_torture_read_unlock_raw, - .completed = srcu_torture_completed, - .deferred_free = srcu_torture_deferred_free, - .sync = srcu_torture_synchronize, - .call = NULL, - .cb_barrier = NULL, - .stats = srcu_torture_stats, - .name = "srcu_raw" -}; - -static struct rcu_torture_ops srcu_raw_sync_ops = { .init = srcu_torture_init, .cleanup = srcu_torture_cleanup, .readlock = srcu_torture_read_lock_raw, @@ -716,10 +661,9 @@ static struct rcu_torture_ops srcu_raw_sync_ops = { .completed = srcu_torture_completed, .deferred_free = rcu_sync_torture_deferred_free, .sync = srcu_torture_synchronize, - .call = NULL, .cb_barrier = NULL, .stats = srcu_torture_stats, - .name = "srcu_raw_sync" + .name = "srcu_raw" }; static void srcu_torture_synchronize_expedited(void) @@ -736,7 +680,6 @@ static struct rcu_torture_ops srcu_expedited_ops = { .completed = srcu_torture_completed, .deferred_free = rcu_sync_torture_deferred_free, .sync = srcu_torture_synchronize_expedited, - .call = NULL, .cb_barrier = NULL, .stats = srcu_torture_stats, .name = "srcu_expedited" @@ -1186,8 +1129,7 @@ rcu_torture_printk(char *page) "rtc: %p ver: %lu tfle: %d rta: %d rtaf: %d rtf: %d " "rtmbe: %d rtbke: %ld rtbre: %ld " "rtbf: %ld rtb: %ld nt: %ld " - "onoff: %ld/%ld:%ld/%ld " - "barrier: %ld/%ld:%ld", + "onoff: %ld/%ld:%ld/%ld", rcu_torture_current, rcu_torture_current_version, list_empty(&rcu_torture_freelist), @@ -1203,17 +1145,14 @@ rcu_torture_printk(char *page) n_online_successes, n_online_attempts, n_offline_successes, - n_offline_attempts, - n_barrier_successes, - n_barrier_attempts, - n_rcu_torture_barrier_error); - cnt += sprintf(&page[cnt], "\n%s%s ", torture_type, TORTURE_FLAG); + n_offline_attempts); if (atomic_read(&n_rcu_torture_mberror) != 0 || - n_rcu_torture_barrier_error != 0 || n_rcu_torture_boost_ktrerror != 0 || n_rcu_torture_boost_rterror != 0 || - n_rcu_torture_boost_failure != 0 || - i > 1) { + n_rcu_torture_boost_failure != 0) + cnt += sprintf(&page[cnt], " !!!"); + cnt += sprintf(&page[cnt], "\n%s%s ", torture_type, TORTURE_FLAG); + if (i > 1) { cnt += sprintf(&page[cnt], "!!! "); atomic_inc(&n_rcu_torture_error); WARN_ON_ONCE(1); @@ -1398,7 +1337,6 @@ static void rcutorture_booster_cleanup(int cpu) /* This must be outside of the mutex, otherwise deadlock! */ kthread_stop(t); - boost_tasks[cpu] = NULL; } static int rcutorture_booster_init(int cpu) @@ -1546,15 +1484,13 @@ static void rcu_torture_onoff_cleanup(void) return; VERBOSE_PRINTK_STRING("Stopping rcu_torture_onoff task"); kthread_stop(onoff_task); - onoff_task = NULL; } #else /* #ifdef CONFIG_HOTPLUG_CPU */ -static int +static void rcu_torture_onoff_init(void) { - return 0; } static void rcu_torture_onoff_cleanup(void) @@ -1618,152 +1554,6 @@ static void rcu_torture_stall_cleanup(void) return; VERBOSE_PRINTK_STRING("Stopping rcu_torture_stall_task."); kthread_stop(stall_task); - stall_task = NULL; -} - -/* Callback function for RCU barrier testing. */ -void rcu_torture_barrier_cbf(struct rcu_head *rcu) -{ - atomic_inc(&barrier_cbs_invoked); -} - -/* kthread function to register callbacks used to test RCU barriers. */ -static int rcu_torture_barrier_cbs(void *arg) -{ - long myid = (long)arg; - struct rcu_head rcu; - - init_rcu_head_on_stack(&rcu); - VERBOSE_PRINTK_STRING("rcu_torture_barrier_cbs task started"); - set_user_nice(current, 19); - do { - wait_event(barrier_cbs_wq[myid], - atomic_read(&barrier_cbs_count) == n_barrier_cbs || - kthread_should_stop() || - fullstop != FULLSTOP_DONTSTOP); - if (kthread_should_stop() || fullstop != FULLSTOP_DONTSTOP) - break; - cur_ops->call(&rcu, rcu_torture_barrier_cbf); - if (atomic_dec_and_test(&barrier_cbs_count)) - wake_up(&barrier_wq); - } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP); - VERBOSE_PRINTK_STRING("rcu_torture_barrier_cbs task stopping"); - rcutorture_shutdown_absorb("rcu_torture_barrier_cbs"); - while (!kthread_should_stop()) - schedule_timeout_interruptible(1); - cur_ops->cb_barrier(); - destroy_rcu_head_on_stack(&rcu); - return 0; -} - -/* kthread function to drive and coordinate RCU barrier testing. */ -static int rcu_torture_barrier(void *arg) -{ - int i; - - VERBOSE_PRINTK_STRING("rcu_torture_barrier task starting"); - do { - atomic_set(&barrier_cbs_invoked, 0); - atomic_set(&barrier_cbs_count, n_barrier_cbs); - /* wake_up() path contains the required barriers. */ - for (i = 0; i < n_barrier_cbs; i++) - wake_up(&barrier_cbs_wq[i]); - wait_event(barrier_wq, - atomic_read(&barrier_cbs_count) == 0 || - kthread_should_stop() || - fullstop != FULLSTOP_DONTSTOP); - if (kthread_should_stop() || fullstop != FULLSTOP_DONTSTOP) - break; - n_barrier_attempts++; - cur_ops->cb_barrier(); - if (atomic_read(&barrier_cbs_invoked) != n_barrier_cbs) { - n_rcu_torture_barrier_error++; - WARN_ON_ONCE(1); - } - n_barrier_successes++; - schedule_timeout_interruptible(HZ / 10); - } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP); - VERBOSE_PRINTK_STRING("rcu_torture_barrier task stopping"); - rcutorture_shutdown_absorb("rcu_torture_barrier_cbs"); - while (!kthread_should_stop()) - schedule_timeout_interruptible(1); - return 0; -} - -/* Initialize RCU barrier testing. */ -static int rcu_torture_barrier_init(void) -{ - int i; - int ret; - - if (n_barrier_cbs == 0) - return 0; - if (cur_ops->call == NULL || cur_ops->cb_barrier == NULL) { - printk(KERN_ALERT "%s" TORTURE_FLAG - " Call or barrier ops missing for %s,\n", - torture_type, cur_ops->name); - printk(KERN_ALERT "%s" TORTURE_FLAG - " RCU barrier testing omitted from run.\n", - torture_type); - return 0; - } - atomic_set(&barrier_cbs_count, 0); - atomic_set(&barrier_cbs_invoked, 0); - barrier_cbs_tasks = - kzalloc(n_barrier_cbs * sizeof(barrier_cbs_tasks[0]), - GFP_KERNEL); - barrier_cbs_wq = - kzalloc(n_barrier_cbs * sizeof(barrier_cbs_wq[0]), - GFP_KERNEL); - if (barrier_cbs_tasks == NULL || barrier_cbs_wq == 0) - return -ENOMEM; - for (i = 0; i < n_barrier_cbs; i++) { - init_waitqueue_head(&barrier_cbs_wq[i]); - barrier_cbs_tasks[i] = kthread_run(rcu_torture_barrier_cbs, - (void *)(long)i, - "rcu_torture_barrier_cbs"); - if (IS_ERR(barrier_cbs_tasks[i])) { - ret = PTR_ERR(barrier_cbs_tasks[i]); - VERBOSE_PRINTK_ERRSTRING("Failed to create rcu_torture_barrier_cbs"); - barrier_cbs_tasks[i] = NULL; - return ret; - } - } - barrier_task = kthread_run(rcu_torture_barrier, NULL, - "rcu_torture_barrier"); - if (IS_ERR(barrier_task)) { - ret = PTR_ERR(barrier_task); - VERBOSE_PRINTK_ERRSTRING("Failed to create rcu_torture_barrier"); - barrier_task = NULL; - } - return 0; -} - -/* Clean up after RCU barrier testing. */ -static void rcu_torture_barrier_cleanup(void) -{ - int i; - - if (barrier_task != NULL) { - VERBOSE_PRINTK_STRING("Stopping rcu_torture_barrier task"); - kthread_stop(barrier_task); - barrier_task = NULL; - } - if (barrier_cbs_tasks != NULL) { - for (i = 0; i < n_barrier_cbs; i++) { - if (barrier_cbs_tasks[i] != NULL) { - VERBOSE_PRINTK_STRING("Stopping rcu_torture_barrier_cbs task"); - kthread_stop(barrier_cbs_tasks[i]); - barrier_cbs_tasks[i] = NULL; - } - } - kfree(barrier_cbs_tasks); - barrier_cbs_tasks = NULL; - } - if (barrier_cbs_wq != NULL) { - kfree(barrier_cbs_wq); - barrier_cbs_wq = NULL; - } } static int rcutorture_cpu_notify(struct notifier_block *self, @@ -1808,7 +1598,6 @@ rcu_torture_cleanup(void) fullstop = FULLSTOP_RMMOD; mutex_unlock(&fullstop_mutex); unregister_reboot_notifier(&rcutorture_shutdown_nb); - rcu_torture_barrier_cleanup(); rcu_torture_stall_cleanup(); if (stutter_task) { VERBOSE_PRINTK_STRING("Stopping rcu_torture_stutter task"); @@ -1876,7 +1665,6 @@ rcu_torture_cleanup(void) VERBOSE_PRINTK_STRING("Stopping rcu_torture_shutdown task"); kthread_stop(shutdown_task); } - shutdown_task = NULL; rcu_torture_onoff_cleanup(); /* Wait for all RCU callbacks to fire. */ @@ -1888,7 +1676,7 @@ rcu_torture_cleanup(void) if (cur_ops->cleanup) cur_ops->cleanup(); - if (atomic_read(&n_rcu_torture_error) || n_rcu_torture_barrier_error) + if (atomic_read(&n_rcu_torture_error)) rcu_torture_print_module_parms(cur_ops, "End of test: FAILURE"); else if (n_online_successes != n_online_attempts || n_offline_successes != n_offline_attempts) @@ -1904,12 +1692,10 @@ rcu_torture_init(void) int i; int cpu; int firsterr = 0; - int retval; static struct rcu_torture_ops *torture_ops[] = { &rcu_ops, &rcu_sync_ops, &rcu_expedited_ops, &rcu_bh_ops, &rcu_bh_sync_ops, &rcu_bh_expedited_ops, - &srcu_ops, &srcu_sync_ops, &srcu_raw_ops, - &srcu_raw_sync_ops, &srcu_expedited_ops, + &srcu_ops, &srcu_raw_ops, &srcu_expedited_ops, &sched_ops, &sched_sync_ops, &sched_expedited_ops, }; mutex_lock(&fullstop_mutex); @@ -1963,7 +1749,6 @@ rcu_torture_init(void) atomic_set(&n_rcu_torture_free, 0); atomic_set(&n_rcu_torture_mberror, 0); atomic_set(&n_rcu_torture_error, 0); - n_rcu_torture_barrier_error = 0; n_rcu_torture_boost_ktrerror = 0; n_rcu_torture_boost_rterror = 0; n_rcu_torture_boost_failure = 0; @@ -2087,6 +1872,7 @@ rcu_torture_init(void) test_boost_duration = 2; if ((test_boost == 1 && cur_ops->can_boost) || test_boost == 2) { + int retval; boost_starttime = jiffies + test_boost_interval * HZ; register_cpu_notifier(&rcutorture_cpu_nb); @@ -2111,22 +1897,9 @@ rcu_torture_init(void) goto unwind; } } - i = rcu_torture_onoff_init(); - if (i != 0) { - firsterr = i; - goto unwind; - } + rcu_torture_onoff_init(); register_reboot_notifier(&rcutorture_shutdown_nb); - i = rcu_torture_stall_init(); - if (i != 0) { - firsterr = i; - goto unwind; - } - retval = rcu_torture_barrier_init(); - if (retval != 0) { - firsterr = retval; - goto unwind; - } + rcu_torture_stall_init(); rcutorture_record_test_transition(); mutex_unlock(&fullstop_mutex); return 0; diff --git a/trunk/kernel/rcutree.c b/trunk/kernel/rcutree.c index 0da7b88d92d0..d0c5baf1ab18 100644 --- a/trunk/kernel/rcutree.c +++ b/trunk/kernel/rcutree.c @@ -75,8 +75,6 @@ static struct lock_class_key rcu_node_class[NUM_RCU_LVLS]; .gpnum = -300, \ .completed = -300, \ .onofflock = __RAW_SPIN_LOCK_UNLOCKED(&structname##_state.onofflock), \ - .orphan_nxttail = &structname##_state.orphan_nxtlist, \ - .orphan_donetail = &structname##_state.orphan_donelist, \ .fqslock = __RAW_SPIN_LOCK_UNLOCKED(&structname##_state.fqslock), \ .n_force_qs = 0, \ .n_force_qs_ngp = 0, \ @@ -147,13 +145,6 @@ static void invoke_rcu_callbacks(struct rcu_state *rsp, struct rcu_data *rdp); unsigned long rcutorture_testseq; unsigned long rcutorture_vernum; -/* State information for rcu_barrier() and friends. */ - -static DEFINE_PER_CPU(struct rcu_head, rcu_barrier_head) = {NULL}; -static atomic_t rcu_barrier_cpu_count; -static DEFINE_MUTEX(rcu_barrier_mutex); -static struct completion rcu_barrier_completion; - /* * Return true if an RCU grace period is in progress. The ACCESS_ONCE()s * permit this function to be invoked without holding the root rcu_node @@ -201,6 +192,7 @@ void rcu_note_context_switch(int cpu) { trace_rcu_utilization("Start context switch"); rcu_sched_qs(cpu); + rcu_preempt_note_context_switch(cpu); trace_rcu_utilization("End context switch"); } EXPORT_SYMBOL_GPL(rcu_note_context_switch); @@ -1319,133 +1311,95 @@ rcu_check_quiescent_state(struct rcu_state *rsp, struct rcu_data *rdp) #ifdef CONFIG_HOTPLUG_CPU /* - * Send the specified CPU's RCU callbacks to the orphanage. The - * specified CPU must be offline, and the caller must hold the - * ->onofflock. + * Move a dying CPU's RCU callbacks to online CPU's callback list. + * Also record a quiescent state for this CPU for the current grace period. + * Synchronization and interrupt disabling are not required because + * this function executes in stop_machine() context. Therefore, cleanup + * operations that might block must be done later from the CPU_DEAD + * notifier. + * + * Note that the outgoing CPU's bit has already been cleared in the + * cpu_online_mask. This allows us to randomly pick a callback + * destination from the bits set in that mask. */ -static void -rcu_send_cbs_to_orphanage(int cpu, struct rcu_state *rsp, - struct rcu_node *rnp, struct rcu_data *rdp) +static void rcu_cleanup_dying_cpu(struct rcu_state *rsp) { int i; + unsigned long mask; + int receive_cpu = cpumask_any(cpu_online_mask); + struct rcu_data *rdp = this_cpu_ptr(rsp->rda); + struct rcu_data *receive_rdp = per_cpu_ptr(rsp->rda, receive_cpu); + RCU_TRACE(struct rcu_node *rnp = rdp->mynode); /* For dying CPU. */ - /* - * Orphan the callbacks. First adjust the counts. This is safe - * because ->onofflock excludes _rcu_barrier()'s adoption of - * the callbacks, thus no memory barrier is required. - */ + /* First, adjust the counts. */ if (rdp->nxtlist != NULL) { - rsp->qlen_lazy += rdp->qlen_lazy; - rsp->qlen += rdp->qlen; - rdp->n_cbs_orphaned += rdp->qlen; + receive_rdp->qlen_lazy += rdp->qlen_lazy; + receive_rdp->qlen += rdp->qlen; rdp->qlen_lazy = 0; rdp->qlen = 0; } /* - * Next, move those callbacks still needing a grace period to - * the orphanage, where some other CPU will pick them up. - * Some of the callbacks might have gone partway through a grace - * period, but that is too bad. They get to start over because we - * cannot assume that grace periods are synchronized across CPUs. - * We don't bother updating the ->nxttail[] array yet, instead - * we just reset the whole thing later on. + * Next, move ready-to-invoke callbacks to be invoked on some + * other CPU. These will not be required to pass through another + * grace period: They are done, regardless of CPU. */ - if (*rdp->nxttail[RCU_DONE_TAIL] != NULL) { - *rsp->orphan_nxttail = *rdp->nxttail[RCU_DONE_TAIL]; - rsp->orphan_nxttail = rdp->nxttail[RCU_NEXT_TAIL]; - *rdp->nxttail[RCU_DONE_TAIL] = NULL; + if (rdp->nxtlist != NULL && + rdp->nxttail[RCU_DONE_TAIL] != &rdp->nxtlist) { + struct rcu_head *oldhead; + struct rcu_head **oldtail; + struct rcu_head **newtail; + + oldhead = rdp->nxtlist; + oldtail = receive_rdp->nxttail[RCU_DONE_TAIL]; + rdp->nxtlist = *rdp->nxttail[RCU_DONE_TAIL]; + *rdp->nxttail[RCU_DONE_TAIL] = *oldtail; + *receive_rdp->nxttail[RCU_DONE_TAIL] = oldhead; + newtail = rdp->nxttail[RCU_DONE_TAIL]; + for (i = RCU_DONE_TAIL; i < RCU_NEXT_SIZE; i++) { + if (receive_rdp->nxttail[i] == oldtail) + receive_rdp->nxttail[i] = newtail; + if (rdp->nxttail[i] == newtail) + rdp->nxttail[i] = &rdp->nxtlist; + } } /* - * Then move the ready-to-invoke callbacks to the orphanage, - * where some other CPU will pick them up. These will not be - * required to pass though another grace period: They are done. + * Finally, put the rest of the callbacks at the end of the list. + * The ones that made it partway through get to start over: We + * cannot assume that grace periods are synchronized across CPUs. + * (We could splice RCU_WAIT_TAIL into RCU_NEXT_READY_TAIL, but + * this does not seem compelling. Not yet, anyway.) */ if (rdp->nxtlist != NULL) { - *rsp->orphan_donetail = rdp->nxtlist; - rsp->orphan_donetail = rdp->nxttail[RCU_DONE_TAIL]; - } - - /* Finally, initialize the rcu_data structure's list to empty. */ - rdp->nxtlist = NULL; - for (i = 0; i < RCU_NEXT_SIZE; i++) - rdp->nxttail[i] = &rdp->nxtlist; -} - -/* - * Adopt the RCU callbacks from the specified rcu_state structure's - * orphanage. The caller must hold the ->onofflock. - */ -static void rcu_adopt_orphan_cbs(struct rcu_state *rsp) -{ - int i; - struct rcu_data *rdp = __this_cpu_ptr(rsp->rda); - - /* - * If there is an rcu_barrier() operation in progress, then - * only the task doing that operation is permitted to adopt - * callbacks. To do otherwise breaks rcu_barrier() and friends - * by causing them to fail to wait for the callbacks in the - * orphanage. - */ - if (rsp->rcu_barrier_in_progress && - rsp->rcu_barrier_in_progress != current) - return; + *receive_rdp->nxttail[RCU_NEXT_TAIL] = rdp->nxtlist; + receive_rdp->nxttail[RCU_NEXT_TAIL] = + rdp->nxttail[RCU_NEXT_TAIL]; + receive_rdp->n_cbs_adopted += rdp->qlen; + rdp->n_cbs_orphaned += rdp->qlen; - /* Do the accounting first. */ - rdp->qlen_lazy += rsp->qlen_lazy; - rdp->qlen += rsp->qlen; - rdp->n_cbs_adopted += rsp->qlen; - rsp->qlen_lazy = 0; - rsp->qlen = 0; + rdp->nxtlist = NULL; + for (i = 0; i < RCU_NEXT_SIZE; i++) + rdp->nxttail[i] = &rdp->nxtlist; + } /* - * We do not need a memory barrier here because the only way we - * can get here if there is an rcu_barrier() in flight is if - * we are the task doing the rcu_barrier(). + * Record a quiescent state for the dying CPU. This is safe + * only because we have already cleared out the callbacks. + * (Otherwise, the RCU core might try to schedule the invocation + * of callbacks on this now-offline CPU, which would be bad.) */ - - /* First adopt the ready-to-invoke callbacks. */ - if (rsp->orphan_donelist != NULL) { - *rsp->orphan_donetail = *rdp->nxttail[RCU_DONE_TAIL]; - *rdp->nxttail[RCU_DONE_TAIL] = rsp->orphan_donelist; - for (i = RCU_NEXT_SIZE - 1; i >= RCU_DONE_TAIL; i--) - if (rdp->nxttail[i] == rdp->nxttail[RCU_DONE_TAIL]) - rdp->nxttail[i] = rsp->orphan_donetail; - rsp->orphan_donelist = NULL; - rsp->orphan_donetail = &rsp->orphan_donelist; - } - - /* And then adopt the callbacks that still need a grace period. */ - if (rsp->orphan_nxtlist != NULL) { - *rdp->nxttail[RCU_NEXT_TAIL] = rsp->orphan_nxtlist; - rdp->nxttail[RCU_NEXT_TAIL] = rsp->orphan_nxttail; - rsp->orphan_nxtlist = NULL; - rsp->orphan_nxttail = &rsp->orphan_nxtlist; - } -} - -/* - * Trace the fact that this CPU is going offline. - */ -static void rcu_cleanup_dying_cpu(struct rcu_state *rsp) -{ - RCU_TRACE(unsigned long mask); - RCU_TRACE(struct rcu_data *rdp = this_cpu_ptr(rsp->rda)); - RCU_TRACE(struct rcu_node *rnp = rdp->mynode); - - RCU_TRACE(mask = rdp->grpmask); + mask = rdp->grpmask; /* rnp->grplo is constant. */ trace_rcu_grace_period(rsp->name, rnp->gpnum + 1 - !!(rnp->qsmask & mask), "cpuofl"); + rcu_report_qs_rdp(smp_processor_id(), rsp, rdp, rsp->gpnum); + /* Note that rcu_report_qs_rdp() might call trace_rcu_grace_period(). */ } /* * The CPU has been completely removed, and some other CPU is reporting - * this fact from process context. Do the remainder of the cleanup, - * including orphaning the outgoing CPU's RCU callbacks, and also - * adopting them, if there is no _rcu_barrier() instance running. + * this fact from process context. Do the remainder of the cleanup. * There can only be one CPU hotplug operation at a time, so no other * CPU can be attempting to update rcu_cpu_kthread_task. */ @@ -1455,21 +1409,17 @@ static void rcu_cleanup_dead_cpu(int cpu, struct rcu_state *rsp) unsigned long mask; int need_report = 0; struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu); - struct rcu_node *rnp = rdp->mynode; /* Outgoing CPU's rdp & rnp. */ + struct rcu_node *rnp = rdp->mynode; /* Outgoing CPU's rnp. */ /* Adjust any no-longer-needed kthreads. */ rcu_stop_cpu_kthread(cpu); rcu_node_kthread_setaffinity(rnp, -1); - /* Remove the dead CPU from the bitmasks in the rcu_node hierarchy. */ + /* Remove the dying CPU from the bitmasks in the rcu_node hierarchy. */ /* Exclude any attempts to start a new grace period. */ raw_spin_lock_irqsave(&rsp->onofflock, flags); - /* Orphan the dead CPU's callbacks, and adopt them if appropriate. */ - rcu_send_cbs_to_orphanage(cpu, rsp, rnp, rdp); - rcu_adopt_orphan_cbs(rsp); - /* Remove the outgoing CPU from the masks in the rcu_node hierarchy. */ mask = rdp->grpmask; /* rnp->grplo is constant. */ do { @@ -1506,10 +1456,6 @@ static void rcu_cleanup_dead_cpu(int cpu, struct rcu_state *rsp) #else /* #ifdef CONFIG_HOTPLUG_CPU */ -static void rcu_adopt_orphan_cbs(struct rcu_state *rsp) -{ -} - static void rcu_cleanup_dying_cpu(struct rcu_state *rsp) { } @@ -1578,6 +1524,9 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp) rcu_is_callbacks_kthread()); /* Update count, and requeue any remaining callbacks. */ + rdp->qlen_lazy -= count_lazy; + rdp->qlen -= count; + rdp->n_cbs_invoked += count; if (list != NULL) { *tail = rdp->nxtlist; rdp->nxtlist = list; @@ -1587,10 +1536,6 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp) else break; } - smp_mb(); /* List handling before counting for rcu_barrier(). */ - rdp->qlen_lazy -= count_lazy; - rdp->qlen -= count; - rdp->n_cbs_invoked += count; /* Reinstate batch limit if we have worked down the excess. */ if (rdp->blimit == LONG_MAX && rdp->qlen <= qlowmark) @@ -1878,14 +1823,11 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu), rdp = this_cpu_ptr(rsp->rda); /* Add the callback to our list. */ + *rdp->nxttail[RCU_NEXT_TAIL] = head; + rdp->nxttail[RCU_NEXT_TAIL] = &head->next; rdp->qlen++; if (lazy) rdp->qlen_lazy++; - else - rcu_idle_count_callbacks_posted(); - smp_mb(); /* Count before adding callback for rcu_barrier(). */ - *rdp->nxttail[RCU_NEXT_TAIL] = head; - rdp->nxttail[RCU_NEXT_TAIL] = &head->next; if (__is_kfree_rcu_offset((unsigned long)func)) trace_rcu_kfree_callback(rsp->name, head, (unsigned long)func, @@ -1951,38 +1893,6 @@ void call_rcu_bh(struct rcu_head *head, void (*func)(struct rcu_head *rcu)) } EXPORT_SYMBOL_GPL(call_rcu_bh); -/* - * Because a context switch is a grace period for RCU-sched and RCU-bh, - * any blocking grace-period wait automatically implies a grace period - * if there is only one CPU online at any point time during execution - * of either synchronize_sched() or synchronize_rcu_bh(). It is OK to - * occasionally incorrectly indicate that there are multiple CPUs online - * when there was in fact only one the whole time, as this just adds - * some overhead: RCU still operates correctly. - * - * Of course, sampling num_online_cpus() with preemption enabled can - * give erroneous results if there are concurrent CPU-hotplug operations. - * For example, given a demonic sequence of preemptions in num_online_cpus() - * and CPU-hotplug operations, there could be two or more CPUs online at - * all times, but num_online_cpus() might well return one (or even zero). - * - * However, all such demonic sequences require at least one CPU-offline - * operation. Furthermore, rcu_blocking_is_gp() giving the wrong answer - * is only a problem if there is an RCU read-side critical section executing - * throughout. But RCU-sched and RCU-bh read-side critical sections - * disable either preemption or bh, which prevents a CPU from going offline. - * Therefore, the only way that rcu_blocking_is_gp() can incorrectly return - * that there is only one CPU when in fact there was more than one throughout - * is when there were no RCU readers in the system. If there are no - * RCU readers, the grace period by definition can be of zero length, - * regardless of the number of online CPUs. - */ -static inline int rcu_blocking_is_gp(void) -{ - might_sleep(); /* Check for RCU read-side critical section. */ - return num_online_cpus() <= 1; -} - /** * synchronize_sched - wait until an rcu-sched grace period has elapsed. * @@ -2256,10 +2166,11 @@ static int rcu_cpu_has_callbacks(int cpu) rcu_preempt_cpu_has_callbacks(cpu); } -/* - * RCU callback function for _rcu_barrier(). If we are last, wake - * up the task executing _rcu_barrier(). - */ +static DEFINE_PER_CPU(struct rcu_head, rcu_barrier_head) = {NULL}; +static atomic_t rcu_barrier_cpu_count; +static DEFINE_MUTEX(rcu_barrier_mutex); +static struct completion rcu_barrier_completion; + static void rcu_barrier_callback(struct rcu_head *notused) { if (atomic_dec_and_test(&rcu_barrier_cpu_count)) @@ -2289,94 +2200,27 @@ static void _rcu_barrier(struct rcu_state *rsp, void (*call_rcu_func)(struct rcu_head *head, void (*func)(struct rcu_head *head))) { - int cpu; - unsigned long flags; - struct rcu_data *rdp; - struct rcu_head rh; - - init_rcu_head_on_stack(&rh); - + BUG_ON(in_interrupt()); /* Take mutex to serialize concurrent rcu_barrier() requests. */ mutex_lock(&rcu_barrier_mutex); - - smp_mb(); /* Prevent any prior operations from leaking in. */ - - /* - * Initialize the count to one rather than to zero in order to - * avoid a too-soon return to zero in case of a short grace period - * (or preemption of this task). Also flag this task as doing - * an rcu_barrier(). This will prevent anyone else from adopting - * orphaned callbacks, which could cause otherwise failure if a - * CPU went offline and quickly came back online. To see this, - * consider the following sequence of events: - * - * 1. We cause CPU 0 to post an rcu_barrier_callback() callback. - * 2. CPU 1 goes offline, orphaning its callbacks. - * 3. CPU 0 adopts CPU 1's orphaned callbacks. - * 4. CPU 1 comes back online. - * 5. We cause CPU 1 to post an rcu_barrier_callback() callback. - * 6. Both rcu_barrier_callback() callbacks are invoked, awakening - * us -- but before CPU 1's orphaned callbacks are invoked!!! - */ init_completion(&rcu_barrier_completion); - atomic_set(&rcu_barrier_cpu_count, 1); - raw_spin_lock_irqsave(&rsp->onofflock, flags); - rsp->rcu_barrier_in_progress = current; - raw_spin_unlock_irqrestore(&rsp->onofflock, flags); - - /* - * Force every CPU with callbacks to register a new callback - * that will tell us when all the preceding callbacks have - * been invoked. If an offline CPU has callbacks, wait for - * it to either come back online or to finish orphaning those - * callbacks. - */ - for_each_possible_cpu(cpu) { - preempt_disable(); - rdp = per_cpu_ptr(rsp->rda, cpu); - if (cpu_is_offline(cpu)) { - preempt_enable(); - while (cpu_is_offline(cpu) && ACCESS_ONCE(rdp->qlen)) - schedule_timeout_interruptible(1); - } else if (ACCESS_ONCE(rdp->qlen)) { - smp_call_function_single(cpu, rcu_barrier_func, - (void *)call_rcu_func, 1); - preempt_enable(); - } else { - preempt_enable(); - } - } - /* - * Now that all online CPUs have rcu_barrier_callback() callbacks - * posted, we can adopt all of the orphaned callbacks and place - * an rcu_barrier_callback() callback after them. When that is done, - * we are guaranteed to have an rcu_barrier_callback() callback - * following every callback that could possibly have been - * registered before _rcu_barrier() was called. - */ - raw_spin_lock_irqsave(&rsp->onofflock, flags); - rcu_adopt_orphan_cbs(rsp); - rsp->rcu_barrier_in_progress = NULL; - raw_spin_unlock_irqrestore(&rsp->onofflock, flags); - atomic_inc(&rcu_barrier_cpu_count); - smp_mb__after_atomic_inc(); /* Ensure atomic_inc() before callback. */ - call_rcu_func(&rh, rcu_barrier_callback); - - /* - * Now that we have an rcu_barrier_callback() callback on each - * CPU, and thus each counted, remove the initial count. + * Initialize rcu_barrier_cpu_count to 1, then invoke + * rcu_barrier_func() on each CPU, so that each CPU also has + * incremented rcu_barrier_cpu_count. Only then is it safe to + * decrement rcu_barrier_cpu_count -- otherwise the first CPU + * might complete its grace period before all of the other CPUs + * did their increment, causing this function to return too + * early. Note that on_each_cpu() disables irqs, which prevents + * any CPUs from coming online or going offline until each online + * CPU has queued its RCU-barrier callback. */ + atomic_set(&rcu_barrier_cpu_count, 1); + on_each_cpu(rcu_barrier_func, (void *)call_rcu_func, 1); if (atomic_dec_and_test(&rcu_barrier_cpu_count)) complete(&rcu_barrier_completion); - - /* Wait for all rcu_barrier_callback() callbacks to be invoked. */ wait_for_completion(&rcu_barrier_completion); - - /* Other rcu_barrier() invocations can now safely proceed. */ mutex_unlock(&rcu_barrier_mutex); - - destroy_rcu_head_on_stack(&rh); } /** @@ -2573,7 +2417,7 @@ static void __init rcu_init_levelspread(struct rcu_state *rsp) for (i = NUM_RCU_LVLS - 1; i > 0; i--) rsp->levelspread[i] = CONFIG_RCU_FANOUT; - rsp->levelspread[0] = CONFIG_RCU_FANOUT_LEAF; + rsp->levelspread[0] = RCU_FANOUT_LEAF; } #else /* #ifdef CONFIG_RCU_FANOUT_EXACT */ static void __init rcu_init_levelspread(struct rcu_state *rsp) diff --git a/trunk/kernel/rcutree.h b/trunk/kernel/rcutree.h index 7f5d138dedf5..cdd1be0a4072 100644 --- a/trunk/kernel/rcutree.h +++ b/trunk/kernel/rcutree.h @@ -29,14 +29,18 @@ #include /* - * Define shape of hierarchy based on NR_CPUS, CONFIG_RCU_FANOUT, and - * CONFIG_RCU_FANOUT_LEAF. + * Define shape of hierarchy based on NR_CPUS and CONFIG_RCU_FANOUT. * In theory, it should be possible to add more levels straightforwardly. * In practice, this did work well going from three levels to four. * Of course, your mileage may vary. */ #define MAX_RCU_LVLS 4 -#define RCU_FANOUT_1 (CONFIG_RCU_FANOUT_LEAF) +#if CONFIG_RCU_FANOUT > 16 +#define RCU_FANOUT_LEAF 16 +#else /* #if CONFIG_RCU_FANOUT > 16 */ +#define RCU_FANOUT_LEAF (CONFIG_RCU_FANOUT) +#endif /* #else #if CONFIG_RCU_FANOUT > 16 */ +#define RCU_FANOUT_1 (RCU_FANOUT_LEAF) #define RCU_FANOUT_2 (RCU_FANOUT_1 * CONFIG_RCU_FANOUT) #define RCU_FANOUT_3 (RCU_FANOUT_2 * CONFIG_RCU_FANOUT) #define RCU_FANOUT_4 (RCU_FANOUT_3 * CONFIG_RCU_FANOUT) @@ -367,17 +371,6 @@ struct rcu_state { raw_spinlock_t onofflock; /* exclude on/offline and */ /* starting new GP. */ - struct rcu_head *orphan_nxtlist; /* Orphaned callbacks that */ - /* need a grace period. */ - struct rcu_head **orphan_nxttail; /* Tail of above. */ - struct rcu_head *orphan_donelist; /* Orphaned callbacks that */ - /* are ready to invoke. */ - struct rcu_head **orphan_donetail; /* Tail of above. */ - long qlen_lazy; /* Number of lazy callbacks. */ - long qlen; /* Total number of callbacks. */ - struct task_struct *rcu_barrier_in_progress; - /* Task doing rcu_barrier(), */ - /* or NULL if no barrier. */ raw_spinlock_t fqslock; /* Only one task forcing */ /* quiescent states. */ unsigned long jiffies_force_qs; /* Time at which to invoke */ @@ -430,6 +423,7 @@ DECLARE_PER_CPU(char, rcu_cpu_has_work); /* Forward declarations for rcutree_plugin.h */ static void rcu_bootup_announce(void); long rcu_batches_completed(void); +static void rcu_preempt_note_context_switch(int cpu); static int rcu_preempt_blocked_readers_cgp(struct rcu_node *rnp); #ifdef CONFIG_HOTPLUG_CPU static void rcu_report_unblock_qs_rnp(struct rcu_node *rnp, @@ -477,7 +471,6 @@ static void __cpuinit rcu_prepare_kthreads(int cpu); static void rcu_prepare_for_idle_init(int cpu); static void rcu_cleanup_after_idle(int cpu); static void rcu_prepare_for_idle(int cpu); -static void rcu_idle_count_callbacks_posted(void); static void print_cpu_stall_info_begin(void); static void print_cpu_stall_info(struct rcu_state *rsp, int cpu); static void print_cpu_stall_info_end(void); diff --git a/trunk/kernel/rcutree_plugin.h b/trunk/kernel/rcutree_plugin.h index 2411000d9869..c023464816be 100644 --- a/trunk/kernel/rcutree_plugin.h +++ b/trunk/kernel/rcutree_plugin.h @@ -153,7 +153,7 @@ static void rcu_preempt_qs(int cpu) * * Caller must disable preemption. */ -void rcu_preempt_note_context_switch(void) +static void rcu_preempt_note_context_switch(int cpu) { struct task_struct *t = current; unsigned long flags; @@ -164,7 +164,7 @@ void rcu_preempt_note_context_switch(void) (t->rcu_read_unlock_special & RCU_READ_UNLOCK_BLOCKED) == 0) { /* Possibly blocking in an RCU read-side critical section. */ - rdp = __this_cpu_ptr(rcu_preempt_state.rda); + rdp = per_cpu_ptr(rcu_preempt_state.rda, cpu); rnp = rdp->mynode; raw_spin_lock_irqsave(&rnp->lock, flags); t->rcu_read_unlock_special |= RCU_READ_UNLOCK_BLOCKED; @@ -228,7 +228,7 @@ void rcu_preempt_note_context_switch(void) * means that we continue to block the current grace period. */ local_irq_save(flags); - rcu_preempt_qs(smp_processor_id()); + rcu_preempt_qs(cpu); local_irq_restore(flags); } @@ -969,6 +969,22 @@ static void __init __rcu_init_preempt(void) rcu_init_one(&rcu_preempt_state, &rcu_preempt_data); } +/* + * Check for a task exiting while in a preemptible-RCU read-side + * critical section, clean up if so. No need to issue warnings, + * as debug_check_no_locks_held() already does this if lockdep + * is enabled. + */ +void exit_rcu(void) +{ + struct task_struct *t = current; + + if (t->rcu_read_lock_nesting == 0) + return; + t->rcu_read_lock_nesting = 1; + __rcu_read_unlock(); +} + #else /* #ifdef CONFIG_TREE_PREEMPT_RCU */ static struct rcu_state *rcu_state = &rcu_sched_state; @@ -1001,6 +1017,14 @@ void rcu_force_quiescent_state(void) } EXPORT_SYMBOL_GPL(rcu_force_quiescent_state); +/* + * Because preemptible RCU does not exist, we never have to check for + * CPUs being in quiescent states. + */ +static void rcu_preempt_note_context_switch(int cpu) +{ +} + /* * Because preemptible RCU does not exist, there are never any preempted * RCU readers. @@ -1914,14 +1938,6 @@ static void rcu_prepare_for_idle(int cpu) { } -/* - * Don't bother keeping a running count of the number of RCU callbacks - * posted because CONFIG_RCU_FAST_NO_HZ=n. - */ -static void rcu_idle_count_callbacks_posted(void) -{ -} - #else /* #if !defined(CONFIG_RCU_FAST_NO_HZ) */ /* @@ -1962,20 +1978,11 @@ static void rcu_idle_count_callbacks_posted(void) #define RCU_IDLE_GP_DELAY 6 /* Roughly one grace period. */ #define RCU_IDLE_LAZY_GP_DELAY (6 * HZ) /* Roughly six seconds. */ -/* Loop counter for rcu_prepare_for_idle(). */ static DEFINE_PER_CPU(int, rcu_dyntick_drain); -/* If rcu_dyntick_holdoff==jiffies, don't try to enter dyntick-idle mode. */ static DEFINE_PER_CPU(unsigned long, rcu_dyntick_holdoff); -/* Timer to awaken the CPU if it enters dyntick-idle mode with callbacks. */ -static DEFINE_PER_CPU(struct timer_list, rcu_idle_gp_timer); -/* Scheduled expiry time for rcu_idle_gp_timer to allow reposting. */ -static DEFINE_PER_CPU(unsigned long, rcu_idle_gp_timer_expires); -/* Enable special processing on first attempt to enter dyntick-idle mode. */ -static DEFINE_PER_CPU(bool, rcu_idle_first_pass); -/* Running count of non-lazy callbacks posted, never decremented. */ -static DEFINE_PER_CPU(unsigned long, rcu_nonlazy_posted); -/* Snapshot of rcu_nonlazy_posted to detect meaningful exits from idle. */ -static DEFINE_PER_CPU(unsigned long, rcu_nonlazy_posted_snap); +static DEFINE_PER_CPU(struct hrtimer, rcu_idle_gp_timer); +static ktime_t rcu_idle_gp_wait; /* If some non-lazy callbacks. */ +static ktime_t rcu_idle_lazy_gp_wait; /* If only lazy callbacks. */ /* * Allow the CPU to enter dyntick-idle mode if either: (1) There are no @@ -1988,8 +1995,6 @@ static DEFINE_PER_CPU(unsigned long, rcu_nonlazy_posted_snap); */ int rcu_needs_cpu(int cpu) { - /* Flag a new idle sojourn to the idle-entry state machine. */ - per_cpu(rcu_idle_first_pass, cpu) = 1; /* If no callbacks, RCU doesn't need the CPU. */ if (!rcu_cpu_has_callbacks(cpu)) return 0; @@ -2039,35 +2044,17 @@ static bool rcu_cpu_has_nonlazy_callbacks(int cpu) rcu_preempt_cpu_has_nonlazy_callbacks(cpu); } -/* - * Handler for smp_call_function_single(). The only point of this - * handler is to wake the CPU up, so the handler does only tracing. - */ -void rcu_idle_demigrate(void *unused) -{ - trace_rcu_prep_idle("Demigrate"); -} - /* * Timer handler used to force CPU to start pushing its remaining RCU * callbacks in the case where it entered dyntick-idle mode with callbacks * pending. The hander doesn't really need to do anything because the * real work is done upon re-entry to idle, or by the next scheduling-clock * interrupt should idle not be re-entered. - * - * One special case: the timer gets migrated without awakening the CPU - * on which the timer was scheduled on. In this case, we must wake up - * that CPU. We do so with smp_call_function_single(). */ -static void rcu_idle_gp_timer_func(unsigned long cpu_in) +static enum hrtimer_restart rcu_idle_gp_timer_func(struct hrtimer *hrtp) { - int cpu = (int)cpu_in; - trace_rcu_prep_idle("Timer"); - if (cpu != smp_processor_id()) - smp_call_function_single(cpu, rcu_idle_demigrate, NULL, 0); - else - WARN_ON_ONCE(1); /* Getting here can hang the system... */ + return HRTIMER_NORESTART; } /* @@ -2075,11 +2062,19 @@ static void rcu_idle_gp_timer_func(unsigned long cpu_in) */ static void rcu_prepare_for_idle_init(int cpu) { - per_cpu(rcu_dyntick_holdoff, cpu) = jiffies - 1; - setup_timer(&per_cpu(rcu_idle_gp_timer, cpu), - rcu_idle_gp_timer_func, cpu); - per_cpu(rcu_idle_gp_timer_expires, cpu) = jiffies - 1; - per_cpu(rcu_idle_first_pass, cpu) = 1; + static int firsttime = 1; + struct hrtimer *hrtp = &per_cpu(rcu_idle_gp_timer, cpu); + + hrtimer_init(hrtp, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtp->function = rcu_idle_gp_timer_func; + if (firsttime) { + unsigned int upj = jiffies_to_usecs(RCU_IDLE_GP_DELAY); + + rcu_idle_gp_wait = ns_to_ktime(upj * (u64)1000); + upj = jiffies_to_usecs(RCU_IDLE_LAZY_GP_DELAY); + rcu_idle_lazy_gp_wait = ns_to_ktime(upj * (u64)1000); + firsttime = 0; + } } /* @@ -2089,8 +2084,7 @@ static void rcu_prepare_for_idle_init(int cpu) */ static void rcu_cleanup_after_idle(int cpu) { - del_timer(&per_cpu(rcu_idle_gp_timer, cpu)); - trace_rcu_prep_idle("Cleanup after idle"); + hrtimer_cancel(&per_cpu(rcu_idle_gp_timer, cpu)); } /* @@ -2114,29 +2108,6 @@ static void rcu_cleanup_after_idle(int cpu) */ static void rcu_prepare_for_idle(int cpu) { - struct timer_list *tp; - - /* - * If this is an idle re-entry, for example, due to use of - * RCU_NONIDLE() or the new idle-loop tracing API within the idle - * loop, then don't take any state-machine actions, unless the - * momentary exit from idle queued additional non-lazy callbacks. - * Instead, repost the rcu_idle_gp_timer if this CPU has callbacks - * pending. - */ - if (!per_cpu(rcu_idle_first_pass, cpu) && - (per_cpu(rcu_nonlazy_posted, cpu) == - per_cpu(rcu_nonlazy_posted_snap, cpu))) { - if (rcu_cpu_has_callbacks(cpu)) { - tp = &per_cpu(rcu_idle_gp_timer, cpu); - mod_timer_pinned(tp, per_cpu(rcu_idle_gp_timer_expires, cpu)); - } - return; - } - per_cpu(rcu_idle_first_pass, cpu) = 0; - per_cpu(rcu_nonlazy_posted_snap, cpu) = - per_cpu(rcu_nonlazy_posted, cpu) - 1; - /* * If there are no callbacks on this CPU, enter dyntick-idle mode. * Also reset state to avoid prejudicing later attempts. @@ -2169,15 +2140,11 @@ static void rcu_prepare_for_idle(int cpu) per_cpu(rcu_dyntick_drain, cpu) = 0; per_cpu(rcu_dyntick_holdoff, cpu) = jiffies; if (rcu_cpu_has_nonlazy_callbacks(cpu)) - per_cpu(rcu_idle_gp_timer_expires, cpu) = - jiffies + RCU_IDLE_GP_DELAY; + hrtimer_start(&per_cpu(rcu_idle_gp_timer, cpu), + rcu_idle_gp_wait, HRTIMER_MODE_REL); else - per_cpu(rcu_idle_gp_timer_expires, cpu) = - jiffies + RCU_IDLE_LAZY_GP_DELAY; - tp = &per_cpu(rcu_idle_gp_timer, cpu); - mod_timer_pinned(tp, per_cpu(rcu_idle_gp_timer_expires, cpu)); - per_cpu(rcu_nonlazy_posted_snap, cpu) = - per_cpu(rcu_nonlazy_posted, cpu); + hrtimer_start(&per_cpu(rcu_idle_gp_timer, cpu), + rcu_idle_lazy_gp_wait, HRTIMER_MODE_REL); return; /* Nothing more to do immediately. */ } else if (--per_cpu(rcu_dyntick_drain, cpu) <= 0) { /* We have hit the limit, so time to give up. */ @@ -2217,19 +2184,6 @@ static void rcu_prepare_for_idle(int cpu) trace_rcu_prep_idle("Callbacks drained"); } -/* - * Keep a running count of the number of non-lazy callbacks posted - * on this CPU. This running counter (which is never decremented) allows - * rcu_prepare_for_idle() to detect when something out of the idle loop - * posts a callback, even if an equal number of callbacks are invoked. - * Of course, callbacks should only be posted from within a trace event - * designed to be called from idle or from within RCU_NONIDLE(). - */ -static void rcu_idle_count_callbacks_posted(void) -{ - __this_cpu_add(rcu_nonlazy_posted, 1); -} - #endif /* #else #if !defined(CONFIG_RCU_FAST_NO_HZ) */ #ifdef CONFIG_RCU_CPU_STALL_INFO @@ -2238,12 +2192,14 @@ static void rcu_idle_count_callbacks_posted(void) static void print_cpu_stall_fast_no_hz(char *cp, int cpu) { - struct timer_list *tltp = &per_cpu(rcu_idle_gp_timer, cpu); + struct hrtimer *hrtp = &per_cpu(rcu_idle_gp_timer, cpu); - sprintf(cp, "drain=%d %c timer=%lu", + sprintf(cp, "drain=%d %c timer=%lld", per_cpu(rcu_dyntick_drain, cpu), per_cpu(rcu_dyntick_holdoff, cpu) == jiffies ? 'H' : '.', - timer_pending(tltp) ? tltp->expires - jiffies : -1); + hrtimer_active(hrtp) + ? ktime_to_us(hrtimer_get_remaining(hrtp)) + : -1); } #else /* #ifdef CONFIG_RCU_FAST_NO_HZ */ diff --git a/trunk/kernel/rcutree_trace.c b/trunk/kernel/rcutree_trace.c index d4bc16ddd1d4..ed459edeff43 100644 --- a/trunk/kernel/rcutree_trace.c +++ b/trunk/kernel/rcutree_trace.c @@ -271,13 +271,13 @@ static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp) gpnum = rsp->gpnum; seq_printf(m, "c=%lu g=%lu s=%d jfq=%ld j=%x " - "nfqs=%lu/nfqsng=%lu(%lu) fqlh=%lu oqlen=%ld/%ld\n", + "nfqs=%lu/nfqsng=%lu(%lu) fqlh=%lu\n", rsp->completed, gpnum, rsp->fqs_state, (long)(rsp->jiffies_force_qs - jiffies), (int)(jiffies & 0xffff), rsp->n_force_qs, rsp->n_force_qs_ngp, rsp->n_force_qs - rsp->n_force_qs_ngp, - rsp->n_force_qs_lh, rsp->qlen_lazy, rsp->qlen); + rsp->n_force_qs_lh); for (rnp = &rsp->node[0]; rnp - &rsp->node[0] < NUM_RCU_NODES; rnp++) { if (rnp->level != level) { seq_puts(m, "\n"); diff --git a/trunk/kernel/sched/Makefile b/trunk/kernel/sched/Makefile index 173ea52f3af0..9a7dd35102a3 100644 --- a/trunk/kernel/sched/Makefile +++ b/trunk/kernel/sched/Makefile @@ -16,3 +16,5 @@ obj-$(CONFIG_SMP) += cpupri.o obj-$(CONFIG_SCHED_AUTOGROUP) += auto_group.o obj-$(CONFIG_SCHEDSTATS) += stats.o obj-$(CONFIG_SCHED_DEBUG) += debug.o + + diff --git a/trunk/kernel/sched/core.c b/trunk/kernel/sched/core.c index ea8a4769fea5..0533a688ce22 100644 --- a/trunk/kernel/sched/core.c +++ b/trunk/kernel/sched/core.c @@ -83,7 +83,6 @@ #include "sched.h" #include "../workqueue_sched.h" -#include "../smpboot.h" #define CREATE_TRACE_POINTS #include @@ -2084,7 +2083,6 @@ context_switch(struct rq *rq, struct task_struct *prev, #endif /* Here we just switch the register state and the stack. */ - rcu_switch_from(prev); switch_to(prev, next, prev); barrier(); @@ -6384,8 +6382,6 @@ static int __sdt_alloc(const struct cpumask *cpu_map) if (!sg) return -ENOMEM; - sg->next = sg; - *per_cpu_ptr(sdd->sg, j) = sg; sgp = kzalloc_node(sizeof(struct sched_group_power), @@ -7063,7 +7059,6 @@ void __init sched_init(void) /* May be allocated at isolcpus cmdline parse time */ if (cpu_isolated_map == NULL) zalloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT); - idle_thread_set_boot_cpu(); #endif init_sched_fair_class(); diff --git a/trunk/kernel/seccomp.c b/trunk/kernel/seccomp.c index ee376beedaf9..e8d76c5895ea 100644 --- a/trunk/kernel/seccomp.c +++ b/trunk/kernel/seccomp.c @@ -3,357 +3,16 @@ * * Copyright 2004-2005 Andrea Arcangeli * - * Copyright (C) 2012 Google, Inc. - * Will Drewry - * - * This defines a simple but solid secure-computing facility. - * - * Mode 1 uses a fixed list of allowed system calls. - * Mode 2 allows user-defined system call filters in the form - * of Berkeley Packet Filters/Linux Socket Filters. + * This defines a simple but solid secure-computing mode. */ -#include #include -#include -#include #include +#include +#include /* #define SECCOMP_DEBUG 1 */ - -#ifdef CONFIG_SECCOMP_FILTER -#include -#include -#include -#include -#include -#include -#include - -/** - * struct seccomp_filter - container for seccomp BPF programs - * - * @usage: reference count to manage the object lifetime. - * get/put helpers should be used when accessing an instance - * outside of a lifetime-guarded section. In general, this - * is only needed for handling filters shared across tasks. - * @prev: points to a previously installed, or inherited, filter - * @len: the number of instructions in the program - * @insns: the BPF program instructions to evaluate - * - * seccomp_filter objects are organized in a tree linked via the @prev - * pointer. For any task, it appears to be a singly-linked list starting - * with current->seccomp.filter, the most recently attached or inherited filter. - * However, multiple filters may share a @prev node, by way of fork(), which - * results in a unidirectional tree existing in memory. This is similar to - * how namespaces work. - * - * seccomp_filter objects should never be modified after being attached - * to a task_struct (other than @usage). - */ -struct seccomp_filter { - atomic_t usage; - struct seccomp_filter *prev; - unsigned short len; /* Instruction count */ - struct sock_filter insns[]; -}; - -/* Limit any path through the tree to 256KB worth of instructions. */ -#define MAX_INSNS_PER_PATH ((1 << 18) / sizeof(struct sock_filter)) - -/** - * get_u32 - returns a u32 offset into data - * @data: a unsigned 64 bit value - * @index: 0 or 1 to return the first or second 32-bits - * - * This inline exists to hide the length of unsigned long. If a 32-bit - * unsigned long is passed in, it will be extended and the top 32-bits will be - * 0. If it is a 64-bit unsigned long, then whatever data is resident will be - * properly returned. - * - * Endianness is explicitly ignored and left for BPF program authors to manage - * as per the specific architecture. - */ -static inline u32 get_u32(u64 data, int index) -{ - return ((u32 *)&data)[index]; -} - -/* Helper for bpf_load below. */ -#define BPF_DATA(_name) offsetof(struct seccomp_data, _name) -/** - * bpf_load: checks and returns a pointer to the requested offset - * @off: offset into struct seccomp_data to load from - * - * Returns the requested 32-bits of data. - * seccomp_check_filter() should assure that @off is 32-bit aligned - * and not out of bounds. Failure to do so is a BUG. - */ -u32 seccomp_bpf_load(int off) -{ - struct pt_regs *regs = task_pt_regs(current); - if (off == BPF_DATA(nr)) - return syscall_get_nr(current, regs); - if (off == BPF_DATA(arch)) - return syscall_get_arch(current, regs); - if (off >= BPF_DATA(args[0]) && off < BPF_DATA(args[6])) { - unsigned long value; - int arg = (off - BPF_DATA(args[0])) / sizeof(u64); - int index = !!(off % sizeof(u64)); - syscall_get_arguments(current, regs, arg, 1, &value); - return get_u32(value, index); - } - if (off == BPF_DATA(instruction_pointer)) - return get_u32(KSTK_EIP(current), 0); - if (off == BPF_DATA(instruction_pointer) + sizeof(u32)) - return get_u32(KSTK_EIP(current), 1); - /* seccomp_check_filter should make this impossible. */ - BUG(); -} - -/** - * seccomp_check_filter - verify seccomp filter code - * @filter: filter to verify - * @flen: length of filter - * - * Takes a previously checked filter (by sk_chk_filter) and - * redirects all filter code that loads struct sk_buff data - * and related data through seccomp_bpf_load. It also - * enforces length and alignment checking of those loads. - * - * Returns 0 if the rule set is legal or -EINVAL if not. - */ -static int seccomp_check_filter(struct sock_filter *filter, unsigned int flen) -{ - int pc; - for (pc = 0; pc < flen; pc++) { - struct sock_filter *ftest = &filter[pc]; - u16 code = ftest->code; - u32 k = ftest->k; - - switch (code) { - case BPF_S_LD_W_ABS: - ftest->code = BPF_S_ANC_SECCOMP_LD_W; - /* 32-bit aligned and not out of bounds. */ - if (k >= sizeof(struct seccomp_data) || k & 3) - return -EINVAL; - continue; - case BPF_S_LD_W_LEN: - ftest->code = BPF_S_LD_IMM; - ftest->k = sizeof(struct seccomp_data); - continue; - case BPF_S_LDX_W_LEN: - ftest->code = BPF_S_LDX_IMM; - ftest->k = sizeof(struct seccomp_data); - continue; - /* Explicitly include allowed calls. */ - case BPF_S_RET_K: - case BPF_S_RET_A: - case BPF_S_ALU_ADD_K: - case BPF_S_ALU_ADD_X: - case BPF_S_ALU_SUB_K: - case BPF_S_ALU_SUB_X: - case BPF_S_ALU_MUL_K: - case BPF_S_ALU_MUL_X: - case BPF_S_ALU_DIV_X: - case BPF_S_ALU_AND_K: - case BPF_S_ALU_AND_X: - case BPF_S_ALU_OR_K: - case BPF_S_ALU_OR_X: - case BPF_S_ALU_LSH_K: - case BPF_S_ALU_LSH_X: - case BPF_S_ALU_RSH_K: - case BPF_S_ALU_RSH_X: - case BPF_S_ALU_NEG: - case BPF_S_LD_IMM: - case BPF_S_LDX_IMM: - case BPF_S_MISC_TAX: - case BPF_S_MISC_TXA: - case BPF_S_ALU_DIV_K: - case BPF_S_LD_MEM: - case BPF_S_LDX_MEM: - case BPF_S_ST: - case BPF_S_STX: - case BPF_S_JMP_JA: - case BPF_S_JMP_JEQ_K: - case BPF_S_JMP_JEQ_X: - case BPF_S_JMP_JGE_K: - case BPF_S_JMP_JGE_X: - case BPF_S_JMP_JGT_K: - case BPF_S_JMP_JGT_X: - case BPF_S_JMP_JSET_K: - case BPF_S_JMP_JSET_X: - continue; - default: - return -EINVAL; - } - } - return 0; -} - -/** - * seccomp_run_filters - evaluates all seccomp filters against @syscall - * @syscall: number of the current system call - * - * Returns valid seccomp BPF response codes. - */ -static u32 seccomp_run_filters(int syscall) -{ - struct seccomp_filter *f; - u32 ret = SECCOMP_RET_ALLOW; - - /* Ensure unexpected behavior doesn't result in failing open. */ - if (WARN_ON(current->seccomp.filter == NULL)) - return SECCOMP_RET_KILL; - - /* - * All filters in the list are evaluated and the lowest BPF return - * value always takes priority (ignoring the DATA). - */ - for (f = current->seccomp.filter; f; f = f->prev) { - u32 cur_ret = sk_run_filter(NULL, f->insns); - if ((cur_ret & SECCOMP_RET_ACTION) < (ret & SECCOMP_RET_ACTION)) - ret = cur_ret; - } - return ret; -} - -/** - * seccomp_attach_filter: Attaches a seccomp filter to current. - * @fprog: BPF program to install - * - * Returns 0 on success or an errno on failure. - */ -static long seccomp_attach_filter(struct sock_fprog *fprog) -{ - struct seccomp_filter *filter; - unsigned long fp_size = fprog->len * sizeof(struct sock_filter); - unsigned long total_insns = fprog->len; - long ret; - - if (fprog->len == 0 || fprog->len > BPF_MAXINSNS) - return -EINVAL; - - for (filter = current->seccomp.filter; filter; filter = filter->prev) - total_insns += filter->len + 4; /* include a 4 instr penalty */ - if (total_insns > MAX_INSNS_PER_PATH) - return -ENOMEM; - - /* - * Installing a seccomp filter requires that the task have - * CAP_SYS_ADMIN in its namespace or be running with no_new_privs. - * This avoids scenarios where unprivileged tasks can affect the - * behavior of privileged children. - */ - if (!current->no_new_privs && - security_capable_noaudit(current_cred(), current_user_ns(), - CAP_SYS_ADMIN) != 0) - return -EACCES; - - /* Allocate a new seccomp_filter */ - filter = kzalloc(sizeof(struct seccomp_filter) + fp_size, - GFP_KERNEL|__GFP_NOWARN); - if (!filter) - return -ENOMEM; - atomic_set(&filter->usage, 1); - filter->len = fprog->len; - - /* Copy the instructions from fprog. */ - ret = -EFAULT; - if (copy_from_user(filter->insns, fprog->filter, fp_size)) - goto fail; - - /* Check and rewrite the fprog via the skb checker */ - ret = sk_chk_filter(filter->insns, filter->len); - if (ret) - goto fail; - - /* Check and rewrite the fprog for seccomp use */ - ret = seccomp_check_filter(filter->insns, filter->len); - if (ret) - goto fail; - - /* - * If there is an existing filter, make it the prev and don't drop its - * task reference. - */ - filter->prev = current->seccomp.filter; - current->seccomp.filter = filter; - return 0; -fail: - kfree(filter); - return ret; -} - -/** - * seccomp_attach_user_filter - attaches a user-supplied sock_fprog - * @user_filter: pointer to the user data containing a sock_fprog. - * - * Returns 0 on success and non-zero otherwise. - */ -long seccomp_attach_user_filter(char __user *user_filter) -{ - struct sock_fprog fprog; - long ret = -EFAULT; - -#ifdef CONFIG_COMPAT - if (is_compat_task()) { - struct compat_sock_fprog fprog32; - if (copy_from_user(&fprog32, user_filter, sizeof(fprog32))) - goto out; - fprog.len = fprog32.len; - fprog.filter = compat_ptr(fprog32.filter); - } else /* falls through to the if below. */ -#endif - if (copy_from_user(&fprog, user_filter, sizeof(fprog))) - goto out; - ret = seccomp_attach_filter(&fprog); -out: - return ret; -} - -/* get_seccomp_filter - increments the reference count of the filter on @tsk */ -void get_seccomp_filter(struct task_struct *tsk) -{ - struct seccomp_filter *orig = tsk->seccomp.filter; - if (!orig) - return; - /* Reference count is bounded by the number of total processes. */ - atomic_inc(&orig->usage); -} - -/* put_seccomp_filter - decrements the ref count of tsk->seccomp.filter */ -void put_seccomp_filter(struct task_struct *tsk) -{ - struct seccomp_filter *orig = tsk->seccomp.filter; - /* Clean up single-reference branches iteratively. */ - while (orig && atomic_dec_and_test(&orig->usage)) { - struct seccomp_filter *freeme = orig; - orig = orig->prev; - kfree(freeme); - } -} - -/** - * seccomp_send_sigsys - signals the task to allow in-process syscall emulation - * @syscall: syscall number to send to userland - * @reason: filter-supplied reason code to send to userland (via si_errno) - * - * Forces a SIGSYS with a code of SYS_SECCOMP and related sigsys info. - */ -static void seccomp_send_sigsys(int syscall, int reason) -{ - struct siginfo info; - memset(&info, 0, sizeof(info)); - info.si_signo = SIGSYS; - info.si_code = SYS_SECCOMP; - info.si_call_addr = (void __user *)KSTK_EIP(current); - info.si_errno = reason; - info.si_arch = syscall_get_arch(current, task_pt_regs(current)); - info.si_syscall = syscall; - force_sig_info(SIGSYS, &info, current); -} -#endif /* CONFIG_SECCOMP_FILTER */ +#define NR_SECCOMP_MODES 1 /* * Secure computing mode 1 allows only read/write/exit/sigreturn. @@ -372,15 +31,13 @@ static int mode1_syscalls_32[] = { }; #endif -int __secure_computing(int this_syscall) +void __secure_computing(int this_syscall) { int mode = current->seccomp.mode; - int exit_sig = 0; - int *syscall; - u32 ret; + int * syscall; switch (mode) { - case SECCOMP_MODE_STRICT: + case 1: syscall = mode1_syscalls; #ifdef CONFIG_COMPAT if (is_compat_task()) @@ -388,54 +45,9 @@ int __secure_computing(int this_syscall) #endif do { if (*syscall == this_syscall) - return 0; + return; } while (*++syscall); - exit_sig = SIGKILL; - ret = SECCOMP_RET_KILL; - break; -#ifdef CONFIG_SECCOMP_FILTER - case SECCOMP_MODE_FILTER: { - int data; - ret = seccomp_run_filters(this_syscall); - data = ret & SECCOMP_RET_DATA; - ret &= SECCOMP_RET_ACTION; - switch (ret) { - case SECCOMP_RET_ERRNO: - /* Set the low-order 16-bits as a errno. */ - syscall_set_return_value(current, task_pt_regs(current), - -data, 0); - goto skip; - case SECCOMP_RET_TRAP: - /* Show the handler the original registers. */ - syscall_rollback(current, task_pt_regs(current)); - /* Let the filter pass back 16 bits of data. */ - seccomp_send_sigsys(this_syscall, data); - goto skip; - case SECCOMP_RET_TRACE: - /* Skip these calls if there is no tracer. */ - if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP)) - goto skip; - /* Allow the BPF to provide the event message */ - ptrace_event(PTRACE_EVENT_SECCOMP, data); - /* - * The delivery of a fatal signal during event - * notification may silently skip tracer notification. - * Terminating the task now avoids executing a system - * call that may not be intended. - */ - if (fatal_signal_pending(current)) - break; - return 0; - case SECCOMP_RET_ALLOW: - return 0; - case SECCOMP_RET_KILL: - default: - break; - } - exit_sig = SIGSYS; break; - } -#endif default: BUG(); } @@ -443,13 +55,8 @@ int __secure_computing(int this_syscall) #ifdef SECCOMP_DEBUG dump_stack(); #endif - audit_seccomp(this_syscall, exit_sig, ret); - do_exit(exit_sig); -#ifdef CONFIG_SECCOMP_FILTER -skip: - audit_seccomp(this_syscall, exit_sig, ret); -#endif - return -1; + audit_seccomp(this_syscall); + do_exit(SIGKILL); } long prctl_get_seccomp(void) @@ -457,48 +64,25 @@ long prctl_get_seccomp(void) return current->seccomp.mode; } -/** - * prctl_set_seccomp: configures current->seccomp.mode - * @seccomp_mode: requested mode to use - * @filter: optional struct sock_fprog for use with SECCOMP_MODE_FILTER - * - * This function may be called repeatedly with a @seccomp_mode of - * SECCOMP_MODE_FILTER to install additional filters. Every filter - * successfully installed will be evaluated (in reverse order) for each system - * call the task makes. - * - * Once current->seccomp.mode is non-zero, it may not be changed. - * - * Returns 0 on success or -EINVAL on failure. - */ -long prctl_set_seccomp(unsigned long seccomp_mode, char __user *filter) +long prctl_set_seccomp(unsigned long seccomp_mode) { - long ret = -EINVAL; + long ret; - if (current->seccomp.mode && - current->seccomp.mode != seccomp_mode) + /* can set it only once to be even more secure */ + ret = -EPERM; + if (unlikely(current->seccomp.mode)) goto out; - switch (seccomp_mode) { - case SECCOMP_MODE_STRICT: - ret = 0; + ret = -EINVAL; + if (seccomp_mode && seccomp_mode <= NR_SECCOMP_MODES) { + current->seccomp.mode = seccomp_mode; + set_thread_flag(TIF_SECCOMP); #ifdef TIF_NOTSC disable_TSC(); #endif - break; -#ifdef CONFIG_SECCOMP_FILTER - case SECCOMP_MODE_FILTER: - ret = seccomp_attach_user_filter(filter); - if (ret) - goto out; - break; -#endif - default: - goto out; + ret = 0; } - current->seccomp.mode = seccomp_mode; - set_thread_flag(TIF_SECCOMP); -out: + out: return ret; } diff --git a/trunk/kernel/signal.c b/trunk/kernel/signal.c index 1a006b5d9d9d..17afcaf582d0 100644 --- a/trunk/kernel/signal.c +++ b/trunk/kernel/signal.c @@ -160,7 +160,7 @@ void recalc_sigpending(void) #define SYNCHRONOUS_MASK \ (sigmask(SIGSEGV) | sigmask(SIGBUS) | sigmask(SIGILL) | \ - sigmask(SIGTRAP) | sigmask(SIGFPE) | sigmask(SIGSYS)) + sigmask(SIGTRAP) | sigmask(SIGFPE)) int next_signal(struct sigpending *pending, sigset_t *mask) { @@ -2706,13 +2706,6 @@ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from) err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_ptr, &to->si_ptr); break; -#ifdef __ARCH_SIGSYS - case __SI_SYS: - err |= __put_user(from->si_call_addr, &to->si_call_addr); - err |= __put_user(from->si_syscall, &to->si_syscall); - err |= __put_user(from->si_arch, &to->si_arch); - break; -#endif default: /* this is just in case for now ... */ err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); diff --git a/trunk/kernel/smp.c b/trunk/kernel/smp.c index d0ae5b24875e..2f8b10ecf759 100644 --- a/trunk/kernel/smp.c +++ b/trunk/kernel/smp.c @@ -13,8 +13,6 @@ #include #include -#include "smpboot.h" - #ifdef CONFIG_USE_GENERIC_SMP_HELPERS static struct { struct list_head queue; @@ -671,8 +669,6 @@ void __init smp_init(void) { unsigned int cpu; - idle_threads_init(); - /* FIXME: This should be done in userspace --RR */ for_each_present_cpu(cpu) { if (num_online_cpus() >= setup_max_cpus) @@ -795,26 +791,3 @@ void on_each_cpu_cond(bool (*cond_func)(int cpu, void *info), } } EXPORT_SYMBOL(on_each_cpu_cond); - -static void do_nothing(void *unused) -{ -} - -/** - * kick_all_cpus_sync - Force all cpus out of idle - * - * Used to synchronize the update of pm_idle function pointer. It's - * called after the pointer is updated and returns after the dummy - * callback function has been executed on all cpus. The execution of - * the function can only happen on the remote cpus after they have - * left the idle function which had been called via pm_idle function - * pointer. So it's guaranteed that nothing uses the previous pointer - * anymore. - */ -void kick_all_cpus_sync(void) -{ - /* Make sure the change is visible before we kick the cpus */ - smp_mb(); - smp_call_function(do_nothing, NULL, 1); -} -EXPORT_SYMBOL_GPL(kick_all_cpus_sync); diff --git a/trunk/kernel/smpboot.c b/trunk/kernel/smpboot.c deleted file mode 100644 index e1a797e028a3..000000000000 --- a/trunk/kernel/smpboot.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Common SMP CPU bringup/teardown functions - */ -#include -#include -#include -#include -#include - -#include "smpboot.h" - -#ifdef CONFIG_GENERIC_SMP_IDLE_THREAD -/* - * For the hotplug case we keep the task structs around and reuse - * them. - */ -static DEFINE_PER_CPU(struct task_struct *, idle_threads); - -struct task_struct * __cpuinit idle_thread_get(unsigned int cpu) -{ - struct task_struct *tsk = per_cpu(idle_threads, cpu); - - if (!tsk) - return ERR_PTR(-ENOMEM); - init_idle(tsk, cpu); - return tsk; -} - -void __init idle_thread_set_boot_cpu(void) -{ - per_cpu(idle_threads, smp_processor_id()) = current; -} - -static inline void idle_init(unsigned int cpu) -{ - struct task_struct *tsk = per_cpu(idle_threads, cpu); - - if (!tsk) { - tsk = fork_idle(cpu); - if (IS_ERR(tsk)) - pr_err("SMP: fork_idle() failed for CPU %u\n", cpu); - else - per_cpu(idle_threads, cpu) = tsk; - } -} - -/** - * idle_thread_init - Initialize the idle thread for a cpu - * @cpu: The cpu for which the idle thread should be initialized - * - * Creates the thread if it does not exist. - */ -void __init idle_threads_init(void) -{ - unsigned int cpu; - - for_each_possible_cpu(cpu) { - if (cpu != smp_processor_id()) - idle_init(cpu); - } -} -#endif diff --git a/trunk/kernel/smpboot.h b/trunk/kernel/smpboot.h deleted file mode 100644 index 80c0acfb8472..000000000000 --- a/trunk/kernel/smpboot.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef SMPBOOT_H -#define SMPBOOT_H - -struct task_struct; - -int smpboot_prepare(unsigned int cpu); - -#ifdef CONFIG_GENERIC_SMP_IDLE_THREAD -struct task_struct *idle_thread_get(unsigned int cpu); -void idle_thread_set_boot_cpu(void); -void idle_threads_init(void); -#else -static inline struct task_struct *idle_thread_get(unsigned int cpu) { return NULL; } -static inline void idle_thread_set_boot_cpu(void) { } -static inline void idle_threads_init(void) { } -#endif - -#endif diff --git a/trunk/kernel/srcu.c b/trunk/kernel/srcu.c index 2095be3318d5..ba35f3a4a1f4 100644 --- a/trunk/kernel/srcu.c +++ b/trunk/kernel/srcu.c @@ -34,77 +34,10 @@ #include #include -/* - * Initialize an rcu_batch structure to empty. - */ -static inline void rcu_batch_init(struct rcu_batch *b) -{ - b->head = NULL; - b->tail = &b->head; -} - -/* - * Enqueue a callback onto the tail of the specified rcu_batch structure. - */ -static inline void rcu_batch_queue(struct rcu_batch *b, struct rcu_head *head) -{ - *b->tail = head; - b->tail = &head->next; -} - -/* - * Is the specified rcu_batch structure empty? - */ -static inline bool rcu_batch_empty(struct rcu_batch *b) -{ - return b->tail == &b->head; -} - -/* - * Remove the callback at the head of the specified rcu_batch structure - * and return a pointer to it, or return NULL if the structure is empty. - */ -static inline struct rcu_head *rcu_batch_dequeue(struct rcu_batch *b) -{ - struct rcu_head *head; - - if (rcu_batch_empty(b)) - return NULL; - - head = b->head; - b->head = head->next; - if (b->tail == &head->next) - rcu_batch_init(b); - - return head; -} - -/* - * Move all callbacks from the rcu_batch structure specified by "from" to - * the structure specified by "to". - */ -static inline void rcu_batch_move(struct rcu_batch *to, struct rcu_batch *from) -{ - if (!rcu_batch_empty(from)) { - *to->tail = from->head; - to->tail = from->tail; - rcu_batch_init(from); - } -} - -/* single-thread state-machine */ -static void process_srcu(struct work_struct *work); - static int init_srcu_struct_fields(struct srcu_struct *sp) { sp->completed = 0; - spin_lock_init(&sp->queue_lock); - sp->running = false; - rcu_batch_init(&sp->batch_queue); - rcu_batch_init(&sp->batch_check0); - rcu_batch_init(&sp->batch_check1); - rcu_batch_init(&sp->batch_done); - INIT_DELAYED_WORK(&sp->work, process_srcu); + mutex_init(&sp->mutex); sp->per_cpu_ref = alloc_percpu(struct srcu_struct_array); return sp->per_cpu_ref ? 0 : -ENOMEM; } @@ -140,116 +73,21 @@ EXPORT_SYMBOL_GPL(init_srcu_struct); #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ /* - * Returns approximate total of the readers' ->seq[] values for the - * rank of per-CPU counters specified by idx. + * srcu_readers_active_idx -- returns approximate number of readers + * active on the specified rank of per-CPU counters. */ -static unsigned long srcu_readers_seq_idx(struct srcu_struct *sp, int idx) -{ - int cpu; - unsigned long sum = 0; - unsigned long t; - for_each_possible_cpu(cpu) { - t = ACCESS_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->seq[idx]); - sum += t; - } - return sum; -} - -/* - * Returns approximate number of readers active on the specified rank - * of the per-CPU ->c[] counters. - */ -static unsigned long srcu_readers_active_idx(struct srcu_struct *sp, int idx) +static int srcu_readers_active_idx(struct srcu_struct *sp, int idx) { int cpu; - unsigned long sum = 0; - unsigned long t; + int sum; - for_each_possible_cpu(cpu) { - t = ACCESS_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[idx]); - sum += t; - } + sum = 0; + for_each_possible_cpu(cpu) + sum += per_cpu_ptr(sp->per_cpu_ref, cpu)->c[idx]; return sum; } -/* - * Return true if the number of pre-existing readers is determined to - * be stably zero. An example unstable zero can occur if the call - * to srcu_readers_active_idx() misses an __srcu_read_lock() increment, - * but due to task migration, sees the corresponding __srcu_read_unlock() - * decrement. This can happen because srcu_readers_active_idx() takes - * time to sum the array, and might in fact be interrupted or preempted - * partway through the summation. - */ -static bool srcu_readers_active_idx_check(struct srcu_struct *sp, int idx) -{ - unsigned long seq; - - seq = srcu_readers_seq_idx(sp, idx); - - /* - * The following smp_mb() A pairs with the smp_mb() B located in - * __srcu_read_lock(). This pairing ensures that if an - * __srcu_read_lock() increments its counter after the summation - * in srcu_readers_active_idx(), then the corresponding SRCU read-side - * critical section will see any changes made prior to the start - * of the current SRCU grace period. - * - * Also, if the above call to srcu_readers_seq_idx() saw the - * increment of ->seq[], then the call to srcu_readers_active_idx() - * must see the increment of ->c[]. - */ - smp_mb(); /* A */ - - /* - * Note that srcu_readers_active_idx() can incorrectly return - * zero even though there is a pre-existing reader throughout. - * To see this, suppose that task A is in a very long SRCU - * read-side critical section that started on CPU 0, and that - * no other reader exists, so that the sum of the counters - * is equal to one. Then suppose that task B starts executing - * srcu_readers_active_idx(), summing up to CPU 1, and then that - * task C starts reading on CPU 0, so that its increment is not - * summed, but finishes reading on CPU 2, so that its decrement - * -is- summed. Then when task B completes its sum, it will - * incorrectly get zero, despite the fact that task A has been - * in its SRCU read-side critical section the whole time. - * - * We therefore do a validation step should srcu_readers_active_idx() - * return zero. - */ - if (srcu_readers_active_idx(sp, idx) != 0) - return false; - - /* - * The remainder of this function is the validation step. - * The following smp_mb() D pairs with the smp_mb() C in - * __srcu_read_unlock(). If the __srcu_read_unlock() was seen - * by srcu_readers_active_idx() above, then any destructive - * operation performed after the grace period will happen after - * the corresponding SRCU read-side critical section. - * - * Note that there can be at most NR_CPUS worth of readers using - * the old index, which is not enough to overflow even a 32-bit - * integer. (Yes, this does mean that systems having more than - * a billion or so CPUs need to be 64-bit systems.) Therefore, - * the sum of the ->seq[] counters cannot possibly overflow. - * Therefore, the only way that the return values of the two - * calls to srcu_readers_seq_idx() can be equal is if there were - * no increments of the corresponding rank of ->seq[] counts - * in the interim. But the missed-increment scenario laid out - * above includes an increment of the ->seq[] counter by - * the corresponding __srcu_read_lock(). Therefore, if this - * scenario occurs, the return values from the two calls to - * srcu_readers_seq_idx() will differ, and thus the validation - * step below suffices. - */ - smp_mb(); /* D */ - - return srcu_readers_seq_idx(sp, idx) == seq; -} - /** * srcu_readers_active - returns approximate number of readers. * @sp: which srcu_struct to count active readers (holding srcu_read_lock). @@ -260,14 +98,7 @@ static bool srcu_readers_active_idx_check(struct srcu_struct *sp, int idx) */ static int srcu_readers_active(struct srcu_struct *sp) { - int cpu; - unsigned long sum = 0; - - for_each_possible_cpu(cpu) { - sum += ACCESS_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[0]); - sum += ACCESS_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[1]); - } - return sum; + return srcu_readers_active_idx(sp, 0) + srcu_readers_active_idx(sp, 1); } /** @@ -300,11 +131,10 @@ int __srcu_read_lock(struct srcu_struct *sp) int idx; preempt_disable(); - idx = rcu_dereference_index_check(sp->completed, - rcu_read_lock_sched_held()) & 0x1; - ACCESS_ONCE(this_cpu_ptr(sp->per_cpu_ref)->c[idx]) += 1; - smp_mb(); /* B */ /* Avoid leaking the critical section. */ - ACCESS_ONCE(this_cpu_ptr(sp->per_cpu_ref)->seq[idx]) += 1; + idx = sp->completed & 0x1; + barrier(); /* ensure compiler looks -once- at sp->completed. */ + per_cpu_ptr(sp->per_cpu_ref, smp_processor_id())->c[idx]++; + srcu_barrier(); /* ensure compiler won't misorder critical section. */ preempt_enable(); return idx; } @@ -319,8 +149,8 @@ EXPORT_SYMBOL_GPL(__srcu_read_lock); void __srcu_read_unlock(struct srcu_struct *sp, int idx) { preempt_disable(); - smp_mb(); /* C */ /* Avoid leaking the critical section. */ - ACCESS_ONCE(this_cpu_ptr(sp->per_cpu_ref)->c[idx]) -= 1; + srcu_barrier(); /* ensure compiler won't misorder critical section. */ + per_cpu_ptr(sp->per_cpu_ref, smp_processor_id())->c[idx]--; preempt_enable(); } EXPORT_SYMBOL_GPL(__srcu_read_unlock); @@ -333,119 +163,106 @@ EXPORT_SYMBOL_GPL(__srcu_read_unlock); * we repeatedly block for 1-millisecond time periods. This approach * has done well in testing, so there is no need for a config parameter. */ -#define SRCU_RETRY_CHECK_DELAY 5 -#define SYNCHRONIZE_SRCU_TRYCOUNT 2 -#define SYNCHRONIZE_SRCU_EXP_TRYCOUNT 12 +#define SYNCHRONIZE_SRCU_READER_DELAY 10 /* - * @@@ Wait until all pre-existing readers complete. Such readers - * will have used the index specified by "idx". - * the caller should ensures the ->completed is not changed while checking - * and idx = (->completed & 1) ^ 1 + * Helper function for synchronize_srcu() and synchronize_srcu_expedited(). */ -static bool try_check_zero(struct srcu_struct *sp, int idx, int trycount) +static void __synchronize_srcu(struct srcu_struct *sp, void (*sync_func)(void)) { - for (;;) { - if (srcu_readers_active_idx_check(sp, idx)) - return true; - if (--trycount <= 0) - return false; - udelay(SRCU_RETRY_CHECK_DELAY); - } -} + int idx; -/* - * Increment the ->completed counter so that future SRCU readers will - * use the other rank of the ->c[] and ->seq[] arrays. This allows - * us to wait for pre-existing readers in a starvation-free manner. - */ -static void srcu_flip(struct srcu_struct *sp) -{ - sp->completed++; -} + rcu_lockdep_assert(!lock_is_held(&sp->dep_map) && + !lock_is_held(&rcu_bh_lock_map) && + !lock_is_held(&rcu_lock_map) && + !lock_is_held(&rcu_sched_lock_map), + "Illegal synchronize_srcu() in same-type SRCU (or RCU) read-side critical section"); -/* - * Enqueue an SRCU callback on the specified srcu_struct structure, - * initiating grace-period processing if it is not already running. - */ -void call_srcu(struct srcu_struct *sp, struct rcu_head *head, - void (*func)(struct rcu_head *head)) -{ - unsigned long flags; - - head->next = NULL; - head->func = func; - spin_lock_irqsave(&sp->queue_lock, flags); - rcu_batch_queue(&sp->batch_queue, head); - if (!sp->running) { - sp->running = true; - queue_delayed_work(system_nrt_wq, &sp->work, 0); + idx = sp->completed; + mutex_lock(&sp->mutex); + + /* + * Check to see if someone else did the work for us while we were + * waiting to acquire the lock. We need -two- advances of + * the counter, not just one. If there was but one, we might have + * shown up -after- our helper's first synchronize_sched(), thus + * having failed to prevent CPU-reordering races with concurrent + * srcu_read_unlock()s on other CPUs (see comment below). So we + * either (1) wait for two or (2) supply the second ourselves. + */ + + if ((sp->completed - idx) >= 2) { + mutex_unlock(&sp->mutex); + return; } - spin_unlock_irqrestore(&sp->queue_lock, flags); -} -EXPORT_SYMBOL_GPL(call_srcu); -struct rcu_synchronize { - struct rcu_head head; - struct completion completion; -}; + sync_func(); /* Force memory barrier on all CPUs. */ -/* - * Awaken the corresponding synchronize_srcu() instance now that a - * grace period has elapsed. - */ -static void wakeme_after_rcu(struct rcu_head *head) -{ - struct rcu_synchronize *rcu; + /* + * The preceding synchronize_sched() ensures that any CPU that + * sees the new value of sp->completed will also see any preceding + * changes to data structures made by this CPU. This prevents + * some other CPU from reordering the accesses in its SRCU + * read-side critical section to precede the corresponding + * srcu_read_lock() -- ensuring that such references will in + * fact be protected. + * + * So it is now safe to do the flip. + */ - rcu = container_of(head, struct rcu_synchronize, head); - complete(&rcu->completion); -} + idx = sp->completed & 0x1; + sp->completed++; -static void srcu_advance_batches(struct srcu_struct *sp, int trycount); -static void srcu_reschedule(struct srcu_struct *sp); + sync_func(); /* Force memory barrier on all CPUs. */ -/* - * Helper function for synchronize_srcu() and synchronize_srcu_expedited(). - */ -static void __synchronize_srcu(struct srcu_struct *sp, int trycount) -{ - struct rcu_synchronize rcu; - struct rcu_head *head = &rcu.head; - bool done = false; + /* + * At this point, because of the preceding synchronize_sched(), + * all srcu_read_lock() calls using the old counters have completed. + * Their corresponding critical sections might well be still + * executing, but the srcu_read_lock() primitives themselves + * will have finished executing. We initially give readers + * an arbitrarily chosen 10 microseconds to get out of their + * SRCU read-side critical sections, then loop waiting 1/HZ + * seconds per iteration. The 10-microsecond value has done + * very well in testing. + */ - rcu_lockdep_assert(!lock_is_held(&sp->dep_map) && - !lock_is_held(&rcu_bh_lock_map) && - !lock_is_held(&rcu_lock_map) && - !lock_is_held(&rcu_sched_lock_map), - "Illegal synchronize_srcu() in same-type SRCU (or RCU) read-side critical section"); + if (srcu_readers_active_idx(sp, idx)) + udelay(SYNCHRONIZE_SRCU_READER_DELAY); + while (srcu_readers_active_idx(sp, idx)) + schedule_timeout_interruptible(1); - init_completion(&rcu.completion); - - head->next = NULL; - head->func = wakeme_after_rcu; - spin_lock_irq(&sp->queue_lock); - if (!sp->running) { - /* steal the processing owner */ - sp->running = true; - rcu_batch_queue(&sp->batch_check0, head); - spin_unlock_irq(&sp->queue_lock); - - srcu_advance_batches(sp, trycount); - if (!rcu_batch_empty(&sp->batch_done)) { - BUG_ON(sp->batch_done.head != head); - rcu_batch_dequeue(&sp->batch_done); - done = true; - } - /* give the processing owner to work_struct */ - srcu_reschedule(sp); - } else { - rcu_batch_queue(&sp->batch_queue, head); - spin_unlock_irq(&sp->queue_lock); - } + sync_func(); /* Force memory barrier on all CPUs. */ - if (!done) - wait_for_completion(&rcu.completion); + /* + * The preceding synchronize_sched() forces all srcu_read_unlock() + * primitives that were executing concurrently with the preceding + * for_each_possible_cpu() loop to have completed by this point. + * More importantly, it also forces the corresponding SRCU read-side + * critical sections to have also completed, and the corresponding + * references to SRCU-protected data items to be dropped. + * + * Note: + * + * Despite what you might think at first glance, the + * preceding synchronize_sched() -must- be within the + * critical section ended by the following mutex_unlock(). + * Otherwise, a task taking the early exit can race + * with a srcu_read_unlock(), which might have executed + * just before the preceding srcu_readers_active() check, + * and whose CPU might have reordered the srcu_read_unlock() + * with the preceding critical section. In this case, there + * is nothing preventing the synchronize_sched() task that is + * taking the early exit from freeing a data structure that + * is still being referenced (out of order) by the task + * doing the srcu_read_unlock(). + * + * Alternatively, the comparison with "2" on the early exit + * could be changed to "3", but this increases synchronize_srcu() + * latency for bulk loads. So the current code is preferred. + */ + + mutex_unlock(&sp->mutex); } /** @@ -464,7 +281,7 @@ static void __synchronize_srcu(struct srcu_struct *sp, int trycount) */ void synchronize_srcu(struct srcu_struct *sp) { - __synchronize_srcu(sp, SYNCHRONIZE_SRCU_TRYCOUNT); + __synchronize_srcu(sp, synchronize_sched); } EXPORT_SYMBOL_GPL(synchronize_srcu); @@ -472,11 +289,18 @@ EXPORT_SYMBOL_GPL(synchronize_srcu); * synchronize_srcu_expedited - Brute-force SRCU grace period * @sp: srcu_struct with which to synchronize. * - * Wait for an SRCU grace period to elapse, but be more aggressive about - * spinning rather than blocking when waiting. + * Wait for an SRCU grace period to elapse, but use a "big hammer" + * approach to force the grace period to end quickly. This consumes + * significant time on all CPUs and is unfriendly to real-time workloads, + * so is thus not recommended for any sort of common-case code. In fact, + * if you are using synchronize_srcu_expedited() in a loop, please + * restructure your code to batch your updates, and then use a single + * synchronize_srcu() instead. * * Note that it is illegal to call this function while holding any lock - * that is acquired by a CPU-hotplug notifier. It is also illegal to call + * that is acquired by a CPU-hotplug notifier. And yes, it is also illegal + * to call this function from a CPU-hotplug notifier. Failing to observe + * these restriction will result in deadlock. It is also illegal to call * synchronize_srcu_expedited() from the corresponding SRCU read-side * critical section; doing so will result in deadlock. However, it is * perfectly legal to call synchronize_srcu_expedited() on one srcu_struct @@ -485,19 +309,10 @@ EXPORT_SYMBOL_GPL(synchronize_srcu); */ void synchronize_srcu_expedited(struct srcu_struct *sp) { - __synchronize_srcu(sp, SYNCHRONIZE_SRCU_EXP_TRYCOUNT); + __synchronize_srcu(sp, synchronize_sched_expedited); } EXPORT_SYMBOL_GPL(synchronize_srcu_expedited); -/** - * srcu_barrier - Wait until all in-flight call_srcu() callbacks complete. - */ -void srcu_barrier(struct srcu_struct *sp) -{ - synchronize_srcu(sp); -} -EXPORT_SYMBOL_GPL(srcu_barrier); - /** * srcu_batches_completed - return batches completed. * @sp: srcu_struct on which to report batch completion. @@ -505,146 +320,9 @@ EXPORT_SYMBOL_GPL(srcu_barrier); * Report the number of batches, correlated with, but not necessarily * precisely the same as, the number of grace periods that have elapsed. */ + long srcu_batches_completed(struct srcu_struct *sp) { return sp->completed; } EXPORT_SYMBOL_GPL(srcu_batches_completed); - -#define SRCU_CALLBACK_BATCH 10 -#define SRCU_INTERVAL 1 - -/* - * Move any new SRCU callbacks to the first stage of the SRCU grace - * period pipeline. - */ -static void srcu_collect_new(struct srcu_struct *sp) -{ - if (!rcu_batch_empty(&sp->batch_queue)) { - spin_lock_irq(&sp->queue_lock); - rcu_batch_move(&sp->batch_check0, &sp->batch_queue); - spin_unlock_irq(&sp->queue_lock); - } -} - -/* - * Core SRCU state machine. Advance callbacks from ->batch_check0 to - * ->batch_check1 and then to ->batch_done as readers drain. - */ -static void srcu_advance_batches(struct srcu_struct *sp, int trycount) -{ - int idx = 1 ^ (sp->completed & 1); - - /* - * Because readers might be delayed for an extended period after - * fetching ->completed for their index, at any point in time there - * might well be readers using both idx=0 and idx=1. We therefore - * need to wait for readers to clear from both index values before - * invoking a callback. - */ - - if (rcu_batch_empty(&sp->batch_check0) && - rcu_batch_empty(&sp->batch_check1)) - return; /* no callbacks need to be advanced */ - - if (!try_check_zero(sp, idx, trycount)) - return; /* failed to advance, will try after SRCU_INTERVAL */ - - /* - * The callbacks in ->batch_check1 have already done with their - * first zero check and flip back when they were enqueued on - * ->batch_check0 in a previous invocation of srcu_advance_batches(). - * (Presumably try_check_zero() returned false during that - * invocation, leaving the callbacks stranded on ->batch_check1.) - * They are therefore ready to invoke, so move them to ->batch_done. - */ - rcu_batch_move(&sp->batch_done, &sp->batch_check1); - - if (rcu_batch_empty(&sp->batch_check0)) - return; /* no callbacks need to be advanced */ - srcu_flip(sp); - - /* - * The callbacks in ->batch_check0 just finished their - * first check zero and flip, so move them to ->batch_check1 - * for future checking on the other idx. - */ - rcu_batch_move(&sp->batch_check1, &sp->batch_check0); - - /* - * SRCU read-side critical sections are normally short, so check - * at least twice in quick succession after a flip. - */ - trycount = trycount < 2 ? 2 : trycount; - if (!try_check_zero(sp, idx^1, trycount)) - return; /* failed to advance, will try after SRCU_INTERVAL */ - - /* - * The callbacks in ->batch_check1 have now waited for all - * pre-existing readers using both idx values. They are therefore - * ready to invoke, so move them to ->batch_done. - */ - rcu_batch_move(&sp->batch_done, &sp->batch_check1); -} - -/* - * Invoke a limited number of SRCU callbacks that have passed through - * their grace period. If there are more to do, SRCU will reschedule - * the workqueue. - */ -static void srcu_invoke_callbacks(struct srcu_struct *sp) -{ - int i; - struct rcu_head *head; - - for (i = 0; i < SRCU_CALLBACK_BATCH; i++) { - head = rcu_batch_dequeue(&sp->batch_done); - if (!head) - break; - local_bh_disable(); - head->func(head); - local_bh_enable(); - } -} - -/* - * Finished one round of SRCU grace period. Start another if there are - * more SRCU callbacks queued, otherwise put SRCU into not-running state. - */ -static void srcu_reschedule(struct srcu_struct *sp) -{ - bool pending = true; - - if (rcu_batch_empty(&sp->batch_done) && - rcu_batch_empty(&sp->batch_check1) && - rcu_batch_empty(&sp->batch_check0) && - rcu_batch_empty(&sp->batch_queue)) { - spin_lock_irq(&sp->queue_lock); - if (rcu_batch_empty(&sp->batch_done) && - rcu_batch_empty(&sp->batch_check1) && - rcu_batch_empty(&sp->batch_check0) && - rcu_batch_empty(&sp->batch_queue)) { - sp->running = false; - pending = false; - } - spin_unlock_irq(&sp->queue_lock); - } - - if (pending) - queue_delayed_work(system_nrt_wq, &sp->work, SRCU_INTERVAL); -} - -/* - * This is the work-queue function that handles SRCU grace periods. - */ -static void process_srcu(struct work_struct *work) -{ - struct srcu_struct *sp; - - sp = container_of(work, struct srcu_struct, work.work); - - srcu_collect_new(sp); - srcu_advance_batches(sp, 1); - srcu_invoke_callbacks(sp); - srcu_reschedule(sp); -} diff --git a/trunk/kernel/sys.c b/trunk/kernel/sys.c index ba0ae8eea6fb..e7006eb6c1e4 100644 --- a/trunk/kernel/sys.c +++ b/trunk/kernel/sys.c @@ -1908,7 +1908,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, error = prctl_get_seccomp(); break; case PR_SET_SECCOMP: - error = prctl_set_seccomp(arg2, (char __user *)arg3); + error = prctl_set_seccomp(arg2); break; case PR_GET_TSC: error = GET_TSC_CTL(arg2); @@ -1979,16 +1979,6 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, error = put_user(me->signal->is_child_subreaper, (int __user *) arg2); break; - case PR_SET_NO_NEW_PRIVS: - if (arg2 != 1 || arg3 || arg4 || arg5) - return -EINVAL; - - current->no_new_privs = 1; - break; - case PR_GET_NO_NEW_PRIVS: - if (arg2 || arg3 || arg4 || arg5) - return -EINVAL; - return current->no_new_privs ? 1 : 0; default: error = -EINVAL; break; diff --git a/trunk/kernel/timer.c b/trunk/kernel/timer.c index 837c552fe838..a297ffcf888e 100644 --- a/trunk/kernel/timer.c +++ b/trunk/kernel/timer.c @@ -861,13 +861,7 @@ EXPORT_SYMBOL(mod_timer); * * mod_timer_pinned() is a way to update the expire field of an * active timer (if the timer is inactive it will be activated) - * and to ensure that the timer is scheduled on the current CPU. - * - * Note that this does not prevent the timer from being migrated - * when the current CPU goes offline. If this is a problem for - * you, use CPU-hotplug notifiers to handle it correctly, for - * example, cancelling the timer when the corresponding CPU goes - * offline. + * and not allow the timer to be migrated to a different CPU. * * mod_timer_pinned(timer, expires) is equivalent to: * diff --git a/trunk/kernel/trace/trace_events.c b/trunk/kernel/trace/trace_events.c index 29111da1d100..079a93ae8a9d 100644 --- a/trunk/kernel/trace/trace_events.c +++ b/trunk/kernel/trace/trace_events.c @@ -294,9 +294,6 @@ static int __ftrace_set_clr_event(const char *match, const char *sub, if (!call->name || !call->class || !call->class->reg) continue; - if (call->flags & TRACE_EVENT_FL_IGNORE_ENABLE) - continue; - if (match && strcmp(match, call->name) != 0 && strcmp(match, call->class->system) != 0) @@ -1167,7 +1164,7 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events, return -1; } - if (call->class->reg && !(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE)) + if (call->class->reg) trace_create_file("enable", 0644, call->dir, call, enable); diff --git a/trunk/kernel/trace/trace_export.c b/trunk/kernel/trace/trace_export.c index e039906b037d..3dd15e8bc856 100644 --- a/trunk/kernel/trace/trace_export.c +++ b/trunk/kernel/trace/trace_export.c @@ -180,7 +180,6 @@ struct ftrace_event_call __used event_##call = { \ .event.type = etype, \ .class = &event_class_ftrace_##call, \ .print_fmt = print, \ - .flags = TRACE_EVENT_FL_IGNORE_ENABLE, \ }; \ struct ftrace_event_call __used \ __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call; diff --git a/trunk/lib/debugobjects.c b/trunk/lib/debugobjects.c index d11808ca4bc4..0ab9ae8057f0 100644 --- a/trunk/lib/debugobjects.c +++ b/trunk/lib/debugobjects.c @@ -79,29 +79,30 @@ static const char *obj_states[ODEBUG_STATE_MAX] = { [ODEBUG_STATE_NOTAVAILABLE] = "not available", }; -static void fill_pool(void) +static int fill_pool(void) { gfp_t gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN; struct debug_obj *new; unsigned long flags; if (likely(obj_pool_free >= ODEBUG_POOL_MIN_LEVEL)) - return; + return obj_pool_free; if (unlikely(!obj_cache)) - return; + return obj_pool_free; while (obj_pool_free < ODEBUG_POOL_MIN_LEVEL) { new = kmem_cache_zalloc(obj_cache, gfp); if (!new) - return; + return obj_pool_free; raw_spin_lock_irqsave(&pool_lock, flags); hlist_add_head(&new->node, &obj_pool); obj_pool_free++; raw_spin_unlock_irqrestore(&pool_lock, flags); } + return obj_pool_free; } /* @@ -1051,10 +1052,10 @@ static int __init debug_objects_replace_static_objects(void) cnt++; } } - local_irq_enable(); printk(KERN_DEBUG "ODEBUG: %d of %d active objects replaced\n", cnt, obj_pool_used); + local_irq_enable(); return 0; free: hlist_for_each_entry_safe(obj, node, tmp, &objects, node) { diff --git a/trunk/lib/list_debug.c b/trunk/lib/list_debug.c index 3810b481f940..982b850d4e7a 100644 --- a/trunk/lib/list_debug.c +++ b/trunk/lib/list_debug.c @@ -10,7 +10,6 @@ #include #include #include -#include /* * Insert a new entry between two known consecutive entries. @@ -76,24 +75,3 @@ void list_del(struct list_head *entry) entry->prev = LIST_POISON2; } EXPORT_SYMBOL(list_del); - -/* - * RCU variants. - */ -void __list_add_rcu(struct list_head *new, - struct list_head *prev, struct list_head *next) -{ - WARN(next->prev != prev, - "list_add_rcu corruption. next->prev should be " - "prev (%p), but was %p. (next=%p).\n", - prev, next->prev, next); - WARN(prev->next != next, - "list_add_rcu corruption. prev->next should be " - "next (%p), but was %p. (prev=%p).\n", - next, prev->next, prev); - new->next = next; - new->prev = prev; - rcu_assign_pointer(list_next_rcu(prev), new); - next->prev = new; -} -EXPORT_SYMBOL(__list_add_rcu); diff --git a/trunk/mm/hugetlb.c b/trunk/mm/hugetlb.c index ae8f708e3d75..5a16423a512c 100644 --- a/trunk/mm/hugetlb.c +++ b/trunk/mm/hugetlb.c @@ -2498,6 +2498,7 @@ static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma, if (outside_reserve) { BUG_ON(huge_pte_none(pte)); if (unmap_ref_private(mm, vma, old_page, address)) { + BUG_ON(page_count(old_page) != 1); BUG_ON(huge_pte_none(pte)); spin_lock(&mm->page_table_lock); ptep = huge_pte_offset(mm, address & huge_page_mask(h)); diff --git a/trunk/mm/memcontrol.c b/trunk/mm/memcontrol.c index 7685d4a0b3ce..31ab9c3f0178 100644 --- a/trunk/mm/memcontrol.c +++ b/trunk/mm/memcontrol.c @@ -4507,12 +4507,6 @@ static void mem_cgroup_usage_unregister_event(struct cgroup *cgrp, swap_buffers: /* Swap primary and spare array */ thresholds->spare = thresholds->primary; - /* If all events are unregistered, free the spare array */ - if (!new) { - kfree(thresholds->spare); - thresholds->spare = NULL; - } - rcu_assign_pointer(thresholds->primary, new); /* To be sure that nobody uses thresholds */ @@ -5481,7 +5475,7 @@ static int mem_cgroup_move_charge_pte_range(pmd_t *pmd, * part of thp split is not executed yet. */ if (pmd_trans_huge_lock(pmd, vma) == 1) { - if (mc.precharge < HPAGE_PMD_NR) { + if (!mc.precharge) { spin_unlock(&vma->vm_mm->page_table_lock); return 0; } diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index 1e77da6d82c1..6105f475fa86 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -1295,7 +1295,7 @@ static void unmap_page_range(struct mmu_gather *tlb, static void unmap_single_vma(struct mmu_gather *tlb, struct vm_area_struct *vma, unsigned long start_addr, - unsigned long end_addr, + unsigned long end_addr, unsigned long *nr_accounted, struct zap_details *details) { unsigned long start = max(vma->vm_start, start_addr); @@ -1307,6 +1307,9 @@ static void unmap_single_vma(struct mmu_gather *tlb, if (end <= vma->vm_start) return; + if (vma->vm_flags & VM_ACCOUNT) + *nr_accounted += (end - start) >> PAGE_SHIFT; + if (unlikely(is_pfn_mapping(vma))) untrack_pfn_vma(vma, 0, 0); @@ -1336,6 +1339,8 @@ static void unmap_single_vma(struct mmu_gather *tlb, * @vma: the starting vma * @start_addr: virtual address at which to start unmapping * @end_addr: virtual address at which to end unmapping + * @nr_accounted: Place number of unmapped pages in vm-accountable vma's here + * @details: details of nonlinear truncation or shared cache invalidation * * Unmap all pages in the vma list. * @@ -1350,13 +1355,15 @@ static void unmap_single_vma(struct mmu_gather *tlb, */ void unmap_vmas(struct mmu_gather *tlb, struct vm_area_struct *vma, unsigned long start_addr, - unsigned long end_addr) + unsigned long end_addr, unsigned long *nr_accounted, + struct zap_details *details) { struct mm_struct *mm = vma->vm_mm; mmu_notifier_invalidate_range_start(mm, start_addr, end_addr); for ( ; vma && vma->vm_start < end_addr; vma = vma->vm_next) - unmap_single_vma(tlb, vma, start_addr, end_addr, NULL); + unmap_single_vma(tlb, vma, start_addr, end_addr, nr_accounted, + details); mmu_notifier_invalidate_range_end(mm, start_addr, end_addr); } @@ -1369,21 +1376,19 @@ void unmap_vmas(struct mmu_gather *tlb, * * Caller must protect the VMA list */ -void zap_page_range(struct vm_area_struct *vma, unsigned long start, +void zap_page_range(struct vm_area_struct *vma, unsigned long address, unsigned long size, struct zap_details *details) { struct mm_struct *mm = vma->vm_mm; struct mmu_gather tlb; - unsigned long end = start + size; + unsigned long end = address + size; + unsigned long nr_accounted = 0; lru_add_drain(); tlb_gather_mmu(&tlb, mm, 0); update_hiwater_rss(mm); - mmu_notifier_invalidate_range_start(mm, start, end); - for ( ; vma && vma->vm_start < end; vma = vma->vm_next) - unmap_single_vma(&tlb, vma, start, end, details); - mmu_notifier_invalidate_range_end(mm, start, end); - tlb_finish_mmu(&tlb, start, end); + unmap_vmas(&tlb, vma, address, end, &nr_accounted, details); + tlb_finish_mmu(&tlb, address, end); } /** @@ -1401,12 +1406,13 @@ static void zap_page_range_single(struct vm_area_struct *vma, unsigned long addr struct mm_struct *mm = vma->vm_mm; struct mmu_gather tlb; unsigned long end = address + size; + unsigned long nr_accounted = 0; lru_add_drain(); tlb_gather_mmu(&tlb, mm, 0); update_hiwater_rss(mm); mmu_notifier_invalidate_range_start(mm, address, end); - unmap_single_vma(&tlb, vma, address, end, details); + unmap_single_vma(&tlb, vma, address, end, &nr_accounted, details); mmu_notifier_invalidate_range_end(mm, address, end); tlb_finish_mmu(&tlb, address, end); } diff --git a/trunk/mm/mmap.c b/trunk/mm/mmap.c index 69a1889f3790..848ef52d9603 100644 --- a/trunk/mm/mmap.c +++ b/trunk/mm/mmap.c @@ -1889,20 +1889,15 @@ find_extend_vma(struct mm_struct * mm, unsigned long addr) */ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma) { - unsigned long nr_accounted = 0; - /* Update high watermark before we lower total_vm */ update_hiwater_vm(mm); do { long nrpages = vma_pages(vma); - if (vma->vm_flags & VM_ACCOUNT) - nr_accounted += nrpages; mm->total_vm -= nrpages; vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages); vma = remove_vma(vma); } while (vma); - vm_unacct_memory(nr_accounted); validate_mm(mm); } @@ -1917,11 +1912,13 @@ static void unmap_region(struct mm_struct *mm, { struct vm_area_struct *next = prev? prev->vm_next: mm->mmap; struct mmu_gather tlb; + unsigned long nr_accounted = 0; lru_add_drain(); tlb_gather_mmu(&tlb, mm, 0); update_hiwater_rss(mm); - unmap_vmas(&tlb, vma, start, end); + unmap_vmas(&tlb, vma, start, end, &nr_accounted, NULL); + vm_unacct_memory(nr_accounted); free_pgtables(&tlb, vma, prev ? prev->vm_end : FIRST_USER_ADDRESS, next ? next->vm_start : 0); tlb_finish_mmu(&tlb, start, end); @@ -2308,7 +2305,8 @@ void exit_mmap(struct mm_struct *mm) tlb_gather_mmu(&tlb, mm, 1); /* update_hiwater_rss(mm) here? but nobody should be looking */ /* Use -1 here to ensure all VMAs in the mm are unmapped */ - unmap_vmas(&tlb, vma, 0, -1); + unmap_vmas(&tlb, vma, 0, -1, &nr_accounted, NULL); + vm_unacct_memory(nr_accounted); free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, 0); tlb_finish_mmu(&tlb, 0, -1); @@ -2317,12 +2315,8 @@ void exit_mmap(struct mm_struct *mm) * Walk the list again, actually closing and freeing it, * with preemption enabled, without holding any MM locks. */ - while (vma) { - if (vma->vm_flags & VM_ACCOUNT) - nr_accounted += vma_pages(vma); + while (vma) vma = remove_vma(vma); - } - vm_unacct_memory(nr_accounted); BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT); } diff --git a/trunk/mm/nobootmem.c b/trunk/mm/nobootmem.c index 1983fb1c7026..e53bb8a256b1 100644 --- a/trunk/mm/nobootmem.c +++ b/trunk/mm/nobootmem.c @@ -82,7 +82,8 @@ void __init free_bootmem_late(unsigned long addr, unsigned long size) static void __init __free_pages_memory(unsigned long start, unsigned long end) { - unsigned long i, start_aligned, end_aligned; + int i; + unsigned long start_aligned, end_aligned; int order = ilog2(BITS_PER_LONG); start_aligned = (start + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1); diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index 918330f71dba..a712fb9e04ce 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -5203,7 +5203,7 @@ int percpu_pagelist_fraction_sysctl_handler(ctl_table *table, int write, int ret; ret = proc_dointvec_minmax(table, write, buffer, length, ppos); - if (!write || (ret < 0)) + if (!write || (ret == -EINVAL)) return ret; for_each_populated_zone(zone) { for_each_possible_cpu(cpu) { diff --git a/trunk/mm/percpu.c b/trunk/mm/percpu.c index bb4be7435ce3..f47af9123af7 100644 --- a/trunk/mm/percpu.c +++ b/trunk/mm/percpu.c @@ -1132,20 +1132,20 @@ static void pcpu_dump_alloc_info(const char *lvl, for (alloc_end += gi->nr_units / upa; alloc < alloc_end; alloc++) { if (!(alloc % apl)) { - printk(KERN_CONT "\n"); + printk("\n"); printk("%spcpu-alloc: ", lvl); } - printk(KERN_CONT "[%0*d] ", group_width, group); + printk("[%0*d] ", group_width, group); for (unit_end += upa; unit < unit_end; unit++) if (gi->cpu_map[unit] != NR_CPUS) - printk(KERN_CONT "%0*d ", cpu_width, + printk("%0*d ", cpu_width, gi->cpu_map[unit]); else - printk(KERN_CONT "%s ", empty_str); + printk("%s ", empty_str); } } - printk(KERN_CONT "\n"); + printk("\n"); } /** @@ -1650,16 +1650,6 @@ int __init pcpu_embed_first_chunk(size_t reserved_size, size_t dyn_size, areas[group] = ptr; base = min(ptr, base); - } - - /* - * Copy data and free unused parts. This should happen after all - * allocations are complete; otherwise, we may end up with - * overlapping groups. - */ - for (group = 0; group < ai->nr_groups; group++) { - struct pcpu_group_info *gi = &ai->groups[group]; - void *ptr = areas[group]; for (i = 0; i < gi->nr_units; i++, ptr += ai->unit_size) { if (gi->cpu_map[i] == NR_CPUS) { @@ -1895,8 +1885,6 @@ void __init setup_per_cpu_areas(void) fc = __alloc_bootmem(unit_size, PAGE_SIZE, __pa(MAX_DMA_ADDRESS)); if (!ai || !fc) panic("Failed to allocate memory for percpu areas."); - /* kmemleak tracks the percpu allocations separately */ - kmemleak_free(fc); ai->dyn_size = unit_size; ai->unit_size = unit_size; diff --git a/trunk/mm/slub.c b/trunk/mm/slub.c index 80848cd3901c..ffe13fdf8144 100644 --- a/trunk/mm/slub.c +++ b/trunk/mm/slub.c @@ -2040,7 +2040,7 @@ static bool has_cpu_slab(int cpu, void *info) struct kmem_cache *s = info; struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu); - return c->page || c->partial; + return !!(c->page); } static void flush_all(struct kmem_cache *s) diff --git a/trunk/net/802/Makefile b/trunk/net/802/Makefile index a30d6e385aed..7893d679910c 100644 --- a/trunk/net/802/Makefile +++ b/trunk/net/802/Makefile @@ -4,6 +4,7 @@ # Check the p8022 selections against net/core/Makefile. obj-$(CONFIG_LLC) += p8022.o psnap.o +obj-$(CONFIG_TR) += p8022.o psnap.o tr.o obj-$(CONFIG_NET_FC) += fc.o obj-$(CONFIG_FDDI) += fddi.o obj-$(CONFIG_HIPPI) += hippi.o diff --git a/trunk/net/802/p8022.c b/trunk/net/802/p8022.c index 0bda8de7df51..7f353c4f437a 100644 --- a/trunk/net/802/p8022.c +++ b/trunk/net/802/p8022.c @@ -1,5 +1,6 @@ /* - * NET3: Support for 802.2 demultiplexing off Ethernet + * NET3: Support for 802.2 demultiplexing off Ethernet (Token ring + * is kept separate see p8022tr.c) * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version diff --git a/trunk/net/802/stp.c b/trunk/net/802/stp.c index 2c40ba0ec116..15540b7323cd 100644 --- a/trunk/net/802/stp.c +++ b/trunk/net/802/stp.c @@ -46,7 +46,7 @@ static int stp_pdu_rcv(struct sk_buff *skb, struct net_device *dev, proto = rcu_dereference(garp_protos[eh->h_dest[5] - GARP_ADDR_MIN]); if (proto && - !ether_addr_equal(eh->h_dest, proto->group_address)) + compare_ether_addr(eh->h_dest, proto->group_address)) goto err; } else proto = rcu_dereference(stp_proto); diff --git a/trunk/net/802/tr.c b/trunk/net/802/tr.c new file mode 100644 index 000000000000..30a352ed09b1 --- /dev/null +++ b/trunk/net/802/tr.c @@ -0,0 +1,670 @@ +/* + * NET3: Token ring device handling subroutines + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Fixes: 3 Feb 97 Paul Norton Minor routing fixes. + * Added rif table to /proc/net/tr_rif and rif timeout to + * /proc/sys/net/token-ring/rif_timeout. + * 22 Jun 98 Paul Norton Rearranged + * tr_header and tr_type_trans to handle passing IPX SNAP and + * 802.2 through the correct layers. Eliminated tr_reformat. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev); +static void rif_check_expire(unsigned long dummy); + +#define TR_SR_DEBUG 0 + +/* + * Each RIF entry we learn is kept this way + */ + +struct rif_cache { + unsigned char addr[TR_ALEN]; + int iface; + __be16 rcf; + __be16 rseg[8]; + struct rif_cache *next; + unsigned long last_used; + unsigned char local_ring; +}; + +#define RIF_TABLE_SIZE 32 + +/* + * We hash the RIF cache 32 ways. We do after all have to look it + * up a lot. + */ + +static struct rif_cache *rif_table[RIF_TABLE_SIZE]; + +static DEFINE_SPINLOCK(rif_lock); + + +/* + * Garbage disposal timer. + */ + +static struct timer_list rif_timer; + +static int sysctl_tr_rif_timeout = 60*10*HZ; + +static inline unsigned long rif_hash(const unsigned char *addr) +{ + unsigned long x; + + x = addr[0]; + x = (x << 2) ^ addr[1]; + x = (x << 2) ^ addr[2]; + x = (x << 2) ^ addr[3]; + x = (x << 2) ^ addr[4]; + x = (x << 2) ^ addr[5]; + + x ^= x >> 8; + + return x & (RIF_TABLE_SIZE - 1); +} + +/* + * Put the headers on a token ring packet. Token ring source routing + * makes this a little more exciting than on ethernet. + */ + +static int tr_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, + const void *daddr, const void *saddr, unsigned int len) +{ + struct trh_hdr *trh; + int hdr_len; + + /* + * Add the 802.2 SNAP header if IP as the IPv4/IPv6 code calls + * dev->hard_header directly. + */ + if (type == ETH_P_IP || type == ETH_P_IPV6 || type == ETH_P_ARP) + { + struct trllc *trllc; + + hdr_len = sizeof(struct trh_hdr) + sizeof(struct trllc); + trh = (struct trh_hdr *)skb_push(skb, hdr_len); + trllc = (struct trllc *)(trh+1); + trllc->dsap = trllc->ssap = EXTENDED_SAP; + trllc->llc = UI_CMD; + trllc->protid[0] = trllc->protid[1] = trllc->protid[2] = 0x00; + trllc->ethertype = htons(type); + } + else + { + hdr_len = sizeof(struct trh_hdr); + trh = (struct trh_hdr *)skb_push(skb, hdr_len); + } + + trh->ac=AC; + trh->fc=LLC_FRAME; + + if(saddr) + memcpy(trh->saddr,saddr,dev->addr_len); + else + memcpy(trh->saddr,dev->dev_addr,dev->addr_len); + + /* + * Build the destination and then source route the frame + */ + + if(daddr) + { + memcpy(trh->daddr,daddr,dev->addr_len); + tr_source_route(skb, trh, dev); + return hdr_len; + } + + return -hdr_len; +} + +/* + * A neighbour discovery of some species (eg arp) has completed. We + * can now send the packet. + */ + +static int tr_rebuild_header(struct sk_buff *skb) +{ + struct trh_hdr *trh=(struct trh_hdr *)skb->data; + struct trllc *trllc=(struct trllc *)(skb->data+sizeof(struct trh_hdr)); + struct net_device *dev = skb->dev; + + /* + * FIXME: We don't yet support IPv6 over token rings + */ + + if(trllc->ethertype != htons(ETH_P_IP)) { + printk("tr_rebuild_header: Don't know how to resolve type %04X addresses ?\n", ntohs(trllc->ethertype)); + return 0; + } + +#ifdef CONFIG_INET + if(arp_find(trh->daddr, skb)) { + return 1; + } + else +#endif + { + tr_source_route(skb,trh,dev); + return 0; + } +} + +/* + * Some of this is a bit hackish. We intercept RIF information + * used for source routing. We also grab IP directly and don't feed + * it via SNAP. + */ + +__be16 tr_type_trans(struct sk_buff *skb, struct net_device *dev) +{ + + struct trh_hdr *trh; + struct trllc *trllc; + unsigned int riflen=0; + + skb->dev = dev; + skb_reset_mac_header(skb); + trh = tr_hdr(skb); + + if(trh->saddr[0] & TR_RII) + riflen = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8; + + trllc = (struct trllc *)(skb->data+sizeof(struct trh_hdr)-TR_MAXRIFLEN+riflen); + + skb_pull(skb,sizeof(struct trh_hdr)-TR_MAXRIFLEN+riflen); + + if(*trh->daddr & 0x80) + { + if(!memcmp(trh->daddr,dev->broadcast,TR_ALEN)) + skb->pkt_type=PACKET_BROADCAST; + else + skb->pkt_type=PACKET_MULTICAST; + } + else if ( (trh->daddr[0] & 0x01) && (trh->daddr[1] & 0x00) && (trh->daddr[2] & 0x5E)) + { + skb->pkt_type=PACKET_MULTICAST; + } + else if(dev->flags & IFF_PROMISC) + { + if(memcmp(trh->daddr, dev->dev_addr, TR_ALEN)) + skb->pkt_type=PACKET_OTHERHOST; + } + + if ((skb->pkt_type != PACKET_BROADCAST) && + (skb->pkt_type != PACKET_MULTICAST)) + tr_add_rif_info(trh,dev) ; + + /* + * Strip the SNAP header from ARP packets since we don't + * pass them through to the 802.2/SNAP layers. + */ + + if (trllc->dsap == EXTENDED_SAP && + (trllc->ethertype == htons(ETH_P_IP) || + trllc->ethertype == htons(ETH_P_IPV6) || + trllc->ethertype == htons(ETH_P_ARP))) + { + skb_pull(skb, sizeof(struct trllc)); + return trllc->ethertype; + } + + return htons(ETH_P_TR_802_2); +} + +/* + * We try to do source routing... + */ + +void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh, + struct net_device *dev) +{ + int slack; + unsigned int hash; + struct rif_cache *entry; + unsigned char *olddata; + unsigned long flags; + static const unsigned char mcast_func_addr[] + = {0xC0,0x00,0x00,0x04,0x00,0x00}; + + spin_lock_irqsave(&rif_lock, flags); + + /* + * Broadcasts are single route as stated in RFC 1042 + */ + if( (!memcmp(&(trh->daddr[0]),&(dev->broadcast[0]),TR_ALEN)) || + (!memcmp(&(trh->daddr[0]),&(mcast_func_addr[0]), TR_ALEN)) ) + { + trh->rcf=htons((((sizeof(trh->rcf)) << 8) & TR_RCF_LEN_MASK) + | TR_RCF_FRAME2K | TR_RCF_LIMITED_BROADCAST); + trh->saddr[0]|=TR_RII; + } + else + { + hash = rif_hash(trh->daddr); + /* + * Walk the hash table and look for an entry + */ + for(entry=rif_table[hash];entry && memcmp(&(entry->addr[0]),&(trh->daddr[0]),TR_ALEN);entry=entry->next); + + /* + * If we found an entry we can route the frame. + */ + if(entry) + { +#if TR_SR_DEBUG +printk("source routing for %pM\n", trh->daddr); +#endif + if(!entry->local_ring && (ntohs(entry->rcf) & TR_RCF_LEN_MASK) >> 8) + { + trh->rcf=entry->rcf; + memcpy(&trh->rseg[0],&entry->rseg[0],8*sizeof(unsigned short)); + trh->rcf^=htons(TR_RCF_DIR_BIT); + trh->rcf&=htons(0x1fff); /* Issam Chehab */ + + trh->saddr[0]|=TR_RII; +#if TR_SR_DEBUG + printk("entry found with rcf %04x\n", entry->rcf); + } + else + { + printk("entry found but without rcf length, local=%02x\n", entry->local_ring); +#endif + } + entry->last_used=jiffies; + } + else + { + /* + * Without the information we simply have to shout + * on the wire. The replies should rapidly clean this + * situation up. + */ + trh->rcf=htons((((sizeof(trh->rcf)) << 8) & TR_RCF_LEN_MASK) + | TR_RCF_FRAME2K | TR_RCF_LIMITED_BROADCAST); + trh->saddr[0]|=TR_RII; +#if TR_SR_DEBUG + printk("no entry in rif table found - broadcasting frame\n"); +#endif + } + } + + /* Compress the RIF here so we don't have to do it in the driver(s) */ + if (!(trh->saddr[0] & 0x80)) + slack = 18; + else + slack = 18 - ((ntohs(trh->rcf) & TR_RCF_LEN_MASK)>>8); + olddata = skb->data; + spin_unlock_irqrestore(&rif_lock, flags); + + skb_pull(skb, slack); + memmove(skb->data, olddata, sizeof(struct trh_hdr) - slack); +} + +/* + * We have learned some new RIF information for our source + * routing. + */ + +static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev) +{ + unsigned int hash, rii_p = 0; + unsigned long flags; + struct rif_cache *entry; + unsigned char saddr0; + + spin_lock_irqsave(&rif_lock, flags); + saddr0 = trh->saddr[0]; + + /* + * Firstly see if the entry exists + */ + + if(trh->saddr[0] & TR_RII) + { + trh->saddr[0]&=0x7f; + if (((ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8) > 2) + { + rii_p = 1; + } + } + + hash = rif_hash(trh->saddr); + for(entry=rif_table[hash];entry && memcmp(&(entry->addr[0]),&(trh->saddr[0]),TR_ALEN);entry=entry->next); + + if(entry==NULL) + { +#if TR_SR_DEBUG + printk("adding rif_entry: addr:%pM rcf:%04X\n", + trh->saddr, ntohs(trh->rcf)); +#endif + /* + * Allocate our new entry. A failure to allocate loses + * use the information. This is harmless. + * + * FIXME: We ought to keep some kind of cache size + * limiting and adjust the timers to suit. + */ + entry=kmalloc(sizeof(struct rif_cache),GFP_ATOMIC); + + if(!entry) + { + printk(KERN_DEBUG "tr.c: Couldn't malloc rif cache entry !\n"); + spin_unlock_irqrestore(&rif_lock, flags); + return; + } + + memcpy(&(entry->addr[0]),&(trh->saddr[0]),TR_ALEN); + entry->iface = dev->ifindex; + entry->next=rif_table[hash]; + entry->last_used=jiffies; + rif_table[hash]=entry; + + if (rii_p) + { + entry->rcf = trh->rcf & htons((unsigned short)~TR_RCF_BROADCAST_MASK); + memcpy(&(entry->rseg[0]),&(trh->rseg[0]),8*sizeof(unsigned short)); + entry->local_ring = 0; + } + else + { + entry->local_ring = 1; + } + } + else /* Y. Tahara added */ + { + /* + * Update existing entries + */ + if (!entry->local_ring) + if (entry->rcf != (trh->rcf & htons((unsigned short)~TR_RCF_BROADCAST_MASK)) && + !(trh->rcf & htons(TR_RCF_BROADCAST_MASK))) + { +#if TR_SR_DEBUG +printk("updating rif_entry: addr:%pM rcf:%04X\n", + trh->saddr, ntohs(trh->rcf)); +#endif + entry->rcf = trh->rcf & htons((unsigned short)~TR_RCF_BROADCAST_MASK); + memcpy(&(entry->rseg[0]),&(trh->rseg[0]),8*sizeof(unsigned short)); + } + entry->last_used=jiffies; + } + trh->saddr[0]=saddr0; /* put the routing indicator back for tcpdump */ + spin_unlock_irqrestore(&rif_lock, flags); +} + +/* + * Scan the cache with a timer and see what we need to throw out. + */ + +static void rif_check_expire(unsigned long dummy) +{ + int i; + unsigned long flags, next_interval = jiffies + sysctl_tr_rif_timeout/2; + + spin_lock_irqsave(&rif_lock, flags); + + for(i =0; i < RIF_TABLE_SIZE; i++) { + struct rif_cache *entry, **pentry; + + pentry = rif_table+i; + while((entry=*pentry) != NULL) { + unsigned long expires + = entry->last_used + sysctl_tr_rif_timeout; + + if (time_before_eq(expires, jiffies)) { + *pentry = entry->next; + kfree(entry); + } else { + pentry = &entry->next; + + if (time_before(expires, next_interval)) + next_interval = expires; + } + } + } + + spin_unlock_irqrestore(&rif_lock, flags); + + mod_timer(&rif_timer, next_interval); + +} + +/* + * Generate the /proc/net information for the token ring RIF + * routing. + */ + +#ifdef CONFIG_PROC_FS + +static struct rif_cache *rif_get_idx(loff_t pos) +{ + int i; + struct rif_cache *entry; + loff_t off = 0; + + for(i = 0; i < RIF_TABLE_SIZE; i++) + for(entry = rif_table[i]; entry; entry = entry->next) { + if (off == pos) + return entry; + ++off; + } + + return NULL; +} + +static void *rif_seq_start(struct seq_file *seq, loff_t *pos) + __acquires(&rif_lock) +{ + spin_lock_irq(&rif_lock); + + return *pos ? rif_get_idx(*pos - 1) : SEQ_START_TOKEN; +} + +static void *rif_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + int i; + struct rif_cache *ent = v; + + ++*pos; + + if (v == SEQ_START_TOKEN) { + i = -1; + goto scan; + } + + if (ent->next) + return ent->next; + + i = rif_hash(ent->addr); + scan: + while (++i < RIF_TABLE_SIZE) { + if ((ent = rif_table[i]) != NULL) + return ent; + } + return NULL; +} + +static void rif_seq_stop(struct seq_file *seq, void *v) + __releases(&rif_lock) +{ + spin_unlock_irq(&rif_lock); +} + +static int rif_seq_show(struct seq_file *seq, void *v) +{ + int j, rcf_len, segment, brdgnmb; + struct rif_cache *entry = v; + + if (v == SEQ_START_TOKEN) + seq_puts(seq, + "if TR address TTL rcf routing segments\n"); + else { + struct net_device *dev = dev_get_by_index(&init_net, entry->iface); + long ttl = (long) (entry->last_used + sysctl_tr_rif_timeout) + - (long) jiffies; + + seq_printf(seq, "%s %pM %7li ", + dev?dev->name:"?", + entry->addr, + ttl/HZ); + + if (entry->local_ring) + seq_puts(seq, "local\n"); + else { + + seq_printf(seq, "%04X", ntohs(entry->rcf)); + rcf_len = ((ntohs(entry->rcf) & TR_RCF_LEN_MASK)>>8)-2; + if (rcf_len) + rcf_len >>= 1; + for(j = 1; j < rcf_len; j++) { + if(j==1) { + segment=ntohs(entry->rseg[j-1])>>4; + seq_printf(seq," %03X",segment); + } + + segment=ntohs(entry->rseg[j])>>4; + brdgnmb=ntohs(entry->rseg[j-1])&0x00f; + seq_printf(seq,"-%01X-%03X",brdgnmb,segment); + } + seq_putc(seq, '\n'); + } + + if (dev) + dev_put(dev); + } + return 0; +} + + +static const struct seq_operations rif_seq_ops = { + .start = rif_seq_start, + .next = rif_seq_next, + .stop = rif_seq_stop, + .show = rif_seq_show, +}; + +static int rif_seq_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &rif_seq_ops); +} + +static const struct file_operations rif_seq_fops = { + .owner = THIS_MODULE, + .open = rif_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +#endif + +static const struct header_ops tr_header_ops = { + .create = tr_header, + .rebuild= tr_rebuild_header, +}; + +static void tr_setup(struct net_device *dev) +{ + /* + * Configure and register + */ + + dev->header_ops = &tr_header_ops; + + dev->type = ARPHRD_IEEE802_TR; + dev->hard_header_len = TR_HLEN; + dev->mtu = 2000; + dev->addr_len = TR_ALEN; + dev->tx_queue_len = 100; /* Long queues on tr */ + + memset(dev->broadcast,0xFF, TR_ALEN); + + /* New-style flags. */ + dev->flags = IFF_BROADCAST | IFF_MULTICAST ; +} + +/** + * alloc_trdev - Register token ring device + * @sizeof_priv: Size of additional driver-private structure to be allocated + * for this token ring device + * + * Fill in the fields of the device structure with token ring-generic values. + * + * Constructs a new net device, complete with a private data area of + * size @sizeof_priv. A 32-byte (not bit) alignment is enforced for + * this private data area. + */ +struct net_device *alloc_trdev(int sizeof_priv) +{ + return alloc_netdev(sizeof_priv, "tr%d", tr_setup); +} + +#ifdef CONFIG_SYSCTL +static struct ctl_table tr_table[] = { + { + .procname = "rif_timeout", + .data = &sysctl_tr_rif_timeout, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec + }, + { }, +}; +#endif + +/* + * Called during bootup. We don't actually have to initialise + * too much for this. + */ + +static int __init rif_init(void) +{ + rif_timer.expires = jiffies + sysctl_tr_rif_timeout; + setup_timer(&rif_timer, rif_check_expire, 0); + add_timer(&rif_timer); +#ifdef CONFIG_SYSCTL + register_net_sysctl(&init_net, "net/token-ring", tr_table); +#endif + proc_net_fops_create(&init_net, "tr_rif", S_IRUGO, &rif_seq_fops); + return 0; +} + +module_init(rif_init); + +EXPORT_SYMBOL(tr_type_trans); +EXPORT_SYMBOL(alloc_trdev); + +MODULE_LICENSE("GPL"); diff --git a/trunk/net/8021q/vlan.c b/trunk/net/8021q/vlan.c index 6089f0cf23b4..efea35b02e7f 100644 --- a/trunk/net/8021q/vlan.c +++ b/trunk/net/8021q/vlan.c @@ -266,19 +266,19 @@ static void vlan_sync_address(struct net_device *dev, struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev); /* May be called without an actual change */ - if (ether_addr_equal(vlan->real_dev_addr, dev->dev_addr)) + if (!compare_ether_addr(vlan->real_dev_addr, dev->dev_addr)) return; /* vlan address was different from the old address and is equal to * the new address */ - if (!ether_addr_equal(vlandev->dev_addr, vlan->real_dev_addr) && - ether_addr_equal(vlandev->dev_addr, dev->dev_addr)) + if (compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) && + !compare_ether_addr(vlandev->dev_addr, dev->dev_addr)) dev_uc_del(dev, vlandev->dev_addr); /* vlan address was equal to the old address and is different from * the new address */ - if (ether_addr_equal(vlandev->dev_addr, vlan->real_dev_addr) && - !ether_addr_equal(vlandev->dev_addr, dev->dev_addr)) + if (!compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) && + compare_ether_addr(vlandev->dev_addr, dev->dev_addr)) dev_uc_add(dev, vlandev->dev_addr); memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN); diff --git a/trunk/net/8021q/vlan_core.c b/trunk/net/8021q/vlan_core.c index 8ca533c95de0..4d39d802be2c 100644 --- a/trunk/net/8021q/vlan_core.c +++ b/trunk/net/8021q/vlan_core.c @@ -31,7 +31,8 @@ bool vlan_do_receive(struct sk_buff **skbp, bool last_handler) /* Our lower layer thinks this is not local, let's make sure. * This allows the VLAN to have a different MAC than the * underlying device, and still route correctly. */ - if (ether_addr_equal(eth_hdr(skb)->h_dest, vlan_dev->dev_addr)) + if (!compare_ether_addr(eth_hdr(skb)->h_dest, + vlan_dev->dev_addr)) skb->pkt_type = PACKET_HOST; } diff --git a/trunk/net/8021q/vlan_dev.c b/trunk/net/8021q/vlan_dev.c index da1bc9c3cf38..9988d4abb372 100644 --- a/trunk/net/8021q/vlan_dev.c +++ b/trunk/net/8021q/vlan_dev.c @@ -157,7 +157,7 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, skb = __vlan_hwaccel_put_tag(skb, vlan_tci); } - skb->dev = vlan_dev_priv(dev)->real_dev; + skb_set_dev(skb, vlan_dev_priv(dev)->real_dev); len = skb->len; if (netpoll_tx_running(dev)) return skb->dev->netdev_ops->ndo_start_xmit(skb, skb->dev); @@ -277,7 +277,7 @@ static int vlan_dev_open(struct net_device *dev) !(vlan->flags & VLAN_FLAG_LOOSE_BINDING)) return -ENETDOWN; - if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) { + if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) { err = dev_uc_add(real_dev, dev->dev_addr); if (err < 0) goto out; @@ -307,7 +307,7 @@ static int vlan_dev_open(struct net_device *dev) if (dev->flags & IFF_ALLMULTI) dev_set_allmulti(real_dev, -1); del_unicast: - if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) + if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) dev_uc_del(real_dev, dev->dev_addr); out: netif_carrier_off(dev); @@ -326,7 +326,7 @@ static int vlan_dev_stop(struct net_device *dev) if (dev->flags & IFF_PROMISC) dev_set_promiscuity(real_dev, -1); - if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) + if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) dev_uc_del(real_dev, dev->dev_addr); netif_carrier_off(dev); @@ -345,13 +345,13 @@ static int vlan_dev_set_mac_address(struct net_device *dev, void *p) if (!(dev->flags & IFF_UP)) goto out; - if (!ether_addr_equal(addr->sa_data, real_dev->dev_addr)) { + if (compare_ether_addr(addr->sa_data, real_dev->dev_addr)) { err = dev_uc_add(real_dev, addr->sa_data); if (err < 0) return err; } - if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) + if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) dev_uc_del(real_dev, dev->dev_addr); out: diff --git a/trunk/net/9p/trans_virtio.c b/trunk/net/9p/trans_virtio.c index 5af18d11b518..3d432068f627 100644 --- a/trunk/net/9p/trans_virtio.c +++ b/trunk/net/9p/trans_virtio.c @@ -615,8 +615,7 @@ static void p9_virtio_remove(struct virtio_device *vdev) { struct virtio_chan *chan = vdev->priv; - if (chan->inuse) - p9_virtio_close(chan->client); + BUG_ON(chan->inuse); vdev->config->del_vqs(vdev); mutex_lock(&virtio_9p_lock); diff --git a/trunk/net/Kconfig b/trunk/net/Kconfig index 245831bec09a..e07272d0bb2d 100644 --- a/trunk/net/Kconfig +++ b/trunk/net/Kconfig @@ -207,10 +207,10 @@ source "net/ipx/Kconfig" source "drivers/net/appletalk/Kconfig" source "net/x25/Kconfig" source "net/lapb/Kconfig" +source "net/econet/Kconfig" source "net/wanrouter/Kconfig" source "net/phonet/Kconfig" source "net/ieee802154/Kconfig" -source "net/mac802154/Kconfig" source "net/sched/Kconfig" source "net/dcb/Kconfig" source "net/dns_resolver/Kconfig" @@ -246,6 +246,9 @@ config BQL select DQL default y +config HAVE_BPF_JIT + bool + config BPF_JIT bool "enable BPF Just In Time compiler" depends on HAVE_BPF_JIT @@ -292,7 +295,7 @@ config NET_TCPPROBE module will be called tcp_probe. config NET_DROP_MONITOR - tristate "Network packet drop alerting service" + boolean "Network packet drop alerting service" depends on INET && EXPERIMENTAL && TRACEPOINTS ---help--- This feature provides an alerting service to userspace in the @@ -337,7 +340,3 @@ source "net/nfc/Kconfig" endif # if NET - -# Used by archs to tell that they support BPF_JIT -config HAVE_BPF_JIT - bool diff --git a/trunk/net/Makefile b/trunk/net/Makefile index 4f4ee083064c..ad432fa4d934 100644 --- a/trunk/net/Makefile +++ b/trunk/net/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_AF_RXRPC) += rxrpc/ obj-$(CONFIG_ATM) += atm/ obj-$(CONFIG_L2TP) += l2tp/ obj-$(CONFIG_DECNET) += decnet/ +obj-$(CONFIG_ECONET) += econet/ obj-$(CONFIG_PHONET) += phonet/ ifneq ($(CONFIG_VLAN_8021Q),) obj-y += 8021q/ @@ -59,7 +60,6 @@ ifneq ($(CONFIG_DCB),) obj-y += dcb/ endif obj-$(CONFIG_IEEE802154) += ieee802154/ -obj-$(CONFIG_MAC802154) += mac802154/ ifeq ($(CONFIG_NET),y) obj-$(CONFIG_SYSCTL) += sysctl_net.o diff --git a/trunk/net/atm/ioctl.c b/trunk/net/atm/ioctl.c index bbd3b639992e..62dc8bfe6fe7 100644 --- a/trunk/net/atm/ioctl.c +++ b/trunk/net/atm/ioctl.c @@ -97,8 +97,9 @@ static int do_vcc_ioctl(struct socket *sock, unsigned int cmd, error = sock_get_timestampns(sk, argp); goto done; case ATM_SETSC: - net_warn_ratelimited("ATM_SETSC is obsolete; used by %s:%d\n", - current->comm, task_pid_nr(current)); + if (net_ratelimit()) + pr_warning("ATM_SETSC is obsolete; used by %s:%d\n", + current->comm, task_pid_nr(current)); error = 0; goto done; case ATMSIGD_CTRL: @@ -122,7 +123,8 @@ static int do_vcc_ioctl(struct socket *sock, unsigned int cmd, work for 32-bit userspace. TBH I don't really want to think about it at all. dwmw2. */ if (compat) { - net_warn_ratelimited("32-bit task cannot be atmsigd\n"); + if (net_ratelimit()) + pr_warning("32-bit task cannot be atmsigd\n"); error = -EINVAL; goto done; } diff --git a/trunk/net/atm/lec.c b/trunk/net/atm/lec.c index a7d172105c99..f1964caa0f83 100644 --- a/trunk/net/atm/lec.c +++ b/trunk/net/atm/lec.c @@ -26,6 +26,11 @@ #include #include +/* TokenRing if needed */ +#ifdef CONFIG_TR +#include +#endif + /* And atm device */ #include #include @@ -157,6 +162,50 @@ static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev) } #endif /* defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) */ +/* + * Modelled after tr_type_trans + * All multicast and ARE or STE frames go to BUS. + * Non source routed frames go by destination address. + * Last hop source routed frames go by destination address. + * Not last hop source routed frames go by _next_ route descriptor. + * Returns pointer to destination MAC address or fills in rdesc + * and returns NULL. + */ +#ifdef CONFIG_TR +static unsigned char *get_tr_dst(unsigned char *packet, unsigned char *rdesc) +{ + struct trh_hdr *trh; + unsigned int riflen, num_rdsc; + + trh = (struct trh_hdr *)packet; + if (trh->daddr[0] & (uint8_t) 0x80) + return bus_mac; /* multicast */ + + if (trh->saddr[0] & TR_RII) { + riflen = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8; + if ((ntohs(trh->rcf) >> 13) != 0) + return bus_mac; /* ARE or STE */ + } else + return trh->daddr; /* not source routed */ + + if (riflen < 6) + return trh->daddr; /* last hop, source routed */ + + /* riflen is 6 or more, packet has more than one route descriptor */ + num_rdsc = (riflen / 2) - 1; + memset(rdesc, 0, ETH_ALEN); + /* offset 4 comes from LAN destination field in LE control frames */ + if (trh->rcf & htons((uint16_t) TR_RCF_DIR_BIT)) + memcpy(&rdesc[4], &trh->rseg[num_rdsc - 2], sizeof(__be16)); + else { + memcpy(&rdesc[4], &trh->rseg[1], sizeof(__be16)); + rdesc[5] = ((ntohs(trh->rseg[0]) & 0x000f) | (rdesc[5] & 0xf0)); + } + + return NULL; +} +#endif /* CONFIG_TR */ + /* * Open/initialize the netdevice. This is called (in the current kernel) * sometime after booting when the 'ifconfig' program is run. @@ -208,6 +257,9 @@ static netdev_tx_t lec_start_xmit(struct sk_buff *skb, struct lec_arp_table *entry; unsigned char *dst; int min_frame_size; +#ifdef CONFIG_TR + unsigned char rdesc[ETH_ALEN]; /* Token Ring route descriptor */ +#endif int is_rdesc; pr_debug("called\n"); @@ -238,10 +290,24 @@ static netdev_tx_t lec_start_xmit(struct sk_buff *skb, } skb_push(skb, 2); - /* Put le header to place */ + /* Put le header to place, works for TokenRing too */ lec_h = (struct lecdatahdr_8023 *)skb->data; lec_h->le_header = htons(priv->lecid); +#ifdef CONFIG_TR + /* + * Ugly. Use this to realign Token Ring packets for + * e.g. PCA-200E driver. + */ + if (priv->is_trdev) { + skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN); + kfree_skb(skb); + if (skb2 == NULL) + return NETDEV_TX_OK; + skb = skb2; + } +#endif + #if DUMP_PACKETS >= 2 #define MAX_DUMP_SKB 99 #elif DUMP_PACKETS >= 1 @@ -255,7 +321,12 @@ static netdev_tx_t lec_start_xmit(struct sk_buff *skb, #endif /* DUMP_PACKETS >= 1 */ /* Minimum ethernet-frame size */ - min_frame_size = LEC_MINIMUM_8023_SIZE; +#ifdef CONFIG_TR + if (priv->is_trdev) + min_frame_size = LEC_MINIMUM_8025_SIZE; + else +#endif + min_frame_size = LEC_MINIMUM_8023_SIZE; if (skb->len < min_frame_size) { if ((skb->len + skb_tailroom(skb)) < min_frame_size) { skb2 = skb_copy_expand(skb, 0, @@ -274,6 +345,15 @@ static netdev_tx_t lec_start_xmit(struct sk_buff *skb, /* Send to right vcc */ is_rdesc = 0; dst = lec_h->h_dest; +#ifdef CONFIG_TR + if (priv->is_trdev) { + dst = get_tr_dst(skb->data + 2, rdesc); + if (dst == NULL) { + dst = rdesc; + is_rdesc = 1; + } + } +#endif entry = NULL; vcc = lec_arp_resolve(priv, dst, is_rdesc, &entry); pr_debug("%s:vcc:%p vcc_flags:%lx, entry:%p\n", @@ -630,7 +710,12 @@ static void lec_push(struct atm_vcc *vcc, struct sk_buff *skb) dev_kfree_skb(skb); return; } - dst = ((struct lecdatahdr_8023 *)skb->data)->h_dest; +#ifdef CONFIG_TR + if (priv->is_trdev) + dst = ((struct lecdatahdr_8025 *)skb->data)->h_dest; + else +#endif + dst = ((struct lecdatahdr_8023 *)skb->data)->h_dest; /* * If this is a Data Direct VCC, and the VCC does not match @@ -638,7 +723,16 @@ static void lec_push(struct atm_vcc *vcc, struct sk_buff *skb) */ spin_lock_irqsave(&priv->lec_arp_lock, flags); if (lec_is_data_direct(vcc)) { - src = ((struct lecdatahdr_8023 *)skb->data)->h_source; +#ifdef CONFIG_TR + if (priv->is_trdev) + src = + ((struct lecdatahdr_8025 *)skb->data)-> + h_source; + else +#endif + src = + ((struct lecdatahdr_8023 *)skb->data)-> + h_source; entry = lec_arp_find(priv, src); if (entry && entry->vcc != vcc) { lec_arp_remove(priv, entry); @@ -656,7 +750,12 @@ static void lec_push(struct atm_vcc *vcc, struct sk_buff *skb) if (!hlist_empty(&priv->lec_arp_empty_ones)) lec_arp_check_empties(priv, vcc, skb); skb_pull(skb, 2); /* skip lec_id */ - skb->protocol = eth_type_trans(skb, dev); +#ifdef CONFIG_TR + if (priv->is_trdev) + skb->protocol = tr_type_trans(skb, dev); + else +#endif + skb->protocol = eth_type_trans(skb, dev); dev->stats.rx_packets++; dev->stats.rx_bytes += skb->len; memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data)); @@ -728,13 +827,27 @@ static int lecd_attach(struct atm_vcc *vcc, int arg) i = 0; else i = arg; +#ifdef CONFIG_TR if (arg >= MAX_LEC_ITF) return -EINVAL; +#else /* Reserve the top NUM_TR_DEVS for TR */ + if (arg >= (MAX_LEC_ITF - NUM_TR_DEVS)) + return -EINVAL; +#endif if (!dev_lec[i]) { - int size; + int is_trdev, size; + + is_trdev = 0; + if (i >= (MAX_LEC_ITF - NUM_TR_DEVS)) + is_trdev = 1; size = sizeof(struct lec_priv); - dev_lec[i] = alloc_etherdev(size); +#ifdef CONFIG_TR + if (is_trdev) + dev_lec[i] = alloc_trdev(size); + else +#endif + dev_lec[i] = alloc_etherdev(size); if (!dev_lec[i]) return -ENOMEM; dev_lec[i]->netdev_ops = &lec_netdev_ops; @@ -745,6 +858,7 @@ static int lecd_attach(struct atm_vcc *vcc, int arg) } priv = netdev_priv(dev_lec[i]); + priv->is_trdev = is_trdev; } else { priv = netdev_priv(dev_lec[i]); if (priv->lecd) @@ -1141,7 +1255,7 @@ static int lane2_associate_req(struct net_device *dev, const u8 *lan_dst, struct sk_buff *skb; struct lec_priv *priv = netdev_priv(dev); - if (!ether_addr_equal(lan_dst, dev->dev_addr)) + if (compare_ether_addr(lan_dst, dev->dev_addr)) return 0; /* not our mac address */ kfree(priv->tlvs); /* NULL if there was no previous association */ @@ -1548,7 +1662,7 @@ static struct lec_arp_table *lec_arp_find(struct lec_priv *priv, head = &priv->lec_arp_tables[HASH(mac_addr[ETH_ALEN - 1])]; hlist_for_each_entry(entry, node, head, next) { - if (ether_addr_equal(mac_addr, entry->mac_addr)) + if (!compare_ether_addr(mac_addr, entry->mac_addr)) return entry; } return NULL; @@ -1735,7 +1849,7 @@ static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv, case 1: return priv->mcast_vcc; case 2: /* LANE2 wants arp for multicast addresses */ - if (ether_addr_equal(mac_to_find, bus_mac)) + if (!compare_ether_addr(mac_to_find, bus_mac)) return priv->mcast_vcc; break; default: @@ -2258,7 +2372,15 @@ lec_arp_check_empties(struct lec_priv *priv, struct hlist_node *node, *next; struct lec_arp_table *entry, *tmp; struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data; - unsigned char *src = hdr->h_source; + unsigned char *src; +#ifdef CONFIG_TR + struct lecdatahdr_8025 *tr_hdr = (struct lecdatahdr_8025 *)skb->data; + + if (priv->is_trdev) + src = tr_hdr->h_source; + else +#endif + src = hdr->h_source; spin_lock_irqsave(&priv->lec_arp_lock, flags); hlist_for_each_entry_safe(entry, node, next, diff --git a/trunk/net/atm/lec.h b/trunk/net/atm/lec.h index c730e57de199..dfc071966463 100644 --- a/trunk/net/atm/lec.h +++ b/trunk/net/atm/lec.h @@ -142,6 +142,7 @@ struct lec_priv { int itfnum; /* e.g. 2 for lec2, 5 for lec5 */ struct lane2_ops *lane2_ops; /* can be NULL for LANE v1 */ int is_proxy; /* bridge between ATM and Ethernet */ + int is_trdev; /* Device type, 0 = Ethernet, 1 = TokenRing */ }; struct lec_vcc_priv { diff --git a/trunk/net/atm/mpc.c b/trunk/net/atm/mpc.c index d4cc1be5c364..aa972409f093 100644 --- a/trunk/net/atm/mpc.c +++ b/trunk/net/atm/mpc.c @@ -592,7 +592,8 @@ static netdev_tx_t mpc_send_packet(struct sk_buff *skb, goto non_ip; while (i < mpc->number_of_mps_macs) { - if (ether_addr_equal(eth->h_dest, mpc->mps_macs + i * ETH_ALEN)) + if (!compare_ether_addr(eth->h_dest, + (mpc->mps_macs + i*ETH_ALEN))) if (send_via_shortcut(skb, mpc) == 0) /* try shortcut */ return NETDEV_TX_OK; i++; diff --git a/trunk/net/batman-adv/bat_debugfs.c b/trunk/net/batman-adv/bat_debugfs.c index 3b588f86d770..916380c73ab7 100644 --- a/trunk/net/batman-adv/bat_debugfs.c +++ b/trunk/net/batman-adv/bat_debugfs.c @@ -83,8 +83,8 @@ int debug_log(struct bat_priv *bat_priv, const char *fmt, ...) va_start(args, fmt); vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args); - fdebug_log(bat_priv->debug_log, "[%10u] %s", - jiffies_to_msecs(jiffies), tmp_log_buf); + fdebug_log(bat_priv->debug_log, "[%10lu] %s", + (jiffies / HZ), tmp_log_buf); va_end(args); return 0; diff --git a/trunk/net/batman-adv/bat_iv_ogm.c b/trunk/net/batman-adv/bat_iv_ogm.c index dc53798ebb47..8b2db2e76c7e 100644 --- a/trunk/net/batman-adv/bat_iv_ogm.c +++ b/trunk/net/batman-adv/bat_iv_ogm.c @@ -30,31 +30,6 @@ #include "send.h" #include "bat_algo.h" -static struct neigh_node *bat_iv_ogm_neigh_new(struct hard_iface *hard_iface, - const uint8_t *neigh_addr, - struct orig_node *orig_node, - struct orig_node *orig_neigh, - uint32_t seqno) -{ - struct neigh_node *neigh_node; - - neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr, seqno); - if (!neigh_node) - goto out; - - INIT_LIST_HEAD(&neigh_node->bonding_list); - - neigh_node->orig_node = orig_neigh; - neigh_node->if_incoming = hard_iface; - - spin_lock_bh(&orig_node->neigh_list_lock); - hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); - spin_unlock_bh(&orig_node->neigh_list_lock); - -out: - return neigh_node; -} - static int bat_iv_ogm_iface_enable(struct hard_iface *hard_iface) { struct batman_ogm_packet *batman_ogm_packet; @@ -92,24 +67,24 @@ static void bat_iv_ogm_iface_disable(struct hard_iface *hard_iface) hard_iface->packet_buff = NULL; } -static void bat_iv_ogm_iface_update_mac(struct hard_iface *hard_iface) +static void bat_iv_ogm_primary_iface_set(struct hard_iface *hard_iface) { struct batman_ogm_packet *batman_ogm_packet; batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff; - memcpy(batman_ogm_packet->orig, - hard_iface->net_dev->dev_addr, ETH_ALEN); - memcpy(batman_ogm_packet->prev_sender, - hard_iface->net_dev->dev_addr, ETH_ALEN); + batman_ogm_packet->flags = PRIMARIES_FIRST_HOP; + batman_ogm_packet->header.ttl = TTL; } -static void bat_iv_ogm_primary_iface_set(struct hard_iface *hard_iface) +static void bat_iv_ogm_update_mac(struct hard_iface *hard_iface) { struct batman_ogm_packet *batman_ogm_packet; batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff; - batman_ogm_packet->flags = PRIMARIES_FIRST_HOP; - batman_ogm_packet->header.ttl = TTL; + memcpy(batman_ogm_packet->orig, + hard_iface->net_dev->dev_addr, ETH_ALEN); + memcpy(batman_ogm_packet->prev_sender, + hard_iface->net_dev->dev_addr, ETH_ALEN); } /* when do we schedule our own ogm to be sent */ @@ -505,11 +480,11 @@ static void bat_iv_ogm_queue_add(struct bat_priv *bat_priv, static void bat_iv_ogm_forward(struct orig_node *orig_node, const struct ethhdr *ethhdr, struct batman_ogm_packet *batman_ogm_packet, - bool is_single_hop_neigh, - bool is_from_best_next_hop, - struct hard_iface *if_incoming) + int directlink, struct hard_iface *if_incoming) { struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); + struct neigh_node *router; + uint8_t in_tq, in_ttl, tq_avg = 0; uint8_t tt_num_changes; if (batman_ogm_packet->header.ttl <= 1) { @@ -517,37 +492,48 @@ static void bat_iv_ogm_forward(struct orig_node *orig_node, return; } - if (!is_from_best_next_hop) { - /* Mark the forwarded packet when it is not coming from our - * best next hop. We still need to forward the packet for our - * neighbor link quality detection to work in case the packet - * originated from a single hop neighbor. Otherwise we can - * simply drop the ogm. - */ - if (is_single_hop_neigh) - batman_ogm_packet->flags |= NOT_BEST_NEXT_HOP; - else - return; - } + router = orig_node_get_router(orig_node); + in_tq = batman_ogm_packet->tq; + in_ttl = batman_ogm_packet->header.ttl; tt_num_changes = batman_ogm_packet->tt_num_changes; batman_ogm_packet->header.ttl--; memcpy(batman_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN); + /* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast + * of our best tq value */ + if (router && router->tq_avg != 0) { + + /* rebroadcast ogm of best ranking neighbor as is */ + if (!compare_eth(router->addr, ethhdr->h_source)) { + batman_ogm_packet->tq = router->tq_avg; + + if (router->last_ttl) + batman_ogm_packet->header.ttl = + router->last_ttl - 1; + } + + tq_avg = router->tq_avg; + } + + if (router) + neigh_node_free_ref(router); + /* apply hop penalty */ batman_ogm_packet->tq = hop_penalty(batman_ogm_packet->tq, bat_priv); bat_dbg(DBG_BATMAN, bat_priv, - "Forwarding packet: tq: %i, ttl: %i\n", - batman_ogm_packet->tq, batman_ogm_packet->header.ttl); + "Forwarding packet: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n", + in_tq, tq_avg, batman_ogm_packet->tq, in_ttl - 1, + batman_ogm_packet->header.ttl); batman_ogm_packet->seqno = htonl(batman_ogm_packet->seqno); batman_ogm_packet->tt_crc = htons(batman_ogm_packet->tt_crc); /* switch of primaries first hop flag when forwarding */ batman_ogm_packet->flags &= ~PRIMARIES_FIRST_HOP; - if (is_single_hop_neigh) + if (directlink) batman_ogm_packet->flags |= DIRECTLINK; else batman_ogm_packet->flags &= ~DIRECTLINK; @@ -636,12 +622,12 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, if (is_duplicate) continue; - spin_lock_bh(&tmp_neigh_node->lq_update_lock); + spin_lock_bh(&tmp_neigh_node->tq_lock); ring_buffer_set(tmp_neigh_node->tq_recv, &tmp_neigh_node->tq_index, 0); tmp_neigh_node->tq_avg = ring_buffer_avg(tmp_neigh_node->tq_recv); - spin_unlock_bh(&tmp_neigh_node->lq_update_lock); + spin_unlock_bh(&tmp_neigh_node->tq_lock); } if (!neigh_node) { @@ -651,9 +637,8 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, if (!orig_tmp) goto unlock; - neigh_node = bat_iv_ogm_neigh_new(if_incoming, ethhdr->h_source, - orig_node, orig_tmp, - batman_ogm_packet->seqno); + neigh_node = create_neighbor(orig_node, orig_tmp, + ethhdr->h_source, if_incoming); orig_node_free_ref(orig_tmp); if (!neigh_node) @@ -665,14 +650,14 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, rcu_read_unlock(); orig_node->flags = batman_ogm_packet->flags; - neigh_node->last_seen = jiffies; + neigh_node->last_valid = jiffies; - spin_lock_bh(&neigh_node->lq_update_lock); + spin_lock_bh(&neigh_node->tq_lock); ring_buffer_set(neigh_node->tq_recv, &neigh_node->tq_index, batman_ogm_packet->tq); neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv); - spin_unlock_bh(&neigh_node->lq_update_lock); + spin_unlock_bh(&neigh_node->tq_lock); if (!is_duplicate) { orig_node->last_ttl = batman_ogm_packet->header.ttl; @@ -778,20 +763,19 @@ static int bat_iv_ogm_calc_tq(struct orig_node *orig_node, rcu_read_unlock(); if (!neigh_node) - neigh_node = bat_iv_ogm_neigh_new(if_incoming, - orig_neigh_node->orig, - orig_neigh_node, - orig_neigh_node, - batman_ogm_packet->seqno); + neigh_node = create_neighbor(orig_neigh_node, + orig_neigh_node, + orig_neigh_node->orig, + if_incoming); if (!neigh_node) goto out; - /* if orig_node is direct neighbor update neigh_node last_seen */ + /* if orig_node is direct neighbor update neigh_node last_valid */ if (orig_node == orig_neigh_node) - neigh_node->last_seen = jiffies; + neigh_node->last_valid = jiffies; - orig_node->last_seen = jiffies; + orig_node->last_valid = jiffies; /* find packet count of corresponding one hop neighbor */ spin_lock_bh(&orig_node->ogm_cnt_lock); @@ -934,9 +918,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, struct neigh_node *orig_neigh_router = NULL; int has_directlink_flag; int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0; - int is_broadcast = 0, is_bidirectional; - bool is_single_hop_neigh = false; - bool is_from_best_next_hop = false; + int is_broadcast = 0, is_bidirectional, is_single_hop_neigh; int is_duplicate; uint32_t if_incoming_seqno; @@ -960,8 +942,8 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, has_directlink_flag = (batman_ogm_packet->flags & DIRECTLINK ? 1 : 0); - if (compare_eth(ethhdr->h_source, batman_ogm_packet->orig)) - is_single_hop_neigh = true; + is_single_hop_neigh = (compare_eth(ethhdr->h_source, + batman_ogm_packet->orig) ? 1 : 0); bat_dbg(DBG_BATMAN, bat_priv, "Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, ttvn %u, crc %u, changes %u, td %d, TTL %d, V %d, IDF %d)\n", @@ -1058,13 +1040,6 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, return; } - if (batman_ogm_packet->flags & NOT_BEST_NEXT_HOP) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: ignoring all packets not forwarded from the best next hop (sender: %pM)\n", - ethhdr->h_source); - return; - } - orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig); if (!orig_node) return; @@ -1089,10 +1064,6 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, if (router) router_router = orig_node_get_router(router->orig_node); - if ((router && router->tq_avg != 0) && - (compare_eth(router->addr, ethhdr->h_source))) - is_from_best_next_hop = true; - /* avoid temporary routing loops */ if (router && router_router && (compare_eth(router->addr, batman_ogm_packet->prev_sender)) && @@ -1143,8 +1114,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, /* mark direct link on incoming interface */ bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet, - is_single_hop_neigh, is_from_best_next_hop, - if_incoming); + 1, if_incoming); bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: rebroadcast neighbor packet with direct link flag\n"); @@ -1167,8 +1137,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: rebroadcast originator packet\n"); bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet, - is_single_hop_neigh, is_from_best_next_hop, - if_incoming); + 0, if_incoming); out_neigh: if ((orig_neigh_node) && (!is_single_hop_neigh)) @@ -1184,25 +1153,13 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr, orig_node_free_ref(orig_node); } -static int bat_iv_ogm_receive(struct sk_buff *skb, - struct hard_iface *if_incoming) +static void bat_iv_ogm_receive(struct hard_iface *if_incoming, + struct sk_buff *skb) { - struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct batman_ogm_packet *batman_ogm_packet; struct ethhdr *ethhdr; int buff_pos = 0, packet_len; unsigned char *tt_buff, *packet_buff; - bool ret; - - ret = check_management_packet(skb, if_incoming, BATMAN_OGM_HLEN); - if (!ret) - return NET_RX_DROP; - - /* did we receive a B.A.T.M.A.N. IV OGM packet on an interface - * that does not have B.A.T.M.A.N. IV enabled ? - */ - if (bat_priv->bat_algo_ops->bat_ogm_emit != bat_iv_ogm_emit) - return NET_RX_DROP; packet_len = skb_headlen(skb); ethhdr = (struct ethhdr *)skb_mac_header(skb); @@ -1228,38 +1185,20 @@ static int bat_iv_ogm_receive(struct sk_buff *skb, (packet_buff + buff_pos); } while (bat_iv_ogm_aggr_packet(buff_pos, packet_len, batman_ogm_packet->tt_num_changes)); - - kfree_skb(skb); - return NET_RX_SUCCESS; } static struct bat_algo_ops batman_iv __read_mostly = { .name = "BATMAN IV", .bat_iface_enable = bat_iv_ogm_iface_enable, .bat_iface_disable = bat_iv_ogm_iface_disable, - .bat_iface_update_mac = bat_iv_ogm_iface_update_mac, .bat_primary_iface_set = bat_iv_ogm_primary_iface_set, + .bat_ogm_update_mac = bat_iv_ogm_update_mac, .bat_ogm_schedule = bat_iv_ogm_schedule, .bat_ogm_emit = bat_iv_ogm_emit, + .bat_ogm_receive = bat_iv_ogm_receive, }; int __init bat_iv_init(void) { - int ret; - - /* batman originator packet */ - ret = recv_handler_register(BAT_IV_OGM, bat_iv_ogm_receive); - if (ret < 0) - goto out; - - ret = bat_algo_register(&batman_iv); - if (ret < 0) - goto handler_unregister; - - goto out; - -handler_unregister: - recv_handler_unregister(BAT_IV_OGM); -out: - return ret; + return bat_algo_register(&batman_iv); } diff --git a/trunk/net/batman-adv/bat_sysfs.c b/trunk/net/batman-adv/bat_sysfs.c index 5bc7b66d32dc..2c816883ca13 100644 --- a/trunk/net/batman-adv/bat_sysfs.c +++ b/trunk/net/batman-adv/bat_sysfs.c @@ -63,7 +63,7 @@ struct bat_attribute bat_attr_##_name = { \ .store = _store, \ }; -#define BAT_ATTR_SIF_STORE_BOOL(_name, _post_func) \ +#define BAT_ATTR_STORE_BOOL(_name, _post_func) \ ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ char *buff, size_t count) \ { \ @@ -73,9 +73,9 @@ ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ &bat_priv->_name, net_dev); \ } -#define BAT_ATTR_SIF_SHOW_BOOL(_name) \ -ssize_t show_##_name(struct kobject *kobj, \ - struct attribute *attr, char *buff) \ +#define BAT_ATTR_SHOW_BOOL(_name) \ +ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \ + char *buff) \ { \ struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \ return sprintf(buff, "%s\n", \ @@ -83,17 +83,16 @@ ssize_t show_##_name(struct kobject *kobj, \ "disabled" : "enabled"); \ } \ -/* Use this, if you are going to turn a [name] in the soft-interface - * (bat_priv) on or off */ -#define BAT_ATTR_SIF_BOOL(_name, _mode, _post_func) \ - static BAT_ATTR_SIF_STORE_BOOL(_name, _post_func) \ - static BAT_ATTR_SIF_SHOW_BOOL(_name) \ +/* Use this, if you are going to turn a [name] in bat_priv on or off */ +#define BAT_ATTR_BOOL(_name, _mode, _post_func) \ + static BAT_ATTR_STORE_BOOL(_name, _post_func) \ + static BAT_ATTR_SHOW_BOOL(_name) \ static BAT_ATTR(_name, _mode, show_##_name, store_##_name) -#define BAT_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func) \ +#define BAT_ATTR_STORE_UINT(_name, _min, _max, _post_func) \ ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ - char *buff, size_t count) \ + char *buff, size_t count) \ { \ struct net_device *net_dev = kobj_to_netdev(kobj); \ struct bat_priv *bat_priv = netdev_priv(net_dev); \ @@ -101,62 +100,19 @@ ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ attr, &bat_priv->_name, net_dev); \ } -#define BAT_ATTR_SIF_SHOW_UINT(_name) \ -ssize_t show_##_name(struct kobject *kobj, \ - struct attribute *attr, char *buff) \ +#define BAT_ATTR_SHOW_UINT(_name) \ +ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \ + char *buff) \ { \ struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \ return sprintf(buff, "%i\n", atomic_read(&bat_priv->_name)); \ } \ -/* Use this, if you are going to set [name] in the soft-interface - * (bat_priv) to an unsigned integer value */ -#define BAT_ATTR_SIF_UINT(_name, _mode, _min, _max, _post_func) \ - static BAT_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func) \ - static BAT_ATTR_SIF_SHOW_UINT(_name) \ - static BAT_ATTR(_name, _mode, show_##_name, store_##_name) - - -#define BAT_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func) \ -ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ - char *buff, size_t count) \ -{ \ - struct net_device *net_dev = kobj_to_netdev(kobj); \ - struct hard_iface *hard_iface = hardif_get_by_netdev(net_dev); \ - ssize_t length; \ - \ - if (!hard_iface) \ - return 0; \ - \ - length = __store_uint_attr(buff, count, _min, _max, _post_func, \ - attr, &hard_iface->_name, net_dev); \ - \ - hardif_free_ref(hard_iface); \ - return length; \ -} - -#define BAT_ATTR_HIF_SHOW_UINT(_name) \ -ssize_t show_##_name(struct kobject *kobj, \ - struct attribute *attr, char *buff) \ -{ \ - struct net_device *net_dev = kobj_to_netdev(kobj); \ - struct hard_iface *hard_iface = hardif_get_by_netdev(net_dev); \ - ssize_t length; \ - \ - if (!hard_iface) \ - return 0; \ - \ - length = sprintf(buff, "%i\n", atomic_read(&hard_iface->_name));\ - \ - hardif_free_ref(hard_iface); \ - return length; \ -} - -/* Use this, if you are going to set [name] in hard_iface to an - * unsigned integer value*/ -#define BAT_ATTR_HIF_UINT(_name, _mode, _min, _max, _post_func) \ - static BAT_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func) \ - static BAT_ATTR_HIF_SHOW_UINT(_name) \ +/* Use this, if you are going to set [name] in bat_priv to unsigned integer + * values only */ +#define BAT_ATTR_UINT(_name, _mode, _min, _max, _post_func) \ + static BAT_ATTR_STORE_UINT(_name, _min, _max, _post_func) \ + static BAT_ATTR_SHOW_UINT(_name) \ static BAT_ATTR(_name, _mode, show_##_name, store_##_name) @@ -428,24 +384,24 @@ static ssize_t store_gw_bwidth(struct kobject *kobj, struct attribute *attr, return gw_bandwidth_set(net_dev, buff, count); } -BAT_ATTR_SIF_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL); -BAT_ATTR_SIF_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); +BAT_ATTR_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL); +BAT_ATTR_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); #ifdef CONFIG_BATMAN_ADV_BLA -BAT_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL); +BAT_ATTR_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL); #endif -BAT_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu); -BAT_ATTR_SIF_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL); +BAT_ATTR_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu); +BAT_ATTR_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL); static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode); static BAT_ATTR(routing_algo, S_IRUGO, show_bat_algo, NULL); static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, show_gw_mode, store_gw_mode); -BAT_ATTR_SIF_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL); -BAT_ATTR_SIF_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL); -BAT_ATTR_SIF_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE, - post_gw_deselect); +BAT_ATTR_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL); +BAT_ATTR_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL); +BAT_ATTR_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE, + post_gw_deselect); static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth, store_gw_bwidth); #ifdef CONFIG_BATMAN_ADV_DEBUG -BAT_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, 15, NULL); +BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 15, NULL); #endif static struct bat_attribute *mesh_attrs[] = { diff --git a/trunk/net/batman-adv/bridge_loop_avoidance.c b/trunk/net/batman-adv/bridge_loop_avoidance.c index 8bf97515a77d..ad394c6496cc 100644 --- a/trunk/net/batman-adv/bridge_loop_avoidance.c +++ b/trunk/net/batman-adv/bridge_loop_avoidance.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 B.A.T.M.A.N. contributors: + * Copyright (C) 2011 B.A.T.M.A.N. contributors: * * Simon Wunderlich * diff --git a/trunk/net/batman-adv/bridge_loop_avoidance.h b/trunk/net/batman-adv/bridge_loop_avoidance.h index e39f93acc28f..4a8e4fc766bc 100644 --- a/trunk/net/batman-adv/bridge_loop_avoidance.h +++ b/trunk/net/batman-adv/bridge_loop_avoidance.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 B.A.T.M.A.N. contributors: + * Copyright (C) 2011 B.A.T.M.A.N. contributors: * * Simon Wunderlich * diff --git a/trunk/net/batman-adv/gateway_client.c b/trunk/net/batman-adv/gateway_client.c index 47f7186dcefc..6f9b9b78f77d 100644 --- a/trunk/net/batman-adv/gateway_client.c +++ b/trunk/net/batman-adv/gateway_client.c @@ -558,10 +558,10 @@ static bool is_type_dhcprequest(struct sk_buff *skb, int header_len) p++; /* ...and then we jump over the data */ - if (pkt_len < 1 + (*p)) + if (pkt_len < *p) goto out; - pkt_len -= 1 + (*p); - p += 1 + (*p); + pkt_len -= *p; + p += (*p); } } out: diff --git a/trunk/net/batman-adv/hard-interface.c b/trunk/net/batman-adv/hard-interface.c index dc334fa89847..47c79d724ba3 100644 --- a/trunk/net/batman-adv/hard-interface.c +++ b/trunk/net/batman-adv/hard-interface.c @@ -32,6 +32,12 @@ #include + +static int batman_skb_recv(struct sk_buff *skb, + struct net_device *dev, + struct packet_type *ptype, + struct net_device *orig_dev); + void hardif_free_rcu(struct rcu_head *rcu) { struct hard_iface *hard_iface; @@ -173,9 +179,9 @@ static void check_known_mac_addr(const struct net_device *net_dev) net_dev->dev_addr)) continue; - pr_warn("The newly added mac address (%pM) already exists on: %s\n", - net_dev->dev_addr, hard_iface->net_dev->name); - pr_warn("It is strongly recommended to keep mac addresses unique to avoid problems!\n"); + pr_warning("The newly added mac address (%pM) already exists on: %s\n", + net_dev->dev_addr, hard_iface->net_dev->name); + pr_warning("It is strongly recommended to keep mac addresses unique to avoid problems!\n"); } rcu_read_unlock(); } @@ -228,7 +234,7 @@ static void hardif_activate_interface(struct hard_iface *hard_iface) bat_priv = netdev_priv(hard_iface->soft_iface); - bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface); + bat_priv->bat_algo_ops->bat_ogm_update_mac(hard_iface); hard_iface->if_status = IF_TO_BE_ACTIVATED; /** @@ -524,7 +530,7 @@ static int hard_if_event(struct notifier_block *this, check_known_mac_addr(hard_iface->net_dev); bat_priv = netdev_priv(hard_iface->soft_iface); - bat_priv->bat_algo_ops->bat_iface_update_mac(hard_iface); + bat_priv->bat_algo_ops->bat_ogm_update_mac(hard_iface); primary_if = primary_if_get_selected(bat_priv); if (!primary_if) @@ -545,6 +551,113 @@ static int hard_if_event(struct notifier_block *this, return NOTIFY_DONE; } +/* incoming packets with the batman ethertype received on any active hard + * interface */ +static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *ptype, + struct net_device *orig_dev) +{ + struct bat_priv *bat_priv; + struct batman_ogm_packet *batman_ogm_packet; + struct hard_iface *hard_iface; + int ret; + + hard_iface = container_of(ptype, struct hard_iface, batman_adv_ptype); + skb = skb_share_check(skb, GFP_ATOMIC); + + /* skb was released by skb_share_check() */ + if (!skb) + goto err_out; + + /* packet should hold at least type and version */ + if (unlikely(!pskb_may_pull(skb, 2))) + goto err_free; + + /* expect a valid ethernet header here. */ + if (unlikely(skb->mac_len != ETH_HLEN || !skb_mac_header(skb))) + goto err_free; + + if (!hard_iface->soft_iface) + goto err_free; + + bat_priv = netdev_priv(hard_iface->soft_iface); + + if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) + goto err_free; + + /* discard frames on not active interfaces */ + if (hard_iface->if_status != IF_ACTIVE) + goto err_free; + + batman_ogm_packet = (struct batman_ogm_packet *)skb->data; + + if (batman_ogm_packet->header.version != COMPAT_VERSION) { + bat_dbg(DBG_BATMAN, bat_priv, + "Drop packet: incompatible batman version (%i)\n", + batman_ogm_packet->header.version); + goto err_free; + } + + /* all receive handlers return whether they received or reused + * the supplied skb. if not, we have to free the skb. */ + + switch (batman_ogm_packet->header.packet_type) { + /* batman originator packet */ + case BAT_IV_OGM: + ret = recv_bat_ogm_packet(skb, hard_iface); + break; + + /* batman icmp packet */ + case BAT_ICMP: + ret = recv_icmp_packet(skb, hard_iface); + break; + + /* unicast packet */ + case BAT_UNICAST: + ret = recv_unicast_packet(skb, hard_iface); + break; + + /* fragmented unicast packet */ + case BAT_UNICAST_FRAG: + ret = recv_ucast_frag_packet(skb, hard_iface); + break; + + /* broadcast packet */ + case BAT_BCAST: + ret = recv_bcast_packet(skb, hard_iface); + break; + + /* vis packet */ + case BAT_VIS: + ret = recv_vis_packet(skb, hard_iface); + break; + /* Translation table query (request or response) */ + case BAT_TT_QUERY: + ret = recv_tt_query(skb, hard_iface); + break; + /* Roaming advertisement */ + case BAT_ROAM_ADV: + ret = recv_roam_adv(skb, hard_iface); + break; + default: + ret = NET_RX_DROP; + } + + if (ret == NET_RX_DROP) + kfree_skb(skb); + + /* return NET_RX_SUCCESS in any case as we + * most probably dropped the packet for + * routing-logical reasons. */ + + return NET_RX_SUCCESS; + +err_free: + kfree_skb(skb); +err_out: + return NET_RX_DROP; +} + /* This function returns true if the interface represented by ifindex is a * 802.11 wireless device */ bool is_wifi_iface(int ifindex) diff --git a/trunk/net/batman-adv/main.c b/trunk/net/batman-adv/main.c index 083a2993efe4..791327219531 100644 --- a/trunk/net/batman-adv/main.c +++ b/trunk/net/batman-adv/main.c @@ -39,7 +39,6 @@ /* List manipulations on hardif_list have to be rtnl_lock()'ed, * list traversals just rcu-locked */ struct list_head hardif_list; -static int (*recv_packet_handler[256])(struct sk_buff *, struct hard_iface *); char bat_routing_algo[20] = "BATMAN IV"; static struct hlist_head bat_algo_list; @@ -47,15 +46,11 @@ unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; struct workqueue_struct *bat_event_workqueue; -static void recv_handler_init(void); - static int __init batman_init(void) { INIT_LIST_HEAD(&hardif_list); INIT_HLIST_HEAD(&bat_algo_list); - recv_handler_init(); - bat_iv_init(); /* the name should not be longer than 10 chars - see @@ -184,120 +179,6 @@ int is_my_mac(const uint8_t *addr) return 0; } -static int recv_unhandled_packet(struct sk_buff *skb, - struct hard_iface *recv_if) -{ - return NET_RX_DROP; -} - -/* incoming packets with the batman ethertype received on any active hard - * interface - */ -int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *ptype, struct net_device *orig_dev) -{ - struct bat_priv *bat_priv; - struct batman_ogm_packet *batman_ogm_packet; - struct hard_iface *hard_iface; - uint8_t idx; - int ret; - - hard_iface = container_of(ptype, struct hard_iface, batman_adv_ptype); - skb = skb_share_check(skb, GFP_ATOMIC); - - /* skb was released by skb_share_check() */ - if (!skb) - goto err_out; - - /* packet should hold at least type and version */ - if (unlikely(!pskb_may_pull(skb, 2))) - goto err_free; - - /* expect a valid ethernet header here. */ - if (unlikely(skb->mac_len != ETH_HLEN || !skb_mac_header(skb))) - goto err_free; - - if (!hard_iface->soft_iface) - goto err_free; - - bat_priv = netdev_priv(hard_iface->soft_iface); - - if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) - goto err_free; - - /* discard frames on not active interfaces */ - if (hard_iface->if_status != IF_ACTIVE) - goto err_free; - - batman_ogm_packet = (struct batman_ogm_packet *)skb->data; - - if (batman_ogm_packet->header.version != COMPAT_VERSION) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: incompatible batman version (%i)\n", - batman_ogm_packet->header.version); - goto err_free; - } - - /* all receive handlers return whether they received or reused - * the supplied skb. if not, we have to free the skb. - */ - idx = batman_ogm_packet->header.packet_type; - ret = (*recv_packet_handler[idx])(skb, hard_iface); - - if (ret == NET_RX_DROP) - kfree_skb(skb); - - /* return NET_RX_SUCCESS in any case as we - * most probably dropped the packet for - * routing-logical reasons. - */ - return NET_RX_SUCCESS; - -err_free: - kfree_skb(skb); -err_out: - return NET_RX_DROP; -} - -static void recv_handler_init(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(recv_packet_handler); i++) - recv_packet_handler[i] = recv_unhandled_packet; - - /* batman icmp packet */ - recv_packet_handler[BAT_ICMP] = recv_icmp_packet; - /* unicast packet */ - recv_packet_handler[BAT_UNICAST] = recv_unicast_packet; - /* fragmented unicast packet */ - recv_packet_handler[BAT_UNICAST_FRAG] = recv_ucast_frag_packet; - /* broadcast packet */ - recv_packet_handler[BAT_BCAST] = recv_bcast_packet; - /* vis packet */ - recv_packet_handler[BAT_VIS] = recv_vis_packet; - /* Translation table query (request or response) */ - recv_packet_handler[BAT_TT_QUERY] = recv_tt_query; - /* Roaming advertisement */ - recv_packet_handler[BAT_ROAM_ADV] = recv_roam_adv; -} - -int recv_handler_register(uint8_t packet_type, - int (*recv_handler)(struct sk_buff *, - struct hard_iface *)) -{ - if (recv_packet_handler[packet_type] != &recv_unhandled_packet) - return -EBUSY; - - recv_packet_handler[packet_type] = recv_handler; - return 0; -} - -void recv_handler_unregister(uint8_t packet_type) -{ - recv_packet_handler[packet_type] = recv_unhandled_packet; -} - static struct bat_algo_ops *bat_algo_get(char *name) { struct bat_algo_ops *bat_algo_ops = NULL, *bat_algo_ops_tmp; @@ -329,10 +210,11 @@ int bat_algo_register(struct bat_algo_ops *bat_algo_ops) /* all algorithms must implement all ops (for now) */ if (!bat_algo_ops->bat_iface_enable || !bat_algo_ops->bat_iface_disable || - !bat_algo_ops->bat_iface_update_mac || !bat_algo_ops->bat_primary_iface_set || + !bat_algo_ops->bat_ogm_update_mac || !bat_algo_ops->bat_ogm_schedule || - !bat_algo_ops->bat_ogm_emit) { + !bat_algo_ops->bat_ogm_emit || + !bat_algo_ops->bat_ogm_receive) { pr_info("Routing algo '%s' does not implement required ops\n", bat_algo_ops->name); goto out; diff --git a/trunk/net/batman-adv/main.h b/trunk/net/batman-adv/main.h index f4a3ec003479..d9832acf558d 100644 --- a/trunk/net/batman-adv/main.h +++ b/trunk/net/batman-adv/main.h @@ -28,7 +28,7 @@ #define DRIVER_DEVICE "batman-adv" #ifndef SOURCE_VERSION -#define SOURCE_VERSION "2012.2.0" +#define SOURCE_VERSION "2012.1.0" #endif /* B.A.T.M.A.N. parameters */ @@ -155,12 +155,6 @@ void mesh_free(struct net_device *soft_iface); void inc_module_count(void); void dec_module_count(void); int is_my_mac(const uint8_t *addr); -int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *ptype, struct net_device *orig_dev); -int recv_handler_register(uint8_t packet_type, - int (*recv_handler)(struct sk_buff *, - struct hard_iface *)); -void recv_handler_unregister(uint8_t packet_type); int bat_algo_register(struct bat_algo_ops *bat_algo_ops); int bat_algo_select(struct bat_priv *bat_priv, char *name); int bat_algo_seq_print_text(struct seq_file *seq, void *offset); diff --git a/trunk/net/batman-adv/originator.c b/trunk/net/batman-adv/originator.c index 41147942ba53..ce4969885894 100644 --- a/trunk/net/batman-adv/originator.c +++ b/trunk/net/batman-adv/originator.c @@ -35,8 +35,7 @@ static void purge_orig(struct work_struct *work); static void start_purge_timer(struct bat_priv *bat_priv) { INIT_DELAYED_WORK(&bat_priv->orig_work, purge_orig); - queue_delayed_work(bat_event_workqueue, - &bat_priv->orig_work, msecs_to_jiffies(1000)); + queue_delayed_work(bat_event_workqueue, &bat_priv->orig_work, 1 * HZ); } /* returns 1 if they are the same originator */ @@ -85,30 +84,35 @@ struct neigh_node *orig_node_get_router(struct orig_node *orig_node) return router; } -struct neigh_node *batadv_neigh_node_new(struct hard_iface *hard_iface, - const uint8_t *neigh_addr, - uint32_t seqno) +struct neigh_node *create_neighbor(struct orig_node *orig_node, + struct orig_node *orig_neigh_node, + const uint8_t *neigh, + struct hard_iface *if_incoming) { - struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); + struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct neigh_node *neigh_node; + bat_dbg(DBG_BATMAN, bat_priv, + "Creating new last-hop neighbor of originator\n"); + neigh_node = kzalloc(sizeof(*neigh_node), GFP_ATOMIC); if (!neigh_node) - goto out; + return NULL; INIT_HLIST_NODE(&neigh_node->list); + INIT_LIST_HEAD(&neigh_node->bonding_list); + spin_lock_init(&neigh_node->tq_lock); - memcpy(neigh_node->addr, neigh_addr, ETH_ALEN); - spin_lock_init(&neigh_node->lq_update_lock); + memcpy(neigh_node->addr, neigh, ETH_ALEN); + neigh_node->orig_node = orig_neigh_node; + neigh_node->if_incoming = if_incoming; /* extra reference for return */ atomic_set(&neigh_node->refcount, 2); - bat_dbg(DBG_BATMAN, bat_priv, - "Creating new neighbor %pM, initial seqno %d\n", - neigh_addr, seqno); - -out: + spin_lock_bh(&orig_node->neigh_list_lock); + hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); + spin_unlock_bh(&orig_node->neigh_list_lock); return neigh_node; } @@ -270,7 +274,6 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv, struct hlist_node *node, *node_tmp; struct neigh_node *neigh_node; bool neigh_purged = false; - unsigned long last_seen; *best_neigh_node = NULL; @@ -280,13 +283,11 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv, hlist_for_each_entry_safe(neigh_node, node, node_tmp, &orig_node->neigh_list, list) { - if ((has_timed_out(neigh_node->last_seen, PURGE_TIMEOUT)) || + if ((has_timed_out(neigh_node->last_valid, PURGE_TIMEOUT)) || (neigh_node->if_incoming->if_status == IF_INACTIVE) || (neigh_node->if_incoming->if_status == IF_NOT_IN_USE) || (neigh_node->if_incoming->if_status == IF_TO_BE_REMOVED)) { - last_seen = neigh_node->last_seen; - if ((neigh_node->if_incoming->if_status == IF_INACTIVE) || (neigh_node->if_incoming->if_status == @@ -299,9 +300,9 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv, neigh_node->if_incoming->net_dev->name); else bat_dbg(DBG_BATMAN, bat_priv, - "neighbor timeout: originator %pM, neighbor: %pM, last_seen: %u\n", + "neighbor timeout: originator %pM, neighbor: %pM, last_valid: %lu\n", orig_node->orig, neigh_node->addr, - jiffies_to_msecs(last_seen)); + (neigh_node->last_valid / HZ)); neigh_purged = true; @@ -324,11 +325,10 @@ static bool purge_orig_node(struct bat_priv *bat_priv, { struct neigh_node *best_neigh_node; - if (has_timed_out(orig_node->last_seen, 2 * PURGE_TIMEOUT)) { + if (has_timed_out(orig_node->last_valid, 2 * PURGE_TIMEOUT)) { bat_dbg(DBG_BATMAN, bat_priv, - "Originator timeout: originator %pM, last_seen %u\n", - orig_node->orig, - jiffies_to_msecs(orig_node->last_seen)); + "Originator timeout: originator %pM, last_valid %lu\n", + orig_node->orig, (orig_node->last_valid / HZ)); return true; } else { if (purge_orig_neighbors(bat_priv, orig_node, @@ -446,9 +446,9 @@ int orig_seq_print_text(struct seq_file *seq, void *offset) goto next; last_seen_secs = jiffies_to_msecs(jiffies - - orig_node->last_seen) / 1000; + orig_node->last_valid) / 1000; last_seen_msecs = jiffies_to_msecs(jiffies - - orig_node->last_seen) % 1000; + orig_node->last_valid) % 1000; seq_printf(seq, "%pM %4i.%03is (%3i) %pM [%10s]:", orig_node->orig, last_seen_secs, diff --git a/trunk/net/batman-adv/originator.h b/trunk/net/batman-adv/originator.h index f74d0d693359..3fe2eda85652 100644 --- a/trunk/net/batman-adv/originator.h +++ b/trunk/net/batman-adv/originator.h @@ -29,9 +29,10 @@ void originator_free(struct bat_priv *bat_priv); void purge_orig_ref(struct bat_priv *bat_priv); void orig_node_free_ref(struct orig_node *orig_node); struct orig_node *get_orig_node(struct bat_priv *bat_priv, const uint8_t *addr); -struct neigh_node *batadv_neigh_node_new(struct hard_iface *hard_iface, - const uint8_t *neigh_addr, - uint32_t seqno); +struct neigh_node *create_neighbor(struct orig_node *orig_node, + struct orig_node *orig_neigh_node, + const uint8_t *neigh, + struct hard_iface *if_incoming); void neigh_node_free_ref(struct neigh_node *neigh_node); struct neigh_node *orig_node_get_router(struct orig_node *orig_node); int orig_seq_print_text(struct seq_file *seq, void *offset); diff --git a/trunk/net/batman-adv/packet.h b/trunk/net/batman-adv/packet.h index 0ee1af770798..f54969c61a1e 100644 --- a/trunk/net/batman-adv/packet.h +++ b/trunk/net/batman-adv/packet.h @@ -39,7 +39,6 @@ enum bat_packettype { #define COMPAT_VERSION 14 enum batman_iv_flags { - NOT_BEST_NEXT_HOP = 1 << 3, PRIMARIES_FIRST_HOP = 1 << 4, VIS_SERVER = 1 << 5, DIRECTLINK = 1 << 6 diff --git a/trunk/net/batman-adv/routing.c b/trunk/net/batman-adv/routing.c index 840e2c64a301..ff560863bc74 100644 --- a/trunk/net/batman-adv/routing.c +++ b/trunk/net/batman-adv/routing.c @@ -234,46 +234,51 @@ int window_protected(struct bat_priv *bat_priv, int32_t seq_num_diff, { if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) { - if (!has_timed_out(*last_reset, RESET_PROTECTION_MS)) - return 1; + if (has_timed_out(*last_reset, RESET_PROTECTION_MS)) { - *last_reset = jiffies; - bat_dbg(DBG_BATMAN, bat_priv, - "old packet received, start protection\n"); - } + *last_reset = jiffies; + bat_dbg(DBG_BATMAN, bat_priv, + "old packet received, start protection\n"); + return 0; + } else { + return 1; + } + } return 0; } -bool check_management_packet(struct sk_buff *skb, - struct hard_iface *hard_iface, - int header_len) +int recv_bat_ogm_packet(struct sk_buff *skb, struct hard_iface *hard_iface) { + struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct ethhdr *ethhdr; /* drop packet if it has not necessary minimum size */ - if (unlikely(!pskb_may_pull(skb, header_len))) - return false; + if (unlikely(!pskb_may_pull(skb, BATMAN_OGM_HLEN))) + return NET_RX_DROP; ethhdr = (struct ethhdr *)skb_mac_header(skb); /* packet with broadcast indication but unicast recipient */ if (!is_broadcast_ether_addr(ethhdr->h_dest)) - return false; + return NET_RX_DROP; /* packet with broadcast sender address */ if (is_broadcast_ether_addr(ethhdr->h_source)) - return false; + return NET_RX_DROP; /* create a copy of the skb, if needed, to modify it. */ if (skb_cow(skb, 0) < 0) - return false; + return NET_RX_DROP; /* keep skb linear */ if (skb_linearize(skb) < 0) - return false; + return NET_RX_DROP; - return true; + bat_priv->bat_algo_ops->bat_ogm_receive(hard_iface, skb); + + kfree_skb(skb); + return NET_RX_SUCCESS; } static int recv_my_icmp_packet(struct bat_priv *bat_priv, @@ -913,20 +918,12 @@ static int check_unicast_ttvn(struct bat_priv *bat_priv, /* Check whether I have to reroute the packet */ if (seq_before(unicast_packet->ttvn, curr_ttvn) || tt_poss_change) { - /* check if there is enough data before accessing it */ - if (pskb_may_pull(skb, sizeof(struct unicast_packet) + - ETH_HLEN) < 0) + /* Linearize the skb before accessing it */ + if (skb_linearize(skb) < 0) return 0; ethhdr = (struct ethhdr *)(skb->data + sizeof(struct unicast_packet)); - - /* we don't have an updated route for this client, so we should - * not try to reroute the packet!! - */ - if (tt_global_client_is_roaming(bat_priv, ethhdr->h_dest)) - return 1; - orig_node = transtable_search(bat_priv, NULL, ethhdr->h_dest); if (!orig_node) { diff --git a/trunk/net/batman-adv/routing.h b/trunk/net/batman-adv/routing.h index d6bbbebb6567..3d729cb17113 100644 --- a/trunk/net/batman-adv/routing.h +++ b/trunk/net/batman-adv/routing.h @@ -23,9 +23,6 @@ #define _NET_BATMAN_ADV_ROUTING_H_ void slide_own_bcast_window(struct hard_iface *hard_iface); -bool check_management_packet(struct sk_buff *skb, - struct hard_iface *hard_iface, - int header_len); void update_route(struct bat_priv *bat_priv, struct orig_node *orig_node, struct neigh_node *neigh_node); int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if); @@ -33,6 +30,7 @@ int recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if); int recv_ucast_frag_packet(struct sk_buff *skb, struct hard_iface *recv_if); int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if); int recv_vis_packet(struct sk_buff *skb, struct hard_iface *recv_if); +int recv_bat_ogm_packet(struct sk_buff *skb, struct hard_iface *recv_if); int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if); int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if); struct neigh_node *find_router(struct bat_priv *bat_priv, diff --git a/trunk/net/batman-adv/send.c b/trunk/net/batman-adv/send.c index f47299f22c68..7c66b6121fa6 100644 --- a/trunk/net/batman-adv/send.c +++ b/trunk/net/batman-adv/send.c @@ -45,8 +45,8 @@ int send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface, goto send_skb_err; if (!(hard_iface->net_dev->flags & IFF_UP)) { - pr_warn("Interface %s is not up - can't send packet via that interface!\n", - hard_iface->net_dev->name); + pr_warning("Interface %s is not up - can't send packet via that interface!\n", + hard_iface->net_dev->name); goto send_skb_err; } @@ -292,7 +292,7 @@ static void send_outstanding_bcast_packet(struct work_struct *work) /* if we still have some more bcasts to send */ if (forw_packet->num_packets < 3) { _add_bcast_packet_to_list(bat_priv, forw_packet, - msecs_to_jiffies(5)); + ((5 * HZ) / 1000)); return; } diff --git a/trunk/net/batman-adv/translation-table.c b/trunk/net/batman-adv/translation-table.c index a66c2dcd1088..a38d315d3cd6 100644 --- a/trunk/net/batman-adv/translation-table.c +++ b/trunk/net/batman-adv/translation-table.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * - * Marek Lindner, Simon Wunderlich, Antonio Quartulli + * Marek Lindner, Simon Wunderlich * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -206,8 +206,6 @@ void tt_local_add(struct net_device *soft_iface, const uint8_t *addr, if (tt_local_entry) { tt_local_entry->last_seen = jiffies; - /* possibly unset the TT_CLIENT_PENDING flag */ - tt_local_entry->common.flags &= ~TT_CLIENT_PENDING; goto out; } @@ -2119,22 +2117,3 @@ void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node, } } } - -/* returns true whether we know that the client has moved from its old - * originator to another one. This entry is kept is still kept for consistency - * purposes - */ -bool tt_global_client_is_roaming(struct bat_priv *bat_priv, uint8_t *addr) -{ - struct tt_global_entry *tt_global_entry; - bool ret = false; - - tt_global_entry = tt_global_hash_find(bat_priv, addr); - if (!tt_global_entry) - goto out; - - ret = tt_global_entry->common.flags & TT_CLIENT_ROAM; - tt_global_entry_free_ref(tt_global_entry); -out: - return ret; -} diff --git a/trunk/net/batman-adv/translation-table.h b/trunk/net/batman-adv/translation-table.h index c43374dc364d..bfebe26edd8e 100644 --- a/trunk/net/batman-adv/translation-table.h +++ b/trunk/net/batman-adv/translation-table.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors: * - * Marek Lindner, Simon Wunderlich, Antonio Quartulli + * Marek Lindner, Simon Wunderlich * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -53,7 +53,5 @@ bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst); void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node, const unsigned char *tt_buff, uint8_t tt_num_changes, uint8_t ttvn, uint16_t tt_crc); -bool tt_global_client_is_roaming(struct bat_priv *bat_priv, uint8_t *addr); - #endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */ diff --git a/trunk/net/batman-adv/types.h b/trunk/net/batman-adv/types.h index 61308e8016ff..2f4848b776a7 100644 --- a/trunk/net/batman-adv/types.h +++ b/trunk/net/batman-adv/types.h @@ -52,7 +52,7 @@ struct hard_iface { /** * orig_node - structure for orig_list maintaining nodes of mesh * @primary_addr: hosts primary interface address - * @last_seen: when last packet from this node was received + * @last_valid: when last packet from this node was received * @bcast_seqno_reset: time when the broadcast seqno window was reset * @batman_seqno_reset: time when the batman seqno window was reset * @gw_flags: flags related to gateway class @@ -70,7 +70,7 @@ struct orig_node { struct neigh_node __rcu *router; /* rcu protected pointer */ unsigned long *bcast_own; uint8_t *bcast_own_sum; - unsigned long last_seen; + unsigned long last_valid; unsigned long bcast_seqno_reset; unsigned long batman_seqno_reset; uint8_t gw_flags; @@ -120,7 +120,7 @@ struct gw_node { /** * neigh_node - * @last_seen: when last packet via this neighbor was received + * @last_valid: when last packet via this neighbor was received */ struct neigh_node { struct hlist_node list; @@ -131,13 +131,13 @@ struct neigh_node { uint8_t tq_avg; uint8_t last_ttl; struct list_head bonding_list; - unsigned long last_seen; + unsigned long last_valid; DECLARE_BITMAP(real_bits, TQ_LOCAL_WINDOW_SIZE); atomic_t refcount; struct rcu_head rcu; struct orig_node *orig_node; struct hard_iface *if_incoming; - spinlock_t lq_update_lock; /* protects: tq_recv, tq_index */ + spinlock_t tq_lock; /* protects: tq_recv, tq_index */ }; #ifdef CONFIG_BATMAN_ADV_BLA @@ -381,17 +381,18 @@ struct bat_algo_ops { int (*bat_iface_enable)(struct hard_iface *hard_iface); /* de-init routing info when hard-interface is disabled */ void (*bat_iface_disable)(struct hard_iface *hard_iface); - /* (re-)init mac addresses of the protocol information - * belonging to this hard-interface - */ - void (*bat_iface_update_mac)(struct hard_iface *hard_iface); /* called when primary interface is selected / changed */ void (*bat_primary_iface_set)(struct hard_iface *hard_iface); + /* init mac addresses of the OGM belonging to this hard-interface */ + void (*bat_ogm_update_mac)(struct hard_iface *hard_iface); /* prepare a new outgoing OGM for the send queue */ void (*bat_ogm_schedule)(struct hard_iface *hard_iface, int tt_num_changes); /* send scheduled OGM */ void (*bat_ogm_emit)(struct forw_packet *forw_packet); + /* receive incoming OGM */ + void (*bat_ogm_receive)(struct hard_iface *if_incoming, + struct sk_buff *skb); }; #endif /* _NET_BATMAN_ADV_TYPES_H_ */ diff --git a/trunk/net/batman-adv/unicast.c b/trunk/net/batman-adv/unicast.c index 74175c210858..676f6a626b2c 100644 --- a/trunk/net/batman-adv/unicast.c +++ b/trunk/net/batman-adv/unicast.c @@ -331,14 +331,6 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) unicast_packet->ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn); - /* inform the destination node that we are still missing a correct route - * for this client. The destination will receive this packet and will - * try to reroute it because the ttvn contained in the header is less - * than the current one - */ - if (tt_global_client_is_roaming(bat_priv, ethhdr->h_dest)) - unicast_packet->ttvn = unicast_packet->ttvn - 1; - if (atomic_read(&bat_priv->fragmentation) && data_len + sizeof(*unicast_packet) > neigh_node->if_incoming->net_dev->mtu) { diff --git a/trunk/net/bluetooth/af_bluetooth.c b/trunk/net/bluetooth/af_bluetooth.c index 6fb68a9743af..72eb187a5f60 100644 --- a/trunk/net/bluetooth/af_bluetooth.c +++ b/trunk/net/bluetooth/af_bluetooth.c @@ -450,7 +450,7 @@ unsigned int bt_sock_poll(struct file *file, struct socket *sock, poll_table *wa sk->sk_state == BT_CONFIG) return mask; - if (!bt_sk(sk)->suspended && sock_writeable(sk)) + if (sock_writeable(sk)) mask |= POLLOUT | POLLWRNORM | POLLWRBAND; else set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); diff --git a/trunk/net/bluetooth/bnep/core.c b/trunk/net/bluetooth/bnep/core.c index 88884d1d95fd..a779ec703323 100644 --- a/trunk/net/bluetooth/bnep/core.c +++ b/trunk/net/bluetooth/bnep/core.c @@ -69,7 +69,7 @@ static struct bnep_session *__bnep_get_session(u8 *dst) BT_DBG(""); list_for_each_entry(s, &bnep_session_list, list) - if (ether_addr_equal(dst, s->eh.h_source)) + if (!compare_ether_addr(dst, s->eh.h_source)) return s; return NULL; @@ -422,10 +422,10 @@ static inline int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb) iv[il++] = (struct kvec) { &type, 1 }; len++; - if (compress_src && ether_addr_equal(eh->h_dest, s->eh.h_source)) + if (compress_src && !compare_ether_addr(eh->h_dest, s->eh.h_source)) type |= 0x01; - if (compress_dst && ether_addr_equal(eh->h_source, s->eh.h_dest)) + if (compress_dst && !compare_ether_addr(eh->h_source, s->eh.h_dest)) type |= 0x02; if (type) diff --git a/trunk/net/bluetooth/hci_core.c b/trunk/net/bluetooth/hci_core.c index d6dc44cd15b0..edfd61addcec 100644 --- a/trunk/net/bluetooth/hci_core.c +++ b/trunk/net/bluetooth/hci_core.c @@ -2784,14 +2784,6 @@ static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) if (conn) { hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); - hci_dev_lock(hdev); - if (test_bit(HCI_MGMT, &hdev->dev_flags) && - !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) - mgmt_device_connected(hdev, &conn->dst, conn->type, - conn->dst_type, 0, NULL, 0, - conn->dev_class); - hci_dev_unlock(hdev); - /* Send to upper protocol */ l2cap_recv_acldata(conn, skb, flags); return; diff --git a/trunk/net/bluetooth/hci_event.c b/trunk/net/bluetooth/hci_event.c index 1266f78fa8e3..6c065254afc0 100644 --- a/trunk/net/bluetooth/hci_event.c +++ b/trunk/net/bluetooth/hci_event.c @@ -2039,12 +2039,6 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff * clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); - if (ev->status && conn->state == BT_CONNECTED) { - hci_acl_disconn(conn, 0x13); - hci_conn_put(conn); - goto unlock; - } - if (conn->state == BT_CONFIG) { if (!ev->status) conn->state = BT_CONNECTED; @@ -2055,7 +2049,6 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff * hci_encrypt_cfm(conn, ev->status, ev->encrypt); } -unlock: hci_dev_unlock(hdev); } @@ -2109,7 +2102,7 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff goto unlock; } - if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) { + if (!ev->status) { struct hci_cp_remote_name_req cp; memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, &conn->dst); @@ -2878,7 +2871,7 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b if (conn->state != BT_CONFIG) goto unlock; - if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) { + if (!ev->status) { struct hci_cp_remote_name_req cp; memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, &conn->dst); diff --git a/trunk/net/bluetooth/l2cap_core.c b/trunk/net/bluetooth/l2cap_core.c index 6f9c25b633a6..94552b33d528 100644 --- a/trunk/net/bluetooth/l2cap_core.c +++ b/trunk/net/bluetooth/l2cap_core.c @@ -4589,11 +4589,6 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) if (!status && (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)) { - struct sock *sk = chan->sk; - - bt_sk(sk)->suspended = false; - sk->sk_state_change(sk); - l2cap_check_encryption(chan, encrypt); l2cap_chan_unlock(chan); continue; diff --git a/trunk/net/bluetooth/l2cap_sock.c b/trunk/net/bluetooth/l2cap_sock.c index 04e7c172d49c..29122ed28ea9 100644 --- a/trunk/net/bluetooth/l2cap_sock.c +++ b/trunk/net/bluetooth/l2cap_sock.c @@ -592,14 +592,10 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch sk->sk_state = BT_CONFIG; chan->state = BT_CONFIG; - /* or for ACL link */ - } else if ((sk->sk_state == BT_CONNECT2 && - bt_sk(sk)->defer_setup) || - sk->sk_state == BT_CONNECTED) { - if (!l2cap_chan_check_security(chan)) - bt_sk(sk)->suspended = true; - else - sk->sk_state_change(sk); + /* or for ACL link, under defer_setup time */ + } else if (sk->sk_state == BT_CONNECT2 && + bt_sk(sk)->defer_setup) { + err = l2cap_chan_check_security(chan); } else { err = -EINVAL; } diff --git a/trunk/net/bridge/br_device.c b/trunk/net/bridge/br_device.c index 929e48aed444..d6e5929458b1 100644 --- a/trunk/net/bridge/br_device.c +++ b/trunk/net/bridge/br_device.c @@ -170,7 +170,7 @@ static int br_set_mac_address(struct net_device *dev, void *p) return -EADDRNOTAVAIL; spin_lock_bh(&br->lock); - if (!ether_addr_equal(dev->dev_addr, addr->sa_data)) { + if (compare_ether_addr(dev->dev_addr, addr->sa_data)) { dev->addr_assign_type &= ~NET_ADDR_RANDOM; memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); br_fdb_change_mac_address(br, addr->sa_data); diff --git a/trunk/net/bridge/br_fdb.c b/trunk/net/bridge/br_fdb.c index d21f32383517..5945c54bc2de 100644 --- a/trunk/net/bridge/br_fdb.c +++ b/trunk/net/bridge/br_fdb.c @@ -107,8 +107,8 @@ void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr) struct net_bridge_port *op; list_for_each_entry(op, &br->port_list, list) { if (op != p && - ether_addr_equal(op->dev->dev_addr, - f->addr.addr)) { + !compare_ether_addr(op->dev->dev_addr, + f->addr.addr)) { f->dst = op; goto insert; } @@ -214,8 +214,8 @@ void br_fdb_delete_by_port(struct net_bridge *br, struct net_bridge_port *op; list_for_each_entry(op, &br->port_list, list) { if (op != p && - ether_addr_equal(op->dev->dev_addr, - f->addr.addr)) { + !compare_ether_addr(op->dev->dev_addr, + f->addr.addr)) { f->dst = op; goto skip_delete; } @@ -237,7 +237,7 @@ struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br, struct net_bridge_fdb_entry *fdb; hlist_for_each_entry_rcu(fdb, h, &br->hash[br_mac_hash(addr)], hlist) { - if (ether_addr_equal(fdb->addr.addr, addr)) { + if (!compare_ether_addr(fdb->addr.addr, addr)) { if (unlikely(has_expired(br, fdb))) break; return fdb; @@ -331,7 +331,7 @@ static struct net_bridge_fdb_entry *fdb_find(struct hlist_head *head, struct net_bridge_fdb_entry *fdb; hlist_for_each_entry(fdb, h, head, hlist) { - if (ether_addr_equal(fdb->addr.addr, addr)) + if (!compare_ether_addr(fdb->addr.addr, addr)) return fdb; } return NULL; @@ -344,7 +344,7 @@ static struct net_bridge_fdb_entry *fdb_find_rcu(struct hlist_head *head, struct net_bridge_fdb_entry *fdb; hlist_for_each_entry_rcu(fdb, h, head, hlist) { - if (ether_addr_equal(fdb->addr.addr, addr)) + if (!compare_ether_addr(fdb->addr.addr, addr)) return fdb; } return NULL; diff --git a/trunk/net/bridge/br_input.c b/trunk/net/bridge/br_input.c index 76f15fda0212..5a31731be4d0 100644 --- a/trunk/net/bridge/br_input.c +++ b/trunk/net/bridge/br_input.c @@ -216,7 +216,7 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb) } /* fall through */ case BR_STATE_LEARNING: - if (ether_addr_equal(p->br->dev->dev_addr, dest)) + if (!compare_ether_addr(p->br->dev->dev_addr, dest)) skb->pkt_type = PACKET_HOST; NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, diff --git a/trunk/net/bridge/br_multicast.c b/trunk/net/bridge/br_multicast.c index b66581208cb2..5ca4c50ea233 100644 --- a/trunk/net/bridge/br_multicast.c +++ b/trunk/net/bridge/br_multicast.c @@ -460,8 +460,8 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, hopopt[3] = 2; /* Length of RA Option */ hopopt[4] = 0; /* Type = 0x0000 (MLD) */ hopopt[5] = 0; - hopopt[6] = IPV6_TLV_PAD1; /* Pad1 */ - hopopt[7] = IPV6_TLV_PAD1; /* Pad1 */ + hopopt[6] = IPV6_TLV_PAD0; /* Pad0 */ + hopopt[7] = IPV6_TLV_PAD0; /* Pad0 */ skb_put(skb, sizeof(*ip6h) + 8); diff --git a/trunk/net/bridge/br_netfilter.c b/trunk/net/bridge/br_netfilter.c index e41456bd3cc6..dce55d4ee83b 100644 --- a/trunk/net/bridge/br_netfilter.c +++ b/trunk/net/bridge/br_netfilter.c @@ -558,7 +558,7 @@ static int check_hbh_len(struct sk_buff *skb) int optlen = nh[off + 1] + 2; switch (nh[off]) { - case IPV6_TLV_PAD1: + case IPV6_TLV_PAD0: optlen = 1; break; diff --git a/trunk/net/bridge/br_stp_bpdu.c b/trunk/net/bridge/br_stp_bpdu.c index fd30a6022dea..e16aade51ae0 100644 --- a/trunk/net/bridge/br_stp_bpdu.c +++ b/trunk/net/bridge/br_stp_bpdu.c @@ -167,7 +167,7 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb, if (p->state == BR_STATE_DISABLED) goto out; - if (!ether_addr_equal(dest, br->group_addr)) + if (compare_ether_addr(dest, br->group_addr) != 0) goto out; buf = skb_pull(skb, 3); diff --git a/trunk/net/bridge/br_stp_if.c b/trunk/net/bridge/br_stp_if.c index 9d5a414a3943..f494496373d6 100644 --- a/trunk/net/bridge/br_stp_if.c +++ b/trunk/net/bridge/br_stp_if.c @@ -178,7 +178,7 @@ void br_stp_set_enabled(struct net_bridge *br, unsigned long val) /* called under bridge lock */ void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr) { - /* should be aligned on 2 bytes for ether_addr_equal() */ + /* should be aligned on 2 bytes for compare_ether_addr() */ unsigned short oldaddr_aligned[ETH_ALEN >> 1]; unsigned char *oldaddr = (unsigned char *)oldaddr_aligned; struct net_bridge_port *p; @@ -191,11 +191,12 @@ void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr) memcpy(br->dev->dev_addr, addr, ETH_ALEN); list_for_each_entry(p, &br->port_list, list) { - if (ether_addr_equal(p->designated_bridge.addr, oldaddr)) + if (!compare_ether_addr(p->designated_bridge.addr, oldaddr)) memcpy(p->designated_bridge.addr, addr, ETH_ALEN); - if (ether_addr_equal(p->designated_root.addr, oldaddr)) + if (!compare_ether_addr(p->designated_root.addr, oldaddr)) memcpy(p->designated_root.addr, addr, ETH_ALEN); + } br_configuration_update(br); @@ -204,7 +205,7 @@ void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr) br_become_root_bridge(br); } -/* should be aligned on 2 bytes for ether_addr_equal() */ +/* should be aligned on 2 bytes for compare_ether_addr() */ static const unsigned short br_mac_zero_aligned[ETH_ALEN >> 1]; /* called under bridge lock */ @@ -226,7 +227,7 @@ bool br_stp_recalculate_bridge_id(struct net_bridge *br) } - if (ether_addr_equal(br->bridge_id.addr, addr)) + if (compare_ether_addr(br->bridge_id.addr, addr) == 0) return false; /* no change */ br_stp_change_bridge_id(br, addr); diff --git a/trunk/net/bridge/netfilter/ebt_stp.c b/trunk/net/bridge/netfilter/ebt_stp.c index 071d87214dde..5b33a2e634a6 100644 --- a/trunk/net/bridge/netfilter/ebt_stp.c +++ b/trunk/net/bridge/netfilter/ebt_stp.c @@ -164,8 +164,8 @@ static int ebt_stp_mt_check(const struct xt_mtchk_param *par) !(info->bitmask & EBT_STP_MASK)) return -EINVAL; /* Make sure the match only receives stp frames */ - if (!ether_addr_equal(e->destmac, bridge_ula) || - !ether_addr_equal(e->destmsk, msk) || !(e->bitmask & EBT_DESTMAC)) + if (compare_ether_addr(e->destmac, bridge_ula) || + compare_ether_addr(e->destmsk, msk) || !(e->bitmask & EBT_DESTMAC)) return -EINVAL; return 0; diff --git a/trunk/net/caif/caif_socket.c b/trunk/net/caif/caif_socket.c index fb8944355264..0dccdb3c7d26 100644 --- a/trunk/net/caif/caif_socket.c +++ b/trunk/net/caif/caif_socket.c @@ -131,9 +131,10 @@ static int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= (unsigned int)sk->sk_rcvbuf && rx_flow_is_on(cf_sk)) { - net_dbg_ratelimited("sending flow OFF (queue len = %d %d)\n", - atomic_read(&cf_sk->sk.sk_rmem_alloc), - sk_rcvbuf_lowwater(cf_sk)); + if (net_ratelimit()) + pr_debug("sending flow OFF (queue len = %d %d)\n", + atomic_read(&cf_sk->sk.sk_rmem_alloc), + sk_rcvbuf_lowwater(cf_sk)); set_rx_flow_off(cf_sk); caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ); } @@ -143,7 +144,8 @@ static int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) return err; if (!sk_rmem_schedule(sk, skb->truesize) && rx_flow_is_on(cf_sk)) { set_rx_flow_off(cf_sk); - net_dbg_ratelimited("sending flow OFF due to rmem_schedule\n"); + if (net_ratelimit()) + pr_debug("sending flow OFF due to rmem_schedule\n"); caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ); } skb->dev = NULL; diff --git a/trunk/net/compat.c b/trunk/net/compat.c index 1b96281892de..e240441a2317 100644 --- a/trunk/net/compat.c +++ b/trunk/net/compat.c @@ -328,6 +328,14 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm) __scm_destroy(scm); } +/* + * A struct sock_filter is architecture independent. + */ +struct compat_sock_fprog { + u16 len; + compat_uptr_t filter; /* struct sock_filter * */ +}; + static int do_set_attach_filter(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) { diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index cd0981977f5c..a2be59fe6ab8 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -300,9 +300,10 @@ static const unsigned short netdev_lock_type[] = ARPHRD_BIF, ARPHRD_SIT, ARPHRD_IPDDP, ARPHRD_IPGRE, ARPHRD_PIMREG, ARPHRD_HIPPI, ARPHRD_ASH, ARPHRD_ECONET, ARPHRD_IRDA, ARPHRD_FCPP, ARPHRD_FCAL, ARPHRD_FCPL, - ARPHRD_FCFABRIC, ARPHRD_IEEE80211, ARPHRD_IEEE80211_PRISM, - ARPHRD_IEEE80211_RADIOTAP, ARPHRD_PHONET, ARPHRD_PHONET_PIPE, - ARPHRD_IEEE802154, ARPHRD_VOID, ARPHRD_NONE}; + ARPHRD_FCFABRIC, ARPHRD_IEEE802_TR, ARPHRD_IEEE80211, + ARPHRD_IEEE80211_PRISM, ARPHRD_IEEE80211_RADIOTAP, ARPHRD_PHONET, + ARPHRD_PHONET_PIPE, ARPHRD_IEEE802154, + ARPHRD_VOID, ARPHRD_NONE}; static const char *const netdev_lock_name[] = {"_xmit_NETROM", "_xmit_ETHER", "_xmit_EETHER", "_xmit_AX25", @@ -317,9 +318,10 @@ static const char *const netdev_lock_name[] = "_xmit_BIF", "_xmit_SIT", "_xmit_IPDDP", "_xmit_IPGRE", "_xmit_PIMREG", "_xmit_HIPPI", "_xmit_ASH", "_xmit_ECONET", "_xmit_IRDA", "_xmit_FCPP", "_xmit_FCAL", "_xmit_FCPL", - "_xmit_FCFABRIC", "_xmit_IEEE80211", "_xmit_IEEE80211_PRISM", - "_xmit_IEEE80211_RADIOTAP", "_xmit_PHONET", "_xmit_PHONET_PIPE", - "_xmit_IEEE802154", "_xmit_VOID", "_xmit_NONE"}; + "_xmit_FCFABRIC", "_xmit_IEEE802_TR", "_xmit_IEEE80211", + "_xmit_IEEE80211_PRISM", "_xmit_IEEE80211_RADIOTAP", "_xmit_PHONET", + "_xmit_PHONET_PIPE", "_xmit_IEEE802154", + "_xmit_VOID", "_xmit_NONE"}; static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)]; static struct lock_class_key netdev_addr_lock_key[ARRAY_SIZE(netdev_lock_type)]; @@ -1616,14 +1618,10 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) return NET_RX_DROP; } skb->skb_iif = 0; - skb->dev = dev; - skb_dst_drop(skb); + skb_set_dev(skb, dev); skb->tstamp.tv64 = 0; skb->pkt_type = PACKET_HOST; skb->protocol = eth_type_trans(skb, dev); - skb->mark = 0; - secpath_reset(skb); - nf_reset(skb); return netif_rx(skb); } EXPORT_SYMBOL_GPL(dev_forward_skb); @@ -1675,9 +1673,10 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) if (skb_network_header(skb2) < skb2->data || skb2->network_header > skb2->tail) { - net_crit_ratelimited("protocol %04x is buggy, dev %s\n", - ntohs(skb2->protocol), - dev->name); + if (net_ratelimit()) + pr_crit("protocol %04x is buggy, dev %s\n", + ntohs(skb2->protocol), + dev->name); skb_reset_network_header(skb2); } @@ -1871,6 +1870,36 @@ void netif_device_attach(struct net_device *dev) } EXPORT_SYMBOL(netif_device_attach); +/** + * skb_dev_set -- assign a new device to a buffer + * @skb: buffer for the new device + * @dev: network device + * + * If an skb is owned by a device already, we have to reset + * all data private to the namespace a device belongs to + * before assigning it a new device. + */ +#ifdef CONFIG_NET_NS +void skb_set_dev(struct sk_buff *skb, struct net_device *dev) +{ + skb_dst_drop(skb); + if (skb->dev && !net_eq(dev_net(skb->dev), dev_net(dev))) { + secpath_reset(skb); + nf_reset(skb); + skb_init_secmark(skb); + skb->mark = 0; + skb->priority = 0; + skb->nf_trace = 0; + skb->ipvs_property = 0; +#ifdef CONFIG_NET_SCHED + skb->tc_index = 0; +#endif + } + skb->dev = dev; +} +EXPORT_SYMBOL(skb_set_dev); +#endif /* CONFIG_NET_NS */ + static void skb_warn_bad_offload(const struct sk_buff *skb) { static const netdev_features_t null_features = 0; @@ -2314,9 +2343,11 @@ EXPORT_SYMBOL(__skb_tx_hash); static inline u16 dev_cap_txqueue(struct net_device *dev, u16 queue_index) { if (unlikely(queue_index >= dev->real_num_tx_queues)) { - net_warn_ratelimited("%s selects TX queue %d, but real number of TX queues is %d\n", - dev->name, queue_index, - dev->real_num_tx_queues); + if (net_ratelimit()) { + pr_warn("%s selects TX queue %d, but real number of TX queues is %d\n", + dev->name, queue_index, + dev->real_num_tx_queues); + } return 0; } return queue_index; @@ -2558,15 +2589,17 @@ int dev_queue_xmit(struct sk_buff *skb) } } HARD_TX_UNLOCK(dev, txq); - net_crit_ratelimited("Virtual device %s asks to queue packet!\n", - dev->name); + if (net_ratelimit()) + pr_crit("Virtual device %s asks to queue packet!\n", + dev->name); } else { /* Recursion is detected! It is possible, * unfortunately */ recursion_alert: - net_crit_ratelimited("Dead loop on virtual device %s, fix it urgently!\n", - dev->name); + if (net_ratelimit()) + pr_crit("Dead loop on virtual device %s, fix it urgently!\n", + dev->name); } } @@ -3047,8 +3080,9 @@ static int ing_filter(struct sk_buff *skb, struct netdev_queue *rxq) struct Qdisc *q; if (unlikely(MAX_RED_LOOP < ttl++)) { - net_warn_ratelimited("Redir loop detected Dropping packet (%d->%d)\n", - skb->skb_iif, dev->ifindex); + if (net_ratelimit()) + pr_warn("Redir loop detected Dropping packet (%d->%d)\n", + skb->skb_iif, dev->ifindex); return TC_ACT_SHOT; } @@ -3602,7 +3636,7 @@ gro_result_t napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb, } EXPORT_SYMBOL(napi_frags_finish); -static struct sk_buff *napi_frags_skb(struct napi_struct *napi) +struct sk_buff *napi_frags_skb(struct napi_struct *napi) { struct sk_buff *skb = napi->skb; struct ethhdr *eth; @@ -3637,6 +3671,7 @@ static struct sk_buff *napi_frags_skb(struct napi_struct *napi) out: return skb; } +EXPORT_SYMBOL(napi_frags_skb); gro_result_t napi_gro_frags(struct napi_struct *napi) { diff --git a/trunk/net/core/drop_monitor.c b/trunk/net/core/drop_monitor.c index 3252e7e0a005..a7cad741df01 100644 --- a/trunk/net/core/drop_monitor.c +++ b/trunk/net/core/drop_monitor.c @@ -4,8 +4,6 @@ * Copyright (C) 2009 Neil Horman */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -24,7 +22,6 @@ #include #include #include -#include #include #include @@ -264,15 +261,9 @@ static int set_all_monitor_traces(int state) switch (state) { case TRACE_ON: - if (!try_module_get(THIS_MODULE)) { - rc = -ENODEV; - break; - } - rc |= register_trace_kfree_skb(trace_kfree_skb_hit, NULL); rc |= register_trace_napi_poll(trace_napi_poll_hit, NULL); break; - case TRACE_OFF: rc |= unregister_trace_kfree_skb(trace_kfree_skb_hit, NULL); rc |= unregister_trace_napi_poll(trace_napi_poll_hit, NULL); @@ -288,9 +279,6 @@ static int set_all_monitor_traces(int state) kfree_rcu(new_stat, rcu); } } - - module_put(THIS_MODULE); - break; default: rc = 1; @@ -393,10 +381,10 @@ static int __init init_net_drop_monitor(void) struct per_cpu_dm_data *data; int cpu, rc; - pr_info("Initializing network drop monitor service\n"); + printk(KERN_INFO "Initializing network drop monitor service\n"); if (sizeof(void *) > 8) { - pr_err("Unable to store program counters on this arch, Drop monitor failed\n"); + printk(KERN_ERR "Unable to store program counters on this arch, Drop monitor failed\n"); return -ENOSPC; } @@ -404,19 +392,19 @@ static int __init init_net_drop_monitor(void) dropmon_ops, ARRAY_SIZE(dropmon_ops)); if (rc) { - pr_err("Could not create drop monitor netlink family\n"); + printk(KERN_ERR "Could not create drop monitor netlink family\n"); return rc; } rc = register_netdevice_notifier(&dropmon_net_notifier); if (rc < 0) { - pr_crit("Failed to register netdevice notifier\n"); + printk(KERN_CRIT "Failed to register netdevice notifier\n"); goto out_unreg; } rc = 0; - for_each_possible_cpu(cpu) { + for_each_present_cpu(cpu) { data = &per_cpu(dm_cpu_data, cpu); data->cpu = cpu; INIT_WORK(&data->dm_alert_work, send_dm_alert); @@ -435,36 +423,4 @@ static int __init init_net_drop_monitor(void) return rc; } -static void exit_net_drop_monitor(void) -{ - struct per_cpu_dm_data *data; - int cpu; - - BUG_ON(unregister_netdevice_notifier(&dropmon_net_notifier)); - - /* - * Because of the module_get/put we do in the trace state change path - * we are guarnateed not to have any current users when we get here - * all we need to do is make sure that we don't have any running timers - * or pending schedule calls - */ - - for_each_possible_cpu(cpu) { - data = &per_cpu(dm_cpu_data, cpu); - del_timer_sync(&data->send_timer); - cancel_work_sync(&data->dm_alert_work); - /* - * At this point, we should have exclusive access - * to this struct and can free the skb inside it - */ - kfree_skb(data->skb); - } - - BUG_ON(genl_unregister_family(&net_drop_monitor_family)); -} - -module_init(init_net_drop_monitor); -module_exit(exit_net_drop_monitor); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Neil Horman "); +late_initcall(init_net_drop_monitor); diff --git a/trunk/net/core/ethtool.c b/trunk/net/core/ethtool.c index 9c2afb480270..beacdd93cd8f 100644 --- a/trunk/net/core/ethtool.c +++ b/trunk/net/core/ethtool.c @@ -751,17 +751,18 @@ static int ethtool_get_link(struct net_device *dev, char __user *useraddr) return 0; } -static int ethtool_get_any_eeprom(struct net_device *dev, void __user *useraddr, - int (*getter)(struct net_device *, - struct ethtool_eeprom *, u8 *), - u32 total_len) +static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr) { struct ethtool_eeprom eeprom; + const struct ethtool_ops *ops = dev->ethtool_ops; void __user *userbuf = useraddr + sizeof(eeprom); u32 bytes_remaining; u8 *data; int ret = 0; + if (!ops->get_eeprom || !ops->get_eeprom_len) + return -EOPNOTSUPP; + if (copy_from_user(&eeprom, useraddr, sizeof(eeprom))) return -EFAULT; @@ -770,7 +771,7 @@ static int ethtool_get_any_eeprom(struct net_device *dev, void __user *useraddr, return -EINVAL; /* Check for exceeding total eeprom len */ - if (eeprom.offset + eeprom.len > total_len) + if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev)) return -EINVAL; data = kmalloc(PAGE_SIZE, GFP_USER); @@ -781,7 +782,7 @@ static int ethtool_get_any_eeprom(struct net_device *dev, void __user *useraddr, while (bytes_remaining > 0) { eeprom.len = min(bytes_remaining, (u32)PAGE_SIZE); - ret = getter(dev, &eeprom, data); + ret = ops->get_eeprom(dev, &eeprom, data); if (ret) break; if (copy_to_user(userbuf, data, eeprom.len)) { @@ -802,17 +803,6 @@ static int ethtool_get_any_eeprom(struct net_device *dev, void __user *useraddr, return ret; } -static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr) -{ - const struct ethtool_ops *ops = dev->ethtool_ops; - - if (!ops->get_eeprom || !ops->get_eeprom_len) - return -EOPNOTSUPP; - - return ethtool_get_any_eeprom(dev, useraddr, ops->get_eeprom, - ops->get_eeprom_len(dev)); -} - static int ethtool_set_eeprom(struct net_device *dev, void __user *useraddr) { struct ethtool_eeprom eeprom; @@ -1335,47 +1325,6 @@ static int ethtool_get_ts_info(struct net_device *dev, void __user *useraddr) return err; } -static int ethtool_get_module_info(struct net_device *dev, - void __user *useraddr) -{ - int ret; - struct ethtool_modinfo modinfo; - const struct ethtool_ops *ops = dev->ethtool_ops; - - if (!ops->get_module_info) - return -EOPNOTSUPP; - - if (copy_from_user(&modinfo, useraddr, sizeof(modinfo))) - return -EFAULT; - - ret = ops->get_module_info(dev, &modinfo); - if (ret) - return ret; - - if (copy_to_user(useraddr, &modinfo, sizeof(modinfo))) - return -EFAULT; - - return 0; -} - -static int ethtool_get_module_eeprom(struct net_device *dev, - void __user *useraddr) -{ - int ret; - struct ethtool_modinfo modinfo; - const struct ethtool_ops *ops = dev->ethtool_ops; - - if (!ops->get_module_info || !ops->get_module_eeprom) - return -EOPNOTSUPP; - - ret = ops->get_module_info(dev, &modinfo); - if (ret) - return ret; - - return ethtool_get_any_eeprom(dev, useraddr, ops->get_module_eeprom, - modinfo.eeprom_len); -} - /* The main entry point in this file. Called from net/core/dev.c */ int dev_ethtool(struct net *net, struct ifreq *ifr) @@ -1600,12 +1549,6 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_GET_TS_INFO: rc = ethtool_get_ts_info(dev, useraddr); break; - case ETHTOOL_GMODULEINFO: - rc = ethtool_get_module_info(dev, useraddr); - break; - case ETHTOOL_GMODULEEEPROM: - rc = ethtool_get_module_eeprom(dev, useraddr); - break; default: rc = -EOPNOTSUPP; } diff --git a/trunk/net/core/filter.c b/trunk/net/core/filter.c index a3eddb515d1b..47a5f055e7f3 100644 --- a/trunk/net/core/filter.c +++ b/trunk/net/core/filter.c @@ -38,7 +38,6 @@ #include #include #include -#include /* No hurry in this branch * @@ -356,11 +355,6 @@ unsigned int sk_run_filter(const struct sk_buff *skb, A = 0; continue; } -#ifdef CONFIG_SECCOMP_FILTER - case BPF_S_ANC_SECCOMP_LD_W: - A = seccomp_bpf_load(fentry->k); - continue; -#endif default: WARN_RATELIMIT(1, "Unknown code:%u jt:%u tf:%u k:%u\n", fentry->code, fentry->jt, diff --git a/trunk/net/core/neighbour.c b/trunk/net/core/neighbour.c index eb09f8bbbf07..fadaa819b854 100644 --- a/trunk/net/core/neighbour.c +++ b/trunk/net/core/neighbour.c @@ -15,8 +15,6 @@ * Harald Welte Add neighbour cache statistics like rtstat */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -714,13 +712,14 @@ void neigh_destroy(struct neighbour *neigh) NEIGH_CACHE_STAT_INC(neigh->tbl, destroys); if (!neigh->dead) { - pr_warn("Destroying alive neighbour %p\n", neigh); + printk(KERN_WARNING + "Destroying alive neighbour %p\n", neigh); dump_stack(); return; } if (neigh_del_timer(neigh)) - pr_warn("Impossible event\n"); + printk(KERN_WARNING "Impossible event.\n"); skb_queue_purge(&neigh->arp_queue); neigh->arp_queue_len_bytes = 0; @@ -1555,8 +1554,8 @@ void neigh_table_init(struct neigh_table *tbl) write_unlock(&neigh_tbl_lock); if (unlikely(tmp)) { - pr_err("Registering multiple tables for family %d\n", - tbl->family); + printk(KERN_ERR "NEIGH: Registering multiple tables for " + "family %d\n", tbl->family); dump_stack(); } } @@ -1572,7 +1571,7 @@ int neigh_table_clear(struct neigh_table *tbl) pneigh_queue_purge(&tbl->proxy_queue); neigh_ifdown(tbl, NULL); if (atomic_read(&tbl->entries)) - pr_crit("neighbour leakage\n"); + printk(KERN_CRIT "neighbour leakage\n"); write_lock(&neigh_tbl_lock); for (tp = &neigh_tables; *tp; tp = &(*tp)->next) { if (*tp == tbl) { diff --git a/trunk/net/core/net_namespace.c b/trunk/net/core/net_namespace.c index dddbacb8f28c..31a5ae51a45c 100644 --- a/trunk/net/core/net_namespace.c +++ b/trunk/net/core/net_namespace.c @@ -1,5 +1,3 @@ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -214,8 +212,8 @@ static void net_free(struct net *net) { #ifdef NETNS_REFCNT_DEBUG if (unlikely(atomic_read(&net->use_count) != 0)) { - pr_emerg("network namespace not free! Usage: %d\n", - atomic_read(&net->use_count)); + printk(KERN_EMERG "network namespace not free! Usage: %d\n", + atomic_read(&net->use_count)); return; } #endif diff --git a/trunk/net/core/netprio_cgroup.c b/trunk/net/core/netprio_cgroup.c index 09eda68b6763..ba6900f73900 100644 --- a/trunk/net/core/netprio_cgroup.c +++ b/trunk/net/core/netprio_cgroup.c @@ -9,8 +9,6 @@ * Authors: Neil Horman */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -90,7 +88,7 @@ static void extend_netdev_table(struct net_device *dev, u32 new_len) old_priomap = rtnl_dereference(dev->priomap); if (!new_priomap) { - pr_warn("Unable to alloc new priomap!\n"); + printk(KERN_WARNING "Unable to alloc new priomap!\n"); return; } @@ -138,7 +136,7 @@ static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp) ret = get_prioidx(&cs->prioidx); if (ret != 0) { - pr_warn("No space in priority index array\n"); + printk(KERN_WARNING "No space in priority index array\n"); kfree(cs); return ERR_PTR(ret); } diff --git a/trunk/net/core/pktgen.c b/trunk/net/core/pktgen.c index cce9e53528b1..ffb5d382f241 100644 --- a/trunk/net/core/pktgen.c +++ b/trunk/net/core/pktgen.c @@ -891,8 +891,8 @@ static ssize_t pktgen_if_write(struct file *file, if (copy_from_user(tb, user_buffer, copy)) return -EFAULT; tb[copy] = 0; - pr_debug("%s,%lu buffer -:%s:-\n", - name, (unsigned long)count, tb); + printk(KERN_DEBUG "pktgen: %s,%lu buffer -:%s:-\n", name, + (unsigned long)count, tb); } if (!strcmp(name, "min_pkt_size")) { @@ -1261,7 +1261,8 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->cur_daddr = pkt_dev->daddr_min; } if (debug) - pr_debug("dst_min set to: %s\n", pkt_dev->dst_min); + printk(KERN_DEBUG "pktgen: dst_min set to: %s\n", + pkt_dev->dst_min); i += len; sprintf(pg_result, "OK: dst_min=%s", pkt_dev->dst_min); return count; @@ -1283,7 +1284,8 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->cur_daddr = pkt_dev->daddr_max; } if (debug) - pr_debug("dst_max set to: %s\n", pkt_dev->dst_max); + printk(KERN_DEBUG "pktgen: dst_max set to: %s\n", + pkt_dev->dst_max); i += len; sprintf(pg_result, "OK: dst_max=%s", pkt_dev->dst_max); return count; @@ -1305,7 +1307,7 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->cur_in6_daddr = pkt_dev->in6_daddr; if (debug) - pr_debug("dst6 set to: %s\n", buf); + printk(KERN_DEBUG "pktgen: dst6 set to: %s\n", buf); i += len; sprintf(pg_result, "OK: dst6=%s", buf); @@ -1327,7 +1329,7 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->cur_in6_daddr = pkt_dev->min_in6_daddr; if (debug) - pr_debug("dst6_min set to: %s\n", buf); + printk(KERN_DEBUG "pktgen: dst6_min set to: %s\n", buf); i += len; sprintf(pg_result, "OK: dst6_min=%s", buf); @@ -1348,7 +1350,7 @@ static ssize_t pktgen_if_write(struct file *file, snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->max_in6_daddr); if (debug) - pr_debug("dst6_max set to: %s\n", buf); + printk(KERN_DEBUG "pktgen: dst6_max set to: %s\n", buf); i += len; sprintf(pg_result, "OK: dst6_max=%s", buf); @@ -1371,7 +1373,7 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->cur_in6_saddr = pkt_dev->in6_saddr; if (debug) - pr_debug("src6 set to: %s\n", buf); + printk(KERN_DEBUG "pktgen: src6 set to: %s\n", buf); i += len; sprintf(pg_result, "OK: src6=%s", buf); @@ -1392,7 +1394,8 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->cur_saddr = pkt_dev->saddr_min; } if (debug) - pr_debug("src_min set to: %s\n", pkt_dev->src_min); + printk(KERN_DEBUG "pktgen: src_min set to: %s\n", + pkt_dev->src_min); i += len; sprintf(pg_result, "OK: src_min=%s", pkt_dev->src_min); return count; @@ -1412,7 +1415,8 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->cur_saddr = pkt_dev->saddr_max; } if (debug) - pr_debug("src_max set to: %s\n", pkt_dev->src_max); + printk(KERN_DEBUG "pktgen: src_max set to: %s\n", + pkt_dev->src_max); i += len; sprintf(pg_result, "OK: src_max=%s", pkt_dev->src_max); return count; @@ -1523,7 +1527,7 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->svlan_id = 0xffff; if (debug) - pr_debug("VLAN/SVLAN auto turned off\n"); + printk(KERN_DEBUG "pktgen: VLAN/SVLAN auto turned off\n"); } return count; } @@ -1538,10 +1542,10 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->vlan_id = value; /* turn on VLAN */ if (debug) - pr_debug("VLAN turned on\n"); + printk(KERN_DEBUG "pktgen: VLAN turned on\n"); if (debug && pkt_dev->nr_labels) - pr_debug("MPLS auto turned off\n"); + printk(KERN_DEBUG "pktgen: MPLS auto turned off\n"); pkt_dev->nr_labels = 0; /* turn off MPLS */ sprintf(pg_result, "OK: vlan_id=%u", pkt_dev->vlan_id); @@ -1550,7 +1554,7 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->svlan_id = 0xffff; if (debug) - pr_debug("VLAN/SVLAN turned off\n"); + printk(KERN_DEBUG "pktgen: VLAN/SVLAN turned off\n"); } return count; } @@ -1595,10 +1599,10 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->svlan_id = value; /* turn on SVLAN */ if (debug) - pr_debug("SVLAN turned on\n"); + printk(KERN_DEBUG "pktgen: SVLAN turned on\n"); if (debug && pkt_dev->nr_labels) - pr_debug("MPLS auto turned off\n"); + printk(KERN_DEBUG "pktgen: MPLS auto turned off\n"); pkt_dev->nr_labels = 0; /* turn off MPLS */ sprintf(pg_result, "OK: svlan_id=%u", pkt_dev->svlan_id); @@ -1607,7 +1611,7 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->svlan_id = 0xffff; if (debug) - pr_debug("VLAN/SVLAN turned off\n"); + printk(KERN_DEBUG "pktgen: VLAN/SVLAN turned off\n"); } return count; } @@ -1775,7 +1779,8 @@ static ssize_t pktgen_thread_write(struct file *file, i += len; if (debug) - pr_debug("t=%s, count=%lu\n", name, (unsigned long)count); + printk(KERN_DEBUG "pktgen: t=%s, count=%lu\n", + name, (unsigned long)count); if (!t) { pr_err("ERROR: No thread\n"); @@ -1926,7 +1931,7 @@ static int pktgen_device_event(struct notifier_block *unused, { struct net_device *dev = ptr; - if (!net_eq(dev_net(dev), &init_net) || pktgen_exiting) + if (!net_eq(dev_net(dev), &init_net)) return NOTIFY_DONE; /* It is OK that we do not hold the group lock right now, @@ -2929,7 +2934,8 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, if (datalen < sizeof(struct pktgen_hdr)) { datalen = sizeof(struct pktgen_hdr); - net_info_ratelimited("increased datalen to %d\n", datalen); + if (net_ratelimit()) + pr_info("increased datalen to %d\n", datalen); } udph->source = htons(pkt_dev->cur_udp_src); @@ -3359,8 +3365,8 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev) pkt_dev->errors++; break; default: /* Drivers are not supposed to return other values! */ - net_info_ratelimited("%s xmit error: %d\n", - pkt_dev->odevname, ret); + if (net_ratelimit()) + pr_info("%s xmit error: %d\n", pkt_dev->odevname, ret); pkt_dev->errors++; /* fallthru */ case NETDEV_TX_LOCKED: @@ -3749,18 +3755,12 @@ static void __exit pg_cleanup(void) { struct pktgen_thread *t; struct list_head *q, *n; - LIST_HEAD(list); /* Stop all interfaces & threads */ pktgen_exiting = true; - mutex_lock(&pktgen_thread_lock); - list_splice_init(&pktgen_threads, &list); - mutex_unlock(&pktgen_thread_lock); - - list_for_each_safe(q, n, &list) { + list_for_each_safe(q, n, &pktgen_threads) { t = list_entry(q, struct pktgen_thread, th_list); - list_del(&t->th_list); kthread_stop(t->tsk); kfree(t); } diff --git a/trunk/net/core/rtnetlink.c b/trunk/net/core/rtnetlink.c index 21318d15bbc3..b442d35bbc8b 100644 --- a/trunk/net/core/rtnetlink.c +++ b/trunk/net/core/rtnetlink.c @@ -1524,9 +1524,11 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, err = 0; errout: - if (err < 0 && modified) - net_warn_ratelimited("A link change request failed with some changes committed already. Interface %s may have been left with an inconsistent configuration, please check.\n", - dev->name); + if (err < 0 && modified && net_ratelimit()) + printk(KERN_WARNING "A link change request failed with " + "some changes committed already. Interface %s may " + "have been left with an inconsistent configuration, " + "please check.\n", dev->name); if (send_addr_notify) call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); diff --git a/trunk/net/core/skbuff.c b/trunk/net/core/skbuff.c index 016694d62484..2c35da818ef9 100644 --- a/trunk/net/core/skbuff.c +++ b/trunk/net/core/skbuff.c @@ -36,8 +36,6 @@ * The functions in this file will not compile correctly with gcc 2.4.x */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -120,10 +118,11 @@ static const struct pipe_buf_operations sock_pipe_buf_ops = { */ static void skb_over_panic(struct sk_buff *skb, int sz, void *here) { - pr_emerg("%s: text:%p len:%d put:%d head:%p data:%p tail:%#lx end:%#lx dev:%s\n", - __func__, here, skb->len, sz, skb->head, skb->data, - (unsigned long)skb->tail, (unsigned long)skb->end, - skb->dev ? skb->dev->name : ""); + printk(KERN_EMERG "skb_over_panic: text:%p len:%d put:%d head:%p " + "data:%p tail:%#lx end:%#lx dev:%s\n", + here, skb->len, sz, skb->head, skb->data, + (unsigned long)skb->tail, (unsigned long)skb->end, + skb->dev ? skb->dev->name : ""); BUG(); } @@ -138,10 +137,11 @@ static void skb_over_panic(struct sk_buff *skb, int sz, void *here) static void skb_under_panic(struct sk_buff *skb, int sz, void *here) { - pr_emerg("%s: text:%p len:%d put:%d head:%p data:%p tail:%#lx end:%#lx dev:%s\n", - __func__, here, skb->len, sz, skb->head, skb->data, - (unsigned long)skb->tail, (unsigned long)skb->end, - skb->dev ? skb->dev->name : ""); + printk(KERN_EMERG "skb_under_panic: text:%p len:%d put:%d head:%p " + "data:%p tail:%#lx end:%#lx dev:%s\n", + here, skb->len, sz, skb->head, skb->data, + (unsigned long)skb->tail, (unsigned long)skb->end, + skb->dev ? skb->dev->name : ""); BUG(); } @@ -293,46 +293,6 @@ struct sk_buff *build_skb(void *data, unsigned int frag_size) } EXPORT_SYMBOL(build_skb); -struct netdev_alloc_cache { - struct page *page; - unsigned int offset; -}; -static DEFINE_PER_CPU(struct netdev_alloc_cache, netdev_alloc_cache); - -/** - * netdev_alloc_frag - allocate a page fragment - * @fragsz: fragment size - * - * Allocates a frag from a page for receive buffer. - * Uses GFP_ATOMIC allocations. - */ -void *netdev_alloc_frag(unsigned int fragsz) -{ - struct netdev_alloc_cache *nc; - void *data = NULL; - unsigned long flags; - - local_irq_save(flags); - nc = &__get_cpu_var(netdev_alloc_cache); - if (unlikely(!nc->page)) { -refill: - nc->page = alloc_page(GFP_ATOMIC | __GFP_COLD); - nc->offset = 0; - } - if (likely(nc->page)) { - if (nc->offset + fragsz > PAGE_SIZE) { - put_page(nc->page); - goto refill; - } - data = page_address(nc->page) + nc->offset; - nc->offset += fragsz; - get_page(nc->page); - } - local_irq_restore(flags); - return data; -} -EXPORT_SYMBOL(netdev_alloc_frag); - /** * __netdev_alloc_skb - allocate an skbuff for rx on a specific device * @dev: network device to receive on @@ -347,23 +307,11 @@ EXPORT_SYMBOL(netdev_alloc_frag); * %NULL is returned if there is no free memory. */ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, - unsigned int length, gfp_t gfp_mask) + unsigned int length, gfp_t gfp_mask) { - struct sk_buff *skb = NULL; - unsigned int fragsz = SKB_DATA_ALIGN(length + NET_SKB_PAD) + - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); - - if (fragsz <= PAGE_SIZE && !(gfp_mask & __GFP_WAIT)) { - void *data = netdev_alloc_frag(fragsz); + struct sk_buff *skb; - if (likely(data)) { - skb = build_skb(data, fragsz); - if (unlikely(!skb)) - put_page(virt_to_head_page(data)); - } - } else { - skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, NUMA_NO_NODE); - } + skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, NUMA_NO_NODE); if (likely(skb)) { skb_reserve(skb, NET_SKB_PAD); skb->dev = dev; @@ -382,6 +330,28 @@ void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off, } EXPORT_SYMBOL(skb_add_rx_frag); +/** + * dev_alloc_skb - allocate an skbuff for receiving + * @length: length to allocate + * + * Allocate a new &sk_buff and assign it a usage count of one. The + * buffer has unspecified headroom built in. Users should allocate + * the headroom they think they need without accounting for the + * built in space. The built in space is used for optimisations. + * + * %NULL is returned if there is no free memory. Although this function + * allocates memory it can be called from an interrupt. + */ +struct sk_buff *dev_alloc_skb(unsigned int length) +{ + /* + * There is more code here than it seems: + * __dev_alloc_skb is an inline + */ + return __dev_alloc_skb(length, GFP_ATOMIC); +} +EXPORT_SYMBOL(dev_alloc_skb); + static void skb_drop_list(struct sk_buff **listp) { struct sk_buff *list = *listp; @@ -3329,8 +3299,10 @@ bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off) { if (unlikely(start > skb_headlen(skb)) || unlikely((int)start + off > skb_headlen(skb) - 2)) { - net_warn_ratelimited("bad partial csum: csum=%u/%u len=%u\n", - start, off, skb_headlen(skb)); + if (net_ratelimit()) + printk(KERN_WARNING + "bad partial csum: csum=%u/%u len=%u\n", + start, off, skb_headlen(skb)); return false; } skb->ip_summed = CHECKSUM_PARTIAL; @@ -3342,93 +3314,8 @@ EXPORT_SYMBOL_GPL(skb_partial_csum_set); void __skb_warn_lro_forwarding(const struct sk_buff *skb) { - net_warn_ratelimited("%s: received packets cannot be forwarded while LRO is enabled\n", - skb->dev->name); + if (net_ratelimit()) + pr_warning("%s: received packets cannot be forwarded" + " while LRO is enabled\n", skb->dev->name); } EXPORT_SYMBOL(__skb_warn_lro_forwarding); - -void kfree_skb_partial(struct sk_buff *skb, bool head_stolen) -{ - if (head_stolen) - kmem_cache_free(skbuff_head_cache, skb); - else - __kfree_skb(skb); -} -EXPORT_SYMBOL(kfree_skb_partial); - -/** - * skb_try_coalesce - try to merge skb to prior one - * @to: prior buffer - * @from: buffer to add - * @fragstolen: pointer to boolean - * - */ -bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, - bool *fragstolen, int *delta_truesize) -{ - int i, delta, len = from->len; - - *fragstolen = false; - - if (skb_cloned(to)) - return false; - - if (len <= skb_tailroom(to)) { - BUG_ON(skb_copy_bits(from, 0, skb_put(to, len), len)); - *delta_truesize = 0; - return true; - } - - if (skb_has_frag_list(to) || skb_has_frag_list(from)) - return false; - - if (skb_headlen(from) != 0) { - struct page *page; - unsigned int offset; - - if (skb_shinfo(to)->nr_frags + - skb_shinfo(from)->nr_frags >= MAX_SKB_FRAGS) - return false; - - if (skb_head_is_locked(from)) - return false; - - delta = from->truesize - SKB_DATA_ALIGN(sizeof(struct sk_buff)); - - page = virt_to_head_page(from->head); - offset = from->data - (unsigned char *)page_address(page); - - skb_fill_page_desc(to, skb_shinfo(to)->nr_frags, - page, offset, skb_headlen(from)); - *fragstolen = true; - } else { - if (skb_shinfo(to)->nr_frags + - skb_shinfo(from)->nr_frags > MAX_SKB_FRAGS) - return false; - - delta = from->truesize - - SKB_TRUESIZE(skb_end_pointer(from) - from->head); - } - - WARN_ON_ONCE(delta < len); - - memcpy(skb_shinfo(to)->frags + skb_shinfo(to)->nr_frags, - skb_shinfo(from)->frags, - skb_shinfo(from)->nr_frags * sizeof(skb_frag_t)); - skb_shinfo(to)->nr_frags += skb_shinfo(from)->nr_frags; - - if (!skb_cloned(from)) - skb_shinfo(from)->nr_frags = 0; - - /* if the skb is cloned this does nothing since we set nr_frags to 0 */ - for (i = 0; i < skb_shinfo(from)->nr_frags; i++) - skb_frag_ref(from, i); - - to->truesize += delta; - to->len += len; - to->data_len += len; - - *delta_truesize = delta; - return true; -} -EXPORT_SYMBOL(skb_try_coalesce); diff --git a/trunk/net/core/sock.c b/trunk/net/core/sock.c index 5efcd6307fa7..26ed27fb2bfb 100644 --- a/trunk/net/core/sock.c +++ b/trunk/net/core/sock.c @@ -89,8 +89,6 @@ * 2 of the License, or (at your option) any later version. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -299,8 +297,9 @@ static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen) *timeo_p = 0; if (warned < 10 && net_ratelimit()) { warned++; - pr_info("%s: `%s' (pid %d) tries to set negative timeout\n", - __func__, current->comm, task_pid_nr(current)); + printk(KERN_INFO "sock_set_timeout: `%s' (pid %d) " + "tries to set negative timeout\n", + current->comm, task_pid_nr(current)); } return 0; } @@ -318,8 +317,8 @@ static void sock_warn_obsolete_bsdism(const char *name) static char warncomm[TASK_COMM_LEN]; if (strcmp(warncomm, current->comm) && warned < 5) { strcpy(warncomm, current->comm); - pr_warn("process `%s' is using obsolete %s SO_BSDCOMPAT\n", - warncomm, name); + printk(KERN_WARNING "process `%s' is using obsolete " + "%s SO_BSDCOMPAT\n", warncomm, name); warned++; } } @@ -850,7 +849,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, break; case SO_BROADCAST: - v.val = sock_flag(sk, SOCK_BROADCAST); + v.val = !!sock_flag(sk, SOCK_BROADCAST); break; case SO_SNDBUF: @@ -866,7 +865,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, break; case SO_KEEPALIVE: - v.val = sock_flag(sk, SOCK_KEEPOPEN); + v.val = !!sock_flag(sk, SOCK_KEEPOPEN); break; case SO_TYPE: @@ -888,7 +887,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, break; case SO_OOBINLINE: - v.val = sock_flag(sk, SOCK_URGINLINE); + v.val = !!sock_flag(sk, SOCK_URGINLINE); break; case SO_NO_CHECK: @@ -901,7 +900,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, case SO_LINGER: lv = sizeof(v.ling); - v.ling.l_onoff = sock_flag(sk, SOCK_LINGER); + v.ling.l_onoff = !!sock_flag(sk, SOCK_LINGER); v.ling.l_linger = sk->sk_lingertime / HZ; break; @@ -1013,11 +1012,11 @@ int sock_getsockopt(struct socket *sock, int level, int optname, break; case SO_RXQ_OVFL: - v.val = sock_flag(sk, SOCK_RXQ_OVFL); + v.val = !!sock_flag(sk, SOCK_RXQ_OVFL); break; case SO_WIFI_STATUS: - v.val = sock_flag(sk, SOCK_WIFI_STATUS); + v.val = !!sock_flag(sk, SOCK_WIFI_STATUS); break; case SO_PEEK_OFF: @@ -1027,7 +1026,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, v.val = sk->sk_peek_off; break; case SO_NOFCS: - v.val = sock_flag(sk, SOCK_NOFCS); + v.val = !!sock_flag(sk, SOCK_NOFCS); break; default: return -ENOPROTOOPT; @@ -1239,8 +1238,8 @@ static void __sk_free(struct sock *sk) sock_disable_timestamp(sk, SK_FLAGS_TIMESTAMP); if (atomic_read(&sk->sk_omem_alloc)) - pr_debug("%s: optmem leakage (%d bytes) detected\n", - __func__, atomic_read(&sk->sk_omem_alloc)); + printk(KERN_DEBUG "%s: optmem leakage (%d bytes) detected.\n", + __func__, atomic_read(&sk->sk_omem_alloc)); if (sk->sk_peer_cred) put_cred(sk->sk_peer_cred); @@ -2425,7 +2424,7 @@ static void assign_proto_idx(struct proto *prot) prot->inuse_idx = find_first_zero_bit(proto_inuse_idx, PROTO_INUSE_NR); if (unlikely(prot->inuse_idx == PROTO_INUSE_NR - 1)) { - pr_err("PROTO_INUSE_NR exhausted\n"); + printk(KERN_ERR "PROTO_INUSE_NR exhausted\n"); return; } @@ -2455,8 +2454,8 @@ int proto_register(struct proto *prot, int alloc_slab) NULL); if (prot->slab == NULL) { - pr_crit("%s: Can't create sock SLAB cache!\n", - prot->name); + printk(KERN_CRIT "%s: Can't create sock SLAB cache!\n", + prot->name); goto out; } @@ -2470,8 +2469,8 @@ int proto_register(struct proto *prot, int alloc_slab) SLAB_HWCACHE_ALIGN, NULL); if (prot->rsk_prot->slab == NULL) { - pr_crit("%s: Can't create request sock SLAB cache!\n", - prot->name); + printk(KERN_CRIT "%s: Can't create request sock SLAB cache!\n", + prot->name); goto out_free_request_sock_slab_name; } } diff --git a/trunk/net/dccp/proto.c b/trunk/net/dccp/proto.c index 6c7c78b83940..7065c0ae1e7b 100644 --- a/trunk/net/dccp/proto.c +++ b/trunk/net/dccp/proto.c @@ -848,7 +848,7 @@ int dccp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, default: dccp_pr_debug("packet_type=%s\n", dccp_packet_name(dh->dccph_type)); - sk_eat_skb(sk, skb, false); + sk_eat_skb(sk, skb, 0); } verify_sock_status: if (sock_flag(sk, SOCK_DONE)) { @@ -905,7 +905,7 @@ int dccp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, len = skb->len; found_fin_ok: if (!(flags & MSG_PEEK)) - sk_eat_skb(sk, skb, false); + sk_eat_skb(sk, skb, 0); break; } while (1); out: diff --git a/trunk/net/decnet/dn_fib.c b/trunk/net/decnet/dn_fib.c index 7eaf98799729..65a8cd7891fe 100644 --- a/trunk/net/decnet/dn_fib.c +++ b/trunk/net/decnet/dn_fib.c @@ -438,8 +438,9 @@ int dn_fib_semantic_match(int type, struct dn_fib_info *fi, const struct flowidn res->fi = NULL; return 1; default: - net_err_ratelimited("DECnet: impossible routing event : dn_fib_semantic_match type=%d\n", - type); + if (net_ratelimit()) + printk("DECnet: impossible routing event : dn_fib_semantic_match type=%d\n", + type); res->fi = NULL; return -EINVAL; } diff --git a/trunk/net/decnet/dn_neigh.c b/trunk/net/decnet/dn_neigh.c index ac90f658586c..ee7013f24fca 100644 --- a/trunk/net/decnet/dn_neigh.c +++ b/trunk/net/decnet/dn_neigh.c @@ -162,8 +162,8 @@ static int dn_neigh_construct(struct neighbour *neigh) else if ((dev->type == ARPHRD_ETHER) || (dev->type == ARPHRD_LOOPBACK)) dn_dn2eth(neigh->ha, dn->addr); else { - net_dbg_ratelimited("Trying to create neigh for hw %d\n", - dev->type); + if (net_ratelimit()) + printk(KERN_DEBUG "Trying to create neigh for hw %d\n", dev->type); return -EINVAL; } @@ -236,13 +236,15 @@ static int dn_long_output(struct neighbour *neigh, struct sk_buff *skb) if (skb_headroom(skb) < headroom) { struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom); if (skb2 == NULL) { - net_crit_ratelimited("dn_long_output: no memory\n"); + if (net_ratelimit()) + printk(KERN_CRIT "dn_long_output: no memory\n"); kfree_skb(skb); return -ENOBUFS; } kfree_skb(skb); skb = skb2; - net_info_ratelimited("dn_long_output: Increasing headroom\n"); + if (net_ratelimit()) + printk(KERN_INFO "dn_long_output: Increasing headroom\n"); } data = skb_push(skb, sizeof(struct dn_long_packet) + 3); @@ -279,13 +281,15 @@ static int dn_short_output(struct neighbour *neigh, struct sk_buff *skb) if (skb_headroom(skb) < headroom) { struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom); if (skb2 == NULL) { - net_crit_ratelimited("dn_short_output: no memory\n"); + if (net_ratelimit()) + printk(KERN_CRIT "dn_short_output: no memory\n"); kfree_skb(skb); return -ENOBUFS; } kfree_skb(skb); skb = skb2; - net_info_ratelimited("dn_short_output: Increasing headroom\n"); + if (net_ratelimit()) + printk(KERN_INFO "dn_short_output: Increasing headroom\n"); } data = skb_push(skb, sizeof(struct dn_short_packet) + 2); @@ -318,13 +322,15 @@ static int dn_phase3_output(struct neighbour *neigh, struct sk_buff *skb) if (skb_headroom(skb) < headroom) { struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom); if (skb2 == NULL) { - net_crit_ratelimited("dn_phase3_output: no memory\n"); + if (net_ratelimit()) + printk(KERN_CRIT "dn_phase3_output: no memory\n"); kfree_skb(skb); return -ENOBUFS; } kfree_skb(skb); skb = skb2; - net_info_ratelimited("dn_phase3_output: Increasing headroom\n"); + if (net_ratelimit()) + printk(KERN_INFO "dn_phase3_output: Increasing headroom\n"); } data = skb_push(skb, sizeof(struct dn_short_packet) + 2); diff --git a/trunk/net/decnet/dn_nsp_in.c b/trunk/net/decnet/dn_nsp_in.c index c344163e6ac0..58084f37151e 100644 --- a/trunk/net/decnet/dn_nsp_in.c +++ b/trunk/net/decnet/dn_nsp_in.c @@ -80,15 +80,12 @@ extern int decnet_log_martians; static void dn_log_martian(struct sk_buff *skb, const char *msg) { - if (decnet_log_martians) { + if (decnet_log_martians && net_ratelimit()) { char *devname = skb->dev ? skb->dev->name : "???"; struct dn_skb_cb *cb = DN_SKB_CB(skb); - net_info_ratelimited("DECnet: Martian packet (%s) dev=%s src=0x%04hx dst=0x%04hx srcport=0x%04hx dstport=0x%04hx\n", - msg, devname, - le16_to_cpu(cb->src), - le16_to_cpu(cb->dst), - le16_to_cpu(cb->src_port), - le16_to_cpu(cb->dst_port)); + printk(KERN_INFO "DECnet: Martian packet (%s) dev=%s src=0x%04hx dst=0x%04hx srcport=0x%04hx dstport=0x%04hx\n", + msg, devname, le16_to_cpu(cb->src), le16_to_cpu(cb->dst), + le16_to_cpu(cb->src_port), le16_to_cpu(cb->dst_port)); } } diff --git a/trunk/net/decnet/dn_nsp_out.c b/trunk/net/decnet/dn_nsp_out.c index 564a6ad13ce7..b952f88d9c1f 100644 --- a/trunk/net/decnet/dn_nsp_out.c +++ b/trunk/net/decnet/dn_nsp_out.c @@ -1,3 +1,4 @@ + /* * DECnet An implementation of the DECnet protocol suite for the LINUX * operating system. DECnet is implemented using the BSD Socket @@ -553,8 +554,8 @@ static __inline__ void dn_nsp_do_disc(struct sock *sk, unsigned char msgflg, unsigned char *msg; if ((dst == NULL) || (rem == 0)) { - net_dbg_ratelimited("DECnet: dn_nsp_do_disc: BUG! Please report this to SteveW@ACM.org rem=%u dst=%p\n", - le16_to_cpu(rem), dst); + if (net_ratelimit()) + printk(KERN_DEBUG "DECnet: dn_nsp_do_disc: BUG! Please report this to SteveW@ACM.org rem=%u dst=%p\n", le16_to_cpu(rem), dst); return; } diff --git a/trunk/net/decnet/dn_route.c b/trunk/net/decnet/dn_route.c index 586302e557ad..7e1f8788da19 100644 --- a/trunk/net/decnet/dn_route.c +++ b/trunk/net/decnet/dn_route.c @@ -748,7 +748,8 @@ static int dn_output(struct sk_buff *skb) dn_to_neigh_output); error: - net_dbg_ratelimited("dn_output: This should not happen\n"); + if (net_ratelimit()) + printk(KERN_DEBUG "dn_output: This should not happen\n"); kfree_skb(skb); @@ -806,10 +807,12 @@ static int dn_forward(struct sk_buff *skb) */ static int dn_rt_bug(struct sk_buff *skb) { - struct dn_skb_cb *cb = DN_SKB_CB(skb); + if (net_ratelimit()) { + struct dn_skb_cb *cb = DN_SKB_CB(skb); - net_dbg_ratelimited("dn_rt_bug: skb from:%04x to:%04x\n", - le16_to_cpu(cb->src), le16_to_cpu(cb->dst)); + printk(KERN_DEBUG "dn_rt_bug: skb from:%04x to:%04x\n", + le16_to_cpu(cb->src), le16_to_cpu(cb->dst)); + } kfree_skb(skb); @@ -1324,7 +1327,9 @@ static int dn_route_input_slow(struct sk_buff *skb) out_dev = DN_FIB_RES_DEV(res); if (out_dev == NULL) { - net_crit_ratelimited("Bug in dn_route_input_slow() No output device\n"); + if (net_ratelimit()) + printk(KERN_CRIT "Bug in dn_route_input_slow() " + "No output device\n"); goto e_inval; } dev_hold(out_dev); diff --git a/trunk/net/decnet/dn_table.c b/trunk/net/decnet/dn_table.c index 650f3380c98a..a9a62f225a6b 100644 --- a/trunk/net/decnet/dn_table.c +++ b/trunk/net/decnet/dn_table.c @@ -836,8 +836,8 @@ struct dn_fib_table *dn_fib_get_table(u32 n, int create) if (!create) return NULL; - if (in_interrupt()) { - net_dbg_ratelimited("DECnet: BUG! Attempt to create routing table from interrupt\n"); + if (in_interrupt() && net_ratelimit()) { + printk(KERN_DEBUG "DECnet: BUG! Attempt to create routing table from interrupt\n"); return NULL; } diff --git a/trunk/net/decnet/netfilter/dn_rtmsg.c b/trunk/net/decnet/netfilter/dn_rtmsg.c index 44b890936fc0..1531135130db 100644 --- a/trunk/net/decnet/netfilter/dn_rtmsg.c +++ b/trunk/net/decnet/netfilter/dn_rtmsg.c @@ -57,7 +57,8 @@ static struct sk_buff *dnrmg_build_message(struct sk_buff *rt_skb, int *errp) if (skb) kfree_skb(skb); *errp = -ENOMEM; - net_err_ratelimited("dn_rtmsg: error creating netlink message\n"); + if (net_ratelimit()) + printk(KERN_ERR "dn_rtmsg: error creating netlink message\n"); return NULL; } diff --git a/trunk/net/dns_resolver/dns_key.c b/trunk/net/dns_resolver/dns_key.c index d9507dd05818..6f70ea935b0b 100644 --- a/trunk/net/dns_resolver/dns_key.c +++ b/trunk/net/dns_resolver/dns_key.c @@ -249,6 +249,9 @@ static int __init init_dns_resolver(void) struct key *keyring; int ret; + printk(KERN_NOTICE "Registering the %s key type\n", + key_type_dns_resolver.name); + /* create an override credential set with a special thread keyring in * which DNS requests are cached * @@ -298,6 +301,8 @@ static void __exit exit_dns_resolver(void) key_revoke(dns_resolver_cache->thread_keyring); unregister_key_type(&key_type_dns_resolver); put_cred(dns_resolver_cache); + printk(KERN_NOTICE "Unregistered %s key type\n", + key_type_dns_resolver.name); } module_init(init_dns_resolver) diff --git a/trunk/net/dsa/slave.c b/trunk/net/dsa/slave.c index e32083d5d8f8..56cf9b8e1c7c 100644 --- a/trunk/net/dsa/slave.c +++ b/trunk/net/dsa/slave.c @@ -66,7 +66,7 @@ static int dsa_slave_open(struct net_device *dev) if (!(master->flags & IFF_UP)) return -ENETDOWN; - if (!ether_addr_equal(dev->dev_addr, master->dev_addr)) { + if (compare_ether_addr(dev->dev_addr, master->dev_addr)) { err = dev_uc_add(master, dev->dev_addr); if (err < 0) goto out; @@ -89,7 +89,7 @@ static int dsa_slave_open(struct net_device *dev) if (dev->flags & IFF_ALLMULTI) dev_set_allmulti(master, -1); del_unicast: - if (!ether_addr_equal(dev->dev_addr, master->dev_addr)) + if (compare_ether_addr(dev->dev_addr, master->dev_addr)) dev_uc_del(master, dev->dev_addr); out: return err; @@ -107,7 +107,7 @@ static int dsa_slave_close(struct net_device *dev) if (dev->flags & IFF_PROMISC) dev_set_promiscuity(master, -1); - if (!ether_addr_equal(dev->dev_addr, master->dev_addr)) + if (compare_ether_addr(dev->dev_addr, master->dev_addr)) dev_uc_del(master, dev->dev_addr); return 0; @@ -146,13 +146,13 @@ static int dsa_slave_set_mac_address(struct net_device *dev, void *a) if (!(dev->flags & IFF_UP)) goto out; - if (!ether_addr_equal(addr->sa_data, master->dev_addr)) { + if (compare_ether_addr(addr->sa_data, master->dev_addr)) { err = dev_uc_add(master, addr->sa_data); if (err < 0) return err; } - if (!ether_addr_equal(dev->dev_addr, master->dev_addr)) + if (compare_ether_addr(dev->dev_addr, master->dev_addr)) dev_uc_del(master, dev->dev_addr); out: diff --git a/trunk/net/econet/Kconfig b/trunk/net/econet/Kconfig new file mode 100644 index 000000000000..39a2d2975e0e --- /dev/null +++ b/trunk/net/econet/Kconfig @@ -0,0 +1,36 @@ +# +# Acorn Econet/AUN protocols +# + +config ECONET + tristate "Acorn Econet/AUN protocols (EXPERIMENTAL)" + depends on EXPERIMENTAL && INET + ---help--- + Econet is a fairly old and slow networking protocol mainly used by + Acorn computers to access file and print servers. It uses native + Econet network cards. AUN is an implementation of the higher level + parts of Econet that runs over ordinary Ethernet connections, on + top of the UDP packet protocol, which in turn runs on top of the + Internet protocol IP. + + If you say Y here, you can choose with the next two options whether + to send Econet/AUN traffic over a UDP Ethernet connection or over + a native Econet network card. + + To compile this driver as a module, choose M here: the module + will be called econet. + +config ECONET_AUNUDP + bool "AUN over UDP" + depends on ECONET + help + Say Y here if you want to send Econet/AUN traffic over a UDP + connection (UDP is a packet based protocol that runs on top of the + Internet protocol IP) using an ordinary Ethernet network card. + +config ECONET_NATIVE + bool "Native Econet" + depends on ECONET + help + Say Y here if you have a native Econet network card installed in + your computer. diff --git a/trunk/net/econet/Makefile b/trunk/net/econet/Makefile new file mode 100644 index 000000000000..05fae8be2fed --- /dev/null +++ b/trunk/net/econet/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for Econet support code. +# + +obj-$(CONFIG_ECONET) += econet.o + +econet-y := af_econet.o diff --git a/trunk/net/econet/af_econet.c b/trunk/net/econet/af_econet.c new file mode 100644 index 000000000000..fa14ca76b77b --- /dev/null +++ b/trunk/net/econet/af_econet.c @@ -0,0 +1,1172 @@ +/* + * An implementation of the Acorn Econet and AUN protocols. + * Philip Blundell + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#define pr_fmt(fmt) fmt + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static const struct proto_ops econet_ops; +static struct hlist_head econet_sklist; +static DEFINE_SPINLOCK(econet_lock); +static DEFINE_MUTEX(econet_mutex); + +/* Since there are only 256 possible network numbers (or fewer, depends + how you count) it makes sense to use a simple lookup table. */ +static struct net_device *net2dev_map[256]; + +#define EC_PORT_IP 0xd2 + +#ifdef CONFIG_ECONET_AUNUDP +static DEFINE_SPINLOCK(aun_queue_lock); +static struct socket *udpsock; +#define AUN_PORT 0x8000 + +struct aunhdr { + unsigned char code; /* AUN magic protocol byte */ + unsigned char port; + unsigned char cb; + unsigned char pad; + unsigned long handle; +}; + +static unsigned long aun_seq; + +/* Queue of packets waiting to be transmitted. */ +static struct sk_buff_head aun_queue; +static struct timer_list ab_cleanup_timer; + +#endif /* CONFIG_ECONET_AUNUDP */ + +/* Per-packet information */ +struct ec_cb { + struct sockaddr_ec sec; + unsigned long cookie; /* Supplied by user. */ +#ifdef CONFIG_ECONET_AUNUDP + int done; + unsigned long seq; /* Sequencing */ + unsigned long timeout; /* Timeout */ + unsigned long start; /* jiffies */ +#endif +#ifdef CONFIG_ECONET_NATIVE + void (*sent)(struct sk_buff *, int result); +#endif +}; + +static void econet_remove_socket(struct hlist_head *list, struct sock *sk) +{ + spin_lock_bh(&econet_lock); + sk_del_node_init(sk); + spin_unlock_bh(&econet_lock); +} + +static void econet_insert_socket(struct hlist_head *list, struct sock *sk) +{ + spin_lock_bh(&econet_lock); + sk_add_node(sk, list); + spin_unlock_bh(&econet_lock); +} + +/* + * Pull a packet from our receive queue and hand it to the user. + * If necessary we block. + */ + +static int econet_recvmsg(struct kiocb *iocb, struct socket *sock, + struct msghdr *msg, size_t len, int flags) +{ + struct sock *sk = sock->sk; + struct sk_buff *skb; + size_t copied; + int err; + + msg->msg_namelen = sizeof(struct sockaddr_ec); + + mutex_lock(&econet_mutex); + + /* + * Call the generic datagram receiver. This handles all sorts + * of horrible races and re-entrancy so we can forget about it + * in the protocol layers. + * + * Now it will return ENETDOWN, if device have just gone down, + * but then it will block. + */ + + skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err); + + /* + * An error occurred so return it. Because skb_recv_datagram() + * handles the blocking we don't see and worry about blocking + * retries. + */ + + if (skb == NULL) + goto out; + + /* + * You lose any data beyond the buffer you gave. If it worries a + * user program they can ask the device for its MTU anyway. + */ + + copied = skb->len; + if (copied > len) { + copied = len; + msg->msg_flags |= MSG_TRUNC; + } + + /* We can't use skb_copy_datagram here */ + err = memcpy_toiovec(msg->msg_iov, skb->data, copied); + if (err) + goto out_free; + sk->sk_stamp = skb->tstamp; + + if (msg->msg_name) + memcpy(msg->msg_name, skb->cb, msg->msg_namelen); + + /* + * Free or return the buffer as appropriate. Again this + * hides all the races and re-entrancy issues from us. + */ + err = copied; + +out_free: + skb_free_datagram(sk, skb); +out: + mutex_unlock(&econet_mutex); + return err; +} + +/* + * Bind an Econet socket. + */ + +static int econet_bind(struct socket *sock, struct sockaddr *uaddr, + int addr_len) +{ + struct sockaddr_ec *sec = (struct sockaddr_ec *)uaddr; + struct sock *sk; + struct econet_sock *eo; + + /* + * Check legality + */ + + if (addr_len < sizeof(struct sockaddr_ec) || + sec->sec_family != AF_ECONET) + return -EINVAL; + + mutex_lock(&econet_mutex); + + sk = sock->sk; + eo = ec_sk(sk); + + eo->cb = sec->cb; + eo->port = sec->port; + eo->station = sec->addr.station; + eo->net = sec->addr.net; + + mutex_unlock(&econet_mutex); + + return 0; +} + +#if defined(CONFIG_ECONET_AUNUDP) || defined(CONFIG_ECONET_NATIVE) +/* + * Queue a transmit result for the user to be told about. + */ + +static void tx_result(struct sock *sk, unsigned long cookie, int result) +{ + struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC); + struct ec_cb *eb; + struct sockaddr_ec *sec; + + if (skb == NULL) { + pr_debug("econet: memory squeeze, transmit result dropped\n"); + return; + } + + eb = (struct ec_cb *)&skb->cb; + sec = (struct sockaddr_ec *)&eb->sec; + memset(sec, 0, sizeof(struct sockaddr_ec)); + sec->cookie = cookie; + sec->type = ECTYPE_TRANSMIT_STATUS | result; + sec->sec_family = AF_ECONET; + + if (sock_queue_rcv_skb(sk, skb) < 0) + kfree_skb(skb); +} +#endif + +#ifdef CONFIG_ECONET_NATIVE +/* + * Called by the Econet hardware driver when a packet transmit + * has completed. Tell the user. + */ + +static void ec_tx_done(struct sk_buff *skb, int result) +{ + struct ec_cb *eb = (struct ec_cb *)&skb->cb; + tx_result(skb->sk, eb->cookie, result); +} +#endif + +/* + * Send a packet. We have to work out which device it's going out on + * and hence whether to use real Econet or the UDP emulation. + */ + +static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, + struct msghdr *msg, size_t len) +{ + struct sockaddr_ec *saddr = (struct sockaddr_ec *)msg->msg_name; + struct net_device *dev; + struct ec_addr addr; + int err; + unsigned char port, cb; +#if defined(CONFIG_ECONET_AUNUDP) || defined(CONFIG_ECONET_NATIVE) + struct sock *sk = sock->sk; + struct sk_buff *skb; + struct ec_cb *eb; +#endif +#ifdef CONFIG_ECONET_AUNUDP + struct msghdr udpmsg; + struct iovec iov[2]; + struct aunhdr ah; + struct sockaddr_in udpdest; + __kernel_size_t size; + mm_segment_t oldfs; + char *userbuf; +#endif + + /* + * Check the flags. + */ + + if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) + return -EINVAL; + + /* + * Get and verify the address. + */ + + mutex_lock(&econet_mutex); + + if (saddr == NULL || msg->msg_namelen < sizeof(struct sockaddr_ec)) { + mutex_unlock(&econet_mutex); + return -EINVAL; + } + addr.station = saddr->addr.station; + addr.net = saddr->addr.net; + port = saddr->port; + cb = saddr->cb; + + /* Look for a device with the right network number. */ + dev = net2dev_map[addr.net]; + + /* If not directly reachable, use some default */ + if (dev == NULL) { + dev = net2dev_map[0]; + /* No interfaces at all? */ + if (dev == NULL) { + mutex_unlock(&econet_mutex); + return -ENETDOWN; + } + } + + if (dev->type == ARPHRD_ECONET) { + /* Real hardware Econet. We're not worthy etc. */ +#ifdef CONFIG_ECONET_NATIVE + unsigned short proto = 0; + int hlen, tlen; + int res; + + if (len + 15 > dev->mtu) { + mutex_unlock(&econet_mutex); + return -EMSGSIZE; + } + + dev_hold(dev); + + hlen = LL_RESERVED_SPACE(dev); + tlen = dev->needed_tailroom; + skb = sock_alloc_send_skb(sk, len + hlen + tlen, + msg->msg_flags & MSG_DONTWAIT, &err); + if (skb == NULL) + goto out_unlock; + + skb_reserve(skb, hlen); + skb_reset_network_header(skb); + + eb = (struct ec_cb *)&skb->cb; + + eb->cookie = saddr->cookie; + eb->sec = *saddr; + eb->sent = ec_tx_done; + + err = -EINVAL; + res = dev_hard_header(skb, dev, ntohs(proto), &addr, NULL, len); + if (res < 0) + goto out_free; + if (res > 0) { + struct ec_framehdr *fh; + /* Poke in our control byte and + port number. Hack, hack. */ + fh = (struct ec_framehdr *)skb->data; + fh->cb = cb; + fh->port = port; + if (sock->type != SOCK_DGRAM) { + skb_reset_tail_pointer(skb); + skb->len = 0; + } + } + + /* Copy the data. Returns -EFAULT on error */ + err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); + skb->protocol = proto; + skb->dev = dev; + skb->priority = sk->sk_priority; + if (err) + goto out_free; + + err = -ENETDOWN; + if (!(dev->flags & IFF_UP)) + goto out_free; + + /* + * Now send it + */ + + dev_queue_xmit(skb); + dev_put(dev); + mutex_unlock(&econet_mutex); + return len; + +out_free: + kfree_skb(skb); +out_unlock: + if (dev) + dev_put(dev); +#else + err = -EPROTOTYPE; +#endif + mutex_unlock(&econet_mutex); + + return err; + } + +#ifdef CONFIG_ECONET_AUNUDP + /* AUN virtual Econet. */ + + if (udpsock == NULL) { + mutex_unlock(&econet_mutex); + return -ENETDOWN; /* No socket - can't send */ + } + + if (len > 32768) { + err = -E2BIG; + goto error; + } + + /* Make up a UDP datagram and hand it off to some higher intellect. */ + + memset(&udpdest, 0, sizeof(udpdest)); + udpdest.sin_family = AF_INET; + udpdest.sin_port = htons(AUN_PORT); + + /* At the moment we use the stupid Acorn scheme of Econet address + y.x maps to IP a.b.c.x. This should be replaced with something + more flexible and more aware of subnet masks. */ + { + struct in_device *idev; + unsigned long network = 0; + + rcu_read_lock(); + idev = __in_dev_get_rcu(dev); + if (idev) { + if (idev->ifa_list) + network = ntohl(idev->ifa_list->ifa_address) & + 0xffffff00; /* !!! */ + } + rcu_read_unlock(); + udpdest.sin_addr.s_addr = htonl(network | addr.station); + } + + memset(&ah, 0, sizeof(ah)); + ah.port = port; + ah.cb = cb & 0x7f; + ah.code = 2; /* magic */ + + /* tack our header on the front of the iovec */ + size = sizeof(struct aunhdr); + iov[0].iov_base = (void *)&ah; + iov[0].iov_len = size; + + userbuf = vmalloc(len); + if (userbuf == NULL) { + err = -ENOMEM; + goto error; + } + + iov[1].iov_base = userbuf; + iov[1].iov_len = len; + err = memcpy_fromiovec(userbuf, msg->msg_iov, len); + if (err) + goto error_free_buf; + + /* Get a skbuff (no data, just holds our cb information) */ + skb = sock_alloc_send_skb(sk, 0, msg->msg_flags & MSG_DONTWAIT, &err); + if (skb == NULL) + goto error_free_buf; + + eb = (struct ec_cb *)&skb->cb; + + eb->cookie = saddr->cookie; + eb->timeout = 5 * HZ; + eb->start = jiffies; + ah.handle = aun_seq; + eb->seq = (aun_seq++); + eb->sec = *saddr; + + skb_queue_tail(&aun_queue, skb); + + udpmsg.msg_name = (void *)&udpdest; + udpmsg.msg_namelen = sizeof(udpdest); + udpmsg.msg_iov = &iov[0]; + udpmsg.msg_iovlen = 2; + udpmsg.msg_control = NULL; + udpmsg.msg_controllen = 0; + udpmsg.msg_flags = 0; + + oldfs = get_fs(); + set_fs(KERNEL_DS); /* More privs :-) */ + err = sock_sendmsg(udpsock, &udpmsg, size); + set_fs(oldfs); + +error_free_buf: + vfree(userbuf); +error: +#else + err = -EPROTOTYPE; +#endif + mutex_unlock(&econet_mutex); + + return err; +} + +/* + * Look up the address of a socket. + */ + +static int econet_getname(struct socket *sock, struct sockaddr *uaddr, + int *uaddr_len, int peer) +{ + struct sock *sk; + struct econet_sock *eo; + struct sockaddr_ec *sec = (struct sockaddr_ec *)uaddr; + + if (peer) + return -EOPNOTSUPP; + + memset(sec, 0, sizeof(*sec)); + mutex_lock(&econet_mutex); + + sk = sock->sk; + eo = ec_sk(sk); + + sec->sec_family = AF_ECONET; + sec->port = eo->port; + sec->addr.station = eo->station; + sec->addr.net = eo->net; + + mutex_unlock(&econet_mutex); + + *uaddr_len = sizeof(*sec); + return 0; +} + +static void econet_destroy_timer(unsigned long data) +{ + struct sock *sk = (struct sock *)data; + + if (!sk_has_allocations(sk)) { + sk_free(sk); + return; + } + + sk->sk_timer.expires = jiffies + 10 * HZ; + add_timer(&sk->sk_timer); + pr_debug("econet: socket destroy delayed\n"); +} + +/* + * Close an econet socket. + */ + +static int econet_release(struct socket *sock) +{ + struct sock *sk; + + mutex_lock(&econet_mutex); + + sk = sock->sk; + if (!sk) + goto out_unlock; + + econet_remove_socket(&econet_sklist, sk); + + /* + * Now the socket is dead. No more input will appear. + */ + + sk->sk_state_change(sk); /* It is useless. Just for sanity. */ + + sock_orphan(sk); + + /* Purge queues */ + + skb_queue_purge(&sk->sk_receive_queue); + + if (sk_has_allocations(sk)) { + sk->sk_timer.data = (unsigned long)sk; + sk->sk_timer.expires = jiffies + HZ; + sk->sk_timer.function = econet_destroy_timer; + add_timer(&sk->sk_timer); + + goto out_unlock; + } + + sk_free(sk); + +out_unlock: + mutex_unlock(&econet_mutex); + return 0; +} + +static struct proto econet_proto = { + .name = "ECONET", + .owner = THIS_MODULE, + .obj_size = sizeof(struct econet_sock), +}; + +/* + * Create an Econet socket + */ + +static int econet_create(struct net *net, struct socket *sock, int protocol, + int kern) +{ + struct sock *sk; + struct econet_sock *eo; + int err; + + if (!net_eq(net, &init_net)) + return -EAFNOSUPPORT; + + /* Econet only provides datagram services. */ + if (sock->type != SOCK_DGRAM) + return -ESOCKTNOSUPPORT; + + sock->state = SS_UNCONNECTED; + + err = -ENOBUFS; + sk = sk_alloc(net, PF_ECONET, GFP_KERNEL, &econet_proto); + if (sk == NULL) + goto out; + + sk->sk_reuse = SK_CAN_REUSE; + sock->ops = &econet_ops; + sock_init_data(sock, sk); + + eo = ec_sk(sk); + sock_reset_flag(sk, SOCK_ZAPPED); + sk->sk_family = PF_ECONET; + eo->num = protocol; + + econet_insert_socket(&econet_sklist, sk); + return 0; +out: + return err; +} + +/* + * Handle Econet specific ioctls + */ + +static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg) +{ + struct ifreq ifr; + struct ec_device *edev; + struct net_device *dev; + struct sockaddr_ec *sec; + int err; + + /* + * Fetch the caller's info block into kernel space + */ + + if (copy_from_user(&ifr, arg, sizeof(struct ifreq))) + return -EFAULT; + + dev = dev_get_by_name(&init_net, ifr.ifr_name); + if (dev == NULL) + return -ENODEV; + + sec = (struct sockaddr_ec *)&ifr.ifr_addr; + + mutex_lock(&econet_mutex); + + err = 0; + switch (cmd) { + case SIOCSIFADDR: + if (!capable(CAP_NET_ADMIN)) { + err = -EPERM; + break; + } + + edev = dev->ec_ptr; + if (edev == NULL) { + /* Magic up a new one. */ + edev = kzalloc(sizeof(struct ec_device), GFP_KERNEL); + if (edev == NULL) { + err = -ENOMEM; + break; + } + dev->ec_ptr = edev; + } else + net2dev_map[edev->net] = NULL; + edev->station = sec->addr.station; + edev->net = sec->addr.net; + net2dev_map[sec->addr.net] = dev; + if (!net2dev_map[0]) + net2dev_map[0] = dev; + break; + + case SIOCGIFADDR: + edev = dev->ec_ptr; + if (edev == NULL) { + err = -ENODEV; + break; + } + memset(sec, 0, sizeof(struct sockaddr_ec)); + sec->addr.station = edev->station; + sec->addr.net = edev->net; + sec->sec_family = AF_ECONET; + dev_put(dev); + if (copy_to_user(arg, &ifr, sizeof(struct ifreq))) + err = -EFAULT; + break; + + default: + err = -EINVAL; + break; + } + + mutex_unlock(&econet_mutex); + + dev_put(dev); + + return err; +} + +/* + * Handle generic ioctls + */ + +static int econet_ioctl(struct socket *sock, unsigned int cmd, + unsigned long arg) +{ + struct sock *sk = sock->sk; + void __user *argp = (void __user *)arg; + + switch (cmd) { + case SIOCGSTAMP: + return sock_get_timestamp(sk, argp); + + case SIOCGSTAMPNS: + return sock_get_timestampns(sk, argp); + + case SIOCSIFADDR: + case SIOCGIFADDR: + return ec_dev_ioctl(sock, cmd, argp); + + } + + return -ENOIOCTLCMD; +} + +static const struct net_proto_family econet_family_ops = { + .family = PF_ECONET, + .create = econet_create, + .owner = THIS_MODULE, +}; + +static const struct proto_ops econet_ops = { + .family = PF_ECONET, + .owner = THIS_MODULE, + .release = econet_release, + .bind = econet_bind, + .connect = sock_no_connect, + .socketpair = sock_no_socketpair, + .accept = sock_no_accept, + .getname = econet_getname, + .poll = datagram_poll, + .ioctl = econet_ioctl, + .listen = sock_no_listen, + .shutdown = sock_no_shutdown, + .setsockopt = sock_no_setsockopt, + .getsockopt = sock_no_getsockopt, + .sendmsg = econet_sendmsg, + .recvmsg = econet_recvmsg, + .mmap = sock_no_mmap, + .sendpage = sock_no_sendpage, +}; + +#if defined(CONFIG_ECONET_AUNUDP) || defined(CONFIG_ECONET_NATIVE) +/* + * Find the listening socket, if any, for the given data. + */ + +static struct sock *ec_listening_socket(unsigned char port, unsigned char + station, unsigned char net) +{ + struct sock *sk; + struct hlist_node *node; + + spin_lock(&econet_lock); + sk_for_each(sk, node, &econet_sklist) { + struct econet_sock *opt = ec_sk(sk); + if ((opt->port == port || opt->port == 0) && + (opt->station == station || opt->station == 0) && + (opt->net == net || opt->net == 0)) { + sock_hold(sk); + goto found; + } + } + sk = NULL; +found: + spin_unlock(&econet_lock); + return sk; +} + +/* + * Queue a received packet for a socket. + */ + +static int ec_queue_packet(struct sock *sk, struct sk_buff *skb, + unsigned char stn, unsigned char net, + unsigned char cb, unsigned char port) +{ + struct ec_cb *eb = (struct ec_cb *)&skb->cb; + struct sockaddr_ec *sec = (struct sockaddr_ec *)&eb->sec; + + memset(sec, 0, sizeof(struct sockaddr_ec)); + sec->sec_family = AF_ECONET; + sec->type = ECTYPE_PACKET_RECEIVED; + sec->port = port; + sec->cb = cb; + sec->addr.net = net; + sec->addr.station = stn; + + return sock_queue_rcv_skb(sk, skb); +} +#endif + +#ifdef CONFIG_ECONET_AUNUDP +/* + * Send an AUN protocol response. + */ + +static void aun_send_response(__u32 addr, unsigned long seq, int code, int cb) +{ + struct sockaddr_in sin = { + .sin_family = AF_INET, + .sin_port = htons(AUN_PORT), + .sin_addr = {.s_addr = addr} + }; + struct aunhdr ah = {.code = code, .cb = cb, .handle = seq}; + struct kvec iov = {.iov_base = (void *)&ah, .iov_len = sizeof(ah)}; + struct msghdr udpmsg; + + udpmsg.msg_name = (void *)&sin; + udpmsg.msg_namelen = sizeof(sin); + udpmsg.msg_control = NULL; + udpmsg.msg_controllen = 0; + udpmsg.msg_flags = 0; + + kernel_sendmsg(udpsock, &udpmsg, &iov, 1, sizeof(ah)); +} + + +/* + * Handle incoming AUN packets. Work out if anybody wants them, + * and send positive or negative acknowledgements as appropriate. + */ + +static void aun_incoming(struct sk_buff *skb, struct aunhdr *ah, size_t len) +{ + struct iphdr *ip = ip_hdr(skb); + unsigned char stn = ntohl(ip->saddr) & 0xff; + struct dst_entry *dst = skb_dst(skb); + struct ec_device *edev = NULL; + struct sock *sk = NULL; + struct sk_buff *newskb; + + if (dst) + edev = dst->dev->ec_ptr; + + if (!edev) + goto bad; + + sk = ec_listening_socket(ah->port, stn, edev->net); + if (sk == NULL) + goto bad; /* Nobody wants it */ + + newskb = alloc_skb((len - sizeof(struct aunhdr) + 15) & ~15, + GFP_ATOMIC); + if (newskb == NULL) { + pr_debug("AUN: memory squeeze, dropping packet\n"); + /* Send nack and hope sender tries again */ + goto bad; + } + + memcpy(skb_put(newskb, len - sizeof(struct aunhdr)), (void *)(ah + 1), + len - sizeof(struct aunhdr)); + + if (ec_queue_packet(sk, newskb, stn, edev->net, ah->cb, ah->port)) { + /* Socket is bankrupt. */ + kfree_skb(newskb); + goto bad; + } + + aun_send_response(ip->saddr, ah->handle, 3, 0); + sock_put(sk); + return; + +bad: + aun_send_response(ip->saddr, ah->handle, 4, 0); + if (sk) + sock_put(sk); +} + +/* + * Handle incoming AUN transmit acknowledgements. If the sequence + * number matches something in our backlog then kill it and tell + * the user. If the remote took too long to reply then we may have + * dropped the packet already. + */ + +static void aun_tx_ack(unsigned long seq, int result) +{ + struct sk_buff *skb; + unsigned long flags; + struct ec_cb *eb; + + spin_lock_irqsave(&aun_queue_lock, flags); + skb_queue_walk(&aun_queue, skb) { + eb = (struct ec_cb *)&skb->cb; + if (eb->seq == seq) + goto foundit; + } + spin_unlock_irqrestore(&aun_queue_lock, flags); + pr_debug("AUN: unknown sequence %ld\n", seq); + return; + +foundit: + tx_result(skb->sk, eb->cookie, result); + skb_unlink(skb, &aun_queue); + spin_unlock_irqrestore(&aun_queue_lock, flags); + kfree_skb(skb); +} + +/* + * Deal with received AUN frames - sort out what type of thing it is + * and hand it to the right function. + */ + +static void aun_data_available(struct sock *sk, int slen) +{ + int err; + struct sk_buff *skb; + unsigned char *data; + struct aunhdr *ah; + size_t len; + + while ((skb = skb_recv_datagram(sk, 0, 1, &err)) == NULL) { + if (err == -EAGAIN) { + pr_err("AUN: no data available?!\n"); + return; + } + pr_debug("AUN: recvfrom() error %d\n", -err); + } + + data = skb_transport_header(skb) + sizeof(struct udphdr); + ah = (struct aunhdr *)data; + len = skb->len - sizeof(struct udphdr); + + switch (ah->code) { + case 2: + aun_incoming(skb, ah, len); + break; + case 3: + aun_tx_ack(ah->handle, ECTYPE_TRANSMIT_OK); + break; + case 4: + aun_tx_ack(ah->handle, ECTYPE_TRANSMIT_NOT_LISTENING); + break; + default: + pr_debug("AUN: unknown packet type: %d\n", data[0]); + } + + skb_free_datagram(sk, skb); +} + +/* + * Called by the timer to manage the AUN transmit queue. If a packet + * was sent to a dead or nonexistent host then we will never get an + * acknowledgement back. After a few seconds we need to spot this and + * drop the packet. + */ + +static void ab_cleanup(unsigned long h) +{ + struct sk_buff *skb, *n; + unsigned long flags; + + spin_lock_irqsave(&aun_queue_lock, flags); + skb_queue_walk_safe(&aun_queue, skb, n) { + struct ec_cb *eb = (struct ec_cb *)&skb->cb; + if ((jiffies - eb->start) > eb->timeout) { + tx_result(skb->sk, eb->cookie, + ECTYPE_TRANSMIT_NOT_PRESENT); + skb_unlink(skb, &aun_queue); + kfree_skb(skb); + } + } + spin_unlock_irqrestore(&aun_queue_lock, flags); + + mod_timer(&ab_cleanup_timer, jiffies + (HZ * 2)); +} + +static int __init aun_udp_initialise(void) +{ + int error; + struct sockaddr_in sin; + + skb_queue_head_init(&aun_queue); + setup_timer(&ab_cleanup_timer, ab_cleanup, 0); + ab_cleanup_timer.expires = jiffies + (HZ * 2); + add_timer(&ab_cleanup_timer); + + memset(&sin, 0, sizeof(sin)); + sin.sin_port = htons(AUN_PORT); + + /* We can count ourselves lucky Acorn machines are too dim to + speak IPv6. :-) */ + error = sock_create_kern(PF_INET, SOCK_DGRAM, 0, &udpsock); + if (error < 0) { + pr_err("AUN: socket error %d\n", -error); + return error; + } + + udpsock->sk->sk_reuse = SK_CAN_REUSE; + udpsock->sk->sk_allocation = GFP_ATOMIC; /* we're going to call it + from interrupts */ + + error = udpsock->ops->bind(udpsock, (struct sockaddr *)&sin, + sizeof(sin)); + if (error < 0) { + pr_err("AUN: bind error %d\n", -error); + goto release; + } + + udpsock->sk->sk_data_ready = aun_data_available; + + return 0; + +release: + sock_release(udpsock); + udpsock = NULL; + return error; +} +#endif + +#ifdef CONFIG_ECONET_NATIVE + +/* + * Receive an Econet frame from a device. + */ + +static int econet_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt, struct net_device *orig_dev) +{ + struct ec_framehdr *hdr; + struct sock *sk = NULL; + struct ec_device *edev = dev->ec_ptr; + + if (!net_eq(dev_net(dev), &init_net)) + goto drop; + + if (skb->pkt_type == PACKET_OTHERHOST) + goto drop; + + if (!edev) + goto drop; + + skb = skb_share_check(skb, GFP_ATOMIC); + if (skb == NULL) + return NET_RX_DROP; + + if (!pskb_may_pull(skb, sizeof(struct ec_framehdr))) + goto drop; + + hdr = (struct ec_framehdr *)skb->data; + + /* First check for encapsulated IP */ + if (hdr->port == EC_PORT_IP) { + skb->protocol = htons(ETH_P_IP); + skb_pull(skb, sizeof(struct ec_framehdr)); + netif_rx(skb); + return NET_RX_SUCCESS; + } + + sk = ec_listening_socket(hdr->port, hdr->src_stn, hdr->src_net); + if (!sk) + goto drop; + + if (ec_queue_packet(sk, skb, edev->net, hdr->src_stn, hdr->cb, + hdr->port)) + goto drop; + sock_put(sk); + return NET_RX_SUCCESS; + +drop: + if (sk) + sock_put(sk); + kfree_skb(skb); + return NET_RX_DROP; +} + +static struct packet_type econet_packet_type __read_mostly = { + .type = cpu_to_be16(ETH_P_ECONET), + .func = econet_rcv, +}; + +static void econet_hw_initialise(void) +{ + dev_add_pack(&econet_packet_type); +} + +#endif + +static int econet_notifier(struct notifier_block *this, unsigned long msg, + void *data) +{ + struct net_device *dev = data; + struct ec_device *edev; + + if (!net_eq(dev_net(dev), &init_net)) + return NOTIFY_DONE; + + switch (msg) { + case NETDEV_UNREGISTER: + /* A device has gone down - kill any data we hold for it. */ + edev = dev->ec_ptr; + if (edev) { + if (net2dev_map[0] == dev) + net2dev_map[0] = NULL; + net2dev_map[edev->net] = NULL; + kfree(edev); + dev->ec_ptr = NULL; + } + break; + } + + return NOTIFY_DONE; +} + +static struct notifier_block econet_netdev_notifier = { + .notifier_call = econet_notifier, +}; + +static void __exit econet_proto_exit(void) +{ +#ifdef CONFIG_ECONET_AUNUDP + del_timer(&ab_cleanup_timer); + if (udpsock) + sock_release(udpsock); +#endif + unregister_netdevice_notifier(&econet_netdev_notifier); +#ifdef CONFIG_ECONET_NATIVE + dev_remove_pack(&econet_packet_type); +#endif + sock_unregister(econet_family_ops.family); + proto_unregister(&econet_proto); +} + +static int __init econet_proto_init(void) +{ + int err = proto_register(&econet_proto, 0); + + if (err != 0) + goto out; + sock_register(&econet_family_ops); +#ifdef CONFIG_ECONET_AUNUDP + aun_udp_initialise(); +#endif +#ifdef CONFIG_ECONET_NATIVE + econet_hw_initialise(); +#endif + register_netdevice_notifier(&econet_netdev_notifier); +out: + return err; +} + +module_init(econet_proto_init); +module_exit(econet_proto_exit); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS_NETPROTO(PF_ECONET); diff --git a/trunk/net/ethernet/eth.c b/trunk/net/ethernet/eth.c index 36e58800a9e3..5889a6c38a10 100644 --- a/trunk/net/ethernet/eth.c +++ b/trunk/net/ethernet/eth.c @@ -164,7 +164,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev) eth = eth_hdr(skb); if (unlikely(is_multicast_ether_addr(eth->h_dest))) { - if (ether_addr_equal_64bits(eth->h_dest, dev->broadcast)) + if (!compare_ether_addr_64bits(eth->h_dest, dev->broadcast)) skb->pkt_type = PACKET_BROADCAST; else skb->pkt_type = PACKET_MULTICAST; @@ -179,8 +179,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev) */ else if (1 /*dev->flags&IFF_PROMISC */ ) { - if (unlikely(!ether_addr_equal_64bits(eth->h_dest, - dev->dev_addr))) + if (unlikely(compare_ether_addr_64bits(eth->h_dest, dev->dev_addr))) skb->pkt_type = PACKET_OTHERHOST; } diff --git a/trunk/net/ieee802154/nl-phy.c b/trunk/net/ieee802154/nl-phy.c index eed291626da6..3bdc4303c339 100644 --- a/trunk/net/ieee802154/nl-phy.c +++ b/trunk/net/ieee802154/nl-phy.c @@ -179,7 +179,6 @@ static int ieee802154_add_iface(struct sk_buff *skb, const char *devname; int rc = -ENOBUFS; struct net_device *dev; - int type = __IEEE802154_DEV_INVALID; pr_debug("%s\n", __func__); @@ -222,13 +221,7 @@ static int ieee802154_add_iface(struct sk_buff *skb, goto nla_put_failure; } - if (info->attrs[IEEE802154_ATTR_DEV_TYPE]) { - type = nla_get_u8(info->attrs[IEEE802154_ATTR_DEV_TYPE]); - if (type >= __IEEE802154_DEV_MAX) - return -EINVAL; - } - - dev = phy->add_iface(phy, devname, type); + dev = phy->add_iface(phy, devname); if (IS_ERR(dev)) { rc = PTR_ERR(dev); goto nla_put_failure; diff --git a/trunk/net/ipv4/Kconfig b/trunk/net/ipv4/Kconfig index 20f1cb5c8aba..d183262943d9 100644 --- a/trunk/net/ipv4/Kconfig +++ b/trunk/net/ipv4/Kconfig @@ -262,8 +262,8 @@ config ARPD bool "IP: ARP daemon support" ---help--- The kernel maintains an internal cache which maps IP addresses to - hardware addresses on the local network, so that Ethernet - frames are sent to the proper address on the physical networking + hardware addresses on the local network, so that Ethernet/Token Ring/ + etc. frames are sent to the proper address on the physical networking layer. Normally, kernel uses the ARP protocol to resolve these mappings. @@ -312,7 +312,7 @@ config SYN_COOKIES config INET_AH tristate "IP: AH transformation" - select XFRM_ALGO + select XFRM select CRYPTO select CRYPTO_HMAC select CRYPTO_MD5 @@ -324,7 +324,7 @@ config INET_AH config INET_ESP tristate "IP: ESP transformation" - select XFRM_ALGO + select XFRM select CRYPTO select CRYPTO_AUTHENC select CRYPTO_HMAC diff --git a/trunk/net/ipv4/ah4.c b/trunk/net/ipv4/ah4.c index e8f2617ecd47..3a280756dd73 100644 --- a/trunk/net/ipv4/ah4.c +++ b/trunk/net/ipv4/ah4.c @@ -406,8 +406,8 @@ static void ah4_err(struct sk_buff *skb, u32 info) ah->spi, IPPROTO_AH, AF_INET); if (!x) return; - pr_debug("pmtu discovery on SA AH/%08x/%08x\n", - ntohl(ah->spi), ntohl(iph->daddr)); + printk(KERN_DEBUG "pmtu discovery on SA AH/%08x/%08x\n", + ntohl(ah->spi), ntohl(iph->daddr)); xfrm_state_put(x); } diff --git a/trunk/net/ipv4/arp.c b/trunk/net/ipv4/arp.c index cda37be02f8d..373b56bf8f49 100644 --- a/trunk/net/ipv4/arp.c +++ b/trunk/net/ipv4/arp.c @@ -73,8 +73,6 @@ * Jesper D. Brouer: Proxy ARP PVLAN RFC 3069 support. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -91,6 +89,7 @@ #include #include #include +#include #include #include #include @@ -194,6 +193,9 @@ int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir) case ARPHRD_IEEE802: ip_eth_mc_map(addr, haddr); return 0; + case ARPHRD_IEEE802_TR: + ip_tr_mc_map(addr, haddr); + return 0; case ARPHRD_INFINIBAND: ip_ib_mc_map(addr, dev->broadcast, haddr); return 0; @@ -362,7 +364,8 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) probes -= neigh->parms->ucast_probes; if (probes < 0) { if (!(neigh->nud_state & NUD_VALID)) - pr_debug("trying to ucast probe in NUD_INVALID\n"); + printk(KERN_DEBUG + "trying to ucast probe in NUD_INVALID\n"); dst_ha = neigh->ha; read_lock_bh(&neigh->lock); } else { @@ -449,7 +452,7 @@ static int arp_set_predefined(int addr_hint, unsigned char *haddr, { switch (addr_hint) { case RTN_LOCAL: - pr_debug("arp called for own IP address\n"); + printk(KERN_DEBUG "ARP: arp called for own IP address\n"); memcpy(haddr, dev->dev_addr, dev->addr_len); return 1; case RTN_MULTICAST: @@ -470,7 +473,7 @@ int arp_find(unsigned char *haddr, struct sk_buff *skb) struct neighbour *n; if (!skb_dst(skb)) { - pr_debug("arp_find is called with dst==NULL\n"); + printk(KERN_DEBUG "arp_find is called with dst==NULL\n"); kfree_skb(skb); return 1; } @@ -644,6 +647,12 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip, arp->ar_hrd = htons(ARPHRD_ETHER); arp->ar_pro = htons(ETH_P_IP); break; +#endif +#if IS_ENABLED(CONFIG_TR) + case ARPHRD_IEEE802_TR: + arp->ar_hrd = htons(ARPHRD_IEEE802); + arp->ar_pro = htons(ETH_P_IP); + break; #endif } @@ -742,10 +751,11 @@ static int arp_process(struct sk_buff *skb) goto out; break; case ARPHRD_ETHER: + case ARPHRD_IEEE802_TR: case ARPHRD_FDDI: case ARPHRD_IEEE802: /* - * ETHERNET, and Fibre Channel (which are IEEE 802 + * ETHERNET, Token Ring and Fibre Channel (which are IEEE 802 * devices, according to RFC 2625) devices will accept ARP * hardware types of either 1 (Ethernet) or 6 (IEEE 802.2). * This is the case also of FDDI, where the RFC 1390 says that diff --git a/trunk/net/ipv4/devinet.c b/trunk/net/ipv4/devinet.c index 10e15a144e95..88c9e3f68c78 100644 --- a/trunk/net/ipv4/devinet.c +++ b/trunk/net/ipv4/devinet.c @@ -217,7 +217,8 @@ void in_dev_finish_destroy(struct in_device *idev) WARN_ON(idev->ifa_list); WARN_ON(idev->mc_list); #ifdef NET_REFCNT_DEBUG - pr_debug("%s: %p=%s\n", __func__, idev, dev ? dev->name : "NIL"); + printk(KERN_DEBUG "in_dev_finish_destroy: %p=%s\n", + idev, dev ? dev->name : "NIL"); #endif dev_put(dev); if (!idev->dead) @@ -1173,7 +1174,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, switch (event) { case NETDEV_REGISTER: - pr_debug("%s: bug\n", __func__); + printk(KERN_DEBUG "inetdev_event: bug\n"); RCU_INIT_POINTER(dev->ip_ptr, NULL); break; case NETDEV_UP: diff --git a/trunk/net/ipv4/fib_trie.c b/trunk/net/ipv4/fib_trie.c index 30b88d7b4bd6..bce36f1a37b4 100644 --- a/trunk/net/ipv4/fib_trie.c +++ b/trunk/net/ipv4/fib_trie.c @@ -1370,8 +1370,6 @@ static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l, if (fa->fa_tos && fa->fa_tos != flp->flowi4_tos) continue; - if (fi->fib_dead) - continue; if (fa->fa_info->fib_scope < flp->flowi4_scope) continue; fib_alias_accessed(fa); diff --git a/trunk/net/ipv4/icmp.c b/trunk/net/ipv4/icmp.c index c75efbdc71cb..2cb2bf845641 100644 --- a/trunk/net/ipv4/icmp.c +++ b/trunk/net/ipv4/icmp.c @@ -713,10 +713,11 @@ static void icmp_unreach(struct sk_buff *skb) if (!net->ipv4.sysctl_icmp_ignore_bogus_error_responses && inet_addr_type(net, iph->daddr) == RTN_BROADCAST) { - net_warn_ratelimited("%pI4 sent an invalid ICMP type %u, code %u error to a broadcast: %pI4 on %s\n", - &ip_hdr(skb)->saddr, - icmph->type, icmph->code, - &iph->daddr, skb->dev->name); + if (net_ratelimit()) + pr_warn("%pI4 sent an invalid ICMP type %u, code %u error to a broadcast: %pI4 on %s\n", + &ip_hdr(skb)->saddr, + icmph->type, icmph->code, + &iph->daddr, skb->dev->name); goto out; } @@ -905,7 +906,8 @@ static void icmp_timestamp(struct sk_buff *skb) static void icmp_address(struct sk_buff *skb) { #if 0 - net_dbg_ratelimited("a guy asks for address mask. Who is it?\n"); + if (net_ratelimit()) + printk(KERN_DEBUG "a guy asks for address mask. Who is it?\n"); #endif } @@ -941,10 +943,10 @@ static void icmp_address_reply(struct sk_buff *skb) inet_ifa_match(ip_hdr(skb)->saddr, ifa)) break; } - if (!ifa) - net_info_ratelimited("Wrong address mask %pI4 from %s/%pI4\n", - mp, - dev->name, &ip_hdr(skb)->saddr); + if (!ifa && net_ratelimit()) { + pr_info("Wrong address mask %pI4 from %s/%pI4\n", + mp, dev->name, &ip_hdr(skb)->saddr); + } } } diff --git a/trunk/net/ipv4/inet_timewait_sock.c b/trunk/net/ipv4/inet_timewait_sock.c index 2784db3155fb..543ef6225458 100644 --- a/trunk/net/ipv4/inet_timewait_sock.c +++ b/trunk/net/ipv4/inet_timewait_sock.c @@ -89,8 +89,8 @@ static void __inet_twsk_kill(struct inet_timewait_sock *tw, #ifdef SOCK_REFCNT_DEBUG if (atomic_read(&tw->tw_refcnt) != 1) { - pr_debug("%s timewait_sock %p refcnt=%d\n", - tw->tw_prot->name, tw, atomic_read(&tw->tw_refcnt)); + printk(KERN_DEBUG "%s timewait_sock %p refcnt=%d\n", + tw->tw_prot->name, tw, atomic_read(&tw->tw_refcnt)); } #endif while (refcnt) { diff --git a/trunk/net/ipv4/ip_fragment.c b/trunk/net/ipv4/ip_fragment.c index 9dbd3dd6022d..71e5c328176c 100644 --- a/trunk/net/ipv4/ip_fragment.c +++ b/trunk/net/ipv4/ip_fragment.c @@ -148,17 +148,17 @@ static unsigned int ip4_hashfn(struct inet_frag_queue *q) return ipqhashfn(ipq->id, ipq->saddr, ipq->daddr, ipq->protocol); } -static bool ip4_frag_match(struct inet_frag_queue *q, void *a) +static int ip4_frag_match(struct inet_frag_queue *q, void *a) { struct ipq *qp; struct ip4_create_arg *arg = a; qp = container_of(q, struct ipq, q); return qp->id == arg->iph->id && - qp->saddr == arg->iph->saddr && - qp->daddr == arg->iph->daddr && - qp->protocol == arg->iph->protocol && - qp->user == arg->user; + qp->saddr == arg->iph->saddr && + qp->daddr == arg->iph->daddr && + qp->protocol == arg->iph->protocol && + qp->user == arg->user; } /* Memory Tracking Functions. */ @@ -545,7 +545,6 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, int len; int ihlen; int err; - int sum_truesize; u8 ecn; ipq_kill(qp); @@ -612,32 +611,19 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, atomic_add(clone->truesize, &qp->q.net->mem); } + skb_shinfo(head)->frag_list = head->next; skb_push(head, head->data - skb_network_header(head)); - sum_truesize = head->truesize; - for (fp = head->next; fp;) { - bool headstolen; - int delta; - struct sk_buff *next = fp->next; - - sum_truesize += fp->truesize; + for (fp=head->next; fp; fp = fp->next) { + head->data_len += fp->len; + head->len += fp->len; if (head->ip_summed != fp->ip_summed) head->ip_summed = CHECKSUM_NONE; else if (head->ip_summed == CHECKSUM_COMPLETE) head->csum = csum_add(head->csum, fp->csum); - - if (skb_try_coalesce(head, fp, &headstolen, &delta)) { - kfree_skb_partial(fp, headstolen); - } else { - if (!skb_shinfo(head)->frag_list) - skb_shinfo(head)->frag_list = fp; - head->data_len += fp->len; - head->len += fp->len; - head->truesize += fp->truesize; - } - fp = next; + head->truesize += fp->truesize; } - atomic_sub(sum_truesize, &qp->q.net->mem); + atomic_sub(head->truesize, &qp->q.net->mem); head->next = NULL; head->dev = dev; @@ -658,7 +644,8 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, err = -ENOMEM; goto out_fail; out_oversize: - net_info_ratelimited("Oversized IP packet from %pI4\n", &qp->saddr); + if (net_ratelimit()) + pr_info("Oversized IP packet from %pI4\n", &qp->saddr); out_fail: IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS); return err; diff --git a/trunk/net/ipv4/ip_input.c b/trunk/net/ipv4/ip_input.c index 8590144ca330..26eccc5bab1c 100644 --- a/trunk/net/ipv4/ip_input.c +++ b/trunk/net/ipv4/ip_input.c @@ -210,8 +210,9 @@ static int ip_local_deliver_finish(struct sk_buff *skb) int ret; if (!net_eq(net, &init_net) && !ipprot->netns_ok) { - net_info_ratelimited("%s: proto %d isn't netns-ready\n", - __func__, protocol); + if (net_ratelimit()) + printk("%s: proto %d isn't netns-ready\n", + __func__, protocol); kfree_skb(skb); goto out; } @@ -297,10 +298,10 @@ static inline bool ip_rcv_options(struct sk_buff *skb) if (in_dev) { if (!IN_DEV_SOURCE_ROUTE(in_dev)) { - if (IN_DEV_LOG_MARTIANS(in_dev)) - net_info_ratelimited("source route option %pI4 -> %pI4\n", - &iph->saddr, - &iph->daddr); + if (IN_DEV_LOG_MARTIANS(in_dev) && + net_ratelimit()) + pr_info("source route option %pI4 -> %pI4\n", + &iph->saddr, &iph->daddr); goto drop; } } diff --git a/trunk/net/ipv4/ip_options.c b/trunk/net/ipv4/ip_options.c index 708b99494e23..95722ed0e5bb 100644 --- a/trunk/net/ipv4/ip_options.c +++ b/trunk/net/ipv4/ip_options.c @@ -578,10 +578,8 @@ void ip_forward_options(struct sk_buff *skb) ip_hdr(skb)->daddr = opt->nexthop; ip_rt_get_source(&optptr[srrptr-1], skb, rt); optptr[2] = srrptr+4; - } else { - net_crit_ratelimited("%s(): Argh! Destination lost!\n", - __func__); - } + } else if (net_ratelimit()) + pr_crit("%s(): Argh! Destination lost!\n", __func__); if (opt->ts_needaddr) { optptr = raw + opt->ts; ip_rt_get_source(&optptr[optptr[2]-9], skb, rt); diff --git a/trunk/net/ipv4/ip_output.c b/trunk/net/ipv4/ip_output.c index 451f97c42eb4..4910176d24ed 100644 --- a/trunk/net/ipv4/ip_output.c +++ b/trunk/net/ipv4/ip_output.c @@ -214,8 +214,8 @@ static inline int ip_finish_output2(struct sk_buff *skb) } rcu_read_unlock(); - net_dbg_ratelimited("%s: No header cache and no neighbour!\n", - __func__); + if (net_ratelimit()) + printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n"); kfree_skb(skb); return -EINVAL; } diff --git a/trunk/net/ipv4/ipconfig.c b/trunk/net/ipv4/ipconfig.c index 67e8a6b086ea..f267280d8709 100644 --- a/trunk/net/ipv4/ipconfig.c +++ b/trunk/net/ipv4/ipconfig.c @@ -808,6 +808,8 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d b->op = BOOTP_REQUEST; if (dev->type < 256) /* check for false types */ b->htype = dev->type; + else if (dev->type == ARPHRD_IEEE802_TR) /* fix for token ring */ + b->htype = ARPHRD_IEEE802; else if (dev->type == ARPHRD_FDDI) b->htype = ARPHRD_ETHER; else { @@ -953,7 +955,8 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str /* Fragments are not supported */ if (ip_is_fragment(h)) { - net_err_ratelimited("DHCP/BOOTP: Ignoring fragmented reply\n"); + if (net_ratelimit()) + pr_err("DHCP/BOOTP: Ignoring fragmented reply\n"); goto drop; } @@ -1001,14 +1004,16 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str /* Is it a reply to our BOOTP request? */ if (b->op != BOOTP_REPLY || b->xid != d->xid) { - net_err_ratelimited("DHCP/BOOTP: Reply not for us, op[%x] xid[%x]\n", - b->op, b->xid); + if (net_ratelimit()) + pr_err("DHCP/BOOTP: Reply not for us, op[%x] xid[%x]\n", + b->op, b->xid); goto drop_unlock; } /* Is it a reply for the device we are configuring? */ if (b->xid != ic_dev_xid) { - net_err_ratelimited("DHCP/BOOTP: Ignoring delayed packet\n"); + if (net_ratelimit()) + pr_err("DHCP/BOOTP: Ignoring delayed packet\n"); goto drop_unlock; } @@ -1621,13 +1626,11 @@ static int __init ip_auto_config_setup(char *addrs) return 1; } -__setup("ip=", ip_auto_config_setup); static int __init nfsaddrs_config_setup(char *addrs) { return ip_auto_config_setup(addrs); } -__setup("nfsaddrs=", nfsaddrs_config_setup); static int __init vendor_class_identifier_setup(char *addrs) { @@ -1638,4 +1641,7 @@ static int __init vendor_class_identifier_setup(char *addrs) vendor_class_identifier); return 1; } + +__setup("ip=", ip_auto_config_setup); +__setup("nfsaddrs=", nfsaddrs_config_setup); __setup("dhcpclass=", vendor_class_identifier_setup); diff --git a/trunk/net/ipv4/ipmr.c b/trunk/net/ipv4/ipmr.c index a9e519ad6db5..5bef604ac0fa 100644 --- a/trunk/net/ipv4/ipmr.c +++ b/trunk/net/ipv4/ipmr.c @@ -949,7 +949,8 @@ static int ipmr_cache_report(struct mr_table *mrt, ret = sock_queue_rcv_skb(mroute_sk, skb); rcu_read_unlock(); if (ret < 0) { - net_warn_ratelimited("mroute: pending queue full, dropping entries\n"); + if (net_ratelimit()) + pr_warn("mroute: pending queue full, dropping entries\n"); kfree_skb(skb); } diff --git a/trunk/net/ipv4/netfilter/arp_tables.c b/trunk/net/ipv4/netfilter/arp_tables.c index 97e61eadf580..a3935273869f 100644 --- a/trunk/net/ipv4/netfilter/arp_tables.c +++ b/trunk/net/ipv4/netfilter/arp_tables.c @@ -221,8 +221,9 @@ static inline int arp_checkentry(const struct arpt_arp *arp) static unsigned int arpt_error(struct sk_buff *skb, const struct xt_action_param *par) { - net_err_ratelimited("arp_tables: error: '%s'\n", - (const char *)par->targinfo); + if (net_ratelimit()) + pr_err("arp_tables: error: '%s'\n", + (const char *)par->targinfo); return NF_DROP; } diff --git a/trunk/net/ipv4/netfilter/ip_tables.c b/trunk/net/ipv4/netfilter/ip_tables.c index 170b1fdd6b72..585b80f3cc68 100644 --- a/trunk/net/ipv4/netfilter/ip_tables.c +++ b/trunk/net/ipv4/netfilter/ip_tables.c @@ -153,7 +153,8 @@ ip_checkentry(const struct ipt_ip *ip) static unsigned int ipt_error(struct sk_buff *skb, const struct xt_action_param *par) { - net_info_ratelimited("error: `%s'\n", (const char *)par->targinfo); + if (net_ratelimit()) + pr_info("error: `%s'\n", (const char *)par->targinfo); return NF_DROP; } diff --git a/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c b/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c index fe5daea5214d..a639967eb727 100644 --- a/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -246,7 +246,8 @@ clusterip_hashfn(const struct sk_buff *skb, dport = ports[1]; } } else { - net_info_ratelimited("unknown protocol %u\n", iph->protocol); + if (net_ratelimit()) + pr_info("unknown protocol %u\n", iph->protocol); } switch (config->hash_mode) { diff --git a/trunk/net/ipv4/netfilter/nf_nat_h323.c b/trunk/net/ipv4/netfilter/nf_nat_h323.c index cad29c121318..82536701e3a3 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_h323.c +++ b/trunk/net/ipv4/netfilter/nf_nat_h323.c @@ -42,7 +42,9 @@ static int set_addr(struct sk_buff *skb, if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo, addroff, sizeof(buf), (char *) &buf, sizeof(buf))) { - net_notice_ratelimited("nf_nat_h323: nf_nat_mangle_tcp_packet error\n"); + if (net_ratelimit()) + pr_notice("nf_nat_h323: nf_nat_mangle_tcp_packet" + " error\n"); return -1; } @@ -56,7 +58,9 @@ static int set_addr(struct sk_buff *skb, if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo, addroff, sizeof(buf), (char *) &buf, sizeof(buf))) { - net_notice_ratelimited("nf_nat_h323: nf_nat_mangle_udp_packet error\n"); + if (net_ratelimit()) + pr_notice("nf_nat_h323: nf_nat_mangle_udp_packet" + " error\n"); return -1; } /* nf_nat_mangle_udp_packet uses skb_make_writable() to copy @@ -210,7 +214,8 @@ static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct, /* Run out of expectations */ if (i >= H323_RTP_CHANNEL_MAX) { - net_notice_ratelimited("nf_nat_h323: out of expectations\n"); + if (net_ratelimit()) + pr_notice("nf_nat_h323: out of expectations\n"); return 0; } @@ -239,7 +244,8 @@ static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct, } if (nated_port == 0) { /* No port available */ - net_notice_ratelimited("nf_nat_h323: out of RTP ports\n"); + if (net_ratelimit()) + pr_notice("nf_nat_h323: out of RTP ports\n"); return 0; } @@ -302,7 +308,8 @@ static int nat_t120(struct sk_buff *skb, struct nf_conn *ct, } if (nated_port == 0) { /* No port available */ - net_notice_ratelimited("nf_nat_h323: out of TCP ports\n"); + if (net_ratelimit()) + pr_notice("nf_nat_h323: out of TCP ports\n"); return 0; } @@ -358,7 +365,8 @@ static int nat_h245(struct sk_buff *skb, struct nf_conn *ct, } if (nated_port == 0) { /* No port available */ - net_notice_ratelimited("nf_nat_q931: out of TCP ports\n"); + if (net_ratelimit()) + pr_notice("nf_nat_q931: out of TCP ports\n"); return 0; } @@ -448,7 +456,8 @@ static int nat_q931(struct sk_buff *skb, struct nf_conn *ct, } if (nated_port == 0) { /* No port available */ - net_notice_ratelimited("nf_nat_ras: out of TCP ports\n"); + if (net_ratelimit()) + pr_notice("nf_nat_ras: out of TCP ports\n"); return 0; } @@ -536,7 +545,8 @@ static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct, } if (nated_port == 0) { /* No port available */ - net_notice_ratelimited("nf_nat_q931: out of TCP ports\n"); + if (net_ratelimit()) + pr_notice("nf_nat_q931: out of TCP ports\n"); return 0; } diff --git a/trunk/net/ipv4/netfilter/nf_nat_snmp_basic.c b/trunk/net/ipv4/netfilter/nf_nat_snmp_basic.c index 746edec8b86e..2133c30a4a5f 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_snmp_basic.c +++ b/trunk/net/ipv4/netfilter/nf_nat_snmp_basic.c @@ -1206,7 +1206,8 @@ static int snmp_translate(struct nf_conn *ct, if (!snmp_parse_mangle((unsigned char *)udph + sizeof(struct udphdr), paylen, &map, &udph->check)) { - net_warn_ratelimited("bsalg: parser failed\n"); + if (net_ratelimit()) + printk(KERN_WARNING "bsalg: parser failed\n"); return NF_DROP; } return NF_ACCEPT; @@ -1240,8 +1241,9 @@ static int help(struct sk_buff *skb, unsigned int protoff, * can mess around with the payload. */ if (ntohs(udph->len) != skb->len - (iph->ihl << 2)) { - net_warn_ratelimited("SNMP: dropping malformed packet src=%pI4 dst=%pI4\n", - &iph->saddr, &iph->daddr); + if (net_ratelimit()) + printk(KERN_WARNING "SNMP: dropping malformed packet src=%pI4 dst=%pI4\n", + &iph->saddr, &iph->daddr); return NF_DROP; } diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index ffcb3b016843..5773f5d9e213 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -960,7 +960,8 @@ void rt_cache_flush_batch(struct net *net) static void rt_emergency_hash_rebuild(struct net *net) { - net_warn_ratelimited("Route hash chain too long!\n"); + if (net_ratelimit()) + pr_warn("Route hash chain too long!\n"); rt_cache_invalidate(net); } @@ -1083,7 +1084,8 @@ static int rt_garbage_collect(struct dst_ops *ops) goto out; if (dst_entries_get_slow(&ipv4_dst_ops) < ip_rt_max_size) goto out; - net_warn_ratelimited("dst cache overflow\n"); + if (net_ratelimit()) + pr_warn("dst cache overflow\n"); RT_CACHE_STAT_INC(gc_dst_overflow); return 1; @@ -1180,7 +1182,8 @@ static struct rtable *rt_intern_hash(unsigned int hash, struct rtable *rt, if (rt->rt_type == RTN_UNICAST || rt_is_output_route(rt)) { int err = rt_bind_neighbour(rt); if (err) { - net_warn_ratelimited("Neighbour table failure & not caching routes\n"); + if (net_ratelimit()) + pr_warn("Neighbour table failure & not caching routes\n"); ip_rt_put(rt); return ERR_PTR(err); } @@ -1296,7 +1299,8 @@ static struct rtable *rt_intern_hash(unsigned int hash, struct rtable *rt, goto restart; } - net_warn_ratelimited("Neighbour table overflow\n"); + if (net_ratelimit()) + pr_warn("Neighbour table overflow\n"); rt_drop(rt); return ERR_PTR(-ENOBUFS); } @@ -1374,7 +1378,8 @@ void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more) return; } } else if (!rt) - pr_debug("rt_bind_peer(0) @%p\n", __builtin_return_address(0)); + printk(KERN_DEBUG "rt_bind_peer(0) @%p\n", + __builtin_return_address(0)); ip_select_fb_ident(iph); } @@ -1498,11 +1503,11 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, reject_redirect: #ifdef CONFIG_IP_ROUTE_VERBOSE - if (IN_DEV_LOG_MARTIANS(in_dev)) - net_info_ratelimited("Redirect from %pI4 on %s about %pI4 ignored\n" - " Advised path = %pI4 -> %pI4\n", - &old_gw, dev->name, &new_gw, - &saddr, &daddr); + if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit()) + pr_info("Redirect from %pI4 on %s about %pI4 ignored\n" + " Advised path = %pI4 -> %pI4\n", + &old_gw, dev->name, &new_gw, + &saddr, &daddr); #endif ; } @@ -1612,10 +1617,11 @@ void ip_rt_send_redirect(struct sk_buff *skb) ++peer->rate_tokens; #ifdef CONFIG_IP_ROUTE_VERBOSE if (log_martians && - peer->rate_tokens == ip_rt_redirect_number) - net_warn_ratelimited("host %pI4/if%d ignores redirects for %pI4 to %pI4\n", - &ip_hdr(skb)->saddr, rt->rt_iif, - &rt->rt_dst, &rt->rt_gateway); + peer->rate_tokens == ip_rt_redirect_number && + net_ratelimit()) + pr_warn("host %pI4/if%d ignores redirects for %pI4 to %pI4\n", + &ip_hdr(skb)->saddr, rt->rt_iif, + &rt->rt_dst, &rt->rt_gateway); #endif } } @@ -1838,9 +1844,9 @@ static void ipv4_link_failure(struct sk_buff *skb) static int ip_rt_bug(struct sk_buff *skb) { - pr_debug("%s: %pI4 -> %pI4, %s\n", - __func__, &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr, - skb->dev ? skb->dev->name : "?"); + printk(KERN_DEBUG "ip_rt_bug: %pI4 -> %pI4, %s\n", + &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr, + skb->dev ? skb->dev->name : "?"); kfree_skb(skb); WARN_ON(1); return 0; @@ -2129,7 +2135,8 @@ static int __mkroute_input(struct sk_buff *skb, /* get a working reference to the output device */ out_dev = __in_dev_get_rcu(FIB_RES_DEV(*res)); if (out_dev == NULL) { - net_crit_ratelimited("Bug in ip_route_input_slow(). Please report.\n"); + if (net_ratelimit()) + pr_crit("Bug in ip_route_input_slow(). Please report.\n"); return -EINVAL; } @@ -2400,9 +2407,9 @@ out: return err; martian_destination: RT_CACHE_STAT_INC(in_martian_dst); #ifdef CONFIG_IP_ROUTE_VERBOSE - if (IN_DEV_LOG_MARTIANS(in_dev)) - net_warn_ratelimited("martian destination %pI4 from %pI4, dev %s\n", - &daddr, &saddr, dev->name); + if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit()) + pr_warn("martian destination %pI4 from %pI4, dev %s\n", + &daddr, &saddr, dev->name); #endif e_hostunreach: @@ -3408,15 +3415,9 @@ struct ip_rt_acct __percpu *ip_rt_acct __read_mostly; static __initdata unsigned long rhash_entries; static int __init set_rhash_entries(char *str) { - ssize_t ret; - if (!str) return 0; - - ret = kstrtoul(str, 0, &rhash_entries); - if (ret) - return 0; - + rhash_entries = simple_strtoul(str, &str, 0); return 1; } __setup("rhash_entries=", set_rhash_entries); diff --git a/trunk/net/ipv4/tcp.c b/trunk/net/ipv4/tcp.c index bb485fcb077e..565406287f6f 100644 --- a/trunk/net/ipv4/tcp.c +++ b/trunk/net/ipv4/tcp.c @@ -593,7 +593,7 @@ static inline void tcp_mark_push(struct tcp_sock *tp, struct sk_buff *skb) tp->pushed_seq = tp->write_seq; } -static inline bool forced_push(const struct tcp_sock *tp) +static inline int forced_push(const struct tcp_sock *tp) { return after(tp->write_seq, tp->pushed_seq + (tp->max_window >> 1)); } @@ -917,7 +917,8 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse wait_for_sndbuf: set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); wait_for_memory: - tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH); + if (copied) + tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH); if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) goto do_error; @@ -977,6 +978,39 @@ static inline int select_size(const struct sock *sk, bool sg) return tmp; } +static int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) +{ + struct sk_buff *skb; + struct tcphdr *th; + bool fragstolen; + + skb = alloc_skb(size + sizeof(*th), sk->sk_allocation); + if (!skb) + goto err; + + th = (struct tcphdr *)skb_put(skb, sizeof(*th)); + skb_reset_transport_header(skb); + memset(th, 0, sizeof(*th)); + + if (memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size)) + goto err_free; + + TCP_SKB_CB(skb)->seq = tcp_sk(sk)->rcv_nxt; + TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + size; + TCP_SKB_CB(skb)->ack_seq = tcp_sk(sk)->snd_una - 1; + + if (tcp_queue_rcv(sk, skb, sizeof(*th), &fragstolen)) { + WARN_ON_ONCE(fragstolen); /* should not happen */ + __kfree_skb(skb); + } + return size; + +err_free: + kfree_skb(skb); +err: + return -ENOMEM; +} + int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t size) { @@ -1081,7 +1115,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, if (err) goto do_fault; } else { - bool merge = false; + int merge = 0; int i = skb_shinfo(skb)->nr_frags; struct page *page = sk->sk_sndmsg_page; int off; @@ -1095,7 +1129,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, off != PAGE_SIZE) { /* We can extend the last page * fragment. */ - merge = true; + merge = 1; } else if (i == MAX_SKB_FRAGS || !sg) { /* Need to add new fragment and cannot * do this because interface is non-SG, @@ -1292,7 +1326,7 @@ static int tcp_peek_sndq(struct sock *sk, struct msghdr *msg, int len) void tcp_cleanup_rbuf(struct sock *sk, int copied) { struct tcp_sock *tp = tcp_sk(sk); - bool time_to_ack = false; + int time_to_ack = 0; struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); @@ -1318,7 +1352,7 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied) ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED) && !icsk->icsk_ack.pingpong)) && !atomic_read(&sk->sk_rmem_alloc))) - time_to_ack = true; + time_to_ack = 1; } /* We send an ACK if we can now advertise a non-zero window @@ -1340,7 +1374,7 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied) * "Lots" means "at least twice" here. */ if (new_window && new_window >= 2 * rcv_window_now) - time_to_ack = true; + time_to_ack = 1; } } if (time_to_ack) @@ -1472,11 +1506,11 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, break; } if (tcp_hdr(skb)->fin) { - sk_eat_skb(sk, skb, false); + sk_eat_skb(sk, skb, 0); ++seq; break; } - sk_eat_skb(sk, skb, false); + sk_eat_skb(sk, skb, 0); if (!desc->count) break; tp->copied_seq = seq; @@ -1512,7 +1546,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, int target; /* Read at least this many bytes */ long timeo; struct task_struct *user_recv = NULL; - bool copied_early = false; + int copied_early = 0; struct sk_buff *skb; u32 urg_hole = 0; @@ -1744,9 +1778,9 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, } if ((flags & MSG_PEEK) && (peek_seq - copied - urg_hole != tp->copied_seq)) { - net_dbg_ratelimited("TCP(%s:%d): Application bug, race in MSG_PEEK\n", - current->comm, - task_pid_nr(current)); + if (net_ratelimit()) + printk(KERN_DEBUG "TCP(%s:%d): Application bug, race in MSG_PEEK.\n", + current->comm, task_pid_nr(current)); peek_seq = tp->copied_seq; } continue; @@ -1800,7 +1834,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, dma_async_memcpy_issue_pending(tp->ucopy.dma_chan); if ((offset + used) == skb->len) - copied_early = true; + copied_early = 1; } else #endif @@ -1834,7 +1868,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, goto found_fin_ok; if (!(flags & MSG_PEEK)) { sk_eat_skb(sk, skb, copied_early); - copied_early = false; + copied_early = 0; } continue; @@ -1843,7 +1877,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, ++*seq; if (!(flags & MSG_PEEK)) { sk_eat_skb(sk, skb, copied_early); - copied_early = false; + copied_early = 0; } break; } while (len > 0); @@ -2001,10 +2035,10 @@ bool tcp_check_oom(struct sock *sk, int shift) too_many_orphans = tcp_too_many_orphans(sk, shift); out_of_socket_memory = tcp_out_of_memory(sk); - if (too_many_orphans) - net_info_ratelimited("too many orphaned sockets\n"); - if (out_of_socket_memory) - net_info_ratelimited("out of memory -- consider tuning tcp_mem\n"); + if (too_many_orphans && net_ratelimit()) + pr_info("too many orphaned sockets\n"); + if (out_of_socket_memory && net_ratelimit()) + pr_info("out of memory -- consider tuning tcp_mem\n"); return too_many_orphans || out_of_socket_memory; } @@ -2170,7 +2204,7 @@ EXPORT_SYMBOL(tcp_close); /* These states need RST on ABORT according to RFC793 */ -static inline bool tcp_need_reset(int state) +static inline int tcp_need_reset(int state) { return (1 << state) & (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_FIN_WAIT1 | @@ -2244,7 +2278,7 @@ int tcp_disconnect(struct sock *sk, int flags) } EXPORT_SYMBOL(tcp_disconnect); -static inline bool tcp_can_repair_sock(const struct sock *sk) +static inline int tcp_can_repair_sock(struct sock *sk) { return capable(CAP_NET_ADMIN) && ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_ESTABLISHED)); @@ -3171,13 +3205,13 @@ __tcp_alloc_md5sig_pool(struct sock *sk) struct tcp_md5sig_pool __percpu *tcp_alloc_md5sig_pool(struct sock *sk) { struct tcp_md5sig_pool __percpu *pool; - bool alloc = false; + int alloc = 0; retry: spin_lock_bh(&tcp_md5sig_pool_lock); pool = tcp_md5sig_pool; if (tcp_md5sig_users++ == 0) { - alloc = true; + alloc = 1; spin_unlock_bh(&tcp_md5sig_pool_lock); } else if (!pool) { tcp_md5sig_users--; @@ -3461,15 +3495,9 @@ extern struct tcp_congestion_ops tcp_reno; static __initdata unsigned long thash_entries; static int __init set_thash_entries(char *str) { - ssize_t ret; - if (!str) return 0; - - ret = kstrtoul(str, 0, &thash_entries); - if (ret) - return 0; - + thash_entries = simple_strtoul(str, &str, 0); return 1; } __setup("thash_entries=", set_thash_entries); diff --git a/trunk/net/ipv4/tcp_cong.c b/trunk/net/ipv4/tcp_cong.c index 04dbd7ae7c62..272a84593c85 100644 --- a/trunk/net/ipv4/tcp_cong.c +++ b/trunk/net/ipv4/tcp_cong.c @@ -280,19 +280,19 @@ int tcp_set_congestion_control(struct sock *sk, const char *name) /* RFC2861 Check whether we are limited by application or congestion window * This is the inverse of cwnd check in tcp_tso_should_defer */ -bool tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight) +int tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight) { const struct tcp_sock *tp = tcp_sk(sk); u32 left; if (in_flight >= tp->snd_cwnd) - return true; + return 1; left = tp->snd_cwnd - in_flight; if (sk_can_gso(sk) && left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd && left * tp->mss_cache < sk->sk_gso_max_size) - return true; + return 1; return left <= tcp_max_tso_deferred_mss(tp); } EXPORT_SYMBOL_GPL(tcp_is_cwnd_limited); diff --git a/trunk/net/ipv4/tcp_hybla.c b/trunk/net/ipv4/tcp_hybla.c index 57bdd17dff4d..fe3ecf484b44 100644 --- a/trunk/net/ipv4/tcp_hybla.c +++ b/trunk/net/ipv4/tcp_hybla.c @@ -15,7 +15,7 @@ /* Tcp Hybla structure. */ struct hybla { - bool hybla_en; + u8 hybla_en; u32 snd_cwnd_cents; /* Keeps increment values when it is <1, <<7 */ u32 rho; /* Rho parameter, integer part */ u32 rho2; /* Rho * Rho, integer part */ @@ -24,7 +24,8 @@ struct hybla { u32 minrtt; /* Minimum smoothed round trip time value seen */ }; -/* Hybla reference round trip time (default= 1/40 sec = 25 ms), in ms */ +/* Hybla reference round trip time (default= 1/40 sec = 25 ms), + expressed in jiffies */ static int rtt0 = 25; module_param(rtt0, int, 0644); MODULE_PARM_DESC(rtt0, "reference rout trip time (ms)"); @@ -38,7 +39,7 @@ static inline void hybla_recalc_param (struct sock *sk) ca->rho_3ls = max_t(u32, tcp_sk(sk)->srtt / msecs_to_jiffies(rtt0), 8); ca->rho = ca->rho_3ls >> 3; ca->rho2_7ls = (ca->rho_3ls * ca->rho_3ls) << 1; - ca->rho2 = ca->rho2_7ls >> 7; + ca->rho2 = ca->rho2_7ls >>7; } static void hybla_init(struct sock *sk) @@ -51,7 +52,7 @@ static void hybla_init(struct sock *sk) ca->rho_3ls = 0; ca->rho2_7ls = 0; ca->snd_cwnd_cents = 0; - ca->hybla_en = true; + ca->hybla_en = 1; tp->snd_cwnd = 2; tp->snd_cwnd_clamp = 65535; @@ -66,7 +67,6 @@ static void hybla_init(struct sock *sk) static void hybla_state(struct sock *sk, u8 ca_state) { struct hybla *ca = inet_csk_ca(sk); - ca->hybla_en = (ca_state == TCP_CA_Open); } diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index cfa2aa128342..eb58b94301ec 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -196,10 +196,9 @@ static void tcp_enter_quickack_mode(struct sock *sk) * and the session is not interactive. */ -static inline bool tcp_in_quickack_mode(const struct sock *sk) +static inline int tcp_in_quickack_mode(const struct sock *sk) { const struct inet_connection_sock *icsk = inet_csk(sk); - return icsk->icsk_ack.quick && !icsk->icsk_ack.pingpong; } @@ -254,11 +253,11 @@ static inline void TCP_ECN_rcv_syn(struct tcp_sock *tp, const struct tcphdr *th) tp->ecn_flags &= ~TCP_ECN_OK; } -static bool TCP_ECN_rcv_ecn_echo(const struct tcp_sock *tp, const struct tcphdr *th) +static inline int TCP_ECN_rcv_ecn_echo(const struct tcp_sock *tp, const struct tcphdr *th) { if (th->ece && !th->syn && (tp->ecn_flags & TCP_ECN_OK)) - return true; - return false; + return 1; + return 0; } /* Buffer size and advertised window tuning. @@ -982,12 +981,12 @@ static void tcp_update_reordering(struct sock *sk, const int metric, NET_INC_STATS_BH(sock_net(sk), mib_idx); #if FASTRETRANS_DEBUG > 1 - pr_debug("Disorder%d %d %u f%u s%u rr%d\n", - tp->rx_opt.sack_ok, inet_csk(sk)->icsk_ca_state, - tp->reordering, - tp->fackets_out, - tp->sacked_out, - tp->undo_marker ? tp->undo_retrans : 0); + printk(KERN_DEBUG "Disorder%d %d %u f%u s%u rr%d\n", + tp->rx_opt.sack_ok, inet_csk(sk)->icsk_ca_state, + tp->reordering, + tp->fackets_out, + tp->sacked_out, + tp->undo_marker ? tp->undo_retrans : 0); #endif tcp_disable_fack(tp); } @@ -1124,36 +1123,36 @@ static void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp, * the exact amount is rather hard to quantify. However, tp->max_window can * be used as an exaggerated estimate. */ -static bool tcp_is_sackblock_valid(struct tcp_sock *tp, bool is_dsack, - u32 start_seq, u32 end_seq) +static int tcp_is_sackblock_valid(struct tcp_sock *tp, int is_dsack, + u32 start_seq, u32 end_seq) { /* Too far in future, or reversed (interpretation is ambiguous) */ if (after(end_seq, tp->snd_nxt) || !before(start_seq, end_seq)) - return false; + return 0; /* Nasty start_seq wrap-around check (see comments above) */ if (!before(start_seq, tp->snd_nxt)) - return false; + return 0; /* In outstanding window? ...This is valid exit for D-SACKs too. * start_seq == snd_una is non-sensical (see comments above) */ if (after(start_seq, tp->snd_una)) - return true; + return 1; if (!is_dsack || !tp->undo_marker) - return false; + return 0; /* ...Then it's D-SACK, and must reside below snd_una completely */ if (after(end_seq, tp->snd_una)) - return false; + return 0; if (!before(start_seq, tp->undo_marker)) - return true; + return 1; /* Too old */ if (!after(end_seq, tp->undo_marker)) - return false; + return 0; /* Undo_marker boundary crossing (overestimates a lot). Known already: * start_seq < undo_marker and end_seq >= undo_marker. @@ -1225,17 +1224,17 @@ static void tcp_mark_lost_retrans(struct sock *sk) tp->lost_retrans_low = new_low_seq; } -static bool tcp_check_dsack(struct sock *sk, const struct sk_buff *ack_skb, - struct tcp_sack_block_wire *sp, int num_sacks, - u32 prior_snd_una) +static int tcp_check_dsack(struct sock *sk, const struct sk_buff *ack_skb, + struct tcp_sack_block_wire *sp, int num_sacks, + u32 prior_snd_una) { struct tcp_sock *tp = tcp_sk(sk); u32 start_seq_0 = get_unaligned_be32(&sp[0].start_seq); u32 end_seq_0 = get_unaligned_be32(&sp[0].end_seq); - bool dup_sack = false; + int dup_sack = 0; if (before(start_seq_0, TCP_SKB_CB(ack_skb)->ack_seq)) { - dup_sack = true; + dup_sack = 1; tcp_dsack_seen(tp); NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPDSACKRECV); } else if (num_sacks > 1) { @@ -1244,7 +1243,7 @@ static bool tcp_check_dsack(struct sock *sk, const struct sk_buff *ack_skb, if (!after(end_seq_0, end_seq_1) && !before(start_seq_0, start_seq_1)) { - dup_sack = true; + dup_sack = 1; tcp_dsack_seen(tp); NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPDSACKOFORECV); @@ -1275,10 +1274,9 @@ struct tcp_sacktag_state { * FIXME: this could be merged to shift decision code */ static int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb, - u32 start_seq, u32 end_seq) + u32 start_seq, u32 end_seq) { - int err; - bool in_sack; + int in_sack, err; unsigned int pkt_len; unsigned int mss; @@ -1324,7 +1322,7 @@ static int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb, static u8 tcp_sacktag_one(struct sock *sk, struct tcp_sacktag_state *state, u8 sacked, u32 start_seq, u32 end_seq, - bool dup_sack, int pcount) + int dup_sack, int pcount) { struct tcp_sock *tp = tcp_sk(sk); int fack_count = state->fack_count; @@ -1404,10 +1402,10 @@ static u8 tcp_sacktag_one(struct sock *sk, /* Shift newly-SACKed bytes from this skb to the immediately previous * already-SACKed sk_buff. Mark the newly-SACKed bytes as such. */ -static bool tcp_shifted_skb(struct sock *sk, struct sk_buff *skb, - struct tcp_sacktag_state *state, - unsigned int pcount, int shifted, int mss, - bool dup_sack) +static int tcp_shifted_skb(struct sock *sk, struct sk_buff *skb, + struct tcp_sacktag_state *state, + unsigned int pcount, int shifted, int mss, + int dup_sack) { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *prev = tcp_write_queue_prev(sk, skb); @@ -1457,7 +1455,7 @@ static bool tcp_shifted_skb(struct sock *sk, struct sk_buff *skb, if (skb->len > 0) { BUG_ON(!tcp_skb_pcount(skb)); NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SACKSHIFTED); - return false; + return 0; } /* Whole SKB was eaten :-) */ @@ -1480,7 +1478,7 @@ static bool tcp_shifted_skb(struct sock *sk, struct sk_buff *skb, NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SACKMERGED); - return true; + return 1; } /* I wish gso_size would have a bit more sane initialization than @@ -1503,7 +1501,7 @@ static int skb_can_shift(const struct sk_buff *skb) static struct sk_buff *tcp_shift_skb_data(struct sock *sk, struct sk_buff *skb, struct tcp_sacktag_state *state, u32 start_seq, u32 end_seq, - bool dup_sack) + int dup_sack) { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *prev; @@ -1642,14 +1640,14 @@ static struct sk_buff *tcp_sacktag_walk(struct sk_buff *skb, struct sock *sk, struct tcp_sack_block *next_dup, struct tcp_sacktag_state *state, u32 start_seq, u32 end_seq, - bool dup_sack_in) + int dup_sack_in) { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *tmp; tcp_for_write_queue_from(skb, sk) { int in_sack = 0; - bool dup_sack = dup_sack_in; + int dup_sack = dup_sack_in; if (skb == tcp_send_head(sk)) break; @@ -1664,7 +1662,7 @@ static struct sk_buff *tcp_sacktag_walk(struct sk_buff *skb, struct sock *sk, next_dup->start_seq, next_dup->end_seq); if (in_sack > 0) - dup_sack = true; + dup_sack = 1; } /* skb reference here is a bit tricky to get right, since @@ -1769,7 +1767,7 @@ tcp_sacktag_write_queue(struct sock *sk, const struct sk_buff *ack_skb, struct sk_buff *skb; int num_sacks = min(TCP_NUM_SACKS, (ptr[1] - TCPOLEN_SACK_BASE) >> 3); int used_sacks; - bool found_dup_sack = false; + int found_dup_sack = 0; int i, j; int first_sack_index; @@ -1800,7 +1798,7 @@ tcp_sacktag_write_queue(struct sock *sk, const struct sk_buff *ack_skb, used_sacks = 0; first_sack_index = 0; for (i = 0; i < num_sacks; i++) { - bool dup_sack = !i && found_dup_sack; + int dup_sack = !i && found_dup_sack; sp[used_sacks].start_seq = get_unaligned_be32(&sp_wire[i].start_seq); sp[used_sacks].end_seq = get_unaligned_be32(&sp_wire[i].end_seq); @@ -1867,7 +1865,7 @@ tcp_sacktag_write_queue(struct sock *sk, const struct sk_buff *ack_skb, while (i < used_sacks) { u32 start_seq = sp[i].start_seq; u32 end_seq = sp[i].end_seq; - bool dup_sack = (found_dup_sack && (i == first_sack_index)); + int dup_sack = (found_dup_sack && (i == first_sack_index)); struct tcp_sack_block *next_dup = NULL; if (found_dup_sack && ((i + 1) == first_sack_index)) @@ -1969,9 +1967,9 @@ tcp_sacktag_write_queue(struct sock *sk, const struct sk_buff *ack_skb, } /* Limits sacked_out so that sum with lost_out isn't ever larger than - * packets_out. Returns false if sacked_out adjustement wasn't necessary. + * packets_out. Returns zero if sacked_out adjustement wasn't necessary. */ -static bool tcp_limit_reno_sacked(struct tcp_sock *tp) +static int tcp_limit_reno_sacked(struct tcp_sock *tp) { u32 holes; @@ -1980,9 +1978,9 @@ static bool tcp_limit_reno_sacked(struct tcp_sock *tp) if ((tp->sacked_out + holes) > tp->packets_out) { tp->sacked_out = tp->packets_out - holes; - return true; + return 1; } - return false; + return 0; } /* If we receive more dupacks than we expected counting segments @@ -2036,40 +2034,40 @@ static int tcp_is_sackfrto(const struct tcp_sock *tp) /* F-RTO can only be used if TCP has never retransmitted anything other than * head (SACK enhanced variant from Appendix B of RFC4138 is more robust here) */ -bool tcp_use_frto(struct sock *sk) +int tcp_use_frto(struct sock *sk) { const struct tcp_sock *tp = tcp_sk(sk); const struct inet_connection_sock *icsk = inet_csk(sk); struct sk_buff *skb; if (!sysctl_tcp_frto) - return false; + return 0; /* MTU probe and F-RTO won't really play nicely along currently */ if (icsk->icsk_mtup.probe_size) - return false; + return 0; if (tcp_is_sackfrto(tp)) - return true; + return 1; /* Avoid expensive walking of rexmit queue if possible */ if (tp->retrans_out > 1) - return false; + return 0; skb = tcp_write_queue_head(sk); if (tcp_skb_is_last(sk, skb)) - return true; + return 1; skb = tcp_write_queue_next(sk, skb); /* Skips head */ tcp_for_write_queue_from(skb, sk) { if (skb == tcp_send_head(sk)) break; if (TCP_SKB_CB(skb)->sacked & TCPCB_RETRANS) - return false; + return 0; /* Short-circuit when first non-SACKed skb has been checked */ if (!(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)) break; } - return true; + return 1; } /* RTO occurred, but do not yet enter Loss state. Instead, defer RTO @@ -2305,7 +2303,7 @@ void tcp_enter_loss(struct sock *sk, int how) * * Do processing similar to RTO timeout. */ -static bool tcp_check_sack_reneging(struct sock *sk, int flag) +static int tcp_check_sack_reneging(struct sock *sk, int flag) { if (flag & FLAG_SACK_RENEGING) { struct inet_connection_sock *icsk = inet_csk(sk); @@ -2316,9 +2314,9 @@ static bool tcp_check_sack_reneging(struct sock *sk, int flag) tcp_retransmit_skb(sk, tcp_write_queue_head(sk)); inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX); - return true; + return 1; } - return false; + return 0; } static inline int tcp_fackets_out(const struct tcp_sock *tp) @@ -2474,28 +2472,28 @@ static inline int tcp_head_timedout(const struct sock *sk) * Main question: may we further continue forward transmission * with the same cwnd? */ -static bool tcp_time_to_recover(struct sock *sk, int flag) +static int tcp_time_to_recover(struct sock *sk, int flag) { struct tcp_sock *tp = tcp_sk(sk); __u32 packets_out; /* Do not perform any recovery during F-RTO algorithm */ if (tp->frto_counter) - return false; + return 0; /* Trick#1: The loss is proven. */ if (tp->lost_out) - return true; + return 1; /* Not-A-Trick#2 : Classic rule... */ if (tcp_dupack_heuristics(tp) > tp->reordering) - return true; + return 1; /* Trick#3 : when we use RFC2988 timer restart, fast * retransmit can be triggered by timeout of queue head. */ if (tcp_is_fack(tp) && tcp_head_timedout(sk)) - return true; + return 1; /* Trick#4: It is still not OK... But will it be useful to delay * recovery more? @@ -2507,7 +2505,7 @@ static bool tcp_time_to_recover(struct sock *sk, int flag) /* We have nothing to send. This connection is limited * either by receiver window or by application. */ - return true; + return 1; } /* If a thin stream is detected, retransmit after first @@ -2518,7 +2516,7 @@ static bool tcp_time_to_recover(struct sock *sk, int flag) if ((tp->thin_dupack || sysctl_tcp_thin_dupack) && tcp_stream_is_thin(tp) && tcp_dupack_heuristics(tp) > 1 && tcp_is_sack(tp) && !tcp_send_head(sk)) - return true; + return 1; /* Trick#6: TCP early retransmit, per RFC5827. To avoid spurious * retransmissions due to small network reorderings, we implement @@ -2530,7 +2528,7 @@ static bool tcp_time_to_recover(struct sock *sk, int flag) !tcp_may_send_now(sk)) return !tcp_pause_early_retransmit(sk, flag); - return false; + return 0; } /* New heuristics: it is possible only after we switched to restart timer @@ -2718,22 +2716,22 @@ static void DBGUNDO(struct sock *sk, const char *msg) struct inet_sock *inet = inet_sk(sk); if (sk->sk_family == AF_INET) { - pr_debug("Undo %s %pI4/%u c%u l%u ss%u/%u p%u\n", - msg, - &inet->inet_daddr, ntohs(inet->inet_dport), - tp->snd_cwnd, tcp_left_out(tp), - tp->snd_ssthresh, tp->prior_ssthresh, - tp->packets_out); + printk(KERN_DEBUG "Undo %s %pI4/%u c%u l%u ss%u/%u p%u\n", + msg, + &inet->inet_daddr, ntohs(inet->inet_dport), + tp->snd_cwnd, tcp_left_out(tp), + tp->snd_ssthresh, tp->prior_ssthresh, + tp->packets_out); } #if IS_ENABLED(CONFIG_IPV6) else if (sk->sk_family == AF_INET6) { struct ipv6_pinfo *np = inet6_sk(sk); - pr_debug("Undo %s %pI6/%u c%u l%u ss%u/%u p%u\n", - msg, - &np->daddr, ntohs(inet->inet_dport), - tp->snd_cwnd, tcp_left_out(tp), - tp->snd_ssthresh, tp->prior_ssthresh, - tp->packets_out); + printk(KERN_DEBUG "Undo %s %pI6/%u c%u l%u ss%u/%u p%u\n", + msg, + &np->daddr, ntohs(inet->inet_dport), + tp->snd_cwnd, tcp_left_out(tp), + tp->snd_ssthresh, tp->prior_ssthresh, + tp->packets_out); } #endif } @@ -2769,7 +2767,7 @@ static inline int tcp_may_undo(const struct tcp_sock *tp) } /* People celebrate: "We love our President!" */ -static bool tcp_try_undo_recovery(struct sock *sk) +static int tcp_try_undo_recovery(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); @@ -2794,10 +2792,10 @@ static bool tcp_try_undo_recovery(struct sock *sk) * is ACKed. For Reno it is MUST to prevent false * fast retransmits (RFC2582). SACK TCP is safe. */ tcp_moderate_cwnd(tp); - return true; + return 1; } tcp_set_ca_state(sk, TCP_CA_Open); - return false; + return 0; } /* Try to undo cwnd reduction, because D-SACKs acked all retransmitted data */ @@ -2827,19 +2825,19 @@ static void tcp_try_undo_dsack(struct sock *sk) * that successive retransmissions of a segment must not advance * retrans_stamp under any conditions. */ -static bool tcp_any_retrans_done(const struct sock *sk) +static int tcp_any_retrans_done(const struct sock *sk) { const struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb; if (tp->retrans_out) - return true; + return 1; skb = tcp_write_queue_head(sk); if (unlikely(skb && TCP_SKB_CB(skb)->sacked & TCPCB_EVER_RETRANS)) - return true; + return 1; - return false; + return 0; } /* Undo during fast recovery after partial ACK. */ @@ -2873,7 +2871,7 @@ static int tcp_try_undo_partial(struct sock *sk, int acked) } /* Undo during loss recovery after partial ACK. */ -static bool tcp_try_undo_loss(struct sock *sk) +static int tcp_try_undo_loss(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); @@ -2895,9 +2893,9 @@ static bool tcp_try_undo_loss(struct sock *sk) tp->undo_marker = 0; if (tcp_is_sack(tp)) tcp_set_ca_state(sk, TCP_CA_Open); - return true; + return 1; } - return false; + return 0; } static inline void tcp_complete_cwr(struct sock *sk) @@ -3372,7 +3370,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets, const struct inet_connection_sock *icsk = inet_csk(sk); struct sk_buff *skb; u32 now = tcp_time_stamp; - int fully_acked = true; + int fully_acked = 1; int flag = 0; u32 pkts_acked = 0; u32 reord = tp->packets_out; @@ -3396,7 +3394,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets, if (!acked_pcount) break; - fully_acked = false; + fully_acked = 0; } else { acked_pcount = tcp_skb_pcount(skb); } @@ -3513,18 +3511,18 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets, if (!tp->packets_out && tcp_is_sack(tp)) { icsk = inet_csk(sk); if (tp->lost_out) { - pr_debug("Leak l=%u %d\n", - tp->lost_out, icsk->icsk_ca_state); + printk(KERN_DEBUG "Leak l=%u %d\n", + tp->lost_out, icsk->icsk_ca_state); tp->lost_out = 0; } if (tp->sacked_out) { - pr_debug("Leak s=%u %d\n", - tp->sacked_out, icsk->icsk_ca_state); + printk(KERN_DEBUG "Leak s=%u %d\n", + tp->sacked_out, icsk->icsk_ca_state); tp->sacked_out = 0; } if (tp->retrans_out) { - pr_debug("Leak r=%u %d\n", - tp->retrans_out, icsk->icsk_ca_state); + printk(KERN_DEBUG "Leak r=%u %d\n", + tp->retrans_out, icsk->icsk_ca_state); tp->retrans_out = 0; } } @@ -3675,7 +3673,7 @@ static void tcp_undo_spur_to_response(struct sock *sk, int flag) * to prove that the RTO is indeed spurious. It transfers the control * from F-RTO to the conventional RTO recovery */ -static bool tcp_process_frto(struct sock *sk, int flag) +static int tcp_process_frto(struct sock *sk, int flag) { struct tcp_sock *tp = tcp_sk(sk); @@ -3691,7 +3689,7 @@ static bool tcp_process_frto(struct sock *sk, int flag) if (!before(tp->snd_una, tp->frto_highmark)) { tcp_enter_frto_loss(sk, (tp->frto_counter == 1 ? 2 : 3), flag); - return true; + return 1; } if (!tcp_is_sackfrto(tp)) { @@ -3700,19 +3698,19 @@ static bool tcp_process_frto(struct sock *sk, int flag) * data, winupdate */ if (!(flag & FLAG_ANY_PROGRESS) && (flag & FLAG_NOT_DUP)) - return true; + return 1; if (!(flag & FLAG_DATA_ACKED)) { tcp_enter_frto_loss(sk, (tp->frto_counter == 1 ? 0 : 3), flag); - return true; + return 1; } } else { if (!(flag & FLAG_DATA_ACKED) && (tp->frto_counter == 1)) { /* Prevent sending of new data. */ tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp)); - return true; + return 1; } if ((tp->frto_counter >= 2) && @@ -3722,10 +3720,10 @@ static bool tcp_process_frto(struct sock *sk, int flag) /* RFC4138 shortcoming (see comment above) */ if (!(flag & FLAG_FORWARD_PROGRESS) && (flag & FLAG_NOT_DUP)) - return true; + return 1; tcp_enter_frto_loss(sk, 3, flag); - return true; + return 1; } } @@ -3737,7 +3735,7 @@ static bool tcp_process_frto(struct sock *sk, int flag) if (!tcp_may_send_now(sk)) tcp_enter_frto_loss(sk, 2, flag); - return true; + return 1; } else { switch (sysctl_tcp_frto_response) { case 2: @@ -3754,7 +3752,7 @@ static bool tcp_process_frto(struct sock *sk, int flag) tp->undo_marker = 0; NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSPURIOUSRTOS); } - return false; + return 0; } /* This routine deals with incoming acks, but not outgoing ones. */ @@ -3772,7 +3770,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) int prior_sacked = tp->sacked_out; int pkts_acked = 0; int newly_acked_sacked = 0; - bool frto_cwnd = false; + int frto_cwnd = 0; /* If the ack is older than previous acks * then we can probably ignore it. @@ -3954,9 +3952,10 @@ void tcp_parse_options(const struct sk_buff *skb, struct tcp_options_received *o __u8 snd_wscale = *(__u8 *)ptr; opt_rx->wscale_ok = 1; if (snd_wscale > 14) { - net_info_ratelimited("%s: Illegal window scaling value %d >14 received\n", - __func__, - snd_wscale); + if (net_ratelimit()) + pr_info("%s: Illegal window scaling value %d >14 received\n", + __func__, + snd_wscale); snd_wscale = 14; } opt_rx->snd_wscale = snd_wscale; @@ -4027,7 +4026,7 @@ void tcp_parse_options(const struct sk_buff *skb, struct tcp_options_received *o } EXPORT_SYMBOL(tcp_parse_options); -static bool tcp_parse_aligned_timestamp(struct tcp_sock *tp, const struct tcphdr *th) +static int tcp_parse_aligned_timestamp(struct tcp_sock *tp, const struct tcphdr *th) { const __be32 *ptr = (const __be32 *)(th + 1); @@ -4038,31 +4037,31 @@ static bool tcp_parse_aligned_timestamp(struct tcp_sock *tp, const struct tcphdr tp->rx_opt.rcv_tsval = ntohl(*ptr); ++ptr; tp->rx_opt.rcv_tsecr = ntohl(*ptr); - return true; + return 1; } - return false; + return 0; } /* Fast parse options. This hopes to only see timestamps. * If it is wrong it falls back on tcp_parse_options(). */ -static bool tcp_fast_parse_options(const struct sk_buff *skb, - const struct tcphdr *th, - struct tcp_sock *tp, const u8 **hvpp) +static int tcp_fast_parse_options(const struct sk_buff *skb, + const struct tcphdr *th, + struct tcp_sock *tp, const u8 **hvpp) { /* In the spirit of fast parsing, compare doff directly to constant * values. Because equality is used, short doff can be ignored here. */ if (th->doff == (sizeof(*th) / 4)) { tp->rx_opt.saw_tstamp = 0; - return false; + return 0; } else if (tp->rx_opt.tstamp_ok && th->doff == ((sizeof(*th) + TCPOLEN_TSTAMP_ALIGNED) / 4)) { if (tcp_parse_aligned_timestamp(tp, th)) - return true; + return 1; } tcp_parse_options(skb, &tp->rx_opt, hvpp, 1); - return true; + return 1; } #ifdef CONFIG_TCP_MD5SIG @@ -4303,7 +4302,7 @@ static void tcp_fin(struct sock *sk) } } -static inline bool tcp_sack_extend(struct tcp_sack_block *sp, u32 seq, +static inline int tcp_sack_extend(struct tcp_sack_block *sp, u32 seq, u32 end_seq) { if (!after(seq, sp->end_seq) && !after(sp->start_seq, end_seq)) { @@ -4311,9 +4310,9 @@ static inline bool tcp_sack_extend(struct tcp_sack_block *sp, u32 seq, sp->start_seq = seq; if (after(end_seq, sp->end_seq)) sp->end_seq = end_seq; - return true; + return 1; } - return false; + return 0; } static void tcp_dsack_set(struct sock *sk, u32 seq, u32 end_seq) @@ -4509,10 +4508,10 @@ static void tcp_ofo_queue(struct sock *sk) } } -static bool tcp_prune_ofo_queue(struct sock *sk); +static int tcp_prune_ofo_queue(struct sock *sk); static int tcp_prune_queue(struct sock *sk); -static int tcp_try_rmem_schedule(struct sock *sk, unsigned int size) +static inline int tcp_try_rmem_schedule(struct sock *sk, unsigned int size) { if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || !sk_rmem_schedule(sk, size)) { @@ -4549,23 +4548,84 @@ static bool tcp_try_coalesce(struct sock *sk, struct sk_buff *from, bool *fragstolen) { - int delta; + int i, delta, len = from->len; *fragstolen = false; - if (tcp_hdr(from)->fin) + if (tcp_hdr(from)->fin || skb_cloned(to)) return false; - if (!skb_try_coalesce(to, from, fragstolen, &delta)) + + if (len <= skb_tailroom(to)) { + BUG_ON(skb_copy_bits(from, 0, skb_put(to, len), len)); + goto merge; + } + + if (skb_has_frag_list(to) || skb_has_frag_list(from)) return false; + if (skb_headlen(from) != 0) { + struct page *page; + unsigned int offset; + + if (skb_shinfo(to)->nr_frags + + skb_shinfo(from)->nr_frags >= MAX_SKB_FRAGS) + return false; + + if (skb_head_is_locked(from)) + return false; + + delta = from->truesize - SKB_DATA_ALIGN(sizeof(struct sk_buff)); + + page = virt_to_head_page(from->head); + offset = from->data - (unsigned char *)page_address(page); + + skb_fill_page_desc(to, skb_shinfo(to)->nr_frags, + page, offset, skb_headlen(from)); + *fragstolen = true; + } else { + if (skb_shinfo(to)->nr_frags + + skb_shinfo(from)->nr_frags > MAX_SKB_FRAGS) + return false; + + delta = from->truesize - + SKB_TRUESIZE(skb_end_pointer(from) - from->head); + } + + WARN_ON_ONCE(delta < len); + + memcpy(skb_shinfo(to)->frags + skb_shinfo(to)->nr_frags, + skb_shinfo(from)->frags, + skb_shinfo(from)->nr_frags * sizeof(skb_frag_t)); + skb_shinfo(to)->nr_frags += skb_shinfo(from)->nr_frags; + + if (!skb_cloned(from)) + skb_shinfo(from)->nr_frags = 0; + + /* if the skb is cloned this does nothing since we set nr_frags to 0 */ + for (i = 0; i < skb_shinfo(from)->nr_frags; i++) + skb_frag_ref(from, i); + + to->truesize += delta; atomic_add(delta, &sk->sk_rmem_alloc); sk_mem_charge(sk, delta); + to->len += len; + to->data_len += len; + +merge: NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPRCVCOALESCE); TCP_SKB_CB(to)->end_seq = TCP_SKB_CB(from)->end_seq; TCP_SKB_CB(to)->ack_seq = TCP_SKB_CB(from)->ack_seq; return true; } +static void kfree_skb_partial(struct sk_buff *skb, bool head_stolen) +{ + if (head_stolen) + kmem_cache_free(skbuff_head_cache, skb); + else + __kfree_skb(skb); +} + static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) { struct tcp_sock *tp = tcp_sk(sk); @@ -4686,7 +4746,7 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) skb_set_owner_r(skb, sk); } -static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int hdrlen, +int tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int hdrlen, bool *fragstolen) { int eaten; @@ -4703,42 +4763,6 @@ static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int return eaten; } -int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) -{ - struct sk_buff *skb; - struct tcphdr *th; - bool fragstolen; - - if (tcp_try_rmem_schedule(sk, size + sizeof(*th))) - goto err; - - skb = alloc_skb(size + sizeof(*th), sk->sk_allocation); - if (!skb) - goto err; - - th = (struct tcphdr *)skb_put(skb, sizeof(*th)); - skb_reset_transport_header(skb); - memset(th, 0, sizeof(*th)); - - if (memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size)) - goto err_free; - - TCP_SKB_CB(skb)->seq = tcp_sk(sk)->rcv_nxt; - TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + size; - TCP_SKB_CB(skb)->ack_seq = tcp_sk(sk)->snd_una - 1; - - if (tcp_queue_rcv(sk, skb, sizeof(*th), &fragstolen)) { - WARN_ON_ONCE(fragstolen); /* should not happen */ - __kfree_skb(skb); - } - return size; - -err_free: - kfree_skb(skb); -err: - return -ENOMEM; -} - static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) { const struct tcphdr *th = tcp_hdr(skb); @@ -5033,10 +5057,10 @@ static void tcp_collapse_ofo_queue(struct sock *sk) * Purge the out-of-order queue. * Return true if queue was pruned. */ -static bool tcp_prune_ofo_queue(struct sock *sk) +static int tcp_prune_ofo_queue(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); - bool res = false; + int res = 0; if (!skb_queue_empty(&tp->out_of_order_queue)) { NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_OFOPRUNED); @@ -5050,7 +5074,7 @@ static bool tcp_prune_ofo_queue(struct sock *sk) if (tp->rx_opt.sack_ok) tcp_sack_reset(&tp->rx_opt); sk_mem_reclaim(sk); - res = true; + res = 1; } return res; } @@ -5127,7 +5151,7 @@ void tcp_cwnd_application_limited(struct sock *sk) tp->snd_cwnd_stamp = tcp_time_stamp; } -static bool tcp_should_expand_sndbuf(const struct sock *sk) +static int tcp_should_expand_sndbuf(const struct sock *sk) { const struct tcp_sock *tp = tcp_sk(sk); @@ -5135,21 +5159,21 @@ static bool tcp_should_expand_sndbuf(const struct sock *sk) * not modify it. */ if (sk->sk_userlocks & SOCK_SNDBUF_LOCK) - return false; + return 0; /* If we are under global TCP memory pressure, do not expand. */ if (sk_under_memory_pressure(sk)) - return false; + return 0; /* If we are under soft global TCP memory pressure, do not expand. */ if (sk_memory_allocated(sk) >= sk_prot_mem_limits(sk, 0)) - return false; + return 0; /* If we filled the congestion window, do not expand. */ if (tp->packets_out >= tp->snd_cwnd) - return false; + return 0; - return true; + return 1; } /* When incoming ACK allowed to free some skb from write_queue, @@ -5375,16 +5399,16 @@ static inline int tcp_checksum_complete_user(struct sock *sk, } #ifdef CONFIG_NET_DMA -static bool tcp_dma_try_early_copy(struct sock *sk, struct sk_buff *skb, +static int tcp_dma_try_early_copy(struct sock *sk, struct sk_buff *skb, int hlen) { struct tcp_sock *tp = tcp_sk(sk); int chunk = skb->len - hlen; int dma_cookie; - bool copied_early = false; + int copied_early = 0; if (tp->ucopy.wakeup) - return false; + return 0; if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list) tp->ucopy.dma_chan = net_dma_find_channel(); @@ -5400,7 +5424,7 @@ static bool tcp_dma_try_early_copy(struct sock *sk, struct sk_buff *skb, goto out; tp->ucopy.dma_cookie = dma_cookie; - copied_early = true; + copied_early = 1; tp->ucopy.len -= chunk; tp->copied_seq += chunk; diff --git a/trunk/net/ipv4/tcp_ipv4.c b/trunk/net/ipv4/tcp_ipv4.c index a43b87dfe800..4ff5e1f70d16 100644 --- a/trunk/net/ipv4/tcp_ipv4.c +++ b/trunk/net/ipv4/tcp_ipv4.c @@ -866,14 +866,14 @@ static void tcp_v4_reqsk_destructor(struct request_sock *req) } /* - * Return true if a syncookie should be sent + * Return 1 if a syncookie should be sent */ -bool tcp_syn_flood_action(struct sock *sk, +int tcp_syn_flood_action(struct sock *sk, const struct sk_buff *skb, const char *proto) { const char *msg = "Dropping request"; - bool want_cookie = false; + int want_cookie = 0; struct listen_sock *lopt; @@ -881,7 +881,7 @@ bool tcp_syn_flood_action(struct sock *sk, #ifdef CONFIG_SYN_COOKIES if (sysctl_tcp_syncookies) { msg = "Sending cookies"; - want_cookie = true; + want_cookie = 1; NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPREQQFULLDOCOOKIES); } else #endif @@ -1196,7 +1196,7 @@ int tcp_v4_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key, } EXPORT_SYMBOL(tcp_v4_md5_hash_skb); -static bool tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) +static int tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) { /* * This gets called for each TCP segment that arrives @@ -1219,16 +1219,16 @@ static bool tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) /* We've parsed the options - do we have a hash? */ if (!hash_expected && !hash_location) - return false; + return 0; if (hash_expected && !hash_location) { NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5NOTFOUND); - return true; + return 1; } if (!hash_expected && hash_location) { NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5UNEXPECTED); - return true; + return 1; } /* Okay, so this is hash_expected and hash_location - @@ -1239,14 +1239,15 @@ static bool tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) NULL, NULL, skb); if (genhash || memcmp(hash_location, newhash, 16) != 0) { - net_info_ratelimited("MD5 Hash failed for (%pI4, %d)->(%pI4, %d)%s\n", - &iph->saddr, ntohs(th->source), - &iph->daddr, ntohs(th->dest), - genhash ? " tcp_v4_calc_md5_hash failed" - : ""); - return true; + if (net_ratelimit()) { + pr_info("MD5 Hash failed for (%pI4, %d)->(%pI4, %d)%s\n", + &iph->saddr, ntohs(th->source), + &iph->daddr, ntohs(th->dest), + genhash ? " tcp_v4_calc_md5_hash failed" : ""); + } + return 1; } - return false; + return 0; } #endif @@ -1280,7 +1281,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) __be32 saddr = ip_hdr(skb)->saddr; __be32 daddr = ip_hdr(skb)->daddr; __u32 isn = TCP_SKB_CB(skb)->when; - bool want_cookie = false; + int want_cookie = 0; /* Never answer to SYNs send to broadcast or multicast */ if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) @@ -1339,7 +1340,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) while (l-- > 0) *c++ ^= *hash_location++; - want_cookie = false; /* not our kind of cookie */ + want_cookie = 0; /* not our kind of cookie */ tmp_ext.cookie_out_never = 0; /* false */ tmp_ext.cookie_plus = tmp_opt.cookie_plus; } else if (!tp->rx_opt.cookie_in_always) { @@ -2073,7 +2074,7 @@ static void *listening_get_idx(struct seq_file *seq, loff_t *pos) return rc; } -static inline bool empty_bucket(struct tcp_iter_state *st) +static inline int empty_bucket(struct tcp_iter_state *st) { return hlist_nulls_empty(&tcp_hashinfo.ehash[st->bucket].chain) && hlist_nulls_empty(&tcp_hashinfo.ehash[st->bucket].twchain); diff --git a/trunk/net/ipv4/tcp_minisocks.c b/trunk/net/ipv4/tcp_minisocks.c index b85d9fe7d663..6f6a91832826 100644 --- a/trunk/net/ipv4/tcp_minisocks.c +++ b/trunk/net/ipv4/tcp_minisocks.c @@ -55,7 +55,7 @@ EXPORT_SYMBOL_GPL(tcp_death_row); * state. */ -static bool tcp_remember_stamp(struct sock *sk) +static int tcp_remember_stamp(struct sock *sk) { const struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); @@ -72,13 +72,13 @@ static bool tcp_remember_stamp(struct sock *sk) } if (release_it) inet_putpeer(peer); - return true; + return 1; } - return false; + return 0; } -static bool tcp_tw_remember_stamp(struct inet_timewait_sock *tw) +static int tcp_tw_remember_stamp(struct inet_timewait_sock *tw) { struct sock *sk = (struct sock *) tw; struct inet_peer *peer; @@ -94,17 +94,17 @@ static bool tcp_tw_remember_stamp(struct inet_timewait_sock *tw) peer->tcp_ts = tcptw->tw_ts_recent; } inet_putpeer(peer); - return true; + return 1; } - return false; + return 0; } -static bool tcp_in_window(u32 seq, u32 end_seq, u32 s_win, u32 e_win) +static __inline__ int tcp_in_window(u32 seq, u32 end_seq, u32 s_win, u32 e_win) { if (seq == s_win) - return true; + return 1; if (after(end_seq, s_win) && before(seq, e_win)) - return true; + return 1; return seq == e_win && seq == end_seq; } @@ -143,7 +143,7 @@ tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb, struct tcp_options_received tmp_opt; const u8 *hash_location; struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); - bool paws_reject = false; + int paws_reject = 0; tmp_opt.saw_tstamp = 0; if (th->doff > (sizeof(*th) >> 2) && tcptw->tw_ts_recent_stamp) { @@ -316,7 +316,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) struct inet_timewait_sock *tw = NULL; const struct inet_connection_sock *icsk = inet_csk(sk); const struct tcp_sock *tp = tcp_sk(sk); - bool recycle_ok = false; + int recycle_ok = 0; if (tcp_death_row.sysctl_tw_recycle && tp->rx_opt.ts_recent_stamp) recycle_ok = tcp_remember_stamp(sk); @@ -575,7 +575,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, struct sock *child; const struct tcphdr *th = tcp_hdr(skb); __be32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK); - bool paws_reject = false; + int paws_reject = 0; tmp_opt.saw_tstamp = 0; if (th->doff > (sizeof(struct tcphdr)>>2)) { diff --git a/trunk/net/ipv4/tcp_output.c b/trunk/net/ipv4/tcp_output.c index 803cbfe82fbc..d94733009923 100644 --- a/trunk/net/ipv4/tcp_output.c +++ b/trunk/net/ipv4/tcp_output.c @@ -34,8 +34,6 @@ * */ -#define pr_fmt(fmt) "TCP: " fmt - #include #include @@ -370,7 +368,7 @@ static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags) TCP_SKB_CB(skb)->end_seq = seq; } -static inline bool tcp_urg_mode(const struct tcp_sock *tp) +static inline int tcp_urg_mode(const struct tcp_sock *tp) { return tp->snd_una != tp->snd_up; } @@ -1391,20 +1389,20 @@ static int tcp_init_tso_segs(const struct sock *sk, struct sk_buff *skb, } /* Minshall's variant of the Nagle send check. */ -static inline bool tcp_minshall_check(const struct tcp_sock *tp) +static inline int tcp_minshall_check(const struct tcp_sock *tp) { return after(tp->snd_sml, tp->snd_una) && !after(tp->snd_sml, tp->snd_nxt); } -/* Return false, if packet can be sent now without violation Nagle's rules: +/* Return 0, if packet can be sent now without violation Nagle's rules: * 1. It is full sized. * 2. Or it contains FIN. (already checked by caller) * 3. Or TCP_CORK is not set, and TCP_NODELAY is set. * 4. Or TCP_CORK is not set, and all sent packets are ACKed. * With Minshall's modification: all sent small packets are ACKed. */ -static inline bool tcp_nagle_check(const struct tcp_sock *tp, +static inline int tcp_nagle_check(const struct tcp_sock *tp, const struct sk_buff *skb, unsigned int mss_now, int nonagle) { @@ -1413,11 +1411,11 @@ static inline bool tcp_nagle_check(const struct tcp_sock *tp, (!nonagle && tp->packets_out && tcp_minshall_check(tp))); } -/* Return true if the Nagle test allows this packet to be +/* Return non-zero if the Nagle test allows this packet to be * sent now. */ -static inline bool tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buff *skb, - unsigned int cur_mss, int nonagle) +static inline int tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buff *skb, + unsigned int cur_mss, int nonagle) { /* Nagle rule does not apply to frames, which sit in the middle of the * write_queue (they have no chances to get new data). @@ -1426,25 +1424,24 @@ static inline bool tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buf * argument based upon the location of SKB in the send queue. */ if (nonagle & TCP_NAGLE_PUSH) - return true; + return 1; /* Don't use the nagle rule for urgent data (or for the final FIN). * Nagle can be ignored during F-RTO too (see RFC4138). */ if (tcp_urg_mode(tp) || (tp->frto_counter == 2) || (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)) - return true; + return 1; if (!tcp_nagle_check(tp, skb, cur_mss, nonagle)) - return true; + return 1; - return false; + return 0; } /* Does at least the first segment of SKB fit into the send window? */ -static bool tcp_snd_wnd_test(const struct tcp_sock *tp, - const struct sk_buff *skb, - unsigned int cur_mss) +static inline int tcp_snd_wnd_test(const struct tcp_sock *tp, const struct sk_buff *skb, + unsigned int cur_mss) { u32 end_seq = TCP_SKB_CB(skb)->end_seq; @@ -1477,7 +1474,7 @@ static unsigned int tcp_snd_test(const struct sock *sk, struct sk_buff *skb, } /* Test if sending is allowed right now. */ -bool tcp_may_send_now(struct sock *sk) +int tcp_may_send_now(struct sock *sk) { const struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb = tcp_send_head(sk); @@ -1547,7 +1544,7 @@ static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len, * * This algorithm is from John Heffner. */ -static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) +static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) { struct tcp_sock *tp = tcp_sk(sk); const struct inet_connection_sock *icsk = inet_csk(sk); @@ -1607,11 +1604,11 @@ static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) /* Ok, it looks like it is advisable to defer. */ tp->tso_deferred = 1 | (jiffies << 1); - return true; + return 1; send_now: tp->tso_deferred = 0; - return false; + return 0; } /* Create a new MTU probe if we are ready. @@ -1753,11 +1750,11 @@ static int tcp_mtu_probe(struct sock *sk) * snd_up-64k-mss .. snd_up cannot be large. However, taking into * account rare use of URG, this is not a big flaw. * - * Returns true, if no segments are in flight and we have queued segments, - * but cannot send anything now because of SWS or another problem. + * Returns 1, if no segments are in flight and we have queued segments, but + * cannot send anything now because of SWS or another problem. */ -static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, - int push_one, gfp_t gfp) +static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, + int push_one, gfp_t gfp) { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb; @@ -1771,7 +1768,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, /* Do MTU probing. */ result = tcp_mtu_probe(sk); if (!result) { - return false; + return 0; } else if (result > 0) { sent_pkts = 1; } @@ -1830,7 +1827,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, if (likely(sent_pkts)) { tcp_cwnd_validate(sk); - return false; + return 0; } return !tp->packets_out && tcp_send_head(sk); } @@ -2029,22 +2026,22 @@ static void tcp_collapse_retrans(struct sock *sk, struct sk_buff *skb) } /* Check if coalescing SKBs is legal. */ -static bool tcp_can_collapse(const struct sock *sk, const struct sk_buff *skb) +static int tcp_can_collapse(const struct sock *sk, const struct sk_buff *skb) { if (tcp_skb_pcount(skb) > 1) - return false; + return 0; /* TODO: SACK collapsing could be used to remove this condition */ if (skb_shinfo(skb)->nr_frags != 0) - return false; + return 0; if (skb_cloned(skb)) - return false; + return 0; if (skb == tcp_send_head(sk)) - return false; + return 0; /* Some heurestics for collapsing over SACK'd could be invented */ if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED) - return false; + return 0; - return true; + return 1; } /* Collapse packets in the retransmit queue to make to create @@ -2055,7 +2052,7 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *to, { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb = to, *tmp; - bool first = true; + int first = 1; if (!sysctl_tcp_retrans_collapse) return; @@ -2069,7 +2066,7 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *to, space -= skb->len; if (first) { - first = false; + first = 0; continue; } @@ -2184,7 +2181,8 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) #if FASTRETRANS_DEBUG > 0 if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS) { - net_dbg_ratelimited("retrans_out leaked\n"); + if (net_ratelimit()) + printk(KERN_DEBUG "retrans_out leaked.\n"); } #endif if (!tp->retrans_out) @@ -2209,18 +2207,18 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) /* Check if we forward retransmits are possible in the current * window/congestion state. */ -static bool tcp_can_forward_retransmit(struct sock *sk) +static int tcp_can_forward_retransmit(struct sock *sk) { const struct inet_connection_sock *icsk = inet_csk(sk); const struct tcp_sock *tp = tcp_sk(sk); /* Forward retransmissions are possible only during Recovery. */ if (icsk->icsk_ca_state != TCP_CA_Recovery) - return false; + return 0; /* No forward retransmissions in Reno are possible. */ if (tcp_is_reno(tp)) - return false; + return 0; /* Yeah, we have to make difficult choice between forward transmission * and retransmission... Both ways have their merits... @@ -2231,9 +2229,9 @@ static bool tcp_can_forward_retransmit(struct sock *sk) */ if (tcp_may_send_now(sk)) - return false; + return 0; - return true; + return 1; } /* This gets called after a retransmit timeout, and the initially @@ -2418,7 +2416,7 @@ int tcp_send_synack(struct sock *sk) skb = tcp_write_queue_head(sk); if (skb == NULL || !(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN)) { - pr_debug("%s: wrong queue state\n", __func__); + printk(KERN_DEBUG "tcp_send_synack: wrong queue state\n"); return -EFAULT; } if (!(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_ACK)) { diff --git a/trunk/net/ipv4/udp.c b/trunk/net/ipv4/udp.c index 609397ee78fb..279fd0846302 100644 --- a/trunk/net/ipv4/udp.c +++ b/trunk/net/ipv4/udp.c @@ -2173,15 +2173,9 @@ void udp4_proc_exit(void) static __initdata unsigned long uhash_entries; static int __init set_uhash_entries(char *str) { - ssize_t ret; - if (!str) return 0; - - ret = kstrtoul(str, 0, &uhash_entries); - if (ret) - return 0; - + uhash_entries = simple_strtoul(str, &str, 0); if (uhash_entries && uhash_entries < UDP_HTABLE_SIZE_MIN) uhash_entries = UDP_HTABLE_SIZE_MIN; return 1; diff --git a/trunk/net/ipv6/Kconfig b/trunk/net/ipv6/Kconfig index 5728695b5449..36d7437ac054 100644 --- a/trunk/net/ipv6/Kconfig +++ b/trunk/net/ipv6/Kconfig @@ -69,7 +69,7 @@ config IPV6_OPTIMISTIC_DAD config INET6_AH tristate "IPv6: AH transformation" - select XFRM_ALGO + select XFRM select CRYPTO select CRYPTO_HMAC select CRYPTO_MD5 @@ -81,7 +81,7 @@ config INET6_AH config INET6_ESP tristate "IPv6: ESP transformation" - select XFRM_ALGO + select XFRM select CRYPTO select CRYPTO_AUTHENC select CRYPTO_HMAC diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index 8f6411c97189..e3b3421f8dad 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -38,8 +38,6 @@ * status etc. */ -#define pr_fmt(fmt) "IPv6: " fmt - #include #include #include @@ -68,7 +66,6 @@ #include #include -#include #include #include #include @@ -329,11 +326,11 @@ void in6_dev_finish_destroy(struct inet6_dev *idev) WARN_ON(idev->mc_list != NULL); #ifdef NET_REFCNT_DEBUG - pr_debug("%s: %s\n", __func__, dev ? dev->name : "NIL"); + printk(KERN_DEBUG "in6_dev_finish_destroy: %s\n", dev ? dev->name : "NIL"); #endif dev_put(dev); if (!idev->dead) { - pr_warn("Freeing alive inet6 device %p\n", idev); + pr_warning("Freeing alive inet6 device %p\n", idev); return; } snmp6_free_dev(idev); @@ -374,7 +371,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev) if (snmp6_alloc_dev(ndev) < 0) { ADBG((KERN_WARNING - "%s: cannot allocate memory for statistics; dev=%s.\n", + "%s(): cannot allocate memory for statistics; dev=%s.\n", __func__, dev->name)); neigh_parms_release(&nd_tbl, ndev->nd_parms); dev_put(dev); @@ -384,7 +381,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev) if (snmp6_register_dev(ndev) < 0) { ADBG((KERN_WARNING - "%s: cannot create /proc/net/dev_snmp6/%s\n", + "%s(): cannot create /proc/net/dev_snmp6/%s\n", __func__, dev->name)); neigh_parms_release(&nd_tbl, ndev->nd_parms); ndev->dead = 1; @@ -402,7 +399,9 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev) #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) { - pr_info("%s: Disabled Multicast RS\n", dev->name); + printk(KERN_INFO + "%s: Disabled Multicast RS\n", + dev->name); ndev->cnf.rtr_solicits = 0; } #endif @@ -542,7 +541,7 @@ void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp) WARN_ON(!hlist_unhashed(&ifp->addr_lst)); #ifdef NET_REFCNT_DEBUG - pr_debug("%s\n", __func__); + printk(KERN_DEBUG "inet6_ifa_finish_destroy\n"); #endif in6_dev_put(ifp->idev); @@ -551,7 +550,7 @@ void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp) pr_notice("Timer is still running, when freeing ifa=%p\n", ifp); if (ifp->state != INET6_IFADDR_STATE_DEAD) { - pr_warn("Freeing alive inet6 address %p\n", ifp); + pr_warning("Freeing alive inet6 address %p\n", ifp); return; } dst_release(&ifp->rt->dst); @@ -841,7 +840,8 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i in6_dev_hold(idev); if (idev->cnf.use_tempaddr <= 0) { write_unlock(&idev->lock); - pr_info("%s: use_tempaddr is disabled\n", __func__); + printk(KERN_INFO + "ipv6_create_tempaddr(): use_tempaddr is disabled.\n"); in6_dev_put(idev); ret = -1; goto out; @@ -851,8 +851,8 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i idev->cnf.use_tempaddr = -1; /*XXX*/ spin_unlock_bh(&ifp->lock); write_unlock(&idev->lock); - pr_warn("%s: regeneration time exceeded - disabled temporary address support\n", - __func__); + printk(KERN_WARNING + "ipv6_create_tempaddr(): regeneration time exceeded. disabled temporary address support.\n"); in6_dev_put(idev); ret = -1; goto out; @@ -862,8 +862,8 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i if (__ipv6_try_regen_rndid(idev, tmpaddr) < 0) { spin_unlock_bh(&ifp->lock); write_unlock(&idev->lock); - pr_warn("%s: regeneration of randomized interface id failed\n", - __func__); + printk(KERN_WARNING + "ipv6_create_tempaddr(): regeneration of randomized interface id failed.\n"); in6_ifa_put(ifp); in6_dev_put(idev); ret = -1; @@ -913,7 +913,8 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i if (!ift || IS_ERR(ift)) { in6_ifa_put(ifp); in6_dev_put(idev); - pr_info("%s: retry temporary address regeneration\n", __func__); + printk(KERN_INFO + "ipv6_create_tempaddr(): retry temporary address regeneration.\n"); tmpaddr = &addr; write_lock(&idev->lock); goto retry; @@ -1413,8 +1414,9 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp) return; } - net_info_ratelimited("%s: IPv6 duplicate address %pI6c detected!\n", - ifp->idev->dev->name, &ifp->addr); + if (net_ratelimit()) + printk(KERN_INFO "%s: IPv6 duplicate address %pI6c detected!\n", + ifp->idev->dev->name, &ifp->addr); if (idev->cnf.accept_dad > 1 && !idev->cnf.disable_ipv6) { struct in6_addr addr; @@ -1427,7 +1429,7 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp) /* DAD failed for link-local based on MAC address */ idev->cnf.disable_ipv6 = 1; - pr_info("%s: IPv6 being disabled!\n", + printk(KERN_INFO "%s: IPv6 being disabled!\n", ifp->idev->dev->name); } } @@ -1512,14 +1514,6 @@ static int addrconf_ifid_eui48(u8 *eui, struct net_device *dev) return 0; } -static int addrconf_ifid_eui64(u8 *eui, struct net_device *dev) -{ - if (dev->addr_len != IEEE802154_ADDR_LEN) - return -1; - memcpy(eui, dev->dev_addr, 8); - return 0; -} - static int addrconf_ifid_arcnet(u8 *eui, struct net_device *dev) { /* XXX: inherit EUI-64 from other interface -- yoshfuji */ @@ -1573,6 +1567,7 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev) switch (dev->type) { case ARPHRD_ETHER: case ARPHRD_FDDI: + case ARPHRD_IEEE802_TR: return addrconf_ifid_eui48(eui, dev); case ARPHRD_ARCNET: return addrconf_ifid_arcnet(eui, dev); @@ -1582,8 +1577,6 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev) return addrconf_ifid_sit(eui, dev); case ARPHRD_IPGRE: return addrconf_ifid_gre(eui, dev); - case ARPHRD_IEEE802154: - return addrconf_ifid_eui64(eui, dev); } return -1; } @@ -1657,8 +1650,9 @@ static void ipv6_regen_rndid(unsigned long data) idev->cnf.regen_max_retry * idev->cnf.dad_transmits * idev->nd_parms->retrans_time - idev->cnf.max_desync_factor * HZ; if (time_before(expires, jiffies)) { - pr_warn("%s: too short regeneration interval; timer disabled for %s\n", - __func__, idev->dev->name); + printk(KERN_WARNING + "ipv6_regen_rndid(): too short regeneration interval; timer disabled for %s.\n", + idev->dev->name); goto out; } @@ -1842,15 +1836,16 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) prefered_lft = ntohl(pinfo->prefered); if (prefered_lft > valid_lft) { - net_warn_ratelimited("addrconf: prefix option has invalid lifetime\n"); + if (net_ratelimit()) + printk(KERN_WARNING "addrconf: prefix option has invalid lifetime\n"); return; } in6_dev = in6_dev_get(dev); if (in6_dev == NULL) { - net_dbg_ratelimited("addrconf: device %s not configured\n", - dev->name); + if (net_ratelimit()) + printk(KERN_DEBUG "addrconf: device %s not configured\n", dev->name); return; } @@ -1925,8 +1920,9 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) } goto ok; } - net_dbg_ratelimited("IPv6 addrconf: prefix with wrong length %d\n", - pinfo->prefix_len); + if (net_ratelimit()) + printk(KERN_DEBUG "IPv6 addrconf: prefix with wrong length %d\n", + pinfo->prefix_len); in6_dev_put(in6_dev); return; @@ -2404,7 +2400,7 @@ static void init_loopback(struct net_device *dev) ASSERT_RTNL(); if ((idev = ipv6_find_idev(dev)) == NULL) { - pr_debug("%s: add_dev failed\n", __func__); + printk(KERN_DEBUG "init loopback: add_dev failed\n"); return; } @@ -2440,9 +2436,9 @@ static void addrconf_dev_config(struct net_device *dev) if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_FDDI) && + (dev->type != ARPHRD_IEEE802_TR) && (dev->type != ARPHRD_ARCNET) && - (dev->type != ARPHRD_INFINIBAND) && - (dev->type != ARPHRD_IEEE802154)) { + (dev->type != ARPHRD_INFINIBAND)) { /* Alas, we support only Ethernet autoconfiguration. */ return; } @@ -2472,7 +2468,7 @@ static void addrconf_sit_config(struct net_device *dev) */ if ((idev = ipv6_find_idev(dev)) == NULL) { - pr_debug("%s: add_dev failed\n", __func__); + printk(KERN_DEBUG "init sit: add_dev failed\n"); return; } @@ -2502,12 +2498,12 @@ static void addrconf_gre_config(struct net_device *dev) struct inet6_dev *idev; struct in6_addr addr; - pr_info("%s(%s)\n", __func__, dev->name); + pr_info("ipv6: addrconf_gre_config(%s)\n", dev->name); ASSERT_RTNL(); if ((idev = ipv6_find_idev(dev)) == NULL) { - pr_debug("%s: add_dev failed\n", __func__); + printk(KERN_DEBUG "init gre: add_dev failed\n"); return; } @@ -2547,7 +2543,7 @@ static void ip6_tnl_add_linklocal(struct inet6_dev *idev) if (!ipv6_inherit_linklocal(idev, link_dev)) return; } - pr_debug("init ip6-ip6: add_linklocal failed\n"); + printk(KERN_DEBUG "init ip6-ip6: add_linklocal failed\n"); } /* @@ -2563,7 +2559,7 @@ static void addrconf_ip6_tnl_config(struct net_device *dev) idev = addrconf_add_dev(dev); if (IS_ERR(idev)) { - pr_debug("init ip6-ip6: add_dev failed\n"); + printk(KERN_DEBUG "init ip6-ip6: add_dev failed\n"); return; } ip6_tnl_add_linklocal(idev); @@ -2594,7 +2590,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, if (event == NETDEV_UP) { if (!addrconf_qdisc_ok(dev)) { /* device is not ready yet. */ - pr_info("ADDRCONF(NETDEV_UP): %s: link is not ready\n", + printk(KERN_INFO + "ADDRCONF(NETDEV_UP): %s: " + "link is not ready\n", dev->name); break; } @@ -2619,8 +2617,10 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, idev->if_flags |= IF_READY; } - pr_info("ADDRCONF(NETDEV_CHANGE): %s: link becomes ready\n", - dev->name); + printk(KERN_INFO + "ADDRCONF(NETDEV_CHANGE): %s: " + "link becomes ready\n", + dev->name); run_pending = 1; } @@ -2891,7 +2891,8 @@ static void addrconf_rs_timer(unsigned long data) * Note: we do not support deprecated "all on-link" * assumption any longer. */ - pr_debug("%s: no IPv6 routers present\n", idev->dev->name); + printk(KERN_DEBUG "%s: no IPv6 routers present\n", + idev->dev->name); } out: @@ -4747,8 +4748,8 @@ int __init addrconf_init(void) err = ipv6_addr_label_init(); if (err < 0) { - pr_crit("%s: cannot initialize default policy table: %d\n", - __func__, err); + printk(KERN_CRIT "IPv6 Addrconf:" + " cannot initialize default policy table: %d.\n", err); goto out; } diff --git a/trunk/net/ipv6/addrlabel.c b/trunk/net/ipv6/addrlabel.c index eb6a63632d3c..2d8ddba9ee58 100644 --- a/trunk/net/ipv6/addrlabel.c +++ b/trunk/net/ipv6/addrlabel.c @@ -129,7 +129,7 @@ static void ip6addrlbl_free_rcu(struct rcu_head *h) ip6addrlbl_free(container_of(h, struct ip6addrlbl_entry, rcu)); } -static bool ip6addrlbl_hold(struct ip6addrlbl_entry *p) +static inline int ip6addrlbl_hold(struct ip6addrlbl_entry *p) { return atomic_inc_not_zero(&p->refcnt); } @@ -141,20 +141,20 @@ static inline void ip6addrlbl_put(struct ip6addrlbl_entry *p) } /* Find label */ -static bool __ip6addrlbl_match(struct net *net, - const struct ip6addrlbl_entry *p, - const struct in6_addr *addr, - int addrtype, int ifindex) +static int __ip6addrlbl_match(struct net *net, + struct ip6addrlbl_entry *p, + const struct in6_addr *addr, + int addrtype, int ifindex) { if (!net_eq(ip6addrlbl_net(p), net)) - return false; + return 0; if (p->ifindex && p->ifindex != ifindex) - return false; + return 0; if (p->addrtype && p->addrtype != addrtype) - return false; + return 0; if (!ipv6_prefix_equal(addr, &p->prefix, p->prefixlen)) - return false; - return true; + return 0; + return 1; } static struct ip6addrlbl_entry *__ipv6_addr_label(struct net *net, @@ -350,7 +350,7 @@ static int __net_init ip6addrlbl_net_init(struct net *net) int err = 0; int i; - ADDRLABEL(KERN_DEBUG "%s\n", __func__); + ADDRLABEL(KERN_DEBUG "%s()\n", __func__); for (i = 0; i < ARRAY_SIZE(ip6addrlbl_init_table); i++) { int ret = ip6addrlbl_add(net, @@ -456,8 +456,8 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh, return err; } -static void ip6addrlbl_putmsg(struct nlmsghdr *nlh, - int prefixlen, int ifindex, u32 lseq) +static inline void ip6addrlbl_putmsg(struct nlmsghdr *nlh, + int prefixlen, int ifindex, u32 lseq) { struct ifaddrlblmsg *ifal = nlmsg_data(nlh); ifal->ifal_family = AF_INET6; diff --git a/trunk/net/ipv6/af_inet6.c b/trunk/net/ipv6/af_inet6.c index e22e6d88bac6..0ad046c7ae95 100644 --- a/trunk/net/ipv6/af_inet6.c +++ b/trunk/net/ipv6/af_inet6.c @@ -18,7 +18,6 @@ * 2 of the License, or (at your option) any later version. */ -#define pr_fmt(fmt) "IPv6: " fmt #include #include @@ -78,7 +77,7 @@ struct ipv6_params ipv6_defaults = { .autoconf = 1, }; -static int disable_ipv6_mod; +static int disable_ipv6_mod = 0; module_param_named(disable, disable_ipv6_mod, int, 0444); MODULE_PARM_DESC(disable, "Disable IPv6 module such that it is non-functional"); @@ -257,7 +256,7 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol, /* bind for INET6 API */ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) { - struct sockaddr_in6 *addr = (struct sockaddr_in6 *)uaddr; + struct sockaddr_in6 *addr=(struct sockaddr_in6 *)uaddr; struct sock *sk = sock->sk; struct inet_sock *inet = inet_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk); @@ -391,6 +390,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) rcu_read_unlock(); goto out; } + EXPORT_SYMBOL(inet6_bind); int inet6_release(struct socket *sock) @@ -408,6 +408,7 @@ int inet6_release(struct socket *sock) return inet_release(sock); } + EXPORT_SYMBOL(inet6_release); void inet6_destroy_sock(struct sock *sk) @@ -418,12 +419,10 @@ void inet6_destroy_sock(struct sock *sk) /* Release rx options */ - skb = xchg(&np->pktoptions, NULL); - if (skb != NULL) + if ((skb = xchg(&np->pktoptions, NULL)) != NULL) kfree_skb(skb); - skb = xchg(&np->rxpmtu, NULL); - if (skb != NULL) + if ((skb = xchg(&np->rxpmtu, NULL)) != NULL) kfree_skb(skb); /* Free flowlabels */ @@ -431,10 +430,10 @@ void inet6_destroy_sock(struct sock *sk) /* Free tx options */ - opt = xchg(&np->opt, NULL); - if (opt != NULL) + if ((opt = xchg(&np->opt, NULL)) != NULL) sock_kfree_s(sk, opt, opt->tot_len); } + EXPORT_SYMBOL_GPL(inet6_destroy_sock); /* @@ -444,7 +443,7 @@ EXPORT_SYMBOL_GPL(inet6_destroy_sock); int inet6_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer) { - struct sockaddr_in6 *sin = (struct sockaddr_in6 *)uaddr; + struct sockaddr_in6 *sin=(struct sockaddr_in6 *)uaddr; struct sock *sk = sock->sk; struct inet_sock *inet = inet_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk); @@ -475,6 +474,7 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr, *uaddr_len = sizeof(*sin); return 0; } + EXPORT_SYMBOL(inet6_getname); int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) @@ -482,7 +482,8 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) struct sock *sk = sock->sk; struct net *net = sock_net(sk); - switch (cmd) { + switch(cmd) + { case SIOCGSTAMP: return sock_get_timestamp(sk, (struct timeval __user *)arg); @@ -508,6 +509,7 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) /*NOTREACHED*/ return 0; } + EXPORT_SYMBOL(inet6_ioctl); const struct proto_ops inet6_stream_ops = { @@ -613,21 +615,25 @@ int inet6_register_protosw(struct inet_protosw *p) return ret; out_permanent: - pr_err("Attempt to override permanent protocol %d\n", protocol); + printk(KERN_ERR "Attempt to override permanent protocol %d.\n", + protocol); goto out; out_illegal: - pr_err("Ignoring attempt to register invalid socket type %d\n", + printk(KERN_ERR + "Ignoring attempt to register invalid socket type %d.\n", p->type); goto out; } + EXPORT_SYMBOL(inet6_register_protosw); void inet6_unregister_protosw(struct inet_protosw *p) { if (INET_PROTOSW_PERMANENT & p->flags) { - pr_err("Attempt to unregister permanent protocol %d\n", + printk(KERN_ERR + "Attempt to unregister permanent protocol %d.\n", p->protocol); } else { spin_lock_bh(&inetsw6_lock); @@ -637,6 +643,7 @@ inet6_unregister_protosw(struct inet_protosw *p) synchronize_net(); } } + EXPORT_SYMBOL(inet6_unregister_protosw); int inet6_sk_rebuild_header(struct sock *sk) @@ -676,12 +683,13 @@ int inet6_sk_rebuild_header(struct sock *sk) return 0; } + EXPORT_SYMBOL_GPL(inet6_sk_rebuild_header); -bool ipv6_opt_accepted(const struct sock *sk, const struct sk_buff *skb) +int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb) { - const struct ipv6_pinfo *np = inet6_sk(sk); - const struct inet6_skb_parm *opt = IP6CB(skb); + struct ipv6_pinfo *np = inet6_sk(sk); + struct inet6_skb_parm *opt = IP6CB(skb); if (np->rxopt.all) { if ((opt->hop && (np->rxopt.bits.hopopts || @@ -693,10 +701,11 @@ bool ipv6_opt_accepted(const struct sock *sk, const struct sk_buff *skb) np->rxopt.bits.osrcrt)) || ((opt->dst1 || opt->dst0) && (np->rxopt.bits.dstopts || np->rxopt.bits.odstopts))) - return true; + return 1; } - return false; + return 0; } + EXPORT_SYMBOL_GPL(ipv6_opt_accepted); static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto) @@ -1061,11 +1070,13 @@ static int __init inet6_init(void) BUILD_BUG_ON(sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb)); /* Register the socket-side information for inet6_create. */ - for (r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r) + for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r) INIT_LIST_HEAD(r); if (disable_ipv6_mod) { - pr_info("Loaded, but administratively disabled, reboot required to enable\n"); + printk(KERN_INFO + "IPv6: Loaded, but administratively disabled, " + "reboot required to enable\n"); goto out; } diff --git a/trunk/net/ipv6/ah6.c b/trunk/net/ipv6/ah6.c index f1a4a2c28ed3..2ae79dbeec2f 100644 --- a/trunk/net/ipv6/ah6.c +++ b/trunk/net/ipv6/ah6.c @@ -24,8 +24,6 @@ * This file is derived from net/ipv4/ah.c. */ -#define pr_fmt(fmt) "IPv6: " fmt - #include #include #include @@ -113,7 +111,7 @@ static inline struct scatterlist *ah_req_sg(struct crypto_ahash *ahash, __alignof__(struct scatterlist)); } -static bool zero_out_mutable_opts(struct ipv6_opt_hdr *opthdr) +static int zero_out_mutable_opts(struct ipv6_opt_hdr *opthdr) { u8 *opt = (u8 *)opthdr; int len = ipv6_optlen(opthdr); @@ -127,7 +125,7 @@ static bool zero_out_mutable_opts(struct ipv6_opt_hdr *opthdr) switch (opt[off]) { - case IPV6_TLV_PAD1: + case IPV6_TLV_PAD0: optlen = 1; break; default: @@ -145,10 +143,10 @@ static bool zero_out_mutable_opts(struct ipv6_opt_hdr *opthdr) len -= optlen; } if (len == 0) - return true; + return 1; bad: - return false; + return 0; } #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) @@ -171,7 +169,7 @@ static void ipv6_rearrange_destopt(struct ipv6hdr *iph, struct ipv6_opt_hdr *des switch (opt[off]) { - case IPV6_TLV_PAD1: + case IPV6_TLV_PAD0: optlen = 1; break; default: @@ -191,8 +189,8 @@ static void ipv6_rearrange_destopt(struct ipv6hdr *iph, struct ipv6_opt_hdr *des hao = (struct ipv6_destopt_hao *)&opt[off]; if (hao->length != sizeof(hao->addr)) { - net_warn_ratelimited("destopt hao: invalid header length: %u\n", - hao->length); + if (net_ratelimit()) + printk(KERN_WARNING "destopt hao: invalid header length: %u\n", hao->length); goto bad; } final_addr = hao->addr; @@ -661,9 +659,9 @@ static int ah6_init_state(struct xfrm_state *x) if (aalg_desc->uinfo.auth.icv_fullbits/8 != crypto_ahash_digestsize(ahash)) { - pr_info("AH: %s digestsize %u != %hu\n", - x->aalg->alg_name, crypto_ahash_digestsize(ahash), - aalg_desc->uinfo.auth.icv_fullbits/8); + printk(KERN_INFO "AH: %s digestsize %u != %hu\n", + x->aalg->alg_name, crypto_ahash_digestsize(ahash), + aalg_desc->uinfo.auth.icv_fullbits/8); goto error; } @@ -729,12 +727,12 @@ static const struct inet6_protocol ah6_protocol = { static int __init ah6_init(void) { if (xfrm_register_type(&ah6_type, AF_INET6) < 0) { - pr_info("%s: can't add xfrm type\n", __func__); + printk(KERN_INFO "ipv6 ah init: can't add xfrm type\n"); return -EAGAIN; } if (inet6_add_protocol(&ah6_protocol, IPPROTO_AH) < 0) { - pr_info("%s: can't add protocol\n", __func__); + printk(KERN_INFO "ipv6 ah init: can't add protocol\n"); xfrm_unregister_type(&ah6_type, AF_INET6); return -EAGAIN; } @@ -745,10 +743,10 @@ static int __init ah6_init(void) static void __exit ah6_fini(void) { if (inet6_del_protocol(&ah6_protocol, IPPROTO_AH) < 0) - pr_info("%s: can't remove protocol\n", __func__); + printk(KERN_INFO "ipv6 ah close: can't remove protocol\n"); if (xfrm_unregister_type(&ah6_type, AF_INET6) < 0) - pr_info("%s: can't remove xfrm type\n", __func__); + printk(KERN_INFO "ipv6 ah close: can't remove xfrm type\n"); } diff --git a/trunk/net/ipv6/anycast.c b/trunk/net/ipv6/anycast.c index cdf02be5f191..db00d27ffb16 100644 --- a/trunk/net/ipv6/anycast.c +++ b/trunk/net/ipv6/anycast.c @@ -342,7 +342,7 @@ static int ipv6_dev_ac_dec(struct net_device *dev, const struct in6_addr *addr) * check if the interface has this anycast address * called with rcu_read_lock() */ -static bool ipv6_chk_acast_dev(struct net_device *dev, const struct in6_addr *addr) +static int ipv6_chk_acast_dev(struct net_device *dev, const struct in6_addr *addr) { struct inet6_dev *idev; struct ifacaddr6 *aca; @@ -356,16 +356,16 @@ static bool ipv6_chk_acast_dev(struct net_device *dev, const struct in6_addr *ad read_unlock_bh(&idev->lock); return aca != NULL; } - return false; + return 0; } /* * check if given interface (or any, if dev==0) has this anycast address */ -bool ipv6_chk_acast_addr(struct net *net, struct net_device *dev, - const struct in6_addr *addr) +int ipv6_chk_acast_addr(struct net *net, struct net_device *dev, + const struct in6_addr *addr) { - bool found = false; + int found = 0; rcu_read_lock(); if (dev) @@ -373,7 +373,7 @@ bool ipv6_chk_acast_addr(struct net *net, struct net_device *dev, else for_each_netdev_rcu(net, dev) if (ipv6_chk_acast_dev(dev, addr)) { - found = true; + found = 1; break; } rcu_read_unlock(); diff --git a/trunk/net/ipv6/datagram.c b/trunk/net/ipv6/datagram.c index be2b67d631e5..b8b61ac88bc2 100644 --- a/trunk/net/ipv6/datagram.c +++ b/trunk/net/ipv6/datagram.c @@ -34,9 +34,9 @@ #include #include -static bool ipv6_mapped_addr_any(const struct in6_addr *a) +static inline int ipv6_mapped_addr_any(const struct in6_addr *a) { - return ipv6_addr_v4mapped(a) && (a->s6_addr32[3] == 0); + return (ipv6_addr_v4mapped(a) && (a->s6_addr32[3] == 0)); } int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) diff --git a/trunk/net/ipv6/esp6.c b/trunk/net/ipv6/esp6.c index 1e62b7557b00..1ac7938dd9ec 100644 --- a/trunk/net/ipv6/esp6.c +++ b/trunk/net/ipv6/esp6.c @@ -24,8 +24,6 @@ * This file is derived from net/ipv4/esp.c */ -#define pr_fmt(fmt) "IPv6: " fmt - #include #include #include @@ -444,8 +442,8 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, esph->spi, IPPROTO_ESP, AF_INET6); if (!x) return; - pr_debug("pmtu discovery on SA ESP/%08x/%pI6\n", - ntohl(esph->spi), &iph->daddr); + printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%pI6\n", + ntohl(esph->spi), &iph->daddr); xfrm_state_put(x); } @@ -653,11 +651,11 @@ static const struct inet6_protocol esp6_protocol = { static int __init esp6_init(void) { if (xfrm_register_type(&esp6_type, AF_INET6) < 0) { - pr_info("%s: can't add xfrm type\n", __func__); + printk(KERN_INFO "ipv6 esp init: can't add xfrm type\n"); return -EAGAIN; } if (inet6_add_protocol(&esp6_protocol, IPPROTO_ESP) < 0) { - pr_info("%s: can't add protocol\n", __func__); + printk(KERN_INFO "ipv6 esp init: can't add protocol\n"); xfrm_unregister_type(&esp6_type, AF_INET6); return -EAGAIN; } @@ -668,9 +666,9 @@ static int __init esp6_init(void) static void __exit esp6_fini(void) { if (inet6_del_protocol(&esp6_protocol, IPPROTO_ESP) < 0) - pr_info("%s: can't remove protocol\n", __func__); + printk(KERN_INFO "ipv6 esp close: can't remove protocol\n"); if (xfrm_unregister_type(&esp6_type, AF_INET6) < 0) - pr_info("%s: can't remove xfrm type\n", __func__); + printk(KERN_INFO "ipv6 esp close: can't remove xfrm type\n"); } module_init(esp6_init); diff --git a/trunk/net/ipv6/exthdrs.c b/trunk/net/ipv6/exthdrs.c index 6447dc49429f..a93bd231eca1 100644 --- a/trunk/net/ipv6/exthdrs.c +++ b/trunk/net/ipv6/exthdrs.c @@ -75,7 +75,7 @@ int ipv6_find_tlv(struct sk_buff *skb, int offset, int type) return offset; switch (opttype) { - case IPV6_TLV_PAD1: + case IPV6_TLV_PAD0: optlen = 1; break; default: @@ -96,14 +96,14 @@ EXPORT_SYMBOL_GPL(ipv6_find_tlv); /* * Parsing tlv encoded headers. * - * Parsing function "func" returns true, if parsing succeed - * and false, if it failed. + * Parsing function "func" returns 1, if parsing succeed + * and 0, if it failed. * It MUST NOT touch skb->h. */ struct tlvtype_proc { int type; - bool (*func)(struct sk_buff *skb, int offset); + int (*func)(struct sk_buff *skb, int offset); }; /********************* @@ -112,11 +112,11 @@ struct tlvtype_proc { /* An unknown option is detected, decide what to do */ -static bool ip6_tlvopt_unknown(struct sk_buff *skb, int optoff) +static int ip6_tlvopt_unknown(struct sk_buff *skb, int optoff) { switch ((skb_network_header(skb)[optoff] & 0xC0) >> 6) { case 0: /* ignore */ - return true; + return 1; case 1: /* drop packet */ break; @@ -129,22 +129,21 @@ static bool ip6_tlvopt_unknown(struct sk_buff *skb, int optoff) break; case 2: /* send ICMP PARM PROB regardless and drop packet */ icmpv6_param_prob(skb, ICMPV6_UNK_OPTION, optoff); - return false; + return 0; } kfree_skb(skb); - return false; + return 0; } /* Parse tlv encoded option header (hop-by-hop or destination) */ -static bool ip6_parse_tlv(const struct tlvtype_proc *procs, struct sk_buff *skb) +static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff *skb) { - const struct tlvtype_proc *curr; + struct tlvtype_proc *curr; const unsigned char *nh = skb_network_header(skb); int off = skb_network_header_len(skb); int len = (skb_transport_header(skb)[1] + 1) << 3; - int padlen = 0; if (skb_transport_offset(skb) + len > skb_headlen(skb)) goto bad; @@ -157,11 +156,8 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs, struct sk_buff *skb) int i; switch (nh[off]) { - case IPV6_TLV_PAD1: + case IPV6_TLV_PAD0: optlen = 1; - padlen++; - if (padlen > 7) - goto bad; break; case IPV6_TLV_PADN: @@ -170,8 +166,7 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs, struct sk_buff *skb) * of 8. 7 is therefore the highest valid value. * See also RFC 4942, Section 2.1.9.5. */ - padlen += optlen; - if (padlen > 7) + if (optlen > 7) goto bad; /* RFC 4942 recommends receiving hosts to * actively check PadN payload to contain @@ -191,33 +186,25 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs, struct sk_buff *skb) /* type specific length/alignment checks will be performed in the func(). */ - if (curr->func(skb, off) == false) - return false; + if (curr->func(skb, off) == 0) + return 0; break; } } if (curr->type < 0) { if (ip6_tlvopt_unknown(skb, off) == 0) - return false; + return 0; } - padlen = 0; break; } off += optlen; len -= optlen; } - /* This case will not be caught by above check since its padding - * length is smaller than 7: - * 1 byte NH + 1 byte Length + 6 bytes Padding - */ - if ((padlen == 6) && ((off - skb_network_header_len(skb)) == 8)) - goto bad; - if (len == 0) - return true; + return 1; bad: kfree_skb(skb); - return false; + return 0; } /***************************** @@ -225,7 +212,7 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs, struct sk_buff *skb) *****************************/ #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) -static bool ipv6_dest_hao(struct sk_buff *skb, int optoff) +static int ipv6_dest_hao(struct sk_buff *skb, int optoff) { struct ipv6_destopt_hao *hao; struct inet6_skb_parm *opt = IP6CB(skb); @@ -279,15 +266,15 @@ static bool ipv6_dest_hao(struct sk_buff *skb, int optoff) if (skb->tstamp.tv64 == 0) __net_timestamp(skb); - return true; + return 1; discard: kfree_skb(skb); - return false; + return 0; } #endif -static const struct tlvtype_proc tlvprocdestopt_lst[] = { +static struct tlvtype_proc tlvprocdestopt_lst[] = { #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) { .type = IPV6_TLV_HAO, @@ -592,23 +579,23 @@ static inline struct net *ipv6_skb_net(struct sk_buff *skb) /* Router Alert as of RFC 2711 */ -static bool ipv6_hop_ra(struct sk_buff *skb, int optoff) +static int ipv6_hop_ra(struct sk_buff *skb, int optoff) { const unsigned char *nh = skb_network_header(skb); if (nh[optoff + 1] == 2) { IP6CB(skb)->ra = optoff; - return true; + return 1; } LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n", nh[optoff + 1]); kfree_skb(skb); - return false; + return 0; } /* Jumbo payload */ -static bool ipv6_hop_jumbo(struct sk_buff *skb, int optoff) +static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff) { const unsigned char *nh = skb_network_header(skb); struct net *net = ipv6_skb_net(skb); @@ -627,13 +614,13 @@ static bool ipv6_hop_jumbo(struct sk_buff *skb, int optoff) IP6_INC_STATS_BH(net, ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); - return false; + return 0; } if (ipv6_hdr(skb)->payload_len) { IP6_INC_STATS_BH(net, ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff); - return false; + return 0; } if (pkt_len > skb->len - sizeof(struct ipv6hdr)) { @@ -645,14 +632,14 @@ static bool ipv6_hop_jumbo(struct sk_buff *skb, int optoff) if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr))) goto drop; - return true; + return 1; drop: kfree_skb(skb); - return false; + return 0; } -static const struct tlvtype_proc tlvprochopopt_lst[] = { +static struct tlvtype_proc tlvprochopopt_lst[] = { { .type = IPV6_TLV_ROUTERALERT, .func = ipv6_hop_ra, diff --git a/trunk/net/ipv6/exthdrs_core.c b/trunk/net/ipv6/exthdrs_core.c index f73d59a14131..7b1a884634d5 100644 --- a/trunk/net/ipv6/exthdrs_core.c +++ b/trunk/net/ipv6/exthdrs_core.c @@ -9,7 +9,7 @@ * find out if nexthdr is a well-known extension header or a protocol */ -bool ipv6_ext_hdr(u8 nexthdr) +int ipv6_ext_hdr(u8 nexthdr) { /* * find out if nexthdr is an extension header or a protocol diff --git a/trunk/net/ipv6/icmp.c b/trunk/net/ipv6/icmp.c index 091a2971c7b7..cc079d8d4681 100644 --- a/trunk/net/ipv6/icmp.c +++ b/trunk/net/ipv6/icmp.c @@ -29,8 +29,6 @@ * Kazunori MIYAZAWA @USAGI: change output process to use ip6_append_data */ -#define pr_fmt(fmt) "IPv6: " fmt - #include #include #include @@ -131,7 +129,7 @@ void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos) * --ANK (980726) */ -static bool is_ineligible(const struct sk_buff *skb) +static int is_ineligible(struct sk_buff *skb) { int ptr = (u8 *)(ipv6_hdr(skb) + 1) - skb->data; int len = skb->len - ptr; @@ -139,11 +137,11 @@ static bool is_ineligible(const struct sk_buff *skb) __be16 frag_off; if (len < 0) - return true; + return 1; ptr = ipv6_skip_exthdr(skb, ptr, &nexthdr, &frag_off); if (ptr < 0) - return false; + return 0; if (nexthdr == IPPROTO_ICMPV6) { u8 _type, *tp; tp = skb_header_pointer(skb, @@ -151,9 +149,9 @@ static bool is_ineligible(const struct sk_buff *skb) sizeof(_type), &_type); if (tp == NULL || !(*tp & ICMPV6_INFOMSG_MASK)) - return true; + return 1; } - return false; + return 0; } /* @@ -208,14 +206,14 @@ static inline bool icmpv6_xrlim_allow(struct sock *sk, u8 type, * highest-order two bits set to 10 */ -static bool opt_unrec(struct sk_buff *skb, __u32 offset) +static __inline__ int opt_unrec(struct sk_buff *skb, __u32 offset) { u8 _optval, *op; offset += skb_network_offset(skb); op = skb_header_pointer(skb, offset, sizeof(_optval), &_optval); if (op == NULL) - return true; + return 1; return (*op & 0xC0) == 0x80; } @@ -822,7 +820,9 @@ static int __net_init icmpv6_sk_init(struct net *net) err = inet_ctl_sock_create(&sk, PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, net); if (err < 0) { - pr_err("Failed to initialize the ICMP6 control socket (err %d)\n", + printk(KERN_ERR + "Failed to initialize the ICMP6 control socket " + "(err %d).\n", err); goto fail; } @@ -881,7 +881,7 @@ int __init icmpv6_init(void) return 0; fail: - pr_err("Failed to register ICMP6 protocol\n"); + printk(KERN_ERR "Failed to register ICMP6 protocol\n"); unregister_pernet_subsys(&icmpv6_sk_ops); return err; } diff --git a/trunk/net/ipv6/ip6_fib.c b/trunk/net/ipv6/ip6_fib.c index 0c220a416626..93717435013e 100644 --- a/trunk/net/ipv6/ip6_fib.c +++ b/trunk/net/ipv6/ip6_fib.c @@ -18,9 +18,6 @@ * routing table. * Ville Nuorvala: Fixed routing subtrees. */ - -#define pr_fmt(fmt) "IPv6: " fmt - #include #include #include @@ -41,7 +38,7 @@ #define RT6_DEBUG 2 #if RT6_DEBUG >= 3 -#define RT6_TRACE(x...) pr_debug(x) +#define RT6_TRACE(x...) printk(KERN_DEBUG x) #else #define RT6_TRACE(x...) do { ; } while (0) #endif @@ -454,10 +451,12 @@ static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr, !ipv6_prefix_equal(&key->addr, addr, fn->fn_bit)) { if (!allow_create) { if (replace_required) { - pr_warn("Can't replace route, no match found\n"); + pr_warn("IPv6: Can't replace route, " + "no match found\n"); return ERR_PTR(-ENOENT); } - pr_warn("NLM_F_CREATE should be set when creating new route\n"); + pr_warn("IPv6: NLM_F_CREATE should be set " + "when creating new route\n"); } goto insert_above; } @@ -500,10 +499,11 @@ static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr, * That would keep IPv6 consistent with IPv4 */ if (replace_required) { - pr_warn("Can't replace route, no match found\n"); + pr_warn("IPv6: Can't replace route, no match found\n"); return ERR_PTR(-ENOENT); } - pr_warn("NLM_F_CREATE should be set when creating new route\n"); + pr_warn("IPv6: NLM_F_CREATE should be set " + "when creating new route\n"); } /* * We walked to the bottom of tree. @@ -696,7 +696,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, */ if (!replace) { if (!add) - pr_warn("NLM_F_CREATE should be set when creating new route\n"); + pr_warn("IPv6: NLM_F_CREATE should be set when creating new route\n"); add: rt->dst.rt6_next = iter; @@ -715,7 +715,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, if (!found) { if (add) goto add; - pr_warn("NLM_F_REPLACE set, but no existing node found!\n"); + pr_warn("IPv6: NLM_F_REPLACE set, but no existing node found!\n"); return -ENOENT; } *ins = rt; @@ -768,7 +768,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info) replace_required = 1; } if (!allow_create && !replace_required) - pr_warn("RTM_NEWROUTE with no NLM_F_CREATE or NLM_F_REPLACE\n"); + pr_warn("IPv6: RTM_NEWROUTE with no NLM_F_CREATE or NLM_F_REPLACE\n"); fn = fib6_add_1(root, &rt->rt6i_dst.addr, sizeof(struct in6_addr), rt->rt6i_dst.plen, offsetof(struct rt6_info, rt6i_dst), @@ -1420,8 +1420,7 @@ static int fib6_clean_node(struct fib6_walker_t *w) res = fib6_del(rt, &info); if (res) { #if RT6_DEBUG >= 2 - pr_debug("%s: del failed: rt=%p@%p err=%d\n", - __func__, rt, rt->rt6i_node, res); + printk(KERN_DEBUG "fib6_clean_node: del failed: rt=%p@%p err=%d\n", rt, rt->rt6i_node, res); #endif continue; } diff --git a/trunk/net/ipv6/ip6_flowlabel.c b/trunk/net/ipv6/ip6_flowlabel.c index 9772fbd8a3f5..cb43df690210 100644 --- a/trunk/net/ipv6/ip6_flowlabel.c +++ b/trunk/net/ipv6/ip6_flowlabel.c @@ -433,32 +433,32 @@ static int mem_check(struct sock *sk) return 0; } -static bool ipv6_hdr_cmp(struct ipv6_opt_hdr *h1, struct ipv6_opt_hdr *h2) +static int ipv6_hdr_cmp(struct ipv6_opt_hdr *h1, struct ipv6_opt_hdr *h2) { if (h1 == h2) - return false; + return 0; if (h1 == NULL || h2 == NULL) - return true; + return 1; if (h1->hdrlen != h2->hdrlen) - return true; + return 1; return memcmp(h1+1, h2+1, ((h1->hdrlen+1)<<3) - sizeof(*h1)); } -static bool ipv6_opt_cmp(struct ipv6_txoptions *o1, struct ipv6_txoptions *o2) +static int ipv6_opt_cmp(struct ipv6_txoptions *o1, struct ipv6_txoptions *o2) { if (o1 == o2) - return false; + return 0; if (o1 == NULL || o2 == NULL) - return true; + return 1; if (o1->opt_nflen != o2->opt_nflen) - return true; + return 1; if (ipv6_hdr_cmp(o1->hopopt, o2->hopopt)) - return true; + return 1; if (ipv6_hdr_cmp(o1->dst0opt, o2->dst0opt)) - return true; + return 1; if (ipv6_hdr_cmp((struct ipv6_opt_hdr *)o1->srcrt, (struct ipv6_opt_hdr *)o2->srcrt)) - return true; - return false; + return 1; + return 0; } static inline void fl_link(struct ipv6_pinfo *np, struct ipv6_fl_socklist *sfl, diff --git a/trunk/net/ipv6/ip6_input.c b/trunk/net/ipv6/ip6_input.c index 21a15dfe4a9e..1ca5d45a12e8 100644 --- a/trunk/net/ipv6/ip6_input.c +++ b/trunk/net/ipv6/ip6_input.c @@ -170,8 +170,7 @@ static int ip6_input_finish(struct sk_buff *skb) { const struct inet6_protocol *ipprot; unsigned int nhoff; - int nexthdr; - bool raw; + int nexthdr, raw; u8 hash; struct inet6_dev *idev; struct net *net = dev_net(skb_dst(skb)->dev); @@ -252,7 +251,7 @@ int ip6_input(struct sk_buff *skb) int ip6_mc_input(struct sk_buff *skb) { const struct ipv6hdr *hdr; - bool deliver; + int deliver; IP6_UPD_PO_STATS_BH(dev_net(skb_dst(skb)->dev), ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_INMCAST, @@ -288,7 +287,7 @@ int ip6_mc_input(struct sk_buff *skb) * is for MLD (0x0000). */ if ((ptr[2] | ptr[3]) == 0) { - deliver = false; + deliver = 0; if (!ipv6_ext_hdr(nexthdr)) { /* BUG */ @@ -313,7 +312,7 @@ int ip6_mc_input(struct sk_buff *skb) case ICMPV6_MGM_REPORT: case ICMPV6_MGM_REDUCTION: case ICMPV6_MLD2_REPORT: - deliver = true; + deliver = 1; break; } goto out; diff --git a/trunk/net/ipv6/ip6_output.c b/trunk/net/ipv6/ip6_output.c index d99fdc699625..d8e05af2c4bb 100644 --- a/trunk/net/ipv6/ip6_output.c +++ b/trunk/net/ipv6/ip6_output.c @@ -252,7 +252,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6, dst->dev, dst_output); } - net_dbg_ratelimited("IPv6: sending pkt_too_big to self\n"); + if (net_ratelimit()) + printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); skb->dev = dst->dev; icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_FRAGFAILS); @@ -643,10 +644,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) /* We must not fragment if the socket is set to force MTU discovery * or if the skb it not generated by a local socket. */ - if (unlikely(!skb->local_df && skb->len > mtu)) { - if (skb->sk && dst_allfrag(skb_dst(skb))) - sk_nocaps_add(skb->sk, NETIF_F_GSO_MASK); - + if (!skb->local_df && skb->len > mtu) { skb->dev = skb_dst(skb)->dev; icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), @@ -791,10 +789,6 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) } slow_path: - if ((skb->ip_summed == CHECKSUM_PARTIAL) && - skb_checksum_help(skb)) - goto fail; - left = skb->len - hlen; /* Space per frame */ ptr = hlen; /* Where to start from */ @@ -1205,6 +1199,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int copy; int err; int offset = 0; + int csummode = CHECKSUM_NONE; __u8 tx_flags = 0; if (flags&MSG_PROBE) @@ -1417,7 +1412,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, /* * Fill in the control structures */ - skb->ip_summed = CHECKSUM_NONE; + skb->ip_summed = csummode; skb->csum = 0; /* reserve for fragmentation and ipsec header */ skb_reserve(skb, hh_len + sizeof(struct frag_hdr) + @@ -1460,6 +1455,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, transhdrlen = 0; exthdrlen = 0; dst_exthdrlen = 0; + csummode = CHECKSUM_NONE; /* * Put the packet on the pending queue diff --git a/trunk/net/ipv6/ip6_tunnel.c b/trunk/net/ipv6/ip6_tunnel.c index c9015fad8d65..5df487c81ed9 100644 --- a/trunk/net/ipv6/ip6_tunnel.c +++ b/trunk/net/ipv6/ip6_tunnel.c @@ -18,8 +18,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -62,7 +60,7 @@ MODULE_LICENSE("GPL"); MODULE_ALIAS_NETDEV("ip6tnl0"); #ifdef IP6_TNL_DEBUG -#define IP6_TNL_TRACE(x...) pr_debug("%s:" x "\n", __func__) +#define IP6_TNL_TRACE(x...) printk(KERN_DEBUG "%s:" x "\n", __func__) #else #define IP6_TNL_TRACE(x...) do {;} while(0) #endif @@ -462,14 +460,19 @@ ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt, struct ipv6_tlv_tnl_enc_lim *tel; __u32 mtu; case ICMPV6_DEST_UNREACH: - net_warn_ratelimited("%s: Path to destination invalid or inactive!\n", - t->parms.name); + if (net_ratelimit()) + printk(KERN_WARNING + "%s: Path to destination invalid " + "or inactive!\n", t->parms.name); rel_msg = 1; break; case ICMPV6_TIME_EXCEED: if ((*code) == ICMPV6_EXC_HOPLIMIT) { - net_warn_ratelimited("%s: Too small hop limit or routing loop in tunnel!\n", - t->parms.name); + if (net_ratelimit()) + printk(KERN_WARNING + "%s: Too small hop limit or " + "routing loop in tunnel!\n", + t->parms.name); rel_msg = 1; } break; @@ -481,13 +484,17 @@ ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt, if (teli && teli == *info - 2) { tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->data[teli]; if (tel->encap_limit == 0) { - net_warn_ratelimited("%s: Too small encapsulation limit or routing loop in tunnel!\n", - t->parms.name); + if (net_ratelimit()) + printk(KERN_WARNING + "%s: Too small encapsulation " + "limit or routing loop in " + "tunnel!\n", t->parms.name); rel_msg = 1; } - } else { - net_warn_ratelimited("%s: Recipient unable to parse tunneled packet!\n", - t->parms.name); + } else if (net_ratelimit()) { + printk(KERN_WARNING + "%s: Recipient unable to parse tunneled " + "packet!\n ", t->parms.name); } break; case ICMPV6_PKT_TOOBIG: @@ -818,7 +825,7 @@ static void init_tel_txopt(struct ipv6_tel_txoption *opt, __u8 encap_limit) * 0 else **/ -static inline bool +static inline int ip6_tnl_addr_conflict(const struct ip6_tnl *t, const struct ipv6hdr *hdr) { return ipv6_addr_equal(&t->parms.raddr, &hdr->saddr); @@ -838,12 +845,15 @@ static inline int ip6_tnl_xmit_ctl(struct ip6_tnl *t) ldev = dev_get_by_index_rcu(net, p->link); if (unlikely(!ipv6_chk_addr(net, &p->laddr, ldev, 0))) - pr_warn("%s xmit: Local address not yet configured!\n", - p->name); + printk(KERN_WARNING + "%s xmit: Local address not yet configured!\n", + p->name); else if (!ipv6_addr_is_multicast(&p->raddr) && unlikely(ipv6_chk_addr(net, &p->raddr, NULL, 0))) - pr_warn("%s xmit: Routing loop! Remote address found on this node!\n", - p->name); + printk(KERN_WARNING + "%s xmit: Routing loop! " + "Remote address found on this node!\n", + p->name); else ret = 1; rcu_read_unlock(); @@ -909,8 +919,10 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, if (tdev == dev) { stats->collisions++; - net_warn_ratelimited("%s: Local routing loop detected!\n", - t->parms.name); + if (net_ratelimit()) + printk(KERN_WARNING + "%s: Local routing loop detected!\n", + t->parms.name); goto tx_err_dst_release; } mtu = dst_mtu(dst) - sizeof (*ipv6h); @@ -1541,13 +1553,13 @@ static int __init ip6_tunnel_init(void) err = xfrm6_tunnel_register(&ip4ip6_handler, AF_INET); if (err < 0) { - pr_err("%s: can't register ip4ip6\n", __func__); + printk(KERN_ERR "ip6_tunnel init: can't register ip4ip6\n"); goto out_ip4ip6; } err = xfrm6_tunnel_register(&ip6ip6_handler, AF_INET6); if (err < 0) { - pr_err("%s: can't register ip6ip6\n", __func__); + printk(KERN_ERR "ip6_tunnel init: can't register ip6ip6\n"); goto out_ip6ip6; } @@ -1568,10 +1580,10 @@ static int __init ip6_tunnel_init(void) static void __exit ip6_tunnel_cleanup(void) { if (xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET)) - pr_info("%s: can't deregister ip4ip6\n", __func__); + printk(KERN_INFO "ip6_tunnel close: can't deregister ip4ip6\n"); if (xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6)) - pr_info("%s: can't deregister ip6ip6\n", __func__); + printk(KERN_INFO "ip6_tunnel close: can't deregister ip6ip6\n"); unregister_pernet_device(&ip6_tnl_net_ops); } diff --git a/trunk/net/ipv6/ip6mr.c b/trunk/net/ipv6/ip6mr.c index b15dc08643a4..efc0098b59dd 100644 --- a/trunk/net/ipv6/ip6mr.c +++ b/trunk/net/ipv6/ip6mr.c @@ -1147,7 +1147,8 @@ static int ip6mr_cache_report(struct mr6_table *mrt, struct sk_buff *pkt, */ ret = sock_queue_rcv_skb(mrt->mroute6_sk, skb); if (ret < 0) { - net_warn_ratelimited("mroute6: pending queue full, dropping entries\n"); + if (net_ratelimit()) + printk(KERN_WARNING "mroute6: pending queue full, dropping entries.\n"); kfree_skb(skb); } @@ -1350,7 +1351,7 @@ int __init ip6_mr_init(void) goto reg_notif_fail; #ifdef CONFIG_IPV6_PIMSM_V2 if (inet6_add_protocol(&pim6_protocol, IPPROTO_PIM) < 0) { - pr_err("%s: can't add PIM protocol\n", __func__); + printk(KERN_ERR "ip6_mr_init: can't add PIM protocol\n"); err = -EAGAIN; goto add_proto_fail; } diff --git a/trunk/net/ipv6/ipcomp6.c b/trunk/net/ipv6/ipcomp6.c index 5cb75bfe45b1..bba658d9a03c 100644 --- a/trunk/net/ipv6/ipcomp6.c +++ b/trunk/net/ipv6/ipcomp6.c @@ -30,9 +30,6 @@ * The decompression of IP datagram MUST be done after the reassembly, * AH/ESP processing. */ - -#define pr_fmt(fmt) "IPv6: " fmt - #include #include #include @@ -72,8 +69,8 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, if (!x) return; - pr_debug("pmtu discovery on SA IPCOMP/%08x/%pI6\n", - spi, &iph->daddr); + printk(KERN_DEBUG "pmtu discovery on SA IPCOMP/%08x/%pI6\n", + spi, &iph->daddr); xfrm_state_put(x); } @@ -193,11 +190,11 @@ static const struct inet6_protocol ipcomp6_protocol = static int __init ipcomp6_init(void) { if (xfrm_register_type(&ipcomp6_type, AF_INET6) < 0) { - pr_info("%s: can't add xfrm type\n", __func__); + printk(KERN_INFO "ipcomp6 init: can't add xfrm type\n"); return -EAGAIN; } if (inet6_add_protocol(&ipcomp6_protocol, IPPROTO_COMP) < 0) { - pr_info("%s: can't add protocol\n", __func__); + printk(KERN_INFO "ipcomp6 init: can't add protocol\n"); xfrm_unregister_type(&ipcomp6_type, AF_INET6); return -EAGAIN; } @@ -207,9 +204,9 @@ static int __init ipcomp6_init(void) static void __exit ipcomp6_fini(void) { if (inet6_del_protocol(&ipcomp6_protocol, IPPROTO_COMP) < 0) - pr_info("%s: can't remove protocol\n", __func__); + printk(KERN_INFO "ipv6 ipcomp close: can't remove protocol\n"); if (xfrm_unregister_type(&ipcomp6_type, AF_INET6) < 0) - pr_info("%s: can't remove xfrm type\n", __func__); + printk(KERN_INFO "ipv6 ipcomp close: can't remove xfrm type\n"); } module_init(ipcomp6_init); diff --git a/trunk/net/ipv6/mcast.c b/trunk/net/ipv6/mcast.c index 6d0f5dc8e3a6..7dfb89f2bae5 100644 --- a/trunk/net/ipv6/mcast.c +++ b/trunk/net/ipv6/mcast.c @@ -606,13 +606,13 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf, return err; } -bool inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr, - const struct in6_addr *src_addr) +int inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr, + const struct in6_addr *src_addr) { struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_mc_socklist *mc; struct ip6_sf_socklist *psl; - bool rv = true; + int rv = 1; rcu_read_lock(); for_each_pmc_rcu(np, mc) { @@ -621,7 +621,7 @@ bool inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr, } if (!mc) { rcu_read_unlock(); - return true; + return 1; } read_lock(&mc->sflock); psl = mc->sflist; @@ -635,9 +635,9 @@ bool inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr, break; } if (mc->sfmode == MCAST_INCLUDE && i >= psl->sl_count) - rv = false; + rv = 0; if (mc->sfmode == MCAST_EXCLUDE && i < psl->sl_count) - rv = false; + rv = 0; } read_unlock(&mc->sflock); rcu_read_unlock(); @@ -931,15 +931,15 @@ int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr) /* * identify MLD packets for MLD filter exceptions */ -bool ipv6_is_mld(struct sk_buff *skb, int nexthdr) +int ipv6_is_mld(struct sk_buff *skb, int nexthdr) { struct icmp6hdr *pic; if (nexthdr != IPPROTO_ICMPV6) - return false; + return 0; if (!pskb_may_pull(skb, sizeof(struct icmp6hdr))) - return false; + return 0; pic = icmp6_hdr(skb); @@ -948,22 +948,22 @@ bool ipv6_is_mld(struct sk_buff *skb, int nexthdr) case ICMPV6_MGM_REPORT: case ICMPV6_MGM_REDUCTION: case ICMPV6_MLD2_REPORT: - return true; + return 1; default: break; } - return false; + return 0; } /* * check if the interface/address pair is valid */ -bool ipv6_chk_mcast_addr(struct net_device *dev, const struct in6_addr *group, - const struct in6_addr *src_addr) +int ipv6_chk_mcast_addr(struct net_device *dev, const struct in6_addr *group, + const struct in6_addr *src_addr) { struct inet6_dev *idev; struct ifmcaddr6 *mc; - bool rv = false; + int rv = 0; rcu_read_lock(); idev = __in6_dev_get(dev); @@ -990,7 +990,7 @@ bool ipv6_chk_mcast_addr(struct net_device *dev, const struct in6_addr *group, rv = mc->mca_sfcount[MCAST_EXCLUDE] !=0; spin_unlock_bh(&mc->mca_lock); } else - rv = true; /* don't filter unspecified source */ + rv = 1; /* don't filter unspecified source */ } read_unlock_bh(&idev->lock); } @@ -1046,8 +1046,8 @@ static void igmp6_group_queried(struct ifmcaddr6 *ma, unsigned long resptime) } /* mark EXCLUDE-mode sources */ -static bool mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs, - const struct in6_addr *srcs) +static int mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs, + const struct in6_addr *srcs) { struct ip6_sf_list *psf; int i, scount; @@ -1070,12 +1070,12 @@ static bool mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs, } pmc->mca_flags &= ~MAF_GSQUERY; if (scount == nsrcs) /* all sources excluded */ - return false; - return true; + return 0; + return 1; } -static bool mld_marksources(struct ifmcaddr6 *pmc, int nsrcs, - const struct in6_addr *srcs) +static int mld_marksources(struct ifmcaddr6 *pmc, int nsrcs, + const struct in6_addr *srcs) { struct ip6_sf_list *psf; int i, scount; @@ -1099,10 +1099,10 @@ static bool mld_marksources(struct ifmcaddr6 *pmc, int nsrcs, } if (!scount) { pmc->mca_flags &= ~MAF_GSQUERY; - return false; + return 0; } pmc->mca_flags |= MAF_GSQUERY; - return true; + return 1; } /* called with rcu_read_lock() */ @@ -1276,17 +1276,17 @@ int igmp6_event_report(struct sk_buff *skb) return 0; } -static bool is_in(struct ifmcaddr6 *pmc, struct ip6_sf_list *psf, int type, - int gdeleted, int sdeleted) +static int is_in(struct ifmcaddr6 *pmc, struct ip6_sf_list *psf, int type, + int gdeleted, int sdeleted) { switch (type) { case MLD2_MODE_IS_INCLUDE: case MLD2_MODE_IS_EXCLUDE: if (gdeleted || sdeleted) - return false; + return 0; if (!((pmc->mca_flags & MAF_GSQUERY) && !psf->sf_gsresp)) { if (pmc->mca_sfmode == MCAST_INCLUDE) - return true; + return 1; /* don't include if this source is excluded * in all filters */ @@ -1295,29 +1295,29 @@ static bool is_in(struct ifmcaddr6 *pmc, struct ip6_sf_list *psf, int type, return pmc->mca_sfcount[MCAST_EXCLUDE] == psf->sf_count[MCAST_EXCLUDE]; } - return false; + return 0; case MLD2_CHANGE_TO_INCLUDE: if (gdeleted || sdeleted) - return false; + return 0; return psf->sf_count[MCAST_INCLUDE] != 0; case MLD2_CHANGE_TO_EXCLUDE: if (gdeleted || sdeleted) - return false; + return 0; if (pmc->mca_sfcount[MCAST_EXCLUDE] == 0 || psf->sf_count[MCAST_INCLUDE]) - return false; + return 0; return pmc->mca_sfcount[MCAST_EXCLUDE] == psf->sf_count[MCAST_EXCLUDE]; case MLD2_ALLOW_NEW_SOURCES: if (gdeleted || !psf->sf_crcount) - return false; + return 0; return (pmc->mca_sfmode == MCAST_INCLUDE) ^ sdeleted; case MLD2_BLOCK_OLD_SOURCES: if (pmc->mca_sfmode == MCAST_INCLUDE) return gdeleted || (psf->sf_crcount && sdeleted); return psf->sf_crcount && !gdeleted && !sdeleted; } - return false; + return 0; } static int @@ -2627,7 +2627,8 @@ static int __net_init igmp6_net_init(struct net *net) err = inet_ctl_sock_create(&net->ipv6.igmp_sk, PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, net); if (err < 0) { - pr_err("Failed to initialize the IGMP6 control socket (err %d)\n", + printk(KERN_ERR + "Failed to initialize the IGMP6 control socket (err %d).\n", err); goto out; } diff --git a/trunk/net/ipv6/mip6.c b/trunk/net/ipv6/mip6.c index 5b087c31d87b..7e1e0fbfef21 100644 --- a/trunk/net/ipv6/mip6.c +++ b/trunk/net/ipv6/mip6.c @@ -22,8 +22,6 @@ * Masahide NAKAMURA @USAGI */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -46,7 +44,7 @@ static inline void *mip6_padn(__u8 *data, __u8 padlen) if (!data) return NULL; if (padlen == 1) { - data[0] = IPV6_TLV_PAD1; + data[0] = IPV6_TLV_PAD0; } else if (padlen > 1) { data[0] = IPV6_TLV_PADN; data[1] = padlen - 2; @@ -309,12 +307,13 @@ static int mip6_destopt_offset(struct xfrm_state *x, struct sk_buff *skb, static int mip6_destopt_init_state(struct xfrm_state *x) { if (x->id.spi) { - pr_info("%s: spi is not 0: %u\n", __func__, x->id.spi); + printk(KERN_INFO "%s: spi is not 0: %u\n", __func__, + x->id.spi); return -EINVAL; } if (x->props.mode != XFRM_MODE_ROUTEOPTIMIZATION) { - pr_info("%s: state's mode is not %u: %u\n", - __func__, XFRM_MODE_ROUTEOPTIMIZATION, x->props.mode); + printk(KERN_INFO "%s: state's mode is not %u: %u\n", + __func__, XFRM_MODE_ROUTEOPTIMIZATION, x->props.mode); return -EINVAL; } @@ -444,12 +443,13 @@ static int mip6_rthdr_offset(struct xfrm_state *x, struct sk_buff *skb, static int mip6_rthdr_init_state(struct xfrm_state *x) { if (x->id.spi) { - pr_info("%s: spi is not 0: %u\n", __func__, x->id.spi); + printk(KERN_INFO "%s: spi is not 0: %u\n", __func__, + x->id.spi); return -EINVAL; } if (x->props.mode != XFRM_MODE_ROUTEOPTIMIZATION) { - pr_info("%s: state's mode is not %u: %u\n", - __func__, XFRM_MODE_ROUTEOPTIMIZATION, x->props.mode); + printk(KERN_INFO "%s: state's mode is not %u: %u\n", + __func__, XFRM_MODE_ROUTEOPTIMIZATION, x->props.mode); return -EINVAL; } @@ -481,18 +481,18 @@ static const struct xfrm_type mip6_rthdr_type = static int __init mip6_init(void) { - pr_info("Mobile IPv6\n"); + printk(KERN_INFO "Mobile IPv6\n"); if (xfrm_register_type(&mip6_destopt_type, AF_INET6) < 0) { - pr_info("%s: can't add xfrm type(destopt)\n", __func__); + printk(KERN_INFO "%s: can't add xfrm type(destopt)\n", __func__); goto mip6_destopt_xfrm_fail; } if (xfrm_register_type(&mip6_rthdr_type, AF_INET6) < 0) { - pr_info("%s: can't add xfrm type(rthdr)\n", __func__); + printk(KERN_INFO "%s: can't add xfrm type(rthdr)\n", __func__); goto mip6_rthdr_xfrm_fail; } if (rawv6_mh_filter_register(mip6_mh_filter) < 0) { - pr_info("%s: can't add rawv6 mh filter\n", __func__); + printk(KERN_INFO "%s: can't add rawv6 mh filter\n", __func__); goto mip6_rawv6_mh_fail; } @@ -510,11 +510,11 @@ static int __init mip6_init(void) static void __exit mip6_fini(void) { if (rawv6_mh_filter_unregister(mip6_mh_filter) < 0) - pr_info("%s: can't remove rawv6 mh filter\n", __func__); + printk(KERN_INFO "%s: can't remove rawv6 mh filter\n", __func__); if (xfrm_unregister_type(&mip6_rthdr_type, AF_INET6) < 0) - pr_info("%s: can't remove xfrm type(rthdr)\n", __func__); + printk(KERN_INFO "%s: can't remove xfrm type(rthdr)\n", __func__); if (xfrm_unregister_type(&mip6_destopt_type, AF_INET6) < 0) - pr_info("%s: can't remove xfrm type(destopt)\n", __func__); + printk(KERN_INFO "%s: can't remove xfrm type(destopt)\n", __func__); } module_init(mip6_init); diff --git a/trunk/net/ipv6/ndisc.c b/trunk/net/ipv6/ndisc.c index 54f62d3b8dd6..35615c6358b8 100644 --- a/trunk/net/ipv6/ndisc.c +++ b/trunk/net/ipv6/ndisc.c @@ -27,7 +27,27 @@ * YOSHIFUJI Hideaki @USAGI : Verify ND options properly */ -#define pr_fmt(fmt) "ICMPv6: " fmt +/* Set to 3 to get tracing... */ +#define ND_DEBUG 1 + +#define ND_PRINTK(fmt, args...) do { if (net_ratelimit()) { printk(fmt, ## args); } } while(0) +#define ND_NOPRINTK(x...) do { ; } while(0) +#define ND_PRINTK0 ND_PRINTK +#define ND_PRINTK1 ND_NOPRINTK +#define ND_PRINTK2 ND_NOPRINTK +#define ND_PRINTK3 ND_NOPRINTK +#if ND_DEBUG >= 1 +#undef ND_PRINTK1 +#define ND_PRINTK1 ND_PRINTK +#endif +#if ND_DEBUG >= 2 +#undef ND_PRINTK2 +#define ND_PRINTK2 ND_PRINTK +#endif +#if ND_DEBUG >= 3 +#undef ND_PRINTK3 +#define ND_PRINTK3 ND_PRINTK +#endif #include #include @@ -72,15 +92,6 @@ #include #include -/* Set to 3 to get tracing... */ -#define ND_DEBUG 1 - -#define ND_PRINTK(val, level, fmt, ...) \ -do { \ - if (val <= ND_DEBUG) \ - net_##level##_ratelimited(fmt, ##__VA_ARGS__); \ -} while (0) - static u32 ndisc_hash(const void *pkey, const struct net_device *dev, __u32 *hash_rnd); @@ -254,9 +265,10 @@ static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len, case ND_OPT_MTU: case ND_OPT_REDIRECT_HDR: if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) { - ND_PRINTK(2, warn, - "%s: duplicated ND6 option found: type=%d\n", - __func__, nd_opt->nd_opt_type); + ND_PRINTK2(KERN_WARNING + "%s(): duplicated ND6 option found: type=%d\n", + __func__, + nd_opt->nd_opt_type); } else { ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt; } @@ -284,11 +296,10 @@ static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len, * to accommodate future extension to the * protocol. */ - ND_PRINTK(2, notice, - "%s: ignored unsupported option; type=%d, len=%d\n", - __func__, - nd_opt->nd_opt_type, - nd_opt->nd_opt_len); + ND_PRINTK2(KERN_NOTICE + "%s(): ignored unsupported option; type=%d, len=%d\n", + __func__, + nd_opt->nd_opt_type, nd_opt->nd_opt_len); } } opt_len -= l; @@ -316,6 +327,9 @@ int ndisc_mc_map(const struct in6_addr *addr, char *buf, struct net_device *dev, case ARPHRD_FDDI: ipv6_eth_mc_map(addr, buf); return 0; + case ARPHRD_IEEE802_TR: + ipv6_tr_mc_map(addr,buf); + return 0; case ARPHRD_ARCNET: ipv6_arcnet_mc_map(addr, buf); return 0; @@ -348,7 +362,7 @@ static int ndisc_constructor(struct neighbour *neigh) struct net_device *dev = neigh->dev; struct inet6_dev *in6_dev; struct neigh_parms *parms; - bool is_multicast = ipv6_addr_is_multicast(addr); + int is_multicast = ipv6_addr_is_multicast(addr); in6_dev = in6_dev_get(dev); if (in6_dev == NULL) { @@ -444,8 +458,9 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev, len + hlen + tlen), 1, &err); if (!skb) { - ND_PRINTK(0, err, "ND: %s failed to allocate an skb, err=%d\n", - __func__, err); + ND_PRINTK0(KERN_ERR + "ICMPv6 ND: %s() failed to allocate an skb, err=%d.\n", + __func__, err); return NULL; } @@ -681,9 +696,8 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb) if ((probes -= neigh->parms->ucast_probes) < 0) { if (!(neigh->nud_state & NUD_VALID)) { - ND_PRINTK(1, dbg, - "%s: trying to ucast probe in NUD_INVALID: %pI6\n", - __func__, target); + ND_PRINTK1(KERN_DEBUG "%s(): trying to ucast probe in NUD_INVALID: %pI6\n", + __func__, target); } ndisc_send_ns(dev, neigh, target, target, saddr); } else if ((probes -= neigh->parms->app_probes) < 0) { @@ -725,11 +739,12 @@ static void ndisc_recv_ns(struct sk_buff *skb) struct inet6_dev *idev = NULL; struct neighbour *neigh; int dad = ipv6_addr_any(saddr); - bool inc; + int inc; int is_router = -1; if (ipv6_addr_is_multicast(&msg->target)) { - ND_PRINTK(2, warn, "NS: multicast target address\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 NS: multicast target address"); return; } @@ -742,20 +757,22 @@ static void ndisc_recv_ns(struct sk_buff *skb) daddr->s6_addr32[1] == htonl(0x00000000) && daddr->s6_addr32[2] == htonl(0x00000001) && daddr->s6_addr [12] == 0xff )) { - ND_PRINTK(2, warn, "NS: bad DAD packet (wrong destination)\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 NS: bad DAD packet (wrong destination)\n"); return; } if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) { - ND_PRINTK(2, warn, "NS: invalid ND options\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 NS: invalid ND options\n"); return; } if (ndopts.nd_opts_src_lladdr) { lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr, dev); if (!lladdr) { - ND_PRINTK(2, warn, - "NS: invalid link-layer address length\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 NS: invalid link-layer address length\n"); return; } @@ -765,8 +782,8 @@ static void ndisc_recv_ns(struct sk_buff *skb) * in the message. */ if (dad) { - ND_PRINTK(2, warn, - "NS: bad DAD packet (link-layer address option)\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 NS: bad DAD packet (link-layer address option)\n"); return; } } @@ -778,6 +795,20 @@ static void ndisc_recv_ns(struct sk_buff *skb) if (ifp->flags & (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)) { if (dad) { + if (dev->type == ARPHRD_IEEE802_TR) { + const unsigned char *sadr; + sadr = skb_mac_header(skb); + if (((sadr[8] ^ dev->dev_addr[0]) & 0x7f) == 0 && + sadr[9] == dev->dev_addr[1] && + sadr[10] == dev->dev_addr[2] && + sadr[11] == dev->dev_addr[3] && + sadr[12] == dev->dev_addr[4] && + sadr[13] == dev->dev_addr[5]) { + /* looped-back to us */ + goto out; + } + } + /* * We are colliding with another node * who is doing DAD @@ -884,30 +915,34 @@ static void ndisc_recv_na(struct sk_buff *skb) struct neighbour *neigh; if (skb->len < sizeof(struct nd_msg)) { - ND_PRINTK(2, warn, "NA: packet too short\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 NA: packet too short\n"); return; } if (ipv6_addr_is_multicast(&msg->target)) { - ND_PRINTK(2, warn, "NA: target address is multicast\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 NA: target address is multicast.\n"); return; } if (ipv6_addr_is_multicast(daddr) && msg->icmph.icmp6_solicited) { - ND_PRINTK(2, warn, "NA: solicited NA is multicasted\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 NA: solicited NA is multicasted.\n"); return; } if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) { - ND_PRINTK(2, warn, "NS: invalid ND option\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 NS: invalid ND option\n"); return; } if (ndopts.nd_opts_tgt_lladdr) { lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr, dev); if (!lladdr) { - ND_PRINTK(2, warn, - "NA: invalid link-layer address length\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 NA: invalid link-layer address length\n"); return; } } @@ -928,9 +963,9 @@ static void ndisc_recv_na(struct sk_buff *skb) unsolicited advertisement. */ if (skb->pkt_type != PACKET_LOOPBACK) - ND_PRINTK(1, warn, - "NA: someone advertises our address %pI6 on %s!\n", - &ifp->addr, ifp->idev->dev->name); + ND_PRINTK1(KERN_WARNING + "ICMPv6 NA: someone advertises our address %pI6 on %s!\n", + &ifp->addr, ifp->idev->dev->name); in6_ifa_put(ifp); return; } @@ -992,7 +1027,8 @@ static void ndisc_recv_rs(struct sk_buff *skb) idev = __in6_dev_get(skb->dev); if (!idev) { - ND_PRINTK(1, err, "RS: can't find in6 device\n"); + if (net_ratelimit()) + ND_PRINTK1("ICMP6 RS: can't find in6 device\n"); return; } @@ -1009,7 +1045,8 @@ static void ndisc_recv_rs(struct sk_buff *skb) /* Parse ND options */ if (!ndisc_parse_options(rs_msg->opt, ndoptlen, &ndopts)) { - ND_PRINTK(2, notice, "NS: invalid ND option, ignored\n"); + if (net_ratelimit()) + ND_PRINTK2("ICMP6 NS: invalid ND option, ignored\n"); goto out; } @@ -1107,17 +1144,20 @@ static void ndisc_router_discovery(struct sk_buff *skb) optlen = (skb->tail - skb->transport_header) - sizeof(struct ra_msg); if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) { - ND_PRINTK(2, warn, "RA: source address is not link-local\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 RA: source address is not link-local.\n"); return; } if (optlen < 0) { - ND_PRINTK(2, warn, "RA: packet too short\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 RA: packet too short\n"); return; } #ifdef CONFIG_IPV6_NDISC_NODETYPE if (skb->ndisc_nodetype == NDISC_NODETYPE_HOST) { - ND_PRINTK(2, warn, "RA: from host or unauthorized router\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 RA: from host or unauthorized router\n"); return; } #endif @@ -1128,13 +1168,15 @@ static void ndisc_router_discovery(struct sk_buff *skb) in6_dev = __in6_dev_get(skb->dev); if (in6_dev == NULL) { - ND_PRINTK(0, err, "RA: can't find inet6 device for %s\n", - skb->dev->name); + ND_PRINTK0(KERN_ERR + "ICMPv6 RA: can't find inet6 device for %s.\n", + skb->dev->name); return; } if (!ndisc_parse_options(opt, optlen, &ndopts)) { - ND_PRINTK(2, warn, "RA: invalid ND options\n"); + ND_PRINTK2(KERN_WARNING + "ICMP6 RA: invalid ND options\n"); return; } @@ -1187,9 +1229,9 @@ static void ndisc_router_discovery(struct sk_buff *skb) if (rt) { neigh = dst_neigh_lookup(&rt->dst, &ipv6_hdr(skb)->saddr); if (!neigh) { - ND_PRINTK(0, err, - "RA: %s got default router without neighbour\n", - __func__); + ND_PRINTK0(KERN_ERR + "ICMPv6 RA: %s() got default router without neighbour.\n", + __func__); dst_release(&rt->dst); return; } @@ -1200,21 +1242,22 @@ static void ndisc_router_discovery(struct sk_buff *skb) } if (rt == NULL && lifetime) { - ND_PRINTK(3, dbg, "RA: adding default router\n"); + ND_PRINTK3(KERN_DEBUG + "ICMPv6 RA: adding default router.\n"); rt = rt6_add_dflt_router(&ipv6_hdr(skb)->saddr, skb->dev, pref); if (rt == NULL) { - ND_PRINTK(0, err, - "RA: %s failed to add default route\n", - __func__); + ND_PRINTK0(KERN_ERR + "ICMPv6 RA: %s() failed to add default route.\n", + __func__); return; } neigh = dst_neigh_lookup(&rt->dst, &ipv6_hdr(skb)->saddr); if (neigh == NULL) { - ND_PRINTK(0, err, - "RA: %s got default router without neighbour\n", - __func__); + ND_PRINTK0(KERN_ERR + "ICMPv6 RA: %s() got default router without neighbour.\n", + __func__); dst_release(&rt->dst); return; } @@ -1282,8 +1325,8 @@ static void ndisc_router_discovery(struct sk_buff *skb) lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr, skb->dev); if (!lladdr) { - ND_PRINTK(2, warn, - "RA: invalid link-layer address length\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 RA: invalid link-layer address length\n"); goto out; } } @@ -1347,7 +1390,9 @@ static void ndisc_router_discovery(struct sk_buff *skb) mtu = ntohl(n); if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) { - ND_PRINTK(2, warn, "RA: invalid mtu: %d\n", mtu); + ND_PRINTK2(KERN_WARNING + "ICMPv6 RA: invalid mtu: %d\n", + mtu); } else if (in6_dev->cnf.mtu6 != mtu) { in6_dev->cnf.mtu6 = mtu; @@ -1368,7 +1413,8 @@ static void ndisc_router_discovery(struct sk_buff *skb) } if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) { - ND_PRINTK(2, warn, "RA: invalid RA options\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 RA: invalid RA options"); } out: if (rt) @@ -1393,15 +1439,15 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) switch (skb->ndisc_nodetype) { case NDISC_NODETYPE_HOST: case NDISC_NODETYPE_NODEFAULT: - ND_PRINTK(2, warn, - "Redirect: from host or unauthorized router\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 Redirect: from host or unauthorized router\n"); return; } #endif if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) { - ND_PRINTK(2, warn, - "Redirect: source address is not link-local\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 Redirect: source address is not link-local.\n"); return; } @@ -1409,7 +1455,8 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) optlen -= sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr); if (optlen < 0) { - ND_PRINTK(2, warn, "Redirect: packet too short\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 Redirect: packet too short\n"); return; } @@ -1418,8 +1465,8 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) dest = target + 1; if (ipv6_addr_is_multicast(dest)) { - ND_PRINTK(2, warn, - "Redirect: destination address is multicast\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 Redirect: destination address is multicast.\n"); return; } @@ -1427,8 +1474,8 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) on_link = 1; } else if (ipv6_addr_type(target) != (IPV6_ADDR_UNICAST|IPV6_ADDR_LINKLOCAL)) { - ND_PRINTK(2, warn, - "Redirect: target address is not link-local unicast\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 Redirect: target address is not link-local unicast.\n"); return; } @@ -1444,15 +1491,16 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) */ if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) { - ND_PRINTK(2, warn, "Redirect: invalid ND options\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 Redirect: invalid ND options\n"); return; } if (ndopts.nd_opts_tgt_lladdr) { lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr, skb->dev); if (!lladdr) { - ND_PRINTK(2, warn, - "Redirect: invalid link-layer address length\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 Redirect: invalid link-layer address length\n"); return; } } @@ -1487,15 +1535,16 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) u8 ha_buf[MAX_ADDR_LEN], *ha = NULL; if (ipv6_get_lladdr(dev, &saddr_buf, IFA_F_TENTATIVE)) { - ND_PRINTK(2, warn, "Redirect: no link-local address on %s\n", - dev->name); + ND_PRINTK2(KERN_WARNING + "ICMPv6 Redirect: no link-local address on %s\n", + dev->name); return; } if (!ipv6_addr_equal(&ipv6_hdr(skb)->daddr, target) && ipv6_addr_type(target) != (IPV6_ADDR_UNICAST|IPV6_ADDR_LINKLOCAL)) { - ND_PRINTK(2, warn, - "Redirect: target address is not link-local unicast\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 Redirect: target address is not link-local unicast.\n"); return; } @@ -1514,8 +1563,8 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) rt = (struct rt6_info *) dst; if (rt->rt6i_flags & RTF_GATEWAY) { - ND_PRINTK(2, warn, - "Redirect: destination is not a neighbour\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 Redirect: destination is not a neighbour.\n"); goto release; } if (!rt->rt6i_peer) @@ -1526,8 +1575,8 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) if (dev->addr_len) { struct neighbour *neigh = dst_neigh_lookup(skb_dst(skb), target); if (!neigh) { - ND_PRINTK(2, warn, - "Redirect: no neigh for target address\n"); + ND_PRINTK2(KERN_WARNING + "ICMPv6 Redirect: no neigh for target address\n"); goto release; } @@ -1555,9 +1604,9 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) len + hlen + tlen), 1, &err); if (buff == NULL) { - ND_PRINTK(0, err, - "Redirect: %s failed to allocate an skb, err=%d\n", - __func__, err); + ND_PRINTK0(KERN_ERR + "ICMPv6 Redirect: %s() failed to allocate an skb, err=%d.\n", + __func__, err); goto release; } @@ -1642,14 +1691,16 @@ int ndisc_rcv(struct sk_buff *skb) __skb_push(skb, skb->data - skb_transport_header(skb)); if (ipv6_hdr(skb)->hop_limit != 255) { - ND_PRINTK(2, warn, "NDISC: invalid hop-limit: %d\n", - ipv6_hdr(skb)->hop_limit); + ND_PRINTK2(KERN_WARNING + "ICMPv6 NDISC: invalid hop-limit: %d\n", + ipv6_hdr(skb)->hop_limit); return 0; } if (msg->icmph.icmp6_code != 0) { - ND_PRINTK(2, warn, "NDISC: invalid ICMPv6 code: %d\n", - msg->icmph.icmp6_code); + ND_PRINTK2(KERN_WARNING + "ICMPv6 NDISC: invalid ICMPv6 code: %d\n", + msg->icmph.icmp6_code); return 0; } @@ -1716,7 +1767,11 @@ static void ndisc_warn_deprecated_sysctl(struct ctl_table *ctl, static int warned; if (strcmp(warncomm, current->comm) && warned < 5) { strcpy(warncomm, current->comm); - pr_warn("process `%s' is using deprecated sysctl (%s) net.ipv6.neigh.%s.%s - use net.ipv6.neigh.%s.%s_ms instead\n", + printk(KERN_WARNING + "process `%s' is using deprecated sysctl (%s) " + "net.ipv6.neigh.%s.%s; " + "Use net.ipv6.neigh.%s.%s_ms " + "instead.\n", warncomm, func, dev_name, ctl->procname, dev_name, ctl->procname); @@ -1770,9 +1825,9 @@ static int __net_init ndisc_net_init(struct net *net) err = inet_ctl_sock_create(&sk, PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, net); if (err < 0) { - ND_PRINTK(0, err, - "NDISC: Failed to initialize the control socket (err %d)\n", - err); + ND_PRINTK0(KERN_ERR + "ICMPv6 NDISC: Failed to initialize the control socket (err %d).\n", + err); return err; } diff --git a/trunk/net/ipv6/netfilter/ip6_tables.c b/trunk/net/ipv6/netfilter/ip6_tables.c index d7cb04506c3d..d4e350f72bbb 100644 --- a/trunk/net/ipv6/netfilter/ip6_tables.c +++ b/trunk/net/ipv6/netfilter/ip6_tables.c @@ -133,7 +133,7 @@ ip6_packet_match(const struct sk_buff *skb, int protohdr; unsigned short _frag_off; - protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off, NULL); + protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off); if (protohdr < 0) { if (_frag_off == 0) *hotdrop = true; @@ -181,7 +181,8 @@ ip6_checkentry(const struct ip6t_ip6 *ipv6) static unsigned int ip6t_error(struct sk_buff *skb, const struct xt_action_param *par) { - net_info_ratelimited("error: `%s'\n", (const char *)par->targinfo); + if (net_ratelimit()) + pr_info("error: `%s'\n", (const char *)par->targinfo); return NF_DROP; } @@ -361,7 +362,6 @@ ip6t_do_table(struct sk_buff *skb, const struct xt_entry_match *ematch; IP_NF_ASSERT(e); - acpar.thoff = 0; if (!ip6_packet_match(skb, indev, outdev, &e->ipv6, &acpar.thoff, &acpar.fragoff, &acpar.hotdrop)) { no_match: @@ -2278,10 +2278,6 @@ static void __exit ip6_tables_fini(void) * if target < 0. "last header" is transport protocol header, ESP, or * "No next header". * - * Note that *offset is used as input/output parameter. an if it is not zero, - * then it must be a valid offset to an inner IPv6 header. This can be used - * to explore inner IPv6 header, eg. ICMPv6 error messages. - * * If target header is found, its offset is set in *offset and return protocol * number. Otherwise, return -1. * @@ -2293,33 +2289,17 @@ static void __exit ip6_tables_fini(void) * *offset is meaningless and fragment offset is stored in *fragoff if fragoff * isn't NULL. * - * if flags is not NULL and it's a fragment, then the frag flag IP6T_FH_F_FRAG - * will be set. If it's an AH header, the IP6T_FH_F_AUTH flag is set and - * target < 0, then this function will stop at the AH header. */ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, - int target, unsigned short *fragoff, int *flags) + int target, unsigned short *fragoff) { unsigned int start = skb_network_offset(skb) + sizeof(struct ipv6hdr); u8 nexthdr = ipv6_hdr(skb)->nexthdr; - unsigned int len; + unsigned int len = skb->len - start; if (fragoff) *fragoff = 0; - if (*offset) { - struct ipv6hdr _ip6, *ip6; - - ip6 = skb_header_pointer(skb, *offset, sizeof(_ip6), &_ip6); - if (!ip6 || (ip6->version != 6)) { - printk(KERN_ERR "IPv6 header not found\n"); - return -EBADMSG; - } - start = *offset + sizeof(struct ipv6hdr); - nexthdr = ip6->nexthdr; - } - len = skb->len - start; - while (nexthdr != target) { struct ipv6_opt_hdr _hdr, *hp; unsigned int hdrlen; @@ -2336,9 +2316,6 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, if (nexthdr == NEXTHDR_FRAGMENT) { unsigned short _frag_off; __be16 *fp; - - if (flags) /* Indicate that this is a fragment */ - *flags |= IP6T_FH_F_FRAG; fp = skb_header_pointer(skb, start+offsetof(struct frag_hdr, frag_off), @@ -2359,11 +2336,9 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, return -ENOENT; } hdrlen = 8; - } else if (nexthdr == NEXTHDR_AUTH) { - if (flags && (*flags & IP6T_FH_F_AUTH) && (target < 0)) - break; + } else if (nexthdr == NEXTHDR_AUTH) hdrlen = (hp->hdrlen + 2) << 2; - } else + else hdrlen = ipv6_optlen(hp); nexthdr = hp->nexthdr; diff --git a/trunk/net/ipv6/netfilter/ip6t_REJECT.c b/trunk/net/ipv6/netfilter/ip6t_REJECT.c index fd4fb34c51c7..aad2fa41cf46 100644 --- a/trunk/net/ipv6/netfilter/ip6t_REJECT.c +++ b/trunk/net/ipv6/netfilter/ip6t_REJECT.c @@ -114,7 +114,8 @@ static void send_reset(struct net *net, struct sk_buff *oldskb) GFP_ATOMIC); if (!nskb) { - net_dbg_ratelimited("cannot alloc skb\n"); + if (net_ratelimit()) + pr_debug("cannot alloc skb\n"); dst_release(dst); return; } @@ -209,7 +210,8 @@ reject_tg6(struct sk_buff *skb, const struct xt_action_param *par) send_reset(net, skb); break; default: - net_info_ratelimited("case %u not handled yet\n", reject->with); + if (net_ratelimit()) + pr_info("case %u not handled yet\n", reject->with); break; } diff --git a/trunk/net/ipv6/netfilter/ip6t_ah.c b/trunk/net/ipv6/netfilter/ip6t_ah.c index 04099ab7d2e3..89cccc5a9c92 100644 --- a/trunk/net/ipv6/netfilter/ip6t_ah.c +++ b/trunk/net/ipv6/netfilter/ip6t_ah.c @@ -41,11 +41,11 @@ static bool ah_mt6(const struct sk_buff *skb, struct xt_action_param *par) struct ip_auth_hdr _ah; const struct ip_auth_hdr *ah; const struct ip6t_ah *ahinfo = par->matchinfo; - unsigned int ptr = 0; + unsigned int ptr; unsigned int hdrlen = 0; int err; - err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL, NULL); + err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL); if (err < 0) { if (err != -ENOENT) par->hotdrop = true; diff --git a/trunk/net/ipv6/netfilter/ip6t_frag.c b/trunk/net/ipv6/netfilter/ip6t_frag.c index 3b5735e56bfe..eda898fda6ca 100644 --- a/trunk/net/ipv6/netfilter/ip6t_frag.c +++ b/trunk/net/ipv6/netfilter/ip6t_frag.c @@ -40,10 +40,10 @@ frag_mt6(const struct sk_buff *skb, struct xt_action_param *par) struct frag_hdr _frag; const struct frag_hdr *fh; const struct ip6t_frag *fraginfo = par->matchinfo; - unsigned int ptr = 0; + unsigned int ptr; int err; - err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL, NULL); + err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL); if (err < 0) { if (err != -ENOENT) par->hotdrop = true; diff --git a/trunk/net/ipv6/netfilter/ip6t_hbh.c b/trunk/net/ipv6/netfilter/ip6t_hbh.c index 01df142bb027..59df051eaef6 100644 --- a/trunk/net/ipv6/netfilter/ip6t_hbh.c +++ b/trunk/net/ipv6/netfilter/ip6t_hbh.c @@ -50,7 +50,7 @@ hbh_mt6(const struct sk_buff *skb, struct xt_action_param *par) const struct ipv6_opt_hdr *oh; const struct ip6t_opts *optinfo = par->matchinfo; unsigned int temp; - unsigned int ptr = 0; + unsigned int ptr; unsigned int hdrlen = 0; bool ret = false; u8 _opttype; @@ -62,7 +62,7 @@ hbh_mt6(const struct sk_buff *skb, struct xt_action_param *par) err = ipv6_find_hdr(skb, &ptr, (par->match == &hbh_mt6_reg[0]) ? - NEXTHDR_HOP : NEXTHDR_DEST, NULL, NULL); + NEXTHDR_HOP : NEXTHDR_DEST, NULL); if (err < 0) { if (err != -ENOENT) par->hotdrop = true; diff --git a/trunk/net/ipv6/netfilter/ip6t_rt.c b/trunk/net/ipv6/netfilter/ip6t_rt.c index 2c99b94eeca3..d8488c50a8e0 100644 --- a/trunk/net/ipv6/netfilter/ip6t_rt.c +++ b/trunk/net/ipv6/netfilter/ip6t_rt.c @@ -42,14 +42,14 @@ static bool rt_mt6(const struct sk_buff *skb, struct xt_action_param *par) const struct ipv6_rt_hdr *rh; const struct ip6t_rt *rtinfo = par->matchinfo; unsigned int temp; - unsigned int ptr = 0; + unsigned int ptr; unsigned int hdrlen = 0; bool ret = false; struct in6_addr _addr; const struct in6_addr *ap; int err; - err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL, NULL); + err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL); if (err < 0) { if (err != -ENOENT) par->hotdrop = true; diff --git a/trunk/net/ipv6/netfilter/ip6table_mangle.c b/trunk/net/ipv6/netfilter/ip6table_mangle.c index 4d782405f125..00d19173db7e 100644 --- a/trunk/net/ipv6/netfilter/ip6table_mangle.c +++ b/trunk/net/ipv6/netfilter/ip6table_mangle.c @@ -42,7 +42,8 @@ ip6t_mangle_out(struct sk_buff *skb, const struct net_device *out) /* root is playing with raw sockets. */ if (skb->len < sizeof(struct iphdr) || ip_hdrlen(skb) < sizeof(struct iphdr)) { - net_warn_ratelimited("ip6t_hook: happy cracking\n"); + if (net_ratelimit()) + pr_warning("ip6t_hook: happy cracking.\n"); return NF_ACCEPT; } #endif diff --git a/trunk/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/trunk/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 3224ef90a21a..fe925e492520 100644 --- a/trunk/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/trunk/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c @@ -232,7 +232,8 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum, { /* root is playing with raw sockets. */ if (skb->len < sizeof(struct ipv6hdr)) { - net_notice_ratelimited("ipv6_conntrack_local: packet too short\n"); + if (net_ratelimit()) + pr_notice("ipv6_conntrack_local: packet too short\n"); return NF_ACCEPT; } return __ipv6_conntrack_in(dev_net(out), hooknum, skb, okfn); diff --git a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c index c9c78c2e666b..48a2be1b7c70 100644 --- a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -444,11 +444,12 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) return head; out_oversize: - net_dbg_ratelimited("nf_ct_frag6_reasm: payload len = %d\n", - payload_len); + if (net_ratelimit()) + printk(KERN_DEBUG "nf_ct_frag6_reasm: payload len = %d\n", payload_len); goto out_fail; out_oom: - net_dbg_ratelimited("nf_ct_frag6_reasm: no memory for reassembly\n"); + if (net_ratelimit()) + printk(KERN_DEBUG "nf_ct_frag6_reasm: no memory for reassembly\n"); out_fail: return NULL; } diff --git a/trunk/net/ipv6/raw.c b/trunk/net/ipv6/raw.c index 93d69836fded..5bddea778840 100644 --- a/trunk/net/ipv6/raw.c +++ b/trunk/net/ipv6/raw.c @@ -72,7 +72,7 @@ static struct sock *__raw_v6_lookup(struct net *net, struct sock *sk, const struct in6_addr *rmt_addr, int dif) { struct hlist_node *node; - bool is_multicast = ipv6_addr_is_multicast(loc_addr); + int is_multicast = ipv6_addr_is_multicast(loc_addr); sk_for_each_from(sk, node) if (inet_sk(sk)->inet_num == num) { @@ -153,12 +153,12 @@ EXPORT_SYMBOL(rawv6_mh_filter_unregister); * * Caller owns SKB so we must make clones. */ -static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) +static int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) { const struct in6_addr *saddr; const struct in6_addr *daddr; struct sock *sk; - bool delivered = false; + int delivered = 0; __u8 hash; struct net *net; @@ -179,7 +179,7 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) while (sk) { int filtered; - delivered = true; + delivered = 1; switch (nexthdr) { case IPPROTO_ICMPV6: filtered = icmpv6_filter(sk, skb); @@ -225,7 +225,7 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) return delivered; } -bool raw6_local_deliver(struct sk_buff *skb, int nexthdr) +int raw6_local_deliver(struct sk_buff *skb, int nexthdr) { struct sock *raw_sk; diff --git a/trunk/net/ipv6/reassembly.c b/trunk/net/ipv6/reassembly.c index 4ff9af628e72..54c5d2b704df 100644 --- a/trunk/net/ipv6/reassembly.c +++ b/trunk/net/ipv6/reassembly.c @@ -134,16 +134,15 @@ static unsigned int ip6_hashfn(struct inet_frag_queue *q) return inet6_hash_frag(fq->id, &fq->saddr, &fq->daddr, ip6_frags.rnd); } -bool ip6_frag_match(struct inet_frag_queue *q, void *a) +int ip6_frag_match(struct inet_frag_queue *q, void *a) { struct frag_queue *fq; struct ip6_create_arg *arg = a; fq = container_of(q, struct frag_queue, q); - return fq->id == arg->id && - fq->user == arg->user && - ipv6_addr_equal(&fq->saddr, arg->src) && - ipv6_addr_equal(&fq->daddr, arg->dst); + return (fq->id == arg->id && fq->user == arg->user && + ipv6_addr_equal(&fq->saddr, arg->src) && + ipv6_addr_equal(&fq->daddr, arg->dst)); } EXPORT_SYMBOL(ip6_frag_match); @@ -415,7 +414,6 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, struct sk_buff *fp, *head = fq->q.fragments; int payload_len; unsigned int nhoff; - int sum_truesize; fq_kill(fq); @@ -485,33 +483,20 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, head->mac_header += sizeof(struct frag_hdr); head->network_header += sizeof(struct frag_hdr); + skb_shinfo(head)->frag_list = head->next; skb_reset_transport_header(head); skb_push(head, head->data - skb_network_header(head)); - sum_truesize = head->truesize; - for (fp = head->next; fp;) { - bool headstolen; - int delta; - struct sk_buff *next = fp->next; - - sum_truesize += fp->truesize; + for (fp=head->next; fp; fp = fp->next) { + head->data_len += fp->len; + head->len += fp->len; if (head->ip_summed != fp->ip_summed) head->ip_summed = CHECKSUM_NONE; else if (head->ip_summed == CHECKSUM_COMPLETE) head->csum = csum_add(head->csum, fp->csum); - - if (skb_try_coalesce(head, fp, &headstolen, &delta)) { - kfree_skb_partial(fp, headstolen); - } else { - if (!skb_shinfo(head)->frag_list) - skb_shinfo(head)->frag_list = fp; - head->data_len += fp->len; - head->len += fp->len; - head->truesize += fp->truesize; - } - fp = next; + head->truesize += fp->truesize; } - atomic_sub(sum_truesize, &fq->q.net->mem); + atomic_sub(head->truesize, &fq->q.net->mem); head->next = NULL; head->dev = dev; @@ -533,10 +518,12 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, return 1; out_oversize: - net_dbg_ratelimited("ip6_frag_reasm: payload len = %d\n", payload_len); + if (net_ratelimit()) + printk(KERN_DEBUG "ip6_frag_reasm: payload len = %d\n", payload_len); goto out_fail; out_oom: - net_dbg_ratelimited("ip6_frag_reasm: no memory for reassembly\n"); + if (net_ratelimit()) + printk(KERN_DEBUG "ip6_frag_reasm: no memory for reassembly\n"); out_fail: rcu_read_lock(); IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c index 999a982ad3fd..0aefc36f74c7 100644 --- a/trunk/net/ipv6/route.c +++ b/trunk/net/ipv6/route.c @@ -24,8 +24,6 @@ * Fixed routing subtrees. */ -#define pr_fmt(fmt) "IPv6: " fmt - #include #include #include @@ -333,22 +331,22 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, } } -static bool rt6_check_expired(const struct rt6_info *rt) +static __inline__ int rt6_check_expired(const struct rt6_info *rt) { struct rt6_info *ort = NULL; if (rt->rt6i_flags & RTF_EXPIRES) { if (time_after(jiffies, rt->dst.expires)) - return true; + return 1; } else if (rt->dst.from) { ort = (struct rt6_info *) rt->dst.from; return (ort->rt6i_flags & RTF_EXPIRES) && time_after(jiffies, ort->dst.expires); } - return false; + return 0; } -static bool rt6_need_strict(const struct in6_addr *daddr) +static inline int rt6_need_strict(const struct in6_addr *daddr) { return ipv6_addr_type(daddr) & (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK); @@ -796,7 +794,9 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, goto retry; } - net_warn_ratelimited("Neighbour table overflow\n"); + if (net_ratelimit()) + printk(KERN_WARNING + "ipv6: Neighbour table overflow.\n"); dst_free(&rt->dst); return NULL; } @@ -1282,7 +1282,7 @@ int ip6_route_add(struct fib6_config *cfg) !(cfg->fc_nlinfo.nlh->nlmsg_flags & NLM_F_CREATE)) { table = fib6_get_table(net, cfg->fc_table); if (!table) { - pr_warn("NLM_F_CREATE should be specified when creating new route\n"); + printk(KERN_WARNING "IPv6: NLM_F_CREATE should be specified when creating new route\n"); table = fib6_new_table(net, cfg->fc_table); } } else { @@ -1643,7 +1643,9 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src, rt = ip6_route_redirect(dest, src, saddr, neigh->dev); if (rt == net->ipv6.ip6_null_entry) { - net_dbg_ratelimited("rt6_redirect: source isn't a valid nexthop for redirect target\n"); + if (net_ratelimit()) + printk(KERN_DEBUG "rt6_redirect: source isn't a valid nexthop " + "for redirect target\n"); goto out; } @@ -2104,7 +2106,9 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, int err; if (!rt) { - net_warn_ratelimited("Maximum number of routes reached, consider increasing route/max_size\n"); + if (net_ratelimit()) + pr_warning("IPv6: Maximum number of routes reached," + " consider increasing route/max_size.\n"); return ERR_PTR(-ENOMEM); } diff --git a/trunk/net/ipv6/sit.c b/trunk/net/ipv6/sit.c index 60415711563f..e5fef943e30a 100644 --- a/trunk/net/ipv6/sit.c +++ b/trunk/net/ipv6/sit.c @@ -17,8 +17,6 @@ * Fred Templin : isatap support */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -704,7 +702,8 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, neigh = dst_neigh_lookup(skb_dst(skb), &iph6->daddr); if (neigh == NULL) { - net_dbg_ratelimited("sit: nexthop == NULL\n"); + if (net_ratelimit()) + printk(KERN_DEBUG "sit: nexthop == NULL\n"); goto tx_error; } @@ -733,7 +732,8 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, neigh = dst_neigh_lookup(skb_dst(skb), &iph6->daddr); if (neigh == NULL) { - net_dbg_ratelimited("sit: nexthop == NULL\n"); + if (net_ratelimit()) + printk(KERN_DEBUG "sit: nexthop == NULL\n"); goto tx_error; } @@ -1303,7 +1303,7 @@ static int __init sit_init(void) { int err; - pr_info("IPv6 over IPv4 tunneling driver\n"); + printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n"); err = register_pernet_device(&sit_net_ops); if (err < 0) @@ -1311,7 +1311,7 @@ static int __init sit_init(void) err = xfrm4_tunnel_register(&sit_handler, AF_INET6); if (err < 0) { unregister_pernet_device(&sit_net_ops); - pr_info("%s: can't add protocol\n", __func__); + printk(KERN_INFO "sit init: Can't add protocol\n"); } return err; } diff --git a/trunk/net/ipv6/tcp_ipv6.c b/trunk/net/ipv6/tcp_ipv6.c index 554d5999abc4..078d039e8fd2 100644 --- a/trunk/net/ipv6/tcp_ipv6.c +++ b/trunk/net/ipv6/tcp_ipv6.c @@ -723,10 +723,12 @@ static int tcp_v6_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) NULL, NULL, skb); if (genhash || memcmp(hash_location, newhash, 16) != 0) { - net_info_ratelimited("MD5 Hash %s for [%pI6c]:%u->[%pI6c]:%u\n", - genhash ? "failed" : "mismatch", - &ip6h->saddr, ntohs(th->source), - &ip6h->daddr, ntohs(th->dest)); + if (net_ratelimit()) { + printk(KERN_INFO "MD5 Hash %s for [%pI6c]:%u->[%pI6c]:%u\n", + genhash ? "failed" : "mismatch", + &ip6h->saddr, ntohs(th->source), + &ip6h->daddr, ntohs(th->dest)); + } return 1; } return 0; @@ -1055,7 +1057,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) struct tcp_sock *tp = tcp_sk(sk); __u32 isn = TCP_SKB_CB(skb)->when; struct dst_entry *dst = NULL; - bool want_cookie = false; + int want_cookie = 0; if (skb->protocol == htons(ETH_P_IP)) return tcp_v4_conn_request(sk, skb); @@ -1116,7 +1118,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) while (l-- > 0) *c++ ^= *hash_location++; - want_cookie = false; /* not our kind of cookie */ + want_cookie = 0; /* not our kind of cookie */ tmp_ext.cookie_out_never = 0; /* false */ tmp_ext.cookie_plus = tmp_opt.cookie_plus; } else if (!tp->rx_opt.cookie_in_always) { diff --git a/trunk/net/ipv6/tunnel6.c b/trunk/net/ipv6/tunnel6.c index 4b0f50d9a962..4f3cec12aa85 100644 --- a/trunk/net/ipv6/tunnel6.c +++ b/trunk/net/ipv6/tunnel6.c @@ -19,8 +19,6 @@ * YOSHIFUJI Hideaki */ -#define pr_fmt(fmt) "IPv6: " fmt - #include #include #include @@ -162,11 +160,11 @@ static const struct inet6_protocol tunnel46_protocol = { static int __init tunnel6_init(void) { if (inet6_add_protocol(&tunnel6_protocol, IPPROTO_IPV6)) { - pr_err("%s: can't add protocol\n", __func__); + printk(KERN_ERR "tunnel6 init(): can't add protocol\n"); return -EAGAIN; } if (inet6_add_protocol(&tunnel46_protocol, IPPROTO_IPIP)) { - pr_err("%s: can't add protocol\n", __func__); + printk(KERN_ERR "tunnel6 init(): can't add protocol\n"); inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6); return -EAGAIN; } @@ -176,9 +174,9 @@ static int __init tunnel6_init(void) static void __exit tunnel6_fini(void) { if (inet6_del_protocol(&tunnel46_protocol, IPPROTO_IPIP)) - pr_err("%s: can't remove protocol\n", __func__); + printk(KERN_ERR "tunnel6 close: can't remove protocol\n"); if (inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6)) - pr_err("%s: can't remove protocol\n", __func__); + printk(KERN_ERR "tunnel6 close: can't remove protocol\n"); } module_init(tunnel6_init); diff --git a/trunk/net/ipv6/udp.c b/trunk/net/ipv6/udp.c index f05099fc5901..c1d91a713e8e 100644 --- a/trunk/net/ipv6/udp.c +++ b/trunk/net/ipv6/udp.c @@ -103,7 +103,7 @@ int udp_v6_get_port(struct sock *sk, unsigned short snum) { unsigned int hash2_nulladdr = udp6_portaddr_hash(sock_net(sk), &in6addr_any, snum); - unsigned int hash2_partial = + unsigned int hash2_partial = udp6_portaddr_hash(sock_net(sk), &inet6_sk(sk)->rcv_saddr, 0); /* precompute partial secondary hash */ @@ -349,7 +349,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, bool slow; if (addr_len) - *addr_len = sizeof(struct sockaddr_in6); + *addr_len=sizeof(struct sockaddr_in6); if (flags & MSG_ERRQUEUE) return ipv6_recv_error(sk, msg, len); @@ -1379,7 +1379,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, * do checksum of UDP packets sent as multiple IP fragments. */ offset = skb_checksum_start_offset(skb); - csum = skb_checksum(skb, offset, skb->len - offset, 0); + csum = skb_checksum(skb, offset, skb->len- offset, 0); offset += skb->csum_offset; *(__sum16 *)(skb->data + offset) = csum_fold(csum); skb->ip_summed = CHECKSUM_NONE; diff --git a/trunk/net/ipx/af_ipx.c b/trunk/net/ipx/af_ipx.c index dfd6faaf0ea7..9680226640ef 100644 --- a/trunk/net/ipx/af_ipx.c +++ b/trunk/net/ipx/af_ipx.c @@ -983,6 +983,10 @@ static int ipxitf_create(struct ipx_interface_definition *idef) goto out; switch (idef->ipx_dlink_type) { + case IPX_FRAME_TR_8022: + printk(KERN_WARNING "IPX frame type 802.2TR is " + "obsolete Use 802.2 instead.\n"); + /* fall through */ case IPX_FRAME_8022: dlink_type = htons(ETH_P_802_2); datalink = p8022_datalink; @@ -992,7 +996,10 @@ static int ipxitf_create(struct ipx_interface_definition *idef) dlink_type = htons(ETH_P_IPX); datalink = pEII_datalink; break; - } + } else + printk(KERN_WARNING "IPX frame type EtherII over " + "token-ring is obsolete. Use SNAP " + "instead.\n"); /* fall through */ case IPX_FRAME_SNAP: dlink_type = htons(ETH_P_SNAP); @@ -1268,6 +1275,7 @@ const char *ipx_frame_name(__be16 frame) case ETH_P_802_2: rc = "802.2"; break; case ETH_P_SNAP: rc = "SNAP"; break; case ETH_P_802_3: rc = "802.3"; break; + case ETH_P_TR_802_2: rc = "802.2TR"; break; } return rc; @@ -1901,7 +1909,9 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) (const unsigned short __user *)argp); break; case SIOCGSTAMP: - rc = sock_get_timestamp(sk, argp); + rc = -EINVAL; + if (sk) + rc = sock_get_timestamp(sk, argp); break; case SIOCGIFDSTADDR: case SIOCSIFDSTADDR: diff --git a/trunk/net/l2tp/l2tp_core.c b/trunk/net/l2tp/l2tp_core.c index 32b2155e7ab4..456b52d8f6d8 100644 --- a/trunk/net/l2tp/l2tp_core.c +++ b/trunk/net/l2tp/l2tp_core.c @@ -18,8 +18,6 @@ * published by the Free Software Foundation. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -88,6 +86,12 @@ /* Default trace flags */ #define L2TP_DEFAULT_DEBUG_FLAGS 0 +#define PRINTK(_mask, _type, _lvl, _fmt, args...) \ + do { \ + if ((_mask) & (_type)) \ + printk(_lvl "L2TP: " _fmt, ##args); \ + } while (0) + /* Private data stored for received packets in the skb. */ struct l2tp_skb_cb { @@ -137,20 +141,14 @@ static inline void l2tp_tunnel_dec_refcount_1(struct l2tp_tunnel *tunnel) l2tp_tunnel_free(tunnel); } #ifdef L2TP_REFCNT_DEBUG -#define l2tp_tunnel_inc_refcount(_t) \ -do { \ - pr_debug("l2tp_tunnel_inc_refcount: %s:%d %s: cnt=%d\n", \ - __func__, __LINE__, (_t)->name, \ - atomic_read(&_t->ref_count)); \ - l2tp_tunnel_inc_refcount_1(_t); \ -} while (0) -#define l2tp_tunnel_dec_refcount(_t) -do { \ - pr_debug("l2tp_tunnel_dec_refcount: %s:%d %s: cnt=%d\n", \ - __func__, __LINE__, (_t)->name, \ - atomic_read(&_t->ref_count)); \ - l2tp_tunnel_dec_refcount_1(_t); \ -} while (0) +#define l2tp_tunnel_inc_refcount(_t) do { \ + printk(KERN_DEBUG "l2tp_tunnel_inc_refcount: %s:%d %s: cnt=%d\n", __func__, __LINE__, (_t)->name, atomic_read(&_t->ref_count)); \ + l2tp_tunnel_inc_refcount_1(_t); \ + } while (0) +#define l2tp_tunnel_dec_refcount(_t) do { \ + printk(KERN_DEBUG "l2tp_tunnel_dec_refcount: %s:%d %s: cnt=%d\n", __func__, __LINE__, (_t)->name, atomic_read(&_t->ref_count)); \ + l2tp_tunnel_dec_refcount_1(_t); \ + } while (0) #else #define l2tp_tunnel_inc_refcount(t) l2tp_tunnel_inc_refcount_1(t) #define l2tp_tunnel_dec_refcount(t) l2tp_tunnel_dec_refcount_1(t) @@ -339,10 +337,10 @@ static void l2tp_recv_queue_skb(struct l2tp_session *session, struct sk_buff *sk skb_queue_walk_safe(&session->reorder_q, skbp, tmp) { if (L2TP_SKB_CB(skbp)->ns > ns) { __skb_queue_before(&session->reorder_q, skbp, skb); - l2tp_dbg(session, L2TP_MSG_SEQ, - "%s: pkt %hu, inserted before %hu, reorder_q len=%d\n", - session->name, ns, L2TP_SKB_CB(skbp)->ns, - skb_queue_len(&session->reorder_q)); + PRINTK(session->debug, L2TP_MSG_SEQ, KERN_DEBUG, + "%s: pkt %hu, inserted before %hu, reorder_q len=%d\n", + session->name, ns, L2TP_SKB_CB(skbp)->ns, + skb_queue_len(&session->reorder_q)); u64_stats_update_begin(&sstats->syncp); sstats->rx_oos_packets++; u64_stats_update_end(&sstats->syncp); @@ -388,8 +386,8 @@ static void l2tp_recv_dequeue_skb(struct l2tp_session *session, struct sk_buff * else session->nr &= 0xffffff; - l2tp_dbg(session, L2TP_MSG_SEQ, "%s: updated nr to %hu\n", - session->name, session->nr); + PRINTK(session->debug, L2TP_MSG_SEQ, KERN_DEBUG, + "%s: updated nr to %hu\n", session->name, session->nr); } /* call private receive handler */ @@ -424,12 +422,12 @@ static void l2tp_recv_dequeue(struct l2tp_session *session) sstats->rx_seq_discards++; sstats->rx_errors++; u64_stats_update_end(&sstats->syncp); - l2tp_dbg(session, L2TP_MSG_SEQ, - "%s: oos pkt %u len %d discarded (too old), waiting for %u, reorder_q_len=%d\n", - session->name, L2TP_SKB_CB(skb)->ns, - L2TP_SKB_CB(skb)->length, session->nr, - skb_queue_len(&session->reorder_q)); - session->reorder_skip = 1; + PRINTK(session->debug, L2TP_MSG_SEQ, KERN_DEBUG, + "%s: oos pkt %u len %d discarded (too old), " + "waiting for %u, reorder_q_len=%d\n", + session->name, L2TP_SKB_CB(skb)->ns, + L2TP_SKB_CB(skb)->length, session->nr, + skb_queue_len(&session->reorder_q)); __skb_unlink(skb, &session->reorder_q); kfree_skb(skb); if (session->deref) @@ -438,20 +436,13 @@ static void l2tp_recv_dequeue(struct l2tp_session *session) } if (L2TP_SKB_CB(skb)->has_seq) { - if (session->reorder_skip) { - l2tp_dbg(session, L2TP_MSG_SEQ, - "%s: advancing nr to next pkt: %u -> %u", - session->name, session->nr, - L2TP_SKB_CB(skb)->ns); - session->reorder_skip = 0; - session->nr = L2TP_SKB_CB(skb)->ns; - } if (L2TP_SKB_CB(skb)->ns != session->nr) { - l2tp_dbg(session, L2TP_MSG_SEQ, - "%s: holding oos pkt %u len %d, waiting for %u, reorder_q_len=%d\n", - session->name, L2TP_SKB_CB(skb)->ns, - L2TP_SKB_CB(skb)->length, session->nr, - skb_queue_len(&session->reorder_q)); + PRINTK(session->debug, L2TP_MSG_SEQ, KERN_DEBUG, + "%s: holding oos pkt %u len %d, " + "waiting for %u, reorder_q_len=%d\n", + session->name, L2TP_SKB_CB(skb)->ns, + L2TP_SKB_CB(skb)->length, session->nr, + skb_queue_len(&session->reorder_q)); goto out; } } @@ -595,10 +586,9 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, /* Parse and check optional cookie */ if (session->peer_cookie_len > 0) { if (memcmp(ptr, &session->peer_cookie[0], session->peer_cookie_len)) { - l2tp_info(tunnel, L2TP_MSG_DATA, - "%s: cookie mismatch (%u/%u). Discarding.\n", - tunnel->name, tunnel->tunnel_id, - session->session_id); + PRINTK(tunnel->debug, L2TP_MSG_DATA, KERN_INFO, + "%s: cookie mismatch (%u/%u). Discarding.\n", + tunnel->name, tunnel->tunnel_id, session->session_id); u64_stats_update_begin(&sstats->syncp); sstats->rx_cookie_discards++; u64_stats_update_end(&sstats->syncp); @@ -627,9 +617,9 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, L2TP_SKB_CB(skb)->ns = ns; L2TP_SKB_CB(skb)->has_seq = 1; - l2tp_dbg(session, L2TP_MSG_SEQ, - "%s: recv data ns=%u, nr=%u, session nr=%u\n", - session->name, ns, nr, session->nr); + PRINTK(session->debug, L2TP_MSG_SEQ, KERN_DEBUG, + "%s: recv data ns=%u, nr=%u, session nr=%u\n", + session->name, ns, nr, session->nr); } } else if (session->l2specific_type == L2TP_L2SPECTYPE_DEFAULT) { u32 l2h = ntohl(*(__be32 *) ptr); @@ -641,9 +631,9 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, L2TP_SKB_CB(skb)->ns = ns; L2TP_SKB_CB(skb)->has_seq = 1; - l2tp_dbg(session, L2TP_MSG_SEQ, - "%s: recv data ns=%u, session nr=%u\n", - session->name, ns, session->nr); + PRINTK(session->debug, L2TP_MSG_SEQ, KERN_DEBUG, + "%s: recv data ns=%u, session nr=%u\n", + session->name, ns, session->nr); } } @@ -656,9 +646,9 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, * configure it so. */ if ((!session->lns_mode) && (!session->send_seq)) { - l2tp_info(session, L2TP_MSG_SEQ, - "%s: requested to enable seq numbers by LNS\n", - session->name); + PRINTK(session->debug, L2TP_MSG_SEQ, KERN_INFO, + "%s: requested to enable seq numbers by LNS\n", + session->name); session->send_seq = -1; l2tp_session_set_header_len(session, tunnel->version); } @@ -667,9 +657,9 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, * If user has configured mandatory sequence numbers, discard. */ if (session->recv_seq) { - l2tp_warn(session, L2TP_MSG_SEQ, - "%s: recv data has no seq numbers when required. Discarding.\n", - session->name); + PRINTK(session->debug, L2TP_MSG_SEQ, KERN_WARNING, + "%s: recv data has no seq numbers when required. " + "Discarding\n", session->name); u64_stats_update_begin(&sstats->syncp); sstats->rx_seq_discards++; u64_stats_update_end(&sstats->syncp); @@ -682,15 +672,15 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, * LAC is broken. Discard the frame. */ if ((!session->lns_mode) && (session->send_seq)) { - l2tp_info(session, L2TP_MSG_SEQ, - "%s: requested to disable seq numbers by LNS\n", - session->name); + PRINTK(session->debug, L2TP_MSG_SEQ, KERN_INFO, + "%s: requested to disable seq numbers by LNS\n", + session->name); session->send_seq = 0; l2tp_session_set_header_len(session, tunnel->version); } else if (session->send_seq) { - l2tp_warn(session, L2TP_MSG_SEQ, - "%s: recv data has no seq numbers when required. Discarding.\n", - session->name); + PRINTK(session->debug, L2TP_MSG_SEQ, KERN_WARNING, + "%s: recv data has no seq numbers when required. " + "Discarding\n", session->name); u64_stats_update_begin(&sstats->syncp); sstats->rx_seq_discards++; u64_stats_update_end(&sstats->syncp); @@ -750,11 +740,12 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, u64_stats_update_begin(&sstats->syncp); sstats->rx_seq_discards++; u64_stats_update_end(&sstats->syncp); - l2tp_dbg(session, L2TP_MSG_SEQ, - "%s: oos pkt %u len %d discarded, waiting for %u, reorder_q_len=%d\n", - session->name, L2TP_SKB_CB(skb)->ns, - L2TP_SKB_CB(skb)->length, session->nr, - skb_queue_len(&session->reorder_q)); + PRINTK(session->debug, L2TP_MSG_SEQ, KERN_DEBUG, + "%s: oos pkt %u len %d discarded, " + "waiting for %u, reorder_q_len=%d\n", + session->name, L2TP_SKB_CB(skb)->ns, + L2TP_SKB_CB(skb)->length, session->nr, + skb_queue_len(&session->reorder_q)); goto discard; } skb_queue_tail(&session->reorder_q, skb); @@ -800,6 +791,7 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb, unsigned char *ptr, *optr; u16 hdrflags; u32 tunnel_id, session_id; + int offset; u16 version; int length; struct l2tp_stats *tstats; @@ -812,9 +804,8 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb, /* Short packet? */ if (!pskb_may_pull(skb, L2TP_HDR_SIZE_SEQ)) { - l2tp_info(tunnel, L2TP_MSG_DATA, - "%s: recv short packet (len=%d)\n", - tunnel->name, skb->len); + PRINTK(tunnel->debug, L2TP_MSG_DATA, KERN_INFO, + "%s: recv short packet (len=%d)\n", tunnel->name, skb->len); goto error; } @@ -824,8 +815,14 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb, if (!pskb_may_pull(skb, length)) goto error; - pr_debug("%s: recv\n", tunnel->name); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, skb->data, length); + printk(KERN_DEBUG "%s: recv: ", tunnel->name); + + offset = 0; + do { + printk(" %02X", skb->data[offset]); + } while (++offset < length); + + printk("\n"); } /* Point to L2TP header */ @@ -837,9 +834,9 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb, /* Check protocol version */ version = hdrflags & L2TP_HDR_VER_MASK; if (version != tunnel->version) { - l2tp_info(tunnel, L2TP_MSG_DATA, - "%s: recv protocol version mismatch: got %d expected %d\n", - tunnel->name, version, tunnel->version); + PRINTK(tunnel->debug, L2TP_MSG_DATA, KERN_INFO, + "%s: recv protocol version mismatch: got %d expected %d\n", + tunnel->name, version, tunnel->version); goto error; } @@ -848,9 +845,8 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb, /* If type is control packet, it is handled by userspace. */ if (hdrflags & L2TP_HDRFLAG_T) { - l2tp_dbg(tunnel, L2TP_MSG_DATA, - "%s: recv control packet, len=%d\n", - tunnel->name, length); + PRINTK(tunnel->debug, L2TP_MSG_DATA, KERN_DEBUG, + "%s: recv control packet, len=%d\n", tunnel->name, length); goto error; } @@ -878,9 +874,9 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb, session = l2tp_session_find(tunnel->l2tp_net, tunnel, session_id); if (!session || !session->recv_skb) { /* Not found? Pass to userspace to deal with */ - l2tp_info(tunnel, L2TP_MSG_DATA, - "%s: no session found (%u/%u). Passing up.\n", - tunnel->name, tunnel_id, session_id); + PRINTK(tunnel->debug, L2TP_MSG_DATA, KERN_INFO, + "%s: no session found (%u/%u). Passing up.\n", + tunnel->name, tunnel_id, session_id); goto error; } @@ -920,8 +916,8 @@ int l2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) if (tunnel == NULL) goto pass_up; - l2tp_dbg(tunnel, L2TP_MSG_DATA, "%s: received %d bytes\n", - tunnel->name, skb->len); + PRINTK(tunnel->debug, L2TP_MSG_DATA, KERN_DEBUG, + "%s: received %d bytes\n", tunnel->name, skb->len); if (l2tp_udp_recv_core(tunnel, skb, tunnel->recv_payload_hook)) goto pass_up_put; @@ -963,8 +959,8 @@ static int l2tp_build_l2tpv2_header(struct l2tp_session *session, void *buf) *bufp++ = 0; session->ns++; session->ns &= 0xffff; - l2tp_dbg(session, L2TP_MSG_SEQ, "%s: updated ns to %u\n", - session->name, session->ns); + PRINTK(session->debug, L2TP_MSG_SEQ, KERN_DEBUG, + "%s: updated ns to %u\n", session->name, session->ns); } return bufp - optr; @@ -1000,9 +996,8 @@ static int l2tp_build_l2tpv3_header(struct l2tp_session *session, void *buf) l2h = 0x40000000 | session->ns; session->ns++; session->ns &= 0xffffff; - l2tp_dbg(session, L2TP_MSG_SEQ, - "%s: updated ns to %u\n", - session->name, session->ns); + PRINTK(session->debug, L2TP_MSG_SEQ, KERN_DEBUG, + "%s: updated ns to %u\n", session->name, session->ns); } *((__be32 *) bufp) = htonl(l2h); @@ -1025,19 +1020,27 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, /* Debug */ if (session->send_seq) - l2tp_dbg(session, L2TP_MSG_DATA, "%s: send %Zd bytes, ns=%u\n", - session->name, data_len, session->ns - 1); + PRINTK(session->debug, L2TP_MSG_DATA, KERN_DEBUG, + "%s: send %Zd bytes, ns=%u\n", session->name, + data_len, session->ns - 1); else - l2tp_dbg(session, L2TP_MSG_DATA, "%s: send %Zd bytes\n", - session->name, data_len); + PRINTK(session->debug, L2TP_MSG_DATA, KERN_DEBUG, + "%s: send %Zd bytes\n", session->name, data_len); if (session->debug & L2TP_MSG_DATA) { + int i; int uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0; unsigned char *datap = skb->data + uhlen; - pr_debug("%s: xmit\n", session->name); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - datap, min_t(size_t, 32, len - uhlen)); + printk(KERN_DEBUG "%s: xmit:", session->name); + for (i = 0; i < (len - uhlen); i++) { + printk(" %02X", *datap++); + if (i == 31) { + printk(" ..."); + break; + } + } + printk("\n"); } /* Queue the packet to IP for output */ @@ -1236,7 +1239,8 @@ static void l2tp_tunnel_destruct(struct sock *sk) if (tunnel == NULL) goto end; - l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: closing...\n", tunnel->name); + PRINTK(tunnel->debug, L2TP_MSG_CONTROL, KERN_INFO, + "%s: closing...\n", tunnel->name); /* Close all sessions */ l2tp_tunnel_closeall(tunnel); @@ -1278,8 +1282,8 @@ static void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel) BUG_ON(tunnel == NULL); - l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: closing all sessions...\n", - tunnel->name); + PRINTK(tunnel->debug, L2TP_MSG_CONTROL, KERN_INFO, + "%s: closing all sessions...\n", tunnel->name); write_lock_bh(&tunnel->hlist_lock); for (hash = 0; hash < L2TP_HASH_SIZE; hash++) { @@ -1287,8 +1291,8 @@ static void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel) hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) { session = hlist_entry(walk, struct l2tp_session, hlist); - l2tp_info(session, L2TP_MSG_CONTROL, - "%s: closing session\n", session->name); + PRINTK(session->debug, L2TP_MSG_CONTROL, KERN_INFO, + "%s: closing session\n", session->name); hlist_del_init(&session->hlist); @@ -1341,7 +1345,8 @@ static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel) BUG_ON(atomic_read(&tunnel->ref_count) != 0); BUG_ON(tunnel->sock != NULL); - l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: free...\n", tunnel->name); + PRINTK(tunnel->debug, L2TP_MSG_CONTROL, KERN_INFO, + "%s: free...\n", tunnel->name); /* Remove from tunnel list */ spin_lock_bh(&pn->l2tp_tunnel_list_lock); @@ -1522,7 +1527,7 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 err = -EBADF; sock = sockfd_lookup(fd, &err); if (!sock) { - pr_err("tunl %hu: sockfd_lookup(fd=%d) returned %d\n", + printk(KERN_ERR "tunl %hu: sockfd_lookup(fd=%d) returned %d\n", tunnel_id, fd, err); goto err; } @@ -1538,7 +1543,7 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 case L2TP_ENCAPTYPE_UDP: err = -EPROTONOSUPPORT; if (sk->sk_protocol != IPPROTO_UDP) { - pr_err("tunl %hu: fd %d wrong protocol, got %d, expected %d\n", + printk(KERN_ERR "tunl %hu: fd %d wrong protocol, got %d, expected %d\n", tunnel_id, fd, sk->sk_protocol, IPPROTO_UDP); goto err; } @@ -1546,7 +1551,7 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 case L2TP_ENCAPTYPE_IP: err = -EPROTONOSUPPORT; if (sk->sk_protocol != IPPROTO_L2TP) { - pr_err("tunl %hu: fd %d wrong protocol, got %d, expected %d\n", + printk(KERN_ERR "tunl %hu: fd %d wrong protocol, got %d, expected %d\n", tunnel_id, fd, sk->sk_protocol, IPPROTO_L2TP); goto err; } @@ -1748,7 +1753,7 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn session->session_id = session_id; session->peer_session_id = peer_session_id; - session->nr = 0; + session->nr = 1; sprintf(&session->name[0], "sess %u/%u", tunnel->tunnel_id, session->session_id); @@ -1854,7 +1859,7 @@ static int __init l2tp_init(void) if (rc) goto out; - pr_info("L2TP core driver, %s\n", L2TP_DRV_VERSION); + printk(KERN_INFO "L2TP core driver, %s\n", L2TP_DRV_VERSION); out: return rc; diff --git a/trunk/net/l2tp/l2tp_core.h b/trunk/net/l2tp/l2tp_core.h index a38ec6cdeee1..0bf60fc88bb7 100644 --- a/trunk/net/l2tp/l2tp_core.h +++ b/trunk/net/l2tp/l2tp_core.h @@ -123,7 +123,6 @@ struct l2tp_session { * categories */ int reorder_timeout; /* configured reorder timeout * (in jiffies) */ - int reorder_skip; /* set if skip to next nr */ int mtu; int mru; enum l2tp_pwtype pwtype; @@ -261,36 +260,17 @@ static inline void l2tp_session_dec_refcount_1(struct l2tp_session *session) } #ifdef L2TP_REFCNT_DEBUG -#define l2tp_session_inc_refcount(_s) \ -do { \ - pr_debug("l2tp_session_inc_refcount: %s:%d %s: cnt=%d\n", \ - __func__, __LINE__, (_s)->name, \ - atomic_read(&_s->ref_count)); \ - l2tp_session_inc_refcount_1(_s); \ -} while (0) -#define l2tp_session_dec_refcount(_s) \ -do { \ - pr_debug("l2tp_session_dec_refcount: %s:%d %s: cnt=%d\n", \ - __func__, __LINE__, (_s)->name, \ - atomic_read(&_s->ref_count)); \ - l2tp_session_dec_refcount_1(_s); \ -} while (0) +#define l2tp_session_inc_refcount(_s) do { \ + printk(KERN_DEBUG "l2tp_session_inc_refcount: %s:%d %s: cnt=%d\n", __func__, __LINE__, (_s)->name, atomic_read(&_s->ref_count)); \ + l2tp_session_inc_refcount_1(_s); \ + } while (0) +#define l2tp_session_dec_refcount(_s) do { \ + printk(KERN_DEBUG "l2tp_session_dec_refcount: %s:%d %s: cnt=%d\n", __func__, __LINE__, (_s)->name, atomic_read(&_s->ref_count)); \ + l2tp_session_dec_refcount_1(_s); \ + } while (0) #else #define l2tp_session_inc_refcount(s) l2tp_session_inc_refcount_1(s) #define l2tp_session_dec_refcount(s) l2tp_session_dec_refcount_1(s) #endif -#define l2tp_printk(ptr, type, func, fmt, ...) \ -do { \ - if (((ptr)->debug) & (type)) \ - func(fmt, ##__VA_ARGS__); \ -} while (0) - -#define l2tp_warn(ptr, type, fmt, ...) \ - l2tp_printk(ptr, type, pr_warn, fmt, ##__VA_ARGS__) -#define l2tp_info(ptr, type, fmt, ...) \ - l2tp_printk(ptr, type, pr_info, fmt, ##__VA_ARGS__) -#define l2tp_dbg(ptr, type, fmt, ...) \ - l2tp_printk(ptr, type, pr_debug, fmt, ##__VA_ARGS__) - #endif /* _L2TP_CORE_H_ */ diff --git a/trunk/net/l2tp/l2tp_debugfs.c b/trunk/net/l2tp/l2tp_debugfs.c index c3813bc84552..c0d57bad8b79 100644 --- a/trunk/net/l2tp/l2tp_debugfs.c +++ b/trunk/net/l2tp/l2tp_debugfs.c @@ -9,8 +9,6 @@ * 2 of the License, or (at your option) any later version. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -327,11 +325,11 @@ static int __init l2tp_debugfs_init(void) if (tunnels == NULL) rc = -EIO; - pr_info("L2TP debugfs support\n"); + printk(KERN_INFO "L2TP debugfs support\n"); out: if (rc) - pr_warn("unable to init\n"); + printk(KERN_WARNING "l2tp debugfs: unable to init\n"); return rc; } diff --git a/trunk/net/l2tp/l2tp_eth.c b/trunk/net/l2tp/l2tp_eth.c index 443591d629ca..63fe5f353f04 100644 --- a/trunk/net/l2tp/l2tp_eth.c +++ b/trunk/net/l2tp/l2tp_eth.c @@ -9,8 +9,6 @@ * 2 of the License, or (at your option) any later version. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -117,14 +115,21 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, if (session->debug & L2TP_MSG_DATA) { unsigned int length; + int offset; u8 *ptr = skb->data; length = min(32u, skb->len); if (!pskb_may_pull(skb, length)) goto error; - pr_debug("%s: eth recv\n", session->name); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); + printk(KERN_DEBUG "%s: eth recv: ", session->name); + + offset = 0; + do { + printk(" %02X", ptr[offset]); + } while (++offset < length); + + printk("\n"); } if (!pskb_may_pull(skb, sizeof(ETH_HLEN))) @@ -303,7 +308,7 @@ static int __init l2tp_eth_init(void) if (err) goto out_unreg; - pr_info("L2TP ethernet pseudowire support (L2TPv3)\n"); + printk(KERN_INFO "L2TP ethernet pseudowire support (L2TPv3)\n"); return 0; diff --git a/trunk/net/l2tp/l2tp_ip.c b/trunk/net/l2tp/l2tp_ip.c index 889f5d13d7ba..c89a32fb5d5e 100644 --- a/trunk/net/l2tp/l2tp_ip.c +++ b/trunk/net/l2tp/l2tp_ip.c @@ -9,8 +9,6 @@ * 2 of the License, or (at your option) any later version. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -122,6 +120,7 @@ static int l2tp_ip_recv(struct sk_buff *skb) struct l2tp_session *session; struct l2tp_tunnel *tunnel = NULL; int length; + int offset; /* Point to L2TP header */ optr = ptr = skb->data; @@ -156,8 +155,14 @@ static int l2tp_ip_recv(struct sk_buff *skb) if (!pskb_may_pull(skb, length)) goto discard; - pr_debug("%s: ip recv\n", tunnel->name); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); + printk(KERN_DEBUG "%s: ip recv: ", tunnel->name); + + offset = 0; + do { + printk(" %02X", ptr[offset]); + } while (++offset < length); + + printk("\n"); } l2tp_recv_common(session, skb, ptr, optr, 0, skb->len, tunnel->recv_payload_hook); @@ -588,7 +593,7 @@ static int __init l2tp_ip_init(void) { int err; - pr_info("L2TP IP encapsulation support (L2TPv3)\n"); + printk(KERN_INFO "L2TP IP encapsulation support (L2TPv3)\n"); err = proto_register(&l2tp_ip_prot, 1); if (err != 0) diff --git a/trunk/net/l2tp/l2tp_ip6.c b/trunk/net/l2tp/l2tp_ip6.c index 0291d8d85f30..88f0abe35443 100644 --- a/trunk/net/l2tp/l2tp_ip6.c +++ b/trunk/net/l2tp/l2tp_ip6.c @@ -9,8 +9,6 @@ * 2 of the License, or (at your option) any later version. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -135,6 +133,7 @@ static int l2tp_ip6_recv(struct sk_buff *skb) struct l2tp_session *session; struct l2tp_tunnel *tunnel = NULL; int length; + int offset; /* Point to L2TP header */ optr = ptr = skb->data; @@ -169,8 +168,14 @@ static int l2tp_ip6_recv(struct sk_buff *skb) if (!pskb_may_pull(skb, length)) goto discard; - pr_debug("%s: ip recv\n", tunnel->name); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); + printk(KERN_DEBUG "%s: ip recv: ", tunnel->name); + + offset = 0; + do { + printk(" %02X", ptr[offset]); + } while (++offset < length); + + printk("\n"); } l2tp_recv_common(session, skb, ptr, optr, 0, skb->len, @@ -747,7 +752,7 @@ static int __init l2tp_ip6_init(void) { int err; - pr_info("L2TP IP encapsulation support for IPv6 (L2TPv3)\n"); + printk(KERN_INFO "L2TP IP encapsulation support for IPv6 (L2TPv3)\n"); err = proto_register(&l2tp_ip6_prot, 1); if (err != 0) diff --git a/trunk/net/l2tp/l2tp_netlink.c b/trunk/net/l2tp/l2tp_netlink.c index 8577264378fe..24edad0fd9ba 100644 --- a/trunk/net/l2tp/l2tp_netlink.c +++ b/trunk/net/l2tp/l2tp_netlink.c @@ -14,8 +14,6 @@ * published by the Free Software Foundation. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -904,7 +902,7 @@ static int l2tp_nl_init(void) { int err; - pr_info("L2TP netlink interface\n"); + printk(KERN_INFO "L2TP netlink interface\n"); err = genl_register_family_with_ops(&l2tp_nl_family, l2tp_nl_ops, ARRAY_SIZE(l2tp_nl_ops)); diff --git a/trunk/net/l2tp/l2tp_ppp.c b/trunk/net/l2tp/l2tp_ppp.c index 8ef6b9416cba..9f2c421aa307 100644 --- a/trunk/net/l2tp/l2tp_ppp.c +++ b/trunk/net/l2tp/l2tp_ppp.c @@ -57,8 +57,6 @@ * http://openl2tp.sourceforge.net. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -108,6 +106,12 @@ /* Space for UDP, L2TP and PPP headers */ #define PPPOL2TP_HEADER_OVERHEAD 40 +#define PRINTK(_mask, _type, _lvl, _fmt, args...) \ + do { \ + if ((_mask) & (_type)) \ + printk(_lvl "PPPOL2TP: " _fmt, ##args); \ + } while (0) + /* Number of bytes to build transmit L2TP headers. * Unfortunately the size is different depending on whether sequence numbers * are enabled. @@ -232,9 +236,9 @@ static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int if (sk->sk_state & PPPOX_BOUND) { struct pppox_sock *po; - l2tp_dbg(session, PPPOL2TP_MSG_DATA, - "%s: recv %d byte data frame, passing to ppp\n", - session->name, data_len); + PRINTK(session->debug, PPPOL2TP_MSG_DATA, KERN_DEBUG, + "%s: recv %d byte data frame, passing to ppp\n", + session->name, data_len); /* We need to forget all info related to the L2TP packet * gathered in the skb as we are going to reuse the same @@ -255,8 +259,8 @@ static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int po = pppox_sk(sk); ppp_input(&po->chan, skb); } else { - l2tp_info(session, PPPOL2TP_MSG_DATA, "%s: socket not bound\n", - session->name); + PRINTK(session->debug, PPPOL2TP_MSG_DATA, KERN_INFO, + "%s: socket not bound\n", session->name); /* Not bound. Nothing we can do, so discard. */ session->stats.rx_errors++; @@ -266,7 +270,8 @@ static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int return; no_sock: - l2tp_info(session, PPPOL2TP_MSG_DATA, "%s: no socket\n", session->name); + PRINTK(session->debug, PPPOL2TP_MSG_DATA, KERN_INFO, + "%s: no socket\n", session->name); kfree_skb(skb); } @@ -822,8 +827,8 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, /* This is how we get the session context from the socket. */ sk->sk_user_data = session; sk->sk_state = PPPOX_CONNECTED; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: created\n", - session->name); + PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: created\n", session->name); end: release_sock(sk); @@ -876,8 +881,8 @@ static int pppol2tp_session_create(struct net *net, u32 tunnel_id, u32 session_i ps = l2tp_session_priv(session); ps->tunnel_sock = tunnel->sock; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: created\n", - session->name); + PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: created\n", session->name); error = 0; @@ -1053,9 +1058,9 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session, struct l2tp_tunnel *tunnel = session->tunnel; struct pppol2tp_ioc_stats stats; - l2tp_dbg(session, PPPOL2TP_MSG_CONTROL, - "%s: pppol2tp_session_ioctl(cmd=%#x, arg=%#lx)\n", - session->name, cmd, arg); + PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_DEBUG, + "%s: pppol2tp_session_ioctl(cmd=%#x, arg=%#lx)\n", + session->name, cmd, arg); sk = ps->sock; sock_hold(sk); @@ -1073,8 +1078,8 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session, if (copy_to_user((void __user *) arg, &ifr, sizeof(struct ifreq))) break; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: get mtu=%d\n", - session->name, session->mtu); + PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: get mtu=%d\n", session->name, session->mtu); err = 0; break; @@ -1089,8 +1094,8 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session, session->mtu = ifr.ifr_mtu; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: set mtu=%d\n", - session->name, session->mtu); + PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: set mtu=%d\n", session->name, session->mtu); err = 0; break; @@ -1103,8 +1108,8 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session, if (put_user(session->mru, (int __user *) arg)) break; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: get mru=%d\n", - session->name, session->mru); + PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: get mru=%d\n", session->name, session->mru); err = 0; break; @@ -1118,8 +1123,8 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session, break; session->mru = val; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: set mru=%d\n", - session->name, session->mru); + PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: set mru=%d\n", session->name, session->mru); err = 0; break; @@ -1128,8 +1133,8 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session, if (put_user(ps->flags, (int __user *) arg)) break; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: get flags=%d\n", - session->name, ps->flags); + PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: get flags=%d\n", session->name, ps->flags); err = 0; break; @@ -1138,8 +1143,8 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session, if (get_user(val, (int __user *) arg)) break; ps->flags = val; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: set flags=%d\n", - session->name, ps->flags); + PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: set flags=%d\n", session->name, ps->flags); err = 0; break; @@ -1155,8 +1160,8 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session, if (copy_to_user((void __user *) arg, &stats, sizeof(stats))) break; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: get L2TP stats\n", - session->name); + PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: get L2TP stats\n", session->name); err = 0; break; @@ -1183,9 +1188,9 @@ static int pppol2tp_tunnel_ioctl(struct l2tp_tunnel *tunnel, struct sock *sk; struct pppol2tp_ioc_stats stats; - l2tp_dbg(tunnel, PPPOL2TP_MSG_CONTROL, - "%s: pppol2tp_tunnel_ioctl(cmd=%#x, arg=%#lx)\n", - tunnel->name, cmd, arg); + PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_DEBUG, + "%s: pppol2tp_tunnel_ioctl(cmd=%#x, arg=%#lx)\n", + tunnel->name, cmd, arg); sk = tunnel->sock; sock_hold(sk); @@ -1219,8 +1224,8 @@ static int pppol2tp_tunnel_ioctl(struct l2tp_tunnel *tunnel, err = -EFAULT; break; } - l2tp_info(tunnel, PPPOL2TP_MSG_CONTROL, "%s: get L2TP stats\n", - tunnel->name); + PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: get L2TP stats\n", tunnel->name); err = 0; break; @@ -1309,8 +1314,8 @@ static int pppol2tp_tunnel_setsockopt(struct sock *sk, switch (optname) { case PPPOL2TP_SO_DEBUG: tunnel->debug = val; - l2tp_info(tunnel, PPPOL2TP_MSG_CONTROL, "%s: set debug=%x\n", - tunnel->name, tunnel->debug); + PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: set debug=%x\n", tunnel->name, tunnel->debug); break; default: @@ -1337,9 +1342,8 @@ static int pppol2tp_session_setsockopt(struct sock *sk, break; } session->recv_seq = val ? -1 : 0; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, - "%s: set recv_seq=%d\n", - session->name, session->recv_seq); + PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: set recv_seq=%d\n", session->name, session->recv_seq); break; case PPPOL2TP_SO_SENDSEQ: @@ -1354,9 +1358,8 @@ static int pppol2tp_session_setsockopt(struct sock *sk, po->chan.hdrlen = val ? PPPOL2TP_L2TP_HDR_SIZE_SEQ : PPPOL2TP_L2TP_HDR_SIZE_NOSEQ; } - l2tp_info(session, PPPOL2TP_MSG_CONTROL, - "%s: set send_seq=%d\n", - session->name, session->send_seq); + PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: set send_seq=%d\n", session->name, session->send_seq); break; case PPPOL2TP_SO_LNSMODE: @@ -1365,22 +1368,20 @@ static int pppol2tp_session_setsockopt(struct sock *sk, break; } session->lns_mode = val ? -1 : 0; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, - "%s: set lns_mode=%d\n", - session->name, session->lns_mode); + PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: set lns_mode=%d\n", session->name, session->lns_mode); break; case PPPOL2TP_SO_DEBUG: session->debug = val; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: set debug=%x\n", - session->name, session->debug); + PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: set debug=%x\n", session->name, session->debug); break; case PPPOL2TP_SO_REORDERTO: session->reorder_timeout = msecs_to_jiffies(val); - l2tp_info(session, PPPOL2TP_MSG_CONTROL, - "%s: set reorder_timeout=%d\n", - session->name, session->reorder_timeout); + PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: set reorder_timeout=%d\n", session->name, session->reorder_timeout); break; default: @@ -1459,8 +1460,8 @@ static int pppol2tp_tunnel_getsockopt(struct sock *sk, switch (optname) { case PPPOL2TP_SO_DEBUG: *val = tunnel->debug; - l2tp_info(tunnel, PPPOL2TP_MSG_CONTROL, "%s: get debug=%x\n", - tunnel->name, tunnel->debug); + PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: get debug=%x\n", tunnel->name, tunnel->debug); break; default: @@ -1482,32 +1483,32 @@ static int pppol2tp_session_getsockopt(struct sock *sk, switch (optname) { case PPPOL2TP_SO_RECVSEQ: *val = session->recv_seq; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, - "%s: get recv_seq=%d\n", session->name, *val); + PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: get recv_seq=%d\n", session->name, *val); break; case PPPOL2TP_SO_SENDSEQ: *val = session->send_seq; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, - "%s: get send_seq=%d\n", session->name, *val); + PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: get send_seq=%d\n", session->name, *val); break; case PPPOL2TP_SO_LNSMODE: *val = session->lns_mode; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, - "%s: get lns_mode=%d\n", session->name, *val); + PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: get lns_mode=%d\n", session->name, *val); break; case PPPOL2TP_SO_DEBUG: *val = session->debug; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: get debug=%d\n", - session->name, *val); + PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: get debug=%d\n", session->name, *val); break; case PPPOL2TP_SO_REORDERTO: *val = (int) jiffies_to_msecs(session->reorder_timeout); - l2tp_info(session, PPPOL2TP_MSG_CONTROL, - "%s: get reorder_timeout=%d\n", session->name, *val); + PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, + "%s: get reorder_timeout=%d\n", session->name, *val); break; default: @@ -1870,7 +1871,8 @@ static int __init pppol2tp_init(void) goto out_unregister_pppox; #endif - pr_info("PPPoL2TP kernel driver, %s\n", PPPOL2TP_DRV_VERSION); + printk(KERN_INFO "PPPoL2TP kernel driver, %s\n", + PPPOL2TP_DRV_VERSION); out: return err; diff --git a/trunk/net/lapb/lapb_iface.c b/trunk/net/lapb/lapb_iface.c index 3cdaa046c1bc..ab3d35f23257 100644 --- a/trunk/net/lapb/lapb_iface.c +++ b/trunk/net/lapb/lapb_iface.c @@ -15,8 +15,6 @@ * 2000-10-29 Henner Eisen lapb_data_indication() return status. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -281,7 +279,9 @@ int lapb_connect_request(struct net_device *dev) lapb_establish_data_link(lapb); - lapb_dbg(0, "(%p) S0 -> S1\n", lapb->dev); +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S0 -> S1\n", lapb->dev); +#endif lapb->state = LAPB_STATE_1; rc = LAPB_OK; @@ -305,8 +305,12 @@ int lapb_disconnect_request(struct net_device *dev) goto out_put; case LAPB_STATE_1: - lapb_dbg(1, "(%p) S1 TX DISC(1)\n", lapb->dev); - lapb_dbg(0, "(%p) S1 -> S0\n", lapb->dev); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S1 TX DISC(1)\n", lapb->dev); +#endif +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S1 -> S0\n", lapb->dev); +#endif lapb_send_control(lapb, LAPB_DISC, LAPB_POLLON, LAPB_COMMAND); lapb->state = LAPB_STATE_0; lapb_start_t1timer(lapb); @@ -325,8 +329,12 @@ int lapb_disconnect_request(struct net_device *dev) lapb_stop_t2timer(lapb); lapb->state = LAPB_STATE_2; - lapb_dbg(1, "(%p) S3 DISC(1)\n", lapb->dev); - lapb_dbg(0, "(%p) S3 -> S2\n", lapb->dev); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S3 DISC(1)\n", lapb->dev); +#endif +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S3 -> S2\n", lapb->dev); +#endif rc = LAPB_OK; out_put: diff --git a/trunk/net/lapb/lapb_in.c b/trunk/net/lapb/lapb_in.c index 5dba899131b3..f4e3c1accab7 100644 --- a/trunk/net/lapb/lapb_in.c +++ b/trunk/net/lapb/lapb_in.c @@ -15,8 +15,6 @@ * 2000-10-29 Henner Eisen lapb_data_indication() return status. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -46,16 +44,25 @@ static void lapb_state0_machine(struct lapb_cb *lapb, struct sk_buff *skb, { switch (frame->type) { case LAPB_SABM: - lapb_dbg(1, "(%p) S0 RX SABM(%d)\n", lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S0 RX SABM(%d)\n", + lapb->dev, frame->pf); +#endif if (lapb->mode & LAPB_EXTENDED) { - lapb_dbg(1, "(%p) S0 TX DM(%d)\n", - lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S0 TX DM(%d)\n", + lapb->dev, frame->pf); +#endif lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); } else { - lapb_dbg(1, "(%p) S0 TX UA(%d)\n", - lapb->dev, frame->pf); - lapb_dbg(0, "(%p) S0 -> S3\n", lapb->dev); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)\n", + lapb->dev, frame->pf); +#endif +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S0 -> S3\n", lapb->dev); +#endif lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); lapb_stop_t1timer(lapb); @@ -71,11 +78,18 @@ static void lapb_state0_machine(struct lapb_cb *lapb, struct sk_buff *skb, break; case LAPB_SABME: - lapb_dbg(1, "(%p) S0 RX SABME(%d)\n", lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S0 RX SABME(%d)\n", + lapb->dev, frame->pf); +#endif if (lapb->mode & LAPB_EXTENDED) { - lapb_dbg(1, "(%p) S0 TX UA(%d)\n", - lapb->dev, frame->pf); - lapb_dbg(0, "(%p) S0 -> S3\n", lapb->dev); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)\n", + lapb->dev, frame->pf); +#endif +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S0 -> S3\n", lapb->dev); +#endif lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); lapb_stop_t1timer(lapb); @@ -88,16 +102,22 @@ static void lapb_state0_machine(struct lapb_cb *lapb, struct sk_buff *skb, lapb->va = 0; lapb_connect_indication(lapb, LAPB_OK); } else { - lapb_dbg(1, "(%p) S0 TX DM(%d)\n", - lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S0 TX DM(%d)\n", + lapb->dev, frame->pf); +#endif lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); } break; case LAPB_DISC: - lapb_dbg(1, "(%p) S0 RX DISC(%d)\n", lapb->dev, frame->pf); - lapb_dbg(1, "(%p) S0 TX UA(%d)\n", lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S0 RX DISC(%d)\n", + lapb->dev, frame->pf); + printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)\n", + lapb->dev, frame->pf); +#endif lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); break; @@ -117,45 +137,68 @@ static void lapb_state1_machine(struct lapb_cb *lapb, struct sk_buff *skb, { switch (frame->type) { case LAPB_SABM: - lapb_dbg(1, "(%p) S1 RX SABM(%d)\n", lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S1 RX SABM(%d)\n", + lapb->dev, frame->pf); +#endif if (lapb->mode & LAPB_EXTENDED) { - lapb_dbg(1, "(%p) S1 TX DM(%d)\n", - lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)\n", + lapb->dev, frame->pf); +#endif lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); } else { - lapb_dbg(1, "(%p) S1 TX UA(%d)\n", - lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S1 TX UA(%d)\n", + lapb->dev, frame->pf); +#endif lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); } break; case LAPB_SABME: - lapb_dbg(1, "(%p) S1 RX SABME(%d)\n", lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S1 RX SABME(%d)\n", + lapb->dev, frame->pf); +#endif if (lapb->mode & LAPB_EXTENDED) { - lapb_dbg(1, "(%p) S1 TX UA(%d)\n", - lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S1 TX UA(%d)\n", + lapb->dev, frame->pf); +#endif lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); } else { - lapb_dbg(1, "(%p) S1 TX DM(%d)\n", - lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)\n", + lapb->dev, frame->pf); +#endif lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); } break; case LAPB_DISC: - lapb_dbg(1, "(%p) S1 RX DISC(%d)\n", lapb->dev, frame->pf); - lapb_dbg(1, "(%p) S1 TX DM(%d)\n", lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S1 RX DISC(%d)\n", + lapb->dev, frame->pf); + printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)\n", + lapb->dev, frame->pf); +#endif lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); break; case LAPB_UA: - lapb_dbg(1, "(%p) S1 RX UA(%d)\n", lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S1 RX UA(%d)\n", + lapb->dev, frame->pf); +#endif if (frame->pf) { - lapb_dbg(0, "(%p) S1 -> S3\n", lapb->dev); +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S1 -> S3\n", lapb->dev); +#endif lapb_stop_t1timer(lapb); lapb_stop_t2timer(lapb); lapb->state = LAPB_STATE_3; @@ -169,9 +212,14 @@ static void lapb_state1_machine(struct lapb_cb *lapb, struct sk_buff *skb, break; case LAPB_DM: - lapb_dbg(1, "(%p) S1 RX DM(%d)\n", lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S1 RX DM(%d)\n", + lapb->dev, frame->pf); +#endif if (frame->pf) { - lapb_dbg(0, "(%p) S1 -> S0\n", lapb->dev); +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S1 -> S0\n", lapb->dev); +#endif lapb_clear_queues(lapb); lapb->state = LAPB_STATE_0; lapb_start_t1timer(lapb); @@ -194,22 +242,34 @@ static void lapb_state2_machine(struct lapb_cb *lapb, struct sk_buff *skb, switch (frame->type) { case LAPB_SABM: case LAPB_SABME: - lapb_dbg(1, "(%p) S2 RX {SABM,SABME}(%d)\n", - lapb->dev, frame->pf); - lapb_dbg(1, "(%p) S2 TX DM(%d)\n", lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S2 RX {SABM,SABME}(%d)\n", + lapb->dev, frame->pf); + printk(KERN_DEBUG "lapb: (%p) S2 TX DM(%d)\n", + lapb->dev, frame->pf); +#endif lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); break; case LAPB_DISC: - lapb_dbg(1, "(%p) S2 RX DISC(%d)\n", lapb->dev, frame->pf); - lapb_dbg(1, "(%p) S2 TX UA(%d)\n", lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S2 RX DISC(%d)\n", + lapb->dev, frame->pf); + printk(KERN_DEBUG "lapb: (%p) S2 TX UA(%d)\n", + lapb->dev, frame->pf); +#endif lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); break; case LAPB_UA: - lapb_dbg(1, "(%p) S2 RX UA(%d)\n", lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S2 RX UA(%d)\n", + lapb->dev, frame->pf); +#endif if (frame->pf) { - lapb_dbg(0, "(%p) S2 -> S0\n", lapb->dev); +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S2 -> S0\n", lapb->dev); +#endif lapb->state = LAPB_STATE_0; lapb_start_t1timer(lapb); lapb_stop_t2timer(lapb); @@ -218,9 +278,14 @@ static void lapb_state2_machine(struct lapb_cb *lapb, struct sk_buff *skb, break; case LAPB_DM: - lapb_dbg(1, "(%p) S2 RX DM(%d)\n", lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S2 RX DM(%d)\n", + lapb->dev, frame->pf); +#endif if (frame->pf) { - lapb_dbg(0, "(%p) S2 -> S0\n", lapb->dev); +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S2 -> S0\n", lapb->dev); +#endif lapb->state = LAPB_STATE_0; lapb_start_t1timer(lapb); lapb_stop_t2timer(lapb); @@ -232,9 +297,12 @@ static void lapb_state2_machine(struct lapb_cb *lapb, struct sk_buff *skb, case LAPB_REJ: case LAPB_RNR: case LAPB_RR: - lapb_dbg(1, "(%p) S2 RX {I,REJ,RNR,RR}(%d)\n", +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S2 RX {I,REJ,RNR,RR}(%d)\n", + lapb->dev, frame->pf); + printk(KERN_DEBUG "lapb: (%p) S2 RX DM(%d)\n", lapb->dev, frame->pf); - lapb_dbg(1, "(%p) S2 RX DM(%d)\n", lapb->dev, frame->pf); +#endif if (frame->pf) lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); @@ -257,15 +325,22 @@ static void lapb_state3_machine(struct lapb_cb *lapb, struct sk_buff *skb, switch (frame->type) { case LAPB_SABM: - lapb_dbg(1, "(%p) S3 RX SABM(%d)\n", lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S3 RX SABM(%d)\n", + lapb->dev, frame->pf); +#endif if (lapb->mode & LAPB_EXTENDED) { - lapb_dbg(1, "(%p) S3 TX DM(%d)\n", - lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S3 TX DM(%d)\n", + lapb->dev, frame->pf); +#endif lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); } else { - lapb_dbg(1, "(%p) S3 TX UA(%d)\n", - lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S3 TX UA(%d)\n", + lapb->dev, frame->pf); +#endif lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); lapb_stop_t1timer(lapb); @@ -280,10 +355,15 @@ static void lapb_state3_machine(struct lapb_cb *lapb, struct sk_buff *skb, break; case LAPB_SABME: - lapb_dbg(1, "(%p) S3 RX SABME(%d)\n", lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S3 RX SABME(%d)\n", + lapb->dev, frame->pf); +#endif if (lapb->mode & LAPB_EXTENDED) { - lapb_dbg(1, "(%p) S3 TX UA(%d)\n", - lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S3 TX UA(%d)\n", + lapb->dev, frame->pf); +#endif lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); lapb_stop_t1timer(lapb); @@ -295,16 +375,23 @@ static void lapb_state3_machine(struct lapb_cb *lapb, struct sk_buff *skb, lapb->va = 0; lapb_requeue_frames(lapb); } else { - lapb_dbg(1, "(%p) S3 TX DM(%d)\n", - lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S3 TX DM(%d)\n", + lapb->dev, frame->pf); +#endif lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); } break; case LAPB_DISC: - lapb_dbg(1, "(%p) S3 RX DISC(%d)\n", lapb->dev, frame->pf); - lapb_dbg(0, "(%p) S3 -> S0\n", lapb->dev); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S3 RX DISC(%d)\n", + lapb->dev, frame->pf); +#endif +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S3 -> S0\n", lapb->dev); +#endif lapb_clear_queues(lapb); lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); lapb_start_t1timer(lapb); @@ -314,8 +401,13 @@ static void lapb_state3_machine(struct lapb_cb *lapb, struct sk_buff *skb, break; case LAPB_DM: - lapb_dbg(1, "(%p) S3 RX DM(%d)\n", lapb->dev, frame->pf); - lapb_dbg(0, "(%p) S3 -> S0\n", lapb->dev); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S3 RX DM(%d)\n", + lapb->dev, frame->pf); +#endif +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S3 -> S0\n", lapb->dev); +#endif lapb_clear_queues(lapb); lapb->state = LAPB_STATE_0; lapb_start_t1timer(lapb); @@ -324,8 +416,10 @@ static void lapb_state3_machine(struct lapb_cb *lapb, struct sk_buff *skb, break; case LAPB_RNR: - lapb_dbg(1, "(%p) S3 RX RNR(%d) R%d\n", - lapb->dev, frame->pf, frame->nr); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S3 RX RNR(%d) R%d\n", + lapb->dev, frame->pf, frame->nr); +#endif lapb->condition |= LAPB_PEER_RX_BUSY_CONDITION; lapb_check_need_response(lapb, frame->cr, frame->pf); if (lapb_validate_nr(lapb, frame->nr)) { @@ -334,7 +428,9 @@ static void lapb_state3_machine(struct lapb_cb *lapb, struct sk_buff *skb, lapb->frmr_data = *frame; lapb->frmr_type = LAPB_FRMR_Z; lapb_transmit_frmr(lapb); - lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev); +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->dev); +#endif lapb_start_t1timer(lapb); lapb_stop_t2timer(lapb); lapb->state = LAPB_STATE_4; @@ -343,8 +439,10 @@ static void lapb_state3_machine(struct lapb_cb *lapb, struct sk_buff *skb, break; case LAPB_RR: - lapb_dbg(1, "(%p) S3 RX RR(%d) R%d\n", - lapb->dev, frame->pf, frame->nr); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S3 RX RR(%d) R%d\n", + lapb->dev, frame->pf, frame->nr); +#endif lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION; lapb_check_need_response(lapb, frame->cr, frame->pf); if (lapb_validate_nr(lapb, frame->nr)) { @@ -353,7 +451,9 @@ static void lapb_state3_machine(struct lapb_cb *lapb, struct sk_buff *skb, lapb->frmr_data = *frame; lapb->frmr_type = LAPB_FRMR_Z; lapb_transmit_frmr(lapb); - lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev); +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->dev); +#endif lapb_start_t1timer(lapb); lapb_stop_t2timer(lapb); lapb->state = LAPB_STATE_4; @@ -362,8 +462,10 @@ static void lapb_state3_machine(struct lapb_cb *lapb, struct sk_buff *skb, break; case LAPB_REJ: - lapb_dbg(1, "(%p) S3 RX REJ(%d) R%d\n", - lapb->dev, frame->pf, frame->nr); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S3 RX REJ(%d) R%d\n", + lapb->dev, frame->pf, frame->nr); +#endif lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION; lapb_check_need_response(lapb, frame->cr, frame->pf); if (lapb_validate_nr(lapb, frame->nr)) { @@ -375,7 +477,9 @@ static void lapb_state3_machine(struct lapb_cb *lapb, struct sk_buff *skb, lapb->frmr_data = *frame; lapb->frmr_type = LAPB_FRMR_Z; lapb_transmit_frmr(lapb); - lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev); +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->dev); +#endif lapb_start_t1timer(lapb); lapb_stop_t2timer(lapb); lapb->state = LAPB_STATE_4; @@ -384,13 +488,17 @@ static void lapb_state3_machine(struct lapb_cb *lapb, struct sk_buff *skb, break; case LAPB_I: - lapb_dbg(1, "(%p) S3 RX I(%d) S%d R%d\n", - lapb->dev, frame->pf, frame->ns, frame->nr); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S3 RX I(%d) S%d R%d\n", + lapb->dev, frame->pf, frame->ns, frame->nr); +#endif if (!lapb_validate_nr(lapb, frame->nr)) { lapb->frmr_data = *frame; lapb->frmr_type = LAPB_FRMR_Z; lapb_transmit_frmr(lapb); - lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev); +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->dev); +#endif lapb_start_t1timer(lapb); lapb_stop_t2timer(lapb); lapb->state = LAPB_STATE_4; @@ -414,7 +522,7 @@ static void lapb_state3_machine(struct lapb_cb *lapb, struct sk_buff *skb, * a frame lost on the wire. */ if (cn == NET_RX_DROP) { - pr_debug("rx congestion\n"); + printk(KERN_DEBUG "LAPB: rx congestion\n"); break; } lapb->vr = (lapb->vr + 1) % modulus; @@ -433,8 +541,11 @@ static void lapb_state3_machine(struct lapb_cb *lapb, struct sk_buff *skb, if (frame->pf) lapb_enquiry_response(lapb); } else { - lapb_dbg(1, "(%p) S3 TX REJ(%d) R%d\n", - lapb->dev, frame->pf, lapb->vr); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG + "lapb: (%p) S3 TX REJ(%d) R%d\n", + lapb->dev, frame->pf, lapb->vr); +#endif lapb->condition |= LAPB_REJECT_CONDITION; lapb_send_control(lapb, LAPB_REJ, frame->pf, LAPB_RESPONSE); @@ -444,22 +555,31 @@ static void lapb_state3_machine(struct lapb_cb *lapb, struct sk_buff *skb, break; case LAPB_FRMR: - lapb_dbg(1, "(%p) S3 RX FRMR(%d) %02X %02X %02X %02X %02X\n", - lapb->dev, frame->pf, - skb->data[0], skb->data[1], skb->data[2], - skb->data[3], skb->data[4]); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S3 RX FRMR(%d) %02X " + "%02X %02X %02X %02X\n", lapb->dev, frame->pf, + skb->data[0], skb->data[1], skb->data[2], + skb->data[3], skb->data[4]); +#endif lapb_establish_data_link(lapb); - lapb_dbg(0, "(%p) S3 -> S1\n", lapb->dev); +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S3 -> S1\n", lapb->dev); +#endif lapb_requeue_frames(lapb); lapb->state = LAPB_STATE_1; break; case LAPB_ILLEGAL: - lapb_dbg(1, "(%p) S3 RX ILLEGAL(%d)\n", lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S3 RX ILLEGAL(%d)\n", + lapb->dev, frame->pf); +#endif lapb->frmr_data = *frame; lapb->frmr_type = LAPB_FRMR_W; lapb_transmit_frmr(lapb); - lapb_dbg(0, "(%p) S3 -> S4\n", lapb->dev); +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->dev); +#endif lapb_start_t1timer(lapb); lapb_stop_t2timer(lapb); lapb->state = LAPB_STATE_4; @@ -480,16 +600,25 @@ static void lapb_state4_machine(struct lapb_cb *lapb, struct sk_buff *skb, { switch (frame->type) { case LAPB_SABM: - lapb_dbg(1, "(%p) S4 RX SABM(%d)\n", lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S4 RX SABM(%d)\n", + lapb->dev, frame->pf); +#endif if (lapb->mode & LAPB_EXTENDED) { - lapb_dbg(1, "(%p) S4 TX DM(%d)\n", - lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S4 TX DM(%d)\n", + lapb->dev, frame->pf); +#endif lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); } else { - lapb_dbg(1, "(%p) S4 TX UA(%d)\n", - lapb->dev, frame->pf); - lapb_dbg(0, "(%p) S4 -> S3\n", lapb->dev); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S4 TX UA(%d)\n", + lapb->dev, frame->pf); +#endif +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S4 -> S3\n", lapb->dev); +#endif lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); lapb_stop_t1timer(lapb); @@ -505,11 +634,18 @@ static void lapb_state4_machine(struct lapb_cb *lapb, struct sk_buff *skb, break; case LAPB_SABME: - lapb_dbg(1, "(%p) S4 RX SABME(%d)\n", lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S4 RX SABME(%d)\n", + lapb->dev, frame->pf); +#endif if (lapb->mode & LAPB_EXTENDED) { - lapb_dbg(1, "(%p) S4 TX UA(%d)\n", - lapb->dev, frame->pf); - lapb_dbg(0, "(%p) S4 -> S3\n", lapb->dev); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S4 TX UA(%d)\n", + lapb->dev, frame->pf); +#endif +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S4 -> S3\n", lapb->dev); +#endif lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE); lapb_stop_t1timer(lapb); @@ -522,8 +658,10 @@ static void lapb_state4_machine(struct lapb_cb *lapb, struct sk_buff *skb, lapb->va = 0; lapb_connect_indication(lapb, LAPB_OK); } else { - lapb_dbg(1, "(%p) S4 TX DM(%d)\n", - lapb->dev, frame->pf); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S4 TX DM(%d)\n", + lapb->dev, frame->pf); +#endif lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE); } diff --git a/trunk/net/lapb/lapb_out.c b/trunk/net/lapb/lapb_out.c index ba4d015bd1a6..baab2760f651 100644 --- a/trunk/net/lapb/lapb_out.c +++ b/trunk/net/lapb/lapb_out.c @@ -14,8 +14,6 @@ * LAPB 002 Jonathan Naylor New timer architecture. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -62,8 +60,10 @@ static void lapb_send_iframe(struct lapb_cb *lapb, struct sk_buff *skb, int poll *frame |= lapb->vs << 1; } - lapb_dbg(1, "(%p) S%d TX I(%d) S%d R%d\n", - lapb->dev, lapb->state, poll_bit, lapb->vs, lapb->vr); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S%d TX I(%d) S%d R%d\n", + lapb->dev, lapb->state, poll_bit, lapb->vs, lapb->vr); +#endif lapb_transmit_buffer(lapb, skb, LAPB_COMMAND); } @@ -148,9 +148,11 @@ void lapb_transmit_buffer(struct lapb_cb *lapb, struct sk_buff *skb, int type) } } - lapb_dbg(2, "(%p) S%d TX %02X %02X %02X\n", - lapb->dev, lapb->state, - skb->data[0], skb->data[1], skb->data[2]); +#if LAPB_DEBUG > 2 + printk(KERN_DEBUG "lapb: (%p) S%d TX %02X %02X %02X\n", + lapb->dev, lapb->state, + skb->data[0], skb->data[1], skb->data[2]); +#endif if (!lapb_data_transmit(lapb, skb)) kfree_skb(skb); @@ -162,10 +164,16 @@ void lapb_establish_data_link(struct lapb_cb *lapb) lapb->n2count = 0; if (lapb->mode & LAPB_EXTENDED) { - lapb_dbg(1, "(%p) S%d TX SABME(1)\n", lapb->dev, lapb->state); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S%d TX SABME(1)\n", + lapb->dev, lapb->state); +#endif lapb_send_control(lapb, LAPB_SABME, LAPB_POLLON, LAPB_COMMAND); } else { - lapb_dbg(1, "(%p) S%d TX SABM(1)\n", lapb->dev, lapb->state); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S%d TX SABM(1)\n", + lapb->dev, lapb->state); +#endif lapb_send_control(lapb, LAPB_SABM, LAPB_POLLON, LAPB_COMMAND); } @@ -175,8 +183,10 @@ void lapb_establish_data_link(struct lapb_cb *lapb) void lapb_enquiry_response(struct lapb_cb *lapb) { - lapb_dbg(1, "(%p) S%d TX RR(1) R%d\n", - lapb->dev, lapb->state, lapb->vr); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S%d TX RR(1) R%d\n", + lapb->dev, lapb->state, lapb->vr); +#endif lapb_send_control(lapb, LAPB_RR, LAPB_POLLON, LAPB_RESPONSE); @@ -185,8 +195,10 @@ void lapb_enquiry_response(struct lapb_cb *lapb) void lapb_timeout_response(struct lapb_cb *lapb) { - lapb_dbg(1, "(%p) S%d TX RR(0) R%d\n", - lapb->dev, lapb->state, lapb->vr); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S%d TX RR(0) R%d\n", + lapb->dev, lapb->state, lapb->vr); +#endif lapb_send_control(lapb, LAPB_RR, LAPB_POLLOFF, LAPB_RESPONSE); lapb->condition &= ~LAPB_ACK_PENDING_CONDITION; diff --git a/trunk/net/lapb/lapb_subr.c b/trunk/net/lapb/lapb_subr.c index 9d0a426eccbb..066225b4e824 100644 --- a/trunk/net/lapb/lapb_subr.c +++ b/trunk/net/lapb/lapb_subr.c @@ -13,8 +13,6 @@ * LAPB 001 Jonathan Naylor Started Coding */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -113,9 +111,11 @@ int lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb, { frame->type = LAPB_ILLEGAL; - lapb_dbg(2, "(%p) S%d RX %02X %02X %02X\n", - lapb->dev, lapb->state, - skb->data[0], skb->data[1], skb->data[2]); +#if LAPB_DEBUG > 2 + printk(KERN_DEBUG "lapb: (%p) S%d RX %02X %02X %02X\n", + lapb->dev, lapb->state, + skb->data[0], skb->data[1], skb->data[2]); +#endif /* We always need to look at 2 bytes, sometimes we need * to look at 3 and those cases are handled below. @@ -284,10 +284,12 @@ void lapb_transmit_frmr(struct lapb_cb *lapb) dptr++; *dptr++ = lapb->frmr_type; - lapb_dbg(1, "(%p) S%d TX FRMR %02X %02X %02X %02X %02X\n", - lapb->dev, lapb->state, - skb->data[1], skb->data[2], skb->data[3], - skb->data[4], skb->data[5]); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S%d TX FRMR %02X %02X %02X %02X %02X\n", + lapb->dev, lapb->state, + skb->data[1], skb->data[2], skb->data[3], + skb->data[4], skb->data[5]); +#endif } else { dptr = skb_put(skb, 4); *dptr++ = LAPB_FRMR; @@ -299,9 +301,11 @@ void lapb_transmit_frmr(struct lapb_cb *lapb) dptr++; *dptr++ = lapb->frmr_type; - lapb_dbg(1, "(%p) S%d TX FRMR %02X %02X %02X\n", - lapb->dev, lapb->state, skb->data[1], - skb->data[2], skb->data[3]); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S%d TX FRMR %02X %02X %02X\n", + lapb->dev, lapb->state, skb->data[1], + skb->data[2], skb->data[3]); +#endif } lapb_transmit_buffer(lapb, skb, LAPB_RESPONSE); diff --git a/trunk/net/lapb/lapb_timer.c b/trunk/net/lapb/lapb_timer.c index 54563ad8aeb1..f8cd641dfc82 100644 --- a/trunk/net/lapb/lapb_timer.c +++ b/trunk/net/lapb/lapb_timer.c @@ -14,8 +14,6 @@ * LAPB 002 Jonathan Naylor New timer architecture. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -107,17 +105,21 @@ static void lapb_t1timer_expiry(unsigned long param) lapb_clear_queues(lapb); lapb->state = LAPB_STATE_0; lapb_disconnect_indication(lapb, LAPB_TIMEDOUT); - lapb_dbg(0, "(%p) S1 -> S0\n", lapb->dev); +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S1 -> S0\n", lapb->dev); +#endif return; } else { lapb->n2count++; if (lapb->mode & LAPB_EXTENDED) { - lapb_dbg(1, "(%p) S1 TX SABME(1)\n", - lapb->dev); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S1 TX SABME(1)\n", lapb->dev); +#endif lapb_send_control(lapb, LAPB_SABME, LAPB_POLLON, LAPB_COMMAND); } else { - lapb_dbg(1, "(%p) S1 TX SABM(1)\n", - lapb->dev); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S1 TX SABM(1)\n", lapb->dev); +#endif lapb_send_control(lapb, LAPB_SABM, LAPB_POLLON, LAPB_COMMAND); } } @@ -131,11 +133,15 @@ static void lapb_t1timer_expiry(unsigned long param) lapb_clear_queues(lapb); lapb->state = LAPB_STATE_0; lapb_disconnect_confirmation(lapb, LAPB_TIMEDOUT); - lapb_dbg(0, "(%p) S2 -> S0\n", lapb->dev); +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S2 -> S0\n", lapb->dev); +#endif return; } else { lapb->n2count++; - lapb_dbg(1, "(%p) S2 TX DISC(1)\n", lapb->dev); +#if LAPB_DEBUG > 1 + printk(KERN_DEBUG "lapb: (%p) S2 TX DISC(1)\n", lapb->dev); +#endif lapb_send_control(lapb, LAPB_DISC, LAPB_POLLON, LAPB_COMMAND); } break; @@ -149,7 +155,9 @@ static void lapb_t1timer_expiry(unsigned long param) lapb->state = LAPB_STATE_0; lapb_stop_t2timer(lapb); lapb_disconnect_indication(lapb, LAPB_TIMEDOUT); - lapb_dbg(0, "(%p) S3 -> S0\n", lapb->dev); +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S3 -> S0\n", lapb->dev); +#endif return; } else { lapb->n2count++; @@ -165,7 +173,9 @@ static void lapb_t1timer_expiry(unsigned long param) lapb_clear_queues(lapb); lapb->state = LAPB_STATE_0; lapb_disconnect_indication(lapb, LAPB_TIMEDOUT); - lapb_dbg(0, "(%p) S4 -> S0\n", lapb->dev); +#if LAPB_DEBUG > 0 + printk(KERN_DEBUG "lapb: (%p) S4 -> S0\n", lapb->dev); +#endif return; } else { lapb->n2count++; diff --git a/trunk/net/llc/af_llc.c b/trunk/net/llc/af_llc.c index fe5453c3e719..17bc85d5b7ba 100644 --- a/trunk/net/llc/af_llc.c +++ b/trunk/net/llc/af_llc.c @@ -71,7 +71,8 @@ static inline u16 llc_ui_next_link_no(int sap) */ static inline __be16 llc_proto_type(u16 arphrd) { - return htons(ETH_P_802_2); + return arphrd == ARPHRD_IEEE802_TR ? + htons(ETH_P_TR_802_2) : htons(ETH_P_802_2); } /** @@ -805,9 +806,10 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, sk_wait_data(sk, &timeo); if ((flags & MSG_PEEK) && peek_seq != llc->copied_seq) { - net_dbg_ratelimited("LLC(%s:%d): Application bug, race in MSG_PEEK\n", - current->comm, - task_pid_nr(current)); + if (net_ratelimit()) + printk(KERN_DEBUG "LLC(%s:%d): Application " + "bug, race in MSG_PEEK.\n", + current->comm, task_pid_nr(current)); peek_seq = llc->copied_seq; } continue; @@ -838,7 +840,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, if (!(flags & MSG_PEEK)) { spin_lock_irqsave(&sk->sk_receive_queue.lock, cpu_flags); - sk_eat_skb(sk, skb, false); + sk_eat_skb(sk, skb, 0); spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags); *seq = 0; } @@ -861,7 +863,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, if (!(flags & MSG_PEEK)) { spin_lock_irqsave(&sk->sk_receive_queue.lock, cpu_flags); - sk_eat_skb(sk, skb, false); + sk_eat_skb(sk, skb, 0); spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags); *seq = 0; } diff --git a/trunk/net/llc/llc_output.c b/trunk/net/llc/llc_output.c index 2dae8a5df23f..b658cba89fdd 100644 --- a/trunk/net/llc/llc_output.c +++ b/trunk/net/llc/llc_output.c @@ -14,7 +14,9 @@ */ #include +#include #include +#include #include #include #include @@ -35,6 +37,7 @@ int llc_mac_hdr_init(struct sk_buff *skb, int rc = -EINVAL; switch (skb->dev->type) { + case ARPHRD_IEEE802_TR: case ARPHRD_ETHER: case ARPHRD_LOOPBACK: rc = dev_hard_header(skb, skb->dev, ETH_P_802_2, da, sa, diff --git a/trunk/net/llc/llc_sap.c b/trunk/net/llc/llc_sap.c index 7c5073badc73..94e7fca75b85 100644 --- a/trunk/net/llc/llc_sap.c +++ b/trunk/net/llc/llc_sap.c @@ -31,6 +31,10 @@ static int llc_mac_header_len(unsigned short devtype) case ARPHRD_ETHER: case ARPHRD_LOOPBACK: return sizeof(struct ethhdr); +#if defined(CONFIG_TR) || defined(CONFIG_TR_MODULE) + case ARPHRD_IEEE802_TR: + return sizeof(struct trh_hdr); +#endif } return 0; } diff --git a/trunk/net/mac80211/agg-rx.c b/trunk/net/mac80211/agg-rx.c index 26ddb699d693..a070d4f460ea 100644 --- a/trunk/net/mac80211/agg-rx.c +++ b/trunk/net/mac80211/agg-rx.c @@ -260,8 +260,11 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, (buf_size > IEEE80211_MAX_AMPDU_BUF)) { status = WLAN_STATUS_INVALID_QOS_PARAM; #ifdef CONFIG_MAC80211_HT_DEBUG - net_dbg_ratelimited("AddBA Req with bad params from %pM on tid %u. policy %d, buffer size %d\n", - mgmt->sa, tid, ba_policy, buf_size); + if (net_ratelimit()) + printk(KERN_DEBUG "AddBA Req with bad params from " + "%pM on tid %u. policy %d, buffer size %d\n", + mgmt->sa, tid, ba_policy, + buf_size); #endif /* CONFIG_MAC80211_HT_DEBUG */ goto end_no_lock; } @@ -278,8 +281,10 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, if (sta->ampdu_mlme.tid_rx[tid]) { #ifdef CONFIG_MAC80211_HT_DEBUG - net_dbg_ratelimited("unexpected AddBA Req from %pM on tid %u\n", - mgmt->sa, tid); + if (net_ratelimit()) + printk(KERN_DEBUG "unexpected AddBA Req from " + "%pM on tid %u\n", + mgmt->sa, tid); #endif /* CONFIG_MAC80211_HT_DEBUG */ /* delete existing Rx BA session on the same tid */ diff --git a/trunk/net/mac80211/cfg.c b/trunk/net/mac80211/cfg.c index 495831ee48f1..0221270c0ddf 100644 --- a/trunk/net/mac80211/cfg.c +++ b/trunk/net/mac80211/cfg.c @@ -1093,7 +1093,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, } else sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (ether_addr_equal(mac, sdata->vif.addr)) + if (compare_ether_addr(mac, sdata->vif.addr) == 0) return -EINVAL; if (is_multicast_ether_addr(mac)) diff --git a/trunk/net/mac80211/ht.c b/trunk/net/mac80211/ht.c index 6f8615c54b22..9b603366943c 100644 --- a/trunk/net/mac80211/ht.c +++ b/trunk/net/mac80211/ht.c @@ -306,10 +306,10 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, initiator = (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) >> 11; #ifdef CONFIG_MAC80211_HT_DEBUG - net_dbg_ratelimited("delba from %pM (%s) tid %d reason code %d\n", - mgmt->sa, initiator ? "initiator" : "recipient", - tid, - le16_to_cpu(mgmt->u.action.u.delba.reason_code)); + if (net_ratelimit()) + printk(KERN_DEBUG "delba from %pM (%s) tid %d reason code %d\n", + mgmt->sa, initiator ? "initiator" : "recipient", tid, + le16_to_cpu(mgmt->u.action.u.delba.reason_code)); #endif /* CONFIG_MAC80211_HT_DEBUG */ if (initiator == WLAN_BACK_INITIATOR) diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c index 3ad33a824624..bb1a3e62a66a 100644 --- a/trunk/net/mac80211/ibss.c +++ b/trunk/net/mac80211/ibss.c @@ -66,7 +66,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, skb_reset_tail_pointer(skb); skb_reserve(skb, sdata->local->hw.extra_tx_headroom); - if (!ether_addr_equal(ifibss->bssid, bssid)) + if (compare_ether_addr(ifibss->bssid, bssid)) sta_info_flush(sdata->local, sdata); /* if merging, indicate to driver that we leave the old IBSS */ @@ -303,8 +303,9 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, * allow new one to be added. */ if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { - net_dbg_ratelimited("%s: No room for a new IBSS STA entry %pM\n", - sdata->name, addr); + if (net_ratelimit()) + printk(KERN_DEBUG "%s: No room for a new IBSS STA entry %pM\n", + sdata->name, addr); rcu_read_lock(); return NULL; } @@ -314,7 +315,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, return NULL; } - if (!ether_addr_equal(bssid, sdata->u.ibss.bssid)) { + if (compare_ether_addr(bssid, sdata->u.ibss.bssid)) { rcu_read_lock(); return NULL; } @@ -400,7 +401,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, return; if (sdata->vif.type == NL80211_IFTYPE_ADHOC && - ether_addr_equal(mgmt->bssid, sdata->u.ibss.bssid)) { + compare_ether_addr(mgmt->bssid, sdata->u.ibss.bssid) == 0) { rcu_read_lock(); sta = sta_info_get(sdata, mgmt->sa); @@ -505,7 +506,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, goto put_bss; /* same BSSID */ - if (ether_addr_equal(cbss->bssid, sdata->u.ibss.bssid)) + if (compare_ether_addr(cbss->bssid, sdata->u.ibss.bssid) == 0) goto put_bss; if (rx_status->flag & RX_FLAG_MACTIME_MPDU) { @@ -581,15 +582,16 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata, * allow new one to be added. */ if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { - net_dbg_ratelimited("%s: No room for a new IBSS STA entry %pM\n", - sdata->name, addr); + if (net_ratelimit()) + printk(KERN_DEBUG "%s: No room for a new IBSS STA entry %pM\n", + sdata->name, addr); return; } if (ifibss->state == IEEE80211_IBSS_MLME_SEARCH) return; - if (!ether_addr_equal(bssid, sdata->u.ibss.bssid)) + if (compare_ether_addr(bssid, sdata->u.ibss.bssid)) return; sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); @@ -827,7 +829,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da)) return; - if (!ether_addr_equal(mgmt->bssid, ifibss->bssid) && + if (compare_ether_addr(mgmt->bssid, ifibss->bssid) != 0 && !is_broadcast_ether_addr(mgmt->bssid)) return; diff --git a/trunk/net/mac80211/ieee80211_i.h b/trunk/net/mac80211/ieee80211_i.h index 3f3cd50fff16..ae046b52d5e2 100644 --- a/trunk/net/mac80211/ieee80211_i.h +++ b/trunk/net/mac80211/ieee80211_i.h @@ -1195,7 +1195,7 @@ static inline struct ieee80211_local *hw_to_local( static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) { - return ether_addr_equal(raddr, addr) || + return compare_ether_addr(raddr, addr) == 0 || is_broadcast_ether_addr(raddr); } diff --git a/trunk/net/mac80211/iface.c b/trunk/net/mac80211/iface.c index 856237c5c1f8..3e05a8bfddf0 100644 --- a/trunk/net/mac80211/iface.c +++ b/trunk/net/mac80211/iface.c @@ -127,7 +127,7 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, * The remaining checks are only performed for interfaces * with the same MAC address. */ - if (!ether_addr_equal(dev->dev_addr, ndev->dev_addr)) + if (compare_ether_addr(dev->dev_addr, ndev->dev_addr)) continue; /* diff --git a/trunk/net/mac80211/mesh.c b/trunk/net/mac80211/mesh.c index 0675a2fec6a6..0a21e4e55f43 100644 --- a/trunk/net/mac80211/mesh.c +++ b/trunk/net/mac80211/mesh.c @@ -215,7 +215,7 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr, kmem_cache_free(rm_cache, p); --entries; } else if ((seqnum == p->seqnum) && - (ether_addr_equal(sa, p->sa))) + (compare_ether_addr(sa, p->sa) == 0)) return -1; } @@ -649,7 +649,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, /* ignore ProbeResp to foreign address */ if (stype == IEEE80211_STYPE_PROBE_RESP && - !ether_addr_equal(mgmt->da, sdata->vif.addr)) + compare_ether_addr(mgmt->da, sdata->vif.addr)) return; baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; diff --git a/trunk/net/mac80211/mesh_hwmp.c b/trunk/net/mac80211/mesh_hwmp.c index 27e0c2f06795..503016f58631 100644 --- a/trunk/net/mac80211/mesh_hwmp.c +++ b/trunk/net/mac80211/mesh_hwmp.c @@ -422,7 +422,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata, new_metric = MAX_METRIC; exp_time = TU_TO_EXP_TIME(orig_lifetime); - if (ether_addr_equal(orig_addr, sdata->vif.addr)) { + if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0) { /* This MP is the originator, we are not interested in this * frame, except for updating transmitter's path info. */ @@ -472,7 +472,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata, /* Update and check transmitter routing info */ ta = mgmt->sa; - if (ether_addr_equal(orig_addr, ta)) + if (compare_ether_addr(orig_addr, ta) == 0) fresh_info = false; else { fresh_info = true; @@ -533,7 +533,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, mhwmp_dbg("received PREQ from %pM", orig_addr); - if (ether_addr_equal(target_addr, sdata->vif.addr)) { + if (compare_ether_addr(target_addr, sdata->vif.addr) == 0) { mhwmp_dbg("PREQ is for us"); forward = false; reply = true; @@ -631,7 +631,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata, mhwmp_dbg("received PREP from %pM", PREP_IE_ORIG_ADDR(prep_elem)); orig_addr = PREP_IE_ORIG_ADDR(prep_elem); - if (ether_addr_equal(orig_addr, sdata->vif.addr)) + if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0) /* destination, no forwarding required */ return; @@ -709,7 +709,7 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata, spin_lock_bh(&mpath->state_lock); sta = next_hop_deref_protected(mpath); if (mpath->flags & MESH_PATH_ACTIVE && - ether_addr_equal(ta, sta->sta.addr) && + compare_ether_addr(ta, sta->sta.addr) == 0 && (!(mpath->flags & MESH_PATH_SN_VALID) || SN_GT(target_sn, mpath->sn))) { mpath->flags &= ~MESH_PATH_ACTIVE; @@ -756,7 +756,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, metric = le32_to_cpu(rann->rann_metric); /* Ignore our own RANNs */ - if (ether_addr_equal(orig_addr, sdata->vif.addr)) + if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0) return; mhwmp_dbg("received RANN from %pM via neighbour %pM (is_gate=%d)", @@ -1099,7 +1099,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb, if (time_after(jiffies, mpath->exp_time - msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) && - ether_addr_equal(sdata->vif.addr, hdr->addr4) && + !compare_ether_addr(sdata->vif.addr, hdr->addr4) && !(mpath->flags & MESH_PATH_RESOLVING) && !(mpath->flags & MESH_PATH_FIXED)) mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); diff --git a/trunk/net/mac80211/mesh_pathtbl.c b/trunk/net/mac80211/mesh_pathtbl.c index b39224d8255c..baa6096c66b4 100644 --- a/trunk/net/mac80211/mesh_pathtbl.c +++ b/trunk/net/mac80211/mesh_pathtbl.c @@ -348,7 +348,7 @@ static struct mesh_path *mpath_lookup(struct mesh_table *tbl, u8 *dst, hlist_for_each_entry_rcu(node, n, bucket, list) { mpath = node->mpath; if (mpath->sdata == sdata && - ether_addr_equal(dst, mpath->dst)) { + compare_ether_addr(dst, mpath->dst) == 0) { if (MPATH_EXPIRED(mpath)) { spin_lock_bh(&mpath->state_lock); mpath->flags &= ~MESH_PATH_ACTIVE; @@ -517,7 +517,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) int err = 0; u32 hash_idx; - if (ether_addr_equal(dst, sdata->vif.addr)) + if (compare_ether_addr(dst, sdata->vif.addr) == 0) /* never add ourselves as neighbours */ return -ENOTSUPP; @@ -561,7 +561,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) hlist_for_each_entry(node, n, bucket, list) { mpath = node->mpath; if (mpath->sdata == sdata && - ether_addr_equal(dst, mpath->dst)) + compare_ether_addr(dst, mpath->dst) == 0) goto err_exists; } @@ -652,7 +652,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) int err = 0; u32 hash_idx; - if (ether_addr_equal(dst, sdata->vif.addr)) + if (compare_ether_addr(dst, sdata->vif.addr) == 0) /* never add ourselves as neighbours */ return -ENOTSUPP; @@ -690,7 +690,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) hlist_for_each_entry(node, n, bucket, list) { mpath = node->mpath; if (mpath->sdata == sdata && - ether_addr_equal(dst, mpath->dst)) + compare_ether_addr(dst, mpath->dst) == 0) goto err_exists; } @@ -884,7 +884,7 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata) hlist_for_each_entry(node, n, bucket, list) { mpath = node->mpath; if (mpath->sdata == sdata && - ether_addr_equal(addr, mpath->dst)) { + compare_ether_addr(addr, mpath->dst) == 0) { __mesh_path_del(tbl, node); goto enddel; } diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index b3b3c264ff66..dbd4bd92c018 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -1567,9 +1567,9 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, } #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - if (beacon) - net_dbg_ratelimited("%s: detected beacon loss from AP - sending probe request\n", - sdata->name); + if (beacon && net_ratelimit()) + printk(KERN_DEBUG "%s: detected beacon loss from AP " + "- sending probe request\n", sdata->name); #endif /* @@ -1776,7 +1776,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN); - if (!ether_addr_equal(bssid, mgmt->bssid)) + if (compare_ether_addr(bssid, mgmt->bssid)) return RX_MGMT_NONE; auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); @@ -1853,7 +1853,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, return RX_MGMT_NONE; if (!ifmgd->associated || - !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) + compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid)) return RX_MGMT_NONE; bssid = ifmgd->associated->bssid; @@ -1886,7 +1886,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, return RX_MGMT_NONE; if (!ifmgd->associated || - !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) + compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid)) return RX_MGMT_NONE; reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); @@ -2113,7 +2113,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, if (!assoc_data) return RX_MGMT_NONE; - if (!ether_addr_equal(assoc_data->bss->bssid, mgmt->bssid)) + if (compare_ether_addr(assoc_data->bss->bssid, mgmt->bssid)) return RX_MGMT_NONE; /* @@ -2193,7 +2193,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, bool need_ps = false; if (sdata->u.mgd.associated && - ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) { + compare_ether_addr(mgmt->bssid, sdata->u.mgd.associated->bssid) + == 0) { bss = (void *)sdata->u.mgd.associated->priv; /* not previously set so we may need to recalc */ need_ps = !bss->dtim_period; @@ -2248,7 +2249,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, ASSERT_MGD_MTX(ifmgd); - if (!ether_addr_equal(mgmt->da, sdata->vif.addr)) + if (compare_ether_addr(mgmt->da, sdata->vif.addr)) return; /* ignore ProbeResp to foreign address */ baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; @@ -2261,11 +2262,12 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false); if (ifmgd->associated && - ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) + compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid) == 0) ieee80211_reset_ap_probe(sdata); if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies && - ether_addr_equal(mgmt->bssid, ifmgd->auth_data->bss->bssid)) { + compare_ether_addr(mgmt->bssid, ifmgd->auth_data->bss->bssid) + == 0) { /* got probe response, continue with auth */ printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name); ifmgd->auth_data->tries = 0; @@ -2322,7 +2324,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, return; if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon && - ether_addr_equal(mgmt->bssid, ifmgd->assoc_data->bss->bssid)) { + compare_ether_addr(mgmt->bssid, ifmgd->assoc_data->bss->bssid) + == 0) { ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); @@ -2337,7 +2340,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, } if (!ifmgd->associated || - !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) + compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid)) return; bssid = ifmgd->associated->bssid; @@ -2404,8 +2407,10 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - net_dbg_ratelimited("%s: cancelling probereq poll due to a received beacon\n", - sdata->name); + if (net_ratelimit()) { + printk(KERN_DEBUG "%s: cancelling probereq poll due " + "to a received beacon\n", sdata->name); + } #endif ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL; mutex_lock(&local->iflist_mtx); @@ -3161,7 +3166,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, return err; } } else - WARN_ON_ONCE(!ether_addr_equal(ifmgd->bssid, cbss->bssid)); + WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, cbss->bssid)); return 0; } @@ -3301,7 +3306,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, bool match; /* keep sta info, bssid if matching */ - match = ether_addr_equal(ifmgd->bssid, req->bss->bssid); + match = compare_ether_addr(ifmgd->bssid, req->bss->bssid) == 0; ieee80211_destroy_auth_data(sdata, match); } @@ -3461,7 +3466,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, sdata->name, req->bssid, req->reason_code); if (ifmgd->associated && - ether_addr_equal(ifmgd->associated->bssid, req->bssid)) + compare_ether_addr(ifmgd->associated->bssid, req->bssid) == 0) ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, req->reason_code, true, frame_buf); else diff --git a/trunk/net/mac80211/rx.c b/trunk/net/mac80211/rx.c index 8257a09eeed4..d5ac02fe37ff 100644 --- a/trunk/net/mac80211/rx.c +++ b/trunk/net/mac80211/rx.c @@ -492,12 +492,12 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) if (ieee80211_has_tods(hdr->frame_control) || !ieee80211_has_fromds(hdr->frame_control)) return RX_DROP_MONITOR; - if (ether_addr_equal(hdr->addr3, dev_addr)) + if (compare_ether_addr(hdr->addr3, dev_addr) == 0) return RX_DROP_MONITOR; } else { if (!ieee80211_has_a4(hdr->frame_control)) return RX_DROP_MONITOR; - if (ether_addr_equal(hdr->addr4, dev_addr)) + if (compare_ether_addr(hdr->addr4, dev_addr) == 0) return RX_DROP_MONITOR; } } @@ -1275,7 +1275,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) if (rx->sdata->vif.type == NL80211_IFTYPE_ADHOC) { u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len, NL80211_IFTYPE_ADHOC); - if (ether_addr_equal(bssid, rx->sdata->u.ibss.bssid)) { + if (compare_ether_addr(bssid, rx->sdata->u.ibss.bssid) == 0) { sta->last_rx = jiffies; if (ieee80211_is_data(hdr->frame_control)) { sta->last_rx_rate_idx = status->rate_idx; @@ -1438,8 +1438,8 @@ ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, */ if (((hdr->frame_control ^ f_hdr->frame_control) & cpu_to_le16(IEEE80211_FCTL_FTYPE)) || - !ether_addr_equal(hdr->addr1, f_hdr->addr1) || - !ether_addr_equal(hdr->addr2, f_hdr->addr2)) + compare_ether_addr(hdr->addr1, f_hdr->addr1) != 0 || + compare_ether_addr(hdr->addr2, f_hdr->addr2) != 0) continue; if (time_after(jiffies, entry->first_frag_time + 2 * HZ)) { @@ -1714,8 +1714,8 @@ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc) * of whether the frame was encrypted or not. */ if (ehdr->h_proto == rx->sdata->control_port_protocol && - (ether_addr_equal(ehdr->h_dest, rx->sdata->vif.addr) || - ether_addr_equal(ehdr->h_dest, pae_group_addr))) + (compare_ether_addr(ehdr->h_dest, rx->sdata->vif.addr) == 0 || + compare_ether_addr(ehdr->h_dest, pae_group_addr) == 0)) return true; if (ieee80211_802_1x_port_control(rx) || @@ -1752,9 +1752,9 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) * local net stack and back to the wireless medium */ xmit_skb = skb_copy(skb, GFP_ATOMIC); - if (!xmit_skb) - net_dbg_ratelimited("%s: failed to clone multicast frame\n", - dev->name); + if (!xmit_skb && net_ratelimit()) + printk(KERN_DEBUG "%s: failed to clone " + "multicast frame\n", dev->name); } else { dsta = sta_info_get(sdata, skb->data); if (dsta) { @@ -1925,7 +1925,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) mpp_path_add(proxied_addr, mpp_addr, sdata); } else { spin_lock_bh(&mppath->state_lock); - if (!ether_addr_equal(mppath->mpp, mpp_addr)) + if (compare_ether_addr(mppath->mpp, mpp_addr) != 0) memcpy(mppath->mpp, mpp_addr, ETH_ALEN); spin_unlock_bh(&mppath->state_lock); } @@ -1934,7 +1934,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) /* Frame has reached destination. Don't forward */ if (!is_multicast_ether_addr(hdr->addr1) && - ether_addr_equal(sdata->vif.addr, hdr->addr3)) + compare_ether_addr(sdata->vif.addr, hdr->addr3) == 0) return RX_CONTINUE; q = ieee80211_select_queue_80211(local, skb, hdr); @@ -1957,8 +1957,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) fwd_skb = skb_copy(skb, GFP_ATOMIC); if (!fwd_skb) { - net_dbg_ratelimited("%s: failed to clone mesh frame\n", - sdata->name); + if (net_ratelimit()) + printk(KERN_DEBUG "%s: failed to clone mesh frame\n", + sdata->name); goto out; } @@ -2121,13 +2122,13 @@ static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb; struct ieee80211_mgmt *resp; - if (!ether_addr_equal(mgmt->da, sdata->vif.addr)) { + if (compare_ether_addr(mgmt->da, sdata->vif.addr) != 0) { /* Not to own unicast address */ return; } - if (!ether_addr_equal(mgmt->sa, sdata->u.mgd.bssid) || - !ether_addr_equal(mgmt->bssid, sdata->u.mgd.bssid)) { + if (compare_ether_addr(mgmt->sa, sdata->u.mgd.bssid) != 0 || + compare_ether_addr(mgmt->bssid, sdata->u.mgd.bssid) != 0) { /* Not from the current AP or not associated yet. */ return; } @@ -2337,7 +2338,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) if (sdata->vif.type != NL80211_IFTYPE_STATION) break; - if (!ether_addr_equal(mgmt->bssid, sdata->u.mgd.bssid)) + if (compare_ether_addr(mgmt->bssid, sdata->u.mgd.bssid)) break; goto queue; @@ -2771,7 +2772,7 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, if (!bssid && !sdata->u.mgd.use_4addr) return 0; if (!multicast && - !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { + compare_ether_addr(sdata->vif.addr, hdr->addr1) != 0) { if (!(sdata->dev->flags & IFF_PROMISC) || sdata->u.mgd.use_4addr) return 0; @@ -2789,7 +2790,8 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, return 0; status->rx_flags &= ~IEEE80211_RX_RA_MATCH; } else if (!multicast && - !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { + compare_ether_addr(sdata->vif.addr, + hdr->addr1) != 0) { if (!(sdata->dev->flags & IFF_PROMISC)) return 0; status->rx_flags &= ~IEEE80211_RX_RA_MATCH; @@ -2805,7 +2807,8 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, break; case NL80211_IFTYPE_MESH_POINT: if (!multicast && - !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { + compare_ether_addr(sdata->vif.addr, + hdr->addr1) != 0) { if (!(sdata->dev->flags & IFF_PROMISC)) return 0; @@ -2815,7 +2818,8 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_AP: if (!bssid) { - if (!ether_addr_equal(sdata->vif.addr, hdr->addr1)) + if (compare_ether_addr(sdata->vif.addr, + hdr->addr1)) return 0; } else if (!ieee80211_bssid_match(bssid, sdata->vif.addr)) { @@ -2837,7 +2841,7 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, case NL80211_IFTYPE_WDS: if (bssid || !ieee80211_is_data(hdr->frame_control)) return 0; - if (!ether_addr_equal(sdata->u.wds.remote_addr, hdr->addr2)) + if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) return 0; break; default: diff --git a/trunk/net/mac80211/scan.c b/trunk/net/mac80211/scan.c index 169da0742c81..8282284f835c 100644 --- a/trunk/net/mac80211/scan.c +++ b/trunk/net/mac80211/scan.c @@ -194,7 +194,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) presp = ieee80211_is_probe_resp(fc); if (presp) { /* ignore ProbeResp to foreign address */ - if (!ether_addr_equal(mgmt->da, sdata->vif.addr)) + if (compare_ether_addr(mgmt->da, sdata->vif.addr)) return RX_DROP_MONITOR; presp = true; diff --git a/trunk/net/mac80211/sta_info.c b/trunk/net/mac80211/sta_info.c index f5b1638fbf80..97a9d6639fb9 100644 --- a/trunk/net/mac80211/sta_info.c +++ b/trunk/net/mac80211/sta_info.c @@ -102,7 +102,7 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata, lockdep_is_held(&local->sta_mtx)); while (sta) { if (sta->sdata == sdata && - ether_addr_equal(sta->sta.addr, addr)) + compare_ether_addr(sta->sta.addr, addr) == 0) break; sta = rcu_dereference_check(sta->hnext, lockdep_is_held(&local->sta_mtx)); @@ -125,7 +125,7 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata, while (sta) { if ((sta->sdata == sdata || (sta->sdata->bss && sta->sdata->bss == sdata->bss)) && - ether_addr_equal(sta->sta.addr, addr)) + compare_ether_addr(sta->sta.addr, addr) == 0) break; sta = rcu_dereference_check(sta->hnext, lockdep_is_held(&local->sta_mtx)); @@ -302,7 +302,7 @@ static int sta_info_insert_check(struct sta_info *sta) if (unlikely(!ieee80211_sdata_running(sdata))) return -ENETDOWN; - if (WARN_ON(ether_addr_equal(sta->sta.addr, sdata->vif.addr) || + if (WARN_ON(compare_ether_addr(sta->sta.addr, sdata->vif.addr) == 0 || is_multicast_ether_addr(sta->sta.addr))) return -EINVAL; @@ -912,7 +912,7 @@ struct ieee80211_sta *ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw, */ for_each_sta_info(hw_to_local(hw), addr, sta, nxt) { if (localaddr && - !ether_addr_equal(sta->sdata->vif.addr, localaddr)) + compare_ether_addr(sta->sdata->vif.addr, localaddr) != 0) continue; if (!sta->uploaded) return NULL; diff --git a/trunk/net/mac80211/sta_info.h b/trunk/net/mac80211/sta_info.h index 3bb24a121c95..663dc90c4e31 100644 --- a/trunk/net/mac80211/sta_info.h +++ b/trunk/net/mac80211/sta_info.h @@ -502,7 +502,7 @@ void for_each_sta_info_type_check(struct ieee80211_local *local, nxt = _sta ? rcu_dereference(_sta->hnext) : NULL \ ) \ /* compare address and run code only if it matches */ \ - if (ether_addr_equal(_sta->sta.addr, (_addr))) + if (compare_ether_addr(_sta->sta.addr, (_addr)) == 0) /* * Get STA info by index, BROKEN! diff --git a/trunk/net/mac80211/status.c b/trunk/net/mac80211/status.c index 28cfa981cfb1..05f257aa2e08 100644 --- a/trunk/net/mac80211/status.c +++ b/trunk/net/mac80211/status.c @@ -384,7 +384,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) for_each_sta_info(local, hdr->addr1, sta, tmp) { /* skip wrong virtual interface */ - if (!ether_addr_equal(hdr->addr2, sta->sdata->vif.addr)) + if (compare_ether_addr(hdr->addr2, sta->sdata->vif.addr)) continue; if (info->flags & IEEE80211_TX_STATUS_EOSP) diff --git a/trunk/net/mac80211/tx.c b/trunk/net/mac80211/tx.c index 5f827a6b0d8d..d67d36f57d78 100644 --- a/trunk/net/mac80211/tx.c +++ b/trunk/net/mac80211/tx.c @@ -413,8 +413,9 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >= AP_MAX_BC_BUFFER) { #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - net_dbg_ratelimited("%s: BC TX buffer full - dropping the oldest frame\n", - tx->sdata->name); + if (net_ratelimit()) + printk(KERN_DEBUG "%s: BC TX buffer full - dropping the oldest frame\n", + tx->sdata->name); #endif dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf)); } else @@ -475,8 +476,10 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) { struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]); #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - net_dbg_ratelimited("%s: STA %pM TX buffer for AC %d full - dropping oldest frame\n", - tx->sdata->name, sta->sta.addr, ac); + if (net_ratelimit()) + printk(KERN_DEBUG "%s: STA %pM TX buffer for " + "AC %d full - dropping oldest frame\n", + tx->sdata->name, sta->sta.addr, ac); #endif dev_kfree_skb(old); } else @@ -1662,7 +1665,7 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, skb->len >= len_rthdr + hdrlen + sizeof(rfc1042_header) + 2) { u8 *payload = (u8 *)hdr + hdrlen; - if (ether_addr_equal(payload, rfc1042_header)) + if (compare_ether_addr(payload, rfc1042_header) == 0) skb->protocol = cpu_to_be16((payload[6] << 8) | payload[7]); } @@ -1695,7 +1698,7 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, tmp_sdata->vif.type == NL80211_IFTYPE_AP_VLAN || tmp_sdata->vif.type == NL80211_IFTYPE_WDS) continue; - if (ether_addr_equal(tmp_sdata->vif.addr, hdr->addr2)) { + if (compare_ether_addr(tmp_sdata->vif.addr, hdr->addr2) == 0) { sdata = tmp_sdata; break; } @@ -1812,8 +1815,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, * is being proxied by a portal (i.e. portal address * differs from proxied address) */ - if (ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN) && - !(mppath && !ether_addr_equal(mppath->mpp, skb->data))) { + if (compare_ether_addr(sdata->vif.addr, + skb->data + ETH_ALEN) == 0 && + !(mppath && compare_ether_addr(mppath->mpp, skb->data))) { hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, skb->data, skb->data + ETH_ALEN); rcu_read_unlock(); @@ -1960,10 +1964,12 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, if (unlikely(!ieee80211_vif_is_mesh(&sdata->vif) && !is_multicast_ether_addr(hdr.addr1) && !authorized && (cpu_to_be16(ethertype) != sdata->control_port_protocol || - !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) { + compare_ether_addr(sdata->vif.addr, skb->data + ETH_ALEN)))) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - net_dbg_ratelimited("%s: dropped frame to %pM (unauthorized port)\n", - dev->name, hdr.addr1); + if (net_ratelimit()) + printk(KERN_DEBUG "%s: dropped frame to %pM" + " (unauthorized port)\n", dev->name, + hdr.addr1); #endif I802_DEBUG_INC(local->tx_handlers_drop_unauth_port); diff --git a/trunk/net/mac802154/Kconfig b/trunk/net/mac802154/Kconfig deleted file mode 100644 index a967ddaa4e2f..000000000000 --- a/trunk/net/mac802154/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -config MAC802154 - tristate "Generic IEEE 802.15.4 Soft Networking Stack (mac802154)" - depends on IEEE802154 && EXPERIMENTAL - select CRC_CCITT - ---help--- - This option enables the hardware independent IEEE 802.15.4 - networking stack for SoftMAC devices (the ones implementing - only PHY level of IEEE 802.15.4 standard). - - Note: this implementation is neither certified, nor feature - complete! Compatibility with other implementations hasn't - been tested yet! - - If you plan to use HardMAC IEEE 802.15.4 devices, you can - say N here. Alternatievly you can say M to compile it as - module. diff --git a/trunk/net/mac802154/Makefile b/trunk/net/mac802154/Makefile deleted file mode 100644 index ec1bd3fc1273..000000000000 --- a/trunk/net/mac802154/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -obj-$(CONFIG_MAC802154) += mac802154.o -mac802154-objs := ieee802154_dev.o rx.o tx.o mac_cmd.o mib.o monitor.o diff --git a/trunk/net/mac802154/ieee802154_dev.c b/trunk/net/mac802154/ieee802154_dev.c deleted file mode 100644 index e3edfb0661b0..000000000000 --- a/trunk/net/mac802154/ieee802154_dev.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright (C) 2007-2012 Siemens AG - * - * Written by: - * Alexander Smirnov - * - * Based on the code from 'linux-zigbee.sourceforge.net' project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "mac802154.h" - -int mac802154_slave_open(struct net_device *dev) -{ - struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct mac802154_priv *ipriv = priv->hw; - int res = 0; - - if (ipriv->open_count++ == 0) { - res = ipriv->ops->start(&ipriv->hw); - WARN_ON(res); - if (res) - goto err; - } - - if (ipriv->ops->ieee_addr) { - res = ipriv->ops->ieee_addr(&ipriv->hw, dev->dev_addr); - WARN_ON(res); - if (res) - goto err; - mac802154_dev_set_ieee_addr(dev); - } - - netif_start_queue(dev); - return 0; -err: - priv->hw->open_count--; - - return res; -} - -int mac802154_slave_close(struct net_device *dev) -{ - struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct mac802154_priv *ipriv = priv->hw; - - netif_stop_queue(dev); - - if (!--ipriv->open_count) - ipriv->ops->stop(&ipriv->hw); - - return 0; -} - -static int -mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) -{ - struct mac802154_sub_if_data *priv; - struct mac802154_priv *ipriv; - int err; - - ipriv = wpan_phy_priv(phy); - - priv = netdev_priv(dev); - priv->dev = dev; - priv->hw = ipriv; - - dev->needed_headroom = ipriv->hw.extra_tx_headroom; - - SET_NETDEV_DEV(dev, &ipriv->phy->dev); - - mutex_lock(&ipriv->slaves_mtx); - if (!ipriv->running) { - mutex_unlock(&ipriv->slaves_mtx); - return -ENODEV; - } - mutex_unlock(&ipriv->slaves_mtx); - - err = register_netdev(dev); - if (err < 0) - return err; - - rtnl_lock(); - mutex_lock(&ipriv->slaves_mtx); - list_add_tail_rcu(&priv->list, &ipriv->slaves); - mutex_unlock(&ipriv->slaves_mtx); - rtnl_unlock(); - - return 0; -} - -static void -mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev) -{ - struct mac802154_sub_if_data *sdata; - ASSERT_RTNL(); - - sdata = netdev_priv(dev); - - BUG_ON(sdata->hw->phy != phy); - - mutex_lock(&sdata->hw->slaves_mtx); - list_del_rcu(&sdata->list); - mutex_unlock(&sdata->hw->slaves_mtx); - - synchronize_rcu(); - unregister_netdevice(sdata->dev); -} - -static struct net_device * -mac802154_add_iface(struct wpan_phy *phy, const char *name, int type) -{ - struct net_device *dev; - int err = -ENOMEM; - - switch (type) { - case IEEE802154_DEV_MONITOR: - dev = alloc_netdev(sizeof(struct mac802154_sub_if_data), - name, mac802154_monitor_setup); - break; - default: - dev = NULL; - err = -EINVAL; - break; - } - if (!dev) - goto err; - - err = mac802154_netdev_register(phy, dev); - if (err) - goto err_free; - - dev_hold(dev); /* we return an incremented device refcount */ - return dev; - -err_free: - free_netdev(dev); -err: - return ERR_PTR(err); -} - -struct ieee802154_dev * -ieee802154_alloc_device(size_t priv_data_len, struct ieee802154_ops *ops) -{ - struct wpan_phy *phy; - struct mac802154_priv *priv; - size_t priv_size; - - if (!ops || !ops->xmit || !ops->ed || !ops->start || - !ops->stop || !ops->set_channel) { - printk(KERN_ERR - "undefined IEEE802.15.4 device operations\n"); - return NULL; - } - - /* Ensure 32-byte alignment of our private data and hw private data. - * We use the wpan_phy priv data for both our mac802154_priv and for - * the driver's private data - * - * in memory it'll be like this: - * - * +-----------------------+ - * | struct wpan_phy | - * +-----------------------+ - * | struct mac802154_priv | - * +-----------------------+ - * | driver's private data | - * +-----------------------+ - * - * Due to ieee802154 layer isn't aware of driver and MAC structures, - * so lets allign them here. - */ - - priv_size = ALIGN(sizeof(*priv), NETDEV_ALIGN) + priv_data_len; - - phy = wpan_phy_alloc(priv_size); - if (!phy) { - printk(KERN_ERR - "failure to allocate master IEEE802.15.4 device\n"); - return NULL; - } - - priv = wpan_phy_priv(phy); - priv->hw.phy = priv->phy = phy; - priv->hw.priv = (char *)priv + ALIGN(sizeof(*priv), NETDEV_ALIGN); - priv->ops = ops; - - INIT_LIST_HEAD(&priv->slaves); - mutex_init(&priv->slaves_mtx); - - return &priv->hw; -} -EXPORT_SYMBOL(ieee802154_alloc_device); - -void ieee802154_free_device(struct ieee802154_dev *hw) -{ - struct mac802154_priv *priv = mac802154_to_priv(hw); - - BUG_ON(!list_empty(&priv->slaves)); - - wpan_phy_free(priv->phy); - - mutex_destroy(&priv->slaves_mtx); -} -EXPORT_SYMBOL(ieee802154_free_device); - -int ieee802154_register_device(struct ieee802154_dev *dev) -{ - struct mac802154_priv *priv = mac802154_to_priv(dev); - int rc = -ENOMEM; - - priv->dev_workqueue = - create_singlethread_workqueue(wpan_phy_name(priv->phy)); - if (!priv->dev_workqueue) - goto out; - - wpan_phy_set_dev(priv->phy, priv->hw.parent); - - priv->phy->add_iface = mac802154_add_iface; - priv->phy->del_iface = mac802154_del_iface; - - rc = wpan_phy_register(priv->phy); - if (rc < 0) - goto out_wq; - - rtnl_lock(); - - mutex_lock(&priv->slaves_mtx); - priv->running = MAC802154_DEVICE_RUN; - mutex_unlock(&priv->slaves_mtx); - - rtnl_unlock(); - - return 0; - -out_wq: - destroy_workqueue(priv->dev_workqueue); -out: - return rc; -} -EXPORT_SYMBOL(ieee802154_register_device); - -void ieee802154_unregister_device(struct ieee802154_dev *dev) -{ - struct mac802154_priv *priv = mac802154_to_priv(dev); - struct mac802154_sub_if_data *sdata, *next; - - flush_workqueue(priv->dev_workqueue); - destroy_workqueue(priv->dev_workqueue); - - rtnl_lock(); - - mutex_lock(&priv->slaves_mtx); - priv->running = MAC802154_DEVICE_STOPPED; - mutex_unlock(&priv->slaves_mtx); - - list_for_each_entry_safe(sdata, next, &priv->slaves, list) { - mutex_lock(&sdata->hw->slaves_mtx); - list_del(&sdata->list); - mutex_unlock(&sdata->hw->slaves_mtx); - - unregister_netdevice(sdata->dev); - } - - rtnl_unlock(); - - wpan_phy_unregister(priv->phy); -} -EXPORT_SYMBOL(ieee802154_unregister_device); - -MODULE_DESCRIPTION("IEEE 802.15.4 implementation"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/net/mac802154/mac802154.h b/trunk/net/mac802154/mac802154.h deleted file mode 100644 index 789d9c948aec..000000000000 --- a/trunk/net/mac802154/mac802154.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2007-2012 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Pavel Smolenskiy - * Maxim Gorbachyov - * Dmitry Eremin-Solenikov - * Alexander Smirnov - */ -#ifndef MAC802154_H -#define MAC802154_H - -/* mac802154 device private data */ -struct mac802154_priv { - struct ieee802154_dev hw; - struct ieee802154_ops *ops; - - /* ieee802154 phy */ - struct wpan_phy *phy; - - int open_count; - - /* As in mac80211 slaves list is modified: - * 1) under the RTNL - * 2) protected by slaves_mtx; - * 3) in an RCU manner - * - * So atomic readers can use any of this protection methods. - */ - struct list_head slaves; - struct mutex slaves_mtx; - - /* This one is used for scanning and other jobs not to be interfered - * with serial driver. - */ - struct workqueue_struct *dev_workqueue; - - /* SoftMAC device is registered and running. One can add subinterfaces. - * This flag should be modified under slaves_mtx and RTNL, so you can - * read them using any of protection methods. - */ - bool running; -}; - -#define MAC802154_DEVICE_STOPPED 0x00 -#define MAC802154_DEVICE_RUN 0x01 - -/* Slave interface definition. - * - * Slaves represent typical network interfaces available from userspace. - * Each ieee802154 device/transceiver may have several slaves and able - * to be associated with several networks at the same time. - */ -struct mac802154_sub_if_data { - struct list_head list; /* the ieee802154_priv->slaves list */ - - struct mac802154_priv *hw; - struct net_device *dev; - - int type; - - spinlock_t mib_lock; - - __le16 pan_id; - __le16 short_addr; - - u8 chan; - u8 page; - - /* MAC BSN field */ - u8 bsn; - /* MAC DSN field */ - u8 dsn; -}; - -#define mac802154_to_priv(_hw) container_of(_hw, struct mac802154_priv, hw) - -#define MAC802154_MAX_XMIT_ATTEMPTS 3 - -#define MAC802154_CHAN_NONE (~(u8)0) /* No channel is assigned */ - -extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced; - -int mac802154_slave_open(struct net_device *dev); -int mac802154_slave_close(struct net_device *dev); - -void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb); -void mac802154_monitor_setup(struct net_device *dev); - -netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, - u8 page, u8 chan); - -/* MIB callbacks */ -void mac802154_dev_set_ieee_addr(struct net_device *dev); - -#endif /* MAC802154_H */ diff --git a/trunk/net/mac802154/mac_cmd.c b/trunk/net/mac802154/mac_cmd.c deleted file mode 100644 index 7a5d0e052cd7..000000000000 --- a/trunk/net/mac802154/mac_cmd.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * MAC commands interface - * - * Copyright 2007-2012 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Sergey Lapin - * Dmitry Eremin-Solenikov - * Alexander Smirnov - */ - -#include -#include - -#include -#include -#include - -#include "mac802154.h" - -struct wpan_phy *mac802154_get_phy(const struct net_device *dev) -{ - struct mac802154_sub_if_data *priv = netdev_priv(dev); - - BUG_ON(dev->type != ARPHRD_IEEE802154); - - return to_phy(get_device(&priv->hw->phy->dev)); -} - -struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced = { - .get_phy = mac802154_get_phy, -}; diff --git a/trunk/net/mac802154/mib.c b/trunk/net/mac802154/mib.c deleted file mode 100644 index ab59821ec729..000000000000 --- a/trunk/net/mac802154/mib.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2007-2012 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Dmitry Eremin-Solenikov - * Sergey Lapin - * Maxim Gorbachyov - * Alexander Smirnov - */ - -#include - -#include -#include - -#include "mac802154.h" - -struct hw_addr_filt_notify_work { - struct work_struct work; - struct net_device *dev; - unsigned long changed; -}; - -struct mac802154_priv *mac802154_slave_get_priv(struct net_device *dev) -{ - struct mac802154_sub_if_data *priv = netdev_priv(dev); - - BUG_ON(dev->type != ARPHRD_IEEE802154); - - return priv->hw; -} - -static void hw_addr_notify(struct work_struct *work) -{ - struct hw_addr_filt_notify_work *nw = container_of(work, - struct hw_addr_filt_notify_work, work); - struct mac802154_priv *hw = mac802154_slave_get_priv(nw->dev); - int res; - - res = hw->ops->set_hw_addr_filt(&hw->hw, - &hw->hw.hw_filt, - nw->changed); - if (res) - pr_debug("failed changed mask %lx\n", nw->changed); - - kfree(nw); - - return; -} - -static void set_hw_addr_filt(struct net_device *dev, unsigned long changed) -{ - struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct hw_addr_filt_notify_work *work; - - work = kzalloc(sizeof(*work), GFP_ATOMIC); - if (!work) - return; - - INIT_WORK(&work->work, hw_addr_notify); - work->dev = dev; - work->changed = changed; - queue_work(priv->hw->dev_workqueue, &work->work); - - return; -} - -void mac802154_dev_set_ieee_addr(struct net_device *dev) -{ - struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct mac802154_priv *mac = priv->hw; - - if (mac->ops->set_hw_addr_filt && - memcmp(mac->hw.hw_filt.ieee_addr, - dev->dev_addr, IEEE802154_ADDR_LEN)) { - memcpy(mac->hw.hw_filt.ieee_addr, - dev->dev_addr, IEEE802154_ADDR_LEN); - set_hw_addr_filt(dev, IEEE802515_AFILT_IEEEADDR_CHANGED); - } -} diff --git a/trunk/net/mac802154/monitor.c b/trunk/net/mac802154/monitor.c deleted file mode 100644 index 434a26f76a80..000000000000 --- a/trunk/net/mac802154/monitor.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2007, 2008, 2009 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Dmitry Eremin-Solenikov - * Sergey Lapin - * Maxim Gorbachyov - * Alexander Smirnov - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "mac802154.h" - -static netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, - struct net_device *dev) -{ - struct mac802154_sub_if_data *priv; - u8 chan, page; - - priv = netdev_priv(dev); - - /* FIXME: locking */ - chan = priv->hw->phy->current_channel; - page = priv->hw->phy->current_page; - - if (chan == MAC802154_CHAN_NONE) /* not initialized */ - return NETDEV_TX_OK; - - if (WARN_ON(page >= WPAN_NUM_PAGES) || - WARN_ON(chan >= WPAN_NUM_CHANNELS)) - return NETDEV_TX_OK; - - skb->skb_iif = dev->ifindex; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - - return mac802154_tx(priv->hw, skb, page, chan); -} - - -void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb) -{ - struct sk_buff *skb2; - struct mac802154_sub_if_data *sdata; - u16 crc = crc_ccitt(0, skb->data, skb->len); - u8 *data; - - rcu_read_lock(); - list_for_each_entry_rcu(sdata, &priv->slaves, list) { - if (sdata->type != IEEE802154_DEV_MONITOR) - continue; - - skb2 = skb_clone(skb, GFP_ATOMIC); - skb2->dev = sdata->dev; - skb2->pkt_type = PACKET_HOST; - data = skb_put(skb2, 2); - data[0] = crc & 0xff; - data[1] = crc >> 8; - - netif_rx_ni(skb2); - } - rcu_read_unlock(); -} - -static const struct net_device_ops mac802154_monitor_ops = { - .ndo_open = mac802154_slave_open, - .ndo_stop = mac802154_slave_close, - .ndo_start_xmit = mac802154_monitor_xmit, -}; - -void mac802154_monitor_setup(struct net_device *dev) -{ - struct mac802154_sub_if_data *priv; - - dev->addr_len = 0; - dev->hard_header_len = 0; - dev->needed_tailroom = 2; /* room for FCS */ - dev->mtu = IEEE802154_MTU; - dev->tx_queue_len = 10; - dev->type = ARPHRD_IEEE802154_MONITOR; - dev->flags = IFF_NOARP | IFF_BROADCAST; - dev->watchdog_timeo = 0; - - dev->destructor = free_netdev; - dev->netdev_ops = &mac802154_monitor_ops; - dev->ml_priv = &mac802154_mlme_reduced; - - priv = netdev_priv(dev); - priv->type = IEEE802154_DEV_MONITOR; - - priv->chan = MAC802154_CHAN_NONE; /* not initialized */ - priv->page = 0; -} diff --git a/trunk/net/mac802154/rx.c b/trunk/net/mac802154/rx.c deleted file mode 100644 index 4a7d76d4f8bc..000000000000 --- a/trunk/net/mac802154/rx.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2007-2012 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Pavel Smolenskiy - * Maxim Gorbachyov - * Dmitry Eremin-Solenikov - * Alexander Smirnov - */ - -#include -#include -#include -#include -#include - -#include -#include - -#include "mac802154.h" - -/* The IEEE 802.15.4 standard defines 4 MAC packet types: - * - beacon frame - * - MAC command frame - * - acknowledgement frame - * - data frame - * - * and only the data frame should be pushed to the upper layers, other types - * are just internal MAC layer management information. So only data packets - * are going to be sent to the networking queue, all other will be processed - * right here by using the device workqueue. - */ -struct rx_work { - struct sk_buff *skb; - struct work_struct work; - struct ieee802154_dev *dev; - u8 lqi; -}; - -static void -mac802154_subif_rx(struct ieee802154_dev *hw, struct sk_buff *skb, u8 lqi) -{ - struct mac802154_priv *priv = mac802154_to_priv(hw); - - mac_cb(skb)->lqi = lqi; - skb->protocol = htons(ETH_P_IEEE802154); - skb_reset_mac_header(skb); - - BUILD_BUG_ON(sizeof(struct ieee802154_mac_cb) > sizeof(skb->cb)); - - if (!(priv->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { - u16 crc; - - if (skb->len < 2) { - pr_debug("got invalid frame\n"); - goto out; - } - crc = crc_ccitt(0, skb->data, skb->len); - if (crc) { - pr_debug("CRC mismatch\n"); - goto out; - } - skb_trim(skb, skb->len - 2); /* CRC */ - } - - mac802154_monitors_rx(priv, skb); -out: - dev_kfree_skb(skb); - return; -} - -static void mac802154_rx_worker(struct work_struct *work) -{ - struct rx_work *rw = container_of(work, struct rx_work, work); - struct sk_buff *skb = rw->skb; - - mac802154_subif_rx(rw->dev, skb, rw->lqi); - kfree(rw); -} - -void -ieee802154_rx_irqsafe(struct ieee802154_dev *dev, struct sk_buff *skb, u8 lqi) -{ - struct mac802154_priv *priv = mac802154_to_priv(dev); - struct rx_work *work; - - if (!skb) - return; - - work = kzalloc(sizeof(struct rx_work), GFP_ATOMIC); - if (!work) - return; - - INIT_WORK(&work->work, mac802154_rx_worker); - work->skb = skb; - work->dev = dev; - work->lqi = lqi; - - queue_work(priv->dev_workqueue, &work->work); -} -EXPORT_SYMBOL(ieee802154_rx_irqsafe); diff --git a/trunk/net/mac802154/tx.c b/trunk/net/mac802154/tx.c deleted file mode 100644 index 8781d8f904d9..000000000000 --- a/trunk/net/mac802154/tx.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2007-2012 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Dmitry Eremin-Solenikov - * Sergey Lapin - * Maxim Gorbachyov - * Alexander Smirnov - */ - -#include -#include -#include - -#include -#include - -#include "mac802154.h" - -/* IEEE 802.15.4 transceivers can sleep during the xmit session, so process - * packets through the workqueue. - */ -struct xmit_work { - struct sk_buff *skb; - struct work_struct work; - struct mac802154_priv *priv; - u8 chan; - u8 page; - u8 xmit_attempts; -}; - -static void mac802154_xmit_worker(struct work_struct *work) -{ - struct xmit_work *xw = container_of(work, struct xmit_work, work); - int res; - - mutex_lock(&xw->priv->phy->pib_lock); - if (xw->priv->phy->current_channel != xw->chan || - xw->priv->phy->current_page != xw->page) { - res = xw->priv->ops->set_channel(&xw->priv->hw, - xw->page, - xw->chan); - if (res) { - pr_debug("set_channel failed\n"); - goto out; - } - } - - res = xw->priv->ops->xmit(&xw->priv->hw, xw->skb); - -out: - mutex_unlock(&xw->priv->phy->pib_lock); - - if (res) { - if (xw->xmit_attempts++ < MAC802154_MAX_XMIT_ATTEMPTS) { - queue_work(xw->priv->dev_workqueue, &xw->work); - return; - } else - pr_debug("transmission failed for %d times", - MAC802154_MAX_XMIT_ATTEMPTS); - } - - dev_kfree_skb(xw->skb); - - kfree(xw); -} - -netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, - u8 page, u8 chan) -{ - struct xmit_work *work; - - if (!(priv->phy->channels_supported[page] & (1 << chan))) - WARN_ON(1); - return NETDEV_TX_OK; - - if (!(priv->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { - u16 crc = crc_ccitt(0, skb->data, skb->len); - u8 *data = skb_put(skb, 2); - data[0] = crc & 0xff; - data[1] = crc >> 8; - } - - if (skb_cow_head(skb, priv->hw.extra_tx_headroom)) { - dev_kfree_skb(skb); - return NETDEV_TX_OK; - } - - work = kzalloc(sizeof(struct xmit_work), GFP_ATOMIC); - if (!work) - return NETDEV_TX_BUSY; - - INIT_WORK(&work->work, mac802154_xmit_worker); - work->skb = skb; - work->priv = priv; - work->page = page; - work->chan = chan; - work->xmit_attempts = 0; - - queue_work(priv->dev_workqueue, &work->work); - - return NETDEV_TX_OK; -} diff --git a/trunk/net/netfilter/Kconfig b/trunk/net/netfilter/Kconfig index 209c1ed43368..0c6f67e8f2e5 100644 --- a/trunk/net/netfilter/Kconfig +++ b/trunk/net/netfilter/Kconfig @@ -509,21 +509,6 @@ config NETFILTER_XT_TARGET_HL since you can easily create immortal packets that loop forever on the network. -config NETFILTER_XT_TARGET_HMARK - tristate '"HMARK" target support' - depends on (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n) - depends on NETFILTER_ADVANCED - ---help--- - This option adds the "HMARK" target. - - The target allows you to create rules in the "raw" and "mangle" tables - which set the skbuff mark by means of hash calculation within a given - range. The nfmark can influence the routing method (see "Use netfilter - MARK value as routing key") and can also be used by other subsystems to - change their behaviour. - - To compile it as a module, choose M here. If unsure, say N. - config NETFILTER_XT_TARGET_IDLETIMER tristate "IDLETIMER target support" depends on NETFILTER_ADVANCED diff --git a/trunk/net/netfilter/Makefile b/trunk/net/netfilter/Makefile index 4e7960cc7b97..ca3676586f51 100644 --- a/trunk/net/netfilter/Makefile +++ b/trunk/net/netfilter/Makefile @@ -59,7 +59,6 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o -obj-$(CONFIG_NETFILTER_XT_TARGET_HMARK) += xt_HMARK.o obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o obj-$(CONFIG_NETFILTER_XT_TARGET_LOG) += xt_LOG.o obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o diff --git a/trunk/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/trunk/net/netfilter/ipset/ip_set_bitmap_ipmac.c index d7eaf10edb6d..0bb16c469a89 100644 --- a/trunk/net/netfilter/ipset/ip_set_bitmap_ipmac.c +++ b/trunk/net/netfilter/ipset/ip_set_bitmap_ipmac.c @@ -111,7 +111,7 @@ bitmap_ipmac_test(struct ip_set *set, void *value, u32 timeout, u32 flags) return -EAGAIN; case MAC_FILLED: return data->ether == NULL || - ether_addr_equal(data->ether, elem->ether); + compare_ether_addr(data->ether, elem->ether) == 0; } return 0; } @@ -225,7 +225,7 @@ bitmap_ipmac_ttest(struct ip_set *set, void *value, u32 timeout, u32 flags) return -EAGAIN; case MAC_FILLED: return (data->ether == NULL || - ether_addr_equal(data->ether, elem->ether)) && + compare_ether_addr(data->ether, elem->ether) == 0) && !bitmap_expired(map, data->id); } return 0; diff --git a/trunk/net/netfilter/ipset/ip_set_hash_ip.c b/trunk/net/netfilter/ipset/ip_set_hash_ip.c index a68dbd4f1e4e..507fe93794aa 100644 --- a/trunk/net/netfilter/ipset/ip_set_hash_ip.c +++ b/trunk/net/netfilter/ipset/ip_set_hash_ip.c @@ -368,7 +368,6 @@ hash_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags) { u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; u8 netmask, hbits; - size_t hsize; struct ip_set_hash *h; if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) @@ -410,12 +409,9 @@ hash_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags) h->timeout = IPSET_NO_TIMEOUT; hbits = htable_bits(hashsize); - hsize = htable_size(hbits); - if (hsize == 0) { - kfree(h); - return -ENOMEM; - } - h->table = ip_set_alloc(hsize); + h->table = ip_set_alloc( + sizeof(struct htable) + + jhash_size(hbits) * sizeof(struct hbucket)); if (!h->table) { kfree(h); return -ENOMEM; diff --git a/trunk/net/netfilter/ipset/ip_set_hash_ipport.c b/trunk/net/netfilter/ipset/ip_set_hash_ipport.c index 92722bb82eea..68f284c97490 100644 --- a/trunk/net/netfilter/ipset/ip_set_hash_ipport.c +++ b/trunk/net/netfilter/ipset/ip_set_hash_ipport.c @@ -452,7 +452,6 @@ hash_ipport_create(struct ip_set *set, struct nlattr *tb[], u32 flags) struct ip_set_hash *h; u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; u8 hbits; - size_t hsize; if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) return -IPSET_ERR_INVALID_FAMILY; @@ -480,12 +479,9 @@ hash_ipport_create(struct ip_set *set, struct nlattr *tb[], u32 flags) h->timeout = IPSET_NO_TIMEOUT; hbits = htable_bits(hashsize); - hsize = htable_size(hbits); - if (hsize == 0) { - kfree(h); - return -ENOMEM; - } - h->table = ip_set_alloc(hsize); + h->table = ip_set_alloc( + sizeof(struct htable) + + jhash_size(hbits) * sizeof(struct hbucket)); if (!h->table) { kfree(h); return -ENOMEM; diff --git a/trunk/net/netfilter/ipset/ip_set_hash_ipportip.c b/trunk/net/netfilter/ipset/ip_set_hash_ipportip.c index 0637ce096def..1eec4b9e0dca 100644 --- a/trunk/net/netfilter/ipset/ip_set_hash_ipportip.c +++ b/trunk/net/netfilter/ipset/ip_set_hash_ipportip.c @@ -470,7 +470,6 @@ hash_ipportip_create(struct ip_set *set, struct nlattr *tb[], u32 flags) struct ip_set_hash *h; u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; u8 hbits; - size_t hsize; if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) return -IPSET_ERR_INVALID_FAMILY; @@ -498,12 +497,9 @@ hash_ipportip_create(struct ip_set *set, struct nlattr *tb[], u32 flags) h->timeout = IPSET_NO_TIMEOUT; hbits = htable_bits(hashsize); - hsize = htable_size(hbits); - if (hsize == 0) { - kfree(h); - return -ENOMEM; - } - h->table = ip_set_alloc(hsize); + h->table = ip_set_alloc( + sizeof(struct htable) + + jhash_size(hbits) * sizeof(struct hbucket)); if (!h->table) { kfree(h); return -ENOMEM; diff --git a/trunk/net/netfilter/ipset/ip_set_hash_ipportnet.c b/trunk/net/netfilter/ipset/ip_set_hash_ipportnet.c index 1ce21ca976e1..62d66ecef369 100644 --- a/trunk/net/netfilter/ipset/ip_set_hash_ipportnet.c +++ b/trunk/net/netfilter/ipset/ip_set_hash_ipportnet.c @@ -619,7 +619,6 @@ hash_ipportnet_create(struct ip_set *set, struct nlattr *tb[], u32 flags) struct ip_set_hash *h; u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; u8 hbits; - size_t hsize; if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) return -IPSET_ERR_INVALID_FAMILY; @@ -649,12 +648,9 @@ hash_ipportnet_create(struct ip_set *set, struct nlattr *tb[], u32 flags) h->timeout = IPSET_NO_TIMEOUT; hbits = htable_bits(hashsize); - hsize = htable_size(hbits); - if (hsize == 0) { - kfree(h); - return -ENOMEM; - } - h->table = ip_set_alloc(hsize); + h->table = ip_set_alloc( + sizeof(struct htable) + + jhash_size(hbits) * sizeof(struct hbucket)); if (!h->table) { kfree(h); return -ENOMEM; diff --git a/trunk/net/netfilter/ipset/ip_set_hash_net.c b/trunk/net/netfilter/ipset/ip_set_hash_net.c index c57a6a09906d..6607a814be57 100644 --- a/trunk/net/netfilter/ipset/ip_set_hash_net.c +++ b/trunk/net/netfilter/ipset/ip_set_hash_net.c @@ -463,7 +463,6 @@ hash_net_create(struct ip_set *set, struct nlattr *tb[], u32 flags) u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; struct ip_set_hash *h; u8 hbits; - size_t hsize; if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) return -IPSET_ERR_INVALID_FAMILY; @@ -493,12 +492,9 @@ hash_net_create(struct ip_set *set, struct nlattr *tb[], u32 flags) h->timeout = IPSET_NO_TIMEOUT; hbits = htable_bits(hashsize); - hsize = htable_size(hbits); - if (hsize == 0) { - kfree(h); - return -ENOMEM; - } - h->table = ip_set_alloc(hsize); + h->table = ip_set_alloc( + sizeof(struct htable) + + jhash_size(hbits) * sizeof(struct hbucket)); if (!h->table) { kfree(h); return -ENOMEM; diff --git a/trunk/net/netfilter/ipset/ip_set_hash_netiface.c b/trunk/net/netfilter/ipset/ip_set_hash_netiface.c index ee863943c826..6093f3daa911 100644 --- a/trunk/net/netfilter/ipset/ip_set_hash_netiface.c +++ b/trunk/net/netfilter/ipset/ip_set_hash_netiface.c @@ -726,7 +726,6 @@ hash_netiface_create(struct ip_set *set, struct nlattr *tb[], u32 flags) struct ip_set_hash *h; u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; u8 hbits; - size_t hsize; if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) return -IPSET_ERR_INVALID_FAMILY; @@ -757,12 +756,9 @@ hash_netiface_create(struct ip_set *set, struct nlattr *tb[], u32 flags) h->ahash_max = AHASH_MAX_SIZE; hbits = htable_bits(hashsize); - hsize = htable_size(hbits); - if (hsize == 0) { - kfree(h); - return -ENOMEM; - } - h->table = ip_set_alloc(hsize); + h->table = ip_set_alloc( + sizeof(struct htable) + + jhash_size(hbits) * sizeof(struct hbucket)); if (!h->table) { kfree(h); return -ENOMEM; diff --git a/trunk/net/netfilter/ipset/ip_set_hash_netport.c b/trunk/net/netfilter/ipset/ip_set_hash_netport.c index fc3143a2d41b..ae3c644adc14 100644 --- a/trunk/net/netfilter/ipset/ip_set_hash_netport.c +++ b/trunk/net/netfilter/ipset/ip_set_hash_netport.c @@ -575,7 +575,6 @@ hash_netport_create(struct ip_set *set, struct nlattr *tb[], u32 flags) struct ip_set_hash *h; u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; u8 hbits; - size_t hsize; if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) return -IPSET_ERR_INVALID_FAMILY; @@ -605,12 +604,9 @@ hash_netport_create(struct ip_set *set, struct nlattr *tb[], u32 flags) h->timeout = IPSET_NO_TIMEOUT; hbits = htable_bits(hashsize); - hsize = htable_size(hbits); - if (hsize == 0) { - kfree(h); - return -ENOMEM; - } - h->table = ip_set_alloc(hsize); + h->table = ip_set_alloc( + sizeof(struct htable) + + jhash_size(hbits) * sizeof(struct hbucket)); if (!h->table) { kfree(h); return -ENOMEM; diff --git a/trunk/net/netfilter/nf_conntrack_amanda.c b/trunk/net/netfilter/nf_conntrack_amanda.c index f2de8c55ac50..13fd2c55e329 100644 --- a/trunk/net/netfilter/nf_conntrack_amanda.c +++ b/trunk/net/netfilter/nf_conntrack_amanda.c @@ -107,7 +107,8 @@ static int amanda_help(struct sk_buff *skb, /* No data? */ dataoff = protoff + sizeof(struct udphdr); if (dataoff >= skb->len) { - net_err_ratelimited("amanda_help: skblen = %u\n", skb->len); + if (net_ratelimit()) + printk(KERN_ERR "amanda_help: skblen = %u\n", skb->len); return NF_ACCEPT; } diff --git a/trunk/net/netfilter/nf_conntrack_core.c b/trunk/net/netfilter/nf_conntrack_core.c index ac3af97cc468..32c59093146e 100644 --- a/trunk/net/netfilter/nf_conntrack_core.c +++ b/trunk/net/netfilter/nf_conntrack_core.c @@ -683,7 +683,10 @@ __nf_conntrack_alloc(struct net *net, u16 zone, unlikely(atomic_read(&net->ct.count) > nf_conntrack_max)) { if (!early_drop(net, hash_bucket(hash, net))) { atomic_dec(&net->ct.count); - net_warn_ratelimited("nf_conntrack: table full, dropping packet\n"); + if (net_ratelimit()) + printk(KERN_WARNING + "nf_conntrack: table full, dropping" + " packet.\n"); return ERR_PTR(-ENOMEM); } } diff --git a/trunk/net/netfilter/nf_conntrack_expect.c b/trunk/net/netfilter/nf_conntrack_expect.c index 45cf602a76bc..4147ba3f653c 100644 --- a/trunk/net/netfilter/nf_conntrack_expect.c +++ b/trunk/net/netfilter/nf_conntrack_expect.c @@ -424,7 +424,9 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect) } if (net->ct.expect_count >= nf_ct_expect_max) { - net_warn_ratelimited("nf_conntrack: expectation table full\n"); + if (net_ratelimit()) + printk(KERN_WARNING + "nf_conntrack: expectation table full\n"); ret = -EMFILE; } out: diff --git a/trunk/net/netfilter/nf_conntrack_h323_main.c b/trunk/net/netfilter/nf_conntrack_h323_main.c index 46d69d7f1bb4..471b054ad002 100644 --- a/trunk/net/netfilter/nf_conntrack_h323_main.c +++ b/trunk/net/netfilter/nf_conntrack_h323_main.c @@ -605,7 +605,8 @@ static int h245_help(struct sk_buff *skb, unsigned int protoff, drop: spin_unlock_bh(&nf_h323_lock); - net_info_ratelimited("nf_ct_h245: packet dropped\n"); + if (net_ratelimit()) + pr_info("nf_ct_h245: packet dropped\n"); return NF_DROP; } @@ -1155,7 +1156,8 @@ static int q931_help(struct sk_buff *skb, unsigned int protoff, drop: spin_unlock_bh(&nf_h323_lock); - net_info_ratelimited("nf_ct_q931: packet dropped\n"); + if (net_ratelimit()) + pr_info("nf_ct_q931: packet dropped\n"); return NF_DROP; } @@ -1729,7 +1731,8 @@ static int ras_help(struct sk_buff *skb, unsigned int protoff, drop: spin_unlock_bh(&nf_h323_lock); - net_info_ratelimited("nf_ct_ras: packet dropped\n"); + if (net_ratelimit()) + pr_info("nf_ct_ras: packet dropped\n"); return NF_DROP; } @@ -1830,6 +1833,4 @@ MODULE_AUTHOR("Jing Min Zhao "); MODULE_DESCRIPTION("H.323 connection tracking helper"); MODULE_LICENSE("GPL"); MODULE_ALIAS("ip_conntrack_h323"); -MODULE_ALIAS_NFCT_HELPER("RAS"); -MODULE_ALIAS_NFCT_HELPER("Q.931"); -MODULE_ALIAS_NFCT_HELPER("H.245"); +MODULE_ALIAS_NFCT_HELPER("h323"); diff --git a/trunk/net/netfilter/nf_conntrack_irc.c b/trunk/net/netfilter/nf_conntrack_irc.c index 81366c118271..4f9390b98697 100644 --- a/trunk/net/netfilter/nf_conntrack_irc.c +++ b/trunk/net/netfilter/nf_conntrack_irc.c @@ -185,9 +185,11 @@ static int help(struct sk_buff *skb, unsigned int protoff, tuple = &ct->tuplehash[dir].tuple; if (tuple->src.u3.ip != dcc_ip && tuple->dst.u3.ip != dcc_ip) { - net_warn_ratelimited("Forged DCC command from %pI4: %pI4:%u\n", - &tuple->src.u3.ip, - &dcc_ip, dcc_port); + if (net_ratelimit()) + printk(KERN_WARNING + "Forged DCC command from %pI4: %pI4:%u\n", + &tuple->src.u3.ip, + &dcc_ip, dcc_port); continue; } diff --git a/trunk/net/netfilter/nf_conntrack_proto_tcp.c b/trunk/net/netfilter/nf_conntrack_proto_tcp.c index 21ff1a99f534..4dfbfa840f8a 100644 --- a/trunk/net/netfilter/nf_conntrack_proto_tcp.c +++ b/trunk/net/netfilter/nf_conntrack_proto_tcp.c @@ -952,8 +952,7 @@ static int tcp_packet(struct nf_conn *ct, spin_unlock_bh(&ct->lock); if (LOG_INVALID(net, IPPROTO_TCP)) nf_log_packet(pf, 0, skb, NULL, NULL, NULL, - "nf_ct_tcp: invalid packet ignored in " - "state %s ", tcp_conntrack_names[old_state]); + "nf_ct_tcp: invalid packet ignored "); return NF_ACCEPT; case TCP_CONNTRACK_MAX: /* Invalid packet */ diff --git a/trunk/net/netfilter/nfnetlink_queue.c b/trunk/net/netfilter/nfnetlink_queue.c index 4162437b8361..8d6bcf32c0ed 100644 --- a/trunk/net/netfilter/nfnetlink_queue.c +++ b/trunk/net/netfilter/nfnetlink_queue.c @@ -395,7 +395,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, nla_put_failure: if (skb) kfree_skb(skb); - net_err_ratelimited("nf_queue: error creating packet message\n"); + if (net_ratelimit()) + printk(KERN_ERR "nf_queue: error creating packet message\n"); return NULL; } @@ -432,8 +433,10 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum) } if (queue->queue_total >= queue->queue_maxlen) { queue->queue_dropped++; - net_warn_ratelimited("nf_queue: full at %d entries, dropping packets(s)\n", - queue->queue_total); + if (net_ratelimit()) + printk(KERN_WARNING "nf_queue: full at %d entries, " + "dropping packets(s).\n", + queue->queue_total); goto err_out_free_nskb; } entry->id = ++queue->id_sequence; diff --git a/trunk/net/netfilter/xt_CT.c b/trunk/net/netfilter/xt_CT.c index a51de9b052be..3746d8b9a478 100644 --- a/trunk/net/netfilter/xt_CT.c +++ b/trunk/net/netfilter/xt_CT.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/trunk/net/netfilter/xt_HMARK.c b/trunk/net/netfilter/xt_HMARK.c deleted file mode 100644 index 0a96a43108ed..000000000000 --- a/trunk/net/netfilter/xt_HMARK.c +++ /dev/null @@ -1,362 +0,0 @@ -/* - * xt_HMARK - Netfilter module to set mark by means of hashing - * - * (C) 2012 by Hans Schillstrom - * (C) 2012 by Pablo Neira Ayuso - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -#include -#include -#include - -#include -#include - -#include -#if IS_ENABLED(CONFIG_NF_CONNTRACK) -#include -#endif -#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) -#include -#include -#endif - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Hans Schillstrom "); -MODULE_DESCRIPTION("Xtables: packet marking using hash calculation"); -MODULE_ALIAS("ipt_HMARK"); -MODULE_ALIAS("ip6t_HMARK"); - -struct hmark_tuple { - u32 src; - u32 dst; - union hmark_ports uports; - uint8_t proto; -}; - -static inline u32 hmark_addr6_mask(const __u32 *addr32, const __u32 *mask) -{ - return (addr32[0] & mask[0]) ^ - (addr32[1] & mask[1]) ^ - (addr32[2] & mask[2]) ^ - (addr32[3] & mask[3]); -} - -static inline u32 -hmark_addr_mask(int l3num, const __u32 *addr32, const __u32 *mask) -{ - switch (l3num) { - case AF_INET: - return *addr32 & *mask; - case AF_INET6: - return hmark_addr6_mask(addr32, mask); - } - return 0; -} - -static int -hmark_ct_set_htuple(const struct sk_buff *skb, struct hmark_tuple *t, - const struct xt_hmark_info *info) -{ -#if IS_ENABLED(CONFIG_NF_CONNTRACK) - enum ip_conntrack_info ctinfo; - struct nf_conn *ct = nf_ct_get(skb, &ctinfo); - struct nf_conntrack_tuple *otuple; - struct nf_conntrack_tuple *rtuple; - - if (ct == NULL || nf_ct_is_untracked(ct)) - return -1; - - otuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; - rtuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple; - - t->src = hmark_addr_mask(otuple->src.l3num, otuple->src.u3.all, - info->src_mask.all); - t->dst = hmark_addr_mask(otuple->src.l3num, rtuple->src.u3.all, - info->dst_mask.all); - - if (info->flags & XT_HMARK_FLAG(XT_HMARK_METHOD_L3)) - return 0; - - t->proto = nf_ct_protonum(ct); - if (t->proto != IPPROTO_ICMP) { - t->uports.p16.src = otuple->src.u.all; - t->uports.p16.dst = rtuple->src.u.all; - t->uports.v32 = (t->uports.v32 & info->port_mask.v32) | - info->port_set.v32; - if (t->uports.p16.dst < t->uports.p16.src) - swap(t->uports.p16.dst, t->uports.p16.src); - } - - return 0; -#else - return -1; -#endif -} - -static inline u32 -hmark_hash(struct hmark_tuple *t, const struct xt_hmark_info *info) -{ - u32 hash; - - if (t->dst < t->src) - swap(t->src, t->dst); - - hash = jhash_3words(t->src, t->dst, t->uports.v32, info->hashrnd); - hash = hash ^ (t->proto & info->proto_mask); - - return (((u64)hash * info->hmodulus) >> 32) + info->hoffset; -} - -static void -hmark_set_tuple_ports(const struct sk_buff *skb, unsigned int nhoff, - struct hmark_tuple *t, const struct xt_hmark_info *info) -{ - int protoff; - - protoff = proto_ports_offset(t->proto); - if (protoff < 0) - return; - - nhoff += protoff; - if (skb_copy_bits(skb, nhoff, &t->uports, sizeof(t->uports)) < 0) - return; - - t->uports.v32 = (t->uports.v32 & info->port_mask.v32) | - info->port_set.v32; - - if (t->uports.p16.dst < t->uports.p16.src) - swap(t->uports.p16.dst, t->uports.p16.src); -} - -#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) -static int get_inner6_hdr(const struct sk_buff *skb, int *offset) -{ - struct icmp6hdr *icmp6h, _ih6; - - icmp6h = skb_header_pointer(skb, *offset, sizeof(_ih6), &_ih6); - if (icmp6h == NULL) - return 0; - - if (icmp6h->icmp6_type && icmp6h->icmp6_type < 128) { - *offset += sizeof(struct icmp6hdr); - return 1; - } - return 0; -} - -static int -hmark_pkt_set_htuple_ipv6(const struct sk_buff *skb, struct hmark_tuple *t, - const struct xt_hmark_info *info) -{ - struct ipv6hdr *ip6, _ip6; - int flag = IP6T_FH_F_AUTH; - unsigned int nhoff = 0; - u16 fragoff = 0; - int nexthdr; - - ip6 = (struct ipv6hdr *) (skb->data + skb_network_offset(skb)); - nexthdr = ipv6_find_hdr(skb, &nhoff, -1, &fragoff, &flag); - if (nexthdr < 0) - return 0; - /* No need to check for icmp errors on fragments */ - if ((flag & IP6T_FH_F_FRAG) || (nexthdr != IPPROTO_ICMPV6)) - goto noicmp; - /* Use inner header in case of ICMP errors */ - if (get_inner6_hdr(skb, &nhoff)) { - ip6 = skb_header_pointer(skb, nhoff, sizeof(_ip6), &_ip6); - if (ip6 == NULL) - return -1; - /* If AH present, use SPI like in ESP. */ - flag = IP6T_FH_F_AUTH; - nexthdr = ipv6_find_hdr(skb, &nhoff, -1, &fragoff, &flag); - if (nexthdr < 0) - return -1; - } -noicmp: - t->src = hmark_addr6_mask(ip6->saddr.s6_addr32, info->src_mask.all); - t->dst = hmark_addr6_mask(ip6->daddr.s6_addr32, info->dst_mask.all); - - if (info->flags & XT_HMARK_FLAG(XT_HMARK_METHOD_L3)) - return 0; - - t->proto = nexthdr; - if (t->proto == IPPROTO_ICMPV6) - return 0; - - if (flag & IP6T_FH_F_FRAG) - return 0; - - hmark_set_tuple_ports(skb, nhoff, t, info); - return 0; -} - -static unsigned int -hmark_tg_v6(struct sk_buff *skb, const struct xt_action_param *par) -{ - const struct xt_hmark_info *info = par->targinfo; - struct hmark_tuple t; - - memset(&t, 0, sizeof(struct hmark_tuple)); - - if (info->flags & XT_HMARK_FLAG(XT_HMARK_CT)) { - if (hmark_ct_set_htuple(skb, &t, info) < 0) - return XT_CONTINUE; - } else { - if (hmark_pkt_set_htuple_ipv6(skb, &t, info) < 0) - return XT_CONTINUE; - } - - skb->mark = hmark_hash(&t, info); - return XT_CONTINUE; -} -#endif - -static int get_inner_hdr(const struct sk_buff *skb, int iphsz, int *nhoff) -{ - const struct icmphdr *icmph; - struct icmphdr _ih; - - /* Not enough header? */ - icmph = skb_header_pointer(skb, *nhoff + iphsz, sizeof(_ih), &_ih); - if (icmph == NULL || icmph->type > NR_ICMP_TYPES) - return 0; - - /* Error message? */ - if (icmph->type != ICMP_DEST_UNREACH && - icmph->type != ICMP_SOURCE_QUENCH && - icmph->type != ICMP_TIME_EXCEEDED && - icmph->type != ICMP_PARAMETERPROB && - icmph->type != ICMP_REDIRECT) - return 0; - - *nhoff += iphsz + sizeof(_ih); - return 1; -} - -static int -hmark_pkt_set_htuple_ipv4(const struct sk_buff *skb, struct hmark_tuple *t, - const struct xt_hmark_info *info) -{ - struct iphdr *ip, _ip; - int nhoff = skb_network_offset(skb); - - ip = (struct iphdr *) (skb->data + nhoff); - if (ip->protocol == IPPROTO_ICMP) { - /* Use inner header in case of ICMP errors */ - if (get_inner_hdr(skb, ip->ihl * 4, &nhoff)) { - ip = skb_header_pointer(skb, nhoff, sizeof(_ip), &_ip); - if (ip == NULL) - return -1; - } - } - - t->src = (__force u32) ip->saddr; - t->dst = (__force u32) ip->daddr; - - t->src &= info->src_mask.ip; - t->dst &= info->dst_mask.ip; - - if (info->flags & XT_HMARK_FLAG(XT_HMARK_METHOD_L3)) - return 0; - - t->proto = ip->protocol; - - /* ICMP has no ports, skip */ - if (t->proto == IPPROTO_ICMP) - return 0; - - /* follow-up fragments don't contain ports, skip all fragments */ - if (ip->frag_off & htons(IP_MF | IP_OFFSET)) - return 0; - - hmark_set_tuple_ports(skb, (ip->ihl * 4) + nhoff, t, info); - - return 0; -} - -static unsigned int -hmark_tg_v4(struct sk_buff *skb, const struct xt_action_param *par) -{ - const struct xt_hmark_info *info = par->targinfo; - struct hmark_tuple t; - - memset(&t, 0, sizeof(struct hmark_tuple)); - - if (info->flags & XT_HMARK_FLAG(XT_HMARK_CT)) { - if (hmark_ct_set_htuple(skb, &t, info) < 0) - return XT_CONTINUE; - } else { - if (hmark_pkt_set_htuple_ipv4(skb, &t, info) < 0) - return XT_CONTINUE; - } - - skb->mark = hmark_hash(&t, info); - return XT_CONTINUE; -} - -static int hmark_tg_check(const struct xt_tgchk_param *par) -{ - const struct xt_hmark_info *info = par->targinfo; - - if (!info->hmodulus) { - pr_info("xt_HMARK: hash modulus can't be zero\n"); - return -EINVAL; - } - if (info->proto_mask && - (info->flags & XT_HMARK_FLAG(XT_HMARK_METHOD_L3))) { - pr_info("xt_HMARK: proto mask must be zero with L3 mode\n"); - return -EINVAL; - } - if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPI_MASK) && - (info->flags & (XT_HMARK_FLAG(XT_HMARK_SPORT_MASK) | - XT_HMARK_FLAG(XT_HMARK_DPORT_MASK)))) { - pr_info("xt_HMARK: spi-mask and port-mask can't be combined\n"); - return -EINVAL; - } - if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPI) && - (info->flags & (XT_HMARK_FLAG(XT_HMARK_SPORT) | - XT_HMARK_FLAG(XT_HMARK_DPORT)))) { - pr_info("xt_HMARK: spi-set and port-set can't be combined\n"); - return -EINVAL; - } - return 0; -} - -static struct xt_target hmark_tg_reg[] __read_mostly = { - { - .name = "HMARK", - .family = NFPROTO_IPV4, - .target = hmark_tg_v4, - .targetsize = sizeof(struct xt_hmark_info), - .checkentry = hmark_tg_check, - .me = THIS_MODULE, - }, -#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) - { - .name = "HMARK", - .family = NFPROTO_IPV6, - .target = hmark_tg_v6, - .targetsize = sizeof(struct xt_hmark_info), - .checkentry = hmark_tg_check, - .me = THIS_MODULE, - }, -#endif -}; - -static int __init hmark_tg_init(void) -{ - return xt_register_targets(hmark_tg_reg, ARRAY_SIZE(hmark_tg_reg)); -} - -static void __exit hmark_tg_exit(void) -{ - xt_unregister_targets(hmark_tg_reg, ARRAY_SIZE(hmark_tg_reg)); -} - -module_init(hmark_tg_init); -module_exit(hmark_tg_exit); diff --git a/trunk/net/netfilter/xt_TCPMSS.c b/trunk/net/netfilter/xt_TCPMSS.c index 71a266de5fb4..190ad37c5cf8 100644 --- a/trunk/net/netfilter/xt_TCPMSS.c +++ b/trunk/net/netfilter/xt_TCPMSS.c @@ -67,13 +67,15 @@ tcpmss_mangle_packet(struct sk_buff *skb, if (info->mss == XT_TCPMSS_CLAMP_PMTU) { if (dst_mtu(skb_dst(skb)) <= minlen) { - net_err_ratelimited("unknown or invalid path-MTU (%u)\n", - dst_mtu(skb_dst(skb))); + if (net_ratelimit()) + pr_err("unknown or invalid path-MTU (%u)\n", + dst_mtu(skb_dst(skb))); return -1; } if (in_mtu <= minlen) { - net_err_ratelimited("unknown or invalid path-MTU (%u)\n", - in_mtu); + if (net_ratelimit()) + pr_err("unknown or invalid path-MTU (%u)\n", + in_mtu); return -1; } newmss = min(dst_mtu(skb_dst(skb)), in_mtu) - minlen; diff --git a/trunk/net/netfilter/xt_TPROXY.c b/trunk/net/netfilter/xt_TPROXY.c index 146033a86de8..35a959a096e0 100644 --- a/trunk/net/netfilter/xt_TPROXY.c +++ b/trunk/net/netfilter/xt_TPROXY.c @@ -282,10 +282,10 @@ tproxy_tg6_v1(struct sk_buff *skb, const struct xt_action_param *par) struct sock *sk; const struct in6_addr *laddr; __be16 lport; - int thoff = 0; + int thoff; int tproto; - tproto = ipv6_find_hdr(skb, &thoff, -1, NULL, NULL); + tproto = ipv6_find_hdr(skb, &thoff, -1, NULL); if (tproto < 0) { pr_debug("unable to find transport header in IPv6 packet, dropping\n"); return NF_DROP; diff --git a/trunk/net/netfilter/xt_hashlimit.c b/trunk/net/netfilter/xt_hashlimit.c index 26a668a84aa2..d95f9c963cde 100644 --- a/trunk/net/netfilter/xt_hashlimit.c +++ b/trunk/net/netfilter/xt_hashlimit.c @@ -171,7 +171,8 @@ dsthash_alloc_init(struct xt_hashlimit_htable *ht, if (ht->cfg.max && ht->count >= ht->cfg.max) { /* FIXME: do something. question is what.. */ - net_err_ratelimited("max count of %u reached\n", ht->cfg.max); + if (net_ratelimit()) + pr_err("max count of %u reached\n", ht->cfg.max); ent = NULL; } else ent = kmem_cache_alloc(hashlimit_cachep, GFP_ATOMIC); @@ -387,20 +388,9 @@ static void htable_put(struct xt_hashlimit_htable *hinfo) #define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ) -/* in byte mode, the lowest possible rate is one packet/second. - * credit_cap is used as a counter that tells us how many times we can - * refill the "credits available" counter when it becomes empty. - */ -#define MAX_CPJ_BYTES (0xFFFFFFFF / HZ) -#define CREDITS_PER_JIFFY_BYTES POW2_BELOW32(MAX_CPJ_BYTES) - -static u32 xt_hashlimit_len_to_chunks(u32 len) -{ - return (len >> XT_HASHLIMIT_BYTE_SHIFT) + 1; -} - /* Precision saver. */ -static u32 user2credits(u32 user) +static inline u_int32_t +user2credits(u_int32_t user) { /* If multiplying would overflow... */ if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY)) @@ -410,53 +400,12 @@ static u32 user2credits(u32 user) return (user * HZ * CREDITS_PER_JIFFY) / XT_HASHLIMIT_SCALE; } -static u32 user2credits_byte(u32 user) +static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now) { - u64 us = user; - us *= HZ * CREDITS_PER_JIFFY_BYTES; - return (u32) (us >> 32); -} - -static void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now, u32 mode) -{ - unsigned long delta = now - dh->rateinfo.prev; - u32 cap; - - if (delta == 0) - return; - + dh->rateinfo.credit += (now - dh->rateinfo.prev) * CREDITS_PER_JIFFY; + if (dh->rateinfo.credit > dh->rateinfo.credit_cap) + dh->rateinfo.credit = dh->rateinfo.credit_cap; dh->rateinfo.prev = now; - - if (mode & XT_HASHLIMIT_BYTES) { - u32 tmp = dh->rateinfo.credit; - dh->rateinfo.credit += CREDITS_PER_JIFFY_BYTES * delta; - cap = CREDITS_PER_JIFFY_BYTES * HZ; - if (tmp >= dh->rateinfo.credit) {/* overflow */ - dh->rateinfo.credit = cap; - return; - } - } else { - dh->rateinfo.credit += delta * CREDITS_PER_JIFFY; - cap = dh->rateinfo.credit_cap; - } - if (dh->rateinfo.credit > cap) - dh->rateinfo.credit = cap; -} - -static void rateinfo_init(struct dsthash_ent *dh, - struct xt_hashlimit_htable *hinfo) -{ - dh->rateinfo.prev = jiffies; - if (hinfo->cfg.mode & XT_HASHLIMIT_BYTES) { - dh->rateinfo.credit = CREDITS_PER_JIFFY_BYTES * HZ; - dh->rateinfo.cost = user2credits_byte(hinfo->cfg.avg); - dh->rateinfo.credit_cap = hinfo->cfg.burst; - } else { - dh->rateinfo.credit = user2credits(hinfo->cfg.avg * - hinfo->cfg.burst); - dh->rateinfo.cost = user2credits(hinfo->cfg.avg); - dh->rateinfo.credit_cap = dh->rateinfo.credit; - } } static inline __be32 maskl(__be32 a, unsigned int l) @@ -562,21 +511,6 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo, return 0; } -static u32 hashlimit_byte_cost(unsigned int len, struct dsthash_ent *dh) -{ - u64 tmp = xt_hashlimit_len_to_chunks(len); - tmp = tmp * dh->rateinfo.cost; - - if (unlikely(tmp > CREDITS_PER_JIFFY_BYTES * HZ)) - tmp = CREDITS_PER_JIFFY_BYTES * HZ; - - if (dh->rateinfo.credit < tmp && dh->rateinfo.credit_cap) { - dh->rateinfo.credit_cap--; - dh->rateinfo.credit = CREDITS_PER_JIFFY_BYTES * HZ; - } - return (u32) tmp; -} - static bool hashlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) { @@ -585,7 +519,6 @@ hashlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) unsigned long now = jiffies; struct dsthash_ent *dh; struct dsthash_dst dst; - u32 cost; if (hashlimit_init_dst(hinfo, &dst, skb, par->thoff) < 0) goto hotdrop; @@ -599,21 +532,21 @@ hashlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) goto hotdrop; } dh->expires = jiffies + msecs_to_jiffies(hinfo->cfg.expire); - rateinfo_init(dh, hinfo); + dh->rateinfo.prev = jiffies; + dh->rateinfo.credit = user2credits(hinfo->cfg.avg * + hinfo->cfg.burst); + dh->rateinfo.credit_cap = user2credits(hinfo->cfg.avg * + hinfo->cfg.burst); + dh->rateinfo.cost = user2credits(hinfo->cfg.avg); } else { /* update expiration timeout */ dh->expires = now + msecs_to_jiffies(hinfo->cfg.expire); - rateinfo_recalc(dh, now, hinfo->cfg.mode); + rateinfo_recalc(dh, now); } - if (info->cfg.mode & XT_HASHLIMIT_BYTES) - cost = hashlimit_byte_cost(skb->len, dh); - else - cost = dh->rateinfo.cost; - - if (dh->rateinfo.credit >= cost) { + if (dh->rateinfo.credit >= dh->rateinfo.cost) { /* below the limit */ - dh->rateinfo.credit -= cost; + dh->rateinfo.credit -= dh->rateinfo.cost; spin_unlock(&dh->lock); rcu_read_unlock_bh(); return !(info->cfg.mode & XT_HASHLIMIT_INVERT); @@ -635,6 +568,14 @@ static int hashlimit_mt_check(const struct xt_mtchk_param *par) struct xt_hashlimit_mtinfo1 *info = par->matchinfo; int ret; + /* Check for overflow. */ + if (info->cfg.burst == 0 || + user2credits(info->cfg.avg * info->cfg.burst) < + user2credits(info->cfg.avg)) { + pr_info("overflow, try lower: %u/%u\n", + info->cfg.avg, info->cfg.burst); + return -ERANGE; + } if (info->cfg.gc_interval == 0 || info->cfg.expire == 0) return -EINVAL; if (info->name[sizeof(info->name)-1] != '\0') @@ -647,26 +588,6 @@ static int hashlimit_mt_check(const struct xt_mtchk_param *par) return -EINVAL; } - if (info->cfg.mode & ~XT_HASHLIMIT_ALL) { - pr_info("Unknown mode mask %X, kernel too old?\n", - info->cfg.mode); - return -EINVAL; - } - - /* Check for overflow. */ - if (info->cfg.mode & XT_HASHLIMIT_BYTES) { - if (user2credits_byte(info->cfg.avg) == 0) { - pr_info("overflow, rate too high: %u\n", info->cfg.avg); - return -EINVAL; - } - } else if (info->cfg.burst == 0 || - user2credits(info->cfg.avg * info->cfg.burst) < - user2credits(info->cfg.avg)) { - pr_info("overflow, try lower: %u/%u\n", - info->cfg.avg, info->cfg.burst); - return -ERANGE; - } - mutex_lock(&hashlimit_mutex); info->hinfo = htable_find_get(net, info->name, par->family); if (info->hinfo == NULL) { @@ -759,11 +680,10 @@ static int dl_seq_real_show(struct dsthash_ent *ent, u_int8_t family, struct seq_file *s) { int res; - const struct xt_hashlimit_htable *ht = s->private; spin_lock(&ent->lock); /* recalculate to show accurate numbers */ - rateinfo_recalc(ent, jiffies, ht->cfg.mode); + rateinfo_recalc(ent, jiffies); switch (family) { case NFPROTO_IPV4: diff --git a/trunk/net/netfilter/xt_limit.c b/trunk/net/netfilter/xt_limit.c index 5c22ce8ab309..32b7a579a032 100644 --- a/trunk/net/netfilter/xt_limit.c +++ b/trunk/net/netfilter/xt_limit.c @@ -88,7 +88,8 @@ limit_mt(const struct sk_buff *skb, struct xt_action_param *par) } /* Precision saver. */ -static u32 user2credits(u32 user) +static u_int32_t +user2credits(u_int32_t user) { /* If multiplying would overflow... */ if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY)) @@ -122,7 +123,7 @@ static int limit_mt_check(const struct xt_mtchk_param *par) 128. */ priv->prev = jiffies; priv->credit = user2credits(r->avg * r->burst); /* Credits full. */ - r->credit_cap = priv->credit; /* Credits full. */ + r->credit_cap = user2credits(r->avg * r->burst); /* Credits full. */ r->cost = user2credits(r->avg); } return 0; diff --git a/trunk/net/netfilter/xt_mac.c b/trunk/net/netfilter/xt_mac.c index d5b4fd4f91ed..8160f6b1435d 100644 --- a/trunk/net/netfilter/xt_mac.c +++ b/trunk/net/netfilter/xt_mac.c @@ -36,7 +36,7 @@ static bool mac_mt(const struct sk_buff *skb, struct xt_action_param *par) return false; if (skb_mac_header(skb) + ETH_HLEN > skb->data) return false; - ret = ether_addr_equal(eth_hdr(skb)->h_source, info->srcaddr); + ret = compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr) == 0; ret ^= info->invert; return ret; } diff --git a/trunk/net/netfilter/xt_set.c b/trunk/net/netfilter/xt_set.c index 035960ec5cb9..0ec8138aa470 100644 --- a/trunk/net/netfilter/xt_set.c +++ b/trunk/net/netfilter/xt_set.c @@ -44,14 +44,6 @@ const struct ip_set_adt_opt n = { \ .cmdflags = cfs, \ .timeout = t, \ } -#define ADT_MOPT(n, f, d, fs, cfs, t) \ -struct ip_set_adt_opt n = { \ - .family = f, \ - .dim = d, \ - .flags = fs, \ - .cmdflags = cfs, \ - .timeout = t, \ -} /* Revision 0 interface: backward compatible with netfilter/iptables */ @@ -304,14 +296,11 @@ static unsigned int set_target_v2(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_set_info_target_v2 *info = par->targinfo; - ADT_MOPT(add_opt, par->family, info->add_set.dim, - info->add_set.flags, info->flags, info->timeout); + ADT_OPT(add_opt, par->family, info->add_set.dim, + info->add_set.flags, info->flags, info->timeout); ADT_OPT(del_opt, par->family, info->del_set.dim, info->del_set.flags, 0, UINT_MAX); - /* Normalize to fit into jiffies */ - if (add_opt.timeout > UINT_MAX/MSEC_PER_SEC) - add_opt.timeout = UINT_MAX/MSEC_PER_SEC; if (info->add_set.index != IPSET_INVALID_ID) ip_set_add(info->add_set.index, skb, par, &add_opt); if (info->del_set.index != IPSET_INVALID_ID) diff --git a/trunk/net/netfilter/xt_socket.c b/trunk/net/netfilter/xt_socket.c index 9ea482d08cf7..72bb07f57f97 100644 --- a/trunk/net/netfilter/xt_socket.c +++ b/trunk/net/netfilter/xt_socket.c @@ -263,10 +263,10 @@ socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par) struct sock *sk; struct in6_addr *daddr, *saddr; __be16 dport, sport; - int thoff = 0, tproto; + int thoff, tproto; const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo; - tproto = ipv6_find_hdr(skb, &thoff, -1, NULL, NULL); + tproto = ipv6_find_hdr(skb, &thoff, -1, NULL); if (tproto < 0) { pr_debug("unable to find transport header in IPv6 packet, dropping\n"); return NF_DROP; diff --git a/trunk/net/openvswitch/datapath.c b/trunk/net/openvswitch/datapath.c index 2c74daa5aca5..f86de29979ef 100644 --- a/trunk/net/openvswitch/datapath.c +++ b/trunk/net/openvswitch/datapath.c @@ -321,7 +321,7 @@ static int queue_userspace_packet(int dp_ifindex, struct sk_buff *skb, return -ENOMEM; nskb = __vlan_put_tag(nskb, vlan_tx_tag_get(nskb)); - if (!nskb) + if (!skb) return -ENOMEM; nskb->vlan_tci = 0; @@ -421,19 +421,6 @@ static int validate_sample(const struct nlattr *attr, return validate_actions(actions, key, depth + 1); } -static int validate_tp_port(const struct sw_flow_key *flow_key) -{ - if (flow_key->eth.type == htons(ETH_P_IP)) { - if (flow_key->ipv4.tp.src && flow_key->ipv4.tp.dst) - return 0; - } else if (flow_key->eth.type == htons(ETH_P_IPV6)) { - if (flow_key->ipv6.tp.src && flow_key->ipv6.tp.dst) - return 0; - } - - return -EINVAL; -} - static int validate_set(const struct nlattr *a, const struct sw_flow_key *flow_key) { @@ -475,13 +462,18 @@ static int validate_set(const struct nlattr *a, if (flow_key->ip.proto != IPPROTO_TCP) return -EINVAL; - return validate_tp_port(flow_key); + if (!flow_key->ipv4.tp.src || !flow_key->ipv4.tp.dst) + return -EINVAL; + + break; case OVS_KEY_ATTR_UDP: if (flow_key->ip.proto != IPPROTO_UDP) return -EINVAL; - return validate_tp_port(flow_key); + if (!flow_key->ipv4.tp.src || !flow_key->ipv4.tp.dst) + return -EINVAL; + break; default: return -EINVAL; @@ -1655,9 +1647,10 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info) reply = ovs_vport_cmd_build_info(vport, info->snd_pid, info->snd_seq, OVS_VPORT_CMD_NEW); if (IS_ERR(reply)) { + err = PTR_ERR(reply); netlink_set_err(init_net.genl_sock, 0, - ovs_dp_vport_multicast_group.id, PTR_ERR(reply)); - goto exit_unlock; + ovs_dp_vport_multicast_group.id, err); + return 0; } genl_notify(reply, genl_info_net(info), info->snd_pid, diff --git a/trunk/net/openvswitch/flow.c b/trunk/net/openvswitch/flow.c index 6d4d8097cf96..7cb416381e87 100644 --- a/trunk/net/openvswitch/flow.c +++ b/trunk/net/openvswitch/flow.c @@ -183,8 +183,7 @@ void ovs_flow_used(struct sw_flow *flow, struct sk_buff *skb) u8 tcp_flags = 0; if (flow->key.eth.type == htons(ETH_P_IP) && - flow->key.ip.proto == IPPROTO_TCP && - likely(skb->len >= skb_transport_offset(skb) + sizeof(struct tcphdr))) { + flow->key.ip.proto == IPPROTO_TCP) { u8 *tcp = (u8 *)tcp_hdr(skb); tcp_flags = *(tcp + TCP_FLAGS_OFFSET) & TCP_FLAG_MASK; } diff --git a/trunk/net/openvswitch/vport-netdev.c b/trunk/net/openvswitch/vport-netdev.c index 3fd6c0d88e12..5920bda4ab6b 100644 --- a/trunk/net/openvswitch/vport-netdev.c +++ b/trunk/net/openvswitch/vport-netdev.c @@ -157,9 +157,9 @@ static int netdev_send(struct vport *vport, struct sk_buff *skb) int len; if (unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) { - net_warn_ratelimited("%s: dropped over-mtu packet: %d > %d\n", - ovs_dp_name(vport->dp), - packet_length(skb), mtu); + if (net_ratelimit()) + pr_warn("%s: dropped over-mtu packet: %d > %d\n", + ovs_dp_name(vport->dp), packet_length(skb), mtu); goto error; } diff --git a/trunk/net/sched/Kconfig b/trunk/net/sched/Kconfig index e7a8976bf25c..75b58f81d53d 100644 --- a/trunk/net/sched/Kconfig +++ b/trunk/net/sched/Kconfig @@ -250,28 +250,6 @@ config NET_SCH_QFQ If unsure, say N. -config NET_SCH_CODEL - tristate "Controlled Delay AQM (CODEL)" - help - Say Y here if you want to use the Controlled Delay (CODEL) - packet scheduling algorithm. - - To compile this driver as a module, choose M here: the module - will be called sch_codel. - - If unsure, say N. - -config NET_SCH_FQ_CODEL - tristate "Fair Queue Controlled Delay AQM (FQ_CODEL)" - help - Say Y here if you want to use the FQ Controlled Delay (FQ_CODEL) - packet scheduling algorithm. - - To compile this driver as a module, choose M here: the module - will be called sch_fq_codel. - - If unsure, say N. - config NET_SCH_INGRESS tristate "Ingress Qdisc" depends on NET_CLS_ACT diff --git a/trunk/net/sched/Makefile b/trunk/net/sched/Makefile index 5940a1992f0d..8cdf4e2b51d3 100644 --- a/trunk/net/sched/Makefile +++ b/trunk/net/sched/Makefile @@ -37,8 +37,6 @@ obj-$(CONFIG_NET_SCH_PLUG) += sch_plug.o obj-$(CONFIG_NET_SCH_MQPRIO) += sch_mqprio.o obj-$(CONFIG_NET_SCH_CHOKE) += sch_choke.o obj-$(CONFIG_NET_SCH_QFQ) += sch_qfq.o -obj-$(CONFIG_NET_SCH_CODEL) += sch_codel.o -obj-$(CONFIG_NET_SCH_FQ_CODEL) += sch_fq_codel.o obj-$(CONFIG_NET_CLS_U32) += cls_u32.o obj-$(CONFIG_NET_CLS_ROUTE4) += cls_route.o diff --git a/trunk/net/sched/act_csum.c b/trunk/net/sched/act_csum.c index 2c8ad7c86e43..882124ceb70c 100644 --- a/trunk/net/sched/act_csum.c +++ b/trunk/net/sched/act_csum.c @@ -397,7 +397,7 @@ static int tcf_csum_ipv6_hopopts(struct ipv6_opt_hdr *ip6xh, while (len > 1) { switch (xh[off]) { - case IPV6_TLV_PAD1: + case IPV6_TLV_PAD0: optlen = 1; break; case IPV6_TLV_JUMBO: diff --git a/trunk/net/sched/act_ipt.c b/trunk/net/sched/act_ipt.c index 60e281ad0f07..0beba0e5312e 100644 --- a/trunk/net/sched/act_ipt.c +++ b/trunk/net/sched/act_ipt.c @@ -1,5 +1,5 @@ /* - * net/sched/ipt.c iptables target interface + * net/sched/ipt.c iptables target interface * *TODO: Add other tables. For now we only support the ipv4 table targets * @@ -235,8 +235,9 @@ static int tcf_ipt(struct sk_buff *skb, const struct tc_action *a, result = TC_ACT_PIPE; break; default: - net_notice_ratelimited("tc filter: Bogus netfilter code %d assume ACCEPT\n", - ret); + if (net_ratelimit()) + pr_notice("tc filter: Bogus netfilter code" + " %d assume ACCEPT\n", ret); result = TC_POLICE_OK; break; } diff --git a/trunk/net/sched/act_mirred.c b/trunk/net/sched/act_mirred.c index fe81cc18e9e0..d583aea3b3df 100644 --- a/trunk/net/sched/act_mirred.c +++ b/trunk/net/sched/act_mirred.c @@ -174,8 +174,9 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a, } if (!(dev->flags & IFF_UP)) { - net_notice_ratelimited("tc mirred to Houston: device %s is down\n", - dev->name); + if (net_ratelimit()) + pr_notice("tc mirred to Houston: device %s is down\n", + dev->name); goto out; } diff --git a/trunk/net/sched/cls_u32.c b/trunk/net/sched/cls_u32.c index d45373fb00b9..591b006a8c5a 100644 --- a/trunk/net/sched/cls_u32.c +++ b/trunk/net/sched/cls_u32.c @@ -234,7 +234,8 @@ static int u32_classify(struct sk_buff *skb, const struct tcf_proto *tp, struct return -1; deadloop: - net_warn_ratelimited("cls_u32: dead loop\n"); + if (net_ratelimit()) + pr_warning("cls_u32: dead loop\n"); return -1; } diff --git a/trunk/net/sched/ematch.c b/trunk/net/sched/ematch.c index 3a633debb6df..aca233c2b848 100644 --- a/trunk/net/sched/ematch.c +++ b/trunk/net/sched/ematch.c @@ -537,7 +537,9 @@ int __tcf_em_tree_match(struct sk_buff *skb, struct tcf_ematch_tree *tree, return res; stack_overflow: - net_warn_ratelimited("tc ematch: local stack overflow, increase NET_EMATCH_STACK\n"); + if (net_ratelimit()) + pr_warning("tc ematch: local stack overflow," + " increase NET_EMATCH_STACK\n"); return -1; } EXPORT_SYMBOL(__tcf_em_tree_match); diff --git a/trunk/net/sched/sch_api.c b/trunk/net/sched/sch_api.c index 085ce53d570a..d2daefcc205f 100644 --- a/trunk/net/sched/sch_api.c +++ b/trunk/net/sched/sch_api.c @@ -1691,10 +1691,12 @@ int tc_classify(struct sk_buff *skb, const struct tcf_proto *tp, tp = otp; if (verd++ >= MAX_REC_LOOP) { - net_notice_ratelimited("%s: packet reclassify loop rule prio %u protocol %02x\n", - tp->q->ops->id, - tp->prio & 0xffff, - ntohs(tp->protocol)); + if (net_ratelimit()) + pr_notice("%s: packet reclassify loop" + " rule prio %u protocol %02x\n", + tp->q->ops->id, + tp->prio & 0xffff, + ntohs(tp->protocol)); return TC_ACT_SHOT; } skb->tc_verd = SET_TC_VERD(skb->tc_verd, verd); diff --git a/trunk/net/sched/sch_atm.c b/trunk/net/sched/sch_atm.c index 8522a4793374..a77a4fbc069a 100644 --- a/trunk/net/sched/sch_atm.c +++ b/trunk/net/sched/sch_atm.c @@ -423,6 +423,8 @@ drop: __maybe_unused } return ret; } + qdisc_bstats_update(sch, skb); + bstats_update(&flow->bstats, skb); /* * Okay, this may seem weird. We pretend we've dropped the packet if * it goes via ATM. The reason for this is that the outer qdisc @@ -470,8 +472,6 @@ static void sch_atm_dequeue(unsigned long data) if (unlikely(!skb)) break; - qdisc_bstats_update(sch, skb); - bstats_update(&flow->bstats, skb); pr_debug("atm_tc_dequeue: sending on class %p\n", flow); /* remove any LL header somebody else has attached */ skb_pull(skb, skb_network_offset(skb)); diff --git a/trunk/net/sched/sch_codel.c b/trunk/net/sched/sch_codel.c deleted file mode 100644 index 2f9ab17db85a..000000000000 --- a/trunk/net/sched/sch_codel.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Codel - The Controlled-Delay Active Queue Management algorithm - * - * Copyright (C) 2011-2012 Kathleen Nichols - * Copyright (C) 2011-2012 Van Jacobson - * - * Implemented on linux by : - * Copyright (C) 2012 Michael D. Taht - * Copyright (C) 2012 Eric Dumazet - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The names of the authors may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * Alternatively, provided that this notice is retained in full, this - * software may be distributed under the terms of the GNU General - * Public License ("GPL") version 2, in which case the provisions of the - * GPL apply INSTEAD OF those given above. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define DEFAULT_CODEL_LIMIT 1000 - -struct codel_sched_data { - struct codel_params params; - struct codel_vars vars; - struct codel_stats stats; - u32 drop_overlimit; -}; - -/* This is the specific function called from codel_dequeue() - * to dequeue a packet from queue. Note: backlog is handled in - * codel, we dont need to reduce it here. - */ -static struct sk_buff *dequeue(struct codel_vars *vars, struct Qdisc *sch) -{ - struct sk_buff *skb = __skb_dequeue(&sch->q); - - prefetch(&skb->end); /* we'll need skb_shinfo() */ - return skb; -} - -static struct sk_buff *codel_qdisc_dequeue(struct Qdisc *sch) -{ - struct codel_sched_data *q = qdisc_priv(sch); - struct sk_buff *skb; - - skb = codel_dequeue(sch, &q->params, &q->vars, &q->stats, dequeue); - - /* We cant call qdisc_tree_decrease_qlen() if our qlen is 0, - * or HTB crashes. Defer it for next round. - */ - if (q->stats.drop_count && sch->q.qlen) { - qdisc_tree_decrease_qlen(sch, q->stats.drop_count); - q->stats.drop_count = 0; - } - if (skb) - qdisc_bstats_update(sch, skb); - return skb; -} - -static int codel_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch) -{ - struct codel_sched_data *q; - - if (likely(qdisc_qlen(sch) < sch->limit)) { - codel_set_enqueue_time(skb); - return qdisc_enqueue_tail(skb, sch); - } - q = qdisc_priv(sch); - q->drop_overlimit++; - return qdisc_drop(skb, sch); -} - -static const struct nla_policy codel_policy[TCA_CODEL_MAX + 1] = { - [TCA_CODEL_TARGET] = { .type = NLA_U32 }, - [TCA_CODEL_LIMIT] = { .type = NLA_U32 }, - [TCA_CODEL_INTERVAL] = { .type = NLA_U32 }, - [TCA_CODEL_ECN] = { .type = NLA_U32 }, -}; - -static int codel_change(struct Qdisc *sch, struct nlattr *opt) -{ - struct codel_sched_data *q = qdisc_priv(sch); - struct nlattr *tb[TCA_CODEL_MAX + 1]; - unsigned int qlen; - int err; - - if (!opt) - return -EINVAL; - - err = nla_parse_nested(tb, TCA_CODEL_MAX, opt, codel_policy); - if (err < 0) - return err; - - sch_tree_lock(sch); - - if (tb[TCA_CODEL_TARGET]) { - u32 target = nla_get_u32(tb[TCA_CODEL_TARGET]); - - q->params.target = ((u64)target * NSEC_PER_USEC) >> CODEL_SHIFT; - } - - if (tb[TCA_CODEL_INTERVAL]) { - u32 interval = nla_get_u32(tb[TCA_CODEL_INTERVAL]); - - q->params.interval = ((u64)interval * NSEC_PER_USEC) >> CODEL_SHIFT; - } - - if (tb[TCA_CODEL_LIMIT]) - sch->limit = nla_get_u32(tb[TCA_CODEL_LIMIT]); - - if (tb[TCA_CODEL_ECN]) - q->params.ecn = !!nla_get_u32(tb[TCA_CODEL_ECN]); - - qlen = sch->q.qlen; - while (sch->q.qlen > sch->limit) { - struct sk_buff *skb = __skb_dequeue(&sch->q); - - sch->qstats.backlog -= qdisc_pkt_len(skb); - qdisc_drop(skb, sch); - } - qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen); - - sch_tree_unlock(sch); - return 0; -} - -static int codel_init(struct Qdisc *sch, struct nlattr *opt) -{ - struct codel_sched_data *q = qdisc_priv(sch); - - sch->limit = DEFAULT_CODEL_LIMIT; - - codel_params_init(&q->params); - codel_vars_init(&q->vars); - codel_stats_init(&q->stats); - - if (opt) { - int err = codel_change(sch, opt); - - if (err) - return err; - } - - if (sch->limit >= 1) - sch->flags |= TCQ_F_CAN_BYPASS; - else - sch->flags &= ~TCQ_F_CAN_BYPASS; - - return 0; -} - -static int codel_dump(struct Qdisc *sch, struct sk_buff *skb) -{ - struct codel_sched_data *q = qdisc_priv(sch); - struct nlattr *opts; - - opts = nla_nest_start(skb, TCA_OPTIONS); - if (opts == NULL) - goto nla_put_failure; - - if (nla_put_u32(skb, TCA_CODEL_TARGET, - codel_time_to_us(q->params.target)) || - nla_put_u32(skb, TCA_CODEL_LIMIT, - sch->limit) || - nla_put_u32(skb, TCA_CODEL_INTERVAL, - codel_time_to_us(q->params.interval)) || - nla_put_u32(skb, TCA_CODEL_ECN, - q->params.ecn)) - goto nla_put_failure; - - return nla_nest_end(skb, opts); - -nla_put_failure: - nla_nest_cancel(skb, opts); - return -1; -} - -static int codel_dump_stats(struct Qdisc *sch, struct gnet_dump *d) -{ - const struct codel_sched_data *q = qdisc_priv(sch); - struct tc_codel_xstats st = { - .maxpacket = q->stats.maxpacket, - .count = q->vars.count, - .lastcount = q->vars.lastcount, - .drop_overlimit = q->drop_overlimit, - .ldelay = codel_time_to_us(q->vars.ldelay), - .dropping = q->vars.dropping, - .ecn_mark = q->stats.ecn_mark, - }; - - if (q->vars.dropping) { - codel_tdiff_t delta = q->vars.drop_next - codel_get_time(); - - if (delta >= 0) - st.drop_next = codel_time_to_us(delta); - else - st.drop_next = -codel_time_to_us(-delta); - } - - return gnet_stats_copy_app(d, &st, sizeof(st)); -} - -static void codel_reset(struct Qdisc *sch) -{ - struct codel_sched_data *q = qdisc_priv(sch); - - qdisc_reset_queue(sch); - codel_vars_init(&q->vars); -} - -static struct Qdisc_ops codel_qdisc_ops __read_mostly = { - .id = "codel", - .priv_size = sizeof(struct codel_sched_data), - - .enqueue = codel_qdisc_enqueue, - .dequeue = codel_qdisc_dequeue, - .peek = qdisc_peek_dequeued, - .init = codel_init, - .reset = codel_reset, - .change = codel_change, - .dump = codel_dump, - .dump_stats = codel_dump_stats, - .owner = THIS_MODULE, -}; - -static int __init codel_module_init(void) -{ - return register_qdisc(&codel_qdisc_ops); -} - -static void __exit codel_module_exit(void) -{ - unregister_qdisc(&codel_qdisc_ops); -} - -module_init(codel_module_init) -module_exit(codel_module_exit) - -MODULE_DESCRIPTION("Controlled Delay queue discipline"); -MODULE_AUTHOR("Dave Taht"); -MODULE_AUTHOR("Eric Dumazet"); -MODULE_LICENSE("Dual BSD/GPL"); diff --git a/trunk/net/sched/sch_drr.c b/trunk/net/sched/sch_drr.c index 9ce0b4fe23ff..c2189879359b 100644 --- a/trunk/net/sched/sch_drr.c +++ b/trunk/net/sched/sch_drr.c @@ -376,6 +376,8 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch) cl->deficit = cl->quantum; } + bstats_update(&cl->bstats, skb); + sch->q.qlen++; return err; } @@ -401,8 +403,6 @@ static struct sk_buff *drr_dequeue(struct Qdisc *sch) skb = qdisc_dequeue_peeked(cl->qdisc); if (cl->qdisc->q.qlen == 0) list_del(&cl->alist); - - bstats_update(&cl->bstats, skb); qdisc_bstats_update(sch, skb); sch->q.qlen--; return skb; diff --git a/trunk/net/sched/sch_fq_codel.c b/trunk/net/sched/sch_fq_codel.c deleted file mode 100644 index 9fc1c62ec80e..000000000000 --- a/trunk/net/sched/sch_fq_codel.c +++ /dev/null @@ -1,626 +0,0 @@ -/* - * Fair Queue CoDel discipline - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Copyright (C) 2012 Eric Dumazet - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Fair Queue CoDel. - * - * Principles : - * Packets are classified (internal classifier or external) on flows. - * This is a Stochastic model (as we use a hash, several flows - * might be hashed on same slot) - * Each flow has a CoDel managed queue. - * Flows are linked onto two (Round Robin) lists, - * so that new flows have priority on old ones. - * - * For a given flow, packets are not reordered (CoDel uses a FIFO) - * head drops only. - * ECN capability is on by default. - * Low memory footprint (64 bytes per flow) - */ - -struct fq_codel_flow { - struct sk_buff *head; - struct sk_buff *tail; - struct list_head flowchain; - int deficit; - u32 dropped; /* number of drops (or ECN marks) on this flow */ - struct codel_vars cvars; -}; /* please try to keep this structure <= 64 bytes */ - -struct fq_codel_sched_data { - struct tcf_proto *filter_list; /* optional external classifier */ - struct fq_codel_flow *flows; /* Flows table [flows_cnt] */ - u32 *backlogs; /* backlog table [flows_cnt] */ - u32 flows_cnt; /* number of flows */ - u32 perturbation; /* hash perturbation */ - u32 quantum; /* psched_mtu(qdisc_dev(sch)); */ - struct codel_params cparams; - struct codel_stats cstats; - u32 drop_overlimit; - u32 new_flow_count; - - struct list_head new_flows; /* list of new flows */ - struct list_head old_flows; /* list of old flows */ -}; - -static unsigned int fq_codel_hash(const struct fq_codel_sched_data *q, - const struct sk_buff *skb) -{ - struct flow_keys keys; - unsigned int hash; - - skb_flow_dissect(skb, &keys); - hash = jhash_3words((__force u32)keys.dst, - (__force u32)keys.src ^ keys.ip_proto, - (__force u32)keys.ports, q->perturbation); - return ((u64)hash * q->flows_cnt) >> 32; -} - -static unsigned int fq_codel_classify(struct sk_buff *skb, struct Qdisc *sch, - int *qerr) -{ - struct fq_codel_sched_data *q = qdisc_priv(sch); - struct tcf_result res; - int result; - - if (TC_H_MAJ(skb->priority) == sch->handle && - TC_H_MIN(skb->priority) > 0 && - TC_H_MIN(skb->priority) <= q->flows_cnt) - return TC_H_MIN(skb->priority); - - if (!q->filter_list) - return fq_codel_hash(q, skb) + 1; - - *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; - result = tc_classify(skb, q->filter_list, &res); - if (result >= 0) { -#ifdef CONFIG_NET_CLS_ACT - switch (result) { - case TC_ACT_STOLEN: - case TC_ACT_QUEUED: - *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN; - case TC_ACT_SHOT: - return 0; - } -#endif - if (TC_H_MIN(res.classid) <= q->flows_cnt) - return TC_H_MIN(res.classid); - } - return 0; -} - -/* helper functions : might be changed when/if skb use a standard list_head */ - -/* remove one skb from head of slot queue */ -static inline struct sk_buff *dequeue_head(struct fq_codel_flow *flow) -{ - struct sk_buff *skb = flow->head; - - flow->head = skb->next; - skb->next = NULL; - return skb; -} - -/* add skb to flow queue (tail add) */ -static inline void flow_queue_add(struct fq_codel_flow *flow, - struct sk_buff *skb) -{ - if (flow->head == NULL) - flow->head = skb; - else - flow->tail->next = skb; - flow->tail = skb; - skb->next = NULL; -} - -static unsigned int fq_codel_drop(struct Qdisc *sch) -{ - struct fq_codel_sched_data *q = qdisc_priv(sch); - struct sk_buff *skb; - unsigned int maxbacklog = 0, idx = 0, i, len; - struct fq_codel_flow *flow; - - /* Queue is full! Find the fat flow and drop packet from it. - * This might sound expensive, but with 1024 flows, we scan - * 4KB of memory, and we dont need to handle a complex tree - * in fast path (packet queue/enqueue) with many cache misses. - */ - for (i = 0; i < q->flows_cnt; i++) { - if (q->backlogs[i] > maxbacklog) { - maxbacklog = q->backlogs[i]; - idx = i; - } - } - flow = &q->flows[idx]; - skb = dequeue_head(flow); - len = qdisc_pkt_len(skb); - q->backlogs[idx] -= len; - kfree_skb(skb); - sch->q.qlen--; - sch->qstats.drops++; - sch->qstats.backlog -= len; - flow->dropped++; - return idx; -} - -static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch) -{ - struct fq_codel_sched_data *q = qdisc_priv(sch); - unsigned int idx; - struct fq_codel_flow *flow; - int uninitialized_var(ret); - - idx = fq_codel_classify(skb, sch, &ret); - if (idx == 0) { - if (ret & __NET_XMIT_BYPASS) - sch->qstats.drops++; - kfree_skb(skb); - return ret; - } - idx--; - - codel_set_enqueue_time(skb); - flow = &q->flows[idx]; - flow_queue_add(flow, skb); - q->backlogs[idx] += qdisc_pkt_len(skb); - sch->qstats.backlog += qdisc_pkt_len(skb); - - if (list_empty(&flow->flowchain)) { - list_add_tail(&flow->flowchain, &q->new_flows); - codel_vars_init(&flow->cvars); - q->new_flow_count++; - flow->deficit = q->quantum; - flow->dropped = 0; - } - if (++sch->q.qlen < sch->limit) - return NET_XMIT_SUCCESS; - - q->drop_overlimit++; - /* Return Congestion Notification only if we dropped a packet - * from this flow. - */ - if (fq_codel_drop(sch) == idx) - return NET_XMIT_CN; - - /* As we dropped a packet, better let upper stack know this */ - qdisc_tree_decrease_qlen(sch, 1); - return NET_XMIT_SUCCESS; -} - -/* This is the specific function called from codel_dequeue() - * to dequeue a packet from queue. Note: backlog is handled in - * codel, we dont need to reduce it here. - */ -static struct sk_buff *dequeue(struct codel_vars *vars, struct Qdisc *sch) -{ - struct fq_codel_sched_data *q = qdisc_priv(sch); - struct fq_codel_flow *flow; - struct sk_buff *skb = NULL; - - flow = container_of(vars, struct fq_codel_flow, cvars); - if (flow->head) { - skb = dequeue_head(flow); - q->backlogs[flow - q->flows] -= qdisc_pkt_len(skb); - sch->q.qlen--; - } - return skb; -} - -static struct sk_buff *fq_codel_dequeue(struct Qdisc *sch) -{ - struct fq_codel_sched_data *q = qdisc_priv(sch); - struct sk_buff *skb; - struct fq_codel_flow *flow; - struct list_head *head; - u32 prev_drop_count, prev_ecn_mark; - -begin: - head = &q->new_flows; - if (list_empty(head)) { - head = &q->old_flows; - if (list_empty(head)) - return NULL; - } - flow = list_first_entry(head, struct fq_codel_flow, flowchain); - - if (flow->deficit <= 0) { - flow->deficit += q->quantum; - list_move_tail(&flow->flowchain, &q->old_flows); - goto begin; - } - - prev_drop_count = q->cstats.drop_count; - prev_ecn_mark = q->cstats.ecn_mark; - - skb = codel_dequeue(sch, &q->cparams, &flow->cvars, &q->cstats, - dequeue); - - flow->dropped += q->cstats.drop_count - prev_drop_count; - flow->dropped += q->cstats.ecn_mark - prev_ecn_mark; - - if (!skb) { - /* force a pass through old_flows to prevent starvation */ - if ((head == &q->new_flows) && !list_empty(&q->old_flows)) - list_move_tail(&flow->flowchain, &q->old_flows); - else - list_del_init(&flow->flowchain); - goto begin; - } - qdisc_bstats_update(sch, skb); - flow->deficit -= qdisc_pkt_len(skb); - /* We cant call qdisc_tree_decrease_qlen() if our qlen is 0, - * or HTB crashes. Defer it for next round. - */ - if (q->cstats.drop_count && sch->q.qlen) { - qdisc_tree_decrease_qlen(sch, q->cstats.drop_count); - q->cstats.drop_count = 0; - } - return skb; -} - -static void fq_codel_reset(struct Qdisc *sch) -{ - struct sk_buff *skb; - - while ((skb = fq_codel_dequeue(sch)) != NULL) - kfree_skb(skb); -} - -static const struct nla_policy fq_codel_policy[TCA_FQ_CODEL_MAX + 1] = { - [TCA_FQ_CODEL_TARGET] = { .type = NLA_U32 }, - [TCA_FQ_CODEL_LIMIT] = { .type = NLA_U32 }, - [TCA_FQ_CODEL_INTERVAL] = { .type = NLA_U32 }, - [TCA_FQ_CODEL_ECN] = { .type = NLA_U32 }, - [TCA_FQ_CODEL_FLOWS] = { .type = NLA_U32 }, - [TCA_FQ_CODEL_QUANTUM] = { .type = NLA_U32 }, -}; - -static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt) -{ - struct fq_codel_sched_data *q = qdisc_priv(sch); - struct nlattr *tb[TCA_FQ_CODEL_MAX + 1]; - int err; - - if (!opt) - return -EINVAL; - - err = nla_parse_nested(tb, TCA_FQ_CODEL_MAX, opt, fq_codel_policy); - if (err < 0) - return err; - if (tb[TCA_FQ_CODEL_FLOWS]) { - if (q->flows) - return -EINVAL; - q->flows_cnt = nla_get_u32(tb[TCA_FQ_CODEL_FLOWS]); - if (!q->flows_cnt || - q->flows_cnt > 65536) - return -EINVAL; - } - sch_tree_lock(sch); - - if (tb[TCA_FQ_CODEL_TARGET]) { - u64 target = nla_get_u32(tb[TCA_FQ_CODEL_TARGET]); - - q->cparams.target = (target * NSEC_PER_USEC) >> CODEL_SHIFT; - } - - if (tb[TCA_FQ_CODEL_INTERVAL]) { - u64 interval = nla_get_u32(tb[TCA_FQ_CODEL_INTERVAL]); - - q->cparams.interval = (interval * NSEC_PER_USEC) >> CODEL_SHIFT; - } - - if (tb[TCA_FQ_CODEL_LIMIT]) - sch->limit = nla_get_u32(tb[TCA_FQ_CODEL_LIMIT]); - - if (tb[TCA_FQ_CODEL_ECN]) - q->cparams.ecn = !!nla_get_u32(tb[TCA_FQ_CODEL_ECN]); - - if (tb[TCA_FQ_CODEL_QUANTUM]) - q->quantum = max(256U, nla_get_u32(tb[TCA_FQ_CODEL_QUANTUM])); - - while (sch->q.qlen > sch->limit) { - struct sk_buff *skb = fq_codel_dequeue(sch); - - kfree_skb(skb); - q->cstats.drop_count++; - } - qdisc_tree_decrease_qlen(sch, q->cstats.drop_count); - q->cstats.drop_count = 0; - - sch_tree_unlock(sch); - return 0; -} - -static void *fq_codel_zalloc(size_t sz) -{ - void *ptr = kzalloc(sz, GFP_KERNEL | __GFP_NOWARN); - - if (!ptr) - ptr = vzalloc(sz); - return ptr; -} - -static void fq_codel_free(void *addr) -{ - if (addr) { - if (is_vmalloc_addr(addr)) - vfree(addr); - else - kfree(addr); - } -} - -static void fq_codel_destroy(struct Qdisc *sch) -{ - struct fq_codel_sched_data *q = qdisc_priv(sch); - - tcf_destroy_chain(&q->filter_list); - fq_codel_free(q->backlogs); - fq_codel_free(q->flows); -} - -static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt) -{ - struct fq_codel_sched_data *q = qdisc_priv(sch); - int i; - - sch->limit = 10*1024; - q->flows_cnt = 1024; - q->quantum = psched_mtu(qdisc_dev(sch)); - q->perturbation = net_random(); - INIT_LIST_HEAD(&q->new_flows); - INIT_LIST_HEAD(&q->old_flows); - codel_params_init(&q->cparams); - codel_stats_init(&q->cstats); - q->cparams.ecn = true; - - if (opt) { - int err = fq_codel_change(sch, opt); - if (err) - return err; - } - - if (!q->flows) { - q->flows = fq_codel_zalloc(q->flows_cnt * - sizeof(struct fq_codel_flow)); - if (!q->flows) - return -ENOMEM; - q->backlogs = fq_codel_zalloc(q->flows_cnt * sizeof(u32)); - if (!q->backlogs) { - fq_codel_free(q->flows); - return -ENOMEM; - } - for (i = 0; i < q->flows_cnt; i++) { - struct fq_codel_flow *flow = q->flows + i; - - INIT_LIST_HEAD(&flow->flowchain); - } - } - if (sch->limit >= 1) - sch->flags |= TCQ_F_CAN_BYPASS; - else - sch->flags &= ~TCQ_F_CAN_BYPASS; - return 0; -} - -static int fq_codel_dump(struct Qdisc *sch, struct sk_buff *skb) -{ - struct fq_codel_sched_data *q = qdisc_priv(sch); - struct nlattr *opts; - - opts = nla_nest_start(skb, TCA_OPTIONS); - if (opts == NULL) - goto nla_put_failure; - - if (nla_put_u32(skb, TCA_FQ_CODEL_TARGET, - codel_time_to_us(q->cparams.target)) || - nla_put_u32(skb, TCA_FQ_CODEL_LIMIT, - sch->limit) || - nla_put_u32(skb, TCA_FQ_CODEL_INTERVAL, - codel_time_to_us(q->cparams.interval)) || - nla_put_u32(skb, TCA_FQ_CODEL_ECN, - q->cparams.ecn) || - nla_put_u32(skb, TCA_FQ_CODEL_QUANTUM, - q->quantum) || - nla_put_u32(skb, TCA_FQ_CODEL_FLOWS, - q->flows_cnt)) - goto nla_put_failure; - - nla_nest_end(skb, opts); - return skb->len; - -nla_put_failure: - return -1; -} - -static int fq_codel_dump_stats(struct Qdisc *sch, struct gnet_dump *d) -{ - struct fq_codel_sched_data *q = qdisc_priv(sch); - struct tc_fq_codel_xstats st = { - .type = TCA_FQ_CODEL_XSTATS_QDISC, - }; - struct list_head *pos; - - st.qdisc_stats.maxpacket = q->cstats.maxpacket; - st.qdisc_stats.drop_overlimit = q->drop_overlimit; - st.qdisc_stats.ecn_mark = q->cstats.ecn_mark; - st.qdisc_stats.new_flow_count = q->new_flow_count; - - list_for_each(pos, &q->new_flows) - st.qdisc_stats.new_flows_len++; - - list_for_each(pos, &q->old_flows) - st.qdisc_stats.old_flows_len++; - - return gnet_stats_copy_app(d, &st, sizeof(st)); -} - -static struct Qdisc *fq_codel_leaf(struct Qdisc *sch, unsigned long arg) -{ - return NULL; -} - -static unsigned long fq_codel_get(struct Qdisc *sch, u32 classid) -{ - return 0; -} - -static unsigned long fq_codel_bind(struct Qdisc *sch, unsigned long parent, - u32 classid) -{ - /* we cannot bypass queue discipline anymore */ - sch->flags &= ~TCQ_F_CAN_BYPASS; - return 0; -} - -static void fq_codel_put(struct Qdisc *q, unsigned long cl) -{ -} - -static struct tcf_proto **fq_codel_find_tcf(struct Qdisc *sch, unsigned long cl) -{ - struct fq_codel_sched_data *q = qdisc_priv(sch); - - if (cl) - return NULL; - return &q->filter_list; -} - -static int fq_codel_dump_class(struct Qdisc *sch, unsigned long cl, - struct sk_buff *skb, struct tcmsg *tcm) -{ - tcm->tcm_handle |= TC_H_MIN(cl); - return 0; -} - -static int fq_codel_dump_class_stats(struct Qdisc *sch, unsigned long cl, - struct gnet_dump *d) -{ - struct fq_codel_sched_data *q = qdisc_priv(sch); - u32 idx = cl - 1; - struct gnet_stats_queue qs = { 0 }; - struct tc_fq_codel_xstats xstats; - - if (idx < q->flows_cnt) { - const struct fq_codel_flow *flow = &q->flows[idx]; - const struct sk_buff *skb = flow->head; - - memset(&xstats, 0, sizeof(xstats)); - xstats.type = TCA_FQ_CODEL_XSTATS_CLASS; - xstats.class_stats.deficit = flow->deficit; - xstats.class_stats.ldelay = - codel_time_to_us(flow->cvars.ldelay); - xstats.class_stats.count = flow->cvars.count; - xstats.class_stats.lastcount = flow->cvars.lastcount; - xstats.class_stats.dropping = flow->cvars.dropping; - if (flow->cvars.dropping) { - codel_tdiff_t delta = flow->cvars.drop_next - - codel_get_time(); - - xstats.class_stats.drop_next = (delta >= 0) ? - codel_time_to_us(delta) : - -codel_time_to_us(-delta); - } - while (skb) { - qs.qlen++; - skb = skb->next; - } - qs.backlog = q->backlogs[idx]; - qs.drops = flow->dropped; - } - if (gnet_stats_copy_queue(d, &qs) < 0) - return -1; - if (idx < q->flows_cnt) - return gnet_stats_copy_app(d, &xstats, sizeof(xstats)); - return 0; -} - -static void fq_codel_walk(struct Qdisc *sch, struct qdisc_walker *arg) -{ - struct fq_codel_sched_data *q = qdisc_priv(sch); - unsigned int i; - - if (arg->stop) - return; - - for (i = 0; i < q->flows_cnt; i++) { - if (list_empty(&q->flows[i].flowchain) || - arg->count < arg->skip) { - arg->count++; - continue; - } - if (arg->fn(sch, i + 1, arg) < 0) { - arg->stop = 1; - break; - } - arg->count++; - } -} - -static const struct Qdisc_class_ops fq_codel_class_ops = { - .leaf = fq_codel_leaf, - .get = fq_codel_get, - .put = fq_codel_put, - .tcf_chain = fq_codel_find_tcf, - .bind_tcf = fq_codel_bind, - .unbind_tcf = fq_codel_put, - .dump = fq_codel_dump_class, - .dump_stats = fq_codel_dump_class_stats, - .walk = fq_codel_walk, -}; - -static struct Qdisc_ops fq_codel_qdisc_ops __read_mostly = { - .cl_ops = &fq_codel_class_ops, - .id = "fq_codel", - .priv_size = sizeof(struct fq_codel_sched_data), - .enqueue = fq_codel_enqueue, - .dequeue = fq_codel_dequeue, - .peek = qdisc_peek_dequeued, - .drop = fq_codel_drop, - .init = fq_codel_init, - .reset = fq_codel_reset, - .destroy = fq_codel_destroy, - .change = fq_codel_change, - .dump = fq_codel_dump, - .dump_stats = fq_codel_dump_stats, - .owner = THIS_MODULE, -}; - -static int __init fq_codel_module_init(void) -{ - return register_qdisc(&fq_codel_qdisc_ops); -} - -static void __exit fq_codel_module_exit(void) -{ - unregister_qdisc(&fq_codel_qdisc_ops); -} - -module_init(fq_codel_module_init) -module_exit(fq_codel_module_exit) -MODULE_AUTHOR("Eric Dumazet"); -MODULE_LICENSE("GPL"); diff --git a/trunk/net/sched/sch_generic.c b/trunk/net/sched/sch_generic.c index 511323e89cec..0eb1202c22a6 100644 --- a/trunk/net/sched/sch_generic.c +++ b/trunk/net/sched/sch_generic.c @@ -86,8 +86,9 @@ static inline int handle_dev_cpu_collision(struct sk_buff *skb, * deadloop is detected. Return OK to try the next skb. */ kfree_skb(skb); - net_warn_ratelimited("Dead loop on netdevice %s, fix it urgently!\n", - dev_queue->dev->name); + if (net_ratelimit()) + pr_warning("Dead loop on netdevice %s, fix it urgently!\n", + dev_queue->dev->name); ret = qdisc_qlen(q); } else { /* @@ -135,9 +136,9 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, ret = handle_dev_cpu_collision(skb, txq, q); } else { /* Driver returned NETDEV_TX_BUSY - requeue skb */ - if (unlikely(ret != NETDEV_TX_BUSY)) - net_warn_ratelimited("BUG %s code %d qlen %d\n", - dev->name, ret, q->q.qlen); + if (unlikely (ret != NETDEV_TX_BUSY && net_ratelimit())) + pr_warning("BUG %s code %d qlen %d\n", + dev->name, ret, q->q.qlen); ret = dev_requeue_skb(skb, q); } diff --git a/trunk/net/sched/sch_gred.c b/trunk/net/sched/sch_gred.c index e901583e4ea5..ab620bf90785 100644 --- a/trunk/net/sched/sch_gred.c +++ b/trunk/net/sched/sch_gred.c @@ -255,8 +255,10 @@ static struct sk_buff *gred_dequeue(struct Qdisc *sch) u16 dp = tc_index_to_dp(skb); if (dp >= t->DPs || (q = t->tab[dp]) == NULL) { - net_warn_ratelimited("GRED: Unable to relocate VQ 0x%x after dequeue, screwing up backlog\n", - tc_index_to_dp(skb)); + if (net_ratelimit()) + pr_warning("GRED: Unable to relocate VQ 0x%x " + "after dequeue, screwing up " + "backlog.\n", tc_index_to_dp(skb)); } else { q->backlog -= qdisc_pkt_len(skb); @@ -285,8 +287,10 @@ static unsigned int gred_drop(struct Qdisc *sch) u16 dp = tc_index_to_dp(skb); if (dp >= t->DPs || (q = t->tab[dp]) == NULL) { - net_warn_ratelimited("GRED: Unable to relocate VQ 0x%x while dropping, screwing up backlog\n", - tc_index_to_dp(skb)); + if (net_ratelimit()) + pr_warning("GRED: Unable to relocate VQ 0x%x " + "while dropping, screwing up " + "backlog.\n", tc_index_to_dp(skb)); } else { q->backlog -= len; q->stats.other++; diff --git a/trunk/net/sched/sch_hfsc.c b/trunk/net/sched/sch_hfsc.c index 6c2ec4510540..8db3e2c72827 100644 --- a/trunk/net/sched/sch_hfsc.c +++ b/trunk/net/sched/sch_hfsc.c @@ -1609,6 +1609,7 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch) if (cl->qdisc->q.qlen == 1) set_active(cl, qdisc_pkt_len(skb)); + bstats_update(&cl->bstats, skb); sch->q.qlen++; return NET_XMIT_SUCCESS; @@ -1656,7 +1657,6 @@ hfsc_dequeue(struct Qdisc *sch) return NULL; } - bstats_update(&cl->bstats, skb); update_vf(cl, qdisc_pkt_len(skb), cur_time); if (realtime) cl->cl_cumul += qdisc_pkt_len(skb); diff --git a/trunk/net/sched/sch_htb.c b/trunk/net/sched/sch_htb.c index 9d75b7761313..acae5b0e3849 100644 --- a/trunk/net/sched/sch_htb.c +++ b/trunk/net/sched/sch_htb.c @@ -574,6 +574,7 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch) } return ret; } else { + bstats_update(&cl->bstats, skb); htb_activate(q, cl); } @@ -834,7 +835,6 @@ static struct sk_buff *htb_dequeue_tree(struct htb_sched *q, int prio, } while (cl != start); if (likely(skb != NULL)) { - bstats_update(&cl->bstats, skb); cl->un.leaf.deficit[level] -= qdisc_pkt_len(skb); if (cl->un.leaf.deficit[level] < 0) { cl->un.leaf.deficit[level] += cl->quantum; diff --git a/trunk/net/sctp/output.c b/trunk/net/sctp/output.c index f1b7d4bb591e..69534c5f8afa 100644 --- a/trunk/net/sctp/output.c +++ b/trunk/net/sctp/output.c @@ -377,7 +377,9 @@ int sctp_packet_transmit(struct sctp_packet *packet) */ skb_set_owner_w(nskb, sk); - if (!sctp_transport_dst_check(tp)) { + /* The 'obsolete' field of dst is set to 2 when a dst is freed. */ + if (!dst || (dst->obsolete > 1)) { + dst_release(dst); sctp_transport_route(tp, NULL, sctp_sk(sk)); if (asoc && (asoc->param_flags & SPP_PMTUD_ENABLE)) { sctp_assoc_sync_pmtu(asoc); diff --git a/trunk/net/sctp/sm_sideeffect.c b/trunk/net/sctp/sm_sideeffect.c index c96d1a81cf42..fbb374c65945 100644 --- a/trunk/net/sctp/sm_sideeffect.c +++ b/trunk/net/sctp/sm_sideeffect.c @@ -1161,8 +1161,9 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype, break; case SCTP_DISPOSITION_VIOLATION: - net_err_ratelimited("protocol violation state %d chunkid %d\n", - state, subtype.chunk); + if (net_ratelimit()) + pr_err("protocol violation state %d chunkid %d\n", + state, subtype.chunk); break; case SCTP_DISPOSITION_NOT_IMPL: diff --git a/trunk/net/sctp/sm_statefuns.c b/trunk/net/sctp/sm_statefuns.c index 9fca10357350..a147b4d307d2 100644 --- a/trunk/net/sctp/sm_statefuns.c +++ b/trunk/net/sctp/sm_statefuns.c @@ -1129,15 +1129,17 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep, /* This should never happen, but lets log it if so. */ if (unlikely(!link)) { if (from_addr.sa.sa_family == AF_INET6) { - net_warn_ratelimited("%s association %p could not find address %pI6\n", - __func__, - asoc, - &from_addr.v6.sin6_addr); + if (net_ratelimit()) + pr_warn("%s association %p could not find address %pI6\n", + __func__, + asoc, + &from_addr.v6.sin6_addr); } else { - net_warn_ratelimited("%s association %p could not find address %pI4\n", - __func__, - asoc, - &from_addr.v4.sin_addr.s_addr); + if (net_ratelimit()) + pr_warn("%s association %p could not find address %pI4\n", + __func__, + asoc, + &from_addr.v4.sin_addr.s_addr); } return SCTP_DISPOSITION_DISCARD; } diff --git a/trunk/net/sctp/socket.c b/trunk/net/sctp/socket.c index b3b8a8d813eb..92ba71dfe080 100644 --- a/trunk/net/sctp/socket.c +++ b/trunk/net/sctp/socket.c @@ -5840,8 +5840,10 @@ SCTP_STATIC int sctp_listen_start(struct sock *sk, int backlog) if (!sctp_sk(sk)->hmac && sctp_hmac_alg) { tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm)) { - net_info_ratelimited("failed to load transform for %s: %ld\n", - sctp_hmac_alg, PTR_ERR(tfm)); + if (net_ratelimit()) { + pr_info("failed to load transform for %s: %ld\n", + sctp_hmac_alg, PTR_ERR(tfm)); + } return -ENOSYS; } sctp_sk(sk)->hmac = tfm; diff --git a/trunk/net/sctp/transport.c b/trunk/net/sctp/transport.c index b026ba0c6992..3889330b7b04 100644 --- a/trunk/net/sctp/transport.c +++ b/trunk/net/sctp/transport.c @@ -226,6 +226,23 @@ void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk) transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; } +/* this is a complete rip-off from __sk_dst_check + * the cookie is always 0 since this is how it's used in the + * pmtu code + */ +static struct dst_entry *sctp_transport_dst_check(struct sctp_transport *t) +{ + struct dst_entry *dst = t->dst; + + if (dst && dst->obsolete && dst->ops->check(dst, 0) == NULL) { + dst_release(t->dst); + t->dst = NULL; + return NULL; + } + + return dst; +} + void sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu) { struct dst_entry *dst; diff --git a/trunk/net/socket.c b/trunk/net/socket.c index 2a2898ce596e..d3aaa4f67a3b 100644 --- a/trunk/net/socket.c +++ b/trunk/net/socket.c @@ -1234,7 +1234,8 @@ int __sock_create(struct net *net, int family, int type, int protocol, */ sock = sock_alloc(); if (!sock) { - net_warn_ratelimited("socket: no more sockets\n"); + if (net_ratelimit()) + printk(KERN_WARNING "socket: no more sockets\n"); return -ENFILE; /* Not exactly a match, but its the closest posix thing */ } diff --git a/trunk/net/sunrpc/auth_gss/gss_mech_switch.c b/trunk/net/sunrpc/auth_gss/gss_mech_switch.c index 782bfe1b6465..ca8cad8251c7 100644 --- a/trunk/net/sunrpc/auth_gss/gss_mech_switch.c +++ b/trunk/net/sunrpc/auth_gss/gss_mech_switch.c @@ -242,13 +242,12 @@ EXPORT_SYMBOL_GPL(gss_mech_get_by_pseudoflavor); int gss_mech_list_pseudoflavors(rpc_authflavor_t *array_ptr) { struct gss_api_mech *pos = NULL; - int j, i = 0; + int i = 0; spin_lock(®istered_mechs_lock); list_for_each_entry(pos, ®istered_mechs, gm_list) { - for (j=0; j < pos->gm_pf_num; j++) { - array_ptr[i++] = pos->gm_pfs[j].pseudoflavor; - } + array_ptr[i] = pos->gm_pfs->pseudoflavor; + i++; } spin_unlock(®istered_mechs_lock); return i; diff --git a/trunk/net/sunrpc/clnt.c b/trunk/net/sunrpc/clnt.c index 7fee13b331d1..adf2990acebf 100644 --- a/trunk/net/sunrpc/clnt.c +++ b/trunk/net/sunrpc/clnt.c @@ -127,7 +127,9 @@ static struct dentry *rpc_setup_pipedir_sb(struct super_block *sb, { static uint32_t clntid; char name[15]; - struct qstr q = { .name = name }; + struct qstr q = { + .name = name, + }; struct dentry *dir, *dentry; int error; diff --git a/trunk/net/sunrpc/rpc_pipe.c b/trunk/net/sunrpc/rpc_pipe.c index fd2423991c2d..3b62cf288031 100644 --- a/trunk/net/sunrpc/rpc_pipe.c +++ b/trunk/net/sunrpc/rpc_pipe.c @@ -1059,9 +1059,12 @@ static const struct rpc_filelist files[] = { struct dentry *rpc_d_lookup_sb(const struct super_block *sb, const unsigned char *dir_name) { - struct qstr dir = QSTR_INIT(dir_name, strlen(dir_name)); + struct qstr dir = { + .name = dir_name, + .len = strlen(dir_name), + .hash = full_name_hash(dir_name, strlen(dir_name)), + }; - dir.hash = full_name_hash(dir.name, dir.len); return d_lookup(sb->s_root, &dir); } EXPORT_SYMBOL_GPL(rpc_d_lookup_sb); diff --git a/trunk/net/sunrpc/svc.c b/trunk/net/sunrpc/svc.c index 017c0117d154..4153846984ac 100644 --- a/trunk/net/sunrpc/svc.c +++ b/trunk/net/sunrpc/svc.c @@ -1041,21 +1041,23 @@ static void svc_unregister(const struct svc_serv *serv, struct net *net) * Printk the given error with the address of the client that caused it. */ static __printf(2, 3) -void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) +int svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) { - struct va_format vaf; va_list args; + int r; char buf[RPC_MAX_ADDRBUFLEN]; - va_start(args, fmt); - - vaf.fmt = fmt; - vaf.va = &args; + if (!net_ratelimit()) + return 0; - net_warn_ratelimited("svc: %s: %pV", - svc_print_addr(rqstp, buf, sizeof(buf)), &vaf); + printk(KERN_WARNING "svc: %s: ", + svc_print_addr(rqstp, buf, sizeof(buf))); + va_start(args, fmt); + r = vprintk(fmt, args); va_end(args); + + return r; } /* diff --git a/trunk/net/sunrpc/svc_xprt.c b/trunk/net/sunrpc/svc_xprt.c index b98ee3514912..4bda09d7e1a4 100644 --- a/trunk/net/sunrpc/svc_xprt.c +++ b/trunk/net/sunrpc/svc_xprt.c @@ -544,11 +544,14 @@ static void svc_check_conn_limits(struct svc_serv *serv) struct svc_xprt *xprt = NULL; spin_lock_bh(&serv->sv_lock); if (!list_empty(&serv->sv_tempsocks)) { - /* Try to help the admin */ - net_notice_ratelimited("%s: too many open connections, consider increasing the %s\n", - serv->sv_name, serv->sv_maxconn ? - "max number of connections" : - "number of threads"); + if (net_ratelimit()) { + /* Try to help the admin */ + printk(KERN_NOTICE "%s: too many open " + "connections, consider increasing %s\n", + serv->sv_name, serv->sv_maxconn ? + "the max number of connections." : + "the number of threads."); + } /* * Always select the oldest connection. It's not fair, * but so is life diff --git a/trunk/net/sunrpc/svcsock.c b/trunk/net/sunrpc/svcsock.c index a6de09de5d21..f0132b2e875e 100644 --- a/trunk/net/sunrpc/svcsock.c +++ b/trunk/net/sunrpc/svcsock.c @@ -617,8 +617,11 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) rqstp->rq_prot = IPPROTO_UDP; if (!svc_udp_get_dest_address(rqstp, cmh)) { - net_warn_ratelimited("svc: received unknown control message %d/%d; dropping RPC reply datagram\n", - cmh->cmsg_level, cmh->cmsg_type); + if (net_ratelimit()) + printk(KERN_WARNING + "svc: received unknown control message %d/%d; " + "dropping RPC reply datagram\n", + cmh->cmsg_level, cmh->cmsg_type); skb_free_datagram_locked(svsk->sk_sk, skb); return 0; } @@ -868,17 +871,18 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt) if (err == -ENOMEM) printk(KERN_WARNING "%s: no more sockets!\n", serv->sv_name); - else if (err != -EAGAIN) - net_warn_ratelimited("%s: accept failed (err %d)!\n", - serv->sv_name, -err); + else if (err != -EAGAIN && net_ratelimit()) + printk(KERN_WARNING "%s: accept failed (err %d)!\n", + serv->sv_name, -err); return NULL; } set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags); err = kernel_getpeername(newsock, sin, &slen); if (err < 0) { - net_warn_ratelimited("%s: peername failed (err %d)!\n", - serv->sv_name, -err); + if (net_ratelimit()) + printk(KERN_WARNING "%s: peername failed (err %d)!\n", + serv->sv_name, -err); goto failed; /* aborted connection or whatever */ } @@ -1008,15 +1012,19 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) * bit set in the fragment length header. * But apparently no known nfs clients send fragmented * records. */ - net_notice_ratelimited("RPC: multiple fragments per record not supported\n"); + if (net_ratelimit()) + printk(KERN_NOTICE "RPC: multiple fragments " + "per record not supported\n"); goto err_delete; } svsk->sk_reclen &= RPC_FRAGMENT_SIZE_MASK; dprintk("svc: TCP record, %d bytes\n", svsk->sk_reclen); if (svsk->sk_reclen > serv->sv_max_mesg) { - net_notice_ratelimited("RPC: fragment too large: 0x%08lx\n", - (unsigned long)svsk->sk_reclen); + if (net_ratelimit()) + printk(KERN_NOTICE "RPC: " + "fragment too large: 0x%08lx\n", + (unsigned long)svsk->sk_reclen); goto err_delete; } } diff --git a/trunk/net/sysctl_net.c b/trunk/net/sysctl_net.c index e3a6e37cd1c5..f3e813a8d107 100644 --- a/trunk/net/sysctl_net.c +++ b/trunk/net/sysctl_net.c @@ -26,6 +26,10 @@ #include #endif +#ifdef CONFIG_TR +#include +#endif + static struct ctl_table_set * net_ctl_header_lookup(struct ctl_table_root *root, struct nsproxy *namespaces) { diff --git a/trunk/net/wireless/ibss.c b/trunk/net/wireless/ibss.c index d2a19b0ff71f..30f20fe4a5fe 100644 --- a/trunk/net/wireless/ibss.c +++ b/trunk/net/wireless/ibss.c @@ -473,7 +473,7 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev, /* fixed already - and no change */ if (wdev->wext.ibss.bssid && bssid && - ether_addr_equal(bssid, wdev->wext.ibss.bssid)) + compare_ether_addr(bssid, wdev->wext.ibss.bssid) == 0) return 0; wdev_lock(wdev); diff --git a/trunk/net/wireless/lib80211_crypt_ccmp.c b/trunk/net/wireless/lib80211_crypt_ccmp.c index 1526c211db66..755738d26bb4 100644 --- a/trunk/net/wireless/lib80211_crypt_ccmp.c +++ b/trunk/net/wireless/lib80211_crypt_ccmp.c @@ -304,8 +304,10 @@ static int lib80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) pos = skb->data + hdr_len; keyidx = pos[3]; if (!(keyidx & (1 << 5))) { - net_dbg_ratelimited("CCMP: received packet without ExtIV flag from %pM\n", - hdr->addr2); + if (net_ratelimit()) { + printk(KERN_DEBUG "CCMP: received packet without ExtIV" + " flag from %pM\n", hdr->addr2); + } key->dot11RSNAStatsCCMPFormatErrors++; return -2; } @@ -316,8 +318,11 @@ static int lib80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) return -6; } if (!key->key_set) { - net_dbg_ratelimited("CCMP: received packet from %pM with keyid=%d that does not have a configured key\n", - hdr->addr2, keyidx); + if (net_ratelimit()) { + printk(KERN_DEBUG "CCMP: received packet from %pM" + " with keyid=%d that does not have a configured" + " key\n", hdr->addr2, keyidx); + } return -3; } @@ -331,11 +336,15 @@ static int lib80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (ccmp_replay_check(pn, key->rx_pn)) { #ifdef CONFIG_LIB80211_DEBUG - net_dbg_ratelimited("CCMP: replay detected: STA=%pM previous PN %02x%02x%02x%02x%02x%02x received PN %02x%02x%02x%02x%02x%02x\n", - hdr->addr2, - key->rx_pn[0], key->rx_pn[1], key->rx_pn[2], - key->rx_pn[3], key->rx_pn[4], key->rx_pn[5], - pn[0], pn[1], pn[2], pn[3], pn[4], pn[5]); + if (net_ratelimit()) { + printk(KERN_DEBUG "CCMP: replay detected: STA=%pM " + "previous PN %02x%02x%02x%02x%02x%02x " + "received PN %02x%02x%02x%02x%02x%02x\n", + hdr->addr2, + key->rx_pn[0], key->rx_pn[1], key->rx_pn[2], + key->rx_pn[3], key->rx_pn[4], key->rx_pn[5], + pn[0], pn[1], pn[2], pn[3], pn[4], pn[5]); + } #endif key->dot11RSNAStatsCCMPReplays++; return -4; @@ -361,8 +370,10 @@ static int lib80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) } if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { - net_dbg_ratelimited("CCMP: decrypt failed: STA=%pM\n", - hdr->addr2); + if (net_ratelimit()) { + printk(KERN_DEBUG "CCMP: decrypt failed: STA=" + "%pM\n", hdr->addr2); + } key->dot11RSNAStatsCCMPDecryptErrors++; return -5; } diff --git a/trunk/net/wireless/lib80211_crypt_tkip.c b/trunk/net/wireless/lib80211_crypt_tkip.c index d475cfc8568f..38734846c19e 100644 --- a/trunk/net/wireless/lib80211_crypt_tkip.c +++ b/trunk/net/wireless/lib80211_crypt_tkip.c @@ -360,9 +360,12 @@ static int lib80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) struct scatterlist sg; if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - net_dbg_ratelimited("TKIP countermeasures: dropped TX packet to %pM\n", - hdr->addr1); + if (net_ratelimit()) { + struct ieee80211_hdr *hdr = + (struct ieee80211_hdr *)skb->data; + printk(KERN_DEBUG ": TKIP countermeasures: dropped " + "TX packet to %pM\n", hdr->addr1); + } return -1; } @@ -417,8 +420,10 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) hdr = (struct ieee80211_hdr *)skb->data; if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) { - net_dbg_ratelimited("TKIP countermeasures: dropped received packet from %pM\n", - hdr->addr2); + if (net_ratelimit()) { + printk(KERN_DEBUG ": TKIP countermeasures: dropped " + "received packet from %pM\n", hdr->addr2); + } return -1; } @@ -428,8 +433,10 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) pos = skb->data + hdr_len; keyidx = pos[3]; if (!(keyidx & (1 << 5))) { - net_dbg_ratelimited("TKIP: received packet without ExtIV flag from %pM\n", - hdr->addr2); + if (net_ratelimit()) { + printk(KERN_DEBUG "TKIP: received packet without ExtIV" + " flag from %pM\n", hdr->addr2); + } return -2; } keyidx >>= 6; @@ -439,8 +446,11 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) return -6; } if (!tkey->key_set) { - net_dbg_ratelimited("TKIP: received packet from %pM with keyid=%d that does not have a configured key\n", - hdr->addr2, keyidx); + if (net_ratelimit()) { + printk(KERN_DEBUG "TKIP: received packet from %pM" + " with keyid=%d that does not have a configured" + " key\n", hdr->addr2, keyidx); + } return -3; } iv16 = (pos[0] << 8) | pos[2]; @@ -449,9 +459,12 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) { #ifdef CONFIG_LIB80211_DEBUG - net_dbg_ratelimited("TKIP: replay detected: STA=%pM previous TSC %08x%04x received TSC %08x%04x\n", - hdr->addr2, tkey->rx_iv32, tkey->rx_iv16, - iv32, iv16); + if (net_ratelimit()) { + printk(KERN_DEBUG "TKIP: replay detected: STA=%pM" + " previous TSC %08x%04x received TSC " + "%08x%04x\n", hdr->addr2, + tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); + } #endif tkey->dot11RSNAStatsTKIPReplays++; return -4; @@ -468,8 +481,11 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16); sg_init_one(&sg, pos, plen + 4); if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) { - net_dbg_ratelimited("TKIP: failed to decrypt received packet from %pM\n", - hdr->addr2); + if (net_ratelimit()) { + printk(KERN_DEBUG ": TKIP: failed to decrypt " + "received packet from %pM\n", + hdr->addr2); + } return -7; } @@ -485,8 +501,10 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) tkey->rx_phase1_done = 0; } #ifdef CONFIG_LIB80211_DEBUG - net_dbg_ratelimited("TKIP: ICV error detected: STA=%pM\n", - hdr->addr2); + if (net_ratelimit()) { + printk(KERN_DEBUG "TKIP: ICV error detected: STA=" + "%pM\n", hdr->addr2); + } #endif tkey->dot11RSNAStatsTKIPICVErrors++; return -5; diff --git a/trunk/net/wireless/mlme.c b/trunk/net/wireless/mlme.c index eb90988bbd36..6801d96bc224 100644 --- a/trunk/net/wireless/mlme.c +++ b/trunk/net/wireless/mlme.c @@ -101,7 +101,7 @@ void __cfg80211_send_deauth(struct net_device *dev, ASSERT_WDEV_LOCK(wdev); if (wdev->current_bss && - ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { + compare_ether_addr(wdev->current_bss->pub.bssid, bssid) == 0) { cfg80211_unhold_bss(wdev->current_bss); cfg80211_put_bss(&wdev->current_bss->pub); wdev->current_bss = NULL; @@ -116,7 +116,7 @@ void __cfg80211_send_deauth(struct net_device *dev, reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); - from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr); + from_ap = compare_ether_addr(mgmt->sa, dev->dev_addr) != 0; __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap); } else if (wdev->sme_state == CFG80211_SME_CONNECTING) { __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0, @@ -155,7 +155,7 @@ void __cfg80211_send_disassoc(struct net_device *dev, return; if (wdev->current_bss && - ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { + compare_ether_addr(wdev->current_bss->pub.bssid, bssid) == 0) { cfg80211_sme_disassoc(dev, wdev->current_bss); cfg80211_unhold_bss(wdev->current_bss); cfg80211_put_bss(&wdev->current_bss->pub); @@ -166,7 +166,7 @@ void __cfg80211_send_disassoc(struct net_device *dev, reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); - from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr); + from_ap = compare_ether_addr(mgmt->sa, dev->dev_addr) != 0; __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap); } EXPORT_SYMBOL(__cfg80211_send_disassoc); @@ -286,7 +286,7 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, return -EINVAL; if (wdev->current_bss && - ether_addr_equal(bssid, wdev->current_bss->pub.bssid)) + compare_ether_addr(bssid, wdev->current_bss->pub.bssid) == 0) return -EALREADY; memset(&req, 0, sizeof(req)); @@ -363,7 +363,7 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, memset(&req, 0, sizeof(req)); if (wdev->current_bss && prev_bssid && - ether_addr_equal(wdev->current_bss->pub.bssid, prev_bssid)) { + compare_ether_addr(wdev->current_bss->pub.bssid, prev_bssid) == 0) { /* * Trying to reassociate: Allow this to proceed and let the old * association to be dropped when the new one is completed. @@ -447,7 +447,8 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, if (local_state_change) { if (wdev->current_bss && - ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { + compare_ether_addr(wdev->current_bss->pub.bssid, bssid) + == 0) { cfg80211_unhold_bss(wdev->current_bss); cfg80211_put_bss(&wdev->current_bss->pub); wdev->current_bss = NULL; @@ -496,7 +497,7 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, req.local_state_change = local_state_change; req.ie = ie; req.ie_len = ie_len; - if (ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) + if (compare_ether_addr(wdev->current_bss->pub.bssid, bssid) == 0) req.bss = &wdev->current_bss->pub; else return -ENOTCONN; @@ -759,8 +760,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, break; } - if (!ether_addr_equal(wdev->current_bss->pub.bssid, - mgmt->bssid)) { + if (compare_ether_addr(wdev->current_bss->pub.bssid, + mgmt->bssid)) { err = -ENOTCONN; break; } @@ -773,8 +774,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, break; /* for station, check that DA is the AP */ - if (!ether_addr_equal(wdev->current_bss->pub.bssid, - mgmt->da)) { + if (compare_ether_addr(wdev->current_bss->pub.bssid, + mgmt->da)) { err = -ENOTCONN; break; } @@ -782,11 +783,11 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, case NL80211_IFTYPE_AP: case NL80211_IFTYPE_P2P_GO: case NL80211_IFTYPE_AP_VLAN: - if (!ether_addr_equal(mgmt->bssid, dev->dev_addr)) + if (compare_ether_addr(mgmt->bssid, dev->dev_addr)) err = -EINVAL; break; case NL80211_IFTYPE_MESH_POINT: - if (!ether_addr_equal(mgmt->sa, mgmt->bssid)) { + if (compare_ether_addr(mgmt->sa, mgmt->bssid)) { err = -EINVAL; break; } @@ -805,7 +806,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, return err; } - if (!ether_addr_equal(mgmt->sa, dev->dev_addr)) + if (compare_ether_addr(mgmt->sa, dev->dev_addr) != 0) return -EINVAL; /* Transmit the Action frame as requested by user space */ diff --git a/trunk/net/wireless/scan.c b/trunk/net/wireless/scan.c index af2b1caa37fa..9dee87c0358c 100644 --- a/trunk/net/wireless/scan.c +++ b/trunk/net/wireless/scan.c @@ -281,7 +281,7 @@ static bool is_bss(struct cfg80211_bss *a, { const u8 *ssidie; - if (bssid && !ether_addr_equal(a->bssid, bssid)) + if (bssid && compare_ether_addr(a->bssid, bssid)) return false; if (!ssid) diff --git a/trunk/net/wireless/util.c b/trunk/net/wireless/util.c index 1cd255892a43..6cba00173a2f 100644 --- a/trunk/net/wireless/util.c +++ b/trunk/net/wireless/util.c @@ -370,7 +370,7 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, iftype != NL80211_IFTYPE_P2P_CLIENT && iftype != NL80211_IFTYPE_MESH_POINT) || (is_multicast_ether_addr(dst) && - ether_addr_equal(src, addr))) + !compare_ether_addr(src, addr))) return -1; if (iftype == NL80211_IFTYPE_MESH_POINT) { struct ieee80211s_hdr *meshdr = @@ -398,9 +398,9 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, payload = skb->data + hdrlen; ethertype = (payload[6] << 8) | payload[7]; - if (likely((ether_addr_equal(payload, rfc1042_header) && + if (likely((compare_ether_addr(payload, rfc1042_header) == 0 && ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || - ether_addr_equal(payload, bridge_tunnel_header))) { + compare_ether_addr(payload, bridge_tunnel_header) == 0)) { /* remove RFC1042 or Bridge-Tunnel encapsulation and * replace EtherType */ skb_pull(skb, hdrlen + 6); @@ -609,9 +609,10 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, payload = frame->data; ethertype = (payload[6] << 8) | payload[7]; - if (likely((ether_addr_equal(payload, rfc1042_header) && + if (likely((compare_ether_addr(payload, rfc1042_header) == 0 && ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || - ether_addr_equal(payload, bridge_tunnel_header))) { + compare_ether_addr(payload, + bridge_tunnel_header) == 0)) { /* remove RFC1042 or Bridge-Tunnel * encapsulation and replace EtherType */ skb_pull(frame, 6); diff --git a/trunk/net/wireless/wext-sme.c b/trunk/net/wireless/wext-sme.c index 7decbd357d51..7c01c2f3b6cf 100644 --- a/trunk/net/wireless/wext-sme.c +++ b/trunk/net/wireless/wext-sme.c @@ -276,7 +276,7 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev, /* fixed already - and no change */ if (wdev->wext.connect.bssid && bssid && - ether_addr_equal(bssid, wdev->wext.connect.bssid)) + compare_ether_addr(bssid, wdev->wext.connect.bssid) == 0) goto out; err = __cfg80211_disconnect(rdev, dev, diff --git a/trunk/net/wireless/wext-spy.c b/trunk/net/wireless/wext-spy.c index 33bef22e44e9..5d643a548feb 100644 --- a/trunk/net/wireless/wext-spy.c +++ b/trunk/net/wireless/wext-spy.c @@ -203,7 +203,7 @@ void wireless_spy_update(struct net_device * dev, /* Update all records that match */ for (i = 0; i < spydata->spy_number; i++) - if (ether_addr_equal(address, spydata->spy_address[i])) { + if (!compare_ether_addr(address, spydata->spy_address[i])) { memcpy(&(spydata->spy_stat[i]), wstats, sizeof(struct iw_quality)); match = i; diff --git a/trunk/net/xfrm/Kconfig b/trunk/net/xfrm/Kconfig index ce90b8d92365..6d081674515f 100644 --- a/trunk/net/xfrm/Kconfig +++ b/trunk/net/xfrm/Kconfig @@ -3,17 +3,12 @@ # config XFRM bool + select CRYPTO depends on NET -config XFRM_ALGO - tristate - select XFRM - select CRYPTO - config XFRM_USER tristate "Transformation user configuration interface" - depends on INET - select XFRM_ALGO + depends on INET && XFRM ---help--- Support for Transformation(XFRM) user configuration interface like IPsec used by native Linux tools. @@ -53,13 +48,13 @@ config XFRM_STATISTICS config XFRM_IPCOMP tristate - select XFRM_ALGO + select XFRM select CRYPTO select CRYPTO_DEFLATE config NET_KEY tristate "PF_KEY sockets" - select XFRM_ALGO + select XFRM ---help--- PF_KEYv2 socket family, compatible to KAME ones. They are required if you are going to use IPsec tools ported diff --git a/trunk/net/xfrm/Makefile b/trunk/net/xfrm/Makefile index c0e961983f17..aa429eefe919 100644 --- a/trunk/net/xfrm/Makefile +++ b/trunk/net/xfrm/Makefile @@ -3,9 +3,8 @@ # obj-$(CONFIG_XFRM) := xfrm_policy.o xfrm_state.o xfrm_hash.o \ - xfrm_input.o xfrm_output.o \ + xfrm_input.o xfrm_output.o xfrm_algo.o \ xfrm_sysctl.o xfrm_replay.o obj-$(CONFIG_XFRM_STATISTICS) += xfrm_proc.o -obj-$(CONFIG_XFRM_ALGO) += xfrm_algo.o obj-$(CONFIG_XFRM_USER) += xfrm_user.o obj-$(CONFIG_XFRM_IPCOMP) += xfrm_ipcomp.o diff --git a/trunk/net/xfrm/xfrm_algo.c b/trunk/net/xfrm/xfrm_algo.c index 4ce2d93162c1..791ab2e77f3f 100644 --- a/trunk/net/xfrm/xfrm_algo.c +++ b/trunk/net/xfrm/xfrm_algo.c @@ -15,6 +15,9 @@ #include #include #include +#if defined(CONFIG_INET_AH) || defined(CONFIG_INET_AH_MODULE) || defined(CONFIG_INET6_AH) || defined(CONFIG_INET6_AH_MODULE) +#include +#endif #if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE) #include #endif @@ -749,5 +752,3 @@ void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len) } EXPORT_SYMBOL_GPL(pskb_put); #endif - -MODULE_LICENSE("GPL"); diff --git a/trunk/net/xfrm/xfrm_policy.c b/trunk/net/xfrm/xfrm_policy.c index c53e8f42aa75..7661576b6f45 100644 --- a/trunk/net/xfrm/xfrm_policy.c +++ b/trunk/net/xfrm/xfrm_policy.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #ifdef CONFIG_XFRM_STATISTICS @@ -57,7 +56,7 @@ static int xfrm_bundle_ok(struct xfrm_dst *xdst); static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol, int dir); -static inline bool +static inline int __xfrm4_selector_match(const struct xfrm_selector *sel, const struct flowi *fl) { const struct flowi4 *fl4 = &fl->u.ip4; @@ -70,7 +69,7 @@ __xfrm4_selector_match(const struct xfrm_selector *sel, const struct flowi *fl) (fl4->flowi4_oif == sel->ifindex || !sel->ifindex); } -static inline bool +static inline int __xfrm6_selector_match(const struct xfrm_selector *sel, const struct flowi *fl) { const struct flowi6 *fl6 = &fl->u.ip6; @@ -83,8 +82,8 @@ __xfrm6_selector_match(const struct xfrm_selector *sel, const struct flowi *fl) (fl6->flowi6_oif == sel->ifindex || !sel->ifindex); } -bool xfrm_selector_match(const struct xfrm_selector *sel, const struct flowi *fl, - unsigned short family) +int xfrm_selector_match(const struct xfrm_selector *sel, const struct flowi *fl, + unsigned short family) { switch (family) { case AF_INET: @@ -92,7 +91,7 @@ bool xfrm_selector_match(const struct xfrm_selector *sel, const struct flowi *fl case AF_INET6: return __xfrm6_selector_match(sel, fl); } - return false; + return 0; } static inline struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, @@ -878,8 +877,7 @@ static int xfrm_policy_match(const struct xfrm_policy *pol, u8 type, u16 family, int dir) { const struct xfrm_selector *sel = &pol->selector; - int ret = -ESRCH; - bool match; + int match, ret = -ESRCH; if (pol->family != family || (fl->flowi_mark & pol->mark.m) != pol->mark.v || @@ -1008,8 +1006,8 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, read_lock_bh(&xfrm_policy_lock); if ((pol = sk->sk_policy[dir]) != NULL) { - bool match = xfrm_selector_match(&pol->selector, fl, - sk->sk_family); + int match = xfrm_selector_match(&pol->selector, fl, + sk->sk_family); int err = 0; if (match) { @@ -2769,8 +2767,8 @@ EXPORT_SYMBOL_GPL(xfrm_audit_policy_delete); #endif #ifdef CONFIG_XFRM_MIGRATE -static bool xfrm_migrate_selector_match(const struct xfrm_selector *sel_cmp, - const struct xfrm_selector *sel_tgt) +static int xfrm_migrate_selector_match(const struct xfrm_selector *sel_cmp, + const struct xfrm_selector *sel_tgt) { if (sel_cmp->proto == IPSEC_ULPROTO_ANY) { if (sel_tgt->family == sel_cmp->family && @@ -2780,14 +2778,14 @@ static bool xfrm_migrate_selector_match(const struct xfrm_selector *sel_cmp, sel_cmp->family) == 0 && sel_tgt->prefixlen_d == sel_cmp->prefixlen_d && sel_tgt->prefixlen_s == sel_cmp->prefixlen_s) { - return true; + return 1; } } else { if (memcmp(sel_tgt, sel_cmp, sizeof(*sel_tgt)) == 0) { - return true; + return 1; } } - return false; + return 0; } static struct xfrm_policy * xfrm_migrate_policy_find(const struct xfrm_selector *sel, diff --git a/trunk/samples/Makefile b/trunk/samples/Makefile index 5ef08bba96ce..2f75851ec629 100644 --- a/trunk/samples/Makefile +++ b/trunk/samples/Makefile @@ -1,4 +1,4 @@ # Makefile for Linux samples code obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \ - hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/ + hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ diff --git a/trunk/samples/seccomp/Makefile b/trunk/samples/seccomp/Makefile deleted file mode 100644 index 16aa2d424985..000000000000 --- a/trunk/samples/seccomp/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -# kbuild trick to avoid linker error. Can be omitted if a module is built. -obj- := dummy.o - -hostprogs-$(CONFIG_SECCOMP_FILTER) := bpf-fancy dropper bpf-direct - -HOSTCFLAGS_bpf-fancy.o += -I$(objtree)/usr/include -HOSTCFLAGS_bpf-fancy.o += -idirafter $(objtree)/include -HOSTCFLAGS_bpf-helper.o += -I$(objtree)/usr/include -HOSTCFLAGS_bpf-helper.o += -idirafter $(objtree)/include -bpf-fancy-objs := bpf-fancy.o bpf-helper.o - -HOSTCFLAGS_dropper.o += -I$(objtree)/usr/include -HOSTCFLAGS_dropper.o += -idirafter $(objtree)/include -dropper-objs := dropper.o - -HOSTCFLAGS_bpf-direct.o += -I$(objtree)/usr/include -HOSTCFLAGS_bpf-direct.o += -idirafter $(objtree)/include -bpf-direct-objs := bpf-direct.o - -# Try to match the kernel target. -ifeq ($(CONFIG_64BIT),) -HOSTCFLAGS_bpf-direct.o += -m32 -HOSTCFLAGS_dropper.o += -m32 -HOSTCFLAGS_bpf-helper.o += -m32 -HOSTCFLAGS_bpf-fancy.o += -m32 -HOSTLOADLIBES_bpf-direct += -m32 -HOSTLOADLIBES_bpf-fancy += -m32 -HOSTLOADLIBES_dropper += -m32 -endif - -# Tell kbuild to always build the programs -always := $(hostprogs-y) diff --git a/trunk/samples/seccomp/bpf-direct.c b/trunk/samples/seccomp/bpf-direct.c deleted file mode 100644 index 151ec3f52189..000000000000 --- a/trunk/samples/seccomp/bpf-direct.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Seccomp filter example for x86 (32-bit and 64-bit) with BPF macros - * - * Copyright (c) 2012 The Chromium OS Authors - * Author: Will Drewry - * - * The code may be used by anyone for any purpose, - * and can serve as a starting point for developing - * applications using prctl(PR_SET_SECCOMP, 2, ...). - */ -#if defined(__i386__) || defined(__x86_64__) -#define SUPPORTED_ARCH 1 -#endif - -#if defined(SUPPORTED_ARCH) -#define __USE_GNU 1 -#define _GNU_SOURCE 1 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define syscall_arg(_n) (offsetof(struct seccomp_data, args[_n])) -#define syscall_nr (offsetof(struct seccomp_data, nr)) - -#if defined(__i386__) -#define REG_RESULT REG_EAX -#define REG_SYSCALL REG_EAX -#define REG_ARG0 REG_EBX -#define REG_ARG1 REG_ECX -#define REG_ARG2 REG_EDX -#define REG_ARG3 REG_ESI -#define REG_ARG4 REG_EDI -#define REG_ARG5 REG_EBP -#elif defined(__x86_64__) -#define REG_RESULT REG_RAX -#define REG_SYSCALL REG_RAX -#define REG_ARG0 REG_RDI -#define REG_ARG1 REG_RSI -#define REG_ARG2 REG_RDX -#define REG_ARG3 REG_R10 -#define REG_ARG4 REG_R8 -#define REG_ARG5 REG_R9 -#endif - -#ifndef PR_SET_NO_NEW_PRIVS -#define PR_SET_NO_NEW_PRIVS 38 -#endif - -#ifndef SYS_SECCOMP -#define SYS_SECCOMP 1 -#endif - -static void emulator(int nr, siginfo_t *info, void *void_context) -{ - ucontext_t *ctx = (ucontext_t *)(void_context); - int syscall; - char *buf; - ssize_t bytes; - size_t len; - if (info->si_code != SYS_SECCOMP) - return; - if (!ctx) - return; - syscall = ctx->uc_mcontext.gregs[REG_SYSCALL]; - buf = (char *) ctx->uc_mcontext.gregs[REG_ARG1]; - len = (size_t) ctx->uc_mcontext.gregs[REG_ARG2]; - - if (syscall != __NR_write) - return; - if (ctx->uc_mcontext.gregs[REG_ARG0] != STDERR_FILENO) - return; - /* Redirect stderr messages to stdout. Doesn't handle EINTR, etc */ - ctx->uc_mcontext.gregs[REG_RESULT] = -1; - if (write(STDOUT_FILENO, "[ERR] ", 6) > 0) { - bytes = write(STDOUT_FILENO, buf, len); - ctx->uc_mcontext.gregs[REG_RESULT] = bytes; - } - return; -} - -static int install_emulator(void) -{ - struct sigaction act; - sigset_t mask; - memset(&act, 0, sizeof(act)); - sigemptyset(&mask); - sigaddset(&mask, SIGSYS); - - act.sa_sigaction = &emulator; - act.sa_flags = SA_SIGINFO; - if (sigaction(SIGSYS, &act, NULL) < 0) { - perror("sigaction"); - return -1; - } - if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) { - perror("sigprocmask"); - return -1; - } - return 0; -} - -static int install_filter(void) -{ - struct sock_filter filter[] = { - /* Grab the system call number */ - BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_nr), - /* Jump table for the allowed syscalls */ - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_rt_sigreturn, 0, 1), - BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), -#ifdef __NR_sigreturn - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_sigreturn, 0, 1), - BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), -#endif - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_exit_group, 0, 1), - BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_exit, 0, 1), - BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_read, 1, 0), - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_write, 3, 2), - - /* Check that read is only using stdin. */ - BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_arg(0)), - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, STDIN_FILENO, 4, 0), - BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL), - - /* Check that write is only using stdout */ - BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_arg(0)), - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, STDOUT_FILENO, 1, 0), - /* Trap attempts to write to stderr */ - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, STDERR_FILENO, 1, 2), - - BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), - BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP), - BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL), - }; - struct sock_fprog prog = { - .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])), - .filter = filter, - }; - - if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { - perror("prctl(NO_NEW_PRIVS)"); - return 1; - } - - - if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) { - perror("prctl"); - return 1; - } - return 0; -} - -#define payload(_c) (_c), sizeof((_c)) -int main(int argc, char **argv) -{ - char buf[4096]; - ssize_t bytes = 0; - if (install_emulator()) - return 1; - if (install_filter()) - return 1; - syscall(__NR_write, STDOUT_FILENO, - payload("OHAI! WHAT IS YOUR NAME? ")); - bytes = syscall(__NR_read, STDIN_FILENO, buf, sizeof(buf)); - syscall(__NR_write, STDOUT_FILENO, payload("HELLO, ")); - syscall(__NR_write, STDOUT_FILENO, buf, bytes); - syscall(__NR_write, STDERR_FILENO, - payload("Error message going to STDERR\n")); - return 0; -} -#else /* SUPPORTED_ARCH */ -/* - * This sample is x86-only. Since kernel samples are compiled with the - * host toolchain, a non-x86 host will result in using only the main() - * below. - */ -int main(void) -{ - return 1; -} -#endif /* SUPPORTED_ARCH */ diff --git a/trunk/samples/seccomp/bpf-fancy.c b/trunk/samples/seccomp/bpf-fancy.c deleted file mode 100644 index 8eb483aaec46..000000000000 --- a/trunk/samples/seccomp/bpf-fancy.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Seccomp BPF example using a macro-based generator. - * - * Copyright (c) 2012 The Chromium OS Authors - * Author: Will Drewry - * - * The code may be used by anyone for any purpose, - * and can serve as a starting point for developing - * applications using prctl(PR_ATTACH_SECCOMP_FILTER). - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "bpf-helper.h" - -#ifndef PR_SET_NO_NEW_PRIVS -#define PR_SET_NO_NEW_PRIVS 38 -#endif - -int main(int argc, char **argv) -{ - struct bpf_labels l; - static const char msg1[] = "Please type something: "; - static const char msg2[] = "You typed: "; - char buf[256]; - struct sock_filter filter[] = { - /* TODO: LOAD_SYSCALL_NR(arch) and enforce an arch */ - LOAD_SYSCALL_NR, - SYSCALL(__NR_exit, ALLOW), - SYSCALL(__NR_exit_group, ALLOW), - SYSCALL(__NR_write, JUMP(&l, write_fd)), - SYSCALL(__NR_read, JUMP(&l, read)), - DENY, /* Don't passthrough into a label */ - - LABEL(&l, read), - ARG(0), - JNE(STDIN_FILENO, DENY), - ARG(1), - JNE((unsigned long)buf, DENY), - ARG(2), - JGE(sizeof(buf), DENY), - ALLOW, - - LABEL(&l, write_fd), - ARG(0), - JEQ(STDOUT_FILENO, JUMP(&l, write_buf)), - JEQ(STDERR_FILENO, JUMP(&l, write_buf)), - DENY, - - LABEL(&l, write_buf), - ARG(1), - JEQ((unsigned long)msg1, JUMP(&l, msg1_len)), - JEQ((unsigned long)msg2, JUMP(&l, msg2_len)), - JEQ((unsigned long)buf, JUMP(&l, buf_len)), - DENY, - - LABEL(&l, msg1_len), - ARG(2), - JLT(sizeof(msg1), ALLOW), - DENY, - - LABEL(&l, msg2_len), - ARG(2), - JLT(sizeof(msg2), ALLOW), - DENY, - - LABEL(&l, buf_len), - ARG(2), - JLT(sizeof(buf), ALLOW), - DENY, - }; - struct sock_fprog prog = { - .filter = filter, - .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])), - }; - ssize_t bytes; - bpf_resolve_jumps(&l, filter, sizeof(filter)/sizeof(*filter)); - - if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { - perror("prctl(NO_NEW_PRIVS)"); - return 1; - } - - if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) { - perror("prctl(SECCOMP)"); - return 1; - } - syscall(__NR_write, STDOUT_FILENO, msg1, strlen(msg1)); - bytes = syscall(__NR_read, STDIN_FILENO, buf, sizeof(buf)-1); - bytes = (bytes > 0 ? bytes : 0); - syscall(__NR_write, STDERR_FILENO, msg2, strlen(msg2)); - syscall(__NR_write, STDERR_FILENO, buf, bytes); - /* Now get killed */ - syscall(__NR_write, STDERR_FILENO, msg2, strlen(msg2)+2); - return 0; -} diff --git a/trunk/samples/seccomp/bpf-helper.c b/trunk/samples/seccomp/bpf-helper.c deleted file mode 100644 index 579cfe331886..000000000000 --- a/trunk/samples/seccomp/bpf-helper.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Seccomp BPF helper functions - * - * Copyright (c) 2012 The Chromium OS Authors - * Author: Will Drewry - * - * The code may be used by anyone for any purpose, - * and can serve as a starting point for developing - * applications using prctl(PR_ATTACH_SECCOMP_FILTER). - */ - -#include -#include - -#include "bpf-helper.h" - -int bpf_resolve_jumps(struct bpf_labels *labels, - struct sock_filter *filter, size_t count) -{ - struct sock_filter *begin = filter; - __u8 insn = count - 1; - - if (count < 1) - return -1; - /* - * Walk it once, backwards, to build the label table and do fixups. - * Since backward jumps are disallowed by BPF, this is easy. - */ - filter += insn; - for (; filter >= begin; --insn, --filter) { - if (filter->code != (BPF_JMP+BPF_JA)) - continue; - switch ((filter->jt<<8)|filter->jf) { - case (JUMP_JT<<8)|JUMP_JF: - if (labels->labels[filter->k].location == 0xffffffff) { - fprintf(stderr, "Unresolved label: '%s'\n", - labels->labels[filter->k].label); - return 1; - } - filter->k = labels->labels[filter->k].location - - (insn + 1); - filter->jt = 0; - filter->jf = 0; - continue; - case (LABEL_JT<<8)|LABEL_JF: - if (labels->labels[filter->k].location != 0xffffffff) { - fprintf(stderr, "Duplicate label use: '%s'\n", - labels->labels[filter->k].label); - return 1; - } - labels->labels[filter->k].location = insn; - filter->k = 0; /* fall through */ - filter->jt = 0; - filter->jf = 0; - continue; - } - } - return 0; -} - -/* Simple lookup table for labels. */ -__u32 seccomp_bpf_label(struct bpf_labels *labels, const char *label) -{ - struct __bpf_label *begin = labels->labels, *end; - int id; - if (labels->count == 0) { - begin->label = label; - begin->location = 0xffffffff; - labels->count++; - return 0; - } - end = begin + labels->count; - for (id = 0; begin < end; ++begin, ++id) { - if (!strcmp(label, begin->label)) - return id; - } - begin->label = label; - begin->location = 0xffffffff; - labels->count++; - return id; -} - -void seccomp_bpf_print(struct sock_filter *filter, size_t count) -{ - struct sock_filter *end = filter + count; - for ( ; filter < end; ++filter) - printf("{ code=%u,jt=%u,jf=%u,k=%u },\n", - filter->code, filter->jt, filter->jf, filter->k); -} diff --git a/trunk/samples/seccomp/bpf-helper.h b/trunk/samples/seccomp/bpf-helper.h deleted file mode 100644 index 643279dd30fb..000000000000 --- a/trunk/samples/seccomp/bpf-helper.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Example wrapper around BPF macros. - * - * Copyright (c) 2012 The Chromium OS Authors - * Author: Will Drewry - * - * The code may be used by anyone for any purpose, - * and can serve as a starting point for developing - * applications using prctl(PR_SET_SECCOMP, 2, ...). - * - * No guarantees are provided with respect to the correctness - * or functionality of this code. - */ -#ifndef __BPF_HELPER_H__ -#define __BPF_HELPER_H__ - -#include /* for __BITS_PER_LONG */ -#include -#include -#include /* for seccomp_data */ -#include -#include -#include - -#define BPF_LABELS_MAX 256 -struct bpf_labels { - int count; - struct __bpf_label { - const char *label; - __u32 location; - } labels[BPF_LABELS_MAX]; -}; - -int bpf_resolve_jumps(struct bpf_labels *labels, - struct sock_filter *filter, size_t count); -__u32 seccomp_bpf_label(struct bpf_labels *labels, const char *label); -void seccomp_bpf_print(struct sock_filter *filter, size_t count); - -#define JUMP_JT 0xff -#define JUMP_JF 0xff -#define LABEL_JT 0xfe -#define LABEL_JF 0xfe - -#define ALLOW \ - BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) -#define DENY \ - BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL) -#define JUMP(labels, label) \ - BPF_JUMP(BPF_JMP+BPF_JA, FIND_LABEL((labels), (label)), \ - JUMP_JT, JUMP_JF) -#define LABEL(labels, label) \ - BPF_JUMP(BPF_JMP+BPF_JA, FIND_LABEL((labels), (label)), \ - LABEL_JT, LABEL_JF) -#define SYSCALL(nr, jt) \ - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (nr), 0, 1), \ - jt - -/* Lame, but just an example */ -#define FIND_LABEL(labels, label) seccomp_bpf_label((labels), #label) - -#define EXPAND(...) __VA_ARGS__ -/* Map all width-sensitive operations */ -#if __BITS_PER_LONG == 32 - -#define JEQ(x, jt) JEQ32(x, EXPAND(jt)) -#define JNE(x, jt) JNE32(x, EXPAND(jt)) -#define JGT(x, jt) JGT32(x, EXPAND(jt)) -#define JLT(x, jt) JLT32(x, EXPAND(jt)) -#define JGE(x, jt) JGE32(x, EXPAND(jt)) -#define JLE(x, jt) JLE32(x, EXPAND(jt)) -#define JA(x, jt) JA32(x, EXPAND(jt)) -#define ARG(i) ARG_32(i) -#define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)]) - -#elif __BITS_PER_LONG == 64 - -/* Ensure that we load the logically correct offset. */ -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define ENDIAN(_lo, _hi) _lo, _hi -#define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)]) -#define HI_ARG(idx) offsetof(struct seccomp_data, args[(idx)]) + sizeof(__u32) -#elif __BYTE_ORDER == __BIG_ENDIAN -#define ENDIAN(_lo, _hi) _hi, _lo -#define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)]) + sizeof(__u32) -#define HI_ARG(idx) offsetof(struct seccomp_data, args[(idx)]) -#else -#error "Unknown endianness" -#endif - -union arg64 { - struct { - __u32 ENDIAN(lo32, hi32); - }; - __u64 u64; -}; - -#define JEQ(x, jt) \ - JEQ64(((union arg64){.u64 = (x)}).lo32, \ - ((union arg64){.u64 = (x)}).hi32, \ - EXPAND(jt)) -#define JGT(x, jt) \ - JGT64(((union arg64){.u64 = (x)}).lo32, \ - ((union arg64){.u64 = (x)}).hi32, \ - EXPAND(jt)) -#define JGE(x, jt) \ - JGE64(((union arg64){.u64 = (x)}).lo32, \ - ((union arg64){.u64 = (x)}).hi32, \ - EXPAND(jt)) -#define JNE(x, jt) \ - JNE64(((union arg64){.u64 = (x)}).lo32, \ - ((union arg64){.u64 = (x)}).hi32, \ - EXPAND(jt)) -#define JLT(x, jt) \ - JLT64(((union arg64){.u64 = (x)}).lo32, \ - ((union arg64){.u64 = (x)}).hi32, \ - EXPAND(jt)) -#define JLE(x, jt) \ - JLE64(((union arg64){.u64 = (x)}).lo32, \ - ((union arg64){.u64 = (x)}).hi32, \ - EXPAND(jt)) - -#define JA(x, jt) \ - JA64(((union arg64){.u64 = (x)}).lo32, \ - ((union arg64){.u64 = (x)}).hi32, \ - EXPAND(jt)) -#define ARG(i) ARG_64(i) - -#else -#error __BITS_PER_LONG value unusable. -#endif - -/* Loads the arg into A */ -#define ARG_32(idx) \ - BPF_STMT(BPF_LD+BPF_W+BPF_ABS, LO_ARG(idx)) - -/* Loads hi into A and lo in X */ -#define ARG_64(idx) \ - BPF_STMT(BPF_LD+BPF_W+BPF_ABS, LO_ARG(idx)), \ - BPF_STMT(BPF_ST, 0), /* lo -> M[0] */ \ - BPF_STMT(BPF_LD+BPF_W+BPF_ABS, HI_ARG(idx)), \ - BPF_STMT(BPF_ST, 1) /* hi -> M[1] */ - -#define JEQ32(value, jt) \ - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (value), 0, 1), \ - jt - -#define JNE32(value, jt) \ - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (value), 1, 0), \ - jt - -/* Checks the lo, then swaps to check the hi. A=lo,X=hi */ -#define JEQ64(lo, hi, jt) \ - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \ - BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \ - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (lo), 0, 2), \ - BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \ - jt, \ - BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */ - -#define JNE64(lo, hi, jt) \ - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 5, 0), \ - BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \ - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (lo), 2, 0), \ - BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \ - jt, \ - BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */ - -#define JA32(value, jt) \ - BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (value), 0, 1), \ - jt - -#define JA64(lo, hi, jt) \ - BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (hi), 3, 0), \ - BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \ - BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (lo), 0, 2), \ - BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \ - jt, \ - BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */ - -#define JGE32(value, jt) \ - BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 0, 1), \ - jt - -#define JLT32(value, jt) \ - BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 1, 0), \ - jt - -/* Shortcut checking if hi > arg.hi. */ -#define JGE64(lo, hi, jt) \ - BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 4, 0), \ - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \ - BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \ - BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (lo), 0, 2), \ - BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \ - jt, \ - BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */ - -#define JLT64(lo, hi, jt) \ - BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (hi), 0, 4), \ - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \ - BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \ - BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 2, 0), \ - BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \ - jt, \ - BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */ - -#define JGT32(value, jt) \ - BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 0, 1), \ - jt - -#define JLE32(value, jt) \ - BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 1, 0), \ - jt - -/* Check hi > args.hi first, then do the GE checking */ -#define JGT64(lo, hi, jt) \ - BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 4, 0), \ - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \ - BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \ - BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 0, 2), \ - BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \ - jt, \ - BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */ - -#define JLE64(lo, hi, jt) \ - BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 6, 0), \ - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 3), \ - BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \ - BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 2, 0), \ - BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \ - jt, \ - BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */ - -#define LOAD_SYSCALL_NR \ - BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ - offsetof(struct seccomp_data, nr)) - -#endif /* __BPF_HELPER_H__ */ diff --git a/trunk/samples/seccomp/dropper.c b/trunk/samples/seccomp/dropper.c deleted file mode 100644 index c69c347c7011..000000000000 --- a/trunk/samples/seccomp/dropper.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Naive system call dropper built on seccomp_filter. - * - * Copyright (c) 2012 The Chromium OS Authors - * Author: Will Drewry - * - * The code may be used by anyone for any purpose, - * and can serve as a starting point for developing - * applications using prctl(PR_SET_SECCOMP, 2, ...). - * - * When run, returns the specified errno for the specified - * system call number against the given architecture. - * - * Run this one as root as PR_SET_NO_NEW_PRIVS is not called. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int install_filter(int nr, int arch, int error) -{ - struct sock_filter filter[] = { - BPF_STMT(BPF_LD+BPF_W+BPF_ABS, - (offsetof(struct seccomp_data, arch))), - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, arch, 0, 3), - BPF_STMT(BPF_LD+BPF_W+BPF_ABS, - (offsetof(struct seccomp_data, nr))), - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, nr, 0, 1), - BPF_STMT(BPF_RET+BPF_K, - SECCOMP_RET_ERRNO|(error & SECCOMP_RET_DATA)), - BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), - }; - struct sock_fprog prog = { - .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])), - .filter = filter, - }; - if (prctl(PR_SET_SECCOMP, 2, &prog)) { - perror("prctl"); - return 1; - } - return 0; -} - -int main(int argc, char **argv) -{ - if (argc < 5) { - fprintf(stderr, "Usage:\n" - "dropper []\n" - "Hint: AUDIT_ARCH_I386: 0x%X\n" - " AUDIT_ARCH_X86_64: 0x%X\n" - "\n", AUDIT_ARCH_I386, AUDIT_ARCH_X86_64); - return 1; - } - if (install_filter(strtol(argv[1], NULL, 0), strtol(argv[2], NULL, 0), - strtol(argv[3], NULL, 0))) - return 1; - execv(argv[4], &argv[4]); - printf("Failed to execv\n"); - return 255; -} diff --git a/trunk/scripts/Makefile b/trunk/scripts/Makefile index 36266665dbcb..df7678febf27 100644 --- a/trunk/scripts/Makefile +++ b/trunk/scripts/Makefile @@ -8,8 +8,6 @@ # conmakehash: Create arrays for initializing the kernel console tables # docproc: Used in Documentation/DocBook -HOST_EXTRACFLAGS += -I$(srctree)/tools/include - hostprogs-$(CONFIG_KALLSYMS) += kallsyms hostprogs-$(CONFIG_LOGO) += pnmtologo hostprogs-$(CONFIG_VT) += conmakehash diff --git a/trunk/security/Kconfig b/trunk/security/Kconfig index e9c6ac724fef..ccc61f8006b2 100644 --- a/trunk/security/Kconfig +++ b/trunk/security/Kconfig @@ -4,7 +4,73 @@ menu "Security options" -source security/keys/Kconfig +config KEYS + bool "Enable access key retention support" + help + This option provides support for retaining authentication tokens and + access keys in the kernel. + + It also includes provision of methods by which such keys might be + associated with a process so that network filesystems, encryption + support and the like can find them. + + Furthermore, a special type of key is available that acts as keyring: + a searchable sequence of keys. Each process is equipped with access + to five standard keyrings: UID-specific, GID-specific, session, + process and thread. + + If you are unsure as to whether this is required, answer N. + +config TRUSTED_KEYS + tristate "TRUSTED KEYS" + depends on KEYS && TCG_TPM + select CRYPTO + select CRYPTO_HMAC + select CRYPTO_SHA1 + help + This option provides support for creating, sealing, and unsealing + keys in the kernel. Trusted keys are random number symmetric keys, + generated and RSA-sealed by the TPM. The TPM only unseals the keys, + if the boot PCRs and other criteria match. Userspace will only ever + see encrypted blobs. + + If you are unsure as to whether this is required, answer N. + +config ENCRYPTED_KEYS + tristate "ENCRYPTED KEYS" + depends on KEYS + select CRYPTO + select CRYPTO_HMAC + select CRYPTO_AES + select CRYPTO_CBC + select CRYPTO_SHA256 + select CRYPTO_RNG + help + This option provides support for create/encrypting/decrypting keys + in the kernel. Encrypted keys are kernel generated random numbers, + which are encrypted/decrypted with a 'master' symmetric key. The + 'master' key can be either a trusted-key or user-key type. + Userspace only ever sees/stores encrypted blobs. + + If you are unsure as to whether this is required, answer N. + +config KEYS_DEBUG_PROC_KEYS + bool "Enable the /proc/keys file by which keys may be viewed" + depends on KEYS + help + This option turns on support for the /proc/keys file - through which + can be listed all the keys on the system that are viewable by the + reading process. + + The only keys included in the list are those that grant View + permission to the reading process whether or not it possesses them. + Note that LSM security checks are still performed, and may further + filter out keys that the current process is not authorised to view. + + Only key attributes are listed here; key payloads are not included in + the resulting table. + + If you are unsure as to whether this is required, answer N. config SECURITY_DMESG_RESTRICT bool "Restrict unprivileged access to the kernel syslog" diff --git a/trunk/security/apparmor/audit.c b/trunk/security/apparmor/audit.c index 3ae28db5a64f..cc3520d39a78 100644 --- a/trunk/security/apparmor/audit.c +++ b/trunk/security/apparmor/audit.c @@ -111,7 +111,7 @@ static const char *const aa_audit_type[] = { static void audit_pre(struct audit_buffer *ab, void *ca) { struct common_audit_data *sa = ca; - struct task_struct *tsk = sa->aad->tsk ? sa->aad->tsk : current; + struct task_struct *tsk = sa->tsk ? sa->tsk : current; if (aa_g_audit_header) { audit_log_format(ab, "apparmor="); @@ -149,12 +149,6 @@ static void audit_pre(struct audit_buffer *ab, void *ca) audit_log_format(ab, " name="); audit_log_untrustedstring(ab, sa->aad->name); } - - if (sa->aad->tsk) { - audit_log_format(ab, " pid=%d comm=", tsk->pid); - audit_log_untrustedstring(ab, tsk->comm); - } - } /** @@ -211,8 +205,7 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp, aa_audit_msg(type, sa, cb); if (sa->aad->type == AUDIT_APPARMOR_KILL) - (void)send_sig_info(SIGKILL, NULL, - sa->aad->tsk ? sa->aad->tsk : current); + (void)send_sig_info(SIGKILL, NULL, sa->tsk ? sa->tsk : current); if (sa->aad->type == AUDIT_APPARMOR_ALLOWED) return complain_error(sa->aad->error); diff --git a/trunk/security/apparmor/capability.c b/trunk/security/apparmor/capability.c index 887a5e948945..088dba3bf7dc 100644 --- a/trunk/security/apparmor/capability.c +++ b/trunk/security/apparmor/capability.c @@ -65,10 +65,10 @@ static int audit_caps(struct aa_profile *profile, struct task_struct *task, int type = AUDIT_APPARMOR_AUTO; struct common_audit_data sa; struct apparmor_audit_data aad = {0,}; - sa.type = LSM_AUDIT_DATA_CAP; + COMMON_AUDIT_DATA_INIT(&sa, CAP); sa.aad = &aad; + sa.tsk = task; sa.u.cap = cap; - sa.aad->tsk = task; sa.aad->op = OP_CAPABLE; sa.aad->error = error; diff --git a/trunk/security/apparmor/domain.c b/trunk/security/apparmor/domain.c index b81ea10a17a3..6327685c101e 100644 --- a/trunk/security/apparmor/domain.c +++ b/trunk/security/apparmor/domain.c @@ -394,11 +394,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm) new_profile = find_attach(ns, &ns->base.profiles, name); if (!new_profile) goto cleanup; - /* - * NOTE: Domain transitions from unconfined are allowed - * even when no_new_privs is set because this aways results - * in a further reduction of permissions. - */ goto apply; } @@ -460,16 +455,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm) /* fail exec */ error = -EACCES; - /* - * Policy has specified a domain transition, if no_new_privs then - * fail the exec. - */ - if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) { - aa_put_profile(new_profile); - error = -EPERM; - goto cleanup; - } - if (!new_profile) goto audit; @@ -624,14 +609,6 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest) const char *target = NULL, *info = NULL; int error = 0; - /* - * Fail explicitly requested domain transitions if no_new_privs. - * There is no exception for unconfined as change_hat is not - * available. - */ - if (current->no_new_privs) - return -EPERM; - /* released below */ cred = get_current_cred(); cxt = cred->security; @@ -773,18 +750,6 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec, cxt = cred->security; profile = aa_cred_profile(cred); - /* - * Fail explicitly requested domain transitions if no_new_privs - * and not unconfined. - * Domain transitions from unconfined are allowed even when - * no_new_privs is set because this aways results in a reduction - * of permissions. - */ - if (current->no_new_privs && !unconfined(profile)) { - put_cred(cred); - return -EPERM; - } - if (ns_name) { /* released below */ ns = aa_find_namespace(profile->ns, ns_name); diff --git a/trunk/security/apparmor/file.c b/trunk/security/apparmor/file.c index cf19d4093ca4..2f8fcba9ce4b 100644 --- a/trunk/security/apparmor/file.c +++ b/trunk/security/apparmor/file.c @@ -108,7 +108,7 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, int type = AUDIT_APPARMOR_AUTO; struct common_audit_data sa; struct apparmor_audit_data aad = {0,}; - sa.type = LSM_AUDIT_DATA_NONE; + COMMON_AUDIT_DATA_INIT(&sa, NONE); sa.aad = &aad; aad.op = op, aad.fs.request = request; diff --git a/trunk/security/apparmor/include/audit.h b/trunk/security/apparmor/include/audit.h index 4b7e18951aea..3868b1e5d5ba 100644 --- a/trunk/security/apparmor/include/audit.h +++ b/trunk/security/apparmor/include/audit.h @@ -110,7 +110,6 @@ struct apparmor_audit_data { void *profile; const char *name; const char *info; - struct task_struct *tsk; union { void *target; struct { diff --git a/trunk/security/apparmor/ipc.c b/trunk/security/apparmor/ipc.c index cf1071b14232..c3da93a5150d 100644 --- a/trunk/security/apparmor/ipc.c +++ b/trunk/security/apparmor/ipc.c @@ -42,7 +42,7 @@ static int aa_audit_ptrace(struct aa_profile *profile, { struct common_audit_data sa; struct apparmor_audit_data aad = {0,}; - sa.type = LSM_AUDIT_DATA_NONE; + COMMON_AUDIT_DATA_INIT(&sa, NONE); sa.aad = &aad; aad.op = OP_PTRACE; aad.target = target; diff --git a/trunk/security/apparmor/lib.c b/trunk/security/apparmor/lib.c index 7430298116d6..e75829ba0ff9 100644 --- a/trunk/security/apparmor/lib.c +++ b/trunk/security/apparmor/lib.c @@ -66,7 +66,7 @@ void aa_info_message(const char *str) if (audit_enabled) { struct common_audit_data sa; struct apparmor_audit_data aad = {0,}; - sa.type = LSM_AUDIT_DATA_NONE; + COMMON_AUDIT_DATA_INIT(&sa, NONE); sa.aad = &aad; aad.info = str; aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL); diff --git a/trunk/security/apparmor/lsm.c b/trunk/security/apparmor/lsm.c index 032daab449b0..ad05d391974d 100644 --- a/trunk/security/apparmor/lsm.c +++ b/trunk/security/apparmor/lsm.c @@ -373,7 +373,7 @@ static int apparmor_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) AA_MAY_META_READ); } -static int apparmor_file_open(struct file *file, const struct cred *cred) +static int apparmor_dentry_open(struct file *file, const struct cred *cred) { struct aa_file_cxt *fcxt = file->f_security; struct aa_profile *profile; @@ -589,7 +589,7 @@ static int apparmor_setprocattr(struct task_struct *task, char *name, } else { struct common_audit_data sa; struct apparmor_audit_data aad = {0,}; - sa.type = LSM_AUDIT_DATA_NONE; + COMMON_AUDIT_DATA_INIT(&sa, NONE); sa.aad = &aad; aad.op = OP_SETPROCATTR; aad.info = name; @@ -640,9 +640,9 @@ static struct security_operations apparmor_ops = { .path_chmod = apparmor_path_chmod, .path_chown = apparmor_path_chown, .path_truncate = apparmor_path_truncate, + .dentry_open = apparmor_dentry_open, .inode_getattr = apparmor_inode_getattr, - .file_open = apparmor_file_open, .file_permission = apparmor_file_permission, .file_alloc_security = apparmor_file_alloc_security, .file_free_security = apparmor_file_free_security, diff --git a/trunk/security/apparmor/path.c b/trunk/security/apparmor/path.c index e91ffee80162..2daeea4f9266 100644 --- a/trunk/security/apparmor/path.c +++ b/trunk/security/apparmor/path.c @@ -94,8 +94,6 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, * be returned. */ if (!res || IS_ERR(res)) { - if (PTR_ERR(res) == -ENAMETOOLONG) - return -ENAMETOOLONG; connected = 0; res = dentry_path_raw(path->dentry, buf, buflen); if (IS_ERR(res)) { diff --git a/trunk/security/apparmor/policy.c b/trunk/security/apparmor/policy.c index cf5fd220309b..f1f7506a464d 100644 --- a/trunk/security/apparmor/policy.c +++ b/trunk/security/apparmor/policy.c @@ -903,10 +903,6 @@ struct aa_profile *aa_lookup_profile(struct aa_namespace *ns, const char *hname) profile = aa_get_profile(__lookup_profile(&ns->base, hname)); read_unlock(&ns->lock); - /* the unconfined profile is not in the regular profile list */ - if (!profile && strcmp(hname, "unconfined") == 0) - profile = aa_get_profile(ns->unconfined); - /* refcount released by caller */ return profile; } @@ -969,7 +965,7 @@ static int audit_policy(int op, gfp_t gfp, const char *name, const char *info, { struct common_audit_data sa; struct apparmor_audit_data aad = {0,}; - sa.type = LSM_AUDIT_DATA_NONE; + COMMON_AUDIT_DATA_INIT(&sa, NONE); sa.aad = &aad; aad.op = op; aad.name = name; diff --git a/trunk/security/apparmor/policy_unpack.c b/trunk/security/apparmor/policy_unpack.c index 329b1fd30749..deab7c7e8dc0 100644 --- a/trunk/security/apparmor/policy_unpack.c +++ b/trunk/security/apparmor/policy_unpack.c @@ -95,7 +95,7 @@ static int audit_iface(struct aa_profile *new, const char *name, struct aa_profile *profile = __aa_current_profile(); struct common_audit_data sa; struct apparmor_audit_data aad = {0,}; - sa.type = LSM_AUDIT_DATA_NONE; + COMMON_AUDIT_DATA_INIT(&sa, NONE); sa.aad = &aad; if (e) aad.iface.pos = e->pos - e->start; diff --git a/trunk/security/apparmor/resource.c b/trunk/security/apparmor/resource.c index e1f3d7ef2c54..2fe8613efe33 100644 --- a/trunk/security/apparmor/resource.c +++ b/trunk/security/apparmor/resource.c @@ -52,7 +52,7 @@ static int audit_resource(struct aa_profile *profile, unsigned int resource, struct common_audit_data sa; struct apparmor_audit_data aad = {0,}; - sa.type = LSM_AUDIT_DATA_NONE; + COMMON_AUDIT_DATA_INIT(&sa, NONE); sa.aad = &aad; aad.op = OP_SETRLIMIT, aad.rlim.rlim = resource; diff --git a/trunk/security/capability.c b/trunk/security/capability.c index fca889676c5e..5bb21b1c448c 100644 --- a/trunk/security/capability.c +++ b/trunk/security/capability.c @@ -348,7 +348,7 @@ static int cap_file_receive(struct file *file) return 0; } -static int cap_file_open(struct file *file, const struct cred *cred) +static int cap_dentry_open(struct file *file, const struct cred *cred) { return 0; } @@ -956,7 +956,7 @@ void __init security_fixup_ops(struct security_operations *ops) set_to_cap_if_null(ops, file_set_fowner); set_to_cap_if_null(ops, file_send_sigiotask); set_to_cap_if_null(ops, file_receive); - set_to_cap_if_null(ops, file_open); + set_to_cap_if_null(ops, dentry_open); set_to_cap_if_null(ops, task_create); set_to_cap_if_null(ops, task_free); set_to_cap_if_null(ops, cred_alloc_blank); diff --git a/trunk/security/commoncap.c b/trunk/security/commoncap.c index f80d11609391..71a166a05975 100644 --- a/trunk/security/commoncap.c +++ b/trunk/security/commoncap.c @@ -512,17 +512,14 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) /* Don't let someone trace a set[ug]id/setpcap binary with the revised - * credentials unless they have the appropriate permit. - * - * In addition, if NO_NEW_PRIVS, then ensure we get no new privs. + * credentials unless they have the appropriate permit */ if ((new->euid != old->uid || new->egid != old->gid || !cap_issubset(new->cap_permitted, old->cap_permitted)) && bprm->unsafe & ~LSM_UNSAFE_PTRACE_CAP) { /* downgrade; they get no more than they had, and maybe less */ - if (!capable(CAP_SETUID) || - (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)) { + if (!capable(CAP_SETUID)) { new->euid = new->uid; new->egid = new->gid; } diff --git a/trunk/security/integrity/ima/ima_main.c b/trunk/security/integrity/ima/ima_main.c index b17be79b9cf2..1eff5cb001e5 100644 --- a/trunk/security/integrity/ima/ima_main.c +++ b/trunk/security/integrity/ima/ima_main.c @@ -194,9 +194,7 @@ int ima_bprm_check(struct linux_binprm *bprm) { int rc; - rc = process_measurement(bprm->file, - (strcmp(bprm->filename, bprm->interp) == 0) ? - bprm->filename : bprm->interp, + rc = process_measurement(bprm->file, bprm->filename, MAY_EXEC, BPRM_CHECK); return 0; } diff --git a/trunk/security/keys/Kconfig b/trunk/security/keys/Kconfig deleted file mode 100644 index a90d6d300dbd..000000000000 --- a/trunk/security/keys/Kconfig +++ /dev/null @@ -1,71 +0,0 @@ -# -# Key management configuration -# - -config KEYS - bool "Enable access key retention support" - help - This option provides support for retaining authentication tokens and - access keys in the kernel. - - It also includes provision of methods by which such keys might be - associated with a process so that network filesystems, encryption - support and the like can find them. - - Furthermore, a special type of key is available that acts as keyring: - a searchable sequence of keys. Each process is equipped with access - to five standard keyrings: UID-specific, GID-specific, session, - process and thread. - - If you are unsure as to whether this is required, answer N. - -config TRUSTED_KEYS - tristate "TRUSTED KEYS" - depends on KEYS && TCG_TPM - select CRYPTO - select CRYPTO_HMAC - select CRYPTO_SHA1 - help - This option provides support for creating, sealing, and unsealing - keys in the kernel. Trusted keys are random number symmetric keys, - generated and RSA-sealed by the TPM. The TPM only unseals the keys, - if the boot PCRs and other criteria match. Userspace will only ever - see encrypted blobs. - - If you are unsure as to whether this is required, answer N. - -config ENCRYPTED_KEYS - tristate "ENCRYPTED KEYS" - depends on KEYS - select CRYPTO - select CRYPTO_HMAC - select CRYPTO_AES - select CRYPTO_CBC - select CRYPTO_SHA256 - select CRYPTO_RNG - help - This option provides support for create/encrypting/decrypting keys - in the kernel. Encrypted keys are kernel generated random numbers, - which are encrypted/decrypted with a 'master' symmetric key. The - 'master' key can be either a trusted-key or user-key type. - Userspace only ever sees/stores encrypted blobs. - - If you are unsure as to whether this is required, answer N. - -config KEYS_DEBUG_PROC_KEYS - bool "Enable the /proc/keys file by which keys may be viewed" - depends on KEYS - help - This option turns on support for the /proc/keys file - through which - can be listed all the keys on the system that are viewable by the - reading process. - - The only keys included in the list are those that grant View - permission to the reading process whether or not it possesses them. - Note that LSM security checks are still performed, and may further - filter out keys that the current process is not authorised to view. - - Only key attributes are listed here; key payloads are not included in - the resulting table. - - If you are unsure as to whether this is required, answer N. diff --git a/trunk/security/keys/Makefile b/trunk/security/keys/Makefile index 504aaa008388..a56f1ffdc64d 100644 --- a/trunk/security/keys/Makefile +++ b/trunk/security/keys/Makefile @@ -2,9 +2,6 @@ # Makefile for key management # -# -# Core -# obj-y := \ gc.o \ key.o \ @@ -15,12 +12,9 @@ obj-y := \ request_key.o \ request_key_auth.o \ user_defined.o -obj-$(CONFIG_KEYS_COMPAT) += compat.o -obj-$(CONFIG_PROC_FS) += proc.o -obj-$(CONFIG_SYSCTL) += sysctl.o -# -# Key types -# obj-$(CONFIG_TRUSTED_KEYS) += trusted.o obj-$(CONFIG_ENCRYPTED_KEYS) += encrypted-keys/ +obj-$(CONFIG_KEYS_COMPAT) += compat.o +obj-$(CONFIG_PROC_FS) += proc.o +obj-$(CONFIG_SYSCTL) += sysctl.o diff --git a/trunk/security/keys/compat.c b/trunk/security/keys/compat.c index fab4f8dda6c6..4c48e13448f8 100644 --- a/trunk/security/keys/compat.c +++ b/trunk/security/keys/compat.c @@ -135,9 +135,6 @@ asmlinkage long compat_sys_keyctl(u32 option, return compat_keyctl_instantiate_key_iov( arg2, compat_ptr(arg3), arg4, arg5); - case KEYCTL_INVALIDATE: - return keyctl_invalidate_key(arg2); - default: return -EOPNOTSUPP; } diff --git a/trunk/security/keys/gc.c b/trunk/security/keys/gc.c index 61ab7c82ebb1..a42b45531aac 100644 --- a/trunk/security/keys/gc.c +++ b/trunk/security/keys/gc.c @@ -71,15 +71,6 @@ void key_schedule_gc(time_t gc_at) } } -/* - * Schedule a dead links collection run. - */ -void key_schedule_gc_links(void) -{ - set_bit(KEY_GC_KEY_EXPIRED, &key_gc_flags); - queue_work(system_nrt_wq, &key_gc_work); -} - /* * Some key's cleanup time was met after it expired, so we need to get the * reaper to go through a cycle finding expired keys. @@ -88,7 +79,8 @@ static void key_gc_timer_func(unsigned long data) { kenter(""); key_gc_next_run = LONG_MAX; - key_schedule_gc_links(); + set_bit(KEY_GC_KEY_EXPIRED, &key_gc_flags); + queue_work(system_nrt_wq, &key_gc_work); } /* @@ -139,12 +131,12 @@ void key_gc_keytype(struct key_type *ktype) static void key_gc_keyring(struct key *keyring, time_t limit) { struct keyring_list *klist; + struct key *key; int loop; kenter("%x", key_serial(keyring)); - if (keyring->flags & ((1 << KEY_FLAG_INVALIDATED) | - (1 << KEY_FLAG_REVOKED))) + if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) goto dont_gc; /* scan the keyring looking for dead keys */ @@ -156,8 +148,9 @@ static void key_gc_keyring(struct key *keyring, time_t limit) loop = klist->nkeys; smp_rmb(); for (loop--; loop >= 0; loop--) { - struct key *key = rcu_dereference(klist->keys[loop]); - if (key_is_dead(key, limit)) + key = klist->keys[loop]; + if (test_bit(KEY_FLAG_DEAD, &key->flags) || + (key->expiry > 0 && key->expiry <= limit)) goto do_gc; } @@ -175,45 +168,38 @@ static void key_gc_keyring(struct key *keyring, time_t limit) } /* - * Garbage collect a list of unreferenced, detached keys + * Garbage collect an unreferenced, detached key */ -static noinline void key_gc_unused_keys(struct list_head *keys) +static noinline void key_gc_unused_key(struct key *key) { - while (!list_empty(keys)) { - struct key *key = - list_entry(keys->next, struct key, graveyard_link); - list_del(&key->graveyard_link); - - kdebug("- %u", key->serial); - key_check(key); - - security_key_free(key); - - /* deal with the user's key tracking and quota */ - if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) { - spin_lock(&key->user->lock); - key->user->qnkeys--; - key->user->qnbytes -= key->quotalen; - spin_unlock(&key->user->lock); - } + key_check(key); + + security_key_free(key); + + /* deal with the user's key tracking and quota */ + if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) { + spin_lock(&key->user->lock); + key->user->qnkeys--; + key->user->qnbytes -= key->quotalen; + spin_unlock(&key->user->lock); + } - atomic_dec(&key->user->nkeys); - if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) - atomic_dec(&key->user->nikeys); + atomic_dec(&key->user->nkeys); + if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) + atomic_dec(&key->user->nikeys); - key_user_put(key->user); + key_user_put(key->user); - /* now throw away the key memory */ - if (key->type->destroy) - key->type->destroy(key); + /* now throw away the key memory */ + if (key->type->destroy) + key->type->destroy(key); - kfree(key->description); + kfree(key->description); #ifdef KEY_DEBUGGING - key->magic = KEY_DEBUG_MAGIC_X; + key->magic = KEY_DEBUG_MAGIC_X; #endif - kmem_cache_free(key_jar, key); - } + kmem_cache_free(key_jar, key); } /* @@ -225,7 +211,6 @@ static noinline void key_gc_unused_keys(struct list_head *keys) */ static void key_garbage_collector(struct work_struct *work) { - static LIST_HEAD(graveyard); static u8 gc_state; /* Internal persistent state */ #define KEY_GC_REAP_AGAIN 0x01 /* - Need another cycle */ #define KEY_GC_REAPING_LINKS 0x02 /* - We need to reap links */ @@ -331,22 +316,15 @@ static void key_garbage_collector(struct work_struct *work) key_schedule_gc(new_timer); } - if (unlikely(gc_state & KEY_GC_REAPING_DEAD_2) || - !list_empty(&graveyard)) { - /* Make sure that all pending keyring payload destructions are - * fulfilled and that people aren't now looking at dead or - * dying keys that they don't have a reference upon or a link - * to. + if (unlikely(gc_state & KEY_GC_REAPING_DEAD_2)) { + /* Make sure everyone revalidates their keys if we marked a + * bunch as being dead and make sure all keyring ex-payloads + * are destroyed. */ - kdebug("gc sync"); + kdebug("dead sync"); synchronize_rcu(); } - if (!list_empty(&graveyard)) { - kdebug("gc keys"); - key_gc_unused_keys(&graveyard); - } - if (unlikely(gc_state & (KEY_GC_REAPING_DEAD_1 | KEY_GC_REAPING_DEAD_2))) { if (!(gc_state & KEY_GC_FOUND_DEAD_KEY)) { @@ -381,7 +359,7 @@ static void key_garbage_collector(struct work_struct *work) rb_erase(&key->serial_node, &key_serial_tree); spin_unlock(&key_serial_lock); - list_add_tail(&key->graveyard_link, &graveyard); + key_gc_unused_key(key); gc_state |= KEY_GC_REAP_AGAIN; goto maybe_resched; diff --git a/trunk/security/keys/internal.h b/trunk/security/keys/internal.h index f711b094ed41..65647f825584 100644 --- a/trunk/security/keys/internal.h +++ b/trunk/security/keys/internal.h @@ -152,8 +152,7 @@ extern long join_session_keyring(const char *name); extern struct work_struct key_gc_work; extern unsigned key_gc_delay; extern void keyring_gc(struct key *keyring, time_t limit); -extern void key_schedule_gc(time_t gc_at); -extern void key_schedule_gc_links(void); +extern void key_schedule_gc(time_t expiry_at); extern void key_gc_keytype(struct key_type *ktype); extern int key_task_permission(const key_ref_t key_ref, @@ -197,17 +196,6 @@ extern struct key *request_key_auth_new(struct key *target, extern struct key *key_get_instantiation_authkey(key_serial_t target_id); -/* - * Determine whether a key is dead. - */ -static inline bool key_is_dead(struct key *key, time_t limit) -{ - return - key->flags & ((1 << KEY_FLAG_DEAD) | - (1 << KEY_FLAG_INVALIDATED)) || - (key->expiry > 0 && key->expiry <= limit); -} - /* * keyctl() functions */ @@ -237,7 +225,6 @@ extern long keyctl_reject_key(key_serial_t, unsigned, unsigned, key_serial_t); extern long keyctl_instantiate_key_iov(key_serial_t, const struct iovec __user *, unsigned, key_serial_t); -extern long keyctl_invalidate_key(key_serial_t); extern long keyctl_instantiate_key_common(key_serial_t, const struct iovec __user *, diff --git a/trunk/security/keys/key.c b/trunk/security/keys/key.c index c9bf66ac36e0..06783cffb3af 100644 --- a/trunk/security/keys/key.c +++ b/trunk/security/keys/key.c @@ -954,28 +954,6 @@ void key_revoke(struct key *key) } EXPORT_SYMBOL(key_revoke); -/** - * key_invalidate - Invalidate a key. - * @key: The key to be invalidated. - * - * Mark a key as being invalidated and have it cleaned up immediately. The key - * is ignored by all searches and other operations from this point. - */ -void key_invalidate(struct key *key) -{ - kenter("%d", key_serial(key)); - - key_check(key); - - if (!test_bit(KEY_FLAG_INVALIDATED, &key->flags)) { - down_write_nested(&key->sem, 1); - if (!test_and_set_bit(KEY_FLAG_INVALIDATED, &key->flags)) - key_schedule_gc_links(); - up_write(&key->sem); - } -} -EXPORT_SYMBOL(key_invalidate); - /** * register_key_type - Register a type of key. * @ktype: The new key type. @@ -1002,8 +980,6 @@ int register_key_type(struct key_type *ktype) /* store the type */ list_add(&ktype->link, &key_types_list); - - pr_notice("Key type %s registered\n", ktype->name); ret = 0; out: @@ -1026,7 +1002,6 @@ void unregister_key_type(struct key_type *ktype) list_del_init(&ktype->link); downgrade_write(&key_types_sem); key_gc_keytype(ktype); - pr_notice("Key type %s unregistered\n", ktype->name); up_read(&key_types_sem); } EXPORT_SYMBOL(unregister_key_type); diff --git a/trunk/security/keys/keyctl.c b/trunk/security/keys/keyctl.c index ddb3e05bc5fc..fb767c6cd99f 100644 --- a/trunk/security/keys/keyctl.c +++ b/trunk/security/keys/keyctl.c @@ -374,37 +374,6 @@ long keyctl_revoke_key(key_serial_t id) return ret; } -/* - * Invalidate a key. - * - * The key must be grant the caller Invalidate permission for this to work. - * The key and any links to the key will be automatically garbage collected - * immediately. - * - * If successful, 0 is returned. - */ -long keyctl_invalidate_key(key_serial_t id) -{ - key_ref_t key_ref; - long ret; - - kenter("%d", id); - - key_ref = lookup_user_key(id, 0, KEY_SEARCH); - if (IS_ERR(key_ref)) { - ret = PTR_ERR(key_ref); - goto error; - } - - key_invalidate(key_ref_to_ptr(key_ref)); - ret = 0; - - key_ref_put(key_ref); -error: - kleave(" = %ld", ret); - return ret; -} - /* * Clear the specified keyring, creating an empty process keyring if one of the * special keyring IDs is used. @@ -1653,9 +1622,6 @@ SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3, (unsigned) arg4, (key_serial_t) arg5); - case KEYCTL_INVALIDATE: - return keyctl_invalidate_key((key_serial_t) arg2); - default: return -EOPNOTSUPP; } diff --git a/trunk/security/keys/keyring.c b/trunk/security/keys/keyring.c index 7445875f6818..d605f75292e4 100644 --- a/trunk/security/keys/keyring.c +++ b/trunk/security/keys/keyring.c @@ -25,15 +25,6 @@ (keyring)->payload.subscriptions, \ rwsem_is_locked((struct rw_semaphore *)&(keyring)->sem))) -#define rcu_deref_link_locked(klist, index, keyring) \ - (rcu_dereference_protected( \ - (klist)->keys[index], \ - rwsem_is_locked((struct rw_semaphore *)&(keyring)->sem))) - -#define MAX_KEYRING_LINKS \ - min_t(size_t, USHRT_MAX - 1, \ - ((PAGE_SIZE - sizeof(struct keyring_list)) / sizeof(struct key *))) - #define KEY_LINK_FIXQUOTA 1UL /* @@ -147,11 +138,6 @@ static int keyring_match(const struct key *keyring, const void *description) /* * Clean up a keyring when it is destroyed. Unpublish its name if it had one * and dispose of its data. - * - * The garbage collector detects the final key_put(), removes the keyring from - * the serial number tree and then does RCU synchronisation before coming here, - * so we shouldn't need to worry about code poking around here with the RCU - * readlock held by this time. */ static void keyring_destroy(struct key *keyring) { @@ -168,10 +154,11 @@ static void keyring_destroy(struct key *keyring) write_unlock(&keyring_name_lock); } - klist = rcu_access_pointer(keyring->payload.subscriptions); + klist = rcu_dereference_check(keyring->payload.subscriptions, + atomic_read(&keyring->usage) == 0); if (klist) { for (loop = klist->nkeys - 1; loop >= 0; loop--) - key_put(rcu_access_pointer(klist->keys[loop])); + key_put(klist->keys[loop]); kfree(klist); } } @@ -227,8 +214,7 @@ static long keyring_read(const struct key *keyring, ret = -EFAULT; for (loop = 0; loop < klist->nkeys; loop++) { - key = rcu_deref_link_locked(klist, loop, - keyring); + key = klist->keys[loop]; tmp = sizeof(key_serial_t); if (tmp > buflen) @@ -323,8 +309,6 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref, bool no_state_check) { struct { - /* Need a separate keylist pointer for RCU purposes */ - struct key *keyring; struct keyring_list *keylist; int kix; } stack[KEYRING_SEARCH_MAX_DEPTH]; @@ -382,17 +366,13 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref, /* otherwise, the top keyring must not be revoked, expired, or * negatively instantiated if we are to search it */ key_ref = ERR_PTR(-EAGAIN); - if (kflags & ((1 << KEY_FLAG_INVALIDATED) | - (1 << KEY_FLAG_REVOKED) | - (1 << KEY_FLAG_NEGATIVE)) || + if (kflags & ((1 << KEY_FLAG_REVOKED) | (1 << KEY_FLAG_NEGATIVE)) || (keyring->expiry && now.tv_sec >= keyring->expiry)) goto error_2; /* start processing a new keyring */ descend: - kflags = keyring->flags; - if (kflags & ((1 << KEY_FLAG_INVALIDATED) | - (1 << KEY_FLAG_REVOKED))) + if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) goto not_this_keyring; keylist = rcu_dereference(keyring->payload.subscriptions); @@ -403,17 +383,16 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref, nkeys = keylist->nkeys; smp_rmb(); for (kix = 0; kix < nkeys; kix++) { - key = rcu_dereference(keylist->keys[kix]); + key = keylist->keys[kix]; kflags = key->flags; /* ignore keys not of this type */ if (key->type != type) continue; - /* skip invalidated, revoked and expired keys */ + /* skip revoked keys and expired keys */ if (!no_state_check) { - if (kflags & ((1 << KEY_FLAG_INVALIDATED) | - (1 << KEY_FLAG_REVOKED))) + if (kflags & (1 << KEY_FLAG_REVOKED)) continue; if (key->expiry && now.tv_sec >= key->expiry) @@ -447,7 +426,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref, nkeys = keylist->nkeys; smp_rmb(); for (; kix < nkeys; kix++) { - key = rcu_dereference(keylist->keys[kix]); + key = keylist->keys[kix]; if (key->type != &key_type_keyring) continue; @@ -462,7 +441,6 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref, continue; /* stack the current position */ - stack[sp].keyring = keyring; stack[sp].keylist = keylist; stack[sp].kix = kix; sp++; @@ -478,7 +456,6 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref, if (sp > 0) { /* resume the processing of a keyring higher up in the tree */ sp--; - keyring = stack[sp].keyring; keylist = stack[sp].keylist; kix = stack[sp].kix + 1; goto ascend; @@ -490,10 +467,6 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref, /* we found a viable match */ found: atomic_inc(&key->usage); - key->last_used_at = now.tv_sec; - keyring->last_used_at = now.tv_sec; - while (sp > 0) - stack[--sp].keyring->last_used_at = now.tv_sec; key_check(key); key_ref = make_key_ref(key, possessed); error_2: @@ -558,14 +531,14 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref, nkeys = klist->nkeys; smp_rmb(); for (loop = 0; loop < nkeys ; loop++) { - key = rcu_dereference(klist->keys[loop]); + key = klist->keys[loop]; + if (key->type == ktype && (!key->type->match || key->type->match(key, description)) && key_permission(make_key_ref(key, possessed), perm) == 0 && - !(key->flags & ((1 << KEY_FLAG_INVALIDATED) | - (1 << KEY_FLAG_REVOKED))) + !test_bit(KEY_FLAG_REVOKED, &key->flags) ) goto found; } @@ -576,8 +549,6 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref, found: atomic_inc(&key->usage); - keyring->last_used_at = key->last_used_at = - current_kernel_time().tv_sec; rcu_read_unlock(); return make_key_ref(key, possessed); } @@ -631,7 +602,6 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check) * (ie. it has a zero usage count) */ if (!atomic_inc_not_zero(&keyring->usage)) continue; - keyring->last_used_at = current_kernel_time().tv_sec; goto out; } } @@ -684,7 +654,7 @@ static int keyring_detect_cycle(struct key *A, struct key *B) nkeys = keylist->nkeys; smp_rmb(); for (; kix < nkeys; kix++) { - key = rcu_dereference(keylist->keys[kix]); + key = keylist->keys[kix]; if (key == A) goto cycle_detected; @@ -741,7 +711,7 @@ static void keyring_unlink_rcu_disposal(struct rcu_head *rcu) container_of(rcu, struct keyring_list, rcu); if (klist->delkey != USHRT_MAX) - key_put(rcu_access_pointer(klist->keys[klist->delkey])); + key_put(klist->keys[klist->delkey]); kfree(klist); } @@ -755,9 +725,8 @@ int __key_link_begin(struct key *keyring, const struct key_type *type, struct keyring_list *klist, *nklist; unsigned long prealloc; unsigned max; - time_t lowest_lru; size_t size; - int loop, lru, ret; + int loop, ret; kenter("%d,%s,%s,", key_serial(keyring), type->name, description); @@ -778,39 +747,31 @@ int __key_link_begin(struct key *keyring, const struct key_type *type, klist = rcu_dereference_locked_keyring(keyring); /* see if there's a matching key we can displace */ - lru = -1; if (klist && klist->nkeys > 0) { - lowest_lru = TIME_T_MAX; for (loop = klist->nkeys - 1; loop >= 0; loop--) { - struct key *key = rcu_deref_link_locked(klist, loop, - keyring); - if (key->type == type && - strcmp(key->description, description) == 0) { - /* Found a match - we'll replace the link with - * one to the new key. We record the slot - * position. - */ - klist->delkey = loop; - prealloc = 0; + if (klist->keys[loop]->type == type && + strcmp(klist->keys[loop]->description, + description) == 0 + ) { + /* found a match - we'll replace this one with + * the new key */ + size = sizeof(struct key *) * klist->maxkeys; + size += sizeof(*klist); + BUG_ON(size > PAGE_SIZE); + + ret = -ENOMEM; + nklist = kmemdup(klist, size, GFP_KERNEL); + if (!nklist) + goto error_sem; + + /* note replacement slot */ + klist->delkey = nklist->delkey = loop; + prealloc = (unsigned long)nklist; goto done; } - if (key->last_used_at < lowest_lru) { - lowest_lru = key->last_used_at; - lru = loop; - } } } - /* If the keyring is full then do an LRU discard */ - if (klist && - klist->nkeys == klist->maxkeys && - klist->maxkeys >= MAX_KEYRING_LINKS) { - kdebug("LRU discard %d\n", lru); - klist->delkey = lru; - prealloc = 0; - goto done; - } - /* check that we aren't going to overrun the user's quota */ ret = key_payload_reserve(keyring, keyring->datalen + KEYQUOTA_LINK_BYTES); @@ -819,19 +780,20 @@ int __key_link_begin(struct key *keyring, const struct key_type *type, if (klist && klist->nkeys < klist->maxkeys) { /* there's sufficient slack space to append directly */ - klist->delkey = klist->nkeys; + nklist = NULL; prealloc = KEY_LINK_FIXQUOTA; } else { /* grow the key list */ max = 4; - if (klist) { + if (klist) max += klist->maxkeys; - if (max > MAX_KEYRING_LINKS) - max = MAX_KEYRING_LINKS; - BUG_ON(max <= klist->maxkeys); - } + ret = -ENFILE; + if (max > USHRT_MAX - 1) + goto error_quota; size = sizeof(*klist) + sizeof(struct key *) * max; + if (size > PAGE_SIZE) + goto error_quota; ret = -ENOMEM; nklist = kmalloc(size, GFP_KERNEL); @@ -851,10 +813,10 @@ int __key_link_begin(struct key *keyring, const struct key_type *type, } /* add the key into the new space */ - RCU_INIT_POINTER(nklist->keys[nklist->delkey], NULL); - prealloc = (unsigned long)nklist | KEY_LINK_FIXQUOTA; + nklist->keys[nklist->delkey] = NULL; } + prealloc = (unsigned long)nklist | KEY_LINK_FIXQUOTA; done: *_prealloc = prealloc; kleave(" = 0"); @@ -900,7 +862,6 @@ void __key_link(struct key *keyring, struct key *key, unsigned long *_prealloc) { struct keyring_list *klist, *nklist; - struct key *discard; nklist = (struct keyring_list *)(*_prealloc & ~KEY_LINK_FIXQUOTA); *_prealloc = 0; @@ -910,16 +871,14 @@ void __key_link(struct key *keyring, struct key *key, klist = rcu_dereference_locked_keyring(keyring); atomic_inc(&key->usage); - keyring->last_used_at = key->last_used_at = - current_kernel_time().tv_sec; /* there's a matching key we can displace or an empty slot in a newly * allocated list we can fill */ if (nklist) { - kdebug("reissue %hu/%hu/%hu", + kdebug("replace %hu/%hu/%hu", nklist->delkey, nklist->nkeys, nklist->maxkeys); - RCU_INIT_POINTER(nklist->keys[nklist->delkey], key); + nklist->keys[nklist->delkey] = key; rcu_assign_pointer(keyring->payload.subscriptions, nklist); @@ -930,23 +889,9 @@ void __key_link(struct key *keyring, struct key *key, klist->delkey, klist->nkeys, klist->maxkeys); call_rcu(&klist->rcu, keyring_unlink_rcu_disposal); } - } else if (klist->delkey < klist->nkeys) { - kdebug("replace %hu/%hu/%hu", - klist->delkey, klist->nkeys, klist->maxkeys); - - discard = rcu_dereference_protected( - klist->keys[klist->delkey], - rwsem_is_locked(&keyring->sem)); - rcu_assign_pointer(klist->keys[klist->delkey], key); - /* The garbage collector will take care of RCU - * synchronisation */ - key_put(discard); } else { /* there's sufficient slack space to append directly */ - kdebug("append %hu/%hu/%hu", - klist->delkey, klist->nkeys, klist->maxkeys); - - RCU_INIT_POINTER(klist->keys[klist->delkey], key); + klist->keys[klist->nkeys] = key; smp_wmb(); klist->nkeys++; } @@ -1053,7 +998,7 @@ int key_unlink(struct key *keyring, struct key *key) if (klist) { /* search the keyring for the key */ for (loop = 0; loop < klist->nkeys; loop++) - if (rcu_access_pointer(klist->keys[loop]) == key) + if (klist->keys[loop] == key) goto key_is_present; } @@ -1116,7 +1061,7 @@ static void keyring_clear_rcu_disposal(struct rcu_head *rcu) klist = container_of(rcu, struct keyring_list, rcu); for (loop = klist->nkeys - 1; loop >= 0; loop--) - key_put(rcu_access_pointer(klist->keys[loop])); + key_put(klist->keys[loop]); kfree(klist); } @@ -1182,6 +1127,15 @@ static void keyring_revoke(struct key *keyring) } } +/* + * Determine whether a key is dead. + */ +static bool key_is_dead(struct key *key, time_t limit) +{ + return test_bit(KEY_FLAG_DEAD, &key->flags) || + (key->expiry > 0 && key->expiry <= limit); +} + /* * Collect garbage from the contents of a keyring, replacing the old list with * a new one with the pointers all shuffled down. @@ -1207,8 +1161,7 @@ void keyring_gc(struct key *keyring, time_t limit) /* work out how many subscriptions we're keeping */ keep = 0; for (loop = klist->nkeys - 1; loop >= 0; loop--) - if (!key_is_dead(rcu_deref_link_locked(klist, loop, keyring), - limit)) + if (!key_is_dead(klist->keys[loop], limit)) keep++; if (keep == klist->nkeys) @@ -1229,11 +1182,11 @@ void keyring_gc(struct key *keyring, time_t limit) */ keep = 0; for (loop = klist->nkeys - 1; loop >= 0; loop--) { - key = rcu_deref_link_locked(klist, loop, keyring); + key = klist->keys[loop]; if (!key_is_dead(key, limit)) { if (keep >= max) goto discard_new; - RCU_INIT_POINTER(new->keys[keep++], key_get(key)); + new->keys[keep++] = key_get(key); } } new->nkeys = keep; diff --git a/trunk/security/keys/permission.c b/trunk/security/keys/permission.c index 57d96363d7f1..c35b5229e3cd 100644 --- a/trunk/security/keys/permission.c +++ b/trunk/security/keys/permission.c @@ -87,29 +87,32 @@ EXPORT_SYMBOL(key_task_permission); * key_validate - Validate a key. * @key: The key to be validated. * - * Check that a key is valid, returning 0 if the key is okay, -ENOKEY if the - * key is invalidated, -EKEYREVOKED if the key's type has been removed or if - * the key has been revoked or -EKEYEXPIRED if the key has expired. + * Check that a key is valid, returning 0 if the key is okay, -EKEYREVOKED if + * the key's type has been removed or if the key has been revoked or + * -EKEYEXPIRED if the key has expired. */ -int key_validate(const struct key *key) +int key_validate(struct key *key) { - unsigned long flags = key->flags; - - if (flags & (1 << KEY_FLAG_INVALIDATED)) - return -ENOKEY; - - /* check it's still accessible */ - if (flags & ((1 << KEY_FLAG_REVOKED) | - (1 << KEY_FLAG_DEAD))) - return -EKEYREVOKED; - - /* check it hasn't expired */ - if (key->expiry) { - struct timespec now = current_kernel_time(); - if (now.tv_sec >= key->expiry) - return -EKEYEXPIRED; + struct timespec now; + int ret = 0; + + if (key) { + /* check it's still accessible */ + ret = -EKEYREVOKED; + if (test_bit(KEY_FLAG_REVOKED, &key->flags) || + test_bit(KEY_FLAG_DEAD, &key->flags)) + goto error; + + /* check it hasn't expired */ + ret = 0; + if (key->expiry) { + now = current_kernel_time(); + if (now.tv_sec >= key->expiry) + ret = -EKEYEXPIRED; + } } - return 0; +error: + return ret; } EXPORT_SYMBOL(key_validate); diff --git a/trunk/security/keys/proc.c b/trunk/security/keys/proc.c index 30d1ddfd9cef..49bbc97943ad 100644 --- a/trunk/security/keys/proc.c +++ b/trunk/security/keys/proc.c @@ -242,7 +242,7 @@ static int proc_keys_show(struct seq_file *m, void *v) #define showflag(KEY, LETTER, FLAG) \ (test_bit(FLAG, &(KEY)->flags) ? LETTER : '-') - seq_printf(m, "%08x %c%c%c%c%c%c%c %5d %4s %08x %5d %5d %-9.9s ", + seq_printf(m, "%08x %c%c%c%c%c%c %5d %4s %08x %5d %5d %-9.9s ", key->serial, showflag(key, 'I', KEY_FLAG_INSTANTIATED), showflag(key, 'R', KEY_FLAG_REVOKED), @@ -250,7 +250,6 @@ static int proc_keys_show(struct seq_file *m, void *v) showflag(key, 'Q', KEY_FLAG_IN_QUOTA), showflag(key, 'U', KEY_FLAG_USER_CONSTRUCT), showflag(key, 'N', KEY_FLAG_NEGATIVE), - showflag(key, 'i', KEY_FLAG_INVALIDATED), atomic_read(&key->usage), xbuf, key->perm, diff --git a/trunk/security/keys/process_keys.c b/trunk/security/keys/process_keys.c index e137fcd7042c..be7ecb2018dd 100644 --- a/trunk/security/keys/process_keys.c +++ b/trunk/security/keys/process_keys.c @@ -732,8 +732,6 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, if (ret < 0) goto invalid_key; - key->last_used_at = current_kernel_time().tv_sec; - error: put_cred(cred); return key_ref; diff --git a/trunk/security/lsm_audit.c b/trunk/security/lsm_audit.c index 8d8d97dbb389..90c129b0102f 100644 --- a/trunk/security/lsm_audit.c +++ b/trunk/security/lsm_audit.c @@ -213,15 +213,12 @@ static void dump_common_audit_data(struct audit_buffer *ab, { struct task_struct *tsk = current; - /* - * To keep stack sizes in check force programers to notice if they - * start making this union too large! See struct lsm_network_audit - * as an example of how to deal with large data. - */ - BUILD_BUG_ON(sizeof(a->u) > sizeof(void *)*2); - - audit_log_format(ab, " pid=%d comm=", tsk->pid); - audit_log_untrustedstring(ab, tsk->comm); + if (a->tsk) + tsk = a->tsk; + if (tsk && tsk->pid) { + audit_log_format(ab, " pid=%d comm=", tsk->pid); + audit_log_untrustedstring(ab, tsk->comm); + } switch (a->type) { case LSM_AUDIT_DATA_NONE: diff --git a/trunk/security/security.c b/trunk/security/security.c index 5497a57fba01..bf619ffc9a4d 100644 --- a/trunk/security/security.c +++ b/trunk/security/security.c @@ -701,11 +701,11 @@ int security_file_receive(struct file *file) return security_ops->file_receive(file); } -int security_file_open(struct file *file, const struct cred *cred) +int security_dentry_open(struct file *file, const struct cred *cred) { int ret; - ret = security_ops->file_open(file, cred); + ret = security_ops->dentry_open(file, cred); if (ret) return ret; diff --git a/trunk/security/selinux/avc.c b/trunk/security/selinux/avc.c index 68d82daed257..8ee42b2a5f19 100644 --- a/trunk/security/selinux/avc.c +++ b/trunk/security/selinux/avc.c @@ -65,8 +65,14 @@ struct avc_cache { }; struct avc_callback_node { - int (*callback) (u32 event); + int (*callback) (u32 event, u32 ssid, u32 tsid, + u16 tclass, u32 perms, + u32 *out_retained); u32 events; + u32 ssid; + u32 tsid; + u16 tclass; + u32 perms; struct avc_callback_node *next; }; @@ -430,9 +436,9 @@ static void avc_audit_pre_callback(struct audit_buffer *ab, void *a) { struct common_audit_data *ad = a; audit_log_format(ab, "avc: %s ", - ad->selinux_audit_data->denied ? "denied" : "granted"); - avc_dump_av(ab, ad->selinux_audit_data->tclass, - ad->selinux_audit_data->audited); + ad->selinux_audit_data->slad->denied ? "denied" : "granted"); + avc_dump_av(ab, ad->selinux_audit_data->slad->tclass, + ad->selinux_audit_data->slad->audited); audit_log_format(ab, " for "); } @@ -446,23 +452,25 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a) { struct common_audit_data *ad = a; audit_log_format(ab, " "); - avc_dump_query(ab, ad->selinux_audit_data->ssid, - ad->selinux_audit_data->tsid, - ad->selinux_audit_data->tclass); + avc_dump_query(ab, ad->selinux_audit_data->slad->ssid, + ad->selinux_audit_data->slad->tsid, + ad->selinux_audit_data->slad->tclass); } /* This is the slow part of avc audit with big stack footprint */ -noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, +static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, u32 requested, u32 audited, u32 denied, struct common_audit_data *a, unsigned flags) { struct common_audit_data stack_data; - struct selinux_audit_data sad; + struct selinux_audit_data sad = {0,}; + struct selinux_late_audit_data slad; if (!a) { a = &stack_data; - a->type = LSM_AUDIT_DATA_NONE; + COMMON_AUDIT_DATA_INIT(a, NONE); + a->selinux_audit_data = &sad; } /* @@ -476,34 +484,104 @@ noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, (flags & MAY_NOT_BLOCK)) return -ECHILD; - sad.tclass = tclass; - sad.requested = requested; - sad.ssid = ssid; - sad.tsid = tsid; - sad.audited = audited; - sad.denied = denied; - - a->selinux_audit_data = &sad; + slad.tclass = tclass; + slad.requested = requested; + slad.ssid = ssid; + slad.tsid = tsid; + slad.audited = audited; + slad.denied = denied; + a->selinux_audit_data->slad = &slad; common_lsm_audit(a, avc_audit_pre_callback, avc_audit_post_callback); return 0; } +/** + * avc_audit - Audit the granting or denial of permissions. + * @ssid: source security identifier + * @tsid: target security identifier + * @tclass: target security class + * @requested: requested permissions + * @avd: access vector decisions + * @result: result from avc_has_perm_noaudit + * @a: auxiliary audit data + * @flags: VFS walk flags + * + * Audit the granting or denial of permissions in accordance + * with the policy. This function is typically called by + * avc_has_perm() after a permission check, but can also be + * called directly by callers who use avc_has_perm_noaudit() + * in order to separate the permission check from the auditing. + * For example, this separation is useful when the permission check must + * be performed under a lock, to allow the lock to be released + * before calling the auditing code. + */ +inline int avc_audit(u32 ssid, u32 tsid, + u16 tclass, u32 requested, + struct av_decision *avd, int result, struct common_audit_data *a, + unsigned flags) +{ + u32 denied, audited; + denied = requested & ~avd->allowed; + if (unlikely(denied)) { + audited = denied & avd->auditdeny; + /* + * a->selinux_audit_data->auditdeny is TRICKY! Setting a bit in + * this field means that ANY denials should NOT be audited if + * the policy contains an explicit dontaudit rule for that + * permission. Take notice that this is unrelated to the + * actual permissions that were denied. As an example lets + * assume: + * + * denied == READ + * avd.auditdeny & ACCESS == 0 (not set means explicit rule) + * selinux_audit_data->auditdeny & ACCESS == 1 + * + * We will NOT audit the denial even though the denied + * permission was READ and the auditdeny checks were for + * ACCESS + */ + if (a && + a->selinux_audit_data->auditdeny && + !(a->selinux_audit_data->auditdeny & avd->auditdeny)) + audited = 0; + } else if (result) + audited = denied = requested; + else + audited = requested & avd->auditallow; + if (likely(!audited)) + return 0; + + return slow_avc_audit(ssid, tsid, tclass, + requested, audited, denied, + a, flags); +} + /** * avc_add_callback - Register a callback for security events. * @callback: callback function * @events: security events + * @ssid: source security identifier or %SECSID_WILD + * @tsid: target security identifier or %SECSID_WILD + * @tclass: target security class + * @perms: permissions * - * Register a callback function for events in the set @events. - * Returns %0 on success or -%ENOMEM if insufficient memory - * exists to add the callback. + * Register a callback function for events in the set @events + * related to the SID pair (@ssid, @tsid) + * and the permissions @perms, interpreting + * @perms based on @tclass. Returns %0 on success or + * -%ENOMEM if insufficient memory exists to add the callback. */ -int __init avc_add_callback(int (*callback)(u32 event), u32 events) +int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid, + u16 tclass, u32 perms, + u32 *out_retained), + u32 events, u32 ssid, u32 tsid, + u16 tclass, u32 perms) { struct avc_callback_node *c; int rc = 0; - c = kmalloc(sizeof(*c), GFP_KERNEL); + c = kmalloc(sizeof(*c), GFP_ATOMIC); if (!c) { rc = -ENOMEM; goto out; @@ -511,6 +589,9 @@ int __init avc_add_callback(int (*callback)(u32 event), u32 events) c->callback = callback; c->events = events; + c->ssid = ssid; + c->tsid = tsid; + c->perms = perms; c->next = avc_callbacks; avc_callbacks = c; out: @@ -650,7 +731,8 @@ int avc_ss_reset(u32 seqno) for (c = avc_callbacks; c; c = c->next) { if (c->events & AVC_CALLBACK_RESET) { - tmprc = c->callback(AVC_CALLBACK_RESET); + tmprc = c->callback(AVC_CALLBACK_RESET, + 0, 0, 0, 0, NULL); /* save the first error encountered for the return value and continue processing the callbacks */ if (!rc) diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index fa2341b68331..d85b793c9321 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -1420,13 +1420,16 @@ static int cred_has_capability(const struct cred *cred, int cap, int audit) { struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; struct av_decision avd; u16 sclass; u32 sid = cred_sid(cred); u32 av = CAP_TO_MASK(cap); int rc; - ad.type = LSM_AUDIT_DATA_CAP; + COMMON_AUDIT_DATA_INIT(&ad, CAP); + ad.selinux_audit_data = &sad; + ad.tsk = current; ad.u.cap = cap; switch (CAP_TO_INDEX(cap)) { @@ -1485,6 +1488,20 @@ static int inode_has_perm(const struct cred *cred, return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags); } +static int inode_has_perm_noadp(const struct cred *cred, + struct inode *inode, + u32 perms, + unsigned flags) +{ + struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; + + COMMON_AUDIT_DATA_INIT(&ad, INODE); + ad.u.inode = inode; + ad.selinux_audit_data = &sad; + return inode_has_perm(cred, inode, perms, &ad, flags); +} + /* Same as inode_has_perm, but pass explicit audit data containing the dentry to help the auditing code to more easily generate the pathname if needed. */ @@ -1494,9 +1511,11 @@ static inline int dentry_has_perm(const struct cred *cred, { struct inode *inode = dentry->d_inode; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; - ad.type = LSM_AUDIT_DATA_DENTRY; + COMMON_AUDIT_DATA_INIT(&ad, DENTRY); ad.u.dentry = dentry; + ad.selinux_audit_data = &sad; return inode_has_perm(cred, inode, av, &ad, 0); } @@ -1509,9 +1528,11 @@ static inline int path_has_perm(const struct cred *cred, { struct inode *inode = path->dentry->d_inode; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; - ad.type = LSM_AUDIT_DATA_PATH; + COMMON_AUDIT_DATA_INIT(&ad, PATH); ad.u.path = *path; + ad.selinux_audit_data = &sad; return inode_has_perm(cred, inode, av, &ad, 0); } @@ -1530,11 +1551,13 @@ static int file_has_perm(const struct cred *cred, struct file_security_struct *fsec = file->f_security; struct inode *inode = file->f_path.dentry->d_inode; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; u32 sid = cred_sid(cred); int rc; - ad.type = LSM_AUDIT_DATA_PATH; + COMMON_AUDIT_DATA_INIT(&ad, PATH); ad.u.path = file->f_path; + ad.selinux_audit_data = &sad; if (sid != fsec->sid) { rc = avc_has_perm(sid, fsec->sid, @@ -1564,6 +1587,7 @@ static int may_create(struct inode *dir, struct superblock_security_struct *sbsec; u32 sid, newsid; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; int rc; dsec = dir->i_security; @@ -1572,8 +1596,9 @@ static int may_create(struct inode *dir, sid = tsec->sid; newsid = tsec->create_sid; - ad.type = LSM_AUDIT_DATA_DENTRY; + COMMON_AUDIT_DATA_INIT(&ad, DENTRY); ad.u.dentry = dentry; + ad.selinux_audit_data = &sad; rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, DIR__ADD_NAME | DIR__SEARCH, @@ -1618,6 +1643,7 @@ static int may_link(struct inode *dir, { struct inode_security_struct *dsec, *isec; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; u32 sid = current_sid(); u32 av; int rc; @@ -1625,8 +1651,9 @@ static int may_link(struct inode *dir, dsec = dir->i_security; isec = dentry->d_inode->i_security; - ad.type = LSM_AUDIT_DATA_DENTRY; + COMMON_AUDIT_DATA_INIT(&ad, DENTRY); ad.u.dentry = dentry; + ad.selinux_audit_data = &sad; av = DIR__SEARCH; av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); @@ -1661,6 +1688,7 @@ static inline int may_rename(struct inode *old_dir, { struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; u32 sid = current_sid(); u32 av; int old_is_dir, new_is_dir; @@ -1671,7 +1699,8 @@ static inline int may_rename(struct inode *old_dir, old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); new_dsec = new_dir->i_security; - ad.type = LSM_AUDIT_DATA_DENTRY; + COMMON_AUDIT_DATA_INIT(&ad, DENTRY); + ad.selinux_audit_data = &sad; ad.u.dentry = old_dentry; rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, @@ -1957,6 +1986,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) struct task_security_struct *new_tsec; struct inode_security_struct *isec; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; struct inode *inode = bprm->file->f_path.dentry->d_inode; int rc; @@ -1986,13 +2016,6 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) new_tsec->sid = old_tsec->exec_sid; /* Reset exec SID on execve. */ new_tsec->exec_sid = 0; - - /* - * Minimize confusion: if no_new_privs and a transition is - * explicitly requested, then fail the exec. - */ - if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) - return -EPERM; } else { /* Check for a default transition on this program. */ rc = security_transition_sid(old_tsec->sid, isec->sid, @@ -2002,11 +2025,11 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) return rc; } - ad.type = LSM_AUDIT_DATA_PATH; + COMMON_AUDIT_DATA_INIT(&ad, PATH); + ad.selinux_audit_data = &sad; ad.u.path = bprm->file->f_path; - if ((bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) || - (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)) + if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) new_tsec->sid = old_tsec->sid; if (new_tsec->sid == old_tsec->sid) { @@ -2092,6 +2115,8 @@ static int selinux_bprm_secureexec(struct linux_binprm *bprm) static inline void flush_unauthorized_files(const struct cred *cred, struct files_struct *files) { + struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; struct file *file, *devnull = NULL; struct tty_struct *tty; struct fdtable *fdt; @@ -2103,17 +2128,21 @@ static inline void flush_unauthorized_files(const struct cred *cred, spin_lock(&tty_files_lock); if (!list_empty(&tty->tty_files)) { struct tty_file_private *file_priv; + struct inode *inode; /* Revalidate access to controlling tty. - Use path_has_perm on the tty path directly rather + Use inode_has_perm on the tty inode directly rather than using file_has_perm, as this particular open file may belong to another process and we are only interested in the inode-based check here. */ file_priv = list_first_entry(&tty->tty_files, struct tty_file_private, list); file = file_priv->file; - if (path_has_perm(cred, &file->f_path, FILE__READ | FILE__WRITE)) + inode = file->f_path.dentry->d_inode; + if (inode_has_perm_noadp(cred, inode, + FILE__READ | FILE__WRITE, 0)) { drop_tty = 1; + } } spin_unlock(&tty_files_lock); tty_kref_put(tty); @@ -2123,6 +2152,10 @@ static inline void flush_unauthorized_files(const struct cred *cred, no_tty(); /* Revalidate access to inherited open files. */ + + COMMON_AUDIT_DATA_INIT(&ad, INODE); + ad.selinux_audit_data = &sad; + spin_lock(&files->file_lock); for (;;) { unsigned long set, i; @@ -2459,6 +2492,7 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) { const struct cred *cred = current_cred(); struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; int rc; rc = superblock_doinit(sb, data); @@ -2469,7 +2503,8 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) if (flags & MS_KERNMOUNT) return 0; - ad.type = LSM_AUDIT_DATA_DENTRY; + COMMON_AUDIT_DATA_INIT(&ad, DENTRY); + ad.selinux_audit_data = &sad; ad.u.dentry = sb->s_root; return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); } @@ -2478,8 +2513,10 @@ static int selinux_sb_statfs(struct dentry *dentry) { const struct cred *cred = current_cred(); struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; - ad.type = LSM_AUDIT_DATA_DENTRY; + COMMON_AUDIT_DATA_INIT(&ad, DENTRY); + ad.selinux_audit_data = &sad; ad.u.dentry = dentry->d_sb->s_root; return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); } @@ -2639,35 +2676,14 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na return dentry_has_perm(cred, dentry, FILE__READ); } -static noinline int audit_inode_permission(struct inode *inode, - u32 perms, u32 audited, u32 denied, - unsigned flags) -{ - struct common_audit_data ad; - struct inode_security_struct *isec = inode->i_security; - int rc; - - ad.type = LSM_AUDIT_DATA_INODE; - ad.u.inode = inode; - - rc = slow_avc_audit(current_sid(), isec->sid, isec->sclass, perms, - audited, denied, &ad, flags); - if (rc) - return rc; - return 0; -} - static int selinux_inode_permission(struct inode *inode, int mask) { const struct cred *cred = current_cred(); + struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; u32 perms; bool from_access; unsigned flags = mask & MAY_NOT_BLOCK; - struct inode_security_struct *isec; - u32 sid; - struct av_decision avd; - int rc, rc2; - u32 audited, denied; from_access = mask & MAY_ACCESS; mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND); @@ -2676,34 +2692,22 @@ static int selinux_inode_permission(struct inode *inode, int mask) if (!mask) return 0; - validate_creds(cred); + COMMON_AUDIT_DATA_INIT(&ad, INODE); + ad.selinux_audit_data = &sad; + ad.u.inode = inode; - if (unlikely(IS_PRIVATE(inode))) - return 0; + if (from_access) + ad.selinux_audit_data->auditdeny |= FILE__AUDIT_ACCESS; perms = file_mask_to_av(inode->i_mode, mask); - sid = cred_sid(cred); - isec = inode->i_security; - - rc = avc_has_perm_noaudit(sid, isec->sid, isec->sclass, perms, 0, &avd); - audited = avc_audit_required(perms, &avd, rc, - from_access ? FILE__AUDIT_ACCESS : 0, - &denied); - if (likely(!audited)) - return rc; - - rc2 = audit_inode_permission(inode, perms, audited, denied, flags); - if (rc2) - return rc2; - return rc; + return inode_has_perm(cred, inode, perms, &ad, flags); } static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) { const struct cred *cred = current_cred(); unsigned int ia_valid = iattr->ia_valid; - __u32 av = FILE__WRITE; /* ATTR_FORCE is just used for ATTR_KILL_S[UG]ID. */ if (ia_valid & ATTR_FORCE) { @@ -2717,10 +2721,7 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) return dentry_has_perm(cred, dentry, FILE__SETATTR); - if (ia_valid & ATTR_SIZE) - av |= FILE__OPEN; - - return dentry_has_perm(cred, dentry, av); + return dentry_has_perm(cred, dentry, FILE__WRITE); } static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) @@ -2762,6 +2763,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, struct inode_security_struct *isec = inode->i_security; struct superblock_security_struct *sbsec; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; u32 newsid, sid = current_sid(); int rc = 0; @@ -2775,7 +2777,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, if (!inode_owner_or_capable(inode)) return -EPERM; - ad.type = LSM_AUDIT_DATA_DENTRY; + COMMON_AUDIT_DATA_INIT(&ad, DENTRY); + ad.selinux_audit_data = &sad; ad.u.dentry = dentry; rc = avc_has_perm(sid, isec->sid, isec->sclass, @@ -2785,25 +2788,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, rc = security_context_to_sid(value, size, &newsid); if (rc == -EINVAL) { - if (!capable(CAP_MAC_ADMIN)) { - struct audit_buffer *ab; - size_t audit_size; - const char *str; - - /* We strip a nul only if it is at the end, otherwise the - * context contains a nul and we should audit that */ - str = value; - if (str[size - 1] == '\0') - audit_size = size - 1; - else - audit_size = size; - ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR); - audit_log_format(ab, "op=setxattr invalid_context="); - audit_log_n_untrustedstring(ab, value, audit_size); - audit_log_end(ab); - + if (!capable(CAP_MAC_ADMIN)) return rc; - } rc = security_context_to_sid_force(value, size, &newsid); } if (rc) @@ -2983,7 +2969,7 @@ static int selinux_file_permission(struct file *file, int mask) if (sid == fsec->sid && fsec->isid == isec->sid && fsec->pseqno == avc_policy_seqno()) - /* No change since file_open check. */ + /* No change since dentry_open check. */ return 0; return selinux_revalidate_file_permission(file, mask); @@ -3242,13 +3228,15 @@ static int selinux_file_receive(struct file *file) return file_has_perm(cred, file, file_to_av(file)); } -static int selinux_file_open(struct file *file, const struct cred *cred) +static int selinux_dentry_open(struct file *file, const struct cred *cred) { struct file_security_struct *fsec; + struct inode *inode; struct inode_security_struct *isec; + inode = file->f_path.dentry->d_inode; fsec = file->f_security; - isec = file->f_path.dentry->d_inode->i_security; + isec = inode->i_security; /* * Save inode label and policy sequence number * at open-time so that selinux_file_permission @@ -3266,7 +3254,7 @@ static int selinux_file_open(struct file *file, const struct cred *cred) * new inode label or new policy. * This check is not redundant - do not remove. */ - return path_has_perm(cred, &file->f_path, open_file_to_av(file)); + return inode_has_perm_noadp(cred, inode, open_file_to_av(file), 0); } /* task security operations */ @@ -3385,10 +3373,12 @@ static int selinux_kernel_module_request(char *kmod_name) { u32 sid; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; sid = task_sid(current); - ad.type = LSM_AUDIT_DATA_KMOD; + COMMON_AUDIT_DATA_INIT(&ad, KMOD); + ad.selinux_audit_data = &sad; ad.u.kmod_name = kmod_name; return avc_has_perm(sid, SECINITSID_KERNEL, SECCLASS_SYSTEM, @@ -3761,13 +3751,15 @@ static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms) { struct sk_security_struct *sksec = sk->sk_security; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; struct lsm_network_audit net = {0,}; u32 tsid = task_sid(task); if (sksec->sid == SECINITSID_KERNEL) return 0; - ad.type = LSM_AUDIT_DATA_NET; + COMMON_AUDIT_DATA_INIT(&ad, NET); + ad.selinux_audit_data = &sad; ad.u.net = &net; ad.u.net->sk = sk; @@ -3847,6 +3839,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in char *addrp; struct sk_security_struct *sksec = sk->sk_security; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; struct lsm_network_audit net = {0,}; struct sockaddr_in *addr4 = NULL; struct sockaddr_in6 *addr6 = NULL; @@ -3873,7 +3866,8 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in snum, &sid); if (err) goto out; - ad.type = LSM_AUDIT_DATA_NET; + COMMON_AUDIT_DATA_INIT(&ad, NET); + ad.selinux_audit_data = &sad; ad.u.net = &net; ad.u.net->sport = htons(snum); ad.u.net->family = family; @@ -3907,7 +3901,8 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in if (err) goto out; - ad.type = LSM_AUDIT_DATA_NET; + COMMON_AUDIT_DATA_INIT(&ad, NET); + ad.selinux_audit_data = &sad; ad.u.net = &net; ad.u.net->sport = htons(snum); ad.u.net->family = family; @@ -3942,6 +3937,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, if (sksec->sclass == SECCLASS_TCP_SOCKET || sksec->sclass == SECCLASS_DCCP_SOCKET) { struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; struct lsm_network_audit net = {0,}; struct sockaddr_in *addr4 = NULL; struct sockaddr_in6 *addr6 = NULL; @@ -3967,7 +3963,8 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, perm = (sksec->sclass == SECCLASS_TCP_SOCKET) ? TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT; - ad.type = LSM_AUDIT_DATA_NET; + COMMON_AUDIT_DATA_INIT(&ad, NET); + ad.selinux_audit_data = &sad; ad.u.net = &net; ad.u.net->dport = htons(snum); ad.u.net->family = sk->sk_family; @@ -4059,10 +4056,12 @@ static int selinux_socket_unix_stream_connect(struct sock *sock, struct sk_security_struct *sksec_other = other->sk_security; struct sk_security_struct *sksec_new = newsk->sk_security; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; struct lsm_network_audit net = {0,}; int err; - ad.type = LSM_AUDIT_DATA_NET; + COMMON_AUDIT_DATA_INIT(&ad, NET); + ad.selinux_audit_data = &sad; ad.u.net = &net; ad.u.net->sk = other; @@ -4091,9 +4090,11 @@ static int selinux_socket_unix_may_send(struct socket *sock, struct sk_security_struct *ssec = sock->sk->sk_security; struct sk_security_struct *osec = other->sk->sk_security; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; struct lsm_network_audit net = {0,}; - ad.type = LSM_AUDIT_DATA_NET; + COMMON_AUDIT_DATA_INIT(&ad, NET); + ad.selinux_audit_data = &sad; ad.u.net = &net; ad.u.net->sk = other->sk; @@ -4131,10 +4132,12 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, struct sk_security_struct *sksec = sk->sk_security; u32 sk_sid = sksec->sid; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; struct lsm_network_audit net = {0,}; char *addrp; - ad.type = LSM_AUDIT_DATA_NET; + COMMON_AUDIT_DATA_INIT(&ad, NET); + ad.selinux_audit_data = &sad; ad.u.net = &net; ad.u.net->netif = skb->skb_iif; ad.u.net->family = family; @@ -4164,6 +4167,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) u16 family = sk->sk_family; u32 sk_sid = sksec->sid; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; struct lsm_network_audit net = {0,}; char *addrp; u8 secmark_active; @@ -4188,7 +4192,8 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) if (!secmark_active && !peerlbl_active) return 0; - ad.type = LSM_AUDIT_DATA_NET; + COMMON_AUDIT_DATA_INIT(&ad, NET); + ad.selinux_audit_data = &sad; ad.u.net = &net; ad.u.net->netif = skb->skb_iif; ad.u.net->family = family; @@ -4526,6 +4531,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, char *addrp; u32 peer_sid; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; struct lsm_network_audit net = {0,}; u8 secmark_active; u8 netlbl_active; @@ -4543,7 +4549,8 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0) return NF_DROP; - ad.type = LSM_AUDIT_DATA_NET; + COMMON_AUDIT_DATA_INIT(&ad, NET); + ad.selinux_audit_data = &sad; ad.u.net = &net; ad.u.net->netif = ifindex; ad.u.net->family = family; @@ -4633,6 +4640,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, struct sock *sk = skb->sk; struct sk_security_struct *sksec; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; struct lsm_network_audit net = {0,}; char *addrp; u8 proto; @@ -4641,7 +4649,8 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, return NF_ACCEPT; sksec = sk->sk_security; - ad.type = LSM_AUDIT_DATA_NET; + COMMON_AUDIT_DATA_INIT(&ad, NET); + ad.selinux_audit_data = &sad; ad.u.net = &net; ad.u.net->netif = ifindex; ad.u.net->family = family; @@ -4666,6 +4675,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, u32 peer_sid; struct sock *sk; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; struct lsm_network_audit net = {0,}; char *addrp; u8 secmark_active; @@ -4712,7 +4722,8 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, secmark_perm = PACKET__SEND; } - ad.type = LSM_AUDIT_DATA_NET; + COMMON_AUDIT_DATA_INIT(&ad, NET); + ad.selinux_audit_data = &sad; ad.u.net = &net; ad.u.net->netif = ifindex; ad.u.net->family = family; @@ -4830,11 +4841,13 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, { struct ipc_security_struct *isec; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; u32 sid = current_sid(); isec = ipc_perms->security; - ad.type = LSM_AUDIT_DATA_IPC; + COMMON_AUDIT_DATA_INIT(&ad, IPC); + ad.selinux_audit_data = &sad; ad.u.ipc_id = ipc_perms->key; return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad); @@ -4855,6 +4868,7 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq) { struct ipc_security_struct *isec; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; u32 sid = current_sid(); int rc; @@ -4864,7 +4878,8 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq) isec = msq->q_perm.security; - ad.type = LSM_AUDIT_DATA_IPC; + COMMON_AUDIT_DATA_INIT(&ad, IPC); + ad.selinux_audit_data = &sad; ad.u.ipc_id = msq->q_perm.key; rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, @@ -4885,11 +4900,13 @@ static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg) { struct ipc_security_struct *isec; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; u32 sid = current_sid(); isec = msq->q_perm.security; - ad.type = LSM_AUDIT_DATA_IPC; + COMMON_AUDIT_DATA_INIT(&ad, IPC); + ad.selinux_audit_data = &sad; ad.u.ipc_id = msq->q_perm.key; return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, @@ -4929,6 +4946,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, struct ipc_security_struct *isec; struct msg_security_struct *msec; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; u32 sid = current_sid(); int rc; @@ -4949,7 +4967,8 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, return rc; } - ad.type = LSM_AUDIT_DATA_IPC; + COMMON_AUDIT_DATA_INIT(&ad, IPC); + ad.selinux_audit_data = &sad; ad.u.ipc_id = msq->q_perm.key; /* Can this process write to the queue? */ @@ -4974,13 +4993,15 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, struct ipc_security_struct *isec; struct msg_security_struct *msec; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; u32 sid = task_sid(target); int rc; isec = msq->q_perm.security; msec = msg->security; - ad.type = LSM_AUDIT_DATA_IPC; + COMMON_AUDIT_DATA_INIT(&ad, IPC); + ad.selinux_audit_data = &sad; ad.u.ipc_id = msq->q_perm.key; rc = avc_has_perm(sid, isec->sid, @@ -4996,6 +5017,7 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp) { struct ipc_security_struct *isec; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; u32 sid = current_sid(); int rc; @@ -5005,7 +5027,8 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp) isec = shp->shm_perm.security; - ad.type = LSM_AUDIT_DATA_IPC; + COMMON_AUDIT_DATA_INIT(&ad, IPC); + ad.selinux_audit_data = &sad; ad.u.ipc_id = shp->shm_perm.key; rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM, @@ -5026,11 +5049,13 @@ static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg) { struct ipc_security_struct *isec; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; u32 sid = current_sid(); isec = shp->shm_perm.security; - ad.type = LSM_AUDIT_DATA_IPC; + COMMON_AUDIT_DATA_INIT(&ad, IPC); + ad.selinux_audit_data = &sad; ad.u.ipc_id = shp->shm_perm.key; return avc_has_perm(sid, isec->sid, SECCLASS_SHM, @@ -5088,6 +5113,7 @@ static int selinux_sem_alloc_security(struct sem_array *sma) { struct ipc_security_struct *isec; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; u32 sid = current_sid(); int rc; @@ -5097,7 +5123,8 @@ static int selinux_sem_alloc_security(struct sem_array *sma) isec = sma->sem_perm.security; - ad.type = LSM_AUDIT_DATA_IPC; + COMMON_AUDIT_DATA_INIT(&ad, IPC); + ad.selinux_audit_data = &sad; ad.u.ipc_id = sma->sem_perm.key; rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM, @@ -5118,11 +5145,13 @@ static int selinux_sem_associate(struct sem_array *sma, int semflg) { struct ipc_security_struct *isec; struct common_audit_data ad; + struct selinux_audit_data sad = {0,}; u32 sid = current_sid(); isec = sma->sem_perm.security; - ad.type = LSM_AUDIT_DATA_IPC; + COMMON_AUDIT_DATA_INIT(&ad, IPC); + ad.selinux_audit_data = &sad; ad.u.ipc_id = sma->sem_perm.key; return avc_has_perm(sid, isec->sid, SECCLASS_SEM, @@ -5302,23 +5331,8 @@ static int selinux_setprocattr(struct task_struct *p, } error = security_context_to_sid(value, size, &sid); if (error == -EINVAL && !strcmp(name, "fscreate")) { - if (!capable(CAP_MAC_ADMIN)) { - struct audit_buffer *ab; - size_t audit_size; - - /* We strip a nul only if it is at the end, otherwise the - * context contains a nul and we should audit that */ - if (str[size - 1] == '\0') - audit_size = size - 1; - else - audit_size = size; - ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR); - audit_log_format(ab, "op=fscreate invalid_context="); - audit_log_n_untrustedstring(ab, value, audit_size); - audit_log_end(ab); - + if (!capable(CAP_MAC_ADMIN)) return error; - } error = security_context_to_sid_force(value, size, &sid); } @@ -5578,7 +5592,7 @@ static struct security_operations selinux_ops = { .file_send_sigiotask = selinux_file_send_sigiotask, .file_receive = selinux_file_receive, - .file_open = selinux_file_open, + .dentry_open = selinux_dentry_open, .task_create = selinux_task_create, .cred_alloc_blank = selinux_cred_alloc_blank, diff --git a/trunk/security/selinux/include/avc.h b/trunk/security/selinux/include/avc.h index 92d0ab561db8..1931370233d7 100644 --- a/trunk/security/selinux/include/avc.h +++ b/trunk/security/selinux/include/avc.h @@ -49,7 +49,7 @@ struct avc_cache_stats { /* * We only need this data after we have decided to send an audit message. */ -struct selinux_audit_data { +struct selinux_late_audit_data { u32 ssid; u32 tsid; u16 tclass; @@ -59,87 +59,29 @@ struct selinux_audit_data { int result; }; +/* + * We collect this at the beginning or during an selinux security operation + */ +struct selinux_audit_data { + /* + * auditdeny is a bit tricky and unintuitive. See the + * comments in avc.c for it's meaning and usage. + */ + u32 auditdeny; + struct selinux_late_audit_data *slad; +}; + /* * AVC operations */ void __init avc_init(void); -static inline u32 avc_audit_required(u32 requested, - struct av_decision *avd, - int result, - u32 auditdeny, - u32 *deniedp) -{ - u32 denied, audited; - denied = requested & ~avd->allowed; - if (unlikely(denied)) { - audited = denied & avd->auditdeny; - /* - * auditdeny is TRICKY! Setting a bit in - * this field means that ANY denials should NOT be audited if - * the policy contains an explicit dontaudit rule for that - * permission. Take notice that this is unrelated to the - * actual permissions that were denied. As an example lets - * assume: - * - * denied == READ - * avd.auditdeny & ACCESS == 0 (not set means explicit rule) - * auditdeny & ACCESS == 1 - * - * We will NOT audit the denial even though the denied - * permission was READ and the auditdeny checks were for - * ACCESS - */ - if (auditdeny && !(auditdeny & avd->auditdeny)) - audited = 0; - } else if (result) - audited = denied = requested; - else - audited = requested & avd->auditallow; - *deniedp = denied; - return audited; -} - -int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, - u32 requested, u32 audited, u32 denied, - struct common_audit_data *a, - unsigned flags); - -/** - * avc_audit - Audit the granting or denial of permissions. - * @ssid: source security identifier - * @tsid: target security identifier - * @tclass: target security class - * @requested: requested permissions - * @avd: access vector decisions - * @result: result from avc_has_perm_noaudit - * @a: auxiliary audit data - * @flags: VFS walk flags - * - * Audit the granting or denial of permissions in accordance - * with the policy. This function is typically called by - * avc_has_perm() after a permission check, but can also be - * called directly by callers who use avc_has_perm_noaudit() - * in order to separate the permission check from the auditing. - * For example, this separation is useful when the permission check must - * be performed under a lock, to allow the lock to be released - * before calling the auditing code. - */ -static inline int avc_audit(u32 ssid, u32 tsid, - u16 tclass, u32 requested, - struct av_decision *avd, - int result, - struct common_audit_data *a, unsigned flags) -{ - u32 audited, denied; - audited = avc_audit_required(requested, avd, result, 0, &denied); - if (likely(!audited)) - return 0; - return slow_avc_audit(ssid, tsid, tclass, - requested, audited, denied, - a, flags); -} +int avc_audit(u32 ssid, u32 tsid, + u16 tclass, u32 requested, + struct av_decision *avd, + int result, + struct common_audit_data *a, unsigned flags); #define AVC_STRICT 1 /* Ignore permissive mode. */ int avc_has_perm_noaudit(u32 ssid, u32 tsid, @@ -170,7 +112,11 @@ u32 avc_policy_seqno(void); #define AVC_CALLBACK_AUDITDENY_ENABLE 64 #define AVC_CALLBACK_AUDITDENY_DISABLE 128 -int avc_add_callback(int (*callback)(u32 event), u32 events); +int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid, + u16 tclass, u32 perms, + u32 *out_retained), + u32 events, u32 ssid, u32 tsid, + u16 tclass, u32 perms); /* Exported to selinuxfs */ int avc_get_hash_stats(char *page); diff --git a/trunk/security/selinux/include/security.h b/trunk/security/selinux/include/security.h index dde2005407aa..d871e8ad2103 100644 --- a/trunk/security/selinux/include/security.h +++ b/trunk/security/selinux/include/security.h @@ -31,15 +31,13 @@ #define POLICYDB_VERSION_BOUNDARY 24 #define POLICYDB_VERSION_FILENAME_TRANS 25 #define POLICYDB_VERSION_ROLETRANS 26 -#define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27 -#define POLICYDB_VERSION_DEFAULT_TYPE 28 /* Range of policy versions we understand*/ #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX #define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE #else -#define POLICYDB_VERSION_MAX POLICYDB_VERSION_DEFAULT_TYPE +#define POLICYDB_VERSION_MAX POLICYDB_VERSION_ROLETRANS #endif /* Mask for just the mount related flags */ diff --git a/trunk/security/selinux/netif.c b/trunk/security/selinux/netif.c index 47a49d1a6f6a..326f22cbe405 100644 --- a/trunk/security/selinux/netif.c +++ b/trunk/security/selinux/netif.c @@ -252,7 +252,8 @@ static void sel_netif_flush(void) spin_unlock_bh(&sel_netif_lock); } -static int sel_netif_avc_callback(u32 event) +static int sel_netif_avc_callback(u32 event, u32 ssid, u32 tsid, + u16 class, u32 perms, u32 *retained) { if (event == AVC_CALLBACK_RESET) { sel_netif_flush(); @@ -291,7 +292,8 @@ static __init int sel_netif_init(void) register_netdevice_notifier(&sel_netif_netdev_notifier); - err = avc_add_callback(sel_netif_avc_callback, AVC_CALLBACK_RESET); + err = avc_add_callback(sel_netif_avc_callback, AVC_CALLBACK_RESET, + SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0); if (err) panic("avc_add_callback() failed, error %d\n", err); diff --git a/trunk/security/selinux/netnode.c b/trunk/security/selinux/netnode.c index 28f911cdd7c7..86365857c088 100644 --- a/trunk/security/selinux/netnode.c +++ b/trunk/security/selinux/netnode.c @@ -297,7 +297,8 @@ static void sel_netnode_flush(void) spin_unlock_bh(&sel_netnode_lock); } -static int sel_netnode_avc_callback(u32 event) +static int sel_netnode_avc_callback(u32 event, u32 ssid, u32 tsid, + u16 class, u32 perms, u32 *retained) { if (event == AVC_CALLBACK_RESET) { sel_netnode_flush(); @@ -319,7 +320,8 @@ static __init int sel_netnode_init(void) sel_netnode_hash[iter].size = 0; } - ret = avc_add_callback(sel_netnode_avc_callback, AVC_CALLBACK_RESET); + ret = avc_add_callback(sel_netnode_avc_callback, AVC_CALLBACK_RESET, + SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0); if (ret != 0) panic("avc_add_callback() failed, error %d\n", ret); diff --git a/trunk/security/selinux/netport.c b/trunk/security/selinux/netport.c index d35379781c2c..7b9eb1faf68b 100644 --- a/trunk/security/selinux/netport.c +++ b/trunk/security/selinux/netport.c @@ -234,7 +234,8 @@ static void sel_netport_flush(void) spin_unlock_bh(&sel_netport_lock); } -static int sel_netport_avc_callback(u32 event) +static int sel_netport_avc_callback(u32 event, u32 ssid, u32 tsid, + u16 class, u32 perms, u32 *retained) { if (event == AVC_CALLBACK_RESET) { sel_netport_flush(); @@ -256,7 +257,8 @@ static __init int sel_netport_init(void) sel_netport_hash[iter].size = 0; } - ret = avc_add_callback(sel_netport_avc_callback, AVC_CALLBACK_RESET); + ret = avc_add_callback(sel_netport_avc_callback, AVC_CALLBACK_RESET, + SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0); if (ret != 0) panic("avc_add_callback() failed, error %d\n", ret); diff --git a/trunk/security/selinux/selinuxfs.c b/trunk/security/selinux/selinuxfs.c index 4e93f9ef970b..d7018bfa1f00 100644 --- a/trunk/security/selinux/selinuxfs.c +++ b/trunk/security/selinux/selinuxfs.c @@ -496,7 +496,6 @@ static const struct file_operations sel_policy_ops = { .read = sel_read_policy, .mmap = sel_mmap_policy, .release = sel_release_policy, - .llseek = generic_file_llseek, }; static ssize_t sel_write_load(struct file *file, const char __user *buf, @@ -1233,7 +1232,6 @@ static int sel_make_bools(void) kfree(bool_pending_names[i]); kfree(bool_pending_names); kfree(bool_pending_values); - bool_num = 0; bool_pending_names = NULL; bool_pending_values = NULL; @@ -1534,6 +1532,11 @@ static int sel_make_initcon_files(struct dentry *dir) return 0; } +static inline unsigned int sel_div(unsigned long a, unsigned long b) +{ + return a / b - (a % b < 0); +} + static inline unsigned long sel_class_to_ino(u16 class) { return (class * (SEL_VEC_MAX + 1)) | SEL_CLASS_INO_OFFSET; @@ -1541,7 +1544,7 @@ static inline unsigned long sel_class_to_ino(u16 class) static inline u16 sel_ino_to_class(unsigned long ino) { - return (ino & SEL_INO_MASK) / (SEL_VEC_MAX + 1); + return sel_div(ino & SEL_INO_MASK, SEL_VEC_MAX + 1); } static inline unsigned long sel_perm_to_ino(u16 class, u32 perm) @@ -1828,7 +1831,7 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) [SEL_REJECT_UNKNOWN] = {"reject_unknown", &sel_handle_unknown_ops, S_IRUGO}, [SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO}, [SEL_STATUS] = {"status", &sel_handle_status_ops, S_IRUGO}, - [SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUGO}, + [SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUSR}, /* last one */ {""} }; ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files); diff --git a/trunk/security/selinux/ss/context.h b/trunk/security/selinux/ss/context.h index 212e3479a0d9..45e8fb0515f8 100644 --- a/trunk/security/selinux/ss/context.h +++ b/trunk/security/selinux/ss/context.h @@ -74,26 +74,6 @@ static inline int mls_context_cpy_low(struct context *dst, struct context *src) return rc; } -/* - * Sets both levels in the MLS range of 'dst' to the high level of 'src'. - */ -static inline int mls_context_cpy_high(struct context *dst, struct context *src) -{ - int rc; - - dst->range.level[0].sens = src->range.level[1].sens; - rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[1].cat); - if (rc) - goto out; - - dst->range.level[1].sens = src->range.level[1].sens; - rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat); - if (rc) - ebitmap_destroy(&dst->range.level[0].cat); -out: - return rc; -} - static inline int mls_context_cmp(struct context *c1, struct context *c2) { return ((c1->range.level[0].sens == c2->range.level[0].sens) && diff --git a/trunk/security/selinux/ss/mls.c b/trunk/security/selinux/ss/mls.c index 40de8d3f208e..fbf9c5816c71 100644 --- a/trunk/security/selinux/ss/mls.c +++ b/trunk/security/selinux/ss/mls.c @@ -517,8 +517,6 @@ int mls_compute_sid(struct context *scontext, { struct range_trans rtr; struct mls_range *r; - struct class_datum *cladatum; - int default_range = 0; if (!policydb.mls_enabled) return 0; @@ -532,28 +530,6 @@ int mls_compute_sid(struct context *scontext, r = hashtab_search(policydb.range_tr, &rtr); if (r) return mls_range_set(newcontext, r); - - if (tclass && tclass <= policydb.p_classes.nprim) { - cladatum = policydb.class_val_to_struct[tclass - 1]; - if (cladatum) - default_range = cladatum->default_range; - } - - switch (default_range) { - case DEFAULT_SOURCE_LOW: - return mls_context_cpy_low(newcontext, scontext); - case DEFAULT_SOURCE_HIGH: - return mls_context_cpy_high(newcontext, scontext); - case DEFAULT_SOURCE_LOW_HIGH: - return mls_context_cpy(newcontext, scontext); - case DEFAULT_TARGET_LOW: - return mls_context_cpy_low(newcontext, tcontext); - case DEFAULT_TARGET_HIGH: - return mls_context_cpy_high(newcontext, tcontext); - case DEFAULT_TARGET_LOW_HIGH: - return mls_context_cpy(newcontext, tcontext); - } - /* Fallthrough */ case AVTAB_CHANGE: if ((tclass == policydb.process_class) || (sock == true)) diff --git a/trunk/security/selinux/ss/policydb.c b/trunk/security/selinux/ss/policydb.c index 9cd9b7c661ec..a7f61d52f05c 100644 --- a/trunk/security/selinux/ss/policydb.c +++ b/trunk/security/selinux/ss/policydb.c @@ -133,16 +133,6 @@ static struct policydb_compat_info policydb_compat[] = { .sym_num = SYM_NUM, .ocon_num = OCON_NUM, }, - { - .version = POLICYDB_VERSION_NEW_OBJECT_DEFAULTS, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM, - }, - { - .version = POLICYDB_VERSION_DEFAULT_TYPE, - .sym_num = SYM_NUM, - .ocon_num = OCON_NUM, - }, }; static struct policydb_compat_info *policydb_lookup_compat(int version) @@ -1316,23 +1306,6 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) goto bad; } - if (p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) { - rc = next_entry(buf, fp, sizeof(u32) * 3); - if (rc) - goto bad; - - cladatum->default_user = le32_to_cpu(buf[0]); - cladatum->default_role = le32_to_cpu(buf[1]); - cladatum->default_range = le32_to_cpu(buf[2]); - } - - if (p->policyvers >= POLICYDB_VERSION_DEFAULT_TYPE) { - rc = next_entry(buf, fp, sizeof(u32) * 1); - if (rc) - goto bad; - cladatum->default_type = le32_to_cpu(buf[0]); - } - rc = hashtab_insert(h, key, cladatum); if (rc) goto bad; @@ -2859,23 +2832,6 @@ static int class_write(void *vkey, void *datum, void *ptr) if (rc) return rc; - if (p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) { - buf[0] = cpu_to_le32(cladatum->default_user); - buf[1] = cpu_to_le32(cladatum->default_role); - buf[2] = cpu_to_le32(cladatum->default_range); - - rc = put_entry(buf, sizeof(uint32_t), 3, fp); - if (rc) - return rc; - } - - if (p->policyvers >= POLICYDB_VERSION_DEFAULT_TYPE) { - buf[0] = cpu_to_le32(cladatum->default_type); - rc = put_entry(buf, sizeof(uint32_t), 1, fp); - if (rc) - return rc; - } - return 0; } diff --git a/trunk/security/selinux/ss/policydb.h b/trunk/security/selinux/ss/policydb.h index da637471d4ce..b846c0387180 100644 --- a/trunk/security/selinux/ss/policydb.h +++ b/trunk/security/selinux/ss/policydb.h @@ -60,20 +60,6 @@ struct class_datum { struct symtab permissions; /* class-specific permission symbol table */ struct constraint_node *constraints; /* constraints on class permissions */ struct constraint_node *validatetrans; /* special transition rules */ -/* Options how a new object user, role, and type should be decided */ -#define DEFAULT_SOURCE 1 -#define DEFAULT_TARGET 2 - char default_user; - char default_role; - char default_type; -/* Options how a new object range should be decided */ -#define DEFAULT_SOURCE_LOW 1 -#define DEFAULT_SOURCE_HIGH 2 -#define DEFAULT_SOURCE_LOW_HIGH 3 -#define DEFAULT_TARGET_LOW 4 -#define DEFAULT_TARGET_HIGH 5 -#define DEFAULT_TARGET_LOW_HIGH 6 - char default_range; }; /* Role attributes */ diff --git a/trunk/security/selinux/ss/services.c b/trunk/security/selinux/ss/services.c index 4321b8fc8863..185f849a26f6 100644 --- a/trunk/security/selinux/ss/services.c +++ b/trunk/security/selinux/ss/services.c @@ -1018,11 +1018,9 @@ static int context_struct_to_string(struct context *context, char **scontext, u3 if (context->len) { *scontext_len = context->len; - if (scontext) { - *scontext = kstrdup(context->str, GFP_ATOMIC); - if (!(*scontext)) - return -ENOMEM; - } + *scontext = kstrdup(context->str, GFP_ATOMIC); + if (!(*scontext)) + return -ENOMEM; return 0; } @@ -1391,7 +1389,6 @@ static int security_compute_sid(u32 ssid, u32 *out_sid, bool kern) { - struct class_datum *cladatum = NULL; struct context *scontext = NULL, *tcontext = NULL, newcontext; struct role_trans *roletr = NULL; struct avtab_key avkey; @@ -1440,20 +1437,12 @@ static int security_compute_sid(u32 ssid, goto out_unlock; } - if (tclass && tclass <= policydb.p_classes.nprim) - cladatum = policydb.class_val_to_struct[tclass - 1]; - /* Set the user identity. */ switch (specified) { case AVTAB_TRANSITION: case AVTAB_CHANGE: - if (cladatum && cladatum->default_user == DEFAULT_TARGET) { - newcontext.user = tcontext->user; - } else { - /* notice this gets both DEFAULT_SOURCE and unset */ - /* Use the process user identity. */ - newcontext.user = scontext->user; - } + /* Use the process user identity. */ + newcontext.user = scontext->user; break; case AVTAB_MEMBER: /* Use the related object owner. */ @@ -1461,31 +1450,16 @@ static int security_compute_sid(u32 ssid, break; } - /* Set the role to default values. */ - if (cladatum && cladatum->default_role == DEFAULT_SOURCE) { + /* Set the role and type to default values. */ + if ((tclass == policydb.process_class) || (sock == true)) { + /* Use the current role and type of process. */ newcontext.role = scontext->role; - } else if (cladatum && cladatum->default_role == DEFAULT_TARGET) { - newcontext.role = tcontext->role; - } else { - if ((tclass == policydb.process_class) || (sock == true)) - newcontext.role = scontext->role; - else - newcontext.role = OBJECT_R_VAL; - } - - /* Set the type to default values. */ - if (cladatum && cladatum->default_type == DEFAULT_SOURCE) { newcontext.type = scontext->type; - } else if (cladatum && cladatum->default_type == DEFAULT_TARGET) { - newcontext.type = tcontext->type; } else { - if ((tclass == policydb.process_class) || (sock == true)) { - /* Use the type of process. */ - newcontext.type = scontext->type; - } else { - /* Use the type of the related object. */ - newcontext.type = tcontext->type; - } + /* Use the well-defined object role. */ + newcontext.role = OBJECT_R_VAL; + /* Use the type of the related object. */ + newcontext.type = tcontext->type; } /* Look for a type transition/member/change rule. */ @@ -3044,7 +3018,8 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, static int (*aurule_callback)(void) = audit_update_lsm_rules; -static int aurule_avc_callback(u32 event) +static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid, + u16 class, u32 perms, u32 *retained) { int err = 0; @@ -3057,7 +3032,8 @@ static int __init aurule_init(void) { int err; - err = avc_add_callback(aurule_avc_callback, AVC_CALLBACK_RESET); + err = avc_add_callback(aurule_avc_callback, AVC_CALLBACK_RESET, + SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0); if (err) panic("avc_add_callback() failed, error %d\n", err); diff --git a/trunk/security/smack/smack.h b/trunk/security/smack/smack.h index cc361b8f3d13..4ede719922ed 100644 --- a/trunk/security/smack/smack.h +++ b/trunk/security/smack/smack.h @@ -23,19 +23,13 @@ #include /* - * Smack labels were limited to 23 characters for a long time. - */ -#define SMK_LABELLEN 24 -#define SMK_LONGLABEL 256 - -/* - * Maximum number of bytes for the levels in a CIPSO IP option. * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is * bigger than can be used, and 24 is the next lower multiple * of 8, and there are too many issues if there isn't space set * aside for the terminating null byte. */ -#define SMK_CIPSOLEN 24 +#define SMK_MAXLEN 23 +#define SMK_LABELLEN (SMK_MAXLEN+1) struct superblock_smack { char *smk_root; @@ -72,7 +66,6 @@ struct task_smack { #define SMK_INODE_INSTANT 0x01 /* inode is instantiated */ #define SMK_INODE_TRANSMUTE 0x02 /* directory is transmuting */ -#define SMK_INODE_CHANGED 0x04 /* smack was transmuted */ /* * A label access rule. @@ -84,6 +77,15 @@ struct smack_rule { int smk_access; }; +/* + * An entry in the table mapping smack values to + * CIPSO level/category-set values. + */ +struct smack_cipso { + int smk_level; + char smk_catset[SMK_LABELLEN]; +}; + /* * An entry in the table identifying hosts. */ @@ -111,19 +113,22 @@ struct smk_netlbladdr { * interfaces don't. The secid should go away when all of * these components have been repaired. * - * The cipso value associated with the label gets stored here, too. + * If there is a cipso value associated with the label it + * gets stored here, too. This will most likely be rare as + * the cipso direct mapping in used internally. * * Keep the access rules for this subject label here so that * the entire set of rules does not need to be examined every * time. */ struct smack_known { - struct list_head list; - char *smk_known; - u32 smk_secid; - struct netlbl_lsm_secattr smk_netlabel; /* on wire labels */ - struct list_head smk_rules; /* access rules */ - struct mutex smk_rules_lock; /* lock for rules */ + struct list_head list; + char smk_known[SMK_LABELLEN]; + u32 smk_secid; + struct smack_cipso *smk_cipso; + spinlock_t smk_cipsolock; /* for changing cipso map */ + struct list_head smk_rules; /* access rules */ + struct mutex smk_rules_lock; /* lock for the rules */ }; /* @@ -160,7 +165,6 @@ struct smack_known { #define SMACK_CIPSO_DOI_DEFAULT 3 /* Historical */ #define SMACK_CIPSO_DOI_INVALID -1 /* Not a DOI */ #define SMACK_CIPSO_DIRECT_DEFAULT 250 /* Arbitrary */ -#define SMACK_CIPSO_MAPPED_DEFAULT 251 /* Also arbitrary */ #define SMACK_CIPSO_MAXCATVAL 63 /* Bigger gets harder */ #define SMACK_CIPSO_MAXLEVEL 255 /* CIPSO 2.2 standard */ #define SMACK_CIPSO_MAXCATNUM 239 /* CIPSO 2.2 standard */ @@ -211,9 +215,10 @@ struct inode_smack *new_inode_smack(char *); int smk_access_entry(char *, char *, struct list_head *); int smk_access(char *, char *, int, struct smk_audit_info *); int smk_curacc(char *, u32, struct smk_audit_info *); +int smack_to_cipso(const char *, struct smack_cipso *); +char *smack_from_cipso(u32, char *); char *smack_from_secid(const u32); -char *smk_parse_smack(const char *string, int len); -int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int); +void smk_parse_smack(const char *string, int len, char *smack); char *smk_import(const char *, int); struct smack_known *smk_import_entry(const char *, int); struct smack_known *smk_find_entry(const char *); @@ -223,7 +228,6 @@ u32 smack_to_secid(const char *); * Shared data. */ extern int smack_cipso_direct; -extern int smack_cipso_mapped; extern char *smack_net_ambient; extern char *smack_onlycap; extern const char *smack_cipso_option; @@ -235,12 +239,23 @@ extern struct smack_known smack_known_invalid; extern struct smack_known smack_known_star; extern struct smack_known smack_known_web; -extern struct mutex smack_known_lock; extern struct list_head smack_known_list; extern struct list_head smk_netlbladdr_list; extern struct security_operations smack_ops; +/* + * Stricly for CIPSO level manipulation. + * Set the category bit number in a smack label sized buffer. + */ +static inline void smack_catset_bit(int cat, char *catsetp) +{ + if (cat > SMK_LABELLEN * 8) + return; + + catsetp[(cat - 1) / 8] |= 0x80 >> ((cat - 1) % 8); +} + /* * Is the directory transmuting? */ @@ -304,7 +319,7 @@ void smack_log(char *subject_label, char *object_label, static inline void smk_ad_init(struct smk_audit_info *a, const char *func, char type) { - memset(&a->sad, 0, sizeof(a->sad)); + memset(a, 0, sizeof(*a)); a->a.type = type; a->a.smack_audit_data = &a->sad; a->a.smack_audit_data->function = func; diff --git a/trunk/security/smack/smack_access.c b/trunk/security/smack/smack_access.c index 9f3705e92712..c8115f7308f8 100644 --- a/trunk/security/smack/smack_access.c +++ b/trunk/security/smack/smack_access.c @@ -19,31 +19,37 @@ struct smack_known smack_known_huh = { .smk_known = "?", .smk_secid = 2, + .smk_cipso = NULL, }; struct smack_known smack_known_hat = { .smk_known = "^", .smk_secid = 3, + .smk_cipso = NULL, }; struct smack_known smack_known_star = { .smk_known = "*", .smk_secid = 4, + .smk_cipso = NULL, }; struct smack_known smack_known_floor = { .smk_known = "_", .smk_secid = 5, + .smk_cipso = NULL, }; struct smack_known smack_known_invalid = { .smk_known = "", .smk_secid = 6, + .smk_cipso = NULL, }; struct smack_known smack_known_web = { .smk_known = "@", .smk_secid = 7, + .smk_cipso = NULL, }; LIST_HEAD(smack_known_list); @@ -325,7 +331,7 @@ void smack_log(char *subject_label, char *object_label, int request, } #endif -DEFINE_MUTEX(smack_known_lock); +static DEFINE_MUTEX(smack_known_lock); /** * smk_find_entry - find a label on the list, return the list entry @@ -339,7 +345,7 @@ struct smack_known *smk_find_entry(const char *string) struct smack_known *skp; list_for_each_entry_rcu(skp, &smack_known_list, list) { - if (strcmp(skp->smk_known, string) == 0) + if (strncmp(skp->smk_known, string, SMK_MAXLEN) == 0) return skp; } @@ -350,76 +356,27 @@ struct smack_known *smk_find_entry(const char *string) * smk_parse_smack - parse smack label from a text string * @string: a text string that might contain a Smack label * @len: the maximum size, or zero if it is NULL terminated. - * - * Returns a pointer to the clean label, or NULL + * @smack: parsed smack label, or NULL if parse error */ -char *smk_parse_smack(const char *string, int len) +void smk_parse_smack(const char *string, int len, char *smack) { - char *smack; + int found; int i; - if (len <= 0) - len = strlen(string) + 1; - - /* - * Reserve a leading '-' as an indicator that - * this isn't a label, but an option to interfaces - * including /smack/cipso and /smack/cipso2 - */ - if (string[0] == '-') - return NULL; - - for (i = 0; i < len; i++) - if (string[i] > '~' || string[i] <= ' ' || string[i] == '/' || - string[i] == '"' || string[i] == '\\' || string[i] == '\'') - break; - - if (i == 0 || i >= SMK_LONGLABEL) - return NULL; - - smack = kzalloc(i + 1, GFP_KERNEL); - if (smack != NULL) { - strncpy(smack, string, i + 1); - smack[i] = '\0'; + if (len <= 0 || len > SMK_MAXLEN) + len = SMK_MAXLEN; + + for (i = 0, found = 0; i < SMK_LABELLEN; i++) { + if (found) + smack[i] = '\0'; + else if (i >= len || string[i] > '~' || string[i] <= ' ' || + string[i] == '/' || string[i] == '"' || + string[i] == '\\' || string[i] == '\'') { + smack[i] = '\0'; + found = 1; + } else + smack[i] = string[i]; } - return smack; -} - -/** - * smk_netlbl_mls - convert a catset to netlabel mls categories - * @catset: the Smack categories - * @sap: where to put the netlabel categories - * - * Allocates and fills attr.mls - * Returns 0 on success, error code on failure. - */ -int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap, - int len) -{ - unsigned char *cp; - unsigned char m; - int cat; - int rc; - int byte; - - sap->flags |= NETLBL_SECATTR_MLS_CAT; - sap->attr.mls.lvl = level; - sap->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC); - sap->attr.mls.cat->startbit = 0; - - for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++) - for (m = 0x80; m != 0; m >>= 1, cat++) { - if ((m & *cp) == 0) - continue; - rc = netlbl_secattr_catmap_setbit(sap->attr.mls.cat, - cat, GFP_ATOMIC); - if (rc < 0) { - netlbl_secattr_catmap_free(sap->attr.mls.cat); - return rc; - } - } - - return 0; } /** @@ -433,59 +390,33 @@ int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap, struct smack_known *smk_import_entry(const char *string, int len) { struct smack_known *skp; - char *smack; - int slen; - int rc; + char smack[SMK_LABELLEN]; - smack = smk_parse_smack(string, len); - if (smack == NULL) + smk_parse_smack(string, len, smack); + if (smack[0] == '\0') return NULL; mutex_lock(&smack_known_lock); skp = smk_find_entry(smack); - if (skp != NULL) - goto freeout; - - skp = kzalloc(sizeof(*skp), GFP_KERNEL); - if (skp == NULL) - goto freeout; - skp->smk_known = smack; - skp->smk_secid = smack_next_secid++; - skp->smk_netlabel.domain = skp->smk_known; - skp->smk_netlabel.flags = - NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL; - /* - * If direct labeling works use it. - * Otherwise use mapped labeling. - */ - slen = strlen(smack); - if (slen < SMK_CIPSOLEN) - rc = smk_netlbl_mls(smack_cipso_direct, skp->smk_known, - &skp->smk_netlabel, slen); - else - rc = smk_netlbl_mls(smack_cipso_mapped, (char *)&skp->smk_secid, - &skp->smk_netlabel, sizeof(skp->smk_secid)); - - if (rc >= 0) { - INIT_LIST_HEAD(&skp->smk_rules); - mutex_init(&skp->smk_rules_lock); - /* - * Make sure that the entry is actually - * filled before putting it on the list. - */ - list_add_rcu(&skp->list, &smack_known_list); - goto unlockout; + if (skp == NULL) { + skp = kzalloc(sizeof(struct smack_known), GFP_KERNEL); + if (skp != NULL) { + strncpy(skp->smk_known, smack, SMK_MAXLEN); + skp->smk_secid = smack_next_secid++; + skp->smk_cipso = NULL; + INIT_LIST_HEAD(&skp->smk_rules); + spin_lock_init(&skp->smk_cipsolock); + mutex_init(&skp->smk_rules_lock); + /* + * Make sure that the entry is actually + * filled before putting it on the list. + */ + list_add_rcu(&skp->list, &smack_known_list); + } } - /* - * smk_netlbl_mls failed. - */ - kfree(skp); - skp = NULL; -freeout: - kfree(smack); -unlockout: + mutex_unlock(&smack_known_lock); return skp; @@ -548,9 +479,79 @@ char *smack_from_secid(const u32 secid) */ u32 smack_to_secid(const char *smack) { - struct smack_known *skp = smk_find_entry(smack); + struct smack_known *skp; - if (skp == NULL) - return 0; - return skp->smk_secid; + rcu_read_lock(); + list_for_each_entry_rcu(skp, &smack_known_list, list) { + if (strncmp(skp->smk_known, smack, SMK_MAXLEN) == 0) { + rcu_read_unlock(); + return skp->smk_secid; + } + } + rcu_read_unlock(); + return 0; +} + +/** + * smack_from_cipso - find the Smack label associated with a CIPSO option + * @level: Bell & LaPadula level from the network + * @cp: Bell & LaPadula categories from the network + * + * This is a simple lookup in the label table. + * + * Return the matching label from the label list or NULL. + */ +char *smack_from_cipso(u32 level, char *cp) +{ + struct smack_known *kp; + char *final = NULL; + + rcu_read_lock(); + list_for_each_entry(kp, &smack_known_list, list) { + if (kp->smk_cipso == NULL) + continue; + + spin_lock_bh(&kp->smk_cipsolock); + + if (kp->smk_cipso->smk_level == level && + memcmp(kp->smk_cipso->smk_catset, cp, SMK_LABELLEN) == 0) + final = kp->smk_known; + + spin_unlock_bh(&kp->smk_cipsolock); + + if (final != NULL) + break; + } + rcu_read_unlock(); + + return final; +} + +/** + * smack_to_cipso - find the CIPSO option to go with a Smack label + * @smack: a pointer to the smack label in question + * @cp: where to put the result + * + * Returns zero if a value is available, non-zero otherwise. + */ +int smack_to_cipso(const char *smack, struct smack_cipso *cp) +{ + struct smack_known *kp; + int found = 0; + + rcu_read_lock(); + list_for_each_entry_rcu(kp, &smack_known_list, list) { + if (kp->smk_known == smack || + strcmp(kp->smk_known, smack) == 0) { + found = 1; + break; + } + } + rcu_read_unlock(); + + if (found == 0 || kp->smk_cipso == NULL) + return -ENOENT; + + memcpy(cp, kp->smk_cipso, sizeof(struct smack_cipso)); + return 0; } diff --git a/trunk/security/smack/smack_lsm.c b/trunk/security/smack/smack_lsm.c index d583c0545808..45c32f074166 100644 --- a/trunk/security/smack/smack_lsm.c +++ b/trunk/security/smack/smack_lsm.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -56,23 +57,16 @@ static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp) { int rc; - char *buffer; - char *result = NULL; + char in[SMK_LABELLEN]; if (ip->i_op->getxattr == NULL) return NULL; - buffer = kzalloc(SMK_LONGLABEL, GFP_KERNEL); - if (buffer == NULL) + rc = ip->i_op->getxattr(dp, name, in, SMK_LABELLEN); + if (rc < 0) return NULL; - rc = ip->i_op->getxattr(dp, name, buffer, SMK_LONGLABEL); - if (rc > 0) - result = smk_import(buffer, rc); - - kfree(buffer); - - return result; + return smk_import(in, rc); } /** @@ -85,7 +79,7 @@ struct inode_smack *new_inode_smack(char *smack) { struct inode_smack *isp; - isp = kzalloc(sizeof(struct inode_smack), GFP_NOFS); + isp = kzalloc(sizeof(struct inode_smack), GFP_KERNEL); if (isp == NULL) return NULL; @@ -562,14 +556,13 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, void **value, size_t *len) { struct smack_known *skp; - struct inode_smack *issp = inode->i_security; char *csp = smk_of_current(); char *isp = smk_of_inode(inode); char *dsp = smk_of_inode(dir); int may; if (name) { - *name = kstrdup(XATTR_SMACK_SUFFIX, GFP_NOFS); + *name = kstrdup(XATTR_SMACK_SUFFIX, GFP_KERNEL); if (*name == NULL) return -ENOMEM; } @@ -584,15 +577,12 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, * If the access rule allows transmutation and * the directory requests transmutation then * by all means transmute. - * Mark the inode as changed. */ if (may > 0 && ((may & MAY_TRANSMUTE) != 0) && - smk_inode_transmutable(dir)) { + smk_inode_transmutable(dir)) isp = dsp; - issp->smk_flags |= SMK_INODE_CHANGED; - } - *value = kstrdup(isp, GFP_NOFS); + *value = kstrdup(isp, GFP_KERNEL); if (*value == NULL) return -ENOMEM; } @@ -831,7 +821,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, * check label validity here so import wont fail on * post_setxattr */ - if (size == 0 || size >= SMK_LONGLABEL || + if (size == 0 || size >= SMK_LABELLEN || smk_import(value, size) == NULL) rc = -EINVAL; } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { @@ -1359,7 +1349,7 @@ static int smack_file_receive(struct file *file) } /** - * smack_file_open - Smack dentry open processing + * smack_dentry_open - Smack dentry open processing * @file: the object * @cred: unused * @@ -1367,7 +1357,7 @@ static int smack_file_receive(struct file *file) * * Returns 0 */ -static int smack_file_open(struct file *file, const struct cred *cred) +static int smack_dentry_open(struct file *file, const struct cred *cred) { struct inode_smack *isp = file->f_path.dentry->d_inode->i_security; @@ -1829,6 +1819,65 @@ static char *smack_host_label(struct sockaddr_in *sip) return NULL; } +/** + * smack_set_catset - convert a capset to netlabel mls categories + * @catset: the Smack categories + * @sap: where to put the netlabel categories + * + * Allocates and fills attr.mls.cat + */ +static void smack_set_catset(char *catset, struct netlbl_lsm_secattr *sap) +{ + unsigned char *cp; + unsigned char m; + int cat; + int rc; + int byte; + + if (!catset) + return; + + sap->flags |= NETLBL_SECATTR_MLS_CAT; + sap->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC); + sap->attr.mls.cat->startbit = 0; + + for (cat = 1, cp = catset, byte = 0; byte < SMK_LABELLEN; cp++, byte++) + for (m = 0x80; m != 0; m >>= 1, cat++) { + if ((m & *cp) == 0) + continue; + rc = netlbl_secattr_catmap_setbit(sap->attr.mls.cat, + cat, GFP_ATOMIC); + } +} + +/** + * smack_to_secattr - fill a secattr from a smack value + * @smack: the smack value + * @nlsp: where the result goes + * + * Casey says that CIPSO is good enough for now. + * It can be used to effect. + * It can also be abused to effect when necessary. + * Apologies to the TSIG group in general and GW in particular. + */ +static void smack_to_secattr(char *smack, struct netlbl_lsm_secattr *nlsp) +{ + struct smack_cipso cipso; + int rc; + + nlsp->domain = smack; + nlsp->flags = NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL; + + rc = smack_to_cipso(smack, &cipso); + if (rc == 0) { + nlsp->attr.mls.lvl = cipso.smk_level; + smack_set_catset(cipso.smk_catset, nlsp); + } else { + nlsp->attr.mls.lvl = smack_cipso_direct; + smack_set_catset(smack, nlsp); + } +} + /** * smack_netlabel - Set the secattr on a socket * @sk: the socket @@ -1841,8 +1890,8 @@ static char *smack_host_label(struct sockaddr_in *sip) */ static int smack_netlabel(struct sock *sk, int labeled) { - struct smack_known *skp; struct socket_smack *ssp = sk->sk_security; + struct netlbl_lsm_secattr secattr; int rc = 0; /* @@ -1860,8 +1909,10 @@ static int smack_netlabel(struct sock *sk, int labeled) labeled == SMACK_UNLABELED_SOCKET) netlbl_sock_delattr(sk); else { - skp = smk_find_entry(ssp->smk_out); - rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel); + netlbl_secattr_init(&secattr); + smack_to_secattr(ssp->smk_out, &secattr); + rc = netlbl_sock_setattr(sk, sk->sk_family, &secattr); + netlbl_secattr_destroy(&secattr); } bh_unlock_sock(sk); @@ -1934,7 +1985,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, struct socket *sock; int rc = 0; - if (value == NULL || size > SMK_LONGLABEL || size == 0) + if (value == NULL || size > SMK_LABELLEN || size == 0) return -EACCES; sp = smk_import(value, size); @@ -2501,7 +2552,6 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) char *final; char trattr[TRANS_TRUE_SIZE]; int transflag = 0; - int rc; struct dentry *dp; if (inode == NULL) @@ -2620,38 +2670,17 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) */ dp = dget(opt_dentry); fetched = smk_fetch(XATTR_NAME_SMACK, inode, dp); - if (fetched != NULL) + if (fetched != NULL) { final = fetched; - - /* - * Transmuting directory - */ - if (S_ISDIR(inode->i_mode)) { - /* - * If this is a new directory and the label was - * transmuted when the inode was initialized - * set the transmute attribute on the directory - * and mark the inode. - * - * If there is a transmute attribute on the - * directory mark the inode. - */ - if (isp->smk_flags & SMK_INODE_CHANGED) { - isp->smk_flags &= ~SMK_INODE_CHANGED; - rc = inode->i_op->setxattr(dp, + if (S_ISDIR(inode->i_mode)) { + trattr[0] = '\0'; + inode->i_op->getxattr(dp, XATTR_NAME_SMACKTRANSMUTE, - TRANS_TRUE, TRANS_TRUE_SIZE, - 0); - } else { - rc = inode->i_op->getxattr(dp, - XATTR_NAME_SMACKTRANSMUTE, trattr, - TRANS_TRUE_SIZE); - if (rc >= 0 && strncmp(trattr, TRANS_TRUE, - TRANS_TRUE_SIZE) != 0) - rc = -EINVAL; + trattr, TRANS_TRUE_SIZE); + if (strncmp(trattr, TRANS_TRUE, + TRANS_TRUE_SIZE) == 0) + transflag = SMK_INODE_TRANSMUTE; } - if (rc >= 0) - transflag = SMK_INODE_TRANSMUTE; } isp->smk_task = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp); isp->smk_mmap = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp); @@ -2730,7 +2759,7 @@ static int smack_setprocattr(struct task_struct *p, char *name, if (!capable(CAP_MAC_ADMIN)) return -EPERM; - if (value == NULL || size == 0 || size >= SMK_LONGLABEL) + if (value == NULL || size == 0 || size >= SMK_LABELLEN) return -EINVAL; if (strcmp(name, "current") != 0) @@ -2866,9 +2895,10 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, static char *smack_from_secattr(struct netlbl_lsm_secattr *sap, struct socket_smack *ssp) { - struct smack_known *kp; + struct smack_known *skp; + char smack[SMK_LABELLEN]; char *sp; - int found = 0; + int pcat; if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) { /* @@ -2876,27 +2906,59 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap, * If there are flags but no level netlabel isn't * behaving the way we expect it to. * - * Look it up in the label table + * Get the categories, if any * Without guidance regarding the smack value * for the packet fall back on the network * ambient value. */ - rcu_read_lock(); - list_for_each_entry(kp, &smack_known_list, list) { - if (sap->attr.mls.lvl != kp->smk_netlabel.attr.mls.lvl) - continue; - if (memcmp(sap->attr.mls.cat, - kp->smk_netlabel.attr.mls.cat, - SMK_CIPSOLEN) != 0) - continue; - found = 1; - break; + memset(smack, '\0', SMK_LABELLEN); + if ((sap->flags & NETLBL_SECATTR_MLS_CAT) != 0) + for (pcat = -1;;) { + pcat = netlbl_secattr_catmap_walk( + sap->attr.mls.cat, pcat + 1); + if (pcat < 0) + break; + smack_catset_bit(pcat, smack); + } + /* + * If it is CIPSO using smack direct mapping + * we are already done. WeeHee. + */ + if (sap->attr.mls.lvl == smack_cipso_direct) { + /* + * The label sent is usually on the label list. + * + * If it is not we may still want to allow the + * delivery. + * + * If the recipient is accepting all packets + * because it is using the star ("*") label + * for SMACK64IPIN provide the web ("@") label + * so that a directed response will succeed. + * This is not very correct from a MAC point + * of view, but gets around the problem that + * locking prevents adding the newly discovered + * label to the list. + * The case where the recipient is not using + * the star label should obviously fail. + * The easy way to do this is to provide the + * star label as the subject label. + */ + skp = smk_find_entry(smack); + if (skp != NULL) + return skp->smk_known; + if (ssp != NULL && + ssp->smk_in == smack_known_star.smk_known) + return smack_known_web.smk_known; + return smack_known_star.smk_known; } - rcu_read_unlock(); - - if (found) - return kp->smk_known; - + /* + * Look it up in the supplied table if it is not + * a direct mapping. + */ + sp = smack_from_cipso(sap->attr.mls.lvl, smack); + if (sp != NULL) + return sp; if (ssp != NULL && ssp->smk_in == smack_known_star.smk_known) return smack_known_web.smk_known; return smack_known_star.smk_known; @@ -3096,13 +3158,11 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, struct request_sock *req) { u16 family = sk->sk_family; - struct smack_known *skp; struct socket_smack *ssp = sk->sk_security; struct netlbl_lsm_secattr secattr; struct sockaddr_in addr; struct iphdr *hdr; char *sp; - char *hsp; int rc; struct smk_audit_info ad; #ifdef CONFIG_AUDIT @@ -3149,14 +3209,16 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, hdr = ip_hdr(skb); addr.sin_addr.s_addr = hdr->saddr; rcu_read_lock(); - hsp = smack_host_label(&addr); - rcu_read_unlock(); - - if (hsp == NULL) { - skp = smk_find_entry(sp); - rc = netlbl_req_setattr(req, &skp->smk_netlabel); - } else + if (smack_host_label(&addr) == NULL) { + rcu_read_unlock(); + netlbl_secattr_init(&secattr); + smack_to_secattr(sp, &secattr); + rc = netlbl_req_setattr(req, &secattr); + netlbl_secattr_destroy(&secattr); + } else { + rcu_read_unlock(); netlbl_req_delattr(req); + } return rc; } @@ -3338,7 +3400,7 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule, char *rule = vrule; if (!rule) { - audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, + audit_log(actx, GFP_KERNEL, AUDIT_SELINUX_ERR, "Smack: missing rule\n"); return -ENOENT; } @@ -3487,7 +3549,7 @@ struct security_operations smack_ops = { .file_send_sigiotask = smack_file_send_sigiotask, .file_receive = smack_file_receive, - .file_open = smack_file_open, + .dentry_open = smack_dentry_open, .cred_alloc_blank = smack_cred_alloc_blank, .cred_free = smack_cred_free, @@ -3580,6 +3642,15 @@ struct security_operations smack_ops = { static __init void init_smack_known_list(void) { + /* + * Initialize CIPSO locks + */ + spin_lock_init(&smack_known_huh.smk_cipsolock); + spin_lock_init(&smack_known_hat.smk_cipsolock); + spin_lock_init(&smack_known_star.smk_cipsolock); + spin_lock_init(&smack_known_floor.smk_cipsolock); + spin_lock_init(&smack_known_invalid.smk_cipsolock); + spin_lock_init(&smack_known_web.smk_cipsolock); /* * Initialize rule list locks */ diff --git a/trunk/security/smack/smackfs.c b/trunk/security/smack/smackfs.c index 1810c9a4ed48..038811cb7e62 100644 --- a/trunk/security/smack/smackfs.c +++ b/trunk/security/smack/smackfs.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -44,11 +45,6 @@ enum smk_inos { SMK_LOGGING = 10, /* logging */ SMK_LOAD_SELF = 11, /* task specific rules */ SMK_ACCESSES = 12, /* access policy */ - SMK_MAPPED = 13, /* CIPSO level indicating mapped label */ - SMK_LOAD2 = 14, /* load policy with long labels */ - SMK_LOAD_SELF2 = 15, /* load task specific rules with long labels */ - SMK_ACCESS2 = 16, /* make an access check with long labels */ - SMK_CIPSO2 = 17, /* load long label -> CIPSO mapping */ }; /* @@ -64,7 +60,7 @@ static DEFINE_MUTEX(smk_netlbladdr_lock); * If it isn't somehow marked, use this. * It can be reset via smackfs/ambient */ -char *smack_net_ambient; +char *smack_net_ambient = smack_known_floor.smk_known; /* * This is the level in a CIPSO header that indicates a @@ -73,13 +69,6 @@ char *smack_net_ambient; */ int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT; -/* - * This is the level in a CIPSO header that indicates a - * secid is contained directly in the category set. - * It can be reset via smackfs/mapped - */ -int smack_cipso_mapped = SMACK_CIPSO_MAPPED_DEFAULT; - /* * Unless a process is running with this label even * having CAP_MAC_OVERRIDE isn't enough to grant @@ -100,7 +89,7 @@ LIST_HEAD(smk_netlbladdr_list); /* * Rule lists are maintained for each label. - * This master list is just for reading /smack/load and /smack/load2. + * This master list is just for reading /smack/load. */ struct smack_master_list { struct list_head list; @@ -136,18 +125,6 @@ const char *smack_cipso_option = SMACK_CIPSO_OPTION; #define SMK_OLOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_OACCESSLEN) #define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN) -/* - * Stricly for CIPSO level manipulation. - * Set the category bit number in a smack label sized buffer. - */ -static inline void smack_catset_bit(unsigned int cat, char *catsetp) -{ - if (cat == 0 || cat > (SMK_CIPSOLEN * 8)) - return; - - catsetp[(cat - 1) / 8] |= 0x80 >> ((cat - 1) % 8); -} - /** * smk_netlabel_audit_set - fill a netlbl_audit struct * @nap: structure to fill @@ -160,10 +137,12 @@ static void smk_netlabel_audit_set(struct netlbl_audit *nap) } /* - * Value for parsing single label host rules + * Values for parsing single label host rules * "1.2.3.4 X" + * "192.168.138.129/32 abcdefghijklmnopqrstuvw" */ #define SMK_NETLBLADDRMIN 9 +#define SMK_NETLBLADDRMAX 42 /** * smk_set_access - add a rule to the rule list @@ -209,47 +188,33 @@ static int smk_set_access(struct smack_rule *srp, struct list_head *rule_list, } /** - * smk_fill_rule - Fill Smack rule from strings - * @subject: subject label string - * @object: object label string - * @access: access string + * smk_parse_rule - parse Smack rule from load string + * @data: string to be parsed whose size is SMK_LOADLEN * @rule: Smack rule * @import: if non-zero, import labels - * - * Returns 0 on success, -1 on failure */ -static int smk_fill_rule(const char *subject, const char *object, - const char *access, struct smack_rule *rule, - int import) +static int smk_parse_rule(const char *data, struct smack_rule *rule, int import) { - int rc = -1; - int done; - const char *cp; + char smack[SMK_LABELLEN]; struct smack_known *skp; if (import) { - rule->smk_subject = smk_import(subject, 0); + rule->smk_subject = smk_import(data, 0); if (rule->smk_subject == NULL) return -1; - rule->smk_object = smk_import(object, 0); + rule->smk_object = smk_import(data + SMK_LABELLEN, 0); if (rule->smk_object == NULL) return -1; } else { - cp = smk_parse_smack(subject, 0); - if (cp == NULL) - return -1; - skp = smk_find_entry(cp); - kfree(cp); + smk_parse_smack(data, 0, smack); + skp = smk_find_entry(smack); if (skp == NULL) return -1; rule->smk_subject = skp->smk_known; - cp = smk_parse_smack(object, 0); - if (cp == NULL) - return -1; - skp = smk_find_entry(cp); - kfree(cp); + smk_parse_smack(data + SMK_LABELLEN, 0, smack); + skp = smk_find_entry(smack); if (skp == NULL) return -1; rule->smk_object = skp->smk_known; @@ -257,127 +222,90 @@ static int smk_fill_rule(const char *subject, const char *object, rule->smk_access = 0; - for (cp = access, done = 0; *cp && !done; cp++) { - switch (*cp) { - case '-': - break; - case 'r': - case 'R': - rule->smk_access |= MAY_READ; - break; - case 'w': - case 'W': - rule->smk_access |= MAY_WRITE; - break; - case 'x': - case 'X': - rule->smk_access |= MAY_EXEC; - break; - case 'a': - case 'A': - rule->smk_access |= MAY_APPEND; - break; - case 't': - case 'T': - rule->smk_access |= MAY_TRANSMUTE; - break; - default: - done = 1; - break; - } + switch (data[SMK_LABELLEN + SMK_LABELLEN]) { + case '-': + break; + case 'r': + case 'R': + rule->smk_access |= MAY_READ; + break; + default: + return -1; } - rc = 0; - return rc; -} - -/** - * smk_parse_rule - parse Smack rule from load string - * @data: string to be parsed whose size is SMK_LOADLEN - * @rule: Smack rule - * @import: if non-zero, import labels - * - * Returns 0 on success, -1 on errors. - */ -static int smk_parse_rule(const char *data, struct smack_rule *rule, int import) -{ - int rc; + switch (data[SMK_LABELLEN + SMK_LABELLEN + 1]) { + case '-': + break; + case 'w': + case 'W': + rule->smk_access |= MAY_WRITE; + break; + default: + return -1; + } - rc = smk_fill_rule(data, data + SMK_LABELLEN, - data + SMK_LABELLEN + SMK_LABELLEN, rule, import); - return rc; -} + switch (data[SMK_LABELLEN + SMK_LABELLEN + 2]) { + case '-': + break; + case 'x': + case 'X': + rule->smk_access |= MAY_EXEC; + break; + default: + return -1; + } -/** - * smk_parse_long_rule - parse Smack rule from rule string - * @data: string to be parsed, null terminated - * @rule: Smack rule - * @import: if non-zero, import labels - * - * Returns 0 on success, -1 on failure - */ -static int smk_parse_long_rule(const char *data, struct smack_rule *rule, - int import) -{ - char *subject; - char *object; - char *access; - int datalen; - int rc = -1; + switch (data[SMK_LABELLEN + SMK_LABELLEN + 3]) { + case '-': + break; + case 'a': + case 'A': + rule->smk_access |= MAY_APPEND; + break; + default: + return -1; + } - /* - * This is probably inefficient, but safe. - */ - datalen = strlen(data); - subject = kzalloc(datalen, GFP_KERNEL); - if (subject == NULL) + switch (data[SMK_LABELLEN + SMK_LABELLEN + 4]) { + case '-': + break; + case 't': + case 'T': + rule->smk_access |= MAY_TRANSMUTE; + break; + default: return -1; - object = kzalloc(datalen, GFP_KERNEL); - if (object == NULL) - goto free_out_s; - access = kzalloc(datalen, GFP_KERNEL); - if (access == NULL) - goto free_out_o; - - if (sscanf(data, "%s %s %s", subject, object, access) == 3) - rc = smk_fill_rule(subject, object, access, rule, import); - - kfree(access); -free_out_o: - kfree(object); -free_out_s: - kfree(subject); - return rc; + } + + return 0; } -#define SMK_FIXED24_FMT 0 /* Fixed 24byte label format */ -#define SMK_LONG_FMT 1 /* Variable long label format */ /** - * smk_write_rules_list - write() for any /smack rule file + * smk_write_load_list - write() for any /smack/load * @file: file pointer, not actually used * @buf: where to get the data from * @count: bytes sent * @ppos: where to start - must be 0 * @rule_list: the list of rules to write to * @rule_lock: lock for the rule list - * @format: /smack/load or /smack/load2 format. * * Get one smack access rule from above. - * The format for SMK_LONG_FMT is: - * "subjectobjectaccess[...]" - * The format for SMK_FIXED24_FMT is exactly: - * "subject object rwxat" + * The format is exactly: + * char subject[SMK_LABELLEN] + * char object[SMK_LABELLEN] + * char access[SMK_ACCESSLEN] + * + * writes must be SMK_LABELLEN+SMK_LABELLEN+SMK_ACCESSLEN bytes. */ -static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, - size_t count, loff_t *ppos, - struct list_head *rule_list, - struct mutex *rule_lock, int format) +static ssize_t smk_write_load_list(struct file *file, const char __user *buf, + size_t count, loff_t *ppos, + struct list_head *rule_list, + struct mutex *rule_lock) { struct smack_master_list *smlp; struct smack_known *skp; struct smack_rule *rule; char *data; - int datalen; int rc = -EINVAL; int load = 0; @@ -387,18 +315,13 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, */ if (*ppos != 0) return -EINVAL; + /* + * Minor hack for backward compatibility + */ + if (count < (SMK_OLOADLEN) || count > SMK_LOADLEN) + return -EINVAL; - if (format == SMK_FIXED24_FMT) { - /* - * Minor hack for backward compatibility - */ - if (count != SMK_OLOADLEN && count != SMK_LOADLEN) - return -EINVAL; - datalen = SMK_LOADLEN; - } else - datalen = count + 1; - - data = kzalloc(datalen, GFP_KERNEL); + data = kzalloc(SMK_LOADLEN, GFP_KERNEL); if (data == NULL) return -ENOMEM; @@ -407,29 +330,20 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, goto out; } + /* + * More on the minor hack for backward compatibility + */ + if (count == (SMK_OLOADLEN)) + data[SMK_OLOADLEN] = '-'; + rule = kzalloc(sizeof(*rule), GFP_KERNEL); if (rule == NULL) { rc = -ENOMEM; goto out; } - if (format == SMK_LONG_FMT) { - /* - * Be sure the data string is terminated. - */ - data[count] = '\0'; - if (smk_parse_long_rule(data, rule, 1)) - goto out_free_rule; - } else { - /* - * More on the minor hack for backward compatibility - */ - if (count == (SMK_OLOADLEN)) - data[SMK_OLOADLEN] = '-'; - if (smk_parse_rule(data, rule, 1)) - goto out_free_rule; - } - + if (smk_parse_rule(data, rule, 1)) + goto out_free_rule; if (rule_list == NULL) { load = 1; @@ -440,20 +354,18 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, rc = count; /* - * If this is a global as opposed to self and a new rule + * If this is "load" as opposed to "load-self" and a new rule * it needs to get added for reporting. * smk_set_access returns true if there was already a rule * for the subject/object pair, and false if it was new. */ - if (!smk_set_access(rule, rule_list, rule_lock)) { - if (load) { - smlp = kzalloc(sizeof(*smlp), GFP_KERNEL); - if (smlp != NULL) { - smlp->smk_rule = rule; - list_add_rcu(&smlp->list, &smack_rule_list); - } else - rc = -ENOMEM; - } + if (load && !smk_set_access(rule, rule_list, rule_lock)) { + smlp = kzalloc(sizeof(*smlp), GFP_KERNEL); + if (smlp != NULL) { + smlp->smk_rule = rule; + list_add_rcu(&smlp->list, &smack_rule_list); + } else + rc = -ENOMEM; goto out; } @@ -509,18 +421,29 @@ static void smk_seq_stop(struct seq_file *s, void *v) /* No-op */ } -static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max) +/* + * Seq_file read operations for /smack/load + */ + +static void *load_seq_start(struct seq_file *s, loff_t *pos) +{ + return smk_seq_start(s, pos, &smack_rule_list); +} + +static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos) { - /* - * Don't show any rules with label names too long for - * interface file (/smack/load or /smack/load2) - * because you should expect to be able to write - * anything you read back. - */ - if (strlen(srp->smk_subject) >= max || strlen(srp->smk_object) >= max) - return; + return smk_seq_next(s, v, pos, &smack_rule_list); +} + +static int load_seq_show(struct seq_file *s, void *v) +{ + struct list_head *list = v; + struct smack_master_list *smlp = + list_entry(list, struct smack_master_list, list); + struct smack_rule *srp = smlp->smk_rule; - seq_printf(s, "%s %s", srp->smk_subject, srp->smk_object); + seq_printf(s, "%s %s", (char *)srp->smk_subject, + (char *)srp->smk_object); seq_putc(s, ' '); @@ -538,36 +461,13 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max) seq_putc(s, '-'); seq_putc(s, '\n'); -} - -/* - * Seq_file read operations for /smack/load - */ - -static void *load2_seq_start(struct seq_file *s, loff_t *pos) -{ - return smk_seq_start(s, pos, &smack_rule_list); -} - -static void *load2_seq_next(struct seq_file *s, void *v, loff_t *pos) -{ - return smk_seq_next(s, v, pos, &smack_rule_list); -} - -static int load_seq_show(struct seq_file *s, void *v) -{ - struct list_head *list = v; - struct smack_master_list *smlp = - list_entry(list, struct smack_master_list, list); - - smk_rule_show(s, smlp->smk_rule, SMK_LABELLEN); return 0; } static const struct seq_operations load_seq_ops = { - .start = load2_seq_start, - .next = load2_seq_next, + .start = load_seq_start, + .next = load_seq_next, .show = load_seq_show, .stop = smk_seq_stop, }; @@ -604,8 +504,7 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf, if (!capable(CAP_MAC_ADMIN)) return -EPERM; - return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, - SMK_FIXED24_FMT); + return smk_write_load_list(file, buf, count, ppos, NULL, NULL); } static const struct file_operations smk_load_ops = { @@ -675,8 +574,6 @@ static void smk_unlbl_ambient(char *oldambient) printk(KERN_WARNING "%s:%d remove rc = %d\n", __func__, __LINE__, rc); } - if (smack_net_ambient == NULL) - smack_net_ambient = smack_known_floor.smk_known; rc = netlbl_cfg_unlbl_map_add(smack_net_ambient, PF_INET, NULL, NULL, &nai); @@ -708,28 +605,27 @@ static int cipso_seq_show(struct seq_file *s, void *v) struct list_head *list = v; struct smack_known *skp = list_entry(list, struct smack_known, list); - struct netlbl_lsm_secattr_catmap *cmp = skp->smk_netlabel.attr.mls.cat; + struct smack_cipso *scp = skp->smk_cipso; + char *cbp; char sep = '/'; + int cat = 1; int i; + unsigned char m; - /* - * Don't show a label that could not have been set using - * /smack/cipso. This is in support of the notion that - * anything read from /smack/cipso ought to be writeable - * to /smack/cipso. - * - * /smack/cipso2 should be used instead. - */ - if (strlen(skp->smk_known) >= SMK_LABELLEN) + if (scp == NULL) return 0; - seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl); + seq_printf(s, "%s %3d", (char *)&skp->smk_known, scp->smk_level); - for (i = netlbl_secattr_catmap_walk(cmp, 0); i >= 0; - i = netlbl_secattr_catmap_walk(cmp, i + 1)) { - seq_printf(s, "%c%d", sep, i); - sep = ','; - } + cbp = scp->smk_catset; + for (i = 0; i < SMK_LABELLEN; i++) + for (m = 0x80; m != 0; m >>= 1) { + if (m & cbp[i]) { + seq_printf(s, "%c%d", sep, cat); + sep = ','; + } + cat++; + } seq_putc(s, '\n'); @@ -757,24 +653,23 @@ static int smk_open_cipso(struct inode *inode, struct file *file) } /** - * smk_set_cipso - do the work for write() for cipso and cipso2 + * smk_write_cipso - write() for /smack/cipso * @file: file pointer, not actually used * @buf: where to get the data from * @count: bytes sent * @ppos: where to start - * @format: /smack/cipso or /smack/cipso2 * * Accepts only one cipso rule per write call. * Returns number of bytes written or error code, as appropriate */ -static ssize_t smk_set_cipso(struct file *file, const char __user *buf, - size_t count, loff_t *ppos, int format) +static ssize_t smk_write_cipso(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) { struct smack_known *skp; - struct netlbl_lsm_secattr ncats; - char mapcatset[SMK_CIPSOLEN]; + struct smack_cipso *scp = NULL; + char mapcatset[SMK_LABELLEN]; int maplevel; - unsigned int cat; + int cat; int catlen; ssize_t rc = -EINVAL; char *data = NULL; @@ -791,8 +686,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, return -EPERM; if (*ppos != 0) return -EINVAL; - if (format == SMK_FIXED24_FMT && - (count < SMK_CIPSOMIN || count > SMK_CIPSOMAX)) + if (count < SMK_CIPSOMIN || count > SMK_CIPSOMAX) return -EINVAL; data = kzalloc(count + 1, GFP_KERNEL); @@ -804,6 +698,11 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, goto unlockedout; } + /* labels cannot begin with a '-' */ + if (data[0] == '-') { + rc = -EINVAL; + goto unlockedout; + } data[count] = '\0'; rule = data; /* @@ -816,11 +715,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, if (skp == NULL) goto out; - if (format == SMK_FIXED24_FMT) - rule += SMK_LABELLEN; - else - rule += strlen(skp->smk_known); - + rule += SMK_LABELLEN; ret = sscanf(rule, "%d", &maplevel); if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL) goto out; @@ -830,29 +725,41 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM) goto out; - if (format == SMK_FIXED24_FMT && - count != (SMK_CIPSOMIN + catlen * SMK_DIGITLEN)) + if (count != (SMK_CIPSOMIN + catlen * SMK_DIGITLEN)) goto out; memset(mapcatset, 0, sizeof(mapcatset)); for (i = 0; i < catlen; i++) { rule += SMK_DIGITLEN; - ret = sscanf(rule, "%u", &cat); + ret = sscanf(rule, "%d", &cat); if (ret != 1 || cat > SMACK_CIPSO_MAXCATVAL) goto out; smack_catset_bit(cat, mapcatset); } - rc = smk_netlbl_mls(maplevel, mapcatset, &ncats, SMK_CIPSOLEN); - if (rc >= 0) { - netlbl_secattr_catmap_free(skp->smk_netlabel.attr.mls.cat); - skp->smk_netlabel.attr.mls.cat = ncats.attr.mls.cat; - skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl; - rc = count; + if (skp->smk_cipso == NULL) { + scp = kzalloc(sizeof(struct smack_cipso), GFP_KERNEL); + if (scp == NULL) { + rc = -ENOMEM; + goto out; + } } + spin_lock_bh(&skp->smk_cipsolock); + + if (scp == NULL) + scp = skp->smk_cipso; + else + skp->smk_cipso = scp; + + scp->smk_level = maplevel; + memcpy(scp->smk_catset, mapcatset, sizeof(mapcatset)); + + spin_unlock_bh(&skp->smk_cipsolock); + + rc = count; out: mutex_unlock(&smack_cipso_lock); unlockedout: @@ -860,22 +767,6 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, return rc; } -/** - * smk_write_cipso - write() for /smack/cipso - * @file: file pointer, not actually used - * @buf: where to get the data from - * @count: bytes sent - * @ppos: where to start - * - * Accepts only one cipso rule per write call. - * Returns number of bytes written or error code, as appropriate - */ -static ssize_t smk_write_cipso(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - return smk_set_cipso(file, buf, count, ppos, SMK_FIXED24_FMT); -} - static const struct file_operations smk_cipso_ops = { .open = smk_open_cipso, .read = seq_read, @@ -884,80 +775,6 @@ static const struct file_operations smk_cipso_ops = { .release = seq_release, }; -/* - * Seq_file read operations for /smack/cipso2 - */ - -/* - * Print cipso labels in format: - * label level[/cat[,cat]] - */ -static int cipso2_seq_show(struct seq_file *s, void *v) -{ - struct list_head *list = v; - struct smack_known *skp = - list_entry(list, struct smack_known, list); - struct netlbl_lsm_secattr_catmap *cmp = skp->smk_netlabel.attr.mls.cat; - char sep = '/'; - int i; - - seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl); - - for (i = netlbl_secattr_catmap_walk(cmp, 0); i >= 0; - i = netlbl_secattr_catmap_walk(cmp, i + 1)) { - seq_printf(s, "%c%d", sep, i); - sep = ','; - } - - seq_putc(s, '\n'); - - return 0; -} - -static const struct seq_operations cipso2_seq_ops = { - .start = cipso_seq_start, - .next = cipso_seq_next, - .show = cipso2_seq_show, - .stop = smk_seq_stop, -}; - -/** - * smk_open_cipso2 - open() for /smack/cipso2 - * @inode: inode structure representing file - * @file: "cipso2" file pointer - * - * Connect our cipso_seq_* operations with /smack/cipso2 - * file_operations - */ -static int smk_open_cipso2(struct inode *inode, struct file *file) -{ - return seq_open(file, &cipso2_seq_ops); -} - -/** - * smk_write_cipso2 - write() for /smack/cipso2 - * @file: file pointer, not actually used - * @buf: where to get the data from - * @count: bytes sent - * @ppos: where to start - * - * Accepts only one cipso rule per write call. - * Returns number of bytes written or error code, as appropriate - */ -static ssize_t smk_write_cipso2(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - return smk_set_cipso(file, buf, count, ppos, SMK_LONG_FMT); -} - -static const struct file_operations smk_cipso2_ops = { - .open = smk_open_cipso2, - .read = seq_read, - .llseek = seq_lseek, - .write = smk_write_cipso2, - .release = seq_release, -}; - /* * Seq_file read operations for /smack/netlabel */ @@ -1070,9 +887,9 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, { struct smk_netlbladdr *skp; struct sockaddr_in newname; - char *smack; + char smack[SMK_LABELLEN]; char *sp; - char *data; + char data[SMK_NETLBLADDRMAX + 1]; char *host = (char *)&newname.sin_addr.s_addr; int rc; struct netlbl_audit audit_info; @@ -1094,23 +911,10 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, return -EPERM; if (*ppos != 0) return -EINVAL; - if (count < SMK_NETLBLADDRMIN) + if (count < SMK_NETLBLADDRMIN || count > SMK_NETLBLADDRMAX) return -EINVAL; - - data = kzalloc(count + 1, GFP_KERNEL); - if (data == NULL) - return -ENOMEM; - - if (copy_from_user(data, buf, count) != 0) { - rc = -EFAULT; - goto free_data_out; - } - - smack = kzalloc(count + 1, GFP_KERNEL); - if (smack == NULL) { - rc = -ENOMEM; - goto free_data_out; - } + if (copy_from_user(data, buf, count) != 0) + return -EFAULT; data[count] = '\0'; @@ -1119,34 +923,24 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, if (rc != 6) { rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s", &host[0], &host[1], &host[2], &host[3], smack); - if (rc != 5) { - rc = -EINVAL; - goto free_out; - } + if (rc != 5) + return -EINVAL; m = BEBITS; } - if (m > BEBITS) { - rc = -EINVAL; - goto free_out; - } + if (m > BEBITS) + return -EINVAL; - /* - * If smack begins with '-', it is an option, don't import it - */ + /* if smack begins with '-', its an option, don't import it */ if (smack[0] != '-') { sp = smk_import(smack, 0); - if (sp == NULL) { - rc = -EINVAL; - goto free_out; - } + if (sp == NULL) + return -EINVAL; } else { /* check known options */ if (strcmp(smack, smack_cipso_option) == 0) sp = (char *)smack_cipso_option; - else { - rc = -EINVAL; - goto free_out; - } + else + return -EINVAL; } for (temp_mask = 0; m > 0; m--) { @@ -1212,11 +1006,6 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, mutex_unlock(&smk_netlbladdr_lock); -free_out: - kfree(smack); -free_data_out: - kfree(data); - return rc; } @@ -1330,7 +1119,6 @@ static ssize_t smk_read_direct(struct file *filp, char __user *buf, static ssize_t smk_write_direct(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - struct smack_known *skp; char temp[80]; int i; @@ -1348,20 +1136,7 @@ static ssize_t smk_write_direct(struct file *file, const char __user *buf, if (sscanf(temp, "%d", &i) != 1) return -EINVAL; - /* - * Don't do anything if the value hasn't actually changed. - * If it is changing reset the level on entries that were - * set up to be direct when they were created. - */ - if (smack_cipso_direct != i) { - mutex_lock(&smack_known_lock); - list_for_each_entry_rcu(skp, &smack_known_list, list) - if (skp->smk_netlabel.attr.mls.lvl == - smack_cipso_direct) - skp->smk_netlabel.attr.mls.lvl = i; - smack_cipso_direct = i; - mutex_unlock(&smack_known_lock); - } + smack_cipso_direct = i; return count; } @@ -1372,84 +1147,6 @@ static const struct file_operations smk_direct_ops = { .llseek = default_llseek, }; -/** - * smk_read_mapped - read() for /smack/mapped - * @filp: file pointer, not actually used - * @buf: where to put the result - * @count: maximum to send along - * @ppos: where to start - * - * Returns number of bytes read or error code, as appropriate - */ -static ssize_t smk_read_mapped(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - char temp[80]; - ssize_t rc; - - if (*ppos != 0) - return 0; - - sprintf(temp, "%d", smack_cipso_mapped); - rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp)); - - return rc; -} - -/** - * smk_write_mapped - write() for /smack/mapped - * @file: file pointer, not actually used - * @buf: where to get the data from - * @count: bytes sent - * @ppos: where to start - * - * Returns number of bytes written or error code, as appropriate - */ -static ssize_t smk_write_mapped(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct smack_known *skp; - char temp[80]; - int i; - - if (!capable(CAP_MAC_ADMIN)) - return -EPERM; - - if (count >= sizeof(temp) || count == 0) - return -EINVAL; - - if (copy_from_user(temp, buf, count) != 0) - return -EFAULT; - - temp[count] = '\0'; - - if (sscanf(temp, "%d", &i) != 1) - return -EINVAL; - - /* - * Don't do anything if the value hasn't actually changed. - * If it is changing reset the level on entries that were - * set up to be mapped when they were created. - */ - if (smack_cipso_mapped != i) { - mutex_lock(&smack_known_lock); - list_for_each_entry_rcu(skp, &smack_known_list, list) - if (skp->smk_netlabel.attr.mls.lvl == - smack_cipso_mapped) - skp->smk_netlabel.attr.mls.lvl = i; - smack_cipso_mapped = i; - mutex_unlock(&smack_known_lock); - } - - return count; -} - -static const struct file_operations smk_mapped_ops = { - .read = smk_read_mapped, - .write = smk_write_mapped, - .llseek = default_llseek, -}; - /** * smk_read_ambient - read() for /smack/ambient * @filp: file pointer, not actually used @@ -1498,28 +1195,22 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf, static ssize_t smk_write_ambient(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { + char in[SMK_LABELLEN]; char *oldambient; - char *smack = NULL; - char *data; - int rc = count; + char *smack; if (!capable(CAP_MAC_ADMIN)) return -EPERM; - data = kzalloc(count + 1, GFP_KERNEL); - if (data == NULL) - return -ENOMEM; + if (count >= SMK_LABELLEN) + return -EINVAL; - if (copy_from_user(data, buf, count) != 0) { - rc = -EFAULT; - goto out; - } + if (copy_from_user(in, buf, count) != 0) + return -EFAULT; - smack = smk_import(data, count); - if (smack == NULL) { - rc = -EINVAL; - goto out; - } + smack = smk_import(in, count); + if (smack == NULL) + return -EINVAL; mutex_lock(&smack_ambient_lock); @@ -1529,9 +1220,7 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf, mutex_unlock(&smack_ambient_lock); -out: - kfree(data); - return rc; + return count; } static const struct file_operations smk_ambient_ops = { @@ -1582,9 +1271,8 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf, static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - char *data; + char in[SMK_LABELLEN]; char *sp = smk_of_task(current->cred->security); - int rc = count; if (!capable(CAP_MAC_ADMIN)) return -EPERM; @@ -1597,9 +1285,11 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, if (smack_onlycap != NULL && smack_onlycap != sp) return -EPERM; - data = kzalloc(count, GFP_KERNEL); - if (data == NULL) - return -ENOMEM; + if (count >= SMK_LABELLEN) + return -EINVAL; + + if (copy_from_user(in, buf, count) != 0) + return -EFAULT; /* * Should the null string be passed in unset the onlycap value. @@ -1607,17 +1297,10 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, * smk_import only expects to return NULL for errors. It * is usually the case that a nullstring or "\n" would be * bad to pass to smk_import but in fact this is useful here. - * - * smk_import will also reject a label beginning with '-', - * so "-usecapabilities" will also work. */ - if (copy_from_user(data, buf, count) != 0) - rc = -EFAULT; - else - smack_onlycap = smk_import(data, count); + smack_onlycap = smk_import(in, count); - kfree(data); - return rc; + return count; } static const struct file_operations smk_onlycap_ops = { @@ -1715,7 +1398,25 @@ static int load_self_seq_show(struct seq_file *s, void *v) struct smack_rule *srp = list_entry(list, struct smack_rule, list); - smk_rule_show(s, srp, SMK_LABELLEN); + seq_printf(s, "%s %s", (char *)srp->smk_subject, + (char *)srp->smk_object); + + seq_putc(s, ' '); + + if (srp->smk_access & MAY_READ) + seq_putc(s, 'r'); + if (srp->smk_access & MAY_WRITE) + seq_putc(s, 'w'); + if (srp->smk_access & MAY_EXEC) + seq_putc(s, 'x'); + if (srp->smk_access & MAY_APPEND) + seq_putc(s, 'a'); + if (srp->smk_access & MAY_TRANSMUTE) + seq_putc(s, 't'); + if (srp->smk_access == 0) + seq_putc(s, '-'); + + seq_putc(s, '\n'); return 0; } @@ -1729,7 +1430,7 @@ static const struct seq_operations load_self_seq_ops = { /** - * smk_open_load_self - open() for /smack/load-self2 + * smk_open_load_self - open() for /smack/load-self * @inode: inode structure representing file * @file: "load" file pointer * @@ -1753,8 +1454,8 @@ static ssize_t smk_write_load_self(struct file *file, const char __user *buf, { struct task_smack *tsp = current_security(); - return smk_write_rules_list(file, buf, count, ppos, &tsp->smk_rules, - &tsp->smk_rules_lock, SMK_FIXED24_FMT); + return smk_write_load_list(file, buf, count, ppos, &tsp->smk_rules, + &tsp->smk_rules_lock); } static const struct file_operations smk_load_self_ops = { @@ -1766,42 +1467,24 @@ static const struct file_operations smk_load_self_ops = { }; /** - * smk_user_access - handle access check transaction + * smk_write_access - handle access check transaction * @file: file pointer * @buf: data from user space * @count: bytes sent * @ppos: where to start - must be 0 */ -static ssize_t smk_user_access(struct file *file, const char __user *buf, - size_t count, loff_t *ppos, int format) +static ssize_t smk_write_access(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) { struct smack_rule rule; char *data; - char *cod; int res; data = simple_transaction_get(file, buf, count); if (IS_ERR(data)) return PTR_ERR(data); - if (format == SMK_FIXED24_FMT) { - if (count < SMK_LOADLEN) - return -EINVAL; - res = smk_parse_rule(data, &rule, 0); - } else { - /* - * Copy the data to make sure the string is terminated. - */ - cod = kzalloc(count + 1, GFP_KERNEL); - if (cod == NULL) - return -ENOMEM; - memcpy(cod, data, count); - cod[count] = '\0'; - res = smk_parse_long_rule(cod, &rule, 0); - kfree(cod); - } - - if (res) + if (count < SMK_LOADLEN || smk_parse_rule(data, &rule, 0)) return -EINVAL; res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access, @@ -1810,23 +1493,7 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf, data[1] = '\0'; simple_transaction_set(file, 2); - - if (format == SMK_FIXED24_FMT) - return SMK_LOADLEN; - return count; -} - -/** - * smk_write_access - handle access check transaction - * @file: file pointer - * @buf: data from user space - * @count: bytes sent - * @ppos: where to start - must be 0 - */ -static ssize_t smk_write_access(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - return smk_user_access(file, buf, count, ppos, SMK_FIXED24_FMT); + return SMK_LOADLEN; } static const struct file_operations smk_access_ops = { @@ -1836,163 +1503,6 @@ static const struct file_operations smk_access_ops = { .llseek = generic_file_llseek, }; - -/* - * Seq_file read operations for /smack/load2 - */ - -static int load2_seq_show(struct seq_file *s, void *v) -{ - struct list_head *list = v; - struct smack_master_list *smlp = - list_entry(list, struct smack_master_list, list); - - smk_rule_show(s, smlp->smk_rule, SMK_LONGLABEL); - - return 0; -} - -static const struct seq_operations load2_seq_ops = { - .start = load2_seq_start, - .next = load2_seq_next, - .show = load2_seq_show, - .stop = smk_seq_stop, -}; - -/** - * smk_open_load2 - open() for /smack/load2 - * @inode: inode structure representing file - * @file: "load2" file pointer - * - * For reading, use load2_seq_* seq_file reading operations. - */ -static int smk_open_load2(struct inode *inode, struct file *file) -{ - return seq_open(file, &load2_seq_ops); -} - -/** - * smk_write_load2 - write() for /smack/load2 - * @file: file pointer, not actually used - * @buf: where to get the data from - * @count: bytes sent - * @ppos: where to start - must be 0 - * - */ -static ssize_t smk_write_load2(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - /* - * Must have privilege. - */ - if (!capable(CAP_MAC_ADMIN)) - return -EPERM; - - return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, - SMK_LONG_FMT); -} - -static const struct file_operations smk_load2_ops = { - .open = smk_open_load2, - .read = seq_read, - .llseek = seq_lseek, - .write = smk_write_load2, - .release = seq_release, -}; - -/* - * Seq_file read operations for /smack/load-self2 - */ - -static void *load_self2_seq_start(struct seq_file *s, loff_t *pos) -{ - struct task_smack *tsp = current_security(); - - return smk_seq_start(s, pos, &tsp->smk_rules); -} - -static void *load_self2_seq_next(struct seq_file *s, void *v, loff_t *pos) -{ - struct task_smack *tsp = current_security(); - - return smk_seq_next(s, v, pos, &tsp->smk_rules); -} - -static int load_self2_seq_show(struct seq_file *s, void *v) -{ - struct list_head *list = v; - struct smack_rule *srp = - list_entry(list, struct smack_rule, list); - - smk_rule_show(s, srp, SMK_LONGLABEL); - - return 0; -} - -static const struct seq_operations load_self2_seq_ops = { - .start = load_self2_seq_start, - .next = load_self2_seq_next, - .show = load_self2_seq_show, - .stop = smk_seq_stop, -}; - -/** - * smk_open_load_self2 - open() for /smack/load-self2 - * @inode: inode structure representing file - * @file: "load" file pointer - * - * For reading, use load_seq_* seq_file reading operations. - */ -static int smk_open_load_self2(struct inode *inode, struct file *file) -{ - return seq_open(file, &load_self2_seq_ops); -} - -/** - * smk_write_load_self2 - write() for /smack/load-self2 - * @file: file pointer, not actually used - * @buf: where to get the data from - * @count: bytes sent - * @ppos: where to start - must be 0 - * - */ -static ssize_t smk_write_load_self2(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct task_smack *tsp = current_security(); - - return smk_write_rules_list(file, buf, count, ppos, &tsp->smk_rules, - &tsp->smk_rules_lock, SMK_LONG_FMT); -} - -static const struct file_operations smk_load_self2_ops = { - .open = smk_open_load_self2, - .read = seq_read, - .llseek = seq_lseek, - .write = smk_write_load_self2, - .release = seq_release, -}; - -/** - * smk_write_access2 - handle access check transaction - * @file: file pointer - * @buf: data from user space - * @count: bytes sent - * @ppos: where to start - must be 0 - */ -static ssize_t smk_write_access2(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - return smk_user_access(file, buf, count, ppos, SMK_LONG_FMT); -} - -static const struct file_operations smk_access2_ops = { - .write = smk_write_access2, - .read = simple_transaction_read, - .release = simple_transaction_release, - .llseek = generic_file_llseek, -}; - /** * smk_fill_super - fill the /smackfs superblock * @sb: the empty superblock @@ -2029,16 +1539,6 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) "load-self", &smk_load_self_ops, S_IRUGO|S_IWUGO}, [SMK_ACCESSES] = { "access", &smk_access_ops, S_IRUGO|S_IWUGO}, - [SMK_MAPPED] = { - "mapped", &smk_mapped_ops, S_IRUGO|S_IWUSR}, - [SMK_LOAD2] = { - "load2", &smk_load2_ops, S_IRUGO|S_IWUSR}, - [SMK_LOAD_SELF2] = { - "load-self2", &smk_load_self2_ops, S_IRUGO|S_IWUGO}, - [SMK_ACCESS2] = { - "access2", &smk_access2_ops, S_IRUGO|S_IWUGO}, - [SMK_CIPSO2] = { - "cipso2", &smk_cipso2_ops, S_IRUGO|S_IWUSR}, /* last one */ {""} }; @@ -2081,15 +1581,6 @@ static struct file_system_type smk_fs_type = { static struct vfsmount *smackfs_mount; -static int __init smk_preset_netlabel(struct smack_known *skp) -{ - skp->smk_netlabel.domain = skp->smk_known; - skp->smk_netlabel.flags = - NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL; - return smk_netlbl_mls(smack_cipso_direct, skp->smk_known, - &skp->smk_netlabel, strlen(skp->smk_known)); -} - /** * init_smk_fs - get the smackfs superblock * @@ -2106,7 +1597,6 @@ static int __init smk_preset_netlabel(struct smack_known *skp) static int __init init_smk_fs(void) { int err; - int rc; if (!security_module_enable(&smack_ops)) return 0; @@ -2124,25 +1614,6 @@ static int __init init_smk_fs(void) smk_cipso_doi(); smk_unlbl_ambient(NULL); - rc = smk_preset_netlabel(&smack_known_floor); - if (err == 0 && rc < 0) - err = rc; - rc = smk_preset_netlabel(&smack_known_hat); - if (err == 0 && rc < 0) - err = rc; - rc = smk_preset_netlabel(&smack_known_huh); - if (err == 0 && rc < 0) - err = rc; - rc = smk_preset_netlabel(&smack_known_invalid); - if (err == 0 && rc < 0) - err = rc; - rc = smk_preset_netlabel(&smack_known_star); - if (err == 0 && rc < 0) - err = rc; - rc = smk_preset_netlabel(&smack_known_web); - if (err == 0 && rc < 0) - err = rc; - return err; } diff --git a/trunk/security/tomoyo/common.c b/trunk/security/tomoyo/common.c index 2e0f12c62938..8656b16eef7b 100644 --- a/trunk/security/tomoyo/common.c +++ b/trunk/security/tomoyo/common.c @@ -850,9 +850,14 @@ static int tomoyo_update_manager_entry(const char *manager, policy_list[TOMOYO_ID_MANAGER], }; int error = is_delete ? -ENOENT : -ENOMEM; - if (!tomoyo_correct_domain(manager) && - !tomoyo_correct_word(manager)) - return -EINVAL; + if (tomoyo_domain_def(manager)) { + if (!tomoyo_correct_domain(manager)) + return -EINVAL; + e.is_domain = true; + } else { + if (!tomoyo_correct_path(manager)) + return -EINVAL; + } e.manager = tomoyo_get_name(manager); if (e.manager) { error = tomoyo_update_policy(&e.head, sizeof(e), ¶m, @@ -927,14 +932,23 @@ static bool tomoyo_manager(void) return true; if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid)) return false; + list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace. + policy_list[TOMOYO_ID_MANAGER], head.list) { + if (!ptr->head.is_deleted && ptr->is_domain + && !tomoyo_pathcmp(domainname, ptr->manager)) { + found = true; + break; + } + } + if (found) + return true; exe = tomoyo_get_exe(); if (!exe) return false; list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace. policy_list[TOMOYO_ID_MANAGER], head.list) { - if (!ptr->head.is_deleted && - (!tomoyo_pathcmp(domainname, ptr->manager) || - !strcmp(exe, ptr->manager->name))) { + if (!ptr->head.is_deleted && !ptr->is_domain + && !strcmp(exe, ptr->manager->name)) { found = true; break; } diff --git a/trunk/security/tomoyo/common.h b/trunk/security/tomoyo/common.h index 75e4dc1c02a0..30fd98369700 100644 --- a/trunk/security/tomoyo/common.h +++ b/trunk/security/tomoyo/common.h @@ -860,6 +860,7 @@ struct tomoyo_aggregator { /* Structure for policy manager. */ struct tomoyo_manager { struct tomoyo_acl_head head; + bool is_domain; /* True if manager is a domainname. */ /* A path to program or a domainname. */ const struct tomoyo_path_info *manager; }; diff --git a/trunk/security/tomoyo/tomoyo.c b/trunk/security/tomoyo/tomoyo.c index c2d04a50f76a..620d37c159a3 100644 --- a/trunk/security/tomoyo/tomoyo.c +++ b/trunk/security/tomoyo/tomoyo.c @@ -319,14 +319,14 @@ static int tomoyo_file_fcntl(struct file *file, unsigned int cmd, } /** - * tomoyo_file_open - Target for security_file_open(). + * tomoyo_dentry_open - Target for security_dentry_open(). * * @f: Pointer to "struct file". * @cred: Pointer to "struct cred". * * Returns 0 on success, negative value otherwise. */ -static int tomoyo_file_open(struct file *f, const struct cred *cred) +static int tomoyo_dentry_open(struct file *f, const struct cred *cred) { int flags = f->f_flags; /* Don't check read permission here if called from do_execve(). */ @@ -510,7 +510,7 @@ static struct security_operations tomoyo_security_ops = { .bprm_set_creds = tomoyo_bprm_set_creds, .bprm_check_security = tomoyo_bprm_check_security, .file_fcntl = tomoyo_file_fcntl, - .file_open = tomoyo_file_open, + .dentry_open = tomoyo_dentry_open, .path_truncate = tomoyo_path_truncate, .path_unlink = tomoyo_path_unlink, .path_mkdir = tomoyo_path_mkdir, diff --git a/trunk/security/yama/yama_lsm.c b/trunk/security/yama/yama_lsm.c index 83554ee8a587..573723843a04 100644 --- a/trunk/security/yama/yama_lsm.c +++ b/trunk/security/yama/yama_lsm.c @@ -18,12 +18,7 @@ #include #include -#define YAMA_SCOPE_DISABLED 0 -#define YAMA_SCOPE_RELATIONAL 1 -#define YAMA_SCOPE_CAPABILITY 2 -#define YAMA_SCOPE_NO_ATTACH 3 - -static int ptrace_scope = YAMA_SCOPE_RELATIONAL; +static int ptrace_scope = 1; /* describe a ptrace relationship for potential exception */ struct ptrace_relation { @@ -256,32 +251,17 @@ static int yama_ptrace_access_check(struct task_struct *child, return rc; /* require ptrace target be a child of ptracer on attach */ - if (mode == PTRACE_MODE_ATTACH) { - switch (ptrace_scope) { - case YAMA_SCOPE_DISABLED: - /* No additional restrictions. */ - break; - case YAMA_SCOPE_RELATIONAL: - if (!task_is_descendant(current, child) && - !ptracer_exception_found(current, child) && - !ns_capable(task_user_ns(child), CAP_SYS_PTRACE)) - rc = -EPERM; - break; - case YAMA_SCOPE_CAPABILITY: - if (!ns_capable(task_user_ns(child), CAP_SYS_PTRACE)) - rc = -EPERM; - break; - case YAMA_SCOPE_NO_ATTACH: - default: - rc = -EPERM; - break; - } - } + if (mode == PTRACE_MODE_ATTACH && + ptrace_scope && + !task_is_descendant(current, child) && + !ptracer_exception_found(current, child) && + !capable(CAP_SYS_PTRACE)) + rc = -EPERM; if (rc) { char name[sizeof(current->comm)]; - printk_ratelimited(KERN_NOTICE - "ptrace of pid %d was attempted by: %s (pid %d)\n", + printk_ratelimited(KERN_NOTICE "ptrace of non-child" + " pid %d was attempted by: %s (pid %d)\n", child->pid, get_task_comm(name, current), current->pid); @@ -299,27 +279,8 @@ static struct security_operations yama_ops = { }; #ifdef CONFIG_SYSCTL -static int yama_dointvec_minmax(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) -{ - int rc; - - if (write && !capable(CAP_SYS_PTRACE)) - return -EPERM; - - rc = proc_dointvec_minmax(table, write, buffer, lenp, ppos); - if (rc) - return rc; - - /* Lock the max value if it ever gets set. */ - if (write && *(int *)table->data == *(int *)table->extra2) - table->extra1 = table->extra2; - - return rc; -} - static int zero; -static int max_scope = YAMA_SCOPE_NO_ATTACH; +static int one = 1; struct ctl_path yama_sysctl_path[] = { { .procname = "kernel", }, @@ -333,9 +294,9 @@ static struct ctl_table yama_sysctl_table[] = { .data = &ptrace_scope, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = yama_dointvec_minmax, + .proc_handler = proc_dointvec_minmax, .extra1 = &zero, - .extra2 = &max_scope, + .extra2 = &one, }, { } }; diff --git a/trunk/sound/pci/echoaudio/echoaudio_dsp.c b/trunk/sound/pci/echoaudio/echoaudio_dsp.c index d8c670c9d62c..64417a733220 100644 --- a/trunk/sound/pci/echoaudio/echoaudio_dsp.c +++ b/trunk/sound/pci/echoaudio/echoaudio_dsp.c @@ -475,7 +475,7 @@ static int load_firmware(struct echoaudio *chip) const struct firmware *fw; int box_type, err; - if (snd_BUG_ON(!chip->comm_page)) + if (snd_BUG_ON(!chip->dsp_code_to_load || !chip->comm_page)) return -EPERM; /* See if the ASIC is present and working - only if the DSP is already loaded */ diff --git a/trunk/sound/pci/hda/hda_codec.c b/trunk/sound/pci/hda/hda_codec.c index 841475cc13b6..7a8fcc4c15f8 100644 --- a/trunk/sound/pci/hda/hda_codec.c +++ b/trunk/sound/pci/hda/hda_codec.c @@ -5444,6 +5444,10 @@ int snd_hda_suspend(struct hda_bus *bus) list_for_each_entry(codec, &bus->codec_list, list) { if (hda_codec_is_power_on(codec)) hda_call_codec_suspend(codec); + else /* forcibly change the power to D3 even if not used */ + hda_set_power_state(codec, + codec->afg ? codec->afg : codec->mfg, + AC_PWRST_D3); if (codec->patch_ops.post_suspend) codec->patch_ops.post_suspend(codec); } diff --git a/trunk/sound/pci/hda/hda_intel.c b/trunk/sound/pci/hda/hda_intel.c index 1f350522bed4..c19e71a94e1b 100644 --- a/trunk/sound/pci/hda/hda_intel.c +++ b/trunk/sound/pci/hda/hda_intel.c @@ -783,13 +783,11 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus, { struct azx *chip = bus->private_data; unsigned long timeout; - unsigned long loopcounter; int do_poll = 0; again: timeout = jiffies + msecs_to_jiffies(1000); - - for (loopcounter = 0;; loopcounter++) { + for (;;) { if (chip->polling_mode || do_poll) { spin_lock_irq(&chip->reg_lock); azx_update_rirb(chip); @@ -805,7 +803,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus, } if (time_after(jiffies, timeout)) break; - if (bus->needs_damn_long_delay || loopcounter > 3000) + if (bus->needs_damn_long_delay) msleep(2); /* temporary workaround */ else { udelay(10); @@ -2353,17 +2351,6 @@ static void azx_power_notify(struct hda_bus *bus) * power management */ -static int snd_hda_codecs_inuse(struct hda_bus *bus) -{ - struct hda_codec *codec; - - list_for_each_entry(codec, &bus->codec_list, list) { - if (snd_hda_codec_needs_resume(codec)) - return 1; - } - return 0; -} - static int azx_suspend(struct pci_dev *pci, pm_message_t state) { struct snd_card *card = pci_get_drvdata(pci); @@ -2410,8 +2397,7 @@ static int azx_resume(struct pci_dev *pci) return -EIO; azx_init_pci(chip); - if (snd_hda_codecs_inuse(chip->bus)) - azx_init_chip(chip, 1); + azx_init_chip(chip, 1); snd_hda_resume(chip->bus); snd_power_change_state(card, SNDRV_CTL_POWER_D0); diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index 7810913d07a0..818f90bc7d57 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -5405,8 +5405,6 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", ALC882_FIXUP_ACER_ASPIRE_4930G), SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), - SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G", - ALC882_FIXUP_ACER_ASPIRE_4930G), SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE), SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G), SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), @@ -5440,7 +5438,6 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), - SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3", ALC889_FIXUP_CD), SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), @@ -5641,13 +5638,13 @@ static int patch_alc262(struct hda_codec *codec) snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); } #endif + alc_auto_parse_customize_define(codec); + alc_fix_pll_init(codec, 0x20, 0x0a, 10); alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); - alc_auto_parse_customize_define(codec); - /* automatic parse from the BIOS config */ err = alc262_parse_auto_config(codec); if (err < 0) @@ -6252,6 +6249,8 @@ static int patch_alc269(struct hda_codec *codec) spec->mixer_nid = 0x0b; + alc_auto_parse_customize_define(codec); + err = alc_codec_rename_from_preset(codec); if (err < 0) goto error; @@ -6284,8 +6283,6 @@ static int patch_alc269(struct hda_codec *codec) alc269_fixup_tbl, alc269_fixups); alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); - alc_auto_parse_customize_define(codec); - /* automatic parse from the BIOS config */ err = alc269_parse_auto_config(codec); if (err < 0) @@ -6862,6 +6859,8 @@ static int patch_alc662(struct hda_codec *codec) /* handle multiple HPs as is */ spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; + alc_auto_parse_customize_define(codec); + alc_fix_pll_init(codec, 0x20, 0x04, 15); err = alc_codec_rename_from_preset(codec); @@ -6878,9 +6877,6 @@ static int patch_alc662(struct hda_codec *codec) alc_pick_fixup(codec, alc662_fixup_models, alc662_fixup_tbl, alc662_fixups); alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); - - alc_auto_parse_customize_define(codec); - /* automatic parse from the BIOS config */ err = alc662_parse_auto_config(codec); if (err < 0) diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c index 2cb1e08f962a..4742cac26aa9 100644 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ b/trunk/sound/pci/hda/patch_sigmatel.c @@ -4415,9 +4415,9 @@ static int stac92xx_init(struct hda_codec *codec) def_conf = get_defcfg_connect(def_conf); /* skip any ports that don't have jacks since presence * detection is useless */ - if (def_conf != AC_JACK_PORT_NONE && - !is_jack_detectable(codec, nid)) { - stac_toggle_power_map(codec, nid, 1); + if (def_conf != AC_JACK_PORT_COMPLEX) { + if (def_conf != AC_JACK_PORT_NONE) + stac_toggle_power_map(codec, nid, 1); continue; } if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) { diff --git a/trunk/sound/pci/rme9652/hdsp.c b/trunk/sound/pci/rme9652/hdsp.c index 0b2aea2ce172..b68cdec03b9e 100644 --- a/trunk/sound/pci/rme9652/hdsp.c +++ b/trunk/sound/pci/rme9652/hdsp.c @@ -5170,7 +5170,6 @@ static int snd_hdsp_create_hwdep(struct snd_card *card, struct hdsp *hdsp) strcpy(hw->name, "HDSP hwdep interface"); hw->ops.ioctl = snd_hdsp_hwdep_ioctl; - hw->ops.ioctl_compat = snd_hdsp_hwdep_ioctl; return 0; } diff --git a/trunk/sound/soc/blackfin/bf5xx-ssm2602.c b/trunk/sound/soc/blackfin/bf5xx-ssm2602.c index b39ad356b92b..df3ac73f8778 100644 --- a/trunk/sound/soc/blackfin/bf5xx-ssm2602.c +++ b/trunk/sound/soc/blackfin/bf5xx-ssm2602.c @@ -99,7 +99,6 @@ static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = { .platform_name = "bfin-i2s-pcm-audio", .codec_name = "ssm2602.0-001b", .ops = &bf5xx_ssm2602_ops, - .dai_fmt = BF5XX_SSM2602_DAIFMT, }, { .name = "ssm2602", @@ -109,7 +108,6 @@ static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = { .platform_name = "bfin-i2s-pcm-audio", .codec_name = "ssm2602.0-001b", .ops = &bf5xx_ssm2602_ops, - .dai_fmt = BF5XX_SSM2602_DAIFMT, }, }; diff --git a/trunk/sound/soc/codecs/cs42l73.c b/trunk/sound/soc/codecs/cs42l73.c index 3686417f5ea5..07c44b71f096 100644 --- a/trunk/sound/soc/codecs/cs42l73.c +++ b/trunk/sound/soc/codecs/cs42l73.c @@ -568,22 +568,22 @@ static const struct snd_kcontrol_new cs42l73_snd_controls[] = { attn_tlv), SOC_SINGLE_TLV("SPK-IP Mono Volume", - CS42L73_SPKMIPMA, 0, 0x3F, 1, attn_tlv), + CS42L73_SPKMIPMA, 0, 0x3E, 1, attn_tlv), SOC_SINGLE_TLV("SPK-XSP Mono Volume", - CS42L73_SPKMXSPA, 0, 0x3F, 1, attn_tlv), + CS42L73_SPKMXSPA, 0, 0x3E, 1, attn_tlv), SOC_SINGLE_TLV("SPK-ASP Mono Volume", - CS42L73_SPKMASPA, 0, 0x3F, 1, attn_tlv), + CS42L73_SPKMASPA, 0, 0x3E, 1, attn_tlv), SOC_SINGLE_TLV("SPK-VSP Mono Volume", - CS42L73_SPKMVSPMA, 0, 0x3F, 1, attn_tlv), + CS42L73_SPKMVSPMA, 0, 0x3E, 1, attn_tlv), SOC_SINGLE_TLV("ESL-IP Mono Volume", - CS42L73_ESLMIPMA, 0, 0x3F, 1, attn_tlv), + CS42L73_ESLMIPMA, 0, 0x3E, 1, attn_tlv), SOC_SINGLE_TLV("ESL-XSP Mono Volume", - CS42L73_ESLMXSPA, 0, 0x3F, 1, attn_tlv), + CS42L73_ESLMXSPA, 0, 0x3E, 1, attn_tlv), SOC_SINGLE_TLV("ESL-ASP Mono Volume", - CS42L73_ESLMASPA, 0, 0x3F, 1, attn_tlv), + CS42L73_ESLMASPA, 0, 0x3E, 1, attn_tlv), SOC_SINGLE_TLV("ESL-VSP Mono Volume", - CS42L73_ESLMVSPMA, 0, 0x3F, 1, attn_tlv), + CS42L73_ESLMVSPMA, 0, 0x3E, 1, attn_tlv), SOC_ENUM("IP Digital Swap/Mono Select", ip_swap_enum), diff --git a/trunk/sound/soc/codecs/sgtl5000.c b/trunk/sound/soc/codecs/sgtl5000.c index c395ec370445..8e92fb88ed09 100644 --- a/trunk/sound/soc/codecs/sgtl5000.c +++ b/trunk/sound/soc/codecs/sgtl5000.c @@ -809,7 +809,6 @@ static int ldo_regulator_register(struct snd_soc_codec *codec, { struct ldo_regulator *ldo; struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); - struct regulator_config config = { }; ldo = kzalloc(sizeof(struct ldo_regulator), GFP_KERNEL); @@ -833,11 +832,8 @@ static int ldo_regulator_register(struct snd_soc_codec *codec, ldo->codec_data = codec; ldo->voltage = voltage; - config.dev = codec->dev; - config.driver_data = ldo; - config.init_data = init_data; - - ldo->dev = regulator_register(&ldo->desc, &config); + ldo->dev = regulator_register(&ldo->desc, codec->dev, + init_data, ldo, NULL); if (IS_ERR(ldo->dev)) { int ret = PTR_ERR(ldo->dev); diff --git a/trunk/sound/soc/codecs/tlv320aic23.c b/trunk/sound/soc/codecs/tlv320aic23.c index df1e07ffac32..16d55f91a653 100644 --- a/trunk/sound/soc/codecs/tlv320aic23.c +++ b/trunk/sound/soc/codecs/tlv320aic23.c @@ -472,7 +472,7 @@ static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai, static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - u16 reg = snd_soc_read(codec, TLV320AIC23_PWR) & 0x17f; + u16 reg = snd_soc_read(codec, TLV320AIC23_PWR) & 0xff7f; switch (level) { case SND_SOC_BIAS_ON: @@ -491,7 +491,7 @@ static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_OFF: /* everything off, dac mute, inactive */ snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0); - snd_soc_write(codec, TLV320AIC23_PWR, 0x1ff); + snd_soc_write(codec, TLV320AIC23_PWR, 0xffff); break; } codec->dapm.bias_level = level; diff --git a/trunk/sound/soc/codecs/wm8350.c b/trunk/sound/soc/codecs/wm8350.c index aa12c6b6beeb..8c4c9591ec05 100644 --- a/trunk/sound/soc/codecs/wm8350.c +++ b/trunk/sound/soc/codecs/wm8350.c @@ -60,7 +60,7 @@ struct wm8350_jack_data { }; struct wm8350_data { - struct wm8350 *wm8350; + struct snd_soc_codec codec; struct wm8350_output out1; struct wm8350_output out2; struct wm8350_jack_data hpl; @@ -1309,7 +1309,7 @@ static void wm8350_hp_work(struct wm8350_data *priv, struct wm8350_jack_data *jack, u16 mask) { - struct wm8350 *wm8350 = priv->wm8350; + struct wm8350 *wm8350 = priv->codec.control_data; u16 reg; int report; @@ -1342,7 +1342,7 @@ static void wm8350_hpr_work(struct work_struct *work) static irqreturn_t wm8350_hp_jack_handler(int irq, void *data) { struct wm8350_data *priv = data; - struct wm8350 *wm8350 = priv->wm8350; + struct wm8350 *wm8350 = priv->codec.control_data; struct wm8350_jack_data *jack = NULL; switch (irq - wm8350->irq_base) { @@ -1427,7 +1427,7 @@ EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect); static irqreturn_t wm8350_mic_handler(int irq, void *data) { struct wm8350_data *priv = data; - struct wm8350 *wm8350 = priv->wm8350; + struct wm8350 *wm8350 = priv->codec.control_data; u16 reg; int report = 0; @@ -1536,8 +1536,6 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) return -ENOMEM; snd_soc_codec_set_drvdata(codec, priv); - priv->wm8350 = wm8350; - for (i = 0; i < ARRAY_SIZE(supply_names); i++) priv->supplies[i].supply = supply_names[i]; @@ -1546,6 +1544,7 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) if (ret != 0) return ret; + wm8350->codec.codec = codec; codec->control_data = wm8350; /* Put the codec into reset if it wasn't already */ diff --git a/trunk/sound/soc/codecs/wm8994.c b/trunk/sound/soc/codecs/wm8994.c index 2de12ebe43b5..6c1fe3afd4b5 100644 --- a/trunk/sound/soc/codecs/wm8994.c +++ b/trunk/sound/soc/codecs/wm8994.c @@ -1144,7 +1144,7 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA, 0); - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, + snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA, 0); diff --git a/trunk/sound/soc/codecs/wm_hubs.c b/trunk/sound/soc/codecs/wm_hubs.c index 6c028c470601..f13f2886339c 100644 --- a/trunk/sound/soc/codecs/wm_hubs.c +++ b/trunk/sound/soc/codecs/wm_hubs.c @@ -1035,7 +1035,7 @@ void wm_hubs_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); - int mask, val; + int val; switch (level) { case SND_SOC_BIAS_STANDBY: @@ -1047,13 +1047,6 @@ void wm_hubs_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_ON: /* Turn off any unneded single ended outputs */ val = 0; - mask = 0; - - if (hubs->lineout1_se) - mask |= WM8993_LINEOUT1N_ENA | WM8993_LINEOUT1P_ENA; - - if (hubs->lineout2_se) - mask |= WM8993_LINEOUT2N_ENA | WM8993_LINEOUT2P_ENA; if (hubs->lineout1_se && hubs->lineout1n_ena) val |= WM8993_LINEOUT1N_ENA; @@ -1068,7 +1061,11 @@ void wm_hubs_set_bias_level(struct snd_soc_codec *codec, val |= WM8993_LINEOUT2P_ENA; snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3, - mask, val); + WM8993_LINEOUT1N_ENA | + WM8993_LINEOUT1P_ENA | + WM8993_LINEOUT2N_ENA | + WM8993_LINEOUT2P_ENA, + val); /* Remove the input clamps */ snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG, diff --git a/trunk/sound/soc/omap/omap-pcm.c b/trunk/sound/soc/omap/omap-pcm.c index 5a649da9122a..a59bd352d342 100644 --- a/trunk/sound/soc/omap/omap-pcm.c +++ b/trunk/sound/soc/omap/omap-pcm.c @@ -401,10 +401,6 @@ static int omap_pcm_new(struct snd_soc_pcm_runtime *rtd) } out: - /* free preallocated buffers in case of error */ - if (ret) - omap_pcm_free_dma_buffers(pcm); - return ret; } diff --git a/trunk/sound/soc/samsung/s3c2412-i2s.c b/trunk/sound/soc/samsung/s3c2412-i2s.c index 79fbeea99d46..72185078ddf8 100644 --- a/trunk/sound/soc/samsung/s3c2412-i2s.c +++ b/trunk/sound/soc/samsung/s3c2412-i2s.c @@ -166,7 +166,7 @@ static struct snd_soc_dai_driver s3c2412_i2s_dai = { static __devinit int s3c2412_iis_dev_probe(struct platform_device *pdev) { - return s3c_i2sv2_register_dai(&pdev->dev, -1, &s3c2412_i2s_dai); + return snd_soc_register_dai(&pdev->dev, &s3c2412_i2s_dai); } static __devexit int s3c2412_iis_dev_remove(struct platform_device *pdev) diff --git a/trunk/sound/soc/sh/migor.c b/trunk/sound/soc/sh/migor.c index 8526e1edaf45..9d9ad8d61c0a 100644 --- a/trunk/sound/soc/sh/migor.c +++ b/trunk/sound/soc/sh/migor.c @@ -35,7 +35,7 @@ static unsigned long siumckb_recalc(struct clk *clk) return codec_freq; } -static struct sh_clk_ops siumckb_clk_ops = { +static struct clk_ops siumckb_clk_ops = { .recalc = siumckb_recalc, }; diff --git a/trunk/sound/soc/soc-core.c b/trunk/sound/soc/soc-core.c index c88d9741b9e7..1d6a80c9f4c2 100644 --- a/trunk/sound/soc/soc-core.c +++ b/trunk/sound/soc/soc-core.c @@ -3625,10 +3625,10 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, int i, ret; num_routes = of_property_count_strings(np, propname); - if (num_routes < 0 || num_routes & 1) { + if (num_routes & 1) { dev_err(card->dev, - "Property '%s' does not exist or its length is not even\n", - propname); + "Property '%s's length is not even\n", + propname); return -EINVAL; } num_routes /= 2; diff --git a/trunk/tools/perf/Makefile b/trunk/tools/perf/Makefile index 92271d32bc30..9bf3fc759344 100644 --- a/trunk/tools/perf/Makefile +++ b/trunk/tools/perf/Makefile @@ -774,10 +774,10 @@ $(OUTPUT)perf.o perf.spec \ # over the general rule for .o $(OUTPUT)util/%-flex.o: $(OUTPUT)util/%-flex.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Iutil/ -w $< + $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Iutil/ -Wno-redundant-decls -Wno-switch-default -Wno-unused-function $< $(OUTPUT)util/%-bison.o: $(OUTPUT)util/%-bison.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -Iutil/ -w $< + $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -Iutil/ -Wno-redundant-decls -Wno-switch-default -Wno-unused-function $< $(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $< diff --git a/trunk/tools/perf/builtin-stat.c b/trunk/tools/perf/builtin-stat.c index 1e5e9b270f5e..c941bb640f49 100644 --- a/trunk/tools/perf/builtin-stat.c +++ b/trunk/tools/perf/builtin-stat.c @@ -283,8 +283,6 @@ static int create_perf_stat_counter(struct perf_evsel *evsel, { struct perf_event_attr *attr = &evsel->attr; struct xyarray *group_fd = NULL; - bool exclude_guest_missing = false; - int ret; if (group && evsel != first) group_fd = first->fd; @@ -295,39 +293,16 @@ static int create_perf_stat_counter(struct perf_evsel *evsel, attr->inherit = !no_inherit; -retry: - if (exclude_guest_missing) - evsel->attr.exclude_guest = evsel->attr.exclude_host = 0; - - if (system_wide) { - ret = perf_evsel__open_per_cpu(evsel, evsel_list->cpus, + if (system_wide) + return perf_evsel__open_per_cpu(evsel, evsel_list->cpus, group, group_fd); - if (ret) - goto check_ret; - return 0; - } - if (!target_pid && !target_tid && (!group || evsel == first)) { attr->disabled = 1; attr->enable_on_exec = 1; } - ret = perf_evsel__open_per_thread(evsel, evsel_list->threads, - group, group_fd); - if (!ret) - return 0; - /* fall through */ -check_ret: - if (ret && errno == EINVAL) { - if (!exclude_guest_missing && - (evsel->attr.exclude_guest || evsel->attr.exclude_host)) { - pr_debug("Old kernel, cannot exclude " - "guest or host samples.\n"); - exclude_guest_missing = true; - goto retry; - } - } - return ret; + return perf_evsel__open_per_thread(evsel, evsel_list->threads, + group, group_fd); } /* @@ -488,13 +463,8 @@ static int run_perf_stat(int argc __used, const char **argv) list_for_each_entry(counter, &evsel_list->entries, node) { if (create_perf_stat_counter(counter, first) < 0) { - /* - * PPC returns ENXIO for HW counters until 2.6.37 - * (behavior changed with commit b0a873e). - */ if (errno == EINVAL || errno == ENOSYS || - errno == ENOENT || errno == EOPNOTSUPP || - errno == ENXIO) { + errno == ENOENT || errno == EOPNOTSUPP) { if (verbose) ui__warning("%s event is not supported by the kernel.\n", event_name(counter)); diff --git a/trunk/tools/perf/util/header.c b/trunk/tools/perf/util/header.c index c0b70c697a36..4c7c2d73251f 100644 --- a/trunk/tools/perf/util/header.c +++ b/trunk/tools/perf/util/header.c @@ -296,7 +296,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, if (mkdir_p(filename, 0755)) goto out_free; - snprintf(filename + len, size - len, "/%s", sbuild_id); + snprintf(filename + len, sizeof(filename) - len, "/%s", sbuild_id); if (access(filename, F_OK)) { if (is_kallsyms) {